@pellux/goodvibes-agent 1.1.7 → 1.3.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 (274) hide show
  1. package/CHANGELOG.md +329 -0
  2. package/README.md +46 -30
  3. package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
  4. package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
  5. package/dist/package/main.js +138903 -91477
  6. package/docs/README.md +14 -7
  7. package/docs/channels-remote-and-api.md +8 -5
  8. package/docs/connected-host.md +14 -12
  9. package/docs/getting-started.md +58 -30
  10. package/docs/knowledge-artifacts-and-multimodal.md +7 -5
  11. package/docs/project-planning.md +2 -2
  12. package/docs/providers-and-routing.md +11 -3
  13. package/docs/tools-and-commands.md +116 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +142 -5
  17. package/release/release-readiness.json +124 -94
  18. package/src/agent/assistant-cockpit.ts +247 -0
  19. package/src/agent/autonomy-schedule-format.ts +96 -0
  20. package/src/agent/autonomy-schedule.ts +514 -0
  21. package/src/agent/channel-delivery-receipts.ts +292 -0
  22. package/src/agent/competitive-feature-inventory.ts +294 -0
  23. package/src/agent/document-registry-types.ts +106 -0
  24. package/src/agent/document-registry.ts +734 -0
  25. package/src/agent/harness-control.ts +2 -2
  26. package/src/agent/memory-prompt.ts +2 -2
  27. package/src/agent/operator-actions.ts +50 -6
  28. package/src/agent/persona-registry.ts +8 -0
  29. package/src/agent/project-context-files.ts +273 -0
  30. package/src/agent/prompt-context-receipts.ts +502 -0
  31. package/src/agent/reminder-schedule-format.ts +16 -2
  32. package/src/agent/research-run-registry.ts +582 -0
  33. package/src/agent/research-source-registry.ts +441 -0
  34. package/src/agent/routine-registry.ts +19 -3
  35. package/src/agent/routine-schedule-format.ts +27 -2
  36. package/src/agent/runtime-profile-starters.ts +7 -0
  37. package/src/agent/runtime-profile.ts +106 -4
  38. package/src/agent/schedule-edit-format.ts +129 -0
  39. package/src/agent/schedule-edit.ts +496 -0
  40. package/src/agent/schedule-next-routes.ts +42 -0
  41. package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
  42. package/src/agent/setup-wizard-checkpoint.ts +140 -0
  43. package/src/agent/setup-wizard.ts +683 -0
  44. package/src/agent/skill-registry-types.ts +102 -0
  45. package/src/agent/skill-registry.ts +81 -107
  46. package/src/agent/vibe-confirmation-routes.ts +62 -0
  47. package/src/agent/vibe-file.ts +285 -0
  48. package/src/cli/agent-knowledge-command.ts +45 -2
  49. package/src/cli/help.ts +3 -0
  50. package/src/cli/profiles-command.ts +25 -11
  51. package/src/config/agent-settings-policy.ts +1 -18
  52. package/src/input/agent-workspace-activation.ts +53 -0
  53. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  54. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  55. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  56. package/src/input/agent-workspace-categories.ts +153 -155
  57. package/src/input/agent-workspace-channel-triage.ts +481 -0
  58. package/src/input/agent-workspace-channels.ts +263 -0
  59. package/src/input/agent-workspace-command-editor.ts +152 -0
  60. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  61. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  62. package/src/input/agent-workspace-document-editor.ts +502 -0
  63. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  64. package/src/input/agent-workspace-host-category.ts +1 -1
  65. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  66. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  67. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  68. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  69. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  70. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  71. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  72. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  73. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  74. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  75. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  76. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  77. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  78. package/src/input/agent-workspace-settings.ts +313 -30
  79. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  80. package/src/input/agent-workspace-setup-snapshot.ts +217 -0
  81. package/src/input/agent-workspace-setup.ts +61 -1
  82. package/src/input/agent-workspace-snapshot.ts +184 -149
  83. package/src/input/agent-workspace-types.ts +287 -2
  84. package/src/input/agent-workspace.ts +23 -1
  85. package/src/input/command-registry.ts +9 -2
  86. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  87. package/src/input/commands/channels-runtime.ts +102 -114
  88. package/src/input/commands/delegation-runtime.ts +87 -24
  89. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  90. package/src/input/commands/knowledge.ts +28 -14
  91. package/src/input/commands/operator-actions-runtime.ts +6 -3
  92. package/src/input/commands/schedule-runtime.ts +71 -14
  93. package/src/input/commands/session-content.ts +2 -2
  94. package/src/input/commands/shell-core.ts +2 -0
  95. package/src/input/commands/vibe-runtime.ts +140 -0
  96. package/src/input/commands.ts +2 -0
  97. package/src/input/connected-host-routes.ts +123 -0
  98. package/src/input/settings-modal-types.ts +14 -0
  99. package/src/input/setup-wizard-live-receipts.ts +76 -0
  100. package/src/main.ts +15 -15
  101. package/src/panels/qr-panel.ts +2 -2
  102. package/src/renderer/agent-workspace-context-lines.ts +701 -0
  103. package/src/renderer/agent-workspace.ts +68 -421
  104. package/src/renderer/settings-modal-helpers.ts +12 -0
  105. package/src/renderer/settings-modal.ts +12 -0
  106. package/src/runtime/bootstrap-command-context.ts +11 -1
  107. package/src/runtime/bootstrap-command-parts.ts +14 -3
  108. package/src/runtime/bootstrap-core.ts +39 -1
  109. package/src/runtime/bootstrap-shell.ts +6 -0
  110. package/src/runtime/bootstrap.ts +113 -30
  111. package/src/runtime/connected-host-auth.ts +3 -2
  112. package/src/runtime/execution-ledger.ts +231 -0
  113. package/src/runtime/services.ts +88 -10
  114. package/src/runtime/tool-permission-safety.ts +199 -5
  115. package/src/shell/session-continuity-hints.ts +39 -0
  116. package/src/tools/agent-artifacts-tool.ts +606 -0
  117. package/src/tools/agent-audit-tool.ts +155 -0
  118. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  119. package/src/tools/agent-autonomy-tool.ts +140 -0
  120. package/src/tools/agent-channel-send-tool.ts +24 -2
  121. package/src/tools/agent-channels-tool.ts +140 -0
  122. package/src/tools/agent-computer-tool.ts +168 -0
  123. package/src/tools/agent-context-policy.ts +137 -7
  124. package/src/tools/agent-context-tool.ts +143 -0
  125. package/src/tools/agent-delegation-tool.ts +128 -0
  126. package/src/tools/agent-device-tool.ts +240 -0
  127. package/src/tools/agent-documents-tool.ts +684 -0
  128. package/src/tools/agent-execution-tool.ts +230 -0
  129. package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
  130. package/src/tools/agent-harness-agent-orchestration.ts +791 -0
  131. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  132. package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
  133. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  134. package/src/tools/agent-harness-autonomy-queue.ts +571 -0
  135. package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
  136. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  137. package/src/tools/agent-harness-background-processes.ts +798 -0
  138. package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
  139. package/src/tools/agent-harness-browser-control.ts +346 -0
  140. package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
  141. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  142. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  143. package/src/tools/agent-harness-command-catalog.ts +4 -2
  144. package/src/tools/agent-harness-command-runner.ts +42 -0
  145. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  146. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  147. package/src/tools/agent-harness-device-live-read-models.ts +366 -0
  148. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  149. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  150. package/src/tools/agent-harness-document-ops.ts +671 -0
  151. package/src/tools/agent-harness-execution-history.ts +489 -0
  152. package/src/tools/agent-harness-execution-posture.ts +385 -0
  153. package/src/tools/agent-harness-file-recovery.ts +135 -0
  154. package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
  155. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  156. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  157. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  158. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  159. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  160. package/src/tools/agent-harness-learning-curator.ts +417 -0
  161. package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
  162. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  163. package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
  164. package/src/tools/agent-harness-local-model-smoke.ts +277 -0
  165. package/src/tools/agent-harness-local-model-url.ts +78 -0
  166. package/src/tools/agent-harness-media-posture.ts +223 -2
  167. package/src/tools/agent-harness-memory-external-providers.ts +796 -0
  168. package/src/tools/agent-harness-memory-posture.ts +672 -0
  169. package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
  170. package/src/tools/agent-harness-memory-refinement.ts +340 -0
  171. package/src/tools/agent-harness-metadata.ts +100 -168
  172. package/src/tools/agent-harness-mode-catalog.ts +86 -33
  173. package/src/tools/agent-harness-model-catalog.ts +162 -0
  174. package/src/tools/agent-harness-model-provider-health.ts +283 -0
  175. package/src/tools/agent-harness-model-readiness.ts +432 -0
  176. package/src/tools/agent-harness-model-routing-types.ts +327 -0
  177. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  178. package/src/tools/agent-harness-model-routing.ts +165 -193
  179. package/src/tools/agent-harness-operator-methods.ts +115 -133
  180. package/src/tools/agent-harness-pairing-posture.ts +452 -18
  181. package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
  182. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  183. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  184. package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
  185. package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
  186. package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
  187. package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
  188. package/src/tools/agent-harness-personal-ops-records.ts +684 -0
  189. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  190. package/src/tools/agent-harness-personal-ops-types.ts +240 -0
  191. package/src/tools/agent-harness-personal-ops.ts +613 -0
  192. package/src/tools/agent-harness-project-context.ts +144 -0
  193. package/src/tools/agent-harness-prompt-context.ts +589 -0
  194. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  195. package/src/tools/agent-harness-release-evidence.ts +9 -7
  196. package/src/tools/agent-harness-release-readiness.ts +9 -7
  197. package/src/tools/agent-harness-remote-read-models.ts +541 -0
  198. package/src/tools/agent-harness-research-briefing.ts +446 -0
  199. package/src/tools/agent-harness-research-live-read-models.ts +500 -0
  200. package/src/tools/agent-harness-research-queue.ts +250 -0
  201. package/src/tools/agent-harness-research-runs.ts +307 -0
  202. package/src/tools/agent-harness-research-workflow.ts +395 -0
  203. package/src/tools/agent-harness-security-posture.ts +2 -2
  204. package/src/tools/agent-harness-service-posture.ts +9 -9
  205. package/src/tools/agent-harness-session-metadata.ts +3 -3
  206. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  207. package/src/tools/agent-harness-setup-describe.ts +557 -0
  208. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  209. package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
  210. package/src/tools/agent-harness-setup-plan.ts +253 -0
  211. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  212. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  213. package/src/tools/agent-harness-setup-posture.ts +449 -221
  214. package/src/tools/agent-harness-setup-smoke.ts +533 -0
  215. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  216. package/src/tools/agent-harness-tool-schema.ts +142 -7
  217. package/src/tools/agent-harness-tool-types.ts +83 -0
  218. package/src/tools/agent-harness-tool-utils.ts +43 -0
  219. package/src/tools/agent-harness-tool.ts +319 -370
  220. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  221. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  222. package/src/tools/agent-harness-vibe-health.ts +105 -0
  223. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  224. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  225. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  226. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  227. package/src/tools/agent-host-tool.ts +159 -0
  228. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  229. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  230. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  231. package/src/tools/agent-memory-tool.ts +253 -0
  232. package/src/tools/agent-model-compare-export.ts +315 -0
  233. package/src/tools/agent-model-compare-handoff.ts +592 -0
  234. package/src/tools/agent-model-compare-judgment.ts +633 -0
  235. package/src/tools/agent-model-compare-run.ts +735 -0
  236. package/src/tools/agent-model-compare-tool.ts +698 -0
  237. package/src/tools/agent-model-compare-types.ts +191 -0
  238. package/src/tools/agent-model-compare-utils.ts +93 -0
  239. package/src/tools/agent-models-tool.ts +208 -0
  240. package/src/tools/agent-operator-action-tool.ts +1 -1
  241. package/src/tools/agent-operator-method-tool.ts +643 -0
  242. package/src/tools/agent-personal-ops-tool.ts +197 -0
  243. package/src/tools/agent-policy-explanation.ts +415 -0
  244. package/src/tools/agent-research-report-tool.ts +608 -0
  245. package/src/tools/agent-research-runner.ts +367 -0
  246. package/src/tools/agent-research-runs-tool.ts +434 -0
  247. package/src/tools/agent-research-sources-tool.ts +443 -0
  248. package/src/tools/agent-research-tool.ts +515 -0
  249. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  250. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  251. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  252. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  253. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  254. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  255. package/src/tools/agent-route-planner-helpers.ts +667 -0
  256. package/src/tools/agent-route-planner.ts +185 -0
  257. package/src/tools/agent-route-tool.ts +105 -0
  258. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  259. package/src/tools/agent-schedule-tool.ts +282 -0
  260. package/src/tools/agent-security-tool.ts +145 -0
  261. package/src/tools/agent-sessions-tool.ts +122 -0
  262. package/src/tools/agent-settings-import-tool.ts +104 -0
  263. package/src/tools/agent-settings-tool.ts +176 -0
  264. package/src/tools/agent-setup-tool.ts +226 -0
  265. package/src/tools/agent-support-tool.ts +122 -0
  266. package/src/tools/agent-terminal-process-tools.ts +167 -0
  267. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  268. package/src/tools/agent-tool-policy-guard.ts +106 -85
  269. package/src/tools/agent-vibe-tool.ts +297 -0
  270. package/src/tools/agent-work-plan-tool.ts +265 -6
  271. package/src/tools/agent-workspace-tool.ts +305 -0
  272. package/src/tools/artifact-archive.ts +169 -0
  273. package/src/tools/tool-definition-compaction.ts +36 -0
  274. package/src/version.ts +1 -1
@@ -0,0 +1,88 @@
1
+ export type AutonomyQueueStatus = 'ready' | 'active' | 'needs-setup' | 'attention' | 'blocked';
2
+
3
+ export interface AgentHarnessAutonomyQueueArgs {
4
+ readonly queueItemId?: unknown;
5
+ readonly target?: unknown;
6
+ readonly query?: unknown;
7
+ readonly includeParameters?: unknown;
8
+ readonly limit?: unknown;
9
+ }
10
+
11
+ export interface OperatorContractMethod {
12
+ readonly id: string;
13
+ readonly title?: string;
14
+ readonly description?: string;
15
+ readonly category?: string;
16
+ readonly http?: {
17
+ readonly method?: string;
18
+ readonly path?: string;
19
+ };
20
+ }
21
+
22
+ export interface AutonomyQueueItem {
23
+ readonly id: string;
24
+ readonly label: string;
25
+ readonly status: AutonomyQueueStatus;
26
+ readonly owner: 'agent' | 'connected-host' | 'agent-and-connected-host';
27
+ readonly kind: 'work-plan' | 'research-run' | 'host-task' | 'approval' | 'automation-run' | 'schedule' | 'reminder' | 'routine-schedule' | 'delegated-agent' | 'delivery';
28
+ readonly visible: true;
29
+ readonly cancellable: boolean;
30
+ readonly count: number;
31
+ readonly current: string;
32
+ readonly next: string;
33
+ readonly inspectRoute: string;
34
+ readonly modelRoute: string;
35
+ readonly cancelRoute?: string;
36
+ readonly createRoute?: string;
37
+ readonly batchCreateRoute?: string;
38
+ readonly methodIds?: readonly string[];
39
+ readonly liveRecords?: readonly AutonomyQueueLiveRecord[];
40
+ }
41
+
42
+ export interface AutonomyQueueLiveRecord {
43
+ readonly id: string;
44
+ readonly label: string;
45
+ readonly status: string;
46
+ readonly phase?: string;
47
+ readonly progress?: number;
48
+ readonly updatedAt?: string;
49
+ readonly summary: string;
50
+ readonly inspectRoute: string;
51
+ readonly cancelRoute?: string;
52
+ readonly checkpointRoute?: string;
53
+ readonly pauseRoute?: string;
54
+ readonly resumeRoute?: string;
55
+ readonly nextSteps?: readonly string[];
56
+ readonly sourceIds?: readonly string[];
57
+ readonly logTail?: readonly string[];
58
+ readonly output?: AutonomyQueueRecordOutput;
59
+ readonly diagnostics?: readonly string[];
60
+ readonly controls?: readonly AutonomyQueueRecordControl[];
61
+ }
62
+
63
+ export interface AutonomyQueueRecordOutput {
64
+ readonly status: 'preview' | 'route-only';
65
+ readonly route: string;
66
+ readonly source: 'runtime-task-result' | 'runtime-task-error' | 'host-output-chunk' | 'provider-source-preview' | 'not-published';
67
+ readonly preview?: string;
68
+ readonly policy: string;
69
+ }
70
+
71
+ export interface AutonomyQueueRecordControl {
72
+ readonly id: string;
73
+ readonly label: string;
74
+ readonly state: 'available' | 'unavailable';
75
+ readonly effect: 'read-only' | 'confirmed-effect';
76
+ readonly confirmationRequired: boolean;
77
+ readonly modelRoute?: string;
78
+ readonly reason?: string;
79
+ }
80
+
81
+ export type SnapshotReader<TSnapshot> = {
82
+ readonly getSnapshot: () => TSnapshot;
83
+ };
84
+
85
+ export type AutonomyQueueResolution =
86
+ | { readonly status: 'found'; readonly item: Record<string, unknown> }
87
+ | { readonly status: 'ambiguous'; readonly input: string; readonly candidates: readonly Record<string, unknown>[] }
88
+ | { readonly status: 'missing_lookup'; readonly usage: string };
@@ -0,0 +1,571 @@
1
+ import { getOperatorContract } from '@pellux/goodvibes-sdk/contracts';
2
+ import type { CommandContext } from '../input/command-registry.ts';
3
+ import { buildAgentWorkspaceRuntimeSnapshot } from '../input/agent-workspace-snapshot.ts';
4
+ import { automationRunLiveRecords, approvalLiveRecords, controlAvailable, firstAvailableControlRoute, researchRunLiveRecords, scheduleLiveRecords, taskLiveRecords, watcherReceiptLiveRecords } from './agent-harness-autonomy-live-records.ts';
5
+ import { watcherReadModelLiveRecords } from './agent-harness-autonomy-watcher-read-models.ts';
6
+ import type { AgentHarnessAutonomyQueueArgs, AutonomyQueueItem, AutonomyQueueLiveRecord, AutonomyQueueRecordControl, AutonomyQueueRecordOutput, AutonomyQueueResolution, AutonomyQueueStatus, OperatorContractMethod } from './agent-harness-autonomy-queue-types.ts';
7
+ export type { AutonomyQueueResolution } from './agent-harness-autonomy-queue-types.ts';
8
+ import { previewHarnessText } from './agent-harness-text.ts';
9
+
10
+ function readString(value: unknown): string {
11
+ return typeof value === 'string' ? value.trim() : '';
12
+ }
13
+
14
+ function readLimit(value: unknown, fallback: number): number {
15
+ const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
16
+ if (typeof parsed !== 'number' || !Number.isFinite(parsed)) return fallback;
17
+ return Math.max(1, Math.min(200, Math.trunc(parsed)));
18
+ }
19
+
20
+ function operatorContractMethods(): readonly OperatorContractMethod[] {
21
+ const contract = getOperatorContract();
22
+ const methods = Array.isArray(contract.operator?.methods)
23
+ ? contract.operator.methods as OperatorContractMethod[]
24
+ : [];
25
+ return methods.filter((method) => method.id);
26
+ }
27
+
28
+ function methodSearchText(method: OperatorContractMethod): string {
29
+ return [
30
+ method.id,
31
+ method.title,
32
+ method.description,
33
+ method.category,
34
+ method.http?.method,
35
+ method.http?.path,
36
+ ].filter(Boolean).join('\n').toLowerCase();
37
+ }
38
+
39
+ function methodIdsMatching(tokens: readonly string[]): readonly string[] {
40
+ if (tokens.length === 0) return [];
41
+ return operatorContractMethods()
42
+ .filter((method) => {
43
+ const text = methodSearchText(method);
44
+ return tokens.some((token) => text.includes(token));
45
+ })
46
+ .map((method) => method.id)
47
+ .sort((left, right) => left.localeCompare(right));
48
+ }
49
+
50
+ function statusRank(status: AutonomyQueueStatus): number {
51
+ if (status === 'attention') return 5;
52
+ if (status === 'active') return 4;
53
+ if (status === 'needs-setup') return 3;
54
+ if (status === 'ready') return 2;
55
+ return 1;
56
+ }
57
+
58
+ function itemSearchText(item: AutonomyQueueItem): string {
59
+ return [
60
+ item.id,
61
+ item.label,
62
+ item.status,
63
+ item.owner,
64
+ item.kind,
65
+ item.current,
66
+ item.next,
67
+ item.inspectRoute,
68
+ item.modelRoute,
69
+ item.cancelRoute ?? '',
70
+ item.createRoute ?? '',
71
+ item.batchCreateRoute ?? '',
72
+ item.methodIds?.join('\n') ?? '',
73
+ item.liveRecords?.flatMap((record) => [
74
+ record.id,
75
+ record.label,
76
+ record.status,
77
+ record.phase ?? '',
78
+ record.summary,
79
+ record.inspectRoute,
80
+ record.cancelRoute ?? '',
81
+ record.checkpointRoute ?? '',
82
+ record.pauseRoute ?? '',
83
+ record.resumeRoute ?? '',
84
+ record.nextSteps?.join('\n') ?? '',
85
+ record.sourceIds?.join('\n') ?? '',
86
+ record.logTail?.join('\n') ?? '',
87
+ record.output ? [
88
+ record.output.status,
89
+ record.output.route,
90
+ record.output.source,
91
+ record.output.preview ?? '',
92
+ record.output.policy,
93
+ ].join('\n') : '',
94
+ record.diagnostics?.join('\n') ?? '',
95
+ record.controls?.map((control) => [
96
+ control.id,
97
+ control.label,
98
+ control.state,
99
+ control.effect,
100
+ control.modelRoute ?? '',
101
+ control.reason ?? '',
102
+ ].join(' ')).join('\n') ?? '',
103
+ ]).join('\n') ?? '',
104
+ ].join('\n').toLowerCase();
105
+ }
106
+
107
+ function describeControl(control: AutonomyQueueRecordControl): Record<string, unknown> {
108
+ return {
109
+ id: control.id,
110
+ label: control.label,
111
+ state: control.state,
112
+ effect: control.effect,
113
+ confirmationRequired: control.confirmationRequired,
114
+ ...(control.modelRoute ? { modelRoute: control.modelRoute } : {}),
115
+ ...(control.reason ? { reason: previewHarnessText(control.reason, 120) } : {}),
116
+ };
117
+ }
118
+
119
+ function describeOutput(output: AutonomyQueueRecordOutput, includeParameters: boolean): Record<string, unknown> {
120
+ return {
121
+ status: output.status,
122
+ route: output.route,
123
+ source: output.source,
124
+ ...(output.preview ? { preview: previewHarnessText(output.preview, includeParameters ? 220 : 96) } : {}),
125
+ policy: previewHarnessText(output.policy, includeParameters ? 180 : 96),
126
+ };
127
+ }
128
+
129
+ function describeLiveRecord(record: AutonomyQueueLiveRecord, includeParameters: boolean): Record<string, unknown> {
130
+ const availableControls = record.controls
131
+ ?.filter((control) => control.state === 'available')
132
+ .map((control) => control.id);
133
+ return {
134
+ id: record.id,
135
+ label: record.label,
136
+ status: record.status,
137
+ ...(record.phase ? { phase: record.phase } : {}),
138
+ ...(typeof record.progress === 'number' ? { progress: record.progress } : {}),
139
+ ...(record.updatedAt ? { updatedAt: record.updatedAt } : {}),
140
+ summary: previewHarnessText(record.summary, includeParameters ? 180 : 96),
141
+ inspectRoute: record.inspectRoute,
142
+ ...(record.cancelRoute ? { cancelRoute: record.cancelRoute } : {}),
143
+ ...(record.checkpointRoute ? { checkpointRoute: record.checkpointRoute } : {}),
144
+ ...(record.pauseRoute ? { pauseRoute: record.pauseRoute } : {}),
145
+ ...(record.resumeRoute ? { resumeRoute: record.resumeRoute } : {}),
146
+ ...(record.nextSteps && record.nextSteps.length > 0 ? { nextSteps: record.nextSteps.slice(0, includeParameters ? 8 : 3) } : {}),
147
+ ...(record.sourceIds && record.sourceIds.length > 0 ? { sourceIds: record.sourceIds.slice(0, includeParameters ? 12 : 4) } : {}),
148
+ ...(record.logTail && record.logTail.length > 0 ? { logTail: record.logTail.slice(-(includeParameters ? 5 : 2)) } : {}),
149
+ ...(record.output ? { output: describeOutput(record.output, includeParameters) } : {}),
150
+ ...(record.diagnostics && record.diagnostics.length > 0 ? { diagnostics: record.diagnostics.slice(0, includeParameters ? 10 : 3).map((line) => previewHarnessText(line, includeParameters ? 160 : 96)) } : {}),
151
+ ...(availableControls && availableControls.length > 0 ? { availableControls: availableControls.slice(0, includeParameters ? 8 : 4) } : {}),
152
+ ...(includeParameters && record.controls && record.controls.length > 0 ? { controls: record.controls.map(describeControl) } : {}),
153
+ };
154
+ }
155
+
156
+ function describeItem(item: AutonomyQueueItem, includeParameters: boolean, lookup?: Record<string, unknown>): Record<string, unknown> {
157
+ return {
158
+ queueItemId: item.id,
159
+ label: item.label,
160
+ status: item.status,
161
+ owner: item.owner,
162
+ kind: item.kind,
163
+ visible: item.visible,
164
+ cancellable: item.cancellable,
165
+ count: item.count,
166
+ current: previewHarnessText(item.current, includeParameters ? 180 : 96),
167
+ next: previewHarnessText(item.next, includeParameters ? 180 : 96),
168
+ modelRoute: item.modelRoute,
169
+ inspectRoute: item.inspectRoute,
170
+ ...(item.cancelRoute ? { cancelRoute: item.cancelRoute } : {}),
171
+ ...(item.createRoute ? { createRoute: item.createRoute } : {}),
172
+ ...(item.batchCreateRoute ? { batchCreateRoute: item.batchCreateRoute } : {}),
173
+ ...(item.liveRecords && item.liveRecords.length > 0 ? { liveRecords: item.liveRecords.slice(0, includeParameters ? 8 : 3).map((record) => describeLiveRecord(record, includeParameters)) } : {}),
174
+ ...(lookup ? { lookup } : {}),
175
+ ...(includeParameters ? {
176
+ routes: {
177
+ inspect: item.inspectRoute,
178
+ model: item.modelRoute,
179
+ cancel: item.cancelRoute ?? null,
180
+ create: item.createRoute ?? null,
181
+ batchCreate: item.batchCreateRoute ?? null,
182
+ },
183
+ methodIds: item.methodIds ?? [],
184
+ policy: 'Queue rows are read-only. Create, run, pause, resume, cancel, approve, deny, send, and schedule effects stay on their owning confirmed route.',
185
+ } : {}),
186
+ };
187
+ }
188
+
189
+ function buildQueueItems(context: CommandContext): readonly AutonomyQueueItem[] {
190
+ const snapshot = buildAgentWorkspaceRuntimeSnapshot(context);
191
+ const approvalMethods = methodIdsMatching(['approval']);
192
+ const automationMethods = methodIdsMatching(['automation']);
193
+ const scheduleMethods = methodIdsMatching(['schedule', 'reminder']);
194
+ const taskMethods = methodIdsMatching(['task', 'work-plan', 'workplan']);
195
+ const readyChannels = snapshot.channels.filter((channel) => channel.ready).length;
196
+ const configuredTargets = snapshot.channels.filter((channel) => channel.defaultTarget === 'configured').length;
197
+ const researchRuns = researchRunLiveRecords(snapshot);
198
+ const taskRecords = taskLiveRecords(context);
199
+ const approvalRecords = approvalLiveRecords(context);
200
+ const automationReadModelRecords = automationRunLiveRecords(context);
201
+ const watcherReadModelRecords = watcherReadModelLiveRecords(context);
202
+ const watcherReceiptRecords = watcherReceiptLiveRecords(context);
203
+ const automationRecords = [...automationReadModelRecords, ...watcherReadModelRecords, ...watcherReceiptRecords];
204
+ const scheduleRecords = scheduleLiveRecords(context);
205
+ const latestResearchRun = researchRuns[0];
206
+ const taskCancelRoute = firstAvailableControlRoute(taskRecords, 'cancel');
207
+ const taskStatus: AutonomyQueueStatus = taskRecords.some((record) => record.status === 'blocked' || record.status === 'failed')
208
+ ? 'attention'
209
+ : taskRecords.some((record) => record.status === 'running' || record.status === 'queued')
210
+ ? 'active'
211
+ : taskMethods.length > 0
212
+ ? 'ready'
213
+ : 'needs-setup';
214
+ const approvalStatus: AutonomyQueueStatus = approvalRecords.some((record) => record.status === 'pending' || record.status === 'claimed')
215
+ ? 'attention'
216
+ : approvalMethods.length > 0
217
+ ? 'ready'
218
+ : 'needs-setup';
219
+ const automationStatus: AutonomyQueueStatus = automationRecords.some((record) => record.status === 'failed' || record.status === 'blocked')
220
+ ? 'attention'
221
+ : automationReadModelRecords.some((record) => record.status === 'queued' || record.status === 'running')
222
+ || watcherReadModelRecords.some((record) => record.status === 'queued' || record.status === 'running')
223
+ ? 'active'
224
+ : automationMethods.length > 0 || watcherReadModelRecords.length > 0 || watcherReceiptRecords.length > 0
225
+ ? 'ready'
226
+ : 'needs-setup';
227
+ const scheduleStatus: AutonomyQueueStatus = scheduleRecords.some((record) => record.status === 'error')
228
+ ? 'attention'
229
+ : scheduleRecords.some((record) => record.status === 'enabled')
230
+ ? 'active'
231
+ : scheduleMethods.length > 0
232
+ ? 'ready'
233
+ : 'needs-setup';
234
+ const scheduleReadyRoutines = snapshot.localRoutines.filter((routine) => (
235
+ routine.enabled === true
236
+ && routine.reviewState === 'reviewed'
237
+ && (routine.missingRequirementCount ?? 0) === 0
238
+ )).length;
239
+ const routineReceiptStatus: AutonomyQueueStatus = snapshot.failedRoutineScheduleReceiptCount > 0
240
+ ? 'attention'
241
+ : snapshot.successfulRoutineScheduleReceiptCount > 0
242
+ ? 'active'
243
+ : scheduleReadyRoutines > 0
244
+ ? 'ready'
245
+ : 'needs-setup';
246
+
247
+ const items: AutonomyQueueItem[] = [
248
+ {
249
+ id: 'visible-work-plan',
250
+ label: 'Visible work plan',
251
+ status: 'ready',
252
+ owner: 'agent',
253
+ kind: 'work-plan',
254
+ visible: true,
255
+ cancellable: true,
256
+ count: taskMethods.length,
257
+ current: `Work-plan actions are available in the Agent workspace; ${taskMethods.length} task/work-plan daemon method(s) are discoverable.`,
258
+ next: 'Track ongoing user work here first, then update status to active, blocked, done, failed, or cancelled from the confirmed form.',
259
+ inspectRoute: 'workspace action:"action" actionId:"workplan-show"',
260
+ modelRoute: 'agent_work_plan',
261
+ cancelRoute: 'workspace action:"run" actionId:"workplan-status" confirm:true explicitUserRequest:"..."',
262
+ createRoute: 'workspace action:"run" actionId:"workplan-add" confirm:true explicitUserRequest:"..."',
263
+ methodIds: taskMethods,
264
+ },
265
+ {
266
+ id: 'research-runs',
267
+ label: 'Research runs',
268
+ status: snapshot.researchRunBlockedCount > 0
269
+ ? 'attention'
270
+ : snapshot.researchRunRunningCount > 0
271
+ ? 'active'
272
+ : snapshot.researchRunPausedCount > 0 || snapshot.researchRunPlannedCount > 0
273
+ ? 'ready'
274
+ : 'needs-setup',
275
+ owner: 'agent',
276
+ kind: 'research-run',
277
+ visible: true,
278
+ cancellable: snapshot.researchRunRunningCount + snapshot.researchRunPausedCount + snapshot.researchRunPlannedCount + snapshot.researchRunBlockedCount > 0,
279
+ count: snapshot.researchRunCount,
280
+ current: [
281
+ `${snapshot.researchRunCount} run(s), ${snapshot.researchRunRunningCount} running, ${snapshot.researchRunPausedCount} paused, ${snapshot.researchRunBlockedCount} blocked, ${snapshot.researchRunPlannedCount} planned.`,
282
+ latestResearchRun ? `Latest visible run: ${latestResearchRun.label} (${latestResearchRun.status}${typeof latestResearchRun.progress === 'number' ? ` ${latestResearchRun.progress}%` : ''}).` : '',
283
+ ].filter(Boolean).join(' '),
284
+ next: snapshot.researchRunBlockedCount > 0
285
+ ? 'Inspect blocked research runs, then checkpoint, resume, cancel, or complete one exact run.'
286
+ : snapshot.researchRunRunningCount > 0
287
+ ? 'Checkpoint progress, source ids, and next steps before switching tasks or saving a report.'
288
+ : 'Create a visible research run when the user wants resumable deep research.',
289
+ inspectRoute: 'research action:"runs"',
290
+ modelRoute: 'research action:"runs"',
291
+ cancelRoute: 'research action:"cancel" id="..." note="..." confirm:true explicitUserRequest="..."',
292
+ createRoute: 'research action:"create_run" title:"..." question:"..." confirm:true explicitUserRequest:"..."',
293
+ liveRecords: researchRuns,
294
+ },
295
+ {
296
+ id: 'connected-host-tasks',
297
+ label: 'Connected-host tasks',
298
+ status: taskStatus,
299
+ owner: 'connected-host',
300
+ kind: 'host-task',
301
+ visible: true,
302
+ cancellable: taskRecords.some((record) => controlAvailable(record, 'cancel')),
303
+ count: taskRecords.length > 0 ? taskRecords.length : taskMethods.length,
304
+ current: taskRecords.length > 0
305
+ ? `${taskRecords.length} live connected-host task record(s); active cancellable tasks expose exact confirmed daemon controls. ${taskMethods.length} task-like daemon method(s) are discoverable.`
306
+ : `${taskMethods.length} task-like daemon method(s) are present; Agent exposes read-only host task inspection.`,
307
+ next: taskRecords.some((record) => record.status === 'blocked' || record.status === 'failed')
308
+ ? 'Inspect failed or blocked host tasks, then use the exact retry control when useful or update Agent workplan state from the visible work-plan route.'
309
+ : taskCancelRoute
310
+ ? 'Inspect active host tasks; cancel only the exact host task id through its confirmed daemon control when the user authorizes it.'
311
+ : taskRecords.some((record) => record.status === 'running' || record.status === 'queued')
312
+ ? 'Inspect active host tasks before changing any work plan, delegation, or automation state.'
313
+ : taskMethods.length > 0
314
+ ? 'Inspect host tasks before changing any work plan or automation state.'
315
+ : 'Update the connected GoodVibes host or connector set until task inspection methods are present.',
316
+ inspectRoute: 'workspace action:"action" actionId:"tasks-list"',
317
+ modelRoute: 'host action:"methods" query:"task"',
318
+ ...(taskCancelRoute ? { cancelRoute: taskCancelRoute } : {}),
319
+ methodIds: taskMethods,
320
+ liveRecords: taskRecords,
321
+ },
322
+ {
323
+ id: 'pending-approvals',
324
+ label: 'Pending approvals',
325
+ status: approvalStatus,
326
+ owner: 'connected-host',
327
+ kind: 'approval',
328
+ visible: true,
329
+ cancellable: true,
330
+ count: approvalRecords.length > 0 ? approvalRecords.length : approvalMethods.length,
331
+ current: approvalRecords.length > 0
332
+ ? `${approvalRecords.length} recent approval record(s); pending or claimed approvals require explicit user-visible decisions.`
333
+ : `${approvalMethods.length} approval daemon method(s) are present; approval decisions remain explicit and reviewable.`,
334
+ next: approvalRecords.some((record) => record.status === 'pending' || record.status === 'claimed')
335
+ ? 'Review pending approval records, risk, and args; approve, deny, or cancel exactly one id only when the user asks.'
336
+ : 'Review the matrix, then approve, deny, or cancel one exact approval id only when the user asks.',
337
+ inspectRoute: 'workspace action:"action" actionId:"approvals"',
338
+ modelRoute: 'host action:"methods" query:"approval"',
339
+ cancelRoute: 'workspace action:"run" actionId:"approval-cancel" confirm:true explicitUserRequest:"..."',
340
+ methodIds: approvalMethods,
341
+ liveRecords: approvalRecords,
342
+ },
343
+ {
344
+ id: 'automation-runs',
345
+ label: 'Automation runs',
346
+ status: automationStatus,
347
+ owner: 'connected-host',
348
+ kind: 'automation-run',
349
+ visible: true,
350
+ cancellable: true,
351
+ count: automationRecords.length > 0 ? automationRecords.length : automationMethods.length,
352
+ current: automationRecords.length > 0
353
+ ? `${automationReadModelRecords.length} recent automation run record(s), ${watcherReadModelRecords.length} live watcher run/source record(s), ${watcherReceiptRecords.length} durable watcher/run receipt(s); active, failed, and retryable live runs expose exact control routes while receipt records stay read-only.`
354
+ : `${automationMethods.length} automation daemon method(s) are present; run, pause, resume, cancel, and retry actions are confirmed forms.`,
355
+ next: automationRecords.some((record) => record.status === 'failed')
356
+ ? 'Inspect failed automation runs, then retry or leave them alone only through exact confirmed run routes.'
357
+ : automationReadModelRecords.some((record) => record.status === 'queued' || record.status === 'running')
358
+ ? 'Inspect active automation runs and cancel only the exact run id the user authorizes.'
359
+ : watcherReadModelRecords.some((record) => record.status === 'queued' || record.status === 'running')
360
+ ? 'Inspect live watcher/source records and use exact published watcher controls only for the run id the user authorizes.'
361
+ : watcherReadModelRecords.length > 0
362
+ ? 'Review live watcher/source read models and durable receipts; mutate only through exact confirmed routes published by the host.'
363
+ : watcherReceiptRecords.length > 0
364
+ ? 'Review durable watcher/run receipts, then wait for live SDK/daemon run records before controlling any run.'
365
+ : 'Inspect automation posture first. Use exact run/job ids for confirmed run control.',
366
+ inspectRoute: 'host action:"methods" query:"automation"',
367
+ modelRoute: 'workspace action:"actions" categoryId:"automation"',
368
+ cancelRoute: 'workspace action:"run" actionId:"automation-run-cancel" confirm:true explicitUserRequest:"..."',
369
+ methodIds: automationMethods,
370
+ liveRecords: automationRecords,
371
+ },
372
+ {
373
+ id: 'autonomous-schedule-requests',
374
+ label: 'Autonomous schedule requests',
375
+ status: scheduleMethods.length > 0 ? 'ready' : 'needs-setup',
376
+ owner: 'agent-and-connected-host',
377
+ kind: 'schedule',
378
+ visible: true,
379
+ cancellable: false,
380
+ count: scheduleMethods.length,
381
+ current: `${scheduleMethods.length} schedule/reminder daemon method(s); autonomous schedules require explicit task, cadence, success criteria, and user request provenance.`,
382
+ next: scheduleMethods.length > 0
383
+ ? 'Create one visible autonomous schedule only after the user gives exact timing and success criteria.'
384
+ : 'Update the connected GoodVibes host until schedules.create is available.',
385
+ inspectRoute: 'autonomy action:"intake" query:"..."',
386
+ modelRoute: 'schedule action:"create"',
387
+ createRoute: 'schedule action:"create" task:"..." successCriteria:"..." scheduleKind:"..." scheduleValue:"..." confirm:true explicitUserRequest:"..."',
388
+ methodIds: scheduleMethods,
389
+ },
390
+ {
391
+ id: 'connected-schedules',
392
+ label: 'Connected schedules',
393
+ status: scheduleStatus,
394
+ owner: 'connected-host',
395
+ kind: 'schedule',
396
+ visible: true,
397
+ cancellable: true,
398
+ count: scheduleRecords.length > 0 ? scheduleRecords.length : scheduleMethods.length,
399
+ current: scheduleRecords.length > 0
400
+ ? `${scheduleRecords.length} live connected schedule record(s); edit, run-now, enable, disable, and delete remain explicit confirmed actions.`
401
+ : `${scheduleMethods.length} schedule/reminder daemon method(s) are present; schedule inspection, edit, and lifecycle controls are visible.`,
402
+ next: scheduleRecords.some((record) => record.status === 'error')
403
+ ? 'Inspect schedule errors before running, enabling, disabling, deleting, or creating more schedules.'
404
+ : scheduleRecords.length > 0
405
+ ? 'Review live schedules or reconcile routine receipts before controlling one exact schedule id.'
406
+ : 'List schedules or reconcile routine receipts before controlling one schedule by id.',
407
+ inspectRoute: 'workspace action:"action" actionId:"schedule-list"',
408
+ modelRoute: 'schedule action:"list|edit|run|pause|resume|delete"',
409
+ cancelRoute: 'schedule action:"pause" scheduleId:"..." confirm:true explicitUserRequest:"..."',
410
+ createRoute: 'schedule action:"create" task:"..." successCriteria:"..." scheduleKind:"..." scheduleValue:"..." confirm:true explicitUserRequest:"..."',
411
+ methodIds: scheduleMethods,
412
+ liveRecords: scheduleRecords,
413
+ },
414
+ {
415
+ id: 'reminder-requests',
416
+ label: 'Reminder requests',
417
+ status: scheduleMethods.length > 0 ? readyChannels > 0 || configuredTargets > 0 ? 'ready' : 'needs-setup' : 'needs-setup',
418
+ owner: 'agent-and-connected-host',
419
+ kind: 'reminder',
420
+ visible: true,
421
+ cancellable: false,
422
+ count: configuredTargets,
423
+ current: `${configuredTargets} configured delivery target(s), ${readyChannels} ready channel(s), ${scheduleMethods.length} schedule/reminder method(s).`,
424
+ next: readyChannels > 0 || configuredTargets > 0
425
+ ? 'Create one reminder only after the user gives real timing and delivery scope.'
426
+ : 'Configure at least one delivery target before relying on reminder delivery.',
427
+ inspectRoute: 'personal_ops action:"lane" laneId:"reminders"',
428
+ modelRoute: 'schedule action:"remind"',
429
+ createRoute: 'schedule action:"remind" message:"..." scheduleKind:"..." scheduleValue:"..." confirm:true explicitUserRequest:"..."',
430
+ methodIds: scheduleMethods,
431
+ },
432
+ {
433
+ id: 'routine-schedule-promotions',
434
+ label: 'Routine schedule promotions',
435
+ status: routineReceiptStatus,
436
+ owner: 'agent-and-connected-host',
437
+ kind: 'routine-schedule',
438
+ visible: true,
439
+ cancellable: false,
440
+ count: snapshot.routineScheduleReceiptCount,
441
+ current: `${snapshot.routineScheduleReceiptCount} receipt(s), ${snapshot.successfulRoutineScheduleReceiptCount} created, ${snapshot.failedRoutineScheduleReceiptCount} failed, ${scheduleReadyRoutines} schedule-ready routine(s).`,
442
+ next: snapshot.failedRoutineScheduleReceiptCount > 0
443
+ ? 'Reconcile failed receipts before creating more routine schedules.'
444
+ : scheduleReadyRoutines > 0
445
+ ? 'Promote one reviewed routine only when the user asks for recurrence.'
446
+ : 'Create, enable, and review a routine before schedule promotion.',
447
+ inspectRoute: 'workspace action:"action" actionId:"schedule-receipts"',
448
+ modelRoute: 'workspace action:"actions" categoryId:"routines"',
449
+ createRoute: 'workspace action:"run" actionId:"schedule-promote-routine" confirm:true explicitUserRequest:"..."',
450
+ methodIds: scheduleMethods,
451
+ },
452
+ {
453
+ id: 'delegated-subagents',
454
+ label: 'Delegated subagents',
455
+ status: 'ready',
456
+ owner: 'agent',
457
+ kind: 'delegated-agent',
458
+ visible: true,
459
+ cancellable: true,
460
+ count: 0,
461
+ current: 'Subagent and delegation routes are visible and cancellable; ordinary chat remains serial by default.',
462
+ next: 'Use visible delegation only when isolation, parallelism, remote execution, or an explicit build/fix/review handoff helps the user.',
463
+ inspectRoute: 'agent_harness mode:"agent_orchestration"',
464
+ modelRoute: 'agent_harness mode:"agent_orchestration"',
465
+ cancelRoute: 'agent { mode: "cancel", agentId: "..." }',
466
+ createRoute: 'agent { mode: "spawn", task: "..." }',
467
+ batchCreateRoute: 'agent { mode: "batch-spawn", tasks: [...] }',
468
+ },
469
+ {
470
+ id: 'delivery-followups',
471
+ label: 'Delivery follow-ups',
472
+ status: readyChannels > 0 ? 'ready' : 'needs-setup',
473
+ owner: 'agent-and-connected-host',
474
+ kind: 'delivery',
475
+ visible: true,
476
+ cancellable: false,
477
+ count: readyChannels,
478
+ current: `${readyChannels}/${snapshot.channels.length} channel(s) ready; ${configuredTargets} configured default target(s).`,
479
+ next: readyChannels > 0
480
+ ? 'Use confirmed notification or channel send tools only after the user asks for delivery.'
481
+ : 'Pair or configure a delivery channel before promising proactive follow-up.',
482
+ inspectRoute: 'channels action:"status"',
483
+ modelRoute: 'channels action:"status"',
484
+ createRoute: 'workspace action:"run" actionId:"personal-ops-channels" confirm:true explicitUserRequest:"..."',
485
+ },
486
+ ];
487
+ return items.sort((left, right) => statusRank(right.status) - statusRank(left.status) || left.label.localeCompare(right.label));
488
+ }
489
+
490
+ function nextActions(items: readonly AutonomyQueueItem[]): readonly string[] {
491
+ return items
492
+ .filter((item) => item.status === 'attention' || item.status === 'needs-setup' || item.status === 'active')
493
+ .map((item) => `${item.label}: ${item.next}`)
494
+ .slice(0, 5);
495
+ }
496
+
497
+ export function autonomyQueueCatalogStatus(context: CommandContext): Record<string, unknown> {
498
+ const items = buildQueueItems(context);
499
+ const counts = items.reduce<Record<AutonomyQueueStatus, number>>((acc, item) => {
500
+ acc[item.status] += 1;
501
+ return acc;
502
+ }, { ready: 0, active: 0, 'needs-setup': 0, attention: 0, blocked: 0 });
503
+ return {
504
+ modes: ['autonomy_queue', 'autonomy_queue_item'],
505
+ items: items.length,
506
+ cancellable: items.filter((item) => item.cancellable).length,
507
+ ...counts,
508
+ readOnly: true,
509
+ };
510
+ }
511
+
512
+ export function autonomyQueueSummary(context: CommandContext, args: AgentHarnessAutonomyQueueArgs): Record<string, unknown> {
513
+ const includeParameters = args.includeParameters === true;
514
+ const query = readString(args.query).toLowerCase();
515
+ const limit = readLimit(args.limit, 100);
516
+ const all = buildQueueItems(context);
517
+ const filtered = all.filter((item) => !query || itemSearchText(item).includes(query));
518
+ return {
519
+ summary: {
520
+ items: all.length,
521
+ visible: all.filter((item) => item.visible).length,
522
+ cancellable: all.filter((item) => item.cancellable).length,
523
+ attention: all.filter((item) => item.status === 'attention').length,
524
+ needsSetup: all.filter((item) => item.status === 'needs-setup').length,
525
+ active: all.filter((item) => item.status === 'active').length,
526
+ ready: all.filter((item) => item.status === 'ready').length,
527
+ },
528
+ queue: filtered.slice(0, limit).map((item) => describeItem(item, includeParameters)),
529
+ returned: Math.min(filtered.length, limit),
530
+ total: all.length,
531
+ nextActions: nextActions(all),
532
+ policy: 'Visible autonomy queue is read-only. Autonomous work must have a visible owner, status/progress route, inspect route, and cancellation or recovery route when the owning surface supports one.',
533
+ };
534
+ }
535
+
536
+ export function describeAutonomyQueueItem(context: CommandContext, args: AgentHarnessAutonomyQueueArgs): AutonomyQueueResolution {
537
+ const queueItemId = readString(args.queueItemId);
538
+ const target = readString(args.target);
539
+ const query = readString(args.query);
540
+ const input = queueItemId || target || query;
541
+ if (!input) {
542
+ return {
543
+ status: 'missing_lookup',
544
+ usage: 'autonomy action:"item" requires queueItemId, target, or query. Use action:"queue" to inspect queue item ids.',
545
+ };
546
+ }
547
+ const normalized = input.toLowerCase();
548
+ const items = buildQueueItems(context);
549
+ const exact = items.find((item) => item.id === input);
550
+ if (exact) return { status: 'found', item: describeItem(exact, true, { source: queueItemId ? 'queueItemId' : target ? 'target' : 'query', input, resolvedBy: 'id' }) };
551
+ const insensitive = items.find((item) => item.id.toLowerCase() === normalized);
552
+ if (insensitive) return { status: 'found', item: describeItem(insensitive, true, { source: queueItemId ? 'queueItemId' : target ? 'target' : 'query', input, resolvedBy: 'case-insensitive-id' }) };
553
+ const matches = items.filter((item) => itemSearchText(item).includes(normalized));
554
+ if (matches.length === 1) return { status: 'found', item: describeItem(matches[0]!, true, { source: queueItemId ? 'queueItemId' : target ? 'target' : 'query', input, resolvedBy: 'search' }) };
555
+ if (matches.length > 1) {
556
+ return {
557
+ status: 'ambiguous',
558
+ input,
559
+ candidates: matches.slice(0, 8).map((item) => ({
560
+ queueItemId: item.id,
561
+ label: item.label,
562
+ status: item.status,
563
+ modelRoute: item.modelRoute,
564
+ })),
565
+ };
566
+ }
567
+ return {
568
+ status: 'missing_lookup',
569
+ usage: `Unknown autonomy queue item ${input}. Use autonomy action:"queue" to inspect queue item ids.`,
570
+ };
571
+ }