@kbediako/codex-orchestrator 0.1.38 → 0.2.1

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 (311) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +46 -317
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +797 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +50 -0
  7. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  8. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  9. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  10. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +295 -11
  11. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  12. package/dist/orchestrator/src/cli/coStatusCliShell.js +451 -0
  13. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  14. package/dist/orchestrator/src/cli/codexCliShell.js +119 -0
  15. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +265 -36
  16. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  17. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  18. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  19. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  22. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  23. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  24. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  25. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  26. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  27. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  28. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  29. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  30. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  31. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  32. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  33. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  34. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  35. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  36. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  37. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  39. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  40. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  41. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  42. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  43. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +630 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  47. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  48. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  49. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  53. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  54. package/dist/orchestrator/src/cli/control/controlRuntime.js +1003 -0
  55. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  56. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  57. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  59. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  60. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  62. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  64. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  67. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  69. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  71. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  72. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  73. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1904 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  84. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  85. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  86. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  87. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  88. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  89. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  90. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  91. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  92. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  93. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  94. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  95. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  96. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  97. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  98. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  99. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  100. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  101. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  102. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  105. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  111. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  112. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  115. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  116. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  117. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  119. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  120. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  121. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  122. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  123. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  124. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  125. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1885 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  131. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  132. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  133. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  134. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  135. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  136. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  137. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  138. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  139. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  140. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  141. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  142. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  143. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  144. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  145. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  146. package/dist/orchestrator/src/cli/doctor.js +678 -164
  147. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  148. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  149. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  150. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  151. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  152. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  153. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  154. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  156. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  157. package/dist/orchestrator/src/cli/init.js +95 -1
  158. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  159. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  160. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  161. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  162. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  163. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  164. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  165. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1835 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  169. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  170. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +6834 -0
  171. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  172. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  173. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  174. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  175. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  176. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  177. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  178. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  179. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  180. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  181. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  182. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  183. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  184. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  185. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  186. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  187. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  188. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  189. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  190. package/dist/orchestrator/src/cli/services/commandRunner.js +698 -18
  191. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  192. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  220. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  221. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  222. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  223. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  224. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  225. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  226. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  227. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  228. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  229. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  230. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  231. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  232. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +285 -7
  233. package/dist/orchestrator/src/cli/utils/codexFeatures.js +60 -0
  234. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  235. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  236. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  237. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  238. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  239. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  240. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  241. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  242. package/dist/orchestrator/src/manager.js +74 -4
  243. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  244. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  245. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  246. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  247. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  248. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  249. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  250. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  251. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  252. package/dist/packages/shared/config/designConfig.js +8 -1
  253. package/dist/packages/shared/streams/stdio.js +1 -1
  254. package/dist/scripts/design/pipeline/permit.js +15 -0
  255. package/dist/scripts/lib/docs-catalog.js +399 -0
  256. package/dist/scripts/lib/docs-helpers.js +87 -5
  257. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  258. package/dist/scripts/lib/provider-run-contract.js +26 -0
  259. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  260. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  261. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  262. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  263. package/dist/scripts/lib/review-execution-state.js +1144 -0
  264. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  265. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  266. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  267. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  268. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  269. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  270. package/dist/scripts/lib/review-prompt-context.js +376 -0
  271. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  272. package/dist/scripts/lib/review-scope-paths.js +123 -0
  273. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  274. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  275. package/dist/scripts/lib/run-manifests.js +192 -36
  276. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  277. package/dist/scripts/run-review.js +507 -1777
  278. package/docs/README.md +43 -20
  279. package/docs/book/README.md +19 -0
  280. package/docs/book/codex-cli-0124-adoption.md +68 -0
  281. package/docs/book/local-hook-impact.md +73 -0
  282. package/docs/book/operations.md +60 -0
  283. package/docs/book/public-posture.md +34 -0
  284. package/docs/book/setup.md +91 -0
  285. package/docs/book/skills.md +11 -0
  286. package/docs/guides/codex-version-policy.md +104 -0
  287. package/docs/public/downstream-setup.md +113 -0
  288. package/docs/public/provider-onboarding.md +173 -0
  289. package/package.json +23 -10
  290. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  291. package/plugins/codex-orchestrator/.mcp.json +13 -0
  292. package/plugins/codex-orchestrator/launcher.mjs +361 -0
  293. package/schemas/manifest.json +411 -0
  294. package/skills/README.md +26 -0
  295. package/skills/collab-subagents-first/SKILL.md +1 -1
  296. package/skills/delegation-usage/DELEGATION_GUIDE.md +30 -12
  297. package/skills/delegation-usage/SKILL.md +25 -14
  298. package/skills/land/SKILL.md +77 -0
  299. package/skills/linear/SKILL.md +255 -0
  300. package/skills/release/SKILL.md +47 -3
  301. package/skills/standalone-review/SKILL.md +6 -1
  302. package/templates/README.md +4 -2
  303. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  304. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  305. package/templates/codex/.codex/config.toml +3 -4
  306. package/templates/codex/.codex/providers/README.md +13 -0
  307. package/templates/codex/.codex/providers/control.example.json +18 -0
  308. package/templates/codex/.codex/providers/provider.env.example +15 -0
  309. package/templates/codex/AGENTS.md +15 -8
  310. package/templates/codex/mcp-client.json +5 -1
  311. package/docs/assets/setup.gif +0 -0
@@ -5,6 +5,7 @@ import { EnvUtils } from '../../../../packages/shared/config/env.js';
5
5
  import { resolveCodexCliBin } from './codexCli.js';
6
6
  import { resolveCodexHome } from './codexPaths.js';
7
7
  import { buildCommandPreview } from './commandPreview.js';
8
+ import { hasMcpServerEntry } from './mcpServerEntry.js';
8
9
  export const DEVTOOLS_SKILL_NAME = 'chrome-devtools';
9
10
  export const DEVTOOLS_CONFIG_OVERRIDE = 'mcp_servers.chrome-devtools.enabled=true';
10
11
  const CONFIG_OVERRIDE_ENV_KEYS = ['CODEX_MCP_CONFIG_OVERRIDES', 'CODEX_CONFIG_OVERRIDES'];
@@ -132,7 +133,7 @@ function inspectDevtoolsConfig(env = process.env) {
132
133
  error: error instanceof Error ? error.message : String(error)
133
134
  };
134
135
  }
135
- const hasEntry = hasDevtoolsConfigEntry(raw);
136
+ const hasEntry = hasMcpServerEntry(raw, DEVTOOLS_SKILL_NAME);
136
137
  if (hasEntry) {
137
138
  return { status: 'ok', path: configPath };
138
139
  }
@@ -142,52 +143,6 @@ function inspectDevtoolsConfig(env = process.env) {
142
143
  detail: 'chrome-devtools entry not found'
143
144
  };
144
145
  }
145
- function hasDevtoolsConfigEntry(raw) {
146
- const lines = raw.split('\n');
147
- let currentTable = null;
148
- for (const line of lines) {
149
- const trimmed = stripTomlComment(line).trim();
150
- if (!trimmed) {
151
- continue;
152
- }
153
- const tableMatch = trimmed.match(/^\[(.+)\]$/);
154
- if (tableMatch) {
155
- currentTable = tableMatch[1]?.trim() ?? null;
156
- if (currentTable === 'mcp_servers.chrome-devtools' ||
157
- currentTable === 'mcp_servers."chrome-devtools"' ||
158
- currentTable === "mcp_servers.'chrome-devtools'") {
159
- return true;
160
- }
161
- continue;
162
- }
163
- if (trimmed.startsWith('mcp_servers.')) {
164
- if (trimmed.startsWith('mcp_servers."chrome-devtools".')) {
165
- return true;
166
- }
167
- if (trimmed.startsWith("mcp_servers.'chrome-devtools'.")) {
168
- return true;
169
- }
170
- if (trimmed.startsWith('mcp_servers.chrome-devtools.')) {
171
- return true;
172
- }
173
- if (trimmed.startsWith('mcp_servers."chrome-devtools"=')) {
174
- return true;
175
- }
176
- if (trimmed.startsWith("mcp_servers.'chrome-devtools'=")) {
177
- return true;
178
- }
179
- if (trimmed.startsWith('mcp_servers.chrome-devtools=')) {
180
- return true;
181
- }
182
- }
183
- if (currentTable === 'mcp_servers') {
184
- if (/^"?chrome-devtools"?\s*=/.test(trimmed)) {
185
- return true;
186
- }
187
- }
188
- }
189
- return false;
190
- }
191
146
  function parseConfigOverrides(env) {
192
147
  const overrides = [];
193
148
  for (const key of CONFIG_OVERRIDE_ENV_KEYS) {
@@ -216,10 +171,3 @@ function applyConfigOverrides(overrides, args) {
216
171
  function dedupeOverrides(overrides) {
217
172
  return Array.from(new Set(overrides.filter((override) => override.trim().length > 0)));
218
173
  }
219
- function stripTomlComment(line) {
220
- const index = line.indexOf('#');
221
- if (index === -1) {
222
- return line;
223
- }
224
- return line.slice(0, index);
225
- }
@@ -0,0 +1,53 @@
1
+ export function hasMcpServerEntry(raw, serverName) {
2
+ const lines = raw.split('\n');
3
+ let currentTable = null;
4
+ const escapedServerName = escapeRegExp(serverName);
5
+ for (const line of lines) {
6
+ const trimmed = stripTomlComment(line).trim();
7
+ if (!trimmed) {
8
+ continue;
9
+ }
10
+ const tableMatch = trimmed.match(/^\[(.+)\]$/u);
11
+ if (tableMatch) {
12
+ currentTable = tableMatch[1]?.trim() ?? null;
13
+ if (currentTable === `mcp_servers.${serverName}` ||
14
+ currentTable === `mcp_servers."${serverName}"` ||
15
+ currentTable === `mcp_servers.'${serverName}'`) {
16
+ return true;
17
+ }
18
+ continue;
19
+ }
20
+ if (trimmed.startsWith('mcp_servers.')) {
21
+ if (trimmed.startsWith(`mcp_servers."${serverName}".`)) {
22
+ return true;
23
+ }
24
+ if (trimmed.startsWith(`mcp_servers.'${serverName}'.`)) {
25
+ return true;
26
+ }
27
+ if (trimmed.startsWith(`mcp_servers.${serverName}.`)) {
28
+ return true;
29
+ }
30
+ const dottedEntryPattern = new RegExp(`^mcp_servers\\.(?:"${escapedServerName}"|'${escapedServerName}'|${escapedServerName})\\s*=`, 'u');
31
+ if (dottedEntryPattern.test(trimmed)) {
32
+ return true;
33
+ }
34
+ }
35
+ if (currentTable === 'mcp_servers') {
36
+ const entryPattern = new RegExp(`^(?:"${escapedServerName}"|'${escapedServerName}'|${escapedServerName})\\s*=`, 'u');
37
+ if (entryPattern.test(trimmed)) {
38
+ return true;
39
+ }
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ function stripTomlComment(line) {
45
+ const index = line.indexOf('#');
46
+ if (index === -1) {
47
+ return line;
48
+ }
49
+ return line.slice(0, index);
50
+ }
51
+ function escapeRegExp(value) {
52
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
53
+ }
@@ -0,0 +1,151 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { extname, join, normalize } from 'node:path';
4
+ import process from 'node:process';
5
+ import { findPackageRoot } from './packageInfo.js';
6
+ const DEFAULT_SOURCE_EXTENSIONS = ['.ts', '.mts', '.js', '.mjs', '.tsx'];
7
+ const BOOTSTRAP_SOURCE_EXTENSIONS = ['.js', '.ts', '.mjs', '.mts', '.tsx'];
8
+ const ALLOWED_RESOLVED_ENV_OVERRIDE_KEYS = ['TS_NODE_PROJECT'];
9
+ export function resolvePackageProgramInvocation(options) {
10
+ const fileExists = options.fileExists ?? existsSync;
11
+ const packageRoot = resolvePackageRoot(options);
12
+ const distRelativePath = stripLeadingSeparators(options.distRelativePath);
13
+ const distPath = join(packageRoot, 'dist', distRelativePath);
14
+ const sourcePath = resolveSourcePath({
15
+ packageRoot,
16
+ distRelativePath,
17
+ fileExists,
18
+ sourcePreference: options.sourcePreference ?? 'default'
19
+ });
20
+ const execPath = options.execPath ?? process.execPath;
21
+ if (sourcePath) {
22
+ const sourceExtension = extname(sourcePath).toLowerCase();
23
+ if (!requiresTsNodeLoader(sourceExtension)) {
24
+ return {
25
+ command: execPath,
26
+ args: [sourcePath],
27
+ packageRoot,
28
+ distPath,
29
+ sourcePath,
30
+ mode: 'source',
31
+ warning: null
32
+ };
33
+ }
34
+ const loaderPath = resolveTsNodeLoaderPath(packageRoot, options.resolveModulePath);
35
+ if (loaderPath) {
36
+ return {
37
+ command: execPath,
38
+ args: ['--no-warnings', '--loader', loaderPath, sourcePath],
39
+ packageRoot,
40
+ distPath,
41
+ sourcePath,
42
+ mode: 'source',
43
+ warning: null,
44
+ envOverrides: filterResolvedProgramInvocationEnvOverrides({
45
+ TS_NODE_PROJECT: join(packageRoot, 'tsconfig.json')
46
+ })
47
+ };
48
+ }
49
+ }
50
+ if (fileExists(distPath)) {
51
+ return {
52
+ command: execPath,
53
+ args: [distPath],
54
+ packageRoot,
55
+ distPath,
56
+ sourcePath,
57
+ mode: 'dist',
58
+ warning: sourcePath ? buildSourceFallbackWarning(sourcePath, distPath) : null
59
+ };
60
+ }
61
+ if (sourcePath) {
62
+ throw new Error(`Unable to run ${sourcePath} because ts-node/esm is unavailable, and fallback dist artifact ${distPath} is missing.`);
63
+ }
64
+ throw new Error(`Unable to locate packaged program. Expected ${distPath}.`);
65
+ }
66
+ export function resolveCodexOrchestratorBootstrapInvocation(options = {}) {
67
+ return resolvePackageProgramInvocation({
68
+ ...options,
69
+ distRelativePath: 'bin/codex-orchestrator.js',
70
+ sourcePreference: 'bootstrap'
71
+ });
72
+ }
73
+ export function resolveProviderLinearWorkerProgramInvocation(options = {}) {
74
+ return resolvePackageProgramInvocation({
75
+ ...options,
76
+ distRelativePath: 'orchestrator/src/cli/providerLinearWorkerRunner.js'
77
+ });
78
+ }
79
+ export function filterResolvedProgramInvocationEnvOverrides(envOverrides) {
80
+ if (!envOverrides) {
81
+ return undefined;
82
+ }
83
+ const filtered = {};
84
+ for (const key of ALLOWED_RESOLVED_ENV_OVERRIDE_KEYS) {
85
+ const value = envOverrides[key];
86
+ if (typeof value === 'string' && value.trim().length > 0) {
87
+ filtered[key] = value;
88
+ }
89
+ }
90
+ return Object.keys(filtered).length > 0 ? filtered : undefined;
91
+ }
92
+ export function applyResolvedProgramInvocationEnvOverrides(targetEnv, envOverrides) {
93
+ const filtered = filterResolvedProgramInvocationEnvOverrides(envOverrides);
94
+ if (filtered) {
95
+ Object.assign(targetEnv, filtered);
96
+ }
97
+ }
98
+ function resolvePackageRoot(options) {
99
+ const defaultPackageRoot = normalize(options.packageRoot ?? findPackageRoot(import.meta.url));
100
+ const configured = normalizeOptionalString(options.env?.CODEX_ORCHESTRATOR_PACKAGE_ROOT);
101
+ if (configured &&
102
+ (options.allowConfiguredForeignPackageRoot === true || pathsEqual(configured, defaultPackageRoot))) {
103
+ return normalize(configured);
104
+ }
105
+ return defaultPackageRoot;
106
+ }
107
+ function resolveSourcePath(input) {
108
+ const relativeWithoutExtension = input.distRelativePath.replace(/\.js$/u, '');
109
+ const extensions = input.sourcePreference === 'bootstrap' ? BOOTSTRAP_SOURCE_EXTENSIONS : DEFAULT_SOURCE_EXTENSIONS;
110
+ for (const extension of extensions) {
111
+ const candidate = join(input.packageRoot, `${relativeWithoutExtension}${extension}`);
112
+ if (input.fileExists(candidate)) {
113
+ return candidate;
114
+ }
115
+ }
116
+ return null;
117
+ }
118
+ function resolveTsNodeLoaderPath(packageRoot, resolveModulePath) {
119
+ try {
120
+ const resolver = resolveModulePath ??
121
+ ((specifier, fromPath) => createRequire(fromPath).resolve(specifier));
122
+ return resolver('ts-node/esm', join(packageRoot, 'package.json'));
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ function requiresTsNodeLoader(extension) {
129
+ return extension === '.ts' || extension === '.mts' || extension === '.tsx';
130
+ }
131
+ function buildSourceFallbackWarning(sourcePath, distPath) {
132
+ return [
133
+ 'Source checkout fallback: ts-node/esm is unavailable, so execution is using the built dist artifact instead of the live source entrypoint.',
134
+ `source=${sourcePath}`,
135
+ `dist=${distPath}`,
136
+ 'Fresh merged TypeScript changes may remain stale until dist is rebuilt.'
137
+ ].join(' ');
138
+ }
139
+ function normalizeOptionalString(value) {
140
+ if (typeof value !== 'string') {
141
+ return null;
142
+ }
143
+ const trimmed = value.trim();
144
+ return trimmed.length > 0 ? trimmed : null;
145
+ }
146
+ function pathsEqual(leftPath, rightPath) {
147
+ return normalize(leftPath) === normalize(rightPath);
148
+ }
149
+ function stripLeadingSeparators(value) {
150
+ return value.replace(/^[/\\]+/u, '');
151
+ }
@@ -0,0 +1,71 @@
1
+ import { join } from 'node:path';
2
+ import { readProviderControlHostLocatorFromEnv } from '../../../../scripts/lib/provider-run-contract.js';
3
+ import { REPO_CONFIG_REQUIRED_ENV_KEY } from '../config/repoConfigPolicy.js';
4
+ import { REPO_CONFIG_PATH_ENV_KEY } from '../config/userConfig.js';
5
+ const PROVIDER_REPO_CONFIG_PATH_ENV_KEY = 'CODEX_ORCHESTRATOR_PROVIDER_REPO_CONFIG_PATH';
6
+ const PROVIDER_PACKAGE_ROOT_ENV_KEY = 'CODEX_ORCHESTRATOR_PROVIDER_PACKAGE_ROOT';
7
+ const PROVIDER_OVERRIDE_ENV_KEYS = [
8
+ REPO_CONFIG_PATH_ENV_KEY,
9
+ 'CODEX_ORCHESTRATOR_PACKAGE_ROOT'
10
+ ];
11
+ const PROVIDER_OVERRIDE_MARKER_ENV_KEYS = [
12
+ PROVIDER_REPO_CONFIG_PATH_ENV_KEY,
13
+ PROVIDER_PACKAGE_ROOT_ENV_KEY
14
+ ];
15
+ const PROVIDER_WORKSPACE_ARTIFACT_ENV_KEYS = [
16
+ 'CODEX_ORCHESTRATOR_ROOT',
17
+ 'CODEX_ORCHESTRATOR_RUNS_DIR',
18
+ 'CODEX_ORCHESTRATOR_OUT_DIR'
19
+ ];
20
+ export { PROVIDER_OVERRIDE_ENV_KEYS, PROVIDER_OVERRIDE_MARKER_ENV_KEYS, PROVIDER_PACKAGE_ROOT_ENV_KEY, PROVIDER_REPO_CONFIG_PATH_ENV_KEY };
21
+ export function sanitizeProviderOverrideEnv(env = process.env, options = {}) {
22
+ const sanitized = { ...env };
23
+ if (options.stripWorkspaceArtifactEnv) {
24
+ for (const key of PROVIDER_WORKSPACE_ARTIFACT_ENV_KEYS) {
25
+ delete sanitized[key];
26
+ }
27
+ }
28
+ const controlHostLocator = readProviderControlHostLocatorFromEnv(sanitized);
29
+ if (!controlHostLocator) {
30
+ return sanitized;
31
+ }
32
+ const currentRepoConfigPath = normalizeEnvString(sanitized[REPO_CONFIG_PATH_ENV_KEY]);
33
+ const currentPackageRoot = normalizeEnvString(sanitized.CODEX_ORCHESTRATOR_PACKAGE_ROOT);
34
+ const providerPackageRootMarker = normalizeEnvString(sanitized[PROVIDER_PACKAGE_ROOT_ENV_KEY]);
35
+ const providerRepoConfigPath = normalizeEnvString(sanitized[PROVIDER_REPO_CONFIG_PATH_ENV_KEY]) ??
36
+ deriveProviderRepoConfigPath(providerPackageRootMarker ?? currentPackageRoot, controlHostLocator.taskId, controlHostLocator.runId);
37
+ const providerPackageRoot = providerPackageRootMarker ??
38
+ (currentRepoConfigPath && providerRepoConfigPath && currentRepoConfigPath === providerRepoConfigPath
39
+ ? currentPackageRoot
40
+ : null);
41
+ const shouldStripRepoConfig = currentRepoConfigPath !== null &&
42
+ providerRepoConfigPath !== null &&
43
+ currentRepoConfigPath === providerRepoConfigPath;
44
+ const shouldStripPackageRoot = currentPackageRoot !== null &&
45
+ providerPackageRoot !== null &&
46
+ currentPackageRoot === providerPackageRoot;
47
+ if (shouldStripRepoConfig) {
48
+ delete sanitized[REPO_CONFIG_PATH_ENV_KEY];
49
+ delete sanitized[REPO_CONFIG_REQUIRED_ENV_KEY];
50
+ }
51
+ if (shouldStripPackageRoot) {
52
+ delete sanitized.CODEX_ORCHESTRATOR_PACKAGE_ROOT;
53
+ }
54
+ for (const key of PROVIDER_OVERRIDE_MARKER_ENV_KEYS) {
55
+ delete sanitized[key];
56
+ }
57
+ return sanitized;
58
+ }
59
+ function deriveProviderRepoConfigPath(packageRoot, controlHostTaskId, controlHostRunId) {
60
+ if (!packageRoot) {
61
+ return null;
62
+ }
63
+ return join(packageRoot, '.runs', controlHostTaskId, 'cli', controlHostRunId, 'provider-workflow.last-known-good.json');
64
+ }
65
+ function normalizeEnvString(value) {
66
+ if (typeof value !== 'string') {
67
+ return null;
68
+ }
69
+ const trimmed = value.trim();
70
+ return trimmed.length > 0 ? trimmed : null;
71
+ }
@@ -0,0 +1,59 @@
1
+ export function parseTrailingJsonObject(raw, options = {}) {
2
+ const trimmed = raw.trim();
3
+ if (!trimmed) {
4
+ return null;
5
+ }
6
+ const direct = safeJsonObjectParse(trimmed);
7
+ if (direct) {
8
+ return direct;
9
+ }
10
+ if (options.allowTrailingTextAfterJson) {
11
+ return parseJsonObjectBeforeTrailingText(trimmed);
12
+ }
13
+ return parseStrictTrailingJsonObject(trimmed);
14
+ }
15
+ function parseStrictTrailingJsonObject(trimmed) {
16
+ if (!trimmed.endsWith('}')) {
17
+ return null;
18
+ }
19
+ const lines = trimmed.split(/\r?\n/u);
20
+ for (let start = 0; start < lines.length; start += 1) {
21
+ if (!lines[start]?.trimStart().startsWith('{')) {
22
+ continue;
23
+ }
24
+ const parsed = safeJsonObjectParse(lines.slice(start).join('\n'));
25
+ if (parsed) {
26
+ return parsed;
27
+ }
28
+ }
29
+ return null;
30
+ }
31
+ function parseJsonObjectBeforeTrailingText(trimmed) {
32
+ const lines = trimmed.split(/\r?\n/u);
33
+ for (let start = lines.length - 1; start >= 0; start -= 1) {
34
+ if (!lines[start]?.trimStart().startsWith('{')) {
35
+ continue;
36
+ }
37
+ for (let end = lines.length - 1; end >= start; end -= 1) {
38
+ if (!lines[end]?.includes('}')) {
39
+ continue;
40
+ }
41
+ const parsed = safeJsonObjectParse(lines.slice(start, end + 1).join('\n'));
42
+ if (parsed) {
43
+ return parsed;
44
+ }
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ function safeJsonObjectParse(value) {
50
+ try {
51
+ const parsed = JSON.parse(value);
52
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
53
+ ? parsed
54
+ : null;
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
@@ -7,7 +7,7 @@ import { isoTimestamp } from '../cli/utils/time.js';
7
7
  import { resolveCodexCliBin } from '../cli/utils/codexCli.js';
8
8
  import { slugify } from '../cli/utils/strings.js';
9
9
  import { appendLearningAlert, ensureLearningSection } from './manifest.js';
10
- import { computePromptPackStamp, loadPromptPacks } from '../../../packages/orchestrator/src/instructions/promptPacks.js';
10
+ import { loadPromptPacks } from '../../../packages/orchestrator/src/instructions/promptPacks.js';
11
11
  const DEFAULT_PROMPT_PACK = 'crystalizer-v1';
12
12
  const DEFAULT_OUTPUT_DIR = '.agent/patterns/candidates';
13
13
  const DEFAULT_MODEL = process.env.CRYSTALIZER_MODEL || 'gpt-5.1-codex-max';
@@ -23,7 +23,7 @@ export async function runCrystalizer(options) {
23
23
  if (!pack) {
24
24
  throw new Error(`Prompt pack ${promptPackId} not found`);
25
25
  }
26
- const packStamp = computePromptPackStamp(pack.sources);
26
+ const packStamp = pack.stamp;
27
27
  const promptSources = pack.sources.map((source) => source.content).join('\n\n');
28
28
  const prompt = composePrompt(promptSources, packStamp, problemStatement, validatedPatch, scenarioSummary ?? '');
29
29
  const response = await client.generate(prompt, { model });
@@ -160,7 +160,7 @@ export class TaskManager {
160
160
  const build = await this.executeBuilder(task, plan, target, mode, runId);
161
161
  if (!build.success) {
162
162
  const skippedTest = this.createSkippedTestResult(build, runId);
163
- const skippedReview = this.createSkippedReviewResult('build-failed');
163
+ const skippedReview = this.createSkippedReviewResult('build-failed', build);
164
164
  const summary = this.createRunSummary(task, mode, plan, build, skippedTest, skippedReview, runId);
165
165
  return { target, mode, build, test: skippedTest, review: skippedReview, summary };
166
166
  }
@@ -239,13 +239,27 @@ export class TaskManager {
239
239
  runId
240
240
  };
241
241
  }
242
- createSkippedReviewResult(reason) {
242
+ createSkippedReviewResult(reason, build) {
243
243
  if (reason === 'build-failed') {
244
+ const prerequisiteStage = this.extractFailedPrerequisiteStage(build);
245
+ if (prerequisiteStage) {
246
+ const artifactPath = this.findFailedStageArtifactPath(build);
247
+ const artifactFeedback = artifactPath ? ` Error artifact: ${artifactPath}.` : '';
248
+ return {
249
+ summary: `Review skipped: prerequisite stage \`${prerequisiteStage}\` failed.`,
250
+ decision: {
251
+ approved: false,
252
+ feedback: `Prerequisite stage \`${prerequisiteStage}\` failed; review skipped.${artifactFeedback}`
253
+ }
254
+ };
255
+ }
256
+ const artifactPath = this.findFailedStageArtifactPath(build);
257
+ const artifactFeedback = artifactPath ? ` Error artifact: ${artifactPath}.` : '';
244
258
  return {
245
259
  summary: 'Review skipped: build stage failed.',
246
260
  decision: {
247
261
  approved: false,
248
- feedback: 'Build stage failed; review skipped.'
262
+ feedback: `Build stage failed; review skipped.${artifactFeedback}`
249
263
  }
250
264
  };
251
265
  }
@@ -257,6 +271,62 @@ export class TaskManager {
257
271
  }
258
272
  };
259
273
  }
274
+ extractFailedPrerequisiteStage(build) {
275
+ const stage = build?.failureStage?.trim();
276
+ const canonicalStage = stage?.toLowerCase();
277
+ if (!stage || (canonicalStage != null && ['build', 'test', 'review'].includes(canonicalStage))) {
278
+ return null;
279
+ }
280
+ return stage;
281
+ }
282
+ findFailedStageArtifactPath(build) {
283
+ if (build?.failureArtifactPath) {
284
+ return build.failureArtifactPath;
285
+ }
286
+ const failureStage = build?.failureStage?.trim().toLowerCase();
287
+ if (!failureStage) {
288
+ return null;
289
+ }
290
+ if (['build', 'test', 'review'].includes(failureStage)) {
291
+ return null;
292
+ }
293
+ const stagePathToken = failureStage.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
294
+ const stageArtifact = build?.artifacts.find((candidate) => {
295
+ const normalizedPath = candidate.path.replace(/\\/g, '/').toLowerCase();
296
+ const isErrorArtifact = normalizedPath.startsWith('errors/') ||
297
+ normalizedPath.includes('/errors/') ||
298
+ /\berror\b/i.test(candidate.description);
299
+ if (!isErrorArtifact) {
300
+ return false;
301
+ }
302
+ return this.artifactMatchesFailedStage(candidate, failureStage, stagePathToken);
303
+ });
304
+ return stageArtifact?.path ?? null;
305
+ }
306
+ artifactMatchesFailedStage(candidate, failureStage, stagePathToken) {
307
+ const normalizedDescription = candidate.description.toLowerCase();
308
+ const parentheticalStages = [...normalizedDescription.matchAll(/\(([^)]+)\)/g)]
309
+ .map((match) => match[1]?.trim() ?? '')
310
+ .filter(Boolean);
311
+ if (parentheticalStages.some((stage) => this.stageTokenMatches(stage, failureStage, stagePathToken))) {
312
+ return true;
313
+ }
314
+ const normalizedPath = candidate.path.replace(/\\/g, '/').toLowerCase();
315
+ return normalizedPath
316
+ .split('/')
317
+ .map((segment) => segment.replace(/\.[^.]+$/, '').replace(/^\d+-/, ''))
318
+ .some((segment) => this.stageTokenMatches(segment, failureStage, stagePathToken));
319
+ }
320
+ stageTokenMatches(candidate, failureStage, stagePathToken) {
321
+ if (candidate === failureStage) {
322
+ return true;
323
+ }
324
+ if (!stagePathToken) {
325
+ return false;
326
+ }
327
+ const candidatePathToken = candidate.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
328
+ return candidatePathToken === stagePathToken;
329
+ }
260
330
  async executePlanner(task, runId) {
261
331
  try {
262
332
  const plan = await this.options.planner.plan(task);
@@ -335,7 +405,7 @@ export class TaskManager {
335
405
  const cause = error ?? new Error('Planner stage failed without an error payload');
336
406
  const build = this.createBuilderErrorResult('planner-unavailable', mode, runId, cause);
337
407
  const skippedTest = this.createSkippedTestResult(build, runId);
338
- const skippedReview = this.createSkippedReviewResult('build-failed');
408
+ const skippedReview = this.createSkippedReviewResult('build-failed', build);
339
409
  const summary = this.createRunSummary(task, mode, plan, build, skippedTest, skippedReview, runId);
340
410
  this.eventBus.emit({ type: 'run:completed', payload: summary });
341
411
  return summary;