SPB Git

spb/khaelor Public

KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.

TypeScript 82.9% HTML 14.9% CSS 1.1% JavaScript 0.7%
2.9 KB · 92 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/tools/refs.ts4 * Description: The refs tool — who uses what: callers/callees/importers of a symbol via the RepoGraph index (v2 design §3).5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import type { ToolDefinition } from "./registry.js";11import type { ToolContext, ToolResult } from "./types.js";1213export interface RefsInput {14  symbol: string;15  direction: string;16}1718const DESCRIPTION =19  "Find usage sites of a symbol via the semantic index. direction: callers (who calls/uses it), " +20  "callees (what it calls), importers (which files import it). Each site comes with its line of " +21  "context. Use this to assess blast radius before editing a symbol.";2223const MAX_RESULTS = 80;2425async function executeRefs(input: RefsInput, ctx: ToolContext): Promise<ToolResult> {26  const startedAt = Date.now();27  if (ctx.repograph === undefined) {28    return {29      content:30        "The semantic index is unavailable in this session. Use grep to find usages instead.",31      isError: true,32      metadata: { title: "refs · index unavailable", durationMs: Date.now() - startedAt },33    };34  }35  const direction =36    input.direction === "callers" || input.direction === "callees" || input.direction === "importers"37      ? input.direction38      : null;39  if (direction === null) {40    return {41      content: 'Parameter "direction" must be one of: callers, callees, importers.',42      isError: true,43      metadata: { title: "refs · invalid direction", durationMs: Date.now() - startedAt },44    };45  }46  const hits = await ctx.repograph.queryRefs(input.symbol, direction);47  if (hits.length === 0) {48    return {49      content: `No ${direction} found for "${input.symbol}". The symbol may be unused, dynamic, or misspelled.`,50      metadata: {51        title: `Refs ${input.symbol} · 0`,52        durationMs: Date.now() - startedAt,53        matches: 0,54      },55    };56  }57  const shown = hits.slice(0, MAX_RESULTS);58  const lines = shown.map((hit) => `${hit.file}:${hit.line}  ${hit.context}`);59  const omitted = hits.length - shown.length;60  const tail = omitted > 0 ? `\n[... ${omitted} more sites omitted]` : "";61  return {62    content: lines.join("\n") + tail,63    metadata: {64      title: `Refs ${input.symbol} · ${hits.length} ${direction}`,65      durationMs: Date.now() - startedAt,66      matches: hits.length,67    },68  };69}7071/** Build the refs tool (RepoGraph, v2 §3). */72export function createRefsTool(): ToolDefinition<RefsInput> {73  return {74    name: "refs",75    description: DESCRIPTION,76    inputSchema: {77      type: "object",78      properties: {79        symbol: { type: "string", description: "The symbol name to trace." },80        direction: {81          type: "string",82          description: "callers | callees | importers",83          enum: ["callers", "callees", "importers"],84        },85      },86      required: ["symbol", "direction"],87    },88    capability: "file.read",89    execute: executeRefs,90  };91}92