@zq-silk/yui 0.15.11 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/ARCHITECTURE.md +11 -6
  2. package/ARCHITECTURE.zh-CN.md +8 -4
  3. package/README.md +13 -5
  4. package/dist/agentRun/agentRun.js +3 -0
  5. package/dist/artifacts/artifactCommitLock.js +16 -55
  6. package/dist/artifacts/taskArtifactRepository.js +3 -3
  7. package/dist/cli/agentConfigurationPicker.js +1 -1
  8. package/dist/cli/commandCatalog.js +92 -48
  9. package/dist/cli/completion.js +18 -18
  10. package/dist/cli/completionWizard.js +1 -1
  11. package/dist/cli/dynamicCompletion.js +1 -1
  12. package/dist/cli/interactionPolicy.js +11 -3
  13. package/dist/cli/invocationAuthority.js +64 -0
  14. package/dist/cli/managedDiagnostics.js +2 -2
  15. package/dist/cli/parseRepeatable.js +35 -0
  16. package/dist/cli/updatePorts.js +26 -5
  17. package/dist/cli.js +1303 -1235
  18. package/dist/commands/agentCommands.js +4 -4
  19. package/dist/commands/capabilityCommands.js +1 -1
  20. package/dist/commands/configCommands.js +6 -57
  21. package/dist/commands/configOverview.js +2 -2
  22. package/dist/commands/durableJobCommands.js +12 -6
  23. package/dist/commands/executionAuditCommands.js +10 -0
  24. package/dist/commands/globalRoleCommands.js +78 -29
  25. package/dist/commands/grantCommands.js +0 -3
  26. package/dist/commands/jobCommands.js +1 -4
  27. package/dist/commands/operatorCommands.js +3 -3
  28. package/dist/commands/projectCommands.js +45 -25
  29. package/dist/commands/resourcesCommands.js +10 -40
  30. package/dist/commands/roleConfiguration.js +2 -6
  31. package/dist/commands/taskActivationCommands.js +4 -8
  32. package/dist/commands/taskAgentCapabilities.js +9 -0
  33. package/dist/commands/taskCommandSupport.js +155 -0
  34. package/dist/commands/taskCommandTypes.js +1 -0
  35. package/dist/commands/taskCommands.js +355 -732
  36. package/dist/commands/taskCompletionGate.js +1 -1
  37. package/dist/commands/taskExecutionCommands.js +1 -1
  38. package/dist/commands/taskFactCommands.js +325 -0
  39. package/dist/commands/taskInputCommands.js +12 -42
  40. package/dist/commands/taskIntegrationCommands.js +20 -58
  41. package/dist/commands/taskNextActionCommand.js +7 -6
  42. package/dist/commands/taskPublicationAdoptCommand.js +127 -0
  43. package/dist/commands/taskPublicationCommands.js +12 -3
  44. package/dist/commands/taskPublicationVerifyCommand.js +24 -40
  45. package/dist/commands/taskRemoteDeliveryCommand.js +5 -86
  46. package/dist/commands/taskUpstreamCommands.js +19 -8
  47. package/dist/commands/workflowCommands.js +6 -1
  48. package/dist/completion/completionInstaller.js +26 -26
  49. package/dist/completion/completionState.js +26 -26
  50. package/dist/completion/fileCompletionManager.js +6 -11
  51. package/dist/config/configCatalog.js +0 -2
  52. package/dist/config/timeZone.js +14 -0
  53. package/dist/config/yuiConfig.js +0 -29
  54. package/dist/context/runContextPack.js +5 -3
  55. package/dist/context/taskCatalog.js +185 -0
  56. package/dist/context/taskContext.js +152 -151
  57. package/dist/context/wakeRunReferences.js +11 -0
  58. package/dist/controller/agentCapabilities.js +58 -0
  59. package/dist/controller/agentRuntimeObserver.js +6 -11
  60. package/dist/controller/clientRuntime.js +22 -14
  61. package/dist/controller/controller.js +20 -24
  62. package/dist/controller/fileSchedulerStoreAdapter.js +191 -225
  63. package/dist/controller/globalInputDelivery.js +13 -0
  64. package/dist/controller/jobClient.js +4 -4
  65. package/dist/controller/jobControl.js +60 -25
  66. package/dist/controller/jobSupervisor.js +4 -4
  67. package/dist/controller/providerRetryAdmission.js +100 -0
  68. package/dist/controller/providerRetryDelivery.js +218 -0
  69. package/dist/controller/runtime.js +85 -43
  70. package/dist/controller/runtimeEventProcessor.js +0 -5
  71. package/dist/controller/sessionOwnerReconciliation.js +5 -0
  72. package/dist/controller/taskAgentError.js +35 -0
  73. package/dist/coordination/workMailboxQueue.js +2 -24
  74. package/dist/core/controllerClient.js +2 -2
  75. package/dist/core/fileLockOwner.js +74 -0
  76. package/dist/decision/decision.js +17 -0
  77. package/dist/doctor/doctor.js +18 -9
  78. package/dist/event/taskEvent.js +12 -0
  79. package/dist/execution/workItemExecutionProjection.js +2 -2
  80. package/dist/executor/agentCapabilityConfig.js +43 -0
  81. package/dist/executor/agentConfigurationCatalog.js +49 -11
  82. package/dist/executor/agentExecutor.js +5 -8
  83. package/dist/executor/fileRoleLaunchPlanner.js +11 -53
  84. package/dist/executor/taskAgentCapabilities.js +64 -0
  85. package/dist/integration/deliveryObligation.js +1 -69
  86. package/dist/integration/gitIntegrationService.js +79 -90
  87. package/dist/integration/integrationAttempt.js +3 -14
  88. package/dist/integration/integrationSourceApplication.js +4 -12
  89. package/dist/integration/manifestTags.js +2 -2
  90. package/dist/job/durableJob.js +4 -25
  91. package/dist/job/jobAssignmentScope.js +22 -0
  92. package/dist/job/jobOperation.js +16 -0
  93. package/dist/job/jobRunner.js +2 -1
  94. package/dist/job/stepDirectory.js +15 -0
  95. package/dist/kernel/builtinCapabilities.js +15 -11
  96. package/dist/kernel/kernelPorts.js +1 -17
  97. package/dist/lifecycle/exactRunTerminalization.js +5 -10
  98. package/dist/message/globalProviderRetry.js +15 -0
  99. package/dist/message/inputControlResolution.js +3 -4
  100. package/dist/message/message.js +17 -20
  101. package/dist/message/messageContinuation.js +1 -1
  102. package/dist/milestone/milestone.js +11 -0
  103. package/dist/observability/executionAudit.js +19 -0
  104. package/dist/observability/orchestrationMetrics.js +24 -1
  105. package/dist/observability/runtimeIdentity.js +1 -17
  106. package/dist/output/agentConfigurationPresentation.js +2 -0
  107. package/dist/output/timePresentation.js +1 -14
  108. package/dist/plugins/pluginService.js +12 -4
  109. package/dist/release/releaseWorkflowPorts.js +45 -96
  110. package/dist/release/runtimeRelease.js +9 -15
  111. package/dist/repository/gitWorkspace.js +371 -105
  112. package/dist/repository/projectMaintenanceLock.js +98 -82
  113. package/dist/repository/taskBaseFreshness.js +1 -1
  114. package/dist/repository/taskWorkspaceCoordinator.js +82 -144
  115. package/dist/repository/taskWorkspacePreparer.js +113 -47
  116. package/dist/repository/workspaceCleanupInspection.js +187 -0
  117. package/dist/resources/autoResourceGc.js +4 -77
  118. package/dist/resources/liveReferences.js +7 -54
  119. package/dist/resources/resourceDiscovery.js +5 -118
  120. package/dist/resources/resourceGc.js +233 -181
  121. package/dist/resources/resourceRegistrar.js +5 -4
  122. package/dist/resources/resourceRegistry.js +3 -37
  123. package/dist/resources/resourceRegistryStore.js +13 -36
  124. package/dist/resources/sqliteResourceRegistry.js +43 -26
  125. package/dist/review/deltaRecheck.js +1 -1
  126. package/dist/review/reviewAcceptance.js +1 -1
  127. package/dist/review/reviewDecision.js +1 -1
  128. package/dist/review/reviewRound.js +8 -7
  129. package/dist/review/taskFinalReviewContractResolution.js +1 -1
  130. package/dist/runtime/acpProtocol.js +4 -51
  131. package/dist/runtime/acpSession.js +10 -75
  132. package/dist/runtime/acpSessionConfiguration.js +1 -8
  133. package/dist/runtime/agentEndpoint.js +3 -2
  134. package/dist/runtime/agentError.js +5 -3
  135. package/dist/runtime/agentFailureContext.js +43 -0
  136. package/dist/runtime/agentHost.js +42 -25
  137. package/dist/runtime/builtinAgentErrorMappers.js +91 -0
  138. package/dist/runtime/codexAppServerRuntime.js +34 -3
  139. package/dist/runtime/codexInteractiveHost.js +2 -2
  140. package/dist/runtime/index.js +0 -1
  141. package/dist/runtime/managedCaller.js +21 -1
  142. package/dist/runtime/providerControl.js +5 -1
  143. package/dist/runtime/providerErrors.js +38 -0
  144. package/dist/runtime/providerRetry.js +198 -0
  145. package/dist/runtime/providerRuntimeIdentity.js +28 -2
  146. package/dist/runtime/runtimeObservation.js +0 -5
  147. package/dist/runtime/runtimeSessionCandidate.js +2 -3
  148. package/dist/runtime/sessionOwnerIdentity.js +1 -1
  149. package/dist/runtime/sessionTokenMetrics.js +15 -5
  150. package/dist/runtime/structuredProviderHost.js +10 -43
  151. package/dist/runtime/taskUsageMetrics.js +275 -0
  152. package/dist/runtime/tmuxAdapters.js +6 -8
  153. package/dist/scheduler/activeRoleRunDelivery.js +19 -7
  154. package/dist/scheduler/leaderWakeupProcessor.js +24 -6
  155. package/dist/scheduler/operatorEvent.js +12 -20
  156. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  157. package/dist/scheduler/ports.js +5 -8
  158. package/dist/scheduler/roleRunLiveness.js +4 -4
  159. package/dist/scheduler/roleRunStall.js +16 -23
  160. package/dist/scheduler/taskExecutionProjection.js +49 -36
  161. package/dist/scheduler/taskObservabilityProjection.js +6 -45
  162. package/dist/scheduler/taskWake.js +5 -10
  163. package/dist/scheduler/wakeReason.js +2 -0
  164. package/dist/scheduler/wakeupQueue.js +2 -4
  165. package/dist/setup/setupCommand.js +1 -1
  166. package/dist/storage/contextRecords.js +106 -0
  167. package/dist/storage/currentTaskStore.js +1 -1
  168. package/dist/storage/homeLayout.js +13 -17
  169. package/dist/storage/migrations/agentFailureContext.js +22 -0
  170. package/dist/storage/migrations/currentInputContract.js +86 -0
  171. package/dist/storage/migrations/currentRuntimeContract.js +228 -0
  172. package/dist/storage/migrations/historicalVerificationPlan.js +35 -0
  173. package/dist/storage/migrations/integrationContinuation.js +5 -4
  174. package/dist/storage/migrations/narrowAgentFailureContext.js +65 -0
  175. package/dist/storage/migrations/notificationOnlyWakes.js +74 -0
  176. package/dist/storage/migrations/verificationPlanV1.js +162 -0
  177. package/dist/storage/migrations/verificationPolicy.js +74 -0
  178. package/dist/storage/migrations/workItemHistory.js +46 -0
  179. package/dist/storage/persistenceWorker.js +12 -4
  180. package/dist/storage/recordValidation.js +87 -0
  181. package/dist/storage/sqliteSchema.js +173 -1
  182. package/dist/storage/sqliteStore.js +172 -161
  183. package/dist/storage/storageSchema.js +2 -14
  184. package/dist/storage/storageVersions.js +1 -1
  185. package/dist/storage/storeRpc.js +16 -7
  186. package/dist/storage/taskCatalog.js +123 -0
  187. package/dist/storage/taskStore.js +5 -7
  188. package/dist/storage/upgrade/upgradeOrchestrator.js +25 -37
  189. package/dist/task/archiveDiagnostics.js +1 -0
  190. package/dist/task/archivePreflight.js +124 -0
  191. package/dist/task/completionReadiness.js +5 -24
  192. package/dist/task/draftPlan.js +0 -53
  193. package/dist/task/nextAction.js +7 -13
  194. package/dist/task/publicationAdoption.js +56 -0
  195. package/dist/task/publicationReference.js +10 -0
  196. package/dist/task/remoteDelivery.js +31 -16
  197. package/dist/task/remoteDeliveryService.js +89 -0
  198. package/dist/task/taskActivation.js +2 -25
  199. package/dist/task/taskActivationService.js +0 -2
  200. package/dist/task/taskRecordReference.js +0 -1
  201. package/dist/task/taskSubmission.js +3 -14
  202. package/dist/telemetry/sqliteTelemetryBatch.js +29 -0
  203. package/dist/telemetry/sqliteTelemetryStore.js +49 -49
  204. package/dist/telemetry/telemetryWiring.js +4 -3
  205. package/dist/tmux/tmuxManager.js +29 -20
  206. package/dist/verification/gateArtifact.js +15 -24
  207. package/dist/verification/gateArtifactStore.js +14 -7
  208. package/dist/verification/verificationGateService.js +29 -88
  209. package/dist/verification/verificationPlan.js +27 -72
  210. package/dist/web/assets/client/app.js +92 -17
  211. package/dist/web/assets/client/components.js +55 -13
  212. package/dist/web/assets/client/i18n.js +72 -4
  213. package/dist/web/assets/client/taskSurface.js +6 -5
  214. package/dist/web/assets/client/view.js +35 -7
  215. package/dist/web/assets/shell.js +6 -0
  216. package/dist/web/assets/styles/layout.js +7 -0
  217. package/dist/web/webServer.js +12 -3
  218. package/dist/web/webSnapshot.js +14 -85
  219. package/dist/web/webTaskSurface.js +17 -46
  220. package/dist/workItem/workItem.js +1 -12
  221. package/dist/workspace/cleanupInspection.js +63 -0
  222. package/dist/workspace/workItemChangeSetManager.js +110 -50
  223. package/docs/agent-result-consumption.md +4 -0
  224. package/docs/agent-result-consumption.zh-CN.md +3 -0
  225. package/docs/agent-runtime-drivers.md +7 -0
  226. package/docs/agent-runtime-drivers.zh-CN.md +5 -0
  227. package/docs/architecture/README.md +2 -0
  228. package/docs/architecture/README.zh-CN.md +3 -1
  229. package/docs/architecture/capabilities-and-resources.md +42 -5
  230. package/docs/architecture/capabilities-and-resources.zh-CN.md +33 -3
  231. package/docs/managed-turn-and-session-runtime.md +121 -1
  232. package/docs/managed-turn-and-session-runtime.zh-CN.md +96 -2
  233. package/docs/observability/README.md +62 -0
  234. package/docs/observability/README.zh-CN.md +47 -0
  235. package/docs/plugin-sdk.md +4 -2
  236. package/docs/project-refresh.md +77 -0
  237. package/docs/project-refresh.zh-CN.md +59 -0
  238. package/docs/provider-retry.md +70 -0
  239. package/docs/provider-runtime.md +3 -1
  240. package/docs/provider-runtime.zh-CN.md +4 -2
  241. package/docs/release-workflow.md +190 -7
  242. package/docs/release-workflow.zh-CN.md +139 -5
  243. package/docs/roles-and-configuration.md +29 -0
  244. package/docs/roles-and-configuration.zh-CN.md +21 -0
  245. package/docs/sqlite-control-plane-design.md +16 -3
  246. package/docs/sqlite-control-plane-design.zh-CN.md +13 -2
  247. package/docs/task-dag-semantics.md +3 -3
  248. package/docs/task-dag-semantics.zh-CN.md +2 -2
  249. package/docs/task-delivery.md +223 -17
  250. package/docs/task-delivery.zh-CN.md +171 -14
  251. package/docs/task-discovery.md +101 -0
  252. package/docs/task-discovery.zh-CN.md +85 -0
  253. package/docs/testing/verification-levels.md +161 -9
  254. package/docs/testing/verification-levels.zh-CN.md +116 -9
  255. package/i18n/README.zh-CN.md +13 -7
  256. package/package.json +1 -1
  257. package/skills/yui-leader/SKILL.md +5 -0
  258. package/skills/yui-leader/references/execution.md +3 -2
  259. package/skills/yui-leader/references/integration.md +9 -5
  260. package/skills/yui-leader/references/planning.md +9 -3
  261. package/skills/yui-operator/SKILL.md +24 -8
  262. package/skills/yui-reviewer/SKILL.md +4 -0
  263. package/skills/yui-runtime/SKILL.md +17 -2
  264. package/skills/yui-runtime/references/publication.md +26 -4
  265. package/skills/yui-runtime/references/recovery.md +71 -0
  266. package/dist/agent/agentRegistry.js +0 -10
  267. package/dist/agentRun/runIdentity.js +0 -22
  268. package/dist/commands/deliveryGuardPreflight.js +0 -30
  269. package/dist/commands/taskIntegrationQueueCommands.js +0 -226
  270. package/dist/commands/taskOverviewCommand.js +0 -376
  271. package/dist/completion/completionWizard.js +0 -125
  272. package/dist/context/dispatchContext.js +0 -110
  273. package/dist/context/wakeNotification.js +0 -144
  274. package/dist/integration/integrationCheckEvidenceReuse.js +0 -53
  275. package/dist/integration/integrationQueueEntry.js +0 -191
  276. package/dist/integration/integrationQueueService.js +0 -810
  277. package/dist/release/fakeReleasePorts.js +0 -55
  278. package/dist/runtime/sessionOwnerRegistry.js +0 -137
  279. package/dist/task/deliveryGuard.js +0 -226
  280. /package/dist/{commands/taskActor.js → task/taskAuthority.js} +0 -0
@@ -1,11 +1,11 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
- import { agentNotFound, usageError } from "../errors/cliError.js";
3
- import { defaultTableWidth, renderTable } from "../output/table.js";
4
2
  import { isAgentAdapterId, supportedAgentAdapterIds } from "../agent/adapterCatalog.js";
5
- import { adapterIdForExecutionComponent, agentExecutionComponentLabel, defaultExecutionComponentForAdapter, isAgentExecutionComponentId, supportedAgentExecutionComponentIds } from "../agent/executionComponents.js";
6
3
  import { createConfiguredAgent, validateConfiguredAgent } from "../agent/agent.js";
7
- import { LIVE_SESSION_ACKNOWLEDGEMENT_OPTION } from "./roleRuntimeGuard.js";
4
+ import { adapterIdForExecutionComponent, agentExecutionComponentLabel, defaultExecutionComponentForAdapter, isAgentExecutionComponentId, supportedAgentExecutionComponentIds } from "../agent/executionComponents.js";
5
+ import { agentNotFound, usageError } from "../errors/cliError.js";
6
+ import { defaultTableWidth, renderTable } from "../output/table.js";
8
7
  import { hasRuntimeLifecycleWork, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
8
+ import { LIVE_SESSION_ACKNOWLEDGEMENT_OPTION } from "./roleRuntimeGuard.js";
9
9
  export function runAgentCommand(args, store) {
10
10
  const [command, ...rest] = args;
11
11
  switch (command) {
@@ -1,5 +1,5 @@
1
1
  import { usageError } from "../errors/cliError.js";
2
- import { resolveJobCaller } from "./taskActor.js";
2
+ import { resolveJobCaller } from "../task/taskAuthority.js";
3
3
  import { callFileTaskController } from "../controller/clientRuntime.js";
4
4
  export async function runCapabilityCommand(args, home, environment) {
5
5
  const [action, ...rest] = args;
@@ -1,15 +1,14 @@
1
1
  import { mkdirSync, realpathSync } from "node:fs";
2
2
  import { isAbsolute, relative, resolve } from "node:path";
3
- import { usageError } from "../errors/cliError.js";
4
- import { DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_LEADER_NEXT_ACTION_MODE, DEFAULT_LEADER_SEMANTIC_BUDGET_RUNS, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, LEADER_NEXT_ACTION_MODES, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetRuns, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
5
3
  import { CONFIG_DEFINITIONS, CONFIG_KEYS, configDefinition, configDefinitionsForDomain } from "../config/configCatalog.js";
6
- import { resolveTimeZone } from "../output/timePresentation.js";
4
+ import { resolveTimeZone } from "../config/timeZone.js";
5
+ import { DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
6
+ import { usageError } from "../errors/cliError.js";
7
7
  import { defaultTableWidth, renderTable } from "../output/table.js";
8
8
  import { REVIEW_TRIGGERS } from "../review/reviewConfig.js";
9
9
  /**
10
10
  * One uniform key model for every durable setting. Each catalog domain uses
11
- * the same show/set/clear contract; strategy settings such as `review` and
12
- * `leader-next-action` are keys like any other.
11
+ * the same show/set/clear contract, including the explicit review policy.
13
12
  */
14
13
  export { CONFIG_KEYS } from "../config/configCatalog.js";
15
14
  const CONFIG_PROPERTIES = Object.fromEntries(CONFIG_DEFINITIONS.map(({ key, property }) => [
@@ -20,7 +19,6 @@ const TIME_ZONE_SET_USAGE = "System config set usage: yui config system set time
20
19
  const RECONCILIATION_SET_USAGE = "Runtime config set usage: yui config runtime set reconciliation-interval-seconds <5-300>.";
21
20
  const RESOURCES_GC_MODE_SET_USAGE = "Resources config set usage: yui config resources set resources-gc-mode <report|quarantine>.";
22
21
  const RESOURCES_GC_AUTO_QUARANTINE_SET_USAGE = "Resources config set usage: yui config resources set resources-gc-auto-quarantine <true|false>.";
23
- const LEADER_NEXT_ACTION_SET_USAGE = `Workflow config set usage: yui config workflow set leader-next-action <${LEADER_NEXT_ACTION_MODES.join("|")}>.`;
24
22
  const REVIEW_SET_USAGE = "Workflow config set usage: yui config workflow set review --role <global-role> --trigger <always|leader|final>.";
25
23
  export function runConfigCommand(domain, args, store) {
26
24
  const keys = configDefinitionsForDomain(domain).map(({ key }) => key);
@@ -65,7 +63,6 @@ export function effectiveConfigData(config, domain) {
65
63
  lastTaskId: config.lastTaskId ?? null,
66
64
  reconciliationIntervalSeconds: config.reconciliationIntervalSeconds
67
65
  ?? DEFAULT_RECONCILIATION_INTERVAL_SECONDS,
68
- leaderNextActionMode: resolveLeaderNextActionMode(config.leaderNextActionMode),
69
66
  resourcesGcMode: resolveResourcesGcMode(config.resourcesGcMode),
70
67
  resourcesGcAutoQuarantine: resolveResourcesGcAutoQuarantine(config.resourcesGcAutoQuarantine),
71
68
  resourcesQuarantineTtlHours: resolveResourcesQuarantineTtlHours(config.resourcesQuarantineTtlHours),
@@ -77,7 +74,6 @@ export function effectiveConfigData(config, domain) {
77
74
  controllerTaskConcurrency: resolveControllerTaskConcurrency(config.controllerTaskConcurrency),
78
75
  agentLaunchInactivityTimeoutSeconds: resolveAgentLaunchInactivityTimeoutSeconds(config.agentLaunchInactivityTimeoutSeconds),
79
76
  deliveryTimeoutSeconds: resolveDeliveryTimeoutSeconds(config.deliveryTimeoutSeconds),
80
- leaderSemanticBudgetRuns: resolveLeaderSemanticBudgetRuns(config.leaderSemanticBudgetRuns),
81
77
  tmuxBin: resolveTmuxBin(config.tmuxBin),
82
78
  tmuxHistoryLimit: resolveTmuxHistoryLimit(config.tmuxHistoryLimit),
83
79
  telemetryEnabled: resolveTelemetryEnabled(config.telemetryEnabled),
@@ -164,7 +160,7 @@ const CONFIG_KEY_HANDLERS = [
164
160
  throw usageError("System config set usage: yui config system set default-agent <agent-id>.");
165
161
  }
166
162
  const defaultAgent = args[0].trim();
167
- if (store.getConfiguredAgent?.(defaultAgent) === null) {
163
+ if (store.getConfiguredAgent(defaultAgent) === null) {
168
164
  throw usageError(`Configured Agent not found: ${defaultAgent}.`);
169
165
  }
170
166
  saveConfigKey(store, (config) => ({ ...config, defaultAgent }));
@@ -237,51 +233,6 @@ const CONFIG_KEY_HANDLERS = [
237
233
  return `Reconciliation interval reset to ${DEFAULT_RECONCILIATION_INTERVAL_SECONDS} seconds\n`;
238
234
  }
239
235
  },
240
- {
241
- key: "leader-next-action",
242
- showLabel: "Leader next-action mode",
243
- showValue: (config) => resolveLeaderNextActionMode(config.leaderNextActionMode),
244
- set(args, store) {
245
- if (args.length !== 1)
246
- throw usageError(LEADER_NEXT_ACTION_SET_USAGE);
247
- let mode;
248
- try {
249
- mode = resolveLeaderNextActionMode(args[0]);
250
- }
251
- catch (error) {
252
- throw usageError(error instanceof Error ? error.message : String(error), LEADER_NEXT_ACTION_SET_USAGE);
253
- }
254
- saveConfigKey(store, (config) => ({ ...config, leaderNextActionMode: mode }));
255
- return `Leader next-action mode set to ${mode}\n`;
256
- },
257
- clear(store) {
258
- saveConfigKey(store, (config) => {
259
- const { leaderNextActionMode: _removed, ...rest } = config;
260
- return rest;
261
- });
262
- return `Leader next-action mode reset to ${DEFAULT_LEADER_NEXT_ACTION_MODE}\n`;
263
- }
264
- },
265
- {
266
- key: "leader-semantic-budget-runs",
267
- showLabel: "Leader semantic budget",
268
- showValue: (config) => `${resolveLeaderSemanticBudgetRuns(config.leaderSemanticBudgetRuns)} runs`,
269
- set(args, store) {
270
- const usage = "Workflow config set usage: yui config workflow set leader-semantic-budget-runs <1-20>.";
271
- if (args.length !== 1)
272
- throw usageError(usage);
273
- const leaderSemanticBudgetRuns = validatedConfigValue(() => resolveLeaderSemanticBudgetRuns(Number(args[0])), usage);
274
- saveConfigKey(store, (config) => ({ ...config, leaderSemanticBudgetRuns }));
275
- return `Leader semantic budget set to ${leaderSemanticBudgetRuns} runs\n`;
276
- },
277
- clear(store) {
278
- saveConfigKey(store, (config) => {
279
- const { leaderSemanticBudgetRuns: _removed, ...rest } = config;
280
- return rest;
281
- });
282
- return `Leader semantic budget reset to ${DEFAULT_LEADER_SEMANTIC_BUDGET_RUNS} runs\n`;
283
- }
284
- },
285
236
  {
286
237
  key: "resources-gc-mode",
287
238
  showLabel: "Resources GC mode",
@@ -565,7 +516,7 @@ const CONFIG_KEY_HANDLERS = [
565
516
  || !REVIEW_TRIGGERS.includes(rawTrigger)) {
566
517
  throw usageError(REVIEW_SET_USAGE);
567
518
  }
568
- if (store.getGlobalRole?.(roleName) === null) {
519
+ if (store.getGlobalRole(roleName) === null) {
569
520
  throw usageError(`Global Role not found: ${roleName}.`);
570
521
  }
571
522
  const trigger = rawTrigger;
@@ -598,8 +549,6 @@ if (missingConfigHandlers.length > 0 || duplicateConfigHandlers.length > 0) {
598
549
  }
599
550
  function resolveDefaultWorkspace(value, store) {
600
551
  const requested = resolve(value);
601
- if (store.rootDirectory === undefined)
602
- return requested;
603
552
  const requestedHome = resolve(store.rootDirectory());
604
553
  assertWorkspaceOutsideHome(requested, requestedHome);
605
554
  mkdirSync(requested, { recursive: true, mode: 0o700 });
@@ -12,7 +12,7 @@ import { CONFIG_DOMAINS } from "../config/configCatalog.js";
12
12
  * therefore explain what the user sees without reconstructing configuration
13
13
  * from help text or implementation defaults.
14
14
  */
15
- export function runConfigOverview(args, store, environment, identity, roleOptions) {
15
+ export function runConfigOverview(args, store, environment, roleOptions) {
16
16
  if (args.length !== 0)
17
17
  throw usageError("Config show usage: yui config show.");
18
18
  const domains = Object.fromEntries(CONFIG_DOMAINS.map((domain) => [
@@ -27,7 +27,7 @@ export function runConfigOverview(args, store, environment, identity, roleOption
27
27
  ]));
28
28
  const profileResult = runProfileCommand(["list"], store);
29
29
  const profiles = profileResult.data.profiles;
30
- const completion = inspectCompletionStates(store.getConfig(), environment, identity);
30
+ const completion = inspectCompletionStates(store.getConfig(), environment);
31
31
  const roleOutput = runGlobalRoleCommand(["list"], store, roleOptions);
32
32
  if (typeof roleOutput !== "string") {
33
33
  throw new Error("Config overview received an invalid Role control result.");
@@ -1,7 +1,7 @@
1
1
  import { usageError } from "../errors/cliError.js";
2
2
  import { ensureFileTaskController } from "../controller/clientRuntime.js";
3
3
  import { acknowledgeDurableJob, cancelDurableJob, getDurableJob, startDurableJob } from "../controller/jobClient.js";
4
- import { resolveJobCaller, taskLocalActor } from "./taskActor.js";
4
+ import { resolveJobCaller, taskLocalActor } from "../task/taskAuthority.js";
5
5
  /**
6
6
  * The textual `--owner` forms accepted by `job start`. The public help text in
7
7
  * the command catalog must document exactly these forms.
@@ -25,7 +25,7 @@ export async function runDurableJobCommand(args, options) {
25
25
  throw usageError(command === undefined
26
26
  ? "Job command is required: start, get, cancel, or acknowledge."
27
27
  : `Unknown command: job ${command}`, "yui job start --task <id> --project <project> --head <sha> --workspace <dir> "
28
- + "--step <name>=<command> [--step ...] [--env K=V ...] "
28
+ + "--request-id <id> --step <name>=<command> [--step ...] [--env K=V ...] "
29
29
  + `[--owner ${JOB_OWNER_USAGE}] [--retry-of <job-id>]\n`
30
30
  + "yui job get --task <id> --job <job-id>\n"
31
31
  + "yui job cancel --task <id> --job <job-id>\n"
@@ -36,6 +36,7 @@ async function startJob(args, options) {
36
36
  await ensureFileTaskController(options.home, { environment: options.environment });
37
37
  const caller = resolveJobCaller(options.environment, parsed.taskId);
38
38
  const params = {
39
+ requestId: parsed.requestId,
39
40
  taskId: parsed.taskId,
40
41
  owner: parsed.owner,
41
42
  projectId: parsed.projectId,
@@ -54,8 +55,9 @@ async function startJob(args, options) {
54
55
  }
55
56
  async function getJob(args, options) {
56
57
  const ref = parseRefArgs(args, "get");
58
+ const caller = resolveJobCaller(options.environment, ref.taskId);
57
59
  await ensureFileTaskController(options.home, { environment: options.environment });
58
- const job = await getDurableJob(options.home, ref.taskId, ref.jobId);
60
+ const job = await getDurableJob(options.home, ref.taskId, ref.jobId, caller);
59
61
  if (options.json === true)
60
62
  return `${JSON.stringify(job, null, 2)}\n`;
61
63
  const lines = [
@@ -111,6 +113,7 @@ async function acknowledgeJob(args, options) {
111
113
  }
112
114
  function parseStartArgs(args) {
113
115
  let taskId;
116
+ let requestId;
114
117
  let projectId;
115
118
  let head;
116
119
  let workspace;
@@ -129,6 +132,9 @@ function parseStartArgs(args) {
129
132
  case "--task":
130
133
  taskId = value;
131
134
  break;
135
+ case "--request-id":
136
+ requestId = value;
137
+ break;
132
138
  case "--project":
133
139
  projectId = value;
134
140
  break;
@@ -165,10 +171,10 @@ function parseStartArgs(args) {
165
171
  }
166
172
  }
167
173
  if (taskId === undefined || projectId === undefined || head === undefined
168
- || workspace === undefined || steps.length === 0) {
169
- throw usageError("job start requires --task, --project, --head, --workspace, and at least one --step.", "yui job start ...");
174
+ || workspace === undefined || requestId === undefined || requestId.trim().length === 0 || steps.length === 0) {
175
+ throw usageError("job start requires --request-id, --task, --project, --head, --workspace, and at least one --step.", "yui job start ...");
170
176
  }
171
- return { taskId, owner, projectId, head, workspace, env, steps, retryOf };
177
+ return { taskId, requestId, owner, projectId, head, workspace, env, steps, retryOf };
172
178
  }
173
179
  export function parseJobOwner(value) {
174
180
  if (value === "task")
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { usageError } from "../errors/cliError.js";
9
9
  import { defaultTableWidth, renderTable } from "../output/table.js";
10
+ import { formatUsageMetric } from "../runtime/taskUsageMetrics.js";
10
11
  import { runExecutionAudit } from "../observability/executionAudit.js";
11
12
  export function parseExecutionAuditOptions(args) {
12
13
  const options = {};
@@ -246,6 +247,15 @@ export function renderExecutionAudit(report, width = defaultTableWidth()) {
246
247
  else {
247
248
  lines.push("", ...sectionError("orchestration", report));
248
249
  }
250
+ if (report.usage.status === "ok" && report.usage.data !== undefined) {
251
+ lines.push("", "Observed usage — Task lifetime, observed sources only (audit time window not applied):");
252
+ for (const usage of report.usage.data) {
253
+ lines.push(` ${usage.taskId}: tokens=${formatUsageMetric(usage.tokens)}; tools=${formatUsageMetric(usage.toolCalls)}; elapsed=${formatUsageMetric(usage.elapsedSeconds, "s")}; native execution sum=${formatUsageMetric(usage.executionSeconds, "s")}`);
254
+ }
255
+ }
256
+ else {
257
+ lines.push("", ...sectionError("usage", report));
258
+ }
249
259
  if (report.storage.status === "ok" && report.storage.data !== undefined) {
250
260
  const storage = report.storage.data;
251
261
  lines.push("", `Storage: backend ${storage.backend} · state.json ${formatBytes(storage.stateJsonBytes)} · yui.db ${formatBytes(storage.databaseBytes)}`
@@ -1,4 +1,6 @@
1
1
  import { roleNotFound, usageError } from "../errors/cliError.js";
2
+ import { controlProviderRetry, providerRetryProjection, renderProviderRetry } from "../runtime/providerRetry.js";
3
+ import { settleGlobalRetryInput } from "../message/globalProviderRetry.js";
2
4
  import { createRoleSessionSet, recordRoleAgentSession } from "../executor/agentExecutor.js";
3
5
  import { resolveEffectiveLaunch } from "../executor/effectiveLaunch.js";
4
6
  import { managedGlobalRoleWorkspace } from "../storage/homeLayout.js";
@@ -12,30 +14,41 @@ import { isSystemRoleName, SYSTEM_ROLE_NAMES, systemRoleDescription } from "../r
12
14
  import { hasAgentConfigOptions, hasNoRoleMutation, parseRoleOptions, patchRoleAgentBinding, roleOptionSpecs, roleProfileFrom, roleProfilePatch } from "./roleConfiguration.js";
13
15
  import { hasRoleLaunchContextOptions, validateConfiguredRoleSkills } from "./roleSkillValidation.js";
14
16
  import { assertLiveRoleSessionAcknowledged, assertRoleRuntimeMutationAllowed, LIVE_SESSION_ACKNOWLEDGEMENT_OPTION } from "./roleRuntimeGuard.js";
15
- export function runGlobalRoleCommand(args, store, options = {}) {
16
- const [command, ...rest] = args;
17
- if (command === "message" || command === "interrupt") {
18
- const env = options.env ?? process.env;
19
- const target = command === "message" ? rest[1] : rest[0];
20
- if (env.YUI_SESSION_SCOPE !== undefined && env.YUI_SESSION_SCOPE !== "global"
21
- || env.YUI_SESSION_SCOPE === "global" && env.YUI_ROLE !== "operator"
22
- && env.YUI_ROLE !== target) {
23
- throw usageError("Global input mutation is outside the exact Session authority.");
24
- }
25
- if (env.YUI_SESSION_SCOPE === "global") {
26
- const caller = store.getGlobalRoleSessionSet(env.YUI_ROLE ?? "");
27
- const session = caller?.sessions[caller.activeAgentId];
28
- if (session === undefined || session.status !== "active" || env.YUI_AGENT_ID !== session.agentId
29
- || env.YUI_ADAPTER_ID !== session.adapterId
30
- || (env.CODEX_THREAD_ID ?? env.YUI_NATIVE_SESSION_ID) !== session.nativeSessionId) {
31
- throw usageError("Global input mutation requires the current native caller Session.");
32
- }
33
- }
34
- else if (env.YUI_ROLE !== undefined || env.YUI_AGENT_ID !== undefined
35
- || env.YUI_NATIVE_SESSION_ID !== undefined) {
36
- throw usageError("Incomplete managed identity cannot acquire user authority.");
17
+ export function applyGlobalInputControl(name, input, store, options = {}) {
18
+ assertGlobalInputAuthority(store, options, name);
19
+ return input.action === "interrupt"
20
+ ? interruptGlobalInput(name, input, store)
21
+ : messageGlobalInput(name, input, store, options);
22
+ }
23
+ function inputOutput(output, data) {
24
+ return { kind: "output", output, data };
25
+ }
26
+ function renderGlobalInput(result, options) {
27
+ return result.kind === "output" ? jsonOrText(options, result.output, result.data) : result;
28
+ }
29
+ function assertGlobalInputAuthority(store, options, target) {
30
+ const env = options.env ?? process.env;
31
+ if (env.YUI_SESSION_SCOPE !== undefined && env.YUI_SESSION_SCOPE !== "global"
32
+ || env.YUI_SESSION_SCOPE === "global" && env.YUI_ROLE !== "operator" && env.YUI_ROLE !== target) {
33
+ throw usageError("Global input mutation is outside the exact Session authority.");
34
+ }
35
+ if (env.YUI_SESSION_SCOPE === "global") {
36
+ const caller = store.getGlobalRoleSessionSet(env.YUI_ROLE ?? "");
37
+ const session = caller?.sessions[caller.activeAgentId];
38
+ if (session === undefined || session.status !== "active" || env.YUI_AGENT_ID !== session.agentId
39
+ || env.YUI_ADAPTER_ID !== session.adapterId
40
+ || (env.CODEX_THREAD_ID ?? env.YUI_NATIVE_SESSION_ID) !== session.nativeSessionId) {
41
+ throw usageError("Global input mutation requires the current native caller Session.");
37
42
  }
38
43
  }
44
+ else if (env.YUI_ROLE !== undefined || env.YUI_AGENT_ID !== undefined || env.YUI_NATIVE_SESSION_ID !== undefined) {
45
+ throw usageError("Incomplete managed identity cannot acquire user authority.");
46
+ }
47
+ }
48
+ export function runGlobalRoleCommand(args, store, options = {}) {
49
+ const [command, ...rest] = args;
50
+ if (command === "session" && rest[0] === "retry")
51
+ assertGlobalInputAuthority(store, options, rest[1]);
39
52
  switch (command) {
40
53
  case "add": return addRole(rest, store, options);
41
54
  case "list": return listRoles(rest, store);
@@ -126,6 +139,7 @@ function roleContext(args, store, options) {
126
139
  pendingMessages: pendingQueue,
127
140
  messages: store.listGlobalRoleMessages(name),
128
141
  nativeTurn: sessions?.providerBinding?.run ?? null,
142
+ retry: providerRetryProjection(sessions?.providerBinding),
129
143
  interrupts: sessions?.interrupts ?? {},
130
144
  sessionManifestPath: environment.YUI_SESSION_MANIFEST,
131
145
  cliCommand: "yui"
@@ -382,6 +396,28 @@ function enterRole(args, store) {
382
396
  }
383
397
  function roleSession(args, store, options) {
384
398
  const [command, rawName, ...tail] = args;
399
+ if (command === "retry") {
400
+ const name = roleName(rawName);
401
+ const [action = "show", ...extra] = tail;
402
+ if (extra.length > 0 || !["show", "cancel", "disable", "enable"].includes(action)) {
403
+ throw usageError("Usage: yui session retry <role> [show|cancel|disable|enable]");
404
+ }
405
+ return store.transaction(tx => {
406
+ requireRole(name, tx);
407
+ const sessions = tx.getGlobalRoleSessionSet(name);
408
+ let binding = sessions?.providerBinding ?? null;
409
+ if (action !== "show") {
410
+ if (sessions === null || binding === null)
411
+ throw usageError("No current Provider Session.");
412
+ binding = controlProviderRetry(binding, action, Date.now());
413
+ tx.saveGlobalRoleSessionSet({ ...sessions, providerBinding: binding });
414
+ settleGlobalRetryInput(tx, name, binding, new Date());
415
+ }
416
+ return options.jsonOutput ? JSON.stringify({
417
+ roleName: name, retry: providerRetryProjection(binding), disabled: binding?.retryDisabled ?? false
418
+ }) + "\n" : renderProviderRetry(binding) + "\n";
419
+ });
420
+ }
385
421
  if (command !== "record" && command !== "replace") {
386
422
  throw usageError("Session usage: yui session record|replace <role> --native-id <id> [--reason <reason>].");
387
423
  }
@@ -526,6 +562,13 @@ function globalRoleMessage(args, store, options) {
526
562
  const expectedTarget = action === "steer"
527
563
  ? required(parsed.one("--expected-target"), "--expected-target")
528
564
  : undefined;
565
+ return renderGlobalInput(applyGlobalInputControl(name, action === "steer"
566
+ ? { action, body, requestId, expectedTarget: expectedTarget, to: name }
567
+ : { action, body, requestId }, store, options), options);
568
+ }
569
+ function messageGlobalInput(name, input, store, options) {
570
+ const { action, body, requestId } = input;
571
+ const expectedTarget = input.action === "steer" ? input.expectedTarget : undefined;
529
572
  const now = new Date();
530
573
  // The durable Global input is authored as an operator input: a Global Role has
531
574
  // no Task Leader, and the operator is the human authority over Global Roles.
@@ -538,14 +581,14 @@ function globalRoleMessage(args, store, options) {
538
581
  });
539
582
  if (action === "queue") {
540
583
  const state = persisted.idempotentReplay ? "idempotent-replay" : "queued";
541
- return jsonOrText(options, `Queued Global message ${persisted.message.id} to ${name} (${state}).\n`, { roleName: name, message: persisted.message, delivery: { state } });
584
+ return inputOutput(`Queued Global message ${persisted.message.id} to ${name} (${state}).\n`, { roleName: name, message: persisted.message, delivery: { state } });
542
585
  }
543
586
  if (persisted.idempotentReplay) {
544
- return jsonOrText(options, `Steer Global message ${persisted.message.id} already recorded (idempotent-replay).\n`, { roleName: name, message: persisted.message, steer: { state: "idempotent-replay" } });
587
+ return inputOutput(`Steer Global message ${persisted.message.id} already recorded (idempotent-replay).\n`, { roleName: name, message: persisted.message, steer: { state: "idempotent-replay" } });
545
588
  }
546
589
  const resolution = resolveGlobalInputControl(store, name, "steer", expectedTarget);
547
590
  if (resolution.outcome !== "ready") {
548
- return jsonOrText(options, `Steer Global message ${persisted.message.id} saved but not delivered (${resolution.code}: ${resolution.detail}).\n`, { roleName: name, message: persisted.message,
591
+ return inputOutput(`Steer Global message ${persisted.message.id} saved but not delivered (${resolution.code}: ${resolution.detail}).\n`, { roleName: name, message: persisted.message,
549
592
  steer: { state: "not-steered", code: resolution.code, detail: resolution.detail } });
550
593
  }
551
594
  store.updateGlobalRoleMessage({ ...persisted.message, control: {
@@ -571,7 +614,6 @@ function globalRoleMessage(args, store, options) {
571
614
  * fourth action and not an auto-fallback (decision-3 §4).
572
615
  */
573
616
  function globalRoleInterrupt(args, store, options) {
574
- const usage = "Role interrupt usage: yui role interrupt <role> --expected-target <turn> [--then-message <global-message-id>] [--request-id <id>].";
575
617
  const [rawName, ...tail] = args;
576
618
  const name = roleName(rawName);
577
619
  const parsed = parseOptions(tail, new Map([
@@ -582,12 +624,19 @@ function globalRoleInterrupt(args, store, options) {
582
624
  const expectedTarget = required(parsed.one("--expected-target"), "--expected-target");
583
625
  const thenMessageId = trimmed(parsed.one("--then-message"));
584
626
  const requestId = trimmed(parsed.one("--request-id")) ?? `cancel:${encodeURIComponent(expectedTarget)}`;
627
+ return renderGlobalInput(applyGlobalInputControl(name, {
628
+ action: "interrupt", role: name, expectedTarget, thenMessage: thenMessageId, requestId
629
+ }, store, options), options);
630
+ }
631
+ function interruptGlobalInput(name, input, store) {
632
+ const { expectedTarget, thenMessage: thenMessageId } = input;
633
+ const requestId = input.requestId ?? `cancel:${encodeURIComponent(expectedTarget)}`;
585
634
  const fingerprint = JSON.stringify({ expectedTarget, thenMessageId });
586
635
  const prior = store.getGlobalRoleSessionSet(name)?.interrupts?.[requestId];
587
636
  if (prior !== undefined) {
588
637
  if (prior.fingerprint !== fingerprint)
589
638
  throw usageError("Interrupt requestId already names another control.");
590
- return jsonOrText(options, `Interrupt ${requestId} already recorded; no native control repeated.\n`, { roleName: name, interrupt: prior.receipt ?? { state: "interrupt-unknown" }, idempotentReplay: true });
639
+ return inputOutput(`Interrupt ${requestId} already recorded; no native control repeated.\n`, { roleName: name, interrupt: prior.receipt ?? { state: "interrupt-unknown" }, idempotentReplay: true });
591
640
  }
592
641
  const resolved = store.transaction((tx) => {
593
642
  requireRole(name, tx);
@@ -620,10 +669,10 @@ function globalRoleInterrupt(args, store, options) {
620
669
  return resolution;
621
670
  });
622
671
  if (resolved.outcome === "then-conflict") {
623
- return jsonOrText(options, `Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
672
+ return inputOutput(`Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
624
673
  }
625
674
  if (resolved.outcome !== "ready") {
626
- return jsonOrText(options, `Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
675
+ return inputOutput(`Interrupt not delivered (${resolved.code}: ${resolved.detail}).\n`, { roleName: name, interrupt: { state: "not-interrupted", code: resolved.code, detail: resolved.detail } });
627
676
  }
628
677
  return {
629
678
  kind: "input-interrupt",
@@ -286,9 +286,6 @@ function requireTask(store, taskId) {
286
286
  function recordTaskEvent(store, taskId, type, payload, now) {
287
287
  store.saveEvent(taskId, createTaskEvent(store.nextEventId(taskId), taskId, type, payload, now));
288
288
  }
289
- function requiredOption(options, name) {
290
- return requiredText(options.get(name), name);
291
- }
292
289
  function optionalOption(options, name) {
293
290
  if (!options.has(name))
294
291
  return undefined;
@@ -93,9 +93,6 @@ function retryJob(args, store, options) {
93
93
  enqueueWork(tx, { kind: "role", taskId: task.id, roleName: "leader" }, "recovery-retry", now, [{ type: "task", id: task.id }]);
94
94
  });
95
95
  const target = { kind: "role", taskId, roleName: "leader" };
96
- if (runtime.notifyMailboxChanged !== undefined)
97
- runtime.notifyMailboxChanged(target);
98
- else
99
- runtime.notifyStateChanged(taskId);
96
+ runtime.notifyMailboxChanged(target);
100
97
  return `Retry requested for ${id}\n`;
101
98
  }
@@ -1,11 +1,11 @@
1
- import { usageError } from "../errors/cliError.js";
2
1
  import { agentAdapterLabel as adapterLabel } from "../agent/adapterCatalog.js";
2
+ import { usageError } from "../errors/cliError.js";
3
3
  import { createRoleSessionSet } from "../executor/agentExecutor.js";
4
- import { listOperatorSessions, projectOperatorStatus, prepareOperatorNewSession, prepareOperatorResumeSession } from "../operator/operatorSessionHistory.js";
4
+ import { TASK_SUBMISSION_INTENTS } from "../message/message.js";
5
+ import { listOperatorSessions, prepareOperatorNewSession, prepareOperatorResumeSession, projectOperatorStatus } from "../operator/operatorSessionHistory.js";
5
6
  import { defaultTableWidth, renderTable } from "../output/table.js";
6
7
  import { formatRelativeTimestamp } from "../output/timePresentation.js";
7
8
  import { updateGlobalRole } from "../role/role.js";
8
- import { TASK_SUBMISSION_INTENTS } from "../message/message.js";
9
9
  import { submitOperatorMessage } from "./taskCommands.js";
10
10
  import { readCommandText } from "./textInput.js";
11
11
  /** Operator command parsing never launches or attaches a native process. */