@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
@@ -0,0 +1,86 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { logger } from '../../logger.js';
6
+ import { isoTimestamp } from '../utils/time.js';
7
+ const UI_ASSET_PATHS = {
8
+ '/ui': 'index.html',
9
+ '/ui/': 'index.html',
10
+ '/ui/app.js': 'app.js',
11
+ '/ui/styles.css': 'styles.css',
12
+ '/ui/favicon.svg': 'favicon.svg'
13
+ };
14
+ const UI_ROOT = resolveUiRoot();
15
+ export async function handlePublicControlRoute(context) {
16
+ if (context.pathname === '/health') {
17
+ context.res.writeHead(200, { 'Content-Type': 'application/json' });
18
+ context.res.end(JSON.stringify({ status: 'ok', timestamp: isoTimestamp() }));
19
+ return true;
20
+ }
21
+ if (context.pathname === '/' || context.pathname === '') {
22
+ context.res.writeHead(302, { Location: `/ui${context.search}` });
23
+ context.res.end();
24
+ return true;
25
+ }
26
+ const uiAsset = resolveUiAssetPath(context.pathname);
27
+ if (!uiAsset) {
28
+ return false;
29
+ }
30
+ await serveUiAsset(uiAsset, context.res);
31
+ return true;
32
+ }
33
+ function resolveUiRoot() {
34
+ const candidates = [
35
+ resolve(process.cwd(), 'packages', 'orchestrator-status-ui'),
36
+ resolve(process.cwd(), '..', 'packages', 'orchestrator-status-ui'),
37
+ resolve(process.cwd(), '..', '..', 'packages', 'orchestrator-status-ui'),
38
+ resolve(fileURLToPath(new URL('../../../../packages/orchestrator-status-ui', import.meta.url)))
39
+ ];
40
+ for (const candidate of candidates) {
41
+ if (existsSync(join(candidate, 'index.html'))) {
42
+ return candidate;
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+ function resolveUiAssetPath(pathname) {
48
+ if (!UI_ROOT) {
49
+ return null;
50
+ }
51
+ const asset = UI_ASSET_PATHS[pathname];
52
+ if (!asset) {
53
+ return null;
54
+ }
55
+ return resolve(UI_ROOT, asset);
56
+ }
57
+ async function serveUiAsset(assetPath, res) {
58
+ try {
59
+ const payload = await readFile(assetPath);
60
+ res.writeHead(200, {
61
+ 'Content-Type': resolveUiContentType(assetPath),
62
+ 'Cache-Control': 'no-store'
63
+ });
64
+ res.end(payload);
65
+ }
66
+ catch (error) {
67
+ logger.warn(`Failed to serve UI asset ${assetPath}: ${error?.message ?? error}`);
68
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
69
+ res.end('Not found');
70
+ }
71
+ }
72
+ function resolveUiContentType(assetPath) {
73
+ if (assetPath.endsWith('.html')) {
74
+ return 'text/html; charset=utf-8';
75
+ }
76
+ if (assetPath.endsWith('.css')) {
77
+ return 'text/css; charset=utf-8';
78
+ }
79
+ if (assetPath.endsWith('.js')) {
80
+ return 'application/javascript; charset=utf-8';
81
+ }
82
+ if (assetPath.endsWith('.svg')) {
83
+ return 'image/svg+xml';
84
+ }
85
+ return 'application/octet-stream';
86
+ }
@@ -0,0 +1,25 @@
1
+ import { assertControlServerBootstrapAssemblyPublished, closeControlServerOwnedRuntime, createControlServerOwnedRuntime } from './controlServerOwnedRuntimeLifecycle.js';
2
+ import { startControlServerReadyInstanceStartup } from './controlServerReadyInstanceStartup.js';
3
+ export async function startControlServerReadyInstanceLifecycle(options) {
4
+ const ownedRuntime = createControlServerOwnedRuntime(options.requestContextShared);
5
+ const baseUrl = await startControlServerReadyInstanceStartup({
6
+ server: ownedRuntime.server,
7
+ requestContextShared: ownedRuntime.requestContextShared,
8
+ intervalMs: options.intervalMs,
9
+ host: options.host,
10
+ controlToken: options.controlToken,
11
+ onBootstrapAssembly: ownedRuntime.publishBootstrapAssembly,
12
+ closeOnFailure: () => closeControlServerOwnedRuntime({
13
+ server: ownedRuntime.server,
14
+ requestContextShared: ownedRuntime.requestContextShared,
15
+ lifecycleState: ownedRuntime.lifecycleState
16
+ })
17
+ });
18
+ assertControlServerBootstrapAssemblyPublished(ownedRuntime.lifecycleState);
19
+ return {
20
+ server: ownedRuntime.server,
21
+ baseUrl,
22
+ lifecycleState: ownedRuntime.lifecycleState
23
+ };
24
+ }
25
+ export { beginClosingControlServerHttpServer, closeControlServerOwnedRuntime } from './controlServerOwnedRuntimeLifecycle.js';
@@ -0,0 +1,18 @@
1
+ import { createControlBootstrapAssembly } from './controlBootstrapAssembly.js';
2
+ import { emitDispatchPilotAuditEvents } from './controlServerAuditAndErrorHelpers.js';
3
+ import { startControlServerStartupSequence } from './controlServerStartupSequence.js';
4
+ export async function startControlServerReadyInstanceStartup(options) {
5
+ const bootstrapAssembly = createControlBootstrapAssembly({
6
+ intervalMs: options.intervalMs,
7
+ requestContextShared: options.requestContextShared,
8
+ emitDispatchPilotAuditEvents
9
+ });
10
+ options.onBootstrapAssembly(bootstrapAssembly);
11
+ return startControlServerStartupSequence({
12
+ server: options.server,
13
+ host: options.host,
14
+ bootstrapLifecycle: bootstrapAssembly.bootstrapLifecycle,
15
+ controlToken: options.controlToken,
16
+ closeOnFailure: options.closeOnFailure
17
+ });
18
+ }
@@ -0,0 +1,37 @@
1
+ const MAX_BODY_BYTES = 1024 * 1024;
2
+ class HttpError extends Error {
3
+ status;
4
+ constructor(status, message) {
5
+ super(message);
6
+ this.status = status;
7
+ }
8
+ }
9
+ export async function readRawBody(req) {
10
+ const chunks = [];
11
+ let totalBytes = 0;
12
+ for await (const chunk of req) {
13
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
14
+ totalBytes += buf.length;
15
+ if (totalBytes > MAX_BODY_BYTES) {
16
+ throw new HttpError(413, 'request_body_too_large');
17
+ }
18
+ chunks.push(buf);
19
+ }
20
+ return Buffer.concat(chunks);
21
+ }
22
+ export async function readJsonBody(req) {
23
+ const rawBuffer = await readRawBody(req);
24
+ if (rawBuffer.length === 0) {
25
+ return {};
26
+ }
27
+ const raw = rawBuffer.toString('utf8');
28
+ if (!raw.trim()) {
29
+ return {};
30
+ }
31
+ try {
32
+ return JSON.parse(raw);
33
+ }
34
+ catch {
35
+ throw new HttpError(400, 'invalid_json');
36
+ }
37
+ }
@@ -0,0 +1,40 @@
1
+ import http from 'node:http';
2
+ import { buildControlRequestContext } from './controlRequestContext.js';
3
+ export function createControlServerRequestShell(options) {
4
+ return http.createServer((req, res) => {
5
+ const runtime = options.readRuntime();
6
+ if (!runtime) {
7
+ writeControlServerUnavailable(res);
8
+ return;
9
+ }
10
+ options
11
+ .handleRequest(buildLiveControlRequestContext(runtime, req, res))
12
+ .catch((error) => writeTopLevelControlRequestError(res, error));
13
+ });
14
+ }
15
+ function buildLiveControlRequestContext(runtime, req, res) {
16
+ return buildControlRequestContext({
17
+ ...runtime.requestContextShared,
18
+ req,
19
+ res,
20
+ expiryLifecycle: runtime.expiryLifecycle
21
+ });
22
+ }
23
+ function writeControlServerUnavailable(res) {
24
+ res.writeHead(503, { 'Content-Type': 'application/json' });
25
+ res.end(JSON.stringify({ error: 'control_server_unavailable' }));
26
+ }
27
+ function writeTopLevelControlRequestError(res, error) {
28
+ const status = readErrorStatus(error);
29
+ res.writeHead(status, { 'Content-Type': 'application/json' });
30
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
31
+ }
32
+ function readErrorStatus(error) {
33
+ if (error &&
34
+ typeof error === 'object' &&
35
+ 'status' in error &&
36
+ typeof error.status === 'number') {
37
+ return error.status;
38
+ }
39
+ return 500;
40
+ }
@@ -0,0 +1,17 @@
1
+ import { handleControlRequest } from './controlRequestController.js';
2
+ import { createControlServerRequestShell } from './controlServerRequestShell.js';
3
+ export function createBoundControlServerRequestShell(options) {
4
+ return createControlServerRequestShell({
5
+ readRuntime: () => {
6
+ const requestContextShared = options.readRequestContextShared();
7
+ if (!requestContextShared) {
8
+ return null;
9
+ }
10
+ return {
11
+ requestContextShared,
12
+ expiryLifecycle: options.readExpiryLifecycle()
13
+ };
14
+ },
15
+ handleRequest: handleControlRequest
16
+ });
17
+ }
@@ -0,0 +1,27 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { logger } from '../../logger.js';
4
+ import { LINEAR_ADVISORY_STATE_FILE, PROVIDER_INTAKE_STATE_FILE } from './controlPersistenceFiles.js';
5
+ export async function readControlServerSeeds(paths) {
6
+ return {
7
+ controlSeed: await readJsonFile(paths.controlPath),
8
+ confirmationsSeed: await readJsonFile(paths.confirmationsPath),
9
+ questionsSeed: await readJsonFile(paths.questionsPath),
10
+ delegationSeed: await readJsonFile(paths.delegationTokensPath),
11
+ linearAdvisorySeed: await readJsonFile(join(paths.runDir, LINEAR_ADVISORY_STATE_FILE)),
12
+ providerIntakeSeed: await readJsonFile(join(paths.runDir, PROVIDER_INTAKE_STATE_FILE))
13
+ };
14
+ }
15
+ async function readJsonFile(path) {
16
+ try {
17
+ const raw = await readFile(path, 'utf8');
18
+ return JSON.parse(raw);
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT') {
22
+ return null;
23
+ }
24
+ logger.warn(`Failed to read JSON file ${path}: ${error?.message ?? error}`);
25
+ return null;
26
+ }
27
+ }
@@ -0,0 +1,186 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { writeJsonAtomic } from '../utils/fs.js';
5
+ import { isoTimestamp } from '../utils/time.js';
6
+ import { ControlStateStore } from './controlState.js';
7
+ import { ConfirmationStore } from './confirmations.js';
8
+ import { QuestionQueue } from './questions.js';
9
+ import { DelegationTokenStore } from './delegationTokens.js';
10
+ import { createControlRuntime } from './controlRuntime.js';
11
+ import { createControlEventTransport } from './controlEventTransport.js';
12
+ import { markLinearAdvisoryStateStaleFromProviderIntake, normalizeLinearAdvisoryState } from './linearWebhookController.js';
13
+ import { isRecordLike, normalizeProviderIntakeState } from './providerIntakeState.js';
14
+ import { LINEAR_ADVISORY_STATE_FILE, PROVIDER_INTAKE_STATE_FILE } from './controlPersistenceFiles.js';
15
+ class SessionTokenStore {
16
+ ttlMs;
17
+ tokens = new Map();
18
+ constructor(ttlMs) {
19
+ this.ttlMs = ttlMs;
20
+ }
21
+ issue() {
22
+ this.prune();
23
+ const token = randomBytes(24).toString('hex');
24
+ const expiresAt = Date.now() + this.ttlMs;
25
+ this.tokens.set(token, expiresAt);
26
+ return { token, expiresAt: new Date(expiresAt).toISOString() };
27
+ }
28
+ validate(token) {
29
+ this.prune();
30
+ const expiresAt = this.tokens.get(token);
31
+ if (!expiresAt) {
32
+ return false;
33
+ }
34
+ if (expiresAt <= Date.now()) {
35
+ this.tokens.delete(token);
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+ prune() {
41
+ const now = Date.now();
42
+ for (const [token, expiresAt] of this.tokens.entries()) {
43
+ if (expiresAt <= now) {
44
+ this.tokens.delete(token);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ export function createControlServerSeededRuntimeAssembly(options) {
50
+ const controlStore = new ControlStateStore({
51
+ runId: options.runId,
52
+ controlSeq: options.controlSeed?.control_seq ?? 0,
53
+ latestAction: options.controlSeed?.latest_action ?? null,
54
+ featureToggles: options.controlSeed?.feature_toggles ?? null,
55
+ transportMutation: options.controlSeed?.transport_mutation ?? null
56
+ });
57
+ const defaultToggles = options.controlSeed?.feature_toggles ?? {};
58
+ if (!('rlm' in defaultToggles)) {
59
+ controlStore.updateFeatureToggles({ rlm: { policy: options.config.rlm.policy } });
60
+ }
61
+ const confirmationStore = new ConfirmationStore({
62
+ runId: options.runId,
63
+ expiresInMs: options.config.confirm.expiresInMs,
64
+ maxPending: options.config.confirm.maxPending,
65
+ seed: {
66
+ pending: options.confirmationsSeed?.pending ?? [],
67
+ issued: options.confirmationsSeed?.issued ?? [],
68
+ consumed_nonce_ids: options.confirmationsSeed?.consumed_nonce_ids ?? []
69
+ }
70
+ });
71
+ const questionQueue = new QuestionQueue({ seed: options.questionsSeed?.questions ?? [] });
72
+ const delegationTokens = new DelegationTokenStore({ seed: options.delegationSeed?.tokens ?? [] });
73
+ const sessionTokens = new SessionTokenStore(options.sessionTtlMs);
74
+ const linearAdvisoryState = normalizeLinearAdvisoryState(options.linearAdvisorySeed);
75
+ const providerIntakeState = normalizeProviderIntakeState(options.providerIntakeSeed);
76
+ let linearAdvisoryStaleWritePending = markLinearAdvisoryStateStaleFromProviderIntake(linearAdvisoryState, providerIntakeState);
77
+ let providerIssueHandoff = null;
78
+ const controlRuntime = createControlRuntime({
79
+ controlStore,
80
+ questionQueue,
81
+ paths: options.paths,
82
+ linearAdvisoryState,
83
+ providerIntakeState,
84
+ providerWorkflowConfigStore: options.providerWorkflowConfigStore,
85
+ readProviderIssueHandoff: () => providerIssueHandoff
86
+ });
87
+ const clients = new Set();
88
+ const eventTransport = createControlEventTransport({
89
+ eventStream: options.eventStream,
90
+ clients,
91
+ runtime: controlRuntime
92
+ });
93
+ const linearAdvisoryStatePath = join(options.paths.runDir, LINEAR_ADVISORY_STATE_FILE);
94
+ const providerIntakeStatePath = join(options.paths.runDir, PROVIDER_INTAKE_STATE_FILE);
95
+ let providerIntakePersistChain = Promise.resolve();
96
+ const queueProviderIntakePersist = async (operation) => {
97
+ const nextOperation = providerIntakePersistChain.then(operation, operation);
98
+ providerIntakePersistChain = nextOperation.then(() => undefined, () => undefined);
99
+ return await nextOperation;
100
+ };
101
+ const readPersistedProviderIntakeState = async () => {
102
+ try {
103
+ return normalizeProviderIntakeState(JSON.parse(await readFile(providerIntakeStatePath, 'utf8')));
104
+ }
105
+ catch (error) {
106
+ if (error?.code === 'ENOENT') {
107
+ return null;
108
+ }
109
+ throw error;
110
+ }
111
+ };
112
+ const persist = {
113
+ control: async () => writeJsonAtomic(options.paths.controlPath, controlStore.snapshot()),
114
+ confirmations: async () => writeJsonAtomic(options.paths.confirmationsPath, confirmationStore.snapshot()),
115
+ questions: async () => writeJsonAtomic(options.paths.questionsPath, { questions: questionQueue.list() }),
116
+ delegationTokens: async () => writeJsonAtomic(options.paths.delegationTokensPath, { tokens: delegationTokens.list() }),
117
+ linearAdvisory: async () => {
118
+ await writeJsonAtomic(linearAdvisoryStatePath, linearAdvisoryState);
119
+ linearAdvisoryStaleWritePending = false;
120
+ },
121
+ providerIntake: async () => await queueProviderIntakePersist(async () => {
122
+ await writeJsonAtomic(providerIntakeStatePath, providerIntakeState);
123
+ const linearAdvisoryMarkedStale = markLinearAdvisoryStateStaleFromProviderIntake(linearAdvisoryState, providerIntakeState);
124
+ if (linearAdvisoryStaleWritePending || linearAdvisoryMarkedStale) {
125
+ await writeJsonAtomic(linearAdvisoryStatePath, linearAdvisoryState);
126
+ linearAdvisoryStaleWritePending = false;
127
+ controlRuntime.publish({ source: 'linear-advisory.stale-source' });
128
+ }
129
+ }),
130
+ providerIntakePolling: async (polling, updatedAt) => await queueProviderIntakePersist(async () => {
131
+ const nextState = (await readPersistedProviderIntakeState()) ?? normalizeProviderIntakeState(null);
132
+ const nextPolling = isRecordLike(polling) ? { ...polling } : null;
133
+ nextState.polling = nextPolling;
134
+ const nextPollingUpdatedAt = typeof nextPolling?.updated_at === 'string' && nextPolling.updated_at.trim().length > 0
135
+ ? nextPolling.updated_at
136
+ : isoTimestamp();
137
+ const nextStateUpdatedAt = typeof updatedAt === 'string' && updatedAt.trim().length > 0 ? updatedAt : nextPollingUpdatedAt;
138
+ nextState.updated_at = pickLatestTimestamp(nextState.updated_at, nextStateUpdatedAt);
139
+ await writeJsonAtomic(providerIntakeStatePath, nextState);
140
+ const linearAdvisoryMarkedStale = markLinearAdvisoryStateStaleFromProviderIntake(linearAdvisoryState, nextState);
141
+ if (linearAdvisoryStaleWritePending || linearAdvisoryMarkedStale) {
142
+ await writeJsonAtomic(linearAdvisoryStatePath, linearAdvisoryState);
143
+ linearAdvisoryStaleWritePending = false;
144
+ controlRuntime.publish({ source: 'linear-advisory.stale-source' });
145
+ }
146
+ })
147
+ };
148
+ providerIssueHandoff =
149
+ options.createProviderIssueHandoff?.({
150
+ providerIntakeState,
151
+ persistProviderIntake: persist.providerIntake,
152
+ publishRuntime: (source) => controlRuntime.publish({ source }),
153
+ readFeatureToggles: () => controlStore.snapshot().feature_toggles
154
+ }) ?? null;
155
+ const requestContextShared = {
156
+ token: options.token,
157
+ controlStore,
158
+ confirmationStore,
159
+ questionQueue,
160
+ delegationTokens,
161
+ sessionTokens,
162
+ config: options.config,
163
+ persist,
164
+ clients,
165
+ eventTransport,
166
+ paths: options.paths,
167
+ linearAdvisoryState,
168
+ providerIntakeState,
169
+ providerIssueHandoff,
170
+ runtime: controlRuntime
171
+ };
172
+ return {
173
+ requestContextShared
174
+ };
175
+ }
176
+ function pickLatestTimestamp(currentIso, candidateIso) {
177
+ const currentMs = Date.parse(currentIso ?? '');
178
+ const candidateMs = Date.parse(candidateIso);
179
+ if (!Number.isFinite(currentMs)) {
180
+ return candidateIso;
181
+ }
182
+ if (!Number.isFinite(candidateMs)) {
183
+ return currentIso ?? candidateIso;
184
+ }
185
+ return candidateMs >= currentMs ? candidateIso : currentIso ?? candidateIso;
186
+ }
@@ -0,0 +1,31 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { readControlServerSeeds } from './controlServerSeedLoading.js';
3
+ import { createControlServerSeededRuntimeAssembly } from './controlServerSeededRuntimeAssembly.js';
4
+ export async function prepareControlServerStartupInputs(options) {
5
+ const controlToken = randomBytes(24).toString('hex');
6
+ const { controlSeed, confirmationsSeed, questionsSeed, delegationSeed, linearAdvisorySeed, providerIntakeSeed } = await readControlServerSeeds(options.paths);
7
+ const { requestContextShared } = createControlServerSeededRuntimeAssembly({
8
+ runId: options.runId,
9
+ token: controlToken,
10
+ config: options.config,
11
+ paths: options.paths,
12
+ eventStream: options.eventStream,
13
+ sessionTtlMs: options.sessionTtlMs,
14
+ controlSeed,
15
+ confirmationsSeed,
16
+ questionsSeed,
17
+ delegationSeed,
18
+ linearAdvisorySeed,
19
+ providerIntakeSeed,
20
+ providerWorkflowConfigStore: options.providerWorkflowConfigStore,
21
+ createProviderIssueHandoff: options.createProviderIssueHandoff
22
+ });
23
+ if (requestContextShared.linearAdvisoryState.stale_source) {
24
+ await requestContextShared.persist.linearAdvisory();
25
+ }
26
+ return {
27
+ requestContextShared,
28
+ host: options.config.ui.bindHost,
29
+ controlToken
30
+ };
31
+ }
@@ -0,0 +1,49 @@
1
+ import { logger } from '../../logger.js';
2
+ export async function startControlServerStartupSequence(options) {
3
+ await bindControlServer(options.server, options.host);
4
+ const baseUrl = resolveControlServerBaseUrl(options.server, options.host);
5
+ options.server.on('error', (error) => {
6
+ logger.error(`Control server error: ${error?.message ?? String(error)}`);
7
+ });
8
+ try {
9
+ await options.bootstrapLifecycle.start({
10
+ baseUrl,
11
+ controlToken: options.controlToken
12
+ });
13
+ }
14
+ catch (error) {
15
+ await options.closeOnFailure();
16
+ throw error;
17
+ }
18
+ return baseUrl;
19
+ }
20
+ async function bindControlServer(server, host) {
21
+ await new Promise((resolve, reject) => {
22
+ const onError = (error) => {
23
+ server.off('error', onError);
24
+ try {
25
+ server.close(() => undefined);
26
+ }
27
+ catch {
28
+ // Ignore close errors on a server that failed to bind.
29
+ }
30
+ reject(error);
31
+ };
32
+ server.once('error', onError);
33
+ server.listen(0, host, () => {
34
+ server.off('error', onError);
35
+ resolve();
36
+ });
37
+ });
38
+ }
39
+ function resolveControlServerBaseUrl(server, host) {
40
+ const address = server.address();
41
+ const port = typeof address === 'string' || !address ? 0 : address.port;
42
+ return `http://${formatHostForUrl(host)}:${port}`;
43
+ }
44
+ export function formatHostForUrl(host) {
45
+ if (host.includes(':') && !host.startsWith('[')) {
46
+ return `[${host}]`;
47
+ }
48
+ return host;
49
+ }