From 4aa59e9ee6d837a7976c5d82af7b2ce075bffd2b Mon Sep 17 00:00:00 2001 From: prosdev Date: Mon, 30 Mar 2026 16:03:11 -0700 Subject: [PATCH] docs: sweep stale references for Phase 2 cleanup - Update MCP tool count from 9 to 6 everywhere (removed dev_history, dev_plan, dev_gh) - Remove references to deleted CLI commands (dev init, update, stats, dashboard, git, github, plan) - Replace LanceDB/@xenova/transformers references with Antfly/Termite - Rename vectors.lance to vectors in all doc examples - Remove dead tool documentation pages (dev-history.mdx, dev-plan.mdx, dev-github.mdx) - Update .claude/agents for current tool set - Clean examples/README.md of removed tool examples - Update config defaults from 9 to 6 adapters - Remove 3 prompts (analyze-issue, search-github, create-plan) and update tests - Update ARCHITECTURE.md, PLAN.md, vector/README.md for Antfly stack Co-Authored-By: Claude Opus 4.6 (1M context) --- .changeset/stale-docs-cleanup.md | 17 + .claude/agents/bug-investigator.md | 3 +- .claude/agents/logic-reviewer.md | 2 +- .claude/agents/quick-scout.md | 8 +- .claude/agents/security-reviewer.md | 2 +- .claude/da-plans/README.md | 2 +- .../1.1-pure-extractors.md | 177 +++++++++ .../1.2-index-based-analysis.md | 307 +++++++++++++++ .../1.3-cleanup.md | 146 +++++++ .../1.4-agent-usability.md | 235 ++++++++++++ .../1.5-ast-pattern-analysis.md | 292 ++++++++++++++ .../1.6-pagerank-map.md | 360 ++++++++++++++++++ .../phase-1-mcp-tools-improvement/overview.md | 145 +++++++ .../user-stories.md | 83 ++++ ARCHITECTURE.md | 39 +- CLAUDE.md | 4 +- PLAN.md | 24 +- README.md | 79 +--- TROUBLESHOOTING.md | 77 +--- WORKFLOW.md | 32 +- examples/README.md | 149 +------- packages/cli/README.md | 32 +- packages/cli/src/cli.ts | 2 - packages/cli/src/commands/explore.ts | 8 +- packages/cli/src/commands/mcp.ts | 4 +- packages/cli/src/commands/search.ts | 55 ++- packages/cli/src/utils/config.test.ts | 9 +- packages/cli/src/utils/config.ts | 5 +- packages/core/src/indexer/README.md | 18 +- packages/core/src/observability/README.md | 8 +- .../__tests__/observability.test.ts | 12 +- packages/core/src/vector/README.md | 61 ++- packages/dev-agent/README.md | 25 +- packages/mcp-server/CLAUDE_CODE_SETUP.md | 64 +--- packages/mcp-server/CURSOR_SETUP.md | 64 +--- packages/mcp-server/README.md | 59 +-- .../__tests__/inspect-adapter.test.ts | 41 +- .../src/adapters/built-in/inspect-adapter.ts | 24 +- .../src/schemas/__tests__/schemas.test.ts | 10 - packages/mcp-server/src/schemas/index.ts | 1 - .../src/server/__tests__/prompts.test.ts | 84 ++-- packages/mcp-server/src/server/prompts.ts | 143 +------ website/content/docs/cli.mdx | 151 +------- website/content/docs/configuration.mdx | 14 +- website/content/docs/index.mdx | 10 +- website/content/docs/quickstart.mdx | 8 +- website/content/docs/tools/_meta.js | 5 +- website/content/docs/tools/dev-github.mdx | 118 ------ website/content/docs/tools/dev-history.mdx | 124 ------ website/content/docs/tools/dev-map.mdx | 1 - .../{dev-inspect.mdx => dev-patterns.mdx} | 28 +- website/content/docs/tools/dev-plan.mdx | 187 --------- website/content/docs/tools/dev-refs.mdx | 2 +- website/content/docs/tools/index.mdx | 18 +- website/content/index.mdx | 46 +-- website/content/latest-version.ts | 8 +- website/content/updates/index.mdx | 50 ++- 57 files changed, 2106 insertions(+), 1576 deletions(-) create mode 100644 .changeset/stale-docs-cleanup.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.1-pure-extractors.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.2-index-based-analysis.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.3-cleanup.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.4-agent-usability.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.5-ast-pattern-analysis.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.6-pagerank-map.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/overview.md create mode 100644 .claude/da-plans/mcp/phase-1-mcp-tools-improvement/user-stories.md delete mode 100644 website/content/docs/tools/dev-github.mdx delete mode 100644 website/content/docs/tools/dev-history.mdx rename website/content/docs/tools/{dev-inspect.mdx => dev-patterns.mdx} (79%) delete mode 100644 website/content/docs/tools/dev-plan.mdx diff --git a/.changeset/stale-docs-cleanup.md b/.changeset/stale-docs-cleanup.md new file mode 100644 index 0000000..2eedd17 --- /dev/null +++ b/.changeset/stale-docs-cleanup.md @@ -0,0 +1,17 @@ +--- +"@prosdevlab/dev-agent": patch +--- + +### Docs Cleanup & Tool Refinements + +**CLI:** +- Removed `dev explore` — merged `--similar-to` flag into `dev search` +- Search threshold default changed from 0.7 to 0 (RRF scores are much lower than cosine similarity) + +**MCP Tools:** +- Renamed `dev_inspect` → `dev_patterns` (focused on pattern analysis) +- Removed `threshold` parameter from `dev_patterns` +- Removed 3 prompts: `analyze-issue`, `search-github`, `create-plan` + +**Scanner:** +- Extended default exclusions: `.env*`, `*.min.js`, `*.d.ts`, `generated/`, `.terraform/`, `.claude/`, `*.wasm`, `public/`, `static/` diff --git a/.claude/agents/bug-investigator.md b/.claude/agents/bug-investigator.md index a6ded04..fbcc156 100644 --- a/.claude/agents/bug-investigator.md +++ b/.claude/agents/bug-investigator.md @@ -36,8 +36,7 @@ User Command → Commander.js → Core Service → Scanner/Vector/GitHub **Indexing path:** ``` -dev index . → Indexer → Scanner (ts-morph/tree-sitter) → Vector Storage (LanceDB) - → Embedding (@xenova/transformers) → Persisted Index +dev index → Indexer → Scanner (ts-morph/tree-sitter) → Antfly (embed + store + hybrid search) ``` ### Phase 3: Identify Root Cause diff --git a/.claude/agents/logic-reviewer.md b/.claude/agents/logic-reviewer.md index 33fa240..0910358 100644 --- a/.claude/agents/logic-reviewer.md +++ b/.claude/agents/logic-reviewer.md @@ -55,7 +55,7 @@ Every finding MUST include confidence: **HIGH** (verified from code), **MEDIUM** ### Tier 2 (Standard+ Effort) - [ ] Scanner handles malformed source files gracefully (ts-morph, tree-sitter) -- [ ] Vector storage operations handle LanceDB connection failures +- [ ] Vector storage operations handle Antfly connection failures - [ ] MCP adapter responses follow the expected schema - [ ] Event bus listeners cleaned up properly (no memory leaks) - [ ] Subagent coordinator handles agent failures without crashing diff --git a/.claude/agents/quick-scout.md b/.claude/agents/quick-scout.md index f14bca6..740004c 100644 --- a/.claude/agents/quick-scout.md +++ b/.claude/agents/quick-scout.md @@ -35,13 +35,11 @@ Do NOT guess at architectural reasoning or make recommendations. packages/ core/src/ scanner/ # ts-morph (TS/JS) and tree-sitter (Go) analysis - vector/ # LanceDB vector storage + embeddings - services/ # Coordinator, search, GitHub, health, metrics + vector/ # Antfly vector storage + embeddings + services/ # Coordinator, search, health events/ # Event bus system indexer/ # Repository indexing orchestration map/ # Codebase structure mapping - git/ # Git history indexing - metrics/ # Metrics store observability/ # Logger integration cli/src/ @@ -50,7 +48,7 @@ packages/ mcp-server/src/ server/ # MCP server setup - adapters/ # Tool adapters (search, refs, map, history, etc.) + adapters/ # Tool adapters (search, refs, map, inspect, status, health) formatters/ # Compact and verbose output formatters utils/ # Logger diff --git a/.claude/agents/security-reviewer.md b/.claude/agents/security-reviewer.md index 1bb98b8..fe98891 100644 --- a/.claude/agents/security-reviewer.md +++ b/.claude/agents/security-reviewer.md @@ -41,7 +41,7 @@ This agent **NEVER modifies code**. It reports issues for the developer to fix. ### Data Exposure - [ ] Vector storage doesn't leak sensitive file contents in error messages - [ ] GitHub integration doesn't expose private repo data unintentionally -- [ ] Embedding model doesn't send data externally (local-only with @xenova/transformers) +- [ ] Embedding model doesn't send data externally (local-only with Antfly/Termite ONNX) ## Output Format diff --git a/.claude/da-plans/README.md b/.claude/da-plans/README.md index ea4d778..bdb816d 100644 --- a/.claude/da-plans/README.md +++ b/.claude/da-plans/README.md @@ -11,7 +11,7 @@ Implementation deviations are logged at the bottom of each plan file. |-------|-------------|--------| | [Core](core/) | Scanner, vector storage, services, indexer | Phase 1: Merged, Phase 2: Draft (indexing rethink) | | [CLI](cli/) | Command-line interface | Not started | -| [MCP Server](mcp-server/) | Model Context Protocol server + adapters | Phase 1: Draft (blocked on core/phase-1) | +| [MCP Server](mcp/) | Model Context Protocol server + adapters | Phase 1: Draft (tools improvement) | | [Subagents](subagents/) | Coordinator, explorer, planner, GitHub agents | Not started | | [Integrations](integrations/) | Claude Code, VS Code, Cursor | Not started | | [Logger](logger/) | @prosdevlab/kero centralized logging | Not started | diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.1-pure-extractors.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.1-pure-extractors.md new file mode 100644 index 0000000..40f4db6 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.1-pure-extractors.md @@ -0,0 +1,177 @@ +# Part 1.1: Extract Pure Pattern Analyzers + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Extract the pattern analysis logic from private methods into exported pure functions that are testable without file I/O. + +**User stories:** US-1, US-3 + +**Files:** +- Modify: `packages/core/src/services/pattern-analysis-service.ts` +- Modify: `packages/core/src/services/__tests__/pattern-analysis-service.test.ts` + +--- + +## Task 1: Write tests for pure extraction functions + +- [ ] **Step 1: Add test block for extractImportStyleFromContent** + +```typescript +// In pattern-analysis-service.test.ts, add: +import { + extractImportStyleFromContent, + extractErrorHandlingFromContent, + extractTypeCoverageFromSignatures, +} from '../pattern-analysis-service'; + +describe('Pure Pattern Extractors', () => { + describe('extractImportStyleFromContent', () => { + it('should detect ESM imports', () => { + const content = 'import { foo } from "./bar";\nimport * as baz from "baz";'; + const result = extractImportStyleFromContent(content); + expect(result).toEqual({ style: 'esm', importCount: 2 }); + }); + + it('should detect CJS requires', () => { + const content = 'const foo = require("bar");\nconst baz = require("baz");'; + const result = extractImportStyleFromContent(content); + expect(result).toEqual({ style: 'cjs', importCount: 2 }); + }); + + it('should detect mixed imports', () => { + const content = 'import { foo } from "./bar";\nconst baz = require("baz");'; + const result = extractImportStyleFromContent(content); + expect(result).toEqual({ style: 'mixed', importCount: 2 }); + }); + + it('should return unknown for no imports', () => { + const content = 'const x = 1;'; + const result = extractImportStyleFromContent(content); + expect(result).toEqual({ style: 'unknown', importCount: 0 }); + }); + }); + + describe('extractErrorHandlingFromContent', () => { + it('should detect throw style', () => { + const content = 'throw new Error("oops");\nthrow new TypeError("bad");'; + const result = extractErrorHandlingFromContent(content); + expect(result.style).toBe('throw'); + }); + + it('should return unknown for no error handling', () => { + const content = 'const x = 1;'; + const result = extractErrorHandlingFromContent(content); + expect(result.style).toBe('unknown'); + }); + }); + + describe('extractTypeCoverageFromSignatures', () => { + it('should detect full coverage', () => { + const signatures = [ + 'function foo(x: string): number', + 'function bar(y: boolean): void', + ]; + const result = extractTypeCoverageFromSignatures(signatures); + expect(result.coverage).toBe('full'); + expect(result.annotatedCount).toBe(2); + expect(result.totalCount).toBe(2); + }); + + it('should detect partial coverage', () => { + const signatures = [ + 'function foo(x: string): number', + 'function bar(y)', + ]; + const result = extractTypeCoverageFromSignatures(signatures); + expect(result.coverage).toBe('partial'); + }); + + it('should return none for empty', () => { + const result = extractTypeCoverageFromSignatures([]); + expect(result.coverage).toBe('none'); + }); + }); +}); +``` + +- [ ] **Step 2: Run tests to verify they fail** + +Run: `pnpm test -- packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +Expected: FAIL — functions not exported + +--- + +## Task 2: Implement and export pure functions + +- [ ] **Step 1: Add exported pure functions to pattern-analysis-service.ts** + +Add before the class definition: + +```typescript +/** + * Extract import style from raw file content. Pure function — no I/O. + */ +export function extractImportStyleFromContent(content: string): ImportStylePattern { + const esmImports = content.match(/^import\s/gm) || []; + const cjsImports = content.match(/require\s*\(/g) || []; + const hasESM = esmImports.length > 0; + const hasCJS = cjsImports.length > 0; + + if (!hasESM && !hasCJS) return { style: 'unknown', importCount: 0 }; + + const importCount = esmImports.length + cjsImports.length; + const style: ImportStylePattern['style'] = + hasESM && hasCJS ? 'mixed' : hasESM ? 'esm' : 'cjs'; + return { style, importCount }; +} + +/** + * Extract error handling pattern from raw file content. Pure function — no I/O. + */ +export function extractErrorHandlingFromContent(content: string): ErrorHandlingPattern { + const counts = { + throw: [...content.matchAll(/throw\s+new\s+\w*Error/g)].length, + result: [...content.matchAll(/Result<|{\s*ok:\s*(true|false)/g)].length, + errorReturn: [...content.matchAll(/\)\s*:\s*\([^)]*,\s*error\)/g)].length, + }; + const total = counts.throw + counts.result + counts.errorReturn; + if (total === 0) return { style: 'unknown', examples: [] }; + + const max = Math.max(counts.throw, counts.result, counts.errorReturn); + const hasMultiple = Object.values(counts).filter((c) => c > 0).length > 1; + let style: ErrorHandlingPattern['style'] = 'unknown'; + if (hasMultiple) style = 'mixed'; + else if (counts.throw === max) style = 'throw'; + else if (counts.result === max) style = 'result'; + else if (counts.errorReturn === max) style = 'error-return'; + return { style, examples: [] }; +} + +/** + * Extract type coverage from function/method signatures. Pure function — no I/O. + */ +export function extractTypeCoverageFromSignatures(signatures: string[]): TypeAnnotationPattern { + if (signatures.length === 0) return { coverage: 'none', annotatedCount: 0, totalCount: 0 }; + + const annotated = signatures.filter((sig) => /(\)|=>)\s*:\s*\w+/.test(sig)); + const ratio = annotated.length / signatures.length; + let coverage: TypeAnnotationPattern['coverage']; + if (ratio >= 0.9) coverage = 'full'; + else if (ratio >= 0.5) coverage = 'partial'; + else if (ratio > 0) coverage = 'minimal'; + else coverage = 'none'; + return { coverage, annotatedCount: annotated.length, totalCount: signatures.length }; +} +``` + +- [ ] **Step 2: Run tests to verify they pass** + +Run: `pnpm test -- packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +Expected: ALL PASS (new + existing) + +- [ ] **Step 3: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-service.ts packages/core/src/services/__tests__/pattern-analysis-service.test.ts +git commit -m "refactor(core): extract pure pattern analyzers for testability" +``` diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.2-index-based-analysis.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.2-index-based-analysis.md new file mode 100644 index 0000000..1355c2f --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.2-index-based-analysis.md @@ -0,0 +1,307 @@ +# Part 1.2: Index-Based Pattern Analysis + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Add `getDocsByFilePath` to VectorStorage, replace `scanRepository()` with index reads, wire VectorStorage into the pattern service. + +**User stories:** US-1, US-2, US-3, US-4 + +**Files:** +- Modify: `packages/core/src/services/pattern-analysis-types.ts` +- Modify: `packages/core/src/vector/index.ts` (add `getDocsByFilePath`) +- Modify: `packages/core/src/services/pattern-analysis-service.ts` +- Modify: `packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/inspect-adapter.ts` +- Modify: `packages/mcp-server/bin/dev-agent-mcp.ts` + +--- + +## Task 1: Add VectorStorage config + getDocsByFilePath + +- [ ] **Step 1: Update PatternAnalysisConfig** + +In `packages/core/src/services/pattern-analysis-types.ts`: + +```typescript +import type { VectorStorage } from '../vector/index.js'; + +export interface PatternAnalysisConfig { + repositoryPath: string; + vectorStorage?: VectorStorage; +} +``` + +- [ ] **Step 2: Add getDocsByFilePath to VectorStorage** + +In `packages/core/src/vector/index.ts`, add method to VectorStorage class: + +```typescript +/** + * Get indexed documents for specific file paths. + * Uses getAll with capped limit + client-side exact path filter. + * More reliable than BM25 search which tokenizes paths unpredictably. + */ +async getDocsByFilePath(filePaths: string[]): Promise> { + this.assertReady(); + const pathSet = new Set(filePaths); + const allDocs = await this.getAll({ limit: 5000 }); + + if (allDocs.length >= 5000) { + console.error('[dev-agent] Warning: getDocsByFilePath hit 5000 doc limit. Some files may be missing.'); + } + + const byFile = new Map(); + for (const doc of allDocs) { + const docPath = doc.metadata.path as string; + if (pathSet.has(docPath)) { + if (!byFile.has(docPath)) byFile.set(docPath, []); + byFile.get(docPath)!.push(doc); + } + } + return byFile; +} +``` + +- [ ] **Step 3: Write test for getDocsByFilePath** + +```typescript +// In a new or existing vector test file +describe('getDocsByFilePath', () => { + it('should return docs grouped by file path', async () => { + // This requires a mock or integration test with Antfly + // For unit test: mock getAll to return known docs + }); + + it('should return empty map for unknown paths', async () => { + // getAll returns docs, none match requested paths + }); +}); +``` + +- [ ] **Step 4: Verify build** + +Run: `pnpm build` +Expected: PASS + +- [ ] **Step 5: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-types.ts packages/core/src/vector/index.ts +git commit -m "feat(core): add getDocsByFilePath to VectorStorage" +``` + +--- + +## Task 2: Implement analyzeFileFromIndex + +- [ ] **Step 1: Write tests** + +```typescript +import type { SearchResult } from '@prosdevlab/dev-agent-core'; + +describe('analyzeFileFromIndex', () => { + it('should extract patterns from indexed metadata', async () => { + const filePath = 'src/test.ts'; + await fs.mkdir(path.join(tempDir, 'src'), { recursive: true }); + await fs.writeFile( + path.join(tempDir, 'src/test.ts'), + 'import { foo } from "./bar";\n\nexport function test(): string {\n throw new Error("oops");\n return "hello";\n}\n' + ); + + const indexedDocs: SearchResult[] = [{ + id: 'src/test.ts:test:3', score: 0.9, + metadata: { + path: 'src/test.ts', type: 'function', name: 'test', + signature: 'function test(): string', exported: true, + }, + }]; + + const result = await service.analyzeFileFromIndex(filePath, indexedDocs); + expect(result.importStyle.style).toBe('esm'); + expect(result.typeAnnotations.coverage).toBe('full'); + expect(result.fileSize.lines).toBe(7); + expect(result.errorHandling.style).toBe('throw'); + }); + + it('should handle files with no indexed docs', async () => { + await fs.writeFile(path.join(tempDir, 'empty.ts'), 'const x = 1;\n'); + const result = await service.analyzeFileFromIndex('empty.ts', []); + expect(result.typeAnnotations.coverage).toBe('none'); + }); + + it('should handle deleted files gracefully (ENOENT)', async () => { + const result = await service.analyzeFileFromIndex('nonexistent.ts', []); + expect(result.fileSize.lines).toBe(0); + expect(result.fileSize.bytes).toBe(0); + expect(result.importStyle.style).toBe('unknown'); + expect(result.errorHandling.style).toBe('unknown'); + }); +}); +``` + +- [ ] **Step 2: Implement analyzeFileFromIndex** + +```typescript +import type { SearchResult } from '../vector/types.js'; + +async analyzeFileFromIndex( + filePath: string, + indexedDocs: SearchResult[] +): Promise { + const fullPath = path.join(this.config.repositoryPath, filePath); + + let content = ''; + let bytes = 0; + let lines = 0; + try { + const [fileContent, stat] = await Promise.all([ + fs.readFile(fullPath, 'utf-8'), + fs.stat(fullPath), + ]); + content = fileContent; + bytes = stat.size; + lines = content.split('\n').length; + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error; + } + + const testing = await this.analyzeTesting(filePath); + const signatures = indexedDocs + .filter((d) => d.metadata.type === 'function' || d.metadata.type === 'method') + .map((d) => (d.metadata.signature as string) || '') + .filter(Boolean); + + return { + fileSize: { lines, bytes }, + testing, + importStyle: extractImportStyleFromContent(content), + errorHandling: extractErrorHandlingFromContent(content), + typeAnnotations: extractTypeCoverageFromSignatures(signatures), + }; +} +``` + +- [ ] **Step 3: Run tests, verify pass** + +Run: `pnpm test -- packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +Expected: ALL PASS + +- [ ] **Step 4: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-service.ts packages/core/src/services/__tests__/pattern-analysis-service.test.ts +git commit -m "feat(core): add index-based pattern analysis with ENOENT handling" +``` + +--- + +## Task 3: Wire index path into comparePatterns + +- [ ] **Step 1: Write test for fast path** + +```typescript +describe('comparePatterns with vectorStorage', () => { + it('should use index path when vectorStorage is provided', async () => { + await fs.mkdir(path.join(tempDir, 'src'), { recursive: true }); + await fs.writeFile(path.join(tempDir, 'src/target.ts'), + 'import { x } from "./y";\nexport function target(): string { throw new Error("oops"); }\n'); + await fs.writeFile(path.join(tempDir, 'src/similar.ts'), + 'import { a } from "./b";\nexport function similar(): number { throw new Error("bad"); }\n'); + + const mockGetDocsByFilePath = vi.fn().mockResolvedValue( + new Map([ + ['src/target.ts', [{ id: 'src/target.ts:target:2', score: 0.9, + metadata: { path: 'src/target.ts', type: 'function', signature: 'function target(): string' } }]], + ['src/similar.ts', [{ id: 'src/similar.ts:similar:2', score: 0.9, + metadata: { path: 'src/similar.ts', type: 'function', signature: 'function similar(): number' } }]], + ]) + ); + + const mockVectorStorage = { getDocsByFilePath: mockGetDocsByFilePath } as any; + const serviceWithIndex = new PatternAnalysisService({ + repositoryPath: tempDir, + vectorStorage: mockVectorStorage, + }); + + const result = await serviceWithIndex.comparePatterns('src/target.ts', ['src/similar.ts']); + expect(mockGetDocsByFilePath).toHaveBeenCalledWith(['src/target.ts', 'src/similar.ts']); + expect(result.importStyle).toBeDefined(); + expect(result.typeAnnotations).toBeDefined(); + }); + + it('should handle empty results from index gracefully', async () => { + await fs.writeFile(path.join(tempDir, 'solo.ts'), 'const x = 1;\n'); + + const mockGetDocsByFilePath = vi.fn().mockResolvedValue(new Map()); + const mockVectorStorage = { getDocsByFilePath: mockGetDocsByFilePath } as any; + const serviceWithIndex = new PatternAnalysisService({ + repositoryPath: tempDir, + vectorStorage: mockVectorStorage, + }); + + const result = await serviceWithIndex.comparePatterns('solo.ts', []); + expect(result.fileSize.yourFile).toBeGreaterThan(0); + }); +}); +``` + +- [ ] **Step 2: Update comparePatterns to use getDocsByFilePath** + +```typescript +async comparePatterns(targetFile: string, similarFiles: string[]): Promise { + const allFiles = [targetFile, ...similarFiles]; + let targetPatterns: FilePatterns; + let similarPatterns: FilePatterns[]; + + if (this.config.vectorStorage) { + // FAST PATH: read from Antfly index via exact path match + const docsByFile = await this.config.vectorStorage.getDocsByFilePath(allFiles); + + targetPatterns = await this.analyzeFileFromIndex(targetFile, docsByFile.get(targetFile) || []); + similarPatterns = await Promise.all( + similarFiles.map((f) => this.analyzeFileFromIndex(f, docsByFile.get(f) || [])) + ); + } else { + // FALLBACK: scan files (for tests/offline) + const batchResult = await scanRepository({ + repoRoot: this.config.repositoryPath, + include: allFiles, + }); + const docsByFile = new Map(); + for (const doc of batchResult.documents) { + const file = doc.metadata.file; + if (!docsByFile.has(file)) docsByFile.set(file, []); + docsByFile.get(file)!.push(doc); + } + targetPatterns = await this.analyzeFileWithDocs(targetFile, docsByFile.get(targetFile) || []); + similarPatterns = await Promise.all( + similarFiles.map((f) => this.analyzeFileWithDocs(f, docsByFile.get(f) || [])) + ); + } + + return { + fileSize: this.compareFileSize(targetPatterns.fileSize, similarPatterns.map((s) => s.fileSize)), + testing: this.compareTesting(targetPatterns.testing, similarPatterns.map((s) => s.testing)), + importStyle: this.compareImportStyle(targetPatterns.importStyle, similarPatterns.map((s) => s.importStyle)), + errorHandling: this.compareErrorHandling(targetPatterns.errorHandling, similarPatterns.map((s) => s.errorHandling)), + typeAnnotations: this.compareTypeAnnotations(targetPatterns.typeAnnotations, similarPatterns.map((s) => s.typeAnnotations)), + }; +} +``` + +- [ ] **Step 3: Wire VectorStorage into InspectAdapter and MCP entry point** + +In `inspect-adapter.ts`, add `vectorStorage?: VectorStorage` to config, pass to PatternAnalysisService. +In `dev-agent-mcp.ts`, pass `indexer.getVectorStorage()` to InspectAdapter. + +- [ ] **Step 4: Run full test suite** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 5: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-service.ts packages/core/src/services/__tests__/pattern-analysis-service.test.ts packages/mcp-server/src/adapters/built-in/inspect-adapter.ts packages/mcp-server/bin/dev-agent-mcp.ts +git commit -m "feat(core,mcp): use Antfly index for pattern analysis (10-30x faster)" +``` diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.3-cleanup.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.3-cleanup.md new file mode 100644 index 0000000..5906564 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.3-cleanup.md @@ -0,0 +1,146 @@ +# Part 1.3: Cleanup — Dead Code, Health GitHub Removal, Missing Tests + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Remove duplicate private methods, clean up GitHub references from health adapter (code + description), and add missing edge case tests. + +**User stories:** US-7 + +**Files:** +- Modify: `packages/core/src/services/pattern-analysis-service.ts` +- Modify: `packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/health-adapter.ts` +- Modify: `packages/mcp-server/src/adapters/__tests__/health-adapter.test.ts` + +--- + +## Task 1: Update analyzeFileWithDocs + remove dead methods + +- [ ] **Step 1: Rewrite analyzeFileWithDocs to use pure functions** + +```typescript +private async analyzeFileWithDocs(filePath: string, documents: Document[]): Promise { + const fullPath = path.join(this.config.repositoryPath, filePath); + const [content, stat, testing] = await Promise.all([ + fs.readFile(fullPath, 'utf-8'), + fs.stat(fullPath), + this.analyzeTesting(filePath), + ]); + + const signatures = documents + .filter((d) => d.type === 'function' || d.type === 'method') + .map((d) => d.metadata.signature || '') + .filter(Boolean); + + return { + fileSize: { lines: content.split('\n').length, bytes: stat.size }, + testing, + importStyle: extractImportStyleFromContent(content), + errorHandling: extractErrorHandlingFromContent(content), + typeAnnotations: extractTypeCoverageFromSignatures(signatures), + }; +} +``` + +- [ ] **Step 2: Delete unused private methods** + +Remove: `analyzeImportsFromFile`, `analyzeImportsFromContent`, `analyzeErrorHandling`, `analyzeTypes`. + +- [ ] **Step 3: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 4: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-service.ts +git commit -m "refactor(core): remove duplicate pattern analyzers, use pure functions" +``` + +--- + +## Task 2: Add missing edge case tests + +- [ ] **Step 1: Add minimal coverage test** + +```typescript +it('should detect minimal type coverage', () => { + const signatures = [ + 'function foo(x: string): number', + 'function bar(y)', + 'function baz(z)', + 'function qux(w)', + 'function quux(v)', + ]; + const result = extractTypeCoverageFromSignatures(signatures); + expect(result.coverage).toBe('minimal'); + expect(result.annotatedCount).toBe(1); + expect(result.totalCount).toBe(5); +}); +``` + +- [ ] **Step 2: Add result-style error handling test** + +```typescript +it('should detect result style error handling', () => { + const content = 'function foo(): Result { return { ok: true }; }'; + const result = extractErrorHandlingFromContent(content); + expect(result.style).toBe('result'); +}); + +it('should detect mixed error handling', () => { + const content = 'throw new Error("oops");\nfunction foo(): Result {}'; + const result = extractErrorHandlingFromContent(content); + expect(result.style).toBe('mixed'); +}); +``` + +- [ ] **Step 3: Run tests** + +Run: `pnpm test -- packages/core/src/services/__tests__/pattern-analysis-service.test.ts` +Expected: ALL PASS + +- [ ] **Step 4: Commit** + +```bash +git add packages/core/src/services/__tests__/pattern-analysis-service.test.ts +git commit -m "test(core): add missing edge case tests for pattern extractors" +``` + +--- + +## Task 3: Remove GitHub from health adapter + +Remove `githubStatePath`, `checkGitHubIndex()`, `githubIndex` from the health adapter code — not just the description. + +- [ ] **Step 1: Update health adapter** + +In `packages/mcp-server/src/adapters/built-in/health-adapter.ts`: +- Remove `githubStatePath` from `HealthCheckConfig` interface +- Remove `checkGitHubIndex()` private method +- Remove `githubIndex` from `HealthStatus` return type +- Remove the GitHub check call from the `execute()` method +- Update the tool description: + +```typescript +description: + 'Check the health status of the dev-agent MCP server and its dependencies ' + + '(Antfly vector storage, repository access)', +``` + +- [ ] **Step 2: Update health adapter tests** + +Remove any tests that reference `githubIndex` or `checkGitHubIndex`. Update test expectations for the new output shape. + +- [ ] **Step 3: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 4: Commit** + +```bash +git add packages/mcp-server/src/adapters/built-in/health-adapter.ts packages/mcp-server/src/adapters/__tests__/health-adapter.test.ts +git commit -m "fix(mcp): remove stale GitHub code from health adapter" +``` diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.4-agent-usability.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.4-agent-usability.md new file mode 100644 index 0000000..81d52f5 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.4-agent-usability.md @@ -0,0 +1,235 @@ +# Part 1.4: MCP Agent Usability + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Make all MCP tools more effective for AI agents: merge overlapping tools, add error recovery guidance, improve parameter naming, and add structured output. + +**User stories:** US-5, US-8, US-9, US-10 + +**Files:** +- Modify: `packages/mcp-server/src/adapters/built-in/status-adapter.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/health-adapter.ts` (remove) +- Modify: `packages/mcp-server/src/adapters/built-in/index.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/inspect-adapter.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/search-adapter.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/refs-adapter.ts` +- Modify: `packages/mcp-server/src/adapters/built-in/map-adapter.ts` +- Modify: `packages/mcp-server/bin/dev-agent-mcp.ts` +- Modify: various test files + +--- + +## Task 1: Merge dev_health into dev_status + +`dev_status` already has `section: "health"` option. `dev_health` is redundant. Merge health checks into status and remove the separate health adapter. + +- [ ] **Step 1: Move health check logic into StatusAdapter** + +In `status-adapter.ts`, add the health check as a section option. The StatusAdapter already supports `section: "summary" | "repo" | "indexes" | "health"`. Verify the `health` section calls the same checks that HealthAdapter did. + +If the StatusAdapter's health section is a stub, implement it by importing the health check logic from HealthAdapter before deleting it. + +- [ ] **Step 2: Remove HealthAdapter registration** + +In `packages/mcp-server/bin/dev-agent-mcp.ts`: +- Remove `HealthAdapter` import +- Remove `healthAdapter` construction +- Remove `healthAdapter` from the adapter registration list + +In `packages/mcp-server/src/adapters/built-in/index.ts`: +- Remove `HealthAdapter` export + +- [ ] **Step 3: Update tests** + +- Remove `health-adapter.test.ts` or convert to test `dev_status section="health"` +- Update `status-adapter.test.ts` to verify health section returns expected data + +- [ ] **Step 4: Update tool count in docs** + +Search for "6 tools" or "6 MCP" and update to "5 tools" / "5 MCP" in: +- CLAUDE.md +- README.md +- Website docs + +- [ ] **Step 5: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 6: Commit** + +```bash +git add -A +git commit -m "refactor(mcp): merge dev_health into dev_status, reduce to 5 tools" +``` + +--- + +## Task 2: Add `suggestion` field to all adapter error paths + +Currently only `InspectAdapter` returns `suggestion` on errors. Add it to all adapters so AI agents can recover. + +- [ ] **Step 1: Audit all adapter error returns** + +Check each adapter's `execute()` catch blocks and error returns: +- `search-adapter.ts` — add suggestion: "Check query syntax" or "Run dev index if no results" +- `refs-adapter.ts` — add suggestion: "Verify the function name exists" or "Try dev_search first" +- `map-adapter.ts` — add suggestion: "Run dev index first" or "Try a lower depth" +- `status-adapter.ts` — add suggestion: "Run dev setup" or "Check Antfly server" + +- [ ] **Step 2: Update error returns with suggestions** + +Pattern for each adapter: + +```typescript +return { + success: false, + error: { + code: String(ErrorCode.ToolExecutionError), + message: error instanceof Error ? error.message : 'Tool execution failed', + recoverable: true, + suggestion: 'Specific actionable guidance for the AI agent', + }, +}; +``` + +- [ ] **Step 3: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS (error returns are not asserted for suggestion field in most tests) + +- [ ] **Step 4: Commit** + +```bash +git add packages/mcp-server/src/adapters/built-in/ +git commit -m "feat(mcp): add error recovery suggestions to all tool adapters" +``` + +--- + +## Task 3: Rename dev_patterns `query` → `filePath` + +The `query` parameter misleads LLMs into passing natural language. Rename to `filePath`. + +- [ ] **Step 1: Update InspectAdapter tool definition** + +```typescript +inputSchema: { + type: 'object', + properties: { + filePath: { + type: 'string', + description: 'File path to analyze (e.g., "src/auth/middleware.ts")', + }, + // ... rest unchanged + }, + required: ['filePath'], +}, +``` + +- [ ] **Step 2: Update execute() to read filePath** + +```typescript +const { filePath, limit, format } = validation.data; +``` + +Update `InspectArgsSchema` in `packages/mcp-server/src/schemas/index.ts`: + +```typescript +export const InspectArgsSchema = z + .object({ + filePath: z.string().min(1, 'filePath must be a non-empty file path'), + limit: z.number().int().min(1).max(50).default(10), + format: FormatSchema.default('compact'), + }) + .strict(); +``` + +- [ ] **Step 3: Update description with negative guidance** + +```typescript +description: + 'Analyze coding patterns in a file against similar code in the codebase. ' + + 'Compares import style, error handling, type coverage, test coverage, and file size. ' + + 'Use for code reviews and consistency checks. ' + + 'NOT for finding code (use dev_search) or tracing calls (use dev_refs).', +``` + +- [ ] **Step 4: Update tests** + +In `inspect-adapter.test.ts`, replace all `query:` with `filePath:` in test args. +In `schemas.test.ts`, update InspectArgsSchema tests. + +- [ ] **Step 5: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 6: Commit** + +```bash +git add packages/mcp-server/src/adapters/built-in/inspect-adapter.ts packages/mcp-server/src/schemas/ packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts +git commit -m "feat(mcp): rename dev_patterns query to filePath, add negative guidance" +``` + +--- + +## Task 4: Add JSON output format to dev_patterns + +Markdown output wastes ~2000 tokens. JSON is compact and machine-parseable. + +- [ ] **Step 1: Add json format option to tool definition** + +```typescript +format: { + type: 'string', + enum: ['compact', 'verbose', 'json'], + description: 'Output format: "compact" (default), "verbose" for details, "json" for structured data', + default: this.defaultFormat, +}, +``` + +- [ ] **Step 2: Add JSON format handler in execute()** + +When `format === 'json'`, return `JSON.stringify(patternComparison)` instead of the markdown formatters: + +```typescript +if (format === 'json') { + return { + success: true, + data: JSON.stringify(patternComparison, null, 2), + metadata: { format: 'json', similar_files_count: similarFilesCount, patterns_analyzed: 5 }, + }; +} +``` + +Where `patternComparison` is the raw `PatternComparison` object from `comparePatterns()`. + +- [ ] **Step 3: Update schema** + +In `InspectArgsSchema`, update FormatSchema or add `'json'` to the enum. + +- [ ] **Step 4: Add test** + +```typescript +it('should return JSON when format is json', async () => { + // ... setup mocks + const result = await adapter.execute({ filePath: 'test.ts', format: 'json' }, mockContext); + expect(result.success).toBe(true); + const parsed = JSON.parse(result.data as string); + expect(parsed.importStyle).toBeDefined(); + expect(parsed.fileSize).toBeDefined(); +}); +``` + +- [ ] **Step 5: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS + +- [ ] **Step 6: Commit** + +```bash +git add packages/mcp-server/src/adapters/built-in/inspect-adapter.ts packages/mcp-server/src/schemas/ packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts +git commit -m "feat(mcp): add JSON output format to dev_patterns for token efficiency" +``` diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.5-ast-pattern-analysis.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.5-ast-pattern-analysis.md new file mode 100644 index 0000000..9e4a1a9 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.5-ast-pattern-analysis.md @@ -0,0 +1,292 @@ +# Part 1.5: AST-Based Pattern Analysis via ast-grep + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Replace regex-based pattern detection in `dev_patterns` with ast-grep's tree-sitter AST matching for significantly more accurate analysis. + +**User stories:** US-11 + +**Inspiration:** [ast-grep](https://github.com/ast-grep/ast-grep) — MIT licensed, structural code search using tree-sitter AST patterns. Has its own [MCP server](https://github.com/ast-grep/ast-grep-mcp) validating the approach. + +**Files:** +- Create: `packages/core/src/services/ast-patterns.ts` +- Create: `packages/core/src/services/__tests__/ast-patterns.test.ts` +- Modify: `packages/core/src/services/pattern-analysis-service.ts` + +--- + +## Why ast-grep over regex + +Current regex approach misses common patterns: + +| Pattern | Regex detects | ast-grep detects | +|---------|--------------|-----------------| +| `try { } catch (e) { }` | No | Yes — structural match | +| `promise.catch(handler)` | No | Yes — method call pattern | +| Custom error classes | No | Yes — class extends Error | +| Async error handling | No | Yes — await in try/catch | +| Type annotations on arrow functions | Fragile | Yes — AST node type | + +ast-grep is a CLI tool (`npm install -g @ast-grep/cli`) that we shell out to. No need to import its internals — just call it with YAML rules and parse JSON output. + +--- + +## Task 1: Add ast-grep as optional dependency + +- [ ] **Step 1: Check if ast-grep is available** + +```typescript +// In packages/core/src/services/ast-patterns.ts + +import { execFileSync, execSync } from 'node:child_process'; +import * as fs from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; + +let _astGrepAvailable: boolean | null = null; + +/** + * Check if ast-grep CLI is available. Memoized per process. + */ +export function hasAstGrep(): boolean { + if (_astGrepAvailable !== null) return _astGrepAvailable; + try { + execSync('ast-grep --version', { stdio: 'pipe', timeout: 5000 }); + _astGrepAvailable = true; + } catch { + _astGrepAvailable = false; + } + return _astGrepAvailable; +} +``` + +- [ ] **Step 2: Write test** + +```typescript +describe('ast-grep integration', () => { + it('should detect if ast-grep is available', () => { + // This test passes regardless — just checks the function works + const available = hasAstGrep(); + expect(typeof available).toBe('boolean'); + }); +}); +``` + +- [ ] **Step 3: Commit** + +```bash +git add packages/core/src/services/ast-patterns.ts packages/core/src/services/__tests__/ast-patterns.test.ts +git commit -m "feat(core): add ast-grep availability check" +``` + +--- + +## Task 2: Define AST pattern rules for error handling + +ast-grep uses YAML rules. We define patterns for the 5 categories we analyze. + +- [ ] **Step 1: Create error handling patterns** + +```typescript +// In ast-patterns.ts + +export interface AstPatternResult { + file: string; + matches: Array<{ + rule: string; + line: number; + text: string; + }>; +} + +/** + * Run ast-grep with a pattern rule on a file. Returns matches. + * Pure function over CLI — no state. + */ +/** + * Run ast-grep with a YAML rule on a file. Returns matches. + * + * IMPORTANT: `--rule` expects a file path, not inline YAML. + * We write a temp file for each rule invocation. + * Uses execFileSync (array args) to avoid shell injection via file paths. + */ +export function runAstGrepRule( + filePath: string, + ruleYaml: string, + repositoryPath: string +): AstPatternResult { + try { + const tmpRule = path.join(os.tmpdir(), `ast-grep-rule-${Date.now()}.yml`); + fs.writeFileSync(tmpRule, ruleYaml); + try { + const output = execFileSync( + 'ast-grep', ['scan', '--rule', tmpRule, '--json', filePath], + { cwd: repositoryPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 10000 } + ); + const matches = JSON.parse(output || '[]'); + return { file: filePath, matches }; + } finally { + fs.unlinkSync(tmpRule); + } + } catch { + return { file: filePath, matches: [] }; + } +} + +/** Built-in rules for error handling detection */ +export const ERROR_HANDLING_RULES = { + tryCatch: ` +rule: + kind: try_statement +`, + promiseCatch: ` +rule: + pattern: $PROMISE.catch($HANDLER) +`, + throwStatement: ` +rule: + kind: throw_statement +`, + asyncAwaitTryCatch: ` +rule: + kind: try_statement + has: + kind: await_expression +`, +}; +``` + +- [ ] **Step 2: Write test for error handling detection** + +```typescript +describe('AST error handling detection', () => { + // Mock execFileSync to avoid requiring ast-grep binary in CI. + // Tests verify parsing and classification logic, not the binary. + + it('should detect try/catch blocks via mock', () => { + const mockOutput = JSON.stringify([{ rule: 'try_statement', line: 2, text: 'try {' }]); + vi.spyOn(child_process, 'execFileSync').mockReturnValue(mockOutput); + + const result = runAstGrepRule('src/test.ts', ERROR_HANDLING_RULES.tryCatch, tempDir); + expect(result.matches.length).toBe(1); + expect(result.matches[0].rule).toBe('try_statement'); + + vi.restoreAllMocks(); + }); + + it('should detect throw statements via mock', () => { + const mockOutput = JSON.stringify([{ rule: 'throw_statement', line: 1, text: 'throw new Error' }]); + vi.spyOn(child_process, 'execFileSync').mockReturnValue(mockOutput); + + const result = runAstGrepRule('src/test.ts', ERROR_HANDLING_RULES.throwStatement, tempDir); + expect(result.matches.length).toBe(1); + + vi.restoreAllMocks(); + }); + + it('should return empty matches on failure', () => { + vi.spyOn(child_process, 'execFileSync').mockImplementation(() => { throw new Error('not found'); }); + + const result = runAstGrepRule('src/test.ts', ERROR_HANDLING_RULES.tryCatch, tempDir); + expect(result.matches.length).toBe(0); + + vi.restoreAllMocks(); + }); + + it('should detect promise.catch via mock', () => { + const mockOutput = JSON.stringify([{ rule: 'promiseCatch', line: 3, text: '.catch(handler)' }]); + vi.spyOn(child_process, 'execFileSync').mockReturnValue(mockOutput); + + const result = runAstGrepRule('src/test.ts', ERROR_HANDLING_RULES.promiseCatch, tempDir); + expect(result.matches.length).toBe(1); + + vi.restoreAllMocks(); + }); +}); +``` + +- [ ] **Step 3: Commit** + +```bash +git add packages/core/src/services/ast-patterns.ts packages/core/src/services/__tests__/ast-patterns.test.ts +git commit -m "feat(core): add ast-grep based error handling detection" +``` + +--- + +## Task 3: Integrate AST patterns into PatternAnalysisService + +Replace the regex-based `extractErrorHandlingFromContent` with AST detection when ast-grep is available, falling back to regex otherwise. + +- [ ] **Step 1: Add AST-enhanced error handling analyzer** + +```typescript +// In pattern-analysis-service.ts + +import { ERROR_HANDLING_RULES, hasAstGrep, runAstGrepRule } from './ast-patterns.js'; + +/** + * Extract error handling pattern using AST (preferred) or regex (fallback). + */ +export function extractErrorHandling( + content: string, + filePath?: string, + repositoryPath?: string +): ErrorHandlingPattern { + // Try AST-based detection first (more accurate) + if (filePath && repositoryPath && hasAstGrep()) { + const tryCatch = runAstGrepRule(filePath, ERROR_HANDLING_RULES.tryCatch, repositoryPath); + const throwStmt = runAstGrepRule(filePath, ERROR_HANDLING_RULES.throwStatement, repositoryPath); + const promiseCatch = runAstGrepRule(filePath, ERROR_HANDLING_RULES.promiseCatch, repositoryPath); + + const counts = { + tryCatch: tryCatch.matches.length, + throw: throwStmt.matches.length, + promiseCatch: promiseCatch.matches.length, + }; + + const total = counts.tryCatch + counts.throw + counts.promiseCatch; + if (total === 0) return { style: 'unknown', examples: [] }; + + const activePatterns = Object.values(counts).filter((c) => c > 0).length; + if (activePatterns > 1) return { style: 'mixed', examples: [] }; + if (counts.throw > 0) return { style: 'throw', examples: [] }; + // try/catch and .catch() are both catch-based — map to 'result' + // (closest existing style for structured error handling) + if (counts.tryCatch > 0 || counts.promiseCatch > 0) return { style: 'result', examples: [] }; + + return { style: 'unknown', examples: [] }; + } + + // Fallback to regex + return extractErrorHandlingFromContent(content); +} +``` + +- [ ] **Step 2: Update analyzeFileFromIndex and analyzeFileWithDocs to use new function** + +Replace `extractErrorHandlingFromContent(content)` with `extractErrorHandling(content, filePath, this.config.repositoryPath)` in both methods. + +- [ ] **Step 3: Run tests** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS (ast-grep detection used when available, regex fallback otherwise) + +- [ ] **Step 4: Commit** + +```bash +git add packages/core/src/services/pattern-analysis-service.ts packages/core/src/services/ast-patterns.ts +git commit -m "feat(core): use ast-grep for pattern analysis with regex fallback" +``` + +--- + +## Notes + +- ast-grep is an **optional** dependency — all functionality works without it via regex fallback +- `hasAstGrep()` is memoized per process — single execSync on first call +- Uses `execFileSync` (array args) instead of `execSync` (string) to prevent shell injection via file paths +- `--rule` requires a file path — we write temp YAML files and clean up after +- Tests mock `execFileSync` so they run in CI without ast-grep installed +- Future: expand AST rules for import style, type coverage, naming conventions +- Attribution: add to ARCHITECTURE.md: "AST pattern matching inspired by [ast-grep](https://github.com/ast-grep/ast-grep)" diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.6-pagerank-map.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.6-pagerank-map.md new file mode 100644 index 0000000..005d038 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/1.6-pagerank-map.md @@ -0,0 +1,360 @@ +# Part 1.6: PageRank File Ranking for dev_map + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Replace simple reference counting in `dev_map` hot paths with PageRank over the call graph for more meaningful file ranking. + +**User stories:** US-12 (meaningful file importance in codebase map) + +**Inspiration:** [aider's repo map](https://aider.chat/docs/repomap.html) — Apache 2.0. Uses PageRank over dependency graph to identify architecturally central files. We already have the call graph data from the scanner (callees metadata in Antfly). + +**Files:** +- Create: `packages/core/src/map/pagerank.ts` +- Create: `packages/core/src/map/__tests__/pagerank.test.ts` +- Modify: `packages/core/src/map/index.ts` +- Modify: `packages/core/src/map/types.ts` + +--- + +## Background + +Current hot paths use simple incoming reference count: + +``` +output.ts 147 refs ← most imported file +types.d.ts 83 refs +typescript.ts 56 refs +``` + +This is a good proxy but misses graph structure. A file could have few direct references but be a critical bridge between subsystems. PageRank captures this — files that are referenced by other highly-referenced files rank higher. + +We already have the data: every indexed document has `callees: [{ name, file, line }]` metadata. This is the dependency graph. + +--- + +## Task 1: Implement PageRank algorithm + +Pure function — takes a graph, returns ranked nodes. No I/O. + +- [ ] **Step 1: Write tests for PageRank** + +```typescript +// In packages/core/src/map/__tests__/pagerank.test.ts + +import { pageRank } from '../pagerank'; + +describe('pageRank', () => { + it('should rank nodes by importance', () => { + // A -> B -> C, A -> C + // C should rank highest (most incoming from important nodes) + const graph = new Map(); + graph.set('A', ['B', 'C']); + graph.set('B', ['C']); + graph.set('C', []); + + const ranks = pageRank(graph); + expect(ranks.get('C')).toBeGreaterThan(ranks.get('A')!); + expect(ranks.get('C')).toBeGreaterThan(ranks.get('B')!); + }); + + it('should handle cycles', () => { + // A -> B -> A (mutual dependency) + const graph = new Map(); + graph.set('A', ['B']); + graph.set('B', ['A']); + + const ranks = pageRank(graph); + // Both should have similar rank + expect(Math.abs(ranks.get('A')! - ranks.get('B')!)).toBeLessThan(0.1); + }); + + it('should handle disconnected nodes', () => { + const graph = new Map(); + graph.set('A', ['B']); + graph.set('B', []); + graph.set('C', []); // No connections + + const ranks = pageRank(graph); + expect(ranks.get('A')).toBeDefined(); + expect(ranks.get('C')).toBeDefined(); + // Connected nodes should rank higher than isolated + expect(ranks.get('B')!).toBeGreaterThan(ranks.get('C')!); + }); + + it('should return empty map for empty graph', () => { + const ranks = pageRank(new Map()); + expect(ranks.size).toBe(0); + }); + + it('should converge within iterations', () => { + // Large-ish graph + const graph = new Map(); + for (let i = 0; i < 100; i++) { + graph.set(`node${i}`, [`node${(i + 1) % 100}`]); + } + const ranks = pageRank(graph); + expect(ranks.size).toBe(100); + }); +}); +``` + +- [ ] **Step 2: Run tests, verify fail** + +Run: `pnpm test -- packages/core/src/map/__tests__/pagerank.test.ts` +Expected: FAIL — module not found + +- [ ] **Step 3: Implement PageRank** + +```typescript +// packages/core/src/map/pagerank.ts + +/** + * PageRank algorithm for ranking nodes in a directed graph. + * Pure function — no I/O. + * + * Inspired by aider's repo map (https://github.com/Aider-AI/aider). + * + * @param graph - Map of node -> outgoing edges (dependencies) + * @param damping - Damping factor (default 0.85, standard for PageRank) + * @param iterations - Number of iterations (default 20, sufficient for convergence) + * @returns Map of node -> rank score (higher = more important) + */ +export function pageRank( + graph: Map, + damping = 0.85, + iterations = 20 +): Map { + const nodes = new Set(); + for (const [src, targets] of graph) { + nodes.add(src); + for (const t of targets) nodes.add(t); + } + + if (nodes.size === 0) return new Map(); + + const n = nodes.size; + const ranks = new Map(); + const initial = 1 / n; + + // Initialize equal rank + for (const node of nodes) { + ranks.set(node, initial); + } + + // Build reverse graph (who points to me?) + const inbound = new Map(); + for (const node of nodes) inbound.set(node, []); + for (const [src, targets] of graph) { + for (const t of targets) { + inbound.get(t)?.push(src); + } + } + + // Iterate + for (let i = 0; i < iterations; i++) { + const newRanks = new Map(); + + for (const node of nodes) { + let sum = 0; + const sources = inbound.get(node) || []; + for (const src of sources) { + const outDegree = graph.get(src)?.length || 1; + sum += (ranks.get(src) || 0) / outDegree; + } + newRanks.set(node, (1 - damping) / n + damping * sum); + } + + // Update ranks + for (const [node, rank] of newRanks) { + ranks.set(node, rank); + } + } + + return ranks; +} +``` + +- [ ] **Step 4: Run tests, verify pass** + +Run: `pnpm test -- packages/core/src/map/__tests__/pagerank.test.ts` +Expected: ALL PASS + +- [ ] **Step 5: Commit** + +```bash +git add packages/core/src/map/pagerank.ts packages/core/src/map/__tests__/pagerank.test.ts +git commit -m "feat(core): add PageRank algorithm for file importance ranking" +``` + +--- + +## Task 2: Build dependency graph from indexed callees + +- [ ] **Step 1: Add graph builder function** + +```typescript +// In pagerank.ts + +import type { SearchResult } from '../vector/types.js'; + +/** + * Build a file dependency graph from indexed documents. + * Uses callees metadata to create edges: file A calls something in file B → A depends on B. + * Pure function. + */ +export function buildDependencyGraph(docs: SearchResult[]): Map { + const graph = new Map(); + + for (const doc of docs) { + const sourceFile = doc.metadata.path as string; + if (!sourceFile) continue; + + if (!graph.has(sourceFile)) graph.set(sourceFile, []); + + const callees = doc.metadata.callees as Array<{ file?: string }> | undefined; + if (callees && Array.isArray(callees)) { + for (const callee of callees) { + if (callee.file && callee.file !== sourceFile) { + graph.get(sourceFile)!.push(callee.file); + } + } + } + } + + // Deduplicate edges + for (const [node, edges] of graph) { + graph.set(node, [...new Set(edges)]); + } + + return graph; +} +``` + +- [ ] **Step 2: Write test** + +```typescript +describe('buildDependencyGraph', () => { + it('should build graph from callees metadata', () => { + const docs: SearchResult[] = [ + { id: '1', score: 0.9, metadata: { + path: 'src/a.ts', + callees: [{ name: 'foo', file: 'src/b.ts', line: 10 }], + }}, + { id: '2', score: 0.9, metadata: { + path: 'src/b.ts', + callees: [{ name: 'bar', file: 'src/c.ts', line: 5 }], + }}, + ]; + + const graph = buildDependencyGraph(docs); + expect(graph.get('src/a.ts')).toContain('src/b.ts'); + expect(graph.get('src/b.ts')).toContain('src/c.ts'); + }); + + it('should handle docs without callees metadata', () => { + const docs: SearchResult[] = [ + { id: '1', score: 0.9, metadata: { path: 'src/types.ts', type: 'interface' } }, + { id: '2', score: 0.9, metadata: { + path: 'src/a.ts', + callees: [{ name: 'MyType', file: 'src/types.ts', line: 1 }], + }}, + ]; + + const graph = buildDependencyGraph(docs); + expect(graph.get('src/a.ts')).toContain('src/types.ts'); + expect(graph.get('src/types.ts')).toEqual([]); + }); + + it('should deduplicate edges', () => { + const docs: SearchResult[] = [ + { id: '1', score: 0.9, metadata: { + path: 'src/a.ts', + callees: [ + { name: 'foo', file: 'src/b.ts', line: 10 }, + { name: 'bar', file: 'src/b.ts', line: 20 }, + ], + }}, + ]; + + const graph = buildDependencyGraph(docs); + expect(graph.get('src/a.ts')).toEqual(['src/b.ts']); + }); +}); +``` + +- [ ] **Step 3: Commit** + +```bash +git add packages/core/src/map/pagerank.ts packages/core/src/map/__tests__/pagerank.test.ts +git commit -m "feat(core): add dependency graph builder from indexed callees" +``` + +--- + +## Task 3: Replace reference counting with PageRank in dev_map + +- [ ] **Step 1: Update computeHotPaths in map/index.ts** + +Replace the current `computeHotPaths` function (simple reference count) with PageRank-based ranking: + +```typescript +import { buildDependencyGraph, pageRank } from './pagerank.js'; + +function computeHotPaths(docs: SearchResult[], maxPaths: number): HotPath[] { + const graph = buildDependencyGraph(docs); + const ranks = pageRank(graph); + + // Build a lookup for primary component name per file + const componentByFile = new Map(); + for (const doc of docs) { + const filePath = doc.metadata.path as string; + if (filePath && doc.metadata.name && !componentByFile.has(filePath)) { + componentByFile.set(filePath, doc.metadata.name as string); + } + } + + // Sort by PageRank score and take top N + return Array.from(ranks.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, maxPaths) + .map(([file, score]) => ({ + file, + incomingRefs: Math.round(score * 1000), // Normalized PageRank for display + primaryComponent: componentByFile.get(file), + })); +} +``` + +- [ ] **Step 2: Update HotPath type if needed** + +In `packages/core/src/map/types.ts`, consider adding a `pageRankScore` field: + +```typescript +export interface HotPath { + file: string; + incomingRefs: number; + primaryComponent?: string; + pageRankScore?: number; // Optional, for debugging/verbose output +} +``` + +- [ ] **Step 3: Run full test suite** + +Run: `pnpm build && pnpm test` +Expected: ALL PASS (hot paths test may need updating for new ranking order) + +- [ ] **Step 4: Commit** + +```bash +git add packages/core/src/map/index.ts packages/core/src/map/types.ts packages/core/src/map/pagerank.ts packages/core/src/map/__tests__/ +git commit -m "feat(core): use PageRank for dev_map hot paths ranking" +``` + +--- + +## Notes + +- **Existing map tests need updating:** Tests in `map.test.ts` mock `callers` data. After this change, `computeHotPaths` uses `callees` via `buildDependencyGraph`. Update mock data to use `callees` instead of `callers`, and adjust expected ranking order since PageRank differs from simple ref counting. +- PageRank is ~O(V + E) per iteration × 20 iterations. For a 2k-file repo with 10k edges, this is <10ms. Negligible. +- The `incomingRefs` field now shows normalized PageRank score, not raw count. Display label in `formatCodebaseMap` could change from "refs" to "importance" or keep "refs" for familiarity. +- Attribution: add to ARCHITECTURE.md: "File importance ranking inspired by [aider's repo map](https://github.com/Aider-AI/aider)" diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/overview.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/overview.md new file mode 100644 index 0000000..a482a85 --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/overview.md @@ -0,0 +1,145 @@ +# Phase 1: MCP Tools Improvement + +**Status:** Draft + +## Context + +The 6 MCP tools (`dev_search`, `dev_refs`, `dev_map`, `dev_patterns`, `dev_status`, +`dev_health`) are functional but have two categories of issues: + +1. **Performance:** `dev_patterns` re-scans files with ts-morph on every call (1-3s) + instead of reading from the Antfly index. +2. **Agent usability:** inconsistent error recovery guidance, overlapping tools + (`dev_status` vs `dev_health`), misleading parameter names, and verbose output + that wastes LLM context tokens. + +The other 5 tools already read from the index and are fast (<100ms). This phase +brings `dev_patterns` to the same standard and makes all tools more effective for +AI agents. + +See [user-stories.md](./user-stories.md) for the user stories driving this work. + +--- + +## Current architecture (dev_patterns) + +``` +dev_patterns request + → InspectAdapter.execute() + → SearchService.findSimilar(file) ← Antfly (fast, ~50ms) + → PatternAnalysisService.comparePatterns() + → scanRepository({ include: allFiles }) ← RE-PARSES with ts-morph (SLOW) + → analyzeFileWithDocs() + → fs.readFile() × 2 (duplicate reads) + → regex on content (error handling) + → regex on signatures (type coverage) + → compare*() methods ← pure logic (fast) +``` + +## Proposed architecture + +``` +dev_patterns request + → InspectAdapter.execute() + → SearchService.findSimilar(file) ← Antfly (fast, ~50ms) + → PatternAnalysisService.comparePatterns() + → getDocsByFilePath(paths) ← Antfly (fast, ~20ms) + → analyzeFileFromIndex() + → extract type coverage from indexed signatures + → fs.readFile() ONCE (line count + error handling regex) + → compare*() methods ← unchanged +``` + +**Performance:** 1-3s → ~100ms (10-30x faster) + +**Note on mixed data sources:** `analyzeFileFromIndex` reads from two sources — +indexed metadata for type coverage/signatures, disk for line count and error +handling regex. Line count and raw content patterns are not stored in the index. +This is an acceptable trade-off: line count is a cheap stat call. + +--- + +## Parts + +| Part | Description | Risk | +|------|-------------|------| +| [1.1](./1.1-pure-extractors.md) | Extract pure testable pattern analyzers | Low — refactor only | +| [1.2](./1.2-index-based-analysis.md) | Add `getDocsByFilePath`, index analysis path, wire VectorStorage | Medium — new code path | +| [1.3](./1.3-cleanup.md) | Consolidate reads, remove dead code, remove GitHub from health | Low — cleanup | +| [1.4](./1.4-agent-usability.md) | Merge status/health, add error suggestions, rename params, JSON output | Medium — tool surface change | +| [1.5](./1.5-ast-pattern-analysis.md) | AST-based pattern analysis via ast-grep (optional dep) | Low — additive, regex fallback | +| [1.6](./1.6-pagerank-map.md) | PageRank file ranking for dev_map hot paths | Low — replaces simple counting | + +--- + +## Decisions + +| Decision | Rationale | Alternatives | +|----------|-----------|-------------| +| Optional `vectorStorage` in config | Preserves fallback for tests and offline (US-4) | Required — breaks all existing tests | +| `getDocsByFilePath()` with capped `getAll` + exact filter | Reliable exact-match. BM25 search tokenizes paths unpredictably. | BM25 search — fragile, noise in results | +| Cap `getAll` at 5,000 docs | Covers most repos. Warns if exceeded. | No cap — memory risk on large repos | +| Use `SearchResult` type | Matches actual VectorStorage return type | Inline type — fragile, loses safety | +| Merge `dev_health` into `dev_status` | Removes tool overlap that confuses agents (US-8) | Keep both — agents waste turns choosing | +| Rename `query` → `filePath` in `dev_patterns` | Prevents LLMs from passing natural language | Keep `query` — higher misuse rate | +| Add `format: "json"` to `dev_patterns` | Token-efficient for agent workflows (US-9) | Markdown only — wastes ~2000 tokens per call | +| ast-grep for pattern analysis (optional) | More accurate AST matching than regex. Falls back to regex if not installed. | Use ts-morph directly — too slow. Regex only — less accurate. | +| PageRank for hot paths | Captures graph centrality, not just direct refs. Inspired by aider. | Keep ref counting — simpler but misses bridge files. | +| Catch ENOENT in analyzeFileFromIndex | File may be deleted between index and analysis | Let it throw — worse UX | + +--- + +## Risk register + +| Risk | Likelihood | Impact | Mitigation | +|------|-----------|--------|------------| +| `getDocsByFilePath` slow on 50k+ doc repos | Medium | Medium | Cap at 5,000 docs. Warn if exceeded. Future: add server-side path filter to Antfly SDK | +| Indexed metadata missing fields (partial index) | Low | Low | Fallback path preserved via optional vectorStorage | +| Error handling regex misses patterns | Low | Low | Existing behavior unchanged. AST is separate future work | +| File deleted between index and analysis | Low | Low | ENOENT caught, partial results returned | +| Disk content differs from index | Medium | Low | Documented trade-off. Line count from disk, types from index | +| ast-grep not installed on user machine | Medium | None | Regex fallback — all functionality works without ast-grep | +| PageRank changes hot paths ordering | High | Low | Better ranking is the goal. Users may notice different order — this is an improvement. | +| Merging status/health breaks `dev_health` callers | Low | Medium | `dev_health` was rarely used directly. `dev_status section="health"` is equivalent. | +| Agents pass natural language to `filePath` param | Low | Low | Description explicitly says "file path" with example | + +--- + +## Test strategy + +| Test | Priority | Location | +|------|----------|----------| +| `extractImportStyleFromContent` — ESM, CJS, mixed, unknown | P1 | `core/services/__tests__/pattern-analysis-service.test.ts` | +| `extractErrorHandlingFromContent` — throw, result, mixed, unknown | P1 | same | +| `extractTypeCoverageFromSignatures` — full, partial, minimal, none | P1 | same | +| `analyzeFileFromIndex` — real file + mock index docs | P1 | same | +| `analyzeFileFromIndex` — ENOENT (deleted file) | P1 | same | +| `getDocsByFilePath` — filters exact match, ignores noise | P1 | `core/vector/__tests__/` or inline | +| `comparePatterns` with mock vectorStorage — fast path | P1 | same | +| `comparePatterns` without vectorStorage — fallback path | P1 | same | +| `comparePatterns` — search returns noise, zero results | P1 | same | +| Error `suggestion` fields on all 6 adapters | P2 | adapter test files | +| `dev_status section="health"` returns health data | P2 | `mcp-server/adapters/__tests__/status-adapter.test.ts` | +| PageRank — basic graph, cycles, disconnected | P1 | `core/map/__tests__/pagerank.test.ts` | +| buildDependencyGraph from callees metadata | P1 | same | +| ast-grep detection — try/catch, throw (if installed) | P2 | `core/services/__tests__/ast-patterns.test.ts` | +| Regex fallback when ast-grep unavailable | P1 | `core/services/__tests__/pattern-analysis-service.test.ts` | +| Existing 30+ tests unchanged (regression) | P1 | same | + +--- + +## Verification checklist + +- [ ] `pnpm build` passes +- [ ] `pnpm test` — all tests pass (existing + new) +- [ ] Manual: `dev_patterns` returns results via MCP +- [ ] Manual: `dev_patterns` response time < 200ms +- [ ] Manual: `dev_status section="health"` works +- [ ] Manual: `dev_health` is no longer listed in tools +- [ ] All error paths return `suggestion` field +- [ ] `dev_patterns` accepts `filePath` parameter +- [ ] `dev_patterns format="json"` returns structured data +- [ ] `dev_map` hot paths use PageRank (order may differ from before — expected) +- [ ] PageRank unit tests pass (cycles, disconnected nodes, convergence) +- [ ] Pattern analysis uses ast-grep when installed, regex otherwise +- [ ] Attribution noted in ARCHITECTURE.md for aider and ast-grep inspiration diff --git a/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/user-stories.md b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/user-stories.md new file mode 100644 index 0000000..f554efa --- /dev/null +++ b/.claude/da-plans/mcp/phase-1-mcp-tools-improvement/user-stories.md @@ -0,0 +1,83 @@ +# User Stories: MCP Tools Improvement + +## Pattern Analysis + +**US-1: Fast pattern analysis during code review** +As a developer reviewing a pull request, +when my AI tool calls `dev_patterns` on a changed file, +I should get results in under 200ms (not 1-3 seconds), +so that the code review doesn't stall waiting for pattern analysis. + +**US-2: Pattern analysis on large repos** +As a developer on a monorepo with 10k+ files, +when my AI tool calls `dev_patterns`, +it should not fetch the entire index into memory, +so that the MCP server stays responsive. + +**US-3: Consistent pattern analysis without re-scanning** +As a developer editing files rapidly, +when my AI tool calls `dev_patterns` on a file I just saved, +it should use the already-indexed metadata (not re-parse from disk), +so that results reflect the indexed state without redundant work. + +> **Note:** Line count and error handling analysis still read from disk since this +> data isn't in the index. Type coverage and import style use indexed metadata. +> Documented trade-off in the decisions table. + +**US-4: Pattern analysis without Antfly** +As a developer running tests or in CI, +when `dev_patterns` is called without a live Antfly server, +it should fall back to scanning files directly, +so that tests and offline usage still work. + +## Agent Usability + +**US-5: AI knows which tool to use** +As a developer asking "check this file for consistency," +when my AI tool reads the MCP tool descriptions, +it should immediately know to call `dev_patterns` (not `dev_search`), +so that it picks the right tool without trial and error. + +**US-6: AI doesn't call removed tools** +As a developer with dev-agent installed, +when my AI tool lists available tools, +it should only see the current tools (no stale references to removed ones), +so that it doesn't waste turns calling tools that don't exist. + +> **Note:** US-6 is already resolved by the docs sweep in `fix/stale-docs-cleanup`. + +**US-7: Accurate health reporting** +As a developer asking "is dev-agent working?", +when my AI tool calls a health/status tool, +the response should reflect the actual system (no GitHub references), +so that the output is trustworthy. + +**US-8: AI doesn't confuse overlapping tools** +As a developer asking "what's the status of dev-agent?", +when my AI tool sees `dev_status` and `dev_health` in the tool list, +it should not have to guess which one to call, +so that it gets the right answer on the first try. + +**US-9: Token-efficient responses** +As a developer in a long conversation, +when my AI tool calls `dev_patterns`, +the response should be structured and compact (not verbose markdown), +so that the AI has room in its context for actual work. + +**US-10: AI recovers from errors** +As a developer whose Antfly server crashed, +when my AI tool calls any dev-agent tool and gets an error, +the error should tell the AI exactly what to do next, +so that it can recover without human intervention. + +## Analysis Quality + +**US-11: Accurate pattern detection** +As a developer running `dev_patterns` on a file with try/catch, .catch(), and async error handling, +the tool should detect all these patterns (not just throw statements), +so that the pattern analysis is trustworthy for code review decisions. + +**US-12: Meaningful file importance in codebase map** +As a developer exploring an unfamiliar codebase via `dev_map`, +the hot paths should show architecturally central files (not just frequently imported ones), +so that I understand which files are the critical connective tissue of the codebase. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index eae5bfd..26b5e54 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -50,31 +50,32 @@ Personal tool combining deep code intelligence with specialized AI subagents. CL **Trade-off:** More complexity, but gets us real multi-language support. -### Why @xenova/transformers? +### Why Antfly Termite (ONNX)? **Problem:** Need embeddings, but want local-first. **Options considered:** - TensorFlow.js: Older, limited models - OpenAI API: Best quality but requires API key -- @xenova/transformers: Modern, all-MiniLM-L6-v2 +- @xenova/transformers: Predecessor, now superseded +- Antfly Termite: Local ONNX inference, BAAI/bge-small-en-v1.5 -**Choice:** @xenova/transformers +**Choice:** Antfly Termite (ONNX) - Local (no API keys) -- Good quality (384 dims) -- Active development +- Good quality (384 dims, BAAI/bge-small-en-v1.5) +- Integrated with Antfly search backend -### Why LanceDB? +### Why Antfly? -**Problem:** Need vector storage without running a server. +**Problem:** Need vector storage and hybrid search without running a separate server. **Options considered:** - ChromaDB: Requires server process - FAISS: Python-focused -- In-memory: Doesn't persist -- LanceDB: Embedded, TypeScript-native +- LanceDB: Embedded but vector-only (no BM25) +- Antfly: Local hybrid search (BM25 + vector + RRF) -**Choice:** LanceDB (embedded, no server) +**Choice:** Antfly (local hybrid search) ### Why CLI-first? @@ -143,8 +144,8 @@ interface VectorStore { ``` **Why pluggable?** Technology changes fast. Easy to swap: -- Embedders: transformers → OpenAI → Ollama -- Stores: LanceDB → ChromaDB → in-memory (testing) +- Embedders: Antfly Termite → OpenAI → Ollama +- Stores: Antfly → ChromaDB → in-memory (testing) ### Repository Indexer (Issue #12) @@ -238,8 +239,8 @@ dev-agent search "query" --json # JSON output - tree-sitter (multi-language parsing) - ts-morph (TypeScript analysis) - remark (Markdown) -- @xenova/transformers (embeddings) -- LanceDB (vector storage) +- Antfly Termite (ONNX embeddings, BAAI/bge-small-en-v1.5) +- Antfly (hybrid search: BM25 + vector + RRF) - GitHub CLI (GitHub operations) ### CLI @@ -264,8 +265,8 @@ dev-agent search "query" --json # JSON output - Scanner registry 2. **Issue #4: Vector Storage** (2 weeks) - - TransformersEmbedder (all-MiniLM-L6-v2) - - LanceDBVectorStore + - TermiteEmbedder (BAAI/bge-small-en-v1.5) + - AntflyVectorStore - InMemoryVectorStore (testing) 3. **Issue #12: Indexer** (2 weeks) @@ -323,9 +324,9 @@ dev-agent search "query" --json # JSON output ```json { - "embedder": "transformers", + "embedder": "termite", "vectorStore": { - "type": "lancedb", + "type": "antfly", "path": ".dev-agent/vectors" }, "exclude": [ @@ -343,7 +344,7 @@ dev-agent search "query" --json # JSON output ``` .dev-agent/ ├── config.json # User configuration -├── vectors/ # LanceDB storage +├── vectors/ # Antfly storage ├── cache/ # Model cache └── logs/ # Debug logs ``` diff --git a/CLAUDE.md b/CLAUDE.md index b798566..b9fd978 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,7 @@ Everything runs on your machine. No data leaves. packages/ core/ # Scanner (ts-morph, tree-sitter), vector storage (Antfly), services cli/ # Commander.js CLI — dev index, dev mcp install, etc. - mcp-server/ # MCP server with 9 built-in adapters + mcp-server/ # MCP server with 6 built-in adapters subagents/ # Coordinator, explorer, planner, PR agents integrations/ # Claude Code, VS Code, Cursor logger/ # @prosdevlab/kero — centralized logging @@ -124,7 +124,7 @@ See `.claude/da-plans/README.md` for status and format details. | `dev_search` | Hybrid code search — BM25 + vector + RRF (use FIRST for conceptual queries) | | `dev_refs` | Find callers/callees of functions | | `dev_map` | Codebase structure with change frequency | -| `dev_inspect` | File pattern analysis (similar code, error handling, types) | +| `dev_patterns` | File pattern analysis (similar code, error handling, types) | | `dev_status` | Repository indexing status + Antfly stats + watcher status | | `dev_health` | Server health checks (Antfly connectivity) | diff --git a/PLAN.md b/PLAN.md index 82c8281..7620575 100644 --- a/PLAN.md +++ b/PLAN.md @@ -30,8 +30,8 @@ Dev-agent provides semantic code search, codebase intelligence, and GitHub integ |---------|--------|---------| | TypeScript scanner (ts-morph) | ✅ Done | `@prosdevlab/dev-agent-core` | | Repository indexer | ✅ Done | `@prosdevlab/dev-agent-core` | -| Vector storage (LanceDB) | ✅ Done | `@prosdevlab/dev-agent-core` | -| Embeddings (@xenova/transformers) | ✅ Done | `@prosdevlab/dev-agent-core` | +| Vector storage (Antfly) | ✅ Done | `@prosdevlab/dev-agent-core` | +| Embeddings (Antfly Termite) | ✅ Done | `@prosdevlab/dev-agent-core` | | Semantic search | ✅ Done | `@prosdevlab/dev-agent-core` | | CLI interface | ✅ Done | `@prosdevlab/dev-agent-cli` | | Centralized logging | ✅ Done | `@prosdevlab/kero` | @@ -44,7 +44,7 @@ Dev-agent provides semantic code search, codebase intelligence, and GitHub integ | Adapter framework | ✅ Done | `@prosdevlab/dev-agent-mcp` | | `dev_search` - Semantic code search | ✅ Done | MCP adapter | | `dev_status` - Repository status | ✅ Done | MCP adapter | -| `dev_inspect` - File analysis | ✅ Done | MCP adapter | +| `dev_patterns` - File analysis | ✅ Done | MCP adapter | | `dev_plan` - Issue planning | ✅ Done | MCP adapter | | `dev_gh` - GitHub search | ✅ Done | MCP adapter | | `dev_health` - Health checks | ✅ Done | MCP adapter | @@ -219,7 +219,7 @@ Git history is valuable context that LLMs can't easily access. We add intelligen | Phase | Tool | Status | |-------|------|--------| | 1 (v0.4.4) | `dev_search` | ✅ Done | -| 2 | `dev_refs`, `dev_inspect` | ✅ Done | +| 2 | `dev_refs`, `dev_patterns` | ✅ Done | | 3 | `dev_map`, `dev_status` | ✅ Done | **Implementation (Phase 1):** @@ -234,7 +234,7 @@ Git history is valuable context that LLMs can't easily access. We add intelligen |------|--------| | Improved dev_search description ("USE THIS FIRST") | ✅ Done | | Improved dev_map description (vs list_dir) | ✅ Done | -| Improved dev_inspect description (file analysis) | ✅ Done | +| Improved dev_patterns description (file analysis) | ✅ Done | | Improved dev_refs description (specific symbols) | ✅ Done | | All 9 adapters registered in CLI | ✅ Done | @@ -399,13 +399,13 @@ packages/core/ --- -## Next: Advanced LanceDB Visualizations (v0.7.2) +## Next: Advanced Vector Visualizations (v0.7.2) > Making vector embeddings visible and explorable. ### Philosophy -LanceDB stores 384-dimensional embeddings for semantic search, but these are invisible to users. Advanced visualizations reveal: +Antfly stores 384-dimensional embeddings for semantic search, but these are invisible to users. Advanced visualizations reveal: - **Where code lives** in semantic space (2D projections) - **What's related** beyond imports (similarity networks) - **How embeddings evolve** over time (drift tracking) @@ -456,7 +456,7 @@ New API Routes ├─ GET /api/embeddings/quality (coverage metrics) └─ GET /api/embeddings/search-history (query analysis) ↓ -LanceDB + Vector Analysis +Antfly + Vector Analysis └─ Dimensionality reduction, similarity queries, metrics ``` @@ -552,14 +552,14 @@ These were in the original plan but have been deprioritized or reconsidered: - **Build:** Turborepo - **Linting:** Biome - **Testing:** Vitest (1379+ tests) -- **Vector Storage:** LanceDB (embedded, no server) -- **Embeddings:** @xenova/transformers (all-MiniLM-L6-v2) +- **Vector Storage:** Antfly (hybrid search: BM25 + vector + RRF) +- **Embeddings:** Antfly Termite (ONNX, BAAI/bge-small-en-v1.5) - **AI Integration:** MCP (Model Context Protocol) - **Code Analysis:** ts-morph (TypeScript Compiler API) ### Considered but Not Adopted -- ChromaDB → LanceDB (embedded is simpler) -- TensorFlow.js → @xenova/transformers (better models) +- ChromaDB → Antfly (hybrid search is better) +- TensorFlow.js → Antfly Termite (local ONNX, better models) - Express → MCP (protocol is the interface) --- diff --git a/README.md b/README.md index 7a23b60..21ae603 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,12 @@ ## What it does -dev-agent indexes your codebase and provides 9 MCP tools to AI assistants. Instead of AI tools grepping through files, they can ask conceptual questions like "where do we handle authentication?" +dev-agent indexes your codebase and provides 6 MCP tools to AI assistants. Instead of AI tools grepping through files, they can ask conceptual questions like "where do we handle authentication?" - `dev_search` — Semantic code search by meaning -- `dev_refs` — Find callers/callees of functions +- `dev_refs` — Find callers/callees of functions - `dev_map` — Codebase structure with change frequency -- `dev_history` — Semantic search over git commits -- `dev_plan` — Assemble context for GitHub issues -- `dev_inspect` — Inspect files (compare similar code, check patterns) -- `dev_gh` — Search GitHub issues/PRs semantically +- `dev_patterns` — Inspect files (compare similar code, check patterns) - `dev_status` / `dev_health` — Monitoring ## Measured results @@ -130,37 +127,7 @@ Show hot areas with recent changes │ └── exports: class MCPServer, function createAdapter(config): Adapter ``` -### `dev_history` - Git History Search ✨ New in v0.4 -Semantic search over git commit history. - -``` -Find commits about authentication token fixes -Show history for src/auth/middleware.ts -``` - -**Features:** -- **Semantic search:** Find commits by meaning, not just text -- **File history:** Track changes with rename detection -- **Issue/PR refs:** Extracted from commit messages -- **Token-budgeted output** - -### `dev_plan` - Context Assembly ✨ Enhanced in v0.4 -Assemble rich context for implementing GitHub issues. - -``` -Assemble context for issue #42 -``` - -**Returns:** -- Full issue with comments -- Relevant code snippets from semantic search -- **Related commits** from git history (new in v0.4) -- Detected codebase patterns (test naming, locations) -- Metadata (tokens, timing) - -**Note:** This tool no longer generates task breakdowns. It provides comprehensive context so the AI assistant can create better plans. - -### `dev_inspect` - File Analysis +### `dev_patterns` - File Analysis Inspect files for pattern analysis. Finds similar code and compares patterns (error handling, type coverage, imports, testing). ``` @@ -178,14 +145,6 @@ Check how src/hooks/useAuth.ts compares to similar hooks ### `dev_status` - Repository Status View indexing status, component health, and repository information. -### `dev_gh` - GitHub Search -Search issues and PRs with semantic understanding. - -``` -Find authentication-related bugs -Search for performance issues in closed PRs -``` - ### `dev_health` - Health Monitoring Check MCP server and component health. @@ -244,24 +203,19 @@ npm link dev index dev index --no-github # Skip GitHub indexing -# Incremental updates (only changed files) - much faster, typically seconds -dev update # Fast incremental reindexing -dev update -v # Verbose output showing what changed - # Semantic search dev search "how do agents communicate" -dev search "error handling" --threshold 0.3 - -# Git history search -dev git search "authentication fix" # Semantic search over commits -dev git stats # Show indexed commit count +dev search "error handling" --verbose +dev search --similar-to src/auth.ts # Find similar code -# GitHub integration -dev github index # Index issues and PRs (also done by dev index) -dev github search "authentication bug" # Semantic search +# Codebase structure +dev map -# View statistics -dev stats +# Storage management +dev storage path # Show storage path +dev storage size # Show storage size +dev compact # Compact vector database +dev clean --force # Remove all indexed data # MCP management dev mcp install --cursor # Install for Cursor @@ -327,9 +281,7 @@ dev index **Search results are outdated:** ```bash -# Update index with recent file changes -dev update -# Or do a full reindex if needed +# Re-index to pick up recent file changes dev index ``` @@ -407,14 +359,11 @@ pnpm typecheck - Build-time validation to prevent silent WASM dependency failures - Infrastructure for future Python/Rust support - **v0.4.0** - Intelligent Git History release - - New `dev_history` tool for semantic commit search - Enhanced `dev_map` with change frequency indicators (🔥 hot, ✏️ active) - - Enhanced `dev_plan` with related commits from git history - New `GitIndexer` and `LocalGitExtractor` in core - **v0.3.0** - Context Quality release - New `dev_refs` tool for relationship queries - Enhanced `dev_map` with hot paths, smart depth, signatures - - Refactored `dev_plan` to context assembly - **v0.2.0** - Richer search results with snippets and imports - **v0.1.0** - Initial release diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index b4ed79c..04a068d 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -350,7 +350,7 @@ dev index ## GitHub Integration -### `dev github index` fails +### GitHub indexing fails **Common causes:** @@ -382,11 +382,7 @@ Failed to fetch issues: spawnSync /bin/sh ENOBUFS 1. **Use lower limit (recommended):** ```bash - # For main index command dev index --gh-limit 100 - - # For dedicated GitHub indexing - dev github index --limit 100 ``` 2. **Adjust limit based on repository size:** @@ -394,61 +390,11 @@ Failed to fetch issues: spawnSync /bin/sh ENOBUFS - Medium repos (50-200 issues/PRs): Use `--gh-limit 200` - Large repos (200+ issues/PRs): Use `--gh-limit 100` or lower -3. **Index in batches:** - ```bash - # Index open items only (usually smaller) - dev github index --state open --limit 500 - - # Then index closed items with lower limit - dev github index --state closed --limit 100 - ``` - **Technical details:** - Default limit reduced to 500 (from 1000) to prevent buffer overflow - Buffer size increased to 50MB for large payloads - Helpful error messages now guide users to use `--gh-limit` flag -### `dev_gh` tool not finding issues - -**Diagnosis:** - -1. **Check if GitHub is indexed:** - ``` - Use dev_status tool - should show GitHub section - ``` - -2. **Verify state file exists:** - ```bash - ls -la ~/.dev-agent/indexes/*/github-state.json - ``` - -3. **Re-index:** - ```bash - dev github index - ``` - -**Note:** The `dev_gh` tool automatically reloads when you run `dev github index` - no restart needed! - -### GitHub index is stale - -**Check age:** -``` -Use dev_health tool - warns if GitHub index >24h old -``` - -**Solution:** -```bash -dev github index -``` - -**Automation (optional):** -```bash -# Add to crontab for daily updates -0 9 * * * cd /path/to/repo && dev github index -``` - ---- - ## Performance Issues ### Slow response times @@ -456,9 +402,7 @@ dev github index **Expected:** - `dev_search`: 100-500ms - `dev_status`: 50-100ms -- `dev_inspect`: 200-800ms -- `dev_plan`: 5-15 seconds -- `dev_gh`: 100-300ms +- `dev_patterns`: 200-800ms **If slower:** @@ -534,7 +478,6 @@ Use dev_health tool to check component status ```bash # Re-index everything dev index -dev github index # Restart MCP server ``` @@ -546,9 +489,7 @@ dev github index **Solution:** Check the tool's input schema: - `dev_search`: Requires `query` (string) -- `dev_inspect`: Requires `action` and `query` (file path) -- `dev_plan`: Requires `issue` (number) -- `dev_gh`: Requires `action` +- `dev_patterns`: Requires `action` and `query` (file path) ### "Adapter not found" @@ -655,7 +596,7 @@ dev mcp start --verbose # In another terminal, send test message echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | dev mcp start -# Should list all 9 tools: dev_search, dev_refs, dev_map, dev_history, dev_status, dev_plan, dev_inspect, dev_gh, dev_health +# Should list all 6 tools: dev_search, dev_refs, dev_map, dev_patterns, dev_status, dev_health ``` ### Inspect storage @@ -689,7 +630,6 @@ rm -rf ~/.dev-agent/indexes/* # Re-index your repositories cd /path/to/your/repo dev index -dev github index # Reinstall MCP dev mcp install --cursor # or without --cursor for Claude Code @@ -755,7 +695,6 @@ npm update -g dev-agent # Re-index repositories (recommended) cd /path/to/your/repo dev index -dev github index # Restart AI tool ``` @@ -864,7 +803,7 @@ dev_health 3. **Selective indexing:** - Only index repos you actively work on - - GitHub index optional (only if using `dev_gh`) + - GitHub index optional --- @@ -875,7 +814,7 @@ dev_health **Solution:** - Index at monorepo root - Search works across all projects -- Use `dev_inspect` to analyze specific files +- Use `dev_patterns` to analyze specific files ### Non-git repositories @@ -890,7 +829,7 @@ dev_health dev index # Skip GitHub indexing -# Just use dev_search, dev_status, dev_inspect, dev_plan +# Just use dev_search, dev_status, dev_patterns ``` ### Very large files (>10MB) @@ -944,7 +883,7 @@ dev index **GitHub Index Stale:** ```bash -dev github index +dev index ``` **Repository Not Accessible:** diff --git a/WORKFLOW.md b/WORKFLOW.md index 2bfce4e..7f9938d 100644 --- a/WORKFLOW.md +++ b/WORKFLOW.md @@ -19,17 +19,11 @@ Before starting development, familiarize yourself with our coding standards: git checkout main git pull origin main -# Use GitHub Context to find what to work on next -dev github search "state:open label:\"Epic: MCP Integration\"" --type issue - -# Or use gh CLI directly +# Use gh CLI to find what to work on next gh issue list --milestone "Epic #3: MCP Integration" --state open -# The tool helps you: -# - Find open issues by epic/milestone -# - See issue dependencies -# - Prioritize based on labels -# - Avoid duplicate work +# Or use dev_gh MCP tool to search semantically +# dev_gh: { action: "search", query: "open MCP integration issues" } ``` ### 2. Start New Feature @@ -42,29 +36,19 @@ git checkout -b feat/feature-name # Done via todo_write tool in Claude ``` -### 3. Planning Phase (Dogfooding! 🐕🍽️) +### 3. Planning Phase ```bash # Read the issue requirements gh issue view -# Use the Planner to break down the work -dev plan --json +# Use the dev_plan MCP tool to assemble context +# dev_plan: { issue: } -# Review the plan and adjust as needed -# The planner will: -# - Break issue into specific tasks -# - Find relevant code locations -# - Estimate effort -# - Suggest implementation order +# Or write a plan in .claude/da-plans/ for non-trivial features +# and run the plan-reviewer agent before implementation ``` -**Why dogfood the Planner?** -- ✅ Tests our own tool in real scenarios -- ✅ Identifies bugs and missing features -- ✅ Improves estimation accuracy over time -- ✅ Validates usefulness for end users - ### 4. Implementation Phase ```bash diff --git a/examples/README.md b/examples/README.md index 85a392d..86bb7e0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,7 @@ Real-world usage patterns for dev-agent MCP tools. # Install dev-agent npm install -g dev-agent -# Index your repository (code, git history, GitHub) +# Index your repository cd /path/to/your/project dev index @@ -118,100 +118,18 @@ dev_map: --- -### `dev_history` - Git History Search ✨ v0.4 - -Semantic search over git commits: - -``` -# Search commits by meaning -dev_history: - query: "authentication token fix" - -# Get file history -dev_history: - mode: "file" - file: "src/auth/middleware.ts" - -# Filter by author -dev_history: - query: "performance optimization" - author: "alice" - -# Recent commits only -dev_history: - query: "bug fix" - since: "30 days ago" -``` - -**Output shows:** -- Commits with relevance scores -- Author and date -- Changed files -- Issue/PR references extracted from messages - ---- - -### `dev_plan` - Context Assembly - -Get rich context for implementing a GitHub issue: - -``` -# Basic context -dev_plan: - issue: 42 - -# Full context package (v0.4+) -dev_plan: - issue: 42 - includeCode: true - includeHistory: true - includePatterns: true -``` - -**Returns:** -- Issue details (title, body, labels, comments) -- Relevant code snippets from semantic search -- **Related commits** from git history (v0.4+) -- Codebase patterns (test conventions, etc.) -- Related issues/PRs - ---- - -### `dev_gh` - GitHub Search - -Search issues and PRs semantically: - -``` -# Search issues -dev_gh: - action: "search" - query: "authentication bugs" - -# Get specific issue -dev_gh: - action: "get" - number: 42 -``` - -**First, index GitHub:** -```bash -dev github index -``` - ---- - -### `dev_inspect` - File Analysis +### `dev_patterns` - File Analysis Inspect files and compare implementations: ``` # Compare similar implementations -dev_inspect: +dev_patterns: action: "compare" query: "src/utils/retry.ts" # Validate pattern consistency (coming soon) -dev_inspect: +dev_patterns: action: "validate" query: "src/hooks/useAuth.ts" ``` @@ -277,28 +195,6 @@ dev_health: dev_refs: { name: "suspectFunction", direction: "callees" } ``` -3. **Find related commits:** - ``` - dev_history: { query: "similar bug fix" } - ``` - -4. **Find similar issues:** - ``` - dev_gh: { action: "search", query: "similar error" } - ``` - -### Implementing a GitHub Issue - -1. **Get full context:** - ``` - dev_plan: { issue: 123 } - ``` - -2. **Search for relevant patterns:** - ``` - dev_search: { query: "feature type from issue" } - ``` - ### Code Review Prep 1. **Understand the change area:** @@ -306,12 +202,7 @@ dev_health: dev_map: { focus: "path/to/changed/dir", includeChangeFrequency: true } ``` -2. **Check file history:** - ``` - dev_history: { mode: "file", file: "path/to/changed/file.ts" } - ``` - -3. **Check impact:** +2. **Check impact:** ``` dev_refs: { name: "changedFunction", direction: "callers" } ``` @@ -338,9 +229,6 @@ dev_health: # After major changes dev index -# After new issues/PRs -dev github index - # Check health dev_health ``` @@ -356,17 +244,8 @@ dev index # Search code dev search "authentication" --limit 5 --threshold 0.4 -# Search git history -dev git search "authentication fix" - -# Check stats -dev stats - -# Explore patterns -dev explore pattern "error handling" - -# Find similar code -dev explore similar src/utils/retry.ts +# View codebase map +dev map --depth 3 ``` --- @@ -387,16 +266,6 @@ dev mcp install # Tools available immediately ``` -### In Scripts - -```bash -# JSON output for scripting -dev search "coordinator" --json | jq '.[].metadata.path' - -# Check if indexed -dev stats --json | jq '.filesIndexed' -``` - --- ## Troubleshooting @@ -404,8 +273,8 @@ dev stats --json | jq '.filesIndexed' ### "No results found" ```bash -# Check if indexed -dev stats +# Check status +dev_status # Re-index dev index diff --git a/packages/cli/README.md b/packages/cli/README.md index fc40ed0..ae3e91a 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -52,20 +52,12 @@ Options: ### Explore -Explore code patterns and relationships: +Find code similar to a file: ```bash -# Find patterns using semantic search -dev explore pattern "error handling" --limit 5 - -# Find code similar to a file -dev explore similar path/to/file.ts --limit 5 +dev search --similar-to path/to/file.ts ``` -Options: -- `-l, --limit ` - Maximum results (default: 10) -- `-t, --threshold ` - Minimum similarity score (default: 0.7) - ### Update Incrementally update the index with changed files: @@ -106,8 +98,8 @@ The `.dev-agent.json` file configures the indexer: ```json { "repositoryPath": "/path/to/repo", - "vectorStorePath": ".dev-agent/vectors.lance", - "embeddingModel": "Xenova/all-MiniLM-L6-v2", + "vectorStorePath": ".dev-agent/vectors", + "embeddingModel": "BAAI/bge-small-en-v1.5", "dimension": 384, "excludePatterns": [ "**/node_modules/**", @@ -170,19 +162,9 @@ dev search "RepositoryIndexer" --threshold 0.4 ```bash # Find patterns in your codebase -dev explore pattern "test coverage utilities" --threshold 0.25 - -# Results: -# 1. Coverage Targets (56.0% match) -# 2. 100% Coverage on Utilities (50.8% match) -# 3. Testing (42.3% match) - -# Discover error handling patterns -dev explore pattern "error handling" --threshold 0.3 - -# Results: -# 1. Handle Errors Gracefully (39.3% match) -# 2. createErrorResponse (35.9% match) +dev search "test coverage utilities" +dev search "error handling" --verbose +dev search --similar-to src/utils/retry.ts ``` ### Pro Tips diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index b532a93..b5dacc5 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import { Command } from 'commander'; import { cleanCommand } from './commands/clean.js'; import { compactCommand } from './commands/compact.js'; -import { exploreCommand } from './commands/explore.js'; import { indexCommand } from './commands/index.js'; import { mapCommand } from './commands/map.js'; import { mcpCommand } from './commands/mcp.js'; @@ -27,7 +26,6 @@ program // Register commands program.addCommand(indexCommand); program.addCommand(searchCommand); -program.addCommand(exploreCommand); program.addCommand(mapCommand); program.addCommand(compactCommand); program.addCommand(cleanCommand); diff --git a/packages/cli/src/commands/explore.ts b/packages/cli/src/commands/explore.ts index 5e4e4c2..9d327c9 100644 --- a/packages/cli/src/commands/explore.ts +++ b/packages/cli/src/commands/explore.ts @@ -19,7 +19,7 @@ explore .description('Search for code patterns using semantic search') .argument('', 'Pattern to search for') .option('-l, --limit ', 'Number of results', '10') - .option('-t, --threshold ', 'Similarity threshold (0-1)', '0.7') + .option('-t, --threshold ', 'Minimum score', '0') .action(async (query: string, options) => { const spinner = ora('Searching for patterns...').start(); @@ -68,7 +68,7 @@ explore console.log(chalk.white(`${i + 1}. ${meta.name || meta.type}`)); console.log(chalk.gray(` ${meta.path}${meta.startLine ? `:${meta.startLine}` : ''}`)); - console.log(chalk.green(` ${(result.score * 100).toFixed(1)}% match\n`)); + console.log(''); } await indexer.close(); @@ -85,7 +85,7 @@ explore .description('Find code similar to a file') .argument('', 'File path') .option('-l, --limit ', 'Number of results', '5') - .option('-t, --threshold ', 'Similarity threshold (0-1)', '0.5') + .option('-t, --threshold ', 'Minimum score', '0') .action(async (file: string, options) => { const spinner = ora('Finding similar code...').start(); @@ -156,7 +156,7 @@ explore console.log(chalk.white(`${i + 1}. ${meta.name || meta.type}`)); console.log(chalk.gray(` ${meta.path}${meta.startLine ? `:${meta.startLine}` : ''}`)); - console.log(chalk.green(` ${(result.score * 100).toFixed(1)}% similar\n`)); + console.log(''); } await indexer.close(); diff --git a/packages/cli/src/commands/mcp.ts b/packages/cli/src/commands/mcp.ts index 9a15527..2fafc1b 100644 --- a/packages/cli/src/commands/mcp.ts +++ b/packages/cli/src/commands/mcp.ts @@ -50,7 +50,7 @@ Setup: 3. Restart Cursor to activate Available Tools (6): - dev_search, dev_status, dev_inspect, + dev_search, dev_status, dev_patterns, dev_health, dev_refs, dev_map ` ) @@ -175,7 +175,7 @@ Available Tools (6): logger.info(chalk.green('MCP server started successfully!')); logger.info( - 'Available tools: dev_search, dev_status, dev_inspect, dev_health, dev_refs, dev_map' + 'Available tools: dev_search, dev_status, dev_patterns, dev_health, dev_refs, dev_map' ); if (options.transport === 'stdio') { diff --git a/packages/cli/src/commands/search.ts b/packages/cli/src/commands/search.ts index 24d5291..bf4d5e9 100644 --- a/packages/cli/src/commands/search.ts +++ b/packages/cli/src/commands/search.ts @@ -9,31 +9,35 @@ import chalk from 'chalk'; import { Command } from 'commander'; import ora from 'ora'; import { loadConfig } from '../utils/config.js'; +import { prepareFileForSearch } from '../utils/file.js'; import { logger } from '../utils/logger.js'; import { formatSearchResults, output } from '../utils/output.js'; export const searchCommand = new Command('search') .description('Search indexed code semantically') - .argument('', 'Search query') + .argument('[query]', 'Search query (optional with --similar-to)') .option('-l, --limit ', 'Maximum number of results', '10') .option('-t, --threshold ', 'Minimum similarity score', '0') + .option('-s, --similar-to ', 'Find code similar to a file') .option('--json', 'Output results as JSON', false) .option('-v, --verbose', 'Show detailed results with signatures and docs', false) - .action(async (query: string, options) => { + .action(async (query: string | undefined, options) => { + if (!query && !options.similarTo) { + console.error('Provide a search query or use --similar-to '); + process.exit(1); + } + const spinner = ora('Searching...').start(); try { - // Load config (optional — defaults to cwd) const config = await loadConfig(); const repositoryPath = config?.repository?.path || config?.repositoryPath || process.cwd(); const resolvedRepoPath = path.resolve(repositoryPath); - // Get centralized storage paths const storagePath = await getStoragePath(resolvedRepoPath); await ensureStorageDirectory(storagePath); const filePaths = getStorageFilePaths(storagePath); - spinner.text = 'Initializing indexer...'; const indexer = new RepositoryIndexer({ repositoryPath: resolvedRepoPath, vectorStorePath: filePaths.vectors, @@ -43,38 +47,59 @@ export const searchCommand = new Command('search') await indexer.initialize(); - spinner.text = `Searching for: ${chalk.cyan(query)}`; + // If --similar-to is provided, use file content as the search query + let searchQuery = query || ''; + let similarFile = ''; + if (options.similarTo) { + spinner.text = 'Reading file content...'; + try { + const fileInfo = await prepareFileForSearch(resolvedRepoPath, options.similarTo); + searchQuery = fileInfo.content; + similarFile = fileInfo.relativePath; + } catch (error) { + spinner.fail((error as Error).message); + await indexer.close(); + process.exit(1); + } + } + + spinner.text = options.similarTo + ? `Finding code similar to: ${chalk.cyan(options.similarTo)}` + : `Searching for: ${chalk.cyan(query)}`; - const results = await indexer.search(query, { - limit: Number.parseInt(options.limit, 10), + const limit = Number.parseInt(options.limit, 10); + const results = await indexer.search(searchQuery, { + limit: similarFile ? limit + 1 : limit, scoreThreshold: Number.parseFloat(options.threshold), }); await indexer.close(); + // Filter out the source file for similar-to searches + const filtered = similarFile + ? results.filter((r) => (r.metadata.path as string) !== similarFile).slice(0, limit) + : results; + spinner.stop(); - if (results.length === 0) { + if (filtered.length === 0) { output.log(''); output.warn('No results found. Try:'); - output.log(` • Lower threshold: ${chalk.cyan('--threshold 0.3')}`); output.log(` • Different keywords`); output.log(` • Re-index: ${chalk.cyan('dev index --force')}`); output.log(''); return; } - // Output as JSON if requested if (options.json) { - console.log(JSON.stringify(results, null, 2)); + console.log(JSON.stringify(filtered, null, 2)); return; } - // Pretty print results (compact or verbose) output.log(''); - output.success(`Found ${results.length} result(s)`); + output.success(`Found ${filtered.length} result(s)`); output.log(''); - output.log(formatSearchResults(results, resolvedRepoPath, { verbose: options.verbose })); + output.log(formatSearchResults(filtered, resolvedRepoPath, { verbose: options.verbose })); output.log(''); } catch (error) { spinner.fail('Search failed'); diff --git a/packages/cli/src/utils/config.test.ts b/packages/cli/src/utils/config.test.ts index 01db737..3c573df 100644 --- a/packages/cli/src/utils/config.test.ts +++ b/packages/cli/src/utils/config.test.ts @@ -39,21 +39,18 @@ describe('Config Utilities', () => { expect(config.repositoryPath).toBe(process.cwd()); }); - it('should include all 9 MCP adapters', () => { + it('should include all 6 MCP adapters', () => { const config = getDefaultConfig('/test/path'); const adapters = config.mcp?.adapters; expect(adapters).toBeDefined(); - expect(Object.keys(adapters ?? {})).toHaveLength(9); + expect(Object.keys(adapters ?? {})).toHaveLength(6); // Verify all adapters are present and enabled by default expect(adapters?.search?.enabled).toBe(true); expect(adapters?.refs?.enabled).toBe(true); expect(adapters?.map?.enabled).toBe(true); - expect(adapters?.history?.enabled).toBe(true); - expect(adapters?.plan?.enabled).toBe(true); - expect(adapters?.explore?.enabled).toBe(true); - expect(adapters?.github?.enabled).toBe(true); + expect(adapters?.inspect?.enabled).toBe(true); expect(adapters?.status?.enabled).toBe(true); expect(adapters?.health?.enabled).toBe(true); }); diff --git a/packages/cli/src/utils/config.ts b/packages/cli/src/utils/config.ts index fab5976..6ced408 100644 --- a/packages/cli/src/utils/config.ts +++ b/packages/cli/src/utils/config.ts @@ -219,10 +219,7 @@ export function getDefaultConfig(repositoryPath: string = process.cwd()): DevAge search: { enabled: true }, refs: { enabled: true }, map: { enabled: true }, - history: { enabled: true }, - plan: { enabled: true }, - explore: { enabled: true }, - github: { enabled: true }, + inspect: { enabled: true }, status: { enabled: true }, health: { enabled: true }, }, diff --git a/packages/core/src/indexer/README.md b/packages/core/src/indexer/README.md index 26d2c92..3905d84 100644 --- a/packages/core/src/indexer/README.md +++ b/packages/core/src/indexer/README.md @@ -45,7 +45,7 @@ import { RepositoryIndexer } from '@prosdevlab/dev-agent-core'; // Initialize indexer const indexer = new RepositoryIndexer({ repositoryPath: '/path/to/repo', - vectorStorePath: './.dev-agent/vectors.lance', + vectorStorePath: './.dev-agent/vectors', }); await indexer.initialize(); @@ -109,7 +109,7 @@ const indexer = new RepositoryIndexer({ vectorStorePath: './.vectors/my-repo.lance', // Custom embedding model - embeddingModel: 'Xenova/all-MiniLM-L6-v2', + embeddingModel: 'BAAI/bge-small-en-v1.5', embeddingDimension: 384, // Batch size for embedding generation @@ -167,8 +167,8 @@ if (stats.errors.length > 0) { ```typescript { repositoryPath: '/Users/dev/my-project', - vectorStorePath: './.dev-agent/vectors.lance', - embeddingModel: 'Xenova/all-MiniLM-L6-v2', + vectorStorePath: './.dev-agent/vectors', + embeddingModel: 'BAAI/bge-small-en-v1.5', embeddingDimension: 384, batchSize: 32, excludePatterns: ['**/node_modules/**'], @@ -238,7 +238,7 @@ async function indexRepository(repoPath: string) { // Create indexer const indexer = new RepositoryIndexer({ repositoryPath: repoPath, - vectorStorePath: path.join(repoPath, '.dev-agent', 'vectors.lance'), + vectorStorePath: path.join(repoPath, '.dev-agent', 'vectors'), batchSize: 32, excludePatterns: [ '**/node_modules/**', @@ -318,7 +318,7 @@ The indexer maintains state for incremental updates: ```typescript { version: "1.0.0", - embeddingModel: "Xenova/all-MiniLM-L6-v2", + embeddingModel: "BAAI/bge-small-en-v1.5", embeddingDimension: 384, repositoryPath: "/path/to/repo", lastIndexTime: "2025-11-22T10:00:00.000Z", @@ -443,7 +443,7 @@ interface IndexProgress { // Simple setup works great for most repos const indexer = new RepositoryIndexer({ repositoryPath: './my-repo', - vectorStorePath: './.dev-agent/vectors.lance', + vectorStorePath: './.dev-agent/vectors', }); ``` @@ -547,7 +547,7 @@ const stats = await indexer.index({ // Increase batch size (uses more memory) const indexer = new RepositoryIndexer({ repositoryPath: './repo', - vectorStorePath: './vectors.lance', + vectorStorePath: './vectors', batchSize: 64, // Default is 32 }); ``` @@ -558,7 +558,7 @@ const indexer = new RepositoryIndexer({ // Decrease batch size const indexer = new RepositoryIndexer({ repositoryPath: './repo', - vectorStorePath: './vectors.lance', + vectorStorePath: './vectors', batchSize: 16, // Lower batch size }); ``` diff --git a/packages/core/src/observability/README.md b/packages/core/src/observability/README.md index 0968ca6..b03ad4c 100644 --- a/packages/core/src/observability/README.md +++ b/packages/core/src/observability/README.md @@ -125,8 +125,8 @@ tracker.failRequest(ctx.requestId, 'Timeout after 30s'); Track parent-child relationships: ```typescript -const parent = tracker.startRequest('dev_plan', { issue: 42 }); -const child = tracker.startRequest('dev_inspect', { action: 'compare' }, parent.requestId); +const parent = tracker.startRequest('dev_search', { query: 'auth' }); +const child = tracker.startRequest('dev_patterns', { action: 'compare' }, parent.requestId); // child.parentId === parent.requestId ``` @@ -144,8 +144,8 @@ const metrics = tracker.getMetrics(); // p99Duration: 890, // byTool: { // 'dev_search': { count: 500, avgDuration: 100 }, -// 'dev_inspect': { count: 300, avgDuration: 200 }, -// 'dev_plan': { count: 200, avgDuration: 180 } +// 'dev_patterns': { count: 300, avgDuration: 200 }, +// 'dev_refs': { count: 200, avgDuration: 180 } // } // } ``` diff --git a/packages/core/src/observability/__tests__/observability.test.ts b/packages/core/src/observability/__tests__/observability.test.ts index 25befd9..e78beb2 100644 --- a/packages/core/src/observability/__tests__/observability.test.ts +++ b/packages/core/src/observability/__tests__/observability.test.ts @@ -184,11 +184,11 @@ describe('RequestTracker', () => { describe('startRequest', () => { it('should create request context with unique ID', () => { const ctx1 = tracker.startRequest('dev_search', { query: 'auth' }); - const ctx2 = tracker.startRequest('dev_inspect', { action: 'compare' }); + const ctx2 = tracker.startRequest('dev_patterns', { action: 'compare' }); expect(ctx1.requestId).not.toBe(ctx2.requestId); expect(ctx1.tool).toBe('dev_search'); - expect(ctx2.tool).toBe('dev_inspect'); + expect(ctx2.tool).toBe('dev_patterns'); }); it('should emit request.started event', async () => { @@ -207,8 +207,8 @@ describe('RequestTracker', () => { }); it('should track parent ID for nested requests', () => { - const parent = tracker.startRequest('dev_plan', { issue: 1 }); - const child = tracker.startRequest('dev_inspect', { action: 'compare' }, parent.requestId); + const parent = tracker.startRequest('dev_search', { query: 'auth' }); + const child = tracker.startRequest('dev_patterns', { action: 'compare' }, parent.requestId); expect(child.parentId).toBe(parent.requestId); }); @@ -282,7 +282,7 @@ describe('RequestTracker', () => { tracker.completeRequest(ctx.requestId); } - const ctx = tracker.startRequest('dev_inspect', {}); + const ctx = tracker.startRequest('dev_patterns', {}); tracker.failRequest(ctx.requestId, 'error'); const metrics = tracker.getMetrics(); @@ -291,7 +291,7 @@ describe('RequestTracker', () => { expect(metrics.failed).toBe(1); expect(metrics.avgDuration).toBeGreaterThan(0); expect(metrics.byTool.dev_search.count).toBe(5); - expect(metrics.byTool.dev_inspect.count).toBe(1); + expect(metrics.byTool.dev_patterns.count).toBe(1); }); it('should calculate percentiles', async () => { diff --git a/packages/core/src/vector/README.md b/packages/core/src/vector/README.md index 98d67b4..2c7df5d 100644 --- a/packages/core/src/vector/README.md +++ b/packages/core/src/vector/README.md @@ -1,13 +1,13 @@ # Vector Storage System -Local-first semantic search powered by **LanceDB** and **Transformers.js**. +Local-first semantic search powered by **Antfly** and **Antfly Termite (ONNX)**. ## Overview The vector storage system provides semantic search capabilities for code and documentation. It combines: -- **LanceDB**: Embedded vector database with efficient columnar storage -- **Transformers.js**: Local ML model (all-MiniLM-L6-v2) for generating embeddings +- **Antfly**: Hybrid search backend with BM25 + vector search and RRF fusion +- **Antfly Termite (ONNX)**: Local ML model (BAAI/bge-small-en-v1.5) for generating embeddings - **Zero configuration**: No API keys, servers, or external dependencies - **Offline-capable**: Models cached locally after first download @@ -23,18 +23,18 @@ The vector storage system provides semantic search capabilities for code and doc │ │ ▼ ▼ ┌───────────────────┐ ┌──────────────────┐ -│ TransformersEmbedder│ │ LanceDBVectorStore│ -│ - all-MiniLM-L6-v2 │ │ - Vector search │ -│ - 384 dimensions │ │ - Metadata │ -│ - Local inference │ │ - Persistence │ +│ TermiteEmbedder │ │ AntflyVectorStore │ +│ - bge-small-en │ │ - Hybrid search │ +│ - 384 dimensions │ │ - BM25 + vector │ +│ - Local inference │ │ - Persistence │ └───────────────────┘ └──────────────────┘ ``` ### Key Components 1. **VectorStorage** - Main interface for semantic search -2. **TransformersEmbedder** - Converts text to 384-dim vectors -3. **LanceDBVectorStore** - Stores and searches vectors efficiently +2. **TermiteEmbedder** - Converts text to 384-dim vectors via Antfly Termite (ONNX) +3. **AntflyVectorStore** - Stores and searches vectors via Antfly hybrid search ## Usage Examples @@ -43,9 +43,9 @@ The vector storage system provides semantic search capabilities for code and doc ```typescript import { VectorStorage } from '@prosdevlab/dev-agent-core'; -// Initialize with default settings (all-MiniLM-L6-v2, 384 dimensions) +// Initialize with default settings (BAAI/bge-small-en-v1.5, 384 dimensions) const storage = new VectorStorage({ - storePath: './vector-data/my-project.lance', + storePath: './vector-data/my-project', }); await storage.initialize(); @@ -217,7 +217,7 @@ const documents = scanResult.documents.map((doc) => ({ // 3. Initialize vector storage const storage = new VectorStorage({ - storePath: './vector-data/my-repo.lance', + storePath: './vector-data/my-repo', }); await storage.initialize(); @@ -255,16 +255,16 @@ await storage.close(); ### Comparison to Alternatives -| Feature | Our Approach (LanceDB) | Hash-based (claude-flow) | +| Feature | Our Approach (Antfly) | Hash-based (claude-flow) | |---------|------------------------|--------------------------| -| **Search Type** | Semantic similarity | Lexical pattern matching | +| **Search Type** | Hybrid (BM25 + vector + RRF) | Lexical pattern matching | | **Query Time** | ~10-20ms | <1ms | | **Quality** | Finds conceptually similar code | Requires lexical overlap | -| **Setup** | Download 50MB model once | Zero setup | +| **Setup** | `dev setup` (one-time) | Zero setup | | **Use Case** | Code intelligence, RAG | Pattern cache, exact match | -| **Offline** | ✅ Full offline after download | ✅ Always offline | +| **Offline** | ✅ Full offline after setup | ✅ Always offline | -**Why LanceDB for Code Intelligence?** +**Why Antfly for Code Intelligence?** ```typescript // Semantic search finds these as related even with different words: @@ -298,7 +298,7 @@ class VectorStorage { // Get document by ID getDocument(id: string): Promise - // Delete documents (not yet implemented for LanceDB) + // Delete documents deleteDocuments(ids: string[]): Promise // Get statistics @@ -313,8 +313,8 @@ class VectorStorage { ```typescript interface VectorStorageConfig { - storePath: string; // Path to LanceDB store - embeddingModel?: string; // Default: 'Xenova/all-MiniLM-L6-v2' + storePath: string; // Path to Antfly store + embeddingModel?: string; // Default: 'BAAI/bge-small-en-v1.5' dimension?: number; // Default: 384 } @@ -348,8 +348,8 @@ interface VectorStats { ```typescript const storage = new VectorStorage({ - storePath: './data.lance', - embeddingModel: 'Xenova/all-MiniLM-L12-v2', // Larger model + storePath: './data', + embeddingModel: 'BAAI/bge-small-en-v1.5', dimension: 384, }); ``` @@ -359,10 +359,10 @@ const storage = new VectorStorage({ For more control, use the components directly: ```typescript -import { TransformersEmbedder, LanceDBVectorStore } from '@prosdevlab/dev-agent-core'; +import { TermiteEmbedder, AntflyVectorStore } from '@prosdevlab/dev-agent-core'; // 1. Create embedder -const embedder = new TransformersEmbedder(); +const embedder = new TermiteEmbedder(); await embedder.initialize(); // 2. Generate embeddings @@ -370,7 +370,7 @@ const texts = ['First text', 'Second text']; const embeddings = await embedder.embedBatch(texts); // 3. Create store -const store = new LanceDBVectorStore('./data.lance'); +const store = new AntflyVectorStore('./data'); await store.initialize(); // 4. Store vectors @@ -390,7 +390,7 @@ const results = await store.search(queryEmbedding, { limit: 5 }); ### Batch Size Tuning ```typescript -const embedder = new TransformersEmbedder(); +const embedder = new TermiteEmbedder(); await embedder.initialize(); // Default is 32, adjust based on memory constraints @@ -467,16 +467,13 @@ async function indexNewFile(filePath: string) { ### Current Limitations -1. **Delete operation**: Not yet implemented for LanceDB (requires API update) -2. **Model size**: 50MB download on first run (cached thereafter) +1. **Model size**: Download on first run (cached thereafter) 3. **Context length**: Model supports ~512 tokens (use summaries for long docs) 4. **Multi-language**: Single model for all languages (language-specific models possible) ### Future Enhancements -- [ ] Implement delete operation when LanceDB API stabilizes - [ ] Add support for larger embedding models (768, 1024 dimensions) -- [ ] Implement hybrid search (semantic + keyword) - [ ] Add re-ranking for improved precision - [ ] Support for incremental updates (modify existing documents) - [ ] Metadata filtering in search queries @@ -513,7 +510,7 @@ await storage.initialize(); // Will re-attempt download ```typescript // Reduce batch size for memory-constrained environments -const embedder = new TransformersEmbedder(); +const embedder = new TermiteEmbedder(); embedder.setBatchSize(8); // Lower batch size ``` @@ -521,7 +518,7 @@ embedder.setBatchSize(8); // Lower batch size ```typescript // Ensure model is initialized once and reused -const storage = new VectorStorage({ storePath: './data.lance' }); +const storage = new VectorStorage({ storePath: './data' }); await storage.initialize(); // Do this once // Reuse for multiple operations diff --git a/packages/dev-agent/README.md b/packages/dev-agent/README.md index 981d985..747bec3 100644 --- a/packages/dev-agent/README.md +++ b/packages/dev-agent/README.md @@ -27,8 +27,6 @@ dev mcp install # For Claude Code ## Features - 🔍 **Semantic Code Search** - Natural language queries across your codebase -- 🐙 **GitHub Integration** - Search issues/PRs with semantic understanding -- 📋 **Implementation Planning** - Generate plans from GitHub issues with code context - 🔎 **Code Exploration** - Discover patterns, find similar code, analyze relationships - 💚 **Health Monitoring** - Check component status and system health - 📊 **Repository Status** - View indexing progress and statistics @@ -38,16 +36,15 @@ dev mcp install # For Claude Code When integrated with Cursor or Claude Code, you get 6 powerful tools: - `dev_search` - Semantic code search +- `dev_refs` - Find callers/callees of functions +- `dev_map` - Codebase structure with change frequency +- `dev_patterns` - File analysis and pattern checking - `dev_status` - Repository status and health -- `dev_inspect` - File analysis and pattern checking -- `dev_plan` - Implementation planning from issues -- `dev_gh` - GitHub issue/PR search - `dev_health` - Component health checks ## Requirements - Node.js >= 22 (LTS) -- For GitHub integration: [GitHub CLI](https://cli.github.com/) ## Production Features @@ -86,8 +83,8 @@ dev --help # Help for specific command ## How It Works 1. **Index** - Scans your TypeScript/JavaScript codebase and builds semantic vectors -2. **Search** - Uses local embeddings (all-MiniLM-L6-v2) for semantic understanding -3. **Store** - LanceDB vector storage, all data stays on your machine +2. **Search** - Uses local embeddings (BAAI/bge-small-en-v1.5) for semantic understanding +3. **Store** - Antfly hybrid search (BM25 + vector), all data stays on your machine 4. **Integrate** - MCP protocol connects to Cursor/Claude Code 5. **Query** - AI tools can now understand your codebase semantically @@ -102,8 +99,8 @@ All processing happens on your machine: ## Technology - **Analysis:** TypeScript Compiler API + ts-morph -- **Embeddings:** @xenova/transformers (all-MiniLM-L6-v2) -- **Vector Storage:** LanceDB +- **Embeddings:** Antfly Termite (ONNX, BAAI/bge-small-en-v1.5) +- **Vector Storage:** Antfly (hybrid search: BM25 + vector + RRF) - **GitHub:** GitHub CLI for local metadata - **Protocol:** Model Context Protocol (MCP) @@ -113,14 +110,8 @@ All processing happens on your machine: # Find authentication-related code dev_search: "JWT token validation middleware" -# Plan implementation from GitHub issue -dev_plan: issue #42 - # Find similar code patterns -dev_inspect: { action: "compare", query: "src/auth/middleware.ts" } - -# Search GitHub issues semantically -dev_gh: search "memory leak in vector storage" +dev_patterns: { action: "compare", query: "src/auth/middleware.ts" } # Check system health dev_health: verbose diff --git a/packages/mcp-server/CLAUDE_CODE_SETUP.md b/packages/mcp-server/CLAUDE_CODE_SETUP.md index 0ba5294..839f6c9 100644 --- a/packages/mcp-server/CLAUDE_CODE_SETUP.md +++ b/packages/mcp-server/CLAUDE_CODE_SETUP.md @@ -48,7 +48,7 @@ Show me the repository status - `section`: `summary`, `repo`, `indexes`, `github`, `health` (default: `summary`) - `format`: `compact` (default) or `verbose` -### `dev_inspect` - File Analysis +### `dev_patterns` - File Analysis Inspect specific files, compare implementations, validate patterns. ``` @@ -66,42 +66,6 @@ Compare src/auth/middleware.ts with similar implementations - `limit`: Number of results (default: 10, for compare action) - `format`: Output format (`compact` or `verbose`) -### `dev_plan` - Generate Implementation Plans -Create actionable implementation plans from GitHub issues. - -``` -Generate a plan for GitHub issue #42 -``` - -**Parameters:** -- `issue` (required): GitHub issue number -- `detailLevel`: `simple` (4-8 tasks) or `detailed` (10-15 tasks, default) -- `useExplorer`: Use semantic search for relevant code (default: true) -- `format`: `compact` (default) or `verbose` - -### `dev_gh` - GitHub Issue/PR Search -Search GitHub issues and pull requests with semantic understanding. - -``` -Find issues related to authentication bugs -``` - -**Actions:** -- `search`: Semantic search across issues/PRs -- `context`: Get full context for an issue/PR -- `related`: Find related issues/PRs - -**Parameters:** -- `action` (required): Search action -- `query`: Search query (for `search` action) -- `number`: Issue/PR number (for `context`/`related` actions) -- `type`: Filter by `issue` or `pull_request` -- `state`: Filter by `open`, `closed`, or `merged` -- `labels`: Filter by labels (e.g., `["bug", "enhancement"]`) -- `limit`: Number of results (default: 10) - -**Note:** Automatically reloads when you run `dev github index` to update GitHub data. - ### `dev_health` - Server Health Check Check the health of dev-agent MCP server and its components. @@ -139,18 +103,18 @@ Claude Code uses different config locations than Claude Desktop: ## GitHub Integration -To enable GitHub issue/PR search: +GitHub issues and PRs are indexed automatically when you run `dev index`. To enable GitHub search, make sure the `gh` CLI is installed and authenticated: ```bash -# Index GitHub issues and PRs -cd /path/to/your/repository -dev github index +gh auth status +# If not logged in: +gh auth login -# The dev_gh tool will automatically pick up new data +# Then index (includes GitHub data by default) +cd /path/to/your/repository +dev index ``` -**Auto-Reload:** The MCP server detects changes to the GitHub index and reloads automatically - no restart needed! - ## Manual Configuration (Advanced) If you prefer manual setup instead of using `dev mcp install`, you can configure Claude Code directly: @@ -236,16 +200,15 @@ dev index ### GitHub Tools Not Working -**Cause:** GitHub data not indexed. +**Cause:** GitHub data not indexed, or `gh` CLI not authenticated. **Solution:** ```bash +gh auth status cd /path/to/your/repository -dev github index +dev index ``` -The `dev_gh` tool will automatically reload the new data. - ### Zombie Processes If you notice multiple `dev` processes: @@ -282,7 +245,7 @@ Check server health with verbose details **Common Issues:** - **Vector storage warning:** Run `dev index` -- **GitHub index stale (>24h):** Run `dev github index` +- **GitHub index stale (>24h):** Run `dev index` - **Repository not accessible:** Check paths and permissions ## Production Features @@ -341,7 +304,6 @@ npm update -g dev-agent # Rebuild indexes (recommended) cd /path/to/your/repository dev index -dev github index # Restart Claude Code ``` @@ -351,7 +313,7 @@ No need to reinstall MCP integration - it automatically uses the latest version. ## Performance Tips 1. **Index Incrementally:** Run `dev index` after major changes -2. **GitHub Index:** Update periodically with `dev github index` +2. **GitHub Index:** Re-run `dev index` to refresh GitHub data 3. **Health Checks:** Use `dev_health` to monitor component status 4. **Verbose Only When Needed:** Keep `LOG_LEVEL: info` for production diff --git a/packages/mcp-server/CURSOR_SETUP.md b/packages/mcp-server/CURSOR_SETUP.md index 443a388..8efd776 100644 --- a/packages/mcp-server/CURSOR_SETUP.md +++ b/packages/mcp-server/CURSOR_SETUP.md @@ -48,7 +48,7 @@ Show me the repository status - `section`: `summary`, `repo`, `indexes`, `github`, `health` (default: `summary`) - `format`: `compact` (default) or `verbose` -### `dev_inspect` - File Analysis +### `dev_patterns` - File Analysis Inspect specific files, compare implementations, validate patterns. ``` @@ -66,42 +66,6 @@ Compare src/auth/middleware.ts with similar implementations - `limit`: Number of results (default: 10, for compare action) - `format`: Output format (`compact` or `verbose`) -### `dev_plan` - Generate Implementation Plans -Create actionable implementation plans from GitHub issues. - -``` -Generate a plan for GitHub issue #42 -``` - -**Parameters:** -- `issue` (required): GitHub issue number -- `detailLevel`: `simple` (4-8 tasks) or `detailed` (10-15 tasks, default) -- `useExplorer`: Use semantic search for relevant code (default: true) -- `format`: `compact` (default) or `verbose` - -### `dev_gh` - GitHub Issue/PR Search -Search GitHub issues and pull requests with semantic understanding. - -``` -Find issues related to authentication bugs -``` - -**Actions:** -- `search`: Semantic search across issues/PRs -- `context`: Get full context for an issue/PR -- `related`: Find related issues/PRs - -**Parameters:** -- `action` (required): Search action -- `query`: Search query (for `search` action) -- `number`: Issue/PR number (for `context`/`related` actions) -- `type`: Filter by `issue` or `pull_request` -- `state`: Filter by `open`, `closed`, or `merged` -- `labels`: Filter by labels (e.g., `["bug", "enhancement"]`) -- `limit`: Number of results (default: 10) - -**Note:** Automatically reloads when you run `dev github index` to update GitHub data. - ### `dev_health` - Server Health Check Check the health of dev-agent MCP server and its components. @@ -139,18 +103,18 @@ Dev-agent intelligently detects your current workspace: ## GitHub Integration -To enable GitHub issue/PR search: +GitHub issues and PRs are indexed automatically when you run `dev index`. To enable GitHub search, make sure the `gh` CLI is installed and authenticated: ```bash -# Index GitHub issues and PRs -cd /path/to/your/repository -dev github index +gh auth status +# If not logged in: +gh auth login -# The dev_gh tool will automatically pick up new data +# Then index (includes GitHub data by default) +cd /path/to/your/repository +dev index ``` -**Auto-Reload:** The MCP server detects changes to the GitHub index and reloads automatically - no restart needed! - ## Manual Configuration (Advanced) If you prefer manual setup, the CLI creates this configuration in Cursor's `mcp.json`: @@ -230,16 +194,15 @@ dev index ### GitHub Tools Not Working -**Cause:** GitHub data not indexed. +**Cause:** GitHub data not indexed, or `gh` CLI not authenticated. **Solution:** ```bash +gh auth status cd /path/to/your/repository -dev github index +dev index ``` -The `dev_gh` tool will automatically reload the new data. - ### Zombie Processes If you notice multiple `dev` processes: @@ -276,7 +239,7 @@ Check server health with verbose details **Common Issues:** - **Vector storage warning:** Run `dev index` -- **GitHub index stale (>24h):** Run `dev github index` +- **GitHub index stale (>24h):** Run `dev index` - **Repository not accessible:** Check paths and permissions ## Production Features @@ -320,7 +283,6 @@ npm update -g dev-agent # Rebuild indexes (recommended) cd /path/to/your/repository dev index -dev github index # Restart Cursor ``` @@ -330,7 +292,7 @@ No need to reinstall MCP integration - it automatically uses the latest version. ## Performance Tips 1. **Index Incrementally:** Run `dev index` after major changes -2. **GitHub Index:** Update periodically with `dev github index` +2. **GitHub Index:** Re-run `dev index` to refresh GitHub data 3. **Health Checks:** Use `dev_health` to monitor component status 4. **Verbose Only When Needed:** Keep `LOG_LEVEL: info` for production diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 457ac8a..715b3ee 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -122,55 +122,18 @@ The MCP server provides 5 powerful adapters (tools) and 8 guided prompts: - GitHub integration status - Health checks -3. **`dev_plan`** - Generate implementation plans from GitHub issues - - Fetch issue details - - Find relevant code - - Break down into tasks - -4. **`dev_inspect`** - File analysis and pattern validation +3. **`dev_patterns`** - File analysis and pattern validation - Compare similar implementations - Validate pattern consistency - File-focused deep analysis -5. **`dev_gh`** - GitHub issue and PR search - - Semantic search with filters - - Full context retrieval - - Offline operation with cache - - **Auto-reload**: Automatically picks up new data when `dev github index` runs - -### Auto-Reload Feature - -The GitHub adapter automatically reloads index data when it detects changes, eliminating the need to restart the MCP server: - -- **How it works**: Monitors GitHub state file modification time -- **When it reloads**: On next query after `dev github index` updates the data -- **No user action required**: Changes are picked up automatically -- **Efficient**: Only checks file timestamps (no polling) - -**Example workflow:** -```bash -# 1. Query GitHub data in Claude Code/Cursor -> Use dev_gh to search for "authentication issues" - -# 2. Update the index (in terminal) -$ dev github index -✓ Indexed 59 documents (32 issues + 27 PRs) - -# 3. Query again - new data appears automatically! -> Use dev_gh to search for "authentication issues" -# Results now include newly created issues #58, #59 -``` - ### Prompts (Guided Workflows) -1. **`analyze-issue`** - Full issue analysis with implementation plan -2. **`find-pattern`** - Search codebase for specific patterns -3. **`repo-overview`** - Comprehensive repository health dashboard -4. **`find-similar`** - Find code similar to a file -5. **`search-github`** - Search issues/PRs by topic -6. **`explore-relationships`** - Analyze file dependencies -7. **`create-plan`** - Generate detailed task breakdown -8. **`quick-search`** - Fast semantic code search +1. **`find-pattern`** - Search codebase for specific patterns +2. **`repo-overview`** - Comprehensive repository health dashboard +3. **`find-similar`** - Find code similar to a file +4. **`explore-relationships`** - Analyze file dependencies +5. **`quick-search`** - Fast semantic code search All tools include **token cost footers** (🪙) for real-time cost tracking! @@ -395,22 +358,16 @@ All adapters are fully tested and production-ready: - GitHub integration status (auto-reloads on change) - Health checks and storage metrics -- **PlanAdapter** (`dev_plan`) - Implementation planning from GitHub issues + - Issue fetching and analysis - Semantic code search for relevant files - Task breakdown with complexity estimates -- **InspectAdapter** (`dev_inspect`) - File analysis +- **InspectAdapter** (`dev_patterns`) - File analysis - Compare similar implementations - Pattern consistency checking - Relationship mapping -- **GitHubAdapter** (`dev_gh`) - GitHub issue and PR management - - Semantic search with filters - - Full context retrieval - - Works offline with cached data - - **Auto-reload**: Automatically picks up index updates without restart - - Token cost display: 🪙 ~36 tokens (compact) to ~462 tokens (verbose) ## Configuration diff --git a/packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts b/packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts index d5b9c78..ec52d20 100644 --- a/packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts +++ b/packages/mcp-server/src/adapters/__tests__/inspect-adapter.test.ts @@ -1,7 +1,7 @@ /** * InspectAdapter Unit Tests * - * Tests for the refactored single-purpose dev_inspect tool + * Tests for the refactored single-purpose dev_patterns tool */ import * as path from 'node:path'; @@ -51,7 +51,7 @@ describe('InspectAdapter', () => { it('should return correct tool definition', () => { const definition = adapter.getToolDefinition(); - expect(definition.name).toBe('dev_inspect'); + expect(definition.name).toBe('dev_patterns'); expect(definition.description).toContain('pattern'); expect(definition.description).toContain('similar'); expect(definition.inputSchema.required).toContain('query'); @@ -99,19 +99,6 @@ describe('InspectAdapter', () => { expect(result.error?.code).toBe('INVALID_PARAMS'); }); - it('should reject invalid threshold', async () => { - const result = await adapter.execute( - { - query: 'src/test.ts', - threshold: 1.5, - }, - mockContext - ); - - expect(result.success).toBe(false); - expect(result.error?.code).toBe('INVALID_PARAMS'); - }); - it('should accept valid inputs', async () => { vi.mocked(mockSearchService.findSimilar).mockResolvedValue([ { @@ -126,7 +113,6 @@ describe('InspectAdapter', () => { { query: 'modern-typescript.ts', limit: 10, - threshold: 0.7, format: 'compact', }, mockContext @@ -134,7 +120,6 @@ describe('InspectAdapter', () => { expect(result.success).toBe(true); expect(typeof result.data).toBe('string'); - // Metadata contains counts expect(result.metadata).toHaveProperty('similar_files_count'); expect(result.metadata).toHaveProperty('patterns_analyzed'); }); @@ -169,7 +154,7 @@ describe('InspectAdapter', () => { expect(result.success).toBe(true); expect(mockSearchService.findSimilar).toHaveBeenCalledWith('modern-typescript.ts', { limit: 15, // default 10 + 5 buffer for extension filtering - threshold: 0.7, + threshold: 0, }); // With mock data (files don't exist), counts may be 0 expect(result.metadata?.similar_files_count).toBeGreaterThanOrEqual(0); @@ -270,28 +255,10 @@ describe('InspectAdapter', () => { expect(result.success).toBe(true); expect(mockSearchService.findSimilar).toHaveBeenCalledWith('modern-typescript.ts', { limit: 10, // 5 + 5 buffer for extension filtering - threshold: 0.7, + threshold: 0, }); - // With mock data (files don't exist), count may vary expect(result.metadata?.similar_files_count).toBeGreaterThanOrEqual(0); }); - - it('should apply threshold correctly', async () => { - vi.mocked(mockSearchService.findSimilar).mockResolvedValue([]); - - await adapter.execute( - { - query: 'modern-typescript.ts', - threshold: 0.9, - }, - mockContext - ); - - expect(mockSearchService.findSimilar).toHaveBeenCalledWith('modern-typescript.ts', { - limit: 15, // default 10 + 5 buffer - threshold: 0.9, - }); - }); }); describe('Output Formatting', () => { diff --git a/packages/mcp-server/src/adapters/built-in/inspect-adapter.ts b/packages/mcp-server/src/adapters/built-in/inspect-adapter.ts index 451fe0e..ff30236 100644 --- a/packages/mcp-server/src/adapters/built-in/inspect-adapter.ts +++ b/packages/mcp-server/src/adapters/built-in/inspect-adapter.ts @@ -70,17 +70,17 @@ export class InspectAdapter extends ToolAdapter { getToolDefinition(): ToolDefinition { return { - name: 'dev_inspect', + name: 'dev_patterns', description: - 'Inspect a file for pattern analysis. Finds similar code and compares patterns ' + - '(error handling, naming, types, structure). Returns facts about how this file ' + - 'compares to similar code, without making judgments.', + 'Analyze coding patterns in a file against the codebase. Compares import style, ' + + 'error handling, type coverage, test coverage, and file size against similar files. ' + + 'Use for code reviews and consistency checks.', inputSchema: { type: 'object', properties: { query: { type: 'string', - description: 'File path to inspect (e.g., "src/auth/middleware.ts")', + description: 'File path to analyze (e.g., "src/auth/middleware.ts")', }, limit: { type: 'number', @@ -89,13 +89,6 @@ export class InspectAdapter extends ToolAdapter { minimum: 1, maximum: 50, }, - threshold: { - type: 'number', - description: `Similarity threshold 0-1 (default: ${this.defaultThreshold})`, - default: this.defaultThreshold, - minimum: 0, - maximum: 1, - }, format: { type: 'string', enum: ['compact', 'verbose'], @@ -116,13 +109,12 @@ export class InspectAdapter extends ToolAdapter { return validation.error; } - const { query, limit, threshold, format } = validation.data; + const { query, limit, format } = validation.data; try { - context.logger.debug('Executing file inspection', { + context.logger.debug('Executing pattern analysis', { query, limit, - threshold, format, }); @@ -130,7 +122,7 @@ export class InspectAdapter extends ToolAdapter { const { content, similarFilesCount, patternsAnalyzed } = await this.inspectFile( query, limit, - threshold, + 0, // No threshold — let the pattern service decide relevance format ); diff --git a/packages/mcp-server/src/schemas/__tests__/schemas.test.ts b/packages/mcp-server/src/schemas/__tests__/schemas.test.ts index 6f00a0b..2b787e5 100644 --- a/packages/mcp-server/src/schemas/__tests__/schemas.test.ts +++ b/packages/mcp-server/src/schemas/__tests__/schemas.test.ts @@ -36,7 +36,6 @@ describe('InspectArgsSchema', () => { if (result.success) { expect(result.data).toMatchObject({ limit: 10, - threshold: 0.7, format: 'compact', }); } @@ -59,15 +58,6 @@ describe('InspectArgsSchema', () => { expect(result.success).toBe(false); }); - it('should reject out-of-range threshold', () => { - const result = InspectArgsSchema.safeParse({ - query: 'test', - threshold: 1.5, - }); - - expect(result.success).toBe(false); - }); - it('should reject unknown properties', () => { const result = InspectArgsSchema.safeParse({ query: 'test', diff --git a/packages/mcp-server/src/schemas/index.ts b/packages/mcp-server/src/schemas/index.ts index 5093e4d..8b8ce24 100644 --- a/packages/mcp-server/src/schemas/index.ts +++ b/packages/mcp-server/src/schemas/index.ts @@ -32,7 +32,6 @@ export const InspectArgsSchema = z .object({ query: z.string().min(1, 'Query must be a non-empty string (file path)'), limit: z.number().int().min(1).max(50).default(10), - threshold: z.number().min(0).max(1).default(0.7), format: FormatSchema.default('compact'), }) .strict(); // Reject unknown properties diff --git a/packages/mcp-server/src/server/__tests__/prompts.test.ts b/packages/mcp-server/src/server/__tests__/prompts.test.ts index 7e763c8..7eb9333 100644 --- a/packages/mcp-server/src/server/__tests__/prompts.test.ts +++ b/packages/mcp-server/src/server/__tests__/prompts.test.ts @@ -10,12 +10,6 @@ describe('PromptRegistry', () => { expect(prompts.length).toBeGreaterThan(0); }); - it('should include analyze-issue prompt', () => { - const registry = new PromptRegistry(); - - expect(registry.hasPrompt('analyze-issue')).toBe(true); - }); - it('should include find-pattern prompt', () => { const registry = new PromptRegistry(); @@ -35,7 +29,7 @@ describe('PromptRegistry', () => { const prompts = registry.listPrompts(); expect(Array.isArray(prompts)).toBe(true); - expect(prompts.length).toBeGreaterThan(5); + expect(prompts.length).toBeGreaterThan(3); }); it('should return prompt definitions with name and description', () => { @@ -51,26 +45,26 @@ describe('PromptRegistry', () => { it('should include prompt arguments', () => { const registry = new PromptRegistry(); const prompts = registry.listPrompts(); - const analyzeIssue = prompts.find((p) => p.name === 'analyze-issue'); + const findPattern = prompts.find((p) => p.name === 'find-pattern'); - expect(analyzeIssue?.arguments).toBeDefined(); - expect(analyzeIssue?.arguments?.length).toBeGreaterThan(0); + expect(findPattern?.arguments).toBeDefined(); + expect(findPattern?.arguments?.length).toBeGreaterThan(0); }); it('should mark required arguments', () => { const registry = new PromptRegistry(); const prompts = registry.listPrompts(); - const analyzeIssue = prompts.find((p) => p.name === 'analyze-issue'); - const issueNumArg = analyzeIssue?.arguments?.find((a) => a.name === 'issue_number'); + const findPattern = prompts.find((p) => p.name === 'find-pattern'); + const descArg = findPattern?.arguments?.find((a) => a.name === 'description'); - expect(issueNumArg?.required).toBe(true); + expect(descArg?.required).toBe(true); }); }); describe('getPrompt', () => { it('should retrieve prompt by name', () => { const registry = new PromptRegistry(); - const prompt = registry.getPrompt('analyze-issue', { issue_number: '42' }); + const prompt = registry.getPrompt('find-pattern', { description: 'error handling' }); expect(prompt).toBeDefined(); expect(prompt?.messages).toBeDefined(); @@ -85,19 +79,18 @@ describe('PromptRegistry', () => { it('should generate messages with arguments', () => { const registry = new PromptRegistry(); - const prompt = registry.getPrompt('analyze-issue', { issue_number: '42' }); + const prompt = registry.getPrompt('find-pattern', { description: 'error handling' }); expect(prompt?.messages).toHaveLength(1); expect(prompt?.messages[0].role).toBe('user'); - expect(prompt?.messages[0].content.text).toContain('#42'); + expect(prompt?.messages[0].content.text).toContain('error handling'); }); it('should include description', () => { const registry = new PromptRegistry(); - const prompt = registry.getPrompt('analyze-issue', { issue_number: '42' }); + const prompt = registry.getPrompt('find-pattern', { description: 'test' }); expect(prompt?.description).toBeDefined(); - expect(prompt?.description).toContain('issue'); }); it('should handle prompts without arguments', () => { @@ -108,20 +101,6 @@ describe('PromptRegistry', () => { expect(prompt?.messages).toBeDefined(); }); - it('should handle optional arguments', () => { - const registry = new PromptRegistry(); - const withDetail = registry.getPrompt('analyze-issue', { - issue_number: '42', - detail_level: 'simple', - }); - const withoutDetail = registry.getPrompt('analyze-issue', { issue_number: '42' }); - - // When detail_level is provided, it appears in the prompt - expect(withDetail?.messages[0].content.text).toContain('detailLevel "simple"'); - // When not provided, it doesn't appear - expect(withoutDetail?.messages[0].content.text).not.toContain('detailLevel'); - }); - it('should use default empty args when not provided', () => { const registry = new PromptRegistry(); const prompt = registry.getPrompt('repo-overview'); @@ -131,12 +110,11 @@ describe('PromptRegistry', () => { it('should generate different messages for different args', () => { const registry = new PromptRegistry(); - const prompt1 = registry.getPrompt('analyze-issue', { issue_number: '42' }); - const prompt2 = registry.getPrompt('analyze-issue', { issue_number: '99' }); + const prompt1 = registry.getPrompt('find-similar', { file_path: 'src/a.ts' }); + const prompt2 = registry.getPrompt('find-similar', { file_path: 'src/b.ts' }); - expect(prompt1?.messages[0].content.text).toContain('#42'); - expect(prompt2?.messages[0].content.text).toContain('#99'); - expect(prompt1?.messages[0].content.text).not.toEqual(prompt2?.messages[0].content.text); + expect(prompt1?.messages[0].content.text).toContain('src/a.ts'); + expect(prompt2?.messages[0].content.text).toContain('src/b.ts'); }); }); @@ -144,15 +122,14 @@ describe('PromptRegistry', () => { it('should return true for existing prompt', () => { const registry = new PromptRegistry(); - expect(registry.hasPrompt('analyze-issue')).toBe(true); expect(registry.hasPrompt('find-pattern')).toBe(true); + expect(registry.hasPrompt('repo-overview')).toBe(true); }); it('should return false for non-existent prompt', () => { const registry = new PromptRegistry(); expect(registry.hasPrompt('non-existent')).toBe(false); - expect(registry.hasPrompt('random-prompt')).toBe(false); }); }); @@ -160,13 +137,10 @@ describe('PromptRegistry', () => { it('should include all expected workflow prompts', () => { const registry = new PromptRegistry(); const expectedPrompts = [ - 'analyze-issue', 'find-pattern', 'repo-overview', 'find-similar', - 'search-github', 'explore-relationships', - 'create-plan', 'quick-search', ]; @@ -175,33 +149,19 @@ describe('PromptRegistry', () => { } }); - it('should register exactly 8 prompts', () => { + it('should register exactly 5 prompts', () => { const registry = new PromptRegistry(); const prompts = registry.listPrompts(); - expect(prompts).toHaveLength(8); + expect(prompts).toHaveLength(5); }); it('should provide user-facing messages', () => { const registry = new PromptRegistry(); - const prompts = registry.listPrompts(); - - for (const promptDef of prompts) { - // Provide required arguments based on prompt - const args: Record = {}; - if (promptDef.arguments) { - for (const arg of promptDef.arguments) { - if (arg.required) { - args[arg.name] = arg.name === 'issue_number' ? '42' : 'test-value'; - } - } - } - - const prompt = registry.getPrompt(promptDef.name, args); - expect(prompt?.messages[0].role).toBe('user'); - expect(prompt?.messages[0].content.type).toBe('text'); - expect(prompt?.messages[0].content.text.length).toBeGreaterThan(0); - } + // Test with a prompt that has no required args + const prompt = registry.getPrompt('repo-overview'); + expect(prompt?.messages.length).toBeGreaterThan(0); + expect(prompt?.messages[0].content.text.length).toBeGreaterThan(0); }); }); }); diff --git a/packages/mcp-server/src/server/prompts.ts b/packages/mcp-server/src/server/prompts.ts index e56f7c6..750d0f8 100644 --- a/packages/mcp-server/src/server/prompts.ts +++ b/packages/mcp-server/src/server/prompts.ts @@ -41,44 +41,6 @@ export class PromptRegistry { * Register default prompts that ship with dev-agent */ private registerDefaultPrompts(): void { - // Analyze GitHub Issue - this.register( - { - name: 'analyze-issue', - description: 'Analyze a GitHub issue and create an implementation plan', - arguments: [ - { - name: 'issue_number', - description: 'GitHub issue number to analyze', - required: true, - }, - { - name: 'detail_level', - description: 'Level of detail for the plan (simple or detailed)', - required: false, - }, - ], - }, - (args) => ({ - description: `Analyze GitHub issue #${args.issue_number} and create implementation plan`, - messages: [ - { - role: 'user', - content: { - type: 'text', - text: `Please analyze GitHub issue #${args.issue_number} and create a detailed implementation plan. - -Steps: -1. Use dev_gh with action "context" to get full issue details and related items -2. Use dev_search to find relevant code that needs to be modified -3. Use dev_plan to generate a structured implementation plan${args.detail_level ? ` with detailLevel "${args.detail_level}"` : ''} -4. Summarize the approach, key files, and estimated complexity`, - }, - }, - ], - }) - ); - // Search for Code Pattern this.register( { @@ -137,11 +99,9 @@ Then provide: text: `Provide a comprehensive overview of the repository status: 1. Use dev_status with section "summary" and format "verbose" for detailed stats -2. Use dev_gh with action "search" to find recent open issues (limit 5) -3. Summarize: +2. Summarize: - Repository health (indexing status, storage size) - Code metrics (files, components, vectors) - - GitHub activity (open issues, recent PRs) - Any recommendations for maintenance`, }, }, @@ -176,7 +136,7 @@ Then provide: type: 'text', text: `Find code that is similar to "${args.file_path}": -Use dev_inspect with: +Use dev_patterns with: - query: "${args.file_path}"${args.threshold ? `\n- threshold: ${args.threshold}` : ''} - format: "verbose" @@ -191,55 +151,6 @@ Then explain: }) ); - // Search GitHub Issues/PRs - this.register( - { - name: 'search-github', - description: 'Search GitHub issues and pull requests by topic', - arguments: [ - { - name: 'query', - description: - 'What to search for (e.g., "authentication bug", "performance improvement")', - required: true, - }, - { - name: 'type', - description: 'Filter by type: "issue" or "pull_request"', - required: false, - }, - { - name: 'state', - description: 'Filter by state: "open", "closed", or "merged"', - required: false, - }, - ], - }, - (args) => ({ - description: `Search GitHub for: ${args.query}`, - messages: [ - { - role: 'user', - content: { - type: 'text', - text: `Search GitHub for "${args.query}": - -Use dev_gh with: -- action: "search" -- query: "${args.query}"${args.type ? `\n- type: "${args.type}"` : ''}${args.state ? `\n- state: "${args.state}"` : ''} -- limit: 10 - -Provide: -1. Summary of relevant items found -2. Key themes or patterns -3. Status overview (how many open vs closed) -4. Suggestions for next steps`, - }, - }, - ], - }) - ); - // Code Relationships this.register( { @@ -264,7 +175,7 @@ Provide: Use dev_refs to find what calls or is called by functions in this file. -Alternatively, use dev_inspect with: +Alternatively, use dev_patterns with: - query: "${args.file_path}" - format: "verbose" @@ -282,54 +193,6 @@ Then explain: }) ); - // Implementation Planning - this.register( - { - name: 'create-plan', - description: 'Create detailed implementation plan for a GitHub issue', - arguments: [ - { - name: 'issue_number', - description: 'GitHub issue number to plan for', - required: true, - }, - { - name: 'detail_level', - description: 'Plan detail level: "simple" or "detailed" (default)', - required: false, - }, - { - name: 'use_explorer', - description: 'Use semantic search to find relevant code (true/false, default: true)', - required: false, - }, - ], - }, - (args) => ({ - description: `Create implementation plan for issue #${args.issue_number}`, - messages: [ - { - role: 'user', - content: { - type: 'text', - text: `Create an implementation plan for GitHub issue #${args.issue_number}: - -Use dev_plan with: -- issue: ${args.issue_number}${args.detail_level ? `\n- detailLevel: "${args.detail_level}"` : ''}${args.use_explorer === 'false' ? '\n- useExplorer: false' : ''} - -The tool will: -1. Fetch the issue details -2. Find relevant code using semantic search -3. Break down the work into specific tasks -4. Estimate complexity and dependencies - -Review the plan and suggest any modifications or improvements.`, - }, - }, - ], - }) - ); - // Quick Search this.register( { diff --git a/website/content/docs/cli.mdx b/website/content/docs/cli.mdx index 16e2a90..f6c4c3d 100644 --- a/website/content/docs/cli.mdx +++ b/website/content/docs/cli.mdx @@ -22,20 +22,11 @@ dev index /path/to/repo ``` **What gets indexed:** -- ✅ Code (always) -- ✅ Git history (if in a git repo) -- ✅ GitHub issues/PRs (if gh CLI installed and authenticated) - -Shows an upfront "indexing plan" before starting. - **Options:** | Flag | Description | |------|-------------| | `-f, --force` | Force re-index even if unchanged | | `-v, --verbose` | Show verbose output | -| `--no-git` | Skip git history indexing | -| `--no-github` | Skip GitHub issues/PRs indexing | -| `--git-limit ` | Max git commits to index (default: 500) | ### `dev search` @@ -43,134 +34,18 @@ Search your indexed code semantically. ```bash dev search "authentication logic" -dev search "error handling" --limit 5 --threshold 0.4 +dev search "error handling" --verbose +dev search --similar-to src/auth.ts # Find similar code ``` **Options:** | Flag | Description | Default | |------|-------------|---------| | `-l, --limit ` | Maximum results | 10 | -| `-t, --threshold ` | Minimum similarity (0-1) | 0.7 | +| `-s, --similar-to ` | Find code similar to a file | — | +| `-v, --verbose` | Show detailed results | false | | `--json` | Output as JSON | false | -**Threshold Guide:** -- `0.7+` — Precise matches only -- `0.4-0.6` — Balanced (good for most searches) -- `0.25-0.3` — Exploratory (finds related concepts) - -### `dev explore` - -Explore code patterns and relationships. - -```bash -# Find patterns semantically -dev explore pattern "error handling" --limit 5 - -# Find code similar to a file -dev explore similar path/to/file.ts -``` - -**Options:** -| Flag | Description | Default | -|------|-------------|---------| -| `-l, --limit ` | Maximum results | 10 | -| `-t, --threshold ` | Minimum similarity | 0.7 | - -### `dev plan` - -Assemble context for implementing a GitHub issue. - -```bash -dev plan 42 -dev plan 42 --include-comments --include-history -``` - -**Options:** -| Flag | Description | Default | -|------|-------------|---------| -| `--include-comments` | Include issue comments | true | -| `--include-history` | Include related PRs/issues | true | -| `--token-budget ` | Max tokens for output | 4000 | - -### `dev gh` - -Index and search GitHub issues/PRs. - -```bash -# Index GitHub metadata (also done by dev index) -dev github index - -# Search issues/PRs -dev github search "authentication bug" - -# Get context for an issue -dev github context --issue 42 -``` - -### `dev git` - -Index and search git commit history. - -```bash -# Index git history (also done by dev index) -dev git index -dev git index --limit 1000 --since "6 months ago" - -# Semantic search over commits -dev git search "authentication fix" -dev git search "bug fix" --limit 5 - -# Show indexed commit stats -dev git stats -``` - -**Subcommands:** -| Command | Description | -|---------|-------------| -| `dev git index` | Index git commit history | -| `dev git search ` | Semantic search over commits | -| `dev git stats` | Show indexed commit count | - -**Index Options:** -| Flag | Description | Default | -|------|-------------|---------| -| `--limit ` | Max commits to index | 500 | -| `--since ` | Only index commits after date | - | - -**Search Options:** -| Flag | Description | Default | -|------|-------------|---------| -| `--limit ` | Max results | 10 | -| `--json` | Output as JSON | false | - -### `dev update` - -Incrementally update the index with changed files. Much faster than full indexing - typically completes in seconds. - -```bash -dev update -dev update -v # Show what files changed -``` - -**Options:** -| Flag | Description | -|------|-------------| -| `-v, --verbose` | Show verbose output and which files changed | - -### `dev stats` - -Show indexing statistics. - -```bash -dev stats -dev stats --json -``` - -**Options:** -| Flag | Description | -|------|-------------| -| `--json` | Output as JSON | - ### `dev clean` Remove all indexed data. @@ -268,8 +143,8 @@ The `.dev-agent.json` file configures the indexer: ```json { "repositoryPath": "/path/to/repo", - "vectorStorePath": ".dev-agent/vectors.lance", - "embeddingModel": "Xenova/all-MiniLM-L6-v2", + "vectorStorePath": ".dev-agent/vectors", + "embeddingModel": "BAAI/bge-small-en-v1.5", "dimension": 384, "excludePatterns": [ "**/node_modules/**", @@ -293,11 +168,8 @@ dev index # Search for code dev search "user authentication" -# Search git history -dev git search "authentication fix" - -# View statistics -dev stats +# Explore code patterns +dev explore pattern "error handling" ``` ### Integration with Cursor @@ -317,18 +189,15 @@ dev mcp install --cursor ```bash # Get file paths from search dev search "coordinator" --json | jq '.[].metadata.path' | sort -u - -# Check if indexed -dev stats --json | jq '.filesIndexed' ``` ### Exploratory Search ```bash # Lower threshold for broader matches -dev search "architectural patterns" --threshold 0.25 --limit 10 +dev search "architectural patterns" --limit 10 # Find similar code -dev explore similar src/utils/retry.ts --threshold 0.3 +dev search --similar-to src/utils/retry.ts ``` diff --git a/website/content/docs/configuration.mdx b/website/content/docs/configuration.mdx index e98888e..b01b588 100644 --- a/website/content/docs/configuration.mdx +++ b/website/content/docs/configuration.mdx @@ -65,9 +65,7 @@ Control which MCP tools are enabled: | Adapter | Default | Tool | Description | |---------|---------|------|-------------| | `search` | enabled | `dev_search` | Semantic code search | -| `github` | enabled | `dev_gh` | GitHub issues/PRs search | -| `plan` | enabled | `dev_plan` | Context assembly for issues | -| `inspect` | enabled | `dev_inspect` | File analysis | +| `inspect` | enabled | `dev_patterns` | File analysis | | `status` | disabled | `dev_status` | Repository status | | `refs` | enabled | `dev_refs` | Relationship queries | | `map` | enabled | `dev_map` | Codebase overview | @@ -147,7 +145,7 @@ Dev-agent stores index data in `~/.dev-agent/indexes/`: ~/.dev-agent/ └── indexes/ └── {hash}/ # Per-repository storage - ├── vectors.lance # Vector embeddings + ├── vectors/ # Vector embeddings ├── metadata.json # Repository metadata ├── indexer-state.json └── github-state.json @@ -211,16 +209,16 @@ dev mcp uninstall ## Embedding Model -Dev-agent uses `Xenova/all-MiniLM-L6-v2` for embeddings: +Dev-agent uses `BAAI/bge-small-en-v1.5` for embeddings via Antfly Termite (ONNX): | Property | Value | |----------|-------| -| Model | all-MiniLM-L6-v2 | +| Model | BAAI/bge-small-en-v1.5 | | Dimensions | 384 | -| Provider | @xenova/transformers | +| Provider | Antfly Termite (ONNX) | | Location | Local (no API calls) | -The model is downloaded on first run (~23MB) and cached locally. +The model is downloaded on first run and cached locally. ## Advanced: Custom Exclude Patterns diff --git a/website/content/docs/index.mdx b/website/content/docs/index.mdx index 006b43f..79d040e 100644 --- a/website/content/docs/index.mdx +++ b/website/content/docs/index.mdx @@ -8,8 +8,7 @@ We built this for ourselves. When exploring large codebases, we found AI tools s 1. **Indexes your codebase** locally with embeddings (all-MiniLM-L6-v2) 2. **Returns code snippets** — not just file paths, reducing input tokens by 99% -3. **Bundles context** — `dev_plan` assembles issue + code + commits in one call -4. **Integrates with GitHub** to search issues and PRs semantically +3. **Provides semantic search** — find code by meaning, not just keywords ## Measured impact @@ -19,7 +18,7 @@ We benchmarked dev-agent against baseline Claude Code across different task type |-----------|--------------|--------------|-----| | **Debugging** | **42%** | 37% | Semantic search beats grep chains | | **Exploration** | **44%** | 19% | Find code by meaning | -| **Implementation** | **29%** | 22% | Context bundling via `dev_plan` | +| **Implementation** | **29%** | 22% | Semantic search finds relevant code | **Key insight:** Savings scale with task complexity. Simple lookups show no improvement; complex debugging shows 42% cost reduction. @@ -30,17 +29,14 @@ We benchmarked dev-agent against baseline Claude Code across different task type | What dev-agent does | Manual equivalent | Impact | |---------------------|-------------------|--------| | Returns code snippets in search | Read entire files | 99% fewer input tokens | -| `dev_plan` bundles issue + code + commits | 5-10 separate tool calls | 29% cost reduction | | Semantic search finds relevant code | grep chains + filtering | 42% cost reduction | ## Key Features | Feature | Description | |---------|-------------| -| **Context Bundling** | `dev_plan` replaces 5-10 tool calls with one | | **Code Snippets** | Search returns code, not just file paths | | **Semantic Search** | Find code by meaning, not keywords | -| **Git History** | Semantic search over commits | | **100% Local** | Your code never leaves your machine | ## Architecture @@ -49,7 +45,7 @@ dev-agent is a monorepo: - **@prosdevlab/dev-agent-core** — Scanning, vector storage, GitHub integration - **@prosdevlab/dev-agent-cli** — Command-line interface -- **@prosdevlab/dev-agent-mcp** — MCP server with 9 tool adapters +- **@prosdevlab/dev-agent-mcp** — MCP server with 6 tool adapters - **@prosdevlab/dev-agent-subagents** — Planner, explorer agents ## Next Steps diff --git a/website/content/docs/quickstart.mdx b/website/content/docs/quickstart.mdx index 89071bd..19ecef2 100644 --- a/website/content/docs/quickstart.mdx +++ b/website/content/docs/quickstart.mdx @@ -61,14 +61,8 @@ You'll get results like: Try these prompts: -**Planning from GitHub issues:** -> "Use dev_plan to create an implementation plan for issue #42" - **Find similar code:** -> "Use dev_inspect to compare src/utils/cache.ts with similar implementations" - -**Search GitHub issues:** -> "Use dev_gh to search for issues about performance" +> "Use dev_patterns to compare src/utils/cache.ts with similar implementations" ## What's Happening Under the Hood diff --git a/website/content/docs/tools/_meta.js b/website/content/docs/tools/_meta.js index 3fe168d..db98a95 100644 --- a/website/content/docs/tools/_meta.js +++ b/website/content/docs/tools/_meta.js @@ -3,10 +3,7 @@ export default { 'dev-search': 'dev_search', 'dev-refs': 'dev_refs', 'dev-map': 'dev_map', - 'dev-history': 'dev_history', - 'dev-plan': 'dev_plan', - 'dev-inspect': 'dev_inspect', - 'dev-github': 'dev_gh', + 'dev-patterns': 'dev_patterns', 'dev-status': 'dev_status', 'dev-health': 'dev_health', }; diff --git a/website/content/docs/tools/dev-github.mdx b/website/content/docs/tools/dev-github.mdx deleted file mode 100644 index d0665f7..0000000 --- a/website/content/docs/tools/dev-github.mdx +++ /dev/null @@ -1,118 +0,0 @@ -# dev_gh - -Search GitHub issues and pull requests using semantic search. Understand your project's history and context. - -> **Note:** The CLI command is `dev github`, but the MCP tool name is `dev_gh` for brevity in AI interactions. - -## Usage - -``` -dev_gh(action, query?, number?, format?, limit?, type?, state?, labels?, author?) -``` - -## Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `action` | `"search"` \| `"context"` \| `"related"` | required | Action type | -| `query` | string | — | Search query (for search action) | -| `number` | number | — | Issue/PR number (for context/related) | -| `format` | `"compact"` \| `"verbose"` | `"compact"` | Output format | -| `limit` | number | 10 | Maximum results | -| `type` | `"issue"` \| `"pull_request"` | all | Filter by type | -| `state` | `"open"` \| `"closed"` \| `"merged"` | all | Filter by state | -| `labels` | string[] | — | Filter by labels | -| `author` | string | — | Filter by author | - -## Actions - -### Search - -Semantic search across issues and PRs: - -> "Use dev_gh action search, query 'performance problems with large files'" - -``` -## GitHub Search Results -Query: "performance problems with large files" - -1. 🔴 #127: File upload times out for large files [92%] -2. 🟢 #98: Optimize chunked file processing [87%] -3. 🔵 PR #112: Add streaming for large file uploads [84%] -``` - -### Get Context - -Get full context for a specific issue or PR: - -> "Use dev_gh action context, number 42" - -``` -## Issue #42: Add user preferences API - -**State:** Open | **Author:** @developer | **Labels:** enhancement, api - -### Description -We need an API endpoint for user preferences... - -### Comments (3) -1. @reviewer: Should we use JSON or a dedicated table? -2. @developer: I'm thinking a separate preferences table... -3. @maintainer: Let's go with the table approach. - -### Related PRs -- PR #45: Database schema updates (merged) -``` - -### Find Related - -Find issues/PRs related to a specific one: - -> "Use dev_gh action related, number 42" - -``` -## Related to #42: Add user preferences API - -1. #38: User settings page redesign [89%] -2. #29: API authentication improvements [76%] -3. PR #45: Database schema updates [72%] -``` - -## Examples - -### Filter Open Bugs - -> "Use dev_gh action search, query 'crash', type issue, state open, labels ['bug']" - -### Find Author's Issues - -> "Use dev_gh action search, query 'refactor', author 'username'" - -## Requirements - -> ⚠️ **Index GitHub first.** Run `dev github index` to enable semantic search: -> ```bash -> dev github index -> ``` - -This fetches and indexes your repository's issues and PRs. - -## Tips - -> **Search by intent, not keywords.** Try "issues about slow API responses" instead of "performance". - -> **GitHub index auto-reloads.** Changes are detected automatically when you re-run `dev github index`. - -## Response Metadata - -```json -{ - "metadata": { - "tokens": 456, - "duration_ms": 234, - "results_total": 45, - "results_returned": 10 - } -} -``` - diff --git a/website/content/docs/tools/dev-history.mdx b/website/content/docs/tools/dev-history.mdx deleted file mode 100644 index 32ec8c5..0000000 --- a/website/content/docs/tools/dev-history.mdx +++ /dev/null @@ -1,124 +0,0 @@ -# dev_history - -Semantic search over git commit history. - -## Overview - -`dev_history` provides intelligent access to git history that goes beyond `git log --grep`: - -- **Semantic search** — Find commits by meaning, not just text matching -- **File history** — Track file changes with rename detection -- **Issue/PR refs** — Extracted from commit messages -- **Token-budgeted** — Output fits within specified limits - -This helps AI assistants understand *who changed what and why*. - -## Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `query` | string | - | Semantic search query (required for search mode) | -| `file` | string | - | File path for history (required for file mode) | -| `mode` | `"search"` \| `"file"` | `"search"` | Search commits or get file history | -| `limit` | number | `20` | Maximum commits to return | -| `since` | string | - | Start date (ISO format or relative like "30 days ago") | -| `until` | string | - | End date (ISO format or relative) | -| `author` | string | - | Filter by author name or email | -| `tokenBudget` | number | `2000` | Max tokens for output | -| `format` | `"compact"` \| `"verbose"` | `"compact"` | Output format | - -## Example Output - -### Semantic Search - -``` -dev_history: { query: "authentication token fix" } -``` - -```markdown -# Git History: "authentication token fix" - -## Commits (5 results) - -### 1. [92%] Fix JWT token refresh race condition -**Hash:** `a1b2c3d` | **Author:** alice | **Date:** 2024-01-15 -**Files:** `src/auth/token.ts`, `src/auth/refresh.ts` -**Refs:** #42, PR #45 - -Resolved issue where concurrent token refreshes could cause duplicate sessions. - ---- - -### 2. [87%] Add token expiry validation -**Hash:** `e4f5g6h` | **Author:** bob | **Date:** 2024-01-10 -**Files:** `src/auth/validate.ts` -**Refs:** #38 - -Added middleware to check token expiration before processing requests. -``` - -### File History - -``` -dev_history: { mode: "file", file: "src/auth/middleware.ts" } -``` - -```markdown -# File History: src/auth/middleware.ts - -## Changes (8 commits) - -| Date | Author | Message | Lines | -|------|--------|---------|-------| -| 2024-01-15 | alice | Fix JWT token refresh race condition | +12 -5 | -| 2024-01-10 | bob | Add token expiry validation | +45 -0 | -| 2024-01-05 | alice | Refactor auth middleware for clarity | +20 -35 | -| 2023-12-20 | carol | Initial authentication middleware | +150 -0 | -``` - -## How It Works - -1. **Indexing** — Commit messages are embedded and stored in vector storage -2. **Semantic search** — Queries are embedded and matched against commit embeddings -3. **File history** — Uses `git log --follow` for rename tracking -4. **Reference extraction** — Parses `#123`, `fixes #42`, `PR #45` from messages - -## Use Cases - -### Finding Related Changes - -``` -Find commits related to the database connection pooling issue -``` - -### Understanding Prior Work - -``` -What changes were made to authentication in the last month? -``` - -### Tracking File Evolution - -``` -Show me the history of src/core/indexer.ts -``` - -### Finding Bug Fixes - -``` -Find commits that fixed memory leaks -``` - -## Tips - -- **Use natural language** — "JWT refresh bug" not "fix: jwt" -- **Combine with `dev_plan`** — Related commits are included automatically -- **Check file history** — Before major refactors, understand the evolution -- **Filter by author** — Find changes by specific team members - -## Related Tools - -- [`dev_plan`](/docs/tools/dev-plan) — Includes related commits in context -- [`dev_map`](/docs/tools/dev-map) — Shows change frequency indicators -- [`dev_search`](/docs/tools/dev-search) — Search code, not commits - diff --git a/website/content/docs/tools/dev-map.mdx b/website/content/docs/tools/dev-map.mdx index 633a5e4..1381570 100644 --- a/website/content/docs/tools/dev-map.mdx +++ b/website/content/docs/tools/dev-map.mdx @@ -157,7 +157,6 @@ Focus on packages/core/src with depth 4 to see all scanner components ## Related Tools -- [`dev_history`](/docs/tools/dev-history) — Semantic search over git commits - [`dev_refs`](/docs/tools/dev-refs) — Query relationships for hot path files - [`dev_search`](/docs/tools/dev-search) — Search within focused area - [`dev_status`](/docs/tools/dev-status) — Check indexing completeness diff --git a/website/content/docs/tools/dev-inspect.mdx b/website/content/docs/tools/dev-patterns.mdx similarity index 79% rename from website/content/docs/tools/dev-inspect.mdx rename to website/content/docs/tools/dev-patterns.mdx index 86b2772..b400e1c 100644 --- a/website/content/docs/tools/dev-inspect.mdx +++ b/website/content/docs/tools/dev-patterns.mdx @@ -1,11 +1,11 @@ -# dev_inspect +# dev_patterns Inspect a file for pattern analysis. Finds similar code and compares patterns like error handling, type coverage, imports, and testing. ## Usage ``` -dev_inspect(query, format?, limit?, threshold?) +dev_patterns(query, format?, limit?, threshold?) ``` ## Parameters @@ -19,7 +19,7 @@ dev_inspect(query, format?, limit?, threshold?) ## What It Does -`dev_inspect` performs comprehensive file analysis in two steps: +`dev_patterns` performs comprehensive file analysis in two steps: 1. **Finds similar files** - Uses semantic search to find code with similar structure/purpose 2. **Analyzes patterns** - Compares error handling, type coverage, imports, testing, and file size @@ -30,7 +30,7 @@ This helps you understand how your file compares to similar code in the reposito ### Basic Inspection -> "Use dev_inspect with query 'src/auth/middleware.ts'" +> "Use dev_patterns with query 'src/auth/middleware.ts'" ``` ## File Inspection: src/auth/middleware.ts @@ -51,19 +51,19 @@ This helps you understand how your file compares to similar code in the reposito ### Verbose Output -> "Use dev_inspect with query 'packages/core/src/indexer/index.ts', format 'verbose'" +> "Use dev_patterns with query 'packages/core/src/indexer/index.ts', format 'verbose'" Returns detailed pattern distribution and statistics for each pattern category. ### High Similarity Only -> "Use dev_inspect with query 'src/utils/date.ts', threshold 0.9" +> "Use dev_patterns with query 'src/utils/date.ts', threshold 0.9" Only analyzes very similar files (90%+ match). ## Pattern Categories -`dev_inspect` analyzes 5 key patterns: +`dev_patterns` analyzes 5 key patterns: | Pattern | What It Checks | |---------|----------------| @@ -112,22 +112,22 @@ Shows full pattern distribution: **Typical usage pattern:** 1. **Search** for concepts: `dev_search { query: "authentication middleware" }` -2. **Inspect** what you found: `dev_inspect { query: "src/auth/middleware.ts" }` +2. **Inspect** what you found: `dev_patterns { query: "src/auth/middleware.ts" }` 3. **Analyze** dependencies: `dev_refs { name: "authMiddleware" }` ## Tips -> **Always provide a file path.** Unlike `dev_search`, `dev_inspect` requires a specific file to analyze. +> **Always provide a file path.** Unlike `dev_search`, `dev_patterns` requires a specific file to analyze. > **Extension filtering.** Only compares files with the same extension (e.g., `.ts` with `.ts`). -> **Use after search.** `dev_inspect` is most valuable after finding relevant files with `dev_search`. +> **Use after search.** `dev_patterns` is most valuable after finding relevant files with `dev_search`. > **Pattern-driven insights.** Focus on patterns where your file differs from similar code. ## Performance -`dev_inspect` is optimized for speed: +`dev_patterns` is optimized for speed: - Batch scanning (5-10x faster than individual scans) - Semantic similarity matching (not just path-based) - Extension-based filtering for relevant comparisons @@ -138,9 +138,9 @@ Typical analysis time: **500-1000ms** for 5 similar files. If you previously used `dev_explore`: -- `dev_explore { action: "similar", query: "file.ts" }` → `dev_inspect { query: "file.ts" }` -- `dev_explore { action: "validate", query: "file.ts" }` → `dev_inspect { query: "file.ts" }` (now does both!) +- `dev_explore { action: "similar", query: "file.ts" }` → `dev_patterns { query: "file.ts" }` +- `dev_explore { action: "validate", query: "file.ts" }` → `dev_patterns { query: "file.ts" }` (now does both!) - `dev_explore { action: "pattern" }` → Use `dev_search` instead - `dev_explore { action: "relationships" }` → Use `dev_refs` instead -**Key change:** `dev_inspect` no longer requires an `action` parameter. It automatically finds similar files AND performs pattern analysis in one call. +**Key change:** `dev_patterns` no longer requires an `action` parameter. It automatically finds similar files AND performs pattern analysis in one call. diff --git a/website/content/docs/tools/dev-plan.mdx b/website/content/docs/tools/dev-plan.mdx deleted file mode 100644 index 00e262e..0000000 --- a/website/content/docs/tools/dev-plan.mdx +++ /dev/null @@ -1,187 +0,0 @@ -# dev_plan - -Assemble rich context for implementing GitHub issues. - -## Overview - -`dev_plan` fetches a GitHub issue and assembles comprehensive context for AI assistants to create implementation plans. Instead of generating heuristic task breakdowns, it provides: - -- Full issue content with comments -- Relevant code snippets from semantic search -- **Related commits** from git history (v0.4+) -- Detected codebase patterns -- Metadata for token budgeting - -**Philosophy:** Provide data, let LLMs reason. AI assistants create better plans when given rich context. - -## Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `issue` | number | required | GitHub issue number | -| `format` | `"compact"` \| `"verbose"` | `"compact"` | Output format | -| `includeCode` | boolean | `true` | Include relevant code snippets | -| `includeHistory` | boolean | `true` | Include related commits ✨ v0.4 | -| `includePatterns` | boolean | `true` | Include codebase patterns | -| `tokenBudget` | number | `4000` | Max tokens for output | - -## Example Output - -### Compact Format - -```markdown -# Issue #42: Add user preferences API - -**Author:** alice | **State:** open | **Labels:** enhancement, api - -## Description - -We need an API endpoint for user preferences. Should support: -- GET /preferences - retrieve current preferences -- PUT /preferences - update preferences - -## Comments - -**bob** (2024-01-15): -Consider using the existing validation middleware from src/middleware/validation.ts - -## Relevant Code - -### UserController (class) -**File:** `src/api/controllers/user.ts` | **Relevance:** 85% -**Reason:** Similar pattern - -```typescript -export class UserController { - async getUser(req: Request, res: Response) { - // ... - } -} -``` - -### validateBody (function) -**File:** `src/middleware/validation.ts` | **Relevance:** 72% -**Reason:** Relevant type definition - -```typescript -export function validateBody(schema: Schema) { - // ... -} -``` - -## Codebase Patterns - -- **Test naming:** *.test.ts -- **Test location:** __tests__/ - -## Related Commits ✨ v0.4 - -### [92%] Add user preferences schema -**Hash:** `a1b2c3d` | **Author:** bob | **Date:** 2024-01-10 -Related to preferences feature groundwork. - -### [85%] Implement validation middleware -**Hash:** `e4f5g6h` | **Author:** alice | **Date:** 2024-01-05 -Similar pattern for request validation. - ---- -*Context assembled at 2024-01-20T10:30:00Z | ~1250 tokens* -``` - -### Verbose Format (JSON) - -```json -{ - "issue": { - "number": 42, - "title": "Add user preferences API", - "body": "We need an API endpoint...", - "labels": ["enhancement", "api"], - "author": "alice", - "comments": [...] - }, - "relevantCode": [ - { - "file": "src/api/controllers/user.ts", - "name": "UserController", - "type": "class", - "snippet": "export class UserController {...}", - "relevanceScore": 0.85, - "reason": "Similar pattern" - } - ], - "codebasePatterns": { - "testPattern": "*.test.ts", - "testLocation": "__tests__/" - }, - "metadata": { - "generatedAt": "2024-01-20T10:30:00Z", - "tokensUsed": 1250 - } -} -``` - -## How It Works - -1. **Fetch issue** — Retrieves issue with comments via GitHub CLI -2. **Search code** — Finds relevant code using semantic search -3. **Search history** — Finds related commits via semantic search (v0.4+) -4. **Detect patterns** — Identifies test naming and location patterns -5. **Assemble context** — Packages everything for LLM consumption - -## Requirements - -> ⚠️ **GitHub CLI required.** `dev_plan` uses `gh` to fetch issue data. - -```bash -# Install GitHub CLI -brew install gh # macOS -# or visit https://cli.github.com - -# Authenticate -gh auth login -``` - -## Use Cases - -### Implementation Planning - -``` -Assemble context for issue #42 so I can create an implementation plan -``` - -### Understanding Requirements - -``` -Get the full context for issue #123 including comments -``` - -### Code Discovery - -``` -What existing code is relevant to implementing issue #55? -``` - -## Tips - -- **Comments are valuable** — They often contain design decisions and constraints -- **Relevant code shows patterns** — Use it to understand existing conventions -- **Codebase patterns help** — Know where to put tests and how to name them -- **Token budget matters** — Reduce if context is too large - -## Migration from v0.2 - -In v0.2, `dev_plan` generated heuristic task breakdowns with estimates. In v0.3+, it returns raw context instead. - -**Why the change?** AI assistants create better plans when given comprehensive context rather than our heuristic guesses. - -**Old parameters removed:** -- `detailLevel` — No longer applicable -- `useExplorer` — Now always uses code search (controlled by `includeCode`) - -## Related Tools - -- [`dev_history`](/docs/tools/dev-history) — Search git history directly -- [`dev_search`](/docs/tools/dev-search) — Search for more relevant code -- [`dev_refs`](/docs/tools/dev-refs) — Understand relationships in relevant code -- [`dev_gh`](/docs/tools/dev-gh) — Search related issues/PRs diff --git a/website/content/docs/tools/dev-refs.mdx b/website/content/docs/tools/dev-refs.mdx index e235f81..3f58aef 100644 --- a/website/content/docs/tools/dev-refs.mdx +++ b/website/content/docs/tools/dev-refs.mdx @@ -122,5 +122,5 @@ Find everything that calls the old validateUser function - [`dev_search`](/docs/tools/dev-search) — Find symbols first - [`dev_map`](/docs/tools/dev-map) — See hot paths (most referenced files) -- [`dev_inspect`](/docs/tools/dev-inspect) — Find similar implementations +- [`dev_patterns`](/docs/tools/dev-inspect) — Find similar implementations diff --git a/website/content/docs/tools/index.mdx b/website/content/docs/tools/index.mdx index 788ed53..2078706 100644 --- a/website/content/docs/tools/index.mdx +++ b/website/content/docs/tools/index.mdx @@ -1,6 +1,6 @@ # MCP Tools Overview -dev-agent provides nine tools through the Model Context Protocol (MCP). These tools give AI assistants deep understanding of your codebase. +dev-agent provides six tools through the Model Context Protocol (MCP). These tools give AI assistants deep understanding of your codebase. ## Available Tools @@ -9,16 +9,13 @@ dev-agent provides nine tools through the Model Context Protocol (MCP). These to | [`dev_search`](/docs/tools/dev-search) | Semantic code search with snippets | | [`dev_refs`](/docs/tools/dev-refs) | Query code relationships (callers/callees) | | [`dev_map`](/docs/tools/dev-map) | Codebase structure overview with change frequency | -| [`dev_history`](/docs/tools/dev-history) | Semantic search over git commits ✨ v0.4 | -| [`dev_plan`](/docs/tools/dev-plan) | Assemble context for GitHub issues | -| [`dev_inspect`](/docs/tools/dev-inspect) | File pattern analysis (finds similar code, compares 5 pattern categories) ✨ v0.8.5 | -| [`dev_gh`](/docs/tools/dev-gh) | Search GitHub issues and PRs | +| [`dev_patterns`](/docs/tools/dev-inspect) | File pattern analysis (finds similar code, compares 5 pattern categories) ✨ v0.8.5 | | [`dev_status`](/docs/tools/dev-status) | Check repository indexing status | | [`dev_health`](/docs/tools/dev-health) | Monitor MCP server health | ## New in v0.8.5 -- **`dev_inspect`** — Refactored for comprehensive pattern analysis (5 categories) +- **`dev_patterns`** — Refactored for comprehensive pattern analysis (5 categories) - **Performance** — 5-10x faster pattern analysis via batch scanning (500-1000ms) - **Accuracy** — Semantic similarity using document embeddings, extension filtering - **Simplified API** — Streamlined interface (no action parameter needed) @@ -30,15 +27,12 @@ dev-agent provides nine tools through the Model Context Protocol (MCP). These to ## v0.4.0 -- **`dev_history`** — Semantic search over git commit history - **`dev_map`** — Change frequency indicators (🔥 hot, ✏️ active, 📝 recent) -- **`dev_plan`** — Related commits included in context assembly ## v0.3.0 - **`dev_refs`** — Query what calls what and what is called by what - **`dev_map`** — Get codebase overview with hot paths and smart depth -- **`dev_plan`** — Refactored to assemble context (no more heuristic task breakdown) ## How Tools Are Exposed @@ -54,10 +48,7 @@ AI Assistant (Cursor/Claude) ├── SearchAdapter → dev_search ├── RefsAdapter → dev_refs ├── MapAdapter → dev_map - ├── HistoryAdapter → dev_history ✨ v0.4 - ├── PlanAdapter → dev_plan - ├── InspectAdapter → dev_inspect - ├── GitHubAdapter → dev_gh + ├── InspectAdapter → dev_patterns ├── StatusAdapter → dev_status └── HealthAdapter → dev_health ``` @@ -97,6 +88,5 @@ Most tools support two output formats: ## Next Steps - [dev_search →](/docs/tools/dev-search) — Semantic code search -- [dev_history →](/docs/tools/dev-history) — Git commit search - [dev_refs →](/docs/tools/dev-refs) — Relationship queries - [dev_map →](/docs/tools/dev-map) — Codebase overview diff --git a/website/content/index.mdx b/website/content/index.mdx index 52b5b8a..71f1743 100644 --- a/website/content/index.mdx +++ b/website/content/index.mdx @@ -30,7 +30,6 @@ dev-agent doesn't just search — it **bundles context** so Claude reads less: | What dev-agent does | Manual equivalent | Savings | |---------------------|-------------------|---------| | Returns code snippets in search | Read entire files | 99% fewer input tokens | -| `dev_plan` bundles issue + code + commits | 5-10 separate tool calls | 29% cost reduction | | Semantic search finds relevant code | grep chains + manual filtering | 42% cost reduction | **The harder the task, the bigger the savings.** @@ -41,7 +40,7 @@ dev-agent doesn't just search — it **bundles context** so Claude reads less: |-----------|--------------|--------------|-----| | **Debugging** | **42%** | 37% | Semantic search beats grep for "where is the bug?" | | **Exploration** | **44%** | 19% | Find code by meaning, not keywords | -| **Implementation** | **29%** | 22% | `dev_plan` bundles context in one call | +| **Implementation** | **29%** | 22% | Semantic search finds relevant code | | **Simple lookup** | ~0% | ~0% | Both approaches are fast | @@ -94,39 +93,6 @@ We asked Claude Code: *"Debug why search returns duplicates"* **Same root cause identified. 42% cheaper. 37% faster.** -## Context bundling: `dev_plan` - -For implementation tasks, `dev_plan` bundles everything in one call: - - - - **Claude's approach for "Implement issue #61":** - ```bash - gh issue view 61 --json title,body # Fetch issue - grep "--json" -r packages/cli # Find existing flags - Read search.ts # Check implementation - Read mcp.ts # Check implementation - Read config.ts # Check file writes - # ... 5+ more tool calls - ``` - - **Result:** $0.55, 5.7 minutes - - - **Claude's approach:** - ```bash - dev_plan --issue 61 - # Returns in ONE call: - # - Issue details + comments - # - Relevant code snippets - # - Related commits (5 found) - # - Codebase patterns - ``` - - **Result:** $0.39, 4.5 minutes (**29% cheaper**) - - - ## How it works ```mermaid @@ -137,7 +103,7 @@ flowchart LR subgraph Agent["dev-agent"] B["MCP Server"] - C["9 Tools"] + C["6 Tools"] end subgraph Local["Antfly (local)"] @@ -177,17 +143,14 @@ dev mcp install # For Claude Code ``` -## 9 MCP Tools +## 6 MCP Tools | Tool | What it does | |------|--------------| | [`dev_search`](/docs/tools/dev-search) | Semantic code search — returns snippets, not just paths | -| [`dev_plan`](/docs/tools/dev-plan) | **Context bundling** — issue + code + commits in one call | | [`dev_refs`](/docs/tools/dev-refs) | Find callers/callees of any function | | [`dev_map`](/docs/tools/dev-map) | Codebase structure with change frequency | -| [`dev_history`](/docs/tools/dev-history) | Semantic search over git commits | -| [`dev_inspect`](/docs/tools/dev-inspect) | Inspect files (compare implementations, check patterns) | -| [`dev_gh`](/docs/tools/dev-gh) | Search GitHub issues/PRs semantically | +| [`dev_patterns`](/docs/tools/dev-inspect) | Inspect files (compare implementations, check patterns) | | [`dev_status`](/docs/tools/dev-status) | Repository indexing status | | [`dev_health`](/docs/tools/dev-health) | Server health checks | @@ -203,7 +166,6 @@ dev mcp install # For Claude Code ## Features -- **Context Bundling** — `dev_plan` replaces 5-10 tool calls with one - **Code Snippets** — Search returns code, not just file paths - **Multi-Language** — TypeScript, JavaScript, Go, Markdown - **100% Local** — Your code never leaves your machine diff --git a/website/content/latest-version.ts b/website/content/latest-version.ts index e49f9bc..e8e3df3 100644 --- a/website/content/latest-version.ts +++ b/website/content/latest-version.ts @@ -4,10 +4,10 @@ */ export const latestVersion = { - version: '0.10.0', - title: 'CLI UX Overhaul & Antfly Resilience', + version: '0.10.1', + title: 'Tool Refinements & Docs Cleanup', date: 'March 30, 2026', summary: - '7x faster indexing, native-first Antfly, auto-recovery, cleaner search/map output, new `dev reset` command.', - link: '/updates#v0100--cli-ux-overhaul--antfly-resilience', + 'Renamed dev_inspect → dev_patterns, merged dev explore into dev search, fixed search thresholds, expanded scanner exclusions.', + link: '/updates#v0101--tool-refinements--docs-cleanup', } as const; diff --git a/website/content/updates/index.mdx b/website/content/updates/index.mdx index ecdbcd3..3043fc7 100644 --- a/website/content/updates/index.mdx +++ b/website/content/updates/index.mdx @@ -9,6 +9,22 @@ What's new in dev-agent. We ship improvements regularly to help AI assistants un --- +## v0.10.1 — Tool Refinements & Docs Cleanup + +*March 30, 2026* + +**Cleaned up stale references, renamed `dev_inspect` → `dev_patterns`, merged `dev explore` into `dev search`.** + +- `dev_inspect` renamed to `dev_patterns` — focused on pattern analysis, removed redundant similar-files feature +- `dev explore` removed — `dev search --similar-to ` replaces it +- Search threshold default fixed (0.7 → 0) for RRF fusion scores +- Scanner exclusions expanded: `.env*`, `*.min.js`, `*.d.ts`, `generated/`, `.terraform/`, `.claude/` +- Removed 3 stale MCP prompts (analyze-issue, search-github, create-plan) +- Swept all docs for LanceDB/@xenova/transformers → Antfly/Termite references +- 1,620 tests passing, 0 failures + +--- + ## v0.10.0 — CLI UX Overhaul & Antfly Resilience *March 30, 2026* @@ -136,29 +152,29 @@ After: Scanner → Antfly (embed + store + hybrid search) *December 14, 2025* -**Refactored `dev_inspect` with 5-10x faster pattern analysis and comprehensive code comparison.** +**Refactored `dev_patterns` with 5-10x faster pattern analysis and comprehensive code comparison.** ### What's Changed -**🔄 Simplified `dev_inspect` Tool** +**🔄 Simplified `dev_patterns` Tool** -The `action` parameter has been streamlined. `dev_inspect` is now a single-purpose tool that automatically: +The `action` parameter has been streamlined. `dev_patterns` is now a single-purpose tool that automatically: - Finds similar files using semantic search - Analyzes and compares 5 pattern categories ```bash # Before (v0.8.4) -dev_inspect { action: "compare", query: "src/auth.ts" } +dev_patterns { action: "compare", query: "src/auth.ts" } # After (v0.8.5) - Simpler! -dev_inspect { query: "src/auth.ts" } +dev_patterns { query: "src/auth.ts" } ``` ### What's New **🔍 Comprehensive Pattern Analysis** -`dev_inspect` now analyzes 5 pattern categories automatically: +`dev_patterns` now analyzes 5 pattern categories automatically: 1. **Import Style** — ESM, CJS, mixed, or unknown 2. **Error Handling** — throw, result types, callbacks, or unknown @@ -242,7 +258,7 @@ dev_inspect { query: "src/auth.ts" } - Complete rewrite of dev-inspect.mdx - Updated README.md with pattern categories - Updated CLAUDE.md with new descriptions -- Migration guide from dev_explore to dev_inspect +- Migration guide from dev_explore to dev_patterns ### Testing @@ -256,13 +272,13 @@ dev_inspect { query: "src/auth.ts" } **API Simplification:** ```typescript // Old (v0.8.4) - Had action parameter -dev_inspect({ +dev_patterns({ action: "compare", query: "src/auth.ts" }) // New (v0.8.5) - Streamlined! -dev_inspect({ +dev_patterns({ query: "src/auth.ts" }) ``` @@ -302,9 +318,7 @@ Eliminated CLI commands that duplicate git/GitHub functionality: Dev-agent's **unique value** is semantic understanding: - ✅ **Semantic code search** (`dev_search`) — Find code by meaning, not keywords -- ✅ **Semantic commit search** (`dev_history`) — Search git history by concept -- ✅ **Code structure analysis** (`dev_map`, `dev_inspect`) — AST + embeddings -- ✅ **GitHub context** (`dev_plan`, `dev_gh`) — Cross-reference issues with code +- ✅ **Code structure analysis** (`dev_map`, `dev_patterns`) — AST + embeddings Git analytics (ownership, activity) are better served by existing tools: - Git CLI has excellent built-in analytics @@ -315,11 +329,11 @@ Git analytics (ownership, activity) are better served by existing tools: **Core semantic tools remain:** - `dev_search` — Semantic code search -- `dev_history` — Semantic commit search +- `dev_refs` — Relationship queries (callers/callees) - `dev_map` — Codebase structure with change frequency -- `dev_plan` — GitHub issue context assembly -- `dev_inspect` — File analysis (similarity + pattern checking) -- `dev_gh` — GitHub semantic search +- `dev_patterns` — File analysis (similarity + pattern checking) +- `dev_status` — Repository indexing status +- `dev_health` — Server health checks **Supporting infrastructure:** - `code_metadata` table — Introspection of indexed code (LOC, functions, imports) @@ -1032,11 +1046,11 @@ Hot Paths (most referenced): |------|---------| | `dev_search` | Semantic code search | | `dev_plan` | Context assembly for issues | -| `dev_inspect` | File analysis & pattern discovery | +| `dev_patterns` | File analysis & pattern discovery | | `dev_gh` | GitHub issue/PR search | | `dev_status` | Repository health | -> **Note:** `dev_inspect` was originally named `dev_explore` at launch. It was renamed and enhanced in v0.8.5 with comprehensive pattern analysis. +> **Note:** `dev_patterns` was originally named `dev_explore` at launch. It was renamed and enhanced in v0.8.5 with comprehensive pattern analysis. ### Installation