Skip to content

DoraemonHugU/opencode-arch-index

Repository files navigation

opencode-arch-index-plugin

English | 简体中文

OpenCode plugin that maintains a searchable architecture index at .arch-index/ARCH_INDEX.md.

What it does

  • Tracks Python/TypeScript/JavaScript/Rust source changes and marks dirty files.
  • Rebuilds index sections with deterministic ordering and stable line-range pointers.
  • Enforces freshness on index reads (read and common shell readers like cat).
  • Uses Python AST extraction by default, with optional LSP enrichment.

Manual control tools

The plugin exposes manual control tools that can be invoked through OpenCode tool calling:

  • arch_index_reload_full: Force a full rebuild from current tracked files.
  • arch_index_refresh_dirty: Run dirty-file incremental refresh immediately.
  • arch_index_status: Show overview status (index existence, in-flight rebuild, dirty counts, sequence counters, preview of dirty files).

By default, these tools are not exposed to model tool-calling. Enable exposure via config when needed.

The plugin also supports slash commands (enabled by default):

  • /arch-index-reload (alias: /arch-index-reload-full)
  • /arch-index-refresh (alias: /arch-index-refresh-dirty)
  • /arch-index-status [--dirty-limit N]

These are useful when you want deterministic operator-driven refresh behavior instead of waiting for a read trigger.

Runtime requirements

  • Bun 1.0+
  • Python 3 available as python3

Install

npm install opencode-arch-index-plugin

OpenCode configuration

Add the plugin in your OpenCode config (project or global):

{
  "plugin": [
    "opencode-arch-index-plugin"
  ]
}

Configuration

The plugin supports configuration via JSON files at the following locations (highest precedence first):

  1. Project Config: .opencode/opencode-arch-index.json
  2. User Config: ~/.config/opencode/opencode-arch-index.json (on Linux/macOS)
  3. Defaults: Internal plugin defaults

You can start from the bundled default language profile and copy it into your project config path:

mkdir -p .opencode
cp examples/opencode-arch-index.default.json .opencode/opencode-arch-index.json

Config Schema

{
  "respect_gitignore": true,
  "include": [],
  "exclude": [],
  "global_mode": "hybrid",
  "modes": {
    "rust": "off"
  },
  "logging": {
    "level": "info",
    "metrics_enabled": false,
    "metrics_top_n": 10,
    "metrics_history_limit": 20
  },
  "lsp": {
    "references_batch_concurrency": 4,
    "reference_cache_enabled": true,
    "reference_cache_max_entries": 20000,
    "circuit_breaker_failure_threshold": 5,
    "circuit_breaker_cooldown_ms": 30000,
    "servers": {
      "python": {
        "initialization_options": {
          "python": {
            "analysis": {
              "diagnosticMode": "openFilesOnly"
            }
          }
        }
      }
    }
  },
  "analysis": {
    "max_file_size_bytes": 2097152,
    "skip_binary_files": true,
    "binary_sniff_bytes": 4096
  },
  "controls": {
    "expose_tools_to_model": false,
    "enable_slash_commands": true
  }
}
  • respect_gitignore: Whether to skip files matched by .gitignore (default: true).
  • include: Optional allowlist of glob patterns. When non-empty, only matched files continue to analysis.
  • exclude: Array of glob patterns to explicitly exclude.
  • global_mode: Default mode for all supported languages (off, ast, lsp, hybrid).
  • modes: Per-language mode overrides (python, typescript, javascript, rust).
  • logging.level: Log verbosity (debug, info, warn, error, silent).
  • logging.metrics_enabled: Emit rebuild/analyzer performance metrics in logs.
  • logging.metrics_top_n: Number of slowest files to include in bottleneck summaries.
  • logging.metrics_history_limit: Number of recent metric runs persisted to history.
  • lsp.references_batch_concurrency: Max parallel references requests per file while a document stays open.
  • lsp.reference_cache_enabled: Enable dirty-safe reference count cache.
  • lsp.reference_cache_max_entries: Max persistent reference cache entries.
  • lsp.circuit_breaker_failure_threshold: Consecutive failures before opening LSP circuit breaker.
  • lsp.circuit_breaker_cooldown_ms: Cooldown time for a tripped LSP circuit breaker.
  • lsp.servers.<language>.initialization_options: Pass-through LSP initialization options (python, typescript, rust).
  • analysis.max_file_size_bytes: Skip files larger than this byte limit.
  • analysis.skip_binary_files: Enable binary-content guard.
  • analysis.binary_sniff_bytes: Bytes sampled for binary detection.
  • controls.expose_tools_to_model: Expose manual tools to model tool-calling.
  • controls.enable_slash_commands: Enable slash commands for manual control actions.

Precedence Rules

Configuration Merge

Layers are merged such that defaults < user < project. Atomic values like respect_gitignore and global_mode are overwritten, while objects like modes, logging, and lsp are shallow-merged.

File Selection

The selector evaluates paths in this order:

  1. Exclude: If a file matches any exclude pattern, it is skipped.
  2. Ignored Directories: Files under default ignored directories are skipped (venv, .venv, __pycache__, .mypy_cache, .pytest_cache, node_modules, .git, .arch-index, dist, build).
  3. Respect Gitignore: If respect_gitignore is true and it matches a .gitignore pattern, it is skipped.
  4. Include Allowlist: If include is non-empty, the file must match one of these patterns.
  5. Extension: File suffix must map to a language whose effective mode is not off.

Language activation is automatic from file extensions in the tracked set; LSP servers are only touched when matching files exist and their effective mode requires LSP.

Bottleneck Tracking

When logging.metrics_enabled is true, the plugin emits structured metrics for:

  • full rebuild phases (snapshot, baseline discovery/analyze, delta analyze, reconcile, render, write)
  • analyzer stage breakdown (prepare, extract_primary, fallback, enrich, finalize)
  • per-language analyzer totals for the same breakdown stages
  • per-file analyzer timings (slowest N files with extract_primary_ms, fallback_ms, enrich_ms, finalize_ms, total_ms)

This is intended for bottleneck diagnosis on large multi-project worktrees.

Metrics history is appended at .arch-index/metrics-history.json and automatically trimmed to the last logging.metrics_history_limit runs.

Indexing Modes & Fallbacks

  • off: No indexing for this language.
  • ast: Pure AST extraction via language-specific adapters.
  • lsp: LSP-only symbol extraction when a document-symbol provider is available.
  • hybrid: AST extraction enriched with LSP data (e.g., reference counts).

Non-fatal Fallbacks:

  • The fallback chain is LSP -> AST -> skip.
  • If lsp mode cannot extract symbols from LSP, it falls back to AST parsing; if AST also fails, that file is skipped.
  • If hybrid enrichment fails, AST symbols are preserved and enrichment is skipped.
  • Fallback/degradation emits visible warnings (toast in TUI when available) and console warnings for auditability.
  • If an adapter fails to parse a specific file, a warning is logged and the file is skipped, but the rest of the indexing continues.
  • If no adapter is found for a file extension, it is skipped with a warning.

Index format

The generated index uses deterministic sections:

  • metadata
  • 0) Usage
  • 1) Tree
  • 2) Symbols

A real generated snapshot for the current repository is committed at:

  • examples/generated/opencode-arch-index.ARCH_INDEX.md

Development

bun run build
bun test

Build output:

  • dist/index.js
  • dist/extract_symbols.py

About

OpenCode architecture index plugin

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •