pi-crew 0.9.47 → 0.9.49

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 (58) hide show
  1. package/AGENTS.md +18 -0
  2. package/CHANGELOG.md +132 -4
  3. package/README.md +1 -1
  4. package/dist/build-meta.json +22 -12
  5. package/dist/index.mjs +430 -388
  6. package/dist/index.mjs.map +3 -3
  7. package/docs/decisions/2026-07-24-oidc-trusted-publishing.md +112 -0
  8. package/docs/publishing.md +5 -2
  9. package/package.json +2 -2
  10. package/scripts/postinstall.mjs +43 -18
  11. package/skills/.gitkeep +0 -0
  12. package/skills/distill-persona/BUILD-NOTES.md +55 -0
  13. package/skills/distill-persona/SKILL.md +612 -0
  14. package/skills/distill-persona/UPGRADE-LOG-RESEARCH-SKILLS.md +100 -0
  15. package/skills/distill-persona/references/coverage-manifest.md +65 -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/handoff.md +42 -0
  19. package/skills/distill-persona/references/research/lesson-memory-shortcut.md +33 -0
  20. package/skills/distill-persona/references/research/r1-a-examples.md +23 -0
  21. package/skills/distill-persona/references/research/r1-b-scripts.md +26 -0
  22. package/skills/distill-persona/references/research/r1-c-human-readme.md +31 -0
  23. package/skills/distill-persona/references/research/r1-d-tests.md +28 -0
  24. package/skills/distill-persona/references/research/r1-verification.md +36 -0
  25. package/skills/distill-persona/references/research/r2-low-yield.md +26 -0
  26. package/skills/distill-persona/scripts/fidelity_eval.py +244 -0
  27. package/skills/distill-persona/scripts/validate-skill-structure.mjs +177 -0
  28. package/skills/distill-software/BUILD-NOTES.md +56 -0
  29. package/skills/distill-software/SKILL.md +302 -0
  30. package/skills/distill-software/references/handoff.md +47 -0
  31. package/skills/distill-software/scripts/code_dna.py +290 -0
  32. package/skills/research/DISTILLATION-PROCESS-CHECKLIST.md +120 -0
  33. package/skills/research/EXCAVATION-CHECKLIST.md +142 -0
  34. package/skills/research/FIDELITY.md +180 -0
  35. package/skills/research/SKILL.md +432 -0
  36. package/skills/research/references/anti-patterns.md +184 -0
  37. package/skills/research/references/fidelity.md +241 -0
  38. package/skills/research/references/handoff.md +48 -0
  39. package/skills/research/references/research-protocol.md +162 -0
  40. package/skills/research/references/source-inventory.md +135 -0
  41. package/skills/research/references/verified-models.md +163 -0
  42. package/skills/research/scripts/__pycache__/safe_io.cpython-312.pyc +0 -0
  43. package/skills/research/scripts/code_dna.py +233 -0
  44. package/skills/research/scripts/emit_run_summary.py +142 -0
  45. package/skills/research/scripts/safe_io.py +314 -0
  46. package/skills/research/scripts/source_evaluator.py +234 -0
  47. package/skills/research/scripts/validate-skill-structure.mjs +177 -0
  48. package/skills/research/scripts/verify_citations.py +225 -0
  49. package/skills/security-priority.json +28 -0
  50. package/src/config/config.ts +1 -0
  51. package/src/config/role-tools.ts +6 -3
  52. package/src/config/types.ts +8 -0
  53. package/src/runtime/background-runner.ts +11 -16
  54. package/src/runtime/heartbeat-watcher.ts +28 -1
  55. package/src/runtime/task-runner.ts +165 -119
  56. package/src/schema/config-schema.ts +1 -0
  57. package/src/utils/gh-protocol.ts +9 -8
  58. package/workflows/distill.workflow.md +198 -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;
@@ -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(),
@@ -8774,13 +8779,13 @@ var init_errors = __esm({
8774
8779
  }
8775
8780
  };
8776
8781
  errors = {
8777
- fileRead(path84, source) {
8778
- return new CrewError(ErrorCode.FileReadError, `Failed to read ${path84}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8782
+ fileRead(path85, source) {
8783
+ return new CrewError(ErrorCode.FileReadError, `Failed to read ${path85}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8779
8784
  "file system read operation"
8780
8785
  );
8781
8786
  },
8782
- fileWrite(path84, source) {
8783
- return new CrewError(ErrorCode.FileWriteError, `Failed to write ${path84}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8787
+ fileWrite(path85, source) {
8788
+ return new CrewError(ErrorCode.FileWriteError, `Failed to write ${path85}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
8784
8789
  "file system write operation"
8785
8790
  );
8786
8791
  },
@@ -10032,9 +10037,9 @@ function appendEventBuffered(eventsPath, event, bufferMs = DEFAULT_BUFFER_MS) {
10032
10037
  }
10033
10038
  return Promise.resolve(appendEvent(eventsPath, event));
10034
10039
  }
10035
- return new Promise((resolve22, reject) => {
10040
+ return new Promise((resolve23, reject) => {
10036
10041
  const queue = bufferedQueues.get(eventsPath) ?? [];
10037
- queue.push({ event, resolve: resolve22, reject });
10042
+ queue.push({ event, resolve: resolve23, reject });
10038
10043
  bufferedQueues.set(eventsPath, queue);
10039
10044
  if (!bufferedTimers.has(eventsPath)) {
10040
10045
  const timer = setTimeout(() => {
@@ -13712,8 +13717,8 @@ var init_config_patch = __esm({
13712
13717
  });
13713
13718
 
13714
13719
  // src/extension/team-tool/handle-settings.ts
13715
- function setNested(obj, path84, value) {
13716
- const keys = path84.split(".");
13720
+ function setNested(obj, path85, value) {
13721
+ const keys = path85.split(".");
13717
13722
  let target = obj;
13718
13723
  for (let i = 0; i < keys.length - 1; i++) {
13719
13724
  if (!target[keys[i]] || typeof target[keys[i]] !== "object") {
@@ -13723,8 +13728,8 @@ function setNested(obj, path84, value) {
13723
13728
  }
13724
13729
  target[keys[keys.length - 1]] = value;
13725
13730
  }
13726
- function getNested(obj, path84) {
13727
- const keys = path84.split(".");
13731
+ function getNested(obj, path85) {
13732
+ const keys = path85.split(".");
13728
13733
  let current = obj;
13729
13734
  for (const key of keys) {
13730
13735
  if (!current || typeof current !== "object") return void 0;
@@ -14398,9 +14403,9 @@ async function isLiveSessionRuntimeAvailable(timeoutMs = 1500, env = process.env
14398
14403
  try {
14399
14404
  return await Promise.race([
14400
14405
  probe(),
14401
- new Promise((resolve22) => {
14406
+ new Promise((resolve23) => {
14402
14407
  timer = setTimeout(
14403
- () => resolve22({
14408
+ () => resolve23({
14404
14409
  available: false,
14405
14410
  reason: `Timed out probing optional Pi SDK live-session runtime after ${timeoutMs}ms.`
14406
14411
  }),
@@ -14677,17 +14682,17 @@ var require_visit = __commonJS({
14677
14682
  visit.BREAK = BREAK;
14678
14683
  visit.SKIP = SKIP;
14679
14684
  visit.REMOVE = REMOVE;
14680
- function visit_(key, node, visitor, path84) {
14681
- const ctrl = callVisitor(key, node, visitor, path84);
14685
+ function visit_(key, node, visitor, path85) {
14686
+ const ctrl = callVisitor(key, node, visitor, path85);
14682
14687
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
14683
- replaceNode(key, path84, ctrl);
14684
- return visit_(key, ctrl, visitor, path84);
14688
+ replaceNode(key, path85, ctrl);
14689
+ return visit_(key, ctrl, visitor, path85);
14685
14690
  }
14686
14691
  if (typeof ctrl !== "symbol") {
14687
14692
  if (identity.isCollection(node)) {
14688
- path84 = Object.freeze(path84.concat(node));
14693
+ path85 = Object.freeze(path85.concat(node));
14689
14694
  for (let i = 0; i < node.items.length; ++i) {
14690
- const ci = visit_(i, node.items[i], visitor, path84);
14695
+ const ci = visit_(i, node.items[i], visitor, path85);
14691
14696
  if (typeof ci === "number")
14692
14697
  i = ci - 1;
14693
14698
  else if (ci === BREAK)
@@ -14698,13 +14703,13 @@ var require_visit = __commonJS({
14698
14703
  }
14699
14704
  }
14700
14705
  } else if (identity.isPair(node)) {
14701
- path84 = Object.freeze(path84.concat(node));
14702
- const ck = visit_("key", node.key, visitor, path84);
14706
+ path85 = Object.freeze(path85.concat(node));
14707
+ const ck = visit_("key", node.key, visitor, path85);
14703
14708
  if (ck === BREAK)
14704
14709
  return BREAK;
14705
14710
  else if (ck === REMOVE)
14706
14711
  node.key = null;
14707
- const cv = visit_("value", node.value, visitor, path84);
14712
+ const cv = visit_("value", node.value, visitor, path85);
14708
14713
  if (cv === BREAK)
14709
14714
  return BREAK;
14710
14715
  else if (cv === REMOVE)
@@ -14725,17 +14730,17 @@ var require_visit = __commonJS({
14725
14730
  visitAsync.BREAK = BREAK;
14726
14731
  visitAsync.SKIP = SKIP;
14727
14732
  visitAsync.REMOVE = REMOVE;
14728
- async function visitAsync_(key, node, visitor, path84) {
14729
- const ctrl = await callVisitor(key, node, visitor, path84);
14733
+ async function visitAsync_(key, node, visitor, path85) {
14734
+ const ctrl = await callVisitor(key, node, visitor, path85);
14730
14735
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
14731
- replaceNode(key, path84, ctrl);
14732
- return visitAsync_(key, ctrl, visitor, path84);
14736
+ replaceNode(key, path85, ctrl);
14737
+ return visitAsync_(key, ctrl, visitor, path85);
14733
14738
  }
14734
14739
  if (typeof ctrl !== "symbol") {
14735
14740
  if (identity.isCollection(node)) {
14736
- path84 = Object.freeze(path84.concat(node));
14741
+ path85 = Object.freeze(path85.concat(node));
14737
14742
  for (let i = 0; i < node.items.length; ++i) {
14738
- const ci = await visitAsync_(i, node.items[i], visitor, path84);
14743
+ const ci = await visitAsync_(i, node.items[i], visitor, path85);
14739
14744
  if (typeof ci === "number")
14740
14745
  i = ci - 1;
14741
14746
  else if (ci === BREAK)
@@ -14746,13 +14751,13 @@ var require_visit = __commonJS({
14746
14751
  }
14747
14752
  }
14748
14753
  } else if (identity.isPair(node)) {
14749
- path84 = Object.freeze(path84.concat(node));
14750
- const ck = await visitAsync_("key", node.key, visitor, path84);
14754
+ path85 = Object.freeze(path85.concat(node));
14755
+ const ck = await visitAsync_("key", node.key, visitor, path85);
14751
14756
  if (ck === BREAK)
14752
14757
  return BREAK;
14753
14758
  else if (ck === REMOVE)
14754
14759
  node.key = null;
14755
- const cv = await visitAsync_("value", node.value, visitor, path84);
14760
+ const cv = await visitAsync_("value", node.value, visitor, path85);
14756
14761
  if (cv === BREAK)
14757
14762
  return BREAK;
14758
14763
  else if (cv === REMOVE)
@@ -14779,23 +14784,23 @@ var require_visit = __commonJS({
14779
14784
  }
14780
14785
  return visitor;
14781
14786
  }
14782
- function callVisitor(key, node, visitor, path84) {
14787
+ function callVisitor(key, node, visitor, path85) {
14783
14788
  if (typeof visitor === "function")
14784
- return visitor(key, node, path84);
14789
+ return visitor(key, node, path85);
14785
14790
  if (identity.isMap(node))
14786
- return visitor.Map?.(key, node, path84);
14791
+ return visitor.Map?.(key, node, path85);
14787
14792
  if (identity.isSeq(node))
14788
- return visitor.Seq?.(key, node, path84);
14793
+ return visitor.Seq?.(key, node, path85);
14789
14794
  if (identity.isPair(node))
14790
- return visitor.Pair?.(key, node, path84);
14795
+ return visitor.Pair?.(key, node, path85);
14791
14796
  if (identity.isScalar(node))
14792
- return visitor.Scalar?.(key, node, path84);
14797
+ return visitor.Scalar?.(key, node, path85);
14793
14798
  if (identity.isAlias(node))
14794
- return visitor.Alias?.(key, node, path84);
14799
+ return visitor.Alias?.(key, node, path85);
14795
14800
  return void 0;
14796
14801
  }
14797
- function replaceNode(key, path84, node) {
14798
- const parent = path84[path84.length - 1];
14802
+ function replaceNode(key, path85, node) {
14803
+ const parent = path85[path85.length - 1];
14799
14804
  if (identity.isCollection(parent)) {
14800
14805
  parent.items[key] = node;
14801
14806
  } else if (identity.isPair(parent)) {
@@ -15405,10 +15410,10 @@ var require_Collection = __commonJS({
15405
15410
  var createNode = require_createNode();
15406
15411
  var identity = require_identity();
15407
15412
  var Node = require_Node();
15408
- function collectionFromPath(schema, path84, value) {
15413
+ function collectionFromPath(schema, path85, value) {
15409
15414
  let v = value;
15410
- for (let i = path84.length - 1; i >= 0; --i) {
15411
- const k = path84[i];
15415
+ for (let i = path85.length - 1; i >= 0; --i) {
15416
+ const k = path85[i];
15412
15417
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
15413
15418
  const a = [];
15414
15419
  a[k] = v;
@@ -15427,7 +15432,7 @@ var require_Collection = __commonJS({
15427
15432
  sourceObjects: /* @__PURE__ */ new Map()
15428
15433
  });
15429
15434
  }
15430
- var isEmptyPath = (path84) => path84 == null || typeof path84 === "object" && !!path84[Symbol.iterator]().next().done;
15435
+ var isEmptyPath = (path85) => path85 == null || typeof path85 === "object" && !!path85[Symbol.iterator]().next().done;
15431
15436
  var Collection = class extends Node.NodeBase {
15432
15437
  constructor(type, schema) {
15433
15438
  super(type);
@@ -15457,11 +15462,11 @@ var require_Collection = __commonJS({
15457
15462
  * be a Pair instance or a `{ key, value }` object, which may not have a key
15458
15463
  * that already exists in the map.
15459
15464
  */
15460
- addIn(path84, value) {
15461
- if (isEmptyPath(path84))
15465
+ addIn(path85, value) {
15466
+ if (isEmptyPath(path85))
15462
15467
  this.add(value);
15463
15468
  else {
15464
- const [key, ...rest] = path84;
15469
+ const [key, ...rest] = path85;
15465
15470
  const node = this.get(key, true);
15466
15471
  if (identity.isCollection(node))
15467
15472
  node.addIn(rest, value);
@@ -15475,8 +15480,8 @@ var require_Collection = __commonJS({
15475
15480
  * Removes a value from the collection.
15476
15481
  * @returns `true` if the item was found and removed.
15477
15482
  */
15478
- deleteIn(path84) {
15479
- const [key, ...rest] = path84;
15483
+ deleteIn(path85) {
15484
+ const [key, ...rest] = path85;
15480
15485
  if (rest.length === 0)
15481
15486
  return this.delete(key);
15482
15487
  const node = this.get(key, true);
@@ -15490,8 +15495,8 @@ var require_Collection = __commonJS({
15490
15495
  * scalar values from their surrounding node; to disable set `keepScalar` to
15491
15496
  * `true` (collections are always returned intact).
15492
15497
  */
15493
- getIn(path84, keepScalar) {
15494
- const [key, ...rest] = path84;
15498
+ getIn(path85, keepScalar) {
15499
+ const [key, ...rest] = path85;
15495
15500
  const node = this.get(key, true);
15496
15501
  if (rest.length === 0)
15497
15502
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -15509,8 +15514,8 @@ var require_Collection = __commonJS({
15509
15514
  /**
15510
15515
  * Checks if the collection includes a value with the key `key`.
15511
15516
  */
15512
- hasIn(path84) {
15513
- const [key, ...rest] = path84;
15517
+ hasIn(path85) {
15518
+ const [key, ...rest] = path85;
15514
15519
  if (rest.length === 0)
15515
15520
  return this.has(key);
15516
15521
  const node = this.get(key, true);
@@ -15520,8 +15525,8 @@ var require_Collection = __commonJS({
15520
15525
  * Sets a value in this collection. For `!!set`, `value` needs to be a
15521
15526
  * boolean to add/remove the item from the set.
15522
15527
  */
15523
- setIn(path84, value) {
15524
- const [key, ...rest] = path84;
15528
+ setIn(path85, value) {
15529
+ const [key, ...rest] = path85;
15525
15530
  if (rest.length === 0) {
15526
15531
  this.set(key, value);
15527
15532
  } else {
@@ -18036,9 +18041,9 @@ var require_Document = __commonJS({
18036
18041
  this.contents.add(value);
18037
18042
  }
18038
18043
  /** Adds a value to the document. */
18039
- addIn(path84, value) {
18044
+ addIn(path85, value) {
18040
18045
  if (assertCollection(this.contents))
18041
- this.contents.addIn(path84, value);
18046
+ this.contents.addIn(path85, value);
18042
18047
  }
18043
18048
  /**
18044
18049
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -18113,14 +18118,14 @@ var require_Document = __commonJS({
18113
18118
  * Removes a value from the document.
18114
18119
  * @returns `true` if the item was found and removed.
18115
18120
  */
18116
- deleteIn(path84) {
18117
- if (Collection.isEmptyPath(path84)) {
18121
+ deleteIn(path85) {
18122
+ if (Collection.isEmptyPath(path85)) {
18118
18123
  if (this.contents == null)
18119
18124
  return false;
18120
18125
  this.contents = null;
18121
18126
  return true;
18122
18127
  }
18123
- return assertCollection(this.contents) ? this.contents.deleteIn(path84) : false;
18128
+ return assertCollection(this.contents) ? this.contents.deleteIn(path85) : false;
18124
18129
  }
18125
18130
  /**
18126
18131
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -18135,10 +18140,10 @@ var require_Document = __commonJS({
18135
18140
  * scalar values from their surrounding node; to disable set `keepScalar` to
18136
18141
  * `true` (collections are always returned intact).
18137
18142
  */
18138
- getIn(path84, keepScalar) {
18139
- if (Collection.isEmptyPath(path84))
18143
+ getIn(path85, keepScalar) {
18144
+ if (Collection.isEmptyPath(path85))
18140
18145
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
18141
- return identity.isCollection(this.contents) ? this.contents.getIn(path84, keepScalar) : void 0;
18146
+ return identity.isCollection(this.contents) ? this.contents.getIn(path85, keepScalar) : void 0;
18142
18147
  }
18143
18148
  /**
18144
18149
  * Checks if the document includes a value with the key `key`.
@@ -18149,10 +18154,10 @@ var require_Document = __commonJS({
18149
18154
  /**
18150
18155
  * Checks if the document includes a value at `path`.
18151
18156
  */
18152
- hasIn(path84) {
18153
- if (Collection.isEmptyPath(path84))
18157
+ hasIn(path85) {
18158
+ if (Collection.isEmptyPath(path85))
18154
18159
  return this.contents !== void 0;
18155
- return identity.isCollection(this.contents) ? this.contents.hasIn(path84) : false;
18160
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path85) : false;
18156
18161
  }
18157
18162
  /**
18158
18163
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -18169,13 +18174,13 @@ var require_Document = __commonJS({
18169
18174
  * Sets a value in this document. For `!!set`, `value` needs to be a
18170
18175
  * boolean to add/remove the item from the set.
18171
18176
  */
18172
- setIn(path84, value) {
18173
- if (Collection.isEmptyPath(path84)) {
18177
+ setIn(path85, value) {
18178
+ if (Collection.isEmptyPath(path85)) {
18174
18179
  this.contents = value;
18175
18180
  } else if (this.contents == null) {
18176
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path84), value);
18181
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path85), value);
18177
18182
  } else if (assertCollection(this.contents)) {
18178
- this.contents.setIn(path84, value);
18183
+ this.contents.setIn(path85, value);
18179
18184
  }
18180
18185
  }
18181
18186
  /**
@@ -18561,10 +18566,10 @@ var require_resolve_block_map = __commonJS({
18561
18566
  let offset = bm.offset;
18562
18567
  let commentEnd = null;
18563
18568
  for (const collItem of bm.items) {
18564
- const { start, key, sep: sep10, value } = collItem;
18569
+ const { start, key, sep: sep11, value } = collItem;
18565
18570
  const keyProps = resolveProps.resolveProps(start, {
18566
18571
  indicator: "explicit-key-ind",
18567
- next: key ?? sep10?.[0],
18572
+ next: key ?? sep11?.[0],
18568
18573
  offset,
18569
18574
  onError,
18570
18575
  parentIndent: bm.indent,
@@ -18578,7 +18583,7 @@ var require_resolve_block_map = __commonJS({
18578
18583
  else if ("indent" in key && key.indent !== bm.indent)
18579
18584
  onError(offset, "BAD_INDENT", startColMsg);
18580
18585
  }
18581
- if (!keyProps.anchor && !keyProps.tag && !sep10) {
18586
+ if (!keyProps.anchor && !keyProps.tag && !sep11) {
18582
18587
  commentEnd = keyProps.end;
18583
18588
  if (keyProps.comment) {
18584
18589
  if (map.comment)
@@ -18602,7 +18607,7 @@ var require_resolve_block_map = __commonJS({
18602
18607
  ctx.atKey = false;
18603
18608
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
18604
18609
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
18605
- const valueProps = resolveProps.resolveProps(sep10 ?? [], {
18610
+ const valueProps = resolveProps.resolveProps(sep11 ?? [], {
18606
18611
  indicator: "map-value-ind",
18607
18612
  next: value,
18608
18613
  offset: keyNode.range[2],
@@ -18618,7 +18623,7 @@ var require_resolve_block_map = __commonJS({
18618
18623
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
18619
18624
  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
18625
  }
18621
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep10, null, valueProps, onError);
18626
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep11, null, valueProps, onError);
18622
18627
  if (ctx.schema.compat)
18623
18628
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
18624
18629
  offset = valueNode.range[2];
@@ -18709,7 +18714,7 @@ var require_resolve_end = __commonJS({
18709
18714
  let comment = "";
18710
18715
  if (end) {
18711
18716
  let hasSpace = false;
18712
- let sep10 = "";
18717
+ let sep11 = "";
18713
18718
  for (const token of end) {
18714
18719
  const { source, type } = token;
18715
18720
  switch (type) {
@@ -18723,13 +18728,13 @@ var require_resolve_end = __commonJS({
18723
18728
  if (!comment)
18724
18729
  comment = cb;
18725
18730
  else
18726
- comment += sep10 + cb;
18727
- sep10 = "";
18731
+ comment += sep11 + cb;
18732
+ sep11 = "";
18728
18733
  break;
18729
18734
  }
18730
18735
  case "newline":
18731
18736
  if (comment)
18732
- sep10 += source;
18737
+ sep11 += source;
18733
18738
  hasSpace = true;
18734
18739
  break;
18735
18740
  default:
@@ -18772,18 +18777,18 @@ var require_resolve_flow_collection = __commonJS({
18772
18777
  let offset = fc.offset + fc.start.source.length;
18773
18778
  for (let i = 0; i < fc.items.length; ++i) {
18774
18779
  const collItem = fc.items[i];
18775
- const { start, key, sep: sep10, value } = collItem;
18780
+ const { start, key, sep: sep11, value } = collItem;
18776
18781
  const props = resolveProps.resolveProps(start, {
18777
18782
  flow: fcName,
18778
18783
  indicator: "explicit-key-ind",
18779
- next: key ?? sep10?.[0],
18784
+ next: key ?? sep11?.[0],
18780
18785
  offset,
18781
18786
  onError,
18782
18787
  parentIndent: fc.indent,
18783
18788
  startOnNewline: false
18784
18789
  });
18785
18790
  if (!props.found) {
18786
- if (!props.anchor && !props.tag && !sep10 && !value) {
18791
+ if (!props.anchor && !props.tag && !sep11 && !value) {
18787
18792
  if (i === 0 && props.comma)
18788
18793
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
18789
18794
  else if (i < fc.items.length - 1)
@@ -18837,8 +18842,8 @@ var require_resolve_flow_collection = __commonJS({
18837
18842
  }
18838
18843
  }
18839
18844
  }
18840
- if (!isMap && !sep10 && !props.found) {
18841
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep10, null, props, onError);
18845
+ if (!isMap && !sep11 && !props.found) {
18846
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep11, null, props, onError);
18842
18847
  coll.items.push(valueNode);
18843
18848
  offset = valueNode.range[2];
18844
18849
  if (isBlock(value))
@@ -18850,7 +18855,7 @@ var require_resolve_flow_collection = __commonJS({
18850
18855
  if (isBlock(key))
18851
18856
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
18852
18857
  ctx.atKey = false;
18853
- const valueProps = resolveProps.resolveProps(sep10 ?? [], {
18858
+ const valueProps = resolveProps.resolveProps(sep11 ?? [], {
18854
18859
  flow: fcName,
18855
18860
  indicator: "map-value-ind",
18856
18861
  next: value,
@@ -18861,8 +18866,8 @@ var require_resolve_flow_collection = __commonJS({
18861
18866
  });
18862
18867
  if (valueProps.found) {
18863
18868
  if (!isMap && !props.found && ctx.options.strict) {
18864
- if (sep10)
18865
- for (const st of sep10) {
18869
+ if (sep11)
18870
+ for (const st of sep11) {
18866
18871
  if (st === valueProps.found)
18867
18872
  break;
18868
18873
  if (st.type === "newline") {
@@ -18879,7 +18884,7 @@ var require_resolve_flow_collection = __commonJS({
18879
18884
  else
18880
18885
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
18881
18886
  }
18882
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep10, null, valueProps, onError) : null;
18887
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep11, null, valueProps, onError) : null;
18883
18888
  if (valueNode) {
18884
18889
  if (isBlock(value))
18885
18890
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -19059,7 +19064,7 @@ var require_resolve_block_scalar = __commonJS({
19059
19064
  chompStart = i + 1;
19060
19065
  }
19061
19066
  let value = "";
19062
- let sep10 = "";
19067
+ let sep11 = "";
19063
19068
  let prevMoreIndented = false;
19064
19069
  for (let i = 0; i < contentStart; ++i)
19065
19070
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -19076,24 +19081,24 @@ var require_resolve_block_scalar = __commonJS({
19076
19081
  indent = "";
19077
19082
  }
19078
19083
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
19079
- value += sep10 + indent.slice(trimIndent) + content;
19080
- sep10 = "\n";
19084
+ value += sep11 + indent.slice(trimIndent) + content;
19085
+ sep11 = "\n";
19081
19086
  } 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";
19087
+ if (sep11 === " ")
19088
+ sep11 = "\n";
19089
+ else if (!prevMoreIndented && sep11 === "\n")
19090
+ sep11 = "\n\n";
19091
+ value += sep11 + indent.slice(trimIndent) + content;
19092
+ sep11 = "\n";
19088
19093
  prevMoreIndented = true;
19089
19094
  } else if (content === "") {
19090
- if (sep10 === "\n")
19095
+ if (sep11 === "\n")
19091
19096
  value += "\n";
19092
19097
  else
19093
- sep10 = "\n";
19098
+ sep11 = "\n";
19094
19099
  } else {
19095
- value += sep10 + content;
19096
- sep10 = " ";
19100
+ value += sep11 + content;
19101
+ sep11 = " ";
19097
19102
  prevMoreIndented = false;
19098
19103
  }
19099
19104
  }
@@ -19275,25 +19280,25 @@ var require_resolve_flow_scalar = __commonJS({
19275
19280
  if (!match)
19276
19281
  return source;
19277
19282
  let res = match[1];
19278
- let sep10 = " ";
19283
+ let sep11 = " ";
19279
19284
  let pos = first.lastIndex;
19280
19285
  line4.lastIndex = pos;
19281
19286
  while (match = line4.exec(source)) {
19282
19287
  if (match[1] === "") {
19283
- if (sep10 === "\n")
19284
- res += sep10;
19288
+ if (sep11 === "\n")
19289
+ res += sep11;
19285
19290
  else
19286
- sep10 = "\n";
19291
+ sep11 = "\n";
19287
19292
  } else {
19288
- res += sep10 + match[1];
19289
- sep10 = " ";
19293
+ res += sep11 + match[1];
19294
+ sep11 = " ";
19290
19295
  }
19291
19296
  pos = line4.lastIndex;
19292
19297
  }
19293
19298
  const last = /[ \t]*(.*)/sy;
19294
19299
  last.lastIndex = pos;
19295
19300
  match = last.exec(source);
19296
- return res + sep10 + (match?.[1] ?? "");
19301
+ return res + sep11 + (match?.[1] ?? "");
19297
19302
  }
19298
19303
  function doubleQuotedValue(source, onError) {
19299
19304
  let res = "";
@@ -20103,14 +20108,14 @@ var require_cst_stringify = __commonJS({
20103
20108
  }
20104
20109
  }
20105
20110
  }
20106
- function stringifyItem({ start, key, sep: sep10, value }) {
20111
+ function stringifyItem({ start, key, sep: sep11, value }) {
20107
20112
  let res = "";
20108
20113
  for (const st of start)
20109
20114
  res += st.source;
20110
20115
  if (key)
20111
20116
  res += stringifyToken(key);
20112
- if (sep10)
20113
- for (const st of sep10)
20117
+ if (sep11)
20118
+ for (const st of sep11)
20114
20119
  res += st.source;
20115
20120
  if (value)
20116
20121
  res += stringifyToken(value);
@@ -20135,9 +20140,9 @@ var require_cst_visit = __commonJS({
20135
20140
  visit.BREAK = BREAK;
20136
20141
  visit.SKIP = SKIP;
20137
20142
  visit.REMOVE = REMOVE;
20138
- visit.itemAtPath = (cst, path84) => {
20143
+ visit.itemAtPath = (cst, path85) => {
20139
20144
  let item = cst;
20140
- for (const [field, index] of path84) {
20145
+ for (const [field, index] of path85) {
20141
20146
  const tok = item?.[field];
20142
20147
  if (tok && "items" in tok) {
20143
20148
  item = tok.items[index];
@@ -20146,23 +20151,23 @@ var require_cst_visit = __commonJS({
20146
20151
  }
20147
20152
  return item;
20148
20153
  };
20149
- visit.parentCollection = (cst, path84) => {
20150
- const parent = visit.itemAtPath(cst, path84.slice(0, -1));
20151
- const field = path84[path84.length - 1][0];
20154
+ visit.parentCollection = (cst, path85) => {
20155
+ const parent = visit.itemAtPath(cst, path85.slice(0, -1));
20156
+ const field = path85[path85.length - 1][0];
20152
20157
  const coll = parent?.[field];
20153
20158
  if (coll && "items" in coll)
20154
20159
  return coll;
20155
20160
  throw new Error("Parent collection not found");
20156
20161
  };
20157
- function _visit(path84, item, visitor) {
20158
- let ctrl = visitor(item, path84);
20162
+ function _visit(path85, item, visitor) {
20163
+ let ctrl = visitor(item, path85);
20159
20164
  if (typeof ctrl === "symbol")
20160
20165
  return ctrl;
20161
20166
  for (const field of ["key", "value"]) {
20162
20167
  const token = item[field];
20163
20168
  if (token && "items" in token) {
20164
20169
  for (let i = 0; i < token.items.length; ++i) {
20165
- const ci = _visit(Object.freeze(path84.concat([[field, i]])), token.items[i], visitor);
20170
+ const ci = _visit(Object.freeze(path85.concat([[field, i]])), token.items[i], visitor);
20166
20171
  if (typeof ci === "number")
20167
20172
  i = ci - 1;
20168
20173
  else if (ci === BREAK)
@@ -20173,10 +20178,10 @@ var require_cst_visit = __commonJS({
20173
20178
  }
20174
20179
  }
20175
20180
  if (typeof ctrl === "function" && field === "key")
20176
- ctrl = ctrl(item, path84);
20181
+ ctrl = ctrl(item, path85);
20177
20182
  }
20178
20183
  }
20179
- return typeof ctrl === "function" ? ctrl(item, path84) : ctrl;
20184
+ return typeof ctrl === "function" ? ctrl(item, path85) : ctrl;
20180
20185
  }
20181
20186
  exports.visit = visit;
20182
20187
  }
@@ -21277,18 +21282,18 @@ var require_parser = __commonJS({
21277
21282
  if (this.type === "map-value-ind") {
21278
21283
  const prev = getPrevProps(this.peek(2));
21279
21284
  const start = getFirstKeyStartProps(prev);
21280
- let sep10;
21285
+ let sep11;
21281
21286
  if (scalar.end) {
21282
- sep10 = scalar.end;
21283
- sep10.push(this.sourceToken);
21287
+ sep11 = scalar.end;
21288
+ sep11.push(this.sourceToken);
21284
21289
  delete scalar.end;
21285
21290
  } else
21286
- sep10 = [this.sourceToken];
21291
+ sep11 = [this.sourceToken];
21287
21292
  const map = {
21288
21293
  type: "block-map",
21289
21294
  offset: scalar.offset,
21290
21295
  indent: scalar.indent,
21291
- items: [{ start, key: scalar, sep: sep10 }]
21296
+ items: [{ start, key: scalar, sep: sep11 }]
21292
21297
  };
21293
21298
  this.onKeyLine = true;
21294
21299
  this.stack[this.stack.length - 1] = map;
@@ -21441,15 +21446,15 @@ var require_parser = __commonJS({
21441
21446
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
21442
21447
  const start2 = getFirstKeyStartProps(it.start);
21443
21448
  const key = it.key;
21444
- const sep10 = it.sep;
21445
- sep10.push(this.sourceToken);
21449
+ const sep11 = it.sep;
21450
+ sep11.push(this.sourceToken);
21446
21451
  delete it.key;
21447
21452
  delete it.sep;
21448
21453
  this.stack.push({
21449
21454
  type: "block-map",
21450
21455
  offset: this.offset,
21451
21456
  indent: this.indent,
21452
- items: [{ start: start2, key, sep: sep10 }]
21457
+ items: [{ start: start2, key, sep: sep11 }]
21453
21458
  });
21454
21459
  } else if (start.length > 0) {
21455
21460
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -21643,13 +21648,13 @@ var require_parser = __commonJS({
21643
21648
  const prev = getPrevProps(parent);
21644
21649
  const start = getFirstKeyStartProps(prev);
21645
21650
  fixFlowSeqItems(fc);
21646
- const sep10 = fc.end.splice(1, fc.end.length);
21647
- sep10.push(this.sourceToken);
21651
+ const sep11 = fc.end.splice(1, fc.end.length);
21652
+ sep11.push(this.sourceToken);
21648
21653
  const map = {
21649
21654
  type: "block-map",
21650
21655
  offset: fc.offset,
21651
21656
  indent: fc.indent,
21652
- items: [{ start, key: fc, sep: sep10 }]
21657
+ items: [{ start, key: fc, sep: sep11 }]
21653
21658
  };
21654
21659
  this.onKeyLine = true;
21655
21660
  this.stack[this.stack.length - 1] = map;
@@ -21950,11 +21955,11 @@ function parseSkillFrontmatter(content) {
21950
21955
  };
21951
21956
  }
21952
21957
  }
21953
- function hard(path84, field, reason) {
21954
- return { path: path84, field, reason, severity: "error" };
21958
+ function hard(path85, field, reason) {
21959
+ return { path: path85, field, reason, severity: "error" };
21955
21960
  }
21956
- function warn(path84, field, reason) {
21957
- return { path: path84, field, reason, severity: "warn" };
21961
+ function warn(path85, field, reason) {
21962
+ return { path: path85, field, reason, severity: "warn" };
21958
21963
  }
21959
21964
  function validateSkillFrontmatter(skillDir) {
21960
21965
  const errors2 = [];
@@ -22956,7 +22961,7 @@ async function respondAsBackground(targetAgentId, fromId, message, opts) {
22956
22961
  return awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, opts?.signal);
22957
22962
  }
22958
22963
  function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
22959
- return new Promise((resolve22) => {
22964
+ return new Promise((resolve23) => {
22960
22965
  const deadline = Date.now() + timeoutMs;
22961
22966
  let settled = false;
22962
22967
  let timer;
@@ -22970,7 +22975,7 @@ function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
22970
22975
  const set2 = pendingRepliesByTarget.get(targetAgentId);
22971
22976
  set2?.delete(corrId);
22972
22977
  if (set2 && set2.size === 0) pendingRepliesByTarget.delete(targetAgentId);
22973
- resolve22(result4);
22978
+ resolve23(result4);
22974
22979
  };
22975
22980
  timer = setTimeout(() => finish({ ok: false, corrId, timedOut: true }), timeoutMs);
22976
22981
  if (signal) {
@@ -27138,7 +27143,7 @@ var require_compile = __commonJS({
27138
27143
  const schOrFunc = root.refs[ref];
27139
27144
  if (schOrFunc)
27140
27145
  return schOrFunc;
27141
- let _sch = resolve22.call(this, root, ref);
27146
+ let _sch = resolve23.call(this, root, ref);
27142
27147
  if (_sch === void 0) {
27143
27148
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
27144
27149
  const { schemaId } = this.opts;
@@ -27165,7 +27170,7 @@ var require_compile = __commonJS({
27165
27170
  function sameSchemaEnv(s1, s2) {
27166
27171
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
27167
27172
  }
27168
- function resolve22(root, ref) {
27173
+ function resolve23(root, ref) {
27169
27174
  let sch;
27170
27175
  while (typeof (sch = this.refs[ref]) == "string")
27171
27176
  ref = sch;
@@ -27383,8 +27388,8 @@ var require_utils = __commonJS({
27383
27388
  }
27384
27389
  return ind;
27385
27390
  }
27386
- function removeDotSegments(path84) {
27387
- let input = path84;
27391
+ function removeDotSegments(path85) {
27392
+ let input = path85;
27388
27393
  const output = [];
27389
27394
  let nextSlash = -1;
27390
27395
  let len = 0;
@@ -27636,8 +27641,8 @@ var require_schemes = __commonJS({
27636
27641
  wsComponent.secure = void 0;
27637
27642
  }
27638
27643
  if (wsComponent.resourceName) {
27639
- const [path84, query] = wsComponent.resourceName.split("?");
27640
- wsComponent.path = path84 && path84 !== "/" ? path84 : void 0;
27644
+ const [path85, query] = wsComponent.resourceName.split("?");
27645
+ wsComponent.path = path85 && path85 !== "/" ? path85 : void 0;
27641
27646
  wsComponent.query = query;
27642
27647
  wsComponent.resourceName = void 0;
27643
27648
  }
@@ -27796,7 +27801,7 @@ var require_fast_uri = __commonJS({
27796
27801
  }
27797
27802
  return uri;
27798
27803
  }
27799
- function resolve22(baseURI, relativeURI, options) {
27804
+ function resolve23(baseURI, relativeURI, options) {
27800
27805
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
27801
27806
  const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
27802
27807
  schemelessOptions.skipEscape = true;
@@ -28054,7 +28059,7 @@ var require_fast_uri = __commonJS({
28054
28059
  var fastUri = {
28055
28060
  SCHEMES,
28056
28061
  normalize: normalize2,
28057
- resolve: resolve22,
28062
+ resolve: resolve23,
28058
28063
  resolveComponent,
28059
28064
  equal,
28060
28065
  serialize,
@@ -31541,7 +31546,7 @@ ${input.prompt}` : input.prompt;
31541
31546
  );
31542
31547
  } catch {
31543
31548
  }
31544
- await new Promise((resolve22) => setTimeout(resolve22, DEFAULT_LIVE_SESSION.yieldPollIntervalMs));
31549
+ await new Promise((resolve23) => setTimeout(resolve23, DEFAULT_LIVE_SESSION.yieldPollIntervalMs));
31545
31550
  if (customToolYieldResolved && customToolYieldResult) {
31546
31551
  yieldResult = customToolYieldResult;
31547
31552
  } else if (collectedJsonEvents) {
@@ -31585,7 +31590,7 @@ ${input.prompt}` : input.prompt;
31585
31590
  }
31586
31591
  }
31587
31592
  const pollInterval = DEFAULT_LIVE_SESSION.yieldPollIntervalMs;
31588
- await new Promise((resolve22) => setTimeout(resolve22, pollInterval));
31593
+ await new Promise((resolve23) => setTimeout(resolve23, pollInterval));
31589
31594
  if (customToolYieldResolved && customToolYieldResult) {
31590
31595
  yieldResult = customToolYieldResult;
31591
31596
  break;
@@ -33005,13 +33010,13 @@ var init_checkpoint = __esm({
33005
33010
  import * as fs44 from "node:fs";
33006
33011
  import * as path36 from "node:path";
33007
33012
  function registerRunPromise(runId) {
33008
- let resolve22;
33013
+ let resolve23;
33009
33014
  let reject;
33010
33015
  const promise = new Promise((res, rej) => {
33011
- resolve22 = res;
33016
+ resolve23 = res;
33012
33017
  reject = rej;
33013
33018
  });
33014
- const entry = { promise, resolve: resolve22, reject };
33019
+ const entry = { promise, resolve: resolve23, reject };
33015
33020
  activeRunPromises.set(runId, entry);
33016
33021
  return entry;
33017
33022
  }
@@ -33255,17 +33260,17 @@ function confidenceToThreshold(confidence) {
33255
33260
  }
33256
33261
  function recordSkillActivation(cwd, activation) {
33257
33262
  ensureSkillMetricsDir(cwd, activation.runId);
33258
- const path84 = getSkillActivationsPath(cwd, activation.runId);
33263
+ const path85 = getSkillActivationsPath(cwd, activation.runId);
33259
33264
  const line4 = JSON.stringify(activation) + "\n";
33260
- writeFileSync6(path84, line4, { flag: "a", encoding: "utf-8" });
33265
+ writeFileSync6(path85, line4, { flag: "a", encoding: "utf-8" });
33261
33266
  return activation;
33262
33267
  }
33263
33268
  function getSkillActivations(cwd, runId) {
33264
- const path84 = getSkillActivationsPath(cwd, runId);
33265
- if (!existsSync32(path84)) {
33269
+ const path85 = getSkillActivationsPath(cwd, runId);
33270
+ if (!existsSync32(path85)) {
33266
33271
  return [];
33267
33272
  }
33268
- const content = readFileSync30(path84, "utf-8");
33273
+ const content = readFileSync30(path85, "utf-8");
33269
33274
  if (!content.trim()) {
33270
33275
  return [];
33271
33276
  }
@@ -35505,11 +35510,11 @@ function resolveSchemaKey(schema, key) {
35505
35510
  childSchema: childSchemas[0]
35506
35511
  };
35507
35512
  }
35508
- function findUnknownConfigKeyPaths(value, schema, depth = 0, path84 = []) {
35513
+ function findUnknownConfigKeyPaths(value, schema, depth = 0, path85 = []) {
35509
35514
  if (!isRecord2(value) || depth > MAX_CONFIG_KEY_DEPTH) return [];
35510
35515
  const unknownPaths = [];
35511
35516
  for (const [key, childValue] of Object.entries(value)) {
35512
- const childPath = [...path84, key];
35517
+ const childPath = [...path85, key];
35513
35518
  const resolution = resolveSchemaKey(schema, key);
35514
35519
  if (!resolution.allowed) {
35515
35520
  unknownPaths.push(childPath);
@@ -35521,8 +35526,8 @@ function findUnknownConfigKeyPaths(value, schema, depth = 0, path84 = []) {
35521
35526
  }
35522
35527
  return unknownPaths;
35523
35528
  }
35524
- function isAgentOverrideKeyPath(path84) {
35525
- return path84.length === 4 && path84[0] === "agents" && path84[1] === "overrides";
35529
+ function isAgentOverrideKeyPath(path85) {
35530
+ return path85.length === 4 && path85[0] === "agents" && path85[1] === "overrides";
35526
35531
  }
35527
35532
  function extractConfigReferences(config) {
35528
35533
  const agents = /* @__PURE__ */ new Set();
@@ -36707,10 +36712,10 @@ var init_goal_state_store = __esm({
36707
36712
  }
36708
36713
  /** Load a goal by id. Returns undefined if missing/corrupt. Throws on unsafe goalId (§0c C10). */
36709
36714
  load(goalId) {
36710
- const path84 = goalFilePath(this.cwd, goalId);
36715
+ const path85 = goalFilePath(this.cwd, goalId);
36711
36716
  try {
36712
- if (!existsSync39(path84)) return void 0;
36713
- const raw = readFileSync36(path84, "utf-8");
36717
+ if (!existsSync39(path85)) return void 0;
36718
+ const raw = readFileSync36(path85, "utf-8");
36714
36719
  const parsed = JSON.parse(raw);
36715
36720
  if (!parsed || typeof parsed !== "object" || typeof parsed.goalId !== "string") return void 0;
36716
36721
  return parsed;
@@ -36721,11 +36726,11 @@ var init_goal_state_store = __esm({
36721
36726
  /** Atomically persist a goal state. Emits a goal.state_changed event if eventsPath given. */
36722
36727
  save(state, eventsPath) {
36723
36728
  assertSafePathId("goalId", state.goalId);
36724
- const path84 = goalFilePath(this.cwd, state.goalId);
36729
+ const path85 = goalFilePath(this.cwd, state.goalId);
36725
36730
  const next = { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
36726
36731
  try {
36727
- mkdirSync23(dirname22(path84), { recursive: true });
36728
- atomicWriteJson(path84, next);
36732
+ mkdirSync23(dirname22(path85), { recursive: true });
36733
+ atomicWriteJson(path85, next);
36729
36734
  if (eventsPath) {
36730
36735
  appendEvent(eventsPath, {
36731
36736
  type: "goal.state_changed",
@@ -36822,9 +36827,9 @@ var init_goal_state_store = __esm({
36822
36827
  /** Remove a goal file (used by `goal clear`). Returns true if deleted. */
36823
36828
  remove(goalId) {
36824
36829
  try {
36825
- const path84 = goalFilePath(this.cwd, goalId);
36826
- if (!existsSync39(path84)) return false;
36827
- unlinkSync7(path84);
36830
+ const path85 = goalFilePath(this.cwd, goalId);
36831
+ if (!existsSync39(path85)) return false;
36832
+ unlinkSync7(path85);
36828
36833
  return true;
36829
36834
  } catch (error) {
36830
36835
  logInternalError("goal-state-store.remove", error, `goalId=${goalId}`);
@@ -46389,8 +46394,8 @@ var init_deduplicate_stage = __esm({
46389
46394
  const cur = lines[i];
46390
46395
  if (cur !== out[out.length - 1]) out.push(cur);
46391
46396
  }
46392
- const sep10 = text.includes("\r\n") ? "\r\n" : "\n";
46393
- return out.join(sep10);
46397
+ const sep11 = text.includes("\r\n") ? "\r\n" : "\n";
46398
+ return out.join(sep11);
46394
46399
  }
46395
46400
  };
46396
46401
  DEDUPLICATE_STAGE = new DeduplicateStage();
@@ -47918,8 +47923,8 @@ async function runCoalescedTaskGroup(input) {
47918
47923
  try {
47919
47924
  await Promise.race([
47920
47925
  pendingHeartbeat,
47921
- new Promise((resolve22) => {
47922
- drainTimeout = setTimeout(resolve22, 5e3);
47926
+ new Promise((resolve23) => {
47927
+ drainTimeout = setTimeout(resolve23, 5e3);
47923
47928
  })
47924
47929
  ]);
47925
47930
  } finally {
@@ -48549,7 +48554,7 @@ import * as fs76 from "node:fs";
48549
48554
  import * as path64 from "node:path";
48550
48555
  async function detectRipgrep() {
48551
48556
  if (cachedRgCheck !== void 0) return cachedRgCheck;
48552
- return await new Promise((resolve22) => {
48557
+ return await new Promise((resolve23) => {
48553
48558
  let settled = false;
48554
48559
  try {
48555
48560
  const child = spawn4("rg", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
@@ -48561,7 +48566,7 @@ async function detectRipgrep() {
48561
48566
  if (settled) return;
48562
48567
  settled = true;
48563
48568
  cachedRgCheck = { available: false };
48564
- resolve22(cachedRgCheck);
48569
+ resolve23(cachedRgCheck);
48565
48570
  });
48566
48571
  child.on("close", (code) => {
48567
48572
  if (settled) return;
@@ -48571,13 +48576,13 @@ async function detectRipgrep() {
48571
48576
  } else {
48572
48577
  cachedRgCheck = { available: false };
48573
48578
  }
48574
- resolve22(cachedRgCheck);
48579
+ resolve23(cachedRgCheck);
48575
48580
  });
48576
48581
  } catch {
48577
48582
  if (settled) return;
48578
48583
  settled = true;
48579
48584
  cachedRgCheck = { available: false };
48580
- resolve22(cachedRgCheck);
48585
+ resolve23(cachedRgCheck);
48581
48586
  }
48582
48587
  });
48583
48588
  }
@@ -48594,7 +48599,7 @@ function reasonFor(file, keywords) {
48594
48599
  return `keyword match: ${hits.join(", ")}`;
48595
48600
  }
48596
48601
  function runRipgrep(args, cwd) {
48597
- return new Promise((resolve22, reject) => {
48602
+ return new Promise((resolve23, reject) => {
48598
48603
  let settled = false;
48599
48604
  let stdout = "";
48600
48605
  let stderr = "";
@@ -48615,7 +48620,7 @@ function runRipgrep(args, cwd) {
48615
48620
  if (settled) return;
48616
48621
  settled = true;
48617
48622
  if (code === 0 || code === 1) {
48618
- resolve22(stdout);
48623
+ resolve23(stdout);
48619
48624
  } else {
48620
48625
  reject(new Error(`rg exited ${code}: ${stderr.slice(0, 200)}`));
48621
48626
  }
@@ -50299,7 +50304,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50299
50304
  const start = Date.now();
50300
50305
  let output = "";
50301
50306
  let exitCode = null;
50302
- return new Promise((resolve22) => {
50307
+ return new Promise((resolve23) => {
50303
50308
  const shell = spawn5("sh", ["-c", command], {
50304
50309
  cwd,
50305
50310
  timeout: timeoutMs,
@@ -50313,7 +50318,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50313
50318
  });
50314
50319
  const timer = setTimeout(() => {
50315
50320
  shell.kill("SIGKILL");
50316
- resolve22({
50321
+ resolve23({
50317
50322
  exitCode: -1,
50318
50323
  output: output + "\n[TIMEOUT: Command exceeded limit]",
50319
50324
  durationMs: Date.now() - start
@@ -50324,7 +50329,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50324
50329
  shell.on("close", (code) => {
50325
50330
  clearTimer();
50326
50331
  exitCode = code;
50327
- resolve22({
50332
+ resolve23({
50328
50333
  exitCode,
50329
50334
  output: output.slice(-1e5),
50330
50335
  // Cap at 100KB
@@ -50333,7 +50338,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
50333
50338
  });
50334
50339
  shell.on("error", (err2) => {
50335
50340
  clearTimer();
50336
- resolve22({
50341
+ resolve23({
50337
50342
  exitCode: -1,
50338
50343
  output: `Execution error: ${err2.message}`,
50339
50344
  durationMs: Date.now() - start
@@ -51061,115 +51066,143 @@ async function runTeamTask(input) {
51061
51066
  data: { role: task.role, model: model ?? "default" }
51062
51067
  });
51063
51068
  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
- });
51069
+ const taskTimeoutMs = input.runtimeConfig?.taskTimeoutMs ?? 0;
51070
+ const timeoutController = new AbortController();
51071
+ let externalAbortListener;
51072
+ if (input.signal) {
51073
+ if (input.signal.aborted) {
51074
+ timeoutController.abort(input.signal.reason);
51075
+ } else {
51076
+ externalAbortListener = () => timeoutController.abort(input.signal.reason);
51077
+ input.signal.addEventListener("abort", externalAbortListener, { once: true });
51078
+ }
51079
+ }
51080
+ let timeoutHandle;
51081
+ if (taskTimeoutMs > 0 && !timeoutController.signal.aborted) {
51082
+ timeoutHandle = setTimeout(() => {
51083
+ if (!timeoutController.signal.aborted) {
51084
+ timeoutController.abort(new Error(`Task exceeded wall-clock timeout of ${taskTimeoutMs}ms`));
51117
51085
  }
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
- }
51086
+ }, taskTimeoutMs);
51087
+ timeoutHandle.unref?.();
51088
+ }
51089
+ let childResult;
51090
+ try {
51091
+ childResult = await runChildPi({
51092
+ cwd: task.cwd,
51093
+ task: prompt,
51094
+ agent: input.agent,
51095
+ model,
51096
+ signal: timeoutController.signal,
51097
+ transcriptPath,
51098
+ maxDepth: input.limits?.maxTaskDepth,
51099
+ skillPaths,
51100
+ maxTurns: input.runtimeConfig?.maxTurns,
51101
+ graceTurns: input.runtimeConfig?.graceTurns,
51102
+ inheritContext: input.runtimeConfig?.inheritContext,
51103
+ parentContext: input.parentContext,
51104
+ excludeContextBash: input.runtimeConfig?.excludeContextBash,
51105
+ sessionId: manifest.sessionId,
51106
+ role: task.role,
51107
+ runId: manifest.runId,
51108
+ agentId: task.id,
51109
+ artifactsRoot: manifest.artifactsRoot,
51110
+ steeringFile: resolveContainedPath(`${manifest.artifactsRoot}/steering`, `${task.id}.jsonl`),
51111
+ onSpawn: (pid) => {
51112
+ try {
51113
+ ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-spawned", pid));
51114
+ if (task.pendingSteers?.length) {
51115
+ const steeringDir = `${manifest.artifactsRoot}/steering`;
51116
+ void appendSteeringAsync(steeringDir, task.id, task.pendingSteers);
51117
+ task.pendingSteers = [];
51118
+ tasks = persistSingleTaskUpdate(manifest, tasks, task);
51138
51119
  }
51120
+ } catch (err2) {
51121
+ logInternalError("task-runner.on-spawn", err2, `pid=${pid}, taskId=${task.id}`);
51139
51122
  }
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
51123
+ },
51124
+ onLifecycleEvent: (event) => {
51125
+ void appendEventAsync(manifest.eventsPath, {
51126
+ type: `worker.${event.type}`,
51127
+ runId: manifest.runId,
51128
+ taskId: task.id,
51129
+ message: `Worker lifecycle: ${event.type}${event.error ? ` error=${event.error}` : ""}${event.exitCode != null ? ` exit=${event.exitCode}` : ""}`,
51130
+ data: { ...event }
51131
+ }).catch(
51132
+ (error2) => logInternalError("task-runner.lifecycle-event", error2, `taskId=${task.id}, type=${event.type}`)
51150
51133
  );
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);
51134
+ },
51135
+ onStdoutLine: (line4) => {
51136
+ appendCrewAgentOutput(manifest, task.id, line4);
51137
+ persistHeartbeat();
51138
+ const contact = parseSupervisorContactFromLine(line4);
51139
+ if (contact) {
51140
+ recordSupervisorContact(manifest, {
51141
+ runId: manifest.runId,
51142
+ ...contact
51143
+ });
51162
51144
  }
51163
- if (!finalCheckpointWritten && isFinalChildEvent(event)) {
51164
- finalCheckpointWritten = true;
51165
- ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-stdout-final"));
51145
+ },
51146
+ onJsonEvent: (event) => {
51147
+ try {
51148
+ appendCrewAgentEvent(manifest, task.id, event);
51149
+ if (collectedJsonEvents && event && typeof event === "object" && !Array.isArray(event))
51150
+ collectedJsonEvents.push(event);
51151
+ if (collectedJsonEvents && collectedJsonEvents.length > 1e3) {
51152
+ collectedJsonEvents.splice(0, collectedJsonEvents.length - 1e3);
51153
+ }
51154
+ if (event && typeof event === "object" && event.type === "message_end") {
51155
+ const msg = event.message;
51156
+ if (msg?.role === "assistant") {
51157
+ const usage = msg.usage;
51158
+ if (usage) {
51159
+ task.lifetimeUsage = {
51160
+ input: (task.lifetimeUsage?.input ?? 0) + (usage.input ?? 0),
51161
+ output: (task.lifetimeUsage?.output ?? 0) + (usage.output ?? 0),
51162
+ cacheWrite: (task.lifetimeUsage?.cacheWrite ?? 0) + (usage.cacheWrite ?? 0)
51163
+ };
51164
+ }
51165
+ }
51166
+ }
51167
+ persistHeartbeat();
51168
+ if (process.env.PI_CREW_BACKGROUND_MODE === "1" && event) {
51169
+ const bgLogPath = `${manifest.stateRoot}/background.log`;
51170
+ const eventLine = typeof event === "object" && !Array.isArray(event) ? JSON.stringify(event) : String(event);
51171
+ void appendBackgroundLogAsync(bgLogPath, eventLine);
51172
+ }
51173
+ const nextProgress = applyAgentProgressEvent(
51174
+ task.agentProgress ?? emptyCrewAgentProgress(),
51175
+ event,
51176
+ task.startedAt
51177
+ );
51178
+ task = { ...task, agentProgress: nextProgress };
51179
+ tasks = updateTask(tasks, task);
51180
+ const progressNow = Date.now();
51181
+ if (progressNow - lastTaskProgressPersistedAt >= 500) {
51182
+ tasks = persistSingleTaskUpdate(manifest, tasks, task);
51183
+ lastTaskProgressPersistedAt = progressNow;
51184
+ }
51185
+ const bridgeEvent = bridgeEventFromJsonEvent(manifest.runId, task.id, event);
51186
+ if (bridgeEvent) streamBridge?.handler(bridgeEvent);
51187
+ if (input.onJsonEvent) {
51188
+ input.onJsonEvent(task.id, manifest.runId, event);
51189
+ }
51190
+ if (!finalCheckpointWritten && isFinalChildEvent(event)) {
51191
+ finalCheckpointWritten = true;
51192
+ ({ task, tasks } = checkpointTask(manifest, tasks, task, "child-stdout-final"));
51193
+ }
51194
+ persistChildProgress(event);
51195
+ } catch (err2) {
51196
+ logInternalError("task-runner.on-json-event", err2, `taskId=${task.id}`);
51166
51197
  }
51167
- persistChildProgress(event);
51168
- } catch (err2) {
51169
- logInternalError("task-runner.on-json-event", err2, `taskId=${task.id}`);
51170
51198
  }
51199
+ });
51200
+ } finally {
51201
+ if (timeoutHandle) clearTimeout(timeoutHandle);
51202
+ if (externalAbortListener && input.signal) {
51203
+ input.signal.removeEventListener("abort", externalAbortListener);
51171
51204
  }
51172
- });
51205
+ }
51173
51206
  const evidenceStatus = childResult.exitStatus?.cancelled ? "cancelled" : childResult.error || childResult.exitCode && childResult.exitCode !== 0 ? "failed" : "completed";
51174
51207
  terminalEvidence = [
51175
51208
  ...terminalEvidence,
@@ -54489,19 +54522,19 @@ function parseRoot(start) {
54489
54522
  function safeJoin(...parts) {
54490
54523
  const filtered = parts.filter(Boolean);
54491
54524
  if (filtered.length === 0) return "";
54492
- const sep10 = filtered.some((p) => p.includes("\\")) ? "\\" : "/";
54525
+ const sep11 = filtered.some((p) => p.includes("\\")) ? "\\" : "/";
54493
54526
  const firstPart = filtered[0];
54494
54527
  let leading = "";
54495
- if (sep10 === "\\") {
54528
+ if (sep11 === "\\") {
54496
54529
  if (firstPart.startsWith("\\\\")) leading = "\\\\";
54497
54530
  else if (firstPart.startsWith("\\")) leading = "\\";
54498
54531
  } else if (firstPart.startsWith("/")) {
54499
54532
  leading = "/";
54500
54533
  }
54501
- const firstPartStripped = sep10 === "\\" ? firstPart.replace(/^\\{1,2}/, "") : firstPart.replace(/^\/+/, "");
54534
+ const firstPartStripped = sep11 === "\\" ? firstPart.replace(/^\\{1,2}/, "") : firstPart.replace(/^\/+/, "");
54502
54535
  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);
54536
+ const joined = [firstPartStripped, ...rest].filter(Boolean).join(sep11);
54537
+ const collapsed = joined.replace(new RegExp(`${sep11 === "\\" ? "\\\\" : "/"}{2,}`, "g"), sep11);
54505
54538
  return leading + collapsed;
54506
54539
  }
54507
54540
  function safeDirname(p) {
@@ -55965,10 +55998,10 @@ var init_dwf_state_store = __esm({
55965
55998
  }
55966
55999
  /** Load the checkpoint for this run's stateRoot. Returns undefined if missing or corrupt (fresh run). */
55967
56000
  load() {
55968
- const path84 = this.path;
56001
+ const path85 = this.path;
55969
56002
  try {
55970
- if (!existsSync70(path84)) return void 0;
55971
- const raw = readFileSync64(path84, "utf-8");
56003
+ if (!existsSync70(path85)) return void 0;
56004
+ const raw = readFileSync64(path85, "utf-8");
55972
56005
  const parsed = JSON.parse(raw);
55973
56006
  if (!parsed || typeof parsed !== "object" || typeof parsed.runId !== "string") return void 0;
55974
56007
  return parsed;
@@ -55978,11 +56011,11 @@ var init_dwf_state_store = __esm({
55978
56011
  }
55979
56012
  /** Atomically persist a checkpoint state. Stamps `updatedAt` (callers need not set it). */
55980
56013
  save(state) {
55981
- const path84 = this.path;
56014
+ const path85 = this.path;
55982
56015
  const next = { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
55983
56016
  try {
55984
- mkdirSync39(dirname35(path84), { recursive: true });
55985
- atomicWriteJson(path84, next);
56017
+ mkdirSync39(dirname35(path85), { recursive: true });
56018
+ atomicWriteJson(path85, next);
55986
56019
  } catch (error) {
55987
56020
  logInternalError("dwf-state-store.save", error, `runId=${state.runId}`);
55988
56021
  throw error;
@@ -55990,10 +56023,10 @@ var init_dwf_state_store = __esm({
55990
56023
  }
55991
56024
  /** Remove the checkpoint file (after a clean completion). Best-effort; never throws. */
55992
56025
  delete() {
55993
- const path84 = this.path;
56026
+ const path85 = this.path;
55994
56027
  try {
55995
- if (!existsSync70(path84)) return;
55996
- unlinkSync10(path84);
56028
+ if (!existsSync70(path85)) return;
56029
+ unlinkSync10(path85);
55997
56030
  } catch (error) {
55998
56031
  logInternalError("dwf-state-store.delete", error);
55999
56032
  }
@@ -56025,14 +56058,14 @@ var init_semaphore = __esm({
56025
56058
  if (this.#queue.length >= _Semaphore.MAX_QUEUE) {
56026
56059
  throw new Error(`Semaphore queue full: ${this.#queue.length} waiters (max ${_Semaphore.MAX_QUEUE}); cannot acquire slot`);
56027
56060
  }
56028
- const { promise, resolve: resolve22 } = (() => {
56061
+ const { promise, resolve: resolve23 } = (() => {
56029
56062
  let res;
56030
56063
  const p = new Promise((r) => {
56031
56064
  res = r;
56032
56065
  });
56033
56066
  return { promise: p, resolve: res };
56034
56067
  })();
56035
- this.#queue.push(resolve22);
56068
+ this.#queue.push(resolve23);
56036
56069
  return promise;
56037
56070
  }
56038
56071
  release() {
@@ -58736,7 +58769,7 @@ function installCrewGlobalRegistry(deps) {
58736
58769
  if (!loaded) return true;
58737
58770
  return !loaded.tasks.some((t2) => t2.status === "running" || t2.status === "queued");
58738
58771
  };
58739
- while (!check()) await new Promise((resolve22) => setTimeout(resolve22, 500));
58772
+ while (!check()) await new Promise((resolve23) => setTimeout(resolve23, 500));
58740
58773
  },
58741
58774
  hasRunning: (runId) => {
58742
58775
  if (!manifestCache2) return false;
@@ -59446,26 +59479,26 @@ var init_syntax_highlight = __esm({
59446
59479
 
59447
59480
  // src/ui/transcript-cache.ts
59448
59481
  import * as fs91 from "node:fs";
59449
- function cacheKey(path84, options) {
59450
- return `${path84}:${options.full ? "full" : `tail:${options.maxTailBytes}`}`;
59482
+ function cacheKey(path85, options) {
59483
+ return `${path85}:${options.full ? "full" : `tail:${options.maxTailBytes}`}`;
59451
59484
  }
59452
- function getTranscriptCacheEntry(path84, options = {}) {
59485
+ function getTranscriptCacheEntry(path85, options = {}) {
59453
59486
  const normalized = {
59454
59487
  full: options.full === true,
59455
59488
  maxTailBytes: options.maxTailBytes ?? DEFAULT_TAIL_BYTES
59456
59489
  };
59457
- return transcriptCache.get(cacheKey(path84, normalized)) ?? transcriptCache.get(path84);
59490
+ return transcriptCache.get(cacheKey(path85, normalized)) ?? transcriptCache.get(path85);
59458
59491
  }
59459
- function readTranscriptText(path84, stat2, options) {
59492
+ function readTranscriptText(path85, stat2, options) {
59460
59493
  if (options.full || stat2.size <= options.maxTailBytes) {
59461
59494
  return {
59462
- text: fs91.readFileSync(path84, "utf-8"),
59495
+ text: fs91.readFileSync(path85, "utf-8"),
59463
59496
  bytesRead: stat2.size,
59464
59497
  truncated: false
59465
59498
  };
59466
59499
  }
59467
59500
  const bytesToRead = Math.min(stat2.size, options.maxTailBytes);
59468
- const fd = fs91.openSync(path84, "r");
59501
+ const fd = fs91.openSync(path85, "r");
59469
59502
  try {
59470
59503
  const buffer = Buffer.alloc(bytesToRead);
59471
59504
  fs91.readSync(fd, buffer, 0, bytesToRead, stat2.size - bytesToRead);
@@ -59477,16 +59510,16 @@ function readTranscriptText(path84, stat2, options) {
59477
59510
  fs91.closeSync(fd);
59478
59511
  }
59479
59512
  }
59480
- function readTranscriptLinesCached(path84, parse4, now = Date.now(), options = {}) {
59513
+ function readTranscriptLinesCached(path85, parse4, now = Date.now(), options = {}) {
59481
59514
  const normalized = {
59482
59515
  full: options.full === true,
59483
59516
  maxTailBytes: Math.max(1024, options.maxTailBytes ?? DEFAULT_TAIL_BYTES)
59484
59517
  };
59485
- const key = cacheKey(path84, normalized);
59518
+ const key = cacheKey(path85, normalized);
59486
59519
  const previous = transcriptCache.get(key);
59487
59520
  let stat2;
59488
59521
  try {
59489
- stat2 = fs91.statSync(path84);
59522
+ stat2 = fs91.statSync(path85);
59490
59523
  } catch {
59491
59524
  return previous?.lines ?? [];
59492
59525
  }
@@ -59495,10 +59528,10 @@ function readTranscriptLinesCached(path84, parse4, now = Date.now(), options = {
59495
59528
  return previous.lines;
59496
59529
  }
59497
59530
  try {
59498
- const read = readTranscriptText(path84, stat2, normalized);
59531
+ const read = readTranscriptText(path85, stat2, normalized);
59499
59532
  const lines = parse4(read.text);
59500
59533
  const entry = {
59501
- path: path84,
59534
+ path: path85,
59502
59535
  mtimeMs: stat2.mtimeMs,
59503
59536
  size: stat2.size,
59504
59537
  lines,
@@ -61088,7 +61121,7 @@ var init_run_dashboard = __esm({
61088
61121
  const borderFill = (count2) => new DynamicCrewBorder(this.theme).render(count2)[0];
61089
61122
  const border2 = (left, right) => `${fg("border", left)}${borderFill(borderWidth)}${fg("border", right)}`;
61090
61123
  const row = (text) => `\u2502 ${pad(truncate(text, innerWidth - 1), innerWidth - 1)}\u2502`;
61091
- const sep10 = () => border2("\u251C", "\u2524");
61124
+ const sep11 = () => border2("\u251C", "\u2524");
61092
61125
  const lines = [];
61093
61126
  if (this.showHelp) {
61094
61127
  lines.push(...new HelpOverlay(this.theme).render(width));
@@ -61098,7 +61131,7 @@ var init_run_dashboard = __esm({
61098
61131
  row(
61099
61132
  `${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
61133
  ),
61101
- sep10()
61134
+ sep11()
61102
61135
  );
61103
61136
  if (this.runs.length === 0) {
61104
61137
  lines.push(row(fg("dim", "No runs yet.")));
@@ -61146,7 +61179,7 @@ var init_run_dashboard = __esm({
61146
61179
  const agents = snap?.agents ?? agentsFor2(selectedRun, this.options.snapshotCache);
61147
61180
  const statusStr = isLikelyOrphanedActiveRun(r, agents) ? "stale" : r.status;
61148
61181
  const selectedTasks = snap?.tasks ?? readRunTasks2(r, this.options.snapshotCache);
61149
- lines.push(sep10());
61182
+ lines.push(sep11());
61150
61183
  lines.push(row(`${fg("accent", "\u25B8")} ${truncate(sanitizeLine(r.goal), innerWidth - 6)}`));
61151
61184
  const isTerminal = statusStr === "failed" || statusStr === "cancelled" || statusStr === "stopped";
61152
61185
  const reason = isTerminal ? summarizeTerminalReason(r, selectedTasks, snap?.cancellationReason) : void 0;
@@ -62345,8 +62378,8 @@ function formatValue2(value, id) {
62345
62378
  if (typeof value === "object") return JSON.stringify(value);
62346
62379
  return String(value);
62347
62380
  }
62348
- function getNestedValue(obj, path84) {
62349
- const keys = path84.split(".");
62381
+ function getNestedValue(obj, path85) {
62382
+ const keys = path85.split(".");
62350
62383
  let current = obj;
62351
62384
  for (const key of keys) {
62352
62385
  if (!current || typeof current !== "object") return void 0;
@@ -64462,7 +64495,7 @@ var init_subagent_manager = __esm({
64462
64495
  await record.promise.catch((error) => {
64463
64496
  logInternalError("subagent-manager.waitForRecord", error, `id=${id}`);
64464
64497
  });
64465
- else await new Promise((resolve22) => setTimeout(resolve22, 100));
64498
+ else await new Promise((resolve23) => setTimeout(resolve23, 100));
64466
64499
  }
64467
64500
  }
64468
64501
  setMaxConcurrent(value) {
@@ -64574,7 +64607,7 @@ var init_subagent_manager = __esm({
64574
64607
  }
64575
64608
  const loaded = loadRunManifestById(cwd, record.runId);
64576
64609
  if (!loaded) {
64577
- await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
64610
+ await new Promise((resolve23) => setTimeout(resolve23, this.pollIntervalMs));
64578
64611
  continue;
64579
64612
  }
64580
64613
  if (loaded.manifest.status === "completed") {
@@ -64607,7 +64640,7 @@ var init_subagent_manager = __esm({
64607
64640
  savePersistedSubagentRecord(cwd, record);
64608
64641
  return;
64609
64642
  }
64610
- await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
64643
+ await new Promise((resolve23) => setTimeout(resolve23, this.pollIntervalMs));
64611
64644
  }
64612
64645
  }
64613
64646
  scheduleBlockedTerminalPoll(cwd, record) {
@@ -64805,13 +64838,13 @@ function line3(text, width) {
64805
64838
  function border(left, fill, right, width) {
64806
64839
  return `${left}${fill.repeat(Math.max(0, width - 2))}${right}`;
64807
64840
  }
64808
- function readTasks3(path84) {
64841
+ function readTasks3(path85) {
64809
64842
  const parse4 = () => {
64810
- const parsed = JSON.parse(fs100.readFileSync(path84, "utf-8"));
64843
+ const parsed = JSON.parse(fs100.readFileSync(path85, "utf-8"));
64811
64844
  return Array.isArray(parsed) ? parsed : [];
64812
64845
  };
64813
64846
  try {
64814
- return readJsonFileCoalesced(path84, TASK_READ_TTL_MS3, parse4);
64847
+ return readJsonFileCoalesced(path85, TASK_READ_TTL_MS3, parse4);
64815
64848
  } catch {
64816
64849
  return [];
64817
64850
  }
@@ -66828,10 +66861,10 @@ function createMetricFileSink(opts) {
66828
66861
  const target = ensureFd(date);
66829
66862
  const line4 = `${JSON.stringify({ exportedAt: now.toISOString(), snapshots: redacted })}
66830
66863
  `;
66831
- return new Promise((resolve22) => {
66864
+ return new Promise((resolve23) => {
66832
66865
  fs103.write(target, line4, (err2) => {
66833
66866
  if (err2) logInternalError("metric-sink.asyncWrite", err2);
66834
- resolve22();
66867
+ resolve23();
66835
66868
  });
66836
66869
  });
66837
66870
  } catch (error) {
@@ -66871,6 +66904,7 @@ __export(heartbeat_watcher_exports, {
66871
66904
  HeartbeatWatcher: () => HeartbeatWatcher
66872
66905
  });
66873
66906
  import * as fs104 from "node:fs";
66907
+ import * as path81 from "node:path";
66874
66908
  var HeartbeatWatcher;
66875
66909
  var init_heartbeat_watcher = __esm({
66876
66910
  "src/runtime/heartbeat-watcher.ts"() {
@@ -66951,6 +66985,13 @@ var init_heartbeat_watcher = __esm({
66951
66985
  if (level === "dead" && isProcessAlive) {
66952
66986
  level = "stale";
66953
66987
  }
66988
+ if (level === "dead" && !isProcessAlive && loaded.manifest.artifactsRoot) {
66989
+ const resultsDir = path81.resolve(loaded.manifest.artifactsRoot, "results");
66990
+ const candidate = path81.resolve(resultsDir, `${task.id}.txt`);
66991
+ if (candidate.startsWith(resultsDir + path81.sep) && fs104.existsSync(candidate)) {
66992
+ level = "stale";
66993
+ }
66994
+ }
66954
66995
  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
66996
  this.opts.registry.counter("crew.heartbeat.level_total", "Heartbeat classifications by level").inc({ runId: run.runId, level });
66956
66997
  const previous = this.lastLevel.get(key);
@@ -66966,12 +67007,13 @@ var init_heartbeat_watcher = __esm({
66966
67007
  elapsedMs: Number.isFinite(elapsed2) ? elapsed2 : void 0
66967
67008
  }
66968
67009
  });
67010
+ const runLabel2 = run.runId.slice(0, 8);
66969
67011
  this.opts.router.enqueue({
66970
67012
  id: `dead_${run.runId}_${task.id}`,
66971
67013
  severity: "warning",
66972
67014
  source: "heartbeat-watcher",
66973
67015
  runId: run.runId,
66974
- title: `Task ${task.id} heartbeat dead`,
67016
+ title: `[${runLabel2}] Task ${task.id} heartbeat dead`,
66975
67017
  body: "Background watcher detected a stuck worker."
66976
67018
  });
66977
67019
  this.opts.onDead?.(run.runId, task.id, Number.isFinite(elapsed2) ? elapsed2 : thresholds.deadMs);
@@ -68226,17 +68268,17 @@ function normalizeConfig(raw) {
68226
68268
  }
68227
68269
  function loadConfig2() {
68228
68270
  try {
68229
- const path84 = configPath2();
68230
- if (!existsSync76(path84)) return normalizeConfig(void 0);
68231
- return normalizeConfig(JSON.parse(readFileSync71(path84, "utf8")));
68271
+ const path85 = configPath2();
68272
+ if (!existsSync76(path85)) return normalizeConfig(void 0);
68273
+ return normalizeConfig(JSON.parse(readFileSync71(path85, "utf8")));
68232
68274
  } catch {
68233
68275
  return normalizeConfig(void 0);
68234
68276
  }
68235
68277
  }
68236
68278
  function saveConfig(config) {
68237
- const path84 = configPath2();
68238
- mkdirSync42(dirname37(path84), { recursive: true });
68239
- writeFileSync11(path84, `${JSON.stringify(normalizeConfig(config), null, 2)}
68279
+ const path85 = configPath2();
68280
+ mkdirSync42(dirname37(path85), { recursive: true });
68281
+ writeFileSync11(path85, `${JSON.stringify(normalizeConfig(config), null, 2)}
68240
68282
  `);
68241
68283
  }
68242
68284
 
@@ -69754,9 +69796,9 @@ function closeWatcher(watcher) {
69754
69796
  } catch {
69755
69797
  }
69756
69798
  }
69757
- function watchWithErrorHandler(path84, listener, onError) {
69799
+ function watchWithErrorHandler(path85, listener, onError) {
69758
69800
  try {
69759
- const watcher = fs95.watch(path84, listener);
69801
+ const watcher = fs95.watch(path85, listener);
69760
69802
  watcher.on("error", onError);
69761
69803
  return watcher;
69762
69804
  } catch (error) {
@@ -71150,9 +71192,9 @@ function validateJson(content, _filePath) {
71150
71192
  var DEFAULT_VALIDATORS = /* @__PURE__ */ new Map([["json", validateJson]]);
71151
71193
  var MAX_DEDUP_ENTRIES = 256;
71152
71194
  var seenContent = /* @__PURE__ */ new Map();
71153
- function rememberSeen(path84, content) {
71154
- if (seenContent.has(path84)) seenContent.delete(path84);
71155
- seenContent.set(path84, content);
71195
+ function rememberSeen(path85, content) {
71196
+ if (seenContent.has(path85)) seenContent.delete(path85);
71197
+ seenContent.set(path85, content);
71156
71198
  while (seenContent.size > MAX_DEDUP_ENTRIES) {
71157
71199
  const oldest = seenContent.keys().next().value;
71158
71200
  if (oldest === void 0) break;
@@ -71358,7 +71400,7 @@ init_run_maintenance();
71358
71400
  init_broker_issuer();
71359
71401
  init_crash_recovery();
71360
71402
  import * as fs105 from "node:fs";
71361
- import * as path83 from "node:path";
71403
+ import * as path84 from "node:path";
71362
71404
 
71363
71405
  // src/runtime/crew-broker.ts
71364
71406
  init_event_log();
@@ -71496,7 +71538,7 @@ import { createHash as createHash11 } from "node:crypto";
71496
71538
  import * as fsp2 from "node:fs/promises";
71497
71539
  import * as net from "node:net";
71498
71540
  import * as os17 from "node:os";
71499
- import * as path81 from "node:path";
71541
+ import * as path82 from "node:path";
71500
71542
  var DEFAULT_PATH_HASH_LEN = 8;
71501
71543
  var POSIX_SUN_PATH_BUDGET = 107;
71502
71544
  function hashSessionId(sessionId, length = DEFAULT_PATH_HASH_LEN) {
@@ -71515,7 +71557,7 @@ function getBrokerSocketPath(sessionId, platform2 = process.platform) {
71515
71557
  return `\\\\.\\pipe\\pi-crew-broker-${hash}`;
71516
71558
  }
71517
71559
  const base = process.env.XDG_RUNTIME_DIR || os17.tmpdir();
71518
- const sock = path81.join(base, `pi-crew-${hash}.sock`);
71560
+ const sock = path82.join(base, `pi-crew-${hash}.sock`);
71519
71561
  const encoded = Buffer.byteLength(sock, "utf8");
71520
71562
  if (encoded > POSIX_SUN_PATH_BUDGET) {
71521
71563
  throw new Error(
@@ -71526,7 +71568,7 @@ function getBrokerSocketPath(sessionId, platform2 = process.platform) {
71526
71568
  }
71527
71569
  async function prepareBrokerSocketDir(sockPath) {
71528
71570
  if (process.platform === "win32") return;
71529
- const dir = path81.dirname(sockPath);
71571
+ const dir = path82.dirname(sockPath);
71530
71572
  await fsp2.mkdir(dir, { recursive: true, mode: 448 });
71531
71573
  try {
71532
71574
  await fsp2.chmod(dir, 448);
@@ -71543,7 +71585,7 @@ async function removeStaleBrokerSocket(sockPath, probeTimeoutMs = 250) {
71543
71585
  throw e;
71544
71586
  }
71545
71587
  if (st.isSymbolicLink()) return "refused";
71546
- const live = await new Promise((resolve22) => {
71588
+ const live = await new Promise((resolve23) => {
71547
71589
  let settled = false;
71548
71590
  const sock = net.createConnection(sockPath);
71549
71591
  const finish = (v) => {
@@ -71553,7 +71595,7 @@ async function removeStaleBrokerSocket(sockPath, probeTimeoutMs = 250) {
71553
71595
  sock.destroy();
71554
71596
  } catch {
71555
71597
  }
71556
- resolve22(v);
71598
+ resolve23(v);
71557
71599
  };
71558
71600
  sock.once("connect", () => finish(true));
71559
71601
  sock.once("error", () => finish(false));
@@ -71670,14 +71712,14 @@ var CrewBroker = class {
71670
71712
  );
71671
71713
  });
71672
71714
  });
71673
- await new Promise((resolve22, reject) => {
71715
+ await new Promise((resolve23, reject) => {
71674
71716
  const onError = (err2) => {
71675
71717
  server.removeListener("listening", onListening);
71676
71718
  reject(err2);
71677
71719
  };
71678
71720
  const onListening = () => {
71679
71721
  server.removeListener("error", onError);
71680
- resolve22();
71722
+ resolve23();
71681
71723
  };
71682
71724
  server.once("error", onError);
71683
71725
  server.once("listening", onListening);
@@ -71749,11 +71791,11 @@ var CrewBroker = class {
71749
71791
  }
71750
71792
  this.connections.clear();
71751
71793
  if (this.server) {
71752
- await new Promise((resolve22) => {
71794
+ await new Promise((resolve23) => {
71753
71795
  const srv = this.server;
71754
- if (!srv) return resolve22();
71755
- srv.close(() => resolve22());
71756
- setTimeout(() => resolve22(), 250).unref();
71796
+ if (!srv) return resolve23();
71797
+ srv.close(() => resolve23());
71798
+ setTimeout(() => resolve23(), 250).unref();
71757
71799
  });
71758
71800
  this.server = null;
71759
71801
  }
@@ -72329,45 +72371,45 @@ var CrewBroker = class {
72329
72371
  const isTerminal = (s) => s === "completed" || s === "failed" || s === "cancelled";
72330
72372
  const start = Date.now();
72331
72373
  const interval = 200;
72332
- const pollUntilDone = () => new Promise((resolve22) => {
72374
+ const pollUntilDone = () => new Promise((resolve23) => {
72333
72375
  const tick = () => {
72334
72376
  if (conn.closed) {
72335
72377
  this.sendError(conn, id, "close", "connection closed during wait");
72336
- resolve22();
72378
+ resolve23();
72337
72379
  return;
72338
72380
  }
72339
72381
  const connRunId = conn.runId;
72340
72382
  if (!connRunId) {
72341
72383
  this.sendError(conn, id, "auth", "not authed (post-narrow)");
72342
- resolve22();
72384
+ resolve23();
72343
72385
  return;
72344
72386
  }
72345
72387
  if (Date.now() - start >= timeoutMs) {
72346
72388
  this.sendError(conn, id, "wait-timeout", `task did not reach '${targetStatus}' within ${timeoutMs}ms`);
72347
- resolve22();
72389
+ resolve23();
72348
72390
  return;
72349
72391
  }
72350
72392
  try {
72351
72393
  const loaded = loadRunManifestById(cwd, connRunId);
72352
72394
  if (!loaded) {
72353
72395
  this.sendError(conn, id, "no-manifest", `run '${conn.runId}' not found`);
72354
- resolve22();
72396
+ resolve23();
72355
72397
  return;
72356
72398
  }
72357
72399
  const task = loaded.tasks.find((t2) => t2.id === targetTaskId);
72358
72400
  if (!task) {
72359
72401
  this.sendError(conn, id, "no-task", `task '${targetTaskId}' not found`);
72360
- resolve22();
72402
+ resolve23();
72361
72403
  return;
72362
72404
  }
72363
72405
  if (task.status === targetStatus || isTerminal(targetStatus) && isTerminal(task.status)) {
72364
72406
  this.sendResult(conn, id, { taskId: task.id, status: task.status, waitedMs: Date.now() - start });
72365
- resolve22();
72407
+ resolve23();
72366
72408
  return;
72367
72409
  }
72368
72410
  } catch (err2) {
72369
72411
  this.sendError(conn, id, "wait-failed", err2.message);
72370
- resolve22();
72412
+ resolve23();
72371
72413
  return;
72372
72414
  }
72373
72415
  setTimeout(tick, interval);
@@ -72805,14 +72847,14 @@ init_defaults();
72805
72847
  init_artifact_store();
72806
72848
  init_internal_error();
72807
72849
  init_paths();
72808
- import * as path82 from "node:path";
72850
+ import * as path83 from "node:path";
72809
72851
  function runArtifactCleanup(cwd) {
72810
72852
  try {
72811
- cleanupOldArtifacts(path82.join(userCrewRoot(), DEFAULT_PATHS.state.artifactsSubdir), {
72853
+ cleanupOldArtifacts(path83.join(userCrewRoot(), DEFAULT_PATHS.state.artifactsSubdir), {
72812
72854
  maxAgeDays: DEFAULT_ARTIFACT_CLEANUP.maxAgeDays,
72813
72855
  markerFile: CLEANUP_MARKER_FILE
72814
72856
  });
72815
- cleanupOldArtifacts(path82.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.artifactsSubdir), {
72857
+ cleanupOldArtifacts(path83.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.artifactsSubdir), {
72816
72858
  maxAgeDays: DEFAULT_ARTIFACT_CLEANUP.maxAgeDays,
72817
72859
  markerFile: CLEANUP_MARKER_FILE
72818
72860
  });
@@ -73318,7 +73360,7 @@ function setupRenderLoop(pi, ctx, extensionCtx, loadedConfig) {
73318
73360
  try {
73319
73361
  ctx.crewRunWatchers?.closeAll();
73320
73362
  ctx.crewRunWatchers = void 0;
73321
- const crewRunsDir = path83.join(projectCrewRoot(extensionCtx.cwd), "state", "runs");
73363
+ const crewRunsDir = path84.join(projectCrewRoot(extensionCtx.cwd), "state", "runs");
73322
73364
  if (fs105.existsSync(crewRunsDir)) {
73323
73365
  ctx.crewRunWatchers = new RunWatcherRegistry();
73324
73366
  ctx.crewRunWatchers.setRootWatcher(crewRunsDir, crewRunWatcherOnChange, crewRunWatcherOnError);
@@ -73329,7 +73371,7 @@ function setupRenderLoop(pi, ctx, extensionCtx, loadedConfig) {
73329
73371
  try {
73330
73372
  ctx.userCrewWatchers?.closeAll();
73331
73373
  ctx.userCrewWatchers = void 0;
73332
- const userRunsDir = path83.join(userCrewRoot(), "state", "runs");
73374
+ const userRunsDir = path84.join(userCrewRoot(), "state", "runs");
73333
73375
  if (fs105.existsSync(userRunsDir)) {
73334
73376
  ctx.userCrewWatchers = new RunWatcherRegistry();
73335
73377
  ctx.userCrewWatchers.setRootWatcher(userRunsDir, crewRunWatcherOnChange, crewRunWatcherOnError);
@@ -74034,7 +74076,7 @@ function registerSubagentTools(pi, subagentManager, options = {}) {
74034
74076
  savePersistedSubagentRecord(ctx.cwd, current);
74035
74077
  break;
74036
74078
  }
74037
- await new Promise((resolve22) => setTimeout(resolve22, 1e3));
74079
+ await new Promise((resolve23) => setTimeout(resolve23, 1e3));
74038
74080
  current = refreshPersistedSubagentRecord(ctx, current);
74039
74081
  if (!current.runId) break;
74040
74082
  }