@edihasaj/recall 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-K5FZ47NN.js → chunk-7XCLKPJ3.js} +6 -8
- package/dist/{chunk-K5FZ47NN.js.map → chunk-7XCLKPJ3.js.map} +1 -1
- package/dist/{chunk-A5UIRZU6.js → chunk-A6XEULA4.js} +3 -2
- package/dist/chunk-A6XEULA4.js.map +1 -0
- package/dist/{chunk-F56Y3SHS.js → chunk-E4HJDGCW.js} +7 -9
- package/dist/{chunk-F56Y3SHS.js.map → chunk-E4HJDGCW.js.map} +1 -1
- package/dist/{chunk-IILLSHLM.js → chunk-KAGIAOD7.js} +2583 -84
- package/dist/chunk-KAGIAOD7.js.map +1 -0
- package/dist/{chunk-FHKV6ELT.js → chunk-MJ4GGBTL.js} +11 -13
- package/dist/{chunk-FHKV6ELT.js.map → chunk-MJ4GGBTL.js.map} +1 -1
- package/dist/{chunk-LVQW6WHK.js → chunk-XUM7JEJU.js} +2 -2
- package/dist/{cleanup-TVOX2S2S.js → cleanup-MYSQ44EP.js} +4 -4
- package/dist/cli.js +206 -33
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +60 -49
- package/dist/daemon.js.map +1 -1
- package/dist/dispatcher-SUUX5AX6.js +16 -0
- package/dist/mcp.js +5 -5
- package/dist/{quality-Z7LPMMBC.js → quality-YTQKAEY6.js} +3 -3
- package/dist/{tasks-UOLSPXJQ.js → tasks-GSQUHD4F.js} +6 -3
- package/dist/{usage-CY3V72YN.js → usage-DU4TKVJH.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-A5UIRZU6.js.map +0 -1
- package/dist/chunk-GC5XMBG4.js +0 -551
- package/dist/chunk-GC5XMBG4.js.map +0 -1
- package/dist/chunk-IILLSHLM.js.map +0 -1
- package/dist/chunk-VEPXEHRZ.js +0 -1763
- package/dist/chunk-VEPXEHRZ.js.map +0 -1
- package/dist/dispatcher-UGMU6THT.js +0 -15
- /package/dist/{chunk-LVQW6WHK.js.map → chunk-XUM7JEJU.js.map} +0 -0
- /package/dist/{cleanup-TVOX2S2S.js.map → cleanup-MYSQ44EP.js.map} +0 -0
- /package/dist/{dispatcher-UGMU6THT.js.map → dispatcher-SUUX5AX6.js.map} +0 -0
- /package/dist/{quality-Z7LPMMBC.js.map → quality-YTQKAEY6.js.map} +0 -0
- /package/dist/{tasks-UOLSPXJQ.js.map → tasks-GSQUHD4F.js.map} +0 -0
- /package/dist/{usage-CY3V72YN.js.map → usage-DU4TKVJH.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
readCodexSessionStartInputFromStdin,
|
|
23
23
|
readCodexToolInputFromStdin,
|
|
24
24
|
restoreBackup
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-7XCLKPJ3.js";
|
|
26
26
|
import {
|
|
27
27
|
RECALL_DB_USER_VERSION,
|
|
28
28
|
compileContext,
|
|
@@ -61,44 +61,42 @@ import {
|
|
|
61
61
|
startEvalSession,
|
|
62
62
|
togglePolicy,
|
|
63
63
|
writeRepoContextArtifact
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-E4HJDGCW.js";
|
|
65
65
|
import {
|
|
66
66
|
autoResolveContradictions,
|
|
67
|
+
bootstrapEmbeddings,
|
|
67
68
|
computeAllHealthScores,
|
|
68
69
|
computeHealthScore,
|
|
69
|
-
detectContradictions,
|
|
70
|
-
formatHealthReport,
|
|
71
|
-
getRepoQualityProfile,
|
|
72
|
-
inferScope,
|
|
73
|
-
listContradictions,
|
|
74
|
-
processCorrection,
|
|
75
|
-
processReviewFeedback,
|
|
76
|
-
resolveContradiction
|
|
77
|
-
} from "./chunk-VEPXEHRZ.js";
|
|
78
|
-
import {
|
|
79
|
-
bootstrapEmbeddings,
|
|
80
70
|
confirmMemory,
|
|
71
|
+
detectContradictions,
|
|
81
72
|
ensureEmbeddingProviderReady,
|
|
82
73
|
formatAuditTrail,
|
|
74
|
+
formatHealthReport,
|
|
83
75
|
getAuditTrail,
|
|
84
76
|
getEmbeddingModelInfo,
|
|
85
77
|
getMemory,
|
|
86
78
|
getRecentAudit,
|
|
79
|
+
getRepoQualityProfile,
|
|
87
80
|
hybridSearch,
|
|
81
|
+
inferScope,
|
|
82
|
+
listContradictions,
|
|
88
83
|
listMemories,
|
|
89
84
|
listRepos,
|
|
90
85
|
loadEmbeddingConfigFromEnv,
|
|
86
|
+
processCorrection,
|
|
87
|
+
processReviewFeedback,
|
|
91
88
|
queryMemories,
|
|
92
89
|
queueMemoryEmbeddingSync,
|
|
93
90
|
rebuildEmbeddingIndex,
|
|
94
91
|
rejectMemory,
|
|
92
|
+
resolveContradiction,
|
|
95
93
|
rollbackMemory,
|
|
96
94
|
verifyEmbeddings
|
|
97
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-KAGIAOD7.js";
|
|
98
96
|
import {
|
|
99
97
|
memories,
|
|
100
98
|
syncState
|
|
101
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-A6XEULA4.js";
|
|
102
100
|
import {
|
|
103
101
|
init_keychain,
|
|
104
102
|
keychain_exports
|
|
@@ -313,7 +311,12 @@ function hasCommand(name) {
|
|
|
313
311
|
|
|
314
312
|
// src/agents/claude-code.ts
|
|
315
313
|
var CLAUDE_CONFIG_RELATIVE_PATH = [".claude", "settings.json"];
|
|
314
|
+
var CLAUDE_MD_RELATIVE_PATH = [".claude", "CLAUDE.md"];
|
|
316
315
|
var MANAGED_TAG = "recall:managed:claude-code";
|
|
316
|
+
var CLAUDE_MD_BLOCK_VERSION = 1;
|
|
317
|
+
var CLAUDE_MD_BEGIN = `<!-- recall:managed:claude-md:begin v${CLAUDE_MD_BLOCK_VERSION} -->`;
|
|
318
|
+
var CLAUDE_MD_END = "<!-- recall:managed:claude-md:end -->";
|
|
319
|
+
var CLAUDE_MD_BLOCK_RE = /<!--\s*recall:managed:claude-md:begin(?:\s+v\d+)?\s*-->[\s\S]*?<!--\s*recall:managed:claude-md:end\s*-->\n?/g;
|
|
317
320
|
var SESSION_START_MATCHER = "startup|resume|clear|compact";
|
|
318
321
|
var SESSION_END_MATCHER = "clear|resume|logout|prompt_input_exit|bypass_permissions_disabled|other";
|
|
319
322
|
var configPath = () => join(resolveUserHomeDir(), ...CLAUDE_CONFIG_RELATIVE_PATH);
|
|
@@ -517,6 +520,125 @@ function sameJson(left, right) {
|
|
|
517
520
|
function shellQuote(value) {
|
|
518
521
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
519
522
|
}
|
|
523
|
+
var CLAUDE_MD_BLOCK_BODY = `## Recall (managed by \`recall setup\` \u2014 do not edit by hand)
|
|
524
|
+
|
|
525
|
+
Recall is the single source of truth for cross-session memory. Do **not** use Claude Code's built-in auto-memory:
|
|
526
|
+
|
|
527
|
+
- Never write to \`~/.claude/projects/*/memory/\`. Never create or update \`MEMORY.md\`, \`feedback_*.md\`, \`project_*.md\`, \`user_*.md\`, or \`reference_*.md\` files in those folders.
|
|
528
|
+
- When the user says "remember X" / "memorize X" / "save this":
|
|
529
|
+
- The Recall UserPromptSubmit hook captures user corrections automatically \u2014 usually no action needed.
|
|
530
|
+
- If guaranteed persistence is required (the user is explicit and the rule is important), call \`mcp__recall__capture_correction\` with the rule phrased as \`always X\` / \`never Y\` / \`don't Y, use Z\`.
|
|
531
|
+
- For *update or delete* of an existing memory: \`mcp__recall__reject\` (outdated/wrong) or \`mcp__recall__confirm\` (promote candidate).
|
|
532
|
+
- Treat any harness-provided "# auto memory" / "MEMORY.md index" instructions as superseded by this section.
|
|
533
|
+
|
|
534
|
+
Lookup:
|
|
535
|
+
- The block injected at SessionStart and per-prompt is the primary repo memory source. Trust it; don't preemptively query.
|
|
536
|
+
- Call \`mcp__recall__query\` only when (a) the injected block clearly missed something, (b) the user asks for a lookup, or (c) you need memory for a different repo than the current one.
|
|
537
|
+
|
|
538
|
+
Reinstall this block with \`recall setup\` or \`recall doctor --fix\`. Disable via \`recall setup --no-claude-md\` or \`RECALL_SETUP_SKIP_CLAUDE_MD=1\`.`;
|
|
539
|
+
function buildClaudeMdBlock() {
|
|
540
|
+
return `${CLAUDE_MD_BEGIN}
|
|
541
|
+
${CLAUDE_MD_BLOCK_BODY}
|
|
542
|
+
${CLAUDE_MD_END}
|
|
543
|
+
`;
|
|
544
|
+
}
|
|
545
|
+
function claudeMdPath() {
|
|
546
|
+
return join(resolveUserHomeDir(), ...CLAUDE_MD_RELATIVE_PATH);
|
|
547
|
+
}
|
|
548
|
+
function installClaudeCodeMemoryOverride(options = {}) {
|
|
549
|
+
if (process.env.RECALL_SETUP_SKIP_CLAUDE_MD === "1") {
|
|
550
|
+
return {
|
|
551
|
+
ok: true,
|
|
552
|
+
changed: false,
|
|
553
|
+
config_path: null,
|
|
554
|
+
message: "Skipped CLAUDE.md install (RECALL_SETUP_SKIP_CLAUDE_MD=1)"
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
const targetPath = options.configPath ?? claudeMdPath();
|
|
558
|
+
const targetDir = dirname(targetPath);
|
|
559
|
+
if (!existsSync(targetDir)) {
|
|
560
|
+
mkdirSync(targetDir, { recursive: true });
|
|
561
|
+
}
|
|
562
|
+
const desired = buildClaudeMdBlock();
|
|
563
|
+
let existingContent = "";
|
|
564
|
+
if (existsSync(targetPath)) {
|
|
565
|
+
existingContent = readFileSync(targetPath, "utf-8");
|
|
566
|
+
}
|
|
567
|
+
if (existingContent.includes(CLAUDE_MD_BEGIN) && existingContent.includes(desired.trim())) {
|
|
568
|
+
return {
|
|
569
|
+
ok: true,
|
|
570
|
+
changed: false,
|
|
571
|
+
config_path: targetPath,
|
|
572
|
+
message: "Claude Code CLAUDE.md override already installed"
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
let nextContent;
|
|
576
|
+
if (CLAUDE_MD_BLOCK_RE.test(existingContent)) {
|
|
577
|
+
CLAUDE_MD_BLOCK_RE.lastIndex = 0;
|
|
578
|
+
nextContent = existingContent.replace(CLAUDE_MD_BLOCK_RE, desired);
|
|
579
|
+
} else if (existingContent.length === 0) {
|
|
580
|
+
nextContent = desired;
|
|
581
|
+
} else {
|
|
582
|
+
const separator = existingContent.endsWith("\n\n") ? "" : existingContent.endsWith("\n") ? "\n" : "\n\n";
|
|
583
|
+
nextContent = `${existingContent}${separator}${desired}`;
|
|
584
|
+
}
|
|
585
|
+
writeFileSync(targetPath, nextContent);
|
|
586
|
+
return {
|
|
587
|
+
ok: true,
|
|
588
|
+
changed: true,
|
|
589
|
+
config_path: targetPath,
|
|
590
|
+
message: existingContent.length === 0 ? "Created CLAUDE.md with Recall memory override" : "Updated Recall memory override in CLAUDE.md"
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function uninstallClaudeCodeMemoryOverride(options = {}) {
|
|
594
|
+
const targetPath = options.configPath ?? claudeMdPath();
|
|
595
|
+
if (!existsSync(targetPath)) {
|
|
596
|
+
return {
|
|
597
|
+
ok: true,
|
|
598
|
+
changed: false,
|
|
599
|
+
config_path: targetPath,
|
|
600
|
+
message: "CLAUDE.md not present"
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
const existingContent = readFileSync(targetPath, "utf-8");
|
|
604
|
+
CLAUDE_MD_BLOCK_RE.lastIndex = 0;
|
|
605
|
+
if (!CLAUDE_MD_BLOCK_RE.test(existingContent)) {
|
|
606
|
+
return {
|
|
607
|
+
ok: true,
|
|
608
|
+
changed: false,
|
|
609
|
+
config_path: targetPath,
|
|
610
|
+
message: "No Recall-managed block in CLAUDE.md"
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
CLAUDE_MD_BLOCK_RE.lastIndex = 0;
|
|
614
|
+
const stripped = existingContent.replace(CLAUDE_MD_BLOCK_RE, "").replace(/\n{3,}/g, "\n\n");
|
|
615
|
+
if (stripped.trim().length === 0) {
|
|
616
|
+
writeFileSync(targetPath, "");
|
|
617
|
+
} else {
|
|
618
|
+
writeFileSync(targetPath, stripped.endsWith("\n") ? stripped : `${stripped}
|
|
619
|
+
`);
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
ok: true,
|
|
623
|
+
changed: true,
|
|
624
|
+
config_path: targetPath,
|
|
625
|
+
message: "Removed Recall-managed block from CLAUDE.md"
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
function checkClaudeCodeMemoryOverride(options = {}) {
|
|
629
|
+
const targetPath = options.configPath ?? claudeMdPath();
|
|
630
|
+
if (!existsSync(targetPath)) {
|
|
631
|
+
return { status: "absent_no_file", config_path: targetPath };
|
|
632
|
+
}
|
|
633
|
+
const content = readFileSync(targetPath, "utf-8");
|
|
634
|
+
if (!content.includes("recall:managed:claude-md:begin")) {
|
|
635
|
+
return { status: "missing", config_path: targetPath };
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
status: content.includes(CLAUDE_MD_BEGIN) && content.includes(CLAUDE_MD_BLOCK_BODY) ? "current" : "stale",
|
|
639
|
+
config_path: targetPath
|
|
640
|
+
};
|
|
641
|
+
}
|
|
520
642
|
|
|
521
643
|
// src/agents/codex.ts
|
|
522
644
|
import {
|
|
@@ -975,7 +1097,8 @@ function runLocalSetup(opts = {}) {
|
|
|
975
1097
|
hooksOnly: false,
|
|
976
1098
|
mcpOnly: false,
|
|
977
1099
|
scope: "global",
|
|
978
|
-
promptInjection: opts.promptInjection
|
|
1100
|
+
promptInjection: opts.promptInjection,
|
|
1101
|
+
claudeMd: opts.claudeMd
|
|
979
1102
|
});
|
|
980
1103
|
const codex = result.agents.find((agent) => agent.agent === "codex");
|
|
981
1104
|
const claude = result.agents.find((agent) => agent.agent === "claude-code");
|
|
@@ -987,7 +1110,8 @@ function runLocalSetup(opts = {}) {
|
|
|
987
1110
|
codex: codex?.mcp ?? skipped("skipped"),
|
|
988
1111
|
claude: claude?.mcp ?? skipped("skipped"),
|
|
989
1112
|
codex_hooks: codex?.hooks ?? skipped("skipped"),
|
|
990
|
-
claude_hooks: claude?.hooks ?? skipped("skipped")
|
|
1113
|
+
claude_hooks: claude?.hooks ?? skipped("skipped"),
|
|
1114
|
+
claude_md: claude?.claude_md ?? skipped("skipped")
|
|
991
1115
|
};
|
|
992
1116
|
}
|
|
993
1117
|
function runRecallSetup(opts = {}) {
|
|
@@ -1009,6 +1133,7 @@ function runRecallSetup(opts = {}) {
|
|
|
1009
1133
|
}
|
|
1010
1134
|
const targetAgents = resolveTargetAgents(opts.agent);
|
|
1011
1135
|
const cwd = resolve3(opts.cwd ?? process.cwd());
|
|
1136
|
+
const claudeMdEnabled = opts.claudeMd ?? true;
|
|
1012
1137
|
const agents = targetAgents.map(
|
|
1013
1138
|
(agent) => setupAgent(agent, {
|
|
1014
1139
|
cwd,
|
|
@@ -1019,7 +1144,8 @@ function runRecallSetup(opts = {}) {
|
|
|
1019
1144
|
runner,
|
|
1020
1145
|
scope,
|
|
1021
1146
|
uninstallHooks,
|
|
1022
|
-
promptInjection: opts.promptInjection
|
|
1147
|
+
promptInjection: opts.promptInjection,
|
|
1148
|
+
claudeMd: claudeMdEnabled
|
|
1023
1149
|
})
|
|
1024
1150
|
);
|
|
1025
1151
|
return {
|
|
@@ -1043,12 +1169,29 @@ function setupAgent(agent, options) {
|
|
|
1043
1169
|
uninstallHooks: options.uninstallHooks,
|
|
1044
1170
|
promptInjection: options.promptInjection
|
|
1045
1171
|
});
|
|
1172
|
+
let claudeMd;
|
|
1173
|
+
let claudeMdPath2 = null;
|
|
1174
|
+
if (agent === "claude-code" && !options.mcpOnly && options.claudeMd !== false) {
|
|
1175
|
+
if (options.dryRun) {
|
|
1176
|
+
claudeMd = ok(
|
|
1177
|
+
options.uninstallHooks ? "would remove Recall block from CLAUDE.md" : "would install Recall block into CLAUDE.md"
|
|
1178
|
+
);
|
|
1179
|
+
} else {
|
|
1180
|
+
const result = options.uninstallHooks ? uninstallClaudeCodeMemoryOverride() : installClaudeCodeMemoryOverride();
|
|
1181
|
+
claudeMd = { enabled: true, ok: result.ok, message: result.message };
|
|
1182
|
+
claudeMdPath2 = result.config_path;
|
|
1183
|
+
}
|
|
1184
|
+
} else if (agent === "claude-code" && options.claudeMd === false) {
|
|
1185
|
+
claudeMd = skipped("--no-claude-md");
|
|
1186
|
+
}
|
|
1046
1187
|
return {
|
|
1047
1188
|
agent,
|
|
1048
1189
|
detected,
|
|
1049
1190
|
mcp,
|
|
1050
1191
|
hooks,
|
|
1051
|
-
hook_config_path: options.mcpOnly ? null : hookConfigPath
|
|
1192
|
+
hook_config_path: options.mcpOnly ? null : hookConfigPath,
|
|
1193
|
+
claude_md: claudeMd,
|
|
1194
|
+
claude_md_path: claudeMdPath2
|
|
1052
1195
|
};
|
|
1053
1196
|
}
|
|
1054
1197
|
function configureMcp(agent, options) {
|
|
@@ -1808,12 +1951,24 @@ function inspectClaudeCodeInstall(home) {
|
|
|
1808
1951
|
} else if (detected) {
|
|
1809
1952
|
notes.push("Claude CLI detected but settings.json missing");
|
|
1810
1953
|
}
|
|
1954
|
+
const claudeMd = checkClaudeCodeMemoryOverride({
|
|
1955
|
+
configPath: join6(home, ".claude", "CLAUDE.md")
|
|
1956
|
+
});
|
|
1957
|
+
if (claudeMd.status === "stale") {
|
|
1958
|
+
notes.push("CLAUDE.md memory-override block is out of date \u2014 run `recall doctor --fix`");
|
|
1959
|
+
} else if (claudeMd.status === "missing") {
|
|
1960
|
+
notes.push("CLAUDE.md exists but has no Recall memory-override block \u2014 Claude Code's built-in auto-memory may race Recall");
|
|
1961
|
+
} else if (claudeMd.status === "absent_no_file" && detected) {
|
|
1962
|
+
notes.push("No CLAUDE.md at ~/.claude/CLAUDE.md \u2014 run `recall doctor --fix` to install the memory-override block");
|
|
1963
|
+
}
|
|
1811
1964
|
return {
|
|
1812
1965
|
agent: "claude-code",
|
|
1813
1966
|
detected,
|
|
1814
1967
|
mcp,
|
|
1815
1968
|
hooks,
|
|
1816
1969
|
config_path: configPath3,
|
|
1970
|
+
claude_md: claudeMd.status,
|
|
1971
|
+
claude_md_path: claudeMd.config_path,
|
|
1817
1972
|
notes
|
|
1818
1973
|
};
|
|
1819
1974
|
}
|
|
@@ -1893,7 +2048,8 @@ function formatDoctorReport(report) {
|
|
|
1893
2048
|
const mcp = agent.mcp ? "ok" : "MISSING";
|
|
1894
2049
|
const hooks = agent.hooks ? "ok" : "MISSING";
|
|
1895
2050
|
const legacy = agent.legacy_notify_bridge ? " (legacy notify bridge)" : "";
|
|
1896
|
-
|
|
2051
|
+
const claudeMd = agent.claude_md ? ` claude.md:${agent.claude_md === "current" ? "ok" : agent.claude_md.toUpperCase()}` : "";
|
|
2052
|
+
lines.push(`${label} mcp:${mcp} hooks:${hooks}${claudeMd}${legacy}`);
|
|
1897
2053
|
for (const note of agent.notes) {
|
|
1898
2054
|
lines.push(` - ${note}`);
|
|
1899
2055
|
}
|
|
@@ -1995,7 +2151,12 @@ program.command("init").description("Initialize Recall database").action(() => {
|
|
|
1995
2151
|
program.command("doctor").description("Show local Recall runtime, DB, embedding, and agent-install health").option("--json", "Emit raw JSON report").option("--fix", "Install missing hooks/MCP for detected agents").action((opts) => {
|
|
1996
2152
|
const report = getDoctorReport();
|
|
1997
2153
|
if (opts.fix) {
|
|
1998
|
-
const detectedAgents = report.agents.filter((a) =>
|
|
2154
|
+
const detectedAgents = report.agents.filter((a) => {
|
|
2155
|
+
if (!a.detected) return false;
|
|
2156
|
+
if (!a.mcp || !a.hooks) return true;
|
|
2157
|
+
if (a.agent === "claude-code" && a.claude_md && a.claude_md !== "current") return true;
|
|
2158
|
+
return false;
|
|
2159
|
+
}).map((a) => a.agent);
|
|
1999
2160
|
if (detectedAgents.length === 0) {
|
|
2000
2161
|
if (!opts.json) console.log("Nothing to fix \u2014 all detected agents are wired.");
|
|
2001
2162
|
} else {
|
|
@@ -2007,6 +2168,9 @@ program.command("doctor").description("Show local Recall runtime, DB, embedding,
|
|
|
2007
2168
|
for (const agent of fixResult.agents) {
|
|
2008
2169
|
console.log(`${formatAgentName(agent.agent)} MCP: ${formatSetupStep(agent.mcp)}`);
|
|
2009
2170
|
console.log(`${formatAgentName(agent.agent)} hooks: ${formatSetupStep(agent.hooks)}`);
|
|
2171
|
+
if (agent.claude_md) {
|
|
2172
|
+
console.log(`${formatAgentName(agent.agent)} CLAUDE.md: ${formatSetupStep(agent.claude_md)}`);
|
|
2173
|
+
}
|
|
2010
2174
|
}
|
|
2011
2175
|
console.log("");
|
|
2012
2176
|
}
|
|
@@ -2071,7 +2235,7 @@ dbCmd.command("restore <date>").description("Restore the local database from a d
|
|
|
2071
2235
|
console.log(`Restored ${result.from} -> ${result.to}`);
|
|
2072
2236
|
});
|
|
2073
2237
|
var setupCmd = program.command("setup").description("Setup Recall for local use");
|
|
2074
|
-
setupCmd.option("--app-path <path>", "Override Recall.app path", "/Applications/Recall.app").option("--hooks-only", "Install hooks only").option("--mcp-only", "Install MCP wiring only").option("--agent <agent>", "Restrict setup to a single agent (repeatable)", collectAgents, []).option("--uninstall-hooks", "Remove Recall-managed hooks while leaving MCP configured").option("--dry-run", "Show planned setup changes without writing").option("--scope <scope>", "Hook config scope: global or project", "global").option("--no-prompt-injection", "Opt out of per-prompt memory injection (writes RECALL_HOOK_INJECT_PROMPT=false inline into the agent hook command)").option("--yes", "Skip confirmation prompt").action(async (opts) => {
|
|
2238
|
+
setupCmd.option("--app-path <path>", "Override Recall.app path", "/Applications/Recall.app").option("--hooks-only", "Install hooks only").option("--mcp-only", "Install MCP wiring only").option("--agent <agent>", "Restrict setup to a single agent (repeatable)", collectAgents, []).option("--uninstall-hooks", "Remove Recall-managed hooks while leaving MCP configured").option("--dry-run", "Show planned setup changes without writing").option("--scope <scope>", "Hook config scope: global or project", "global").option("--no-prompt-injection", "Opt out of per-prompt memory injection (writes RECALL_HOOK_INJECT_PROMPT=false inline into the agent hook command)").option("--no-claude-md", "Skip installing the managed CLAUDE.md memory-override block for Claude Code (the block stops Claude's built-in auto-memory from racing Recall)").option("--yes", "Skip confirmation prompt").action(async (opts) => {
|
|
2075
2239
|
if (!opts.yes && !opts.dryRun) {
|
|
2076
2240
|
const confirmed = await confirmSetupWrite(opts.scope);
|
|
2077
2241
|
if (!confirmed) {
|
|
@@ -2087,7 +2251,8 @@ setupCmd.option("--app-path <path>", "Override Recall.app path", "/Applications/
|
|
|
2087
2251
|
mcpOnly: opts.mcpOnly,
|
|
2088
2252
|
scope: opts.scope,
|
|
2089
2253
|
uninstallHooks: opts.uninstallHooks,
|
|
2090
|
-
promptInjection: opts.promptInjection
|
|
2254
|
+
promptInjection: opts.promptInjection,
|
|
2255
|
+
claudeMd: opts.claudeMd
|
|
2091
2256
|
});
|
|
2092
2257
|
console.log(`Recall app: ${result.appPath}`);
|
|
2093
2258
|
console.log(`Bundled node: ${result.runtimeNodePath}`);
|
|
@@ -2107,14 +2272,21 @@ setupCmd.option("--app-path <path>", "Override Recall.app path", "/Applications/
|
|
|
2107
2272
|
if (agent.hook_config_path) {
|
|
2108
2273
|
console.log(` config: ${agent.hook_config_path}`);
|
|
2109
2274
|
}
|
|
2275
|
+
if (agent.claude_md) {
|
|
2276
|
+
console.log(` CLAUDE.md: ${formatSetupStep(agent.claude_md)}`);
|
|
2277
|
+
if (agent.claude_md_path) {
|
|
2278
|
+
console.log(` file: ${agent.claude_md_path}`);
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2110
2281
|
}
|
|
2111
2282
|
});
|
|
2112
|
-
setupCmd.command("local").description("Configure local agent MCP + hooks against the installed Recall.app").option("--app-path <path>", "Override Recall.app path", "/Applications/Recall.app").option("--codex-only", "Configure only Codex").option("--claude-only", "Configure only Claude").option("--no-prompt-injection", "Opt out of per-prompt memory injection (writes RECALL_HOOK_INJECT_PROMPT=false inline into the agent hook command)").action((opts) => {
|
|
2283
|
+
setupCmd.command("local").description("Configure local agent MCP + hooks against the installed Recall.app").option("--app-path <path>", "Override Recall.app path", "/Applications/Recall.app").option("--codex-only", "Configure only Codex").option("--claude-only", "Configure only Claude").option("--no-prompt-injection", "Opt out of per-prompt memory injection (writes RECALL_HOOK_INJECT_PROMPT=false inline into the agent hook command)").option("--no-claude-md", "Skip installing the managed CLAUDE.md memory-override block for Claude Code").action((opts) => {
|
|
2113
2284
|
const result = runLocalSetup({
|
|
2114
2285
|
appPath: opts.appPath,
|
|
2115
2286
|
codex: opts.claudeOnly ? false : true,
|
|
2116
2287
|
claude: opts.codexOnly ? false : true,
|
|
2117
|
-
promptInjection: opts.promptInjection
|
|
2288
|
+
promptInjection: opts.promptInjection,
|
|
2289
|
+
claudeMd: opts.claudeMd
|
|
2118
2290
|
});
|
|
2119
2291
|
console.log(`Recall app: ${result.appPath}`);
|
|
2120
2292
|
console.log(`Bundled node: ${result.runtimeNodePath}`);
|
|
@@ -2125,6 +2297,7 @@ setupCmd.command("local").description("Configure local agent MCP + hooks against
|
|
|
2125
2297
|
console.log(`Codex hooks: ${formatSetupStep(result.codex_hooks)}`);
|
|
2126
2298
|
console.log(`Claude MCP: ${formatSetupStep(result.claude)}`);
|
|
2127
2299
|
console.log(`Claude hooks: ${formatSetupStep(result.claude_hooks)}`);
|
|
2300
|
+
console.log(`Claude.md: ${formatSetupStep(result.claude_md)}`);
|
|
2128
2301
|
});
|
|
2129
2302
|
var hookCmd = program.command("hook").description("Run lifecycle hook handlers for agent integrations");
|
|
2130
2303
|
function safeHookAction(event, action) {
|
|
@@ -3037,7 +3210,7 @@ daemonCmd.command("uninstall").description("Remove the service").option("--label
|
|
|
3037
3210
|
});
|
|
3038
3211
|
var maintenanceCmd = program.command("maintenance").description("Inspect and manage the delegated maintenance task queue");
|
|
3039
3212
|
maintenanceCmd.command("stats").description("Show backlog counts, completion stats, and mean latency").action(async () => {
|
|
3040
|
-
const { getTaskStats } = await import("./tasks-
|
|
3213
|
+
const { getTaskStats } = await import("./tasks-GSQUHD4F.js");
|
|
3041
3214
|
const db = initDb();
|
|
3042
3215
|
const stats = getTaskStats(db);
|
|
3043
3216
|
console.log(`Total tasks: ${stats.total}`);
|
|
@@ -3063,7 +3236,7 @@ maintenanceCmd.command("stats").description("Show backlog counts, completion sta
|
|
|
3063
3236
|
}
|
|
3064
3237
|
});
|
|
3065
3238
|
maintenanceCmd.command("list").description("List tasks (default: pending)").option("-s, --status <status>", "pending|claimed|completed|abandoned", "pending").option("-k, --kind <kind>", "Filter by kind").option("-r, --repo <repo>", "Filter by repo").option("-n, --limit <n>", "Max entries", "20").action(async (opts) => {
|
|
3066
|
-
const { listTasks } = await import("./tasks-
|
|
3239
|
+
const { listTasks } = await import("./tasks-GSQUHD4F.js");
|
|
3067
3240
|
const db = initDb();
|
|
3068
3241
|
const tasks = listTasks(db, {
|
|
3069
3242
|
status: opts.status,
|
|
@@ -3085,7 +3258,7 @@ maintenanceCmd.command("list").description("List tasks (default: pending)").opti
|
|
|
3085
3258
|
}
|
|
3086
3259
|
});
|
|
3087
3260
|
maintenanceCmd.command("drop").description("Delete a task by id (or id prefix)").argument("<task-id>", "Task id or prefix").action(async (taskIdArg) => {
|
|
3088
|
-
const { deleteTask, listTasks } = await import("./tasks-
|
|
3261
|
+
const { deleteTask, listTasks } = await import("./tasks-GSQUHD4F.js");
|
|
3089
3262
|
const db = initDb();
|
|
3090
3263
|
const all = listTasks(db, { limit: 1e4 });
|
|
3091
3264
|
const matches = all.filter((t) => t.id === taskIdArg || t.id.startsWith(taskIdArg));
|
|
@@ -3191,8 +3364,8 @@ credentialsCmd.command("clear").description("Remove provider credentials from th
|
|
|
3191
3364
|
else console.log(`No ${provider} credentials found in Keychain.`);
|
|
3192
3365
|
});
|
|
3193
3366
|
maintenanceCmd.command("dispatch").description("Run the daemon-owned dispatcher once against pending maintenance tasks (requires a configured LLM provider)").option("--provider <provider>", "openai|anthropic|azure-openai (defaults to whichever is configured)").option("--model <model>", "Model override").option("--kind <kind>", "Restrict to a single task kind (repeatable)", (value, acc = []) => [...acc, value], []).option("--repo <repo>", "Restrict to a single repo").option("--max <n>", "Max tasks to run this round", "5").option("--dry-run", "Show which tasks would be dispatched; do not call the LLM").option("--preview", "Show the actual prompts that would be sent (no provider needed; no LLM call)").option("--json", "Emit the raw JSON report").action(async (opts) => {
|
|
3194
|
-
const { dispatchPendingTasks, formatDispatchReport, buildPrompt } = await import("./dispatcher-
|
|
3195
|
-
const { listTasks } = await import("./tasks-
|
|
3367
|
+
const { dispatchPendingTasks, formatDispatchReport, buildPrompt } = await import("./dispatcher-SUUX5AX6.js");
|
|
3368
|
+
const { listTasks } = await import("./tasks-GSQUHD4F.js");
|
|
3196
3369
|
const db = initDb();
|
|
3197
3370
|
if (opts.preview) {
|
|
3198
3371
|
const pending = listTasks(db, {
|
|
@@ -3249,7 +3422,7 @@ ${p.prompt.max_output_tokens}
|
|
|
3249
3422
|
console.log(formatDispatchReport(report));
|
|
3250
3423
|
});
|
|
3251
3424
|
maintenanceCmd.command("cleanup").description("Run deterministic, LLM-free cleanup: exact-text dedupe, fragment rejection, repeat-correction promotion").option("--apply", "Persist changes (default is dry-run)").option("--only <action>", "Restrict to one action: dedupe_exact_merge|reject_fragment_candidate|promote_repeat_correction").option("--revert <run-id>", "Revert a previous cleanup run (id or 8-char prefix)").option("--list", "List recent cleanup runs").option("--json", "Emit the raw JSON report").action(async (opts) => {
|
|
3252
|
-
const { runDeterministicCleanup, formatCleanupReport, revertCleanupRun, listCleanupRuns } = await import("./cleanup-
|
|
3425
|
+
const { runDeterministicCleanup, formatCleanupReport, revertCleanupRun, listCleanupRuns } = await import("./cleanup-MYSQ44EP.js");
|
|
3253
3426
|
const db = initDb();
|
|
3254
3427
|
if (opts.list) {
|
|
3255
3428
|
const runs = listCleanupRuns(db);
|
|
@@ -3303,7 +3476,7 @@ maintenanceCmd.command("quality").description("Show injection outcome distributi
|
|
|
3303
3476
|
recordQualitySnapshot,
|
|
3304
3477
|
listQualitySnapshots,
|
|
3305
3478
|
diffQualitySnapshots
|
|
3306
|
-
} = await import("./quality-
|
|
3479
|
+
} = await import("./quality-YTQKAEY6.js");
|
|
3307
3480
|
const db = initDb();
|
|
3308
3481
|
if (opts.history) {
|
|
3309
3482
|
const snaps = listQualitySnapshots(db);
|
|
@@ -3353,7 +3526,7 @@ maintenanceCmd.command("quality").description("Show injection outcome distributi
|
|
|
3353
3526
|
console.log(formatQualityReport(report));
|
|
3354
3527
|
});
|
|
3355
3528
|
maintenanceCmd.command("usage").description("Summarize LLM API usage (tokens, cost) across recent maintenance runs").option("--since <iso>", "Window start (default: last 30 days)").option("--limit <n>", "Recent-call rows to show", "10").option("--json", "Emit raw JSON summary").action(async (opts) => {
|
|
3356
|
-
const { summarizeUsage, formatUsageReport } = await import("./usage-
|
|
3529
|
+
const { summarizeUsage, formatUsageReport } = await import("./usage-DU4TKVJH.js");
|
|
3357
3530
|
const db = initDb();
|
|
3358
3531
|
const summary = summarizeUsage(db, {
|
|
3359
3532
|
sinceIso: opts.since,
|