@zq-silk/yui 0.15.7 → 0.15.9
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/ARCHITECTURE.md +194 -399
- package/ARCHITECTURE.zh-CN.md +151 -0
- package/README.md +306 -1131
- package/dist/agent/adapterCatalog.js +15 -2
- package/dist/agent/agent.js +23 -3
- package/dist/agent/argumentPolicy.js +7 -1
- package/dist/agent/connectionPlan.js +62 -0
- package/dist/agent/executionComponents.js +158 -0
- package/dist/agent/launchEnvironment.js +31 -3
- package/dist/agent/managedRuntimeEnvironment.js +3 -5
- package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
- package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
- package/dist/artifacts/artifactCapability.js +74 -0
- package/dist/artifacts/artifactCommitLock.js +249 -0
- package/dist/artifacts/artifactPaths.js +151 -0
- package/dist/artifacts/gitArtifactRef.js +146 -0
- package/dist/artifacts/managedGit.js +332 -0
- package/dist/artifacts/taskArtifactRepository.js +277 -0
- package/dist/brief/taskBrief.js +12 -0
- package/dist/cli/agentConfigurationPicker.js +13 -0
- package/dist/cli/commandCatalog.js +165 -74
- package/dist/cli/interactionCandidates.js +5 -5
- package/dist/cli/interactionPolicy.js +38 -8
- package/dist/cli/invocationRouter.js +1 -1
- package/dist/cli/managedDiagnostics.js +28 -0
- package/dist/cli/operatorWizard.js +1 -7
- package/dist/cli/roleOptionOrder.js +27 -0
- package/dist/cli/roleWizard.js +50 -14
- package/dist/cli/updateOrchestrator.js +1 -1
- package/dist/cli/updatePorts.js +3 -4
- package/dist/cli.js +245 -95
- package/dist/commands/agentCommands.js +72 -14
- package/dist/commands/capabilityCommands.js +9 -6
- package/dist/commands/configCommands.js +20 -20
- package/dist/commands/deliveryGuardPreflight.js +2 -2
- package/dist/commands/executionAuditCommands.js +24 -24
- package/dist/commands/globalRoleCommands.js +1 -1
- package/dist/commands/grantCommands.js +4 -4
- package/dist/commands/operatorCommands.js +34 -9
- package/dist/commands/projectCommands.js +4 -4
- package/dist/commands/resourcesCommands.js +2 -2
- package/dist/commands/roleConfiguration.js +25 -5
- package/dist/commands/roleRuntimeGuard.js +4 -5
- package/dist/commands/sessionCommands.js +3 -7
- package/dist/commands/taskActivationCommands.js +281 -0
- package/dist/commands/taskActor.js +28 -49
- package/dist/commands/taskCommands.js +1461 -720
- package/dist/commands/taskContextCommand.js +39 -583
- package/dist/commands/taskExecutionCommands.js +32 -32
- package/dist/commands/taskInputCommands.js +40 -104
- package/dist/commands/taskIntegrationCommands.js +3 -2
- package/dist/commands/taskIntegrationQueueCommands.js +1 -1
- package/dist/commands/taskNextActionCommand.js +8 -8
- package/dist/commands/taskOverviewCommand.js +33 -45
- package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
- package/dist/commands/taskRoleRuntimeStatus.js +133 -102
- package/dist/commands/telemetryCommands.js +36 -38
- package/dist/config/configCatalog.js +4 -4
- package/dist/config/yuiConfig.js +8 -8
- package/dist/context/contextSnapshot.js +10 -10
- package/dist/context/dispatchContext.js +11 -11
- package/dist/context/roleSessionContext.js +6 -3
- package/dist/context/{turnContextPack.js → runContextPack.js} +158 -81
- package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
- package/dist/context/sessionBootstrapManifest.js +21 -2
- package/dist/context/sourceRunContext.js +30 -0
- package/dist/context/taskContext.js +481 -0
- package/dist/context/wakeNotification.js +27 -27
- package/dist/controller/agentRuntimeObserver.js +21 -24
- package/dist/controller/capabilityBridge.js +17 -6
- package/dist/controller/clientRuntime.js +65 -92
- package/dist/controller/controller.js +120 -188
- package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
- package/dist/controller/jobControl.js +54 -85
- package/dist/controller/resourceInventory.js +8 -27
- package/dist/controller/resourceInventoryLinux.js +12 -13
- package/dist/controller/runtime.js +529 -479
- package/dist/controller/runtimeEventInbox.js +55 -25
- package/dist/controller/runtimeEventProcessor.js +22 -31
- package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
- package/dist/controller/runtimeLaunchCoordinator.js +80 -426
- package/dist/controller/runtimeObservationHook.js +14 -18
- package/dist/controller/sessionNotify.js +16 -24
- package/dist/controller/sessionOwnerReconciliation.js +168 -50
- package/dist/controller/structuredProviderObservation.js +138 -99
- package/dist/coordination/workMailbox.js +3 -3
- package/dist/coordination/workMailboxQueue.js +36 -33
- package/dist/core/boundedRpc.js +8 -1
- package/dist/core/controllerClient.js +20 -1
- package/dist/core/controllerServer.js +4 -4
- package/dist/doctor/doctor.js +13 -2
- package/dist/domain/agentResultTransport.js +9 -9
- package/dist/execution/codexThreadNaming.js +2 -8
- package/dist/execution/executionHealth.js +51 -63
- package/dist/execution/reviewMainRun.js +137 -0
- package/dist/execution/workItemExecution.js +28 -29
- package/dist/execution/workItemExecutionProjection.js +99 -107
- package/dist/execution/workItemMainRun.js +141 -0
- package/dist/executor/agentAdapter.js +227 -20
- package/dist/executor/agentConfigurationCatalog.js +126 -4
- package/dist/executor/agentConfigurationProbe.js +162 -4
- package/dist/executor/agentExecutor.js +79 -78
- package/dist/executor/effectiveLaunch.js +105 -18
- package/dist/executor/executorRegistry.js +29 -44
- package/dist/executor/fileRoleLaunchPlanner.js +229 -154
- package/dist/executor/workspacePreflightClassification.js +16 -16
- package/dist/grant/capabilityGrant.js +6 -3
- package/dist/input/inputRequest.js +12 -10
- package/dist/integration/gitIntegrationService.js +4 -11
- package/dist/integration/integrationQueueService.js +4 -4
- package/dist/interaction/operatorPresentation.js +1 -1
- package/dist/kernel/builtinCapabilities.js +255 -12
- package/dist/kernel/capabilityRegistry.js +64 -18
- package/dist/kernel/instanceHost.js +12 -1
- package/dist/kernel/kernelPorts.js +2 -2
- package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
- package/dist/lifecycle/exactRunTerminalization.js +449 -0
- package/dist/message/message.js +118 -6
- package/dist/message/messageContinuation.js +204 -0
- package/dist/observability/executionAudit.js +70 -72
- package/dist/observability/faultClassification.js +2 -2
- package/dist/observability/orchestrationMetrics.js +8 -8
- package/dist/operator/operatorSessionHistory.js +1 -7
- package/dist/output/agentConfigurationPresentation.js +8 -3
- package/dist/output/agentRunConfigurationPresentation.js +128 -0
- package/dist/output/rolePresentation.js +54 -3
- package/dist/plugins/pluginChild.js +104 -0
- package/dist/plugins/pluginIntent.js +26 -0
- package/dist/plugins/pluginInterpreter.js +43 -0
- package/dist/plugins/pluginPackage.js +101 -0
- package/dist/plugins/pluginProcess.js +112 -0
- package/dist/plugins/pluginService.js +388 -0
- package/dist/profile/agentProfile.js +1 -1
- package/dist/repository/gitWorkspace.js +26 -4
- package/dist/repository/project.js +19 -4
- package/dist/repository/taskBaseFreshness.js +13 -13
- package/dist/repository/taskWorkspaceCoordinator.js +20 -27
- package/dist/repository/taskWorkspacePreparer.js +344 -83
- package/dist/resources/autoResourceGc.js +3 -3
- package/dist/resources/liveReferences.js +3 -3
- package/dist/resources/projectResource.js +75 -0
- package/dist/resources/projectResourceService.js +343 -0
- package/dist/resources/resourceDiscovery.js +6 -6
- package/dist/resources/resourceGc.js +1 -1
- package/dist/resources/resourceRegistrar.js +1 -1
- package/dist/resources/resourceTypes.js +1 -1
- package/dist/review/deltaRecheck.js +3 -3
- package/dist/review/reviewAcceptance.js +16 -16
- package/dist/review/reviewDecision.js +7 -7
- package/dist/review/reviewRound.js +21 -20
- package/dist/review/reviewerAvailability.js +2 -2
- package/dist/role/role.js +51 -7
- package/dist/role/taskRoleUpdate.js +30 -0
- package/dist/runtime/acpProtocol.js +425 -0
- package/dist/runtime/acpSession.js +731 -0
- package/dist/runtime/acpSessionConfiguration.js +260 -0
- package/dist/runtime/agentDriver.js +30 -11
- package/dist/runtime/agentEndpoint.js +278 -0
- package/dist/runtime/agentEndpointIdentity.js +86 -0
- package/dist/runtime/agentEndpointOwnership.js +239 -0
- package/dist/runtime/agentError.js +2 -10
- package/dist/runtime/agentHost.js +565 -314
- package/dist/runtime/agentRunConfiguration.js +258 -0
- package/dist/runtime/builtinAgentDrivers.js +134 -18
- package/dist/runtime/builtinAgentErrorMappers.js +55 -3
- package/dist/runtime/builtinTranscriptUsage.js +1 -1
- package/dist/runtime/claude-process-owner +0 -0
- package/dist/runtime/codexAppServerRuntime.js +38 -30
- package/dist/runtime/codexInteractiveHost.js +41 -6
- package/dist/runtime/continuationManager.js +2 -6
- package/dist/runtime/executionEnvironment.js +30 -0
- package/dist/runtime/firstProgressAdvisory.js +11 -11
- package/dist/runtime/index.js +4 -3
- package/dist/runtime/jsonLineChannel.js +109 -0
- package/dist/runtime/launchBroker.js +91 -16
- package/dist/runtime/launchDiagnostics.js +2 -2
- package/dist/runtime/lifecycleReservation.js +10 -18
- package/dist/runtime/managedCaller.js +61 -17
- package/dist/runtime/nativeSessionControl.js +102 -0
- package/dist/runtime/ports.js +6 -21
- package/dist/runtime/processExitObservation.js +8 -7
- package/dist/runtime/promptEnvelope.js +17 -6
- package/dist/runtime/providerContinuation.js +3 -9
- package/dist/runtime/providerContinuationReconciliationService.js +4 -13
- package/dist/runtime/providerControl.js +2 -7
- package/dist/runtime/providerRuntimeIdentity.js +110 -222
- package/dist/runtime/providerRuntimeReconciler.js +5 -9
- package/dist/runtime/runtimeBinding.js +0 -1
- package/dist/runtime/runtimeContinuationProjection.js +4 -7
- package/dist/runtime/runtimeDeadlines.js +9 -0
- package/dist/runtime/runtimeHealthPolicy.js +1 -1
- package/dist/runtime/runtimeObservation.js +29 -65
- package/dist/runtime/runtimeProjection.js +43 -51
- package/dist/runtime/runtimeSessionCandidate.js +1 -3
- package/dist/runtime/sessionLaunchRequest.js +3 -7
- package/dist/runtime/sessionOwnerIdentity.js +7 -54
- package/dist/runtime/sessionOwnerRegistry.js +22 -17
- package/dist/runtime/sessionReconciliation.js +4 -8
- package/dist/runtime/sessionTerminationGuard.js +70 -259
- package/dist/runtime/sessionTokenMetrics.js +5 -16
- package/dist/runtime/structuredProviderHost.js +237 -117
- package/dist/runtime/taskRuntimeIsolation.js +39 -122
- package/dist/runtime/tmuxAdapters.js +39 -86
- package/dist/scheduler/activeRoleRunDelivery.js +354 -0
- package/dist/scheduler/leaderWakeupProcessor.js +75 -266
- package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
- package/dist/scheduler/ports.js +80 -9
- package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
- package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
- package/dist/scheduler/taskExecutionProjection.js +120 -124
- package/dist/scheduler/taskObservabilityProjection.js +29 -29
- package/dist/scheduler/taskWake.js +11 -4
- package/dist/scheduler/wakeReason.js +9 -1
- package/dist/setup/setupCommand.js +3 -7
- package/dist/storage/migrations/agentRunContract.js +159 -0
- package/dist/storage/migrations/artifactsToGit.js +338 -0
- package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
- package/dist/storage/migrations/submitIntent.js +126 -0
- package/dist/storage/sqliteSchema.js +467 -7
- package/dist/storage/sqliteStore.js +355 -220
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +10 -5
- package/dist/storage/taskStore.js +13 -11
- package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
- package/dist/surface/surfaceContributions.js +102 -0
- package/dist/task/completionReadiness.js +32 -6
- package/dist/task/deliveryGuard.js +16 -16
- package/dist/task/draftPlan.js +72 -12
- package/dist/task/nextAction.js +144 -128
- package/dist/task/remoteDelivery.js +6 -6
- package/dist/task/task.js +184 -18
- package/dist/task/taskActivation.js +327 -0
- package/dist/task/taskActivationService.js +408 -0
- package/dist/task/taskRecordReference.js +5 -4
- package/dist/task/taskRecordRetirement.js +1 -1
- package/dist/task/taskSubmission.js +236 -0
- package/dist/telemetry/sqliteTelemetryStore.js +55 -68
- package/dist/telemetry/telemetryConfig.js +14 -14
- package/dist/telemetry/telemetryWiring.js +2 -2
- package/dist/web/assets/assetManifest.js +2 -0
- package/dist/web/assets/client/app.js +121 -20
- package/dist/web/assets/client/components.js +87 -54
- package/dist/web/assets/client/i18n.js +83 -41
- package/dist/web/assets/client/markdown.js +1 -1
- package/dist/web/assets/client/taskSurface.js +442 -0
- package/dist/web/assets/client/view.js +49 -44
- package/dist/web/assets/shell.js +1 -1
- package/dist/web/assets/styles/cards.js +22 -4
- package/dist/web/controllerWeb.js +60 -0
- package/dist/web/webMutation.js +28 -0
- package/dist/web/webServer.js +133 -8
- package/dist/web/webSnapshot.js +81 -74
- package/dist/web/webTaskSurface.js +64 -0
- package/dist/workItem/dependencyGate.js +1 -1
- package/dist/workItem/workItem.js +84 -48
- package/dist/workspace/workItemChangeSetManager.js +16 -9
- package/docs/agent-result-consumption.md +96 -0
- package/docs/agent-result-consumption.zh-CN.md +81 -0
- package/docs/agent-runtime-drivers.md +93 -0
- package/docs/agent-runtime-drivers.zh-CN.md +77 -0
- package/docs/architecture/README.md +50 -0
- package/docs/architecture/README.zh-CN.md +43 -0
- package/docs/architecture/capabilities-and-resources.md +118 -0
- package/docs/architecture/capabilities-and-resources.zh-CN.md +83 -0
- package/docs/managed-turn-and-session-runtime.md +224 -0
- package/docs/managed-turn-and-session-runtime.zh-CN.md +180 -0
- package/docs/observability/README.md +83 -0
- package/docs/observability/README.zh-CN.md +71 -0
- package/docs/plugin-sdk.md +393 -0
- package/docs/plugin-sdk.zh-CN.md +293 -0
- package/docs/provider-runtime.md +165 -0
- package/docs/provider-runtime.zh-CN.md +132 -0
- package/docs/release-workflow.md +305 -0
- package/docs/release-workflow.zh-CN.md +237 -0
- package/docs/roles-and-configuration.md +115 -0
- package/docs/roles-and-configuration.zh-CN.md +96 -0
- package/docs/sqlite-control-plane-design.md +78 -0
- package/docs/sqlite-control-plane-design.zh-CN.md +62 -0
- package/docs/task-dag-semantics.md +80 -0
- package/docs/task-dag-semantics.zh-CN.md +59 -0
- package/docs/task-delivery.md +105 -0
- package/docs/task-delivery.zh-CN.md +82 -0
- package/docs/task-local-identity.md +8 -6
- package/docs/task-local-identity.zh-CN.md +58 -0
- package/docs/testing/verification-levels.md +88 -0
- package/docs/testing/verification-levels.zh-CN.md +69 -0
- package/i18n/README.zh-CN.md +270 -722
- package/package.json +3 -2
- package/skills/yui-leader/SKILL.md +88 -304
- package/skills/yui-leader/references/execution.md +303 -0
- package/skills/yui-leader/references/integration.md +39 -0
- package/skills/yui-leader/references/planning.md +109 -0
- package/skills/yui-leader/references/replicated-execution.md +42 -0
- package/skills/yui-leader/references/task-plugins.md +37 -0
- package/skills/yui-operator/SKILL.md +46 -62
- package/skills/yui-reviewer/SKILL.md +35 -36
- package/skills/yui-runtime/SKILL.md +88 -24
- package/skills/yui-runtime/references/publication.md +22 -0
- package/skills/yui-runtime/references/recovery.md +64 -0
- package/skills/yui-worker/SKILL.md +37 -39
- package/dist/cli/roleOptionCatalog.js +0 -68
- package/dist/context/sourceTurnContext.js +0 -30
- package/dist/execution/reviewMainTurn.js +0 -161
- package/dist/execution/workItemMainTurn.js +0 -164
- package/dist/lifecycle/exactTurnTerminalization.js +0 -407
- package/dist/runtime/preallocatedNativeSession.js +0 -13
- package/dist/runtime/runtimeStopReceipt.js +0 -42
- package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { agentAdapterLabel as adapterLabel } from "./agent/adapterCatalog.js";
|
|
3
5
|
import { readFileSync } from "node:fs";
|
|
4
6
|
import { resolve } from "node:path";
|
|
5
7
|
import { createInterface } from "node:readline/promises";
|
|
@@ -43,7 +45,8 @@ import { assertTaskRemoteDeliveryIntegrated, createTaskRemoteDeliveryProof } fro
|
|
|
43
45
|
import { runTaskPublicationVerifyCommand } from "./commands/taskPublicationVerifyCommand.js";
|
|
44
46
|
import { createGitHubCliPublicationVerifier } from "./external/githubPublicationVerifier.js";
|
|
45
47
|
import { createGitLabCliPublicationVerifier } from "./external/gitlabPublicationVerifier.js";
|
|
46
|
-
import {
|
|
48
|
+
import { taskLocalActor, assertTaskDeliveryAuthority } from "./commands/taskActor.js";
|
|
49
|
+
import { saveArtifactCapability, readArtifactCapability, listArtifactsCapability } from "./artifacts/artifactCapability.js";
|
|
47
50
|
import { parseTaskExecutionStartRequest, parseTaskExecutionStopRequest, finalizeStoppedTaskExecution, startTaskExecutionCommand, stopTaskExecutionCommand } from "./commands/taskExecutionCommands.js";
|
|
48
51
|
import { runTaskIntegrationCommand } from "./commands/taskIntegrationCommands.js";
|
|
49
52
|
import { runTaskChangeSetCommand } from "./commands/taskChangeSetCommands.js";
|
|
@@ -72,7 +75,8 @@ import { runRuntimeObservationHookCommand } from "./controller/runtimeObservatio
|
|
|
72
75
|
import { buildDoctorReport, renderDoctor, runDoctorCommand } from "./doctor/doctor.js";
|
|
73
76
|
import { agentNotFound, CliError, runtimeError, usageError } from "./errors/cliError.js";
|
|
74
77
|
import { FileRoleLaunchPlanner } from "./executor/fileRoleLaunchPlanner.js";
|
|
75
|
-
import { AGENT_HOST_CONTROL_PROTOCOL, runAgentHost, sendAgentHostAuthorityControl } from "./runtime/agentHost.js";
|
|
78
|
+
import { AGENT_HOST_CONTROL_PROTOCOL, inspectAgentHost, runAgentHost, sendAgentHostAuthorityControl } from "./runtime/agentHost.js";
|
|
79
|
+
import { unknownAgentRunConfiguration } from "./runtime/agentRunConfiguration.js";
|
|
76
80
|
import { TaskWorkspaceCoordinator, WorkspaceCleanupBlockedError } from "./repository/taskWorkspaceCoordinator.js";
|
|
77
81
|
import { FileTaskWorkspacePreparer } from "./repository/taskWorkspacePreparer.js";
|
|
78
82
|
import { inspectStorageSchema } from "./storage/storageSchema.js";
|
|
@@ -85,15 +89,15 @@ import { NodeCommandExecutor } from "./tmux/commandExecutor.js";
|
|
|
85
89
|
import { TmuxManager } from "./tmux/tmuxManager.js";
|
|
86
90
|
import { WorkItemChangeSetManager } from "./workspace/workItemChangeSetManager.js";
|
|
87
91
|
import { workspaceProjectEntry } from "./worktree/managedWorkspace.js";
|
|
88
|
-
import { parseWebCommandOptions
|
|
92
|
+
import { parseWebCommandOptions } from "./web/webServer.js";
|
|
89
93
|
import { AgentConfigurationCatalogService, validateAgentLaunchConfiguration } from "./executor/agentConfigurationCatalog.js";
|
|
90
94
|
import { resolveAgentProfileView } from "./profile/agentProfileRuntime.js";
|
|
91
|
-
import { TmuxWebTerminalService } from "./web/tmuxWebTerminal.js";
|
|
92
95
|
import { listOperatorSessions, operatorSessionRef } from "./operator/operatorSessionHistory.js";
|
|
93
96
|
import { YUI_VERSION, yuiVersionIdentity } from "./version.js";
|
|
94
97
|
import { SqliteSchemaMigrationError } from "./storage/sqliteSchema.js";
|
|
95
|
-
import { assertRuntimeCoherence
|
|
96
|
-
import { requireManagedTaskCaller } from "./runtime/managedCaller.js";
|
|
98
|
+
import { assertRuntimeCoherence } from "./runtime/runtimeCoherence.js";
|
|
99
|
+
import { requireManagedTaskCaller, resolveManagedTaskReader } from "./runtime/managedCaller.js";
|
|
100
|
+
import { operatorOfflineCommand, taskDiagnosticTarget } from "./cli/managedDiagnostics.js";
|
|
97
101
|
import { readSessionBootstrapManifest, refreshManagedSessionCliWrappers } from "./context/sessionBootstrapManifest.js";
|
|
98
102
|
import { createTaskFinalReviewContract, extractTaskFinalReviewRequest } from "./review/taskFinalReviewContract.js";
|
|
99
103
|
import { resolveRecordedTaskFinalReviewContract } from "./review/taskFinalReviewContractResolution.js";
|
|
@@ -146,7 +150,7 @@ export async function main() {
|
|
|
146
150
|
|| routedForFence?.kind === "help"
|
|
147
151
|
|| routedForFence?.kind === "path-error"
|
|
148
152
|
|| routedForFence?.kind === "incomplete";
|
|
149
|
-
if (
|
|
153
|
+
if (!homeFreeInvocation) {
|
|
150
154
|
assertCliHomeReleaseFence({
|
|
151
155
|
home,
|
|
152
156
|
packageRoot: fileURLToPath(new URL("../", import.meta.url)),
|
|
@@ -170,7 +174,6 @@ export async function main() {
|
|
|
170
174
|
process.exitCode = delegated.status ?? 5;
|
|
171
175
|
return;
|
|
172
176
|
}
|
|
173
|
-
const { contract: taskFinalReviewContract, verifiedStore } = await preflightManagedTaskControlPlane();
|
|
174
177
|
if (args.length === 0) {
|
|
175
178
|
emit(renderCommandHelp((await import("./cli/commandCatalog.js")).ROOT_COMMAND, VERSION));
|
|
176
179
|
return;
|
|
@@ -192,6 +195,7 @@ export async function main() {
|
|
|
192
195
|
}
|
|
193
196
|
if (args[0] === "version")
|
|
194
197
|
throw usageError("Version usage: yui version");
|
|
198
|
+
const { contract: taskFinalReviewContract, verifiedStore } = await preflightManagedTaskControlPlane();
|
|
195
199
|
if (args[0] === "update") {
|
|
196
200
|
if (jsonOutput)
|
|
197
201
|
throw usageError("Update does not support --json.");
|
|
@@ -328,11 +332,10 @@ export async function main() {
|
|
|
328
332
|
+ `${result.current} already current, ${result.skipped} skipped.`, false, result);
|
|
329
333
|
return;
|
|
330
334
|
}
|
|
331
|
-
if (args[1] === "agent-host" && args.length ===
|
|
335
|
+
if (args[1] === "agent-host" && args.length === 3) {
|
|
332
336
|
process.exitCode = await runAgentHost({
|
|
333
337
|
home,
|
|
334
|
-
|
|
335
|
-
ticket: args[3]
|
|
338
|
+
ticket: args[2]
|
|
336
339
|
});
|
|
337
340
|
return;
|
|
338
341
|
}
|
|
@@ -343,7 +346,7 @@ export async function main() {
|
|
|
343
346
|
if (args[1] === "runtime-hook" && args.length === 2) {
|
|
344
347
|
// Provider lifecycle Hooks are observation channels, never execution
|
|
345
348
|
// gates. A late/stale Hook must not make Claude reject an otherwise
|
|
346
|
-
// valid Session or
|
|
349
|
+
// valid Session or AgentRun; its exact fence is revalidated before any
|
|
347
350
|
// inbox fact is written, so dropping an invalid observation is safe.
|
|
348
351
|
try {
|
|
349
352
|
await runRuntimeObservationHookCommand(readFileSync(0, "utf8"), process.env);
|
|
@@ -549,7 +552,8 @@ export async function main() {
|
|
|
549
552
|
emit(result.output, false, result.data);
|
|
550
553
|
return;
|
|
551
554
|
}
|
|
552
|
-
|
|
555
|
+
if (!operatorOfflineCommand(args))
|
|
556
|
+
await assertFileTaskControllerStorageCompatible(home);
|
|
553
557
|
// Reuse the store the exact runtime preflight already opened and read for
|
|
554
558
|
// this same Home. Opening a second store would parse the unchanged large
|
|
555
559
|
// state a second time; the per-instance fingerprint cache still invalidates
|
|
@@ -586,46 +590,37 @@ export async function main() {
|
|
|
586
590
|
});
|
|
587
591
|
const workspaceCoordinator = new TaskWorkspaceCoordinator(store, workspacePreparer, runtime);
|
|
588
592
|
if (resolved[0] === "web") {
|
|
593
|
+
if (managedInvocation || process.env.YUI_ROLE || process.env.YUI_NATIVE_SESSION_ID) {
|
|
594
|
+
throw usageError("The Web user ingress must be started from a local user terminal, not a managed Session.");
|
|
595
|
+
}
|
|
596
|
+
if (resolved.length === 2 && (resolved[1] === "--status" || resolved[1] === "--stop")) {
|
|
597
|
+
const status = await callController(home, "web.status", {});
|
|
598
|
+
if (resolved[1] === "--status")
|
|
599
|
+
emit(status ? `Yui web control room: ${status.url}\n` : "Web is not running.\n", false, status);
|
|
600
|
+
else {
|
|
601
|
+
if (status)
|
|
602
|
+
await callController(home, "web.stop", { id: status.id });
|
|
603
|
+
emit("Web listener stopped; Controller and Agents are unchanged.\n");
|
|
604
|
+
}
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
589
607
|
if (jsonOutput)
|
|
590
|
-
throw usageError("Web does not support --json.");
|
|
608
|
+
throw usageError("Web start does not support --json; use --status.");
|
|
591
609
|
const options = parseWebCommandOptions(resolved.slice(1));
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
tmuxBin: resolveTmuxBin(store.getConfig().tmuxBin),
|
|
595
|
-
tmux,
|
|
596
|
-
prepareGlobalRole: (roleName) => runtime.prepareGlobalRoleEnter(roleName),
|
|
597
|
-
environment: process.env,
|
|
598
|
-
onError: (error) => {
|
|
599
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
600
|
-
process.stderr.write(`Web terminal cleanup error: ${message}\n`);
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
await startYuiWebServer(store, options, {
|
|
604
|
-
terminal,
|
|
605
|
-
answerInput: async ({ taskId, inputId, answer }) => {
|
|
606
|
-
const command = [
|
|
607
|
-
"input", "answer", inputId, "--task", taskId,
|
|
608
|
-
...("choiceKey" in answer
|
|
609
|
-
? ["--choice", answer.choiceKey]
|
|
610
|
-
: ["--text", answer.text])
|
|
611
|
-
];
|
|
612
|
-
const result = runTaskCommand(command, store, {
|
|
613
|
-
runtime,
|
|
614
|
-
environment: {},
|
|
615
|
-
yuiHome: home
|
|
616
|
-
});
|
|
617
|
-
if (result.kind !== "output") {
|
|
618
|
-
throw new Error("Input answer returned an invalid control result.");
|
|
619
|
-
}
|
|
620
|
-
const data = result.data;
|
|
621
|
-
if (data?.request === undefined) {
|
|
622
|
-
throw new Error("Input answer did not return the updated request.");
|
|
623
|
-
}
|
|
624
|
-
return data.request;
|
|
625
|
-
}
|
|
626
|
-
});
|
|
610
|
+
const id = randomUUID();
|
|
611
|
+
await callController(home, "web.start", { ...options, id });
|
|
627
612
|
const displayHost = options.host === "::1" ? "[::1]" : options.host;
|
|
628
613
|
process.stdout.write(`Yui web control room: http://${displayHost}:${options.port}\n`);
|
|
614
|
+
await new Promise((resolve) => {
|
|
615
|
+
const stop = () => {
|
|
616
|
+
process.off("SIGINT", stop);
|
|
617
|
+
process.off("SIGTERM", stop);
|
|
618
|
+
resolve();
|
|
619
|
+
};
|
|
620
|
+
process.once("SIGINT", stop);
|
|
621
|
+
process.once("SIGTERM", stop);
|
|
622
|
+
});
|
|
623
|
+
await callController(home, "web.stop", { id });
|
|
629
624
|
return;
|
|
630
625
|
}
|
|
631
626
|
if (resolved[0] === "config") {
|
|
@@ -779,6 +774,72 @@ export async function main() {
|
|
|
779
774
|
return;
|
|
780
775
|
}
|
|
781
776
|
if (resolved[0] === "task") {
|
|
777
|
+
if (resolved[1] === "artifact") {
|
|
778
|
+
// File/directory artifacts live in the Task's local Git repository, so
|
|
779
|
+
// their save/read/list are asynchronous and handled here rather than in
|
|
780
|
+
// the synchronous runTaskCommand chain. Save commits exactly one path and
|
|
781
|
+
// returns a self-certifying commit-pinned reference; read pins to a commit
|
|
782
|
+
// for frozen evidence; list is an ordinary current read.
|
|
783
|
+
const action = resolved[2];
|
|
784
|
+
const taskId = resolved[3];
|
|
785
|
+
const usage = "Usage: yui task artifact list <task> | read <task> <relative-path> [<commit>] | "
|
|
786
|
+
+ "save <task> <relative-path> <content> [--message <text>] [--expected-head <commit>]";
|
|
787
|
+
if (taskId === undefined || action === undefined || !["list", "read", "save"].includes(action)) {
|
|
788
|
+
throw usageError(usage);
|
|
789
|
+
}
|
|
790
|
+
if (process.env.YUI_SESSION_SCOPE === "task" && process.env.YUI_TASK_ID !== taskId) {
|
|
791
|
+
throw usageError("Artifact is outside the managed Task scope.");
|
|
792
|
+
}
|
|
793
|
+
if (store.getTask(taskId) === null)
|
|
794
|
+
throw usageError(`Task not found: ${taskId}.`);
|
|
795
|
+
let data;
|
|
796
|
+
if (action === "list") {
|
|
797
|
+
if (resolved.length !== 4)
|
|
798
|
+
throw usageError(usage);
|
|
799
|
+
data = await listArtifactsCapability(home, taskId);
|
|
800
|
+
}
|
|
801
|
+
else if (action === "read") {
|
|
802
|
+
const relativePath = resolved[4];
|
|
803
|
+
const commit = resolved[5];
|
|
804
|
+
if (relativePath === undefined || resolved.length > 6)
|
|
805
|
+
throw usageError(usage);
|
|
806
|
+
data = await readArtifactCapability(home, taskId, {
|
|
807
|
+
relativePath, ...(commit === undefined ? {} : { commit })
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
// save: a delivery-authoritative action; a managed Task caller must be the current Leader.
|
|
812
|
+
taskLocalActor(store, process.env, taskId);
|
|
813
|
+
const relativePath = resolved[4];
|
|
814
|
+
const content = resolved[5];
|
|
815
|
+
if (relativePath === undefined || content === undefined)
|
|
816
|
+
throw usageError(usage);
|
|
817
|
+
const rest = resolved.slice(6);
|
|
818
|
+
let message;
|
|
819
|
+
let expectedHead;
|
|
820
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
821
|
+
const value = rest[index + 1];
|
|
822
|
+
if (rest[index] === "--message" && value !== undefined) {
|
|
823
|
+
message = value;
|
|
824
|
+
index += 1;
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
if (rest[index] === "--expected-head" && value !== undefined) {
|
|
828
|
+
expectedHead = value;
|
|
829
|
+
index += 1;
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
throw usageError(usage);
|
|
833
|
+
}
|
|
834
|
+
data = await saveArtifactCapability(home, taskId, {
|
|
835
|
+
relativePath, content,
|
|
836
|
+
...(message === undefined ? {} : { message }),
|
|
837
|
+
...(expectedHead === undefined ? {} : { expectedHead })
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
emit(JSON.stringify(data, null, 2), false, data);
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
782
843
|
if (resolved[1] === "execution") {
|
|
783
844
|
if (resolved[2] === "stop") {
|
|
784
845
|
const request = parseTaskExecutionStopRequest(resolved.slice(3));
|
|
@@ -803,7 +864,7 @@ export async function main() {
|
|
|
803
864
|
if (task === null)
|
|
804
865
|
throw usageError(`Task not found: ${taskId}.`);
|
|
805
866
|
// Reject managed Task callers before inspecting or starting runtime resources.
|
|
806
|
-
if (
|
|
867
|
+
if (taskLocalActor(store, process.env, taskId) === "leader") {
|
|
807
868
|
throw usageError("Task execution stop/start requires the global Operator or a human user.");
|
|
808
869
|
}
|
|
809
870
|
if (task.executionGate.state === "stopped") {
|
|
@@ -845,7 +906,7 @@ export async function main() {
|
|
|
845
906
|
},
|
|
846
907
|
candidateForTask: async (taskId) => {
|
|
847
908
|
const status = store.getTask(taskId)?.status;
|
|
848
|
-
return status === "active" || status === "
|
|
909
|
+
return status === "active" || status === "cancelled"
|
|
849
910
|
? snapshotActualTaskReviewCandidate(taskId, store, workspacePreparer)
|
|
850
911
|
: null;
|
|
851
912
|
},
|
|
@@ -911,7 +972,7 @@ export async function main() {
|
|
|
911
972
|
throw usageError("Task work capture usage: yui task work capture <task>/<work>.");
|
|
912
973
|
}
|
|
913
974
|
const reference = cliWorkItemReference(workItemId, process.env);
|
|
914
|
-
|
|
975
|
+
assertTaskDeliveryAuthority(store, process.env, reference.taskId);
|
|
915
976
|
const changeSets = await new WorkItemChangeSetManager(store).capture(reference.taskId, reference.localId, taskFinalReviewContract === undefined
|
|
916
977
|
? {}
|
|
917
978
|
: { taskFinalReviewContract });
|
|
@@ -932,7 +993,7 @@ export async function main() {
|
|
|
932
993
|
}
|
|
933
994
|
const reference = cliWorkItemReference(workItemId, process.env);
|
|
934
995
|
const qualified = `${reference.taskId}/${reference.localId}`;
|
|
935
|
-
|
|
996
|
+
assertTaskDeliveryAuthority(store, process.env, reference.taskId);
|
|
936
997
|
if (disposition === "--runtime-only") {
|
|
937
998
|
let runtimeCleanup;
|
|
938
999
|
try {
|
|
@@ -1024,7 +1085,7 @@ export async function main() {
|
|
|
1024
1085
|
.flatMap(({ owner }) => owner.type === "work-item" ? [owner.workItemId] : []);
|
|
1025
1086
|
for (const workItemId of workItemIds) {
|
|
1026
1087
|
const item = store.getWorkItem(task.id, workItemId);
|
|
1027
|
-
if (item?.status !== "
|
|
1088
|
+
if (item?.status !== "accepted" || disposition !== "integrated")
|
|
1028
1089
|
continue;
|
|
1029
1090
|
try {
|
|
1030
1091
|
await new WorkItemChangeSetManager(store).assertIntegrated(task.id, item.id);
|
|
@@ -1071,15 +1132,15 @@ export async function main() {
|
|
|
1071
1132
|
if (item !== null && task !== null) {
|
|
1072
1133
|
// Authority and pure Lane-shape checks precede every physical or
|
|
1073
1134
|
// durable workspace preparation performed for dispatch.
|
|
1074
|
-
|
|
1135
|
+
assertTaskDeliveryAuthority(store, process.env, task.id);
|
|
1075
1136
|
if (item.assignee !== undefined) {
|
|
1076
1137
|
workItemDispatchLanePlan(resolved, store, item);
|
|
1077
1138
|
}
|
|
1078
1139
|
}
|
|
1079
1140
|
// A rejected Candidate starts a new execution iteration. Release every
|
|
1080
1141
|
// terminal Lane Role runtime before preparing the new Lane workspaces;
|
|
1081
|
-
// durable
|
|
1082
|
-
if (item?.status === "
|
|
1142
|
+
// durable AgentRuns, Groups, Candidates, and workspace owners remain intact.
|
|
1143
|
+
if (item?.status === "open"
|
|
1083
1144
|
&& currentWorkItemExecutionGroup(item)?.lanes.every(({ disposition }) => disposition !== "open")) {
|
|
1084
1145
|
await workspaceCoordinator.cleanupWorkItemRuntime(item.taskId, item.id);
|
|
1085
1146
|
}
|
|
@@ -1118,7 +1179,7 @@ export async function main() {
|
|
|
1118
1179
|
try {
|
|
1119
1180
|
const reference = cliWorkItemReference(workItemId, process.env);
|
|
1120
1181
|
workItemIntegrationProof = await new WorkItemChangeSetManager(store)
|
|
1121
|
-
.assertIntegrated(reference.taskId, reference.localId) ?? undefined;
|
|
1182
|
+
.assertIntegrated(reference.taskId, reference.localId, optionValue(resolved, "--candidate")) ?? undefined;
|
|
1122
1183
|
}
|
|
1123
1184
|
catch (error) {
|
|
1124
1185
|
throw usageError(error instanceof Error ? error.message : String(error));
|
|
@@ -1204,6 +1265,11 @@ export async function main() {
|
|
|
1204
1265
|
? await actualTaskReviewCandidateForTaskCommand(resolved, store, workspacePreparer, process.env)
|
|
1205
1266
|
: archiveTaskReviewCandidate;
|
|
1206
1267
|
const deltaRecheckPreflight = await deltaRecheckPreflightForTaskCommand(resolved.slice(1), store, actualTaskReviewCandidate);
|
|
1268
|
+
// Read-only, and only for a Session inspect. The command itself stays
|
|
1269
|
+
// synchronous over persisted state; this is the live reading it prints
|
|
1270
|
+
// beside those facts, prepared here because the Host is reached over a
|
|
1271
|
+
// socket.
|
|
1272
|
+
const liveRunConfiguration = await liveRunConfigurationForTaskCommand(resolved, store, home);
|
|
1207
1273
|
// Physical preparation may precede the durable write, but Task status,
|
|
1208
1274
|
// workspace identity/cwd, and ManagedWorkspace ownership are adopted by
|
|
1209
1275
|
// one transaction. A failed attempt therefore leaves the Task Draft and
|
|
@@ -1213,7 +1279,8 @@ export async function main() {
|
|
|
1213
1279
|
const taskId = resolved[2];
|
|
1214
1280
|
const task = taskId === undefined ? null : store.getTask(taskId);
|
|
1215
1281
|
if (task !== null && task.status === "draft") {
|
|
1216
|
-
|
|
1282
|
+
taskLocalActor(store, process.env, task.id);
|
|
1283
|
+
taskWorkspaceActivation = await workspacePreparer.activateTaskWorkspace(task.id, process.env);
|
|
1217
1284
|
}
|
|
1218
1285
|
}
|
|
1219
1286
|
const result = runTaskCommand(resolved.slice(1), store, {
|
|
@@ -1242,6 +1309,9 @@ export async function main() {
|
|
|
1242
1309
|
...(deltaRecheckPreflight === undefined
|
|
1243
1310
|
? {}
|
|
1244
1311
|
: { deltaRecheckPreflight }),
|
|
1312
|
+
...(liveRunConfiguration === undefined
|
|
1313
|
+
? {}
|
|
1314
|
+
: { liveRunConfiguration }),
|
|
1245
1315
|
...(taskRetirementProof === undefined ? {} : { taskRetirementProof }),
|
|
1246
1316
|
...(validateAgentConfiguration === undefined
|
|
1247
1317
|
? {}
|
|
@@ -1263,13 +1333,13 @@ export async function main() {
|
|
|
1263
1333
|
let reviewData;
|
|
1264
1334
|
const resumesReviewDispatch = (resolved[1] === "review" && resolved[2] === "request")
|
|
1265
1335
|
|| (resolved[1] === "work" && resolved[2] === "review")
|
|
1266
|
-
|| (resolved[1] === "
|
|
1336
|
+
|| (resolved[1] === "run" && resolved[2] === "retry");
|
|
1267
1337
|
const reviewDispatchNeeded = requestedRound?.status === "pending"
|
|
1268
1338
|
|| (requestedRound?.status === "running"
|
|
1269
1339
|
&& resumesReviewDispatch
|
|
1270
1340
|
&& persistedRequestedRound?.executionGroup?.lanes.some((lane) => (lane.disposition === "open"
|
|
1271
|
-
&& (lane.
|
|
1272
|
-
|| store.
|
|
1341
|
+
&& (lane.currentRunId === undefined
|
|
1342
|
+
|| store.getRun(requestedRound.taskId, lane.currentRunId)?.status === "failed"))) === true);
|
|
1273
1343
|
if (reviewDispatchNeeded) {
|
|
1274
1344
|
try {
|
|
1275
1345
|
const workspace = requestedRound.status === "running"
|
|
@@ -1319,7 +1389,7 @@ export async function main() {
|
|
|
1319
1389
|
kind: "started",
|
|
1320
1390
|
reviewerRoleName: requestedRound.reviewerRoleName,
|
|
1321
1391
|
reviewRoundId: requestedRound.id,
|
|
1322
|
-
|
|
1392
|
+
runId: run.id
|
|
1323
1393
|
},
|
|
1324
1394
|
reviewRound: store.getReviewRound(requestedRound.taskId, requestedRound.id),
|
|
1325
1395
|
...(run === null ? {} : { reviewRun: run }),
|
|
@@ -1372,7 +1442,6 @@ export async function main() {
|
|
|
1372
1442
|
agentId: result.agentId,
|
|
1373
1443
|
adapterId: result.adapterId,
|
|
1374
1444
|
nativeSessionId: result.nativeSessionId,
|
|
1375
|
-
...(result.runtimeGenerationId === undefined ? {} : { runtimeGenerationId: result.runtimeGenerationId }),
|
|
1376
1445
|
sessionUpdatedAt: result.sessionUpdatedAt
|
|
1377
1446
|
});
|
|
1378
1447
|
}
|
|
@@ -1446,7 +1515,7 @@ export async function main() {
|
|
|
1446
1515
|
}
|
|
1447
1516
|
finally {
|
|
1448
1517
|
const currentTask = store.getTask(result.taskId);
|
|
1449
|
-
// Completing or retiring the Task from inside the takeover
|
|
1518
|
+
// Completing or retiring the Task from inside the takeover AgentRun owns
|
|
1450
1519
|
// Provider shutdown and clears the live binding. Do not turn that
|
|
1451
1520
|
// successful terminal transition into a failing best-effort release.
|
|
1452
1521
|
if (currentTask?.status === "active") {
|
|
@@ -1530,21 +1599,38 @@ async function preflightManagedTaskControlPlane() {
|
|
|
1530
1599
|
&& ["agent-host", "session-notify", "runtime-hook"].includes(args[1] ?? "");
|
|
1531
1600
|
const home = resolveYuiHome(process.env);
|
|
1532
1601
|
const manifest = assertManagedSessionManifest(home, "task");
|
|
1602
|
+
const diagnosticTarget = taskDiagnosticTarget(args);
|
|
1603
|
+
const diagnostic = diagnosticTarget !== undefined
|
|
1604
|
+
&& diagnosticTarget === process.env.YUI_TASK_ID;
|
|
1605
|
+
if (diagnosticTarget !== undefined && !diagnostic) {
|
|
1606
|
+
throw usageError("Diagnostics must remain within this Session's Task.");
|
|
1607
|
+
}
|
|
1533
1608
|
// One gate for every managed command: the current CLI, Home, and Controller
|
|
1534
1609
|
// must agree. Internal callbacks must still be able to append their immutable
|
|
1535
1610
|
// fact while the Controller is offline.
|
|
1536
|
-
await assertRuntimeCoherence({ actualHome: home }, { checkController: !internalCallback });
|
|
1611
|
+
await assertRuntimeCoherence({ actualHome: home }, { checkController: !internalCallback && !diagnostic });
|
|
1537
1612
|
const verifiedStore = openCurrentTaskStore(home);
|
|
1538
1613
|
// One authority for "may this process act as this Task Role?". Yui's own
|
|
1539
1614
|
// internal callbacks run inside the Host process Yui itself launched; an Agent
|
|
1540
1615
|
// command proves it is the Role's current runtime with its per-Session caller
|
|
1541
1616
|
// key. Nothing here
|
|
1542
|
-
// gates on the current
|
|
1617
|
+
// gates on the current AgentRun: which AgentRun is active is durable state that the
|
|
1543
1618
|
// command needing it reads, never a fact frozen into a process environment.
|
|
1544
1619
|
const runtime = internalCallback
|
|
1545
1620
|
? undefined
|
|
1546
|
-
:
|
|
1621
|
+
: diagnostic
|
|
1622
|
+
? resolveManagedTaskReader(verifiedStore, process.env)
|
|
1623
|
+
: requireManagedTaskCaller(verifiedStore, process.env);
|
|
1624
|
+
if (diagnostic && runtime?.roleName !== "leader"
|
|
1625
|
+
&& !(args[1] === "show"
|
|
1626
|
+
|| (args[1] === "role" && args[2] === "session" && args[3] === "inspect"
|
|
1627
|
+
&& args[5] === runtime?.roleName))) {
|
|
1628
|
+
// Non-Leaders keep their Assignment-scoped read authorization.
|
|
1629
|
+
requireManagedTaskCaller(verifiedStore, process.env);
|
|
1630
|
+
}
|
|
1547
1631
|
const request = taskFinalReviewInvocation.request;
|
|
1632
|
+
if (request !== undefined && diagnostic)
|
|
1633
|
+
requireManagedTaskCaller(verifiedStore, process.env);
|
|
1548
1634
|
if (request === undefined) {
|
|
1549
1635
|
return { contract: undefined, verifiedStore };
|
|
1550
1636
|
}
|
|
@@ -1579,7 +1665,14 @@ async function preflightManagedGlobalControlPlane() {
|
|
|
1579
1665
|
|| manifest.roleKind !== expectedRoleKind) {
|
|
1580
1666
|
throw new Error("Managed global invocation does not match its Session Manifest.");
|
|
1581
1667
|
}
|
|
1582
|
-
|
|
1668
|
+
if (expectedRoleKind === "operator" && ["doctor", "upgrade", "update"].includes(args[0] ?? "")) {
|
|
1669
|
+
// These commands inspect/adopt the storage contract themselves. Requiring
|
|
1670
|
+
// current storage before reaching upgrade would make recovery impossible.
|
|
1671
|
+
return { contract: undefined, verifiedStore: undefined };
|
|
1672
|
+
}
|
|
1673
|
+
await assertRuntimeCoherence({ actualHome: home }, {
|
|
1674
|
+
checkController: !(expectedRoleKind === "operator" && operatorOfflineCommand(args))
|
|
1675
|
+
});
|
|
1583
1676
|
return { contract: undefined, verifiedStore: openCurrentTaskStore(home) };
|
|
1584
1677
|
}
|
|
1585
1678
|
/**
|
|
@@ -1643,7 +1736,7 @@ function cliTaskRecordReference(value, kind, environment) {
|
|
|
1643
1736
|
try {
|
|
1644
1737
|
return resolveTaskRecordReference(value, {
|
|
1645
1738
|
kind,
|
|
1646
|
-
label: kind === "
|
|
1739
|
+
label: kind === "run" ? "AgentRun reference" : "ReviewRound reference",
|
|
1647
1740
|
...(environment.YUI_TASK_ID === undefined
|
|
1648
1741
|
? {}
|
|
1649
1742
|
: { contextTaskId: environment.YUI_TASK_ID })
|
|
@@ -1660,12 +1753,12 @@ function assertWorkItemExecutionDependenciesForCommand(args, store, environment)
|
|
|
1660
1753
|
const reference = cliWorkItemReference(args[3], environment);
|
|
1661
1754
|
item = store.getWorkItem(reference.taskId, reference.localId) ?? undefined;
|
|
1662
1755
|
}
|
|
1663
|
-
else if (args[0] === "task" && args[1] === "
|
|
1756
|
+
else if (args[0] === "task" && args[1] === "run" && args[2] === "retry"
|
|
1664
1757
|
&& args[3] !== undefined) {
|
|
1665
|
-
const reference = cliTaskRecordReference(args[3], "
|
|
1666
|
-
const
|
|
1667
|
-
item =
|
|
1668
|
-
? store.getWorkItem(
|
|
1758
|
+
const reference = cliTaskRecordReference(args[3], "run", environment);
|
|
1759
|
+
const run = store.getRun(reference.taskId, reference.localId);
|
|
1760
|
+
item = run?.purpose === "execution" && run.workItemId !== undefined
|
|
1761
|
+
? store.getWorkItem(run.taskId, run.workItemId) ?? undefined
|
|
1669
1762
|
: undefined;
|
|
1670
1763
|
}
|
|
1671
1764
|
if (item === undefined)
|
|
@@ -1720,7 +1813,7 @@ async function prepareExecutionLaneWorkspacesForCommand(args, store, preparer, e
|
|
|
1720
1813
|
if (store.getRole(item.taskId, roleName) === null) {
|
|
1721
1814
|
throw usageError(`Task Role not found: ${item.taskId}/${roleName}.`);
|
|
1722
1815
|
}
|
|
1723
|
-
if (store.
|
|
1816
|
+
if (store.getActiveRun(item.taskId, roleName) !== null) {
|
|
1724
1817
|
throw usageError(`${item.taskId}/${roleName} already has an active turn.`);
|
|
1725
1818
|
}
|
|
1726
1819
|
}
|
|
@@ -1759,7 +1852,7 @@ function workItemDispatchLanePlan(args, store, item) {
|
|
|
1759
1852
|
const roles = args.flatMap((value, index) => (value === "--lane-role" && args[index + 1] !== undefined
|
|
1760
1853
|
? [args[index + 1]]
|
|
1761
1854
|
: []));
|
|
1762
|
-
const groupId = `execution-group-${store.
|
|
1855
|
+
const groupId = `execution-group-${store.peekNextRunId(item.taskId)}`;
|
|
1763
1856
|
return {
|
|
1764
1857
|
groupId,
|
|
1765
1858
|
...planReplicatedWorkItemLanes(item.assignee, roles, groupId)
|
|
@@ -1855,11 +1948,11 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
|
|
|
1855
1948
|
taskId = reference.taskId;
|
|
1856
1949
|
}
|
|
1857
1950
|
}
|
|
1858
|
-
else if (args[1] === "
|
|
1951
|
+
else if (args[1] === "run"
|
|
1859
1952
|
&& (args[2] === "retry" || args[2] === "settle")
|
|
1860
1953
|
&& args[3] !== undefined) {
|
|
1861
|
-
const reference = cliTaskRecordReference(args[3], "
|
|
1862
|
-
const run = store.
|
|
1954
|
+
const reference = cliTaskRecordReference(args[3], "run", environment);
|
|
1955
|
+
const run = store.getRun(reference.taskId, reference.localId);
|
|
1863
1956
|
const round = run?.reviewRoundId === undefined
|
|
1864
1957
|
? null
|
|
1865
1958
|
: store.getReviewRound(reference.taskId, run.reviewRoundId);
|
|
@@ -1875,7 +1968,6 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
|
|
|
1875
1968
|
taskId = store.getTask(args[2])?.id;
|
|
1876
1969
|
}
|
|
1877
1970
|
else if ((args[1] === "show"
|
|
1878
|
-
|| args[1] === "context"
|
|
1879
1971
|
|| args[1] === "next-action"
|
|
1880
1972
|
|| args[1] === "remote-delivery")
|
|
1881
1973
|
&& args[2] !== undefined) {
|
|
@@ -1883,10 +1975,10 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
|
|
|
1883
1975
|
decisionSupportRead = true;
|
|
1884
1976
|
}
|
|
1885
1977
|
const status = taskId === undefined ? undefined : store.getTask(taskId)?.status;
|
|
1886
|
-
if (taskId === undefined || (status !== "active" && status !== "
|
|
1978
|
+
if (taskId === undefined || (status !== "active" && status !== "cancelled"))
|
|
1887
1979
|
return undefined;
|
|
1888
1980
|
try {
|
|
1889
|
-
return await snapshotActualTaskReviewCandidate(taskId, store, preparer);
|
|
1981
|
+
return await snapshotActualTaskReviewCandidate(taskId, store, preparer, !decisionSupportRead);
|
|
1890
1982
|
}
|
|
1891
1983
|
catch (error) {
|
|
1892
1984
|
if (decisionSupportRead && error instanceof CliError)
|
|
@@ -1894,16 +1986,18 @@ async function actualTaskReviewCandidateForTaskCommand(args, store, preparer, en
|
|
|
1894
1986
|
throw error;
|
|
1895
1987
|
}
|
|
1896
1988
|
}
|
|
1897
|
-
async function snapshotActualTaskReviewCandidate(taskId, store, preparer) {
|
|
1989
|
+
async function snapshotActualTaskReviewCandidate(taskId, store, preparer, prepareWorkspace = true) {
|
|
1898
1990
|
const task = store.getTask(taskId);
|
|
1899
1991
|
if (task === null)
|
|
1900
1992
|
throw usageError(`Task not found: ${taskId}.`);
|
|
1901
1993
|
if (task.projectBindings.length === 0) {
|
|
1902
1994
|
throw usageError(`Final Task Review requires a Project-backed Task: ${task.id}.`);
|
|
1903
1995
|
}
|
|
1904
|
-
//
|
|
1905
|
-
//
|
|
1906
|
-
|
|
1996
|
+
// Mutation preflights reconcile before freezing a candidate. A decision-
|
|
1997
|
+
// support read only observes existing heads; it must not migrate Sessions,
|
|
1998
|
+
// create worktrees or acquire workspace ownership as a side effect.
|
|
1999
|
+
if (prepareWorkspace)
|
|
2000
|
+
await preparer.prepareTaskWorkspace(task.id);
|
|
1907
2001
|
const workspace = store.getTaskWorkspace(task.id);
|
|
1908
2002
|
if (workspace === null
|
|
1909
2003
|
|| workspace.owner.type !== "task"
|
|
@@ -2075,13 +2169,6 @@ async function executeOperatorSessionControl(control, home, store, runtime, tmux
|
|
|
2075
2169
|
await runtime.prepareGlobalRoleEnter(role.name);
|
|
2076
2170
|
tmux.attachRole("operator", role.name, "auto");
|
|
2077
2171
|
}
|
|
2078
|
-
function adapterLabel(adapterId) {
|
|
2079
|
-
return adapterId === "codex"
|
|
2080
|
-
? "Codex"
|
|
2081
|
-
: adapterId === "claude"
|
|
2082
|
-
? "Claude"
|
|
2083
|
-
: adapterId;
|
|
2084
|
-
}
|
|
2085
2172
|
function renderControllerResult(method, value) {
|
|
2086
2173
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2087
2174
|
return JSON.stringify(value);
|
|
@@ -2264,6 +2351,65 @@ async function warmLegacyRoleConfigurationMutation(commandArgs, store, catalogs)
|
|
|
2264
2351
|
cwd: store.getConfig().defaultWorkspace ?? process.cwd()
|
|
2265
2352
|
});
|
|
2266
2353
|
}
|
|
2354
|
+
/**
|
|
2355
|
+
* Ask the live Agent Host what the Session is running under, for a Session
|
|
2356
|
+
* inspect.
|
|
2357
|
+
*
|
|
2358
|
+
* Only for `task role session inspect`. Every other command reads persisted
|
|
2359
|
+
* state and must keep doing so: a query that reached into a running Session
|
|
2360
|
+
* would make reading a Task's records depend on whether an Agent happened to be
|
|
2361
|
+
* up.
|
|
2362
|
+
*
|
|
2363
|
+
* The request is the Host's existing `status` control, which reads state the
|
|
2364
|
+
* Host already holds. It creates no Session, sends no prompt and changes nothing
|
|
2365
|
+
* — which is what lets a read-only inspect use it at all.
|
|
2366
|
+
*
|
|
2367
|
+
* Every failure resolves to `unknown` with the reason rather than propagating:
|
|
2368
|
+
* no Host is running for most Sessions ever inspected, and the persisted facts
|
|
2369
|
+
* the command prints are worth showing regardless of whether a live one answered.
|
|
2370
|
+
*/
|
|
2371
|
+
async function liveRunConfigurationForTaskCommand(args, store, home) {
|
|
2372
|
+
if (args[0] !== "task" || args[1] !== "role" || args[2] !== "session"
|
|
2373
|
+
|| args[3] !== "inspect" || args.length !== 6) {
|
|
2374
|
+
return undefined;
|
|
2375
|
+
}
|
|
2376
|
+
const taskId = args[4];
|
|
2377
|
+
const roleName = args[5];
|
|
2378
|
+
if (taskId === undefined || roleName === undefined)
|
|
2379
|
+
return undefined;
|
|
2380
|
+
// A Session must be recorded as active before asking. Probing a socket for a
|
|
2381
|
+
// Role that never ran would report a reach failure as if it were a fact about
|
|
2382
|
+
// that Role's Agent.
|
|
2383
|
+
const sessions = store.getTaskRoleSessionSet(taskId, roleName);
|
|
2384
|
+
const active = sessions === null
|
|
2385
|
+
? undefined
|
|
2386
|
+
: sessions.sessions[sessions.activeAgentId];
|
|
2387
|
+
if (active === undefined)
|
|
2388
|
+
return undefined;
|
|
2389
|
+
if (active.status !== "active") {
|
|
2390
|
+
return unknownAgentRunConfiguration(`This Session is ${active.status}, so there is no live Agent to report what it `
|
|
2391
|
+
+ "is running under.");
|
|
2392
|
+
}
|
|
2393
|
+
try {
|
|
2394
|
+
const snapshot = await inspectAgentHost({
|
|
2395
|
+
home,
|
|
2396
|
+
scope: "task",
|
|
2397
|
+
taskId,
|
|
2398
|
+
roleName
|
|
2399
|
+
});
|
|
2400
|
+
if (snapshot.nativeSessionId !== active.nativeSessionId
|
|
2401
|
+
|| snapshot.adapterId !== active.adapterId
|
|
2402
|
+
|| snapshot.state === "exited" || snapshot.state === "failed") {
|
|
2403
|
+
return unknownAgentRunConfiguration("The Agent Host has no live connection matching the recorded Session.");
|
|
2404
|
+
}
|
|
2405
|
+
return snapshot.runConfiguration ?? unknownAgentRunConfiguration("The Agent Host is running but has no Provider Session open, so no Agent "
|
|
2406
|
+
+ "has reported a configuration yet.");
|
|
2407
|
+
}
|
|
2408
|
+
catch (error) {
|
|
2409
|
+
return unknownAgentRunConfiguration("The Agent Host for this Session could not be reached, so its live "
|
|
2410
|
+
+ `configuration is unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2267
2413
|
function hasModelOrEffortMutation(args) {
|
|
2268
2414
|
const operation = (args[0] === "config" && args[1] === "role")
|
|
2269
2415
|
|| (args[0] === "task" && args[1] === "role");
|
|
@@ -2336,7 +2482,7 @@ function selectionCall(store, catalogs, method, params) {
|
|
|
2336
2482
|
: store.listInputRequests(taskId);
|
|
2337
2483
|
return params.all === true ? requests : requests.filter((request) => request.status === "open");
|
|
2338
2484
|
}
|
|
2339
|
-
case "task.turn.list": return callOptional(reader, "
|
|
2485
|
+
case "task.turn.list": return callOptional(reader, "listRuns", [params.taskId]);
|
|
2340
2486
|
case "task.decision.list": return callOptional(reader, "listDecisions", [params.taskId]);
|
|
2341
2487
|
case "task.milestone.list": return presentSelectionTimes(callOptional(reader, "listMilestones", [params.taskId]), store);
|
|
2342
2488
|
case "task.event.list": return presentSelectionTimes(callOptional(reader, "listEvents", [params.taskId]), store);
|
|
@@ -2434,6 +2580,10 @@ export function cliIdentity(env) {
|
|
|
2434
2580
|
}
|
|
2435
2581
|
function normalizeAliases(input) {
|
|
2436
2582
|
const normalized = [...input];
|
|
2583
|
+
// Existing immutable Session Manifests (through 0.15.8) name this entry.
|
|
2584
|
+
// Remove once those Sessions are retired; both names share one handler.
|
|
2585
|
+
if (normalized[0] === "task" && normalized[1] === "turn")
|
|
2586
|
+
normalized[1] = "run";
|
|
2437
2587
|
if (normalized.length === 1 && (normalized[0] === "-v" || normalized[0] === "--version")) {
|
|
2438
2588
|
return ["version"];
|
|
2439
2589
|
}
|