pi-crew 0.9.55 → 0.9.57

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 (309) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +58 -0
  3. package/README.md +53 -5
  4. package/dist/index.mjs +5666 -4370
  5. package/docs/README.md +54 -0
  6. package/package.json +12 -13
  7. package/skills/real-test-pi-crew/SKILL.md +93 -3
  8. package/src/agents/discover-agents.ts +68 -10
  9. package/src/benchmark/feedback-loop.ts +1 -1
  10. package/src/config/config.ts +2 -1
  11. package/src/config/types.ts +12 -0
  12. package/src/extension/action-suggestions.ts +16 -63
  13. package/src/extension/async-notifier.ts +3 -3
  14. package/src/extension/command-completions.ts +2 -2
  15. package/src/extension/crew-cleanup.ts +3 -3
  16. package/src/extension/crew-vibes/footer.ts +4 -2
  17. package/src/extension/cross-extension-rpc.ts +10 -5
  18. package/src/extension/knowledge-injection.ts +57 -10
  19. package/src/extension/register.ts +2 -2
  20. package/src/extension/registration/artifact-cleanup.ts +41 -3
  21. package/src/extension/registration/commands.ts +4 -4
  22. package/src/extension/registration/context-builder.ts +10 -10
  23. package/src/extension/registration/crash-recovery-cache.ts +3 -3
  24. package/src/extension/registration/foreground-run-controller.ts +1 -1
  25. package/src/extension/registration/lazy-configurers.ts +2 -2
  26. package/src/extension/registration/lifecycle-handlers.ts +12 -12
  27. package/src/extension/registration/lifecycle.ts +2 -2
  28. package/src/extension/registration/observability.ts +2 -2
  29. package/src/extension/registration/registration-types.ts +3 -3
  30. package/src/extension/registration/runtime-cleanup.ts +1 -1
  31. package/src/extension/registration/subagent-helpers.ts +2 -2
  32. package/src/extension/registration/subagent-manager-setup.ts +2 -2
  33. package/src/extension/registration/subagent-tools.ts +21 -16
  34. package/src/extension/registration/team-tool.ts +109 -17
  35. package/src/extension/registration/viewers.ts +3 -4
  36. package/src/extension/registration/wire-cross-extension.ts +7 -7
  37. package/src/extension/rpc-hmac.ts +3 -2
  38. package/src/extension/run-bundle-schema.ts +13 -4
  39. package/src/extension/run-export.ts +2 -2
  40. package/src/extension/run-index.ts +2 -3
  41. package/src/extension/run-maintenance.ts +57 -1
  42. package/src/extension/team-manager-command.ts +3 -1
  43. package/src/extension/team-tool/anchor.ts +8 -2
  44. package/src/extension/team-tool/api.ts +117 -39
  45. package/src/extension/team-tool/cancel.ts +23 -8
  46. package/src/extension/team-tool/chain-executor.ts +1 -1
  47. package/src/extension/team-tool/dispatch/automate.ts +17 -2
  48. package/src/extension/team-tool/dispatch/control.ts +17 -2
  49. package/src/extension/team-tool/dispatch/manage.ts +34 -2
  50. package/src/extension/team-tool/dispatch/run.ts +17 -2
  51. package/src/extension/team-tool/dispatch/status.ts +37 -5
  52. package/src/extension/team-tool/doctor.ts +2 -2
  53. package/src/extension/team-tool/explain.ts +1 -1
  54. package/src/extension/team-tool/goal-wrap.ts +5 -5
  55. package/src/extension/team-tool/goal.ts +30 -9
  56. package/src/extension/team-tool/handle-schedule.ts +37 -19
  57. package/src/extension/team-tool/inspect.ts +21 -5
  58. package/src/extension/team-tool/lifecycle-actions.ts +53 -10
  59. package/src/extension/team-tool/parallel-dispatch.ts +14 -5
  60. package/src/extension/team-tool/param-error.ts +138 -0
  61. package/src/extension/team-tool/respond.ts +20 -6
  62. package/src/extension/team-tool/run.ts +27 -17
  63. package/src/extension/team-tool/status.ts +17 -6
  64. package/src/extension/team-tool.ts +26 -19
  65. package/src/hooks/registry.ts +1 -1
  66. package/src/i18n.ts +22 -0
  67. package/src/observability/event-bus.ts +1 -1
  68. package/src/prompt/prompt-runtime.ts +2 -2
  69. package/src/runtime/README.md +35 -0
  70. package/src/runtime/agent-control.ts +1 -1
  71. package/src/runtime/anchor-manager.ts +0 -2
  72. package/src/runtime/async-runner.ts +1 -1
  73. package/src/runtime/attention-events.ts +3 -2
  74. package/src/runtime/auto-summarize.ts +0 -2
  75. package/src/runtime/background-runner.ts +103 -30
  76. package/src/runtime/{crew-broker-child.ts → broker/crew-broker-child.ts} +2 -2
  77. package/src/runtime/{crew-broker-client.ts → broker/crew-broker-client.ts} +4 -7
  78. package/src/runtime/{crew-broker.ts → broker/crew-broker.ts} +13 -21
  79. package/src/runtime/chain-runner.ts +50 -5
  80. package/src/runtime/{child-pi-constants.ts → child-pi/child-pi-constants.ts} +1 -1
  81. package/src/runtime/{child-pi-kill.ts → child-pi/child-pi-kill.ts} +3 -3
  82. package/src/runtime/{child-pi-spawn.ts → child-pi/child-pi-spawn.ts} +28 -12
  83. package/src/runtime/{child-pi-steering.ts → child-pi/child-pi-steering.ts} +1 -1
  84. package/src/runtime/{child-pi-streams.ts → child-pi/child-pi-streams.ts} +23 -4
  85. package/src/runtime/{child-pi-transcript.ts → child-pi/child-pi-transcript.ts} +6 -6
  86. package/src/runtime/{child-pi.ts → child-pi/child-pi.ts} +47 -78
  87. package/src/runtime/compaction/compact-stages/bounded-tail.ts +84 -0
  88. package/src/runtime/{compact-stages → compaction/compact-stages}/index.ts +2 -2
  89. package/src/runtime/{compaction-summary.ts → compaction/compaction-summary.ts} +3 -3
  90. package/src/runtime/{tool-output-pruner.ts → compaction/tool-output-pruner.ts} +1 -1
  91. package/src/runtime/crew-agent-records.ts +48 -2
  92. package/src/runtime/custom-tools/irc-tool.ts +2 -2
  93. package/src/runtime/delivery-coordinator.ts +0 -3
  94. package/src/runtime/diagnostic-export.ts +5 -4
  95. package/src/runtime/foreground-control.ts +1 -1
  96. package/src/runtime/foreground-watchdog.ts +1 -1
  97. package/src/runtime/{adaptive-plan.ts → goal-workflow/adaptive-plan.ts} +8 -8
  98. package/src/runtime/{dynamic-workflow-context.ts → goal-workflow/dynamic-workflow-context.ts} +16 -16
  99. package/src/runtime/{dynamic-workflow-runner.ts → goal-workflow/dynamic-workflow-runner.ts} +10 -10
  100. package/src/runtime/{goal-achievement.ts → goal-workflow/goal-achievement.ts} +3 -3
  101. package/src/runtime/{goal-evaluator.ts → goal-workflow/goal-evaluator.ts} +8 -8
  102. package/src/runtime/{goal-loop-runner.ts → goal-workflow/goal-loop-runner.ts} +27 -25
  103. package/src/runtime/{goal-state-store.ts → goal-workflow/goal-state-store.ts} +8 -8
  104. package/src/runtime/{plan-templates.ts → goal-workflow/plan-templates.ts} +1 -1
  105. package/src/runtime/group-join.ts +3 -3
  106. package/src/runtime/handoff-manager.ts +0 -2
  107. package/src/runtime/{heartbeat-watcher.ts → heartbeat/heartbeat-watcher.ts} +7 -7
  108. package/src/runtime/iteration-hooks.ts +1 -1
  109. package/src/runtime/{live-agent-control.ts → live-session/live-agent-control.ts} +2 -2
  110. package/src/runtime/{live-agent-manager.ts → live-session/live-agent-manager.ts} +4 -4
  111. package/src/runtime/{live-session-runtime.ts → live-session/live-session-runtime.ts} +39 -41
  112. package/src/runtime/manifest-cache.ts +6 -2
  113. package/src/runtime/{model-fallback.ts → model/model-fallback.ts} +1 -1
  114. package/src/runtime/{pi-args.ts → model/pi-args.ts} +20 -5
  115. package/src/runtime/model/provider-extensions.ts +116 -0
  116. package/src/runtime/{runtime-policy.ts → model/runtime-policy.ts} +2 -2
  117. package/src/runtime/{runtime-resolver.ts → model/runtime-resolver.ts} +3 -3
  118. package/src/runtime/{runtime-warmup.ts → model/runtime-warmup.ts} +8 -8
  119. package/src/runtime/orphan-worker-registry.ts +1 -1
  120. package/src/runtime/{progress-tracker.ts → output/progress-tracker.ts} +1 -1
  121. package/src/runtime/{result-extractor.ts → output/result-extractor.ts} +4 -4
  122. package/src/runtime/{sidechain-output.ts → output/sidechain-output.ts} +2 -2
  123. package/src/runtime/{stream-preview.ts → output/stream-preview.ts} +1 -1
  124. package/src/runtime/{streaming-output.ts → output/streaming-output.ts} +2 -2
  125. package/src/runtime/{tool-progress.ts → output/tool-progress.ts} +1 -1
  126. package/src/runtime/parent-guard.ts +30 -10
  127. package/src/runtime/pipeline-runner.ts +2 -2
  128. package/src/runtime/policy-engine.ts +2 -2
  129. package/src/runtime/{cancellation.ts → process/cancellation.ts} +1 -1
  130. package/src/runtime/{post-exit-stdio-guard.ts → process/post-exit-stdio-guard.ts} +1 -1
  131. package/src/runtime/{process-lifecycle.ts → process/process-lifecycle.ts} +3 -3
  132. package/src/runtime/{checkpoint.ts → recovery/checkpoint.ts} +4 -4
  133. package/src/runtime/{crash-recovery.ts → recovery/crash-recovery.ts} +93 -21
  134. package/src/runtime/{overflow-recovery.ts → recovery/overflow-recovery.ts} +1 -1
  135. package/src/runtime/{recovery-recipes.ts → recovery/recovery-recipes.ts} +1 -1
  136. package/src/runtime/{retry-executor.ts → recovery/retry-executor.ts} +2 -2
  137. package/src/runtime/{retry-runner.ts → recovery/retry-runner.ts} +2 -8
  138. package/src/runtime/run-tracker.ts +1 -1
  139. package/src/runtime/run-worker.ts +3 -3
  140. package/src/runtime/{coalesce-tasks.ts → scheduling/coalesce-tasks.ts} +3 -3
  141. package/src/runtime/{concurrency.ts → scheduling/concurrency.ts} +9 -3
  142. package/src/runtime/{parallel-research.ts → scheduling/parallel-research.ts} +4 -2
  143. package/src/runtime/{run-coalesced-task-group.ts → scheduling/run-coalesced-task-group.ts} +95 -36
  144. package/src/runtime/{semaphore.ts → scheduling/semaphore.ts} +4 -1
  145. package/src/runtime/{task-graph-scheduler.ts → scheduling/task-graph-scheduler.ts} +1 -1
  146. package/src/runtime/session-resources.ts +1 -1
  147. package/src/runtime/settings-store.ts +1 -1
  148. package/src/runtime/single-agent-compose.ts +1 -0
  149. package/src/runtime/stale-reconciler.ts +1 -1
  150. package/src/runtime/subagent-manager.ts +1 -1
  151. package/src/runtime/supervisor-contact.ts +28 -13
  152. package/src/runtime/task-output-context.ts +7 -5
  153. package/src/runtime/task-runner/child-executor.ts +67 -31
  154. package/src/runtime/task-runner/live-executor.ts +8 -8
  155. package/src/runtime/task-runner/post-execution.ts +12 -12
  156. package/src/runtime/task-runner/pre-execution.ts +6 -6
  157. package/src/runtime/task-runner/progress.ts +1 -1
  158. package/src/runtime/task-runner/run-projection.ts +1 -1
  159. package/src/runtime/task-runner/scaffold-executor.ts +1 -1
  160. package/src/runtime/task-runner/state-helpers.ts +2 -2
  161. package/src/runtime/task-runner.ts +4 -4
  162. package/src/runtime/team-runner.ts +441 -175
  163. package/src/runtime/{completion-guard.ts → verification/completion-guard.ts} +1 -1
  164. package/src/runtime/{green-contract.ts → verification/green-contract.ts} +1 -1
  165. package/src/runtime/{post-checks.ts → verification/post-checks.ts} +4 -4
  166. package/src/runtime/{verification-gates.ts → verification/verification-gates.ts} +5 -5
  167. package/src/runtime/{verification-integrity.ts → verification/verification-integrity.ts} +1 -1
  168. package/src/schema/config-schema.ts +1 -0
  169. package/src/schema/team-tool-schema.ts +149 -185
  170. package/src/state/README.md +44 -0
  171. package/src/state/atomic-write.ts +24 -3
  172. package/src/state/{locks.ts → coordination/locks.ts} +118 -38
  173. package/src/state/{mailbox.ts → coordination/mailbox.ts} +14 -8
  174. package/src/state/{schedule.ts → coordination/schedule.ts} +3 -3
  175. package/src/state/{task-claims.ts → coordination/task-claims.ts} +1 -1
  176. package/src/state/decision-ledger.ts +1 -1
  177. package/src/state/{event-log-rotation.ts → event-log/event-log-rotation.ts} +189 -31
  178. package/src/state/{event-log.ts → event-log/event-log.ts} +77 -39
  179. package/src/state/{jsonl-writer.ts → event-log/jsonl-writer.ts} +14 -6
  180. package/src/state/hook-instinct-bridge.ts +2 -2
  181. package/src/state/{active-run-registry.ts → stores/active-run-registry.ts} +7 -7
  182. package/src/state/{artifact-store.ts → stores/artifact-store.ts} +62 -4
  183. package/src/state/{blob-store.ts → stores/blob-store.ts} +3 -3
  184. package/src/state/{health-store.ts → stores/health-store.ts} +3 -3
  185. package/src/state/{instinct-store.ts → stores/instinct-store.ts} +3 -3
  186. package/src/state/{observation-store.ts → stores/observation-store.ts} +2 -2
  187. package/src/state/{run-cache.ts → stores/run-cache.ts} +4 -4
  188. package/src/state/{run-graph.ts → stores/run-graph.ts} +4 -4
  189. package/src/state/{run-metrics.ts → stores/run-metrics.ts} +3 -3
  190. package/src/state/{state-store.ts → stores/state-store.ts} +254 -21
  191. package/src/state/types.ts +27 -3
  192. package/src/ui/component.ts +55 -0
  193. package/src/ui/crew-select-list.ts +3 -1
  194. package/src/ui/dashboard-panes/agents-pane.ts +1 -1
  195. package/src/ui/dwf-phase-display.ts +1 -1
  196. package/src/ui/heartbeat-aggregator.ts +1 -1
  197. package/src/ui/keybinding-map.ts +179 -6
  198. package/src/ui/layout-primitives.ts +9 -5
  199. package/src/ui/live-conversation-overlay.ts +1 -1
  200. package/src/ui/live-run-sidebar.ts +1 -1
  201. package/src/ui/overlay-stack.ts +148 -0
  202. package/src/ui/overlays/agent-picker-overlay.ts +1 -1
  203. package/src/ui/overlays/mailbox-compose-overlay.ts +1 -1
  204. package/src/ui/overlays/mailbox-detail-overlay.ts +2 -2
  205. package/src/ui/powerbar-publisher.ts +1 -1
  206. package/src/ui/render-scheduler.ts +1 -1
  207. package/src/ui/run-action-dispatcher.ts +3 -3
  208. package/src/ui/run-dashboard.ts +5 -33
  209. package/src/ui/run-event-bus.ts +3 -3
  210. package/src/ui/run-snapshot-cache.ts +37 -18
  211. package/src/ui/settings-overlay.ts +13 -21
  212. package/src/ui/snapshot-types.ts +1 -1
  213. package/src/ui/status-colors.ts +0 -2
  214. package/src/ui/terminal-status.ts +1 -1
  215. package/src/ui/theme-adapter.ts +33 -13
  216. package/src/ui/tool-renderers/index.ts +8 -0
  217. package/src/ui/transcript-viewer.ts +37 -13
  218. package/src/ui/widget/index.ts +32 -9
  219. package/src/ui/widget/widget-formatters.ts +62 -4
  220. package/src/ui/widget/widget-model.ts +2 -2
  221. package/src/ui/widget/widget-renderer.ts +1 -1
  222. package/src/utils/conflict-detect.ts +58 -5
  223. package/src/utils/ndjson.ts +2 -2
  224. package/src/utils/redaction.ts +39 -0
  225. package/src/utils/socket-path.ts +1 -1
  226. package/src/workflows/workflow-config.ts +1 -1
  227. package/src/worktree/cleanup.ts +1 -1
  228. package/src/worktree/worktree-manager.ts +111 -47
  229. package/workflows/chain.workflow.md +2 -2
  230. package/dist/build-meta.json +0 -16807
  231. package/index.bundle.ts +0 -25
  232. package/scripts/bench-check.mjs +0 -96
  233. package/scripts/bench-cold-start.mjs +0 -216
  234. package/scripts/build-bundle.mjs +0 -92
  235. package/scripts/check-all-skills.ts +0 -294
  236. package/scripts/check-bundle-size.mjs +0 -38
  237. package/scripts/check-bundle-staleness.mjs +0 -97
  238. package/scripts/check-conflict-markers.mjs +0 -91
  239. package/scripts/check-lazy-imports.mjs +0 -28
  240. package/scripts/dev-runner.mjs +0 -106
  241. package/scripts/profile-startup.mjs +0 -125
  242. package/scripts/release-smoke.mjs +0 -74
  243. package/scripts/run-bench.mjs +0 -47
  244. package/scripts/run-real-chain.ts +0 -41
  245. package/scripts/test-issue-29-crash.ts +0 -111
  246. package/scripts/test-issue-29-e2e.ts +0 -183
  247. package/scripts/test-issue-29-real-runtime.ts +0 -330
  248. package/scripts/test-issue-29-real-tasks.ts +0 -387
  249. package/scripts/test-issue-29-team-tool.ts +0 -105
  250. package/scripts/test-runner.mjs +0 -84
  251. package/scripts/verify-flicker-fix.ts +0 -109
  252. package/scripts/verify-skill.ts +0 -550
  253. package/scripts/watch-bundle.mjs +0 -259
  254. package/scripts/watchdog-harness.ts +0 -119
  255. package/src/adapters/claude-adapter.ts +0 -23
  256. package/src/adapters/codex-adapter.ts +0 -21
  257. package/src/adapters/cursor-adapter.ts +0 -17
  258. package/src/adapters/export-util.ts +0 -143
  259. package/src/adapters/index.ts +0 -15
  260. package/src/adapters/registry.ts +0 -18
  261. package/src/adapters/types.ts +0 -23
  262. package/src/runtime/code-summary.ts +0 -292
  263. package/src/runtime/cross-extension-rpc.ts +0 -143
  264. package/src/runtime/hidden-handoff.ts +0 -407
  265. package/src/runtime/prose-compressor.ts +0 -162
  266. package/src/subagents/async-entry.ts +0 -1
  267. package/src/subagents/index.ts +0 -3
  268. package/src/subagents/live/control.ts +0 -1
  269. package/src/subagents/live/manager.ts +0 -1
  270. package/src/subagents/live/realtime.ts +0 -1
  271. package/src/subagents/live/session-runtime.ts +0 -1
  272. package/src/subagents/manager.ts +0 -1
  273. package/src/subagents/spawn.ts +0 -1
  274. package/test-integration-check.ts +0 -118
  275. /package/src/runtime/{broker-issuer.ts → broker/broker-issuer.ts} +0 -0
  276. /package/src/runtime/{crew-broker-tokens.ts → broker/crew-broker-tokens.ts} +0 -0
  277. /package/src/runtime/{child-pi-pool.ts → child-pi/child-pi-pool.ts} +0 -0
  278. /package/src/runtime/{compact-pipeline.ts → compaction/compact-pipeline.ts} +0 -0
  279. /package/src/runtime/{compact-stages → compaction/compact-stages}/ansi-strip-stage.ts +0 -0
  280. /package/src/runtime/{compact-stages → compaction/compact-stages}/blank-collapse-stage.ts +0 -0
  281. /package/src/runtime/{compact-stages → compaction/compact-stages}/deduplicate-stage.ts +0 -0
  282. /package/src/runtime/{compact-stages → compaction/compact-stages}/head-snap-stage.ts +0 -0
  283. /package/src/runtime/{compact-stages → compaction/compact-stages}/tail-capture-stage.ts +0 -0
  284. /package/src/runtime/{compact-stages → compaction/compact-stages}/truncation-stage.ts +0 -0
  285. /package/src/runtime/{important-line-classifier.ts → compaction/important-line-classifier.ts} +0 -0
  286. /package/src/runtime/{heartbeat-gradient.ts → heartbeat/heartbeat-gradient.ts} +0 -0
  287. /package/src/runtime/{worker-heartbeat.ts → heartbeat/worker-heartbeat.ts} +0 -0
  288. /package/src/runtime/{worker-startup.ts → heartbeat/worker-startup.ts} +0 -0
  289. /package/src/runtime/{intercom-bridge.ts → live-session/intercom-bridge.ts} +0 -0
  290. /package/src/runtime/{live-control-realtime.ts → live-session/live-control-realtime.ts} +0 -0
  291. /package/src/runtime/{live-extension-bridge.ts → live-session/live-extension-bridge.ts} +0 -0
  292. /package/src/runtime/{live-irc.ts → live-session/live-irc.ts} +0 -0
  293. /package/src/runtime/{live-session-health.ts → live-session/live-session-health.ts} +0 -0
  294. /package/src/runtime/{model-resolver.ts → model/model-resolver.ts} +0 -0
  295. /package/src/runtime/{model-scope.ts → model/model-scope.ts} +0 -0
  296. /package/src/runtime/{output-validator.ts → output/output-validator.ts} +0 -0
  297. /package/src/runtime/{pi-json-output.ts → output/pi-json-output.ts} +0 -0
  298. /package/src/runtime/{progress-event-coalescer.ts → output/progress-event-coalescer.ts} +0 -0
  299. /package/src/runtime/{cancellation-token.ts → process/cancellation-token.ts} +0 -0
  300. /package/src/runtime/{zombie-scanner.ts → process/zombie-scanner.ts} +0 -0
  301. /package/src/runtime/{crash-classification.ts → recovery/crash-classification.ts} +0 -0
  302. /package/src/runtime/{batch-barrier.ts → scheduling/batch-barrier.ts} +0 -0
  303. /package/src/runtime/{global-worker-cap.ts → scheduling/global-worker-cap.ts} +0 -0
  304. /package/src/runtime/{parallel-utils.ts → scheduling/parallel-utils.ts} +0 -0
  305. /package/src/runtime/{scheduler.ts → scheduling/scheduler.ts} +0 -0
  306. /package/src/runtime/{task-graph.ts → scheduling/task-graph.ts} +0 -0
  307. /package/src/runtime/{verification-worktree.ts → verification/verification-worktree.ts} +0 -0
  308. /package/src/state/{event-reconstructor.ts → event-log/event-reconstructor.ts} +0 -0
  309. /package/src/state/{worker-atomic-writer.ts → event-log/worker-atomic-writer.ts} +0 -0
@@ -2,16 +2,17 @@ import { spawn } from "node:child_process";
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
- import type { AgentConfig } from "../agents/agent-config.ts";
6
- import { DEFAULT_CHILD_PI } from "../config/defaults.ts";
7
- import { registerChildProcess, unregisterChildProcess } from "../extension/crew-cleanup.ts";
8
- import { atomicWriteFile } from "../state/atomic-write.ts";
9
- import type { WorkerExitStatus } from "../state/types.ts";
10
- import { logInternalError } from "../utils/internal-error.ts";
11
- import { redactSecretString } from "../utils/redaction.ts";
12
- import { getActiveBrokerIssuer } from "./broker-issuer.ts";
5
+ import type { AgentConfig } from "../../agents/agent-config.ts";
6
+ import { DEFAULT_CHILD_PI } from "../../config/defaults.ts";
7
+ import { registerChildProcess, unregisterChildProcess } from "../../extension/crew-cleanup.ts";
8
+ import { atomicWriteFile } from "../../state/atomic-write.ts";
9
+ import type { WorkerExitStatus } from "../../state/types.ts";
10
+ import { logInternalError } from "../../utils/internal-error.ts";
11
+ import { redactSecretString } from "../../utils/redaction.ts";
12
+ import { getActiveBrokerIssuer } from "../broker/broker-issuer.ts";
13
+ import { BoundedTail } from "../compaction/compact-stages/bounded-tail.ts";
13
14
  import { FINAL_DRAIN_MS, HARD_KILL_MS, POST_EXIT_STDIO_GUARD_MS, RESPONSE_TIMEOUT_MS } from "./child-pi-constants.ts";
14
- import { appendBoundedTail, clearHardKillTimer, killProcessTree, registerActiveChild, unregisterActiveChild } from "./child-pi-kill.ts";
15
+ import { clearHardKillTimer, killProcessTree, registerActiveChild, unregisterActiveChild } from "./child-pi-kill.ts";
15
16
  import { buildFinalChildPiSpawnOptions, prepareSpawnContext } from "./child-pi-spawn.ts";
16
17
  import { ChildPiSteeringController } from "./child-pi-steering.ts";
17
18
  // Internal helpers for active-child bookkeeping (extracted to child-pi-kill.ts).
@@ -32,10 +33,9 @@ export { buildChildPiSpawnOptions, buildFinalChildPiSpawnOptions } from "./child
32
33
  // ── Re-export from child-pi-streams.ts (H-7 decomposition step 4) ──
33
34
  export { ChildPiLineObserver } from "./child-pi-streams.ts";
34
35
 
35
- import { classifyProcessCrash } from "./crash-classification.ts";
36
- import { checkCrewDepth, cleanupTempDir } from "./pi-args.ts";
37
-
38
- import { attachPostExitStdioGuard, trySignalChild } from "./post-exit-stdio-guard.ts";
36
+ import { checkCrewDepth, cleanupTempDir } from "../model/pi-args.ts";
37
+ import { attachPostExitStdioGuard, trySignalChild } from "../process/post-exit-stdio-guard.ts";
38
+ import { classifyProcessCrash } from "../recovery/crash-classification.ts";
39
39
 
40
40
  /** Maximum size (bytes) for the ChildPiLineObserver's line accumulation buffer.
41
41
  * When exceeded, the buffer is force-flushed to prevent unbounded memory growth
@@ -420,10 +420,15 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
420
420
  pid: child.pid,
421
421
  ts: new Date().toISOString(),
422
422
  });
423
- // Register with cleanup handler for graceful shutdown
424
- if (input.runId && input.agentId) {
425
- registerChildProcess(child.pid, input.runId, input.agentId);
426
- }
423
+ // Register with cleanup handler for graceful shutdown (RT-11):
424
+ // ALWAYS register — every spawned child must be visible to host-SIGTERM
425
+ // cleanup. Use synthetic IDs when the caller omitted runId/agentId so the
426
+ // PID is still tracked for killProcessPid on session shutdown.
427
+ registerChildProcess(
428
+ child.pid,
429
+ input.runId ?? `untracked-run-${child.pid}`,
430
+ input.agentId ?? `untracked-agent-${child.pid}`,
431
+ );
427
432
  } else {
428
433
  input.onLifecycleEvent?.({
429
434
  type: "spawn_error",
@@ -431,8 +436,10 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
431
436
  ts: new Date().toISOString(),
432
437
  });
433
438
  }
434
- let stdout = "";
435
- let stderr = "";
439
+ // P0-1: O(1)-amortized bounded accumulators (segment ring) — replaces the O(n²)
440
+ // appendBoundedTail rebuild-per-line pattern that re-scanned 512 KiB every line.
441
+ const stdoutTail = new BoundedTail();
442
+ const stderrTail = new BoundedTail();
436
443
  let settled = false;
437
444
  let childExited = false;
438
445
  let postExitGuardCleanup: (() => void) | undefined;
@@ -473,37 +480,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
473
480
  let hardKilled = false;
474
481
  const cleanupErrors: string[] = [];
475
482
  const steeringController = new ChildPiSteeringController(input.maxTurns, input.graceTurns);
476
- // Track in-flight operations for proper rejection on unexpected exit
477
- interface PendingOperation {
478
- id: string;
479
- type: "prompt" | "steer" | "json_event";
480
- startedAt: number;
481
- }
482
- const pendingOperations = new Map<string, PendingOperation>();
483
- let operationIdCounter = 0;
484
-
485
- const startOperation = (type: PendingOperation["type"]): string => {
486
- const id = `op-${++operationIdCounter}`;
487
- pendingOperations.set(id, { id, type, startedAt: Date.now() });
488
- return id;
489
- };
490
-
491
- const completeOperation = (id: string): void => {
492
- pendingOperations.delete(id);
493
- };
494
-
495
- const rejectPendingOperations = (error: Error): void => {
496
- pendingOperations.forEach((op, id) => {
497
- logInternalError(
498
- "child-pi.pending-operation-rejected",
499
- error,
500
- `opId=${id} type=${op.type} elapsed=${Date.now() - op.startedAt}ms`,
501
- );
502
- });
503
- pendingOperations.clear();
504
- };
505
-
506
- const steerInjectionFailed = false;
507
483
  let abortDueToParentSignal = false;
508
484
  // CP-1: track whether the turn-limit hard-abort has been initiated. Once
509
485
  // true, we must NOT restart the no-response timer — the child is already
@@ -526,6 +502,8 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
526
502
  if (noResponseTimer) clearTimeout(noResponseTimer);
527
503
  noResponseTimer = setTimeout(() => {
528
504
  responseTimeoutHit = true;
505
+ // P0-1: snapshot the bounded stderr accumulator once for this timer fire.
506
+ const stderr = stderrTail.value();
529
507
  // Capture stderr at timeout moment for debugging
530
508
  // SEC-1: redact secrets before embedding in lifecycle event so
531
509
  // worker-emitted secrets (API keys etc.) don't bypass redaction.
@@ -569,8 +547,8 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
569
547
  const timeoutErr = `Child Pi produced no new output for ${responseTimeoutMs}ms; killed but did not exit within ${SAFETY_SETTLE_MS}ms (possible zombie).`;
570
548
  void settle({
571
549
  exitCode: null,
572
- stdout,
573
- stderr,
550
+ stdout: stdoutTail.value(),
551
+ stderr: stderrTail.value(),
574
552
  error: timeoutErr,
575
553
  exitStatus: {
576
554
  exitCode: null,
@@ -600,26 +578,19 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
600
578
  ...input,
601
579
  onStdoutLine: (line) => {
602
580
  if (!steeringController.isHardAbortInitiated()) restartNoResponseTimer();
603
- stdout = appendBoundedTail(stdout, `${line}\n`);
581
+ stdoutTail.push(`${line}\n`);
604
582
  input.onStdoutLine?.(line);
605
583
  },
606
584
  onJsonEvent: (event) => {
607
585
  if (!steeringController.isHardAbortInitiated()) restartNoResponseTimer();
608
- const eventOpId = startOperation("json_event");
609
- try {
610
- // Turn-count-based steering: soft limit steer + hard abort after graceTurns
611
- if (event && typeof event === "object" && !Array.isArray(event)) {
612
- const obj = event as Record<string, unknown>;
613
- if (obj.type === "turn_end") {
614
- // H-7 step 5: steering state machine extracted to ChildPiSteeringController.
615
- const action = steeringController.onTurnEnd(child.pid, child, input.steeringFile);
616
- if (action.kind === "hardAbort") killProcessTree(action.pid, action.child);
617
- }
586
+ // Turn-count-based steering: soft limit steer + hard abort after graceTurns
587
+ if (event && typeof event === "object" && !Array.isArray(event)) {
588
+ const obj = event as Record<string, unknown>;
589
+ if (obj.type === "turn_end") {
590
+ // H-7 step 5: steering state machine extracted to ChildPiSteeringController.
591
+ const action = steeringController.onTurnEnd(child.pid, child, input.steeringFile);
592
+ if (action.kind === "hardAbort") killProcessTree(action.pid, action.child);
618
593
  }
619
- completeOperation(eventOpId);
620
- } catch (err) {
621
- completeOperation(eventOpId);
622
- throw err;
623
594
  }
624
595
  // F12: capture monotonic timestamp BEFORE dispatching — any stdout
625
596
  // JSON event counts as activity. This lets the quiet-window
@@ -913,15 +884,16 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
913
884
  });
914
885
  child.stderr?.on("data", (chunk: Buffer) => {
915
886
  if (!steeringController.isHardAbortInitiated()) restartNoResponseTimer();
916
- stderr = appendBoundedTail(stderr, chunk.toString("utf-8"));
887
+ stderrTail.push(chunk.toString("utf-8"));
917
888
  });
918
889
  child.on("error", (error) => {
919
- // Reject pending operations with process error context
890
+ // P0-1: snapshot the bounded accumulators once for this handler.
891
+ const stdout = stdoutTail.value();
892
+ const stderr = stderrTail.value();
920
893
  // SEC-1: redact stderr secrets embedded in the error message + excerpt.
921
894
  const processError = new Error(
922
895
  `Child Pi process error: ${error.message}. Stderr: ${redactStderrExcerpt(stderr, 500) || "(none)"}`,
923
896
  );
924
- rejectPendingOperations(processError);
925
897
  try {
926
898
  input.onLifecycleEvent?.({
927
899
  type: "spawn_error",
@@ -956,6 +928,8 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
956
928
  });
957
929
  });
958
930
  child.on("exit", (code, signal) => {
931
+ // P0-1: snapshot the bounded stderr accumulator once for this handler.
932
+ const stderr = stderrTail.value();
959
933
  if (child.pid) {
960
934
  unregisterActiveChild(child.pid);
961
935
  clearHardKillTimer(child.pid);
@@ -975,9 +949,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
975
949
  `Stderr: ${redactStderrExcerpt(stderr, 1000) || "(none)"}`,
976
950
  )
977
951
  : null;
978
- if (exitError) {
979
- rejectPendingOperations(exitError);
980
- }
981
952
  try {
982
953
  // Phase-0 diagnostic (HB-003a): capture signal + drain timing in the
983
954
  // exit lifecycle event so the exit-null race is diagnosable instead of
@@ -1017,6 +988,9 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
1017
988
  }
1018
989
  });
1019
990
  child.on("close", (exitCode) => {
991
+ // P0-1: snapshot the bounded accumulators once for this handler.
992
+ const stdout = stdoutTail.value();
993
+ const stderr = stderrTail.value();
1020
994
  if (child.pid) {
1021
995
  unregisterActiveChild(child.pid);
1022
996
  clearHardKillTimer(child.pid);
@@ -1059,10 +1033,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
1059
1033
  steeringController.getTurnCount() >=
1060
1034
  (steeringController.getMaxTurns() ?? 0) + (steeringController.getGraceTurns() ?? 5);
1061
1035
  const wasParentAborted = abortDueToParentSignal && !wasGraceAborted;
1062
- // steerInjectionFailed is now always false (Phase-1 fix: steer backpressure
1063
- // is logged, not fatal). The steerError branch is retained for safety in
1064
- // case a future change reintroduces a fatal steer path.
1065
- const steerError = steerInjectionFailed ? "Steer injection failed due to stdin backpressure; process killed" : undefined;
1066
1036
  // P0 crash taxonomy: classify the exit so callers/dashboards can bucket
1067
1037
  // failure modes (timeout vs cancel vs native panic vs signal …).
1068
1038
  // The classifier is a pure function; this is the single integration point.
@@ -1080,7 +1050,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
1080
1050
  stdout,
1081
1051
  stderr,
1082
1052
  ...(timeoutError ? { error: timeoutError.error } : {}),
1083
- ...(steerError ? { error: steerError } : {}),
1084
1053
  aborted: wasGraceAborted || wasParentAborted,
1085
1054
  steered: steeringController.isSoftLimitReached() && !wasGraceAborted,
1086
1055
  exitStatus: {
@@ -0,0 +1,84 @@
1
+ /**
2
+ * BoundedTail — O(1)-amortized bounded string accumulator (segment ring + running
3
+ * byte counter).
4
+ *
5
+ * Replaces the O(n²) `appendBoundedTail` rebuild-per-line pattern on the child stdout/stderr
6
+ * hot path. The defect (P0-1, verified 2026-07-29): the old accumulator did
7
+ * `new TailCaptureStage(...).apply(current + chunk)` on EVERY output line, so once the
8
+ * buffer filled to the 512 KiB cap each line re-scanned the whole buffer with
9
+ * `Buffer.byteLength` AND ran a per-character `while(...) tail = tail.slice(0,-1)` trim
10
+ * — 2.3 s (ASCII) to 112 s (multi-byte) of main-thread block per task.
11
+ *
12
+ * `push(chunk)` is O(chunk): it appends the segment and shifts whole leading segments
13
+ * while over cap, recomputing byte length only for the dropped segment — never the full
14
+ * buffer, never per-character. The single byte-exact boundary trim runs ONCE, in
15
+ * `value()`, which is read only at result-build / error time (rare).
16
+ *
17
+ * Output parity with the old `TailCaptureStage`-based path is preserved: under cap →
18
+ * verbatim; over cap → `[pi-crew captured output truncated to last X KiB]\n` + the last
19
+ * ≤maxBytes bytes snapped to a UTF-8 char boundary.
20
+ */
21
+ import { DEFAULT_CHILD_PI } from "../../../config/defaults.ts";
22
+
23
+ const DEFAULT_MAX_BYTES = DEFAULT_CHILD_PI.maxCaptureBytes;
24
+
25
+ /** Default marker, identical to the old appendBoundedTail/TailCaptureStage wording. */
26
+ function defaultMarker(maxBytes: number): string {
27
+ return `[pi-crew captured output truncated to last ${Math.round(maxBytes / 1024)} KiB]`;
28
+ }
29
+
30
+ export class BoundedTail {
31
+ readonly #maxBytes: number;
32
+ readonly #marker: string;
33
+ #segs: string[] = [];
34
+ #bytes = 0;
35
+ #dropped = false;
36
+ #cached: string | undefined;
37
+ #dirty = false;
38
+
39
+ constructor(maxBytes: number = DEFAULT_MAX_BYTES, marker?: string) {
40
+ if (!(maxBytes > 0)) throw new Error(`BoundedTail: maxBytes must be > 0, got ${maxBytes}`);
41
+ this.#maxBytes = maxBytes;
42
+ this.#marker = marker ?? defaultMarker(maxBytes);
43
+ }
44
+
45
+ /** Append a chunk. O(chunk) amortized; never scans the full buffer. */
46
+ push(chunk: string): this {
47
+ if (!chunk) return this;
48
+ this.#segs.push(chunk);
49
+ this.#bytes += Buffer.byteLength(chunk, "utf-8");
50
+ // Drop whole leading segments while over cap. Stop at length 1 so a single
51
+ // oversized segment is trimmed exactly once in value() instead of per-char.
52
+ while (this.#bytes > this.#maxBytes && this.#segs.length > 1) {
53
+ const dropped = this.#segs.shift() as string;
54
+ this.#bytes -= Buffer.byteLength(dropped, "utf-8");
55
+ this.#dropped = true;
56
+ }
57
+ this.#dirty = true;
58
+ return this;
59
+ }
60
+
61
+ /** Materialize the bounded string. Computed at most once per push; cached otherwise. */
62
+ value(): string {
63
+ if (!this.#dirty && this.#cached !== undefined) return this.#cached;
64
+ const body = this.#segs.join("");
65
+ const result = this.#bound(body);
66
+ this.#cached = result;
67
+ this.#dirty = false;
68
+ return result;
69
+ }
70
+
71
+ /** Byte-exact bound with marker parity vs the old TailCaptureStage path. */
72
+ #bound(body: string): string {
73
+ if (Buffer.byteLength(body, "utf-8") <= this.#maxBytes) {
74
+ // Under cap: add the marker only if we dropped earlier segments.
75
+ return this.#dropped ? `${this.#marker}\n${body}` : body;
76
+ }
77
+ // Over cap (single segment larger than max, or a boundary segment): keep the
78
+ // last ≤maxBytes bytes snapped forward past any UTF-8 continuation bytes.
79
+ const buf = Buffer.from(body, "utf-8");
80
+ let start = Math.max(0, buf.length - this.#maxBytes);
81
+ while (start < buf.length && (buf[start] & 0xc0) === 0x80) start++;
82
+ return `${this.#marker}\n${buf.subarray(start).toString("utf-8")}`;
83
+ }
84
+ }
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Barrel re-exports for the compact-stages module.
3
3
  *
4
- * Callers import from `../../runtime/compact-stages/index.ts` (or just
5
- * `../../runtime/compact-stages/`) rather than reaching into individual
4
+ * Callers import from `../../runtime/compaction/compact-stages/index.ts` (or just
5
+ * `../../runtime/compaction/compact-stages/`) rather than reaching into individual
6
6
  * stage files, so internal refactors do not break the public surface.
7
7
  */
8
8
  export { ANSI_STRIP_STAGE, AnsiStripStage } from "./ansi-strip-stage.ts";
@@ -14,9 +14,9 @@ class GiantLineFallbackError extends Error {
14
14
 
15
15
  import * as fs from "node:fs";
16
16
  import * as path from "node:path";
17
- import { readJsonFile } from "../state/atomic-write.ts";
18
- import type { TeamEvent } from "../state/event-log.ts";
19
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
17
+ import { readJsonFile } from "../../state/atomic-write.ts";
18
+ import type { TeamEvent } from "../../state/event-log/event-log.ts";
19
+ import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
20
20
 
21
21
  /** Maximum number of events to read from the tail of events.jsonl. */
22
22
  const MAX_TAIL_EVENTS = 100;
@@ -90,7 +90,7 @@ export interface PruneResult {
90
90
  // Token estimation (rough char/4 heuristic, matching gajae-code)
91
91
  // ---------------------------------------------------------------------------
92
92
 
93
- import { countTokens } from "../utils/token-counter.ts";
93
+ import { countTokens } from "../../utils/token-counter.ts";
94
94
 
95
95
  function estimateTokens(text: string): number {
96
96
  return countTokens(text);
@@ -26,14 +26,39 @@ export function agentStateDir(manifest: TeamRunManifest, taskId: string): string
26
26
  return path.join(agentsRoot(manifest), safeAgentTaskId(taskId));
27
27
  }
28
28
 
29
+ // P1-5: per-task path memoization. The agent state dir + file paths cannot
30
+ // change within a task, so the mkdir/lstat/resolveRealContainedPath validation
31
+ // (≈30 syscalls each, incl. a full ancestor walk) only needs to run ONCE per
32
+ // task — not on every event/output line (was ~60 syscalls/event for the double
33
+ // ensureAgentStateDir call alone). FIFO-bounded so the cache can't grow with
34
+ // run count.
35
+ const ensuredAgentDirs = new Map<string, string>();
36
+ const resolvedAgentFiles = new Map<string, string>();
37
+ const AGENT_PATH_CACHE_MAX = 512;
38
+
39
+ function bumpAgentPathCache(): void {
40
+ if (ensuredAgentDirs.size > AGENT_PATH_CACHE_MAX) {
41
+ const oldest = ensuredAgentDirs.keys().next().value;
42
+ if (oldest !== undefined) ensuredAgentDirs.delete(oldest);
43
+ }
44
+ if (resolvedAgentFiles.size > AGENT_PATH_CACHE_MAX) {
45
+ const oldest = resolvedAgentFiles.keys().next().value;
46
+ if (oldest !== undefined) resolvedAgentFiles.delete(oldest);
47
+ }
48
+ }
49
+
29
50
  export function ensureAgentStateDir(manifest: TeamRunManifest, taskId: string): string {
30
51
  const root = agentsRoot(manifest);
52
+ const dir = agentStateDir(manifest, taskId);
53
+ const cachedDir = ensuredAgentDirs.get(dir);
54
+ if (cachedDir !== undefined) return cachedDir;
31
55
  fs.mkdirSync(root, { recursive: true });
32
56
  if (fs.lstatSync(root).isSymbolicLink()) throw new Error(`Invalid agents root: ${root}`);
33
- const dir = agentStateDir(manifest, taskId);
34
57
  fs.mkdirSync(dir, { recursive: true });
35
58
  if (fs.lstatSync(dir).isSymbolicLink()) throw new Error(`Invalid agent state directory: ${dir}`);
36
59
  resolveRealContainedPath(root, path.basename(dir));
60
+ ensuredAgentDirs.set(dir, dir);
61
+ bumpAgentPathCache();
37
62
  return dir;
38
63
  }
39
64
 
@@ -45,8 +70,26 @@ function safeExistingAgentFile(manifest: TeamRunManifest, taskId: string, fileNa
45
70
  }
46
71
 
47
72
  export function agentStateFile(manifest: TeamRunManifest, taskId: string, fileName: string): string {
73
+ const dir = agentStateDir(manifest, taskId);
74
+ const cacheKey = `${dir}\0${fileName}`;
75
+ const cached = resolvedAgentFiles.get(cacheKey);
76
+ if (cached !== undefined) return cached;
48
77
  ensureAgentStateDir(manifest, taskId);
49
- return safeExistingAgentFile(manifest, taskId, fileName);
78
+ const resolved = safeExistingAgentFile(manifest, taskId, fileName);
79
+ resolvedAgentFiles.set(cacheKey, resolved);
80
+ bumpAgentPathCache();
81
+ return resolved;
82
+ }
83
+
84
+ /** @internal Test-only: clear the path memoization cache. */
85
+ export function __test_clearAgentPathCache(): void {
86
+ ensuredAgentDirs.clear();
87
+ resolvedAgentFiles.clear();
88
+ }
89
+
90
+ /** @internal Test-only: inspect cache occupancy (regression guard for P1-5). */
91
+ export function __test_agentPathCacheStats(): { dirs: number; files: number } {
92
+ return { dirs: ensuredAgentDirs.size, files: resolvedAgentFiles.size };
50
93
  }
51
94
 
52
95
  export function agentStatusPath(manifest: TeamRunManifest, taskId: string): string {
@@ -250,6 +293,9 @@ export async function readCrewAgentsAsync(manifest: TeamRunManifest): Promise<Cr
250
293
  }
251
294
 
252
295
  export function saveCrewAgents(manifest: TeamRunManifest, records: CrewAgentRecord[]): void {
296
+ // P0-3: flush any pending coalesced (best-effort) write first so a stale
297
+ // debounced progress snapshot can't clobber this durable write.
298
+ flushPendingAgentWrites();
253
299
  withAgentsLock(manifest, () => {
254
300
  fs.mkdirSync(manifest.stateRoot, { recursive: true });
255
301
  const filePath = agentsPath(manifest);
@@ -14,8 +14,8 @@
14
14
 
15
15
  import { defineTool, type ToolDefinition } from "@earendil-works/pi-coding-agent";
16
16
  import { type Static, Type } from "@sinclair/typebox";
17
- import { broadcastIrcMessage, listLiveAgents, respondAsBackground, sendIrcMessage } from "../live-agent-manager.ts";
18
- import type { IrcMessage } from "../live-irc.ts";
17
+ import { broadcastIrcMessage, listLiveAgents, respondAsBackground, sendIrcMessage } from "../live-session/live-agent-manager.ts";
18
+ import type { IrcMessage } from "../live-session/live-irc.ts";
19
19
 
20
20
  const IrcParams = Type.Object({
21
21
  op: Type.Union(
@@ -28,21 +28,18 @@ export class DeliveryCoordinator {
28
28
  private readonly deps: DeliveryCoordinatorDeps;
29
29
  private ttlTimer: ReturnType<typeof setInterval> | undefined;
30
30
  private timerStarted = false;
31
- private ownerSessionId: string | undefined = undefined;
32
31
 
33
32
  constructor(deps: DeliveryCoordinatorDeps) {
34
33
  this.deps = deps;
35
34
  }
36
35
 
37
36
  activate(sessionId: string): void {
38
- this.ownerSessionId = sessionId;
39
37
  this.active = true;
40
38
  this.flushQueuedResults();
41
39
  }
42
40
 
43
41
  deactivate(): void {
44
42
  this.active = false;
45
- this.ownerSessionId = undefined;
46
43
  this.generation += 1;
47
44
  }
48
45
 
@@ -4,14 +4,15 @@ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
4
4
  import type { MetricRegistry } from "../observability/metric-registry.ts";
5
5
  import type { MetricSnapshot } from "../observability/metrics-primitives.ts";
6
6
  import { atomicWriteFile } from "../state/atomic-write.ts";
7
- import { readEvents, type TeamEvent } from "../state/event-log.ts";
8
- import { loadRunManifestById } from "../state/state-store.ts";
7
+ import type { TeamEvent } from "../state/event-log/event-log.ts";
8
+ import { loadRunManifestById } from "../state/stores/state-store.ts";
9
9
  import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
10
10
  import { type HeartbeatSummary, summarizeHeartbeats } from "../ui/heartbeat-aggregator.ts";
11
11
  import type { RunUiSnapshot } from "../ui/snapshot-types.ts";
12
+ import { readJsonlTail } from "../utils/incremental-reader.ts";
12
13
  import { isSecretKey, redactSecrets } from "../utils/redaction.ts";
13
14
  import { readCrewAgents } from "./crew-agent-records.ts";
14
- import { buildRecoveryLedger, type RecoveryLedgerEntry } from "./recovery-recipes.ts";
15
+ import { buildRecoveryLedger, type RecoveryLedgerEntry } from "./recovery/recovery-recipes.ts";
15
16
 
16
17
  export { isSecretKey, redactSecrets } from "../utils/redaction.ts";
17
18
 
@@ -92,7 +93,7 @@ export async function exportDiagnostic(
92
93
  if (!loaded) throw new Error(`Run '${runId}' not found.`);
93
94
  const exportedAt = new Date().toISOString();
94
95
  const safeTimestamp = exportedAt.replace(/[:.]/g, "-");
95
- const recentEvents = readEvents(loaded.manifest.eventsPath).slice(-200);
96
+ const recentEvents = readJsonlTail<TeamEvent>(loaded.manifest.eventsPath, 256 * 1024).items.slice(-200);
96
97
  const metricsSnapshot = options.registry?.snapshot();
97
98
  const taskDiagnostics: Record<string, Record<string, unknown>> = {};
98
99
  const terminalEvidence: Record<string, TeamTaskState["terminalEvidence"]> = {};
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { atomicWriteFile } from "../state/atomic-write.ts";
4
- import { appendEvent } from "../state/event-log.ts";
4
+ import { appendEvent } from "../state/event-log/event-log.ts";
5
5
  import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
6
6
  import { logInternalError } from "../utils/internal-error.ts";
7
7
  import { sleepSync } from "../utils/sleep.ts";
@@ -12,7 +12,7 @@
12
12
  * 3. Cleans up after itself when the run completes or the session ends.
13
13
  */
14
14
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
15
- import { loadRunManifestById } from "../state/state-store.ts";
15
+ import { loadRunManifestById } from "../state/stores/state-store.ts";
16
16
  import { readCrewAgents } from "./crew-agent-records.ts";
17
17
  import { isActiveRunStatus, isLikelyOrphanedActiveRun } from "./process-status.ts";
18
18
 
@@ -15,14 +15,14 @@
15
15
  // `__test__parseAdaptivePlan` and `__test__repairAdaptivePlan` are re-exported
16
16
  // from team-runner.ts so existing test imports keep working.
17
17
  import * as fs from "node:fs";
18
- import { writeArtifact } from "../state/artifact-store.ts";
19
- import { appendEventAsync, appendEventFireAndForget } from "../state/event-log.ts";
20
- import { saveRunManifestAsync } from "../state/state-store.ts";
21
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
22
- import type { TeamConfig } from "../teams/team-config.ts";
23
- import type { WorkflowConfig, WorkflowStep } from "../workflows/workflow-config.ts";
18
+ import { appendEventAsync, appendEventFireAndForget } from "../../state/event-log/event-log.ts";
19
+ import { writeArtifact } from "../../state/stores/artifact-store.ts";
20
+ import { saveRunManifestAsync } from "../../state/stores/state-store.ts";
21
+ import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
22
+ import type { TeamConfig } from "../../teams/team-config.ts";
23
+ import type { WorkflowConfig, WorkflowStep } from "../../workflows/workflow-config.ts";
24
+ import { refreshTaskGraphQueues } from "../scheduling/task-graph-scheduler.ts";
24
25
  import { getPlanTemplate, renderPlanTemplate } from "./plan-templates.ts";
25
- import { refreshTaskGraphQueues } from "./task-graph-scheduler.ts";
26
26
 
27
27
  export interface AdaptivePlanTask {
28
28
  role: string;
@@ -557,7 +557,7 @@ export async function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput):
557
557
 
558
558
  // Test compatibility: original team-runner.ts exposed these names. Keep
559
559
  // matching exports here; team-runner.ts re-exports them so existing test
560
- // imports (`import { __test__parseAdaptivePlan } from "../../src/runtime/team-runner.ts"`)
560
+ // imports (`import { __test__parseAdaptivePlan } from "../../../src/runtime/team-runner.ts"`)
561
561
  // keep working without churn.
562
562
  export const __test__parseAdaptivePlan = parseAdaptivePlan;
563
563
  export const __test__repairAdaptivePlan = repairAdaptivePlan;
@@ -24,23 +24,23 @@
24
24
 
25
25
  import { randomBytes } from "node:crypto";
26
26
  import type { TSchema } from "@sinclair/typebox";
27
- import type { AgentConfig } from "../agents/agent-config.ts";
28
- import { allAgents, discoverAgents } from "../agents/discover-agents.ts";
29
- import { writeArtifact } from "../state/artifact-store.ts";
30
- import { appendEvent } from "../state/event-log.ts";
31
- import { appendMailboxMessage, readMailbox } from "../state/mailbox.ts";
32
- import type { TeamRunManifest } from "../state/types.ts";
33
- import type { TeamConfig } from "../teams/team-config.ts";
34
- import { logInternalError } from "../utils/internal-error.ts";
35
- import { cleanupAgentWorktreeAsync, prepareAgentWorktreeAsync } from "../worktree/worktree-manager.ts";
36
- import type { DwfCheckpointState } from "./dwf-state-store.ts";
37
- import { mapConcurrent } from "./parallel-utils.ts";
38
- import { parsePiJsonOutput } from "./pi-json-output.ts";
27
+ import type { AgentConfig } from "../../agents/agent-config.ts";
28
+ import { allAgents, discoverAgents } from "../../agents/discover-agents.ts";
29
+ import { appendMailboxMessage, readMailbox } from "../../state/coordination/mailbox.ts";
30
+ import { appendEvent } from "../../state/event-log/event-log.ts";
31
+ import { writeArtifact } from "../../state/stores/artifact-store.ts";
32
+ import type { TeamRunManifest } from "../../state/types.ts";
33
+ import type { TeamConfig } from "../../teams/team-config.ts";
34
+ import { logInternalError } from "../../utils/internal-error.ts";
35
+ import { cleanupAgentWorktreeAsync, prepareAgentWorktreeAsync } from "../../worktree/worktree-manager.ts";
36
+ import type { DwfCheckpointState } from "../dwf-state-store.ts";
37
+ import { parsePiJsonOutput } from "../output/pi-json-output.ts";
38
+ import { extractStructuredResult } from "../output/result-extractor.ts";
39
+ import { executeWithRetry } from "../recovery/retry-executor.ts";
40
+ import { runWorker } from "../run-worker.ts";
41
+ import { mapConcurrent } from "../scheduling/parallel-utils.ts";
42
+ import { Semaphore } from "../scheduling/semaphore.ts";
39
43
  import { renderPlanTemplate } from "./plan-templates.ts";
40
- import { extractStructuredResult } from "./result-extractor.ts";
41
- import { executeWithRetry } from "./retry-executor.ts";
42
- import { runWorker } from "./run-worker.ts";
43
- import { Semaphore } from "./semaphore.ts";
44
44
 
45
45
  export interface AgentCallOpts {
46
46
  prompt: string;
@@ -20,22 +20,22 @@
20
20
  import { readFileSync } from "node:fs";
21
21
  import { join } from "node:path";
22
22
  import { transformSync } from "esbuild";
23
- import { writeArtifact } from "../state/artifact-store.ts";
24
- import { appendEvent } from "../state/event-log.ts";
25
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
26
- import { logInternalError } from "../utils/internal-error.ts";
27
- import { packageRoot, projectCrewRoot, userPiRoot } from "../utils/paths.ts";
28
- import { resolveRealContainedPath } from "../utils/safe-paths.ts";
29
- import type { DynamicWorkflowConfig } from "../workflows/workflow-config.ts";
30
- import { assertDeterministicScript, isDeterminismCheckEnabled } from "./deterministic-ast.ts";
31
- import { DwfStore } from "./dwf-state-store.ts";
23
+ import { appendEvent } from "../../state/event-log/event-log.ts";
24
+ import { writeArtifact } from "../../state/stores/artifact-store.ts";
25
+ import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
26
+ import { logInternalError } from "../../utils/internal-error.ts";
27
+ import { packageRoot, projectCrewRoot, userPiRoot } from "../../utils/paths.ts";
28
+ import { resolveRealContainedPath } from "../../utils/safe-paths.ts";
29
+ import type { DynamicWorkflowConfig } from "../../workflows/workflow-config.ts";
30
+ import { assertDeterministicScript, isDeterminismCheckEnabled } from "../deterministic-ast.ts";
31
+ import { DwfStore } from "../dwf-state-store.ts";
32
32
  import { getWorkflowFinalResult, getWorkflowPhaseState, makeWorkflowCtx } from "./dynamic-workflow-context.ts";
33
33
 
34
34
  export interface RunDynamicWorkflowInput {
35
35
  manifest: TeamRunManifest;
36
36
  workflow: DynamicWorkflowConfig;
37
37
  /** Optional team for role resolution (G4 tier 2). */
38
- team?: import("../teams/team-config.ts").TeamConfig;
38
+ team?: import("../../teams/team-config.ts").TeamConfig;
39
39
  signal: AbortSignal;
40
40
  concurrency?: number;
41
41
  modelOverride?: string;
@@ -18,9 +18,9 @@
18
18
  * without breaking a legitimately-no-op run.
19
19
  */
20
20
  import { spawnSync } from "node:child_process";
21
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
22
- import { findRepoRoot } from "../utils/paths.ts";
23
- import type { WorkflowConfig } from "../workflows/workflow-config.ts";
21
+ import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
22
+ import { findRepoRoot } from "../../utils/paths.ts";
23
+ import type { WorkflowConfig } from "../../workflows/workflow-config.ts";
24
24
 
25
25
  /**
26
26
  * Roles whose job is to EDIT project source/test files (changes that appear in