@selesai/code 0.13.12 → 0.13.14

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 (203) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/extensions/pi-subagents/CHANGELOG.md +77 -1
  3. package/dist/extensions/pi-subagents/VISION.md +12 -1
  4. package/dist/extensions/pi-subagents/docs/agents.md +13 -6
  5. package/dist/extensions/pi-subagents/docs/configuration.md +35 -9
  6. package/dist/extensions/pi-subagents/docs/extension-api.md +1 -1
  7. package/dist/extensions/pi-subagents/docs/missions.md +1 -1
  8. package/dist/extensions/pi-subagents/docs/models.md +6 -6
  9. package/dist/extensions/pi-subagents/docs/observability.md +6 -3
  10. package/dist/extensions/pi-subagents/docs/tool-reference.md +3 -3
  11. package/dist/extensions/pi-subagents/docs/watchdog.md +92 -114
  12. package/dist/extensions/pi-subagents/docs/workflows.md +1 -1
  13. package/dist/extensions/pi-subagents/install.mjs +1 -2
  14. package/dist/extensions/pi-subagents/package.json +1 -1
  15. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  16. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +6 -6
  17. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  18. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
  19. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +4 -4
  20. package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +1 -1
  21. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -4
  22. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +3 -0
  23. package/dist/extensions/pi-subagents/src/agents/agents.ts +120 -124
  24. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +5 -1
  25. package/dist/extensions/pi-subagents/src/api/preflight.ts +4 -0
  26. package/dist/extensions/pi-subagents/src/api/shared-types.ts +3 -0
  27. package/dist/extensions/pi-subagents/src/extension/config.ts +20 -0
  28. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +1 -0
  29. package/dist/extensions/pi-subagents/src/extension/schemas.ts +6 -2
  30. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +1 -1
  31. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +19 -13
  32. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +26 -8
  33. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +103 -23
  34. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +6 -2
  35. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -2
  36. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +54 -3
  37. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +16 -0
  38. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +22 -2
  39. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +63 -6
  40. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -1
  41. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +69 -12
  42. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +13 -0
  43. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +3 -1
  44. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +21 -8
  45. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +59 -6
  46. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +95 -18
  47. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +11 -43
  48. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -0
  49. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  50. package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +24 -3
  51. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +4 -0
  52. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -6
  53. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +1 -0
  54. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +33 -18
  55. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +73 -37
  56. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +33 -6
  57. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +4 -2
  58. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +20 -3
  59. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +21 -7
  60. package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +1 -1
  61. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +467 -63
  62. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +3 -1
  63. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +0 -12
  64. package/dist/extensions/pi-subagents/src/shared/fork-session-cwd.ts +27 -0
  65. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +3 -0
  66. package/dist/extensions/pi-subagents/src/shared/types.ts +42 -4
  67. package/dist/extensions/pi-subagents/src/shared/utils.ts +18 -7
  68. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +1 -1
  69. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +26 -12
  70. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +61 -2
  71. package/dist/extensions/pi-subagents/src/tui/fleet.ts +12 -7
  72. package/dist/extensions/pi-subagents/src/tui/render.ts +227 -14
  73. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +56 -34
  74. package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +77 -0
  75. package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +5 -3
  76. package/dist/extensions/pi-subagents/src/watchdog/guidance.ts +20 -0
  77. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +16 -13
  78. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +10 -9
  79. package/dist/extensions/pi-subagents/src/watchdog/render.ts +4 -5
  80. package/dist/extensions/pi-subagents/src/watchdog/review.ts +15 -4
  81. package/dist/extensions/pi-subagents/src/watchdog/rules.ts +70 -0
  82. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +75 -92
  83. package/dist/extensions/pi-subagents/src/watchdog/scope.ts +2 -1
  84. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +48 -104
  85. package/dist/extensions/pi-subagents/src/watchdog/types.ts +18 -32
  86. package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +0 -1
  87. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -2
  88. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +439 -0
  89. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +28 -1
  90. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +335 -21
  91. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +4 -1
  92. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +1 -1
  93. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +22 -18
  94. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +0 -1
  95. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +21 -18
  96. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +307 -22
  97. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -0
  98. package/dist/extensions/pi-subagents/test/support/helpers.ts +25 -0
  99. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +15 -4
  100. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +17 -2
  101. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +96 -15
  102. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +53 -5
  103. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +20 -0
  104. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +221 -8
  105. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +45 -24
  106. package/dist/extensions/pi-subagents/test/unit/agent-scan-dirs.test.ts +133 -0
  107. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +28 -2
  108. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +1 -1
  109. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +2 -0
  110. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +4 -1
  111. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +18 -4
  112. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +16 -0
  113. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +38 -0
  114. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +2 -2
  115. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +21 -0
  116. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +19 -6
  117. package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +26 -0
  118. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +22 -1
  119. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +2 -6
  120. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +66 -1
  121. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +1 -1
  122. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +116 -10
  123. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +136 -18
  124. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +20 -0
  125. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +22 -0
  126. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +1 -0
  127. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +8 -0
  128. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +127 -48
  129. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +68 -0
  130. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +17 -0
  131. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +88 -0
  132. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +4 -2
  133. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +9 -9
  134. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -2
  135. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +9 -3
  136. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +22 -9
  137. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +91 -8
  138. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +27 -0
  139. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +50 -0
  140. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +0 -1
  141. package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +2 -2
  142. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +34 -0
  143. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -2
  144. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +73 -13
  145. package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +79 -0
  146. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +2 -4
  147. package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -8
  148. package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +48 -3
  149. package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +37 -0
  150. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +36 -118
  151. package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +1 -1
  152. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +37 -14
  153. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +45 -26
  154. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +223 -0
  155. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +50 -1
  156. package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +22 -0
  157. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +136 -4
  158. package/dist/extensions/pi-zentui/README.md +19 -5
  159. package/dist/extensions/pi-zentui/docs/configuration.md +37 -9
  160. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +29 -0
  161. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +31 -2
  162. package/dist/extensions/pi-zentui/extensions/zentui/prototype-patch-registry.ts +55 -11
  163. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +115 -3
  164. package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +119 -2
  165. package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +1768 -0
  166. package/dist/extensions/pi-zentui/extensions/zentui/thinking-status.ts +69 -0
  167. package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +155 -0
  168. package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +2 -1
  169. package/dist/extensions/pi-zentui/extensions/zentui/user-message-osc.ts +16 -2
  170. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
  171. package/dist/extensions/pi-zentui/test/config-load-lifecycle.test.ts +124 -0
  172. package/dist/extensions/pi-zentui/test/config.test.ts +82 -2
  173. package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +19 -4
  174. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +58 -9
  175. package/dist/extensions/pi-zentui/test/package-contents.mjs +33 -0
  176. package/dist/extensions/pi-zentui/test/prototype-patch-registry.test.ts +131 -0
  177. package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +4 -4
  178. package/dist/extensions/pi-zentui/test/settings-command.test.ts +289 -7
  179. package/dist/extensions/pi-zentui/test/settings-previews.test.ts +106 -0
  180. package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +51 -0
  181. package/dist/extensions/pi-zentui/test/thinking-experimental-loader-diagnostics.mjs +54 -0
  182. package/dist/extensions/pi-zentui/test/thinking-experimental-missing-export.test.ts +44 -0
  183. package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +297 -0
  184. package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +2329 -0
  185. package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +1668 -0
  186. package/dist/extensions/pi-zentui/test/thinking-status.test.ts +85 -0
  187. package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +122 -0
  188. package/dist/extensions/pi-zentui/test/user-message-osc.test.ts +58 -0
  189. package/dist/skills/brandkit/SKILL.md +0 -2
  190. package/dist/skills/{industrial-brutalist-ui → brutalist}/SKILL.md +1 -3
  191. package/dist/skills/gpt-taste/SKILL.md +0 -2
  192. package/dist/skills/image-to-code/SKILL.md +0 -2
  193. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -2
  194. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -2
  195. package/dist/skills/{minimalist-ui → minimalist}/SKILL.md +1 -3
  196. package/dist/skills/{full-output-enforcement → output}/SKILL.md +1 -3
  197. package/dist/skills/{redesign-existing-projects → redesign}/SKILL.md +1 -3
  198. package/dist/skills/{high-end-visual-design → soft}/SKILL.md +1 -3
  199. package/dist/skills/stitch/DESIGN.md +121 -0
  200. package/dist/skills/{stitch-design-taste → stitch}/SKILL.md +1 -3
  201. package/dist/skills/{design-taste-frontend → taste}/SKILL.md +1 -3
  202. package/dist/skills/{design-taste-frontend-v1 → taste-v1}/SKILL.md +2 -4
  203. package/package.json +1 -1
@@ -13,7 +13,7 @@ import { updateActiveRunIndex } from "./active-run-index.ts";
13
13
  import { createChildTranscriptWriter, type ChildTranscriptWriter } from "../../shared/child-transcript.ts";
14
14
  import { closeSteerInbox, consumeInterruptRequest, consumeSteerRequests, deliverInterruptRequest, deliverStopRequest, deliverTimeoutRequest, enqueueStepSteer, steerAcksDir, steerCapabilityPath, stepSteerInboxDir, watchAsyncControlInbox, type SteerAck, type SteerCapability, type SteerRequest, type StopRequest } from "./control-channel.ts";
15
15
  import { appendJsonl as appendRawJsonl, formatOutputArtifactContent, getArtifactPaths, writeArtifact, writeMetadata } from "../../shared/artifacts.ts";
16
- import { PI_CODING_AGENT_PACKAGE, getPiSpawnCommand, resolveInstalledPiPackageRoot } from "../shared/pi-spawn.ts";
16
+ import { SELESAI_CODING_AGENT_PACKAGE, getPiSpawnCommand, resolveInstalledPiPackageRoot } from "../shared/pi-spawn.ts";
17
17
  import { preflightLaunchCwd } from "../shared/launch-cwd.ts";
18
18
  import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, injectSingleOutputInstruction, resolveSingleOutput, type SingleOutputSnapshot } from "../shared/single-output.ts";
19
19
  import {
@@ -77,9 +77,10 @@ import {
77
77
  } from "../shared/parallel-utils.ts";
78
78
  import { applyThinkingSuffix, buildPiArgs, cleanupTempDir, deriveForkPromptCacheKey, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan, type SubagentTaskDelivery } from "../shared/pi-args.ts";
79
79
  import { deriveChildSessionName } from "../../shared/child-session-name.ts";
80
+ import { alignForkedSessionCwd } from "../../shared/fork-session-cwd.ts";
80
81
  import { readRuntimeAcknowledgedExtensions } from "../shared/runtime-acknowledged-extensions.ts";
81
82
  import { outputEntryFromAsyncResult, resolveOutputReferences } from "../shared/chain-outputs.ts";
82
- import { createStructuredOutputRuntime, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
83
+ import { clearStructuredOutputCaptures, createStructuredOutputRuntime, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
83
84
  import { formatMidToolExitError, formatProcessSignalError, isOrdinaryToolForMidToolExit, isUnexplainedProcessSignal } from "../shared/process-signal.ts";
84
85
  import { readChildToolDiagnosticError } from "../shared/tool-availability.ts";
85
86
  import { buildTimeoutRecoverySummary, collectTrackedMutationEvidence, snapshotTrackedMutations } from "../shared/mutation-evidence.ts";
@@ -123,6 +124,7 @@ import {
123
124
  findWorktreeTaskCwdConflict,
124
125
  formatWorktreeDiffSummary,
125
126
  formatWorktreeTaskCwdConflict,
127
+ WORKTREE_AGENT_CWD_PLACEHOLDER,
126
128
  type WorktreeSetup,
127
129
  } from "../shared/worktree.ts";
128
130
  import { findModelInfo, resolveEffectiveThinking } from "../../shared/model-info.ts";
@@ -130,7 +132,7 @@ import { assertThinkingWithinCeiling, decodeThinkingCeiling, SUBAGENT_THINKING_C
130
132
  import { launchBindingDigest } from "../../shared/launch-contract.ts";
131
133
  import { writeInitialProgressFile } from "../../shared/settings.ts";
132
134
  import { resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.ts";
133
- import { acceptanceFailureMessage, aggregateAcceptanceReport, buildSkippedAcceptanceLedger, evaluateAcceptance, formatAcceptancePrompt, resolveEffectiveAcceptance, stripAcceptanceReport } from "../shared/acceptance.ts";
135
+ import { acceptanceFailureMessage, aggregateAcceptanceReport, buildSkippedAcceptanceLedger, evaluateAcceptance, formatAcceptancePrompt, resolveAcceptanceReportMode, resolveEffectiveAcceptance, stripAcceptanceReport } from "../shared/acceptance.ts";
134
136
  import { attachContractProjections, isAgentContractV1 } from "../shared/agent-contract.ts";
135
137
  import { waitForImportedAsyncRoot } from "./chain-root-attachment.ts";
136
138
  import { normalizeExtensionBindings } from "../shared/extension-bindings.ts";
@@ -151,6 +153,7 @@ import { decodeSubagentCapabilityCeiling, SUBAGENT_CAPABILITY_CEILING_ENV, type
151
153
  import {
152
154
  CHILD_WATCHDOG_CONFIG_ENV,
153
155
  acceptChildWatchdogEvent,
156
+ applyChildWatchdogMessage,
154
157
  childWatchdogIsActive,
155
158
  decodeChildWatchdogConfig,
156
159
  isChildWatchdogStatusEvent,
@@ -181,6 +184,8 @@ interface SubagentRunConfig {
181
184
  worktreeSetupHook?: string;
182
185
  worktreeSetupHookTimeoutMs?: number;
183
186
  worktreeBaseDir?: string;
187
+ worktreeProvider?: import("../../shared/types.ts").WorktreeProvider;
188
+ worktreeBranchPrefix?: string;
184
189
  controlConfig?: ResolvedControlConfig;
185
190
  controlIntercomTarget?: string;
186
191
  childIntercomTargets?: Array<string | undefined>;
@@ -241,6 +246,7 @@ interface StepResult {
241
246
  sessionFile?: string;
242
247
  intercomTarget?: string;
243
248
  model?: string;
249
+ thinking?: string;
244
250
  attemptedModels?: string[];
245
251
  modelAttempts?: ModelAttempt[];
246
252
  /** True when the dispatch failed because the input exceeded the model's context window. */
@@ -846,6 +852,10 @@ function runPiStreaming(
846
852
  const text = extractTextFromContent(event.message.content);
847
853
  if (text) writeOutputText(text);
848
854
 
855
+ if (childWatchdogConfig && event.type === "message_end") {
856
+ const next = applyChildWatchdogMessage(childWatchdogState, event.message);
857
+ if (next) updateChildWatchdogState(next);
858
+ }
849
859
  if (event.type !== "message_end" || event.message.role !== "assistant") return;
850
860
  const hasToolCall = assistantStartsToolCall(event.message);
851
861
  if (event.message.model) {
@@ -1062,7 +1072,6 @@ function runPiStreaming(
1062
1072
  phase: "stale",
1063
1073
  seq: (childWatchdogState?.seq ?? 0) + 1,
1064
1074
  lastUpdate: Date.now(),
1065
- followUpPending: false,
1066
1075
  reason: "child watchdog tail timeout",
1067
1076
  timedOut: true,
1068
1077
  });
@@ -1164,7 +1173,7 @@ function runPiStreaming(
1164
1173
  function resolvePiPackageRootFallback(): string {
1165
1174
  const root = resolveInstalledPiPackageRoot();
1166
1175
  if (root) return root;
1167
- throw new Error(`Could not resolve ${PI_CODING_AGENT_PACKAGE} package root`);
1176
+ throw new Error(`Could not resolve ${SELESAI_CODING_AGENT_PACKAGE} package root`);
1168
1177
  }
1169
1178
 
1170
1179
  async function exportSessionHtml(sessionFile: string, outputDir: string, piPackageRoot?: string): Promise<string> {
@@ -1394,7 +1403,7 @@ async function runSingleStepInner(
1394
1403
  }
1395
1404
 
1396
1405
  const effectiveStructuredOutput = step.structuredOutput ?? (step.structuredOutputSchema
1397
- ? createStructuredOutputRuntime(step.structuredOutputSchema, path.join(path.dirname(ctx.outputFile), "structured-output"))
1406
+ ? createStructuredOutputRuntime(step.structuredOutputSchema, path.join(path.dirname(ctx.outputFile), "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(step.acceptanceInput) })
1398
1407
  : undefined);
1399
1408
  const placeholderRegex = new RegExp(ctx.placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
1400
1409
  let task = step.task.replace(placeholderRegex, () => ctx.previousOutput);
@@ -1404,6 +1413,7 @@ async function runSingleStepInner(
1404
1413
  if (!step.runner) {
1405
1414
  resolvedTaskToolPlan = resolvePiLaunchToolPlan(omitUndefinedProperties({
1406
1415
  tools: step.tools,
1416
+ excludeTools: step.excludeTools,
1407
1417
  allowNestedSubagents: step.allowNestedSubagents,
1408
1418
  extensions: step.extensions,
1409
1419
  subagentOnlyExtensions: step.subagentOnlyExtensions,
@@ -1611,6 +1621,9 @@ async function runSingleStepInner(
1611
1621
  const effectiveCwd = step.cwd ?? ctx.cwd;
1612
1622
  const cwdError = preflightLaunchCwd(step.requestedCwd ?? effectiveCwd, effectiveCwd);
1613
1623
  if (cwdError) return { agent: step.agent, output: cwdError, error: cwdError, exitCode: 1, context: step.context };
1624
+ if (step.context === "fork" && step.sessionFile && fs.existsSync(step.sessionFile)) {
1625
+ alignForkedSessionCwd(step.sessionFile, effectiveCwd);
1626
+ }
1614
1627
 
1615
1628
  const candidates = step.modelCandidates !== undefined
1616
1629
  ? step.modelCandidates.length > 0 ? step.modelCandidates : [undefined]
@@ -1665,10 +1678,9 @@ async function runSingleStepInner(
1665
1678
  }));
1666
1679
  const outputSnapshot = captureSingleOutputSnapshot(step.outputPath);
1667
1680
  if (effectiveStructuredOutput) {
1668
- try {
1669
- if (fs.existsSync(effectiveStructuredOutput.outputPath)) fs.unlinkSync(effectiveStructuredOutput.outputPath);
1670
- } catch {
1671
- // Missing/stale structured-output files are handled after the child exits.
1681
+ const cleanupError = clearStructuredOutputCaptures(effectiveStructuredOutput);
1682
+ if (cleanupError) {
1683
+ return omitUndefinedProperties({ agent: step.agent, output: cleanupError, error: cleanupError, exitCode: 1, context: step.context });
1672
1684
  }
1673
1685
  }
1674
1686
  const watchdogConfig = resolveWatchdogConfig(step.cwd ?? ctx.cwd);
@@ -1696,6 +1708,7 @@ async function runSingleStepInner(
1696
1708
  inheritSkills: step.inheritSkills,
1697
1709
  requireReadTool: Boolean(step.skills?.length),
1698
1710
  tools: step.tools,
1711
+ excludeTools: step.excludeTools,
1699
1712
  allowNestedSubagents: step.allowNestedSubagents,
1700
1713
  extensions: step.extensions,
1701
1714
  subagentOnlyExtensions: step.subagentOnlyExtensions,
@@ -1745,6 +1758,7 @@ async function runSingleStepInner(
1745
1758
  if (step.definitionDigest) {
1746
1759
  const toolPlan = resolvedTaskToolPlan ?? resolvePiLaunchToolPlan(omitUndefinedProperties({
1747
1760
  tools: step.tools,
1761
+ excludeTools: step.excludeTools,
1748
1762
  allowNestedSubagents: step.allowNestedSubagents,
1749
1763
  extensions: step.extensions,
1750
1764
  subagentOnlyExtensions: step.subagentOnlyExtensions,
@@ -1777,6 +1791,7 @@ async function runSingleStepInner(
1777
1791
  inheritSkills: step.inheritSkills,
1778
1792
  skills: step.skills,
1779
1793
  tools: toolPlan.effectiveToolAllowlist,
1794
+ ...(toolPlan.excludeTools.length > 0 ? { excludeTools: toolPlan.excludeTools } : {}),
1780
1795
  extensions: toolPlan.extensionArgs,
1781
1796
  mcpDirectTools: toolPlan.effectiveMcpTools,
1782
1797
  ...(step.outputPath ? { outputPath: step.outputPath } : {}),
@@ -2141,6 +2156,7 @@ async function runSingleStepInner(
2141
2156
  reportOptional: isAgentContractV1(step.agentContract),
2142
2157
  artifactsDir: ctx.artifactsDir,
2143
2158
  runId: ctx.id,
2159
+ watchdog: finalResult?.watchdog,
2144
2160
  }))
2145
2161
  : undefined;
2146
2162
  const stoppedAfterAcceptance = finalResult?.stopped === true || ctx.stopSignal?.aborted === true;
@@ -2218,6 +2234,7 @@ async function runSingleStepInner(
2218
2234
  sessionFile: step.sessionFile,
2219
2235
  intercomTarget: ctx.childIntercomTarget,
2220
2236
  model: finalResult?.model,
2237
+ thinking: resolveEffectiveThinking(finalResult?.model, step.thinking),
2221
2238
  attemptedModels: attemptedModels.length > 0 ? attemptedModels : undefined,
2222
2239
  modelAttempts,
2223
2240
  contextOverflow: contextOverflow || undefined,
@@ -2316,6 +2333,8 @@ function requiredStatusStep(statusPayload: RunnerStatusPayload, index: number):
2316
2333
  function setStatusWorktreeReference(statusStep: RunnerStatusStep, worktree: WorktreeSetup["worktrees"][number]): void {
2317
2334
  statusStep.worktreePath = worktree.path;
2318
2335
  statusStep.branch = worktree.branch;
2336
+ if (worktree.provider) statusStep.provider = worktree.provider;
2337
+ if (worktree.naming) statusStep.naming = worktree.naming;
2319
2338
  }
2320
2339
 
2321
2340
  function markParallelGroupSetupFailure(input: {
@@ -2396,6 +2415,18 @@ function markParallelGroupRunning(input: {
2396
2415
  }));
2397
2416
  }
2398
2417
 
2418
+ function bindWorktreeCwd(step: SubagentStep, worktreeCwd: string): SubagentStep {
2419
+ const bind = <T extends string | null | undefined>(value: T): T => value === null || value === undefined ? value : value.replaceAll(WORKTREE_AGENT_CWD_PLACEHOLDER, worktreeCwd) as T;
2420
+ return {
2421
+ ...step,
2422
+ task: bind(step.task) ?? step.task,
2423
+ ...(step.systemPrompt !== undefined ? { systemPrompt: bind(step.systemPrompt) } : {}),
2424
+ ...(step.outputPath !== undefined ? { outputPath: bind(step.outputPath) } : {}),
2425
+ ...(step.launchBindingTask !== undefined ? { launchBindingTask: bind(step.launchBindingTask) } : {}),
2426
+ ...(step.requestedCwd !== undefined ? { requestedCwd: bind(step.requestedCwd) } : {}),
2427
+ };
2428
+ }
2429
+
2399
2430
  function prepareParallelTaskRun(
2400
2431
  task: SubagentStep,
2401
2432
  cwd: string,
@@ -2404,8 +2435,9 @@ function prepareParallelTaskRun(
2404
2435
  ): { taskForRun: SubagentStep; taskCwd: string } {
2405
2436
  if (!worktreeSetup) return { taskForRun: task, taskCwd: cwd };
2406
2437
  const { cwd: _taskCwd, ...taskForRun } = task;
2438
+ const boundTask = bindWorktreeCwd(taskForRun, worktreeSetup.worktrees[taskIndex]!.agentCwd);
2407
2439
  return {
2408
- taskForRun,
2440
+ taskForRun: boundTask,
2409
2441
  taskCwd: worktreeSetup.worktrees[taskIndex]!.agentCwd,
2410
2442
  };
2411
2443
  }
@@ -2864,6 +2896,7 @@ async function runSubagent(
2864
2896
  success: statusResultSuccess(state, step),
2865
2897
  sessionFile: step.sessionFile,
2866
2898
  model: step.model,
2899
+ thinking: step.thinking,
2867
2900
  attemptedModels: step.attemptedModels,
2868
2901
  modelAttempts: step.modelAttempts,
2869
2902
  usage: usageFromAttempts(step.modelAttempts),
@@ -3543,6 +3576,15 @@ async function runSubagent(
3543
3576
  writeStatusPayload(false);
3544
3577
  return;
3545
3578
  }
3579
+ if (event.type === "message_end") {
3580
+ const next = applyChildWatchdogMessage(step.watchdog, event.message, now);
3581
+ if (next) step.watchdog = next;
3582
+ if (next && (event.message as { role?: unknown } | undefined)?.role === "custom") {
3583
+ statusPayload.lastUpdate = now;
3584
+ writeStatusPayload(false);
3585
+ return;
3586
+ }
3587
+ }
3546
3588
  if (event.type === "tool_execution_start" && event.toolName) {
3547
3589
  const mutates = isMutatingTool(event.toolName, event.args, flatSteps[flatIndex]?.mutationTools);
3548
3590
  const currentPath = resolveCurrentPath(event.toolName, event.args);
@@ -3687,6 +3729,7 @@ async function runSubagent(
3687
3729
  config: controlConfig,
3688
3730
  startedAt: step.startedAt ?? overallStartTime,
3689
3731
  lastActivityAt,
3732
+ turnCount: step.turnCount,
3690
3733
  currentTool: step.currentTool,
3691
3734
  thinking: step.thinking,
3692
3735
  now,
@@ -4308,6 +4351,7 @@ async function runSubagent(
4308
4351
  sessionFile: pr.sessionFile,
4309
4352
  intercomTarget: pr.intercomTarget,
4310
4353
  model: pr.model,
4354
+ thinking: pr.thinking,
4311
4355
  attemptedModels: pr.attemptedModels,
4312
4356
  modelAttempts: pr.modelAttempts,
4313
4357
  contextOverflow: pr.contextOverflow,
@@ -4452,6 +4496,10 @@ async function runSubagent(
4452
4496
  try {
4453
4497
  worktreeSetup = createWorktrees(cwd, `${id}-s${stepIndex}`, group.parallel.length, omitUndefinedProperties({
4454
4498
  agents: group.parallel.map((task) => task.agent),
4499
+ labels: group.parallel.map((task) => task.lane?.key ?? config.workflowKey ?? task.outputName ?? task.label),
4500
+ tasks: group.parallel.map((task) => task.task),
4501
+ provider: config.worktreeProvider,
4502
+ branchPrefix: config.worktreeBranchPrefix,
4455
4503
  setupHook: config.worktreeSetupHook
4456
4504
  ? omitUndefinedProperties({ hookPath: config.worktreeSetupHook, timeoutMs: config.worktreeSetupHookTimeoutMs })
4457
4505
  : undefined,
@@ -4749,6 +4797,7 @@ async function runSubagent(
4749
4797
  sessionFile: pr.sessionFile,
4750
4798
  intercomTarget: pr.intercomTarget,
4751
4799
  model: pr.model,
4800
+ thinking: pr.thinking,
4752
4801
  attemptedModels: pr.attemptedModels,
4753
4802
  modelAttempts: pr.modelAttempts,
4754
4803
  contextOverflow: pr.contextOverflow,
@@ -4884,6 +4933,10 @@ async function runSubagent(
4884
4933
  try {
4885
4934
  singleWorktreeSetup = createWorktrees(cwd, `${id}-s${stepIndex}`, 1, omitUndefinedProperties({
4886
4935
  agents: [seqStep.agent],
4936
+ labels: [seqStep.lane?.key ?? config.workflowKey ?? seqStep.outputName ?? seqStep.label],
4937
+ tasks: [seqStep.task],
4938
+ provider: config.worktreeProvider,
4939
+ branchPrefix: config.worktreeBranchPrefix,
4887
4940
  setupHook: config.worktreeSetupHook
4888
4941
  ? omitUndefinedProperties({ hookPath: config.worktreeSetupHook, timeoutMs: config.worktreeSetupHookTimeoutMs })
4889
4942
  : undefined,
@@ -4938,7 +4991,9 @@ async function runSubagent(
4938
4991
  }));
4939
4992
 
4940
4993
  flushPendingStepSteers(flatIndex);
4941
- const executionStep = singleWorktreeSetup ? { ...seqStep, cwd: singleCwd } : seqStep;
4994
+ const executionStep = singleWorktreeSetup
4995
+ ? bindWorktreeCwd({ ...seqStep, cwd: singleCwd }, singleCwd)
4996
+ : seqStep;
4942
4997
  let singleResult: Awaited<ReturnType<typeof runSingleStepWithTimeout>>;
4943
4998
  try {
4944
4999
  singleResult = await runSingleStepWithTimeout(executionStep, compactOptional<SingleStepContext>({
@@ -5002,6 +5057,7 @@ async function runSubagent(
5002
5057
  sessionFile: singleResult.sessionFile,
5003
5058
  intercomTarget: singleResult.intercomTarget,
5004
5059
  model: singleResult.model,
5060
+ thinking: singleResult.thinking,
5005
5061
  attemptedModels: singleResult.attemptedModels,
5006
5062
  modelAttempts: singleResult.modelAttempts,
5007
5063
  contextOverflow: singleResult.contextOverflow,
@@ -5365,6 +5421,7 @@ async function runSubagent(
5365
5421
  sessionFile: r.sessionFile,
5366
5422
  intercomTarget: r.intercomTarget,
5367
5423
  model: r.model,
5424
+ thinking: r.thinking,
5368
5425
  attemptedModels: r.attemptedModels,
5369
5426
  modelAttempts: r.modelAttempts,
5370
5427
  contextOverflow: r.contextOverflow,
@@ -42,6 +42,15 @@ function errorMessage(error: unknown): string {
42
42
  return error instanceof Error ? error.message : String(error);
43
43
  }
44
44
 
45
+ const STRUCTURED_OUTPUT_INLINE_LIMIT_BYTES = 4 * 1024;
46
+
47
+ export function projectStructuredOutput(value: unknown): unknown {
48
+ if (value === undefined) return undefined;
49
+ const serialized = JSON.stringify(value);
50
+ if (typeof serialized !== "string") throw new Error("Structured output must be JSON-serializable");
51
+ return Buffer.byteLength(serialized, "utf8") <= STRUCTURED_OUTPUT_INLINE_LIMIT_BYTES ? JSON.parse(serialized) : undefined;
52
+ }
53
+
45
54
  /**
46
55
  * Project a terminal result payload into the slim shape that is safe to surface in
47
56
  * tool_result details: run identity, per-child outcome, and the artifact trail.
@@ -65,6 +74,8 @@ export function toWaitCompletion(data: Record<string, unknown>, runId: string):
65
74
  const sessionFile = asNonEmptyString(child.sessionFile);
66
75
  const error = asNonEmptyString(child.error);
67
76
  const model = asNonEmptyString(child.model);
77
+ const structuredOutput = projectStructuredOutput(child.structuredOutput);
78
+ const structuredOutputPath = asNonEmptyString(child.structuredOutputPath);
68
79
  const contextOverflow = child.contextOverflow === true;
69
80
  const timeoutRecovery = projectTimeoutRecovery(child.timeoutRecovery);
70
81
  return [{
@@ -74,6 +85,8 @@ export function toWaitCompletion(data: Record<string, unknown>, runId: string):
74
85
  ...(sessionFile ? { sessionFile } : {}),
75
86
  ...(typeof child.success === "boolean" ? { success: child.success } : {}),
76
87
  ...(outputState ? { outputState } : {}),
88
+ ...(structuredOutput !== undefined ? { structuredOutput } : {}),
89
+ ...(structuredOutputPath ? { structuredOutputPath } : {}),
77
90
  ...(error ? { error } : {}),
78
91
  ...(model ? { model } : {}),
79
92
  ...(contextOverflow ? { contextOverflow: true } : {}),
@@ -24,6 +24,7 @@ Ordinary async subagent runs already notify this session natively when they comp
24
24
  • { timeoutMs: 600000 } — stop waiting after N ms; active work keeps running. Omitted values use waitTool.defaultTimeoutMs, then 30 minutes. Window expiry returns a non-error window_elapsed result with active work identities.
25
25
 
26
26
  Non-blocking subscriptions are visible in subagent status and differ from disabling waitTool: waitTool.enabled=false returns immediately without registering any future wake. Provider jobs are session-scoped and identified exactly, so replacing one job with another cannot hide a completion. Provider extensions must be explicitly loaded in this process. In a child agent, keep \`bg_wait\` (or the deprecated \`subagent_wait\` compatibility alias) in the child tool allowlist and load each provider through the agent's extensions or subagentOnlyExtensions; this tool never loads providers or grants tools itself.${enabled ? "" : "\n\nConfigured behavior: bg_wait and its subagent_wait compatibility alias are disabled by config.waitTool or SELESAI_SUBAGENT_WAIT_TOOL_ENABLED and return immediately without blocking."}`;
27
+
27
28
  const execute: ToolDefinition<typeof SubagentWaitParams, Details>["execute"] = async (_id, params, signal, onUpdate, ctx) => finalizeToolResult(await waitForSubagents(params, signal, {
28
29
  state,
29
30
  events: pi.events,
@@ -46,4 +47,5 @@ Non-blocking subscriptions are visible in subagent status and differ from disabl
46
47
  label: "Subagent Wait (deprecated)",
47
48
  description: "Deprecated compatibility alias for `bg_wait`. Use `bg_wait` for background, provider, or detached work without a native completion notification. It has the same parameters and behavior.",
48
49
  });
49
- }
50
+ }
51
+
@@ -3,12 +3,12 @@
3
3
  */
4
4
 
5
5
  import { spawn } from "node:child_process";
6
- import { existsSync, unlinkSync } from "node:fs";
6
+ import { existsSync } from "node:fs";
7
7
  import * as path from "node:path";
8
8
  import type { Message } from "@earendil-works/pi-ai";
9
9
  import { discoverAgents, formatUnknownAgentError, unknownAgentDiagnosticContext, type AgentConfig } from "../../agents/agents.ts";
10
10
  import { appendAgentRefinementOverlay } from "../../agents/agent-refinements.ts";
11
- import { alignForkedSessionCwd } from "../../shared/fork-context.ts";
11
+ import { alignForkedSessionCwd } from "../../shared/fork-session-cwd.ts";
12
12
  import {
13
13
  ensureArtifactsDir,
14
14
  formatOutputArtifactContent,
@@ -73,7 +73,7 @@ import { readRuntimeAcknowledgedExtensions } from "../shared/runtime-acknowledge
73
73
  import { assertAgentAllowedByCapabilityCeiling, decodeSubagentCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling, SUBAGENT_CAPABILITY_CEILING_ENV } from "../shared/capability-ceiling.ts";
74
74
  import { resolveEffectiveThinking } from "../../shared/model-info.ts";
75
75
  import { assertThinkingWithinCeiling, decodeThinkingCeiling, intersectThinkingCeilings, SUBAGENT_THINKING_CEILING_ENV } from "../../shared/thinking-ceiling.ts";
76
- import { MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
76
+ import { clearStructuredOutputCaptures, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
77
77
  import { formatMidToolExitError, formatProcessSignalError, isOrdinaryToolForMidToolExit, isUnexplainedProcessSignal } from "../shared/process-signal.ts";
78
78
  import { readChildToolDiagnosticError } from "../shared/tool-availability.ts";
79
79
  import { buildTimeoutRecoverySummary, collectTrackedMutationEvidence, snapshotTrackedMutations } from "../shared/mutation-evidence.ts";
@@ -115,6 +115,7 @@ import { consumeWorkflowChildPermit } from "../../shared/workflow-child-permit.t
115
115
  import { createBoundedByteTail, createBoundedLineReader, formatProtocolOutputLimit, MAX_CHILD_STDERR_BYTES, PI_AGGREGATE_EVENT_PROJECTOR, projectChildLifecycle, type ChildLifecycleAction, type ChildLifecycleState, type ProtocolOutputLimit } from "../shared/child-protocol.ts";
116
116
  import {
117
117
  acceptChildWatchdogEvent,
118
+ applyChildWatchdogMessage,
118
119
  childWatchdogIsActive,
119
120
  isChildWatchdogStatusEvent,
120
121
  resolveChildWatchdogConfig,
@@ -411,6 +412,7 @@ async function runSingleAttempt(
411
412
  inheritSkills: agent.inheritSkills,
412
413
  requireReadTool: Boolean(shared.resolvedSkillNames?.length),
413
414
  tools: agent.tools,
415
+ excludeTools: agent.excludeTools,
414
416
  allowNestedSubagents: agent.allowNestedSubagents,
415
417
  extensions: agent.extensions,
416
418
  subagentOnlyExtensions: agent.subagentOnlyExtensions,
@@ -464,6 +466,7 @@ async function runSingleAttempt(
464
466
  cwd: options.cwd ?? runtimeCwd,
465
467
  requireReadTool: Boolean(shared.resolvedSkillNames?.length),
466
468
  structuredOutput: Boolean(options.structuredOutput),
469
+ excludeTools: agent.excludeTools,
467
470
  fast: options.fast ?? agent.fast,
468
471
  model: modelArg,
469
472
  modelCandidates: shared.modelCandidates,
@@ -520,6 +523,7 @@ async function runSingleAttempt(
520
523
  inheritSkills: agent.inheritSkills,
521
524
  skills: shared.resolvedSkillNames ?? [],
522
525
  tools: toolPlan.effectiveToolAllowlist,
526
+ ...(toolPlan.excludeTools.length > 0 ? { excludeTools: toolPlan.excludeTools } : {}),
523
527
  extensions: toolPlan.extensionArgs,
524
528
  mcpDirectTools: toolPlan.effectiveMcpTools,
525
529
  ...(options.outputPath ? { outputPath: options.outputPath } : {}),
@@ -551,10 +555,14 @@ async function runSingleAttempt(
551
555
  }, options.context);
552
556
  const startTime = Date.now();
553
557
  if (options.structuredOutput) {
554
- try {
555
- if (existsSync(options.structuredOutput.outputPath)) unlinkSync(options.structuredOutput.outputPath);
556
- } catch {
557
- // Missing/stale structured-output files are handled after the child exits.
558
+ const cleanupError = clearStructuredOutputCaptures(options.structuredOutput);
559
+ if (cleanupError) {
560
+ cleanupTempDir(tempDir);
561
+ result.exitCode = 1;
562
+ result.error = cleanupError;
563
+ result.finalOutput = cleanupError;
564
+ result.progressSummary = { toolCount: 0, tokens: 0, durationMs: Date.now() - startTime };
565
+ return result;
558
566
  }
559
567
  }
560
568
  const controlConfig = options.controlConfig ?? DEFAULT_CONTROL_CONFIG;
@@ -772,7 +780,6 @@ async function runSingleAttempt(
772
780
  phase: "stale",
773
781
  seq: (childWatchdogState?.seq ?? 0) + 1,
774
782
  lastUpdate: Date.now(),
775
- followUpPending: false,
776
783
  reason: "child watchdog tail timeout",
777
784
  timedOut: true,
778
785
  });
@@ -958,6 +965,7 @@ async function runSingleAttempt(
958
965
  config: controlConfig,
959
966
  startedAt: startTime,
960
967
  lastActivityAt: progress.lastActivityAt,
968
+ turnCount: progress.turnCount,
961
969
  currentTool: progress.currentTool,
962
970
  thinking: resolvedThinking,
963
971
  now,
@@ -1112,6 +1120,10 @@ async function runSingleAttempt(
1112
1120
 
1113
1121
  if (evt.type === "message_end" && evt.message) {
1114
1122
  result.messages!.push(evt.message);
1123
+ if (childWatchdog) {
1124
+ const next = applyChildWatchdogMessage(childWatchdogState, evt.message);
1125
+ if (next) updateChildWatchdogState(next);
1126
+ }
1115
1127
  if (evt.message.role === "assistant") {
1116
1128
  result.usage.turns++;
1117
1129
  progress.turnCount = result.usage.turns;
@@ -2224,6 +2236,7 @@ async function runSyncCompletionInner(
2224
2236
  reportOptional: isAgentContractV1(options.agentContract),
2225
2237
  artifactsDir: options.artifactsDir,
2226
2238
  runId: options.runId,
2239
+ watchdog: result.watchdog,
2227
2240
  });
2228
2241
  }
2229
2242
  } catch (error) {