Files
clawdbot/src/cli/memory-cli.ts
Peter Steinberger c379191f80 chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
2026-01-14 15:02:19 +00:00

123 lines
4.1 KiB
TypeScript

import chalk from "chalk";
import type { Command } from "commander";
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
import { loadConfig } from "../config/config.js";
import { getMemorySearchManager } from "../memory/index.js";
import { defaultRuntime } from "../runtime.js";
type MemoryCommandOptions = {
agent?: string;
json?: boolean;
};
function resolveAgent(cfg: ReturnType<typeof loadConfig>, agent?: string) {
const trimmed = agent?.trim();
if (trimmed) return trimmed;
return resolveDefaultAgentId(cfg);
}
export function registerMemoryCli(program: Command) {
const memory = program.command("memory").description("Memory search tools");
memory
.command("status")
.description("Show memory search index status")
.option("--agent <id>", "Agent id (default: default agent)")
.option("--json", "Print JSON")
.action(async (opts: MemoryCommandOptions) => {
const cfg = loadConfig();
const agentId = resolveAgent(cfg, opts.agent);
const { manager, error } = await getMemorySearchManager({ cfg, agentId });
if (!manager) {
defaultRuntime.log(error ?? "Memory search disabled.");
return;
}
const status = manager.status();
if (opts.json) {
defaultRuntime.log(JSON.stringify(status, null, 2));
return;
}
const lines = [
`${chalk.bold.cyan("Memory Search")} (${agentId})`,
`Provider: ${status.provider} (requested: ${status.requestedProvider})`,
status.fallback ? chalk.yellow(`Fallback: ${status.fallback.from}`) : null,
`Files: ${status.files}`,
`Chunks: ${status.chunks}`,
`Dirty: ${status.dirty ? "yes" : "no"}`,
`Index: ${status.dbPath}`,
].filter(Boolean) as string[];
if (status.fallback?.reason) {
lines.push(chalk.gray(status.fallback.reason));
}
defaultRuntime.log(lines.join("\n"));
});
memory
.command("index")
.description("Reindex memory files")
.option("--agent <id>", "Agent id (default: default agent)")
.option("--force", "Force full reindex", false)
.action(async (opts: MemoryCommandOptions & { force?: boolean }) => {
const cfg = loadConfig();
const agentId = resolveAgent(cfg, opts.agent);
const { manager, error } = await getMemorySearchManager({ cfg, agentId });
if (!manager) {
defaultRuntime.log(error ?? "Memory search disabled.");
return;
}
await manager.sync({ reason: "cli", force: opts.force });
defaultRuntime.log("Memory index updated.");
});
memory
.command("search")
.description("Search memory files")
.argument("<query>", "Search query")
.option("--agent <id>", "Agent id (default: default agent)")
.option("--max-results <n>", "Max results", (v) => Number(v))
.option("--min-score <n>", "Minimum score", (v) => Number(v))
.option("--json", "Print JSON")
.action(
async (
query: string,
opts: MemoryCommandOptions & {
maxResults?: number;
minScore?: number;
},
) => {
const cfg = loadConfig();
const agentId = resolveAgent(cfg, opts.agent);
const { manager, error } = await getMemorySearchManager({
cfg,
agentId,
});
if (!manager) {
defaultRuntime.log(error ?? "Memory search disabled.");
return;
}
const results = await manager.search(query, {
maxResults: opts.maxResults,
minScore: opts.minScore,
});
if (opts.json) {
defaultRuntime.log(JSON.stringify({ results }, null, 2));
return;
}
if (results.length === 0) {
defaultRuntime.log("No matches.");
return;
}
const lines: string[] = [];
for (const result of results) {
lines.push(
`${chalk.green(result.score.toFixed(3))} ${result.path}:${result.startLine}-${result.endLine}`,
);
lines.push(chalk.gray(result.snippet));
lines.push("");
}
defaultRuntime.log(lines.join("\n").trim());
},
);
}