Skip to content

Commit d02b915

Browse files
committed
docs: add comprehensive AI agent guidelines to AGENTS.md
1 parent ebe409f commit d02b915

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

AGENTS.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# AGENTS.md - AI Agent Guidelines for opencode-codebase-index
2+
3+
Semantic codebase indexing plugin for OpenCode. Hybrid TypeScript/Rust architecture:
4+
- **TypeScript** (`src/`): Plugin logic, embedding providers, tools
5+
- **Rust** (`native/`): Tree-sitter parsing, vector search (usearch), SQLite storage
6+
7+
## Build/Test/Lint Commands
8+
9+
```bash
10+
npm run build # Build both TypeScript and Rust native module
11+
npm run build:ts # Build TypeScript only (via tsup)
12+
npm run build:native # Build Rust native module only
13+
14+
npm run test:run # Run all tests once (CI mode)
15+
npm test # Run tests in watch mode
16+
17+
npm run lint # ESLint on src/
18+
npm run typecheck # TypeScript type checking (tsc --noEmit)
19+
```
20+
21+
### Running a Single Test
22+
23+
```bash
24+
npx vitest run tests/files.test.ts # Run specific test file
25+
npx vitest run -t "parseFile" # Run tests matching pattern
26+
npx vitest run tests/native.test.ts --reporter=verbose
27+
```
28+
29+
### Native Module Build (requires Rust)
30+
31+
```bash
32+
cd native && cargo build --release && napi build --release --platform
33+
```
34+
35+
## Code Style Guidelines
36+
37+
### Import Organization
38+
39+
Group imports in this order, separated by blank lines:
40+
1. Type-only imports (`import type { ... }`)
41+
2. External packages and Node.js built-ins
42+
3. Internal modules
43+
44+
**Always use `.js` extension** for internal imports (ESM requirement):
45+
```typescript
46+
import { Indexer } from "./indexer/index.js"; // Correct
47+
import { Indexer } from "./indexer/index"; // Wrong - runtime error
48+
```
49+
50+
**Use namespace imports** for Node.js built-ins:
51+
```typescript
52+
import * as path from "path";
53+
import * as os from "os";
54+
```
55+
56+
### Naming Conventions
57+
58+
| Element | Convention | Example |
59+
|---------|------------|---------|
60+
| Files/Directories | kebab-case | `codebase-index.json`, `native/` |
61+
| Functions/Variables | camelCase | `loadJsonFile`, `projectRoot` |
62+
| Classes/Types/Interfaces | PascalCase | `Indexer`, `ChunkType` |
63+
| OpenCode tools | snake_case | `codebase_search`, `index_codebase` |
64+
| Constants | UPPER_SNAKE_CASE | `MAX_BATCH_TOKENS` |
65+
66+
### Type Patterns
67+
68+
- **Explicit return types** on all exported functions
69+
- **Strict TypeScript** enabled (`strict: true`)
70+
- **Prefix unused parameters** with `_` (ESLint enforced)
71+
- **Use `unknown`** for error handling, then narrow:
72+
73+
```typescript
74+
function getErrorMessage(error: unknown): string {
75+
if (error instanceof Error) return error.message;
76+
return String(error);
77+
}
78+
```
79+
80+
### Error Handling
81+
82+
```typescript
83+
// Non-critical: empty catch
84+
try {
85+
return JSON.parse(readFileSync(filePath, "utf-8"));
86+
} catch { /* ignore */ }
87+
return null;
88+
89+
// Critical: descriptive error
90+
throw new Error("No embedding provider available. Configure GitHub, OpenAI, Google, or Ollama.");
91+
```
92+
93+
Use `p-retry` for network operations with rate limit handling.
94+
95+
### OpenCode Tool Definitions
96+
97+
```typescript
98+
import { tool, type ToolDefinition } from "@opencode-ai/plugin";
99+
const z = tool.schema;
100+
101+
export const my_tool: ToolDefinition = tool({
102+
description: "Clear, concise description",
103+
args: {
104+
query: z.string().describe("What this argument is for"),
105+
limit: z.number().optional().default(10),
106+
},
107+
async execute(args) {
108+
return "Result string";
109+
},
110+
});
111+
```
112+
113+
## File Structure
114+
115+
```
116+
src/
117+
├── index.ts # Plugin entry point
118+
├── config/ # Configuration schema and parsing
119+
├── embeddings/ # Provider detection and API clients
120+
├── indexer/ # Core indexing logic
121+
├── git/ # Git utilities (branch detection)
122+
├── tools/ # OpenCode tool definitions
123+
├── utils/ # File collection, cost estimation
124+
├── native/ # Rust native module wrapper
125+
└── watcher/ # File/git change watcher
126+
127+
native/ # Rust source (tree-sitter, usearch, SQLite)
128+
tests/ # Vitest test files (.test.ts suffix)
129+
```
130+
131+
## Testing Guidelines
132+
133+
- Use Vitest globals (`describe`, `it`, `expect`, `beforeEach`, `afterEach`)
134+
- Test timeout is 30 seconds (native module operations can be slow)
135+
- Use temp directories for file-based tests:
136+
137+
```typescript
138+
let tempDir: string;
139+
beforeEach(() => { tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "test-")); });
140+
afterEach(() => { fs.rmSync(tempDir, { recursive: true, force: true }); });
141+
```
142+
143+
## Configuration Files
144+
145+
| File | Purpose |
146+
|------|---------|
147+
| `tsconfig.json` | ES2022 target, ESNext modules, strict mode |
148+
| `tsup.config.ts` | ESM + CJS output, external node modules |
149+
| `eslint.config.js` | typescript-eslint recommended rules |
150+
| `vitest.config.ts` | Node environment, 30s timeout |
151+
| `native/Cargo.toml` | Rust dependencies and build config |
152+
153+
## Common Pitfalls
154+
155+
1. **Missing `.js` extension** in imports causes runtime errors
156+
2. **Native module not built**: Run `npm run build:native` after cloning
157+
3. **Type errors with tool schemas**: Use `z` from `tool.schema`, not direct zod import
158+
159+
## PR Checklist
160+
161+
```bash
162+
npm run build && npm run typecheck && npm run lint && npm run test:run
163+
```

0 commit comments

Comments
 (0)