@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
@@ -34,6 +34,18 @@ import {
34
34
  reconcileRoutineScheduleReceipts,
35
35
  RoutineScheduleReceiptStore,
36
36
  } from '../../agent/routine-schedule-receipts.ts';
37
+ import {
38
+ buildScheduleEditPreview,
39
+ editConnectedSchedule,
40
+ enrichScheduleEditPreviewFromConnectedHost,
41
+ parseScheduleEditArgs,
42
+ resolveScheduleEditConnectedHostConnection,
43
+ } from '../../agent/schedule-edit.ts';
44
+ import {
45
+ formatScheduleEditFailure,
46
+ formatScheduleEditPreview,
47
+ formatScheduleEditSuccess,
48
+ } from '../../agent/schedule-edit-format.ts';
37
49
  import type { CommandContext } from '../command-registry.ts';
38
50
  import { requireShellPaths } from './runtime-services.ts';
39
51
  import { executeConfirmedOperatorAction } from './operator-actions-runtime.ts';
@@ -119,13 +131,42 @@ async function createReminder(args: readonly string[], ctx: CommandContext): Pro
119
131
  ctx.print(result.ok ? formatReminderScheduleSuccess(result) : formatReminderScheduleFailure(result));
120
132
  }
121
133
 
134
+ async function editSchedule(args: readonly string[], ctx: CommandContext): Promise<void> {
135
+ const parsed = parseScheduleEditArgs(args, {
136
+ defaultExplicitUserRequest: `/schedule edit ${args[0] ?? ''}`.trim(),
137
+ });
138
+ if (parsed.errors.length > 0) {
139
+ ctx.print([
140
+ 'Usage: /schedule edit <schedule-id> [--cron <expr>|--every <interval>|--at <iso-time>] [--timezone <tz>] [--stagger-ms <ms>] [--name <text>] [--prompt <text>|--task <text> --success-criteria <text>] --yes',
141
+ ...parsed.errors.map((error) => ` ${error}`),
142
+ ].join('\n'));
143
+ return;
144
+ }
145
+ let preview = buildScheduleEditPreview(parsed);
146
+ if (!parsed.yes) {
147
+ try {
148
+ const shellPaths = requireShellPaths(ctx);
149
+ const connection = resolveScheduleEditConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
150
+ preview = await enrichScheduleEditPreviewFromConnectedHost(connection, preview);
151
+ } catch {
152
+ // A basic preview is still safer than blocking confirmation on local path services.
153
+ }
154
+ ctx.print(formatScheduleEditPreview(preview));
155
+ return;
156
+ }
157
+ const shellPaths = requireShellPaths(ctx);
158
+ const connection = resolveScheduleEditConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
159
+ const result = await editConnectedSchedule(connection, preview);
160
+ ctx.print(result.ok ? formatScheduleEditSuccess(result) : formatScheduleEditFailure(result));
161
+ }
162
+
122
163
  export function registerScheduleRuntimeCommands(registry: CommandRegistry): void {
123
164
  registry.register({
124
165
  name: 'schedule',
125
166
  aliases: ['sched'],
126
167
  description: 'Inspect schedules, create confirmed reminders, and explicitly promote Agent-local routines to connected schedules',
127
- usage: 'list | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
128
- argsHint: 'list | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
168
+ usage: 'list | edit <id> --cron <expr> --yes | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> --yes',
169
+ argsHint: 'list | edit <id> --cron <expr> --yes | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> --yes',
129
170
  async handler(args, ctx) {
130
171
  const sub = args[0];
131
172
 
@@ -163,6 +204,28 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
163
204
  return;
164
205
  }
165
206
 
207
+ if (sub === 'edit' || sub === 'update' || sub === 'patch') {
208
+ await editSchedule(args.slice(1), ctx);
209
+ return;
210
+ }
211
+
212
+ if (sub === 'run' || sub === 'enable' || sub === 'disable' || sub === 'delete' || sub === 'remove') {
213
+ const scheduleId = args[1] ?? '';
214
+ if (!scheduleId) {
215
+ ctx.print(`Usage: /schedule ${sub} <schedule-id> --yes`);
216
+ return;
217
+ }
218
+ const action = sub === 'run'
219
+ ? 'schedules.run'
220
+ : sub === 'enable'
221
+ ? 'schedules.enable'
222
+ : sub === 'disable'
223
+ ? 'schedules.disable'
224
+ : 'schedules.delete';
225
+ await executeConfirmedOperatorAction(ctx, action, 'scheduleId', scheduleId, args.slice(2), `/schedule ${sub} <schedule-id> --yes`);
226
+ return;
227
+ }
228
+
166
229
  const manager = ctx.ops.automationManager;
167
230
  if (!manager) {
168
231
  ctx.print('Automation manager is not available in this runtime.');
@@ -191,17 +254,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
191
254
  return;
192
255
  }
193
256
 
194
- if (sub === 'run') {
195
- const scheduleId = args[1] ?? '';
196
- if (!scheduleId) {
197
- ctx.print('Usage: /schedule run <schedule-id> --yes');
198
- return;
199
- }
200
- await executeConfirmedOperatorAction(ctx, 'schedules.run', 'scheduleId', scheduleId, args.slice(2), '/schedule run <schedule-id> --yes');
201
- return;
202
- }
203
-
204
- if (sub === 'add' || sub === 'remove' || sub === 'enable' || sub === 'disable') {
257
+ if (sub === 'add') {
205
258
  printReadOnlyScheduleBoundary(ctx.print, `/schedule ${args.join(' ')}`.trim());
206
259
  return;
207
260
  }
@@ -213,9 +266,13 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
213
266
  + ' /schedule reconcile\n'
214
267
  + ' /schedule receipt <receipt-id>\n'
215
268
  + ' /schedule run <schedule-id> --yes\n'
269
+ + ' /schedule enable <schedule-id> --yes\n'
270
+ + ' /schedule disable <schedule-id> --yes\n'
271
+ + ' /schedule delete <schedule-id> --yes\n'
272
+ + ' /schedule edit <schedule-id> [--cron <expr>|--every <interval>|--at <iso-time>] [--name <text>] [--prompt <text>|--task <text> --success-criteria <text>] --yes\n'
216
273
  + ' /schedule remind (--cron <expr>|--every <interval>|--at <iso-time>) (--message <text>|<text...>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
217
274
  + ' /schedule promote-routine <routine-id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
218
- + ' Local schedule mutations remain blocked; schedule run is a confirmed connected-host action.'
275
+ + ' Local schedule creation remains blocked; schedule lifecycle/edit actions are confirmed connected-host actions.'
219
276
  );
220
277
  },
221
278
  });
@@ -197,7 +197,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
197
197
  argsHint: '',
198
198
  handler(args, ctx) {
199
199
  if (args.length > 0) {
200
- ctx.print('Usage: /undo\n Removes the last conversation turn. File edit undo belongs to the delegated GoodVibes TUI session.');
200
+ ctx.print('Usage: /undo\n Removes the last conversation turn. Use execution action:"recovery" for local file edit undo.');
201
201
  return;
202
202
  }
203
203
  const success = ctx.session.conversationManager.undo();
@@ -217,7 +217,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
217
217
  argsHint: '',
218
218
  handler(args, ctx) {
219
219
  if (args.length > 0) {
220
- ctx.print('Usage: /redo\n Restores the last undone conversation turn. File edit redo belongs to the delegated GoodVibes TUI session.');
220
+ ctx.print('Usage: /redo\n Restores the last undone conversation turn. Use execution action:"recovery" for local file edit redo.');
221
221
  return;
222
222
  }
223
223
  const success = ctx.session.conversationManager.redo();
@@ -26,6 +26,8 @@ function commandCategory(commandName: string): string {
26
26
  'knowledge',
27
27
  'memory',
28
28
  'notes',
29
+ 'vibe',
30
+ 'vibes',
29
31
  'personas',
30
32
  'skills',
31
33
  'routines',
@@ -0,0 +1,140 @@
1
+ import { AgentPersonaRegistry } from '../../agent/persona-registry.ts';
2
+ import {
3
+ discoverVibeFiles,
4
+ formatVibeStatus,
5
+ initVibeFile,
6
+ loadVibeImportSource,
7
+ resolveVibePathReference,
8
+ } from '../../agent/vibe-file.ts';
9
+ import {
10
+ formatVibeConfirmationRouteLines,
11
+ vibeImportPersonaConfirmationRoutes,
12
+ vibeInitConfirmationRoutes,
13
+ } from '../../agent/vibe-confirmation-routes.ts';
14
+ import type { CommandContext, CommandRegistry } from '../command-registry.ts';
15
+ import { parseAgentLocalLibraryArgs } from './agent-local-library-args.ts';
16
+ import { requireShellPaths } from './runtime-services.ts';
17
+
18
+ const VIBE_VALUE_FLAGS = ['name', 'description'] as const;
19
+
20
+ function printError(ctx: CommandContext, error: unknown): void {
21
+ ctx.print([
22
+ 'Error',
23
+ ` message ${error instanceof Error ? error.message : String(error)}`,
24
+ ].join('\n'));
25
+ }
26
+
27
+ function usage(): string {
28
+ return [
29
+ 'Usage: /vibe [status|init|show|import-persona]',
30
+ ' /vibe',
31
+ ' /vibe init [--global] [--force] --yes',
32
+ ' /vibe show [project|global|path]',
33
+ ' /vibe import-persona [project|global|path] [--name <name>] [--description <summary>] [--review] [--use] --yes',
34
+ ].join('\n');
35
+ }
36
+
37
+ export function registerVibeRuntimeCommands(registry: CommandRegistry): void {
38
+ registry.register({
39
+ name: 'vibe',
40
+ aliases: ['vibes'],
41
+ description: 'Inspect, create, and import VIBE.md personality files',
42
+ usage: '[status|init|show|import-persona]',
43
+ async handler(args, ctx) {
44
+ const sub = (args[0] ?? 'status').toLowerCase();
45
+ const shellPaths = requireShellPaths(ctx);
46
+ try {
47
+ if (sub === 'status' || sub === 'list' || sub === 'open') {
48
+ ctx.print(formatVibeStatus(discoverVibeFiles(shellPaths)));
49
+ return;
50
+ }
51
+
52
+ if (sub === 'init') {
53
+ const parsed = parseAgentLocalLibraryArgs(args.slice(1), { valueFlags: VIBE_VALUE_FLAGS });
54
+ const scope = parsed.flags.has('global') ? 'global' : 'project';
55
+ const previewPath = scope === 'global'
56
+ ? resolveVibePathReference(shellPaths, 'global')
57
+ : resolveVibePathReference(shellPaths, 'project');
58
+ if (!parsed.yes) {
59
+ ctx.print([
60
+ 'VIBE.md init preview',
61
+ ` scope ${scope}`,
62
+ ` path ${previewPath}`,
63
+ ...formatVibeConfirmationRouteLines(vibeInitConfirmationRoutes(scope, parsed.flags.has('force'))),
64
+ ].join('\n'));
65
+ return;
66
+ }
67
+ const result = initVibeFile(shellPaths, { scope, force: parsed.flags.has('force') });
68
+ ctx.print(result.created
69
+ ? `Created ${scope} VIBE.md\n path ${result.path}`
70
+ : `VIBE.md already exists\n path ${result.path}\n next rerun with --force --yes to replace it`);
71
+ return;
72
+ }
73
+
74
+ if (sub === 'show') {
75
+ const reference = args.slice(1).join(' ').trim() || 'project';
76
+ const source = loadVibeImportSource(shellPaths, reference);
77
+ ctx.print([
78
+ `${source.scope === 'global' ? 'Global' : 'Project'} VIBE.md`,
79
+ ` path ${source.path}`,
80
+ ` name ${source.name}`,
81
+ ` description ${source.description}`,
82
+ '',
83
+ source.body,
84
+ ].join('\n'));
85
+ return;
86
+ }
87
+
88
+ if (sub === 'import-persona' || sub === 'import') {
89
+ const parsed = parseAgentLocalLibraryArgs(args.slice(1), { valueFlags: VIBE_VALUE_FLAGS });
90
+ const reference = parsed.rest.join(' ').trim() || 'project';
91
+ const source = loadVibeImportSource(shellPaths, reference);
92
+ const name = parsed.flags.get('name')?.trim() || source.name;
93
+ const description = parsed.flags.get('description')?.trim() || source.description;
94
+ if (!parsed.yes) {
95
+ ctx.print([
96
+ 'VIBE.md persona import preview',
97
+ ` source ${source.scope}`,
98
+ ` path ${source.path}`,
99
+ ` name ${name}`,
100
+ ` description ${description}`,
101
+ ` body characters ${source.body.length}`,
102
+ ...formatVibeConfirmationRouteLines(vibeImportPersonaConfirmationRoutes({
103
+ reference,
104
+ name,
105
+ description,
106
+ review: parsed.flags.has('review'),
107
+ use: parsed.flags.has('use'),
108
+ })),
109
+ ].join('\n'));
110
+ return;
111
+ }
112
+ const personaRegistry = AgentPersonaRegistry.fromShellPaths(shellPaths);
113
+ const persona = personaRegistry.create({
114
+ name,
115
+ description,
116
+ body: source.body,
117
+ tags: ['vibe', source.scope],
118
+ triggers: ['vibe'],
119
+ source: 'imported',
120
+ provenance: `Imported VIBE.md (${source.scope}): ${source.path}`,
121
+ });
122
+ if (parsed.flags.has('review')) personaRegistry.markReviewed(persona.id);
123
+ if (parsed.flags.has('use')) personaRegistry.setActive(persona.id);
124
+ ctx.print([
125
+ `Imported VIBE.md persona ${persona.id}: ${persona.name}`,
126
+ ` source ${source.scope}`,
127
+ ` path ${source.path}`,
128
+ ` reviewed ${parsed.flags.has('review') ? 'yes' : 'no'}`,
129
+ ` active ${parsed.flags.has('use') ? 'yes' : 'no'}`,
130
+ ].join('\n'));
131
+ return;
132
+ }
133
+
134
+ ctx.print(usage());
135
+ } catch (error) {
136
+ printError(ctx, error);
137
+ }
138
+ },
139
+ });
140
+ }
@@ -32,6 +32,7 @@ import { registerAgentWorkspaceRuntimeCommands } from './commands/agent-workspac
32
32
  import { registerAgentRuntimeProfileRuntimeCommands } from './commands/agent-runtime-profile-runtime.ts';
33
33
  import { registerDelegationRuntimeCommands } from './commands/delegation-runtime.ts';
34
34
  import { registerPersonasRuntimeCommands } from './commands/personas-runtime.ts';
35
+ import { registerVibeRuntimeCommands } from './commands/vibe-runtime.ts';
35
36
  import { registerAgentSkillsRuntimeCommands } from './commands/agent-skills-runtime.ts';
36
37
  import { registerRoutinesRuntimeCommands } from './commands/routines-runtime.ts';
37
38
  import { registerChannelsRuntimeCommands } from './commands/channels-runtime.ts';
@@ -65,6 +66,7 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
65
66
  registerCompatRuntimeCommands(registry);
66
67
  registerOperatorActionRuntimeCommands(registry);
67
68
  registerAgentRuntimeProfileRuntimeCommands(registry);
69
+ registerVibeRuntimeCommands(registry);
68
70
  registerPersonasRuntimeCommands(registry);
69
71
  registerAgentSkillsRuntimeCommands(registry);
70
72
  registerRoutinesRuntimeCommands(registry);
@@ -0,0 +1,123 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import type { CommandContext } from './command-registry.ts';
4
+
5
+ export interface ConnectedHostConnection {
6
+ readonly baseUrl: string;
7
+ readonly token: string | null;
8
+ readonly tokenPath: string;
9
+ }
10
+
11
+ export interface ConnectedHostRouteSuccess {
12
+ readonly ok: true;
13
+ readonly route: string;
14
+ readonly body: unknown;
15
+ }
16
+
17
+ export interface ConnectedHostRouteFailure {
18
+ readonly ok: false;
19
+ readonly route: string;
20
+ readonly kind: 'auth_required' | 'connected_host_unavailable' | 'connected_host_route_unavailable' | 'connected_host_error';
21
+ readonly baseUrl: string;
22
+ readonly message: string;
23
+ }
24
+
25
+ export type ConnectedHostRouteResult = ConnectedHostRouteSuccess | ConnectedHostRouteFailure;
26
+
27
+ export const CONNECTED_HOST_FAILURE_LABELS: Record<ConnectedHostRouteFailure['kind'], string> = {
28
+ auth_required: 'auth required',
29
+ connected_host_unavailable: 'connected host unavailable',
30
+ connected_host_route_unavailable: 'connected host route unavailable',
31
+ connected_host_error: 'connected host error',
32
+ };
33
+
34
+ function isRecord(value: unknown): value is Record<string, unknown> {
35
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
36
+ }
37
+
38
+ export function resolveConnectedHostConnection(context: CommandContext): ConnectedHostConnection {
39
+ const hostValue = context.platform?.configManager?.get('controlPlane.host');
40
+ const portValue = context.platform?.configManager?.get('controlPlane.port');
41
+ const host = typeof hostValue === 'string' && hostValue.trim().length > 0 ? hostValue.trim() : '127.0.0.1';
42
+ const port = typeof portValue === 'number' && Number.isFinite(portValue) ? portValue : 3421;
43
+ const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? process.env.HOME ?? '';
44
+ const tokenPath = join(homeDirectory, '.goodvibes', 'daemon', 'operator-tokens.json');
45
+ if (!existsSync(tokenPath)) return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
46
+ try {
47
+ const parsed = JSON.parse(readFileSync(tokenPath, 'utf-8')) as unknown;
48
+ const token = isRecord(parsed) && typeof parsed.token === 'string' ? parsed.token : null;
49
+ return { baseUrl: `http://${host}:${port}`, token, tokenPath };
50
+ } catch {
51
+ return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
52
+ }
53
+ }
54
+
55
+ export async function fetchConnectedHostReadOnlyRoute(
56
+ context: CommandContext,
57
+ route: string,
58
+ ): Promise<ConnectedHostRouteResult> {
59
+ const connection = resolveConnectedHostConnection(context);
60
+ if (!connection.token) {
61
+ return {
62
+ ok: false,
63
+ route,
64
+ kind: 'auth_required',
65
+ baseUrl: connection.baseUrl,
66
+ message: `No connected-host operator token found at ${connection.tokenPath}`,
67
+ };
68
+ }
69
+
70
+ try {
71
+ const response = await fetch(`${connection.baseUrl}${route}`, {
72
+ headers: { authorization: `Bearer ${connection.token}` },
73
+ });
74
+ const text = await response.text();
75
+ let body: unknown = text;
76
+ if (text.trim().length > 0) {
77
+ try {
78
+ body = JSON.parse(text) as unknown;
79
+ } catch {
80
+ body = text;
81
+ }
82
+ }
83
+ if (!response.ok) {
84
+ const detail = isRecord(body) && typeof body.error === 'string' ? body.error : text;
85
+ return {
86
+ ok: false,
87
+ route,
88
+ kind: response.status === 401 || response.status === 403
89
+ ? 'auth_required'
90
+ : response.status === 404
91
+ ? 'connected_host_route_unavailable'
92
+ : 'connected_host_error',
93
+ baseUrl: connection.baseUrl,
94
+ message: `HTTP ${response.status}${detail ? `: ${detail}` : ''}`,
95
+ };
96
+ }
97
+ return { ok: true, route, body };
98
+ } catch (error) {
99
+ return {
100
+ ok: false,
101
+ route,
102
+ kind: 'connected_host_unavailable',
103
+ baseUrl: connection.baseUrl,
104
+ message: error instanceof Error ? error.message : String(error),
105
+ };
106
+ }
107
+ }
108
+
109
+ export function formatConnectedHostRouteFailure(
110
+ title: string,
111
+ failure: ConnectedHostRouteFailure,
112
+ policy = 'read-only; no mutation route was called',
113
+ ): string {
114
+ return [
115
+ `${title}: unavailable`,
116
+ ` status: ${CONNECTED_HOST_FAILURE_LABELS[failure.kind]}`,
117
+ ` kind: ${failure.kind}`,
118
+ ` connected host: ${failure.baseUrl}`,
119
+ ` route: ${failure.route}`,
120
+ ` error: ${failure.message}`,
121
+ ` policy: ${policy}`,
122
+ ].join('\n');
123
+ }
@@ -32,6 +32,18 @@ export type SettingsCategory =
32
32
  | 'tts'
33
33
  | 'surfaces'
34
34
  | 'automation'
35
+ | 'service'
36
+ | 'controlPlane'
37
+ | 'httpListener'
38
+ | 'web'
39
+ | 'watchers'
40
+ | 'network'
41
+ | 'orchestration'
42
+ | 'runtime'
43
+ | 'sandbox'
44
+ | 'batch'
45
+ | 'cloudflare'
46
+ | 'wrfc'
35
47
  | 'telemetry'
36
48
  | 'cache'
37
49
  | 'mcp'
@@ -48,6 +60,8 @@ export const SETTINGS_CATEGORY_GROUPS: ReadonlyArray<{
48
60
  { label: 'Models and Providers', categories: ['provider', 'subscriptions', 'helper', 'tools', 'tts'] },
49
61
  { label: 'Agent-local state', categories: ['storage', 'cache', 'telemetry'] },
50
62
  { label: 'Channels and Tools', categories: ['surfaces', 'mcp', 'automation'] },
63
+ { label: 'Daemon Runtime', categories: ['service', 'controlPlane', 'httpListener', 'web', 'watchers', 'network'] },
64
+ { label: 'Advanced Runtime', categories: ['orchestration', 'runtime', 'sandbox', 'batch', 'cloudflare', 'wrfc'] },
51
65
  { label: 'Advanced', categories: ['flags', 'release'] },
52
66
  ];
53
67
 
@@ -0,0 +1,76 @@
1
+ import type { CommandContext } from './command-registry.ts';
2
+ import { buildSetupWizardDurableReceiptsFromReadModel, mergeSetupWizardDurableReceipts } from '../agent/setup-wizard-artifact-receipts.ts';
3
+ import type { AgentSetupWizardDurableReceipt } from '../agent/setup-wizard.ts';
4
+
5
+ interface SetupReceiptReadModelSource {
6
+ readonly path: string;
7
+ readonly source: unknown;
8
+ }
9
+
10
+ function readRecord(value: unknown): Record<string, unknown> {
11
+ return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
12
+ }
13
+
14
+ function setupReceiptReadModelSources(context: CommandContext): readonly SetupReceiptReadModelSource[] {
15
+ const contextRecord = context as unknown as Record<string, unknown>;
16
+ const platform = readRecord(contextRecord.platform);
17
+ const clients = readRecord(contextRecord.clients);
18
+ const readModels = readRecord(platform.readModels);
19
+ const setup = readRecord(readModels.setup);
20
+ const setupWizard = readRecord(readModels.setupWizard);
21
+ const firstRun = readRecord(readModels.firstRun);
22
+ const browserPwa = readRecord(readModels.browserPwa);
23
+ const operator = readRecord(clients.operator);
24
+ return [
25
+ { path: 'context.platform.readModels.setup.receipts', source: setup.receipts },
26
+ { path: 'context.platform.readModels.setup.setupReceipts', source: setup.setupReceipts },
27
+ { path: 'context.platform.readModels.setup.receiptEvents', source: setup.receiptEvents },
28
+ { path: 'context.platform.readModels.setup.eventStream', source: setup.eventStream },
29
+ { path: 'context.platform.readModels.setup', source: readModels.setup },
30
+ { path: 'context.platform.readModels.setupWizard.receipts', source: setupWizard.receipts },
31
+ { path: 'context.platform.readModels.setupWizard.durableReceipts', source: setupWizard.durableReceipts },
32
+ { path: 'context.platform.readModels.setupWizard.receiptEvents', source: setupWizard.receiptEvents },
33
+ { path: 'context.platform.readModels.setupWizard.eventStream', source: setupWizard.eventStream },
34
+ { path: 'context.platform.readModels.setupReceipts', source: readModels.setupReceipts },
35
+ { path: 'context.platform.readModels.setupReceiptEvents', source: readModels.setupReceiptEvents },
36
+ { path: 'context.platform.readModels.setupReceiptEventStream', source: readModels.setupReceiptEventStream },
37
+ { path: 'context.platform.readModels.durableSetupReceipts', source: readModels.durableSetupReceipts },
38
+ { path: 'context.platform.readModels.firstRun.receipts', source: firstRun.receipts },
39
+ { path: 'context.platform.readModels.browserPwa.firstRunReceipts', source: browserPwa.firstRunReceipts },
40
+ { path: 'context.platform.setupReceipts', source: platform.setupReceipts },
41
+ { path: 'context.platform.setupReceiptEvents', source: platform.setupReceiptEvents },
42
+ { path: 'context.clients.operator.setupReceipts', source: operator.setupReceipts },
43
+ { path: 'context.clients.operator.setupReceiptEvents', source: operator.setupReceiptEvents },
44
+ ];
45
+ }
46
+
47
+ function readSnapshot(source: unknown): unknown {
48
+ if (typeof source === 'function') {
49
+ const result = (source as () => unknown)();
50
+ return result instanceof Promise ? undefined : result;
51
+ }
52
+ const record = readRecord(source);
53
+ for (const methodName of ['getSnapshot', 'snapshot', 'list', 'listReceipts', 'listEvents', 'listReceiptEvents', 'readEvents']) {
54
+ const method = record[methodName];
55
+ if (typeof method === 'function') {
56
+ const result = (method as () => unknown)();
57
+ return result instanceof Promise ? undefined : result;
58
+ }
59
+ }
60
+ return source;
61
+ }
62
+
63
+ export function setupWizardLiveDurableReceipts(context: CommandContext): readonly AgentSetupWizardDurableReceipt[] {
64
+ const receipts: AgentSetupWizardDurableReceipt[][] = [];
65
+ for (const entry of setupReceiptReadModelSources(context)) {
66
+ if (entry.source === undefined || entry.source === null) continue;
67
+ try {
68
+ receipts.push([...buildSetupWizardDurableReceiptsFromReadModel(readSnapshot(entry.source), entry.path)]);
69
+ } catch {
70
+ // Broken host read models should not hide local setup posture.
71
+ }
72
+ }
73
+ return mergeSetupWizardDurableReceipts(...receipts);
74
+ }
75
+
76
+ export { mergeSetupWizardDurableReceipts };
package/src/main.ts CHANGED
@@ -44,6 +44,7 @@ import type { SessionSnapshot } from '@/runtime/index.ts';
44
44
  import { handleBlockingShellInput, type PendingPermissionState } from './shell/blocking-input.ts';
45
45
  import { createAgentWorkspaceFullscreenComposite, createFullscreenCompositeFromLines } from './shell/agent-workspace-fullscreen.ts';
46
46
  import { getTerminalSize } from './shell/terminal-size.ts';
47
+ import { buildShellSessionContinuityHints } from './shell/session-continuity-hints.ts';
47
48
  import { wireShellUiOpeners } from './shell/ui-openers.ts';
48
49
  import { deriveComposerState } from './core/composer-state.ts';
49
50
  import { buildPersistedSessionContext, formatReturnContextForDisplay, getReturnContextMode, maybeAssistReturnContextSummary } from '@/runtime/index.ts';
@@ -128,19 +129,12 @@ async function main() {
128
129
  }
129
130
 
130
131
  const panelManager = ctx.services.panelManager;
131
- const buildSessionContinuityHints = () => {
132
- const sessionSnapshot = uiServices.readModels.session.getSnapshot();
133
- const tasksSnapshot = uiServices.readModels.tasks.getSnapshot();
134
- const remoteSnapshot = uiServices.readModels.remote.getSnapshot();
135
- return {
136
- pendingApprovals: sessionSnapshot.pendingApproval ? 1 : 0,
137
- activeTasks: tasksSnapshot.tasks.filter((task) => task.status === 'running' || task.status === 'queued').length,
138
- blockedTasks: tasksSnapshot.tasks.filter((task) => task.status === 'blocked').length,
139
- remoteContracts: remoteSnapshot.contracts.length,
140
- remoteRunners: remoteSnapshot.contracts.slice(0, 4).map((contract) => contract.runnerId),
141
- openPanels: panelManager.getAllOpen().map((panel) => panel.id),
142
- };
143
- };
132
+ const buildSessionContinuityHints = () => buildShellSessionContinuityHints(
133
+ uiServices.readModels.session.getSnapshot(),
134
+ uiServices.readModels.tasks.getSnapshot(),
135
+ uiServices.readModels.remote.getSnapshot(),
136
+ panelManager.getAllOpen(),
137
+ );
144
138
  const buildCurrentSessionSnapshot = (): SessionSnapshot => {
145
139
  const messages = conversation.getMessageSnapshot();
146
140
  const persisted = buildPersistedSessionContext(messages, conversation.getTitleSource(), buildSessionContinuityHints());
@@ -494,9 +488,13 @@ async function main() {
494
488
  // Cache the current model for consistent values across the entire render frame
495
489
  const currentModel = providerRegistry.getCurrentModel();
496
490
  const sessionSnapshot = uiServices.readModels.session.getSnapshot();
491
+ const agentSnapshot = uiServices.readModels.agents.getSnapshot();
492
+ const activeAgents = agentSnapshot.active;
493
+ const primaryActiveAgent = activeAgents.find((agent) => agent.latestProgress?.trim())
494
+ ?? activeAgents[0];
497
495
 
498
496
  const headerLines = UIFactory.createHeader(width, currentModel.id, currentModel.provider, conversation.title || undefined);
499
- const runningAgentCount = 0;
497
+ const runningAgentCount = activeAgents.length;
500
498
  const runningProcessCount = processManager.list().filter((p) => !p.status.startsWith('done')).length;
501
499
  const cw = getPromptContentWidth();
502
500
  const promptInfo = input.getWrappedPromptInfo(cw);
@@ -543,7 +541,9 @@ async function main() {
543
541
  runningAgentCount,
544
542
  runningProcessCount,
545
543
  indicatorFocused: input.indicatorFocused,
546
- runningAgentProgress: undefined,
544
+ runningAgentProgress: primaryActiveAgent
545
+ ? `${primaryActiveAgent.label}: ${primaryActiveAgent.latestProgress?.trim() || primaryActiveAgent.status}`
546
+ : undefined,
547
547
  composerMode: composerState.modeLabel,
548
548
  composerStatus: composerState.statusLabel,
549
549
  composerFlags: composerState.flags,
@@ -158,12 +158,12 @@ export class QrPanel extends BasePanel {
158
158
  );
159
159
  lines.push(
160
160
  buildPanelLine(width, [
161
- [' Connected-host operator token is missing. Agent does not create or rotate host auth tokens. ', C.dim],
161
+ [' Connected-host operator token is missing. Use confirmed setup to create or repair it. ', C.dim],
162
162
  ]),
163
163
  );
164
164
  lines.push(
165
165
  buildPanelLine(width, [
166
- [' Provision or repair connected-host access through the owning GoodVibes host, then reopen this panel. ', C.dim],
166
+ [' agent_harness mode:"provision_connected_host_token" then reopen this panel. ', C.dim],
167
167
  ]),
168
168
  );
169
169
  }