Thanks for your interest in contributing! This guide covers everything you need to get started.
- Node.js >= 18.0.0
- pnpm (package manager)
- Git
# Clone the repo
git clone https://github.com/askpext/kode.git
cd kode
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run in development mode (watch + launch CLI)
pnpm dev
# Run tests
pnpm testkode/
├── src/
│ ├── cli.tsx # Main entry point
│ ├── config.ts # Configuration loading
│ ├── agent/ # Core agent logic
│ │ ├── loop.ts # Main agent loop
│ │ ├── tools.ts # Tool definitions + executor
│ │ ├── context.ts # Context management
│ │ ├── cache.ts # Tool result caching
│ │ └── planner.ts # Todo/plan management
│ ├── core/ # Shared logic
│ │ ├── cli/args.ts # CLI argument parsing
│ │ ├── commands/slash.ts# Slash command registry
│ │ ├── session/ # Session lifecycle
│ │ └── agent/ # Intent routing + analysis
│ │ ├── analyze.ts # Codebase analysis
│ │ └── router.ts # Deterministic intent router
│ ├── db/sessions.ts # SQLite session storage
│ ├── tools/ # Tool implementations
│ ├── ui/ # Ink React components
│ └── utils/ # Utilities (tokens, git, etc.)
├── docs/ # Documentation
├── dist/ # Build output (gitignored)
├── package.json
├── tsconfig.json
└── tsup.config.ts
- Bug fixes: Check issues
- New tools: Add to
src/tools/and register insrc/agent/tools.ts - Intent routing: Modify
src/core/agent/router.ts - UI changes: Edit components in
src/ui/ - Session/DB: Work in
src/db/sessions.ts
git checkout -b feat/your-feature-name
# or
git checkout -b fix/issue-descriptionFollow these guidelines:
- TypeScript strict mode — No
anytypes, proper null checks - ESM imports — Use
.jsextensions in imports:import { foo } from './bar.js' - No relative imports between packages — Not applicable here (single package), but keep imports clean
- Tests co-located — Put tests next to source:
router.ts→router.test.ts - No filler comments — Code should speak for itself
# Run all tests
pnpm test
# Run specific test file
pnpm test src/core/agent/router.test.tsTest patterns:
- Use
vitestwithdescribe,it,expect - Mock external services with
vi.mock() - Use temporary directories for file system tests
- Clean up in
afterEach()
# Build the project
pnpm build
# Verify the build works
node dist/cli.js --helpgit add .
git commit -m "feat: add your feature description"Commit message format:
feat:— New featurefix:— Bug fixdocs:— Documentation changestest:— Test additions/changesrefactor:— Code restructuring (no behavior change)chore:— Maintenance tasks
Push your branch and open a Pull Request:
git push origin your-branch-nameInclude:
- Clear description of what changed
- Link to related issue (if applicable)
- Screenshots for UI changes (terminal output counts)
- Test results
Tools are the building blocks of Kode. Here's how to add one:
// src/tools/your-tool.ts
export interface YourToolArgs {
someParam: string;
}
export interface YourToolResult {
success: boolean;
result: string;
error?: string;
}
export async function yourTool(args: YourToolArgs, cwd: string): Promise<YourToolResult> {
// Implementation
return { success: true, result: 'done' };
}// src/agent/tools.ts
import { yourTool } from '../tools/your-tool.js';
// In ToolExecutor.executeTool():
if (toolCall.name === 'your_tool') {
return yourTool(toolCall.args, this.cwd);
}Update the system prompt in src/agent/loop.ts to mention your tool:
// In callLLM() system prompt:
// - your_tool → description of what it doesIf your tool should be triggered deterministically (not via LLM), add detection in src/core/agent/router.ts and handling in src/agent/loop.ts.
// src/tools/your-tool.test.ts
import { describe, it, expect } from 'vitest';
import { yourTool } from './your-tool.js';
describe('yourTool', () => {
it('should do something', async () => {
const result = await yourTool({ someParam: 'test' }, '/tmp');
expect(result.success).toBe(true);
});
});- 2-space indentation
- Single quotes for strings
- Semicolons — Always
- Trailing commas — Yes
- Line length — No hard limit, but keep it reasonable
- Naming — camelCase for variables/functions, PascalCase for classes/types
- Tool functions — Input/output, error cases
- Intent routing — Pattern matching, edge cases
- Agent loop — Permission flows, retry logic
- Session management — CRUD operations, wordir changes
- Config loading — Priority, env vars, fallbacks
- UI components — Visual output changes (manual testing)
- LLM calls — External service (mock instead)
- Build artifacts — Not our responsibility
- Issues: Open a GitHub issue
- Discussions: Start a discussion for questions/ideas
- Code: Read the source — it's well-commented and structured
By contributing, you agree that your work will be licensed under the MIT License.