@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.
- package/.agents/plugins/marketplace.json +20 -0
- package/README.md +46 -317
- package/bin/codex-orchestrator.js +161 -0
- package/codex.orchestrator.json +149 -13
- package/dist/bin/codex-orchestrator.js +797 -1154
- package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +50 -0
- package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +22 -4
- package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +3 -3
- package/dist/orchestrator/src/cli/adapters/CommandTester.js +2 -2
- package/dist/orchestrator/src/cli/adapters/cloudFailureDiagnostics.js +295 -11
- package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
- package/dist/orchestrator/src/cli/coStatusCliShell.js +451 -0
- package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
- package/dist/orchestrator/src/cli/codexCliShell.js +119 -0
- package/dist/orchestrator/src/cli/codexDefaultsSetup.js +265 -36
- package/dist/orchestrator/src/cli/config/delegationConfig.js +317 -5
- package/dist/orchestrator/src/cli/config/repoConfigPolicy.js +2 -3
- package/dist/orchestrator/src/cli/config/userConfig.js +28 -13
- package/dist/orchestrator/src/cli/control/authenticatedControlRouteGate.js +69 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteComposition.js +267 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteController.js +5 -0
- package/dist/orchestrator/src/cli/control/authenticatedRouteDispatcher.js +41 -0
- package/dist/orchestrator/src/cli/control/compatibilityIssuePresenter.js +1035 -0
- package/dist/orchestrator/src/cli/control/confirmationApproveController.js +62 -0
- package/dist/orchestrator/src/cli/control/confirmationCreateController.js +69 -0
- package/dist/orchestrator/src/cli/control/confirmationIssueConsumeController.js +43 -0
- package/dist/orchestrator/src/cli/control/confirmationListController.js +22 -0
- package/dist/orchestrator/src/cli/control/confirmationValidateController.js +58 -0
- package/dist/orchestrator/src/cli/control/confirmations.js +25 -3
- package/dist/orchestrator/src/cli/control/controlActionCancelConfirmation.js +65 -0
- package/dist/orchestrator/src/cli/control/controlActionController.js +77 -0
- package/dist/orchestrator/src/cli/control/controlActionControllerSequencing.js +161 -0
- package/dist/orchestrator/src/cli/control/controlActionExecution.js +142 -0
- package/dist/orchestrator/src/cli/control/controlActionFinalization.js +43 -0
- package/dist/orchestrator/src/cli/control/controlActionOutcome.js +60 -0
- package/dist/orchestrator/src/cli/control/controlActionPreflight.js +476 -0
- package/dist/orchestrator/src/cli/control/controlAuthenticatedRouteHandoff.js +57 -0
- package/dist/orchestrator/src/cli/control/controlBootstrapAssembly.js +39 -0
- package/dist/orchestrator/src/cli/control/controlBootstrapMetadataPersistence.js +16 -0
- package/dist/orchestrator/src/cli/control/controlEventTransport.js +49 -0
- package/dist/orchestrator/src/cli/control/controlExpiryLifecycle.js +102 -0
- package/dist/orchestrator/src/cli/control/controlHostOwnership.js +480 -0
- package/dist/orchestrator/src/cli/control/controlHostSupervision.js +630 -0
- package/dist/orchestrator/src/cli/control/controlOversightFacade.js +8 -0
- package/dist/orchestrator/src/cli/control/controlOversightReadContract.js +1 -0
- package/dist/orchestrator/src/cli/control/controlOversightReadService.js +16 -0
- package/dist/orchestrator/src/cli/control/controlOversightUpdateContract.js +1 -0
- package/dist/orchestrator/src/cli/control/controlPersistenceFiles.js +6 -0
- package/dist/orchestrator/src/cli/control/controlQuestionChildResolution.js +18 -0
- package/dist/orchestrator/src/cli/control/controlRequestContext.js +42 -0
- package/dist/orchestrator/src/cli/control/controlRequestController.js +9 -0
- package/dist/orchestrator/src/cli/control/controlRequestPredispatch.js +17 -0
- package/dist/orchestrator/src/cli/control/controlRequestRouteDispatch.js +44 -0
- package/dist/orchestrator/src/cli/control/controlRuntime.js +1003 -0
- package/dist/orchestrator/src/cli/control/controlServer.js +23 -1456
- package/dist/orchestrator/src/cli/control/controlServerAuditAndErrorHelpers.js +115 -0
- package/dist/orchestrator/src/cli/control/controlServerAuthenticatedRouteBranch.js +29 -0
- package/dist/orchestrator/src/cli/control/controlServerBootstrapLifecycle.js +30 -0
- package/dist/orchestrator/src/cli/control/controlServerBootstrapStartSequence.js +21 -0
- package/dist/orchestrator/src/cli/control/controlServerOwnedRuntimeLifecycle.js +67 -0
- package/dist/orchestrator/src/cli/control/controlServerPublicLifecycle.js +756 -0
- package/dist/orchestrator/src/cli/control/controlServerPublicRouteHelpers.js +86 -0
- package/dist/orchestrator/src/cli/control/controlServerReadyInstanceLifecycle.js +25 -0
- package/dist/orchestrator/src/cli/control/controlServerReadyInstanceStartup.js +18 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestBodyHelpers.js +37 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestShell.js +40 -0
- package/dist/orchestrator/src/cli/control/controlServerRequestShellBinding.js +17 -0
- package/dist/orchestrator/src/cli/control/controlServerSeedLoading.js +27 -0
- package/dist/orchestrator/src/cli/control/controlServerSeededRuntimeAssembly.js +186 -0
- package/dist/orchestrator/src/cli/control/controlServerStartupInputPreparation.js +31 -0
- package/dist/orchestrator/src/cli/control/controlServerStartupSequence.js +49 -0
- package/dist/orchestrator/src/cli/control/controlState.js +233 -2
- package/dist/orchestrator/src/cli/control/controlStatusDashboard.js +1904 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeBootstrapLifecycle.js +22 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeLifecycle.js +67 -0
- package/dist/orchestrator/src/cli/control/controlTelegramBridgeOversightFacadeFactory.js +8 -0
- package/dist/orchestrator/src/cli/control/controlTelegramCommandController.js +49 -0
- package/dist/orchestrator/src/cli/control/controlTelegramDispatchRead.js +40 -0
- package/dist/orchestrator/src/cli/control/controlTelegramPollingController.js +89 -0
- package/dist/orchestrator/src/cli/control/controlTelegramProjectionNotificationController.js +29 -0
- package/dist/orchestrator/src/cli/control/controlTelegramPushState.js +63 -0
- package/dist/orchestrator/src/cli/control/controlTelegramQuestionRead.js +13 -0
- package/dist/orchestrator/src/cli/control/controlTelegramReadController.js +216 -0
- package/dist/orchestrator/src/cli/control/controlTelegramUpdateHandler.js +63 -0
- package/dist/orchestrator/src/cli/control/controlWatcher.js +73 -5
- package/dist/orchestrator/src/cli/control/delegationRegisterController.js +35 -0
- package/dist/orchestrator/src/cli/control/dynamicToolBridgePolicy.js +139 -0
- package/dist/orchestrator/src/cli/control/eventsSseController.js +12 -0
- package/dist/orchestrator/src/cli/control/linearBudgetState.js +1789 -0
- package/dist/orchestrator/src/cli/control/linearDispatchSource.js +1137 -0
- package/dist/orchestrator/src/cli/control/linearGraphqlClient.js +150 -0
- package/dist/orchestrator/src/cli/control/linearRateLimit.js +102 -0
- package/dist/orchestrator/src/cli/control/linearWebhookController.js +499 -0
- package/dist/orchestrator/src/cli/control/liveLinearAdvisoryRuntime.js +70 -0
- package/dist/orchestrator/src/cli/control/observabilityApiController.js +173 -0
- package/dist/orchestrator/src/cli/control/observabilityReadModel.js +500 -0
- package/dist/orchestrator/src/cli/control/observabilitySurface.js +284 -0
- package/dist/orchestrator/src/cli/control/observabilityUpdateNotifier.js +22 -0
- package/dist/orchestrator/src/cli/control/operatorDashboardPresenter.js +252 -0
- package/dist/orchestrator/src/cli/control/providerAgentCapacity.js +70 -0
- package/dist/orchestrator/src/cli/control/providerControlHostFreshnessGauge.js +1068 -0
- package/dist/orchestrator/src/cli/control/providerIntakeState.js +473 -0
- package/dist/orchestrator/src/cli/control/providerIssueHandoff.js +6811 -0
- package/dist/orchestrator/src/cli/control/providerIssueObservability.js +1348 -0
- package/dist/orchestrator/src/cli/control/providerIssueRetryQueue.js +84 -0
- package/dist/orchestrator/src/cli/control/providerLinearRuntimeProof.js +588 -0
- package/dist/orchestrator/src/cli/control/providerLinearScreenshotProof.js +473 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkerTruth.js +383 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowAudit.js +254 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowFacade.js +5573 -0
- package/dist/orchestrator/src/cli/control/providerLinearWorkflowStates.js +115 -0
- package/dist/orchestrator/src/cli/control/providerMergeCloseout.js +1868 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilot.js +1580 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLifecycle.js +154 -0
- package/dist/orchestrator/src/cli/control/providerOperatorAutopilotLocalRolloutExecution.js +1006 -0
- package/dist/orchestrator/src/cli/control/providerPollingHealth.js +435 -0
- package/dist/orchestrator/src/cli/control/providerTerminalCleanup.js +516 -0
- package/dist/orchestrator/src/cli/control/providerWorkerHosts.js +191 -0
- package/dist/orchestrator/src/cli/control/providerWorkflowConfigStore.js +515 -0
- package/dist/orchestrator/src/cli/control/questionChildResolutionAdapter.js +361 -0
- package/dist/orchestrator/src/cli/control/questionQueueController.js +181 -0
- package/dist/orchestrator/src/cli/control/questionReadRetryDeduplication.js +9 -0
- package/dist/orchestrator/src/cli/control/questionReadSequence.js +10 -0
- package/dist/orchestrator/src/cli/control/securityViolationController.js +27 -0
- package/dist/orchestrator/src/cli/control/selectedRunProjection.js +1885 -0
- package/dist/orchestrator/src/cli/control/telegramOversightApiClient.js +48 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridge.js +180 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeProjectionDeliveryQueue.js +25 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeRuntimeLifecycle.js +45 -0
- package/dist/orchestrator/src/cli/control/telegramOversightBridgeStateStore.js +77 -0
- package/dist/orchestrator/src/cli/control/telegramOversightControlActionApiClient.js +45 -0
- package/dist/orchestrator/src/cli/control/trackerDispatchPilot.js +439 -0
- package/dist/orchestrator/src/cli/control/uiDataController.js +34 -0
- package/dist/orchestrator/src/cli/control/uiSessionController.js +100 -0
- package/dist/orchestrator/src/cli/controlHostCliShell.js +860 -0
- package/dist/orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js +129 -0
- package/dist/orchestrator/src/cli/controlHostSupervisionCliShell.js +2127 -0
- package/dist/orchestrator/src/cli/delegationCliShell.js +62 -0
- package/dist/orchestrator/src/cli/delegationServer.js +567 -678
- package/dist/orchestrator/src/cli/delegationServerCliShell.js +52 -0
- package/dist/orchestrator/src/cli/delegationServerQuestionFlowShell.js +228 -0
- package/dist/orchestrator/src/cli/delegationServerToolDispatchShell.js +411 -0
- package/dist/orchestrator/src/cli/delegationServerTransport.js +274 -0
- package/dist/orchestrator/src/cli/delegationSetup.js +51 -171
- package/dist/orchestrator/src/cli/devtoolsCliShell.js +34 -0
- package/dist/orchestrator/src/cli/doctor.js +678 -164
- package/dist/orchestrator/src/cli/doctorCliRequestShell.js +72 -0
- package/dist/orchestrator/src/cli/doctorCliShell.js +138 -0
- package/dist/orchestrator/src/cli/doctorUsage.js +119 -15
- package/dist/orchestrator/src/cli/exec/experience.js +16 -2
- package/dist/orchestrator/src/cli/exec/summary.js +3 -0
- package/dist/orchestrator/src/cli/execCliShell.js +51 -0
- package/dist/orchestrator/src/cli/flowCliRequestShell.js +44 -0
- package/dist/orchestrator/src/cli/flowCliShell.js +239 -0
- package/dist/orchestrator/src/cli/frontendTestCliRequestShell.js +80 -0
- package/dist/orchestrator/src/cli/frontendTestCliShell.js +41 -0
- package/dist/orchestrator/src/cli/init.js +95 -1
- package/dist/orchestrator/src/cli/initCliShell.js +50 -0
- package/dist/orchestrator/src/cli/linearCliShell.js +1200 -0
- package/dist/orchestrator/src/cli/mcpEnableCliShell.js +132 -0
- package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +3 -2
- package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +56 -0
- package/dist/orchestrator/src/cli/orchestrator.js +66 -1376
- package/dist/orchestrator/src/cli/planCliShell.js +19 -0
- package/dist/orchestrator/src/cli/prCliShell.js +41 -0
- package/dist/orchestrator/src/cli/providerLinearChildLanePhaseContract.js +204 -0
- package/dist/orchestrator/src/cli/providerLinearChildLaneRunner.js +1835 -0
- package/dist/orchestrator/src/cli/providerLinearChildLaneShell.js +2420 -0
- package/dist/orchestrator/src/cli/providerLinearChildStreamShell.js +385 -0
- package/dist/orchestrator/src/cli/providerLinearWorkerRunner.js +6834 -0
- package/dist/orchestrator/src/cli/resumeCliShell.js +14 -0
- package/dist/orchestrator/src/cli/reviewCliLaunchShell.js +72 -0
- package/dist/orchestrator/src/cli/rlm/alignment.js +3 -3
- package/dist/orchestrator/src/cli/rlm/context.js +94 -7
- package/dist/orchestrator/src/cli/rlm/rlmCodexRuntimeShell.js +546 -0
- package/dist/orchestrator/src/cli/rlm/symbolic.js +4 -2
- package/dist/orchestrator/src/cli/rlmCliRequestShell.js +42 -0
- package/dist/orchestrator/src/cli/rlmCompletionCliShell.js +46 -0
- package/dist/orchestrator/src/cli/rlmLaunchCliShell.js +51 -0
- package/dist/orchestrator/src/cli/rlmRunner.js +83 -523
- package/dist/orchestrator/src/cli/run/blockMemory.js +500 -0
- package/dist/orchestrator/src/cli/run/manifest.js +410 -73
- package/dist/orchestrator/src/cli/run/manifestPersister.js +45 -14
- package/dist/orchestrator/src/cli/run/runMemoryController.js +216 -0
- package/dist/orchestrator/src/cli/run/source0.js +690 -0
- package/dist/orchestrator/src/cli/run/workspacePath.js +101 -0
- package/dist/orchestrator/src/cli/runtime/mode.js +2 -1
- package/dist/orchestrator/src/cli/runtime/provider.js +39 -2
- package/dist/orchestrator/src/cli/selfCheckCliShell.js +12 -0
- package/dist/orchestrator/src/cli/services/commandRunner.js +698 -18
- package/dist/orchestrator/src/cli/services/execRuntime.js +66 -1
- package/dist/orchestrator/src/cli/services/orchestratorAutoScoutEvidenceRecorder.js +71 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudBranchResolution.js +8 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudEnvironmentResolution.js +22 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudExecutionLifecycleShell.js +39 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudPromptBuilder.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudRouteFallbackContract.js +45 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudRouteShell.js +36 -0
- package/dist/orchestrator/src/cli/services/orchestratorCloudTargetExecutor.js +277 -0
- package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycle.js +98 -0
- package/dist/orchestrator/src/cli/services/orchestratorControlPlaneLifecycleShell.js +54 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionLifecycle.js +112 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionModePolicy.js +27 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteAdapterShell.js +59 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteDecisionShell.js +57 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouteState.js +21 -0
- package/dist/orchestrator/src/cli/services/orchestratorExecutionRouter.js +2 -0
- package/dist/orchestrator/src/cli/services/orchestratorLocalPipelineExecutor.js +149 -0
- package/dist/orchestrator/src/cli/services/orchestratorLocalRouteShell.js +63 -0
- package/dist/orchestrator/src/cli/services/orchestratorPlanShell.js +54 -0
- package/dist/orchestrator/src/cli/services/orchestratorPlanTargetTracker.js +16 -0
- package/dist/orchestrator/src/cli/services/orchestratorResumePreparationShell.js +84 -0
- package/dist/orchestrator/src/cli/services/orchestratorResumeTokenValidation.js +15 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleCompletion.js +31 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleExecutionRegistration.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleOrchestrationShell.js +83 -0
- package/dist/orchestrator/src/cli/services/orchestratorRunLifecycleTaskManagerShell.js +37 -0
- package/dist/orchestrator/src/cli/services/orchestratorRuntimeManifestMutation.js +20 -0
- package/dist/orchestrator/src/cli/services/orchestratorStartPreparationShell.js +56 -0
- package/dist/orchestrator/src/cli/services/orchestratorStatusShell.js +70 -0
- package/dist/orchestrator/src/cli/services/pipelineResolver.js +7 -3
- package/dist/orchestrator/src/cli/services/plannerMemory.js +119 -0
- package/dist/orchestrator/src/cli/services/runPreparation.js +7 -3
- package/dist/orchestrator/src/cli/services/runSummaryWriter.js +9 -0
- package/dist/orchestrator/src/cli/setupBootstrapShell.js +114 -0
- package/dist/orchestrator/src/cli/setupCliShell.js +51 -0
- package/dist/orchestrator/src/cli/skillsCliShell.js +56 -0
- package/dist/orchestrator/src/cli/startCliRequestShell.js +53 -0
- package/dist/orchestrator/src/cli/startCliShell.js +68 -0
- package/dist/orchestrator/src/cli/statusCliShell.js +22 -0
- package/dist/orchestrator/src/cli/utils/authProvenanceFingerprint.js +27 -0
- package/dist/orchestrator/src/cli/utils/cloudPreflight.js +285 -7
- package/dist/orchestrator/src/cli/utils/codexFeatures.js +60 -0
- package/dist/orchestrator/src/cli/utils/delegationConfigParser.js +250 -0
- package/dist/orchestrator/src/cli/utils/delegationMcpHealth.js +1382 -0
- package/dist/orchestrator/src/cli/utils/devtools.js +2 -54
- package/dist/orchestrator/src/cli/utils/mcpServerEntry.js +53 -0
- package/dist/orchestrator/src/cli/utils/packageProgramResolver.js +151 -0
- package/dist/orchestrator/src/cli/utils/providerOverrideEnv.js +71 -0
- package/dist/orchestrator/src/cli/utils/trailingJsonObject.js +59 -0
- package/dist/orchestrator/src/learning/crystalizer.js +2 -2
- package/dist/orchestrator/src/manager.js +74 -4
- package/dist/orchestrator/src/persistence/ExperienceStore.js +233 -49
- package/dist/orchestrator/src/persistence/TaskStateStore.js +6 -6
- package/dist/orchestrator/src/persistence/lockFile.js +70 -4
- package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +39 -0
- package/dist/orchestrator/src/sync/createCloudSyncWorker.js +3 -2
- package/dist/orchestrator/src/utils/atomicWrite.js +17 -2
- package/dist/packages/orchestrator/src/exec/unified-exec.js +99 -6
- package/dist/packages/orchestrator/src/instructions/promptPacks.js +150 -19
- package/dist/packages/sdk-node/src/orchestrator.js +137 -13
- package/dist/packages/shared/config/designConfig.js +8 -1
- package/dist/packages/shared/streams/stdio.js +1 -1
- package/dist/scripts/design/pipeline/permit.js +15 -0
- package/dist/scripts/lib/docs-catalog.js +399 -0
- package/dist/scripts/lib/docs-helpers.js +87 -5
- package/dist/scripts/lib/pr-watch-merge.js +1088 -80
- package/dist/scripts/lib/provider-run-contract.js +26 -0
- package/dist/scripts/lib/review-command-intent-classification.js +532 -0
- package/dist/scripts/lib/review-command-probe-classification.js +385 -0
- package/dist/scripts/lib/review-execution-boundary-preflight.js +279 -0
- package/dist/scripts/lib/review-execution-runtime.js +753 -0
- package/dist/scripts/lib/review-execution-state.js +1144 -0
- package/dist/scripts/lib/review-execution-telemetry.js +215 -0
- package/dist/scripts/lib/review-inspection-target-parsing.js +78 -0
- package/dist/scripts/lib/review-launch-attempt.js +601 -0
- package/dist/scripts/lib/review-meta-surface-boundary-analysis.js +300 -0
- package/dist/scripts/lib/review-meta-surface-normalization.js +746 -0
- package/dist/scripts/lib/review-non-interactive-handoff.js +61 -0
- package/dist/scripts/lib/review-prompt-context.js +376 -0
- package/dist/scripts/lib/review-scope-advisory.js +286 -0
- package/dist/scripts/lib/review-scope-paths.js +123 -0
- package/dist/scripts/lib/review-shell-command-parser.js +389 -0
- package/dist/scripts/lib/review-shell-env-interpreter.js +340 -0
- package/dist/scripts/lib/run-manifests.js +192 -36
- package/dist/scripts/lib/spark-policy-classifier.js +593 -0
- package/dist/scripts/run-review.js +507 -1777
- package/docs/README.md +43 -20
- package/docs/book/README.md +19 -0
- package/docs/book/codex-cli-0124-adoption.md +68 -0
- package/docs/book/local-hook-impact.md +73 -0
- package/docs/book/operations.md +60 -0
- package/docs/book/public-posture.md +34 -0
- package/docs/book/setup.md +91 -0
- package/docs/book/skills.md +11 -0
- package/docs/guides/codex-version-policy.md +104 -0
- package/docs/public/downstream-setup.md +113 -0
- package/docs/public/provider-onboarding.md +173 -0
- package/package.json +23 -10
- package/plugins/codex-orchestrator/.codex-plugin/plugin.json +30 -0
- package/plugins/codex-orchestrator/.mcp.json +13 -0
- package/plugins/codex-orchestrator/launcher.mjs +361 -0
- package/schemas/manifest.json +411 -0
- package/skills/README.md +26 -0
- package/skills/collab-subagents-first/SKILL.md +1 -1
- package/skills/delegation-usage/DELEGATION_GUIDE.md +30 -12
- package/skills/delegation-usage/SKILL.md +25 -14
- package/skills/land/SKILL.md +77 -0
- package/skills/linear/SKILL.md +255 -0
- package/skills/release/SKILL.md +47 -3
- package/skills/standalone-review/SKILL.md +6 -1
- package/templates/README.md +4 -2
- package/templates/codex/.codex/agents/awaiter-high.toml +2 -2
- package/templates/codex/.codex/agents/worker-complex.toml +1 -1
- package/templates/codex/.codex/config.toml +3 -4
- package/templates/codex/.codex/providers/README.md +13 -0
- package/templates/codex/.codex/providers/control.example.json +18 -0
- package/templates/codex/.codex/providers/provider.env.example +15 -0
- package/templates/codex/AGENTS.md +15 -8
- package/templates/codex/mcp-client.json +5 -1
- package/docs/assets/setup.gif +0 -0
|
@@ -1,50 +1,86 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { basename, join } from 'node:path';
|
|
2
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { opendir } from 'node:fs/promises';
|
|
4
|
+
import { basename, join, resolve } from 'node:path';
|
|
6
5
|
import process from 'node:process';
|
|
7
|
-
import {
|
|
6
|
+
import { pathToFileURL } from 'node:url';
|
|
8
7
|
import { CodexOrchestrator } from '../orchestrator/src/cli/orchestrator.js';
|
|
9
|
-
import {
|
|
10
|
-
import { executeExecCommand } from '../orchestrator/src/cli/exec/command.js';
|
|
8
|
+
import { runExecCliShell } from '../orchestrator/src/cli/execCliShell.js';
|
|
11
9
|
import { resolveEnvironmentPaths } from '../scripts/lib/run-manifests.js';
|
|
12
|
-
import {
|
|
13
|
-
import { normalizeEnvironmentPaths, sanitizeTaskId } from '../orchestrator/src/cli/run/environment.js';
|
|
10
|
+
import { sanitizeTaskId } from '../orchestrator/src/cli/run/environment.js';
|
|
14
11
|
import { RunEventEmitter } from '../orchestrator/src/cli/events/runEvents.js';
|
|
15
12
|
import { evaluateInteractiveGate } from '../orchestrator/src/cli/utils/interactive.js';
|
|
16
13
|
import { buildSelfCheckResult } from '../orchestrator/src/cli/selfCheck.js';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { formatDoctorUsageSummary, runDoctorUsage } from '../orchestrator/src/cli/doctorUsage.js';
|
|
14
|
+
import { runDoctor } from '../orchestrator/src/cli/doctor.js';
|
|
15
|
+
import { runDoctorUsage } from '../orchestrator/src/cli/doctorUsage.js';
|
|
20
16
|
import { formatDoctorIssueLogSummary, writeDoctorIssueLog } from '../orchestrator/src/cli/doctorIssueLog.js';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
17
|
+
import { runInitCliShell } from '../orchestrator/src/cli/initCliShell.js';
|
|
18
|
+
import { runCodexCliShell } from '../orchestrator/src/cli/codexCliShell.js';
|
|
19
|
+
import { runDevtoolsCliShell } from '../orchestrator/src/cli/devtoolsCliShell.js';
|
|
20
|
+
import { runDelegationCliShell } from '../orchestrator/src/cli/delegationCliShell.js';
|
|
21
|
+
import { runLinearCliShell } from '../orchestrator/src/cli/linearCliShell.js';
|
|
22
|
+
import { runSkillsCliShell } from '../orchestrator/src/cli/skillsCliShell.js';
|
|
23
|
+
import { runFlowCliRequestShell } from '../orchestrator/src/cli/flowCliRequestShell.js';
|
|
24
|
+
import { runStartCliRequestShell } from '../orchestrator/src/cli/startCliRequestShell.js';
|
|
25
|
+
import { runFrontendTestCliRequestShell } from '../orchestrator/src/cli/frontendTestCliRequestShell.js';
|
|
26
|
+
import { runPlanCliShell } from '../orchestrator/src/cli/planCliShell.js';
|
|
27
|
+
import { runDoctorCliRequestShell } from '../orchestrator/src/cli/doctorCliRequestShell.js';
|
|
28
|
+
import { runRlmCliRequestShell } from '../orchestrator/src/cli/rlmCliRequestShell.js';
|
|
29
|
+
import { runRlmCompletionCliShell } from '../orchestrator/src/cli/rlmCompletionCliShell.js';
|
|
30
|
+
import { runResumeCliShell } from '../orchestrator/src/cli/resumeCliShell.js';
|
|
31
|
+
import { runStatusCliShell } from '../orchestrator/src/cli/statusCliShell.js';
|
|
32
|
+
import { runSelfCheckCliShell } from '../orchestrator/src/cli/selfCheckCliShell.js';
|
|
33
|
+
import { printSetupCliHelp, runSetupCliShell } from '../orchestrator/src/cli/setupCliShell.js';
|
|
34
|
+
import { runReviewCliLaunchShell } from '../orchestrator/src/cli/reviewCliLaunchShell.js';
|
|
35
|
+
import { loadPackageInfo } from '../orchestrator/src/cli/utils/packageInfo.js';
|
|
27
36
|
import { slugify } from '../orchestrator/src/cli/utils/strings.js';
|
|
28
37
|
import { serveMcp } from '../orchestrator/src/cli/mcp.js';
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
38
|
+
import { runMcpEnableCliShell } from '../orchestrator/src/cli/mcpEnableCliShell.js';
|
|
39
|
+
import { runDelegationServerCliShell } from '../orchestrator/src/cli/delegationServerCliShell.js';
|
|
40
|
+
import { DEFAULT_PROVIDER_START_PIPELINE_ID, runControlHostCliShell } from '../orchestrator/src/cli/controlHostCliShell.js';
|
|
41
|
+
import { runControlHostFreshnessGaugeCliShell } from '../orchestrator/src/cli/controlHostFreshnessGaugeCliShell.js';
|
|
42
|
+
import { runControlHostSupervisionCliShell } from '../orchestrator/src/cli/controlHostSupervisionCliShell.js';
|
|
43
|
+
import { runCoStatusAttachCliShell } from '../orchestrator/src/cli/coStatusAttachCliShell.js';
|
|
44
|
+
import { runCoStatusCliShell } from '../orchestrator/src/cli/coStatusCliShell.js';
|
|
45
|
+
import { runCoStatusOperatorAutopilotCliShell } from '../orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js';
|
|
33
46
|
import { REPO_CONFIG_REQUIRED_ENV_KEY } from '../orchestrator/src/cli/config/repoConfigPolicy.js';
|
|
34
47
|
const AUTO_ISSUE_LOG_ENV_KEY = 'CODEX_ORCHESTRATOR_AUTO_ISSUE_LOG';
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
function writeStderrLine(message) {
|
|
49
|
+
process.stderr.write(`${message}\n`);
|
|
50
|
+
}
|
|
51
|
+
export function isDirectExecution(entryArg = process.argv[1], metaUrl = import.meta.url) {
|
|
52
|
+
if (typeof entryArg !== 'string' || entryArg.length === 0) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const candidateUrls = new Set();
|
|
56
|
+
try {
|
|
57
|
+
candidateUrls.add(pathToFileURL(resolve(entryArg)).href);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Fall through to the realpath check so missing/cwd issues still fail closed.
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
candidateUrls.add(pathToFileURL(realpathSync(entryArg)).href);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Missing or unreadable entry points should not be treated as direct execution.
|
|
67
|
+
}
|
|
68
|
+
return candidateUrls.has(metaUrl);
|
|
69
|
+
}
|
|
70
|
+
export async function runCodexOrchestratorCli(rawArgs = process.argv.slice(2)) {
|
|
71
|
+
process.exitCode = 0;
|
|
72
|
+
const args = [...rawArgs];
|
|
37
73
|
const command = args.shift();
|
|
38
74
|
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
39
75
|
printHelp();
|
|
40
|
-
return;
|
|
76
|
+
return 0;
|
|
41
77
|
}
|
|
42
78
|
if (command === '--version' || command === '-v') {
|
|
43
79
|
printVersion();
|
|
44
|
-
return;
|
|
80
|
+
return 0;
|
|
45
81
|
}
|
|
46
|
-
const orchestrator = new CodexOrchestrator();
|
|
47
82
|
try {
|
|
83
|
+
const orchestrator = new CodexOrchestrator();
|
|
48
84
|
switch (command) {
|
|
49
85
|
case 'start':
|
|
50
86
|
await handleStart(orchestrator, args);
|
|
@@ -70,6 +106,12 @@ async function main() {
|
|
|
70
106
|
case 'status':
|
|
71
107
|
await handleStatus(orchestrator, args);
|
|
72
108
|
break;
|
|
109
|
+
case 'control-host':
|
|
110
|
+
await handleControlHost(args);
|
|
111
|
+
break;
|
|
112
|
+
case 'co-status':
|
|
113
|
+
await handleCoStatus(args);
|
|
114
|
+
break;
|
|
73
115
|
case 'exec':
|
|
74
116
|
await handleExec(args);
|
|
75
117
|
break;
|
|
@@ -88,6 +130,9 @@ async function main() {
|
|
|
88
130
|
case 'codex':
|
|
89
131
|
await handleCodex(args);
|
|
90
132
|
break;
|
|
133
|
+
case 'linear':
|
|
134
|
+
await handleLinear(args);
|
|
135
|
+
break;
|
|
91
136
|
case 'devtools':
|
|
92
137
|
await handleDevtools(args);
|
|
93
138
|
break;
|
|
@@ -111,15 +156,16 @@ async function main() {
|
|
|
111
156
|
printVersion();
|
|
112
157
|
break;
|
|
113
158
|
default:
|
|
114
|
-
|
|
159
|
+
writeStderrLine(`Unknown command: ${command}`);
|
|
115
160
|
printHelp();
|
|
116
161
|
process.exitCode = 1;
|
|
117
162
|
}
|
|
118
163
|
}
|
|
119
164
|
catch (error) {
|
|
120
|
-
|
|
165
|
+
writeStderrLine(error?.message ?? String(error));
|
|
121
166
|
process.exitCode = 1;
|
|
122
167
|
}
|
|
168
|
+
return typeof process.exitCode === 'number' ? process.exitCode : 0;
|
|
123
169
|
}
|
|
124
170
|
function parseArgs(raw) {
|
|
125
171
|
const positionals = [];
|
|
@@ -128,6 +174,7 @@ function parseArgs(raw) {
|
|
|
128
174
|
const booleanFlagKeys = new Set([
|
|
129
175
|
'apply',
|
|
130
176
|
'auto-issue-log',
|
|
177
|
+
'blocked-by-source',
|
|
131
178
|
'cloud',
|
|
132
179
|
'cloud-preflight',
|
|
133
180
|
'codex-cli',
|
|
@@ -206,132 +253,6 @@ function resolveTargetStageId(flags) {
|
|
|
206
253
|
}
|
|
207
254
|
return undefined;
|
|
208
255
|
}
|
|
209
|
-
const FLOW_TARGET_PIPELINE_SCOPES = new Set(['docs-review', 'implementation-gate']);
|
|
210
|
-
function isFlowTargetPipelineScope(scope) {
|
|
211
|
-
return FLOW_TARGET_PIPELINE_SCOPES.has(scope);
|
|
212
|
-
}
|
|
213
|
-
function normalizeFlowTargetToken(candidate) {
|
|
214
|
-
const trimmed = candidate.trim();
|
|
215
|
-
if (!trimmed) {
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
const tokens = trimmed.split(':');
|
|
219
|
-
if (tokens.length > 1 && !(tokens[0] ?? '').trim()) {
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
let scoped = false;
|
|
223
|
-
let scopeToken = null;
|
|
224
|
-
let suffixToken = trimmed;
|
|
225
|
-
if (tokens.length > 1) {
|
|
226
|
-
const candidateScope = (tokens[0] ?? '').trim().toLowerCase();
|
|
227
|
-
if (isFlowTargetPipelineScope(candidateScope)) {
|
|
228
|
-
scoped = true;
|
|
229
|
-
scopeToken = candidateScope;
|
|
230
|
-
suffixToken = (tokens[tokens.length - 1] ?? '').trim();
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (!suffixToken) {
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
literal: trimmed,
|
|
238
|
-
literalLower: trimmed.toLowerCase(),
|
|
239
|
-
stageTokenLower: suffixToken.toLowerCase(),
|
|
240
|
-
scopeLower: scopeToken,
|
|
241
|
-
scoped
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function flowPlanItemPipelineId(item) {
|
|
245
|
-
const metadataPipelineId = item.metadata && typeof item.metadata['pipelineId'] === 'string'
|
|
246
|
-
? item.metadata['pipelineId'].trim().toLowerCase()
|
|
247
|
-
: '';
|
|
248
|
-
if (metadataPipelineId) {
|
|
249
|
-
return metadataPipelineId;
|
|
250
|
-
}
|
|
251
|
-
const delimiterIndex = item.id.indexOf(':');
|
|
252
|
-
if (delimiterIndex <= 0) {
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
return item.id.slice(0, delimiterIndex).trim().toLowerCase() || null;
|
|
256
|
-
}
|
|
257
|
-
function flowPlanItemMatchesTarget(item, candidate) {
|
|
258
|
-
const normalized = normalizeFlowTargetToken(candidate);
|
|
259
|
-
if (!normalized) {
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
if (item.id.toLowerCase() === normalized.literalLower) {
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
if (normalized.scoped && normalized.scopeLower) {
|
|
266
|
-
const itemPipelineId = flowPlanItemPipelineId(item);
|
|
267
|
-
if (itemPipelineId && itemPipelineId !== normalized.scopeLower) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
const metadataStageId = item.metadata && typeof item.metadata['stageId'] === 'string'
|
|
272
|
-
? item.metadata['stageId'].toLowerCase()
|
|
273
|
-
: null;
|
|
274
|
-
const aliases = Array.isArray(item.metadata?.['aliases'])
|
|
275
|
-
? item.metadata?.['aliases']
|
|
276
|
-
: [];
|
|
277
|
-
const aliasTokens = aliases.filter((alias) => typeof alias === 'string')
|
|
278
|
-
.map((alias) => alias.toLowerCase());
|
|
279
|
-
if (normalized.scoped) {
|
|
280
|
-
if (metadataStageId
|
|
281
|
-
&& (metadataStageId === normalized.literalLower || metadataStageId === normalized.stageTokenLower)) {
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
return aliasTokens.some((alias) => alias === normalized.literalLower || alias === normalized.stageTokenLower);
|
|
285
|
-
}
|
|
286
|
-
if (item.id.toLowerCase().endsWith(`:${normalized.stageTokenLower}`)) {
|
|
287
|
-
return true;
|
|
288
|
-
}
|
|
289
|
-
if (metadataStageId
|
|
290
|
-
&& (metadataStageId === normalized.stageTokenLower
|
|
291
|
-
|| metadataStageId.endsWith(`:${normalized.stageTokenLower}`))) {
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
return aliasTokens.some((alias) => alias === normalized.stageTokenLower || alias.endsWith(`:${normalized.stageTokenLower}`));
|
|
295
|
-
}
|
|
296
|
-
function planIncludesStageId(plan, stageId) {
|
|
297
|
-
if (!stageId.trim()) {
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
return plan.plan.items.some((item) => flowPlanItemMatchesTarget(item, stageId));
|
|
301
|
-
}
|
|
302
|
-
function resolveFlowTargetScope(stageId) {
|
|
303
|
-
const delimiterIndex = stageId.indexOf(':');
|
|
304
|
-
if (delimiterIndex <= 0) {
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
|
-
const scope = stageId.slice(0, delimiterIndex).trim().toLowerCase();
|
|
308
|
-
if (!isFlowTargetPipelineScope(scope)) {
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
return scope;
|
|
312
|
-
}
|
|
313
|
-
async function resolveFlowTargetStageSelection(orchestrator, taskId, requestedTargetStageId) {
|
|
314
|
-
if (!requestedTargetStageId) {
|
|
315
|
-
return {};
|
|
316
|
-
}
|
|
317
|
-
const [docsPlan, implementationPlan] = (await Promise.all([
|
|
318
|
-
orchestrator.plan({ pipelineId: 'docs-review', taskId }),
|
|
319
|
-
orchestrator.plan({ pipelineId: 'implementation-gate', taskId })
|
|
320
|
-
]));
|
|
321
|
-
const requestedScope = resolveFlowTargetScope(requestedTargetStageId);
|
|
322
|
-
const docsScopeMatch = !requestedScope || requestedScope === 'docs-review';
|
|
323
|
-
const implementationScopeMatch = !requestedScope || requestedScope === 'implementation-gate';
|
|
324
|
-
const docsReviewTargetStageId = docsScopeMatch && planIncludesStageId(docsPlan, requestedTargetStageId)
|
|
325
|
-
? requestedTargetStageId
|
|
326
|
-
: undefined;
|
|
327
|
-
const implementationGateTargetStageId = implementationScopeMatch && planIncludesStageId(implementationPlan, requestedTargetStageId)
|
|
328
|
-
? requestedTargetStageId
|
|
329
|
-
: undefined;
|
|
330
|
-
if (!docsReviewTargetStageId && !implementationGateTargetStageId) {
|
|
331
|
-
throw new Error(`Target stage "${requestedTargetStageId}" is not defined in docs-review or implementation-gate.`);
|
|
332
|
-
}
|
|
333
|
-
return { docsReviewTargetStageId, implementationGateTargetStageId };
|
|
334
|
-
}
|
|
335
256
|
function readStringFlag(flags, key) {
|
|
336
257
|
const value = flags[key];
|
|
337
258
|
if (typeof value !== 'string') {
|
|
@@ -515,30 +436,6 @@ function resolveRlmTaskId(taskFlag) {
|
|
|
515
436
|
const slug = slugify(repoName, 'adhoc');
|
|
516
437
|
return sanitizeTaskId(`rlm-${slug}`);
|
|
517
438
|
}
|
|
518
|
-
async function waitForManifestCompletion(manifestPath, intervalMs = 2000) {
|
|
519
|
-
const terminal = new Set(['succeeded', 'failed', 'cancelled']);
|
|
520
|
-
while (true) {
|
|
521
|
-
const raw = await readFile(manifestPath, 'utf8');
|
|
522
|
-
const manifest = JSON.parse(raw);
|
|
523
|
-
if (terminal.has(manifest.status)) {
|
|
524
|
-
return manifest;
|
|
525
|
-
}
|
|
526
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
async function readRlmState(statePath) {
|
|
530
|
-
try {
|
|
531
|
-
const raw = await readFile(statePath, 'utf8');
|
|
532
|
-
const parsed = JSON.parse(raw);
|
|
533
|
-
if (!parsed?.final) {
|
|
534
|
-
return null;
|
|
535
|
-
}
|
|
536
|
-
return { exitCode: parsed.final.exitCode, status: parsed.final.status };
|
|
537
|
-
}
|
|
538
|
-
catch {
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
439
|
async function maybeCaptureAutoIssueLog(params) {
|
|
543
440
|
if (!params.enabled) {
|
|
544
441
|
return { issueLog: null, issueLogError: null };
|
|
@@ -594,110 +491,52 @@ async function handleStart(orchestrator, rawArgs) {
|
|
|
594
491
|
printStartHelp();
|
|
595
492
|
return;
|
|
596
493
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
494
|
+
await runStartCliRequestShell({
|
|
495
|
+
orchestrator,
|
|
496
|
+
positionals,
|
|
497
|
+
flags,
|
|
498
|
+
runWithUi: async (format, action) => await withRunUi(flags, format, action),
|
|
499
|
+
emitRunOutput,
|
|
500
|
+
maybeCaptureAutoIssueLog,
|
|
501
|
+
resolveTaskFilter,
|
|
502
|
+
withAutoIssueLogContext,
|
|
503
|
+
maybeEmitRunAdoptionHint,
|
|
504
|
+
resolveExecutionModeFlag,
|
|
505
|
+
resolveRuntimeModeFlag,
|
|
506
|
+
applyRepoConfigRequiredPolicy,
|
|
507
|
+
resolveAutoIssueLogEnabled,
|
|
508
|
+
resolveTargetStageId,
|
|
509
|
+
readStringFlag,
|
|
510
|
+
shouldWarnLegacyMultiAgentEnv: (requestFlags) => shouldWarnLegacyMultiAgentEnv(requestFlags, process.env),
|
|
511
|
+
applyRlmEnvOverrides,
|
|
512
|
+
resolveRlmTaskId,
|
|
513
|
+
setTaskEnvironment: (taskId) => {
|
|
514
|
+
process.env.MCP_RUNNER_TASK_ID = taskId;
|
|
515
|
+
},
|
|
516
|
+
log: (line) => console.log(line),
|
|
517
|
+
warn: (line) => console.warn(line),
|
|
518
|
+
setExitCode: (code) => {
|
|
519
|
+
process.exitCode = code;
|
|
609
520
|
}
|
|
610
|
-
}
|
|
611
|
-
let taskIdOverride = typeof flags['task'] === 'string' ? flags['task'] : undefined;
|
|
612
|
-
try {
|
|
613
|
-
await withRunUi(flags, format, async (runEvents) => {
|
|
614
|
-
if (pipelineId === 'rlm') {
|
|
615
|
-
taskIdOverride = resolveRlmTaskId(taskIdOverride);
|
|
616
|
-
process.env.MCP_RUNNER_TASK_ID = taskIdOverride;
|
|
617
|
-
if (format !== 'json') {
|
|
618
|
-
console.log(`Task: ${taskIdOverride}`);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
const result = await orchestrator.start({
|
|
622
|
-
pipelineId,
|
|
623
|
-
taskId: taskIdOverride,
|
|
624
|
-
parentRunId: typeof flags['parent-run'] === 'string' ? flags['parent-run'] : undefined,
|
|
625
|
-
approvalPolicy: typeof flags['approval-policy'] === 'string' ? flags['approval-policy'] : undefined,
|
|
626
|
-
targetStageId: resolveTargetStageId(flags),
|
|
627
|
-
executionMode,
|
|
628
|
-
runtimeMode,
|
|
629
|
-
runEvents
|
|
630
|
-
});
|
|
631
|
-
const issueLogCapture = result.manifest.status !== 'succeeded'
|
|
632
|
-
? await maybeCaptureAutoIssueLog({
|
|
633
|
-
enabled: autoIssueLogEnabled,
|
|
634
|
-
issueTitle: `Auto issue log: start ${pipelineId ?? 'diagnostics'} failed`,
|
|
635
|
-
issueNotes: `Automatic failure capture for run ${result.manifest.run_id} (${result.manifest.status}).`,
|
|
636
|
-
taskFilter: resolveTaskFilter(result.manifest.task_id, taskIdOverride)
|
|
637
|
-
})
|
|
638
|
-
: { issueLog: null, issueLogError: null };
|
|
639
|
-
emitRunOutput(result, format, 'Run started', issueLogCapture);
|
|
640
|
-
if (result.manifest.status === 'failed' || result.manifest.status === 'cancelled') {
|
|
641
|
-
process.exitCode = 1;
|
|
642
|
-
}
|
|
643
|
-
if (result.manifest.status === 'succeeded' && result.manifest.pipeline_id !== 'rlm') {
|
|
644
|
-
await maybeEmitRunAdoptionHint({
|
|
645
|
-
format,
|
|
646
|
-
taskFilter: resolveTaskFilter(result.manifest.task_id, taskIdOverride)
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
catch (error) {
|
|
652
|
-
const issueLogCapture = await maybeCaptureAutoIssueLog({
|
|
653
|
-
enabled: autoIssueLogEnabled,
|
|
654
|
-
issueTitle: `Auto issue log: start ${pipelineId ?? 'diagnostics'} failed before run manifest`,
|
|
655
|
-
issueNotes: 'Automatic failure capture for start setup failure before run manifest creation.',
|
|
656
|
-
taskFilter: resolveTaskFilter(undefined, taskIdOverride)
|
|
657
|
-
});
|
|
658
|
-
throw withAutoIssueLogContext(error, issueLogCapture);
|
|
659
|
-
}
|
|
521
|
+
});
|
|
660
522
|
}
|
|
661
523
|
async function handleFrontendTest(orchestrator, rawArgs) {
|
|
662
524
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
applyRepoConfigRequiredPolicy(flags);
|
|
667
|
-
if (positionals.length > 0) {
|
|
668
|
-
console.error(`[frontend-test] ignoring extra arguments: ${positionals.join(' ')}`);
|
|
669
|
-
}
|
|
670
|
-
const originalDevtools = process.env.CODEX_REVIEW_DEVTOOLS;
|
|
671
|
-
if (devtools) {
|
|
672
|
-
process.env.CODEX_REVIEW_DEVTOOLS = '1';
|
|
673
|
-
}
|
|
674
|
-
try {
|
|
675
|
-
await withRunUi(flags, format, async (runEvents) => {
|
|
676
|
-
const result = await orchestrator.start({
|
|
677
|
-
pipelineId: 'frontend-testing',
|
|
678
|
-
taskId: typeof flags['task'] === 'string' ? flags['task'] : undefined,
|
|
679
|
-
parentRunId: typeof flags['parent-run'] === 'string' ? flags['parent-run'] : undefined,
|
|
680
|
-
approvalPolicy: typeof flags['approval-policy'] === 'string' ? flags['approval-policy'] : undefined,
|
|
681
|
-
targetStageId: resolveTargetStageId(flags),
|
|
682
|
-
runtimeMode,
|
|
683
|
-
runEvents
|
|
684
|
-
});
|
|
685
|
-
emitRunOutput(result, format, 'Run started');
|
|
686
|
-
if (result.manifest.status === 'failed' || result.manifest.status === 'cancelled') {
|
|
687
|
-
process.exitCode = 1;
|
|
688
|
-
}
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
finally {
|
|
692
|
-
if (devtools) {
|
|
693
|
-
if (originalDevtools === undefined) {
|
|
694
|
-
delete process.env.CODEX_REVIEW_DEVTOOLS;
|
|
695
|
-
}
|
|
696
|
-
else {
|
|
697
|
-
process.env.CODEX_REVIEW_DEVTOOLS = originalDevtools;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
525
|
+
if (isHelpRequest(positionals, flags)) {
|
|
526
|
+
printFrontendTestHelp();
|
|
527
|
+
return;
|
|
700
528
|
}
|
|
529
|
+
await runFrontendTestCliRequestShell({
|
|
530
|
+
orchestrator,
|
|
531
|
+
positionals,
|
|
532
|
+
flags,
|
|
533
|
+
resolveRuntimeModeFlag,
|
|
534
|
+
applyRepoConfigRequiredPolicy,
|
|
535
|
+
resolveTargetStageId,
|
|
536
|
+
runWithUi: async (format, action) => await withRunUi(flags, format, action),
|
|
537
|
+
emitRunOutput,
|
|
538
|
+
warn: (line) => console.error(line)
|
|
539
|
+
});
|
|
701
540
|
}
|
|
702
541
|
async function handleFlow(orchestrator, rawArgs) {
|
|
703
542
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
@@ -705,174 +544,23 @@ async function handleFlow(orchestrator, rawArgs) {
|
|
|
705
544
|
printFlowHelp();
|
|
706
545
|
return;
|
|
707
546
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
taskId,
|
|
726
|
-
parentRunId,
|
|
727
|
-
approvalPolicy,
|
|
728
|
-
targetStageId: docsReviewTargetStageId,
|
|
729
|
-
executionMode,
|
|
730
|
-
runtimeMode,
|
|
731
|
-
runEvents
|
|
732
|
-
});
|
|
733
|
-
const docsPayload = toRunOutputPayload(docsReviewResult);
|
|
734
|
-
if (format === 'text') {
|
|
735
|
-
emitRunOutput(docsReviewResult, format, 'Docs-review run');
|
|
736
|
-
}
|
|
737
|
-
if (docsReviewResult.manifest.status !== 'succeeded') {
|
|
738
|
-
const issueLogCapture = await maybeCaptureAutoIssueLog({
|
|
739
|
-
enabled: autoIssueLogEnabled,
|
|
740
|
-
issueTitle: 'Auto issue log: flow docs-review failed',
|
|
741
|
-
issueNotes: `Automatic failure capture for docs-review run ${docsReviewResult.manifest.run_id} (${docsReviewResult.manifest.status}).`,
|
|
742
|
-
taskFilter: resolveTaskFilter(docsReviewResult.manifest.task_id, taskId)
|
|
743
|
-
});
|
|
744
|
-
process.exitCode = 1;
|
|
745
|
-
if (format === 'json') {
|
|
746
|
-
const payload = {
|
|
747
|
-
status: docsReviewResult.manifest.status,
|
|
748
|
-
failed_stage: 'docs-review',
|
|
749
|
-
docs_review: docsPayload,
|
|
750
|
-
implementation_gate: null,
|
|
751
|
-
issue_log: issueLogCapture.issueLog,
|
|
752
|
-
issue_log_error: issueLogCapture.issueLogError
|
|
753
|
-
};
|
|
754
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
755
|
-
}
|
|
756
|
-
else {
|
|
757
|
-
console.log('Flow halted: docs-review failed.');
|
|
758
|
-
if (issueLogCapture.issueLog) {
|
|
759
|
-
for (const line of formatDoctorIssueLogSummary(issueLogCapture.issueLog)) {
|
|
760
|
-
console.log(line);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
if (issueLogCapture.issueLogError) {
|
|
764
|
-
console.log(`Auto issue log: failed (${issueLogCapture.issueLogError})`);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
const implementationGateResult = await orchestrator.start({
|
|
770
|
-
pipelineId: 'implementation-gate',
|
|
771
|
-
taskId,
|
|
772
|
-
parentRunId: docsReviewResult.manifest.run_id,
|
|
773
|
-
approvalPolicy,
|
|
774
|
-
targetStageId: implementationGateTargetStageId,
|
|
775
|
-
executionMode,
|
|
776
|
-
runtimeMode,
|
|
777
|
-
runEvents
|
|
778
|
-
});
|
|
779
|
-
const implementationPayload = toRunOutputPayload(implementationGateResult);
|
|
780
|
-
const issueLogCapture = implementationGateResult.manifest.status !== 'succeeded'
|
|
781
|
-
? await maybeCaptureAutoIssueLog({
|
|
782
|
-
enabled: autoIssueLogEnabled,
|
|
783
|
-
issueTitle: 'Auto issue log: flow implementation-gate failed',
|
|
784
|
-
issueNotes: `Automatic failure capture for implementation-gate run ${implementationGateResult.manifest.run_id} (${implementationGateResult.manifest.status}).`,
|
|
785
|
-
taskFilter: resolveTaskFilter(implementationGateResult.manifest.task_id, taskId)
|
|
786
|
-
})
|
|
787
|
-
: { issueLog: null, issueLogError: null };
|
|
788
|
-
if (format === 'json') {
|
|
789
|
-
const payload = {
|
|
790
|
-
status: implementationGateResult.manifest.status,
|
|
791
|
-
failed_stage: implementationGateResult.manifest.status === 'succeeded' ? null : 'implementation-gate',
|
|
792
|
-
docs_review: docsPayload,
|
|
793
|
-
implementation_gate: implementationPayload,
|
|
794
|
-
issue_log: issueLogCapture.issueLog,
|
|
795
|
-
issue_log_error: issueLogCapture.issueLogError
|
|
796
|
-
};
|
|
797
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
798
|
-
if (implementationGateResult.manifest.status !== 'succeeded') {
|
|
799
|
-
process.exitCode = 1;
|
|
800
|
-
}
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
emitRunOutput(implementationGateResult, format, 'Implementation-gate run');
|
|
804
|
-
if (implementationGateResult.manifest.status !== 'succeeded') {
|
|
805
|
-
process.exitCode = 1;
|
|
806
|
-
console.log('Flow halted: implementation-gate failed.');
|
|
807
|
-
if (issueLogCapture.issueLog) {
|
|
808
|
-
for (const line of formatDoctorIssueLogSummary(issueLogCapture.issueLog)) {
|
|
809
|
-
console.log(line);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
if (issueLogCapture.issueLogError) {
|
|
813
|
-
console.log(`Auto issue log: failed (${issueLogCapture.issueLogError})`);
|
|
814
|
-
}
|
|
815
|
-
return;
|
|
816
|
-
}
|
|
817
|
-
console.log('Flow complete: docs-review -> implementation-gate.');
|
|
818
|
-
await maybeEmitRunAdoptionHint({
|
|
819
|
-
format,
|
|
820
|
-
taskFilter: resolveTaskFilter(implementationGateResult.manifest.task_id, taskId)
|
|
821
|
-
});
|
|
822
|
-
});
|
|
823
|
-
}
|
|
824
|
-
catch (error) {
|
|
825
|
-
const issueLogCapture = await maybeCaptureAutoIssueLog({
|
|
826
|
-
enabled: autoIssueLogEnabled,
|
|
827
|
-
issueTitle: 'Auto issue log: flow failed before run manifest',
|
|
828
|
-
issueNotes: 'Automatic failure capture for flow setup failure before run manifest creation.',
|
|
829
|
-
taskFilter: resolveTaskFilter(undefined, taskId)
|
|
830
|
-
});
|
|
831
|
-
throw withAutoIssueLogContext(error, issueLogCapture);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
function runningFromSourceRuntime() {
|
|
835
|
-
return fileURLToPath(import.meta.url).endsWith('.ts');
|
|
836
|
-
}
|
|
837
|
-
function resolveReviewRunner() {
|
|
838
|
-
const packageRoot = findPackageRoot(import.meta.url);
|
|
839
|
-
const sourceRunner = join(packageRoot, 'scripts', 'run-review.ts');
|
|
840
|
-
const distRunner = join(packageRoot, 'dist', 'scripts', 'run-review.js');
|
|
841
|
-
if (runningFromSourceRuntime() && existsSync(sourceRunner)) {
|
|
842
|
-
return {
|
|
843
|
-
command: process.execPath,
|
|
844
|
-
args: ['--loader', 'ts-node/esm', sourceRunner]
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
if (existsSync(distRunner)) {
|
|
848
|
-
return {
|
|
849
|
-
command: process.execPath,
|
|
850
|
-
args: [distRunner]
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
if (existsSync(sourceRunner)) {
|
|
854
|
-
return {
|
|
855
|
-
command: process.execPath,
|
|
856
|
-
args: ['--loader', 'ts-node/esm', sourceRunner]
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
throw new Error('Unable to locate review runner. Expected dist/scripts/run-review.js (npm) or scripts/run-review.ts (source checkout).');
|
|
860
|
-
}
|
|
861
|
-
async function runPassthroughCommand(command, args, options = {}) {
|
|
862
|
-
return await new Promise((resolve, reject) => {
|
|
863
|
-
const child = spawn(command, args, {
|
|
864
|
-
env: options.env ?? process.env,
|
|
865
|
-
cwd: options.cwd ?? process.cwd(),
|
|
866
|
-
stdio: 'inherit'
|
|
867
|
-
});
|
|
868
|
-
child.once('error', (error) => reject(error instanceof Error ? error : new Error(String(error))));
|
|
869
|
-
child.once('close', (code, signal) => {
|
|
870
|
-
if (signal) {
|
|
871
|
-
resolve(1);
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
resolve(typeof code === 'number' ? code : 1);
|
|
875
|
-
});
|
|
547
|
+
await runFlowCliRequestShell({
|
|
548
|
+
orchestrator,
|
|
549
|
+
positionals,
|
|
550
|
+
flags,
|
|
551
|
+
runWithUi: async (format, action) => await withRunUi(flags, format, action),
|
|
552
|
+
emitRunOutput,
|
|
553
|
+
formatIssueLogSummary: formatDoctorIssueLogSummary,
|
|
554
|
+
toRunOutputPayload,
|
|
555
|
+
maybeCaptureAutoIssueLog,
|
|
556
|
+
resolveTaskFilter,
|
|
557
|
+
withAutoIssueLogContext,
|
|
558
|
+
maybeEmitRunAdoptionHint,
|
|
559
|
+
resolveExecutionModeFlag,
|
|
560
|
+
resolveRuntimeModeFlag,
|
|
561
|
+
applyRepoConfigRequiredPolicy,
|
|
562
|
+
resolveAutoIssueLogEnabled,
|
|
563
|
+
resolveTargetStageId
|
|
876
564
|
});
|
|
877
565
|
}
|
|
878
566
|
async function handleReview(rawArgs) {
|
|
@@ -881,11 +569,7 @@ async function handleReview(rawArgs) {
|
|
|
881
569
|
printReviewHelp();
|
|
882
570
|
return;
|
|
883
571
|
}
|
|
884
|
-
const
|
|
885
|
-
const exitCode = await runPassthroughCommand(runner.command, [...runner.args, ...rawArgs], {
|
|
886
|
-
cwd: process.cwd(),
|
|
887
|
-
env: process.env
|
|
888
|
-
});
|
|
572
|
+
const exitCode = await runReviewCliLaunchShell({ rawArgs });
|
|
889
573
|
if (exitCode !== 0) {
|
|
890
574
|
process.exitCode = exitCode;
|
|
891
575
|
}
|
|
@@ -899,16 +583,13 @@ async function handlePlan(orchestrator, rawArgs) {
|
|
|
899
583
|
applyRepoConfigRequiredPolicy(flags);
|
|
900
584
|
const pipelineId = positionals[0];
|
|
901
585
|
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
902
|
-
|
|
586
|
+
await runPlanCliShell({
|
|
587
|
+
orchestrator,
|
|
903
588
|
pipelineId,
|
|
904
589
|
taskId: typeof flags['task'] === 'string' ? flags['task'] : undefined,
|
|
905
|
-
targetStageId: resolveTargetStageId(flags)
|
|
590
|
+
targetStageId: resolveTargetStageId(flags),
|
|
591
|
+
format
|
|
906
592
|
});
|
|
907
|
-
if (format === 'json') {
|
|
908
|
-
console.log(JSON.stringify(result, null, 2));
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
process.stdout.write(`${formatPlanPreview(result)}\n`);
|
|
912
593
|
}
|
|
913
594
|
async function handleRlm(orchestrator, rawArgs) {
|
|
914
595
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
@@ -916,64 +597,36 @@ async function handleRlm(orchestrator, rawArgs) {
|
|
|
916
597
|
printRlmHelp();
|
|
917
598
|
return;
|
|
918
599
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
let startResult = null;
|
|
949
|
-
await withRunUi(flags, 'text', async (runEvents) => {
|
|
950
|
-
startResult = await orchestrator.start({
|
|
951
|
-
pipelineId: 'rlm',
|
|
952
|
-
taskId,
|
|
953
|
-
parentRunId: typeof flags['parent-run'] === 'string' ? flags['parent-run'] : undefined,
|
|
954
|
-
approvalPolicy: typeof flags['approval-policy'] === 'string' ? flags['approval-policy'] : undefined,
|
|
955
|
-
runtimeMode,
|
|
956
|
-
runEvents
|
|
957
|
-
});
|
|
958
|
-
emitRunOutput(startResult, 'text', 'Run started');
|
|
600
|
+
await runRlmCliRequestShell({
|
|
601
|
+
orchestrator,
|
|
602
|
+
positionals,
|
|
603
|
+
flags,
|
|
604
|
+
env: process.env,
|
|
605
|
+
runWithUi: async (action) => await withRunUi(flags, 'text', action),
|
|
606
|
+
emitRunOutput,
|
|
607
|
+
resolveRuntimeModeFlag,
|
|
608
|
+
applyRepoConfigRequiredPolicy,
|
|
609
|
+
readStringFlag,
|
|
610
|
+
applyRlmEnvOverrides,
|
|
611
|
+
shouldWarnLegacyEnvAlias: shouldWarnLegacyMultiAgentEnv,
|
|
612
|
+
resolveRlmTaskId,
|
|
613
|
+
setTaskEnvironment: (taskId) => {
|
|
614
|
+
process.env.MCP_RUNNER_TASK_ID = taskId;
|
|
615
|
+
},
|
|
616
|
+
runDoctor,
|
|
617
|
+
resolveRepoRoot: () => resolveEnvironmentPaths().repoRoot,
|
|
618
|
+
runCompletionShell: async ({ repoRoot, artifactRoot }) => await runRlmCompletionCliShell({
|
|
619
|
+
repoRoot,
|
|
620
|
+
artifactRoot,
|
|
621
|
+
log: (line) => console.log(line),
|
|
622
|
+
error: (line) => console.error(line),
|
|
623
|
+
setExitCode: (code) => {
|
|
624
|
+
process.exitCode = code;
|
|
625
|
+
}
|
|
626
|
+
}),
|
|
627
|
+
log: (line) => console.log(line),
|
|
628
|
+
warn: (line) => console.warn(line)
|
|
959
629
|
});
|
|
960
|
-
if (!startResult) {
|
|
961
|
-
throw new Error('rlm run failed to start.');
|
|
962
|
-
}
|
|
963
|
-
const resolvedStart = startResult;
|
|
964
|
-
const { repoRoot } = resolveEnvironmentPaths();
|
|
965
|
-
const manifestPath = join(repoRoot, resolvedStart.manifest.artifact_root, 'manifest.json');
|
|
966
|
-
const manifest = await waitForManifestCompletion(manifestPath);
|
|
967
|
-
const statePath = join(repoRoot, resolvedStart.manifest.artifact_root, 'rlm', 'state.json');
|
|
968
|
-
const rlmState = await readRlmState(statePath);
|
|
969
|
-
if (rlmState) {
|
|
970
|
-
console.log(`RLM status: ${rlmState.status}`);
|
|
971
|
-
process.exitCode = rlmState.exitCode;
|
|
972
|
-
return;
|
|
973
|
-
}
|
|
974
|
-
console.log(`RLM status: ${manifest.status}`);
|
|
975
|
-
console.error('RLM state file missing; treating as internal error.');
|
|
976
|
-
process.exitCode = 10;
|
|
977
630
|
}
|
|
978
631
|
async function handleResume(orchestrator, rawArgs) {
|
|
979
632
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
@@ -988,17 +641,17 @@ async function handleResume(orchestrator, rawArgs) {
|
|
|
988
641
|
throw new Error('resume requires --run <run-id>.');
|
|
989
642
|
}
|
|
990
643
|
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
991
|
-
await
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
emitRunOutput
|
|
644
|
+
await runResumeCliShell({
|
|
645
|
+
orchestrator,
|
|
646
|
+
runId,
|
|
647
|
+
format,
|
|
648
|
+
runtimeMode,
|
|
649
|
+
resumeToken: typeof flags['token'] === 'string' ? flags['token'] : undefined,
|
|
650
|
+
actor: typeof flags['actor'] === 'string' ? flags['actor'] : undefined,
|
|
651
|
+
reason: typeof flags['reason'] === 'string' ? flags['reason'] : undefined,
|
|
652
|
+
targetStageId: resolveTargetStageId(flags),
|
|
653
|
+
runWithUi: async (action) => await withRunUi(flags, format, action),
|
|
654
|
+
emitRunOutput
|
|
1002
655
|
});
|
|
1003
656
|
}
|
|
1004
657
|
async function handleStatus(orchestrator, rawArgs) {
|
|
@@ -1014,18 +667,84 @@ async function handleStatus(orchestrator, rawArgs) {
|
|
|
1014
667
|
const watch = Boolean(flags['watch']);
|
|
1015
668
|
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1016
669
|
const interval = parseInt(flags['interval'] ?? '10', 10);
|
|
1017
|
-
|
|
1018
|
-
|
|
670
|
+
await runStatusCliShell({ orchestrator, runId, watch, format, interval });
|
|
671
|
+
}
|
|
672
|
+
async function handleControlHost(rawArgs) {
|
|
673
|
+
if (rawArgs[0] === 'freshness-gauge') {
|
|
674
|
+
const { positionals, flags } = parseArgs(rawArgs.slice(1));
|
|
675
|
+
if (isHelpRequest(positionals, flags)) {
|
|
676
|
+
printControlHostFreshnessGaugeHelp();
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (positionals.length > 0) {
|
|
680
|
+
throw new Error(`Unknown control-host freshness-gauge argument(s): ${positionals.join(' ')}`);
|
|
681
|
+
}
|
|
682
|
+
await runControlHostFreshnessGaugeCliShell({
|
|
683
|
+
flags,
|
|
684
|
+
printHelp: printControlHostFreshnessGaugeHelp
|
|
685
|
+
});
|
|
1019
686
|
return;
|
|
1020
687
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
688
|
+
if (rawArgs[0] === 'supervise') {
|
|
689
|
+
const { positionals, flags } = parseArgs(rawArgs.slice(1));
|
|
690
|
+
await runControlHostSupervisionCliShell({
|
|
691
|
+
positionals,
|
|
692
|
+
flags,
|
|
693
|
+
printHelp: printControlHostSupervisionHelp
|
|
694
|
+
});
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const { positionals, flags } = parseArgs(rawArgs);
|
|
698
|
+
if (isHelpRequest(positionals, flags)) {
|
|
699
|
+
printControlHostHelp();
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
if (positionals.length > 0) {
|
|
703
|
+
throw new Error(`Unknown control-host argument(s): ${positionals.join(' ')}`);
|
|
704
|
+
}
|
|
705
|
+
await runControlHostCliShell({
|
|
706
|
+
flags,
|
|
707
|
+
printHelp: printControlHostHelp
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
async function handleCoStatus(rawArgs) {
|
|
711
|
+
if (rawArgs[0] === 'operator-autopilot') {
|
|
712
|
+
const { positionals, flags } = parseArgs(rawArgs.slice(1));
|
|
713
|
+
if (isHelpRequest(positionals, flags)) {
|
|
714
|
+
printCoStatusOperatorAutopilotHelp();
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
await runCoStatusOperatorAutopilotCliShell({
|
|
718
|
+
positionals,
|
|
719
|
+
flags,
|
|
720
|
+
printHelp: printCoStatusOperatorAutopilotHelp
|
|
721
|
+
});
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
if (rawArgs[0] === 'attach') {
|
|
725
|
+
const { positionals, flags } = parseArgs(rawArgs.slice(1));
|
|
726
|
+
if (isHelpRequest(positionals, flags)) {
|
|
727
|
+
printCoStatusAttachHelp();
|
|
728
|
+
return;
|
|
1026
729
|
}
|
|
1027
|
-
|
|
730
|
+
if (positionals.length > 0) {
|
|
731
|
+
throw new Error(`Unknown co-status attach argument(s): ${positionals.join(' ')}`);
|
|
732
|
+
}
|
|
733
|
+
await runCoStatusAttachCliShell({
|
|
734
|
+
flags,
|
|
735
|
+
printHelp: printCoStatusAttachHelp
|
|
736
|
+
});
|
|
737
|
+
return;
|
|
1028
738
|
}
|
|
739
|
+
const { positionals, flags } = parseArgs(rawArgs);
|
|
740
|
+
if (isHelpRequest(positionals, flags)) {
|
|
741
|
+
printCoStatusHelp();
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
await runCoStatusCliShell({
|
|
745
|
+
flags,
|
|
746
|
+
printHelp: printCoStatusHelp
|
|
747
|
+
});
|
|
1029
748
|
}
|
|
1030
749
|
async function maybeStartHud(gate, emitter) {
|
|
1031
750
|
if (!gate.enabled) {
|
|
@@ -1111,40 +830,9 @@ function toRunOutputPayload(result, issueLogCapture = { issueLog: null, issueLog
|
|
|
1111
830
|
};
|
|
1112
831
|
}
|
|
1113
832
|
async function handleExec(rawArgs) {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1118
|
-
const isInteractive = process.stdout.isTTY === true && process.stderr.isTTY === true;
|
|
1119
|
-
const outputMode = parsed.requestedMode ?? (isInteractive ? 'interactive' : 'jsonl');
|
|
1120
|
-
const env = normalizeEnvironmentPaths(resolveEnvironmentPaths());
|
|
1121
|
-
if (parsed.taskId) {
|
|
1122
|
-
env.taskId = sanitizeTaskId(parsed.taskId);
|
|
1123
|
-
}
|
|
1124
|
-
const context = {
|
|
1125
|
-
env,
|
|
1126
|
-
stdout: process.stdout,
|
|
1127
|
-
stderr: process.stderr
|
|
1128
|
-
};
|
|
1129
|
-
const invocation = {
|
|
1130
|
-
command: parsed.commandTokens[0],
|
|
1131
|
-
args: parsed.commandTokens.slice(1),
|
|
1132
|
-
cwd: parsed.cwd,
|
|
1133
|
-
outputMode,
|
|
1134
|
-
notifyTargets: parsed.notifyTargets,
|
|
1135
|
-
otelEndpoint: parsed.otelEndpoint,
|
|
1136
|
-
jsonPretty: parsed.jsonPretty
|
|
1137
|
-
};
|
|
1138
|
-
const result = await executeExecCommand(context, invocation);
|
|
1139
|
-
if (result.exitCode !== null) {
|
|
1140
|
-
process.exitCode = result.exitCode;
|
|
1141
|
-
}
|
|
1142
|
-
else if (result.status !== 'succeeded') {
|
|
1143
|
-
process.exitCode = 1;
|
|
1144
|
-
}
|
|
1145
|
-
if (outputMode === 'interactive') {
|
|
1146
|
-
await maybeEmitExecAdoptionHint(env.taskId);
|
|
1147
|
-
}
|
|
833
|
+
await runExecCliShell(parseExecArgs(rawArgs), {
|
|
834
|
+
maybeEmitAdoptionHint: maybeEmitExecAdoptionHint
|
|
835
|
+
});
|
|
1148
836
|
}
|
|
1149
837
|
async function shouldScanAdoptionHint(taskFilter) {
|
|
1150
838
|
if (!taskFilter) {
|
|
@@ -1204,16 +892,11 @@ async function maybeEmitExecAdoptionHint(taskFilter) {
|
|
|
1204
892
|
async function handleSelfCheck(rawArgs) {
|
|
1205
893
|
const { flags } = parseArgs(rawArgs);
|
|
1206
894
|
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}
|
|
1212
|
-
console.log(`Status: ${result.status}`);
|
|
1213
|
-
console.log(`Name: ${result.name}`);
|
|
1214
|
-
console.log(`Version: ${result.version}`);
|
|
1215
|
-
console.log(`Node: ${result.node}`);
|
|
1216
|
-
console.log(`Timestamp: ${result.timestamp}`);
|
|
895
|
+
await runSelfCheckCliShell({
|
|
896
|
+
format,
|
|
897
|
+
buildResult: buildSelfCheckResult,
|
|
898
|
+
log: (line) => console.log(line)
|
|
899
|
+
});
|
|
1217
900
|
}
|
|
1218
901
|
async function handleInit(rawArgs) {
|
|
1219
902
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
@@ -1221,439 +904,46 @@ async function handleInit(rawArgs) {
|
|
|
1221
904
|
printInitHelp();
|
|
1222
905
|
return;
|
|
1223
906
|
}
|
|
1224
|
-
|
|
1225
|
-
if (!template) {
|
|
1226
|
-
throw new Error('init requires a template name (e.g. init codex).');
|
|
1227
|
-
}
|
|
1228
|
-
if (template !== 'codex') {
|
|
1229
|
-
throw new Error(`Unknown init template: ${template}`);
|
|
1230
|
-
}
|
|
1231
|
-
const cwd = typeof flags['cwd'] === 'string' ? flags['cwd'] : process.cwd();
|
|
1232
|
-
const force = Boolean(flags['force']);
|
|
1233
|
-
const result = await initCodexTemplates({ template, cwd, force });
|
|
1234
|
-
const summary = formatInitSummary(result, cwd);
|
|
1235
|
-
for (const line of summary) {
|
|
1236
|
-
console.log(line);
|
|
1237
|
-
}
|
|
1238
|
-
if (flags['codex-cli'] === true) {
|
|
1239
|
-
const apply = Boolean(flags['yes']);
|
|
1240
|
-
const source = readStringFlag(flags, 'codex-source');
|
|
1241
|
-
const ref = readStringFlag(flags, 'codex-ref');
|
|
1242
|
-
const downloadUrl = readStringFlag(flags, 'codex-download-url');
|
|
1243
|
-
const downloadSha256 = readStringFlag(flags, 'codex-download-sha256');
|
|
1244
|
-
const cliForce = Boolean(flags['codex-force']);
|
|
1245
|
-
const setupResult = await runCodexCliSetup({
|
|
1246
|
-
apply,
|
|
1247
|
-
force: cliForce,
|
|
1248
|
-
source,
|
|
1249
|
-
ref,
|
|
1250
|
-
downloadUrl,
|
|
1251
|
-
downloadSha256
|
|
1252
|
-
});
|
|
1253
|
-
for (const line of formatCodexCliSetupSummary(setupResult)) {
|
|
1254
|
-
console.log(line);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
907
|
+
await runInitCliShell({ positionals, flags });
|
|
1257
908
|
}
|
|
1258
909
|
async function handleSetup(rawArgs) {
|
|
1259
910
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1260
911
|
if (isHelpRequest(positionals, flags)) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
One-shot bootstrap for downstream users. Installs bundled skills and configures
|
|
1264
|
-
delegation + DevTools MCP wiring.
|
|
1265
|
-
|
|
1266
|
-
Options:
|
|
1267
|
-
--yes Apply setup (otherwise plan only).
|
|
1268
|
-
--refresh-skills Overwrite bundled skills in $CODEX_HOME/skills during setup.
|
|
1269
|
-
--repo <path> Repo root for delegation wiring (default cwd).
|
|
1270
|
-
--format json Emit machine-readable output (dry-run only).
|
|
1271
|
-
`);
|
|
912
|
+
printSetupCliHelp();
|
|
1272
913
|
return;
|
|
1273
914
|
}
|
|
1274
|
-
|
|
1275
|
-
const apply = Boolean(flags['yes']);
|
|
1276
|
-
const refreshSkills = Boolean(flags['refresh-skills']);
|
|
1277
|
-
if (format === 'json' && apply) {
|
|
1278
|
-
throw new Error('setup does not support --format json with --yes.');
|
|
1279
|
-
}
|
|
1280
|
-
const repoFlag = readStringFlag(flags, 'repo');
|
|
1281
|
-
const repoRoot = repoFlag ?? process.cwd();
|
|
1282
|
-
const delegationCommandPreview = repoFlag
|
|
1283
|
-
? buildCommandPreview('codex-orchestrator', ['delegation', 'setup', '--yes', '--repo', repoFlag])
|
|
1284
|
-
: 'codex-orchestrator delegation setup --yes';
|
|
1285
|
-
const bundledSkills = await listBundledSkills();
|
|
1286
|
-
if (bundledSkills.length === 0) {
|
|
1287
|
-
throw new Error('No bundled skills detected; cannot run setup.');
|
|
1288
|
-
}
|
|
1289
|
-
const guidance = buildSetupGuidance();
|
|
1290
|
-
if (!apply) {
|
|
1291
|
-
const installCommand = `codex-orchestrator skills install ${refreshSkills ? '--force ' : ''}--only ${bundledSkills.join(',')}`;
|
|
1292
|
-
const skillsNote = refreshSkills
|
|
1293
|
-
? 'Installs bundled skills into $CODEX_HOME/skills with overwrite enabled via --refresh-skills.'
|
|
1294
|
-
: 'Installs bundled skills into $CODEX_HOME/skills without overwriting existing files by default. Add --refresh-skills to force overwrite.';
|
|
1295
|
-
const delegation = await runDelegationSetup({ repoRoot });
|
|
1296
|
-
const devtools = await runDevtoolsSetup();
|
|
1297
|
-
const payload = {
|
|
1298
|
-
status: 'planned',
|
|
1299
|
-
steps: {
|
|
1300
|
-
skills: {
|
|
1301
|
-
commandLines: [installCommand],
|
|
1302
|
-
note: skillsNote
|
|
1303
|
-
},
|
|
1304
|
-
delegation,
|
|
1305
|
-
devtools,
|
|
1306
|
-
guidance
|
|
1307
|
-
}
|
|
1308
|
-
};
|
|
1309
|
-
if (format === 'json') {
|
|
1310
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
1311
|
-
return;
|
|
1312
|
-
}
|
|
1313
|
-
console.log('Setup plan:');
|
|
1314
|
-
console.log('- Skills:');
|
|
1315
|
-
for (const commandLine of payload.steps.skills.commandLines) {
|
|
1316
|
-
console.log(` - ${commandLine}`);
|
|
1317
|
-
}
|
|
1318
|
-
console.log(`- Delegation: ${delegationCommandPreview}`);
|
|
1319
|
-
console.log('- DevTools: codex-orchestrator devtools setup --yes');
|
|
1320
|
-
for (const line of formatSetupGuidanceSummary(guidance)) {
|
|
1321
|
-
console.log(line);
|
|
1322
|
-
}
|
|
1323
|
-
console.log('Run with --yes to apply this setup.');
|
|
1324
|
-
return;
|
|
1325
|
-
}
|
|
1326
|
-
const skills = await installSkills({ force: refreshSkills, only: bundledSkills });
|
|
1327
|
-
const delegation = await runDelegationSetup({ apply: true, repoRoot });
|
|
1328
|
-
const devtools = await runDevtoolsSetup({ apply: true });
|
|
1329
|
-
for (const line of formatSkillsInstallSummary(skills)) {
|
|
1330
|
-
console.log(line);
|
|
1331
|
-
}
|
|
1332
|
-
for (const line of formatDelegationSetupSummary(delegation)) {
|
|
1333
|
-
console.log(line);
|
|
1334
|
-
}
|
|
1335
|
-
for (const line of formatDevtoolsSetupSummary(devtools)) {
|
|
1336
|
-
console.log(line);
|
|
1337
|
-
}
|
|
1338
|
-
for (const line of formatSetupGuidanceSummary(guidance)) {
|
|
1339
|
-
console.log(line);
|
|
1340
|
-
}
|
|
1341
|
-
console.log('Next: codex-orchestrator doctor --usage');
|
|
1342
|
-
}
|
|
1343
|
-
function buildSetupGuidance() {
|
|
1344
|
-
return {
|
|
1345
|
-
note: 'Agent-first default: run docs-review before implementation and implementation-gate before handoff.',
|
|
1346
|
-
references: [
|
|
1347
|
-
'https://github.com/Kbediako/CO#downstream-usage-cheatsheet-agent-first',
|
|
1348
|
-
'https://github.com/Kbediako/CO/blob/main/docs/AGENTS.md',
|
|
1349
|
-
'https://github.com/Kbediako/CO/blob/main/docs/guides/collab-vs-mcp.md',
|
|
1350
|
-
'https://github.com/Kbediako/CO/blob/main/docs/guides/rlm-recursion-v2.md'
|
|
1351
|
-
],
|
|
1352
|
-
recommended_commands: [
|
|
1353
|
-
'codex-orchestrator flow --task <task-id>',
|
|
1354
|
-
'codex-orchestrator doctor --usage',
|
|
1355
|
-
'codex-orchestrator rlm --multi-agent auto "<goal>"',
|
|
1356
|
-
'codex-orchestrator codex defaults --yes',
|
|
1357
|
-
'codex-orchestrator mcp enable --servers delegation --yes'
|
|
1358
|
-
]
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
|
-
function formatSetupGuidanceSummary(guidance) {
|
|
1362
|
-
const lines = ['Setup guidance:', `- ${guidance.note}`];
|
|
1363
|
-
if (guidance.recommended_commands.length > 0) {
|
|
1364
|
-
lines.push('- Recommended commands:');
|
|
1365
|
-
for (const command of guidance.recommended_commands) {
|
|
1366
|
-
lines.push(` - ${command}`);
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
if (guidance.references.length > 0) {
|
|
1370
|
-
lines.push('- References:');
|
|
1371
|
-
for (const reference of guidance.references) {
|
|
1372
|
-
lines.push(` - ${reference}`);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
return lines;
|
|
915
|
+
await runSetupCliShell({ flags });
|
|
1376
916
|
}
|
|
1377
917
|
async function handleDoctor(rawArgs) {
|
|
1378
|
-
const { flags } = parseArgs(rawArgs);
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
const includeCloudPreflight = Boolean(flags['cloud-preflight']);
|
|
1382
|
-
const includeIssueLog = Boolean(flags['issue-log']);
|
|
1383
|
-
const cloudEnvIdOverride = readStringFlag(flags, 'cloud-env-id');
|
|
1384
|
-
const cloudBranchOverride = readStringFlag(flags, 'cloud-branch');
|
|
1385
|
-
const issueTitle = readStringFlag(flags, 'issue-title');
|
|
1386
|
-
const issueNotes = readStringFlag(flags, 'issue-notes');
|
|
1387
|
-
const issueLogPath = readStringFlag(flags, 'issue-log-path');
|
|
1388
|
-
if (!includeCloudPreflight && (cloudEnvIdOverride || cloudBranchOverride)) {
|
|
1389
|
-
throw new Error('--cloud-env-id/--cloud-branch require --cloud-preflight.');
|
|
1390
|
-
}
|
|
1391
|
-
if (!includeIssueLog && (issueTitle || issueNotes || issueLogPath)) {
|
|
1392
|
-
throw new Error('--issue-title/--issue-notes/--issue-log-path require --issue-log.');
|
|
1393
|
-
}
|
|
1394
|
-
const wantsApply = Boolean(flags['apply']);
|
|
1395
|
-
const apply = Boolean(flags['yes']);
|
|
1396
|
-
if (wantsApply && format === 'json') {
|
|
1397
|
-
throw new Error('doctor --apply does not support --format json.');
|
|
1398
|
-
}
|
|
1399
|
-
const windowDaysRaw = readStringFlag(flags, 'window-days');
|
|
1400
|
-
let windowDays = undefined;
|
|
1401
|
-
if (windowDaysRaw) {
|
|
1402
|
-
if (!/^\d+$/u.test(windowDaysRaw)) {
|
|
1403
|
-
throw new Error(`Invalid --window-days value '${windowDaysRaw}'. Expected a positive integer.`);
|
|
1404
|
-
}
|
|
1405
|
-
const parsed = Number(windowDaysRaw);
|
|
1406
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
1407
|
-
throw new Error(`Invalid --window-days value '${windowDaysRaw}'. Expected a positive integer.`);
|
|
1408
|
-
}
|
|
1409
|
-
windowDays = parsed;
|
|
1410
|
-
}
|
|
1411
|
-
const taskFilter = readStringFlag(flags, 'task') ?? null;
|
|
1412
|
-
const doctorResult = runDoctor();
|
|
1413
|
-
const usageResult = includeUsage ? await runDoctorUsage({ windowDays, taskFilter }) : null;
|
|
1414
|
-
const cloudPreflightResult = includeCloudPreflight
|
|
1415
|
-
? await runDoctorCloudPreflight({
|
|
1416
|
-
cwd: process.cwd(),
|
|
1417
|
-
environmentId: cloudEnvIdOverride,
|
|
1418
|
-
branch: cloudBranchOverride,
|
|
1419
|
-
taskId: taskFilter
|
|
1420
|
-
})
|
|
1421
|
-
: null;
|
|
1422
|
-
const issueLogResult = includeIssueLog
|
|
1423
|
-
? await writeDoctorIssueLog({
|
|
1424
|
-
doctor: doctorResult,
|
|
1425
|
-
usage: usageResult,
|
|
1426
|
-
cloudPreflight: cloudPreflightResult,
|
|
1427
|
-
issueTitle,
|
|
1428
|
-
issueNotes,
|
|
1429
|
-
issueLogPath,
|
|
1430
|
-
taskFilter
|
|
1431
|
-
})
|
|
1432
|
-
: null;
|
|
1433
|
-
if (format === 'json') {
|
|
1434
|
-
const payload = { ...doctorResult };
|
|
1435
|
-
if (usageResult) {
|
|
1436
|
-
payload.usage = usageResult;
|
|
1437
|
-
}
|
|
1438
|
-
if (cloudPreflightResult) {
|
|
1439
|
-
payload.cloud_preflight = cloudPreflightResult;
|
|
1440
|
-
}
|
|
1441
|
-
if (issueLogResult) {
|
|
1442
|
-
payload.issue_log = issueLogResult;
|
|
1443
|
-
}
|
|
1444
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
1445
|
-
return;
|
|
1446
|
-
}
|
|
1447
|
-
for (const line of formatDoctorSummary(doctorResult)) {
|
|
1448
|
-
console.log(line);
|
|
1449
|
-
}
|
|
1450
|
-
if (usageResult) {
|
|
1451
|
-
for (const line of formatDoctorUsageSummary(usageResult)) {
|
|
1452
|
-
console.log(line);
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
if (cloudPreflightResult) {
|
|
1456
|
-
for (const line of formatDoctorCloudPreflightSummary(cloudPreflightResult)) {
|
|
1457
|
-
console.log(line);
|
|
1458
|
-
}
|
|
1459
|
-
}
|
|
1460
|
-
if (issueLogResult) {
|
|
1461
|
-
for (const line of formatDoctorIssueLogSummary(issueLogResult)) {
|
|
1462
|
-
console.log(line);
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
if (!wantsApply) {
|
|
1466
|
-
return;
|
|
1467
|
-
}
|
|
1468
|
-
const repoRoot = process.cwd();
|
|
1469
|
-
const delegationPlan = await runDelegationSetup({ repoRoot });
|
|
1470
|
-
const devtoolsPlan = await runDevtoolsSetup();
|
|
1471
|
-
const needsDelegation = !delegationPlan.readiness.configured;
|
|
1472
|
-
const needsDevtoolsSkill = devtoolsPlan.readiness.skill.status !== 'ok';
|
|
1473
|
-
const devtoolsConfigStatus = devtoolsPlan.readiness.config.status;
|
|
1474
|
-
const needsDevtoolsConfig = devtoolsConfigStatus === 'missing';
|
|
1475
|
-
const hasInvalidDevtoolsConfig = devtoolsConfigStatus === 'invalid';
|
|
1476
|
-
if (!needsDelegation && !needsDevtoolsSkill && !needsDevtoolsConfig && !hasInvalidDevtoolsConfig) {
|
|
1477
|
-
console.log('Doctor apply: nothing to do.');
|
|
1478
|
-
return;
|
|
1479
|
-
}
|
|
1480
|
-
console.log('Doctor apply plan:');
|
|
1481
|
-
if (needsDevtoolsSkill) {
|
|
1482
|
-
console.log('- Install skill: chrome-devtools (codex-orchestrator skills install --only chrome-devtools)');
|
|
1483
|
-
}
|
|
1484
|
-
if (hasInvalidDevtoolsConfig) {
|
|
1485
|
-
console.log(`- DevTools MCP config is invalid: ${devtoolsPlan.readiness.config.path} (fix config.toml then rerun doctor --apply)`);
|
|
1486
|
-
}
|
|
1487
|
-
if (needsDevtoolsConfig) {
|
|
1488
|
-
console.log('- Configure DevTools MCP: codex-orchestrator devtools setup --yes');
|
|
1489
|
-
}
|
|
1490
|
-
if (needsDelegation) {
|
|
1491
|
-
console.log('- Configure delegation MCP: codex-orchestrator delegation setup --yes');
|
|
1492
|
-
}
|
|
1493
|
-
if (!apply) {
|
|
1494
|
-
console.log('Run with --apply --yes to apply these fixes.');
|
|
918
|
+
const { positionals, flags } = parseArgs(rawArgs);
|
|
919
|
+
if (isHelpRequest(positionals, flags)) {
|
|
920
|
+
printDoctorHelp();
|
|
1495
921
|
return;
|
|
1496
922
|
}
|
|
1497
|
-
if (
|
|
1498
|
-
|
|
1499
|
-
for (const line of formatSkillsInstallSummary(skills)) {
|
|
1500
|
-
console.log(line);
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
if (needsDelegation) {
|
|
1504
|
-
const delegation = await runDelegationSetup({ apply: true, repoRoot });
|
|
1505
|
-
for (const line of formatDelegationSetupSummary(delegation)) {
|
|
1506
|
-
console.log(line);
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
if (hasInvalidDevtoolsConfig) {
|
|
1510
|
-
console.log(`DevTools setup: skipped (config.toml is invalid: ${devtoolsPlan.readiness.config.path}). Fix it and rerun doctor --apply --yes.`);
|
|
1511
|
-
}
|
|
1512
|
-
else if (needsDevtoolsConfig) {
|
|
1513
|
-
const devtools = await runDevtoolsSetup({ apply: true });
|
|
1514
|
-
for (const line of formatDevtoolsSetupSummary(devtools)) {
|
|
1515
|
-
console.log(line);
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
const doctorAfter = runDoctor();
|
|
1519
|
-
for (const line of formatDoctorSummary(doctorAfter)) {
|
|
1520
|
-
console.log(line);
|
|
923
|
+
if (positionals.length > 0) {
|
|
924
|
+
throw new Error(`Unknown doctor argument(s): ${positionals.join(' ')}`);
|
|
1521
925
|
}
|
|
926
|
+
await runDoctorCliRequestShell({ flags });
|
|
1522
927
|
}
|
|
1523
928
|
async function handleDevtools(rawArgs) {
|
|
1524
929
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1525
|
-
|
|
1526
|
-
if (!subcommand) {
|
|
1527
|
-
throw new Error('devtools requires a subcommand (setup).');
|
|
1528
|
-
}
|
|
1529
|
-
if (subcommand !== 'setup') {
|
|
1530
|
-
throw new Error(`Unknown devtools subcommand: ${subcommand}`);
|
|
1531
|
-
}
|
|
1532
|
-
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1533
|
-
const apply = Boolean(flags['yes']);
|
|
1534
|
-
if (format === 'json' && apply) {
|
|
1535
|
-
throw new Error('devtools setup does not support --format json with --yes.');
|
|
1536
|
-
}
|
|
1537
|
-
const result = await runDevtoolsSetup({ apply });
|
|
1538
|
-
if (format === 'json') {
|
|
1539
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1540
|
-
return;
|
|
1541
|
-
}
|
|
1542
|
-
const summary = formatDevtoolsSetupSummary(result);
|
|
1543
|
-
for (const line of summary) {
|
|
1544
|
-
console.log(line);
|
|
1545
|
-
}
|
|
930
|
+
await runDevtoolsCliShell({ positionals, flags });
|
|
1546
931
|
}
|
|
1547
932
|
async function handleDelegation(rawArgs) {
|
|
1548
933
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1549
|
-
|
|
1550
|
-
if (!subcommand) {
|
|
1551
|
-
throw new Error('delegation requires a subcommand (setup).');
|
|
1552
|
-
}
|
|
1553
|
-
if (subcommand !== 'setup') {
|
|
1554
|
-
throw new Error(`Unknown delegation subcommand: ${subcommand}`);
|
|
1555
|
-
}
|
|
1556
|
-
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1557
|
-
const apply = Boolean(flags['yes']);
|
|
1558
|
-
if (format === 'json' && apply) {
|
|
1559
|
-
throw new Error('delegation setup does not support --format json with --yes.');
|
|
1560
|
-
}
|
|
1561
|
-
const repoRoot = readStringFlag(flags, 'repo') ?? process.cwd();
|
|
1562
|
-
const result = await runDelegationSetup({ apply, repoRoot });
|
|
1563
|
-
if (format === 'json') {
|
|
1564
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1565
|
-
return;
|
|
1566
|
-
}
|
|
1567
|
-
for (const line of formatDelegationSetupSummary(result)) {
|
|
1568
|
-
console.log(line);
|
|
1569
|
-
}
|
|
934
|
+
await runDelegationCliShell({ positionals, flags });
|
|
1570
935
|
}
|
|
1571
936
|
async function handleCodex(rawArgs) {
|
|
1572
937
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1573
|
-
|
|
1574
|
-
if (flags['help'] === true || flags['--help'] === true || flags['h'] === true || !subcommand || subcommand === 'help' || subcommand === '--help' || subcommand === '-h') {
|
|
1575
|
-
printCodexHelp();
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
|
-
if (subcommand === 'setup') {
|
|
1579
|
-
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1580
|
-
const apply = Boolean(flags['yes']);
|
|
1581
|
-
const source = readStringFlag(flags, 'source');
|
|
1582
|
-
const ref = readStringFlag(flags, 'ref');
|
|
1583
|
-
const downloadUrl = readStringFlag(flags, 'download-url');
|
|
1584
|
-
const downloadSha256 = readStringFlag(flags, 'download-sha256');
|
|
1585
|
-
const force = Boolean(flags['force']);
|
|
1586
|
-
const result = await runCodexCliSetup({
|
|
1587
|
-
apply,
|
|
1588
|
-
force,
|
|
1589
|
-
source,
|
|
1590
|
-
ref,
|
|
1591
|
-
downloadUrl,
|
|
1592
|
-
downloadSha256
|
|
1593
|
-
});
|
|
1594
|
-
if (format === 'json') {
|
|
1595
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1596
|
-
return;
|
|
1597
|
-
}
|
|
1598
|
-
const summary = formatCodexCliSetupSummary(result);
|
|
1599
|
-
for (const line of summary) {
|
|
1600
|
-
console.log(line);
|
|
1601
|
-
}
|
|
1602
|
-
return;
|
|
1603
|
-
}
|
|
1604
|
-
if (subcommand === 'defaults') {
|
|
1605
|
-
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1606
|
-
const apply = Boolean(flags['yes']);
|
|
1607
|
-
const force = Boolean(flags['force']);
|
|
1608
|
-
const result = await runCodexDefaultsSetup({
|
|
1609
|
-
apply,
|
|
1610
|
-
force
|
|
1611
|
-
});
|
|
1612
|
-
if (format === 'json') {
|
|
1613
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1614
|
-
return;
|
|
1615
|
-
}
|
|
1616
|
-
const summary = formatCodexDefaultsSetupSummary(result);
|
|
1617
|
-
for (const line of summary) {
|
|
1618
|
-
console.log(line);
|
|
1619
|
-
}
|
|
1620
|
-
return;
|
|
1621
|
-
}
|
|
1622
|
-
throw new Error(`Unknown codex subcommand: ${subcommand}`);
|
|
938
|
+
await runCodexCliShell({ positionals, flags, printHelp: printCodexHelp });
|
|
1623
939
|
}
|
|
1624
940
|
async function handleSkills(rawArgs) {
|
|
1625
941
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
}
|
|
1632
|
-
switch (subcommand) {
|
|
1633
|
-
case 'install': {
|
|
1634
|
-
const format = flags['format'] === 'json' ? 'json' : 'text';
|
|
1635
|
-
const force = flags['force'] === true;
|
|
1636
|
-
const codexHome = readStringFlag(flags, 'codex-home');
|
|
1637
|
-
const onlyRaw = flags['only'];
|
|
1638
|
-
let only;
|
|
1639
|
-
if (onlyRaw !== undefined) {
|
|
1640
|
-
if (typeof onlyRaw !== 'string') {
|
|
1641
|
-
throw new Error('--only requires a comma-separated list of skill names.');
|
|
1642
|
-
}
|
|
1643
|
-
only = onlyRaw.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
1644
|
-
}
|
|
1645
|
-
const result = await installSkills({ force, codexHome, only });
|
|
1646
|
-
if (format === 'json') {
|
|
1647
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1648
|
-
}
|
|
1649
|
-
else {
|
|
1650
|
-
console.log(formatSkillsInstallSummary(result).join('\n'));
|
|
1651
|
-
}
|
|
1652
|
-
return;
|
|
1653
|
-
}
|
|
1654
|
-
default:
|
|
1655
|
-
throw new Error(`Unknown skills command: ${subcommand}`);
|
|
1656
|
-
}
|
|
942
|
+
await runSkillsCliShell({ positionals, flags, printHelp: printSkillsHelp });
|
|
943
|
+
}
|
|
944
|
+
async function handleLinear(rawArgs) {
|
|
945
|
+
const { positionals, flags } = parseArgs(rawArgs);
|
|
946
|
+
await runLinearCliShell({ positionals, flags, printHelp: printLinearHelp });
|
|
1657
947
|
}
|
|
1658
948
|
async function handleMcp(rawArgs) {
|
|
1659
949
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
@@ -1672,182 +962,31 @@ async function handleMcp(rawArgs) {
|
|
|
1672
962
|
return;
|
|
1673
963
|
}
|
|
1674
964
|
if (subcommand === 'enable') {
|
|
1675
|
-
|
|
1676
|
-
let yesFlag;
|
|
1677
|
-
let formatFlag;
|
|
1678
|
-
let serversFlag;
|
|
1679
|
-
const unexpectedPositionals = [];
|
|
1680
|
-
const enableTokens = rawArgs.slice(1);
|
|
1681
|
-
for (let index = 0; index < enableTokens.length; index += 1) {
|
|
1682
|
-
const token = enableTokens[index];
|
|
1683
|
-
if (!token) {
|
|
1684
|
-
continue;
|
|
1685
|
-
}
|
|
1686
|
-
if (token === '--') {
|
|
1687
|
-
unexpectedPositionals.push(...enableTokens.slice(index + 1));
|
|
1688
|
-
break;
|
|
1689
|
-
}
|
|
1690
|
-
if (!token.startsWith('--')) {
|
|
1691
|
-
unexpectedPositionals.push(token);
|
|
1692
|
-
continue;
|
|
1693
|
-
}
|
|
1694
|
-
const [key, inlineValue] = token.slice(2).split('=', 2);
|
|
1695
|
-
if (!allowedEnableFlags.has(key)) {
|
|
1696
|
-
throw new Error(`Unknown mcp enable flag: --${key}`);
|
|
1697
|
-
}
|
|
1698
|
-
let resolvedValue = true;
|
|
1699
|
-
if (inlineValue !== undefined) {
|
|
1700
|
-
resolvedValue = inlineValue;
|
|
1701
|
-
}
|
|
1702
|
-
else {
|
|
1703
|
-
const nextToken = enableTokens[index + 1];
|
|
1704
|
-
if (nextToken && !nextToken.startsWith('--')) {
|
|
1705
|
-
resolvedValue = nextToken;
|
|
1706
|
-
index += 1;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
if (key === 'yes') {
|
|
1710
|
-
if (yesFlag !== undefined) {
|
|
1711
|
-
throw new Error('--yes specified multiple times.');
|
|
1712
|
-
}
|
|
1713
|
-
yesFlag = resolvedValue;
|
|
1714
|
-
continue;
|
|
1715
|
-
}
|
|
1716
|
-
if (key === 'format') {
|
|
1717
|
-
if (formatFlag !== undefined) {
|
|
1718
|
-
throw new Error('--format specified multiple times.');
|
|
1719
|
-
}
|
|
1720
|
-
formatFlag = resolvedValue;
|
|
1721
|
-
continue;
|
|
1722
|
-
}
|
|
1723
|
-
if (serversFlag !== undefined) {
|
|
1724
|
-
throw new Error('--servers specified multiple times.');
|
|
1725
|
-
}
|
|
1726
|
-
serversFlag = resolvedValue;
|
|
1727
|
-
}
|
|
1728
|
-
if (positionals.length > 0 || unexpectedPositionals.length > 0) {
|
|
1729
|
-
throw new Error(`mcp enable does not accept positional arguments: ${[...positionals, ...unexpectedPositionals].join(' ')}`);
|
|
1730
|
-
}
|
|
1731
|
-
let apply = false;
|
|
1732
|
-
if (yesFlag === true) {
|
|
1733
|
-
apply = true;
|
|
1734
|
-
}
|
|
1735
|
-
else if (typeof yesFlag === 'string') {
|
|
1736
|
-
const normalizedYes = yesFlag.trim().toLowerCase();
|
|
1737
|
-
if (normalizedYes === 'true' || normalizedYes === '1' || normalizedYes === 'yes' || normalizedYes === 'on') {
|
|
1738
|
-
apply = true;
|
|
1739
|
-
}
|
|
1740
|
-
else if (normalizedYes === 'false'
|
|
1741
|
-
|| normalizedYes === '0'
|
|
1742
|
-
|| normalizedYes === 'no'
|
|
1743
|
-
|| normalizedYes === 'off') {
|
|
1744
|
-
apply = false;
|
|
1745
|
-
}
|
|
1746
|
-
else {
|
|
1747
|
-
throw new Error('--yes expects true/false when provided as --yes=<value>.');
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
let format = 'text';
|
|
1751
|
-
if (formatFlag !== undefined) {
|
|
1752
|
-
if (formatFlag === true) {
|
|
1753
|
-
throw new Error('--format requires a value of "text" or "json".');
|
|
1754
|
-
}
|
|
1755
|
-
if (formatFlag === 'json') {
|
|
1756
|
-
format = 'json';
|
|
1757
|
-
}
|
|
1758
|
-
else if (formatFlag === 'text') {
|
|
1759
|
-
format = 'text';
|
|
1760
|
-
}
|
|
1761
|
-
else {
|
|
1762
|
-
throw new Error('--format must be "text" or "json".');
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
let serverNames;
|
|
1766
|
-
if (serversFlag !== undefined) {
|
|
1767
|
-
if (typeof serversFlag !== 'string') {
|
|
1768
|
-
throw new Error('--servers must include a comma-separated list of MCP server names.');
|
|
1769
|
-
}
|
|
1770
|
-
serverNames = serversFlag
|
|
1771
|
-
.split(',')
|
|
1772
|
-
.map((entry) => entry.trim())
|
|
1773
|
-
.filter((entry) => entry.length > 0);
|
|
1774
|
-
if (serverNames.length === 0) {
|
|
1775
|
-
throw new Error('--servers must include a comma-separated list of MCP server names.');
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
const result = await runMcpEnable({ apply, serverNames });
|
|
1779
|
-
const hasApplyFailures = apply
|
|
1780
|
-
&& result.actions.some((action) => action.status !== 'enabled' && action.status !== 'already_enabled');
|
|
1781
|
-
if (format === 'json') {
|
|
1782
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1783
|
-
}
|
|
1784
|
-
else {
|
|
1785
|
-
for (const line of formatMcpEnableSummary(result)) {
|
|
1786
|
-
console.log(line);
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
if (hasApplyFailures) {
|
|
1790
|
-
process.exitCode = 1;
|
|
1791
|
-
}
|
|
965
|
+
await runMcpEnableCliShell({ rawArgs: rawArgs.slice(1) });
|
|
1792
966
|
return;
|
|
1793
967
|
}
|
|
1794
968
|
throw new Error(`Unknown mcp subcommand: ${subcommand}`);
|
|
1795
969
|
}
|
|
1796
970
|
async function handlePr(rawArgs) {
|
|
1797
|
-
if (rawArgs.length === 0 || rawArgs[0]
|
|
971
|
+
if (rawArgs.length === 0 || isCliHelpToken(rawArgs[0])) {
|
|
1798
972
|
printPrHelp();
|
|
1799
973
|
return;
|
|
1800
974
|
}
|
|
1801
975
|
const [subcommand, ...subcommandArgs] = rawArgs;
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
},
|
|
1806
|
-
'resolve-merge': {
|
|
1807
|
-
usage: 'codex-orchestrator pr resolve-merge',
|
|
1808
|
-
defaultExitOnActionRequired: true
|
|
1809
|
-
}
|
|
1810
|
-
};
|
|
1811
|
-
const mode = modeBySubcommand[subcommand];
|
|
1812
|
-
if (!mode) {
|
|
1813
|
-
throw new Error(`Unknown pr subcommand: ${subcommand}`);
|
|
1814
|
-
}
|
|
1815
|
-
const exitCode = await runPrWatchMerge(subcommandArgs, mode);
|
|
1816
|
-
if (exitCode !== 0) {
|
|
1817
|
-
process.exitCode = exitCode;
|
|
976
|
+
if (isPrHelpSubcommand(subcommand) && shouldPrintPrSubcommandHelp(subcommandArgs)) {
|
|
977
|
+
printPrSubcommandHelp(subcommand);
|
|
978
|
+
return;
|
|
1818
979
|
}
|
|
980
|
+
const { runPrCliShell } = await import('../orchestrator/src/cli/prCliShell.js');
|
|
981
|
+
await runPrCliShell({ rawArgs });
|
|
1819
982
|
}
|
|
1820
983
|
async function handleDelegationServer(rawArgs) {
|
|
1821
984
|
const { positionals, flags } = parseArgs(rawArgs);
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
const modeFlag = typeof flags['mode'] === 'string' ? flags['mode'] : undefined;
|
|
1828
|
-
const overrideFlag = typeof flags['config'] === 'string'
|
|
1829
|
-
? flags['config']
|
|
1830
|
-
: typeof flags['config-override'] === 'string'
|
|
1831
|
-
? flags['config-override']
|
|
1832
|
-
: undefined;
|
|
1833
|
-
const envMode = process.env.CODEX_DELEGATE_MODE?.trim();
|
|
1834
|
-
const resolvedMode = modeFlag ?? envMode;
|
|
1835
|
-
let mode;
|
|
1836
|
-
if (resolvedMode) {
|
|
1837
|
-
if (resolvedMode === 'full' || resolvedMode === 'question_only') {
|
|
1838
|
-
mode = resolvedMode;
|
|
1839
|
-
}
|
|
1840
|
-
else {
|
|
1841
|
-
console.warn(`Invalid delegate mode "${resolvedMode}". Falling back to config default.`);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
const configOverrides = overrideFlag
|
|
1845
|
-
? splitDelegationConfigOverrides(overrideFlag).map((value) => ({
|
|
1846
|
-
source: 'cli',
|
|
1847
|
-
value
|
|
1848
|
-
}))
|
|
1849
|
-
: [];
|
|
1850
|
-
await startDelegationServer({ repoRoot, mode, configOverrides });
|
|
985
|
+
await runDelegationServerCliShell({
|
|
986
|
+
positionals,
|
|
987
|
+
flags,
|
|
988
|
+
printHelp: printDelegationServerHelp
|
|
989
|
+
});
|
|
1851
990
|
}
|
|
1852
991
|
function parseExecArgs(rawArgs) {
|
|
1853
992
|
const notifyTargets = [];
|
|
@@ -2136,6 +1275,20 @@ Commands:
|
|
|
2136
1275
|
--interactive | --ui Enable read-only HUD when running in a TTY.
|
|
2137
1276
|
--no-interactive Force disable HUD (default is off unless requested).
|
|
2138
1277
|
|
|
1278
|
+
control-host [options]
|
|
1279
|
+
Start a persistent Linear intake and Telegram/status host without tying it to a foreground run.
|
|
1280
|
+
--task <id> Artifact task id for the host state (default: local-mcp).
|
|
1281
|
+
--run <id> Host run id for persisted state files (default: control-host).
|
|
1282
|
+
--pipeline <id> Pipeline used for provider-driven starts (default: diagnostics).
|
|
1283
|
+
--format json Emit machine-readable readiness output.
|
|
1284
|
+
control-host freshness-gauge [options]
|
|
1285
|
+
Replay local provider/control-host artifacts and emit throughput/freshness health JSON.
|
|
1286
|
+
|
|
1287
|
+
co-status [options]
|
|
1288
|
+
Attach the CO STATUS terminal viewer or emit the current snapshot from an already-running local control-host.
|
|
1289
|
+
co-status attach [options]
|
|
1290
|
+
Attach a read-only CO STATUS viewer to an already-running local control-host.
|
|
1291
|
+
|
|
2139
1292
|
status --run <id> [--watch] [--interval N] [--format json]
|
|
2140
1293
|
|
|
2141
1294
|
self-check [--format json]
|
|
@@ -2178,6 +1331,7 @@ Commands:
|
|
|
2178
1331
|
codex defaults
|
|
2179
1332
|
--yes Apply setup (otherwise dry-run plan only).
|
|
2180
1333
|
--force Allow overwriting existing role files in ~/.codex/agents.
|
|
1334
|
+
--auth-scope <portable|chatgpt> Select portable defaults or validated ChatGPT-auth gpt-5.5 defaults.
|
|
2181
1335
|
--format json Emit machine-readable output.
|
|
2182
1336
|
devtools setup Print DevTools MCP setup instructions.
|
|
2183
1337
|
--yes Apply setup by running "codex mcp add ...".
|
|
@@ -2186,11 +1340,15 @@ Commands:
|
|
|
2186
1340
|
--repo <path> Repo root for delegation server (default cwd).
|
|
2187
1341
|
--yes Apply setup by running "codex mcp add ...".
|
|
2188
1342
|
--format json Emit machine-readable output (dry-run only).
|
|
1343
|
+
delegation cleanup-stale
|
|
1344
|
+
--yes Terminate stale delegate-server processes not rooted in a live codex client.
|
|
1345
|
+
--format json Emit machine-readable output.
|
|
2189
1346
|
skills install Install bundled skills into $CODEX_HOME/skills.
|
|
2190
1347
|
--force Overwrite existing skill files.
|
|
2191
1348
|
--only <skills> Install only selected skills (comma-separated).
|
|
2192
1349
|
--codex-home <path> Override the target Codex home directory.
|
|
2193
1350
|
--format json Emit machine-readable output.
|
|
1351
|
+
linear <subcommand> Run worker-visible Linear helper operations.
|
|
2194
1352
|
mcp serve [--repo <path>] [--dry-run] [-- <extra args>]
|
|
2195
1353
|
mcp enable [--servers <csv>] [--yes] [--format json]
|
|
2196
1354
|
--servers <csv> Comma-separated MCP server names to enable (default: all disabled).
|
|
@@ -2202,10 +1360,15 @@ Commands:
|
|
|
2202
1360
|
pr resolve-merge [options]
|
|
2203
1361
|
Monitor until merge-ready or actionable feedback appears; exits early when author action is required.
|
|
2204
1362
|
Use \`codex-orchestrator pr resolve-merge --help\` for full options.
|
|
1363
|
+
pr ready-review [options]
|
|
1364
|
+
Wait through a bounded automated-feedback drain before human review handoff; exits early when author action is required.
|
|
1365
|
+
Use \`codex-orchestrator pr ready-review --help\` for full options.
|
|
2205
1366
|
delegate-server Run the delegation MCP server (stdio).
|
|
2206
1367
|
--repo <path> Repo root for config + manifests (default cwd).
|
|
2207
|
-
--mode <full|question_only> Limit tool surface for child runs.
|
|
1368
|
+
--mode <full|question_only|status_only> Limit tool surface for child runs.
|
|
2208
1369
|
--config "<key>=<value>[;...]" Apply config overrides (repeat via separators).
|
|
1370
|
+
control-host Run the persistent provider intake + oversight host.
|
|
1371
|
+
co-status Attach the CO STATUS terminal viewer or emit the current snapshot from an already-running local control-host.
|
|
2209
1372
|
version | --version
|
|
2210
1373
|
|
|
2211
1374
|
help Show this message.
|
|
@@ -2213,6 +1376,7 @@ Commands:
|
|
|
2213
1376
|
Quickstart (agent-first):
|
|
2214
1377
|
codex-orchestrator flow --task <task-id>
|
|
2215
1378
|
NOTES="Goal: ... | Summary: ... | Risks: ..." codex-orchestrator review --task <task-id>
|
|
1379
|
+
codex-orchestrator doctor --format json
|
|
2216
1380
|
codex-orchestrator doctor --usage --window-days 30
|
|
2217
1381
|
codex-orchestrator rlm --multi-agent auto "<goal>"
|
|
2218
1382
|
codex-orchestrator start implementation-gate --cloud --target <stage-id>
|
|
@@ -2223,7 +1387,9 @@ Notes:
|
|
|
2223
1387
|
Review artifacts guide: docs/guides/review-artifacts.md
|
|
2224
1388
|
`);
|
|
2225
1389
|
}
|
|
2226
|
-
|
|
1390
|
+
if (isDirectExecution()) {
|
|
1391
|
+
void runCodexOrchestratorCli();
|
|
1392
|
+
}
|
|
2227
1393
|
function printVersion() {
|
|
2228
1394
|
const pkg = loadPackageInfo();
|
|
2229
1395
|
console.log(pkg.version ?? 'unknown');
|
|
@@ -2239,6 +1405,144 @@ Commands:
|
|
|
2239
1405
|
--format json Emit machine-readable output.
|
|
2240
1406
|
`);
|
|
2241
1407
|
}
|
|
1408
|
+
function printLinearHelp() {
|
|
1409
|
+
console.log(`Usage: codex-orchestrator linear <subcommand> [options]
|
|
1410
|
+
|
|
1411
|
+
Subcommands:
|
|
1412
|
+
issue-context
|
|
1413
|
+
--issue-id <id> Linear issue id/key to inspect.
|
|
1414
|
+
--workspace-id <id> Optional workspace scope check (falls back to env when configured).
|
|
1415
|
+
--team-id <id> Optional team scope check (falls back to env when configured).
|
|
1416
|
+
--project-id <id> Optional project scope check (falls back to env when configured).
|
|
1417
|
+
--format json Emit machine-readable output.
|
|
1418
|
+
|
|
1419
|
+
upsert-workpad
|
|
1420
|
+
--issue-id <id> Linear issue id/key to update.
|
|
1421
|
+
--body <text> Workpad body to create/update. Local markdown image refs are uploaded to Linear.
|
|
1422
|
+
--body-file <path> Read workpad body from a file. Supports local image refs like file:///abs/proof.png or <file:///abs/proof (1).png>.
|
|
1423
|
+
--comment-id <id> Optional persisted workpad comment id.
|
|
1424
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1425
|
+
--team-id <id> Optional team scope check.
|
|
1426
|
+
--project-id <id> Optional project scope check.
|
|
1427
|
+
--format json Emit machine-readable output.
|
|
1428
|
+
|
|
1429
|
+
delete-workpad
|
|
1430
|
+
--issue-id <id> Linear issue id/key whose workpad should be deleted.
|
|
1431
|
+
--comment-id <id> Optional persisted workpad comment id to delete.
|
|
1432
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1433
|
+
--team-id <id> Optional team scope check.
|
|
1434
|
+
--project-id <id> Optional project scope check.
|
|
1435
|
+
--format json Emit machine-readable output.
|
|
1436
|
+
|
|
1437
|
+
transition
|
|
1438
|
+
--issue-id <id> Linear issue id/key to update.
|
|
1439
|
+
--state <name> Destination Linear state name (resolved to stateId via team workflow states).
|
|
1440
|
+
--expected-state <name>
|
|
1441
|
+
Optional expected live state name; conflicts fail closed before mutation.
|
|
1442
|
+
--expected-state-type <type>
|
|
1443
|
+
Optional expected live workflow type; conflicts fail closed before mutation.
|
|
1444
|
+
--expected-updated-at <iso>
|
|
1445
|
+
Optional expected live updated_at timestamp; conflicts fail closed before mutation.
|
|
1446
|
+
--force Allow terminal-to-reopen transitions with an audited force reason.
|
|
1447
|
+
--force-reason <text> Required whenever --force is set.
|
|
1448
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1449
|
+
--team-id <id> Optional team scope check.
|
|
1450
|
+
--project-id <id> Optional project scope check.
|
|
1451
|
+
--format json Emit machine-readable output.
|
|
1452
|
+
|
|
1453
|
+
attach-pr
|
|
1454
|
+
--issue-id <id> Linear issue id/key to update.
|
|
1455
|
+
--url <url> GitHub PR URL to attach.
|
|
1456
|
+
--title <title> Optional attachment title.
|
|
1457
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1458
|
+
--team-id <id> Optional team scope check.
|
|
1459
|
+
--project-id <id> Optional project scope check.
|
|
1460
|
+
--format json Emit machine-readable output.
|
|
1461
|
+
|
|
1462
|
+
parallelization
|
|
1463
|
+
--issue-id <id> Linear issue id/key for the active provider-worker turn.
|
|
1464
|
+
--decision <mode> parallelize_now, stay_serial, or forbid_parallel.
|
|
1465
|
+
--reason <code> Reason code allowed for the selected decision.
|
|
1466
|
+
--summary <text> Required operator summary. Include matrix/cap evidence.
|
|
1467
|
+
Parallel-first rule: create a pre-turn decomposition matrix before the decision.
|
|
1468
|
+
Matrix columns: candidate lane, file/phase scope, dependencies, overlap risk,
|
|
1469
|
+
expected validation artifact, child-lane owner, and cap-slot use.
|
|
1470
|
+
stay_serial is invalid while any safe independent child-lane candidate remains;
|
|
1471
|
+
single_bounded_change must label docs/test/research/review slice justifications.
|
|
1472
|
+
Child-lane cap: at most 2 active, pending, or unaccepted same-issue child lanes.
|
|
1473
|
+
On cap exhaustion, use stay_serial/existing_child_lane_active and include cap_exhausted: evidence.
|
|
1474
|
+
Stale in-flight accept claims older than 30 minutes, or legacy claims without timestamps, are recoverable and do not consume cap.
|
|
1475
|
+
Parent ownership: avoid delegated files/phases while a child lane is active; collisions
|
|
1476
|
+
require invalidate/reject/rebase reasoning before child patch acceptance.
|
|
1477
|
+
--format json Emit machine-readable output.
|
|
1478
|
+
|
|
1479
|
+
create-follow-up
|
|
1480
|
+
--issue-id <id> Source Linear issue id/key.
|
|
1481
|
+
--title <title> Follow-up issue title.
|
|
1482
|
+
--description <text> Follow-up issue description.
|
|
1483
|
+
--description-file <path> Read follow-up issue description from a file.
|
|
1484
|
+
--intent-checksum <text> Exact wording, protected terms, and wrong interpretations to reject.
|
|
1485
|
+
--intent-checksum-file <path> Read the intent checksum from a file.
|
|
1486
|
+
--non-goals <text> Explicit follow-up non-goals.
|
|
1487
|
+
--non-goals-file <path> Read follow-up non-goals from a file.
|
|
1488
|
+
--not-done-if <text> Readiness blockers / false-done conditions.
|
|
1489
|
+
--not-done-if-file <path> Read the false-done block from a file.
|
|
1490
|
+
--acceptance-criteria <text> Follow-up acceptance criteria.
|
|
1491
|
+
--acceptance-criteria-file <path> Read follow-up acceptance criteria from a file.
|
|
1492
|
+
--parity-lane Require a parity/alignment matrix for this follow-up.
|
|
1493
|
+
--parity-matrix <text> Current/reference/target matrix (required when --parity-lane is set).
|
|
1494
|
+
--parity-matrix-file <path> Read the parity/alignment matrix from a file (required when --parity-lane is set).
|
|
1495
|
+
--canonical-owner-key <text> Exact canonical owner key for reuse before creating a new issue.
|
|
1496
|
+
--canonical-owner-key-file <path> Read the canonical owner key from a file.
|
|
1497
|
+
--blocked-by-source Add blocker linkage when the follow-up depends on the source issue.
|
|
1498
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1499
|
+
--team-id <id> Optional team scope check.
|
|
1500
|
+
--project-id <id> Optional project scope check.
|
|
1501
|
+
--format json Emit machine-readable output.
|
|
1502
|
+
|
|
1503
|
+
runtime-proof
|
|
1504
|
+
--issue-id <id> Linear issue id/key for audit continuity.
|
|
1505
|
+
--origin <url> App origin whose permit posture should be evaluated.
|
|
1506
|
+
--kind <mode> Optional proof kind: screenshot, external-link, or video.
|
|
1507
|
+
--proof-url <url> Reviewer-usable proof URL for workpad/PR handoff generation.
|
|
1508
|
+
--title <title> Optional proof label (defaults by kind).
|
|
1509
|
+
--summary <text> Optional short proof summary for workpad/PR handoff text.
|
|
1510
|
+
--reachability-mode <mode>
|
|
1511
|
+
Optional reviewer reachability mode: deterministic (default) or dns-public.
|
|
1512
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1513
|
+
--team-id <id> Optional team scope check.
|
|
1514
|
+
--project-id <id> Optional project scope check.
|
|
1515
|
+
--format json Emit machine-readable output.
|
|
1516
|
+
|
|
1517
|
+
screenshot-proof
|
|
1518
|
+
--issue-id <id> Linear issue id/key for audit continuity.
|
|
1519
|
+
--output <path> Optional local screenshot path (.png/.jpg/.jpeg). Defaults under .tmp/.
|
|
1520
|
+
--display-id <id> Optional macOS display id for bounded display capture.
|
|
1521
|
+
--window-id <id> Optional macOS window id for bounded window capture.
|
|
1522
|
+
--open-preview Open the captured file in Preview and attempt bounded AppleScript cleanup.
|
|
1523
|
+
--workspace-id <id> Optional workspace scope check.
|
|
1524
|
+
--team-id <id> Optional team scope check.
|
|
1525
|
+
--project-id <id> Optional project scope check.
|
|
1526
|
+
--format json Emit machine-readable output.
|
|
1527
|
+
|
|
1528
|
+
child-stream
|
|
1529
|
+
--pipeline <id> Allowlisted child pipeline: docs-review, implementation-gate, or docs-relevance-advisory.
|
|
1530
|
+
--stream <name> Optional task-id suffix for the child stream (defaults to the pipeline id).
|
|
1531
|
+
--format json Emit machine-readable output.
|
|
1532
|
+
|
|
1533
|
+
child-lane
|
|
1534
|
+
--action <mode> launch, accept, reject, or invalidate.
|
|
1535
|
+
--stream <name> Lane stream name / task-id suffix.
|
|
1536
|
+
--purpose <text> Required for launch: bounded lane objective.
|
|
1537
|
+
--files <csv> Optional comma-separated file ownership scope.
|
|
1538
|
+
--phases <csv> Optional comma-separated phase ownership scope.
|
|
1539
|
+
--instructions <text> Optional extra bounded instructions for launch.
|
|
1540
|
+
--instructions-file <path>
|
|
1541
|
+
Optional file containing extra bounded instructions for launch.
|
|
1542
|
+
--reason <text> Optional parent decision rationale for accept/reject/invalidate.
|
|
1543
|
+
--format json Emit machine-readable output.
|
|
1544
|
+
`);
|
|
1545
|
+
}
|
|
2242
1546
|
function printCodexHelp() {
|
|
2243
1547
|
console.log(`Usage: codex-orchestrator codex <subcommand> [options]
|
|
2244
1548
|
|
|
@@ -2255,6 +1559,7 @@ Subcommands:
|
|
|
2255
1559
|
defaults Plan/apply additive global Codex defaults in ~/.codex/config.toml.
|
|
2256
1560
|
--yes Apply setup (otherwise dry-run plan only).
|
|
2257
1561
|
--force Overwrite existing role files in ~/.codex/agents.
|
|
1562
|
+
--auth-scope <portable|chatgpt> Select portable defaults or validated ChatGPT-auth gpt-5.5 defaults.
|
|
2258
1563
|
--format json Emit machine-readable output.
|
|
2259
1564
|
`);
|
|
2260
1565
|
}
|
|
@@ -2268,6 +1573,158 @@ Options:
|
|
|
2268
1573
|
--format json Emit machine-readable status output.
|
|
2269
1574
|
`);
|
|
2270
1575
|
}
|
|
1576
|
+
function printControlHostHelp() {
|
|
1577
|
+
console.log(`Usage:
|
|
1578
|
+
codex-orchestrator control-host [options]
|
|
1579
|
+
codex-orchestrator control-host freshness-gauge [options]
|
|
1580
|
+
codex-orchestrator control-host supervise <install|status|restart|uninstall|run> [options]
|
|
1581
|
+
|
|
1582
|
+
Options:
|
|
1583
|
+
--task <id> Artifact task id for the host state (default: local-mcp).
|
|
1584
|
+
--run <id> Host run id for persisted state files (default: control-host).
|
|
1585
|
+
--pipeline <id> Pipeline used for provider-driven starts (default: ${DEFAULT_PROVIDER_START_PIPELINE_ID}).
|
|
1586
|
+
--format json Emit the startup readiness payload to stdout, then keep the host running.
|
|
1587
|
+
--help Show this message.
|
|
1588
|
+
|
|
1589
|
+
Read-only gauge subcommand:
|
|
1590
|
+
freshness-gauge Replay existing local/sanitized artifacts and classify provider/control-host freshness.
|
|
1591
|
+
|
|
1592
|
+
Supervision subcommands:
|
|
1593
|
+
supervise install Install a launchd LaunchAgent-backed local control-host supervisor.
|
|
1594
|
+
supervise status Show the installed launchd/config/state status.
|
|
1595
|
+
supervise restart Restart the installed control-host supervisor.
|
|
1596
|
+
supervise uninstall Remove the installed launchd supervisor and generated artifacts.
|
|
1597
|
+
supervise run Internal long-lived runner for launchd ProgramArguments.
|
|
1598
|
+
`);
|
|
1599
|
+
}
|
|
1600
|
+
function printControlHostFreshnessGaugeHelp() {
|
|
1601
|
+
console.log(`Usage: codex-orchestrator control-host freshness-gauge [options]
|
|
1602
|
+
|
|
1603
|
+
Replay existing provider/control-host artifacts without starting a host or polling Linear/GitHub.
|
|
1604
|
+
|
|
1605
|
+
Options:
|
|
1606
|
+
--artifact-root <path> Directory to scan for local artifacts (required unless explicit paths are provided).
|
|
1607
|
+
--run-dir <path> Alias for --artifact-root when checking one run directory.
|
|
1608
|
+
--provider-intake-state <csv> Explicit provider-intake-state.json path(s).
|
|
1609
|
+
--provider-manifest <csv> Explicit manifest.json path(s).
|
|
1610
|
+
--provider-proof <csv> Explicit provider-linear-worker-proof.json path(s).
|
|
1611
|
+
--worker-audit-jsonl <csv> Explicit provider worker audit JSONL path(s).
|
|
1612
|
+
--control-endpoint-metadata <csv> Explicit control endpoint metadata path(s).
|
|
1613
|
+
--status-dataset <csv> Explicit CO STATUS/status dataset path(s).
|
|
1614
|
+
--polling-health <csv> Explicit provider polling health path(s).
|
|
1615
|
+
--linear-budget-state <csv> Explicit Linear shared-budget state path(s).
|
|
1616
|
+
--now <iso> Deterministic reference time for age/latency calculations.
|
|
1617
|
+
--strict Exit non-zero when the verdict is stale or contradictory.
|
|
1618
|
+
--max-depth <n> Recursive artifact scan depth (default: 8).
|
|
1619
|
+
--stale-refresh-after-ms <n> Refresh age threshold (default: 300000).
|
|
1620
|
+
--stale-heartbeat-after-ms <n> Active heartbeat age threshold (default: 600000).
|
|
1621
|
+
--stale-retry-after-ms <n> Retry/backoff overdue threshold (default: 600000).
|
|
1622
|
+
--stale-claim-queue-after-ms <n> Claim queue age threshold (default: 1800000).
|
|
1623
|
+
--claim-to-start-degraded-after-ms <n> Claim-to-start degraded threshold (default: 300000).
|
|
1624
|
+
--start-to-heartbeat-degraded-after-ms <n> Start-to-first-heartbeat degraded threshold (default: 120000).
|
|
1625
|
+
--linear-headroom-low-ratio <n> Low Linear shared-budget remaining ratio (default: 0.05).
|
|
1626
|
+
--child-lane-cap <n> Same-parent active/pending child-lane cap (default: 2).
|
|
1627
|
+
--format json Emit machine-readable gauge output.
|
|
1628
|
+
--help Show this message.
|
|
1629
|
+
`);
|
|
1630
|
+
}
|
|
1631
|
+
function printControlHostSupervisionHelp() {
|
|
1632
|
+
console.log(`Usage: codex-orchestrator control-host supervise <install|status|restart|uninstall|run> [options]
|
|
1633
|
+
|
|
1634
|
+
Subcommands:
|
|
1635
|
+
install Install the macOS launchd LaunchAgent plus generated config/state files.
|
|
1636
|
+
status Show the current install, launchctl, and restart-reason state.
|
|
1637
|
+
restart Kickstart the installed launchd service.
|
|
1638
|
+
uninstall Boot out the launchd service and remove generated artifacts.
|
|
1639
|
+
run Internal long-lived supervision runner for launchd use.
|
|
1640
|
+
|
|
1641
|
+
Common options:
|
|
1642
|
+
--label <value> LaunchAgent label (default: com.kbediako.co.control-host).
|
|
1643
|
+
--config <path> Explicit config path for status, restart, uninstall, or run.
|
|
1644
|
+
--format json Emit machine-readable output for install, status, restart, or uninstall.
|
|
1645
|
+
|
|
1646
|
+
Install options:
|
|
1647
|
+
--repo-root <path> Repo root used as the supervised control-host working directory.
|
|
1648
|
+
--node <path> Explicit Node executable for launchd ProgramArguments.
|
|
1649
|
+
--cli-entrypoint <path> Explicit codex-orchestrator JS entrypoint for launchd ProgramArguments.
|
|
1650
|
+
--task <id> Control-host task id (default: local-mcp).
|
|
1651
|
+
--run <id> Control-host run id (default: control-host).
|
|
1652
|
+
--pipeline <id> Provider start pipeline (default: provider-linear-worker).
|
|
1653
|
+
--health-interval <sec> Health poll interval in seconds (default: 30).
|
|
1654
|
+
--unhealthy-threshold <n> Consecutive unhealthy samples before launchd restart (default: 3).
|
|
1655
|
+
--launchd-throttle <sec> LaunchAgent ThrottleInterval value (default: 15).
|
|
1656
|
+
--kill-timeout <sec> Grace period before force-killing the child host (default: 10).
|
|
1657
|
+
--env-files <csv|none> Comma-separated env/bootstrap files to source before launch.
|
|
1658
|
+
--shell <path> Shell used to source env/bootstrap files (default: $SHELL or /bin/zsh).
|
|
1659
|
+
`);
|
|
1660
|
+
}
|
|
1661
|
+
function printCoStatusHelp() {
|
|
1662
|
+
console.log(`Usage:
|
|
1663
|
+
codex-orchestrator co-status [options]
|
|
1664
|
+
codex-orchestrator co-status attach [options]
|
|
1665
|
+
codex-orchestrator co-status operator-autopilot local-rollout <acknowledge|clear|dismiss> [options]
|
|
1666
|
+
|
|
1667
|
+
Attach the CO STATUS terminal viewer to an already-running local JSON control-host,
|
|
1668
|
+
or emit the current CO STATUS snapshot from that host in JSON mode.
|
|
1669
|
+
|
|
1670
|
+
Viewer options:
|
|
1671
|
+
--task <id> Artifact task id for the host state (default: local-mcp).
|
|
1672
|
+
--run <id> Host run id for persisted state files (default: control-host).
|
|
1673
|
+
--format json Emit the current CO STATUS snapshot from the local control-host and exit.
|
|
1674
|
+
--help Show this message.
|
|
1675
|
+
|
|
1676
|
+
JSON contract:
|
|
1677
|
+
co-status --format json reads the authenticated operator-dashboard snapshot from the
|
|
1678
|
+
current local control-host and exits. Use \`control-host --format json\` for startup readiness output.
|
|
1679
|
+
|
|
1680
|
+
Attach subcommand:
|
|
1681
|
+
attach Attach to an already-running local JSON control-host.
|
|
1682
|
+
Run \`codex-orchestrator co-status attach --help\` for attach flags.
|
|
1683
|
+
|
|
1684
|
+
Operator autopilot lifecycle:
|
|
1685
|
+
operator-autopilot Acknowledge, clear, or dismiss a pending local rollout action.
|
|
1686
|
+
Run \`codex-orchestrator co-status operator-autopilot --help\` for lifecycle flags.
|
|
1687
|
+
`);
|
|
1688
|
+
}
|
|
1689
|
+
function printCoStatusOperatorAutopilotHelp() {
|
|
1690
|
+
console.log(`Usage: codex-orchestrator co-status operator-autopilot local-rollout <acknowledge|clear|dismiss> [options]
|
|
1691
|
+
|
|
1692
|
+
Record durable lifecycle metadata for one pending operator-autopilot local rollout
|
|
1693
|
+
action from an already-running local JSON control-host.
|
|
1694
|
+
|
|
1695
|
+
Options:
|
|
1696
|
+
--issue <id|identifier> Pending Linear issue id or identifier to match.
|
|
1697
|
+
--action-id <id> Stable local rollout action instance id to match.
|
|
1698
|
+
--actor <name> Operator recording the lifecycle event (default: current user).
|
|
1699
|
+
--reason <text> Required reason for the lifecycle event.
|
|
1700
|
+
--task <id> Artifact task id for the host state (default: local-mcp).
|
|
1701
|
+
--run <id> Host run id for persisted state files (default: control-host).
|
|
1702
|
+
--run-dir <path> Resolve the host from a specific existing run directory.
|
|
1703
|
+
--manifest-path <path> Resolve the host from an explicit manifest.json path.
|
|
1704
|
+
--format json Emit machine-readable lifecycle output.
|
|
1705
|
+
--help Show this message.
|
|
1706
|
+
`);
|
|
1707
|
+
}
|
|
1708
|
+
function printCoStatusAttachHelp() {
|
|
1709
|
+
console.log(`Usage: codex-orchestrator co-status attach [options]
|
|
1710
|
+
|
|
1711
|
+
Attach a read-only CO STATUS viewer to an already-running local JSON control-host.
|
|
1712
|
+
This reads persisted endpoint/auth artifacts and does not start another control-host,
|
|
1713
|
+
Linear poller, or Telegram poller.
|
|
1714
|
+
If the supervised control-host restarts and rotates control_endpoint.json while
|
|
1715
|
+
attached, the viewer re-resolves the endpoint on fetch failures and reports
|
|
1716
|
+
stale endpoint, unavailable host, auth, and timeout guidance in the dashboard.
|
|
1717
|
+
|
|
1718
|
+
Options:
|
|
1719
|
+
--task <id> Artifact task id for the host state (default: local-mcp).
|
|
1720
|
+
--run <id> Host run id for persisted state files (default: control-host).
|
|
1721
|
+
--run-dir <path> Resolve the host from a specific existing run directory.
|
|
1722
|
+
--manifest-path <path> Resolve the host from an explicit manifest.json path.
|
|
1723
|
+
--refresh-interval-ms <n> Viewer refresh interval in milliseconds (default: 1000).
|
|
1724
|
+
--format json Emit machine-readable attach target output instead of launching the viewer.
|
|
1725
|
+
--help Show this message.
|
|
1726
|
+
`);
|
|
1727
|
+
}
|
|
2271
1728
|
function printResumeHelp() {
|
|
2272
1729
|
console.log(`Usage: codex-orchestrator resume --run <id> [options]
|
|
2273
1730
|
|
|
@@ -2284,12 +1741,43 @@ Options:
|
|
|
2284
1741
|
--no-interactive Force disable HUD.
|
|
2285
1742
|
`);
|
|
2286
1743
|
}
|
|
1744
|
+
function printDoctorHelp() {
|
|
1745
|
+
console.log(`Usage: codex-orchestrator doctor [options]
|
|
1746
|
+
|
|
1747
|
+
Inspect the current repo/user environment for downstream readiness:
|
|
1748
|
+
- packaged and seeded provider onboarding files
|
|
1749
|
+
- DevTools + delegation MCP wiring
|
|
1750
|
+
- Codex defaults and current CLI posture
|
|
1751
|
+
- optional local usage and cloud preflight checks
|
|
1752
|
+
|
|
1753
|
+
Options:
|
|
1754
|
+
--format json Emit machine-readable output (not supported with --apply).
|
|
1755
|
+
--usage Include a local usage snapshot (scans .runs/).
|
|
1756
|
+
--window-days <n> Window for --usage (default 30).
|
|
1757
|
+
--task <id> Limit --usage scan to a specific task directory.
|
|
1758
|
+
--cloud-preflight Run cloud readiness preflight checks (env/codex/git/branch).
|
|
1759
|
+
--cloud-env-id <id> Override env id for --cloud-preflight (default: CODEX_CLOUD_ENV_ID).
|
|
1760
|
+
--cloud-branch <name> Override branch for --cloud-preflight (default: CODEX_CLOUD_BRANCH).
|
|
1761
|
+
--issue-log Append markdown issue entry + JSON bundle for downstream triage.
|
|
1762
|
+
--issue-title <text> Optional title for --issue-log entries.
|
|
1763
|
+
--issue-notes <text> Optional notes for --issue-log entries.
|
|
1764
|
+
--issue-log-path <p> Output markdown path (default: docs/codex-orchestrator-issues.md).
|
|
1765
|
+
--apply Plan/apply quick fixes for DevTools + delegation wiring (use with --yes).
|
|
1766
|
+
--yes Apply fixes when --apply is set.
|
|
1767
|
+
--help Show this message.
|
|
1768
|
+
|
|
1769
|
+
Examples:
|
|
1770
|
+
codex-orchestrator doctor --format json
|
|
1771
|
+
codex-orchestrator doctor --usage --window-days 30
|
|
1772
|
+
codex-orchestrator doctor --cloud-preflight --cloud-env-id <env-id> --cloud-branch main
|
|
1773
|
+
`);
|
|
1774
|
+
}
|
|
2287
1775
|
function printDelegationServerHelp() {
|
|
2288
1776
|
console.log(`Usage: codex-orchestrator delegate-server [options]
|
|
2289
1777
|
|
|
2290
1778
|
Options:
|
|
2291
1779
|
--repo <path> Repo root for config + manifests (default cwd).
|
|
2292
|
-
--mode <full|question_only> Limit tool surface for child runs.
|
|
1780
|
+
--mode <full|question_only|status_only> Limit tool surface for child runs.
|
|
2293
1781
|
--config "<key>=<value>[;...]" Apply config overrides.
|
|
2294
1782
|
--help Show this message.
|
|
2295
1783
|
`);
|
|
@@ -2316,17 +1804,144 @@ Subcommands:
|
|
|
2316
1804
|
Supports PR_MONITOR_* env vars and standard flags (see: pr watch-merge --help).
|
|
2317
1805
|
resolve-merge Watch for merge readiness but exit early on actionable feedback requiring author response.
|
|
2318
1806
|
Inherits watch-merge flags; defaults exit-on-action-required to on.
|
|
1807
|
+
ready-review Wait through a bounded automated-feedback drain before review handoff.
|
|
1808
|
+
Reuses watch-merge polling, treats REVIEW_REQUIRED as informational, and defaults exit-on-action-required to on.
|
|
2319
1809
|
|
|
2320
1810
|
Examples:
|
|
2321
1811
|
codex-orchestrator pr watch-merge --pr 211 --dry-run --quiet-minutes 10
|
|
2322
1812
|
codex-orchestrator pr watch-merge --pr 211 --auto-merge --merge-method squash
|
|
2323
1813
|
codex-orchestrator pr resolve-merge --pr 211 --quiet-minutes 15
|
|
2324
1814
|
codex-orchestrator pr resolve-merge --pr 211 --auto-merge --quiet-minutes 10
|
|
1815
|
+
codex-orchestrator pr ready-review --pr 211 --quiet-minutes 15 --timeout-minutes 20
|
|
2325
1816
|
|
|
2326
1817
|
Guide:
|
|
2327
1818
|
Review artifacts (prompt + output log paths): docs/guides/review-artifacts.md
|
|
2328
1819
|
`);
|
|
2329
1820
|
}
|
|
1821
|
+
function isCliHelpToken(value) {
|
|
1822
|
+
return value === '--help' || value === '-h' || value === 'help';
|
|
1823
|
+
}
|
|
1824
|
+
function envFlagEnabled(value, fallback = false) {
|
|
1825
|
+
if (value === undefined || value === null) {
|
|
1826
|
+
return fallback;
|
|
1827
|
+
}
|
|
1828
|
+
const normalized = value.trim().toLowerCase();
|
|
1829
|
+
if (normalized.length === 0) {
|
|
1830
|
+
return fallback;
|
|
1831
|
+
}
|
|
1832
|
+
if (normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on') {
|
|
1833
|
+
return true;
|
|
1834
|
+
}
|
|
1835
|
+
if (normalized === '0' || normalized === 'false' || normalized === 'no' || normalized === 'off') {
|
|
1836
|
+
return false;
|
|
1837
|
+
}
|
|
1838
|
+
return fallback;
|
|
1839
|
+
}
|
|
1840
|
+
function isPrHelpSubcommand(value) {
|
|
1841
|
+
return value === 'watch-merge' || value === 'resolve-merge' || value === 'ready-review';
|
|
1842
|
+
}
|
|
1843
|
+
function shouldPrintPrSubcommandHelp(args) {
|
|
1844
|
+
if (args.length === 0) {
|
|
1845
|
+
return false;
|
|
1846
|
+
}
|
|
1847
|
+
if (args[0] === 'help') {
|
|
1848
|
+
return true;
|
|
1849
|
+
}
|
|
1850
|
+
return args.some((arg) => arg === '--help' || arg === '-h');
|
|
1851
|
+
}
|
|
1852
|
+
function printPrSubcommandHelp(subcommand) {
|
|
1853
|
+
const defaultAutoMerge = envFlagEnabled(process.env.PR_MONITOR_AUTO_MERGE, false);
|
|
1854
|
+
switch (subcommand) {
|
|
1855
|
+
case 'watch-merge':
|
|
1856
|
+
console.log(`Usage: codex-orchestrator pr watch-merge [options]
|
|
1857
|
+
|
|
1858
|
+
Monitor PR checks/reviews with polling and optionally merge after a quiet window.
|
|
1859
|
+
|
|
1860
|
+
Options:
|
|
1861
|
+
--pr <number> PR number (default: PR for current branch)
|
|
1862
|
+
--owner <name> Repo owner (default: inferred via gh repo view)
|
|
1863
|
+
--repo <name> Repo name (default: inferred via gh repo view)
|
|
1864
|
+
--interval-seconds <n> Poll interval in seconds (default: 30)
|
|
1865
|
+
--quiet-minutes <n> Required quiet window after ready state (default: 15)
|
|
1866
|
+
--timeout-minutes <n> Max monitor duration before failing (default: 180)
|
|
1867
|
+
--merge-method <method> merge|squash|rebase (default: squash)
|
|
1868
|
+
--auto-merge Merge automatically after quiet window
|
|
1869
|
+
--no-auto-merge Never merge automatically (monitor only)
|
|
1870
|
+
--delete-branch Delete remote branch when merging
|
|
1871
|
+
--no-delete-branch Keep remote branch after merge
|
|
1872
|
+
--exit-on-action-required Exit non-zero when author action is required
|
|
1873
|
+
--no-exit-on-action-required Keep monitoring even when author action is required
|
|
1874
|
+
--dry-run Never call gh pr merge (report only)
|
|
1875
|
+
-h, --help Show this help message
|
|
1876
|
+
|
|
1877
|
+
Environment:
|
|
1878
|
+
PR_MONITOR_QUIET_MINUTES=<n> Override quiet window default
|
|
1879
|
+
PR_MONITOR_INTERVAL_SECONDS=<n>
|
|
1880
|
+
PR_MONITOR_TIMEOUT_MINUTES=<n>
|
|
1881
|
+
PR_MONITOR_AUTO_MERGE=1 Default auto-merge on (current default: ${defaultAutoMerge ? 'on' : 'off'})
|
|
1882
|
+
PR_MONITOR_DELETE_BRANCH=1 Default delete branch on merge
|
|
1883
|
+
PR_MONITOR_MERGE_METHOD=<method>
|
|
1884
|
+
`);
|
|
1885
|
+
return;
|
|
1886
|
+
case 'resolve-merge':
|
|
1887
|
+
console.log(`Usage: codex-orchestrator pr resolve-merge [options]
|
|
1888
|
+
|
|
1889
|
+
Monitor until merge-ready or actionable feedback appears; exits early when author action is required.
|
|
1890
|
+
|
|
1891
|
+
Options:
|
|
1892
|
+
--pr <number> PR number (default: PR for current branch)
|
|
1893
|
+
--owner <name> Repo owner (default: inferred via gh repo view)
|
|
1894
|
+
--repo <name> Repo name (default: inferred via gh repo view)
|
|
1895
|
+
--interval-seconds <n> Poll interval in seconds (default: 30)
|
|
1896
|
+
--quiet-minutes <n> Required quiet window after ready state (default: 15)
|
|
1897
|
+
--timeout-minutes <n> Max monitor duration before failing (default: 180)
|
|
1898
|
+
--merge-method <method> merge|squash|rebase (default: squash)
|
|
1899
|
+
--auto-merge Merge automatically after quiet window
|
|
1900
|
+
--no-auto-merge Never merge automatically (monitor only)
|
|
1901
|
+
--delete-branch Delete remote branch when merging
|
|
1902
|
+
--no-delete-branch Keep remote branch after merge
|
|
1903
|
+
--exit-on-action-required Exit non-zero when author action is required
|
|
1904
|
+
--no-exit-on-action-required Keep monitoring even when author action is required
|
|
1905
|
+
--dry-run Never call gh pr merge (report only)
|
|
1906
|
+
-h, --help Show this help message
|
|
1907
|
+
|
|
1908
|
+
Environment:
|
|
1909
|
+
PR_MONITOR_QUIET_MINUTES=<n> Override quiet window default
|
|
1910
|
+
PR_MONITOR_INTERVAL_SECONDS=<n>
|
|
1911
|
+
PR_MONITOR_TIMEOUT_MINUTES=<n>
|
|
1912
|
+
PR_MONITOR_AUTO_MERGE=1 Default auto-merge on (current default: ${defaultAutoMerge ? 'on' : 'off'})
|
|
1913
|
+
PR_MONITOR_DELETE_BRANCH=1 Default delete branch on merge
|
|
1914
|
+
PR_MONITOR_MERGE_METHOD=<method>
|
|
1915
|
+
resolve-merge default: exit-on-action-required is on
|
|
1916
|
+
`);
|
|
1917
|
+
return;
|
|
1918
|
+
case 'ready-review':
|
|
1919
|
+
console.log(`Usage: codex-orchestrator pr ready-review [options]
|
|
1920
|
+
|
|
1921
|
+
Monitor PR checks/reviews with polling and report when review handoff is safe after a bounded automated-feedback drain.
|
|
1922
|
+
|
|
1923
|
+
Options:
|
|
1924
|
+
--pr <number> PR number (default: PR for current branch)
|
|
1925
|
+
--owner <name> Repo owner (default: inferred via gh repo view)
|
|
1926
|
+
--repo <name> Repo name (default: inferred via gh repo view)
|
|
1927
|
+
--interval-seconds <n> Poll interval in seconds (default: 30)
|
|
1928
|
+
--quiet-minutes <n> Required quiet window after ready state (default: 15)
|
|
1929
|
+
--timeout-minutes <n> Max monitor duration before failing (default: 180)
|
|
1930
|
+
--exit-on-action-required Exit non-zero when author action is required
|
|
1931
|
+
--no-exit-on-action-required Keep monitoring even when author action is required
|
|
1932
|
+
--dry-run Never call gh pr merge (report only)
|
|
1933
|
+
-h, --help Show this help message
|
|
1934
|
+
|
|
1935
|
+
Environment:
|
|
1936
|
+
PR_MONITOR_QUIET_MINUTES=<n> Override quiet window default
|
|
1937
|
+
PR_MONITOR_INTERVAL_SECONDS=<n>
|
|
1938
|
+
PR_MONITOR_TIMEOUT_MINUTES=<n>
|
|
1939
|
+
ready-review default: exit-on-action-required is on
|
|
1940
|
+
ready-review treats REVIEW_REQUIRED as informational; CHANGES_REQUESTED and actionable machine feedback still block handoff.
|
|
1941
|
+
`);
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
2330
1945
|
function printRlmHelp() {
|
|
2331
1946
|
console.log(`Usage: codex-orchestrator rlm "<goal>" [options]
|
|
2332
1947
|
|
|
@@ -2356,6 +1971,29 @@ Tips:
|
|
|
2356
1971
|
- Ensure multi-agent is enabled in Codex: codex features enable multi_agent (legacy alias: collab).
|
|
2357
1972
|
`);
|
|
2358
1973
|
}
|
|
1974
|
+
function printFrontendTestHelp() {
|
|
1975
|
+
console.log(`Usage: codex-orchestrator frontend-test [options]
|
|
1976
|
+
|
|
1977
|
+
Runs the frontend-testing pipeline.
|
|
1978
|
+
|
|
1979
|
+
Options:
|
|
1980
|
+
--devtools Enable Chrome DevTools MCP for this run.
|
|
1981
|
+
--task <id> Override task identifier (defaults to MCP_RUNNER_TASK_ID).
|
|
1982
|
+
--runtime-mode <cli|appserver> Force runtime mode for this run.
|
|
1983
|
+
--repo-config-required [true|false] Require repo-local codex.orchestrator.json (no package fallback).
|
|
1984
|
+
--parent-run <id> Link run to parent run id.
|
|
1985
|
+
--approval-policy <p> Record approval policy metadata.
|
|
1986
|
+
--format json Emit machine-readable output.
|
|
1987
|
+
--target <stage-id> Focus plan/build metadata on a specific stage (alias: --target-stage).
|
|
1988
|
+
--interactive | --ui Enable read-only HUD when running in a TTY.
|
|
1989
|
+
--no-interactive Force disable HUD.
|
|
1990
|
+
--help Show this message.
|
|
1991
|
+
|
|
1992
|
+
Examples:
|
|
1993
|
+
codex-orchestrator frontend-test
|
|
1994
|
+
codex-orchestrator frontend-test --devtools --format json
|
|
1995
|
+
`);
|
|
1996
|
+
}
|
|
2359
1997
|
function printFlowHelp() {
|
|
2360
1998
|
console.log(`Usage: codex-orchestrator flow [options]
|
|
2361
1999
|
|
|
@@ -2393,6 +2031,7 @@ Common options:
|
|
|
2393
2031
|
--manifest <path> Explicit manifest path for review evidence.
|
|
2394
2032
|
--runs-dir <path> Root runs directory when auto-resolving manifest.
|
|
2395
2033
|
--task <id> Task id used for prompt context.
|
|
2034
|
+
--surface <diff|audit|architecture> Select review surface (default: diff).
|
|
2396
2035
|
--uncommitted Review uncommitted diff scope.
|
|
2397
2036
|
--base <branch> Review against a base branch.
|
|
2398
2037
|
--commit <sha> Review a specific commit.
|
|
@@ -2425,6 +2064,10 @@ Options:
|
|
|
2425
2064
|
--task <id> Override task identifier.
|
|
2426
2065
|
--parent-run <id> Link run to parent run id.
|
|
2427
2066
|
--approval-policy <p> Record approval policy metadata.
|
|
2067
|
+
--issue-provider <name> Persist provider identity for autonomous intake handoff.
|
|
2068
|
+
--issue-id <id> Persist provider issue id on the run manifest.
|
|
2069
|
+
--issue-identifier <id> Persist human issue identifier on the run manifest.
|
|
2070
|
+
--issue-updated-at <iso> Persist provider issue updated timestamp on the run manifest.
|
|
2428
2071
|
--format json Emit machine-readable output.
|
|
2429
2072
|
--execution-mode <mcp|cloud> Force execution mode for this run.
|
|
2430
2073
|
--cloud Shortcut for --execution-mode cloud.
|