diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..1f548c8 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,28 @@ +{ + "name": "yatai", + "owner": { + "name": "Gaijin Entertainment", + "email": "a.zinoviev@gaijin.team" + }, + "metadata": { + "description": "Gaijin Entertainment Claude Code plugin marketplace", + "pluginRoot": "./claude" + }, + "plugins": [ + { + "name": "kensai", + "description": "Multi-agent code review pipeline with adversarial falsification, orchestrated by a stateful MCP server", + "source": "kensai", + "version": "0.1.0", + "license": "MIT", + "keywords": [ + "code-review", + "multi-agent", + "review-pipeline", + "falsification", + "proving", + "mcp" + ] + } + ] +} diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..741af5d --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,19 @@ +{ + "enabledPlugins": { + "ai-helpers@foundry": true, + "git-commit@foundry": true, + "skill-enforcer@foundry": true, + "the-coder@foundry": true, + "the-workflow@foundry": true, + "javascript@foundry": true + }, + "extraKnownMarketplaces": { + "foundry": { + "source": { + "source": "github", + "repo": "xobotyi/cc-foundry" + } + } + }, + "alwaysThinkingEnabled": true +} diff --git a/.github/workflows/kensai-review-mcp.yml b/.github/workflows/kensai-review-mcp.yml new file mode 100644 index 0000000..c22389c --- /dev/null +++ b/.github/workflows/kensai-review-mcp.yml @@ -0,0 +1,58 @@ +name: Kensai Review MCP + +on: + push: + branches: [main] + paths: + - "claude/kensai/mcp/review/**" + - ".github/workflows/kensai-review-mcp.yml" + pull_request: + paths: + - "claude/kensai/mcp/review/**" + - ".github/workflows/kensai-review-mcp.yml" + +defaults: + run: + working-directory: claude/kensai/mcp/review + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + package_json_file: claude/kensai/mcp/review/package.json + + - uses: actions/setup-node@v4 + with: + node-version: "26" + cache: pnpm + cache-dependency-path: claude/kensai/mcp/review/pnpm-lock.yaml + + - run: pnpm install --frozen-lockfile + + - run: pnpm lint + + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: ["lts/*", "26"] + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + package_json_file: claude/kensai/mcp/review/package.json + + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + cache-dependency-path: claude/kensai/mcp/review/pnpm-lock.yaml + + - run: pnpm install --frozen-lockfile + + - run: pnpm test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ba7aef --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +node_modules/ +.DS_Store diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1c0c107 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,86 @@ +# yatai + +Gaijin Entertainment plugin repository. Houses plugins for two ecosystems: Claude Code (`claude/`) and Pi (`pi/`). + +## Structure + +``` +yatai/ +├── claude/ # Claude Code plugins +│ └── kensai/ # Multi-agent code review pipeline +└── pi/ # PI plugins (future) +``` + +Each ecosystem has its own instruction file (`CLAUDE.md`, `AGENTS.md`, etc.) with ecosystem-specific conventions. + +## Conventions + + + +**Plugin context:** + +- Each plugin has an agent-facing instruction file (`CLAUDE.md`, `AGENTS.md`, etc.) explaining its components +- Each plugin has `README.md` for humans + +**Plugin documentation style:** + +- **Agent-facing file** — brief prose introduction, then structured content: component tables, dependency diagrams, + bullet-list conventions. Optimize for LLM compliance — terse bullets over explanatory paragraphs. +- **README.md** — human-facing documentation. Explanatory prose that frames the plugin around the problem it solves, + explains what each component does and when to use it. + +**Documentation maintenance:** Update plugin docs in the same work session as the code change: + +- **Plugin agent-facing file** — update when: adding/removing/renaming components; changing purpose, scope, or + dependencies; adding/removing conventions +- **Plugin README.md** — update when: any change that affects what users see or install +- **Ecosystem instruction file** — update plugin table when: adding/removing a plugin +- **Root CLAUDE.md** — update structure diagram when: adding/removing a plugin or ecosystem + +**Installation instructions:** + +- All plugin READMEs must use marketplace commands: + ``` + /plugin marketplace add GaijinEntertainment/yatai + /plugin install + ``` +- Do not use manual cp/ln installation methods + +**Version management:** + +- Plugin versions must be synchronized between each plugin's `.claude-plugin/plugin.json` and the repo-root + `.claude-plugin/marketplace.json` (which lists all plugins in a single file) +- Update both files when bumping versions + +**Licensing:** + +- Every plugin must contain a copy of the root `LICENSE` file in its directory +- When adding a new plugin, copy `LICENSE` from the repository root into the plugin directory + +**npm packages:** + +- Use `vp` for all toolchain operations — `vp install`, `vp check`, `vp test`, `vp build`. Never invoke `npm`, + `yarn`, or bare `pnpm` commands directly in instructions or CI +- Every `package.json` must include: `license` (matching the plugin license), `author`, `repository`, `type` (`module`), + `engines`, and `packageManager` fields +- Publishable packages must also include: `description`, `bin` or `exports`, `engines`, and `publishConfig` +- Publishable packages must have a `.npmignore` excluding tests, configs, lock files, and agent-facing docs +- Lock files (`pnpm-lock.yaml`) must be committed +- Pin `packageManager` in `package.json` to the exact pnpm version used by the project +- Use `--frozen-lockfile` in CI to catch uncommitted dependency changes + +**npm supply chain protection:** + +- Every package must have an `.npmrc` with `ignore-scripts=true` (blocks post-install script attacks) and + `minimum-release-age=7d` (rejects packages published less than 7 days ago) +- All publishable packages must set `"publishConfig": { "access": "public" }` in `package.json` +- The `@gaijin` npm scope must have 2FA enforced at the org level (manual npm setting) + + + + + +Since the project is about plugins, the scope in the commit message, if defined, must not contain the ecosystem path +(`claude/` or `pi/`). Use the plugin name as the scope. + + diff --git a/claude/CLAUDE.md b/claude/CLAUDE.md new file mode 100644 index 0000000..061ede0 --- /dev/null +++ b/claude/CLAUDE.md @@ -0,0 +1,37 @@ +# Claude Code Plugins + +Claude Code plugin ecosystem. Each subdirectory is a self-contained plugin. + +## Plugins + +| Plugin | Purpose | +|--------|---------| +| [kensai](kensai/) | Multi-agent code review pipeline with adversarial falsification | + +## Conventions + + +**Formatting:** +- Agent instruction files and prompts use the MDX parser (block-level XML tag support) +- README.md files use GFM parser + +**Skill structure:** + +- Router pattern: SKILL.md routes to `references/` for detailed content +- Keep SKILL.md under 500 lines; move depth to references + +**Installation instructions:** + +- All plugin READMEs must use marketplace commands: + ``` + /plugin marketplace add GaijinEntertainment/yatai + /plugin install + ``` +- Do not use manual cp/ln installation methods + +**Version management:** + +- Plugin versions must be synchronized between each plugin's `.claude-plugin/plugin.json` and the repo-root + `.claude-plugin/marketplace.json` (which lists all plugins in a single file) +- Update both files when bumping versions + diff --git a/claude/kensai/.claude-plugin/plugin.json b/claude/kensai/.claude-plugin/plugin.json new file mode 100644 index 0000000..d5ecf1e --- /dev/null +++ b/claude/kensai/.claude-plugin/plugin.json @@ -0,0 +1,19 @@ +{ + "name": "kensai", + "version": "0.1.0", + "description": "Multi-agent code review pipeline with adversarial falsification, orchestrated by a stateful MCP server", + "author": { + "name": "xobotyi", + "email": "a.zinoviev@gaijin.team" + }, + "repository": "https://github.com/GaijinEntertainment/yatai", + "license": "MIT", + "keywords": [ + "code-review", + "multi-agent", + "review-pipeline", + "falsification", + "proving", + "mcp" + ] +} diff --git a/claude/kensai/.mcp.json b/claude/kensai/.mcp.json new file mode 100644 index 0000000..ccab6ed --- /dev/null +++ b/claude/kensai/.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "kensai": { + "type": "stdio", + "command": "node", + "args": ["${CLAUDE_PLUGIN_ROOT}/mcp/review/src/index.ts"], + "alwaysLoad": true + } + } +} diff --git a/claude/kensai/CLAUDE.md b/claude/kensai/CLAUDE.md new file mode 100644 index 0000000..415ab4a --- /dev/null +++ b/claude/kensai/CLAUDE.md @@ -0,0 +1,92 @@ +# Kensai + +Multi-agent code review pipeline with adversarial falsification. A stateful MCP server orchestrates four phases — +grounding, surfacing, proving, filing — with dedicated agents per phase. + +## Pipeline + +``` +/kensai-review [mode] [path] + → mcp__kensai__session_start IDLE → GROUNDING + → mcp__kensai__grounding_store + → mcp__kensai__grounding_complete GROUNDING → SURFACING + → mcp__kensai__finding_surface / surface_clean + → mcp__kensai__surfacing_complete SURFACING → PROVING (or FILING if 0 findings) + → mcp__kensai__finding_verdict + → mcp__kensai__proving_complete PROVING → FILING + → mcp__kensai__filing_complete FILING → COMPLETE +``` + +## Components + +| Component | Purpose | +|-----------|---------| +| `mcp/review/src/index.ts` | MCP server — phase state machine, context persistence, handler-level phase enforcement | +| `skills/review/SKILL.md` | `/kensai-review` entry point — mode/path resolution, pipeline orchestration | +| `agents/review-grounder.md` | Grounding agent — maps the change, builds three-layer model, stores context via MCP | +| `agents/review-surfacer.md` | Surfacing agent — parallel read-only reviewer per dimension, records findings via MCP | +| `agents/review-prover.md` | Proving agent — adversarial falsification of surfaced findings, verdicts via MCP | + +## MCP Tools + +### Session lifecycle + +| Tool | Purpose | +|------|---------| +| `session_start` | Initialize session (IDLE -> GROUNDING) | +| `session_state` | Current phase, mode, refs, file/finding counts | +| `session_priming` | Paginated full context: metadata, changed files, file stats, agent-instructions, diffs. Call with `page=N` for large changes. | +| `session_end` | Destroy session | + +### Filesystem and search (session-scoped) + +| Tool | Purpose | +|------|---------| +| `read_file` | Read file with line numbers, binary detection | +| `list_dir` | Directory listing with depth control | +| `find_files` | Fuzzy file-name search | +| `grep` | Regex content search via ripgrep | + +### Git (session-scoped) + +| Tool | Purpose | +|------|---------| +| `changed_files` | File list with status (A/M/D) and +/- counts | +| `diff_file` | Annotated unified diff for one file | +| `log` | Recent commit history | + +### Review pipeline + +| Tool | Phase | Purpose | +|------|-------|---------| +| `observation_create` | GROUNDING | Record an observation | +| `observation_cancel` | GROUNDING | Retract an observation | +| `grounding_store` | GROUNDING | Persist grounding context | +| `grounding_get` | SURFACING+ | Retrieve grounding context | +| `grounding_complete` | GROUNDING -> SURFACING | Advance phase | +| `finding_surface` | SURFACING | Record a finding | +| `surface_clean` | SURFACING | Report a clean dimension | +| `finding_cancel` | SURFACING | Retract a finding | +| `surfacing_complete` | SURFACING -> PROVING/FILING | Advance (skip proving if 0 findings) | +| `findings_list` | PROVING+ | List findings with filter | +| `finding_get` | PROVING+ | Get single finding detail | +| `finding_verdict` | PROVING | Verdict a finding (pass/reject) | +| `proving_complete` | PROVING -> FILING | Advance phase | +| `filing_complete` | FILING -> COMPLETE | Mark review done | + +## Requirements + +- Agent teams: `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` +- Node.js 26+ (MCP server) + +## Design + +- **MCP-first** — agents access codebase exclusively through `mcp__kensai__*` tools; no direct Read/Grep/Bash +- **Self-serve context** — agents call `session_priming` to receive full review context; no data threading from lead +- **Handler-level phase enforcement** — all tools always registered; invalid-phase calls return hard error via `#require()` +- **Dedicated completion tools** — `grounding_complete`, `surfacing_complete`, `proving_complete` (not generic `transition`) +- **0-findings shortcut** — `surfacing_complete` jumps to FILING when no findings, skipping PROVING +- **Recall over precision** — surfacers cast a wide net; prover applies falsification gates to filter +- **Read-only agents** — grounder, surfacers, and prover never edit files +- **Stable finding IDs** — F1, F2, ... carried across phase boundaries +- **Soft errors** — not-found/binary/empty return `ok("[marker]")` with path suggestions, not `err()` diff --git a/claude/kensai/LICENSE b/claude/kensai/LICENSE new file mode 100644 index 0000000..b40df94 --- /dev/null +++ b/claude/kensai/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Gaijin Entertainment + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/claude/kensai/README.md b/claude/kensai/README.md new file mode 100644 index 0000000..e4c428f --- /dev/null +++ b/claude/kensai/README.md @@ -0,0 +1,53 @@ +# Kensai + +Kensai is an AI-powered code review plugin for Claude Code. The name blends the Japanese _kensa_ (検査) — "inspection" +— with _AI_. A secondary reading, _kensai_ (剣聖, "sword saint"), evokes the precision of a master swordsman: a +reviewer that cuts with exactness. + +## The Problem + +Code review is a bottleneck. Human reviewers skim past mechanical issues — missing error handling, stale references, +integration gaps — because their attention is consumed by the volume of changes. Automated linters catch syntax and +style, but miss semantic problems that require understanding what the code _does_. + +## The Solution + +Kensai runs a multi-agent review pipeline with adversarial falsification. Instead of one pass through the diff, it +separates comprehension, discovery, and verification into distinct phases with dedicated agents: + +1. **Grounding** — a dedicated agent maps the change: what moved, what it touches, what the author intended. Builds a + three-layer model (Plan / Intent / Reality) that anchors all subsequent review work. + +2. **Surfacing** — parallel agents review the change through different lenses (design, integration, correctness, etc.). + Each operates independently, optimizing for recall — surface everything suspicious. False positives are expected. + +3. **Proving** — a single agent applies adversarial falsification gates to every surfaced finding. Each finding is + treated as a hypothesis: name what would disprove it, then check. Findings that survive all gates reach the report; + the rest are rejected. + +4. **Filing** — surviving findings are formatted into a final report with code quotes, file references, and severity + ratings. + +The pipeline is orchestrated by a stateful MCP server that enforces phase order — tools reject calls outside their valid +phase, preventing agents from skipping steps or mixing concerns. + +## Usage + +``` +/kensai-review # review uncommitted changes +/kensai-review committed # review the last commit +/kensai-review all # review last commit + uncommitted (amendment preview) +/kensai-review uncommitted ./src # review uncommitted changes in a specific path +``` + +## Requirements + +- Node.js 26+ (MCP server runtime) +- Agent teams enabled: set `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in your Claude Code environment + +## Installation + +``` +/plugin marketplace add GaijinEntertainment/yatai +/plugin install kensai +``` diff --git a/claude/kensai/agents/review-grounder.md b/claude/kensai/agents/review-grounder.md new file mode 100644 index 0000000..14afa19 --- /dev/null +++ b/claude/kensai/agents/review-grounder.md @@ -0,0 +1,138 @@ +--- +name: review-grounder +description: >- + Grounding phase agent for the code review pipeline. Reads the diff, maps the integration surface, + builds the three-layer model, and stores structured grounding context via MCP. Use when spawning + the grounding teammate. +tools: mcp__kensai__session_priming, mcp__kensai__session_state, mcp__kensai__read_file, mcp__kensai__find_files, mcp__kensai__list_dir, mcp__kensai__grep, mcp__kensai__diff_file, mcp__kensai__changed_files, mcp__kensai__log, mcp__kensai__observation_create, mcp__kensai__observation_cancel, mcp__kensai__grounding_store, mcp__kensai__grounding_complete, SendMessage, TaskUpdate +model: inherit +--- + +Grounding agent. Map what changed, what it touches, what author said. Store structured result via MCP. + +**Read-only** — do not edit, write, or modify files. + +**Data flows through MCP tools only.** Store grounding via `mcp__kensai__grounding_store`, complete via +`mcp__kensai__grounding_complete`. SendMessage is for completion notification only — never for grounding data. + +## Tool Usage + +All codebase access goes through `mcp__kensai__*` tools — no direct filesystem or git access. + +- `mcp__kensai__session_priming` — call first. Returns metadata, changed-files table, file stats, agent-instructions, + and diffs as paginated response. If footer shows `[page X of Y]`, paginate until last page. Read ALL pages before + exploring. +- `mcp__kensai__read_file` — read specific lines when the diff is insufficient. Prefer line-windowed reads over whole + files. +- `mcp__kensai__grep` — search file contents by regex. For a content match, one scoped call. After 2 calls on the same + symbol, stop and read. +- `mcp__kensai__find_files` — locate files by name when path is unknown. Keep queries short (1-2 terms). +- `mcp__kensai__list_dir` — directory listing when exploring structure. +- `mcp__kensai__diff_file` — single-file annotated diff when you need to re-examine one file's changes. +- `mcp__kensai__changed_files` — file list with status and +/- counts (also in priming). +- `mcp__kensai__log` — recent commit history. + +Batch independent tool calls in a single turn. Every tool call answers a specific question — can't state the question, +skip the call. + +## Agent Instructions + +The priming context may include `` blocks — project conventions discovered from +CLAUDE.md/AGENTS.md files in the repository's directory chain. Apply these conventions when evaluating code under their +scope. Deeper (more specific) paths win on conflict. + +## Terse Register + +Active throughout. Verbose thinking → context drift → degraded quality. Drop articles, filler, pleasantries, hedging. +Fragments OK. Short synonyms. Technical terms exact. Code verbatim. Pattern: `[issue] at [file:line]. [evidence]. +[action].` + +## Three-Layer Model + +Every change has three layers. + +**Plan** — what was supposed to happen. Source: task reference in commit trailer, linked issues. May be absent. When present, fetch. + +**Intent** — what author meant. Source: commit message. Extract intent from subject, body, references. Uninformative → +infer from diff structure. + +**Reality** — what code does. Source: diff + integration surface (callers, consumers, dependency edges, registrations). +Identify by name and location first — that catalog is the deliverable. Read consumer bodies when correctness depends on +consumer semantics (security boundaries, concurrency invariants, schema migrations, protocol versions, contract +refactors) — not as a sweep "to make sure." + +The gap between layers is where findings live. Plan ≠ Intent → scope creep or misunderstood requirements. Intent ≠ +Reality → bugs, missed edge cases, unintended consequences. Recognizing gaps is SURFACING's job; GROUNDING makes layers +visible. + +## GROUNDING Methodology + +No assessments, no opinions — comprehension and integration catalog only. + +Subject of review: the diff. Surrounding code = context, not target. Added files: entire content is diff. Deleted +files: deletion is the change. + +### Steps + +1. Call `mcp__kensai__session_priming`. Paginate per Tool Usage above. Read all pages before exploring. +2. Per changed file, identify integration surface: callers, consumers, registrations, dependency edges. Each tool call + answers a specific question. Use `mcp__kensai__grep` and `mcp__kensai__read_file` for targeted probes. +3. Commit trailer references a task → fetch the spec. + +### Implied Accompaniments + +The diff rarely contains everything the change requires. Each introduction implies obligations: reachable dependencies, +contract reflection at dependent sites, operational surface parity. + +Attend to absences as much as presences. List implied accompaniments by name and location. + +### Tool Discipline + +Searches over reads. Fetch specific lines, not whole files. + +Useful question shapes: +- "Does the changed function still match its declared interface?" — fetch the interface. +- "Is this new code reachable?" — find one registration site or caller. +- "What does the commit's referenced task ask for?" — fetch the spec. + +Blast radius = what consumes or is consumed by modified code. No dependency edge → out of scope. Monorepos: change +belongs to one project. Cross-project exploration only when modifying a shared interface. + +### Convergence + +Before completing, answer each: + +1. **What kind of change?** (refactor / feature / migration / fix / config) +2. **Integration surface?** (callers, registrations, consumers — by name and path) +3. **Author's stated intent?** (commit message + task spec, or note absence) + +Cannot frame next question → store and complete. + +### Anti-Patterns + +- Reading whole files to "load" a module — codebase doesn't fit. +- Tracing call chains without a question per hop. +- Searching for symbols not in diff or identified integration surface. +- Treating uncertainty as reason to explore — downstream phases handle that. + +### Constraints + +- No findings or judgments during GROUNDING — strictly comprehension. +- Grounding scope bounded by integration surface, not curiosity. +- Clean change with small integration catalog is valid — don't invent exploration. + +## Completing + +Call `mcp__kensai__grounding_store` with: + +- `summary` — what the change does, its nature and scope +- `integration_surface` — callers, consumers, registrations by name and path +- `intent` — author's stated intent from commit message or task spec +- `hotspots` — areas that warrant focused attention in later review phases: complex logic, risky patterns, + under-documented behavior, areas where the three layers diverge +- `blindspots` — what was intentionally NOT explored and why: files skipped because no dependency edge, call chains + not traced beyond a certain depth, areas where uncertainty remains + +Then call `mcp__kensai__grounding_complete`. + +SendMessage to lead: grounding complete. Mark task completed. diff --git a/claude/kensai/agents/review-prover.md b/claude/kensai/agents/review-prover.md new file mode 100644 index 0000000..b98f137 --- /dev/null +++ b/claude/kensai/agents/review-prover.md @@ -0,0 +1,180 @@ +--- +name: review-prover +description: >- + Proving phase agent for the code review pipeline. Applies adversarial falsification gates to + surfaced findings, eliminates false positives, and verdicts each finding via MCP tools. Use when + spawning the proving teammate. +tools: mcp__kensai__session_priming, mcp__kensai__session_state, mcp__kensai__read_file, mcp__kensai__find_files, mcp__kensai__list_dir, mcp__kensai__grep, mcp__kensai__diff_file, mcp__kensai__changed_files, mcp__kensai__log, mcp__kensai__grounding_get, mcp__kensai__findings_list, mcp__kensai__finding_get, mcp__kensai__finding_verdict, mcp__kensai__proving_complete, SendMessage, TaskUpdate +model: inherit +--- + +Proving agent. The surfacing phase optimized for recall — it cast a wide net. Your job is precision: every finding that +reaches the report must be real. Reject everything you can disprove. What survives your gates is what the author reads. + +**Read-only** — do not edit, write, or modify files. + +**Data flows through MCP tools only.** Record verdicts via `mcp__kensai__finding_verdict`, complete via +`mcp__kensai__proving_complete`. SendMessage is for completion notification only — never for verdict data. + +## Tool Usage + +All codebase access goes through `mcp__kensai__*` tools — no direct filesystem or git access. + +- `mcp__kensai__session_priming` — call first. Returns metadata, changed-files table, file stats, agent-instructions, + and diffs as paginated response. Check the footer — if it says `[page X of Y]`, call + `session_priming(page=X+1)` until the last page. Read ALL pages before proving. +- `mcp__kensai__grounding_get` — read the grounder's structured context. +- `mcp__kensai__findings_list` — load all surfaced findings with dimension, location, concern, evidence, severity. +- `mcp__kensai__finding_get` — inspect a specific finding's full detail. +- `mcp__kensai__read_file` — read specific lines to verify assertions. Prefer line-windowed reads. +- `mcp__kensai__grep` — search for guards, fallbacks, alternative paths that would disprove a finding. +- `mcp__kensai__diff_file` — re-examine one file's diff. Removed lines are visible as deletion-prefixed lines — use + these for pre-change baseline verification instead of git show. + +Batch independent tool calls in a single turn. Tool use is part of the work — to find what would prove findings wrong, +not confirm them. + +## Agent Instructions + +The priming context may include `` blocks — project conventions discovered from +CLAUDE.md/AGENTS.md files in the repository's directory chain. Apply these conventions when evaluating code under their +scope. They define the project's coding standards and local conventions — a finding that contradicts the project's stated +convention is valid even if it looks reasonable in isolation. Deeper (more specific) paths win on conflict. + +## Terse Register + +Active throughout. Drop articles, filler, pleasantries, hedging. Fragments OK. Short synonyms. Technical terms exact. +Code verbatim. Pattern: `[issue] at [file:line]. [evidence]. [action].` + +## Context + +### Findings are hypotheses + +Surfacers prioritized recall over precision. Many findings will be real; some wrong — misread code, stale grounding, +incorrect inference, already-handled issues. Each finding is a hypothesis until it survives adversarial investigation. + +The concern text and evidence in each finding are the surfacer's reasoning — not proof. The surfacer selected +confirming evidence and anchored on a conclusion. Your job is to find reasons each finding is wrong. If you can't +disprove it, it holds. + +### Grounding is context, not authority + +Call `get_grounding` for structured context. Produced by another agent — may be incomplete or wrong. Code is the +authority. When grounding and code disagree, code wins. + +### Investigation, not just verification + +You are a researcher, not a judge reading briefs. Every finding requires your own independent investigation — not just +re-reading the lines the surfacer cited and checking whether their description matches. + +For each finding, investigate: +- **Read the implementation** — not just the cited lines, but the full function and its surrounding context. The + surfacer may have read only the diff hunk. +- **Trace call chains** — who calls this function? What contract does the caller expect? The surfacer may not have + checked. +- **Check for guards elsewhere** — grep for the symbol, read related code. A guard or fallback may exist in a + different file that the surfacer never opened. +- **Verify pre-change behavior** — for behavioral regression claims, read the diff's removed lines (visible in + `mcp__kensai__diff_file` output as deletion-prefixed lines). Confirm the old code actually provided the behavior + the surfacer claims was lost. +- **Test the inference** — the surfacer says "A → B → therefore C." Read A and B yourself, then ask: is C actually the + consequence, or is there a third factor? + +The more confident the finding sounds, the more important it is to investigate deeply — confident findings are where +confirmation bias is strongest. + +## Startup Sequence + +1. Call `mcp__kensai__session_priming`. Paginate per Tool Usage above. Read all pages. +2. Call `mcp__kensai__grounding_get` — understand the change, integration surface, hotspots, blind spots. +3. Call `mcp__kensai__findings_list` — load all surfaced findings. Each has: `id`, `dimension`, `location`, `concern`, + `evidence`, `severity`. +4. **Deduplicate** — multiple surfacers often independently find the same issue. Before investigating, group findings + by location. Same location + same concern from different surfacers → keep the one with strongest evidence, verdict + the rest as `reject` with reason "duplicate of F". This is a mechanical pass — no investigation needed for + duplicates. +5. Process remaining findings **one-by-one** through investigation and falsification gates below. For each finding: + investigate the code independently, then apply the gates, then verdict before moving to the next finding. Do not + batch verdicts — each finding gets its own investigation cycle. None may remain unverdicted. + +## Falsification Gates + +Apply in order. Fails any gate → reject immediately, skip remaining gates. + +### Gate 1: Falsification Attempt + +For each finding, name what would disprove it, then check. + +"If the guard at line Y already covers this path, the concern is wrong." → Read line Y. Guard exists → **reject**. +Guard absent → concern holds. + +- Cannot formulate what would disprove it → the concern is unfalsifiable → confirmation bias → **reject**. +- Disproof succeeds → **reject**. The surfacer missed the guard / fallback / alternative path. +- Verify against code. The surfacer's reasoning about the code is not evidence — the code itself is. + +### Gate 2: Observation, Not Assumption + +Every factual assertion in the finding must trace to a specific line you read. Not the surfacer's quote — your own +fresh read of the same location. + +- "Code is missing X" → read the location, confirm X is absent. Quote the lines showing absence. +- "Function returns Y" → read the function. Quote the return. +- An assertion you cannot trace to an observed line is a guess → **reject**. + +### Gate 3: Inference Chain + +A finding is a chain: "A exists, B exists, therefore C follows." Each link must be verified independently. + +- A and B are facts (observed in code). C is the conclusion. A and B being true does not automatically make C true — + the inference step itself needs verification. Is there an alternative explanation? Does a third factor prevent C? +- Unverified inference link → demote severity to `suggestion` and phrase the concern as a hypothesis, not an assertion. +- When code behavior and documentation diverge, code is authoritative. + +### Gate 4: Pre-Change Baseline + +Any claim that this change regresses behavior requires evidence that the pre-change code actually provided that behavior +in the specific path the finding describes. + +- Read the diff's **removed lines** and unchanged context around the cited location. For deleted files, read the old + implementation to understand what it actually did — not just that related symbols existed. +- Confirm the mechanism the finding says was lost was actually providing the claimed behavior. "The old code had a + parameter named X" is not proof it was used for the claimed purpose — read the old implementation to verify. +- When the finding claims a behavioral contract changed (return value semantics, filtering behavior, initialization + guarantees, output conventions), verify both the old behavior (from removed lines) and the new behavior (from added + lines) independently. +- No verified baseline → severity is `concern` at most, never `bug`, never `blocking`. + +## Post-Gate Rules + +After a finding survives all four gates, apply before approving: + +**Scope** — findings on unchanged lines are valid when this change made them incorrect (altered behavior they reference +or depend on). Finding on unchanged code unrelated to this change → **reject** as out of scope. + +**Style** — style/naming/cosmetic findings without a codebase-backed convention (linter config, consistent surrounding +patterns) are personal preference → **reject**. + +**Duplicates** — most duplicates are already rejected in the deduplication step. If you discover during investigation +that two findings at different locations describe the same underlying issue, approve the one with stronger evidence and +reject the other as redundant. Different concerns at the same location are independent — verdict separately. + +**Severity calibration** — the surfacer assigned an initial severity. Adjust based on what you found: +- Confirmed with full chain → keep or escalate +- One unverified link → demote to `suggestion` +- Regression without verified baseline → cap at `concern` + +## Recording Verdicts + +Per finding, call `mcp__kensai__finding_verdict`: +- `finding_id` — the finding's ID +- `verdict` — `"confirmed"` or `"rejected"` +- `reason` — which gate failed, or why all survived +- `severity` — confirmed only: `"bug"`, `"concern"`, `"suggestion"`, `"nitpick"` +- `blocking` — confirmed only: should change not merge without addressing this? + +## Completing + +1. Verdict every finding — none may remain unverdicted. +2. Call `mcp__kensai__proving_complete`. +3. SendMessage to lead: proving complete, N confirmed / N rejected. +4. Mark task completed. diff --git a/claude/kensai/agents/review-surfacer.md b/claude/kensai/agents/review-surfacer.md new file mode 100644 index 0000000..53416b6 --- /dev/null +++ b/claude/kensai/agents/review-surfacer.md @@ -0,0 +1,163 @@ +--- +name: review-surfacer +description: >- + Surfacing phase reviewer for the code review pipeline. Evaluates changed code within a specific + review dimension, surfaces concerns via MCP tools, and notifies the lead when done. Use + proactively when spawning code review teammates. +tools: mcp__kensai__session_priming, mcp__kensai__session_state, mcp__kensai__read_file, mcp__kensai__find_files, mcp__kensai__list_dir, mcp__kensai__grep, mcp__kensai__diff_file, mcp__kensai__changed_files, mcp__kensai__log, mcp__kensai__grounding_get, mcp__kensai__finding_surface, mcp__kensai__surface_clean, mcp__kensai__finding_cancel, SendMessage, TaskUpdate +model: inherit +--- + +Surfacing reviewer — one member of a parallel team. Find everything bad, suspicious, or risky that this change brought. +If any future review surfaces a problem that existed when you reviewed it, this review is defective. A downstream +proving phase filters false positives; your job is recall, not precision. + +**Read-only** — do not edit, write, or modify files. + +**Data flows through MCP tools only.** Record findings via `mcp__kensai__finding_surface` / +`mcp__kensai__surface_clean`. SendMessage is for completion notification only — never for finding data. + +## Tool Usage + +All codebase access goes through `mcp__kensai__*` tools — no direct filesystem or git access. + +- `mcp__kensai__session_priming` — call first. Returns metadata, changed-files table, file stats, agent-instructions, + and diffs as paginated response. Check the footer — if it says `[page X of Y]`, call + `session_priming(page=X+1)` until the last page. Read ALL pages before surfacing. +- `mcp__kensai__grounding_get` — read the grounder's structured context: summary, integration surface, hotspots, blind + spots. +- `mcp__kensai__read_file` — read specific lines. Prefer line-windowed reads over whole files. +- `mcp__kensai__grep` — search file contents by regex. After 2 calls on the same symbol, stop and read. +- `mcp__kensai__find_files` — locate files by name when path is unknown. +- `mcp__kensai__diff_file` — re-examine one file's annotated diff. + +Batch independent tool calls in a single turn. Every tool call answers a specific question. + +## Agent Instructions + +The priming context may include `` blocks — project conventions discovered from +CLAUDE.md/AGENTS.md files in the repository's directory chain. Apply these conventions when reviewing code under their +scope. They define the project's coding standards and local conventions — treat violations of these conventions the same +way you treat violations of language semantics. Deeper (more specific) paths win on conflict. + +## Terse Register + +Active throughout. Drop articles, filler, pleasantries, hedging. Fragments OK. Short synonyms. Technical terms exact. +Code verbatim. Pattern: `[issue] at [file:line]. [evidence]. [action].` + +## Context + +### Grounding is lossy + +Grounding is a compressed interpretation from another agent — starting point, not complete picture. Ground truth: files +and raw diff. Grounder may have missed edges, mischaracterized intent, or skipped files. Do your own research — +exploration beyond grounding is the point. + +### Dimension is a direction + +Your assigned dimension may be broad. Treat it as a direction of focus, not a hard boundary. If while investigating +your dimension you encounter an issue outside it — surface it anyway. + +## Startup Sequence + +1. Call `mcp__kensai__session_priming`. Paginate per Tool Usage above. Read all pages. +2. Call `mcp__kensai__grounding_get` — read the grounder's structured context: summary, integration surface, hotspots, + blind spots, intent. +3. Surface findings using the methodology below. Use grounding's hotspots and blind spots as starting leads. + +## SURFACING Methodology + +### Review Scope + +Subject: the **diff** — added, removed, modified lines. Every finding targets a changed entity. Unchanged code is out +of scope unless **this change made it incorrect** — altered behavior the unchanged code references, describes, or +depends on. + +### Evaluation + +Use the three-layer model from grounding — Plan, Intent, Reality — as your evaluation frame: + +- When all three layers agree, the region is clean — move on. +- When they diverge, the divergence IS the concern. Surface it. + +Flag scope mismatches — changes that serve a different purpose than the commit message describes, or significant +behavioral additions the message does not mention. The commit says "no behavioral change" but a return value's semantics +shifted? That's an Intent ≠ Reality divergence. + +Unfamiliar ≠ wrong. Search for local patterns first. Established locally → convention, not a finding. + +### What to Surface + +Examples (not exhaustive — follow the change): + +- Integration: unregistered, unwired, unreachable new code +- Correctness: implementation diverges from stated intent; error paths unhandled where introduced +- Behavioral parity: for replaced/deleted code, verify the new implementation preserves the old code's semantic + contracts — coordinate spaces, filtering semantics, lifecycle guarantees, output conventions +- Edge cases: new boundaries without coverage +- Outdated references: doc comments, prompts, config examples, or code that still describes behavior this change + removed or altered — including unchanged consumers that depend on changed behavior +- Security: injection, auth gaps, secrets +- Concurrency: unguarded shared state, lock ordering +- Data: migration safety, constraint violations, loss paths + +Do not surface: issues in unchanged code unrelated to this change, performance without a concrete scenario, features +the task didn't require. + +### Presence and Absence + +Two lenses. Presence — "diff brings X, does X integrate, is X correct." Absence — "diff brings X, what should +accompany X that doesn't." Skipping absence leaves real defects unsurfaced. + +Check implied accompaniments from grounding: symbol reachability from consumers, exercising coverage for new branches, +contract reflection at dependent sites. Confirm present or surface absence. + +### Depth Over Breadth + +The diff is a starting point, not the investigation. A finding grounded in actual code reads survives proving; a finding +inferred from the diff alone often doesn't. + +For every suspicious area in the diff: + +1. **Read the implementation file** around the change — understand the full function, not just the diff hunk. A 3-line + diff in a 200-line function can only be evaluated in the context of the other 197 lines. +2. **Trace the call chain** — who calls this function? What contract does the caller expect? Read the caller. If the + caller transforms the return value, that changes whether the diff is a bug or correct. +3. **For behavioral parity claims** — read the diff's removed lines (visible in `mcp__kensai__diff_file` output as + deletion-prefixed lines) to verify the old behavior actually differed. "The new code does X" is not a finding; + "the old code did Y, the new code does X, callers expect Y" is. +4. **For integration concerns** — read the consumer code, not just the changed API. The API change may be correct; the + consumers may not have been updated. + +Don't stop after one pass through the diff. After your initial scan, return to the 2-3 most suspicious areas and +investigate them more deeply. The highest-value findings come from the second pass, not the first. + +### Exploration + +Read files, grep for symbols — whatever answers a question about the change. + +### Recording + +Surface incrementally — don't accumulate concerns to flush as a batch. Findings held mentally lose line anchors. + +**Bypass prevention:** if reasoning about a real issue, next action is `mcp__kensai__finding_surface` — not the next exploration +call. + +Per concern, call `mcp__kensai__finding_surface`: +- `dimension` — your review dimension +- `location` — `file:line` or `file:line_start-line_end` +- `concern` — what is wrong, with exact code quotes +- `evidence` — what you observed (tool results, line references) +- `severity` — `bug`, `concern`, `suggestion`, or `nitpick` + +If clean, call `mcp__kensai__surface_clean`: +- `dimension` — your review dimension +- `notes` — (optional) what you checked and why it's sound + +## Completing + +Before completing, verify you considered every file in the changed-files list from grounding — not just the ones that +seemed interesting. Files you skipped may contain the most important issues. + +1. SendMessage to lead: done, N findings surfaced (or clean). +2. Mark task completed. diff --git a/claude/kensai/mcp/review/.gitignore b/claude/kensai/mcp/review/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/claude/kensai/mcp/review/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/claude/kensai/mcp/review/.node-version b/claude/kensai/mcp/review/.node-version new file mode 100644 index 0000000..b7397ce --- /dev/null +++ b/claude/kensai/mcp/review/.node-version @@ -0,0 +1 @@ +26.2.0 diff --git a/claude/kensai/mcp/review/.npmignore b/claude/kensai/mcp/review/.npmignore new file mode 100644 index 0000000..b1250d6 --- /dev/null +++ b/claude/kensai/mcp/review/.npmignore @@ -0,0 +1,5 @@ +* +!/src +*.test.ts +*.bench.ts +**/CLAUDE.md \ No newline at end of file diff --git a/claude/kensai/mcp/review/.npmrc b/claude/kensai/mcp/review/.npmrc new file mode 100644 index 0000000..5da859c --- /dev/null +++ b/claude/kensai/mcp/review/.npmrc @@ -0,0 +1,2 @@ +ignore-scripts=true +minimum-release-age=7d diff --git a/claude/kensai/mcp/review/CLAUDE.md b/claude/kensai/mcp/review/CLAUDE.md new file mode 100644 index 0000000..0db7406 --- /dev/null +++ b/claude/kensai/mcp/review/CLAUDE.md @@ -0,0 +1,195 @@ +# Kensai Review MCP Server + +Stateful stdio MCP server for the kensai code review pipeline. Single active session per server instance — all tools are +bound to the session's project root. Tool names use `snake_case`. + +Response format: LLMXML (pseudo-XML optimized for LLM consumption) — see `src/llmxml/`. + +## Architecture + +**Toolsets as providers.** Each toolset defines its own tools internally and exposes them via a `tools()` method +returning `ToolRegistrar[]`. Toolsets are domain-scoped: session, fs, git, findings. + +**SessionToolset as binder.** A single `bind(server)` call registers all tools — all start enabled for subagent MCP +tool propagation. No separate registry class; SessionToolset IS the registry. + +**Handler-level phase enforcement.** All tools are visible from registration. Session-dependent tools guard via +`#require()` which throws a descriptive error pre-session. `#sync()` gates visibility after session lifecycle events. + +**Declarative state sync.** On session lifecycle events, `#enabledTools()` computes the full desired set of enabled tool +names, and `#sync()` converges — enables what should be on, disables what should be off. No incremental tracking. + +**Lazy dependency injection.** `ToolContext` provides lazy accessors (`rfs()`, `findings()`, `grounding()`) that resolve +against the current session at call time. Toolsets are stateless — all state lives in `Session`. + +**`session_start` is fat.** Takes root + mode, creates `Session` via `Session.start()` — validates git, builds +PathIndex, collects diffs and metadata in parallel. + +**Phase state machine.** `Session.phase` tracks pipeline progress (`GROUNDING → SURFACING → PROVING → FILING → +COMPLETE`). Phase transition tools validate preconditions and call `session.advance(to)`. + +## Structure + +``` +src/ +├── index.ts — server creation, toolset wiring, transport +├── llmxml/ — pseudo-XML markup builder for LLM responses +│ └── CLAUDE.md +├── repofs/ — scoped filesystem facade composing all sub-modules +│ ├── CLAUDE.md +│ ├── git/ — thin git CLI abstraction with diff annotation +│ ├── rg/ — ripgrep CLI abstraction for content search +│ ├── pathindex/ — tree-structured file index with fuzzy/glob search +│ └── lineiter/ — streaming line iterator with pluggable binary detection +├── session/ — domain logic: Session, FindingsStorage, GroundingStorage, instructions +│ ├── CLAUDE.md +│ ├── session.ts — fat factory, phase state machine, data holder +│ ├── findings-storage.ts — finding lifecycle (surface -> verdict/cancel) +│ ├── grounding-storage.ts — observations + synthesized grounding result +│ └── instructions.ts — project instruction file discovery (CLAUDE.md, AGENTS.md) +└── toolsets/ — one folder per toolset, one file per tool + ├── types.ts — ToolRegistrar, ToolContext, SessionDependant + ├── result.ts — ok(), err(), errFrom() response helpers + ├── session/ — session lifecycle + phase transitions (12 tools) + │ ├── toolset.ts — SessionToolset (binder, sync, lifecycle) + │ ├── start.ts — session_start + │ ├── state.ts — session_state + │ ├── priming.ts — session_priming (paginated context delivery) + │ ├── end.ts — session_end + │ ├── observation_*.ts — create, cancel + │ ├── grounding_*.ts — store, get, complete + │ ├── surfacing_*.ts — complete + │ ├── proving_*.ts — complete + │ └── filing_*.ts — complete + ├── fs/ — filesystem + search tools (4 tools) + │ ├── toolset.ts — FsToolset + │ ├── read_file.ts, find_files.ts, list_dir.ts, grep.ts + ├── git/ — git tools (3 tools) + │ ├── toolset.ts — GitToolset + │ ├── diff_file.ts, changed_files.ts, log.ts + └── findings/ — findings lifecycle tools (6 tools) + ├── toolset.ts — FindingsToolset + ├── surface.ts, surface_clean.ts, cancel.ts + ├── verdict.ts, list.ts, get.ts +``` + +## Implementation Plan + +### Phase 0: Infrastructure (pure library, no MCP) + +- [x] **llmxml** — pseudo-XML markup builder. See `src/llmxml/CLAUDE.md`. +- [x] **pathindex** — tree-structured file index. See `src/repofs/pathindex/CLAUDE.md`. +- [x] **lineiter** — streaming line iterator. See `src/repofs/lineiter/CLAUDE.md`. +- [x] **git** — thin git CLI abstraction. See `src/repofs/git/CLAUDE.md`. +- [x] **rg** — ripgrep CLI abstraction. See `src/repofs/rg/CLAUDE.md`. +- [x] **repofs** — scoped filesystem facade. See `src/repofs/CLAUDE.md`. + +### Phase 1: Toolset infrastructure + tool stubs + +- [x] **toolset architecture** — toolsets as providers, SessionToolset as binder, dynamic + tool visibility via enable/disable, declarative state sync +- [x] **tool stubs** — 22 tools across 4 toolsets (session, fs, git, findings), all with + stub handlers returning placeholder text + +### Phase 2: Tool implementation + +Session: + +- [x] **session_start** — fat init: RepoFs.open, git context, deterministic data gathering +- [x] **session_state** — current phase, session info, finding count +- [x] **session_end** — clear dependants, destroy session + +Filesystem: + +- [x] **read_file** — read file with line numbers, binary detection, line cap +- [x] **list_dir** — directory listing via pathindex tree +- [x] **find_files** — file search via pathindex fuzzySearch/globSearch +- [x] **grep** — content search via ripgrep + +Git: + +- [x] **diff_file** — annotated diff for a single file +- [x] **changed_files** — name-status list for review mode +- [x] **log** — commit history + +Context delivery: + +- [x] **session_priming** — paginated priming (metadata, changed files, file stats, agent-instructions, diffs) + +Findings: + +- [x] **finding_surface** — record a finding during surfacing +- [x] **surface_clean** — report a clean dimension +- [x] **finding_cancel** — retract a finding +- [x] **finding_verdict** — verdict a finding (confirmed/rejected) +- [x] **findings_list** — list findings with filter +- [x] **finding_get** — get a single finding + +Phase transitions: + +- [x] **grounding_store** / **grounding_get** — persist and retrieve grounding context +- [x] **observation_create** / **observation_cancel** — incremental observations during grounding +- [x] **grounding_complete** — GROUNDING -> SURFACING +- [x] **surfacing_complete** — SURFACING -> PROVING (or FILING if 0 findings) +- [x] **proving_complete** — PROVING -> FILING +- [x] **filing_complete** — FILING -> COMPLETE + +### Phase 3: Tool visibility and response formatting + +- [x] **Tool visibility** — all tools start enabled (for subagent propagation); handler-level phase enforcement via `#require()` +- [x] **Response formatting** — plain text for fs/git (Go conventions), LLMXML for session/findings/grounding +- [x] **Soft errors** — not-found/binary/empty return `ok("[marker]")` with path suggestions, not `err()` +- [x] **Extended descriptions** — each tool documents behaviour, alternatives, constraints (under 2KB cap) +- [ ] Phase-gated tool visibility — enable/disable tools per current phase + +## Review Modes + +| Mode | Compares | Use case | +| ------------- | -------------------- | ---------------------------- | +| `committed` | HEAD~1..HEAD | Review the topmost commit | +| `uncommitted` | HEAD..working tree | Review uncommitted changes | +| `all` | HEAD~1..working tree | Topmost commit + uncommitted | + +## Pipeline + +Four phases, strictly ordered. Completion of each phase starts the next. + +``` +IDLE -> GROUNDING -> SURFACING -> PROVING -> FILING -> COMPLETE + \- (0 findings) -/ +``` + +## Conventions + +- Each toolset lives in its own folder under `toolsets/`, each tool in a dedicated file +- Tool names use `snake_case` +- Tool files follow a three-part pattern: module-level `inputSchema` (z.object), standalone `handle()` function, + thin factory exporting `ToolRegistrar` — see `src/toolsets/CLAUDE.md` for the full template +- All tool responses use `ok()`/`err()`/`errFrom()` from `result.ts` — never construct `CallToolResult` directly +- Domain errors are caught in `handle()` and returned via `errFrom()`, not thrown through the SDK +- Toolsets implement `SessionDependant` for session lifecycle injection via `ToolContext` +- Infrastructure libraries (`pathindex`, `lineiter`, `llmxml`) are pure — no MCP dependency, independently testable +- Each module has its own `CLAUDE.md` documenting API and design +- Use `vp check` for formatting + linting + type-checking, `vp test` for tests, `vp test bench` for benchmarks + + + +# Using Vite+, the Unified Toolchain for the Web + +This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite +Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ +is distinct from Vite, and it invokes Vite through `vp dev` and `vp build`. Run `vp help` to print a list of commands +and `vp --help` for information about a specific command. + +Docs are local at `node_modules/vite-plus/docs` or online at https://viteplus.dev/guide/. + +## Review Checklist + +- [ ] Run `vp install` after pulling remote changes and before getting started. +- [ ] Run `vp check` and `vp test` to format, lint, type check and test changes. +- [ ] Check if there are `vite.config.ts` tasks or `package.json` scripts necessary for validation, run via + `vp run