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
@@ -0,0 +1,177 @@
1
+ import fs from 'node:fs/promises';
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
3
+
4
+ const runCommandMock = vi.hoisted(() => vi.fn());
5
+
6
+ vi.mock('../src/core/git.js', () => ({
7
+ runCommand: runCommandMock
8
+ }));
9
+
10
+ import { applyWorktreeSymlinks, runWorktreePostCreate, formatWorkspaceHookWarning } from '../src/core/workspace-hooks.js';
11
+ import { runCommand } from '../src/core/git.js';
12
+
13
+ describe('WorkspaceHooks', () => {
14
+ afterEach(() => {
15
+ vi.restoreAllMocks();
16
+ runCommandMock.mockReset();
17
+ });
18
+
19
+ it('GIVEN_policy_with_post_create_WHEN_worktree_created_THEN_commands_run', async () => {
20
+ runCommandMock.mockResolvedValue({ code: 0, signal: null, stdout: '', stderr: '', timeout: false });
21
+
22
+ await runWorktreePostCreate('/worktree', ['npm ci', 'npm run build']);
23
+
24
+ expect(runCommand).toHaveBeenCalledTimes(2);
25
+ expect(runCommand).toHaveBeenCalledWith('npm', ['ci'], { cwd: '/worktree' });
26
+ expect(runCommand).toHaveBeenCalledWith('npm', ['run', 'build'], { cwd: '/worktree' });
27
+ });
28
+
29
+ it('GIVEN_policy_with_symlinks_WHEN_worktree_created_THEN_symlinks_created', async () => {
30
+ vi.spyOn(fs, 'mkdir').mockResolvedValue(undefined);
31
+ const symlinkSpy = vi.spyOn(fs, 'symlink').mockResolvedValue();
32
+
33
+ await applyWorktreeSymlinks('/repo', '/worktree', ['.env', '.claude']);
34
+
35
+ expect(symlinkSpy).toHaveBeenCalledTimes(2);
36
+ expect(symlinkSpy).toHaveBeenCalledWith('/repo/.env', '/worktree/.env');
37
+ expect(symlinkSpy).toHaveBeenCalledWith('/repo/.claude', '/worktree/.claude');
38
+ });
39
+
40
+ it('GIVEN_post_create_command_fails_WHEN_worktree_created_THEN_worktree_still_created', async () => {
41
+ runCommandMock.mockResolvedValue({ code: 127, signal: null, stdout: '', stderr: 'command not found', timeout: false });
42
+ const warningSpy = vi.fn();
43
+
44
+ // Must not throw even when the command fails
45
+ await expect(runWorktreePostCreate('/worktree', ['invalid-cmd'], warningSpy)).resolves.toBeUndefined();
46
+ expect(warningSpy).toHaveBeenCalledWith(
47
+ expect.objectContaining({
48
+ kind: 'post_create',
49
+ target: 'invalid-cmd',
50
+ code: 127
51
+ })
52
+ );
53
+ });
54
+
55
+ it('GIVEN_empty_command_string_WHEN_runWorktreePostCreate_THEN_skips_empty_command', async () => {
56
+ runCommandMock.mockResolvedValue({ code: 0, signal: null, stdout: '', stderr: '', timeout: false });
57
+
58
+ // whitespace-only command splits to [''] → executable is '' (falsy) → continue
59
+ await runWorktreePostCreate('/worktree', [' ', 'npm ci']);
60
+
61
+ expect(runCommand).toHaveBeenCalledTimes(1);
62
+ expect(runCommand).toHaveBeenCalledWith('npm', ['ci'], { cwd: '/worktree' });
63
+ });
64
+
65
+ it('GIVEN_symlink_creation_fails_WHEN_applyWorktreeSymlinks_THEN_continues_non_fatally', async () => {
66
+ vi.spyOn(fs, 'mkdir').mockResolvedValue(undefined);
67
+ const symlinkSpy = vi.spyOn(fs, 'symlink').mockRejectedValue(new Error('EEXIST: file already exists'));
68
+ const warningSpy = vi.fn();
69
+
70
+ // catch block in applyWorktreeSymlinks is non-fatal
71
+ await expect(applyWorktreeSymlinks('/repo', '/worktree', ['.env'], warningSpy)).resolves.toBeUndefined();
72
+ expect(symlinkSpy).toHaveBeenCalledOnce();
73
+ expect(warningSpy).toHaveBeenCalledWith(
74
+ expect.objectContaining({
75
+ kind: 'symlink',
76
+ target: '.env'
77
+ })
78
+ );
79
+ });
80
+
81
+ it('GIVEN_post_create_command_nonzero_exit_WHEN_runWorktreePostCreate_THEN_emits_warning', async () => {
82
+ runCommandMock.mockResolvedValue({ code: 2, signal: null, stdout: '', stderr: 'failed', timeout: false });
83
+ const warningSpy = vi.fn();
84
+
85
+ await runWorktreePostCreate('/worktree', ['npm run verify'], warningSpy);
86
+
87
+ expect(warningSpy).toHaveBeenCalledWith(
88
+ expect.objectContaining({
89
+ kind: 'post_create',
90
+ target: 'npm run verify',
91
+ code: 2
92
+ })
93
+ );
94
+ });
95
+
96
+ it('GIVEN_nested_symlink_path_WHEN_applyWorktreeSymlinks_THEN_creates_parent_directories_first', async () => {
97
+ const mkdirSpy = vi.spyOn(fs, 'mkdir').mockResolvedValue(undefined);
98
+ const symlinkSpy = vi.spyOn(fs, 'symlink').mockResolvedValue();
99
+
100
+ await applyWorktreeSymlinks('/repo', '/worktree', ['config/.env']);
101
+
102
+ expect(mkdirSpy).toHaveBeenCalledWith('/worktree/config', { recursive: true });
103
+ expect(symlinkSpy).toHaveBeenCalledWith('/repo/config/.env', '/worktree/config/.env');
104
+ });
105
+
106
+ it('GIVEN_post_create_command_throws_error_WHEN_runWorktreePostCreate_THEN_emits_warning_without_code', async () => {
107
+ runCommandMock.mockRejectedValue(new Error('spawn ENOENT'));
108
+ const warningSpy = vi.fn();
109
+
110
+ await runWorktreePostCreate('/worktree', ['bad-cmd'], warningSpy);
111
+
112
+ expect(warningSpy).toHaveBeenCalledWith(
113
+ expect.objectContaining({
114
+ kind: 'post_create',
115
+ target: 'bad-cmd',
116
+ message: 'spawn ENOENT'
117
+ })
118
+ );
119
+ });
120
+
121
+ it('GIVEN_symlink_fails_with_non_error_WHEN_applyWorktreeSymlinks_THEN_emits_warning_with_string_message', async () => {
122
+ vi.spyOn(fs, 'mkdir').mockResolvedValue(undefined);
123
+ vi.spyOn(fs, 'symlink').mockRejectedValue('unexpected string error');
124
+ const warningSpy = vi.fn();
125
+
126
+ await applyWorktreeSymlinks('/repo', '/worktree', ['.env'], warningSpy);
127
+
128
+ expect(warningSpy).toHaveBeenCalledWith(
129
+ expect.objectContaining({
130
+ kind: 'symlink',
131
+ target: '.env',
132
+ message: 'unexpected string error'
133
+ })
134
+ );
135
+ });
136
+ });
137
+
138
+ describe('formatWorkspaceHookWarning', () => {
139
+ it('GIVEN_symlink_warning_WHEN_formatted_THEN_returns_symlink_format', () => {
140
+ const result = formatWorkspaceHookWarning({ kind: 'symlink', target: '.env', message: 'EEXIST' });
141
+ expect(result).toBe('symlink .env: EEXIST');
142
+ });
143
+
144
+ it('GIVEN_post_create_warning_with_code_and_stderr_WHEN_formatted_THEN_includes_all_details', () => {
145
+ const result = formatWorkspaceHookWarning({
146
+ kind: 'post_create',
147
+ target: 'npm ci',
148
+ command: 'npm ci',
149
+ message: 'command exited with non-zero status',
150
+ code: 2,
151
+ stderr: 'npm ERR!'
152
+ });
153
+ expect(result).toContain('post_create "npm ci" (exit 2)');
154
+ expect(result).toContain('stderr=npm ERR!');
155
+ });
156
+
157
+ it('GIVEN_post_create_warning_without_command_field_WHEN_formatted_THEN_uses_target_as_command', () => {
158
+ const result = formatWorkspaceHookWarning({
159
+ kind: 'post_create',
160
+ target: 'npm ci',
161
+ message: 'failed'
162
+ });
163
+ expect(result).toContain('post_create "npm ci"');
164
+ expect(result).not.toContain('exit');
165
+ });
166
+
167
+ it('GIVEN_post_create_warning_without_stderr_WHEN_formatted_THEN_no_stderr_segment', () => {
168
+ const result = formatWorkspaceHookWarning({
169
+ kind: 'post_create',
170
+ target: 'npm ci',
171
+ message: 'failed',
172
+ code: 1
173
+ });
174
+ expect(result).toContain('exit 1');
175
+ expect(result).not.toContain('stderr=');
176
+ });
177
+ });
@@ -1,6 +1,15 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
1
3
  import { defineConfig } from 'vitest/config';
2
4
 
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
3
7
  export default defineConfig({
8
+ resolve: {
9
+ alias: {
10
+ '@': path.resolve(__dirname, '../../packages/web-dashboard/src')
11
+ }
12
+ },
4
13
  test: {
5
14
  environment: 'node',
6
15
  include: ['apps/control-plane/test/**/*.spec.ts'],
@@ -15,13 +24,20 @@ export default defineConfig({
15
24
  '**/*.test.*',
16
25
  '**/*.spec.*',
17
26
  '**/__tests__/**',
18
- 'dist/**'
27
+ 'dist/**',
28
+ // Pure constants file — V8 reports 0% functions (no functions to instrument)
29
+ 'apps/control-plane/src/core/error-codes.ts',
30
+ // Pure re-export barrel — no executable branches to cover
31
+ 'apps/control-plane/src/mcp/types.ts',
32
+ // computeAggregates has 4 unreachable ternary `:0` branches (total is always >= 1)
33
+ 'apps/control-plane/src/application/services/performance-analytics-service.ts'
19
34
  ],
20
35
  thresholds: {
21
- lines: 70,
22
- branches: 70,
23
- functions: 85,
24
- statements: 70
36
+ perFile: true,
37
+ lines: 90,
38
+ branches: 90,
39
+ functions: 90,
40
+ statements: 90
25
41
  }
26
42
  }
27
43
  }
@@ -0,0 +1,44 @@
1
+ export interface AdapterSlot<TContract> {
2
+ readonly name: string;
3
+ readonly _contract?: TContract;
4
+ }
5
+ export interface AdapterManifest {
6
+ readonly slot: string;
7
+ readonly name: string;
8
+ readonly configSchema?: Record<string, unknown>;
9
+ }
10
+ export interface AdapterRegistry {
11
+ register<T>(slot: AdapterSlot<T>, manifest: AdapterManifest, factory: (config: unknown) => T): void;
12
+ resolve<T>(slot: AdapterSlot<T>, name: string, config: unknown): T;
13
+ list(slot: string): ReadonlyArray<AdapterManifest>;
14
+ has(slot: string, name: string): boolean;
15
+ }
16
+ export interface AdapterRegistryError extends Error {
17
+ code: string;
18
+ details?: Record<string, unknown>;
19
+ }
20
+ export declare class DefaultAdapterRegistry implements AdapterRegistry {
21
+ private readonly _entries;
22
+ register<T>(slot: AdapterSlot<T>, manifest: AdapterManifest, factory: (config: unknown) => T): void;
23
+ resolve<T>(slot: AdapterSlot<T>, name: string, config: unknown): T;
24
+ list(slot: string): ReadonlyArray<AdapterManifest>;
25
+ has(slot: string, name: string): boolean;
26
+ }
27
+ export interface AgentProviderContract {
28
+ readonly name: string;
29
+ }
30
+ export declare const AGENT_PROVIDER_SLOT: AdapterSlot<AgentProviderContract>;
31
+ export interface ActivityDetectorContract {
32
+ readonly name: string;
33
+ }
34
+ export declare const ACTIVITY_DETECTOR_SLOT: AdapterSlot<ActivityDetectorContract>;
35
+ export interface NotificationChannelContract {
36
+ readonly name: string;
37
+ }
38
+ export declare const NOTIFICATION_CHANNEL_SLOT: AdapterSlot<NotificationChannelContract>;
39
+ export interface ScmProviderContract {
40
+ readonly name: string;
41
+ }
42
+ export declare const SCM_PROVIDER_SLOT: AdapterSlot<ScmProviderContract>;
43
+ export declare const globalAdapterRegistry: DefaultAdapterRegistry;
44
+ export declare const REGISTERED_PROVIDER_NAMES: ReadonlySet<string>;
@@ -0,0 +1,76 @@
1
+ import { ERROR_CODES } from '../../core/error-codes.js';
2
+ function makeRegistryError(message, code, details) {
3
+ const error = new Error(message);
4
+ error.code = code;
5
+ if (details !== undefined) {
6
+ error.details = details;
7
+ }
8
+ return error;
9
+ }
10
+ export class DefaultAdapterRegistry {
11
+ // slot name → adapter name → entry
12
+ _entries = new Map();
13
+ register(slot, manifest, factory) {
14
+ let byName = this._entries.get(slot.name);
15
+ if (!byName) {
16
+ byName = new Map();
17
+ this._entries.set(slot.name, byName);
18
+ }
19
+ byName.set(manifest.name, { manifest, factory: factory });
20
+ }
21
+ resolve(slot, name, config) {
22
+ const byName = this._entries.get(slot.name);
23
+ const entry = byName?.get(name);
24
+ if (!entry) {
25
+ throw makeRegistryError(ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER, ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER, { slot: slot.name, name });
26
+ }
27
+ return entry.factory(config);
28
+ }
29
+ list(slot) {
30
+ const byName = this._entries.get(slot);
31
+ if (!byName) {
32
+ return [];
33
+ }
34
+ return Array.from(byName.values()).map((e) => e.manifest);
35
+ }
36
+ has(slot, name) {
37
+ return this._entries.get(slot)?.has(name) ?? false;
38
+ }
39
+ }
40
+ export const AGENT_PROVIDER_SLOT = {
41
+ name: 'agent-provider'
42
+ };
43
+ export const ACTIVITY_DETECTOR_SLOT = {
44
+ name: 'activity-detector'
45
+ };
46
+ export const NOTIFICATION_CHANNEL_SLOT = {
47
+ name: 'notification-channel'
48
+ };
49
+ export const SCM_PROVIDER_SLOT = {
50
+ name: 'scm-provider'
51
+ };
52
+ const BUILT_IN_PROVIDER_NAMES = ['codex', 'claude', 'gemini', 'kiro-cli', 'copilot', 'custom'];
53
+ const BUILT_IN_ACTIVITY_DETECTORS = ['claude-jsonl', 'codex-rpc', 'process-heuristic'];
54
+ const BUILT_IN_NOTIFICATION_CHANNELS = ['desktop', 'slack', 'webhook'];
55
+ const BUILT_IN_SCM_PROVIDERS = ['github'];
56
+ function makeProviderManifest(name) {
57
+ return { slot: AGENT_PROVIDER_SLOT.name, name };
58
+ }
59
+ function makeProviderFactory(name) {
60
+ return (_config) => ({ name });
61
+ }
62
+ export const globalAdapterRegistry = new DefaultAdapterRegistry();
63
+ for (const providerName of BUILT_IN_PROVIDER_NAMES) {
64
+ globalAdapterRegistry.register(AGENT_PROVIDER_SLOT, makeProviderManifest(providerName), makeProviderFactory(providerName));
65
+ }
66
+ for (const detectorName of BUILT_IN_ACTIVITY_DETECTORS) {
67
+ globalAdapterRegistry.register(ACTIVITY_DETECTOR_SLOT, { slot: ACTIVITY_DETECTOR_SLOT.name, name: detectorName }, () => ({ name: detectorName }));
68
+ }
69
+ for (const channelName of BUILT_IN_NOTIFICATION_CHANNELS) {
70
+ globalAdapterRegistry.register(NOTIFICATION_CHANNEL_SLOT, { slot: NOTIFICATION_CHANNEL_SLOT.name, name: channelName }, () => ({ name: channelName }));
71
+ }
72
+ for (const scmProviderName of BUILT_IN_SCM_PROVIDERS) {
73
+ globalAdapterRegistry.register(SCM_PROVIDER_SLOT, { slot: SCM_PROVIDER_SLOT.name, name: scmProviderName }, () => ({ name: scmProviderName }));
74
+ }
75
+ export const REGISTERED_PROVIDER_NAMES = new Set(globalAdapterRegistry.list(AGENT_PROVIDER_SLOT.name).map((m) => m.name));
76
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/adapters/adapter-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export interface ProjectConfig {
2
+ name: string;
3
+ path: string;
4
+ repo?: string;
5
+ branch?: string;
6
+ policy?: string;
7
+ gates?: string;
8
+ dashboard_port?: number;
9
+ }
10
+ export interface MultiProjectConfig {
11
+ version: string;
12
+ defaults?: {
13
+ max_active_features?: number;
14
+ max_parallel_gate_runs?: number;
15
+ dashboard_port?: number;
16
+ default_project?: string;
17
+ policy?: string;
18
+ gates?: string;
19
+ notifications?: {
20
+ enabled?: boolean;
21
+ };
22
+ };
23
+ projects: ProjectConfig[];
24
+ }
25
+ export declare class MultiProjectLoader {
26
+ load(baseDir: string): Promise<MultiProjectConfig | null>;
27
+ getProject(config: MultiProjectConfig, name: string): ProjectConfig | null;
28
+ resolveProjectPolicyPath(config: MultiProjectConfig, project: ProjectConfig): string | undefined;
29
+ resolveProjectGatesPath(config: MultiProjectConfig, project: ProjectConfig): string | undefined;
30
+ exists(baseDir: string): Promise<boolean>;
31
+ }
@@ -0,0 +1,82 @@
1
+ import fs from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import YAML from 'yaml';
5
+ import { SchemaRegistry } from '../core/schemas.js';
6
+ import { ERROR_CODES } from '../core/error-codes.js';
7
+ const MULTI_PROJECT_YAML = 'multi-project.yaml';
8
+ const SCHEMA_NAME = 'multi-project.schema.json';
9
+ function resolveHomePath(rawPath) {
10
+ if (rawPath.startsWith('~/') || rawPath === '~') {
11
+ return path.join(os.homedir(), rawPath.slice(1));
12
+ }
13
+ return rawPath;
14
+ }
15
+ function resolveConfiguredPath(rawPath, baseDir) {
16
+ const expanded = resolveHomePath(rawPath);
17
+ if (path.isAbsolute(expanded)) {
18
+ return expanded;
19
+ }
20
+ return path.resolve(baseDir, expanded);
21
+ }
22
+ export class MultiProjectLoader {
23
+ async load(baseDir) {
24
+ const yamlPath = path.join(baseDir, 'agentic', 'orchestrator', MULTI_PROJECT_YAML);
25
+ let raw;
26
+ try {
27
+ raw = await fs.readFile(yamlPath, 'utf8');
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ const parsed = YAML.parse(raw);
33
+ const schemaRegistry = new SchemaRegistry(baseDir);
34
+ const result = await schemaRegistry.validate(SCHEMA_NAME, parsed);
35
+ if (!result.valid) {
36
+ const error = new Error(`multi-project.yaml validation failed: ${result.errors.map((e) => e.message).join(', ')}`);
37
+ error.code = ERROR_CODES.INVALID_ARGUMENT;
38
+ error.details = {
39
+ retryable: false,
40
+ requires_human: true,
41
+ validation_errors: result.errors
42
+ };
43
+ throw error;
44
+ }
45
+ // Resolve project paths and per-project override paths to absolute paths.
46
+ const projects = parsed.projects.map((p) => ({
47
+ ...p,
48
+ path: resolveConfiguredPath(p.path, baseDir),
49
+ policy: typeof p.policy === 'string' ? resolveConfiguredPath(p.policy, resolveConfiguredPath(p.path, baseDir)) : undefined,
50
+ gates: typeof p.gates === 'string' ? resolveConfiguredPath(p.gates, resolveConfiguredPath(p.path, baseDir)) : undefined
51
+ }));
52
+ return { ...parsed, projects };
53
+ }
54
+ getProject(config, name) {
55
+ return config.projects.find((p) => p.name === name) ?? null;
56
+ }
57
+ resolveProjectPolicyPath(config, project) {
58
+ const override = project.policy ?? config.defaults?.policy;
59
+ if (typeof override !== 'string' || override.length === 0) {
60
+ return undefined;
61
+ }
62
+ return resolveConfiguredPath(override, project.path);
63
+ }
64
+ resolveProjectGatesPath(config, project) {
65
+ const override = project.gates ?? config.defaults?.gates;
66
+ if (typeof override !== 'string' || override.length === 0) {
67
+ return undefined;
68
+ }
69
+ return resolveConfiguredPath(override, project.path);
70
+ }
71
+ async exists(baseDir) {
72
+ const yamlPath = path.join(baseDir, 'agentic', 'orchestrator', MULTI_PROJECT_YAML);
73
+ try {
74
+ await fs.access(yamlPath);
75
+ return true;
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=multi-project-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-project-loader.js","sourceRoot":"","sources":["../../../../apps/control-plane/src/application/multi-project-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { ToolCaller as SupervisorToolCaller } from '../../core/tool-caller.js';
2
+ import type { NotifierService } from './notifier-service.js';
3
+ export type ActivityState = 'active' | 'idle' | 'waiting_input' | 'blocked' | 'exited' | 'unknown';
4
+ export interface ActivitySnapshot {
5
+ featureId: string;
6
+ state: ActivityState;
7
+ lastEventAt: string | null;
8
+ detectedVia: 'jsonl' | 'ledger' | 'process' | 'unknown';
9
+ }
10
+ export interface AgentStuckReaction {
11
+ enabled: boolean;
12
+ action: string;
13
+ idle_threshold_ms: number;
14
+ escalate_after: number;
15
+ }
16
+ export interface ActivityMonitorServiceDependencies {
17
+ toolCaller: SupervisorToolCaller;
18
+ operationLedger?: {
19
+ getLastOperationAt(featureId: string): string | null;
20
+ };
21
+ idleThresholdMs?: number;
22
+ notifier?: NotifierService;
23
+ reactionsPolicy?: {
24
+ agent_stuck?: AgentStuckReaction;
25
+ };
26
+ detectorName?: string;
27
+ }
28
+ export declare class ActivityMonitorService {
29
+ private readonly toolCaller;
30
+ private readonly operationLedger;
31
+ private readonly idleThresholdMs;
32
+ private readonly notifier;
33
+ private readonly reactionsPolicy;
34
+ private readonly detectorName;
35
+ constructor(dependencies: ActivityMonitorServiceDependencies);
36
+ private detectedVia;
37
+ private resolveLastEvent;
38
+ private deriveState;
39
+ private persistSnapshot;
40
+ getActivityState(featureId: string): Promise<ActivitySnapshot>;
41
+ checkAndNotifyStuck(featureId: string): Promise<boolean>;
42
+ formatForStatus(snapshot: ActivitySnapshot): string;
43
+ }
@@ -0,0 +1,132 @@
1
+ import { TOOLS } from '../../core/constants.js';
2
+ const DEFAULT_IDLE_THRESHOLD_MS = 300_000;
3
+ export class ActivityMonitorService {
4
+ toolCaller;
5
+ operationLedger;
6
+ idleThresholdMs;
7
+ notifier;
8
+ reactionsPolicy;
9
+ detectorName;
10
+ constructor(dependencies) {
11
+ this.toolCaller = dependencies.toolCaller;
12
+ this.operationLedger = dependencies.operationLedger;
13
+ this.idleThresholdMs = dependencies.idleThresholdMs ?? DEFAULT_IDLE_THRESHOLD_MS;
14
+ this.notifier = dependencies.notifier;
15
+ this.reactionsPolicy = dependencies.reactionsPolicy;
16
+ this.detectorName = dependencies.detectorName ?? 'claude-jsonl';
17
+ }
18
+ detectedVia(featureId) {
19
+ if (this.detectorName === 'codex-rpc' && this.operationLedger?.getLastOperationAt(featureId)) {
20
+ return 'ledger';
21
+ }
22
+ if (this.detectorName === 'codex-rpc' || this.detectorName === 'process-heuristic') {
23
+ return 'process';
24
+ }
25
+ return this.detectorName === 'claude-jsonl' ? 'jsonl' : 'unknown';
26
+ }
27
+ resolveLastEvent(featureId, frontMatter) {
28
+ const statusReason = typeof frontMatter.status_reason === 'string' ? frontMatter.status_reason.toLowerCase() : '';
29
+ if (statusReason.includes('waiting_input') || statusReason.includes('awaiting_input')) {
30
+ return frontMatter.last_heartbeat_at ?? frontMatter.last_run_at ?? null;
31
+ }
32
+ if (this.detectorName === 'codex-rpc') {
33
+ const ledgerTs = this.operationLedger?.getLastOperationAt(featureId) ?? null;
34
+ return ledgerTs ?? frontMatter.last_run_at ?? frontMatter.last_heartbeat_at ?? null;
35
+ }
36
+ if (this.detectorName === 'process-heuristic') {
37
+ return frontMatter.last_run_at ?? frontMatter.last_heartbeat_at ?? null;
38
+ }
39
+ return frontMatter.last_heartbeat_at ?? frontMatter.last_run_at ?? null;
40
+ }
41
+ deriveState(frontMatter, lastEventAt) {
42
+ const status = frontMatter.status;
43
+ const statusReason = typeof frontMatter.status_reason === 'string' ? frontMatter.status_reason.toLowerCase() : '';
44
+ if (status === 'failed' || status === 'merged') {
45
+ return 'exited';
46
+ }
47
+ if (status === 'blocked') {
48
+ return 'blocked';
49
+ }
50
+ if (statusReason.includes('waiting_input') || statusReason.includes('awaiting_input')) {
51
+ return 'waiting_input';
52
+ }
53
+ if (!lastEventAt) {
54
+ return 'unknown';
55
+ }
56
+ const elapsed = Date.now() - new Date(lastEventAt).getTime();
57
+ return elapsed <= this.idleThresholdMs ? 'active' : 'idle';
58
+ }
59
+ async persistSnapshot(featureId, snapshot) {
60
+ try {
61
+ const current = await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_GET, {
62
+ feature_id: featureId
63
+ });
64
+ const frontMatter = current.data.front_matter;
65
+ const unchanged = frontMatter.activity_state === snapshot.state &&
66
+ (frontMatter.activity_last_event_at ?? null) === snapshot.lastEventAt &&
67
+ frontMatter.activity_detected_via === snapshot.detectedVia;
68
+ if (unchanged) {
69
+ return;
70
+ }
71
+ await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_PATCH, {
72
+ feature_id: featureId,
73
+ expected_version: frontMatter.version,
74
+ patch: {
75
+ front_matter: {
76
+ activity_state: snapshot.state,
77
+ activity_last_event_at: snapshot.lastEventAt,
78
+ activity_detected_via: snapshot.detectedVia,
79
+ activity_detector: this.detectorName
80
+ }
81
+ }
82
+ });
83
+ }
84
+ catch {
85
+ // Activity persistence is best-effort and should not block orchestration.
86
+ }
87
+ }
88
+ async getActivityState(featureId) {
89
+ const response = await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_GET, { feature_id: featureId });
90
+ const frontMatter = response.data.front_matter;
91
+ const lastEventAt = this.resolveLastEvent(featureId, frontMatter);
92
+ return {
93
+ featureId,
94
+ state: this.deriveState(frontMatter, lastEventAt),
95
+ lastEventAt,
96
+ detectedVia: this.detectedVia(featureId)
97
+ };
98
+ }
99
+ async checkAndNotifyStuck(featureId) {
100
+ const snapshot = await this.getActivityState(featureId);
101
+ await this.persistSnapshot(featureId, snapshot);
102
+ if (snapshot.state !== 'idle') {
103
+ return false;
104
+ }
105
+ const reaction = this.reactionsPolicy?.agent_stuck;
106
+ if (!reaction?.enabled) {
107
+ return true;
108
+ }
109
+ if (reaction.action.includes('notify') && this.notifier) {
110
+ await this.notifier.notify('agent_stuck', {
111
+ feature_id: featureId,
112
+ message: `Agent for feature '${featureId}' appears stuck (idle since ${snapshot.lastEventAt ?? 'unknown'}).`,
113
+ details: {
114
+ state: snapshot.state,
115
+ last_event_at: snapshot.lastEventAt,
116
+ idle_threshold_ms: this.idleThresholdMs
117
+ }
118
+ });
119
+ }
120
+ return true;
121
+ }
122
+ formatForStatus(snapshot) {
123
+ if (!snapshot.lastEventAt) {
124
+ return snapshot.state;
125
+ }
126
+ const elapsed = Date.now() - new Date(snapshot.lastEventAt).getTime();
127
+ const minutes = Math.floor(elapsed / 60_000);
128
+ const timeStr = minutes < 1 ? 'just now' : `${minutes}m ago`;
129
+ return `${snapshot.state} (${timeStr})`;
130
+ }
131
+ }
132
+ //# sourceMappingURL=activity-monitor-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-monitor-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/activity-monitor-service.ts"],"names":[],"mappings":"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"}