chat-recall 0.6.3 → 0.6.5

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/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
  Every coding agent you run keeps a full transcript of its work: the decisions, the
20
20
  reasoning, the keys somebody pasted, the problems it found and never filed. Each one
21
21
  writes to its own directory in its own format, none can read another's, and nothing
22
- reads any of them. `chat-recall` does, through **61 MCP tools**.
22
+ reads any of them. `chat-recall` does, through **62 MCP tools**.
23
23
 
24
24
  | | What it does | Tools |
25
25
  |---|---|---|
@@ -131,7 +131,7 @@ Exclusions live on the machine that holds the data, so the CLI owns them; they a
131
131
  ## Four things it actually does
132
132
 
133
133
  1. **Cross-tool unified memory.** One index, one search, one UI over Claude Code (`~/.claude/projects/`), Codex (`~/.codex/`), OpenCode (`~/.local/share/opencode/`), Antigravity (`~/.gemini/antigravity-cli/`) and Cursor (`~/.cursor/` for the CLI, `~/.config/Cursor/` for the IDE). Sessions, plans, tasks, CLAUDE.md files, paste cache, shell history and agent diaries all share one pluggable `MemorySource` interface.
134
- 2. **The agent recalls itself.** 61 MCP tools, so Claude Code can `recall_smart_resume`, `recall_search` (with `like_session` to find similar work), `recall_edits_timeline`, `recall_subagent_search` and `recall_redundant_files` rather than asking you what happened last time. It writes back too, via `recall_decision_record`, `recall_kg_add` and `recall_set`.
134
+ 2. **The agent recalls itself.** 62 MCP tools, so Claude Code can `recall_smart_resume`, `recall_search` (with `like_session` to find similar work), `recall_edits_timeline`, `recall_subagent_search` and `recall_redundant_files` rather than asking you what happened last time. It writes back too, via `recall_decision_record`, `recall_kg_add` and `recall_set`.
135
135
  3. **Warns before you redo work.** A `UserPromptSubmit` hook searches for similar past sessions on every prompt and injects a short "you have done this before, in session X" note into the agent's context.
136
136
  4. **Temporal knowledge graph.** Decisions and tool mentions become entity-relationship triples with `valid_from`/`valid_to` windows, so you can ask what was decided in March and whether it still holds.
137
137
 
@@ -270,7 +270,7 @@ codeindex is open source (MIT) at [github.com/munhq/codeindex](https://github.co
270
270
  | **Paste** | `~/.claude/paste-cache/*.txt` | Large pasted blobs |
271
271
  | **Diary** | `~/.chat-recall/index/diary/<agent>/*.json` | What the agent told its future self via `recall_diary_write` |
272
272
 
273
- ## MCP tools (61, including 4 code-intelligence tools that register when the companion binary is installed)
273
+ ## MCP tools (62, including 4 code-intelligence tools that register when the companion binary is installed)
274
274
 
275
275
  **Search & retrieve** — `recall_search`, `recall_memory_search`, `recall_recent`, `recall_show`, `recall_context`, `recall_summary`, `recall_smart_resume`, `recall_project_context`, `recall_weekly_digest`, `recall_analytics_summary`, `recall_wake_up`.
276
276
 
package/dist/cli.js CHANGED
@@ -14322,12 +14322,12 @@ function extractEntities(text, context3 = {}) {
14322
14322
  if (chosen && looksLikeStrictTool(chosen) && looksLikeStrictTool(rejected)) {
14323
14323
  const c = canonTool(chosen), r = canonTool(rejected);
14324
14324
  if (projectName)
14325
- addTriple(projectName, "chose", c, 0.8);
14326
- addTriple(projectName || "project", "rejected", r, 0.7);
14327
- addTriple(c, "chosen_over", r, 0.8);
14325
+ addTriple(projectName, "chose", c, DECISION_GUESS_CONFIDENCE);
14326
+ addTriple(projectName || "project", "rejected", r, DECISION_GUESS_CONFIDENCE);
14327
+ addTriple(c, "chosen_over", r, DECISION_GUESS_CONFIDENCE);
14328
14328
  }
14329
14329
  } else if (chosen && looksLikeDecisionObject(chosen) && projectName) {
14330
- addTriple(projectName, "chose", canonTool(chosen), 0.8);
14330
+ addTriple(projectName, "chose", canonTool(chosen), DECISION_GUESS_CONFIDENCE);
14331
14331
  }
14332
14332
  }
14333
14333
  }
@@ -14364,7 +14364,7 @@ function extractEntities(text, context3 = {}) {
14364
14364
  }
14365
14365
  return triples;
14366
14366
  }
14367
- var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
14367
+ var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, DECISION_GUESS_CONFIDENCE, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
14368
14368
  var init_entity_extractor = __esm({
14369
14369
  "../engine/dist/core/entity-extractor.js"() {
14370
14370
  "use strict";
@@ -14585,6 +14585,7 @@ var init_entity_extractor = __esm({
14585
14585
  "nextjs": "next.js"
14586
14586
  };
14587
14587
  canonTool = (n) => CANONICAL_TOOL[n.toLowerCase()] ?? n;
14588
+ DECISION_GUESS_CONFIDENCE = 0.6;
14588
14589
  PROJECT_PATH_PATTERN = /\/(?:home|Users)\/\w+\/(?:code|projects|work|dev|src)\/(?:\w+\/)?([a-zA-Z][a-zA-Z0-9_-]{1,40})/g;
14589
14590
  PEOPLE_PATTERNS = [
14590
14591
  /\b(?:my name is|I'm|I am)\s+([A-Z][a-z]{1,15}(?:\s+[A-Z][a-z]{1,15})?)/g,
@@ -18816,7 +18817,7 @@ var init_http = __esm({
18816
18817
  CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
18817
18818
  } catch {
18818
18819
  try {
18819
- if (true) CLI_VERSION = "0.6.3";
18820
+ if (true) CLI_VERSION = "0.6.5";
18820
18821
  } catch {
18821
18822
  }
18822
18823
  }
@@ -19336,7 +19337,7 @@ var init_telemetry = __esm({
19336
19337
  init_sync_client();
19337
19338
  cliVersion2 = () => {
19338
19339
  try {
19339
- return true ? "0.6.3" : "dev";
19340
+ return true ? "0.6.5" : "dev";
19340
19341
  } catch {
19341
19342
  return "dev";
19342
19343
  }
@@ -21425,7 +21426,7 @@ var init_sync_client = __esm({
21425
21426
  ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
21426
21427
  } catch {
21427
21428
  try {
21428
- if (true) ownVersion = "0.6.3";
21429
+ if (true) ownVersion = "0.6.5";
21429
21430
  } catch {
21430
21431
  }
21431
21432
  }
@@ -25227,7 +25228,7 @@ var init_intent_drain = __esm({
25227
25228
  ownVersion2 = JSON.parse(readFileSync44(join53(dir, "../package.json"), "utf-8")).version || ownVersion2;
25228
25229
  } catch {
25229
25230
  try {
25230
- if (true) ownVersion2 = "0.6.3";
25231
+ if (true) ownVersion2 = "0.6.5";
25231
25232
  } catch {
25232
25233
  }
25233
25234
  }
@@ -26286,6 +26287,8 @@ function refreshServiceDefinition() {
26286
26287
  const { watchJs, node, logFile } = resolveDaemonPaths();
26287
26288
  const unitPath = join57(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
26288
26289
  if (!existsSync53(unitPath)) return false;
26290
+ const current = readFileSync47(unitPath, "utf8");
26291
+ if (!current.includes(watchJs)) return false;
26289
26292
  const wanted = renderSystemdUnit(watchJs, node, logFile);
26290
26293
  if (readFileSync47(unitPath, "utf8") === wanted) return false;
26291
26294
  writeFileSync20(unitPath, wanted);
@@ -26334,6 +26337,14 @@ function renderSystemdUnit(watchJs, node, logFile) {
26334
26337
  "[Unit]",
26335
26338
  "Description=chat-recall live indexer (sessions \u2192 local index, optional server sync)",
26336
26339
  "After=default.target",
26340
+ // NEVER STOP RETRYING, and it must be in [Unit] — systemd reads the start
26341
+ // limiter there and ignores it under [Service], silently. The default gives
26342
+ // up after a burst and leaves the unit dead until a human notices: 53
26343
+ // restarts here, then "Start request repeated too quickly", then twelve
26344
+ // hours with nothing collected and nothing said. A collector that stops
26345
+ // forever after a crash loop is worse than one that keeps crashing.
26346
+ // 0 disables the limiter, so RestartSec below is the only pacing.
26347
+ "StartLimitIntervalSec=0",
26337
26348
  "",
26338
26349
  "[Service]",
26339
26350
  // Bounded heap: the daemon does bursty batch work (transcript parse,
@@ -26356,7 +26367,6 @@ function renderSystemdUnit(watchJs, node, logFile) {
26356
26367
  // that stops forever after a crash loop is worse than one that keeps
26357
26368
  // crashing: the user is told nothing and their history silently ends.
26358
26369
  // 0 disables the limiter, so RestartSec above is the only pacing.
26359
- "StartLimitIntervalSec=0",
26360
26370
  // A bounded cgroup, so a leak becomes a restart rather than a machine that
26361
26371
  // swaps. MemoryHigh throttles and reclaims first; MemoryMax is the kill.
26362
26372
  // --max-old-space-size bounds the V8 heap and NOT Buffers, and the observed
@@ -27141,6 +27151,7 @@ var DEFAULT_ALLOW = [
27141
27151
  "recall_redundant_files",
27142
27152
  "recall_user_prompts",
27143
27153
  "recall_decision_record",
27154
+ "recall_decisions",
27144
27155
  "recall_analytics_summary",
27145
27156
  "recall_outcome_summary",
27146
27157
  "recall_regenerate_summary",