toyon 0.21.0 → 0.22.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.
Files changed (105) hide show
  1. package/README.md +2 -2
  2. package/dist/CHANGELOG.md +26 -0
  3. package/dist/bridge.js +1 -1
  4. package/dist/cli.js +2 -2
  5. package/dist/daemon.js +216 -72
  6. package/dist/shell/assets/{Editor-D_bxx8PL.js → Editor-1fCgxkUp.js} +177 -177
  7. package/dist/shell/assets/Editor-1fCgxkUp.js.br +0 -0
  8. package/dist/shell/assets/Editor-1fCgxkUp.js.gz +0 -0
  9. package/dist/shell/assets/{XTerm-DNFNsoHC.js → XTerm-B_hkTWne.js} +1 -1
  10. package/dist/shell/assets/XTerm-B_hkTWne.js.br +0 -0
  11. package/dist/shell/assets/XTerm-B_hkTWne.js.gz +0 -0
  12. package/dist/shell/assets/{cssMode-BxHmuU8y.js → cssMode-1LqDnQzX.js} +1 -1
  13. package/dist/shell/assets/cssMode-1LqDnQzX.js.br +0 -0
  14. package/dist/shell/assets/cssMode-1LqDnQzX.js.gz +0 -0
  15. package/dist/shell/assets/{freemarker2-Cx9ZoWdp.js → freemarker2-BJFDEJKJ.js} +1 -1
  16. package/dist/shell/assets/freemarker2-BJFDEJKJ.js.br +0 -0
  17. package/dist/shell/assets/freemarker2-BJFDEJKJ.js.gz +0 -0
  18. package/dist/shell/assets/{grammar-DlhzivAk.js → grammar-DVeERVO3.js} +1 -1
  19. package/dist/shell/assets/grammar-DVeERVO3.js.br +0 -0
  20. package/dist/shell/assets/grammar-DVeERVO3.js.gz +0 -0
  21. package/dist/shell/assets/{handlebars-D0MhpM71.js → handlebars-BGFLy2DH.js} +1 -1
  22. package/dist/shell/assets/handlebars-BGFLy2DH.js.br +0 -0
  23. package/dist/shell/assets/handlebars-BGFLy2DH.js.gz +0 -0
  24. package/dist/shell/assets/{html-Da9gyCH4.js → html-CPJflvc5.js} +1 -1
  25. package/dist/shell/assets/html-CPJflvc5.js.br +0 -0
  26. package/dist/shell/assets/html-CPJflvc5.js.gz +0 -0
  27. package/dist/shell/assets/{htmlMode-CGo3ddCJ.js → htmlMode-CjqzceBV.js} +1 -1
  28. package/dist/shell/assets/htmlMode-CjqzceBV.js.br +0 -0
  29. package/dist/shell/assets/htmlMode-CjqzceBV.js.gz +0 -0
  30. package/dist/shell/assets/index-DdrVWdNt.js +292 -0
  31. package/dist/shell/assets/index-DdrVWdNt.js.br +0 -0
  32. package/dist/shell/assets/index-DdrVWdNt.js.gz +0 -0
  33. package/dist/shell/assets/index-Dx-i3szQ.css +1 -0
  34. package/dist/shell/assets/index-Dx-i3szQ.css.br +0 -0
  35. package/dist/shell/assets/index-Dx-i3szQ.css.gz +0 -0
  36. package/dist/shell/assets/{javascript-BXQxakKJ.js → javascript-B4CelO-C.js} +1 -1
  37. package/dist/shell/assets/{jsonMode-DT4ON4ij.js → jsonMode-C2JxYuT6.js} +1 -1
  38. package/dist/shell/assets/jsonMode-C2JxYuT6.js.br +0 -0
  39. package/dist/shell/assets/jsonMode-C2JxYuT6.js.gz +0 -0
  40. package/dist/shell/assets/{liquid-Bm6Hq-FF.js → liquid-BfXRgBm_.js} +1 -1
  41. package/dist/shell/assets/liquid-BfXRgBm_.js.br +0 -0
  42. package/dist/shell/assets/liquid-BfXRgBm_.js.gz +0 -0
  43. package/dist/shell/assets/{lspLanguageFeatures-DWvAzXxS.js → lspLanguageFeatures-CAi6hRgs.js} +1 -1
  44. package/dist/shell/assets/lspLanguageFeatures-CAi6hRgs.js.br +0 -0
  45. package/dist/shell/assets/lspLanguageFeatures-CAi6hRgs.js.gz +0 -0
  46. package/dist/shell/assets/{mdx-DNcDUEs7.js → mdx-DeBYGdge.js} +1 -1
  47. package/dist/shell/assets/mdx-DeBYGdge.js.br +0 -0
  48. package/dist/shell/assets/mdx-DeBYGdge.js.gz +0 -0
  49. package/dist/shell/assets/{python-BgETNCIe.js → python-CFhHKm43.js} +1 -1
  50. package/dist/shell/assets/python-CFhHKm43.js.br +0 -0
  51. package/dist/shell/assets/python-CFhHKm43.js.gz +0 -0
  52. package/dist/shell/assets/{razor-Cf_D69YI.js → razor-C-gkU4Y9.js} +1 -1
  53. package/dist/shell/assets/razor-C-gkU4Y9.js.br +0 -0
  54. package/dist/shell/assets/razor-C-gkU4Y9.js.gz +0 -0
  55. package/dist/shell/assets/{tsMode-BQA_zU_Q.js → tsMode-8E7grKbo.js} +1 -1
  56. package/dist/shell/assets/tsMode-8E7grKbo.js.br +0 -0
  57. package/dist/shell/assets/tsMode-8E7grKbo.js.gz +0 -0
  58. package/dist/shell/assets/{xml-DrZtVQVT.js → xml-CBoTF2r1.js} +1 -1
  59. package/dist/shell/assets/xml-CBoTF2r1.js.br +0 -0
  60. package/dist/shell/assets/xml-CBoTF2r1.js.gz +0 -0
  61. package/dist/shell/assets/{yaml-CzR4Kx36.js → yaml-CyKxhzxl.js} +1 -1
  62. package/dist/shell/assets/yaml-CyKxhzxl.js.br +0 -0
  63. package/dist/shell/assets/yaml-CyKxhzxl.js.gz +0 -0
  64. package/dist/shell/index.html +2 -2
  65. package/package.json +1 -1
  66. package/dist/shell/assets/Editor-D_bxx8PL.js.br +0 -0
  67. package/dist/shell/assets/Editor-D_bxx8PL.js.gz +0 -0
  68. package/dist/shell/assets/XTerm-DNFNsoHC.js.br +0 -0
  69. package/dist/shell/assets/XTerm-DNFNsoHC.js.gz +0 -0
  70. package/dist/shell/assets/cssMode-BxHmuU8y.js.br +0 -0
  71. package/dist/shell/assets/cssMode-BxHmuU8y.js.gz +0 -0
  72. package/dist/shell/assets/freemarker2-Cx9ZoWdp.js.br +0 -0
  73. package/dist/shell/assets/freemarker2-Cx9ZoWdp.js.gz +0 -0
  74. package/dist/shell/assets/grammar-DlhzivAk.js.br +0 -0
  75. package/dist/shell/assets/grammar-DlhzivAk.js.gz +0 -0
  76. package/dist/shell/assets/handlebars-D0MhpM71.js.br +0 -0
  77. package/dist/shell/assets/handlebars-D0MhpM71.js.gz +0 -0
  78. package/dist/shell/assets/html-Da9gyCH4.js.br +0 -0
  79. package/dist/shell/assets/html-Da9gyCH4.js.gz +0 -0
  80. package/dist/shell/assets/htmlMode-CGo3ddCJ.js.br +0 -0
  81. package/dist/shell/assets/htmlMode-CGo3ddCJ.js.gz +0 -0
  82. package/dist/shell/assets/index-DJ0qL1Ze.css +0 -1
  83. package/dist/shell/assets/index-DJ0qL1Ze.css.br +0 -0
  84. package/dist/shell/assets/index-DJ0qL1Ze.css.gz +0 -0
  85. package/dist/shell/assets/index-DMDdU-hM.js +0 -288
  86. package/dist/shell/assets/index-DMDdU-hM.js.br +0 -0
  87. package/dist/shell/assets/index-DMDdU-hM.js.gz +0 -0
  88. package/dist/shell/assets/jsonMode-DT4ON4ij.js.br +0 -0
  89. package/dist/shell/assets/jsonMode-DT4ON4ij.js.gz +0 -0
  90. package/dist/shell/assets/liquid-Bm6Hq-FF.js.br +0 -0
  91. package/dist/shell/assets/liquid-Bm6Hq-FF.js.gz +0 -0
  92. package/dist/shell/assets/lspLanguageFeatures-DWvAzXxS.js.br +0 -0
  93. package/dist/shell/assets/lspLanguageFeatures-DWvAzXxS.js.gz +0 -0
  94. package/dist/shell/assets/mdx-DNcDUEs7.js.br +0 -0
  95. package/dist/shell/assets/mdx-DNcDUEs7.js.gz +0 -0
  96. package/dist/shell/assets/python-BgETNCIe.js.br +0 -0
  97. package/dist/shell/assets/python-BgETNCIe.js.gz +0 -0
  98. package/dist/shell/assets/razor-Cf_D69YI.js.br +0 -0
  99. package/dist/shell/assets/razor-Cf_D69YI.js.gz +0 -0
  100. package/dist/shell/assets/tsMode-BQA_zU_Q.js.br +0 -0
  101. package/dist/shell/assets/tsMode-BQA_zU_Q.js.gz +0 -0
  102. package/dist/shell/assets/xml-DrZtVQVT.js.br +0 -0
  103. package/dist/shell/assets/xml-DrZtVQVT.js.gz +0 -0
  104. package/dist/shell/assets/yaml-CzR4Kx36.js.br +0 -0
  105. package/dist/shell/assets/yaml-CzR4Kx36.js.gz +0 -0
package/dist/daemon.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // ../daemon/src/index.ts
3
- import { rmSync as rmSync9, writeFileSync as writeFileSync14 } from "fs";
3
+ import { rmSync as rmSync10, writeFileSync as writeFileSync14 } from "fs";
4
4
  import { homedir as homedir15 } from "os";
5
5
  import { dirname as dirname15, join as join36 } from "path";
6
6
  import { fileURLToPath } from "url";
@@ -6762,7 +6762,7 @@ ${text.slice(text.length - (CONTEXT_CHARS - HEAD_CHARS))}`;
6762
6762
  }
6763
6763
 
6764
6764
  // ../shared/src/protocol/limits.ts
6765
- var PROTOCOL_VERSION = 142;
6765
+ var PROTOCOL_VERSION = 143;
6766
6766
  var PAGE_ERROR_MAX_CHARS = 2000;
6767
6767
  var PAGE_TITLE_MAX_CHARS = 1000;
6768
6768
  var FILE_MAX_CHARS = 5000000;
@@ -7283,7 +7283,7 @@ var clientMsgSchema = discriminatedUnion("t", [
7283
7283
  value: string2().max(100)
7284
7284
  }),
7285
7285
  object({ t: literal("set-keep-awake"), mode: _enum(KEEP_AWAKE_MODES) }),
7286
- object({ t: literal("install-agent"), agent: id }),
7286
+ object({ t: literal("install-agent"), agent: id, anyway: boolean2().optional() }),
7287
7287
  object({
7288
7288
  t: literal("agent-auth"),
7289
7289
  worktreeId: id,
@@ -8393,7 +8393,8 @@ function viewerOf(path) {
8393
8393
  }
8394
8394
  var RENDERINGS = [
8395
8395
  [/\.(md|markdown)$/i, "markdown"],
8396
- [/\.html?$/i, "html"]
8396
+ [/\.html?$/i, "html"],
8397
+ [/\.svg$/i, "svg"]
8397
8398
  ];
8398
8399
  function renderedAs(path) {
8399
8400
  return RENDERINGS.find(([re]) => re.test(path))?.[1] ?? null;
@@ -8832,7 +8833,7 @@ async function turnRemoteOff(ts, daemonPort, file, was) {
8832
8833
  // ../daemon/package.json
8833
8834
  var package_default = {
8834
8835
  name: "@toyon/daemon",
8835
- version: "0.21.0",
8836
+ version: "0.22.0",
8836
8837
  private: true,
8837
8838
  type: "module",
8838
8839
  main: "src/index.ts",
@@ -13927,7 +13928,8 @@ function same(a, b) {
13927
13928
  }
13928
13929
 
13929
13930
  // ../daemon/src/agent/registry.ts
13930
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
13931
+ import { existsSync as existsSync10, lstatSync, mkdirSync as mkdirSync6, readFileSync as readFileSync8, rmSync as rmSync3, unlinkSync, writeFileSync as writeFileSync5 } from "fs";
13932
+ import { rm, symlink } from "fs/promises";
13931
13933
  import { homedir as homedir3 } from "os";
13932
13934
  import { dirname as dirname3, isAbsolute as isAbsolute2, join as join8, resolve as resolve3 } from "path";
13933
13935
 
@@ -14614,6 +14616,7 @@ function makePaths(home = process.env.TOYON_HOME ?? join5(homedir(), ".toyon"))
14614
14616
  cacheDir: join5(home, "cache.noindex"),
14615
14617
  themesDir: join5(home, "themes"),
14616
14618
  agentsDir: process.env.TOYON_AGENTS_DIR ?? join5(home, "agents"),
14619
+ agentsFrom: process.env.TOYON_AGENTS_FROM || null,
14617
14620
  agentsFile: join5(home, "agents.json"),
14618
14621
  scratchDir: join5(home, "scratch"),
14619
14622
  gitCredentialsFile: join5(home, "git-credentials")
@@ -14964,14 +14967,39 @@ function installErrorLine(stderr) {
14964
14967
  const lines = stderr.split(`
14965
14968
  `).map((l) => l.trim()).filter(Boolean);
14966
14969
  const first = lines.find((l) => l.startsWith("error:"))?.slice("error:".length).trim();
14967
- const line = first || lines.at(-1) || "no output";
14968
- if (UNTRUSTED_CA.test(line))
14969
- return `${line}. A certificate bun does not trust, usually a proxy's: set NODE_EXTRA_CA_CERTS to its file and restart Toyon`;
14970
- return line;
14970
+ return first || lines.at(-1) || "no output";
14971
+ }
14972
+ function explainInstallError(line) {
14973
+ if (UNTRUSTED_CA.test(line)) {
14974
+ return {
14975
+ text: `${line}. A certificate bun does not trust, usually a proxy's: set NODE_EXTRA_CA_CERTS to its file and restart Toyon`
14976
+ };
14977
+ }
14978
+ if (AGE_BLOCK.test(line)) {
14979
+ return {
14980
+ text: `${line}. bun's minimumReleaseAge rule in ~/.bunfig.toml holds this version back: wait it out, or install anyway to set the rule aside for this download`,
14981
+ held: true
14982
+ };
14983
+ }
14984
+ return { text: line };
14985
+ }
14986
+ function mirrorWithout(line) {
14987
+ const m = MIRROR_404.exec(line);
14988
+ return m?.[1] && m[1] !== PUBLIC_REGISTRY_HOST ? m[1] : null;
14971
14989
  }
14972
14990
  var UNTRUSTED_CA = /UNKNOWN_CERTIFICATE_VERIFICATION_ERROR|SELF_SIGNED_CERT|UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE/;
14973
- var bunInstall = async (dir) => {
14974
- const r = await run(process.execPath, ["install", "--no-progress", "--no-summary"], dir, { NO_COLOR: "1", FORCE_COLOR: "0" }, { timeoutMs: 30 * 60000 });
14991
+ var MIRROR_404 = /^GET https?:\/\/([^/\s]+)\/\S* - 404$/;
14992
+ var AGE_BLOCK = /blocked by minimum-release-age/;
14993
+ var PUBLIC_REGISTRY_HOST = "registry.npmjs.org";
14994
+ var PUBLIC_REGISTRY = `https://${PUBLIC_REGISTRY_HOST}/`;
14995
+ function publicRegistryRc(pkg) {
14996
+ const scope = pkg.startsWith("@") ? pkg.slice(0, pkg.indexOf("/")) : null;
14997
+ return `registry=${PUBLIC_REGISTRY}
14998
+ ${scope ? `${scope}:registry=${PUBLIC_REGISTRY}
14999
+ ` : ""}`;
15000
+ }
15001
+ var bunInstall = async (dir, _pkg, _version, opts = {}) => {
15002
+ const r = await run(process.execPath, ["install", "--no-progress", "--no-summary", ...opts.pastAge ? ["--minimum-release-age=0"] : []], dir, { NO_COLOR: "1", FORCE_COLOR: "0" }, { timeoutMs: 30 * 60000 });
14975
15003
  return { ok: r.ok, err: r.ok ? "" : installErrorLine(r.err) };
14976
15004
  };
14977
15005
  var RETRY_AFTER_MS = 30000;
@@ -14994,17 +15022,19 @@ class AgentRegistry {
14994
15022
  host;
14995
15023
  sandbox;
14996
15024
  now;
15025
+ borrowFrom;
14997
15026
  specs = new Map;
14998
15027
  installing = new Map;
14999
15028
  installErrors = new Map;
15000
15029
  failures = new Map;
15001
15030
  onChange = null;
15002
- constructor(specs, dir, installer = bunInstall, host = hostTraits(), sandbox = { problem: () => null }, now = Date.now) {
15031
+ constructor(specs, dir, installer = bunInstall, host = hostTraits(), sandbox = { problem: () => null }, now = Date.now, borrowFrom = null) {
15003
15032
  this.dir = dir;
15004
15033
  this.installer = installer;
15005
15034
  this.host = host;
15006
15035
  this.sandbox = sandbox;
15007
15036
  this.now = now;
15037
+ this.borrowFrom = borrowFrom;
15008
15038
  for (const s of specs)
15009
15039
  this.specs.set(s.id, s);
15010
15040
  }
@@ -15038,10 +15068,13 @@ class AgentRegistry {
15038
15068
  return null;
15039
15069
  }
15040
15070
  installed(spec) {
15071
+ return this.installedIn(this.dir, spec);
15072
+ }
15073
+ installedIn(base, spec) {
15041
15074
  const name = this.packageName(spec);
15042
15075
  if (!name || spec.run.kind === "command")
15043
15076
  return null;
15044
- const pkgDir = join8(this.dir, spec.id, "node_modules", name);
15077
+ const pkgDir = join8(base, spec.id, "node_modules", name);
15045
15078
  if (spec.run.kind === "npm-native") {
15046
15079
  const bin = join8(pkgDir, spec.run.bin);
15047
15080
  return existsSync10(bin) ? bin : null;
@@ -15078,10 +15111,13 @@ class AgentRegistry {
15078
15111
  if (this.installing.has(spec.id))
15079
15112
  return { reason: "installing" };
15080
15113
  const failed = this.installErrors.get(spec.id);
15081
- const missing = failed !== undefined ? failedReason(failed) : spec.onDemand ? "not installed" : "not installed yet";
15114
+ const missing = failed ? failedReason(failed.why) : spec.onDemand ? "not installed" : "not installed yet";
15082
15115
  if (boxed)
15083
- return { reason: failed !== undefined ? `${missing}; ${boxed}` : boxed };
15084
- return { reason: missing, install: failed !== undefined ? { failed } : "missing" };
15116
+ return { reason: failed ? `${missing}; ${boxed}` : boxed };
15117
+ return {
15118
+ reason: missing,
15119
+ install: failed ? { failed: failed.why, ...failed.held ? { held: true } : {} } : "missing"
15120
+ };
15085
15121
  }
15086
15122
  command(spec) {
15087
15123
  const why = this.unavailable(spec);
@@ -15099,7 +15135,7 @@ class AgentRegistry {
15099
15135
  return base;
15100
15136
  return confine(base, prepared.bounds, (spec.stateDirs ?? []).map((d) => resolve3(homedir3(), d)));
15101
15137
  }
15102
- install(id) {
15138
+ install(id, opts = {}) {
15103
15139
  const spec = this.specs.get(id);
15104
15140
  if (!spec)
15105
15141
  throw new UserError(`unknown agent "${id}"`);
@@ -15108,7 +15144,7 @@ class AgentRegistry {
15108
15144
  return Promise.resolve();
15109
15145
  const running = this.installing.get(id);
15110
15146
  if (running)
15111
- return running;
15147
+ return opts.anyway ? running.then(() => this.install(id, opts)) : running;
15112
15148
  if (this.installed(spec) && this.installedVersion(spec) === spec.run.version) {
15113
15149
  this.installErrors.delete(id);
15114
15150
  this.failures.delete(id);
@@ -15118,20 +15154,47 @@ class AgentRegistry {
15118
15154
  const dir = join8(this.dir, id);
15119
15155
  const p = (async () => {
15120
15156
  try {
15157
+ const borrowed = await this.borrow(spec, version);
15158
+ if (borrowed) {
15159
+ this.installErrors.delete(id);
15160
+ this.failures.delete(id);
15161
+ log.info("agents", `${id} ready, linked from ${borrowed}`);
15162
+ return;
15163
+ }
15164
+ disown(dir);
15121
15165
  mkdirSync6(dir, { recursive: true });
15122
15166
  writeFileSync5(join8(dir, "package.json"), `${JSON.stringify({ name: `toyon-agent-${id}`, private: true, dependencies: { [pkg]: version } }, null, 2)}
15123
15167
  `);
15124
15168
  log.info("agents", `installing ${pkg}@${version} for ${id}`);
15125
- const r = await this.installer(dir, pkg, version);
15169
+ const rc = join8(dir, ".npmrc");
15170
+ rmSync3(rc, { force: true });
15171
+ const fetch2 = () => this.installer(dir, pkg, version, { pastAge: opts.anyway === true });
15172
+ let r = await fetch2();
15173
+ let why = r.ok ? null : explainInstallError(r.err);
15174
+ const mirror = r.ok ? null : mirrorWithout(r.err);
15175
+ if (mirror) {
15176
+ log.info("agents", `${mirror} does not carry ${pkg}; fetching it from the public registry`);
15177
+ writeFileSync5(rc, publicRegistryRc(pkg));
15178
+ r = await fetch2();
15179
+ if (!r.ok) {
15180
+ rmSync3(rc, { force: true });
15181
+ const again = explainInstallError(r.err);
15182
+ why = {
15183
+ ...again,
15184
+ text: `${mirror} does not carry the package, and from the public registry: ${again.text}`
15185
+ };
15186
+ } else
15187
+ why = null;
15188
+ }
15126
15189
  if (r.ok && this.installed(spec)) {
15127
15190
  this.installErrors.delete(id);
15128
15191
  this.failures.delete(id);
15129
15192
  log.info("agents", `${id} ready`);
15130
15193
  return;
15131
15194
  }
15132
- this.fail(id, r.err || "no bin after install");
15195
+ this.fail(id, why?.text || "no bin after install", why?.held === true);
15133
15196
  } catch (e) {
15134
- this.fail(id, e instanceof Error ? e.message : String(e));
15197
+ this.fail(id, e instanceof Error ? e.message : String(e), false);
15135
15198
  }
15136
15199
  })().finally(() => {
15137
15200
  this.installing.delete(id);
@@ -15141,16 +15204,33 @@ class AgentRegistry {
15141
15204
  this.onChange?.();
15142
15205
  return p;
15143
15206
  }
15144
- fail(id, why) {
15145
- this.installErrors.set(id, why);
15207
+ async borrow(spec, version) {
15208
+ const from = this.borrowFrom;
15209
+ if (!from || resolve3(from) === resolve3(this.dir))
15210
+ return null;
15211
+ if (!this.installedIn(from, spec) || this.installedVersionIn(from, spec) !== version)
15212
+ return null;
15213
+ const src = join8(from, spec.id);
15214
+ const own = join8(this.dir, spec.id);
15215
+ disown(own);
15216
+ await rm(own, { recursive: true, force: true });
15217
+ mkdirSync6(this.dir, { recursive: true });
15218
+ await symlink(src, own);
15219
+ return src;
15220
+ }
15221
+ fail(id, why, held) {
15222
+ this.installErrors.set(id, { why, held });
15146
15223
  this.failures.set(id, { at: this.now(), retries: this.failures.get(id)?.retries ?? 0 });
15147
15224
  log.warn("agents", `${id}: ${failedReason(why)}`);
15148
15225
  }
15149
15226
  installedVersion(spec) {
15227
+ return this.installedVersionIn(this.dir, spec);
15228
+ }
15229
+ installedVersionIn(base, spec) {
15150
15230
  const name = this.packageName(spec);
15151
15231
  if (!name)
15152
15232
  return null;
15153
- const pkgJson = join8(this.dir, spec.id, "node_modules", name, "package.json");
15233
+ const pkgJson = join8(base, spec.id, "node_modules", name, "package.json");
15154
15234
  try {
15155
15235
  return JSON.parse(readFileSync8(pkgJson, "utf8")).version ?? null;
15156
15236
  } catch {
@@ -15188,7 +15268,7 @@ class AgentRegistry {
15188
15268
  id: spec.id,
15189
15269
  installed,
15190
15270
  pinned: spec.run.version,
15191
- ...failed !== undefined ? { error: failedReason(failed) } : {}
15271
+ ...failed ? { error: failedReason(failed.why), ...failed.held ? { held: true } : {} } : {}
15192
15272
  });
15193
15273
  }
15194
15274
  return out;
@@ -15273,9 +15353,13 @@ function managedSpecs(specs, managed) {
15273
15353
  const kept = managed.customAgents ? specs : specs.filter((s) => s.builtin);
15274
15354
  return managed.agents === null ? kept : kept.filter((s) => managed.agents?.includes(s.id));
15275
15355
  }
15276
- function loadAgentRegistry(agentsFile, agentsDir, sandbox, managed = MANAGED_DEFAULTS) {
15356
+ function loadAgentRegistry(agentsFile, agentsDir, sandbox, managed = MANAGED_DEFAULTS, agentsFrom = null) {
15277
15357
  const specs = managed.customAgents && existsSync10(agentsFile) ? parseAgentsFile(readFileSync8(agentsFile, "utf8"), BUILTIN_AGENTS) : BUILTIN_AGENTS;
15278
- return new AgentRegistry(managedSpecs(specs, managed), agentsDir, undefined, undefined, sandbox);
15358
+ return new AgentRegistry(managedSpecs(specs, managed), agentsDir, undefined, undefined, sandbox, undefined, agentsFrom);
15359
+ }
15360
+ function disown(dir) {
15361
+ if (lstatSync(dir, { throwIfNoEntry: false })?.isSymbolicLink())
15362
+ unlinkSync(dir);
15279
15363
  }
15280
15364
 
15281
15365
  // ../daemon/src/agent/acp/session.ts
@@ -17185,6 +17269,12 @@ var CLAUDE = {
17185
17269
  upstream: "The ACP draft for subagent sessions (agent-client-protocol#1992) is the real shape; the adapter " + "serves it behind the AIR `nativeSubagentSessions` capability only.",
17186
17270
  open: true
17187
17271
  },
17272
+ mcpServerIcon: {
17273
+ gap: "An MCP server's tool arrives under its wire name (`mcp__<server>__<tool>`) with the server repeated " + "as `_meta.claudeCode.mcpServer: { name, source }` and nothing of the server itself: not the `icons` " + "or `websiteUrl` the server sent at MCP initialize (spec 2025-11-25). The adapter forwards the SDK's " + "`mcpServer` whole; the SDK's `mcpServerStatus().serverInfo` is `{ name, version }`, so the icons " + "are dropped inside Claude Code, before the adapter sees them.",
17274
+ here: "agent-tools.ts mcpTool reads the server off the wire name and toolCall.ts draws the cube beside it; " + "the meta's `name` and `source` go unread. No flag.",
17275
+ upstream: "anthropics/claude-code#95558 (open, no maintainer reply; five earlier tickets closed by the stale " + "bot) asks the CLI and Desktop to render `serverInfo.icons`; the SDK host side, `serverInfo` and " + "the per-call `mcpServer` carrying `icons` and `websiteUrl` from the handshake, is toyon's comment " + "there. Then one adapter PR forwards them under the same meta key " + "(the fork can carry it meanwhile), and map.ts passes the icon that matches the theme to the row. " + "A second handshake from toyon or the adapter to fetch them is ruled out: it doubles every " + "connection, OAuth included, for a glyph.",
17276
+ open: true
17277
+ },
17188
17278
  rateLimitMeta: {
17189
17279
  gap: 'The account\'s rate-limit windows ride `usage_update._meta["_claude/rateLimit"]`, a private key.',
17190
17280
  here: "ratelimit.ts reads it. No flag: a key that moves is a parse that returns null.",
@@ -17611,6 +17701,12 @@ class AcpSession {
17611
17701
  this.clearReaper();
17612
17702
  await this.dropConn("restart");
17613
17703
  }
17704
+ async lapse(why) {
17705
+ this.clearReaper();
17706
+ this.cancelAsks("expired");
17707
+ this.stop();
17708
+ await this.dropConn(why);
17709
+ }
17614
17710
  setCommands(next) {
17615
17711
  if (sameCommands(this.commandList, next))
17616
17712
  return;
@@ -17622,7 +17718,7 @@ class AcpSession {
17622
17718
  return this.queue.length;
17623
17719
  }
17624
17720
  get unsettled() {
17625
- return this.queue.length > 0 || this.steered.length > 0 || this.refused !== null || this.asks.size > 0;
17721
+ return this.queue.length > 0 || this.steered.length > 0 || this.refused !== null;
17626
17722
  }
17627
17723
  get queueItems() {
17628
17724
  return this.waiting().map(queued);
@@ -20108,10 +20204,15 @@ class RuntimeRegistry {
20108
20204
  }
20109
20205
  busy(id) {
20110
20206
  const agent = this.agentFor(id);
20111
- if (agent && (agent.status !== "idle" || agent.unsettled))
20207
+ if (agent && (agent.status !== "idle" && agent.status !== "waiting" || agent.unsettled))
20112
20208
  return true;
20113
20209
  return this.holdCount(id) > 0;
20114
20210
  }
20211
+ async lapse(id, why) {
20212
+ const agent = this.agentFor(id);
20213
+ if (agent?.status === "waiting")
20214
+ await agent.lapse(why);
20215
+ }
20115
20216
  anyBusy() {
20116
20217
  for (const id of this.runtimes.keys())
20117
20218
  if (this.busy(id))
@@ -21357,7 +21458,7 @@ function transcriptsUnder(dir) {
21357
21458
  }
21358
21459
 
21359
21460
  // ../daemon/src/core/assets.ts
21360
- import { existsSync as existsSync17, readdirSync as readdirSync6, rmSync as rmSync3, statSync as statSync5 } from "fs";
21461
+ import { existsSync as existsSync17, readdirSync as readdirSync6, rmSync as rmSync4, statSync as statSync5 } from "fs";
21361
21462
  import { join as join15, resolve as resolve6 } from "path";
21362
21463
  function locateAssets(here, env = process.env) {
21363
21464
  const packaged = existsSync17(join15(here, "shell", "index.html"));
@@ -21395,7 +21496,7 @@ function pruneAssets(shellDist) {
21395
21496
  if (newest - f.mtime <= KEEP_MS)
21396
21497
  continue;
21397
21498
  try {
21398
- rmSync3(f.path, { recursive: true, force: true });
21499
+ rmSync4(f.path, { recursive: true, force: true });
21399
21500
  gone++;
21400
21501
  } catch {}
21401
21502
  }
@@ -21559,7 +21660,7 @@ class IdlePolicy {
21559
21660
  const signal = await (this.d.memory ?? memoryTight)();
21560
21661
  if (!signal?.tight)
21561
21662
  return;
21562
- const pick = this.d.state.worktrees.filter((w) => this.candidate(w.id)).sort((a, b) => this.entry(a.id).activeAt - this.entry(b.id).activeAt)[0];
21663
+ const pick = this.d.state.worktrees.filter((w) => this.candidate(w.id) && this.awakeProcs(w.id)).sort((a, b) => this.entry(a.id).activeAt - this.entry(b.id).activeAt)[0];
21563
21664
  if (!pick)
21564
21665
  return;
21565
21666
  log.info("idle", `${signal.why}; ${pick.id} is the least recently used`);
@@ -21607,11 +21708,14 @@ class IdlePolicy {
21607
21708
  const wt = this.d.state.worktree(id);
21608
21709
  if (!wt || this.isViewed(id) || this.busy(id))
21609
21710
  return false;
21711
+ const card = this.d.runtime.agentFor(id)?.status === "waiting";
21610
21712
  const procs = this.d.runtime.get(id)?.procs;
21611
21713
  if (!procs || procs.asleep)
21612
- return false;
21714
+ return card;
21613
21715
  const states = procs.states();
21614
- if (states.length === 0 || states.some((s) => s.status === "starting"))
21716
+ if (states.length === 0 && !card)
21717
+ return false;
21718
+ if (states.some((s) => s.status === "starting"))
21615
21719
  return false;
21616
21720
  if (wt.kind === "spare") {
21617
21721
  return !this.d.state.worktrees.some((w) => w.repoId === wt.repoId && w.id !== id && this.busy(w.id));
@@ -21627,6 +21731,10 @@ class IdlePolicy {
21627
21731
  busy(id) {
21628
21732
  return this.d.runtime.busy(id);
21629
21733
  }
21734
+ awakeProcs(id) {
21735
+ const procs = this.d.runtime.get(id)?.procs;
21736
+ return !!procs && !procs.asleep;
21737
+ }
21630
21738
  reconsider(id) {
21631
21739
  if (!this.candidate(id)) {
21632
21740
  this.disarm(id);
@@ -21672,6 +21780,7 @@ class IdlePolicy {
21672
21780
  this.arm(id, this.sleepMs - idle);
21673
21781
  return;
21674
21782
  }
21783
+ fireAndForget(id, this.d.runtime.lapse(id, `nobody answered for ${humanMs(this.sleepMs)}`), "lapse");
21675
21784
  this.sleep(id, `nobody looked for ${humanMs(this.sleepMs)}`);
21676
21785
  }
21677
21786
  sleep(id, why) {
@@ -22202,7 +22311,7 @@ class GrantCodes {
22202
22311
  // ../daemon/src/core/helper.ts
22203
22312
  import { createHash as createHash3 } from "crypto";
22204
22313
  import { existsSync as existsSync19 } from "fs";
22205
- import { chmod, copyFile as copyFile3, mkdir as mkdir2, readFile as readFile3, rm, writeFile as writeFile2 } from "fs/promises";
22314
+ import { chmod, copyFile as copyFile3, mkdir as mkdir2, readFile as readFile3, rm as rm2, writeFile as writeFile2 } from "fs/promises";
22206
22315
  import { basename as basename6, dirname as dirname7, join as join17 } from "path";
22207
22316
  var EXECUTABLE = "Toyon";
22208
22317
  function helperWanted(where) {
@@ -22320,7 +22429,7 @@ class Helper {
22320
22429
  }
22321
22430
  await this.run(["iconutil", "-c", "icns", set, "-o", join17(resources, "AppIcon.icns")]);
22322
22431
  }
22323
- await rm(tmp, { recursive: true, force: true });
22432
+ await rm2(tmp, { recursive: true, force: true });
22324
22433
  }
22325
22434
  }
22326
22435
 
@@ -24461,7 +24570,7 @@ function isFileAt(abs) {
24461
24570
 
24462
24571
  // ../daemon/src/repos/create.ts
24463
24572
  import { existsSync as existsSync24, realpathSync as realpathSync3, statSync as statSync8 } from "fs";
24464
- import { appendFile as appendFile2, mkdir as mkdir3, rm as rm2 } from "fs/promises";
24573
+ import { appendFile as appendFile2, mkdir as mkdir3, rm as rm3 } from "fs/promises";
24465
24574
  import { homedir as homedir9 } from "os";
24466
24575
  import { dirname as dirname9, join as join20, resolve as resolve8 } from "path";
24467
24576
  function isInside(dir, parent) {
@@ -24577,14 +24686,14 @@ function cloneError(stderr) {
24577
24686
  }
24578
24687
  async function undoCreate(dir) {
24579
24688
  try {
24580
- await rm2(dir, { recursive: true, force: true });
24689
+ await rm3(dir, { recursive: true, force: true });
24581
24690
  } catch (e) {
24582
24691
  log.warn(dir, "could not clean up a half-made project", e);
24583
24692
  }
24584
24693
  }
24585
24694
  async function undoInit(dir) {
24586
24695
  try {
24587
- await rm2(join20(dir, ".git"), { recursive: true, force: true });
24696
+ await rm3(join20(dir, ".git"), { recursive: true, force: true });
24588
24697
  } catch (e) {
24589
24698
  log.warn(dir, "could not take back a half-made .git", e);
24590
24699
  }
@@ -24592,7 +24701,7 @@ async function undoInit(dir) {
24592
24701
  async function unmakeProject(dir, made) {
24593
24702
  const target = made === "folder" ? dir : join20(dir, ".git");
24594
24703
  try {
24595
- await rm2(target, { recursive: true, force: true });
24704
+ await rm3(target, { recursive: true, force: true });
24596
24705
  } catch (e) {
24597
24706
  throw new UserError(`could not remove ${target}: ${e instanceof Error ? e.message : String(e)}`);
24598
24707
  }
@@ -24652,12 +24761,47 @@ function looksBinary(text) {
24652
24761
  import { spawn as spawn5 } from "child_process";
24653
24762
  import { stat as stat3, unlink } from "fs/promises";
24654
24763
 
24764
+ // ../daemon/src/git/forge.ts
24765
+ function githubRepoUrl(remoteUrl) {
24766
+ const m = remoteUrl.match(/^git@github\.com:(.+?)(?:\.git)?\/?$/) ?? remoteUrl.match(/^(?:https|ssh):\/\/(?:[^@/]+@)?github\.com\/(.+?)(?:\.git)?\/?$/);
24767
+ return m ? `https://github.com/${m[1]}` : null;
24768
+ }
24769
+ function prInSubject(subject) {
24770
+ const m = /\(#(\d+)\)\s*$/.exec(subject) ?? /^Merge pull request #(\d+)\b/.exec(subject);
24771
+ return m ? Number(m[1]) : null;
24772
+ }
24773
+ function commitPage(repoUrl, commit) {
24774
+ const pr = prInSubject(commit.subject);
24775
+ return pr === null ? { url: `${repoUrl}/commit/${commit.sha}` } : { url: `${repoUrl}/pull/${pr}`, pr };
24776
+ }
24777
+
24655
24778
  // ../daemon/src/git/blame.ts
24656
24779
  var NONE = { commits: [], lines: [] };
24657
24780
  var UNCOMMITTED = "0".repeat(40);
24658
24781
  async function blameFile(cwd, file, ref) {
24659
- const r = await gitRaw(cwd, "blame", "--porcelain", ...ref ? [ref] : [], "--", file);
24660
- return r.ok ? parseBlame(r.out) : NONE;
24782
+ const [r, origin, fetched] = await Promise.all([
24783
+ gitRaw(cwd, "blame", "--porcelain", ...ref ? [ref] : [], "--", file),
24784
+ git(cwd, "remote", "get-url", "origin"),
24785
+ git(cwd, "for-each-ref", "--count=1", "refs/remotes/origin")
24786
+ ]);
24787
+ if (!r.ok)
24788
+ return NONE;
24789
+ const blame = parseBlame(r.out);
24790
+ const repoUrl = origin.ok ? githubRepoUrl(origin.out) : null;
24791
+ if (repoUrl && fetched.ok && fetched.out && blame.commits.length > 0) {
24792
+ const local = await unpushed(cwd, blame.commits.map((c) => c.sha));
24793
+ for (const c of blame.commits)
24794
+ if (!local.has(c.sha))
24795
+ Object.assign(c, commitPage(repoUrl, c));
24796
+ }
24797
+ return blame;
24798
+ }
24799
+ async function unpushed(cwd, shas) {
24800
+ const r = await git(cwd, "rev-list", ...shas, "--not", "--remotes=origin");
24801
+ if (!r.ok)
24802
+ return new Set(shas);
24803
+ return new Set(r.out.split(`
24804
+ `).filter(Boolean));
24661
24805
  }
24662
24806
  function parseBlame(out) {
24663
24807
  const commits = [];
@@ -26094,7 +26238,7 @@ class AfterLand {
26094
26238
  }
26095
26239
 
26096
26240
  // ../daemon/src/repos/registry.ts
26097
- import { existsSync as existsSync27, mkdirSync as mkdirSync8, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
26241
+ import { existsSync as existsSync27, mkdirSync as mkdirSync8, rmSync as rmSync5, writeFileSync as writeFileSync11 } from "fs";
26098
26242
  import { homedir as homedir10 } from "os";
26099
26243
  import { basename as basename9, dirname as dirname10, join as join24 } from "path";
26100
26244
 
@@ -28304,7 +28448,7 @@ class RepoRegistry {
28304
28448
  const moved = rel !== was && existsSync27(join24(repo.path, was));
28305
28449
  if (moved && !(kind === "local" && await isTracked(repo.path, was))) {
28306
28450
  try {
28307
- rmSync4(join24(repo.path, was));
28451
+ rmSync5(join24(repo.path, was));
28308
28452
  } catch (e) {
28309
28453
  log.warn(repoId, `could not remove ${was}`, e);
28310
28454
  }
@@ -31320,7 +31464,7 @@ var handlers = {
31320
31464
  "install-agent"(msg, _ctx, s) {
31321
31465
  if (!s.agents.get(msg.agent))
31322
31466
  throw new UserError(`unknown agent "${msg.agent}"`);
31323
- fireAndForget(msg.agent, s.agents.install(msg.agent), "agent install");
31467
+ fireAndForget(msg.agent, s.agents.install(msg.agent, { anyway: msg.anyway === true }), "agent install");
31324
31468
  },
31325
31469
  async "agent-auth"(msg, _ctx, s) {
31326
31470
  requireRun(s, msg.worktreeId);
@@ -33179,11 +33323,11 @@ class BackendShare {
33179
33323
  // ../daemon/src/worktrees/cache.ts
33180
33324
  import { createHash as createHash4 } from "crypto";
33181
33325
  import { existsSync as existsSync32, readFileSync as readFileSync19 } from "fs";
33182
- import { mkdir as mkdir5, readdir as readdir2, rename, rm as rm4, stat as stat5, utimes, writeFile as writeFile3 } from "fs/promises";
33326
+ import { mkdir as mkdir5, readdir as readdir2, rename, rm as rm5, stat as stat5, utimes, writeFile as writeFile3 } from "fs/promises";
33183
33327
  import { join as join29 } from "path";
33184
33328
 
33185
33329
  // ../daemon/src/core/clone.ts
33186
- import { mkdir as mkdir4, rm as rm3 } from "fs/promises";
33330
+ import { mkdir as mkdir4, rm as rm4 } from "fs/promises";
33187
33331
  import { dirname as dirname12 } from "path";
33188
33332
  async function cloneTree(src, dst) {
33189
33333
  const started = Date.now();
@@ -33200,7 +33344,7 @@ async function cloneTree(src, dst) {
33200
33344
  return { ok: true, how, ms: Date.now() - started };
33201
33345
  error = r.err.split(`
33202
33346
  `)[0] ?? r.err;
33203
- await rm3(dst, { recursive: true, force: true });
33347
+ await rm4(dst, { recursive: true, force: true });
33204
33348
  }
33205
33349
  return { ok: false, error };
33206
33350
  }
@@ -33356,7 +33500,7 @@ class ArtifactCache {
33356
33500
  } catch (e) {
33357
33501
  log.warn(worktreeId, "cache publish failed", e);
33358
33502
  if (tmp)
33359
- await rm4(tmp, { recursive: true, force: true });
33503
+ await rm5(tmp, { recursive: true, force: true });
33360
33504
  } finally {
33361
33505
  if (slot)
33362
33506
  this.making.delete(slot);
@@ -33366,7 +33510,7 @@ class ArtifactCache {
33366
33510
  async prune(familyDir) {
33367
33511
  const entries = await listEntries(familyDir);
33368
33512
  for (const e of entries.slice(KEEP_PER_FAMILY))
33369
- await rm4(e.dir, { recursive: true, force: true });
33513
+ await rm5(e.dir, { recursive: true, force: true });
33370
33514
  }
33371
33515
  async sweep() {
33372
33516
  const root = this.d.paths.cacheDir;
@@ -33379,7 +33523,7 @@ class ArtifactCache {
33379
33523
  for (const repoId of repoIds) {
33380
33524
  const repoDir = join29(root, repoId);
33381
33525
  if (!this.d.state.repo(repoId)) {
33382
- await rm4(repoDir, { recursive: true, force: true });
33526
+ await rm5(repoDir, { recursive: true, force: true });
33383
33527
  continue;
33384
33528
  }
33385
33529
  let families;
@@ -33398,7 +33542,7 @@ class ArtifactCache {
33398
33542
  }
33399
33543
  for (const n of names)
33400
33544
  if (n.startsWith(TMP))
33401
- await rm4(join29(familyDir, n), { recursive: true, force: true });
33545
+ await rm5(join29(familyDir, n), { recursive: true, force: true });
33402
33546
  const entries = await listEntries(familyDir);
33403
33547
  let newest = 0;
33404
33548
  for (const e of entries) {
@@ -33407,7 +33551,7 @@ class ArtifactCache {
33407
33551
  newest = Math.max(newest, s.mtimeMs);
33408
33552
  }
33409
33553
  if (Date.now() - newest > STALE_MS)
33410
- await rm4(familyDir, { recursive: true, force: true });
33554
+ await rm5(familyDir, { recursive: true, force: true });
33411
33555
  }
33412
33556
  }
33413
33557
  }
@@ -35798,12 +35942,12 @@ function rankRefs({ refs, merged, prs, query, defaultBranch, rowIdForPath }) {
35798
35942
  }
35799
35943
 
35800
35944
  // ../daemon/src/worktrees/service.ts
35801
- import { cpSync, existsSync as existsSync37, readFileSync as readFileSync22, rmSync as rmSync8 } from "fs";
35802
- import { rm as rm5 } from "fs/promises";
35945
+ import { cpSync, existsSync as existsSync37, readFileSync as readFileSync22, rmSync as rmSync9 } from "fs";
35946
+ import { rm as rm6 } from "fs/promises";
35803
35947
  import { dirname as dirname14, join as join35 } from "path";
35804
35948
 
35805
35949
  // ../daemon/src/git/archive.ts
35806
- import { rmSync as rmSync5 } from "fs";
35950
+ import { rmSync as rmSync6 } from "fs";
35807
35951
  var archiveRef = (worktreeId) => `refs/toyon/archive/${worktreeId}`;
35808
35952
  var SNAPSHOT_SUBJECT = "toyon: uncommitted work";
35809
35953
  var SNAPSHOT_AUTHOR = "toyon";
@@ -35846,7 +35990,7 @@ async function snapshotCommit(wtPath, head, indexFile) {
35846
35990
  ], wtPath);
35847
35991
  return commit.ok ? commit.out : null;
35848
35992
  } finally {
35849
- rmSync5(indexFile, { force: true });
35993
+ rmSync6(indexFile, { force: true });
35850
35994
  }
35851
35995
  }
35852
35996
  async function keptAt(repoPath, ref) {
@@ -36418,14 +36562,14 @@ ${r.err}`))
36418
36562
  return { ok: true, message: `PR #${number} merged` };
36419
36563
  }
36420
36564
  function compareUrl(remoteUrl, base, branch) {
36421
- const m = remoteUrl.match(/^git@github\.com:(.+?)(?:\.git)?$/) ?? remoteUrl.match(/^https:\/\/github\.com\/(.+?)(?:\.git)?$/);
36422
- if (!m)
36565
+ const repo = githubRepoUrl(remoteUrl);
36566
+ if (!repo)
36423
36567
  return null;
36424
- return `https://github.com/${m[1]}/compare/${encodeURIComponent(base)}...${encodeURIComponent(branch)}?expand=1`;
36568
+ return `${repo}/compare/${encodeURIComponent(base)}...${encodeURIComponent(branch)}?expand=1`;
36425
36569
  }
36426
36570
 
36427
36571
  // ../daemon/src/git/turn.ts
36428
- import { copyFileSync, existsSync as existsSync34, rmSync as rmSync6 } from "fs";
36572
+ import { copyFileSync, existsSync as existsSync34, rmSync as rmSync7 } from "fs";
36429
36573
  import { join as join31 } from "path";
36430
36574
  var turnRef = (worktreeId, which) => `refs/toyon/turns/${worktreeId}/${which}`;
36431
36575
  var SNAPSHOT_SUBJECT2 = "toyon: tree at a send";
@@ -36476,7 +36620,7 @@ async function treeNow(wtPath, head, dirty) {
36476
36620
  const full = async () => (await run(GIT, ["add", "-A"], wtPath, env)).ok ? writeTree() : null;
36477
36621
  let tree = await full();
36478
36622
  if (!tree) {
36479
- rmSync6(index, { force: true });
36623
+ rmSync7(index, { force: true });
36480
36624
  if (!(await run(GIT, ["read-tree", "HEAD"], wtPath, env)).ok)
36481
36625
  return null;
36482
36626
  tree = await full();
@@ -36549,7 +36693,7 @@ async function dropTurnRefs(repoPath, worktreeId) {
36549
36693
  }
36550
36694
 
36551
36695
  // ../daemon/src/worktrees/archive.ts
36552
- import { existsSync as existsSync35, mkdirSync as mkdirSync9, readdirSync as readdirSync9, readFileSync as readFileSync21, renameSync as renameSync7, rmSync as rmSync7, writeFileSync as writeFileSync13 } from "fs";
36696
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readdirSync as readdirSync9, readFileSync as readFileSync21, renameSync as renameSync7, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
36553
36697
  import { basename as basename12, dirname as dirname13, join as join32 } from "path";
36554
36698
  class WorktreeArchive {
36555
36699
  dir;
@@ -36593,7 +36737,7 @@ class WorktreeArchive {
36593
36737
  delete(id) {
36594
36738
  if (!this.records.has(id))
36595
36739
  return;
36596
- rmSync7(this.filesOf(id).dir, { recursive: true, force: true });
36740
+ rmSync8(this.filesOf(id).dir, { recursive: true, force: true });
36597
36741
  this.records.delete(id);
36598
36742
  }
36599
36743
  list(repo) {
@@ -36695,7 +36839,7 @@ function move(from, to) {
36695
36839
  if (!existsSync35(from))
36696
36840
  return;
36697
36841
  mkdirSync9(dirname13(to), { recursive: true });
36698
- rmSync7(to, { recursive: true, force: true });
36842
+ rmSync8(to, { recursive: true, force: true });
36699
36843
  renameSync7(from, to);
36700
36844
  }
36701
36845
 
@@ -37746,7 +37890,7 @@ var BASE_IGNORE = "base .gitignore";
37746
37890
  var REFUSAL_CHARS = 400;
37747
37891
  async function deleteTree(path) {
37748
37892
  try {
37749
- await rm5(path, { recursive: true, force: true });
37893
+ await rm6(path, { recursive: true, force: true });
37750
37894
  return true;
37751
37895
  } catch (e) {
37752
37896
  log.warn("rm", `could not delete ${path}`, e);
@@ -38316,7 +38460,7 @@ class WorktreeService {
38316
38460
  try {
38317
38461
  await this.removeDirectory(repo, wt);
38318
38462
  } catch (e) {
38319
- rmSync8(this.plansScratch(wt.id), { recursive: true, force: true });
38463
+ rmSync9(this.plansScratch(wt.id), { recursive: true, force: true });
38320
38464
  throw e;
38321
38465
  }
38322
38466
  if (hasOwnBranch(wt)) {
@@ -38438,8 +38582,8 @@ class WorktreeService {
38438
38582
  deleteChat(worktreeId) {
38439
38583
  const files = this.chatFiles(worktreeId);
38440
38584
  try {
38441
- rmSync8(files.transcript, { force: true });
38442
- rmSync8(files.attachments, { recursive: true, force: true });
38585
+ rmSync9(files.transcript, { force: true });
38586
+ rmSync9(files.attachments, { recursive: true, force: true });
38443
38587
  } catch (e) {
38444
38588
  log.warn(worktreeId, "could not delete transcript or attachments", e);
38445
38589
  }
@@ -40062,7 +40206,7 @@ var knocks = new Knocks(hub);
40062
40206
  var origins = new Origins({ setting, port, branded: () => branded });
40063
40207
  var linuxSandbox = new LinuxSandbox;
40064
40208
  await linuxSandbox.refresh();
40065
- var agents = loadAgentRegistry(paths.agentsFile, paths.agentsDir, linuxSandbox, managed.policy);
40209
+ var agents = loadAgentRegistry(paths.agentsFile, paths.agentsDir, linuxSandbox, managed.policy, paths.agentsFrom);
40066
40210
  if (state.defaultAgent !== undefined && !agents.get(state.defaultAgent))
40067
40211
  state.clearDefaultAgent();
40068
40212
  var readiness2 = new AgentReadiness({
@@ -40442,7 +40586,7 @@ async function shutdown(signal, opts = {}) {
40442
40586
  const deadline = new Promise((resolve) => setTimeout(resolve, 5000));
40443
40587
  await Promise.race([Promise.all([runtime.shutdown(), exec.stopAll()]), deadline]);
40444
40588
  state.flushGroups();
40445
- rmSync9(paths.pidFile, { force: true });
40589
+ rmSync10(paths.pidFile, { force: true });
40446
40590
  if (opts.respawn) {
40447
40591
  await Bun.sleep(250);
40448
40592
  log.info("daemon", "starting the replacement");