pi-subagents 0.82.1 → 0.83.1

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 (94) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/bundle/agents.js +5 -5
  3. package/bundle/background-work.js +1 -1
  4. package/bundle/capability-ceiling.js +1 -1
  5. package/bundle/child-tool-plan.js +4 -4
  6. package/bundle/{chunk-RMQFMMAT.js → chunk-2D52JFLF.js} +231 -10
  7. package/bundle/{chunk-52UBALJL.js → chunk-2DHZTCOL.js} +2 -2
  8. package/bundle/{chunk-43SCHIMD.js → chunk-2S4K53MV.js} +1 -1
  9. package/bundle/{chunk-IVAE5Z6Q.js → chunk-5YIITCPD.js} +31 -27
  10. package/bundle/{chunk-JYUKW2SY.js → chunk-AHIFYGR3.js} +13 -13
  11. package/bundle/{chunk-XSWOTIA3.js → chunk-C5P5CHYK.js} +1 -1
  12. package/bundle/{chunk-PDZWJCHD.js → chunk-C7JMPU5F.js} +10 -7
  13. package/bundle/{chunk-5TYMSZX3.js → chunk-D3JAFGMO.js} +2 -2
  14. package/bundle/{chunk-OYF6AFDY.js → chunk-F4ASL6OV.js} +2 -2
  15. package/bundle/{chunk-ZIV4J4HG.js → chunk-F5DBXJ2G.js} +51 -34
  16. package/bundle/{chunk-YKEWIB4M.js → chunk-G2Z6ZH26.js} +1 -1
  17. package/bundle/{chunk-G4GZD3OJ.js → chunk-IPGZMQXV.js} +11 -11
  18. package/bundle/{chunk-5LFLVSTM.js → chunk-JEZOSEWG.js} +2 -0
  19. package/bundle/{chunk-PLCCBLPY.js → chunk-LFDBD4PW.js} +2 -2
  20. package/bundle/{chunk-CIZQXJ5Q.js → chunk-LNRJCP2Y.js} +56 -20
  21. package/bundle/{chunk-UTT254JE.js → chunk-MABL3FUM.js} +8 -4
  22. package/bundle/{chunk-3JCDWF4V.js → chunk-NPIYWVOD.js} +12 -18
  23. package/bundle/{chunk-UCPP4GNU.js → chunk-QP5ZWNIS.js} +12 -5
  24. package/bundle/{chunk-Z7KVHQHL.js → chunk-QXASAHIA.js} +2 -2
  25. package/bundle/{chunk-46XKCPJR.js → chunk-RNIZLSEA.js} +2221 -3260
  26. package/bundle/{chunk-GJECHSAR.js → chunk-SSG7IEP5.js} +2 -2
  27. package/bundle/{chunk-VSUSLDNW.js → chunk-UFL7IYCW.js} +10 -8
  28. package/bundle/{chunk-QE4AGIMG.js → chunk-UUP372DR.js} +482 -705
  29. package/bundle/{chunk-6XJB7PIX.js → chunk-UYK5MZWE.js} +16 -12
  30. package/bundle/{chunk-4SDU2BZX.js → chunk-V2BZYLEP.js} +3 -3
  31. package/bundle/{chunk-FXUXCX2K.js → chunk-VLFZIN6D.js} +6 -6
  32. package/bundle/{chunk-N2BN7BF5.js → chunk-XA3DY6UG.js} +7 -5
  33. package/bundle/{chunk-PBK2I7WY.js → chunk-YXFJVCOL.js} +6 -6
  34. package/bundle/{chunk-4Y2ROR7L.js → chunk-ZVOAMTUQ.js} +5 -5
  35. package/bundle/control-channel.js +4 -4
  36. package/bundle/index.js +1 -1
  37. package/bundle/intercom-bridge.js +4 -4
  38. package/bundle/preflight.js +10 -10
  39. package/bundle/project-panes.js +5 -5
  40. package/bundle/shared-types.js +1 -1
  41. package/docs/configuration.md +13 -2
  42. package/docs/extension-api.md +21 -4
  43. package/docs/missions.md +2 -0
  44. package/docs/observability.md +1 -0
  45. package/docs/tool-reference.md +2 -2
  46. package/package.json +1 -1
  47. package/skills/pi-subagents/SKILL.md +6 -6
  48. package/src/agents/agent-management.d.ts +1 -1
  49. package/src/agents/agent-management.js +10 -16
  50. package/src/agents/agent-serializer.js +1 -2
  51. package/src/agents/agents.js +20 -5
  52. package/src/agents/frontmatter.js +22 -18
  53. package/src/api/background-work.d.ts +9 -6
  54. package/src/api/background-work.js +14 -7
  55. package/src/extension/index.js +6 -3
  56. package/src/extension/public-execution.d.ts +2 -2
  57. package/src/extension/public-execution.js +3 -3
  58. package/src/extension/reply-workflow-script.js +4 -5
  59. package/src/extension/rpc.js +3 -1
  60. package/src/extension/subagent-options.js +17 -4
  61. package/src/missions/actions.js +7 -2
  62. package/src/missions/lifecycle.d.ts +11 -0
  63. package/src/missions/lifecycle.js +37 -6
  64. package/src/missions/store.js +1 -0
  65. package/src/missions/types.d.ts +2 -0
  66. package/src/runs/background/async-execution.d.ts +1 -1
  67. package/src/runs/background/async-execution.js +7 -4
  68. package/src/runs/background/async-job-tracker.js +2 -1
  69. package/src/runs/background/async-resume.js +3 -2
  70. package/src/runs/background/auto-drain.js +2 -3
  71. package/src/runs/background/fleet-view.js +1 -1
  72. package/src/runs/background/retained-children.js +1 -1
  73. package/src/runs/background/run-child-session.js +22 -6
  74. package/src/runs/background/subagent-wait.d.ts +2 -1
  75. package/src/runs/background/subagent-wait.js +5 -2
  76. package/src/runs/foreground/execution.js +22 -6
  77. package/src/runs/foreground/subagent-executor.js +26 -56
  78. package/src/runs/shared/capability-ceiling.d.ts +2 -1
  79. package/src/runs/shared/capability-ceiling.js +3 -2
  80. package/src/runs/shared/child-launch.js +5 -2
  81. package/src/runs/shared/child-session.d.ts +6 -0
  82. package/src/runs/shared/child-session.js +20 -4
  83. package/src/runs/shared/herdr-machine.d.ts +2 -0
  84. package/src/runs/shared/herdr-machine.js +2 -0
  85. package/src/runs/shared/herdr-placed-run.js +11 -4
  86. package/src/runs/shared/parallel-handoff.d.ts +1 -1
  87. package/src/runs/shared/parallel-handoff.js +10 -6
  88. package/src/runs/shared/subagent-prompt-runtime.js +11 -17
  89. package/src/shared/disabled-features.d.ts +3 -1
  90. package/src/shared/disabled-features.js +11 -3
  91. package/src/shared/types.d.ts +4 -2
  92. package/src/shared/types.js +2 -0
  93. package/src/workflows/scripted-workflow.js +13 -1071
  94. package/workflow-script-worker.cjs +1068 -0
@@ -3,7 +3,7 @@ import {
3
3
  projectRuntimeAcknowledgedExtensions,
4
4
  registerSubagentPromptBoundary,
5
5
  registerSubagentPromptRuntime
6
- } from "./chunk-3JCDWF4V.js";
6
+ } from "./chunk-NPIYWVOD.js";
7
7
  import {
8
8
  INSPECTOR_ACTIONS,
9
9
  canQueueRetainedAsyncFollowUp,
@@ -25,12 +25,13 @@ import {
25
25
  updateSteeringTarget,
26
26
  waitForSteeringAction,
27
27
  workflowAsyncChildSteeringGuidance
28
- } from "./chunk-PBK2I7WY.js";
28
+ } from "./chunk-YXFJVCOL.js";
29
29
  import {
30
- REX_LOCAL_MACHINE,
30
+ PLACED_RESTORE_UNSUPPORTED,
31
+ formatHerdrMachineRunnerUnsupported,
31
32
  isRexLocalMachine,
32
- resolveRexLocalPlacement
33
- } from "./chunk-RMQFMMAT.js";
33
+ resolveMachinePlacement
34
+ } from "./chunk-2D52JFLF.js";
34
35
  import {
35
36
  COMPLETION_ACTION,
36
37
  DEFAULT_CONTROL_CONFIG,
@@ -119,7 +120,7 @@ import {
119
120
  workflowStopCause,
120
121
  writeWorkflowLaunchRecord,
121
122
  writeWorkflowReceipt
122
- } from "./chunk-ZIV4J4HG.js";
123
+ } from "./chunk-F5DBXJ2G.js";
123
124
  import {
124
125
  NATIVE_SUPERVISOR_TOOL_NAME,
125
126
  SUBAGENT_PARENT_SESSION_ENV,
@@ -135,7 +136,7 @@ import {
135
136
  resolveWatchdogConfig,
136
137
  sendRuleViolationWarning,
137
138
  writeWatchdogModelSettings
138
- } from "./chunk-VSUSLDNW.js";
139
+ } from "./chunk-UFL7IYCW.js";
139
140
  import {
140
141
  MAX_REMEMBERED_FOREGROUND_RUNS,
141
142
  discardRunningForegroundRun,
@@ -148,7 +149,7 @@ import {
148
149
  resolveSubagentRunId,
149
150
  resolveWorkflowChatProgress,
150
151
  stopAsyncRun
151
- } from "./chunk-FXUXCX2K.js";
152
+ } from "./chunk-VLFZIN6D.js";
152
153
  import {
153
154
  MODEL_ONLY_TOOL,
154
155
  RunFanoutLimitError,
@@ -210,7 +211,7 @@ import {
210
211
  writeParallelHandoffGroup,
211
212
  writeRunFanoutBudgetDescriptor,
212
213
  writeWorktreeSetupHandoff
213
- } from "./chunk-6XJB7PIX.js";
214
+ } from "./chunk-UYK5MZWE.js";
214
215
  import {
215
216
  authorizeWorkflowResourceHost,
216
217
  claimWorkflowChildPermit,
@@ -227,14 +228,15 @@ import {
227
228
  canPreferFork,
228
229
  createForkContextResolver,
229
230
  resolveSubagentLaunchContext
230
- } from "./chunk-GJECHSAR.js";
231
+ } from "./chunk-SSG7IEP5.js";
231
232
  import {
232
233
  handleRefinementAction
233
- } from "./chunk-PLCCBLPY.js";
234
+ } from "./chunk-LFDBD4PW.js";
234
235
  import {
235
236
  ActiveAsyncCapacityError,
236
237
  acquireActiveAsyncCapacity,
237
238
  disabledFeatureNotice,
239
+ disabledFeatureSectionNotice,
238
240
  disabledFeatureUseError,
239
241
  getActiveAsyncCapacitySnapshot,
240
242
  inspectActiveAsyncCapacityOwner,
@@ -244,7 +246,7 @@ import {
244
246
  resolveDisabledFeatureSurface,
245
247
  resolveMaxActiveAsyncRunsPerSession,
246
248
  transferActiveAsyncCapacity
247
- } from "./chunk-UCPP4GNU.js";
249
+ } from "./chunk-QP5ZWNIS.js";
248
250
  import {
249
251
  DEFAULT_STALE_TERMINAL_ACTIVE_MARKER_MS,
250
252
  MACHINE_DIFF_OPTIONS,
@@ -278,6 +280,7 @@ import {
278
280
  inheritedNestedParentAddressOf,
279
281
  inheritedNestedRouteOf,
280
282
  initializeProcessTerminal,
283
+ missionAcceptanceStatus,
281
284
  nestedResultsPath,
282
285
  nestedRunNotActiveMessage,
283
286
  nestedRunScope,
@@ -323,7 +326,7 @@ import {
323
326
  writeNestedControlRequest,
324
327
  writeNestedControlResult,
325
328
  writeNestedEvent
326
- } from "./chunk-46XKCPJR.js";
329
+ } from "./chunk-RNIZLSEA.js";
327
330
  import {
328
331
  closeSteerInbox,
329
332
  consumeSteerRequests,
@@ -331,7 +334,7 @@ import {
331
334
  readRevivalBriefs,
332
335
  requestAsyncSteer,
333
336
  watchAsyncControlInbox
334
- } from "./chunk-OYF6AFDY.js";
337
+ } from "./chunk-F4ASL6OV.js";
335
338
  import "./chunk-NIXWDZZV.js";
336
339
  import {
337
340
  INTERCOM_BRIDGE_MARKER,
@@ -340,7 +343,7 @@ import {
340
343
  resolveIntercomBridge,
341
344
  resolveIntercomSessionTarget,
342
345
  resolveSubagentIntercomTarget
343
- } from "./chunk-XSWOTIA3.js";
346
+ } from "./chunk-C5P5CHYK.js";
344
347
  import {
345
348
  resolveLaunchBinding,
346
349
  stableJsonDigest
@@ -354,7 +357,7 @@ import {
354
357
  resolvePiLaunchToolPlan,
355
358
  resolveRuntimeModulePath,
356
359
  supervisorChannelDir
357
- } from "./chunk-4SDU2BZX.js";
360
+ } from "./chunk-V2BZYLEP.js";
358
361
  import {
359
362
  assertRequiredChildExtensionsAdmitted,
360
363
  hasMandatoryRequiredChildExtensions,
@@ -365,7 +368,7 @@ import {
365
368
  import {
366
369
  HERDR_PROJECT_PANE_ACTIONS,
367
370
  handleHerdrProjectPaneAction
368
- } from "./chunk-52UBALJL.js";
371
+ } from "./chunk-2DHZTCOL.js";
369
372
  import "./chunk-7J4ZXMY7.js";
370
373
  import {
371
374
  PROJECT_SUBAGENTS_RELATIVE_DIR,
@@ -378,14 +381,13 @@ import {
378
381
  getProjectSubagentsDir,
379
382
  writeArtifact,
380
383
  writeMetadata
381
- } from "./chunk-5TYMSZX3.js";
382
- import "./chunk-N2BN7BF5.js";
384
+ } from "./chunk-D3JAFGMO.js";
385
+ import "./chunk-XA3DY6UG.js";
383
386
  import {
384
387
  getExternalJobProvider
385
388
  } from "./chunk-YYREO77V.js";
386
- import "./chunk-YKEWIB4M.js";
389
+ import "./chunk-G2Z6ZH26.js";
387
390
  import {
388
- CODE_OWNED_EXTERNAL_CLI_ADAPTER_IDS,
389
391
  ChainOutputValidationError,
390
392
  MAX_STREAMED_RECENT_TOOLS,
391
393
  MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR,
@@ -449,7 +451,6 @@ import {
449
451
  formatUnknownAgentError,
450
452
  getAgentDir,
451
453
  getFinalOutput,
452
- getProjectConfigDir,
453
454
  getSingleResultOutput,
454
455
  getStepAgents,
455
456
  hasEmptyTerminalAssistantResponse,
@@ -531,7 +532,7 @@ import {
531
532
  writeAtomicJson,
532
533
  writeInitialProgressFile,
533
534
  writePrivateAtomicJson
534
- } from "./chunk-CIZQXJ5Q.js";
535
+ } from "./chunk-LNRJCP2Y.js";
535
536
  import {
536
537
  CHAIN_RUNS_DIR,
537
538
  DEFAULT_ARTIFACT_CONFIG,
@@ -560,7 +561,7 @@ import {
560
561
  resolveMaxSubagentSpawnsPerSession,
561
562
  truncateOutput,
562
563
  wrapForkTask
563
- } from "./chunk-5LFLVSTM.js";
564
+ } from "./chunk-JEZOSEWG.js";
564
565
  import {
565
566
  safeTerminalText
566
567
  } from "./chunk-YFCK7H2S.js";
@@ -569,12 +570,12 @@ import {
569
570
  assertAgentAllowedByCapabilityCeiling,
570
571
  intersectSubagentCapabilityCeilings,
571
572
  resolveCurrentSubagentCapabilityCeiling
572
- } from "./chunk-Z7KVHQHL.js";
573
+ } from "./chunk-QXASAHIA.js";
573
574
 
574
575
  // src/runs/foreground/subagent-executor.ts
575
576
  import { randomUUID as randomUUID5 } from "node:crypto";
576
- import * as fs21 from "node:fs";
577
- import * as path19 from "node:path";
577
+ import * as fs20 from "node:fs";
578
+ import * as path18 from "node:path";
578
579
 
579
580
  // src/shared/capacity-resilient-json.ts
580
581
  var defaultTimerApi = {
@@ -775,235 +776,24 @@ function finishForegroundChild(control, index) {
775
776
  }
776
777
 
777
778
  // src/extension/doctor.ts
778
- import * as fs8 from "node:fs";
779
- import * as path7 from "node:path";
779
+ import * as fs7 from "node:fs";
780
+ import * as path6 from "node:path";
780
781
 
781
782
  // src/runs/background/async-execution.ts
782
783
  import { spawn } from "node:child_process";
783
784
  import { randomUUID as randomUUID2 } from "node:crypto";
784
- import * as fs7 from "node:fs";
785
- import * as path6 from "node:path";
785
+ import * as fs6 from "node:fs";
786
+ import * as path5 from "node:path";
786
787
  import { fileURLToPath } from "node:url";
787
788
  import * as nodeModule from "node:module";
788
789
 
789
- // src/runs/shared/herdr-machine.ts
790
- import { spawnSync } from "node:child_process";
791
- import * as fs from "node:fs";
792
- import * as path from "node:path";
793
- var MAX_MACHINE_NAME_LENGTH = 128;
794
- var HERDR_MACHINE_LIST_TIMEOUT_MS = 7500;
795
- var MAX_HERDR_MACHINE_LIST_BYTES = 1024 * 1024;
796
- var CONTROL_CHARS = /[\u0000-\u001f\u007f]/u;
797
- var SUPPORTED_MACHINE_ADAPTERS = new Set(CODE_OWNED_EXTERNAL_CLI_ADAPTER_IDS);
798
- function validateMachineName(value) {
799
- const trimmed = value.trim();
800
- if (!trimmed) throw new Error("Herdr machine id or label is required.");
801
- if (trimmed.length > MAX_MACHINE_NAME_LENGTH) throw new Error(`Herdr machine '${trimmed.slice(0, 24)}\u2026' exceeds ${MAX_MACHINE_NAME_LENGTH} characters.`);
802
- if (CONTROL_CHARS.test(trimmed)) throw new Error("Herdr machine id or label contains control characters.");
803
- return trimmed;
804
- }
805
- function validateTarget(value, requested) {
806
- const target = value.trim();
807
- if (!target || target.startsWith("-") || /[\s\u0000-\u001f\u007f]/u.test(target)) {
808
- throw new Error(`Herdr machine '${requested}' has an ssh target that cannot be passed safely: ${JSON.stringify(target)}.`);
809
- }
810
- return target;
811
- }
812
- function isRemoteAbsolute(value) {
813
- return value.startsWith("/") || value === "~" || value.startsWith("~/");
814
- }
815
- function validateRemoteCwd(value, requested) {
816
- const cwd = value.trim();
817
- if (!isRemoteAbsolute(cwd)) throw new Error(`Herdr machine '${requested}' cwd must be an absolute POSIX path or start with '~': ${JSON.stringify(cwd)}.`);
818
- if (CONTROL_CHARS.test(cwd)) throw new Error(`Herdr machine '${requested}' cwd contains control characters.`);
819
- return cwd.length > 1 ? cwd.replace(/\/+$/u, "") : cwd;
820
- }
821
- function parseMachineCatalog(json) {
822
- let parsed;
823
- try {
824
- parsed = JSON.parse(json);
825
- } catch (error) {
826
- throw new Error(`Failed to parse herdr machine list --json: ${error instanceof Error ? error.message : String(error)}`);
827
- }
828
- const entries = Array.isArray(parsed) ? parsed : parsed && typeof parsed === "object" && Array.isArray(parsed.machines) ? parsed.machines : void 0;
829
- if (!entries) throw new Error("herdr machine list --json returned no machine list.");
830
- return entries.flatMap((entry) => {
831
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
832
- const record2 = entry;
833
- if (typeof record2.id !== "string" || !record2.id.trim() || typeof record2.target !== "string") return [];
834
- return [{
835
- id: record2.id.trim(),
836
- ...typeof record2.label === "string" && record2.label.trim() ? { label: record2.label.trim() } : {},
837
- target: record2.target,
838
- ...typeof record2.session === "string" && record2.session.trim() ? { session: record2.session.trim() } : {},
839
- enabled: record2.enabled !== false
840
- }];
841
- });
842
- }
843
- function readHerdrMachineCatalog(env, herdrBin) {
844
- const result2 = spawnSync(herdrBin, ["machine", "list", "--json"], {
845
- env,
846
- encoding: "utf-8",
847
- maxBuffer: MAX_HERDR_MACHINE_LIST_BYTES,
848
- timeout: HERDR_MACHINE_LIST_TIMEOUT_MS,
849
- windowsHide: true
850
- });
851
- if (result2.error) {
852
- const code = result2.error.code;
853
- if (code === "ENOENT") throw new Error(`Herdr CLI '${herdrBin}' was not found on PATH. Saved-machine placement needs Herdr installed locally.`);
854
- throw new Error(`Failed to run herdr machine list --json: ${result2.error.message}`);
855
- }
856
- if (result2.status !== 0) throw new Error(`herdr machine list --json exited with code ${result2.status}: ${(result2.stderr || result2.stdout).trim()}`);
857
- return parseMachineCatalog(result2.stdout);
858
- }
859
- function selectMachine(catalog, requested) {
860
- const byId = catalog.find((entry) => entry.id === requested);
861
- const matches = byId ? [byId] : catalog.filter((entry) => entry.label === requested);
862
- if (matches.length > 1) throw new Error(`Machine label '${requested}' is ambiguous; use its profile ID.`);
863
- const machine = matches[0];
864
- if (!machine) {
865
- const saved = catalog.filter((entry) => entry.enabled).map((entry) => entry.label ?? entry.id);
866
- throw new Error(`Herdr machine '${requested}' was not found. Saved machines: ${saved.length ? saved.join(", ") : "none"}. Add one with herdr machine add <target> --label <name>.`);
867
- }
868
- if (!machine.enabled) throw new Error(`Machine '${requested}' is disabled. Run herdr machine enable ${machine.id}.`);
869
- return machine;
870
- }
871
- function readJsonObject(filePath) {
872
- if (!fs.existsSync(filePath)) return {};
873
- let parsed;
874
- try {
875
- parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
876
- } catch (error) {
877
- throw new Error(`Failed to read settings file '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
878
- }
879
- return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
880
- }
881
- function machineSettingsFrom(settings, keys, filePath) {
882
- const subagents = settings.subagents;
883
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return void 0;
884
- const machines = subagents.machines;
885
- if (machines === void 0) return void 0;
886
- if (!machines || typeof machines !== "object" || Array.isArray(machines)) throw new Error(`Subagent settings in '${filePath}' have invalid 'machines'; expected an object keyed by machine label or id.`);
887
- const key = keys.find((candidate) => candidate in machines);
888
- if (key === void 0) return void 0;
889
- const value = machines[key];
890
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Subagent settings in '${filePath}' have invalid 'machines.${key}'; expected an object with 'cwd' and optional 'env'.`);
891
- const record2 = value;
892
- const entry = {};
893
- if (record2.cwd !== void 0) {
894
- if (typeof record2.cwd !== "string" || !record2.cwd.trim()) throw new Error(`Subagent settings in '${filePath}' have invalid 'machines.${key}.cwd'; expected a non-empty string.`);
895
- entry.cwd = validateRemoteCwd(record2.cwd, key);
896
- }
897
- if (record2.env !== void 0) {
898
- if (!record2.env || typeof record2.env !== "object" || Array.isArray(record2.env) || Object.entries(record2.env).some(([name, item]) => !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name) || typeof item !== "string")) {
899
- throw new Error(`Subagent settings in '${filePath}' have invalid 'machines.${key}.env'; expected an object of string values keyed by variable name.`);
900
- }
901
- entry.env = { ...record2.env };
902
- if (Object.keys(entry.env).length > 0) {
903
- throw new Error(`Subagent settings in '${filePath}' set 'machines.${key}.env'. Saved-machine runs use the remote Herdr/Pi environment; configure credentials and environment on '${key}' and remove the local env map.`);
904
- }
905
- }
906
- if (record2.rex !== void 0) {
907
- const rex = record2.rex, ssh = rex && typeof rex === "object" && !Array.isArray(rex) && Object.keys(rex).every((field) => field === "ssh") ? rex.ssh : void 0;
908
- if (typeof ssh !== "string") throw new Error(`Subagent settings in '${filePath}' have invalid 'machines.${key}.rex'; expected { "ssh": "<ssh target>" }.`);
909
- entry.rex = { ssh: validateTarget(ssh, key) };
910
- }
911
- return entry;
912
- }
913
- function readMachineSettings(cwd, keys) {
914
- const userPath = path.join(getAgentDir(), "settings.json");
915
- const projectPath = path.join(getProjectConfigDir(findProjectRootForSettings(cwd)), "settings.json");
916
- const user = machineSettingsFrom(readJsonObject(userPath), keys, userPath);
917
- const project = projectPath === userPath ? void 0 : machineSettingsFrom(readJsonObject(projectPath), keys, projectPath);
918
- if (project?.rex) throw new Error(`Project settings '${projectPath}' set a Rex SSH host in 'machines'. Move the rex entry to your user settings '${userPath}'; only user settings choose which host a task runs on.`);
919
- if (!user && !project) return void 0;
920
- return { ...user, ...project };
921
- }
922
- function userRexMachine(machine) {
923
- const userPath = path.join(getAgentDir(), "settings.json");
924
- return machineSettingsFrom(readJsonObject(userPath), [machine], userPath)?.rex !== void 0;
925
- }
926
- function findProjectRootForSettings(cwd) {
927
- let current = path.resolve(cwd);
928
- while (true) {
929
- if (fs.existsSync(path.join(getProjectConfigDir(current), "settings.json"))) return current;
930
- const parent = path.dirname(current);
931
- if (parent === current) return path.resolve(cwd);
932
- current = parent;
933
- }
934
- }
935
- function remoteMachineCwd(stepCwd, root, name) {
936
- const step = stepCwd?.trim();
937
- if (step && isRemoteAbsolute(step)) return step;
938
- if (!root) throw new Error(`No root for ${name} in this repo. Set subagents.machines.${name}.cwd in .pi/settings.json or pass an absolute cwd on that machine.`);
939
- return step ? path.posix.join(root, step) : root;
940
- }
941
- function resolveHerdrMachinePlacement(input) {
942
- const requested = validateMachineName(input.machine);
943
- const catalog = input.catalogJson !== void 0 ? parseMachineCatalog(input.catalogJson) : readHerdrMachineCatalog(input.env ?? process.env, input.herdrBin ?? process.env.HERDR_BIN ?? "herdr");
944
- const selected = selectMachine(catalog, requested);
945
- const name = selected.label ?? selected.id;
946
- const keys = [.../* @__PURE__ */ new Set([requested, ...selected.label ? [selected.label] : [], selected.id])];
947
- const settings = input.settings ?? readMachineSettings(input.cwd, keys);
948
- if (settings?.env && Object.keys(settings.env).length > 0) {
949
- throw new Error(`Saved-machine environment for '${name}' must be configured remotely. Remove machines.${name}.env and configure the remote Herdr/Pi session instead.`);
950
- }
951
- const cwd = remoteMachineCwd(input.stepCwd, settings?.cwd, name);
952
- return {
953
- machine: {
954
- provider: "herdr",
955
- id: selected.id,
956
- ...selected.label ? { label: selected.label } : {},
957
- target: validateTarget(selected.target, requested),
958
- ...selected.session && selected.session !== "default" ? { session: selected.session } : {},
959
- cwd: validateRemoteCwd(cwd, requested)
960
- },
961
- ...settings?.env ? { env: settings.env } : {}
962
- };
963
- }
964
- function resolveMachinePlacement(input) {
965
- const requested = validateMachineName(input.machine);
966
- const settings = input.settings ?? readMachineSettings(input.cwd, [requested]);
967
- if (requested === REX_LOCAL_MACHINE) {
968
- if (settings?.rex) throw new Error("Machine 'local' is reserved for a Rex pane on this machine; give the Rex SSH host in subagents.machines.local.rex another name.");
969
- return { machine: resolveRexLocalPlacement({ cwd: input.cwd, stepCwd: input.stepCwd, env: input.env }) };
970
- }
971
- if (settings?.rex) return { machine: { provider: "rex", id: requested, target: settings.rex.ssh, cwd: validateRemoteCwd(remoteMachineCwd(input.stepCwd, settings.cwd, requested), requested) } };
972
- return resolveHerdrMachinePlacement(input);
973
- }
974
- function formatHerdrMachineRunnerUnsupported(input) {
975
- if (input.machine === void 0) return void 0;
976
- const name = input.machine.trim();
977
- let rex;
978
- try {
979
- rex = name === REX_LOCAL_MACHINE || userRexMachine(name);
980
- } catch (error) {
981
- return error instanceof Error ? error.message : String(error);
982
- }
983
- if (rex) {
984
- if (input.runnerType !== void 0 && input.runnerType !== "pi") return `Agent '${input.agentName}' requested machine '${name}', but Rex supports native Pi children only. Remove the machine or use a native Pi agent.`;
985
- if (input.worktree === true) return `Agent '${input.agentName}' requested machine '${name}', but managed worktrees cannot be combined with machine placement.`;
986
- if (process.platform === "win32") return `Machine '${name}' runs the child in a Rex pane, which is not supported on Windows.`;
987
- return void 0;
988
- }
989
- if (input.runnerType !== void 0 && input.runnerType !== "pi" && input.runnerType !== "external-cli") {
990
- return `Agent '${input.agentName}' requested machine '${input.machine}', but this runner cannot use pane-native Herdr placement. Use native Pi or a built-in Claude, Codex, or Cursor profile.`;
991
- }
992
- if (input.runnerType === "external-cli" && (input.adapter === void 0 || !SUPPORTED_MACHINE_ADAPTERS.has(input.adapter))) {
993
- return `Agent '${input.agentName}' requested machine '${input.machine}', but generic external-cli commands cannot be remote-wrapped safely. Use claude-code, claude-code-writer, codex-exec, codex-exec-writer, cursor-agent, or cursor-agent-writer.`;
994
- }
995
- if (input.worktree === true) return `Agent '${input.agentName}' requested machine '${input.machine}', but managed worktrees are local git operations and cannot be combined with a Herdr saved machine.`;
996
- if (process.platform === "win32") return "Herdr saved-machine pane transport requires hardened OpenSSH StreamLocal forwarding, which is not supported from a Windows host yet.";
997
- return void 0;
998
- }
999
-
1000
790
  // src/runs/shared/launch-cwd.ts
1001
- import * as fs2 from "node:fs";
791
+ import * as fs from "node:fs";
1002
792
  function preflightLaunchCwd(requestedCwd, effectiveCwd) {
1003
793
  const resolution = requestedCwd === effectiveCwd ? "" : `
1004
794
  (resolved from ${JSON.stringify(requestedCwd)})`;
1005
795
  try {
1006
- if (!fs2.statSync(effectiveCwd).isDirectory()) {
796
+ if (!fs.statSync(effectiveCwd).isDirectory()) {
1007
797
  return `Subagent launch aborted: cwd is not a directory: ${effectiveCwd}${resolution}`;
1008
798
  }
1009
799
  } catch (error) {
@@ -1025,23 +815,23 @@ function backgroundProcessOptions(platform = process.platform) {
1025
815
  }
1026
816
 
1027
817
  // src/runs/shared/child-launch.ts
1028
- import * as fs4 from "node:fs";
1029
- import * as path3 from "node:path";
818
+ import * as fs3 from "node:fs";
819
+ import * as path2 from "node:path";
1030
820
 
1031
821
  // src/extension/fanout-child.ts
1032
- import * as fs3 from "node:fs";
822
+ import * as fs2 from "node:fs";
1033
823
  import * as os from "node:os";
1034
- import * as path2 from "node:path";
824
+ import * as path from "node:path";
1035
825
  function getSubagentSessionRoot(parentSessionFile) {
1036
826
  if (parentSessionFile) {
1037
- const baseName = path2.basename(parentSessionFile, ".jsonl");
1038
- const sessionsDir = path2.dirname(parentSessionFile);
1039
- return path2.join(sessionsDir, baseName);
827
+ const baseName = path.basename(parentSessionFile, ".jsonl");
828
+ const sessionsDir = path.dirname(parentSessionFile);
829
+ return path.join(sessionsDir, baseName);
1040
830
  }
1041
- return fs3.mkdtempSync(path2.join(os.tmpdir(), "pi-subagent-session-"));
831
+ return fs2.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-session-"));
1042
832
  }
1043
833
  function expandTilde(p) {
1044
- return p.startsWith("~/") ? path2.join(os.homedir(), p.slice(2)) : p;
834
+ return p.startsWith("~/") ? path.join(os.homedir(), p.slice(2)) : p;
1045
835
  }
1046
836
  function createChildSafeState() {
1047
837
  return {
@@ -1127,7 +917,7 @@ ${request.message.trim()}`,
1127
917
  inboxState.pendingResults.delete(request.requestId);
1128
918
  inboxState.seen.add(request.requestId);
1129
919
  try {
1130
- fs3.unlinkSync(request.filePath);
920
+ fs2.unlinkSync(request.filePath);
1131
921
  } catch {
1132
922
  }
1133
923
  } finally {
@@ -1413,12 +1203,12 @@ function childProcessEnv(input, toolPlan) {
1413
1203
  }
1414
1204
  function childStorage(input) {
1415
1205
  if (input.sessionFile) {
1416
- fs4.mkdirSync(path3.dirname(input.sessionFile), { recursive: true });
1206
+ fs3.mkdirSync(path2.dirname(input.sessionFile), { recursive: true });
1417
1207
  return { kind: "file", sessionFile: input.sessionFile };
1418
1208
  }
1419
1209
  if (!input.sessionEnabled) return { kind: "memory" };
1420
1210
  if (input.sessionDir) {
1421
- fs4.mkdirSync(input.sessionDir, { recursive: true });
1211
+ fs3.mkdirSync(input.sessionDir, { recursive: true });
1422
1212
  return { kind: "dir", sessionDir: input.sessionDir };
1423
1213
  }
1424
1214
  return { kind: "default" };
@@ -1472,8 +1262,8 @@ function buildInProcessChildLaunch(input) {
1472
1262
  let supervisorDir;
1473
1263
  if (input.orchestratorIntercomTarget && input.parentSessionId && input.runId) {
1474
1264
  supervisorDir = supervisorChannelDir(input.runId, input.childAgentName, input.childIndex);
1475
- fs4.mkdirSync(path3.join(supervisorDir, "requests"), { recursive: true });
1476
- fs4.mkdirSync(path3.join(supervisorDir, "replies"), { recursive: true });
1265
+ fs3.mkdirSync(path2.join(supervisorDir, "requests"), { recursive: true });
1266
+ fs3.mkdirSync(path2.join(supervisorDir, "replies"), { recursive: true });
1477
1267
  }
1478
1268
  const thinkingCeiling = intersectThinkingCeilings(input.thinkingCeiling, inherited?.thinkingCeiling);
1479
1269
  let structuredValue;
@@ -1558,7 +1348,8 @@ ${input.systemPrompt}` : void 0;
1558
1348
  requiredExtensions: toolPlan.requiredExtensions,
1559
1349
  ambientExtensions,
1560
1350
  hooks: capturedHooks.hooks,
1561
- ...input.host === "runner" ? { processEnv: childProcessEnv(input, toolPlan) } : {},
1351
+ // A foreground child gets only its own bindings, so it never sees those of the session that launched it.
1352
+ ...input.host === "runner" ? { processEnv: childProcessEnv(input, toolPlan) } : { processEnv: { [PI_SUBAGENT_EXTENSION_BINDINGS_ENV]: encodeExtensionBindings(input.extensionBindings) }, restoreProcessEnv: true },
1562
1353
  runtime: config,
1563
1354
  noSkills: !input.inheritSkills,
1564
1355
  noContextFiles: !input.inheritProjectContext,
@@ -1642,14 +1433,14 @@ function usageBudgetExceededMessage(state) {
1642
1433
  }
1643
1434
 
1644
1435
  // src/runs/background/runner-startup-failure.ts
1645
- import * as fs5 from "node:fs";
1646
- import * as path4 from "node:path";
1436
+ import * as fs4 from "node:fs";
1437
+ import * as path3 from "node:path";
1647
1438
  function persistRunnerStartupFailure(input) {
1648
1439
  const now = Date.now();
1649
- const statusPath = path4.join(input.asyncDir, "status.json");
1440
+ const statusPath = path3.join(input.asyncDir, "status.json");
1650
1441
  let status = {};
1651
1442
  try {
1652
- status = JSON.parse(fs5.readFileSync(statusPath, "utf-8"));
1443
+ status = JSON.parse(fs4.readFileSync(statusPath, "utf-8"));
1653
1444
  } catch (error) {
1654
1445
  if (error.code !== "ENOENT") throw error;
1655
1446
  }
@@ -1671,7 +1462,7 @@ function persistRunnerStartupFailure(input) {
1671
1462
  });
1672
1463
  const existingCandidate = readProcessTerminalCandidate(input.asyncDir);
1673
1464
  const stepCount = Math.max(1, status.steps?.length ?? 0);
1674
- writePrivateAtomicJson(path4.join(input.asyncDir, "process-terminal-candidate.json"), {
1465
+ writePrivateAtomicJson(path3.join(input.asyncDir, "process-terminal-candidate.json"), {
1675
1466
  ...existingCandidate,
1676
1467
  version: 1,
1677
1468
  runId: input.runId,
@@ -1685,19 +1476,19 @@ function persistRunnerStartupFailure(input) {
1685
1476
 
1686
1477
  // src/runs/background/chain-append.ts
1687
1478
  import { randomUUID } from "node:crypto";
1688
- import * as fs6 from "node:fs";
1689
- import * as path5 from "node:path";
1479
+ import * as fs5 from "node:fs";
1480
+ import * as path4 from "node:path";
1690
1481
  var APPEND_REQUESTS_DIR = "append-requests";
1691
1482
  function appendDir(asyncDir) {
1692
- return path5.join(asyncDir, APPEND_REQUESTS_DIR);
1483
+ return path4.join(asyncDir, APPEND_REQUESTS_DIR);
1693
1484
  }
1694
1485
  function appendRequestPath(asyncDir, request) {
1695
- return path5.join(appendDir(asyncDir), `${request.createdAt}-${request.id}.json`);
1486
+ return path4.join(appendDir(asyncDir), `${request.createdAt}-${request.id}.json`);
1696
1487
  }
1697
1488
  function listAppendRequestFiles(asyncDir) {
1698
1489
  const dir = appendDir(asyncDir);
1699
1490
  try {
1700
- return fs6.readdirSync(dir).filter((entry) => entry.endsWith(".json")).map((entry) => path5.join(dir, entry)).sort();
1491
+ return fs5.readdirSync(dir).filter((entry) => entry.endsWith(".json")).map((entry) => path4.join(dir, entry)).sort();
1701
1492
  } catch (error) {
1702
1493
  if (error.code === "ENOENT") return [];
1703
1494
  throw error;
@@ -1733,7 +1524,7 @@ function enqueueChainAppendRequest(input) {
1733
1524
  createdAt: input.now ?? Date.now(),
1734
1525
  steps: input.steps
1735
1526
  };
1736
- fs6.mkdirSync(appendDir(input.asyncDir), { recursive: true });
1527
+ fs5.mkdirSync(appendDir(input.asyncDir), { recursive: true });
1737
1528
  const persist = () => writeAtomicJson(appendRequestPath(input.asyncDir, request), request);
1738
1529
  if (input.admit) input.admit(persist);
1739
1530
  else persist();
@@ -1744,7 +1535,7 @@ function enqueueChainAppendRequest(input) {
1744
1535
  } catch (error) {
1745
1536
  bookkeepingErrors.push(`pending append count failed: ${error instanceof Error ? error.message : String(error)}`);
1746
1537
  }
1747
- const statusPath = path5.join(input.asyncDir, "status.json");
1538
+ const statusPath = path4.join(input.asyncDir, "status.json");
1748
1539
  const updatedStatus = { ...status, pendingAppends: pendingCount, lastUpdate: request.createdAt };
1749
1540
  try {
1750
1541
  writeAtomicJson(statusPath, updatedStatus);
@@ -1752,7 +1543,7 @@ function enqueueChainAppendRequest(input) {
1752
1543
  bookkeepingErrors.push(`status update failed: ${error instanceof Error ? error.message : String(error)}`);
1753
1544
  }
1754
1545
  try {
1755
- appendJsonl(path5.join(input.asyncDir, "events.jsonl"), JSON.stringify({
1546
+ appendJsonl(path4.join(input.asyncDir, "events.jsonl"), JSON.stringify({
1756
1547
  type: "subagent.chain.append.requested",
1757
1548
  ts: request.createdAt,
1758
1549
  runId: input.runId,
@@ -1766,7 +1557,7 @@ function enqueueChainAppendRequest(input) {
1766
1557
  return { request, pendingCount, ...bookkeepingErrors.length > 0 ? { bookkeepingError: bookkeepingErrors.join("; ") } : {} };
1767
1558
  }
1768
1559
  function readAppendRequest(filePath) {
1769
- const raw = JSON.parse(fs6.readFileSync(filePath, "utf-8"));
1560
+ const raw = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
1770
1561
  if (!raw.id || typeof raw.id !== "string") return void 0;
1771
1562
  const createdAt = raw.createdAt;
1772
1563
  if (typeof createdAt !== "number" || !Number.isFinite(createdAt)) return void 0;
@@ -1813,28 +1604,28 @@ var piPackageSelection = (() => {
1813
1604
  })();
1814
1605
  var piPackageRoot = piPackageSelection.root;
1815
1606
  function resolveJitiCliFromPackageJson(packageJsonPath) {
1816
- if (!fs7.existsSync(packageJsonPath)) return void 0;
1817
- const packageRoot = path6.dirname(packageJsonPath);
1818
- const pkg = JSON.parse(fs7.readFileSync(packageJsonPath, "utf-8"));
1607
+ if (!fs6.existsSync(packageJsonPath)) return void 0;
1608
+ const packageRoot = path5.dirname(packageJsonPath);
1609
+ const pkg = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
1819
1610
  const binField = pkg.bin;
1820
1611
  const binPath = typeof binField === "string" ? binField : binField?.jiti ?? Object.values(binField ?? {})[0];
1821
1612
  const candidates = [binPath, "lib/jiti-cli.mjs"].filter((candidate) => Boolean(candidate));
1822
1613
  for (const candidate of candidates) {
1823
- const cliPath = path6.resolve(packageRoot, candidate);
1824
- if (fs7.existsSync(cliPath)) return cliPath;
1614
+ const cliPath = path5.resolve(packageRoot, candidate);
1615
+ if (fs6.existsSync(cliPath)) return cliPath;
1825
1616
  }
1826
1617
  return void 0;
1827
1618
  }
1828
1619
  function resolveJitiCliPath() {
1829
1620
  const candidates = [
1830
1621
  () => require2.resolve("jiti/package.json"),
1831
- () => piPackageRoot ? nodeModule.createRequire(path6.join(piPackageRoot, "package.json")).resolve("jiti/package.json") : void 0,
1622
+ () => piPackageRoot ? nodeModule.createRequire(path5.join(piPackageRoot, "package.json")).resolve("jiti/package.json") : void 0,
1832
1623
  () => {
1833
1624
  if (!process.argv[1]) return void 0;
1834
- const piEntry = fs7.realpathSync(process.argv[1]);
1625
+ const piEntry = fs6.realpathSync(process.argv[1]);
1835
1626
  return nodeModule.createRequire(piEntry).resolve("jiti/package.json");
1836
1627
  },
1837
- () => piPackageRoot ? path6.join(piPackageRoot, "node_modules", "jiti", "package.json") : void 0
1628
+ () => piPackageRoot ? path5.join(piPackageRoot, "node_modules", "jiti", "package.json") : void 0
1838
1629
  ];
1839
1630
  for (const candidate of candidates) {
1840
1631
  try {
@@ -1848,12 +1639,12 @@ function resolveJitiCliPath() {
1848
1639
  return void 0;
1849
1640
  }
1850
1641
  var jitiCliPath = resolveJitiCliPath();
1851
- var asyncRunnerModuleDir = path6.dirname(fileURLToPath(new URL("../src/runs/background/async-execution.js", import.meta.url).href));
1642
+ var asyncRunnerModuleDir = path5.dirname(fileURLToPath(new URL("../src/runs/background/async-execution.js", import.meta.url).href));
1852
1643
  function asyncRunnerSourcePath() {
1853
1644
  return resolveRuntimeModulePath(asyncRunnerModuleDir, "subagent-runner-bootstrap");
1854
1645
  }
1855
1646
  function sourceUnderNodeModules() {
1856
- return asyncRunnerSourcePath().split(path6.sep).some((segment) => segment.toLowerCase() === "node_modules");
1647
+ return asyncRunnerSourcePath().split(path5.sep).some((segment) => segment.toLowerCase() === "node_modules");
1857
1648
  }
1858
1649
  function supportsNativeRunner(nodeExecutable) {
1859
1650
  return Boolean(process.features.typescript) && typeof nodeModule.registerHooks === "function" && nodeExecutable === process.execPath && !sourceUnderNodeModules();
@@ -1875,25 +1666,25 @@ function resolveAsyncRunnerLogPaths(cfg) {
1875
1666
  const asyncDir = typeof cfg.asyncDir === "string" ? cfg.asyncDir : void 0;
1876
1667
  if (!asyncDir) return void 0;
1877
1668
  return {
1878
- stdoutPath: path6.join(asyncDir, "runner.stdout.log"),
1879
- stderrPath: path6.join(asyncDir, "runner.stderr.log")
1669
+ stdoutPath: path5.join(asyncDir, "runner.stdout.log"),
1670
+ stderrPath: path5.join(asyncDir, "runner.stderr.log")
1880
1671
  };
1881
1672
  }
1882
1673
  function closeFd(fd) {
1883
1674
  if (fd === void 0) return;
1884
1675
  try {
1885
- fs7.closeSync(fd);
1676
+ fs6.closeSync(fd);
1886
1677
  } catch {
1887
1678
  }
1888
1679
  }
1889
1680
  var RUNNER_STARTUP_TIMEOUT_MS = 1e4;
1890
1681
  function waitForStartupInterval(delayMs = 20) {
1891
- return new Promise((resolve10) => setTimeout(resolve10, delayMs));
1682
+ return new Promise((resolve9) => setTimeout(resolve9, delayMs));
1892
1683
  }
1893
1684
  function readRunnerStartup(startupPath, expectedState, expectedToken) {
1894
- if (!fs7.existsSync(startupPath)) return void 0;
1685
+ if (!fs6.existsSync(startupPath)) return void 0;
1895
1686
  try {
1896
- const payload = JSON.parse(fs7.readFileSync(startupPath, "utf-8"));
1687
+ const payload = JSON.parse(fs6.readFileSync(startupPath, "utf-8"));
1897
1688
  if (payload.state === "error" && typeof payload.error === "string") return { ok: false, error: payload.error, startupDidNotProceed: true };
1898
1689
  if (payload.state !== expectedState) return void 0;
1899
1690
  if (typeof payload.token !== "string" || expectedToken !== void 0 && payload.token !== expectedToken) {
@@ -1907,7 +1698,7 @@ function readRunnerStartup(startupPath, expectedState, expectedToken) {
1907
1698
  async function waitForRunnerStartup(startupPath, expectedState, timeoutMs, expectedToken, processClosed) {
1908
1699
  const confirmOpen = async (result2) => {
1909
1700
  if (!processClosed || result2.ok === false) return result2;
1910
- const outcome = await Promise.race([processClosed.then((exit) => ({ exit })), new Promise((resolve10) => setImmediate(() => resolve10(void 0)))]);
1701
+ const outcome = await Promise.race([processClosed.then((exit) => ({ exit })), new Promise((resolve9) => setImmediate(() => resolve9(void 0)))]);
1911
1702
  if (!outcome) return result2;
1912
1703
  const finalResult2 = readRunnerStartup(startupPath, expectedState, expectedToken);
1913
1704
  if (finalResult2?.ok === false) return finalResult2;
@@ -2022,7 +1813,7 @@ async function completeRunnerStartupHandshake(startupPath, startupAckPath, start
2022
1813
  }
2023
1814
  const closedAtCommit = await Promise.race([
2024
1815
  processClosed.then((exit) => exit),
2025
- new Promise((resolve10) => setImmediate(() => resolve10(void 0)))
1816
+ new Promise((resolve9) => setImmediate(() => resolve9(void 0)))
2026
1817
  ]);
2027
1818
  const observedExit = closedAtCommit ?? getObservedProcessExit();
2028
1819
  if (observedExit) {
@@ -2040,12 +1831,12 @@ async function completeRunnerStartupHandshake(startupPath, startupAckPath, start
2040
1831
  return { pid: proc.pid, runnerProcessInstanceId, error: message, terminationObserved, startupDidNotProceed: true };
2041
1832
  }
2042
1833
  try {
2043
- fs7.rmSync(startupPath, { force: true });
1834
+ fs6.rmSync(startupPath, { force: true });
2044
1835
  } catch {
2045
1836
  }
2046
1837
  return { pid: proc.pid, runnerProcessInstanceId };
2047
1838
  } finally {
2048
- await new Promise((resolve10) => setImmediate(resolve10));
1839
+ await new Promise((resolve9) => setImmediate(resolve9));
2049
1840
  }
2050
1841
  }
2051
1842
  function persistPreProceedStartupFailure(asyncDir, runId, runnerProcessInstanceId, sessionId, completionOwnerId, message) {
@@ -2080,9 +1871,9 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2080
1871
  const nodeExecutable = resolveNodeExecutable();
2081
1872
  const nativeRunnerSupported = supportsNativeRunner(nodeExecutable);
2082
1873
  const runner = asyncRunnerSourcePath();
2083
- const runnerIsJavaScript = path6.extname(runner) === ".js";
2084
- const bootstrap = resolveRuntimeModulePath(path6.dirname(runner), "binary-bootstrap");
2085
- if (binaryHost && !fs7.existsSync(bootstrap)) return { error: `Background runner bootstrap not found: ${bootstrap}` };
1874
+ const runnerIsJavaScript = path5.extname(runner) === ".js";
1875
+ const bootstrap = resolveRuntimeModulePath(path5.dirname(runner), "binary-bootstrap");
1876
+ if (binaryHost && !fs6.existsSync(bootstrap)) return { error: `Background runner bootstrap not found: ${bootstrap}` };
2086
1877
  if (!binaryHost && !runnerIsJavaScript && !nativeRunnerSupported && !jitiCliPath) {
2087
1878
  return { error: sourceUnderNodeModules() ? "Background runner source is installed under node_modules, so upstream jiti is required for TypeScript execution." : "Background runner requires enabled native TypeScript with synchronous module hooks, or installed upstream jiti for TypeScript execution." };
2088
1879
  }
@@ -2093,7 +1884,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2093
1884
  if (hostPeerAliases.missing.length > 0) {
2094
1885
  return { error: `Background children require the host npm package (${PI_CODING_AGENT_PACKAGE}) with its dependencies; ${piPackageRoot} does not provide ${hostPeerAliases.missing.join(", ")}.` };
2095
1886
  }
2096
- fs7.mkdirSync(TEMP_ROOT_DIR, { recursive: true });
1887
+ fs6.mkdirSync(TEMP_ROOT_DIR, { recursive: true });
2097
1888
  const cfgPath = getAsyncConfigPath(suffix);
2098
1889
  const runnerProcessInstanceId = randomUUID2();
2099
1890
  const hasRevivalLease = typeof cfg.revivalLease === "object";
@@ -2108,23 +1899,23 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2108
1899
  const launchRunId = typeof launchForStartup.id === "string" ? launchForStartup.id : suffix;
2109
1900
  const launchSessionId = typeof launchForStartup.sessionId === "string" ? launchForStartup.sessionId : void 0;
2110
1901
  const launchCompletionOwnerId = typeof launchForStartup.completionOwnerId === "string" ? launchForStartup.completionOwnerId : void 0;
2111
- const startupPath = typeof launchForStartup.revivalLease === "object" && launchAsyncDir ? path6.join(launchAsyncDir, "runner-startup.json") : void 0;
2112
- const startupAckPath = startupPath ? path6.join(path6.dirname(startupPath), "runner-startup-ack.json") : void 0;
2113
- const startupConfirmPath = startupPath ? path6.join(path6.dirname(startupPath), "runner-startup-confirm.json") : void 0;
2114
- const startupProceedPath = launchAsyncDir && (startupPath || launchBarrierToken) ? path6.join(launchAsyncDir, "runner-startup-proceed.json") : void 0;
2115
- if (startupPath) fs7.rmSync(startupPath, { force: true });
2116
- if (startupAckPath) fs7.rmSync(startupAckPath, { force: true });
2117
- if (startupConfirmPath) fs7.rmSync(startupConfirmPath, { force: true });
2118
- if (startupProceedPath) fs7.rmSync(startupProceedPath, { force: true });
2119
- const identityPath = launcher && launchBarrierToken && launchAsyncDir ? path6.join(launchAsyncDir, "runner-startup.json") : void 0;
2120
- if (identityPath) fs7.rmSync(identityPath, { force: true });
1902
+ const startupPath = typeof launchForStartup.revivalLease === "object" && launchAsyncDir ? path5.join(launchAsyncDir, "runner-startup.json") : void 0;
1903
+ const startupAckPath = startupPath ? path5.join(path5.dirname(startupPath), "runner-startup-ack.json") : void 0;
1904
+ const startupConfirmPath = startupPath ? path5.join(path5.dirname(startupPath), "runner-startup-confirm.json") : void 0;
1905
+ const startupProceedPath = launchAsyncDir && (startupPath || launchBarrierToken) ? path5.join(launchAsyncDir, "runner-startup-proceed.json") : void 0;
1906
+ if (startupPath) fs6.rmSync(startupPath, { force: true });
1907
+ if (startupAckPath) fs6.rmSync(startupAckPath, { force: true });
1908
+ if (startupConfirmPath) fs6.rmSync(startupConfirmPath, { force: true });
1909
+ if (startupProceedPath) fs6.rmSync(startupProceedPath, { force: true });
1910
+ const identityPath = launcher && launchBarrierToken && launchAsyncDir ? path5.join(launchAsyncDir, "runner-startup.json") : void 0;
1911
+ if (identityPath) fs6.rmSync(identityPath, { force: true });
2121
1912
  let runnerIdentity;
2122
1913
  const terminateBeforeProceed = (pid) => !launcher ? terminateRunnerBeforeProceed(pid) : runnerIdentity !== void 0 && runnerIdentity.pidNamespaceScope === currentPidNamespaceScope() && terminateRunnerBeforeProceed(runnerIdentity.pid);
2123
1914
  const adoptRunnerIdentity = (pid, pidNamespaceScope) => {
2124
1915
  if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid < 1) return `Async runner reported an invalid process identity in '${launchAsyncDir}'.`;
2125
1916
  runnerIdentity = { pid, ...typeof pidNamespaceScope === "string" ? { pidNamespaceScope } : {} };
2126
1917
  try {
2127
- const status = JSON.parse(fs7.readFileSync(initialStatusPath, "utf-8"));
1918
+ const status = JSON.parse(fs6.readFileSync(initialStatusPath, "utf-8"));
2128
1919
  writePrivateAtomicJson(initialStatusPath, { ...status, pid, ...runnerIdentity.pidNamespaceScope !== void 0 ? { pidNamespaceScope: runnerIdentity.pidNamespaceScope } : {} });
2129
1920
  return void 0;
2130
1921
  } catch (error) {
@@ -2136,9 +1927,9 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2136
1927
  let stderrFd;
2137
1928
  try {
2138
1929
  if (logPaths) {
2139
- fs7.mkdirSync(path6.dirname(logPaths.stdoutPath), { recursive: true });
2140
- stdoutFd = fs7.openSync(logPaths.stdoutPath, "a");
2141
- stderrFd = fs7.openSync(logPaths.stderrPath, "a");
1930
+ fs6.mkdirSync(path5.dirname(logPaths.stdoutPath), { recursive: true });
1931
+ stdoutFd = fs6.openSync(logPaths.stdoutPath, "a");
1932
+ stderrFd = fs6.openSync(logPaths.stderrPath, "a");
2142
1933
  }
2143
1934
  const preload = Object.keys(hostPeerAliases.aliases).length > 0 ? ["--import", new URL("../../../runner-peer-preload.mjs", new URL("../src/runs/background/async-execution.js", import.meta.url).href).href] : [];
2144
1935
  const args = binaryHost ? ["--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session", "--mode", "rpc", "--extension", bootstrap] : runnerIsJavaScript ? [...preload, runner, cfgPath] : nativeRunnerSupported ? [...preload, "--experimental-strip-types", runner, cfgPath] : [...preload, jitiCliPath, runner, cfgPath];
@@ -2165,10 +1956,10 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2165
1956
  proc.once("exit", (exitCode, signal) => {
2166
1957
  observedProcessExit = { exitCode, signal };
2167
1958
  });
2168
- const processClosed = new Promise((resolve10) => {
1959
+ const processClosed = new Promise((resolve9) => {
2169
1960
  proc.once("close", (exitCode, signal) => {
2170
1961
  observedProcessExit ??= { exitCode, signal };
2171
- resolve10({ exitCode, signal });
1962
+ resolve9({ exitCode, signal });
2172
1963
  });
2173
1964
  });
2174
1965
  closeFd(stdoutFd);
@@ -2184,7 +1975,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2184
1975
  if (typeof asyncDir !== "string" || typeof runId !== "string") return;
2185
1976
  if (launcher) {
2186
1977
  try {
2187
- writePrivateAtomicJson(path6.join(asyncDir, "launcher-close.json"), { version: 1, runId, runnerProcessInstanceId, closeObservedAt: Date.now(), exitCode, signal, ...runnerIdentity ? { runnerPid: runnerIdentity.pid } : {} });
1978
+ writePrivateAtomicJson(path5.join(asyncDir, "launcher-close.json"), { version: 1, runId, runnerProcessInstanceId, closeObservedAt: Date.now(), exitCode, signal, ...runnerIdentity ? { runnerPid: runnerIdentity.pid } : {} });
2188
1979
  } catch {
2189
1980
  }
2190
1981
  if (!runnerIdentity || runnerIdentity.pidNamespaceScope !== currentPidNamespaceScope() || checkRecordedPidLiveness(runnerIdentity) !== "dead") return;
@@ -2201,7 +1992,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2201
1992
  try {
2202
1993
  let status;
2203
1994
  try {
2204
- status = JSON.parse(fs7.readFileSync(path6.join(asyncDir, "status.json"), "utf-8"));
1995
+ status = JSON.parse(fs6.readFileSync(path5.join(asyncDir, "status.json"), "utf-8"));
2205
1996
  status.processTerminal = persisted;
2206
1997
  } catch {
2207
1998
  status = {
@@ -2246,7 +2037,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
2246
2037
  ...launcher ? {} : { pid: proc.pid, pidNamespaceScope: currentPidNamespaceScope(), ...bootId ? { bootId } : {} },
2247
2038
  processTerminal: { version: 1, state: "pending", runId: initialStatus.runId, runnerProcessInstanceId }
2248
2039
  });
2249
- updateActiveRunIndex(path6.dirname(initialStatusPath), initialStatus.state, initialStatus.toolCallId);
2040
+ updateActiveRunIndex(path5.dirname(initialStatusPath), initialStatus.state, initialStatus.toolCallId);
2250
2041
  } catch (error) {
2251
2042
  const message = `Failed to persist initial async status: ${error instanceof Error ? error.message : String(error)}`;
2252
2043
  if (launchAsyncDir) persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
@@ -2387,7 +2178,7 @@ function buildAsyncRunnerSteps(id, params) {
2387
2178
  if (error instanceof ChainOutputValidationError) return { error: error.message };
2388
2179
  throw error;
2389
2180
  }
2390
- const diagnosticContext = params.unknownAgentDiagnosticContext ?? unknownAgentDiagnosticContext(discoverAgents(path6.resolve(runnerCwd), "both"));
2181
+ const diagnosticContext = params.unknownAgentDiagnosticContext ?? unknownAgentDiagnosticContext(discoverAgents(path5.resolve(runnerCwd), "both"));
2391
2182
  for (const s of chain) {
2392
2183
  const stepAgents = isParallelStep(s) ? s.parallel.map((t) => t.agent) : isDynamicParallelStep(s) ? [s.parallel.agent] : [s.agent];
2393
2184
  for (const agentName of stepAgents) {
@@ -2484,7 +2275,7 @@ function buildAsyncRunnerSteps(id, params) {
2484
2275
  stepCwd,
2485
2276
  ctx.cwd,
2486
2277
  a.skillPath,
2487
- a.filePath ? path6.dirname(a.filePath) : stepCwd
2278
+ a.filePath ? path5.dirname(a.filePath) : stepCwd
2488
2279
  );
2489
2280
  if (missingSkills.includes("pi-subagents")) throw new UnavailableSubagentSkillError(UNAVAILABLE_SUBAGENT_SKILL_ERROR);
2490
2281
  const systemPrompt = buildEffectiveSystemPrompt({ agent: a, resolvedSkills, cwd: stepCwd });
@@ -2657,7 +2448,7 @@ function buildAsyncRunnerSteps(id, params) {
2657
2448
  acceptanceRole: a.acceptanceRole,
2658
2449
  ...s.gateOn ? { gateOn: s.gateOn } : {},
2659
2450
  ...behavior.outputSchema ? { structuredOutputSchema: behavior.outputSchema } : {},
2660
- ...behavior.outputSchema ? { structuredOutput: createStructuredOutputRuntime(behavior.outputSchema, path6.join(asyncDir, "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(s.acceptance) }) } : {},
2451
+ ...behavior.outputSchema ? { structuredOutput: createStructuredOutputRuntime(behavior.outputSchema, path5.join(asyncDir, "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(s.acceptance) }) } : {},
2661
2452
  ...resolvedToolBudget.budget ? { toolBudget: resolvedToolBudget.budget } : {},
2662
2453
  ...s.worktree ? { worktree: true } : {}
2663
2454
  };
@@ -2831,14 +2622,15 @@ function executeAsyncChain(id, params) {
2831
2622
  if (acceptanceErrors.length > 0) return formatAsyncStartError(resultMode, acceptanceErrors.join(" "));
2832
2623
  const undefinedLauncher = chain.flatMap(getStepAgents).map((name) => agents.find((agent) => agent.name === name)?.launcher).find((name) => name !== void 0 && !lookupRunnerLauncher(ctx.runnerLaunchers, name));
2833
2624
  if (undefinedLauncher !== void 0) return formatAsyncStartError(resultMode, `Launcher '${undefinedLauncher}' used by this ${resultMode} is not defined in runnerLaunchers in the user subagent config.`);
2834
- const capabilityCeiling = params.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(ctx.currentSessionId);
2625
+ const launchParentSessionId = ctx.parentSessionId ?? ctx.currentSessionId;
2626
+ const capabilityCeiling = params.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(launchParentSessionId);
2835
2627
  const inheritedNestedRoute2 = inheritedNestedRouteOf(ctx.childRuntime);
2836
2628
  const nestedAddress = inheritedNestedRoute2 ? inheritedNestedParentAddressOf(ctx.childRuntime) : void 0;
2837
- const asyncDir = inheritedNestedRoute2 ? path6.join(TEMP_ROOT_DIR, "nested-subagent-runs", inheritedNestedRoute2.rootRunId, id) : path6.join(DIRS.async, id);
2629
+ const asyncDir = inheritedNestedRoute2 ? path5.join(TEMP_ROOT_DIR, "nested-subagent-runs", inheritedNestedRoute2.rootRunId, id) : path5.join(DIRS.async, id);
2838
2630
  let runFanoutBudget;
2839
2631
  try {
2840
2632
  runFanoutBudget = params.runFanoutBudget ?? createRunFanoutBudget(id, 64);
2841
- fs7.mkdirSync(asyncDir, { recursive: true });
2633
+ fs6.mkdirSync(asyncDir, { recursive: true });
2842
2634
  writeRunFanoutBudgetDescriptor(asyncDir, runFanoutBudget);
2843
2635
  } catch (error) {
2844
2636
  const message = error instanceof Error ? error.message : String(error);
@@ -2864,9 +2656,9 @@ function executeAsyncChain(id, params) {
2864
2656
  sessionFilesByFlatIndex,
2865
2657
  thinkingOverridesByFlatIndex,
2866
2658
  contextForAgent: params.contextForAgent,
2867
- progressDir: params.progressDir ?? (artifactsDir ? path6.join(artifactsDir, "progress", id) : resultMode === "parallel" ? path6.join(asyncDir, "progress") : void 0),
2659
+ progressDir: params.progressDir ?? (artifactsDir ? path5.join(artifactsDir, "progress", id) : resultMode === "parallel" ? path5.join(asyncDir, "progress") : void 0),
2868
2660
  agentContract: params.agentContract,
2869
- outputBaseDir: artifactsDir ? path6.join(artifactsDir, "outputs", id) : void 0,
2661
+ outputBaseDir: artifactsDir ? path5.join(artifactsDir, "outputs", id) : void 0,
2870
2662
  dynamicFanoutMaxItems: params.dynamicFanoutMaxItems,
2871
2663
  maxSubagentDepth,
2872
2664
  waitToolEnabled: params.waitToolEnabled,
@@ -2887,7 +2679,7 @@ function executeAsyncChain(id, params) {
2887
2679
  });
2888
2680
  if ("error" in built) {
2889
2681
  try {
2890
- fs7.rmSync(asyncDir, { recursive: true, force: true });
2682
+ fs6.rmSync(asyncDir, { recursive: true, force: true });
2891
2683
  } catch {
2892
2684
  }
2893
2685
  return formatAsyncStartError(resultMode, built.error);
@@ -2923,11 +2715,10 @@ function executeAsyncChain(id, params) {
2923
2715
  const initialStatusAt = Date.now();
2924
2716
  const initialCompletionOwnerId = ctx.completionOwnerId ?? currentCompletionOwnerId();
2925
2717
  const completionOwnerProcess = currentRecordedPid();
2926
- const launchParentSessionId = ctx.parentSessionId ?? ctx.currentSessionId;
2927
2718
  try {
2928
2719
  writeRetainedRequiredChildExtensions(asyncDir, params.requiredExtensions ?? ctx.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(launchParentSessionId ?? void 0));
2929
2720
  } catch (error) {
2930
- fs7.rmSync(asyncDir, { recursive: true, force: true });
2721
+ fs6.rmSync(asyncDir, { recursive: true, force: true });
2931
2722
  return formatAsyncStartError(resultMode, `Failed to record required child extensions: ${error instanceof Error ? error.message : String(error)}`);
2932
2723
  }
2933
2724
  let spawnResultOrPromise = {};
@@ -2943,7 +2734,7 @@ function executeAsyncChain(id, params) {
2943
2734
  artifactsDir: artifactConfig.enabled ? artifactsDir : void 0,
2944
2735
  artifactConfig,
2945
2736
  share: shareEnabled,
2946
- sessionDir: sessionRoot ? path6.join(sessionRoot, `async-${id}`) : void 0,
2737
+ sessionDir: sessionRoot ? path5.join(sessionRoot, `async-${id}`) : void 0,
2947
2738
  asyncDir,
2948
2739
  sessionId: ctx.currentSessionId,
2949
2740
  completionOwnerId: ctx.completionOwnerId ?? currentCompletionOwnerId(),
@@ -3000,7 +2791,7 @@ function executeAsyncChain(id, params) {
3000
2791
  ...launcher ? { launcher } : {},
3001
2792
  steps: initialStatusSteps
3002
2793
  },
3003
- path6.join(asyncDir, "status.json"),
2794
+ path5.join(asyncDir, "status.json"),
3004
2795
  launchParentSessionId,
3005
2796
  (proof) => emitProcessTerminalEvent(ctx, proof),
3006
2797
  (runnerProcessInstanceId) => params.activeAsyncCapacity?.markStarted(runnerProcessInstanceId)
@@ -3123,7 +2914,7 @@ function executeAsyncChain(id, params) {
3123
2914
  return spawnResultOrPromise instanceof Promise ? spawnResultOrPromise.then(finishSpawnResult) : finishSpawnResult(spawnResultOrPromise);
3124
2915
  }
3125
2916
  function workflowAwaitedAsyncResultPath(asyncDir) {
3126
- return path6.join(asyncDir, "workflow-result.json");
2917
+ return path5.join(asyncDir, "workflow-result.json");
3127
2918
  }
3128
2919
  function executeAsyncSingle(id, params) {
3129
2920
  const {
@@ -3183,7 +2974,7 @@ function executeAsyncSingle(id, params) {
3183
2974
  if (extensionBindings !== void 0) unsupported.push("extension bindings");
3184
2975
  if (unsupported.length > 0) return formatAsyncStartError("single", `Agent '${agentConfig.name}' uses runner.type='${externalRunnerType}' and does not support: ${unsupported.join(", ")}.`);
3185
2976
  }
3186
- const capabilityCeiling = intersectSubagentCapabilityCeilings(params.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(ctx.currentSessionId), ctx.childRuntime?.capabilityCeiling);
2977
+ const capabilityCeiling = intersectSubagentCapabilityCeilings(params.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(ctx.parentSessionId ?? ctx.currentSessionId), ctx.childRuntime?.capabilityCeiling);
3187
2978
  try {
3188
2979
  assertAgentAllowedByCapabilityCeiling(agentConfig.name, capabilityCeiling);
3189
2980
  } catch (error) {
@@ -3193,6 +2984,7 @@ function executeAsyncSingle(id, params) {
3193
2984
  const requestedMachine = params.machine ?? agentConfig.machine;
3194
2985
  const machineUnsupported = formatHerdrMachineRunnerUnsupported({ machine: requestedMachine, agentName: agentConfig.name, runnerType: agentConfig.runner?.type, adapter: agentConfig.runner?.type === "external-cli" ? agentConfig.runner.adapter : void 0, worktree: params.worktree });
3195
2986
  if (machineUnsupported) return formatAsyncStartError("single", machineUnsupported);
2987
+ if (requestedMachine && params.revivalLease) return formatAsyncStartError("single", PLACED_RESTORE_UNSUPPORTED);
3196
2988
  const resolvedLauncher = resolveAgentRunnerLauncher(agentConfig, ctx.runnerLaunchers, requestedMachine);
3197
2989
  if (resolvedLauncher.error) return formatAsyncStartError("single", resolvedLauncher.error);
3198
2990
  const launcher = resolvedLauncher.launcher;
@@ -3231,16 +3023,16 @@ function executeAsyncSingle(id, params) {
3231
3023
  runnerCwd,
3232
3024
  ctx.cwd,
3233
3025
  agentConfig.skillPath,
3234
- agentConfig.filePath ? path6.dirname(agentConfig.filePath) : runnerCwd
3026
+ agentConfig.filePath ? path5.dirname(agentConfig.filePath) : runnerCwd
3235
3027
  );
3236
3028
  if (missingSkills.includes("pi-subagents")) return formatAsyncStartError("single", UNAVAILABLE_SUBAGENT_SKILL_ERROR);
3237
3029
  const inheritedNestedRoute2 = inheritedNestedRouteOf(ctx.childRuntime);
3238
3030
  const nestedAddress = inheritedNestedRoute2 ? inheritedNestedParentAddressOf(ctx.childRuntime) : void 0;
3239
- const asyncDir = inheritedNestedRoute2 ? path6.join(TEMP_ROOT_DIR, "nested-subagent-runs", inheritedNestedRoute2.rootRunId, id) : path6.join(DIRS.async, id);
3031
+ const asyncDir = inheritedNestedRoute2 ? path5.join(TEMP_ROOT_DIR, "nested-subagent-runs", inheritedNestedRoute2.rootRunId, id) : path5.join(DIRS.async, id);
3240
3032
  let runFanoutBudget;
3241
3033
  try {
3242
3034
  runFanoutBudget = params.runFanoutBudget ?? createRunFanoutBudget(id, 64);
3243
- fs7.mkdirSync(asyncDir, { recursive: true });
3035
+ fs6.mkdirSync(asyncDir, { recursive: true });
3244
3036
  writeRunFanoutBudgetDescriptor(asyncDir, runFanoutBudget);
3245
3037
  } catch (error) {
3246
3038
  const message = error instanceof Error ? error.message : String(error);
@@ -3251,14 +3043,14 @@ function executeAsyncSingle(id, params) {
3251
3043
  };
3252
3044
  }
3253
3045
  const effectiveOutput = normalizeSingleOutputOverride(params.output, agentConfig.output);
3254
- const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, instructionCwd, params.outputBaseDir ?? (artifactsDir ? path6.join(artifactsDir, "outputs", id) : void 0));
3046
+ const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, instructionCwd, params.outputBaseDir ?? (artifactsDir ? path5.join(artifactsDir, "outputs", id) : void 0));
3255
3047
  const systemPrompt = buildEffectiveSystemPrompt({ agent: agentConfig, resolvedSkills, cwd: runnerCwd });
3256
3048
  const outputMode = params.outputMode ?? agentConfig.outputMode ?? "inline";
3257
3049
  const validationError = validateFileOnlyOutputMode(outputMode, outputPath, `Async single run (${agent})`);
3258
3050
  if (validationError) return formatAsyncStartError("single", validationError);
3259
3051
  const taskWithOutputInstruction = injectSingleOutputInstruction(task, outputPath, agentConfig);
3260
3052
  const reads = params.reads !== void 0 ? params.reads : agentConfig.defaultReads ?? false;
3261
- const readPaths = Array.isArray(reads) ? machine ? externalRunner ? reads.map((read) => read === "~" || read.startsWith("~/") || path6.posix.isAbsolute(read) ? read : path6.posix.resolve(instructionCwd, read)) : [] : managedWorktreeProvider === "worktrunk" ? resolveExistingReadInstructionPaths(reads, instructionCwd, readExistenceCwd) : resolveExistingReadPaths(reads, readExistenceCwd) : [];
3053
+ const readPaths = Array.isArray(reads) ? machine ? externalRunner ? reads.map((read) => read === "~" || read.startsWith("~/") || path5.posix.isAbsolute(read) ? read : path5.posix.resolve(instructionCwd, read)) : [] : managedWorktreeProvider === "worktrunk" ? resolveExistingReadInstructionPaths(reads, instructionCwd, readExistenceCwd) : resolveExistingReadPaths(reads, readExistenceCwd) : [];
3262
3054
  const readsInstruction = readPaths.length > 0 ? `[Read from: ${readPaths.join(", ")}]
3263
3055
 
3264
3056
  ` : "";
@@ -3330,8 +3122,8 @@ function executeAsyncSingle(id, params) {
3330
3122
  if (resolvedToolTimeout.error) return formatAsyncStartError("single", resolvedToolTimeout.error);
3331
3123
  const toolTimeoutMs = resolvedToolTimeout.toolTimeoutMs;
3332
3124
  const initialUsageBudget = usageBudgetState(params.usageBudget, void 0);
3333
- const resolvedSessionDir = params.sessionDir ?? (sessionRoot ? path6.join(sessionRoot, `async-${id}`) : void 0);
3334
- const structuredOutput = params.structuredOutputSchema ? createStructuredOutputRuntime(params.structuredOutputSchema, path6.join(asyncDir, "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : void 0;
3125
+ const resolvedSessionDir = params.sessionDir ?? (sessionRoot ? path5.join(sessionRoot, `async-${id}`) : void 0);
3126
+ const structuredOutput = params.structuredOutputSchema ? createStructuredOutputRuntime(params.structuredOutputSchema, path5.join(asyncDir, "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : void 0;
3335
3127
  let selectedModel = model;
3336
3128
  let requestedModel;
3337
3129
  if (!externalRunner) {
@@ -3454,7 +3246,7 @@ function executeAsyncSingle(id, params) {
3454
3246
  };
3455
3247
  if (!externalRunner) {
3456
3248
  try {
3457
- writePrivateAtomicJson(path6.join(asyncDir, "recovery-descriptor.json"), recoveryDescriptor);
3249
+ writePrivateAtomicJson(path5.join(asyncDir, "recovery-descriptor.json"), recoveryDescriptor);
3458
3250
  } catch (error) {
3459
3251
  return formatAsyncStartError("single", `Failed to persist async recovery descriptor for '${id}': ${error instanceof Error ? error.message : String(error)}`);
3460
3252
  }
@@ -3601,7 +3393,7 @@ function executeAsyncSingle(id, params) {
3601
3393
  ...launcher ? { launcher } : {},
3602
3394
  steps: [{ agent, status: "pending", ...lane ? { lane } : {}, ...model ? { model } : {}, ...contextLimit !== void 0 ? { contextLimit } : {} }]
3603
3395
  },
3604
- path6.join(asyncDir, "status.json"),
3396
+ path5.join(asyncDir, "status.json"),
3605
3397
  launchParentSessionId,
3606
3398
  (proof) => emitProcessTerminalEvent(ctx, proof),
3607
3399
  (runnerProcessInstanceId) => params.activeAsyncCapacity?.markStarted(runnerProcessInstanceId),
@@ -3809,10 +3601,10 @@ function lineFromCheck(label, check) {
3809
3601
  }
3810
3602
  function formatExistingDirectory(label, dirPath) {
3811
3603
  try {
3812
- if (!fs8.existsSync(dirPath)) return `- ${label}: missing (${dirPath})`;
3813
- const stats = fs8.statSync(dirPath);
3604
+ if (!fs7.existsSync(dirPath)) return `- ${label}: missing (${dirPath})`;
3605
+ const stats = fs7.statSync(dirPath);
3814
3606
  if (!stats.isDirectory()) throw new Error(`not a directory: ${dirPath}`);
3815
- fs8.accessSync(dirPath, fs8.constants.R_OK | fs8.constants.W_OK);
3607
+ fs7.accessSync(dirPath, fs7.constants.R_OK | fs7.constants.W_OK);
3816
3608
  return `- ${label}: ok (${dirPath})`;
3817
3609
  } catch (error) {
3818
3610
  return `- ${label}: failed (${dirPath}) \u2014 ${errorText(error)}`;
@@ -3840,10 +3632,10 @@ function formatSkillSourceCounts(skills) {
3840
3632
  }
3841
3633
  function formatConfiguredSessionDir(input) {
3842
3634
  if (input.requestedSessionDir) {
3843
- return path7.resolve(input.expandTilde?.(input.requestedSessionDir) ?? input.requestedSessionDir);
3635
+ return path6.resolve(input.expandTilde?.(input.requestedSessionDir) ?? input.requestedSessionDir);
3844
3636
  }
3845
3637
  if (input.config.defaultSessionDir) {
3846
- return path7.resolve(input.expandTilde?.(input.config.defaultSessionDir) ?? input.config.defaultSessionDir);
3638
+ return path6.resolve(input.expandTilde?.(input.config.defaultSessionDir) ?? input.config.defaultSessionDir);
3847
3639
  }
3848
3640
  return "not configured";
3849
3641
  }
@@ -3852,7 +3644,7 @@ function formatSessionLines(input) {
3852
3644
  const lines = [
3853
3645
  lineFromCheck("configured session dir", () => `- configured session dir: ${formatConfiguredSessionDir(input)}`),
3854
3646
  `- current session file: ${sessionFile ?? "not available"}`,
3855
- `- current session dir: ${sessionFile ? path7.dirname(sessionFile) : "not available"}`,
3647
+ `- current session dir: ${sessionFile ? path6.dirname(sessionFile) : "not available"}`,
3856
3648
  `- current session id: ${input.currentSessionId ?? input.state.currentSessionId ?? "not available"}`
3857
3649
  ];
3858
3650
  if (input.sessionError) lines.push(`- session manager: failed \u2014 ${input.sessionError}`);
@@ -3987,8 +3779,7 @@ var WORKFLOW_FENCE = /^```(?:js|javascript) workflow[ \t]*$/;
3987
3779
  var PLAIN_JS_FENCE = /^```(?:js|javascript)[ \t]*$/;
3988
3780
  var OPEN_FENCE = /^(`{3,}|~{3,})/;
3989
3781
  var CLOSE_FENCE = /^(`{3,}|~{3,})[ \t]*$/;
3990
- var SUMMARY_NOTE = 'On some models, text written after a tool call in the same turn reaches the session only as a summary without code blocks, so for the rest of this turn write the script to a file and pass its path, such as workflow: "./script.js".';
3991
- var FILE_FALLBACK = `If the block is in your reply: ${SUMMARY_NOTE}`;
3782
+ var SUMMARY_NOTE = `On some hosts, text written after a tool call in the same turn reaches the session only as a summary without code blocks, so for the rest of this turn pass the script's source as a tool argument: options: { script: "..." } in place of workflow: true, with the call's other fields unchanged.`;
3992
3783
  function readReplyWorkflowScript(sessionManager, toolCallId) {
3993
3784
  const branch = sessionManager.getBranch();
3994
3785
  for (let index = branch.length - 1; index >= 0; index--) {
@@ -4011,7 +3802,7 @@ function scriptFromReply(content) {
4011
3802
  const blocks = tagged.length > 0 ? tagged : plain.length === 1 ? plain : [];
4012
3803
  if (blocks.length !== 1) {
4013
3804
  const untagged = tagged.length === 0 && plain.length > 1 ? ` This reply has ${plain.length} untagged js blocks; open the script's block with the line "\`\`\`js workflow".` : "";
4014
- return { error: `workflow: true needs one fenced block in the same reply as the tool call, opened with the exact line "\`\`\`js workflow" and closed with "\`\`\`"; found ${tagged.length}.${untagged} ${FILE_FALLBACK}` };
3805
+ return { error: `workflow: true needs one fenced block in the same reply as the tool call, opened with the exact line "\`\`\`js workflow" and closed with "\`\`\`"; found ${tagged.length}.${untagged} If the block is in your reply: ${SUMMARY_NOTE}` };
4015
3806
  }
4016
3807
  const script = blocks[0];
4017
3808
  if (!script.trim()) return { error: "The script's fenced block in this reply is empty." };
@@ -4038,14 +3829,14 @@ function workflowBlocks(text) {
4038
3829
  }
4039
3830
 
4040
3831
  // src/runs/foreground/execution.ts
4041
- import { existsSync as existsSync5, mkdirSync as mkdirSync6, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
4042
- import * as path11 from "node:path";
3832
+ import { existsSync as existsSync4, mkdirSync as mkdirSync6, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
3833
+ import * as path10 from "node:path";
4043
3834
 
4044
3835
  // src/shared/fork-session-cwd.ts
4045
- import * as fs9 from "node:fs";
4046
- import * as path8 from "node:path";
3836
+ import * as fs8 from "node:fs";
3837
+ import * as path7 from "node:path";
4047
3838
  function alignForkedSessionCwd(sessionFile, cwd) {
4048
- const lines = fs9.readFileSync(sessionFile, "utf-8").split("\n").filter((line) => line.trim().length > 0);
3839
+ const lines = fs8.readFileSync(sessionFile, "utf-8").split("\n").filter((line) => line.trim().length > 0);
4049
3840
  const entries = lines.map((line, index) => {
4050
3841
  try {
4051
3842
  return JSON.parse(line);
@@ -4056,16 +3847,16 @@ function alignForkedSessionCwd(sessionFile, cwd) {
4056
3847
  });
4057
3848
  const header = entries[0];
4058
3849
  if (header?.type !== "session") throw new Error(`Forked session ${sessionFile} does not start with a session header.`);
4059
- const effectiveCwd = fs9.realpathSync.native(path8.resolve(cwd));
3850
+ const effectiveCwd = fs8.realpathSync.native(path7.resolve(cwd));
4060
3851
  if (header.cwd === effectiveCwd) return;
4061
3852
  header.cwd = effectiveCwd;
4062
- fs9.writeFileSync(sessionFile, `${entries.map((entry) => JSON.stringify(entry)).join("\n")}
3853
+ fs8.writeFileSync(sessionFile, `${entries.map((entry) => JSON.stringify(entry)).join("\n")}
4063
3854
  `, "utf-8");
4064
3855
  }
4065
3856
 
4066
3857
  // src/shared/child-transcript.ts
4067
- import * as fs10 from "node:fs";
4068
- import * as path9 from "node:path";
3858
+ import * as fs9 from "node:fs";
3859
+ import * as path8 from "node:path";
4069
3860
  var MAX_TOOL_PAYLOAD_BYTES = 32 * 1024;
4070
3861
  var TOOL_PAYLOAD_TRUNCATION_MARKER = "\n\n\u2026 payload truncated";
4071
3862
  function boundedPayload(value, maxBytes = MAX_TOOL_PAYLOAD_BYTES) {
@@ -4142,7 +3933,7 @@ function createChildTranscriptWriter(input) {
4142
3933
  const markerBytes = Buffer.byteLength(marker, "utf-8");
4143
3934
  if (bytesWritten + markerBytes > maxBytes) return false;
4144
3935
  try {
4145
- fs10.appendFileSync(input.transcriptPath, marker, "utf-8");
3936
+ fs9.appendFileSync(input.transcriptPath, marker, "utf-8");
4146
3937
  bytesWritten += markerBytes;
4147
3938
  return true;
4148
3939
  } catch (error) {
@@ -4170,15 +3961,15 @@ function createChildTranscriptWriter(input) {
4170
3961
  return;
4171
3962
  }
4172
3963
  try {
4173
- fs10.appendFileSync(input.transcriptPath, line, "utf-8");
3964
+ fs9.appendFileSync(input.transcriptPath, line, "utf-8");
4174
3965
  bytesWritten += bytes;
4175
3966
  } catch (error) {
4176
3967
  writeError = `Failed to write child transcript '${input.transcriptPath}': ${errorMessage(error)}`;
4177
3968
  }
4178
3969
  };
4179
3970
  try {
4180
- fs10.mkdirSync(path9.dirname(input.transcriptPath), { recursive: true });
4181
- fs10.writeFileSync(input.transcriptPath, "", "utf-8");
3971
+ fs9.mkdirSync(path8.dirname(input.transcriptPath), { recursive: true });
3972
+ fs9.writeFileSync(input.transcriptPath, "", "utf-8");
4182
3973
  } catch (error) {
4183
3974
  writeError = `Failed to initialize child transcript '${input.transcriptPath}': ${errorMessage(error)}`;
4184
3975
  }
@@ -4300,7 +4091,7 @@ ${text}`;
4300
4091
  }
4301
4092
 
4302
4093
  // src/shared/jsonl-writer.ts
4303
- import * as fs11 from "node:fs";
4094
+ import * as fs10 from "node:fs";
4304
4095
  var DEFAULT_MAX_JSONL_BYTES = 50 * 1024 * 1024;
4305
4096
  function createJsonlWriter(filePath, source, deps = {}) {
4306
4097
  if (!filePath) {
@@ -4311,7 +4102,7 @@ function createJsonlWriter(filePath, source, deps = {}) {
4311
4102
  }
4312
4103
  };
4313
4104
  }
4314
- const createWriteStream3 = deps.createWriteStream ?? ((targetPath) => fs11.createWriteStream(targetPath, { flags: "a" }));
4105
+ const createWriteStream3 = deps.createWriteStream ?? ((targetPath) => fs10.createWriteStream(targetPath, { flags: "a" }));
4315
4106
  let stream;
4316
4107
  try {
4317
4108
  stream = createWriteStream3(filePath);
@@ -4361,15 +4152,15 @@ function createJsonlWriter(filePath, source, deps = {}) {
4361
4152
  closed = true;
4362
4153
  const current = stream;
4363
4154
  stream = void 0;
4364
- await new Promise((resolve10) => current.end(() => resolve10()));
4155
+ await new Promise((resolve9) => current.end(() => resolve9()));
4365
4156
  }
4366
4157
  };
4367
4158
  }
4368
4159
 
4369
4160
  // src/runs/shared/orca-progress-tabs.ts
4370
4161
  import { spawn as spawn2 } from "node:child_process";
4371
- import * as fs12 from "node:fs";
4372
- import * as path10 from "node:path";
4162
+ import * as fs11 from "node:fs";
4163
+ import * as path9 from "node:path";
4373
4164
  import { createHash, randomUUID as randomUUID3 } from "node:crypto";
4374
4165
  var ORCA_CREATE_TIMEOUT_MS = 2e4;
4375
4166
  var ORCA_KILL_GRACE_MS = 2e3;
@@ -4414,10 +4205,10 @@ var ORCA_CLEANUP_WATCHDOG_SCRIPT = [
4414
4205
  ].join("");
4415
4206
  function executableFile(candidate) {
4416
4207
  try {
4417
- const stats = fs12.statSync(candidate);
4208
+ const stats = fs11.statSync(candidate);
4418
4209
  if (!stats.isFile()) return false;
4419
4210
  if (process.platform === "win32") return true;
4420
- fs12.accessSync(candidate, fs12.constants.X_OK);
4211
+ fs11.accessSync(candidate, fs11.constants.X_OK);
4421
4212
  return true;
4422
4213
  } catch {
4423
4214
  return false;
@@ -4431,9 +4222,9 @@ function executableNames(command, env) {
4431
4222
  function resolveOrcaCommand(env = process.env) {
4432
4223
  const override = env.PI_SUBAGENT_ORCA_BINARY?.trim();
4433
4224
  if (override) return executableFile(override) ? override : void 0;
4434
- for (const directory of (env.PATH ?? "").split(path10.delimiter).filter(Boolean)) {
4225
+ for (const directory of (env.PATH ?? "").split(path9.delimiter).filter(Boolean)) {
4435
4226
  for (const name of executableNames("orca", env)) {
4436
- const candidate = path10.join(directory, name);
4227
+ const candidate = path9.join(directory, name);
4437
4228
  if (executableFile(candidate)) return candidate;
4438
4229
  }
4439
4230
  }
@@ -4470,15 +4261,15 @@ function viewerCommand(nodeExecutable, logPath, donePath) {
4470
4261
  return invocation;
4471
4262
  }
4472
4263
  function progressRoot() {
4473
- return path10.join(TEMP_ROOT_DIR, "orca-progress");
4264
+ return path9.join(TEMP_ROOT_DIR, "orca-progress");
4474
4265
  }
4475
4266
  function pruneStaleProgressFiles(root, now = Date.now()) {
4476
4267
  try {
4477
- for (const entry of fs12.readdirSync(root, { withFileTypes: true })) {
4268
+ for (const entry of fs11.readdirSync(root, { withFileTypes: true })) {
4478
4269
  if (!entry.isFile() || !entry.name.endsWith(".log") && !entry.name.endsWith(".done") && !entry.name.endsWith(".ready") && !entry.name.endsWith(".pending")) continue;
4479
- const file = path10.join(root, entry.name);
4270
+ const file = path9.join(root, entry.name);
4480
4271
  try {
4481
- if (now - fs12.statSync(file).mtimeMs > STALE_PROGRESS_MAX_AGE_MS) fs12.rmSync(file, { force: true });
4272
+ if (now - fs11.statSync(file).mtimeMs > STALE_PROGRESS_MAX_AGE_MS) fs11.rmSync(file, { force: true });
4482
4273
  } catch {
4483
4274
  }
4484
4275
  }
@@ -4491,9 +4282,9 @@ function safeSegment(value, fallback = "subagent") {
4491
4282
  }
4492
4283
  function observerManifestPath(cwd, stem) {
4493
4284
  try {
4494
- const dir = path10.join(getProjectSubagentsDir(resolveSequenceScope(cwd)), "views", "orca");
4495
- fs12.mkdirSync(dir, { recursive: true, mode: 448 });
4496
- return path10.join(dir, `${stem}.json`);
4285
+ const dir = path9.join(getProjectSubagentsDir(resolveSequenceScope(cwd)), "views", "orca");
4286
+ fs11.mkdirSync(dir, { recursive: true, mode: 448 });
4287
+ return path9.join(dir, `${stem}.json`);
4497
4288
  } catch {
4498
4289
  return void 0;
4499
4290
  }
@@ -4501,7 +4292,7 @@ function observerManifestPath(cwd, stem) {
4501
4292
  function writeObserverManifest(manifestPath, manifest) {
4502
4293
  if (!manifestPath) return;
4503
4294
  try {
4504
- fs12.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
4295
+ fs11.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}
4505
4296
  `, { encoding: "utf-8", mode: 384 });
4506
4297
  } catch {
4507
4298
  }
@@ -4511,18 +4302,18 @@ function sleepSync(ms) {
4511
4302
  Atomics.wait(signal, 0, 0, ms);
4512
4303
  }
4513
4304
  function resolveSequenceScope(cwd) {
4514
- let current = path10.resolve(cwd);
4305
+ let current = path9.resolve(cwd);
4515
4306
  try {
4516
- current = fs12.realpathSync(current);
4307
+ current = fs11.realpathSync(current);
4517
4308
  } catch {
4518
4309
  }
4519
4310
  while (true) {
4520
4311
  try {
4521
- if (fs12.existsSync(path10.join(current, ".git"))) return current;
4312
+ if (fs11.existsSync(path9.join(current, ".git"))) return current;
4522
4313
  } catch {
4523
4314
  }
4524
- const parent = path10.dirname(current);
4525
- if (parent === current) return path10.resolve(cwd);
4315
+ const parent = path9.dirname(current);
4316
+ if (parent === current) return path9.resolve(cwd);
4526
4317
  current = parent;
4527
4318
  }
4528
4319
  }
@@ -4530,18 +4321,18 @@ function sequenceKey(cwd) {
4530
4321
  return createHash("sha256").update(resolveSequenceScope(cwd)).digest("hex").slice(0, 20);
4531
4322
  }
4532
4323
  function withSequenceLock(root, key, fn) {
4533
- const lockPath = path10.join(root, `counter-${key}.lock`);
4324
+ const lockPath = path9.join(root, `counter-${key}.lock`);
4534
4325
  let locked = false;
4535
4326
  for (let attempt = 0; attempt < COUNTER_LOCK_RETRIES; attempt++) {
4536
4327
  try {
4537
- fs12.mkdirSync(lockPath, { mode: 448 });
4328
+ fs11.mkdirSync(lockPath, { mode: 448 });
4538
4329
  locked = true;
4539
4330
  break;
4540
4331
  } catch (error) {
4541
4332
  if (error.code !== "EEXIST") break;
4542
4333
  try {
4543
- if (Date.now() - fs12.statSync(lockPath).mtimeMs > COUNTER_LOCK_STALE_MS) {
4544
- fs12.rmSync(lockPath, { recursive: true, force: true });
4334
+ if (Date.now() - fs11.statSync(lockPath).mtimeMs > COUNTER_LOCK_STALE_MS) {
4335
+ fs11.rmSync(lockPath, { recursive: true, force: true });
4545
4336
  continue;
4546
4337
  }
4547
4338
  } catch {
@@ -4554,7 +4345,7 @@ function withSequenceLock(root, key, fn) {
4554
4345
  return fn();
4555
4346
  } finally {
4556
4347
  try {
4557
- fs12.rmSync(lockPath, { recursive: true, force: true });
4348
+ fs11.rmSync(lockPath, { recursive: true, force: true });
4558
4349
  } catch {
4559
4350
  }
4560
4351
  }
@@ -4563,18 +4354,18 @@ function predecessorMarker(pathValue) {
4563
4354
  if (!pathValue) return void 0;
4564
4355
  const ready = pathValue.endsWith(".pending") ? pathValue.replace(/\.pending$/, ".ready") : pathValue;
4565
4356
  const pending = ready.replace(/\.ready$/, ".pending");
4566
- if (fs12.existsSync(ready) || fs12.existsSync(pending)) return pending;
4357
+ if (fs11.existsSync(ready) || fs11.existsSync(pending)) return pending;
4567
4358
  return void 0;
4568
4359
  }
4569
4360
  function reserveTabSequence(root, cwd) {
4570
4361
  const key = sequenceKey(cwd);
4571
- const counterPath = path10.join(root, `counter-${key}`);
4572
- const createDone = path10.join(root, `create-${key}-${randomUUID3()}.pending`);
4362
+ const counterPath = path9.join(root, `counter-${key}`);
4363
+ const createDone = path9.join(root, `create-${key}-${randomUUID3()}.pending`);
4573
4364
  return withSequenceLock(root, key, () => {
4574
4365
  let current = 0;
4575
4366
  let previousCreateDone;
4576
4367
  try {
4577
- const raw = fs12.readFileSync(counterPath, "utf-8");
4368
+ const raw = fs11.readFileSync(counterPath, "utf-8");
4578
4369
  const [countLine, previousLine] = raw.split("\n");
4579
4370
  const parsed = Number.parseInt(countLine ?? "", 10);
4580
4371
  if (Number.isSafeInteger(parsed) && parsed >= 0) current = parsed;
@@ -4583,14 +4374,14 @@ function reserveTabSequence(root, cwd) {
4583
4374
  }
4584
4375
  const next = current + 1;
4585
4376
  try {
4586
- fs12.writeFileSync(createDone, "", { encoding: "utf-8", mode: 384 });
4587
- fs12.writeFileSync(counterPath, `${next}
4377
+ fs11.writeFileSync(createDone, "", { encoding: "utf-8", mode: 384 });
4378
+ fs11.writeFileSync(counterPath, `${next}
4588
4379
  ${createDone}
4589
4380
  `, { encoding: "utf-8", mode: 384 });
4590
4381
  return { sequence: next, previousCreateDone, createDone };
4591
4382
  } catch {
4592
4383
  try {
4593
- fs12.rmSync(createDone, { force: true });
4384
+ fs11.rmSync(createDone, { force: true });
4594
4385
  } catch {
4595
4386
  }
4596
4387
  return void 0;
@@ -4612,8 +4403,8 @@ function scheduleCleanup(nodeExecutable, paths) {
4612
4403
  }
4613
4404
  function loadOrcaProgressTabsConfig() {
4614
4405
  try {
4615
- const configPath = path10.join(getAgentDir(), "extensions", "subagent", "config.json");
4616
- const parsed = JSON.parse(fs12.readFileSync(configPath, "utf-8"));
4406
+ const configPath = path9.join(getAgentDir(), "extensions", "subagent", "config.json");
4407
+ const parsed = JSON.parse(fs11.readFileSync(configPath, "utf-8"));
4617
4408
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
4618
4409
  const value = parsed.orcaProgressTabs;
4619
4410
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
@@ -4632,7 +4423,7 @@ function createOrcaProgressTab(input) {
4632
4423
  const nodeExecutable = resolveNodeExecutable();
4633
4424
  const root = progressRoot();
4634
4425
  try {
4635
- fs12.mkdirSync(root, { recursive: true, mode: 448 });
4426
+ fs11.mkdirSync(root, { recursive: true, mode: 448 });
4636
4427
  } catch {
4637
4428
  return void 0;
4638
4429
  }
@@ -4646,12 +4437,12 @@ function createOrcaProgressTab(input) {
4646
4437
  const tabSequence = reservation.sequence;
4647
4438
  const stem = `${runId}-${index}-${randomUUID3()}`;
4648
4439
  const stepCount = typeof input.stepCount === "number" && Number.isInteger(input.stepCount) && input.stepCount > 0 ? input.stepCount : 1;
4649
- const logPath = path10.join(root, `${stem}.log`);
4650
- const donePath = path10.join(root, `${stem}.done`);
4440
+ const logPath = path9.join(root, `${stem}.log`);
4441
+ const donePath = path9.join(root, `${stem}.done`);
4651
4442
  const title = `subagents \xB7 ${agent} \xB7 ${tabSequence}`;
4652
4443
  const markCreateReady = () => {
4653
4444
  try {
4654
- fs12.writeFileSync(reservation.createDone.replace(/\.pending$/, ".ready"), "");
4445
+ fs11.writeFileSync(reservation.createDone.replace(/\.pending$/, ".ready"), "");
4655
4446
  } catch {
4656
4447
  }
4657
4448
  };
@@ -4663,36 +4454,36 @@ function createOrcaProgressTab(input) {
4663
4454
  role: "run",
4664
4455
  runId,
4665
4456
  title,
4666
- worktree: path10.resolve(cwd),
4457
+ worktree: path9.resolve(cwd),
4667
4458
  state: "opening",
4668
4459
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
4669
4460
  logPath
4670
4461
  });
4671
4462
  try {
4672
- fs12.writeFileSync(logPath, `pi-subagents / ${agent}
4463
+ fs11.writeFileSync(logPath, `pi-subagents / ${agent}
4673
4464
  run ${runId} \xB7 ${stepCount === 1 ? "1 child" : `${stepCount} children`}
4674
4465
  ${"\u2500".repeat(48)}
4675
4466
  `, { encoding: "utf-8", mode: 384 });
4676
- fs12.rmSync(donePath, { force: true });
4467
+ fs11.rmSync(donePath, { force: true });
4677
4468
  } catch {
4678
4469
  markCreateReady();
4679
4470
  return void 0;
4680
4471
  }
4681
4472
  let available = true;
4682
4473
  let truncated = false;
4683
- let scheduledBytes = fs12.statSync(logPath).size;
4474
+ let scheduledBytes = fs11.statSync(logPath).size;
4684
4475
  const progressByteLimit = MAX_MIRROR_BYTES - MIRROR_FOOTER_RESERVE_BYTES;
4685
- const logStream = fs12.createWriteStream(logPath, { flags: "a", mode: 384 });
4476
+ const logStream = fs11.createWriteStream(logPath, { flags: "a", mode: 384 });
4686
4477
  const failObserver = () => {
4687
4478
  if (!available) return;
4688
4479
  available = false;
4689
4480
  logStream.destroy();
4690
4481
  try {
4691
- fs12.rmSync(logPath, { force: true });
4482
+ fs11.rmSync(logPath, { force: true });
4692
4483
  } catch {
4693
4484
  }
4694
4485
  try {
4695
- fs12.rmSync(donePath, { force: true });
4486
+ fs11.rmSync(donePath, { force: true });
4696
4487
  } catch {
4697
4488
  }
4698
4489
  };
@@ -4713,8 +4504,8 @@ ${"\u2500".repeat(48)}
4713
4504
  };
4714
4505
  let createSettled = false;
4715
4506
  let resolveCreationSettled;
4716
- const creationSettled = new Promise((resolve10) => {
4717
- resolveCreationSettled = resolve10;
4507
+ const creationSettled = new Promise((resolve9) => {
4508
+ resolveCreationSettled = resolve9;
4718
4509
  });
4719
4510
  let cleanupPaths;
4720
4511
  const scheduleDeferredCleanup = () => {
@@ -4736,7 +4527,7 @@ ${"\u2500".repeat(48)}
4736
4527
  "terminal",
4737
4528
  "create",
4738
4529
  "--worktree",
4739
- `path:${path10.resolve(cwd)}`,
4530
+ `path:${path9.resolve(cwd)}`,
4740
4531
  "--title",
4741
4532
  title,
4742
4533
  "--command",
@@ -4804,7 +4595,7 @@ ${"\u2500".repeat(16)} child ${index2 + 1}/${count} \xB7 ${label} ${"\u2500".rep
4804
4595
  let verifiedSessionFile;
4805
4596
  if (sessionId && sessionFile) {
4806
4597
  try {
4807
- verifiedSessionFile = fs12.realpathSync(sessionFile);
4598
+ verifiedSessionFile = fs11.realpathSync(sessionFile);
4808
4599
  } catch {
4809
4600
  }
4810
4601
  }
@@ -4819,18 +4610,18 @@ ${terminalMessage}
4819
4610
  if (scheduledBytes + Buffer.byteLength(footer) > MAX_MIRROR_BYTES) footer = `
4820
4611
  ${status}
4821
4612
  `;
4822
- return new Promise((resolve10) => {
4613
+ return new Promise((resolve9) => {
4823
4614
  logStream.end(footer, () => {
4824
4615
  if (available) {
4825
4616
  try {
4826
- fs12.writeFileSync(donePath, `${status}
4617
+ fs11.writeFileSync(donePath, `${status}
4827
4618
  `, { encoding: "utf-8", mode: 384 });
4828
4619
  } catch {
4829
4620
  }
4830
4621
  cleanupPaths = [logPath, donePath];
4831
4622
  scheduleDeferredCleanup();
4832
4623
  }
4833
- resolve10();
4624
+ resolve9();
4834
4625
  });
4835
4626
  });
4836
4627
  }
@@ -5456,7 +5247,7 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
5456
5247
  childIndex: options.index ?? 0
5457
5248
  }) : void 0;
5458
5249
  const permissionRules = resolvePermissionRules(options.permissions, agent.permissions);
5459
- const permissionAuditPath = permissionRules && options.artifactsDir ? path11.join(options.artifactsDir, "permission-audit", `${options.runId}-${options.index ?? 0}.jsonl`) : void 0;
5250
+ const permissionAuditPath = permissionRules && options.artifactsDir ? path10.join(options.artifactsDir, "permission-audit", `${options.runId}-${options.index ?? 0}.jsonl`) : void 0;
5460
5251
  let onWatchdogStatus;
5461
5252
  const launch = buildInProcessChildLaunch({
5462
5253
  machine: options.machine,
@@ -5647,7 +5438,7 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5647
5438
  const childSessions = options.childSessionFactory ?? childSessionFactory();
5648
5439
  const partialOutput = createPartialOutputTracker();
5649
5440
  let childPromptFailed = false;
5650
- const exitCode = await new Promise((resolve10) => {
5441
+ const exitCode = await new Promise((resolve9) => {
5651
5442
  const jsonlWriter = createJsonlWriter(shared.jsonlPath, { pause() {
5652
5443
  }, resume() {
5653
5444
  } });
@@ -5720,6 +5511,8 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5720
5511
  let agentSettledReceived = false;
5721
5512
  let queuedDrainHold = false;
5722
5513
  let compactionStartedReceived = false;
5514
+ let terminalAgentEndReceived = false;
5515
+ let compactionAfterFinalOpen = false;
5723
5516
  let finalDrainTimer;
5724
5517
  let finalHardFinishTimer;
5725
5518
  let watchdogTailTimer;
@@ -5762,7 +5555,7 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5762
5555
  if (sessionSettled || finalDrainTimer || lifecycleFinished) return;
5763
5556
  finalDrainTimer = setTimeout(() => {
5764
5557
  if (lifecycleFinished || sessionSettled) return;
5765
- if (capture.finalDrainHeld() || observeQueuedDrainHold()) {
5558
+ if (capture.finalDrainHeld() || observeQueuedDrainHold() || compactionAfterFinalOpen) {
5766
5559
  finalDrainTimer = void 0;
5767
5560
  armFinalDrainTimer();
5768
5561
  return;
@@ -5776,9 +5569,7 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5776
5569
  if (lifecycleFinished || sessionSettled) return;
5777
5570
  settle(void 0, true);
5778
5571
  }, HARD_FINISH_MS);
5779
- finalHardFinishTimer.unref?.();
5780
5572
  }, FINAL_STOP_GRACE_MS);
5781
- finalDrainTimer.unref?.();
5782
5573
  };
5783
5574
  function armWatchdogTail() {
5784
5575
  if (!cleanTerminalAssistantStopReceived && !agentSettledReceived || watchdogTailTimer || lifecycleFinished || sessionSettled) return;
@@ -5796,12 +5587,18 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5796
5587
  }, childWatchdog?.watchdogTailTimeoutMs ?? 12e4);
5797
5588
  watchdogTailTimer.unref?.();
5798
5589
  }
5799
- const applyChildLifecycle = (action) => {
5590
+ const applyChildLifecycle = (action, event) => {
5800
5591
  if (action === "cancel-drain") {
5801
- cleanTerminalAssistantStopReceived = false;
5592
+ terminalAgentEndReceived = event?.type === "agent_end" && event.willRetry !== true && cleanTerminalAssistantStopReceived;
5802
5593
  agentSettledReceived = false;
5803
5594
  clearFinalDrainTimers();
5804
5595
  clearWatchdogTailTimer();
5596
+ if (terminalAgentEndReceived) {
5597
+ startFinalDrain();
5598
+ return;
5599
+ }
5600
+ cleanTerminalAssistantStopReceived = false;
5601
+ compactionAfterFinalOpen = false;
5805
5602
  return;
5806
5603
  }
5807
5604
  if (action === "start-drain") startFinalDrain();
@@ -5851,7 +5648,7 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5851
5648
  }
5852
5649
  await session?.dispose();
5853
5650
  }).catch(() => void 0).then(() => {
5854
- resolve10(code);
5651
+ resolve9(code);
5855
5652
  });
5856
5653
  };
5857
5654
  const drainPendingControlEvents = () => {
@@ -5883,13 +5680,13 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
5883
5680
  };
5884
5681
  const recordActiveToolCall = (event, args, now) => {
5885
5682
  const key = toolTimeoutCallKey(event, ++activeToolSequence);
5886
- const path20 = resolveCurrentPath(event.toolName, args);
5683
+ const path19 = resolveCurrentPath(event.toolName, args);
5887
5684
  const active = {
5888
5685
  key,
5889
5686
  tool: event.toolName,
5890
5687
  args: extractToolArgsPreview(args),
5891
5688
  startedAt: now,
5892
- ...path20 !== void 0 ? { path: path20 } : {}
5689
+ ...path19 !== void 0 ? { path: path19 } : {}
5893
5690
  };
5894
5691
  activeToolCalls.set(key, active);
5895
5692
  const keys = activeToolKeysByName.get(active.tool) ?? [];
@@ -6042,11 +5839,17 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
6042
5839
  if (evt.type === "compaction_start") {
6043
5840
  compactionStartedReceived = true;
6044
5841
  if (agentSettledReceived) afterCompactionSettlement = true;
5842
+ if (terminalAgentEndReceived) compactionAfterFinalOpen = true;
6045
5843
  }
6046
5844
  if (evt.type === "compaction_end" && evt.willRetry === true) {
6047
5845
  compactionStartedReceived = false;
6048
5846
  afterCompactionSettlement = false;
6049
5847
  }
5848
+ if (evt.type === "compaction_end" && evt.willRetry !== true && compactionAfterFinalOpen) {
5849
+ compactionAfterFinalOpen = false;
5850
+ clearFinalDrainTimers();
5851
+ startFinalDrain();
5852
+ }
6050
5853
  if (evt.type === "turn_start" || evt.type === "agent_start" || evt.type === "auto_retry_start") {
6051
5854
  queuedDrainHold = false;
6052
5855
  }
@@ -6073,7 +5876,7 @@ ${shared.acceptancePrompt}` : shared.systemPrompt,
6073
5876
  agentSettledReceived = true;
6074
5877
  afterCompactionSettlement = compactionStartedReceived;
6075
5878
  }
6076
- applyChildLifecycle(lifecycleAction);
5879
+ applyChildLifecycle(lifecycleAction, evt);
6077
5880
  if (isChildWatchdogStatusEvent(evt)) {
6078
5881
  if (!childWatchdog) return;
6079
5882
  const next = acceptChildWatchdogEvent({
@@ -6625,7 +6428,7 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError;
6625
6428
  }
6626
6429
  function writeStructuredOutputArtifacts(runtime, value, acceptanceReport) {
6627
6430
  try {
6628
- mkdirSync6(path11.dirname(runtime.outputPath), { recursive: true });
6431
+ mkdirSync6(path10.dirname(runtime.outputPath), { recursive: true });
6629
6432
  writeFileSync4(runtime.outputPath, JSON.stringify(value), { mode: 384 });
6630
6433
  if (runtime.acceptanceReportPath) {
6631
6434
  if (acceptanceReport !== void 0) writeFileSync4(runtime.acceptanceReportPath, JSON.stringify(acceptanceReport), { mode: 384 });
@@ -6655,7 +6458,7 @@ async function runSyncCompletionInner(runtimeCwd, agents, agentName, task, optio
6655
6458
  const childSessionName = deriveChildSessionName({ agent: agentName, task });
6656
6459
  const agent = agents.find((a) => a.name === agentName);
6657
6460
  if (!agent) {
6658
- const diagnosticContext = options.unknownAgentDiagnosticContext ?? unknownAgentDiagnosticContext(discoverAgents(path11.resolve(options.cwd ?? runtimeCwd), "both"));
6461
+ const diagnosticContext = options.unknownAgentDiagnosticContext ?? unknownAgentDiagnosticContext(discoverAgents(path10.resolve(options.cwd ?? runtimeCwd), "both"));
6659
6462
  return redactResultPrompt(withRunContext({
6660
6463
  index: options.index ?? 0,
6661
6464
  agent: agentName,
@@ -6748,7 +6551,7 @@ async function runSyncCompletionInner(runtimeCwd, agents, agentName, task, optio
6748
6551
  ${acceptancePrompt}` : task;
6749
6552
  options.onEffectivePrompt?.(taskWithAcceptance);
6750
6553
  const sessionEnabled = Boolean(options.sessionFile || options.sessionDir) || shareEnabled;
6751
- if (options.context === "fork" && options.sessionFile && existsSync5(options.sessionFile)) {
6554
+ if (options.context === "fork" && options.sessionFile && existsSync4(options.sessionFile)) {
6752
6555
  alignForkedSessionCwd(options.sessionFile, options.cwd ?? runtimeCwd);
6753
6556
  }
6754
6557
  const skillNames = options.skills ?? agent.skills ?? [];
@@ -6758,7 +6561,7 @@ ${acceptancePrompt}` : task;
6758
6561
  skillCwd,
6759
6562
  runtimeCwd,
6760
6563
  agent.skillPath,
6761
- agent.filePath ? path11.dirname(agent.filePath) : skillCwd
6564
+ agent.filePath ? path10.dirname(agent.filePath) : skillCwd
6762
6565
  );
6763
6566
  if (skillNames.some((skill) => skill.trim() === "pi-subagents") && missingSkills.includes("pi-subagents")) {
6764
6567
  return redactResultPrompt(withRunContext({
@@ -6913,7 +6716,7 @@ ${PROMPT_REDACTED}; live Prompt Audit only.
6913
6716
  messages: attemptResult.messages ?? [],
6914
6717
  error: attemptResult.error,
6915
6718
  processSignal: attemptResult.processSignal,
6916
- sessionAvailable: Boolean(options.sessionFile && existsSync5(options.sessionFile)),
6719
+ sessionAvailable: Boolean(options.sessionFile && existsSync4(options.sessionFile)),
6917
6720
  alreadyResumed: attemptIndex > 0,
6918
6721
  stopped: attemptResult.stopped || attemptResult.detached || Boolean(detachedReason) || Boolean(options.workflowChildPermitLaunch) || options.signal?.aborted,
6919
6722
  interrupted: attemptResult.interrupted || options.interruptSignal?.aborted,
@@ -6984,7 +6787,7 @@ ${recovery.diagnostic}` : recovery.diagnostic;
6984
6787
  result2.outputSaveError = result2.outputSaveError ? `${result2.outputSaveError}
6985
6788
  ${message}` : message;
6986
6789
  }
6987
- if (options.sessionFile && (existsSync5(options.sessionFile) || result2.messages?.length)) {
6790
+ if (options.sessionFile && (existsSync4(options.sessionFile) || result2.messages?.length)) {
6988
6791
  result2.sessionFile = options.sessionFile;
6989
6792
  } else if (shareEnabled && options.sessionDir) {
6990
6793
  const sessionFile = findLatestSessionFile(options.sessionDir);
@@ -7089,8 +6892,8 @@ async function runSync(runtimeCwd, agents, agentName, task, options) {
7089
6892
  let activeDetachAttempt;
7090
6893
  let detachReadyPublished = false;
7091
6894
  let resolveReceipt;
7092
- const receipt = new Promise((resolve10) => {
7093
- resolveReceipt = resolve10;
6895
+ const receipt = new Promise((resolve9) => {
6896
+ resolveReceipt = resolve9;
7094
6897
  });
7095
6898
  const originSignal = options.signal;
7096
6899
  const originController = new AbortController();
@@ -7344,8 +7147,8 @@ var WATCHDOG_THINKING_VALUES = ["inherit", ...THINKING_LEVELS];
7344
7147
  // src/shared/pruned-fork.ts
7345
7148
  import { Buffer as Buffer2 } from "node:buffer";
7346
7149
  import { createHash as createHash2 } from "node:crypto";
7347
- import * as fs13 from "node:fs";
7348
- import * as path12 from "node:path";
7150
+ import * as fs12 from "node:fs";
7151
+ import * as path11 from "node:path";
7349
7152
  var MAX_INHERITED_SESSION_BYTES = 64 * 1024;
7350
7153
  var MIN_USEFUL_SPILL_BYTES = 320;
7351
7154
  var MAX_ITEM_SUMMARY_CHARS = 160;
@@ -7374,7 +7177,7 @@ function stableJson(value) {
7374
7177
  throw new Error(`Pruned fork cannot serialize ${typeof value} transcript data.`);
7375
7178
  }
7376
7179
  function readEntries(sessionFile) {
7377
- return fs13.readFileSync(sessionFile, "utf-8").split("\n").filter((line) => line.trim()).map((line, index) => {
7180
+ return fs12.readFileSync(sessionFile, "utf-8").split("\n").filter((line) => line.trim()).map((line, index) => {
7378
7181
  try {
7379
7182
  const parsed = JSON.parse(line);
7380
7183
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.type !== "string") throw new Error("entry must be an object with a type");
@@ -7615,17 +7418,17 @@ function prunedForkRecoveryPath(sessionFile) {
7615
7418
  return `${sessionFile}.pruned-recovery.json`;
7616
7419
  }
7617
7420
  function writeAtomicPrivate(filePath, content, mode) {
7618
- const tempFile = path12.join(path12.dirname(filePath), `.${path12.basename(filePath)}.${process.pid}.tmp`);
7421
+ const tempFile = path11.join(path11.dirname(filePath), `.${path11.basename(filePath)}.${process.pid}.tmp`);
7619
7422
  try {
7620
- fs13.writeFileSync(tempFile, content, { encoding: "utf-8", mode });
7621
- fs13.chmodSync(tempFile, mode);
7622
- fs13.renameSync(tempFile, filePath);
7423
+ fs12.writeFileSync(tempFile, content, { encoding: "utf-8", mode });
7424
+ fs12.chmodSync(tempFile, mode);
7425
+ fs12.renameSync(tempFile, filePath);
7623
7426
  } finally {
7624
- fs13.rmSync(tempFile, { force: true });
7427
+ fs12.rmSync(tempFile, { force: true });
7625
7428
  }
7626
7429
  }
7627
7430
  function writeEntriesAtomic(sessionFile, entries) {
7628
- writeAtomicPrivate(sessionFile, serializedEntries(entries), fs13.statSync(sessionFile).mode & 511);
7431
+ writeAtomicPrivate(sessionFile, serializedEntries(entries), fs12.statSync(sessionFile).mode & 511);
7629
7432
  }
7630
7433
  async function pruneForkSessionFile(sessionFile, summarize, options = {}) {
7631
7434
  const entries = readEntries(sessionFile);
@@ -7666,11 +7469,11 @@ async function pruneForkSessionFile(sessionFile, summarize, options = {}) {
7666
7469
  try {
7667
7470
  writeAtomicPrivate(recoveryPath, `${JSON.stringify(payload, null, " ")}
7668
7471
  `, 384);
7669
- const stored = JSON.parse(fs13.readFileSync(recoveryPath, "utf-8"));
7472
+ const stored = JSON.parse(fs12.readFileSync(recoveryPath, "utf-8"));
7670
7473
  if (!validateRecovery(stored) || stableJson(stored) !== stableJson(payload)) throw new Error("Pruned fork stored recovery payload failed validation.");
7671
7474
  writeEntriesAtomic(sessionFile, entries);
7672
7475
  } catch (error) {
7673
- fs13.rmSync(recoveryPath, { force: true });
7476
+ fs12.rmSync(recoveryPath, { force: true });
7674
7477
  throw error;
7675
7478
  }
7676
7479
  return true;
@@ -7719,11 +7522,11 @@ async function createPrunedForkSessionWriter(ctx, config, signal) {
7719
7522
  }
7720
7523
 
7721
7524
  // src/runs/foreground/async-dismiss-action.ts
7722
- import * as fs14 from "node:fs";
7723
- import * as path13 from "node:path";
7525
+ import * as fs13 from "node:fs";
7526
+ import * as path12 from "node:path";
7724
7527
  function dismissRecoveredWorkflow(state, location) {
7725
7528
  const asyncDir = location.asyncDir;
7726
- const runId = location.resolvedId ?? (asyncDir ? path13.basename(asyncDir) : "requested");
7529
+ const runId = location.resolvedId ?? (asyncDir ? path12.basename(asyncDir) : "requested");
7727
7530
  if (!asyncDir) {
7728
7531
  return {
7729
7532
  content: [{ type: "text", text: `Recovered workflow '${runId}' has no disk status to dismiss.` }],
@@ -7762,7 +7565,7 @@ function dismissRecoveredWorkflow(state, location) {
7762
7565
  }
7763
7566
  let latestStatus = status;
7764
7567
  const resultPath = resultFilePath(DIRS.results, status.runId);
7765
- if (fs14.existsSync(resultPath)) {
7568
+ if (fs13.existsSync(resultPath)) {
7766
7569
  const reconciled = reconcileAsyncRun(asyncDir).status;
7767
7570
  if (reconciled && reconciled.state !== "running") {
7768
7571
  return {
@@ -7774,7 +7577,7 @@ function dismissRecoveredWorkflow(state, location) {
7774
7577
  if (reconciled) latestStatus = reconciled;
7775
7578
  }
7776
7579
  const dismissed = { ...latestStatus, displayDismissedAt: Date.now() };
7777
- writeAtomicJson(path13.join(asyncDir, "status.json"), dismissed);
7580
+ writeAtomicJson(path12.join(asyncDir, "status.json"), dismissed);
7778
7581
  const repaired = reconcileAsyncRun(asyncDir).status;
7779
7582
  if (repaired && repaired.state !== "running") {
7780
7583
  return {
@@ -7795,8 +7598,8 @@ function dismissRecoveredWorkflow(state, location) {
7795
7598
  }
7796
7599
 
7797
7600
  // src/runs/foreground/workflow-detach-reconcile.ts
7798
- import * as fs15 from "node:fs";
7799
- import * as path14 from "node:path";
7601
+ import * as fs14 from "node:fs";
7602
+ import * as path13 from "node:path";
7800
7603
 
7801
7604
  // src/workflows/workflow-settlement.ts
7802
7605
  var UNSUPPORTED_DETACHED_WORKFLOW_CONTINUATION = "unsupported-continuation: detached workflow child settled, but JavaScript workflow continuation was not persisted. Resume the workflow explicitly instead of treating the completed child as top-level workflow completion.";
@@ -8028,9 +7831,9 @@ function workflowResultChildren(status, childRunId, result2, existingResults, re
8028
7831
  }));
8029
7832
  }
8030
7833
  function reconcileWorkflowReceipt(status, childRunId, result2, asyncDir, resolution) {
8031
- const receiptRoot = path14.dirname(asyncDir);
7834
+ const receiptRoot = path13.dirname(asyncDir);
8032
7835
  const receiptPath = workflowReceiptPath(receiptRoot, status.runId);
8033
- if (!fs15.existsSync(receiptPath)) return void 0;
7836
+ if (!fs14.existsSync(receiptPath)) return void 0;
8034
7837
  const receipt = readWorkflowReceipt(receiptRoot, status.runId);
8035
7838
  const step = status.steps?.find((candidate) => candidate.runId === childRunId);
8036
7839
  const key = step?.workflowKey;
@@ -8039,13 +7842,13 @@ function reconcileWorkflowReceipt(status, childRunId, result2, asyncDir, resolut
8039
7842
  if (!entry) throw new Error(`Workflow receipt '${status.runId}' has no detached child key '${key}'.`);
8040
7843
  let resumability;
8041
7844
  try {
8042
- const target = resolveAsyncResumeTarget({ id: childRunId, dir: path14.join(DIRS.async, childRunId) }, {}, { requireSessionFile: true, sessionId: status.sessionId });
7845
+ const target = resolveAsyncResumeTarget({ id: childRunId, dir: path13.join(DIRS.async, childRunId) }, {}, { requireSessionFile: true, sessionId: status.sessionId });
8043
7846
  resumability = target.kind === "revive" ? { state: "resumable" } : { state: "not-resumable", reason: "child is still running" };
8044
7847
  } catch (error) {
8045
7848
  resumability = { state: "not-resumable", reason: error instanceof Error ? error.message : String(error) };
8046
7849
  }
8047
7850
  const outputReference = result2.savedOutputPath ?? result2.outputReference?.path ?? entry.outputReference;
8048
- const childStatus = readStatus(path14.join(DIRS.async, childRunId));
7851
+ const childStatus = readStatus(path13.join(DIRS.async, childRunId));
8049
7852
  const externalStep = childStatus?.steps?.length === 1 && childStatus.steps[0]?.runner?.type === "external-cli" ? childStatus.steps[0] : void 0;
8050
7853
  const externalRunner = normalizeExternalCliRunnerStatus(result2.runner?.type === "external-cli" ? result2.runner : externalStep?.runner);
8051
7854
  const externalProcess = result2.externalProcess ?? externalStep?.externalProcess;
@@ -8089,9 +7892,9 @@ function reconcileWorkflowReceipt(status, childRunId, result2, asyncDir, resolut
8089
7892
  return { receipt: next, path: writeWorkflowReceipt(asyncDir, next) };
8090
7893
  }
8091
7894
  function appendDetachedWorkflowEvent(asyncDir, event) {
8092
- const eventsPath = path14.join(asyncDir, "events.jsonl");
7895
+ const eventsPath = path13.join(asyncDir, "events.jsonl");
8093
7896
  try {
8094
- fs15.appendFileSync(eventsPath, `${JSON.stringify(event)}
7897
+ fs14.appendFileSync(eventsPath, `${JSON.stringify(event)}
8095
7898
  `, "utf-8");
8096
7899
  } catch (error) {
8097
7900
  console.error(`Failed to append detached workflow event '${eventsPath}':`, error);
@@ -8099,7 +7902,7 @@ function appendDetachedWorkflowEvent(asyncDir, event) {
8099
7902
  }
8100
7903
  function reconcileDetachedWorkflowChildCompletion(input) {
8101
7904
  const job = input.state.asyncJobs.get(input.workflowRunId);
8102
- const asyncDir = job?.asyncDir ?? path14.join(DIRS.async, input.workflowRunId);
7905
+ const asyncDir = job?.asyncDir ?? path13.join(DIRS.async, input.workflowRunId);
8103
7906
  const status = readStatus(asyncDir);
8104
7907
  if (!status) return false;
8105
7908
  const matchingControls = input.workflowKey === void 0 ? [] : [...input.state.foregroundControls?.values() ?? []].filter(
@@ -8124,7 +7927,7 @@ function reconcileDetachedWorkflowChildCompletion(input) {
8124
7927
  const resultPath = resultFilePath(DIRS.results, input.workflowRunId);
8125
7928
  let existing;
8126
7929
  try {
8127
- const parsed = JSON.parse(fs15.readFileSync(resultPath, "utf-8"));
7930
+ const parsed = JSON.parse(fs14.readFileSync(resultPath, "utf-8"));
8128
7931
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) existing = parsed;
8129
7932
  } catch (error) {
8130
7933
  if (error.code !== "ENOENT") throw error;
@@ -8170,7 +7973,7 @@ function reconcileDetachedWorkflowChildCompletion(input) {
8170
7973
  terminalOutcome: receipt?.terminalOutcome,
8171
7974
  eventMetadata: { reconciledFromDetachedChild: input.childRunId }
8172
7975
  });
8173
- writeAtomicJson(path14.join(asyncDir, "status.json"), plan.status);
7976
+ writeAtomicJson(path13.join(asyncDir, "status.json"), plan.status);
8174
7977
  updateActiveRunIndex(asyncDir, plan.status.state, plan.status.toolCallId);
8175
7978
  if (job) {
8176
7979
  job.status = plan.status.state;
@@ -8222,14 +8025,14 @@ function reconcileDetachedWorkflowChildCompletion(input) {
8222
8025
  }
8223
8026
 
8224
8027
  // src/runs/background/chain-root-attachment.ts
8225
- import * as fs16 from "node:fs";
8226
- import * as path15 from "node:path";
8028
+ import * as fs15 from "node:fs";
8029
+ import * as path14 from "node:path";
8227
8030
  var TERMINAL_STATES = /* @__PURE__ */ new Set(["complete", "failed", "partial", "paused", "stopped"]);
8228
8031
  var TERMINAL_STEP_STATUSES = /* @__PURE__ */ new Set(["complete", "completed", "failed", "partial", "paused", "stopped"]);
8229
8032
  function readResultFile(resultPath) {
8230
8033
  let raw;
8231
8034
  try {
8232
- raw = fs16.readFileSync(resultPath, "utf-8");
8035
+ raw = fs15.readFileSync(resultPath, "utf-8");
8233
8036
  } catch (error) {
8234
8037
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
8235
8038
  return void 0;
@@ -8241,7 +8044,7 @@ function readResultFile(resultPath) {
8241
8044
  function readImportedResultFile(root, status) {
8242
8045
  const direct = readResultFile(root.resultPath);
8243
8046
  if (direct || !status?.sessionId) return direct;
8244
- const indexedPath = resultPayloadPathForSessionRun(path15.dirname(root.resultPath), status.sessionId, root.runId);
8047
+ const indexedPath = resultPayloadPathForSessionRun(path14.dirname(root.resultPath), status.sessionId, root.runId);
8245
8048
  return indexedPath ? readResultFile(indexedPath) : void 0;
8246
8049
  }
8247
8050
  function selectedStatusStep(status, index) {
@@ -8376,10 +8179,10 @@ async function waitForImportedAsyncRoot(root, options = {}) {
8376
8179
  } else {
8377
8180
  terminalSince = void 0;
8378
8181
  }
8379
- if (!status && !fs16.existsSync(root.asyncDir)) {
8182
+ if (!status && !fs15.existsSync(root.asyncDir)) {
8380
8183
  throw new Error(`Attached async root '${root.runId}' directory does not exist: ${root.asyncDir}`);
8381
8184
  }
8382
- await new Promise((resolve10) => setTimeout(resolve10, pollIntervalMs));
8185
+ await new Promise((resolve9) => setTimeout(resolve9, pollIntervalMs));
8383
8186
  }
8384
8187
  }
8385
8188
  function resolveAsyncRootResultPath(resultsDir, runId) {
@@ -8387,7 +8190,7 @@ function resolveAsyncRootResultPath(resultsDir, runId) {
8387
8190
  }
8388
8191
 
8389
8192
  // src/runs/background/await-async-run.ts
8390
- import * as fs17 from "node:fs";
8193
+ import * as fs16 from "node:fs";
8391
8194
  function errorMessage2(error) {
8392
8195
  return error instanceof Error ? error.message : String(error);
8393
8196
  }
@@ -8395,7 +8198,7 @@ function runnerExitedWithoutResult(asyncDir, runId, resultPath) {
8395
8198
  const status = readStatus(asyncDir);
8396
8199
  if (!status || status.state !== "running" && status.state !== "queued" || typeof status.pid !== "number") return false;
8397
8200
  if (checkRecordedPidLiveness({ pid: status.pid, pidNamespaceScope: status.pidNamespaceScope, bootId: status.bootId }) !== "dead") return false;
8398
- return !fs17.existsSync(resultPath) && !(status.sessionId && resultPayloadPathForSessionRun(asyncDir, status.sessionId, runId));
8201
+ return !fs16.existsSync(resultPath) && !(status.sessionId && resultPayloadPathForSessionRun(asyncDir, status.sessionId, runId));
8399
8202
  }
8400
8203
  async function awaitExistingAsyncRun(asyncDir, runId, signal) {
8401
8204
  signal.throwIfAborted();
@@ -8430,7 +8233,7 @@ function claimWorkflowAwaitedResult(asyncDir, claimant, read) {
8430
8233
  try {
8431
8234
  return withResultRunLease(asyncDir, read.runId, () => {
8432
8235
  if (resultSnapshotReplaced(resultPath, read)) return void 0;
8433
- fs17.renameSync(resultPath, claimedPath);
8236
+ fs16.renameSync(resultPath, claimedPath);
8434
8237
  return claimedPath;
8435
8238
  });
8436
8239
  } catch {
@@ -8439,8 +8242,8 @@ function claimWorkflowAwaitedResult(asyncDir, claimant, read) {
8439
8242
  }
8440
8243
 
8441
8244
  // src/runs/background/run-status.ts
8442
- import * as fs18 from "node:fs";
8443
- import * as path16 from "node:path";
8245
+ import * as fs17 from "node:fs";
8246
+ import * as path15 from "node:path";
8444
8247
  var STRUCTURED_PREVIEW_WITH_PATH_CHARS = 500;
8445
8248
  function formatProcessTerminal(value) {
8446
8249
  if (!value) return "missing";
@@ -8450,7 +8253,7 @@ function debugProcessTerminal(asyncDir, status) {
8450
8253
  const expected = { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId };
8451
8254
  return {
8452
8255
  sidecar: readProcessTerminal(asyncDir, expected),
8453
- overlay: sanitizeProcessTerminal(status.processTerminal, expected, path16.join(asyncDir, "status.json"))
8256
+ overlay: sanitizeProcessTerminal(status.processTerminal, expected, path15.join(asyncDir, "status.json"))
8454
8257
  };
8455
8258
  }
8456
8259
  function formatCapacityOwner(inspect) {
@@ -8484,9 +8287,9 @@ function formatRunLifecycleDebug(input) {
8484
8287
  "Run lifecycle debug",
8485
8288
  `Run: ${status.runId}`,
8486
8289
  `Dir: ${asyncDir}`,
8487
- `Status file: ${path16.join(asyncDir, "status.json")}`,
8290
+ `Status file: ${path15.join(asyncDir, "status.json")}`,
8488
8291
  status.workflowReceiptPath ? `Workflow receipt: ${status.workflowReceiptPath}` : void 0,
8489
- `Process terminal file: ${path16.join(asyncDir, "process-terminal.json")}`,
8292
+ `Process terminal file: ${path15.join(asyncDir, "process-terminal.json")}`,
8490
8293
  `Session: ${status.sessionId ?? "unknown"}`,
8491
8294
  `State: ${status.state}`,
8492
8295
  `Mode: ${status.mode}`,
@@ -8501,7 +8304,7 @@ function formatRunLifecycleDebug(input) {
8501
8304
  return lines.join("\n");
8502
8305
  }
8503
8306
  function hasExistingSessionFile(value) {
8504
- return typeof value === "string" && fs18.existsSync(value);
8307
+ return typeof value === "string" && fs17.existsSync(value);
8505
8308
  }
8506
8309
  function formatResumeGuidance(runId, children, fallbackSessionFile, options = {}) {
8507
8310
  if (options.stopped) return "Resume: unavailable; stopped runs are not resumable. Start a new run instead.";
@@ -8564,9 +8367,9 @@ function externalJobFollowUpSupported(provider) {
8564
8367
  }
8565
8368
  function rememberedForegroundChildOutput(child) {
8566
8369
  const outputPath = child.artifactPaths?.outputPath ?? child.savedOutputPath;
8567
- if (outputPath && fs18.existsSync(outputPath)) {
8370
+ if (outputPath && fs17.existsSync(outputPath)) {
8568
8371
  try {
8569
- const artifactOutput = fs18.readFileSync(outputPath, "utf-8").trim();
8372
+ const artifactOutput = fs17.readFileSync(outputPath, "utf-8").trim();
8570
8373
  if (artifactOutput) return artifactOutput;
8571
8374
  } catch {
8572
8375
  }
@@ -8865,8 +8668,8 @@ No running work was terminated.` }],
8865
8668
  };
8866
8669
  }
8867
8670
  const effectiveRunId = status?.runId ?? resolvedId ?? "unknown";
8868
- const logPath = path16.join(asyncDir, `subagent-log-${effectiveRunId}.md`);
8869
- const eventsPath = path16.join(asyncDir, "events.jsonl");
8671
+ const logPath = path15.join(asyncDir, `subagent-log-${effectiveRunId}.md`);
8672
+ const eventsPath = path15.join(asyncDir, "events.jsonl");
8870
8673
  if (status) {
8871
8674
  if (params.action === "debug.run") {
8872
8675
  const { sidecar, overlay } = debugProcessTerminal(asyncDir, status);
@@ -8915,7 +8718,7 @@ No running work was terminated.` }],
8915
8718
  const updated = status.lastUpdate ? new Date(status.lastUpdate).toISOString() : "n/a";
8916
8719
  const statusActivityText = status.state === "running" ? formatActivityLabel(status.lastActivityAt, status.activityState) : void 0;
8917
8720
  const steeringText = formatSteeringSummary(status);
8918
- const processTerminal = readProcessTerminal(asyncDir, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId }) ?? sanitizeProcessTerminal(status.processTerminal, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId }, path16.join(asyncDir, "status.json"));
8721
+ const processTerminal = readProcessTerminal(asyncDir, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId }) ?? sanitizeProcessTerminal(status.processTerminal, { runId: status.runId, runnerProcessInstanceId: status.processTerminal?.runnerProcessInstanceId }, path15.join(asyncDir, "status.json"));
8919
8722
  const runFanoutBudgetDescriptor = readRunFanoutBudgetDescriptor(asyncDir);
8920
8723
  const runFanoutBudget = runFanoutBudgetDescriptor ? getRunFanoutBudgetSnapshot(runFanoutBudgetDescriptor) : status.runFanoutBudget;
8921
8724
  let missionId;
@@ -8951,7 +8754,7 @@ Extensions denied: ${status.capabilityCeiling.denyExtensions ? "yes" : "no"} (so
8951
8754
  status.parentWorkflowRunId ? `Workflow parent: ${status.parentWorkflowRunId}${status.workflowKey ? ` (${status.workflowKey})` : ""}` : void 0,
8952
8755
  status.mode === "workflow" && workflowReturnPreview !== void 0 ? `Return: ${workflowReturnPreview}` : void 0,
8953
8756
  status.mode === "workflow" && workflowEmitPreview !== void 0 ? `Latest emit: ${workflowEmitPreview}` : void 0,
8954
- status.mode === "workflow" && (workflowReturnPreview?.endsWith("\u2026") || workflowEmitPreview?.endsWith("\u2026")) ? `Full return value and emits: ${path16.join(asyncDir, "status.json")} (workflow.value, workflow.emits)` : void 0,
8757
+ status.mode === "workflow" && (workflowReturnPreview?.endsWith("\u2026") || workflowEmitPreview?.endsWith("\u2026")) ? `Full return value and emits: ${path15.join(asyncDir, "status.json")} (workflow.value, workflow.emits)` : void 0,
8955
8758
  `Progress: ${progressLabel}`,
8956
8759
  ...status.mode === "workflow" ? formatWorkflowChecklistText(projectWorkflowChecklist({
8957
8760
  graph: status.workflowGraph,
@@ -8969,7 +8772,7 @@ Extensions denied: ${status.capabilityCeiling.denyExtensions ? "yes" : "no"} (so
8969
8772
  outputPath ? `Output: ${outputPath}` : void 0,
8970
8773
  status.parallelHandoff ? `Parallel handoff: ${status.parallelHandoff.path}` : void 0,
8971
8774
  reconciliation.message ? `Diagnosis: ${reconciliation.message}` : void 0,
8972
- reconciliation.resultPath && fs18.existsSync(reconciliation.resultPath) ? `Result: ${reconciliation.resultPath}` : void 0
8775
+ reconciliation.resultPath && fs17.existsSync(reconciliation.resultPath) ? `Result: ${reconciliation.resultPath}` : void 0
8973
8776
  ].filter((line) => Boolean(line));
8974
8777
  const liveWorkflowControls = status.mode === "workflow" && deps.state?.currentSessionId === status.sessionId && deps.state?.workflowControllers?.has(status.runId) ? [...deps.state?.foregroundControls.values() ?? []].filter((control) => control.parentWorkflowRunId === status.runId && control.sessionId === status.sessionId && (control.activeChildren?.size ?? 0) > 0) : [];
8975
8778
  let hasExternalJobFollowUpHint = false;
@@ -9031,8 +8834,8 @@ Extensions denied: ${status.capabilityCeiling.denyExtensions ? "yes" : "no"} (so
9031
8834
  }
9032
8835
  }
9033
8836
  lines.push(...formatNestedRunStatusLines(step.children, { indent: " ", commandHints: true, maxLines: 20 }));
9034
- const stepOutputPath = path16.join(asyncDir, `output-${index}.log`);
9035
- if (stepOutputPath !== outputPath && fs18.existsSync(stepOutputPath)) lines.push(` Output: ${stepOutputPath}`);
8837
+ const stepOutputPath = path15.join(asyncDir, `output-${index}.log`);
8838
+ if (stepOutputPath !== outputPath && fs17.existsSync(stepOutputPath)) lines.push(` Output: ${stepOutputPath}`);
9036
8839
  if (step.status === "running" && step.runner?.type !== "external-cli" && step.runner?.type !== "external-job" && status.mode !== "workflow") {
9037
8840
  lines.push(` Intercom target: ${resolveSubagentIntercomTarget(status.runId, step.agent, index)} (if registered)`);
9038
8841
  lines.push(` Steer: subagent({ action: "steer", id: "${status.runId}", message: "...", options: { index: ${index} } })`);
@@ -9065,8 +8868,8 @@ Extensions denied: ${status.capabilityCeiling.denyExtensions ? "yes" : "no"} (so
9065
8868
  if (status.state !== "running") {
9066
8869
  lines.push(allExternal ? hasExternalJobFollowUpHint ? "Resume: use the external-job follow-up hint above." : "Resume: unavailable; external runners do not persist Pi sessions." : formatResumeGuidance(status.runId, status.steps ?? [], status.sessionFile, { stopped: status.state === "stopped" || status.stopped === true, otherSession: foreign(status.sessionId) }));
9067
8870
  }
9068
- if (fs18.existsSync(logPath)) lines.push(`Log: ${logPath}`);
9069
- if (fs18.existsSync(eventsPath)) lines.push(`Events: ${eventsPath}`);
8871
+ if (fs17.existsSync(logPath)) lines.push(`Log: ${logPath}`);
8872
+ if (fs17.existsSync(eventsPath)) lines.push(`Events: ${eventsPath}`);
9070
8873
  return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", runId: status.runId, ...status.toolCallId ? { toolCallId: status.toolCallId } : {}, results: [], ...status.workflowReceiptPath ? { workflowReceiptPath: status.workflowReceiptPath } : {}, ...status.preflight ? { preflight: status.preflight } : {}, ...status.workflow?.preflightWarnings?.length ? { preflightWarnings: status.workflow.preflightWarnings } : {}, ...workflowChildren ? { workflowChildren } : {}, ...workflowTerminalProof ? { workflowTerminalProof } : {}, ...runFanoutBudget ? { runFanoutBudget } : {}, ...processTerminal ? { lifecycleStatus: { processTerminal } } : {} } };
9071
8874
  }
9072
8875
  }
@@ -9079,7 +8882,7 @@ Extensions denied: ${status.capabilityCeiling.denyExtensions ? "yes" : "no"} (so
9079
8882
  };
9080
8883
  }
9081
8884
  try {
9082
- const raw = fs18.readFileSync(resultPath, "utf-8");
8885
+ const raw = fs17.readFileSync(resultPath, "utf-8");
9083
8886
  const data = JSON.parse(raw);
9084
8887
  if (params.view === "transcript") {
9085
8888
  try {
@@ -9172,16 +8975,16 @@ function applyForceTopLevelAsyncOverride(params, depth, forceTopLevelAsync) {
9172
8975
 
9173
8976
  // src/runs/shared/worktree-cleanup-apply.ts
9174
8977
  import { createHash as createHash5 } from "node:crypto";
9175
- import { spawnSync as spawnSync3 } from "node:child_process";
9176
- import * as fs20 from "node:fs";
9177
- import * as path18 from "node:path";
8978
+ import { spawnSync as spawnSync2 } from "node:child_process";
8979
+ import * as fs19 from "node:fs";
8980
+ import * as path17 from "node:path";
9178
8981
 
9179
8982
  // src/runs/shared/worktree-cleanup-plan.ts
9180
8983
  import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
9181
- import { spawnSync as spawnSync2 } from "node:child_process";
9182
- import * as fs19 from "node:fs";
8984
+ import { spawnSync } from "node:child_process";
8985
+ import * as fs18 from "node:fs";
9183
8986
  import * as os2 from "node:os";
9184
- import * as path17 from "node:path";
8987
+ import * as path16 from "node:path";
9185
8988
  var WORKTREE_CLEANUP_PLAN_VERSION = 1;
9186
8989
  var WORKTREE_CLEANUP_PLAN_TTL_MS = 30 * 60 * 1e3;
9187
8990
  var MAX_DISCOVERED_HANDOFFS = 256;
@@ -9189,7 +8992,7 @@ var MAX_PLAN_ENTRIES = 512;
9189
8992
  var MAX_METADATA_FILE_BYTES = 2 * 1024 * 1024;
9190
8993
  function runGit(cwd, args) {
9191
8994
  try {
9192
- const result2 = spawnSync2("git", ["-C", cwd, ...args], { encoding: "utf-8", windowsHide: true });
8995
+ const result2 = spawnSync("git", ["-C", cwd, ...args], { encoding: "utf-8", windowsHide: true });
9193
8996
  return {
9194
8997
  stdout: result2.stdout ?? "",
9195
8998
  stderr: result2.stderr ?? "",
@@ -9213,7 +9016,7 @@ function runGitChecked(cwd, args) {
9213
9016
  if (result2.status !== 0) throw new Error(gitFailure(result2, `git -C ${cwd} ${args.join(" ")}`));
9214
9017
  return result2.stdout.trim();
9215
9018
  }
9216
- function realpathExisting(candidate, nativeRealpath = fs19.realpathSync.native, fallbackRealpath = fs19.realpathSync) {
9019
+ function realpathExisting(candidate, nativeRealpath = fs18.realpathSync.native, fallbackRealpath = fs18.realpathSync) {
9217
9020
  try {
9218
9021
  return nativeRealpath(candidate);
9219
9022
  } catch {
@@ -9221,29 +9024,29 @@ function realpathExisting(candidate, nativeRealpath = fs19.realpathSync.native,
9221
9024
  }
9222
9025
  }
9223
9026
  function comparablePath(candidate) {
9224
- let current = path17.resolve(candidate);
9027
+ let current = path16.resolve(candidate);
9225
9028
  const missingSegments = [];
9226
9029
  let canonical = current;
9227
9030
  while (true) {
9228
9031
  try {
9229
- canonical = path17.join(realpathExisting(current), ...missingSegments.reverse());
9032
+ canonical = path16.join(realpathExisting(current), ...missingSegments.reverse());
9230
9033
  break;
9231
9034
  } catch {
9232
- const parent = path17.dirname(current);
9035
+ const parent = path16.dirname(current);
9233
9036
  if (parent === current) break;
9234
- missingSegments.push(path17.basename(current));
9037
+ missingSegments.push(path16.basename(current));
9235
9038
  current = parent;
9236
9039
  }
9237
9040
  }
9238
- const normalized = path17.normalize(canonical);
9041
+ const normalized = path16.normalize(canonical);
9239
9042
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
9240
9043
  }
9241
9044
  function samePath(left, right) {
9242
9045
  if (comparablePath(left) === comparablePath(right)) return true;
9243
9046
  if (process.platform !== "win32") return false;
9244
9047
  try {
9245
- const leftStat = fs19.statSync(left, { bigint: true });
9246
- const rightStat = fs19.statSync(right, { bigint: true });
9048
+ const leftStat = fs18.statSync(left, { bigint: true });
9049
+ const rightStat = fs18.statSync(right, { bigint: true });
9247
9050
  return leftStat.dev !== 0n && leftStat.ino !== 0n && leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
9248
9051
  } catch {
9249
9052
  return false;
@@ -9253,15 +9056,15 @@ function resolveExistingPath(candidate) {
9253
9056
  try {
9254
9057
  return realpathExisting(candidate);
9255
9058
  } catch {
9256
- return path17.resolve(candidate);
9059
+ return path16.resolve(candidate);
9257
9060
  }
9258
9061
  }
9259
9062
  function pathInside(root, candidate, strict = false) {
9260
9063
  const normalizedRoot = comparablePath(root);
9261
9064
  const normalizedCandidate = comparablePath(candidate);
9262
9065
  if (!strict && normalizedRoot === normalizedCandidate) return true;
9263
- const relative3 = path17.relative(normalizedRoot, normalizedCandidate);
9264
- return relative3 !== "" && relative3 !== ".." && !relative3.startsWith(`..${path17.sep}`) && !path17.isAbsolute(relative3);
9066
+ const relative3 = path16.relative(normalizedRoot, normalizedCandidate);
9067
+ return relative3 !== "" && relative3 !== ".." && !relative3.startsWith(`..${path16.sep}`) && !path16.isAbsolute(relative3);
9265
9068
  }
9266
9069
  function sha2562(value) {
9267
9070
  return createHash4("sha256").update(value, "utf-8").digest("hex");
@@ -9273,7 +9076,7 @@ function validatePlanId(planId) {
9273
9076
  return planId;
9274
9077
  }
9275
9078
  function resolveCleanupRepoRoot(repo) {
9276
- const requested = path17.resolve(repo);
9079
+ const requested = path16.resolve(repo);
9277
9080
  const toplevel = runGitChecked(requested, ["rev-parse", "--show-toplevel"]);
9278
9081
  return realpathExisting(toplevel);
9279
9082
  }
@@ -9281,17 +9084,17 @@ function resolveCleanupBaseDir(repoRoot, configuredBaseDir) {
9281
9084
  const raw = configuredBaseDir ?? process.env.PI_SUBAGENTS_WORKTREE_DIR;
9282
9085
  let dedicatedRoot;
9283
9086
  if (raw === void 0 || configuredBaseDir === void 0 && !raw.trim()) {
9284
- dedicatedRoot = path17.join(path17.dirname(repoRoot), "worktrees");
9087
+ dedicatedRoot = path16.join(path16.dirname(repoRoot), "worktrees");
9285
9088
  } else {
9286
9089
  const trimmed = raw.trim();
9287
9090
  if (!trimmed) throw new Error("worktree base directory cannot be empty");
9288
- const expanded = trimmed.startsWith("~/") ? path17.join(os2.homedir(), trimmed.slice(2)) : trimmed;
9289
- dedicatedRoot = path17.isAbsolute(expanded) ? expanded : path17.resolve(repoRoot, expanded);
9091
+ const expanded = trimmed.startsWith("~/") ? path16.join(os2.homedir(), trimmed.slice(2)) : trimmed;
9092
+ dedicatedRoot = path16.isAbsolute(expanded) ? expanded : path16.resolve(repoRoot, expanded);
9290
9093
  }
9291
- return path17.resolve(path17.join(dedicatedRoot, path17.basename(repoRoot)));
9094
+ return path16.resolve(path16.join(dedicatedRoot, path16.basename(repoRoot)));
9292
9095
  }
9293
9096
  function cleanupContainmentInvalid(repoRoot, projectDir) {
9294
- const extensionsDir = path17.join(getAgentDir(), "extensions");
9097
+ const extensionsDir = path16.join(getAgentDir(), "extensions");
9295
9098
  return samePath(projectDir, repoRoot) || pathInside(repoRoot, projectDir, true) || pathInside(extensionsDir, projectDir);
9296
9099
  }
9297
9100
  function parseGitWorktreeList(raw) {
@@ -9330,14 +9133,14 @@ function isRegisteredCleanupWorktree(repoRoot, candidate) {
9330
9133
  return listGitWorktrees(repoRoot).some((tree) => samePath(tree.path, candidate));
9331
9134
  }
9332
9135
  function readJsonFile(filePath) {
9333
- return JSON.parse(fs19.readFileSync(filePath, "utf-8"));
9136
+ return JSON.parse(fs18.readFileSync(filePath, "utf-8"));
9334
9137
  }
9335
9138
  function isRecord(value) {
9336
9139
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
9337
9140
  }
9338
9141
  function readManifest(manifestPath) {
9339
9142
  try {
9340
- const stat = fs19.lstatSync(manifestPath);
9143
+ const stat = fs18.lstatSync(manifestPath);
9341
9144
  if (stat.isSymbolicLink() || !stat.isFile()) return { error: `parallel handoff manifest is not a regular file: ${manifestPath}` };
9342
9145
  if (stat.size > MAX_METADATA_FILE_BYTES) return { error: `parallel handoff manifest exceeds the ${MAX_METADATA_FILE_BYTES}-byte limit: ${manifestPath}` };
9343
9146
  const parsed = readParallelHandoffManifest(manifestPath);
@@ -9355,22 +9158,22 @@ function discoverHandoffPaths(repoRoot, input) {
9355
9158
  const paths = [];
9356
9159
  const warnings = [];
9357
9160
  const add = (candidate) => {
9358
- const resolved = path17.isAbsolute(candidate) ? path17.resolve(candidate) : path17.resolve(repoRoot, candidate);
9161
+ const resolved = path16.isAbsolute(candidate) ? path16.resolve(candidate) : path16.resolve(repoRoot, candidate);
9359
9162
  if (!paths.some((existing) => comparablePath(existing) === comparablePath(resolved))) paths.push(resolved);
9360
9163
  };
9361
9164
  if (input.handoffPath) add(input.handoffPath);
9362
9165
  for (const candidate of input.handoffPaths ?? []) add(candidate);
9363
- const artifactsDir = path17.join(repoRoot, PROJECT_SUBAGENTS_RELATIVE_DIR, "artifacts");
9364
- const projectHandoffPath = path17.join(artifactsDir, "handoff.json");
9365
- if (fs19.existsSync(projectHandoffPath)) add(projectHandoffPath);
9366
- const handoffsDir = path17.join(artifactsDir, "handoffs");
9166
+ const artifactsDir = path16.join(repoRoot, PROJECT_SUBAGENTS_RELATIVE_DIR, "artifacts");
9167
+ const projectHandoffPath = path16.join(artifactsDir, "handoff.json");
9168
+ if (fs18.existsSync(projectHandoffPath)) add(projectHandoffPath);
9169
+ const handoffsDir = path16.join(artifactsDir, "handoffs");
9367
9170
  try {
9368
- const stat = fs19.lstatSync(handoffsDir);
9171
+ const stat = fs18.lstatSync(handoffsDir);
9369
9172
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
9370
9173
  warnings.push(`ignored non-directory handoff metadata root: ${handoffsDir}`);
9371
9174
  } else {
9372
- const entries = fs19.readdirSync(handoffsDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort().slice(0, MAX_DISCOVERED_HANDOFFS);
9373
- for (const entry of entries) add(path17.join(handoffsDir, entry));
9175
+ const entries = fs18.readdirSync(handoffsDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort().slice(0, MAX_DISCOVERED_HANDOFFS);
9176
+ for (const entry of entries) add(path16.join(handoffsDir, entry));
9374
9177
  if (entries.length === MAX_DISCOVERED_HANDOFFS) warnings.push(`handoff metadata discovery capped at ${MAX_DISCOVERED_HANDOFFS} files`);
9375
9178
  }
9376
9179
  } catch (error) {
@@ -9380,9 +9183,9 @@ function discoverHandoffPaths(repoRoot, input) {
9380
9183
  return { paths: paths.sort((left, right) => comparablePath(left).localeCompare(comparablePath(right))), warnings: [...new Set(warnings)].sort() };
9381
9184
  }
9382
9185
  function readStatusBesideManifest(manifestPath) {
9383
- const statusPath = path17.join(path17.dirname(manifestPath), "status.json");
9186
+ const statusPath = path16.join(path16.dirname(manifestPath), "status.json");
9384
9187
  try {
9385
- const stat = fs19.lstatSync(statusPath);
9188
+ const stat = fs18.lstatSync(statusPath);
9386
9189
  if (stat.isSymbolicLink() || !stat.isFile()) return { statusPath, error: `async status is not a regular file: ${statusPath}` };
9387
9190
  if (stat.size > MAX_METADATA_FILE_BYTES) return { statusPath, error: `async status exceeds the ${MAX_METADATA_FILE_BYTES}-byte limit: ${statusPath}` };
9388
9191
  const parsed = readJsonFile(statusPath);
@@ -9443,7 +9246,7 @@ function loadMetadata(input, repoRoot) {
9443
9246
  continue;
9444
9247
  }
9445
9248
  const manifestRoot = resolveExistingPath(manifestPath);
9446
- if (manifestRoot !== manifestPath && fs19.lstatSync(manifestPath).isSymbolicLink()) {
9249
+ if (manifestRoot !== manifestPath && fs18.lstatSync(manifestPath).isSymbolicLink()) {
9447
9250
  warnings.push(`ignored symlinked handoff manifest: ${manifestPath}`);
9448
9251
  continue;
9449
9252
  }
@@ -9452,9 +9255,9 @@ function loadMetadata(input, repoRoot) {
9452
9255
  return { records, paths: discovered.paths, warnings: [...new Set(warnings)].sort() };
9453
9256
  }
9454
9257
  function inspectPath(candidate) {
9455
- const resolved = path17.resolve(candidate);
9258
+ const resolved = path16.resolve(candidate);
9456
9259
  try {
9457
- const stat = fs19.lstatSync(resolved);
9260
+ const stat = fs18.lstatSync(resolved);
9458
9261
  if (stat.isSymbolicLink()) return { resolved, missing: false, symlink: true, directory: false };
9459
9262
  return { resolved, realpath: realpathExisting(resolved), missing: false, symlink: false, directory: stat.isDirectory() };
9460
9263
  } catch (error) {
@@ -9464,7 +9267,7 @@ function inspectPath(candidate) {
9464
9267
  }
9465
9268
  }
9466
9269
  function metadataPath(manifestPath, candidate) {
9467
- return path17.isAbsolute(candidate) ? path17.resolve(candidate) : path17.resolve(path17.dirname(manifestPath), candidate);
9270
+ return path16.isAbsolute(candidate) ? path16.resolve(candidate) : path16.resolve(path16.dirname(manifestPath), candidate);
9468
9271
  }
9469
9272
  function metadataRecordPath(record2) {
9470
9273
  return metadataPath(record2.manifestPath, record2.task.path);
@@ -9505,7 +9308,7 @@ function inspectRunState(record2, now, foregroundRunOwnership) {
9505
9308
  }
9506
9309
  }
9507
9310
  try {
9508
- const markerAge = activeRunMarkerAgeMs(path17.dirname(record2.statusPath), now);
9311
+ const markerAge = activeRunMarkerAgeMs(path16.dirname(record2.statusPath), now);
9509
9312
  if (markerAge !== void 0) {
9510
9313
  if (markerAge <= DEFAULT_STALE_TERMINAL_ACTIVE_MARKER_MS) return { kind: "active", reason: "owning run still has a recent active marker" };
9511
9314
  return { kind: "stale", reason: `terminal active marker is stale (${Math.floor(markerAge / 1e3)}s old)` };
@@ -9566,7 +9369,7 @@ function isPatchCaptured(record2, worktreePath, baseCommit) {
9566
9369
  if (inspection.missing || !inspection.realpath) return { error: "captured handoff patch is missing" };
9567
9370
  let patchStat;
9568
9371
  try {
9569
- patchStat = fs19.statSync(patchPath);
9372
+ patchStat = fs18.statSync(patchPath);
9570
9373
  } catch (error) {
9571
9374
  return { error: `captured patch cannot be inspected: ${error instanceof Error ? error.message : String(error)}` };
9572
9375
  }
@@ -9579,7 +9382,7 @@ function isPatchCaptured(record2, worktreePath, baseCommit) {
9579
9382
  }
9580
9383
  function buildManagedEntry(input) {
9581
9384
  const { repoRoot, baseDir, targetHead, rootPath, git, record: record2, foregroundRunOwnership } = input;
9582
- const gitWorktreePath = path17.resolve(git.path);
9385
+ const gitWorktreePath = path16.resolve(git.path);
9583
9386
  const metadataWorktreePath = metadataRecordPath(record2);
9584
9387
  const worktreePath = resolveExistingPath(metadataWorktreePath);
9585
9388
  const entry = buildEntryBase({ path: worktreePath, branch: git.branch ?? "", source: "both", git, metadata: record2, targetHead });
@@ -9596,13 +9399,13 @@ function buildManagedEntry(input) {
9596
9399
  if (pathInspection.missing) return blockedEntry(entry, "stale", "unknown", "worktree path is missing from disk");
9597
9400
  if (pathInspection.symlink) return blockedEntry(entry, "unknown", "unknown", "worktree path is a symlink; cleanup requires a real directory");
9598
9401
  if (!pathInspection.directory || !pathInspection.realpath) return blockedEntry(entry, "unknown", "unknown", "worktree path is not a directory");
9599
- const extensionsDir = path17.join(getAgentDir(), "extensions");
9402
+ const extensionsDir = path16.join(getAgentDir(), "extensions");
9600
9403
  if (pathInside(extensionsDir, pathInspection.realpath)) return blockedEntry(entry, "ineligible", "keep", `worktree real path is inside Pi extensions directory '${extensionsDir}'`);
9601
9404
  if (input.containmentInvalid || !pathInside(baseDir, pathInspection.realpath, true)) return blockedEntry(entry, "ineligible", "keep", `worktree real path is outside configured base directory '${baseDir}'`);
9602
9405
  const recordedBaseDir = record2.task.recordedBaseDir;
9603
- if (typeof recordedBaseDir !== "string" || !path17.isAbsolute(recordedBaseDir)) return blockedEntry(entry, "unknown", "keep", "handoff metadata has no creation-time base directory proof");
9604
- const creationRelative = path17.relative(recordedBaseDir, pathInspection.realpath);
9605
- if (!creationRelative || creationRelative === ".." || creationRelative.startsWith(`..${path17.sep}`) || path17.isAbsolute(creationRelative)) return blockedEntry(entry, "ineligible", "keep", `worktree real path is outside its creation-time recorded base directory '${recordedBaseDir}'`);
9406
+ if (typeof recordedBaseDir !== "string" || !path16.isAbsolute(recordedBaseDir)) return blockedEntry(entry, "unknown", "keep", "handoff metadata has no creation-time base directory proof");
9407
+ const creationRelative = path16.relative(recordedBaseDir, pathInspection.realpath);
9408
+ if (!creationRelative || creationRelative === ".." || creationRelative.startsWith(`..${path16.sep}`) || path16.isAbsolute(creationRelative)) return blockedEntry(entry, "ineligible", "keep", `worktree real path is outside its creation-time recorded base directory '${recordedBaseDir}'`);
9606
9409
  if (rootPath === comparablePath(pathInspection.realpath)) return blockedEntry(entry, "ineligible", "keep", "worktree is the repository root");
9607
9410
  if (git.locked) return blockedEntry(entry, "ineligible", "keep", "Git worktree is locked");
9608
9411
  if (!git.branch) return blockedEntry(entry, "unknown", "unknown", "detached worktrees have no metadata-recorded branch");
@@ -9781,7 +9584,7 @@ function buildWorktreeCleanupPlan(input) {
9781
9584
  };
9782
9585
  }
9783
9586
  function worktreeCleanupPlanPath(repoRoot, planId) {
9784
- return path17.join(repoRoot, PROJECT_SUBAGENTS_RELATIVE_DIR, "cleanup-plans", `${validatePlanId(planId)}.json`);
9587
+ return path16.join(repoRoot, PROJECT_SUBAGENTS_RELATIVE_DIR, "cleanup-plans", `${validatePlanId(planId)}.json`);
9785
9588
  }
9786
9589
  function createWorktreeCleanupPlan(input) {
9787
9590
  const plan = buildWorktreeCleanupPlan(input);
@@ -9829,13 +9632,13 @@ function formatWorktreeCleanupPlan(created) {
9829
9632
 
9830
9633
  // src/runs/shared/worktree-cleanup-apply.ts
9831
9634
  function assertContainedRealPath(repoRoot, candidate, create = false) {
9832
- const relative3 = path18.relative(repoRoot, candidate);
9833
- if (!relative3 || relative3 === ".." || relative3.startsWith(`..${path18.sep}`) || path18.isAbsolute(relative3)) throw new Error("Cleanup evidence must be inside the selected repository.");
9635
+ const relative3 = path17.relative(repoRoot, candidate);
9636
+ if (!relative3 || relative3 === ".." || relative3.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative3)) throw new Error("Cleanup evidence must be inside the selected repository.");
9834
9637
  let current = repoRoot;
9835
- for (const segment of relative3.split(path18.sep)) {
9836
- current = path18.join(current, segment);
9837
- if (!fs20.existsSync(current) && create) fs20.mkdirSync(current, { mode: 448 });
9838
- const stat = fs20.lstatSync(current);
9638
+ for (const segment of relative3.split(path17.sep)) {
9639
+ current = path17.join(current, segment);
9640
+ if (!fs19.existsSync(current) && create) fs19.mkdirSync(current, { mode: 448 });
9641
+ const stat = fs19.lstatSync(current);
9839
9642
  if (stat.isSymbolicLink()) throw new Error(`Cleanup evidence cannot use a symlink: ${current}`);
9840
9643
  }
9841
9644
  }
@@ -9843,14 +9646,14 @@ function loadReviewedCleanupPlan(repo, planId, now = Date.now()) {
9843
9646
  const repoRoot = resolveCleanupRepoRoot(repo);
9844
9647
  const file = worktreeCleanupPlanPath(repoRoot, planId);
9845
9648
  assertContainedRealPath(repoRoot, file);
9846
- const stat = fs20.statSync(file);
9649
+ const stat = fs19.statSync(file);
9847
9650
  if (!stat.isFile() || stat.size > 2 * 1024 * 1024) throw new Error("Cleanup plan is not a bounded regular file.");
9848
- const plan = JSON.parse(fs20.readFileSync(file, "utf-8"));
9849
- if (plan.version !== 1 || plan.planId !== planId || plan.repoRoot !== repoRoot || !Number.isFinite(plan.createdAt) || !Number.isFinite(plan.expiresAt) || plan.createdAt > now || plan.expiresAt <= now && !fs20.existsSync(file.replace(/\.json$/, ".claim")) || plan.expiresAt - plan.createdAt !== WORKTREE_CLEANUP_PLAN_TTL_MS) throw new Error("Cleanup plan is invalid, expired, or belongs to another repository.");
9850
- if (!Array.isArray(plan.entries) || plan.entries.length > 512 || !Array.isArray(plan.baseDirs) || plan.baseDirs.length !== 1 || !plan.baseDirs.every((item) => typeof item === "string" && path18.isAbsolute(item)) || !Array.isArray(plan.metadataPaths) || !plan.metadataPaths.every((item) => typeof item === "string" && path18.isAbsolute(item)) || !Array.isArray(plan.pruneCandidates)) throw new Error("Cleanup plan has invalid inventory fields.");
9651
+ const plan = JSON.parse(fs19.readFileSync(file, "utf-8"));
9652
+ if (plan.version !== 1 || plan.planId !== planId || plan.repoRoot !== repoRoot || !Number.isFinite(plan.createdAt) || !Number.isFinite(plan.expiresAt) || plan.createdAt > now || plan.expiresAt <= now && !fs19.existsSync(file.replace(/\.json$/, ".claim")) || plan.expiresAt - plan.createdAt !== WORKTREE_CLEANUP_PLAN_TTL_MS) throw new Error("Cleanup plan is invalid, expired, or belongs to another repository.");
9653
+ if (!Array.isArray(plan.entries) || plan.entries.length > 512 || !Array.isArray(plan.baseDirs) || plan.baseDirs.length !== 1 || !plan.baseDirs.every((item) => typeof item === "string" && path17.isAbsolute(item)) || !Array.isArray(plan.metadataPaths) || !plan.metadataPaths.every((item) => typeof item === "string" && path17.isAbsolute(item)) || !Array.isArray(plan.pruneCandidates)) throw new Error("Cleanup plan has invalid inventory fields.");
9851
9654
  const paths = /* @__PURE__ */ new Set();
9852
9655
  for (const entry of plan.entries) {
9853
- if (!entry || typeof entry.path !== "string" || !path18.isAbsolute(entry.path) || typeof entry.branch !== "string" || !["remove", "keep", "unknown"].includes(entry.decision) || !entry.preconditions || entry.preconditions.path !== entry.path || entry.preconditions.branch !== entry.branch || !Array.isArray(entry.reasons) || !entry.reasons.every((reason) => typeof reason === "string") || paths.has(entry.path)) throw new Error("Cleanup plan has invalid or duplicate entries.");
9656
+ if (!entry || typeof entry.path !== "string" || !path17.isAbsolute(entry.path) || typeof entry.branch !== "string" || !["remove", "keep", "unknown"].includes(entry.decision) || !entry.preconditions || entry.preconditions.path !== entry.path || entry.preconditions.branch !== entry.branch || !Array.isArray(entry.reasons) || !entry.reasons.every((reason) => typeof reason === "string") || paths.has(entry.path)) throw new Error("Cleanup plan has invalid or duplicate entries.");
9854
9657
  paths.add(entry.path);
9855
9658
  }
9856
9659
  const hash = createHash5("sha256").update(JSON.stringify(worktreeCleanupContentPayload(plan))).digest("hex");
@@ -9860,7 +9663,7 @@ function loadReviewedCleanupPlan(repo, planId, now = Date.now()) {
9860
9663
  function recordRemoval(entry) {
9861
9664
  const manifest = readParallelHandoffManifest(entry.handoffPath);
9862
9665
  if (!manifest || manifest.runId !== entry.runId) throw new Error("Handoff ownership changed before recording removal.");
9863
- const tasks = manifest.groups.flatMap((group) => group.cleanup.tasks).filter((task) => task.index === entry.taskIndex && samePath(path18.resolve(path18.dirname(entry.handoffPath), task.path), entry.path) && task.branch === entry.branch);
9666
+ const tasks = manifest.groups.flatMap((group) => group.cleanup.tasks).filter((task) => task.index === entry.taskIndex && samePath(path17.resolve(path17.dirname(entry.handoffPath), task.path), entry.path) && task.branch === entry.branch);
9864
9667
  if (tasks.length !== 1) throw new Error("Handoff task no longer identifies exactly one removed worktree.");
9865
9668
  if (tasks[0].worktreeRemoved) return;
9866
9669
  tasks[0].worktreeRemoved = true;
@@ -9875,20 +9678,20 @@ async function applyReviewedCleanupPlan(input) {
9875
9678
  return withWorktreeTransaction(() => withRepositoryWorktreeLock(input.repo, async () => {
9876
9679
  const plan = loadReviewedCleanupPlan(input.repo, input.planId);
9877
9680
  const claimPath = worktreeCleanupPlanPath(plan.repoRoot, plan.planId).replace(/\.json$/, ".claim");
9878
- const receiptPath = path18.join(claimPath, "receipt.json");
9879
- assertContainedRealPath(plan.repoRoot, path18.dirname(claimPath));
9681
+ const receiptPath = path17.join(claimPath, "receipt.json");
9682
+ assertContainedRealPath(plan.repoRoot, path17.dirname(claimPath));
9880
9683
  try {
9881
- fs20.mkdirSync(claimPath, { mode: 448 });
9684
+ fs19.mkdirSync(claimPath, { mode: 448 });
9882
9685
  } catch (error) {
9883
9686
  if (error.code !== "EEXIST") throw error;
9884
9687
  assertContainedRealPath(plan.repoRoot, receiptPath);
9885
- const receipt2 = JSON.parse(fs20.readFileSync(receiptPath, "utf-8"));
9688
+ const receipt2 = JSON.parse(fs19.readFileSync(receiptPath, "utf-8"));
9886
9689
  if (receipt2.version !== 1 || receipt2.planId !== plan.planId || receipt2.repoRoot !== plan.repoRoot || receipt2.contentHash !== plan.contentHash || !Array.isArray(receipt2.entries) || !["applying", "complete", "partial"].includes(receipt2.state)) throw new Error("Claimed cleanup plan has an invalid receipt; inspect it before creating a fresh plan.");
9887
9690
  for (const entry of plan.entries.filter((entry2) => receipt2.state !== "complete" && entry2.decision === "remove" && receipt2.entries.some((item) => (item?.state === "removing" || item?.state === "removed") && item.path === entry2.path && item.branch === entry2.branch))) {
9888
- await new Promise((resolve10) => setImmediate(resolve10));
9691
+ await new Promise((resolve9) => setImmediate(resolve9));
9889
9692
  input.signal?.throwIfAborted();
9890
9693
  try {
9891
- fs20.lstatSync(entry.path);
9694
+ fs19.lstatSync(entry.path);
9892
9695
  continue;
9893
9696
  } catch (error2) {
9894
9697
  if (error2.code !== "ENOENT") throw error2;
@@ -9910,7 +9713,7 @@ async function applyReviewedCleanupPlan(input) {
9910
9713
  try {
9911
9714
  const selected = input.select?.(plan);
9912
9715
  for (const entry of plan.entries.filter((item) => item.decision === "remove")) {
9913
- await new Promise((resolve10) => setImmediate(resolve10));
9716
+ await new Promise((resolve9) => setImmediate(resolve9));
9914
9717
  input.signal?.throwIfAborted();
9915
9718
  if (selected && !selected.has(entry.path)) {
9916
9719
  receipt.entries.push({ path: entry.path, branch: entry.branch, state: "kept", reason: "outside the current retention excess" });
@@ -9920,7 +9723,7 @@ async function applyReviewedCleanupPlan(input) {
9920
9723
  withHandoffWriteLock(entry.handoffPath, () => {
9921
9724
  const manifest = readParallelHandoffManifest(entry.handoffPath);
9922
9725
  if (!manifest || manifest.runId !== entry.runId) throw new Error("Handoff ownership changed before cleanup validation.");
9923
- const fresh = buildWorktreeCleanupPlan({ repo: plan.repoRoot, candidatePaths: [entry.path], handoffPaths: plan.metadataPaths, worktreeBaseDir: path18.dirname(plan.baseDirs[0]), foregroundRunOwnership: input.foregroundRunOwnership });
9726
+ const fresh = buildWorktreeCleanupPlan({ repo: plan.repoRoot, candidatePaths: [entry.path], handoffPaths: plan.metadataPaths, worktreeBaseDir: path17.dirname(plan.baseDirs[0]), foregroundRunOwnership: input.foregroundRunOwnership });
9924
9727
  const candidate = fresh.entries.find((item) => item.path === entry.path);
9925
9728
  if (fresh.warnings?.some((warning) => /capped|failed to inspect/.test(warning)) || !candidate || candidate.decision !== "remove" || candidate.handoffPath !== entry.handoffPath || candidate.runId !== entry.runId || candidate.taskIndex !== entry.taskIndex || candidate.patchPath !== entry.patchPath || JSON.stringify(candidate.preconditions) !== JSON.stringify(entry.preconditions)) {
9926
9729
  receipt.entries.push({ path: entry.path, branch: entry.branch, state: "kept", reason: candidate?.reasons.join("; ") || "reviewed ownership or Git facts changed" });
@@ -9930,7 +9733,7 @@ async function applyReviewedCleanupPlan(input) {
9930
9733
  const journalEntry = { path: entry.path, branch: entry.branch, state: "removing", reason: "removal prepared; outcome not yet recorded" };
9931
9734
  receipt.entries.push(journalEntry);
9932
9735
  writePrivateAtomicJson(receiptPath, receipt);
9933
- const removed = spawnSync3("git", ["-C", plan.repoRoot, "worktree", "remove", "--", entry.path], { encoding: "utf-8", windowsHide: true });
9736
+ const removed = spawnSync2("git", ["-C", plan.repoRoot, "worktree", "remove", "--", entry.path], { encoding: "utf-8", windowsHide: true });
9934
9737
  if (removed.status !== 0) throw new Error(removed.error?.message || removed.stderr.trim() || "git worktree remove failed");
9935
9738
  journalEntry.state = "removed";
9936
9739
  journalEntry.reason = "worktree removed; local branch retained";
@@ -10018,13 +9821,13 @@ function inheritedRunFanoutBudget(deps) {
10018
9821
  return deps.childRuntime?.runFanoutBudget;
10019
9822
  }
10020
9823
  function resolveRequestedCwd(runtimeCwd, requestedCwd) {
10021
- return requestedCwd ? path19.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
9824
+ return requestedCwd ? path18.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
10022
9825
  }
10023
9826
  function readWorkflowScriptFile(requestedPath, requestedCwd, runtimeCwd) {
10024
- const scriptPath = path19.resolve(resolveRequestedCwd(runtimeCwd, requestedCwd), requestedPath);
9827
+ const scriptPath = path18.resolve(resolveRequestedCwd(runtimeCwd, requestedCwd), requestedPath);
10025
9828
  let script;
10026
9829
  try {
10027
- script = fs21.readFileSync(scriptPath, "utf8");
9830
+ script = fs20.readFileSync(scriptPath, "utf8");
10028
9831
  } catch (error) {
10029
9832
  return { error: `Failed to read workflow script '${scriptPath}': ${error instanceof Error ? error.message : String(error)}` };
10030
9833
  }
@@ -10098,7 +9901,7 @@ function nestedResolutionScopeForExecutor(deps) {
10098
9901
  };
10099
9902
  }
10100
9903
  function trustedSessionRoots(parentSessionFile, deps) {
10101
- const roots = deps.config.defaultSessionDir ? [path19.resolve(deps.expandTilde(deps.config.defaultSessionDir))] : [];
9904
+ const roots = deps.config.defaultSessionDir ? [path18.resolve(deps.expandTilde(deps.config.defaultSessionDir))] : [];
10102
9905
  if (parentSessionFile) for (const sessionFile of [parentSessionFile, ...inheritedSessionIds(parentSessionFile)]) roots.push(deps.getSubagentSessionRoot(sessionFile));
10103
9906
  return [...new Set(roots)];
10104
9907
  }
@@ -10428,9 +10231,9 @@ function resolveForegroundResumeTarget(params, state, options = {}) {
10428
10231
  if (index < 0 || index >= run.children.length) throw new Error(`Foreground run '${run.runId}' has ${run.children.length} children. Index ${index} is out of range.`);
10429
10232
  const child = run.children[index];
10430
10233
  if (!child.sessionFile) throw new Error(`Foreground run '${run.runId}' child ${index} does not have a persisted session file to resume from.`);
10431
- if (path19.extname(child.sessionFile) !== ".jsonl") throw new Error(`Foreground run '${run.runId}' child ${index} session file must be a .jsonl file: ${child.sessionFile}`);
10432
- const sessionFile = path19.resolve(child.sessionFile);
10433
- if (!fs21.existsSync(sessionFile)) throw new Error(`Foreground run '${run.runId}' child ${index} session file does not exist: ${child.sessionFile}`);
10234
+ if (path18.extname(child.sessionFile) !== ".jsonl") throw new Error(`Foreground run '${run.runId}' child ${index} session file must be a .jsonl file: ${child.sessionFile}`);
10235
+ const sessionFile = path18.resolve(child.sessionFile);
10236
+ if (!fs20.existsSync(sessionFile)) throw new Error(`Foreground run '${run.runId}' child ${index} session file does not exist: ${child.sessionFile}`);
10434
10237
  return {
10435
10238
  runId: run.runId,
10436
10239
  mode: run.mode,
@@ -10449,9 +10252,6 @@ function resolveForegroundResumeTarget(params, state, options = {}) {
10449
10252
  ...child.capabilityCeiling ? { capabilityCeiling: child.capabilityCeiling } : {}
10450
10253
  };
10451
10254
  }
10452
- function isAsyncRunNotFound(error) {
10453
- return error instanceof Error && error.message.startsWith("Async run not found.");
10454
- }
10455
10255
  function isMissingExactAsyncStatusFile(error, requested) {
10456
10256
  return error instanceof Error && error.message === `Status file not found for async run '${requested}'.`;
10457
10257
  }
@@ -10481,7 +10281,7 @@ function resolveResumeTarget(params, state, options = {}) {
10481
10281
  foregroundError = error;
10482
10282
  }
10483
10283
  try {
10484
- const asyncParams = options.exactOnly && requested && !params.dir ? { ...params, dir: path19.join(DIRS.async, requested) } : params;
10284
+ const asyncParams = options.exactOnly && requested && !params.dir ? { ...params, dir: path18.join(DIRS.async, requested) } : params;
10485
10285
  asyncTarget = {
10486
10286
  source: "async",
10487
10287
  ...resolveAsyncResumeTarget(asyncParams, {}, compactOptional({
@@ -10509,32 +10309,10 @@ function resolveResumeTarget(params, state, options = {}) {
10509
10309
  if (isResumeAmbiguity(foregroundError) && !resumeTargetExact(asyncTarget, requested)) throw foregroundError;
10510
10310
  return asyncTarget;
10511
10311
  }
10512
- if (foregroundError && !isAsyncRunNotFound(asyncError)) throw foregroundError;
10513
10312
  if (foregroundError) throw foregroundError;
10514
10313
  if (asyncError) throw asyncError;
10515
10314
  throw new Error("Run not found. Provide id or runId.");
10516
10315
  }
10517
- function getAsyncInterruptTarget(state, runId, location, options = {}) {
10518
- if (location?.asyncDir) {
10519
- return {
10520
- asyncId: location.resolvedId ?? runId ?? path19.basename(location.asyncDir),
10521
- asyncDir: location.asyncDir
10522
- };
10523
- }
10524
- if (runId) {
10525
- const direct = state.asyncJobs.get(runId);
10526
- if (direct) return { asyncId: direct.asyncId, asyncDir: direct.asyncDir };
10527
- if (options.fallbackToNewest === false) return void 0;
10528
- }
10529
- let newest;
10530
- for (const job of state.asyncJobs.values()) {
10531
- if (job.status !== "running") continue;
10532
- if (!newest || (job.updatedAt ?? 0) > newest.updatedAt) {
10533
- newest = { asyncId: job.asyncId, asyncDir: job.asyncDir, updatedAt: job.updatedAt ?? 0 };
10534
- }
10535
- }
10536
- return newest ? { asyncId: newest.asyncId, asyncDir: newest.asyncDir } : void 0;
10537
- }
10538
10316
  function isStaleExtensionContextError2(error) {
10539
10317
  if (!(error instanceof Error)) return false;
10540
10318
  return /extension ctx is stale|stale after session replacement or reload/i.test(error.message);
@@ -10566,7 +10344,7 @@ function persistAsyncWorkflowControlEvent(input) {
10566
10344
  } : {}
10567
10345
  };
10568
10346
  try {
10569
- fs21.appendFileSync(path19.join(input.job.asyncDir, "events.jsonl"), `${JSON.stringify(record2)}
10347
+ fs20.appendFileSync(path18.join(input.job.asyncDir, "events.jsonl"), `${JSON.stringify(record2)}
10570
10348
  `, "utf-8");
10571
10349
  } catch (error) {
10572
10350
  if (!isStorageCapacityError(error)) throw error;
@@ -10594,12 +10372,12 @@ function emitControlNotification(input) {
10594
10372
  }
10595
10373
  }
10596
10374
  function interruptAsyncRun(state, runId, kill, location) {
10597
- const target = getAsyncInterruptTarget(state, runId, location, { fallbackToNewest: runId === void 0 });
10375
+ const target = location?.asyncDir ? { asyncId: location.resolvedId ?? runId, asyncDir: location.asyncDir } : state.asyncJobs.get(runId);
10598
10376
  if (!target) return null;
10599
10377
  const status = reconcileAsyncRun(target.asyncDir, omitUndefinedProperties({ kill })).status;
10600
10378
  if (!status || status.state !== "running" || typeof status.pid !== "number") {
10601
10379
  return {
10602
- content: [{ type: "text", text: `No running async run with an interrupt-capable pid was found for '${runId ?? "current"}'.` }],
10380
+ content: [{ type: "text", text: `No running async run with an interrupt-capable pid was found for '${runId}'.` }],
10603
10381
  isError: true,
10604
10382
  details: { mode: "management", results: [] }
10605
10383
  };
@@ -10816,7 +10594,7 @@ function appendStepToAsyncChain(input) {
10816
10594
  worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
10817
10595
  asyncDir: resolved.location.asyncDir,
10818
10596
  validateOutputBindings: false,
10819
- capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId)),
10597
+ capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.parentSessionId)),
10820
10598
  requiredExtensions: retainedRequiredExtensions
10821
10599
  }));
10822
10600
  if ("error" in built) {
@@ -10886,25 +10664,25 @@ function nestedRunAgent(run) {
10886
10664
  return run.agent ?? run.agents?.[0] ?? (run.steps?.length === 1 ? run.steps[0]?.agent : void 0);
10887
10665
  }
10888
10666
  function pathWithin(base, candidate) {
10889
- const resolvedBase = path19.resolve(base);
10890
- const resolvedCandidate = path19.resolve(candidate);
10891
- return resolvedCandidate === resolvedBase || resolvedCandidate.startsWith(`${resolvedBase}${path19.sep}`);
10667
+ const resolvedBase = path18.resolve(base);
10668
+ const resolvedCandidate = path18.resolve(candidate);
10669
+ return resolvedCandidate === resolvedBase || resolvedCandidate.startsWith(`${resolvedBase}${path18.sep}`);
10892
10670
  }
10893
10671
  function validateNestedSessionFile(run, trustedSessionRoots2, resolveSource, visited = []) {
10894
10672
  const sessionFile = nestedRunSessionFile(run);
10895
10673
  if (!sessionFile) throw new Error(`Nested run '${run.id}' does not have a persisted session file to resume from.`);
10896
- if (path19.extname(sessionFile) !== ".jsonl") throw new Error(`Nested run '${run.id}' session file must be a .jsonl file: ${sessionFile}`);
10897
- const resolved = path19.resolve(sessionFile);
10898
- if (!path19.isAbsolute(sessionFile)) throw new Error(`Nested run '${run.id}' session file must be absolute: ${sessionFile}`);
10899
- if (!fs21.existsSync(resolved)) throw new Error(`Nested run '${run.id}' session file does not exist: ${sessionFile}`);
10900
- const stat = fs21.lstatSync(resolved);
10674
+ if (path18.extname(sessionFile) !== ".jsonl") throw new Error(`Nested run '${run.id}' session file must be a .jsonl file: ${sessionFile}`);
10675
+ const resolved = path18.resolve(sessionFile);
10676
+ if (!path18.isAbsolute(sessionFile)) throw new Error(`Nested run '${run.id}' session file must be absolute: ${sessionFile}`);
10677
+ if (!fs20.existsSync(resolved)) throw new Error(`Nested run '${run.id}' session file does not exist: ${sessionFile}`);
10678
+ const stat = fs20.lstatSync(resolved);
10901
10679
  if (!stat.isFile() || stat.isSymbolicLink()) throw new Error(`Nested run '${run.id}' session file is not a regular file: ${sessionFile}`);
10902
- const realSessionFile = fs21.realpathSync(resolved);
10903
- const trustedRoots = trustedSessionRoots2.filter((root) => fs21.existsSync(root)).map((root) => fs21.realpathSync(root));
10680
+ const realSessionFile = fs20.realpathSync(resolved);
10681
+ const trustedRoots = trustedSessionRoots2.filter((root) => fs20.existsSync(root)).map((root) => fs20.realpathSync(root));
10904
10682
  if (!trustedRoots.some((root) => pathWithin(root, realSessionFile))) {
10905
10683
  throw new Error(`Nested run '${run.id}' session file is outside trusted nested session roots: ${sessionFile}`);
10906
10684
  }
10907
- if (!realSessionFile.split(path19.sep).includes(run.id)) {
10685
+ if (!realSessionFile.split(path18.sep).includes(run.id)) {
10908
10686
  const sourceId = run.revivedFrom;
10909
10687
  const chain = [...visited, run.id];
10910
10688
  const source = sourceId && chain.length <= 8 && !chain.includes(sourceId) ? resolveSource(sourceId) : void 0;
@@ -10945,7 +10723,7 @@ function resolveNestedResumeTarget(match, trustedSessionRoots2, resolveSource) {
10945
10723
  state,
10946
10724
  agent,
10947
10725
  index: 0,
10948
- cwd: asyncDir ? path19.dirname(asyncDir) : void 0,
10726
+ cwd: asyncDir ? path18.dirname(asyncDir) : void 0,
10949
10727
  sessionFile: validateNestedSessionFile(run, trustedSessionRoots2, resolveSource),
10950
10728
  ...run.capabilityCeiling ? { capabilityCeiling: run.capabilityCeiling } : {},
10951
10729
  ...recoveryDescriptor ? { recoveryDescriptor } : {}
@@ -10992,7 +10770,7 @@ async function waitForNestedControlResult(target, requestId, ignoredFiles, timeo
10992
10770
  while (Date.now() < deadline) {
10993
10771
  const result2 = findNestedControlResult(target.match.route, requestId, target.match.run.id, ignoredFiles);
10994
10772
  if (result2) return result2;
10995
- await new Promise((resolve10) => setTimeout(resolve10, 50));
10773
+ await new Promise((resolve9) => setTimeout(resolve9, 50));
10996
10774
  }
10997
10775
  return void 0;
10998
10776
  }
@@ -11013,7 +10791,7 @@ function directNestedAsyncInterrupt(target) {
11013
10791
  const run = target.match.run;
11014
10792
  const asyncDir = resolveNestedAsyncDir(target.match.rootRunId, run);
11015
10793
  if (!asyncDir) return void 0;
11016
- const status = reconcileAsyncRun(asyncDir, { resultsDir: path19.join(DIRS.results, "nested", target.match.rootRunId) }).status;
10794
+ const status = reconcileAsyncRun(asyncDir, { resultsDir: path18.join(DIRS.results, "nested", target.match.rootRunId) }).status;
11017
10795
  const pid = typeof status?.pid === "number" && status.pid > 0 ? status.pid : run.pid;
11018
10796
  if (!status || status.state !== "running" || typeof pid !== "number" || pid <= 0) return void 0;
11019
10797
  try {
@@ -11028,7 +10806,7 @@ async function directNestedAsyncSteer(input) {
11028
10806
  const run = input.target.match.run;
11029
10807
  const asyncDir = resolveNestedAsyncDir(input.target.match.rootRunId, run);
11030
10808
  if (!asyncDir) return void 0;
11031
- const status = reconcileAsyncRun(asyncDir, { resultsDir: path19.join(DIRS.results, "nested", input.target.match.rootRunId) }).status;
10809
+ const status = reconcileAsyncRun(asyncDir, { resultsDir: path18.join(DIRS.results, "nested", input.target.match.rootRunId) }).status;
11032
10810
  if (!status || status.state !== "running" && status.state !== "queued") return void 0;
11033
10811
  const steps = status.steps ?? [];
11034
10812
  if (input.index !== void 0) {
@@ -11137,10 +10915,10 @@ async function resumeExternalJobFollowUp(input) {
11137
10915
  const runId = externalJobFollowUpRunId(requestDigest);
11138
10916
  const nestedRoute = inheritedNestedRoute(input.deps);
11139
10917
  const runRoots = nestedRoute ? nestedRunScope(nestedRoute.rootRunId) : { asyncDirRoot: DIRS.async, resultsDir: DIRS.results };
11140
- const asyncDir = path19.join(runRoots.asyncDirRoot, runId);
10918
+ const asyncDir = path18.join(runRoots.asyncDirRoot, runId);
11141
10919
  const currentSessionId = input.deps.state.currentSessionId;
11142
10920
  if (!currentSessionId) return { content: [{ type: "text", text: "External-job follow-up requires an active parent session." }], isError: true, details: { mode: "management", results: [] } };
11143
- if (fs21.existsSync(asyncDir) || fs21.existsSync(resultFilePath(runRoots.resultsDir, runId))) {
10921
+ if (fs20.existsSync(asyncDir) || fs20.existsSync(resultFilePath(runRoots.resultsDir, runId))) {
11144
10922
  return externalJobFollowUpStarted({ sourceRunId: input.target.runId, runId, asyncDir, duplicate: true, interactive: input.ctx.hasUI });
11145
10923
  }
11146
10924
  const depthState = checkSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime);
@@ -11209,7 +10987,7 @@ async function resumeExternalJobFollowUp(input) {
11209
10987
  availableModels: input.ctx.modelRegistry.getAvailable().map(toModelInfo),
11210
10988
  outputBaseDir: resolveSingleRunOutputBaseDir(input.deps, artifactsDir, runId),
11211
10989
  ...input.absoluteDeadlineAt !== void 0 ? { absoluteDeadlineAt: input.absoluteDeadlineAt } : {},
11212
- capabilityCeiling: resolveCurrentSubagentCapabilityCeiling(currentSessionId),
10990
+ capabilityCeiling: resolveCurrentSubagentCapabilityCeiling(input.ctx.sessionManager.getSessionId() ?? void 0),
11213
10991
  runFanoutBudget: createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(input.deps.config.maxSubagentSpawnsPerRun)),
11214
10992
  activeAsyncCapacity,
11215
10993
  externalJobFollowUp: { sourceRunId: input.target.runId, sourceStepIndex: input.target.index, parentProviderJobId: externalJob.providerJobId, requestId, requestDigest }
@@ -11341,7 +11119,7 @@ async function resumeAsyncRun(input) {
11341
11119
  inheritGlobalContext: recoveryDescriptor.inheritGlobalContext,
11342
11120
  inheritSkills: recoveryDescriptor.inheritSkills,
11343
11121
  source: "project",
11344
- filePath: recoveryDescriptor.agentFilePath ?? path19.join(getProjectSubagentsDir(recoveryDescriptor.cwd), "recovery-agent"),
11122
+ filePath: recoveryDescriptor.agentFilePath ?? path18.join(getProjectSubagentsDir(recoveryDescriptor.cwd), "recovery-agent"),
11345
11123
  ...discovered.maxThinking ? { maxThinking: discovered.maxThinking } : {}
11346
11124
  } : void 0);
11347
11125
  if (!baseAgentConfig) {
@@ -11362,7 +11140,7 @@ async function resumeAsyncRun(input) {
11362
11140
  if (target.source === "async" && target.managedWorktree && target.asyncDir) {
11363
11141
  try {
11364
11142
  const protectedCwd = await protectRetainedWorktreeForResume(parallelHandoffPath(target.asyncDir), target.runId, target.index, input.signal);
11365
- if (path19.resolve(protectedCwd) !== path19.resolve(effectiveCwd)) throw new Error("Retained worktree cwd changed during resume admission.");
11143
+ if (path18.resolve(protectedCwd) !== path18.resolve(effectiveCwd)) throw new Error("Retained worktree cwd changed during resume admission.");
11366
11144
  } catch (error) {
11367
11145
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
11368
11146
  }
@@ -11415,7 +11193,7 @@ async function resumeAsyncRun(input) {
11415
11193
  limit: resolveMaxActiveAsyncRunsPerSession(input.deps.config.maxActiveAsyncRunsPerSession),
11416
11194
  runId: runId2,
11417
11195
  kind: "runner",
11418
- asyncDir: path19.join(DIRS.async, runId2)
11196
+ asyncDir: path18.join(DIRS.async, runId2)
11419
11197
  }, { liveWorkflowRunIds: new Set(input.deps.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(input.deps.config.capacity?.abandonedSlotReleaseAfterMs) }) : void 0;
11420
11198
  } catch (error) {
11421
11199
  if (error instanceof ActiveAsyncCapacityError) return { content: [{ type: "text", text: error.message }], isError: true, details: { mode: "chain", results: [], activeAsyncCapacity: error.snapshot } };
@@ -11435,7 +11213,7 @@ async function resumeAsyncRun(input) {
11435
11213
  goal,
11436
11214
  attachRoot: {
11437
11215
  runId: target.runId,
11438
- asyncDir: target.asyncDir ?? path19.join(DIRS.async, target.runId),
11216
+ asyncDir: target.asyncDir ?? path18.join(DIRS.async, target.runId),
11439
11217
  resultPath: resolveAsyncRootResultPath(DIRS.results, target.runId),
11440
11218
  index: target.index,
11441
11219
  agent: target.agent,
@@ -11486,7 +11264,7 @@ async function resumeAsyncRun(input) {
11486
11264
  childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId2, agent, index) : void 0,
11487
11265
  globalConcurrencyLimit: input.deps.config.globalConcurrencyLimit,
11488
11266
  runFanoutBudget: createRunFanoutBudget(runId2, resolveMaxSubagentSpawnsPerRun(input.deps.config.maxSubagentSpawnsPerRun)),
11489
- capabilityCeiling: intersectSubagentCapabilityCeilings("capabilityCeiling" in target ? target.capabilityCeiling : void 0, resolveCurrentSubagentCapabilityCeiling(input.deps.state.currentSessionId)),
11267
+ capabilityCeiling: intersectSubagentCapabilityCeilings("capabilityCeiling" in target ? target.capabilityCeiling : void 0, resolveCurrentSubagentCapabilityCeiling(input.ctx.sessionManager.getSessionId() ?? void 0)),
11490
11268
  thinkingCeiling: target.thinkingCeiling,
11491
11269
  activeAsyncCapacity: activeAsyncCapacity2
11492
11270
  }));
@@ -11539,13 +11317,13 @@ async function resumeAsyncRun(input) {
11539
11317
  limit: resolveMaxActiveAsyncRunsPerSession(input.deps.config.maxActiveAsyncRunsPerSession),
11540
11318
  sourceRunId: target.runId,
11541
11319
  runId,
11542
- asyncDir: path19.join(DIRS.async, runId)
11320
+ asyncDir: path18.join(DIRS.async, runId)
11543
11321
  }, { abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(input.deps.config.capacity?.abandonedSlotReleaseAfterMs) }) : acquireActiveAsyncCapacity({
11544
11322
  sessionId: input.deps.state.currentSessionId,
11545
11323
  limit: resolveMaxActiveAsyncRunsPerSession(input.deps.config.maxActiveAsyncRunsPerSession),
11546
11324
  runId,
11547
11325
  kind: "runner",
11548
- asyncDir: path19.join(DIRS.async, runId)
11326
+ asyncDir: path18.join(DIRS.async, runId)
11549
11327
  }, { abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(input.deps.config.capacity?.abandonedSlotReleaseAfterMs) });
11550
11328
  } catch (error) {
11551
11329
  if (error instanceof ActiveAsyncCapacityError) return { content: [{ type: "text", text: error.message }], isError: true, details: { mode: "single", results: [], activeAsyncCapacity: error.snapshot } };
@@ -11556,7 +11334,7 @@ async function resumeAsyncRun(input) {
11556
11334
  const artifactsDir = recoveryDescriptor?.artifactsDir ?? getArtifactsDir(parentSessionFile, effectiveCwd, artifactConfig.dir);
11557
11335
  const availableModels = input.ctx.modelRegistry.getAvailable().map(toModelInfo);
11558
11336
  const parentModel = input.parentModel;
11559
- const revivalAsyncDir = path19.join(DIRS.async, runId);
11337
+ const revivalAsyncDir = path18.join(DIRS.async, runId);
11560
11338
  const revivalOutputBaseDir = resolveSingleRunOutputBaseDir(input.deps, artifactsDir, runId);
11561
11339
  const inheritedOutput = foregroundContract?.output ?? recoveryDescriptor?.outputPath;
11562
11340
  const inheritedOutputPath = input.params.output === void 0 && input.params.workflowParentRunId === void 0 ? (target.source === "foreground" ? target.savedOutputPath : void 0) ?? resolveSingleOutputPath(inheritedOutput, input.requestCwd, effectiveCwd, revivalOutputBaseDir) : void 0;
@@ -11638,7 +11416,7 @@ async function resumeAsyncRun(input) {
11638
11416
  ...input.params.toolBudget !== void 0 ? { toolBudget: input.params.toolBudget } : {},
11639
11417
  // Recovery descriptors, remembered foreground runs, and current workflow roots
11640
11418
  // preserve parent authority before the selected agent's descendant ceiling.
11641
- capabilityCeiling: intersectSubagentCapabilityCeilings(recoveryDescriptor?.capabilityCeiling ?? (target.source === "foreground" || target.source === "async" && target.mode === "workflow" ? target.capabilityCeiling : void 0), resolveCurrentSubagentCapabilityCeiling(input.deps.state.currentSessionId)),
11419
+ capabilityCeiling: intersectSubagentCapabilityCeilings(recoveryDescriptor?.capabilityCeiling ?? (target.source === "foreground" || target.source === "async" && target.mode === "workflow" ? target.capabilityCeiling : void 0), resolveCurrentSubagentCapabilityCeiling(input.ctx.sessionManager.getSessionId() ?? void 0)),
11642
11420
  runFanoutBudget: input.params.runFanoutBudget ?? recoveryDescriptor?.runFanoutBudget ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(input.deps.config.maxSubagentSpawnsPerRun)),
11643
11421
  parentWorkflowRunId: input.params.workflowParentRunId,
11644
11422
  workflowKey: input.params.workflowKey,
@@ -11664,12 +11442,12 @@ async function resumeAsyncRun(input) {
11664
11442
  return result2;
11665
11443
  }
11666
11444
  notifyLaunch();
11667
- for (const brief of queuedBriefs) fs21.rmSync(brief.path, { force: true });
11445
+ for (const brief of queuedBriefs) fs20.rmSync(brief.path, { force: true });
11668
11446
  if (queuedBriefs.length > 0 && sourceAsyncDir) {
11669
11447
  const sourceStatus = readStatus(sourceAsyncDir);
11670
11448
  if (sourceStatus?.steering) {
11671
11449
  for (const brief of queuedBriefs) updateSteeringTarget(sourceStatus.steering, brief.request.id, target.index, "delivered", Date.now());
11672
- createCapacityResilientJsonWriter({ keepAlive: true }).write(path19.join(sourceAsyncDir, "status.json"), sourceStatus);
11450
+ createCapacityResilientJsonWriter({ keepAlive: true }).write(path18.join(sourceAsyncDir, "status.json"), sourceStatus);
11673
11451
  }
11674
11452
  }
11675
11453
  const revivedId = result2.details.asyncId ?? runId;
@@ -11731,7 +11509,7 @@ function formatFailedSingleRunOutput(result2, displayOutput) {
11731
11509
  cappedOutput = capInlineOutput(output, { artifactPath: result2.artifactPaths?.outputPath, savedPath: result2.savedOutputPath });
11732
11510
  lines.push("", "Output:", cappedOutput);
11733
11511
  }
11734
- if (cappedOutput === output && result2.artifactPaths?.outputPath && fs21.existsSync(result2.artifactPaths.outputPath)) {
11512
+ if (cappedOutput === output && result2.artifactPaths?.outputPath && fs20.existsSync(result2.artifactPaths.outputPath)) {
11735
11513
  lines.push("", `Output artifact: ${result2.artifactPaths.outputPath}`);
11736
11514
  }
11737
11515
  return lines.join("\n");
@@ -11824,7 +11602,7 @@ async function maybeBuildForegroundIntercomReceipt(input) {
11824
11602
  }
11825
11603
  function diagnosticContextFromDiscovery(discovered, cwd, scope) {
11826
11604
  if (discovered.cwd && discovered.scope && discovered.directories) return unknownAgentDiagnosticContext({ ...discovered, cwd: discovered.cwd, scope: discovered.scope, directories: discovered.directories });
11827
- return unknownAgentDiagnosticContext(discoverAgents(path19.resolve(cwd), scope));
11605
+ return unknownAgentDiagnosticContext(discoverAgents(path18.resolve(cwd), scope));
11828
11606
  }
11829
11607
  function canonicalizeAgentName(name, agents, diagnostics, context) {
11830
11608
  const resolved = resolveAgentName(name, agents);
@@ -11857,12 +11635,12 @@ function workflowValidationOptions(deps, params, runtimeCwd, parentModelProvider
11857
11635
  };
11858
11636
  }
11859
11637
  function canonicalizeExecutionParams(params, agents, diagnostics, context) {
11860
- const resolve10 = (name, location) => {
11638
+ const resolve9 = (name, location) => {
11861
11639
  const result2 = canonicalizeAgentName(name, agents, diagnostics, context);
11862
11640
  return result2.error && location ? { error: `${result2.error} (${location})` } : result2;
11863
11641
  };
11864
11642
  if (params.agent) {
11865
- const result2 = resolve10(params.agent);
11643
+ const result2 = resolve9(params.agent);
11866
11644
  if (result2.error) return { error: result2.error };
11867
11645
  params = omitUndefinedProperties({ ...params, agent: result2.name });
11868
11646
  const agent = agents.find((candidate) => candidate.name === result2.name);
@@ -11881,7 +11659,7 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
11881
11659
  const tasks = [];
11882
11660
  for (let index = 0; index < params.tasks.length; index++) {
11883
11661
  const task = params.tasks[index];
11884
- const result2 = resolve10(task.agent, `task ${index + 1}`);
11662
+ const result2 = resolve9(task.agent, `task ${index + 1}`);
11885
11663
  if (result2.error) return { error: result2.error };
11886
11664
  tasks.push({ ...task, agent: result2.name });
11887
11665
  }
@@ -11895,7 +11673,7 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
11895
11673
  const parallel = [];
11896
11674
  for (let taskIndex = 0; taskIndex < step.parallel.length; taskIndex++) {
11897
11675
  const task = step.parallel[taskIndex];
11898
- const result2 = resolve10(task.agent, `step ${index + 1}, task ${taskIndex + 1}`);
11676
+ const result2 = resolve9(task.agent, `step ${index + 1}, task ${taskIndex + 1}`);
11899
11677
  if (result2.error) return { error: result2.error };
11900
11678
  parallel.push({ ...task, agent: result2.name });
11901
11679
  }
@@ -11903,13 +11681,13 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
11903
11681
  continue;
11904
11682
  }
11905
11683
  if (isDynamicParallelStep(step)) {
11906
- const result2 = resolve10(step.parallel.agent, `step ${index + 1}`);
11684
+ const result2 = resolve9(step.parallel.agent, `step ${index + 1}`);
11907
11685
  if (result2.error) return { error: result2.error };
11908
11686
  chain.push({ ...step, parallel: { ...step.parallel, agent: result2.name } });
11909
11687
  continue;
11910
11688
  }
11911
11689
  if ("agent" in step && typeof step.agent === "string") {
11912
- const result2 = resolve10(step.agent, `step ${index + 1}`);
11690
+ const result2 = resolve9(step.agent, `step ${index + 1}`);
11913
11691
  if (result2.error) return { error: result2.error };
11914
11692
  chain.push({ ...step, agent: result2.name });
11915
11693
  continue;
@@ -12776,7 +12554,7 @@ async function createSingleWorktreeSetup(cwd, runId, agent, setupHook, setupHook
12776
12554
  }
12777
12555
  }
12778
12556
  function resolveConfiguredSingleRunOutputBaseDir(deps) {
12779
- return deps.config.singleRunOutputBaseDir ? path19.resolve(deps.expandTilde(deps.config.singleRunOutputBaseDir)) : void 0;
12557
+ return deps.config.singleRunOutputBaseDir ? path18.resolve(deps.expandTilde(deps.config.singleRunOutputBaseDir)) : void 0;
12780
12558
  }
12781
12559
  function sanitizeRunPathSegment(value, maxBytes = 120) {
12782
12560
  const sanitized = value.trim().replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
@@ -12785,22 +12563,22 @@ function sanitizeRunPathSegment(value, maxBytes = 120) {
12785
12563
  return sanitized.slice(0, maxBytes).replace(/_+$/, "") || "unknown";
12786
12564
  }
12787
12565
  function resolveSingleRunOutputBaseDir(deps, artifactsDir, runId) {
12788
- return resolveConfiguredSingleRunOutputBaseDir(deps) ?? path19.join(artifactsDir, "outputs", sanitizeRunPathSegment(runId));
12566
+ return resolveConfiguredSingleRunOutputBaseDir(deps) ?? path18.join(artifactsDir, "outputs", sanitizeRunPathSegment(runId));
12789
12567
  }
12790
12568
  function suffixedOutputPath(outputPath, suffix) {
12791
- const parsed = path19.parse(outputPath);
12792
- return path19.join(parsed.dir, `${parsed.name}.${suffix}${parsed.ext || ".md"}`);
12569
+ const parsed = path18.parse(outputPath);
12570
+ return path18.join(parsed.dir, `${parsed.name}.${suffix}${parsed.ext || ".md"}`);
12793
12571
  }
12794
12572
  function workflowChildDefaultOutput(aggregateOutputPath, artifactsDir, workflowRunId, workflowKey) {
12795
12573
  if (aggregateOutputPath) return suffixedOutputPath(aggregateOutputPath, workflowKey);
12796
- return path19.join(artifactsDir, "outputs", sanitizeRunPathSegment(workflowRunId), `${workflowKey}.md`);
12574
+ return path18.join(artifactsDir, "outputs", sanitizeRunPathSegment(workflowRunId), `${workflowKey}.md`);
12797
12575
  }
12798
12576
  function workflowHostCommandRunner(input) {
12799
12577
  return async (key, params, signal) => {
12800
12578
  const authorizationError = input.authorize?.(key, params);
12801
12579
  if (authorizationError) throw new Error(authorizationError);
12802
- const defaultOutputPath = path19.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId), "host", `${sanitizeRunPathSegment(key)}.log`);
12803
- const outputPath = params.output ? path19.resolve(input.workflowCwd, params.output) : defaultOutputPath;
12580
+ const defaultOutputPath = path18.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId), "host", `${sanitizeRunPathSegment(key)}.log`);
12581
+ const outputPath = params.output ? path18.resolve(input.workflowCwd, params.output) : defaultOutputPath;
12804
12582
  const claimPath = resolveWorkflowHostOutputClaimPath(outputPath);
12805
12583
  const previous = input.claimedOutputPaths.get(claimPath);
12806
12584
  if (previous) throw new Error(`runs.host('${key}') output path is already claimed by '${previous}': ${outputPath}.`);
@@ -12814,8 +12592,8 @@ function writeWorkflowAggregateOutput(outputPath, text, producedChildOutputPaths
12814
12592
  if (!outputPath) return void 0;
12815
12593
  try {
12816
12594
  if (producedChildOutputPaths.has(resolveWorkflowHostOutputClaimPath(outputPath))) return void 0;
12817
- fs21.mkdirSync(path19.dirname(outputPath), { recursive: true });
12818
- fs21.writeFileSync(outputPath, text, "utf-8");
12595
+ fs20.mkdirSync(path18.dirname(outputPath), { recursive: true });
12596
+ fs20.writeFileSync(outputPath, text, "utf-8");
12819
12597
  return void 0;
12820
12598
  } catch (error) {
12821
12599
  return `Output file error: ${outputPath}
@@ -12886,7 +12664,7 @@ function resolveWorkflowChildOutputPath(input) {
12886
12664
  }
12887
12665
  const output = rawOutput === true || rawOutput === "true" ? agentOutput : hasExplicitOutput ? rawOutput : input.aggregateOutputPath ? workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.workflowRunId, input.key) : agentOutput;
12888
12666
  return {
12889
- path: resolveSingleOutputPath(output, input.ctxCwd, childCwd, input.configuredOutputBaseDir ?? path19.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId))),
12667
+ path: resolveSingleOutputPath(output, input.ctxCwd, childCwd, input.configuredOutputBaseDir ?? path18.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId))),
12890
12668
  inherited: !hasExplicitOutput && !input.aggregateOutputPath && agentOutput !== void 0
12891
12669
  };
12892
12670
  }
@@ -12951,7 +12729,7 @@ async function finalizeSingleWorktreeHandoff(input) {
12951
12729
  try {
12952
12730
  return await withWorktreeTransaction(() => {
12953
12731
  admitted = true;
12954
- const diffsDir = path19.join(input.artifactsDir, "worktree-diffs", input.runId);
12732
+ const diffsDir = path18.join(input.artifactsDir, "worktree-diffs", input.runId);
12955
12733
  const diffs = diffWorktrees(input.worktreeSetup, [input.agent], diffsDir);
12956
12734
  const diffSummary = formatWorktreeDiffSummary(diffs);
12957
12735
  const manifestPath = parallelHandoffPath(input.artifactsDir, input.runId);
@@ -13197,7 +12975,7 @@ async function runSinglePath(data, deps) {
13197
12975
  await cleanupSingleWorktree();
13198
12976
  return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [], parallelHandoff: pendingHandoff } };
13199
12977
  }
13200
- const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path19.join(artifactsDir, "structured-output", runId) : void 0, { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : void 0;
12978
+ const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path18.join(artifactsDir, "structured-output", runId) : void 0, { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : void 0;
13201
12979
  const reads = readsOverride !== void 0 ? readsOverride : agentConfig.defaultReads ?? false;
13202
12980
  const readPaths = !foregroundMachine && Array.isArray(reads) ? resolveExistingReadPaths(reads, singleCwd) : [];
13203
12981
  const readsInstruction = readPaths.length > 0 ? `[Read from: ${readPaths.join(", ")}]
@@ -13281,8 +13059,8 @@ async function runSinglePath(data, deps) {
13281
13059
  };
13282
13060
  let r;
13283
13061
  let resolveDetachedWorkflowChild;
13284
- const detachedWorkflowChild = params.workflowAwaitDetached === true ? new Promise((resolve10) => {
13285
- resolveDetachedWorkflowChild = resolve10;
13062
+ const detachedWorkflowChild = params.workflowAwaitDetached === true ? new Promise((resolve9) => {
13063
+ resolveDetachedWorkflowChild = resolve9;
13286
13064
  }) : void 0;
13287
13065
  try {
13288
13066
  const childSessionFile = sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin);
@@ -13427,7 +13205,7 @@ async function runSinglePath(data, deps) {
13427
13205
  }));
13428
13206
  if (launched.detached && foregroundControl) {
13429
13207
  foregroundControl.stopForRuntimeReplacement = () => {
13430
- const sessionFile = childSessionFile && fs21.existsSync(childSessionFile) ? childSessionFile : void 0;
13208
+ const sessionFile = childSessionFile && fs20.existsSync(childSessionFile) ? childSessionFile : void 0;
13431
13209
  const stopped = { ...launched, detached: void 0, stopped: true, exitCode: 1, error: RUNTIME_REPLACED_STOP_ERROR, finalOutput: RUNTIME_REPLACED_STOP_ERROR, sessionFile };
13432
13210
  rememberForegroundRun(deps.state, { modelResponseAliases, runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: [stopped], params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings, requiredExtensions });
13433
13211
  if (childSessionControls) childSessionControls.stop(RUNTIME_REPLACED_STOP_ERROR);
@@ -13595,8 +13373,8 @@ function bindMissionWorkflowChildAsyncLaunch(params, binding, asyncByDefault, as
13595
13373
  const requestedAsync = params.async ?? asyncByDefault;
13596
13374
  if (!binding || !requestedAsync || params.clarify === true) return params;
13597
13375
  const id = asyncId.trim();
13598
- if (!id || path19.basename(id) !== id) throw new Error("workflow child async id must be a single path segment");
13599
- writeMissionAsyncBinding(path19.join(nestedRootRunId ? nestedRunScope(nestedRootRunId).asyncDirRoot : DIRS.async, id), binding);
13376
+ if (!id || path18.basename(id) !== id) throw new Error("workflow child async id must be a single path segment");
13377
+ writeMissionAsyncBinding(path18.join(nestedRootRunId ? nestedRunScope(nestedRootRunId).asyncDirRoot : DIRS.async, id), binding);
13600
13378
  return { ...params, workflowChildAsyncId: id };
13601
13379
  }
13602
13380
  function workflowChildResult(key, result2, childParams = {}, resumeState, forcedTerminalOutcome) {
@@ -13737,7 +13515,7 @@ var WORKFLOW_STEP_STATES = /* @__PURE__ */ new Set(["pending", "running", "compl
13737
13515
  function isSafeWorkflowChildRunId(value) {
13738
13516
  if (typeof value !== "string") return false;
13739
13517
  const runId = value.trim();
13740
- return value === runId && Boolean(runId) && Buffer.byteLength(runId, "utf8") <= MAX_WORKFLOW_CHILD_RUN_ID_BYTES && path19.basename(runId) === runId && path19.win32.basename(runId) === runId && !/[\\/]/.test(runId) && !runId.includes("..") && !/[\u0000-\u001f\u007f]/.test(runId);
13518
+ return value === runId && Boolean(runId) && Buffer.byteLength(runId, "utf8") <= MAX_WORKFLOW_CHILD_RUN_ID_BYTES && path18.basename(runId) === runId && path18.win32.basename(runId) === runId && !/[\\/]/.test(runId) && !runId.includes("..") && !/[\u0000-\u001f\u007f]/.test(runId);
13741
13519
  }
13742
13520
  function isMissingWorkflowReceiptDiagnostic(error, workflowRunId) {
13743
13521
  return error instanceof Error && error.message.startsWith(`Workflow receipt '${workflowRunId}' is not available because the workflow may still be active or terminal receipt writing failed.`);
@@ -13746,7 +13524,7 @@ function missingWorkflowReceiptResumeHint(reference, state) {
13746
13524
  try {
13747
13525
  if (!state.currentSessionId) return void 0;
13748
13526
  const workflowRunId = reference.workflowRunId.trim();
13749
- const workflowStatus = readStatus(path19.join(DIRS.async, workflowRunId));
13527
+ const workflowStatus = readStatus(path18.join(DIRS.async, workflowRunId));
13750
13528
  if (!workflowStatus || workflowStatus.runId !== workflowRunId || workflowStatus.mode !== "workflow" || workflowStatus.sessionId !== state.currentSessionId || typeof workflowStatus.startedAt !== "number" || !Number.isFinite(workflowStatus.startedAt) || !WORKFLOW_RESUME_HINT_PARENT_STATES.has(workflowStatus.state) || !Array.isArray(workflowStatus.steps) || workflowStatus.steps.some((step) => {
13751
13529
  if (!step || typeof step !== "object" || Array.isArray(step)) return true;
13752
13530
  const record2 = step;
@@ -13781,7 +13559,7 @@ function resolveWorkflowResume(reference, deps, parentSessionFile, index) {
13781
13559
  if (status?.runId === runId && status.parentWorkflowRunId && status.workflowKey) {
13782
13560
  const receiptPath = workflowReceiptPath(DIRS.async, status.parentWorkflowRunId);
13783
13561
  try {
13784
- fs21.statSync(receiptPath);
13562
+ fs20.statSync(receiptPath);
13785
13563
  } catch (error) {
13786
13564
  if (error.code === "ENOENT") return { runId, runIds: [runId] };
13787
13565
  throw error;
@@ -13840,11 +13618,11 @@ async function steerWorkflowChildByKey(input) {
13840
13618
  });
13841
13619
  if (!result2.details.steering?.targets.some((target) => target.reason === CHILD_SESSION_NOT_RUNNING_YET) || Date.now() >= deadline) return workflowSteerReceipt(input.key, result2);
13842
13620
  }
13843
- const workflowStatus = readStatus(path19.join(asyncDirRoot, input.workflowRunId));
13621
+ const workflowStatus = readStatus(path18.join(asyncDirRoot, input.workflowRunId));
13844
13622
  const step = workflowStatus?.steps?.find((candidate) => candidate.workflowKey === input.key);
13845
13623
  const childRunId = step?.runId ?? input.resolveRunId?.();
13846
13624
  if (childRunId) {
13847
- const asyncDir = path19.join(asyncDirRoot, childRunId);
13625
+ const asyncDir = path18.join(asyncDirRoot, childRunId);
13848
13626
  const childStatus = reconcileAsyncRun(asyncDir).status;
13849
13627
  if (childStatus && childStatus.state !== "running" && childStatus.state !== "queued" && (input.options.mode !== "follow_up" || !canQueueRetainedAsyncFollowUp(childStatus, input.options.index))) {
13850
13628
  return { key: input.key, state: "missed", error: `Workflow child '${input.key}' is ${childStatus.state}.` };
@@ -13874,7 +13652,7 @@ async function steerWorkflowChildByKey(input) {
13874
13652
  if (input.signal?.aborted || Date.now() >= deadline) {
13875
13653
  return { key: input.key, state: "missed", error: `Workflow child '${input.key}' had no live steering route.` };
13876
13654
  }
13877
- await new Promise((resolve10) => setTimeout(resolve10, Math.min(10, Math.max(1, deadline - Date.now()))));
13655
+ await new Promise((resolve9) => setTimeout(resolve9, Math.min(10, Math.max(1, deadline - Date.now()))));
13878
13656
  }
13879
13657
  }
13880
13658
  async function preflightWorkflowWorktrees(input) {
@@ -14320,7 +14098,7 @@ function createSubagentExecutor(deps) {
14320
14098
  limit: resolveMaxActiveAsyncRunsPerSession(deps2.config.maxActiveAsyncRunsPerSession),
14321
14099
  runId: workflowRunId,
14322
14100
  kind: "workflow",
14323
- asyncDir: path19.join(DIRS.async, workflowRunId)
14101
+ asyncDir: path18.join(DIRS.async, workflowRunId)
14324
14102
  }, { liveWorkflowRunIds: new Set(deps2.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps2.config.capacity?.abandonedSlotReleaseAfterMs) });
14325
14103
  } catch (error) {
14326
14104
  if (error instanceof ActiveAsyncCapacityError) {
@@ -14366,14 +14144,14 @@ function createSubagentExecutor(deps) {
14366
14144
  };
14367
14145
  if (workflowRunId) {
14368
14146
  const toolCallId = _id;
14369
- const workflowSessionRoot = requestParams.sessionDir ? path19.resolve(deps2.expandTilde(requestParams.sessionDir)) : trustedSessionRoots(ctx.sessionManager.getSessionFile() ?? null, deps2)[0];
14370
- const asyncDir = path19.join(DIRS.async, workflowRunId);
14147
+ const workflowSessionRoot = requestParams.sessionDir ? path18.resolve(deps2.expandTilde(requestParams.sessionDir)) : trustedSessionRoots(ctx.sessionManager.getSessionFile() ?? null, deps2)[0];
14148
+ const asyncDir = path18.join(DIRS.async, workflowRunId);
14371
14149
  const resultPath = resultFilePath(DIRS.results, workflowRunId);
14372
- const statusPath = path19.join(asyncDir, "status.json");
14373
- const eventsPath = path19.join(asyncDir, "events.jsonl");
14150
+ const statusPath = path18.join(asyncDir, "status.json");
14151
+ const eventsPath = path18.join(asyncDir, "events.jsonl");
14374
14152
  const startedAt = Date.now();
14375
14153
  const currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
14376
- const workflowCapabilityCeiling2 = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(currentSessionId));
14154
+ const workflowCapabilityCeiling2 = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(ctx.sessionManager.getSessionId() ?? void 0));
14377
14155
  const completionOwnerId = deps2.state.completionOwnerId ?? currentCompletionOwnerId();
14378
14156
  deps2.state.completionOwnerId = completionOwnerId;
14379
14157
  const workflowScriptSourceDigest = workflowScriptDigest(requestParams.workflowScript);
@@ -14386,7 +14164,7 @@ function createSubagentExecutor(deps) {
14386
14164
  return { content: [{ type: "text", text: `Failed to create async workflow storage: ${error instanceof Error ? error.message : String(error)}` }], isError: true, details: { mode: "workflow", results: [] } };
14387
14165
  };
14388
14166
  if (workflowReuseSource) {
14389
- const reuseSourceDir = path19.join(DIRS.async, workflowReuseSource.runId);
14167
+ const reuseSourceDir = path18.join(DIRS.async, workflowReuseSource.runId);
14390
14168
  let claim;
14391
14169
  try {
14392
14170
  claim = claimWorkflowResume(reuseSourceDir, { newRunId: workflowRunId, trigger: "reuse" });
@@ -14398,14 +14176,14 @@ function createSubagentExecutor(deps) {
14398
14176
  return { content: [{ type: "text", text: claimedWorkflowRunRefusal(workflowReuseSource.runId, claim, requestParams.reuseFrom !== void 0) }], isError: true, details: { mode: "workflow", results: [] } };
14399
14177
  }
14400
14178
  pendingReuseClaimReleases.set(params, () => {
14401
- if (!fs21.existsSync(statusPath)) releaseWorkflowResumeClaim(reuseSourceDir, workflowRunId);
14179
+ if (!fs20.existsSync(statusPath)) releaseWorkflowResumeClaim(reuseSourceDir, workflowRunId);
14402
14180
  });
14403
14181
  }
14404
14182
  try {
14405
- fs21.mkdirSync(asyncDir, { recursive: true });
14183
+ fs20.mkdirSync(asyncDir, { recursive: true });
14406
14184
  writeRunFanoutBudgetDescriptor(asyncDir, workflowFanoutBudget);
14407
14185
  if (topLevelAsyncWorkflow && publicWorkflowLaunch) writeWorkflowLaunchRecord(asyncDir, workflowLaunchRecord(publicWorkflowLaunch, workflowCwd, workflowScriptSourceDigest));
14408
- fs21.mkdirSync(DIRS.results, { recursive: true });
14186
+ fs20.mkdirSync(DIRS.results, { recursive: true });
14409
14187
  } catch (error) {
14410
14188
  return storageFailure(error);
14411
14189
  }
@@ -14438,7 +14216,7 @@ function createSubagentExecutor(deps) {
14438
14216
  };
14439
14217
  const appendWorkflowEvent = (event) => {
14440
14218
  try {
14441
- fs21.appendFileSync(eventsPath, `${JSON.stringify({ ts: Date.now(), runId: workflowRunId, ...event })}
14219
+ fs20.appendFileSync(eventsPath, `${JSON.stringify({ ts: Date.now(), runId: workflowRunId, ...event })}
14442
14220
  `, "utf-8");
14443
14221
  } catch (error) {
14444
14222
  console.error(`Failed to append async workflow event '${eventsPath}':`, error);
@@ -14467,7 +14245,7 @@ function createSubagentExecutor(deps) {
14467
14245
  const message = `Failed to write async workflow result ${resultPath}: ${error instanceof Error ? error.message : String(error)}`;
14468
14246
  console.error(message, error);
14469
14247
  try {
14470
- if (currentSessionId && fallbackResultPayloadPathForSessionRun(path19.dirname(resultPath), currentSessionId, workflowRunId)) return true;
14248
+ if (currentSessionId && fallbackResultPayloadPathForSessionRun(path18.dirname(resultPath), currentSessionId, workflowRunId)) return true;
14471
14249
  } catch (pendingError) {
14472
14250
  console.error(`Failed to verify pending async workflow result '${workflowRunId}':`, pendingError);
14473
14251
  }
@@ -14575,8 +14353,8 @@ Parent action: ${STATUS_ACTION}`,
14575
14353
  };
14576
14354
  pendingResultPublication = void 0;
14577
14355
  runPersistence.write(resultPath, payload);
14578
- if (!resultPublished) pendingResultPublication = new Promise((resolve10) => {
14579
- settleResultPublication = resolve10;
14356
+ if (!resultPublished) pendingResultPublication = new Promise((resolve9) => {
14357
+ settleResultPublication = resolve9;
14580
14358
  });
14581
14359
  return true;
14582
14360
  } catch (error) {
@@ -14913,7 +14691,7 @@ Parent action: ${STATUS_ACTION}`,
14913
14691
  const step = status.steps?.find((candidate) => candidate.workflowKey === key);
14914
14692
  if (!step) return;
14915
14693
  if (runId2) step.runId = runId2;
14916
- step.async = runId2 !== void 0 && path19.basename(runId2) === runId2 && fs21.existsSync(path19.join(path19.dirname(asyncDir), runId2));
14694
+ step.async = runId2 !== void 0 && path18.basename(runId2) === runId2 && fs20.existsSync(path18.join(path18.dirname(asyncDir), runId2));
14917
14695
  persist({ tolerateStatusWriteFailure: true });
14918
14696
  };
14919
14697
  try {
@@ -15014,7 +14792,7 @@ Parent action: ${COMPLETION_ACTION}` : content,
15014
14792
  }
15015
14793
  if (priorChild?.kind === "started") {
15016
14794
  const priorRunId = priorChild.runId;
15017
- const priorAsyncDir = path19.join(DIRS.async, priorRunId);
14795
+ const priorAsyncDir = path18.join(DIRS.async, priorRunId);
15018
14796
  appendWorkflowChildJournal(asyncDir, { type: "start", key, fingerprint: journalFingerprint, runId: priorRunId });
15019
14797
  recordReusedWorkflowChild(key, priorRunId);
15020
14798
  const stopListener = stopAwaitedAsyncChildOnAbort(workflowSignal, deps2.state, priorRunId, priorAsyncDir, deps2.kill, true);
@@ -15117,6 +14895,7 @@ Parent action: ${COMPLETION_ACTION}` : content,
15117
14895
  ...result2.details.results[0]?.sessionFile ? { sessionPath: result2.details.results[0].sessionFile } : {},
15118
14896
  artifactPaths: child.artifactPaths,
15119
14897
  ...["completed", "failed"].includes(childStatus) ? { completedAt: (/* @__PURE__ */ new Date()).toISOString() } : {},
14898
+ acceptanceStatus: missionAcceptanceStatus(result2.details.results),
15120
14899
  heartbeat: { status: childStatus, ...childPhase ? { phase: childPhase } : {} }
15121
14900
  });
15122
14901
  if (result2.details.asyncId) {
@@ -15236,7 +15015,7 @@ Parent action: ${COMPLETION_ACTION}` : content,
15236
15015
  const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : void 0;
15237
15016
  const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps2);
15238
15017
  const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps2, workflowArtifactsDir, foregroundWorkflowRunId));
15239
- const workflowFullResultPath = path19.join(workflowArtifactsDir, `${sanitizeRunPathSegment(foregroundWorkflowRunId)}_workflow-result.md`);
15018
+ const workflowFullResultPath = path18.join(workflowArtifactsDir, `${sanitizeRunPathSegment(foregroundWorkflowRunId)}_workflow-result.md`);
15240
15019
  const claimedOutputPaths = /* @__PURE__ */ new Map();
15241
15020
  const childOutputOverrides = /* @__PURE__ */ new Map();
15242
15021
  const childOutputClaimPaths = /* @__PURE__ */ new Map();
@@ -15261,7 +15040,7 @@ Parent action: ${COMPLETION_ACTION}` : content,
15261
15040
  let lastProgressAt = 0;
15262
15041
  let workflowProgressClosed = false;
15263
15042
  const workflowDeadlineAt = timeout === void 0 ? void 0 : Date.now() + timeout;
15264
- const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(resolveCurrentSessionId(ctx.sessionManager)));
15043
+ const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(ctx.sessionManager.getSessionId() ?? void 0));
15265
15044
  const sendWorkflowProgress = () => {
15266
15045
  if (workflowProgressClosed) return;
15267
15046
  if (activityTimer) clearTimeout(activityTimer);
@@ -15394,6 +15173,7 @@ Parent action: ${COMPLETION_ACTION}` : content,
15394
15173
  ...result2.details.results[0]?.sessionFile ? { sessionPath: result2.details.results[0].sessionFile } : {},
15395
15174
  artifactPaths: child.artifactPaths,
15396
15175
  ...["completed", "failed"].includes(childStatus) ? { completedAt: (/* @__PURE__ */ new Date()).toISOString() } : {},
15176
+ acceptanceStatus: missionAcceptanceStatus(result2.details.results),
15397
15177
  heartbeat: { status: childStatus, ...childPhase ? { phase: childPhase } : {} }
15398
15178
  });
15399
15179
  return child;
@@ -15507,7 +15287,7 @@ ${partial.console.map((entry) => `[${entry.level}] ${entry.text}`).join("\n")}`]
15507
15287
  if (paramsWithResolvedCwd.mode === "apply") {
15508
15288
  try {
15509
15289
  if (!paramsWithResolvedCwd.repo?.trim() || !paramsWithResolvedCwd.planId?.trim() || paramsWithResolvedCwd.handoffPath !== void 0) throw new Error("worktree.cleanup apply requires explicit repo and planId, without handoffPath.");
15510
- const repo = path19.resolve(requestCwd, paramsWithResolvedCwd.repo);
15290
+ const repo = path18.resolve(requestCwd, paramsWithResolvedCwd.repo);
15511
15291
  const plan = loadReviewedCleanupPlan(repo, paramsWithResolvedCwd.planId);
15512
15292
  const decision = resolveAuthorityDecision({ action: "discardWorktree", ...deps2.config.authorityPolicy === void 0 ? {} : { policy: deps2.config.authorityPolicy } });
15513
15293
  if (decision === "forbid") throw new Error("Authority policy forbids worktree cleanup.");
@@ -15537,8 +15317,8 @@ Remove up to ${plan.entries.filter((entry) => entry.decision === "remove").lengt
15537
15317
  }
15538
15318
  try {
15539
15319
  const created = createWorktreeCleanupPlan({
15540
- repo: paramsWithResolvedCwd.repo?.trim() ? path19.isAbsolute(paramsWithResolvedCwd.repo) ? paramsWithResolvedCwd.repo : path19.resolve(requestCwd, paramsWithResolvedCwd.repo) : requestCwd,
15541
- ...paramsWithResolvedCwd.handoffPath ? { handoffPath: path19.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path19.resolve(requestCwd, paramsWithResolvedCwd.handoffPath) } : {},
15320
+ repo: paramsWithResolvedCwd.repo?.trim() ? path18.isAbsolute(paramsWithResolvedCwd.repo) ? paramsWithResolvedCwd.repo : path18.resolve(requestCwd, paramsWithResolvedCwd.repo) : requestCwd,
15321
+ ...paramsWithResolvedCwd.handoffPath ? { handoffPath: path18.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path18.resolve(requestCwd, paramsWithResolvedCwd.handoffPath) } : {},
15542
15322
  ...deps2.config.worktreeBaseDir ? { worktreeBaseDir: deps2.config.worktreeBaseDir } : {},
15543
15323
  foregroundRunOwnership: (runId2) => {
15544
15324
  if (deps2.state.foregroundControls.has(runId2)) return "active";
@@ -15571,7 +15351,7 @@ ${paramsWithResolvedCwd.handoffPath}`);
15571
15351
  }
15572
15352
  if (!confirmed) return { content: [{ type: "text", text: "Worktree discard canceled; preserved worktrees were not changed." }], details: { mode: "management", results: [] } };
15573
15353
  try {
15574
- const manifestPath = path19.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path19.resolve(requestCwd, paramsWithResolvedCwd.handoffPath);
15354
+ const manifestPath = path18.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path18.resolve(requestCwd, paramsWithResolvedCwd.handoffPath);
15575
15355
  const discarded = await withWorktreeTransaction(() => discardPreservedWorktrees(
15576
15356
  manifestPath,
15577
15357
  { kind: decision === "confirm" ? "confirmed" : "policy", ...deps2.config.authorityPolicy ? { policy: deps2.config.authorityPolicy } : {} }
@@ -15589,7 +15369,7 @@ ${paramsWithResolvedCwd.handoffPath}`);
15589
15369
  if (!laneId) return { content: [{ type: "text", text: `${action} requires laneId.` }], isError: true, details: { mode: "management", results: [] } };
15590
15370
  const handoffPath = paramsWithResolvedCwd.handoffPath?.trim();
15591
15371
  if (!handoffPath) return { content: [{ type: "text", text: `${action} requires handoffPath for the existing parallel handoff manifest.` }], isError: true, details: { mode: "management", results: [] } };
15592
- const manifestPath = path19.isAbsolute(handoffPath) ? handoffPath : path19.resolve(requestCwd, handoffPath);
15372
+ const manifestPath = path18.isAbsolute(handoffPath) ? handoffPath : path18.resolve(requestCwd, handoffPath);
15593
15373
  try {
15594
15374
  if (action === "lane.status") {
15595
15375
  let manifest;
@@ -15765,9 +15545,7 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
15765
15545
  if (action === "guide") {
15766
15546
  try {
15767
15547
  const guide = readSubagentGuide(paramsWithResolvedCwd.topic);
15768
- const [topic, section] = paramsWithResolvedCwd.topic?.split("/") ?? [];
15769
- const fullNotice = topic === "tool-reference" ? disabledFeatureNotice(disabledFeatures) : void 0;
15770
- const notice = fullNotice && section !== void 0 ? "Some options and actions documented here are disabled by config in this session; guide topic tool-reference lists them." : fullNotice;
15548
+ const notice = paramsWithResolvedCwd.topic?.includes("/") ? disabledFeatureSectionNotice(disabledFeatures) : disabledFeatureNotice(disabledFeatures);
15771
15549
  return {
15772
15550
  content: [{ type: "text", text: notice ? `${notice}
15773
15551
 
@@ -15918,7 +15696,7 @@ ${item.text}` } : item)
15918
15696
  if (paramsWithResolvedCwd.dir) {
15919
15697
  try {
15920
15698
  const location = resolveAsyncRunLocation(paramsWithResolvedCwd, DIRS.async, DIRS.results);
15921
- const runId2 = location.resolvedId ?? targetRunId ?? path19.basename(location.asyncDir ?? paramsWithResolvedCwd.dir);
15699
+ const runId2 = location.resolvedId ?? targetRunId ?? path18.basename(location.asyncDir ?? paramsWithResolvedCwd.dir);
15922
15700
  const directoryStatus = location.asyncDir ? readStatus(location.asyncDir) : null;
15923
15701
  if (directoryStatus?.mode === "workflow") {
15924
15702
  return steerWorkflowRun({ state: deps2.state, runId: runId2, asyncDir: location.asyncDir, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
@@ -16051,7 +15829,7 @@ ${item.text}` } : item)
16051
15829
  if (!stopChild) return { content: [{ type: "text", text: `Workflow ${workflowRunId} child stop is unavailable in this extension runtime.` }], isError: true, details: { mode: "management", results: [] } };
16052
15830
  if (!stopChild(resolution.child.id, `Workflow child '${resolution.child.id}' stopped.`)) return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in workflow ${workflowRunId} is not available to stop.` }], isError: true, details: { mode: "management", results: [] } };
16053
15831
  try {
16054
- fs21.appendFileSync(path19.join(asyncJob.asyncDir, "events.jsonl"), `${JSON.stringify({
15832
+ fs20.appendFileSync(path18.join(asyncJob.asyncDir, "events.jsonl"), `${JSON.stringify({
16055
15833
  type: "subagent.child-status",
16056
15834
  version: 1,
16057
15835
  runId: workflowRunId,
@@ -16077,7 +15855,7 @@ ${item.text}` } : item)
16077
15855
  if (paramsWithResolvedCwd.dir) {
16078
15856
  try {
16079
15857
  const location = resolveAsyncRunLocation(paramsWithResolvedCwd, DIRS.async, DIRS.results);
16080
- const stopResult2 = stopAsyncRun(deps2.state, location.resolvedId ?? targetRunId ?? path19.basename(location.asyncDir ?? paramsWithResolvedCwd.dir), deps2.kill, location, paramsWithResolvedCwd.childId);
15858
+ const stopResult2 = stopAsyncRun(deps2.state, location.resolvedId ?? targetRunId ?? path18.basename(location.asyncDir ?? paramsWithResolvedCwd.dir), deps2.kill, location, paramsWithResolvedCwd.childId);
16081
15859
  return stopResult2 ?? { content: [{ type: "text", text: `No running or queued async run was found for '${targetRunId ?? paramsWithResolvedCwd.dir}'.` }], isError: true, details: { mode: "management", results: [] } };
16082
15860
  } catch (error) {
16083
15861
  const text = error instanceof Error ? error.message : String(error);
@@ -16102,21 +15880,20 @@ ${item.text}` } : item)
16102
15880
  );
16103
15881
  if (stopResult) return stopResult;
16104
15882
  return {
16105
- content: [{ type: "text", text: "No stoppable async run found in this session." }],
15883
+ content: [{ type: "text", text: `No stoppable async run found for '${targetRunId}'.` }],
16106
15884
  isError: true,
16107
15885
  details: { mode: "management", results: [] }
16108
15886
  };
16109
15887
  }
16110
15888
  if (action === "interrupt") {
16111
15889
  const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
15890
+ if (!targetRunId) return { content: [{ type: "text", text: "action='interrupt' requires id." }], isError: true, details: { mode: "management", results: [] } };
16112
15891
  let resolved;
16113
- if (targetRunId) {
16114
- try {
16115
- resolved = resolveSubagentRunId(targetRunId, omitUndefinedProperties({ state: deps2.state, nested: nestedResolutionScopeForExecutor(deps2) }));
16116
- } catch (error) {
16117
- const message = error instanceof Error ? error.message : String(error);
16118
- return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
16119
- }
15892
+ try {
15893
+ resolved = resolveSubagentRunId(targetRunId, omitUndefinedProperties({ state: deps2.state, nested: nestedResolutionScopeForExecutor(deps2) }));
15894
+ } catch (error) {
15895
+ const message = error instanceof Error ? error.message : String(error);
15896
+ return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
16120
15897
  }
16121
15898
  if (resolved?.kind === "nested") return interruptNestedRun(resolved);
16122
15899
  const foreground = getForegroundControl(deps2.state, resolved?.kind === "foreground" ? resolved.id : targetRunId);
@@ -16144,7 +15921,7 @@ ${item.text}` } : item)
16144
15921
  );
16145
15922
  if (asyncInterruptResult) return asyncInterruptResult;
16146
15923
  return {
16147
- content: [{ type: "text", text: "No interrupt-capable run found in this session." }],
15924
+ content: [{ type: "text", text: `No interrupt-capable run found for '${targetRunId}'.` }],
16148
15925
  isError: true,
16149
15926
  details: { mode: "management", results: [] }
16150
15927
  };
@@ -16160,7 +15937,7 @@ ${item.text}` } : item)
16160
15937
  ...ctx,
16161
15938
  cwd: requestCwd,
16162
15939
  config: deps2.config,
16163
- currentSessionId: deps2.state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? void 0,
15940
+ piSessionId: ctx.sessionManager.getSessionId() ?? void 0,
16164
15941
  discoverAgentsAll: deps2.discoverAgentsAll,
16165
15942
  runtimeAgentOwner: deps2.pi,
16166
15943
  onAgentsChanged: deps2.onAgentsChanged
@@ -16262,7 +16039,7 @@ ${item.text}` } : item)
16262
16039
  let prepareForkSessionForIndex = async () => {
16263
16040
  };
16264
16041
  const launchCapabilityCeiling = () => intersectSubagentCapabilityCeilings(
16265
- intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestSessionId)),
16042
+ intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestPiSessionId)),
16266
16043
  deps2.childRuntime?.capabilityCeiling
16267
16044
  );
16268
16045
  const assertLaunchableAgentsAllowedBeforeFork = () => {
@@ -16325,7 +16102,7 @@ ${item.text}` } : item)
16325
16102
  if (foregroundTimeout.error) return buildRequestedModeError(effectiveParams, foregroundTimeout.error);
16326
16103
  const controlConfig = resolveControlConfig(deps2.config.control, effectiveParams.control);
16327
16104
  const requestedWorkflowChildAsyncId = typeof effectiveParams.workflowChildAsyncId === "string" ? effectiveParams.workflowChildAsyncId.trim() : "";
16328
- const asyncRunId = requestedWorkflowChildAsyncId && path19.basename(requestedWorkflowChildAsyncId) === requestedWorkflowChildAsyncId ? requestedWorkflowChildAsyncId : randomUUID5();
16105
+ const asyncRunId = requestedWorkflowChildAsyncId && path18.basename(requestedWorkflowChildAsyncId) === requestedWorkflowChildAsyncId ? requestedWorkflowChildAsyncId : randomUUID5();
16329
16106
  const topLevelAsyncCapacityEligible = depth === 0 && !inheritedNestedRouteValue && !effectiveParams.workflowParentRunId;
16330
16107
  const topLevelAsync = effectiveAsync && topLevelAsyncCapacityEligible;
16331
16108
  let activeAsyncCapacity;
@@ -16337,7 +16114,7 @@ ${item.text}` } : item)
16337
16114
  limit: activeLimit,
16338
16115
  runId: asyncRunId,
16339
16116
  kind: "runner",
16340
- asyncDir: path19.join(DIRS.async, asyncRunId)
16117
+ asyncDir: path18.join(DIRS.async, asyncRunId)
16341
16118
  }, { liveWorkflowRunIds: new Set(deps2.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps2.config.capacity?.abandonedSlotReleaseAfterMs) });
16342
16119
  deps2.state.activeAsyncCapacity = getActiveAsyncCapacitySnapshot(requestSessionId, activeLimit, { liveWorkflowRunIds: new Set(deps2.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps2.config.capacity?.abandonedSlotReleaseAfterMs) });
16343
16120
  } catch (error) {
@@ -16373,13 +16150,13 @@ ${item.text}` } : item)
16373
16150
  let sessionRoot;
16374
16151
  sessionRunId = effectiveAsync ? asyncRunId : runId;
16375
16152
  if (effectiveParams.sessionDir) {
16376
- sessionRoot = path19.join(path19.resolve(deps2.expandTilde(effectiveParams.sessionDir)), sessionRunId);
16153
+ sessionRoot = path18.join(path18.resolve(deps2.expandTilde(effectiveParams.sessionDir)), sessionRunId);
16377
16154
  } else {
16378
- const baseSessionRoot = deps2.config.defaultSessionDir ? path19.resolve(deps2.expandTilde(deps2.config.defaultSessionDir)) : deps2.getSubagentSessionRoot(parentSessionFile);
16379
- sessionRoot = path19.join(baseSessionRoot, sessionRunId);
16155
+ const baseSessionRoot = deps2.config.defaultSessionDir ? path18.resolve(deps2.expandTilde(deps2.config.defaultSessionDir)) : deps2.getSubagentSessionRoot(parentSessionFile);
16156
+ sessionRoot = path18.join(baseSessionRoot, sessionRunId);
16380
16157
  }
16381
16158
  try {
16382
- fs21.mkdirSync(sessionRoot, { recursive: true });
16159
+ fs20.mkdirSync(sessionRoot, { recursive: true });
16383
16160
  } catch (error) {
16384
16161
  activeAsyncCapacity?.rollback();
16385
16162
  const message = error instanceof Error ? error.message : String(error);
@@ -16389,7 +16166,7 @@ ${item.text}` } : item)
16389
16166
  contextPolicy.contextSummary
16390
16167
  );
16391
16168
  }
16392
- const sessionDirForIndex = (idx) => path19.join(sessionRoot, `run-${idx ?? 0}`);
16169
+ const sessionDirForIndex = (idx) => path18.join(sessionRoot, `run-${idx ?? 0}`);
16393
16170
  const forkSessionFileForTask = (agentName, idx = 0) => {
16394
16171
  if (!shouldForkAgent(contextPolicy, agentName)) return void 0;
16395
16172
  return forkSessionFileForIndex(idx);
@@ -16399,8 +16176,8 @@ ${item.text}` } : item)
16399
16176
  await prepareForkSessionForIndex(idx);
16400
16177
  };
16401
16178
  const thinkingOverrideForTask = () => delegatedThinkingOverride;
16402
- const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path19.join(sessionDirForIndex(idx), "session.jsonl");
16403
- const childSessionFileForIndex = (idx) => path19.join(sessionDirForIndex(idx), "session.jsonl");
16179
+ const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path18.join(sessionDirForIndex(idx), "session.jsonl");
16180
+ const childSessionFileForIndex = (idx) => path18.join(sessionDirForIndex(idx), "session.jsonl");
16404
16181
  try {
16405
16182
  assertLaunchableAgentsAllowedBeforeFork();
16406
16183
  if (!(effectiveParams.clarify === true && ctx.hasUI) || deps2.config.forkContext?.mode === "pruned") {
@@ -16508,7 +16285,7 @@ ${item.text}` } : item)
16508
16285
  scopedModelIds: scopedModelIdsFromContext(ctx),
16509
16286
  parentSessionId: requestSessionId,
16510
16287
  parentPiSessionId: requestPiSessionId,
16511
- capabilityCeiling: intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestSessionId)),
16288
+ capabilityCeiling: intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestPiSessionId)),
16512
16289
  runFanoutBudget,
16513
16290
  topLevelAsyncCapacityEligible,
16514
16291
  activeAsyncCapacity,