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,380 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
4
+ import { startChildBrokerClient } from "../runtime/crew-broker-child.ts";
5
+ import { logInternalError } from "../utils/internal-error.ts";
6
+ import { resolveRealContainedPath } from "../utils/safe-paths.ts";
7
+
8
+ export const PI_TEAMS_INHERIT_PROJECT_CONTEXT_ENV = "PI_TEAMS_INHERIT_PROJECT_CONTEXT";
9
+ export const PI_TEAMS_INHERIT_SKILLS_ENV = "PI_TEAMS_INHERIT_SKILLS";
10
+ export const PI_CREW_INHERIT_PROJECT_CONTEXT_ENV = "PI_CREW_INHERIT_PROJECT_CONTEXT";
11
+ export const PI_CREW_INHERIT_SKILLS_ENV = "PI_CREW_INHERIT_SKILLS";
12
+ const PI_CREW_MAX_OUTPUT_ENV = "PI_CREW_MAX_OUTPUT";
13
+ const PI_CREW_STEERING_FILE_ENV = "PI_CREW_STEERING_FILE";
14
+
15
+ const PROJECT_CONTEXT_HEADER = "\n\n# Project Context\n\nProject-specific instructions and guidelines:\n\n";
16
+ const SKILLS_HEADER = "\n\nThe following skills provide specialized instructions for specific tasks.";
17
+ const DATE_HEADER = "\nCurrent date:";
18
+
19
+ // ── FIX-02: Steering content sanitization limits ──────────────────────────
20
+ // Bounded to keep a malformed/malicious steer entry from blowing up the
21
+ // worker's prompt budget or smuggling control sequences into the agent.
22
+ const MAX_STEER_MESSAGE_LENGTH = 4096;
23
+ const MAX_STEER_MESSAGE_NEWLINES = 50;
24
+ // C0 control characters minus the printable whitespace (\t \n \r). These
25
+ // are the bytes most useful for ANSI escapes, terminal-control tricks, and
26
+ // NUL-injection attacks when steer content reaches the worker's UI.
27
+ const STEER_CONTROL_CHAR_PATTERN = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/;
28
+
29
+ export interface SteerSanitizeResult {
30
+ valid: boolean;
31
+ reason?: string;
32
+ message?: string;
33
+ }
34
+
35
+ export interface SteerEntry {
36
+ type?: string;
37
+ message?: string;
38
+ /** Message id. Present in entries the broker writes; absent in legacy
39
+ * entries pre-dating the broker id-forwarding change. */
40
+ id?: string;
41
+ }
42
+
43
+ // ── FIX-S1: Cross-channel steer dedup state ──────────────────────────────
44
+ // Both the live broker push (mailbox.message → onSteer) and the durable
45
+ // file poll (pollSteering JSONL) can deliver the SAME steer to the worker
46
+ // for two reasons:
47
+ // 1. The broker writes to BOTH the mailbox AND the steering JSONL for
48
+ // durability. A connected child receives the broker push FIRST, then
49
+ // file-poll sees the JSONL shortly after (the broker's own write is
50
+ // what populates that file).
51
+ // 2. A reconnect / catch-up from a previously-disconnected child can
52
+ // re-deliver the same mailbox.message id a second time.
53
+ //
54
+ // We dedup at the recipient (worker) by tracking steer ids across BOTH
55
+ // channels in a single bounded FIFO set. Entries without an id (legacy
56
+ // JSONL rows written before S1) are NOT deduped, because they lack a
57
+ // stable identity — the file-poll path is their only delivery route.
58
+ const SEEN_STEER_ID_CAP = 1024;
59
+
60
+ /**
61
+ * Bounded FIFO seen-set for steer message ids.
62
+ *
63
+ * - `markOrSkip(undefined)` returns true (the file-poll path may emit
64
+ * legacy id-less entries; forward them).
65
+ * - `markOrSkip('a')` first call returns true; the same call again returns
66
+ * false (id already seen → drop the duplicate deliver).
67
+ * - When the cap is exceeded, the oldest id is evicted so the set stays
68
+ * bounded under long-running workers with high steer churn.
69
+ *
70
+ * Factory-shaped so multiple prompt-runtime instances (tests, parallel
71
+ * workers) get independent sets.
72
+ */
73
+ export function createSeenSteerIdSet(): { markOrSkip: (id?: string) => boolean; size: () => number } {
74
+ const seen: string[] = [];
75
+ const set = new Set<string>();
76
+ return {
77
+ markOrSkip(id?: string): boolean {
78
+ if (id === undefined) return true; // legacy steers have no id; only file-poll path can produce these
79
+ if (set.has(id)) return false;
80
+ set.add(id);
81
+ seen.push(id);
82
+ // FIFO eviction: when the cap is exceeded, drop the oldest entry.
83
+ while (seen.length > SEEN_STEER_ID_CAP) {
84
+ const oldest = seen.shift();
85
+ if (oldest !== undefined) set.delete(oldest);
86
+ }
87
+ return true;
88
+ },
89
+ size: () => set.size,
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Validate a single steering-file entry before forwarding it to
95
+ * `pi.sendMessage`. FIX-02: reject oversized payloads, excessive newlines,
96
+ * or control characters that could be used to confuse the worker UI.
97
+ */
98
+ export function sanitizeSteerMessage(entry: SteerEntry): SteerSanitizeResult {
99
+ const message = entry.message;
100
+ if (typeof message !== "string" || message.length === 0) {
101
+ return { valid: false, reason: "missing-or-empty-message" };
102
+ }
103
+ if (message.length > MAX_STEER_MESSAGE_LENGTH) {
104
+ return { valid: false, reason: `message-too-long:${message.length}` };
105
+ }
106
+ const newlineCount = (message.match(/\n/g) ?? []).length;
107
+ if (newlineCount > MAX_STEER_MESSAGE_NEWLINES) {
108
+ return { valid: false, reason: `too-many-newlines:${newlineCount}` };
109
+ }
110
+ if (STEER_CONTROL_CHAR_PATTERN.test(message)) {
111
+ return { valid: false, reason: "contains-control-characters" };
112
+ }
113
+ return { valid: true, message };
114
+ }
115
+
116
+ // ── FIX-03: Steering file path containment validation ─────────────────────
117
+ // The steering file path is inherited from the parent via env, so we
118
+ // defensively re-validate it before the first read to catch symlink
119
+ // redirection or paths that escape the session's artifacts root.
120
+ export interface SteeringFileValidation {
121
+ valid: boolean;
122
+ reason?: string;
123
+ resolvedPath?: string;
124
+ }
125
+
126
+ /**
127
+ * Validate `PI_CREW_STEERING_FILE` before first read. FIX-03:
128
+ * 1. `lstatSync` rejects a symlink at the steering file itself.
129
+ * 2. `resolveRealContainedPath` walks the ancestor chain with O_NOFOLLOW
130
+ * to reject any symlinked parent (e.g. a redirected `artifactsRoot`)
131
+ * and to verify the resolved path stays inside the derived artifacts
132
+ * root (`<artifactsRoot>/steering/<taskId>.jsonl` → `<artifactsRoot>`).
133
+ *
134
+ * Returns `{ valid: false }` with a reason on any violation. Callers must
135
+ * log + skip steering on failure rather than abort the worker.
136
+ */
137
+ export function validateSteeringFile(steeringFile: string): SteeringFileValidation {
138
+ try {
139
+ const lst = fs.lstatSync(steeringFile);
140
+ if (lst.isSymbolicLink()) {
141
+ return { valid: false, reason: "steering-file-is-symlink" };
142
+ }
143
+ } catch (error) {
144
+ const errCode = (error as NodeJS.ErrnoException).code;
145
+ if (errCode && errCode !== "ENOENT") {
146
+ return { valid: false, reason: `lstat-failed:${errCode}` };
147
+ }
148
+ }
149
+ // Layout invariant from task-runner.ts: `steeringFile` is built as
150
+ // `<artifactsRoot>/steering/<taskId>.jsonl`. We don't trust the caller
151
+ // to pass `artifactsRoot`, so derive it as 2 levels up. `resolveRealContainedPath`
152
+ // then enforces both containment AND ancestor-symlink safety in one shot.
153
+ const artifactsRoot = path.resolve(steeringFile, "..", "..");
154
+ try {
155
+ const resolved = resolveRealContainedPath(artifactsRoot, steeringFile);
156
+ return { valid: true, resolvedPath: resolved };
157
+ } catch (error) {
158
+ return {
159
+ valid: false,
160
+ reason: `path-validation-failed:${error instanceof Error ? error.message : String(error)}`,
161
+ };
162
+ }
163
+ }
164
+
165
+ function readBooleanEnv(name: string): boolean | undefined {
166
+ const value = process.env[name];
167
+ if (value === undefined) return undefined;
168
+ const normalized = value.trim().toLowerCase();
169
+ if (normalized === "1" || normalized === "true" || normalized === "yes") return true;
170
+ if (normalized === "0" || normalized === "false" || normalized === "no") return false;
171
+ // Ambiguous value — treat as undefined so callers apply their default.
172
+ return undefined;
173
+ }
174
+
175
+ function readBooleanEnvAny(...names: string[]): boolean | undefined {
176
+ for (const name of names) {
177
+ const value = readBooleanEnv(name);
178
+ if (value !== undefined) return value;
179
+ }
180
+ return undefined;
181
+ }
182
+
183
+ function findSectionEnd(prompt: string, startIndex: number, nextHeaders: string[]): number {
184
+ let endIndex = prompt.length;
185
+ for (const header of nextHeaders) {
186
+ const index = prompt.indexOf(header, startIndex);
187
+ if (index !== -1 && index < endIndex) endIndex = index;
188
+ }
189
+ return endIndex;
190
+ }
191
+
192
+ export function stripProjectContext(prompt: string): string {
193
+ const startIndex = prompt.indexOf(PROJECT_CONTEXT_HEADER);
194
+ if (startIndex === -1) return prompt;
195
+ const endIndex = findSectionEnd(prompt, startIndex + PROJECT_CONTEXT_HEADER.length, [SKILLS_HEADER, DATE_HEADER]);
196
+ return `${prompt.slice(0, startIndex)}${prompt.slice(endIndex)}`;
197
+ }
198
+
199
+ export function stripInheritedSkills(prompt: string): string {
200
+ const startIndex = prompt.indexOf(SKILLS_HEADER);
201
+ if (startIndex === -1) return prompt;
202
+ const endIndex = findSectionEnd(prompt, startIndex + SKILLS_HEADER.length, [DATE_HEADER]);
203
+ return `${prompt.slice(0, startIndex)}${prompt.slice(endIndex)}`;
204
+ }
205
+
206
+ export function rewriteTeamWorkerPrompt(prompt: string, options: { inheritProjectContext: boolean; inheritSkills: boolean }): string {
207
+ let rewritten = prompt;
208
+ if (!options.inheritProjectContext) rewritten = stripProjectContext(rewritten);
209
+ if (!options.inheritSkills) rewritten = stripInheritedSkills(rewritten);
210
+ return rewritten;
211
+ }
212
+
213
+ export default function registerPiTeamsPromptRuntime(pi: ExtensionAPI): void {
214
+ // ── FIX-S1: cross-channel steer dedup state ────────────────────────────
215
+ // Both the broker push (mailbox.message → onSteer callback below) and the
216
+ // file poll (pollSteering below) are wired to sendMessage. The broker
217
+ // writes to BOTH the mailbox observer (live fanout) AND the steering
218
+ // JSONL (durable fallback) so a connected worker will see the same steer
219
+ // twice: once via the broker, once via the next poll tick. We dedup at the
220
+ // consumer by tracking steer ids in a bounded FIFO set shared by both
221
+ // delivery paths. Without id-bearing entries (legacy producer), pollSteering
222
+ // is the only delivery channel and dedup is a no-op for id-less entries.
223
+ const seenSteers = createSeenSteerIdSet();
224
+ // ── Feature 1: maxTokens cap ──────────────────────────────────────────
225
+ // Cap output tokens per API call for background workers. Reads
226
+ // PI_CREW_MAX_OUTPUT_TOKENS env (set by pi-args.ts from agent.maxTokens).
227
+ const maxTokensEnv = process.env[PI_CREW_MAX_OUTPUT_ENV];
228
+ const maxTokensCap = maxTokensEnv ? Number.parseInt(maxTokensEnv, 10) : undefined;
229
+ if (maxTokensCap && maxTokensCap > 0) {
230
+ pi.on("before_provider_request", (event) => {
231
+ const payload = event.payload as Record<string, unknown> | undefined;
232
+ if (!payload || typeof payload !== "object") return;
233
+ // Cap both OpenAI-style max_tokens and Anthropic-style max_tokens
234
+ if (typeof payload.max_tokens === "number" && payload.max_tokens > maxTokensCap) {
235
+ payload.max_tokens = maxTokensCap;
236
+ }
237
+ // Also cap newer field names used by some providers
238
+ if (typeof payload.max_completion_tokens === "number" && payload.max_completion_tokens > maxTokensCap) {
239
+ payload.max_completion_tokens = maxTokensCap;
240
+ }
241
+ if (typeof payload.max_output_tokens === "number" && payload.max_output_tokens > maxTokensCap) {
242
+ payload.max_output_tokens = maxTokensCap;
243
+ }
244
+ const generationConfig = payload.generationConfig as Record<string, unknown> | undefined;
245
+ if (
246
+ generationConfig &&
247
+ typeof generationConfig.max_output_tokens === "number" &&
248
+ generationConfig.max_output_tokens > maxTokensCap
249
+ ) {
250
+ generationConfig.max_output_tokens = maxTokensCap;
251
+ }
252
+ });
253
+ }
254
+
255
+ // ── Feature 2: real-time steering ──────────────────────────────────────
256
+ // Poll the steering JSONL file for new steer messages. The parent (team
257
+ // tool) writes steers here in real-time; this reader injects them into
258
+ // the active session via pi.sendMessage with deliverAs:"steer".
259
+ const steeringFile = process.env[PI_CREW_STEERING_FILE_ENV];
260
+ if (steeringFile) {
261
+ // FIX-03: validate the steering file path once before first read.
262
+ const validation = validateSteeringFile(steeringFile);
263
+ if (!validation.valid) {
264
+ logInternalError(
265
+ "prompt-runtime.steering-file-rejected",
266
+ new Error(validation.reason ?? "steering-file-validation-failed"),
267
+ `path=${steeringFile}`,
268
+ "warn",
269
+ );
270
+ } else {
271
+ const safeSteeringFile = validation.resolvedPath ?? steeringFile;
272
+ let lastOffset = 0;
273
+ const pollSteering = (): void => {
274
+ try {
275
+ const stat = fs.statSync(safeSteeringFile, { throwIfNoEntry: false });
276
+ if (!stat || stat.size <= lastOffset) return;
277
+ const fd = fs.openSync(safeSteeringFile, "r");
278
+ try {
279
+ const buf = Buffer.alloc(stat.size - lastOffset);
280
+ fs.readSync(fd, buf, 0, buf.length, lastOffset);
281
+ lastOffset = stat.size;
282
+ const lines = buf.toString("utf8").split("\n").filter(Boolean);
283
+ for (const line of lines) {
284
+ try {
285
+ const entry = JSON.parse(line) as SteerEntry;
286
+ if (entry.type !== "steer") continue;
287
+ // FIX-S1: cross-channel dedup. The broker writes the
288
+ // same steer to both the mailbox (live fanout via the
289
+ // onSteer callback below) and this JSONL file. A
290
+ // connected worker receives it via the broker first
291
+ // and via this poll second; the seen-id set ensures
292
+ // only the first arrival reaches pi.sendMessage.
293
+ const entryId =
294
+ typeof (entry as { id?: unknown }).id === "string" ? (entry as { id: string }).id : undefined;
295
+ if (!seenSteers.markOrSkip(entryId)) continue;
296
+ // FIX-02: sanitize each steer entry before forwarding
297
+ // to pi.sendMessage. Reject oversized payloads,
298
+ // excessive newlines, and control characters.
299
+ const sanitized = sanitizeSteerMessage(entry);
300
+ if (!sanitized.valid || sanitized.message === undefined) {
301
+ logInternalError(
302
+ "prompt-runtime.steer-rejected",
303
+ new Error(sanitized.reason ?? "steer-sanitization-failed"),
304
+ `line-preview=${line.slice(0, 64)}`,
305
+ "warn",
306
+ );
307
+ continue;
308
+ }
309
+ pi.sendMessage(
310
+ { customType: "crew-steer", content: sanitized.message, display: false },
311
+ { deliverAs: "steer" },
312
+ );
313
+ } catch {
314
+ // Malformed line — skip
315
+ }
316
+ }
317
+ } finally {
318
+ try {
319
+ fs.closeSync(fd);
320
+ } catch {
321
+ /* already closed */
322
+ }
323
+ }
324
+ } catch {
325
+ // File doesn't exist yet or read error — will retry next tick
326
+ }
327
+ };
328
+ const timer = setInterval(pollSteering, 500);
329
+ timer.unref?.();
330
+ }
331
+ }
332
+
333
+ // ── Feature 2b: broker push steering (opt-in, layered on the file poll) ──
334
+ // When the parent injected broker credentials, connect a broker client and
335
+ // deliver pushed steers with the SAME sanitize + pi.sendMessage path as the
336
+ // file poll above. The file poll remains the durable fallback; a broker
337
+ // connect failure is invisible to the worker.
338
+ const brokerHandle = startChildBrokerClient({
339
+ onSteer: (rawMessage, id) => {
340
+ // FIX-S1: cross-channel dedup. The broker persists every steer to
341
+ // the steering JSONL (durable) AND pushes it via the mailbox
342
+ // observer (live). This callback sees the live push; the
343
+ // pollSteering path above will see the same steer on its next
344
+ // tick. Keying on `id` (a stable identifier emitted by the broker)
345
+ // guarantees a single pi.sendMessage per steer.
346
+ if (!seenSteers.markOrSkip(id)) return;
347
+ const sanitized = sanitizeSteerMessage({ type: "steer", message: rawMessage });
348
+ if (!sanitized.valid || sanitized.message === undefined) {
349
+ logInternalError(
350
+ "prompt-runtime.broker-steer-rejected",
351
+ new Error(sanitized.reason ?? "steer-sanitization-failed"),
352
+ undefined,
353
+ "warn",
354
+ );
355
+ return;
356
+ }
357
+ pi.sendMessage({ customType: "crew-steer", content: sanitized.message, display: false }, { deliverAs: "steer" });
358
+ },
359
+ });
360
+ // Close the broker connection on session shutdown to avoid leaking the
361
+ // persistent socket / reconnect timer. Fire-and-forget: the socket is
362
+ // already .unref()'d so it never blocks event-loop exit; errors are
363
+ // swallowed because teardown failures during shutdown are harmless.
364
+ pi.on("session_shutdown", () => {
365
+ void brokerHandle.close().catch(() => {});
366
+ });
367
+
368
+ // ── Prompt rewriting (existing) ────────────────────────────────────────
369
+ pi.on("before_agent_start", (event) => {
370
+ const inheritProjectContext = readBooleanEnvAny(PI_CREW_INHERIT_PROJECT_CONTEXT_ENV, PI_TEAMS_INHERIT_PROJECT_CONTEXT_ENV);
371
+ const inheritSkills = readBooleanEnvAny(PI_CREW_INHERIT_SKILLS_ENV, PI_TEAMS_INHERIT_SKILLS_ENV);
372
+ if (inheritProjectContext === undefined && inheritSkills === undefined) return;
373
+ const rewritten = rewriteTeamWorkerPrompt(event.systemPrompt, {
374
+ inheritProjectContext: inheritProjectContext ?? true,
375
+ inheritSkills: inheritSkills ?? true,
376
+ });
377
+ if (rewritten === event.systemPrompt) return;
378
+ return { systemPrompt: rewritten };
379
+ });
380
+ }