agentic-orchestrator 0.1.2 → 0.1.4

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 (300) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CLAUDE.md +126 -0
  3. package/README.md +166 -25
  4. package/agentic/orchestrator/adapters.yaml +3 -0
  5. package/agentic/orchestrator/gates.yaml +47 -0
  6. package/agentic/orchestrator/policy.yaml +89 -0
  7. package/agentic/orchestrator/schemas/adapters.schema.json +12 -0
  8. package/agentic/orchestrator/schemas/gates.schema.json +6 -1
  9. package/agentic/orchestrator/schemas/index.schema.json +14 -0
  10. package/agentic/orchestrator/schemas/multi-project.schema.json +41 -0
  11. package/agentic/orchestrator/schemas/policy.schema.json +449 -52
  12. package/agentic/orchestrator/schemas/state.schema.json +16 -0
  13. package/agentic/orchestrator/tools/catalog.json +68 -0
  14. package/agentic/orchestrator/tools/schemas/input/cost.get.input.schema.json +10 -0
  15. package/agentic/orchestrator/tools/schemas/input/cost.record.input.schema.json +13 -0
  16. package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +11 -0
  17. package/agentic/orchestrator/tools/schemas/input/performance.get_analytics.input.schema.json +10 -0
  18. package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +18 -0
  19. package/agentic/orchestrator/tools/schemas/output/cost.get.output.schema.json +13 -0
  20. package/agentic/orchestrator/tools/schemas/output/cost.record.output.schema.json +13 -0
  21. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +7 -0
  22. package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +23 -0
  23. package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +46 -0
  24. package/agentic/orchestrator/tools/schemas/output/performance.record_outcome.output.schema.json +10 -0
  25. package/agentic/orchestrator/tools.md +5 -0
  26. package/apps/control-plane/scripts/validate-architecture-rules.mjs +28 -2
  27. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +12 -0
  28. package/apps/control-plane/scripts/validate-mcp-contracts.ts +92 -0
  29. package/apps/control-plane/src/application/adapters/adapter-registry.ts +169 -0
  30. package/apps/control-plane/src/application/multi-project-loader.ts +119 -0
  31. package/apps/control-plane/src/application/services/activity-monitor-service.ts +199 -0
  32. package/apps/control-plane/src/application/services/cost-tracking-service.ts +82 -0
  33. package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +86 -0
  34. package/apps/control-plane/src/application/services/feature-deletion-service.ts +8 -7
  35. package/apps/control-plane/src/application/services/gate-interpolation-service.ts +15 -0
  36. package/apps/control-plane/src/application/services/gate-service.ts +38 -2
  37. package/apps/control-plane/src/application/services/instance-isolation-service.ts +18 -0
  38. package/apps/control-plane/src/application/services/issue-tracker-service.ts +469 -0
  39. package/apps/control-plane/src/application/services/merge-service.ts +67 -3
  40. package/apps/control-plane/src/application/services/notifier-service.ts +295 -0
  41. package/apps/control-plane/src/application/services/performance-analytics-service.ts +122 -0
  42. package/apps/control-plane/src/application/services/plan-service.ts +51 -0
  43. package/apps/control-plane/src/application/services/pr-monitor-service.ts +262 -0
  44. package/apps/control-plane/src/application/services/reactions-service.ts +175 -0
  45. package/apps/control-plane/src/application/services/reporting-service.ts +17 -2
  46. package/apps/control-plane/src/application/services/run-lease-service.ts +16 -38
  47. package/apps/control-plane/src/application/tools/tool-metadata.ts +4 -1
  48. package/apps/control-plane/src/cli/aop.ts +1 -1
  49. package/apps/control-plane/src/cli/attach-command-handler.ts +120 -0
  50. package/apps/control-plane/src/cli/cleanup-command-handler.ts +190 -0
  51. package/apps/control-plane/src/cli/cli-argument-parser.ts +69 -3
  52. package/apps/control-plane/src/cli/dashboard-command-handler.ts +57 -0
  53. package/apps/control-plane/src/cli/help-command-handler.ts +163 -0
  54. package/apps/control-plane/src/cli/init-command-handler.ts +609 -0
  55. package/apps/control-plane/src/cli/resume-command-handler.ts +1 -0
  56. package/apps/control-plane/src/cli/retry-command-handler.ts +138 -0
  57. package/apps/control-plane/src/cli/run-command-handler.ts +115 -3
  58. package/apps/control-plane/src/cli/send-command-handler.ts +65 -0
  59. package/apps/control-plane/src/cli/status-command-handler.ts +102 -2
  60. package/apps/control-plane/src/cli/types.ts +26 -1
  61. package/apps/control-plane/src/core/constants.ts +8 -2
  62. package/apps/control-plane/src/core/error-codes.ts +3 -1
  63. package/apps/control-plane/src/core/gates.ts +170 -50
  64. package/apps/control-plane/src/core/kernel.ts +280 -5
  65. package/apps/control-plane/src/core/path-layout.ts +12 -0
  66. package/apps/control-plane/src/core/tool-caller.ts +36 -0
  67. package/apps/control-plane/src/core/workspace-hooks.ts +87 -0
  68. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +258 -9
  69. package/apps/control-plane/src/providers/providers.ts +235 -14
  70. package/apps/control-plane/src/supervisor/build-wave-executor.ts +129 -8
  71. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +123 -5
  72. package/apps/control-plane/src/supervisor/run-coordinator.ts +143 -6
  73. package/apps/control-plane/src/supervisor/runtime.ts +135 -6
  74. package/apps/control-plane/src/supervisor/types.ts +12 -21
  75. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +8 -0
  76. package/apps/control-plane/test/activity-monitor.spec.ts +294 -0
  77. package/apps/control-plane/test/adapter-registry.spec.ts +132 -0
  78. package/apps/control-plane/test/batch-operations.spec.ts +112 -0
  79. package/apps/control-plane/test/bootstrap-attach.spec.ts +102 -0
  80. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +252 -0
  81. package/apps/control-plane/test/bootstrap.spec.ts +560 -0
  82. package/apps/control-plane/test/cleanup-command.spec.ts +301 -0
  83. package/apps/control-plane/test/cli-helpers.spec.ts +404 -1
  84. package/apps/control-plane/test/cli.unit.spec.ts +182 -1
  85. package/apps/control-plane/test/collision-queue.spec.ts +104 -1
  86. package/apps/control-plane/test/core-utils.spec.ts +175 -2
  87. package/apps/control-plane/test/cost-tracking.spec.ts +143 -0
  88. package/apps/control-plane/test/dashboard-api.integration.spec.ts +247 -0
  89. package/apps/control-plane/test/dashboard-client.spec.ts +116 -0
  90. package/apps/control-plane/test/dashboard-command.spec.ts +103 -0
  91. package/apps/control-plane/test/dependency-scheduler.spec.ts +189 -0
  92. package/apps/control-plane/test/epoch-tracking.spec.ts +4 -4
  93. package/apps/control-plane/test/feature-deletion-service.spec.ts +422 -0
  94. package/apps/control-plane/test/feature-lifecycle.spec.ts +202 -0
  95. package/apps/control-plane/test/git-spawn-error.spec.ts +24 -0
  96. package/apps/control-plane/test/incremental-gates.spec.ts +137 -0
  97. package/apps/control-plane/test/init-wizard.spec.ts +506 -0
  98. package/apps/control-plane/test/instance-isolation.spec.ts +83 -0
  99. package/apps/control-plane/test/issue-tracker.spec.ts +890 -0
  100. package/apps/control-plane/test/kernel.coverage.spec.ts +3 -5
  101. package/apps/control-plane/test/kernel.coverage2.spec.ts +871 -0
  102. package/apps/control-plane/test/kernel.spec.ts +13 -11
  103. package/apps/control-plane/test/lock-service.spec.ts +508 -0
  104. package/apps/control-plane/test/mcp-helpers.spec.ts +176 -0
  105. package/apps/control-plane/test/mcp.spec.ts +50 -15
  106. package/apps/control-plane/test/merge-service.spec.ts +67 -4
  107. package/apps/control-plane/test/multi-project.spec.ts +372 -0
  108. package/apps/control-plane/test/notifier-service.spec.ts +388 -0
  109. package/apps/control-plane/test/parallel-gates.spec.ts +312 -0
  110. package/apps/control-plane/test/patch-service.spec.ts +253 -0
  111. package/apps/control-plane/test/performance-analytics.spec.ts +338 -0
  112. package/apps/control-plane/test/planning-wave-executor.spec.ts +168 -0
  113. package/apps/control-plane/test/pr-monitor.spec.ts +385 -0
  114. package/apps/control-plane/test/providers.spec.ts +344 -1
  115. package/apps/control-plane/test/reactions.spec.ts +392 -0
  116. package/apps/control-plane/test/resume-command.spec.ts +390 -0
  117. package/apps/control-plane/test/run-coordinator.spec.ts +481 -2
  118. package/apps/control-plane/test/schema-date-time.spec.ts +46 -0
  119. package/apps/control-plane/test/service-retry-paths.spec.ts +30 -0
  120. package/apps/control-plane/test/services.spec.ts +95 -2
  121. package/apps/control-plane/test/session-management.spec.ts +450 -0
  122. package/apps/control-plane/test/spec-ingestion.spec.ts +190 -0
  123. package/apps/control-plane/test/supervisor-collaborators.spec.ts +699 -2
  124. package/apps/control-plane/test/supervisor.spec.ts +36 -30
  125. package/apps/control-plane/test/supervisor.unit.spec.ts +405 -0
  126. package/apps/control-plane/test/worker-decision-loop.spec.ts +57 -0
  127. package/apps/control-plane/test/workspace-hooks.spec.ts +177 -0
  128. package/apps/control-plane/vitest.config.ts +21 -5
  129. package/dist/apps/control-plane/application/adapters/adapter-registry.d.ts +44 -0
  130. package/dist/apps/control-plane/application/adapters/adapter-registry.js +76 -0
  131. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -0
  132. package/dist/apps/control-plane/application/multi-project-loader.d.ts +31 -0
  133. package/dist/apps/control-plane/application/multi-project-loader.js +82 -0
  134. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -0
  135. package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +43 -0
  136. package/dist/apps/control-plane/application/services/activity-monitor-service.js +132 -0
  137. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -0
  138. package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +28 -0
  139. package/dist/apps/control-plane/application/services/cost-tracking-service.js +48 -0
  140. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -0
  141. package/dist/apps/control-plane/application/services/dependency-scheduler-service.d.ts +26 -0
  142. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js +75 -0
  143. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -0
  144. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +2 -0
  145. package/dist/apps/control-plane/application/services/feature-deletion-service.js +6 -7
  146. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  147. package/dist/apps/control-plane/application/services/gate-interpolation-service.d.ts +7 -0
  148. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +7 -0
  149. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -0
  150. package/dist/apps/control-plane/application/services/gate-service.js +32 -2
  151. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  152. package/dist/apps/control-plane/application/services/instance-isolation-service.d.ts +11 -0
  153. package/dist/apps/control-plane/application/services/instance-isolation-service.js +17 -0
  154. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -0
  155. package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +65 -0
  156. package/dist/apps/control-plane/application/services/issue-tracker-service.js +358 -0
  157. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -0
  158. package/dist/apps/control-plane/application/services/merge-service.d.ts +4 -0
  159. package/dist/apps/control-plane/application/services/merge-service.js +44 -2
  160. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  161. package/dist/apps/control-plane/application/services/notifier-service.d.ts +74 -0
  162. package/dist/apps/control-plane/application/services/notifier-service.js +212 -0
  163. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -0
  164. package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +39 -0
  165. package/dist/apps/control-plane/application/services/performance-analytics-service.js +75 -0
  166. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -0
  167. package/dist/apps/control-plane/application/services/plan-service.d.ts +1 -0
  168. package/dist/apps/control-plane/application/services/plan-service.js +53 -0
  169. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  170. package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +44 -0
  171. package/dist/apps/control-plane/application/services/pr-monitor-service.js +192 -0
  172. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -0
  173. package/dist/apps/control-plane/application/services/reactions-service.d.ts +67 -0
  174. package/dist/apps/control-plane/application/services/reactions-service.js +114 -0
  175. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -0
  176. package/dist/apps/control-plane/application/services/reporting-service.d.ts +1 -0
  177. package/dist/apps/control-plane/application/services/reporting-service.js +13 -2
  178. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  179. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +2 -0
  180. package/dist/apps/control-plane/application/services/run-lease-service.js +14 -38
  181. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  182. package/dist/apps/control-plane/application/tools/tool-metadata.js +3 -1
  183. package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
  184. package/dist/apps/control-plane/cli/aop.d.ts +1 -1
  185. package/dist/apps/control-plane/cli/aop.js +1 -1
  186. package/dist/apps/control-plane/cli/attach-command-handler.d.ts +12 -0
  187. package/dist/apps/control-plane/cli/attach-command-handler.js +98 -0
  188. package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -0
  189. package/dist/apps/control-plane/cli/cleanup-command-handler.d.ts +12 -0
  190. package/dist/apps/control-plane/cli/cleanup-command-handler.js +162 -0
  191. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -0
  192. package/dist/apps/control-plane/cli/cli-argument-parser.js +73 -3
  193. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  194. package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +7 -0
  195. package/dist/apps/control-plane/cli/dashboard-command-handler.js +45 -0
  196. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -0
  197. package/dist/apps/control-plane/cli/help-command-handler.d.ts +8 -0
  198. package/dist/apps/control-plane/cli/help-command-handler.js +146 -0
  199. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -0
  200. package/dist/apps/control-plane/cli/init-command-handler.d.ts +26 -0
  201. package/dist/apps/control-plane/cli/init-command-handler.js +517 -0
  202. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -0
  203. package/dist/apps/control-plane/cli/resume-command-handler.js +1 -1
  204. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  205. package/dist/apps/control-plane/cli/retry-command-handler.d.ts +8 -0
  206. package/dist/apps/control-plane/cli/retry-command-handler.js +111 -0
  207. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -0
  208. package/dist/apps/control-plane/cli/run-command-handler.d.ts +5 -0
  209. package/dist/apps/control-plane/cli/run-command-handler.js +82 -3
  210. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  211. package/dist/apps/control-plane/cli/send-command-handler.d.ts +8 -0
  212. package/dist/apps/control-plane/cli/send-command-handler.js +55 -0
  213. package/dist/apps/control-plane/cli/send-command-handler.js.map +1 -0
  214. package/dist/apps/control-plane/cli/status-command-handler.d.ts +12 -1
  215. package/dist/apps/control-plane/cli/status-command-handler.js +55 -2
  216. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  217. package/dist/apps/control-plane/cli/types.d.ts +26 -1
  218. package/dist/apps/control-plane/cli/types.js +15 -1
  219. package/dist/apps/control-plane/cli/types.js.map +1 -1
  220. package/dist/apps/control-plane/core/constants.d.ts +6 -0
  221. package/dist/apps/control-plane/core/constants.js +8 -2
  222. package/dist/apps/control-plane/core/constants.js.map +1 -1
  223. package/dist/apps/control-plane/core/error-codes.d.ts +2 -0
  224. package/dist/apps/control-plane/core/error-codes.js +3 -1
  225. package/dist/apps/control-plane/core/error-codes.js.map +1 -1
  226. package/dist/apps/control-plane/core/gates.d.ts +4 -0
  227. package/dist/apps/control-plane/core/gates.js +140 -43
  228. package/dist/apps/control-plane/core/gates.js.map +1 -1
  229. package/dist/apps/control-plane/core/kernel.d.ts +50 -1
  230. package/dist/apps/control-plane/core/kernel.js +220 -7
  231. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  232. package/dist/apps/control-plane/core/path-layout.d.ts +3 -0
  233. package/dist/apps/control-plane/core/path-layout.js +9 -0
  234. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  235. package/dist/apps/control-plane/core/tool-caller.d.ts +32 -0
  236. package/dist/apps/control-plane/core/tool-caller.js +2 -0
  237. package/dist/apps/control-plane/core/tool-caller.js.map +1 -0
  238. package/dist/apps/control-plane/core/workspace-hooks.d.ts +20 -0
  239. package/dist/apps/control-plane/core/workspace-hooks.js +69 -0
  240. package/dist/apps/control-plane/core/workspace-hooks.js.map +1 -0
  241. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +245 -9
  242. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  243. package/dist/apps/control-plane/providers/providers.d.ts +42 -3
  244. package/dist/apps/control-plane/providers/providers.js +216 -5
  245. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  246. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
  247. package/dist/apps/control-plane/supervisor/build-wave-executor.js +115 -6
  248. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  249. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
  250. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +109 -5
  251. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  252. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +15 -0
  253. package/dist/apps/control-plane/supervisor/run-coordinator.js +132 -6
  254. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  255. package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
  256. package/dist/apps/control-plane/supervisor/runtime.js +110 -6
  257. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  258. package/dist/apps/control-plane/supervisor/types.d.ts +9 -16
  259. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  260. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +3 -0
  261. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +5 -0
  262. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  263. package/eslint.config.mjs +2 -1
  264. package/package.json +12 -2
  265. package/packages/web-dashboard/next-env.d.ts +5 -0
  266. package/packages/web-dashboard/next.config.js +7 -0
  267. package/packages/web-dashboard/package.json +26 -0
  268. package/packages/web-dashboard/src/app/api/actions/route.ts +64 -0
  269. package/packages/web-dashboard/src/app/api/events/route.ts +51 -0
  270. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +256 -0
  271. package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +10 -0
  272. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +25 -0
  273. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +63 -0
  274. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +16 -0
  275. package/packages/web-dashboard/src/app/api/projects/route.ts +31 -0
  276. package/packages/web-dashboard/src/app/api/status/route.ts +15 -0
  277. package/packages/web-dashboard/src/app/globals.css +2 -0
  278. package/packages/web-dashboard/src/app/layout.tsx +15 -0
  279. package/packages/web-dashboard/src/app/page.tsx +393 -0
  280. package/packages/web-dashboard/src/lib/aop-client.ts +244 -0
  281. package/packages/web-dashboard/src/lib/multi-project-config.ts +116 -0
  282. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +284 -0
  283. package/packages/web-dashboard/src/lib/types.ts +58 -0
  284. package/packages/web-dashboard/tsconfig.json +40 -0
  285. package/packages/web-dashboard/vitest.config.ts +6 -0
  286. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +1764 -0
  287. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +348 -0
  288. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +344 -0
  289. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +374 -0
  290. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +1059 -0
  291. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +466 -0
  292. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +198 -0
  293. package/spec-files/outstanding/agentic_orchestrator_validator_hardening_spec.md +365 -0
  294. package/spec-files/progress.md +481 -52
  295. /package/spec-files/{agentic_orchestrator_cli_delete_command_spec.md → completed/agentic_orchestrator_cli_delete_command_spec.md} +0 -0
  296. /package/spec-files/{agentic_orchestrator_dot_aop_generated_artifacts_spec.md → completed/agentic_orchestrator_dot_aop_generated_artifacts_spec.md} +0 -0
  297. /package/spec-files/{agentic_orchestrator_mcp_formalization_spec.md → completed/agentic_orchestrator_mcp_formalization_spec.md} +0 -0
  298. /package/spec-files/{agentic_orchestrator_oop_refactor_spec.md → completed/agentic_orchestrator_oop_refactor_spec.md} +0 -0
  299. /package/spec-files/{agentic_orchestrator_single_global_orchestrator_spec.md → completed/agentic_orchestrator_single_global_orchestrator_spec.md} +0 -0
  300. /package/spec-files/{agentic_orchestrator_spec.md → completed/agentic_orchestrator_spec.md} +0 -0
package/eslint.config.mjs CHANGED
@@ -14,7 +14,8 @@ export default tseslint.config(
14
14
  '**/.aop/**',
15
15
  'agentic/features/**',
16
16
  'agentic/runtime/**',
17
- '**/*.d.ts'
17
+ '**/*.d.ts',
18
+ 'packages/web-dashboard/**'
18
19
  ]
19
20
  },
20
21
  js.configs.recommended,
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "agentic-orchestrator",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
+ "workspaces": [
6
+ "packages/*"
7
+ ],
5
8
  "type": "module",
6
9
  "description": "MCP-first, platform-agnostic multi-agent orchestrator control plane",
7
10
  "scripts": {
@@ -13,13 +16,18 @@
13
16
  "validate:mcp-contracts": "tsx apps/control-plane/scripts/validate-mcp-contracts.ts",
14
17
  "validate:docker-mcp": "node apps/control-plane/scripts/validate-docker-mcp-contract.mjs",
15
18
  "validate:architecture": "node apps/control-plane/scripts/validate-architecture-rules.mjs",
19
+ "validate:all": "npm run validate:mcp-contracts && npm run validate:docker-mcp && npm run validate:architecture",
16
20
  "lint": "eslint . --max-warnings 0",
17
- "lint:fix": "npm run lint -- --fix"
21
+ "lint:fix": "npm run lint -- --fix",
22
+ "dashboard:dev": "npm run --workspace @aop/web-dashboard dev",
23
+ "dashboard:build": "npm run --workspace @aop/web-dashboard build",
24
+ "dashboard:start": "npm run --workspace @aop/web-dashboard start"
18
25
  },
19
26
  "bin": {
20
27
  "aop": "dist/apps/control-plane/cli/aop.js"
21
28
  },
22
29
  "devDependencies": {
30
+ "@testing-library/react": "^14.3.1",
23
31
  "@eslint/js": "^9.37.0",
24
32
  "@types/node": "^22.13.10",
25
33
  "@vitest/coverage-v8": "^3.2.4",
@@ -29,10 +37,12 @@
29
37
  "tsx": "^4.19.3",
30
38
  "typescript-eslint": "^8.46.1",
31
39
  "typescript": "^5.8.2",
40
+ "msw": "^2.7.0",
32
41
  "vitest": "^3.2.4"
33
42
  },
34
43
  "dependencies": {
35
44
  "ajv": "^8.17.1",
45
+ "chalk": "^5.4.1",
36
46
  "minimatch": "^10.0.1",
37
47
  "yaml": "^2.6.1"
38
48
  }
@@ -0,0 +1,5 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // NOTE: This file should not be edited
5
+ // see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
@@ -0,0 +1,7 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ experimental: {
4
+ externalDir: true
5
+ }
6
+ };
7
+ export default nextConfig;
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@aop/web-dashboard",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "next dev",
8
+ "build": "next build",
9
+ "start": "next start",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@monaco-editor/react": "^4.7.0",
14
+ "next": "16.1.5",
15
+ "react": "^18.3.0",
16
+ "react-dom": "^18.3.0",
17
+ "tailwindcss": "^3.4.17",
18
+ "yaml": "^2.6.1"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^20.0.0",
22
+ "@types/react": "^18.3.0",
23
+ "@types/react-dom": "^18.3.0",
24
+ "typescript": "^5.4.0"
25
+ }
26
+ }
@@ -0,0 +1,64 @@
1
+ import { approveFeatureReview, denyFeatureReview, requestFeatureChanges } from '@/lib/orchestrator-tools';
2
+ import { resolveProjectRoot } from '@/lib/aop-client';
3
+
4
+ export const dynamic = 'force-dynamic';
5
+
6
+ interface ActionsRequest {
7
+ action: 'review.approve' | 'review.deny' | 'review.request_changes';
8
+ feature_id: string;
9
+ approval_token?: string;
10
+ reason?: string;
11
+ message?: string;
12
+ merge_strategy?: 'merge_commit' | 'squash' | 'rebase';
13
+ commit_message?: string;
14
+ }
15
+
16
+ export async function POST(req: Request): Promise<Response> {
17
+ const project = new URL(req.url).searchParams.get('project');
18
+ const repoRoot = await resolveProjectRoot(project);
19
+ const body = (await req.json()) as ActionsRequest;
20
+ if (!body.feature_id) {
21
+ return Response.json(
22
+ { ok: false, error: { code: 'feature_id_required', message: 'feature_id is required' } },
23
+ { status: 400 }
24
+ );
25
+ }
26
+
27
+ if (body.action === 'review.approve') {
28
+ if (!body.approval_token) {
29
+ return Response.json(
30
+ { ok: false, error: { code: 'approval_token_required', message: 'approval_token is required for approval' } },
31
+ { status: 400 }
32
+ );
33
+ }
34
+ const response = await approveFeatureReview(
35
+ body.feature_id,
36
+ body.approval_token,
37
+ body.merge_strategy ?? 'merge_commit',
38
+ body.commit_message,
39
+ repoRoot
40
+ );
41
+ return Response.json(response, { status: response.ok ? 200 : 409 });
42
+ }
43
+
44
+ if (body.action === 'review.deny') {
45
+ if (!body.reason || body.reason.trim().length === 0) {
46
+ return Response.json(
47
+ { ok: false, error: { code: 'reason_required', message: 'reason is required for deny action' } },
48
+ { status: 400 }
49
+ );
50
+ }
51
+ const response = await denyFeatureReview(body.feature_id, body.reason.trim(), repoRoot);
52
+ return Response.json(response, { status: response.ok ? 200 : 409 });
53
+ }
54
+
55
+ if (body.action === 'review.request_changes') {
56
+ const response = await requestFeatureChanges(body.feature_id, body.message ?? '', repoRoot);
57
+ return Response.json(response, { status: response.ok ? 200 : 409 });
58
+ }
59
+
60
+ return Response.json(
61
+ { ok: false, error: { code: 'unsupported_action', message: `Unsupported action: ${String(body.action)}` } },
62
+ { status: 400 }
63
+ );
64
+ }
@@ -0,0 +1,51 @@
1
+ import { readDashboardStatus, resolveProjectRoot } from '@/lib/aop-client';
2
+
3
+ export const dynamic = 'force-dynamic';
4
+
5
+ export async function GET(req: Request): Promise<Response> {
6
+ const url = new URL(req.url);
7
+ const project = url.searchParams.get('project');
8
+ const repoRoot = await resolveProjectRoot(project);
9
+ const encoder = new TextEncoder();
10
+ let heartbeatInterval: ReturnType<typeof setInterval> | undefined;
11
+ let pollInterval: ReturnType<typeof setInterval> | undefined;
12
+
13
+ const stream = new ReadableStream({
14
+ start(controller) {
15
+ // Send initial snapshot
16
+ void (async () => {
17
+ const payload = await readDashboardStatus(repoRoot);
18
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'snapshot', features: payload.index, payload })}\n\n`));
19
+ })();
20
+
21
+ // Heartbeat every 15s
22
+ heartbeatInterval = setInterval(() => {
23
+ try { controller.enqueue(encoder.encode(': heartbeat\n\n')); }
24
+ catch { clearInterval(heartbeatInterval); clearInterval(pollInterval); }
25
+ }, 15000);
26
+
27
+ // Poll every 2s
28
+ pollInterval = setInterval(() => {
29
+ void (async () => {
30
+ try {
31
+ const payload = await readDashboardStatus(repoRoot);
32
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'snapshot', features: payload.index, payload })}\n\n`));
33
+ } catch { /* ignore */ }
34
+ })();
35
+ }, 2000);
36
+ },
37
+ cancel() {
38
+ clearInterval(heartbeatInterval);
39
+ clearInterval(pollInterval);
40
+ },
41
+ });
42
+
43
+ return new Response(stream, {
44
+ headers: {
45
+ 'Content-Type': 'text/event-stream',
46
+ 'Cache-Control': 'no-cache',
47
+ 'Connection': 'keep-alive',
48
+ 'X-Accel-Buffering': 'no',
49
+ },
50
+ });
51
+ }
@@ -0,0 +1,256 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { access, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { readFeatureState, resolveProjectRoot } from '@/lib/aop-client';
6
+
7
+ const execFileAsync = promisify(execFile);
8
+
9
+ interface CheckoutRequest {
10
+ stash_changes?: boolean;
11
+ action?: 'checkout' | 'restore';
12
+ }
13
+
14
+ interface CheckoutRestoreRecord {
15
+ checked_out_feature_id: string;
16
+ checked_out_branch: string;
17
+ previous_branch: string;
18
+ stash_ref?: string;
19
+ created_at: string;
20
+ }
21
+
22
+ export const dynamic = 'force-dynamic';
23
+
24
+ function restoreFilePath(repoRoot: string): string {
25
+ return path.join(repoRoot, '.aop', 'runtime', 'checkout-restore.json');
26
+ }
27
+
28
+ async function git(repoRoot: string, args: string[]): Promise<{ stdout: string; stderr: string }> {
29
+ const result = await execFileAsync('git', args, { cwd: repoRoot });
30
+ return {
31
+ stdout: result.stdout ?? '',
32
+ stderr: result.stderr ?? ''
33
+ };
34
+ }
35
+
36
+ async function gitTry(repoRoot: string, args: string[]): Promise<{ ok: boolean; stdout: string; stderr: string }> {
37
+ try {
38
+ const result = await git(repoRoot, args);
39
+ return { ok: true, stdout: result.stdout, stderr: result.stderr };
40
+ } catch (error) {
41
+ const typed = error as { stdout?: string; stderr?: string };
42
+ return {
43
+ ok: false,
44
+ stdout: typed.stdout ?? '',
45
+ stderr: typed.stderr ?? ''
46
+ };
47
+ }
48
+ }
49
+
50
+ async function readRestoreRecord(repoRoot: string): Promise<CheckoutRestoreRecord | null> {
51
+ try {
52
+ const raw = await readFile(restoreFilePath(repoRoot), 'utf8');
53
+ return JSON.parse(raw) as CheckoutRestoreRecord;
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ async function branchExists(repoRoot: string, branch: string): Promise<boolean> {
60
+ const local = await gitTry(repoRoot, ['show-ref', '--verify', '--quiet', `refs/heads/${branch}`]);
61
+ if (local.ok) {
62
+ return true;
63
+ }
64
+ const remote = await gitTry(repoRoot, ['show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`]);
65
+ return remote.ok;
66
+ }
67
+
68
+ async function isDirtyWorkspace(repoRoot: string): Promise<boolean> {
69
+ const result = await gitTry(repoRoot, ['status', '--porcelain']);
70
+ return result.ok && result.stdout.trim().length > 0;
71
+ }
72
+
73
+ async function mergeInProgress(repoRoot: string): Promise<boolean> {
74
+ try {
75
+ await access(path.join(repoRoot, '.git', 'MERGE_HEAD'));
76
+ return true;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ async function currentBranch(repoRoot: string): Promise<string> {
83
+ const result = await git(repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD']);
84
+ return result.stdout.trim();
85
+ }
86
+
87
+ async function checkoutFeature(repoRoot: string, featureId: string, stashChanges: boolean): Promise<Response> {
88
+ if (await mergeInProgress(repoRoot)) {
89
+ return Response.json(
90
+ { ok: false, error: { code: 'merge_in_progress', message: 'Cannot checkout while merge is in progress' } },
91
+ { status: 409 }
92
+ );
93
+ }
94
+
95
+ const existing = await readRestoreRecord(repoRoot);
96
+ if (existing) {
97
+ return Response.json(
98
+ {
99
+ ok: false,
100
+ error: {
101
+ code: 'checkout_already_active',
102
+ message: `Checkout already active for feature ${existing.checked_out_feature_id}; restore first`
103
+ }
104
+ },
105
+ { status: 409 }
106
+ );
107
+ }
108
+
109
+ const state = await readFeatureState(featureId, repoRoot);
110
+ if (!state) {
111
+ return Response.json(
112
+ { ok: false, error: { code: 'feature_not_found', message: `Feature ${featureId} not found` } },
113
+ { status: 404 }
114
+ );
115
+ }
116
+
117
+ const branch = state.branch ?? featureId;
118
+ if (!(await branchExists(repoRoot, branch))) {
119
+ return Response.json(
120
+ { ok: false, error: { code: 'branch_not_found', message: `Feature branch not found: ${branch}` } },
121
+ { status: 404 }
122
+ );
123
+ }
124
+
125
+ const worktreePath = state.worktree_path ?? path.join(repoRoot, '.worktrees', featureId);
126
+ try {
127
+ await access(worktreePath);
128
+ } catch {
129
+ return Response.json(
130
+ { ok: false, error: { code: 'worktree_not_found', message: `Feature worktree not found: ${worktreePath}` } },
131
+ { status: 404 }
132
+ );
133
+ }
134
+
135
+ const previous = await currentBranch(repoRoot);
136
+ let stashRef: string | undefined;
137
+
138
+ if (stashChanges && (await isDirtyWorkspace(repoRoot))) {
139
+ const beforeStash = await gitTry(repoRoot, ['rev-parse', '--verify', '-q', 'refs/stash']);
140
+ await git(repoRoot, ['stash', 'push', '-u', '-m', `aop-dashboard-checkout:${featureId}:${Date.now()}`]);
141
+ const afterStash = await gitTry(repoRoot, ['rev-parse', '--verify', '-q', 'refs/stash']);
142
+ if (afterStash.ok && (!beforeStash.ok || beforeStash.stdout.trim() !== afterStash.stdout.trim())) {
143
+ stashRef = afterStash.stdout.trim();
144
+ }
145
+ }
146
+
147
+ const checkoutResult = await gitTry(repoRoot, ['checkout', branch]);
148
+ if (!checkoutResult.ok) {
149
+ return Response.json(
150
+ { ok: false, error: { code: 'checkout_failed', message: checkoutResult.stderr.trim() || 'git checkout failed' } },
151
+ { status: 409 }
152
+ );
153
+ }
154
+
155
+ const record: CheckoutRestoreRecord = {
156
+ checked_out_feature_id: featureId,
157
+ checked_out_branch: branch,
158
+ previous_branch: previous,
159
+ stash_ref: stashRef,
160
+ created_at: new Date().toISOString()
161
+ };
162
+ const restoreFile = restoreFilePath(repoRoot);
163
+ await mkdir(path.dirname(restoreFile), { recursive: true });
164
+ await writeFile(restoreFile, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
165
+
166
+ return Response.json({
167
+ ok: true,
168
+ data: {
169
+ feature_id: featureId,
170
+ branch,
171
+ previous_branch: previous,
172
+ stashed: Boolean(stashRef),
173
+ stash_ref: stashRef ?? null
174
+ }
175
+ });
176
+ }
177
+
178
+ async function restoreCheckout(repoRoot: string, featureId: string): Promise<Response> {
179
+ const saved = await readRestoreRecord(repoRoot);
180
+ if (!saved) {
181
+ return Response.json(
182
+ { ok: false, error: { code: 'restore_not_available', message: 'No active dashboard checkout to restore' } },
183
+ { status: 404 }
184
+ );
185
+ }
186
+
187
+ if (saved.checked_out_feature_id !== featureId) {
188
+ return Response.json(
189
+ {
190
+ ok: false,
191
+ error: {
192
+ code: 'restore_feature_mismatch',
193
+ message: `Active checkout belongs to ${saved.checked_out_feature_id}; restore that feature first`
194
+ }
195
+ },
196
+ { status: 409 }
197
+ );
198
+ }
199
+
200
+ const checkoutResult = await gitTry(repoRoot, ['checkout', saved.previous_branch]);
201
+ if (!checkoutResult.ok) {
202
+ return Response.json(
203
+ {
204
+ ok: false,
205
+ error: {
206
+ code: 'restore_checkout_failed',
207
+ message: checkoutResult.stderr.trim() || 'Failed to restore previous branch'
208
+ }
209
+ },
210
+ { status: 409 }
211
+ );
212
+ }
213
+
214
+ let stashRestored = false;
215
+ if (saved.stash_ref) {
216
+ const apply = await gitTry(repoRoot, ['stash', 'apply', '--index', saved.stash_ref]);
217
+ if (apply.ok) {
218
+ stashRestored = true;
219
+ await gitTry(repoRoot, ['stash', 'drop', saved.stash_ref]);
220
+ } else {
221
+ return Response.json(
222
+ {
223
+ ok: false,
224
+ error: {
225
+ code: 'stash_restore_failed',
226
+ message: apply.stderr.trim() || 'Failed to restore stashed changes'
227
+ }
228
+ },
229
+ { status: 409 }
230
+ );
231
+ }
232
+ }
233
+
234
+ await unlink(restoreFilePath(repoRoot)).catch(() => undefined);
235
+
236
+ return Response.json({
237
+ ok: true,
238
+ data: {
239
+ restored_to: saved.previous_branch,
240
+ stash_restored: stashRestored,
241
+ stash_ref: saved.stash_ref ?? null
242
+ }
243
+ });
244
+ }
245
+
246
+ export async function POST(req: Request, { params }: { params: { id: string } }): Promise<Response> {
247
+ const url = new URL(req.url);
248
+ const project = url.searchParams.get('project');
249
+ const repoRoot = await resolveProjectRoot(project);
250
+ const body = (await req.json()) as CheckoutRequest;
251
+ const action = body.action ?? 'checkout';
252
+ if (action === 'restore') {
253
+ return await restoreCheckout(repoRoot, params.id);
254
+ }
255
+ return await checkoutFeature(repoRoot, params.id, body.stash_changes ?? true);
256
+ }
@@ -0,0 +1,10 @@
1
+ import { readFeatureDiff, resolveProjectRoot } from '@/lib/aop-client';
2
+
3
+ export const dynamic = 'force-dynamic';
4
+
5
+ export async function GET(req: Request, { params }: { params: { id: string } }): Promise<Response> {
6
+ const project = new URL(req.url).searchParams.get('project');
7
+ const repoRoot = await resolveProjectRoot(project);
8
+ const diff = await readFeatureDiff(params.id, repoRoot);
9
+ return new Response(diff, { headers: { 'Content-Type': 'text/plain' } });
10
+ }
@@ -0,0 +1,25 @@
1
+ import { readEvidenceArtifact, resolveProjectRoot } from '@/lib/aop-client';
2
+
3
+ export const dynamic = 'force-dynamic';
4
+
5
+ export async function GET(
6
+ req: Request,
7
+ { params }: { params: { id: string; artifact: string } }
8
+ ): Promise<Response> {
9
+ const project = new URL(req.url).searchParams.get('project');
10
+ const repoRoot = await resolveProjectRoot(project);
11
+ const content = await readEvidenceArtifact(params.id, params.artifact, repoRoot);
12
+ if (content == null) {
13
+ return Response.json(
14
+ { ok: false, error: { code: 'artifact_not_found', message: `Artifact not found: ${params.artifact}` } },
15
+ { status: 404 }
16
+ );
17
+ }
18
+
19
+ return new Response(content, {
20
+ headers: {
21
+ 'Content-Type': params.artifact.endsWith('.json') ? 'application/json' : 'text/plain',
22
+ 'Content-Disposition': `attachment; filename="${params.artifact}"`
23
+ }
24
+ });
25
+ }
@@ -0,0 +1,63 @@
1
+ import {
2
+ approveFeatureReview,
3
+ denyFeatureReview,
4
+ requestFeatureChanges
5
+ } from '@/lib/orchestrator-tools';
6
+ import { resolveProjectRoot } from '@/lib/aop-client';
7
+
8
+ export const dynamic = 'force-dynamic';
9
+
10
+ interface ReviewRequest {
11
+ decision: 'approve' | 'deny' | 'request_changes';
12
+ approval_token?: string;
13
+ merge_strategy?: 'merge_commit' | 'squash' | 'rebase';
14
+ commit_message?: string;
15
+ reason?: string;
16
+ message?: string;
17
+ }
18
+
19
+ export async function POST(req: Request, { params }: { params: { id: string } }): Promise<Response> {
20
+ const project = new URL(req.url).searchParams.get('project');
21
+ const repoRoot = await resolveProjectRoot(project);
22
+ const body = (await req.json()) as ReviewRequest;
23
+
24
+ if (!['approve', 'deny', 'request_changes'].includes(body.decision)) {
25
+ return Response.json(
26
+ { ok: false, error: { code: 'invalid_decision', message: 'decision must be approve, deny, or request_changes' } },
27
+ { status: 400 }
28
+ );
29
+ }
30
+
31
+ if (body.decision === 'approve') {
32
+ if (!body.approval_token || body.approval_token.trim().length === 0) {
33
+ return Response.json(
34
+ { ok: false, error: { code: 'approval_token_required', message: 'approval_token is required for approve' } },
35
+ { status: 400 }
36
+ );
37
+ }
38
+
39
+ const response = await approveFeatureReview(
40
+ params.id,
41
+ body.approval_token.trim(),
42
+ body.merge_strategy ?? 'merge_commit',
43
+ body.commit_message,
44
+ repoRoot
45
+ );
46
+ return Response.json(response, { status: response.ok ? 200 : 409 });
47
+ }
48
+
49
+ if (body.decision === 'deny') {
50
+ const reason = body.reason?.trim();
51
+ if (!reason) {
52
+ return Response.json(
53
+ { ok: false, error: { code: 'reason_required', message: 'reason is required when decision=deny' } },
54
+ { status: 400 }
55
+ );
56
+ }
57
+ const response = await denyFeatureReview(params.id, reason, repoRoot);
58
+ return Response.json(response, { status: response.ok ? 200 : 409 });
59
+ }
60
+
61
+ const response = await requestFeatureChanges(params.id, body.message ?? '', repoRoot);
62
+ return Response.json(response, { status: response.ok ? 200 : 409 });
63
+ }
@@ -0,0 +1,16 @@
1
+ import { readFeatureDetail, resolveProjectRoot } from '@/lib/aop-client';
2
+
3
+ export const dynamic = 'force-dynamic';
4
+
5
+ export async function GET(req: Request, { params }: { params: { id: string } }): Promise<Response> {
6
+ const project = new URL(req.url).searchParams.get('project');
7
+ const repoRoot = await resolveProjectRoot(project);
8
+ const detail = await readFeatureDetail(params.id, repoRoot);
9
+ if (!detail) {
10
+ return Response.json(
11
+ { ok: false, error: { code: 'feature_not_found', message: `Feature ${params.id} not found` } },
12
+ { status: 404 }
13
+ );
14
+ }
15
+ return Response.json({ ok: true, data: detail });
16
+ }
@@ -0,0 +1,31 @@
1
+ import { getAopRoot } from '@/lib/aop-client';
2
+ import { readMultiProjectConfig } from '@/lib/multi-project-config';
3
+
4
+ export const dynamic = 'force-dynamic';
5
+
6
+ export async function GET(): Promise<Response> {
7
+ const config = await readMultiProjectConfig(getAopRoot());
8
+ if (!config) {
9
+ return Response.json({
10
+ ok: true,
11
+ data: {
12
+ projects: [],
13
+ defaults: null
14
+ }
15
+ });
16
+ }
17
+
18
+ return Response.json({
19
+ ok: true,
20
+ data: {
21
+ defaults: config.defaults ?? null,
22
+ projects: config.projects.map((project) => ({
23
+ name: project.name,
24
+ path: project.path,
25
+ policy: project.policy ?? null,
26
+ gates: project.gates ?? null,
27
+ dashboard_port: project.dashboard_port ?? null
28
+ }))
29
+ }
30
+ });
31
+ }
@@ -0,0 +1,15 @@
1
+ import { readDashboardStatus, resolveProjectRoot } from '@/lib/aop-client';
2
+
3
+ export const dynamic = 'force-dynamic';
4
+
5
+ export async function GET(req: Request): Promise<Response> {
6
+ const url = new URL(req.url);
7
+ const project = url.searchParams.get('project');
8
+ const repoRoot = await resolveProjectRoot(project);
9
+ const payload = await readDashboardStatus(repoRoot);
10
+ return Response.json({
11
+ ok: true,
12
+ data: payload,
13
+ timestamp: new Date().toISOString(),
14
+ });
15
+ }
@@ -0,0 +1,2 @@
1
+ * { box-sizing: border-box; margin: 0; padding: 0; }
2
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; }
@@ -0,0 +1,15 @@
1
+ import type { Metadata } from 'next';
2
+ import './globals.css';
3
+
4
+ export const metadata: Metadata = {
5
+ title: 'AOP Dashboard',
6
+ description: 'Agentic Orchestrator Dashboard',
7
+ };
8
+
9
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
10
+ return (
11
+ <html lang="en">
12
+ <body>{children}</body>
13
+ </html>
14
+ );
15
+ }