chat-recall 0.5.31 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp.js CHANGED
@@ -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: join53 } = __require("path");
2037
+ var { join: join54 } = __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"] || join53(__dirname, "lib", "worker.js");
2080
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join54(__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: join53, isAbsolute: isAbsolute3, sep: sep4 } = __require("node:path");
2483
+ var { join: join54, isAbsolute: isAbsolute3, 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"] || join53(__dirname, "worker.js");
2546
+ target = bundlerOverrides["pino-worker"] || join54(__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"] || join53(__dirname, "worker.js");
2564
+ target = bundlerOverrides["pino-worker"] || join54(__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 join53(__dirname, "..", "file.js");
2586
+ return join54(__dirname, "..", "file.js");
2587
2587
  }
2588
2588
  let fixTarget2;
2589
2589
  for (const filePath of callers) {
@@ -3572,7 +3572,7 @@ var require_safe_stable_stringify = __commonJS({
3572
3572
  return circularValue;
3573
3573
  }
3574
3574
  let res = "";
3575
- let join53 = ",";
3575
+ let join54 = ",";
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
- join53 = `,
3589
+ join54 = `,
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 += join53;
3597
+ res += join54;
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 += `${join53}"... ${getItemCount(removedKeys)} not stringified"`;
3603
+ res += `${join54}"... ${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
- join53 = `,
3624
+ join54 = `,
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 = join53;
3638
+ separator = join54;
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 = join53;
3644
+ separator = join54;
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 join53 = ",";
3685
+ let join54 = ",";
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
- join53 = `,
3698
+ join54 = `,
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 += join53;
3706
+ res += join54;
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 += `${join53}"... ${getItemCount(removedKeys)} not stringified"`;
3712
+ res += `${join54}"... ${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
- join53 = `,
3725
+ join54 = `,
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 = join53;
3734
+ separator = join54;
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 join54 = `,
3792
+ const join55 = `,
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 += join54;
3799
+ res2 += join55;
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 += `${join54}"... ${getItemCount(removedKeys)} not stringified"`;
3805
+ res2 += `${join55}"... ${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 join53 = `,
3821
+ const join54 = `,
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, join53, maximumBreadth);
3827
+ res += stringifyTypedArray(value, join54, maximumBreadth);
3828
3828
  keys = keys.slice(value.length);
3829
3829
  maximumPropertiesToStringify -= value.length;
3830
- separator = join53;
3830
+ separator = join54;
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 = join53;
3841
+ separator = join54;
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 = join53;
3847
+ separator = join54;
3848
3848
  }
3849
3849
  if (separator !== "") {
3850
3850
  res = `
@@ -4432,58 +4432,58 @@ var init_logger = __esm({
4432
4432
  });
4433
4433
 
4434
4434
  // ../engine/dist/core/paths.js
4435
- import { existsSync, mkdirSync, renameSync, readdirSync, statSync, copyFileSync, rmSync } from "fs";
4435
+ import { existsSync, mkdirSync as mkdirSync2, renameSync, readdirSync, statSync as statSync2, copyFileSync, rmSync } from "fs";
4436
4436
  import { homedir } from "os";
4437
- import { join, dirname } from "path";
4437
+ import { join as join2, dirname as dirname2 } from "path";
4438
4438
  function getDataDir() {
4439
4439
  const override = process.env.CHAT_RECALL_DATA_DIR;
4440
4440
  if (override && override.trim())
4441
4441
  return override.trim();
4442
- return join(homedir(), ".chat-recall");
4442
+ return join2(homedir(), ".chat-recall");
4443
4443
  }
4444
4444
  function getIndexDir() {
4445
4445
  ensureMigrated();
4446
- const p = join(getDataDir(), "index");
4446
+ const p = join2(getDataDir(), "index");
4447
4447
  ensureDir(p);
4448
4448
  return p;
4449
4449
  }
4450
4450
  function getWalDir() {
4451
- const p = join(getIndexDir(), "wal");
4451
+ const p = join2(getIndexDir(), "wal");
4452
4452
  ensureDir(p);
4453
4453
  return p;
4454
4454
  }
4455
4455
  function getDiaryDir() {
4456
- const p = join(getIndexDir(), "diary");
4456
+ const p = join2(getIndexDir(), "diary");
4457
4457
  ensureDir(p);
4458
4458
  return p;
4459
4459
  }
4460
4460
  function getDetectorBinDir() {
4461
- return join(getDataDir(), "bin");
4461
+ return join2(getDataDir(), "bin");
4462
4462
  }
4463
4463
  function getIdentityFilePath() {
4464
4464
  ensureMigrated();
4465
4465
  ensureDir(getDataDir());
4466
- return join(getDataDir(), "identity.txt");
4466
+ return join2(getDataDir(), "identity.txt");
4467
4467
  }
4468
4468
  function legacyRoot() {
4469
- return join(homedir(), ".claude");
4469
+ return join2(homedir(), ".claude");
4470
4470
  }
4471
4471
  function legacyMappings() {
4472
4472
  const root = legacyRoot();
4473
4473
  const newRoot = getDataDir();
4474
4474
  return [
4475
- { legacyPath: join(root, "chat-recall-cache.db"), newPath: join(newRoot, "cache.db"), isDir: false },
4476
- { legacyPath: join(root, "chat-recall-index"), newPath: join(newRoot, "index"), isDir: true },
4477
- { legacyPath: join(root, "chat-recall-memory"), newPath: join(newRoot, "memory"), isDir: true },
4478
- { legacyPath: join(root, "chat-recall-identity.txt"), newPath: join(newRoot, "identity.txt"), isDir: false },
4479
- { legacyPath: join(root, "chat-recall-hooks"), newPath: join(newRoot, "hooks"), isDir: true },
4475
+ { legacyPath: join2(root, "chat-recall-cache.db"), newPath: join2(newRoot, "cache.db"), isDir: false },
4476
+ { legacyPath: join2(root, "chat-recall-index"), newPath: join2(newRoot, "index"), isDir: true },
4477
+ { legacyPath: join2(root, "chat-recall-memory"), newPath: join2(newRoot, "memory"), isDir: true },
4478
+ { legacyPath: join2(root, "chat-recall-identity.txt"), newPath: join2(newRoot, "identity.txt"), isDir: false },
4479
+ { legacyPath: join2(root, "chat-recall-hooks"), newPath: join2(newRoot, "hooks"), isDir: true },
4480
4480
  // The legacy settings directory was named just "chat-recall" (no
4481
4481
  // suffix) — odd choice. Move it to a clearer "settings" subdir.
4482
- { legacyPath: join(root, "chat-recall"), newPath: join(newRoot, "settings"), isDir: true },
4482
+ { legacyPath: join2(root, "chat-recall"), newPath: join2(newRoot, "settings"), isDir: true },
4483
4483
  // SQLite WAL/SHM siblings — must move with their main .db so they don't
4484
4484
  // get re-created and stale-out the migrated cache.
4485
- { legacyPath: join(root, "chat-recall-cache.db-wal"), newPath: join(newRoot, "cache.db-wal"), isDir: false },
4486
- { legacyPath: join(root, "chat-recall-cache.db-shm"), newPath: join(newRoot, "cache.db-shm"), isDir: false }
4485
+ { legacyPath: join2(root, "chat-recall-cache.db-wal"), newPath: join2(newRoot, "cache.db-wal"), isDir: false },
4486
+ { legacyPath: join2(root, "chat-recall-cache.db-shm"), newPath: join2(newRoot, "cache.db-shm"), isDir: false }
4487
4487
  ];
4488
4488
  }
4489
4489
  function ensureMigrated() {
@@ -4508,7 +4508,7 @@ function ensureMigrated() {
4508
4508
  if (m.isDir)
4509
4509
  copyDir(m.legacyPath, m.newPath);
4510
4510
  else {
4511
- ensureDir(dirname(m.newPath));
4511
+ ensureDir(dirname2(m.newPath));
4512
4512
  copyFileSync(m.legacyPath, m.newPath);
4513
4513
  }
4514
4514
  rmSync(m.legacyPath, { recursive: true, force: true });
@@ -4524,14 +4524,14 @@ function ensureMigrated() {
4524
4524
  }
4525
4525
  function ensureDir(p) {
4526
4526
  if (!existsSync(p))
4527
- mkdirSync(p, { recursive: true });
4527
+ mkdirSync2(p, { recursive: true });
4528
4528
  }
4529
4529
  function copyDir(src, dest) {
4530
4530
  ensureDir(dest);
4531
4531
  for (const entry of readdirSync(src)) {
4532
- const srcPath = join(src, entry);
4533
- const destPath = join(dest, entry);
4534
- const st = statSync(srcPath);
4532
+ const srcPath = join2(src, entry);
4533
+ const destPath = join2(dest, entry);
4534
+ const st = statSync2(srcPath);
4535
4535
  if (st.isDirectory())
4536
4536
  copyDir(srcPath, destPath);
4537
4537
  else if (st.isFile())
@@ -4550,11 +4550,11 @@ var init_paths = __esm({
4550
4550
 
4551
4551
  // ../engine/dist/core/project-resolver.js
4552
4552
  import { execSync } from "child_process";
4553
- import { createHash } from "crypto";
4554
- import { existsSync as existsSync2, readFileSync, realpathSync, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
4555
- import { basename, dirname as dirname2, isAbsolute, join as join2, resolve, sep } from "path";
4553
+ import { createHash as createHash2 } from "crypto";
4554
+ import { existsSync as existsSync2, readFileSync, realpathSync, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
4555
+ import { basename, dirname as dirname3, isAbsolute, join as join3, resolve, sep } from "path";
4556
4556
  function getProjectsConfigPath() {
4557
- return join2(getDataDir(), "projects.json");
4557
+ return join3(getDataDir(), "projects.json");
4558
4558
  }
4559
4559
  function loadProjectsConfig() {
4560
4560
  if (cachedConfig && cachedConfig.mtime === Number.MAX_SAFE_INTEGER) {
@@ -4565,7 +4565,7 @@ function loadProjectsConfig() {
4565
4565
  cachedConfig = { mtime: 0, cfg: {} };
4566
4566
  return cachedConfig.cfg;
4567
4567
  }
4568
- const mtime = statSync2(path).mtimeMs;
4568
+ const mtime = statSync3(path).mtimeMs;
4569
4569
  if (cachedConfig && cachedConfig.mtime === mtime)
4570
4570
  return cachedConfig.cfg;
4571
4571
  try {
@@ -4665,7 +4665,7 @@ function matchDeclaredProject(realPath, projects) {
4665
4665
  function matchChild(realPath, parentRoot, children) {
4666
4666
  const sorted = [...children].sort((a, b) => b.path.length - a.path.length);
4667
4667
  for (const c of sorted) {
4668
- const childRoot = safeRealpath(join2(parentRoot, c.path));
4668
+ const childRoot = safeRealpath(join3(parentRoot, c.path));
4669
4669
  if (isInside(realPath, childRoot))
4670
4670
  return c;
4671
4671
  }
@@ -4689,7 +4689,7 @@ function resolveGit(realPath) {
4689
4689
  if (probe.kind === "failed") {
4690
4690
  console.error(`[project] could not read git remotes in ${toplevel} \u2014 filing it as a local-only repo for now, which is probably wrong: ${probe.reason}`);
4691
4691
  }
4692
- const hash = createHash("sha1").update(toplevel).digest("hex").slice(0, 12);
4692
+ const hash = createHash2("sha1").update(toplevel).digest("hex").slice(0, 12);
4693
4693
  return {
4694
4694
  id: `git-local:${hash}`,
4695
4695
  displayName: basename(toplevel),
@@ -4700,10 +4700,10 @@ function findGitToplevel(realPath) {
4700
4700
  let cur = realPath;
4701
4701
  let last = "";
4702
4702
  while (cur && cur !== last) {
4703
- if (existsSync2(join2(cur, ".git")))
4703
+ if (existsSync2(join3(cur, ".git")))
4704
4704
  return cur;
4705
4705
  last = cur;
4706
- cur = dirname2(cur);
4706
+ cur = dirname3(cur);
4707
4707
  }
4708
4708
  return null;
4709
4709
  }
@@ -4767,7 +4767,7 @@ function resolveAutoWorkspace(realPath, minRepos) {
4767
4767
  let last = "";
4768
4768
  let depth = 0;
4769
4769
  while (cur && cur !== last && depth < AUTO_WORKSPACE_MAX_DEPTH) {
4770
- if (!existsSync2(join2(cur, ".git"))) {
4770
+ if (!existsSync2(join3(cur, ".git"))) {
4771
4771
  const cached = workspaceCache.get(cur);
4772
4772
  let qualifies;
4773
4773
  if (cached === void 0) {
@@ -4782,7 +4782,7 @@ function resolveAutoWorkspace(realPath, minRepos) {
4782
4782
  }
4783
4783
  }
4784
4784
  last = cur;
4785
- cur = dirname2(cur);
4785
+ cur = dirname3(cur);
4786
4786
  depth++;
4787
4787
  }
4788
4788
  return null;
@@ -4798,12 +4798,12 @@ function countGitChildren(dir) {
4798
4798
  for (const name of entries) {
4799
4799
  if (name.startsWith("."))
4800
4800
  continue;
4801
- const child = join2(dir, name);
4801
+ const child = join3(dir, name);
4802
4802
  try {
4803
- const st = statSync2(child);
4803
+ const st = statSync3(child);
4804
4804
  if (!st.isDirectory())
4805
4805
  continue;
4806
- if (existsSync2(join2(child, ".git")))
4806
+ if (existsSync2(join3(child, ".git")))
4807
4807
  count++;
4808
4808
  } catch {
4809
4809
  }
@@ -5084,9 +5084,9 @@ __export(settings_exports, {
5084
5084
  saveSettings: () => saveSettings,
5085
5085
  settingsFilePath: () => settingsFilePath
5086
5086
  });
5087
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync, chmodSync, statSync as statSync3 } from "fs";
5087
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync, chmodSync as chmodSync2, statSync as statSync4 } from "fs";
5088
5088
  import { delimiter } from "path";
5089
- import { dirname as dirname3, join as join3 } from "path";
5089
+ import { dirname as dirname4, join as join4 } from "path";
5090
5090
  function whichSync(bin) {
5091
5091
  const path = process.env.PATH;
5092
5092
  if (!path)
@@ -5094,9 +5094,9 @@ function whichSync(bin) {
5094
5094
  for (const dir of path.split(delimiter)) {
5095
5095
  if (!dir)
5096
5096
  continue;
5097
- const full = join3(dir, bin);
5097
+ const full = join4(dir, bin);
5098
5098
  try {
5099
- const s = statSync3(full);
5099
+ const s = statSync4(full);
5100
5100
  if (s.isFile())
5101
5101
  return true;
5102
5102
  } catch {
@@ -5284,12 +5284,12 @@ function settingsFilePath() {
5284
5284
  return settingsPath();
5285
5285
  }
5286
5286
  function settingsPath() {
5287
- return join3(getDataDir(), "settings", "settings.json");
5287
+ return join4(getDataDir(), "settings", "settings.json");
5288
5288
  }
5289
5289
  function loadSourceSettings() {
5290
5290
  let mtimeMs = -1;
5291
5291
  try {
5292
- mtimeMs = statSync3(settingsPath()).mtimeMs;
5292
+ mtimeMs = statSync4(settingsPath()).mtimeMs;
5293
5293
  } catch {
5294
5294
  }
5295
5295
  if (_sourceSettingsCache && _sourceSettingsCache.mtimeMs === mtimeMs) {
@@ -5313,7 +5313,7 @@ function _resetSourceSettingsCache() {
5313
5313
  _sourceSettingsCache = null;
5314
5314
  }
5315
5315
  function secretsPath() {
5316
- return join3(getDataDir(), "secrets.env");
5316
+ return join4(getDataDir(), "secrets.env");
5317
5317
  }
5318
5318
  function _resetSecretsCacheForTests() {
5319
5319
  _secretsCache = null;
@@ -5325,7 +5325,7 @@ function loadSecrets() {
5325
5325
  return out;
5326
5326
  let mtimeMs = -1, size = -1;
5327
5327
  try {
5328
- const st = statSync3(p);
5328
+ const st = statSync4(p);
5329
5329
  mtimeMs = st.mtimeMs;
5330
5330
  size = st.size;
5331
5331
  } catch {
@@ -5357,11 +5357,11 @@ function loadSecrets() {
5357
5357
  function writeSecrets(secrets) {
5358
5358
  _secretsCache = null;
5359
5359
  const p = secretsPath();
5360
- mkdirSync2(dirname3(p), { recursive: true });
5360
+ mkdirSync3(dirname4(p), { recursive: true });
5361
5361
  const body = "# chat-recall secrets \u2014 NOT committed/synced. Mode 0600.\n" + Object.entries(secrets).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join("\n") + "\n";
5362
5362
  writeFileSync(p, body);
5363
5363
  try {
5364
- chmodSync(p, 384);
5364
+ chmodSync2(p, 384);
5365
5365
  } catch {
5366
5366
  }
5367
5367
  }
@@ -5384,7 +5384,7 @@ function loadSettings() {
5384
5384
  return freshDefaults();
5385
5385
  let mtimeMs = -1, size = -1;
5386
5386
  try {
5387
- const st = statSync3(path);
5387
+ const st = statSync4(path);
5388
5388
  mtimeMs = st.mtimeMs;
5389
5389
  size = st.size;
5390
5390
  } catch {
@@ -5430,10 +5430,10 @@ function saveSettings(settings2) {
5430
5430
  }
5431
5431
  writeSecrets(secrets);
5432
5432
  const path = settingsPath();
5433
- mkdirSync2(dirname3(path), { recursive: true });
5433
+ mkdirSync3(dirname4(path), { recursive: true });
5434
5434
  writeFileSync(path, JSON.stringify(stripped, null, 2));
5435
5435
  try {
5436
- chmodSync(path, 384);
5436
+ chmodSync2(path, 384);
5437
5437
  } catch {
5438
5438
  }
5439
5439
  }
@@ -5572,9 +5572,9 @@ var init_settings = __esm({
5572
5572
  // ../engine/dist/core/home-approval.js
5573
5573
  import { existsSync as existsSync4, readdirSync as readdirSync3, realpathSync as realpathSync2 } from "fs";
5574
5574
  import { homedir as homedir2 } from "os";
5575
- import { join as join4, dirname as dirname4 } from "path";
5575
+ import { join as join5, dirname as dirname5 } from "path";
5576
5576
  function normalizeHomePath(p) {
5577
- const expanded = p.startsWith("~") ? join4(homedir2(), p.slice(1)) : p;
5577
+ const expanded = p.startsWith("~") ? join5(homedir2(), p.slice(1)) : p;
5578
5578
  const trimmed = expanded.replace(/[/\\]+$/, "");
5579
5579
  try {
5580
5580
  return realpathSync2(trimmed);
@@ -5586,23 +5586,23 @@ function legacyAutoSyncedHomes() {
5586
5586
  const home = homedir2();
5587
5587
  const out = [];
5588
5588
  const add = (dir, marker) => {
5589
- if (!existsSync4(join4(dir, marker)))
5589
+ if (!existsSync4(join5(dir, marker)))
5590
5590
  return;
5591
5591
  const n = normalizeHomePath(dir);
5592
5592
  if (!out.includes(n))
5593
5593
  out.push(n);
5594
5594
  };
5595
5595
  const bases = [
5596
- { base: join4(home, ".claude"), marker: "projects" },
5597
- { base: join4(home, ".gemini"), marker: "tmp" },
5598
- { base: join4(home, ".codex"), marker: "sessions" },
5599
- { base: join4(home, ".gemini", "antigravity-cli"), marker: "brain" },
5600
- { base: join4(home, ".local", "share", "opencode"), marker: "opencode.db" },
5601
- { base: join4(home, ".cursor"), marker: "chats" }
5596
+ { base: join5(home, ".claude"), marker: "projects" },
5597
+ { base: join5(home, ".gemini"), marker: "tmp" },
5598
+ { base: join5(home, ".codex"), marker: "sessions" },
5599
+ { base: join5(home, ".gemini", "antigravity-cli"), marker: "brain" },
5600
+ { base: join5(home, ".local", "share", "opencode"), marker: "opencode.db" },
5601
+ { base: join5(home, ".cursor"), marker: "chats" }
5602
5602
  ];
5603
5603
  for (const { base, marker } of bases) {
5604
5604
  add(base, marker);
5605
- const parent = dirname4(base);
5605
+ const parent = dirname5(base);
5606
5606
  const leaf = base.slice(parent.length + 1);
5607
5607
  try {
5608
5608
  for (const e of readdirSync3(parent, { withFileTypes: true })) {
@@ -5612,7 +5612,7 @@ function legacyAutoSyncedHomes() {
5612
5612
  continue;
5613
5613
  if (e.name === ".claude-code")
5614
5614
  continue;
5615
- add(join4(parent, e.name), marker);
5615
+ add(join5(parent, e.name), marker);
5616
5616
  }
5617
5617
  } catch {
5618
5618
  }
@@ -5655,13 +5655,13 @@ function primaryHomes() {
5655
5655
  } catch {
5656
5656
  s = void 0;
5657
5657
  }
5658
- const opencodeDb = env.CHAT_RECALL_OPENCODE_DB || s?.opencodeDbPath || join4(home, ".local", "share", "opencode", "opencode.db");
5658
+ const opencodeDb = env.CHAT_RECALL_OPENCODE_DB || s?.opencodeDbPath || join5(home, ".local", "share", "opencode", "opencode.db");
5659
5659
  const candidates2 = [
5660
- env.CHAT_RECALL_CLAUDE_HOME || s?.claudeHome || join4(home, ".claude"),
5661
- env.CHAT_RECALL_GEMINI_HOME || s?.geminiHome || join4(home, ".gemini"),
5662
- env.CHAT_RECALL_CODEX_HOME || s?.codexHome || join4(home, ".codex"),
5663
- env.CHAT_RECALL_AGY_HOME || s?.agyHome || join4(home, ".gemini", "antigravity-cli"),
5664
- env.CHAT_RECALL_CURSOR_HOME || s?.cursorHome || join4(home, ".cursor"),
5660
+ env.CHAT_RECALL_CLAUDE_HOME || s?.claudeHome || join5(home, ".claude"),
5661
+ env.CHAT_RECALL_GEMINI_HOME || s?.geminiHome || join5(home, ".gemini"),
5662
+ env.CHAT_RECALL_CODEX_HOME || s?.codexHome || join5(home, ".codex"),
5663
+ env.CHAT_RECALL_AGY_HOME || s?.agyHome || join5(home, ".gemini", "antigravity-cli"),
5664
+ env.CHAT_RECALL_CURSOR_HOME || s?.cursorHome || join5(home, ".cursor"),
5665
5665
  dirOf(opencodeDb)
5666
5666
  ];
5667
5667
  return candidates2.map(normalizeHomePath);
@@ -5721,22 +5721,22 @@ var init_home_approval = __esm({
5721
5721
  "../engine/dist/core/home-approval.js"() {
5722
5722
  "use strict";
5723
5723
  init_settings();
5724
- dirOf = (filePath) => dirname4(filePath);
5724
+ dirOf = (filePath) => dirname5(filePath);
5725
5725
  }
5726
5726
  });
5727
5727
 
5728
5728
  // ../engine/dist/core/tool-paths.js
5729
5729
  import { existsSync as existsSync5, readdirSync as readdirSync4 } from "fs";
5730
5730
  import { homedir as homedir3 } from "os";
5731
- import { join as join5, dirname as dirname5, basename as basename2 } from "path";
5731
+ import { join as join6, dirname as dirname6, basename as basename2 } from "path";
5732
5732
  function claudeHomeDir() {
5733
- return process.env.CHAT_RECALL_CLAUDE_HOME || sources().claudeHome || join5(homedir3(), ".claude");
5733
+ return process.env.CHAT_RECALL_CLAUDE_HOME || sources().claudeHome || join6(homedir3(), ".claude");
5734
5734
  }
5735
5735
  function claudeProjectDirs(opts = {}) {
5736
5736
  const home = homedir3();
5737
5737
  const dirs = [];
5738
5738
  const addHome = (d) => {
5739
- const p = join5(d, "projects");
5739
+ const p = join6(d, "projects");
5740
5740
  if (existsSync5(p) && !dirs.includes(p))
5741
5741
  dirs.push(p);
5742
5742
  };
@@ -5746,7 +5746,7 @@ function claudeProjectDirs(opts = {}) {
5746
5746
  try {
5747
5747
  for (const entry of readdirSync4(home, { withFileTypes: true })) {
5748
5748
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
5749
- addHome(join5(home, entry.name));
5749
+ addHome(join6(home, entry.name));
5750
5750
  }
5751
5751
  }
5752
5752
  } catch {
@@ -5756,44 +5756,44 @@ function claudeProjectDirs(opts = {}) {
5756
5756
  for (const d of process.env.CLAUDE_DIRS.split(",")) {
5757
5757
  const t = d.trim();
5758
5758
  if (t)
5759
- addHome(t.startsWith("~/") ? join5(home, t.slice(2)) : t);
5759
+ addHome(t.startsWith("~/") ? join6(home, t.slice(2)) : t);
5760
5760
  }
5761
5761
  }
5762
5762
  if (dirs.length === 0)
5763
- dirs.push(join5(claudeHomeDir(), "projects"));
5763
+ dirs.push(join6(claudeHomeDir(), "projects"));
5764
5764
  return applyDecisions(dirs, opts.includeExcluded);
5765
5765
  }
5766
5766
  function _setSourceExclusionFilter(fn) {
5767
5767
  _sourceExclusionFilter = fn;
5768
5768
  }
5769
5769
  function geminiHomeDir() {
5770
- return process.env.CHAT_RECALL_GEMINI_HOME || sources().geminiHome || join5(homedir3(), ".gemini");
5770
+ return process.env.CHAT_RECALL_GEMINI_HOME || sources().geminiHome || join6(homedir3(), ".gemini");
5771
5771
  }
5772
5772
  function opencodeDbPath() {
5773
- return process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath || join5(homedir3(), ".local", "share", "opencode", "opencode.db");
5773
+ return process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath || join6(homedir3(), ".local", "share", "opencode", "opencode.db");
5774
5774
  }
5775
5775
  function codexHomeDir() {
5776
- return process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome || join5(homedir3(), ".codex");
5776
+ return process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome || join6(homedir3(), ".codex");
5777
5777
  }
5778
5778
  function agyHomeDir() {
5779
- return process.env.CHAT_RECALL_AGY_HOME || sources().agyHome || join5(homedir3(), ".gemini", "antigravity-cli");
5779
+ return process.env.CHAT_RECALL_AGY_HOME || sources().agyHome || join6(homedir3(), ".gemini", "antigravity-cli");
5780
5780
  }
5781
5781
  function cursorHomeDir() {
5782
- return process.env.CHAT_RECALL_CURSOR_HOME || sources().cursorHome || join5(homedir3(), ".cursor");
5782
+ return process.env.CHAT_RECALL_CURSOR_HOME || sources().cursorHome || join6(homedir3(), ".cursor");
5783
5783
  }
5784
5784
  function cursorIdeHomeDir() {
5785
- return process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome || (process.platform === "darwin" ? join5(homedir3(), "Library", "Application Support", "Cursor") : join5(homedir3(), ".config", "Cursor"));
5785
+ return process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome || (process.platform === "darwin" ? join6(homedir3(), "Library", "Application Support", "Cursor") : join6(homedir3(), ".config", "Cursor"));
5786
5786
  }
5787
5787
  function siblingHomes(base, overridden, suffix) {
5788
5788
  const roots = [];
5789
5789
  const add = (home) => {
5790
- const root = suffix ? join5(home, suffix) : home;
5790
+ const root = suffix ? join6(home, suffix) : home;
5791
5791
  if (existsSync5(root) && !roots.includes(root))
5792
5792
  roots.push(root);
5793
5793
  };
5794
5794
  add(base);
5795
5795
  if (!overridden) {
5796
- const parent = dirname5(base);
5796
+ const parent = dirname6(base);
5797
5797
  const leaf = basename2(base);
5798
5798
  try {
5799
5799
  for (const entry of readdirSync4(parent, { withFileTypes: true })) {
@@ -5801,7 +5801,7 @@ function siblingHomes(base, overridden, suffix) {
5801
5801
  continue;
5802
5802
  if (entry.name === leaf || !entry.name.startsWith(leaf + "-"))
5803
5803
  continue;
5804
- add(join5(parent, entry.name));
5804
+ add(join6(parent, entry.name));
5805
5805
  }
5806
5806
  } catch {
5807
5807
  }
@@ -5815,7 +5815,7 @@ function applyDecisions(roots, includeExcluded) {
5815
5815
  if (!includeExcluded) {
5816
5816
  try {
5817
5817
  grandfatherLegacyHomes();
5818
- const approved = kept.filter((r) => isHomeSynced(dirname5(r)));
5818
+ const approved = kept.filter((r) => isHomeSynced(dirname6(r)));
5819
5819
  if (approved.length > 0)
5820
5820
  kept = approved;
5821
5821
  } catch {
@@ -5849,14 +5849,14 @@ function cursorChatDirs(opts = {}) {
5849
5849
  }
5850
5850
  function cursorIdeWorkspaceDirs(opts = {}) {
5851
5851
  const overridden = !!(process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome);
5852
- return applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join5("User", "workspaceStorage")), opts.includeExcluded);
5852
+ return applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join6("User", "workspaceStorage")), opts.includeExcluded);
5853
5853
  }
5854
5854
  function cursorIdeGlobalDbs(opts = {}) {
5855
5855
  const overridden = !!(process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome);
5856
- const roots = applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join5("User", "globalStorage")), opts.includeExcluded);
5856
+ const roots = applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join6("User", "globalStorage")), opts.includeExcluded);
5857
5857
  const dbs = [];
5858
5858
  for (const r of roots) {
5859
- const p = join5(r, "state.vscdb");
5859
+ const p = join6(r, "state.vscdb");
5860
5860
  if (existsSync5(p) && !dbs.includes(p))
5861
5861
  dbs.push(p);
5862
5862
  }
@@ -5866,10 +5866,10 @@ function opencodeDbPaths(opts = {}) {
5866
5866
  const primary = opencodeDbPath();
5867
5867
  const overridden = !!(process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath);
5868
5868
  const dbFile = basename2(primary);
5869
- const dirs = siblingHomes(dirname5(primary), overridden, "");
5869
+ const dirs = siblingHomes(dirname6(primary), overridden, "");
5870
5870
  const dbs = [];
5871
5871
  for (const d of dirs) {
5872
- const p = join5(d, dbFile);
5872
+ const p = join6(d, dbFile);
5873
5873
  if (existsSync5(p) && !dbs.includes(p))
5874
5874
  dbs.push(p);
5875
5875
  }
@@ -5903,7 +5903,7 @@ var init_tool_paths = __esm({
5903
5903
  });
5904
5904
 
5905
5905
  // ../engine/dist/core/secret-redactor.js
5906
- import { statSync as statSync4 } from "fs";
5906
+ import { statSync as statSync5 } from "fs";
5907
5907
  function secretOf(rule, m) {
5908
5908
  const raw = rule.secret != null ? m[rule.secret] : m[0];
5909
5909
  if (raw == null)
@@ -5961,7 +5961,7 @@ function isEnvRedactionRequested() {
5961
5961
  function settingsView() {
5962
5962
  let mtimeMs = -1;
5963
5963
  try {
5964
- mtimeMs = statSync4(settingsFilePath()).mtimeMs;
5964
+ mtimeMs = statSync5(settingsFilePath()).mtimeMs;
5965
5965
  } catch {
5966
5966
  }
5967
5967
  if (cache && cache.mtimeMs === mtimeMs)
@@ -6132,7 +6132,7 @@ function scanTextForFindings(text, opts = {}) {
6132
6132
  function privacyView() {
6133
6133
  let mtimeMs = -1;
6134
6134
  try {
6135
- mtimeMs = statSync4(settingsFilePath()).mtimeMs;
6135
+ mtimeMs = statSync5(settingsFilePath()).mtimeMs;
6136
6136
  } catch {
6137
6137
  }
6138
6138
  if (privacyCache && privacyCache.mtimeMs === mtimeMs)
@@ -6468,6 +6468,64 @@ var init_chunker = __esm({
6468
6468
  }
6469
6469
  });
6470
6470
 
6471
+ // ../engine/dist/core/project-dir-name.js
6472
+ import { readdirSync as readdirSync5 } from "node:fs";
6473
+ function looksWindowsEncoded(dirName) {
6474
+ return /^[A-Za-z]--/.test(dirName);
6475
+ }
6476
+ function decodeProjectDirName(dirName) {
6477
+ if (!dirName)
6478
+ return "";
6479
+ if (looksWindowsEncoded(dirName)) {
6480
+ const drive = dirName[0].toUpperCase();
6481
+ const rest = dirName.slice(3).replace(/-/g, "\\");
6482
+ return `${drive}:\\${rest}`;
6483
+ }
6484
+ return "/" + dirName.replace(/^-/, "").replace(/-/g, "/");
6485
+ }
6486
+ function resolveProjectDirName(dirName, deps = {}) {
6487
+ const structural = decodeProjectDirName(dirName);
6488
+ if (!dirName)
6489
+ return structural;
6490
+ if (looksWindowsEncoded(dirName))
6491
+ return structural;
6492
+ const readdir3 = deps.readdir ?? ((p) => readdirSync5(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name));
6493
+ const encodeName = (name) => name.replace(/[-_.]/g, "-");
6494
+ let remaining = dirName.replace(/^-/, "");
6495
+ let current = "/";
6496
+ while (remaining) {
6497
+ let children;
6498
+ try {
6499
+ children = readdir3(current);
6500
+ } catch {
6501
+ break;
6502
+ }
6503
+ let best = "";
6504
+ for (const child of children) {
6505
+ const encoded = encodeName(child);
6506
+ if (!encoded || encoded.length < best.length)
6507
+ continue;
6508
+ if (!remaining.startsWith(encoded))
6509
+ continue;
6510
+ const next = remaining[encoded.length];
6511
+ if (next !== void 0 && next !== "-")
6512
+ continue;
6513
+ if (encoded.length > best.length)
6514
+ best = child;
6515
+ }
6516
+ if (!best)
6517
+ break;
6518
+ current = current === "/" ? `/${best}` : `${current}/${best}`;
6519
+ remaining = remaining.slice(encodeName(best).length).replace(/^-/, "");
6520
+ }
6521
+ return remaining ? structural : current;
6522
+ }
6523
+ var init_project_dir_name = __esm({
6524
+ "../engine/dist/core/project-dir-name.js"() {
6525
+ "use strict";
6526
+ }
6527
+ });
6528
+
6471
6529
  // ../engine/dist/core/model-pricing.js
6472
6530
  function pricingFor(modelId) {
6473
6531
  if (!modelId)
@@ -6639,9 +6697,9 @@ var init_model_pricing = __esm({
6639
6697
  });
6640
6698
 
6641
6699
  // ../engine/dist/parsers/session.js
6642
- import { createReadStream, existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync3, statSync as statSync5, openSync, readSync, closeSync } from "fs";
6700
+ import { createReadStream, existsSync as existsSync6, readdirSync as readdirSync6, readFileSync as readFileSync3, statSync as statSync6, openSync, readSync, closeSync } from "fs";
6643
6701
  import { createInterface } from "readline";
6644
- import { join as join6, basename as basename3 } from "path";
6702
+ import { join as join7, basename as basename3 } from "path";
6645
6703
  function removeCodeBlocks(text) {
6646
6704
  let result = text.replace(/```[\s\S]*?```/g, "[code block]");
6647
6705
  result = result.replace(/`[^`]+`/g, "[code]");
@@ -6710,12 +6768,12 @@ function* iterAllSessionIndices(claudeDir) {
6710
6768
  if (!existsSync6(dir)) {
6711
6769
  return;
6712
6770
  }
6713
- const entries = readdirSync5(dir, { withFileTypes: true });
6771
+ const entries = readdirSync6(dir, { withFileTypes: true });
6714
6772
  for (const entry of entries) {
6715
6773
  if (!entry.isDirectory())
6716
6774
  continue;
6717
- const projectDir = join6(dir, entry.name);
6718
- const indexPath = join6(projectDir, "sessions-index.json");
6775
+ const projectDir = join7(dir, entry.name);
6776
+ const indexPath = join7(projectDir, "sessions-index.json");
6719
6777
  if (existsSync6(indexPath)) {
6720
6778
  const sessions = parseSessionsIndex(indexPath);
6721
6779
  if (sessions.length > 0) {
@@ -6726,13 +6784,13 @@ function* iterAllSessionIndices(claudeDir) {
6726
6784
  }
6727
6785
  function hasSubagentsDir(sessionPath) {
6728
6786
  const dir = sessionPath.slice(0, -6);
6729
- return existsSync6(join6(dir, "subagents"));
6787
+ return existsSync6(join7(dir, "subagents"));
6730
6788
  }
6731
6789
  function getSubagentPaths(sessionPath) {
6732
- const subagentsDir = join6(sessionPath.slice(0, -6), "subagents");
6790
+ const subagentsDir = join7(sessionPath.slice(0, -6), "subagents");
6733
6791
  if (!existsSync6(subagentsDir))
6734
6792
  return [];
6735
- return readdirSync5(subagentsDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join6(subagentsDir, f));
6793
+ return readdirSync6(subagentsDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join7(subagentsDir, f));
6736
6794
  }
6737
6795
  function getSubagentProjectPath(sessionPath, folderDerivedPath) {
6738
6796
  const subagentPaths = getSubagentPaths(sessionPath);
@@ -6799,12 +6857,12 @@ function readCwdFromJsonl(sessionPath) {
6799
6857
  function getSessionMtime(sessionPath) {
6800
6858
  const subagentPaths = getSubagentPaths(sessionPath);
6801
6859
  if (subagentPaths.length === 0) {
6802
- return statSync5(sessionPath).mtimeMs;
6860
+ return statSync6(sessionPath).mtimeMs;
6803
6861
  }
6804
- let maxMtime = statSync5(sessionPath).mtimeMs;
6862
+ let maxMtime = statSync6(sessionPath).mtimeMs;
6805
6863
  for (const p of subagentPaths) {
6806
6864
  try {
6807
- const m = statSync5(p).mtimeMs;
6865
+ const m = statSync6(p).mtimeMs;
6808
6866
  if (m > maxMtime)
6809
6867
  maxMtime = m;
6810
6868
  } catch {
@@ -7049,40 +7107,6 @@ ${resultText}` : resultText;
7049
7107
  });
7050
7108
  return content;
7051
7109
  }
7052
- function decodeDirName(dirName) {
7053
- const segments = dirName.replace(/^-/, "").split("-");
7054
- let currentPath = "/";
7055
- let i = 0;
7056
- while (i < segments.length) {
7057
- let matched = false;
7058
- const singleCandidate = join6(currentPath, segments[i]);
7059
- if (existsSync6(singleCandidate)) {
7060
- currentPath = singleCandidate;
7061
- i++;
7062
- matched = true;
7063
- continue;
7064
- }
7065
- for (let len = 2; len <= segments.length - i; len++) {
7066
- const joinedSegments = segments.slice(i, i + len);
7067
- for (const sep4 of ["-", "_", "."]) {
7068
- const candidate = join6(currentPath, joinedSegments.join(sep4));
7069
- if (existsSync6(candidate)) {
7070
- currentPath = candidate;
7071
- i += len;
7072
- matched = true;
7073
- break;
7074
- }
7075
- }
7076
- if (matched)
7077
- break;
7078
- }
7079
- if (!matched) {
7080
- currentPath = join6(currentPath, segments[i]);
7081
- i++;
7082
- }
7083
- }
7084
- return currentPath;
7085
- }
7086
7110
  function* getAllSessions(claudeDir) {
7087
7111
  const seenSessionIds = /* @__PURE__ */ new Set();
7088
7112
  const projectDirs = claudeDir ? [claudeDir] : claudeProjectDirs();
@@ -7097,12 +7121,12 @@ function* getAllSessions(claudeDir) {
7097
7121
  }
7098
7122
  if (!existsSync6(dir))
7099
7123
  continue;
7100
- const dirEntries = readdirSync5(dir, { withFileTypes: true });
7124
+ const dirEntries = readdirSync6(dir, { withFileTypes: true });
7101
7125
  for (const projDirEntry of dirEntries) {
7102
7126
  if (!projDirEntry.isDirectory())
7103
7127
  continue;
7104
- const projectPath = join6(dir, projDirEntry.name);
7105
- const files = readdirSync5(projectPath);
7128
+ const projectPath = join7(dir, projDirEntry.name);
7129
+ const files = readdirSync6(projectPath);
7106
7130
  for (const file of files) {
7107
7131
  if (!file.endsWith(".jsonl"))
7108
7132
  continue;
@@ -7113,10 +7137,10 @@ function* getAllSessions(claudeDir) {
7113
7137
  const sessionId = basename3(file, ".jsonl");
7114
7138
  if (seenSessionIds.has(sessionId))
7115
7139
  continue;
7116
- const fullPath = join6(projectPath, file);
7140
+ const fullPath = join7(projectPath, file);
7117
7141
  try {
7118
- const stat3 = statSync5(fullPath);
7119
- const derivedProjectPath = decodeDirName(projDirEntry.name);
7142
+ const stat3 = statSync6(fullPath);
7143
+ const derivedProjectPath = resolveProjectDirName(projDirEntry.name);
7120
7144
  const effectiveMtime = getSessionMtime(fullPath);
7121
7145
  let projectPath2 = "";
7122
7146
  if (hasSubagentsDir(fullPath)) {
@@ -7155,13 +7179,14 @@ var init_session = __esm({
7155
7179
  init_chunker();
7156
7180
  init_claude2();
7157
7181
  init_tool_paths();
7182
+ init_project_dir_name();
7158
7183
  init_model_pricing();
7159
7184
  }
7160
7185
  });
7161
7186
 
7162
7187
  // ../engine/dist/transcript/claude.js
7163
7188
  import { open, readdir, readFile, stat } from "fs/promises";
7164
- import { dirname as dirname6, join as join7, basename as basename4 } from "path";
7189
+ import { dirname as dirname7, join as join8, basename as basename4 } from "path";
7165
7190
  function stripBanners(text) {
7166
7191
  let out = text;
7167
7192
  for (const re of INJECTED_BANNERS2)
@@ -7278,7 +7303,7 @@ function messagesFromRawLines(raw) {
7278
7303
  }
7279
7304
  async function parseClaudeSubagents(sessionPath) {
7280
7305
  const sessionId = basename4(sessionPath).replace(/\.jsonl$/i, "");
7281
- const subagentsDir = join7(dirname6(sessionPath), sessionId, "subagents");
7306
+ const subagentsDir = join8(dirname7(sessionPath), sessionId, "subagents");
7282
7307
  let entries;
7283
7308
  try {
7284
7309
  entries = await readdir(subagentsDir);
@@ -7288,12 +7313,12 @@ async function parseClaudeSubagents(sessionPath) {
7288
7313
  const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
7289
7314
  const subagents = [];
7290
7315
  for (const fileName of jsonlFiles) {
7291
- const filePath = join7(subagentsDir, fileName);
7316
+ const filePath = join8(subagentsDir, fileName);
7292
7317
  const id = fileName.replace(/\.jsonl$/i, "");
7293
7318
  const kind = id.includes("acompact") ? "compact" : id.includes("aside_question") ? "aside" : id.includes("explore") || /^agent-a[0-9a-f]{16,}$/i.test(id) ? "explore" : "other";
7294
7319
  let agentType;
7295
7320
  let description;
7296
- const metaPath = join7(subagentsDir, `${id}.meta.json`);
7321
+ const metaPath = join8(subagentsDir, `${id}.meta.json`);
7297
7322
  try {
7298
7323
  const metaRaw = await readFile(metaPath, "utf-8");
7299
7324
  const meta = JSON.parse(metaRaw);
@@ -7416,9 +7441,9 @@ var init_gemini = __esm({
7416
7441
 
7417
7442
  // ../engine/dist/transcript/codex.js
7418
7443
  import { open as open2, readdir as readdir2, stat as stat2 } from "fs/promises";
7419
- import { dirname as dirname7, join as join8, basename as basename5 } from "path";
7444
+ import { dirname as dirname8, join as join9, basename as basename5 } from "path";
7420
7445
  async function parseCodexSubagents(sessionPath) {
7421
- const dayDir = dirname7(sessionPath);
7446
+ const dayDir = dirname8(sessionPath);
7422
7447
  const parentId = basename5(sessionPath).match(/([a-f0-9-]{36})\.jsonl$/i)?.[1];
7423
7448
  if (!parentId)
7424
7449
  return [];
@@ -7432,7 +7457,7 @@ async function parseCodexSubagents(sessionPath) {
7432
7457
  for (const fileName of entries) {
7433
7458
  if (!fileName.endsWith(".jsonl") || !fileName.startsWith("rollout-"))
7434
7459
  continue;
7435
- const filePath = join8(dayDir, fileName);
7460
+ const filePath = join9(dayDir, fileName);
7436
7461
  if (filePath === sessionPath)
7437
7462
  continue;
7438
7463
  let firstLine = "";
@@ -7653,7 +7678,7 @@ __export(raw_exports, {
7653
7678
  parseTranscriptFromContainer: () => parseTranscriptFromContainer
7654
7679
  });
7655
7680
  import { gzipSync, gunzipSync } from "zlib";
7656
- import { createHash as createHash2 } from "crypto";
7681
+ import { createHash as createHash3 } from "crypto";
7657
7682
  import * as fsMod from "fs";
7658
7683
  import * as pathMod from "path";
7659
7684
  function buildRawContainer(exp) {
@@ -7665,7 +7690,7 @@ function buildRawContainer(exp) {
7665
7690
  };
7666
7691
  }
7667
7692
  function containerSrcHash(c) {
7668
- const h = createHash2("sha1");
7693
+ const h = createHash3("sha1");
7669
7694
  h.update(c.tool);
7670
7695
  for (const f of c.files) {
7671
7696
  h.update("\0");
@@ -7813,8 +7838,8 @@ async function archiveRawSession(store2, sessionId) {
7813
7838
  return await store2.putRawSession(sessionId, exp.tool, Math.floor(exp.mtime), gz, size);
7814
7839
  }
7815
7840
  function detectForkPredecessor(sessionPath) {
7816
- const { readFileSync: readFileSync44, readdirSync: readdirSync35 } = requireFs();
7817
- const { dirname: dirname20, join: join53, basename: basename25 } = requirePath();
7841
+ const { readFileSync: readFileSync44, readdirSync: readdirSync36 } = requireFs();
7842
+ const { dirname: dirname21, join: join54, basename: basename25 } = requirePath();
7818
7843
  let text;
7819
7844
  try {
7820
7845
  text = readFileSync44(sessionPath, "utf-8");
@@ -7839,11 +7864,11 @@ function detectForkPredecessor(sessionPath) {
7839
7864
  return null;
7840
7865
  if (text.includes(`"uuid":"${headParent}"`))
7841
7866
  return null;
7842
- const dir = dirname20(sessionPath);
7867
+ const dir = dirname21(sessionPath);
7843
7868
  const self = basename25(sessionPath);
7844
7869
  let entries;
7845
7870
  try {
7846
- entries = readdirSync35(dir);
7871
+ entries = readdirSync36(dir);
7847
7872
  } catch {
7848
7873
  return null;
7849
7874
  }
@@ -7851,7 +7876,7 @@ function detectForkPredecessor(sessionPath) {
7851
7876
  if (!f.endsWith(".jsonl") || f === self || f === "sessions-index.json")
7852
7877
  continue;
7853
7878
  try {
7854
- if (readFileSync44(join53(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
7879
+ if (readFileSync44(join54(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
7855
7880
  return basename25(f, ".jsonl");
7856
7881
  }
7857
7882
  } catch {
@@ -7878,15 +7903,15 @@ var init_raw = __esm({
7878
7903
 
7879
7904
  // ../engine/dist/transcript/shadow.js
7880
7905
  import { gzipSync as gzipSync2, gunzipSync as gunzipSync2 } from "zlib";
7881
- import { createHash as createHash3 } from "crypto";
7882
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync as renameSync2, statSync as statSync6 } from "fs";
7883
- import { dirname as dirname8, join as join9 } from "path";
7906
+ import { createHash as createHash4 } from "crypto";
7907
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync as renameSync2, statSync as statSync7 } from "fs";
7908
+ import { dirname as dirname9, join as join10 } from "path";
7884
7909
  function shadowRoot() {
7885
- return join9(getDataDir(), "shadow");
7910
+ return join10(getDataDir(), "shadow");
7886
7911
  }
7887
7912
  function shadowFileFor(tool, rawId) {
7888
7913
  const safe = rawId.replace(/[^A-Za-z0-9._-]/g, "_");
7889
- return join9(shadowRoot(), tool, `${safe}.gz`);
7914
+ return join10(shadowRoot(), tool, `${safe}.gz`);
7890
7915
  }
7891
7916
  function readShadowContainer(tool, rawId) {
7892
7917
  const path = shadowFileFor(tool, rawId);
@@ -7902,14 +7927,14 @@ function readShadowContainer(tool, rawId) {
7902
7927
  }
7903
7928
  function writeShadowContainer(tool, rawId, container) {
7904
7929
  const path = shadowFileFor(tool, rawId);
7905
- mkdirSync3(dirname8(path), { recursive: true });
7930
+ mkdirSync4(dirname9(path), { recursive: true });
7906
7931
  const gz = gzipSync2(JSON.stringify(container), { level: 6 });
7907
7932
  const tmp = `${path}.tmp-${process.pid}`;
7908
7933
  writeFileSync2(tmp, gz);
7909
7934
  renameSync2(tmp, path);
7910
7935
  }
7911
7936
  function sha1(s) {
7912
- return createHash3("sha1").update(s).digest("hex");
7937
+ return createHash4("sha1").update(s).digest("hex");
7913
7938
  }
7914
7939
  function lineKey(line) {
7915
7940
  try {
@@ -8066,32 +8091,12 @@ var init_shadow = __esm({
8066
8091
  }
8067
8092
  });
8068
8093
 
8069
- // ../engine/dist/core/project-dir-name.js
8070
- function looksWindowsEncoded(dirName) {
8071
- return /^[A-Za-z]--/.test(dirName);
8072
- }
8073
- function decodeProjectDirName(dirName) {
8074
- if (!dirName)
8075
- return "";
8076
- if (looksWindowsEncoded(dirName)) {
8077
- const drive = dirName[0].toUpperCase();
8078
- const rest = dirName.slice(3).replace(/-/g, "\\");
8079
- return `${drive}:\\${rest}`;
8080
- }
8081
- return "/" + dirName.replace(/^-/, "").replace(/-/g, "/");
8082
- }
8083
- var init_project_dir_name = __esm({
8084
- "../engine/dist/core/project-dir-name.js"() {
8085
- "use strict";
8086
- }
8087
- });
8088
-
8089
8094
  // ../engine/dist/core/live-session-scan.js
8090
- import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as readFileSync5, statSync as statSync7, openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
8091
- import { join as join10, basename as basename6 } from "path";
8092
- import { createHash as createHash4 } from "crypto";
8095
+ import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync5, statSync as statSync8, openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
8096
+ import { join as join11, basename as basename6 } from "path";
8097
+ import { createHash as createHash5 } from "crypto";
8093
8098
  function lazyGeminiProjectsJson() {
8094
- return join10(geminiHomeDir(), "projects.json");
8099
+ return join11(geminiHomeDir(), "projects.json");
8095
8100
  }
8096
8101
  function detectTool(sessionId) {
8097
8102
  return getBackendForId(sessionId)?.id ?? "claude";
@@ -8124,17 +8129,17 @@ function sessionFileIndex() {
8124
8129
  seenRoots.add(root);
8125
8130
  let entries;
8126
8131
  try {
8127
- entries = readdirSync6(root, { withFileTypes: true });
8132
+ entries = readdirSync7(root, { withFileTypes: true });
8128
8133
  } catch {
8129
8134
  continue;
8130
8135
  }
8131
8136
  for (const entry of entries) {
8132
8137
  if (!entry.isDirectory())
8133
8138
  continue;
8134
- const dir = join10(root, entry.name);
8139
+ const dir = join11(root, entry.name);
8135
8140
  let names;
8136
8141
  try {
8137
- names = readdirSync6(dir);
8142
+ names = readdirSync7(dir);
8138
8143
  } catch {
8139
8144
  continue;
8140
8145
  }
@@ -8143,9 +8148,9 @@ function sessionFileIndex() {
8143
8148
  continue;
8144
8149
  const id = name.slice(0, -".jsonl".length);
8145
8150
  const located = {
8146
- path: join10(dir, name),
8151
+ path: join11(dir, name),
8147
8152
  projectDir: entry.name,
8148
- projectPath: decodeProjectDirName(entry.name)
8153
+ projectPath: resolveProjectDirName(entry.name)
8149
8154
  };
8150
8155
  const prior = byId.get(id);
8151
8156
  if (prior)
@@ -8196,7 +8201,7 @@ function readSessionGroupText(group) {
8196
8201
  const parts = [];
8197
8202
  for (const p of group.paths) {
8198
8203
  try {
8199
- const st = statSync7(p);
8204
+ const st = statSync8(p);
8200
8205
  parts.push(`${p}:${st.mtimeMs}:${st.size}`);
8201
8206
  } catch {
8202
8207
  parts.push(`${p}:missing`);
@@ -8216,7 +8221,7 @@ function readSessionGroupText(group) {
8216
8221
  continue;
8217
8222
  }
8218
8223
  try {
8219
- mtime = Math.max(mtime, statSync7(p).mtimeMs);
8224
+ mtime = Math.max(mtime, statSync8(p).mtimeMs);
8220
8225
  } catch {
8221
8226
  }
8222
8227
  text = text ? mergeLineText(text, raw).text : raw;
@@ -8229,10 +8234,10 @@ function readSessionGroupText(group) {
8229
8234
  function resolveSessionContentPaths(sessionFile) {
8230
8235
  if (!hasSubagentsDir(sessionFile))
8231
8236
  return [sessionFile];
8232
- const subDir = join10(sessionFile.slice(0, -6), "subagents");
8237
+ const subDir = join11(sessionFile.slice(0, -6), "subagents");
8233
8238
  if (!existsSync8(subDir))
8234
8239
  return [sessionFile];
8235
- const subPaths = readdirSync6(subDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join10(subDir, f));
8240
+ const subPaths = readdirSync7(subDir).filter((f) => f.endsWith(".jsonl")).sort().map((f) => join11(subDir, f));
8236
8241
  return [sessionFile, ...subPaths];
8237
8242
  }
8238
8243
  function loadGeminiProjectMap() {
@@ -8244,7 +8249,7 @@ function loadGeminiProjectMap() {
8244
8249
  try {
8245
8250
  const data = JSON.parse(readFileSync5(projectsPath, "utf-8"));
8246
8251
  for (const path of Object.keys(data.projects || {})) {
8247
- map.set(createHash4("sha256").update(path).digest("hex"), path);
8252
+ map.set(createHash5("sha256").update(path).digest("hex"), path);
8248
8253
  }
8249
8254
  } catch {
8250
8255
  }
@@ -8280,19 +8285,19 @@ function geminiIndex() {
8280
8285
  continue;
8281
8286
  let projs;
8282
8287
  try {
8283
- projs = readdirSync6(tmpRoot, { withFileTypes: true });
8288
+ projs = readdirSync7(tmpRoot, { withFileTypes: true });
8284
8289
  } catch {
8285
8290
  continue;
8286
8291
  }
8287
8292
  for (const proj of projs) {
8288
8293
  if (!proj.isDirectory())
8289
8294
  continue;
8290
- const chats = join10(tmpRoot, proj.name, "chats");
8295
+ const chats = join11(tmpRoot, proj.name, "chats");
8291
8296
  if (!existsSync8(chats))
8292
8297
  continue;
8293
8298
  let files;
8294
8299
  try {
8295
- files = readdirSync6(chats);
8300
+ files = readdirSync7(chats);
8296
8301
  } catch {
8297
8302
  continue;
8298
8303
  }
@@ -8301,7 +8306,7 @@ function geminiIndex() {
8301
8306
  continue;
8302
8307
  const base = f.replace(/\.jsonl?$/, "");
8303
8308
  const located = {
8304
- path: join10(chats, f),
8309
+ path: join11(chats, f),
8305
8310
  projectDir: proj.name,
8306
8311
  projectPath: projMap.get(proj.name) || "",
8307
8312
  format: f.endsWith(".jsonl") ? "jsonl" : "json"
@@ -8411,21 +8416,21 @@ function findCodexSessionFile(sessionId) {
8411
8416
  function findCodexSessionFileIn(root, sessionId) {
8412
8417
  if (!existsSync8(root))
8413
8418
  return null;
8414
- for (const year of readdirSync6(root, { withFileTypes: true })) {
8419
+ for (const year of readdirSync7(root, { withFileTypes: true })) {
8415
8420
  if (!year.isDirectory())
8416
8421
  continue;
8417
- const yearPath = join10(root, year.name);
8418
- for (const month of readdirSync6(yearPath, { withFileTypes: true })) {
8422
+ const yearPath = join11(root, year.name);
8423
+ for (const month of readdirSync7(yearPath, { withFileTypes: true })) {
8419
8424
  if (!month.isDirectory())
8420
8425
  continue;
8421
- const monthPath = join10(yearPath, month.name);
8422
- for (const day of readdirSync6(monthPath, { withFileTypes: true })) {
8426
+ const monthPath = join11(yearPath, month.name);
8427
+ for (const day of readdirSync7(monthPath, { withFileTypes: true })) {
8423
8428
  if (!day.isDirectory())
8424
8429
  continue;
8425
- const dayPath = join10(monthPath, day.name);
8430
+ const dayPath = join11(monthPath, day.name);
8426
8431
  let files;
8427
8432
  try {
8428
- files = readdirSync6(dayPath);
8433
+ files = readdirSync7(dayPath);
8429
8434
  } catch {
8430
8435
  continue;
8431
8436
  }
@@ -8433,20 +8438,20 @@ function findCodexSessionFileIn(root, sessionId) {
8433
8438
  if (!f.endsWith(".jsonl"))
8434
8439
  continue;
8435
8440
  if (f.includes(sessionId)) {
8436
- return { path: join10(dayPath, f), projectPath: "" };
8441
+ return { path: join11(dayPath, f), projectPath: "" };
8437
8442
  }
8438
8443
  }
8439
8444
  }
8440
8445
  }
8441
8446
  }
8442
8447
  function scanDir(dir) {
8443
- for (const entry of readdirSync6(dir, { withFileTypes: true })) {
8448
+ for (const entry of readdirSync7(dir, { withFileTypes: true })) {
8444
8449
  if (entry.isDirectory()) {
8445
- const found = scanDir(join10(dir, entry.name));
8450
+ const found = scanDir(join11(dir, entry.name));
8446
8451
  if (found)
8447
8452
  return found;
8448
8453
  } else if (entry.name.endsWith(".jsonl")) {
8449
- const p = join10(dir, entry.name);
8454
+ const p = join11(dir, entry.name);
8450
8455
  try {
8451
8456
  const first = readFileSync5(p, "utf-8").split("\n")[0];
8452
8457
  if (!first)
@@ -8590,15 +8595,15 @@ var init_session_sentiment = __esm({
8590
8595
 
8591
8596
  // ../engine/dist/core/session-replay.js
8592
8597
  import { existsSync as existsSync9 } from "fs";
8593
- import { dirname as dirname9, resolve as pathResolve } from "path";
8598
+ import { dirname as dirname10, resolve as pathResolve } from "path";
8594
8599
  function findRepoRoot(filePath) {
8595
8600
  if (!filePath)
8596
8601
  return null;
8597
- let dir = pathResolve(dirname9(filePath));
8602
+ let dir = pathResolve(dirname10(filePath));
8598
8603
  for (let i = 0; i < 64; i++) {
8599
8604
  if (existsSync9(`${dir}/.git`))
8600
8605
  return dir;
8601
- const parent = dirname9(dir);
8606
+ const parent = dirname10(dir);
8602
8607
  if (parent === dir)
8603
8608
  return null;
8604
8609
  dir = parent;
@@ -9064,11 +9069,11 @@ var init_first_prompt = __esm({
9064
9069
  });
9065
9070
 
9066
9071
  // ../engine/dist/core/backends/tail-read.js
9067
- import { openSync as openSync4, readSync as readSync4, closeSync as closeSync4, statSync as statSync8 } from "node:fs";
9072
+ import { openSync as openSync4, readSync as readSync4, closeSync as closeSync4, statSync as statSync9 } from "node:fs";
9068
9073
  function readTailFromOffset(path, offset) {
9069
9074
  let size = 0;
9070
9075
  try {
9071
- size = statSync8(path).size;
9076
+ size = statSync9(path).size;
9072
9077
  } catch {
9073
9078
  return { text: "", newOffset: offset };
9074
9079
  }
@@ -9385,8 +9390,8 @@ var init_generic_engine = __esm({
9385
9390
  });
9386
9391
 
9387
9392
  // ../engine/dist/core/backends/claude.js
9388
- import { existsSync as existsSync11, readdirSync as readdirSync7, readFileSync as readFileSync6, statSync as statSync9, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "fs";
9389
- import { join as join11, basename as basename9 } from "path";
9393
+ import { existsSync as existsSync11, readdirSync as readdirSync8, readFileSync as readFileSync6, statSync as statSync10, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "fs";
9394
+ import { join as join12, basename as basename9 } from "path";
9390
9395
  function stripReminders(text) {
9391
9396
  return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
9392
9397
  }
@@ -9416,41 +9421,41 @@ var init_claude2 = __esm({
9416
9421
  }
9417
9422
  // ── Subpath helpers used by the parser/source layer ─────────────
9418
9423
  projectsDir() {
9419
- return join11(this.homeDir(), "projects");
9424
+ return join12(this.homeDir(), "projects");
9420
9425
  }
9421
9426
  plansDir() {
9422
- return join11(this.homeDir(), "plans");
9427
+ return join12(this.homeDir(), "plans");
9423
9428
  }
9424
9429
  todosDir() {
9425
- return join11(this.homeDir(), "todos");
9430
+ return join12(this.homeDir(), "todos");
9426
9431
  }
9427
9432
  /** Legacy task-list directory still used by older Claude Code releases. */
9428
9433
  tasksDir() {
9429
- return join11(this.homeDir(), "tasks");
9434
+ return join12(this.homeDir(), "tasks");
9430
9435
  }
9431
9436
  pasteCacheDir() {
9432
- return join11(this.homeDir(), "paste-cache");
9437
+ return join12(this.homeDir(), "paste-cache");
9433
9438
  }
9434
9439
  skillsDir() {
9435
- return join11(this.homeDir(), "skills");
9440
+ return join12(this.homeDir(), "skills");
9436
9441
  }
9437
9442
  agentsDir() {
9438
- return join11(this.homeDir(), "agents");
9443
+ return join12(this.homeDir(), "agents");
9439
9444
  }
9440
9445
  commandsDir() {
9441
- return join11(this.homeDir(), "commands");
9446
+ return join12(this.homeDir(), "commands");
9442
9447
  }
9443
9448
  pluginsManifestPath() {
9444
- return join11(this.homeDir(), "plugins", "installed_plugins.json");
9449
+ return join12(this.homeDir(), "plugins", "installed_plugins.json");
9445
9450
  }
9446
9451
  hooksFile() {
9447
- return join11(this.homeDir(), "hooks.json");
9452
+ return join12(this.homeDir(), "hooks.json");
9448
9453
  }
9449
9454
  settingsFile() {
9450
- return join11(this.homeDir(), "settings.json");
9455
+ return join12(this.homeDir(), "settings.json");
9451
9456
  }
9452
9457
  historyFile() {
9453
- return join11(this.homeDir(), "history.jsonl");
9458
+ return join12(this.homeDir(), "history.jsonl");
9454
9459
  }
9455
9460
  isAvailable() {
9456
9461
  return existsSync11(this.projectsDir());
@@ -9514,7 +9519,7 @@ var init_claude2 = __esm({
9514
9519
  let mtime = 0;
9515
9520
  for (const c of copies) {
9516
9521
  try {
9517
- mtime = Math.max(mtime, statSync9(c.path).mtimeMs);
9522
+ mtime = Math.max(mtime, statSync10(c.path).mtimeMs);
9518
9523
  } catch {
9519
9524
  }
9520
9525
  }
@@ -9540,14 +9545,14 @@ var init_claude2 = __esm({
9540
9545
  collectSessionsFromRoot(root, cutoff, filter, seen, out) {
9541
9546
  if (!existsSync11(root))
9542
9547
  return;
9543
- for (const proj of readdirSync7(root, { withFileTypes: true })) {
9548
+ for (const proj of readdirSync8(root, { withFileTypes: true })) {
9544
9549
  if (!proj.isDirectory())
9545
9550
  continue;
9546
9551
  if (filter && !proj.name.toLowerCase().includes(filter))
9547
9552
  continue;
9548
- const projPath = join11(root, proj.name);
9549
- const projectPath = decodeProjectDirName(proj.name);
9550
- const indexPath = join11(projPath, "sessions-index.json");
9553
+ const projPath = join12(root, proj.name);
9554
+ const projectPath = resolveProjectDirName(proj.name);
9555
+ const indexPath = join12(projPath, "sessions-index.json");
9551
9556
  if (existsSync11(indexPath)) {
9552
9557
  try {
9553
9558
  const indexData = JSON.parse(readFileSync6(indexPath, "utf-8"));
@@ -9577,7 +9582,7 @@ var init_claude2 = __esm({
9577
9582
  }
9578
9583
  let files;
9579
9584
  try {
9580
- files = readdirSync7(projPath);
9585
+ files = readdirSync8(projPath);
9581
9586
  } catch {
9582
9587
  continue;
9583
9588
  }
@@ -9587,10 +9592,10 @@ var init_claude2 = __esm({
9587
9592
  const sessionId = basename9(f, ".jsonl");
9588
9593
  if (seen.has(sessionId))
9589
9594
  continue;
9590
- const fullPath = join11(projPath, f);
9595
+ const fullPath = join12(projPath, f);
9591
9596
  let stat3;
9592
9597
  try {
9593
- stat3 = statSync9(fullPath);
9598
+ stat3 = statSync10(fullPath);
9594
9599
  } catch {
9595
9600
  continue;
9596
9601
  }
@@ -9808,7 +9813,7 @@ var init_claude2 = __esm({
9808
9813
  const events = this.readEvents(rawId);
9809
9814
  let fileMtime = 0;
9810
9815
  try {
9811
- fileMtime = statSync9(located.path).mtimeMs;
9816
+ fileMtime = statSync10(located.path).mtimeMs;
9812
9817
  } catch {
9813
9818
  }
9814
9819
  return liveScanEditsFromEvents(events, this.fileToolMap, {
@@ -9846,30 +9851,30 @@ var init_claude2 = __esm({
9846
9851
  for (const root of claudeProjectDirs()) {
9847
9852
  if (!existsSync11(root))
9848
9853
  continue;
9849
- for (const projEntry of readdirSync7(root, { withFileTypes: true })) {
9854
+ for (const projEntry of readdirSync8(root, { withFileTypes: true })) {
9850
9855
  if (!projEntry.isDirectory())
9851
9856
  continue;
9852
9857
  if (opts.projectFilter && !projEntry.name.toLowerCase().includes(opts.projectFilter.toLowerCase()))
9853
9858
  continue;
9854
- const projPath = join11(root, projEntry.name);
9859
+ const projPath = join12(root, projEntry.name);
9855
9860
  let files;
9856
9861
  try {
9857
- files = readdirSync7(projPath);
9862
+ files = readdirSync8(projPath);
9858
9863
  } catch {
9859
9864
  continue;
9860
9865
  }
9861
9866
  for (const f of files) {
9862
9867
  if (!f.endsWith(".jsonl") || f === "sessions-index.json")
9863
9868
  continue;
9864
- const fp = join11(projPath, f);
9869
+ const fp = join12(projPath, f);
9865
9870
  try {
9866
- const st = statSync9(fp);
9871
+ const st = statSync10(fp);
9867
9872
  let mtime = st.mtimeMs;
9868
- const subDir = join11(projPath, f.slice(0, -6), "subagents");
9873
+ const subDir = join12(projPath, f.slice(0, -6), "subagents");
9869
9874
  if (existsSync11(subDir)) {
9870
- for (const sub of readdirSync7(subDir)) {
9875
+ for (const sub of readdirSync8(subDir)) {
9871
9876
  try {
9872
- const subSt = statSync9(join11(subDir, sub));
9877
+ const subSt = statSync10(join12(subDir, sub));
9873
9878
  if (subSt.mtimeMs > mtime)
9874
9879
  mtime = subSt.mtimeMs;
9875
9880
  } catch {
@@ -9934,7 +9939,7 @@ var init_claude2 = __esm({
9934
9939
  let total = 0;
9935
9940
  for (const located of findSessionFiles(this.toRawId(prefixedId))) {
9936
9941
  try {
9937
- total += statSync9(located.path).size;
9942
+ total += statSync10(located.path).size;
9938
9943
  } catch {
9939
9944
  }
9940
9945
  }
@@ -9971,9 +9976,9 @@ var init_claude2 = __esm({
9971
9976
  });
9972
9977
 
9973
9978
  // ../engine/dist/core/backends/gemini.js
9974
- import { createHash as createHash5 } from "crypto";
9975
- import { existsSync as existsSync12, readdirSync as readdirSync8, readFileSync as readFileSync7, statSync as statSync10 } from "fs";
9976
- import { basename as basename10, join as join12 } from "path";
9979
+ import { createHash as createHash6 } from "crypto";
9980
+ import { existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync7, statSync as statSync11 } from "fs";
9981
+ import { basename as basename10, join as join13 } from "path";
9977
9982
  function readSessionId(path, format) {
9978
9983
  try {
9979
9984
  if (format === "json") {
@@ -10023,30 +10028,30 @@ var init_gemini2 = __esm({
10023
10028
  }
10024
10029
  // ── Subpath helpers ────────────────────────────────────────────
10025
10030
  tmpDir() {
10026
- return join12(this.homeDir(), "tmp");
10031
+ return join13(this.homeDir(), "tmp");
10027
10032
  }
10028
10033
  projectsJson() {
10029
- return join12(this.homeDir(), "projects.json");
10034
+ return join13(this.homeDir(), "projects.json");
10030
10035
  }
10031
10036
  settingsFile() {
10032
- return join12(this.homeDir(), "settings.json");
10037
+ return join13(this.homeDir(), "settings.json");
10033
10038
  }
10034
10039
  extensionsDir() {
10035
- return join12(this.homeDir(), "extensions");
10040
+ return join13(this.homeDir(), "extensions");
10036
10041
  }
10037
10042
  antigravityBrainDir() {
10038
- return join12(this.homeDir(), "antigravity", "brain");
10043
+ return join13(this.homeDir(), "antigravity", "brain");
10039
10044
  }
10040
10045
  // Toolkit-artifact dirs. Gemini gained first-class Skills + Agents + (TOML)
10041
10046
  // Commands; all live directly under the home dir, mirroring Claude's layout.
10042
10047
  skillsDir() {
10043
- return join12(this.homeDir(), "skills");
10048
+ return join13(this.homeDir(), "skills");
10044
10049
  }
10045
10050
  commandsDir() {
10046
- return join12(this.homeDir(), "commands");
10051
+ return join13(this.homeDir(), "commands");
10047
10052
  }
10048
10053
  agentsDir() {
10049
- return join12(this.homeDir(), "agents");
10054
+ return join13(this.homeDir(), "agents");
10050
10055
  }
10051
10056
  isAvailable() {
10052
10057
  return geminiTmpDirs().length > 0;
@@ -10068,7 +10073,7 @@ var init_gemini2 = __esm({
10068
10073
  return null;
10069
10074
  let mtime = 0;
10070
10075
  try {
10071
- mtime = statSync10(located.path).mtimeMs;
10076
+ mtime = statSync11(located.path).mtimeMs;
10072
10077
  } catch {
10073
10078
  }
10074
10079
  return {
@@ -10086,28 +10091,28 @@ var init_gemini2 = __esm({
10086
10091
  const out = [];
10087
10092
  const seen = /* @__PURE__ */ new Map();
10088
10093
  for (const root of geminiTmpDirs()) {
10089
- for (const projDir of readdirSync8(root, { withFileTypes: true })) {
10094
+ for (const projDir of readdirSync9(root, { withFileTypes: true })) {
10090
10095
  if (!projDir.isDirectory())
10091
10096
  continue;
10092
10097
  const projectPath = projMap.get(projDir.name) || "";
10093
10098
  if (filter && !projectPath.toLowerCase().includes(filter))
10094
10099
  continue;
10095
- const chatsDir = join12(root, projDir.name, "chats");
10100
+ const chatsDir = join13(root, projDir.name, "chats");
10096
10101
  if (!existsSync12(chatsDir))
10097
10102
  continue;
10098
10103
  let files;
10099
10104
  try {
10100
- files = readdirSync8(chatsDir);
10105
+ files = readdirSync9(chatsDir);
10101
10106
  } catch {
10102
10107
  continue;
10103
10108
  }
10104
10109
  for (const f of files) {
10105
10110
  if (!f.startsWith("session-") || !f.endsWith(".json") && !f.endsWith(".jsonl"))
10106
10111
  continue;
10107
- const fullPath = join12(chatsDir, f);
10112
+ const fullPath = join13(chatsDir, f);
10108
10113
  let stat3;
10109
10114
  try {
10110
- stat3 = statSync10(fullPath);
10115
+ stat3 = statSync11(fullPath);
10111
10116
  } catch {
10112
10117
  continue;
10113
10118
  }
@@ -10219,7 +10224,7 @@ var init_gemini2 = __esm({
10219
10224
  return [];
10220
10225
  let mtime = 0;
10221
10226
  try {
10222
- mtime = statSync10(located.path).mtimeMs;
10227
+ mtime = statSync11(located.path).mtimeMs;
10223
10228
  } catch {
10224
10229
  }
10225
10230
  const messages = readGeminiMessages(located.path, located.format);
@@ -10283,7 +10288,7 @@ var init_gemini2 = __esm({
10283
10288
  }
10284
10289
  let fileMtime = 0;
10285
10290
  try {
10286
- fileMtime = statSync10(located.path).mtimeMs;
10291
+ fileMtime = statSync11(located.path).mtimeMs;
10287
10292
  } catch {
10288
10293
  }
10289
10294
  const events = this.readEvents(this.toRawId(id));
@@ -10320,7 +10325,7 @@ var init_gemini2 = __esm({
10320
10325
  return [];
10321
10326
  const projMap = this.loadProjectMap();
10322
10327
  const candidates2 = [];
10323
- for (const proj of readdirSync8(tmpRoot, { withFileTypes: true })) {
10328
+ for (const proj of readdirSync9(tmpRoot, { withFileTypes: true })) {
10324
10329
  if (!proj.isDirectory())
10325
10330
  continue;
10326
10331
  const projectPath = projMap.get(proj.name) || "";
@@ -10329,12 +10334,12 @@ var init_gemini2 = __esm({
10329
10334
  if (!haystack.includes(opts.projectFilter.toLowerCase()))
10330
10335
  continue;
10331
10336
  }
10332
- const chats = join12(tmpRoot, proj.name, "chats");
10337
+ const chats = join13(tmpRoot, proj.name, "chats");
10333
10338
  if (!existsSync12(chats))
10334
10339
  continue;
10335
10340
  let files;
10336
10341
  try {
10337
- files = readdirSync8(chats);
10342
+ files = readdirSync9(chats);
10338
10343
  } catch {
10339
10344
  continue;
10340
10345
  }
@@ -10346,7 +10351,7 @@ var init_gemini2 = __esm({
10346
10351
  if (!isJsonl && !isJson)
10347
10352
  continue;
10348
10353
  try {
10349
- const st = statSync10(join12(chats, f));
10354
+ const st = statSync11(join13(chats, f));
10350
10355
  if (st.mtimeMs < opts.sinceMs)
10351
10356
  continue;
10352
10357
  const trimLen = isJsonl ? 6 : 5;
@@ -10378,7 +10383,7 @@ var init_gemini2 = __esm({
10378
10383
  const json = JSON.parse(readFileSync7(path, "utf-8"));
10379
10384
  const projects = json?.projects ?? {};
10380
10385
  for (const projectPath of Object.keys(projects)) {
10381
- const hash = createHash5("sha256").update(projectPath).digest("hex");
10386
+ const hash = createHash6("sha256").update(projectPath).digest("hex");
10382
10387
  map.set(hash, projectPath);
10383
10388
  }
10384
10389
  } catch {
@@ -10392,7 +10397,7 @@ var init_gemini2 = __esm({
10392
10397
  try {
10393
10398
  return {
10394
10399
  tool: "gemini",
10395
- mtime: statSync10(loc.path).mtimeMs,
10400
+ mtime: statSync11(loc.path).mtimeMs,
10396
10401
  files: [{ name: basename10(loc.path), bytes: readFileSync7(loc.path) }]
10397
10402
  };
10398
10403
  } catch {
@@ -10407,7 +10412,7 @@ var init_gemini2 = __esm({
10407
10412
  if (!loc)
10408
10413
  return 0;
10409
10414
  try {
10410
- return statSync10(loc.path).size;
10415
+ return statSync11(loc.path).size;
10411
10416
  } catch {
10412
10417
  return 0;
10413
10418
  }
@@ -10475,7 +10480,7 @@ __export(opencode_exports, {
10475
10480
  });
10476
10481
  import { existsSync as existsSync13 } from "fs";
10477
10482
  import { homedir as homedir4 } from "os";
10478
- import { dirname as dirname10, join as join13 } from "path";
10483
+ import { dirname as dirname11, join as join14 } from "path";
10479
10484
  function openReadonly(path) {
10480
10485
  return openSqliteReadonly(path);
10481
10486
  }
@@ -10502,15 +10507,15 @@ var init_opencode = __esm({
10502
10507
  return opencodeDbPath();
10503
10508
  }
10504
10509
  homeDir() {
10505
- return dirname10(this.dbPath());
10510
+ return dirname11(this.dbPath());
10506
10511
  }
10507
10512
  // ── Subpath helpers ────────────────────────────────────────────
10508
10513
  plansDir() {
10509
- return join13(this.homeDir(), "plans");
10514
+ return join14(this.homeDir(), "plans");
10510
10515
  }
10511
10516
  /** Root that holds OpenCode's global config dir (~/.config/opencode). */
10512
10517
  configRoot() {
10513
- return join13(process.env.HOME || homedir4(), ".config", "opencode");
10518
+ return join14(process.env.HOME || homedir4(), ".config", "opencode");
10514
10519
  }
10515
10520
  /**
10516
10521
  * Canonical OpenCode skills location. The current docs use the plural
@@ -10519,15 +10524,15 @@ var init_opencode = __esm({
10519
10524
  * plural canonical dir for "promote skill to OpenCode" actions.
10520
10525
  */
10521
10526
  skillsDir() {
10522
- return join13(this.configRoot(), "skills");
10527
+ return join14(this.configRoot(), "skills");
10523
10528
  }
10524
10529
  /** Custom slash commands — markdown with frontmatter, plural canonical dir. */
10525
10530
  commandsDir() {
10526
- return join13(this.configRoot(), "commands");
10531
+ return join14(this.configRoot(), "commands");
10527
10532
  }
10528
10533
  /** Agent/subagent definitions — markdown with frontmatter. */
10529
10534
  agentsDir() {
10530
- return join13(this.configRoot(), "agents");
10535
+ return join14(this.configRoot(), "agents");
10531
10536
  }
10532
10537
  /** Every configured OpenCode database, primary first. Unlike the other tools
10533
10538
  * OpenCode stores sessions in a FILE, so a second profile means a second db
@@ -11000,8 +11005,8 @@ var init_opencode = __esm({
11000
11005
  });
11001
11006
 
11002
11007
  // ../engine/dist/core/backends/codex.js
11003
- import { readdirSync as readdirSync9, readFileSync as readFileSync8, statSync as statSync11, openSync as openSync6, readSync as readSync6, closeSync as closeSync6 } from "fs";
11004
- import { basename as basename11, dirname as dirname11, join as join14 } from "path";
11008
+ import { readdirSync as readdirSync10, readFileSync as readFileSync8, statSync as statSync12, openSync as openSync6, readSync as readSync6, closeSync as closeSync6 } from "fs";
11009
+ import { basename as basename11, dirname as dirname12, join as join15 } from "path";
11005
11010
  function parseShellWrites(cmd) {
11006
11011
  const out = [];
11007
11012
  const firstLine = cmd.split("\n", 1)[0].trim();
@@ -11096,12 +11101,12 @@ function parseCodexPatch(input) {
11096
11101
  function* walkRollouts(root) {
11097
11102
  let entries;
11098
11103
  try {
11099
- entries = readdirSync9(root, { withFileTypes: true });
11104
+ entries = readdirSync10(root, { withFileTypes: true });
11100
11105
  } catch {
11101
11106
  return;
11102
11107
  }
11103
11108
  for (const e of entries) {
11104
- const full = join14(root, e.name);
11109
+ const full = join15(root, e.name);
11105
11110
  if (e.isDirectory()) {
11106
11111
  yield* walkRollouts(full);
11107
11112
  } else if (e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")) {
@@ -11158,29 +11163,29 @@ var init_codex2 = __esm({
11158
11163
  }
11159
11164
  // ── Subpath helpers ────────────────────────────────────────────
11160
11165
  sessionsDir() {
11161
- return join14(this.homeDir(), "sessions");
11166
+ return join15(this.homeDir(), "sessions");
11162
11167
  }
11163
11168
  configToml() {
11164
- return join14(this.homeDir(), "config.toml");
11169
+ return join15(this.homeDir(), "config.toml");
11165
11170
  }
11166
11171
  pluginsDir() {
11167
- return join14(this.homeDir(), ".tmp", "plugins", "plugins");
11172
+ return join15(this.homeDir(), ".tmp", "plugins", "plugins");
11168
11173
  }
11169
11174
  /** OpenAI-bundled, read-only system skills (imagegen, skill-creator, …). */
11170
11175
  skillsSystemDir() {
11171
- return join14(this.homeDir(), "skills", ".system");
11176
+ return join15(this.homeDir(), "skills", ".system");
11172
11177
  }
11173
11178
  /** User skills root. Direct children (excluding `.system`) are user-authored. */
11174
11179
  skillsDir() {
11175
- return join14(this.homeDir(), "skills");
11180
+ return join15(this.homeDir(), "skills");
11176
11181
  }
11177
11182
  /** Custom prompts (deprecated upstream in favor of skills) — flat *.md. */
11178
11183
  promptsDir() {
11179
- return join14(this.homeDir(), "prompts");
11184
+ return join15(this.homeDir(), "prompts");
11180
11185
  }
11181
11186
  /** Subagent definitions — one TOML file per agent. */
11182
11187
  agentsDir() {
11183
- return join14(this.homeDir(), "agents");
11188
+ return join15(this.homeDir(), "agents");
11184
11189
  }
11185
11190
  /** Any configured home having a sessions/ tree makes Codex available — a
11186
11191
  * machine whose only Codex profile is a secondary one still counts. */
@@ -11208,7 +11213,7 @@ var init_codex2 = __esm({
11208
11213
  return null;
11209
11214
  let mtime = 0;
11210
11215
  try {
11211
- mtime = statSync11(located.path).mtimeMs;
11216
+ mtime = statSync12(located.path).mtimeMs;
11212
11217
  } catch {
11213
11218
  }
11214
11219
  return {
@@ -11228,7 +11233,7 @@ var init_codex2 = __esm({
11228
11233
  for (const filePath of walkRollouts(root)) {
11229
11234
  let stat3;
11230
11235
  try {
11231
- stat3 = statSync11(filePath);
11236
+ stat3 = statSync12(filePath);
11232
11237
  } catch {
11233
11238
  continue;
11234
11239
  }
@@ -11388,7 +11393,7 @@ var init_codex2 = __esm({
11388
11393
  const dayDir = located.path.substring(0, located.path.lastIndexOf("/"));
11389
11394
  let entries = [];
11390
11395
  try {
11391
- entries = readdirSync9(dayDir);
11396
+ entries = readdirSync10(dayDir);
11392
11397
  } catch {
11393
11398
  }
11394
11399
  for (const entry of entries) {
@@ -11424,7 +11429,7 @@ var init_codex2 = __esm({
11424
11429
  let mtime = 0;
11425
11430
  try {
11426
11431
  raw = readFileSync8(path, "utf-8");
11427
- mtime = statSync11(path).mtimeMs;
11432
+ mtime = statSync12(path).mtimeMs;
11428
11433
  } catch {
11429
11434
  return [];
11430
11435
  }
@@ -11524,7 +11529,7 @@ var init_codex2 = __esm({
11524
11529
  const events = this.readEvents(this.toRawId(id));
11525
11530
  let fileMtime = 0;
11526
11531
  try {
11527
- fileMtime = statSync11(located.path).mtimeMs;
11532
+ fileMtime = statSync12(located.path).mtimeMs;
11528
11533
  } catch {
11529
11534
  }
11530
11535
  return liveScanEditsFromEvents(events, this.fileToolMap, {
@@ -11574,21 +11579,21 @@ var init_codex2 = __esm({
11574
11579
  const scanDir = (dir) => {
11575
11580
  let entries;
11576
11581
  try {
11577
- entries = readdirSync9(dir, { withFileTypes: true });
11582
+ entries = readdirSync10(dir, { withFileTypes: true });
11578
11583
  } catch {
11579
11584
  return;
11580
11585
  }
11581
11586
  for (const entry of entries) {
11582
11587
  if (entry.isDirectory()) {
11583
- scanDir(join14(dir, entry.name));
11588
+ scanDir(join15(dir, entry.name));
11584
11589
  continue;
11585
11590
  }
11586
11591
  if (!entry.name.endsWith(".jsonl"))
11587
11592
  continue;
11588
- const p = join14(dir, entry.name);
11593
+ const p = join15(dir, entry.name);
11589
11594
  let st;
11590
11595
  try {
11591
- st = statSync11(p);
11596
+ st = statSync12(p);
11592
11597
  } catch {
11593
11598
  continue;
11594
11599
  }
@@ -11655,7 +11660,7 @@ var init_codex2 = __esm({
11655
11660
  let mtime = 0;
11656
11661
  const push = (path, name) => {
11657
11662
  try {
11658
- const st = statSync11(path);
11663
+ const st = statSync12(path);
11659
11664
  files.push({ name, bytes: readFileSync8(path) });
11660
11665
  if (st.mtimeMs > mtime)
11661
11666
  mtime = st.mtimeMs;
@@ -11665,12 +11670,12 @@ var init_codex2 = __esm({
11665
11670
  push(loc.path, basename11(loc.path));
11666
11671
  const parentId = basename11(loc.path).match(/([a-f0-9-]{36})\.jsonl$/i)?.[1];
11667
11672
  if (parentId) {
11668
- const dayDir = dirname11(loc.path);
11673
+ const dayDir = dirname12(loc.path);
11669
11674
  try {
11670
- for (const f of readdirSync9(dayDir)) {
11675
+ for (const f of readdirSync10(dayDir)) {
11671
11676
  if (!f.endsWith(".jsonl") || !f.startsWith("rollout-"))
11672
11677
  continue;
11673
- const p = join14(dayDir, f);
11678
+ const p = join15(dayDir, f);
11674
11679
  if (p === loc.path)
11675
11680
  continue;
11676
11681
  try {
@@ -11697,7 +11702,7 @@ var init_codex2 = __esm({
11697
11702
  if (!loc)
11698
11703
  return 0;
11699
11704
  try {
11700
- return statSync11(loc.path).size;
11705
+ return statSync12(loc.path).size;
11701
11706
  } catch {
11702
11707
  return 0;
11703
11708
  }
@@ -11714,13 +11719,13 @@ var init_codex2 = __esm({
11714
11719
  });
11715
11720
 
11716
11721
  // ../engine/dist/core/backends/agy.js
11717
- import { existsSync as existsSync14, readdirSync as readdirSync10, readFileSync as readFileSync9, statSync as statSync12 } from "fs";
11718
- import { basename as basename12, dirname as dirname12, join as join15 } from "path";
11722
+ import { existsSync as existsSync14, readdirSync as readdirSync11, readFileSync as readFileSync9, statSync as statSync13 } from "fs";
11723
+ import { basename as basename12, dirname as dirname13, join as join16 } from "path";
11719
11724
  function agyTranscriptPath(logsDir) {
11720
- const full = join15(logsDir, "transcript_full.jsonl");
11725
+ const full = join16(logsDir, "transcript_full.jsonl");
11721
11726
  if (existsSync14(full))
11722
11727
  return full;
11723
- const primary = join15(logsDir, "transcript.jsonl");
11728
+ const primary = join16(logsDir, "transcript.jsonl");
11724
11729
  if (existsSync14(primary))
11725
11730
  return primary;
11726
11731
  return "";
@@ -11854,18 +11859,18 @@ var init_agy = __esm({
11854
11859
  }
11855
11860
  /** Resolve a session inside ONE brain root. */
11856
11861
  findSessionIn(brainDir, rawId) {
11857
- const sessionDir = join15(brainDir, rawId);
11862
+ const sessionDir = join16(brainDir, rawId);
11858
11863
  if (!existsSync14(sessionDir))
11859
11864
  return null;
11860
- const path = agyTranscriptPath(join15(sessionDir, ".system_generated", "logs"));
11865
+ const path = agyTranscriptPath(join16(sessionDir, ".system_generated", "logs"));
11861
11866
  if (!path)
11862
11867
  return null;
11863
11868
  let mtime = 0;
11864
11869
  try {
11865
- mtime = statSync12(path).mtimeMs;
11870
+ mtime = statSync13(path).mtimeMs;
11866
11871
  } catch {
11867
11872
  }
11868
- const projectPath = resolveAgyProject(dirname12(path), this.homeDir());
11873
+ const projectPath = resolveAgyProject(dirname13(path), this.homeDir());
11869
11874
  const projectDir = projectPath ? basename12(projectPath) : "";
11870
11875
  return {
11871
11876
  path,
@@ -11883,30 +11888,30 @@ var init_agy = __esm({
11883
11888
  for (const brainDir of agyBrainDirs()) {
11884
11889
  let sessionDirs;
11885
11890
  try {
11886
- sessionDirs = readdirSync10(brainDir);
11891
+ sessionDirs = readdirSync11(brainDir);
11887
11892
  } catch {
11888
11893
  continue;
11889
11894
  }
11890
11895
  for (const rawId of sessionDirs) {
11891
- const sessionPath = join15(brainDir, rawId);
11896
+ const sessionPath = join16(brainDir, rawId);
11892
11897
  try {
11893
- if (!statSync12(sessionPath).isDirectory())
11898
+ if (!statSync13(sessionPath).isDirectory())
11894
11899
  continue;
11895
11900
  } catch {
11896
11901
  continue;
11897
11902
  }
11898
- const filePath = agyTranscriptPath(join15(sessionPath, ".system_generated", "logs"));
11903
+ const filePath = agyTranscriptPath(join16(sessionPath, ".system_generated", "logs"));
11899
11904
  if (!filePath)
11900
11905
  continue;
11901
11906
  let stat3;
11902
11907
  try {
11903
- stat3 = statSync12(filePath);
11908
+ stat3 = statSync13(filePath);
11904
11909
  } catch {
11905
11910
  continue;
11906
11911
  }
11907
11912
  if (stat3.mtimeMs < cutoff)
11908
11913
  continue;
11909
- const projectPath = resolveAgyProject(dirname12(filePath), this.homeDir());
11914
+ const projectPath = resolveAgyProject(dirname13(filePath), this.homeDir());
11910
11915
  if (filter && (!projectPath || !projectPath.toLowerCase().includes(filter)))
11911
11916
  continue;
11912
11917
  const projectDir = projectPath ? basename12(projectPath) : "";
@@ -12158,23 +12163,23 @@ var init_agy = __esm({
12158
12163
  const candidates2 = [];
12159
12164
  let sessionDirs;
12160
12165
  try {
12161
- sessionDirs = readdirSync10(brainDir);
12166
+ sessionDirs = readdirSync11(brainDir);
12162
12167
  } catch {
12163
12168
  return [];
12164
12169
  }
12165
12170
  for (const rawId of sessionDirs) {
12166
- const sessionPath = join15(brainDir, rawId);
12171
+ const sessionPath = join16(brainDir, rawId);
12167
12172
  try {
12168
- if (!statSync12(sessionPath).isDirectory())
12173
+ if (!statSync13(sessionPath).isDirectory())
12169
12174
  continue;
12170
12175
  } catch {
12171
12176
  continue;
12172
12177
  }
12173
- const filePath = agyTranscriptPath(join15(sessionPath, ".system_generated", "logs"));
12178
+ const filePath = agyTranscriptPath(join16(sessionPath, ".system_generated", "logs"));
12174
12179
  if (!filePath)
12175
12180
  continue;
12176
12181
  try {
12177
- const st = statSync12(filePath);
12182
+ const st = statSync13(filePath);
12178
12183
  if (st.mtimeMs < opts.sinceMs)
12179
12184
  continue;
12180
12185
  candidates2.push({ rawId, mtime: st.mtimeMs });
@@ -12202,7 +12207,7 @@ var init_agy = __esm({
12202
12207
  try {
12203
12208
  return {
12204
12209
  tool: "agy",
12205
- mtime: statSync12(loc.path).mtimeMs,
12210
+ mtime: statSync13(loc.path).mtimeMs,
12206
12211
  files: [{ name: basename12(loc.path), bytes: readFileSync9(loc.path) }]
12207
12212
  };
12208
12213
  } catch {
@@ -12217,7 +12222,7 @@ var init_agy = __esm({
12217
12222
  if (!loc)
12218
12223
  return 0;
12219
12224
  try {
12220
- return statSync12(loc.path).size;
12225
+ return statSync13(loc.path).size;
12221
12226
  } catch {
12222
12227
  return 0;
12223
12228
  }
@@ -12234,8 +12239,8 @@ var init_agy = __esm({
12234
12239
  });
12235
12240
 
12236
12241
  // ../engine/dist/core/backends/cursor-store.js
12237
- import { existsSync as existsSync15, readdirSync as readdirSync11, readFileSync as readFileSync10, statSync as statSync13 } from "fs";
12238
- import { join as join16 } from "path";
12242
+ import { existsSync as existsSync15, readdirSync as readdirSync12, readFileSync as readFileSync10, statSync as statSync14 } from "fs";
12243
+ import { join as join17 } from "path";
12239
12244
  function cursorProjectSlug(absPath) {
12240
12245
  return absPath.replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
12241
12246
  }
@@ -12243,28 +12248,28 @@ function listChatsIn(chatsRoot) {
12243
12248
  const out = [];
12244
12249
  let hashDirs;
12245
12250
  try {
12246
- hashDirs = readdirSync11(chatsRoot);
12251
+ hashDirs = readdirSync12(chatsRoot);
12247
12252
  } catch {
12248
12253
  return out;
12249
12254
  }
12250
12255
  for (const workspaceHash of hashDirs) {
12251
- const hashPath2 = join16(chatsRoot, workspaceHash);
12256
+ const hashPath2 = join17(chatsRoot, workspaceHash);
12252
12257
  let chatIds;
12253
12258
  try {
12254
- if (!statSync13(hashPath2).isDirectory())
12259
+ if (!statSync14(hashPath2).isDirectory())
12255
12260
  continue;
12256
- chatIds = readdirSync11(hashPath2);
12261
+ chatIds = readdirSync12(hashPath2);
12257
12262
  } catch {
12258
12263
  continue;
12259
12264
  }
12260
12265
  for (const chatId of chatIds) {
12261
- const dir = join16(hashPath2, chatId);
12262
- const dbPath = join16(dir, "store.db");
12266
+ const dir = join17(hashPath2, chatId);
12267
+ const dbPath = join17(dir, "store.db");
12263
12268
  if (!existsSync15(dbPath))
12264
12269
  continue;
12265
12270
  let meta = {};
12266
12271
  try {
12267
- meta = JSON.parse(readFileSync10(join16(dir, "meta.json"), "utf-8"));
12272
+ meta = JSON.parse(readFileSync10(join17(dir, "meta.json"), "utf-8"));
12268
12273
  } catch {
12269
12274
  }
12270
12275
  if (meta.hasConversation === false)
@@ -12273,7 +12278,7 @@ function listChatsIn(chatsRoot) {
12273
12278
  let created = meta.createdAtMs ?? 0;
12274
12279
  if (!mtime || !created) {
12275
12280
  try {
12276
- const st = statSync13(dbPath);
12281
+ const st = statSync14(dbPath);
12277
12282
  mtime = mtime || st.mtimeMs;
12278
12283
  created = created || st.birthtimeMs || st.mtimeMs;
12279
12284
  } catch {
@@ -12298,25 +12303,25 @@ function findChat(chatsRoots, chatId) {
12298
12303
  for (const root of chatsRoots) {
12299
12304
  let hashDirs;
12300
12305
  try {
12301
- hashDirs = readdirSync11(root);
12306
+ hashDirs = readdirSync12(root);
12302
12307
  } catch {
12303
12308
  continue;
12304
12309
  }
12305
12310
  for (const workspaceHash of hashDirs) {
12306
- const dir = join16(root, workspaceHash, chatId);
12307
- const dbPath = join16(dir, "store.db");
12311
+ const dir = join17(root, workspaceHash, chatId);
12312
+ const dbPath = join17(dir, "store.db");
12308
12313
  if (!existsSync15(dbPath))
12309
12314
  continue;
12310
12315
  let meta = {};
12311
12316
  try {
12312
- meta = JSON.parse(readFileSync10(join16(dir, "meta.json"), "utf-8"));
12317
+ meta = JSON.parse(readFileSync10(join17(dir, "meta.json"), "utf-8"));
12313
12318
  } catch {
12314
12319
  }
12315
12320
  let mtime = meta.updatedAtMs ?? 0;
12316
12321
  let created = meta.createdAtMs ?? 0;
12317
12322
  if (!mtime || !created) {
12318
12323
  try {
12319
- const st = statSync13(dbPath);
12324
+ const st = statSync14(dbPath);
12320
12325
  mtime = mtime || st.mtimeMs;
12321
12326
  created = created || st.birthtimeMs || st.mtimeMs;
12322
12327
  } catch {
@@ -12557,7 +12562,7 @@ function readStoreEvents(chat) {
12557
12562
  function transcriptPath(cursorHome, projectPath, chatId) {
12558
12563
  if (!projectPath)
12559
12564
  return null;
12560
- const p = join16(cursorHome, "projects", cursorProjectSlug(projectPath), "agent-transcripts", chatId, `${chatId}.jsonl`);
12565
+ const p = join17(cursorHome, "projects", cursorProjectSlug(projectPath), "agent-transcripts", chatId, `${chatId}.jsonl`);
12561
12566
  return existsSync15(p) ? p : null;
12562
12567
  }
12563
12568
  function readTranscriptEvents(rawText, mtimeFallback = 0) {
@@ -12619,8 +12624,8 @@ var init_cursor_store = __esm({
12619
12624
  });
12620
12625
 
12621
12626
  // ../engine/dist/core/backends/cursor-ide.js
12622
- import { existsSync as existsSync16, readFileSync as readFileSync11, readdirSync as readdirSync12, statSync as statSync14 } from "fs";
12623
- import { dirname as dirname13, join as join17 } from "path";
12627
+ import { existsSync as existsSync16, readFileSync as readFileSync11, readdirSync as readdirSync13, statSync as statSync15 } from "fs";
12628
+ import { dirname as dirname14, join as join18 } from "path";
12624
12629
  function jsonOf(value) {
12625
12630
  if (value == null)
12626
12631
  return null;
@@ -12664,7 +12669,7 @@ function pathFromUri(uri) {
12664
12669
  return uri.startsWith("/") ? uri : "";
12665
12670
  }
12666
12671
  function projectPathForWorkspace(workspaceDir) {
12667
- const meta = jsonOf(safeRead(join17(workspaceDir, "workspace.json")));
12672
+ const meta = jsonOf(safeRead(join18(workspaceDir, "workspace.json")));
12668
12673
  if (!meta)
12669
12674
  return "";
12670
12675
  const uri = typeof meta.workspace === "string" && meta.workspace || typeof meta.folder === "string" && meta.folder || "";
@@ -12682,14 +12687,14 @@ function workspaceIndex(workspaceRoots) {
12682
12687
  for (const root of workspaceRoots) {
12683
12688
  let entries;
12684
12689
  try {
12685
- entries = readdirSync12(root);
12690
+ entries = readdirSync13(root);
12686
12691
  } catch {
12687
12692
  continue;
12688
12693
  }
12689
12694
  for (const id of entries) {
12690
- const dir = join17(root, id);
12695
+ const dir = join18(root, id);
12691
12696
  try {
12692
- if (!statSync14(dir).isDirectory())
12697
+ if (!statSync15(dir).isDirectory())
12693
12698
  continue;
12694
12699
  } catch {
12695
12700
  continue;
@@ -12769,12 +12774,12 @@ function listComposers(globalDbPath, workspaceRoots) {
12769
12774
  for (const root of workspaceRoots) {
12770
12775
  let entries;
12771
12776
  try {
12772
- entries = readdirSync12(root);
12777
+ entries = readdirSync13(root);
12773
12778
  } catch {
12774
12779
  continue;
12775
12780
  }
12776
12781
  for (const workspaceId of entries) {
12777
- const wsDb = join17(root, workspaceId, "state.vscdb");
12782
+ const wsDb = join18(root, workspaceId, "state.vscdb");
12778
12783
  if (!existsSync16(wsDb))
12779
12784
  continue;
12780
12785
  const projectPath = wsIndex.get(workspaceId) || "";
@@ -13035,8 +13040,8 @@ var init_cursor_ide = __esm({
13035
13040
  });
13036
13041
 
13037
13042
  // ../engine/dist/core/backends/cursor.js
13038
- import { existsSync as existsSync17, readFileSync as readFileSync12, statSync as statSync15 } from "fs";
13039
- import { join as join18 } from "path";
13043
+ import { existsSync as existsSync17, readFileSync as readFileSync12, statSync as statSync16 } from "fs";
13044
+ import { join as join19 } from "path";
13040
13045
  var PREFIX5, CursorBackend, cursorBackend;
13041
13046
  var init_cursor = __esm({
13042
13047
  "../engine/dist/core/backends/cursor.js"() {
@@ -13088,7 +13093,7 @@ var init_cursor = __esm({
13088
13093
  if (r.surface === "cli") {
13089
13094
  let mtime2 = r.chat.updatedAtMs;
13090
13095
  try {
13091
- mtime2 = statSync15(r.chat.dbPath).mtimeMs || mtime2;
13096
+ mtime2 = statSync16(r.chat.dbPath).mtimeMs || mtime2;
13092
13097
  } catch {
13093
13098
  }
13094
13099
  return {
@@ -13101,7 +13106,7 @@ var init_cursor = __esm({
13101
13106
  }
13102
13107
  let mtime = r.composer.updatedAtMs;
13103
13108
  try {
13104
- mtime = statSync15(r.composer.globalDbPath).mtimeMs || mtime;
13109
+ mtime = statSync16(r.composer.globalDbPath).mtimeMs || mtime;
13105
13110
  } catch {
13106
13111
  }
13107
13112
  return {
@@ -13343,11 +13348,11 @@ var init_cursor = __esm({
13343
13348
  if (!lines)
13344
13349
  return null;
13345
13350
  const files = [{ name: `${r.chat.chatId}.jsonl`, bytes: Buffer.from(lines, "utf8") }];
13346
- const metaPath = join18(r.chat.dir, "meta.json");
13351
+ const metaPath = join19(r.chat.dir, "meta.json");
13347
13352
  if (existsSync17(metaPath)) {
13348
13353
  files.push({ name: "meta.json", bytes: readFileSync12(metaPath) });
13349
13354
  }
13350
- return { tool: "cursor", mtime: statSync15(r.chat.dbPath).mtimeMs, files };
13355
+ return { tool: "cursor", mtime: statSync16(r.chat.dbPath).mtimeMs, files };
13351
13356
  }
13352
13357
  const events = readComposerEvents(r.composer);
13353
13358
  if (events.length === 0)
@@ -13355,7 +13360,7 @@ var init_cursor = __esm({
13355
13360
  const body = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
13356
13361
  return {
13357
13362
  tool: "cursor",
13358
- mtime: statSync15(r.composer.globalDbPath).mtimeMs,
13363
+ mtime: statSync16(r.composer.globalDbPath).mtimeMs,
13359
13364
  files: [{ name: `${r.composer.composerId}.jsonl`, bytes: Buffer.from(body, "utf8") }]
13360
13365
  };
13361
13366
  } catch {
@@ -13420,11 +13425,11 @@ var init_credentials_env = __esm({
13420
13425
  });
13421
13426
 
13422
13427
  // ../engine/dist/core/which.js
13423
- import { existsSync as existsSync19, statSync as statSync16, accessSync, constants } from "node:fs";
13424
- import { join as join20, isAbsolute as isAbsolute2, delimiter as delimiter2, sep as sep2 } from "node:path";
13428
+ import { existsSync as existsSync19, statSync as statSync17, accessSync as accessSync2, constants as constants2 } from "node:fs";
13429
+ import { join as join21, isAbsolute as isAbsolute2, delimiter as delimiter2, sep as sep2 } from "node:path";
13425
13430
  function executable(p) {
13426
13431
  try {
13427
- if (!statSync16(p).isFile())
13432
+ if (!statSync17(p).isFile())
13428
13433
  return false;
13429
13434
  } catch {
13430
13435
  return false;
@@ -13432,7 +13437,7 @@ function executable(p) {
13432
13437
  if (isWindows)
13433
13438
  return true;
13434
13439
  try {
13435
- accessSync(p, constants.X_OK);
13440
+ accessSync2(p, constants2.X_OK);
13436
13441
  return true;
13437
13442
  } catch {
13438
13443
  return false;
@@ -13460,7 +13465,7 @@ function resolveOnPath(name) {
13460
13465
  if (!dir)
13461
13466
  continue;
13462
13467
  for (const c of candidates(name)) {
13463
- const full = join20(dir, c);
13468
+ const full = join21(dir, c);
13464
13469
  if (existsSync19(full) && executable(full))
13465
13470
  return full;
13466
13471
  }
@@ -13479,8 +13484,8 @@ var init_which = __esm({
13479
13484
  });
13480
13485
 
13481
13486
  // ../engine/dist/core/collector-health.js
13482
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5 } from "node:fs";
13483
- import { join as join21, dirname as dirname14 } from "node:path";
13487
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync3, mkdirSync as mkdirSync6 } from "node:fs";
13488
+ import { join as join22, dirname as dirname15 } from "node:path";
13484
13489
  function progressLine(h) {
13485
13490
  const p = h?.progress;
13486
13491
  if (!p || p.complete || p.total <= 0)
@@ -13499,7 +13504,7 @@ function readCollectorHealth() {
13499
13504
  function writeCollectorHealth(h) {
13500
13505
  try {
13501
13506
  const p = healthPath();
13502
- mkdirSync5(dirname14(p), { recursive: true });
13507
+ mkdirSync6(dirname15(p), { recursive: true });
13503
13508
  writeFileSync3(p, JSON.stringify(h));
13504
13509
  } catch {
13505
13510
  }
@@ -13562,7 +13567,7 @@ var init_collector_health = __esm({
13562
13567
  "../engine/dist/core/collector-health.js"() {
13563
13568
  "use strict";
13564
13569
  init_paths();
13565
- healthPath = () => join21(getDataDir(), "collector-health.json");
13570
+ healthPath = () => join22(getDataDir(), "collector-health.json");
13566
13571
  PROGRESS_WRITE_INTERVAL_MS = 2e3;
13567
13572
  lastProgressWrite = 0;
13568
13573
  STALE_AFTER_MS = 30 * 6e4;
@@ -13578,9 +13583,9 @@ var init_collector_health = __esm({
13578
13583
  });
13579
13584
 
13580
13585
  // ../engine/dist/types/code-intel.js
13581
- import { createHash as createHash6 } from "crypto";
13586
+ import { createHash as createHash7 } from "crypto";
13582
13587
  function shortHash(s) {
13583
- return createHash6("sha256").update(s).digest("hex").slice(0, 16);
13588
+ return createHash7("sha256").update(s).digest("hex").slice(0, 16);
13584
13589
  }
13585
13590
  function snippetKey(snippet) {
13586
13591
  return (snippet ?? "").replace(/\s+/g, " ").trim().slice(0, 200);
@@ -13621,11 +13626,11 @@ var init_code_intel = __esm({
13621
13626
  });
13622
13627
 
13623
13628
  // ../engine/dist/core/companions.js
13624
- import { existsSync as existsSync20, mkdirSync as mkdirSync6, statSync as statSync17, chmodSync as chmodSync3, unlinkSync, renameSync as renameSync3, createWriteStream, readFileSync as readFileSync14, writeFileSync as writeFileSync4 } from "node:fs";
13629
+ import { existsSync as existsSync20, mkdirSync as mkdirSync7, statSync as statSync18, chmodSync as chmodSync4, unlinkSync, renameSync as renameSync3, createWriteStream, readFileSync as readFileSync14, writeFileSync as writeFileSync4 } from "node:fs";
13625
13630
  import { homedir as homedir5 } from "node:os";
13626
- import { join as join22 } from "node:path";
13631
+ import { join as join23 } from "node:path";
13627
13632
  import { execSync as execSync2 } from "node:child_process";
13628
- import { createHash as createHash7 } from "node:crypto";
13633
+ import { createHash as createHash8 } from "node:crypto";
13629
13634
  function expectedCodeindexSha256(artifact) {
13630
13635
  return CODEINDEX_SHA256[artifact.replace(/^codeindex-/, "").replace(/\.exe$/, "")] ?? null;
13631
13636
  }
@@ -13672,7 +13677,7 @@ function checkCodeindexStatus() {
13672
13677
  status.installed = true;
13673
13678
  status.path = foundPath;
13674
13679
  try {
13675
- status.size = statSync17(foundPath).size;
13680
+ status.size = statSync18(foundPath).size;
13676
13681
  } catch {
13677
13682
  }
13678
13683
  try {
@@ -13725,7 +13730,7 @@ async function installCodeindex(opts = {}) {
13725
13730
  return status;
13726
13731
  if (!status.prebuiltAvailable)
13727
13732
  return status;
13728
- mkdirSync6(CODEINDEX_INSTALL_DIR, { recursive: true });
13733
+ mkdirSync7(CODEINDEX_INSTALL_DIR, { recursive: true });
13729
13734
  const tmpPath = `${CODEINDEX_BIN_PATH}.partial`;
13730
13735
  try {
13731
13736
  await downloadArtifact(status.artifactName, tmpPath);
@@ -13733,14 +13738,14 @@ async function installCodeindex(opts = {}) {
13733
13738
  if (!expected) {
13734
13739
  throw new Error(`No pinned checksum for ${status.artifactName} \u2014 refusing to install an unverified binary. Add its sha256 to CODEINDEX_SHA256 in companions.ts.`);
13735
13740
  }
13736
- const actual = createHash7("sha256").update(readFileSync14(tmpPath)).digest("hex");
13741
+ const actual = createHash8("sha256").update(readFileSync14(tmpPath)).digest("hex");
13737
13742
  if (actual !== expected) {
13738
13743
  throw new Error(`Checksum mismatch for ${status.artifactName}.
13739
13744
  expected ${expected}
13740
13745
  actual ${actual}
13741
13746
  Refusing to install. The release may have been re-uploaded, or something is serving different bytes.`);
13742
13747
  }
13743
- chmodSync3(tmpPath, 493);
13748
+ chmodSync4(tmpPath, 493);
13744
13749
  renameSync3(tmpPath, CODEINDEX_BIN_PATH);
13745
13750
  } catch (err) {
13746
13751
  try {
@@ -13767,24 +13772,24 @@ var init_companions = __esm({
13767
13772
  "x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
13768
13773
  "aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
13769
13774
  };
13770
- CODEINDEX_INSTALL_DIR = join22(homedir5(), ".local", "bin");
13775
+ CODEINDEX_INSTALL_DIR = join23(homedir5(), ".local", "bin");
13771
13776
  CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
13772
- CODEINDEX_BIN_PATH = join22(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
13777
+ CODEINDEX_BIN_PATH = join23(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
13773
13778
  }
13774
13779
  });
13775
13780
 
13776
13781
  // ../engine/dist/core/detector-install.js
13777
- import { createHash as createHash8 } from "crypto";
13778
- import { existsSync as existsSync21, mkdirSync as mkdirSync7, mkdtempSync, chmodSync as chmodSync4, renameSync as renameSync4, rmSync as rmSync2, writeFileSync as writeFileSync5, readFileSync as readFileSync15, statSync as statSync18, copyFileSync as copyFileSync2 } from "fs";
13779
- import { join as join23 } from "path";
13782
+ import { createHash as createHash9 } from "crypto";
13783
+ import { existsSync as existsSync21, mkdirSync as mkdirSync8, mkdtempSync, chmodSync as chmodSync5, renameSync as renameSync4, rmSync as rmSync2, writeFileSync as writeFileSync5, readFileSync as readFileSync15, statSync as statSync19, copyFileSync as copyFileSync2 } from "fs";
13784
+ import { join as join24 } from "path";
13780
13785
  function managedDetectorPath(name) {
13781
- return join23(getDetectorBinDir(), name + exeSuffix());
13786
+ return join24(getDetectorBinDir(), name + exeSuffix());
13782
13787
  }
13783
13788
  function receiptPath(name) {
13784
- return join23(getDetectorBinDir(), `${name}.receipt.json`);
13789
+ return join24(getDetectorBinDir(), `${name}.receipt.json`);
13785
13790
  }
13786
13791
  function sha256File(path) {
13787
- return createHash8("sha256").update(readFileSync15(path)).digest("hex");
13792
+ return createHash9("sha256").update(readFileSync15(path)).digest("hex");
13788
13793
  }
13789
13794
  function readReceipt(name) {
13790
13795
  try {
@@ -13796,7 +13801,7 @@ function readReceipt(name) {
13796
13801
  function verifiedSha(path) {
13797
13802
  let st;
13798
13803
  try {
13799
- st = statSync18(path);
13804
+ st = statSync19(path);
13800
13805
  } catch {
13801
13806
  return null;
13802
13807
  }
@@ -13814,7 +13819,7 @@ function configuredDir() {
13814
13819
  function resolveDetector(name) {
13815
13820
  const dir = configuredDir();
13816
13821
  if (dir) {
13817
- const p2 = join23(dir, name + exeSuffix());
13822
+ const p2 = join24(dir, name + exeSuffix());
13818
13823
  if (existsSync21(p2))
13819
13824
  return { path: p2, version: "operator-supplied", source: "configured" };
13820
13825
  return { error: "not-installed" };
@@ -13880,8 +13885,8 @@ var init_detector_install = __esm({
13880
13885
  // ../engine/dist/core/secret-scanner.js
13881
13886
  import { spawnSync } from "child_process";
13882
13887
  import { existsSync as existsSync22, unlinkSync as unlinkSync2, readFileSync as readFileSync16, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "fs";
13883
- import { tmpdir } from "os";
13884
- import { join as join24 } from "path";
13888
+ import { tmpdir as tmpdir2 } from "os";
13889
+ import { join as join25 } from "path";
13885
13890
  function mask(s) {
13886
13891
  if (!s)
13887
13892
  return "";
@@ -13909,7 +13914,7 @@ function whichDetector(bin) {
13909
13914
  return null;
13910
13915
  }
13911
13916
  function spawnScoped(binary, args, opts) {
13912
- const scratch = mkdtempSync2(join24(tmpdir(), "cr-scan-tmp-"));
13917
+ const scratch = mkdtempSync2(join25(tmpdir2(), "cr-scan-tmp-"));
13913
13918
  try {
13914
13919
  return spawnSync(binary, args, {
13915
13920
  ...opts,
@@ -14227,7 +14232,7 @@ __export(collector_exports, {
14227
14232
  import { spawn } from "node:child_process";
14228
14233
  import { execSync as execSync3 } from "node:child_process";
14229
14234
  import { readFileSync as readFileSync17 } from "node:fs";
14230
- import { join as join25, basename as basename13 } from "node:path";
14235
+ import { join as join26, basename as basename13 } from "node:path";
14231
14236
  async function resolveCodeindexBin(autoInstall = true) {
14232
14237
  let st = checkCodeindexStatus();
14233
14238
  if (!st.installed && autoInstall)
@@ -14406,7 +14411,7 @@ async function collectCode(opts) {
14406
14411
  }
14407
14412
  const complexity = (r) => {
14408
14413
  try {
14409
- const txt = readFileSync17(join25(ws, r), "utf8");
14414
+ const txt = readFileSync17(join26(ws, r), "utf8");
14410
14415
  if (txt.length > 2e6)
14411
14416
  return 1;
14412
14417
  const m = txt.match(CF_RE);
@@ -15157,11 +15162,11 @@ var init_collector = __esm({
15157
15162
  });
15158
15163
 
15159
15164
  // ../engine/dist/core/source-discovery.js
15160
- import { createHash as createHash9 } from "crypto";
15161
- import { existsSync as existsSync24, readdirSync as readdirSync13, statSync as statSync20 } from "fs";
15162
- import { join as join27 } from "path";
15165
+ import { createHash as createHash10 } from "crypto";
15166
+ import { existsSync as existsSync24, readdirSync as readdirSync14, statSync as statSync21 } from "fs";
15167
+ import { join as join28 } from "path";
15163
15168
  function sourceId(path) {
15164
- return "src_" + createHash9("sha256").update(path).digest("hex").slice(0, 12);
15169
+ return "src_" + createHash10("sha256").update(path).digest("hex").slice(0, 12);
15165
15170
  }
15166
15171
  function installSourceExclusions(ids) {
15167
15172
  excludedIds = new Set((ids || []).filter((s) => typeof s === "string" && SOURCE_ID_RE.test(s)));
@@ -15195,12 +15200,12 @@ function countTranscripts(root, tool) {
15195
15200
  return;
15196
15201
  let entries;
15197
15202
  try {
15198
- entries = readdirSync13(dir, { withFileTypes: true });
15203
+ entries = readdirSync14(dir, { withFileTypes: true });
15199
15204
  } catch {
15200
15205
  return;
15201
15206
  }
15202
15207
  for (const e of entries) {
15203
- const full = join27(dir, e.name);
15208
+ const full = join28(dir, e.name);
15204
15209
  if (e.isDirectory()) {
15205
15210
  walk(full, depth + 1);
15206
15211
  continue;
@@ -15209,7 +15214,7 @@ function countTranscripts(root, tool) {
15209
15214
  continue;
15210
15215
  sessions++;
15211
15216
  try {
15212
- const m = statSync20(full).mtimeMs;
15217
+ const m = statSync21(full).mtimeMs;
15213
15218
  if (m > newestMtime)
15214
15219
  newestMtime = m;
15215
15220
  } catch {
@@ -15221,7 +15226,7 @@ function countTranscripts(root, tool) {
15221
15226
  }
15222
15227
  function countOpencodeSessions(dbPath) {
15223
15228
  try {
15224
- const st = statSync20(dbPath);
15229
+ const st = statSync21(dbPath);
15225
15230
  return { sessions: 0, newestMtime: st.mtimeMs };
15226
15231
  } catch {
15227
15232
  return { sessions: 0, newestMtime: 0 };
@@ -15265,9 +15270,9 @@ var init_source_discovery = __esm({
15265
15270
 
15266
15271
  // ../engine/dist/core/home-discovery.js
15267
15272
  import { execFileSync as execFileSync2 } from "child_process";
15268
- import { existsSync as existsSync25, readdirSync as readdirSync14, readFileSync as readFileSync19, realpathSync as realpathSync3, statSync as statSync21 } from "fs";
15273
+ import { existsSync as existsSync25, readdirSync as readdirSync15, readFileSync as readFileSync19, realpathSync as realpathSync3, statSync as statSync22 } from "fs";
15269
15274
  import { homedir as homedir7, platform as osPlatform } from "os";
15270
- import { join as join28 } from "path";
15275
+ import { join as join29 } from "path";
15271
15276
  function candidateRoots(plat = osPlatform(), env = process.env) {
15272
15277
  const home = homedir7();
15273
15278
  const roots = [home];
@@ -15280,25 +15285,25 @@ function candidateRoots(plat = osPlatform(), env = process.env) {
15280
15285
  add(env.LOCALAPPDATA);
15281
15286
  add(env.USERPROFILE);
15282
15287
  } else if (plat === "darwin") {
15283
- add(join28(home, "Library", "Application Support"));
15288
+ add(join29(home, "Library", "Application Support"));
15284
15289
  add(env.XDG_CONFIG_HOME);
15285
15290
  } else {
15286
- add(env.XDG_CONFIG_HOME || join28(home, ".config"));
15287
- add(env.XDG_DATA_HOME || join28(home, ".local", "share"));
15291
+ add(env.XDG_CONFIG_HOME || join29(home, ".config"));
15292
+ add(env.XDG_DATA_HOME || join29(home, ".local", "share"));
15288
15293
  }
15289
15294
  return roots.filter((r) => existsSync25(r));
15290
15295
  }
15291
15296
  function identifyHome(dir) {
15292
- const has = (...parts) => existsSync25(join28(dir, ...parts));
15293
- if (has("projects") && dirHasTranscript(join28(dir, "projects"), (f) => f.endsWith(".jsonl"), 2))
15297
+ const has = (...parts) => existsSync25(join29(dir, ...parts));
15298
+ if (has("projects") && dirHasTranscript(join29(dir, "projects"), (f) => f.endsWith(".jsonl"), 2))
15294
15299
  return "claude";
15295
- if (has("sessions") && dirHasTranscript(join28(dir, "sessions"), (f) => f.startsWith("rollout-") && f.endsWith(".jsonl"), 4))
15300
+ if (has("sessions") && dirHasTranscript(join29(dir, "sessions"), (f) => f.startsWith("rollout-") && f.endsWith(".jsonl"), 4))
15296
15301
  return "codex";
15297
- if (has("tmp") && dirHasTranscript(join28(dir, "tmp"), (f) => f.startsWith("session-"), 3))
15302
+ if (has("tmp") && dirHasTranscript(join29(dir, "tmp"), (f) => f.startsWith("session-"), 3))
15298
15303
  return "gemini";
15299
- if (has("brain") && dirHasTranscript(join28(dir, "brain"), (f) => f.endsWith(".jsonl"), 4))
15304
+ if (has("brain") && dirHasTranscript(join29(dir, "brain"), (f) => f.endsWith(".jsonl"), 4))
15300
15305
  return "agy";
15301
- if (has("chats") && dirHasTranscript(join28(dir, "chats"), (f) => f === "store.db", 3))
15306
+ if (has("chats") && dirHasTranscript(join29(dir, "chats"), (f) => f === "store.db", 3))
15302
15307
  return "cursor";
15303
15308
  if (has("opencode.db"))
15304
15309
  return "opencode";
@@ -15309,7 +15314,7 @@ function dirHasTranscript(root, match, depth) {
15309
15314
  return false;
15310
15315
  let entries;
15311
15316
  try {
15312
- entries = readdirSync14(root, { withFileTypes: true });
15317
+ entries = readdirSync15(root, { withFileTypes: true });
15313
15318
  } catch {
15314
15319
  return false;
15315
15320
  }
@@ -15318,7 +15323,7 @@ function dirHasTranscript(root, match, depth) {
15318
15323
  continue;
15319
15324
  if (e.isFile() && match(e.name))
15320
15325
  return true;
15321
- if (e.isDirectory() && dirHasTranscript(join28(root, e.name), match, depth - 1))
15326
+ if (e.isDirectory() && dirHasTranscript(join29(root, e.name), match, depth - 1))
15322
15327
  return true;
15323
15328
  }
15324
15329
  return false;
@@ -15341,7 +15346,7 @@ function countSessions(dir, tool) {
15341
15346
  return;
15342
15347
  let entries;
15343
15348
  try {
15344
- entries = readdirSync14(d, { withFileTypes: true });
15349
+ entries = readdirSync15(d, { withFileTypes: true });
15345
15350
  } catch {
15346
15351
  return;
15347
15352
  }
@@ -15349,12 +15354,12 @@ function countSessions(dir, tool) {
15349
15354
  if (SKIP.has(e.name))
15350
15355
  continue;
15351
15356
  if (e.isDirectory())
15352
- walk(join28(d, e.name), depth - 1);
15357
+ walk(join29(d, e.name), depth - 1);
15353
15358
  else if (s.match(e.name))
15354
15359
  n++;
15355
15360
  }
15356
15361
  };
15357
- walk(join28(dir, s.sub), s.depth);
15362
+ walk(join29(dir, s.sub), s.depth);
15358
15363
  return n;
15359
15364
  }
15360
15365
  function declaredHomes(env = process.env, plat = osPlatform()) {
@@ -15388,7 +15393,7 @@ function declaredHomes(env = process.env, plat = osPlatform()) {
15388
15393
  return out;
15389
15394
  }
15390
15395
  const home = homedir7();
15391
- const rcs = [".bashrc", ".bash_profile", ".zshrc", ".zprofile", ".profile"].map((f) => join28(home, f)).concat([join28(home, ".config", "fish", "config.fish")]);
15396
+ const rcs = [".bashrc", ".bash_profile", ".zshrc", ".zprofile", ".profile"].map((f) => join29(home, f)).concat([join29(home, ".config", "fish", "config.fish")]);
15392
15397
  for (const rc of rcs) {
15393
15398
  let text;
15394
15399
  try {
@@ -15403,14 +15408,14 @@ function declaredHomes(env = process.env, plat = osPlatform()) {
15403
15408
  add(d);
15404
15409
  }
15405
15410
  }
15406
- return out.map((p) => p.startsWith("~") ? join28(home, p.slice(1)) : p);
15411
+ return out.map((p) => p.startsWith("~") ? join29(home, p.slice(1)) : p);
15407
15412
  }
15408
15413
  function runningToolHomes(plat = osPlatform()) {
15409
15414
  const out = [];
15410
15415
  if (plat === "linux") {
15411
15416
  let pids;
15412
15417
  try {
15413
- pids = readdirSync14("/proc").filter((p) => /^\d+$/.test(p));
15418
+ pids = readdirSync15("/proc").filter((p) => /^\d+$/.test(p));
15414
15419
  } catch {
15415
15420
  return out;
15416
15421
  }
@@ -15460,7 +15465,7 @@ function discoverHomes(opts = {}) {
15460
15465
  return;
15461
15466
  }
15462
15467
  try {
15463
- if (!statSync21(real).isDirectory())
15468
+ if (!statSync22(real).isDirectory())
15464
15469
  return;
15465
15470
  } catch {
15466
15471
  return;
@@ -15490,14 +15495,14 @@ function walkForHomes(dir, depth, visit) {
15490
15495
  return;
15491
15496
  let entries;
15492
15497
  try {
15493
- entries = readdirSync14(dir, { withFileTypes: true });
15498
+ entries = readdirSync15(dir, { withFileTypes: true });
15494
15499
  } catch {
15495
15500
  return;
15496
15501
  }
15497
15502
  for (const e of entries) {
15498
15503
  if (!e.isDirectory() || SKIP.has(e.name))
15499
15504
  continue;
15500
- const child = join28(dir, e.name);
15505
+ const child = join29(dir, e.name);
15501
15506
  visit(child);
15502
15507
  walkForHomes(child, depth - 1, visit);
15503
15508
  }
@@ -15717,7 +15722,7 @@ var init_opencode2 = __esm({
15717
15722
  });
15718
15723
 
15719
15724
  // ../engine/dist/transcript/index.js
15720
- import { statSync as statSync22 } from "fs";
15725
+ import { statSync as statSync23 } from "fs";
15721
15726
  async function parseTranscript(sessionId) {
15722
15727
  const tool = detectTool(sessionId);
15723
15728
  if (tool === "claude") {
@@ -15791,7 +15796,7 @@ async function parseTranscript(sessionId) {
15791
15796
  }
15792
15797
  function safeMtime(path) {
15793
15798
  try {
15794
- return statSync22(path).mtimeMs;
15799
+ return statSync23(path).mtimeMs;
15795
15800
  } catch {
15796
15801
  return 0;
15797
15802
  }
@@ -16288,11 +16293,11 @@ var init_entity_extractor = __esm({
16288
16293
  });
16289
16294
 
16290
16295
  // ../engine/dist/core/source-policy.js
16291
- import { statSync as statSync23 } from "fs";
16296
+ import { statSync as statSync24 } from "fs";
16292
16297
  function settings() {
16293
16298
  let mtimeMs = -1;
16294
16299
  try {
16295
- mtimeMs = statSync23(settingsFilePath()).mtimeMs;
16300
+ mtimeMs = statSync24(settingsFilePath()).mtimeMs;
16296
16301
  } catch {
16297
16302
  }
16298
16303
  if (cache2 && cache2.mtimeMs === mtimeMs)
@@ -16586,9 +16591,9 @@ var init_session_source = __esm({
16586
16591
  });
16587
16592
 
16588
16593
  // ../engine/dist/core/utils.js
16589
- import { existsSync as existsSync26, readdirSync as readdirSync15 } from "fs";
16594
+ import { existsSync as existsSync26, readdirSync as readdirSync16 } from "fs";
16590
16595
  import { homedir as homedir8 } from "os";
16591
- import { join as join29 } from "path";
16596
+ import { join as join30 } from "path";
16592
16597
  function splitByHeaders(markdown) {
16593
16598
  const lines = markdown.split("\n");
16594
16599
  const sections = [];
@@ -16631,17 +16636,17 @@ function getClaudeDirs() {
16631
16636
  for (const d of process.env.CLAUDE_DIRS.split(",")) {
16632
16637
  const trimmed = d.trim();
16633
16638
  if (trimmed) {
16634
- add(trimmed.startsWith("~/") ? join29(home, trimmed.slice(2)) : trimmed);
16639
+ add(trimmed.startsWith("~/") ? join30(home, trimmed.slice(2)) : trimmed);
16635
16640
  }
16636
16641
  }
16637
16642
  }
16638
- add(join29(home, ".claude"));
16643
+ add(join30(home, ".claude"));
16639
16644
  try {
16640
- const entries = readdirSync15(home, { withFileTypes: true });
16645
+ const entries = readdirSync16(home, { withFileTypes: true });
16641
16646
  for (const entry of entries) {
16642
16647
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
16643
- const candidate = join29(home, entry.name);
16644
- if (existsSync26(join29(candidate, "projects"))) {
16648
+ const candidate = join30(home, entry.name);
16649
+ if (existsSync26(join30(candidate, "projects"))) {
16645
16650
  add(candidate);
16646
16651
  }
16647
16652
  }
@@ -16653,12 +16658,12 @@ function getClaudeDirs() {
16653
16658
  function discoverSubdirs(subdir) {
16654
16659
  const result = [];
16655
16660
  for (const claudeDir of getClaudeDirs()) {
16656
- const path = join29(claudeDir, subdir);
16661
+ const path = join30(claudeDir, subdir);
16657
16662
  if (existsSync26(path)) {
16658
16663
  result.push(path);
16659
16664
  }
16660
16665
  }
16661
- return result.length > 0 ? result : [join29(homedir8(), ".claude", subdir)];
16666
+ return result.length > 0 ? result : [join30(homedir8(), ".claude", subdir)];
16662
16667
  }
16663
16668
  var init_utils = __esm({
16664
16669
  "../engine/dist/core/utils.js"() {
@@ -16667,10 +16672,10 @@ var init_utils = __esm({
16667
16672
  });
16668
16673
 
16669
16674
  // ../engine/dist/parsers/plan-source.js
16670
- import { existsSync as existsSync27, readdirSync as readdirSync16, readFileSync as readFileSync20, statSync as statSync24 } from "fs";
16675
+ import { existsSync as existsSync27, readdirSync as readdirSync17, readFileSync as readFileSync20, statSync as statSync25 } from "fs";
16671
16676
  import { homedir as homedir9 } from "os";
16672
- import { join as join30, basename as basename14 } from "path";
16673
- import { createHash as createHash10 } from "crypto";
16677
+ import { join as join31, basename as basename14 } from "path";
16678
+ import { createHash as createHash11 } from "crypto";
16674
16679
  function parseFrontmatter(content) {
16675
16680
  if (!content.startsWith("---"))
16676
16681
  return { body: content };
@@ -16694,7 +16699,7 @@ function parseFrontmatter(content) {
16694
16699
  }
16695
16700
  function safeReaddir(dir) {
16696
16701
  try {
16697
- return readdirSync16(dir);
16702
+ return readdirSync17(dir);
16698
16703
  } catch {
16699
16704
  return [];
16700
16705
  }
@@ -16730,11 +16735,11 @@ var init_plan_source = __esm({
16730
16735
  if (!existsSync27(projectsDir))
16731
16736
  return this._knownProjectDirs;
16732
16737
  try {
16733
- const entries = readdirSync16(projectsDir, { withFileTypes: true });
16738
+ const entries = readdirSync17(projectsDir, { withFileTypes: true });
16734
16739
  for (const entry of entries) {
16735
16740
  if (!entry.isDirectory() || entry.name.startsWith("."))
16736
16741
  continue;
16737
- const projectPath = decodeProjectDirName(entry.name);
16742
+ const projectPath = resolveProjectDirName(entry.name);
16738
16743
  if (existsSync27(projectPath)) {
16739
16744
  this._knownProjectDirs.push(projectPath);
16740
16745
  }
@@ -16762,14 +16767,14 @@ var init_plan_source = __esm({
16762
16767
  for (const plansDir of this.plansDirs) {
16763
16768
  if (!existsSync27(plansDir))
16764
16769
  continue;
16765
- const files = readdirSync16(plansDir).filter((f) => f.endsWith(".md"));
16770
+ const files = readdirSync17(plansDir).filter((f) => f.endsWith(".md"));
16766
16771
  for (const file of files) {
16767
16772
  if (seenClaude.has(file))
16768
16773
  continue;
16769
16774
  seenClaude.add(file);
16770
- const filePath = join30(plansDir, file);
16775
+ const filePath = join31(plansDir, file);
16771
16776
  try {
16772
- const stat3 = statSync24(filePath);
16777
+ const stat3 = statSync25(filePath);
16773
16778
  const planName = basename14(file, ".md");
16774
16779
  const isAgentPlan = planName.includes("-agent-");
16775
16780
  const content = readFileSync20(filePath, "utf-8");
@@ -16806,14 +16811,14 @@ var init_plan_source = __esm({
16806
16811
  return;
16807
16812
  let files;
16808
16813
  try {
16809
- files = readdirSync16(plansDir).filter((f) => f.endsWith(".md"));
16814
+ files = readdirSync17(plansDir).filter((f) => f.endsWith(".md"));
16810
16815
  } catch {
16811
16816
  return;
16812
16817
  }
16813
16818
  for (const file of files) {
16814
- const filePath = join30(plansDir, file);
16819
+ const filePath = join31(plansDir, file);
16815
16820
  try {
16816
- const stat3 = statSync24(filePath);
16821
+ const stat3 = statSync25(filePath);
16817
16822
  const content = readFileSync20(filePath, "utf-8");
16818
16823
  const firstLine = content.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || file;
16819
16824
  const planName = `${opencodeBackend.idPrefix}plan_${basename14(file, ".md")}`;
@@ -16846,40 +16851,40 @@ var init_plan_source = __esm({
16846
16851
  try {
16847
16852
  const data = JSON.parse(readFileSync20(projectsPath, "utf-8"));
16848
16853
  for (const path of Object.keys(data.projects || {})) {
16849
- projMap.set(createHash10("sha256").update(path).digest("hex"), path);
16854
+ projMap.set(createHash11("sha256").update(path).digest("hex"), path);
16850
16855
  }
16851
16856
  } catch {
16852
16857
  }
16853
16858
  }
16854
16859
  let projDirs;
16855
16860
  try {
16856
- projDirs = readdirSync16(tmpRoot);
16861
+ projDirs = readdirSync17(tmpRoot);
16857
16862
  } catch {
16858
16863
  return;
16859
16864
  }
16860
16865
  for (const projDir of projDirs) {
16861
16866
  const projPath = projMap.get(projDir) || "";
16862
- const projRoot = join30(tmpRoot, projDir);
16867
+ const projRoot = join31(tmpRoot, projDir);
16863
16868
  let sessions;
16864
16869
  try {
16865
- sessions = readdirSync16(projRoot);
16870
+ sessions = readdirSync17(projRoot);
16866
16871
  } catch {
16867
16872
  continue;
16868
16873
  }
16869
16874
  for (const sess of sessions) {
16870
- const plansDir = join30(projRoot, sess, "plans");
16875
+ const plansDir = join31(projRoot, sess, "plans");
16871
16876
  if (!existsSync27(plansDir))
16872
16877
  continue;
16873
16878
  let files;
16874
16879
  try {
16875
- files = readdirSync16(plansDir).filter((f) => f.endsWith(".md"));
16880
+ files = readdirSync17(plansDir).filter((f) => f.endsWith(".md"));
16876
16881
  } catch {
16877
16882
  continue;
16878
16883
  }
16879
16884
  for (const file of files) {
16880
- const filePath = join30(plansDir, file);
16885
+ const filePath = join31(plansDir, file);
16881
16886
  try {
16882
- const stat3 = statSync24(filePath);
16887
+ const stat3 = statSync25(filePath);
16883
16888
  const content = readFileSync20(filePath, "utf-8");
16884
16889
  const firstLine = content.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || file;
16885
16890
  const planName = `${geminiBackend.idPrefix}plan_${sess}_${basename14(file, ".md")}`;
@@ -16910,7 +16915,7 @@ var init_plan_source = __esm({
16910
16915
  for (const match of content.matchAll(fullPathPattern)) {
16911
16916
  let path = (match[1] || "").trim();
16912
16917
  if (path.startsWith("~/")) {
16913
- path = join30(homedir9(), path.slice(2));
16918
+ path = join31(homedir9(), path.slice(2));
16914
16919
  }
16915
16920
  for (const projectDir of knownProjects) {
16916
16921
  if (path.startsWith(projectDir)) {
@@ -16995,9 +17000,9 @@ var init_plan_source = __esm({
16995
17000
  const map = /* @__PURE__ */ new Map();
16996
17001
  const root = claudeBackend.projectsDir();
16997
17002
  for (const proj of safeReaddir(root)) {
16998
- const projPath = join30(root, proj);
17003
+ const projPath = join31(root, proj);
16999
17004
  for (const sessionEntry of safeReaddir(projPath)) {
17000
- const subDir = join30(projPath, sessionEntry, "subagents");
17005
+ const subDir = join31(projPath, sessionEntry, "subagents");
17001
17006
  if (!existsSync27(subDir))
17002
17007
  continue;
17003
17008
  for (const f of safeReaddir(subDir)) {
@@ -17076,33 +17081,33 @@ var init_plan_source = __esm({
17076
17081
  return links;
17077
17082
  }
17078
17083
  async *discoverAgyPlans() {
17079
- const brainDir = join30(agyBackend.homeDir(), "brain");
17084
+ const brainDir = join31(agyBackend.homeDir(), "brain");
17080
17085
  if (!existsSync27(brainDir))
17081
17086
  return;
17082
17087
  let sessionDirs;
17083
17088
  try {
17084
- sessionDirs = readdirSync16(brainDir);
17089
+ sessionDirs = readdirSync17(brainDir);
17085
17090
  } catch {
17086
17091
  return;
17087
17092
  }
17088
17093
  for (const rawId of sessionDirs) {
17089
- const sessionPath = join30(brainDir, rawId);
17094
+ const sessionPath = join31(brainDir, rawId);
17090
17095
  try {
17091
- if (!statSync24(sessionPath).isDirectory())
17096
+ if (!statSync25(sessionPath).isDirectory())
17092
17097
  continue;
17093
17098
  } catch {
17094
17099
  continue;
17095
17100
  }
17096
17101
  let files;
17097
17102
  try {
17098
- files = readdirSync16(sessionPath).filter((f) => f.endsWith(".md"));
17103
+ files = readdirSync17(sessionPath).filter((f) => f.endsWith(".md"));
17099
17104
  } catch {
17100
17105
  continue;
17101
17106
  }
17102
17107
  for (const file of files) {
17103
- const filePath = join30(sessionPath, file);
17108
+ const filePath = join31(sessionPath, file);
17104
17109
  try {
17105
- const stat3 = statSync24(filePath);
17110
+ const stat3 = statSync25(filePath);
17106
17111
  const content = readFileSync20(filePath, "utf-8");
17107
17112
  const firstLine = content.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || file;
17108
17113
  const sessionLoc = agyBackend.findSession(rawId);
@@ -17132,8 +17137,8 @@ var init_plan_source = __esm({
17132
17137
  });
17133
17138
 
17134
17139
  // ../engine/dist/parsers/task-source.js
17135
- import { existsSync as existsSync28, readdirSync as readdirSync17, readFileSync as readFileSync21, statSync as statSync25 } from "fs";
17136
- import { join as join31 } from "path";
17140
+ import { existsSync as existsSync28, readdirSync as readdirSync18, readFileSync as readFileSync21, statSync as statSync26 } from "fs";
17141
+ import { join as join32 } from "path";
17137
17142
  var MAX_CHUNK_CHARS2, TaskSource;
17138
17143
  var init_task_source = __esm({
17139
17144
  "../engine/dist/parsers/task-source.js"() {
@@ -17166,15 +17171,15 @@ var init_task_source = __esm({
17166
17171
  return;
17167
17172
  let files;
17168
17173
  try {
17169
- files = readdirSync17(todosDir).filter((f) => f.endsWith(".json"));
17174
+ files = readdirSync18(todosDir).filter((f) => f.endsWith(".json"));
17170
17175
  } catch {
17171
17176
  return;
17172
17177
  }
17173
17178
  for (const file of files) {
17174
- const filePath = join31(todosDir, file);
17179
+ const filePath = join32(todosDir, file);
17175
17180
  let stat3;
17176
17181
  try {
17177
- stat3 = statSync25(filePath);
17182
+ stat3 = statSync26(filePath);
17178
17183
  } catch {
17179
17184
  continue;
17180
17185
  }
@@ -17215,15 +17220,15 @@ var init_task_source = __esm({
17215
17220
  async *discoverInDir(tasksDir) {
17216
17221
  if (!existsSync28(tasksDir))
17217
17222
  return;
17218
- const entries = readdirSync17(tasksDir, { withFileTypes: true });
17223
+ const entries = readdirSync18(tasksDir, { withFileTypes: true });
17219
17224
  for (const entry of entries) {
17220
17225
  if (!entry.isDirectory())
17221
17226
  continue;
17222
17227
  const sessionUuid = entry.name;
17223
- const taskDir = join31(tasksDir, sessionUuid);
17228
+ const taskDir = join32(tasksDir, sessionUuid);
17224
17229
  try {
17225
- const stat3 = statSync25(taskDir);
17226
- const taskFiles = readdirSync17(taskDir).filter((f) => f.endsWith(".json"));
17230
+ const stat3 = statSync26(taskDir);
17231
+ const taskFiles = readdirSync18(taskDir).filter((f) => f.endsWith(".json"));
17227
17232
  if (taskFiles.length === 0)
17228
17233
  continue;
17229
17234
  const tasks = this.readTasks(taskDir, taskFiles);
@@ -17257,7 +17262,7 @@ var init_task_source = __esm({
17257
17262
  const taskDir = item.filePath;
17258
17263
  if (!existsSync28(taskDir))
17259
17264
  return [];
17260
- const taskFiles = readdirSync17(taskDir).filter((f) => f.endsWith(".json"));
17265
+ const taskFiles = readdirSync18(taskDir).filter((f) => f.endsWith(".json"));
17261
17266
  const tasks = this.readTasks(taskDir, taskFiles);
17262
17267
  if (tasks.length === 0)
17263
17268
  return [];
@@ -17295,7 +17300,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
17295
17300
  text,
17296
17301
  chunkType: "task_detail",
17297
17302
  projectPath: item.projectPath,
17298
- filePath: join31(taskDir, `${task.id}.json`),
17303
+ filePath: join32(taskDir, `${task.id}.json`),
17299
17304
  mtime: item.mtime
17300
17305
  });
17301
17306
  }
@@ -17352,7 +17357,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
17352
17357
  });
17353
17358
  for (const file of sorted) {
17354
17359
  try {
17355
- const content = readFileSync21(join31(taskDir, file), "utf-8");
17360
+ const content = readFileSync21(join32(taskDir, file), "utf-8");
17356
17361
  const task = JSON.parse(content);
17357
17362
  if (task.subject) {
17358
17363
  tasks.push(task);
@@ -17368,10 +17373,10 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
17368
17373
  });
17369
17374
 
17370
17375
  // ../engine/dist/parsers/claude-md-source.js
17371
- import { existsSync as existsSync29, readFileSync as readFileSync22, readdirSync as readdirSync18, statSync as statSync26 } from "fs";
17376
+ import { existsSync as existsSync29, readFileSync as readFileSync22, readdirSync as readdirSync19, statSync as statSync27 } from "fs";
17372
17377
  import { homedir as homedir10 } from "os";
17373
- import { join as join32, basename as basename15, dirname as dirname15 } from "path";
17374
- import { createHash as createHash11 } from "crypto";
17378
+ import { join as join33, basename as basename15, dirname as dirname16 } from "path";
17379
+ import { createHash as createHash12 } from "crypto";
17375
17380
  function discoverProjectDirs(claudeDir) {
17376
17381
  const dirs = [];
17377
17382
  const seen = /* @__PURE__ */ new Set();
@@ -17385,26 +17390,26 @@ function discoverProjectDirs(claudeDir) {
17385
17390
  if (!existsSync29(projectsDir))
17386
17391
  return;
17387
17392
  try {
17388
- const entries = readdirSync18(projectsDir, { withFileTypes: true });
17393
+ const entries = readdirSync19(projectsDir, { withFileTypes: true });
17389
17394
  for (const entry of entries) {
17390
17395
  if (!entry.isDirectory() || entry.name.startsWith("."))
17391
17396
  continue;
17392
- const projectPath = decodeProjectDirName(entry.name);
17397
+ const projectPath = resolveProjectDirName(entry.name);
17393
17398
  addProject(projectPath);
17394
17399
  }
17395
17400
  } catch {
17396
17401
  }
17397
17402
  };
17398
17403
  if (claudeDir) {
17399
- scanProjectsDir(join32(claudeDir, "projects"));
17404
+ scanProjectsDir(join33(claudeDir, "projects"));
17400
17405
  return dirs;
17401
17406
  }
17402
17407
  const home = homedir10();
17403
17408
  scanProjectsDir(claudeBackend.projectsDir());
17404
17409
  try {
17405
- for (const entry of readdirSync18(home, { withFileTypes: true })) {
17410
+ for (const entry of readdirSync19(home, { withFileTypes: true })) {
17406
17411
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
17407
- scanProjectsDir(join32(home, entry.name, "projects"));
17412
+ scanProjectsDir(join33(home, entry.name, "projects"));
17408
17413
  }
17409
17414
  }
17410
17415
  } catch {
@@ -17433,7 +17438,7 @@ function discoverProjectDirs(claudeDir) {
17433
17438
  } catch {
17434
17439
  }
17435
17440
  }
17436
- void createHash11;
17441
+ void createHash12;
17437
17442
  return dirs;
17438
17443
  }
17439
17444
  var MAX_CHUNK_CHARS3, NOTE_FILES, ClaudeMdSource;
@@ -17468,7 +17473,7 @@ var init_claude_md_source = __esm({
17468
17473
  const seen = /* @__PURE__ */ new Set();
17469
17474
  const seenKey = (path, tool) => `${tool}:${path}`;
17470
17475
  for (const note of NOTE_FILES) {
17471
- const p = join32(homedir10(), note.filename);
17476
+ const p = join33(homedir10(), note.filename);
17472
17477
  const key2 = seenKey(p, note.tool);
17473
17478
  if (existsSync29(p) && !seen.has(key2)) {
17474
17479
  seen.add(key2);
@@ -17480,7 +17485,7 @@ var init_claude_md_source = __esm({
17480
17485
  const projectDirs = discoverProjectDirs(this.claudeDir);
17481
17486
  for (const projectDir of projectDirs) {
17482
17487
  for (const note of NOTE_FILES) {
17483
- const p = join32(projectDir, note.filename);
17488
+ const p = join33(projectDir, note.filename);
17484
17489
  const key2 = seenKey(p, note.tool);
17485
17490
  if (existsSync29(p) && !seen.has(key2)) {
17486
17491
  seen.add(key2);
@@ -17494,7 +17499,7 @@ var init_claude_md_source = __esm({
17494
17499
  if (!existsSync29(searchDir))
17495
17500
  continue;
17496
17501
  for (const note of NOTE_FILES) {
17497
- const directPath = join32(searchDir, note.filename);
17502
+ const directPath = join33(searchDir, note.filename);
17498
17503
  const key2 = seenKey(directPath, note.tool);
17499
17504
  if (existsSync29(directPath) && !seen.has(key2)) {
17500
17505
  seen.add(key2);
@@ -17504,12 +17509,12 @@ var init_claude_md_source = __esm({
17504
17509
  }
17505
17510
  }
17506
17511
  try {
17507
- const entries = readdirSync18(searchDir, { withFileTypes: true });
17512
+ const entries = readdirSync19(searchDir, { withFileTypes: true });
17508
17513
  for (const entry of entries) {
17509
17514
  if (!entry.isDirectory())
17510
17515
  continue;
17511
17516
  for (const note of NOTE_FILES) {
17512
- const p = join32(searchDir, entry.name, note.filename);
17517
+ const p = join33(searchDir, entry.name, note.filename);
17513
17518
  const key2 = seenKey(p, note.tool);
17514
17519
  if (existsSync29(p) && !seen.has(key2)) {
17515
17520
  seen.add(key2);
@@ -17565,8 +17570,8 @@ var init_claude_md_source = __esm({
17565
17570
  }
17566
17571
  fileToItem(filePath, filename, tool) {
17567
17572
  try {
17568
- const stat3 = statSync26(filePath);
17569
- const projectDir = dirname15(filePath);
17573
+ const stat3 = statSync27(filePath);
17574
+ const projectDir = dirname16(filePath);
17570
17575
  const projectName = basename15(projectDir);
17571
17576
  const projectPath = projectDir;
17572
17577
  const content = readFileSync22(filePath, "utf-8");
@@ -17594,9 +17599,9 @@ var init_claude_md_source = __esm({
17594
17599
  });
17595
17600
 
17596
17601
  // ../engine/dist/parsers/agent-memory-source.js
17597
- import { existsSync as existsSync30, readFileSync as readFileSync23, readdirSync as readdirSync19, statSync as statSync27 } from "fs";
17602
+ import { existsSync as existsSync30, readFileSync as readFileSync23, readdirSync as readdirSync20, statSync as statSync28 } from "fs";
17598
17603
  import { homedir as homedir11 } from "os";
17599
- import { join as join33, basename as basename16 } from "path";
17604
+ import { join as join34, basename as basename16 } from "path";
17600
17605
  function parseFrontmatter2(content) {
17601
17606
  const fm = {};
17602
17607
  let body = content;
@@ -17622,7 +17627,7 @@ function parseFrontmatter2(content) {
17622
17627
  return { fm, body };
17623
17628
  }
17624
17629
  function projectHashToPath(hashDir) {
17625
- return decodeProjectDirName(hashDir);
17630
+ return resolveProjectDirName(hashDir);
17626
17631
  }
17627
17632
  function discoverMemoryDirs() {
17628
17633
  const out = [];
@@ -17636,9 +17641,9 @@ function discoverMemoryDirs() {
17636
17641
  const home = homedir11();
17637
17642
  const claudeRoots = [claudeBackend.projectsDir()];
17638
17643
  try {
17639
- for (const entry of readdirSync19(home, { withFileTypes: true })) {
17644
+ for (const entry of readdirSync20(home, { withFileTypes: true })) {
17640
17645
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
17641
- claudeRoots.push(join33(home, entry.name, "projects"));
17646
+ claudeRoots.push(join34(home, entry.name, "projects"));
17642
17647
  }
17643
17648
  }
17644
17649
  } catch {
@@ -17647,10 +17652,10 @@ function discoverMemoryDirs() {
17647
17652
  if (!existsSync30(projectsDir))
17648
17653
  continue;
17649
17654
  try {
17650
- for (const entry of readdirSync19(projectsDir, { withFileTypes: true })) {
17655
+ for (const entry of readdirSync20(projectsDir, { withFileTypes: true })) {
17651
17656
  if (!entry.isDirectory() || entry.name.startsWith("."))
17652
17657
  continue;
17653
- add(join33(projectsDir, entry.name, "memory"), entry.name);
17658
+ add(join34(projectsDir, entry.name, "memory"), entry.name);
17654
17659
  }
17655
17660
  } catch {
17656
17661
  }
@@ -17676,10 +17681,10 @@ var init_agent_memory_source = __esm({
17676
17681
  for (const { memoryDir, projectHash } of discoverMemoryDirs()) {
17677
17682
  const projectPath = projectHashToPath(projectHash);
17678
17683
  try {
17679
- for (const entry of readdirSync19(memoryDir, { withFileTypes: true })) {
17684
+ for (const entry of readdirSync20(memoryDir, { withFileTypes: true })) {
17680
17685
  if (!entry.isFile() || !entry.name.endsWith(".md"))
17681
17686
  continue;
17682
- const filePath = join33(memoryDir, entry.name);
17687
+ const filePath = join34(memoryDir, entry.name);
17683
17688
  if (seen.has(filePath))
17684
17689
  continue;
17685
17690
  seen.add(filePath);
@@ -17747,7 +17752,7 @@ var init_agent_memory_source = __esm({
17747
17752
  }
17748
17753
  fileToItem(filePath, filename, projectPath, _projectHash) {
17749
17754
  try {
17750
- const stat3 = statSync27(filePath);
17755
+ const stat3 = statSync28(filePath);
17751
17756
  const content = readFileSync23(filePath, "utf-8");
17752
17757
  const { fm } = parseFrontmatter2(content);
17753
17758
  const stem = filename.replace(/\.md$/, "");
@@ -17779,11 +17784,11 @@ var init_agent_memory_source = __esm({
17779
17784
  });
17780
17785
 
17781
17786
  // ../engine/dist/parsers/history-source.js
17782
- import { existsSync as existsSync31, readdirSync as readdirSync20, statSync as statSync28 } from "fs";
17787
+ import { existsSync as existsSync31, readdirSync as readdirSync21, statSync as statSync29 } from "fs";
17783
17788
  import { createReadStream as createReadStream3 } from "fs";
17784
17789
  import { createInterface as createInterface2 } from "readline";
17785
17790
  import { homedir as homedir12 } from "os";
17786
- import { join as join34 } from "path";
17791
+ import { join as join35 } from "path";
17787
17792
  var MAX_CHUNK_CHARS5, HistorySource;
17788
17793
  var init_history_source = __esm({
17789
17794
  "../engine/dist/parsers/history-source.js"() {
@@ -17806,14 +17811,14 @@ var init_history_source = __esm({
17806
17811
  };
17807
17812
  tryAdd(claudeBackend.historyFile());
17808
17813
  try {
17809
- for (const entry of readdirSync20(home, { withFileTypes: true })) {
17814
+ for (const entry of readdirSync21(home, { withFileTypes: true })) {
17810
17815
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
17811
- tryAdd(join34(home, entry.name, "history.jsonl"));
17816
+ tryAdd(join35(home, entry.name, "history.jsonl"));
17812
17817
  }
17813
17818
  }
17814
17819
  } catch {
17815
17820
  }
17816
- this.historyPaths = paths.length > 0 ? paths : [join34(home, ".claude", "history.jsonl")];
17821
+ this.historyPaths = paths.length > 0 ? paths : [join35(home, ".claude", "history.jsonl")];
17817
17822
  }
17818
17823
  }
17819
17824
  async *discover() {
@@ -17822,7 +17827,7 @@ var init_history_source = __esm({
17822
17827
  const historyPath = this.historyPaths.find((p) => existsSync31(p));
17823
17828
  if (!historyPath)
17824
17829
  return;
17825
- const stat3 = statSync28(historyPath);
17830
+ const stat3 = statSync29(historyPath);
17826
17831
  const groups = await this.groupByProject();
17827
17832
  for (const [project, group] of groups) {
17828
17833
  const projectId = project.replace(/\//g, "-").replace(/^-/, "");
@@ -17963,9 +17968,9 @@ var init_history_source = __esm({
17963
17968
  });
17964
17969
 
17965
17970
  // ../engine/dist/parsers/paste-source.js
17966
- import { existsSync as existsSync32, readdirSync as readdirSync21, readFileSync as readFileSync24, statSync as statSync29 } from "fs";
17971
+ import { existsSync as existsSync32, readdirSync as readdirSync22, readFileSync as readFileSync24, statSync as statSync30 } from "fs";
17967
17972
  import { homedir as homedir13 } from "os";
17968
- import { join as join35, basename as basename17 } from "path";
17973
+ import { join as join36, basename as basename17 } from "path";
17969
17974
  var MAX_CHUNK_CHARS6, MAX_FILE_SIZE, PasteSource;
17970
17975
  var init_paste_source = __esm({
17971
17976
  "../engine/dist/parsers/paste-source.js"() {
@@ -17989,9 +17994,9 @@ var init_paste_source = __esm({
17989
17994
  };
17990
17995
  tryAdd(claudeBackend.pasteCacheDir());
17991
17996
  try {
17992
- for (const entry of readdirSync21(home, { withFileTypes: true })) {
17997
+ for (const entry of readdirSync22(home, { withFileTypes: true })) {
17993
17998
  if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
17994
- tryAdd(join35(home, entry.name, "paste-cache"));
17999
+ tryAdd(join36(home, entry.name, "paste-cache"));
17995
18000
  }
17996
18001
  }
17997
18002
  } catch {
@@ -18006,14 +18011,14 @@ var init_paste_source = __esm({
18006
18011
  for (const cacheDir of this.cacheDirs) {
18007
18012
  if (!existsSync32(cacheDir))
18008
18013
  continue;
18009
- const files = readdirSync21(cacheDir).filter((f) => f.endsWith(".txt"));
18014
+ const files = readdirSync22(cacheDir).filter((f) => f.endsWith(".txt"));
18010
18015
  for (const file of files) {
18011
18016
  if (seen.has(file))
18012
18017
  continue;
18013
18018
  seen.add(file);
18014
- const filePath = join35(cacheDir, file);
18019
+ const filePath = join36(cacheDir, file);
18015
18020
  try {
18016
- const stat3 = statSync29(filePath);
18021
+ const stat3 = statSync30(filePath);
18017
18022
  if (stat3.size > MAX_FILE_SIZE)
18018
18023
  continue;
18019
18024
  if (stat3.size < 10)
@@ -18063,9 +18068,9 @@ var init_paste_source = __esm({
18063
18068
  });
18064
18069
 
18065
18070
  // ../engine/dist/parsers/gemini-source.js
18066
- import { existsSync as existsSync33, readdirSync as readdirSync22, readFileSync as readFileSync25, statSync as statSync30 } from "fs";
18067
- import { join as join36, basename as basename18 } from "path";
18068
- import { createHash as createHash12 } from "crypto";
18071
+ import { existsSync as existsSync33, readdirSync as readdirSync23, readFileSync as readFileSync25, statSync as statSync31 } from "fs";
18072
+ import { join as join37, basename as basename18 } from "path";
18073
+ import { createHash as createHash13 } from "crypto";
18069
18074
  function loadGeminiProjectMap2() {
18070
18075
  const map = /* @__PURE__ */ new Map();
18071
18076
  const projectsPath = geminiBackend.projectsJson();
@@ -18075,7 +18080,7 @@ function loadGeminiProjectMap2() {
18075
18080
  const data = JSON.parse(readFileSync25(projectsPath, "utf-8"));
18076
18081
  const projects = data.projects || {};
18077
18082
  for (const [path] of Object.entries(projects)) {
18078
- const hash = createHash12("sha256").update(path).digest("hex");
18083
+ const hash = createHash13("sha256").update(path).digest("hex");
18079
18084
  map.set(hash, path);
18080
18085
  }
18081
18086
  } catch {
@@ -18100,23 +18105,23 @@ var init_gemini_source = __esm({
18100
18105
  async *discover() {
18101
18106
  if (!isSourceEnabled("gemini", "sessions"))
18102
18107
  return;
18103
- const tmpDir = join36(this.geminiDir, "tmp");
18108
+ const tmpDir = join37(this.geminiDir, "tmp");
18104
18109
  if (!existsSync33(tmpDir))
18105
18110
  return;
18106
18111
  const seen = /* @__PURE__ */ new Set();
18107
18112
  try {
18108
- for (const projectDirEntry of readdirSync22(tmpDir, { withFileTypes: true })) {
18113
+ for (const projectDirEntry of readdirSync23(tmpDir, { withFileTypes: true })) {
18109
18114
  if (!projectDirEntry.isDirectory())
18110
18115
  continue;
18111
- const chatsDir = join36(tmpDir, projectDirEntry.name, "chats");
18116
+ const chatsDir = join37(tmpDir, projectDirEntry.name, "chats");
18112
18117
  if (!existsSync33(chatsDir))
18113
18118
  continue;
18114
- for (const file of readdirSync22(chatsDir)) {
18119
+ for (const file of readdirSync23(chatsDir)) {
18115
18120
  if (!file.endsWith(".json") || !file.startsWith("session-"))
18116
18121
  continue;
18117
- const filePath = join36(chatsDir, file);
18122
+ const filePath = join37(chatsDir, file);
18118
18123
  try {
18119
- const stat3 = statSync30(filePath);
18124
+ const stat3 = statSync31(filePath);
18120
18125
  const content = JSON.parse(readFileSync25(filePath, "utf-8"));
18121
18126
  const sessionId = content.sessionId || basename18(file, ".json");
18122
18127
  if (seen.has(sessionId))
@@ -18246,8 +18251,8 @@ var init_gemini_source = __esm({
18246
18251
  });
18247
18252
 
18248
18253
  // ../engine/dist/parsers/gemini-brain-source.js
18249
- import { existsSync as existsSync34, readdirSync as readdirSync23, readFileSync as readFileSync26, statSync as statSync31 } from "fs";
18250
- import { join as join37 } from "path";
18254
+ import { existsSync as existsSync34, readdirSync as readdirSync24, readFileSync as readFileSync26, statSync as statSync32 } from "fs";
18255
+ import { join as join38 } from "path";
18251
18256
  var MAX_CHUNK_CHARS8, GeminiBrainSource;
18252
18257
  var init_gemini_brain_source = __esm({
18253
18258
  "../engine/dist/parsers/gemini-brain-source.js"() {
@@ -18267,18 +18272,18 @@ var init_gemini_brain_source = __esm({
18267
18272
  return;
18268
18273
  if (!existsSync34(this.brainDir))
18269
18274
  return;
18270
- const sessions = readdirSync23(this.brainDir, { withFileTypes: true });
18275
+ const sessions = readdirSync24(this.brainDir, { withFileTypes: true });
18271
18276
  for (const entry of sessions) {
18272
18277
  if (!entry.isDirectory())
18273
18278
  continue;
18274
- const sessionDir = join37(this.brainDir, entry.name);
18275
- const files = readdirSync23(sessionDir).filter((f) => f.endsWith(".md") && !f.includes(".resolved") && !f.includes(".metadata"));
18279
+ const sessionDir = join38(this.brainDir, entry.name);
18280
+ const files = readdirSync24(sessionDir).filter((f) => f.endsWith(".md") && !f.includes(".resolved") && !f.includes(".metadata"));
18276
18281
  if (files.length === 0)
18277
18282
  continue;
18278
18283
  for (const file of files) {
18279
- const filePath = join37(sessionDir, file);
18284
+ const filePath = join38(sessionDir, file);
18280
18285
  try {
18281
- const stat3 = statSync31(filePath);
18286
+ const stat3 = statSync32(filePath);
18282
18287
  const content = readFileSync26(filePath, "utf-8");
18283
18288
  const firstLine = content.split("\n").find((l) => l.trim() && !l.startsWith("#"))?.trim() || "";
18284
18289
  const heading = content.split("\n").find((l) => l.startsWith("#"))?.replace(/^#+\s*/, "").trim() || file;
@@ -18660,8 +18665,8 @@ var init_opencode_todo_source = __esm({
18660
18665
  });
18661
18666
 
18662
18667
  // ../engine/dist/parsers/codex-session-source.js
18663
- import { existsSync as existsSync37, readdirSync as readdirSync24, readFileSync as readFileSync27, statSync as statSync32 } from "fs";
18664
- import { join as join38, basename as basename19 } from "path";
18668
+ import { existsSync as existsSync37, readdirSync as readdirSync25, readFileSync as readFileSync27, statSync as statSync33 } from "fs";
18669
+ import { join as join39, basename as basename19 } from "path";
18665
18670
  function getCodexSessionsDir() {
18666
18671
  return codexBackend.sessionsDir();
18667
18672
  }
@@ -18722,7 +18727,7 @@ var init_codex_session_source = __esm({
18722
18727
  const jsonlFiles = this.collectJsonlFiles(this.sessionsDir);
18723
18728
  for (const filePath of jsonlFiles) {
18724
18729
  try {
18725
- const stat3 = statSync32(filePath);
18730
+ const stat3 = statSync33(filePath);
18726
18731
  const lines = readFileSync27(filePath, "utf-8").split("\n");
18727
18732
  const firstLine = lines.find((l) => l.trim());
18728
18733
  if (!firstLine)
@@ -18881,8 +18886,8 @@ var init_codex_session_source = __esm({
18881
18886
  const results = [];
18882
18887
  if (!existsSync37(dir))
18883
18888
  return results;
18884
- for (const entry of readdirSync24(dir, { withFileTypes: true })) {
18885
- const fullPath = join38(dir, entry.name);
18889
+ for (const entry of readdirSync25(dir, { withFileTypes: true })) {
18890
+ const fullPath = join39(dir, entry.name);
18886
18891
  if (entry.isDirectory()) {
18887
18892
  results.push(...this.collectJsonlFiles(fullPath));
18888
18893
  } else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl")) {
@@ -18896,8 +18901,8 @@ var init_codex_session_source = __esm({
18896
18901
  });
18897
18902
 
18898
18903
  // ../engine/dist/parsers/diary-source.js
18899
- import { existsSync as existsSync38, mkdirSync as mkdirSync8, readdirSync as readdirSync25, readFileSync as readFileSync28, writeFileSync as writeFileSync6, statSync as statSync33 } from "fs";
18900
- import { join as join39, basename as basename20 } from "path";
18904
+ import { existsSync as existsSync38, mkdirSync as mkdirSync9, readdirSync as readdirSync26, readFileSync as readFileSync28, writeFileSync as writeFileSync6, statSync as statSync34 } from "fs";
18905
+ import { join as join40, basename as basename20 } from "path";
18901
18906
  var MAX_CHUNK_CHARS11, DiarySource;
18902
18907
  var init_diary_source = __esm({
18903
18908
  "../engine/dist/parsers/diary-source.js"() {
@@ -18914,14 +18919,14 @@ var init_diary_source = __esm({
18914
18919
  async *discover() {
18915
18920
  if (!existsSync38(this.diaryDir))
18916
18921
  return;
18917
- const agents = readdirSync25(this.diaryDir, { withFileTypes: true }).filter((d) => d.isDirectory());
18922
+ const agents = readdirSync26(this.diaryDir, { withFileTypes: true }).filter((d) => d.isDirectory());
18918
18923
  for (const agentDir of agents) {
18919
- const agentPath = join39(this.diaryDir, agentDir.name);
18920
- const files = readdirSync25(agentPath).filter((f) => f.endsWith(".json"));
18924
+ const agentPath = join40(this.diaryDir, agentDir.name);
18925
+ const files = readdirSync26(agentPath).filter((f) => f.endsWith(".json"));
18921
18926
  for (const file of files) {
18922
- const filePath = join39(agentPath, file);
18927
+ const filePath = join40(agentPath, file);
18923
18928
  try {
18924
- const stat3 = statSync33(filePath);
18929
+ const stat3 = statSync34(filePath);
18925
18930
  const raw = readFileSync28(filePath, "utf-8");
18926
18931
  const entry = JSON.parse(raw);
18927
18932
  const entryId = basename20(file, ".json");
@@ -18986,13 +18991,13 @@ var init_diary_source = __esm({
18986
18991
  */
18987
18992
  static write(entry, diaryDir) {
18988
18993
  const dir = diaryDir || getDiaryDir();
18989
- const agentDir = join39(dir, entry.agent.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
18994
+ const agentDir = join40(dir, entry.agent.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
18990
18995
  if (!existsSync38(agentDir)) {
18991
- mkdirSync8(agentDir, { recursive: true });
18996
+ mkdirSync9(agentDir, { recursive: true });
18992
18997
  }
18993
18998
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
18994
18999
  const entryId = `diary_${entry.agent.toLowerCase()}_${ts}`;
18995
- const filePath = join39(agentDir, `${entryId}.json`);
19000
+ const filePath = join40(agentDir, `${entryId}.json`);
18996
19001
  const full = {
18997
19002
  ...entry,
18998
19003
  timestamp: entry.timestamp || (/* @__PURE__ */ new Date()).toISOString()
@@ -19005,14 +19010,14 @@ var init_diary_source = __esm({
19005
19010
  */
19006
19011
  static read(agentName, lastN = 10, diaryDir) {
19007
19012
  const dir = diaryDir || getDiaryDir();
19008
- const agentDir = join39(dir, agentName.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
19013
+ const agentDir = join40(dir, agentName.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
19009
19014
  if (!existsSync38(agentDir))
19010
19015
  return [];
19011
- const files = readdirSync25(agentDir).filter((f) => f.endsWith(".json")).sort().reverse().slice(0, lastN);
19016
+ const files = readdirSync26(agentDir).filter((f) => f.endsWith(".json")).sort().reverse().slice(0, lastN);
19012
19017
  const entries = [];
19013
19018
  for (const file of files) {
19014
19019
  try {
19015
- const raw = readFileSync28(join39(agentDir, file), "utf-8");
19020
+ const raw = readFileSync28(join40(agentDir, file), "utf-8");
19016
19021
  entries.push(JSON.parse(raw));
19017
19022
  } catch {
19018
19023
  continue;
@@ -19057,9 +19062,9 @@ var init_redact_inline = __esm({
19057
19062
  });
19058
19063
 
19059
19064
  // ../engine/dist/parsers/skills-source.js
19060
- import { existsSync as existsSync39, readdirSync as readdirSync26, readFileSync as readFileSync29, statSync as statSync34 } from "fs";
19065
+ import { existsSync as existsSync39, readdirSync as readdirSync27, readFileSync as readFileSync29, statSync as statSync35 } from "fs";
19061
19066
  import { homedir as homedir14 } from "os";
19062
- import { join as join40 } from "path";
19067
+ import { join as join41 } from "path";
19063
19068
  function rebuildBody(content) {
19064
19069
  const { text, redacted } = redactInlineSecrets(content);
19065
19070
  const out = {};
@@ -19077,7 +19082,7 @@ function resolveRoots() {
19077
19082
  const home = homedir14();
19078
19083
  const all = [];
19079
19084
  if (isSourceEnabled("shared", "skills")) {
19080
- all.push({ path: join40(home, ".agents", "skills"), tool: "shared" });
19085
+ all.push({ path: join41(home, ".agents", "skills"), tool: "shared" });
19081
19086
  }
19082
19087
  if (isSourceEnabled("claude", "skills")) {
19083
19088
  all.push({ path: claudeBackend.skillsDir(), tool: "claude" });
@@ -19086,15 +19091,15 @@ function resolveRoots() {
19086
19091
  all.push({ path: geminiBackend.skillsDir(), tool: "gemini" });
19087
19092
  }
19088
19093
  if (isSourceEnabled("opencode", "skills")) {
19089
- all.push({ path: join40(home, ".config", "opencode", "skills"), tool: "opencode" }, { path: join40(home, ".config", "opencode", "skill"), tool: "opencode" }, { path: join40(home, ".opencode", "skill"), tool: "opencode" }, { path: join40(home, ".opencode", "skills"), tool: "opencode" });
19094
+ all.push({ path: join41(home, ".config", "opencode", "skills"), tool: "opencode" }, { path: join41(home, ".config", "opencode", "skill"), tool: "opencode" }, { path: join41(home, ".opencode", "skill"), tool: "opencode" }, { path: join41(home, ".opencode", "skills"), tool: "opencode" });
19090
19095
  }
19091
19096
  if (isSourceEnabled("codex", "skills")) {
19092
19097
  all.push({ path: codexBackend.skillsDir(), tool: "codex", skipChildren: [".system"] });
19093
19098
  all.push({ path: codexBackend.skillsSystemDir(), tool: "codex", readonly: true });
19094
19099
  }
19095
19100
  if (isSourceEnabled("cursor", "skills")) {
19096
- all.push({ path: join40(cursorHomeDir(), "skills"), tool: "cursor" });
19097
- all.push({ path: join40(cursorHomeDir(), "skills-cursor"), tool: "cursor", readonly: true });
19101
+ all.push({ path: join41(cursorHomeDir(), "skills"), tool: "cursor" });
19102
+ all.push({ path: join41(cursorHomeDir(), "skills-cursor"), tool: "cursor", readonly: true });
19098
19103
  }
19099
19104
  return all.filter((r) => existsSync39(r.path));
19100
19105
  }
@@ -19138,8 +19143,8 @@ var init_skills_source = __esm({
19138
19143
  return;
19139
19144
  const codexPluginsDir = codexBackend.pluginsDir();
19140
19145
  if (existsSync39(codexPluginsDir)) {
19141
- for (const pluginName of readdirSync26(codexPluginsDir)) {
19142
- const skillsDir = join40(codexPluginsDir, pluginName, "skills");
19146
+ for (const pluginName of readdirSync27(codexPluginsDir)) {
19147
+ const skillsDir = join41(codexPluginsDir, pluginName, "skills");
19143
19148
  if (!existsSync39(skillsDir))
19144
19149
  continue;
19145
19150
  yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
@@ -19149,23 +19154,23 @@ var init_skills_source = __esm({
19149
19154
  async *fromSkillRoot(root, pluginName) {
19150
19155
  let entries;
19151
19156
  try {
19152
- entries = readdirSync26(root.path);
19157
+ entries = readdirSync27(root.path);
19153
19158
  } catch {
19154
19159
  return;
19155
19160
  }
19156
19161
  for (const name of entries) {
19157
19162
  if (root.skipChildren?.includes(name))
19158
19163
  continue;
19159
- const skillDir = join40(root.path, name);
19164
+ const skillDir = join41(root.path, name);
19160
19165
  let st;
19161
19166
  try {
19162
- st = statSync34(skillDir);
19167
+ st = statSync35(skillDir);
19163
19168
  } catch {
19164
19169
  continue;
19165
19170
  }
19166
19171
  if (!st.isDirectory())
19167
19172
  continue;
19168
- const skillMd = join40(skillDir, "SKILL.md");
19173
+ const skillMd = join41(skillDir, "SKILL.md");
19169
19174
  if (!existsSync39(skillMd))
19170
19175
  continue;
19171
19176
  let content;
@@ -19178,19 +19183,19 @@ var init_skills_source = __esm({
19178
19183
  const skillName = fm.name || name;
19179
19184
  let mtime = st.mtimeMs;
19180
19185
  try {
19181
- mtime = statSync34(skillMd).mtimeMs;
19186
+ mtime = statSync35(skillMd).mtimeMs;
19182
19187
  } catch {
19183
19188
  }
19184
19189
  const subdirs = {};
19185
19190
  try {
19186
- for (const sub of readdirSync26(skillDir)) {
19187
- const subPath = join40(skillDir, sub);
19191
+ for (const sub of readdirSync27(skillDir)) {
19192
+ const subPath = join41(skillDir, sub);
19188
19193
  try {
19189
- const ss = statSync34(subPath);
19194
+ const ss = statSync35(subPath);
19190
19195
  if (ss.isDirectory()) {
19191
19196
  let count = 0;
19192
19197
  try {
19193
- count = readdirSync26(subPath).length;
19198
+ count = readdirSync27(subPath).length;
19194
19199
  } catch {
19195
19200
  }
19196
19201
  subdirs[sub] = count;
@@ -19256,9 +19261,9 @@ var init_skills_source = __esm({
19256
19261
  });
19257
19262
 
19258
19263
  // ../engine/dist/parsers/mcps-source.js
19259
- import { existsSync as existsSync40, readdirSync as readdirSync27, readFileSync as readFileSync30, statSync as statSync35 } from "fs";
19264
+ import { existsSync as existsSync40, readdirSync as readdirSync28, readFileSync as readFileSync30, statSync as statSync36 } from "fs";
19260
19265
  import { homedir as homedir15 } from "os";
19261
- import { join as join41 } from "path";
19266
+ import { join as join42 } from "path";
19262
19267
  function readJson(path) {
19263
19268
  if (!existsSync40(path))
19264
19269
  return null;
@@ -19324,23 +19329,23 @@ var init_mcps_source = __esm({
19324
19329
  if (!isSourceEnabled("common", "mcps"))
19325
19330
  return;
19326
19331
  const home = homedir15();
19327
- yield* this.fromObject(readJson(join41(home, ".mcp.json"))?.mcpServers, {
19332
+ yield* this.fromObject(readJson(join42(home, ".mcp.json"))?.mcpServers, {
19328
19333
  tool: "claude",
19329
- filePath: join41(home, ".mcp.json"),
19334
+ filePath: join42(home, ".mcp.json"),
19330
19335
  scope: "global"
19331
19336
  });
19332
- yield* this.fromObject(readJson(join41(home, ".claude.json"))?.mcpServers, {
19337
+ yield* this.fromObject(readJson(join42(home, ".claude.json"))?.mcpServers, {
19333
19338
  tool: "claude",
19334
- filePath: join41(home, ".claude.json"),
19339
+ filePath: join42(home, ".claude.json"),
19335
19340
  scope: "user"
19336
19341
  });
19337
19342
  for (const path of [
19338
- join41(home, ".config", "opencode", "opencode.json"),
19339
- join41(home, ".config", "opencode", "opencode.jsonc"),
19340
- join41(home, ".config", "opencode", "config.json"),
19341
- join41(home, ".opencode", "opencode.json"),
19342
- join41(home, ".opencode", "opencode.jsonc"),
19343
- join41(home, ".opencode", "config.json")
19343
+ join42(home, ".config", "opencode", "opencode.json"),
19344
+ join42(home, ".config", "opencode", "opencode.jsonc"),
19345
+ join42(home, ".config", "opencode", "config.json"),
19346
+ join42(home, ".opencode", "opencode.json"),
19347
+ join42(home, ".opencode", "opencode.jsonc"),
19348
+ join42(home, ".opencode", "config.json")
19344
19349
  ]) {
19345
19350
  yield* this.fromObject(readJson(path)?.mcp, {
19346
19351
  tool: "opencode",
@@ -19355,13 +19360,13 @@ var init_mcps_source = __esm({
19355
19360
  filePath: geminiSettings,
19356
19361
  scope: "user"
19357
19362
  });
19358
- const cursorMcp = join41(cursorHomeDir(), "mcp.json");
19363
+ const cursorMcp = join42(cursorHomeDir(), "mcp.json");
19359
19364
  yield* this.fromObject(readJson(cursorMcp)?.mcpServers, {
19360
19365
  tool: "cursor",
19361
19366
  filePath: cursorMcp,
19362
19367
  scope: "user"
19363
19368
  });
19364
- const agyMcp = join41(home, ".gemini", "config", "mcp_config.json");
19369
+ const agyMcp = join42(home, ".gemini", "config", "mcp_config.json");
19365
19370
  yield* this.fromObject(readJson(agyMcp)?.mcpServers, {
19366
19371
  tool: "agy",
19367
19372
  filePath: agyMcp,
@@ -19370,8 +19375,8 @@ var init_mcps_source = __esm({
19370
19375
  yield* this.fromCodexToml(codexBackend.configToml());
19371
19376
  const pluginsDir = codexBackend.pluginsDir();
19372
19377
  if (existsSync40(pluginsDir)) {
19373
- for (const plugin of readdirSync27(pluginsDir)) {
19374
- const mcpPath = join41(pluginsDir, plugin, ".mcp.json");
19378
+ for (const plugin of readdirSync28(pluginsDir)) {
19379
+ const mcpPath = join42(pluginsDir, plugin, ".mcp.json");
19375
19380
  yield* this.fromObject(readJson(mcpPath)?.mcpServers, {
19376
19381
  tool: "codex",
19377
19382
  filePath: mcpPath,
@@ -19385,7 +19390,7 @@ var init_mcps_source = __esm({
19385
19390
  return;
19386
19391
  let mtime = 0;
19387
19392
  try {
19388
- mtime = statSync35(ctx.filePath).mtimeMs;
19393
+ mtime = statSync36(ctx.filePath).mtimeMs;
19389
19394
  } catch {
19390
19395
  }
19391
19396
  for (const [name, cfgRaw] of Object.entries(obj)) {
@@ -19577,8 +19582,8 @@ var init_toolkit_format = __esm({
19577
19582
  });
19578
19583
 
19579
19584
  // ../engine/dist/parsers/slash-commands-source.js
19580
- import { existsSync as existsSync41, readdirSync as readdirSync28, readFileSync as readFileSync31, statSync as statSync36 } from "fs";
19581
- import { join as join42, basename as basename21 } from "path";
19585
+ import { existsSync as existsSync41, readdirSync as readdirSync29, readFileSync as readFileSync31, statSync as statSync37 } from "fs";
19586
+ import { join as join43, basename as basename21 } from "path";
19582
19587
  function rebuildBody2(content) {
19583
19588
  const { text, redacted } = redactInlineSecrets(content);
19584
19589
  const out = {};
@@ -19632,11 +19637,11 @@ var init_slash_commands_source = __esm({
19632
19637
  const projectsRoot = claudeBackend.projectsDir();
19633
19638
  if (existsSync41(projectsRoot)) {
19634
19639
  try {
19635
- for (const entry of readdirSync28(projectsRoot, { withFileTypes: true })) {
19640
+ for (const entry of readdirSync29(projectsRoot, { withFileTypes: true })) {
19636
19641
  if (!entry.isDirectory() || entry.name.startsWith("."))
19637
19642
  continue;
19638
- const projectPath = decodeProjectDirName(entry.name);
19639
- const cmdDir = join42(projectPath, ".claude", "commands");
19643
+ const projectPath = resolveProjectDirName(entry.name);
19644
+ const cmdDir = join43(projectPath, ".claude", "commands");
19640
19645
  if (existsSync41(cmdDir))
19641
19646
  roots.push({ path: cmdDir, tool: "claude", scope: "project", projectPath, format: "md" });
19642
19647
  }
@@ -19654,7 +19659,7 @@ var init_slash_commands_source = __esm({
19654
19659
  roots.push({ path: codexBackend.promptsDir(), tool: "codex", scope: "user", projectPath: "", format: "md" });
19655
19660
  }
19656
19661
  if (isSourceEnabled("cursor", "commands")) {
19657
- roots.push({ path: join42(cursorHomeDir(), "commands"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
19662
+ roots.push({ path: join43(cursorHomeDir(), "commands"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
19658
19663
  }
19659
19664
  return roots;
19660
19665
  }
@@ -19663,14 +19668,14 @@ var init_slash_commands_source = __esm({
19663
19668
  const ext = root.format === "toml" ? ".toml" : ".md";
19664
19669
  let files;
19665
19670
  try {
19666
- files = readdirSync28(root.path).filter((f) => f.endsWith(ext));
19671
+ files = readdirSync29(root.path).filter((f) => f.endsWith(ext));
19667
19672
  } catch {
19668
19673
  continue;
19669
19674
  }
19670
19675
  for (const file of files) {
19671
- const filePath = join42(root.path, file);
19676
+ const filePath = join43(root.path, file);
19672
19677
  try {
19673
- const stat3 = statSync36(filePath);
19678
+ const stat3 = statSync37(filePath);
19674
19679
  const content = readFileSync31(filePath, "utf-8");
19675
19680
  const parsed = parseCommand(content, basename21(file, ext), root.format);
19676
19681
  yield {
@@ -19723,8 +19728,8 @@ var init_slash_commands_source = __esm({
19723
19728
  });
19724
19729
 
19725
19730
  // ../engine/dist/parsers/subagents-source.js
19726
- import { existsSync as existsSync42, readdirSync as readdirSync29, readFileSync as readFileSync32, statSync as statSync37 } from "fs";
19727
- import { join as join43, basename as basename22 } from "path";
19731
+ import { existsSync as existsSync42, readdirSync as readdirSync30, readFileSync as readFileSync32, statSync as statSync38 } from "fs";
19732
+ import { join as join44, basename as basename22 } from "path";
19728
19733
  function rebuildBody3(content) {
19729
19734
  const { text, redacted } = redactInlineSecrets(content);
19730
19735
  const out = {};
@@ -19780,11 +19785,11 @@ var init_subagents_source = __esm({
19780
19785
  const projectsRoot = claudeBackend.projectsDir();
19781
19786
  if (existsSync42(projectsRoot)) {
19782
19787
  try {
19783
- for (const entry of readdirSync29(projectsRoot, { withFileTypes: true })) {
19788
+ for (const entry of readdirSync30(projectsRoot, { withFileTypes: true })) {
19784
19789
  if (!entry.isDirectory() || entry.name.startsWith("."))
19785
19790
  continue;
19786
- const projectPath = decodeProjectDirName(entry.name);
19787
- const agentDir = join43(projectPath, ".claude", "agents");
19791
+ const projectPath = resolveProjectDirName(entry.name);
19792
+ const agentDir = join44(projectPath, ".claude", "agents");
19788
19793
  if (existsSync42(agentDir))
19789
19794
  roots.push({ path: agentDir, tool: "claude", scope: "project", projectPath, format: "md" });
19790
19795
  }
@@ -19802,7 +19807,7 @@ var init_subagents_source = __esm({
19802
19807
  roots.push({ path: codexBackend.agentsDir(), tool: "codex", scope: "user", projectPath: "", format: "toml" });
19803
19808
  }
19804
19809
  if (isSourceEnabled("cursor", "agents")) {
19805
- roots.push({ path: join43(cursorHomeDir(), "agents"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
19810
+ roots.push({ path: join44(cursorHomeDir(), "agents"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
19806
19811
  }
19807
19812
  return roots;
19808
19813
  }
@@ -19811,14 +19816,14 @@ var init_subagents_source = __esm({
19811
19816
  const ext = root.format === "toml" ? ".toml" : ".md";
19812
19817
  let files;
19813
19818
  try {
19814
- files = readdirSync29(root.path).filter((f) => f.endsWith(ext));
19819
+ files = readdirSync30(root.path).filter((f) => f.endsWith(ext));
19815
19820
  } catch {
19816
19821
  continue;
19817
19822
  }
19818
19823
  for (const file of files) {
19819
- const filePath = join43(root.path, file);
19824
+ const filePath = join44(root.path, file);
19820
19825
  try {
19821
- const stat3 = statSync37(filePath);
19826
+ const stat3 = statSync38(filePath);
19822
19827
  const content = readFileSync32(filePath, "utf-8");
19823
19828
  const parsed = parseAgent(content, basename22(file, ext), root.format);
19824
19829
  yield {
@@ -19872,8 +19877,8 @@ var init_subagents_source = __esm({
19872
19877
  });
19873
19878
 
19874
19879
  // ../engine/dist/parsers/hooks-source.js
19875
- import { existsSync as existsSync43, readFileSync as readFileSync33, readdirSync as readdirSync30, statSync as statSync38 } from "fs";
19876
- import { join as join44 } from "path";
19880
+ import { existsSync as existsSync43, readFileSync as readFileSync33, readdirSync as readdirSync31, statSync as statSync39 } from "fs";
19881
+ import { join as join45 } from "path";
19877
19882
  function readJson2(path) {
19878
19883
  if (!existsSync43(path))
19879
19884
  return null;
@@ -19899,11 +19904,11 @@ var init_hooks_source = __esm({
19899
19904
  const projectsRoot = claudeBackend.projectsDir();
19900
19905
  if (existsSync43(projectsRoot)) {
19901
19906
  try {
19902
- for (const entry of readdirSync30(projectsRoot, { withFileTypes: true })) {
19907
+ for (const entry of readdirSync31(projectsRoot, { withFileTypes: true })) {
19903
19908
  if (!entry.isDirectory() || entry.name.startsWith("."))
19904
19909
  continue;
19905
- const projectPath = decodeProjectDirName(entry.name);
19906
- const settingsPath2 = join44(projectPath, ".claude", "settings.json");
19910
+ const projectPath = resolveProjectDirName(entry.name);
19911
+ const settingsPath2 = join45(projectPath, ".claude", "settings.json");
19907
19912
  if (existsSync43(settingsPath2)) {
19908
19913
  yield* this.fromSettings(settingsPath2, "project", projectPath);
19909
19914
  }
@@ -19921,7 +19926,7 @@ var init_hooks_source = __esm({
19921
19926
  return;
19922
19927
  let mtime = 0;
19923
19928
  try {
19924
- mtime = statSync38(settingsPath2).mtimeMs;
19929
+ mtime = statSync39(settingsPath2).mtimeMs;
19925
19930
  } catch {
19926
19931
  }
19927
19932
  for (const [event, groups] of Object.entries(hooks)) {
@@ -19995,9 +20000,9 @@ var init_hooks_source = __esm({
19995
20000
  });
19996
20001
 
19997
20002
  // ../engine/dist/parsers/plugins-source.js
19998
- import { existsSync as existsSync44, readFileSync as readFileSync34, readdirSync as readdirSync31, statSync as statSync39 } from "fs";
20003
+ import { existsSync as existsSync44, readFileSync as readFileSync34, readdirSync as readdirSync32, statSync as statSync40 } from "fs";
19999
20004
  import { homedir as homedir16 } from "os";
20000
- import { join as join45 } from "path";
20005
+ import { join as join46 } from "path";
20001
20006
  function readJson3(path) {
20002
20007
  if (!existsSync44(path))
20003
20008
  return null;
@@ -20024,7 +20029,7 @@ var init_plugins_source = __esm({
20024
20029
  if (claudeJson?.plugins && typeof claudeJson.plugins === "object") {
20025
20030
  let mtime = 0;
20026
20031
  try {
20027
- mtime = statSync39(claudePluginsManifest).mtimeMs;
20032
+ mtime = statSync40(claudePluginsManifest).mtimeMs;
20028
20033
  } catch {
20029
20034
  }
20030
20035
  for (const [pluginRef, installs] of Object.entries(claudeJson.plugins)) {
@@ -20057,27 +20062,27 @@ var init_plugins_source = __esm({
20057
20062
  if (isSourceEnabled("gemini", "extensions") && existsSync44(gemRoot)) {
20058
20063
  let entries;
20059
20064
  try {
20060
- entries = readdirSync31(gemRoot);
20065
+ entries = readdirSync32(gemRoot);
20061
20066
  } catch {
20062
20067
  entries = [];
20063
20068
  }
20064
20069
  for (const name of entries) {
20065
- const dir = join45(gemRoot, name);
20070
+ const dir = join46(gemRoot, name);
20066
20071
  let st;
20067
20072
  try {
20068
- st = statSync39(dir);
20073
+ st = statSync40(dir);
20069
20074
  } catch {
20070
20075
  continue;
20071
20076
  }
20072
20077
  if (!st.isDirectory())
20073
20078
  continue;
20074
- const manifestPath = join45(dir, "gemini-extension.json");
20079
+ const manifestPath = join46(dir, "gemini-extension.json");
20075
20080
  const manifest = readJson3(manifestPath);
20076
20081
  if (!manifest || typeof manifest !== "object")
20077
20082
  continue;
20078
20083
  let mtime = st.mtimeMs;
20079
20084
  try {
20080
- mtime = statSync39(manifestPath).mtimeMs;
20085
+ mtime = statSync40(manifestPath).mtimeMs;
20081
20086
  } catch {
20082
20087
  }
20083
20088
  const mcpServers = manifest.mcpServers ? Object.keys(manifest.mcpServers) : [];
@@ -20105,25 +20110,25 @@ var init_plugins_source = __esm({
20105
20110
  if (isSourceEnabled("codex", "plugins") && existsSync44(codexPluginsRoot)) {
20106
20111
  let entries;
20107
20112
  try {
20108
- entries = readdirSync31(codexPluginsRoot);
20113
+ entries = readdirSync32(codexPluginsRoot);
20109
20114
  } catch {
20110
20115
  entries = [];
20111
20116
  }
20112
20117
  for (const name of entries) {
20113
- const pluginDir = join45(codexPluginsRoot, name);
20118
+ const pluginDir = join46(codexPluginsRoot, name);
20114
20119
  let st;
20115
20120
  try {
20116
- st = statSync39(pluginDir);
20121
+ st = statSync40(pluginDir);
20117
20122
  } catch {
20118
20123
  continue;
20119
20124
  }
20120
20125
  if (!st.isDirectory())
20121
20126
  continue;
20122
- const appJson = readJson3(join45(pluginDir, ".codex-plugin", ".app.json"));
20123
- const pluginJson = readJson3(join45(pluginDir, ".codex-plugin", "plugin.json"));
20127
+ const appJson = readJson3(join46(pluginDir, ".codex-plugin", ".app.json"));
20128
+ const pluginJson = readJson3(join46(pluginDir, ".codex-plugin", "plugin.json"));
20124
20129
  const manifest = pluginJson || appJson || {};
20125
20130
  let mcpServers = [];
20126
- const mcpJson = readJson3(join45(pluginDir, ".mcp.json"));
20131
+ const mcpJson = readJson3(join46(pluginDir, ".mcp.json"));
20127
20132
  if (mcpJson?.mcpServers)
20128
20133
  mcpServers = Object.keys(mcpJson.mcpServers);
20129
20134
  yield {
@@ -20131,7 +20136,7 @@ var init_plugins_source = __esm({
20131
20136
  sourceType: "plugin",
20132
20137
  title: manifest.name || name,
20133
20138
  projectPath: "",
20134
- filePath: join45(pluginDir, ".codex-plugin"),
20139
+ filePath: join46(pluginDir, ".codex-plugin"),
20135
20140
  mtime: st.mtimeMs,
20136
20141
  contentPreview: (manifest.description || "").slice(0, 300),
20137
20142
  extra: {
@@ -20270,8 +20275,8 @@ var init_extractor_version = __esm({
20270
20275
  });
20271
20276
 
20272
20277
  // src/sync-ledger.ts
20273
- import { readFileSync as readFileSync35, writeFileSync as writeFileSync7, renameSync as renameSync5, mkdirSync as mkdirSync9 } from "node:fs";
20274
- import { join as join46, dirname as dirname16 } from "node:path";
20278
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync7, renameSync as renameSync5, mkdirSync as mkdirSync10 } from "node:fs";
20279
+ import { join as join47, dirname as dirname17 } from "node:path";
20275
20280
  function toRow(entry) {
20276
20281
  if (entry === void 0) return void 0;
20277
20282
  return typeof entry === "number" ? { m: entry, v: 0 } : entry;
@@ -20288,7 +20293,7 @@ function load() {
20288
20293
  }
20289
20294
  function persistNow(data) {
20290
20295
  const path = ledgerPath();
20291
- mkdirSync9(dirname16(path), { recursive: true });
20296
+ mkdirSync10(dirname17(path), { recursive: true });
20292
20297
  const tmp = `${path}.tmp`;
20293
20298
  writeFileSync7(tmp, JSON.stringify(data));
20294
20299
  renameSync5(tmp, path);
@@ -20363,7 +20368,7 @@ function saveItemVersions(server, versions) {
20363
20368
  const all = loadItemVersionsAll();
20364
20369
  all[server] = { ...all[server] || {}, ...versions };
20365
20370
  const path = itemVersionsPath();
20366
- mkdirSync9(dirname16(path), { recursive: true });
20371
+ mkdirSync10(dirname17(path), { recursive: true });
20367
20372
  const tmp = `${path}.tmp`;
20368
20373
  writeFileSync7(tmp, JSON.stringify(all));
20369
20374
  renameSync5(tmp, path);
@@ -20440,7 +20445,7 @@ function loadReconcile() {
20440
20445
  }
20441
20446
  function persistReconcile(data) {
20442
20447
  const path = reconcilePath();
20443
- mkdirSync9(dirname16(path), { recursive: true });
20448
+ mkdirSync10(dirname17(path), { recursive: true });
20444
20449
  const tmp = `${path}.tmp`;
20445
20450
  writeFileSync7(tmp, JSON.stringify(data));
20446
20451
  renameSync5(tmp, path);
@@ -20485,15 +20490,15 @@ var init_sync_ledger = __esm({
20485
20490
  "use strict";
20486
20491
  init_paths();
20487
20492
  init_extractor_version();
20488
- ledgerPath = () => join46(getDataDir(), "sync-ledger.json");
20493
+ ledgerPath = () => join47(getDataDir(), "sync-ledger.json");
20489
20494
  cache3 = null;
20490
20495
  LEDGER_FLUSH_MS = 2e3;
20491
20496
  pendingWrite = false;
20492
20497
  flushTimer = null;
20493
- itemVersionsPath = () => join46(getDataDir(), "item-versions.json");
20498
+ itemVersionsPath = () => join47(getDataDir(), "item-versions.json");
20494
20499
  itemVersionsCache = null;
20495
20500
  unackedCursorAttempts = 0;
20496
- reconcilePath = () => join46(getDataDir(), "sync-field-reconcile.json");
20501
+ reconcilePath = () => join47(getDataDir(), "sync-field-reconcile.json");
20497
20502
  reconcileCache = null;
20498
20503
  }
20499
20504
  });
@@ -20524,11 +20529,11 @@ var init_sync_fields = __esm({
20524
20529
  });
20525
20530
 
20526
20531
  // ../engine/dist/core/index-lock.js
20527
- import { existsSync as existsSync45, mkdirSync as mkdirSync10, openSync as openSync8, writeFileSync as writeFileSync8, readFileSync as readFileSync36, rmSync as rmSync4, statSync as statSync40, closeSync as closeSync8 } from "fs";
20528
- import { dirname as dirname17, join as join47 } from "path";
20532
+ import { existsSync as existsSync45, mkdirSync as mkdirSync11, openSync as openSync8, writeFileSync as writeFileSync8, readFileSync as readFileSync36, rmSync as rmSync4, statSync as statSync41, closeSync as closeSync8 } from "fs";
20533
+ import { dirname as dirname18, join as join48 } from "path";
20529
20534
  function acquireIndexLock(opts) {
20530
20535
  const lockPath = lockFilePath();
20531
- mkdirSync10(dirname17(lockPath), { recursive: true });
20536
+ mkdirSync11(dirname18(lockPath), { recursive: true });
20532
20537
  if (existsSync45(lockPath)) {
20533
20538
  if (!stealStaleLock(lockPath, opts.staleAfterMs ?? 10 * 6e4)) {
20534
20539
  return null;
@@ -20570,11 +20575,11 @@ function acquireIndexLock(opts) {
20570
20575
  };
20571
20576
  }
20572
20577
  function lockFilePath() {
20573
- return join47(getIndexDir(), ".compact.lock");
20578
+ return join48(getIndexDir(), ".compact.lock");
20574
20579
  }
20575
20580
  function stealStaleLock(lockPath, staleAfterMs) {
20576
20581
  try {
20577
- const s = statSync40(lockPath);
20582
+ const s = statSync41(lockPath);
20578
20583
  const age = Date.now() - s.mtimeMs;
20579
20584
  let payload;
20580
20585
  try {
@@ -20640,7 +20645,7 @@ var init_http = __esm({
20640
20645
  CLI_VERSION = JSON.parse(readFileSync37(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
20641
20646
  } catch {
20642
20647
  try {
20643
- if (true) CLI_VERSION = "0.5.31";
20648
+ if (true) CLI_VERSION = "0.6.0";
20644
20649
  } catch {
20645
20650
  }
20646
20651
  }
@@ -21137,16 +21142,16 @@ async function flush() {
21137
21142
  }
21138
21143
  function stableMark(value) {
21139
21144
  try {
21140
- const { createHash: createHash16 } = __require("node:crypto");
21141
- return createHash16("sha256").update(value).digest("hex").slice(0, 12);
21145
+ const { createHash: createHash17 } = __require("node:crypto");
21146
+ return createHash17("sha256").update(value).digest("hex").slice(0, 12);
21142
21147
  } catch {
21143
21148
  return "";
21144
21149
  }
21145
21150
  }
21146
21151
  function hashHost() {
21147
21152
  try {
21148
- const { createHash: createHash16 } = __require("node:crypto");
21149
- return createHash16("sha256").update(hostname()).digest("hex").slice(0, 12);
21153
+ const { createHash: createHash17 } = __require("node:crypto");
21154
+ return createHash17("sha256").update(hostname()).digest("hex").slice(0, 12);
21150
21155
  } catch {
21151
21156
  return "";
21152
21157
  }
@@ -21160,7 +21165,7 @@ var init_telemetry = __esm({
21160
21165
  init_sync_client();
21161
21166
  cliVersion2 = () => {
21162
21167
  try {
21163
- return true ? "0.5.31" : "dev";
21168
+ return true ? "0.6.0" : "dev";
21164
21169
  } catch {
21165
21170
  return "dev";
21166
21171
  }
@@ -21324,10 +21329,10 @@ __export(auto_update_exports, {
21324
21329
  import { execSync as execSync4 } from "node:child_process";
21325
21330
  import { readFileSync as readFileSync38 } from "node:fs";
21326
21331
  import { fileURLToPath as fileURLToPath2 } from "node:url";
21327
- import { writeFileSync as writeFileSync9, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync32, statSync as statSync41 } from "node:fs";
21328
- import { join as join48, dirname as dirname18, sep as sep3 } from "node:path";
21329
- import { tmpdir as tmpdir2 } from "node:os";
21330
- import { createHash as createHash13 } from "node:crypto";
21332
+ import { writeFileSync as writeFileSync9, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync33, statSync as statSync42 } from "node:fs";
21333
+ import { join as join49, dirname as dirname19, sep as sep3 } from "node:path";
21334
+ import { tmpdir as tmpdir3 } from "node:os";
21335
+ import { createHash as createHash14 } from "node:crypto";
21331
21336
  function compareVersions(a, b) {
21332
21337
  const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
21333
21338
  const pb = String(b).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
@@ -21349,8 +21354,8 @@ function newerOf(a, b) {
21349
21354
  }
21350
21355
  function installedVersion() {
21351
21356
  try {
21352
- const here = dirname18(fileURLToPath2(import.meta.url));
21353
- const raw = readFileSync38(join48(here, "..", "package.json"), "utf-8");
21357
+ const here = dirname19(fileURLToPath2(import.meta.url));
21358
+ const raw = readFileSync38(join49(here, "..", "package.json"), "utf-8");
21354
21359
  return JSON.parse(raw).version || null;
21355
21360
  } catch {
21356
21361
  return null;
@@ -21363,23 +21368,23 @@ function planAutoUpdate(base, caps, ownVersion2, flag) {
21363
21368
  if (compareVersions(rel.version, ownVersion2) <= 0) return { update: false, reason: `already current (own ${ownVersion2} >= server ${rel.version})` };
21364
21369
  return { update: true, reason: `server ${rel.version} > own ${ownVersion2}`, url: tarballUrl(base), sha256: rel.sha256, from: ownVersion2, to: rel.version };
21365
21370
  }
21366
- function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
21371
+ function sweepStaleStaging(root = tmpdir3(), now = Date.now()) {
21367
21372
  const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
21368
21373
  const COLD_MS = 60 * 60 * 1e3;
21369
21374
  let removed = 0;
21370
21375
  let entries;
21371
21376
  try {
21372
- entries = readdirSync32(root);
21377
+ entries = readdirSync33(root);
21373
21378
  } catch {
21374
21379
  return 0;
21375
21380
  }
21376
21381
  for (const name of entries) {
21377
21382
  if (!MKDTEMP_SUFFIX.test(name)) continue;
21378
- const dir = join48(root, name);
21383
+ const dir = join49(root, name);
21379
21384
  try {
21380
- const st = statSync41(dir);
21385
+ const st = statSync42(dir);
21381
21386
  if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
21382
- const inside = readdirSync32(dir);
21387
+ const inside = readdirSync33(dir);
21383
21388
  if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
21384
21389
  rmSync5(dir, { recursive: true, force: true });
21385
21390
  removed++;
@@ -21396,16 +21401,16 @@ async function executeAutoUpdate(plan, deps) {
21396
21401
  } catch (e) {
21397
21402
  return { updated: false, reason: `download failed: ${e instanceof Error ? e.message : e}` };
21398
21403
  }
21399
- const got = createHash13("sha256").update(buf).digest("hex");
21404
+ const got = createHash14("sha256").update(buf).digest("hex");
21400
21405
  if (got !== plan.sha256) return { updated: false, reason: `checksum mismatch (expected ${plan.sha256.slice(0, 12)}\u2026, got ${got.slice(0, 12)}\u2026) \u2014 NOT installing` };
21401
- const dir = mkdtempSync3(join48(tmpdir2(), "cr-update-"));
21406
+ const dir = mkdtempSync3(join49(tmpdir3(), "cr-update-"));
21402
21407
  const discardStaging = () => {
21403
21408
  try {
21404
21409
  rmSync5(dir, { recursive: true, force: true });
21405
21410
  } catch {
21406
21411
  }
21407
21412
  };
21408
- const tgz = join48(dir, "chat-recall.tgz");
21413
+ const tgz = join49(dir, "chat-recall.tgz");
21409
21414
  writeFileSync9(tgz, buf);
21410
21415
  try {
21411
21416
  deps.install(tgz);
@@ -21533,10 +21538,10 @@ __export(sync_client_exports, {
21533
21538
  syncIncremental: () => syncIncremental,
21534
21539
  syncSessions: () => syncSessions
21535
21540
  });
21536
- import { join as join49, dirname as dirname19, basename as basename23 } from "node:path";
21537
- import { readFileSync as readFileSync39, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync5, unlinkSync as unlinkSync3, readdirSync as readdirSync33, statSync as statSync42 } from "node:fs";
21538
- import { tmpdir as tmpdir3, hostname as hostname2 } from "node:os";
21539
- import { createHash as createHash14 } from "node:crypto";
21541
+ import { join as join50, dirname as dirname20, basename as basename23 } from "node:path";
21542
+ import { readFileSync as readFileSync39, writeFileSync as writeFileSync10, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync6, unlinkSync as unlinkSync3, readdirSync as readdirSync34, statSync as statSync43 } from "node:fs";
21543
+ import { tmpdir as tmpdir4, hostname as hostname2 } from "node:os";
21544
+ import { createHash as createHash15 } from "node:crypto";
21540
21545
  import { fileURLToPath as fileURLToPath3 } from "node:url";
21541
21546
  import { gzipSync as gzipSync3 } from "zlib";
21542
21547
  function classedError(errorClass, message) {
@@ -21569,12 +21574,12 @@ function classifyError(msg, err) {
21569
21574
  }
21570
21575
  function saveCredentials(c) {
21571
21576
  assertTransportSafe(c.serverUrl);
21572
- mkdirSync11(dirname19(credPath()), { recursive: true });
21577
+ mkdirSync12(dirname20(credPath()), { recursive: true });
21573
21578
  const targets = loadAllCredentials().filter((t) => t.serverUrl !== c.serverUrl);
21574
21579
  targets.unshift(c);
21575
21580
  writeFileSync10(credPath(), JSON.stringify({ targets }, null, 2));
21576
21581
  try {
21577
- chmodSync5(credPath(), 384);
21582
+ chmodSync6(credPath(), 384);
21578
21583
  } catch {
21579
21584
  }
21580
21585
  try {
@@ -21651,7 +21656,7 @@ function _resetTenantSecurityConfigCache() {
21651
21656
  _securityConfigCache.clear();
21652
21657
  }
21653
21658
  function syncConfigCachePath() {
21654
- return join49(getDataDir(), "sync-config-cache.json");
21659
+ return join50(getDataDir(), "sync-config-cache.json");
21655
21660
  }
21656
21661
  function readPersistedSyncConfigs() {
21657
21662
  try {
@@ -21664,7 +21669,7 @@ function persistSyncConfig(base, config2) {
21664
21669
  try {
21665
21670
  const all = readPersistedSyncConfigs();
21666
21671
  all[base] = { fetchedAt: Date.now(), config: config2 };
21667
- mkdirSync11(dirname19(syncConfigCachePath()), { recursive: true });
21672
+ mkdirSync12(dirname20(syncConfigCachePath()), { recursive: true });
21668
21673
  writeFileSync10(syncConfigCachePath(), JSON.stringify(all, null, 2));
21669
21674
  } catch {
21670
21675
  }
@@ -21929,19 +21934,19 @@ async function reconcileFields(opts = {}) {
21929
21934
  }
21930
21935
  return { sessions: fullRefs().length, scanned, pushed, absent, perTarget };
21931
21936
  }
21932
- function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now()) {
21937
+ function reapStaleScanDirs(dir = tmpdir4(), maxAgeMs = 6 * 36e5, now = Date.now()) {
21933
21938
  let reaped = 0;
21934
21939
  let names;
21935
21940
  try {
21936
- names = readdirSync33(dir);
21941
+ names = readdirSync34(dir);
21937
21942
  } catch {
21938
21943
  return 0;
21939
21944
  }
21940
21945
  for (const name of names) {
21941
21946
  if (!name.startsWith("cr-batchscan-")) continue;
21942
- const p = join49(dir, name);
21947
+ const p = join50(dir, name);
21943
21948
  try {
21944
- if (now - statSync42(p).mtimeMs < maxAgeMs) continue;
21949
+ if (now - statSync43(p).mtimeMs < maxAgeMs) continue;
21945
21950
  rmSync6(p, { recursive: true, force: true });
21946
21951
  reaped++;
21947
21952
  } catch {
@@ -21956,7 +21961,7 @@ function batchScanExternal(items, opts = {}) {
21956
21961
  let scanned = 0, slices = 0, scanMs = 0;
21957
21962
  if (items.length === 0) return { findings, scanned, slices, scanMs };
21958
21963
  reapStaleScanDirs();
21959
- let scanDir = mkdtempSync4(join49(tmpdir3(), "cr-batchscan-"));
21964
+ let scanDir = mkdtempSync4(join50(tmpdir4(), "cr-batchscan-"));
21960
21965
  let safeToId = /* @__PURE__ */ new Map();
21961
21966
  let bytesInDir = 0;
21962
21967
  const flushSlice = () => {
@@ -21987,13 +21992,13 @@ function batchScanExternal(items, opts = {}) {
21987
21992
  if (raw === null) continue;
21988
21993
  const safe = item.id.replace(/[^A-Za-z0-9_-]/g, "");
21989
21994
  safeToId.set(safe, item.id);
21990
- writeFileSync10(join49(scanDir, `${safe}.txt`), raw);
21995
+ writeFileSync10(join50(scanDir, `${safe}.txt`), raw);
21991
21996
  bytesInDir += Buffer.byteLength(raw);
21992
21997
  } catch {
21993
21998
  }
21994
21999
  if (bytesInDir >= maxBytes) {
21995
22000
  flushSlice();
21996
- scanDir = mkdtempSync4(join49(tmpdir3(), "cr-batchscan-"));
22001
+ scanDir = mkdtempSync4(join50(tmpdir4(), "cr-batchscan-"));
21997
22002
  }
21998
22003
  }
21999
22004
  flushSlice();
@@ -22316,7 +22321,7 @@ async function syncToTargetInScope(cred, opts = {}) {
22316
22321
  const kgSeen = /* @__PURE__ */ new Set();
22317
22322
  const kgEntityType = /* @__PURE__ */ new Map();
22318
22323
  const kgEntityNames = /* @__PURE__ */ new Set();
22319
- const kgKey = (subject, predicate, object, validFrom) => createHash14("sha1").update(`${subject}|${predicate}|${object}|${validFrom}`).digest("hex").slice(0, 16);
22324
+ const kgKey = (subject, predicate, object, validFrom) => createHash15("sha1").update(`${subject}|${predicate}|${object}|${validFrom}`).digest("hex").slice(0, 16);
22320
22325
  const accumulateKg = async (triples, sourceSession) => {
22321
22326
  for (const t of triples) {
22322
22327
  const key2 = kgKey(t.subject, t.predicate, t.object, t.validFrom ?? "");
@@ -22839,7 +22844,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
22839
22844
  } else if (opts.scanSecrets) {
22840
22845
  let tmp = null;
22841
22846
  try {
22842
- tmp = join49(tmpdir3(), `cr-scan-${ref.prefixedId.replace(/[^A-Za-z0-9_-]/g, "")}-${mtime}.txt`);
22847
+ tmp = join50(tmpdir4(), `cr-scan-${ref.prefixedId.replace(/[^A-Za-z0-9_-]/g, "")}-${mtime}.txt`);
22843
22848
  writeFileSync10(tmp, rawText);
22844
22849
  for (const f of scanFileForSecrets(tmp, { verifyOnly: opts.verifySecrets, tenantRules: opts.tenantRules })) {
22845
22850
  const verifiedAt = f.verified ? (/* @__PURE__ */ new Date()).toISOString() : null;
@@ -23067,11 +23072,11 @@ var init_sync_client = __esm({
23067
23072
  init_backends();
23068
23073
  ownVersion = "0.0.0";
23069
23074
  try {
23070
- const dir = dirname19(fileURLToPath3(import.meta.url));
23071
- ownVersion = JSON.parse(readFileSync39(join49(dir, "../package.json"), "utf-8")).version || ownVersion;
23075
+ const dir = dirname20(fileURLToPath3(import.meta.url));
23076
+ ownVersion = JSON.parse(readFileSync39(join50(dir, "../package.json"), "utf-8")).version || ownVersion;
23072
23077
  } catch {
23073
23078
  try {
23074
- if (true) ownVersion = "0.5.31";
23079
+ if (true) ownVersion = "0.6.0";
23075
23080
  } catch {
23076
23081
  }
23077
23082
  }
@@ -23083,14 +23088,14 @@ var init_sync_client = __esm({
23083
23088
  ]);
23084
23089
  walkProgressForUpload = null;
23085
23090
  lastServerPackSpec = null;
23086
- credPath = () => join49(getDataDir(), "credentials.json");
23091
+ credPath = () => join50(getDataDir(), "credentials.json");
23087
23092
  _securityConfigCache = /* @__PURE__ */ new Map();
23088
23093
  SECURITY_CONFIG_TTL_MS = 5 * 60 * 1e3;
23089
23094
  _syncConfigCache = /* @__PURE__ */ new Map();
23090
23095
  EMPTY_SYNC_CONFIG = { excludeTools: [], excludeProjects: [], excludeSources: [], approveSources: [] };
23091
23096
  _fetchTenantSyncConfigForTests = fetchTenantSyncConfig;
23092
23097
  SYNC_RULES_REFUSAL = /* @__PURE__ */ Symbol.for("chat-recall.syncRulesRefusal");
23093
- hashPath = (p) => p ? "p_" + createHash14("sha256").update(p).digest("hex").slice(0, 12) : "";
23098
+ hashPath = (p) => p ? "p_" + createHash15("sha256").update(p).digest("hex").slice(0, 12) : "";
23094
23099
  MAX_DERIVED_ROW_BYTES = 2 * 1024 * 1024;
23095
23100
  isLocalHost = isPrivateHost;
23096
23101
  CAPS_TTL_MS = 60 * 6e4;
@@ -23171,12 +23176,17 @@ var init_client_events = __esm({
23171
23176
  // src/update-notice.ts
23172
23177
  var update_notice_exports = {};
23173
23178
  __export(update_notice_exports, {
23179
+ newestKnown: () => newestKnown,
23174
23180
  printUpdateNotice: () => printUpdateNotice,
23175
23181
  refreshUpdateCheck: () => refreshUpdateCheck,
23176
23182
  updateNotice: () => updateNotice2
23177
23183
  });
23178
23184
  import { readFileSync as readFileSync41, writeFileSync as writeFileSync11 } from "node:fs";
23179
- import { join as join50 } from "node:path";
23185
+ import { join as join51 } from "node:path";
23186
+ function newestKnown(c) {
23187
+ const npm = c.npmVersion ?? "0.0.0";
23188
+ return compareVersions(npm, c.serverVersion) > 0 ? { version: npm, source: "npm" } : { version: c.serverVersion, source: "server" };
23189
+ }
23180
23190
  function readCheck() {
23181
23191
  try {
23182
23192
  const c = JSON.parse(readFileSync41(checkPath(), "utf-8"));
@@ -23195,8 +23205,24 @@ function updateNotice2() {
23195
23205
  const c = readCheck();
23196
23206
  if (!c) return null;
23197
23207
  const own = cliVersion();
23198
- if (compareVersions(c.serverVersion, own) <= 0) return null;
23199
- return `chat-recall ${c.serverVersion} is available (you have ${own}). Auto-update should apply it; force it now with: chat-recall update`;
23208
+ const { version: version2, source } = newestKnown(c);
23209
+ if (compareVersions(version2, own) <= 0) return null;
23210
+ const how = source === "npm" ? "The server you sync to has not rolled it yet \u2014 install it with: npm install -g chat-recall@latest" : "Auto-update should apply it; force it now with: chat-recall update";
23211
+ return `chat-recall ${version2} is available (you have ${own}). ${how}`;
23212
+ }
23213
+ async function fetchNpmLatest() {
23214
+ if (process.env.CHAT_RECALL_NO_NPM_CHECK === "1") return null;
23215
+ try {
23216
+ const res = await fetchWithTimeout(NPM_LATEST_URL, {
23217
+ headers: { accept: "application/vnd.npm.install-v1+json" }
23218
+ }, 5e3);
23219
+ if (!res.ok) return null;
23220
+ const body = await res.json();
23221
+ const v = body["dist-tags"]?.latest;
23222
+ return typeof v === "string" && v ? v : null;
23223
+ } catch {
23224
+ return null;
23225
+ }
23200
23226
  }
23201
23227
  async function refreshUpdateCheck(force = false) {
23202
23228
  const prev = readCheck();
@@ -23221,8 +23247,14 @@ async function refreshUpdateCheck(force = false) {
23221
23247
  } catch {
23222
23248
  return prev;
23223
23249
  }
23224
- if (newest === "0.0.0") return prev;
23225
- const next = { serverVersion: newest, checkedAt: Date.now() };
23250
+ const npmVersion = await fetchNpmLatest();
23251
+ if (newest === "0.0.0" && !npmVersion) return prev;
23252
+ const next = {
23253
+ // A server that answered nothing must not erase what we last knew from one.
23254
+ serverVersion: newest !== "0.0.0" ? newest : prev?.serverVersion ?? "0.0.0",
23255
+ checkedAt: Date.now()
23256
+ };
23257
+ if (npmVersion) next.npmVersion = npmVersion;
23226
23258
  writeCheck(next);
23227
23259
  return next;
23228
23260
  }
@@ -23242,7 +23274,7 @@ function printUpdateNotice() {
23242
23274
  } catch {
23243
23275
  }
23244
23276
  }
23245
- var CHECK_TTL_MS, checkPath, printed;
23277
+ var CHECK_TTL_MS, NPM_LATEST_URL, checkPath, printed;
23246
23278
  var init_update_notice = __esm({
23247
23279
  "src/update-notice.ts"() {
23248
23280
  "use strict";
@@ -23250,7 +23282,8 @@ var init_update_notice = __esm({
23250
23282
  init_auto_update();
23251
23283
  init_http();
23252
23284
  CHECK_TTL_MS = 6 * 3600 * 1e3;
23253
- checkPath = () => join50(getDataDir(), "update-check.json");
23285
+ NPM_LATEST_URL = "https://registry.npmjs.org/chat-recall";
23286
+ checkPath = () => join51(getDataDir(), "update-check.json");
23254
23287
  printed = false;
23255
23288
  }
23256
23289
  });
@@ -23266,11 +23299,11 @@ __export(install_skills_exports, {
23266
23299
  skillsSourceDir: () => skillsSourceDir,
23267
23300
  uninstallSkills: () => uninstallSkills
23268
23301
  });
23269
- import { readdirSync as readdirSync34, existsSync as existsSync47, mkdirSync as mkdirSync12, rmSync as rmSync7, cpSync, writeFileSync as writeFileSync12, readFileSync as readFileSync42, statSync as statSync43, realpathSync as realpathSync4 } from "fs";
23270
- import { createHash as createHash15 } from "crypto";
23271
- import { join as join51, basename as basename24 } from "path";
23302
+ import { readdirSync as readdirSync35, existsSync as existsSync47, mkdirSync as mkdirSync13, rmSync as rmSync7, cpSync, writeFileSync as writeFileSync12, readFileSync as readFileSync42, statSync as statSync44, realpathSync as realpathSync4 } from "fs";
23303
+ import { createHash as createHash16 } from "crypto";
23304
+ import { join as join52, basename as basename24 } from "path";
23272
23305
  function skillsSourceDir() {
23273
- return join51(import.meta.dirname, "..", "skills");
23306
+ return join52(import.meta.dirname, "..", "skills");
23274
23307
  }
23275
23308
  function version() {
23276
23309
  try {
@@ -23281,21 +23314,21 @@ function version() {
23281
23314
  }
23282
23315
  function skillsFingerprint() {
23283
23316
  const src = skillsSourceDir();
23284
- const h = createHash15("sha256");
23317
+ const h = createHash16("sha256");
23285
23318
  for (const name of bundledSkillNames()) {
23286
- for (const rel of filesUnder(join51(src, name)).sort()) {
23319
+ for (const rel of filesUnder(join52(src, name)).sort()) {
23287
23320
  h.update(name + "/" + rel);
23288
- h.update(readFileSync42(join51(src, name, rel)));
23321
+ h.update(readFileSync42(join52(src, name, rel)));
23289
23322
  }
23290
23323
  }
23291
23324
  return h.digest("hex").slice(0, 12);
23292
23325
  }
23293
23326
  function filesUnder(dir, prefix = "") {
23294
23327
  const out = [];
23295
- for (const e of readdirSync34(dir, { withFileTypes: true })) {
23328
+ for (const e of readdirSync35(dir, { withFileTypes: true })) {
23296
23329
  if (e.name === MARKER) continue;
23297
23330
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
23298
- if (e.isDirectory()) out.push(...filesUnder(join51(dir, e.name), rel));
23331
+ if (e.isDirectory()) out.push(...filesUnder(join52(dir, e.name), rel));
23299
23332
  else out.push(rel);
23300
23333
  }
23301
23334
  return out;
@@ -23306,7 +23339,7 @@ function skillStamp() {
23306
23339
  function bundledSkillNames() {
23307
23340
  const src = skillsSourceDir();
23308
23341
  if (!existsSync47(src)) return [];
23309
- return readdirSync34(src, { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync47(join51(src, e.name, "SKILL.md"))).map((e) => e.name).sort();
23342
+ return readdirSync35(src, { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync47(join52(src, e.name, "SKILL.md"))).map((e) => e.name).sort();
23310
23343
  }
23311
23344
  function realPathOrSelf(p) {
23312
23345
  try {
@@ -23319,7 +23352,7 @@ function claudeSkillTargets() {
23319
23352
  const targets = [];
23320
23353
  const seen = /* @__PURE__ */ new Set();
23321
23354
  for (const home of claudeHomeDirs()) {
23322
- const dir = join51(home, "skills");
23355
+ const dir = join52(home, "skills");
23323
23356
  const key2 = realPathOrSelf(dir);
23324
23357
  if (seen.has(key2)) continue;
23325
23358
  seen.add(key2);
@@ -23330,7 +23363,7 @@ function claudeSkillTargets() {
23330
23363
  dir,
23331
23364
  // Judge each profile on ITS OWN transcripts, not the primary's: a home
23332
23365
  // with no projects/ is a directory someone made, not a Claude install.
23333
- available: existsSync47(join51(home, "projects"))
23366
+ available: existsSync47(join52(home, "projects"))
23334
23367
  });
23335
23368
  }
23336
23369
  if (targets.length === 0) {
@@ -23352,11 +23385,11 @@ function skillTargets() {
23352
23385
  { id: "opencode", label: "OpenCode", dir: opencodeBackend.skillsDir(), available: opencodeBackend.isAvailable() },
23353
23386
  // Cursor DOES have its own dir (~/.cursor/skills). `skills-cursor` next to
23354
23387
  // it is Cursor's bundled set — read-only, never an install target.
23355
- { id: "cursor", label: "Cursor", dir: join51(cursorHomeDir(), "skills"), available: cursorBackend.isAvailable() }
23388
+ { id: "cursor", label: "Cursor", dir: join52(cursorHomeDir(), "skills"), available: cursorBackend.isAvailable() }
23356
23389
  ];
23357
23390
  }
23358
23391
  function isManaged(dir) {
23359
- return existsSync47(join51(dir, MARKER));
23392
+ return existsSync47(join52(dir, MARKER));
23360
23393
  }
23361
23394
  function installSkills(opts = {}) {
23362
23395
  const onlyAvailable = opts.onlyAvailable ?? true;
@@ -23373,15 +23406,15 @@ function installSkills(opts = {}) {
23373
23406
  continue;
23374
23407
  }
23375
23408
  for (const name of names) {
23376
- const dest = join51(t.dir, name);
23409
+ const dest = join52(t.dir, name);
23377
23410
  if (existsSync47(dest) && !isManaged(dest)) {
23378
23411
  skippedUserOwned.push(name);
23379
23412
  continue;
23380
23413
  }
23381
- mkdirSync12(t.dir, { recursive: true });
23414
+ mkdirSync13(t.dir, { recursive: true });
23382
23415
  rmSync7(dest, { recursive: true, force: true });
23383
- cpSync(join51(src, name), dest, { recursive: true });
23384
- writeFileSync12(join51(dest, MARKER), `${stamp}
23416
+ cpSync(join52(src, name), dest, { recursive: true });
23417
+ writeFileSync12(join52(dest, MARKER), `${stamp}
23385
23418
  `);
23386
23419
  installed.push(name);
23387
23420
  }
@@ -23398,9 +23431,9 @@ function uninstallSkills() {
23398
23431
  perTarget.push({ id: t.id, label: t.label, removed });
23399
23432
  continue;
23400
23433
  }
23401
- for (const entry of readdirSync34(t.dir, { withFileTypes: true })) {
23434
+ for (const entry of readdirSync35(t.dir, { withFileTypes: true })) {
23402
23435
  if (!entry.isDirectory()) continue;
23403
- const dir = join51(t.dir, entry.name);
23436
+ const dir = join52(t.dir, entry.name);
23404
23437
  if (isManaged(dir) && (names.has(entry.name) || entry.name.startsWith("chat-recall"))) {
23405
23438
  rmSync7(dir, { recursive: true, force: true });
23406
23439
  removed.push(entry.name);
@@ -23417,7 +23450,7 @@ function skillsNeedRefresh() {
23417
23450
  for (const t of skillTargets()) {
23418
23451
  if (!t.available) continue;
23419
23452
  for (const name of names) {
23420
- const marker = join51(t.dir, name, MARKER);
23453
+ const marker = join52(t.dir, name, MARKER);
23421
23454
  if (!existsSync47(marker)) return true;
23422
23455
  try {
23423
23456
  if (readFileSync42(marker, "utf-8").trim() !== cur) return true;
@@ -23435,7 +23468,7 @@ function skillStatus() {
23435
23468
  let installed = 0;
23436
23469
  let ver = null;
23437
23470
  for (const name of names) {
23438
- const marker = join51(t.dir, name, MARKER);
23471
+ const marker = join52(t.dir, name, MARKER);
23439
23472
  if (existsSync47(marker)) {
23440
23473
  installed++;
23441
23474
  try {
@@ -23476,15 +23509,15 @@ __export(service_installer_exports, {
23476
23509
  uninstallService: () => uninstallService
23477
23510
  });
23478
23511
  import { execSync as execSync5 } from "child_process";
23479
- import { existsSync as existsSync48, mkdirSync as mkdirSync13, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
23512
+ import { existsSync as existsSync48, mkdirSync as mkdirSync14, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
23480
23513
  import { homedir as homedir17 } from "os";
23481
- import { join as join52 } from "path";
23514
+ import { join as join53 } from "path";
23482
23515
  import { fileURLToPath as fileURLToPath4 } from "url";
23483
23516
  function resolveDaemonPaths() {
23484
23517
  const watchJs = fileURLToPath4(new URL("./watch.js", import.meta.url));
23485
23518
  const node = process.execPath;
23486
- const dataDir = join52(homedir17(), ".chat-recall");
23487
- const logFile = join52(dataDir, "watch.log");
23519
+ const dataDir = join53(homedir17(), ".chat-recall");
23520
+ const logFile = join53(dataDir, "watch.log");
23488
23521
  return { watchJs, node, logFile, dataDir };
23489
23522
  }
23490
23523
  function tryCmd(cmd) {
@@ -23509,7 +23542,7 @@ function isServiceRunning() {
23509
23542
  }
23510
23543
  function installService() {
23511
23544
  const { watchJs, node, logFile, dataDir } = resolveDaemonPaths();
23512
- mkdirSync13(dataDir, { recursive: true });
23545
+ mkdirSync14(dataDir, { recursive: true });
23513
23546
  if (process.platform === "linux") {
23514
23547
  return installSystemd(watchJs, node, logFile);
23515
23548
  }
@@ -23525,10 +23558,10 @@ function installService() {
23525
23558
  );
23526
23559
  }
23527
23560
  function installSystemd(watchJs, node, logFile) {
23528
- const unitDir = join52(homedir17(), ".config", "systemd", "user");
23529
- const unitPath = join52(unitDir, "chat-recall-watch.service");
23561
+ const unitDir = join53(homedir17(), ".config", "systemd", "user");
23562
+ const unitPath = join53(unitDir, "chat-recall-watch.service");
23530
23563
  const unit = renderSystemdUnit(watchJs, node, logFile);
23531
- mkdirSync13(unitDir, { recursive: true });
23564
+ mkdirSync14(unitDir, { recursive: true });
23532
23565
  writeFileSync13(unitPath, unit);
23533
23566
  try {
23534
23567
  execSync5("systemctl --user daemon-reload && systemctl --user enable chat-recall-watch.service && systemctl --user restart chat-recall-watch.service", { stdio: "inherit" });
@@ -23573,10 +23606,10 @@ function renderSystemdUnit(watchJs, node, logFile) {
23573
23606
  }
23574
23607
  function installLaunchd(watchJs, node, logFile) {
23575
23608
  const label = "com.chat-recall.watch";
23576
- const plistDir = join52(homedir17(), "Library", "LaunchAgents");
23577
- const plistPath = join52(plistDir, `${label}.plist`);
23609
+ const plistDir = join53(homedir17(), "Library", "LaunchAgents");
23610
+ const plistPath = join53(plistDir, `${label}.plist`);
23578
23611
  const plist = renderLaunchdPlist(watchJs, node, logFile, label);
23579
- mkdirSync13(plistDir, { recursive: true });
23612
+ mkdirSync14(plistDir, { recursive: true });
23580
23613
  writeFileSync13(plistPath, plist);
23581
23614
  try {
23582
23615
  try {
@@ -23630,7 +23663,7 @@ function uninstallService() {
23630
23663
  removed = true;
23631
23664
  } catch {
23632
23665
  }
23633
- const unitPath = join52(homedir17(), ".config", "systemd", "user", "chat-recall-watch.service");
23666
+ const unitPath = join53(homedir17(), ".config", "systemd", "user", "chat-recall-watch.service");
23634
23667
  if (existsSync48(unitPath)) {
23635
23668
  rmSync8(unitPath, { force: true });
23636
23669
  removed = true;
@@ -23642,7 +23675,7 @@ function uninstallService() {
23642
23675
  return removed;
23643
23676
  }
23644
23677
  if (process.platform === "darwin") {
23645
- const plistPath = join52(homedir17(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
23678
+ const plistPath = join53(homedir17(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
23646
23679
  try {
23647
23680
  execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
23648
23681
  } catch {
@@ -23687,6 +23720,124 @@ var init_service_installer = __esm({
23687
23720
  // src/mcp.ts
23688
23721
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23689
23722
  import { spawn as spawn3 } from "child_process";
23723
+ import { createServer, connect } from "node:net";
23724
+ import { unlinkSync as unlinkSync4 } from "node:fs";
23725
+
23726
+ // src/mcp-socket.ts
23727
+ import { createHash } from "node:crypto";
23728
+ import { tmpdir } from "node:os";
23729
+ import { join } from "node:path";
23730
+ import { accessSync, chmodSync, constants, mkdirSync, statSync } from "node:fs";
23731
+ import { dirname } from "node:path";
23732
+ var MAX_PATH = 100;
23733
+ var fits = (dir) => dir.length + 1 + 16 + 5 <= MAX_PATH;
23734
+ function socketDirCandidates() {
23735
+ if (process.platform === "win32") {
23736
+ const out2 = [];
23737
+ if (process.env.LOCALAPPDATA) out2.push(join(process.env.LOCALAPPDATA, "chat-recall", "run"));
23738
+ if (process.env.TEMP) out2.push(join(process.env.TEMP, "chat-recall-run"));
23739
+ out2.push(join(tmpdir(), "chat-recall-run"));
23740
+ return out2;
23741
+ }
23742
+ const out = [];
23743
+ const xdg = process.env.XDG_RUNTIME_DIR;
23744
+ if (xdg && xdg.length > 0) {
23745
+ const p = join(xdg, "chat-recall");
23746
+ if (fits(p)) out.push(p);
23747
+ }
23748
+ const uid = typeof process.getuid === "function" ? process.getuid() : 0;
23749
+ const named = join(tmpdir(), `chat-recall-${uid}`);
23750
+ if (fits(named)) out.push(named);
23751
+ const last = `/tmp/chat-recall-${uid}`;
23752
+ if (!out.includes(last)) out.push(last);
23753
+ return out;
23754
+ }
23755
+ var MAX_MISSING_LEVELS = 8;
23756
+ function isDir(path) {
23757
+ try {
23758
+ return statSync(path).isDirectory();
23759
+ } catch {
23760
+ return false;
23761
+ }
23762
+ }
23763
+ function usableDir(dir) {
23764
+ if (!isDir(dir)) {
23765
+ const missing = [];
23766
+ let cur = dir;
23767
+ let base = false;
23768
+ while (missing.length < MAX_MISSING_LEVELS) {
23769
+ const parent = dirname(cur);
23770
+ if (parent === cur) break;
23771
+ missing.push(cur);
23772
+ if (isDir(parent)) {
23773
+ base = true;
23774
+ break;
23775
+ }
23776
+ cur = parent;
23777
+ }
23778
+ if (!base) return false;
23779
+ for (let i = missing.length - 1; i >= 0; i--) {
23780
+ try {
23781
+ mkdirSync(missing[i]);
23782
+ } catch {
23783
+ }
23784
+ if (!isDir(missing[i])) return false;
23785
+ }
23786
+ }
23787
+ try {
23788
+ accessSync(dir, constants.W_OK);
23789
+ return true;
23790
+ } catch {
23791
+ return false;
23792
+ }
23793
+ }
23794
+ function privateDir(dir) {
23795
+ if (process.platform === "win32") return true;
23796
+ try {
23797
+ chmodSync(dir, 448);
23798
+ return (statSync(dir).mode & 63) === 0;
23799
+ } catch {
23800
+ return false;
23801
+ }
23802
+ }
23803
+ function ensureSocketDir() {
23804
+ const candidates2 = socketDirCandidates();
23805
+ for (const dir of candidates2) {
23806
+ if (!usableDir(dir)) continue;
23807
+ if (!privateDir(dir)) continue;
23808
+ return dir;
23809
+ }
23810
+ throw new Error(`no private runtime directory for the MCP daemon (tried ${candidates2.join(", ")})`);
23811
+ }
23812
+ function restrictSocket(path) {
23813
+ if (process.platform === "win32") return;
23814
+ try {
23815
+ chmodSync(path, 384);
23816
+ } catch {
23817
+ }
23818
+ }
23819
+ function socketSlug(version2) {
23820
+ const key2 = [
23821
+ process.env.CHAT_RECALL_MCP_PROFILE ?? "",
23822
+ process.env.CHAT_RECALL_SERVER ?? "",
23823
+ version2
23824
+ ].join(" ");
23825
+ return createHash("sha256").update(key2).digest("hex").slice(0, 16);
23826
+ }
23827
+ function socketPath(dir, version2) {
23828
+ const slug = socketSlug(version2);
23829
+ if (process.platform === "win32") return "\\\\.\\pipe\\chat-recall-" + slug;
23830
+ return join(dir, `${slug}.sock`);
23831
+ }
23832
+ var SOCKET_FLAG = "--socket";
23833
+ function socketPathFromArgv(argv) {
23834
+ const i = argv.indexOf(SOCKET_FLAG);
23835
+ if (i === -1) return void 0;
23836
+ const v = argv[i + 1];
23837
+ return v && !v.startsWith("--") ? v : void 0;
23838
+ }
23839
+
23840
+ // src/mcp.ts
23690
23841
  import { fileURLToPath as fileURLToPath5 } from "node:url";
23691
23842
 
23692
23843
  // ../engine/dist/mcp/tools.js
@@ -23827,8 +23978,8 @@ function isMultiTenant() {
23827
23978
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
23828
23979
  import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ListPromptsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
23829
23980
  import { z } from "zod";
23830
- import { existsSync as existsSync23, readFileSync as readFileSync18, statSync as statSync19 } from "fs";
23831
- import { join as join26 } from "path";
23981
+ import { existsSync as existsSync23, readFileSync as readFileSync18, statSync as statSync20 } from "fs";
23982
+ import { join as join27 } from "path";
23832
23983
 
23833
23984
  // ../engine/dist/core/context.js
23834
23985
  init_tool_backend();
@@ -23975,8 +24126,8 @@ function sanitizeQuery(query) {
23975
24126
 
23976
24127
  // ../engine/dist/core/write-ahead-log.js
23977
24128
  init_paths();
23978
- import { existsSync as existsSync18, mkdirSync as mkdirSync4, appendFileSync, openSync as openSync7, closeSync as closeSync7, chmodSync as chmodSync2 } from "fs";
23979
- import { join as join19 } from "path";
24129
+ import { existsSync as existsSync18, mkdirSync as mkdirSync5, appendFileSync, openSync as openSync7, closeSync as closeSync7, chmodSync as chmodSync3 } from "fs";
24130
+ import { join as join20 } from "path";
23980
24131
  var REDACT_KEYS = /* @__PURE__ */ new Set([
23981
24132
  "content",
23982
24133
  "text",
@@ -23993,13 +24144,13 @@ var WriteAheadLog = class {
23993
24144
  constructor(walDir) {
23994
24145
  const dir = walDir || getWalDir();
23995
24146
  if (!existsSync18(dir)) {
23996
- mkdirSync4(dir, { recursive: true });
24147
+ mkdirSync5(dir, { recursive: true });
23997
24148
  try {
23998
- chmodSync2(dir, 448);
24149
+ chmodSync3(dir, 448);
23999
24150
  } catch {
24000
24151
  }
24001
24152
  }
24002
- this.walPath = join19(dir, "write_log.jsonl");
24153
+ this.walPath = join20(dir, "write_log.jsonl");
24003
24154
  if (!existsSync18(this.walPath)) {
24004
24155
  const fd = openSync7(this.walPath, "w", 384);
24005
24156
  closeSync7(fd);
@@ -24189,7 +24340,7 @@ function remoteCredentials() {
24189
24340
  if (fromEnv)
24190
24341
  return { base: fromEnv.serverUrl, token: fromEnv.token };
24191
24342
  try {
24192
- const raw = readFileSync18(join26(getDataDir(), "credentials.json"), "utf-8");
24343
+ const raw = readFileSync18(join27(getDataDir(), "credentials.json"), "utf-8");
24193
24344
  const parsed = JSON.parse(raw);
24194
24345
  if (Array.isArray(parsed.targets) && parsed.targets.length) {
24195
24346
  const valid = parsed.targets.filter((t) => t?.serverUrl);
@@ -26889,7 +27040,7 @@ _Edits stayed local or window was off \u2014 try increasing buffer_minutes._` }]
26889
27040
  }
26890
27041
  case "recall_project_context": {
26891
27042
  const params = RecallProjectContextSchema.parse(args);
26892
- const target = existsSync23(params.project_path) && statSync19(params.project_path).isDirectory() ? resolveProjectId(params.project_path).id : params.project_path;
27043
+ const target = existsSync23(params.project_path) && statSync20(params.project_path).isDirectory() ? resolveProjectId(params.project_path).id : params.project_path;
26893
27044
  const dossier = await remoteGetQS(`/api/projects/${encodeURIComponent(target)}/dossier`, { sessions: params.limit, tasks: params.tasks, plans: params.plans });
26894
27045
  return { content: [{ type: "text", text: dossier.markdown }] };
26895
27046
  }
@@ -28526,10 +28677,112 @@ function installCrashGuards() {
28526
28677
  reportClientEvent2("mcp_crash", { message: err.stack || err.message });
28527
28678
  });
28528
28679
  }
28680
+ var RELAY_VERSION = true ? "0.6.0" : "0.0.0";
28681
+ function daemonIdleSecs() {
28682
+ const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
28683
+ if (raw === void 0) return 900;
28684
+ const n = Number.parseInt(raw.trim(), 10);
28685
+ return Number.isFinite(n) ? n : 900;
28686
+ }
28687
+ function addressIsLive(path) {
28688
+ return new Promise((resolve3) => {
28689
+ const probe = connect(path);
28690
+ probe.once("connect", () => {
28691
+ probe.destroy();
28692
+ resolve3(true);
28693
+ });
28694
+ probe.once("error", () => {
28695
+ probe.destroy();
28696
+ resolve3(false);
28697
+ });
28698
+ });
28699
+ }
28700
+ function listen(path) {
28701
+ return new Promise((resolve3) => {
28702
+ const server = createServer();
28703
+ server.once("error", async (err) => {
28704
+ if (err.code !== "EADDRINUSE") return resolve3(null);
28705
+ if (await addressIsLive(path)) return resolve3(null);
28706
+ try {
28707
+ unlinkSync4(path);
28708
+ } catch {
28709
+ }
28710
+ const retry = createServer();
28711
+ retry.once("error", () => resolve3(null));
28712
+ retry.listen(path, () => {
28713
+ restrictSocket(path);
28714
+ resolve3(retry);
28715
+ });
28716
+ });
28717
+ server.listen(path, () => {
28718
+ restrictSocket(path);
28719
+ resolve3(server);
28720
+ });
28721
+ });
28722
+ }
28723
+ async function runDaemon() {
28724
+ let path = socketPathFromArgv(process.argv);
28725
+ if (!path) {
28726
+ try {
28727
+ path = socketPath(ensureSocketDir(), RELAY_VERSION);
28728
+ } catch (err) {
28729
+ console.error(`[mcp] ${err.message}; sessions will run in-process`);
28730
+ return false;
28731
+ }
28732
+ }
28733
+ const server = await listen(path);
28734
+ if (!server) {
28735
+ return false;
28736
+ }
28737
+ let live = 0;
28738
+ let idleSince = Date.now();
28739
+ server.on("connection", (socket) => {
28740
+ live += 1;
28741
+ socket.on("close", () => {
28742
+ live -= 1;
28743
+ if (live === 0) idleSince = Date.now();
28744
+ });
28745
+ socket.on("error", () => {
28746
+ });
28747
+ void createMcpServer().connect(new StdioServerTransport(socket, socket)).catch((err) => console.error("[mcp] session failed to start:", err?.message ?? err));
28748
+ });
28749
+ console.error(`[mcp] daemon listening on ${path} (v${RELAY_VERSION})`);
28750
+ const idleSecs = daemonIdleSecs();
28751
+ if (idleSecs > 0) {
28752
+ const timer = setInterval(() => {
28753
+ if (live > 0) return;
28754
+ if (Date.now() - idleSince < idleSecs * 1e3) return;
28755
+ clearInterval(timer);
28756
+ server.close(() => {
28757
+ try {
28758
+ if (process.platform !== "win32") unlinkSync4(path);
28759
+ } catch {
28760
+ }
28761
+ process.exit(0);
28762
+ });
28763
+ }, 5e3);
28764
+ timer.unref();
28765
+ }
28766
+ const shutdown = () => {
28767
+ try {
28768
+ server.close();
28769
+ if (process.platform !== "win32") unlinkSync4(path);
28770
+ } catch {
28771
+ }
28772
+ process.exit(0);
28773
+ };
28774
+ process.on("SIGTERM", shutdown);
28775
+ process.on("SIGINT", shutdown);
28776
+ return true;
28777
+ }
28529
28778
  async function main() {
28530
28779
  installCrashGuards();
28531
- const transport2 = new StdioServerTransport();
28532
- await createMcpServer().connect(transport2);
28780
+ if (process.argv.includes("--daemon")) {
28781
+ if (!await runDaemon()) return;
28782
+ } else {
28783
+ const transport2 = new StdioServerTransport();
28784
+ await createMcpServer().connect(transport2);
28785
+ }
28533
28786
  void (async () => {
28534
28787
  try {
28535
28788
  const m = await Promise.resolve().then(() => (init_install_skills(), install_skills_exports));