agentic-orchestrator 0.1.0

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 (439) hide show
  1. package/.dockerignore +24 -0
  2. package/.github/workflows/mcp-contract-validation.yml +38 -0
  3. package/Agentic-Orchestrator.iml +9 -0
  4. package/LICENSE +21 -0
  5. package/README.md +679 -0
  6. package/agentic/orchestrator/agents.yaml +14 -0
  7. package/agentic/orchestrator/gates.yaml +31 -0
  8. package/agentic/orchestrator/policy.yaml +145 -0
  9. package/agentic/orchestrator/prompts/builder.system.md +1 -0
  10. package/agentic/orchestrator/prompts/planner.system.md +15 -0
  11. package/agentic/orchestrator/prompts/qa.system.md +1 -0
  12. package/agentic/orchestrator/schemas/agents.schema.json +49 -0
  13. package/agentic/orchestrator/schemas/gates.schema.json +65 -0
  14. package/agentic/orchestrator/schemas/index.schema.json +108 -0
  15. package/agentic/orchestrator/schemas/plan.schema.json +127 -0
  16. package/agentic/orchestrator/schemas/policy.schema.json +227 -0
  17. package/agentic/orchestrator/schemas/qa_test_index.schema.json +53 -0
  18. package/agentic/orchestrator/schemas/state.schema.json +92 -0
  19. package/agentic/orchestrator/tools/catalog.json +399 -0
  20. package/agentic/orchestrator/tools/errors.schema.json +21 -0
  21. package/agentic/orchestrator/tools/protocol.json +8 -0
  22. package/agentic/orchestrator/tools/schemas/input/collisions.scan.input.schema.json +7 -0
  23. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +15 -0
  24. package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +42 -0
  25. package/agentic/orchestrator/tools/schemas/input/feature.discover_specs.input.schema.json +7 -0
  26. package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +15 -0
  27. package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +21 -0
  28. package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +26 -0
  29. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +34 -0
  30. package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +15 -0
  31. package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +28 -0
  32. package/agentic/orchestrator/tools/schemas/input/gates.list.input.schema.json +11 -0
  33. package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +29 -0
  34. package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +29 -0
  35. package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +26 -0
  36. package/agentic/orchestrator/tools/schemas/input/mutating.schema.json +14 -0
  37. package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +15 -0
  38. package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +28 -0
  39. package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +29 -0
  40. package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +15 -0
  41. package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +38 -0
  42. package/agentic/orchestrator/tools/schemas/input/read.schema.json +6 -0
  43. package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +25 -0
  44. package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +21 -0
  45. package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +15 -0
  46. package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +21 -0
  47. package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +20 -0
  48. package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +20 -0
  49. package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +15 -0
  50. package/agentic/orchestrator/tools/schemas/input/report.dashboard.input.schema.json +7 -0
  51. package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +15 -0
  52. package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +17 -0
  53. package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +20 -0
  54. package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +224 -0
  55. package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +32 -0
  56. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +40 -0
  57. package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +24 -0
  58. package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +24 -0
  59. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +30 -0
  60. package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +18 -0
  61. package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +24 -0
  62. package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +42 -0
  63. package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +37 -0
  64. package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +34 -0
  65. package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +24 -0
  66. package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +26 -0
  67. package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +23 -0
  68. package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +23 -0
  69. package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +22 -0
  70. package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +19 -0
  71. package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +33 -0
  72. package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +19 -0
  73. package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +32 -0
  74. package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +29 -0
  75. package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +24 -0
  76. package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +26 -0
  77. package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +27 -0
  78. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +21 -0
  79. package/agentic/orchestrator/tools/schemas/output/report.feature_summary.output.schema.json +36 -0
  80. package/agentic/orchestrator/tools/schemas/output/standard_success.schema.json +6 -0
  81. package/agentic/orchestrator/tools.md +32 -0
  82. package/apps/control-plane/project.json +39 -0
  83. package/apps/control-plane/scripts/validate-architecture-rules.mjs +170 -0
  84. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +84 -0
  85. package/apps/control-plane/scripts/validate-mcp-contracts.ts +61 -0
  86. package/apps/control-plane/src/application/services/collision-queue-service.ts +227 -0
  87. package/apps/control-plane/src/application/services/feature-deletion-service.ts +459 -0
  88. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +177 -0
  89. package/apps/control-plane/src/application/services/feature-state-service.ts +125 -0
  90. package/apps/control-plane/src/application/services/gate-service.ts +232 -0
  91. package/apps/control-plane/src/application/services/lock-service.ts +298 -0
  92. package/apps/control-plane/src/application/services/merge-service.ts +246 -0
  93. package/apps/control-plane/src/application/services/patch-service.ts +259 -0
  94. package/apps/control-plane/src/application/services/plan-service.ts +302 -0
  95. package/apps/control-plane/src/application/services/qa-index-service.ts +98 -0
  96. package/apps/control-plane/src/application/services/reporting-service.ts +120 -0
  97. package/apps/control-plane/src/application/services/run-lease-service.ts +340 -0
  98. package/apps/control-plane/src/application/tools/tool-metadata.ts +56 -0
  99. package/apps/control-plane/src/application/tools/tool-router.ts +43 -0
  100. package/apps/control-plane/src/cli/aop.ts +31 -0
  101. package/apps/control-plane/src/cli/cli-argument-parser.ts +116 -0
  102. package/apps/control-plane/src/cli/delete-command-handler.ts +90 -0
  103. package/apps/control-plane/src/cli/io.ts +14 -0
  104. package/apps/control-plane/src/cli/resume-command-handler.ts +228 -0
  105. package/apps/control-plane/src/cli/run-command-handler.ts +57 -0
  106. package/apps/control-plane/src/cli/spec-ingestion-service.ts +88 -0
  107. package/apps/control-plane/src/cli/spec-input-resolver.ts +95 -0
  108. package/apps/control-plane/src/cli/spec-utils.ts +40 -0
  109. package/apps/control-plane/src/cli/status-command-handler.ts +17 -0
  110. package/apps/control-plane/src/cli/stop-command-handler.ts +5 -0
  111. package/apps/control-plane/src/cli/tooling.ts +36 -0
  112. package/apps/control-plane/src/cli/types.ts +34 -0
  113. package/apps/control-plane/src/core/collisions.ts +121 -0
  114. package/apps/control-plane/src/core/constants.ts +72 -0
  115. package/apps/control-plane/src/core/error-codes.ts +54 -0
  116. package/apps/control-plane/src/core/frontmatter.ts +42 -0
  117. package/apps/control-plane/src/core/fs.ts +173 -0
  118. package/apps/control-plane/src/core/gates.ts +361 -0
  119. package/apps/control-plane/src/core/git.ts +115 -0
  120. package/apps/control-plane/src/core/kernel.ts +1077 -0
  121. package/apps/control-plane/src/core/patch.ts +152 -0
  122. package/apps/control-plane/src/core/path-layout.ts +113 -0
  123. package/apps/control-plane/src/core/path-rules.ts +71 -0
  124. package/apps/control-plane/src/core/qa-index.ts +179 -0
  125. package/apps/control-plane/src/core/response.ts +62 -0
  126. package/apps/control-plane/src/core/runtime-sessions.ts +20 -0
  127. package/apps/control-plane/src/core/schemas.ts +125 -0
  128. package/apps/control-plane/src/index.ts +21 -0
  129. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +100 -0
  130. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +39 -0
  131. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +74 -0
  132. package/apps/control-plane/src/mcp/operation-ledger.ts +108 -0
  133. package/apps/control-plane/src/mcp/protocol-contract.ts +9 -0
  134. package/apps/control-plane/src/mcp/runtime-factory.ts +105 -0
  135. package/apps/control-plane/src/mcp/runtime-types.ts +44 -0
  136. package/apps/control-plane/src/mcp/token-auth-verifier.ts +63 -0
  137. package/apps/control-plane/src/mcp/token-claims-validator.ts +72 -0
  138. package/apps/control-plane/src/mcp/token-codec.ts +62 -0
  139. package/apps/control-plane/src/mcp/tool-authorizer.ts +43 -0
  140. package/apps/control-plane/src/mcp/tool-client.ts +78 -0
  141. package/apps/control-plane/src/mcp/tool-contract-validator.ts +83 -0
  142. package/apps/control-plane/src/mcp/tool-registry-loader.ts +135 -0
  143. package/apps/control-plane/src/mcp/tool-runtime.ts +336 -0
  144. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +26 -0
  145. package/apps/control-plane/src/mcp/transport-types.ts +16 -0
  146. package/apps/control-plane/src/mcp/types.ts +2 -0
  147. package/apps/control-plane/src/providers/providers.ts +177 -0
  148. package/apps/control-plane/src/supervisor/build-wave-executor.ts +55 -0
  149. package/apps/control-plane/src/supervisor/lease-heartbeat-service.ts +22 -0
  150. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +316 -0
  151. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +62 -0
  152. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +99 -0
  153. package/apps/control-plane/src/supervisor/run-coordinator.ts +224 -0
  154. package/apps/control-plane/src/supervisor/runtime.ts +347 -0
  155. package/apps/control-plane/src/supervisor/session-orchestrator.ts +268 -0
  156. package/apps/control-plane/src/supervisor/types.ts +149 -0
  157. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +299 -0
  158. package/apps/control-plane/test/aop.spec.ts +101 -0
  159. package/apps/control-plane/test/cli-helpers.spec.ts +102 -0
  160. package/apps/control-plane/test/cli.spec.ts +12 -0
  161. package/apps/control-plane/test/cli.unit.spec.ts +609 -0
  162. package/apps/control-plane/test/collision-queue.spec.ts +158 -0
  163. package/apps/control-plane/test/collisions.spec.ts +138 -0
  164. package/apps/control-plane/test/core-utils.spec.ts +102 -0
  165. package/apps/control-plane/test/delete-command-handler.spec.ts +202 -0
  166. package/apps/control-plane/test/epoch-tracking.spec.ts +121 -0
  167. package/apps/control-plane/test/gates.spec.ts +452 -0
  168. package/apps/control-plane/test/helpers.ts +68 -0
  169. package/apps/control-plane/test/index.spec.ts +18 -0
  170. package/apps/control-plane/test/kernel-collision-replay.spec.ts +222 -0
  171. package/apps/control-plane/test/kernel.branches.spec.ts +321 -0
  172. package/apps/control-plane/test/kernel.coverage.spec.ts +408 -0
  173. package/apps/control-plane/test/kernel.spec.ts +369 -0
  174. package/apps/control-plane/test/mcp-helpers.spec.ts +195 -0
  175. package/apps/control-plane/test/mcp.spec.ts +776 -0
  176. package/apps/control-plane/test/merge-service.spec.ts +357 -0
  177. package/apps/control-plane/test/plan-service.spec.ts +195 -0
  178. package/apps/control-plane/test/planning-wave-executor.spec.ts +229 -0
  179. package/apps/control-plane/test/providers.spec.ts +168 -0
  180. package/apps/control-plane/test/qa-index-service.spec.ts +187 -0
  181. package/apps/control-plane/test/qa-index.spec.ts +317 -0
  182. package/apps/control-plane/test/response.spec.ts +55 -0
  183. package/apps/control-plane/test/run-coordinator.spec.ts +334 -0
  184. package/apps/control-plane/test/schema-date-time.spec.ts +170 -0
  185. package/apps/control-plane/test/service-retry-paths.spec.ts +305 -0
  186. package/apps/control-plane/test/services.spec.ts +693 -0
  187. package/apps/control-plane/test/spec-input-resolver.spec.ts +76 -0
  188. package/apps/control-plane/test/supervisor-collaborators.spec.ts +201 -0
  189. package/apps/control-plane/test/supervisor.calltool.spec.ts +120 -0
  190. package/apps/control-plane/test/supervisor.spec.ts +415 -0
  191. package/apps/control-plane/test/supervisor.unit.spec.ts +522 -0
  192. package/apps/control-plane/test/token-auth-verifier.spec.ts +111 -0
  193. package/apps/control-plane/test/tool-registry-loader.spec.ts +268 -0
  194. package/apps/control-plane/test/tool-runtime.spec.ts +294 -0
  195. package/apps/control-plane/test/worker-decision-loop.spec.ts +587 -0
  196. package/apps/control-plane/tsconfig.build.json +17 -0
  197. package/apps/control-plane/tsconfig.json +11 -0
  198. package/apps/control-plane/vitest.config.ts +28 -0
  199. package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +69 -0
  200. package/dist/apps/control-plane/application/services/collision-queue-service.js +158 -0
  201. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -0
  202. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +79 -0
  203. package/dist/apps/control-plane/application/services/feature-deletion-service.js +336 -0
  204. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -0
  205. package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +81 -0
  206. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +117 -0
  207. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -0
  208. package/dist/apps/control-plane/application/services/feature-state-service.d.ts +34 -0
  209. package/dist/apps/control-plane/application/services/feature-state-service.js +90 -0
  210. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -0
  211. package/dist/apps/control-plane/application/services/gate-service.d.ts +46 -0
  212. package/dist/apps/control-plane/application/services/gate-service.js +160 -0
  213. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -0
  214. package/dist/apps/control-plane/application/services/lock-service.d.ts +56 -0
  215. package/dist/apps/control-plane/application/services/lock-service.js +242 -0
  216. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -0
  217. package/dist/apps/control-plane/application/services/merge-service.d.ts +33 -0
  218. package/dist/apps/control-plane/application/services/merge-service.js +194 -0
  219. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -0
  220. package/dist/apps/control-plane/application/services/patch-service.d.ts +39 -0
  221. package/dist/apps/control-plane/application/services/patch-service.js +189 -0
  222. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -0
  223. package/dist/apps/control-plane/application/services/plan-service.d.ts +60 -0
  224. package/dist/apps/control-plane/application/services/plan-service.js +234 -0
  225. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -0
  226. package/dist/apps/control-plane/application/services/qa-index-service.d.ts +26 -0
  227. package/dist/apps/control-plane/application/services/qa-index-service.js +66 -0
  228. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -0
  229. package/dist/apps/control-plane/application/services/reporting-service.d.ts +47 -0
  230. package/dist/apps/control-plane/application/services/reporting-service.js +90 -0
  231. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -0
  232. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +74 -0
  233. package/dist/apps/control-plane/application/services/run-lease-service.js +263 -0
  234. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -0
  235. package/dist/apps/control-plane/application/tools/tool-metadata.d.ts +8 -0
  236. package/dist/apps/control-plane/application/tools/tool-metadata.js +37 -0
  237. package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -0
  238. package/dist/apps/control-plane/application/tools/tool-router.d.ts +16 -0
  239. package/dist/apps/control-plane/application/tools/tool-router.js +25 -0
  240. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -0
  241. package/dist/apps/control-plane/cli/aop.d.ts +5 -0
  242. package/dist/apps/control-plane/cli/aop.js +19 -0
  243. package/dist/apps/control-plane/cli/aop.js.map +1 -0
  244. package/dist/apps/control-plane/cli/cli-argument-parser.d.ts +5 -0
  245. package/dist/apps/control-plane/cli/cli-argument-parser.js +109 -0
  246. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -0
  247. package/dist/apps/control-plane/cli/delete-command-handler.d.ts +8 -0
  248. package/dist/apps/control-plane/cli/delete-command-handler.js +77 -0
  249. package/dist/apps/control-plane/cli/delete-command-handler.js.map +1 -0
  250. package/dist/apps/control-plane/cli/io.d.ts +2 -0
  251. package/dist/apps/control-plane/cli/io.js +14 -0
  252. package/dist/apps/control-plane/cli/io.js.map +1 -0
  253. package/dist/apps/control-plane/cli/resume-command-handler.d.ts +17 -0
  254. package/dist/apps/control-plane/cli/resume-command-handler.js +178 -0
  255. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -0
  256. package/dist/apps/control-plane/cli/run-command-handler.d.ts +15 -0
  257. package/dist/apps/control-plane/cli/run-command-handler.js +39 -0
  258. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -0
  259. package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +8 -0
  260. package/dist/apps/control-plane/cli/spec-ingestion-service.js +77 -0
  261. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -0
  262. package/dist/apps/control-plane/cli/spec-input-resolver.d.ts +9 -0
  263. package/dist/apps/control-plane/cli/spec-input-resolver.js +81 -0
  264. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -0
  265. package/dist/apps/control-plane/cli/spec-utils.d.ts +3 -0
  266. package/dist/apps/control-plane/cli/spec-utils.js +36 -0
  267. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -0
  268. package/dist/apps/control-plane/cli/status-command-handler.d.ts +7 -0
  269. package/dist/apps/control-plane/cli/status-command-handler.js +14 -0
  270. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -0
  271. package/dist/apps/control-plane/cli/stop-command-handler.d.ts +3 -0
  272. package/dist/apps/control-plane/cli/stop-command-handler.js +6 -0
  273. package/dist/apps/control-plane/cli/stop-command-handler.js.map +1 -0
  274. package/dist/apps/control-plane/cli/tooling.d.ts +4 -0
  275. package/dist/apps/control-plane/cli/tooling.js +24 -0
  276. package/dist/apps/control-plane/cli/tooling.js.map +1 -0
  277. package/dist/apps/control-plane/cli/types.d.ts +31 -0
  278. package/dist/apps/control-plane/cli/types.js +2 -0
  279. package/dist/apps/control-plane/cli/types.js.map +1 -0
  280. package/dist/apps/control-plane/core/collisions.d.ts +39 -0
  281. package/dist/apps/control-plane/core/collisions.js +78 -0
  282. package/dist/apps/control-plane/core/collisions.js.map +1 -0
  283. package/dist/apps/control-plane/core/constants.d.ts +64 -0
  284. package/dist/apps/control-plane/core/constants.js +64 -0
  285. package/dist/apps/control-plane/core/constants.js.map +1 -0
  286. package/dist/apps/control-plane/core/error-codes.d.ts +50 -0
  287. package/dist/apps/control-plane/core/error-codes.js +52 -0
  288. package/dist/apps/control-plane/core/error-codes.js.map +1 -0
  289. package/dist/apps/control-plane/core/frontmatter.d.ts +11 -0
  290. package/dist/apps/control-plane/core/frontmatter.js +30 -0
  291. package/dist/apps/control-plane/core/frontmatter.js.map +1 -0
  292. package/dist/apps/control-plane/core/fs.d.ts +33 -0
  293. package/dist/apps/control-plane/core/fs.js +134 -0
  294. package/dist/apps/control-plane/core/fs.js.map +1 -0
  295. package/dist/apps/control-plane/core/gates.d.ts +88 -0
  296. package/dist/apps/control-plane/core/gates.js +229 -0
  297. package/dist/apps/control-plane/core/gates.js.map +1 -0
  298. package/dist/apps/control-plane/core/git.d.ts +31 -0
  299. package/dist/apps/control-plane/core/git.js +79 -0
  300. package/dist/apps/control-plane/core/git.js.map +1 -0
  301. package/dist/apps/control-plane/core/kernel.d.ts +445 -0
  302. package/dist/apps/control-plane/core/kernel.js +805 -0
  303. package/dist/apps/control-plane/core/kernel.js.map +1 -0
  304. package/dist/apps/control-plane/core/patch.d.ts +23 -0
  305. package/dist/apps/control-plane/core/patch.js +118 -0
  306. package/dist/apps/control-plane/core/patch.js.map +1 -0
  307. package/dist/apps/control-plane/core/path-layout.d.ts +23 -0
  308. package/dist/apps/control-plane/core/path-layout.js +90 -0
  309. package/dist/apps/control-plane/core/path-layout.js.map +1 -0
  310. package/dist/apps/control-plane/core/path-rules.d.ts +13 -0
  311. package/dist/apps/control-plane/core/path-rules.js +52 -0
  312. package/dist/apps/control-plane/core/path-rules.js.map +1 -0
  313. package/dist/apps/control-plane/core/qa-index.d.ts +53 -0
  314. package/dist/apps/control-plane/core/qa-index.js +112 -0
  315. package/dist/apps/control-plane/core/qa-index.js.map +1 -0
  316. package/dist/apps/control-plane/core/response.d.ts +19 -0
  317. package/dist/apps/control-plane/core/response.js +34 -0
  318. package/dist/apps/control-plane/core/response.js.map +1 -0
  319. package/dist/apps/control-plane/core/runtime-sessions.d.ts +19 -0
  320. package/dist/apps/control-plane/core/runtime-sessions.js +2 -0
  321. package/dist/apps/control-plane/core/runtime-sessions.js.map +1 -0
  322. package/dist/apps/control-plane/core/schemas.d.ts +23 -0
  323. package/dist/apps/control-plane/core/schemas.js +80 -0
  324. package/dist/apps/control-plane/core/schemas.js.map +1 -0
  325. package/dist/apps/control-plane/index.d.ts +11 -0
  326. package/dist/apps/control-plane/index.js +9 -0
  327. package/dist/apps/control-plane/index.js.map +1 -0
  328. package/dist/apps/control-plane/interfaces/cli/bootstrap.d.ts +2 -0
  329. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +86 -0
  330. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -0
  331. package/dist/apps/control-plane/mcp/kernel-tool-executor.d.ts +14 -0
  332. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +26 -0
  333. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -0
  334. package/dist/apps/control-plane/mcp/mcp-server-adapter.d.ts +19 -0
  335. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +55 -0
  336. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -0
  337. package/dist/apps/control-plane/mcp/operation-ledger.d.ts +21 -0
  338. package/dist/apps/control-plane/mcp/operation-ledger.js +75 -0
  339. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -0
  340. package/dist/apps/control-plane/mcp/protocol-contract.d.ts +8 -0
  341. package/dist/apps/control-plane/mcp/protocol-contract.js +9 -0
  342. package/dist/apps/control-plane/mcp/protocol-contract.js.map +1 -0
  343. package/dist/apps/control-plane/mcp/runtime-factory.d.ts +38 -0
  344. package/dist/apps/control-plane/mcp/runtime-factory.js +71 -0
  345. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -0
  346. package/dist/apps/control-plane/mcp/runtime-types.d.ts +40 -0
  347. package/dist/apps/control-plane/mcp/runtime-types.js +2 -0
  348. package/dist/apps/control-plane/mcp/runtime-types.js.map +1 -0
  349. package/dist/apps/control-plane/mcp/token-auth-verifier.d.ts +24 -0
  350. package/dist/apps/control-plane/mcp/token-auth-verifier.js +45 -0
  351. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -0
  352. package/dist/apps/control-plane/mcp/token-claims-validator.d.ts +9 -0
  353. package/dist/apps/control-plane/mcp/token-claims-validator.js +62 -0
  354. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -0
  355. package/dist/apps/control-plane/mcp/token-codec.d.ts +11 -0
  356. package/dist/apps/control-plane/mcp/token-codec.js +46 -0
  357. package/dist/apps/control-plane/mcp/token-codec.js.map +1 -0
  358. package/dist/apps/control-plane/mcp/tool-authorizer.d.ts +8 -0
  359. package/dist/apps/control-plane/mcp/tool-authorizer.js +36 -0
  360. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -0
  361. package/dist/apps/control-plane/mcp/tool-client.d.ts +30 -0
  362. package/dist/apps/control-plane/mcp/tool-client.js +50 -0
  363. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -0
  364. package/dist/apps/control-plane/mcp/tool-contract-validator.d.ts +29 -0
  365. package/dist/apps/control-plane/mcp/tool-contract-validator.js +61 -0
  366. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -0
  367. package/dist/apps/control-plane/mcp/tool-registry-loader.d.ts +15 -0
  368. package/dist/apps/control-plane/mcp/tool-registry-loader.js +109 -0
  369. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -0
  370. package/dist/apps/control-plane/mcp/tool-runtime.d.ts +34 -0
  371. package/dist/apps/control-plane/mcp/tool-runtime.js +252 -0
  372. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -0
  373. package/dist/apps/control-plane/mcp/tools-markdown-generator.d.ts +7 -0
  374. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +22 -0
  375. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -0
  376. package/dist/apps/control-plane/mcp/transport-types.d.ts +14 -0
  377. package/dist/apps/control-plane/mcp/transport-types.js +2 -0
  378. package/dist/apps/control-plane/mcp/transport-types.js.map +1 -0
  379. package/dist/apps/control-plane/mcp/types.d.ts +2 -0
  380. package/dist/apps/control-plane/mcp/types.js +3 -0
  381. package/dist/apps/control-plane/mcp/types.js.map +1 -0
  382. package/dist/apps/control-plane/providers/providers.d.ts +72 -0
  383. package/dist/apps/control-plane/providers/providers.js +94 -0
  384. package/dist/apps/control-plane/providers/providers.js.map +1 -0
  385. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +13 -0
  386. package/dist/apps/control-plane/supervisor/build-wave-executor.js +40 -0
  387. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -0
  388. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.d.ts +12 -0
  389. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js +14 -0
  390. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js.map +1 -0
  391. package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +19 -0
  392. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +249 -0
  393. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -0
  394. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.d.ts +9 -0
  395. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +53 -0
  396. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -0
  397. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +24 -0
  398. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +70 -0
  399. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -0
  400. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +49 -0
  401. package/dist/apps/control-plane/supervisor/run-coordinator.js +162 -0
  402. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -0
  403. package/dist/apps/control-plane/supervisor/runtime.d.ts +58 -0
  404. package/dist/apps/control-plane/supervisor/runtime.js +270 -0
  405. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -0
  406. package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +29 -0
  407. package/dist/apps/control-plane/supervisor/session-orchestrator.js +211 -0
  408. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -0
  409. package/dist/apps/control-plane/supervisor/types.d.ts +148 -0
  410. package/dist/apps/control-plane/supervisor/types.js +2 -0
  411. package/dist/apps/control-plane/supervisor/types.js.map +1 -0
  412. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +37 -0
  413. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +236 -0
  414. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -0
  415. package/docker/mcp.Dockerfile +14 -0
  416. package/docker/mcp.compose.yaml +15 -0
  417. package/docker/mcp.entrypoint.sh +17 -0
  418. package/eslint.config.mjs +93 -0
  419. package/example-configurations/README.md +26 -0
  420. package/example-configurations/java/agents.yaml +14 -0
  421. package/example-configurations/java/gates.yaml +29 -0
  422. package/example-configurations/java/policy.yaml +148 -0
  423. package/example-configurations/node/agents.yaml +14 -0
  424. package/example-configurations/node/gates.yaml +32 -0
  425. package/example-configurations/node/policy.yaml +143 -0
  426. package/nx.json +16 -0
  427. package/package.json +39 -0
  428. package/prompts/vitest-testing-standards.instructions.md +204 -0
  429. package/scripts/dev-shell-env.sh +7 -0
  430. package/scripts/nx-safe.mjs +33 -0
  431. package/spec-files/agentic_orchestrator_cli_delete_command_spec.md +310 -0
  432. package/spec-files/agentic_orchestrator_dot_aop_generated_artifacts_spec.md +211 -0
  433. package/spec-files/agentic_orchestrator_mcp_formalization_spec.md +379 -0
  434. package/spec-files/agentic_orchestrator_oop_refactor_spec.md +415 -0
  435. package/spec-files/agentic_orchestrator_single_global_orchestrator_spec.md +265 -0
  436. package/spec-files/agentic_orchestrator_spec.md +1334 -0
  437. package/spec-files/progress.md +452 -0
  438. package/tsconfig.base.json +15 -0
  439. package/tsconfig.json +11 -0
@@ -0,0 +1,805 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { ensureDir, pathExists, readJson, atomicWriteJson, atomicWriteFile, withFileLock, nowIso, stableHash } from './fs.js';
4
+ import { SchemaRegistry, loadAndValidateYaml } from './schemas.js';
5
+ import { normalizeRepoPath } from './path-rules.js';
6
+ import { parseFrontMatter, buildFrontMatter } from './frontmatter.js';
7
+ import { runGit, runCommand } from './git.js';
8
+ import { ERROR_CODES } from './error-codes.js';
9
+ import { ok, fail, withSuggestedActions } from './response.js';
10
+ import { ALLOWED_ACTORS, DEFAULT_CLUSTER, DEFAULT_ROLE_STATUS, GATE_RESULT, STATUS, TOOLS } from './constants.js';
11
+ import { AopPathLayout, ensureAopRuntimeLayout } from './path-layout.js';
12
+ import { ToolRegistryLoader } from '../mcp/tool-registry-loader.js';
13
+ import { ToolHandlerRegistry, ToolRouter } from '../application/tools/tool-router.js';
14
+ import { RunLeaseService } from '../application/services/run-lease-service.js';
15
+ import { LockService } from '../application/services/lock-service.js';
16
+ import { ReportingService } from '../application/services/reporting-service.js';
17
+ import { FeatureStateService } from '../application/services/feature-state-service.js';
18
+ import { FeatureLifecycleService } from '../application/services/feature-lifecycle-service.js';
19
+ import { PlanService } from '../application/services/plan-service.js';
20
+ import { PatchService } from '../application/services/patch-service.js';
21
+ import { GateService } from '../application/services/gate-service.js';
22
+ import { QaIndexService } from '../application/services/qa-index-service.js';
23
+ import { MergeService } from '../application/services/merge-service.js';
24
+ import { CollisionQueueService } from '../application/services/collision-queue-service.js';
25
+ import { FeatureDeletionService } from '../application/services/feature-deletion-service.js';
26
+ function asArray(value) {
27
+ return Array.isArray(value) ? value : [];
28
+ }
29
+ function readStringField(record, key) {
30
+ const value = record[key];
31
+ return typeof value === 'string' ? value : null;
32
+ }
33
+ function readNumberField(record, key) {
34
+ const value = record[key];
35
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
36
+ }
37
+ function readBooleanField(record, key) {
38
+ const value = record[key];
39
+ return typeof value === 'boolean' ? value : null;
40
+ }
41
+ function readObjectField(record, key) {
42
+ const value = record[key];
43
+ return value && typeof value === 'object' ? value : {};
44
+ }
45
+ function normalizeSet(array) {
46
+ return [...new Set(array)].sort((a, b) => a.localeCompare(b));
47
+ }
48
+ export class AopKernel {
49
+ repoRoot;
50
+ schemaRegistry;
51
+ loaded;
52
+ gatesConfig;
53
+ policy;
54
+ agentsConfig;
55
+ toolRegistry;
56
+ toolHandlers;
57
+ toolRouter;
58
+ runLeaseService;
59
+ lockService;
60
+ collisionQueueService;
61
+ reportingService;
62
+ featureStateService;
63
+ featureLifecycleService;
64
+ planService;
65
+ patchService;
66
+ gateService;
67
+ qaIndexService;
68
+ mergeService;
69
+ featureDeletionService;
70
+ pathLayout;
71
+ constructor(repoRoot) {
72
+ this.repoRoot = repoRoot;
73
+ this.pathLayout = new AopPathLayout(repoRoot);
74
+ this.schemaRegistry = new SchemaRegistry(repoRoot);
75
+ this.loaded = false;
76
+ this.gatesConfig = {};
77
+ this.policy = {};
78
+ this.agentsConfig = {};
79
+ this.toolRegistry = null;
80
+ this.toolHandlers = new ToolHandlerRegistry();
81
+ this.registerToolHandlers();
82
+ this.runLeaseService = new RunLeaseService(this);
83
+ this.collisionQueueService = new CollisionQueueService(this);
84
+ this.lockService = new LockService(this);
85
+ this.reportingService = new ReportingService(this);
86
+ this.featureStateService = new FeatureStateService(this);
87
+ this.featureLifecycleService = new FeatureLifecycleService(this);
88
+ this.planService = new PlanService(this);
89
+ this.patchService = new PatchService(this);
90
+ this.gateService = new GateService(this);
91
+ this.qaIndexService = new QaIndexService(this);
92
+ this.mergeService = new MergeService(this);
93
+ this.featureDeletionService = new FeatureDeletionService(this);
94
+ this.toolRouter = new ToolRouter(this.toolHandlers, (toolName) => Promise.resolve(fail(ERROR_CODES.INVALID_ARGUMENT, `Unknown tool ${toolName}`, {
95
+ retryable: false,
96
+ requires_human: true
97
+ })));
98
+ }
99
+ getRepoRoot() {
100
+ return this.repoRoot;
101
+ }
102
+ getAgentsConfig() {
103
+ return this.agentsConfig;
104
+ }
105
+ getRbacPolicy() {
106
+ return this.policy.rbac ?? {};
107
+ }
108
+ getPolicySnapshot() {
109
+ return this.policy;
110
+ }
111
+ getGatesConfig() {
112
+ return this.gatesConfig;
113
+ }
114
+ getFeaturesDir() {
115
+ return this.featuresDir;
116
+ }
117
+ get orchestratorDir() {
118
+ return this.pathLayout.orchestratorRoot;
119
+ }
120
+ get featuresDir() {
121
+ return this.pathLayout.featuresRoot;
122
+ }
123
+ get indexPath() {
124
+ return this.pathLayout.indexPath;
125
+ }
126
+ get indexLockPath() {
127
+ return this.pathLayout.indexLockPath;
128
+ }
129
+ runLeaseTtlSeconds() {
130
+ const configured = Number(this.policy?.locks?.lease_ttl_seconds ?? 300);
131
+ if (!Number.isFinite(configured) || configured <= 0) {
132
+ return 300;
133
+ }
134
+ return Math.floor(configured);
135
+ }
136
+ emptyRuntimeSessions(at = nowIso()) {
137
+ return {
138
+ run_id: 'none',
139
+ orchestrator_session_id: 'unknown',
140
+ provider: 'unknown',
141
+ model: 'unknown',
142
+ provider_config_ref_hash: stableHash('none'),
143
+ owner_instance_id: 'none',
144
+ lease_id: 'none',
145
+ started_at: at,
146
+ last_heartbeat_at: at,
147
+ lease_expires_at: at,
148
+ orchestrator_epoch: 0,
149
+ feature_sessions: {}
150
+ };
151
+ }
152
+ normalizeRuntimeSessions(value, at = nowIso()) {
153
+ const fallback = this.emptyRuntimeSessions(at);
154
+ const source = value && typeof value === 'object' ? value : {};
155
+ const featureSessionsInput = source.feature_sessions && typeof source.feature_sessions === 'object'
156
+ ? source.feature_sessions
157
+ : {};
158
+ const featureSessions = {};
159
+ for (const [featureId, raw] of Object.entries(featureSessionsInput)) {
160
+ if (!featureId || typeof raw !== 'object' || !raw) {
161
+ continue;
162
+ }
163
+ const typed = raw;
164
+ featureSessions[featureId] = {
165
+ planner_session_id: typeof typed.planner_session_id === 'string' ? typed.planner_session_id : 'unassigned',
166
+ builder_session_id: typeof typed.builder_session_id === 'string' ? typed.builder_session_id : 'unassigned',
167
+ qa_session_id: typeof typed.qa_session_id === 'string' ? typed.qa_session_id : 'unassigned'
168
+ };
169
+ }
170
+ const epoch = typeof source.orchestrator_epoch === 'number' && Number.isFinite(source.orchestrator_epoch)
171
+ ? Math.max(0, Math.floor(source.orchestrator_epoch))
172
+ : 0;
173
+ return {
174
+ run_id: typeof source.run_id === 'string' && source.run_id ? source.run_id : fallback.run_id,
175
+ orchestrator_session_id: typeof source.orchestrator_session_id === 'string' && source.orchestrator_session_id
176
+ ? source.orchestrator_session_id
177
+ : fallback.orchestrator_session_id,
178
+ provider: typeof source.provider === 'string' && source.provider ? source.provider : fallback.provider,
179
+ model: typeof source.model === 'string' && source.model ? source.model : fallback.model,
180
+ provider_config_ref_hash: typeof source.provider_config_ref_hash === 'string' && source.provider_config_ref_hash
181
+ ? source.provider_config_ref_hash
182
+ : fallback.provider_config_ref_hash,
183
+ owner_instance_id: typeof source.owner_instance_id === 'string' && source.owner_instance_id
184
+ ? source.owner_instance_id
185
+ : fallback.owner_instance_id,
186
+ lease_id: typeof source.lease_id === 'string' && source.lease_id ? source.lease_id : fallback.lease_id,
187
+ started_at: typeof source.started_at === 'string' && source.started_at ? source.started_at : fallback.started_at,
188
+ last_heartbeat_at: typeof source.last_heartbeat_at === 'string' && source.last_heartbeat_at
189
+ ? source.last_heartbeat_at
190
+ : fallback.last_heartbeat_at,
191
+ lease_expires_at: typeof source.lease_expires_at === 'string' && source.lease_expires_at
192
+ ? source.lease_expires_at
193
+ : fallback.lease_expires_at,
194
+ orchestrator_epoch: epoch,
195
+ feature_sessions: featureSessions
196
+ };
197
+ }
198
+ normalizeIndexShape(value) {
199
+ const now = nowIso();
200
+ const source = value && typeof value === 'object' ? value : {};
201
+ return {
202
+ version: typeof source.version === 'number' && Number.isFinite(source.version) ? Math.max(1, Math.floor(source.version)) : 1,
203
+ active: normalizeSet(asArray(source.active).filter((item) => typeof item === 'string')),
204
+ blocked: normalizeSet(asArray(source.blocked).filter((item) => typeof item === 'string')),
205
+ merged: normalizeSet(asArray(source.merged).filter((item) => typeof item === 'string')),
206
+ locks: source.locks && typeof source.locks === 'object' ? source.locks : {},
207
+ lock_leases: source.lock_leases && typeof source.lock_leases === 'object' ? source.lock_leases : {},
208
+ blocked_queue: asArray(source.blocked_queue).filter((item) => item && typeof item === 'object'),
209
+ updated_at: typeof source.updated_at === 'string' && source.updated_at ? source.updated_at : now,
210
+ runtime_sessions: this.normalizeRuntimeSessions(source.runtime_sessions, now)
211
+ };
212
+ }
213
+ isRunLeaseFresh(runtimeSessions) {
214
+ const expiry = new Date(runtimeSessions.lease_expires_at).getTime();
215
+ if (!Number.isFinite(expiry)) {
216
+ return false;
217
+ }
218
+ return expiry > Date.now();
219
+ }
220
+ async load() {
221
+ await ensureAopRuntimeLayout(this.pathLayout);
222
+ const gatesPath = path.join(this.orchestratorDir, 'gates.yaml');
223
+ const policyPath = path.join(this.orchestratorDir, 'policy.yaml');
224
+ const agentsPath = path.join(this.orchestratorDir, 'agents.yaml');
225
+ const gates = await loadAndValidateYaml(this.schemaRegistry, 'gates.schema.json', gatesPath);
226
+ if (!gates.validation.valid) {
227
+ throw new Error(`invalid_gates_yaml:${JSON.stringify(gates.validation.errors)}`);
228
+ }
229
+ const policy = await loadAndValidateYaml(this.schemaRegistry, 'policy.schema.json', policyPath);
230
+ if (!policy.validation.valid) {
231
+ throw new Error(`invalid_policy_yaml:${JSON.stringify(policy.validation.errors)}`);
232
+ }
233
+ const parsedPolicy = policy.parsed;
234
+ const implementation = readObjectField(parsedPolicy, 'implementation');
235
+ const testing = readObjectField(parsedPolicy, 'testing');
236
+ if (readStringField(implementation, 'workspace') !== 'nx') {
237
+ throw new Error(ERROR_CODES.INVALID_WORKSPACE_IMPLEMENTATION);
238
+ }
239
+ if (readStringField(testing, 'framework') !== 'vitest') {
240
+ throw new Error(ERROR_CODES.INVALID_WORKSPACE_IMPLEMENTATION);
241
+ }
242
+ const agentsExists = await pathExists(agentsPath);
243
+ let agents = { parsed: { version: 1, roles: {} }, validation: { valid: true, errors: [] } };
244
+ if (agentsExists) {
245
+ agents = await loadAndValidateYaml(this.schemaRegistry, 'agents.schema.json', agentsPath);
246
+ if (!agents.validation.valid) {
247
+ throw new Error(`invalid_agents_yaml:${JSON.stringify(agents.validation.errors)}`);
248
+ }
249
+ }
250
+ this.gatesConfig = gates.parsed;
251
+ this.policy = parsedPolicy;
252
+ this.agentsConfig = agents.parsed;
253
+ const registryLoader = new ToolRegistryLoader(this.repoRoot);
254
+ this.toolRegistry = await registryLoader.load();
255
+ this.loaded = true;
256
+ }
257
+ async ensureLoaded() {
258
+ if (!this.loaded) {
259
+ await this.load();
260
+ }
261
+ }
262
+ authorize(actorType, toolName) {
263
+ if (!ALLOWED_ACTORS.has(actorType)) {
264
+ return false;
265
+ }
266
+ const allowedTools = this.getRbacPolicy()[actorType] ?? [];
267
+ if (allowedTools.includes('*')) {
268
+ return true;
269
+ }
270
+ return allowedTools.includes(toolName);
271
+ }
272
+ async invoke(toolName, args = {}, context = {}) {
273
+ await this.ensureLoaded();
274
+ const actorType = context.actor_type ?? 'system';
275
+ const actorId = context.actor_id ?? 'system';
276
+ if (!this.authorize(actorType, toolName)) {
277
+ return fail(ERROR_CODES.FORBIDDEN_TOOL_FOR_ROLE, `Tool ${toolName} is not allowed for role ${actorType}`, withSuggestedActions({ actor_type: actorType, tool_name: toolName, retryable: false, requires_human: true }, ['Use orchestrator role for this operation']));
278
+ }
279
+ try {
280
+ const result = (await this.dispatchTool(toolName, args, { actorType, actorId }));
281
+ return ok(result.data ?? result, result.evidence);
282
+ }
283
+ catch (error) {
284
+ return this.normalizeError(error);
285
+ }
286
+ }
287
+ normalizeError(error) {
288
+ if (!error) {
289
+ return fail(ERROR_CODES.INTERNAL_ERROR, 'Unknown error');
290
+ }
291
+ if (typeof error === 'object' && error !== null && 'normalizedResponse' in error) {
292
+ return error.normalizedResponse;
293
+ }
294
+ const message = typeof error === 'object' && error !== null && 'message' in error
295
+ ? error.message
296
+ : undefined;
297
+ const text = String(message ?? error);
298
+ if (text.startsWith('path_out_of_bounds')) {
299
+ return fail(ERROR_CODES.PATH_OUT_OF_BOUNDS, 'Path escapes repository root', {
300
+ retryable: false,
301
+ requires_human: true
302
+ });
303
+ }
304
+ if (text.startsWith('lock_timeout:')) {
305
+ return fail(ERROR_CODES.LOCK_CONFLICT, 'Timed out waiting for lock', {
306
+ retryable: true,
307
+ requires_human: false
308
+ });
309
+ }
310
+ if (text.startsWith('unknown_gate_profile_or_mode:')) {
311
+ return fail(ERROR_CODES.UNKNOWN_GATE_PROFILE_OR_MODE, 'Unknown gate profile or mode', {
312
+ value: text.split(':')[1],
313
+ retryable: false,
314
+ requires_human: true
315
+ });
316
+ }
317
+ if (text.startsWith('unsupported_parser:')) {
318
+ return fail(ERROR_CODES.UNSUPPORTED_PARSER, 'Gate parser type is not supported', {
319
+ parser: text.split(':')[1],
320
+ retryable: false,
321
+ requires_human: true
322
+ });
323
+ }
324
+ if (text.includes('qa_index_version_conflict')) {
325
+ return fail(ERROR_CODES.QA_INDEX_VERSION_CONFLICT, 'QA index expected_version did not match current version', {
326
+ retryable: true,
327
+ requires_human: false
328
+ });
329
+ }
330
+ return fail(ERROR_CODES.INTERNAL_ERROR, text, {
331
+ retryable: false,
332
+ requires_human: true
333
+ });
334
+ }
335
+ async dispatchTool(toolName, args, context) {
336
+ return await this.toolRouter.route(toolName, args, context);
337
+ }
338
+ registerToolHandlers() {
339
+ this.toolHandlers.register(TOOLS.FEATURE_DISCOVER_SPECS, async () => await this.featureDiscoverSpecs());
340
+ this.toolHandlers.register(TOOLS.FEATURE_INIT, async (args) => await this.featureInit(readStringField(args, 'feature_id')));
341
+ this.toolHandlers.register(TOOLS.FEATURE_GET_CONTEXT, async (args) => await this.featureGetContext(readStringField(args, 'feature_id')));
342
+ this.toolHandlers.register(TOOLS.FEATURE_STATE_GET, async (args) => await this.featureStateGet(readStringField(args, 'feature_id')));
343
+ this.toolHandlers.register(TOOLS.FEATURE_STATE_PATCH, async (args) => await this.featureStatePatch(readStringField(args, 'feature_id'), readNumberField(args, 'expected_version'), args.patch));
344
+ this.toolHandlers.register(TOOLS.FEATURE_LOG_APPEND, async (args, context) => await this.featureLogAppend(readStringField(args, 'feature_id'), readStringField(args, 'note'), context));
345
+ this.toolHandlers.register(TOOLS.PLAN_SUBMIT, async (args) => await this.planSubmit(readStringField(args, 'feature_id'), args.plan_json, readNumberField(args, 'expected_version')));
346
+ this.toolHandlers.register(TOOLS.PLAN_GET, async (args) => await this.planGet(readStringField(args, 'feature_id')));
347
+ this.toolHandlers.register(TOOLS.PLAN_UPDATE, async (args) => await this.planUpdate(readStringField(args, 'feature_id'), readNumberField(args, 'expected_plan_version'), args.plan_json));
348
+ this.toolHandlers.register(TOOLS.REPO_ENSURE_WORKTREE, async (args) => await this.repoEnsureWorktree(readStringField(args, 'feature_id')));
349
+ this.toolHandlers.register(TOOLS.REPO_APPLY_PATCH, async (args) => await this.repoApplyPatch(readStringField(args, 'feature_id'), readStringField(args, 'unified_diff')));
350
+ this.toolHandlers.register(TOOLS.REPO_STATUS, async (args) => await this.repoStatus(readStringField(args, 'feature_id')));
351
+ this.toolHandlers.register(TOOLS.REPO_DIFF, async (args) => await this.repoDiff(readStringField(args, 'feature_id'), asArray(args.options)));
352
+ this.toolHandlers.register(TOOLS.REPO_READ_FILE, async (args) => await this.repoReadFile(readStringField(args, 'feature_id'), readStringField(args, 'path')));
353
+ this.toolHandlers.register(TOOLS.REPO_SEARCH, async (args) => await this.repoSearch(readStringField(args, 'feature_id'), readStringField(args, 'query')));
354
+ this.toolHandlers.register(TOOLS.REPO_DIFF_BUNDLE, async (args) => await this.repoDiffBundle(readStringField(args, 'feature_id')));
355
+ this.toolHandlers.register(TOOLS.FEATURE_READY_TO_MERGE, async (args) => await this.featureReadyToMerge(readStringField(args, 'feature_id'), readStringField(args, 'commit_message'), readStringField(args, 'merge_strategy'), readStringField(args, 'user_approval_token')));
356
+ this.toolHandlers.register(TOOLS.FEATURE_DELETE, async (args) => await this.featureDelete(readStringField(args, 'feature_id'), readBooleanField(args, 'dry_run'), readBooleanField(args, 'confirm'), readBooleanField(args, 'remove_worktree'), readStringField(args, 'remove_branch')));
357
+ this.toolHandlers.register(TOOLS.GATES_LIST, async (args) => await this.gatesList(readStringField(args, 'profile')));
358
+ this.toolHandlers.register(TOOLS.GATES_RUN, async (args) => await this.gatesRun(readStringField(args, 'feature_id'), readStringField(args, 'profile'), readStringField(args, 'mode')));
359
+ this.toolHandlers.register(TOOLS.EVIDENCE_LATEST, async (args) => await this.evidenceLatest(readStringField(args, 'feature_id')));
360
+ this.toolHandlers.register(TOOLS.QA_TEST_INDEX_GET, async (args) => await this.qaTestIndexGet(readStringField(args, 'feature_id')));
361
+ this.toolHandlers.register(TOOLS.QA_TEST_INDEX_UPDATE, async (args) => await this.qaTestIndexUpdate(readStringField(args, 'feature_id'), readNumberField(args, 'expected_version'), args.updates, asArray(args.evidence_refs)));
362
+ this.toolHandlers.register(TOOLS.LOCKS_ACQUIRE, async (args) => await this.locksAcquire(readStringField(args, 'resource'), readStringField(args, 'feature_id'), readNumberField(args, 'wait_timeout_seconds')));
363
+ this.toolHandlers.register(TOOLS.LOCKS_RELEASE, async (args) => await this.locksRelease(readStringField(args, 'resource'), readStringField(args, 'feature_id')));
364
+ this.toolHandlers.register(TOOLS.COLLISIONS_SCAN, async () => await this.collisionsScan());
365
+ this.toolHandlers.register(TOOLS.REPORT_DASHBOARD, async () => await this.reportDashboard());
366
+ this.toolHandlers.register(TOOLS.REPORT_FEATURE_SUMMARY, async (args) => await this.reportFeatureSummary(readStringField(args, 'feature_id')));
367
+ }
368
+ featurePath(featureId) {
369
+ return this.pathLayout.featureRoot(featureId);
370
+ }
371
+ featureLockPath(featureId) {
372
+ return this.pathLayout.featureLockPath(featureId);
373
+ }
374
+ statePath(featureId) {
375
+ return this.pathLayout.statePath(featureId);
376
+ }
377
+ planPath(featureId) {
378
+ return this.pathLayout.planPath(featureId);
379
+ }
380
+ qaIndexPath(featureId) {
381
+ return this.pathLayout.qaIndexPath(featureId);
382
+ }
383
+ decisionsPath(featureId) {
384
+ return this.pathLayout.decisionsPath(featureId);
385
+ }
386
+ logsPath(featureId) {
387
+ return this.pathLayout.logsPath(featureId);
388
+ }
389
+ evidencePath(featureId) {
390
+ return this.pathLayout.evidencePath(featureId);
391
+ }
392
+ specPath(featureId) {
393
+ return this.pathLayout.specPath(featureId);
394
+ }
395
+ worktreePath(featureId) {
396
+ return path.join(this.repoRoot, '.worktrees', featureId);
397
+ }
398
+ async ensureFeatureLayout(featureId) {
399
+ const base = this.featurePath(featureId);
400
+ await ensureDir(base);
401
+ await ensureDir(this.logsPath(featureId));
402
+ await ensureDir(this.evidencePath(featureId));
403
+ const decisionsPath = this.decisionsPath(featureId);
404
+ if (!(await pathExists(decisionsPath))) {
405
+ await atomicWriteFile(decisionsPath, `# Decisions for ${featureId}\n\n`);
406
+ }
407
+ }
408
+ makeDefaultState(featureId, branch, worktreePath) {
409
+ return {
410
+ feature_id: featureId,
411
+ version: 1,
412
+ branch,
413
+ worktree_path: normalizeRepoPathForState(this.repoRoot, worktreePath),
414
+ status: STATUS.PLANNING,
415
+ gate_profile: 'default',
416
+ gates: {
417
+ plan: GATE_RESULT.NA,
418
+ fast: GATE_RESULT.NA,
419
+ full: GATE_RESULT.NA,
420
+ merge: GATE_RESULT.NA
421
+ },
422
+ locks: {
423
+ held: []
424
+ },
425
+ collisions: {
426
+ files: [],
427
+ areas: [],
428
+ contracts: []
429
+ },
430
+ cluster: { ...DEFAULT_CLUSTER },
431
+ role_status: { ...DEFAULT_ROLE_STATUS },
432
+ last_updated: nowIso()
433
+ };
434
+ }
435
+ async readState(featureId) {
436
+ const filePath = this.statePath(featureId);
437
+ const raw = await fs.readFile(filePath, 'utf8');
438
+ const parsed = parseFrontMatter(raw);
439
+ return {
440
+ frontMatter: parsed.frontMatter,
441
+ body: parsed.body,
442
+ raw
443
+ };
444
+ }
445
+ async writeState(featureId, frontMatter, body = '') {
446
+ const validation = await this.schemaRegistry.validate('state.schema.json', frontMatter);
447
+ if (!validation.valid) {
448
+ throw {
449
+ normalizedResponse: fail(ERROR_CODES.STATE_VALIDATION_FAILED, 'state.md front matter failed schema validation', {
450
+ errors: validation.errors,
451
+ retryable: false,
452
+ requires_human: true
453
+ })
454
+ };
455
+ }
456
+ const markdown = buildFrontMatter(frontMatter, body);
457
+ await atomicWriteFile(this.statePath(featureId), markdown);
458
+ }
459
+ async withFeatureLock(featureId, operation) {
460
+ return await withFileLock(this.featureLockPath(featureId), operation, {
461
+ timeoutMs: 30_000
462
+ });
463
+ }
464
+ async withIndexLock(operation) {
465
+ return await withFileLock(this.indexLockPath, operation, {
466
+ timeoutMs: 30_000
467
+ });
468
+ }
469
+ async readIndex() {
470
+ const existing = await readJson(this.indexPath, null);
471
+ const normalized = this.normalizeIndexShape(existing);
472
+ const changed = JSON.stringify(existing ?? null) !== JSON.stringify(normalized);
473
+ if (changed) {
474
+ await atomicWriteJson(this.indexPath, normalized);
475
+ }
476
+ return normalized;
477
+ }
478
+ async writeIndex(index) {
479
+ const normalized = this.normalizeIndexShape(index);
480
+ const validation = await this.schemaRegistry.validate('index.schema.json', normalized);
481
+ if (!validation.valid) {
482
+ throw {
483
+ normalizedResponse: fail(ERROR_CODES.INDEX_VALIDATION_FAILED, 'index.json failed schema validation', {
484
+ errors: validation.errors,
485
+ retryable: false,
486
+ requires_human: true
487
+ })
488
+ };
489
+ }
490
+ await atomicWriteJson(this.indexPath, normalized);
491
+ }
492
+ async validateSchema(schemaName, value) {
493
+ return await this.schemaRegistry.validate(schemaName, value);
494
+ }
495
+ async getRuntimeSessions() {
496
+ const index = await this.readIndex();
497
+ return this.normalizeRuntimeSessions(index.runtime_sessions);
498
+ }
499
+ async acquireRunLease(input) {
500
+ return await this.runLeaseService.acquireRunLease(input);
501
+ }
502
+ async renewRunLease(runId, ownerInstanceId) {
503
+ return await this.runLeaseService.renewRunLease(runId, ownerInstanceId);
504
+ }
505
+ async releaseRunLease(runId, ownerInstanceId) {
506
+ return await this.runLeaseService.releaseRunLease(runId, ownerInstanceId);
507
+ }
508
+ async updateOrchestratorSession(params) {
509
+ return await this.runLeaseService.updateOrchestratorSession(params);
510
+ }
511
+ async updateFeatureSessionAssignment(params) {
512
+ return await this.runLeaseService.updateFeatureSessionAssignment(params);
513
+ }
514
+ async pruneFeatureSessionAssignments(params) {
515
+ return await this.runLeaseService.pruneFeatureSessionAssignments(params);
516
+ }
517
+ async updateState(featureId, expectedVersion, updater) {
518
+ return await this.featureStateService.updateState(featureId, expectedVersion, updater);
519
+ }
520
+ async featureDiscoverSpecs() {
521
+ return await this.featureLifecycleService.featureDiscoverSpecs();
522
+ }
523
+ async featureInit(featureId) {
524
+ return await this.featureLifecycleService.featureInit(featureId);
525
+ }
526
+ async featureGetContext(featureId) {
527
+ return await this.featureLifecycleService.featureGetContext(featureId);
528
+ }
529
+ async featureStateGet(featureId) {
530
+ return await this.featureStateService.featureStateGet(featureId);
531
+ }
532
+ async featureStatePatch(featureId, expectedVersion, patch) {
533
+ return await this.featureStateService.featureStatePatch(featureId, expectedVersion, patch);
534
+ }
535
+ async featureLogAppend(featureId, note, context) {
536
+ return await this.featureLifecycleService.featureLogAppend(featureId, note, context);
537
+ }
538
+ async planGet(featureId) {
539
+ return await this.planService.planGet(featureId);
540
+ }
541
+ async collectAcceptedPlans(excludeFeatureId = null) {
542
+ return await this.planService.collectAcceptedPlans(excludeFeatureId);
543
+ }
544
+ async requiredResourcesForPlan(plan) {
545
+ return await this.planService.requiredResourcesForPlan(plan);
546
+ }
547
+ async assertPlanLocksHeld(featureId, plan) {
548
+ return await this.planService.assertPlanLocksHeld(featureId, plan);
549
+ }
550
+ validatePlanRevisionRules(existingPlan, plan, expectedPlanVersion = null) {
551
+ return this.planService.validatePlanRevisionRules(existingPlan, plan, expectedPlanVersion);
552
+ }
553
+ async validatePlanSchema(plan) {
554
+ return await this.planService.validatePlanSchema(plan);
555
+ }
556
+ async checkPlanCollision(featureId, plan) {
557
+ return await this.planService.checkPlanCollision(featureId, plan);
558
+ }
559
+ async planSubmit(featureId, plan, expectedVersion = null) {
560
+ return await this.planService.planSubmit(featureId, plan, expectedVersion);
561
+ }
562
+ async planUpdate(featureId, expectedPlanVersion, plan) {
563
+ return await this.planService.planUpdate(featureId, expectedPlanVersion, plan);
564
+ }
565
+ async repoEnsureWorktree(featureId) {
566
+ const worktree = this.worktreePath(featureId);
567
+ const branch = featureId;
568
+ await ensureDir(path.join(this.repoRoot, '.worktrees'));
569
+ if (await pathExists(worktree)) {
570
+ return {
571
+ data: {
572
+ feature_id: featureId,
573
+ branch,
574
+ worktree_path_abs: worktree,
575
+ existed: true
576
+ }
577
+ };
578
+ }
579
+ const baseBranch = this.policy.worktree.base_branch;
580
+ const baseCheck = await runGit(this.repoRoot, ['rev-parse', '--verify', baseBranch]);
581
+ const baseRef = baseCheck.code === 0 ? baseBranch : 'HEAD';
582
+ const branchCheck = await runGit(this.repoRoot, ['rev-parse', '--verify', branch]);
583
+ if (branchCheck.code !== 0) {
584
+ const branchCreate = await runGit(this.repoRoot, ['branch', branch, baseRef]);
585
+ if (branchCreate.code !== 0) {
586
+ throw {
587
+ normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Unable to create feature branch', {
588
+ feature_id: featureId,
589
+ stderr: branchCreate.stderr,
590
+ retryable: false,
591
+ requires_human: true
592
+ }, {
593
+ command: ['git', 'branch', branch, baseRef],
594
+ exit_code: branchCreate.code
595
+ })
596
+ };
597
+ }
598
+ }
599
+ const addWorktree = await runGit(this.repoRoot, ['worktree', 'add', worktree, branch]);
600
+ if (addWorktree.code !== 0) {
601
+ throw {
602
+ normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Unable to create git worktree', {
603
+ feature_id: featureId,
604
+ stderr: addWorktree.stderr,
605
+ retryable: false,
606
+ requires_human: true
607
+ }, {
608
+ command: ['git', 'worktree', 'add', worktree, branch],
609
+ exit_code: addWorktree.code
610
+ })
611
+ };
612
+ }
613
+ return {
614
+ data: {
615
+ feature_id: featureId,
616
+ branch,
617
+ worktree_path_abs: worktree,
618
+ existed: false
619
+ }
620
+ };
621
+ }
622
+ async loadAcceptedPlan(featureId) {
623
+ return await this.patchService.loadAcceptedPlan(featureId);
624
+ }
625
+ async validatePatchPaths(featureId, parsedDiff, plan) {
626
+ return await this.patchService.validatePatchPaths(featureId, parsedDiff, plan);
627
+ }
628
+ async repoApplyPatch(featureId, unifiedDiff) {
629
+ return await this.patchService.repoApplyPatch(featureId, unifiedDiff);
630
+ }
631
+ async repoStatus(featureId) {
632
+ const worktree = this.worktreePath(featureId);
633
+ const status = await runGit(this.repoRoot, ['status', '--porcelain'], { cwd: worktree });
634
+ const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: worktree });
635
+ return {
636
+ data: {
637
+ feature_id: featureId,
638
+ branch: branch.stdout.trim(),
639
+ status_porcelain: status.stdout.trim().split('\n').filter(Boolean)
640
+ }
641
+ };
642
+ }
643
+ async repoDiff(featureId, options = []) {
644
+ const safeOptions = asArray(options).filter((option) => typeof option === 'string' && option.startsWith('--'));
645
+ const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], { cwd: this.worktreePath(featureId) });
646
+ return {
647
+ data: {
648
+ feature_id: featureId,
649
+ diff: diff.stdout
650
+ }
651
+ };
652
+ }
653
+ async repoReadFile(featureId, filePath) {
654
+ const normalized = await normalizeRepoPath(this.repoRoot, path.join(this.worktreePath(featureId), filePath), this.policy.path_rules.allow_symlink_traversal)
655
+ .then((relative) => normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative));
656
+ const absolute = path.join(this.repoRoot, normalized);
657
+ const exists = await pathExists(absolute);
658
+ if (!exists) {
659
+ throw {
660
+ normalizedResponse: fail(ERROR_CODES.FILE_NOT_FOUND, 'File not found', {
661
+ path: normalized,
662
+ retryable: false,
663
+ requires_human: false
664
+ })
665
+ };
666
+ }
667
+ const content = await fs.readFile(absolute, 'utf8');
668
+ return {
669
+ data: {
670
+ feature_id: featureId,
671
+ path: normalized,
672
+ content
673
+ }
674
+ };
675
+ }
676
+ async repoSearch(featureId, query) {
677
+ const worktree = this.worktreePath(featureId);
678
+ const rgResult = await runCommand('rg', ['-n', '--no-heading', query, '.'], {
679
+ cwd: worktree,
680
+ timeoutMs: 30_000
681
+ });
682
+ if (rgResult.code === 127) {
683
+ throw {
684
+ normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'ripgrep (rg) not found - required for search functionality', {
685
+ stderr: rgResult.stderr,
686
+ retryable: false,
687
+ requires_human: true
688
+ })
689
+ };
690
+ }
691
+ if (rgResult.code !== 0 && rgResult.code !== 1) {
692
+ throw {
693
+ normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Search failed', {
694
+ stderr: rgResult.stderr,
695
+ retryable: true,
696
+ requires_human: false
697
+ })
698
+ };
699
+ }
700
+ const matches = rgResult.stdout
701
+ .trim()
702
+ .split('\n')
703
+ .filter(Boolean)
704
+ .map((line) => {
705
+ const firstColon = line.indexOf(':');
706
+ const secondColon = line.indexOf(':', firstColon + 1);
707
+ if (firstColon === -1 || secondColon === -1) {
708
+ return { raw: line };
709
+ }
710
+ return {
711
+ path: line.slice(0, firstColon),
712
+ line: Number(line.slice(firstColon + 1, secondColon)),
713
+ snippet: line.slice(secondColon + 1)
714
+ };
715
+ });
716
+ return {
717
+ data: {
718
+ feature_id: featureId,
719
+ query,
720
+ matches
721
+ }
722
+ };
723
+ }
724
+ async repoDiffBundle(featureId) {
725
+ const stat = await runGit(this.repoRoot, ['diff', '--stat'], { cwd: this.worktreePath(featureId) });
726
+ const full = await runGit(this.repoRoot, ['diff'], { cwd: this.worktreePath(featureId) });
727
+ const names = await runGit(this.repoRoot, ['diff', '--name-only'], { cwd: this.worktreePath(featureId) });
728
+ const latest = await this.evidenceLatest(featureId);
729
+ return {
730
+ data: {
731
+ feature_id: featureId,
732
+ diff_stat: stat.stdout,
733
+ diff: full.stdout,
734
+ touched_files: names.stdout.split('\n').map((x) => x.trim()).filter(Boolean),
735
+ last_gate_summary: latest.data?.latest ?? null
736
+ }
737
+ };
738
+ }
739
+ async gatesList(profileName = null) {
740
+ return await this.gateService.gatesList(profileName);
741
+ }
742
+ async gateProfileAndMode(profileName, mode) {
743
+ return await this.gateService.gateProfileAndMode(profileName, mode);
744
+ }
745
+ async gatesRun(featureId, profileName, mode) {
746
+ return await this.gateService.gatesRun(featureId, profileName, mode);
747
+ }
748
+ async evidenceLatest(featureId) {
749
+ return await this.gateService.evidenceLatest(featureId);
750
+ }
751
+ async qaTestIndexGet(featureId) {
752
+ return await this.qaIndexService.qaTestIndexGet(featureId);
753
+ }
754
+ async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
755
+ return await this.qaIndexService.qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs);
756
+ }
757
+ async locksAcquire(resource, featureId, waitTimeoutSeconds = null) {
758
+ return await this.lockService.locksAcquire(resource, featureId, waitTimeoutSeconds);
759
+ }
760
+ async locksRelease(resource, featureId) {
761
+ return await this.lockService.locksRelease(resource, featureId);
762
+ }
763
+ async collisionsScan() {
764
+ return await this.reportingService.collisionsScan();
765
+ }
766
+ async reportDashboard() {
767
+ return await this.reportingService.reportDashboard();
768
+ }
769
+ async reportFeatureSummary(featureId) {
770
+ return await this.reportingService.reportFeatureSummary(featureId);
771
+ }
772
+ async featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken) {
773
+ return await this.mergeService.featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken);
774
+ }
775
+ async featureDelete(featureId, dryRun, confirm, removeWorktree, removeBranch) {
776
+ return await this.featureDeletionService.featureDelete(featureId, {
777
+ dryRun: dryRun ?? undefined,
778
+ confirm: confirm ?? undefined,
779
+ removeWorktree: removeWorktree ?? undefined,
780
+ removeBranch: removeBranch ?? undefined
781
+ });
782
+ }
783
+ async renewLeases(featureIds) {
784
+ return await this.lockService.renewLeases(featureIds);
785
+ }
786
+ async recoverFromState() {
787
+ return await this.lockService.recoverFromState();
788
+ }
789
+ }
790
+ function normalizeRepoPathForState(repoRoot, absolutePath) {
791
+ const relative = path.relative(repoRoot, absolutePath).replaceAll('\\\\', '/');
792
+ if (!relative || relative === '.') {
793
+ return '.';
794
+ }
795
+ return relative;
796
+ }
797
+ function normalizeFromWorktree(worktreePath, repoRoot, repoRelativeFromWorktree) {
798
+ const absolute = path.resolve(repoRoot, repoRelativeFromWorktree);
799
+ const maybeRelativeToWorktree = path.relative(worktreePath, absolute).replaceAll('\\\\', '/');
800
+ if (!maybeRelativeToWorktree.startsWith('../')) {
801
+ return maybeRelativeToWorktree;
802
+ }
803
+ return path.relative(repoRoot, absolute).replaceAll('\\\\', '/');
804
+ }
805
+ //# sourceMappingURL=kernel.js.map