@kbediako/codex-orchestrator 0.1.38 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +70 -301
  3. package/bin/codex-orchestrator.js +161 -0
  4. package/codex.orchestrator.json +149 -13
  5. package/dist/bin/codex-orchestrator.js +795 -1154
  6. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
  7. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
  8. package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
  9. package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +183 -11
  10. package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
  11. package/dist/orchestrator/src/cli/coStatusCliShell.js +429 -0
  12. package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
  13. package/dist/orchestrator/src/cli/codexCliShell.js +72 -0
  14. package/dist/orchestrator/src/cli/codexDefaultsSetup.js +49 -11
  15. package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
  16. package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
  17. package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
  18. package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
  19. package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
  20. package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
  21. package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
  22. package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
  23. package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
  24. package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
  25. package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
  26. package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
  27. package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
  28. package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
  29. package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
  30. package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
  31. package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
  32. package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
  33. package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
  34. package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
  35. package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
  36. package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
  37. package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
  38. package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
  39. package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
  40. package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
  41. package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
  42. package/dist/orchestrator/src/cli/control/controlHostSupervision.js +608 -0
  43. package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
  44. package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
  45. package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
  46. package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
  47. package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
  48. package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
  49. package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
  50. package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
  51. package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
  52. package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
  53. package/dist/orchestrator/src/cli/control/controlRuntime.js +992 -0
  54. package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
  55. package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
  56. package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
  57. package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
  58. package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
  59. package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
  60. package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
  61. package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
  62. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
  63. package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
  64. package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
  65. package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
  66. package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
  67. package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
  68. package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
  69. package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
  70. package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
  71. package/dist/orchestrator/src/cli/control/controlState.js +233 -2
  72. package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1899 -0
  73. package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
  74. package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
  75. package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
  76. package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
  77. package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
  78. package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
  79. package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
  80. package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
  81. package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
  82. package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
  83. package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
  84. package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
  85. package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
  86. package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
  87. package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
  88. package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
  89. package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
  90. package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
  91. package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
  92. package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
  93. package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
  94. package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
  95. package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
  96. package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
  97. package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
  98. package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
  99. package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
  100. package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
  101. package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
  102. package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
  103. package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
  104. package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
  105. package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
  106. package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
  107. package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
  108. package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
  109. package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
  110. package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
  111. package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
  112. package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
  113. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
  114. package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
  115. package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
  116. package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
  117. package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
  118. package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
  119. package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
  120. package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
  121. package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
  122. package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
  123. package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
  124. package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1838 -0
  125. package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
  126. package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
  127. package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
  128. package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
  129. package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
  130. package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
  131. package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
  132. package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
  133. package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
  134. package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
  135. package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
  136. package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
  137. package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
  138. package/dist/orchestrator/src/cli/delegationServer.js +567 -678
  139. package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
  140. package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
  141. package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
  142. package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
  143. package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
  144. package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
  145. package/dist/orchestrator/src/cli/doctor.js +542 -122
  146. package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
  147. package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
  148. package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
  149. package/dist/orchestrator/src/cli/exec/experience.js +16 -2
  150. package/dist/orchestrator/src/cli/exec/summary.js +3 -0
  151. package/dist/orchestrator/src/cli/execCliShell.js +51 -0
  152. package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
  153. package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
  154. package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
  155. package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
  156. package/dist/orchestrator/src/cli/init.js +1 -0
  157. package/dist/orchestrator/src/cli/initCliShell.js +50 -0
  158. package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
  159. package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
  160. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
  161. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
  162. package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
  163. package/dist/orchestrator/src/cli/planCliShell.js +19 -0
  164. package/dist/orchestrator/src/cli/prCliShell.js +41 -0
  165. package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
  166. package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1772 -0
  167. package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
  168. package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
  169. package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +5738 -0
  170. package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
  171. package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
  172. package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
  173. package/dist/orchestrator/src/cli/rlm/context.js +94 -7
  174. package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
  175. package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
  176. package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
  177. package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
  178. package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
  179. package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
  180. package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
  181. package/dist/orchestrator/src/cli/run/manifest.js +410 -73
  182. package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
  183. package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
  184. package/dist/orchestrator/src/cli/run/source0.js +690 -0
  185. package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
  186. package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
  187. package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
  188. package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
  189. package/dist/orchestrator/src/cli/services/commandRunner.js +667 -18
  190. package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
  191. package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
  192. package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
  193. package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
  194. package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
  195. package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
  196. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
  197. package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
  198. package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
  199. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
  200. package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
  201. package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
  202. package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
  203. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
  204. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
  205. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
  206. package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
  207. package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
  208. package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
  209. package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
  210. package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
  211. package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
  212. package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
  213. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
  214. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
  215. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
  216. package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
  217. package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
  218. package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
  219. package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
  220. package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
  221. package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
  222. package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
  223. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
  224. package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
  225. package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
  226. package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
  227. package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
  228. package/dist/orchestrator/src/cli/startCliShell.js +68 -0
  229. package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
  230. package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
  231. package/dist/orchestrator/src/cli/utils/cloudPreflight.js +83 -1
  232. package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
  233. package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
  234. package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
  235. package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
  236. package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
  237. package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
  238. package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
  239. package/dist/orchestrator/src/learning/crystalizer.js +2 -2
  240. package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
  241. package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
  242. package/dist/orchestrator/src/persistence/lockFile.js +70 -4
  243. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
  244. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
  245. package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
  246. package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
  247. package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
  248. package/dist/packages/sdk-node/src/orchestrator.js +137 -13
  249. package/dist/packages/shared/config/designConfig.js +8 -1
  250. package/dist/packages/shared/streams/stdio.js +1 -1
  251. package/dist/scripts/design/pipeline/permit.js +15 -0
  252. package/dist/scripts/lib/docs-catalog.js +365 -0
  253. package/dist/scripts/lib/docs-helpers.js +87 -5
  254. package/dist/scripts/lib/pr-watch-merge.js +1088 -80
  255. package/dist/scripts/lib/provider-run-contract.js +26 -0
  256. package/dist/scripts/lib/review-command-intent-classification.js +532 -0
  257. package/dist/scripts/lib/review-command-probe-classification.js +385 -0
  258. package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
  259. package/dist/scripts/lib/review-execution-runtime.js +753 -0
  260. package/dist/scripts/lib/review-execution-state.js +1144 -0
  261. package/dist/scripts/lib/review-execution-telemetry.js +215 -0
  262. package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
  263. package/dist/scripts/lib/review-launch-attempt.js +601 -0
  264. package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
  265. package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
  266. package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
  267. package/dist/scripts/lib/review-prompt-context.js +376 -0
  268. package/dist/scripts/lib/review-scope-advisory.js +286 -0
  269. package/dist/scripts/lib/review-scope-paths.js +123 -0
  270. package/dist/scripts/lib/review-shell-command-parser.js +389 -0
  271. package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
  272. package/dist/scripts/lib/run-manifests.js +192 -36
  273. package/dist/scripts/lib/spark-policy-classifier.js +593 -0
  274. package/dist/scripts/run-review.js +507 -1777
  275. package/docs/public/downstream-setup.md +106 -0
  276. package/docs/public/provider-onboarding.md +173 -0
  277. package/package.json +20 -10
  278. package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
  279. package/plugins/codex-orchestrator/.mcp.json +13 -0
  280. package/plugins/codex-orchestrator/launcher.mjs +359 -0
  281. package/schemas/manifest.json +394 -0
  282. package/skills/collab-subagents-first/SKILL.md +1 -1
  283. package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
  284. package/skills/delegation-usage/SKILL.md +19 -13
  285. package/skills/land/SKILL.md +77 -0
  286. package/skills/linear/SKILL.md +255 -0
  287. package/skills/release/SKILL.md +47 -3
  288. package/skills/standalone-review/SKILL.md +6 -1
  289. package/templates/README.md +4 -2
  290. package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
  291. package/templates/codex/.codex/agents/worker-complex.toml +1 -1
  292. package/templates/codex/.codex/config.toml +3 -4
  293. package/templates/codex/.codex/providers/README.md +13 -0
  294. package/templates/codex/.codex/providers/control.example.json +18 -0
  295. package/templates/codex/.codex/providers/provider.env.example +15 -0
  296. package/templates/codex/AGENTS.md +12 -7
  297. package/templates/codex/mcp-client.json +5 -1
  298. package/docs/README.md +0 -310
  299. package/docs/assets/setup.gif +0 -0
@@ -2,18 +2,23 @@ import process from 'node:process';
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { existsSync, readFileSync } from 'node:fs';
4
4
  import { createRequire } from 'node:module';
5
+ import { release as osRelease } from 'node:os';
5
6
  import { dirname, join, resolve } from 'node:path';
6
7
  import { buildDevtoolsSetupPlan, DEVTOOLS_SKILL_NAME, resolveDevtoolsReadiness } from './utils/devtools.js';
7
8
  import { isManagedCodexCliEnabled, resolveCodexCliBin, resolveCodexCliReadiness } from './utils/codexCli.js';
8
9
  import { resolveCodexHome } from './utils/codexPaths.js';
9
10
  import { resolveOptionalDependency } from './utils/optionalDeps.js';
10
- import { runCloudPreflight } from './utils/cloudPreflight.js';
11
- import { BASELINE_AGENTS, BASELINE_MODEL, BASELINE_REASONING_MINIMUM } from './codexDefaultsSetup.js';
11
+ import { buildCloudPreflightAuthProvenance, buildCloudPreflightRequest, runCloudPreflight } from './utils/cloudPreflight.js';
12
+ import { classifyDelegationTransport, formatDelegateServerProcessSummary, inspectDelegateServerProcesses, inspectDelegationMcpConfig, probeDelegationInitialize, resolveDelegationServerInvocation } from './utils/delegationMcpHealth.js';
13
+ import { sanitizeProviderOverrideEnv } from './utils/providerOverrideEnv.js';
14
+ import { hasLinearApiCredentials, hasLinearSourceBinding, resolveLinearSourceSetup } from './control/linearDispatchSource.js';
15
+ import { normalizeDispatchSourceProvider } from './control/trackerDispatchPilot.js';
16
+ import { BASELINE_AGENTS, BASELINE_MODEL, BASELINE_REVIEW_MODEL, BASELINE_REASONING_MINIMUM } from './codexDefaultsSetup.js';
12
17
  import { CommandPlanner } from './adapters/CommandPlanner.js';
13
18
  import { PipelineResolver } from './services/pipelineResolver.js';
14
19
  import { isRepoConfigRequired } from './config/repoConfigPolicy.js';
15
20
  const require = createRequire(import.meta.url);
16
- const toml = require('@iarna/toml');
21
+ let tomlParser;
17
22
  const OPTIONAL_DEPENDENCIES = [
18
23
  {
19
24
  name: 'playwright',
@@ -23,6 +28,7 @@ const OPTIONAL_DEPENDENCIES = [
23
28
  { name: 'pixelmatch', install: 'npm install --save-dev pixelmatch' },
24
29
  { name: 'cheerio', install: 'npm install --save-dev cheerio' }
25
30
  ];
31
+ const PROVIDER_ROOT_RELATIVE_PATH = '.codex/providers';
26
32
  export function runDoctor(cwd = process.cwd()) {
27
33
  const dependencies = OPTIONAL_DEPENDENCIES.map((entry) => {
28
34
  const resolved = resolveOptionalDependency(entry.name, cwd);
@@ -104,10 +110,30 @@ export function runDoctor(cwd = process.cwd()) {
104
110
  : null;
105
111
  const cloudStatus = !cloudCmdAvailable ? 'unavailable' : cloudEnvIdConfigured ? 'ok' : 'not_configured';
106
112
  const cloudFallbackPolicy = resolveCloudFallbackPolicy();
107
- const delegationConfig = inspectDelegationConfig();
108
- const delegationStatus = delegationConfig.status === 'ok' ? 'ok' : 'missing-config';
113
+ const repoRoot = resolveDoctorRepoRoot(cwd);
114
+ const delegationSnapshot = inspectDelegationMcpConfig(process.env);
115
+ const delegationTransport = classifyDelegationTransport(delegationSnapshot.entry);
116
+ const delegationStartup = probeDelegationInitialize(delegationSnapshot.entry, { env: process.env });
117
+ const delegationProcesses = inspectDelegateServerProcesses({ repoRoot });
118
+ const delegationStatus = delegationSnapshot.status !== 'ok'
119
+ ? 'missing-config'
120
+ : delegationTransport.status !== 'safe'
121
+ || delegationStartup.status === 'slow'
122
+ || delegationStartup.status === 'failed'
123
+ || delegationProcesses.status === 'stale'
124
+ ? 'warning'
125
+ : delegationProcesses.status === 'unavailable'
126
+ ? 'unavailable'
127
+ : 'ok';
128
+ const delegationBlocksOverallStatus = delegationStatus === 'missing-config';
129
+ const providers = inspectProviderReadiness(repoRoot, process.env);
109
130
  return {
110
- status: missing.length === 0 && codexDefaults.status === 'ok' ? 'ok' : 'warning',
131
+ status: missing.length === 0 &&
132
+ codexDefaults.status === 'ok' &&
133
+ providers.status === 'ok' &&
134
+ !delegationBlocksOverallStatus
135
+ ? 'ok'
136
+ : 'warning',
111
137
  missing,
112
138
  dependencies,
113
139
  devtools,
@@ -141,24 +167,71 @@ export function runDoctor(cwd = process.cwd()) {
141
167
  },
142
168
  delegation: {
143
169
  status: delegationStatus,
144
- config: delegationConfig,
145
- enablement: [
146
- 'Quick fix: codex-orchestrator doctor --apply --yes',
147
- 'Run: codex-orchestrator delegation setup --yes',
148
- 'Or manually: codex mcp add delegation -- codex-orchestrator delegate-server',
149
- "Enable for a run with: codex -c 'mcp_servers.delegation.enabled=true' ...",
150
- 'See: codex-orchestrator init codex'
151
- ]
152
- }
170
+ config: {
171
+ status: delegationSnapshot.status,
172
+ path: delegationSnapshot.path,
173
+ detail: delegationSnapshot.detail,
174
+ source: delegationSnapshot.entry?.source,
175
+ pinned_repo: delegationSnapshot.entry?.pinnedRepo ?? null
176
+ },
177
+ transport: {
178
+ status: delegationTransport.status,
179
+ kind: delegationTransport.kind,
180
+ command_line: delegationTransport.commandLine,
181
+ detail: delegationTransport.detail
182
+ },
183
+ startup: {
184
+ status: delegationStartup.status,
185
+ latency_ms: delegationStartup.latencyMs,
186
+ threshold_ms: delegationStartup.thresholdMs,
187
+ detail: delegationStartup.detail
188
+ },
189
+ processes: {
190
+ status: delegationProcesses.status,
191
+ active_count: delegationProcesses.activeCount,
192
+ active_pids: delegationProcesses.activePids,
193
+ stale_count: delegationProcesses.staleCount,
194
+ stale_pids: delegationProcesses.stalePids,
195
+ stale_rss_mb: Number((delegationProcesses.staleRssKb / 1024).toFixed(1)),
196
+ threshold_minutes: delegationProcesses.thresholdSeconds / 60,
197
+ detail: delegationProcesses.detail,
198
+ details: delegationProcesses.details.map((detail) => ({
199
+ pid: detail.pid,
200
+ ppid: detail.ppid,
201
+ elapsed_seconds: detail.elapsedSeconds,
202
+ rss_mb: Number((detail.rssKb / 1024).toFixed(1)),
203
+ cwd: detail.cwd,
204
+ parent_pid: detail.parentPid,
205
+ parent_cwd: detail.parentCwd,
206
+ root_codex_parent_pid: detail.rootCodexParentPid,
207
+ root_codex_parent_cwd: detail.rootCodexParentCwd,
208
+ classification: detail.classification,
209
+ classification_detail: detail.classificationDetail,
210
+ manifest_path: detail.manifestAssociation?.manifestPath ?? null,
211
+ issue_identifier: detail.manifestAssociation?.issueIdentifier ?? null,
212
+ pipeline_id: detail.manifestAssociation?.pipelineId ?? null,
213
+ task_id: detail.manifestAssociation?.taskId ?? null,
214
+ run_id: detail.manifestAssociation?.runId ?? null,
215
+ status: detail.manifestAssociation?.status ?? null
216
+ }))
217
+ },
218
+ enablement: buildDelegationEnablementGuidance({
219
+ configStatus: delegationSnapshot.status,
220
+ transportStatus: delegationTransport.status,
221
+ directTransportGuidance: buildDelegationDirectTransportGuidance()
222
+ })
223
+ },
224
+ providers
153
225
  };
154
226
  }
155
227
  export async function runDoctorCloudPreflight(options = {}) {
156
- const env = options.env ?? process.env;
157
- const cwd = options.cwd ?? process.cwd();
158
- const configuredRoot = normalizeOptionalString(env.CODEX_ORCHESTRATOR_ROOT);
228
+ const env = sanitizeProviderOverrideEnv(options.env ?? process.env);
229
+ const explicitCwd = normalizeOptionalString(options.cwd);
230
+ const cwd = explicitCwd ? resolve(explicitCwd) : process.cwd();
231
+ // An explicit cwd is the caller's repo hint; only fall back to the ambient root override when cwd is implicit.
232
+ const configuredRoot = explicitCwd ? null : normalizeOptionalString(env.CODEX_ORCHESTRATOR_ROOT);
159
233
  const rootHint = configuredRoot ? resolve(cwd, configuredRoot) : cwd;
160
234
  const repoRoot = resolveDoctorRepoRoot(rootHint);
161
- const codexBin = resolveCodexCliBin(env);
162
235
  const taskId = normalizeOptionalString(options.taskId)
163
236
  ?? normalizeOptionalString(env.MCP_RUNNER_TASK_ID)
164
237
  ?? normalizeOptionalString(env.TASK)
@@ -185,41 +258,113 @@ export async function runDoctorCloudPreflight(options = {}) {
185
258
  ?? planMetadataEnvironmentId
186
259
  ?? normalizeOptionalString(env.CODEX_CLOUD_ENV_ID)
187
260
  ?? resolveTaskMetadataCloudEnvironmentId(repoRoot, taskId);
188
- const branch = normalizeOptionalBranch(options.branch) ?? normalizeOptionalBranch(env.CODEX_CLOUD_BRANCH);
189
- const preflight = await runCloudPreflight({
261
+ const preflight = await runCloudPreflight(buildCloudPreflightRequest({
190
262
  repoRoot,
191
- codexBin,
192
263
  environmentId,
193
- branch,
264
+ branch: options.branch,
194
265
  env
195
- });
266
+ }));
267
+ const authProvenance = preflight.details.authProvenance ??
268
+ buildCloudPreflightAuthProvenance({
269
+ env,
270
+ environmentId: preflight.details.environmentId,
271
+ branch: preflight.details.branch
272
+ });
196
273
  const issues = planMetadataIssue ? [planMetadataIssue, ...preflight.issues] : preflight.issues;
274
+ const securityAdvisories = inspectCodexSandboxSecurityAdvisories({ env });
197
275
  const guidance = buildCloudPreflightGuidance(issues);
198
276
  return {
199
277
  ok: preflight.ok && planMetadataIssue === null,
200
278
  details: {
201
279
  codex_bin: preflight.details.codexBin,
202
280
  environment_id: preflight.details.environmentId,
203
- branch: preflight.details.branch
281
+ branch: preflight.details.branch,
282
+ auth_provenance: {
283
+ provider_kind: authProvenance.providerKind,
284
+ active_profile_fingerprint: authProvenance.activeProfileFingerprint,
285
+ active_account_fingerprint: authProvenance.activeAccountFingerprint,
286
+ cloud_env_id: authProvenance.cloudEnvId,
287
+ cloud_branch: authProvenance.cloudBranch,
288
+ credential_source: authProvenance.credentialSource,
289
+ auth_freshness: authProvenance.authFreshness
290
+ }
204
291
  },
205
292
  issues,
293
+ security_advisories: securityAdvisories,
206
294
  guidance
207
295
  };
208
296
  }
297
+ export function inspectCodexSandboxSecurityAdvisories(options = {}) {
298
+ const env = options.env ?? process.env;
299
+ const advisories = [];
300
+ const configPath = join(resolveCodexHome(env), 'config.toml');
301
+ if (existsSync(configPath)) {
302
+ try {
303
+ const raw = readFileSync(configPath, 'utf8');
304
+ const parsed = getTomlParser().parse(raw);
305
+ if (isRecord(parsed)) {
306
+ const sandboxMode = normalizeOptionalString(readStringValue(parsed.sandbox_mode));
307
+ if (sandboxMode === 'danger-full-access') {
308
+ advisories.push({
309
+ code: 'codex_config_danger_full_access',
310
+ scope: 'local-only',
311
+ severity: 'warning',
312
+ message: 'Codex config sets top-level sandbox_mode to danger-full-access.',
313
+ guidance: 'Treat this as a local-only advisory; do not use it to satisfy cloud readiness or weaken CO sandbox defaults.',
314
+ details: {
315
+ path: configPath,
316
+ sandbox_mode: sandboxMode
317
+ }
318
+ });
319
+ }
320
+ }
321
+ }
322
+ catch {
323
+ // Existing Codex defaults checks already report invalid TOML; keep this advisory focused on security posture.
324
+ }
325
+ }
326
+ const platform = options.platform ?? process.platform;
327
+ const releaseText = normalizeOptionalString(options.osRelease ?? osRelease());
328
+ if (isWsl1Release(platform, releaseText)) {
329
+ advisories.push({
330
+ code: 'wsl1_bubblewrap_unsupported',
331
+ scope: 'local-only',
332
+ severity: 'warning',
333
+ message: 'WSL1 detected; Codex bubblewrap sandbox behavior is unsupported for this local platform.',
334
+ guidance: 'Run local Codex sandbox checks on WSL2/Linux/macOS, or keep this as a local-only limitation; it is not cloud canary evidence.',
335
+ details: {
336
+ platform,
337
+ os_release: releaseText ?? undefined
338
+ }
339
+ });
340
+ }
341
+ return advisories;
342
+ }
343
+ function isWsl1Release(platform, releaseText) {
344
+ if (platform !== 'linux' || !releaseText) {
345
+ return false;
346
+ }
347
+ const normalized = releaseText.toLowerCase();
348
+ return normalized.includes('microsoft') && !normalized.includes('microsoft-standard') && !normalized.includes('wsl2');
349
+ }
209
350
  function resolveDoctorRepoRoot(cwd) {
210
351
  const fallback = resolve(cwd);
211
352
  let current = fallback;
353
+ let providerRootCandidate = null;
212
354
  while (current) {
213
355
  if (existsSync(join(current, 'tasks', 'index.json'))) {
214
356
  return current;
215
357
  }
358
+ if (!providerRootCandidate && existsSync(join(current, PROVIDER_ROOT_RELATIVE_PATH))) {
359
+ providerRootCandidate = current;
360
+ }
216
361
  const parent = dirname(current);
217
362
  if (parent === current) {
218
363
  break;
219
364
  }
220
365
  current = parent;
221
366
  }
222
- return fallback;
367
+ return providerRootCandidate ?? fallback;
223
368
  }
224
369
  export function formatDoctorCloudPreflightSummary(result) {
225
370
  const lines = [];
@@ -227,6 +372,11 @@ export function formatDoctorCloudPreflightSummary(result) {
227
372
  lines.push(` - codex bin: ${result.details.codex_bin}`);
228
373
  lines.push(` - environment id: ${result.details.environment_id ?? '<unset>'}`);
229
374
  lines.push(` - branch: ${result.details.branch ?? '<unset>'}`);
375
+ lines.push(` - auth provider: ${result.details.auth_provenance.provider_kind}`);
376
+ lines.push(` - credential source: ${result.details.auth_provenance.credential_source ?? '<none detected>'}`);
377
+ lines.push(` - profile fingerprint: ${result.details.auth_provenance.active_profile_fingerprint ?? '<unset>'}`);
378
+ lines.push(` - account fingerprint: ${result.details.auth_provenance.active_account_fingerprint ?? '<unset>'}`);
379
+ lines.push(` - auth freshness: ${result.details.auth_provenance.auth_freshness}`);
230
380
  if (result.issues.length > 0) {
231
381
  lines.push(' - issues:');
232
382
  for (const issue of result.issues) {
@@ -239,6 +389,19 @@ export function formatDoctorCloudPreflightSummary(result) {
239
389
  lines.push(` - ${item}`);
240
390
  }
241
391
  }
392
+ if (result.security_advisories.length > 0) {
393
+ lines.push(' - sandbox/security advisories:');
394
+ for (const advisory of result.security_advisories) {
395
+ lines.push(` - [${advisory.code}/${advisory.scope}] ${advisory.message}`);
396
+ lines.push(` guidance: ${advisory.guidance}`);
397
+ if (advisory.details?.path) {
398
+ lines.push(` path: ${advisory.details.path}`);
399
+ }
400
+ if (advisory.details?.platform || advisory.details?.os_release) {
401
+ lines.push(` platform: ${advisory.details.platform ?? '<unknown>'}, os_release: ${advisory.details.os_release ?? '<unknown>'}`);
402
+ }
403
+ }
404
+ }
242
405
  return lines;
243
406
  }
244
407
  export function formatDoctorSummary(result) {
@@ -308,10 +471,13 @@ export function formatDoctorSummary(result) {
308
471
  lines.push(` detail: ${result.codex_defaults.config.detail}`);
309
472
  }
310
473
  lines.push(` - model: ${result.codex_defaults.checks.model.status} (actual: ${result.codex_defaults.checks.model.actual ?? '<unset>'}, expected: ${result.codex_defaults.checks.model.expected})`);
474
+ lines.push(` - review_model: ${result.codex_defaults.checks.review_model.status} (actual: ${result.codex_defaults.checks.review_model.actual ?? '<unset>'}, expected: ${result.codex_defaults.checks.review_model.expected})`);
311
475
  lines.push(` - model_reasoning_effort: ${result.codex_defaults.checks.model_reasoning_effort.status} (actual: ${result.codex_defaults.checks.model_reasoning_effort.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.model_reasoning_effort.expected_minimum})`);
312
476
  lines.push(` - agents.max_threads: ${result.codex_defaults.checks.max_threads.status} (actual: ${result.codex_defaults.checks.max_threads.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_threads.expected_minimum})`);
313
- lines.push(` - agents.max_depth: ${result.codex_defaults.checks.max_depth.status} (actual: ${result.codex_defaults.checks.max_depth.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_depth.expected_minimum})`);
314
- lines.push(` - agents.max_spawn_depth: ${result.codex_defaults.checks.max_spawn_depth.status} (actual: ${result.codex_defaults.checks.max_spawn_depth.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_spawn_depth.expected_minimum})`);
477
+ lines.push(` - agents.max_depth: ${result.codex_defaults.checks.max_depth.status} (actual: ${result.codex_defaults.checks.max_depth.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_depth.expected_minimum} when set; <unset> accepted)`);
478
+ if (result.codex_defaults.legacy_max_spawn_depth?.present) {
479
+ lines.push(` - legacy agents.max_spawn_depth: ${result.codex_defaults.legacy_max_spawn_depth.status} (actual: ${result.codex_defaults.legacy_max_spawn_depth.actual ?? '<unset>'}; ${result.codex_defaults.legacy_max_spawn_depth.detail})`);
480
+ }
315
481
  for (const line of result.codex_defaults.guidance) {
316
482
  lines.push(` - ${line}`);
317
483
  }
@@ -340,23 +506,176 @@ export function formatDoctorSummary(result) {
340
506
  if (result.delegation.config.detail) {
341
507
  lines.push(` detail: ${result.delegation.config.detail}`);
342
508
  }
509
+ if (result.delegation.config.source) {
510
+ lines.push(` - source: ${result.delegation.config.source}`);
511
+ }
512
+ lines.push(` - transport: ${result.delegation.transport.status} (${result.delegation.transport.kind})`);
513
+ if (result.delegation.transport.command_line) {
514
+ lines.push(` command: ${result.delegation.transport.command_line}`);
515
+ }
516
+ lines.push(` detail: ${result.delegation.transport.detail}`);
517
+ lines.push(` - initialize: ${result.delegation.startup.status} (latency: ${result.delegation.startup.latency_ms ?? '<skipped>'} ms, threshold: ${result.delegation.startup.threshold_ms} ms)`);
518
+ lines.push(` detail: ${result.delegation.startup.detail}`);
519
+ lines.push(` - processes: ${result.delegation.processes.status} (active: ${result.delegation.processes.active_count}, stale: ${result.delegation.processes.stale_count}, stale rss: ${result.delegation.processes.stale_rss_mb.toFixed(1)} MB)`);
520
+ lines.push(` detail: ${result.delegation.processes.detail}`);
521
+ if (result.delegation.processes.stale_pids.length > 0) {
522
+ lines.push(` stale pids: ${result.delegation.processes.stale_pids.join(', ')}`);
523
+ for (const detail of result.delegation.processes.details
524
+ .filter((entry) => entry.classification === 'stale-parent-session' || entry.classification === 'stale-orphan')
525
+ .slice(0, 3)) {
526
+ lines.push(` stale detail: ${formatDelegateServerProcessSummary({
527
+ pid: detail.pid,
528
+ classification: detail.classification,
529
+ cwd: detail.cwd,
530
+ parentPid: detail.parent_pid,
531
+ parentCwd: detail.parent_cwd,
532
+ rootCodexParentPid: detail.root_codex_parent_pid,
533
+ rootCodexParentCwd: detail.root_codex_parent_cwd,
534
+ manifestPath: detail.manifest_path
535
+ })}`);
536
+ }
537
+ }
343
538
  for (const line of result.delegation.enablement) {
344
539
  lines.push(` - ${line}`);
345
540
  }
541
+ lines.push(`Providers: ${result.providers.status}`);
542
+ lines.push(` - repo examples: ${result.providers.repo_examples.status} (${result.providers.repo_examples.root})`);
543
+ if (result.providers.repo_examples.missing.length > 0) {
544
+ lines.push(` missing: ${result.providers.repo_examples.missing.join(', ')}`);
545
+ }
546
+ lines.push(` - control policy: ${result.providers.control_policy.status} (${result.providers.control_policy.path})`);
547
+ if (result.providers.control_policy.detail) {
548
+ lines.push(` detail: ${result.providers.control_policy.detail}`);
549
+ }
550
+ lines.push(` - Linear: ${result.providers.linear.status}`);
551
+ lines.push(` credentials: ${result.providers.linear.credentials_present ? 'present' : 'missing'}`);
552
+ lines.push(` binding: ${result.providers.linear.binding_present ? 'present' : 'missing'}`);
553
+ lines.push(` webhook secret: ${result.providers.linear.webhook_secret_present ? 'present' : 'missing'}`);
554
+ lines.push(` dispatch_pilot: ${renderProviderToggleSummary(result.providers.linear.dispatch_pilot_enabled, result.providers.linear.dispatch_pilot_provider)}`);
555
+ lines.push(` - Telegram: ${result.providers.telegram.status}`);
556
+ lines.push(` polling: ${result.providers.telegram.polling_enabled ? 'enabled' : 'disabled'}`);
557
+ lines.push(` bot token: ${result.providers.telegram.bot_token_present ? 'present' : 'missing'}`);
558
+ lines.push(` allowlisted chats: ${result.providers.telegram.allowed_chat_ids}`);
559
+ lines.push(` mutations: ${result.providers.telegram.mutations_enabled ? 'enabled' : 'disabled'}`);
560
+ lines.push(` push: ${result.providers.telegram.push_enabled ? 'enabled' : 'disabled'}`);
561
+ lines.push(` transport policy: ${renderTransportPolicySummary(result.providers.telegram.telegram_transport_allowed)}`);
562
+ for (const line of result.providers.guidance) {
563
+ lines.push(` - ${line}`);
564
+ }
346
565
  return lines;
347
566
  }
567
+ export function buildDelegationDirectTransportGuidance(resolver = () => resolveDelegationServerInvocation({ env: process.env, execPath: process.execPath })) {
568
+ try {
569
+ return `Direct dist transport: ${resolver().commandLine} --repo <path>`;
570
+ }
571
+ catch (error) {
572
+ const detail = error instanceof Error ? error.message : String(error);
573
+ return `Direct dist transport unavailable until dist is built: ${detail}`;
574
+ }
575
+ }
576
+ export function buildDelegationEnablementGuidance(options) {
577
+ const lines = [];
578
+ const setupApplyWouldHelp = options.configStatus !== 'ok' || options.transportStatus !== 'safe';
579
+ if (setupApplyWouldHelp) {
580
+ lines.push('Quick fix: codex-orchestrator doctor --apply --yes');
581
+ }
582
+ lines.push('Run: codex-orchestrator delegation setup --yes');
583
+ lines.push('Run: codex-orchestrator delegation cleanup-stale --yes');
584
+ lines.push(options.directTransportGuidance ?? buildDelegationDirectTransportGuidance());
585
+ lines.push("Enable for a run with: codex -c 'mcp_servers.delegation.enabled=true' ...");
586
+ lines.push('See: codex-orchestrator init codex');
587
+ return lines;
588
+ }
589
+ function inspectProviderReadiness(repoRoot, env = process.env) {
590
+ const providerRoot = join(repoRoot, PROVIDER_ROOT_RELATIVE_PATH);
591
+ const repoExamples = {
592
+ readme: join(providerRoot, 'README.md'),
593
+ env_example: join(providerRoot, 'provider.env.example'),
594
+ control_example: join(providerRoot, 'control.example.json')
595
+ };
596
+ const missingRepoExamples = Object.entries(repoExamples)
597
+ .filter(([, filePath]) => !existsSync(filePath))
598
+ .map(([key]) => key);
599
+ const controlPolicy = readProviderControlPolicy(providerRoot);
600
+ const linearSourceSetup = resolveLinearSourceSetup({
601
+ provider: 'linear',
602
+ workspace_id: controlPolicy.dispatch_pilot_source_setup?.workspace_id ?? null,
603
+ team_id: controlPolicy.dispatch_pilot_source_setup?.team_id ?? null,
604
+ project_id: controlPolicy.dispatch_pilot_source_setup?.project_id ?? null
605
+ }, env);
606
+ const linearCredentialsPresent = hasLinearApiCredentials(env);
607
+ const linearBindingPresent = hasLinearSourceBinding(linearSourceSetup);
608
+ const linearWebhookSecretPresent = Boolean(normalizeOptionalString(env.CO_LINEAR_WEBHOOK_SECRET));
609
+ const linearRequired = controlPolicy.dispatch_pilot_enabled === true && controlPolicy.dispatch_pilot_provider === 'linear';
610
+ const linearReady = linearCredentialsPresent &&
611
+ linearBindingPresent &&
612
+ linearWebhookSecretPresent &&
613
+ linearRequired;
614
+ const telegramPollingEnabled = parseEnvBoolean(env.CO_TELEGRAM_POLLING_ENABLED);
615
+ const telegramBotTokenPresent = Boolean(normalizeOptionalString(env.CO_TELEGRAM_BOT_TOKEN));
616
+ const telegramAllowedChatIds = parseCsvList(env.CO_TELEGRAM_ALLOWED_CHAT_IDS).length;
617
+ const telegramMutationsEnabled = parseEnvBoolean(env.CO_TELEGRAM_ENABLE_MUTATIONS);
618
+ const telegramPushEnabled = parseEnvBoolean(env.CO_TELEGRAM_PUSH_ENABLED);
619
+ const telegramRequired = controlPolicy.telegram_transport_allowed === true;
620
+ const telegramReady = telegramPollingEnabled &&
621
+ telegramBotTokenPresent &&
622
+ telegramAllowedChatIds > 0 &&
623
+ telegramMutationsEnabled &&
624
+ telegramRequired;
625
+ const repoExamplesStatus = missingRepoExamples.length === 0 ? 'ok' : 'missing';
626
+ return {
627
+ status: repoExamplesStatus === 'ok' &&
628
+ controlPolicy.status === 'ok' &&
629
+ (!linearRequired || linearReady) &&
630
+ (!telegramRequired || telegramReady)
631
+ ? 'ok'
632
+ : 'advisory',
633
+ repo_examples: {
634
+ status: repoExamplesStatus,
635
+ root: providerRoot,
636
+ paths: repoExamples,
637
+ missing: missingRepoExamples
638
+ },
639
+ control_policy: controlPolicy,
640
+ linear: {
641
+ status: linearReady ? 'ready' : 'incomplete',
642
+ credentials_present: linearCredentialsPresent,
643
+ binding_present: linearBindingPresent,
644
+ webhook_secret_present: linearWebhookSecretPresent,
645
+ dispatch_pilot_enabled: controlPolicy.dispatch_pilot_enabled,
646
+ dispatch_pilot_provider: controlPolicy.dispatch_pilot_provider
647
+ },
648
+ telegram: {
649
+ status: telegramReady ? 'ready' : 'incomplete',
650
+ polling_enabled: telegramPollingEnabled,
651
+ bot_token_present: telegramBotTokenPresent,
652
+ allowed_chat_ids: telegramAllowedChatIds,
653
+ mutations_enabled: telegramMutationsEnabled,
654
+ push_enabled: telegramPushEnabled,
655
+ telegram_transport_allowed: controlPolicy.telegram_transport_allowed
656
+ },
657
+ guidance: [
658
+ 'Seed the current repo with: codex-orchestrator init codex --cwd <repo>',
659
+ 'Review .codex/providers/provider.env.example and .codex/providers/control.example.json before enabling providers.',
660
+ 'Re-run codex-orchestrator doctor --format json after exporting provider env vars to confirm readiness.'
661
+ ]
662
+ };
663
+ }
348
664
  function inspectCodexDefaultsAdvisory(env = process.env) {
349
665
  const configPath = join(resolveCodexHome(env), 'config.toml');
350
666
  const checks = {
351
667
  model: { status: 'advisory', expected: BASELINE_MODEL, actual: null },
668
+ review_model: { status: 'advisory', expected: BASELINE_REVIEW_MODEL, actual: null },
352
669
  model_reasoning_effort: { status: 'advisory', expected_minimum: BASELINE_REASONING_MINIMUM, actual: null },
353
670
  max_threads: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_threads, actual: null },
354
- max_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_depth, actual: null },
355
- max_spawn_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_spawn_depth, actual: null }
671
+ max_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_depth, actual: null }
356
672
  };
673
+ let legacyMaxSpawnDepth = null;
357
674
  const guidance = [
358
675
  'Run `codex-orchestrator codex defaults --yes` to apply additive baseline defaults.',
359
- 'Additive policy: unrelated config keys are preserved; existing role files stay untouched unless `--force` is set.'
676
+ 'Additive policy: unrelated config keys are preserved; existing role files stay untouched unless `--force` is set.',
677
+ 'Current CO baseline no longer seeds or expects `agents.max_spawn_depth`; keep it only as a legacy local override when an older parser/runtime still honors it.',
678
+ 'Leaving `agents.max_depth` unset remains accepted when local parser/runtime constraints require it.'
360
679
  ];
361
680
  if (!existsSync(configPath)) {
362
681
  return {
@@ -369,7 +688,7 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
369
688
  let parsed;
370
689
  try {
371
690
  const raw = readFileSync(configPath, 'utf8');
372
- const value = toml.parse(raw);
691
+ const value = getTomlParser().parse(raw);
373
692
  if (!isRecord(value)) {
374
693
  throw new Error('top-level TOML document must be a table.');
375
694
  }
@@ -393,6 +712,9 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
393
712
  const model = normalizeOptionalString(readStringValue(parsed.model));
394
713
  checks.model.actual = model;
395
714
  checks.model.status = model === BASELINE_MODEL ? 'ok' : 'advisory';
715
+ const reviewModel = normalizeOptionalString(readStringValue(parsed.review_model));
716
+ checks.review_model.actual = reviewModel;
717
+ checks.review_model.status = reviewModel === BASELINE_REVIEW_MODEL ? 'ok' : 'advisory';
396
718
  const reasoning = normalizeOptionalString(readStringValue(parsed.model_reasoning_effort));
397
719
  checks.model_reasoning_effort.actual = reasoning;
398
720
  checks.model_reasoning_effort.status = isReasoningAtLeastMinimum(reasoning, BASELINE_REASONING_MINIMUM)
@@ -406,27 +728,208 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
406
728
  checks.max_threads.status =
407
729
  typeof maxThreads === 'number' && maxThreads >= BASELINE_AGENTS.max_threads ? 'ok' : 'advisory';
408
730
  checks.max_depth.actual = maxDepth;
409
- checks.max_depth.status = typeof maxDepth === 'number' && maxDepth >= BASELINE_AGENTS.max_depth ? 'ok' : 'advisory';
410
- checks.max_spawn_depth.actual = maxSpawnDepth;
411
- checks.max_spawn_depth.status =
412
- typeof maxSpawnDepth === 'number' && maxSpawnDepth >= BASELINE_AGENTS.max_spawn_depth ? 'ok' : 'advisory';
413
- const allChecksOk = Object.values(checks).every((check) => check.status === 'ok');
731
+ checks.max_depth.status =
732
+ maxDepth === null || (typeof maxDepth === 'number' && maxDepth >= BASELINE_AGENTS.max_depth) ? 'ok' : 'advisory';
733
+ if (maxSpawnDepth !== null) {
734
+ const legacySpawnDepthOk = maxSpawnDepth >= BASELINE_AGENTS.max_depth;
735
+ legacyMaxSpawnDepth = {
736
+ present: true,
737
+ status: legacySpawnDepthOk ? 'ok' : 'advisory',
738
+ actual: maxSpawnDepth,
739
+ detail: legacySpawnDepthOk
740
+ ? 'legacy override detected; safe for the CO baseline, but remove it when your local parser/runtime no longer consumes spawn-depth caps'
741
+ : `older parser/runtime may still treat this as a hard cap below the CO baseline depth; raise it to >= ${BASELINE_AGENTS.max_depth} or remove it`
742
+ };
743
+ }
744
+ const allChecksOk = Object.values(checks).every((check) => check.status === 'ok')
745
+ && legacyMaxSpawnDepth?.status !== 'advisory';
414
746
  return {
415
747
  status: allChecksOk ? 'ok' : 'advisory',
416
748
  config: { path: configPath, status: 'ok' },
417
749
  checks,
750
+ legacy_max_spawn_depth: legacyMaxSpawnDepth,
418
751
  guidance
419
752
  };
420
753
  }
754
+ function getTomlParser() {
755
+ if (tomlParser) {
756
+ return tomlParser;
757
+ }
758
+ if (tomlParser === null) {
759
+ throw new Error('Failed to load @iarna/toml.');
760
+ }
761
+ try {
762
+ tomlParser = require('@iarna/toml');
763
+ return tomlParser;
764
+ }
765
+ catch (error) {
766
+ tomlParser = null;
767
+ throw error;
768
+ }
769
+ }
421
770
  function isRecord(value) {
422
771
  return typeof value === 'object' && value !== null && !Array.isArray(value);
423
772
  }
424
- function readStringValue(value) {
425
- return typeof value === 'string' ? value : null;
773
+ function readStringValue(value, ...keys) {
774
+ if (keys.length === 0) {
775
+ return typeof value === 'string' ? value : null;
776
+ }
777
+ if (!isRecord(value)) {
778
+ return null;
779
+ }
780
+ for (const key of keys) {
781
+ if (typeof value[key] === 'string') {
782
+ return value[key];
783
+ }
784
+ }
785
+ return null;
426
786
  }
427
787
  function readNumberValue(value) {
428
788
  return typeof value === 'number' && Number.isFinite(value) ? value : null;
429
789
  }
790
+ function readBooleanValue(value) {
791
+ return typeof value === 'boolean' ? value : null;
792
+ }
793
+ function readRecordValue(value, ...keys) {
794
+ if (!isRecord(value)) {
795
+ return null;
796
+ }
797
+ for (const key of keys) {
798
+ if (isRecord(value[key])) {
799
+ return value[key];
800
+ }
801
+ }
802
+ return null;
803
+ }
804
+ function readStringArrayValue(value, ...keys) {
805
+ const raw = isRecord(value)
806
+ ? keys.map((key) => value[key]).find((entry) => Array.isArray(entry))
807
+ : Array.isArray(value)
808
+ ? value
809
+ : undefined;
810
+ if (!Array.isArray(raw)) {
811
+ return undefined;
812
+ }
813
+ return raw
814
+ .map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
815
+ .filter((entry) => entry.length > 0);
816
+ }
817
+ function parseEnvBoolean(value) {
818
+ const normalized = normalizeOptionalString(value);
819
+ if (!normalized) {
820
+ return false;
821
+ }
822
+ return ['1', 'true', 'yes', 'on'].includes(normalized.toLowerCase());
823
+ }
824
+ function parseCsvList(value) {
825
+ const normalized = normalizeOptionalString(value);
826
+ if (!normalized) {
827
+ return [];
828
+ }
829
+ return normalized
830
+ .split(',')
831
+ .map((entry) => entry.trim())
832
+ .filter((entry) => entry.length > 0);
833
+ }
834
+ function readProviderControlPolicy(providerRoot) {
835
+ const preferredPath = join(providerRoot, 'control.json');
836
+ const fallbackPath = join(providerRoot, 'control.example.json');
837
+ const candidate = existsSync(preferredPath) ? preferredPath : existsSync(fallbackPath) ? fallbackPath : preferredPath;
838
+ if (!existsSync(candidate)) {
839
+ return {
840
+ status: 'missing',
841
+ path: preferredPath,
842
+ dispatch_pilot_enabled: null,
843
+ dispatch_pilot_provider: null,
844
+ dispatch_pilot_source_setup: null,
845
+ transport_mutating_enabled: null,
846
+ telegram_transport_allowed: null
847
+ };
848
+ }
849
+ try {
850
+ const parsed = JSON.parse(readFileSync(candidate, 'utf8'));
851
+ if (!isRecord(parsed)) {
852
+ throw new Error('provider control policy must be a JSON object');
853
+ }
854
+ const featureToggles = isRecord(parsed.feature_toggles) ? parsed.feature_toggles : null;
855
+ const dispatchPilot = resolveDispatchPilotControls(featureToggles);
856
+ const dispatchSource = readRecordValue(dispatchPilot, 'source');
857
+ const dispatchBindingSource = readRecordValue(dispatchSource, 'linear') ?? dispatchSource;
858
+ const dispatchPilotEnabled = readBooleanValue(dispatchPilot?.enabled);
859
+ const rawDispatchPilotProvider = normalizeOptionalString(readStringValue(dispatchSource, 'provider', 'source_provider', 'sourceProvider'));
860
+ const normalizedDispatchPilotProvider = normalizeDispatchSourceProvider(rawDispatchPilotProvider ?? undefined);
861
+ if (dispatchPilotEnabled === true) {
862
+ if (!dispatchSource) {
863
+ throw new Error('dispatch_pilot.source is required when dispatch_pilot.enabled=true');
864
+ }
865
+ if (!normalizedDispatchPilotProvider) {
866
+ throw new Error(rawDispatchPilotProvider
867
+ ? `unsupported dispatch_pilot.source.provider: ${rawDispatchPilotProvider}`
868
+ : 'dispatch_pilot.source.provider is required when dispatch_pilot.enabled=true');
869
+ }
870
+ }
871
+ const transportMutating = resolveTransportMutatingControls(featureToggles);
872
+ const transportMutatingEnabled = readBooleanValue(transportMutating?.enabled);
873
+ const allowedTransports = readStringArrayValue(transportMutating, 'allowed_transports', 'allowedTransports');
874
+ const telegramTransportAllowed = transportMutating === null
875
+ ? null
876
+ : transportMutatingEnabled === true
877
+ ? allowedTransports ? allowedTransports.includes('telegram') : true
878
+ : false;
879
+ return {
880
+ status: 'ok',
881
+ path: candidate,
882
+ dispatch_pilot_enabled: dispatchPilotEnabled,
883
+ dispatch_pilot_provider: normalizedDispatchPilotProvider ?? rawDispatchPilotProvider,
884
+ dispatch_pilot_source_setup: dispatchBindingSource
885
+ ? {
886
+ workspace_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'workspace_id', 'workspaceId')),
887
+ team_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'team_id', 'teamId')),
888
+ project_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'project_id', 'projectId'))
889
+ }
890
+ : null,
891
+ transport_mutating_enabled: transportMutatingEnabled,
892
+ telegram_transport_allowed: telegramTransportAllowed
893
+ };
894
+ }
895
+ catch (error) {
896
+ return {
897
+ status: 'invalid',
898
+ path: candidate,
899
+ detail: error instanceof Error ? error.message : String(error),
900
+ dispatch_pilot_enabled: null,
901
+ dispatch_pilot_provider: null,
902
+ dispatch_pilot_source_setup: null,
903
+ transport_mutating_enabled: null,
904
+ telegram_transport_allowed: null
905
+ };
906
+ }
907
+ }
908
+ function resolveTransportMutatingControls(featureToggles) {
909
+ const direct = readRecordValue(featureToggles, 'transport_mutating_controls');
910
+ const coordinator = readRecordValue(featureToggles, 'coordinator');
911
+ const nested = readRecordValue(coordinator, 'transport_mutating_controls');
912
+ return nested ?? direct ?? null;
913
+ }
914
+ function resolveDispatchPilotControls(featureToggles) {
915
+ const direct = readRecordValue(featureToggles, 'dispatch_pilot');
916
+ const coordinator = readRecordValue(featureToggles, 'coordinator');
917
+ const nested = readRecordValue(coordinator, 'dispatch_pilot');
918
+ return nested ?? direct ?? null;
919
+ }
920
+ function renderProviderToggleSummary(enabled, provider) {
921
+ if (enabled === null) {
922
+ return 'unconfigured';
923
+ }
924
+ const label = enabled ? 'enabled' : 'disabled';
925
+ return provider ? `${label} (${provider})` : label;
926
+ }
927
+ function renderTransportPolicySummary(allowed) {
928
+ if (allowed === null) {
929
+ return 'unconfigured';
930
+ }
931
+ return allowed ? 'telegram allowed' : 'telegram blocked';
932
+ }
430
933
  function isReasoningAtLeastMinimum(value, minimum) {
431
934
  const rank = resolveReasoningRank(value);
432
935
  const minimumRank = resolveReasoningRank(minimum);
@@ -464,10 +967,6 @@ function normalizeOptionalString(value) {
464
967
  const trimmed = value.trim();
465
968
  return trimmed.length > 0 ? trimmed : null;
466
969
  }
467
- function normalizeOptionalBranch(value) {
468
- const normalized = normalizeOptionalString(value);
469
- return normalized ? normalized.replace(/^refs\/heads\//u, '') : null;
470
- }
471
970
  function resolveCloudFallbackPolicy(env = process.env) {
472
971
  const raw = normalizeOptionalString(env.CODEX_ORCHESTRATOR_CLOUD_FALLBACK);
473
972
  if (!raw) {
@@ -641,82 +1140,3 @@ function canRunCommand(command, args) {
641
1140
  }
642
1141
  return result.status === 0;
643
1142
  }
644
- function inspectDelegationConfig(env = process.env) {
645
- const codexHome = resolveCodexHome(env);
646
- const configPath = join(codexHome, 'config.toml');
647
- if (!existsSync(configPath)) {
648
- return { status: 'missing', path: configPath, detail: 'config.toml not found' };
649
- }
650
- try {
651
- const raw = readFileSync(configPath, 'utf8');
652
- const hasEntry = hasMcpServerEntry(raw, 'delegation');
653
- if (hasEntry) {
654
- return { status: 'ok', path: configPath };
655
- }
656
- return { status: 'missing', path: configPath, detail: 'mcp_servers.delegation entry not found' };
657
- }
658
- catch (error) {
659
- return {
660
- status: 'missing',
661
- path: configPath,
662
- detail: error instanceof Error ? error.message : String(error)
663
- };
664
- }
665
- }
666
- function hasMcpServerEntry(raw, serverName) {
667
- const lines = raw.split('\n');
668
- let currentTable = null;
669
- for (const line of lines) {
670
- const trimmed = stripTomlComment(line).trim();
671
- if (!trimmed) {
672
- continue;
673
- }
674
- const tableMatch = trimmed.match(/^\[(.+)\]$/u);
675
- if (tableMatch) {
676
- currentTable = tableMatch[1]?.trim() ?? null;
677
- if (currentTable === `mcp_servers.${serverName}` ||
678
- currentTable === `mcp_servers."${serverName}"` ||
679
- currentTable === `mcp_servers.'${serverName}'`) {
680
- return true;
681
- }
682
- continue;
683
- }
684
- if (trimmed.startsWith('mcp_servers.')) {
685
- if (trimmed.startsWith(`mcp_servers."${serverName}".`)) {
686
- return true;
687
- }
688
- if (trimmed.startsWith(`mcp_servers.'${serverName}'.`)) {
689
- return true;
690
- }
691
- if (trimmed.startsWith(`mcp_servers.${serverName}.`)) {
692
- return true;
693
- }
694
- if (trimmed.startsWith(`mcp_servers."${serverName}"=`)) {
695
- return true;
696
- }
697
- if (trimmed.startsWith(`mcp_servers.'${serverName}'=`)) {
698
- return true;
699
- }
700
- if (trimmed.startsWith(`mcp_servers.${serverName}=`)) {
701
- return true;
702
- }
703
- }
704
- if (currentTable === 'mcp_servers') {
705
- const entryPattern = new RegExp(`^"?${escapeRegExp(serverName)}"?\\s*=`, 'u');
706
- if (entryPattern.test(trimmed)) {
707
- return true;
708
- }
709
- }
710
- }
711
- return false;
712
- }
713
- function stripTomlComment(line) {
714
- const index = line.indexOf('#');
715
- if (index === -1) {
716
- return line;
717
- }
718
- return line.slice(0, index);
719
- }
720
- function escapeRegExp(value) {
721
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
722
- }