chat-recall 0.7.7 → 0.7.8

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/cli.js CHANGED
@@ -4892,8 +4892,8 @@ function writeSecrets(secrets) {
4892
4892
  _secretsCache = null;
4893
4893
  const p = secretsPath();
4894
4894
  mkdirSync2(dirname2(p), { recursive: true });
4895
- const body = "# chat-recall secrets \u2014 NOT committed/synced. Mode 0600.\n" + Object.entries(secrets).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join("\n") + "\n";
4896
- writeFileSync(p, body);
4895
+ const body2 = "# chat-recall secrets \u2014 NOT committed/synced. Mode 0600.\n" + Object.entries(secrets).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join("\n") + "\n";
4896
+ writeFileSync(p, body2);
4897
4897
  try {
4898
4898
  chmodSync(p, 384);
4899
4899
  } catch {
@@ -5979,11 +5979,11 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
5979
5979
  }
5980
5980
  const toolResult = obj.toolUseResult;
5981
5981
  if (toolResult && typeof toolResult === "object" && toolCount < maxMessages) {
5982
- const resultText = toolResult.result;
5982
+ const resultText2 = toolResult.result;
5983
5983
  const query = toolResult.query;
5984
- if (resultText && typeof resultText === "string" && isValuableToolResult(resultText, "WebSearch")) {
5984
+ if (resultText2 && typeof resultText2 === "string" && isValuableToolResult(resultText2, "WebSearch")) {
5985
5985
  const searchText = query ? `Search: ${query}
5986
- ${resultText}` : resultText;
5986
+ ${resultText2}` : resultText2;
5987
5987
  content.toolResults.push({
5988
5988
  text: searchText.slice(0, 2e3),
5989
5989
  lineNumber: lineNum,
@@ -7002,7 +7002,7 @@ function gitLogRepo(repo, startIso, endIso) {
7002
7002
  const authorIso = seg.slice(fieldPositions[1] + 1, fieldPositions[2]);
7003
7003
  const authorName = seg.slice(fieldPositions[2] + 1, fieldPositions[3]);
7004
7004
  const subject = seg.slice(fieldPositions[3] + 1, fieldPositions[4]);
7005
- let body = seg.slice(fieldPositions[4] + 1);
7005
+ let body2 = seg.slice(fieldPositions[4] + 1);
7006
7006
  current = {
7007
7007
  sha,
7008
7008
  shortSha,
@@ -7016,11 +7016,11 @@ function gitLogRepo(repo, startIso, endIso) {
7016
7016
  };
7017
7017
  const recovered = [];
7018
7018
  let m;
7019
- while (m = TRAILING_NUMSTAT.exec(body)) {
7019
+ while (m = TRAILING_NUMSTAT.exec(body2)) {
7020
7020
  recovered.unshift(m[1]);
7021
- body = body.slice(0, body.length - m[0].length);
7021
+ body2 = body2.slice(0, body2.length - m[0].length);
7022
7022
  }
7023
- current.body = body.trim();
7023
+ current.body = body2.trim();
7024
7024
  for (const line of recovered)
7025
7025
  recordNumstat(line);
7026
7026
  } else if (NUMSTAT.test(seg)) {
@@ -7914,7 +7914,7 @@ var init_opencode = __esm({
7914
7914
  });
7915
7915
  const out = d?.state?.output;
7916
7916
  if (out !== void 0 && out !== null) {
7917
- const body = typeof out === "string" ? out : JSON.stringify(out);
7917
+ const body2 = typeof out === "string" ? out : JSON.stringify(out);
7918
7918
  events.push({
7919
7919
  kind: "tool_result",
7920
7920
  ts,
@@ -7922,9 +7922,9 @@ var init_opencode = __esm({
7922
7922
  line: lineNum,
7923
7923
  toolUseId: callId,
7924
7924
  toolName,
7925
- resultBody: body,
7925
+ resultBody: body2,
7926
7926
  resultIsError: d?.state?.status === "error",
7927
- resultBytes: body.length
7927
+ resultBytes: body2.length
7928
7928
  });
7929
7929
  }
7930
7930
  }
@@ -8699,13 +8699,13 @@ var init_codex2 = __esm({
8699
8699
  } else if (obj.type === "response_item" && payload.type === "function_call_output") {
8700
8700
  const callId = String(payload.call_id || "");
8701
8701
  const out = payload.output;
8702
- let body = "";
8702
+ let body2 = "";
8703
8703
  let isError = false;
8704
8704
  let exitCode;
8705
8705
  if (typeof out === "string")
8706
- body = out;
8706
+ body2 = out;
8707
8707
  else if (out && typeof out === "object") {
8708
- body = String(out.content ?? out.output ?? out.stdout ?? out.text ?? "");
8708
+ body2 = String(out.content ?? out.output ?? out.stdout ?? out.text ?? "");
8709
8709
  if (typeof out.exit_code === "number") {
8710
8710
  exitCode = out.exit_code;
8711
8711
  isError = exitCode !== 0;
@@ -8717,10 +8717,10 @@ var init_codex2 = __esm({
8717
8717
  tsIso,
8718
8718
  line: lineNum,
8719
8719
  toolUseId: callId,
8720
- resultBody: body,
8720
+ resultBody: body2,
8721
8721
  resultIsError: isError,
8722
8722
  resultExitCode: exitCode,
8723
- resultBytes: body.length
8723
+ resultBytes: body2.length
8724
8724
  });
8725
8725
  }
8726
8726
  }
@@ -9742,15 +9742,15 @@ function messagesToEvents(messages, createdAtMs, updatedAtMs) {
9742
9742
  const p = part;
9743
9743
  if (p.type !== "tool-result")
9744
9744
  continue;
9745
- const body = resultBodyOf(p);
9745
+ const body2 = resultBodyOf(p);
9746
9746
  events.push({
9747
9747
  kind: "tool_result",
9748
9748
  ts: clock,
9749
9749
  line: 0,
9750
9750
  toolUseId: typeof p.toolCallId === "string" ? p.toolCallId : void 0,
9751
- resultBody: body,
9751
+ resultBody: body2,
9752
9752
  resultIsError: isError,
9753
- resultBytes: Buffer.byteLength(body, "utf8")
9753
+ resultBytes: Buffer.byteLength(body2, "utf8")
9754
9754
  });
9755
9755
  }
9756
9756
  }
@@ -10613,11 +10613,11 @@ var init_cursor = __esm({
10613
10613
  const events = readComposerEvents(r.composer);
10614
10614
  if (events.length === 0)
10615
10615
  return null;
10616
- const body = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
10616
+ const body2 = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
10617
10617
  return {
10618
10618
  tool: "cursor",
10619
10619
  mtime: statSync9(r.composer.globalDbPath).mtimeMs,
10620
- files: [{ name: `${r.composer.composerId}.jsonl`, bytes: Buffer.from(body, "utf8") }]
10620
+ files: [{ name: `${r.composer.composerId}.jsonl`, bytes: Buffer.from(body2, "utf8") }]
10621
10621
  };
10622
10622
  } catch {
10623
10623
  return null;
@@ -10972,9 +10972,29 @@ function findSessionFile(sessionId) {
10972
10972
  function invalidateSessionFileIndex() {
10973
10973
  indexCache = null;
10974
10974
  }
10975
+ function indexStillValid(cache4) {
10976
+ const roots = claudeProjectDirs();
10977
+ if (roots.length !== cache4.roots.length || roots.some((r, i) => r !== cache4.roots[i]))
10978
+ return false;
10979
+ for (const [dir, mtime] of cache4.dirs) {
10980
+ if (dirMtime(dir) !== mtime)
10981
+ return false;
10982
+ }
10983
+ return true;
10984
+ }
10975
10985
  function sessionFileIndex() {
10976
- if (indexCache)
10977
- return indexCache;
10986
+ if (indexCache) {
10987
+ const now = Date.now();
10988
+ if (now - indexCache.checkedAt < INDEX_RECHECK_MS)
10989
+ return indexCache.byId;
10990
+ if (indexStillValid(indexCache)) {
10991
+ indexCache.checkedAt = now;
10992
+ return indexCache.byId;
10993
+ }
10994
+ indexCache = null;
10995
+ }
10996
+ const dirs = /* @__PURE__ */ new Map();
10997
+ const roots = claudeProjectDirs();
10978
10998
  const byId = /* @__PURE__ */ new Map();
10979
10999
  const seenRoots = /* @__PURE__ */ new Set();
10980
11000
  const projectPaths = /* @__PURE__ */ new Map();
@@ -10986,10 +11006,11 @@ function sessionFileIndex() {
10986
11006
  }
10987
11007
  return p;
10988
11008
  };
10989
- for (const root of claudeProjectDirs()) {
11009
+ for (const root of roots) {
10990
11010
  if (seenRoots.has(root) || !existsSync13(root))
10991
11011
  continue;
10992
11012
  seenRoots.add(root);
11013
+ dirs.set(root, dirMtime(root));
10993
11014
  let entries;
10994
11015
  try {
10995
11016
  entries = readdirSync10(root, { withFileTypes: true });
@@ -11000,6 +11021,7 @@ function sessionFileIndex() {
11000
11021
  if (!entry.isDirectory())
11001
11022
  continue;
11002
11023
  const dir = join15(root, entry.name);
11024
+ dirs.set(dir, dirMtime(dir));
11003
11025
  let names;
11004
11026
  try {
11005
11027
  names = readdirSync10(dir);
@@ -11024,7 +11046,7 @@ function sessionFileIndex() {
11024
11046
  }
11025
11047
  }
11026
11048
  if (scanScopeDepth > 0)
11027
- indexCache = byId;
11049
+ indexCache = { byId, dirs, roots, checkedAt: Date.now() };
11028
11050
  return byId;
11029
11051
  }
11030
11052
  function findSessionFiles(sessionId) {
@@ -11182,7 +11204,7 @@ function findCodexSessionFileIn(root, sessionId) {
11182
11204
  }
11183
11205
  return scanDir(root);
11184
11206
  }
11185
- var scanScopeDepth, indexCache, readScope, readScopeDepth, derivedScope, geminiCache, MAX_EVENT_LINE_BYTES;
11207
+ var scanScopeDepth, indexCache, INDEX_RECHECK_MS, dirMtime, readScope, readScopeDepth, derivedScope, geminiCache, MAX_EVENT_LINE_BYTES;
11186
11208
  var init_live_session_scan = __esm({
11187
11209
  "../engine/dist/core/live-session-scan.js"() {
11188
11210
  "use strict";
@@ -11194,6 +11216,14 @@ var init_live_session_scan = __esm({
11194
11216
  init_project_dir_name();
11195
11217
  scanScopeDepth = 0;
11196
11218
  indexCache = null;
11219
+ INDEX_RECHECK_MS = 1e3;
11220
+ dirMtime = (p) => {
11221
+ try {
11222
+ return statSync11(p).mtimeMs;
11223
+ } catch {
11224
+ return -1;
11225
+ }
11226
+ };
11197
11227
  readScope = null;
11198
11228
  readScopeDepth = 0;
11199
11229
  derivedScope = null;
@@ -11459,15 +11489,36 @@ var init_claude2 = __esm({
11459
11489
  listSessions(opts = {}) {
11460
11490
  const cutoff = opts.sinceMs ?? 0;
11461
11491
  const filter = opts.projectFilter?.toLowerCase();
11462
- const seen = /* @__PURE__ */ new Set();
11463
- const out = [];
11492
+ const byId = /* @__PURE__ */ new Map();
11464
11493
  for (const root of claudeProjectDirs()) {
11465
- this.collectSessionsFromRoot(root, cutoff, filter, seen, out, opts.previews !== false);
11494
+ this.collectSessionsFromRoot(root, filter, byId, opts.previews !== false);
11466
11495
  }
11496
+ const out = [...byId.values()].filter((r) => r.mtime >= cutoff);
11467
11497
  out.sort((a, b) => b.mtime - a.mtime);
11468
11498
  return opts.limit ? out.slice(0, opts.limit) : out;
11469
11499
  }
11470
- collectSessionsFromRoot(root, cutoff, filter, seen, out, previews) {
11500
+ /**
11501
+ * Add this root's sessions to `byId`. A session resumed under a second
11502
+ * profile has one file in each home under the same id. It is ONE session: the
11503
+ * first home keeps its path, and its mtime is the newest of all copies.
11504
+ *
11505
+ * Each copy was listed as its own ref before. Session 8da8d72b had a primary
11506
+ * copy frozen at 05:55 and a second-home copy growing until 12:00; the walk
11507
+ * handled both refs under one ledger row with two different mtimes, and the
11508
+ * row that shipped nothing stamped the other copy's mtime.
11509
+ */
11510
+ collectSessionsFromRoot(root, filter, byId, previews) {
11511
+ const add = (ref) => {
11512
+ const prior = byId.get(ref.rawId);
11513
+ if (!prior) {
11514
+ byId.set(ref.rawId, ref);
11515
+ return;
11516
+ }
11517
+ if (ref.mtime > prior.mtime) {
11518
+ prior.mtime = ref.mtime;
11519
+ prior.modified = ref.modified;
11520
+ }
11521
+ };
11471
11522
  if (!existsSync15(root))
11472
11523
  return;
11473
11524
  for (const proj of readdirSync11(root, { withFileTypes: true })) {
@@ -11478,6 +11529,7 @@ var init_claude2 = __esm({
11478
11529
  const projPath = join16(root, proj.name);
11479
11530
  const projectPath = resolveProjectDirName(proj.name);
11480
11531
  const indexPath = join16(projPath, "sessions-index.json");
11532
+ const indexed = /* @__PURE__ */ new Set();
11481
11533
  if (existsSync15(indexPath)) {
11482
11534
  try {
11483
11535
  const indexData = JSON.parse(readFileSync10(indexPath, "utf-8"));
@@ -11485,10 +11537,8 @@ var init_claude2 = __esm({
11485
11537
  for (const entry of entries) {
11486
11538
  if (!entry.fullPath || !existsSync15(entry.fullPath))
11487
11539
  continue;
11488
- if ((entry.fileMtime ?? 0) < cutoff)
11489
- continue;
11490
- seen.add(entry.sessionId);
11491
- out.push({
11540
+ indexed.add(entry.sessionId);
11541
+ add({
11492
11542
  toolId: "claude",
11493
11543
  rawId: entry.sessionId,
11494
11544
  prefixedId: entry.sessionId,
@@ -11515,7 +11565,7 @@ var init_claude2 = __esm({
11515
11565
  if (!f.endsWith(".jsonl") || f === "sessions-index.json")
11516
11566
  continue;
11517
11567
  const sessionId = basename10(f, ".jsonl");
11518
- if (seen.has(sessionId))
11568
+ if (indexed.has(sessionId))
11519
11569
  continue;
11520
11570
  const fullPath = join16(projPath, f);
11521
11571
  let stat3;
@@ -11524,10 +11574,13 @@ var init_claude2 = __esm({
11524
11574
  } catch {
11525
11575
  continue;
11526
11576
  }
11527
- if (stat3.mtimeMs < cutoff)
11577
+ const prior = byId.get(sessionId);
11578
+ if (prior) {
11579
+ add({ ...prior, mtime: stat3.mtimeMs, modified: stat3.mtime.toISOString() });
11528
11580
  continue;
11581
+ }
11529
11582
  const firstPrompt = previews ? extractFirstUserPromptSync(fullPath, { maxLength: 200 }) : "";
11530
- out.push({
11583
+ add({
11531
11584
  toolId: "claude",
11532
11585
  rawId: sessionId,
11533
11586
  prefixedId: sessionId,
@@ -11657,20 +11710,20 @@ var init_claude2 = __esm({
11657
11710
  text += (text ? "\n" : "") + it.text;
11658
11711
  } else if (it.type === "tool_result") {
11659
11712
  const id = typeof it.tool_use_id === "string" ? it.tool_use_id : "";
11660
- let body = "";
11713
+ let body2 = "";
11661
11714
  const c = it.content;
11662
11715
  if (typeof c === "string")
11663
- body = c;
11716
+ body2 = c;
11664
11717
  else if (Array.isArray(c)) {
11665
11718
  for (const sub of c) {
11666
11719
  if (sub && typeof sub === "object" && sub.type === "text") {
11667
11720
  const t = sub.text;
11668
11721
  if (typeof t === "string")
11669
- body += t;
11722
+ body2 += t;
11670
11723
  }
11671
11724
  }
11672
11725
  }
11673
- toolResults.push({ id, body, isError: it.is_error === true });
11726
+ toolResults.push({ id, body: body2, isError: it.is_error === true });
11674
11727
  }
11675
11728
  }
11676
11729
  }
@@ -12606,10 +12659,10 @@ function applyChunkPrivacy(text) {
12606
12659
  out = redactFilePaths(out);
12607
12660
  return out;
12608
12661
  }
12609
- function redactToolResultBody(toolName, body) {
12610
- if (!body)
12611
- return body;
12612
- return `[redacted: ${toolName} output, ${body.length} chars]`;
12662
+ function redactToolResultBody(toolName, body2) {
12663
+ if (!body2)
12664
+ return body2;
12665
+ return `[redacted: ${toolName} output, ${body2.length} chars]`;
12613
12666
  }
12614
12667
  var DEFAULT_REDACTION_RULES, SECRET_CONTEXT_RE, HIGH_ENTROPY_TOKEN_RE, cache, CANARY, MAX_PACK_RULES, MAX_PATTERN_LEN, serverPack, globalRegexCache, privacyCache, PATH_REGEX;
12615
12668
  var init_secret_redactor = __esm({
@@ -14839,8 +14892,8 @@ function parseFrontmatter(content) {
14839
14892
  return { body: content };
14840
14893
  const header = content.slice(3, close);
14841
14894
  const afterFence = content.indexOf("\n", close + 1);
14842
- const body = afterFence === -1 ? "" : content.slice(afterFence + 1);
14843
- const out = { body };
14895
+ const body2 = afterFence === -1 ? "" : content.slice(afterFence + 1);
14896
+ const out = { body: body2 };
14844
14897
  for (const line of header.split("\n")) {
14845
14898
  const m = line.match(/^\s*([A-Za-z_]+)\s*:\s*(.+?)\s*$/);
14846
14899
  if (!m)
@@ -14932,9 +14985,9 @@ var init_plan_source = __esm({
14932
14985
  const isAgentPlan = planName.includes("-agent-");
14933
14986
  const content = readFileSync15(filePath, "utf-8");
14934
14987
  const fm = parseFrontmatter(content);
14935
- const body = fm.body;
14936
- const firstLine = body.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || planName;
14937
- const projectPath = fm.cwd || this.extractProjectPath(body);
14988
+ const body2 = fm.body;
14989
+ const firstLine = body2.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || planName;
14990
+ const projectPath = fm.cwd || this.extractProjectPath(body2);
14938
14991
  const baseName = planName.replace(/-agent-[a-z0-9]+$/i, "");
14939
14992
  const claudeSessionId = fm.sessionId || (UUID_RE3.test(baseName) ? baseName : void 0);
14940
14993
  yield {
@@ -14944,7 +14997,7 @@ var init_plan_source = __esm({
14944
14997
  projectPath,
14945
14998
  filePath,
14946
14999
  mtime: stat3.mtimeMs,
14947
- contentPreview: body.slice(0, 300),
15000
+ contentPreview: body2.slice(0, 300),
14948
15001
  extra: {
14949
15002
  tool: "claude",
14950
15003
  isAgentPlan,
@@ -15051,8 +15104,8 @@ var init_plan_source = __esm({
15051
15104
  return [];
15052
15105
  const content = readFileSync15(item.filePath, "utf-8");
15053
15106
  const chunks = [];
15054
- const { body } = parseFrontmatter(content);
15055
- const sections = splitByHeaders(body);
15107
+ const { body: body2 } = parseFrontmatter(content);
15108
+ const sections = splitByHeaders(body2);
15056
15109
  for (let i = 0; i < sections.length; i++) {
15057
15110
  const section = sections[i];
15058
15111
  if (!section.text.trim() || section.text.trim().length < 20)
@@ -15685,10 +15738,10 @@ import { homedir as homedir9 } from "os";
15685
15738
  import { join as join26, basename as basename14 } from "path";
15686
15739
  function parseFrontmatter2(content) {
15687
15740
  const fm = {};
15688
- let body = content;
15741
+ let body2 = content;
15689
15742
  const m = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
15690
15743
  if (m) {
15691
- body = m[2];
15744
+ body2 = m[2];
15692
15745
  for (const line of m[1].split(/\r?\n/)) {
15693
15746
  const t = line.trim();
15694
15747
  if (!t || t.startsWith("#"))
@@ -15705,7 +15758,7 @@ function parseFrontmatter2(content) {
15705
15758
  fm[k] = v;
15706
15759
  }
15707
15760
  }
15708
- return { fm, body };
15761
+ return { fm, body: body2 };
15709
15762
  }
15710
15763
  function projectHashToPath(hashDir) {
15711
15764
  return resolveProjectDirName(hashDir);
@@ -15782,9 +15835,9 @@ var init_agent_memory_source = __esm({
15782
15835
  if (!existsSync25(item.filePath))
15783
15836
  return [];
15784
15837
  const content = readFileSync18(item.filePath, "utf-8");
15785
- const { body } = parseFrontmatter2(content);
15838
+ const { body: body2 } = parseFrontmatter2(content);
15786
15839
  const chunks = [];
15787
- const sections = splitByHeaders(body);
15840
+ const sections = splitByHeaders(body2);
15788
15841
  for (let i = 0; i < sections.length; i++) {
15789
15842
  const section = sections[i];
15790
15843
  if (!section.text.trim() || section.text.trim().length < 20)
@@ -17428,13 +17481,13 @@ function parseFrontmatter4(text) {
17428
17481
  }
17429
17482
  return { fm, body: m[2] ?? "" };
17430
17483
  }
17431
- function stringifyFrontmatter(fm, body) {
17484
+ function stringifyFrontmatter(fm, body2) {
17432
17485
  const lines = Object.entries(fm).filter(([, v]) => v !== void 0 && v !== "").map(([k, v]) => `${k}: ${needsQuote(v) ? JSON.stringify(v) : v}`);
17433
17486
  return `---
17434
17487
  ${lines.join("\n")}
17435
17488
  ---
17436
17489
 
17437
- ${body.replace(/^\n+/, "")}`;
17490
+ ${body2.replace(/^\n+/, "")}`;
17438
17491
  }
17439
17492
  function needsQuote(v) {
17440
17493
  return /[:#]/.test(v) || /^\s|\s$/.test(v);
@@ -17521,11 +17574,11 @@ function parseCommand(content, fallbackName, format) {
17521
17574
  body: t.prompt || ""
17522
17575
  };
17523
17576
  }
17524
- const { fm, body } = parseFrontmatter4(content);
17577
+ const { fm, body: body2 } = parseFrontmatter4(content);
17525
17578
  return {
17526
17579
  name: fm.name || fallbackName,
17527
17580
  description: fm.description || "",
17528
- body: body.trim()
17581
+ body: body2.trim()
17529
17582
  };
17530
17583
  }
17531
17584
  var MAX_CHUNK_CHARS12, MAX_BODY_CHARS2, SlashCommandsSource;
@@ -17669,12 +17722,12 @@ function parseAgent(content, fallbackName, format) {
17669
17722
  body: t.developer_instructions || t.instructions || ""
17670
17723
  };
17671
17724
  }
17672
- const { fm, body } = parseFrontmatter4(content);
17725
+ const { fm, body: body2 } = parseFrontmatter4(content);
17673
17726
  return {
17674
17727
  name: fm.name || fallbackName,
17675
17728
  description: fm.description || "",
17676
17729
  tools: fm.tools || "",
17677
- body: body.trim()
17730
+ body: body2.trim()
17678
17731
  };
17679
17732
  }
17680
17733
  var MAX_CHUNK_CHARS13, MAX_BODY_CHARS3, SubagentsSource;
@@ -18587,7 +18640,7 @@ var init_http = __esm({
18587
18640
  CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
18588
18641
  } catch {
18589
18642
  try {
18590
- if (true) CLI_VERSION = "0.7.7";
18643
+ if (true) CLI_VERSION = "0.7.8";
18591
18644
  } catch {
18592
18645
  }
18593
18646
  }
@@ -19086,7 +19139,7 @@ var init_telemetry = __esm({
19086
19139
  init_sync_client();
19087
19140
  cliVersion2 = () => {
19088
19141
  try {
19089
- return true ? "0.7.7" : "dev";
19142
+ return true ? "0.7.8" : "dev";
19090
19143
  } catch {
19091
19144
  return "dev";
19092
19145
  }
@@ -19258,20 +19311,20 @@ async function probeServer(base3, opts = {}) {
19258
19311
  if (res.status === 404 || res.status === 410) return { kind: "moved", status: res.status };
19259
19312
  if (res.status >= 500) return { kind: "server_error", status: res.status };
19260
19313
  if (!res.ok) return { kind: "moved", status: res.status };
19261
- let body;
19314
+ let body2;
19262
19315
  try {
19263
- body = await res.text();
19316
+ body2 = await res.text();
19264
19317
  } catch (err) {
19265
19318
  return { kind: "unreachable", error: describeCause(err), reason: classifyUnreachable(err) };
19266
19319
  }
19267
19320
  let parsed;
19268
19321
  try {
19269
- parsed = JSON.parse(body);
19322
+ parsed = JSON.parse(body2);
19270
19323
  } catch {
19271
- return { kind: "not_api", status: res.status, snippet: body.trim().slice(0, 60) };
19324
+ return { kind: "not_api", status: res.status, snippet: body2.trim().slice(0, 60) };
19272
19325
  }
19273
19326
  if (typeof parsed?.apiVersion !== "number") {
19274
- return { kind: "not_api", status: res.status, snippet: body.trim().slice(0, 60) };
19327
+ return { kind: "not_api", status: res.status, snippet: body2.trim().slice(0, 60) };
19275
19328
  }
19276
19329
  return {
19277
19330
  kind: "ok",
@@ -19390,7 +19443,7 @@ function reportClientEvent(kind, opts = {}) {
19390
19443
  try {
19391
19444
  const targets = loadAllCredentials();
19392
19445
  if (!targets.length) return;
19393
- const body = JSON.stringify({
19446
+ const body2 = JSON.stringify({
19394
19447
  events: [{
19395
19448
  ts: Date.now(),
19396
19449
  kind: String(kind).slice(0, 64),
@@ -19407,7 +19460,7 @@ function reportClientEvent(kind, opts = {}) {
19407
19460
  void fetch(`${t.serverUrl.replace(/\/+$/, "")}/api/client-events`, {
19408
19461
  method: "POST",
19409
19462
  headers,
19410
- body,
19463
+ body: body2,
19411
19464
  signal: AbortSignal.timeout(3e3)
19412
19465
  }).catch(() => {
19413
19466
  });
@@ -19821,10 +19874,10 @@ async function fetchTenantSecurityConfig(cred) {
19821
19874
  let tenantRules = [];
19822
19875
  let rulePackVersion = null;
19823
19876
  if (rulesRes.ok) {
19824
- const body = await rulesRes.json().catch(() => ({}));
19825
- const enabled = (body.rules || []).filter((r) => r.enabled !== false);
19877
+ const body2 = await rulesRes.json().catch(() => ({}));
19878
+ const enabled = (body2.rules || []).filter((r) => r.enabled !== false);
19826
19879
  tenantRules = enabled;
19827
- const packSpec = body.pack?.rules ? { version: body.pack.version, rules: body.pack.rules.map((r) => ({ name: r.name, regex: r.regex, flags: r.flags, redact: true, source: r.source })) } : { version: body.version, rules: enabled.filter((r) => r.redact === true).map((r) => ({ name: r.name, regex: r.regex, redact: true, source: "tenant" })) };
19880
+ const packSpec = body2.pack?.rules ? { version: body2.pack.version, rules: body2.pack.rules.map((r) => ({ name: r.name, regex: r.regex, flags: r.flags, redact: true, source: r.source })) } : { version: body2.version, rules: enabled.filter((r) => r.redact === true).map((r) => ({ name: r.name, regex: r.regex, redact: true, source: "tenant" })) };
19828
19881
  lastServerPackSpec = { version: packSpec.version || "", rules: packSpec.rules };
19829
19882
  const pack = installServerRulePack(packSpec);
19830
19883
  rulePackVersion = serverRulePackVersion();
@@ -19832,20 +19885,20 @@ async function fetchTenantSecurityConfig(cred) {
19832
19885
  console.error(`[sync] server redaction rule "${r.name}" ignored: ${r.reason}`);
19833
19886
  }
19834
19887
  if (pack.accepted > 0) {
19835
- const rev = body.pack?.revision ? `, rev ${body.pack.revision}` : "";
19888
+ const rev = body2.pack?.revision ? `, rev ${body2.pack.revision}` : "";
19836
19889
  console.error(`[sync] ${pack.accepted} server redaction rule(s) active (pack ${rulePackVersion}${rev})`);
19837
19890
  }
19838
19891
  }
19839
19892
  let verifySecrets = true;
19840
19893
  if (settingsRes?.ok) {
19841
- const body = await settingsRes.json().catch(() => ({}));
19842
- if (typeof body.verifySecrets === "boolean") verifySecrets = body.verifySecrets;
19843
- if (typeof body.telemetry === "boolean") {
19844
- setTelemetryEligible(base3, body.telemetry);
19894
+ const body2 = await settingsRes.json().catch(() => ({}));
19895
+ if (typeof body2.verifySecrets === "boolean") verifySecrets = body2.verifySecrets;
19896
+ if (typeof body2.telemetry === "boolean") {
19897
+ setTelemetryEligible(base3, body2.telemetry);
19845
19898
  try {
19846
19899
  const prior = readCollectorHealth()?.telemetryEligible ?? {};
19847
19900
  updateCollectorHealth({
19848
- telemetryEligible: { ...prior, [base3]: { allowed: body.telemetry, at: Date.now() } }
19901
+ telemetryEligible: { ...prior, [base3]: { allowed: body2.telemetry, at: Date.now() } }
19849
19902
  });
19850
19903
  } catch {
19851
19904
  }
@@ -19904,14 +19957,14 @@ async function fetchTenantSyncConfig(cred) {
19904
19957
  return EMPTY_SYNC_CONFIG;
19905
19958
  }
19906
19959
  if (!res.ok) return lastKnownSyncConfig(base3, `HTTP ${res.status}`);
19907
- const body = await res.json().catch(() => ({}));
19960
+ const body2 = await res.json().catch(() => ({}));
19908
19961
  const config2 = {
19909
- excludeTools: Array.isArray(body.excludeTools) ? body.excludeTools.filter((t) => typeof t === "string") : [],
19910
- excludeProjects: Array.isArray(body.excludeProjects) ? body.excludeProjects.filter((p) => typeof p === "string") : [],
19962
+ excludeTools: Array.isArray(body2.excludeTools) ? body2.excludeTools.filter((t) => typeof t === "string") : [],
19963
+ excludeProjects: Array.isArray(body2.excludeProjects) ? body2.excludeProjects.filter((p) => typeof p === "string") : [],
19911
19964
  // Ids only — installSourceExclusions drops anything else, so a server
19912
19965
  // sending a path cannot make this collector read it.
19913
- excludeSources: Array.isArray(body.excludeSources) ? body.excludeSources.filter((x) => typeof x === "string") : [],
19914
- approveSources: Array.isArray(body.approveSources) ? body.approveSources.filter((x) => typeof x === "string") : []
19966
+ excludeSources: Array.isArray(body2.excludeSources) ? body2.excludeSources.filter((x) => typeof x === "string") : [],
19967
+ approveSources: Array.isArray(body2.approveSources) ? body2.approveSources.filter((x) => typeof x === "string") : []
19915
19968
  };
19916
19969
  const applied = installSourceExclusions(config2.excludeSources);
19917
19970
  if (applied.excluded > 0) {
@@ -20306,9 +20359,9 @@ async function syncToTargetInScope(cred, opts = {}) {
20306
20359
  const maxInflight = explicitThrottle ? 1 : isLocalHost(cred.serverUrl) ? Math.max(LOCAL_INFLIGHT, advertised ?? 0) : advertised ?? REMOTE_INFLIGHT_FALLBACK;
20307
20360
  const UPLOAD_TIMEOUT_MS = Number(process.env.CHAT_RECALL_UPLOAD_TIMEOUT_MS) || 9e4;
20308
20361
  const gzipBody = serverAcceptsGzipBody(cred.serverUrl);
20309
- const post = async (body) => {
20362
+ const post = async (body2) => {
20310
20363
  const payload = (() => {
20311
- const withProgress = walkProgressForUpload ? { ...body, progress: walkProgressForUpload } : body;
20364
+ const withProgress = walkProgressForUpload ? { ...body2, progress: walkProgressForUpload } : body2;
20312
20365
  const json = JSON.stringify(withProgress);
20313
20366
  const raw = Buffer.from(json, "utf8");
20314
20367
  return gzipBody ? gzipSync3(raw, { level: 6 }) : raw;
@@ -20332,25 +20385,25 @@ async function syncToTargetInScope(cred, opts = {}) {
20332
20385
  });
20333
20386
  if (res.ok) {
20334
20387
  acceptedUploads.set(cred.serverUrl, (acceptedUploads.get(cred.serverUrl) ?? 0) + 1);
20335
- const body2 = await res.json().catch(() => ({}));
20336
- if (typeof body2.telemetry === "boolean") {
20337
- setTelemetryEligible(base3, body2.telemetry);
20388
+ const body3 = await res.json().catch(() => ({}));
20389
+ if (typeof body3.telemetry === "boolean") {
20390
+ setTelemetryEligible(base3, body3.telemetry);
20338
20391
  try {
20339
20392
  const prior = readCollectorHealth()?.telemetryEligible ?? {};
20340
20393
  updateCollectorHealth({
20341
- telemetryEligible: { ...prior, [base3]: { allowed: body2.telemetry, at: Date.now() } }
20394
+ telemetryEligible: { ...prior, [base3]: { allowed: body3.telemetry, at: Date.now() } }
20342
20395
  });
20343
20396
  } catch {
20344
20397
  }
20345
20398
  }
20346
- const adv = body2.limits?.ingestConcurrencyPerTenant;
20399
+ const adv = body3.limits?.ingestConcurrencyPerTenant;
20347
20400
  if (typeof adv === "number" && Number.isFinite(adv) && adv >= 1) {
20348
20401
  setServerIngestConcurrency(base3, Math.floor(adv));
20349
20402
  }
20350
- if (body2.cli && body2.cli.version) {
20403
+ if (body3.cli && body3.cli.version) {
20351
20404
  const { planAutoUpdate: planAutoUpdate2, runAutoUpdate: runAutoUpdate2, sweepStaleStaging: sweepStaleStaging2 } = await Promise.resolve().then(() => (init_auto_update(), auto_update_exports));
20352
20405
  const authHeaders = cred.token ? { authorization: `Bearer ${cred.token}` } : {};
20353
- const plan = planAutoUpdate2(base3, { cli: body2.cli }, ownVersion, process.env.CHAT_RECALL_AUTO_UPDATE);
20406
+ const plan = planAutoUpdate2(base3, { cli: body3.cli }, ownVersion, process.env.CHAT_RECALL_AUTO_UPDATE);
20354
20407
  sweepStaleStaging2();
20355
20408
  if (plan.update) {
20356
20409
  void runAutoUpdate2(base3, authHeaders, ownVersion).catch(() => {
@@ -20367,13 +20420,13 @@ async function syncToTargetInScope(cred, opts = {}) {
20367
20420
  if (res.status === 402) {
20368
20421
  let detail = text;
20369
20422
  try {
20370
- const body2 = JSON.parse(text);
20371
- detail = body2.error ?? text;
20372
- if (body2.detail) detail += `
20373
- ${body2.detail}`;
20374
- if (body2.resetsAt) detail += ` (resets ${new Date(body2.resetsAt).toISOString().slice(0, 10)})`;
20375
- if (body2.upgradeUrl) detail += `
20376
- ${body2.upgradeUrl}`;
20423
+ const body3 = JSON.parse(text);
20424
+ detail = body3.error ?? text;
20425
+ if (body3.detail) detail += `
20426
+ ${body3.detail}`;
20427
+ if (body3.resetsAt) detail += ` (resets ${new Date(body3.resetsAt).toISOString().slice(0, 10)})`;
20428
+ if (body3.upgradeUrl) detail += `
20429
+ ${body3.upgradeUrl}`;
20377
20430
  } catch {
20378
20431
  }
20379
20432
  throw classedError("payment_required", `sync paused by the server: ${detail}`);
@@ -20402,7 +20455,7 @@ async function syncToTargetInScope(cred, opts = {}) {
20402
20455
  let poolError = null;
20403
20456
  const MAX_INFLIGHT_BYTES = (Number(process.env.CHAT_RECALL_MAX_INFLIGHT_MB) || 32) * 1024 * 1024;
20404
20457
  let inflightBytes = 0;
20405
- const submit = async (body, after, bytesHint = 0) => {
20458
+ const submit = async (body2, after, bytesHint = 0) => {
20406
20459
  while (inflight.size > 0 && (inflight.size >= maxInflight || inflightBytes + bytesHint > MAX_INFLIGHT_BYTES)) {
20407
20460
  await Promise.race(inflight);
20408
20461
  }
@@ -20410,7 +20463,7 @@ async function syncToTargetInScope(cred, opts = {}) {
20410
20463
  inflightBytes += bytesHint;
20411
20464
  let task;
20412
20465
  task = (async () => {
20413
- await post(body);
20466
+ await post(body2);
20414
20467
  after();
20415
20468
  })().catch((e) => {
20416
20469
  poolError = poolError ?? e;
@@ -20477,18 +20530,18 @@ async function syncToTargetInScope(cred, opts = {}) {
20477
20530
  signal: ac.signal
20478
20531
  });
20479
20532
  if (!res.ok) throw new Error(`append sync failed: HTTP ${res.status} ${await res.text().catch(() => "")}`);
20480
- const body = await res.json().catch(() => ({}));
20481
- if (body.cli && body.cli.version) {
20533
+ const body2 = await res.json().catch(() => ({}));
20534
+ if (body2.cli && body2.cli.version) {
20482
20535
  const { planAutoUpdate: planAutoUpdate2, runAutoUpdate: runAutoUpdate2, sweepStaleStaging: sweepStaleStaging2 } = await Promise.resolve().then(() => (init_auto_update(), auto_update_exports));
20483
20536
  const authHeaders = cred.token ? { authorization: `Bearer ${cred.token}` } : {};
20484
- const plan = planAutoUpdate2(base3, { cli: body.cli }, ownVersion, process.env.CHAT_RECALL_AUTO_UPDATE);
20537
+ const plan = planAutoUpdate2(base3, { cli: body2.cli }, ownVersion, process.env.CHAT_RECALL_AUTO_UPDATE);
20485
20538
  sweepStaleStaging2();
20486
20539
  if (plan.update) {
20487
20540
  void runAutoUpdate2(base3, authHeaders, ownVersion).catch(() => {
20488
20541
  });
20489
20542
  }
20490
20543
  }
20491
- const fullNeeded = new Set(body.full_resync_needed ?? []);
20544
+ const fullNeeded = new Set(body2.full_resync_needed ?? []);
20492
20545
  const acked = convs.filter((c) => !fullNeeded.has(c.session_id));
20493
20546
  if (acked.length > 0) {
20494
20547
  try {
@@ -20523,9 +20576,9 @@ async function syncToTargetInScope(cred, opts = {}) {
20523
20576
  signal: ac.signal
20524
20577
  });
20525
20578
  if (!res.ok) throw new Error(`chunked head sync failed: HTTP ${res.status} ${await res.text().catch(() => "")}`);
20526
- const body = await res.json().catch(() => ({}));
20579
+ const body2 = await res.json().catch(() => ({}));
20527
20580
  const id = conv.session_id;
20528
- const guarded = (body.shrink_guarded ?? []).find((g) => g.session_id === id);
20581
+ const guarded = (body2.shrink_guarded ?? []).find((g) => g.session_id === id);
20529
20582
  const mtime = conv.mtime;
20530
20583
  try {
20531
20584
  if (!guarded) {
@@ -21402,7 +21455,7 @@ var init_sync_client = __esm({
21402
21455
  ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
21403
21456
  } catch {
21404
21457
  try {
21405
- if (true) ownVersion = "0.7.7";
21458
+ if (true) ownVersion = "0.7.8";
21406
21459
  } catch {
21407
21460
  }
21408
21461
  }
@@ -21481,8 +21534,8 @@ async function fetchNpmLatest() {
21481
21534
  headers: { accept: "application/vnd.npm.install-v1+json" }
21482
21535
  }, 5e3);
21483
21536
  if (!res.ok) return null;
21484
- const body = await res.json();
21485
- const v = body["dist-tags"]?.latest;
21537
+ const body2 = await res.json();
21538
+ const v = body2["dist-tags"]?.latest;
21486
21539
  return typeof v === "string" && v ? v : null;
21487
21540
  } catch {
21488
21541
  return null;
@@ -21664,9 +21717,9 @@ function envHome(varName, fallback) {
21664
21717
  const v = process.env[varName];
21665
21718
  return v && v.trim() ? v.trim() : fallback;
21666
21719
  }
21667
- function writeFileMkdir(path, body) {
21720
+ function writeFileMkdir(path, body2) {
21668
21721
  mkdirSync12(dirname21(path), { recursive: true });
21669
- writeFileSync12(path, body);
21722
+ writeFileSync12(path, body2);
21670
21723
  }
21671
21724
  function readJsonObject(path) {
21672
21725
  const raw = readFileSync37(path, "utf-8");
@@ -21748,8 +21801,8 @@ function registerCodexToml(path, spec) {
21748
21801
  const lines = prev.length ? prev.split("\n") : [];
21749
21802
  const start = lines.findIndex((l) => l.trim() === CODEX_HEADER);
21750
21803
  if (start === -1) {
21751
- const body = prev.length ? prev.replace(/\n*$/, "\n") + "\n" + block : block;
21752
- writeFileMkdir(path, body);
21804
+ const body2 = prev.length ? prev.replace(/\n*$/, "\n") + "\n" + block : block;
21805
+ writeFileMkdir(path, body2);
21753
21806
  return { id, label, path, state: "created" };
21754
21807
  }
21755
21808
  let end = lines.length;
@@ -22290,8 +22343,8 @@ function parseCommandText(content, format, fallbackName) {
22290
22343
  const t = parseScalarToml(content);
22291
22344
  return { name: t.name || fallbackName, description: t.description || "", body: t.prompt || "" };
22292
22345
  }
22293
- const { fm, body } = parseFrontmatter4(content);
22294
- return { name: fm.name || fallbackName, description: fm.description || "", body: body.trim() };
22346
+ const { fm, body: body2 } = parseFrontmatter4(content);
22347
+ return { name: fm.name || fallbackName, description: fm.description || "", body: body2.trim() };
22295
22348
  }
22296
22349
  function parseAgentText(content, format, fallbackName) {
22297
22350
  if (format === "toml") {
@@ -22302,8 +22355,8 @@ function parseAgentText(content, format, fallbackName) {
22302
22355
  body: t.developer_instructions || t.instructions || ""
22303
22356
  };
22304
22357
  }
22305
- const { fm, body } = parseFrontmatter4(content);
22306
- return { name: fm.name || fallbackName, description: fm.description || "", tools: fm.tools, body: body.trim() };
22358
+ const { fm, body: body2 } = parseFrontmatter4(content);
22359
+ return { name: fm.name || fallbackName, description: fm.description || "", tools: fm.tools, body: body2.trim() };
22307
22360
  }
22308
22361
  function readCommand(filePath, format) {
22309
22362
  return parseCommandText(readFileSync40(filePath, "utf-8"), format, base(filePath));
@@ -22960,8 +23013,8 @@ function planPull(rows, opts = {}) {
22960
23013
  continue;
22961
23014
  const extra2 = parseExtra(row);
22962
23015
  const name2 = extra2.skillName || row.title;
22963
- const body = extra2.body;
22964
- if (!name2 || typeof body !== "string" || !body.trim()) {
23016
+ const body2 = extra2.body;
23017
+ if (!name2 || typeof body2 !== "string" || !body2.trim()) {
22965
23018
  seenUnsupported.set("skill", (seenUnsupported.get("skill") || 0) + 1);
22966
23019
  continue;
22967
23020
  }
@@ -22970,7 +23023,7 @@ function planPull(rows, opts = {}) {
22970
23023
  const prev2 = skillsByName.get(name2);
22971
23024
  if (!prev2 || rank >= 0 && (prev2.rank < 0 || rank < prev2.rank)) {
22972
23025
  skillsByName.set(name2, {
22973
- body,
23026
+ body: body2,
22974
23027
  rank,
22975
23028
  truncated: extra2.bodyTruncated === true,
22976
23029
  redacted: extra2.bodySecretsRedacted === true
@@ -22983,8 +23036,8 @@ function planPull(rows, opts = {}) {
22983
23036
  continue;
22984
23037
  const extra2 = parseExtra(row);
22985
23038
  const name2 = extra2[type === "agent" ? "agentName" : "commandName"] || row.title;
22986
- const body = extra2.body;
22987
- if (!name2 || typeof body !== "string" || !body.trim() || extra2.bodyTruncated === true) {
23039
+ const body2 = extra2.body;
23040
+ if (!name2 || typeof body2 !== "string" || !body2.trim() || extra2.bodyTruncated === true) {
22988
23041
  seenUnsupported.set(type, (seenUnsupported.get(type) || 0) + 1);
22989
23042
  continue;
22990
23043
  }
@@ -22994,7 +23047,7 @@ function planPull(rows, opts = {}) {
22994
23047
  const prev2 = bucket.get(name2);
22995
23048
  if (!prev2 || rank >= 0 && (prev2.rank < 0 || rank < prev2.rank)) {
22996
23049
  bucket.set(name2, {
22997
- body,
23050
+ body: body2,
22998
23051
  rank,
22999
23052
  format: extra2.format === "toml" ? "toml" : "md",
23000
23053
  redacted: extra2.bodySecretsRedacted === true
@@ -23063,7 +23116,7 @@ function executePull(rows, opts = {}) {
23063
23116
  const explicit = new Set(opts.explicit ?? []);
23064
23117
  const { mcps, skills, codecs, unsupported } = planPull(rows, opts);
23065
23118
  const outcomes = [];
23066
- for (const { name, body, truncated, redacted, tools } of skills) {
23119
+ for (const { name, body: body2, truncated, redacted, tools } of skills) {
23067
23120
  for (const tool of tools) {
23068
23121
  const dir = join51(skillsDirFor(tool), name);
23069
23122
  const file = join51(dir, "SKILL.md");
@@ -23081,17 +23134,17 @@ function executePull(rows, opts = {}) {
23081
23134
  }
23082
23135
  try {
23083
23136
  mkdirSync16(dir, { recursive: true });
23084
- writeFileSync16(file, body);
23137
+ writeFileSync16(file, body2);
23085
23138
  outcomes.push({ type: "skill", name, tool, status: "written", path: file, redactedContent: redacted });
23086
23139
  } catch (e) {
23087
23140
  outcomes.push({ type: "skill", name, tool, status: "failed", reason: e instanceof Error ? e.message : "write failed" });
23088
23141
  }
23089
23142
  }
23090
23143
  }
23091
- for (const { type, name, body, format, redacted, tools } of codecs) {
23144
+ for (const { type, name, body: body2, format, redacted, tools } of codecs) {
23092
23145
  let art;
23093
23146
  try {
23094
- art = type === "agent" ? parseAgentText(body, format, name) : parseCommandText(body, format, name);
23147
+ art = type === "agent" ? parseAgentText(body2, format, name) : parseCommandText(body2, format, name);
23095
23148
  } catch (e) {
23096
23149
  for (const tool of tools) {
23097
23150
  outcomes.push({ type, name, tool, status: "failed", reason: `could not parse the stored body: ${e instanceof Error ? e.message : "failed"}` });
@@ -24370,11 +24423,11 @@ async function collectCode(opts) {
24370
24423
  for (const block of log22.split("\0END\0")) {
24371
24424
  if (!block.includes("\0"))
24372
24425
  continue;
24373
- const [h, body] = [block.slice(0, block.indexOf("\0")).trim(), block.slice(block.indexOf("\0") + 1)];
24426
+ const [h, body2] = [block.slice(0, block.indexOf("\0")).trim(), block.slice(block.indexOf("\0") + 1)];
24374
24427
  if (!h)
24375
24428
  continue;
24376
24429
  totalCommits++;
24377
- if (AI_RE.test(body)) {
24430
+ if (AI_RE.test(body2)) {
24378
24431
  aiCommits++;
24379
24432
  try {
24380
24433
  const files2 = execSync4(`git -C "${ws}" show --format= --name-only ${h}`, { encoding: "utf8", timeout: 2e4, maxBuffer: 64 * 1024 * 1024, stdio: ["ignore", "pipe", "ignore"] });
@@ -25417,8 +25470,8 @@ async function runPull(base3, opts) {
25417
25470
  try {
25418
25471
  const res = await fetchWithTimeout(`${base3}/api/toolkit/browse/${type}?limit=1000`, { headers });
25419
25472
  if (!res.ok) continue;
25420
- const body = await res.json();
25421
- for (const it of body.items || []) rows.push(it);
25473
+ const body2 = await res.json();
25474
+ for (const it of body2.items || []) rows.push(it);
25422
25475
  } catch {
25423
25476
  }
25424
25477
  }
@@ -25563,7 +25616,7 @@ var init_intent_drain = __esm({
25563
25616
  ownVersion2 = JSON.parse(readFileSync45(join56(dir, "../package.json"), "utf-8")).version || ownVersion2;
25564
25617
  } catch {
25565
25618
  try {
25566
- if (true) ownVersion2 = "0.7.7";
25619
+ if (true) ownVersion2 = "0.7.8";
25567
25620
  } catch {
25568
25621
  }
25569
25622
  }
@@ -25604,7 +25657,7 @@ function context(opts = {}) {
25604
25657
  throw new TeamConfigError("Not joined to a team. Run `chat-recall team join <invite-token>`.");
25605
25658
  return { serverUrl: t.serverUrl, token, handle: t.memberHandle ?? "", teamId: t.teamId };
25606
25659
  }
25607
- async function http(ctx, method, path, body) {
25660
+ async function http(ctx, method, path, body2) {
25608
25661
  const url = ctx.serverUrl.replace(/\/+$/, "") + path;
25609
25662
  const r = await fetch(url, {
25610
25663
  method,
@@ -25613,7 +25666,7 @@ async function http(ctx, method, path, body) {
25613
25666
  "Content-Type": "application/json",
25614
25667
  "Accept": "application/json"
25615
25668
  },
25616
- body: body == null ? void 0 : JSON.stringify(body)
25669
+ body: body2 == null ? void 0 : JSON.stringify(body2)
25617
25670
  });
25618
25671
  const text = await r.text();
25619
25672
  let parsed = void 0;
@@ -25750,10 +25803,10 @@ var init_team_client = __esm({
25750
25803
  TeamHttpError = class extends Error {
25751
25804
  status;
25752
25805
  body;
25753
- constructor(msg, status, body) {
25806
+ constructor(msg, status, body2) {
25754
25807
  super(msg);
25755
25808
  this.status = status;
25756
- this.body = body;
25809
+ this.body = body2;
25757
25810
  }
25758
25811
  };
25759
25812
  }
@@ -25846,8 +25899,8 @@ async function mergePullResult(opts) {
25846
25899
  report.skipped.push({ artifactId: a.id, path: "(no installed target tool)", reason: "no-target-tool" });
25847
25900
  continue;
25848
25901
  }
25849
- const body = Buffer.from(a.bodyB64, "base64");
25850
- const sha = createHash14("sha256").update(body).digest("hex");
25902
+ const body2 = Buffer.from(a.bodyB64, "base64");
25903
+ const sha = createHash14("sha256").update(body2).digest("hex");
25851
25904
  for (const tool of targets) {
25852
25905
  const path = installPathFor(a, tool);
25853
25906
  if (!path)
@@ -25860,7 +25913,7 @@ async function mergePullResult(opts) {
25860
25913
  continue;
25861
25914
  }
25862
25915
  mkdirSync20(dirname27(path), { recursive: true });
25863
- writeFileSync20(path, body);
25916
+ writeFileSync20(path, body2);
25864
25917
  pending.push({ artifactId: a.id, tool, artifactType: a.type, artifactName: a.name, sha256: sha, installedAt: Date.now() });
25865
25918
  report.written.push({ artifactId: a.id, path });
25866
25919
  } catch (err) {
@@ -26166,7 +26219,7 @@ function context2() {
26166
26219
  throw new VaultConfigError(`Env var ${s.tokenRef} is not set.`);
26167
26220
  return { serverUrl: s.serverUrl, teamId: s.teamId, token };
26168
26221
  }
26169
- async function api(ctx, method, path, body) {
26222
+ async function api(ctx, method, path, body2) {
26170
26223
  const doFetch = () => fetch(ctx.serverUrl.replace(/\/+$/, "") + path, {
26171
26224
  method,
26172
26225
  headers: {
@@ -26174,7 +26227,7 @@ async function api(ctx, method, path, body) {
26174
26227
  "Content-Type": "application/json",
26175
26228
  "Accept": "application/json"
26176
26229
  },
26177
- body: body == null ? void 0 : JSON.stringify(body)
26230
+ body: body2 == null ? void 0 : JSON.stringify(body2)
26178
26231
  });
26179
26232
  let r;
26180
26233
  try {
@@ -26253,13 +26306,13 @@ async function vaultEnableWithRemote(passphrase, remote, opts = {}) {
26253
26306
  body: JSON.stringify({ saltHex: result.saltHex, keyId: result.keyId })
26254
26307
  });
26255
26308
  if (r.status === 409) {
26256
- const body = await r.json();
26257
- if (body.saltHex && body.saltHex !== result.saltHex) {
26258
- const redone = vaultEnable(passphrase, { existingSaltHex: body.saltHex });
26259
- if (body.keyId && body.keyId !== redone.keyId) {
26309
+ const body2 = await r.json();
26310
+ if (body2.saltHex && body2.saltHex !== result.saltHex) {
26311
+ const redone = vaultEnable(passphrase, { existingSaltHex: body2.saltHex });
26312
+ if (body2.keyId && body2.keyId !== redone.keyId) {
26260
26313
  throw new VaultPassphraseMismatchError("Another device published a vault with a different passphrase. Nothing was changed here.");
26261
26314
  }
26262
- return { ...redone, saltSource: "server", keyIdMatches: body.keyId ? true : void 0 };
26315
+ return { ...redone, saltSource: "server", keyIdMatches: body2.keyId ? true : void 0 };
26263
26316
  }
26264
26317
  }
26265
26318
  } catch (err) {
@@ -26421,10 +26474,10 @@ var init_vault_client = __esm({
26421
26474
  VaultHttpError = class extends Error {
26422
26475
  status;
26423
26476
  body;
26424
- constructor(msg, status, body) {
26477
+ constructor(msg, status, body2) {
26425
26478
  super(msg);
26426
26479
  this.status = status;
26427
- this.body = body;
26480
+ this.body = body2;
26428
26481
  }
26429
26482
  };
26430
26483
  uploadKey = (sessionId, tool) => `${sessionId}\0${tool}`;
@@ -27321,15 +27374,15 @@ async function deviceLogin(opts, onPrompt) {
27321
27374
  code_verifier: codeVerifier
27322
27375
  })
27323
27376
  });
27324
- const body = await res.json().catch(() => ({}));
27325
- if (res.ok && typeof body.access_token === "string") {
27377
+ const body2 = await res.json().catch(() => ({}));
27378
+ if (res.ok && typeof body2.access_token === "string") {
27326
27379
  return {
27327
- accessToken: body.access_token,
27328
- refreshToken: typeof body.refresh_token === "string" ? body.refresh_token : void 0,
27329
- expiresIn: typeof body.expires_in === "number" ? body.expires_in : 0
27380
+ accessToken: body2.access_token,
27381
+ refreshToken: typeof body2.refresh_token === "string" ? body2.refresh_token : void 0,
27382
+ expiresIn: typeof body2.expires_in === "number" ? body2.expires_in : 0
27330
27383
  };
27331
27384
  }
27332
- const err = body.error;
27385
+ const err = body2.error;
27333
27386
  if (err === "authorization_pending") continue;
27334
27387
  if (err === "slow_down") {
27335
27388
  interval += 5e3;
@@ -27369,14 +27422,14 @@ async function betterAuthDeviceLogin(serverUrl, onPrompt) {
27369
27422
  client_id: BETTER_AUTH_CLI_CLIENT_ID
27370
27423
  })
27371
27424
  });
27372
- const body = await res.json().catch(() => ({}));
27373
- if (res.ok && typeof body.access_token === "string") {
27425
+ const body2 = await res.json().catch(() => ({}));
27426
+ if (res.ok && typeof body2.access_token === "string") {
27374
27427
  return {
27375
- accessToken: body.access_token,
27376
- expiresIn: typeof body.expires_in === "number" ? body.expires_in : 0
27428
+ accessToken: body2.access_token,
27429
+ expiresIn: typeof body2.expires_in === "number" ? body2.expires_in : 0
27377
27430
  };
27378
27431
  }
27379
- const err = body.error;
27432
+ const err = body2.error;
27380
27433
  if (err === "authorization_pending") continue;
27381
27434
  if (err === "slow_down") {
27382
27435
  interval += 5e3;
@@ -27466,8 +27519,8 @@ async function selectSessions(target, opts, fetchImpl = fetch) {
27466
27519
  headers: { authorization: `Bearer ${target.token}` }
27467
27520
  });
27468
27521
  if (!res.ok) throw new Error(`list failed: HTTP ${res.status}`);
27469
- const body = await res.json();
27470
- const page = body.sessions ?? [];
27522
+ const body2 = await res.json();
27523
+ const page = body2.sessions ?? [];
27471
27524
  if (page.length === 0) break;
27472
27525
  for (const row of page) {
27473
27526
  if (!row.sessionId) continue;
@@ -27550,9 +27603,9 @@ async function restoreSessions(ids, opts = {}) {
27550
27603
  body: JSON.stringify({ session_ids: unique.slice(i, i + BATCH) })
27551
27604
  });
27552
27605
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
27553
- const body = await res.json();
27554
- restored += body.restored ?? 0;
27555
- notDeleted += (body.notDeleted ?? []).length;
27606
+ const body2 = await res.json();
27607
+ restored += body2.restored ?? 0;
27608
+ notDeleted += (body2.notDeleted ?? []).length;
27556
27609
  }
27557
27610
  out.perTarget[t.serverUrl] = { restored, notDeleted };
27558
27611
  best = Math.max(best, restored);
@@ -27618,6 +27671,104 @@ function resumeCommandFor(sessionId, tool) {
27618
27671
  }
27619
27672
  }
27620
27673
 
27674
+ // ../engine/dist/mcp/show-render.js
27675
+ var BODY_LIMIT = 2e3;
27676
+ var EDGE = 100;
27677
+ var INDENT = " ";
27678
+ var oneLine = (v) => String(v).replace(/\s*\n\s*/g, " \u23CE ");
27679
+ var indent = (text) => text.split("\n").map((l) => INDENT + l).join("\n");
27680
+ function safeSlice(s, start, end) {
27681
+ const lo = start > 0 && /[\uDC00-\uDFFF]/.test(s[start] ?? "") ? start - 1 : start;
27682
+ const hi = end < s.length && /[\uD800-\uDBFF]/.test(s[end - 1] ?? "") ? end + 1 : end;
27683
+ return s.slice(lo, hi);
27684
+ }
27685
+ function body(text, line, opts) {
27686
+ if (opts.full || text.length <= BODY_LIMIT)
27687
+ return indent(text);
27688
+ const lines = text.split("\n").length;
27689
+ const cut = text.length - 2 * EDGE;
27690
+ const how = opts.expandHint ? ` ${opts.expandHint(line)}` : "";
27691
+ return [
27692
+ indent(safeSlice(text, 0, EDGE)),
27693
+ `${INDENT}\u2026 ${cut} characters cut (${text.length} in all, ${lines} lines).${how} \u2026`,
27694
+ indent(safeSlice(text, text.length - EDGE, text.length))
27695
+ ].join("\n");
27696
+ }
27697
+ function resultText(result) {
27698
+ if (typeof result === "string")
27699
+ return result;
27700
+ if (Array.isArray(result)) {
27701
+ return result.map((b) => {
27702
+ if (b?.type === "text")
27703
+ return String(b.text ?? "");
27704
+ if (b?.type === "image")
27705
+ return "[image]";
27706
+ if (b?.type === "tool_reference")
27707
+ return `[tool_reference: ${b.tool_name ?? ""}]`;
27708
+ return JSON.stringify(b);
27709
+ }).join("\n");
27710
+ }
27711
+ return JSON.stringify(result);
27712
+ }
27713
+ function renderToolCall(tc, line, opts) {
27714
+ const inp = tc.input && typeof tc.input === "object" ? tc.input : {};
27715
+ const out = [];
27716
+ if (tc.name === "Bash" && inp.command !== void 0) {
27717
+ const desc = inp.description ? ` # ${oneLine(inp.description)}` : "";
27718
+ out.push(`[Bash]${desc}
27719
+ $ ${oneLine(inp.command)}`);
27720
+ } else if (inp.file_path !== void 0) {
27721
+ const inline = {};
27722
+ const blocks = [];
27723
+ for (const [k, v] of Object.entries(inp)) {
27724
+ if (k === "file_path")
27725
+ continue;
27726
+ if (typeof v === "string" && (v.includes("\n") || v.length > 120))
27727
+ blocks.push([k, v]);
27728
+ else
27729
+ inline[k] = v;
27730
+ }
27731
+ const opts_ = Object.keys(inline).length ? ` ${JSON.stringify(inline)}` : "";
27732
+ out.push(`[${tc.name}] ${inp.file_path}${opts_}`);
27733
+ for (const [k, v] of blocks)
27734
+ out.push(` ${k}:`, body(v, line, opts));
27735
+ } else if (typeof tc.input === "string") {
27736
+ out.push(`[${tc.name}]`, body(tc.input, line, opts));
27737
+ } else {
27738
+ const json = JSON.stringify(tc.input ?? {});
27739
+ if (opts.full || json.length <= BODY_LIMIT)
27740
+ out.push(`[${tc.name}] ${oneLine(json)}`);
27741
+ else
27742
+ out.push(`[${tc.name}]`, body(json, line, opts));
27743
+ }
27744
+ if (tc.result !== void 0) {
27745
+ out.push(tc.isError ? " \u2192 error:" : " \u2192 result:", body(resultText(tc.result), line, opts));
27746
+ }
27747
+ return out.join("\n");
27748
+ }
27749
+ function renderShowMessages(messages, opts = {}) {
27750
+ const out = [];
27751
+ for (const msg of messages) {
27752
+ const text = msg.content ?? "";
27753
+ const thinking = msg.thinking ?? "";
27754
+ const calls = msg.toolCalls ?? [];
27755
+ if (!text.trim() && !thinking.trim() && !calls.length && msg.thinking !== void 0)
27756
+ continue;
27757
+ out.push(`**${msg.role}** (line ${msg.line})`);
27758
+ if (thinking.trim())
27759
+ out.push(`_(thinking)_
27760
+ ${thinking}`);
27761
+ if (text.trim())
27762
+ out.push(text);
27763
+ for (const tc of calls)
27764
+ out.push(renderToolCall(tc, msg.line, opts));
27765
+ if (!text.trim() && !thinking.trim() && !calls.length)
27766
+ out.push("_(empty)_");
27767
+ out.push("");
27768
+ }
27769
+ return out;
27770
+ }
27771
+
27621
27772
  // src/cli.ts
27622
27773
  init_paths();
27623
27774
  init_claude2();
@@ -27850,38 +28001,38 @@ async function serverGetSoft(path) {
27850
28001
  const t = requireTarget();
27851
28002
  const res = await fetch(t.base + path, { headers: t.token ? { authorization: `Bearer ${t.token}` } : {} });
27852
28003
  if (res.status === 202 || res.status === 404) {
27853
- const body = await res.json().catch(() => ({}));
27854
- return { status: res.status, data: null, message: body.message };
28004
+ const body2 = await res.json().catch(() => ({}));
28005
+ return { status: res.status, data: null, message: body2.message };
27855
28006
  }
27856
28007
  if (!res.ok) throw new Error(`server ${path}: HTTP ${res.status} ${await res.text().catch(() => "")}`);
27857
28008
  return { status: res.status, data: await readJsonBody(res, t.base, `GET ${path}`) };
27858
28009
  }
27859
- async function serverPost(path, body) {
28010
+ async function serverPost(path, body2) {
27860
28011
  const t = requireTarget();
27861
28012
  const res = await fetch(t.base + path, {
27862
28013
  method: "POST",
27863
28014
  headers: t.token ? { "content-type": "application/json", authorization: `Bearer ${t.token}` } : { "content-type": "application/json" },
27864
- body: JSON.stringify(body)
28015
+ body: JSON.stringify(body2)
27865
28016
  });
27866
28017
  if (!res.ok) throw new Error(`server ${path}: HTTP ${res.status} ${await res.text().catch(() => "")}`);
27867
28018
  return readJsonBody(res, t.base, `POST ${path}`);
27868
28019
  }
27869
- async function serverPatch(path, body) {
28020
+ async function serverPatch(path, body2) {
27870
28021
  const t = requireTarget();
27871
28022
  const res = await fetch(t.base + path, {
27872
28023
  method: "PATCH",
27873
28024
  headers: t.token ? { "content-type": "application/json", authorization: `Bearer ${t.token}` } : { "content-type": "application/json" },
27874
- body: JSON.stringify(body)
28025
+ body: JSON.stringify(body2)
27875
28026
  });
27876
28027
  if (!res.ok) throw new Error(`server ${path}: HTTP ${res.status} ${await res.text().catch(() => "")}`);
27877
28028
  return readJsonBody(res, t.base, `PATCH ${path}`);
27878
28029
  }
27879
- async function serverDelete(path, body) {
28030
+ async function serverDelete(path, body2) {
27880
28031
  const t = requireTarget();
27881
28032
  const res = await fetch(t.base + path, {
27882
28033
  method: "DELETE",
27883
28034
  headers: t.token ? { "content-type": "application/json", authorization: `Bearer ${t.token}` } : { "content-type": "application/json" },
27884
- body: JSON.stringify(body)
28035
+ body: JSON.stringify(body2)
27885
28036
  });
27886
28037
  if (!res.ok) throw new Error(`server ${path}: HTTP ${res.status} ${await res.text().catch(() => "")}`);
27887
28038
  return readJsonBody(res, t.base, `DELETE ${path}`);
@@ -28168,15 +28319,15 @@ program.command("init").description("Set up chat-recall: connect to your server,
28168
28319
  continue;
28169
28320
  }
28170
28321
  const text = await res.text();
28171
- let body;
28322
+ let body2;
28172
28323
  try {
28173
- body = JSON.parse(text);
28324
+ body2 = JSON.parse(text);
28174
28325
  } catch {
28175
28326
  askFailed.push(`${t.serverUrl} (not JSON: ${JSON.stringify(text.trim().slice(0, 40))})`);
28176
28327
  continue;
28177
28328
  }
28178
28329
  answered++;
28179
- for (const it of body.items || []) rows.push(it);
28330
+ for (const it of body2.items || []) rows.push(it);
28180
28331
  } catch (e) {
28181
28332
  askFailed.push(`${t.serverUrl} (${describeProbeError(e)})`);
28182
28333
  }
@@ -28425,7 +28576,7 @@ program.command("optimize").description("Deprecated: storage is server-side now,
28425
28576
  console.log(chalk2.dim("Run `chat-recall sync` to ship sessions; the server manages its own storage."));
28426
28577
  process.exit(0);
28427
28578
  });
28428
- program.command("show <session_id>").description("Show conversation content from a session (requires login)").option("-m, --messages <number>", "Number of messages to show", "10").option("-f, --full", "Show full conversation (all messages)", false).action(async (sessionId, options) => {
28579
+ program.command("show <session_id>").description("Show conversation content from a session (requires login)").option("-m, --messages <number>", "Number of messages to show", "10").option("-f, --full", "Show full conversation (all messages)", false).option("-l, --line <number>", "Show only the message at this line, with every tool input and result whole").action(async (sessionId, options) => {
28429
28580
  try {
28430
28581
  const soft = await serverGetSoft(`/api/conversations/${encodeURIComponent(sessionId)}?limit=0`);
28431
28582
  if (!soft.data || soft.data.messages.length === 0) {
@@ -28435,20 +28586,21 @@ program.command("show <session_id>").description("Show conversation content from
28435
28586
  const messagesList = soft.data.messages;
28436
28587
  console.log(chalk2.bold("Session:"), sessionId);
28437
28588
  console.log();
28438
- const maxMessages = parseInt(options.messages, 10);
28439
- const displayMessages = options.full ? messagesList : messagesList.slice(0, maxMessages);
28440
- for (const msg of displayMessages) {
28441
- const text = msg.content;
28442
- if (msg.role === "user") {
28443
- console.log(`${chalk2.bold.blue("User")} ${chalk2.dim(`(line ${msg.line})`)}`);
28444
- } else if (msg.role === "assistant") {
28445
- console.log(`${chalk2.bold.green("Assistant")} ${chalk2.dim(`(line ${msg.line})`)}`);
28446
- } else {
28447
- console.log(chalk2.bold.yellow(msg.role));
28589
+ if (options.line !== void 0) {
28590
+ const line = parseInt(options.line, 10);
28591
+ const hit = messagesList.find((m) => m.line === line);
28592
+ if (!hit) {
28593
+ const lines = messagesList.map((m) => m.line);
28594
+ console.log(chalk2.yellow(`No message at line ${options.line}. Its lines run from ${Math.min(...lines)} to ${Math.max(...lines)}.`));
28595
+ process.exit(1);
28448
28596
  }
28449
- console.log(text);
28450
- console.log();
28597
+ console.log(renderShowMessages([hit], { full: true }).join("\n"));
28598
+ return;
28451
28599
  }
28600
+ const maxMessages = parseInt(options.messages, 10);
28601
+ const displayMessages = options.full ? messagesList : messagesList.slice(0, maxMessages);
28602
+ const expandHint = (line) => `Run chat-recall show ${sessionId} --line ${line} for the whole text.`;
28603
+ console.log(renderShowMessages(displayMessages, { expandHint }).join("\n"));
28452
28604
  console.log(chalk2.dim(`Showing ${displayMessages.length} of ${messagesList.length} messages. Use --full for the complete conversation.`));
28453
28605
  {
28454
28606
  const rc = resumeCommandFor(sessionId);
@@ -28661,8 +28813,8 @@ program.command("feedback").argument("<message...>", "what you want to say \u201
28661
28813
  signal: AbortSignal.timeout(1e4)
28662
28814
  });
28663
28815
  if (!res.ok) {
28664
- const body = await res.json().catch(() => ({}));
28665
- console.error(chalk2.red(`Could not send: ${body.error || res.status}`));
28816
+ const body2 = await res.json().catch(() => ({}));
28817
+ console.error(chalk2.red(`Could not send: ${body2.error || res.status}`));
28666
28818
  process.exitCode = 1;
28667
28819
  return;
28668
28820
  }
@@ -29079,8 +29231,8 @@ program.command("verify").description("Check that the server holds everything th
29079
29231
  if (token) headers.authorization = `Bearer ${token}`;
29080
29232
  const res = await fetchWithTimeout2(`${server}/api/status/archives`, { headers }, 12e4);
29081
29233
  if (!res.ok) throw new Error(`${server}: HTTP ${res.status} from /api/status/archives`);
29082
- const body = await res.json();
29083
- return new Map((body.archives || []).map((a) => [a.id, Number(a.size) || 0]));
29234
+ const body2 = await res.json();
29235
+ return new Map((body2.archives || []).map((a) => [a.id, Number(a.size) || 0]));
29084
29236
  }
29085
29237
  };
29086
29238
  let exitCode = 0;
@@ -29132,8 +29284,8 @@ ${t.serverUrl}`));
29132
29284
  console.log(` ${f.sessionId.slice(0, 8)} server records unavailable (HTTP ${res.status})`);
29133
29285
  continue;
29134
29286
  }
29135
- const body = await res.json();
29136
- serverIds = new Set(body.records || []);
29287
+ const body2 = await res.json();
29288
+ serverIds = new Set(body2.records || []);
29137
29289
  } catch (e) {
29138
29290
  console.log(` ${f.sessionId.slice(0, 8)} record fetch failed: ${e instanceof Error ? e.message : e}`);
29139
29291
  continue;
@@ -29453,8 +29605,8 @@ toolkit.command("pull").description("Install artifacts this device is missing, f
29453
29605
  headers: t.token ? { authorization: `Bearer ${t.token}` } : {}
29454
29606
  });
29455
29607
  if (!res.ok) continue;
29456
- const body = await res.json();
29457
- for (const it of body.items || []) rows.push(it);
29608
+ const body2 = await res.json();
29609
+ for (const it of body2.items || []) rows.push(it);
29458
29610
  } catch (err) {
29459
29611
  console.log(chalk2.dim(` (${t.serverUrl} ${type}: ${err instanceof Error ? err.message : err})`));
29460
29612
  }
@@ -29696,13 +29848,13 @@ team.command("publish <type> <name> <file>").description("Publish a local file a
29696
29848
  process.exit(1);
29697
29849
  }
29698
29850
  const { readFileSync: readFileSync50 } = await import("fs");
29699
- const body = readFileSync50(file);
29851
+ const body2 = readFileSync50(file);
29700
29852
  const { teamPublish: teamPublish2 } = await Promise.resolve().then(() => (init_team_client(), team_client_exports));
29701
29853
  const a = await teamPublish2({
29702
29854
  type,
29703
29855
  tool: opts.tool,
29704
29856
  name,
29705
- body,
29857
+ body: body2,
29706
29858
  pinnedTo: opts.pinnedTo
29707
29859
  });
29708
29860
  console.log(chalk2.green(`\u2713 Published ${chalk2.bold(type + "/" + name)} v${a.version}`));
@@ -29995,13 +30147,13 @@ program.command("task-hook").description("Move a board card when a prompt or a c
29995
30147
  4e3
29996
30148
  );
29997
30149
  if (!res.ok) return null;
29998
- const body = await res.json().catch(() => ({}));
29999
- return body.task ?? null;
30150
+ const body2 = await res.json().catch(() => ({}));
30151
+ return body2.task ?? null;
30000
30152
  };
30001
- const patchCard = async (id, body) => {
30153
+ const patchCard = async (id, body2) => {
30002
30154
  const res = await fetchWithTimeout2(
30003
30155
  `${target.base}/api/tasks/${encodeURIComponent(id)}`,
30004
- { method: "PATCH", headers, body: JSON.stringify(body) },
30156
+ { method: "PATCH", headers, body: JSON.stringify(body2) },
30005
30157
  6e3
30006
30158
  );
30007
30159
  return res.ok;
@@ -30166,8 +30318,8 @@ program.command("install-hooks").description("Install Claude Code hooks (Stop +
30166
30318
  for (const target of reg.guardTargets()) {
30167
30319
  if (!existsSync58(target.configPath)) continue;
30168
30320
  if (target.tool === "opencode") {
30169
- const body = readFileSync50(target.configPath, "utf-8");
30170
- if (!body.includes("chat-recall install-hooks")) continue;
30321
+ const body2 = readFileSync50(target.configPath, "utf-8");
30322
+ if (!body2.includes("chat-recall install-hooks")) continue;
30171
30323
  unlinkSync4(target.configPath);
30172
30324
  removed += 1;
30173
30325
  } else {