pi-crew 0.9.48 → 0.9.50

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 (86) hide show
  1. package/AGENTS.md +18 -0
  2. package/CHANGELOG.md +314 -0
  3. package/dist/build-meta.json +70 -42
  4. package/dist/index.mjs +505 -430
  5. package/dist/index.mjs.map +4 -4
  6. package/docs/decisions/2026-07-24-oidc-trusted-publishing.md +112 -0
  7. package/package.json +2 -3
  8. package/skills/.gitkeep +0 -0
  9. package/skills/distill-persona/BUILD-NOTES.md +55 -0
  10. package/skills/distill-persona/SKILL.md +550 -0
  11. package/skills/distill-persona/UPGRADE-LOG-RESEARCH-SKILLS.md +100 -0
  12. package/skills/distill-persona/references/coverage-manifest.md +65 -0
  13. package/skills/distill-persona/references/cross-skill-differentiation.md +12 -0
  14. package/skills/distill-persona/references/description-discipline.md +6 -0
  15. package/skills/distill-persona/references/diagnostic-path.md +25 -0
  16. package/skills/distill-persona/references/distillation-field-synthesis-pass2.md +59 -0
  17. package/skills/distill-persona/references/distillation-field-synthesis.md +108 -0
  18. package/skills/distill-persona/references/fidelity-rubric.md +19 -0
  19. package/skills/distill-persona/references/field-models.md +20 -0
  20. package/skills/distill-persona/references/handoff.md +42 -0
  21. package/skills/distill-persona/references/optional-body-sections.md +9 -0
  22. package/skills/distill-persona/references/registry-routing.md +11 -0
  23. package/skills/distill-persona/references/research/lesson-memory-shortcut.md +33 -0
  24. package/skills/distill-persona/references/research/r1-a-examples.md +23 -0
  25. package/skills/distill-persona/references/research/r1-b-scripts.md +26 -0
  26. package/skills/distill-persona/references/research/r1-c-human-readme.md +31 -0
  27. package/skills/distill-persona/references/research/r1-d-tests.md +28 -0
  28. package/skills/distill-persona/references/research/r1-verification.md +36 -0
  29. package/skills/distill-persona/references/research/r2-low-yield.md +26 -0
  30. package/skills/distill-persona/references/self-upgrade-directive.md +20 -0
  31. package/skills/distill-persona/references/taste-principles.md +8 -0
  32. package/skills/distill-persona/references/topic-variant.md +13 -0
  33. package/skills/distill-persona/references/update-mode.md +7 -0
  34. package/skills/distill-persona/scripts/fidelity_eval.py +244 -0
  35. package/skills/distill-persona/scripts/validate-run.mjs +297 -0
  36. package/skills/distill-persona/scripts/validate-skill-structure.mjs +177 -0
  37. package/skills/distill-software/BUILD-NOTES.md +56 -0
  38. package/skills/distill-software/SKILL.md +363 -0
  39. package/skills/distill-software/references/handoff.md +47 -0
  40. package/skills/distill-software/scripts/code_dna.py +290 -0
  41. package/skills/research/DISTILLATION-PROCESS-CHECKLIST.md +120 -0
  42. package/skills/research/EXCAVATION-CHECKLIST.md +142 -0
  43. package/skills/research/FIDELITY.md +180 -0
  44. package/skills/research/SKILL.md +432 -0
  45. package/skills/research/references/anti-patterns.md +184 -0
  46. package/skills/research/references/fidelity.md +241 -0
  47. package/skills/research/references/handoff.md +48 -0
  48. package/skills/research/references/research-protocol.md +162 -0
  49. package/skills/research/references/source-inventory.md +135 -0
  50. package/skills/research/references/verified-models.md +163 -0
  51. package/skills/research/scripts/__pycache__/safe_io.cpython-312.pyc +0 -0
  52. package/skills/research/scripts/code_dna.py +233 -0
  53. package/skills/research/scripts/emit_run_summary.py +142 -0
  54. package/skills/research/scripts/safe_io.py +314 -0
  55. package/skills/research/scripts/source_evaluator.py +234 -0
  56. package/skills/research/scripts/validate-skill-structure.mjs +177 -0
  57. package/skills/research/scripts/verify_citations.py +225 -0
  58. package/skills/security-priority.json +28 -0
  59. package/src/config/config.ts +1 -0
  60. package/src/config/role-tools.ts +6 -3
  61. package/src/config/types.ts +8 -0
  62. package/src/extension/crew-cleanup.ts +18 -1
  63. package/src/extension/crew-vibes/index.ts +11 -2
  64. package/src/extension/register.ts +1 -1
  65. package/src/extension/registration/command-registration.ts +1 -0
  66. package/src/extension/registration/commands.ts +7 -3
  67. package/src/extension/registration/lifecycle-handlers.ts +1 -3
  68. package/src/extension/registration/ui.ts +4 -0
  69. package/src/extension/registration/viewers.ts +3 -0
  70. package/src/extension/team-tool/run.ts +7 -6
  71. package/src/runtime/background-runner.ts +11 -16
  72. package/src/runtime/chain-runner.ts +3 -2
  73. package/src/runtime/heartbeat-watcher.ts +28 -1
  74. package/src/runtime/pipeline-runner.ts +8 -7
  75. package/src/runtime/task-runner.ts +165 -119
  76. package/src/schema/config-schema.ts +1 -0
  77. package/src/ui/live-run-sidebar.ts +2 -0
  78. package/src/ui/mascot.ts +11 -9
  79. package/src/ui/render-coalescer.ts +9 -0
  80. package/src/ui/run-snapshot-cache.ts +10 -11
  81. package/src/ui/terminal-status.ts +5 -0
  82. package/src/ui/widget/index.ts +3 -5
  83. package/src/ui/widget/widget-types.ts +0 -1
  84. package/src/utils/gh-protocol.ts +9 -8
  85. package/workflows/distill.workflow.md +198 -0
  86. package/assets/runner-spritesheet.png +0 -0
package/dist/index.mjs CHANGED
@@ -110,6 +110,7 @@ var init_config_schema = __esm({
110
110
  allowChildProcessFallback: Type.Optional(Type.Boolean()),
111
111
  maxTurns: Type.Optional(Type.Integer({ minimum: 1 })),
112
112
  graceTurns: Type.Optional(Type.Integer({ minimum: 1 })),
113
+ taskTimeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),
113
114
  inheritContext: Type.Optional(Type.Boolean()),
114
115
  promptMode: Type.Optional(Type.Union([Type.Literal("replace"), Type.Literal("append")])),
115
116
  groupJoin: Type.Optional(Type.Union([Type.Literal("off"), Type.Literal("group"), Type.Literal("smart")])),
@@ -388,8 +389,8 @@ function sleepSync(ms) {
388
389
  }
389
390
  function sleep(ms, signal) {
390
391
  if (signal?.aborted) return Promise.reject(new Error("aborted"));
391
- return new Promise((resolve22, reject) => {
392
- const timer = setTimeout(resolve22, ms);
392
+ return new Promise((resolve23, reject) => {
393
+ const timer = setTimeout(resolve23, ms);
393
394
  signal?.addEventListener(
394
395
  "abort",
395
396
  () => {
@@ -434,9 +435,9 @@ function getWorker() {
434
435
  return worker;
435
436
  }
436
437
  function dispatch(kind, payload) {
437
- return new Promise((resolve22, reject) => {
438
+ return new Promise((resolve23, reject) => {
438
439
  const id = nextRequestId++;
439
- pending.set(id, { resolve: resolve22, reject });
440
+ pending.set(id, { resolve: resolve23, reject });
440
441
  try {
441
442
  getWorker().postMessage({ kind, id, ...payload });
442
443
  } catch (error) {
@@ -698,7 +699,7 @@ function isSymlinkSafeDirCached(filePath) {
698
699
  return verdict;
699
700
  }
700
701
  function sleep2(ms) {
701
- return new Promise((resolve22) => setTimeout(resolve22, ms));
702
+ return new Promise((resolve23) => setTimeout(resolve23, ms));
702
703
  }
703
704
  function isRetryableRenameError(error) {
704
705
  return Boolean(
@@ -1369,7 +1370,7 @@ function acquireLockWithRetry(filePath, staleMs, kind = "file") {
1369
1370
  }
1370
1371
  }
1371
1372
  function sleep3(ms) {
1372
- return new Promise((resolve22) => setTimeout(resolve22, ms));
1373
+ return new Promise((resolve23) => setTimeout(resolve23, ms));
1373
1374
  }
1374
1375
  async function acquireLockWithRetryAsync(filePath, staleMs, kind = "file") {
1375
1376
  let attempt = 0;
@@ -1858,14 +1859,14 @@ function errorPathFromValidation(error) {
1858
1859
  function validateConfigWithWarnings(raw) {
1859
1860
  if (!Value2.Check(PiTeamsConfigSchema, raw)) {
1860
1861
  return [...Value2.Errors(PiTeamsConfigSchema, raw)].map((error) => {
1861
- const path84 = errorPathFromValidation(error);
1862
+ const path85 = errorPathFromValidation(error);
1862
1863
  const message = error.message ?? "invalid value";
1863
1864
  if (error.keyword === "additionalProperties") {
1864
- const offendingKey = path84.split("/").pop() ?? path84;
1865
+ const offendingKey = path85.split("/").pop() ?? path85;
1865
1866
  const suggestion = suggestConfigKey(offendingKey, KNOWN_TOP_LEVEL_KEYS);
1866
- if (suggestion) return `${path84}: ${message} (did you mean '${suggestion}'?)`;
1867
+ if (suggestion) return `${path85}: ${message} (did you mean '${suggestion}'?)`;
1867
1868
  }
1868
- return `${path84}: ${message}`;
1869
+ return `${path85}: ${message}`;
1869
1870
  });
1870
1871
  }
1871
1872
  return [];
@@ -2222,6 +2223,7 @@ function parseRuntimeConfig(value) {
2222
2223
  allowChildProcessFallback: parseWithSchema(Type2.Boolean(), obj.allowChildProcessFallback),
2223
2224
  maxTurns: parsePositiveInteger(obj.maxTurns, LIMIT_CEILINGS.runtimeMaxTurns),
2224
2225
  graceTurns: parsePositiveInteger(obj.graceTurns, LIMIT_CEILINGS.runtimeGraceTurns),
2226
+ taskTimeoutMs: parsePositiveInteger(obj.taskTimeoutMs, LIMIT_CEILINGS.runtimeMaxTurns),
2225
2227
  inheritContext: parseWithSchema(Type2.Boolean(), obj.inheritContext) ?? true,
2226
2228
  promptMode: parseWithSchema(Type2.Union([Type2.Literal("replace"), Type2.Literal("append")]), obj.promptMode),
2227
2229
  groupJoin: parseWithSchema(Type2.Union([Type2.Literal("off"), Type2.Literal("group"), Type2.Literal("smart")]), obj.groupJoin),
@@ -3231,10 +3233,13 @@ var init_role_tools = __esm({
3231
3233
  "src/config/role-tools.ts"() {
3232
3234
  "use strict";
3233
3235
  ROLE_TOOL_CONFIGS = {
3234
- // Explorer - Read-only, no write or execute
3236
+ // Explorer - Read-only exploration; bash is included for git log/show
3237
+ // (decisions stream needs commit-history mining) but edit/write stay
3238
+ // excluded. State-mutation safety is enforced separately by
3239
+ // READ_ONLY_ROLES in role-permission.ts.
3235
3240
  explorer: {
3236
- tools: ["read", "grep", "find", "ls", "glob"],
3237
- excludeTools: ["edit", "write", "bash", "web"]
3241
+ tools: ["read", "grep", "find", "ls", "glob", "bash"],
3242
+ excludeTools: ["edit", "write", "web"]
3238
3243
  },
3239
3244
  // Analyst - Read and analyze, limited execution
3240
3245
  analyst: {
@@ -3798,16 +3803,16 @@ function parseGenericGitUrl(url) {
3798
3803
  const { repo: repoWithoutRef, ref } = splitRef(url);
3799
3804
  let repo = repoWithoutRef;
3800
3805
  let host = "";
3801
- let path84 = "";
3806
+ let path85 = "";
3802
3807
  const scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);
3803
3808
  if (scpLikeMatch) {
3804
3809
  host = scpLikeMatch[1] ?? "";
3805
- path84 = scpLikeMatch[2] ?? "";
3810
+ path85 = scpLikeMatch[2] ?? "";
3806
3811
  } else if (repoWithoutRef.startsWith("https://") || repoWithoutRef.startsWith("http://") || repoWithoutRef.startsWith("ssh://") || repoWithoutRef.startsWith("git://")) {
3807
3812
  try {
3808
3813
  const parsed = new URL(repoWithoutRef);
3809
3814
  host = parsed.hostname;
3810
- path84 = parsed.pathname.replace(/^\/+/, "");
3815
+ path85 = parsed.pathname.replace(/^\/+/, "");
3811
3816
  } catch {
3812
3817
  return null;
3813
3818
  }
@@ -3817,13 +3822,13 @@ function parseGenericGitUrl(url) {
3817
3822
  return null;
3818
3823
  }
3819
3824
  host = repoWithoutRef.slice(0, slashIndex);
3820
- path84 = repoWithoutRef.slice(slashIndex + 1);
3825
+ path85 = repoWithoutRef.slice(slashIndex + 1);
3821
3826
  if (!host.includes(".") && host !== "localhost") {
3822
3827
  return null;
3823
3828
  }
3824
3829
  repo = `https://${repoWithoutRef}`;
3825
3830
  }
3826
- const normalizedPath = path84.replace(/\.git$/, "").replace(/^\/+/, "");
3831
+ const normalizedPath = path85.replace(/\.git$/, "").replace(/^\/+/, "");
3827
3832
  if (!host || !normalizedPath || normalizedPath.split("/").length < 2) {
3828
3833
  return null;
3829
3834
  }
@@ -4612,7 +4617,7 @@ var init_cancellation_token = __esm({
4612
4617
  wait(ms) {
4613
4618
  this.throwIfCancelled();
4614
4619
  if (ms <= 0) return Promise.resolve();
4615
- return new Promise((resolve22, reject) => {
4620
+ return new Promise((resolve23, reject) => {
4616
4621
  let timeout;
4617
4622
  const cleanup = () => {
4618
4623
  if (timeout) clearTimeout(timeout);
@@ -4624,7 +4629,7 @@ var init_cancellation_token = __esm({
4624
4629
  };
4625
4630
  timeout = setTimeout(() => {
4626
4631
  cleanup();
4627
- resolve22();
4632
+ resolve23();
4628
4633
  }, ms);
4629
4634
  this.signal.addEventListener("abort", onAbort, { once: true });
4630
4635
  });
@@ -5903,7 +5908,7 @@ function redactInlineSecrets(value) {
5903
5908
  if (keyLen > 0 && j < value.length && (value[j] === "=" || value[j] === ":")) {
5904
5909
  const key = value.substring(i, j);
5905
5910
  if (isSecretKey(key)) {
5906
- const sep10 = value[j];
5911
+ const sep11 = value[j];
5907
5912
  let k = j + 1;
5908
5913
  let valLen = 0;
5909
5914
  while (k < value.length && valLen < 500 && value[k] !== " " && value[k] !== "," && value[k] !== ";" && value[k] !== '"' && value[k] !== "\r" && value[k] !== "\n") {
@@ -5912,7 +5917,7 @@ function redactInlineSecrets(value) {
5912
5917
  }
5913
5918
  if (valLen > 0) {
5914
5919
  result4.push(key);
5915
- result4.push(sep10);
5920
+ result4.push(sep11);
5916
5921
  result4.push("***");
5917
5922
  i = k;
5918
5923
  redacted = true;
@@ -6888,8 +6893,8 @@ function extractErrorMessage(event) {
6888
6893
  const obj = asRecord3(event);
6889
6894
  if (!obj) return void 0;
6890
6895
  const message = asRecord3(obj.message) ?? obj;
6891
- const errorMessage = message.errorMessage;
6892
- return typeof errorMessage === "string" && errorMessage.trim() ? errorMessage.trim() : void 0;
6896
+ const errorMessage2 = message.errorMessage;
6897
+ return typeof errorMessage2 === "string" && errorMessage2.trim() ? errorMessage2.trim() : void 0;
6893
6898
  }
6894
6899
  function extractPatch(event, patches) {
6895
6900
  const obj = asRecord3(event);
@@ -7501,7 +7506,7 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
7501
7506
  if (spawnPrep.kind === "aborted") return spawnPrep.result;
7502
7507
  const { spawnSpec, mergedEnv, tempDir, builtEnv } = spawnPrep.ctx;
7503
7508
  try {
7504
- return await new Promise((resolve22) => {
7509
+ return await new Promise((resolve23) => {
7505
7510
  const spawnOptions = buildFinalChildPiSpawnOptions(input.cwd, mergedEnv, builtEnv, input.model);
7506
7511
  const child = spawn2(spawnSpec.command, spawnSpec.args, spawnOptions);
7507
7512
  if (child.pid) {
@@ -7773,7 +7778,7 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
7773
7778
  cleanupErrors.push(error instanceof Error ? error.message : String(error));
7774
7779
  }
7775
7780
  try {
7776
- resolve22({
7781
+ resolve23({
7777
7782
  ...result4,
7778
7783
  rawFinalText: lineObserver.getRawFinalText(),
7779
7784
  intermediateFindings: lineObserver.getIntermediateFindings(),
@@ -7815,7 +7820,7 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
7815
7820
  cleanupErrors.push(error instanceof Error ? error.message : String(error));
7816
7821
  }
7817
7822
  try {
7818
- resolve22({
7823
+ resolve23({
7819
7824
  ...result4,
7820
7825
  rawFinalText: lineObserver.getRawFinalText(),
7821
7826
  intermediateFindings: lineObserver.getIntermediateFindings(),
@@ -8073,7 +8078,8 @@ var init_child_pi = __esm({
8073
8078
  });
8074
8079
 
8075
8080
  // src/extension/crew-cleanup.ts
8076
- function registerCleanupHandler(pi) {
8081
+ function registerCleanupHandler(pi, opts) {
8082
+ terminalStatusDispose = opts?.disposeTerminalStatus;
8077
8083
  pi.on("session_shutdown", async () => {
8078
8084
  console.log("[pi-crew] Session shutdown - cleaning up resources");
8079
8085
  try {
@@ -8088,6 +8094,10 @@ function registerCleanupHandler(pi) {
8088
8094
  signalHandlersRegistered = true;
8089
8095
  const handleSignal = async (signal) => {
8090
8096
  console.log(`[pi-crew] Received ${signal} - starting cleanup`);
8097
+ try {
8098
+ terminalStatusDispose?.();
8099
+ } catch {
8100
+ }
8091
8101
  await cleanupChildProcesses();
8092
8102
  };
8093
8103
  process.on("SIGTERM", () => {
@@ -8135,7 +8145,7 @@ function registerChildProcess(pid, runId, agentId) {
8135
8145
  function unregisterChildProcess(pid) {
8136
8146
  childProcessRegistry.unregister(pid);
8137
8147
  }
8138
- var signalHandlersRegistered, ChildProcessRegistry, childProcessRegistry;
8148
+ var signalHandlersRegistered, ChildProcessRegistry, childProcessRegistry, terminalStatusDispose;
8139
8149
  var init_crew_cleanup = __esm({
8140
8150
  "src/extension/crew-cleanup.ts"() {
8141
8151
  "use strict";
@@ -8774,13 +8784,13 @@ var init_errors = __esm({
8774
8784
  }
8775
8785
  };
8776
8786
  errors = {
8777
- fileRead(path84, source) {
8778
- return new CrewError(ErrorCode.FileReadError, `Failed to read ${path84}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8787
+ fileRead(path85, source) {
8788
+ return new CrewError(ErrorCode.FileReadError, `Failed to read ${path85}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8779
8789
  "file system read operation"
8780
8790
  );
8781
8791
  },
8782
- fileWrite(path84, source) {
8783
- return new CrewError(ErrorCode.FileWriteError, `Failed to write ${path84}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8792
+ fileWrite(path85, source) {
8793
+ return new CrewError(ErrorCode.FileWriteError, `Failed to write ${path85}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8784
8794
  "file system write operation"
8785
8795
  );
8786
8796
  },
@@ -10032,9 +10042,9 @@ function appendEventBuffered(eventsPath, event, bufferMs = DEFAULT_BUFFER_MS) {
10032
10042
  }
10033
10043
  return Promise.resolve(appendEvent(eventsPath, event));
10034
10044
  }
10035
- return new Promise((resolve22, reject) => {
10045
+ return new Promise((resolve23, reject) => {
10036
10046
  const queue = bufferedQueues.get(eventsPath) ?? [];
10037
- queue.push({ event, resolve: resolve22, reject });
10047
+ queue.push({ event, resolve: resolve23, reject });
10038
10048
  bufferedQueues.set(eventsPath, queue);
10039
10049
  if (!bufferedTimers.has(eventsPath)) {
10040
10050
  const timer = setTimeout(() => {
@@ -13712,8 +13722,8 @@ var init_config_patch = __esm({
13712
13722
  });
13713
13723
 
13714
13724
  // src/extension/team-tool/handle-settings.ts
13715
- function setNested(obj, path84, value) {
13716
- const keys = path84.split(".");
13725
+ function setNested(obj, path85, value) {
13726
+ const keys = path85.split(".");
13717
13727
  let target = obj;
13718
13728
  for (let i = 0; i < keys.length - 1; i++) {
13719
13729
  if (!target[keys[i]] || typeof target[keys[i]] !== "object") {
@@ -13723,8 +13733,8 @@ function setNested(obj, path84, value) {
13723
13733
  }
13724
13734
  target[keys[keys.length - 1]] = value;
13725
13735
  }
13726
- function getNested(obj, path84) {
13727
- const keys = path84.split(".");
13736
+ function getNested(obj, path85) {
13737
+ const keys = path85.split(".");
13728
13738
  let current = obj;
13729
13739
  for (const key of keys) {
13730
13740
  if (!current || typeof current !== "object") return void 0;
@@ -14398,9 +14408,9 @@ async function isLiveSessionRuntimeAvailable(timeoutMs = 1500, env = process.env
14398
14408
  try {
14399
14409
  return await Promise.race([
14400
14410
  probe(),
14401
- new Promise((resolve22) => {
14411
+ new Promise((resolve23) => {
14402
14412
  timer = setTimeout(
14403
- () => resolve22({
14413
+ () => resolve23({
14404
14414
  available: false,
14405
14415
  reason: `Timed out probing optional Pi SDK live-session runtime after ${timeoutMs}ms.`
14406
14416
  }),
@@ -14677,17 +14687,17 @@ var require_visit = __commonJS({
14677
14687
  visit.BREAK = BREAK;
14678
14688
  visit.SKIP = SKIP;
14679
14689
  visit.REMOVE = REMOVE;
14680
- function visit_(key, node, visitor, path84) {
14681
- const ctrl = callVisitor(key, node, visitor, path84);
14690
+ function visit_(key, node, visitor, path85) {
14691
+ const ctrl = callVisitor(key, node, visitor, path85);
14682
14692
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
14683
- replaceNode(key, path84, ctrl);
14684
- return visit_(key, ctrl, visitor, path84);
14693
+ replaceNode(key, path85, ctrl);
14694
+ return visit_(key, ctrl, visitor, path85);
14685
14695
  }
14686
14696
  if (typeof ctrl !== "symbol") {
14687
14697
  if (identity.isCollection(node)) {
14688
- path84 = Object.freeze(path84.concat(node));
14698
+ path85 = Object.freeze(path85.concat(node));
14689
14699
  for (let i = 0; i < node.items.length; ++i) {
14690
- const ci = visit_(i, node.items[i], visitor, path84);
14700
+ const ci = visit_(i, node.items[i], visitor, path85);
14691
14701
  if (typeof ci === "number")
14692
14702
  i = ci - 1;
14693
14703
  else if (ci === BREAK)
@@ -14698,13 +14708,13 @@ var require_visit = __commonJS({
14698
14708
  }
14699
14709
  }
14700
14710
  } else if (identity.isPair(node)) {
14701
- path84 = Object.freeze(path84.concat(node));
14702
- const ck = visit_("key", node.key, visitor, path84);
14711
+ path85 = Object.freeze(path85.concat(node));
14712
+ const ck = visit_("key", node.key, visitor, path85);
14703
14713
  if (ck === BREAK)
14704
14714
  return BREAK;
14705
14715
  else if (ck === REMOVE)
14706
14716
  node.key = null;
14707
- const cv = visit_("value", node.value, visitor, path84);
14717
+ const cv = visit_("value", node.value, visitor, path85);
14708
14718
  if (cv === BREAK)
14709
14719
  return BREAK;
14710
14720
  else if (cv === REMOVE)
@@ -14725,17 +14735,17 @@ var require_visit = __commonJS({
14725
14735
  visitAsync.BREAK = BREAK;
14726
14736
  visitAsync.SKIP = SKIP;
14727
14737
  visitAsync.REMOVE = REMOVE;
14728
- async function visitAsync_(key, node, visitor, path84) {
14729
- const ctrl = await callVisitor(key, node, visitor, path84);
14738
+ async function visitAsync_(key, node, visitor, path85) {
14739
+ const ctrl = await callVisitor(key, node, visitor, path85);
14730
14740
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
14731
- replaceNode(key, path84, ctrl);
14732
- return visitAsync_(key, ctrl, visitor, path84);
14741
+ replaceNode(key, path85, ctrl);
14742
+ return visitAsync_(key, ctrl, visitor, path85);
14733
14743
  }
14734
14744
  if (typeof ctrl !== "symbol") {
14735
14745
  if (identity.isCollection(node)) {
14736
- path84 = Object.freeze(path84.concat(node));
14746
+ path85 = Object.freeze(path85.concat(node));
14737
14747
  for (let i = 0; i < node.items.length; ++i) {
14738
- const ci = await visitAsync_(i, node.items[i], visitor, path84);
14748
+ const ci = await visitAsync_(i, node.items[i], visitor, path85);
14739
14749
  if (typeof ci === "number")
14740
14750
  i = ci - 1;
14741
14751
  else if (ci === BREAK)
@@ -14746,13 +14756,13 @@ var require_visit = __commonJS({
14746
14756
  }
14747
14757
  }
14748
14758
  } else if (identity.isPair(node)) {
14749
- path84 = Object.freeze(path84.concat(node));
14750
- const ck = await visitAsync_("key", node.key, visitor, path84);
14759
+ path85 = Object.freeze(path85.concat(node));
14760
+ const ck = await visitAsync_("key", node.key, visitor, path85);
14751
14761
  if (ck === BREAK)
14752
14762
  return BREAK;
14753
14763
  else if (ck === REMOVE)
14754
14764
  node.key = null;
14755
- const cv = await visitAsync_("value", node.value, visitor, path84);
14765
+ const cv = await visitAsync_("value", node.value, visitor, path85);
14756
14766
  if (cv === BREAK)
14757
14767
  return BREAK;
14758
14768
  else if (cv === REMOVE)
@@ -14779,23 +14789,23 @@ var require_visit = __commonJS({
14779
14789
  }
14780
14790
  return visitor;
14781
14791
  }
14782
- function callVisitor(key, node, visitor, path84) {
14792
+ function callVisitor(key, node, visitor, path85) {
14783
14793
  if (typeof visitor === "function")
14784
- return visitor(key, node, path84);
14794
+ return visitor(key, node, path85);
14785
14795
  if (identity.isMap(node))
14786
- return visitor.Map?.(key, node, path84);
14796
+ return visitor.Map?.(key, node, path85);
14787
14797
  if (identity.isSeq(node))
14788
- return visitor.Seq?.(key, node, path84);
14798
+ return visitor.Seq?.(key, node, path85);
14789
14799
  if (identity.isPair(node))
14790
- return visitor.Pair?.(key, node, path84);
14800
+ return visitor.Pair?.(key, node, path85);
14791
14801
  if (identity.isScalar(node))
14792
- return visitor.Scalar?.(key, node, path84);
14802
+ return visitor.Scalar?.(key, node, path85);
14793
14803
  if (identity.isAlias(node))
14794
- return visitor.Alias?.(key, node, path84);
14804
+ return visitor.Alias?.(key, node, path85);
14795
14805
  return void 0;
14796
14806
  }
14797
- function replaceNode(key, path84, node) {
14798
- const parent = path84[path84.length - 1];
14807
+ function replaceNode(key, path85, node) {
14808
+ const parent = path85[path85.length - 1];
14799
14809
  if (identity.isCollection(parent)) {
14800
14810
  parent.items[key] = node;
14801
14811
  } else if (identity.isPair(parent)) {
@@ -15405,10 +15415,10 @@ var require_Collection = __commonJS({
15405
15415
  var createNode = require_createNode();
15406
15416
  var identity = require_identity();
15407
15417
  var Node = require_Node();
15408
- function collectionFromPath(schema, path84, value) {
15418
+ function collectionFromPath(schema, path85, value) {
15409
15419
  let v = value;
15410
- for (let i = path84.length - 1; i >= 0; --i) {
15411
- const k = path84[i];
15420
+ for (let i = path85.length - 1; i >= 0; --i) {
15421
+ const k = path85[i];
15412
15422
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
15413
15423
  const a = [];
15414
15424
  a[k] = v;
@@ -15427,7 +15437,7 @@ var require_Collection = __commonJS({
15427
15437
  sourceObjects: /* @__PURE__ */ new Map()
15428
15438
  });
15429
15439
  }
15430
- var isEmptyPath = (path84) => path84 == null || typeof path84 === "object" && !!path84[Symbol.iterator]().next().done;
15440
+ var isEmptyPath = (path85) => path85 == null || typeof path85 === "object" && !!path85[Symbol.iterator]().next().done;
15431
15441
  var Collection = class extends Node.NodeBase {
15432
15442
  constructor(type, schema) {
15433
15443
  super(type);
@@ -15457,11 +15467,11 @@ var require_Collection = __commonJS({
15457
15467
  * be a Pair instance or a `{ key, value }` object, which may not have a key
15458
15468
  * that already exists in the map.
15459
15469
  */
15460
- addIn(path84, value) {
15461
- if (isEmptyPath(path84))
15470
+ addIn(path85, value) {
15471
+ if (isEmptyPath(path85))
15462
15472
  this.add(value);
15463
15473
  else {
15464
- const [key, ...rest] = path84;
15474
+ const [key, ...rest] = path85;
15465
15475
  const node = this.get(key, true);
15466
15476
  if (identity.isCollection(node))
15467
15477
  node.addIn(rest, value);
@@ -15475,8 +15485,8 @@ var require_Collection = __commonJS({
15475
15485
  * Removes a value from the collection.
15476
15486
  * @returns `true` if the item was found and removed.
15477
15487
  */
15478
- deleteIn(path84) {
15479
- const [key, ...rest] = path84;
15488
+ deleteIn(path85) {
15489
+ const [key, ...rest] = path85;
15480
15490
  if (rest.length === 0)
15481
15491
  return this.delete(key);
15482
15492
  const node = this.get(key, true);
@@ -15490,8 +15500,8 @@ var require_Collection = __commonJS({
15490
15500
  * scalar values from their surrounding node; to disable set `keepScalar` to
15491
15501
  * `true` (collections are always returned intact).
15492
15502
  */
15493
- getIn(path84, keepScalar) {
15494
- const [key, ...rest] = path84;
15503
+ getIn(path85, keepScalar) {
15504
+ const [key, ...rest] = path85;
15495
15505
  const node = this.get(key, true);
15496
15506
  if (rest.length === 0)
15497
15507
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -15509,8 +15519,8 @@ var require_Collection = __commonJS({
15509
15519
  /**
15510
15520
  * Checks if the collection includes a value with the key `key`.
15511
15521
  */
15512
- hasIn(path84) {
15513
- const [key, ...rest] = path84;
15522
+ hasIn(path85) {
15523
+ const [key, ...rest] = path85;
15514
15524
  if (rest.length === 0)
15515
15525
  return this.has(key);
15516
15526
  const node = this.get(key, true);
@@ -15520,8 +15530,8 @@ var require_Collection = __commonJS({
15520
15530
  * Sets a value in this collection. For `!!set`, `value` needs to be a
15521
15531
  * boolean to add/remove the item from the set.
15522
15532
  */
15523
- setIn(path84, value) {
15524
- const [key, ...rest] = path84;
15533
+ setIn(path85, value) {
15534
+ const [key, ...rest] = path85;
15525
15535
  if (rest.length === 0) {
15526
15536
  this.set(key, value);
15527
15537
  } else {
@@ -18036,9 +18046,9 @@ var require_Document = __commonJS({
18036
18046
  this.contents.add(value);
18037
18047
  }
18038
18048
  /** Adds a value to the document. */
18039
- addIn(path84, value) {
18049
+ addIn(path85, value) {
18040
18050
  if (assertCollection(this.contents))
18041
- this.contents.addIn(path84, value);
18051
+ this.contents.addIn(path85, value);
18042
18052
  }
18043
18053
  /**
18044
18054
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -18113,14 +18123,14 @@ var require_Document = __commonJS({
18113
18123
  * Removes a value from the document.
18114
18124
  * @returns `true` if the item was found and removed.
18115
18125
  */
18116
- deleteIn(path84) {
18117
- if (Collection.isEmptyPath(path84)) {
18126
+ deleteIn(path85) {
18127
+ if (Collection.isEmptyPath(path85)) {
18118
18128
  if (this.contents == null)
18119
18129
  return false;
18120
18130
  this.contents = null;
18121
18131
  return true;
18122
18132
  }
18123
- return assertCollection(this.contents) ? this.contents.deleteIn(path84) : false;
18133
+ return assertCollection(this.contents) ? this.contents.deleteIn(path85) : false;
18124
18134
  }
18125
18135
  /**
18126
18136
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -18135,10 +18145,10 @@ var require_Document = __commonJS({
18135
18145
  * scalar values from their surrounding node; to disable set `keepScalar` to
18136
18146
  * `true` (collections are always returned intact).
18137
18147
  */
18138
- getIn(path84, keepScalar) {
18139
- if (Collection.isEmptyPath(path84))
18148
+ getIn(path85, keepScalar) {
18149
+ if (Collection.isEmptyPath(path85))
18140
18150
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
18141
- return identity.isCollection(this.contents) ? this.contents.getIn(path84, keepScalar) : void 0;
18151
+ return identity.isCollection(this.contents) ? this.contents.getIn(path85, keepScalar) : void 0;
18142
18152
  }
18143
18153
  /**
18144
18154
  * Checks if the document includes a value with the key `key`.
@@ -18149,10 +18159,10 @@ var require_Document = __commonJS({
18149
18159
  /**
18150
18160
  * Checks if the document includes a value at `path`.
18151
18161
  */
18152
- hasIn(path84) {
18153
- if (Collection.isEmptyPath(path84))
18162
+ hasIn(path85) {
18163
+ if (Collection.isEmptyPath(path85))
18154
18164
  return this.contents !== void 0;
18155
- return identity.isCollection(this.contents) ? this.contents.hasIn(path84) : false;
18165
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path85) : false;
18156
18166
  }
18157
18167
  /**
18158
18168
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -18169,13 +18179,13 @@ var require_Document = __commonJS({
18169
18179
  * Sets a value in this document. For `!!set`, `value` needs to be a
18170
18180
  * boolean to add/remove the item from the set.
18171
18181
  */
18172
- setIn(path84, value) {
18173
- if (Collection.isEmptyPath(path84)) {
18182
+ setIn(path85, value) {
18183
+ if (Collection.isEmptyPath(path85)) {
18174
18184
  this.contents = value;
18175
18185
  } else if (this.contents == null) {
18176
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path84), value);
18186
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path85), value);
18177
18187
  } else if (assertCollection(this.contents)) {
18178
- this.contents.setIn(path84, value);
18188
+ this.contents.setIn(path85, value);
18179
18189
  }
18180
18190
  }
18181
18191
  /**
@@ -18561,10 +18571,10 @@ var require_resolve_block_map = __commonJS({
18561
18571
  let offset = bm.offset;
18562
18572
  let commentEnd = null;
18563
18573
  for (const collItem of bm.items) {
18564
- const { start, key, sep: sep10, value } = collItem;
18574
+ const { start, key, sep: sep11, value } = collItem;
18565
18575
  const keyProps = resolveProps.resolveProps(start, {
18566
18576
  indicator: "explicit-key-ind",
18567
- next: key ?? sep10?.[0],
18577
+ next: key ?? sep11?.[0],
18568
18578
  offset,
18569
18579
  onError,
18570
18580
  parentIndent: bm.indent,
@@ -18578,7 +18588,7 @@ var require_resolve_block_map = __commonJS({
18578
18588
  else if ("indent" in key && key.indent !== bm.indent)
18579
18589
  onError(offset, "BAD_INDENT", startColMsg);
18580
18590
  }
18581
- if (!keyProps.anchor && !keyProps.tag && !sep10) {
18591
+ if (!keyProps.anchor && !keyProps.tag && !sep11) {
18582
18592
  commentEnd = keyProps.end;
18583
18593
  if (keyProps.comment) {
18584
18594
  if (map.comment)
@@ -18602,7 +18612,7 @@ var require_resolve_block_map = __commonJS({
18602
18612
  ctx.atKey = false;
18603
18613
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
18604
18614
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
18605
- const valueProps = resolveProps.resolveProps(sep10 ?? [], {
18615
+ const valueProps = resolveProps.resolveProps(sep11 ?? [], {
18606
18616
  indicator: "map-value-ind",
18607
18617
  next: value,
18608
18618
  offset: keyNode.range[2],
@@ -18618,7 +18628,7 @@ var require_resolve_block_map = __commonJS({
18618
18628
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
18619
18629
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
18620
18630
  }
18621
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep10, null, valueProps, onError);
18631
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep11, null, valueProps, onError);
18622
18632
  if (ctx.schema.compat)
18623
18633
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
18624
18634
  offset = valueNode.range[2];
@@ -18709,7 +18719,7 @@ var require_resolve_end = __commonJS({
18709
18719
  let comment = "";
18710
18720
  if (end) {
18711
18721
  let hasSpace = false;
18712
- let sep10 = "";
18722
+ let sep11 = "";
18713
18723
  for (const token of end) {
18714
18724
  const { source, type } = token;
18715
18725
  switch (type) {
@@ -18723,13 +18733,13 @@ var require_resolve_end = __commonJS({
18723
18733
  if (!comment)
18724
18734
  comment = cb;
18725
18735
  else
18726
- comment += sep10 + cb;
18727
- sep10 = "";
18736
+ comment += sep11 + cb;
18737
+ sep11 = "";
18728
18738
  break;
18729
18739
  }
18730
18740
  case "newline":
18731
18741
  if (comment)
18732
- sep10 += source;
18742
+ sep11 += source;
18733
18743
  hasSpace = true;
18734
18744
  break;
18735
18745
  default:
@@ -18772,18 +18782,18 @@ var require_resolve_flow_collection = __commonJS({
18772
18782
  let offset = fc.offset + fc.start.source.length;
18773
18783
  for (let i = 0; i < fc.items.length; ++i) {
18774
18784
  const collItem = fc.items[i];
18775
- const { start, key, sep: sep10, value } = collItem;
18785
+ const { start, key, sep: sep11, value } = collItem;
18776
18786
  const props = resolveProps.resolveProps(start, {
18777
18787
  flow: fcName,
18778
18788
  indicator: "explicit-key-ind",
18779
- next: key ?? sep10?.[0],
18789
+ next: key ?? sep11?.[0],
18780
18790
  offset,
18781
18791
  onError,
18782
18792
  parentIndent: fc.indent,
18783
18793
  startOnNewline: false
18784
18794
  });
18785
18795
  if (!props.found) {
18786
- if (!props.anchor && !props.tag && !sep10 && !value) {
18796
+ if (!props.anchor && !props.tag && !sep11 && !value) {
18787
18797
  if (i === 0 && props.comma)
18788
18798
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
18789
18799
  else if (i < fc.items.length - 1)
@@ -18837,8 +18847,8 @@ var require_resolve_flow_collection = __commonJS({
18837
18847
  }
18838
18848
  }
18839
18849
  }
18840
- if (!isMap && !sep10 && !props.found) {
18841
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep10, null, props, onError);
18850
+ if (!isMap && !sep11 && !props.found) {
18851
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep11, null, props, onError);
18842
18852
  coll.items.push(valueNode);
18843
18853
  offset = valueNode.range[2];
18844
18854
  if (isBlock(value))
@@ -18850,7 +18860,7 @@ var require_resolve_flow_collection = __commonJS({
18850
18860
  if (isBlock(key))
18851
18861
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
18852
18862
  ctx.atKey = false;
18853
- const valueProps = resolveProps.resolveProps(sep10 ?? [], {
18863
+ const valueProps = resolveProps.resolveProps(sep11 ?? [], {
18854
18864
  flow: fcName,
18855
18865
  indicator: "map-value-ind",
18856
18866
  next: value,
@@ -18861,8 +18871,8 @@ var require_resolve_flow_collection = __commonJS({
18861
18871
  });
18862
18872
  if (valueProps.found) {
18863
18873
  if (!isMap && !props.found && ctx.options.strict) {
18864
- if (sep10)
18865
- for (const st of sep10) {
18874
+ if (sep11)
18875
+ for (const st of sep11) {
18866
18876
  if (st === valueProps.found)
18867
18877
  break;
18868
18878
  if (st.type === "newline") {
@@ -18879,7 +18889,7 @@ var require_resolve_flow_collection = __commonJS({
18879
18889
  else
18880
18890
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
18881
18891
  }
18882
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep10, null, valueProps, onError) : null;
18892
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep11, null, valueProps, onError) : null;
18883
18893
  if (valueNode) {
18884
18894
  if (isBlock(value))
18885
18895
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -19059,7 +19069,7 @@ var require_resolve_block_scalar = __commonJS({
19059
19069
  chompStart = i + 1;
19060
19070
  }
19061
19071
  let value = "";
19062
- let sep10 = "";
19072
+ let sep11 = "";
19063
19073
  let prevMoreIndented = false;
19064
19074
  for (let i = 0; i < contentStart; ++i)
19065
19075
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -19076,24 +19086,24 @@ var require_resolve_block_scalar = __commonJS({
19076
19086
  indent = "";
19077
19087
  }
19078
19088
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
19079
- value += sep10 + indent.slice(trimIndent) + content;
19080
- sep10 = "\n";
19089
+ value += sep11 + indent.slice(trimIndent) + content;
19090
+ sep11 = "\n";
19081
19091
  } else if (indent.length > trimIndent || content[0] === " ") {
19082
- if (sep10 === " ")
19083
- sep10 = "\n";
19084
- else if (!prevMoreIndented && sep10 === "\n")
19085
- sep10 = "\n\n";
19086
- value += sep10 + indent.slice(trimIndent) + content;
19087
- sep10 = "\n";
19092
+ if (sep11 === " ")
19093
+ sep11 = "\n";
19094
+ else if (!prevMoreIndented && sep11 === "\n")
19095
+ sep11 = "\n\n";
19096
+ value += sep11 + indent.slice(trimIndent) + content;
19097
+ sep11 = "\n";
19088
19098
  prevMoreIndented = true;
19089
19099
  } else if (content === "") {
19090
- if (sep10 === "\n")
19100
+ if (sep11 === "\n")
19091
19101
  value += "\n";
19092
19102
  else
19093
- sep10 = "\n";
19103
+ sep11 = "\n";
19094
19104
  } else {
19095
- value += sep10 + content;
19096
- sep10 = " ";
19105
+ value += sep11 + content;
19106
+ sep11 = " ";
19097
19107
  prevMoreIndented = false;
19098
19108
  }
19099
19109
  }
@@ -19275,25 +19285,25 @@ var require_resolve_flow_scalar = __commonJS({
19275
19285
  if (!match)
19276
19286
  return source;
19277
19287
  let res = match[1];
19278
- let sep10 = " ";
19288
+ let sep11 = " ";
19279
19289
  let pos = first.lastIndex;
19280
19290
  line4.lastIndex = pos;
19281
19291
  while (match = line4.exec(source)) {
19282
19292
  if (match[1] === "") {
19283
- if (sep10 === "\n")
19284
- res += sep10;
19293
+ if (sep11 === "\n")
19294
+ res += sep11;
19285
19295
  else
19286
- sep10 = "\n";
19296
+ sep11 = "\n";
19287
19297
  } else {
19288
- res += sep10 + match[1];
19289
- sep10 = " ";
19298
+ res += sep11 + match[1];
19299
+ sep11 = " ";
19290
19300
  }
19291
19301
  pos = line4.lastIndex;
19292
19302
  }
19293
19303
  const last = /[ \t]*(.*)/sy;
19294
19304
  last.lastIndex = pos;
19295
19305
  match = last.exec(source);
19296
- return res + sep10 + (match?.[1] ?? "");
19306
+ return res + sep11 + (match?.[1] ?? "");
19297
19307
  }
19298
19308
  function doubleQuotedValue(source, onError) {
19299
19309
  let res = "";
@@ -20103,14 +20113,14 @@ var require_cst_stringify = __commonJS({
20103
20113
  }
20104
20114
  }
20105
20115
  }
20106
- function stringifyItem({ start, key, sep: sep10, value }) {
20116
+ function stringifyItem({ start, key, sep: sep11, value }) {
20107
20117
  let res = "";
20108
20118
  for (const st of start)
20109
20119
  res += st.source;
20110
20120
  if (key)
20111
20121
  res += stringifyToken(key);
20112
- if (sep10)
20113
- for (const st of sep10)
20122
+ if (sep11)
20123
+ for (const st of sep11)
20114
20124
  res += st.source;
20115
20125
  if (value)
20116
20126
  res += stringifyToken(value);
@@ -20135,9 +20145,9 @@ var require_cst_visit = __commonJS({
20135
20145
  visit.BREAK = BREAK;
20136
20146
  visit.SKIP = SKIP;
20137
20147
  visit.REMOVE = REMOVE;
20138
- visit.itemAtPath = (cst, path84) => {
20148
+ visit.itemAtPath = (cst, path85) => {
20139
20149
  let item = cst;
20140
- for (const [field, index] of path84) {
20150
+ for (const [field, index] of path85) {
20141
20151
  const tok = item?.[field];
20142
20152
  if (tok && "items" in tok) {
20143
20153
  item = tok.items[index];
@@ -20146,23 +20156,23 @@ var require_cst_visit = __commonJS({
20146
20156
  }
20147
20157
  return item;
20148
20158
  };
20149
- visit.parentCollection = (cst, path84) => {
20150
- const parent = visit.itemAtPath(cst, path84.slice(0, -1));
20151
- const field = path84[path84.length - 1][0];
20159
+ visit.parentCollection = (cst, path85) => {
20160
+ const parent = visit.itemAtPath(cst, path85.slice(0, -1));
20161
+ const field = path85[path85.length - 1][0];
20152
20162
  const coll = parent?.[field];
20153
20163
  if (coll && "items" in coll)
20154
20164
  return coll;
20155
20165
  throw new Error("Parent collection not found");
20156
20166
  };
20157
- function _visit(path84, item, visitor) {
20158
- let ctrl = visitor(item, path84);
20167
+ function _visit(path85, item, visitor) {
20168
+ let ctrl = visitor(item, path85);
20159
20169
  if (typeof ctrl === "symbol")
20160
20170
  return ctrl;
20161
20171
  for (const field of ["key", "value"]) {
20162
20172
  const token = item[field];
20163
20173
  if (token && "items" in token) {
20164
20174
  for (let i = 0; i < token.items.length; ++i) {
20165
- const ci = _visit(Object.freeze(path84.concat([[field, i]])), token.items[i], visitor);
20175
+ const ci = _visit(Object.freeze(path85.concat([[field, i]])), token.items[i], visitor);
20166
20176
  if (typeof ci === "number")
20167
20177
  i = ci - 1;
20168
20178
  else if (ci === BREAK)
@@ -20173,10 +20183,10 @@ var require_cst_visit = __commonJS({
20173
20183
  }
20174
20184
  }
20175
20185
  if (typeof ctrl === "function" && field === "key")
20176
- ctrl = ctrl(item, path84);
20186
+ ctrl = ctrl(item, path85);
20177
20187
  }
20178
20188
  }
20179
- return typeof ctrl === "function" ? ctrl(item, path84) : ctrl;
20189
+ return typeof ctrl === "function" ? ctrl(item, path85) : ctrl;
20180
20190
  }
20181
20191
  exports.visit = visit;
20182
20192
  }
@@ -21277,18 +21287,18 @@ var require_parser = __commonJS({
21277
21287
  if (this.type === "map-value-ind") {
21278
21288
  const prev = getPrevProps(this.peek(2));
21279
21289
  const start = getFirstKeyStartProps(prev);
21280
- let sep10;
21290
+ let sep11;
21281
21291
  if (scalar.end) {
21282
- sep10 = scalar.end;
21283
- sep10.push(this.sourceToken);
21292
+ sep11 = scalar.end;
21293
+ sep11.push(this.sourceToken);
21284
21294
  delete scalar.end;
21285
21295
  } else
21286
- sep10 = [this.sourceToken];
21296
+ sep11 = [this.sourceToken];
21287
21297
  const map = {
21288
21298
  type: "block-map",
21289
21299
  offset: scalar.offset,
21290
21300
  indent: scalar.indent,
21291
- items: [{ start, key: scalar, sep: sep10 }]
21301
+ items: [{ start, key: scalar, sep: sep11 }]
21292
21302
  };
21293
21303
  this.onKeyLine = true;
21294
21304
  this.stack[this.stack.length - 1] = map;
@@ -21441,15 +21451,15 @@ var require_parser = __commonJS({
21441
21451
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
21442
21452
  const start2 = getFirstKeyStartProps(it.start);
21443
21453
  const key = it.key;
21444
- const sep10 = it.sep;
21445
- sep10.push(this.sourceToken);
21454
+ const sep11 = it.sep;
21455
+ sep11.push(this.sourceToken);
21446
21456
  delete it.key;
21447
21457
  delete it.sep;
21448
21458
  this.stack.push({
21449
21459
  type: "block-map",
21450
21460
  offset: this.offset,
21451
21461
  indent: this.indent,
21452
- items: [{ start: start2, key, sep: sep10 }]
21462
+ items: [{ start: start2, key, sep: sep11 }]
21453
21463
  });
21454
21464
  } else if (start.length > 0) {
21455
21465
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -21643,13 +21653,13 @@ var require_parser = __commonJS({
21643
21653
  const prev = getPrevProps(parent);
21644
21654
  const start = getFirstKeyStartProps(prev);
21645
21655
  fixFlowSeqItems(fc);
21646
- const sep10 = fc.end.splice(1, fc.end.length);
21647
- sep10.push(this.sourceToken);
21656
+ const sep11 = fc.end.splice(1, fc.end.length);
21657
+ sep11.push(this.sourceToken);
21648
21658
  const map = {
21649
21659
  type: "block-map",
21650
21660
  offset: fc.offset,
21651
21661
  indent: fc.indent,
21652
- items: [{ start, key: fc, sep: sep10 }]
21662
+ items: [{ start, key: fc, sep: sep11 }]
21653
21663
  };
21654
21664
  this.onKeyLine = true;
21655
21665
  this.stack[this.stack.length - 1] = map;
@@ -21950,11 +21960,11 @@ function parseSkillFrontmatter(content) {
21950
21960
  };
21951
21961
  }
21952
21962
  }
21953
- function hard(path84, field, reason) {
21954
- return { path: path84, field, reason, severity: "error" };
21963
+ function hard(path85, field, reason) {
21964
+ return { path: path85, field, reason, severity: "error" };
21955
21965
  }
21956
- function warn(path84, field, reason) {
21957
- return { path: path84, field, reason, severity: "warn" };
21966
+ function warn(path85, field, reason) {
21967
+ return { path: path85, field, reason, severity: "warn" };
21958
21968
  }
21959
21969
  function validateSkillFrontmatter(skillDir) {
21960
21970
  const errors2 = [];
@@ -22956,7 +22966,7 @@ async function respondAsBackground(targetAgentId, fromId, message, opts) {
22956
22966
  return awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, opts?.signal);
22957
22967
  }
22958
22968
  function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
22959
- return new Promise((resolve22) => {
22969
+ return new Promise((resolve23) => {
22960
22970
  const deadline = Date.now() + timeoutMs;
22961
22971
  let settled = false;
22962
22972
  let timer;
@@ -22970,7 +22980,7 @@ function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
22970
22980
  const set2 = pendingRepliesByTarget.get(targetAgentId);
22971
22981
  set2?.delete(corrId);
22972
22982
  if (set2 && set2.size === 0) pendingRepliesByTarget.delete(targetAgentId);
22973
- resolve22(result4);
22983
+ resolve23(result4);
22974
22984
  };
22975
22985
  timer = setTimeout(() => finish({ ok: false, corrId, timedOut: true }), timeoutMs);
22976
22986
  if (signal) {
@@ -27138,7 +27148,7 @@ var require_compile = __commonJS({
27138
27148
  const schOrFunc = root.refs[ref];
27139
27149
  if (schOrFunc)
27140
27150
  return schOrFunc;
27141
- let _sch = resolve22.call(this, root, ref);
27151
+ let _sch = resolve23.call(this, root, ref);
27142
27152
  if (_sch === void 0) {
27143
27153
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
27144
27154
  const { schemaId } = this.opts;
@@ -27165,7 +27175,7 @@ var require_compile = __commonJS({
27165
27175
  function sameSchemaEnv(s1, s2) {
27166
27176
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
27167
27177
  }
27168
- function resolve22(root, ref) {
27178
+ function resolve23(root, ref) {
27169
27179
  let sch;
27170
27180
  while (typeof (sch = this.refs[ref]) == "string")
27171
27181
  ref = sch;
@@ -27383,8 +27393,8 @@ var require_utils = __commonJS({
27383
27393
  }
27384
27394
  return ind;
27385
27395
  }
27386
- function removeDotSegments(path84) {
27387
- let input = path84;
27396
+ function removeDotSegments(path85) {
27397
+ let input = path85;
27388
27398
  const output = [];
27389
27399
  let nextSlash = -1;
27390
27400
  let len = 0;
@@ -27636,8 +27646,8 @@ var require_schemes = __commonJS({
27636
27646
  wsComponent.secure = void 0;
27637
27647
  }
27638
27648
  if (wsComponent.resourceName) {
27639
- const [path84, query] = wsComponent.resourceName.split("?");
27640
- wsComponent.path = path84 && path84 !== "/" ? path84 : void 0;
27649
+ const [path85, query] = wsComponent.resourceName.split("?");
27650
+ wsComponent.path = path85 && path85 !== "/" ? path85 : void 0;
27641
27651
  wsComponent.query = query;
27642
27652
  wsComponent.resourceName = void 0;
27643
27653
  }
@@ -27796,7 +27806,7 @@ var require_fast_uri = __commonJS({
27796
27806
  }
27797
27807
  return uri;
27798
27808
  }
27799
- function resolve22(baseURI, relativeURI, options) {
27809
+ function resolve23(baseURI, relativeURI, options) {
27800
27810
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
27801
27811
  const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
27802
27812
  schemelessOptions.skipEscape = true;
@@ -28054,7 +28064,7 @@ var require_fast_uri = __commonJS({
28054
28064
  var fastUri = {
28055
28065
  SCHEMES,
28056
28066
  normalize: normalize2,
28057
- resolve: resolve22,
28067
+ resolve: resolve23,
28058
28068
  resolveComponent,
28059
28069
  equal,
28060
28070
  serialize,
@@ -31541,7 +31551,7 @@ ${input.prompt}` : input.prompt;
31541
31551
  );
31542
31552
  } catch {
31543
31553
  }
31544
- await new Promise((resolve22) => setTimeout(resolve22, DEFAULT_LIVE_SESSION.yieldPollIntervalMs));
31554
+ await new Promise((resolve23) => setTimeout(resolve23, DEFAULT_LIVE_SESSION.yieldPollIntervalMs));
31545
31555
  if (customToolYieldResolved && customToolYieldResult) {
31546
31556
  yieldResult = customToolYieldResult;
31547
31557
  } else if (collectedJsonEvents) {
@@ -31585,7 +31595,7 @@ ${input.prompt}` : input.prompt;
31585
31595
  }
31586
31596
  }
31587
31597
  const pollInterval = DEFAULT_LIVE_SESSION.yieldPollIntervalMs;
31588
- await new Promise((resolve22) => setTimeout(resolve22, pollInterval));
31598
+ await new Promise((resolve23) => setTimeout(resolve23, pollInterval));
31589
31599
  if (customToolYieldResolved && customToolYieldResult) {
31590
31600
  yieldResult = customToolYieldResult;
31591
31601
  break;
@@ -33005,13 +33015,13 @@ var init_checkpoint = __esm({
33005
33015
  import * as fs44 from "node:fs";
33006
33016
  import * as path36 from "node:path";
33007
33017
  function registerRunPromise(runId) {
33008
- let resolve22;
33018
+ let resolve23;
33009
33019
  let reject;
33010
33020
  const promise = new Promise((res, rej) => {
33011
- resolve22 = res;
33021
+ resolve23 = res;
33012
33022
  reject = rej;
33013
33023
  });
33014
- const entry = { promise, resolve: resolve22, reject };
33024
+ const entry = { promise, resolve: resolve23, reject };
33015
33025
  activeRunPromises.set(runId, entry);
33016
33026
  return entry;
33017
33027
  }
@@ -33255,17 +33265,17 @@ function confidenceToThreshold(confidence) {
33255
33265
  }
33256
33266
  function recordSkillActivation(cwd, activation) {
33257
33267
  ensureSkillMetricsDir(cwd, activation.runId);
33258
- const path84 = getSkillActivationsPath(cwd, activation.runId);
33268
+ const path85 = getSkillActivationsPath(cwd, activation.runId);
33259
33269
  const line4 = JSON.stringify(activation) + "\n";
33260
- writeFileSync6(path84, line4, { flag: "a", encoding: "utf-8" });
33270
+ writeFileSync6(path85, line4, { flag: "a", encoding: "utf-8" });
33261
33271
  return activation;
33262
33272
  }
33263
33273
  function getSkillActivations(cwd, runId) {
33264
- const path84 = getSkillActivationsPath(cwd, runId);
33265
- if (!existsSync32(path84)) {
33274
+ const path85 = getSkillActivationsPath(cwd, runId);
33275
+ if (!existsSync32(path85)) {
33266
33276
  return [];
33267
33277
  }
33268
- const content = readFileSync30(path84, "utf-8");
33278
+ const content = readFileSync30(path85, "utf-8");
33269
33279
  if (!content.trim()) {
33270
33280
  return [];
33271
33281
  }
@@ -35505,11 +35515,11 @@ function resolveSchemaKey(schema, key) {
35505
35515
  childSchema: childSchemas[0]
35506
35516
  };
35507
35517
  }
35508
- function findUnknownConfigKeyPaths(value, schema, depth = 0, path84 = []) {
35518
+ function findUnknownConfigKeyPaths(value, schema, depth = 0, path85 = []) {
35509
35519
  if (!isRecord2(value) || depth > MAX_CONFIG_KEY_DEPTH) return [];
35510
35520
  const unknownPaths = [];
35511
35521
  for (const [key, childValue] of Object.entries(value)) {
35512
- const childPath = [...path84, key];
35522
+ const childPath = [...path85, key];
35513
35523
  const resolution = resolveSchemaKey(schema, key);
35514
35524
  if (!resolution.allowed) {
35515
35525
  unknownPaths.push(childPath);
@@ -35521,8 +35531,8 @@ function findUnknownConfigKeyPaths(value, schema, depth = 0, path84 = []) {
35521
35531
  }
35522
35532
  return unknownPaths;
35523
35533
  }
35524
- function isAgentOverrideKeyPath(path84) {
35525
- return path84.length === 4 && path84[0] === "agents" && path84[1] === "overrides";
35534
+ function isAgentOverrideKeyPath(path85) {
35535
+ return path85.length === 4 && path85[0] === "agents" && path85[1] === "overrides";
35526
35536
  }
35527
35537
  function extractConfigReferences(config) {
35528
35538
  const agents = /* @__PURE__ */ new Set();
@@ -36707,10 +36717,10 @@ var init_goal_state_store = __esm({
36707
36717
  }
36708
36718
  /** Load a goal by id. Returns undefined if missing/corrupt. Throws on unsafe goalId (§0c C10). */
36709
36719
  load(goalId) {
36710
- const path84 = goalFilePath(this.cwd, goalId);
36720
+ const path85 = goalFilePath(this.cwd, goalId);
36711
36721
  try {
36712
- if (!existsSync39(path84)) return void 0;
36713
- const raw = readFileSync36(path84, "utf-8");
36722
+ if (!existsSync39(path85)) return void 0;
36723
+ const raw = readFileSync36(path85, "utf-8");
36714
36724
  const parsed = JSON.parse(raw);
36715
36725
  if (!parsed || typeof parsed !== "object" || typeof parsed.goalId !== "string") return void 0;
36716
36726
  return parsed;
@@ -36721,11 +36731,11 @@ var init_goal_state_store = __esm({
36721
36731
  /** Atomically persist a goal state. Emits a goal.state_changed event if eventsPath given. */
36722
36732
  save(state, eventsPath) {
36723
36733
  assertSafePathId("goalId", state.goalId);
36724
- const path84 = goalFilePath(this.cwd, state.goalId);
36734
+ const path85 = goalFilePath(this.cwd, state.goalId);
36725
36735
  const next = { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
36726
36736
  try {
36727
- mkdirSync23(dirname22(path84), { recursive: true });
36728
- atomicWriteJson(path84, next);
36737
+ mkdirSync23(dirname22(path85), { recursive: true });
36738
+ atomicWriteJson(path85, next);
36729
36739
  if (eventsPath) {
36730
36740
  appendEvent(eventsPath, {
36731
36741
  type: "goal.state_changed",
@@ -36822,9 +36832,9 @@ var init_goal_state_store = __esm({
36822
36832
  /** Remove a goal file (used by `goal clear`). Returns true if deleted. */
36823
36833
  remove(goalId) {
36824
36834
  try {
36825
- const path84 = goalFilePath(this.cwd, goalId);
36826
- if (!existsSync39(path84)) return false;
36827
- unlinkSync7(path84);
36835
+ const path85 = goalFilePath(this.cwd, goalId);
36836
+ if (!existsSync39(path85)) return false;
36837
+ unlinkSync7(path85);
36828
36838
  return true;
36829
36839
  } catch (error) {
36830
36840
  logInternalError("goal-state-store.remove", error, `goalId=${goalId}`);
@@ -40859,6 +40869,14 @@ var init_render_coalescer = __esm({
40859
40869
  this.#timerId = null;
40860
40870
  }
40861
40871
  this.#pending = false;
40872
+ const dropped = this.#dropped;
40873
+ this.#dropped = 0;
40874
+ if (dropped > 0) {
40875
+ try {
40876
+ this.#onDrop(dropped);
40877
+ } catch {
40878
+ }
40879
+ }
40862
40880
  this.#callback();
40863
40881
  }
40864
40882
  /** Check if a render is pending. */
@@ -44016,8 +44034,6 @@ function updateCrewWidget(ctx, state, config, manifestCache2, snapshotCache, pre
44016
44034
  requestRender(ctx);
44017
44035
  }
44018
44036
  function stopCrewWidget(ctx, state, config) {
44019
- if (state.interval) clearInterval(state.interval);
44020
- state.interval = void 0;
44021
44037
  if (ctx?.hasUI) {
44022
44038
  const placement = config?.widgetPlacement ?? DEFAULT_UI.widgetPlacement;
44023
44039
  ctx.ui.setStatus(STATUS_KEY, void 0);
@@ -44088,7 +44104,7 @@ var init_widget = __esm({
44088
44104
  ).join("|");
44089
44105
  const hasRunning = runs.some((entry) => entry.agents.some((a) => a.status === "running")) || [...listLiveAgents()].some((h) => h.status === "running");
44090
44106
  const animation = hasRunning ? `:spin=${spinnerBucket()}` : "";
44091
- return runs.map(
44107
+ const sig = runs.map(
44092
44108
  (entry) => entry.snapshot?.signature ?? `${entry.run.runId}:${entry.run.status}:${entry.run.updatedAt}:` + entry.agents.map((a) => {
44093
44109
  const recentOutput = a.progress?.recentOutput.at(-1) ?? "";
44094
44110
  const progress = [
@@ -44102,6 +44118,7 @@ var init_widget = __esm({
44102
44118
  return `${a.status}:${a.startedAt}:${a.completedAt ?? ""}:${a.toolUses ?? 0}:${progress}`;
44103
44119
  }).join(",")
44104
44120
  ).join("|") + `|live:${liveSig}${animation}`;
44121
+ return sig;
44105
44122
  }
44106
44123
  colorize(lines, width) {
44107
44124
  return renderLines(
@@ -46389,8 +46406,8 @@ var init_deduplicate_stage = __esm({
46389
46406
  const cur = lines[i];
46390
46407
  if (cur !== out[out.length - 1]) out.push(cur);
46391
46408
  }
46392
- const sep10 = text.includes("\r\n") ? "\r\n" : "\n";
46393
- return out.join(sep10);
46409
+ const sep11 = text.includes("\r\n") ? "\r\n" : "\n";
46410
+ return out.join(sep11);
46394
46411
  }
46395
46412
  };
46396
46413
  DEDUPLICATE_STAGE = new DeduplicateStage();
@@ -47918,8 +47935,8 @@ async function runCoalescedTaskGroup(input) {
47918
47935
  try {
47919
47936
  await Promise.race([
47920
47937
  pendingHeartbeat,
47921
- new Promise((resolve22) => {
47922
- drainTimeout = setTimeout(resolve22, 5e3);
47938
+ new Promise((resolve23) => {
47939
+ drainTimeout = setTimeout(resolve23, 5e3);
47923
47940
  })
47924
47941
  ]);
47925
47942
  } finally {
@@ -48549,7 +48566,7 @@ import * as fs76 from "node:fs";
48549
48566
  import * as path64 from "node:path";
48550
48567
  async function detectRipgrep() {
48551
48568
  if (cachedRgCheck !== void 0) return cachedRgCheck;
48552
- return await new Promise((resolve22) => {
48569
+ return await new Promise((resolve23) => {
48553
48570
  let settled = false;
48554
48571
  try {
48555
48572
  const child = spawn4("rg", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
@@ -48561,7 +48578,7 @@ async function detectRipgrep() {
48561
48578
  if (settled) return;
48562
48579
  settled = true;
48563
48580
  cachedRgCheck = { available: false };
48564
- resolve22(cachedRgCheck);
48581
+ resolve23(cachedRgCheck);
48565
48582
  });
48566
48583
  child.on("close", (code) => {
48567
48584
  if (settled) return;
@@ -48571,13 +48588,13 @@ async function detectRipgrep() {
48571
48588
  } else {
48572
48589
  cachedRgCheck = { available: false };
48573
48590
  }
48574
- resolve22(cachedRgCheck);
48591
+ resolve23(cachedRgCheck);
48575
48592
  });
48576
48593
  } catch {
48577
48594
  if (settled) return;
48578
48595
  settled = true;
48579
48596
  cachedRgCheck = { available: false };
48580
- resolve22(cachedRgCheck);
48597
+ resolve23(cachedRgCheck);
48581
48598
  }
48582
48599
  });
48583
48600
  }
@@ -48594,7 +48611,7 @@ function reasonFor(file, keywords) {
48594
48611
  return `keyword match: ${hits.join(", ")}`;
48595
48612
  }
48596
48613
  function runRipgrep(args, cwd) {
48597
- return new Promise((resolve22, reject) => {
48614
+ return new Promise((resolve23, reject) => {
48598
48615
  let settled = false;
48599
48616
  let stdout = "";
48600
48617
  let stderr = "";
@@ -48615,7 +48632,7 @@ function runRipgrep(args, cwd) {
48615
48632
  if (settled) return;
48616
48633
  settled = true;
48617
48634
  if (code === 0 || code === 1) {
48618
- resolve22(stdout);
48635
+ resolve23(stdout);
48619
48636
  } else {
48620
48637
  reject(new Error(`rg exited ${code}: ${stderr.slice(0, 200)}`));
48621
48638
  }
@@ -50299,7 +50316,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50299
50316
  const start = Date.now();
50300
50317
  let output = "";
50301
50318
  let exitCode = null;
50302
- return new Promise((resolve22) => {
50319
+ return new Promise((resolve23) => {
50303
50320
  const shell = spawn5("sh", ["-c", command], {
50304
50321
  cwd,
50305
50322
  timeout: timeoutMs,
@@ -50313,7 +50330,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50313
50330
  });
50314
50331
  const timer = setTimeout(() => {
50315
50332
  shell.kill("SIGKILL");
50316
- resolve22({
50333
+ resolve23({
50317
50334
  exitCode: -1,
50318
50335
  output: output + "\n[TIMEOUT: Command exceeded limit]",
50319
50336
  durationMs: Date.now() - start
@@ -50324,7 +50341,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50324
50341
  shell.on("close", (code) => {
50325
50342
  clearTimer();
50326
50343
  exitCode = code;
50327
- resolve22({
50344
+ resolve23({
50328
50345
  exitCode,
50329
50346
  output: output.slice(-1e5),
50330
50347
  // Cap at 100KB
@@ -50333,7 +50350,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50333
50350
  });
50334
50351
  shell.on("error", (err2) => {
50335
50352
  clearTimer();
50336
- resolve22({
50353
+ resolve23({
50337
50354
  exitCode: -1,
50338
50355
  output: `Execution error: ${err2.message}`,
50339
50356
  durationMs: Date.now() - start
@@ -51061,115 +51078,143 @@ async function runTeamTask(input) {
51061
51078
  data: { role: task.role, model: model ?? "default" }
51062
51079
  });
51063
51080
  upsertCrewAgent(manifest, recordFromTask(manifest, task, "child-process"));
51064
- const childResult = await runChildPi({
51065
- cwd: task.cwd,
51066
- task: prompt,
51067
- agent: input.agent,
51068
- model,
51069
- signal: input.signal,
51070
- transcriptPath,
51071
- maxDepth: input.limits?.maxTaskDepth,
51072
- skillPaths,
51073
- maxTurns: input.runtimeConfig?.maxTurns,
51074
- graceTurns: input.runtimeConfig?.graceTurns,
51075
- inheritContext: input.runtimeConfig?.inheritContext,
51076
- parentContext: input.parentContext,
51077
- excludeContextBash: input.runtimeConfig?.excludeContextBash,
51078
- sessionId: manifest.sessionId,
51079
- role: task.role,
51080
- runId: manifest.runId,
51081
- agentId: task.id,
51082
- artifactsRoot: manifest.artifactsRoot,
51083
- steeringFile: resolveContainedPath(`${manifest.artifactsRoot}/steering`, `${task.id}.jsonl`),
51084
- onSpawn: (pid) => {
51085
- try {
51086
- ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-spawned", pid));
51087
- if (task.pendingSteers?.length) {
51088
- const steeringDir = `${manifest.artifactsRoot}/steering`;
51089
- void appendSteeringAsync(steeringDir, task.id, task.pendingSteers);
51090
- task.pendingSteers = [];
51091
- tasks = persistSingleTaskUpdate(manifest, tasks, task);
51092
- }
51093
- } catch (err2) {
51094
- logInternalError("task-runner.on-spawn", err2, `pid=${pid}, taskId=${task.id}`);
51095
- }
51096
- },
51097
- onLifecycleEvent: (event) => {
51098
- void appendEventAsync(manifest.eventsPath, {
51099
- type: `worker.${event.type}`,
51100
- runId: manifest.runId,
51101
- taskId: task.id,
51102
- message: `Worker lifecycle: ${event.type}${event.error ? ` error=${event.error}` : ""}${event.exitCode != null ? ` exit=${event.exitCode}` : ""}`,
51103
- data: { ...event }
51104
- }).catch(
51105
- (error2) => logInternalError("task-runner.lifecycle-event", error2, `taskId=${task.id}, type=${event.type}`)
51106
- );
51107
- },
51108
- onStdoutLine: (line4) => {
51109
- appendCrewAgentOutput(manifest, task.id, line4);
51110
- persistHeartbeat();
51111
- const contact = parseSupervisorContactFromLine(line4);
51112
- if (contact) {
51113
- recordSupervisorContact(manifest, {
51114
- runId: manifest.runId,
51115
- ...contact
51116
- });
51081
+ const taskTimeoutMs = input.runtimeConfig?.taskTimeoutMs ?? 0;
51082
+ const timeoutController = new AbortController();
51083
+ let externalAbortListener;
51084
+ if (input.signal) {
51085
+ if (input.signal.aborted) {
51086
+ timeoutController.abort(input.signal.reason);
51087
+ } else {
51088
+ externalAbortListener = () => timeoutController.abort(input.signal.reason);
51089
+ input.signal.addEventListener("abort", externalAbortListener, { once: true });
51090
+ }
51091
+ }
51092
+ let timeoutHandle;
51093
+ if (taskTimeoutMs > 0 && !timeoutController.signal.aborted) {
51094
+ timeoutHandle = setTimeout(() => {
51095
+ if (!timeoutController.signal.aborted) {
51096
+ timeoutController.abort(new Error(`Task exceeded wall-clock timeout of ${taskTimeoutMs}ms`));
51117
51097
  }
51118
- },
51119
- onJsonEvent: (event) => {
51120
- try {
51121
- appendCrewAgentEvent(manifest, task.id, event);
51122
- if (collectedJsonEvents && event && typeof event === "object" && !Array.isArray(event))
51123
- collectedJsonEvents.push(event);
51124
- if (collectedJsonEvents && collectedJsonEvents.length > 1e3) {
51125
- collectedJsonEvents.splice(0, collectedJsonEvents.length - 1e3);
51126
- }
51127
- if (event && typeof event === "object" && event.type === "message_end") {
51128
- const msg = event.message;
51129
- if (msg?.role === "assistant") {
51130
- const usage = msg.usage;
51131
- if (usage) {
51132
- task.lifetimeUsage = {
51133
- input: (task.lifetimeUsage?.input ?? 0) + (usage.input ?? 0),
51134
- output: (task.lifetimeUsage?.output ?? 0) + (usage.output ?? 0),
51135
- cacheWrite: (task.lifetimeUsage?.cacheWrite ?? 0) + (usage.cacheWrite ?? 0)
51136
- };
51137
- }
51098
+ }, taskTimeoutMs);
51099
+ timeoutHandle.unref?.();
51100
+ }
51101
+ let childResult;
51102
+ try {
51103
+ childResult = await runChildPi({
51104
+ cwd: task.cwd,
51105
+ task: prompt,
51106
+ agent: input.agent,
51107
+ model,
51108
+ signal: timeoutController.signal,
51109
+ transcriptPath,
51110
+ maxDepth: input.limits?.maxTaskDepth,
51111
+ skillPaths,
51112
+ maxTurns: input.runtimeConfig?.maxTurns,
51113
+ graceTurns: input.runtimeConfig?.graceTurns,
51114
+ inheritContext: input.runtimeConfig?.inheritContext,
51115
+ parentContext: input.parentContext,
51116
+ excludeContextBash: input.runtimeConfig?.excludeContextBash,
51117
+ sessionId: manifest.sessionId,
51118
+ role: task.role,
51119
+ runId: manifest.runId,
51120
+ agentId: task.id,
51121
+ artifactsRoot: manifest.artifactsRoot,
51122
+ steeringFile: resolveContainedPath(`${manifest.artifactsRoot}/steering`, `${task.id}.jsonl`),
51123
+ onSpawn: (pid) => {
51124
+ try {
51125
+ ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-spawned", pid));
51126
+ if (task.pendingSteers?.length) {
51127
+ const steeringDir = `${manifest.artifactsRoot}/steering`;
51128
+ void appendSteeringAsync(steeringDir, task.id, task.pendingSteers);
51129
+ task.pendingSteers = [];
51130
+ tasks = persistSingleTaskUpdate(manifest, tasks, task);
51138
51131
  }
51132
+ } catch (err2) {
51133
+ logInternalError("task-runner.on-spawn", err2, `pid=${pid}, taskId=${task.id}`);
51139
51134
  }
51140
- persistHeartbeat();
51141
- if (process.env.PI_CREW_BACKGROUND_MODE === "1" && event) {
51142
- const bgLogPath = `${manifest.stateRoot}/background.log`;
51143
- const eventLine = typeof event === "object" && !Array.isArray(event) ? JSON.stringify(event) : String(event);
51144
- void appendBackgroundLogAsync(bgLogPath, eventLine);
51145
- }
51146
- const nextProgress = applyAgentProgressEvent(
51147
- task.agentProgress ?? emptyCrewAgentProgress(),
51148
- event,
51149
- task.startedAt
51135
+ },
51136
+ onLifecycleEvent: (event) => {
51137
+ void appendEventAsync(manifest.eventsPath, {
51138
+ type: `worker.${event.type}`,
51139
+ runId: manifest.runId,
51140
+ taskId: task.id,
51141
+ message: `Worker lifecycle: ${event.type}${event.error ? ` error=${event.error}` : ""}${event.exitCode != null ? ` exit=${event.exitCode}` : ""}`,
51142
+ data: { ...event }
51143
+ }).catch(
51144
+ (error2) => logInternalError("task-runner.lifecycle-event", error2, `taskId=${task.id}, type=${event.type}`)
51150
51145
  );
51151
- task = { ...task, agentProgress: nextProgress };
51152
- tasks = updateTask(tasks, task);
51153
- const progressNow = Date.now();
51154
- if (progressNow - lastTaskProgressPersistedAt >= 500) {
51155
- tasks = persistSingleTaskUpdate(manifest, tasks, task);
51156
- lastTaskProgressPersistedAt = progressNow;
51157
- }
51158
- const bridgeEvent = bridgeEventFromJsonEvent(manifest.runId, task.id, event);
51159
- if (bridgeEvent) streamBridge?.handler(bridgeEvent);
51160
- if (input.onJsonEvent) {
51161
- input.onJsonEvent(task.id, manifest.runId, event);
51146
+ },
51147
+ onStdoutLine: (line4) => {
51148
+ appendCrewAgentOutput(manifest, task.id, line4);
51149
+ persistHeartbeat();
51150
+ const contact = parseSupervisorContactFromLine(line4);
51151
+ if (contact) {
51152
+ recordSupervisorContact(manifest, {
51153
+ runId: manifest.runId,
51154
+ ...contact
51155
+ });
51162
51156
  }
51163
- if (!finalCheckpointWritten && isFinalChildEvent(event)) {
51164
- finalCheckpointWritten = true;
51165
- ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-stdout-final"));
51157
+ },
51158
+ onJsonEvent: (event) => {
51159
+ try {
51160
+ appendCrewAgentEvent(manifest, task.id, event);
51161
+ if (collectedJsonEvents && event && typeof event === "object" && !Array.isArray(event))
51162
+ collectedJsonEvents.push(event);
51163
+ if (collectedJsonEvents && collectedJsonEvents.length > 1e3) {
51164
+ collectedJsonEvents.splice(0, collectedJsonEvents.length - 1e3);
51165
+ }
51166
+ if (event && typeof event === "object" && event.type === "message_end") {
51167
+ const msg = event.message;
51168
+ if (msg?.role === "assistant") {
51169
+ const usage = msg.usage;
51170
+ if (usage) {
51171
+ task.lifetimeUsage = {
51172
+ input: (task.lifetimeUsage?.input ?? 0) + (usage.input ?? 0),
51173
+ output: (task.lifetimeUsage?.output ?? 0) + (usage.output ?? 0),
51174
+ cacheWrite: (task.lifetimeUsage?.cacheWrite ?? 0) + (usage.cacheWrite ?? 0)
51175
+ };
51176
+ }
51177
+ }
51178
+ }
51179
+ persistHeartbeat();
51180
+ if (process.env.PI_CREW_BACKGROUND_MODE === "1" && event) {
51181
+ const bgLogPath = `${manifest.stateRoot}/background.log`;
51182
+ const eventLine = typeof event === "object" && !Array.isArray(event) ? JSON.stringify(event) : String(event);
51183
+ void appendBackgroundLogAsync(bgLogPath, eventLine);
51184
+ }
51185
+ const nextProgress = applyAgentProgressEvent(
51186
+ task.agentProgress ?? emptyCrewAgentProgress(),
51187
+ event,
51188
+ task.startedAt
51189
+ );
51190
+ task = { ...task, agentProgress: nextProgress };
51191
+ tasks = updateTask(tasks, task);
51192
+ const progressNow = Date.now();
51193
+ if (progressNow - lastTaskProgressPersistedAt >= 500) {
51194
+ tasks = persistSingleTaskUpdate(manifest, tasks, task);
51195
+ lastTaskProgressPersistedAt = progressNow;
51196
+ }
51197
+ const bridgeEvent = bridgeEventFromJsonEvent(manifest.runId, task.id, event);
51198
+ if (bridgeEvent) streamBridge?.handler(bridgeEvent);
51199
+ if (input.onJsonEvent) {
51200
+ input.onJsonEvent(task.id, manifest.runId, event);
51201
+ }
51202
+ if (!finalCheckpointWritten && isFinalChildEvent(event)) {
51203
+ finalCheckpointWritten = true;
51204
+ ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-stdout-final"));
51205
+ }
51206
+ persistChildProgress(event);
51207
+ } catch (err2) {
51208
+ logInternalError("task-runner.on-json-event", err2, `taskId=${task.id}`);
51166
51209
  }
51167
- persistChildProgress(event);
51168
- } catch (err2) {
51169
- logInternalError("task-runner.on-json-event", err2, `taskId=${task.id}`);
51170
51210
  }
51211
+ });
51212
+ } finally {
51213
+ if (timeoutHandle) clearTimeout(timeoutHandle);
51214
+ if (externalAbortListener && input.signal) {
51215
+ input.signal.removeEventListener("abort", externalAbortListener);
51171
51216
  }
51172
- });
51217
+ }
51173
51218
  const evidenceStatus = childResult.exitStatus?.cancelled ? "cancelled" : childResult.error || childResult.exitCode && childResult.exitCode !== 0 ? "failed" : "completed";
51174
51219
  terminalEvidence = [
51175
51220
  ...terminalEvidence,
@@ -54136,6 +54181,16 @@ var init_team_runner = __esm({
54136
54181
  }
54137
54182
  });
54138
54183
 
54184
+ // src/utils/guards.ts
54185
+ function errorMessage(err2) {
54186
+ return err2 instanceof Error ? err2.message : String(err2);
54187
+ }
54188
+ var init_guards = __esm({
54189
+ "src/utils/guards.ts"() {
54190
+ "use strict";
54191
+ }
54192
+ });
54193
+
54139
54194
  // src/state/run-metrics.ts
54140
54195
  function collectRunMetrics(cwd, runId) {
54141
54196
  assertSafePathId("runId", runId);
@@ -54489,19 +54544,19 @@ function parseRoot(start) {
54489
54544
  function safeJoin(...parts) {
54490
54545
  const filtered = parts.filter(Boolean);
54491
54546
  if (filtered.length === 0) return "";
54492
- const sep10 = filtered.some((p) => p.includes("\\")) ? "\\" : "/";
54547
+ const sep11 = filtered.some((p) => p.includes("\\")) ? "\\" : "/";
54493
54548
  const firstPart = filtered[0];
54494
54549
  let leading = "";
54495
- if (sep10 === "\\") {
54550
+ if (sep11 === "\\") {
54496
54551
  if (firstPart.startsWith("\\\\")) leading = "\\\\";
54497
54552
  else if (firstPart.startsWith("\\")) leading = "\\";
54498
54553
  } else if (firstPart.startsWith("/")) {
54499
54554
  leading = "/";
54500
54555
  }
54501
- const firstPartStripped = sep10 === "\\" ? firstPart.replace(/^\\{1,2}/, "") : firstPart.replace(/^\/+/, "");
54556
+ const firstPartStripped = sep11 === "\\" ? firstPart.replace(/^\\{1,2}/, "") : firstPart.replace(/^\/+/, "");
54502
54557
  const rest = filtered.slice(1);
54503
- const joined = [firstPartStripped, ...rest].filter(Boolean).join(sep10);
54504
- const collapsed = joined.replace(new RegExp(`${sep10 === "\\" ? "\\\\" : "/"}{2,}`, "g"), sep10);
54558
+ const joined = [firstPartStripped, ...rest].filter(Boolean).join(sep11);
54559
+ const collapsed = joined.replace(new RegExp(`${sep11 === "\\" ? "\\\\" : "/"}{2,}`, "g"), sep11);
54505
54560
  return leading + collapsed;
54506
54561
  }
54507
54562
  function safeDirname(p) {
@@ -54776,6 +54831,7 @@ var ChainRunner;
54776
54831
  var init_chain_runner = __esm({
54777
54832
  "src/runtime/chain-runner.ts"() {
54778
54833
  "use strict";
54834
+ init_guards();
54779
54835
  init_chain_parser();
54780
54836
  ChainRunner = class _ChainRunner {
54781
54837
  /** Maximum number of chain history entries to prevent memory leaks */
@@ -54897,13 +54953,13 @@ var init_chain_runner = __esm({
54897
54953
  });
54898
54954
  }
54899
54955
  } catch (error) {
54900
- const errorMessage = error instanceof Error ? error.message : String(error);
54956
+ const errMsg = errorMessage(error);
54901
54957
  stepResults.push({
54902
54958
  step: i + 1,
54903
54959
  name: step.name,
54904
54960
  outcome: "failure",
54905
54961
  duration: Date.now() - stepStart,
54906
- error: errorMessage
54962
+ error: errMsg
54907
54963
  });
54908
54964
  if (!spec.continueOnError && !step.continueOnError) {
54909
54965
  break;
@@ -55965,10 +56021,10 @@ var init_dwf_state_store = __esm({
55965
56021
  }
55966
56022
  /** Load the checkpoint for this run's stateRoot. Returns undefined if missing or corrupt (fresh run). */
55967
56023
  load() {
55968
- const path84 = this.path;
56024
+ const path85 = this.path;
55969
56025
  try {
55970
- if (!existsSync70(path84)) return void 0;
55971
- const raw = readFileSync64(path84, "utf-8");
56026
+ if (!existsSync70(path85)) return void 0;
56027
+ const raw = readFileSync64(path85, "utf-8");
55972
56028
  const parsed = JSON.parse(raw);
55973
56029
  if (!parsed || typeof parsed !== "object" || typeof parsed.runId !== "string") return void 0;
55974
56030
  return parsed;
@@ -55978,11 +56034,11 @@ var init_dwf_state_store = __esm({
55978
56034
  }
55979
56035
  /** Atomically persist a checkpoint state. Stamps `updatedAt` (callers need not set it). */
55980
56036
  save(state) {
55981
- const path84 = this.path;
56037
+ const path85 = this.path;
55982
56038
  const next = { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
55983
56039
  try {
55984
- mkdirSync39(dirname35(path84), { recursive: true });
55985
- atomicWriteJson(path84, next);
56040
+ mkdirSync39(dirname35(path85), { recursive: true });
56041
+ atomicWriteJson(path85, next);
55986
56042
  } catch (error) {
55987
56043
  logInternalError("dwf-state-store.save", error, `runId=${state.runId}`);
55988
56044
  throw error;
@@ -55990,10 +56046,10 @@ var init_dwf_state_store = __esm({
55990
56046
  }
55991
56047
  /** Remove the checkpoint file (after a clean completion). Best-effort; never throws. */
55992
56048
  delete() {
55993
- const path84 = this.path;
56049
+ const path85 = this.path;
55994
56050
  try {
55995
- if (!existsSync70(path84)) return;
55996
- unlinkSync10(path84);
56051
+ if (!existsSync70(path85)) return;
56052
+ unlinkSync10(path85);
55997
56053
  } catch (error) {
55998
56054
  logInternalError("dwf-state-store.delete", error);
55999
56055
  }
@@ -56025,14 +56081,14 @@ var init_semaphore = __esm({
56025
56081
  if (this.#queue.length >= _Semaphore.MAX_QUEUE) {
56026
56082
  throw new Error(`Semaphore queue full: ${this.#queue.length} waiters (max ${_Semaphore.MAX_QUEUE}); cannot acquire slot`);
56027
56083
  }
56028
- const { promise, resolve: resolve22 } = (() => {
56084
+ const { promise, resolve: resolve23 } = (() => {
56029
56085
  let res;
56030
56086
  const p = new Promise((r) => {
56031
56087
  res = r;
56032
56088
  });
56033
56089
  return { promise: p, resolve: res };
56034
56090
  })();
56035
- this.#queue.push(resolve22);
56091
+ this.#queue.push(resolve23);
56036
56092
  return promise;
56037
56093
  }
56038
56094
  release() {
@@ -57312,7 +57368,7 @@ Use workspaceMode: 'single' or run from a git repository.`,
57312
57368
  try {
57313
57369
  await assertCleanLeaderAsync(gitRoot);
57314
57370
  } catch (err2) {
57315
- const msg = err2 instanceof Error ? err2.message : String(err2);
57371
+ const msg = errorMessage(err2);
57316
57372
  return result(
57317
57373
  `${msg}
57318
57374
  Commit or stash changes before using worktree mode, or use workspaceMode: 'single'.`,
@@ -57483,7 +57539,7 @@ Commit or stash changes before using worktree mode, or use workspaceMode: 'singl
57483
57539
  tokenBudget: params.tokenBudget ?? workflow.maxTokenBudget
57484
57540
  });
57485
57541
  } catch (runnerError) {
57486
- const failureReason = runnerError instanceof Error ? runnerError.message : String(runnerError);
57542
+ const failureReason = errorMessage(runnerError);
57487
57543
  const failedManifest = {
57488
57544
  ...dwfManifest,
57489
57545
  status: "failed",
@@ -57671,13 +57727,13 @@ ${dwfResult.manifest.summary ?? ""}`,
57671
57727
  workspaceId: ctx.sessionId ?? ctx.cwd
57672
57728
  });
57673
57729
  } catch (waitError) {
57674
- const errorMessage = waitError instanceof Error ? waitError.message : String(waitError);
57730
+ const waitErrMsg = errorMessage(waitError);
57675
57731
  return result(
57676
57732
  [
57677
57733
  `pi-crew run timed out or failed: ${updatedManifest.runId}`,
57678
57734
  `Team: ${team.name}`,
57679
57735
  `Workflow: ${workflow.name}`,
57680
- `Error: ${errorMessage}`,
57736
+ `Error: ${waitErrMsg}`,
57681
57737
  "",
57682
57738
  `Check status with: team status runId=${updatedManifest.runId}`,
57683
57739
  `State: ${updatedManifest.stateRoot}`,
@@ -57781,13 +57837,13 @@ ${dwfResult.manifest.summary ?? ""}`,
57781
57837
  workspaceId: ctx.sessionId ?? ctx.cwd
57782
57838
  });
57783
57839
  } catch (waitError) {
57784
- const errorMessage = waitError instanceof Error ? waitError.message : String(waitError);
57840
+ const waitErrMsg = errorMessage(waitError);
57785
57841
  return result(
57786
57842
  [
57787
57843
  `pi-crew run timed out or failed: ${updatedManifest.runId}`,
57788
57844
  `Team: ${team.name}`,
57789
57845
  `Workflow: ${workflow.name}`,
57790
- `Error: ${errorMessage}`,
57846
+ `Error: ${waitErrMsg}`,
57791
57847
  "",
57792
57848
  `Check status with: team status runId=${updatedManifest.runId}`,
57793
57849
  `State: ${updatedManifest.stateRoot}`
@@ -57857,6 +57913,7 @@ var init_run = __esm({
57857
57913
  init_discover_teams();
57858
57914
  init_discover_workflows();
57859
57915
  init_worktree_manager();
57916
+ init_guards();
57860
57917
  init_internal_error();
57861
57918
  init_safe_paths();
57862
57919
  init_runtime_resolver();
@@ -58736,7 +58793,7 @@ function installCrewGlobalRegistry(deps) {
58736
58793
  if (!loaded) return true;
58737
58794
  return !loaded.tasks.some((t2) => t2.status === "running" || t2.status === "queued");
58738
58795
  };
58739
- while (!check()) await new Promise((resolve22) => setTimeout(resolve22, 500));
58796
+ while (!check()) await new Promise((resolve23) => setTimeout(resolve23, 500));
58740
58797
  },
58741
58798
  hasRunning: (runId) => {
58742
58799
  if (!manifestCache2) return false;
@@ -59446,26 +59503,26 @@ var init_syntax_highlight = __esm({
59446
59503
 
59447
59504
  // src/ui/transcript-cache.ts
59448
59505
  import * as fs91 from "node:fs";
59449
- function cacheKey(path84, options) {
59450
- return `${path84}:${options.full ? "full" : `tail:${options.maxTailBytes}`}`;
59506
+ function cacheKey(path85, options) {
59507
+ return `${path85}:${options.full ? "full" : `tail:${options.maxTailBytes}`}`;
59451
59508
  }
59452
- function getTranscriptCacheEntry(path84, options = {}) {
59509
+ function getTranscriptCacheEntry(path85, options = {}) {
59453
59510
  const normalized = {
59454
59511
  full: options.full === true,
59455
59512
  maxTailBytes: options.maxTailBytes ?? DEFAULT_TAIL_BYTES
59456
59513
  };
59457
- return transcriptCache.get(cacheKey(path84, normalized)) ?? transcriptCache.get(path84);
59514
+ return transcriptCache.get(cacheKey(path85, normalized)) ?? transcriptCache.get(path85);
59458
59515
  }
59459
- function readTranscriptText(path84, stat2, options) {
59516
+ function readTranscriptText(path85, stat2, options) {
59460
59517
  if (options.full || stat2.size <= options.maxTailBytes) {
59461
59518
  return {
59462
- text: fs91.readFileSync(path84, "utf-8"),
59519
+ text: fs91.readFileSync(path85, "utf-8"),
59463
59520
  bytesRead: stat2.size,
59464
59521
  truncated: false
59465
59522
  };
59466
59523
  }
59467
59524
  const bytesToRead = Math.min(stat2.size, options.maxTailBytes);
59468
- const fd = fs91.openSync(path84, "r");
59525
+ const fd = fs91.openSync(path85, "r");
59469
59526
  try {
59470
59527
  const buffer = Buffer.alloc(bytesToRead);
59471
59528
  fs91.readSync(fd, buffer, 0, bytesToRead, stat2.size - bytesToRead);
@@ -59477,16 +59534,16 @@ function readTranscriptText(path84, stat2, options) {
59477
59534
  fs91.closeSync(fd);
59478
59535
  }
59479
59536
  }
59480
- function readTranscriptLinesCached(path84, parse4, now = Date.now(), options = {}) {
59537
+ function readTranscriptLinesCached(path85, parse4, now = Date.now(), options = {}) {
59481
59538
  const normalized = {
59482
59539
  full: options.full === true,
59483
59540
  maxTailBytes: Math.max(1024, options.maxTailBytes ?? DEFAULT_TAIL_BYTES)
59484
59541
  };
59485
- const key = cacheKey(path84, normalized);
59542
+ const key = cacheKey(path85, normalized);
59486
59543
  const previous = transcriptCache.get(key);
59487
59544
  let stat2;
59488
59545
  try {
59489
- stat2 = fs91.statSync(path84);
59546
+ stat2 = fs91.statSync(path85);
59490
59547
  } catch {
59491
59548
  return previous?.lines ?? [];
59492
59549
  }
@@ -59495,10 +59552,10 @@ function readTranscriptLinesCached(path84, parse4, now = Date.now(), options = {
59495
59552
  return previous.lines;
59496
59553
  }
59497
59554
  try {
59498
- const read = readTranscriptText(path84, stat2, normalized);
59555
+ const read = readTranscriptText(path85, stat2, normalized);
59499
59556
  const lines = parse4(read.text);
59500
59557
  const entry = {
59501
- path: path84,
59558
+ path: path85,
59502
59559
  mtimeMs: stat2.mtimeMs,
59503
59560
  size: stat2.size,
59504
59561
  lines,
@@ -59961,6 +60018,9 @@ async function openLiveConversation(ctx, initialRunId, initialTaskId) {
59961
60018
  }
59962
60019
  },
59963
60020
  invalidate() {
60021
+ },
60022
+ dispose() {
60023
+ overlay.dispose();
59964
60024
  }
59965
60025
  };
59966
60026
  },
@@ -61088,7 +61148,7 @@ var init_run_dashboard = __esm({
61088
61148
  const borderFill = (count2) => new DynamicCrewBorder(this.theme).render(count2)[0];
61089
61149
  const border2 = (left, right) => `${fg("border", left)}${borderFill(borderWidth)}${fg("border", right)}`;
61090
61150
  const row = (text) => `\u2502 ${pad(truncate(text, innerWidth - 1), innerWidth - 1)}\u2502`;
61091
- const sep10 = () => border2("\u251C", "\u2524");
61151
+ const sep11 = () => border2("\u251C", "\u2524");
61092
61152
  const lines = [];
61093
61153
  if (this.showHelp) {
61094
61154
  lines.push(...new HelpOverlay(this.theme).render(width));
@@ -61098,7 +61158,7 @@ var init_run_dashboard = __esm({
61098
61158
  row(
61099
61159
  `${fg("accent", "\u2590")} ${this.theme.bold("pi-crew")} \xB7 ${this.runs.length} runs ${fg("dim", "1-6 pane \xB7 \u2191\u2193 \xB7 Enter \xB7 ? help \xB7 Esc")}`
61100
61160
  ),
61101
- sep10()
61161
+ sep11()
61102
61162
  );
61103
61163
  if (this.runs.length === 0) {
61104
61164
  lines.push(row(fg("dim", "No runs yet.")));
@@ -61146,7 +61206,7 @@ var init_run_dashboard = __esm({
61146
61206
  const agents = snap?.agents ?? agentsFor2(selectedRun, this.options.snapshotCache);
61147
61207
  const statusStr = isLikelyOrphanedActiveRun(r, agents) ? "stale" : r.status;
61148
61208
  const selectedTasks = snap?.tasks ?? readRunTasks2(r, this.options.snapshotCache);
61149
- lines.push(sep10());
61209
+ lines.push(sep11());
61150
61210
  lines.push(row(`${fg("accent", "\u25B8")} ${truncate(sanitizeLine(r.goal), innerWidth - 6)}`));
61151
61211
  const isTerminal = statusStr === "failed" || statusStr === "cancelled" || statusStr === "stopped";
61152
61212
  const reason = isTerminal ? summarizeTerminalReason(r, selectedTasks, snap?.cancellationReason) : void 0;
@@ -62135,7 +62195,7 @@ var init_mascot = __esm({
62135
62195
  tickTypewriter() {
62136
62196
  const state = this.effectState;
62137
62197
  if (state.pos === void 0) return true;
62138
- for (let i = 0; i < 6; i++) {
62198
+ for (let i = 0; i < 18; i++) {
62139
62199
  const row = Math.floor(state.pos / ARMIN_WIDTH);
62140
62200
  const x = state.pos % ARMIN_WIDTH;
62141
62201
  if (row >= ARMIN_DISPLAY_HEIGHT) return true;
@@ -62147,9 +62207,11 @@ var init_mascot = __esm({
62147
62207
  tickScanline() {
62148
62208
  const state = this.effectState;
62149
62209
  if (state.row === void 0) return true;
62150
- if (state.row >= ARMIN_DISPLAY_HEIGHT) return true;
62151
- for (let x = 0; x < ARMIN_WIDTH; x++) this.currentArminGrid[state.row][x] = this.finalArminGrid[state.row][x];
62152
- state.row++;
62210
+ for (let step = 0; step < 3; step++) {
62211
+ if (state.row >= ARMIN_DISPLAY_HEIGHT) return true;
62212
+ for (let x = 0; x < ARMIN_WIDTH; x++) this.currentArminGrid[state.row][x] = this.finalArminGrid[state.row][x];
62213
+ state.row++;
62214
+ }
62153
62215
  return false;
62154
62216
  }
62155
62217
  tickRain() {
@@ -62171,7 +62233,7 @@ var init_mascot = __esm({
62171
62233
  break;
62172
62234
  }
62173
62235
  }
62174
- drop.y++;
62236
+ drop.y += 3;
62175
62237
  if (drop.y >= 0 && drop.y < ARMIN_DISPLAY_HEIGHT) {
62176
62238
  if (targetRow >= 0 && drop.y >= targetRow) {
62177
62239
  drop.settled = ARMIN_DISPLAY_HEIGHT - targetRow;
@@ -62186,7 +62248,7 @@ var init_mascot = __esm({
62186
62248
  tickFade() {
62187
62249
  const state = this.effectState;
62188
62250
  if (!state.positions || state.idx === void 0) return true;
62189
- for (let i = 0; i < 18; i++) {
62251
+ for (let i = 0; i < 54; i++) {
62190
62252
  if (state.idx >= state.positions.length) return true;
62191
62253
  const [row, x] = state.positions[state.idx];
62192
62254
  this.currentArminGrid[row][x] = this.finalArminGrid[row][x];
@@ -62204,7 +62266,7 @@ var init_mascot = __esm({
62204
62266
  for (let row = Math.max(0, top); row <= Math.min(ARMIN_DISPLAY_HEIGHT - 1, bottom); row++) {
62205
62267
  for (let x = 0; x < ARMIN_WIDTH; x++) this.currentArminGrid[row][x] = this.finalArminGrid[row][x];
62206
62268
  }
62207
- state.expansion++;
62269
+ state.expansion += 3;
62208
62270
  return state.expansion > ARMIN_DISPLAY_HEIGHT;
62209
62271
  }
62210
62272
  tickGlitch() {
@@ -62225,7 +62287,7 @@ var init_mascot = __esm({
62225
62287
  }
62226
62288
  }
62227
62289
  }
62228
- state.phase++;
62290
+ state.phase += 3;
62229
62291
  return false;
62230
62292
  }
62231
62293
  for (let row = 0; row < ARMIN_DISPLAY_HEIGHT; row++) {
@@ -62238,7 +62300,7 @@ var init_mascot = __esm({
62238
62300
  tickDissolve() {
62239
62301
  const state = this.effectState;
62240
62302
  if (!state.positions || state.idx === void 0) return true;
62241
- for (let i = 0; i < 22; i++) {
62303
+ for (let i = 0; i < 66; i++) {
62242
62304
  if (state.idx >= state.positions.length) return true;
62243
62305
  const [row, x] = state.positions[state.idx];
62244
62306
  this.currentArminGrid[row][x] = this.finalArminGrid[row][x];
@@ -62345,8 +62407,8 @@ function formatValue2(value, id) {
62345
62407
  if (typeof value === "object") return JSON.stringify(value);
62346
62408
  return String(value);
62347
62409
  }
62348
- function getNestedValue(obj, path84) {
62349
- const keys = path84.split(".");
62410
+ function getNestedValue(obj, path85) {
62411
+ const keys = path85.split(".");
62350
62412
  let current = obj;
62351
62413
  for (const key of keys) {
62352
62414
  if (!current || typeof current !== "object") return void 0;
@@ -63486,6 +63548,7 @@ async function openTeamDashboard(ctx) {
63486
63548
  if (!ctx.hasUI) return;
63487
63549
  const deps = depsRef;
63488
63550
  if (!deps) return;
63551
+ if (deps.uiState) deps.uiState.dashboardOpen = true;
63489
63552
  const cmdCtx = ctx;
63490
63553
  for (; ; ) {
63491
63554
  const sessionId = cmdCtx.sessionManager?.getSessionId?.();
@@ -63519,7 +63582,7 @@ async function openTeamDashboard(ctx) {
63519
63582
  } : { width, maxHeight: "90%", anchor: "center", margin: 2 }
63520
63583
  }
63521
63584
  );
63522
- if (!selection) return;
63585
+ if (!selection) break;
63523
63586
  if (selection.action === "reload") continue;
63524
63587
  if (selection.action === "notifications-dismiss") {
63525
63588
  deps.dismissNotifications?.();
@@ -63613,8 +63676,9 @@ async function openTeamDashboard(ctx) {
63613
63676
  )
63614
63677
  );
63615
63678
  await notifyCommandResult(cmdCtx, commandText2(result4));
63616
- return;
63679
+ break;
63617
63680
  }
63681
+ if (deps.uiState) deps.uiState.dashboardOpen = false;
63618
63682
  }
63619
63683
  function registerTeamCommands(pi, deps) {
63620
63684
  depsRef = deps;
@@ -63992,7 +64056,7 @@ function registerTeamCommands(pi, deps) {
63992
64056
  const { AnimatedMascot: AnimatedMascot2 } = await ui();
63993
64057
  await ctx.ui.custom(
63994
64058
  (tui, theme, _keybindings, done) => new AnimatedMascot2(theme, () => done(void 0), {
63995
- frameIntervalMs: style === "armin" ? 33 : 180,
64059
+ frameIntervalMs: style === "armin" ? 100 : 180,
63996
64060
  autoCloseMs: 7e3,
63997
64061
  requestRender: () => requestRenderTarget(tui),
63998
64062
  style,
@@ -64462,7 +64526,7 @@ var init_subagent_manager = __esm({
64462
64526
  await record.promise.catch((error) => {
64463
64527
  logInternalError("subagent-manager.waitForRecord", error, `id=${id}`);
64464
64528
  });
64465
- else await new Promise((resolve22) => setTimeout(resolve22, 100));
64529
+ else await new Promise((resolve23) => setTimeout(resolve23, 100));
64466
64530
  }
64467
64531
  }
64468
64532
  setMaxConcurrent(value) {
@@ -64574,7 +64638,7 @@ var init_subagent_manager = __esm({
64574
64638
  }
64575
64639
  const loaded = loadRunManifestById(cwd, record.runId);
64576
64640
  if (!loaded) {
64577
- await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
64641
+ await new Promise((resolve23) => setTimeout(resolve23, this.pollIntervalMs));
64578
64642
  continue;
64579
64643
  }
64580
64644
  if (loaded.manifest.status === "completed") {
@@ -64607,7 +64671,7 @@ var init_subagent_manager = __esm({
64607
64671
  savePersistedSubagentRecord(cwd, record);
64608
64672
  return;
64609
64673
  }
64610
- await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
64674
+ await new Promise((resolve23) => setTimeout(resolve23, this.pollIntervalMs));
64611
64675
  }
64612
64676
  }
64613
64677
  scheduleBlockedTerminalPoll(cwd, record) {
@@ -64805,13 +64869,13 @@ function line3(text, width) {
64805
64869
  function border(left, fill, right, width) {
64806
64870
  return `${left}${fill.repeat(Math.max(0, width - 2))}${right}`;
64807
64871
  }
64808
- function readTasks3(path84) {
64872
+ function readTasks3(path85) {
64809
64873
  const parse4 = () => {
64810
- const parsed = JSON.parse(fs100.readFileSync(path84, "utf-8"));
64874
+ const parsed = JSON.parse(fs100.readFileSync(path85, "utf-8"));
64811
64875
  return Array.isArray(parsed) ? parsed : [];
64812
64876
  };
64813
64877
  try {
64814
- return readJsonFileCoalesced(path84, TASK_READ_TTL_MS3, parse4);
64878
+ return readJsonFileCoalesced(path85, TASK_READ_TTL_MS3, parse4);
64815
64879
  } catch {
64816
64880
  return [];
64817
64881
  }
@@ -65005,10 +65069,12 @@ var init_live_run_sidebar = __esm({
65005
65069
  if (isTerminal && !hasActiveAgents && !this.hasAutoClosed) {
65006
65070
  const autoCloseMs = this.config?.autoCloseDashboardMs ?? 3e3;
65007
65071
  if (autoCloseMs > 0) {
65072
+ if (this.autoCloseTimeout) clearTimeout(this.autoCloseTimeout);
65008
65073
  this.autoCloseTimeout = setTimeout(() => {
65009
65074
  this.hasAutoClosed = true;
65010
65075
  this.done(void 0);
65011
65076
  }, autoCloseMs);
65077
+ this.autoCloseTimeout?.unref();
65012
65078
  lines.push(line3(`auto-close in ${Math.round(autoCloseMs / 1e3)}s\u2026`, w));
65013
65079
  }
65014
65080
  } else if (this.autoCloseTimeout) {
@@ -66828,10 +66894,10 @@ function createMetricFileSink(opts) {
66828
66894
  const target = ensureFd(date);
66829
66895
  const line4 = `${JSON.stringify({ exportedAt: now.toISOString(), snapshots: redacted })}
66830
66896
  `;
66831
- return new Promise((resolve22) => {
66897
+ return new Promise((resolve23) => {
66832
66898
  fs103.write(target, line4, (err2) => {
66833
66899
  if (err2) logInternalError("metric-sink.asyncWrite", err2);
66834
- resolve22();
66900
+ resolve23();
66835
66901
  });
66836
66902
  });
66837
66903
  } catch (error) {
@@ -66871,6 +66937,7 @@ __export(heartbeat_watcher_exports, {
66871
66937
  HeartbeatWatcher: () => HeartbeatWatcher
66872
66938
  });
66873
66939
  import * as fs104 from "node:fs";
66940
+ import * as path81 from "node:path";
66874
66941
  var HeartbeatWatcher;
66875
66942
  var init_heartbeat_watcher = __esm({
66876
66943
  "src/runtime/heartbeat-watcher.ts"() {
@@ -66951,6 +67018,13 @@ var init_heartbeat_watcher = __esm({
66951
67018
  if (level === "dead" && isProcessAlive) {
66952
67019
  level = "stale";
66953
67020
  }
67021
+ if (level === "dead" && !isProcessAlive && loaded.manifest.artifactsRoot) {
67022
+ const resultsDir = path81.resolve(loaded.manifest.artifactsRoot, "results");
67023
+ const candidate = path81.resolve(resultsDir, `${task.id}.txt`);
67024
+ if (candidate.startsWith(resultsDir + path81.sep) && fs104.existsSync(candidate)) {
67025
+ level = "stale";
67026
+ }
67027
+ }
66954
67028
  this.opts.registry.gauge("crew.heartbeat.staleness_ms", "Heartbeat elapsed since last seen, milliseconds").set({ runId: run.runId, taskId: task.id }, Number.isFinite(elapsed2) ? elapsed2 : thresholds.deadMs);
66955
67029
  this.opts.registry.counter("crew.heartbeat.level_total", "Heartbeat classifications by level").inc({ runId: run.runId, level });
66956
67030
  const previous = this.lastLevel.get(key);
@@ -66966,12 +67040,13 @@ var init_heartbeat_watcher = __esm({
66966
67040
  elapsedMs: Number.isFinite(elapsed2) ? elapsed2 : void 0
66967
67041
  }
66968
67042
  });
67043
+ const runLabel2 = run.runId.slice(0, 8);
66969
67044
  this.opts.router.enqueue({
66970
67045
  id: `dead_${run.runId}_${task.id}`,
66971
67046
  severity: "warning",
66972
67047
  source: "heartbeat-watcher",
66973
67048
  runId: run.runId,
66974
- title: `Task ${task.id} heartbeat dead`,
67049
+ title: `[${runLabel2}] Task ${task.id} heartbeat dead`,
66975
67050
  body: "Background watcher detected a stuck worker."
66976
67051
  });
66977
67052
  this.opts.onDead?.(run.runId, task.id, Number.isFinite(elapsed2) ? elapsed2 : thresholds.deadMs);
@@ -68226,17 +68301,17 @@ function normalizeConfig(raw) {
68226
68301
  }
68227
68302
  function loadConfig2() {
68228
68303
  try {
68229
- const path84 = configPath2();
68230
- if (!existsSync76(path84)) return normalizeConfig(void 0);
68231
- return normalizeConfig(JSON.parse(readFileSync71(path84, "utf8")));
68304
+ const path85 = configPath2();
68305
+ if (!existsSync76(path85)) return normalizeConfig(void 0);
68306
+ return normalizeConfig(JSON.parse(readFileSync71(path85, "utf8")));
68232
68307
  } catch {
68233
68308
  return normalizeConfig(void 0);
68234
68309
  }
68235
68310
  }
68236
68311
  function saveConfig(config) {
68237
- const path84 = configPath2();
68238
- mkdirSync42(dirname37(path84), { recursive: true });
68239
- writeFileSync11(path84, `${JSON.stringify(normalizeConfig(config), null, 2)}
68312
+ const path85 = configPath2();
68313
+ mkdirSync42(dirname37(path85), { recursive: true });
68314
+ writeFileSync11(path85, `${JSON.stringify(normalizeConfig(config), null, 2)}
68240
68315
  `);
68241
68316
  }
68242
68317
 
@@ -69136,7 +69211,9 @@ function registerCrewVibes(pi) {
69136
69211
  });
69137
69212
  }
69138
69213
  function refreshFooter(ctx) {
69139
- if (ctx?.hasUI) safeUiCall("refresh-footer", () => requestRender(ctx));
69214
+ safeUiCall("refresh-footer", () => {
69215
+ if (ctx?.hasUI) requestRender(ctx);
69216
+ });
69140
69217
  }
69141
69218
  function publishSpeedFooter(ctx, speed = footerAnimator.value()) {
69142
69219
  if (!config.enabled || !config.speed.enabled || !config.speed.footer) {
@@ -69485,6 +69562,7 @@ function registerPiCommands(pi, ctx) {
69485
69562
  getManifestCache: ctx.getManifestCache,
69486
69563
  getRunSnapshotCache: ctx.getRunSnapshotCache,
69487
69564
  getMetricRegistry: () => ctx.observabilityState.metricRegistry,
69565
+ uiState: ctx.uiState,
69488
69566
  dismissNotifications: () => {
69489
69567
  ctx.widgetState.notificationCount = 0;
69490
69568
  if (ctx.currentCtx) {
@@ -69754,9 +69832,9 @@ function closeWatcher(watcher) {
69754
69832
  } catch {
69755
69833
  }
69756
69834
  }
69757
- function watchWithErrorHandler(path84, listener, onError) {
69835
+ function watchWithErrorHandler(path85, listener, onError) {
69758
69836
  try {
69759
- const watcher = fs95.watch(path84, listener);
69837
+ const watcher = fs95.watch(path85, listener);
69760
69838
  watcher.on("error", onError);
69761
69839
  return watcher;
69762
69840
  } catch (error) {
@@ -70797,16 +70875,15 @@ function createRunSnapshotCache(cwd, options = {}) {
70797
70875
  const scheduleRefresh = (runId) => {
70798
70876
  const existing = pendingRefreshes.get(runId);
70799
70877
  if (existing) clearTimeout(existing);
70800
- pendingRefreshes.set(
70801
- runId,
70802
- setTimeout(() => {
70803
- pendingRefreshes.delete(runId);
70804
- try {
70805
- localRefreshIfStale(runId);
70806
- } catch {
70807
- }
70808
- }, INVAL_COALESCE_MS)
70809
- );
70878
+ const timer = setTimeout(() => {
70879
+ pendingRefreshes.delete(runId);
70880
+ try {
70881
+ localRefreshIfStale(runId);
70882
+ } catch {
70883
+ }
70884
+ }, INVAL_COALESCE_MS);
70885
+ timer.unref();
70886
+ pendingRefreshes.set(runId, timer);
70810
70887
  };
70811
70888
  const unsubState = runEventBus.onChannel("run:state", (event) => {
70812
70889
  if (entries.has(event.runId)) scheduleRefresh(event.runId);
@@ -71150,9 +71227,9 @@ function validateJson(content, _filePath) {
71150
71227
  var DEFAULT_VALIDATORS = /* @__PURE__ */ new Map([["json", validateJson]]);
71151
71228
  var MAX_DEDUP_ENTRIES = 256;
71152
71229
  var seenContent = /* @__PURE__ */ new Map();
71153
- function rememberSeen(path84, content) {
71154
- if (seenContent.has(path84)) seenContent.delete(path84);
71155
- seenContent.set(path84, content);
71230
+ function rememberSeen(path85, content) {
71231
+ if (seenContent.has(path85)) seenContent.delete(path85);
71232
+ seenContent.set(path85, content);
71156
71233
  while (seenContent.size > MAX_DEDUP_ENTRIES) {
71157
71234
  const oldest = seenContent.keys().next().value;
71158
71235
  if (oldest === void 0) break;
@@ -71358,7 +71435,7 @@ init_run_maintenance();
71358
71435
  init_broker_issuer();
71359
71436
  init_crash_recovery();
71360
71437
  import * as fs105 from "node:fs";
71361
- import * as path83 from "node:path";
71438
+ import * as path84 from "node:path";
71362
71439
 
71363
71440
  // src/runtime/crew-broker.ts
71364
71441
  init_event_log();
@@ -71496,7 +71573,7 @@ import { createHash as createHash11 } from "node:crypto";
71496
71573
  import * as fsp2 from "node:fs/promises";
71497
71574
  import * as net from "node:net";
71498
71575
  import * as os17 from "node:os";
71499
- import * as path81 from "node:path";
71576
+ import * as path82 from "node:path";
71500
71577
  var DEFAULT_PATH_HASH_LEN = 8;
71501
71578
  var POSIX_SUN_PATH_BUDGET = 107;
71502
71579
  function hashSessionId(sessionId, length = DEFAULT_PATH_HASH_LEN) {
@@ -71515,7 +71592,7 @@ function getBrokerSocketPath(sessionId, platform2 = process.platform) {
71515
71592
  return `\\\\.\\pipe\\pi-crew-broker-${hash}`;
71516
71593
  }
71517
71594
  const base = process.env.XDG_RUNTIME_DIR || os17.tmpdir();
71518
- const sock = path81.join(base, `pi-crew-${hash}.sock`);
71595
+ const sock = path82.join(base, `pi-crew-${hash}.sock`);
71519
71596
  const encoded = Buffer.byteLength(sock, "utf8");
71520
71597
  if (encoded > POSIX_SUN_PATH_BUDGET) {
71521
71598
  throw new Error(
@@ -71526,7 +71603,7 @@ function getBrokerSocketPath(sessionId, platform2 = process.platform) {
71526
71603
  }
71527
71604
  async function prepareBrokerSocketDir(sockPath) {
71528
71605
  if (process.platform === "win32") return;
71529
- const dir = path81.dirname(sockPath);
71606
+ const dir = path82.dirname(sockPath);
71530
71607
  await fsp2.mkdir(dir, { recursive: true, mode: 448 });
71531
71608
  try {
71532
71609
  await fsp2.chmod(dir, 448);
@@ -71543,7 +71620,7 @@ async function removeStaleBrokerSocket(sockPath, probeTimeoutMs = 250) {
71543
71620
  throw e;
71544
71621
  }
71545
71622
  if (st.isSymbolicLink()) return "refused";
71546
- const live = await new Promise((resolve22) => {
71623
+ const live = await new Promise((resolve23) => {
71547
71624
  let settled = false;
71548
71625
  const sock = net.createConnection(sockPath);
71549
71626
  const finish = (v) => {
@@ -71553,7 +71630,7 @@ async function removeStaleBrokerSocket(sockPath, probeTimeoutMs = 250) {
71553
71630
  sock.destroy();
71554
71631
  } catch {
71555
71632
  }
71556
- resolve22(v);
71633
+ resolve23(v);
71557
71634
  };
71558
71635
  sock.once("connect", () => finish(true));
71559
71636
  sock.once("error", () => finish(false));
@@ -71670,14 +71747,14 @@ var CrewBroker = class {
71670
71747
  );
71671
71748
  });
71672
71749
  });
71673
- await new Promise((resolve22, reject) => {
71750
+ await new Promise((resolve23, reject) => {
71674
71751
  const onError = (err2) => {
71675
71752
  server.removeListener("listening", onListening);
71676
71753
  reject(err2);
71677
71754
  };
71678
71755
  const onListening = () => {
71679
71756
  server.removeListener("error", onError);
71680
- resolve22();
71757
+ resolve23();
71681
71758
  };
71682
71759
  server.once("error", onError);
71683
71760
  server.once("listening", onListening);
@@ -71749,11 +71826,11 @@ var CrewBroker = class {
71749
71826
  }
71750
71827
  this.connections.clear();
71751
71828
  if (this.server) {
71752
- await new Promise((resolve22) => {
71829
+ await new Promise((resolve23) => {
71753
71830
  const srv = this.server;
71754
- if (!srv) return resolve22();
71755
- srv.close(() => resolve22());
71756
- setTimeout(() => resolve22(), 250).unref();
71831
+ if (!srv) return resolve23();
71832
+ srv.close(() => resolve23());
71833
+ setTimeout(() => resolve23(), 250).unref();
71757
71834
  });
71758
71835
  this.server = null;
71759
71836
  }
@@ -72329,45 +72406,45 @@ var CrewBroker = class {
72329
72406
  const isTerminal = (s) => s === "completed" || s === "failed" || s === "cancelled";
72330
72407
  const start = Date.now();
72331
72408
  const interval = 200;
72332
- const pollUntilDone = () => new Promise((resolve22) => {
72409
+ const pollUntilDone = () => new Promise((resolve23) => {
72333
72410
  const tick = () => {
72334
72411
  if (conn.closed) {
72335
72412
  this.sendError(conn, id, "close", "connection closed during wait");
72336
- resolve22();
72413
+ resolve23();
72337
72414
  return;
72338
72415
  }
72339
72416
  const connRunId = conn.runId;
72340
72417
  if (!connRunId) {
72341
72418
  this.sendError(conn, id, "auth", "not authed (post-narrow)");
72342
- resolve22();
72419
+ resolve23();
72343
72420
  return;
72344
72421
  }
72345
72422
  if (Date.now() - start >= timeoutMs) {
72346
72423
  this.sendError(conn, id, "wait-timeout", `task did not reach '${targetStatus}' within ${timeoutMs}ms`);
72347
- resolve22();
72424
+ resolve23();
72348
72425
  return;
72349
72426
  }
72350
72427
  try {
72351
72428
  const loaded = loadRunManifestById(cwd, connRunId);
72352
72429
  if (!loaded) {
72353
72430
  this.sendError(conn, id, "no-manifest", `run '${conn.runId}' not found`);
72354
- resolve22();
72431
+ resolve23();
72355
72432
  return;
72356
72433
  }
72357
72434
  const task = loaded.tasks.find((t2) => t2.id === targetTaskId);
72358
72435
  if (!task) {
72359
72436
  this.sendError(conn, id, "no-task", `task '${targetTaskId}' not found`);
72360
- resolve22();
72437
+ resolve23();
72361
72438
  return;
72362
72439
  }
72363
72440
  if (task.status === targetStatus || isTerminal(targetStatus) && isTerminal(task.status)) {
72364
72441
  this.sendResult(conn, id, { taskId: task.id, status: task.status, waitedMs: Date.now() - start });
72365
- resolve22();
72442
+ resolve23();
72366
72443
  return;
72367
72444
  }
72368
72445
  } catch (err2) {
72369
72446
  this.sendError(conn, id, "wait-failed", err2.message);
72370
- resolve22();
72447
+ resolve23();
72371
72448
  return;
72372
72449
  }
72373
72450
  setTimeout(tick, interval);
@@ -72805,14 +72882,14 @@ init_defaults();
72805
72882
  init_artifact_store();
72806
72883
  init_internal_error();
72807
72884
  init_paths();
72808
- import * as path82 from "node:path";
72885
+ import * as path83 from "node:path";
72809
72886
  function runArtifactCleanup(cwd) {
72810
72887
  try {
72811
- cleanupOldArtifacts(path82.join(userCrewRoot(), DEFAULT_PATHS.state.artifactsSubdir), {
72888
+ cleanupOldArtifacts(path83.join(userCrewRoot(), DEFAULT_PATHS.state.artifactsSubdir), {
72812
72889
  maxAgeDays: DEFAULT_ARTIFACT_CLEANUP.maxAgeDays,
72813
72890
  markerFile: CLEANUP_MARKER_FILE
72814
72891
  });
72815
- cleanupOldArtifacts(path82.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.artifactsSubdir), {
72892
+ cleanupOldArtifacts(path83.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.artifactsSubdir), {
72816
72893
  maxAgeDays: DEFAULT_ARTIFACT_CLEANUP.maxAgeDays,
72817
72894
  markerFile: CLEANUP_MARKER_FILE
72818
72895
  });
@@ -72879,8 +72956,6 @@ function installSessionStartHandler(pi, ctx) {
72879
72956
  ctx.crewAutocompleteRegistered = true;
72880
72957
  registerCrewAutocomplete(extensionCtx);
72881
72958
  }
72882
- if (ctx.widgetState.interval) clearInterval(ctx.widgetState.interval);
72883
- ctx.widgetState.interval = void 0;
72884
72959
  notifyActiveRuns(extensionCtx);
72885
72960
  const currentSessionId = extractBrokerSessionId(extensionCtx);
72886
72961
  ctx.brokerController?.setSessionId(currentSessionId);
@@ -73190,7 +73265,7 @@ function setupRenderLoop(pi, ctx, extensionCtx, loadedConfig) {
73190
73265
  const snapshotCache = lastFrameSnapshotCache ?? ctx.getRunSnapshotCache(ctx.currentCtx.cwd);
73191
73266
  const manifests = lastPreloadedManifests;
73192
73267
  if (!lastPreloadedConfig) backgroundPreload();
73193
- if (ctx.uiState.liveSidebarRunId) {
73268
+ if (ctx.uiState.liveSidebarRunId || ctx.uiState.dashboardOpen) {
73194
73269
  const placement = config?.widgetPlacement ?? DEFAULT_UI.widgetPlacement;
73195
73270
  if (ctx.widgetState.lastVisibility !== "hidden" || ctx.widgetState.lastPlacement !== placement) {
73196
73271
  setExtensionWidget(ctx.currentCtx, "pi-crew", void 0, { placement });
@@ -73318,7 +73393,7 @@ function setupRenderLoop(pi, ctx, extensionCtx, loadedConfig) {
73318
73393
  try {
73319
73394
  ctx.crewRunWatchers?.closeAll();
73320
73395
  ctx.crewRunWatchers = void 0;
73321
- const crewRunsDir = path83.join(projectCrewRoot(extensionCtx.cwd), "state", "runs");
73396
+ const crewRunsDir = path84.join(projectCrewRoot(extensionCtx.cwd), "state", "runs");
73322
73397
  if (fs105.existsSync(crewRunsDir)) {
73323
73398
  ctx.crewRunWatchers = new RunWatcherRegistry();
73324
73399
  ctx.crewRunWatchers.setRootWatcher(crewRunsDir, crewRunWatcherOnChange, crewRunWatcherOnError);
@@ -73329,7 +73404,7 @@ function setupRenderLoop(pi, ctx, extensionCtx, loadedConfig) {
73329
73404
  try {
73330
73405
  ctx.userCrewWatchers?.closeAll();
73331
73406
  ctx.userCrewWatchers = void 0;
73332
- const userRunsDir = path83.join(userCrewRoot(), "state", "runs");
73407
+ const userRunsDir = path84.join(userCrewRoot(), "state", "runs");
73333
73408
  if (fs105.existsSync(userRunsDir)) {
73334
73409
  ctx.userCrewWatchers = new RunWatcherRegistry();
73335
73410
  ctx.userCrewWatchers.setRootWatcher(userRunsDir, crewRunWatcherOnChange, crewRunWatcherOnError);
@@ -74034,7 +74109,7 @@ function registerSubagentTools(pi, subagentManager, options = {}) {
74034
74109
  savePersistedSubagentRecord(ctx.cwd, current);
74035
74110
  break;
74036
74111
  }
74037
- await new Promise((resolve22) => setTimeout(resolve22, 1e3));
74112
+ await new Promise((resolve23) => setTimeout(resolve23, 1e3));
74038
74113
  current = refreshPersistedSubagentRecord(ctx, current);
74039
74114
  if (!current.runId) break;
74040
74115
  }
@@ -74610,7 +74685,7 @@ function registerPiTeams(pi) {
74610
74685
  installPiHooks(pi, ctx);
74611
74686
  installSessionLifecycleHandlers(pi, ctx);
74612
74687
  ctx.brokerController = installCrewBrokerLifecycleController(pi, ctx);
74613
- registerCleanupHandler(pi);
74688
+ registerCleanupHandler(pi, { disposeTerminalStatus: () => ctx.terminalStatus?.dispose?.() });
74614
74689
  registerCompactionGuard(pi, {
74615
74690
  foregroundControllers: ctx.foregroundControllers,
74616
74691
  foregroundTeamRunControllers: ctx.foregroundTeamRunControllers