pi-crew 0.9.54 → 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 +24 -0
  2. package/package.json +5 -2
  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
package/CHANGELOG.md CHANGED
@@ -3,6 +3,30 @@
3
3
  > **Note:** `atomic-write-v2.ts` / `AtomicWriter` mentioned in historical entries below was consolidated into `atomic-write.ts` as of v0.9.42. This changelog is preserved as historical record — the migration was completed (the v2 class was never adopted; v1 won on simplicity + symlink-safety + link+unlink atomicity). See `docs/migration/atomic-write-v2-migration.md` for the decision rationale.
4
4
 
5
5
 
6
+ ## [0.9.55] — HOTFIX: ship src/ (child workers load src/prompt/prompt-runtime.ts by path) (2026-07-29)
7
+
8
+ **Fixes the delegation / team-run regression** that affected 0.9.52–0.9.54. The extension loaded fine (0.9.54), but delegation/team-run failed with "pi-crew run failed" — the child worker `pi` process could not find its extension.
9
+
10
+ ### Root cause (third consequence of PKG-2)
11
+ pi-crew spawns a child `pi` worker per agent task and passes it `--extension <packageRoot>/src/prompt/prompt-runtime.ts` (pi-args.ts `PROMPT_RUNTIME_EXTENSION_PATH`). The child loads that file BY PATH as its extension. PKG-2 (Sprint 6) removed `src/` from the npm tarball to slim it, so the file did not exist in published installs → child failed → "pi-crew run failed".
12
+
13
+ This was masked in 0.9.52/0.9.53 by the load failure (extension never loaded, so delegation was never reached). 0.9.54 fixed the load, surfacing this. (Not Windows-specific — my Linux repro passed only because the dev checkout has `src/`; published installs do not.)
14
+
15
+ `prompt-runtime.ts` also imports 3 more src/ files (crew-broker-child, internal-error, safe-paths), so shipping just it is insufficient.
16
+
17
+ ### Fix
18
+ - **Ship `src/` again** — add `"src/"` to package.json `files`. Reverts the PKG-2 src/ removal. The child worker can now find prompt-runtime.ts. Tarball stays lean (2.4MB compressed / 8.9MB unpacked).
19
+ - **prepack hook** (`scripts/clean-strip-types.mjs`): strips the ~290 strip-types `.js` companion files (dev-only cache, gitignored) from `src/` before every pack/publish, keeping the tarball clean regardless of local dev state.
20
+ - esbuild stays in `dependencies` (0.9.54 fix retained).
21
+
22
+ ### Regression guards (CI Test step)
23
+ - `test/unit/package-ships-src.test.ts` — **new**. Asserts `files` includes `src/` and the path-loaded files exist. Would have caught the PKG-2 regression.
24
+ - `test/unit/bundle-deps-consistency.test.ts` (0.9.54) — bundle external imports declared as runtime deps (caught the esbuild-devDep bug).
25
+ - `test/unit/extension-entry-load.test.ts` (0.9.53) — index.ts has no static src/ imports.
26
+
27
+ ### Note on PKG-2 / 0.9.52–0.9.54
28
+ PKG-2's tarball-slimming caused THREE bugs (load failure, esbuild-devDep mask, delegation failure). 0.9.52–0.9.54 are deprecated. `latest` → 0.9.55.
29
+
6
30
  ## [0.9.54] — HOTFIX (real root cause): esbuild runtime dep mis-declared as devDependency (2026-07-29)
7
31
 
8
32
  **Fixes the TRUE root cause** of the extension-load regression that affected 0.9.52 AND 0.9.53. Both are deprecated; `latest` now points here.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-crew",
3
- "version": "0.9.54",
3
+ "version": "0.9.55",
4
4
  "description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
5
5
  "author": "baphuongna",
6
6
  "license": "MIT",
@@ -31,6 +31,7 @@
31
31
  "files": [
32
32
  "*.ts",
33
33
  "*.mjs",
34
+ "src/",
34
35
  "dist/index.mjs",
35
36
  "dist/build-meta.json",
36
37
  "agents/",
@@ -39,6 +40,7 @@
39
40
  "skills/**",
40
41
  "themes/",
41
42
  "assets/crew-vibes.ttf",
43
+ "scripts/clean-strip-types.mjs",
42
44
  "scripts/postinstall.mjs",
43
45
  "scripts/install-crew-vibes-font.mjs",
44
46
  "scripts/build-crew-vibes-font.py",
@@ -93,7 +95,8 @@
93
95
  "bench:capture": "node scripts/run-bench.mjs && node -e \"require('node:fs').copyFileSync('test/bench/results.json','test/bench/baseline.json')\"",
94
96
  "profile:startup": "node scripts/profile-startup.mjs",
95
97
  "smoke:pi": "pi install .",
96
- "smoke:release": "node scripts/release-smoke.mjs"
98
+ "smoke:release": "node scripts/release-smoke.mjs",
99
+ "prepack": "node scripts/clean-strip-types.mjs"
97
100
  },
98
101
  "exports": {
99
102
  "./schema.json": "./schema.json",
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * prepack hook — strip strip-types `.js` companion cruft from `src/` before
4
+ * packing/publishing.
5
+ *
6
+ * WHY: Pi's strip-types loader (and node:test runs) emit a `.js` companion
7
+ * next to every `.ts` it transpiles, as a cache. These are gitignored
8
+ * (the `src slash star-star slash star.js` rule in .gitignore) and never
9
+ * committed, but they accumulate in dev checkouts. `npm pack` would
10
+ * otherwise ship ~290 stale `.js` files (~4MB of cruft) that don't exist in
11
+ * a fresh checkout.
12
+ *
13
+ * This hook runs before every `npm pack` / `npm publish` and deletes them so
14
+ * the published tarball is always clean (only the `.ts` sources ship). They
15
+ * regenerate harmlessly on the next strip-types load. Deleting is safe: pi-crew
16
+ * loads via the bundle (`dist/index.mjs`) or by explicit `.ts` path — never the
17
+ * strip-types `.js` companions.
18
+ *
19
+ * Robust: any error is logged + swallowed (never blocks a pack/publish).
20
+ */
21
+ import { readdirSync, rmSync, statSync } from "node:fs";
22
+ import { resolve, join, relative } from "node:path";
23
+
24
+ const root = resolve(import.meta.dirname, "..");
25
+ const SRC = join(root, "src");
26
+ // Only `.js` and `.js.map` are strip-types companions. `.d.ts` files are NEVER
27
+ // emitted by strip-types — they are hand-written source type shims (e.g.
28
+ // src/types/diff.d.ts) and must be preserved.
29
+ const STRIP_EXT = [".js", ".js.map"];
30
+
31
+ function walk(dir) {
32
+ let out = [];
33
+ let entries;
34
+ try {
35
+ entries = readdirSync(dir, { withFileTypes: true });
36
+ } catch {
37
+ return out;
38
+ }
39
+ for (const e of entries) {
40
+ const full = join(dir, e.name);
41
+ if (e.isDirectory()) {
42
+ out = out.concat(walk(full));
43
+ } else if (e.isFile() && STRIP_EXT.some((x) => e.name.endsWith(x))) {
44
+ out.push(full);
45
+ }
46
+ }
47
+ return out;
48
+ }
49
+
50
+ try {
51
+ const files = walk(SRC);
52
+ for (const f of files) rmSync(f, { force: true });
53
+ if (files.length > 0) {
54
+ console.log(
55
+ `[prepack] removed ${files.length} strip-types companion file(s) from src/`,
56
+ );
57
+ }
58
+ } catch (e) {
59
+ console.warn(`[prepack] non-fatal: ${e?.message ?? e}`);
60
+ }
@@ -0,0 +1,23 @@
1
+ import type { ExportAdapter, ExportContent } from "./types.ts";
2
+
3
+ export const claudeAdapter: ExportAdapter = {
4
+ toolId: "claude",
5
+ toolName: "Claude Code",
6
+ fileExtension: ".md",
7
+
8
+ getFilePath(content: ExportContent): string {
9
+ return `.claude/commands/pi-crew/${content.id}.md`;
10
+ },
11
+
12
+ formatFile(content: ExportContent): string {
13
+ const tagLines = content.tags.length > 0 ? ["tags:", ...content.tags.map((tag) => ` - ${JSON.stringify(tag)}`)] : [];
14
+ const frontmatter = [
15
+ "---",
16
+ `description: ${JSON.stringify(content.description)}`,
17
+ `category: ${JSON.stringify(content.category)}`,
18
+ ...tagLines,
19
+ "---",
20
+ ].join("\n");
21
+ return `${frontmatter}\n\n# ${content.name}\n\n${content.body}\n`;
22
+ },
23
+ };
@@ -0,0 +1,21 @@
1
+ import type { ExportAdapter, ExportContent } from "./types.ts";
2
+
3
+ export const codexAdapter: ExportAdapter = {
4
+ toolId: "codex",
5
+ toolName: "Codex",
6
+ fileExtension: ".md",
7
+
8
+ getFilePath(_content: ExportContent): string {
9
+ return "AGENTS.md";
10
+ },
11
+
12
+ formatFile(content: ExportContent): string {
13
+ const tags = content.tags.length > 0 ? ` (${content.tags.join(", ")})` : "";
14
+ return [
15
+ `## ${content.name}${tags}\n`,
16
+ `**Source:** ${content.source.type}/${content.source.name} `,
17
+ `**Category:** ${content.category}\n`,
18
+ content.body,
19
+ ].join("\n");
20
+ },
21
+ };
@@ -0,0 +1,17 @@
1
+ import type { ExportAdapter, ExportContent } from "./types.ts";
2
+
3
+ export const cursorAdapter: ExportAdapter = {
4
+ toolId: "cursor",
5
+ toolName: "Cursor",
6
+ fileExtension: ".md",
7
+
8
+ getFilePath(content: ExportContent): string {
9
+ return `.cursor/rules/pi-crew-${content.id}.md`;
10
+ },
11
+
12
+ formatFile(content: ExportContent): string {
13
+ const header = `# ${content.name}\n\n> ${content.description}`;
14
+ const tags = content.tags.length > 0 ? `\n\n**Tags:** ${content.tags.join(", ")}` : "";
15
+ return `${header}${tags}\n\n${content.body}\n`;
16
+ },
17
+ };
@@ -0,0 +1,143 @@
1
+ import type { AgentConfig } from "../agents/agent-config.ts";
2
+ import type { SkillDescriptor } from "../skills/discover-skills.ts";
3
+ import type { TeamConfig } from "../teams/team-config.ts";
4
+ import { resolveRealContainedPath } from "../utils/safe-paths.ts";
5
+ import type { WorkflowConfig } from "../workflows/workflow-config.ts";
6
+ import { adapterRegistry } from "./registry.ts";
7
+ import type { ExportContent } from "./types.ts";
8
+
9
+ function slugify(value: string): string {
10
+ return value
11
+ .toLowerCase()
12
+ .replace(/[^a-z0-9]+/g, "-")
13
+ .replace(/^-+|-+$/g, "");
14
+ }
15
+
16
+ export function agentToExportContent(agent: AgentConfig): ExportContent {
17
+ const category = agent.routing?.category ?? "agent";
18
+ const tags = agent.routing?.triggers ?? [];
19
+ return {
20
+ id: slugify(agent.name),
21
+ name: agent.name,
22
+ description: agent.description,
23
+ category,
24
+ tags,
25
+ body: agent.systemPrompt,
26
+ source: { type: "agent", name: agent.name },
27
+ };
28
+ }
29
+
30
+ export function teamToExportContent(team: TeamConfig): ExportContent {
31
+ const category = team.routing?.category ?? "team";
32
+ const tags = team.routing?.triggers ?? [];
33
+ const rolesDesc = team.roles.map((role) => `- **${role.name}**: ${role.description ?? role.agent}`).join("\n");
34
+ const body = `${team.description}\n\n### Roles\n${rolesDesc}`;
35
+ return {
36
+ id: slugify(team.name),
37
+ name: team.name,
38
+ description: team.description,
39
+ category,
40
+ tags,
41
+ body,
42
+ source: { type: "team", name: team.name },
43
+ };
44
+ }
45
+
46
+ export function workflowToExportContent(workflow: WorkflowConfig): ExportContent {
47
+ const stepsDesc = workflow.steps.map((step) => `- **${step.id}** (${step.role}): ${step.task}`).join("\n");
48
+ const body = `${workflow.description}\n\n### Steps\n${stepsDesc}`;
49
+ return {
50
+ id: slugify(workflow.name),
51
+ name: workflow.name,
52
+ description: workflow.description,
53
+ category: "workflow",
54
+ tags: [],
55
+ body,
56
+ source: { type: "workflow", name: workflow.name },
57
+ };
58
+ }
59
+
60
+ export function skillToExportContent(skill: SkillDescriptor): ExportContent {
61
+ return {
62
+ id: slugify(skill.name),
63
+ name: skill.name,
64
+ description: skill.description || `Skill: ${skill.name}`,
65
+ category: "skill",
66
+ tags: [],
67
+ body: `Skill loaded from ${skill.source}: ${skill.path}`,
68
+ source: { type: "skill", name: skill.name },
69
+ };
70
+ }
71
+
72
+ export type ExportableResource =
73
+ | { kind: "agent"; config: AgentConfig }
74
+ | { kind: "team"; config: TeamConfig }
75
+ | { kind: "workflow"; config: WorkflowConfig }
76
+ | { kind: "skill"; config: SkillDescriptor };
77
+
78
+ export function resourcesToExportContent(resources: ExportableResource[]): ExportContent[] {
79
+ const results: ExportContent[] = [];
80
+ for (const resource of resources) {
81
+ switch (resource.kind) {
82
+ case "agent":
83
+ results.push(agentToExportContent(resource.config));
84
+ break;
85
+ case "team":
86
+ results.push(teamToExportContent(resource.config));
87
+ break;
88
+ case "workflow":
89
+ results.push(workflowToExportContent(resource.config));
90
+ break;
91
+ case "skill":
92
+ results.push(skillToExportContent(resource.config));
93
+ break;
94
+ }
95
+ }
96
+ return results;
97
+ }
98
+
99
+ export interface ToolExportResult {
100
+ toolId: string;
101
+ files: Array<{ path: string; content: string }>;
102
+ }
103
+
104
+ export function generateToolExport(toolId: string, resources: ExportableResource[], projectRoot?: string): ToolExportResult {
105
+ const adapter = adapterRegistry.get(toolId);
106
+ if (!adapter) {
107
+ throw new Error(
108
+ `Unknown export adapter: ${toolId}. Available: ${adapterRegistry
109
+ .getAll()
110
+ .map((a) => a.toolId)
111
+ .join(", ")}`,
112
+ );
113
+ }
114
+ const contents = resourcesToExportContent(resources);
115
+ const files = contents.map((content): { path: string; content: string } => {
116
+ const filePath = adapter.getFilePath(content);
117
+ // Validate path containment when a project root is provided
118
+ if (projectRoot) {
119
+ try {
120
+ resolveRealContainedPath(projectRoot, filePath);
121
+ } catch (e) {
122
+ throw new Error(
123
+ `Export path '${filePath}' escapes project root '${projectRoot}': ${e instanceof Error ? e.message : String(e)}`,
124
+ );
125
+ }
126
+ }
127
+ return {
128
+ path: filePath,
129
+ content: adapter.formatFile(content),
130
+ };
131
+ });
132
+ // Merge duplicate file paths (e.g., codex adapter maps everything to AGENTS.md)
133
+ const merged = new Map<string, string>();
134
+ for (const f of files) {
135
+ const existing = merged.get(f.path);
136
+ merged.set(f.path, existing ? `${existing}\n\n${f.content}` : f.content);
137
+ }
138
+ const mergedFiles = [...merged.entries()].map(([p, content]) => ({
139
+ path: p,
140
+ content,
141
+ }));
142
+ return { toolId, files: mergedFiles };
143
+ }
@@ -0,0 +1,15 @@
1
+ export { claudeAdapter } from "./claude-adapter.ts";
2
+ export { codexAdapter } from "./codex-adapter.ts";
3
+ export { cursorAdapter } from "./cursor-adapter.ts";
4
+ export { generateToolExport, resourcesToExportContent } from "./export-util.ts";
5
+ export { adapterRegistry, createAdapterRegistry } from "./registry.ts";
6
+ export type { AdapterRegistry, ExportAdapter, ExportContent } from "./types.ts";
7
+
8
+ import { claudeAdapter } from "./claude-adapter.ts";
9
+ import { codexAdapter } from "./codex-adapter.ts";
10
+ import { cursorAdapter } from "./cursor-adapter.ts";
11
+ import { adapterRegistry } from "./registry.ts";
12
+
13
+ adapterRegistry.register(claudeAdapter);
14
+ adapterRegistry.register(cursorAdapter);
15
+ adapterRegistry.register(codexAdapter);
@@ -0,0 +1,18 @@
1
+ import type { AdapterRegistry, ExportAdapter } from "./types.ts";
2
+
3
+ export function createAdapterRegistry(): AdapterRegistry {
4
+ const adapters = new Map<string, ExportAdapter>();
5
+ return {
6
+ get(toolId: string): ExportAdapter | undefined {
7
+ return adapters.get(toolId);
8
+ },
9
+ getAll(): ExportAdapter[] {
10
+ return [...adapters.values()];
11
+ },
12
+ register(adapter: ExportAdapter): void {
13
+ adapters.set(adapter.toolId, adapter);
14
+ },
15
+ };
16
+ }
17
+
18
+ export const adapterRegistry: AdapterRegistry = createAdapterRegistry();
@@ -0,0 +1,23 @@
1
+ export interface ExportContent {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ category: string;
6
+ tags: string[];
7
+ body: string;
8
+ source: { type: "agent" | "team" | "workflow" | "skill"; name: string };
9
+ }
10
+
11
+ export interface ExportAdapter {
12
+ readonly toolId: string;
13
+ readonly toolName: string;
14
+ readonly fileExtension: string;
15
+ getFilePath(content: ExportContent): string;
16
+ formatFile(content: ExportContent): string;
17
+ }
18
+
19
+ export interface AdapterRegistry {
20
+ get(toolId: string): ExportAdapter | undefined;
21
+ getAll(): ExportAdapter[];
22
+ register(adapter: ExportAdapter): void;
23
+ }
@@ -0,0 +1,194 @@
1
+ import type { RoleToolConfig } from "../config/role-tools.ts";
2
+ import { getToolConfig } from "../config/role-tools.ts";
3
+
4
+ /**
5
+ * F1 (v0.7.9): canonical built-in tool name list. Used by `parseToolsField`
6
+ * to expand wildcard `*` / `all` patterns in agent frontmatter. Matches
7
+ * pi-subagents' `BUILTIN_TOOL_NAMES` (derived from pi's `createCodingTools` /
8
+ * `createReadOnlyTools`). If pi adds a new built-in, update this list and
9
+ * the wildcard expansion will pick it up. The 7 names below are stable
10
+ * across pi v0.77+ and cover read, edit, write, bash, grep, find, ls.
11
+ */
12
+ export const BUILTIN_TOOL_NAMES: readonly string[] = ["read", "edit", "write", "bash", "grep", "find", "ls"];
13
+
14
+ /**
15
+ * F1 (v0.7.9): normalize the raw `tools:` frontmatter CSV into a `string[]`.
16
+ * Semantics (matching pi-subagents' `parseToolsField`):
17
+ * - omitted / undefined → returns `undefined` (back-compat: use the
18
+ * runtime default — today this is the role-tools default; tomorrow this
19
+ * could become the wildcard expansion if the user opts in).
20
+ * - `*` or `all` (case-insensitive) → returns the full BUILTIN_TOOL_NAMES
21
+ * list (no duplicates).
22
+ * - `none` or empty string → returns `[]` (zero built-ins; extension
23
+ * tools via `ext:` can still be added, though pi-crew doesn't parse
24
+ * `ext:` selectors yet — see F1 sub-gap).
25
+ * - CSV → returns the parsed entries (trimmed, empty entries dropped).
26
+ * Plain tool names (no `*`) pass through unchanged so existing agent
27
+ * files keep working with no edits.
28
+ */
29
+ export function parseToolsField(raw: unknown): string[] | undefined {
30
+ if (raw === undefined || raw === null) return undefined;
31
+ const s = typeof raw === "string" ? raw.trim() : String(raw).trim();
32
+ if (!s) return [];
33
+ const lowered = s.toLowerCase();
34
+ if (lowered === "none" || lowered === "[]") return [];
35
+ if (lowered === "*" || lowered === "all") return [...BUILTIN_TOOL_NAMES];
36
+ const items = s
37
+ .split(",")
38
+ .map((t) => t.trim())
39
+ .filter(Boolean);
40
+ return items;
41
+ }
42
+
43
+ export type ResourceSource = "builtin" | "user" | "project" | "git" | "dynamic" | "project-pi";
44
+
45
+ export interface RoutingMetadata {
46
+ triggers?: string[];
47
+ useWhen?: string[];
48
+ avoidWhen?: string[];
49
+ cost?: "free" | "cheap" | "expensive";
50
+ category?: string;
51
+ }
52
+
53
+ export interface AgentConfig {
54
+ name: string;
55
+ description: string;
56
+ source: ResourceSource;
57
+ filePath: string;
58
+ systemPrompt: string;
59
+ model?: string;
60
+ fallbackModels?: string[];
61
+ thinking?: string;
62
+ tools?: string[];
63
+ extensions?: string[];
64
+ /**
65
+ * F1 (v0.7.9): extension denylist (case-insensitive plain names). Applied
66
+ * AFTER `extensions:` (which lists the allowed set) — an excluded
67
+ * extension is removed from the allowlist and never loads. Plain names
68
+ * only (no paths, no `*`); an unknown name logs a warning but is
69
+ * tolerated. Back-compat: omitted = no exclusion.
70
+ */
71
+ excludeExtensions?: string[];
72
+ skills?: string[];
73
+ systemPromptMode?: "replace" | "append";
74
+ inheritProjectContext?: boolean;
75
+ inheritSkills?: boolean;
76
+ routing?: RoutingMetadata;
77
+ memory?: "user" | "project" | "local";
78
+ /** Tool loading strategy: "essential" = always load all tools, "lean" = only load tools in defaultTools list */
79
+ loadMode?: "essential" | "lean";
80
+ /** Explicit tool list when loadMode is "lean". null means all available tools. */
81
+ defaultTools?: string[] | null;
82
+ /** Context mode: "fresh" = clean start, "fork" = inherit parent session context */
83
+ contextMode?: "fresh" | "fork";
84
+ /** Maximum turns for this agent. Overrides runtime config if set. */
85
+ maxTurns?: number;
86
+ /** Cap on output tokens per API call. Set via PI_CREW_MAX_OUTPUT env in child. */
87
+ maxTokens?: number;
88
+ /** Effort level for this agent. Controls how much work the agent puts in. */
89
+ effort?: "low" | "medium" | "high";
90
+ /** Tools to explicitly forbid for this agent. Takes precedence over allowedTools. */
91
+ disallowedTools?: string[];
92
+ /** Disable ALL tools (Pi `--no-tools`). Used by capability-locked agents like the goal-judge (P1)
93
+ * that must have NO agency — only emit a verdict. §0c C6: an empty `tools:[]` is INSUFFICIENT
94
+ * because pi-args.ts skips empty arrays, leaving default tools enabled. */
95
+ disableTools?: boolean;
96
+ disabled?: boolean;
97
+ override?: { source: "config"; path: string };
98
+ }
99
+
100
+ /**
101
+ * Get session options (tools/excludeTools) for a specific role.
102
+ * Used by child-pi to apply role-based tool restrictions.
103
+ */
104
+ export function getAgentSessionOptions(role: string): {
105
+ tools?: string[];
106
+ excludeTools?: string[];
107
+ } {
108
+ const config: RoleToolConfig = getToolConfig(role);
109
+
110
+ if (config.tools || config.excludeTools) {
111
+ return {
112
+ tools: config.tools,
113
+ excludeTools: config.excludeTools,
114
+ };
115
+ }
116
+
117
+ return {};
118
+ }
119
+
120
+ /**
121
+ * F1 unify (v0.8.0): the single source of truth for a worker's tool policy,
122
+ * used by BOTH spawn paths (child-pi `pi-args.ts` and live-session
123
+ * `live-session-runtime.ts`). Before this, the two paths disagreed:
124
+ * - child-pi: `roleConfig.tools ?? agent.tools` (role authoritative)
125
+ * - live-session: `agent.tools` only (frontmatter authoritative, role ignored)
126
+ * so the same agent behaved differently depending on the runtime. A user
127
+ * defining `tools:` or `disallowed_tools:` in a custom agent's frontmatter
128
+ * saw it honored on one path and ignored on the other.
129
+ *
130
+ * Unified semantics (stable across both paths):
131
+ * - **allowlist precedence is source-aware**:
132
+ * - `source === "builtin"` → role-config authoritative (security: a
133
+ * builtin explorer MUST stay read-only even if its frontmatter is
134
+ * loose). Frontmatter is the fallback when the role has no allowlist.
135
+ * - `source !== "builtin"` (user / project) → frontmatter `tools:`
136
+ * authoritative (user intent). Role-config is the fallback.
137
+ * - **denylist is additive**: `roleConfig.excludeTools` and
138
+ * `agent.disallowedTools` are MERGED (dedup, order-insensitive). It is
139
+ * always safe to forbid more, and merging means a security exclude
140
+ * from the role can never be weakened by a frontmatter omission.
141
+ *
142
+ * Returns `{ tools, excludeTools }` where each is `undefined` when no
143
+ * restriction of that kind applies (so callers no-op cleanly).
144
+ */
145
+ export interface ResolvedToolPolicy {
146
+ /** Allowlist; undefined = no allowlist restriction (all built-ins allowed). */
147
+ tools?: string[];
148
+ /** Denylist (additive); undefined = no denylist. */
149
+ excludeTools?: string[];
150
+ }
151
+
152
+ function uniqueToolMerge(...lists: Array<string[] | undefined>): string[] | undefined {
153
+ const merged = [...new Set(lists.flatMap((list) => list ?? []))];
154
+ return merged.length > 0 ? merged : undefined;
155
+ }
156
+
157
+ export function resolveToolPolicy(agent: AgentConfig, role?: string): ResolvedToolPolicy {
158
+ const roleConfig = role ? getToolConfig(role) : {};
159
+ // allowlist: source-aware precedence (see doc above).
160
+ const explicitTools = agent.source === "builtin" ? (roleConfig.tools ?? agent.tools) : (agent.tools ?? roleConfig.tools);
161
+ // L5: when the agent opts into `loadMode: "lean"` AND provides a
162
+ // non-empty `defaultTools` list, merge that list into the resolved
163
+ // allowlist. The merge is additive (union, dedup, order-preserving) so
164
+ // the existing source-aware precedence is preserved and a lean agent
165
+ // gets a focused-but-non-empty tool set. Signal flow:
166
+ // agent YAML frontmatter (loadMode, defaultTools)
167
+ // → parsed into AgentConfig
168
+ // → resolveToolPolicy(agent, role) here
169
+ // → policy.tools returned to buildPiWorkerArgs
170
+ // → `args.push("--tools", policy.tools.join(","))` in pi-args.ts
171
+ // → child pi process sees the merged allowlist
172
+ const tools =
173
+ agent.loadMode === "lean" && agent.defaultTools?.length ? uniqueToolMerge(explicitTools, agent.defaultTools) : explicitTools;
174
+ // denylist: additive merge of role excludeTools + agent disallowedTools.
175
+ const excludeTools = uniqueToolMerge(roleConfig.excludeTools, agent.disallowedTools);
176
+ return { tools, excludeTools };
177
+ }
178
+
179
+ /**
180
+ * Build agent session options including role-based tool restrictions.
181
+ * @param agent - The agent configuration
182
+ * @param role - The role name to use for tool restrictions (defaults to agent.name)
183
+ */
184
+ /** @internal */
185
+ function buildAgentSessionOptions(
186
+ agent: AgentConfig,
187
+ role?: string,
188
+ ): {
189
+ tools?: string[];
190
+ excludeTools?: string[];
191
+ } {
192
+ const effectiveRole = role ?? agent.name;
193
+ return getAgentSessionOptions(effectiveRole);
194
+ }