agentic-orchestrator 0.1.6 → 0.1.8

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 (438) hide show
  1. package/.prettierignore +10 -0
  2. package/.prettierrc.json +24 -0
  3. package/CLAUDE.md +3 -2
  4. package/README.md +71 -48
  5. package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
  6. package/agentic/orchestrator/prompts/planner.system.md +1 -0
  7. package/agentic/orchestrator/schemas/agents.schema.json +5 -22
  8. package/agentic/orchestrator/schemas/gates.schema.json +4 -19
  9. package/agentic/orchestrator/schemas/index.schema.json +3 -14
  10. package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
  11. package/agentic/orchestrator/schemas/plan.schema.json +6 -26
  12. package/agentic/orchestrator/schemas/policy.schema.json +19 -81
  13. package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
  14. package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
  15. package/agentic/orchestrator/schemas/state.schema.json +11 -61
  16. package/agentic/orchestrator/tools/catalog.json +33 -164
  17. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
  18. package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
  19. package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
  20. package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
  21. package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
  22. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
  23. package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
  24. package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
  25. package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
  26. package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
  27. package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
  28. package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
  29. package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
  30. package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
  31. package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
  32. package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
  33. package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
  34. package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
  35. package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
  36. package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
  37. package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
  38. package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
  39. package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
  40. package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
  41. package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
  42. package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
  43. package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
  44. package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
  45. package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
  46. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
  47. package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
  48. package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
  49. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
  50. package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
  51. package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
  52. package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
  53. package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
  54. package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
  55. package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
  56. package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
  57. package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
  58. package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
  59. package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
  60. package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
  61. package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
  62. package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
  63. package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
  64. package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
  65. package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
  66. package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
  67. package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
  68. package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
  69. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
  70. package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
  71. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
  72. package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
  73. package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
  74. package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
  75. package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
  76. package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
  77. package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
  78. package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
  79. package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
  80. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
  81. package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
  82. package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
  83. package/apps/control-plane/src/application/services/gate-service.ts +64 -41
  84. package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
  85. package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
  86. package/apps/control-plane/src/application/services/lock-service.ts +75 -49
  87. package/apps/control-plane/src/application/services/merge-service.ts +91 -50
  88. package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
  89. package/apps/control-plane/src/application/services/patch-service.ts +73 -44
  90. package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
  91. package/apps/control-plane/src/application/services/plan-service.ts +148 -89
  92. package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
  93. package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
  94. package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
  95. package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
  96. package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
  97. package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
  98. package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
  99. package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
  100. package/apps/control-plane/src/cli/aop.ts +2 -2
  101. package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
  102. package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
  103. package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
  104. package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
  105. package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
  106. package/apps/control-plane/src/cli/env-file.ts +115 -0
  107. package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
  108. package/apps/control-plane/src/cli/init-command-handler.ts +182 -56
  109. package/apps/control-plane/src/cli/io.ts +7 -3
  110. package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
  111. package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
  112. package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
  113. package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
  114. package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
  115. package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
  116. package/apps/control-plane/src/cli/spec-utils.ts +2 -2
  117. package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
  118. package/apps/control-plane/src/cli/tooling.ts +3 -3
  119. package/apps/control-plane/src/cli/types.ts +1 -1
  120. package/apps/control-plane/src/core/collisions.ts +27 -10
  121. package/apps/control-plane/src/core/constants.ts +13 -7
  122. package/apps/control-plane/src/core/error-codes.ts +1 -1
  123. package/apps/control-plane/src/core/fs.ts +11 -5
  124. package/apps/control-plane/src/core/gates.ts +53 -27
  125. package/apps/control-plane/src/core/git.ts +18 -6
  126. package/apps/control-plane/src/core/kernel.ts +513 -227
  127. package/apps/control-plane/src/core/patch.ts +7 -3
  128. package/apps/control-plane/src/core/path-layout.ts +5 -1
  129. package/apps/control-plane/src/core/path-rules.ts +19 -5
  130. package/apps/control-plane/src/core/qa-index.ts +26 -12
  131. package/apps/control-plane/src/core/response.ts +9 -6
  132. package/apps/control-plane/src/core/schemas.ts +29 -10
  133. package/apps/control-plane/src/core/tool-caller.ts +1 -1
  134. package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
  135. package/apps/control-plane/src/index.ts +3 -9
  136. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +79 -35
  137. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
  138. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
  139. package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
  140. package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
  141. package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
  142. package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
  143. package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
  144. package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
  145. package/apps/control-plane/src/mcp/tool-client.ts +17 -5
  146. package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
  147. package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
  148. package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
  149. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
  150. package/apps/control-plane/src/providers/providers.ts +137 -54
  151. package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
  152. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
  153. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
  154. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
  155. package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
  156. package/apps/control-plane/src/supervisor/runtime.ts +59 -35
  157. package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
  158. package/apps/control-plane/src/supervisor/types.ts +22 -7
  159. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
  160. package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
  161. package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
  162. package/apps/control-plane/test/aop.spec.ts +4 -4
  163. package/apps/control-plane/test/batch-operations.spec.ts +20 -18
  164. package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
  165. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
  166. package/apps/control-plane/test/bootstrap.spec.ts +72 -40
  167. package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
  168. package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
  169. package/apps/control-plane/test/cli.spec.ts +1 -1
  170. package/apps/control-plane/test/cli.unit.spec.ts +226 -167
  171. package/apps/control-plane/test/collision-queue.spec.ts +49 -40
  172. package/apps/control-plane/test/collisions.spec.ts +30 -30
  173. package/apps/control-plane/test/core-utils.spec.ts +29 -15
  174. package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
  175. package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
  176. package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
  177. package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
  178. package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
  179. package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
  180. package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
  181. package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
  182. package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
  183. package/apps/control-plane/test/gates.spec.ts +101 -81
  184. package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
  185. package/apps/control-plane/test/helpers.ts +10 -6
  186. package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
  187. package/apps/control-plane/test/init-wizard.spec.ts +328 -68
  188. package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
  189. package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
  190. package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
  191. package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
  192. package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
  193. package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
  194. package/apps/control-plane/test/kernel.spec.ts +134 -51
  195. package/apps/control-plane/test/lock-service.spec.ts +92 -68
  196. package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
  197. package/apps/control-plane/test/mcp.spec.ts +231 -115
  198. package/apps/control-plane/test/merge-service.spec.ts +142 -94
  199. package/apps/control-plane/test/multi-project.spec.ts +28 -22
  200. package/apps/control-plane/test/notifier-service.spec.ts +136 -92
  201. package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
  202. package/apps/control-plane/test/patch-service.spec.ts +128 -48
  203. package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
  204. package/apps/control-plane/test/plan-service.spec.ts +50 -39
  205. package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
  206. package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
  207. package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
  208. package/apps/control-plane/test/providers.spec.ts +208 -104
  209. package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
  210. package/apps/control-plane/test/qa-index.spec.ts +58 -61
  211. package/apps/control-plane/test/reactions.spec.ts +88 -45
  212. package/apps/control-plane/test/response.spec.ts +5 -5
  213. package/apps/control-plane/test/resume-command.spec.ts +121 -80
  214. package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
  215. package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
  216. package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
  217. package/apps/control-plane/test/services.spec.ts +147 -129
  218. package/apps/control-plane/test/session-management.spec.ts +136 -74
  219. package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
  220. package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
  221. package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
  222. package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
  223. package/apps/control-plane/test/supervisor.spec.ts +67 -43
  224. package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
  225. package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
  226. package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
  227. package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
  228. package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
  229. package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
  230. package/apps/control-plane/tsconfig.build.json +2 -7
  231. package/apps/control-plane/tsconfig.json +1 -5
  232. package/apps/control-plane/vitest.config.ts +7 -7
  233. package/config/agentic/orchestrator/adapters.yaml +3 -0
  234. package/config/agentic/orchestrator/agents.yaml +14 -0
  235. package/config/agentic/orchestrator/gates.yaml +28 -0
  236. package/config/agentic/orchestrator/policy.yaml +22 -0
  237. package/config/agentic/orchestrator/prompts/builder.system.md +1 -0
  238. package/config/agentic/orchestrator/prompts/planner.system.md +16 -0
  239. package/config/agentic/orchestrator/prompts/qa.system.md +1 -0
  240. package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
  241. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
  242. package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
  243. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
  244. package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
  245. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  246. package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
  247. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  248. package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
  249. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  250. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
  251. package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
  252. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  253. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
  254. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  255. package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
  256. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  257. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
  258. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
  259. package/dist/apps/control-plane/application/services/gate-service.js +26 -26
  260. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  261. package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
  262. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
  263. package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
  264. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
  265. package/dist/apps/control-plane/application/services/lock-service.js +32 -32
  266. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
  267. package/dist/apps/control-plane/application/services/merge-service.js +41 -27
  268. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  269. package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
  270. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  271. package/dist/apps/control-plane/application/services/patch-service.js +21 -19
  272. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  273. package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
  274. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  275. package/dist/apps/control-plane/application/services/plan-service.js +33 -33
  276. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  277. package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
  278. package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
  279. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
  280. package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
  281. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
  282. package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
  283. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  284. package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
  285. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  286. package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
  287. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  288. package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
  289. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
  290. package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
  291. package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
  292. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
  293. package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
  294. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  295. package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
  296. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
  297. package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
  298. package/dist/apps/control-plane/cli/env-file.d.ts +4 -0
  299. package/dist/apps/control-plane/cli/env-file.js +89 -0
  300. package/dist/apps/control-plane/cli/env-file.js.map +1 -0
  301. package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
  302. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  303. package/dist/apps/control-plane/cli/init-command-handler.js +97 -37
  304. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  305. package/dist/apps/control-plane/cli/io.js +2 -2
  306. package/dist/apps/control-plane/cli/io.js.map +1 -1
  307. package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
  308. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  309. package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
  310. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
  311. package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
  312. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  313. package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
  314. package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
  315. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
  316. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
  317. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
  318. package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
  319. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  320. package/dist/apps/control-plane/cli/tooling.js +1 -1
  321. package/dist/apps/control-plane/core/collisions.js +11 -8
  322. package/dist/apps/control-plane/core/collisions.js.map +1 -1
  323. package/dist/apps/control-plane/core/constants.js +13 -7
  324. package/dist/apps/control-plane/core/constants.js.map +1 -1
  325. package/dist/apps/control-plane/core/error-codes.js +1 -1
  326. package/dist/apps/control-plane/core/fs.js.map +1 -1
  327. package/dist/apps/control-plane/core/gates.d.ts +2 -2
  328. package/dist/apps/control-plane/core/gates.js +26 -19
  329. package/dist/apps/control-plane/core/gates.js.map +1 -1
  330. package/dist/apps/control-plane/core/git.js +3 -3
  331. package/dist/apps/control-plane/core/git.js.map +1 -1
  332. package/dist/apps/control-plane/core/kernel.d.ts +1 -0
  333. package/dist/apps/control-plane/core/kernel.js +134 -81
  334. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  335. package/dist/apps/control-plane/core/patch.js +7 -3
  336. package/dist/apps/control-plane/core/patch.js.map +1 -1
  337. package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
  338. package/dist/apps/control-plane/core/path-layout.js +4 -1
  339. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  340. package/dist/apps/control-plane/core/path-rules.js +3 -1
  341. package/dist/apps/control-plane/core/path-rules.js.map +1 -1
  342. package/dist/apps/control-plane/core/qa-index.js +5 -5
  343. package/dist/apps/control-plane/core/qa-index.js.map +1 -1
  344. package/dist/apps/control-plane/core/response.js +3 -3
  345. package/dist/apps/control-plane/core/response.js.map +1 -1
  346. package/dist/apps/control-plane/core/schemas.js +10 -6
  347. package/dist/apps/control-plane/core/schemas.js.map +1 -1
  348. package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
  349. package/dist/apps/control-plane/index.d.ts +1 -1
  350. package/dist/apps/control-plane/index.js +1 -1
  351. package/dist/apps/control-plane/index.js.map +1 -1
  352. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +40 -23
  353. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  354. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
  355. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
  356. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
  357. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
  358. package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
  359. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
  360. package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
  361. package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
  362. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
  363. package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
  364. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
  365. package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
  366. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
  367. package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
  368. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
  369. package/dist/apps/control-plane/mcp/tool-client.js +2 -2
  370. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
  371. package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
  372. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
  373. package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
  374. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
  375. package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
  376. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  377. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
  378. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
  379. package/dist/apps/control-plane/providers/providers.d.ts +3 -2
  380. package/dist/apps/control-plane/providers/providers.js +81 -39
  381. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  382. package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
  383. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  384. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
  385. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  386. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
  387. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
  388. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  389. package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
  390. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  391. package/dist/apps/control-plane/supervisor/runtime.js +25 -21
  392. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  393. package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
  394. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  395. package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
  396. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  397. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
  398. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  399. package/eslint.config.mjs +20 -20
  400. package/example-configurations/README.md +1 -1
  401. package/example-configurations/java/agents.yaml +3 -3
  402. package/example-configurations/java/policy.yaml +1 -1
  403. package/example-configurations/node/agents.yaml +3 -3
  404. package/example-configurations/node/policy.yaml +1 -1
  405. package/package.json +10 -5
  406. package/packages/web-dashboard/next.config.js +2 -2
  407. package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
  408. package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
  409. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
  410. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
  411. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
  412. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
  413. package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
  414. package/packages/web-dashboard/src/app/globals.css +10 -2
  415. package/packages/web-dashboard/src/app/page.tsx +100 -37
  416. package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
  417. package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
  418. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
  419. package/packages/web-dashboard/tsconfig.json +3 -11
  420. package/scripts/nx-safe.mjs +10 -10
  421. package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
  422. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +189 -90
  423. package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
  424. package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
  425. package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
  426. package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
  427. package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
  428. package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
  429. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
  430. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
  431. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
  432. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
  433. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
  434. package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
  435. package/spec-files/outstanding/agentic_orchestrator_provider_auth_bootstrap_spec.md +384 -0
  436. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
  437. package/spec-files/progress.md +186 -175
  438. package/tsconfig.json +2 -8
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  approveFeatureReview,
3
3
  denyFeatureReview,
4
- requestFeatureChanges
4
+ requestFeatureChanges,
5
5
  } from '@/lib/orchestrator-tools.js';
6
6
  import { resolveProjectRoot } from '@/lib/aop-client.js';
7
7
 
@@ -16,23 +16,38 @@ interface ReviewRequest {
16
16
  message?: string;
17
17
  }
18
18
 
19
- export async function POST(req: Request, { params }: { params: { id: string } }): Promise<Response> {
19
+ export async function POST(
20
+ req: Request,
21
+ { params }: { params: { id: string } },
22
+ ): Promise<Response> {
20
23
  const project = new URL(req.url).searchParams.get('project');
21
24
  const repoRoot = await resolveProjectRoot(project);
22
25
  const body = (await req.json()) as ReviewRequest;
23
26
 
24
27
  if (!['approve', 'deny', 'request_changes'].includes(body.decision)) {
25
28
  return Response.json(
26
- { ok: false, error: { code: 'invalid_decision', message: 'decision must be approve, deny, or request_changes' } },
27
- { status: 400 }
29
+ {
30
+ ok: false,
31
+ error: {
32
+ code: 'invalid_decision',
33
+ message: 'decision must be approve, deny, or request_changes',
34
+ },
35
+ },
36
+ { status: 400 },
28
37
  );
29
38
  }
30
39
 
31
40
  if (body.decision === 'approve') {
32
41
  if (!body.approval_token || body.approval_token.trim().length === 0) {
33
42
  return Response.json(
34
- { ok: false, error: { code: 'approval_token_required', message: 'approval_token is required for approve' } },
35
- { status: 400 }
43
+ {
44
+ ok: false,
45
+ error: {
46
+ code: 'approval_token_required',
47
+ message: 'approval_token is required for approve',
48
+ },
49
+ },
50
+ { status: 400 },
36
51
  );
37
52
  }
38
53
 
@@ -41,7 +56,7 @@ export async function POST(req: Request, { params }: { params: { id: string } })
41
56
  body.approval_token.trim(),
42
57
  body.merge_strategy ?? 'merge_commit',
43
58
  body.commit_message,
44
- repoRoot
59
+ repoRoot,
45
60
  );
46
61
  return Response.json(response, { status: response.ok ? 200 : 409 });
47
62
  }
@@ -50,8 +65,11 @@ export async function POST(req: Request, { params }: { params: { id: string } })
50
65
  const reason = body.reason?.trim();
51
66
  if (!reason) {
52
67
  return Response.json(
53
- { ok: false, error: { code: 'reason_required', message: 'reason is required when decision=deny' } },
54
- { status: 400 }
68
+ {
69
+ ok: false,
70
+ error: { code: 'reason_required', message: 'reason is required when decision=deny' },
71
+ },
72
+ { status: 400 },
55
73
  );
56
74
  }
57
75
  const response = await denyFeatureReview(params.id, reason, repoRoot);
@@ -8,8 +8,11 @@ export async function GET(req: Request, { params }: { params: { id: string } }):
8
8
  const detail = await readFeatureDetail(params.id, repoRoot);
9
9
  if (!detail) {
10
10
  return Response.json(
11
- { ok: false, error: { code: 'feature_not_found', message: `Feature ${params.id} not found` } },
12
- { status: 404 }
11
+ {
12
+ ok: false,
13
+ error: { code: 'feature_not_found', message: `Feature ${params.id} not found` },
14
+ },
15
+ { status: 404 },
13
16
  );
14
17
  }
15
18
  return Response.json({ ok: true, data: detail });
@@ -10,8 +10,8 @@ export async function GET(): Promise<Response> {
10
10
  ok: true,
11
11
  data: {
12
12
  projects: [],
13
- defaults: null
14
- }
13
+ defaults: null,
14
+ },
15
15
  });
16
16
  }
17
17
 
@@ -24,8 +24,8 @@ export async function GET(): Promise<Response> {
24
24
  path: project.path,
25
25
  policy: project.policy ?? null,
26
26
  gates: project.gates ?? null,
27
- dashboard_port: project.dashboard_port ?? null
28
- }))
29
- }
27
+ dashboard_port: project.dashboard_port ?? null,
28
+ })),
29
+ },
30
30
  });
31
31
  }
@@ -1,2 +1,10 @@
1
- * { box-sizing: border-box; margin: 0; padding: 0; }
2
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; }
1
+ * {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+ body {
7
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
8
+ background: #0f172a;
9
+ color: #e2e8f0;
10
+ }
@@ -1,7 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { useCallback, useEffect, useMemo, useState } from 'react';
4
- import type { DashboardStatusPayload, FeatureDetail, FeatureSummary, SSEEvent } from '@/lib/types.js';
4
+ import type {
5
+ DashboardStatusPayload,
6
+ FeatureDetail,
7
+ FeatureSummary,
8
+ SSEEvent,
9
+ } from '@/lib/types.js';
5
10
 
6
11
  type ReviewAction = 'review.approve' | 'review.deny' | 'review.request_changes';
7
12
  type ProjectEntry = { name: string; path: string };
@@ -12,7 +17,7 @@ const COLUMN_ORDER: Array<{ title: string; phase: FeatureSummary['phase'] }> = [
12
17
  { title: 'QA', phase: 'qa' },
13
18
  { title: 'Ready To Merge', phase: 'ready_to_merge' },
14
19
  { title: 'Blocked', phase: 'blocked' },
15
- { title: 'Merged', phase: 'merged' }
20
+ { title: 'Merged', phase: 'merged' },
16
21
  ];
17
22
 
18
23
  function columnColor(phase: FeatureSummary['phase']): string {
@@ -53,7 +58,7 @@ function StatusBadge({ status }: { status: string }) {
53
58
  background: '#0f172a',
54
59
  padding: '2px 6px',
55
60
  borderRadius: 6,
56
- border: '1px solid #334155'
61
+ border: '1px solid #334155',
57
62
  }}
58
63
  >
59
64
  {status}
@@ -72,7 +77,7 @@ function ActivityBadge({ activity }: { activity?: FeatureSummary['activity_state
72
77
  background: '#0b2239',
73
78
  padding: '2px 6px',
74
79
  borderRadius: 6,
75
- border: '1px solid #1d4ed8'
80
+ border: '1px solid #1d4ed8',
76
81
  }}
77
82
  >
78
83
  {label}
@@ -83,7 +88,7 @@ function ActivityBadge({ activity }: { activity?: FeatureSummary['activity_state
83
88
  export default function Dashboard() {
84
89
  const [payload, setPayload] = useState<DashboardStatusPayload>({
85
90
  index: { active: [], blocked: [], merged: [], blocked_queue: [] },
86
- features: []
91
+ features: [],
87
92
  });
88
93
  const [connected, setConnected] = useState(false);
89
94
  const [selectedFeatureId, setSelectedFeatureId] = useState<string | null>(null);
@@ -97,18 +102,18 @@ export default function Dashboard() {
97
102
  const refreshDetail = useCallback(
98
103
  async (featureId: string) => {
99
104
  const res = await jsonFetch<{ ok: boolean; data?: FeatureDetail }>(
100
- `/api/features/${featureId}${projectQuery(project)}`
105
+ `/api/features/${featureId}${projectQuery(project)}`,
101
106
  );
102
107
  if (res.ok && res.data) {
103
108
  setDetail(res.data);
104
109
  }
105
110
  },
106
- [project]
111
+ [project],
107
112
  );
108
113
 
109
114
  const refreshStatus = useCallback(async () => {
110
115
  const response = await jsonFetch<{ ok: boolean; data?: DashboardStatusPayload }>(
111
- `/api/status${projectQuery(project)}`
116
+ `/api/status${projectQuery(project)}`,
112
117
  );
113
118
  if (response.ok && response.data) {
114
119
  setPayload(response.data);
@@ -117,7 +122,9 @@ export default function Dashboard() {
117
122
 
118
123
  useEffect(() => {
119
124
  void (async () => {
120
- const response = await jsonFetch<{ ok: boolean; data?: { projects: ProjectEntry[] } }>('/api/projects');
125
+ const response = await jsonFetch<{ ok: boolean; data?: { projects: ProjectEntry[] } }>(
126
+ '/api/projects',
127
+ );
121
128
  if (response.ok && response.data) {
122
129
  setProjects(response.data.projects ?? []);
123
130
  }
@@ -173,7 +180,7 @@ export default function Dashboard() {
173
180
  for (const [phase, items] of byPhase.entries()) {
174
181
  byPhase.set(
175
182
  phase,
176
- [...items].sort((a, b) => a.feature_id.localeCompare(b.feature_id))
183
+ [...items].sort((a, b) => a.feature_id.localeCompare(b.feature_id)),
177
184
  );
178
185
  }
179
186
  return byPhase;
@@ -187,7 +194,7 @@ export default function Dashboard() {
187
194
  const body: Record<string, unknown> = {
188
195
  action,
189
196
  feature_id: selectedFeatureId,
190
- message: reviewMessage
197
+ message: reviewMessage,
191
198
  };
192
199
  if (action === 'review.approve') {
193
200
  body.approval_token = approvalToken;
@@ -201,8 +208,8 @@ export default function Dashboard() {
201
208
  {
202
209
  method: 'POST',
203
210
  headers: { 'Content-Type': 'application/json' },
204
- body: JSON.stringify(body)
205
- }
211
+ body: JSON.stringify(body),
212
+ },
206
213
  );
207
214
 
208
215
  if (result.ok) {
@@ -213,7 +220,7 @@ export default function Dashboard() {
213
220
  setActionResult(result.error?.message ?? `${action} failed`);
214
221
  }
215
222
  },
216
- [approvalToken, project, refreshDetail, refreshStatus, reviewMessage, selectedFeatureId]
223
+ [approvalToken, project, refreshDetail, refreshStatus, reviewMessage, selectedFeatureId],
217
224
  );
218
225
 
219
226
  const triggerCheckout = useCallback(
@@ -226,17 +233,26 @@ export default function Dashboard() {
226
233
  {
227
234
  method: 'POST',
228
235
  headers: { 'Content-Type': 'application/json' },
229
- body: JSON.stringify({ action, stash_changes: true })
230
- }
236
+ body: JSON.stringify({ action, stash_changes: true }),
237
+ },
238
+ );
239
+ setActionResult(
240
+ result.ok ? `${action} completed` : (result.error?.message ?? `${action} failed`),
231
241
  );
232
- setActionResult(result.ok ? `${action} completed` : result.error?.message ?? `${action} failed`);
233
242
  },
234
- [project, selectedFeatureId]
243
+ [project, selectedFeatureId],
235
244
  );
236
245
 
237
246
  return (
238
247
  <div style={{ maxWidth: 1600, margin: '0 auto', padding: 24 }}>
239
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16, alignItems: 'center' }}>
248
+ <div
249
+ style={{
250
+ display: 'flex',
251
+ justifyContent: 'space-between',
252
+ marginBottom: 16,
253
+ alignItems: 'center',
254
+ }}
255
+ >
240
256
  <div>
241
257
  <h1 style={{ fontSize: 28, fontWeight: 700, color: '#f8fafc' }}>AOP Dashboard</h1>
242
258
  <p style={{ fontSize: 12, color: '#94a3b8' }}>
@@ -258,7 +274,12 @@ export default function Dashboard() {
258
274
  }
259
275
  window.history.replaceState(null, '', url.toString());
260
276
  }}
261
- style={{ background: '#0f172a', color: '#e2e8f0', border: '1px solid #334155', padding: '6px 8px' }}
277
+ style={{
278
+ background: '#0f172a',
279
+ color: '#e2e8f0',
280
+ border: '1px solid #334155',
281
+ padding: '6px 8px',
282
+ }}
262
283
  >
263
284
  <option value="">Current Repo</option>
264
285
  {projects.map((entry) => (
@@ -267,17 +288,31 @@ export default function Dashboard() {
267
288
  </option>
268
289
  ))}
269
290
  </select>
270
- <div style={{ width: 10, height: 10, borderRadius: '50%', background: connected ? '#10b981' : '#ef4444' }} />
291
+ <div
292
+ style={{
293
+ width: 10,
294
+ height: 10,
295
+ borderRadius: '50%',
296
+ background: connected ? '#10b981' : '#ef4444',
297
+ }}
298
+ />
271
299
  </div>
272
300
  </div>
273
301
 
274
302
  <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 16 }}>
275
- <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(220px, 1fr))', gap: 12 }}>
303
+ <div
304
+ style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(220px, 1fr))', gap: 12 }}
305
+ >
276
306
  {COLUMN_ORDER.map((column) => {
277
307
  const features = featuresByPhase.get(column.phase) ?? [];
278
308
  return (
279
- <section key={column.title} style={{ background: '#1e293b', borderRadius: 12, padding: 12 }}>
280
- <header style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
309
+ <section
310
+ key={column.title}
311
+ style={{ background: '#1e293b', borderRadius: 12, padding: 12 }}
312
+ >
313
+ <header
314
+ style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}
315
+ >
281
316
  <strong style={{ color: '#f1f5f9', fontSize: 13 }}>{column.title}</strong>
282
317
  <span style={{ color: '#94a3b8', fontSize: 11 }}>{features.length}</span>
283
318
  </header>
@@ -289,14 +324,19 @@ export default function Dashboard() {
289
324
  style={{
290
325
  textAlign: 'left',
291
326
  borderRadius: 10,
292
- border: selectedFeatureId === feature.feature_id ? '1px solid #e2e8f0' : '1px solid #334155',
327
+ border:
328
+ selectedFeatureId === feature.feature_id
329
+ ? '1px solid #e2e8f0'
330
+ : '1px solid #334155',
293
331
  background: '#0f172a',
294
332
  padding: 10,
295
333
  borderLeft: `4px solid ${columnColor(feature.phase)}`,
296
- cursor: 'pointer'
334
+ cursor: 'pointer',
297
335
  }}
298
336
  >
299
- <div style={{ color: '#f8fafc', fontSize: 13, marginBottom: 4 }}>{feature.feature_id}</div>
337
+ <div style={{ color: '#f8fafc', fontSize: 13, marginBottom: 4 }}>
338
+ {feature.feature_id}
339
+ </div>
300
340
  <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
301
341
  <StatusBadge status={feature.status} />
302
342
  <ActivityBadge activity={feature.activity_state} />
@@ -311,7 +351,9 @@ export default function Dashboard() {
311
351
 
312
352
  <aside style={{ background: '#1e293b', borderRadius: 12, padding: 14 }}>
313
353
  {!detail ? (
314
- <div style={{ color: '#94a3b8', fontSize: 13 }}>Select a feature to inspect details, evidence, and review actions.</div>
354
+ <div style={{ color: '#94a3b8', fontSize: 13 }}>
355
+ Select a feature to inspect details, evidence, and review actions.
356
+ </div>
315
357
  ) : (
316
358
  <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
317
359
  <h2 style={{ color: '#f8fafc', fontSize: 16 }}>{detail.feature.feature_id}</h2>
@@ -323,12 +365,15 @@ export default function Dashboard() {
323
365
  Activity: {detail.feature.activity_state ?? 'unknown'}
324
366
  </div>
325
367
  <div style={{ color: '#cbd5e1', fontSize: 12 }}>
326
- Plan version: {detail.plan?.plan_version != null ? String(detail.plan.plan_version) : 'n/a'}
368
+ Plan version:{' '}
369
+ {detail.plan?.plan_version != null ? String(detail.plan.plan_version) : 'n/a'}
327
370
  </div>
328
371
  {detail.feature.pr ? (
329
372
  <div style={{ color: '#cbd5e1', fontSize: 12 }}>
330
- PR: #{detail.feature.pr.number ?? 'n/a'} | CI: {detail.feature.pr.ci_status ?? 'none'} | Review:{' '}
331
- {detail.feature.pr.review_decision ?? 'none'} | Merge Score: {detail.feature.pr.merge_score ?? 0}
373
+ PR: #{detail.feature.pr.number ?? 'n/a'} | CI:{' '}
374
+ {detail.feature.pr.ci_status ?? 'none'} | Review:{' '}
375
+ {detail.feature.pr.review_decision ?? 'none'} | Merge Score:{' '}
376
+ {detail.feature.pr.merge_score ?? 0}
332
377
  </div>
333
378
  ) : null}
334
379
 
@@ -337,24 +382,40 @@ export default function Dashboard() {
337
382
  onChange={(event) => setReviewMessage(event.target.value)}
338
383
  placeholder="Review feedback"
339
384
  rows={4}
340
- style={{ background: '#0f172a', color: '#e2e8f0', border: '1px solid #334155', padding: 8, borderRadius: 8 }}
385
+ style={{
386
+ background: '#0f172a',
387
+ color: '#e2e8f0',
388
+ border: '1px solid #334155',
389
+ padding: 8,
390
+ borderRadius: 8,
391
+ }}
341
392
  />
342
393
  <input
343
394
  value={approvalToken}
344
395
  onChange={(event) => setApprovalToken(event.target.value)}
345
396
  placeholder="approval token"
346
- style={{ background: '#0f172a', color: '#e2e8f0', border: '1px solid #334155', padding: 8, borderRadius: 8 }}
397
+ style={{
398
+ background: '#0f172a',
399
+ color: '#e2e8f0',
400
+ border: '1px solid #334155',
401
+ padding: 8,
402
+ borderRadius: 8,
403
+ }}
347
404
  />
348
405
 
349
406
  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
350
407
  <button onClick={() => void triggerReview('review.approve')}>Approve</button>
351
408
  <button onClick={() => void triggerReview('review.deny')}>Deny</button>
352
- <button onClick={() => void triggerReview('review.request_changes')}>Request Changes</button>
409
+ <button onClick={() => void triggerReview('review.request_changes')}>
410
+ Request Changes
411
+ </button>
353
412
  <button onClick={() => void triggerCheckout('checkout')}>Checkout Branch</button>
354
413
  <button onClick={() => void triggerCheckout('restore')}>Restore Branch</button>
355
414
  </div>
356
415
 
357
- {actionResult ? <div style={{ color: '#93c5fd', fontSize: 12 }}>{actionResult}</div> : null}
416
+ {actionResult ? (
417
+ <div style={{ color: '#93c5fd', fontSize: 12 }}>{actionResult}</div>
418
+ ) : null}
358
419
 
359
420
  <details>
360
421
  <summary style={{ cursor: 'pointer', color: '#e2e8f0' }}>Diff</summary>
@@ -365,7 +426,7 @@ export default function Dashboard() {
365
426
  overflow: 'auto',
366
427
  background: '#0f172a',
367
428
  border: '1px solid #334155',
368
- padding: 8
429
+ padding: 8,
369
430
  }}
370
431
  >
371
432
  {detail.diff || 'No diff artifact available.'}
@@ -377,7 +438,9 @@ export default function Dashboard() {
377
438
  <ul style={{ marginTop: 8, paddingLeft: 18 }}>
378
439
  {detail.evidence.map((artifact) => (
379
440
  <li key={artifact.name} style={{ marginBottom: 4 }}>
380
- <a href={`/api/features/${detail.feature.feature_id}/evidence/${artifact.name}${projectQuery(project)}`}>
441
+ <a
442
+ href={`/api/features/${detail.feature.feature_id}/evidence/${artifact.name}${projectQuery(project)}`}
443
+ >
381
444
  {artifact.name}
382
445
  </a>
383
446
  </li>
@@ -7,7 +7,7 @@ import type {
7
7
  EvidenceArtifact,
8
8
  FeatureDetail,
9
9
  FeaturesIndex,
10
- FeatureSummary
10
+ FeatureSummary,
11
11
  } from './types.js';
12
12
 
13
13
  const AOP_ROOT = process.env.AOP_ROOT ?? process.cwd();
@@ -25,7 +25,7 @@ const STATUS_TO_PHASE: Record<string, FeatureSummary['phase']> = {
25
25
  merged: 'merged',
26
26
  blocked: 'blocked',
27
27
  failed: 'blocked',
28
- paused_budget: 'blocked'
28
+ paused_budget: 'blocked',
29
29
  };
30
30
 
31
31
  function parseFrontMatter(raw: string): ParsedFrontMatter {
@@ -42,16 +42,17 @@ function normalizeFeatureSummary(
42
42
  featureId: string,
43
43
  frontMatter: Record<string, unknown>,
44
44
  index: FeaturesIndex,
45
- repoRoot = AOP_ROOT
45
+ repoRoot = AOP_ROOT,
46
46
  ): FeatureSummary {
47
47
  const status = typeof frontMatter.status === 'string' ? frontMatter.status : 'unknown';
48
- const blockedQueue = Array.isArray(index.blocked_queue) ? index.blocked_queue.map((entry) => entry.feature_id) : [];
49
- const phase =
50
- index.merged?.includes(featureId)
51
- ? 'merged'
52
- : index.blocked?.includes(featureId) || blockedQueue.includes(featureId)
53
- ? 'blocked'
54
- : STATUS_TO_PHASE[status] ?? (index.active?.includes(featureId) ? 'planning' : 'unknown');
48
+ const blockedQueue = Array.isArray(index.blocked_queue)
49
+ ? index.blocked_queue.map((entry) => entry.feature_id)
50
+ : [];
51
+ const phase = index.merged?.includes(featureId)
52
+ ? 'merged'
53
+ : index.blocked?.includes(featureId) || blockedQueue.includes(featureId)
54
+ ? 'blocked'
55
+ : (STATUS_TO_PHASE[status] ?? (index.active?.includes(featureId) ? 'planning' : 'unknown'));
55
56
  const branchRaw =
56
57
  typeof frontMatter.worktree_branch === 'string'
57
58
  ? frontMatter.worktree_branch
@@ -63,20 +64,28 @@ function normalizeFeatureSummary(
63
64
  feature_id: featureId,
64
65
  status,
65
66
  phase,
66
- plan_version: typeof frontMatter.plan_version === 'number' ? frontMatter.plan_version : undefined,
67
+ plan_version:
68
+ typeof frontMatter.plan_version === 'number' ? frontMatter.plan_version : undefined,
67
69
  locks_held: Array.isArray(frontMatter.locks) ? (frontMatter.locks as string[]) : undefined,
68
- gate_profile: typeof frontMatter.gate_profile === 'string' ? frontMatter.gate_profile : undefined,
70
+ gate_profile:
71
+ typeof frontMatter.gate_profile === 'string' ? frontMatter.gate_profile : undefined,
69
72
  branch: branchRaw,
70
73
  worktree_path:
71
74
  typeof frontMatter.worktree_path === 'string'
72
75
  ? frontMatter.worktree_path
73
76
  : path.join(repoRoot, '.worktrees', featureId),
74
- last_updated: typeof frontMatter.last_updated === 'string' ? frontMatter.last_updated : undefined,
75
- status_reason: typeof frontMatter.status_reason === 'string' ? frontMatter.status_reason : undefined,
77
+ last_updated:
78
+ typeof frontMatter.last_updated === 'string' ? frontMatter.last_updated : undefined,
79
+ status_reason:
80
+ typeof frontMatter.status_reason === 'string' ? frontMatter.status_reason : undefined,
76
81
  activity_state:
77
- typeof frontMatter.activity_state === 'string' ? (frontMatter.activity_state as FeatureSummary['activity_state']) : undefined,
82
+ typeof frontMatter.activity_state === 'string'
83
+ ? (frontMatter.activity_state as FeatureSummary['activity_state'])
84
+ : undefined,
78
85
  activity_last_event_at:
79
- typeof frontMatter.activity_last_event_at === 'string' ? frontMatter.activity_last_event_at : undefined,
86
+ typeof frontMatter.activity_last_event_at === 'string'
87
+ ? frontMatter.activity_last_event_at
88
+ : undefined,
80
89
  activity_detected_via:
81
90
  typeof frontMatter.activity_detected_via === 'string'
82
91
  ? (frontMatter.activity_detected_via as FeatureSummary['activity_detected_via'])
@@ -84,7 +93,7 @@ function normalizeFeatureSummary(
84
93
  pr:
85
94
  frontMatter.pr && typeof frontMatter.pr === 'object'
86
95
  ? (frontMatter.pr as FeatureSummary['pr'])
87
- : null
96
+ : null,
88
97
  };
89
98
  }
90
99
 
@@ -120,18 +129,29 @@ export async function readFeaturesIndex(repoRoot = AOP_ROOT): Promise<FeaturesIn
120
129
  }
121
130
  }
122
131
 
123
- export async function readFeatureState(featureId: string, repoRoot = AOP_ROOT): Promise<FeatureSummary | null> {
132
+ export async function readFeatureState(
133
+ featureId: string,
134
+ repoRoot = AOP_ROOT,
135
+ ): Promise<FeatureSummary | null> {
124
136
  const statePath = path.join(getFeatureRoot(featureId, repoRoot), 'state.md');
125
137
  try {
126
138
  const raw = await readFile(statePath, 'utf-8');
127
139
  const { frontMatter } = parseFrontMatter(raw);
128
- return normalizeFeatureSummary(featureId, frontMatter, { active: [], blocked: [], merged: [], blocked_queue: [] }, repoRoot);
140
+ return normalizeFeatureSummary(
141
+ featureId,
142
+ frontMatter,
143
+ { active: [], blocked: [], merged: [], blocked_queue: [] },
144
+ repoRoot,
145
+ );
129
146
  } catch {
130
147
  return null;
131
148
  }
132
149
  }
133
150
 
134
- export async function readFeaturePlan(featureId: string, repoRoot = AOP_ROOT): Promise<Record<string, unknown> | null> {
151
+ export async function readFeaturePlan(
152
+ featureId: string,
153
+ repoRoot = AOP_ROOT,
154
+ ): Promise<Record<string, unknown> | null> {
135
155
  const planPath = path.join(getFeatureRoot(featureId, repoRoot), 'plan.json');
136
156
  try {
137
157
  const raw = await readFile(planPath, 'utf-8');
@@ -150,7 +170,10 @@ export async function readFeatureDiff(featureId: string, repoRoot = AOP_ROOT): P
150
170
  }
151
171
  }
152
172
 
153
- export async function listEvidenceArtifacts(featureId: string, repoRoot = AOP_ROOT): Promise<EvidenceArtifact[]> {
173
+ export async function listEvidenceArtifacts(
174
+ featureId: string,
175
+ repoRoot = AOP_ROOT,
176
+ ): Promise<EvidenceArtifact[]> {
154
177
  const evidenceDir = path.join(getFeatureRoot(featureId, repoRoot), 'evidence');
155
178
  try {
156
179
  const files = await readdir(evidenceDir);
@@ -164,7 +187,7 @@ export async function listEvidenceArtifacts(featureId: string, repoRoot = AOP_RO
164
187
  artifacts.push({
165
188
  name: file,
166
189
  path: fullPath,
167
- updated_at: fileStat.mtime.toISOString()
190
+ updated_at: fileStat.mtime.toISOString(),
168
191
  });
169
192
  }
170
193
  return artifacts;
@@ -176,7 +199,7 @@ export async function listEvidenceArtifacts(featureId: string, repoRoot = AOP_RO
176
199
  export async function readEvidenceArtifact(
177
200
  featureId: string,
178
201
  artifactName: string,
179
- repoRoot = AOP_ROOT
202
+ repoRoot = AOP_ROOT,
180
203
  ): Promise<string | null> {
181
204
  const sanitized = path.basename(artifactName);
182
205
  if (sanitized !== artifactName) {
@@ -196,7 +219,7 @@ export async function readDashboardStatus(repoRoot = AOP_ROOT): Promise<Dashboar
196
219
  ...(index.active ?? []),
197
220
  ...(index.blocked ?? []),
198
221
  ...(index.merged ?? []),
199
- ...((index.blocked_queue ?? []).map((entry) => entry.feature_id))
222
+ ...(index.blocked_queue ?? []).map((entry) => entry.feature_id),
200
223
  ]);
201
224
 
202
225
  const features: FeatureSummary[] = [];
@@ -207,22 +230,27 @@ export async function readDashboardStatus(repoRoot = AOP_ROOT): Promise<Dashboar
207
230
  const { frontMatter } = parseFrontMatter(raw);
208
231
  features.push(normalizeFeatureSummary(featureId, frontMatter, index, repoRoot));
209
232
  } catch {
210
- const blockedQueue = Array.isArray(index.blocked_queue) ? index.blocked_queue.map((entry) => entry.feature_id) : [];
233
+ const blockedQueue = Array.isArray(index.blocked_queue)
234
+ ? index.blocked_queue.map((entry) => entry.feature_id)
235
+ : [];
211
236
  features.push({
212
237
  id: featureId,
213
238
  feature_id: featureId,
214
- status: index.merged?.includes(featureId) ? 'merged' : index.blocked?.includes(featureId) ? 'blocked' : 'unknown',
215
- phase:
216
- index.merged?.includes(featureId)
217
- ? 'merged'
218
- : index.blocked?.includes(featureId) || blockedQueue.includes(featureId)
219
- ? 'blocked'
220
- : index.active?.includes(featureId)
221
- ? 'planning'
222
- : 'unknown',
239
+ status: index.merged?.includes(featureId)
240
+ ? 'merged'
241
+ : index.blocked?.includes(featureId)
242
+ ? 'blocked'
243
+ : 'unknown',
244
+ phase: index.merged?.includes(featureId)
245
+ ? 'merged'
246
+ : index.blocked?.includes(featureId) || blockedQueue.includes(featureId)
247
+ ? 'blocked'
248
+ : index.active?.includes(featureId)
249
+ ? 'planning'
250
+ : 'unknown',
223
251
  branch: null,
224
252
  worktree_path: null,
225
- pr: null
253
+ pr: null,
226
254
  });
227
255
  }
228
256
  }
@@ -230,7 +258,10 @@ export async function readDashboardStatus(repoRoot = AOP_ROOT): Promise<Dashboar
230
258
  return { index, features };
231
259
  }
232
260
 
233
- export async function readFeatureDetail(featureId: string, repoRoot = AOP_ROOT): Promise<FeatureDetail | null> {
261
+ export async function readFeatureDetail(
262
+ featureId: string,
263
+ repoRoot = AOP_ROOT,
264
+ ): Promise<FeatureDetail | null> {
234
265
  const feature = await readFeatureState(featureId, repoRoot);
235
266
  if (!feature) {
236
267
  return null;
@@ -239,6 +270,6 @@ export async function readFeatureDetail(featureId: string, repoRoot = AOP_ROOT):
239
270
  feature,
240
271
  plan: await readFeaturePlan(featureId, repoRoot),
241
272
  diff: await readFeatureDiff(featureId, repoRoot),
242
- evidence: await listEvidenceArtifacts(featureId, repoRoot)
273
+ evidence: await listEvidenceArtifacts(featureId, repoRoot),
243
274
  };
244
275
  }