@kbediako/codex-orchestrator 0.1.38 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +20 -0
- package/README.md +70 -301
- package/bin/codex-orchestrator.js +161 -0
- package/codex.orchestrator.json +149 -13
- package/dist/bin/codex-orchestrator.js +795 -1154
- 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 +183 -11
- package/dist/orchestrator/src/cli/coStatusAttachCliShell.js +402 -0
- package/dist/orchestrator/src/cli/coStatusCliShell.js +429 -0
- package/dist/orchestrator/src/cli/coStatusOperatorAutopilotCliShell.js +120 -0
- package/dist/orchestrator/src/cli/codexCliShell.js +72 -0
- package/dist/orchestrator/src/cli/codexDefaultsSetup.js +49 -11
- 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 +608 -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 +992 -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 +1899 -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 +1838 -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 +542 -122
- 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 +1 -0
- 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 +1772 -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 +5738 -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 +667 -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 +83 -1
- 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/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 +365 -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/public/downstream-setup.md +106 -0
- package/docs/public/provider-onboarding.md +173 -0
- package/package.json +20 -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 +359 -0
- package/schemas/manifest.json +394 -0
- package/skills/collab-subagents-first/SKILL.md +1 -1
- package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
- package/skills/delegation-usage/SKILL.md +19 -13
- 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 +12 -7
- package/templates/codex/mcp-client.json +5 -1
- package/docs/README.md +0 -310
- package/docs/assets/setup.gif +0 -0
|
@@ -2,18 +2,23 @@ import process from 'node:process';
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
|
+
import { release as osRelease } from 'node:os';
|
|
5
6
|
import { dirname, join, resolve } from 'node:path';
|
|
6
7
|
import { buildDevtoolsSetupPlan, DEVTOOLS_SKILL_NAME, resolveDevtoolsReadiness } from './utils/devtools.js';
|
|
7
8
|
import { isManagedCodexCliEnabled, resolveCodexCliBin, resolveCodexCliReadiness } from './utils/codexCli.js';
|
|
8
9
|
import { resolveCodexHome } from './utils/codexPaths.js';
|
|
9
10
|
import { resolveOptionalDependency } from './utils/optionalDeps.js';
|
|
10
|
-
import { runCloudPreflight } from './utils/cloudPreflight.js';
|
|
11
|
-
import {
|
|
11
|
+
import { buildCloudPreflightAuthProvenance, buildCloudPreflightRequest, runCloudPreflight } from './utils/cloudPreflight.js';
|
|
12
|
+
import { classifyDelegationTransport, formatDelegateServerProcessSummary, inspectDelegateServerProcesses, inspectDelegationMcpConfig, probeDelegationInitialize, resolveDelegationServerInvocation } from './utils/delegationMcpHealth.js';
|
|
13
|
+
import { sanitizeProviderOverrideEnv } from './utils/providerOverrideEnv.js';
|
|
14
|
+
import { hasLinearApiCredentials, hasLinearSourceBinding, resolveLinearSourceSetup } from './control/linearDispatchSource.js';
|
|
15
|
+
import { normalizeDispatchSourceProvider } from './control/trackerDispatchPilot.js';
|
|
16
|
+
import { BASELINE_AGENTS, BASELINE_MODEL, BASELINE_REVIEW_MODEL, BASELINE_REASONING_MINIMUM } from './codexDefaultsSetup.js';
|
|
12
17
|
import { CommandPlanner } from './adapters/CommandPlanner.js';
|
|
13
18
|
import { PipelineResolver } from './services/pipelineResolver.js';
|
|
14
19
|
import { isRepoConfigRequired } from './config/repoConfigPolicy.js';
|
|
15
20
|
const require = createRequire(import.meta.url);
|
|
16
|
-
|
|
21
|
+
let tomlParser;
|
|
17
22
|
const OPTIONAL_DEPENDENCIES = [
|
|
18
23
|
{
|
|
19
24
|
name: 'playwright',
|
|
@@ -23,6 +28,7 @@ const OPTIONAL_DEPENDENCIES = [
|
|
|
23
28
|
{ name: 'pixelmatch', install: 'npm install --save-dev pixelmatch' },
|
|
24
29
|
{ name: 'cheerio', install: 'npm install --save-dev cheerio' }
|
|
25
30
|
];
|
|
31
|
+
const PROVIDER_ROOT_RELATIVE_PATH = '.codex/providers';
|
|
26
32
|
export function runDoctor(cwd = process.cwd()) {
|
|
27
33
|
const dependencies = OPTIONAL_DEPENDENCIES.map((entry) => {
|
|
28
34
|
const resolved = resolveOptionalDependency(entry.name, cwd);
|
|
@@ -104,10 +110,30 @@ export function runDoctor(cwd = process.cwd()) {
|
|
|
104
110
|
: null;
|
|
105
111
|
const cloudStatus = !cloudCmdAvailable ? 'unavailable' : cloudEnvIdConfigured ? 'ok' : 'not_configured';
|
|
106
112
|
const cloudFallbackPolicy = resolveCloudFallbackPolicy();
|
|
107
|
-
const
|
|
108
|
-
const
|
|
113
|
+
const repoRoot = resolveDoctorRepoRoot(cwd);
|
|
114
|
+
const delegationSnapshot = inspectDelegationMcpConfig(process.env);
|
|
115
|
+
const delegationTransport = classifyDelegationTransport(delegationSnapshot.entry);
|
|
116
|
+
const delegationStartup = probeDelegationInitialize(delegationSnapshot.entry, { env: process.env });
|
|
117
|
+
const delegationProcesses = inspectDelegateServerProcesses({ repoRoot });
|
|
118
|
+
const delegationStatus = delegationSnapshot.status !== 'ok'
|
|
119
|
+
? 'missing-config'
|
|
120
|
+
: delegationTransport.status !== 'safe'
|
|
121
|
+
|| delegationStartup.status === 'slow'
|
|
122
|
+
|| delegationStartup.status === 'failed'
|
|
123
|
+
|| delegationProcesses.status === 'stale'
|
|
124
|
+
? 'warning'
|
|
125
|
+
: delegationProcesses.status === 'unavailable'
|
|
126
|
+
? 'unavailable'
|
|
127
|
+
: 'ok';
|
|
128
|
+
const delegationBlocksOverallStatus = delegationStatus === 'missing-config';
|
|
129
|
+
const providers = inspectProviderReadiness(repoRoot, process.env);
|
|
109
130
|
return {
|
|
110
|
-
status: missing.length === 0 &&
|
|
131
|
+
status: missing.length === 0 &&
|
|
132
|
+
codexDefaults.status === 'ok' &&
|
|
133
|
+
providers.status === 'ok' &&
|
|
134
|
+
!delegationBlocksOverallStatus
|
|
135
|
+
? 'ok'
|
|
136
|
+
: 'warning',
|
|
111
137
|
missing,
|
|
112
138
|
dependencies,
|
|
113
139
|
devtools,
|
|
@@ -141,24 +167,71 @@ export function runDoctor(cwd = process.cwd()) {
|
|
|
141
167
|
},
|
|
142
168
|
delegation: {
|
|
143
169
|
status: delegationStatus,
|
|
144
|
-
config:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
170
|
+
config: {
|
|
171
|
+
status: delegationSnapshot.status,
|
|
172
|
+
path: delegationSnapshot.path,
|
|
173
|
+
detail: delegationSnapshot.detail,
|
|
174
|
+
source: delegationSnapshot.entry?.source,
|
|
175
|
+
pinned_repo: delegationSnapshot.entry?.pinnedRepo ?? null
|
|
176
|
+
},
|
|
177
|
+
transport: {
|
|
178
|
+
status: delegationTransport.status,
|
|
179
|
+
kind: delegationTransport.kind,
|
|
180
|
+
command_line: delegationTransport.commandLine,
|
|
181
|
+
detail: delegationTransport.detail
|
|
182
|
+
},
|
|
183
|
+
startup: {
|
|
184
|
+
status: delegationStartup.status,
|
|
185
|
+
latency_ms: delegationStartup.latencyMs,
|
|
186
|
+
threshold_ms: delegationStartup.thresholdMs,
|
|
187
|
+
detail: delegationStartup.detail
|
|
188
|
+
},
|
|
189
|
+
processes: {
|
|
190
|
+
status: delegationProcesses.status,
|
|
191
|
+
active_count: delegationProcesses.activeCount,
|
|
192
|
+
active_pids: delegationProcesses.activePids,
|
|
193
|
+
stale_count: delegationProcesses.staleCount,
|
|
194
|
+
stale_pids: delegationProcesses.stalePids,
|
|
195
|
+
stale_rss_mb: Number((delegationProcesses.staleRssKb / 1024).toFixed(1)),
|
|
196
|
+
threshold_minutes: delegationProcesses.thresholdSeconds / 60,
|
|
197
|
+
detail: delegationProcesses.detail,
|
|
198
|
+
details: delegationProcesses.details.map((detail) => ({
|
|
199
|
+
pid: detail.pid,
|
|
200
|
+
ppid: detail.ppid,
|
|
201
|
+
elapsed_seconds: detail.elapsedSeconds,
|
|
202
|
+
rss_mb: Number((detail.rssKb / 1024).toFixed(1)),
|
|
203
|
+
cwd: detail.cwd,
|
|
204
|
+
parent_pid: detail.parentPid,
|
|
205
|
+
parent_cwd: detail.parentCwd,
|
|
206
|
+
root_codex_parent_pid: detail.rootCodexParentPid,
|
|
207
|
+
root_codex_parent_cwd: detail.rootCodexParentCwd,
|
|
208
|
+
classification: detail.classification,
|
|
209
|
+
classification_detail: detail.classificationDetail,
|
|
210
|
+
manifest_path: detail.manifestAssociation?.manifestPath ?? null,
|
|
211
|
+
issue_identifier: detail.manifestAssociation?.issueIdentifier ?? null,
|
|
212
|
+
pipeline_id: detail.manifestAssociation?.pipelineId ?? null,
|
|
213
|
+
task_id: detail.manifestAssociation?.taskId ?? null,
|
|
214
|
+
run_id: detail.manifestAssociation?.runId ?? null,
|
|
215
|
+
status: detail.manifestAssociation?.status ?? null
|
|
216
|
+
}))
|
|
217
|
+
},
|
|
218
|
+
enablement: buildDelegationEnablementGuidance({
|
|
219
|
+
configStatus: delegationSnapshot.status,
|
|
220
|
+
transportStatus: delegationTransport.status,
|
|
221
|
+
directTransportGuidance: buildDelegationDirectTransportGuidance()
|
|
222
|
+
})
|
|
223
|
+
},
|
|
224
|
+
providers
|
|
153
225
|
};
|
|
154
226
|
}
|
|
155
227
|
export async function runDoctorCloudPreflight(options = {}) {
|
|
156
|
-
const env = options.env ?? process.env;
|
|
157
|
-
const
|
|
158
|
-
const
|
|
228
|
+
const env = sanitizeProviderOverrideEnv(options.env ?? process.env);
|
|
229
|
+
const explicitCwd = normalizeOptionalString(options.cwd);
|
|
230
|
+
const cwd = explicitCwd ? resolve(explicitCwd) : process.cwd();
|
|
231
|
+
// An explicit cwd is the caller's repo hint; only fall back to the ambient root override when cwd is implicit.
|
|
232
|
+
const configuredRoot = explicitCwd ? null : normalizeOptionalString(env.CODEX_ORCHESTRATOR_ROOT);
|
|
159
233
|
const rootHint = configuredRoot ? resolve(cwd, configuredRoot) : cwd;
|
|
160
234
|
const repoRoot = resolveDoctorRepoRoot(rootHint);
|
|
161
|
-
const codexBin = resolveCodexCliBin(env);
|
|
162
235
|
const taskId = normalizeOptionalString(options.taskId)
|
|
163
236
|
?? normalizeOptionalString(env.MCP_RUNNER_TASK_ID)
|
|
164
237
|
?? normalizeOptionalString(env.TASK)
|
|
@@ -185,41 +258,113 @@ export async function runDoctorCloudPreflight(options = {}) {
|
|
|
185
258
|
?? planMetadataEnvironmentId
|
|
186
259
|
?? normalizeOptionalString(env.CODEX_CLOUD_ENV_ID)
|
|
187
260
|
?? resolveTaskMetadataCloudEnvironmentId(repoRoot, taskId);
|
|
188
|
-
const
|
|
189
|
-
const preflight = await runCloudPreflight({
|
|
261
|
+
const preflight = await runCloudPreflight(buildCloudPreflightRequest({
|
|
190
262
|
repoRoot,
|
|
191
|
-
codexBin,
|
|
192
263
|
environmentId,
|
|
193
|
-
branch,
|
|
264
|
+
branch: options.branch,
|
|
194
265
|
env
|
|
195
|
-
});
|
|
266
|
+
}));
|
|
267
|
+
const authProvenance = preflight.details.authProvenance ??
|
|
268
|
+
buildCloudPreflightAuthProvenance({
|
|
269
|
+
env,
|
|
270
|
+
environmentId: preflight.details.environmentId,
|
|
271
|
+
branch: preflight.details.branch
|
|
272
|
+
});
|
|
196
273
|
const issues = planMetadataIssue ? [planMetadataIssue, ...preflight.issues] : preflight.issues;
|
|
274
|
+
const securityAdvisories = inspectCodexSandboxSecurityAdvisories({ env });
|
|
197
275
|
const guidance = buildCloudPreflightGuidance(issues);
|
|
198
276
|
return {
|
|
199
277
|
ok: preflight.ok && planMetadataIssue === null,
|
|
200
278
|
details: {
|
|
201
279
|
codex_bin: preflight.details.codexBin,
|
|
202
280
|
environment_id: preflight.details.environmentId,
|
|
203
|
-
branch: preflight.details.branch
|
|
281
|
+
branch: preflight.details.branch,
|
|
282
|
+
auth_provenance: {
|
|
283
|
+
provider_kind: authProvenance.providerKind,
|
|
284
|
+
active_profile_fingerprint: authProvenance.activeProfileFingerprint,
|
|
285
|
+
active_account_fingerprint: authProvenance.activeAccountFingerprint,
|
|
286
|
+
cloud_env_id: authProvenance.cloudEnvId,
|
|
287
|
+
cloud_branch: authProvenance.cloudBranch,
|
|
288
|
+
credential_source: authProvenance.credentialSource,
|
|
289
|
+
auth_freshness: authProvenance.authFreshness
|
|
290
|
+
}
|
|
204
291
|
},
|
|
205
292
|
issues,
|
|
293
|
+
security_advisories: securityAdvisories,
|
|
206
294
|
guidance
|
|
207
295
|
};
|
|
208
296
|
}
|
|
297
|
+
export function inspectCodexSandboxSecurityAdvisories(options = {}) {
|
|
298
|
+
const env = options.env ?? process.env;
|
|
299
|
+
const advisories = [];
|
|
300
|
+
const configPath = join(resolveCodexHome(env), 'config.toml');
|
|
301
|
+
if (existsSync(configPath)) {
|
|
302
|
+
try {
|
|
303
|
+
const raw = readFileSync(configPath, 'utf8');
|
|
304
|
+
const parsed = getTomlParser().parse(raw);
|
|
305
|
+
if (isRecord(parsed)) {
|
|
306
|
+
const sandboxMode = normalizeOptionalString(readStringValue(parsed.sandbox_mode));
|
|
307
|
+
if (sandboxMode === 'danger-full-access') {
|
|
308
|
+
advisories.push({
|
|
309
|
+
code: 'codex_config_danger_full_access',
|
|
310
|
+
scope: 'local-only',
|
|
311
|
+
severity: 'warning',
|
|
312
|
+
message: 'Codex config sets top-level sandbox_mode to danger-full-access.',
|
|
313
|
+
guidance: 'Treat this as a local-only advisory; do not use it to satisfy cloud readiness or weaken CO sandbox defaults.',
|
|
314
|
+
details: {
|
|
315
|
+
path: configPath,
|
|
316
|
+
sandbox_mode: sandboxMode
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
// Existing Codex defaults checks already report invalid TOML; keep this advisory focused on security posture.
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const platform = options.platform ?? process.platform;
|
|
327
|
+
const releaseText = normalizeOptionalString(options.osRelease ?? osRelease());
|
|
328
|
+
if (isWsl1Release(platform, releaseText)) {
|
|
329
|
+
advisories.push({
|
|
330
|
+
code: 'wsl1_bubblewrap_unsupported',
|
|
331
|
+
scope: 'local-only',
|
|
332
|
+
severity: 'warning',
|
|
333
|
+
message: 'WSL1 detected; Codex bubblewrap sandbox behavior is unsupported for this local platform.',
|
|
334
|
+
guidance: 'Run local Codex sandbox checks on WSL2/Linux/macOS, or keep this as a local-only limitation; it is not cloud canary evidence.',
|
|
335
|
+
details: {
|
|
336
|
+
platform,
|
|
337
|
+
os_release: releaseText ?? undefined
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
return advisories;
|
|
342
|
+
}
|
|
343
|
+
function isWsl1Release(platform, releaseText) {
|
|
344
|
+
if (platform !== 'linux' || !releaseText) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
const normalized = releaseText.toLowerCase();
|
|
348
|
+
return normalized.includes('microsoft') && !normalized.includes('microsoft-standard') && !normalized.includes('wsl2');
|
|
349
|
+
}
|
|
209
350
|
function resolveDoctorRepoRoot(cwd) {
|
|
210
351
|
const fallback = resolve(cwd);
|
|
211
352
|
let current = fallback;
|
|
353
|
+
let providerRootCandidate = null;
|
|
212
354
|
while (current) {
|
|
213
355
|
if (existsSync(join(current, 'tasks', 'index.json'))) {
|
|
214
356
|
return current;
|
|
215
357
|
}
|
|
358
|
+
if (!providerRootCandidate && existsSync(join(current, PROVIDER_ROOT_RELATIVE_PATH))) {
|
|
359
|
+
providerRootCandidate = current;
|
|
360
|
+
}
|
|
216
361
|
const parent = dirname(current);
|
|
217
362
|
if (parent === current) {
|
|
218
363
|
break;
|
|
219
364
|
}
|
|
220
365
|
current = parent;
|
|
221
366
|
}
|
|
222
|
-
return fallback;
|
|
367
|
+
return providerRootCandidate ?? fallback;
|
|
223
368
|
}
|
|
224
369
|
export function formatDoctorCloudPreflightSummary(result) {
|
|
225
370
|
const lines = [];
|
|
@@ -227,6 +372,11 @@ export function formatDoctorCloudPreflightSummary(result) {
|
|
|
227
372
|
lines.push(` - codex bin: ${result.details.codex_bin}`);
|
|
228
373
|
lines.push(` - environment id: ${result.details.environment_id ?? '<unset>'}`);
|
|
229
374
|
lines.push(` - branch: ${result.details.branch ?? '<unset>'}`);
|
|
375
|
+
lines.push(` - auth provider: ${result.details.auth_provenance.provider_kind}`);
|
|
376
|
+
lines.push(` - credential source: ${result.details.auth_provenance.credential_source ?? '<none detected>'}`);
|
|
377
|
+
lines.push(` - profile fingerprint: ${result.details.auth_provenance.active_profile_fingerprint ?? '<unset>'}`);
|
|
378
|
+
lines.push(` - account fingerprint: ${result.details.auth_provenance.active_account_fingerprint ?? '<unset>'}`);
|
|
379
|
+
lines.push(` - auth freshness: ${result.details.auth_provenance.auth_freshness}`);
|
|
230
380
|
if (result.issues.length > 0) {
|
|
231
381
|
lines.push(' - issues:');
|
|
232
382
|
for (const issue of result.issues) {
|
|
@@ -239,6 +389,19 @@ export function formatDoctorCloudPreflightSummary(result) {
|
|
|
239
389
|
lines.push(` - ${item}`);
|
|
240
390
|
}
|
|
241
391
|
}
|
|
392
|
+
if (result.security_advisories.length > 0) {
|
|
393
|
+
lines.push(' - sandbox/security advisories:');
|
|
394
|
+
for (const advisory of result.security_advisories) {
|
|
395
|
+
lines.push(` - [${advisory.code}/${advisory.scope}] ${advisory.message}`);
|
|
396
|
+
lines.push(` guidance: ${advisory.guidance}`);
|
|
397
|
+
if (advisory.details?.path) {
|
|
398
|
+
lines.push(` path: ${advisory.details.path}`);
|
|
399
|
+
}
|
|
400
|
+
if (advisory.details?.platform || advisory.details?.os_release) {
|
|
401
|
+
lines.push(` platform: ${advisory.details.platform ?? '<unknown>'}, os_release: ${advisory.details.os_release ?? '<unknown>'}`);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
242
405
|
return lines;
|
|
243
406
|
}
|
|
244
407
|
export function formatDoctorSummary(result) {
|
|
@@ -308,10 +471,13 @@ export function formatDoctorSummary(result) {
|
|
|
308
471
|
lines.push(` detail: ${result.codex_defaults.config.detail}`);
|
|
309
472
|
}
|
|
310
473
|
lines.push(` - model: ${result.codex_defaults.checks.model.status} (actual: ${result.codex_defaults.checks.model.actual ?? '<unset>'}, expected: ${result.codex_defaults.checks.model.expected})`);
|
|
474
|
+
lines.push(` - review_model: ${result.codex_defaults.checks.review_model.status} (actual: ${result.codex_defaults.checks.review_model.actual ?? '<unset>'}, expected: ${result.codex_defaults.checks.review_model.expected})`);
|
|
311
475
|
lines.push(` - model_reasoning_effort: ${result.codex_defaults.checks.model_reasoning_effort.status} (actual: ${result.codex_defaults.checks.model_reasoning_effort.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.model_reasoning_effort.expected_minimum})`);
|
|
312
476
|
lines.push(` - agents.max_threads: ${result.codex_defaults.checks.max_threads.status} (actual: ${result.codex_defaults.checks.max_threads.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_threads.expected_minimum})`);
|
|
313
|
-
lines.push(` - agents.max_depth: ${result.codex_defaults.checks.max_depth.status} (actual: ${result.codex_defaults.checks.max_depth.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_depth.expected_minimum})`);
|
|
314
|
-
|
|
477
|
+
lines.push(` - agents.max_depth: ${result.codex_defaults.checks.max_depth.status} (actual: ${result.codex_defaults.checks.max_depth.actual ?? '<unset>'}, expected >= ${result.codex_defaults.checks.max_depth.expected_minimum} when set; <unset> accepted)`);
|
|
478
|
+
if (result.codex_defaults.legacy_max_spawn_depth?.present) {
|
|
479
|
+
lines.push(` - legacy agents.max_spawn_depth: ${result.codex_defaults.legacy_max_spawn_depth.status} (actual: ${result.codex_defaults.legacy_max_spawn_depth.actual ?? '<unset>'}; ${result.codex_defaults.legacy_max_spawn_depth.detail})`);
|
|
480
|
+
}
|
|
315
481
|
for (const line of result.codex_defaults.guidance) {
|
|
316
482
|
lines.push(` - ${line}`);
|
|
317
483
|
}
|
|
@@ -340,23 +506,176 @@ export function formatDoctorSummary(result) {
|
|
|
340
506
|
if (result.delegation.config.detail) {
|
|
341
507
|
lines.push(` detail: ${result.delegation.config.detail}`);
|
|
342
508
|
}
|
|
509
|
+
if (result.delegation.config.source) {
|
|
510
|
+
lines.push(` - source: ${result.delegation.config.source}`);
|
|
511
|
+
}
|
|
512
|
+
lines.push(` - transport: ${result.delegation.transport.status} (${result.delegation.transport.kind})`);
|
|
513
|
+
if (result.delegation.transport.command_line) {
|
|
514
|
+
lines.push(` command: ${result.delegation.transport.command_line}`);
|
|
515
|
+
}
|
|
516
|
+
lines.push(` detail: ${result.delegation.transport.detail}`);
|
|
517
|
+
lines.push(` - initialize: ${result.delegation.startup.status} (latency: ${result.delegation.startup.latency_ms ?? '<skipped>'} ms, threshold: ${result.delegation.startup.threshold_ms} ms)`);
|
|
518
|
+
lines.push(` detail: ${result.delegation.startup.detail}`);
|
|
519
|
+
lines.push(` - processes: ${result.delegation.processes.status} (active: ${result.delegation.processes.active_count}, stale: ${result.delegation.processes.stale_count}, stale rss: ${result.delegation.processes.stale_rss_mb.toFixed(1)} MB)`);
|
|
520
|
+
lines.push(` detail: ${result.delegation.processes.detail}`);
|
|
521
|
+
if (result.delegation.processes.stale_pids.length > 0) {
|
|
522
|
+
lines.push(` stale pids: ${result.delegation.processes.stale_pids.join(', ')}`);
|
|
523
|
+
for (const detail of result.delegation.processes.details
|
|
524
|
+
.filter((entry) => entry.classification === 'stale-parent-session' || entry.classification === 'stale-orphan')
|
|
525
|
+
.slice(0, 3)) {
|
|
526
|
+
lines.push(` stale detail: ${formatDelegateServerProcessSummary({
|
|
527
|
+
pid: detail.pid,
|
|
528
|
+
classification: detail.classification,
|
|
529
|
+
cwd: detail.cwd,
|
|
530
|
+
parentPid: detail.parent_pid,
|
|
531
|
+
parentCwd: detail.parent_cwd,
|
|
532
|
+
rootCodexParentPid: detail.root_codex_parent_pid,
|
|
533
|
+
rootCodexParentCwd: detail.root_codex_parent_cwd,
|
|
534
|
+
manifestPath: detail.manifest_path
|
|
535
|
+
})}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
343
538
|
for (const line of result.delegation.enablement) {
|
|
344
539
|
lines.push(` - ${line}`);
|
|
345
540
|
}
|
|
541
|
+
lines.push(`Providers: ${result.providers.status}`);
|
|
542
|
+
lines.push(` - repo examples: ${result.providers.repo_examples.status} (${result.providers.repo_examples.root})`);
|
|
543
|
+
if (result.providers.repo_examples.missing.length > 0) {
|
|
544
|
+
lines.push(` missing: ${result.providers.repo_examples.missing.join(', ')}`);
|
|
545
|
+
}
|
|
546
|
+
lines.push(` - control policy: ${result.providers.control_policy.status} (${result.providers.control_policy.path})`);
|
|
547
|
+
if (result.providers.control_policy.detail) {
|
|
548
|
+
lines.push(` detail: ${result.providers.control_policy.detail}`);
|
|
549
|
+
}
|
|
550
|
+
lines.push(` - Linear: ${result.providers.linear.status}`);
|
|
551
|
+
lines.push(` credentials: ${result.providers.linear.credentials_present ? 'present' : 'missing'}`);
|
|
552
|
+
lines.push(` binding: ${result.providers.linear.binding_present ? 'present' : 'missing'}`);
|
|
553
|
+
lines.push(` webhook secret: ${result.providers.linear.webhook_secret_present ? 'present' : 'missing'}`);
|
|
554
|
+
lines.push(` dispatch_pilot: ${renderProviderToggleSummary(result.providers.linear.dispatch_pilot_enabled, result.providers.linear.dispatch_pilot_provider)}`);
|
|
555
|
+
lines.push(` - Telegram: ${result.providers.telegram.status}`);
|
|
556
|
+
lines.push(` polling: ${result.providers.telegram.polling_enabled ? 'enabled' : 'disabled'}`);
|
|
557
|
+
lines.push(` bot token: ${result.providers.telegram.bot_token_present ? 'present' : 'missing'}`);
|
|
558
|
+
lines.push(` allowlisted chats: ${result.providers.telegram.allowed_chat_ids}`);
|
|
559
|
+
lines.push(` mutations: ${result.providers.telegram.mutations_enabled ? 'enabled' : 'disabled'}`);
|
|
560
|
+
lines.push(` push: ${result.providers.telegram.push_enabled ? 'enabled' : 'disabled'}`);
|
|
561
|
+
lines.push(` transport policy: ${renderTransportPolicySummary(result.providers.telegram.telegram_transport_allowed)}`);
|
|
562
|
+
for (const line of result.providers.guidance) {
|
|
563
|
+
lines.push(` - ${line}`);
|
|
564
|
+
}
|
|
346
565
|
return lines;
|
|
347
566
|
}
|
|
567
|
+
export function buildDelegationDirectTransportGuidance(resolver = () => resolveDelegationServerInvocation({ env: process.env, execPath: process.execPath })) {
|
|
568
|
+
try {
|
|
569
|
+
return `Direct dist transport: ${resolver().commandLine} --repo <path>`;
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
573
|
+
return `Direct dist transport unavailable until dist is built: ${detail}`;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
export function buildDelegationEnablementGuidance(options) {
|
|
577
|
+
const lines = [];
|
|
578
|
+
const setupApplyWouldHelp = options.configStatus !== 'ok' || options.transportStatus !== 'safe';
|
|
579
|
+
if (setupApplyWouldHelp) {
|
|
580
|
+
lines.push('Quick fix: codex-orchestrator doctor --apply --yes');
|
|
581
|
+
}
|
|
582
|
+
lines.push('Run: codex-orchestrator delegation setup --yes');
|
|
583
|
+
lines.push('Run: codex-orchestrator delegation cleanup-stale --yes');
|
|
584
|
+
lines.push(options.directTransportGuidance ?? buildDelegationDirectTransportGuidance());
|
|
585
|
+
lines.push("Enable for a run with: codex -c 'mcp_servers.delegation.enabled=true' ...");
|
|
586
|
+
lines.push('See: codex-orchestrator init codex');
|
|
587
|
+
return lines;
|
|
588
|
+
}
|
|
589
|
+
function inspectProviderReadiness(repoRoot, env = process.env) {
|
|
590
|
+
const providerRoot = join(repoRoot, PROVIDER_ROOT_RELATIVE_PATH);
|
|
591
|
+
const repoExamples = {
|
|
592
|
+
readme: join(providerRoot, 'README.md'),
|
|
593
|
+
env_example: join(providerRoot, 'provider.env.example'),
|
|
594
|
+
control_example: join(providerRoot, 'control.example.json')
|
|
595
|
+
};
|
|
596
|
+
const missingRepoExamples = Object.entries(repoExamples)
|
|
597
|
+
.filter(([, filePath]) => !existsSync(filePath))
|
|
598
|
+
.map(([key]) => key);
|
|
599
|
+
const controlPolicy = readProviderControlPolicy(providerRoot);
|
|
600
|
+
const linearSourceSetup = resolveLinearSourceSetup({
|
|
601
|
+
provider: 'linear',
|
|
602
|
+
workspace_id: controlPolicy.dispatch_pilot_source_setup?.workspace_id ?? null,
|
|
603
|
+
team_id: controlPolicy.dispatch_pilot_source_setup?.team_id ?? null,
|
|
604
|
+
project_id: controlPolicy.dispatch_pilot_source_setup?.project_id ?? null
|
|
605
|
+
}, env);
|
|
606
|
+
const linearCredentialsPresent = hasLinearApiCredentials(env);
|
|
607
|
+
const linearBindingPresent = hasLinearSourceBinding(linearSourceSetup);
|
|
608
|
+
const linearWebhookSecretPresent = Boolean(normalizeOptionalString(env.CO_LINEAR_WEBHOOK_SECRET));
|
|
609
|
+
const linearRequired = controlPolicy.dispatch_pilot_enabled === true && controlPolicy.dispatch_pilot_provider === 'linear';
|
|
610
|
+
const linearReady = linearCredentialsPresent &&
|
|
611
|
+
linearBindingPresent &&
|
|
612
|
+
linearWebhookSecretPresent &&
|
|
613
|
+
linearRequired;
|
|
614
|
+
const telegramPollingEnabled = parseEnvBoolean(env.CO_TELEGRAM_POLLING_ENABLED);
|
|
615
|
+
const telegramBotTokenPresent = Boolean(normalizeOptionalString(env.CO_TELEGRAM_BOT_TOKEN));
|
|
616
|
+
const telegramAllowedChatIds = parseCsvList(env.CO_TELEGRAM_ALLOWED_CHAT_IDS).length;
|
|
617
|
+
const telegramMutationsEnabled = parseEnvBoolean(env.CO_TELEGRAM_ENABLE_MUTATIONS);
|
|
618
|
+
const telegramPushEnabled = parseEnvBoolean(env.CO_TELEGRAM_PUSH_ENABLED);
|
|
619
|
+
const telegramRequired = controlPolicy.telegram_transport_allowed === true;
|
|
620
|
+
const telegramReady = telegramPollingEnabled &&
|
|
621
|
+
telegramBotTokenPresent &&
|
|
622
|
+
telegramAllowedChatIds > 0 &&
|
|
623
|
+
telegramMutationsEnabled &&
|
|
624
|
+
telegramRequired;
|
|
625
|
+
const repoExamplesStatus = missingRepoExamples.length === 0 ? 'ok' : 'missing';
|
|
626
|
+
return {
|
|
627
|
+
status: repoExamplesStatus === 'ok' &&
|
|
628
|
+
controlPolicy.status === 'ok' &&
|
|
629
|
+
(!linearRequired || linearReady) &&
|
|
630
|
+
(!telegramRequired || telegramReady)
|
|
631
|
+
? 'ok'
|
|
632
|
+
: 'advisory',
|
|
633
|
+
repo_examples: {
|
|
634
|
+
status: repoExamplesStatus,
|
|
635
|
+
root: providerRoot,
|
|
636
|
+
paths: repoExamples,
|
|
637
|
+
missing: missingRepoExamples
|
|
638
|
+
},
|
|
639
|
+
control_policy: controlPolicy,
|
|
640
|
+
linear: {
|
|
641
|
+
status: linearReady ? 'ready' : 'incomplete',
|
|
642
|
+
credentials_present: linearCredentialsPresent,
|
|
643
|
+
binding_present: linearBindingPresent,
|
|
644
|
+
webhook_secret_present: linearWebhookSecretPresent,
|
|
645
|
+
dispatch_pilot_enabled: controlPolicy.dispatch_pilot_enabled,
|
|
646
|
+
dispatch_pilot_provider: controlPolicy.dispatch_pilot_provider
|
|
647
|
+
},
|
|
648
|
+
telegram: {
|
|
649
|
+
status: telegramReady ? 'ready' : 'incomplete',
|
|
650
|
+
polling_enabled: telegramPollingEnabled,
|
|
651
|
+
bot_token_present: telegramBotTokenPresent,
|
|
652
|
+
allowed_chat_ids: telegramAllowedChatIds,
|
|
653
|
+
mutations_enabled: telegramMutationsEnabled,
|
|
654
|
+
push_enabled: telegramPushEnabled,
|
|
655
|
+
telegram_transport_allowed: controlPolicy.telegram_transport_allowed
|
|
656
|
+
},
|
|
657
|
+
guidance: [
|
|
658
|
+
'Seed the current repo with: codex-orchestrator init codex --cwd <repo>',
|
|
659
|
+
'Review .codex/providers/provider.env.example and .codex/providers/control.example.json before enabling providers.',
|
|
660
|
+
'Re-run codex-orchestrator doctor --format json after exporting provider env vars to confirm readiness.'
|
|
661
|
+
]
|
|
662
|
+
};
|
|
663
|
+
}
|
|
348
664
|
function inspectCodexDefaultsAdvisory(env = process.env) {
|
|
349
665
|
const configPath = join(resolveCodexHome(env), 'config.toml');
|
|
350
666
|
const checks = {
|
|
351
667
|
model: { status: 'advisory', expected: BASELINE_MODEL, actual: null },
|
|
668
|
+
review_model: { status: 'advisory', expected: BASELINE_REVIEW_MODEL, actual: null },
|
|
352
669
|
model_reasoning_effort: { status: 'advisory', expected_minimum: BASELINE_REASONING_MINIMUM, actual: null },
|
|
353
670
|
max_threads: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_threads, actual: null },
|
|
354
|
-
max_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_depth, actual: null }
|
|
355
|
-
max_spawn_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_spawn_depth, actual: null }
|
|
671
|
+
max_depth: { status: 'advisory', expected_minimum: BASELINE_AGENTS.max_depth, actual: null }
|
|
356
672
|
};
|
|
673
|
+
let legacyMaxSpawnDepth = null;
|
|
357
674
|
const guidance = [
|
|
358
675
|
'Run `codex-orchestrator codex defaults --yes` to apply additive baseline defaults.',
|
|
359
|
-
'Additive policy: unrelated config keys are preserved; existing role files stay untouched unless `--force` is set.'
|
|
676
|
+
'Additive policy: unrelated config keys are preserved; existing role files stay untouched unless `--force` is set.',
|
|
677
|
+
'Current CO baseline no longer seeds or expects `agents.max_spawn_depth`; keep it only as a legacy local override when an older parser/runtime still honors it.',
|
|
678
|
+
'Leaving `agents.max_depth` unset remains accepted when local parser/runtime constraints require it.'
|
|
360
679
|
];
|
|
361
680
|
if (!existsSync(configPath)) {
|
|
362
681
|
return {
|
|
@@ -369,7 +688,7 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
|
|
|
369
688
|
let parsed;
|
|
370
689
|
try {
|
|
371
690
|
const raw = readFileSync(configPath, 'utf8');
|
|
372
|
-
const value =
|
|
691
|
+
const value = getTomlParser().parse(raw);
|
|
373
692
|
if (!isRecord(value)) {
|
|
374
693
|
throw new Error('top-level TOML document must be a table.');
|
|
375
694
|
}
|
|
@@ -393,6 +712,9 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
|
|
|
393
712
|
const model = normalizeOptionalString(readStringValue(parsed.model));
|
|
394
713
|
checks.model.actual = model;
|
|
395
714
|
checks.model.status = model === BASELINE_MODEL ? 'ok' : 'advisory';
|
|
715
|
+
const reviewModel = normalizeOptionalString(readStringValue(parsed.review_model));
|
|
716
|
+
checks.review_model.actual = reviewModel;
|
|
717
|
+
checks.review_model.status = reviewModel === BASELINE_REVIEW_MODEL ? 'ok' : 'advisory';
|
|
396
718
|
const reasoning = normalizeOptionalString(readStringValue(parsed.model_reasoning_effort));
|
|
397
719
|
checks.model_reasoning_effort.actual = reasoning;
|
|
398
720
|
checks.model_reasoning_effort.status = isReasoningAtLeastMinimum(reasoning, BASELINE_REASONING_MINIMUM)
|
|
@@ -406,27 +728,208 @@ function inspectCodexDefaultsAdvisory(env = process.env) {
|
|
|
406
728
|
checks.max_threads.status =
|
|
407
729
|
typeof maxThreads === 'number' && maxThreads >= BASELINE_AGENTS.max_threads ? 'ok' : 'advisory';
|
|
408
730
|
checks.max_depth.actual = maxDepth;
|
|
409
|
-
checks.max_depth.status =
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
731
|
+
checks.max_depth.status =
|
|
732
|
+
maxDepth === null || (typeof maxDepth === 'number' && maxDepth >= BASELINE_AGENTS.max_depth) ? 'ok' : 'advisory';
|
|
733
|
+
if (maxSpawnDepth !== null) {
|
|
734
|
+
const legacySpawnDepthOk = maxSpawnDepth >= BASELINE_AGENTS.max_depth;
|
|
735
|
+
legacyMaxSpawnDepth = {
|
|
736
|
+
present: true,
|
|
737
|
+
status: legacySpawnDepthOk ? 'ok' : 'advisory',
|
|
738
|
+
actual: maxSpawnDepth,
|
|
739
|
+
detail: legacySpawnDepthOk
|
|
740
|
+
? 'legacy override detected; safe for the CO baseline, but remove it when your local parser/runtime no longer consumes spawn-depth caps'
|
|
741
|
+
: `older parser/runtime may still treat this as a hard cap below the CO baseline depth; raise it to >= ${BASELINE_AGENTS.max_depth} or remove it`
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
const allChecksOk = Object.values(checks).every((check) => check.status === 'ok')
|
|
745
|
+
&& legacyMaxSpawnDepth?.status !== 'advisory';
|
|
414
746
|
return {
|
|
415
747
|
status: allChecksOk ? 'ok' : 'advisory',
|
|
416
748
|
config: { path: configPath, status: 'ok' },
|
|
417
749
|
checks,
|
|
750
|
+
legacy_max_spawn_depth: legacyMaxSpawnDepth,
|
|
418
751
|
guidance
|
|
419
752
|
};
|
|
420
753
|
}
|
|
754
|
+
function getTomlParser() {
|
|
755
|
+
if (tomlParser) {
|
|
756
|
+
return tomlParser;
|
|
757
|
+
}
|
|
758
|
+
if (tomlParser === null) {
|
|
759
|
+
throw new Error('Failed to load @iarna/toml.');
|
|
760
|
+
}
|
|
761
|
+
try {
|
|
762
|
+
tomlParser = require('@iarna/toml');
|
|
763
|
+
return tomlParser;
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
tomlParser = null;
|
|
767
|
+
throw error;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
421
770
|
function isRecord(value) {
|
|
422
771
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
423
772
|
}
|
|
424
|
-
function readStringValue(value) {
|
|
425
|
-
|
|
773
|
+
function readStringValue(value, ...keys) {
|
|
774
|
+
if (keys.length === 0) {
|
|
775
|
+
return typeof value === 'string' ? value : null;
|
|
776
|
+
}
|
|
777
|
+
if (!isRecord(value)) {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
for (const key of keys) {
|
|
781
|
+
if (typeof value[key] === 'string') {
|
|
782
|
+
return value[key];
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return null;
|
|
426
786
|
}
|
|
427
787
|
function readNumberValue(value) {
|
|
428
788
|
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
429
789
|
}
|
|
790
|
+
function readBooleanValue(value) {
|
|
791
|
+
return typeof value === 'boolean' ? value : null;
|
|
792
|
+
}
|
|
793
|
+
function readRecordValue(value, ...keys) {
|
|
794
|
+
if (!isRecord(value)) {
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
for (const key of keys) {
|
|
798
|
+
if (isRecord(value[key])) {
|
|
799
|
+
return value[key];
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
function readStringArrayValue(value, ...keys) {
|
|
805
|
+
const raw = isRecord(value)
|
|
806
|
+
? keys.map((key) => value[key]).find((entry) => Array.isArray(entry))
|
|
807
|
+
: Array.isArray(value)
|
|
808
|
+
? value
|
|
809
|
+
: undefined;
|
|
810
|
+
if (!Array.isArray(raw)) {
|
|
811
|
+
return undefined;
|
|
812
|
+
}
|
|
813
|
+
return raw
|
|
814
|
+
.map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
|
|
815
|
+
.filter((entry) => entry.length > 0);
|
|
816
|
+
}
|
|
817
|
+
function parseEnvBoolean(value) {
|
|
818
|
+
const normalized = normalizeOptionalString(value);
|
|
819
|
+
if (!normalized) {
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
return ['1', 'true', 'yes', 'on'].includes(normalized.toLowerCase());
|
|
823
|
+
}
|
|
824
|
+
function parseCsvList(value) {
|
|
825
|
+
const normalized = normalizeOptionalString(value);
|
|
826
|
+
if (!normalized) {
|
|
827
|
+
return [];
|
|
828
|
+
}
|
|
829
|
+
return normalized
|
|
830
|
+
.split(',')
|
|
831
|
+
.map((entry) => entry.trim())
|
|
832
|
+
.filter((entry) => entry.length > 0);
|
|
833
|
+
}
|
|
834
|
+
function readProviderControlPolicy(providerRoot) {
|
|
835
|
+
const preferredPath = join(providerRoot, 'control.json');
|
|
836
|
+
const fallbackPath = join(providerRoot, 'control.example.json');
|
|
837
|
+
const candidate = existsSync(preferredPath) ? preferredPath : existsSync(fallbackPath) ? fallbackPath : preferredPath;
|
|
838
|
+
if (!existsSync(candidate)) {
|
|
839
|
+
return {
|
|
840
|
+
status: 'missing',
|
|
841
|
+
path: preferredPath,
|
|
842
|
+
dispatch_pilot_enabled: null,
|
|
843
|
+
dispatch_pilot_provider: null,
|
|
844
|
+
dispatch_pilot_source_setup: null,
|
|
845
|
+
transport_mutating_enabled: null,
|
|
846
|
+
telegram_transport_allowed: null
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
try {
|
|
850
|
+
const parsed = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
851
|
+
if (!isRecord(parsed)) {
|
|
852
|
+
throw new Error('provider control policy must be a JSON object');
|
|
853
|
+
}
|
|
854
|
+
const featureToggles = isRecord(parsed.feature_toggles) ? parsed.feature_toggles : null;
|
|
855
|
+
const dispatchPilot = resolveDispatchPilotControls(featureToggles);
|
|
856
|
+
const dispatchSource = readRecordValue(dispatchPilot, 'source');
|
|
857
|
+
const dispatchBindingSource = readRecordValue(dispatchSource, 'linear') ?? dispatchSource;
|
|
858
|
+
const dispatchPilotEnabled = readBooleanValue(dispatchPilot?.enabled);
|
|
859
|
+
const rawDispatchPilotProvider = normalizeOptionalString(readStringValue(dispatchSource, 'provider', 'source_provider', 'sourceProvider'));
|
|
860
|
+
const normalizedDispatchPilotProvider = normalizeDispatchSourceProvider(rawDispatchPilotProvider ?? undefined);
|
|
861
|
+
if (dispatchPilotEnabled === true) {
|
|
862
|
+
if (!dispatchSource) {
|
|
863
|
+
throw new Error('dispatch_pilot.source is required when dispatch_pilot.enabled=true');
|
|
864
|
+
}
|
|
865
|
+
if (!normalizedDispatchPilotProvider) {
|
|
866
|
+
throw new Error(rawDispatchPilotProvider
|
|
867
|
+
? `unsupported dispatch_pilot.source.provider: ${rawDispatchPilotProvider}`
|
|
868
|
+
: 'dispatch_pilot.source.provider is required when dispatch_pilot.enabled=true');
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const transportMutating = resolveTransportMutatingControls(featureToggles);
|
|
872
|
+
const transportMutatingEnabled = readBooleanValue(transportMutating?.enabled);
|
|
873
|
+
const allowedTransports = readStringArrayValue(transportMutating, 'allowed_transports', 'allowedTransports');
|
|
874
|
+
const telegramTransportAllowed = transportMutating === null
|
|
875
|
+
? null
|
|
876
|
+
: transportMutatingEnabled === true
|
|
877
|
+
? allowedTransports ? allowedTransports.includes('telegram') : true
|
|
878
|
+
: false;
|
|
879
|
+
return {
|
|
880
|
+
status: 'ok',
|
|
881
|
+
path: candidate,
|
|
882
|
+
dispatch_pilot_enabled: dispatchPilotEnabled,
|
|
883
|
+
dispatch_pilot_provider: normalizedDispatchPilotProvider ?? rawDispatchPilotProvider,
|
|
884
|
+
dispatch_pilot_source_setup: dispatchBindingSource
|
|
885
|
+
? {
|
|
886
|
+
workspace_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'workspace_id', 'workspaceId')),
|
|
887
|
+
team_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'team_id', 'teamId')),
|
|
888
|
+
project_id: normalizeOptionalString(readStringValue(dispatchBindingSource, 'project_id', 'projectId'))
|
|
889
|
+
}
|
|
890
|
+
: null,
|
|
891
|
+
transport_mutating_enabled: transportMutatingEnabled,
|
|
892
|
+
telegram_transport_allowed: telegramTransportAllowed
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
catch (error) {
|
|
896
|
+
return {
|
|
897
|
+
status: 'invalid',
|
|
898
|
+
path: candidate,
|
|
899
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
900
|
+
dispatch_pilot_enabled: null,
|
|
901
|
+
dispatch_pilot_provider: null,
|
|
902
|
+
dispatch_pilot_source_setup: null,
|
|
903
|
+
transport_mutating_enabled: null,
|
|
904
|
+
telegram_transport_allowed: null
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
function resolveTransportMutatingControls(featureToggles) {
|
|
909
|
+
const direct = readRecordValue(featureToggles, 'transport_mutating_controls');
|
|
910
|
+
const coordinator = readRecordValue(featureToggles, 'coordinator');
|
|
911
|
+
const nested = readRecordValue(coordinator, 'transport_mutating_controls');
|
|
912
|
+
return nested ?? direct ?? null;
|
|
913
|
+
}
|
|
914
|
+
function resolveDispatchPilotControls(featureToggles) {
|
|
915
|
+
const direct = readRecordValue(featureToggles, 'dispatch_pilot');
|
|
916
|
+
const coordinator = readRecordValue(featureToggles, 'coordinator');
|
|
917
|
+
const nested = readRecordValue(coordinator, 'dispatch_pilot');
|
|
918
|
+
return nested ?? direct ?? null;
|
|
919
|
+
}
|
|
920
|
+
function renderProviderToggleSummary(enabled, provider) {
|
|
921
|
+
if (enabled === null) {
|
|
922
|
+
return 'unconfigured';
|
|
923
|
+
}
|
|
924
|
+
const label = enabled ? 'enabled' : 'disabled';
|
|
925
|
+
return provider ? `${label} (${provider})` : label;
|
|
926
|
+
}
|
|
927
|
+
function renderTransportPolicySummary(allowed) {
|
|
928
|
+
if (allowed === null) {
|
|
929
|
+
return 'unconfigured';
|
|
930
|
+
}
|
|
931
|
+
return allowed ? 'telegram allowed' : 'telegram blocked';
|
|
932
|
+
}
|
|
430
933
|
function isReasoningAtLeastMinimum(value, minimum) {
|
|
431
934
|
const rank = resolveReasoningRank(value);
|
|
432
935
|
const minimumRank = resolveReasoningRank(minimum);
|
|
@@ -464,10 +967,6 @@ function normalizeOptionalString(value) {
|
|
|
464
967
|
const trimmed = value.trim();
|
|
465
968
|
return trimmed.length > 0 ? trimmed : null;
|
|
466
969
|
}
|
|
467
|
-
function normalizeOptionalBranch(value) {
|
|
468
|
-
const normalized = normalizeOptionalString(value);
|
|
469
|
-
return normalized ? normalized.replace(/^refs\/heads\//u, '') : null;
|
|
470
|
-
}
|
|
471
970
|
function resolveCloudFallbackPolicy(env = process.env) {
|
|
472
971
|
const raw = normalizeOptionalString(env.CODEX_ORCHESTRATOR_CLOUD_FALLBACK);
|
|
473
972
|
if (!raw) {
|
|
@@ -641,82 +1140,3 @@ function canRunCommand(command, args) {
|
|
|
641
1140
|
}
|
|
642
1141
|
return result.status === 0;
|
|
643
1142
|
}
|
|
644
|
-
function inspectDelegationConfig(env = process.env) {
|
|
645
|
-
const codexHome = resolveCodexHome(env);
|
|
646
|
-
const configPath = join(codexHome, 'config.toml');
|
|
647
|
-
if (!existsSync(configPath)) {
|
|
648
|
-
return { status: 'missing', path: configPath, detail: 'config.toml not found' };
|
|
649
|
-
}
|
|
650
|
-
try {
|
|
651
|
-
const raw = readFileSync(configPath, 'utf8');
|
|
652
|
-
const hasEntry = hasMcpServerEntry(raw, 'delegation');
|
|
653
|
-
if (hasEntry) {
|
|
654
|
-
return { status: 'ok', path: configPath };
|
|
655
|
-
}
|
|
656
|
-
return { status: 'missing', path: configPath, detail: 'mcp_servers.delegation entry not found' };
|
|
657
|
-
}
|
|
658
|
-
catch (error) {
|
|
659
|
-
return {
|
|
660
|
-
status: 'missing',
|
|
661
|
-
path: configPath,
|
|
662
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
function hasMcpServerEntry(raw, serverName) {
|
|
667
|
-
const lines = raw.split('\n');
|
|
668
|
-
let currentTable = null;
|
|
669
|
-
for (const line of lines) {
|
|
670
|
-
const trimmed = stripTomlComment(line).trim();
|
|
671
|
-
if (!trimmed) {
|
|
672
|
-
continue;
|
|
673
|
-
}
|
|
674
|
-
const tableMatch = trimmed.match(/^\[(.+)\]$/u);
|
|
675
|
-
if (tableMatch) {
|
|
676
|
-
currentTable = tableMatch[1]?.trim() ?? null;
|
|
677
|
-
if (currentTable === `mcp_servers.${serverName}` ||
|
|
678
|
-
currentTable === `mcp_servers."${serverName}"` ||
|
|
679
|
-
currentTable === `mcp_servers.'${serverName}'`) {
|
|
680
|
-
return true;
|
|
681
|
-
}
|
|
682
|
-
continue;
|
|
683
|
-
}
|
|
684
|
-
if (trimmed.startsWith('mcp_servers.')) {
|
|
685
|
-
if (trimmed.startsWith(`mcp_servers."${serverName}".`)) {
|
|
686
|
-
return true;
|
|
687
|
-
}
|
|
688
|
-
if (trimmed.startsWith(`mcp_servers.'${serverName}'.`)) {
|
|
689
|
-
return true;
|
|
690
|
-
}
|
|
691
|
-
if (trimmed.startsWith(`mcp_servers.${serverName}.`)) {
|
|
692
|
-
return true;
|
|
693
|
-
}
|
|
694
|
-
if (trimmed.startsWith(`mcp_servers."${serverName}"=`)) {
|
|
695
|
-
return true;
|
|
696
|
-
}
|
|
697
|
-
if (trimmed.startsWith(`mcp_servers.'${serverName}'=`)) {
|
|
698
|
-
return true;
|
|
699
|
-
}
|
|
700
|
-
if (trimmed.startsWith(`mcp_servers.${serverName}=`)) {
|
|
701
|
-
return true;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
if (currentTable === 'mcp_servers') {
|
|
705
|
-
const entryPattern = new RegExp(`^"?${escapeRegExp(serverName)}"?\\s*=`, 'u');
|
|
706
|
-
if (entryPattern.test(trimmed)) {
|
|
707
|
-
return true;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
return false;
|
|
712
|
-
}
|
|
713
|
-
function stripTomlComment(line) {
|
|
714
|
-
const index = line.indexOf('#');
|
|
715
|
-
if (index === -1) {
|
|
716
|
-
return line;
|
|
717
|
-
}
|
|
718
|
-
return line.slice(0, index);
|
|
719
|
-
}
|
|
720
|
-
function escapeRegExp(value) {
|
|
721
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
722
|
-
}
|