@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
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
export const TASK_SURFACE_SCRIPT = `
|
|
2
|
+
import { node, clear } from "/assets/js/dom.js";
|
|
3
|
+
import { anchorSection, sectionHead, richText, inputCard, roleCard, runCard, pill } from "/assets/js/components.js";
|
|
4
|
+
|
|
5
|
+
// All business facts below retain their Context reference. Expanded values
|
|
6
|
+
// are current reads, not mutations of a historical Context snapshot.
|
|
7
|
+
export function renderTaskSurface(container, data, t, locale, actions) {
|
|
8
|
+
clear(container);
|
|
9
|
+
const core = data.core;
|
|
10
|
+
const task = data.task;
|
|
11
|
+
container.dataset.taskId = task.id;
|
|
12
|
+
const zh = locale.startsWith("zh");
|
|
13
|
+
const say = (en, cn) => zh ? cn : en;
|
|
14
|
+
const records = (store) => core.records.filter((entry) => entry.ref.store === store);
|
|
15
|
+
const values = (store) => records(store).filter((entry) => !entry.omitted).map((entry) => entry.value);
|
|
16
|
+
const scaffold = node("div", "detail-scaffold task-surface");
|
|
17
|
+
const summary = node("div", "section-body");
|
|
18
|
+
summary.append(node("span", "detail-kicker", task.id), node("h2", "detail-title", task.title), pill(t, "status", task.status));
|
|
19
|
+
const conversation = node("button", "record-open", say("View Leader Session (read-only)", "查看 Leader Session(只读)"));
|
|
20
|
+
conversation.type = "button";
|
|
21
|
+
// A Draft's planning Session is a real Leader Session, so it is viewable once it
|
|
22
|
+
// actually exists. The button is disabled only when there is no Session to show
|
|
23
|
+
// — not because the Task has yet to be activated. The Session lives in the
|
|
24
|
+
// runtime observation, which arrives separately from the Context snapshot.
|
|
25
|
+
const leaderRole = (data.runtime?.roles ?? []).find((role) => role.name === "leader") ?? null;
|
|
26
|
+
const hasLeaderSession = Boolean(leaderRole?.runtimeSession?.nativeSessionId);
|
|
27
|
+
conversation.disabled = task.status === "archived" || !hasLeaderSession;
|
|
28
|
+
conversation.addEventListener("click", () => actions.openTerminal({ scope: "task", taskId: task.id, roleName: "leader" }));
|
|
29
|
+
summary.append(conversation);
|
|
30
|
+
const chat = node("form", "record-card");
|
|
31
|
+
const chatLabel = node("label", "", say("Message to Task Leader", "发送给 Task Leader"));
|
|
32
|
+
const message = node("textarea", "");
|
|
33
|
+
message.required = true;
|
|
34
|
+
message.maxLength = 8000;
|
|
35
|
+
chatLabel.append(message);
|
|
36
|
+
// Submission intent is an explicit user choice, never inferred from the body
|
|
37
|
+
// (task-32 §2.5); discuss is the default so the control matches the service.
|
|
38
|
+
const intentLabel = node("label", "", say("Intent", "提交意图"));
|
|
39
|
+
const intentSelect = node("select", "");
|
|
40
|
+
const intentOptions = [
|
|
41
|
+
["discuss", say("Discuss — route to planning", "讨论 — 进入规划")],
|
|
42
|
+
["record", say("Record — save only", "记录 — 仅保存")],
|
|
43
|
+
["develop", say("Develop — request activation", "开发 — 请求激活")]
|
|
44
|
+
];
|
|
45
|
+
for (const [value, text] of intentOptions) {
|
|
46
|
+
const option = node("option", "", text);
|
|
47
|
+
option.value = value;
|
|
48
|
+
intentSelect.append(option);
|
|
49
|
+
}
|
|
50
|
+
intentSelect.value = "discuss";
|
|
51
|
+
intentLabel.append(intentSelect);
|
|
52
|
+
chat.addEventListener("input", () => { chat.dataset.unsent = message.value ? "true" : "false"; });
|
|
53
|
+
const send = node("button", "record-open", say("Send", "发送"));
|
|
54
|
+
send.type = "submit";
|
|
55
|
+
send.disabled = !["active", "draft"].includes(task.status);
|
|
56
|
+
const sent = node("p", "muted", say("Not submitted", "未提交"));
|
|
57
|
+
sent.setAttribute("role", "status");
|
|
58
|
+
// §2.5 facets render here, one per line; cleared and repopulated on every submit.
|
|
59
|
+
const facets = node("div", "section-body");
|
|
60
|
+
facets.dataset.submissionFacets = "";
|
|
61
|
+
chat.append(chatLabel, intentLabel, send, sent, facets);
|
|
62
|
+
chat.addEventListener("submit", async (event) => {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
if (send.disabled) return;
|
|
65
|
+
send.disabled = true;
|
|
66
|
+
chat.dataset.unsent = "true";
|
|
67
|
+
const requestId = crypto.randomUUID();
|
|
68
|
+
const intent = intentSelect.value;
|
|
69
|
+
clear(facets);
|
|
70
|
+
sent.textContent = say("Waiting for receipt · ", "等待回执 · ") + requestId;
|
|
71
|
+
try {
|
|
72
|
+
// requestId is the submission key: the same key retried returns the original
|
|
73
|
+
// Message and routing rather than a second submission (task-32 §2.3).
|
|
74
|
+
const receipt = await actions.sendMessage(task.id, message.value, requestId, intent);
|
|
75
|
+
sent.textContent = say("Saved · ", "已保存 · ") + receipt.record.id;
|
|
76
|
+
renderSubmissionFacets(facets, receipt.submission, say);
|
|
77
|
+
message.value = "";
|
|
78
|
+
chat.dataset.unsent = "false";
|
|
79
|
+
send.disabled = false;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error.disposition === "not-submitted") {
|
|
82
|
+
sent.textContent = say("Not submitted: ", "未提交:") + error.message;
|
|
83
|
+
send.disabled = false;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// A lost response must never auto-replay a write; the same requestId is safe
|
|
87
|
+
// to resend by hand because the server dedups on it (§2.3), but the user
|
|
88
|
+
// reloads and inspects first rather than blindly resending.
|
|
89
|
+
sent.textContent = say("Unknown submission outcome. Reload and inspect saved messages before sending again · ",
|
|
90
|
+
"提交结果未知。请重新加载并检查已保存消息,不要盲目重发 · ") + requestId;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
summary.append(chat);
|
|
94
|
+
// A Draft's Leader conversation IS its planning Turn, so this entry point does
|
|
95
|
+
// reach a Leader. Report the real planning facts the snapshot carries — Turn,
|
|
96
|
+
// Session, environment and the time they were observed — instead of asserting
|
|
97
|
+
// that no runtime exists. When nothing has been dispatched yet, say exactly
|
|
98
|
+
// that rather than implying the entry point is inert.
|
|
99
|
+
if (task.status === "draft") {
|
|
100
|
+
// Planning facts come from the Context snapshot, which is the authoritative
|
|
101
|
+
// durable read and the one that drives re-rendering. The runtime observation
|
|
102
|
+
// is explicitly optional (it may time out and only ever enriches a live
|
|
103
|
+
// Session), so it must not decide whether a planning Turn is reported.
|
|
104
|
+
const turnEntries = records("turn");
|
|
105
|
+
const planningTurns = values("turn").filter((turn) =>
|
|
106
|
+
turn.roleName === "leader" && turn.purpose === "planning");
|
|
107
|
+
// The latest planning Turn, whatever state it reached. A completed planning
|
|
108
|
+
// Turn is still the real observed fact; reporting only active ones would call
|
|
109
|
+
// a Draft that has genuinely talked to its Leader "not dispatched".
|
|
110
|
+
const planningTurn = planningTurns[planningTurns.length - 1] ?? null;
|
|
111
|
+
// A bounded snapshot may withhold Turn values. That is not evidence that no
|
|
112
|
+
// Turn exists, so it is reported as withheld rather than as "not dispatched".
|
|
113
|
+
const withheldTurns = planningTurn === null && turnEntries.some((entry) => entry.omitted);
|
|
114
|
+
const environment = planningTurn?.effective?.executionEnvironment ?? null;
|
|
115
|
+
const liveLeader = (data.runtime?.roles ?? []).find((role) => role.name === "leader") ?? null;
|
|
116
|
+
const planning = node("div", "record-card");
|
|
117
|
+
planning.dataset.planning = planningTurn !== null
|
|
118
|
+
? planningTurn.status
|
|
119
|
+
: withheldTurns ? "withheld" : "not-dispatched";
|
|
120
|
+
planning.append(node("p", "muted", withheldTurns
|
|
121
|
+
? say("This bounded snapshot withholds Turn detail; read the Turn directly to see planning state.",
|
|
122
|
+
"当前受限快照未展开 Turn 详情;请直接读取 Turn 查看规划状态。")
|
|
123
|
+
: planningTurn === null
|
|
124
|
+
? say("No planning Turn has been dispatched yet. Sending a message queues the Leader.",
|
|
125
|
+
"尚未派发 planning Turn;发送消息会为 Leader 排队。")
|
|
126
|
+
: planningTurn.status === "active"
|
|
127
|
+
? say("Planning Turn is active; messages reach the Task Leader.",
|
|
128
|
+
"planning Turn 正在进行;消息会送达 Task Leader。")
|
|
129
|
+
: say("Planning Turn reached " + planningTurn.status
|
|
130
|
+
+ "; messages reach the same Task Leader and queue the next Turn.",
|
|
131
|
+
"planning Turn 已" + planningTurn.status + ";消息仍送达同一 Task Leader 并为下一个 Turn 排队。")));
|
|
132
|
+
const facts = [
|
|
133
|
+
[say("Planning Turn", "planning Turn"), planningTurn
|
|
134
|
+
? planningTurn.id + " (" + planningTurn.status + ")"
|
|
135
|
+
: withheldTurns ? say("withheld by this snapshot", "本快照未展开") : say("none", "无")],
|
|
136
|
+
[say("Provider terminal", "Provider 终态"),
|
|
137
|
+
planningTurn?.result?.provider?.status ?? say("not reported", "未上报")],
|
|
138
|
+
// The Provider conversation is the durable transport identity of the
|
|
139
|
+
// Session this Turn actually ran on; the live Session, when observed,
|
|
140
|
+
// is reported separately so a stale read is never dressed up as current.
|
|
141
|
+
[say("Provider conversation", "Provider 会话"),
|
|
142
|
+
planningTurn?.result?.provider?.conversationId ?? say("not reported", "未上报")],
|
|
143
|
+
[say("Live Leader Session", "在线 Leader Session"),
|
|
144
|
+
liveLeader?.runtimeSession?.nativeSessionId
|
|
145
|
+
?? say("not currently running", "当前未在运行")],
|
|
146
|
+
[say("Environment", "环境"), environment?.environmentRef
|
|
147
|
+
?? say("empty (legal for planning)", "空环境(规划阶段合法)")],
|
|
148
|
+
[say("Turn observed at", "Turn 观测时间"),
|
|
149
|
+
planningTurn?.result?.completedAt ?? planningTurn?.updatedAt ?? say("unknown", "未知")]
|
|
150
|
+
];
|
|
151
|
+
for (const [label, value] of facts) {
|
|
152
|
+
planning.append(node("p", "muted", label + ": " + value));
|
|
153
|
+
}
|
|
154
|
+
summary.append(planning);
|
|
155
|
+
}
|
|
156
|
+
if (task.description) summary.append(richText(say("Current requirements", "当前要求"), task.description, t));
|
|
157
|
+
if (task.completionSummary) summary.append(richText(t("detail.conclusion"), task.completionSummary, t));
|
|
158
|
+
const edit = node("details", "record-card");
|
|
159
|
+
edit.append(node("summary", "", say("Edit Task title", "修改任务标题")));
|
|
160
|
+
const form = node("form", "record-block");
|
|
161
|
+
const label = node("label", "", say("Title", "标题"));
|
|
162
|
+
const title = node("input", "");
|
|
163
|
+
title.value = task.title;
|
|
164
|
+
title.required = true;
|
|
165
|
+
title.disabled = task.status === "archived";
|
|
166
|
+
title.maxLength = 500;
|
|
167
|
+
label.append(title);
|
|
168
|
+
form.addEventListener("input", () => { form.dataset.unsent = "true"; });
|
|
169
|
+
const save = node("button", "record-open", say("Save", "保存"));
|
|
170
|
+
save.type = "submit";
|
|
171
|
+
save.disabled = task.status === "archived";
|
|
172
|
+
const feedback = node("p", "muted", say("Not submitted", "未提交"));
|
|
173
|
+
feedback.setAttribute("role", "status");
|
|
174
|
+
form.append(label, save, feedback);
|
|
175
|
+
form.addEventListener("submit", async (event) => {
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
if (save.disabled) return;
|
|
178
|
+
save.disabled = true;
|
|
179
|
+
form.dataset.unsent = "true";
|
|
180
|
+
const requestId = crypto.randomUUID();
|
|
181
|
+
feedback.textContent = say("Waiting for save receipt · ", "正在等待保存回执 · ") + requestId;
|
|
182
|
+
try {
|
|
183
|
+
const receipt = await actions.updateTask(task.id, { title: title.value }, requestId);
|
|
184
|
+
feedback.textContent = say("Saved · revision ", "已保存 · revision ") + receipt.revision;
|
|
185
|
+
title.value = receipt.record.title;
|
|
186
|
+
form.dataset.unsent = "false";
|
|
187
|
+
save.disabled = false;
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (error.disposition === "not-submitted") {
|
|
190
|
+
feedback.textContent = say("Not saved: ", "未保存:") + error.message;
|
|
191
|
+
save.disabled = false;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Local mutation IDs correlate requests; they are not a deduplication
|
|
195
|
+
// ledger. A lost response must never automatically replay a write.
|
|
196
|
+
feedback.textContent = say("Unknown save outcome. Reload this page to read current facts before submitting again. Request: ",
|
|
197
|
+
"保存结果未知。请重新加载页面读取当前事实,再决定是否提交。请求:") + requestId;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
edit.append(form);
|
|
201
|
+
summary.append(edit);
|
|
202
|
+
scaffold.append(anchorSection("detail-top", sectionHead(t("tabs.summary")), summary));
|
|
203
|
+
|
|
204
|
+
function recordCard(entry) {
|
|
205
|
+
const card = node("article", "record-card");
|
|
206
|
+
card.append(node("strong", "", entry.ref.store + " · " + entry.ref.refId));
|
|
207
|
+
const ref = node("small", "muted", say("Revision: ", "版本:") + entry.ref.revision);
|
|
208
|
+
card.append(ref);
|
|
209
|
+
if (!entry.omitted) {
|
|
210
|
+
const value = entry.value;
|
|
211
|
+
const text = value.content || value.summary || value.body || value.objective || value.title || value.leaderSummary;
|
|
212
|
+
if (text) card.append(richText(null, text, t));
|
|
213
|
+
if (value.status) card.append(node("p", "muted", value.status));
|
|
214
|
+
if (value.roleName) card.append(node("p", "muted", value.roleName));
|
|
215
|
+
if (entry.ref.store === "work-item") {
|
|
216
|
+
card.append(node("p", "muted", say("Owner: ", "负责人:") + (value.assignee || "Leader")));
|
|
217
|
+
if (value.acceptance) card.append(richText(say("Acceptance criteria", "验收标准"), value.acceptance.join("\\n"), t));
|
|
218
|
+
}
|
|
219
|
+
if (entry.ref.store === "job") {
|
|
220
|
+
const status = value.status;
|
|
221
|
+
const label = status === "queued" ? say("Queued", "已排队")
|
|
222
|
+
: status === "running" ? say("Waiting for a terminal receipt", "等待明确终态")
|
|
223
|
+
: status === "unknown-needs-attention" ? say("Unknown effect — inspect the original operation; do not resend", "效果未知——检查原操作,不要重发")
|
|
224
|
+
: say("Terminal record", "已记录终态");
|
|
225
|
+
card.append(node("p", "", label + " · " + task.id + "/" + value.id));
|
|
226
|
+
}
|
|
227
|
+
} else card.append(node("p", "muted", entry.summary || say("Value omitted from compact read", "紧凑读取已省略正文")));
|
|
228
|
+
const expand = node("button", "record-open", say("Read full record / source", "读取完整记录/来源"));
|
|
229
|
+
expand.type = "button";
|
|
230
|
+
expand.addEventListener("click", async () => {
|
|
231
|
+
expand.disabled = true;
|
|
232
|
+
try {
|
|
233
|
+
const result = await actions.inspect(task.id, entry.ref);
|
|
234
|
+
const content = node("pre", "surface-json", JSON.stringify(result.value, null, 2));
|
|
235
|
+
card.append(content);
|
|
236
|
+
if (result.result?.output) card.append(richText(say("Original execution report", "原始执行报告"), result.result.output, t));
|
|
237
|
+
if (result.result?.diagnostic) card.append(richText(say("Execution diagnostic", "执行诊断"), result.result.diagnostic, t));
|
|
238
|
+
if (result.execution) card.append(node("pre", "surface-json", JSON.stringify(result.execution, null, 2)));
|
|
239
|
+
expand.remove();
|
|
240
|
+
} catch {
|
|
241
|
+
expand.disabled = false;
|
|
242
|
+
expand.textContent = say("Record changed or unavailable; refresh context", "记录已变化或不可用;请刷新 Context");
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
card.append(expand);
|
|
246
|
+
return card;
|
|
247
|
+
}
|
|
248
|
+
function section(id, name, entries) {
|
|
249
|
+
const body = node("div", "section-body");
|
|
250
|
+
entries.forEach((entry) => body.append(recordCard(entry)));
|
|
251
|
+
if (!entries.length) body.append(node("p", "muted", core.omitted.records
|
|
252
|
+
? say("Not included in this compact read", "此紧凑读取未包含该记录")
|
|
253
|
+
: say("No records", "暂无记录")));
|
|
254
|
+
scaffold.append(anchorSection(id, sectionHead(name, { count: entries.length }), body));
|
|
255
|
+
return body;
|
|
256
|
+
}
|
|
257
|
+
const focus = section("detail-focus", say("Goal and current focus", "目标与当前关注"), records("task-brief"));
|
|
258
|
+
const brief = values("task-brief")[0];
|
|
259
|
+
if (brief) {
|
|
260
|
+
focus.prepend(richText(t("detail.focus"), brief.currentFocus, t));
|
|
261
|
+
if (brief.boundaries.length) focus.append(richText(say("Boundaries", "边界"), brief.boundaries.join("\\n"), t));
|
|
262
|
+
}
|
|
263
|
+
const questions = node("div", "section-body");
|
|
264
|
+
records("input-request").filter((entry) => entry.omitted || entry.value.status === "open").forEach((entry) => {
|
|
265
|
+
questions.append(entry.omitted ? recordCard(entry) : inputCard(entry.value, { single: true }, t, locale, actions));
|
|
266
|
+
});
|
|
267
|
+
scaffold.append(anchorSection("detail-attention", sectionHead(t("detail.attention")), questions));
|
|
268
|
+
section("detail-work", say("Responsibilities and acceptance", "工作责任与验收"), records("work-item"));
|
|
269
|
+
section("detail-results", say("Saved results and provenance", "已保存结果与来源"), records("artifact").concat(records("candidate")));
|
|
270
|
+
section("detail-messages", t("detail.messages"), records("task-message"));
|
|
271
|
+
section("detail-history", say("Decisions and milestones", "决策与里程碑"), records("task-decision").concat(records("task-milestone")));
|
|
272
|
+
section("detail-reviews", t("detail.reviews"), records("review-round"));
|
|
273
|
+
const roles = node("div", "section-body");
|
|
274
|
+
records("role").forEach((entry) => {
|
|
275
|
+
if (entry.omitted) { roles.append(recordCard(entry)); return; }
|
|
276
|
+
const role = entry.value;
|
|
277
|
+
const active = values("run").find((run) => run.roleName === role.name && run.status === "active");
|
|
278
|
+
const incomplete = core.omitted.records > 0 || records("run").some((entry) => entry.omitted);
|
|
279
|
+
roles.append(roleCard({
|
|
280
|
+
...role, status: active || incomplete ? "unknown" : "idle",
|
|
281
|
+
effectiveLaunch: active ? active.effective : null,
|
|
282
|
+
launchDrift: active && active.effective.sourceDesiredRevision !== role.launchRevision
|
|
283
|
+
}, task, t, locale, actions));
|
|
284
|
+
if (!active) roles.append(node("p", "muted", say(
|
|
285
|
+
"No active AgentRun in this read; Session activity is a separate observation.",
|
|
286
|
+
"此读取中没有活跃 AgentRun;Session 活动属于独立观察。")));
|
|
287
|
+
});
|
|
288
|
+
scaffold.append(anchorSection("detail-roles", sectionHead(t("detail.roles")), roles));
|
|
289
|
+
const execution = node("details", "record-card");
|
|
290
|
+
execution.append(node("summary", "", say("Execution and observations", "展开执行与观察")));
|
|
291
|
+
execution.append(node("p", "muted", say(
|
|
292
|
+
"An open execution record is not proof of Agent activity. Native admission and Task progress are separate facts.",
|
|
293
|
+
"执行记录未结清不等于 Agent 正在工作;原生准入、运行观察与 Task 进展分别呈现。")));
|
|
294
|
+
records("run").forEach((entry) => execution.append(entry.omitted ? recordCard(entry)
|
|
295
|
+
: runCard({ ...entry.value, execution: entry.execution }, t, locale)));
|
|
296
|
+
(core.observations || []).forEach((observation) => execution.append(node("p", "muted",
|
|
297
|
+
observation.source + " · " + observation.status + " · " + observation.coverage + " · " + observation.observedAt)));
|
|
298
|
+
const runtimeStatus = node("p", "muted", data.runtimeStatus + " · " + data.runtimeObservedAt);
|
|
299
|
+
runtimeStatus.dataset.runtimeStatus = "";
|
|
300
|
+
execution.append(runtimeStatus);
|
|
301
|
+
const raw = node("pre", "surface-json", data.runtime ? JSON.stringify({
|
|
302
|
+
roles: data.runtime.roles, runtimeHealth: data.runtime.runtimeHealth
|
|
303
|
+
}, null, 2) : "");
|
|
304
|
+
raw.dataset.runtimeValue = "";
|
|
305
|
+
execution.append(raw);
|
|
306
|
+
scaffold.append(anchorSection("detail-exec", sectionHead(t("detail.execution")), execution));
|
|
307
|
+
section("detail-operations", say("Original operation facts (no automatic retry)", "原始操作事实(不自动重试)"), records("job"));
|
|
308
|
+
const refs = node("details", "record-card");
|
|
309
|
+
refs.append(node("summary", "", say("Context cursor and omitted references", "Context 游标与省略引用")));
|
|
310
|
+
refs.append(node("pre", "surface-json", JSON.stringify({
|
|
311
|
+
coreCursor: core.coreCursor, throughCursor: core.throughCursor, count: core.count, omitted: core.omitted
|
|
312
|
+
}, null, 2)));
|
|
313
|
+
refs.append(node("p", "muted", say("Reads do not acknowledge messages. Omitted records can be located with the CLI domain query and inspected by reference.",
|
|
314
|
+
"读取不确认消息。被省略的记录可经 CLI 领域查询定位后按引用读取。")));
|
|
315
|
+
scaffold.append(refs);
|
|
316
|
+
const panels = node("details", "record-card");
|
|
317
|
+
panels.append(node("summary", "", say("Capability panels", "能力面板")));
|
|
318
|
+
const panelBody = node("div", "section-body");
|
|
319
|
+
panels.append(panelBody);
|
|
320
|
+
let loadingPanels = false;
|
|
321
|
+
panels.addEventListener("toggle", async () => {
|
|
322
|
+
if (!panels.open || loadingPanels) return;
|
|
323
|
+
loadingPanels = true;
|
|
324
|
+
panelBody.textContent = say("Reading current contributions…", "读取当前贡献…");
|
|
325
|
+
try {
|
|
326
|
+
const current = await actions.panels(task.id);
|
|
327
|
+
clear(panelBody);
|
|
328
|
+
panelBody.append(node("small", "muted", current.observedAt));
|
|
329
|
+
if (!current.panels.length) panelBody.append(node("p", "muted", say("No visible panels", "暂无可见面板")));
|
|
330
|
+
current.panels.forEach((item) => {
|
|
331
|
+
const card = node("article", "record-card");
|
|
332
|
+
const panel = item.panel;
|
|
333
|
+
card.append(node("strong", "", panel.title), node("small", "muted", item.capability + " · " + item.provider.id));
|
|
334
|
+
if (item.unavailable) card.append(node("p", "muted", item.unavailable));
|
|
335
|
+
else if (panel.kind === "text") card.append(node("p", "", panel.text));
|
|
336
|
+
else if (panel.kind === "link") {
|
|
337
|
+
const url = new URL(panel.href);
|
|
338
|
+
if (["http:", "https:"].includes(url.protocol) && !url.username && !url.password) {
|
|
339
|
+
const link = node("a", "", panel.title);
|
|
340
|
+
link.href = url.href;
|
|
341
|
+
link.rel = "noopener noreferrer";
|
|
342
|
+
card.append(link);
|
|
343
|
+
}
|
|
344
|
+
} else if (panel.kind === "data" && panel.renderer === "json") {
|
|
345
|
+
const label = node("label", "", say("Query input (JSON)", "查询输入(JSON)"));
|
|
346
|
+
const input = node("textarea", "");
|
|
347
|
+
input.value = JSON.stringify({ taskId: task.id });
|
|
348
|
+
label.append(input);
|
|
349
|
+
const contract = node("details", "");
|
|
350
|
+
contract.append(node("summary", "", say("Input schema", "输入结构")));
|
|
351
|
+
contract.append(node("pre", "surface-json", JSON.stringify(item.inputSchema, null, 2)));
|
|
352
|
+
const read = node("button", "record-open", say("Read", "读取"));
|
|
353
|
+
read.type = "button";
|
|
354
|
+
const output = node("pre", "surface-json");
|
|
355
|
+
read.addEventListener("click", async () => {
|
|
356
|
+
if (read.disabled) return;
|
|
357
|
+
read.disabled = true;
|
|
358
|
+
try {
|
|
359
|
+
const result = await actions.readPanel(task.id, {
|
|
360
|
+
capability: item.capability, contractVersion: item.contractVersion, provider: item.provider
|
|
361
|
+
}, JSON.parse(input.value));
|
|
362
|
+
output.textContent = JSON.stringify(result, null, 2);
|
|
363
|
+
} catch (error) { output.textContent = say("Panel unavailable: ", "面板不可用:") + error.message; }
|
|
364
|
+
finally { read.disabled = false; }
|
|
365
|
+
});
|
|
366
|
+
card.append(label, contract, read, output);
|
|
367
|
+
}
|
|
368
|
+
panelBody.append(card);
|
|
369
|
+
});
|
|
370
|
+
} catch (error) { panelBody.textContent = say("Panels unavailable: ", "面板不可用:") + error.message; }
|
|
371
|
+
finally { loadingPanels = false; }
|
|
372
|
+
});
|
|
373
|
+
scaffold.append(panels);
|
|
374
|
+
container.append(scaffold);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Render each task-32 §2.5 submission facet on its own line, never collapsed into
|
|
378
|
+
// a single "started". This repo has one current server contract: every submission
|
|
379
|
+
// returns its faceted receipt, so there is no old-server flat-disposition path to
|
|
380
|
+
// fall back to. A missing facet block is a contract violation, reported as a
|
|
381
|
+
// limited diagnostic rather than reinterpreted as a plausible flat result.
|
|
382
|
+
function renderSubmissionFacets(container, submission, say) {
|
|
383
|
+
clear(container);
|
|
384
|
+
if (!submission) {
|
|
385
|
+
container.append(node("p", "muted",
|
|
386
|
+
say("Submission receipt is missing its §2.5 facets.", "提交回执缺少 §2.5 分面字段。")));
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const phaseText = {
|
|
390
|
+
"active": say("Active — delivery context", "进行中 — 交付上下文"),
|
|
391
|
+
"draft-planning": say("Draft, in planning", "草稿,规划中"),
|
|
392
|
+
"draft-unplanned": say("Draft, not yet planned", "草稿,尚未规划")
|
|
393
|
+
};
|
|
394
|
+
const planningText = {
|
|
395
|
+
"entered": say("Entered planning", "已进入规划"),
|
|
396
|
+
"continued": say("Continued planning", "继续规划"),
|
|
397
|
+
"none": say("No planning change", "规划无变化")
|
|
398
|
+
};
|
|
399
|
+
const activationText = {
|
|
400
|
+
"requested": say("Activation requested", "已请求激活"),
|
|
401
|
+
"pending": say("Activation pending", "激活待处理"),
|
|
402
|
+
"failed": say("Activation failed", "激活失败"),
|
|
403
|
+
"manual-required": say("Manual activation required", "需手动激活"),
|
|
404
|
+
"execution-stopped": say("Execution stopped; not activated", "执行已停止;未激活"),
|
|
405
|
+
"none": say("No activation", "无激活")
|
|
406
|
+
};
|
|
407
|
+
const deliveryText = {
|
|
408
|
+
"queued": say("Leader queued to act now", "已为 Leader 排队处理"),
|
|
409
|
+
"none": say("Leader not woken", "未唤醒 Leader")
|
|
410
|
+
};
|
|
411
|
+
const facts = [
|
|
412
|
+
[say("Phase", "阶段"), phaseText[submission.phase] ?? submission.phase],
|
|
413
|
+
[say("Planning", "规划"), planningText[submission.planning] ?? submission.planning],
|
|
414
|
+
[say("Activation", "激活"), activationText[submission.activation] ?? submission.activation],
|
|
415
|
+
[say("Delivery", "投递"), deliveryText[submission.delivery] ?? submission.delivery]
|
|
416
|
+
];
|
|
417
|
+
for (const [label, value] of facts) {
|
|
418
|
+
container.append(node("p", "muted", label + ": " + value));
|
|
419
|
+
}
|
|
420
|
+
const step = submission.nextStep;
|
|
421
|
+
if (step) {
|
|
422
|
+
const nextText = step.kind === "activate-manually"
|
|
423
|
+
? say("Next: activate this Task explicitly (yui task activate " + step.taskId + ").",
|
|
424
|
+
"下一步:显式激活该 Task(yui task activate " + step.taskId + ")。")
|
|
425
|
+
: step.kind === "start-execution"
|
|
426
|
+
? say("Next: start execution first, then activate (" + step.taskId + ").",
|
|
427
|
+
"下一步:先启动执行,再激活(" + step.taskId + ")。")
|
|
428
|
+
: step.kind === "await-pending-activation"
|
|
429
|
+
? say("Next: waiting on the pending activation " + step.activationRef + ".",
|
|
430
|
+
"下一步:等待待处理的激活 " + step.activationRef + "。")
|
|
431
|
+
: step.kind === "resolve-failed-activation"
|
|
432
|
+
? say("Next: the prior activation failed (" + step.failure + "); retry with a new request or cancel " + step.activationRef + ".",
|
|
433
|
+
"下一步:之前的激活失败(" + step.failure + ");请用新请求重试或取消 " + step.activationRef + "。")
|
|
434
|
+
: "";
|
|
435
|
+
if (nextText) {
|
|
436
|
+
const next = node("p", "", nextText);
|
|
437
|
+
next.dataset.nextStep = step.kind;
|
|
438
|
+
container.append(next);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
`;
|