@pellux/goodvibes-agent 1.1.7 → 1.2.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 (255) hide show
  1. package/CHANGELOG.md +170 -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 +132577 -91483
  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 +56 -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 +114 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +130 -5
  17. package/release/release-readiness.json +120 -90
  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 +296 -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-checkpoint.ts +140 -0
  42. package/src/agent/setup-wizard.ts +447 -0
  43. package/src/agent/skill-registry-types.ts +102 -0
  44. package/src/agent/skill-registry.ts +81 -107
  45. package/src/agent/vibe-confirmation-routes.ts +62 -0
  46. package/src/agent/vibe-file.ts +285 -0
  47. package/src/cli/agent-knowledge-command.ts +45 -2
  48. package/src/cli/help.ts +3 -0
  49. package/src/cli/profiles-command.ts +25 -11
  50. package/src/config/agent-settings-policy.ts +1 -18
  51. package/src/input/agent-workspace-activation.ts +53 -0
  52. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  53. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  54. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  55. package/src/input/agent-workspace-categories.ts +153 -155
  56. package/src/input/agent-workspace-channel-triage.ts +481 -0
  57. package/src/input/agent-workspace-channels.ts +263 -0
  58. package/src/input/agent-workspace-command-editor.ts +152 -0
  59. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  60. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  61. package/src/input/agent-workspace-document-editor.ts +502 -0
  62. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  63. package/src/input/agent-workspace-host-category.ts +1 -1
  64. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  65. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  66. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  67. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  68. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  69. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  70. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  71. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  72. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  73. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  74. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  75. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  76. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  77. package/src/input/agent-workspace-settings.ts +262 -30
  78. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  79. package/src/input/agent-workspace-setup-snapshot.ts +198 -0
  80. package/src/input/agent-workspace-setup.ts +34 -1
  81. package/src/input/agent-workspace-snapshot.ts +162 -147
  82. package/src/input/agent-workspace-types.ts +287 -2
  83. package/src/input/agent-workspace.ts +18 -0
  84. package/src/input/command-registry.ts +9 -2
  85. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  86. package/src/input/commands/channels-runtime.ts +102 -114
  87. package/src/input/commands/delegation-runtime.ts +87 -24
  88. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  89. package/src/input/commands/knowledge.ts +28 -14
  90. package/src/input/commands/operator-actions-runtime.ts +6 -3
  91. package/src/input/commands/schedule-runtime.ts +71 -14
  92. package/src/input/commands/session-content.ts +2 -2
  93. package/src/input/commands/shell-core.ts +2 -0
  94. package/src/input/commands/vibe-runtime.ts +140 -0
  95. package/src/input/commands.ts +2 -0
  96. package/src/input/connected-host-routes.ts +123 -0
  97. package/src/input/settings-modal-types.ts +14 -0
  98. package/src/main.ts +15 -15
  99. package/src/panels/qr-panel.ts +2 -2
  100. package/src/renderer/agent-workspace-context-lines.ts +686 -0
  101. package/src/renderer/agent-workspace.ts +30 -419
  102. package/src/renderer/settings-modal-helpers.ts +12 -0
  103. package/src/renderer/settings-modal.ts +12 -0
  104. package/src/runtime/bootstrap-command-context.ts +11 -1
  105. package/src/runtime/bootstrap-command-parts.ts +14 -3
  106. package/src/runtime/bootstrap-core.ts +39 -1
  107. package/src/runtime/bootstrap-shell.ts +6 -0
  108. package/src/runtime/bootstrap.ts +113 -30
  109. package/src/runtime/connected-host-auth.ts +3 -2
  110. package/src/runtime/execution-ledger.ts +231 -0
  111. package/src/runtime/services.ts +88 -10
  112. package/src/runtime/tool-permission-safety.ts +199 -5
  113. package/src/shell/session-continuity-hints.ts +39 -0
  114. package/src/tools/agent-artifacts-tool.ts +606 -0
  115. package/src/tools/agent-audit-tool.ts +155 -0
  116. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  117. package/src/tools/agent-autonomy-tool.ts +140 -0
  118. package/src/tools/agent-channel-send-tool.ts +24 -2
  119. package/src/tools/agent-channels-tool.ts +140 -0
  120. package/src/tools/agent-computer-tool.ts +168 -0
  121. package/src/tools/agent-context-policy.ts +137 -7
  122. package/src/tools/agent-context-tool.ts +143 -0
  123. package/src/tools/agent-delegation-tool.ts +128 -0
  124. package/src/tools/agent-device-tool.ts +240 -0
  125. package/src/tools/agent-documents-tool.ts +684 -0
  126. package/src/tools/agent-execution-tool.ts +230 -0
  127. package/src/tools/agent-harness-agent-orchestration.ts +703 -0
  128. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  129. package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
  130. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  131. package/src/tools/agent-harness-autonomy-queue.ts +560 -0
  132. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  133. package/src/tools/agent-harness-background-processes.ts +794 -0
  134. package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
  135. package/src/tools/agent-harness-browser-control.ts +338 -0
  136. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  137. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  138. package/src/tools/agent-harness-command-catalog.ts +4 -2
  139. package/src/tools/agent-harness-command-runner.ts +42 -0
  140. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  141. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  142. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  143. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  144. package/src/tools/agent-harness-document-ops.ts +671 -0
  145. package/src/tools/agent-harness-execution-history.ts +489 -0
  146. package/src/tools/agent-harness-execution-posture.ts +382 -0
  147. package/src/tools/agent-harness-file-recovery.ts +135 -0
  148. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  149. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  150. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  151. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  152. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  153. package/src/tools/agent-harness-learning-curator.ts +417 -0
  154. package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
  155. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  156. package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
  157. package/src/tools/agent-harness-media-posture.ts +208 -2
  158. package/src/tools/agent-harness-memory-posture.ts +556 -0
  159. package/src/tools/agent-harness-metadata.ts +100 -168
  160. package/src/tools/agent-harness-mode-catalog.ts +84 -33
  161. package/src/tools/agent-harness-model-catalog.ts +162 -0
  162. package/src/tools/agent-harness-model-provider-health.ts +186 -0
  163. package/src/tools/agent-harness-model-readiness.ts +406 -0
  164. package/src/tools/agent-harness-model-routing-types.ts +266 -0
  165. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  166. package/src/tools/agent-harness-model-routing.ts +137 -190
  167. package/src/tools/agent-harness-operator-methods.ts +115 -133
  168. package/src/tools/agent-harness-pairing-posture.ts +431 -18
  169. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  170. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  171. package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
  172. package/src/tools/agent-harness-personal-ops-records.ts +732 -0
  173. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  174. package/src/tools/agent-harness-personal-ops-types.ts +222 -0
  175. package/src/tools/agent-harness-personal-ops.ts +606 -0
  176. package/src/tools/agent-harness-project-context.ts +144 -0
  177. package/src/tools/agent-harness-prompt-context.ts +589 -0
  178. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  179. package/src/tools/agent-harness-release-evidence.ts +9 -7
  180. package/src/tools/agent-harness-release-readiness.ts +9 -7
  181. package/src/tools/agent-harness-research-briefing.ts +427 -0
  182. package/src/tools/agent-harness-research-queue.ts +250 -0
  183. package/src/tools/agent-harness-research-runs.ts +295 -0
  184. package/src/tools/agent-harness-research-workflow.ts +322 -0
  185. package/src/tools/agent-harness-security-posture.ts +2 -2
  186. package/src/tools/agent-harness-service-posture.ts +9 -9
  187. package/src/tools/agent-harness-session-metadata.ts +3 -3
  188. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  189. package/src/tools/agent-harness-setup-describe.ts +557 -0
  190. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  191. package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
  192. package/src/tools/agent-harness-setup-plan.ts +253 -0
  193. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  194. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  195. package/src/tools/agent-harness-setup-posture.ts +449 -221
  196. package/src/tools/agent-harness-setup-smoke.ts +508 -0
  197. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  198. package/src/tools/agent-harness-tool-schema.ts +120 -7
  199. package/src/tools/agent-harness-tool-types.ts +78 -0
  200. package/src/tools/agent-harness-tool-utils.ts +43 -0
  201. package/src/tools/agent-harness-tool.ts +311 -370
  202. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  203. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  204. package/src/tools/agent-harness-vibe-health.ts +105 -0
  205. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  206. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  207. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  208. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  209. package/src/tools/agent-host-tool.ts +159 -0
  210. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  211. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  212. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  213. package/src/tools/agent-memory-tool.ts +214 -0
  214. package/src/tools/agent-model-compare-export.ts +315 -0
  215. package/src/tools/agent-model-compare-handoff.ts +592 -0
  216. package/src/tools/agent-model-compare-judgment.ts +633 -0
  217. package/src/tools/agent-model-compare-run.ts +722 -0
  218. package/src/tools/agent-model-compare-tool.ts +698 -0
  219. package/src/tools/agent-model-compare-types.ts +191 -0
  220. package/src/tools/agent-model-compare-utils.ts +93 -0
  221. package/src/tools/agent-models-tool.ts +208 -0
  222. package/src/tools/agent-operator-action-tool.ts +1 -1
  223. package/src/tools/agent-operator-method-tool.ts +643 -0
  224. package/src/tools/agent-personal-ops-tool.ts +197 -0
  225. package/src/tools/agent-policy-explanation.ts +415 -0
  226. package/src/tools/agent-research-report-tool.ts +608 -0
  227. package/src/tools/agent-research-runs-tool.ts +434 -0
  228. package/src/tools/agent-research-sources-tool.ts +443 -0
  229. package/src/tools/agent-research-tool.ts +687 -0
  230. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  231. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  232. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  233. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  234. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  235. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  236. package/src/tools/agent-route-planner-helpers.ts +667 -0
  237. package/src/tools/agent-route-planner.ts +185 -0
  238. package/src/tools/agent-route-tool.ts +105 -0
  239. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  240. package/src/tools/agent-schedule-tool.ts +282 -0
  241. package/src/tools/agent-security-tool.ts +145 -0
  242. package/src/tools/agent-sessions-tool.ts +122 -0
  243. package/src/tools/agent-settings-import-tool.ts +104 -0
  244. package/src/tools/agent-settings-tool.ts +176 -0
  245. package/src/tools/agent-setup-tool.ts +226 -0
  246. package/src/tools/agent-support-tool.ts +122 -0
  247. package/src/tools/agent-terminal-process-tools.ts +167 -0
  248. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  249. package/src/tools/agent-tool-policy-guard.ts +106 -85
  250. package/src/tools/agent-vibe-tool.ts +297 -0
  251. package/src/tools/agent-work-plan-tool.ts +265 -6
  252. package/src/tools/agent-workspace-tool.ts +305 -0
  253. package/src/tools/artifact-archive.ts +169 -0
  254. package/src/tools/tool-definition-compaction.ts +36 -0
  255. package/src/version.ts +1 -1
@@ -0,0 +1,785 @@
1
+ import { getOperatorContract } from '@pellux/goodvibes-sdk/contracts';
2
+ import type { CommandContext } from '../input/command-registry.ts';
3
+ import { previewHarnessText } from './agent-harness-text.ts';
4
+
5
+ interface AgentHarnessAutonomyIntakeArgs {
6
+ readonly query?: unknown;
7
+ readonly target?: unknown;
8
+ readonly includeParameters?: unknown;
9
+ }
10
+
11
+ interface ScheduleDetection {
12
+ readonly kind?: 'at' | 'every' | 'cron';
13
+ readonly value?: string;
14
+ readonly missing: readonly string[];
15
+ readonly notes: readonly string[];
16
+ }
17
+
18
+ interface AutonomyRouteCandidate {
19
+ readonly id: string;
20
+ readonly label: string;
21
+ readonly confidence: 'high' | 'medium' | 'low';
22
+ readonly why: string;
23
+ readonly modelRoute: string;
24
+ readonly inspectRoute: string;
25
+ readonly requiresConfirmation: boolean;
26
+ readonly missingFields?: readonly string[];
27
+ readonly userQuestion?: string;
28
+ readonly setupRoutes?: readonly string[];
29
+ readonly triggerWorkflowId?: string;
30
+ readonly policy?: string;
31
+ }
32
+
33
+ type WatcherEvidenceContractStatus = 'contract-needed' | 'ready';
34
+ type WatcherEvidenceCheckStatus = 'published-route' | 'missing';
35
+
36
+ interface WatcherEvidenceContractRoute {
37
+ readonly id: string;
38
+ readonly label: string;
39
+ readonly modelRoute: string;
40
+ readonly effect: 'read-only' | 'confirmed';
41
+ readonly why: string;
42
+ }
43
+
44
+ interface WatcherEvidenceContractCheck {
45
+ readonly id: string;
46
+ readonly label: string;
47
+ readonly status: WatcherEvidenceCheckStatus;
48
+ readonly requiredFor: string;
49
+ readonly owner: 'goodvibes-sdk-or-daemon';
50
+ readonly inspectRoute: string;
51
+ }
52
+
53
+ interface WatcherEvidenceReceiptContract {
54
+ readonly status: 'missing';
55
+ readonly appliesTo: readonly string[];
56
+ readonly requiredFields: readonly string[];
57
+ readonly nextWhenPublished: string;
58
+ }
59
+
60
+ interface WatcherProviderSourceContract {
61
+ readonly status: 'missing';
62
+ readonly supportedSourceKinds: readonly string[];
63
+ readonly requiredFields: readonly string[];
64
+ readonly policy: string;
65
+ }
66
+
67
+ interface WatcherEvidenceContract {
68
+ readonly status: WatcherEvidenceContractStatus;
69
+ readonly userOutcome: string;
70
+ readonly currentState: string;
71
+ readonly owner: 'goodvibes-sdk-or-daemon';
72
+ readonly nextRoutes: readonly WatcherEvidenceContractRoute[];
73
+ readonly contractChecklist: readonly WatcherEvidenceContractCheck[];
74
+ readonly receiptContract: WatcherEvidenceReceiptContract;
75
+ readonly providerSourceContract: WatcherProviderSourceContract;
76
+ readonly policy: string;
77
+ }
78
+
79
+ type TriggerWorkflowStatus = 'ready' | 'attention' | 'setup-needed' | 'not-published';
80
+
81
+ interface TriggerWorkflow {
82
+ readonly id: string;
83
+ readonly label: string;
84
+ readonly status: TriggerWorkflowStatus;
85
+ readonly userOutcome: string;
86
+ readonly summary: string;
87
+ readonly nextStep: string;
88
+ readonly capabilities: readonly string[];
89
+ readonly requiredFields: readonly string[];
90
+ readonly modelRoute: string;
91
+ readonly inspectRoute: string;
92
+ readonly setupRoutes: readonly string[];
93
+ readonly evidence: Record<string, unknown>;
94
+ readonly outcome?: {
95
+ readonly target: string;
96
+ readonly successCriteria: readonly string[];
97
+ readonly evidenceFields: readonly string[];
98
+ readonly verificationRoute: string;
99
+ };
100
+ readonly evidenceContract?: WatcherEvidenceContract;
101
+ readonly policy: string;
102
+ }
103
+
104
+ const WATCHER_EVIDENCE_RECEIPT_FIELDS = [
105
+ 'receiptId',
106
+ 'watcherId',
107
+ 'runId',
108
+ 'sourceId',
109
+ 'sourceKind',
110
+ 'sourceScope',
111
+ 'operation',
112
+ 'status',
113
+ 'createdAt',
114
+ 'startedAt',
115
+ 'completedAt',
116
+ 'redaction',
117
+ 'lastCheckpoint',
118
+ 'lastError',
119
+ 'nextRoute',
120
+ 'recoveryRoute',
121
+ ] as const;
122
+
123
+ const WATCHER_PROVIDER_SOURCE_FIELDS = [
124
+ 'sourceId',
125
+ 'sourceKind',
126
+ 'providerId',
127
+ 'providerKind',
128
+ 'scope',
129
+ 'filter',
130
+ 'enabled',
131
+ 'lastSeenAt',
132
+ 'lastCheckpoint',
133
+ 'lastError',
134
+ 'redaction',
135
+ 'permissionSummary',
136
+ 'nextRoute',
137
+ ] as const;
138
+
139
+ function readString(value: unknown): string {
140
+ return typeof value === 'string' ? value.trim() : '';
141
+ }
142
+
143
+ function hasAny(text: string, tokens: readonly string[]): boolean {
144
+ return tokens.some((token) => text.includes(token));
145
+ }
146
+
147
+ function operatorMethodIds(): ReadonlySet<string> {
148
+ const methods = getOperatorContract().operator?.methods;
149
+ if (!Array.isArray(methods)) return new Set();
150
+ return new Set(methods.map((method) => (
151
+ method && typeof method === 'object' && 'id' in method && typeof method.id === 'string'
152
+ ? method.id
153
+ : ''
154
+ )).filter(Boolean));
155
+ }
156
+
157
+ function triggerWorkflowSummary(workflows: readonly TriggerWorkflow[]): Record<string, unknown> {
158
+ const watcherContract = workflows.find((workflow) => workflow.evidenceContract)?.evidenceContract;
159
+ return {
160
+ total: workflows.length,
161
+ ready: workflows.filter((workflow) => workflow.status === 'ready').length,
162
+ attention: workflows.filter((workflow) => workflow.status === 'attention').length,
163
+ setupNeeded: workflows.filter((workflow) => workflow.status === 'setup-needed').length,
164
+ notPublished: workflows.filter((workflow) => workflow.status === 'not-published').length,
165
+ watcherEvidenceContractStatus: watcherContract?.status ?? null,
166
+ watcherEvidenceMissing: watcherContract?.contractChecklist
167
+ .filter((check) => check.status === 'missing')
168
+ .map((check) => check.id) ?? [],
169
+ primaryNextStep: workflows.find((workflow) => workflow.status !== 'ready')?.nextStep
170
+ ?? 'Trigger routes are published; require explicit source, scope, task, success criteria, and confirmation before creating anything.',
171
+ };
172
+ }
173
+
174
+ function describeTriggerWorkflow(workflow: TriggerWorkflow, includeParameters: boolean): Record<string, unknown> {
175
+ if (includeParameters) return { ...workflow };
176
+ return {
177
+ workflowId: workflow.id,
178
+ label: workflow.label,
179
+ status: workflow.status,
180
+ summary: previewHarnessText(workflow.summary),
181
+ modelRoute: workflow.modelRoute,
182
+ };
183
+ }
184
+
185
+ function watcherEvidenceContract(methodIds: ReadonlySet<string>): WatcherEvidenceContract {
186
+ const watcherCreatePublished = methodIds.has('watchers.create');
187
+ const watcherListPublished = methodIds.has('watchers.list');
188
+ const watcherRunPublished = methodIds.has('watchers.run');
189
+ const watcherStartStopPublished = methodIds.has('watchers.start') && methodIds.has('watchers.stop');
190
+ return {
191
+ status: 'contract-needed',
192
+ userOutcome: 'Show durable watcher run history and provider-source records in the autonomy queue without hiding trigger ownership.',
193
+ currentState: watcherListPublished
194
+ ? 'Watcher create/list routes are published, but durable run-history and provider-source records are not published as Agent-readable records yet.'
195
+ : 'Watcher visibility, run-history, and provider-source records are not fully published by the current connected-host contract.',
196
+ owner: 'goodvibes-sdk-or-daemon',
197
+ nextRoutes: [
198
+ {
199
+ id: 'inspect-watcher-methods',
200
+ label: 'Inspect watcher methods',
201
+ modelRoute: 'host action:"methods" query:"watchers"',
202
+ effect: 'read-only',
203
+ why: 'Shows which watcher setup and run-control routes the connected host publishes.',
204
+ },
205
+ {
206
+ id: 'inspect-watcher-list',
207
+ label: 'Inspect watcher list contract',
208
+ modelRoute: 'host action:"method" methodId:"watchers.list"',
209
+ effect: 'read-only',
210
+ why: 'Checks the source-owned watcher visibility route before Agent claims durable trigger state.',
211
+ },
212
+ {
213
+ id: 'inspect-autonomy-queue',
214
+ label: 'Inspect autonomy queue',
215
+ modelRoute: 'autonomy action:"queue"',
216
+ effect: 'read-only',
217
+ why: 'Shows the current Agent-visible runs, schedules, tasks, approvals, and watcher-adjacent records.',
218
+ },
219
+ {
220
+ id: 'inspect-personal-ops-source',
221
+ label: 'Inspect Personal Ops source readiness',
222
+ modelRoute: 'personal_ops action:"lane" laneId:"inbox"',
223
+ effect: 'read-only',
224
+ why: 'Checks email/Gmail connector readiness before any provider-backed watcher source is used.',
225
+ },
226
+ ],
227
+ contractChecklist: [
228
+ {
229
+ id: 'watcher-create-route',
230
+ label: 'Watcher creation route',
231
+ status: watcherCreatePublished ? 'published-route' : 'missing',
232
+ requiredFor: 'Create a visible source-scoped watcher after explicit user confirmation.',
233
+ owner: 'goodvibes-sdk-or-daemon',
234
+ inspectRoute: 'host action:"method" methodId:"watchers.create"',
235
+ },
236
+ {
237
+ id: 'watcher-list-route',
238
+ label: 'Watcher visibility route',
239
+ status: watcherListPublished ? 'published-route' : 'missing',
240
+ requiredFor: 'Verify a watcher remains visible, scoped, and enabled after creation or control changes.',
241
+ owner: 'goodvibes-sdk-or-daemon',
242
+ inspectRoute: 'host action:"method" methodId:"watchers.list"',
243
+ },
244
+ {
245
+ id: 'watcher-run-control-routes',
246
+ label: 'Watcher run/control routes',
247
+ status: watcherRunPublished && watcherStartStopPublished ? 'published-route' : 'missing',
248
+ requiredFor: 'Expose explicit run, start, stop, and retry controls without guessing lifecycle state.',
249
+ owner: 'goodvibes-sdk-or-daemon',
250
+ inspectRoute: 'host action:"methods" query:"watchers.run watchers.start watchers.stop"',
251
+ },
252
+ {
253
+ id: 'durable-run-history-records',
254
+ label: 'Durable watcher run history records',
255
+ status: 'missing',
256
+ requiredFor: 'Show past watcher runs, checkpoints, errors, and next recovery routes in the autonomy queue.',
257
+ owner: 'goodvibes-sdk-or-daemon',
258
+ inspectRoute: 'autonomy action:"queue"',
259
+ },
260
+ {
261
+ id: 'provider-source-records',
262
+ label: 'Provider-source records',
263
+ status: 'missing',
264
+ requiredFor: 'Show source-scoped Gmail/email/webhook/file records without polling or exposing raw provider payloads.',
265
+ owner: 'goodvibes-sdk-or-daemon',
266
+ inspectRoute: 'personal_ops action:"lane" laneId:"inbox"',
267
+ },
268
+ {
269
+ id: 'redacted-event-payloads',
270
+ label: 'Redacted event payload descriptors',
271
+ status: 'missing',
272
+ requiredFor: 'Show what triggered a watcher without leaking raw provider payloads, tokens, or personal message bodies.',
273
+ owner: 'goodvibes-sdk-or-daemon',
274
+ inspectRoute: 'autonomy action:"queue"',
275
+ },
276
+ {
277
+ id: 'queue-correlation-records',
278
+ label: 'Queue correlation records',
279
+ status: 'missing',
280
+ requiredFor: 'Link watcher source events, watcher runs, task records, recovery routes, and user-visible queue cards.',
281
+ owner: 'goodvibes-sdk-or-daemon',
282
+ inspectRoute: 'autonomy action:"queue"',
283
+ },
284
+ ],
285
+ receiptContract: {
286
+ status: 'missing',
287
+ appliesTo: [
288
+ 'watchers.create',
289
+ 'watchers.patch',
290
+ 'watchers.run',
291
+ 'watchers.start',
292
+ 'watchers.stop',
293
+ 'watchers.delete',
294
+ 'watcher-run-history',
295
+ 'provider-source-record',
296
+ ],
297
+ requiredFields: WATCHER_EVIDENCE_RECEIPT_FIELDS,
298
+ nextWhenPublished: 'autonomy action:"queue" and autonomy action:"item" should expose watcher run/source receipts with exact recovery and replay routes.',
299
+ },
300
+ providerSourceContract: {
301
+ status: 'missing',
302
+ supportedSourceKinds: ['webhook', 'github-webhook', 'file-watcher', 'gmail', 'email', 'calendar'],
303
+ requiredFields: WATCHER_PROVIDER_SOURCE_FIELDS,
304
+ policy: 'Provider-source records must be scoped, permission-aware, redacted, and source-owned; Agent only consumes published records and never polls personal providers silently.',
305
+ },
306
+ policy: 'This contract is read-only guidance. Watcher creation/control remains on confirmed connected-host operator routes; durable run/source storage remains owned by the SDK/daemon.',
307
+ };
308
+ }
309
+
310
+ function compactWatcherEvidenceContract(contract: WatcherEvidenceContract): Record<string, unknown> {
311
+ return {
312
+ status: contract.status,
313
+ userOutcome: contract.userOutcome,
314
+ owner: contract.owner,
315
+ missing: contract.contractChecklist.filter((check) => check.status === 'missing').map((check) => check.id),
316
+ publishedRoutes: contract.contractChecklist.filter((check) => check.status === 'published-route').map((check) => check.id),
317
+ requiredReceiptFields: contract.receiptContract.requiredFields,
318
+ providerSourceKinds: contract.providerSourceContract.supportedSourceKinds,
319
+ inspectRoute: 'host action:"methods" query:"watchers"',
320
+ };
321
+ }
322
+
323
+ function watcherTriggerOutcome(): TriggerWorkflow['outcome'] {
324
+ return {
325
+ target: 'created-visible-watcher',
326
+ successCriteria: [
327
+ 'The confirmed watchers.create receipt includes id, label, kind, state, source, and metadata.',
328
+ 'The receipt has no lastError.',
329
+ 'A follow-up watchers.list read shows the watcher remains visible before assuming the trigger is active.',
330
+ ],
331
+ evidenceFields: ['id', 'kind', 'label', 'state', 'source.kind', 'source.enabled', 'sourceStatus', 'lastCheckpoint', 'lastError'],
332
+ verificationRoute: 'agent_operator_method methodId:"watchers.list"',
333
+ };
334
+ }
335
+
336
+ function normalizeInterval(amount: string, rawUnit: string): string {
337
+ const unit = rawUnit.toLowerCase();
338
+ if (unit === 'ms') return `${amount}ms`;
339
+ if (unit === 's' || unit.startsWith('sec')) return `${amount}s`;
340
+ if (unit === 'm' || unit === 'min' || unit.startsWith('minute')) return `${amount}m`;
341
+ if (unit === 'h' || unit === 'hr' || unit.startsWith('hour')) return `${amount}h`;
342
+ return `${amount}d`;
343
+ }
344
+
345
+ function detectSchedule(request: string): ScheduleDetection {
346
+ const lower = request.toLowerCase();
347
+ const iso = request.match(/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?\b/);
348
+ if (iso) return { kind: 'at', value: iso[0], missing: [], notes: ['Detected exact ISO timestamp.'] };
349
+
350
+ const interval = lower.match(/\bevery\s+(\d+(?:\.\d+)?)\s*(ms|milliseconds?|s|seconds?|m|min|minutes?|h|hr|hours?|d|days?)\b/);
351
+ if (interval?.[1] && interval[2]) {
352
+ return {
353
+ kind: 'every',
354
+ value: normalizeInterval(interval[1], interval[2]),
355
+ missing: [],
356
+ notes: ['Detected exact recurring interval.'],
357
+ };
358
+ }
359
+
360
+ const compactEvery = lower.match(/\bevery\s+(\d+(?:\.\d+)?(?:ms|s|m|h|d))\b/);
361
+ if (compactEvery?.[1]) {
362
+ return { kind: 'every', value: compactEvery[1], missing: [], notes: ['Detected exact recurring interval.'] };
363
+ }
364
+
365
+ const cron = request.match(/\bcron[:\s]+(\S+\s+\S+\s+\S+\s+\S+\s+\S+(?:\s+\S+)?)/i);
366
+ if (cron?.[1]) return { kind: 'cron', value: cron[1].trim(), missing: [], notes: ['Detected cron expression.'] };
367
+
368
+ if (hasAny(lower, ['daily', 'every day', 'each day'])) {
369
+ return {
370
+ kind: 'cron',
371
+ missing: ['scheduleValue', 'timezone'],
372
+ notes: ['Daily intent detected; ask for an exact time/timezone or cron expression before creating anything.'],
373
+ };
374
+ }
375
+ if (hasAny(lower, ['weekly', 'every week', 'each week'])) {
376
+ return {
377
+ kind: 'cron',
378
+ missing: ['scheduleValue', 'timezone'],
379
+ notes: ['Weekly intent detected; ask for day, time, and timezone or a cron expression before creating anything.'],
380
+ };
381
+ }
382
+ if (hasAny(lower, ['monthly', 'every month', 'each month'])) {
383
+ return {
384
+ kind: 'cron',
385
+ missing: ['scheduleValue', 'timezone'],
386
+ notes: ['Monthly intent detected; ask for day, time, and timezone or a cron expression before creating anything.'],
387
+ };
388
+ }
389
+ if (hasAny(lower, ['schedule', 'scheduled', 'recurring', 'repeat', 'remind', 'reminder', 'follow up', 'follow-up'])) {
390
+ return {
391
+ missing: ['scheduleKind', 'scheduleValue'],
392
+ notes: ['Scheduling intent detected; ask for exact ISO time, interval, or cron expression.'],
393
+ };
394
+ }
395
+ return { missing: [], notes: [] };
396
+ }
397
+
398
+ function asksForEventTrigger(lower: string): boolean {
399
+ return hasAny(lower, [
400
+ 'event trigger',
401
+ 'event-trigger',
402
+ 'incoming webhook',
403
+ 'webhook trigger',
404
+ 'triggered by webhook',
405
+ 'when a webhook',
406
+ 'when webhook',
407
+ 'on webhook',
408
+ 'file watcher',
409
+ 'watcher trigger',
410
+ 'when gmail',
411
+ 'new gmail',
412
+ 'when email arrives',
413
+ 'new email arrives',
414
+ 'github webhook',
415
+ ]);
416
+ }
417
+
418
+ function buildTriggerWorkflows(request: string, schedule: ScheduleDetection): readonly TriggerWorkflow[] {
419
+ const methodIds = operatorMethodIds();
420
+ const schedulesCreatePublished = methodIds.has('schedules.create');
421
+ const schedulesListPublished = methodIds.has('schedules.list');
422
+ const watcherCreatePublished = methodIds.has('watchers.create');
423
+ const watcherListPublished = methodIds.has('watchers.list');
424
+ const watcherRunPublished = methodIds.has('watchers.run');
425
+ const watcherStartStopPublished = methodIds.has('watchers.start') && methodIds.has('watchers.stop');
426
+ const controlEventsPublished = methodIds.has('control.events.stream') || methodIds.has('control.events.catalog');
427
+ const watcherContract = watcherEvidenceContract(methodIds);
428
+ const scheduleMissing = schedule.missing.length > 0 ? schedule.missing : schedule.kind ? [] : ['scheduleKind', 'scheduleValue'];
429
+ const scheduleReady = schedulesCreatePublished && schedule.kind !== undefined && scheduleMissing.length === 0;
430
+ const watcherReady = watcherCreatePublished && watcherListPublished;
431
+ const shortRequest = previewHarnessText(request || 'requested autonomous work', 96).replace(/"/g, "'");
432
+
433
+ return [
434
+ {
435
+ id: 'time-based-wakeup-schedule',
436
+ label: 'Time-based wakeup or schedule',
437
+ status: scheduleReady ? 'ready' : schedulesCreatePublished ? 'attention' : 'setup-needed',
438
+ userOutcome: 'Run autonomous work on an exact at/every/cron cadence without making the user understand scheduler internals.',
439
+ summary: scheduleReady
440
+ ? 'The request includes an exact cadence and the connected host publishes schedules.create.'
441
+ : schedulesCreatePublished
442
+ ? 'The schedule route is published, but this request still needs an exact cadence before creation.'
443
+ : 'The connected host does not publish schedules.create in the current SDK contract.',
444
+ nextStep: scheduleReady
445
+ ? 'Create through schedule action:"create" with confirm:true and explicit success criteria.'
446
+ : 'Ask for the exact ISO time, every interval, or cron expression before offering schedule creation.',
447
+ capabilities: ['cron', 'at', 'every', 'wakeups', 'scheduled autonomous work'],
448
+ requiredFields: ['task', 'successCriteria', ...scheduleMissing],
449
+ modelRoute: `schedule action:"create" task:"${shortRequest}" successCriteria:"..." scheduleKind:"${schedule.kind ?? 'at|every|cron'}" scheduleValue:"${schedule.value ?? '...'}" confirm:true explicitUserRequest:"..."`,
450
+ inspectRoute: 'autonomy action:"item" queueItemId:"connected-schedules"',
451
+ setupRoutes: [
452
+ 'host action:"method" methodId:"schedules.create"',
453
+ 'autonomy action:"item" queueItemId:"connected-schedules"',
454
+ ],
455
+ evidence: {
456
+ schedulesCreatePublished,
457
+ schedulesListPublished,
458
+ detectedScheduleKind: schedule.kind ?? null,
459
+ detectedScheduleValue: schedule.value ?? null,
460
+ missingFields: scheduleMissing,
461
+ },
462
+ policy: 'Schedule creation is a confirmed connected-host mutation; vague recurring intent stays a question, not an inferred background job.',
463
+ },
464
+ {
465
+ id: 'incoming-webhook-or-watcher',
466
+ label: 'Incoming webhook or watcher trigger',
467
+ status: watcherReady ? 'ready' : watcherCreatePublished ? 'attention' : 'setup-needed',
468
+ userOutcome: 'Start visible work from a trusted incoming webhook, file/source watcher, or explicit event source.',
469
+ summary: watcherReady
470
+ ? 'The SDK operator contract publishes watcher create/list routes for trusted event-trigger setup.'
471
+ : watcherCreatePublished
472
+ ? 'Watcher creation is published, but watcher listing/readiness posture is incomplete.'
473
+ : 'Watcher creation is not published by the current connected-host contract.',
474
+ nextStep: watcherReady
475
+ ? 'Inspect watchers.create, then create only after the user provides source scope, run target, success criteria, and confirmation.'
476
+ : 'Use operator method discovery and do not claim incoming trigger setup until watcher routes are published.',
477
+ capabilities: ['incoming webhook', 'watcher', 'event trigger', 'source trigger', 'github webhook'],
478
+ requiredFields: ['trusted trigger source', 'source scope', 'task or run target', 'success criteria', 'confirmation'],
479
+ modelRoute: 'agent_operator_method methodId:"watchers.create" confirm:true explicitUserRequest:"..."',
480
+ inspectRoute: 'host action:"method" methodId:"watchers.create"',
481
+ setupRoutes: [
482
+ 'host action:"methods" query:"watchers"',
483
+ 'host action:"method" methodId:"watchers.list"',
484
+ 'autonomy action:"queue"',
485
+ ],
486
+ evidence: {
487
+ watcherCreatePublished,
488
+ watcherListPublished,
489
+ watcherRunPublished,
490
+ watcherStartStopPublished,
491
+ },
492
+ outcome: watcherTriggerOutcome(),
493
+ evidenceContract: watcherContract,
494
+ policy: 'Incoming triggers are admin connected-host mutations. They require a trusted source boundary, explicit run scope, and user confirmation before creation.',
495
+ },
496
+ {
497
+ id: 'gmail-or-email-trigger',
498
+ label: 'Gmail or email-triggered workflow',
499
+ status: watcherReady ? 'attention' : 'setup-needed',
500
+ userOutcome: 'React to inbox changes only through a configured connector and a permission-scoped watcher/source boundary.',
501
+ summary: watcherReady
502
+ ? 'Watcher routes exist, but email/Gmail automation still needs a configured Personal Ops connector and reviewed source scope.'
503
+ : 'Email-triggered work needs watcher routes plus a configured inbox connector before Agent can offer it.',
504
+ nextStep: 'Inspect Personal Ops inbox connector readiness before creating any watcher for email-triggered work.',
505
+ capabilities: ['gmail trigger', 'email trigger', 'inbox watcher', 'connector event'],
506
+ requiredFields: ['configured inbox connector', 'trusted mailbox/query scope', 'task to run', 'success criteria', 'confirmation'],
507
+ modelRoute: 'personal_ops action:"lane" laneId:"inbox"',
508
+ inspectRoute: 'personal_ops action:"lane" laneId:"inbox"',
509
+ setupRoutes: [
510
+ 'personal_ops action:"status" query:"inbox gmail email"',
511
+ 'host action:"method" methodId:"watchers.create"',
512
+ ],
513
+ evidence: {
514
+ watcherCreatePublished,
515
+ watcherListPublished,
516
+ personalOpsRoutePublished: true,
517
+ },
518
+ evidenceContract: watcherContract,
519
+ policy: 'Agent does not poll or read mail silently. Email-triggered work needs connector setup, scoped query/source details, and confirmation.',
520
+ },
521
+ {
522
+ id: 'control-plane-event-stream',
523
+ label: 'Control-plane event stream',
524
+ status: controlEventsPublished ? 'ready' : 'not-published',
525
+ userOutcome: 'Use daemon control-plane events for status-aware supervision without inventing hidden background work.',
526
+ summary: controlEventsPublished
527
+ ? 'The operator contract publishes control event catalog or stream routes for read-only supervision.'
528
+ : 'Control-plane event stream routes are not published in the current SDK contract.',
529
+ nextStep: controlEventsPublished
530
+ ? 'Use read-only control event routes for supervision, then route mutations through exact confirmed operator methods.'
531
+ : 'Keep supervision on autonomy action:"queue" until control event stream routes are published.',
532
+ capabilities: ['control events', 'event stream', 'always-on gateway supervision'],
533
+ requiredFields: ['event scope', 'supervision route'],
534
+ modelRoute: 'host action:"methods" query:"control events stream"',
535
+ inspectRoute: 'host action:"methods" query:"control events"',
536
+ setupRoutes: [
537
+ 'autonomy action:"queue"',
538
+ 'host action:"methods" query:"control events"',
539
+ ],
540
+ evidence: {
541
+ controlEventsPublished,
542
+ },
543
+ policy: 'Read-only event streams can inform supervision; they do not authorize new effects without the owning confirmed route.',
544
+ },
545
+ ];
546
+ }
547
+
548
+ function reminderRoute(request: string, schedule: ScheduleDetection): string {
549
+ const message = previewHarnessText(request, 72).replace(/"/g, "'");
550
+ const kind = schedule.kind ?? 'at|every|cron';
551
+ const value = schedule.value ?? '...';
552
+ return `schedule action:"remind" message:"${message}" scheduleKind:"${kind}" scheduleValue:"${value}" confirm:true explicitUserRequest:"..."`;
553
+ }
554
+
555
+ function autonomyScheduleRoute(request: string, schedule: ScheduleDetection): string {
556
+ const task = previewHarnessText(request, 96).replace(/"/g, "'");
557
+ const kind = schedule.kind ?? 'at|every|cron';
558
+ const value = schedule.value ?? '...';
559
+ return `schedule action:"create" task:"${task}" successCriteria:"..." scheduleKind:"${kind}" scheduleValue:"${value}" confirm:true explicitUserRequest:"..."`;
560
+ }
561
+
562
+ function buildCandidates(request: string): readonly AutonomyRouteCandidate[] {
563
+ const lower = request.toLowerCase();
564
+ const schedule = detectSchedule(request);
565
+ const candidates: AutonomyRouteCandidate[] = [];
566
+ const scheduled = schedule.missing.length > 0 || schedule.kind !== undefined;
567
+ const asksForReminder = hasAny(lower, ['remind', 'reminder', 'follow up', 'follow-up', 'ping me', 'notify me']);
568
+ const asksForRoutine = hasAny(lower, ['routine', 'checklist', 'recurring task', 'daily review', 'weekly review']);
569
+ const asksForResearch = hasAny(lower, ['research', 'investigate', 'market map', 'source', 'report']);
570
+ const asksForAutonomousSchedule = scheduled && !asksForReminder && hasAny(lower, [
571
+ 'audit',
572
+ 'brief',
573
+ 'briefing',
574
+ 'check',
575
+ 'daily report',
576
+ 'weekly report',
577
+ 'digest',
578
+ 'monitor',
579
+ 'research',
580
+ 'review',
581
+ 'run',
582
+ 'scan',
583
+ 'summarize',
584
+ 'triage',
585
+ ]);
586
+ const asksForDelegation = hasAny(lower, ['build', 'fix', 'implement', 'refactor', 'code', 'test']) && hasAny(lower, ['background', 'subagent', 'delegate', 'parallel']);
587
+ const asksForApproval = hasAny(lower, ['approval', 'approve', 'deny']);
588
+ const asksForAutomationControl = hasAny(lower, ['cancel', 'retry', 'pause', 'resume', 'run now'])
589
+ && hasAny(lower, ['automation', 'schedule', 'job', 'run']);
590
+ const asksForTrigger = asksForEventTrigger(lower);
591
+ const asksForUnsupportedConnector = hasAny(lower, ['email', 'calendar', 'gmail', 'imap', 'caldav']);
592
+
593
+ if (asksForAutomationControl) {
594
+ candidates.push({
595
+ id: 'automation-control',
596
+ label: 'Control an existing automation or schedule',
597
+ confidence: 'high',
598
+ why: 'The request is about run, cancel, retry, pause, resume, or run-now control for an existing job/run/schedule.',
599
+ modelRoute: 'autonomy action:"item" queueItemId:"automation-runs"',
600
+ inspectRoute: 'autonomy action:"queue"',
601
+ requiresConfirmation: true,
602
+ missingFields: ['exact jobId, runId, or scheduleId from the queue record'],
603
+ userQuestion: 'Which exact job, run, or schedule id should be controlled?',
604
+ });
605
+ }
606
+
607
+ if (asksForApproval) {
608
+ candidates.push({
609
+ id: 'approval-decision',
610
+ label: 'Review or decide a pending approval',
611
+ confidence: 'high',
612
+ why: 'The request mentions approval review or decision.',
613
+ modelRoute: 'autonomy action:"item" queueItemId:"pending-approvals"',
614
+ inspectRoute: 'workspace action:"action" actionId:"approvals"',
615
+ requiresConfirmation: true,
616
+ missingFields: ['exact approvalId', 'approve, deny, or cancel decision'],
617
+ userQuestion: 'Which approval id and decision should be applied?',
618
+ });
619
+ }
620
+
621
+ if (asksForTrigger) {
622
+ candidates.push({
623
+ id: 'visible-event-trigger-intake',
624
+ label: 'Create or review a visible webhook or event-trigger watcher',
625
+ confidence: 'high',
626
+ why: 'The request asks for work to start from an external event, webhook, watcher, Gmail, or inbound message instead of a time-based schedule.',
627
+ modelRoute: 'agent_operator_method methodId:"watchers.create" confirm:true explicitUserRequest:"..."',
628
+ inspectRoute: 'host action:"method" methodId:"watchers.create"',
629
+ requiresConfirmation: true,
630
+ missingFields: [
631
+ 'trusted trigger source and scope',
632
+ 'task to run',
633
+ 'success criteria',
634
+ ],
635
+ userQuestion: 'Which trusted event source should be allowed to trigger this work, and what should count as a successful run?',
636
+ setupRoutes: [
637
+ 'host action:"methods" query:"watchers"',
638
+ 'autonomy action:"queue"',
639
+ ],
640
+ triggerWorkflowId: 'incoming-webhook-or-watcher',
641
+ policy: 'Watcher creation is an admin connected-host mutation and must stay source-scoped, visible, and confirmed.',
642
+ });
643
+ }
644
+
645
+ if (asksForReminder || (scheduled && !asksForRoutine && !asksForResearch)) {
646
+ candidates.push({
647
+ id: 'one-reminder-or-simple-recurring-reminder',
648
+ label: 'Create one confirmed reminder schedule',
649
+ confidence: asksForReminder ? 'high' : 'medium',
650
+ why: 'The request looks like a reminder, follow-up, notification, or simple scheduled message.',
651
+ modelRoute: reminderRoute(request, schedule),
652
+ inspectRoute: 'autonomy action:"item" queueItemId:"reminder-requests"',
653
+ requiresConfirmation: true,
654
+ missingFields: schedule.missing.length > 0 ? schedule.missing : undefined,
655
+ userQuestion: schedule.missing.length > 0 ? 'What exact ISO time, interval, or cron expression should GoodVibes use?' : undefined,
656
+ });
657
+ }
658
+
659
+ if (asksForAutonomousSchedule && !asksForRoutine) {
660
+ const missingFields = [
661
+ ...schedule.missing,
662
+ 'successCriteria',
663
+ ];
664
+ candidates.push({
665
+ id: 'confirmed-autonomous-schedule',
666
+ label: 'Create one confirmed autonomous Agent schedule',
667
+ confidence: asksForResearch ? 'high' : 'medium',
668
+ why: 'The request asks for recurring Agent work, not just a reminder notification.',
669
+ modelRoute: autonomyScheduleRoute(request, schedule),
670
+ inspectRoute: 'autonomy action:"item" queueItemId:"autonomous-schedule-requests"',
671
+ requiresConfirmation: true,
672
+ missingFields: missingFields.length > 0 ? missingFields : undefined,
673
+ userQuestion: schedule.missing.length > 0
674
+ ? 'What exact cadence and success criteria should this scheduled Agent work use?'
675
+ : 'What should count as a successful scheduled run?',
676
+ });
677
+ }
678
+
679
+ if (asksForRoutine) {
680
+ candidates.push({
681
+ id: 'reviewed-routine-schedule',
682
+ label: 'Promote a reviewed Agent routine to a connected schedule',
683
+ confidence: asksForRoutine ? 'high' : 'medium',
684
+ why: 'The request sounds like recurring agent work rather than a simple reminder.',
685
+ modelRoute: 'workspace action:"actions" categoryId:"routines" query:"promote routine"',
686
+ inspectRoute: 'autonomy action:"item" queueItemId:"routine-schedule-promotions"',
687
+ requiresConfirmation: true,
688
+ missingFields: ['routineId', ...schedule.missing],
689
+ userQuestion: 'Which reviewed routine should run, and what exact cadence should it use?',
690
+ });
691
+ }
692
+
693
+ if (asksForResearch && !scheduled) {
694
+ candidates.push({
695
+ id: 'visible-research-run',
696
+ label: 'Start a visible research run',
697
+ confidence: 'high',
698
+ why: 'The request is research/report oriented and needs a visible ledger before long-running work.',
699
+ modelRoute: 'research action:"create_run" title:"..." question:"..." confirm:true explicitUserRequest:"..."',
700
+ inspectRoute: 'research action:"runs"',
701
+ requiresConfirmation: true,
702
+ missingFields: ['research question', 'success criteria'],
703
+ userQuestion: 'What exact research question and deliverable should be tracked?',
704
+ });
705
+ }
706
+
707
+ if (asksForDelegation) {
708
+ candidates.push({
709
+ id: 'visible-delegation',
710
+ label: 'Delegate isolated build/fix/review work',
711
+ confidence: 'medium',
712
+ why: 'The request asks for implementation work in the background, parallel, or delegated path.',
713
+ modelRoute: 'delegation action:"status"',
714
+ inspectRoute: 'autonomy action:"item" queueItemId:"delegated-subagents"',
715
+ requiresConfirmation: true,
716
+ missingFields: ['task scope', 'repo/worktree target', 'review expectation'],
717
+ userQuestion: 'What exact implementation scope should be delegated, and what result should come back?',
718
+ });
719
+ }
720
+
721
+ if (asksForUnsupportedConnector) {
722
+ candidates.push({
723
+ id: 'connector-setup-first',
724
+ label: 'Set up missing email or calendar connector first',
725
+ confidence: 'medium',
726
+ why: 'The request depends on email/calendar capability, which must be configured before autonomous inbox or agenda work.',
727
+ modelRoute: 'personal_ops action:"lane" laneId:"inbox"',
728
+ inspectRoute: 'personal_ops action:"status"',
729
+ requiresConfirmation: false,
730
+ missingFields: ['configured connector or MCP/plugin route'],
731
+ userQuestion: 'Which configured connector should GoodVibes use for this inbox or calendar work?',
732
+ });
733
+ }
734
+
735
+ if (candidates.length === 0) {
736
+ candidates.push({
737
+ id: 'inspect-visible-autonomy-first',
738
+ label: 'Inspect visible autonomy queue before acting',
739
+ confidence: 'low',
740
+ why: 'The request does not clearly map to a safe autonomous work route yet.',
741
+ modelRoute: 'autonomy action:"queue"',
742
+ inspectRoute: 'autonomy action:"queue"',
743
+ requiresConfirmation: false,
744
+ missingFields: ['goal', 'owner', 'timing', 'success criteria'],
745
+ userQuestion: 'What should run, when should it run, and how should success be reported?',
746
+ });
747
+ }
748
+
749
+ return candidates;
750
+ }
751
+
752
+ export function autonomyIntakeSummary(_context: CommandContext, args: AgentHarnessAutonomyIntakeArgs): Record<string, unknown> {
753
+ const request = readString(args.query) || readString(args.target);
754
+ const watcherContract = watcherEvidenceContract(operatorMethodIds());
755
+ if (!request) {
756
+ const workflows = buildTriggerWorkflows('', { missing: [], notes: [] });
757
+ return {
758
+ status: 'missing_request',
759
+ usage: 'Use autonomy action:"intake" with query:"<ongoing work request>". This action is read-only and returns the safest confirmed route.',
760
+ examples: [
761
+ 'Remind me every 2h to check the deploy.',
762
+ 'Run the weekly operator report as a reviewed routine.',
763
+ 'Cancel the running automation job.',
764
+ ],
765
+ queueRoute: 'autonomy action:"queue"',
766
+ triggerWorkflowSummary: triggerWorkflowSummary(workflows),
767
+ watcherEvidenceContract: compactWatcherEvidenceContract(watcherContract),
768
+ };
769
+ }
770
+ const schedule = detectSchedule(request);
771
+ const candidates = buildCandidates(request);
772
+ const preferred = candidates[0]!;
773
+ const workflows = buildTriggerWorkflows(request, schedule);
774
+ return {
775
+ status: 'ready',
776
+ request: previewHarnessText(request, args.includeParameters === true ? 220 : 120),
777
+ preferred,
778
+ candidates: candidates.slice(0, args.includeParameters === true ? 8 : 4),
779
+ triggerWorkflowSummary: triggerWorkflowSummary(workflows),
780
+ triggerWorkflows: workflows.map((workflow) => describeTriggerWorkflow(workflow, args.includeParameters === true)),
781
+ watcherEvidenceContract: args.includeParameters === true ? watcherContract : compactWatcherEvidenceContract(watcherContract),
782
+ queueRoute: 'autonomy action:"queue"',
783
+ policy: 'Autonomy intake is read-only. It selects visible routes and missing fields; creation, approval, run control, delegation, and delivery still require the returned confirmed route plus explicit user request.',
784
+ };
785
+ }