pi-crew 0.9.53 → 0.9.55

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 (493) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/package.json +6 -3
  3. package/scripts/clean-strip-types.mjs +60 -0
  4. package/src/adapters/claude-adapter.ts +23 -0
  5. package/src/adapters/codex-adapter.ts +21 -0
  6. package/src/adapters/cursor-adapter.ts +17 -0
  7. package/src/adapters/export-util.ts +143 -0
  8. package/src/adapters/index.ts +15 -0
  9. package/src/adapters/registry.ts +18 -0
  10. package/src/adapters/types.ts +23 -0
  11. package/src/agents/agent-config.ts +194 -0
  12. package/src/agents/agent-search.ts +98 -0
  13. package/src/agents/agent-serializer.ts +38 -0
  14. package/src/agents/discover-agents.ts +623 -0
  15. package/src/benchmark/benchmark-runner.ts +313 -0
  16. package/src/benchmark/feedback-loop.ts +73 -0
  17. package/src/config/config.ts +1270 -0
  18. package/src/config/defaults.ts +193 -0
  19. package/src/config/drift-detector.ts +290 -0
  20. package/src/config/markers.ts +330 -0
  21. package/src/config/resilient-parser.ts +117 -0
  22. package/src/config/role-tools.ts +118 -0
  23. package/src/config/suggestions.ts +75 -0
  24. package/src/config/types.ts +280 -0
  25. package/src/errors.ts +194 -0
  26. package/src/extension/action-suggestions.ts +117 -0
  27. package/src/extension/async-notifier.ts +179 -0
  28. package/src/extension/autonomous-policy.ts +209 -0
  29. package/src/extension/command-completions.ts +120 -0
  30. package/src/extension/context-status-injection.ts +185 -0
  31. package/src/extension/crew-autocomplete.ts +131 -0
  32. package/src/extension/crew-cleanup.ts +168 -0
  33. package/src/extension/crew-input-router.ts +93 -0
  34. package/src/extension/crew-shortcuts.ts +87 -0
  35. package/src/extension/crew-vibes/cat-frames.ts +18 -0
  36. package/src/extension/crew-vibes/config.ts +195 -0
  37. package/src/extension/crew-vibes/figures.ts +101 -0
  38. package/src/extension/crew-vibes/font-detect.ts +71 -0
  39. package/src/extension/crew-vibes/footer.ts +292 -0
  40. package/src/extension/crew-vibes/index.ts +432 -0
  41. package/src/extension/crew-vibes/provider-usage.ts +396 -0
  42. package/src/extension/crew-vibes/render.ts +206 -0
  43. package/src/extension/crew-vibes/speed.ts +286 -0
  44. package/src/extension/cross-extension-rpc.ts +350 -0
  45. package/src/extension/help.ts +62 -0
  46. package/src/extension/import-index.ts +74 -0
  47. package/src/extension/knowledge-injection.ts +402 -0
  48. package/src/extension/management.ts +571 -0
  49. package/src/extension/message-renderers.ts +108 -0
  50. package/src/extension/notification-router.ts +152 -0
  51. package/src/extension/notification-sink.ts +54 -0
  52. package/src/extension/pi-api.ts +56 -0
  53. package/src/extension/plan-orchestrate.ts +302 -0
  54. package/src/extension/project-init.ts +170 -0
  55. package/src/extension/register.ts +113 -0
  56. package/src/extension/registration/artifact-cleanup.ts +20 -0
  57. package/src/extension/registration/command-registration.ts +58 -0
  58. package/src/extension/registration/command-utils.ts +58 -0
  59. package/src/extension/registration/commands.ts +1228 -0
  60. package/src/extension/registration/compaction-guard.ts +333 -0
  61. package/src/extension/registration/context-builder.ts +135 -0
  62. package/src/extension/registration/crash-recovery-cache.ts +54 -0
  63. package/src/extension/registration/foreground-run-controller.ts +238 -0
  64. package/src/extension/registration/hook-registration.ts +119 -0
  65. package/src/extension/registration/lazy-configurers.ts +124 -0
  66. package/src/extension/registration/lifecycle-handlers.ts +923 -0
  67. package/src/extension/registration/lifecycle.ts +259 -0
  68. package/src/extension/registration/observability.ts +322 -0
  69. package/src/extension/registration/registration-types.ts +158 -0
  70. package/src/extension/registration/runtime-cleanup.ts +230 -0
  71. package/src/extension/registration/subagent-helpers.ts +125 -0
  72. package/src/extension/registration/subagent-manager-setup.ts +330 -0
  73. package/src/extension/registration/subagent-tools.ts +456 -0
  74. package/src/extension/registration/team-tool.ts +225 -0
  75. package/src/extension/registration/tool-registration.ts +50 -0
  76. package/src/extension/registration/ui.ts +172 -0
  77. package/src/extension/registration/viewers.ts +121 -0
  78. package/src/extension/registration/wire-cross-extension.ts +37 -0
  79. package/src/extension/result-watcher.ts +139 -0
  80. package/src/extension/rpc-hmac.ts +256 -0
  81. package/src/extension/run-bundle-schema.ts +104 -0
  82. package/src/extension/run-export.ts +97 -0
  83. package/src/extension/run-import.ts +168 -0
  84. package/src/extension/run-index.ts +131 -0
  85. package/src/extension/run-maintenance.ts +190 -0
  86. package/src/extension/session-summary.ts +18 -0
  87. package/src/extension/team-manager-command.ts +153 -0
  88. package/src/extension/team-onboard.ts +180 -0
  89. package/src/extension/team-recommendation.ts +288 -0
  90. package/src/extension/team-tool/anchor.ts +172 -0
  91. package/src/extension/team-tool/api.ts +1244 -0
  92. package/src/extension/team-tool/auto-summarize.ts +142 -0
  93. package/src/extension/team-tool/cache-control.ts +19 -0
  94. package/src/extension/team-tool/cancel.ts +337 -0
  95. package/src/extension/team-tool/chain-dispatch.ts +95 -0
  96. package/src/extension/team-tool/chain-executor.ts +379 -0
  97. package/src/extension/team-tool/config-patch.ts +50 -0
  98. package/src/extension/team-tool/context.ts +149 -0
  99. package/src/extension/team-tool/destructive-gate.ts +52 -0
  100. package/src/extension/team-tool/dispatch/automate.ts +80 -0
  101. package/src/extension/team-tool/dispatch/control.ts +42 -0
  102. package/src/extension/team-tool/dispatch/index.ts +95 -0
  103. package/src/extension/team-tool/dispatch/manage.ts +161 -0
  104. package/src/extension/team-tool/dispatch/run.ts +53 -0
  105. package/src/extension/team-tool/dispatch/status.ts +187 -0
  106. package/src/extension/team-tool/doctor.ts +431 -0
  107. package/src/extension/team-tool/explain.ts +282 -0
  108. package/src/extension/team-tool/failure-patterns.ts +118 -0
  109. package/src/extension/team-tool/goal-wrap.ts +330 -0
  110. package/src/extension/team-tool/goal.ts +556 -0
  111. package/src/extension/team-tool/handle-schedule.ts +332 -0
  112. package/src/extension/team-tool/handle-settings.ts +520 -0
  113. package/src/extension/team-tool/health-monitor.ts +481 -0
  114. package/src/extension/team-tool/inspect.ts +88 -0
  115. package/src/extension/team-tool/intent-policy.ts +45 -0
  116. package/src/extension/team-tool/lifecycle-actions.ts +615 -0
  117. package/src/extension/team-tool/orchestrate.ts +98 -0
  118. package/src/extension/team-tool/parallel-dispatch.ts +183 -0
  119. package/src/extension/team-tool/plan.ts +50 -0
  120. package/src/extension/team-tool/respond.ts +150 -0
  121. package/src/extension/team-tool/run-deadline.ts +66 -0
  122. package/src/extension/team-tool/run-not-found.ts +49 -0
  123. package/src/extension/team-tool/run.ts +1051 -0
  124. package/src/extension/team-tool/status.ts +260 -0
  125. package/src/extension/team-tool/workflow-manage.ts +261 -0
  126. package/src/extension/team-tool-types.ts +26 -0
  127. package/src/extension/team-tool.ts +750 -0
  128. package/src/extension/tool-result.ts +16 -0
  129. package/src/extension/validate-resources.ts +108 -0
  130. package/src/hooks/registry.ts +200 -0
  131. package/src/hooks/types.ts +69 -0
  132. package/src/i18n.ts +212 -0
  133. package/src/observability/correlation.ts +50 -0
  134. package/src/observability/event-bus.ts +86 -0
  135. package/src/observability/event-to-metric.ts +170 -0
  136. package/src/observability/exporters/adapter.ts +27 -0
  137. package/src/observability/exporters/otlp-exporter.ts +356 -0
  138. package/src/observability/exporters/prometheus-exporter.ts +54 -0
  139. package/src/observability/metric-registry.ts +100 -0
  140. package/src/observability/metric-retention.ts +64 -0
  141. package/src/observability/metric-sink.ts +99 -0
  142. package/src/observability/metrics-primitives.ts +219 -0
  143. package/src/plugins/plugin-define.ts +6 -0
  144. package/src/plugins/plugin-registry.ts +32 -0
  145. package/src/plugins/plugins/index.ts +3 -0
  146. package/src/plugins/plugins/nextjs.ts +19 -0
  147. package/src/plugins/plugins/vite.ts +10 -0
  148. package/src/plugins/plugins/vitest.ts +9 -0
  149. package/src/prompt/prompt-runtime.ts +380 -0
  150. package/src/runtime/adaptive-plan.ts +563 -0
  151. package/src/runtime/agent-control.ts +215 -0
  152. package/src/runtime/agent-memory.ts +81 -0
  153. package/src/runtime/agent-observability.ts +122 -0
  154. package/src/runtime/anchor-manager.ts +475 -0
  155. package/src/runtime/async-marker.ts +32 -0
  156. package/src/runtime/async-runner.ts +381 -0
  157. package/src/runtime/attention-events.ts +28 -0
  158. package/src/runtime/auto-summarize.ts +344 -0
  159. package/src/runtime/background-runner.ts +840 -0
  160. package/src/runtime/batch-barrier.ts +147 -0
  161. package/src/runtime/broker-issuer.ts +39 -0
  162. package/src/runtime/cancellation-token.ts +99 -0
  163. package/src/runtime/cancellation.ts +99 -0
  164. package/src/runtime/capability-inventory.ts +137 -0
  165. package/src/runtime/chain-parser.ts +237 -0
  166. package/src/runtime/chain-runner.ts +606 -0
  167. package/src/runtime/checkpoint.ts +291 -0
  168. package/src/runtime/child-pi-constants.ts +42 -0
  169. package/src/runtime/child-pi-kill.ts +180 -0
  170. package/src/runtime/child-pi-pool.ts +68 -0
  171. package/src/runtime/child-pi-spawn.ts +287 -0
  172. package/src/runtime/child-pi-steering.ts +128 -0
  173. package/src/runtime/child-pi-streams.ts +296 -0
  174. package/src/runtime/child-pi-transcript.ts +169 -0
  175. package/src/runtime/child-pi.ts +1105 -0
  176. package/src/runtime/coalesce-tasks.ts +268 -0
  177. package/src/runtime/code-summary.ts +292 -0
  178. package/src/runtime/command-trace.ts +105 -0
  179. package/src/runtime/compact-pipeline.ts +56 -0
  180. package/src/runtime/compact-stages/ansi-strip-stage.ts +25 -0
  181. package/src/runtime/compact-stages/blank-collapse-stage.ts +31 -0
  182. package/src/runtime/compact-stages/deduplicate-stage.ts +34 -0
  183. package/src/runtime/compact-stages/head-snap-stage.ts +57 -0
  184. package/src/runtime/compact-stages/index.ts +23 -0
  185. package/src/runtime/compact-stages/tail-capture-stage.ts +77 -0
  186. package/src/runtime/compact-stages/truncation-stage.ts +74 -0
  187. package/src/runtime/compaction-summary.ts +278 -0
  188. package/src/runtime/completion-guard.ts +207 -0
  189. package/src/runtime/concurrency.ts +58 -0
  190. package/src/runtime/crash-classification.ts +229 -0
  191. package/src/runtime/crash-recovery.ts +594 -0
  192. package/src/runtime/crew-agent-records.ts +595 -0
  193. package/src/runtime/crew-agent-runtime.ts +62 -0
  194. package/src/runtime/crew-broker-child.ts +88 -0
  195. package/src/runtime/crew-broker-client.ts +673 -0
  196. package/src/runtime/crew-broker-tokens.ts +159 -0
  197. package/src/runtime/crew-broker.ts +1304 -0
  198. package/src/runtime/crew-hooks.ts +227 -0
  199. package/src/runtime/cross-extension-rpc.ts +143 -0
  200. package/src/runtime/custom-tools/irc-tool.ts +282 -0
  201. package/src/runtime/custom-tools/submit-result-tool.ts +102 -0
  202. package/src/runtime/deadletter.ts +47 -0
  203. package/src/runtime/delivery-coordinator.ts +211 -0
  204. package/src/runtime/delta-conflict.ts +348 -0
  205. package/src/runtime/deterministic-ast.ts +161 -0
  206. package/src/runtime/diagnostic-export.ts +171 -0
  207. package/src/runtime/direct-run.ts +45 -0
  208. package/src/runtime/dwf-state-store.ts +102 -0
  209. package/src/runtime/dynamic-workflow-context.ts +1013 -0
  210. package/src/runtime/dynamic-workflow-runner.ts +325 -0
  211. package/src/runtime/effectiveness.ts +90 -0
  212. package/src/runtime/errors/crew-errors.ts +162 -0
  213. package/src/runtime/event-stream-bridge.ts +98 -0
  214. package/src/runtime/foreground-control.ts +193 -0
  215. package/src/runtime/foreground-watchdog.ts +132 -0
  216. package/src/runtime/global-worker-cap.ts +96 -0
  217. package/src/runtime/goal-achievement.ts +148 -0
  218. package/src/runtime/goal-evaluator.ts +365 -0
  219. package/src/runtime/goal-loop-runner.ts +825 -0
  220. package/src/runtime/goal-state-store.ts +219 -0
  221. package/src/runtime/green-contract.ts +55 -0
  222. package/src/runtime/group-join.ts +267 -0
  223. package/src/runtime/handoff-manager.ts +598 -0
  224. package/src/runtime/heartbeat-gradient.ts +36 -0
  225. package/src/runtime/heartbeat-watcher.ts +239 -0
  226. package/src/runtime/hidden-handoff.ts +407 -0
  227. package/src/runtime/important-line-classifier.ts +140 -0
  228. package/src/runtime/intercom-bridge.ts +187 -0
  229. package/src/runtime/iteration-hooks.ts +305 -0
  230. package/src/runtime/live-agent-control.ts +136 -0
  231. package/src/runtime/live-agent-manager.ts +704 -0
  232. package/src/runtime/live-control-realtime.ts +56 -0
  233. package/src/runtime/live-extension-bridge.ts +148 -0
  234. package/src/runtime/live-irc.ts +97 -0
  235. package/src/runtime/live-session-health.ts +108 -0
  236. package/src/runtime/live-session-runtime.ts +1146 -0
  237. package/src/runtime/loop-gates.ts +128 -0
  238. package/src/runtime/manifest-cache.ts +375 -0
  239. package/src/runtime/mcp-proxy.ts +105 -0
  240. package/src/runtime/metric-parser.ts +36 -0
  241. package/src/runtime/model-fallback.ts +409 -0
  242. package/src/runtime/model-resolver.ts +126 -0
  243. package/src/runtime/model-scope.ts +158 -0
  244. package/src/runtime/orphan-worker-registry.ts +465 -0
  245. package/src/runtime/output-validator.ts +202 -0
  246. package/src/runtime/overflow-recovery.ts +206 -0
  247. package/src/runtime/parallel-research.ts +68 -0
  248. package/src/runtime/parallel-utils.ts +160 -0
  249. package/src/runtime/parent-guard.ts +134 -0
  250. package/src/runtime/path-overlap.ts +150 -0
  251. package/src/runtime/peer-dep.ts +292 -0
  252. package/src/runtime/per-write-validator.ts +181 -0
  253. package/src/runtime/phase-progress.ts +217 -0
  254. package/src/runtime/phase-tracker.ts +385 -0
  255. package/src/runtime/pi-args.ts +655 -0
  256. package/src/runtime/pi-json-output.ts +170 -0
  257. package/src/runtime/pi-spawn.ts +273 -0
  258. package/src/runtime/pipeline-runner.ts +523 -0
  259. package/src/runtime/plan-templates.ts +201 -0
  260. package/src/runtime/policy-engine.ts +115 -0
  261. package/src/runtime/post-checks.ts +142 -0
  262. package/src/runtime/post-exit-stdio-guard.ts +109 -0
  263. package/src/runtime/process-lifecycle.ts +491 -0
  264. package/src/runtime/process-status.ts +154 -0
  265. package/src/runtime/progress-event-coalescer.ts +44 -0
  266. package/src/runtime/progress-tracker.ts +124 -0
  267. package/src/runtime/prose-compressor.ts +162 -0
  268. package/src/runtime/recovery-recipes.ts +203 -0
  269. package/src/runtime/replace.ts +570 -0
  270. package/src/runtime/resilient-edit.ts +153 -0
  271. package/src/runtime/result-extractor.ts +217 -0
  272. package/src/runtime/retry-executor.ts +109 -0
  273. package/src/runtime/retry-runner.ts +336 -0
  274. package/src/runtime/role-permission.ts +59 -0
  275. package/src/runtime/run-coalesced-task-group.ts +308 -0
  276. package/src/runtime/run-drift.ts +219 -0
  277. package/src/runtime/run-tracker.ts +116 -0
  278. package/src/runtime/run-worker.ts +78 -0
  279. package/src/runtime/runtime-policy.ts +29 -0
  280. package/src/runtime/runtime-resolver.ts +172 -0
  281. package/src/runtime/runtime-warmup.ts +160 -0
  282. package/src/runtime/scheduler.ts +353 -0
  283. package/src/runtime/semaphore.ts +141 -0
  284. package/src/runtime/sensitive-paths.ts +93 -0
  285. package/src/runtime/session-resources.ts +25 -0
  286. package/src/runtime/session-snapshot.ts +59 -0
  287. package/src/runtime/session-usage.ts +79 -0
  288. package/src/runtime/settings-store.ts +155 -0
  289. package/src/runtime/sidechain-output.ts +35 -0
  290. package/src/runtime/single-agent-compose.ts +84 -0
  291. package/src/runtime/skill-effectiveness.ts +524 -0
  292. package/src/runtime/skill-instructions.ts +394 -0
  293. package/src/runtime/stale-reconciler.ts +680 -0
  294. package/src/runtime/stream-preview.ts +184 -0
  295. package/src/runtime/streaming-output.ts +50 -0
  296. package/src/runtime/subagent-manager.ts +561 -0
  297. package/src/runtime/subprocess-tool-registry.ts +70 -0
  298. package/src/runtime/supervisor-contact.ts +64 -0
  299. package/src/runtime/task-display.ts +52 -0
  300. package/src/runtime/task-graph-scheduler.ts +227 -0
  301. package/src/runtime/task-graph.ts +290 -0
  302. package/src/runtime/task-health.ts +83 -0
  303. package/src/runtime/task-id.ts +161 -0
  304. package/src/runtime/task-output-context.ts +602 -0
  305. package/src/runtime/task-packet.ts +268 -0
  306. package/src/runtime/task-quality.ts +199 -0
  307. package/src/runtime/task-runner/capabilities.ts +78 -0
  308. package/src/runtime/task-runner/child-executor.ts +790 -0
  309. package/src/runtime/task-runner/context-retrieval.ts +163 -0
  310. package/src/runtime/task-runner/live-executor.ts +227 -0
  311. package/src/runtime/task-runner/output-splitter.ts +152 -0
  312. package/src/runtime/task-runner/post-execution.ts +480 -0
  313. package/src/runtime/task-runner/pre-execution.ts +365 -0
  314. package/src/runtime/task-runner/progress.ts +157 -0
  315. package/src/runtime/task-runner/prompt-builder.ts +278 -0
  316. package/src/runtime/task-runner/prompt-pipeline.ts +88 -0
  317. package/src/runtime/task-runner/result-utils.ts +16 -0
  318. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  319. package/src/runtime/task-runner/run-projection.ts +125 -0
  320. package/src/runtime/task-runner/scaffold-executor.ts +25 -0
  321. package/src/runtime/task-runner/state-helpers.ts +176 -0
  322. package/src/runtime/task-runner/tail-read.ts +34 -0
  323. package/src/runtime/task-runner.ts +216 -0
  324. package/src/runtime/team-runner-artifacts.ts +13 -0
  325. package/src/runtime/team-runner.ts +2396 -0
  326. package/src/runtime/tool-output-pruner.ts +333 -0
  327. package/src/runtime/tool-progress.ts +278 -0
  328. package/src/runtime/usage-tracker.ts +73 -0
  329. package/src/runtime/verification-gates.ts +579 -0
  330. package/src/runtime/verification-integrity.ts +108 -0
  331. package/src/runtime/verification-worktree.ts +186 -0
  332. package/src/runtime/worker-heartbeat.ts +25 -0
  333. package/src/runtime/worker-startup.ts +83 -0
  334. package/src/runtime/workflow-state.ts +195 -0
  335. package/src/runtime/workspace-lock.ts +443 -0
  336. package/src/runtime/workspace-tree.ts +312 -0
  337. package/src/runtime/yield-handler.ts +224 -0
  338. package/src/runtime/zombie-scanner.ts +298 -0
  339. package/src/schema/config-schema.ts +327 -0
  340. package/src/schema/team-tool-schema.ts +492 -0
  341. package/src/schema/validation-types.ts +159 -0
  342. package/src/skills/discover-skills.ts +203 -0
  343. package/src/skills/skill-templates.ts +456 -0
  344. package/src/skills/validate.ts +285 -0
  345. package/src/state/active-run-registry.ts +439 -0
  346. package/src/state/artifact-store.ts +176 -0
  347. package/src/state/atomic-write.ts +970 -0
  348. package/src/state/blob-store.ts +308 -0
  349. package/src/state/contracts.ts +160 -0
  350. package/src/state/crew-init.ts +269 -0
  351. package/src/state/decision-ledger.ts +372 -0
  352. package/src/state/event-log-rotation.ts +399 -0
  353. package/src/state/event-log.ts +1465 -0
  354. package/src/state/event-reconstructor.ts +229 -0
  355. package/src/state/gitignore-manager.ts +46 -0
  356. package/src/state/health-store.ts +79 -0
  357. package/src/state/hook-instinct-bridge.ts +94 -0
  358. package/src/state/hook-integrations.ts +51 -0
  359. package/src/state/instinct-store.ts +275 -0
  360. package/src/state/jsonl-writer.ts +107 -0
  361. package/src/state/locks.ts +562 -0
  362. package/src/state/mailbox.ts +916 -0
  363. package/src/state/observation-store.ts +176 -0
  364. package/src/state/run-cache.ts +193 -0
  365. package/src/state/run-graph.ts +183 -0
  366. package/src/state/run-metrics.ts +165 -0
  367. package/src/state/schedule.ts +166 -0
  368. package/src/state/session-state-map.ts +51 -0
  369. package/src/state/state-store.ts +973 -0
  370. package/src/state/task-claims.ts +61 -0
  371. package/src/state/tiered-eval.ts +480 -0
  372. package/src/state/types-eval.ts +58 -0
  373. package/src/state/types.ts +447 -0
  374. package/src/state/usage.ts +138 -0
  375. package/src/state/worker-atomic-writer.ts +198 -0
  376. package/src/subagents/async-entry.ts +1 -0
  377. package/src/subagents/index.ts +3 -0
  378. package/src/subagents/live/control.ts +1 -0
  379. package/src/subagents/live/manager.ts +1 -0
  380. package/src/subagents/live/realtime.ts +1 -0
  381. package/src/subagents/live/session-runtime.ts +1 -0
  382. package/src/subagents/manager.ts +1 -0
  383. package/src/subagents/spawn.ts +1 -0
  384. package/src/teams/discover-teams.ts +187 -0
  385. package/src/teams/team-config.ts +27 -0
  386. package/src/teams/team-serializer.ts +38 -0
  387. package/src/tools/safe-bash-extension.ts +54 -0
  388. package/src/tools/safe-bash.ts +505 -0
  389. package/src/types/diff.d.ts +18 -0
  390. package/src/types/new-api-types.ts +35 -0
  391. package/src/ui/agent-management-overlay.ts +160 -0
  392. package/src/ui/card-colors.ts +139 -0
  393. package/src/ui/crew-footer.ts +102 -0
  394. package/src/ui/crew-select-list.ts +112 -0
  395. package/src/ui/dashboard-panes/agents-pane.ts +164 -0
  396. package/src/ui/dashboard-panes/cancellation-pane.ts +66 -0
  397. package/src/ui/dashboard-panes/capability-pane.ts +77 -0
  398. package/src/ui/dashboard-panes/health-pane.ts +31 -0
  399. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -0
  400. package/src/ui/dashboard-panes/metrics-pane.ts +37 -0
  401. package/src/ui/dashboard-panes/progress-pane.ts +38 -0
  402. package/src/ui/dashboard-panes/transcript-pane.ts +10 -0
  403. package/src/ui/deploy-bundled-themes.ts +71 -0
  404. package/src/ui/dwf-phase-display.ts +151 -0
  405. package/src/ui/dynamic-border.ts +35 -0
  406. package/src/ui/format-helpers.ts +31 -0
  407. package/src/ui/heartbeat-aggregator.ts +74 -0
  408. package/src/ui/key-utils.ts +42 -0
  409. package/src/ui/keybinding-map.ts +248 -0
  410. package/src/ui/layout-primitives.ts +106 -0
  411. package/src/ui/live-conversation-overlay.ts +183 -0
  412. package/src/ui/live-duration.ts +55 -0
  413. package/src/ui/live-run-sidebar.ts +293 -0
  414. package/src/ui/loaders.ts +6 -0
  415. package/src/ui/mascot.ts +449 -0
  416. package/src/ui/overlays/agent-picker-overlay.ts +66 -0
  417. package/src/ui/overlays/confirm-overlay.ts +60 -0
  418. package/src/ui/overlays/help-overlay.ts +177 -0
  419. package/src/ui/overlays/mailbox-compose-overlay.ts +181 -0
  420. package/src/ui/overlays/mailbox-compose-preview.ts +78 -0
  421. package/src/ui/overlays/mailbox-detail-overlay.ts +155 -0
  422. package/src/ui/pi-ui-compat.ts +68 -0
  423. package/src/ui/powerbar-publisher.ts +459 -0
  424. package/src/ui/render-coalescer.ts +101 -0
  425. package/src/ui/render-diff.ts +160 -0
  426. package/src/ui/render-scheduler.ts +278 -0
  427. package/src/ui/run-action-dispatcher.ts +182 -0
  428. package/src/ui/run-dashboard.ts +910 -0
  429. package/src/ui/run-event-bus.ts +381 -0
  430. package/src/ui/run-snapshot-cache.ts +1057 -0
  431. package/src/ui/settings-overlay.ts +1067 -0
  432. package/src/ui/shared-overlay-scheduler.ts +96 -0
  433. package/src/ui/snapshot-types.ts +90 -0
  434. package/src/ui/spinner.ts +17 -0
  435. package/src/ui/status-colors.ts +143 -0
  436. package/src/ui/syntax-highlight.ts +136 -0
  437. package/src/ui/terminal-status.ts +269 -0
  438. package/src/ui/theme-adapter.ts +271 -0
  439. package/src/ui/theme-discovery.ts +199 -0
  440. package/src/ui/tool-progress-formatter.ts +93 -0
  441. package/src/ui/tool-renderers/brief-mode.ts +225 -0
  442. package/src/ui/tool-renderers/index.ts +726 -0
  443. package/src/ui/transcript-cache.ts +128 -0
  444. package/src/ui/transcript-entries.ts +256 -0
  445. package/src/ui/transcript-viewer.ts +424 -0
  446. package/src/ui/widget/index.ts +418 -0
  447. package/src/ui/widget/widget-formatters.ts +182 -0
  448. package/src/ui/widget/widget-model.ts +110 -0
  449. package/src/ui/widget/widget-renderer.ts +182 -0
  450. package/src/ui/widget/widget-types.ts +36 -0
  451. package/src/utils/bm25-search.ts +235 -0
  452. package/src/utils/completion-dedupe.ts +63 -0
  453. package/src/utils/conflict-detect.ts +668 -0
  454. package/src/utils/env-allowlist.ts +30 -0
  455. package/src/utils/env-filter.ts +155 -0
  456. package/src/utils/file-coalescer.ts +98 -0
  457. package/src/utils/fingerprint.ts +180 -0
  458. package/src/utils/frontmatter.ts +70 -0
  459. package/src/utils/fs-watch.ts +37 -0
  460. package/src/utils/gh-protocol.ts +556 -0
  461. package/src/utils/git.ts +260 -0
  462. package/src/utils/guards.ts +107 -0
  463. package/src/utils/ids.ts +24 -0
  464. package/src/utils/incremental-reader.ts +220 -0
  465. package/src/utils/internal-error.ts +10 -0
  466. package/src/utils/names.ts +36 -0
  467. package/src/utils/ndjson.ts +115 -0
  468. package/src/utils/paths.ts +227 -0
  469. package/src/utils/project-detector.ts +160 -0
  470. package/src/utils/redaction.ts +370 -0
  471. package/src/utils/resolve-shell.ts +36 -0
  472. package/src/utils/run-watcher-registry.ts +152 -0
  473. package/src/utils/safe-paths.ts +393 -0
  474. package/src/utils/scan-cache.ts +144 -0
  475. package/src/utils/session-utils.ts +110 -0
  476. package/src/utils/sleep.ts +54 -0
  477. package/src/utils/socket-path.ts +164 -0
  478. package/src/utils/sse-parser.ts +131 -0
  479. package/src/utils/task-name-generator.ts +337 -0
  480. package/src/utils/timings.ts +33 -0
  481. package/src/utils/token-counter.ts +200 -0
  482. package/src/utils/visual.ts +207 -0
  483. package/src/workflows/cost-estimator.ts +34 -0
  484. package/src/workflows/discover-workflows.ts +308 -0
  485. package/src/workflows/intermediate-store.ts +166 -0
  486. package/src/workflows/preflight-validator.ts +168 -0
  487. package/src/workflows/topology-analyzer.ts +203 -0
  488. package/src/workflows/validate-workflow.ts +50 -0
  489. package/src/workflows/workflow-config.ts +75 -0
  490. package/src/workflows/workflow-serializer.ts +32 -0
  491. package/src/worktree/branch-freshness.ts +112 -0
  492. package/src/worktree/cleanup.ts +341 -0
  493. package/src/worktree/worktree-manager.ts +1204 -0
@@ -0,0 +1,333 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import type { ArtifactDescriptor, TeamRunManifest } from "../../state/types.ts";
3
+ import { findRepoRoot } from "../../utils/paths.ts";
4
+ import { extractSessionId } from "../../utils/session-utils.ts";
5
+ import { listRecentRuns } from "../run-index.ts";
6
+
7
+ export interface RegisterCompactionGuardOptions {
8
+ foregroundControllers: Map<string | symbol, AbortController>;
9
+ foregroundTeamRunControllers: Map<string | symbol, AbortController>;
10
+ }
11
+
12
+ const TRIGGER_RATIO = 0.75;
13
+ const HARD_RATIO = 0.95;
14
+ const DEFAULT_CONTEXT_WINDOW = 200_000;
15
+ const MAX_ARTIFACT_INDEX_RUNS = 10;
16
+ const MAX_ARTIFACT_INDEX_ITEMS = 80;
17
+ /** Run statuses that mean the run is still in-flight and may need resuming. */
18
+ const IN_FLIGHT_RUN_STATUSES = new Set(["queued", "planning", "running"]);
19
+
20
+ function contextWindow(ctx: { model?: { contextWindow?: number } }): number {
21
+ const value = ctx.model?.contextWindow;
22
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_CONTEXT_WINDOW;
23
+ }
24
+
25
+ function usageRatio(ctx: {
26
+ getContextUsage(): { tokens: number | null } | undefined;
27
+ model?: { contextWindow?: number };
28
+ }): number | undefined {
29
+ const tokens = ctx.getContextUsage()?.tokens;
30
+ if (tokens === null || tokens === undefined || !Number.isFinite(tokens)) return undefined;
31
+ return tokens / contextWindow(ctx);
32
+ }
33
+
34
+ interface CrewArtifactIndexEntry {
35
+ runId: string;
36
+ status: TeamRunManifest["status"];
37
+ team: string;
38
+ workflow?: string;
39
+ goal: string;
40
+ artifact: Pick<ArtifactDescriptor, "kind" | "path" | "producer" | "sizeBytes" | "createdAt">;
41
+ }
42
+
43
+ function collectCrewArtifactIndex(cwd: string): CrewArtifactIndexEntry[] {
44
+ const entries: CrewArtifactIndexEntry[] = [];
45
+ for (const run of listRecentRuns(cwd, MAX_ARTIFACT_INDEX_RUNS)) {
46
+ for (const artifact of run.artifacts) {
47
+ entries.push({
48
+ runId: run.runId,
49
+ status: run.status,
50
+ team: run.team,
51
+ workflow: run.workflow,
52
+ goal: run.goal,
53
+ artifact: {
54
+ kind: artifact.kind,
55
+ path: artifact.path,
56
+ producer: artifact.producer,
57
+ sizeBytes: artifact.sizeBytes,
58
+ createdAt: artifact.createdAt,
59
+ },
60
+ });
61
+ if (entries.length >= MAX_ARTIFACT_INDEX_ITEMS) return entries;
62
+ }
63
+ }
64
+ return entries;
65
+ }
66
+
67
+ function formatCrewArtifactIndex(entries: CrewArtifactIndexEntry[]): string {
68
+ if (!entries.length) return "";
69
+ const lines = ["", "# pi-crew artifact index", "Preserve these run artifact references in the compaction summary:"];
70
+ for (const entry of entries) {
71
+ lines.push(
72
+ `- ${entry.artifact.kind}: ${entry.artifact.path} (run=${entry.runId}, status=${entry.status}, team=${entry.team}, workflow=${entry.workflow ?? "none"}, producer=${entry.artifact.producer})`,
73
+ );
74
+ }
75
+ return lines.join("\n");
76
+ }
77
+
78
+ /**
79
+ * Project-scope filter: keep `run` only if it belongs to the SAME repo as
80
+ * `queryCwd` (or is a user-level / legacy run with no repo). This is the
81
+ * version-independent, reliable barrier against cross-project leaks: even
82
+ * when the session-id filter below cannot fire (ctx.sessionId is absent on
83
+ * some pi versions — observed on pi 0.79.6 ExtensionContext), the cwd filter
84
+ * stops another project's in-flight runs (e.g. edge-ai-agent) from bleeding
85
+ * into this project's ambient status or compaction-resume directive.
86
+ *
87
+ * Note: listRecentRuns already scopes its filesystem scan via scopedRunRoots,
88
+ * BUT it ALSO merges the GLOBAL activeRunEntries() registry (the cross-
89
+ * project dashboard view). That global merge is intentional for the
90
+ * dashboard but wrong for "what should THIS project's session do" — hence
91
+ * this filter at the consumption site.
92
+ */
93
+ function isInProjectScope(run: TeamRunManifest, queryCwd: string): boolean {
94
+ const queryRepo = findRepoRoot(queryCwd);
95
+ if (queryRepo === undefined) return true; // viewer not in a repo → user-level view
96
+ const runRepo = typeof run.cwd === "string" && run.cwd.length > 0 ? findRepoRoot(run.cwd) : undefined;
97
+ if (runRepo === undefined) return true; // run is user-level / legacy / not a repo → include
98
+ return runRepo === queryRepo; // same project only
99
+ }
100
+
101
+ /**
102
+ * Collect in-flight (non-terminal) crew runs that must be resumable after
103
+ * compaction. These are runs the agent was actively working on or awaiting.
104
+ *
105
+ * @param cwd - project working directory (shared, per-project state root).
106
+ * @param currentSessionId - if provided, restrict to runs OWNED BY THIS
107
+ * session (`run.ownerSessionId === currentSessionId`). The state store is
108
+ * per-PROJECT, not per-SESSION — multiple sessions share `.crew/state/runs/`.
109
+ * Without this filter, Session B's compaction would pick up Session A's
110
+ * in-flight runs and wrongly resume them. Legacy runs with no
111
+ * `ownerSessionId` are excluded under filtering (strict): a run with no
112
+ * declared owner must not be auto-resumed by an arbitrary session; true
113
+ * orphans are handled separately by crash-recovery. When omitted, returns
114
+ * ALL in-flight runs (back-compat for callers that deliberately want the
115
+ * cross-session view, e.g. diagnostics).
116
+ */
117
+ export function collectInFlightRuns(cwd: string, currentSessionId?: string): TeamRunManifest[] {
118
+ return listRecentRuns(cwd, MAX_ARTIFACT_INDEX_RUNS).filter((run) => {
119
+ if (!IN_FLIGHT_RUN_STATUSES.has(run.status)) return false;
120
+ // Reliable barrier (2026-06-17): never leak another project's runs into
121
+ // THIS project's resume directive / ambient status, regardless of
122
+ // whether the session-id filter is available. This fixes the live
123
+ // cross-session leak that persisted after 4bd6f5b because ctx.sessionId
124
+ // is absent on pi 0.79.6.
125
+ if (!isInProjectScope(run, cwd)) return false;
126
+ if (currentSessionId === undefined) return true; // no session filter → back-compat (still project-scoped)
127
+ return run.ownerSessionId === currentSessionId; // strict: legacy ownerless runs excluded
128
+ });
129
+ }
130
+
131
+ /**
132
+ * Build an explicit resume directive that survives compaction. This is the
133
+ * core of O10 (compaction resilience): after compaction, the agent MUST know
134
+ * what crew tasks were in-flight and how to continue them.
135
+ */
136
+ function formatResumeDirective(runs: TeamRunManifest[]): string {
137
+ if (!runs.length) return "";
138
+ const lines = [
139
+ "",
140
+ "# pi-crew in-flight task resume directive (CRITICAL — do not drop)",
141
+ "The following pi-crew runs were in progress when the context was compacted.",
142
+ "After compaction, you MUST continue these tasks — do NOT consider them finished.",
143
+ ];
144
+ for (const run of runs) {
145
+ const wf = run.workflow ? `, workflow=${run.workflow}` : "";
146
+ lines.push(`- runId=${run.runId} (status=${run.status}, team=${run.team}${wf}): ${run.goal}`);
147
+ }
148
+ lines.push("");
149
+ lines.push("To resume: call the `team` tool with action='status' to check progress, then");
150
+ lines.push("action='wait' (to join a still-running task) or action='summary' / action='get'");
151
+ lines.push("to retrieve results. If a task was mid-execution and the worker is still alive,");
152
+ lines.push("it continues independently — just re-attach. Do not restart completed work.");
153
+ return lines.join("\n");
154
+ }
155
+
156
+ /**
157
+ * Build a short continuation prompt for sendUserMessage. This is what actually
158
+ * makes the agent resume after compaction — Pi's threshold compaction does NOT
159
+ * auto-retry (it stops and waits for user input). By injecting this as a user
160
+ * message that triggers a turn, the agent automatically continues the in-flight
161
+ * crew task instead of stalling until the user types "continue".
162
+ */
163
+ export function buildContinuationPrompt(runs: TeamRunManifest[]): string {
164
+ if (!runs.length) return "";
165
+ const lines = ["[pi-crew] Context was compacted while crew tasks were still in-flight. Continue the work — do not wait for me."];
166
+ for (const run of runs) {
167
+ const wf = run.workflow ? `, workflow=${run.workflow}` : "";
168
+ lines.push(`- runId=${run.runId} (status=${run.status}, team=${run.team}${wf}): ${run.goal}`);
169
+ }
170
+ lines.push("");
171
+ lines.push(
172
+ "Resume: call `team` with action='status' to check progress, then action='wait' (join a running task), action='summary', or action='get' as appropriate. If a worker is still alive it continues independently — just re-attach. Do NOT restart completed work.",
173
+ );
174
+ return lines.join("\n");
175
+ }
176
+
177
+ /**
178
+ * Trigger automatic agent continuation after compaction. Fire-and-forget the
179
+ * promise — never block the compaction flow. The sendUserMessage type is
180
+ * declared `void` but the runtime returns a Promise (it triggers an agent turn).
181
+ *
182
+ * During compaction the agent may still be mid-processing, so Pi can reject
183
+ * the queued message with "Agent is already processing a prompt...". This is
184
+ * BENIGN — the in-flight worker continues independently regardless — so we
185
+ * detect that specific race and downgrade it to a silent debug log instead of
186
+ * surfacing a scary warning to the user. Other errors still notify.
187
+ */
188
+ export function triggerContinuation(pi: ExtensionAPI, ctx: ExtensionContext, runs: TeamRunManifest[]): void {
189
+ if (!runs.length) return;
190
+ const prompt = buildContinuationPrompt(runs);
191
+ const isBenignProcessingRace = (err: unknown): boolean => {
192
+ const msg = err instanceof Error ? err.message : String(err ?? "");
193
+ return /already processing a prompt/i.test(msg) || /use steer\(\) or followUp\(\)/i.test(msg);
194
+ };
195
+ try {
196
+ const result = pi.sendUserMessage(prompt) as unknown;
197
+ Promise.resolve(result).catch((err: unknown) => {
198
+ // Benign race: the worker keeps running independently — no need to alarm.
199
+ if (isBenignProcessingRace(err)) return;
200
+ // Real failure: surface a hint so the user can resume manually.
201
+ try {
202
+ ctx.ui.notify("pi-crew: auto-continuation after compaction failed — use team status to resume manually.", "warning");
203
+ } catch {
204
+ // swallow
205
+ }
206
+ });
207
+ } catch (err: unknown) {
208
+ // Synchronous throw — same benign-race handling.
209
+ if (isBenignProcessingRace(err)) return;
210
+ // best-effort
211
+ }
212
+ }
213
+
214
+ /** Combined customInstructions injected into proactive compaction summaries. */
215
+ function buildCompactionInstructions(cwd: string, currentSessionId?: string): string {
216
+ const artifactIndex = collectCrewArtifactIndex(cwd);
217
+ const inFlight = collectInFlightRuns(cwd, currentSessionId);
218
+ const parts = [
219
+ "Prioritize keeping pi-crew run state, task results, artifact references, run IDs, and next actions. Keep completed-task detail concise.",
220
+ ];
221
+ if (artifactIndex.length > 0) parts.push(formatCrewArtifactIndex(artifactIndex));
222
+ if (inFlight.length > 0) parts.push(formatResumeDirective(inFlight));
223
+ return parts.join("\n");
224
+ }
225
+
226
+ export function registerCompactionGuard(pi: ExtensionAPI, options: RegisterCompactionGuardOptions): void {
227
+ let pendingCompactReason: string | null = null;
228
+ let compactionInProgress = false;
229
+
230
+ const startCompact = (ctx: ExtensionContext, reason: string): void => {
231
+ if (compactionInProgress) return;
232
+ compactionInProgress = true;
233
+ const sessionId = extractSessionId(ctx);
234
+ const customInstructions = buildCompactionInstructions(ctx.cwd, sessionId);
235
+ // Append a durable resume entry so it appears in the post-compaction
236
+ // context regardless of how summarization treats customInstructions.
237
+ const inFlight = collectInFlightRuns(ctx.cwd, sessionId);
238
+ if (inFlight.length > 0) {
239
+ pi.appendEntry("crew:resume-directive", {
240
+ reason,
241
+ createdAt: new Date().toISOString(),
242
+ runs: inFlight.map((r) => ({
243
+ runId: r.runId,
244
+ status: r.status,
245
+ team: r.team,
246
+ workflow: r.workflow,
247
+ goal: r.goal,
248
+ })),
249
+ });
250
+ }
251
+ ctx.compact({
252
+ customInstructions,
253
+ onComplete: () => {
254
+ compactionInProgress = false;
255
+ // O10 FIX: Pi's threshold compaction does NOT auto-retry — it
256
+ // stops and waits for user input. Trigger automatic
257
+ // continuation so the agent resumes the in-flight crew task.
258
+ const runs = collectInFlightRuns(ctx.cwd, extractSessionId(ctx));
259
+ triggerContinuation(pi, ctx, runs);
260
+ ctx.ui.notify(reason === "deferred" ? "Deferred compaction completed" : "Auto-compacted context during team run", "info");
261
+ },
262
+ onError: (error) => {
263
+ compactionInProgress = false;
264
+ ctx.ui.notify(`${reason === "deferred" ? "Deferred" : "Auto"} compaction failed: ${error.message}`, "error");
265
+ },
266
+ });
267
+ };
268
+
269
+ // Allow compaction to proceed. pi-crew state is preserved via the
270
+ // customInstructions + resume-directive entry appended in startCompact,
271
+ // and re-injected post-compaction by the session_compact handler below.
272
+ pi.on("session_before_compact", async (_event, _ctx) => {
273
+ return;
274
+ });
275
+
276
+ // O10: After ANY compaction (proactive OR reactive/Pi-triggered), detect
277
+ // in-flight crew runs and trigger automatic continuation. This is the
278
+ // critical fix: Pi's threshold compaction does NOT auto-retry — it stops
279
+ // and waits for user input. By injecting a continuation user message that
280
+ // triggers a turn, the agent automatically resumes the in-flight crew task.
281
+ // This covers the common case where Pi auto-compacts without going through
282
+ // our proactive startCompact path.
283
+ pi.on("session_compact", (_event, ctx) => {
284
+ try {
285
+ const sessionId = extractSessionId(ctx);
286
+ const inFlight = collectInFlightRuns(ctx.cwd, sessionId);
287
+ if (inFlight.length === 0) return;
288
+ // Re-append the resume directive entry for durable record.
289
+ pi.appendEntry("crew:resume-directive", {
290
+ reason: "post-compaction-continuation",
291
+ createdAt: new Date().toISOString(),
292
+ runs: inFlight.map((r) => ({
293
+ runId: r.runId,
294
+ status: r.status,
295
+ team: r.team,
296
+ workflow: r.workflow,
297
+ goal: r.goal,
298
+ })),
299
+ });
300
+ ctx.ui.notify(`Context compacted. ${inFlight.length} pi-crew run(s) still in-flight — auto-resuming.`, "info");
301
+ // THE FIX: trigger automatic continuation. Without this, Pi stops
302
+ // after threshold compaction and the user must type "continue".
303
+ triggerContinuation(pi, ctx, inFlight);
304
+ } catch {
305
+ // best-effort: never block compaction completion
306
+ }
307
+ });
308
+
309
+ // Proactive compaction with dynamic threshold.
310
+ pi.on("turn_end", (_event, ctx) => {
311
+ if (compactionInProgress) return;
312
+ const hasActiveForeground = options.foregroundControllers.size > 0 || options.foregroundTeamRunControllers.size > 0;
313
+ const ratio = usageRatio(ctx);
314
+ // If deferred compaction is pending and foreground just ended, check if still needed
315
+ if (!hasActiveForeground && pendingCompactReason) {
316
+ pendingCompactReason = null;
317
+ if (ratio === undefined || ratio < TRIGGER_RATIO) return;
318
+ startCompact(ctx, "deferred");
319
+ return;
320
+ }
321
+ if (ratio === undefined || ratio < TRIGGER_RATIO) return;
322
+ // During foreground run: defer unless context is critically full
323
+ if (hasActiveForeground) {
324
+ if (ratio >= HARD_RATIO) {
325
+ startCompact(ctx, "critical");
326
+ } else {
327
+ pendingCompactReason = "threshold-during-foreground-run";
328
+ }
329
+ return;
330
+ }
331
+ startCompact(ctx, "threshold");
332
+ });
333
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * RegistrationContext builder.
3
+ *
4
+ * Pure construction of the mutable state bag passed to every install*
5
+ * helper under `./registration/`. Kept in its own file because the
6
+ * initialization is verbose (every field of the orchestrator's state
7
+ * is initialized here) and bundling it into `register.ts` would push
8
+ * that file past its size budget.
9
+ */
10
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
11
+ import { loadConfig } from "../../config/config.ts";
12
+ import { initI18n } from "../../i18n.ts";
13
+ import { BatchBarrier } from "../../runtime/batch-barrier.ts";
14
+ import { createManifestCache } from "../../runtime/manifest-cache.ts";
15
+ import { createRunSnapshotCache } from "../../ui/run-snapshot-cache.ts";
16
+ import type { CrewWidgetState } from "../../ui/widget/index.ts";
17
+ import { logInternalError } from "../../utils/internal-error.ts";
18
+ import type { AsyncNotifierState } from "../async-notifier.ts";
19
+ import type { NotificationDescriptor } from "../notification-router.ts";
20
+ import type { LifecycleState } from "./lifecycle.ts";
21
+ import type { ObservabilityState } from "./observability.ts";
22
+ import type { RegistrationContext } from "./registration-types.ts";
23
+ import { sendFollowUp } from "./subagent-helpers.ts";
24
+ import type { UiState } from "./ui.ts";
25
+
26
+ /** Module-level slot for `disposeI18n` so the cleanup helpers can find it. */
27
+ const RUNTIME_CLEANUP_STORE_KEY = Symbol("__piCrewRuntimeCleanup");
28
+
29
+ /**
30
+ * Build the mutable RegistrationContext. All state + bound closures
31
+ * that the extracted modules need are hung off this object.
32
+ *
33
+ * The shape is built once with placeholder closures for fields that the
34
+ * install* helpers under registration/ will rebind. Two of them
35
+ * (`notifyOperator`, `getManifestCache`/`getRunSnapshotCache`) are
36
+ * constructed inline because they only depend on the ctx itself, not
37
+ * on later install steps.
38
+ */
39
+ export function buildRegistrationContext(pi: ExtensionAPI): RegistrationContext {
40
+ const ctx: RegistrationContext = {
41
+ pi,
42
+ currentCtx: undefined,
43
+ sessionGeneration: 0,
44
+ cleanedUp: false,
45
+ rpcHandle: undefined,
46
+ manifestCache: createManifestCache(process.cwd()),
47
+ runSnapshotCache: createRunSnapshotCache(process.cwd()),
48
+ cacheCwd: process.cwd(),
49
+ getManifestCache: undefined as never,
50
+ getRunSnapshotCache: undefined as never,
51
+ widgetState: { frame: 0 } as CrewWidgetState,
52
+ uiState: { liveSidebarRunId: undefined, dashboardOpened: false } as UiState,
53
+ observabilityState: {
54
+ metricRegistry: undefined,
55
+ eventMetricSub: undefined,
56
+ metricSink: undefined,
57
+ heartbeatWatcher: undefined,
58
+ autoRepairTimer: undefined,
59
+ tempReconcileTimer: undefined,
60
+ otlpExporter: undefined,
61
+ } as ObservabilityState,
62
+ lifecycleState: {
63
+ notifierStarted: false,
64
+ notificationSink: undefined,
65
+ notificationRouter: undefined,
66
+ deliveryCoordinator: undefined,
67
+ overflowTracker: undefined,
68
+ } as LifecycleState,
69
+ notifierState: { seenFinishedRunIds: new Set() } as AsyncNotifierState,
70
+ foregroundControllers: new Map(),
71
+ foregroundTeamRunControllers: new Map(),
72
+ renderScheduler: undefined,
73
+ renderSchedulerUnsubscribers: [],
74
+ terminalStatus: undefined,
75
+ terminalStatusActive: false,
76
+ crewScheduler: undefined,
77
+ preloadTimer: undefined,
78
+ crewRunWatchers: undefined,
79
+ userCrewWatchers: undefined,
80
+ subagentManager: undefined as never,
81
+ batchBarrier: new BatchBarrier(),
82
+ crewAutocompleteRegistered: false,
83
+ autoRecoveryLast: new Map(),
84
+ AUTO_RECOVERY_LAST_MAX_ENTRIES: 1000,
85
+ disposeI18n: initI18n(pi),
86
+ globalStore: globalThis as Record<string | symbol, unknown>,
87
+ runtimeCleanupStoreKey: RUNTIME_CLEANUP_STORE_KEY,
88
+ captureSessionGeneration: () => ctx.sessionGeneration,
89
+ isOwnerSessionCurrent: (gen) => !ctx.cleanedUp && (gen === undefined || gen === ctx.sessionGeneration),
90
+ isContextCurrent: (c, gen) => !ctx.cleanedUp && ctx.currentCtx === c && ctx.sessionGeneration === gen,
91
+ telemetryEnabled: () => loadConfig(ctx.currentCtx?.cwd ?? process.cwd()).config.telemetry?.enabled !== false,
92
+ notifyOperator: undefined as never,
93
+ cleanupSessionResourcesOnly: () => {},
94
+ cleanupRuntime: () => {},
95
+ disposeRenderSchedulerSubscriptions: () => {},
96
+ stopSessionBoundSubagents: () => {},
97
+ configureNotifications: () => {},
98
+ configureObservability: () => {},
99
+ configureDeliveryCoordinator: () => {},
100
+ importCrashRecovery: undefined as never,
101
+ purgeStaleActiveRunIndexSyncIfLoaded: () => {},
102
+ startForegroundRun: undefined as never,
103
+ abortForegroundRun: () => false,
104
+ openLiveSidebar: () => {},
105
+ // Phase 0 inter-pi broker controller. Initially undefined; register.ts
106
+ // replaces this with a real controller (or no-op) after lifecycle
107
+ // handlers are installed.
108
+ brokerController: undefined,
109
+ };
110
+
111
+ ctx.notifyOperator = (notification: NotificationDescriptor): void => {
112
+ try {
113
+ ctx.lifecycleState.notificationRouter?.enqueue(notification);
114
+ } catch (error) {
115
+ logInternalError("register.notification", error);
116
+ void sendFollowUp(pi, [notification.title, notification.body].filter((line): line is string => Boolean(line)).join("\n"));
117
+ }
118
+ };
119
+
120
+ ctx.getManifestCache = (cwd: string) => {
121
+ if (ctx.manifestCache && ctx.cacheCwd === cwd) return ctx.manifestCache;
122
+ if (ctx.manifestCache) ctx.manifestCache.dispose();
123
+ if (ctx.runSnapshotCache) ctx.runSnapshotCache.dispose?.();
124
+ ctx.cacheCwd = cwd;
125
+ ctx.manifestCache = createManifestCache(cwd);
126
+ ctx.runSnapshotCache = createRunSnapshotCache(cwd);
127
+ return ctx.manifestCache;
128
+ };
129
+ ctx.getRunSnapshotCache = (cwd: string) => {
130
+ if (ctx.cacheCwd !== cwd) ctx.getManifestCache(cwd);
131
+ return ctx.runSnapshotCache;
132
+ };
133
+
134
+ return ctx;
135
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Crash-recovery lazy import + sync purge helper.
3
+ *
4
+ * The session_start handler needs `cancelOrphanedRuns` and
5
+ * `purgeStaleActiveRunIndex` from runtime/crash-recovery.ts, but that
6
+ * module is ~14 KB and only relevant on the orphan-cleanup path.
7
+ *
8
+ * `importCrashRecovery` defers the actual `import()` until first use,
9
+ * caches the result on a module-level slot, and `purgeStaleActiveRunIndexSyncIfLoaded`
10
+ * fires the purge only if the cache has been populated (cleanup runs
11
+ * synchronously and may not have triggered the lazy import yet).
12
+ *
13
+ * Module-level cache is intentional: it survives across multiple
14
+ * `registerPiTeams` calls during dev hot-reload, so we don't reload
15
+ * the heavy crash-recovery module on every reload.
16
+ */
17
+ import type {
18
+ cancelOrphanedRuns as CancelOrphanedRunsFn,
19
+ detectInterruptedRuns as DetectInterruptedRunsFn,
20
+ purgeStaleActiveRunIndex as PurgeStaleActiveRunIndexFn,
21
+ } from "../../runtime/crash-recovery.ts";
22
+ import { logInternalError } from "../../utils/internal-error.ts";
23
+
24
+ export type CrashRecoveryCache = {
25
+ cancelOrphanedRuns: typeof CancelOrphanedRunsFn;
26
+ detectInterruptedRuns: typeof DetectInterruptedRunsFn;
27
+ purgeStaleActiveRunIndex: typeof PurgeStaleActiveRunIndexFn;
28
+ };
29
+
30
+ let _cachedCrashRecovery: CrashRecoveryCache | undefined;
31
+
32
+ /** Lazy-import crash-recovery. Cached after first call. */
33
+ export async function importCrashRecovery(): Promise<CrashRecoveryCache> {
34
+ if (!_cachedCrashRecovery) {
35
+ // LAZY: defer crash-recovery (~14 KB) until session_start cleanup runs.
36
+ const mod = await import("../../runtime/crash-recovery.ts");
37
+ _cachedCrashRecovery = {
38
+ cancelOrphanedRuns: mod.cancelOrphanedRuns,
39
+ detectInterruptedRuns: mod.detectInterruptedRuns,
40
+ purgeStaleActiveRunIndex: mod.purgeStaleActiveRunIndex,
41
+ };
42
+ }
43
+ return _cachedCrashRecovery;
44
+ }
45
+
46
+ /** Sync purge-if-loaded helper used by cleanup functions. */
47
+ export function purgeStaleActiveRunIndexSyncIfLoaded(): void {
48
+ if (!_cachedCrashRecovery) return;
49
+ try {
50
+ _cachedCrashRecovery.purgeStaleActiveRunIndex();
51
+ } catch (error) {
52
+ logInternalError("register.cleanupRuntime.purgeStale", error);
53
+ }
54
+ }