@pellux/goodvibes-agent 0.1.117 → 1.0.1

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 +20 -4
  2. package/README.md +35 -14
  3. package/bin/goodvibes-agent.ts +16 -2
  4. package/dist/package/main.js +176093 -171065
  5. package/docs/README.md +11 -5
  6. package/docs/channels-remote-and-api.md +50 -0
  7. package/docs/connected-host.md +3 -3
  8. package/docs/getting-started.md +29 -15
  9. package/docs/knowledge-artifacts-and-multimodal.md +91 -0
  10. package/docs/project-planning.md +79 -0
  11. package/docs/providers-and-routing.md +46 -0
  12. package/docs/release-and-publishing.md +44 -9
  13. package/docs/tools-and-commands.md +123 -0
  14. package/docs/voice-and-live-tts.md +51 -0
  15. package/package.json +2 -5
  16. package/src/agent/channel-delivery.ts +201 -0
  17. package/src/agent/media-generation.ts +159 -0
  18. package/src/agent/memory-prompt.ts +0 -1
  19. package/src/agent/note-registry.ts +329 -0
  20. package/src/agent/operator-actions.ts +343 -0
  21. package/src/agent/persona-registry.ts +15 -14
  22. package/src/agent/record-labels.ts +107 -0
  23. package/src/agent/reminder-schedule-format.ts +33 -24
  24. package/src/agent/reminder-schedule.ts +26 -25
  25. package/src/agent/routine-registry.ts +13 -12
  26. package/src/agent/routine-schedule-args.ts +2 -1
  27. package/src/agent/routine-schedule-format.ts +77 -53
  28. package/src/agent/routine-schedule-promotion.ts +34 -32
  29. package/src/agent/routine-schedule-receipts.ts +28 -26
  30. package/src/agent/runtime-profile-starters.ts +2 -2
  31. package/src/agent/runtime-profile.ts +18 -17
  32. package/src/agent/skill-registry.ts +25 -24
  33. package/src/cli/agent-knowledge-args.ts +5 -1
  34. package/src/cli/agent-knowledge-command.ts +39 -33
  35. package/src/cli/agent-knowledge-format.ts +80 -67
  36. package/src/cli/agent-knowledge-methods.ts +1 -1
  37. package/src/cli/agent-knowledge-runtime.ts +32 -26
  38. package/src/cli/bundle-command.ts +13 -8
  39. package/src/cli/config-overrides.ts +37 -36
  40. package/src/cli/external-runtime.ts +10 -4
  41. package/src/cli/help.ts +29 -11
  42. package/src/cli/local-library-command.ts +159 -73
  43. package/src/cli/management-commands.ts +98 -62
  44. package/src/cli/management.ts +52 -26
  45. package/src/cli/memory-command.ts +66 -32
  46. package/src/cli/parser.ts +37 -24
  47. package/src/cli/profiles-command.ts +52 -35
  48. package/src/cli/provider-auth-routes.ts +2 -1
  49. package/src/cli/routines-command.ts +59 -39
  50. package/src/cli/service-posture.ts +6 -6
  51. package/src/cli/status.ts +46 -121
  52. package/src/core/conversation-message-snapshot.ts +131 -0
  53. package/src/input/agent-workspace-activation.ts +33 -7
  54. package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
  55. package/src/input/agent-workspace-basic-command-editors.ts +30 -10
  56. package/src/input/agent-workspace-categories.ts +276 -64
  57. package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
  58. package/src/input/agent-workspace-channel-command-editors.ts +23 -5
  59. package/src/input/agent-workspace-channels.ts +35 -2
  60. package/src/input/agent-workspace-command-editor.ts +18 -2
  61. package/src/input/agent-workspace-config-reader.ts +16 -0
  62. package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
  63. package/src/input/agent-workspace-editors.ts +140 -2
  64. package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
  65. package/src/input/agent-workspace-knowledge-url-editor.ts +4 -11
  66. package/src/input/agent-workspace-learned-behavior.ts +2 -2
  67. package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
  68. package/src/input/agent-workspace-library-command-editors.ts +2 -2
  69. package/src/input/agent-workspace-local-operations.ts +218 -0
  70. package/src/input/agent-workspace-local-selection.ts +75 -0
  71. package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
  72. package/src/input/agent-workspace-media-command-editors.ts +27 -0
  73. package/src/input/agent-workspace-memory-command-editors.ts +1 -1
  74. package/src/input/agent-workspace-memory-editor.ts +2 -2
  75. package/src/input/agent-workspace-navigation.ts +38 -2
  76. package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
  77. package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
  78. package/src/input/agent-workspace-operations-command-editors.ts +80 -3
  79. package/src/input/agent-workspace-panel-route.ts +43 -0
  80. package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
  81. package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
  82. package/src/input/agent-workspace-search.ts +169 -0
  83. package/src/input/agent-workspace-setup.ts +22 -11
  84. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
  85. package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
  86. package/src/input/agent-workspace-snapshot.ts +112 -13
  87. package/src/input/agent-workspace-task-command-editors.ts +4 -4
  88. package/src/input/agent-workspace-token.ts +18 -2
  89. package/src/input/agent-workspace-types.ts +92 -4
  90. package/src/input/agent-workspace-voice-media.ts +3 -6
  91. package/src/input/agent-workspace-web-research-editor.ts +104 -0
  92. package/src/input/agent-workspace.ts +136 -208
  93. package/src/input/command-registry.ts +4 -1
  94. package/src/input/commands/agent-local-library-args.ts +52 -0
  95. package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
  96. package/src/input/commands/agent-skills-runtime.ts +87 -99
  97. package/src/input/commands/agent-workspace-runtime.ts +23 -7
  98. package/src/input/commands/brief-runtime.ts +25 -24
  99. package/src/input/commands/channels-runtime.ts +145 -31
  100. package/src/input/commands/delegation-runtime.ts +29 -23
  101. package/src/input/commands/experience-runtime.ts +6 -4
  102. package/src/input/commands/guidance-runtime.ts +4 -4
  103. package/src/input/commands/health-runtime.ts +140 -115
  104. package/src/input/commands/knowledge.ts +57 -56
  105. package/src/input/commands/local-provider-runtime.ts +36 -18
  106. package/src/input/commands/local-runtime.ts +138 -16
  107. package/src/input/commands/local-setup-review.ts +7 -7
  108. package/src/input/commands/mcp-runtime.ts +118 -50
  109. package/src/input/commands/notify-runtime.ts +38 -9
  110. package/src/input/commands/operator-actions-runtime.ts +138 -0
  111. package/src/input/commands/operator-runtime.ts +6 -17
  112. package/src/input/commands/personas-runtime.ts +49 -59
  113. package/src/input/commands/planning-runtime.ts +1 -1
  114. package/src/input/commands/platform-access-runtime.ts +29 -29
  115. package/src/input/commands/provider-accounts-runtime.ts +60 -39
  116. package/src/input/commands/qrcode-runtime.ts +45 -6
  117. package/src/input/commands/recall-bundle.ts +11 -11
  118. package/src/input/commands/recall-capture.ts +13 -11
  119. package/src/input/commands/recall-query.ts +29 -21
  120. package/src/input/commands/recall-review.ts +2 -1
  121. package/src/input/commands/routines-runtime.ts +63 -72
  122. package/src/input/commands/schedule-runtime.ts +33 -20
  123. package/src/input/commands/security-runtime.ts +4 -4
  124. package/src/input/commands/session-content.ts +80 -78
  125. package/src/input/commands/session-workflow.ts +132 -93
  126. package/src/input/commands/session.ts +3 -174
  127. package/src/input/commands/shell-core.ts +32 -17
  128. package/src/input/commands/subscription-runtime.ts +53 -179
  129. package/src/input/commands/tasks-runtime.ts +20 -20
  130. package/src/input/commands/work-plan-runtime.ts +33 -8
  131. package/src/input/commands.ts +2 -2
  132. package/src/input/feed-context-factory.ts +2 -1
  133. package/src/input/file-picker.ts +3 -2
  134. package/src/input/handler-command-route.ts +4 -7
  135. package/src/input/handler-content-actions.ts +89 -1
  136. package/src/input/handler-feed-routes.ts +19 -12
  137. package/src/input/handler-feed.ts +6 -3
  138. package/src/input/handler-interactions.ts +7 -5
  139. package/src/input/handler-modal-stack.ts +3 -3
  140. package/src/input/handler-onboarding.ts +24 -80
  141. package/src/input/handler-shortcuts.ts +15 -4
  142. package/src/input/handler.ts +47 -17
  143. package/src/input/input-history.ts +5 -6
  144. package/src/input/keybindings.ts +22 -11
  145. package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
  146. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
  147. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
  148. package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
  149. package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
  150. package/src/input/onboarding/onboarding-wizard.ts +68 -0
  151. package/src/input/profile-picker-modal.ts +31 -12
  152. package/src/input/session-picker-modal.ts +22 -4
  153. package/src/input/settings-modal-behavior.ts +0 -3
  154. package/src/input/settings-modal-subscriptions.ts +3 -3
  155. package/src/input/settings-modal-types.ts +2 -13
  156. package/src/input/settings-modal.ts +6 -52
  157. package/src/input/submission-intent.ts +0 -1
  158. package/src/input/submission-router.ts +3 -3
  159. package/src/main.ts +18 -8
  160. package/src/panels/approval-panel.ts +8 -8
  161. package/src/panels/automation-control-panel.ts +2 -2
  162. package/src/panels/base-panel.ts +1 -1
  163. package/src/panels/builtin/agent.ts +1 -1
  164. package/src/panels/builtin/operations.ts +1 -10
  165. package/src/panels/builtin/session.ts +9 -9
  166. package/src/panels/builtin/shared.ts +2 -2
  167. package/src/panels/cost-tracker-panel.ts +1 -1
  168. package/src/panels/docs-panel.ts +5 -3
  169. package/src/panels/index.ts +0 -1
  170. package/src/panels/knowledge-panel.ts +6 -5
  171. package/src/panels/memory-panel.ts +7 -6
  172. package/src/panels/panel-list-panel.ts +36 -80
  173. package/src/panels/project-planning-panel.ts +18 -11
  174. package/src/panels/provider-account-snapshot.ts +51 -25
  175. package/src/panels/provider-accounts-panel.ts +33 -18
  176. package/src/panels/provider-health-domains.ts +45 -4
  177. package/src/panels/provider-health-panel.ts +5 -4
  178. package/src/panels/qr-panel.ts +1 -1
  179. package/src/panels/schedule-panel.ts +9 -17
  180. package/src/panels/security-panel.ts +8 -8
  181. package/src/panels/session-browser-panel.ts +10 -10
  182. package/src/panels/subscription-panel.ts +3 -3
  183. package/src/panels/system-messages-panel.ts +1 -1
  184. package/src/panels/tasks-panel.ts +20 -13
  185. package/src/panels/tool-inspector-panel.ts +19 -12
  186. package/src/panels/work-plan-panel.ts +5 -5
  187. package/src/planning/project-planning-coordinator.ts +1 -1
  188. package/src/provider-auth-route-display.ts +9 -0
  189. package/src/renderer/agent-workspace-style.ts +34 -0
  190. package/src/renderer/agent-workspace.ts +228 -52
  191. package/src/renderer/autocomplete-overlay.ts +25 -6
  192. package/src/renderer/bookmark-modal.ts +19 -4
  193. package/src/renderer/buffer.ts +4 -2
  194. package/src/renderer/context-inspector.ts +50 -13
  195. package/src/renderer/diff.ts +1 -1
  196. package/src/renderer/file-picker-overlay.ts +19 -6
  197. package/src/renderer/help-overlay.ts +106 -33
  198. package/src/renderer/history-search-overlay.ts +19 -4
  199. package/src/renderer/live-tail-modal.ts +27 -5
  200. package/src/renderer/mcp-workspace.ts +164 -50
  201. package/src/renderer/model-picker-overlay.ts +58 -2
  202. package/src/renderer/model-workspace.ts +104 -20
  203. package/src/renderer/process-modal.ts +27 -6
  204. package/src/renderer/profile-picker-modal.ts +20 -4
  205. package/src/renderer/search-overlay.ts +25 -5
  206. package/src/renderer/selection-modal-overlay.ts +46 -14
  207. package/src/renderer/session-picker-modal.ts +18 -1
  208. package/src/renderer/settings-modal-helpers.ts +2 -40
  209. package/src/renderer/settings-modal.ts +83 -50
  210. package/src/renderer/tool-call.ts +20 -11
  211. package/src/runtime/agent-runtime-events.ts +6 -6
  212. package/src/runtime/bootstrap-command-context.ts +7 -1
  213. package/src/runtime/bootstrap-command-parts.ts +9 -7
  214. package/src/runtime/bootstrap-core.ts +19 -1
  215. package/src/runtime/bootstrap-hook-bridge.ts +7 -18
  216. package/src/runtime/bootstrap-shell.ts +4 -4
  217. package/src/runtime/bootstrap.ts +31 -22
  218. package/src/runtime/connected-host-auth.ts +7 -2
  219. package/src/runtime/diagnostics/panels/index.ts +2 -2
  220. package/src/runtime/diagnostics/panels/policy.ts +7 -7
  221. package/src/runtime/index.ts +2 -1
  222. package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
  223. package/src/runtime/onboarding/apply.ts +80 -79
  224. package/src/runtime/onboarding/derivation.ts +5 -8
  225. package/src/runtime/onboarding/snapshot.ts +0 -15
  226. package/src/runtime/onboarding/types.ts +8 -19
  227. package/src/runtime/onboarding/verify.ts +32 -10
  228. package/src/runtime/operator-token-cleanup.ts +1 -1
  229. package/src/runtime/services.ts +91 -22
  230. package/src/runtime/store/selectors/index.ts +3 -3
  231. package/src/runtime/store/state.ts +1 -4
  232. package/src/runtime/surface-feature-flags.ts +41 -6
  233. package/src/runtime/ui-read-models.ts +3 -4
  234. package/src/runtime/ui-services.ts +6 -6
  235. package/src/shell/blocking-input.ts +2 -1
  236. package/src/shell/ui-openers.ts +3 -13
  237. package/src/tools/agent-analysis-registry-policy.ts +0 -1
  238. package/src/tools/agent-channel-send-tool.ts +133 -0
  239. package/src/tools/agent-context-policy.ts +1 -1
  240. package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
  241. package/src/tools/agent-knowledge-tool.ts +170 -0
  242. package/src/tools/agent-local-registry-tool.ts +269 -69
  243. package/src/tools/agent-media-generate-tool.ts +133 -0
  244. package/src/tools/agent-notify-tool.ts +143 -0
  245. package/src/tools/agent-operator-action-tool.ts +137 -0
  246. package/src/tools/agent-operator-briefing-tool.ts +217 -0
  247. package/src/tools/agent-reminder-schedule-tool.ts +237 -0
  248. package/src/tools/agent-tool-policy-guard.ts +8 -8
  249. package/src/tools/agent-work-plan-tool.ts +256 -0
  250. package/src/version.ts +1 -1
  251. package/src/input/commands/policy-dispatch.ts +0 -339
  252. package/src/input/commands/policy.ts +0 -13
  253. package/src/panels/panel-picker.ts +0 -105
  254. package/src/panels/policy-panel.ts +0 -308
  255. package/src/renderer/panel-picker-overlay.ts +0 -202
@@ -23,6 +23,30 @@ function formatDeliveryTargetKind(target: { readonly kind?: string; readonly sur
23
23
  return `${target.kind ?? 'unknown'}${target.surfaceKind ? `/${target.surfaceKind}` : ''}`;
24
24
  }
25
25
 
26
+ function formatDeliveryTarget(target: {
27
+ readonly kind?: string;
28
+ readonly surfaceKind?: string;
29
+ readonly routeId?: string;
30
+ readonly address?: string;
31
+ readonly label?: string;
32
+ }): string {
33
+ const details = [
34
+ target.routeId ? `route=${target.routeId}` : '',
35
+ target.address ? `address=${target.address}` : '',
36
+ target.label ? `label=${target.label}` : '',
37
+ ].filter(Boolean);
38
+ return `${formatDeliveryTargetKind(target)}${details.length > 0 ? ` ${details.join(' ')}` : ''}`;
39
+ }
40
+
41
+ function formatRoutineScheduleFailureKind(kind: string): string {
42
+ if (kind === 'auth_required') return 'authorization required';
43
+ if (kind === 'connected_host_unavailable') return 'connected host unavailable';
44
+ if (kind === 'connected_host_route_unavailable') return 'connected host route unavailable';
45
+ if (kind === 'connected_host_error') return 'connected host error';
46
+ if (kind === 'version_mismatch') return 'version mismatch';
47
+ return kind.replace(/[_-]+/g, ' ');
48
+ }
49
+
26
50
  export function formatRoutineSchedulePreview(preview: RoutineSchedulePromotionPreview): string {
27
51
  const schedule = preview.payload.kind === 'cron'
28
52
  ? `${preview.payload.cron}${preview.payload.timezone ? ` [${preview.payload.timezone}]` : ''}`
@@ -33,15 +57,15 @@ export function formatRoutineSchedulePreview(preview: RoutineSchedulePromotionPr
33
57
  const deliveryTargetCount = delivery?.targets.length ?? 0;
34
58
  return [
35
59
  'GoodVibes schedule preview for Agent routine',
36
- ` routine: ${preview.routineName} (${preview.routineId})`,
37
- ` route: ${preview.method} ${preview.route}`,
38
- ` name: ${String(preview.payload.name ?? '(runtime default)')}`,
39
- ` schedule: ${preview.payload.kind} ${schedule}`,
40
- ` enabled: ${preview.payload.enabled === false ? 'no' : 'yes'}`,
60
+ ` routine ${preview.routineName} (${preview.routineId})`,
61
+ ` route ${preview.method} ${preview.route}`,
62
+ ` name ${String(preview.payload.name ?? '(connected-host default)')}`,
63
+ ` schedule ${preview.payload.kind} ${schedule}`,
64
+ ` enabled ${preview.payload.enabled === false ? 'no' : 'yes'}`,
41
65
  ` delivery: ${delivery?.mode ?? 'none'}${deliveryTargetCount > 0 ? ` (${deliveryTargetCount} target${deliveryTargetCount === 1 ? '' : 's'})` : ''}`,
42
- ' target: GoodVibes runtime/main conversation route',
43
- ' policy: isolated Agent Knowledge only; no default wiki/non-Agent fallback; no WRFC unless explicitly delegated',
44
- ' next: rerun with --yes to create this connected schedule',
66
+ ' target connected GoodVibes host/main conversation route',
67
+ ' policy isolated Agent Knowledge only; no default knowledge/non-Agent fallback; no delegated review unless explicitly requested',
68
+ ' next rerun with --yes to create this connected schedule',
45
69
  ].join('\n');
46
70
  }
47
71
 
@@ -51,11 +75,11 @@ export function formatRoutineScheduleSuccess(result: RoutineSchedulePromotionSuc
51
75
  const status = readString(record, 'status') ?? (record.enabled === false ? 'paused' : 'enabled');
52
76
  return [
53
77
  'Created GoodVibes schedule for Agent routine',
54
- ` routine: ${result.routineName} (${result.routineId})`,
55
- ` schedule: ${id}`,
56
- ` status: ${status}`,
57
- ` route: ${result.kind} ${result.route}`,
58
- ' next: inspect with /schedule list or schedule observability',
78
+ ` routine ${result.routineName} (${result.routineId})`,
79
+ ` schedule ${id}`,
80
+ ` status ${status}`,
81
+ ` route ${result.kind} ${result.route}`,
82
+ ' next inspect with /schedule list or schedule observability',
59
83
  ].join('\n');
60
84
  }
61
85
 
@@ -64,18 +88,18 @@ export function formatRoutineScheduleReceipts(snapshot: RoutineScheduleReceiptSn
64
88
  if (snapshot.receipts.length === 0) {
65
89
  return [
66
90
  'Agent routine schedule receipts',
67
- ` store: ${snapshot.path}`,
91
+ ` store ${snapshot.path}`,
68
92
  ' No routine schedule promotions have been recorded yet.',
69
93
  ' Create one with /schedule promote-routine <routine-id> --cron <expr> --yes.',
70
94
  ].join('\n');
71
95
  }
72
96
  return [
73
97
  `Agent routine schedule receipts (${snapshot.receipts.length})`,
74
- ` store: ${snapshot.path}`,
98
+ ` store ${snapshot.path}`,
75
99
  ...receipts.map((receipt) => {
76
100
  const schedule = receipt.scheduleId ? ` schedule=${receipt.scheduleId}` : '';
77
- const failure = receipt.status === 'failed' && receipt.failureKind ? ` failure=${receipt.failureKind}` : '';
78
- return ` ${receipt.id} ${receipt.status} ${receipt.scheduleKind} ${receipt.scheduleValue} routine=${receipt.routineId}${schedule}${failure}`;
101
+ const failure = receipt.status === 'failed' && receipt.failureKind ? ` failure ${formatRoutineScheduleFailureKind(receipt.failureKind)}` : '';
102
+ return ` ${receipt.id} ${receipt.status} ${receipt.scheduleKind} ${receipt.scheduleValue} routine ${receipt.routineId}${schedule}${failure}`;
79
103
  }),
80
104
  snapshot.receipts.length > receipts.length ? ` ...${snapshot.receipts.length - receipts.length} more` : '',
81
105
  ].filter((line): line is string => Boolean(line)).join('\n');
@@ -84,20 +108,20 @@ export function formatRoutineScheduleReceipts(snapshot: RoutineScheduleReceiptSn
84
108
  export function formatRoutineScheduleReceipt(receipt: RoutineScheduleReceipt): string {
85
109
  return [
86
110
  `Agent routine schedule receipt ${receipt.id}`,
87
- ` created: ${receipt.createdAt}`,
88
- ` status: ${receipt.status}`,
89
- ` routine: ${receipt.routineName} (${receipt.routineId})`,
90
- ` route: ${receipt.method} ${receipt.route}`,
91
- ` runtime: ${receipt.daemonBaseUrl}`,
92
- ` schedule: ${receipt.scheduleName}${receipt.scheduleId ? ` (${receipt.scheduleId})` : ''}`,
93
- receipt.scheduleStatus ? ` schedule status: ${receipt.scheduleStatus}` : '',
111
+ ` created ${receipt.createdAt}`,
112
+ ` status ${receipt.status}`,
113
+ ` routine ${receipt.routineName} (${receipt.routineId})`,
114
+ ` route ${receipt.method} ${receipt.route}`,
115
+ ` connected host: ${receipt.connectedHostBaseUrl}`,
116
+ ` schedule ${receipt.scheduleName}${receipt.scheduleId ? ` (${receipt.scheduleId})` : ''}`,
117
+ receipt.scheduleStatus ? ` schedule status ${receipt.scheduleStatus}` : '',
94
118
  ` cadence: ${receipt.scheduleKind} ${receipt.scheduleValue}${receipt.timezone ? ` [${receipt.timezone}]` : ''}`,
95
- ` enabled: ${receipt.enabled ? 'yes' : 'no'}`,
96
- receipt.provider ? ` provider: ${receipt.provider}` : '',
97
- receipt.model ? ` model: ${receipt.model}` : '',
98
- ` target: ${formatDeliveryTargetKind(receipt.target)}`,
119
+ ` enabled ${receipt.enabled ? 'yes' : 'no'}`,
120
+ receipt.provider ? ` provider ${receipt.provider}` : '',
121
+ receipt.model ? ` model ${receipt.model}` : '',
122
+ ` target ${formatDeliveryTargetKind(receipt.target)}`,
99
123
  receipt.deliveryMode ? ` delivery: ${receipt.deliveryMode}` : '',
100
- ...(receipt.deliveryTargets ?? []).map((target) => ` delivery target: ${formatDeliveryTargetKind(target)}${target.routeId ? ` route=${target.routeId}` : ''}${target.address ? ` address=${target.address}` : ''}${target.label ? ` label=${target.label}` : ''}`),
124
+ ...(receipt.deliveryTargets ?? []).map((target) => ` delivery target: ${formatDeliveryTarget(target)}`),
101
125
  receipt.failureKind ? ` failure: ${receipt.failureKind}` : '',
102
126
  receipt.failureError ? ` error: ${receipt.failureError}` : '',
103
127
  ].filter((line): line is string => Boolean(line)).join('\n');
@@ -106,18 +130,18 @@ export function formatRoutineScheduleReceipt(receipt: RoutineScheduleReceipt): s
106
130
  export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelationResult, limit = 10): string {
107
131
  if (!result.ok) {
108
132
  return [
109
- `GoodVibes schedule reconciliation error: ${result.kind}`,
133
+ `GoodVibes schedule reconciliation error ${formatRoutineScheduleFailureKind(result.kind)}`,
110
134
  ` ${result.error}`,
111
- result.baseUrl ? ` runtime: ${result.baseUrl}` : null,
112
- ` route: ${ROUTINE_SCHEDULE_LIST_METHOD} ${result.route}`,
135
+ result.baseUrl ? ` connected host ${result.baseUrl}` : null,
136
+ ` route ${ROUTINE_SCHEDULE_LIST_METHOD} ${result.route}`,
113
137
  result.kind === 'auth_required'
114
- ? ' next: pair/authenticate with the connected GoodVibes host, then retry.'
138
+ ? ' next pair/authenticate with the connected GoodVibes host, then retry.'
115
139
  : null,
116
- result.kind === 'daemon_unavailable'
117
- ? ' next: make the connected GoodVibes host available outside Agent, then retry.'
140
+ result.kind === 'connected_host_unavailable'
141
+ ? ' next make the connected GoodVibes host available outside Agent, then retry.'
118
142
  : null,
119
- result.kind === 'version_mismatch' || result.kind === 'daemon_route_unavailable'
120
- ? ' next: update the connected GoodVibes host so public schedules.list is available.'
143
+ result.kind === 'version_mismatch' || result.kind === 'connected_host_route_unavailable'
144
+ ? ' next update the connected GoodVibes host so public schedules.list is available.'
121
145
  : null,
122
146
  ].filter((line): line is string => Boolean(line)).join('\n');
123
147
  }
@@ -125,7 +149,7 @@ export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelat
125
149
  if (result.receiptCount === 0) {
126
150
  return [
127
151
  'Agent routine schedule reconciliation',
128
- ` runtime: ${result.baseUrl}`,
152
+ ` connected host: ${result.baseUrl}`,
129
153
  ` route: ${result.kind} ${result.route}`,
130
154
  ` live schedules: ${result.scheduleCount}`,
131
155
  ' No local routine promotion receipts exist yet.',
@@ -137,20 +161,20 @@ export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelat
137
161
  const failed = result.correlations.filter((entry) => entry.liveStatus === 'failed-receipt').length;
138
162
  return [
139
163
  'Agent routine schedule reconciliation',
140
- ` runtime: ${result.baseUrl}`,
164
+ ` connected host: ${result.baseUrl}`,
141
165
  ` route: ${result.kind} ${result.route}`,
142
166
  ` receipts: ${result.receiptCount}; live schedules: ${result.scheduleCount}; matched: ${matched}; missing: ${missing}; failed receipts: ${failed}`,
143
167
  ...correlations.map((entry) => {
144
168
  const receipt = entry.receipt;
145
169
  const schedule = entry.schedule;
146
170
  const live = schedule
147
- ? ` live=${schedule.id} status=${schedule.status ?? (schedule.enabled === false ? 'paused' : 'enabled')}`
171
+ ? ` live=${schedule.id}; status ${schedule.status ?? (schedule.enabled === false ? 'paused' : 'enabled')}`
148
172
  : '';
149
173
  const runs = schedule && schedule.runCount !== undefined
150
- ? ` runs=${schedule.runCount}/${schedule.successCount ?? 0}/${schedule.failureCount ?? 0}`
174
+ ? ` runs ${schedule.runCount}/${schedule.successCount ?? 0}/${schedule.failureCount ?? 0}`
151
175
  : '';
152
- const next = schedule?.nextRunAt ? ` next=${new Date(schedule.nextRunAt).toISOString()}` : '';
153
- return ` ${receipt.id} ${entry.liveStatus} reason=${entry.matchReason} routine=${receipt.routineId} receiptSchedule=${receipt.scheduleId ?? '(none)'}${live}${runs}${next}`;
176
+ const next = schedule?.nextRunAt ? ` next ${new Date(schedule.nextRunAt).toISOString()}` : '';
177
+ return ` ${receipt.id} ${entry.liveStatus} reason ${entry.matchReason} routine ${receipt.routineId} receipt schedule ${receipt.scheduleId ?? '(none)'}${live}${runs}${next}`;
154
178
  }),
155
179
  result.correlations.length > correlations.length ? ` ...${result.correlations.length - correlations.length} more` : '',
156
180
  ].filter((line): line is string => Boolean(line)).join('\n');
@@ -158,21 +182,21 @@ export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelat
158
182
 
159
183
  export function formatRoutineScheduleFailure(failure: RoutineSchedulePromotionFailure): string {
160
184
  return [
161
- `GoodVibes schedule error: ${failure.kind}`,
185
+ `GoodVibes schedule error ${formatRoutineScheduleFailureKind(failure.kind)}`,
162
186
  ` ${failure.error}`,
163
- failure.baseUrl ? ` runtime: ${failure.baseUrl}` : null,
164
- ` route: ${ROUTINE_SCHEDULE_METHOD} ${failure.route}`,
165
- failure.kind === 'version_mismatch' && failure.daemonVersion && failure.expectedSdkVersion
166
- ? ` versions: runtime=${failure.daemonVersion} expected=${failure.expectedSdkVersion}`
187
+ failure.baseUrl ? ` connected host ${failure.baseUrl}` : null,
188
+ ` route ${ROUTINE_SCHEDULE_METHOD} ${failure.route}`,
189
+ failure.kind === 'version_mismatch' && failure.connectedHostVersion && failure.expectedSdkVersion
190
+ ? ` versions connected host ${failure.connectedHostVersion}; expected ${failure.expectedSdkVersion}`
167
191
  : null,
168
192
  failure.kind === 'auth_required'
169
- ? ' next: pair/authenticate with the connected GoodVibes host, then retry with --yes.'
193
+ ? ' next pair/authenticate with the connected GoodVibes host, then retry with --yes.'
170
194
  : null,
171
- failure.kind === 'daemon_unavailable'
172
- ? ' next: make the connected GoodVibes host available outside Agent, then retry.'
195
+ failure.kind === 'connected_host_unavailable'
196
+ ? ' next make the connected GoodVibes host available outside Agent, then retry.'
173
197
  : null,
174
- failure.kind === 'version_mismatch' || failure.kind === 'daemon_route_unavailable'
175
- ? ' next: update the connected GoodVibes host so public schedules.create is available.'
198
+ failure.kind === 'version_mismatch' || failure.kind === 'connected_host_route_unavailable'
199
+ ? ' next update the connected GoodVibes host so public schedules.create is available.'
176
200
  : null,
177
201
  ].filter((line): line is string => Boolean(line)).join('\n');
178
202
  }
@@ -5,6 +5,7 @@ import type { OperatorMethodInput, OperatorMethodOutput } from '@pellux/goodvibe
5
5
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
6
6
  import { getModelIdFromProviderModel, getProviderIdFromModel } from '../config/provider-model.ts';
7
7
  import { SDK_VERSION } from '../version.ts';
8
+ import { formatAgentRecordReviewState } from './record-labels.ts';
8
9
  import type { AgentRoutineRecord } from './routine-registry.ts';
9
10
 
10
11
  export const ROUTINE_SCHEDULE_ROUTE = '/api/automation/schedules';
@@ -16,11 +17,11 @@ type ScheduleCreateOutput = OperatorMethodOutput<'schedules.create'>;
16
17
  type ScheduleDeliveryInput = NonNullable<ScheduleCreateInput['delivery']>;
17
18
  type ScheduleDeliveryTargetInput = ScheduleDeliveryInput['targets'] extends readonly (infer T)[] ? T : never;
18
19
 
19
- export interface AgentDaemonConfigReader {
20
+ export interface AgentConnectedHostConfigReader {
20
21
  get(key: string): unknown;
21
22
  }
22
23
 
23
- export interface AgentDaemonConnection {
24
+ export interface AgentConnectedHostConnection {
24
25
  readonly baseUrl: string;
25
26
  readonly token: string | null;
26
27
  readonly tokenPath: string;
@@ -46,6 +47,7 @@ export type RoutineScheduleDeliverySurfaceKind =
46
47
  | 'google-chat'
47
48
  | 'signal'
48
49
  | 'whatsapp'
50
+ | 'telephony'
49
51
  | 'imessage'
50
52
  | 'msteams'
51
53
  | 'bluebubbles'
@@ -105,14 +107,14 @@ export interface RoutineSchedulePromotionFailure {
105
107
  readonly kind:
106
108
  | 'confirmation_required'
107
109
  | 'auth_required'
108
- | 'daemon_unavailable'
110
+ | 'connected_host_unavailable'
109
111
  | 'version_mismatch'
110
- | 'daemon_route_unavailable'
111
- | 'daemon_error';
112
+ | 'connected_host_route_unavailable'
113
+ | 'connected_host_error';
112
114
  readonly error: string;
113
115
  readonly route: typeof ROUTINE_SCHEDULE_ROUTE;
114
116
  readonly baseUrl?: string;
115
- readonly daemonVersion?: string;
117
+ readonly connectedHostVersion?: string;
116
118
  readonly expectedSdkVersion?: string;
117
119
  }
118
120
 
@@ -128,7 +130,7 @@ export interface RoutineScheduleReceipt {
128
130
  readonly route: typeof ROUTINE_SCHEDULE_ROUTE;
129
131
  readonly method: typeof ROUTINE_SCHEDULE_METHOD;
130
132
  readonly status: 'created' | 'failed';
131
- readonly daemonBaseUrl: string;
133
+ readonly connectedHostBaseUrl: string;
132
134
  readonly scheduleId?: string;
133
135
  readonly scheduleStatus?: string;
134
136
  readonly scheduleName: string;
@@ -191,14 +193,14 @@ export interface RoutineScheduleCorrelationFailure {
191
193
  readonly ok: false;
192
194
  readonly kind:
193
195
  | 'auth_required'
194
- | 'daemon_unavailable'
196
+ | 'connected_host_unavailable'
195
197
  | 'version_mismatch'
196
- | 'daemon_route_unavailable'
197
- | 'daemon_error';
198
+ | 'connected_host_route_unavailable'
199
+ | 'connected_host_error';
198
200
  readonly error: string;
199
201
  readonly route: typeof ROUTINE_SCHEDULE_ROUTE;
200
202
  readonly baseUrl?: string;
201
- readonly daemonVersion?: string;
203
+ readonly connectedHostVersion?: string;
202
204
  readonly expectedSdkVersion?: string;
203
205
  }
204
206
 
@@ -236,17 +238,17 @@ function deliveryModeFromTargets(targets: readonly RoutineScheduleDeliveryTarget
236
238
  function toDeliveryTargetInput(target: RoutineScheduleDeliveryTargetSpec): ScheduleDeliveryTargetInput {
237
239
  return {
238
240
  kind: target.kind,
239
- surfaceKind: target.surfaceKind,
241
+ surfaceKind: target.surfaceKind as ScheduleDeliveryTargetInput['surfaceKind'],
240
242
  address: target.address,
241
243
  routeId: target.routeId,
242
244
  label: target.label,
243
245
  };
244
246
  }
245
247
 
246
- export function resolveAgentDaemonConnection(
247
- configManager: AgentDaemonConfigReader,
248
+ export function resolveAgentConnectedHostConnection(
249
+ configManager: AgentConnectedHostConfigReader,
248
250
  homeDirectory: string,
249
- ): AgentDaemonConnection {
251
+ ): AgentConnectedHostConnection {
250
252
  const host = String(configManager.get('controlPlane.host') ?? '127.0.0.1');
251
253
  const port = Number(configManager.get('controlPlane.port') ?? 3421);
252
254
  const tokenPath = join(homeDirectory, '.goodvibes', 'daemon', 'operator-tokens.json');
@@ -265,16 +267,16 @@ export function buildRoutineSchedulePrompt(routine: AgentRoutineRecord): string
265
267
  'GoodVibes Agent scheduled routine.',
266
268
  '',
267
269
  `Routine: ${routine.name}`,
268
- `Routine id: ${routine.id}`,
269
- `Review state: ${routine.reviewState}`,
270
+ `Routine reference: ${routine.id}`,
271
+ `Review: ${formatAgentRecordReviewState(routine.reviewState)}`,
270
272
  `Tags: ${routine.tags.join(', ') || '(none)'}`,
271
273
  `Triggers: ${routine.triggers.join(', ') || '(manual)'}`,
272
274
  '',
273
275
  'Operator policy:',
274
276
  '- Run this as a serial GoodVibes Agent operator routine.',
275
- '- Use isolated Agent Knowledge routes only; never use default Knowledge/Wiki or non-Agent knowledge spaces as fallback.',
277
+ '- Use isolated Agent Knowledge routes only; never use default knowledge or non-Agent knowledge spaces as fallback.',
276
278
  '- Do not perform destructive, costly, externally visible, or secret-handling actions without explicit approval.',
277
- '- Do not request WRFC unless this scheduled routine explicitly delegates build/fix/review work to GoodVibes TUI.',
279
+ '- Do not request GoodVibes TUI delegation unless this scheduled routine explicitly delegates build/fix/review work to GoodVibes TUI.',
278
280
  '- Summarize what was checked, what changed, and what still needs user review.',
279
281
  '',
280
282
  'Routine description:',
@@ -354,7 +356,7 @@ export function buildRoutineSchedulePreview(
354
356
  };
355
357
  }
356
358
 
357
- async function fetchDaemonStatus(connection: AgentDaemonConnection): Promise<{
359
+ async function fetchConnectedHostStatus(connection: AgentConnectedHostConnection): Promise<{
358
360
  readonly ok: boolean;
359
361
  readonly status: number;
360
362
  readonly body: unknown;
@@ -378,7 +380,7 @@ async function fetchDaemonStatus(connection: AgentDaemonConnection): Promise<{
378
380
 
379
381
  async function classifyScheduleError(
380
382
  error: unknown,
381
- connection: AgentDaemonConnection,
383
+ connection: AgentConnectedHostConnection,
382
384
  ): Promise<RoutineSchedulePromotionFailure> {
383
385
  const message = summarizeError(error);
384
386
  const lower = message.toLowerCase();
@@ -386,30 +388,30 @@ async function classifyScheduleError(
386
388
  return { ok: false, kind: 'auth_required', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
387
389
  }
388
390
  if (lower.includes('404') || lower.includes('not found')) {
389
- const daemon = await fetchDaemonStatus(connection);
390
- const record = isRecord(daemon.body) ? daemon.body : {};
391
- const daemonVersion = readString(record, 'version') ?? 'unknown';
392
- if (daemon.ok && daemonVersion !== SDK_VERSION) {
391
+ const connectedHost = await fetchConnectedHostStatus(connection);
392
+ const record = isRecord(connectedHost.body) ? connectedHost.body : {};
393
+ const connectedHostVersion = readString(record, 'version') ?? 'unknown';
394
+ if (connectedHost.ok && connectedHostVersion !== SDK_VERSION) {
393
395
  return {
394
396
  ok: false,
395
397
  kind: 'version_mismatch',
396
- error: `Connected GoodVibes service SDK version ${daemonVersion} does not match Agent SDK pin ${SDK_VERSION}; schedules.create is unavailable.`,
398
+ error: `Connected GoodVibes host SDK version ${connectedHostVersion} does not match Agent SDK pin ${SDK_VERSION}; schedules.create is unavailable.`,
397
399
  route: ROUTINE_SCHEDULE_ROUTE,
398
400
  baseUrl: connection.baseUrl,
399
- daemonVersion,
401
+ connectedHostVersion,
400
402
  expectedSdkVersion: SDK_VERSION,
401
403
  };
402
404
  }
403
- return { ok: false, kind: 'daemon_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
405
+ return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
404
406
  }
405
407
  if (lower.includes('fetch') || lower.includes('connect') || lower.includes('econnrefused')) {
406
- return { ok: false, kind: 'daemon_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
408
+ return { ok: false, kind: 'connected_host_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
407
409
  }
408
- return { ok: false, kind: 'daemon_error', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
410
+ return { ok: false, kind: 'connected_host_error', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
409
411
  }
410
412
 
411
- export async function promoteRoutineToDaemonSchedule(
412
- connection: AgentDaemonConnection,
413
+ export async function promoteRoutineToConnectedSchedule(
414
+ connection: AgentConnectedHostConnection,
413
415
  preview: RoutineSchedulePromotionPreview,
414
416
  ): Promise<RoutineSchedulePromotionResult> {
415
417
  if (!connection.token) {
@@ -12,7 +12,7 @@ import {
12
12
  ROUTINE_SCHEDULE_LIST_METHOD,
13
13
  ROUTINE_SCHEDULE_METHOD,
14
14
  ROUTINE_SCHEDULE_ROUTE,
15
- type AgentDaemonConnection,
15
+ type AgentConnectedHostConnection,
16
16
  type RoutineScheduleCorrelation,
17
17
  type RoutineScheduleCorrelationFailure,
18
18
  type RoutineScheduleCorrelationResult,
@@ -82,6 +82,15 @@ function redactedDeliveryTargets(delivery: ScheduleDeliveryInput | undefined): r
82
82
  }));
83
83
  }
84
84
 
85
+ function normalizeFailureKind(value: unknown): RoutineScheduleReceipt['failureKind'] {
86
+ if (value === 'confirmation_required' || value === 'auth_required' || value === 'version_mismatch') return value;
87
+ if (value === 'connected_host_unavailable' || value === 'connected_host_route_unavailable' || value === 'connected_host_error') return value;
88
+ if (value === 'daemon_unavailable') return 'connected_host_unavailable';
89
+ if (value === 'daemon_route_unavailable') return 'connected_host_route_unavailable';
90
+ if (value === 'daemon_error') return 'connected_host_error';
91
+ return undefined;
92
+ }
93
+
85
94
  function readReceipt(value: unknown): RoutineScheduleReceipt | null {
86
95
  if (!isRecord(value)) return null;
87
96
  const id = readString(value, 'id')?.trim();
@@ -120,7 +129,7 @@ function readReceipt(value: unknown): RoutineScheduleReceipt | null {
120
129
  route: ROUTINE_SCHEDULE_ROUTE,
121
130
  method: ROUTINE_SCHEDULE_METHOD,
122
131
  status,
123
- daemonBaseUrl: readString(value, 'daemonBaseUrl') ?? '',
132
+ connectedHostBaseUrl: readString(value, 'connectedHostBaseUrl') ?? readString(value, 'daemonBaseUrl') ?? '',
124
133
  scheduleId: readString(value, 'scheduleId') ?? undefined,
125
134
  scheduleStatus: readString(value, 'scheduleStatus') ?? undefined,
126
135
  scheduleName: readString(value, 'scheduleName') ?? routineName,
@@ -138,14 +147,7 @@ function readReceipt(value: unknown): RoutineScheduleReceipt | null {
138
147
  },
139
148
  deliveryMode: readString(value, 'deliveryMode') ?? undefined,
140
149
  deliveryTargets,
141
- failureKind: value.failureKind === 'confirmation_required'
142
- || value.failureKind === 'auth_required'
143
- || value.failureKind === 'daemon_unavailable'
144
- || value.failureKind === 'version_mismatch'
145
- || value.failureKind === 'daemon_route_unavailable'
146
- || value.failureKind === 'daemon_error'
147
- ? value.failureKind
148
- : undefined,
150
+ failureKind: normalizeFailureKind(value.failureKind),
149
151
  failureError: readString(value, 'failureError') ?? undefined,
150
152
  };
151
153
  }
@@ -209,7 +211,7 @@ function resultScheduleRecord(result: RoutineSchedulePromotionResult): Record<st
209
211
 
210
212
  function buildReceipt(
211
213
  existing: readonly RoutineScheduleReceipt[],
212
- connection: AgentDaemonConnection,
214
+ connection: AgentConnectedHostConnection,
213
215
  preview: RoutineSchedulePromotionPreview,
214
216
  result: RoutineSchedulePromotionResult,
215
217
  ): RoutineScheduleReceipt {
@@ -226,7 +228,7 @@ function buildReceipt(
226
228
  route: ROUTINE_SCHEDULE_ROUTE,
227
229
  method: ROUTINE_SCHEDULE_METHOD,
228
230
  status: result.ok ? 'created' : 'failed',
229
- daemonBaseUrl: connection.baseUrl,
231
+ connectedHostBaseUrl: connection.baseUrl,
230
232
  scheduleId,
231
233
  scheduleStatus,
232
234
  scheduleName: String(preview.payload.name ?? `Agent routine: ${preview.routineName}`),
@@ -269,7 +271,7 @@ export class RoutineScheduleReceiptStore {
269
271
  return this.snapshot().receipts.find((receipt) => receipt.id.toLowerCase() === normalized) ?? null;
270
272
  }
271
273
 
272
- public append(connection: AgentDaemonConnection, preview: RoutineSchedulePromotionPreview, result: RoutineSchedulePromotionResult): RoutineScheduleReceipt {
274
+ public append(connection: AgentConnectedHostConnection, preview: RoutineSchedulePromotionPreview, result: RoutineSchedulePromotionResult): RoutineScheduleReceipt {
273
275
  const store = this.readStore();
274
276
  const receipt = buildReceipt(store.receipts, connection, preview, result);
275
277
  this.writeStore({ ...store, receipts: [...store.receipts, receipt] });
@@ -281,7 +283,7 @@ export class RoutineScheduleReceiptStore {
281
283
  try {
282
284
  return parseReceiptStore(readFileSync(this.storePath, 'utf-8'));
283
285
  } catch (error) {
284
- throw new Error(`Could not read Agent routine schedule receipt store: ${summarizeError(error)}`);
286
+ throw new Error(`Could not read Agent routine schedule receipt store ${summarizeError(error)}`);
285
287
  }
286
288
  }
287
289
 
@@ -415,7 +417,7 @@ function correlateReceipts(
415
417
  });
416
418
  }
417
419
 
418
- async function fetchDaemonStatus(connection: AgentDaemonConnection): Promise<{
420
+ async function fetchConnectedHostStatus(connection: AgentConnectedHostConnection): Promise<{
419
421
  readonly ok: boolean;
420
422
  readonly status: number;
421
423
  readonly body: unknown;
@@ -439,7 +441,7 @@ async function fetchDaemonStatus(connection: AgentDaemonConnection): Promise<{
439
441
 
440
442
  async function classifyScheduleListError(
441
443
  error: unknown,
442
- connection: AgentDaemonConnection,
444
+ connection: AgentConnectedHostConnection,
443
445
  ): Promise<RoutineScheduleCorrelationFailure> {
444
446
  const message = summarizeError(error);
445
447
  const lower = message.toLowerCase();
@@ -447,30 +449,30 @@ async function classifyScheduleListError(
447
449
  return { ok: false, kind: 'auth_required', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
448
450
  }
449
451
  if (lower.includes('404') || lower.includes('not found')) {
450
- const daemon = await fetchDaemonStatus(connection);
451
- const record = isRecord(daemon.body) ? daemon.body : {};
452
- const daemonVersion = readString(record, 'version') ?? 'unknown';
453
- if (daemon.ok && daemonVersion !== SDK_VERSION) {
452
+ const connectedHost = await fetchConnectedHostStatus(connection);
453
+ const record = isRecord(connectedHost.body) ? connectedHost.body : {};
454
+ const connectedHostVersion = readString(record, 'version') ?? 'unknown';
455
+ if (connectedHost.ok && connectedHostVersion !== SDK_VERSION) {
454
456
  return {
455
457
  ok: false,
456
458
  kind: 'version_mismatch',
457
- error: `Connected GoodVibes service SDK version ${daemonVersion} does not match Agent SDK pin ${SDK_VERSION}; schedules.list is unavailable.`,
459
+ error: `Connected GoodVibes host SDK version ${connectedHostVersion} does not match Agent SDK pin ${SDK_VERSION}; schedules.list is unavailable.`,
458
460
  route: ROUTINE_SCHEDULE_ROUTE,
459
461
  baseUrl: connection.baseUrl,
460
- daemonVersion,
462
+ connectedHostVersion,
461
463
  expectedSdkVersion: SDK_VERSION,
462
464
  };
463
465
  }
464
- return { ok: false, kind: 'daemon_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
466
+ return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
465
467
  }
466
468
  if (lower.includes('fetch') || lower.includes('connect') || lower.includes('econnrefused')) {
467
- return { ok: false, kind: 'daemon_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
469
+ return { ok: false, kind: 'connected_host_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
468
470
  }
469
- return { ok: false, kind: 'daemon_error', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
471
+ return { ok: false, kind: 'connected_host_error', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
470
472
  }
471
473
 
472
474
  export async function reconcileRoutineScheduleReceipts(
473
- connection: AgentDaemonConnection,
475
+ connection: AgentConnectedHostConnection,
474
476
  snapshot: RoutineScheduleReceiptSnapshot,
475
477
  ): Promise<RoutineScheduleCorrelationResult> {
476
478
  if (!connection.token) {
@@ -81,7 +81,7 @@ export const STARTER_TEMPLATES: readonly AgentRuntimeProfileStarterTemplate[] =
81
81
  description: 'Review open household commitments, pending approvals, and stale home notes.',
82
82
  steps: [
83
83
  '1. List pending local routines, workplan tasks, and approvals.',
84
- '2. Summarize what changed since the last review from local Agent state.',
84
+ '2. Summarize what changed since the last review from Agent-local state.',
85
85
  '3. Ask for confirmation before scheduling, sending messages, purchasing, or changing services.',
86
86
  '4. Record reviewed preferences and stale notes locally.',
87
87
  ].join('\n'),
@@ -200,7 +200,7 @@ export const STARTER_TEMPLATES: readonly AgentRuntimeProfileStarterTemplate[] =
200
200
  name: 'Pre-trip Readiness Review',
201
201
  description: 'Check documents, reservations, transport, packing, weather, and open decisions.',
202
202
  steps: [
203
- '1. Review trip dates, locations, reservations, and open decisions from local Agent state.',
203
+ '1. Review trip dates, locations, reservations, and open decisions from Agent-local state.',
204
204
  '2. Refresh current weather, schedule, and rule data when needed.',
205
205
  '3. Summarize blockers and next confirmed action.',
206
206
  '4. Ask before external sends, purchases, or reservation changes.',