agentleFS
HelwegHelweg/open-codebase-index/AGENTS.md

open-codebase-index

AGENTS.md230 starsChanged 5 months agoMITView on GitHub

Updated: 2026-08-02 | Commit: 32160f8 | Branch: main | Version: 0.22.3 Semantic codebase indexing for OpenCode, MCP hosts, Pi, omp (oh-my-pi), Claude, Codex, and Jcode. repo uses hybrid TypeScript/Rust architecture: When Rust code changes, rebuild native module before running targeted tests that bypass npm run test:run full PR validation gate is:

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository2 other files it gives its agents.

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

23 rules. About 0 are common, 10 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When Rust code changes, rebuild native module before running targeted tests that bypass npm run test:run

    line 32
  2. Very specific:

    Shared tools: use src/tools/contracts.ts operations.ts operation-runtime.ts execute-common.ts.

    line 147
  3. Very specific:

    When adding portable tool, update shared operation and contract first, add its canonical name to src/tools/tool-names.tsthen wire each …

    line 149
  4. Distinctive:

    Do not silently rename tools or change request/result contracts.

    line 162
  5. Distinctive:

    Prefer existing batch database methods for bulk indexing.

    line 178
  6. Very specific:

    Do not broadly replace opencode-codebase-index strings.

    line 189
  7. Very specific:

    Use namespace imports for Node.js built-ins when consistent w/ surrounding code:

    line 211
  8. Distinctive:

    Use explicit return types on exported functions.

    line 229
  9. Very specific:

    Avoid as any @ts-ignoreand empty catch blocks.

    line 232
  10. Very specific:

    Keep NAPI-facing conversions in native/src/bindings/ native/src/lib.rs.

    line 267
  11. Very specific:

    Keep core SQLite logic in native/src/db.rs and focused native/src/db/ modules.

    line 268
  12. Very specific:

    Add call-query files under native/queries/ and update call_extractor.rs when adding call-graph support.

    line 269
  13. Very specific:

    Update native/src/types.rsparser mapping, Cargo dependencies, and tests together when adding language.

    line 270
  14. Distinctive:

    Use isolated temporary directories and always clean them:

    line 279
  15. Distinctive:

    Never move or delete existing user indexes as part of branding or path cleanup w/o separate migration design and rollback path.

    line 336
  16. Distinctive:

    Keep host adapters thin and shared behavior centralized.

    line 356
  17. Distinctive:

    Add or update tests for every affected host contract.

    line 357
  18. Very specific:

    Update CHANGELOG.md for user-visible changes.

    line 367
  19. Very specific:

    Update CHANGELOG.md w/ Added/Changed/Fixed entries.

    line 374
  20. Distinctive:

    Run full PR validation gate.

    line 376
  21. Very specific:

    Commit release metadata and push release/vX.Y.Z.

    line 377
  22. Distinctive:

    Create GitHub release from that tag.

    line 380
  23. Distinctive:

    Do not manually publish release version that workflow is expected to publish.

    line 389

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md - AI Agent Guidelines for open-codebase-index

Updated: 2026-08-02 | Commit: 32160f8 | Branch: main | Version: 0.22.3

Semantic codebase indexing for OpenCode, MCP hosts, Pi, omp (oh-my-pi), Claude, Codex, and Jcode. repo uses hybrid TypeScript/Rust architecture:

  • TypeScript (src/): host adapters, tool orchestration, indexing, retrieval, embedding providers, config, evaluation, and watchers
  • Rust (native/): tree-sitter parsing, semantic chunking, usearch vectors, SQLite persistence, BM25, call graphs, and graph analytics

Build, Test, and Lint

npm run build          # Build TypeScript and the Rust native module
npm run build:ts       # TypeScript bundle plus built-CLI smoke test
npm run build:native   # Rust/NAPI module for the current platform

npm run test:run       # Full Vitest suite once; pretest rebuilds native code
npm test               # Vitest watch mode
npm run test:coverage  # Coverage run; pretest rebuilds native code

npm run lint           # ESLint over src/
npm run typecheck      # tsc --noEmit

Run a Single Test

npx vitest run tests/files.test.ts
npx vitest run -t "parseFile"

When Rust code changes, rebuild native module before running targeted tests that bypass npm run test:run

npm run build:native
# Equivalent low-level command:
cd native && cargo build --release && napi build --release --platform

full PR validation gate is:

npm run build && npm run typecheck && npm run lint && npm run test:run

Architecture and File Structure

src/
├── index.ts                    # Thin OpenCode facade; re-exports adapters/opencode
├── mcp-server.ts               # Thin MCP facade; re-exports createMcpServer
├── cli.ts                      # CLI facade for MCP, eval, and visualization commands
├── adapters/
│   ├── opencode.ts             # OpenCode plugin composition and hooks
│   ├── opencode/               # OpenCode tool and PR-impact adapters
│   ├── mcp/                    # MCP CLI, server, tools, prompts, and shared schemas
│   ├── shared/                 # Shared pi-contract extension core and call-graph registrar
│   ├── pi/                     # Thin Pi package wrappers over the shared core
│   └── omp/                    # Thin omp (oh-my-pi) wrapper over the shared core
├── tools/
│   ├── operations.ts           # Shared host-neutral tool operations
│   ├── operation-runtime.ts    # Shared operation runtime/context
│   ├── contracts.ts            # Shared request/result contracts
│   ├── execute-common.ts       # Common execution helpers
│   ├── context*.ts             # Context routing, retrieval, and evidence packing
│   └── tool-names.ts           # Canonical and host-specific public tool names
├── indexer/
│   ├── index.ts                # Indexer orchestration
│   ├── search-ranking.ts       # Hybrid fusion, filtering, diversity, assembly
│   ├── definition-ranking.ts   # Definition-oriented evidence ranking
│   ├── embedding-batches.ts    # Embedding batching, retry state, vector pooling
│   └── call-graph-constants.ts # Shared declaration chunk-type rules
├── native/                     # Focused TypeScript wrappers over the NAPI binding
├── config/                     # Host-aware config schema, merging, paths, and validation
├── embeddings/                 # Provider detection and implementations
├── git/                        # Branch resolution and branch-index materialization
├── watcher/                    # File and Git branch watchers
├── eval/                       # Retrieval evaluation CLI, datasets, metrics, and reports
├── rerank/                     # Optional external reranking
├── utils/                      # Files, paths, logging, metrics, power state, and helpers
├── identity-catalog.json       # Current/future product and package identities
└── package-metadata.ts         # Runtime package metadata helpers

native/src/
├── lib.rs                      # NAPI facade and exports
├── bindings/
│   └── database.rs             # NAPI Database wrapper methods
├── db.rs                       # Core SQLite database implementation
├── db/call_graph.rs            # Call-graph persistence and query operations
├── parser.rs                   # Tree-sitter parsing
├── chunker.rs                  # Semantic chunking with overlap
├── call_extractor.rs           # Query-based call extraction
├── community.rs                # Community detection and centrality algorithms
├── store.rs                    # usearch vector storage
├── inverted_index.rs           # BM25 keyword index
├── hasher.rs                   # xxhash content hashing
└── types.rs                    # Shared native types and language mapping

native/queries/                 # Tree-sitter call queries by language
tests/                          # Vitest integration and unit tests
benchmarks/                     # Native and retrieval benchmarks/evaluation fixtures
commands/                       # OpenCode slash command definitions
skill/                          # OpenCode skill guidance
docs/                           # Installation, configuration, tools, migration docs

See ARCHITECTURE.md for data flow and design details.

Where to Look

TaskPrimary location
Add or change an OpenCode integrationsrc/adapters/opencode.ts, src/adapters/opencode/
Add or change an MCP tool/promptsrc/adapters/mcp/register-tools.ts, register-prompts.ts
Add or change a Pi integrationsrc/adapters/pi/
Add or change an omp integrationsrc/adapters/omp/, src/omp-extension.ts
Change the shared pi/omp extension bodysrc/adapters/shared/extension-core.ts, src/adapters/shared/call-graph.ts
Change shared tool behaviorsrc/tools/operations.ts, operation-runtime.ts, contracts.ts
Add or rename a public toolsrc/tools/tool-names.ts, then update each host adapter
Change context routing/evidence packssrc/tools/context.ts, context-search.ts, context-pack.ts
Modify indexing orchestrationsrc/indexer/index.ts
Modify generic search rankingsrc/indexer/search-ranking.ts
Modify definition-first rankingsrc/indexer/definition-ranking.ts
Modify embedding batching/retriessrc/indexer/embedding-batches.ts
Add an embedding providersrc/embeddings/detector.ts, provider.ts, provider-types.ts
Change host config or storage pathssrc/config/host.ts, src/config/paths.ts
Change branch resolution/materializationsrc/git/branch-resolution.ts, branch-materialization.ts
Change TypeScript native wrapperssrc/native/
Change parsing/chunkingnative/src/parser.rs, chunker.rs
Add parser language supportnative/src/types.rs, parser.rs; see docs/adding-language-support.md
Modify call extractionnative/src/call_extractor.rs, native/queries/*-calls.scm
Modify SQLite operationsnative/src/db.rs, native/src/db/, native/src/bindings/database.rs
Modify graph communities/centralitynative/src/community.rs and database bindings
Modify vector or BM25 storagenative/src/store.rs, inverted_index.rs
Add a slash commandcommands/, then register it in the OpenCode adapter config callback
Change product/package identitysrc/identity-catalog.json, scripts/prepare-package-metadata.mjs
Change release packaging.github/workflows/build.yml

Host Adapter Boundary

Shared behavior belongs below src/adapters/. Host adapters should translate host schemas and lifecycle events into shared operations rather than reimplement indexing or search.

  • OpenCode: src/index.ts re-exports src/adapters/opencode.ts.
  • MCP: src/mcp-server.ts re-exports src/adapters/mcp/server.ts src/adapters/mcp/cli.ts owns stdio transport.
  • Pi: public compatibility facades src/pi-extension.ts src/pi-call-graph.ts delegate to src/adapters/pi/, which re-exports the shared core in src/adapters/shared/.
  • omp: src/omp-extension.ts re-exports src/adapters/omp/extension.js, a thin wrapper over the same shared tool/session core that injects omp's TypeBox-style builder (pi.typebox.Type) when the host exposes one. omp keeps the Pi host mode and .codebase-index/ storage. Its before_agent_start hook appends guidance as a separate block in omp's string[] prompt; Pi retains its string-valued prompt hook.
  • Shared tools: use src/tools/contracts.ts operations.ts operation-runtime.ts execute-common.ts.

When adding portable tool, update shared operation and contract first, add its canonical name to src/tools/tool-names.tsthen wire each supported host adapter. Preserve host-specific schemas, registration order, and output formats.

Public Tool Families

Canonical tool names live in src/tools/tool-names.ts.

  • Retrieval: codebase_context codebase_search codebase_peek find_similar implementation_lookup
  • Index lifecycle: index_codebase index_status index_health_check index_metrics index_logs
  • Graph analysis: call_graph call_graph_path pr_impact code_communities
  • OpenCode-only additions: knowledge-base management index_visualize
  • Pi knowledge-base aliases: knowledge_base_add knowledge_base_list knowledge_base_remove
  • omp reuses the Pi surface and knowledge-base aliases unchanged; omp's package manifest key is omp with a pi fallback.

Do not silently rename tools or change request/result contracts. They are compatibility surfaces across hosts.

Native Boundary

src/native/binding.ts is only low-level loader for platform-specific .node files. Focused wrappers expose native capabilities:

  • parsing.tsparsing, hashing, and call extraction
  • database.tsSQLite database API
  • embedding.tsembedding-related types/helpers
  • vector-store.tsvector index wrapper
  • inverted-index.tsBM25 wrapper
  • types.tsTypeScript types for native values
  • index.tsnative facade exports

Rust implementation details should remain behind NAPI facade in native/src/lib.rs native/src/bindings/. Keep JavaScript-facing names and value shapes stable unless TypeScript wrappers and tests are updated together.

Prefer existing batch database methods for bulk indexing. Do not replace them w/ sequential calls.

Package Identity and Compatibility

checked-in package remains opencode-codebase-index@0.22.3while release workflow publishes both:

  • open-codebase-indexpreferred host-neutral package; exports open-codebase-index-mcp and legacy binary alias
  • opencode-codebase-indexsynchronized compatibility package

Identity constants live in src/identity-catalog.json. scripts/prepare-package-metadata.mjs stages package-specific manifests w/o rewriting checked-in metadata. Native binary names, tool names, config paths, and persisted index formats remain stable during rename.

Do not broadly replace opencode-codebase-index strings. First classify each occurrence as current compatibility contract, future public identity, historical docs, or test fixture. Follow docs/rename-to-open-codebase-index.md.

TypeScript Conventions

Imports

This is ESM project. Relative TypeScript imports must use .js extensions:

// Correct
import { Indexer } from "./indexer/index.js";

// Wrong at runtime
import { Indexer } from "./indexer/index";

Import order:

  1. Type-only imports
  2. External packages and Node.js built-ins
  3. Internal modules w/ .js extensions

Use namespace imports for Node.js built-ins when consistent w/ surrounding code:

import * as os from "node:os";
import * as path from "node:path";

Naming and Types

ElementConventionExample
Files/directorieskebab-casesearch-ranking.ts
Functions/variablescamelCaseresolveProjectIndexPath
Classes/typesPascalCaseIndexer, SearchResult
Public toolssnake_casecodebase_context
ConstantsUPPER_SNAKE_CASEPORTABLE_TOOL_NAMES
  • Keep strict: true compatibility.
  • Use explicit return types on exported functions.
  • Prefix intentionally unused parameters w/ _.
  • Catch errors as unknown and narrow them.
  • Avoid as any @ts-ignoreand empty catch blocks.
function getErrorMessage(error: unknown): string {
  if (error instanceof Error) return error.message;
  return String(error);
}

Tool Schemas

OpenCode schemas use tool.schema from @opencode-ai/pluginnot direct Zod import:

import { tool, type ToolDefinition } from "@opencode-ai/plugin";

const z = tool.schema;

export const my_tool: ToolDefinition = tool({
  description: "Clear description",
  args: {
    query: z.string().describe("Argument purpose"),
    limit: z.number().optional().default(10),
  },
  async execute(args) {
    return "Result string";
  },
});

Shared behavior should normally be added to tool operations/contracts, not embedded directly in this adapter definition.

Rust Conventions

  • Rebuild w/ npm run build:native after Rust changes.
  • Keep NAPI-facing conversions in native/src/bindings/ native/src/lib.rs.
  • Keep core SQLite logic in native/src/db.rs and focused native/src/db/ modules.
  • Add call-query files under native/queries/ and update call_extractor.rs when adding call-graph support.
  • Update native/src/types.rsparser mapping, Cargo dependencies, and tests together when adding language.
  • Preserve deterministic ordering for graph, search, and batch results exposed to TypeScript.

Testing

  • Framework: Vitest w/ globals enabled
  • Default timeout: 30 seconds b/c native operations can be slow
  • Tests: tests/*.test.ts

Use isolated temporary directories and always clean them:

let tempDir: string;

beforeEach(() => {
  tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "test-"));
});

afterEach(() => {
  fs.rmSync(tempDir, { recursive: true, force: true });
});

Important coverage areas include:

AreaRepresentative tests
Native parsing, vectors, hashingnative.test.ts, inverted-index.test.ts
Database, batches, GCdatabase.test.ts, embedding-batches.test.ts, auto-gc.test.ts
Search and rankingsearch-integration.test.ts, retrieval-ranking.test.ts, definition-ranking.test.ts
Call graph and PR impactcall-graph.test.ts, pr-impact.test.ts
MCP and host adaptersmcp-server.test.ts, plugin-hooks.test.ts, pi-package.test.ts, omp-package.test.ts
Identity and package compatibilityidentity-phase0.test.ts, host-mode-paths.test.ts, claude-plugin.test.ts
Watchers and branch behaviorwatcher.test.ts, watcher-config-refresh.test.ts, automatic-branch-index.test.ts
Multi-process safetymultiprocess-indexing.test.ts, index-lock.test.ts
Retrieval qualityretrieval-benchmark.test.ts, evaluation datasets under benchmarks/golden/

For native performance checks:

npx tsx benchmarks/run.ts

For retrieval-quality gates, use eval:* scripts in package.json. Do not update evaluation baselines merely to make regression pass.

Configuration and Storage

config and index paths are host-aware:

HostProject configProject indexGlobal config
OpenCode.opencode/codebase-index.json.opencode/index/~/.config/opencode/codebase-index.json
Claude.claude/codebase-index.json.claude/index/~/.claude/codebase-index.json
Codex, Pi, omp, Jcode.codebase-index/config.json.codebase-index/index/~/.config/codebase-index/config.json

Non-OpenCode hosts retain fallbacks to existing OpenCode paths for compatibility. Worktrees may resolve config and indexes from main repo. Change path precedence only w/ explicit compatibility tests.

Key config groups in src/config/schema.ts include:

  • embedding provider/model and custom provider settings
  • indexingwatching, semantic-only mode, project markers, battery behavior, batching
  • searchhybrid fusion, limits, ranking, and related options
  • rerankeroptional external reranking
  • debuglogging and metrics
  • effectiveness metrics and knowledge-base settings

Never move or delete existing user indexes as part of branding or path cleanup w/o separate migration design and rollback path.

Anti-Patterns

AvoidReason
Missing .js on relative importsESM runtime failure
Host-specific search/index logic duplicated in adaptersShared operations will diverge
Public tool names duplicated as string literalstool-names.ts is the compatibility catalog
Direct Zod imports for OpenCode toolsUse tool.schema
as any or @ts-ignoreHides strict-mode contract failures
Empty catch blocksHides operational failures
Sequential database writes in bulk pathsExisting batch methods are substantially faster
Rust changes without rebuilding native codeTests may exercise stale .node binaries
Renaming package/native/storage identities togetherBreaks installs and persisted indexes
External reranking before local scope filtersCan leak out-of-scope source and waste requests
Updating retrieval baselines without investigating deltasMasks quality regressions

Pull Request Checklist

  1. Keep host adapters thin and shared behavior centralized.
  2. Add or update tests for every affected host contract.
  3. Rebuild native code when Rust changes.
  4. Run:

    npm run build && npm run typecheck && npm run lint && npm run test:run
  5. For retrieval changes, run relevant evaluation command and inspect per-query deltas.
  6. For identity, config-path, or storage changes, test both current and legacy compatibility paths.
  7. Update CHANGELOG.md for user-visible changes.

Release Checklist

Releases are prepared on release/vX.Y.Zmerged into mainthen tagged and published from merged commit.

  1. Reconcile full delta since previous tag, not only current Unreleased bullets.
  2. Update CHANGELOG.md w/ Added/Changed/Fixed entries.
  3. Bump package.json package-lock.json together.
  4. Run full PR validation gate.
  5. Commit release metadata and push release/vX.Y.Z.
  6. Open and merge release PR into main.
  7. Tag merged commit and push tag.
  8. Create GitHub release from that tag.
  9. Verify Build and Publish workflow:
    • builds all five native targets
    • stages both package identities
    • publishes open-codebase-index opencode-codebase-index through npm trusted publishing
  10. Smoke-test clean installs, both MCP binary names, ESM/CJS loading, MCP initialization, and native loading.

Supported release targets are macOS ARM64/x64, Linux ARM64/x64 GNU, and Windows x64/ARM64 MSVC.

Do not manually publish release version that workflow is expected to publish. Do not reuse or overwrite existing npm version.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.