chat-recall 0.7.11 → 0.7.12

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/mcp-relay.js CHANGED
@@ -192,7 +192,7 @@ function bridge(input, output, sock, exit, opts = {}) {
192
192
  }
193
193
 
194
194
  // src/mcp-relay.ts
195
- var VERSION = true ? "0.7.11" : "0.0.0";
195
+ var VERSION = true ? "0.7.12" : "0.0.0";
196
196
  var SERVER_URL = new URL("./mcp.js", import.meta.url);
197
197
  var SERVER_PATH = fileURLToPath(SERVER_URL);
198
198
  var START_TIMEOUT_MS = 15e3;
package/dist/mcp.js CHANGED
@@ -5065,8 +5065,15 @@ var init_claude_prompt_origin = __esm({
5065
5065
  INJECTED_PREFIXES = [
5066
5066
  ["<task-notification", "task-notification"],
5067
5067
  ["<agent-message", "peer"],
5068
+ ["<cross-session-message", "peer"],
5069
+ ["[Cross-session delivery notice]", "peer"],
5068
5070
  ["Another Claude session sent a message:", "peer"],
5069
- ["Stop hook feedback:", "hook"]
5071
+ ["Stop hook feedback:", "hook"],
5072
+ ["<bash-stdout>", "command-output"],
5073
+ ["<bash-stderr>", "command-output"],
5074
+ ["<local-command-stdout>", "command-output"],
5075
+ ["<local-command-stderr>", "command-output"],
5076
+ ["<<autonomous-loop", "meta"]
5070
5077
  ];
5071
5078
  }
5072
5079
  });
@@ -6041,7 +6048,7 @@ var init_session_sentiment = __esm({
6041
6048
  DIRECTIVE_HEAD = /^(?:please\s+)?(?:use|implement|build|make|add|create|fix|remove|delete|update|refactor|run|deploy|push|merge|test|check|investigate|find|search|show|list|generate|set\s+up|ensure)\b/i;
6042
6049
  CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
6043
6050
  FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
6044
- MARKERS_VERSION = 2;
6051
+ MARKERS_VERSION = 3;
6045
6052
  }
6046
6053
  });
6047
6054
 
@@ -11619,7 +11626,11 @@ __export(raw_exports, {
11619
11626
  gzipContainer: () => gzipContainer,
11620
11627
  mapContainerText: () => mapContainerText,
11621
11628
  parseOpenCodeDumpText: () => parseOpenCodeDumpText,
11622
- parseTranscriptFromContainer: () => parseTranscriptFromContainer
11629
+ parseTranscriptFromContainer: () => parseTranscriptFromContainer,
11630
+ redactContainer: () => redactContainer,
11631
+ redactJsonLine: () => redactJsonLine,
11632
+ repairContainer: () => repairContainer,
11633
+ repairRedactedJsonl: () => repairRedactedJsonl
11623
11634
  });
11624
11635
  import { gzipSync, gunzipSync } from "zlib";
11625
11636
  import { createHash as createHash3 } from "crypto";
@@ -11660,6 +11671,134 @@ function gunzipContainer(gz) {
11660
11671
  function mapContainerText(c, fn) {
11661
11672
  return { ...c, files: c.files.map((f) => ({ name: f.name, text: fn(f.text) })) };
11662
11673
  }
11674
+ function repairRedactedJsonl(text) {
11675
+ let repaired = 0;
11676
+ const parts = [];
11677
+ let copied = 0;
11678
+ let at = text.indexOf("[REDACTED:");
11679
+ while (at >= 0) {
11680
+ const start = text.lastIndexOf("\n", at) + 1;
11681
+ let end = text.indexOf("\n", at);
11682
+ if (end < 0)
11683
+ end = text.length;
11684
+ const fixed = repairLine(text.slice(start, end));
11685
+ if (fixed !== null) {
11686
+ parts.push(text.slice(copied, start), fixed);
11687
+ copied = end;
11688
+ repaired++;
11689
+ }
11690
+ at = text.indexOf("[REDACTED:", end);
11691
+ }
11692
+ if (repaired === 0)
11693
+ return { text, repaired: 0 };
11694
+ parts.push(text.slice(copied));
11695
+ return { text: parts.join(""), repaired };
11696
+ }
11697
+ function parseError(line) {
11698
+ try {
11699
+ JSON.parse(line);
11700
+ return null;
11701
+ } catch (e) {
11702
+ const m = /position (\d+)/.exec(e instanceof Error ? e.message : "");
11703
+ return m ? Number(m[1]) : line.length;
11704
+ }
11705
+ }
11706
+ function repairLine(line) {
11707
+ if (!line.includes("[REDACTED:") || parseError(line) === null)
11708
+ return null;
11709
+ let out = line.replace(/(?<!\\)((?:\\\\)*)\\(\[REDACTED:)/g, "$1$2");
11710
+ for (let attempt = 0; attempt < 64; attempt++) {
11711
+ const at = parseError(out);
11712
+ if (at === null)
11713
+ return out;
11714
+ let site = -1;
11715
+ for (const m of out.matchAll(MARKER_QUOTE)) {
11716
+ const q = m.index + m[0].length - 1;
11717
+ if (q < at)
11718
+ site = q;
11719
+ }
11720
+ if (site < 0)
11721
+ return null;
11722
+ out = out.slice(0, site) + "\\" + out.slice(site);
11723
+ }
11724
+ return null;
11725
+ }
11726
+ function redactJsonLine(line, redact) {
11727
+ if (!line.includes('"'))
11728
+ return redact(line);
11729
+ try {
11730
+ JSON.parse(line);
11731
+ } catch {
11732
+ return redact(line);
11733
+ }
11734
+ const decoded = mapJsonStrings(line, redact, true);
11735
+ const out = redact(decoded);
11736
+ try {
11737
+ JSON.parse(out);
11738
+ return out;
11739
+ } catch {
11740
+ return mapJsonStrings(decoded, redact, false);
11741
+ }
11742
+ }
11743
+ function mapJsonStrings(line, fn, escapedOnly) {
11744
+ let out = "";
11745
+ let i = 0;
11746
+ for (; ; ) {
11747
+ const q = line.indexOf('"', i);
11748
+ if (q < 0)
11749
+ return out + line.slice(i);
11750
+ let j = q + 1;
11751
+ while (j < line.length) {
11752
+ const c = line.charCodeAt(j);
11753
+ if (c === 92)
11754
+ j += 2;
11755
+ else if (c === 34)
11756
+ break;
11757
+ else
11758
+ j++;
11759
+ }
11760
+ const token = line.slice(q, j + 1);
11761
+ out += line.slice(i, q);
11762
+ i = j + 1;
11763
+ const body2 = token.slice(1, -1);
11764
+ const escaped = body2.includes("\\");
11765
+ if (escapedOnly && !escaped) {
11766
+ out += token;
11767
+ continue;
11768
+ }
11769
+ let value = body2;
11770
+ if (escaped) {
11771
+ try {
11772
+ value = JSON.parse(token);
11773
+ } catch {
11774
+ out += token;
11775
+ continue;
11776
+ }
11777
+ }
11778
+ const next = fn(value);
11779
+ out += next === value ? token : JSON.stringify(next);
11780
+ }
11781
+ }
11782
+ function redactContainer(c, redact) {
11783
+ return {
11784
+ ...c,
11785
+ files: c.files.map((f) => ({
11786
+ name: f.name,
11787
+ text: f.name.endsWith(".jsonl") ? f.text.split("\n").map((l) => l ? redactJsonLine(l, redact) : l).join("\n") : redact(f.text)
11788
+ }))
11789
+ };
11790
+ }
11791
+ function repairContainer(c) {
11792
+ let repaired = 0;
11793
+ const files = c.files.map((f) => {
11794
+ if (!f.name.endsWith(".jsonl"))
11795
+ return f;
11796
+ const r = repairRedactedJsonl(f.text);
11797
+ repaired += r.repaired;
11798
+ return r.repaired > 0 ? { name: f.name, text: r.text } : f;
11799
+ });
11800
+ return repaired > 0 ? { container: { ...c, files }, repaired } : { container: c, repaired: 0 };
11801
+ }
11663
11802
  function subagentKind(id) {
11664
11803
  return id.includes("acompact") ? "compact" : id.includes("aside_question") ? "aside" : id.includes("explore") || /^agent-a[0-9a-f]{16,}$/i.test(id) ? "explore" : "other";
11665
11804
  }
@@ -11830,6 +11969,7 @@ function requireFs() {
11830
11969
  function requirePath() {
11831
11970
  return pathMod;
11832
11971
  }
11972
+ var MARKER_QUOTE;
11833
11973
  var init_raw = __esm({
11834
11974
  "../engine/dist/transcript/raw.js"() {
11835
11975
  "use strict";
@@ -11837,6 +11977,7 @@ var init_raw = __esm({
11837
11977
  init_claude2();
11838
11978
  init_codex2();
11839
11979
  init_from_events();
11980
+ MARKER_QUOTE = /\[REDACTED:[A-Za-z0-9_-]+\]"/g;
11840
11981
  }
11841
11982
  });
11842
11983
 
@@ -13173,7 +13314,13 @@ function redactSecrets(text, opts = {}) {
13173
13314
  return whole;
13174
13315
  if (opts.count)
13175
13316
  opts.count.redactions++;
13176
- return whole.slice(0, whole.length - secret.length) + `[REDACTED:${r.label}]`;
13317
+ let last = args.length - 1;
13318
+ if (typeof args[last] === "object")
13319
+ last--;
13320
+ const source = args[last];
13321
+ const secretStart = args[last - 1] + whole.length - secret.length;
13322
+ const head = escapeHead(source, secretStart, secret.length);
13323
+ return whole.slice(0, whole.length - secret.length + head) + `[REDACTED:${r.label}]` + escapeKept(whole, whole.length);
13177
13324
  });
13178
13325
  }
13179
13326
  const ctx = findContextualSecrets(out);
@@ -13181,10 +13328,25 @@ function redactSecrets(text, opts = {}) {
13181
13328
  const { start, end } = ctx[i];
13182
13329
  if (opts.count)
13183
13330
  opts.count.redactions++;
13184
- out = out.slice(0, start) + "[REDACTED:secret-context]" + out.slice(end);
13331
+ const head = escapeHead(out, start, end - start);
13332
+ out = out.slice(0, start + head) + "[REDACTED:secret-context]" + escapeKept(out, end) + out.slice(end);
13185
13333
  }
13186
13334
  return out;
13187
13335
  }
13336
+ function escapeKept(text, end) {
13337
+ let run = 0;
13338
+ while (run < end && text.charCodeAt(end - 1 - run) === 92)
13339
+ run++;
13340
+ return run % 2 === 1 ? "\\" : "";
13341
+ }
13342
+ function escapeHead(text, start, length) {
13343
+ let run = 0;
13344
+ while (run < start && text.charCodeAt(start - 1 - run) === 92)
13345
+ run++;
13346
+ if (run % 2 === 0)
13347
+ return 0;
13348
+ return Math.min(text[start] === "u" ? 5 : 1, length);
13349
+ }
13188
13350
  function maskSecret(s) {
13189
13351
  if (!s)
13190
13352
  return "";
@@ -13291,7 +13453,12 @@ var init_secret_redactor = __esm({
13291
13453
  // userinfo URL walked through in cleartext — and a `jdbc:postgresql://…`
13292
13454
  // prefix broke the \b anchor for the one family it did cover. Any scheme
13293
13455
  // followed by userinfo is a credential, so match the shape, not a list.
13294
- { label: "url-password", secret: 1, pattern: /\b[a-zA-Z][a-zA-Z0-9+.-]{1,31}:\/\/[^:@\s/]{1,64}:([^@\s/]{1,256})(?=@)/g },
13456
+ //
13457
+ // A quote in userinfo is percent-encoded, so neither part takes a `"`. The
13458
+ // sync redacts JSONL text, and a match that ran on through `","is_error":`
13459
+ // to a later `@` replaced JSON structure: 4 lines on one machine stopped
13460
+ // parsing, and their records were dropped.
13461
+ { label: "url-password", secret: 1, pattern: /\b[a-zA-Z][a-zA-Z0-9+.-]{1,31}:\/\/[^:@\s/"]{1,64}:([^@\s/"]{1,256})(?=@)/g },
13295
13462
  // Bare AWS secret-access-key VALUE: EXACTLY 40 base64 chars, word-bounded,
13296
13463
  // containing upper+lower+digit. This is the gitleaks heuristic — the mixed-case
13297
13464
  // requirement excludes 40-char lowercase-hex git SHAs, and the exact-40 bound
@@ -19677,7 +19844,7 @@ var init_http = __esm({
19677
19844
  CLI_VERSION = JSON.parse(readFileSync36(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
19678
19845
  } catch {
19679
19846
  try {
19680
- if (true) CLI_VERSION = "0.7.11";
19847
+ if (true) CLI_VERSION = "0.7.12";
19681
19848
  } catch {
19682
19849
  }
19683
19850
  }
@@ -20175,7 +20342,7 @@ var init_telemetry = __esm({
20175
20342
  init_sync_client();
20176
20343
  cliVersion2 = () => {
20177
20344
  try {
20178
- return true ? "0.7.11" : "dev";
20345
+ return true ? "0.7.12" : "dev";
20179
20346
  } catch {
20180
20347
  return "dev";
20181
20348
  }
@@ -22138,7 +22305,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
22138
22305
  } else {
22139
22306
  try {
22140
22307
  const count2 = { redactions: 0 };
22141
- const redacted = mapContainerText(container, (t) => redactSecrets(t, { force: true, count: count2 }));
22308
+ const redacted = redactContainer(container, (t) => redactSecrets(t, { force: true, count: count2 }));
22142
22309
  count.redactions += count2.redactions;
22143
22310
  const { gz, size } = gzipContainer(redacted);
22144
22311
  if (gz.length <= 8 * 1024 * 1024) {
@@ -22338,7 +22505,7 @@ var init_sync_client = __esm({
22338
22505
  ownVersion = JSON.parse(readFileSync38(join49(dir, "../package.json"), "utf-8")).version || ownVersion;
22339
22506
  } catch {
22340
22507
  try {
22341
- if (true) ownVersion = "0.7.11";
22508
+ if (true) ownVersion = "0.7.12";
22342
22509
  } catch {
22343
22510
  }
22344
22511
  }
@@ -29287,7 +29454,7 @@ function installCrashGuards() {
29287
29454
  reportClientEvent2("mcp_crash", { message: err.stack || err.message });
29288
29455
  });
29289
29456
  }
29290
- var RELAY_VERSION = true ? "0.7.11" : "0.0.0";
29457
+ var RELAY_VERSION = true ? "0.7.12" : "0.0.0";
29291
29458
  function daemonIdleSecs() {
29292
29459
  const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
29293
29460
  if (raw === void 0) return 900;
@@ -1 +1 @@
1
- {"version":3,"file":"scan-worker.d.ts","sourceRoot":"","sources":["../src/scan-worker.ts"],"names":[],"mappings":"AA8BA,OAAO,EAEL,KAAK,cAAc,EAAE,KAAK,eAAe,EAC1C,MAAM,6CAA6C,CAAC;AAErD,oEAAoE;AACpE,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAChJ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE;QAAE,CAAC,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"scan-worker.d.ts","sourceRoot":"","sources":["../src/scan-worker.ts"],"names":[],"mappings":"AA8BA,OAAO,EAEL,KAAK,cAAc,EAAE,KAAK,eAAe,EAC1C,MAAM,6CAA6C,CAAC;AAGrD,oEAAoE;AACpE,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAChJ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE;QAAE,CAAC,EAAE,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}