@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,376 +0,0 @@
1
- import { usageError } from "../errors/cliError.js";
2
- import { isRoleRunStalled, latestStallProgressAt } from "../scheduler/roleRunStall.js";
3
- import { formatTimestamp } from "../output/timePresentation.js";
4
- import { pendingWakeupProjection } from "../storage/taskStore.js";
5
- import { defaultTableWidth, renderTable } from "../output/table.js";
6
- import { projectTaskExecutionFromFacts } from "../scheduler/taskExecutionProjection.js";
7
- import { resolveRuntimeHealth } from "../config/yuiConfig.js";
8
- import { projectNextAction } from "../task/nextAction.js";
9
- import { projectTaskRemoteDeliveryFromStore } from "./taskRemoteDeliveryCommand.js";
10
- export function parseTaskListOptions(args) {
11
- const allowed = new Set(["--all", "--verbose"]);
12
- if (args.some((argument) => !allowed.has(argument))
13
- || new Set(args).size !== args.length) {
14
- throw usageError("Task list usage: yui task list [--all] [--verbose].");
15
- }
16
- return {
17
- all: args.includes("--all"),
18
- verbose: args.includes("--verbose")
19
- };
20
- }
21
- export function buildTaskOverview(store, options, now = new Date()) {
22
- const runtimeHealthPolicy = resolveRuntimeHealth(store.getConfig().runtimeHealth);
23
- const tasks = store.listTasks()
24
- .filter((task) => options.all || task.status !== "archived")
25
- .map((task) => buildTaskOverviewEntry(task, store, now, runtimeHealthPolicy));
26
- return { tasks };
27
- }
28
- export function renderTaskOverview(result, options, timeZone, width = defaultTableWidth()) {
29
- if (result.tasks.length === 0)
30
- return "No tasks found.\n";
31
- const title = options.all ? "Tasks (all)" : "Tasks (unarchived)";
32
- const output = renderTable(title, [
33
- { header: "Task", minWidth: 8, maxWidth: 20 },
34
- { header: "Title", minWidth: 10, maxWidth: 46 },
35
- { header: "Lifecycle", minWidth: 9, maxWidth: 14 },
36
- { header: "Leader", minWidth: 12, maxWidth: 48 },
37
- { header: "Summary updated", minWidth: 16, maxWidth: 28 },
38
- { header: "Work", minWidth: 8, maxWidth: 38 },
39
- { header: "Blockers", minWidth: 9, maxWidth: 42 },
40
- { header: "Execution", minWidth: 14, maxWidth: 34 },
41
- { header: "Delivery", minWidth: 12, maxWidth: 28 },
42
- { header: "Next action / owner", minWidth: 16, maxWidth: 42 }
43
- ], result.tasks.map((task) => [
44
- task.id,
45
- task.title,
46
- task.status,
47
- leaderCell(task),
48
- task.summaryUpdatedAt === null
49
- ? "missing"
50
- : formatTimestamp(task.summaryUpdatedAt, timeZone),
51
- workCell(task.work.counts),
52
- blockersCell(task.blockers),
53
- `${task.execution.status} / ${task.execution.owner}`,
54
- deliveryCell(task.remoteDelivery),
55
- nextCell(task.next)
56
- ]), width);
57
- if (!options.verbose)
58
- return `${output}\n`;
59
- return `${output}\n\n${renderVerboseDetails(result.tasks, timeZone)}\n`;
60
- }
61
- function buildTaskOverviewEntry(task, store, now, runtimeHealthPolicy) {
62
- const brief = store.getTaskBrief(task.id);
63
- const roles = store.listRoles(task.id);
64
- const leaderRole = roles.find((role) => role.name === "leader") ?? null;
65
- const workItems = store.listWorkItems(task.id);
66
- const inputRequests = store.listInputRequests(task.id);
67
- const openInputRequests = inputRequests.filter((request) => request.status === "open");
68
- const runs = store.listRuns(task.id);
69
- const events = store.listEvents(task.id);
70
- const leaderFailure = store.getLeaderFailure(task.id);
71
- const leaderMailbox = store.getWorkMailbox({ kind: "role", taskId: task.id, roleName: "leader" });
72
- const pendingWakeup = pendingWakeupProjection(leaderMailbox);
73
- const reviewRounds = store.listReviewRounds(task.id);
74
- const changeSets = store.listChangeSets(task.id);
75
- const integrations = store.listIntegrationAttempts(task.id);
76
- const roleSessions = roles.flatMap((role) => {
77
- const session = store.getRoleSession(task.id, role.name);
78
- return session === null ? [] : [{ roleName: role.name, ...session }];
79
- });
80
- const providerRuns = new Map(roles.map((role) => [role.name, store.getTaskRoleSessionSet(task.id, role.name)?.providerBinding?.run]));
81
- const runDelivery = Object.fromEntries(runs.map((run) => {
82
- const native = providerRuns.get(run.roleName);
83
- return [run.id, native?.runId === run.id ? native.status : "unobserved"];
84
- }));
85
- const attention = collectAttention(task, runs, events, leaderFailure);
86
- const blockers = collectBlockers(workItems, openInputRequests, attention);
87
- const leader = {
88
- role: "leader",
89
- roleStatus: leaderRole === null
90
- ? "missing"
91
- : providerRuns.get("leader")?.status === "accepted" ? "running"
92
- : roleSessions.some((session) => session.roleName === "leader") ? "unknown" : "idle",
93
- summary: brief?.leaderSummary ?? null,
94
- currentFocus: brief?.currentFocus ?? null,
95
- updatedAt: brief?.updatedAt ?? null,
96
- updatedBy: brief?.updatedBy ?? null,
97
- summaryStatus: brief === null ? "missing" : "available"
98
- };
99
- const counts = countWorkItems(workItems);
100
- const runtimeRuns = runs
101
- .filter((run) => run.status === "active")
102
- .map((run) => ({
103
- id: run.id,
104
- roleName: run.roleName,
105
- status: run.status,
106
- runtime: runDelivery[run.id],
107
- createdAt: run.createdAt,
108
- updatedAt: run.updatedAt
109
- }));
110
- const runtime = {
111
- activeRuns: runtimeRuns,
112
- activeRunCount: runtimeRuns.length,
113
- pendingDeliveryCount: runtimeRuns.filter((run) => run.runtime !== "accepted").length
114
- };
115
- // Fold the execution projection from the facts already read above instead of
116
- // reading the store a second time for the same unchanged revision.
117
- const execution = projectTaskExecutionFromFacts({
118
- task,
119
- roles,
120
- runs,
121
- runDelivery,
122
- workItems,
123
- inputRequests,
124
- reviewRounds,
125
- changeSets,
126
- integrations,
127
- events,
128
- brief,
129
- pendingWakeup,
130
- leaderMailbox,
131
- leaderFailure,
132
- roleSessions,
133
- contextSnapshots: store.listContextSnapshots(task.id),
134
- now,
135
- runtimeHealthPolicy
136
- });
137
- const nextActionFacts = store.readNextActionFacts(task.id);
138
- if (nextActionFacts === null) {
139
- throw new Error(`Task disappeared while building its overview: ${task.id}.`);
140
- }
141
- const next = overviewNextAction(task, workItems, execution, projectNextAction({
142
- ...nextActionFacts,
143
- currentTaskReviewCandidate: null,
144
- executionGroups: execution.executionGroups
145
- }));
146
- const persistedCandidate = task.status === "active" || task.status === "cancelled"
147
- ? taskRemoteDeliveryCandidate(task)
148
- : null;
149
- const remoteDelivery = projectTaskRemoteDeliveryFromStore(store, task, persistedCandidate);
150
- return {
151
- ...task,
152
- brief,
153
- leader,
154
- leaderSummary: leader.summary,
155
- currentFocus: leader.currentFocus,
156
- summaryUpdatedAt: leader.updatedAt,
157
- summaryUpdatedBy: leader.updatedBy,
158
- summaryStatus: leader.summaryStatus,
159
- work: { counts, items: workItems },
160
- input: { open: openInputRequests, openCount: openInputRequests.length },
161
- attention,
162
- attentionCount: attention.length,
163
- blockers,
164
- next,
165
- nextAction: next?.action ?? null,
166
- nextOwner: next?.owner ?? null,
167
- runtime,
168
- execution,
169
- remoteDelivery
170
- };
171
- }
172
- function collectAttention(task, runs, events, failure) {
173
- const items = [];
174
- if (failure !== null) {
175
- items.push({
176
- kind: "leader-recovery",
177
- id: `leader-recovery:${task.id}`,
178
- status: "failed",
179
- owner: "operator",
180
- summary: failure.message,
181
- updatedAt: failure.lastFailedAt
182
- });
183
- }
184
- for (const run of runs) {
185
- if (run.roleName !== "leader"
186
- || run.status !== "active"
187
- || !isRoleRunStalled(events, run.id))
188
- continue;
189
- const progressAt = latestStallProgressAt(events, run.id) ?? run.updatedAt;
190
- items.push({
191
- kind: "leader-stalled",
192
- id: `leader-stall:${run.id}:${progressAt}`,
193
- status: "needs-attention",
194
- owner: "operator",
195
- summary: `AgentRun ${run.id} for ${run.roleName} has no durable progress after ${progressAt}.`,
196
- updatedAt: progressAt,
197
- runId: run.id,
198
- roleName: run.roleName
199
- });
200
- }
201
- return items.sort((left, right) => (Date.parse(left.updatedAt) - Date.parse(right.updatedAt)
202
- || left.id.localeCompare(right.id)));
203
- }
204
- function collectBlockers(workItems, openInputRequests, attention) {
205
- const blockers = [];
206
- const workById = new Map(workItems.map((item) => [item.id, item]));
207
- for (const item of workItems) {
208
- if ((item.status === "open" && item.currentCandidateId !== undefined)) {
209
- blockers.push({
210
- kind: "work",
211
- type: "work",
212
- id: item.id,
213
- status: item.status,
214
- owner: "leader",
215
- action: "accept-work-item",
216
- summary: `Work Item ${item.id} is awaiting Leader acceptance.`
217
- });
218
- continue;
219
- }
220
- if (item.status !== "open")
221
- continue;
222
- const dependencies = item.dependsOn.filter((dependency) => (workById.get(dependency)?.status !== "accepted"));
223
- if (dependencies.length === 0)
224
- continue;
225
- blockers.push({
226
- kind: "work",
227
- type: "work",
228
- id: item.id,
229
- status: item.status,
230
- owner: item.assignee ?? "leader",
231
- action: "unblock-work-item",
232
- summary: `Work Item ${item.id} is waiting on ${dependencies.join(", ")}.`
233
- });
234
- }
235
- for (const request of openInputRequests) {
236
- blockers.push({
237
- kind: "input",
238
- type: "input",
239
- id: request.id,
240
- status: request.status,
241
- owner: "user",
242
- action: "answer-input",
243
- summary: request.question,
244
- blockedRefs: request.blockedRefs
245
- });
246
- }
247
- for (const item of attention) {
248
- blockers.push({
249
- kind: "attention",
250
- type: "attention",
251
- id: item.id,
252
- status: item.status,
253
- owner: item.owner,
254
- action: item.kind === "leader-recovery"
255
- ? "inspect-leader-recovery"
256
- : "inspect-leader-stall",
257
- summary: item.summary
258
- });
259
- }
260
- return blockers;
261
- }
262
- function overviewNextAction(task, workItems, execution, action) {
263
- if (task.status !== "active" && task.status !== "draft")
264
- return null;
265
- const primary = action.refs[0];
266
- const workItem = action.refs
267
- .filter(({ kind }) => kind === "work-item")
268
- .map(({ id }) => workItems.find((item) => item.id === id))
269
- .find((item) => item !== undefined);
270
- const kind = primary?.kind === "input-request"
271
- ? "input"
272
- : primary?.kind === "work-item"
273
- ? "work"
274
- : action.kind.includes("attention") || action.kind.includes("inconsistency")
275
- ? "attention"
276
- : "execution";
277
- return {
278
- action: action.kind,
279
- owner: action.kind === "resolve-input"
280
- ? "user"
281
- : workItem?.assignee ?? execution.owner,
282
- kind,
283
- ...(primary === undefined ? {} : { id: primary.id }),
284
- summary: action.reason
285
- };
286
- }
287
- function countWorkItems(items) {
288
- const counts = {
289
- total: items.length,
290
- open: 0,
291
- accepted: 0,
292
- retired: 0
293
- };
294
- for (const item of items)
295
- counts[item.status] += 1;
296
- return counts;
297
- }
298
- function leaderCell(task) {
299
- const status = task.leader.roleStatus;
300
- if (task.leader.summaryStatus === "missing")
301
- return `${status} · missing summary`;
302
- const values = [task.leader.summary, task.leader.currentFocus]
303
- .filter((value) => value !== null && value.length > 0);
304
- return values.length === 0
305
- ? `${status} · summary unavailable`
306
- : compactText(`${status} · ${values.join(" · ")}`);
307
- }
308
- function workCell(counts) {
309
- if (counts.total === 0)
310
- return "none";
311
- const details = Object.keys(counts)
312
- .filter((status) => status !== "total" && counts[status] > 0)
313
- .map((status) => `${status}:${counts[status]}`);
314
- return `${counts.total} total${details.length === 0 ? "" : ` (${details.join(", ")})`}`;
315
- }
316
- function blockersCell(blockers) {
317
- if (blockers.length === 0)
318
- return "none";
319
- return blockers.map((blocker) => `${blocker.kind}:${blocker.id}`).join(", ");
320
- }
321
- function nextCell(next) {
322
- return next === null ? "—" : `${next.action} / ${next.owner}`;
323
- }
324
- function deliveryCell(delivery) {
325
- if (delivery.status === "none")
326
- return "none";
327
- return `${delivery.status} · ${delivery.mergedProjectCount}/${delivery.codeProjectCount} merged`
328
- + (delivery.allMerged
329
- ? ` · ${delivery.verifiedProjectCount}/${delivery.codeProjectCount} verified`
330
- : "");
331
- }
332
- function taskRemoteDeliveryCandidate(task) {
333
- const projects = task.projectBindings.flatMap(({ projectId, currentCommit }) => (currentCommit === undefined ? [] : [{ projectId, commit: currentCommit }]));
334
- return projects.length === task.projectBindings.length
335
- ? { projects }
336
- : null;
337
- }
338
- function compactText(value) {
339
- const oneLine = value.replace(/\s+/g, " ").trim();
340
- return oneLine.length <= 240 ? oneLine : `${oneLine.slice(0, 237)}...`;
341
- }
342
- function renderVerboseDetails(tasks, timeZone) {
343
- return [
344
- "Task details",
345
- ...tasks.flatMap((task) => [
346
- `${task.id}: ${task.title}`,
347
- ` Description: ${task.description ?? "—"}`,
348
- ` Current focus: ${task.currentFocus ?? "missing"}`,
349
- ` Leader summary: ${task.leaderSummary ?? "missing"}`,
350
- ` Summary updated by: ${task.summaryUpdatedBy ?? "unknown"}`,
351
- ` Summary updated at: ${task.summaryUpdatedAt === null
352
- ? "missing"
353
- : formatTimestamp(task.summaryUpdatedAt, timeZone)}`,
354
- ` Execution: ${task.execution.status} (${task.execution.owner}); ${task.execution.summary}`,
355
- ` Remote delivery: ${deliveryCell(task.remoteDelivery)}; source=${task.remoteDelivery.source}${task.remoteDelivery.provisional ? " (provisional)" : ""}`,
356
- ` Monitoring: ${task.execution.monitoring}; attention: ${task.execution.attention.length}`,
357
- ` DAG: ${task.execution.observability.dag.nodes.length} nodes, ${task.execution.observability.dag.edges.length} edges; ready=${task.execution.observability.dag.readyIds.join(", ") || "none"}; blocked=${task.execution.observability.dag.blockedIds.join(", ") || "none"}`,
358
- ` Cost: tokens=${task.execution.observability.cost.tokens}${task.execution.observability.cost.tokensObservable ? "" : " (partial)"}; tools=${task.execution.observability.cost.toolCalls}${task.execution.observability.cost.toolCallsObservable ? "" : " (partial)"}; wall=${task.execution.observability.cost.wallClockSeconds}s; retries=${task.execution.observability.cost.retryCount}`,
359
- ` Context: snapshots=${task.execution.observability.context.snapshotCount}; bytes=${task.execution.observability.context.totalBytes ?? "partial"}; compression=unavailable`,
360
- ` Session tokens: ${task.execution.observability.sessionTokens.length === 0
361
- ? "unobserved"
362
- : task.execution.observability.sessionTokens.map(({ roleName, metrics }) => {
363
- const total = metrics.cumulativeTotal.status === "observed"
364
- ? metrics.cumulativeTotal.totalTokens
365
- : "unobserved";
366
- const maximum = metrics.maximumRequestInput.status === "observed"
367
- ? metrics.maximumRequestInput.inputTokens
368
- : "unobserved";
369
- return `${roleName}: total=${total}, max-request-input=${maximum}`;
370
- }).join("; ")}`,
371
- ` Projects: ${task.projectBindings.length === 0
372
- ? "none"
373
- : task.projectBindings.map(({ directory, projectId, baseRef }) => (`${directory} (${projectId} @ ${baseRef})`)).join(", ")}`
374
- ])
375
- ].join("\n");
376
- }
@@ -1,125 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { usageError } from "../errors/cliError.js";
3
- import { installCompletion, uninstallCompletion } from "./completionInstaller.js";
4
- import { COMPLETION_SHELLS, activationBlock, activationIsAutomatic, currentCompletionShell, inspectCompletionStates, renderCompletionStateTable, shellQuote, suggestedCompletionInstallation } from "./completionState.js";
5
- export async function runCompletionWizard(operation, store, env, identity, question, options = {}) {
6
- const states = inspectCompletionStates(store.getConfig(), env, identity);
7
- const current = currentCompletionShell(env);
8
- let shell;
9
- if (options.shell === undefined) {
10
- const defaultSelection = options.defaultSelection ?? "current-shell";
11
- const defaultHint = defaultSelection === "skip"
12
- ? " [skip]"
13
- : current === undefined ? "" : ` [${current}]`;
14
- const skipHint = defaultSelection === "skip" ? "" : " (or skip)";
15
- const answer = await question(`${renderCompletionStateTable(states, options.width)}\n`
16
- + `Choose shell by number or name${defaultHint}${skipHint}: `);
17
- const normalized = answer.trim().toLowerCase();
18
- if (normalized === "skip" || (normalized.length === 0 && defaultSelection === "skip")) {
19
- return `Completion ${operation} skipped.\n`;
20
- }
21
- shell = parseSelection(answer, current);
22
- }
23
- else {
24
- shell = options.shell;
25
- }
26
- const state = states.find((candidate) => candidate.shell === shell);
27
- if (state === undefined)
28
- throw usageError("Completion shell selection is invalid.");
29
- if (operation === "uninstall") {
30
- if (state.installation === undefined) {
31
- return `Completion ${shell} is not installed.\n`;
32
- }
33
- const confirm = normalize(await question(`Remove managed ${shell} completion?\n`
34
- + `Script: ${state.installation.scriptPath}\n`
35
- + `Activation: ${state.installation.activationPath}\n`
36
- + "Remove now? [y/N]: "));
37
- if (confirm !== "y" && confirm !== "yes") {
38
- return `Completion ${shell} uninstall skipped.\n`;
39
- }
40
- uninstallCompletion(store, shell, identity);
41
- return `Completion ${shell} uninstalled.\n`;
42
- }
43
- const suggested = state.installation
44
- ?? suggestedCompletionInstallation(shell, env, identity);
45
- const automatic = activationIsAutomatic(shell, suggested, env, identity);
46
- const decision = normalize(await question(`Selected: ${shell} (${state.action})\n`
47
- + `Script: ${suggested.scriptPath}\n`
48
- + `Activation: ${suggested.activationPath}`
49
- + `${automatic ? " (automatic)" : " (managed startup block)"}\n`
50
- + "Install using these paths? [Y/n/customize]: "));
51
- if (decision === "n" || decision === "no") {
52
- return `Completion ${shell} installation skipped.\n`;
53
- }
54
- let installation = suggested;
55
- let customized = false;
56
- if (decision === "customize") {
57
- const scriptPath = resolve((await question(`Completion script path [${suggested.scriptPath}]: `)).trim()
58
- || suggested.scriptPath);
59
- const activationPath = resolve((await question(`Activation file path [${suggested.activationPath}]: `)).trim()
60
- || suggested.activationPath);
61
- installation = { scriptPath, activationPath };
62
- customized = true;
63
- }
64
- else if (decision !== "" && decision !== "y" && decision !== "yes") {
65
- throw usageError("Choose Y, n, or customize.");
66
- }
67
- const needsActivation = !activationIsAutomatic(shell, installation, env, identity);
68
- let activate = false;
69
- let activationReady = !needsActivation;
70
- if (needsActivation) {
71
- const activationAnswer = normalize(await question(`${activationBlock(shell, installation, identity)}\n`
72
- + `Update ${installation.activationPath} with the managed Yui block? [Y/n]: `));
73
- if (activationAnswer !== ""
74
- && activationAnswer !== "y"
75
- && activationAnswer !== "yes"
76
- && activationAnswer !== "n"
77
- && activationAnswer !== "no") {
78
- throw usageError("Choose Y or n.");
79
- }
80
- activate = activationAnswer === ""
81
- || activationAnswer === "y"
82
- || activationAnswer === "yes";
83
- activationReady = activate || (!customized && state.status === "Installed");
84
- }
85
- installCompletion(store, shell, installation, env, identity, activate);
86
- if (!activationReady) {
87
- return `Completion ${shell} script installed; activation still required.\n`;
88
- }
89
- const result = `Completion ${shell} ${pastTense(state.action)}.\n`;
90
- return needsActivation
91
- ? `${result}${activationGuidance(shell, installation, env, identity)}`
92
- : result;
93
- }
94
- function activationGuidance(shell, installation, env, identity) {
95
- const unchanged = "The current shell is unchanged.\n";
96
- const defaultActivationPath = suggestedCompletionInstallation(shell, env, identity).activationPath;
97
- if (installation.activationPath !== defaultActivationPath) {
98
- return `${unchanged}From a ${shell} session, load the custom activation file: source ${shellQuote(installation.activationPath)}\n`;
99
- }
100
- return currentCompletionShell(env) === shell
101
- ? `${unchanged}Restart the current shell to activate completion: exec ${shell}\n`
102
- : `${unchanged}Switch this terminal to ${shell} to activate completion: exec ${shell}\n`;
103
- }
104
- function parseSelection(value, current) {
105
- const normalized = value.trim().toLowerCase();
106
- if (normalized.length === 0 && current !== undefined)
107
- return current;
108
- if (/^[1-3]$/.test(normalized)) {
109
- return COMPLETION_SHELLS[Number.parseInt(normalized, 10) - 1];
110
- }
111
- if (COMPLETION_SHELLS.includes(normalized)) {
112
- return normalized;
113
- }
114
- throw usageError("Choose Bash, Zsh, or Fish by number or name.");
115
- }
116
- function pastTense(action) {
117
- switch (action) {
118
- case "Install": return "installed";
119
- case "Refresh": return "refreshed";
120
- case "Repair": return "repaired";
121
- }
122
- }
123
- function normalize(value) {
124
- return value?.trim().toLowerCase() ?? "";
125
- }
@@ -1,110 +0,0 @@
1
- export function buildRoleContext(context) {
2
- return context.role.name === "leader"
3
- ? buildLeaderContext(context)
4
- : buildWorkerContext(context);
5
- }
6
- export function buildLeaderContext(context) {
7
- return renderDispatchContext("leader", context);
8
- }
9
- export function buildWorkerContext(context) {
10
- return renderDispatchContext("worker", context);
11
- }
12
- const WORKER_RUN_COMPLETION_MARKER = "Yui Role AgentRun result requirement:";
13
- const WORKER_RUN_COMPLETION_REQUIREMENT = [
14
- WORKER_RUN_COMPLETION_MARKER,
15
- "End the Provider turn with a truthful final report. Yui records that native turn result "
16
- + "for the current AgentRun automatically; no completion command is required.",
17
- "If you cannot finally determine success, failure, completeness, or the correct "
18
- + "disposition, do not guess, silently stop, or hide uncertainty behind a success "
19
- + "summary. Label the final report uncertain, incomplete, "
20
- + "blocked, or requiring Leader judgment.",
21
- "Report the most complete truthful evidence available and, when applicable: exact AgentRun, "
22
- + "WorkItem, and native Session identity; actions actually performed; changed paths "
23
- + "and commit/worktree state; checks actually run and their outcomes; provider, runtime, "
24
- + "or permission errors; the last confirmed lifecycle boundary; work not performed; "
25
- + "unresolved assumptions or decisions; residual risks; confidence; and bounded next options.",
26
- "The Provider turn ending closes only this AgentRun. It does not imply Leader acceptance, "
27
- + "WorkItem completion, ChangeSet capture, Integration, or Task completion. Review AgentRuns "
28
- + "report findings, verification gaps, and limits; the Leader decides disposition."
29
- ].join("\n");
30
- export function ensureWorkerRunCompletionRequirement(input) {
31
- return input.endsWith(`\n\n${WORKER_RUN_COMPLETION_REQUIREMENT}`)
32
- ? input
33
- : `${input}\n\n${WORKER_RUN_COMPLETION_REQUIREMENT}`;
34
- }
35
- function renderDispatchContext(kind, context) {
36
- const profile = context.role;
37
- const binding = profile.agentBindings[profile.activeAgentId];
38
- const profileLines = [
39
- `Task: ${context.taskId}`,
40
- `Role: ${profile.name}`,
41
- `Active Agent: ${profile.activeAgentId}`,
42
- `Runtime: ${binding.adapterId}; model: ${binding.config.model ?? "CLI default"}; effort: ${binding.config.effort ?? "CLI default"}; permission: ${binding.config.permission.strategy}`,
43
- profile.description === undefined ? null : `Description: ${profile.description}`,
44
- ...(profile.responsibilities ?? []).map((item) => `Responsibility: ${item}`),
45
- ...(profile.constraints ?? []).map((item) => `Constraint: ${item}`),
46
- profile.expectedOutput === undefined ? null : `Expected output: ${profile.expectedOutput}`
47
- ].filter((line) => line !== null);
48
- const workLines = kind === "worker"
49
- ? renderWorkerScope(context)
50
- : [];
51
- const rendered = [
52
- `Follow the injected yui-${kind} Skill for this Yui dispatch.`,
53
- renderContextLayers(context, kind),
54
- profileLines.join("\n"),
55
- workLines.length === 0 ? null : workLines.join("\n"),
56
- "Yui dispatch:",
57
- requireText(context.input, "dispatch input")
58
- ].filter((section) => section !== null && section.length > 0)
59
- .join("\n\n");
60
- return kind === "worker"
61
- ? ensureWorkerRunCompletionRequirement(rendered)
62
- : rendered;
63
- }
64
- function renderContextLayers(context, kind) {
65
- const projects = context.projectPolicy ?? [];
66
- const policyLines = projects.length === 0
67
- ? ["- none (this Task is not Project-backed)"]
68
- : projects.map(({ projectId, directory }) => {
69
- const label = directory === undefined ? projectId : `${directory} (${projectId})`;
70
- return `- ${label}: \`yui project show ${projectId}\`; then \`yui project knowledge list ${projectId}\` and show the relevant entries`;
71
- });
72
- return [
73
- "Context layers:",
74
- "- Yui Core: durable identity, lifecycle, access, workspace, and exact handoff safety.",
75
- `- Generic ${kind} Skill: reusable role behavior and evidence discipline.`,
76
- "- Project Policy: project-owned build, test, migration, release, and review rules; it is not a Yui Core default.",
77
- ...["Project Policy references:", ...policyLines],
78
- "- Task Contract: the current Task brief, WorkItem objective, acceptance criteria, and dispatch input.",
79
- "Do not import rules from another Project or Task, and do not infer Project Policy from repository files alone."
80
- ].join("\n");
81
- }
82
- function renderWorkerScope(context) {
83
- if (context.workItem === undefined || context.workspace === undefined)
84
- return [];
85
- const writable = context.workspace.entries.filter(({ access }) => access === "write");
86
- const contextOnly = context.workspace.entries.filter(({ access }) => access === "read");
87
- const projectLines = (label, entries) => [
88
- `${label}:`,
89
- ...(entries.length === 0
90
- ? ["- none"]
91
- : entries.map(({ directory, projectId }) => `- ${directory} (${projectId})`))
92
- ];
93
- return [
94
- `WorkItem: ${context.workItem.id}`,
95
- `Workspace root: ${context.workspace.root}`,
96
- ...projectLines("Writable Projects", writable),
97
- ...projectLines("Context-only Projects", contextOnly),
98
- `Read the full Task state with \`yui task context ${context.taskId}\`.`,
99
- `Read the current WorkItem scope with \`yui task work list ${context.taskId}\`.`,
100
- "Modify only Writable Projects. If another Project must change, stop and ask "
101
- + "the Task Leader to expand this WorkItem scope before continuing."
102
- ];
103
- }
104
- function requireText(value, label) {
105
- const normalized = value.trim();
106
- if (normalized.length === 0 || normalized.includes("\0")) {
107
- throw new Error(`${label} is required.`);
108
- }
109
- return normalized;
110
- }