Files
boocode/apps/server/src/services/tools/registry.ts
indifferentketchup 23858e31cc feat(server): Domain 2 Phase 1 — boocontext MCP client + 4 new code intelligence tools
Shared boocontext MCP client (boocontext_client.ts) wrapping the existing
mcp-client.ts callTool() infrastructure with 32KB truncation and error
handling. Used by get_code_health.

4 new first-class agent tools backed by the boocontext MCP server:
- get_code_health — A-F grades per file across 7 dimensions, project health
  summary, refactoring candidates (wraps boocontext_health)
- get_code_impact — merged symbol trace + blast radius in one call (wraps
  boocontext_impact, replaces two-step get_symbol_info+get_blast_radius)
- get_type_info — TypeScript type recovery via type-inject MCP (wraps
  boocontext_types, returns signatures, interfaces, generics, JSDoc)
- get_code_map — DCP-compressed context map with compress toggle (wraps
  boocontext_map, 10x token reduction vs full scan)

All 4 registered in ALL_TOOLS as read-only tools.
2026-06-08 00:45:46 +00:00

107 lines
4.7 KiB
TypeScript

import type { ToolDef, ToolJsonSchema } from './types.js';
import { viewFile, listDir, grep, findFiles, viewTruncatedOutput } from './fs-tools.js';
import { gitStatus, skillFind, skillUse, skillResource, askUserInput } from './misc-tools.js';
import { webSearch } from '../web_search.js';
import { webFetch } from '../web_fetch.js';
// v1.12 Track B.2: codecontext tools. 8 wrappers re-exported from
// tools/codecontext/index.ts. Each calls into services/codecontext_client.ts
// which talks to the codecontext sidecar at http://codecontext:8080.
import {
getCodebaseOverview,
getFileAnalysis,
getSymbolInfo,
searchSymbols,
getDependencies,
watchChanges,
getSemanticNeighborhoods,
getFrameworkAnalysis,
getBlastRadius,
getHotFiles,
getRoutes,
getMiddleware,
getCodeHealth,
getCodeImpact,
getTypeInfo,
getCodeMap,
} from './codecontext/index.js';
// v1.13.17-cross-repo-reads: cross-repo read grant request tool. Paired
// with the pause-on-pending-grant branch in inference/tool-phase.ts and the
// POST /api/chats/:id/grant_read_access endpoint in routes/messages.ts.
import { requestReadAccess } from '../request_read_access.js';
// v2.6.x: read-only tool that reads a tab's transcript by its session-scoped
// tab number. Needs DB/session context (ToolExecCtx 4th arg).
import { readTabByNumber } from '../read_tab_by_number.js';
// v1.13.3: alpha-sorted by tool.name at module load. llama.cpp's prompt
// cache hits on byte-identical prefixes; the tool list lives near the top
// of the system prompt, so any order drift would invalidate every cached
// turn. Single source of truth for ordering lives here — toolJsonSchemas()
// and TOOLS_BY_NAME inherit it.
// v1.14.1-mcp-poc: changed from ReadonlyArray to let-bound mutable array
// so appendMcpTools() can push MCP-discovered tools at startup.
export let ALL_TOOLS: ToolDef<unknown>[] = [
viewFile as ToolDef<unknown>,
viewTruncatedOutput as ToolDef<unknown>,
listDir as ToolDef<unknown>,
grep as ToolDef<unknown>,
findFiles as ToolDef<unknown>,
gitStatus as ToolDef<unknown>,
skillFind as ToolDef<unknown>,
skillUse as ToolDef<unknown>,
skillResource as ToolDef<unknown>,
askUserInput as ToolDef<unknown>,
// v1.11.8: web tools. Gated per-chat via session.web_search_enabled
// (with project default fallback) — see effectiveTools filter in
// services/inference.ts.
webSearch as ToolDef<unknown>,
webFetch as ToolDef<unknown>,
// v1.12 Track B.2: codecontext tools. Backed by the codecontext sidecar
// container. All read-only. target_dir is resolved server-side from the
// project root in codecontext_client.ts (the LLM never supplies it).
getCodebaseOverview as ToolDef<unknown>,
getFileAnalysis as ToolDef<unknown>,
getSymbolInfo as ToolDef<unknown>,
searchSymbols as ToolDef<unknown>,
getDependencies as ToolDef<unknown>,
watchChanges as ToolDef<unknown>,
getSemanticNeighborhoods as ToolDef<unknown>,
getFrameworkAnalysis as ToolDef<unknown>,
// v1.16: codesight-merge tools. Backed by the same codecontext sidecar.
getBlastRadius as ToolDef<unknown>,
getHotFiles as ToolDef<unknown>,
getRoutes as ToolDef<unknown>,
getMiddleware as ToolDef<unknown>,
// v1.13.17-cross-repo-reads: paired with the pause-on-pending-grant
// branch in tool-phase.ts. Read-only — only ever READS files; the only
// state change is appending to sessions.allowed_read_paths via the
// grant endpoint, gated by user consent.
requestReadAccess as ToolDef<unknown>,
// v2.6.x: read a tab's transcript by its session-scoped tab number.
// Read-only; uses the ToolExecCtx 4th arg for DB/session access.
readTabByNumber as ToolDef<unknown>,
// v2.8.14-domain2-phase1: boocontext-backed tools. Backed by the boocontext
// MCP server. All read-only. Health, impact, types, map analysis.
getCodeHealth as ToolDef<unknown>,
getCodeImpact as ToolDef<unknown>,
getTypeInfo as ToolDef<unknown>,
getCodeMap as ToolDef<unknown>,
].sort((a, b) => a.name.localeCompare(b.name));
export let TOOLS_BY_NAME: Record<string, ToolDef<unknown>> = Object.fromEntries(
ALL_TOOLS.map((t) => [t.name, t])
);
// v1.14.1-mcp-poc: append MCP-discovered tools at startup. Called once
// from index.ts after mcpClient.initialize(). Re-sorts ALL_TOOLS and
// rebuilds TOOLS_BY_NAME. MCP tools are all read-only by construction
// (the read-only guard in mcp-client.ts rejects readOnlyHint: false).
export function appendMcpTools(mcpTools: ToolDef<unknown>[]): void {
if (mcpTools.length === 0) return;
ALL_TOOLS = [...ALL_TOOLS, ...mcpTools].sort((a, b) => a.name.localeCompare(b.name));
TOOLS_BY_NAME = Object.fromEntries(ALL_TOOLS.map((t) => [t.name, t]));
}
export function toolJsonSchemas(): ToolJsonSchema[] {
return ALL_TOOLS.map((t) => t.jsonSchema);
}