@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,514 @@
1
+ import { createBrowserGoodVibesSdk } from '@pellux/goodvibes-sdk/browser';
2
+ import type { OperatorMethodInput, OperatorMethodOutput } from '@pellux/goodvibes-sdk/contracts';
3
+ import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
4
+ import { getModelIdFromProviderModel, getProviderIdFromModel } from '../config/provider-model.ts';
5
+ import {
6
+ resolveAgentConnectedHostConnection,
7
+ ROUTINE_SCHEDULE_METHOD,
8
+ ROUTINE_SCHEDULE_ROUTE,
9
+ type AgentConnectedHostConfigReader,
10
+ type AgentConnectedHostConnection,
11
+ type RoutineScheduleDeliveryKind,
12
+ type RoutineScheduleDeliverySurfaceKind,
13
+ type RoutineScheduleDeliveryTargetSpec,
14
+ type RoutineScheduleKind,
15
+ type RoutineScheduleSpec,
16
+ } from './routine-schedule-promotion.ts';
17
+
18
+ type ScheduleCreateInput = OperatorMethodInput<'schedules.create'>;
19
+ type ScheduleCreateOutput = OperatorMethodOutput<'schedules.create'>;
20
+ type ScheduleDeliveryInput = NonNullable<ScheduleCreateInput['delivery']>;
21
+ type ScheduleDeliveryTargetInput = ScheduleDeliveryInput['targets'] extends readonly (infer T)[] ? T : never;
22
+
23
+ export const AUTONOMY_SCHEDULE_METHOD = ROUTINE_SCHEDULE_METHOD;
24
+ export const AUTONOMY_SCHEDULE_ROUTE = ROUTINE_SCHEDULE_ROUTE;
25
+
26
+ export interface ParsedAutonomyScheduleArgs {
27
+ readonly task: string | null;
28
+ readonly successCriteria: string | null;
29
+ readonly schedule: RoutineScheduleSpec | null;
30
+ readonly deliveryTargets: readonly RoutineScheduleDeliveryTargetSpec[];
31
+ readonly name?: string;
32
+ readonly timezone?: string;
33
+ readonly provider?: string;
34
+ readonly model?: string;
35
+ readonly enabled: boolean;
36
+ readonly yes: boolean;
37
+ readonly explicitUserRequest: string | null;
38
+ readonly errors: readonly string[];
39
+ }
40
+
41
+ export interface AutonomySchedulePreview {
42
+ readonly task: string;
43
+ readonly successCriteria: string;
44
+ readonly explicitUserRequest: string;
45
+ readonly route: typeof AUTONOMY_SCHEDULE_ROUTE;
46
+ readonly method: typeof AUTONOMY_SCHEDULE_METHOD;
47
+ readonly payload: ScheduleCreateInput;
48
+ }
49
+
50
+ export interface AutonomyScheduleSuccess {
51
+ readonly ok: true;
52
+ readonly kind: typeof AUTONOMY_SCHEDULE_METHOD;
53
+ readonly route: typeof AUTONOMY_SCHEDULE_ROUTE;
54
+ readonly task: string;
55
+ readonly successCriteria: string;
56
+ readonly schedule: ScheduleCreateOutput;
57
+ readonly request: ScheduleCreateInput;
58
+ }
59
+
60
+ export interface AutonomyScheduleFailure {
61
+ readonly ok: false;
62
+ readonly kind:
63
+ | 'confirmation_required'
64
+ | 'auth_required'
65
+ | 'connected_host_unavailable'
66
+ | 'connected_host_incompatible'
67
+ | 'connected_host_route_unavailable'
68
+ | 'connected_host_error';
69
+ readonly error: string;
70
+ readonly route: typeof AUTONOMY_SCHEDULE_ROUTE;
71
+ readonly baseUrl?: string;
72
+ }
73
+
74
+ export type AutonomyScheduleResult = AutonomyScheduleSuccess | AutonomyScheduleFailure;
75
+
76
+ const DELIVERY_SURFACE_KINDS: readonly RoutineScheduleDeliverySurfaceKind[] = [
77
+ 'tui',
78
+ 'web',
79
+ 'slack',
80
+ 'discord',
81
+ 'ntfy',
82
+ 'webhook',
83
+ 'telegram',
84
+ 'google-chat',
85
+ 'signal',
86
+ 'whatsapp',
87
+ 'telephony',
88
+ 'imessage',
89
+ 'msteams',
90
+ 'bluebubbles',
91
+ 'mattermost',
92
+ 'matrix',
93
+ 'service',
94
+ ];
95
+
96
+ function optionValue(args: readonly string[], index: number, inlineValue: string | undefined): {
97
+ readonly value: string | undefined;
98
+ readonly nextIndex: number;
99
+ } {
100
+ if (inlineValue !== undefined) return { value: inlineValue, nextIndex: index };
101
+ const next = args[index + 1];
102
+ if (next === undefined || next.startsWith('--')) return { value: undefined, nextIndex: index };
103
+ return { value: next, nextIndex: index + 1 };
104
+ }
105
+
106
+ function isDeliverySurfaceKind(value: string): value is RoutineScheduleDeliverySurfaceKind {
107
+ return DELIVERY_SURFACE_KINDS.includes(value as RoutineScheduleDeliverySurfaceKind);
108
+ }
109
+
110
+ function parseChannelDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
111
+ const [surfaceKind = '', routeId, label] = raw.split(':');
112
+ if (!isDeliverySurfaceKind(surfaceKind)) {
113
+ return `Unsupported delivery channel "${surfaceKind}".`;
114
+ }
115
+ return {
116
+ kind: 'surface',
117
+ surfaceKind,
118
+ routeId: routeId?.trim() || undefined,
119
+ label: label?.trim() || undefined,
120
+ };
121
+ }
122
+
123
+ function parseWebhookDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
124
+ const normalized = raw.trim();
125
+ if (!normalized) return '--delivery-webhook requires a URL.';
126
+ try {
127
+ const url = new URL(normalized);
128
+ if (url.protocol !== 'https:' && url.protocol !== 'http:') return '--delivery-webhook must be an http(s) URL.';
129
+ } catch {
130
+ return '--delivery-webhook must be a valid URL.';
131
+ }
132
+ return {
133
+ kind: 'webhook',
134
+ address: normalized,
135
+ };
136
+ }
137
+
138
+ function parseRouteDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
139
+ const [routeId = '', label] = raw.split(':');
140
+ const normalizedRouteId = routeId.trim();
141
+ if (!normalizedRouteId) return '--delivery-route requires a route id.';
142
+ return {
143
+ kind: 'surface',
144
+ routeId: normalizedRouteId,
145
+ label: label?.trim() || undefined,
146
+ };
147
+ }
148
+
149
+ function parseLinkDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
150
+ const normalized = raw.trim();
151
+ if (!normalized) return '--delivery-link requires a URL or label.';
152
+ return {
153
+ kind: 'link',
154
+ address: normalized,
155
+ };
156
+ }
157
+
158
+ function validateDeliveryTargets(targets: readonly RoutineScheduleDeliveryTargetSpec[]): string | null {
159
+ const kinds = new Set(targets.map((target) => target.kind));
160
+ return kinds.size > 1 ? 'Use one delivery target kind per autonomous schedule command.' : null;
161
+ }
162
+
163
+ function normalizeProviderModel(provider: string | undefined, model: string | undefined): {
164
+ readonly provider?: string;
165
+ readonly model?: string;
166
+ } {
167
+ if (!model) return provider ? { provider } : {};
168
+ const normalizedProvider = provider ?? getProviderIdFromModel(model);
169
+ return {
170
+ provider: normalizedProvider,
171
+ model: getModelIdFromProviderModel(model),
172
+ };
173
+ }
174
+
175
+ function deliveryModeFromTargets(targets: readonly RoutineScheduleDeliveryTargetSpec[]): RoutineScheduleDeliveryKind | 'none' {
176
+ const first = targets[0];
177
+ return first ? first.kind : 'none';
178
+ }
179
+
180
+ function toDeliveryTargetInput(target: RoutineScheduleDeliveryTargetSpec): ScheduleDeliveryTargetInput {
181
+ return {
182
+ kind: target.kind,
183
+ surfaceKind: target.surfaceKind as ScheduleDeliveryTargetInput['surfaceKind'],
184
+ address: target.address,
185
+ routeId: target.routeId,
186
+ label: target.label,
187
+ };
188
+ }
189
+
190
+ export function parseAutonomyScheduleArgs(args: readonly string[]): ParsedAutonomyScheduleArgs {
191
+ let task: string | null = null;
192
+ let successCriteria: string | null = null;
193
+ let explicitUserRequest: string | null = null;
194
+ let schedule: RoutineScheduleSpec | null = null;
195
+ const deliveryTargets: RoutineScheduleDeliveryTargetSpec[] = [];
196
+ let name: string | undefined;
197
+ let timezone: string | undefined;
198
+ let provider: string | undefined;
199
+ let model: string | undefined;
200
+ let enabled = true;
201
+ let yes = false;
202
+ const errors: string[] = [];
203
+ const positional: string[] = [];
204
+
205
+ for (let index = 0; index < args.length; index += 1) {
206
+ const raw = args[index] ?? '';
207
+ const equals = raw.indexOf('=');
208
+ const optionName = equals >= 0 ? raw.slice(0, equals) : raw;
209
+ const inlineValue = equals >= 0 ? raw.slice(equals + 1) : undefined;
210
+
211
+ if (raw === '--yes') {
212
+ yes = true;
213
+ continue;
214
+ }
215
+ if (raw === '--disabled') {
216
+ enabled = false;
217
+ continue;
218
+ }
219
+ if (
220
+ optionName === '--task'
221
+ || optionName === '--success-criteria'
222
+ || optionName === '--explicit-user-request'
223
+ || optionName === '--name'
224
+ || optionName === '--timezone'
225
+ || optionName === '--provider'
226
+ || optionName === '--model'
227
+ ) {
228
+ const consumed = optionValue(args, index, inlineValue);
229
+ index = consumed.nextIndex;
230
+ const value = consumed.value?.trim();
231
+ if (!value) {
232
+ errors.push(`${optionName} requires a value.`);
233
+ continue;
234
+ }
235
+ if (optionName === '--task') task = value;
236
+ if (optionName === '--success-criteria') successCriteria = value;
237
+ if (optionName === '--explicit-user-request') explicitUserRequest = value;
238
+ if (optionName === '--name') name = value;
239
+ if (optionName === '--timezone') timezone = value;
240
+ if (optionName === '--provider') provider = value;
241
+ if (optionName === '--model') model = value;
242
+ continue;
243
+ }
244
+ if (optionName === '--cron' || optionName === '--every' || optionName === '--at') {
245
+ const consumed = optionValue(args, index, inlineValue);
246
+ index = consumed.nextIndex;
247
+ const value = consumed.value?.trim();
248
+ if (!value) {
249
+ errors.push(`${optionName} requires a value.`);
250
+ continue;
251
+ }
252
+ if (schedule) {
253
+ errors.push('Choose exactly one schedule selector: --cron, --every, or --at.');
254
+ continue;
255
+ }
256
+ schedule = {
257
+ kind: optionName === '--cron' ? 'cron' : optionName === '--every' ? 'every' : 'at',
258
+ value,
259
+ };
260
+ continue;
261
+ }
262
+ if (optionName === '--delivery-channel' || optionName === '--deliver-channel') {
263
+ const consumed = optionValue(args, index, inlineValue);
264
+ index = consumed.nextIndex;
265
+ const value = consumed.value?.trim();
266
+ if (!value) {
267
+ errors.push(`${optionName} requires a value.`);
268
+ continue;
269
+ }
270
+ const target = parseChannelDeliveryTarget(value);
271
+ if (typeof target === 'string') errors.push(target);
272
+ else deliveryTargets.push(target);
273
+ continue;
274
+ }
275
+ if (optionName === '--delivery-route' || optionName === '--deliver-route') {
276
+ const consumed = optionValue(args, index, inlineValue);
277
+ index = consumed.nextIndex;
278
+ const value = consumed.value?.trim();
279
+ if (!value) {
280
+ errors.push(`${optionName} requires a value.`);
281
+ continue;
282
+ }
283
+ const target = parseRouteDeliveryTarget(value);
284
+ if (typeof target === 'string') errors.push(target);
285
+ else deliveryTargets.push(target);
286
+ continue;
287
+ }
288
+ if (optionName === '--delivery-webhook' || optionName === '--deliver-webhook') {
289
+ const consumed = optionValue(args, index, inlineValue);
290
+ index = consumed.nextIndex;
291
+ const value = consumed.value?.trim();
292
+ if (!value) {
293
+ errors.push(`${optionName} requires a value.`);
294
+ continue;
295
+ }
296
+ const target = parseWebhookDeliveryTarget(value);
297
+ if (typeof target === 'string') errors.push(target);
298
+ else deliveryTargets.push(target);
299
+ continue;
300
+ }
301
+ if (optionName === '--delivery-link' || optionName === '--deliver-link') {
302
+ const consumed = optionValue(args, index, inlineValue);
303
+ index = consumed.nextIndex;
304
+ const value = consumed.value?.trim();
305
+ if (!value) {
306
+ errors.push(`${optionName} requires a value.`);
307
+ continue;
308
+ }
309
+ const target = parseLinkDeliveryTarget(value);
310
+ if (typeof target === 'string') errors.push(target);
311
+ else deliveryTargets.push(target);
312
+ continue;
313
+ }
314
+ if (raw.startsWith('--')) {
315
+ errors.push(`Unknown option ${raw}`);
316
+ continue;
317
+ }
318
+ positional.push(raw);
319
+ }
320
+
321
+ if (!task && positional.length > 0) task = positional.join(' ').trim();
322
+ if (!task) errors.push('Autonomous task is required: use --task <work to perform>.');
323
+ if (!successCriteria) errors.push('Success criteria are required: use --success-criteria <what a good run reports or produces>.');
324
+ if (!explicitUserRequest) errors.push('Explicit user request is required: use --explicit-user-request <authorizing request>.');
325
+ if (!schedule) errors.push('Schedule is required: use --cron <expr>, --every <interval>, or --at <iso-time>.');
326
+ const deliveryError = validateDeliveryTargets(deliveryTargets);
327
+ if (deliveryError) errors.push(deliveryError);
328
+ return { task, successCriteria, schedule, deliveryTargets, name, timezone, provider, model, enabled, yes, explicitUserRequest, errors };
329
+ }
330
+
331
+ export function buildAutonomySchedulePrompt(input: {
332
+ readonly task: string;
333
+ readonly successCriteria: string;
334
+ readonly explicitUserRequest: string;
335
+ }): string {
336
+ return [
337
+ 'GoodVibes Agent autonomous schedule.',
338
+ '',
339
+ 'User request:',
340
+ input.explicitUserRequest,
341
+ '',
342
+ 'Task:',
343
+ input.task,
344
+ '',
345
+ 'Success criteria:',
346
+ input.successCriteria,
347
+ '',
348
+ 'Operator policy:',
349
+ '- Run this as a visible GoodVibes Agent scheduled automation, not a hidden background job.',
350
+ '- Use isolated Agent Knowledge routes only when lookup is needed; never use default knowledge or non-Agent knowledge spaces as fallback.',
351
+ '- Do not perform destructive, costly, externally visible, or secret-handling actions without explicit approval.',
352
+ '- Do not self-expand the scope beyond the task and success criteria; report missing setup or ambiguous requirements instead of improvising.',
353
+ '- Do not request GoodVibes TUI delegation unless this schedule explicitly delegates build/fix/review work and the user asked for that delegation.',
354
+ '- Summarize what was checked, what changed, what still needs review, and the next user-visible action.',
355
+ ].join('\n');
356
+ }
357
+
358
+ export function buildAutonomySchedulePayload(parsed: ParsedAutonomyScheduleArgs): ScheduleCreateInput {
359
+ if (!parsed.task) throw new Error('Autonomous task is required.');
360
+ if (!parsed.successCriteria) throw new Error('Success criteria are required.');
361
+ if (!parsed.explicitUserRequest) throw new Error('Explicit user request is required.');
362
+ if (!parsed.schedule) throw new Error('Schedule is required.');
363
+ const modelRoute = normalizeProviderModel(parsed.provider, parsed.model);
364
+ const payload: ScheduleCreateInput = {
365
+ name: parsed.name ?? `Agent automation: ${parsed.task.slice(0, 48)}`,
366
+ prompt: buildAutonomySchedulePrompt({
367
+ task: parsed.task,
368
+ successCriteria: parsed.successCriteria,
369
+ explicitUserRequest: parsed.explicitUserRequest,
370
+ }),
371
+ kind: parsed.schedule.kind,
372
+ enabled: parsed.enabled,
373
+ target: {
374
+ kind: 'main',
375
+ surfaceKind: 'service',
376
+ preserveThread: true,
377
+ createIfMissing: true,
378
+ },
379
+ delivery: {
380
+ mode: deliveryModeFromTargets(parsed.deliveryTargets),
381
+ targets: parsed.deliveryTargets.map(toDeliveryTargetInput),
382
+ fallbackTargets: [],
383
+ includeSummary: true,
384
+ includeTranscript: false,
385
+ includeLinks: true,
386
+ },
387
+ failure: {
388
+ action: 'retry',
389
+ maxConsecutiveFailures: 3,
390
+ cooldownMs: 3_600_000,
391
+ retryPolicy: {
392
+ maxAttempts: 2,
393
+ delayMs: 60_000,
394
+ strategy: 'exponential',
395
+ maxDelayMs: 900_000,
396
+ jitterMs: 30_000,
397
+ },
398
+ disableAfterFailures: false,
399
+ },
400
+ lightContext: true,
401
+ autoApprove: false,
402
+ allowUnsafeExternalContent: false,
403
+ ...modelRoute,
404
+ };
405
+ if (parsed.schedule.kind === 'cron') {
406
+ return {
407
+ ...payload,
408
+ cron: parsed.schedule.value,
409
+ timezone: parsed.timezone,
410
+ };
411
+ }
412
+ if (parsed.schedule.kind === 'every') {
413
+ return { ...payload, every: parsed.schedule.value };
414
+ }
415
+ return { ...payload, at: parsed.schedule.value };
416
+ }
417
+
418
+ export function buildAutonomySchedulePreview(parsed: ParsedAutonomyScheduleArgs): AutonomySchedulePreview {
419
+ if (!parsed.task) throw new Error('Autonomous task is required.');
420
+ if (!parsed.successCriteria) throw new Error('Success criteria are required.');
421
+ if (!parsed.explicitUserRequest) throw new Error('Explicit user request is required.');
422
+ return {
423
+ task: parsed.task,
424
+ successCriteria: parsed.successCriteria,
425
+ explicitUserRequest: parsed.explicitUserRequest,
426
+ route: AUTONOMY_SCHEDULE_ROUTE,
427
+ method: AUTONOMY_SCHEDULE_METHOD,
428
+ payload: buildAutonomySchedulePayload(parsed),
429
+ };
430
+ }
431
+
432
+ async function fetchConnectedHostStatus(connection: AgentConnectedHostConnection): Promise<{
433
+ readonly ok: boolean;
434
+ readonly status: number;
435
+ readonly body: unknown;
436
+ }> {
437
+ try {
438
+ const response = await fetch(`${connection.baseUrl}/status`, {
439
+ headers: connection.token ? { authorization: `Bearer ${connection.token}` } : undefined,
440
+ });
441
+ const text = await response.text();
442
+ let body: unknown = text;
443
+ try {
444
+ body = text.trim() ? JSON.parse(text) as unknown : {};
445
+ } catch {
446
+ body = text;
447
+ }
448
+ return { ok: response.ok, status: response.status, body };
449
+ } catch (error) {
450
+ return { ok: false, status: 0, body: summarizeError(error) };
451
+ }
452
+ }
453
+
454
+ async function classifyAutonomyScheduleError(
455
+ error: unknown,
456
+ connection: AgentConnectedHostConnection,
457
+ ): Promise<AutonomyScheduleFailure> {
458
+ const message = summarizeError(error);
459
+ const lower = message.toLowerCase();
460
+ if (lower.includes('401') || lower.includes('unauthorized') || lower.includes('auth')) {
461
+ return { ok: false, kind: 'auth_required', error: message, route: AUTONOMY_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
462
+ }
463
+ if (lower.includes('404') || lower.includes('not found')) {
464
+ const connectedHost = await fetchConnectedHostStatus(connection);
465
+ if (connectedHost.ok) {
466
+ return {
467
+ ok: false,
468
+ kind: 'connected_host_incompatible',
469
+ error: 'Connected GoodVibes host compatibility does not satisfy Agent schedule requirements; schedules.create is unavailable.',
470
+ route: AUTONOMY_SCHEDULE_ROUTE,
471
+ baseUrl: connection.baseUrl,
472
+ };
473
+ }
474
+ return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: AUTONOMY_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
475
+ }
476
+ if (lower.includes('fetch') || lower.includes('connect') || lower.includes('econnrefused')) {
477
+ return { ok: false, kind: 'connected_host_unavailable', error: message, route: AUTONOMY_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
478
+ }
479
+ return { ok: false, kind: 'connected_host_error', error: message, route: AUTONOMY_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
480
+ }
481
+
482
+ export async function createAutonomySchedule(
483
+ connection: AgentConnectedHostConnection,
484
+ preview: AutonomySchedulePreview,
485
+ ): Promise<AutonomyScheduleResult> {
486
+ if (!connection.token) {
487
+ return {
488
+ ok: false,
489
+ kind: 'auth_required',
490
+ error: `No connected-host operator token found at ${connection.tokenPath}`,
491
+ route: AUTONOMY_SCHEDULE_ROUTE,
492
+ baseUrl: connection.baseUrl,
493
+ };
494
+ }
495
+ try {
496
+ const sdk = createBrowserGoodVibesSdk({ baseUrl: connection.baseUrl, authToken: connection.token });
497
+ const schedule = await sdk.operator.invoke(AUTONOMY_SCHEDULE_METHOD, preview.payload);
498
+ return {
499
+ ok: true,
500
+ kind: AUTONOMY_SCHEDULE_METHOD,
501
+ route: AUTONOMY_SCHEDULE_ROUTE,
502
+ task: preview.task,
503
+ successCriteria: preview.successCriteria,
504
+ schedule,
505
+ request: preview.payload,
506
+ };
507
+ } catch (error) {
508
+ return classifyAutonomyScheduleError(error, connection);
509
+ }
510
+ }
511
+
512
+ export function resolveAutonomyConnectedHostConnection(configManager: AgentConnectedHostConfigReader, homeDirectory: string): AgentConnectedHostConnection {
513
+ return resolveAgentConnectedHostConnection(configManager, homeDirectory);
514
+ }