@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
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_LABEL = 'com.kbediako.co.control-host';
|
|
4
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_TASK_ID = 'local-mcp';
|
|
5
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_RUN_ID = 'control-host';
|
|
6
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_PIPELINE_ID = 'provider-linear-worker';
|
|
7
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_HEALTH_INTERVAL_SECONDS = 30;
|
|
8
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_UNHEALTHY_THRESHOLD = 3;
|
|
9
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_LAUNCHD_THROTTLE_SECONDS = 15;
|
|
10
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_KILL_TIMEOUT_SECONDS = 10;
|
|
11
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_RESTART_EXIT_CODE = 75;
|
|
12
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_SHELL_PATH = '/bin/zsh';
|
|
13
|
+
export const DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS = 10 * 60 * 1000;
|
|
14
|
+
export const CONTROL_HOST_SUPERVISION_RESTART_HISTORY_LIMIT = 20;
|
|
15
|
+
export const CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS = Math.floor(2_147_483_647 / 1_000);
|
|
16
|
+
export function resolveDefaultControlHostSupervisionEnvFiles(homeDir = homedir()) {
|
|
17
|
+
return [join(homeDir, '.local', 'bin', 'env'), join(homeDir, '.co_provider_env')];
|
|
18
|
+
}
|
|
19
|
+
export function resolveDefaultControlHostSupervisionEntrypoint(currentArgvEntry, packageRoot) {
|
|
20
|
+
const bootstrapEntrypoint = join(packageRoot, 'bin', 'codex-orchestrator.js');
|
|
21
|
+
const currentEntry = typeof currentArgvEntry === 'string' && currentArgvEntry.trim().length > 0
|
|
22
|
+
? resolve(currentArgvEntry)
|
|
23
|
+
: null;
|
|
24
|
+
if (currentEntry === bootstrapEntrypoint) {
|
|
25
|
+
return currentEntry;
|
|
26
|
+
}
|
|
27
|
+
return bootstrapEntrypoint;
|
|
28
|
+
}
|
|
29
|
+
export function resolveControlHostSupervisionPaths(input) {
|
|
30
|
+
const resolvedHomeDir = resolve(input?.homeDir ?? homedir());
|
|
31
|
+
const label = normalizeLabel(input?.label);
|
|
32
|
+
const slug = sanitizeControlHostSupervisionPathSegment(label);
|
|
33
|
+
const supportDir = resolve(input?.supportDir ??
|
|
34
|
+
join(resolvedHomeDir, 'Library', 'Application Support', 'codex-orchestrator', 'control-host-supervision', slug));
|
|
35
|
+
const logsDir = resolve(input?.logsDir ?? join(resolvedHomeDir, 'Library', 'Logs', 'co-control-host', slug));
|
|
36
|
+
return {
|
|
37
|
+
supportDir,
|
|
38
|
+
configPath: join(supportDir, 'config.json'),
|
|
39
|
+
statePath: join(supportDir, 'state.json'),
|
|
40
|
+
plistPath: join(resolvedHomeDir, 'Library', 'LaunchAgents', `${label}.plist`),
|
|
41
|
+
logsDir,
|
|
42
|
+
stdoutLogPath: join(logsDir, 'stdout.log'),
|
|
43
|
+
stderrLogPath: join(logsDir, 'stderr.log')
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function buildControlHostSupervisionConfig(input) {
|
|
47
|
+
const homeDir = resolve(input.homeDir ?? homedir());
|
|
48
|
+
const cwd = resolve(input.cwd ?? process.cwd());
|
|
49
|
+
const label = normalizeLabel(input.label);
|
|
50
|
+
const repoRoot = resolve(input.repoRoot ?? cwd);
|
|
51
|
+
const nodePath = resolveRequiredPath(input.nodePath ?? process.execPath, cwd, 'node path');
|
|
52
|
+
const cliEntrypoint = resolveRequiredPath(input.cliEntrypoint ?? join(repoRoot, 'dist', 'bin', 'codex-orchestrator.js'), cwd, 'CLI entrypoint');
|
|
53
|
+
const taskId = normalizeNonEmptyValue(input.taskId, DEFAULT_CONTROL_HOST_SUPERVISION_TASK_ID);
|
|
54
|
+
const runId = normalizeNonEmptyValue(input.runId, DEFAULT_CONTROL_HOST_SUPERVISION_RUN_ID);
|
|
55
|
+
const pipelineId = normalizeNonEmptyValue(input.pipelineId, DEFAULT_CONTROL_HOST_SUPERVISION_PIPELINE_ID);
|
|
56
|
+
const healthIntervalSeconds = coercePositiveTimerSeconds(input.healthIntervalSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_HEALTH_INTERVAL_SECONDS, 'health interval');
|
|
57
|
+
const unhealthyThreshold = coercePositiveInteger(input.unhealthyThreshold, DEFAULT_CONTROL_HOST_SUPERVISION_UNHEALTHY_THRESHOLD, 'unhealthy threshold');
|
|
58
|
+
const launchdThrottleSeconds = coerceNonNegativeInteger(input.launchdThrottleSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_LAUNCHD_THROTTLE_SECONDS, 'launchd throttle');
|
|
59
|
+
const killTimeoutSeconds = coercePositiveTimerSeconds(input.killTimeoutSeconds, DEFAULT_CONTROL_HOST_SUPERVISION_KILL_TIMEOUT_SECONDS, 'kill timeout');
|
|
60
|
+
const shellPath = resolveRequiredPath(input.shellPath ?? process.env.SHELL ?? DEFAULT_CONTROL_HOST_SUPERVISION_SHELL_PATH, cwd, 'shell path');
|
|
61
|
+
const envFiles = (input.envFiles ?? resolveDefaultControlHostSupervisionEnvFiles(homeDir)).map((value, index) => {
|
|
62
|
+
const trimmed = value.trim();
|
|
63
|
+
if (trimmed.length === 0) {
|
|
64
|
+
throw new Error(`env file entry at index ${index} must be non-empty.`);
|
|
65
|
+
}
|
|
66
|
+
return resolveOptionalPath(trimmed, cwd);
|
|
67
|
+
});
|
|
68
|
+
const paths = resolveControlHostSupervisionPaths({
|
|
69
|
+
homeDir,
|
|
70
|
+
label,
|
|
71
|
+
supportDir: input.supportDir,
|
|
72
|
+
logsDir: input.logsDir
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
version: 1,
|
|
76
|
+
label,
|
|
77
|
+
repoRoot,
|
|
78
|
+
nodePath,
|
|
79
|
+
cliEntrypoint,
|
|
80
|
+
taskId,
|
|
81
|
+
runId,
|
|
82
|
+
pipelineId,
|
|
83
|
+
healthIntervalSeconds,
|
|
84
|
+
unhealthyThreshold,
|
|
85
|
+
launchdThrottleSeconds,
|
|
86
|
+
killTimeoutSeconds,
|
|
87
|
+
shellPath,
|
|
88
|
+
envFiles,
|
|
89
|
+
homeDir,
|
|
90
|
+
paths
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function buildControlHostSupervisionPlist(config) {
|
|
94
|
+
const programArguments = [
|
|
95
|
+
config.nodePath,
|
|
96
|
+
config.cliEntrypoint,
|
|
97
|
+
'control-host',
|
|
98
|
+
'supervise',
|
|
99
|
+
'run',
|
|
100
|
+
'--config',
|
|
101
|
+
config.paths.configPath
|
|
102
|
+
];
|
|
103
|
+
const argumentLines = programArguments
|
|
104
|
+
.map((value) => ` <string>${escapeXml(value)}</string>`)
|
|
105
|
+
.join('\n');
|
|
106
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
107
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
108
|
+
<plist version="1.0">
|
|
109
|
+
<dict>
|
|
110
|
+
<key>Label</key>
|
|
111
|
+
<string>${escapeXml(config.label)}</string>
|
|
112
|
+
<key>ProgramArguments</key>
|
|
113
|
+
<array>
|
|
114
|
+
${argumentLines}
|
|
115
|
+
</array>
|
|
116
|
+
<key>WorkingDirectory</key>
|
|
117
|
+
<string>${escapeXml(config.repoRoot)}</string>
|
|
118
|
+
<key>KeepAlive</key>
|
|
119
|
+
<true/>
|
|
120
|
+
<key>RunAtLoad</key>
|
|
121
|
+
<true/>
|
|
122
|
+
<key>ThrottleInterval</key>
|
|
123
|
+
<integer>${config.launchdThrottleSeconds}</integer>
|
|
124
|
+
<key>StandardOutPath</key>
|
|
125
|
+
<string>${escapeXml(config.paths.stdoutLogPath)}</string>
|
|
126
|
+
<key>StandardErrorPath</key>
|
|
127
|
+
<string>${escapeXml(config.paths.stderrLogPath)}</string>
|
|
128
|
+
</dict>
|
|
129
|
+
</plist>
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
export function buildInitialControlHostSupervisionState(input) {
|
|
133
|
+
return {
|
|
134
|
+
version: 1,
|
|
135
|
+
status: normalizeNonEmptyValue(input.status, 'installed'),
|
|
136
|
+
updated_at: input.updatedAt,
|
|
137
|
+
label: input.config.label,
|
|
138
|
+
repo_root: input.config.repoRoot,
|
|
139
|
+
service_target: input.serviceTarget ?? null,
|
|
140
|
+
child_pid: null,
|
|
141
|
+
last_started_at: null,
|
|
142
|
+
last_exit_at: null,
|
|
143
|
+
last_exit_code: null,
|
|
144
|
+
last_signal: null,
|
|
145
|
+
last_health_check_at: null,
|
|
146
|
+
last_health_status: null,
|
|
147
|
+
last_probe_duration_ms: null,
|
|
148
|
+
consecutive_unhealthy_samples: 0,
|
|
149
|
+
restart_count: input.restartCount ?? 0,
|
|
150
|
+
unhealthy_threshold: input.config.unhealthyThreshold,
|
|
151
|
+
health_interval_seconds: input.config.healthIntervalSeconds,
|
|
152
|
+
last_restart_reason: input.lastRestartReason ?? null,
|
|
153
|
+
last_restart_requested_at: input.lastRestartRequestedAt ?? null,
|
|
154
|
+
restart_history: normalizeControlHostSupervisionRestartHistory(input.restartHistory ?? null),
|
|
155
|
+
message: input.message ?? null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export function readControlHostSupervisionHealthDiagnostic(payload) {
|
|
159
|
+
if (!isRecord(payload)) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const counts = isRecord(payload.counts) ? payload.counts : null;
|
|
163
|
+
const polling = isRecord(payload.polling) ? payload.polling : null;
|
|
164
|
+
const running = Array.isArray(payload.running) ? payload.running : [];
|
|
165
|
+
return {
|
|
166
|
+
counts: {
|
|
167
|
+
running: readFiniteNumber(counts?.running),
|
|
168
|
+
retrying: readFiniteNumber(counts?.retrying),
|
|
169
|
+
max_allowed: readFiniteNumber(counts?.max_allowed)
|
|
170
|
+
},
|
|
171
|
+
polling: polling ? buildControlHostSupervisionPollingDiagnostic(polling) : null,
|
|
172
|
+
running_workers: running
|
|
173
|
+
.map((entry) => buildControlHostSupervisionRunningWorkerSnapshot(entry))
|
|
174
|
+
.filter((entry) => entry !== null)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function normalizeStoredControlHostSupervisionHealthDiagnostic(value) {
|
|
178
|
+
if (!isRecord(value)) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const counts = isRecord(value.counts) ? value.counts : null;
|
|
182
|
+
const polling = isRecord(value.polling) ? value.polling : null;
|
|
183
|
+
const runningWorkers = Array.isArray(value.running_workers) ? value.running_workers : [];
|
|
184
|
+
return {
|
|
185
|
+
counts: {
|
|
186
|
+
running: readFiniteNumber(counts?.running),
|
|
187
|
+
retrying: readFiniteNumber(counts?.retrying),
|
|
188
|
+
max_allowed: readFiniteNumber(counts?.max_allowed)
|
|
189
|
+
},
|
|
190
|
+
polling: polling ? buildControlHostSupervisionPollingDiagnostic(polling) : null,
|
|
191
|
+
running_workers: runningWorkers
|
|
192
|
+
.map((entry) => buildControlHostSupervisionRunningWorkerSnapshot(entry))
|
|
193
|
+
.filter((entry) => entry !== null)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export function evaluateControlHostSupervisionHealthPayload(payload, options = {}) {
|
|
197
|
+
if (!isRecord(payload)) {
|
|
198
|
+
return {
|
|
199
|
+
healthy: false,
|
|
200
|
+
reason: 'invalid_payload',
|
|
201
|
+
message: 'co-status returned a non-object payload.'
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const polling = isRecord(payload.polling) ? payload.polling : null;
|
|
205
|
+
const diagnostic = readControlHostSupervisionHealthDiagnostic(payload);
|
|
206
|
+
if (!polling) {
|
|
207
|
+
return {
|
|
208
|
+
healthy: true,
|
|
209
|
+
reason: 'ok',
|
|
210
|
+
message: 'co-status payload omitted polling state; treating it as healthy.'
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (polling.restart_required === true) {
|
|
214
|
+
if (isStaleRecoverableProviderRestartRequiredPolling(polling, {
|
|
215
|
+
minPollingUpdatedAt: options.minPollingUpdatedAt,
|
|
216
|
+
staleRestartRequiredGraceMs: options.staleRestartRequiredGraceMs,
|
|
217
|
+
now: options.now
|
|
218
|
+
})) {
|
|
219
|
+
const graceSeconds = typeof options.staleRestartRequiredGraceMs === 'number' &&
|
|
220
|
+
Number.isFinite(options.staleRestartRequiredGraceMs)
|
|
221
|
+
? Math.max(0, Math.round(options.staleRestartRequiredGraceMs / 1_000))
|
|
222
|
+
: null;
|
|
223
|
+
return {
|
|
224
|
+
healthy: true,
|
|
225
|
+
reason: 'stale_restart_required',
|
|
226
|
+
message: `co-status reported a stale provider_refresh_lifecycle_stuck restart_required snapshot from before the current supervised child start; treating it as quiescent${graceSeconds === null ? '' : ` for the bounded ${graceSeconds}s startup grace window`} while the current host refreshes.`
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
const repeatedRestartQuarantine = resolveRepeatedActiveWorkerRestartQuarantine({
|
|
230
|
+
polling,
|
|
231
|
+
diagnostic,
|
|
232
|
+
restartHistory: options.restartHistory ?? null,
|
|
233
|
+
activeWorkerRestartQuarantineMs: options.activeWorkerRestartQuarantineMs ??
|
|
234
|
+
DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS,
|
|
235
|
+
now: options.now
|
|
236
|
+
});
|
|
237
|
+
if (repeatedRestartQuarantine) {
|
|
238
|
+
return repeatedRestartQuarantine;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
healthy: false,
|
|
242
|
+
reason: 'restart_required',
|
|
243
|
+
message: 'co-status reported restart_required=true.'
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
healthy: true,
|
|
248
|
+
reason: 'ok',
|
|
249
|
+
message: 'co-status reported a healthy polling state.'
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function isStaleRecoverableProviderRestartRequiredPolling(polling, options) {
|
|
253
|
+
if (polling.reason !== 'provider_refresh_lifecycle_stuck' &&
|
|
254
|
+
polling.last_error !== 'provider_refresh_lifecycle_stuck') {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
const pollingUpdatedAt = parseIsoTimestampToMs(polling.updated_at);
|
|
258
|
+
const minimumUpdatedAt = parseIsoTimestampToMs(options.minPollingUpdatedAt);
|
|
259
|
+
if (pollingUpdatedAt === null || minimumUpdatedAt === null || pollingUpdatedAt >= minimumUpdatedAt) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
if (typeof options.staleRestartRequiredGraceMs !== 'number' ||
|
|
263
|
+
!Number.isFinite(options.staleRestartRequiredGraceMs)) {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
const now = parseIsoTimestampToMs(options.now ?? new Date().toISOString());
|
|
267
|
+
return now !== null && now - minimumUpdatedAt <= Math.max(0, options.staleRestartRequiredGraceMs);
|
|
268
|
+
}
|
|
269
|
+
function resolveRepeatedActiveWorkerRestartQuarantine(input) {
|
|
270
|
+
if (!isProviderRefreshLifecycleRestartRequired(input.polling)) {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
const diagnostic = input.diagnostic;
|
|
274
|
+
if (!diagnostic || diagnostic.running_workers.length === 0) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
if (hasAvailableProviderWorkerCapacity(diagnostic)) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
const restartHistory = normalizeControlHostSupervisionRestartHistory(input.restartHistory);
|
|
281
|
+
if (restartHistory.length === 0) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const currentSignature = buildControlHostSupervisionRestartSignature(diagnostic);
|
|
285
|
+
if (currentSignature === null) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const nowMs = parseIsoTimestampToMs(input.now ?? new Date().toISOString());
|
|
289
|
+
const quarantineMs = typeof input.activeWorkerRestartQuarantineMs === 'number' &&
|
|
290
|
+
Number.isFinite(input.activeWorkerRestartQuarantineMs)
|
|
291
|
+
? Math.max(0, input.activeWorkerRestartQuarantineMs)
|
|
292
|
+
: null;
|
|
293
|
+
for (let index = restartHistory.length - 1; index >= 0; index -= 1) {
|
|
294
|
+
const record = restartHistory[index];
|
|
295
|
+
const requestedAtMs = parseIsoTimestampToMs(record.requested_at);
|
|
296
|
+
if (quarantineMs !== null &&
|
|
297
|
+
nowMs !== null &&
|
|
298
|
+
requestedAtMs !== null &&
|
|
299
|
+
nowMs - requestedAtMs > quarantineMs) {
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
const recordSignature = buildControlHostSupervisionRestartSignature(record.diagnostic);
|
|
303
|
+
if (recordSignature === null || recordSignature !== currentSignature) {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
healthy: true,
|
|
308
|
+
reason: 'active_worker_restart_quarantine',
|
|
309
|
+
message: `co-status reported restart_required=true for the same provider refresh stuck series already restarted at ${record.requested_at}; ${diagnostic.running_workers.length} active provider worker(s) remain visible, so supervision is quarantining repeated restart churn while retaining restart_required in co-status.`
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
export function evaluateControlHostSupervisionProbeTimeoutDiagnostic(diagnostic, options = {}) {
|
|
315
|
+
if (!diagnostic || diagnostic.running_workers.length === 0) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
if (!isProviderRefreshLifecycleRestartRequiredDiagnostic(diagnostic.polling)) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
if (!isCurrentControlHostSupervisionPollingDiagnostic(diagnostic.polling, options.minPollingUpdatedAt)) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const pollingReason = diagnostic.polling?.reason ?? diagnostic.polling?.last_error ?? null;
|
|
325
|
+
if (!pollingReason) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
if (hasAvailableProviderWorkerCapacity(diagnostic)) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
const restartHistory = normalizeControlHostSupervisionRestartHistory(options.restartHistory);
|
|
332
|
+
if (restartHistory.length === 0) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
const currentSignature = buildControlHostSupervisionRestartSignature(diagnostic);
|
|
336
|
+
if (currentSignature === null) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
const nowMs = parseIsoTimestampToMs(options.now ?? new Date().toISOString());
|
|
340
|
+
const quarantineMs = typeof options.activeWorkerRestartQuarantineMs === 'number' &&
|
|
341
|
+
Number.isFinite(options.activeWorkerRestartQuarantineMs)
|
|
342
|
+
? Math.max(0, options.activeWorkerRestartQuarantineMs)
|
|
343
|
+
: DEFAULT_CONTROL_HOST_SUPERVISION_ACTIVE_WORKER_RESTART_QUARANTINE_MS;
|
|
344
|
+
for (let index = restartHistory.length - 1; index >= 0; index -= 1) {
|
|
345
|
+
const record = restartHistory[index];
|
|
346
|
+
const requestedAtMs = parseIsoTimestampToMs(record.requested_at);
|
|
347
|
+
if (nowMs !== null &&
|
|
348
|
+
requestedAtMs !== null &&
|
|
349
|
+
nowMs - requestedAtMs > quarantineMs) {
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
if (record.reason !== 'probe_timeout') {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
const recordSignature = buildControlHostSupervisionRestartSignature(record.diagnostic);
|
|
356
|
+
if (recordSignature === null || recordSignature !== currentSignature) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
healthy: true,
|
|
361
|
+
reason: 'active_worker_probe_timeout_quarantine',
|
|
362
|
+
message: `co-status probe timed out for the same active provider worker series already restarted at ${record.requested_at}; ${diagnostic.running_workers.length} active provider worker(s) remain visible in local provider-intake state, so supervision is quarantining repeated probe timeout restart churn while retaining the prior fail-closed timeout record.`
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
function isProviderRefreshLifecycleRestartRequiredDiagnostic(polling) {
|
|
368
|
+
if (!polling || polling.restart_required !== true) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return (polling.reason === 'provider_refresh_lifecycle_stuck' ||
|
|
372
|
+
polling.last_error === 'provider_refresh_lifecycle_stuck');
|
|
373
|
+
}
|
|
374
|
+
function isCurrentControlHostSupervisionPollingDiagnostic(polling, minPollingUpdatedAt) {
|
|
375
|
+
const minimumUpdatedAt = parseIsoTimestampToMs(minPollingUpdatedAt);
|
|
376
|
+
if (minimumUpdatedAt === null) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
const pollingUpdatedAt = parseIsoTimestampToMs(polling?.updated_at);
|
|
380
|
+
return pollingUpdatedAt !== null && pollingUpdatedAt >= minimumUpdatedAt;
|
|
381
|
+
}
|
|
382
|
+
function hasAvailableProviderWorkerCapacity(diagnostic) {
|
|
383
|
+
const running = diagnostic.counts.running;
|
|
384
|
+
const retrying = diagnostic.counts.retrying;
|
|
385
|
+
const maxAllowed = diagnostic.counts.max_allowed ?? null;
|
|
386
|
+
if (running === null || retrying === null || maxAllowed === null) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
return running + retrying < maxAllowed;
|
|
390
|
+
}
|
|
391
|
+
function buildControlHostSupervisionPollingDiagnostic(polling) {
|
|
392
|
+
return {
|
|
393
|
+
updated_at: readIsoString(polling.updated_at),
|
|
394
|
+
checking: polling.checking === true,
|
|
395
|
+
queued: polling.queued === true,
|
|
396
|
+
stuck: polling.stuck === true,
|
|
397
|
+
restart_required: polling.restart_required === true,
|
|
398
|
+
reason: readNonEmptyString(polling.reason),
|
|
399
|
+
last_error: readNonEmptyString(polling.last_error),
|
|
400
|
+
refresh_phase: readNonEmptyString(polling.refresh_phase),
|
|
401
|
+
refresh_request_class: readNonEmptyString(polling.refresh_request_class),
|
|
402
|
+
refresh_provider_keys: readStringArray(polling.refresh_provider_keys),
|
|
403
|
+
operation_elapsed_ms: readFiniteNumber(polling.operation_elapsed_ms),
|
|
404
|
+
stalled_after_ms: readFiniteNumber(polling.stalled_after_ms),
|
|
405
|
+
control_host_owner: isRecord(polling.control_host_owner) ? { ...polling.control_host_owner } : null
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function buildControlHostSupervisionRunningWorkerSnapshot(value) {
|
|
409
|
+
if (!isRecord(value)) {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
const issueIdentifier = readNonEmptyString(value.issue_identifier);
|
|
413
|
+
if (!issueIdentifier) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
issue_id: readIsoOrPlainString(value.issue_id),
|
|
418
|
+
issue_identifier: issueIdentifier,
|
|
419
|
+
state: readNonEmptyString(value.state),
|
|
420
|
+
display_state: readNonEmptyString(value.display_state),
|
|
421
|
+
pid: readNonEmptyString(value.pid),
|
|
422
|
+
worker_host: readNonEmptyString(value.worker_host),
|
|
423
|
+
session_id: readNonEmptyString(value.session_id),
|
|
424
|
+
started_at: readIsoString(value.started_at),
|
|
425
|
+
last_event_at: readIsoString(value.last_event_at)
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
function normalizeControlHostSupervisionRestartHistory(value) {
|
|
429
|
+
if (!Array.isArray(value)) {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
const normalized = value
|
|
433
|
+
.map((entry) => normalizeControlHostSupervisionRestartRecord(entry))
|
|
434
|
+
.filter((entry) => entry !== null);
|
|
435
|
+
return normalized.slice(-CONTROL_HOST_SUPERVISION_RESTART_HISTORY_LIMIT);
|
|
436
|
+
}
|
|
437
|
+
function normalizeControlHostSupervisionRestartRecord(value) {
|
|
438
|
+
if (!value || typeof value !== 'object') {
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
const requestedAt = readIsoString(value.requested_at);
|
|
442
|
+
const reason = readNonEmptyString(value.reason);
|
|
443
|
+
if (!requestedAt || !reason) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
requested_at: requestedAt,
|
|
448
|
+
reason,
|
|
449
|
+
message: readNonEmptyString(value.message) ?? '',
|
|
450
|
+
consecutive_unhealthy_samples: readFiniteNumber(value.consecutive_unhealthy_samples) ?? 0,
|
|
451
|
+
child_pid: readFiniteNumber(value.child_pid),
|
|
452
|
+
probe_duration_ms: readFiniteNumber(value.probe_duration_ms),
|
|
453
|
+
diagnostic: normalizeStoredControlHostSupervisionHealthDiagnostic(value.diagnostic)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function buildControlHostSupervisionRestartSignature(diagnostic) {
|
|
457
|
+
if (!diagnostic?.polling) {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
const workerSeries = diagnostic.running_workers
|
|
461
|
+
.map((worker) => buildControlHostSupervisionWorkerSeriesKey(worker))
|
|
462
|
+
.filter((value) => value !== null)
|
|
463
|
+
.sort();
|
|
464
|
+
if (workerSeries.length === 0) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
// Quarantine repeated restart churn on the stable active-worker series, not on transient
|
|
468
|
+
// refresh checkpoints that can legitimately drift within one stuck refresh cycle.
|
|
469
|
+
return JSON.stringify({
|
|
470
|
+
reason: diagnostic.polling.reason ?? diagnostic.polling.last_error ?? null,
|
|
471
|
+
worker_series: workerSeries
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
function buildControlHostSupervisionWorkerSeriesKey(worker) {
|
|
475
|
+
if (worker.issue_identifier.length === 0) {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
return JSON.stringify({
|
|
479
|
+
issue_identifier: worker.issue_identifier,
|
|
480
|
+
session_id: worker.session_id ?? null,
|
|
481
|
+
started_at: worker.started_at ?? null,
|
|
482
|
+
pid: worker.pid ?? null
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function isProviderRefreshLifecycleRestartRequired(polling) {
|
|
486
|
+
if (polling.restart_required !== true) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
return (polling.reason === 'provider_refresh_lifecycle_stuck' ||
|
|
490
|
+
polling.last_error === 'provider_refresh_lifecycle_stuck');
|
|
491
|
+
}
|
|
492
|
+
function parseIsoTimestampToMs(value) {
|
|
493
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
const parsed = Date.parse(value);
|
|
497
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
498
|
+
}
|
|
499
|
+
export function parseControlHostSupervisionCsv(raw) {
|
|
500
|
+
if (typeof raw !== 'string') {
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
const trimmed = raw.trim();
|
|
504
|
+
if (trimmed.length === 0) {
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
if (trimmed === '-' || trimmed.toLowerCase() === 'none') {
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
return trimmed
|
|
511
|
+
.split(',')
|
|
512
|
+
.map((value) => value.trim())
|
|
513
|
+
.filter((value) => value.length > 0);
|
|
514
|
+
}
|
|
515
|
+
function readNonEmptyString(value) {
|
|
516
|
+
if (typeof value !== 'string') {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
const trimmed = value.trim();
|
|
520
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
521
|
+
}
|
|
522
|
+
function readIsoString(value) {
|
|
523
|
+
const candidate = readNonEmptyString(value);
|
|
524
|
+
return candidate && Number.isFinite(Date.parse(candidate)) ? candidate : null;
|
|
525
|
+
}
|
|
526
|
+
function readIsoOrPlainString(value) {
|
|
527
|
+
return readNonEmptyString(value);
|
|
528
|
+
}
|
|
529
|
+
function readFiniteNumber(value) {
|
|
530
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
531
|
+
}
|
|
532
|
+
function readStringArray(value) {
|
|
533
|
+
if (!Array.isArray(value)) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
const normalized = value
|
|
537
|
+
.map((entry) => readNonEmptyString(entry))
|
|
538
|
+
.filter((entry) => entry !== null);
|
|
539
|
+
return normalized.length > 0 ? normalized : null;
|
|
540
|
+
}
|
|
541
|
+
export function sanitizeControlHostSupervisionPathSegment(value) {
|
|
542
|
+
const trimmed = value.trim();
|
|
543
|
+
const sanitized = trimmed.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
544
|
+
if (sanitized === '.' || sanitized === '..') {
|
|
545
|
+
throw new Error('control-host supervision label may not resolve to "." or "..".');
|
|
546
|
+
}
|
|
547
|
+
return sanitized.length > 0 ? sanitized : 'control-host';
|
|
548
|
+
}
|
|
549
|
+
function normalizeLabel(value) {
|
|
550
|
+
const normalized = normalizeNonEmptyValue(value, DEFAULT_CONTROL_HOST_SUPERVISION_LABEL);
|
|
551
|
+
if (!/^[A-Za-z0-9._-]+$/u.test(normalized)) {
|
|
552
|
+
throw new Error('control-host supervision label may only contain letters, numbers, dots, underscores, and hyphens.');
|
|
553
|
+
}
|
|
554
|
+
return normalized;
|
|
555
|
+
}
|
|
556
|
+
function normalizeNonEmptyValue(value, fallback) {
|
|
557
|
+
if (typeof value !== 'string') {
|
|
558
|
+
return fallback;
|
|
559
|
+
}
|
|
560
|
+
const trimmed = value.trim();
|
|
561
|
+
return trimmed.length > 0 ? trimmed : fallback;
|
|
562
|
+
}
|
|
563
|
+
function resolveRequiredPath(value, cwd, label) {
|
|
564
|
+
const trimmed = value.trim();
|
|
565
|
+
if (trimmed.length === 0) {
|
|
566
|
+
throw new Error(`${label} must be non-empty.`);
|
|
567
|
+
}
|
|
568
|
+
return resolveOptionalPath(trimmed, cwd);
|
|
569
|
+
}
|
|
570
|
+
function resolveOptionalPath(value, cwd) {
|
|
571
|
+
return isAbsolute(value) ? resolve(value) : resolve(cwd, value);
|
|
572
|
+
}
|
|
573
|
+
function coercePositiveInteger(value, fallback, label) {
|
|
574
|
+
if (value === undefined || value === null) {
|
|
575
|
+
return fallback;
|
|
576
|
+
}
|
|
577
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
578
|
+
throw new Error(`${label} must be a positive integer.`);
|
|
579
|
+
}
|
|
580
|
+
return value;
|
|
581
|
+
}
|
|
582
|
+
function coercePositiveTimerSeconds(value, fallback, label) {
|
|
583
|
+
const parsed = coercePositiveInteger(value, fallback, label);
|
|
584
|
+
if (parsed > CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS) {
|
|
585
|
+
throw new Error(`${label} must be <= ${CONTROL_HOST_SUPERVISION_MAX_NODE_TIMER_SECONDS} seconds to stay within Node timer limits.`);
|
|
586
|
+
}
|
|
587
|
+
return parsed;
|
|
588
|
+
}
|
|
589
|
+
function coerceNonNegativeInteger(value, fallback, label) {
|
|
590
|
+
if (value === undefined || value === null) {
|
|
591
|
+
return fallback;
|
|
592
|
+
}
|
|
593
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
594
|
+
throw new Error(`${label} must be a non-negative integer.`);
|
|
595
|
+
}
|
|
596
|
+
return value;
|
|
597
|
+
}
|
|
598
|
+
function escapeXml(value) {
|
|
599
|
+
return value
|
|
600
|
+
.replaceAll('&', '&')
|
|
601
|
+
.replaceAll('<', '<')
|
|
602
|
+
.replaceAll('>', '>')
|
|
603
|
+
.replaceAll('"', '"')
|
|
604
|
+
.replaceAll("'", ''');
|
|
605
|
+
}
|
|
606
|
+
function isRecord(value) {
|
|
607
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
608
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createControlOversightReadService } from './controlOversightReadService.js';
|
|
2
|
+
export function createControlOversightFacade(context) {
|
|
3
|
+
const readService = createControlOversightReadService(context);
|
|
4
|
+
return {
|
|
5
|
+
...readService,
|
|
6
|
+
subscribe: (listener) => context.runtime.subscribe(listener)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { readControlTelegramDispatch } from './controlTelegramDispatchRead.js';
|
|
2
|
+
import { readControlTelegramQuestions } from './controlTelegramQuestionRead.js';
|
|
3
|
+
export function createControlOversightReadService(context) {
|
|
4
|
+
return {
|
|
5
|
+
readSelectedRun: async () => context.runtime.snapshot().readSelectedRunSnapshot(),
|
|
6
|
+
readDispatch: async () => readControlTelegramDispatch({
|
|
7
|
+
...context,
|
|
8
|
+
expiryLifecycle: context.expiryLifecycle,
|
|
9
|
+
emitDispatchPilotAuditEvents: context.emitDispatchPilotAuditEvents
|
|
10
|
+
}),
|
|
11
|
+
readQuestions: async () => readControlTelegramQuestions({
|
|
12
|
+
...context,
|
|
13
|
+
expiryLifecycle: context.expiryLifecycle
|
|
14
|
+
})
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const LINEAR_ADVISORY_STATE_FILE = 'linear-advisory-state.json';
|
|
2
|
+
export const PROVIDER_INTAKE_STATE_FILE = 'provider-intake-state.json';
|
|
3
|
+
export const CONTROL_HOST_OWNER_FILE = 'control-host-owner.json';
|
|
4
|
+
export const CONTROL_HOST_OWNER_LOCK_DIR = 'control-host-owner.lock';
|
|
5
|
+
export const CONTROL_HOST_DUPLICATE_OWNER_FILE = 'control-host-duplicate-owner.json';
|
|
6
|
+
export const CONTROL_HOST_STALE_OWNER_FILE = 'control-host-stale-owner.json';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createQuestionChildResolutionAdapter } from './questionChildResolutionAdapter.js';
|
|
2
|
+
export function createControlQuestionChildResolutionAdapter(context) {
|
|
3
|
+
return createQuestionChildResolutionAdapter({
|
|
4
|
+
allowedRunRoots: context.config.ui.allowedRunRoots,
|
|
5
|
+
allowedBindHosts: context.config.ui.allowedBindHosts,
|
|
6
|
+
expiryFallback: context.config.delegate.expiryFallback,
|
|
7
|
+
readParentRunId: () => context.controlStore.snapshot().run_id,
|
|
8
|
+
validateDelegationToken: (token, parentRunId, childRunId) => Boolean(context.delegationTokens.validate(token, parentRunId, childRunId)),
|
|
9
|
+
emitResolutionFallback: (payload) => emitControlQuestionChildResolutionFallbackEvent(context, payload)
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
async function emitControlQuestionChildResolutionFallbackEvent(context, payload) {
|
|
13
|
+
await context.eventTransport.emitControlEvent({
|
|
14
|
+
event: 'question.resolve_child_fallback',
|
|
15
|
+
actor: 'control',
|
|
16
|
+
payload: payload
|
|
17
|
+
});
|
|
18
|
+
}
|