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,147 @@
1
+ /**
2
+ * BatchBarrier — Rule 1 (no-wait batch grouping).
3
+ *
4
+ * When a leader launches several background subagents with the SAME `batchId`
5
+ * and does NOT join them immediately (`get_subagent_result(wait:true)`), the
6
+ * completion notifications are coalesced: instead of N individual
7
+ * "changed state" wake-ups, the leader receives ONE consolidated notification
8
+ * once ALL members of the batch have reached a terminal state.
9
+ *
10
+ * Semantics:
11
+ * - `register(batchId, agentId)` is called at spawn time (synchronous within a
12
+ * leader turn). All members of a batch are therefore known by the time the
13
+ * first completion fires (completion is observed via the 1000ms poll loop).
14
+ * - `markTerminal(batchId, agentId)` returns whether THIS completion made every
15
+ * registered member terminal ("allDone"). When allDone, the caller emits a
16
+ * single consolidated notification and calls `markNotified`.
17
+ * - If a member reaches terminal after the batch already notified (late spawn
18
+ * edge case), `markTerminal` returns allDone=false for the straggler path is
19
+ * NOT covered — but `alreadyNotified` lets the caller suppress stray
20
+ * individual notifications once the consolidated one fired.
21
+ *
22
+ * Thread-safety: single-threaded JS event loop. No locks needed.
23
+ */
24
+
25
+ export interface BatchMember {
26
+ id: string;
27
+ description?: string;
28
+ type?: string;
29
+ status: string;
30
+ }
31
+
32
+ export interface BatchSnapshot {
33
+ batchId: string;
34
+ members: BatchMember[];
35
+ terminal: BatchMember[];
36
+ /** true when every registered member has reached a terminal state. */
37
+ allDone: boolean;
38
+ /** true once the consolidated notification has been emitted. */
39
+ notified: boolean;
40
+ }
41
+
42
+ const TERMINAL_STATUSES = new Set(["completed", "failed", "cancelled", "error", "stopped"]);
43
+
44
+ export function isTerminalStatus(status: string): boolean {
45
+ return TERMINAL_STATUSES.has(status);
46
+ }
47
+
48
+ export class BatchBarrier {
49
+ private readonly batches = new Map<
50
+ string,
51
+ {
52
+ members: Map<string, BatchMember>;
53
+ terminal: Map<string, BatchMember>;
54
+ notified: boolean;
55
+ }
56
+ >();
57
+
58
+ /** Register a member at spawn time. Idempotent per (batchId, agentId). */
59
+ register(batchId: string, agentId: string, meta?: { description?: string; type?: string }): void {
60
+ let batch = this.batches.get(batchId);
61
+ if (!batch) {
62
+ batch = {
63
+ members: new Map(),
64
+ terminal: new Map(),
65
+ notified: false,
66
+ };
67
+ this.batches.set(batchId, batch);
68
+ }
69
+ if (!batch.members.has(agentId)) {
70
+ batch.members.set(agentId, {
71
+ id: agentId,
72
+ description: meta?.description,
73
+ type: meta?.type,
74
+ status: "running",
75
+ });
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Record that a member reached a terminal state. Returns the batch snapshot.
81
+ * `snapshot.allDone` is true iff every registered member is now terminal.
82
+ * If the batch was never seen (defensive edge case), the member is registered
83
+ * on-the-fly as a batch-of-one so its terminal state is not silently lost.
84
+ */
85
+ markTerminal(batchId: string, member: BatchMember): BatchSnapshot {
86
+ let batch = this.batches.get(batchId);
87
+ if (!batch) {
88
+ batch = {
89
+ members: new Map(),
90
+ terminal: new Map(),
91
+ notified: false,
92
+ };
93
+ this.batches.set(batchId, batch);
94
+ }
95
+ // Ensure the member is known (auto-register for the defensive case).
96
+ if (!batch.members.has(member.id)) {
97
+ batch.members.set(member.id, { ...member, status: member.status });
98
+ }
99
+ if (isTerminalStatus(member.status)) {
100
+ batch.terminal.set(member.id, { ...member });
101
+ const existing = batch.members.get(member.id);
102
+ if (existing)
103
+ batch.members.set(member.id, {
104
+ ...existing,
105
+ status: member.status,
106
+ });
107
+ }
108
+ const allDone = batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id));
109
+ return {
110
+ batchId,
111
+ members: [...batch.members.values()],
112
+ terminal: [...batch.terminal.values()],
113
+ allDone,
114
+ notified: batch.notified,
115
+ };
116
+ }
117
+
118
+ /** Has the consolidated notification already been emitted for this batch? */
119
+ alreadyNotified(batchId: string): boolean {
120
+ return this.batches.get(batchId)?.notified ?? false;
121
+ }
122
+
123
+ /** Mark the consolidated notification as emitted. No-op if already set. */
124
+ markNotified(batchId: string): void {
125
+ const batch = this.batches.get(batchId);
126
+ if (batch) batch.notified = true;
127
+ }
128
+
129
+ /** Read-only snapshot (for tests / debugging). */
130
+ snapshot(batchId: string): BatchSnapshot | undefined {
131
+ const batch = this.batches.get(batchId);
132
+ if (!batch) return undefined;
133
+ return {
134
+ batchId,
135
+ members: [...batch.members.values()],
136
+ terminal: [...batch.terminal.values()],
137
+ allDone: batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id)),
138
+ notified: batch.notified,
139
+ };
140
+ }
141
+
142
+ /** Drop a batch (used on cleanup / test reset). */
143
+ dispose(batchId?: string): void {
144
+ if (batchId === undefined) this.batches.clear();
145
+ else this.batches.delete(batchId);
146
+ }
147
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * broker-issuer.ts — Process-local registry for the active broker credential
3
+ * issuer.
4
+ *
5
+ * The broker lifecycle controller (parent/root session) registers its
6
+ * `issueForChild` function here on start and clears it on stop. `runChildPi`
7
+ * reads it as the default `brokerIssuer` so the spawn path does not need the
8
+ * registration context threaded through every runner call site.
9
+ *
10
+ * This mirrors the existing module-level singletons in the codebase
11
+ * (`runEventBus`, the mailbox append observers). It lives ONLY in the parent
12
+ * process — children never register an issuer (they receive credentials via
13
+ * env). The value is a function reference, never a token; nothing here is
14
+ * persisted or logged.
15
+ */
16
+
17
+ /** Credentials handed to a child worker so it can authenticate to the broker. */
18
+ export interface BrokerSpawnCredentials {
19
+ socketPath: string;
20
+ token: string;
21
+ }
22
+
23
+ /** Issuer signature: given a runId (+optional taskId for per-task tokens),
24
+ * return credentials or undefined when the broker is disabled / this process
25
+ * is not the root session. taskId is optional for backward compat — callers
26
+ * that still pass only runId receive the legacy per-run token. */
27
+ export type BrokerIssuer = (runId: string, taskId?: string) => Promise<BrokerSpawnCredentials | undefined>;
28
+
29
+ let activeIssuer: BrokerIssuer | undefined;
30
+
31
+ /** Register the active issuer (called by the lifecycle controller on start). */
32
+ export function setActiveBrokerIssuer(issuer: BrokerIssuer | undefined): void {
33
+ activeIssuer = issuer;
34
+ }
35
+
36
+ /** Read the active issuer, if any. Returns undefined when no broker is wired. */
37
+ export function getActiveBrokerIssuer(): BrokerIssuer | undefined {
38
+ return activeIssuer;
39
+ }
@@ -0,0 +1,99 @@
1
+ import { type CancellationReason, CrewCancellationError, cancellationReasonFromUnknown } from "./cancellation.ts";
2
+
3
+ export interface CancellationTokenState {
4
+ aborted: boolean;
5
+ reason?: CancellationReason;
6
+ lastHeartbeatAt?: string;
7
+ lastHeartbeatStage?: string;
8
+ }
9
+
10
+ export interface CancellationTokenOptions {
11
+ signal?: AbortSignal;
12
+ onHeartbeat?: (state: CancellationTokenState) => void;
13
+ now?: () => Date;
14
+ }
15
+
16
+ export class CancellationToken {
17
+ readonly #controller = new AbortController();
18
+ readonly #onHeartbeat?: (state: CancellationTokenState) => void;
19
+ readonly #now: () => Date;
20
+ #reason?: CancellationReason;
21
+ #lastHeartbeatAt?: string;
22
+ #lastHeartbeatStage?: string;
23
+
24
+ constructor(options: CancellationTokenOptions = {}) {
25
+ this.#onHeartbeat = options.onHeartbeat;
26
+ this.#now = options.now ?? (() => new Date());
27
+ if (options.signal?.aborted) this.abort(options.signal.reason);
28
+ else if (options.signal) options.signal.addEventListener("abort", () => this.abort(options.signal?.reason), { once: true });
29
+ }
30
+
31
+ get signal(): AbortSignal {
32
+ return this.#controller.signal;
33
+ }
34
+ get aborted(): boolean {
35
+ return this.#controller.signal.aborted;
36
+ }
37
+ get reason(): CancellationReason | undefined {
38
+ return this.#reason;
39
+ }
40
+ get lastHeartbeatAt(): string | undefined {
41
+ return this.#lastHeartbeatAt;
42
+ }
43
+ get lastHeartbeatStage(): string | undefined {
44
+ return this.#lastHeartbeatStage;
45
+ }
46
+
47
+ heartbeat(stage?: string): CancellationTokenState {
48
+ this.throwIfCancelled();
49
+ this.#lastHeartbeatAt = this.#now().toISOString();
50
+ this.#lastHeartbeatStage = stage;
51
+ const state = this.state();
52
+ this.#onHeartbeat?.(state);
53
+ return state;
54
+ }
55
+
56
+ throwIfCancelled(): void {
57
+ if (this.aborted) throw new CrewCancellationError(this.#reason ?? cancellationReasonFromUnknown(this.#controller.signal.reason));
58
+ }
59
+
60
+ abort(reason?: unknown): void {
61
+ if (this.aborted) return;
62
+ this.#reason = cancellationReasonFromUnknown(reason);
63
+ this.#controller.abort(this.#reason);
64
+ }
65
+
66
+ wait(ms: number): Promise<void> {
67
+ this.throwIfCancelled();
68
+ if (ms <= 0) return Promise.resolve();
69
+ return new Promise((resolve, reject) => {
70
+ let timeout: NodeJS.Timeout | undefined;
71
+ const cleanup = (): void => {
72
+ if (timeout) clearTimeout(timeout);
73
+ this.signal.removeEventListener("abort", onAbort);
74
+ };
75
+ const onAbort = (): void => {
76
+ cleanup();
77
+ reject(new CrewCancellationError(this.#reason ?? cancellationReasonFromUnknown(this.signal.reason)));
78
+ };
79
+ timeout = setTimeout(() => {
80
+ cleanup();
81
+ resolve();
82
+ }, ms);
83
+ this.signal.addEventListener("abort", onAbort, { once: true });
84
+ });
85
+ }
86
+
87
+ state(): CancellationTokenState {
88
+ return {
89
+ aborted: this.aborted,
90
+ ...(this.#reason ? { reason: this.#reason } : {}),
91
+ ...(this.#lastHeartbeatAt ? { lastHeartbeatAt: this.#lastHeartbeatAt } : {}),
92
+ ...(this.#lastHeartbeatStage ? { lastHeartbeatStage: this.#lastHeartbeatStage } : {}),
93
+ };
94
+ }
95
+ }
96
+
97
+ export function createCancellationToken(options: CancellationTokenOptions = {}): CancellationToken {
98
+ return new CancellationToken(options);
99
+ }
@@ -0,0 +1,99 @@
1
+ import type { OperationTerminalEvidence } from "../state/types.ts";
2
+
3
+ export type CancellationReasonCode =
4
+ | "caller_cancelled"
5
+ | "leader_interrupted"
6
+ | "provider_timeout"
7
+ | "worker_timeout"
8
+ | "tool_timeout"
9
+ | "shutdown"
10
+ | "unknown";
11
+
12
+ export interface CancellationReason {
13
+ code: CancellationReasonCode;
14
+ message: string;
15
+ cause?: unknown;
16
+ }
17
+
18
+ export function buildSyntheticTerminalEvidence(
19
+ operation: "worker" | "tool" | "model",
20
+ reason: CancellationReason,
21
+ startedAt?: string,
22
+ ): OperationTerminalEvidence {
23
+ return {
24
+ operation,
25
+ status: "cancelled",
26
+ startedAt,
27
+ finishedAt: new Date().toISOString(),
28
+ reason,
29
+ };
30
+ }
31
+
32
+ const KNOWN_CODES: ReadonlySet<string> = new Set([
33
+ "caller_cancelled",
34
+ "leader_interrupted",
35
+ "provider_timeout",
36
+ "worker_timeout",
37
+ "tool_timeout",
38
+ "shutdown",
39
+ "unknown",
40
+ ]);
41
+
42
+ export class CrewCancellationError extends Error {
43
+ readonly reason: CancellationReason;
44
+
45
+ constructor(reason: CancellationReason) {
46
+ super(reason.message);
47
+ this.name = "CrewCancellationError";
48
+ this.reason = reason;
49
+ }
50
+ }
51
+
52
+ function reasonFromString(value: string): CancellationReason {
53
+ const trimmed = value.trim();
54
+ if (KNOWN_CODES.has(trimmed))
55
+ return {
56
+ code: trimmed as CancellationReasonCode,
57
+ message: `Cancelled: ${trimmed}`,
58
+ };
59
+ return {
60
+ code: "caller_cancelled",
61
+ message: trimmed || "Cancelled by caller.",
62
+ };
63
+ }
64
+
65
+ export function cancellationReasonFromUnknown(value: unknown): CancellationReason {
66
+ if (value instanceof CrewCancellationError) return value.reason;
67
+ if (value instanceof Error)
68
+ return {
69
+ code: "caller_cancelled",
70
+ message: value.message || "Cancelled by caller.",
71
+ cause: value,
72
+ };
73
+ if (typeof value === "string") return reasonFromString(value);
74
+ if (value && typeof value === "object" && !Array.isArray(value)) {
75
+ const record = value as {
76
+ code?: unknown;
77
+ reason?: unknown;
78
+ message?: unknown;
79
+ cause?: unknown;
80
+ };
81
+ const rawCode = typeof record.code === "string" ? record.code : typeof record.reason === "string" ? record.reason : undefined;
82
+ const code = rawCode && KNOWN_CODES.has(rawCode) ? (rawCode as CancellationReasonCode) : "caller_cancelled";
83
+ const message = typeof record.message === "string" && record.message.trim() ? record.message.trim() : `Cancelled: ${code}`;
84
+ return { code, message, cause: record.cause ?? value };
85
+ }
86
+ return { code: "caller_cancelled", message: "Cancelled by caller." };
87
+ }
88
+
89
+ export function cancellationReasonFromSignal(signal: AbortSignal | undefined): CancellationReason {
90
+ return cancellationReasonFromUnknown(signal?.reason);
91
+ }
92
+
93
+ export function cancellationErrorFromSignal(signal: AbortSignal | undefined): CrewCancellationError {
94
+ return new CrewCancellationError(cancellationReasonFromSignal(signal));
95
+ }
96
+
97
+ export function throwIfCancelled(signal: AbortSignal | undefined): void {
98
+ if (signal?.aborted) throw cancellationErrorFromSignal(signal);
99
+ }
@@ -0,0 +1,137 @@
1
+ import type { AgentConfig } from "../agents/agent-config.ts";
2
+ import { discoverAgents } from "../agents/discover-agents.ts";
3
+ import type { PiTeamsConfig } from "../config/config.ts";
4
+ import { discoverSkills, getLastDiscoveryDiagnostics } from "../skills/discover-skills.ts";
5
+ import type { SkillValidationError } from "../skills/validate.ts";
6
+ import { discoverTeams } from "../teams/discover-teams.ts";
7
+ import { discoverWorkflows } from "../workflows/discover-workflows.ts";
8
+
9
+ export type CapabilityKind = "team" | "workflow" | "agent" | "skill" | "tool" | "runtime";
10
+ export type CapabilitySource = "builtin" | "project" | "user" | "package" | "git";
11
+ export type CapabilityState = "active" | "disabled" | "shadowed" | "missing";
12
+
13
+ export interface CapabilityItem {
14
+ id: string;
15
+ kind: CapabilityKind;
16
+ name: string;
17
+ description: string;
18
+ source: CapabilitySource;
19
+ path?: string;
20
+ state: CapabilityState;
21
+ disabledReason?: string;
22
+ shadowedBy?: string;
23
+ }
24
+
25
+ function normalizeAgents(agents: AgentConfig[], source: CapabilitySource, disabledIds: Set<string>): CapabilityItem[] {
26
+ return agents.map((agent) => {
27
+ const id = `agent:${agent.name}`;
28
+ const configDisabled = disabledIds.has(id);
29
+ const agentDisabled = agent.disabled || configDisabled;
30
+ return {
31
+ id,
32
+ kind: "agent" as const,
33
+ name: agent.name,
34
+ description: agent.description,
35
+ source,
36
+ path: agent.filePath,
37
+ state: agentDisabled ? "disabled" : "active",
38
+ disabledReason: configDisabled ? "disabled by policy" : agent.disabled ? "disabled in config" : undefined,
39
+ };
40
+ });
41
+ }
42
+
43
+ function normalizeSkills(cwd: string, disabledIds: Set<string>): CapabilityItem[] {
44
+ const skills = discoverSkills(cwd);
45
+ return skills.map((skill) => {
46
+ const id = `skill:${skill.name}`;
47
+ const configDisabled = disabledIds.has(id);
48
+ return {
49
+ id,
50
+ kind: "skill" as const,
51
+ name: skill.name,
52
+ description: skill.description,
53
+ source: skill.source as CapabilitySource,
54
+ path: skill.path,
55
+ state: configDisabled ? "disabled" : "active",
56
+ disabledReason: configDisabled ? "disabled by policy" : undefined,
57
+ };
58
+ });
59
+ }
60
+
61
+ function normalizeTeams(cwd: string, disabledIds: Set<string>): CapabilityItem[] {
62
+ const result = discoverTeams(cwd);
63
+ return [...result.builtin, ...result.user, ...result.project].map((team) => {
64
+ const id = `team:${team.name}`;
65
+ const configDisabled = disabledIds.has(id);
66
+ return {
67
+ id,
68
+ kind: "team" as const,
69
+ name: team.name,
70
+ description: team.description,
71
+ source: team.source as CapabilitySource,
72
+ path: team.filePath,
73
+ state: configDisabled ? "disabled" : "active",
74
+ disabledReason: configDisabled ? "disabled by policy" : undefined,
75
+ };
76
+ });
77
+ }
78
+
79
+ function normalizeWorkflows(cwd: string, disabledIds: Set<string>): CapabilityItem[] {
80
+ const result = discoverWorkflows(cwd);
81
+ return [...result.builtin, ...result.user, ...result.project].map((workflow) => {
82
+ const id = `workflow:${workflow.name}`;
83
+ const configDisabled = disabledIds.has(id);
84
+ return {
85
+ id,
86
+ kind: "workflow" as const,
87
+ name: workflow.name,
88
+ description: workflow.description,
89
+ source: workflow.source as CapabilitySource,
90
+ path: workflow.filePath,
91
+ state: configDisabled ? "disabled" : "active",
92
+ disabledReason: configDisabled ? "disabled by policy" : undefined,
93
+ };
94
+ });
95
+ }
96
+
97
+ export function buildCapabilityInventory(cwd: string, config?: PiTeamsConfig): CapabilityItem[] {
98
+ const disabledIds = new Set<string>(config?.policy?.disabledCapabilities ?? []);
99
+ const agents = discoverAgents(cwd);
100
+ const items = [
101
+ ...normalizeTeams(cwd, disabledIds),
102
+ ...normalizeWorkflows(cwd, disabledIds),
103
+ ...normalizeAgents([...agents.builtin, ...agents.user, ...agents.project], "builtin", disabledIds),
104
+ ...normalizeSkills(cwd, disabledIds),
105
+ ];
106
+
107
+ // Mark shadowed resources: project/user items with same kind:name as a builtin
108
+ const builtinNames = new Set(
109
+ items.filter((item) => item.source === "builtin" || item.source === "package").map((item) => `${item.kind}:${item.name}`),
110
+ );
111
+ for (const item of items) {
112
+ if (item.source !== "builtin" && item.source !== "package" && builtinNames.has(`${item.kind}:${item.name}`)) {
113
+ item.state = "shadowed";
114
+ item.shadowedBy = `builtin:${item.kind}:${item.name}`;
115
+ }
116
+ }
117
+
118
+ return items.sort((a, b) => a.id.localeCompare(b.id));
119
+ }
120
+
121
+ /**
122
+ * L3: surface skill-validation diagnostics from the most recent
123
+ * `discoverSkills()` call. Skills that fail HARD validation are silently
124
+ * excluded from `buildCapabilityInventory()`; this function exposes the
125
+ * underlying errors so users see WHY a skill is missing instead of just
126
+ * noticing the absence.
127
+ *
128
+ * Soft warnings (unknown props, derived-name fallback) are also returned so
129
+ * skill authors can clean up their frontmatter over time.
130
+ *
131
+ * IMPORTANT: `discoverSkills()` is internally cached for 30s, so this
132
+ * function returns diagnostics from whichever call last populated the cache.
133
+ * Call `buildCapabilityInventory(cwd)` first to ensure a fresh pass.
134
+ */
135
+ export function buildSkillValidationDiagnostics(): SkillValidationError[] {
136
+ return getLastDiscoveryDiagnostics();
137
+ }