chat-recall 0.7.21 → 0.7.24

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.js CHANGED
@@ -443,30 +443,30 @@ var require_caller = __commonJS({
443
443
  var require_redact = __commonJS({
444
444
  "../../node_modules/@pinojs/redact/index.js"(exports, module) {
445
445
  "use strict";
446
- function deepClone(obj) {
447
- if (obj === null || typeof obj !== "object") {
448
- return obj;
446
+ function deepClone(obj2) {
447
+ if (obj2 === null || typeof obj2 !== "object") {
448
+ return obj2;
449
449
  }
450
- if (obj instanceof Date) {
451
- return new Date(obj.getTime());
450
+ if (obj2 instanceof Date) {
451
+ return new Date(obj2.getTime());
452
452
  }
453
- if (obj instanceof Array) {
453
+ if (obj2 instanceof Array) {
454
454
  const cloned = [];
455
- for (let i = 0; i < obj.length; i++) {
456
- cloned[i] = deepClone(obj[i]);
455
+ for (let i = 0; i < obj2.length; i++) {
456
+ cloned[i] = deepClone(obj2[i]);
457
457
  }
458
458
  return cloned;
459
459
  }
460
- if (typeof obj === "object") {
461
- const cloned = Object.create(Object.getPrototypeOf(obj));
462
- for (const key2 in obj) {
463
- if (Object.prototype.hasOwnProperty.call(obj, key2)) {
464
- cloned[key2] = deepClone(obj[key2]);
460
+ if (typeof obj2 === "object") {
461
+ const cloned = Object.create(Object.getPrototypeOf(obj2));
462
+ for (const key2 in obj2) {
463
+ if (Object.prototype.hasOwnProperty.call(obj2, key2)) {
464
+ cloned[key2] = deepClone(obj2[key2]);
465
465
  }
466
466
  }
467
467
  return cloned;
468
468
  }
469
- return obj;
469
+ return obj2;
470
470
  }
471
471
  function parsePath(path2) {
472
472
  const parts = [];
@@ -511,8 +511,8 @@ var require_redact = __commonJS({
511
511
  }
512
512
  return parts;
513
513
  }
514
- function setValue(obj, parts, value) {
515
- let current = obj;
514
+ function setValue(obj2, parts, value) {
515
+ let current = obj2;
516
516
  for (let i = 0; i < parts.length - 1; i++) {
517
517
  const key2 = parts[i];
518
518
  if (typeof current !== "object" || current === null || !(key2 in current)) {
@@ -543,8 +543,8 @@ var require_redact = __commonJS({
543
543
  }
544
544
  return true;
545
545
  }
546
- function removeKey(obj, parts) {
547
- let current = obj;
546
+ function removeKey(obj2, parts) {
547
+ let current = obj2;
548
548
  for (let i = 0; i < parts.length - 1; i++) {
549
549
  const key2 = parts[i];
550
550
  if (typeof current !== "object" || current === null || !(key2 in current)) {
@@ -576,8 +576,8 @@ var require_redact = __commonJS({
576
576
  return true;
577
577
  }
578
578
  var PATH_NOT_FOUND = /* @__PURE__ */ Symbol("PATH_NOT_FOUND");
579
- function getValueIfExists(obj, parts) {
580
- let current = obj;
579
+ function getValueIfExists(obj2, parts) {
580
+ let current = obj2;
581
581
  for (const part of parts) {
582
582
  if (current === null || current === void 0) {
583
583
  return PATH_NOT_FOUND;
@@ -592,8 +592,8 @@ var require_redact = __commonJS({
592
592
  }
593
593
  return current;
594
594
  }
595
- function getValue(obj, parts) {
596
- let current = obj;
595
+ function getValue(obj2, parts) {
596
+ let current = obj2;
597
597
  for (const part of parts) {
598
598
  if (current === null || current === void 0) {
599
599
  return void 0;
@@ -605,30 +605,30 @@ var require_redact = __commonJS({
605
605
  }
606
606
  return current;
607
607
  }
608
- function redactPaths(obj, paths, censor, remove = false) {
608
+ function redactPaths(obj2, paths, censor, remove = false) {
609
609
  for (const path2 of paths) {
610
610
  const parts = parsePath(path2);
611
611
  if (parts.includes("*")) {
612
- redactWildcardPath(obj, parts, censor, path2, remove);
612
+ redactWildcardPath(obj2, parts, censor, path2, remove);
613
613
  } else {
614
614
  if (remove) {
615
- removeKey(obj, parts);
615
+ removeKey(obj2, parts);
616
616
  } else {
617
- const value = getValueIfExists(obj, parts);
617
+ const value = getValueIfExists(obj2, parts);
618
618
  if (value === PATH_NOT_FOUND) {
619
619
  continue;
620
620
  }
621
621
  const actualCensor = typeof censor === "function" ? censor(value, parts) : censor;
622
- setValue(obj, parts, actualCensor);
622
+ setValue(obj2, parts, actualCensor);
623
623
  }
624
624
  }
625
625
  }
626
626
  }
627
- function redactWildcardPath(obj, parts, censor, originalPath, remove = false) {
627
+ function redactWildcardPath(obj2, parts, censor, originalPath, remove = false) {
628
628
  const wildcardIndex = parts.indexOf("*");
629
629
  if (wildcardIndex === parts.length - 1) {
630
630
  const parentParts = parts.slice(0, -1);
631
- let current = obj;
631
+ let current = obj2;
632
632
  for (const part of parentParts) {
633
633
  if (current === null || current === void 0) return;
634
634
  if (typeof current !== "object" || current === null) return;
@@ -666,10 +666,10 @@ var require_redact = __commonJS({
666
666
  }
667
667
  }
668
668
  } else {
669
- redactIntermediateWildcard(obj, parts, censor, wildcardIndex, originalPath, remove);
669
+ redactIntermediateWildcard(obj2, parts, censor, wildcardIndex, originalPath, remove);
670
670
  }
671
671
  }
672
- function redactIntermediateWildcard(obj, parts, censor, wildcardIndex, originalPath, remove = false) {
672
+ function redactIntermediateWildcard(obj2, parts, censor, wildcardIndex, originalPath, remove = false) {
673
673
  const beforeWildcard = parts.slice(0, wildcardIndex);
674
674
  const afterWildcard = parts.slice(wildcardIndex + 1);
675
675
  const pathArray = [];
@@ -710,9 +710,9 @@ var require_redact = __commonJS({
710
710
  }
711
711
  }
712
712
  if (beforeWildcard.length === 0) {
713
- traverse(obj, 0);
713
+ traverse(obj2, 0);
714
714
  } else {
715
- let current = obj;
715
+ let current = obj2;
716
716
  for (let i = 0; i < beforeWildcard.length; i++) {
717
717
  const part = beforeWildcard[i];
718
718
  if (current === null || current === void 0) return;
@@ -743,9 +743,9 @@ var require_redact = __commonJS({
743
743
  }
744
744
  return pathStructure;
745
745
  }
746
- function selectiveClone(obj, pathStructure) {
746
+ function selectiveClone(obj2, pathStructure) {
747
747
  if (!pathStructure) {
748
- return obj;
748
+ return obj2;
749
749
  }
750
750
  function cloneSelectively(source, pathMap, depth = 0) {
751
751
  if (!pathMap || pathMap.size === 0) {
@@ -781,7 +781,7 @@ var require_redact = __commonJS({
781
781
  }
782
782
  return cloned;
783
783
  }
784
- return cloneSelectively(obj, pathStructure);
784
+ return cloneSelectively(obj2, pathStructure);
785
785
  }
786
786
  function validatePath(path2) {
787
787
  if (typeof path2 !== "string") {
@@ -840,17 +840,17 @@ var require_redact = __commonJS({
840
840
  } = options;
841
841
  validatePaths(paths);
842
842
  const pathStructure = buildPathStructure(paths);
843
- return function redact(obj) {
844
- if (strict && (obj === null || typeof obj !== "object")) {
845
- if (obj === null || obj === void 0) {
846
- return serialize ? serialize(obj) : obj;
843
+ return function redact(obj2) {
844
+ if (strict && (obj2 === null || typeof obj2 !== "object")) {
845
+ if (obj2 === null || obj2 === void 0) {
846
+ return serialize ? serialize(obj2) : obj2;
847
847
  }
848
- if (typeof obj !== "object") {
849
- return serialize ? serialize(obj) : obj;
848
+ if (typeof obj2 !== "object") {
849
+ return serialize ? serialize(obj2) : obj2;
850
850
  }
851
851
  }
852
- const cloned = selectiveClone(obj, pathStructure);
853
- const original = obj;
852
+ const cloned = selectiveClone(obj2, pathStructure);
853
+ const original = obj2;
854
854
  let actualCensor = censor;
855
855
  if (typeof censor === "function") {
856
856
  actualCensor = censor;
@@ -1838,10 +1838,10 @@ var require_on_exit_leak_free = __commonJS({
1838
1838
  }
1839
1839
  function callRefs(event) {
1840
1840
  for (const ref of refs[event]) {
1841
- const obj = ref.deref();
1841
+ const obj2 = ref.deref();
1842
1842
  const fn = ref.fn;
1843
- if (obj !== void 0) {
1844
- fn(obj, event);
1843
+ if (obj2 !== void 0) {
1844
+ fn(obj2, event);
1845
1845
  }
1846
1846
  }
1847
1847
  refs[event] = [];
@@ -1853,32 +1853,32 @@ var require_on_exit_leak_free = __commonJS({
1853
1853
  uninstall(event);
1854
1854
  }
1855
1855
  }
1856
- function _register(event, obj, fn) {
1857
- if (obj === void 0) {
1856
+ function _register(event, obj2, fn) {
1857
+ if (obj2 === void 0) {
1858
1858
  throw new Error("the object can't be undefined");
1859
1859
  }
1860
1860
  install(event);
1861
- const ref = new WeakRef(obj);
1861
+ const ref = new WeakRef(obj2);
1862
1862
  ref.fn = fn;
1863
1863
  ensureRegistry();
1864
- registry.register(obj, ref);
1864
+ registry.register(obj2, ref);
1865
1865
  refs[event].push(ref);
1866
1866
  }
1867
- function register(obj, fn) {
1868
- _register("exit", obj, fn);
1867
+ function register(obj2, fn) {
1868
+ _register("exit", obj2, fn);
1869
1869
  }
1870
- function registerBeforeExit(obj, fn) {
1871
- _register("beforeExit", obj, fn);
1870
+ function registerBeforeExit(obj2, fn) {
1871
+ _register("beforeExit", obj2, fn);
1872
1872
  }
1873
- function unregister(obj) {
1873
+ function unregister(obj2) {
1874
1874
  if (registry === void 0) {
1875
1875
  return;
1876
1876
  }
1877
- registry.unregister(obj);
1877
+ registry.unregister(obj2);
1878
1878
  for (const event of ["exit", "beforeExit"]) {
1879
1879
  refs[event] = refs[event].filter((ref) => {
1880
1880
  const _obj = ref.deref();
1881
- return _obj && _obj !== obj;
1881
+ return _obj && _obj !== obj2;
1882
1882
  });
1883
1883
  uninstall(event);
1884
1884
  }
@@ -2034,7 +2034,7 @@ var require_thread_stream = __commonJS({
2034
2034
  var { version: version2 } = require_package();
2035
2035
  var { EventEmitter } = __require("events");
2036
2036
  var { Worker: Worker2 } = __require("worker_threads");
2037
- var { join: join62 } = __require("path");
2037
+ var { join: join63 } = __require("path");
2038
2038
  var { pathToFileURL } = __require("url");
2039
2039
  var { wait } = require_wait();
2040
2040
  var {
@@ -2077,7 +2077,7 @@ var require_thread_stream = __commonJS({
2077
2077
  function createWorker(stream, opts) {
2078
2078
  const { filename, workerData } = opts;
2079
2079
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
2080
- const toExecute = bundlerOverrides["thread-stream-worker"] || join62(__dirname, "lib", "worker.js");
2080
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join63(__dirname, "lib", "worker.js");
2081
2081
  const worker = new Worker2(toExecute, {
2082
2082
  ...opts.workerOpts,
2083
2083
  trackUnmanagedFds: false,
@@ -2480,7 +2480,7 @@ var require_transport = __commonJS({
2480
2480
  "use strict";
2481
2481
  var { createRequire: createRequire3 } = __require("module");
2482
2482
  var getCallers = require_caller();
2483
- var { join: join62, isAbsolute: isAbsolute4, sep: sep4 } = __require("node:path");
2483
+ var { join: join63, isAbsolute: isAbsolute4, sep: sep4 } = __require("node:path");
2484
2484
  var sleep = require_atomic_sleep();
2485
2485
  var onExit = require_on_exit_leak_free();
2486
2486
  var ThreadStream = require_thread_stream();
@@ -2543,7 +2543,7 @@ var require_transport = __commonJS({
2543
2543
  throw new Error("only one of target or targets can be specified");
2544
2544
  }
2545
2545
  if (targets) {
2546
- target = bundlerOverrides["pino-worker"] || join62(__dirname, "worker.js");
2546
+ target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
2547
2547
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
2548
2548
  return {
2549
2549
  ...dest,
@@ -2561,7 +2561,7 @@ var require_transport = __commonJS({
2561
2561
  });
2562
2562
  });
2563
2563
  } else if (pipeline) {
2564
- target = bundlerOverrides["pino-worker"] || join62(__dirname, "worker.js");
2564
+ target = bundlerOverrides["pino-worker"] || join63(__dirname, "worker.js");
2565
2565
  options.pipelines = [pipeline.map((dest) => {
2566
2566
  return {
2567
2567
  ...dest,
@@ -2583,7 +2583,7 @@ var require_transport = __commonJS({
2583
2583
  return origin;
2584
2584
  }
2585
2585
  if (origin === "pino/file") {
2586
- return join62(__dirname, "..", "file.js");
2586
+ return join63(__dirname, "..", "file.js");
2587
2587
  }
2588
2588
  let fixTarget2;
2589
2589
  for (const filePath of callers) {
@@ -2706,14 +2706,14 @@ var require_tools = __commonJS({
2706
2706
  }
2707
2707
  return point < 32 ? JSON.stringify(str) : '"' + result + '"';
2708
2708
  }
2709
- function asJson(obj, msg, num, time) {
2709
+ function asJson(obj2, msg, num, time) {
2710
2710
  if (asJsonChan.hasSubscribers === false) {
2711
- return _asJson.call(this, obj, msg, num, time);
2711
+ return _asJson.call(this, obj2, msg, num, time);
2712
2712
  }
2713
2713
  const store2 = { instance: this, arguments };
2714
- return asJsonChan.traceSync(_asJson, store2, this, obj, msg, num, time);
2714
+ return asJsonChan.traceSync(_asJson, store2, this, obj2, msg, num, time);
2715
2715
  }
2716
- function _asJson(obj, msg, num, time) {
2716
+ function _asJson(obj2, msg, num, time) {
2717
2717
  const stringify2 = this[stringifySym];
2718
2718
  const stringifySafe = this[stringifySafeSym];
2719
2719
  const stringifiers = this[stringifiersSym];
@@ -2727,13 +2727,13 @@ var require_tools = __commonJS({
2727
2727
  data = data + chindings;
2728
2728
  let value;
2729
2729
  if (formatters.log) {
2730
- obj = formatters.log(obj);
2730
+ obj2 = formatters.log(obj2);
2731
2731
  }
2732
2732
  const wildcardStringifier = stringifiers[wildcardFirstSym];
2733
2733
  let propStr = "";
2734
- for (const key2 in obj) {
2735
- value = obj[key2];
2736
- if (Object.prototype.hasOwnProperty.call(obj, key2) && value !== void 0) {
2734
+ for (const key2 in obj2) {
2735
+ value = obj2[key2];
2736
+ if (Object.prototype.hasOwnProperty.call(obj2, key2) && value !== void 0) {
2737
2737
  if (serializers[key2]) {
2738
2738
  value = serializers[key2](value);
2739
2739
  } else if (key2 === errorKey && serializers.err) {
@@ -2899,13 +2899,13 @@ var require_tools = __commonJS({
2899
2899
  return { opts, stream };
2900
2900
  };
2901
2901
  }
2902
- function stringify(obj, stringifySafeFn) {
2902
+ function stringify(obj2, stringifySafeFn) {
2903
2903
  try {
2904
- return JSON.stringify(obj);
2904
+ return JSON.stringify(obj2);
2905
2905
  } catch (_) {
2906
2906
  try {
2907
2907
  const stringify2 = stringifySafeFn || this[stringifySafeSym];
2908
- return stringify2(obj);
2908
+ return stringify2(obj2);
2909
2909
  } catch (_2) {
2910
2910
  return '"[unable to serialize, circular reference is too complex to analyze]"';
2911
2911
  }
@@ -3355,29 +3355,29 @@ var require_proto = __commonJS({
3355
3355
  const errorKey = this[errorKeySym];
3356
3356
  const messageKey = this[messageKeySym];
3357
3357
  const mixinMergeStrategy = this[mixinMergeStrategySym] || defaultMixinMergeStrategy;
3358
- let obj;
3358
+ let obj2;
3359
3359
  const streamWriteHook = this[hooksSym].streamWrite;
3360
3360
  if (_obj === void 0 || _obj === null) {
3361
- obj = {};
3361
+ obj2 = {};
3362
3362
  } else if (_obj instanceof Error) {
3363
- obj = { [errorKey]: _obj };
3363
+ obj2 = { [errorKey]: _obj };
3364
3364
  if (msg === void 0) {
3365
3365
  msg = _obj.message;
3366
3366
  }
3367
3367
  } else {
3368
- obj = _obj;
3368
+ obj2 = _obj;
3369
3369
  if (msg === void 0 && _obj[messageKey] === void 0 && _obj[errorKey]) {
3370
3370
  msg = _obj[errorKey].message;
3371
3371
  }
3372
3372
  }
3373
3373
  if (mixin) {
3374
- obj = mixinMergeStrategy(obj, mixin(obj, num, this));
3374
+ obj2 = mixinMergeStrategy(obj2, mixin(obj2, num, this));
3375
3375
  }
3376
- const s = this[asJsonSym](obj, msg, num, t);
3376
+ const s = this[asJsonSym](obj2, msg, num, t);
3377
3377
  const stream = this[streamSym];
3378
3378
  if (stream[needsMetadataGsym] === true) {
3379
3379
  stream.lastLevel = num;
3380
- stream.lastObj = obj;
3380
+ stream.lastObj = obj2;
3381
3381
  stream.lastMsg = msg;
3382
3382
  stream.lastTime = t.slice(this[timeSliceIndexSym]);
3383
3383
  stream.lastLogger = this;
@@ -3572,7 +3572,7 @@ var require_safe_stable_stringify = __commonJS({
3572
3572
  return circularValue;
3573
3573
  }
3574
3574
  let res = "";
3575
- let join62 = ",";
3575
+ let join63 = ",";
3576
3576
  const originalIndentation = indentation;
3577
3577
  if (Array.isArray(value)) {
3578
3578
  if (value.length === 0) {
@@ -3586,7 +3586,7 @@ var require_safe_stable_stringify = __commonJS({
3586
3586
  indentation += spacer;
3587
3587
  res += `
3588
3588
  ${indentation}`;
3589
- join62 = `,
3589
+ join63 = `,
3590
3590
  ${indentation}`;
3591
3591
  }
3592
3592
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3594,13 +3594,13 @@ ${indentation}`;
3594
3594
  for (; i < maximumValuesToStringify - 1; i++) {
3595
3595
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3596
3596
  res += tmp2 !== void 0 ? tmp2 : "null";
3597
- res += join62;
3597
+ res += join63;
3598
3598
  }
3599
3599
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3600
3600
  res += tmp !== void 0 ? tmp : "null";
3601
3601
  if (value.length - 1 > maximumBreadth) {
3602
3602
  const removedKeys = value.length - maximumBreadth - 1;
3603
- res += `${join62}"... ${getItemCount(removedKeys)} not stringified"`;
3603
+ res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3604
3604
  }
3605
3605
  if (spacer !== "") {
3606
3606
  res += `
@@ -3621,7 +3621,7 @@ ${originalIndentation}`;
3621
3621
  let separator = "";
3622
3622
  if (spacer !== "") {
3623
3623
  indentation += spacer;
3624
- join62 = `,
3624
+ join63 = `,
3625
3625
  ${indentation}`;
3626
3626
  whitespace = " ";
3627
3627
  }
@@ -3635,13 +3635,13 @@ ${indentation}`;
3635
3635
  const tmp = stringifyFnReplacer(key3, value, stack, replacer, spacer, indentation);
3636
3636
  if (tmp !== void 0) {
3637
3637
  res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
3638
- separator = join62;
3638
+ separator = join63;
3639
3639
  }
3640
3640
  }
3641
3641
  if (keyLength > maximumBreadth) {
3642
3642
  const removedKeys = keyLength - maximumBreadth;
3643
3643
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
3644
- separator = join62;
3644
+ separator = join63;
3645
3645
  }
3646
3646
  if (spacer !== "" && separator.length > 1) {
3647
3647
  res = `
@@ -3682,7 +3682,7 @@ ${originalIndentation}`;
3682
3682
  }
3683
3683
  const originalIndentation = indentation;
3684
3684
  let res = "";
3685
- let join62 = ",";
3685
+ let join63 = ",";
3686
3686
  if (Array.isArray(value)) {
3687
3687
  if (value.length === 0) {
3688
3688
  return "[]";
@@ -3695,7 +3695,7 @@ ${originalIndentation}`;
3695
3695
  indentation += spacer;
3696
3696
  res += `
3697
3697
  ${indentation}`;
3698
- join62 = `,
3698
+ join63 = `,
3699
3699
  ${indentation}`;
3700
3700
  }
3701
3701
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3703,13 +3703,13 @@ ${indentation}`;
3703
3703
  for (; i < maximumValuesToStringify - 1; i++) {
3704
3704
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3705
3705
  res += tmp2 !== void 0 ? tmp2 : "null";
3706
- res += join62;
3706
+ res += join63;
3707
3707
  }
3708
3708
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3709
3709
  res += tmp !== void 0 ? tmp : "null";
3710
3710
  if (value.length - 1 > maximumBreadth) {
3711
3711
  const removedKeys = value.length - maximumBreadth - 1;
3712
- res += `${join62}"... ${getItemCount(removedKeys)} not stringified"`;
3712
+ res += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3713
3713
  }
3714
3714
  if (spacer !== "") {
3715
3715
  res += `
@@ -3722,7 +3722,7 @@ ${originalIndentation}`;
3722
3722
  let whitespace = "";
3723
3723
  if (spacer !== "") {
3724
3724
  indentation += spacer;
3725
- join62 = `,
3725
+ join63 = `,
3726
3726
  ${indentation}`;
3727
3727
  whitespace = " ";
3728
3728
  }
@@ -3731,7 +3731,7 @@ ${indentation}`;
3731
3731
  const tmp = stringifyArrayReplacer(key3, value[key3], stack, replacer, spacer, indentation);
3732
3732
  if (tmp !== void 0) {
3733
3733
  res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
3734
- separator = join62;
3734
+ separator = join63;
3735
3735
  }
3736
3736
  }
3737
3737
  if (spacer !== "" && separator.length > 1) {
@@ -3789,20 +3789,20 @@ ${originalIndentation}`;
3789
3789
  indentation += spacer;
3790
3790
  let res2 = `
3791
3791
  ${indentation}`;
3792
- const join63 = `,
3792
+ const join64 = `,
3793
3793
  ${indentation}`;
3794
3794
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
3795
3795
  let i = 0;
3796
3796
  for (; i < maximumValuesToStringify - 1; i++) {
3797
3797
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3798
3798
  res2 += tmp2 !== void 0 ? tmp2 : "null";
3799
- res2 += join63;
3799
+ res2 += join64;
3800
3800
  }
3801
3801
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3802
3802
  res2 += tmp !== void 0 ? tmp : "null";
3803
3803
  if (value.length - 1 > maximumBreadth) {
3804
3804
  const removedKeys = value.length - maximumBreadth - 1;
3805
- res2 += `${join63}"... ${getItemCount(removedKeys)} not stringified"`;
3805
+ res2 += `${join64}"... ${getItemCount(removedKeys)} not stringified"`;
3806
3806
  }
3807
3807
  res2 += `
3808
3808
  ${originalIndentation}`;
@@ -3818,16 +3818,16 @@ ${originalIndentation}`;
3818
3818
  return '"[Object]"';
3819
3819
  }
3820
3820
  indentation += spacer;
3821
- const join62 = `,
3821
+ const join63 = `,
3822
3822
  ${indentation}`;
3823
3823
  let res = "";
3824
3824
  let separator = "";
3825
3825
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
3826
3826
  if (isTypedArrayWithEntries(value)) {
3827
- res += stringifyTypedArray(value, join62, maximumBreadth);
3827
+ res += stringifyTypedArray(value, join63, maximumBreadth);
3828
3828
  keys = keys.slice(value.length);
3829
3829
  maximumPropertiesToStringify -= value.length;
3830
- separator = join62;
3830
+ separator = join63;
3831
3831
  }
3832
3832
  if (deterministic) {
3833
3833
  keys = sort(keys, comparator);
@@ -3838,13 +3838,13 @@ ${indentation}`;
3838
3838
  const tmp = stringifyIndent(key3, value[key3], stack, spacer, indentation);
3839
3839
  if (tmp !== void 0) {
3840
3840
  res += `${separator}${strEscape(key3)}: ${tmp}`;
3841
- separator = join62;
3841
+ separator = join63;
3842
3842
  }
3843
3843
  }
3844
3844
  if (keyLength > maximumBreadth) {
3845
3845
  const removedKeys = keyLength - maximumBreadth;
3846
3846
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
3847
- separator = join62;
3847
+ separator = join63;
3848
3848
  }
3849
3849
  if (separator !== "") {
3850
3850
  res = `
@@ -5036,30 +5036,30 @@ function declaredOrigin(value) {
5036
5036
  const kind = value.kind;
5037
5037
  return typeof kind === "string" && kind ? kind : void 0;
5038
5038
  }
5039
- function userRecordOrigin(obj, text) {
5040
- if (obj.isSidechain === true)
5039
+ function userRecordOrigin(obj2, text) {
5040
+ if (obj2.isSidechain === true)
5041
5041
  return "subagent";
5042
- if (obj.isCompactSummary === true)
5042
+ if (obj2.isCompactSummary === true)
5043
5043
  return "compact-summary";
5044
- const declared = declaredOrigin(obj.origin);
5044
+ const declared = declaredOrigin(obj2.origin);
5045
5045
  if (declared && declared !== "human")
5046
5046
  return declared;
5047
- if (obj.isMeta === true)
5047
+ if (obj2.isMeta === true)
5048
5048
  return "meta";
5049
5049
  if (declared === "human")
5050
5050
  return "human";
5051
5051
  return originFromText(text);
5052
5052
  }
5053
- function queuedCommandPrompt(obj) {
5054
- if (obj.type !== "attachment")
5053
+ function queuedCommandPrompt(obj2) {
5054
+ if (obj2.type !== "attachment")
5055
5055
  return null;
5056
- const att = obj.attachment;
5056
+ const att = obj2.attachment;
5057
5057
  if (!att || att.type !== "queued_command")
5058
5058
  return null;
5059
5059
  const text = promptText(att.prompt);
5060
5060
  if (!text)
5061
5061
  return null;
5062
- if (obj.isSidechain === true)
5062
+ if (obj2.isSidechain === true)
5063
5063
  return { text, origin: "subagent" };
5064
5064
  const declared = declaredOrigin(att.origin);
5065
5065
  if (declared)
@@ -6412,6 +6412,130 @@ var init_sqlite_reader = __esm({
6412
6412
  }
6413
6413
  });
6414
6414
 
6415
+ // ../engine/dist/core/backends/opencode-v2.js
6416
+ function hasTable(db, name) {
6417
+ return !!db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = 'table' AND name = ?").get(name);
6418
+ }
6419
+ function columnsOf(db, table) {
6420
+ return new Set(db.prepare(`SELECT name FROM pragma_table_info('${table}', 'main')`).all().map((r) => r.name));
6421
+ }
6422
+ function installOpencodeV2Views(db) {
6423
+ if (!hasTable(db, "session_v2") || !hasTable(db, "session_message"))
6424
+ return false;
6425
+ const v2Cols = columnsOf(db, "session_v2");
6426
+ const sessionCols = SESSION_COLUMNS.map((c) => v2Cols.has(c) ? c : `NULL AS ${c}`).join(", ");
6427
+ const hasV1 = hasTable(db, "message") && hasTable(db, "part");
6428
+ const v1Messages = hasV1 ? `SELECT id, session_id, time_created, time_updated, data FROM main.message WHERE session_id NOT IN (${V2_SESSIONS}) UNION ALL ` : "";
6429
+ const v1Parts = hasV1 ? `SELECT id, message_id, session_id, time_created, time_updated, data FROM main.part WHERE session_id NOT IN (${V2_SESSIONS}) UNION ALL ` : "";
6430
+ db.exec(`
6431
+ CREATE TEMP VIEW IF NOT EXISTS session AS SELECT ${sessionCols} FROM main.session_v2;
6432
+
6433
+ CREATE TEMP VIEW IF NOT EXISTS message AS
6434
+ ${v1Messages}
6435
+ SELECT m.id, m.session_id, m.time_created, m.time_updated,
6436
+ CASE m.type
6437
+ WHEN 'user' THEN json_object('role', 'user', 'time', ${j("$.time")})
6438
+ ELSE json_object(
6439
+ 'role', 'assistant',
6440
+ 'agent', json_extract(m.data, '$.agent'),
6441
+ 'modelID', json_extract(m.data, '$.model.id'),
6442
+ 'providerID', json_extract(m.data, '$.model.providerID'),
6443
+ 'cost', coalesce(json_extract(m.data, '$.cost'), 0),
6444
+ 'tokens', ${j("$.tokens")},
6445
+ 'time', ${j("$.time")})
6446
+ END AS data
6447
+ FROM main.session_message m WHERE m.type IN ('user', 'assistant');
6448
+
6449
+ CREATE TEMP VIEW IF NOT EXISTS part AS
6450
+ ${v1Parts}
6451
+ SELECT m.id || ':text', m.id, m.session_id, m.time_created, m.time_updated,
6452
+ json_object('type', 'text', 'text', json_extract(m.data, '$.text'))
6453
+ FROM main.session_message m
6454
+ WHERE m.type = 'user' AND json_extract(m.data, '$.text') IS NOT NULL
6455
+ UNION ALL
6456
+ SELECT m.id || ':' || c.key, m.id, m.session_id, m.time_created + c.key, m.time_updated,
6457
+ CASE json_extract(c.value, '$.type')
6458
+ WHEN 'tool' THEN json_object(
6459
+ 'type', 'tool',
6460
+ 'tool', json_extract(c.value, '$.name'),
6461
+ 'callID', json_extract(c.value, '$.id'),
6462
+ 'state', json_object(
6463
+ 'status', json_extract(c.value, '$.state.status'),
6464
+ 'input', json(coalesce(json_extract(c.value, '$.state.input'), '{}')),
6465
+ 'output', (SELECT group_concat(json_extract(o.value, '$.text'), char(10))
6466
+ FROM json_each(c.value, '$.state.content') o
6467
+ WHERE json_extract(o.value, '$.type') = 'text')))
6468
+ ELSE json_object('type', json_extract(c.value, '$.type'), 'text', json_extract(c.value, '$.text'))
6469
+ END
6470
+ FROM main.session_message m, json_each(m.data, '$.content') c
6471
+ WHERE m.type = 'assistant'
6472
+ UNION ALL
6473
+ SELECT m.id || ':step', m.id, m.session_id,
6474
+ coalesce(json_extract(m.data, '$.time.completed'), m.time_created), m.time_updated,
6475
+ json_object('type', 'step-finish', 'cost', coalesce(json_extract(m.data, '$.cost'), 0), 'tokens', ${j("$.tokens")})
6476
+ FROM main.session_message m WHERE m.type = 'assistant';
6477
+ `);
6478
+ return true;
6479
+ }
6480
+ function openOpencodeDb(path2) {
6481
+ const db = openSqliteReadonly(path2);
6482
+ if (!db)
6483
+ return null;
6484
+ try {
6485
+ installOpencodeV2Views(db);
6486
+ } catch {
6487
+ }
6488
+ return db;
6489
+ }
6490
+ function openOpencodeDbOrThrow(path2) {
6491
+ const db = openSqliteReadonlyOrThrow(path2);
6492
+ try {
6493
+ installOpencodeV2Views(db);
6494
+ } catch {
6495
+ }
6496
+ return db;
6497
+ }
6498
+ var SESSION_COLUMNS, j, V2_SESSIONS;
6499
+ var init_opencode_v2 = __esm({
6500
+ "../engine/dist/core/backends/opencode-v2.js"() {
6501
+ "use strict";
6502
+ init_sqlite_reader();
6503
+ SESSION_COLUMNS = [
6504
+ "id",
6505
+ "project_id",
6506
+ "parent_id",
6507
+ "slug",
6508
+ "directory",
6509
+ "title",
6510
+ "version",
6511
+ "share_url",
6512
+ "summary_additions",
6513
+ "summary_deletions",
6514
+ "summary_files",
6515
+ "summary_diffs",
6516
+ "revert",
6517
+ "permission",
6518
+ "time_created",
6519
+ "time_updated",
6520
+ "time_compacting",
6521
+ "time_archived",
6522
+ "workspace_id",
6523
+ "path",
6524
+ "agent",
6525
+ "model",
6526
+ "cost",
6527
+ "tokens_input",
6528
+ "tokens_output",
6529
+ "tokens_reasoning",
6530
+ "tokens_cache_read",
6531
+ "tokens_cache_write",
6532
+ "metadata"
6533
+ ];
6534
+ j = (path2, fallback = "'{}'") => `json(coalesce(json_extract(m.data, '${path2}'), ${fallback}))`;
6535
+ V2_SESSIONS = "SELECT session_id FROM main.session_message";
6536
+ }
6537
+ });
6538
+
6415
6539
  // ../engine/dist/core/generic-engine.js
6416
6540
  import { basename as basename5 } from "path";
6417
6541
  import { createPatch } from "diff";
@@ -6709,13 +6833,13 @@ import { existsSync as existsSync7 } from "fs";
6709
6833
  import { homedir as homedir5 } from "os";
6710
6834
  import { dirname as dirname8, join as join9 } from "path";
6711
6835
  function openReadonly(path2) {
6712
- return openSqliteReadonly(path2);
6836
+ return openOpencodeDb(path2);
6713
6837
  }
6714
6838
  var PREFIX, OpencodeBackend, opencodeBackend;
6715
6839
  var init_opencode = __esm({
6716
6840
  "../engine/dist/core/backends/opencode.js"() {
6717
6841
  "use strict";
6718
- init_sqlite_reader();
6842
+ init_opencode_v2();
6719
6843
  init_tool_paths();
6720
6844
  init_session_outcome();
6721
6845
  init_session_git();
@@ -7006,9 +7130,9 @@ var init_opencode = __esm({
7006
7130
  return [];
7007
7131
  const parts = db.prepare(`
7008
7132
  SELECT p.id, p.message_id, p.time_created, p.data, m.data AS msg_data
7009
- FROM part p JOIN message m ON m.id = p.message_id
7133
+ FROM part p JOIN (SELECT id, data FROM message WHERE session_id = ?) m ON m.id = p.message_id
7010
7134
  WHERE p.session_id = ? ORDER BY p.time_created ASC
7011
- `).all(ocId);
7135
+ `).all(ocId, ocId);
7012
7136
  const events = [];
7013
7137
  let lineNum = 0;
7014
7138
  for (const p of parts) {
@@ -7224,17 +7348,17 @@ var init_opencode = __esm({
7224
7348
  if (!existsSync7(dbPath))
7225
7349
  return null;
7226
7350
  const realId = this.toRawId(id);
7227
- const db = openSqliteReadonlyOrThrow(dbPath);
7351
+ const db = openOpencodeDbOrThrow(dbPath);
7228
7352
  try {
7229
7353
  const session = db.prepare(`SELECT * FROM session WHERE id = ?`).get(realId);
7230
7354
  if (!session)
7231
7355
  return null;
7232
7356
  const rows = db.prepare(`
7233
7357
  SELECT m.id AS message_id, m.data AS message_data, p.id AS part_id, p.data AS part_data, p.time_created
7234
- FROM part p JOIN message m ON p.message_id = m.id
7358
+ FROM part p JOIN (SELECT id, data FROM message WHERE session_id = ?) m ON p.message_id = m.id
7235
7359
  WHERE p.session_id = ?
7236
7360
  ORDER BY p.time_created ASC, p.id ASC
7237
- `).all(realId);
7361
+ `).all(realId, realId);
7238
7362
  const lines = [JSON.stringify({ kind: "session", row: session })];
7239
7363
  for (const r of rows)
7240
7364
  lines.push(JSON.stringify({ kind: "part", row: r }));
@@ -7914,30 +8038,30 @@ var init_codex = __esm({
7914
8038
  lineNum++;
7915
8039
  if (!line.trim())
7916
8040
  continue;
7917
- let obj;
8041
+ let obj2;
7918
8042
  try {
7919
- obj = JSON.parse(line);
8043
+ obj2 = JSON.parse(line);
7920
8044
  } catch {
7921
8045
  continue;
7922
8046
  }
7923
- const tsIso = typeof obj.timestamp === "string" ? obj.timestamp : void 0;
8047
+ const tsIso = typeof obj2.timestamp === "string" ? obj2.timestamp : void 0;
7924
8048
  const ts = tsIso ? Date.parse(tsIso) || mtime : mtime;
7925
- const payload = obj.payload || {};
7926
- if (obj.type === "event_msg" && payload.type === "user_message") {
8049
+ const payload = obj2.payload || {};
8050
+ if (obj2.type === "event_msg" && payload.type === "user_message") {
7927
8051
  const text = String(payload.message || "").trim();
7928
8052
  if (text && !isCodexInjectedWrapper(text)) {
7929
8053
  events.push({ kind: "user", ts, tsIso, line: lineNum, text });
7930
8054
  }
7931
- } else if (obj.type === "response_item" && payload.type === "message" && payload.role === "user") {
8055
+ } else if (obj2.type === "response_item" && payload.type === "message" && payload.role === "user") {
7932
8056
  const text = flattenContent(payload.content).trim();
7933
8057
  if (text && !isCodexInjectedWrapper(text)) {
7934
8058
  events.push({ kind: "user", ts, tsIso, line: lineNum, text });
7935
8059
  }
7936
- } else if (obj.type === "response_item" && payload.type === "message" && payload.role === "assistant") {
8060
+ } else if (obj2.type === "response_item" && payload.type === "message" && payload.role === "assistant") {
7937
8061
  const text = flattenContent(payload.content).trim();
7938
8062
  if (text)
7939
8063
  events.push({ kind: "assistant_text", ts, tsIso, line: lineNum, text });
7940
- } else if (obj.type === "response_item" && payload.type === "function_call") {
8064
+ } else if (obj2.type === "response_item" && payload.type === "function_call") {
7941
8065
  const toolName = String(payload.name || "");
7942
8066
  const callId = String(payload.call_id || "");
7943
8067
  let args = payload.arguments;
@@ -7961,7 +8085,7 @@ var init_codex = __esm({
7961
8085
  toolInput: args,
7962
8086
  command
7963
8087
  });
7964
- } else if (obj.type === "response_item" && payload.type === "function_call_output") {
8088
+ } else if (obj2.type === "response_item" && payload.type === "function_call_output") {
7965
8089
  const callId = String(payload.call_id || "");
7966
8090
  const out = payload.output;
7967
8091
  let body2 = "";
@@ -8221,14 +8345,14 @@ function extractProjectPathFromTranscript(path2, homeDir) {
8221
8345
  for (const line of content.split("\n")) {
8222
8346
  if (!line.trim())
8223
8347
  continue;
8224
- let obj;
8348
+ let obj2;
8225
8349
  try {
8226
- obj = JSON.parse(line);
8350
+ obj2 = JSON.parse(line);
8227
8351
  } catch {
8228
8352
  continue;
8229
8353
  }
8230
- if (obj.source === "USER_EXPLICIT" && obj.type === "USER_INPUT" && typeof obj.content === "string") {
8231
- const match = obj.content.match(/format\s+\[URI\]\s*->\s*\[CorpusName\]:\s*\n?\s*([^\s\n]+)\s*->/);
8354
+ if (obj2.source === "USER_EXPLICIT" && obj2.type === "USER_INPUT" && typeof obj2.content === "string") {
8355
+ const match = obj2.content.match(/format\s+\[URI\]\s*->\s*\[CorpusName\]:\s*\n?\s*([^\s\n]+)\s*->/);
8232
8356
  if (match && match[1])
8233
8357
  return match[1].trim();
8234
8358
  }
@@ -8346,6 +8470,10 @@ var init_agy = __esm({
8346
8470
  sharedSettingsFile() {
8347
8471
  return join11(this.sharedRootDir(), "settings.json");
8348
8472
  }
8473
+ /** The global hooks file the CLI reads. It does not read hooks from its own home directory. */
8474
+ sharedHooksFile() {
8475
+ return join11(this.sharedRootDir(), "config", "hooks.json");
8476
+ }
8349
8477
  sharedProjectsJson() {
8350
8478
  return join11(this.sharedRootDir(), "projects.json");
8351
8479
  }
@@ -8442,9 +8570,9 @@ var init_agy = __esm({
8442
8570
  const lines = readFileSync6(filePath, "utf-8").split("\n").filter(Boolean);
8443
8571
  messageCount = lines.length;
8444
8572
  for (const line of lines) {
8445
- const obj = JSON.parse(line);
8446
- if (obj.source === "USER_EXPLICIT" && obj.type === "USER_INPUT" && typeof obj.content === "string") {
8447
- const content = obj.content;
8573
+ const obj2 = JSON.parse(line);
8574
+ if (obj2.source === "USER_EXPLICIT" && obj2.type === "USER_INPUT" && typeof obj2.content === "string") {
8575
+ const content = obj2.content;
8448
8576
  const match = content.match(/<USER_REQUEST>([\s\S]*?)<\/USER_REQUEST>/);
8449
8577
  const rawText = match ? match[1].trim() : content.trim();
8450
8578
  firstPrompt = flatString(rawText.slice(0, 200));
@@ -8553,27 +8681,27 @@ var init_agy = __esm({
8553
8681
  lineNum++;
8554
8682
  if (!line.trim())
8555
8683
  continue;
8556
- let obj;
8684
+ let obj2;
8557
8685
  try {
8558
- obj = JSON.parse(line);
8686
+ obj2 = JSON.parse(line);
8559
8687
  } catch {
8560
8688
  continue;
8561
8689
  }
8562
- const tsIso = typeof obj.created_at === "string" ? obj.created_at : void 0;
8690
+ const tsIso = typeof obj2.created_at === "string" ? obj2.created_at : void 0;
8563
8691
  const ts = tsIso ? Date.parse(tsIso) || mtimeFallback : mtimeFallback;
8564
- if (obj.source === "USER_EXPLICIT" && obj.type === "USER_INPUT") {
8565
- const content = typeof obj.content === "string" ? obj.content : "";
8692
+ if (obj2.source === "USER_EXPLICIT" && obj2.type === "USER_INPUT") {
8693
+ const content = typeof obj2.content === "string" ? obj2.content : "";
8566
8694
  const match = content.match(/<USER_REQUEST>([\s\S]*?)<\/USER_REQUEST>/);
8567
8695
  const text = match ? match[1].trim() : content.trim();
8568
8696
  if (text) {
8569
8697
  events.push({ kind: "user", ts, tsIso, line: lineNum, text });
8570
8698
  }
8571
- } else if (obj.source === "MODEL" && obj.type === "PLANNER_RESPONSE") {
8572
- const content = typeof obj.content === "string" ? obj.content.trim() : "";
8699
+ } else if (obj2.source === "MODEL" && obj2.type === "PLANNER_RESPONSE") {
8700
+ const content = typeof obj2.content === "string" ? obj2.content.trim() : "";
8573
8701
  if (content) {
8574
8702
  events.push({ kind: "assistant_text", ts, tsIso, line: lineNum, text: content });
8575
8703
  }
8576
- const tcs = Array.isArray(obj.tool_calls) ? obj.tool_calls : [];
8704
+ const tcs = Array.isArray(obj2.tool_calls) ? obj2.tool_calls : [];
8577
8705
  for (const tc of tcs) {
8578
8706
  let toolName = String(tc?.name || "");
8579
8707
  if (!toolName)
@@ -8601,12 +8729,12 @@ var init_agy = __esm({
8601
8729
  command
8602
8730
  });
8603
8731
  }
8604
- } else if (obj.source === "MODEL" && obj.type !== "PLANNER_RESPONSE") {
8605
- const resultBody = typeof obj.content === "string" ? obj.content : "";
8606
- const isError = obj.status === "ERROR" || obj.status === "FAILED";
8732
+ } else if (obj2.source === "MODEL" && obj2.type !== "PLANNER_RESPONSE") {
8733
+ const resultBody = typeof obj2.content === "string" ? obj2.content : "";
8734
+ const isError = obj2.status === "ERROR" || obj2.status === "FAILED";
8607
8735
  let matchedIndex = -1;
8608
8736
  for (let i = 0; i < pendingToolCalls.length; i++) {
8609
- if (matchesTool(obj.type, pendingToolCalls[i].name)) {
8737
+ if (matchesTool(obj2.type, pendingToolCalls[i].name)) {
8610
8738
  matchedIndex = i;
8611
8739
  break;
8612
8740
  }
@@ -8624,7 +8752,7 @@ var init_agy = __esm({
8624
8752
  toolName = popped.name;
8625
8753
  } else {
8626
8754
  toolUseId = `agy_tc_orphan_${toolUseCounter++}`;
8627
- toolName = obj.type.toLowerCase();
8755
+ toolName = obj2.type.toLowerCase();
8628
8756
  }
8629
8757
  }
8630
8758
  events.push({
@@ -9095,22 +9223,22 @@ function readTranscriptEvents(rawText, mtimeFallback = 0) {
9095
9223
  lineNum++;
9096
9224
  if (!line.trim())
9097
9225
  continue;
9098
- let obj;
9226
+ let obj2;
9099
9227
  try {
9100
- obj = JSON.parse(line);
9228
+ obj2 = JSON.parse(line);
9101
9229
  } catch {
9102
9230
  continue;
9103
9231
  }
9104
- if (!obj.role)
9232
+ if (!obj2.role)
9105
9233
  continue;
9106
- const message = obj.message;
9234
+ const message = obj2.message;
9107
9235
  const content = Array.isArray(message?.content) ? message.content : [];
9108
9236
  for (const part of content) {
9109
9237
  if (!part || typeof part !== "object")
9110
9238
  continue;
9111
9239
  const p = part;
9112
9240
  if (p.type === "text" && typeof p.text === "string") {
9113
- if (obj.role === "user") {
9241
+ if (obj2.role === "user") {
9114
9242
  const { text, ts } = unwrapUserText(p.text);
9115
9243
  if (ts)
9116
9244
  clock = ts;
@@ -10385,19 +10513,19 @@ function parsePiFile(path2) {
10385
10513
  for (const line of raw.split("\n")) {
10386
10514
  if (!line.trim())
10387
10515
  continue;
10388
- let obj;
10516
+ let obj2;
10389
10517
  try {
10390
- obj = JSON.parse(line);
10518
+ obj2 = JSON.parse(line);
10391
10519
  } catch {
10392
10520
  continue;
10393
10521
  }
10394
- if (!obj || typeof obj !== "object")
10522
+ if (!obj2 || typeof obj2 !== "object")
10395
10523
  continue;
10396
- if (obj.type === "session" && !out.header) {
10397
- out.header = obj;
10524
+ if (obj2.type === "session" && !out.header) {
10525
+ out.header = obj2;
10398
10526
  continue;
10399
10527
  }
10400
- out.entries.push(obj);
10528
+ out.entries.push(obj2);
10401
10529
  }
10402
10530
  return out;
10403
10531
  }
@@ -10439,10 +10567,10 @@ function readPiHeader(path2) {
10439
10567
  const firstLine = buf.toString("utf-8", 0, n).split("\n", 1)[0];
10440
10568
  if (!firstLine.trim())
10441
10569
  return null;
10442
- const obj = JSON.parse(firstLine);
10443
- if (!obj || typeof obj !== "object" || obj.type !== "session")
10570
+ const obj2 = JSON.parse(firstLine);
10571
+ if (!obj2 || typeof obj2 !== "object" || obj2.type !== "session")
10444
10572
  return null;
10445
- return obj;
10573
+ return obj2;
10446
10574
  } catch {
10447
10575
  return null;
10448
10576
  } finally {
@@ -10770,17 +10898,17 @@ var init_pi = __esm({
10770
10898
  lineNum++;
10771
10899
  if (!line.trim())
10772
10900
  continue;
10773
- let obj;
10901
+ let obj2;
10774
10902
  try {
10775
- obj = JSON.parse(line);
10903
+ obj2 = JSON.parse(line);
10776
10904
  } catch {
10777
10905
  continue;
10778
10906
  }
10779
- const tsIso = typeof obj.timestamp === "string" ? obj.timestamp : void 0;
10780
- const msgTs = typeof obj.message?.timestamp === "number" ? obj.message.timestamp : void 0;
10907
+ const tsIso = typeof obj2.timestamp === "string" ? obj2.timestamp : void 0;
10908
+ const msgTs = typeof obj2.message?.timestamp === "number" ? obj2.message.timestamp : void 0;
10781
10909
  const ts = tsIso ? Date.parse(tsIso) || mtimeFallback : msgTs ?? mtimeFallback;
10782
- if (obj.type === "message") {
10783
- const msg = obj.message || {};
10910
+ if (obj2.type === "message") {
10911
+ const msg = obj2.message || {};
10784
10912
  const role = msg.role;
10785
10913
  if (role === "user") {
10786
10914
  const text = piText(msg.content).trim();
@@ -10859,12 +10987,12 @@ var init_pi = __esm({
10859
10987
  }
10860
10988
  continue;
10861
10989
  }
10862
- if (obj.type === "compaction" && typeof obj.summary === "string" && obj.summary.trim()) {
10863
- events.push({ kind: "summary", ts, tsIso, line: lineNum, text: obj.summary.trim() });
10990
+ if (obj2.type === "compaction" && typeof obj2.summary === "string" && obj2.summary.trim()) {
10991
+ events.push({ kind: "summary", ts, tsIso, line: lineNum, text: obj2.summary.trim() });
10864
10992
  continue;
10865
10993
  }
10866
- if (obj.type === "branch_summary" && typeof obj.summary === "string" && obj.summary.trim()) {
10867
- events.push({ kind: "summary", ts, tsIso, line: lineNum, text: obj.summary.trim() });
10994
+ if (obj2.type === "branch_summary" && typeof obj2.summary === "string" && obj2.summary.trim()) {
10995
+ events.push({ kind: "summary", ts, tsIso, line: lineNum, text: obj2.summary.trim() });
10868
10996
  }
10869
10997
  }
10870
10998
  return events;
@@ -11231,17 +11359,17 @@ function stripBanners(s) {
11231
11359
  function promptFromLine(raw, maxLength) {
11232
11360
  if (!raw.trim())
11233
11361
  return null;
11234
- let obj;
11362
+ let obj2;
11235
11363
  try {
11236
- obj = JSON.parse(raw);
11364
+ obj2 = JSON.parse(raw);
11237
11365
  } catch {
11238
11366
  return null;
11239
11367
  }
11240
- if (obj.type !== "user")
11368
+ if (obj2.type !== "user")
11241
11369
  return null;
11242
- if (obj.isSidechain === true)
11370
+ if (obj2.isSidechain === true)
11243
11371
  return null;
11244
- const message = obj.message;
11372
+ const message = obj2.message;
11245
11373
  if (!message)
11246
11374
  return null;
11247
11375
  const content = message.content;
@@ -11732,17 +11860,17 @@ var init_claude = __esm({
11732
11860
  lineNum++;
11733
11861
  if (!line.trim())
11734
11862
  continue;
11735
- let obj;
11863
+ let obj2;
11736
11864
  try {
11737
- obj = JSON.parse(line);
11865
+ obj2 = JSON.parse(line);
11738
11866
  } catch {
11739
11867
  continue;
11740
11868
  }
11741
- const tsIso = typeof obj.timestamp === "string" ? obj.timestamp : void 0;
11869
+ const tsIso = typeof obj2.timestamp === "string" ? obj2.timestamp : void 0;
11742
11870
  const ts = tsIso ? Date.parse(tsIso) || mtime : mtime;
11743
- if (obj.type === "queue-operation") {
11744
- if (obj.operation === "enqueue" && typeof obj.content === "string") {
11745
- const text = stripReminders(obj.content);
11871
+ if (obj2.type === "queue-operation") {
11872
+ if (obj2.operation === "enqueue" && typeof obj2.content === "string") {
11873
+ const text = stripReminders(obj2.content);
11746
11874
  if (text && originFromText(text) === "human") {
11747
11875
  const e = { kind: "user", ts, tsIso, line: lineNum, text };
11748
11876
  events.push(e);
@@ -11755,15 +11883,15 @@ var init_claude = __esm({
11755
11883
  }
11756
11884
  continue;
11757
11885
  }
11758
- const delivered = queuedCommandPrompt(obj);
11886
+ const delivered = queuedCommandPrompt(obj2);
11759
11887
  if (delivered) {
11760
11888
  const text = stripReminders(delivered.text);
11761
11889
  if (text && delivered.origin === "human")
11762
11890
  pushPrompt({ kind: "user", ts, tsIso, line: lineNum, text });
11763
11891
  continue;
11764
11892
  }
11765
- if (obj.type === "user") {
11766
- const msg = obj.message;
11893
+ if (obj2.type === "user") {
11894
+ const msg = obj2.message;
11767
11895
  const content = msg?.content;
11768
11896
  let text = "";
11769
11897
  const toolResults = [];
@@ -11796,7 +11924,7 @@ var init_claude = __esm({
11796
11924
  }
11797
11925
  }
11798
11926
  const spoken = stripReminders(text);
11799
- if (spoken && userRecordOrigin(obj, spoken) === "human") {
11927
+ if (spoken && userRecordOrigin(obj2, spoken) === "human") {
11800
11928
  pushPrompt({ kind: "user", ts, tsIso, line: lineNum, text: spoken });
11801
11929
  }
11802
11930
  for (const tr of toolResults) {
@@ -11812,13 +11940,13 @@ var init_claude = __esm({
11812
11940
  resultBytes: tr.body.length
11813
11941
  });
11814
11942
  }
11815
- } else if (obj.type === "summary") {
11816
- const summary = typeof obj.summary === "string" ? obj.summary : "";
11943
+ } else if (obj2.type === "summary") {
11944
+ const summary = typeof obj2.summary === "string" ? obj2.summary : "";
11817
11945
  if (summary) {
11818
11946
  events.push({ kind: "summary", ts, tsIso, line: lineNum, text: summary });
11819
11947
  }
11820
- } else if (obj.type === "assistant") {
11821
- const msg = obj.message;
11948
+ } else if (obj2.type === "assistant") {
11949
+ const msg = obj2.message;
11822
11950
  const content = msg?.content;
11823
11951
  if (!Array.isArray(content))
11824
11952
  continue;
@@ -12296,9 +12424,9 @@ function readCwdFromJsonl(sessionPath) {
12296
12424
  if (!line || !line.includes('"cwd"'))
12297
12425
  continue;
12298
12426
  try {
12299
- const obj = JSON.parse(line);
12300
- if (typeof obj.cwd === "string" && obj.cwd)
12301
- return obj.cwd;
12427
+ const obj2 = JSON.parse(line);
12428
+ if (typeof obj2.cwd === "string" && obj2.cwd)
12429
+ return obj2.cwd;
12302
12430
  } catch {
12303
12431
  }
12304
12432
  }
@@ -12380,25 +12508,25 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
12380
12508
  lineNum++;
12381
12509
  if (!line.trim())
12382
12510
  continue;
12383
- let obj;
12511
+ let obj2;
12384
12512
  try {
12385
- obj = JSON.parse(line);
12513
+ obj2 = JSON.parse(line);
12386
12514
  } catch {
12387
12515
  continue;
12388
12516
  }
12389
12517
  try {
12390
- const msgType = obj.type;
12391
- if (!content.metadata.gitBranch && obj.gitBranch) {
12392
- content.metadata.gitBranch = obj.gitBranch;
12518
+ const msgType = obj2.type;
12519
+ if (!content.metadata.gitBranch && obj2.gitBranch) {
12520
+ content.metadata.gitBranch = obj2.gitBranch;
12393
12521
  }
12394
- if (!content.metadata.slug && obj.slug) {
12395
- content.metadata.slug = obj.slug;
12522
+ if (!content.metadata.slug && obj2.slug) {
12523
+ content.metadata.slug = obj2.slug;
12396
12524
  }
12397
- if (msgType === "system" && obj.subtype === "turn_duration" && obj.durationMs) {
12398
- content.metadata.durationMs += obj.durationMs;
12525
+ if (msgType === "system" && obj2.subtype === "turn_duration" && obj2.durationMs) {
12526
+ content.metadata.durationMs += obj2.durationMs;
12399
12527
  }
12400
12528
  if (msgType === "file-history-snapshot") {
12401
- const snapshot2 = obj.snapshot;
12529
+ const snapshot2 = obj2.snapshot;
12402
12530
  if (snapshot2 && typeof snapshot2 === "object") {
12403
12531
  const backups = snapshot2.trackedFileBackups;
12404
12532
  if (backups && typeof backups === "object") {
@@ -12409,14 +12537,14 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
12409
12537
  }
12410
12538
  }
12411
12539
  if (msgType === "summary") {
12412
- const summary = obj.summary;
12540
+ const summary = obj2.summary;
12413
12541
  if (summary) {
12414
12542
  content.summaries.push(summary);
12415
12543
  }
12416
12544
  } else if (msgType === "user") {
12417
12545
  if (userCount >= maxMessages)
12418
12546
  continue;
12419
- const msg = obj.message;
12547
+ const msg = obj2.message;
12420
12548
  let text = "";
12421
12549
  if (msg && typeof msg === "object") {
12422
12550
  const msgContent = msg.content;
@@ -12445,18 +12573,18 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
12445
12573
  text = textParts.join("\n");
12446
12574
  }
12447
12575
  }
12448
- if (text && userRecordOrigin(obj, text) === "human")
12576
+ if (text && userRecordOrigin(obj2, text) === "human")
12449
12577
  recordPrompt(text, lineNum);
12450
12578
  } else if (msgType === "queue-operation") {
12451
- if (obj.operation === "enqueue" && typeof obj.content === "string" && originFromText(obj.content) === "human") {
12452
- recordPrompt(obj.content, lineNum, "enqueue");
12579
+ if (obj2.operation === "enqueue" && typeof obj2.content === "string" && originFromText(obj2.content) === "human") {
12580
+ recordPrompt(obj2.content, lineNum, "enqueue");
12453
12581
  }
12454
12582
  } else if (msgType === "attachment") {
12455
- const queued = queuedCommandPrompt(obj);
12583
+ const queued = queuedCommandPrompt(obj2);
12456
12584
  if (queued?.origin === "human")
12457
12585
  recordPrompt(queued.text, lineNum, "delivery");
12458
12586
  } else if (msgType === "assistant") {
12459
- const msg = obj.message;
12587
+ const msg = obj2.message;
12460
12588
  if (!msg || typeof msg !== "object")
12461
12589
  continue;
12462
12590
  if (msg.model && typeof msg.model === "string") {
@@ -12522,7 +12650,7 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
12522
12650
  }
12523
12651
  }
12524
12652
  }
12525
- const toolResult = obj.toolUseResult;
12653
+ const toolResult = obj2.toolUseResult;
12526
12654
  if (toolResult && typeof toolResult === "object" && toolCount < maxMessages) {
12527
12655
  const resultText2 = toolResult.result;
12528
12656
  const query = toolResult.query;
@@ -12611,10 +12739,10 @@ async function parseMessagesFromFile(sessionPath) {
12611
12739
  }
12612
12740
  function messagesFromRawLines(raw) {
12613
12741
  const toolResults = /* @__PURE__ */ new Map();
12614
- for (const { obj } of raw) {
12615
- if (obj?.type !== "user")
12742
+ for (const { obj: obj2 } of raw) {
12743
+ if (obj2?.type !== "user")
12616
12744
  continue;
12617
- const content = obj.message?.content;
12745
+ const content = obj2.message?.content;
12618
12746
  if (!Array.isArray(content))
12619
12747
  continue;
12620
12748
  for (const block of content) {
@@ -12627,12 +12755,12 @@ function messagesFromRawLines(raw) {
12627
12755
  }
12628
12756
  }
12629
12757
  const messages = [];
12630
- for (const { line, obj } of raw) {
12631
- if (!obj || typeof obj !== "object")
12758
+ for (const { line, obj: obj2 } of raw) {
12759
+ if (!obj2 || typeof obj2 !== "object")
12632
12760
  continue;
12633
- const timestamp = typeof obj.timestamp === "string" ? obj.timestamp : void 0;
12634
- if (obj.type === "user") {
12635
- const content = obj.message?.content;
12761
+ const timestamp = typeof obj2.timestamp === "string" ? obj2.timestamp : void 0;
12762
+ if (obj2.type === "user") {
12763
+ const content = obj2.message?.content;
12636
12764
  let text = "";
12637
12765
  if (typeof content === "string") {
12638
12766
  text = content;
@@ -12644,18 +12772,18 @@ function messagesFromRawLines(raw) {
12644
12772
  const cleaned = stripBanners2(text);
12645
12773
  if (!cleaned)
12646
12774
  continue;
12647
- const origin = userRecordOrigin(obj, cleaned);
12775
+ const origin = userRecordOrigin(obj2, cleaned);
12648
12776
  messages.push({ line, role: "user", content: cleaned, timestamp, ...origin === "human" ? {} : { origin } });
12649
- } else if (obj.type === "attachment") {
12650
- const queued = queuedCommandPrompt(obj);
12777
+ } else if (obj2.type === "attachment") {
12778
+ const queued = queuedCommandPrompt(obj2);
12651
12779
  if (!queued)
12652
12780
  continue;
12653
12781
  const cleaned = stripBanners2(queued.text);
12654
12782
  if (!cleaned)
12655
12783
  continue;
12656
12784
  messages.push({ line, role: "user", content: cleaned, timestamp, ...queued.origin === "human" ? {} : { origin: queued.origin } });
12657
- } else if (obj.type === "assistant") {
12658
- const blocks = Array.isArray(obj.message?.content) ? obj.message.content : [];
12785
+ } else if (obj2.type === "assistant") {
12786
+ const blocks = Array.isArray(obj2.message?.content) ? obj2.message.content : [];
12659
12787
  const thinkingBlock = blocks.find((c) => c?.type === "thinking");
12660
12788
  const textBlock = blocks.find((c) => c?.type === "text");
12661
12789
  const toolUses = blocks.filter((c) => c?.type === "tool_use");
@@ -12681,10 +12809,10 @@ function messagesFromRawLines(raw) {
12681
12809
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
12682
12810
  timestamp
12683
12811
  });
12684
- } else if (obj.type === "summary" && typeof obj.summary === "string") {
12685
- messages.push({ line, role: "summary", content: obj.summary });
12686
- } else if (obj.type === "system" && obj.subtype === "away_summary") {
12687
- const c = obj.content;
12812
+ } else if (obj2.type === "summary" && typeof obj2.summary === "string") {
12813
+ messages.push({ line, role: "summary", content: obj2.summary });
12814
+ } else if (obj2.type === "system" && obj2.subtype === "away_summary") {
12815
+ const c = obj2.content;
12688
12816
  const text = typeof c === "string" ? c : Array.isArray(c) ? c.filter((b) => b?.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n") : "";
12689
12817
  if (text.trim())
12690
12818
  messages.push({ line, role: "summary", content: stripBanners2(text), timestamp });
@@ -12882,31 +13010,31 @@ function parseCodexTranscriptText(text) {
12882
13010
  if (!line.trim())
12883
13011
  continue;
12884
13012
  try {
12885
- const obj = JSON.parse(line);
12886
- if (obj.type === "event_msg" && obj.payload?.type === "user_message") {
12887
- const text2 = String(obj.payload.message || "").trim();
13013
+ const obj2 = JSON.parse(line);
13014
+ if (obj2.type === "event_msg" && obj2.payload?.type === "user_message") {
13015
+ const text2 = String(obj2.payload.message || "").trim();
12888
13016
  if (!text2 || isCodexInjectedWrapper2(text2))
12889
13017
  continue;
12890
13018
  messages.push({
12891
13019
  line: lineNum,
12892
13020
  role: "user",
12893
13021
  content: text2,
12894
- timestamp: obj.timestamp
13022
+ timestamp: obj2.timestamp
12895
13023
  });
12896
- } else if (obj.type === "response_item" && obj.payload?.type === "message") {
12897
- if (obj.payload.role !== "assistant")
13024
+ } else if (obj2.type === "response_item" && obj2.payload?.type === "message") {
13025
+ if (obj2.payload.role !== "assistant")
12898
13026
  continue;
12899
- const text2 = flattenCodexContent(obj.payload.content);
13027
+ const text2 = flattenCodexContent(obj2.payload.content);
12900
13028
  if (!text2.trim())
12901
13029
  continue;
12902
13030
  messages.push({
12903
13031
  line: lineNum,
12904
13032
  role: "assistant",
12905
13033
  content: text2,
12906
- timestamp: obj.timestamp
13034
+ timestamp: obj2.timestamp
12907
13035
  });
12908
- } else if (obj.type === "response_item" && obj.payload?.type === "reasoning") {
12909
- const summary = Array.isArray(obj.payload.summary) ? obj.payload.summary.map((s) => s?.text || "").filter(Boolean).join("\n") : "";
13036
+ } else if (obj2.type === "response_item" && obj2.payload?.type === "reasoning") {
13037
+ const summary = Array.isArray(obj2.payload.summary) ? obj2.payload.summary.map((s) => s?.text || "").filter(Boolean).join("\n") : "";
12910
13038
  if (!summary.trim())
12911
13039
  continue;
12912
13040
  messages.push({
@@ -12914,10 +13042,10 @@ function parseCodexTranscriptText(text) {
12914
13042
  role: "assistant",
12915
13043
  content: "",
12916
13044
  thinking: summary,
12917
- timestamp: obj.timestamp
13045
+ timestamp: obj2.timestamp
12918
13046
  });
12919
- } else if (obj.type === "response_item" && obj.payload?.type === "function_call") {
12920
- let input = obj.payload.arguments || {};
13047
+ } else if (obj2.type === "response_item" && obj2.payload?.type === "function_call") {
13048
+ let input = obj2.payload.arguments || {};
12921
13049
  if (typeof input === "string") {
12922
13050
  try {
12923
13051
  input = JSON.parse(input);
@@ -12928,8 +13056,8 @@ function parseCodexTranscriptText(text) {
12928
13056
  line: lineNum,
12929
13057
  role: "assistant",
12930
13058
  content: "",
12931
- toolCalls: [{ name: obj.payload.name || "", input }],
12932
- timestamp: obj.timestamp
13059
+ toolCalls: [{ name: obj2.payload.name || "", input }],
13060
+ timestamp: obj2.timestamp
12933
13061
  });
12934
13062
  }
12935
13063
  } catch {
@@ -13203,19 +13331,19 @@ function mapJsonStrings(line, fn, escapedOnly) {
13203
13331
  const q = line.indexOf('"', i);
13204
13332
  if (q < 0)
13205
13333
  return out + line.slice(i);
13206
- let j = q + 1;
13207
- while (j < line.length) {
13208
- const c = line.charCodeAt(j);
13334
+ let j2 = q + 1;
13335
+ while (j2 < line.length) {
13336
+ const c = line.charCodeAt(j2);
13209
13337
  if (c === 92)
13210
- j += 2;
13338
+ j2 += 2;
13211
13339
  else if (c === 34)
13212
13340
  break;
13213
13341
  else
13214
- j++;
13342
+ j2++;
13215
13343
  }
13216
- const token = line.slice(q, j + 1);
13344
+ const token = line.slice(q, j2 + 1);
13217
13345
  out += line.slice(i, q);
13218
- i = j + 1;
13346
+ i = j2 + 1;
13219
13347
  const body2 = token.slice(1, -1);
13220
13348
  const escaped = body2.includes("\\");
13221
13349
  if (escapedOnly && !escaped) {
@@ -13374,7 +13502,7 @@ async function archiveRawSession(store2, sessionId) {
13374
13502
  }
13375
13503
  function detectForkPredecessor(sessionPath) {
13376
13504
  const { readFileSync: readFileSync51, readdirSync: readdirSync35 } = requireFs();
13377
- const { dirname: dirname22, join: join62, basename: basename26 } = requirePath();
13505
+ const { dirname: dirname22, join: join63, basename: basename26 } = requirePath();
13378
13506
  let text;
13379
13507
  try {
13380
13508
  text = readFileSync51(sessionPath, "utf-8");
@@ -13411,7 +13539,7 @@ function detectForkPredecessor(sessionPath) {
13411
13539
  if (!f.endsWith(".jsonl") || f === self || f === "sessions-index.json")
13412
13540
  continue;
13413
13541
  try {
13414
- if (readFileSync51(join62(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
13542
+ if (readFileSync51(join63(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
13415
13543
  return basename26(f, ".jsonl");
13416
13544
  }
13417
13545
  } catch {
@@ -13957,7 +14085,7 @@ async function parseOpenCodeSubagents(parentSessionId) {
13957
14085
  if (!existsSync52(dbPath))
13958
14086
  return [];
13959
14087
  const realParent = parentSessionId.replace("opencode_", "");
13960
- const db = openSqliteReadonlyOrThrow(dbPath);
14088
+ const db = openOpencodeDbOrThrow(dbPath);
13961
14089
  try {
13962
14090
  const children = db.prepare(`
13963
14091
  SELECT id, title, time_created
@@ -14001,16 +14129,16 @@ async function parseOpenCodeTranscript(sessionId) {
14001
14129
  if (!existsSync52(dbPath))
14002
14130
  return [];
14003
14131
  const realId = sessionId.replace("opencode_", "");
14004
- const db = openSqliteReadonlyOrThrow(dbPath);
14132
+ const db = openOpencodeDbOrThrow(dbPath);
14005
14133
  const messages = [];
14006
14134
  try {
14007
14135
  const parts = db.prepare(`
14008
14136
  SELECT p.data, p.time_created, m.data as msg_data
14009
14137
  FROM part p
14010
- JOIN message m ON p.message_id = m.id
14138
+ JOIN (SELECT id, data FROM message WHERE session_id = ?) m ON p.message_id = m.id
14011
14139
  WHERE p.session_id = ?
14012
14140
  ORDER BY p.time_created ASC
14013
- `).all(realId);
14141
+ `).all(realId, realId);
14014
14142
  let lineNum = 0;
14015
14143
  for (const part of parts) {
14016
14144
  try {
@@ -14041,7 +14169,7 @@ var log4;
14041
14169
  var init_opencode2 = __esm({
14042
14170
  "../engine/dist/transcript/opencode.js"() {
14043
14171
  "use strict";
14044
- init_sqlite_reader();
14172
+ init_opencode_v2();
14045
14173
  init_logger();
14046
14174
  log4 = createLogger("transcript-opencode");
14047
14175
  }
@@ -15225,19 +15353,19 @@ function runTrufflehog(binary, filePath, opts = {}) {
15225
15353
  if (!line.trim())
15226
15354
  continue;
15227
15355
  try {
15228
- const j = JSON.parse(line);
15229
- const raw = j.Raw || "";
15356
+ const j2 = JSON.parse(line);
15357
+ const raw = j2.Raw || "";
15230
15358
  if (looksLikeUuid(raw))
15231
15359
  continue;
15232
15360
  out.push({
15233
- rule: j.DetectorName || "unknown",
15234
- line: j.SourceMetadata?.Data?.Filesystem?.line || 0,
15361
+ rule: j2.DetectorName || "unknown",
15362
+ line: j2.SourceMetadata?.Data?.Filesystem?.line || 0,
15235
15363
  preview: mask(raw),
15236
15364
  // trufflehog reports `Verified: true` only when --verification
15237
15365
  // ran AND the call succeeded. With --only-verified set, every
15238
15366
  // returned finding is verified live by definition, so we tag
15239
15367
  // them all true; with --no-verification, leave undefined.
15240
- verified: opts.verifyOnly ? true : j.Verified === true ? true : void 0
15368
+ verified: opts.verifyOnly ? true : j2.Verified === true ? true : void 0
15241
15369
  });
15242
15370
  } catch {
15243
15371
  }
@@ -15290,16 +15418,16 @@ function runTrufflehogDir(binary, dir, opts = {}) {
15290
15418
  if (!line.trim())
15291
15419
  continue;
15292
15420
  try {
15293
- const j = JSON.parse(line);
15294
- const raw = j.Raw || "";
15421
+ const j2 = JSON.parse(line);
15422
+ const raw = j2.Raw || "";
15295
15423
  if (looksLikeUuid(raw))
15296
15424
  continue;
15297
15425
  out.push({
15298
- rule: j.DetectorName || "unknown",
15299
- line: j.SourceMetadata?.Data?.Filesystem?.line || 0,
15426
+ rule: j2.DetectorName || "unknown",
15427
+ line: j2.SourceMetadata?.Data?.Filesystem?.line || 0,
15300
15428
  preview: mask(raw),
15301
- verified: opts.verifyOnly ? true : j.Verified === true ? true : void 0,
15302
- file: j.SourceMetadata?.Data?.Filesystem?.file || ""
15429
+ verified: opts.verifyOnly ? true : j2.Verified === true ? true : void 0,
15430
+ file: j2.SourceMetadata?.Data?.Filesystem?.file || ""
15303
15431
  });
15304
15432
  } catch {
15305
15433
  }
@@ -16103,16 +16231,16 @@ async function collectCode(opts) {
16103
16231
  ...blastTargets.map((f, i) => call(2e3 + i, "plan_change", { file: f, format: "json" }))
16104
16232
  ]);
16105
16233
  blastTargets.forEach((f, i) => {
16106
- const j = parseJson(pc, 2e3 + i, null);
16107
- if (j && typeof j === "object" && typeof j.fan_in === "number") {
16234
+ const j2 = parseJson(pc, 2e3 + i, null);
16235
+ if (j2 && typeof j2 === "object" && typeof j2.fan_in === "number") {
16108
16236
  blast[f] = {
16109
- fileRole: j.file_role ?? "regular",
16110
- fanIn: j.fan_in ?? 0,
16111
- fanOut: j.fan_out ?? 0,
16112
- direct: j.direct ?? 0,
16113
- transitive: j.transitive ?? 0,
16114
- maxDepth: j.max_depth ?? 0,
16115
- directFiles: Array.isArray(j.direct_files) ? j.direct_files.map(rel).slice(0, 20) : void 0
16237
+ fileRole: j2.file_role ?? "regular",
16238
+ fanIn: j2.fan_in ?? 0,
16239
+ fanOut: j2.fan_out ?? 0,
16240
+ direct: j2.direct ?? 0,
16241
+ transitive: j2.transitive ?? 0,
16242
+ maxDepth: j2.max_depth ?? 0,
16243
+ directFiles: Array.isArray(j2.direct_files) ? j2.direct_files.map(rel).slice(0, 20) : void 0
16116
16244
  };
16117
16245
  }
16118
16246
  });
@@ -19077,7 +19205,7 @@ var MAX_CHUNK_CHARS8, OpenCodeSource;
19077
19205
  var init_opencode_source = __esm({
19078
19206
  "../engine/dist/parsers/opencode-source.js"() {
19079
19207
  "use strict";
19080
- init_sqlite_reader();
19208
+ init_opencode_v2();
19081
19209
  init_opencode();
19082
19210
  init_settings();
19083
19211
  MAX_CHUNK_CHARS8 = 2e3;
@@ -19094,7 +19222,7 @@ var init_opencode_source = __esm({
19094
19222
  return;
19095
19223
  let db;
19096
19224
  try {
19097
- db = openSqliteReadonlyOrThrow(this.dbPath);
19225
+ db = openOpencodeDbOrThrow(this.dbPath);
19098
19226
  } catch {
19099
19227
  return;
19100
19228
  }
@@ -19191,17 +19319,17 @@ var init_opencode_source = __esm({
19191
19319
  if (!existsSync34(this.dbPath))
19192
19320
  return [];
19193
19321
  const sessionId = item.id.replace("opencode_", "");
19194
- const db = openSqliteReadonlyOrThrow(this.dbPath);
19322
+ const db = openOpencodeDbOrThrow(this.dbPath);
19195
19323
  const chunks = [];
19196
19324
  try {
19197
19325
  const parts = db.prepare(`
19198
19326
  SELECT p.data, m.data as msg_data
19199
19327
  FROM part p
19200
- JOIN message m ON p.message_id = m.id
19328
+ JOIN (SELECT id, data FROM message WHERE session_id = ?) m ON p.message_id = m.id
19201
19329
  WHERE p.session_id = ?
19202
19330
  AND (p.data LIKE '%"type":"text"%' OR p.data LIKE '%"type":"reasoning"%')
19203
19331
  ORDER BY p.time_created ASC
19204
- `).all(sessionId);
19332
+ `).all(sessionId, sessionId);
19205
19333
  const userTexts = [];
19206
19334
  const assistantTexts = [];
19207
19335
  for (const part of parts) {
@@ -19265,7 +19393,7 @@ var OpenCodeTodoSource;
19265
19393
  var init_opencode_todo_source = __esm({
19266
19394
  "../engine/dist/parsers/opencode-todo-source.js"() {
19267
19395
  "use strict";
19268
- init_sqlite_reader();
19396
+ init_opencode_v2();
19269
19397
  init_opencode();
19270
19398
  init_settings();
19271
19399
  OpenCodeTodoSource = class {
@@ -19281,7 +19409,7 @@ var init_opencode_todo_source = __esm({
19281
19409
  return;
19282
19410
  let db;
19283
19411
  try {
19284
- db = openSqliteReadonlyOrThrow(this.dbPath);
19412
+ db = openOpencodeDbOrThrow(this.dbPath);
19285
19413
  } catch {
19286
19414
  return;
19287
19415
  }
@@ -19329,7 +19457,7 @@ var init_opencode_todo_source = __esm({
19329
19457
  if (!existsSync35(this.dbPath))
19330
19458
  return [];
19331
19459
  const sessionId = item.extra?.sessionId || item.id.replace(`${opencodeBackend.idPrefix}todo_`, "");
19332
- const db = openSqliteReadonlyOrThrow(this.dbPath);
19460
+ const db = openOpencodeDbOrThrow(this.dbPath);
19333
19461
  const chunks = [];
19334
19462
  try {
19335
19463
  const todos = db.prepare(`
@@ -20438,7 +20566,7 @@ var require_anchors = __commonJS({
20438
20566
  var require_applyReviver = __commonJS({
20439
20567
  "../../node_modules/yaml/dist/doc/applyReviver.js"(exports) {
20440
20568
  "use strict";
20441
- function applyReviver(reviver, obj, key2, val) {
20569
+ function applyReviver(reviver, obj2, key2, val) {
20442
20570
  if (val && typeof val === "object") {
20443
20571
  if (Array.isArray(val)) {
20444
20572
  for (let i = 0, len = val.length; i < len; ++i) {
@@ -20478,7 +20606,7 @@ var require_applyReviver = __commonJS({
20478
20606
  }
20479
20607
  }
20480
20608
  }
20481
- return reviver.call(obj, key2, val);
20609
+ return reviver.call(obj2, key2, val);
20482
20610
  }
20483
20611
  exports.applyReviver = applyReviver;
20484
20612
  }
@@ -21013,12 +21141,12 @@ var require_foldFlowLines = __commonJS({
21013
21141
  ch = text[i += 1];
21014
21142
  overflow = true;
21015
21143
  }
21016
- const j = i > escEnd + 1 ? i - 2 : escStart - 1;
21017
- if (escapedFolds[j])
21144
+ const j2 = i > escEnd + 1 ? i - 2 : escStart - 1;
21145
+ if (escapedFolds[j2])
21018
21146
  return text;
21019
- folds.push(j);
21020
- escapedFolds[j] = true;
21021
- end = j + endStep;
21147
+ folds.push(j2);
21148
+ escapedFolds[j2] = true;
21149
+ end = j2 + endStep;
21022
21150
  split = void 0;
21023
21151
  } else {
21024
21152
  overflow = true;
@@ -21414,10 +21542,10 @@ var require_stringify = __commonJS({
21414
21542
  return match.find((t) => t.format === item.format) ?? match[0];
21415
21543
  }
21416
21544
  let tagObj = void 0;
21417
- let obj;
21545
+ let obj2;
21418
21546
  if (identity.isScalar(item)) {
21419
- obj = item.value;
21420
- let match = tags.filter((t) => t.identify?.(obj));
21547
+ obj2 = item.value;
21548
+ let match = tags.filter((t) => t.identify?.(obj2));
21421
21549
  if (match.length > 1) {
21422
21550
  const testMatch = match.filter((t) => t.test);
21423
21551
  if (testMatch.length > 0)
@@ -21425,11 +21553,11 @@ var require_stringify = __commonJS({
21425
21553
  }
21426
21554
  tagObj = match.find((t) => t.format === item.format) ?? match.find((t) => !t.format);
21427
21555
  } else {
21428
- obj = item;
21429
- tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass);
21556
+ obj2 = item;
21557
+ tagObj = tags.find((t) => t.nodeClass && obj2 instanceof t.nodeClass);
21430
21558
  }
21431
21559
  if (!tagObj) {
21432
- const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
21560
+ const name = obj2?.constructor?.name ?? (obj2 === null ? "null" : typeof obj2);
21433
21561
  throw new Error(`Tag not resolved for ${name} value`);
21434
21562
  }
21435
21563
  return tagObj;
@@ -21985,23 +22113,23 @@ var require_YAMLMap = __commonJS({
21985
22113
  * A generic collection parsing method that can be extended
21986
22114
  * to other node classes that inherit from YAMLMap
21987
22115
  */
21988
- static from(schema, obj, ctx) {
22116
+ static from(schema, obj2, ctx) {
21989
22117
  const { keepUndefined, replacer } = ctx;
21990
22118
  const map = new this(schema);
21991
22119
  const add = (key2, value) => {
21992
22120
  if (typeof replacer === "function")
21993
- value = replacer.call(obj, key2, value);
22121
+ value = replacer.call(obj2, key2, value);
21994
22122
  else if (Array.isArray(replacer) && !replacer.includes(key2))
21995
22123
  return;
21996
22124
  if (value !== void 0 || keepUndefined)
21997
22125
  map.items.push(Pair.createPair(key2, value, ctx));
21998
22126
  };
21999
- if (obj instanceof Map) {
22000
- for (const [key2, value] of obj)
22127
+ if (obj2 instanceof Map) {
22128
+ for (const [key2, value] of obj2)
22001
22129
  add(key2, value);
22002
- } else if (obj && typeof obj === "object") {
22003
- for (const key2 of Object.keys(obj))
22004
- add(key2, obj[key2]);
22130
+ } else if (obj2 && typeof obj2 === "object") {
22131
+ for (const key2 of Object.keys(obj2))
22132
+ add(key2, obj2[key2]);
22005
22133
  }
22006
22134
  if (typeof schema.sortMapEntries === "function") {
22007
22135
  map.items.sort(schema.sortMapEntries);
@@ -22111,7 +22239,7 @@ var require_map = __commonJS({
22111
22239
  onError("Expected a mapping for this tag");
22112
22240
  return map2;
22113
22241
  },
22114
- createNode: (schema, obj, ctx) => YAMLMap.YAMLMap.from(schema, obj, ctx)
22242
+ createNode: (schema, obj2, ctx) => YAMLMap.YAMLMap.from(schema, obj2, ctx)
22115
22243
  };
22116
22244
  exports.map = map;
22117
22245
  }
@@ -22207,15 +22335,15 @@ var require_YAMLSeq = __commonJS({
22207
22335
  onComment
22208
22336
  });
22209
22337
  }
22210
- static from(schema, obj, ctx) {
22338
+ static from(schema, obj2, ctx) {
22211
22339
  const { replacer } = ctx;
22212
22340
  const seq = new this(schema);
22213
- if (obj && Symbol.iterator in Object(obj)) {
22341
+ if (obj2 && Symbol.iterator in Object(obj2)) {
22214
22342
  let i = 0;
22215
- for (let it of obj) {
22343
+ for (let it of obj2) {
22216
22344
  if (typeof replacer === "function") {
22217
- const key2 = obj instanceof Set ? it : String(i++);
22218
- it = replacer.call(obj, key2, it);
22345
+ const key2 = obj2 instanceof Set ? it : String(i++);
22346
+ it = replacer.call(obj2, key2, it);
22219
22347
  }
22220
22348
  seq.items.push(createNode.createNode(it, void 0, ctx));
22221
22349
  }
@@ -22249,7 +22377,7 @@ var require_seq = __commonJS({
22249
22377
  onError("Expected a sequence for this tag");
22250
22378
  return seq2;
22251
22379
  },
22252
- createNode: (schema, obj, ctx) => YAMLSeq.YAMLSeq.from(schema, obj, ctx)
22380
+ createNode: (schema, obj2, ctx) => YAMLSeq.YAMLSeq.from(schema, obj2, ctx)
22253
22381
  };
22254
22382
  exports.seq = seq;
22255
22383
  }
@@ -27468,15 +27596,15 @@ var init_mcps_source = __esm({
27468
27596
  });
27469
27597
  }
27470
27598
  }
27471
- async *fromObject(obj, ctx) {
27472
- if (!obj || typeof obj !== "object")
27599
+ async *fromObject(obj2, ctx) {
27600
+ if (!obj2 || typeof obj2 !== "object")
27473
27601
  return;
27474
27602
  let mtime = 0;
27475
27603
  try {
27476
27604
  mtime = statSync37(ctx.filePath).mtimeMs;
27477
27605
  } catch {
27478
27606
  }
27479
- for (const [name, cfgRaw] of Object.entries(obj)) {
27607
+ for (const [name, cfgRaw] of Object.entries(obj2)) {
27480
27608
  const cfg = cfgRaw || {};
27481
27609
  const cmd = redactInlineSecrets(commandPreview(cfg)).text;
27482
27610
  const allow = Array.isArray(cfg.alwaysAllow) ? cfg.alwaysAllow.slice(0, 8) : [];
@@ -28848,7 +28976,7 @@ var init_http = __esm({
28848
28976
  CLI_VERSION = JSON.parse(readFileSync41(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
28849
28977
  } catch {
28850
28978
  try {
28851
- if (true) CLI_VERSION = "0.7.21";
28979
+ if (true) CLI_VERSION = "0.7.24";
28852
28980
  } catch {
28853
28981
  }
28854
28982
  }
@@ -29232,7 +29360,7 @@ function serverAllowsTelemetry(serverUrl) {
29232
29360
  function mayReport(serverUrl) {
29233
29361
  return userConsents() && serverAllowsTelemetry(serverUrl);
29234
29362
  }
29235
- function findSensitiveKeys(obj, where = "") {
29363
+ function findSensitiveKeys(obj2, where = "") {
29236
29364
  const out = [];
29237
29365
  const walk = (v, at) => {
29238
29366
  if (!v || typeof v !== "object") return;
@@ -29245,7 +29373,7 @@ function findSensitiveKeys(obj, where = "") {
29245
29373
  walk(val, at ? `${at}.${k}` : k);
29246
29374
  }
29247
29375
  };
29248
- walk(obj, where);
29376
+ walk(obj2, where);
29249
29377
  return out;
29250
29378
  }
29251
29379
  function assertNoSensitiveKeys(payload) {
@@ -29346,7 +29474,7 @@ var init_telemetry = __esm({
29346
29474
  init_sync_client();
29347
29475
  cliVersion2 = () => {
29348
29476
  try {
29349
- return true ? "0.7.21" : "dev";
29477
+ return true ? "0.7.24" : "dev";
29350
29478
  } catch {
29351
29479
  return "dev";
29352
29480
  }
@@ -31741,7 +31869,7 @@ var init_sync_client = __esm({
31741
31869
  ownVersion = JSON.parse(readFileSync44(join55(dir, "../package.json"), "utf-8")).version || ownVersion;
31742
31870
  } catch {
31743
31871
  try {
31744
- if (true) ownVersion = "0.7.21";
31872
+ if (true) ownVersion = "0.7.24";
31745
31873
  } catch {
31746
31874
  }
31747
31875
  }
@@ -32563,6 +32691,7 @@ __export(guard_registration_exports, {
32563
32691
  guardTargets: () => guardTargets,
32564
32692
  guardWrapperName: () => guardWrapperName,
32565
32693
  guardWrapperSource: () => guardWrapperSource,
32694
+ legacyAgyHooksFile: () => legacyAgyHooksFile,
32566
32695
  opencodeConfigDir: () => opencodeConfigDir,
32567
32696
  opencodePluginDir: () => opencodePluginDir,
32568
32697
  opencodePluginSource: () => opencodePluginSource,
@@ -32571,6 +32700,9 @@ __export(guard_registration_exports, {
32571
32700
  });
32572
32701
  import { homedir as homedir20 } from "os";
32573
32702
  import { join as join60 } from "path";
32703
+ function legacyAgyHooksFile() {
32704
+ return join60(agyBackend.homeDir(), "hooks.json");
32705
+ }
32574
32706
  function opencodeConfigDir() {
32575
32707
  const xdg = process.env.XDG_CONFIG_HOME;
32576
32708
  const base2 = xdg && xdg.trim() ? xdg : join60(homedir20(), ".config");
@@ -32597,7 +32729,7 @@ function guardTargets() {
32597
32729
  {
32598
32730
  tool: "agy",
32599
32731
  label: "Antigravity",
32600
- configPath: join60(agyBackend.homeDir(), "hooks.json"),
32732
+ configPath: agyBackend.sharedHooksFile(),
32601
32733
  homeDir: agyBackend.homeDir()
32602
32734
  },
32603
32735
  {
@@ -32747,14 +32879,24 @@ function ask(payload) {
32747
32879
  });
32748
32880
  }
32749
32881
 
32750
- export const ChatRecallGuard = async () => ({
32751
- "tool.execute.before": async (input, output) => {
32752
- const verdict = await ask({ tool: input?.tool, args: output?.args });
32753
- if (!verdict || !verdict.message) return;
32754
- if (verdict.block) throw new Error(verdict.message);
32755
- console.error(verdict.message);
32756
- },
32757
- });
32882
+ async function check(tool, args) {
32883
+ const verdict = await ask({ tool, args });
32884
+ if (!verdict || !verdict.message) return;
32885
+ if (verdict.block) throw new Error(verdict.message);
32886
+ console.error(verdict.message);
32887
+ }
32888
+
32889
+ async function setup(ctx) {
32890
+ await ctx.tool.hook("execute.before", (event) => check(event?.tool, event?.input));
32891
+ }
32892
+
32893
+ async function server() {
32894
+ return {
32895
+ "tool.execute.before": (input, output) => check(input?.tool, output?.args),
32896
+ };
32897
+ }
32898
+
32899
+ export default { id: "${GUARD_ID}", server, setup };
32758
32900
  `;
32759
32901
  }
32760
32902
  var GUARD_ID, AGY_MATCHER, CODEX_MATCHER, TIMEOUT_SECS, isOurs, asArray2;
@@ -32771,6 +32913,383 @@ var init_guard_registration = __esm({
32771
32913
  }
32772
32914
  });
32773
32915
 
32916
+ // ../engine/dist/core/message-registration.js
32917
+ var message_registration_exports = {};
32918
+ __export(message_registration_exports, {
32919
+ MESSAGES_ID: () => MESSAGES_ID,
32920
+ isOurPluginSource: () => isOurPluginSource,
32921
+ messageCommand: () => messageCommand,
32922
+ messageTargets: () => messageTargets,
32923
+ messageWrapperName: () => messageWrapperName,
32924
+ messageWrapperSource: () => messageWrapperSource,
32925
+ opencodeMessagesSource: () => opencodeMessagesSource,
32926
+ piAgentDir: () => piAgentDir,
32927
+ piMessagesSource: () => piMessagesSource,
32928
+ registerMessages: () => registerMessages,
32929
+ unregisterMessages: () => unregisterMessages
32930
+ });
32931
+ import { homedir as homedir21 } from "os";
32932
+ import { join as join61 } from "path";
32933
+ function piAgentDir() {
32934
+ const dir = process.env.PI_CODING_AGENT_DIR;
32935
+ return dir && dir.trim() ? dir : join61(homedir21(), ".pi", "agent");
32936
+ }
32937
+ function messageTargets() {
32938
+ return [
32939
+ {
32940
+ tool: "codex",
32941
+ label: "Codex",
32942
+ configPath: join61(codexBackend.homeDir(), "hooks.json"),
32943
+ homeDir: codexBackend.homeDir(),
32944
+ // Codex binds its approval to the hook's hash, and only a person can give it.
32945
+ note: "Codex asks you to approve a hook before it runs one. Run /hooks in Codex once to approve the message hook."
32946
+ },
32947
+ {
32948
+ tool: "agy",
32949
+ label: "Antigravity",
32950
+ configPath: agyBackend.sharedHooksFile(),
32951
+ homeDir: agyBackend.homeDir()
32952
+ },
32953
+ {
32954
+ tool: "cursor",
32955
+ label: "Cursor",
32956
+ configPath: join61(cursorBackend.homeDir(), "hooks.json"),
32957
+ homeDir: cursorBackend.homeDir(),
32958
+ note: "Cursor delivers a message at the start of a session and when the agent stops, as a follow-up prompt."
32959
+ },
32960
+ {
32961
+ tool: "opencode",
32962
+ label: "OpenCode",
32963
+ configPath: join61(opencodePluginDir(), `${MESSAGES_ID}.js`),
32964
+ homeDir: opencodeConfigDir()
32965
+ },
32966
+ {
32967
+ tool: "pi",
32968
+ label: "pi",
32969
+ configPath: join61(piAgentDir(), "extensions", `${MESSAGES_ID}.js`),
32970
+ homeDir: piAgentDir()
32971
+ }
32972
+ ];
32973
+ }
32974
+ function messageWrapperName(tool) {
32975
+ return `chat_recall_messages_${tool}.sh`;
32976
+ }
32977
+ function messageWrapperSource(tool, nodePath, hookEntry) {
32978
+ return `#!/bin/sh
32979
+ # Written by \`chat-recall install-hooks\`. Re-running replaces it.
32980
+ exec ${JSON.stringify(nodePath)} ${JSON.stringify(hookEntry)} --tool ${tool} "$@"
32981
+ `;
32982
+ }
32983
+ function messageCommand(wrapperPath, args = "") {
32984
+ const p = wrapperPath.includes(" ") ? `"${wrapperPath}"` : wrapperPath;
32985
+ return args ? `${p} ${args}` : p;
32986
+ }
32987
+ function mergeCodex2(config2, command) {
32988
+ const c = obj(config2);
32989
+ const hooks = obj(c.hooks);
32990
+ for (const event of CODEX_EVENTS) {
32991
+ const kept = asArray3(hooks[event]).filter((e) => !asArray3(e?.hooks).some((h) => isOurs2(h?.command)));
32992
+ kept.push({ hooks: [{ type: "command", command, timeout: TIMEOUT_SECS2 }] });
32993
+ hooks[event] = kept;
32994
+ }
32995
+ c.hooks = hooks;
32996
+ return c;
32997
+ }
32998
+ function stripCodex2(config2) {
32999
+ const c = obj(config2);
33000
+ const hooks = obj(c.hooks);
33001
+ let removed = 0;
33002
+ for (const event of CODEX_EVENTS) {
33003
+ const before = asArray3(hooks[event]);
33004
+ const kept = before.filter((e) => !asArray3(e?.hooks).some((h) => isOurs2(h?.command)));
33005
+ removed += before.length - kept.length;
33006
+ if (kept.length)
33007
+ hooks[event] = kept;
33008
+ else
33009
+ delete hooks[event];
33010
+ }
33011
+ if (Object.keys(hooks).length)
33012
+ c.hooks = hooks;
33013
+ else
33014
+ delete c.hooks;
33015
+ return { config: c, removed };
33016
+ }
33017
+ function mergeAgy2(config2, command) {
33018
+ const c = obj(config2);
33019
+ const run2 = (event) => [{ type: "command", command: `${command} --event ${event}`, timeout: TIMEOUT_SECS2 }];
33020
+ c[MESSAGES_ID] = {
33021
+ enabled: true,
33022
+ SessionStart: run2("SessionStart"),
33023
+ PreInvocation: run2("PreInvocation"),
33024
+ Stop: run2("Stop")
33025
+ };
33026
+ return c;
33027
+ }
33028
+ function stripAgy2(config2) {
33029
+ const c = obj(config2);
33030
+ const had = Object.prototype.hasOwnProperty.call(c, MESSAGES_ID) ? 1 : 0;
33031
+ delete c[MESSAGES_ID];
33032
+ return { config: c, removed: had };
33033
+ }
33034
+ function mergeCursor2(config2, command) {
33035
+ const c = obj(config2);
33036
+ c.version = typeof c.version === "number" ? c.version : 1;
33037
+ const hooks = obj(c.hooks);
33038
+ for (const event of CURSOR_EVENTS) {
33039
+ const kept = asArray3(hooks[event]).filter((e) => !isOurs2(e?.command));
33040
+ kept.push({ command, timeout: TIMEOUT_SECS2 });
33041
+ hooks[event] = kept;
33042
+ }
33043
+ c.hooks = hooks;
33044
+ return c;
33045
+ }
33046
+ function stripCursor2(config2) {
33047
+ const c = obj(config2);
33048
+ const hooks = obj(c.hooks);
33049
+ let removed = 0;
33050
+ for (const event of CURSOR_EVENTS) {
33051
+ const before = asArray3(hooks[event]);
33052
+ const kept = before.filter((e) => !isOurs2(e?.command));
33053
+ removed += before.length - kept.length;
33054
+ if (kept.length)
33055
+ hooks[event] = kept;
33056
+ else
33057
+ delete hooks[event];
33058
+ }
33059
+ c.hooks = hooks;
33060
+ return { config: c, removed };
33061
+ }
33062
+ function registerMessages(tool, config2, command) {
33063
+ switch (tool) {
33064
+ case "codex":
33065
+ return mergeCodex2(config2, command);
33066
+ case "agy":
33067
+ return mergeAgy2(config2, command);
33068
+ case "cursor":
33069
+ return mergeCursor2(config2, command);
33070
+ }
33071
+ }
33072
+ function unregisterMessages(tool, config2) {
33073
+ switch (tool) {
33074
+ case "codex":
33075
+ return stripCodex2(config2);
33076
+ case "agy":
33077
+ return stripAgy2(config2);
33078
+ case "cursor":
33079
+ return stripCursor2(config2);
33080
+ }
33081
+ }
33082
+ function isOurPluginSource(source) {
33083
+ return source.includes(`${MESSAGES_ID}: written by`);
33084
+ }
33085
+ function runnerSource(wrapperPath) {
33086
+ return `import { spawn } from "child_process";
33087
+
33088
+ const HOOK = ${JSON.stringify(wrapperPath)};
33089
+
33090
+ function runHook(sessionId, event, cwd) {
33091
+ return new Promise((resolve) => {
33092
+ let out = "";
33093
+ let child;
33094
+ try {
33095
+ child = spawn(HOOK, [], { stdio: ["pipe", "pipe", "ignore"] });
33096
+ } catch {
33097
+ resolve("");
33098
+ return;
33099
+ }
33100
+ const done = setTimeout(() => { child.kill(); resolve(""); }, ${TIMEOUT_SECS2 * 1e3});
33101
+ child.stdout.on("data", (c) => { out += c; });
33102
+ child.on("error", () => { clearTimeout(done); resolve(""); });
33103
+ child.on("close", () => { clearTimeout(done); resolve(out.trim()); });
33104
+ child.stdin.end(JSON.stringify({ session_id: sessionId, hook_event_name: event, cwd }));
33105
+ });
33106
+ }
33107
+
33108
+ /**
33109
+ * Wait for a message to an idle session. The hook long-polls the server and
33110
+ * prints the messages when one arrives; onText gets them. One waiter per
33111
+ * session; stopWaiter ends it when the session gets a prompt.
33112
+ */
33113
+ const waiters = new Map();
33114
+
33115
+ function startWaiter(sessionId, cwd, onText) {
33116
+ if (waiters.has(sessionId)) return;
33117
+ let out = "";
33118
+ let child;
33119
+ try {
33120
+ child = spawn(HOOK, ["--wait"], { stdio: ["pipe", "pipe", "ignore"] });
33121
+ } catch {
33122
+ return;
33123
+ }
33124
+ waiters.set(sessionId, child);
33125
+ child.stdout.on("data", (c) => { out += c; });
33126
+ child.on("error", () => { waiters.delete(sessionId); });
33127
+ child.on("close", () => {
33128
+ if (waiters.get(sessionId) === child) waiters.delete(sessionId);
33129
+ const text = out.trim();
33130
+ if (text) Promise.resolve().then(() => onText(text)).catch(() => {});
33131
+ });
33132
+ child.stdin.end(JSON.stringify({ session_id: sessionId, hook_event_name: "Stop", cwd }));
33133
+ }
33134
+
33135
+ function stopWaiter(sessionId) {
33136
+ const child = waiters.get(sessionId);
33137
+ if (!child) return;
33138
+ waiters.delete(sessionId);
33139
+ try { child.kill(); } catch { /* gone */ }
33140
+ }
33141
+ `;
33142
+ }
33143
+ function opencodeMessagesSource(wrapperPath) {
33144
+ return `// ${MESSAGES_ID}: written by \`chat-recall install-hooks\`. Re-running replaces it.
33145
+ //
33146
+ // Reports each opencode session to chat-recall and adds the messages that
33147
+ // other sessions sent it to the next prompt.
33148
+ ${runnerSource(wrapperPath)}
33149
+ const RUN_END = new Set(["session.execution.succeeded", "session.execution.failed", "session.execution.interrupted", "session.idle"]);
33150
+
33151
+ async function setup(ctx) {
33152
+ const dir = ctx?.location?.directory;
33153
+ const started = new Set();
33154
+ const children = new Set();
33155
+ const isChild = async (id) => {
33156
+ if (children.has(id)) return true;
33157
+ try {
33158
+ const s = await ctx.session.get({ sessionID: id });
33159
+ if (s?.parentID) { children.add(id); return true; }
33160
+ } catch { /* unknown: treat as a main session */ }
33161
+ return false;
33162
+ };
33163
+ await ctx.session.hook("prompt", async (event) => {
33164
+ const id = event?.sessionID;
33165
+ if (!id || !event.prompt || (await isChild(id))) return;
33166
+ stopWaiter("opencode_" + id);
33167
+ const parts = [];
33168
+ if (!started.has(id)) {
33169
+ started.add(id);
33170
+ parts.push(await runHook("opencode_" + id, "SessionStart", dir));
33171
+ }
33172
+ parts.push(await runHook("opencode_" + id, "UserPromptSubmit", dir));
33173
+ const text = parts.filter(Boolean).join("\\n\\n");
33174
+ if (text) event.prompt.text = [event.prompt.text, text].filter(Boolean).join("\\n\\n");
33175
+ });
33176
+ const controller = new AbortController();
33177
+ (async () => {
33178
+ try {
33179
+ for await (const ev of ctx.event.subscribe({ signal: controller.signal })) {
33180
+ const id = ev?.data?.sessionID ?? ev?.properties?.sessionID;
33181
+ if (!id || !started.has(id)) continue;
33182
+ if (RUN_END.has(ev.type)) {
33183
+ await runHook("opencode_" + id, "Stop", dir);
33184
+ // An idle session acts on a message from another session by itself:
33185
+ // the text becomes its next prompt.
33186
+ startWaiter("opencode_" + id, dir, (text) => ctx.session.prompt({ sessionID: id, text }));
33187
+ } else if (ev.type === "session.deleted") {
33188
+ started.delete(id);
33189
+ stopWaiter("opencode_" + id);
33190
+ await runHook("opencode_" + id, "SessionEnd", dir);
33191
+ }
33192
+ }
33193
+ } catch { /* the subscription ends with the plugin */ }
33194
+ })();
33195
+ return () => {
33196
+ controller.abort();
33197
+ for (const id of [...waiters.keys()]) stopWaiter(id);
33198
+ };
33199
+ }
33200
+
33201
+ const pending = new Map();
33202
+ const children = new Set();
33203
+ let seq = 0;
33204
+
33205
+ function partId() {
33206
+ seq += 1;
33207
+ return "prt_" + Date.now().toString(16) + seq.toString(16).padStart(4, "0") + "chatrecall";
33208
+ }
33209
+
33210
+ async function server({ directory }) {
33211
+ return {
33212
+ event: async ({ event }) => {
33213
+ const info = event?.properties?.info;
33214
+ if (event?.type === "session.created" && info?.id) {
33215
+ if (info.parentID) { children.add(info.id); return; }
33216
+ const text = await runHook("opencode_" + info.id, "SessionStart", directory);
33217
+ if (text) pending.set(info.id, text);
33218
+ } else if (event?.type === "session.idle" && event.properties?.sessionID && !children.has(event.properties.sessionID)) {
33219
+ await runHook("opencode_" + event.properties.sessionID, "Stop", directory);
33220
+ } else if (event?.type === "session.deleted" && info?.id) {
33221
+ children.delete(info.id);
33222
+ pending.delete(info.id);
33223
+ await runHook("opencode_" + info.id, "SessionEnd", directory);
33224
+ }
33225
+ },
33226
+ "chat.message": async (input, output) => {
33227
+ const id = input?.sessionID;
33228
+ if (!id || children.has(id) || !output?.message) return;
33229
+ const before = pending.get(id) ?? "";
33230
+ pending.delete(id);
33231
+ const now = await runHook("opencode_" + id, "UserPromptSubmit", directory);
33232
+ const text = [before, now].filter(Boolean).join("\\n\\n");
33233
+ if (!text) return;
33234
+ output.parts.push({ id: partId(), sessionID: id, messageID: output.message.id, type: "text", text, synthetic: true });
33235
+ },
33236
+ };
33237
+ }
33238
+
33239
+ export default { id: "${MESSAGES_ID}", server, setup };
33240
+ `;
33241
+ }
33242
+ function piMessagesSource(wrapperPath) {
33243
+ return `// ${MESSAGES_ID}: written by \`chat-recall install-hooks\`. Re-running replaces it.
33244
+ //
33245
+ // Reports each pi session to chat-recall and adds the messages that other
33246
+ // sessions sent it to the next prompt.
33247
+ ${runnerSource(wrapperPath)}
33248
+ export default function (pi) {
33249
+ let pending = "";
33250
+ const idOf = (ctx) => "pi_" + ctx.sessionManager.getSessionId();
33251
+ const cwdOf = (ctx) => ctx.sessionManager.getCwd();
33252
+
33253
+ pi.on("session_start", async (_event, ctx) => {
33254
+ pending = await runHook(idOf(ctx), "SessionStart", cwdOf(ctx));
33255
+ });
33256
+ pi.on("before_agent_start", async (event, ctx) => {
33257
+ stopWaiter(idOf(ctx));
33258
+ if (event.messageType !== "user") return;
33259
+ const now = await runHook(idOf(ctx), "UserPromptSubmit", cwdOf(ctx));
33260
+ const text = [pending, now].filter(Boolean).join("\\n\\n");
33261
+ pending = "";
33262
+ if (!text) return;
33263
+ return { message: { customType: "${MESSAGES_ID}", content: text, display: true } };
33264
+ });
33265
+ pi.on("agent_end", async (_event, ctx) => {
33266
+ await runHook(idOf(ctx), "Stop", cwdOf(ctx));
33267
+ // An idle session acts on a message from another session by itself.
33268
+ startWaiter(idOf(ctx), cwdOf(ctx), (text) => pi.sendUserMessage(text));
33269
+ });
33270
+ pi.on("session_shutdown", async (_event, ctx) => {
33271
+ stopWaiter(idOf(ctx));
33272
+ await runHook(idOf(ctx), "SessionEnd", cwdOf(ctx));
33273
+ });
33274
+ }
33275
+ `;
33276
+ }
33277
+ var MESSAGES_ID, TIMEOUT_SECS2, isOurs2, asArray3, obj, CODEX_EVENTS, CURSOR_EVENTS;
33278
+ var init_message_registration = __esm({
33279
+ "../engine/dist/core/message-registration.js"() {
33280
+ "use strict";
33281
+ init_backends();
33282
+ init_guard_registration();
33283
+ MESSAGES_ID = "chat-recall-messages";
33284
+ TIMEOUT_SECS2 = 10;
33285
+ isOurs2 = (cmd) => typeof cmd === "string" && cmd.includes("chat_recall_messages_");
33286
+ asArray3 = (v) => Array.isArray(v) ? v : [];
33287
+ obj = (v) => v && typeof v === "object" && !Array.isArray(v) ? { ...v } : {};
33288
+ CODEX_EVENTS = ["SessionStart", "UserPromptSubmit", "Stop", "SessionEnd"];
33289
+ CURSOR_EVENTS = ["sessionStart", "beforeSubmitPrompt", "stop", "sessionEnd"];
33290
+ }
33291
+ });
33292
+
32774
33293
  // src/install-hooks.ts
32775
33294
  var install_hooks_exports = {};
32776
33295
  __export(install_hooks_exports, {
@@ -32786,7 +33305,7 @@ __export(install_hooks_exports, {
32786
33305
  uninstallHooks: () => uninstallHooks
32787
33306
  });
32788
33307
  import { chmodSync as chmodSync7, copyFileSync as copyFileSync3, existsSync as existsSync51, mkdirSync as mkdirSync16, readFileSync as readFileSync49, realpathSync as realpathSync6, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "node:fs";
32789
- import { dirname as dirname21, join as join61 } from "node:path";
33308
+ import { dirname as dirname21, join as join62 } from "node:path";
32790
33309
  function isOurEntry(entry) {
32791
33310
  const cmd = entry?.hooks?.[0]?.command;
32792
33311
  if (typeof cmd !== "string") return false;
@@ -32796,8 +33315,8 @@ function claudeSettingsFiles() {
32796
33315
  const out = [];
32797
33316
  const seen = /* @__PURE__ */ new Set();
32798
33317
  for (const home of claudeHomeDirs()) {
32799
- if (!existsSync51(join61(home, "projects"))) continue;
32800
- const file = join61(home, "settings.json");
33318
+ if (!existsSync51(join62(home, "projects"))) continue;
33319
+ const file = join62(home, "settings.json");
32801
33320
  let key2;
32802
33321
  try {
32803
33322
  key2 = realpathSync6(file);
@@ -32813,9 +33332,9 @@ function claudeSettingsFiles() {
32813
33332
  }
32814
33333
  function findScript(distDir, name) {
32815
33334
  return [
32816
- join61(distDir, "..", "hooks", name),
32817
- join61(distDir, "..", "..", "hooks", name),
32818
- join61(distDir, "..", "..", "..", "hooks", name)
33335
+ join62(distDir, "..", "hooks", name),
33336
+ join62(distDir, "..", "..", "hooks", name),
33337
+ join62(distDir, "..", "..", "..", "hooks", name)
32819
33338
  ].find((p) => existsSync51(p));
32820
33339
  }
32821
33340
  function hookEntries(sel, paths) {
@@ -32880,7 +33399,7 @@ function writeJsonAtomic(file, value) {
32880
33399
  renameSync6(tmp, target);
32881
33400
  }
32882
33401
  function statePath() {
32883
- return join61(getHooksDir(), "install.json");
33402
+ return join62(getHooksDir(), "install.json");
32884
33403
  }
32885
33404
  function readState() {
32886
33405
  try {
@@ -32898,7 +33417,7 @@ async function installHooks(distDir, sel = ALL_HOOKS) {
32898
33417
  if (!sel[key2]) continue;
32899
33418
  const source = findScript(distDir, SCRIPTS[key2]);
32900
33419
  if (!source) continue;
32901
- const target = join61(scriptsDir, SCRIPTS[key2]);
33420
+ const target = join62(scriptsDir, SCRIPTS[key2]);
32902
33421
  copyFileSync3(source, target);
32903
33422
  chmodSync7(target, 493);
32904
33423
  scripts[key2] = target;
@@ -32910,7 +33429,16 @@ async function installHooks(distDir, sel = ALL_HOOKS) {
32910
33429
  cliEntry: resolveCliEntry(distDir),
32911
33430
  messageHookEntry: resolveMessageHookEntry(distDir)
32912
33431
  });
32913
- const report = { written: [], skipped: [], migrated: 0, shellSkipped, scriptsDir, selection: sel, guardTargets: [] };
33432
+ const report = {
33433
+ written: [],
33434
+ skipped: [],
33435
+ migrated: 0,
33436
+ shellSkipped,
33437
+ scriptsDir,
33438
+ selection: sel,
33439
+ guardTargets: [],
33440
+ messageTargets: []
33441
+ };
32914
33442
  for (const settingsFile of claudeSettingsFiles()) {
32915
33443
  const config2 = readJson4(settingsFile);
32916
33444
  if (!config2) {
@@ -32920,9 +33448,12 @@ async function installHooks(distDir, sel = ALL_HOOKS) {
32920
33448
  mergeOurEntries(config2, entries);
32921
33449
  writeJsonAtomic(settingsFile, config2);
32922
33450
  report.written.push(settingsFile);
32923
- report.migrated += migrateHooksJson(join61(dirname21(settingsFile), "hooks.json"));
33451
+ report.migrated += migrateHooksJson(join62(dirname21(settingsFile), "hooks.json"));
32924
33452
  }
32925
33453
  if (sel.guard && scripts.guard) report.guardTargets = await addGuardToOtherTools(scriptsDir, scripts.guard);
33454
+ if (sel.messages && !shellSkipped) {
33455
+ report.messageTargets = await addMessagesToOtherTools(scriptsDir, process.execPath, resolveMessageHookEntry(distDir));
33456
+ }
32926
33457
  writeJsonAtomic(statePath(), { version: cliVersion(), selection: sel });
32927
33458
  return report;
32928
33459
  }
@@ -32937,9 +33468,9 @@ function migrateHooksJson(file) {
32937
33468
  return removed;
32938
33469
  }
32939
33470
  async function uninstallHooks() {
32940
- const report = { removed: 0, files: [], guardRemoved: [] };
33471
+ const report = { removed: 0, files: [], guardRemoved: [], messagesRemoved: [] };
32941
33472
  for (const settingsFile of claudeSettingsFiles()) {
32942
- for (const file of [settingsFile, join61(dirname21(settingsFile), "hooks.json")]) {
33473
+ for (const file of [settingsFile, join62(dirname21(settingsFile), "hooks.json")]) {
32943
33474
  if (!existsSync51(file)) continue;
32944
33475
  const config2 = readJson4(file);
32945
33476
  if (!config2) continue;
@@ -32951,6 +33482,7 @@ async function uninstallHooks() {
32951
33482
  }
32952
33483
  }
32953
33484
  report.guardRemoved = await removeGuardFromOtherTools();
33485
+ report.messagesRemoved = await removeMessagesFromOtherTools();
32954
33486
  writeJsonAtomic(statePath(), { version: cliVersion(), selection: ALL_HOOKS, uninstalled: true });
32955
33487
  return report;
32956
33488
  }
@@ -32974,9 +33506,10 @@ async function ensureHooks(distDir) {
32974
33506
  async function addGuardToOtherTools(scriptsDir, guardScript) {
32975
33507
  const reg = await Promise.resolve().then(() => (init_guard_registration(), guard_registration_exports));
32976
33508
  const out = [];
33509
+ removeLegacyAgyGuard(reg);
32977
33510
  for (const target of reg.guardTargets()) {
32978
33511
  if (!existsSync51(target.homeDir)) continue;
32979
- const wrapper = join61(scriptsDir, reg.guardWrapperName(target.tool));
33512
+ const wrapper = join62(scriptsDir, reg.guardWrapperName(target.tool));
32980
33513
  writeFileSync14(wrapper, reg.guardWrapperSource(target.tool, guardScript));
32981
33514
  chmodSync7(wrapper, 493);
32982
33515
  mkdirSync16(dirname21(target.configPath), { recursive: true });
@@ -32993,6 +33526,7 @@ async function addGuardToOtherTools(scriptsDir, guardScript) {
32993
33526
  async function removeGuardFromOtherTools() {
32994
33527
  const reg = await Promise.resolve().then(() => (init_guard_registration(), guard_registration_exports));
32995
33528
  const out = [];
33529
+ removeLegacyAgyGuard(reg);
32996
33530
  for (const target of reg.guardTargets()) {
32997
33531
  if (!existsSync51(target.configPath)) continue;
32998
33532
  if (target.tool === "opencode") {
@@ -33007,6 +33541,53 @@ async function removeGuardFromOtherTools() {
33007
33541
  }
33008
33542
  return out;
33009
33543
  }
33544
+ function removeLegacyAgyGuard(reg) {
33545
+ const file = reg.legacyAgyHooksFile();
33546
+ if (!existsSync51(file)) return;
33547
+ const r = reg.unregisterGuard("agy", readJson4(file) ?? {});
33548
+ if (r.removed) writeJsonAtomic(file, r.config);
33549
+ }
33550
+ async function addMessagesToOtherTools(scriptsDir, nodePath, hookEntry) {
33551
+ const reg = await Promise.resolve().then(() => (init_message_registration(), message_registration_exports));
33552
+ const out = [];
33553
+ for (const target of reg.messageTargets()) {
33554
+ if (!existsSync51(target.homeDir)) continue;
33555
+ const wrapper = join62(scriptsDir, reg.messageWrapperName(target.tool));
33556
+ writeFileSync14(wrapper, reg.messageWrapperSource(target.tool, nodePath, hookEntry));
33557
+ chmodSync7(wrapper, 493);
33558
+ mkdirSync16(dirname21(target.configPath), { recursive: true });
33559
+ if (target.tool === "opencode") {
33560
+ writeFileSync14(target.configPath, reg.opencodeMessagesSource(wrapper));
33561
+ } else if (target.tool === "pi") {
33562
+ writeFileSync14(target.configPath, reg.piMessagesSource(wrapper));
33563
+ } else {
33564
+ const config2 = readJson4(target.configPath);
33565
+ if (!config2) continue;
33566
+ writeJsonAtomic(target.configPath, reg.registerMessages(target.tool, config2, reg.messageCommand(wrapper)));
33567
+ }
33568
+ out.push({ label: target.label, configPath: target.configPath, note: target.note });
33569
+ }
33570
+ return out;
33571
+ }
33572
+ async function removeMessagesFromOtherTools() {
33573
+ const reg = await Promise.resolve().then(() => (init_message_registration(), message_registration_exports));
33574
+ const out = [];
33575
+ for (const target of reg.messageTargets()) {
33576
+ if (!existsSync51(target.configPath)) continue;
33577
+ if (target.tool === "opencode" || target.tool === "pi") {
33578
+ if (!reg.isOurPluginSource(readFileSync49(target.configPath, "utf-8"))) continue;
33579
+ unlinkSync4(target.configPath);
33580
+ } else {
33581
+ const config2 = readJson4(target.configPath);
33582
+ if (!config2) continue;
33583
+ const r = reg.unregisterMessages(target.tool, config2);
33584
+ if (r.removed === 0) continue;
33585
+ writeJsonAtomic(target.configPath, r.config);
33586
+ }
33587
+ out.push({ label: target.label, configPath: target.configPath });
33588
+ }
33589
+ return out;
33590
+ }
33010
33591
  var ALL_HOOKS, SCRIPTS, HOOK_EVENTS;
33011
33592
  var init_install_hooks = __esm({
33012
33593
  "src/install-hooks.ts"() {
@@ -34700,9 +35281,9 @@ var WriteAheadLog = class {
34700
35281
  logWithResult(operation, params, result) {
34701
35282
  this.log(operation, params, result);
34702
35283
  }
34703
- redactSensitive(obj) {
35284
+ redactSensitive(obj2) {
34704
35285
  const safe = {};
34705
- for (const [key2, value] of Object.entries(obj)) {
35286
+ for (const [key2, value] of Object.entries(obj2)) {
34706
35287
  if (REDACT_KEYS.has(key2)) {
34707
35288
  if (typeof value === "string") {
34708
35289
  safe[key2] = value.length <= MAX_PREVIEW_LENGTH ? value : `[${value.length} chars] ${value.slice(0, MAX_PREVIEW_LENGTH)}...`;
@@ -35671,7 +36252,11 @@ line to pass as \`expand_line\` to get it whole.`,
35671
36252
  Shows your most recent conversations across all projects or filtered by project.
35672
36253
  Use this when the user says "continue our last conversation" or wants to see recent work.
35673
36254
 
35674
- Pass \`since_hours: N\` to restrict to sessions modified in the last N hours.`,
36255
+ Pass \`since_hours: N\` to restrict to sessions modified in the last N hours.
36256
+
36257
+ It lists synced transcripts, which reach the server some time after they change. To find a
36258
+ session that runs NOW, or to send one a message, use recall_session_status: it lists the live
36259
+ sessions of every AI tool, with their ids and names.`,
35675
36260
  inputSchema: {
35676
36261
  type: "object",
35677
36262
  properties: {
@@ -39754,7 +40339,7 @@ function installCrashGuards() {
39754
40339
  reportClientEvent2("mcp_crash", { message: err.stack || err.message });
39755
40340
  });
39756
40341
  }
39757
- var RELAY_VERSION = true ? "0.7.21" : "0.0.0";
40342
+ var RELAY_VERSION = true ? "0.7.24" : "0.0.0";
39758
40343
  function daemonIdleSecs() {
39759
40344
  const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
39760
40345
  if (raw === void 0) return 900;