@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,451 @@
1
+ /* eslint-disable patterns/prefer-logger-over-console */
2
+ import { join, resolve, sep } from 'node:path';
3
+ import { readUiDatasetWithEndpointRecovery, resolveAttachTarget, runCoStatusAttachCliShell } from './coStatusAttachCliShell.js';
4
+ import { readControlServerSeeds } from './control/controlServerSeedLoading.js';
5
+ import { ControlStateStore } from './control/controlState.js';
6
+ import { createControlRuntime } from './control/controlRuntime.js';
7
+ import { normalizeLinearAdvisoryState } from './control/linearWebhookController.js';
8
+ import { readUiDataset } from './control/operatorDashboardPresenter.js';
9
+ import { evaluateProviderControlHostFreshnessGauge } from './control/providerControlHostFreshnessGauge.js';
10
+ import { normalizeProviderIntakeState } from './control/providerIntakeState.js';
11
+ const CO_STATUS_ATTACH_UNSUPPORTED_FLAGS = ['pipeline'];
12
+ const LOCAL_DEGRADED_FALLBACK_ALLOWED_VERDICTS = new Set([
13
+ 'healthy',
14
+ 'degraded'
15
+ ]);
16
+ const LOCAL_DEGRADED_FALLBACK_ALLOWED_FINDING_CODES = new Set(['active_worker_proof_missing']);
17
+ const CURRENT_HOST_UNHEALTHY_MARKER = 'current-host-unhealthy';
18
+ const CURRENT_HOST_UNHEALTHY_STALE_ENDPOINT_FALLBACK = 'control-host unavailable; stale endpoint after control-host restart';
19
+ const LEGACY_CURRENT_HOST_UNHEALTHY_STALE_ENDPOINT_FALLBACK = 'control-host unavailable; control_endpoint.json has not rotated to a reachable host';
20
+ const CURRENT_HOST_UNHEALTHY_ROTATED_ENDPOINT_FALLBACK = 'refreshed control-host endpoint is still unreachable';
21
+ export async function runCoStatusCliShell(params) {
22
+ if (params.flags.help !== undefined) {
23
+ params.printHelp();
24
+ return;
25
+ }
26
+ assertAttachCompatibleFlags(params.flags);
27
+ const format = readStringFlag(params.flags, 'format') === 'json' ? 'json' : 'text';
28
+ if (format !== 'json') {
29
+ await runCoStatusAttachCliShell(params);
30
+ return;
31
+ }
32
+ const dataset = await readCoStatusJsonDataset({ flags: params.flags });
33
+ console.log(JSON.stringify(dataset, null, 2));
34
+ }
35
+ export async function readCoStatusJsonDataset(input) {
36
+ let target = await resolveAttachTarget(input.flags);
37
+ try {
38
+ return await readUiDatasetWithEndpointRecovery({
39
+ flags: input.flags,
40
+ getTarget: () => target,
41
+ setTarget: (nextTarget) => {
42
+ target = nextTarget;
43
+ },
44
+ requestTimeoutMs: input.requestTimeoutMs,
45
+ recoverSameEndpointTimeout: true
46
+ });
47
+ }
48
+ catch (error) {
49
+ const degradedDataset = await tryReadLocalDegradedUiDataset({
50
+ error,
51
+ target
52
+ });
53
+ if (degradedDataset) {
54
+ return degradedDataset;
55
+ }
56
+ throw error;
57
+ }
58
+ }
59
+ function readStringFlag(flags, key) {
60
+ const value = flags[key];
61
+ if (typeof value !== 'string') {
62
+ return undefined;
63
+ }
64
+ const trimmed = value.trim();
65
+ return trimmed.length > 0 ? trimmed : undefined;
66
+ }
67
+ function assertAttachCompatibleFlags(flags) {
68
+ const unsupported = CO_STATUS_ATTACH_UNSUPPORTED_FLAGS.filter((flag) => flags[flag] !== undefined);
69
+ if (unsupported.length === 0) {
70
+ return;
71
+ }
72
+ const renderedFlags = unsupported.map((flag) => `--${flag}`).join(', ');
73
+ throw new Error(`co-status attaches to an existing control host and does not accept launch-only flags: ${renderedFlags}. Use \`control-host\` to start a control host with launch settings.`);
74
+ }
75
+ async function tryReadLocalDegradedUiDataset(input) {
76
+ const degradedReason = resolveLocalDegradedReadReason(input.error);
77
+ if (!degradedReason) {
78
+ return null;
79
+ }
80
+ const freshnessReport = await evaluateProviderControlHostFreshnessGauge({
81
+ artifactRoot: input.target.runDir
82
+ });
83
+ const refreshAgeVerdict = freshnessReport.metrics.last_successful_refresh_age_ms.verdict;
84
+ if (!isEligibleLocalDegradedFallbackFreshnessReport(freshnessReport) ||
85
+ !LOCAL_DEGRADED_FALLBACK_ALLOWED_VERDICTS.has(refreshAgeVerdict)) {
86
+ return null;
87
+ }
88
+ const localDataset = await readLocalUiDataset(input.target);
89
+ const dataset = applyProviderIntakeTruthOverlay(localDataset.dataset, input.target, localDataset.providerIntakeState);
90
+ const providerIntake = dataset.provider_intake ?? null;
91
+ if (!providerIntake || providerIntake.active_claim_count < 1) {
92
+ return null;
93
+ }
94
+ return {
95
+ ...dataset,
96
+ degraded_read: buildDegradedReadPayload(input.target, freshnessReport, degradedReason)
97
+ };
98
+ }
99
+ function resolveLocalDegradedReadReason(error) {
100
+ const message = error?.message ?? String(error);
101
+ if (message.includes('Re-resolving control_endpoint.json failed')) {
102
+ return null;
103
+ }
104
+ if (isCurrentHostUnhealthyErrorMessage(message)) {
105
+ return 'current_host_unhealthy';
106
+ }
107
+ if (message.includes('control-host ui request timeout after')) {
108
+ return 'ui_request_timeout';
109
+ }
110
+ return null;
111
+ }
112
+ function isCurrentHostUnhealthyErrorMessage(message) {
113
+ return [
114
+ CURRENT_HOST_UNHEALTHY_MARKER,
115
+ CURRENT_HOST_UNHEALTHY_STALE_ENDPOINT_FALLBACK,
116
+ LEGACY_CURRENT_HOST_UNHEALTHY_STALE_ENDPOINT_FALLBACK,
117
+ CURRENT_HOST_UNHEALTHY_ROTATED_ENDPOINT_FALLBACK
118
+ ].some((fragment) => message.includes(fragment));
119
+ }
120
+ function isEligibleLocalDegradedFallbackFreshnessReport(report) {
121
+ if (LOCAL_DEGRADED_FALLBACK_ALLOWED_VERDICTS.has(report.verdict)) {
122
+ return true;
123
+ }
124
+ if (report.verdict !== 'unknown') {
125
+ return false;
126
+ }
127
+ return (report.findings.length > 0 &&
128
+ report.findings.every((finding) => LOCAL_DEGRADED_FALLBACK_ALLOWED_FINDING_CODES.has(finding.code)));
129
+ }
130
+ function buildDegradedReadPayload(target, report, reason) {
131
+ return {
132
+ reason,
133
+ source: 'local_seeded_runtime',
134
+ freshness_verdict: report.verdict,
135
+ artifact_root: target.runDir,
136
+ finding_codes: report.findings.map((finding) => finding.code)
137
+ };
138
+ }
139
+ function applyProviderIntakeTruthOverlay(dataset, target, providerIntakeState) {
140
+ const providerIntake = dataset.provider_intake ?? null;
141
+ const selectedClaim = selectDegradedOverlayClaim(providerIntakeState, providerIntake?.selected_claim.issue_identifier);
142
+ if (!selectedClaim) {
143
+ return dataset;
144
+ }
145
+ const activeClaims = [...providerIntakeState.claims]
146
+ .sort(compareDegradedClaims)
147
+ .filter(isDegradedActiveClaim);
148
+ const runningClaims = activeClaims.filter((claim) => resolveDegradedClaimState(claim) === 'running');
149
+ const status = resolveDegradedClaimStatus(resolveDegradedClaimState(selectedClaim));
150
+ const selected = buildDegradedSelectedPayload(dataset.selected, selectedClaim, target, status);
151
+ const runningEntries = runningClaims.map((claim) => buildDegradedRunningSessionPayload(claim, selected, dataset.host));
152
+ const synthesizedIssues = activeClaims.length > 0 ? activeClaims : [selectedClaim];
153
+ const issues = [
154
+ ...synthesizedIssues.map((claim) => buildDegradedIssuePayload(dataset.issues.find((entry) => entry.issue_identifier === claim.issue_identifier) ?? null, claim, selected, dataset.host, resolveDegradedClaimStatus(resolveDegradedClaimState(claim)))),
155
+ ...dataset.issues.filter((entry) => entry.issue_identifier !== selected.issue_identifier &&
156
+ !synthesizedIssues.some((claim) => claim.issue_identifier === entry.issue_identifier) &&
157
+ !isDegradedPlaceholderIssue(entry, target))
158
+ ].map((entry) => ({
159
+ ...entry,
160
+ is_selected: entry.issue_identifier === selected.issue_identifier
161
+ }));
162
+ return {
163
+ ...dataset,
164
+ counts: {
165
+ ...dataset.counts,
166
+ running: runningEntries.length > 0 ? runningEntries.length : dataset.counts.running,
167
+ issues: issues.length
168
+ },
169
+ selected_issue_identifier: selected.issue_identifier,
170
+ selected,
171
+ running: runningEntries.length > 0 ? runningEntries : dataset.running,
172
+ issues
173
+ };
174
+ }
175
+ function selectDegradedOverlayClaim(state, selectedIssueIdentifier) {
176
+ const activeClaims = [...state.claims].sort(compareDegradedClaims).filter(isDegradedActiveClaim);
177
+ const preferred = typeof selectedIssueIdentifier === 'string'
178
+ ? activeClaims.find((claim) => claim.issue_identifier === selectedIssueIdentifier) ??
179
+ state.claims.find((claim) => claim.issue_identifier === selectedIssueIdentifier) ??
180
+ null
181
+ : null;
182
+ return preferred ?? activeClaims[0] ?? state.claims[0] ?? null;
183
+ }
184
+ function isDegradedActiveClaim(claim) {
185
+ switch (claim.state) {
186
+ case 'accepted':
187
+ case 'starting':
188
+ case 'running':
189
+ case 'resuming':
190
+ case 'resumable':
191
+ case 'handoff_failed':
192
+ return true;
193
+ default:
194
+ return false;
195
+ }
196
+ }
197
+ function compareDegradedClaims(left, right) {
198
+ return rankDegradedClaimState(right.state) - rankDegradedClaimState(left.state)
199
+ || Date.parse(right.updated_at) - Date.parse(left.updated_at);
200
+ }
201
+ function rankDegradedClaimState(state) {
202
+ switch (state) {
203
+ case 'running':
204
+ return 9;
205
+ case 'resuming':
206
+ return 8;
207
+ case 'starting':
208
+ return 7;
209
+ case 'resumable':
210
+ return 6;
211
+ case 'accepted':
212
+ return 5;
213
+ case 'released':
214
+ return 4;
215
+ case 'handoff_failed':
216
+ return 3;
217
+ case 'completed':
218
+ return 2;
219
+ case 'duplicate':
220
+ return 1;
221
+ case 'stale':
222
+ return 0;
223
+ case 'ignored':
224
+ default:
225
+ return -1;
226
+ }
227
+ }
228
+ function isDegradedPlaceholderIssue(issue, target) {
229
+ return (issue.task_id === (target.taskId ?? issue.task_id) &&
230
+ issue.run_id === (target.runId ?? issue.run_id) &&
231
+ (issue.issue_identifier === (target.taskId ?? null) ||
232
+ issue.issue_identifier === (target.runId ?? null)));
233
+ }
234
+ function buildDegradedSelectedPayload(existing, claim, target, status) {
235
+ const latestEvent = buildDegradedLatestEvent(claim);
236
+ return {
237
+ issue_id: claim.issue_id,
238
+ issue_identifier: claim.issue_identifier,
239
+ task_id: claim.task_id,
240
+ run_id: claim.run_id,
241
+ raw_status: status.raw_status,
242
+ display_status: status.display_status,
243
+ status_reason: claim.reason,
244
+ started_at: existing?.started_at ?? null,
245
+ updated_at: claim.updated_at,
246
+ completed_at: null,
247
+ summary: claim.issue_title,
248
+ last_error: existing?.last_error ?? null,
249
+ latest_action: existing?.latest_action ?? null,
250
+ latest_event: latestEvent,
251
+ workspace: {
252
+ path: existing?.workspace.path ?? resolve(target.runDir, '..', '..', '..')
253
+ },
254
+ ...(claim.worker_host !== undefined ? { worker_host: claim.worker_host ?? null } : {}),
255
+ question_summary: existing?.question_summary ?? {
256
+ queued_count: 0,
257
+ latest_question: null
258
+ },
259
+ tracked: existing?.tracked ?? { linear: null }
260
+ };
261
+ }
262
+ function buildDegradedIssuePayload(existing, claim, selected, host, status) {
263
+ const running = resolveDegradedClaimState(claim) === 'running' ? buildDegradedRunningPayload(claim) : null;
264
+ return {
265
+ issue_identifier: claim.issue_identifier,
266
+ issue_id: claim.issue_id,
267
+ task_id: claim.task_id,
268
+ run_id: claim.run_id,
269
+ status: status.issue_status,
270
+ raw_status: status.raw_status,
271
+ display_status: status.display_status,
272
+ status_reason: claim.reason,
273
+ title: claim.issue_title,
274
+ url: existing?.url ?? null,
275
+ workspace: {
276
+ path: selected.workspace.path,
277
+ host
278
+ },
279
+ ...(claim.worker_host !== undefined ? { worker_host: claim.worker_host ?? null } : {}),
280
+ session: {
281
+ session_id: existing?.session.session_id ?? null,
282
+ thread_id: existing?.session.thread_id ?? null,
283
+ turn_count: existing?.session.turn_count ?? null
284
+ },
285
+ owner: existing?.owner ?? {
286
+ phase: null,
287
+ status: null
288
+ },
289
+ tokens: existing?.tokens ?? null,
290
+ rate_limits: existing?.rate_limits ?? null,
291
+ summary: claim.issue_title,
292
+ last_error: existing?.last_error ?? null,
293
+ latest_event: buildDegradedLatestEvent(claim),
294
+ recent_agent_activity: existing?.recent_agent_activity ?? [],
295
+ linear_activity: existing?.linear_activity ?? [],
296
+ running,
297
+ retry: existing?.retry ?? null,
298
+ attempts: existing?.attempts ?? {
299
+ restart_count: null,
300
+ current_retry_attempt: claim.retry_attempt ?? null
301
+ },
302
+ tracked: existing?.tracked ?? selected.tracked,
303
+ provider_linear_worker_proof: existing?.provider_linear_worker_proof ?? null,
304
+ provider_debug_snapshot: existing?.provider_debug_snapshot ?? null,
305
+ is_selected: true
306
+ };
307
+ }
308
+ function buildDegradedRunningPayload(claim) {
309
+ return {
310
+ issue_id: claim.issue_id,
311
+ issue_identifier: claim.issue_identifier,
312
+ state: 'running',
313
+ display_state: 'running',
314
+ status_reason: claim.reason,
315
+ pid: null,
316
+ ...(claim.worker_host !== undefined ? { worker_host: claim.worker_host ?? null } : {}),
317
+ session_id: null,
318
+ turn_count: null,
319
+ last_event: 'provider_intake_refresh',
320
+ last_message: claim.reason,
321
+ display_event: 'provider_intake_refresh',
322
+ event_source: 'provider_intake_state',
323
+ message_recorded_at: claim.updated_at,
324
+ source_updated_at: claim.updated_at,
325
+ started_at: null,
326
+ last_event_at: claim.updated_at,
327
+ tokens: {
328
+ input_tokens: null,
329
+ output_tokens: null,
330
+ total_tokens: null
331
+ }
332
+ };
333
+ }
334
+ function buildDegradedRunningSessionPayload(claim, selected, host) {
335
+ return {
336
+ issue_identifier: claim.issue_identifier,
337
+ issue_id: claim.issue_id,
338
+ id: claim.issue_identifier,
339
+ bucket: 'running',
340
+ state: 'running',
341
+ reason: claim.reason,
342
+ aliases: [claim.task_id, claim.run_id].filter((value) => Boolean(value)),
343
+ task_id: claim.task_id,
344
+ run_id: claim.run_id,
345
+ summary: claim.issue_title,
346
+ display_state: 'running',
347
+ status_reason: claim.reason,
348
+ pid: null,
349
+ session_id: null,
350
+ thread_id: null,
351
+ turn_count: null,
352
+ workspace_path: selected.workspace.path,
353
+ host,
354
+ ...(claim.worker_host !== undefined ? { worker_host: claim.worker_host ?? null } : {}),
355
+ last_event: 'provider_intake_refresh',
356
+ last_message: claim.reason,
357
+ display_event: 'provider_intake_refresh',
358
+ started_at: null,
359
+ last_event_at: claim.updated_at,
360
+ tokens: {
361
+ input_tokens: null,
362
+ output_tokens: null,
363
+ total_tokens: null
364
+ }
365
+ };
366
+ }
367
+ function buildDegradedLatestEvent(claim) {
368
+ return {
369
+ event: 'provider_intake_refresh',
370
+ message: claim.reason,
371
+ at: claim.updated_at
372
+ };
373
+ }
374
+ function resolveDegradedClaimStatus(state) {
375
+ if (state === 'running') {
376
+ return {
377
+ raw_status: 'in_progress',
378
+ display_status: 'running',
379
+ issue_status: 'running'
380
+ };
381
+ }
382
+ return {
383
+ raw_status: state,
384
+ display_status: state,
385
+ issue_status: state
386
+ };
387
+ }
388
+ function resolveDegradedClaimState(claim) {
389
+ return claim.state === 'handoff_failed' && claim.reason === 'provider_issue_handoff_owned'
390
+ ? 'handoff_owned'
391
+ : claim.state;
392
+ }
393
+ async function readLocalUiDataset(target) {
394
+ const paths = buildRunPathsFromTarget(target);
395
+ const { controlSeed, linearAdvisorySeed, providerIntakeSeed } = await readControlServerSeeds(paths);
396
+ const providerIntakeState = normalizeProviderIntakeState(providerIntakeSeed);
397
+ const controlStore = new ControlStateStore({
398
+ runId: target.runId ?? 'control-host',
399
+ controlSeq: controlSeed?.control_seq ?? 0,
400
+ latestAction: controlSeed?.latest_action ?? null,
401
+ featureToggles: controlSeed?.feature_toggles ?? null,
402
+ transportMutation: controlSeed?.transport_mutation ?? null
403
+ });
404
+ const runtime = createControlRuntime({
405
+ controlStore,
406
+ questionQueue: { list: () => [] },
407
+ paths,
408
+ linearAdvisoryState: normalizeLinearAdvisoryState(linearAdvisorySeed),
409
+ providerIntakeState
410
+ });
411
+ return {
412
+ dataset: await readUiDataset({
413
+ readCompatibilityProjection: () => runtime.snapshot().readCompatibilityProjection()
414
+ }),
415
+ providerIntakeState
416
+ };
417
+ }
418
+ function buildRunPathsFromTarget(target) {
419
+ const runDir = resolve(target.runDir);
420
+ const manifestPath = resolve(target.manifestPath);
421
+ return {
422
+ runDir,
423
+ manifestPath,
424
+ heartbeatPath: join(runDir, '.heartbeat'),
425
+ resumeTokenPath: join(runDir, '.resume-token'),
426
+ logPath: join(runDir, 'runner.ndjson'),
427
+ eventsPath: join(runDir, 'events.jsonl'),
428
+ controlPath: join(runDir, 'control.json'),
429
+ controlAuthPath: join(runDir, 'control_auth.json'),
430
+ controlEndpointPath: join(runDir, 'control_endpoint.json'),
431
+ confirmationsPath: join(runDir, 'confirmations.json'),
432
+ questionsPath: join(runDir, 'questions.json'),
433
+ delegationTokensPath: join(runDir, 'delegation_tokens.json'),
434
+ commandsDir: join(runDir, 'commands'),
435
+ errorsDir: join(runDir, 'errors'),
436
+ compatDir: join(findTaskCliDir(runDir), 'mcp', target.runId ?? 'control-host'),
437
+ compatManifestPath: join(findTaskCliDir(runDir), 'mcp', target.runId ?? 'control-host', 'manifest.json'),
438
+ localCompatDir: join(findRunsRoot(runDir), 'local-mcp', target.runId ?? 'control-host')
439
+ };
440
+ }
441
+ function findTaskCliDir(runDir) {
442
+ return resolve(runDir, '..', '..');
443
+ }
444
+ function findRunsRoot(runDir) {
445
+ const parts = resolve(runDir).split(sep);
446
+ const runsIndex = parts.lastIndexOf('.runs');
447
+ if (runsIndex <= 0) {
448
+ return resolve(runDir, '..', '..', '..');
449
+ }
450
+ return parts.slice(0, runsIndex + 1).join(sep) || sep;
451
+ }
@@ -0,0 +1,120 @@
1
+ /* eslint-disable patterns/prefer-logger-over-console */
2
+ import process from 'node:process';
3
+ import { isoTimestamp } from './utils/time.js';
4
+ import { fetchUiDataset, resolveAttachTarget } from './coStatusAttachCliShell.js';
5
+ import { appendProviderOperatorAutopilotLifecycleRecord, resolveProviderOperatorAutopilotLifecyclePath } from './control/providerOperatorAutopilotLifecycle.js';
6
+ export async function runCoStatusOperatorAutopilotCliShell(params) {
7
+ if (params.flags.help !== undefined) {
8
+ params.printHelp();
9
+ return;
10
+ }
11
+ const [surface, actionName, ...unexpected] = params.positionals;
12
+ if (surface !== 'local-rollout' || !isLifecycleCommand(actionName)) {
13
+ throw new Error('co-status operator-autopilot requires: local-rollout <acknowledge|clear|dismiss>.');
14
+ }
15
+ if (unexpected.length > 0) {
16
+ throw new Error(`Unknown co-status operator-autopilot argument(s): ${unexpected.join(' ')}`);
17
+ }
18
+ const actionIdSelector = readStringFlag(params.flags, 'action-id');
19
+ const issueSelector = readStringFlag(params.flags, 'issue');
20
+ if (actionIdSelector && issueSelector) {
21
+ throw new Error('co-status operator-autopilot local-rollout accepts exactly one selector: --issue or --action-id.');
22
+ }
23
+ const selector = actionIdSelector ?? issueSelector;
24
+ if (!selector) {
25
+ throw new Error('co-status operator-autopilot local-rollout accepts exactly one selector: --issue or --action-id.');
26
+ }
27
+ const actor = readStringFlag(params.flags, 'actor') ??
28
+ normalizeOptionalString(process.env.USER) ??
29
+ 'operator';
30
+ const reason = readStringFlag(params.flags, 'reason');
31
+ if (!reason) {
32
+ throw new Error('co-status operator-autopilot local-rollout requires --reason.');
33
+ }
34
+ const format = readStringFlag(params.flags, 'format') === 'json' ? 'json' : 'text';
35
+ const state = mapLifecycleCommand(actionName);
36
+ const target = await resolveAttachTarget(params.flags);
37
+ const dataset = await fetchUiDataset(target.baseUrl, target.token);
38
+ const operatorAutopilot = dataset.provider_workflow?.operator_autopilot ?? null;
39
+ const pendingActions = operatorAutopilot?.last_result?.pending_actions ?? [];
40
+ const pendingAction = selectPendingLocalRolloutAction({
41
+ pendingActions,
42
+ selector,
43
+ selectorKind: actionIdSelector ? 'action-id' : 'issue'
44
+ });
45
+ if (!pendingAction.action_instance_id) {
46
+ throw new Error('Matched pending local rollout action is missing action_instance_id; wait for a fresh operator-autopilot evaluation.');
47
+ }
48
+ const lifecyclePath = readLifecyclePath(operatorAutopilot) ??
49
+ resolveProviderOperatorAutopilotLifecyclePath(target.runDir);
50
+ const record = {
51
+ action_instance_id: pendingAction.action_instance_id,
52
+ kind: 'local_rollout',
53
+ issue_id: pendingAction.issue_id,
54
+ issue_identifier: pendingAction.issue_identifier,
55
+ state,
56
+ actor,
57
+ reason,
58
+ recorded_at: isoTimestamp(),
59
+ source: 'co-status'
60
+ };
61
+ const store = await appendProviderOperatorAutopilotLifecycleRecord(lifecyclePath, record);
62
+ const payload = {
63
+ status: 'recorded',
64
+ lifecycle_path: lifecyclePath,
65
+ state,
66
+ action: actionName,
67
+ record,
68
+ record_count: store.records.length,
69
+ pending_action: pendingAction
70
+ };
71
+ if (format === 'json') {
72
+ console.log(JSON.stringify(payload, null, 2));
73
+ return;
74
+ }
75
+ console.log(`Recorded ${state} lifecycle for ${pendingAction.issue_identifier ?? pendingAction.issue_id} (${pendingAction.action_instance_id}).`);
76
+ console.log(`Lifecycle path: ${lifecyclePath}`);
77
+ }
78
+ function selectPendingLocalRolloutAction(input) {
79
+ const selector = input.selector.trim();
80
+ const normalizedSelector = selector.toLowerCase();
81
+ const matches = input.pendingActions.filter((pendingAction) => {
82
+ if (input.selectorKind === 'action-id') {
83
+ return pendingAction.action_instance_id === selector;
84
+ }
85
+ return (pendingAction.issue_id === selector ||
86
+ pendingAction.issue_identifier?.toLowerCase() === normalizedSelector);
87
+ });
88
+ if (matches.length === 0) {
89
+ throw new Error(`No pending local rollout action matched ${selector}.`);
90
+ }
91
+ if (matches.length > 1) {
92
+ throw new Error(`Multiple pending local rollout actions matched ${selector}; retry with --action-id.`);
93
+ }
94
+ return matches[0];
95
+ }
96
+ function readLifecyclePath(operatorAutopilot) {
97
+ const lifecyclePath = operatorAutopilot?.lifecycle_path;
98
+ return typeof lifecyclePath === 'string' && lifecyclePath.trim().length > 0
99
+ ? lifecyclePath
100
+ : null;
101
+ }
102
+ function isLifecycleCommand(value) {
103
+ return value === 'acknowledge' || value === 'clear' || value === 'dismiss';
104
+ }
105
+ function mapLifecycleCommand(command) {
106
+ if (command === 'acknowledge') {
107
+ return 'acknowledged';
108
+ }
109
+ return command === 'clear' ? 'cleared' : 'dismissed';
110
+ }
111
+ function readStringFlag(flags, key) {
112
+ return normalizeOptionalString(flags[key]);
113
+ }
114
+ function normalizeOptionalString(value) {
115
+ if (typeof value !== 'string') {
116
+ return undefined;
117
+ }
118
+ const trimmed = value.trim();
119
+ return trimmed.length > 0 ? trimmed : undefined;
120
+ }
@@ -0,0 +1,119 @@
1
+ /* eslint-disable patterns/prefer-logger-over-console */
2
+ import { formatCodexCliSetupSummary, runCodexCliSetup } from './codexCliSetup.js';
3
+ import { formatCodexDefaultsSetupSummary, runCodexDefaultsSetup } from './codexDefaultsSetup.js';
4
+ const LEGACY_CHATGPT_AUTH_TRUE_VALUES = new Set(['true', '1', 'yes', 'on', 'enabled']);
5
+ const LEGACY_CHATGPT_AUTH_FALSE_VALUES = new Set(['false', '0', 'no', 'off', 'disabled']);
6
+ const DEFAULT_DEPENDENCIES = {
7
+ runCodexCliSetup,
8
+ runCodexDefaultsSetup,
9
+ formatCodexCliSetupSummary,
10
+ formatCodexDefaultsSetupSummary,
11
+ log: (line) => console.log(line)
12
+ };
13
+ export async function runCodexCliShell(params, overrides = {}) {
14
+ const dependencies = { ...DEFAULT_DEPENDENCIES, ...overrides };
15
+ const positionals = [...params.positionals];
16
+ const subcommand = positionals.shift();
17
+ const wantsHelp = params.flags['help'] === true
18
+ || params.flags['--help'] === true
19
+ || params.flags['h'] === true
20
+ || !subcommand
21
+ || subcommand === 'help'
22
+ || subcommand === '--help'
23
+ || subcommand === '-h';
24
+ if (wantsHelp) {
25
+ params.printHelp();
26
+ return;
27
+ }
28
+ if (subcommand === 'setup') {
29
+ const format = resolveOutputFormat(params.flags);
30
+ const apply = Boolean(params.flags['yes']);
31
+ const force = Boolean(params.flags['force']);
32
+ const result = await dependencies.runCodexCliSetup({
33
+ apply,
34
+ force,
35
+ source: readStringFlag(params.flags, 'source'),
36
+ ref: readStringFlag(params.flags, 'ref'),
37
+ downloadUrl: readStringFlag(params.flags, 'download-url'),
38
+ downloadSha256: readStringFlag(params.flags, 'download-sha256')
39
+ });
40
+ if (format === 'json') {
41
+ dependencies.log(JSON.stringify(result, null, 2));
42
+ return;
43
+ }
44
+ for (const line of dependencies.formatCodexCliSetupSummary(result)) {
45
+ dependencies.log(line);
46
+ }
47
+ return;
48
+ }
49
+ if (subcommand === 'defaults') {
50
+ const format = resolveOutputFormat(params.flags);
51
+ const apply = Boolean(params.flags['yes']);
52
+ const force = Boolean(params.flags['force']);
53
+ const authScope = readAuthScopeFlag(params.flags);
54
+ const result = await dependencies.runCodexDefaultsSetup({
55
+ apply,
56
+ force,
57
+ authScope
58
+ });
59
+ if (format === 'json') {
60
+ dependencies.log(JSON.stringify(result, null, 2));
61
+ return;
62
+ }
63
+ for (const line of dependencies.formatCodexDefaultsSetupSummary(result)) {
64
+ dependencies.log(line);
65
+ }
66
+ return;
67
+ }
68
+ throw new Error(`Unknown codex subcommand: ${subcommand}`);
69
+ }
70
+ function resolveOutputFormat(flags) {
71
+ return flags['format'] === 'json' ? 'json' : 'text';
72
+ }
73
+ function readStringFlag(flags, key) {
74
+ const value = flags[key];
75
+ return typeof value === 'string' ? value : undefined;
76
+ }
77
+ function readAuthScopeFlag(flags) {
78
+ const legacyChatGptAuth = readLegacyChatGptAuthFlag(flags);
79
+ if (!Object.prototype.hasOwnProperty.call(flags, 'auth-scope')) {
80
+ if (legacyChatGptAuth === true) {
81
+ return 'chatgpt';
82
+ }
83
+ if (legacyChatGptAuth === false) {
84
+ return 'portable';
85
+ }
86
+ return undefined;
87
+ }
88
+ const value = readStringFlag(flags, 'auth-scope');
89
+ if (value === undefined) {
90
+ throw new Error('Missing value for codex defaults auth scope: expected portable or chatgpt.');
91
+ }
92
+ if (legacyChatGptAuth === true && value !== 'chatgpt') {
93
+ throw new Error('Conflicting codex defaults auth scope: --chatgpt-auth requires --auth-scope chatgpt.');
94
+ }
95
+ if (legacyChatGptAuth === false && value !== 'portable') {
96
+ throw new Error('Conflicting codex defaults auth scope: --chatgpt-auth=false requires --auth-scope portable.');
97
+ }
98
+ if (value === 'portable' || value === 'chatgpt') {
99
+ return value;
100
+ }
101
+ throw new Error(`Invalid codex defaults auth scope: ${value}`);
102
+ }
103
+ function readLegacyChatGptAuthFlag(flags) {
104
+ if (!Object.prototype.hasOwnProperty.call(flags, 'chatgpt-auth')) {
105
+ return undefined;
106
+ }
107
+ const value = flags['chatgpt-auth'];
108
+ if (typeof value === 'boolean') {
109
+ return value;
110
+ }
111
+ const normalized = value.trim().toLowerCase();
112
+ if (LEGACY_CHATGPT_AUTH_TRUE_VALUES.has(normalized)) {
113
+ return true;
114
+ }
115
+ if (LEGACY_CHATGPT_AUTH_FALSE_VALUES.has(normalized)) {
116
+ return false;
117
+ }
118
+ throw new Error(`Invalid codex defaults ChatGPT auth flag: --chatgpt-auth expected a boolean-like value, got ${value}.`);
119
+ }