@kbediako/codex-orchestrator 0.1.37 → 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 +73 -291
- 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 +136 -16
- 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 +668 -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 +30 -11
- 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 +395 -0
- package/skills/chrome-devtools/SKILL.md +1 -1
- package/skills/codex-orchestrator/SKILL.md +83 -0
- package/skills/collab-subagents-first/SKILL.md +2 -1
- package/skills/delegation-usage/DELEGATION_GUIDE.md +24 -11
- package/skills/delegation-usage/SKILL.md +20 -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/explorer-fast.toml +1 -0
- 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 -307
- package/docs/assets/setup.gif +0 -0
|
@@ -29,6 +29,7 @@ export class UnifiedExecRunner {
|
|
|
29
29
|
async run(options) {
|
|
30
30
|
const args = options.args;
|
|
31
31
|
const resolvedArgs = args ?? [];
|
|
32
|
+
const timeoutMs = normalizeTimeoutMs(options.timeoutMs);
|
|
32
33
|
const invocationId = options.invocationId ?? this.idGenerator();
|
|
33
34
|
const correlationId = this.idGenerator();
|
|
34
35
|
const issuedHandle = this.handleService ? this.handleService.issueHandle(correlationId) : undefined;
|
|
@@ -55,7 +56,8 @@ export class UnifiedExecRunner {
|
|
|
55
56
|
sessionId: lease.id,
|
|
56
57
|
correlationId,
|
|
57
58
|
persisted: lease.persisted,
|
|
58
|
-
handleId
|
|
59
|
+
handleId,
|
|
60
|
+
timeoutMs
|
|
59
61
|
};
|
|
60
62
|
const toolInvocation = {
|
|
61
63
|
id: invocationId,
|
|
@@ -98,7 +100,9 @@ export class UnifiedExecRunner {
|
|
|
98
100
|
durationMs: 0,
|
|
99
101
|
status: 'failed',
|
|
100
102
|
sandboxState,
|
|
101
|
-
sessionId: lease.id
|
|
103
|
+
sessionId: lease.id,
|
|
104
|
+
timedOut: false,
|
|
105
|
+
...(timeoutMs !== null ? { timeoutMs } : {})
|
|
102
106
|
};
|
|
103
107
|
try {
|
|
104
108
|
const outcome = await this.executor({
|
|
@@ -109,6 +113,7 @@ export class UnifiedExecRunner {
|
|
|
109
113
|
attempt,
|
|
110
114
|
sandboxState,
|
|
111
115
|
session: lease,
|
|
116
|
+
...(timeoutMs !== null ? { timeoutMs } : {}),
|
|
112
117
|
onStdout: (chunk) => {
|
|
113
118
|
const sequenced = this.recordChunk(tracker, 'stdout', chunk);
|
|
114
119
|
chunkSequence = sequenced.sequence;
|
|
@@ -132,7 +137,11 @@ export class UnifiedExecRunner {
|
|
|
132
137
|
});
|
|
133
138
|
attemptSummary.exitCode = outcome.exitCode ?? null;
|
|
134
139
|
attemptSummary.signal = outcome.signal ?? null;
|
|
135
|
-
attemptSummary.
|
|
140
|
+
attemptSummary.timedOut = outcome.timedOut === true;
|
|
141
|
+
if (typeof outcome.timeoutMs === 'number' && Number.isFinite(outcome.timeoutMs) && outcome.timeoutMs > 0) {
|
|
142
|
+
attemptSummary.timeoutMs = Math.trunc(outcome.timeoutMs);
|
|
143
|
+
}
|
|
144
|
+
attemptSummary.status = outcome.exitCode === 0 && !attemptSummary.timedOut ? 'succeeded' : 'failed';
|
|
136
145
|
attemptSummary.durationMs = outcome.durationMs ?? 0;
|
|
137
146
|
}
|
|
138
147
|
catch (error) {
|
|
@@ -171,6 +180,8 @@ export class UnifiedExecRunner {
|
|
|
171
180
|
durationMs: attemptResult.durationMs,
|
|
172
181
|
status: attemptResult.status,
|
|
173
182
|
sandboxState: attemptResult.sandboxState,
|
|
183
|
+
...(attemptResult.timedOut ? { timedOut: true } : {}),
|
|
184
|
+
...(attemptResult.timeoutMs !== undefined ? { timeoutMs: attemptResult.timeoutMs } : {}),
|
|
174
185
|
record: invocationRecord,
|
|
175
186
|
events,
|
|
176
187
|
handle: undefined
|
|
@@ -307,7 +318,9 @@ export class UnifiedExecRunner {
|
|
|
307
318
|
correlationId,
|
|
308
319
|
handleId,
|
|
309
320
|
exitCode: attemptResult?.exitCode ?? null,
|
|
310
|
-
signal: attemptResult?.signal ?? null
|
|
321
|
+
signal: attemptResult?.signal ?? null,
|
|
322
|
+
timedOut: attemptResult?.timedOut ?? null,
|
|
323
|
+
timeoutMs: attemptResult?.timeoutMs ?? null
|
|
311
324
|
}
|
|
312
325
|
};
|
|
313
326
|
record.metadata = execMetadata;
|
|
@@ -414,20 +427,100 @@ const defaultExecutor = async (request) => {
|
|
|
414
427
|
}
|
|
415
428
|
child.stdout.on('data', request.onStdout);
|
|
416
429
|
child.stderr.on('data', request.onStderr);
|
|
430
|
+
const timeoutMs = normalizeTimeoutMs(request.timeoutMs);
|
|
431
|
+
const startedAt = Date.now();
|
|
417
432
|
return await new Promise((resolve, reject) => {
|
|
418
|
-
|
|
433
|
+
let settled = false;
|
|
434
|
+
let timedOut = false;
|
|
435
|
+
let timeoutHandle = null;
|
|
436
|
+
let forceKillHandle = null;
|
|
437
|
+
let forcedSettleHandle = null;
|
|
438
|
+
const resolveResult = (exitCode, signal) => {
|
|
439
|
+
if (settled) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
settled = true;
|
|
419
443
|
cleanup();
|
|
420
|
-
|
|
444
|
+
const result = {
|
|
445
|
+
exitCode,
|
|
446
|
+
signal,
|
|
447
|
+
durationMs: Math.max(0, Date.now() - startedAt)
|
|
448
|
+
};
|
|
449
|
+
if (timedOut) {
|
|
450
|
+
result.timedOut = true;
|
|
451
|
+
if (timeoutMs !== null) {
|
|
452
|
+
result.timeoutMs = timeoutMs;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
resolve(result);
|
|
456
|
+
};
|
|
457
|
+
const handleExit = (exitCode, signal) => {
|
|
458
|
+
resolveResult(exitCode, signal);
|
|
421
459
|
};
|
|
422
460
|
const handleError = (error) => {
|
|
461
|
+
if (timedOut) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
423
464
|
cleanup();
|
|
424
465
|
reject(error);
|
|
425
466
|
};
|
|
426
467
|
const cleanup = () => {
|
|
427
468
|
child.off('exit', handleExit);
|
|
428
469
|
child.off('error', handleError);
|
|
470
|
+
if (timeoutHandle) {
|
|
471
|
+
clearTimeout(timeoutHandle);
|
|
472
|
+
timeoutHandle = null;
|
|
473
|
+
}
|
|
474
|
+
if (forceKillHandle) {
|
|
475
|
+
clearTimeout(forceKillHandle);
|
|
476
|
+
forceKillHandle = null;
|
|
477
|
+
}
|
|
478
|
+
if (forcedSettleHandle) {
|
|
479
|
+
clearTimeout(forcedSettleHandle);
|
|
480
|
+
forcedSettleHandle = null;
|
|
481
|
+
}
|
|
429
482
|
};
|
|
483
|
+
if (timeoutMs !== null) {
|
|
484
|
+
timeoutHandle = setTimeout(() => {
|
|
485
|
+
timedOut = true;
|
|
486
|
+
if (!child.killed) {
|
|
487
|
+
try {
|
|
488
|
+
child.kill('SIGTERM');
|
|
489
|
+
}
|
|
490
|
+
catch {
|
|
491
|
+
// ignore kill errors and continue to forced settlement fallback
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
forceKillHandle = setTimeout(() => {
|
|
495
|
+
if (settled) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
try {
|
|
499
|
+
child.kill('SIGKILL');
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
// ignore kill errors and allow forced settlement to conclude
|
|
503
|
+
}
|
|
504
|
+
}, 1000);
|
|
505
|
+
forceKillHandle.unref?.();
|
|
506
|
+
forcedSettleHandle = setTimeout(() => {
|
|
507
|
+
resolveResult(null, 'SIGKILL');
|
|
508
|
+
}, 1500);
|
|
509
|
+
forcedSettleHandle.unref?.();
|
|
510
|
+
}, timeoutMs);
|
|
511
|
+
timeoutHandle.unref?.();
|
|
512
|
+
}
|
|
430
513
|
child.once('exit', handleExit);
|
|
431
514
|
child.once('error', handleError);
|
|
432
515
|
});
|
|
433
516
|
};
|
|
517
|
+
function normalizeTimeoutMs(value) {
|
|
518
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
const normalized = Math.trunc(value);
|
|
522
|
+
if (normalized <= 0) {
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
return normalized;
|
|
526
|
+
}
|
|
@@ -3,6 +3,9 @@ import { readFile, readdir, stat } from 'node:fs/promises';
|
|
|
3
3
|
import { join, relative } from 'node:path';
|
|
4
4
|
const PROMPT_SECTIONS = ['system', 'inject', 'summarize', 'extract', 'optimize'];
|
|
5
5
|
const PROMPT_PACK_DIR = ['.agent', 'prompts', 'prompt-packs'];
|
|
6
|
+
const DEFAULT_PROMPT_PACK_RETRIEVAL_POLICY_KIND = 'competitive_scoring_v1';
|
|
7
|
+
const DEFAULT_PROMPT_PACK_SOURCE_GROUPING = 'provenance_fallback_v1';
|
|
8
|
+
const DEFAULT_ANTI_DOMINANCE_STRENGTH = 0.5;
|
|
6
9
|
export async function loadPromptPacks(repoRoot) {
|
|
7
10
|
const manifestPaths = await discoverPromptPackManifests(repoRoot);
|
|
8
11
|
const packs = [];
|
|
@@ -17,6 +20,20 @@ export async function loadPromptPacks(repoRoot) {
|
|
|
17
20
|
});
|
|
18
21
|
return packs;
|
|
19
22
|
}
|
|
23
|
+
export async function loadPromptPackMetadata(repoRoot) {
|
|
24
|
+
const manifestPaths = await discoverPromptPackManifests(repoRoot);
|
|
25
|
+
const packs = [];
|
|
26
|
+
for (const manifestPath of manifestPaths) {
|
|
27
|
+
packs.push(await loadPromptPackMetadataEntry(manifestPath, repoRoot));
|
|
28
|
+
}
|
|
29
|
+
packs.sort((a, b) => {
|
|
30
|
+
if (a.domain === b.domain) {
|
|
31
|
+
return a.id.localeCompare(b.id);
|
|
32
|
+
}
|
|
33
|
+
return a.domain.localeCompare(b.domain);
|
|
34
|
+
});
|
|
35
|
+
return packs;
|
|
36
|
+
}
|
|
20
37
|
async function discoverPromptPackManifests(repoRoot) {
|
|
21
38
|
const baseDir = join(repoRoot, ...PROMPT_PACK_DIR);
|
|
22
39
|
let entries;
|
|
@@ -49,15 +66,11 @@ async function discoverPromptPackManifests(repoRoot) {
|
|
|
49
66
|
return manifests;
|
|
50
67
|
}
|
|
51
68
|
async function loadPromptPack(manifestPath, repoRoot) {
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
const raw = await readFile(manifestPath, 'utf8');
|
|
55
|
-
parsed = JSON.parse(raw);
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
throw new Error(`Failed to read prompt pack manifest at ${relative(repoRoot, manifestPath)}: ${String(error)}`);
|
|
59
|
-
}
|
|
69
|
+
const parsed = await readPromptPackManifestFile(manifestPath, repoRoot);
|
|
60
70
|
validateManifest(parsed, manifestPath, repoRoot);
|
|
71
|
+
const id = requireNonEmptyManifestString(parsed.id, 'id', manifestPath, repoRoot);
|
|
72
|
+
const domain = requireNonEmptyManifestString(parsed.domain, 'domain', manifestPath, repoRoot);
|
|
73
|
+
const system = requireNonEmptyManifestString(parsed.system, 'system', manifestPath, repoRoot);
|
|
61
74
|
const sections = {
|
|
62
75
|
system: [],
|
|
63
76
|
inject: [],
|
|
@@ -65,34 +78,70 @@ async function loadPromptPack(manifestPath, repoRoot) {
|
|
|
65
78
|
extract: [],
|
|
66
79
|
optimize: []
|
|
67
80
|
};
|
|
68
|
-
sections.system = [await loadSectionSource(repoRoot, 'system',
|
|
81
|
+
sections.system = [await loadSectionSource(repoRoot, 'system', system, manifestPath)];
|
|
69
82
|
sections.inject = await loadSectionArray(repoRoot, 'inject', parsed.inject ?? [], manifestPath);
|
|
70
83
|
sections.summarize = await loadSectionArray(repoRoot, 'summarize', parsed.summarize ?? [], manifestPath);
|
|
71
84
|
sections.extract = await loadSectionArray(repoRoot, 'extract', parsed.extract ?? [], manifestPath);
|
|
72
85
|
sections.optimize = await loadSectionArray(repoRoot, 'optimize', parsed.optimize ?? [], manifestPath);
|
|
73
86
|
const allSources = PROMPT_SECTIONS.flatMap((section) => sections[section]);
|
|
74
87
|
if (allSources.length === 0) {
|
|
75
|
-
throw new Error(`Prompt pack ${
|
|
88
|
+
throw new Error(`Prompt pack ${id} ${domain} has no sources defined (${relative(repoRoot, manifestPath)})`);
|
|
76
89
|
}
|
|
77
|
-
const
|
|
90
|
+
const experienceSlots = resolvePromptPackExperienceSlots(parsed, manifestPath, repoRoot);
|
|
91
|
+
const retrievalPolicy = normalizePromptPackRetrievalPolicy(parsed.retrievalPolicy);
|
|
92
|
+
const computedStamp = computePromptPackStamp(allSources, {
|
|
93
|
+
experienceSlots,
|
|
94
|
+
retrievalPolicy
|
|
95
|
+
});
|
|
78
96
|
if (!parsed.stamp) {
|
|
79
|
-
throw new Error(`Prompt pack ${
|
|
97
|
+
throw new Error(`Prompt pack ${id} is missing a stamp (manifest: ${relative(repoRoot, manifestPath)})`);
|
|
80
98
|
}
|
|
81
99
|
if (computedStamp !== parsed.stamp) {
|
|
82
|
-
throw new Error(`Prompt pack ${
|
|
100
|
+
throw new Error(`Prompt pack ${id} stamp mismatch. expected ${parsed.stamp}, computed ${computedStamp} (${relative(repoRoot, manifestPath)})`);
|
|
83
101
|
}
|
|
84
|
-
const experienceSlots = Number.isInteger(parsed.experienceSlots) && parsed.experienceSlots >= 0
|
|
85
|
-
? parsed.experienceSlots
|
|
86
|
-
: 0;
|
|
87
102
|
return {
|
|
88
|
-
id
|
|
89
|
-
domain
|
|
103
|
+
id,
|
|
104
|
+
domain,
|
|
90
105
|
stamp: parsed.stamp,
|
|
91
106
|
experienceSlots,
|
|
107
|
+
retrievalPolicy,
|
|
92
108
|
sections,
|
|
93
109
|
sources: allSources
|
|
94
110
|
};
|
|
95
111
|
}
|
|
112
|
+
async function loadPromptPackMetadataEntry(manifestPath, repoRoot) {
|
|
113
|
+
const parsed = await readPromptPackManifestFile(manifestPath, repoRoot);
|
|
114
|
+
validateManifest(parsed, manifestPath, repoRoot);
|
|
115
|
+
const id = requireNonEmptyManifestString(parsed.id, 'id', manifestPath, repoRoot);
|
|
116
|
+
const domain = requireNonEmptyManifestString(parsed.domain, 'domain', manifestPath, repoRoot);
|
|
117
|
+
requireNonEmptyManifestString(parsed.system, 'system', manifestPath, repoRoot);
|
|
118
|
+
if (!parsed.stamp) {
|
|
119
|
+
throw new Error(`Prompt pack ${id} is missing a stamp (manifest: ${relative(repoRoot, manifestPath)})`);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
id,
|
|
123
|
+
domain,
|
|
124
|
+
experienceSlots: resolvePromptPackExperienceSlots(parsed, manifestPath, repoRoot)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function readPromptPackManifestFile(manifestPath, repoRoot) {
|
|
128
|
+
try {
|
|
129
|
+
const raw = await readFile(manifestPath, 'utf8');
|
|
130
|
+
return JSON.parse(raw);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
throw new Error(`Failed to read prompt pack manifest at ${relative(repoRoot, manifestPath)}: ${String(error)}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function resolvePromptPackExperienceSlots(parsed, manifestPath, repoRoot) {
|
|
137
|
+
if (parsed.experienceSlots !== undefined &&
|
|
138
|
+
(typeof parsed.experienceSlots !== 'number' ||
|
|
139
|
+
!Number.isInteger(parsed.experienceSlots) ||
|
|
140
|
+
parsed.experienceSlots < 0)) {
|
|
141
|
+
throw new Error(`Prompt pack ${parsed.id} has invalid experienceSlots; expected a non-negative integer (${relative(repoRoot, manifestPath)})`);
|
|
142
|
+
}
|
|
143
|
+
return parsed.experienceSlots ?? 0;
|
|
144
|
+
}
|
|
96
145
|
function validateManifest(manifest, manifestPath, repoRoot) {
|
|
97
146
|
const missing = [];
|
|
98
147
|
if (!manifest.id) {
|
|
@@ -108,6 +157,69 @@ function validateManifest(manifest, manifestPath, repoRoot) {
|
|
|
108
157
|
throw new Error(`Prompt pack manifest ${relative(repoRoot, manifestPath)} missing required fields: ${missing.join(', ')}`);
|
|
109
158
|
}
|
|
110
159
|
}
|
|
160
|
+
function requireNonEmptyManifestString(value, field, manifestPath, repoRoot) {
|
|
161
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
162
|
+
throw new Error(`Prompt pack manifest ${relative(repoRoot, manifestPath)} has invalid '${field}'; expected a non-empty string (repoRoot: ${repoRoot})`);
|
|
163
|
+
}
|
|
164
|
+
return value.trim();
|
|
165
|
+
}
|
|
166
|
+
function normalizePromptPackRetrievalPolicy(input) {
|
|
167
|
+
const antiDominance = input?.antiDominanceNormalization;
|
|
168
|
+
return {
|
|
169
|
+
kind: normalizeRetrievalPolicyKind(input?.kind),
|
|
170
|
+
minScore: input?.minScore === null || input?.minScore === undefined
|
|
171
|
+
? null
|
|
172
|
+
: normalizeNonNegativeNumber(input.minScore, 'retrievalPolicy.minScore'),
|
|
173
|
+
scoreWeights: {
|
|
174
|
+
gtScore: normalizeNonNegativeNumber(input?.scoreWeights?.gtScore, 'retrievalPolicy.scoreWeights.gtScore', 1),
|
|
175
|
+
relativeRank: normalizeNonNegativeNumber(input?.scoreWeights?.relativeRank, 'retrievalPolicy.scoreWeights.relativeRank', 1)
|
|
176
|
+
},
|
|
177
|
+
antiDominanceNormalization: {
|
|
178
|
+
enabled: normalizeBoolean(antiDominance?.enabled, 'retrievalPolicy.antiDominanceNormalization.enabled', true),
|
|
179
|
+
strength: normalizeNonNegativeNumber(antiDominance?.strength, 'retrievalPolicy.antiDominanceNormalization.strength', DEFAULT_ANTI_DOMINANCE_STRENGTH),
|
|
180
|
+
sourceGrouping: normalizeSourceGrouping(antiDominance?.sourceGrouping)
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function normalizeRetrievalPolicyKind(value) {
|
|
185
|
+
if (!value || !value.trim()) {
|
|
186
|
+
return DEFAULT_PROMPT_PACK_RETRIEVAL_POLICY_KIND;
|
|
187
|
+
}
|
|
188
|
+
if (value !== DEFAULT_PROMPT_PACK_RETRIEVAL_POLICY_KIND) {
|
|
189
|
+
throw new Error(`Unsupported prompt-pack retrieval policy kind '${value}'. Expected '${DEFAULT_PROMPT_PACK_RETRIEVAL_POLICY_KIND}'.`);
|
|
190
|
+
}
|
|
191
|
+
return DEFAULT_PROMPT_PACK_RETRIEVAL_POLICY_KIND;
|
|
192
|
+
}
|
|
193
|
+
function normalizeSourceGrouping(value) {
|
|
194
|
+
if (!value || !value.trim()) {
|
|
195
|
+
return DEFAULT_PROMPT_PACK_SOURCE_GROUPING;
|
|
196
|
+
}
|
|
197
|
+
if (value !== DEFAULT_PROMPT_PACK_SOURCE_GROUPING) {
|
|
198
|
+
throw new Error(`Unsupported prompt-pack source grouping '${value}'. Expected '${DEFAULT_PROMPT_PACK_SOURCE_GROUPING}'.`);
|
|
199
|
+
}
|
|
200
|
+
return DEFAULT_PROMPT_PACK_SOURCE_GROUPING;
|
|
201
|
+
}
|
|
202
|
+
function normalizeNonNegativeNumber(value, field, defaultValue) {
|
|
203
|
+
if (value === undefined) {
|
|
204
|
+
if (defaultValue === undefined) {
|
|
205
|
+
throw new Error(`${field} is required.`);
|
|
206
|
+
}
|
|
207
|
+
return defaultValue;
|
|
208
|
+
}
|
|
209
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
210
|
+
throw new Error(`${field} must be a finite non-negative number.`);
|
|
211
|
+
}
|
|
212
|
+
return value;
|
|
213
|
+
}
|
|
214
|
+
function normalizeBoolean(value, field, defaultValue) {
|
|
215
|
+
if (value === undefined) {
|
|
216
|
+
return defaultValue;
|
|
217
|
+
}
|
|
218
|
+
if (typeof value !== 'boolean') {
|
|
219
|
+
throw new Error(`${field} must be a boolean.`);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
111
223
|
async function loadSectionArray(repoRoot, section, paths, manifestPath) {
|
|
112
224
|
const sources = [];
|
|
113
225
|
for (const relPath of paths) {
|
|
@@ -134,7 +246,7 @@ async function loadSectionSource(repoRoot, section, relativePath, manifestPath)
|
|
|
134
246
|
content
|
|
135
247
|
};
|
|
136
248
|
}
|
|
137
|
-
export function computePromptPackStamp(sources) {
|
|
249
|
+
export function computePromptPackStamp(sources, config) {
|
|
138
250
|
const hash = createHash('sha256');
|
|
139
251
|
const sorted = [...sources].sort((a, b) => {
|
|
140
252
|
if (a.section === b.section) {
|
|
@@ -147,5 +259,24 @@ export function computePromptPackStamp(sources) {
|
|
|
147
259
|
hash.update(source.content, 'utf8');
|
|
148
260
|
hash.update('\n', 'utf8');
|
|
149
261
|
}
|
|
262
|
+
if (config) {
|
|
263
|
+
hash.update(JSON.stringify({
|
|
264
|
+
experienceSlots: config.experienceSlots,
|
|
265
|
+
retrievalPolicy: {
|
|
266
|
+
kind: config.retrievalPolicy.kind,
|
|
267
|
+
minScore: config.retrievalPolicy.minScore,
|
|
268
|
+
scoreWeights: {
|
|
269
|
+
gtScore: config.retrievalPolicy.scoreWeights.gtScore,
|
|
270
|
+
relativeRank: config.retrievalPolicy.scoreWeights.relativeRank
|
|
271
|
+
},
|
|
272
|
+
antiDominanceNormalization: {
|
|
273
|
+
enabled: config.retrievalPolicy.antiDominanceNormalization.enabled,
|
|
274
|
+
strength: config.retrievalPolicy.antiDominanceNormalization.strength,
|
|
275
|
+
sourceGrouping: config.retrievalPolicy.antiDominanceNormalization.sourceGrouping
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}), 'utf8');
|
|
279
|
+
hash.update('\n', 'utf8');
|
|
280
|
+
}
|
|
150
281
|
return hash.digest('hex');
|
|
151
282
|
}
|
|
@@ -1,11 +1,76 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { createWriteStream, mkdtempSync } from 'node:fs';
|
|
2
|
+
import { createWriteStream, mkdtempSync, rmSync } from 'node:fs';
|
|
3
3
|
import { rm } from 'node:fs/promises';
|
|
4
4
|
import { EventEmitter } from 'node:events';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { createInterface } from 'node:readline';
|
|
7
7
|
import { PassThrough } from 'node:stream';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
|
+
const activeArtifactRoots = new Set();
|
|
10
|
+
const artifactCleanupFinalizer = new FinalizationRegistry((retention) => {
|
|
11
|
+
retention.releaseCollectedHolder();
|
|
12
|
+
});
|
|
13
|
+
process.once('exit', () => {
|
|
14
|
+
for (const artifactRoot of activeArtifactRoots) {
|
|
15
|
+
try {
|
|
16
|
+
rmSync(artifactRoot, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Best-effort cleanup only.
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
class ArtifactRetention {
|
|
24
|
+
artifactRoot;
|
|
25
|
+
holderCount = 0;
|
|
26
|
+
cleaned = false;
|
|
27
|
+
cleanupPromise = null;
|
|
28
|
+
constructor(artifactRoot) {
|
|
29
|
+
this.artifactRoot = artifactRoot;
|
|
30
|
+
activeArtifactRoots.add(artifactRoot);
|
|
31
|
+
}
|
|
32
|
+
registerHolder(target, token) {
|
|
33
|
+
if (this.cleaned) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.holderCount += 1;
|
|
37
|
+
artifactCleanupFinalizer.register(target, this, token);
|
|
38
|
+
}
|
|
39
|
+
unregisterHolder(token) {
|
|
40
|
+
if (!artifactCleanupFinalizer.unregister(token)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.releaseHolder();
|
|
44
|
+
}
|
|
45
|
+
releaseCollectedHolder() {
|
|
46
|
+
this.releaseHolder();
|
|
47
|
+
}
|
|
48
|
+
async cleanup() {
|
|
49
|
+
if (this.cleanupPromise) {
|
|
50
|
+
return await this.cleanupPromise;
|
|
51
|
+
}
|
|
52
|
+
if (!this.cleaned) {
|
|
53
|
+
this.cleaned = true;
|
|
54
|
+
this.holderCount = 0;
|
|
55
|
+
this.cleanupPromise = rm(this.artifactRoot, { recursive: true, force: true })
|
|
56
|
+
.catch(() => { })
|
|
57
|
+
.finally(() => {
|
|
58
|
+
activeArtifactRoots.delete(this.artifactRoot);
|
|
59
|
+
})
|
|
60
|
+
.then(() => undefined);
|
|
61
|
+
}
|
|
62
|
+
await this.cleanupPromise;
|
|
63
|
+
}
|
|
64
|
+
releaseHolder() {
|
|
65
|
+
if (this.cleaned || this.holderCount === 0) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.holderCount -= 1;
|
|
69
|
+
if (this.holderCount === 0) {
|
|
70
|
+
void this.cleanup();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
9
74
|
export class ExecClient {
|
|
10
75
|
cliPath;
|
|
11
76
|
cwd;
|
|
@@ -49,11 +114,15 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
49
114
|
eventsFilePath;
|
|
50
115
|
stderrFilePath;
|
|
51
116
|
artifactRoot;
|
|
117
|
+
artifactRetention;
|
|
52
118
|
maxEventBuffer = 200;
|
|
53
119
|
maxStderrBuffer = 200;
|
|
54
120
|
streamsClosed = false;
|
|
121
|
+
artifactsCleaned = false;
|
|
122
|
+
resultSettled = false;
|
|
55
123
|
summaryEvent = null;
|
|
56
124
|
resultPromise;
|
|
125
|
+
resolvedResult = null;
|
|
57
126
|
resolveResult;
|
|
58
127
|
rejectResult;
|
|
59
128
|
constructor(client, baseOptions, child) {
|
|
@@ -64,12 +133,15 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
64
133
|
this.artifactRoot = mkdtempSync(join(tmpdir(), 'codex-exec-'));
|
|
65
134
|
this.eventsFilePath = join(this.artifactRoot, 'events.ndjson');
|
|
66
135
|
this.stderrFilePath = join(this.artifactRoot, 'stderr.log');
|
|
136
|
+
this.artifactRetention = new ArtifactRetention(this.artifactRoot);
|
|
137
|
+
this.artifactRetention.registerHolder(this, this);
|
|
67
138
|
this.eventsStream = createWriteStream(this.eventsFilePath, { flags: 'a' });
|
|
68
139
|
this.stderrStream = createWriteStream(this.stderrFilePath, { flags: 'a' });
|
|
69
140
|
this.resultPromise = new Promise((resolve, reject) => {
|
|
70
141
|
this.resolveResult = resolve;
|
|
71
142
|
this.rejectResult = reject;
|
|
72
143
|
});
|
|
144
|
+
this.artifactRetention.registerHolder(this.resultPromise, this.resultPromise);
|
|
73
145
|
const stdout = child.stdout ?? new PassThrough();
|
|
74
146
|
const stderr = child.stderr ?? new PassThrough();
|
|
75
147
|
const rl = createInterface({ input: stdout, crlfDelay: Infinity });
|
|
@@ -94,7 +166,6 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
94
166
|
this.emit('event', parsed);
|
|
95
167
|
if (parsed.type === 'run:summary') {
|
|
96
168
|
this.summaryEvent = parsed;
|
|
97
|
-
this.resolveResult(this.buildResult());
|
|
98
169
|
this.emit('summary', this.summaryEvent);
|
|
99
170
|
}
|
|
100
171
|
});
|
|
@@ -108,19 +179,32 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
108
179
|
this.emit('stderr', text);
|
|
109
180
|
});
|
|
110
181
|
child.once('error', (error) => {
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
|
|
182
|
+
if (this.listenerCount('error') > 0) {
|
|
183
|
+
this.emit('error', error);
|
|
184
|
+
}
|
|
185
|
+
this.rejectResultOnce(error);
|
|
186
|
+
void this.closeStreams({ preserveArtifacts: false }).catch(() => {
|
|
187
|
+
// Preserve the original child-process failure as the terminal result.
|
|
188
|
+
});
|
|
114
189
|
});
|
|
115
|
-
child.once('close', (code, signal) => {
|
|
116
|
-
this.
|
|
190
|
+
child.once('close', async (code, signal) => {
|
|
191
|
+
const preserveArtifacts = this.summaryEvent !== null;
|
|
192
|
+
try {
|
|
193
|
+
await this.closeStreams({ preserveArtifacts });
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.rejectResultOnce(error);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
117
199
|
this.emit('exit', { code, signal });
|
|
118
200
|
if (!this.summaryEvent) {
|
|
119
201
|
const error = new Error('Exec command exited without emitting a summary event.');
|
|
120
202
|
error.exitCode = code ?? null;
|
|
121
203
|
error.signal = signal ?? null;
|
|
122
|
-
this.
|
|
204
|
+
this.rejectResultOnce(error);
|
|
205
|
+
return;
|
|
123
206
|
}
|
|
207
|
+
this.resolveResultOnce(this.buildResult());
|
|
124
208
|
});
|
|
125
209
|
}
|
|
126
210
|
get events() {
|
|
@@ -147,12 +231,19 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
147
231
|
delete merged.inheritedEnv;
|
|
148
232
|
return this.client.run(merged);
|
|
149
233
|
}
|
|
234
|
+
async cleanupArtifacts() {
|
|
235
|
+
await this.result.catch(() => undefined);
|
|
236
|
+
await this.removeArtifacts();
|
|
237
|
+
}
|
|
150
238
|
buildResult() {
|
|
239
|
+
if (this.resolvedResult) {
|
|
240
|
+
return this.resolvedResult;
|
|
241
|
+
}
|
|
151
242
|
if (!this.summaryEvent) {
|
|
152
243
|
throw new Error('Summary not available');
|
|
153
244
|
}
|
|
154
245
|
const payload = this.summaryEvent.payload;
|
|
155
|
-
|
|
246
|
+
const result = {
|
|
156
247
|
summary: this.summaryEvent,
|
|
157
248
|
events: [...this.eventsList],
|
|
158
249
|
eventsPath: this.eventsFilePath,
|
|
@@ -162,15 +253,48 @@ export class ExecRunHandle extends EventEmitter {
|
|
|
162
253
|
rawStderr: [...this.stderrLines],
|
|
163
254
|
stderrPath: this.stderrFilePath
|
|
164
255
|
};
|
|
256
|
+
this.resolvedResult = result;
|
|
257
|
+
this.artifactRetention.registerHolder(result, result);
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
resolveResultOnce(value) {
|
|
261
|
+
if (this.resultSettled) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.resultSettled = true;
|
|
265
|
+
this.resolveResult(value);
|
|
266
|
+
}
|
|
267
|
+
rejectResultOnce(reason) {
|
|
268
|
+
if (this.resultSettled) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
this.resultSettled = true;
|
|
272
|
+
this.rejectResult(reason);
|
|
165
273
|
}
|
|
166
|
-
closeStreams() {
|
|
274
|
+
async closeStreams(options) {
|
|
167
275
|
if (this.streamsClosed) {
|
|
168
276
|
return;
|
|
169
277
|
}
|
|
170
278
|
this.streamsClosed = true;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
279
|
+
await Promise.all([
|
|
280
|
+
new Promise((resolve) => this.eventsStream.end(resolve)),
|
|
281
|
+
new Promise((resolve) => this.stderrStream.end(resolve))
|
|
282
|
+
]);
|
|
283
|
+
if (!options.preserveArtifacts) {
|
|
284
|
+
await this.removeArtifacts();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async removeArtifacts() {
|
|
288
|
+
if (this.artifactsCleaned) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
this.artifactsCleaned = true;
|
|
292
|
+
this.artifactRetention.unregisterHolder(this);
|
|
293
|
+
this.artifactRetention.unregisterHolder(this.resultPromise);
|
|
294
|
+
if (this.resolvedResult) {
|
|
295
|
+
this.artifactRetention.unregisterHolder(this.resolvedResult);
|
|
296
|
+
}
|
|
297
|
+
await this.artifactRetention.cleanup();
|
|
174
298
|
}
|
|
175
299
|
}
|
|
176
300
|
function buildCliArgs(options) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { load as parseYaml } from 'js-yaml';
|
|
4
3
|
const DEFAULT_CONFIG_PATH = 'design.config.yaml';
|
|
5
4
|
const DEFAULT_RETENTION_DAYS = 30;
|
|
6
5
|
const DEFAULT_CONFIG = {
|
|
@@ -76,6 +75,7 @@ const DEFAULT_CONFIG = {
|
|
|
76
75
|
};
|
|
77
76
|
const DESIGN_REFERENCE_PIPELINE_ID = 'design-reference';
|
|
78
77
|
const HI_FI_TOOLKIT_PIPELINE_ID = 'hi-fi-design-toolkit';
|
|
78
|
+
let designConfigYamlLoader = null;
|
|
79
79
|
export function designPipelineId(result, env = process.env) {
|
|
80
80
|
return selectDesignPipeline(result ?? null, env).id;
|
|
81
81
|
}
|
|
@@ -84,6 +84,7 @@ export async function loadDesignConfig(options = {}) {
|
|
|
84
84
|
const path = options.filePath ?? join(rootDir, DEFAULT_CONFIG_PATH);
|
|
85
85
|
try {
|
|
86
86
|
const raw = await readFile(path, 'utf-8');
|
|
87
|
+
const parseYaml = await loadDesignConfigYaml();
|
|
87
88
|
const parsed = parseYaml(raw);
|
|
88
89
|
const warnings = [];
|
|
89
90
|
const config = normalizeDesignConfig(parsed, warnings);
|
|
@@ -97,6 +98,12 @@ export async function loadDesignConfig(options = {}) {
|
|
|
97
98
|
throw new Error(`Failed to load design config at ${path}: ${error.message}`);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
101
|
+
async function loadDesignConfigYaml() {
|
|
102
|
+
if (!designConfigYamlLoader) {
|
|
103
|
+
designConfigYamlLoader = import('js-yaml').then((module) => module.load);
|
|
104
|
+
}
|
|
105
|
+
return await designConfigYamlLoader;
|
|
106
|
+
}
|
|
100
107
|
export function shouldActivateDesignPipeline(result, env = process.env) {
|
|
101
108
|
return selectDesignPipeline(result, env).shouldRun;
|
|
102
109
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Deprecated shim: keep exports stable while stdio tracking
|
|
1
|
+
// Deprecated shim: keep exports stable for published importers while stdio tracking lives in packages/orchestrator.
|
|
2
2
|
export * from '../../orchestrator/src/exec/stdio.js';
|