Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 1 addition & 20 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Rust workspace with two crates:
- `crates/aptu-coder-core` -- parsing, analysis, formatting, graph, pagination, types
- `crates/aptu-coder` -- MCP server, tool handlers, logging, metrics, MCP Resources surface (list_resources, list_resource_templates, read_resource in crates/aptu-coder/src/tools/resources.rs)

Seven MCP tools: `analyze_directory`, `analyze_file`, `analyze_module`, `analyze_symbol` (analyze_* family); `edit_overwrite`, `edit_replace` (edit_* family); `exec_command` (exec_* family).
MCP tool surface and parameter schemas are documented by the tools themselves; do not duplicate them here. Tool handler logic lives in `crates/aptu-coder/src/tools/<tool>.rs`.
Rust edition 2024, async with tokio, latest MCP protocol via `rmcp`. Supported languages are listed in `crates/aptu-coder-core/src/lang.rs`.

## CI runners
Expand Down Expand Up @@ -74,25 +74,6 @@ Patterns contributors consistently get wrong:

Follow an existing handler in `crates/aptu-coder-core/src/languages/`. The extension map is in `crates/aptu-coder-core/src/lang.rs`; the `LanguageInfo` registry with queries is in `crates/aptu-coder-core/src/languages/mod.rs`.

## Tool parameters

Canonical parameter lists live in the `types` module (`crates/aptu-coder-core/src/types.rs`). Key non-obvious constraints:

- `summary=true` and `cursor` are mutually exclusive; passing both returns INVALID_PARAMS.
- `impl_only=true` restricts `analyze_symbol` callers to `impl Trait for Type` blocks; returns INVALID_PARAMS for non-Rust directories.
- `analyze_module` supports `path` only -- pagination and summary are not supported.
- `import_lookup=true` on `analyze_symbol` requires a non-empty `symbol` (the module path to search for); returns INVALID_PARAMS if symbol is empty. Mutually exclusive with normal call-graph lookup.
- `def_use=true` on `analyze_symbol` triggers def-use extraction; `def_use_sites` is populated in `structuredContent` only when paginating in DefUse cursor mode, not on the initial call (the handler clears it on the first response and bootstraps a cursor to page through def-use results).
- `working_dir` on `edit_overwrite` and `edit_replace` sets the base directory for path resolution (default: server CWD). Path confinement is the operator responsibility; working_dir is a path-resolution convenience only.
- `edit_replace` accepts an optional `expected_content_hash` (blake3 hex of the raw file bytes the caller last saw). If supplied and the file has changed since the caller read it, the edit is rejected with INVALID_PARAMS directing a re-read; omit to skip the staleness check. Concurrent edits to the same file are serialized via a per-path mutex registry (acquired inside spawn_blocking) to prevent silent read-modify-write data loss.
- `edit_replace` stale-context circuit breaker fires after 5 consecutive `not_found` or `ambiguous` failures on the same (session_id, path) pair, returning a directive error; the map is capped at 1024 entries.
- `exec_command` accepts an optional `timeout_secs` (integer >= 0; 0 or omitted means no limit). When the child process exceeds the limit it is killed; `timed_out: true` is set in the response and `exit_code` is null. Heredoc syntax is rejected before spawn in four cases: file-write pattern (cat/tee/redirect + `<<`), stdin-consuming flag (`--body-file -`, `--data -`, etc.) paired with `<<`, `params.stdin` set while command contains `<<`, or missing closing delimiter.
- `exec_command` accepts an optional `drain_timeout_secs` (integer >= 0; 0 or omitted means 500ms default, negative = INVALID_PARAMS, positive = drain window in milliseconds). Controls how long the post-exit drain waits for a background subprocess holding pipes open before returning `output_truncated: true`.
- `analyze_symbol` uses an L2 on-disk call-graph cache in addition to the L1 in-memory LRU. Configure with `APTU_CODER_DISK_CACHE_DIR` (default: `$XDG_DATA_HOME/aptu-coder/analysis-cache`); disable with `APTU_CODER_DISK_CACHE_DISABLED=1`.
- `call_frequency` on `analyze_symbol` is filtered out when the `Functions` field is not in the projected fields set.
- MCP Resource URI templates use `{repo_hash}` (blake3 hash of the canonical directory path), `depth` query parameter (integer, default 3), and `cursor` (opaque pagination token). Resources are paginated. Cold cache returns a message recommending `analyze_symbol` first.
Escalate to `analyze_symbol` when: (1) you need all callers of a function, (2) you need the full call chain for a symbol, (3) you need all files importing a module path (use `import_lookup=true`).

## Do not

- Add dependencies without justification in the PR description
Expand Down