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%
3.7 KB · 116 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/tools/remember.ts4 * Description: The remember tool — persist a durable project fact into .khaelor/MEMORY.md with provenance (v2 design §5).5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import * as path from "node:path";11import type { ToolDefinition } from "./registry.js";12import type { ToolContext, ToolResult } from "./types.js";1314export interface RememberInput {15  fact: string;16  section: string;17  confidence?: string;18}1920const DESCRIPTION =21  "Persist a durable fact about this project into its memory (.khaelor/MEMORY.md) — a convention, a " +22  "build command, a pitfall, an architectural constraint. Use it when you discover something future " +23  "sessions must know. Do NOT store transient task state. section: conventions | commands | pitfalls " +24  "| architecture | notes. confidence defaults to medium.";2526const MEMORY_RELATIVE = ".khaelor/MEMORY.md";2728// Local re-implementation seam: the memory module's append logic is imported29// lazily to keep the tools layer free of static cross-module dependencies.30async function appendToMemory(31  existing: string | null,32  entry: {33    section: string;34    text: string;35    provenance: { session: string; tool: string; confidence: "high" | "medium" | "low"; date: string };36  },37): Promise<string> {38  const { appendMemoryEntry } = await import("../memory/store.js");39  return appendMemoryEntry(existing, entry);40}4142async function executeRemember(input: RememberInput, ctx: ToolContext): Promise<ToolResult> {43  const startedAt = Date.now();44  const fact = input.fact.trim();45  if (fact.length === 0) {46    return {47      content: 'Parameter "fact" must be a non-empty durable fact about the project.',48      isError: true,49      metadata: { title: "remember · empty fact", durationMs: Date.now() - startedAt },50    };51  }52  const confidence =53    input.confidence === "high" || input.confidence === "low" ? input.confidence : "medium";54  const filePath = path.join(ctx.workspace.cwd(), MEMORY_RELATIVE);5556  let existing: string | null = null;57  try {58    existing = await ctx.workspace.readFile(filePath);59  } catch {60    existing = null; // first memory — the file is created below61  }6263  const updated = await appendToMemory(existing, {64    section: input.section,65    text: fact,66    provenance: {67      session: ctx.sessionId,68      tool: ctx.callId,69      confidence,70      date: new Date().toISOString().slice(0, 10),71    },72  });73  await ctx.workspace.writeFile(filePath, updated);7475  ctx.emit({76    type: "memory.written",77    payload: { section: input.section, entry: fact, confidence, toolUseId: ctx.callId },78  });7980  return {81    content: `Remembered under "${input.section}" (confidence: ${confidence}).`,82    metadata: {83      title: `Remember · ${input.section}`,84      durationMs: Date.now() - startedAt,85      extra: { confidence },86    },87  };88}8990/** Build the remember tool (project memory, v2 §5). */91export function createRememberTool(): ToolDefinition<RememberInput> {92  return {93    name: "remember",94    description: DESCRIPTION,95    inputSchema: {96      type: "object",97      properties: {98        fact: { type: "string", description: "The durable fact, one or two sentences." },99        section: {100          type: "string",101          description: "Where it belongs: conventions, commands, pitfalls, architecture, or notes.",102          enum: ["conventions", "commands", "pitfalls", "architecture", "notes"],103        },104        confidence: {105          type: "string",106          description: "How certain you are: high, medium (default), or low.",107          enum: ["high", "medium", "low"],108        },109      },110      required: ["fact", "section"],111    },112    capability: "file.write",113    execute: executeRemember,114  };115}116