@pellux/goodvibes-agent 1.1.7 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/CHANGELOG.md +170 -0
  2. package/README.md +46 -30
  3. package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
  4. package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
  5. package/dist/package/main.js +132577 -91483
  6. package/docs/README.md +14 -7
  7. package/docs/channels-remote-and-api.md +8 -5
  8. package/docs/connected-host.md +14 -12
  9. package/docs/getting-started.md +56 -30
  10. package/docs/knowledge-artifacts-and-multimodal.md +7 -5
  11. package/docs/project-planning.md +2 -2
  12. package/docs/providers-and-routing.md +11 -3
  13. package/docs/tools-and-commands.md +114 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +130 -5
  17. package/release/release-readiness.json +120 -90
  18. package/src/agent/assistant-cockpit.ts +247 -0
  19. package/src/agent/autonomy-schedule-format.ts +96 -0
  20. package/src/agent/autonomy-schedule.ts +514 -0
  21. package/src/agent/channel-delivery-receipts.ts +292 -0
  22. package/src/agent/competitive-feature-inventory.ts +296 -0
  23. package/src/agent/document-registry-types.ts +106 -0
  24. package/src/agent/document-registry.ts +734 -0
  25. package/src/agent/harness-control.ts +2 -2
  26. package/src/agent/memory-prompt.ts +2 -2
  27. package/src/agent/operator-actions.ts +50 -6
  28. package/src/agent/persona-registry.ts +8 -0
  29. package/src/agent/project-context-files.ts +273 -0
  30. package/src/agent/prompt-context-receipts.ts +502 -0
  31. package/src/agent/reminder-schedule-format.ts +16 -2
  32. package/src/agent/research-run-registry.ts +582 -0
  33. package/src/agent/research-source-registry.ts +441 -0
  34. package/src/agent/routine-registry.ts +19 -3
  35. package/src/agent/routine-schedule-format.ts +27 -2
  36. package/src/agent/runtime-profile-starters.ts +7 -0
  37. package/src/agent/runtime-profile.ts +106 -4
  38. package/src/agent/schedule-edit-format.ts +129 -0
  39. package/src/agent/schedule-edit.ts +496 -0
  40. package/src/agent/schedule-next-routes.ts +42 -0
  41. package/src/agent/setup-wizard-checkpoint.ts +140 -0
  42. package/src/agent/setup-wizard.ts +447 -0
  43. package/src/agent/skill-registry-types.ts +102 -0
  44. package/src/agent/skill-registry.ts +81 -107
  45. package/src/agent/vibe-confirmation-routes.ts +62 -0
  46. package/src/agent/vibe-file.ts +285 -0
  47. package/src/cli/agent-knowledge-command.ts +45 -2
  48. package/src/cli/help.ts +3 -0
  49. package/src/cli/profiles-command.ts +25 -11
  50. package/src/config/agent-settings-policy.ts +1 -18
  51. package/src/input/agent-workspace-activation.ts +53 -0
  52. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  53. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  54. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  55. package/src/input/agent-workspace-categories.ts +153 -155
  56. package/src/input/agent-workspace-channel-triage.ts +481 -0
  57. package/src/input/agent-workspace-channels.ts +263 -0
  58. package/src/input/agent-workspace-command-editor.ts +152 -0
  59. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  60. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  61. package/src/input/agent-workspace-document-editor.ts +502 -0
  62. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  63. package/src/input/agent-workspace-host-category.ts +1 -1
  64. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  65. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  66. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  67. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  68. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  69. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  70. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  71. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  72. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  73. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  74. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  75. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  76. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  77. package/src/input/agent-workspace-settings.ts +262 -30
  78. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  79. package/src/input/agent-workspace-setup-snapshot.ts +198 -0
  80. package/src/input/agent-workspace-setup.ts +34 -1
  81. package/src/input/agent-workspace-snapshot.ts +162 -147
  82. package/src/input/agent-workspace-types.ts +287 -2
  83. package/src/input/agent-workspace.ts +18 -0
  84. package/src/input/command-registry.ts +9 -2
  85. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  86. package/src/input/commands/channels-runtime.ts +102 -114
  87. package/src/input/commands/delegation-runtime.ts +87 -24
  88. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  89. package/src/input/commands/knowledge.ts +28 -14
  90. package/src/input/commands/operator-actions-runtime.ts +6 -3
  91. package/src/input/commands/schedule-runtime.ts +71 -14
  92. package/src/input/commands/session-content.ts +2 -2
  93. package/src/input/commands/shell-core.ts +2 -0
  94. package/src/input/commands/vibe-runtime.ts +140 -0
  95. package/src/input/commands.ts +2 -0
  96. package/src/input/connected-host-routes.ts +123 -0
  97. package/src/input/settings-modal-types.ts +14 -0
  98. package/src/main.ts +15 -15
  99. package/src/panels/qr-panel.ts +2 -2
  100. package/src/renderer/agent-workspace-context-lines.ts +686 -0
  101. package/src/renderer/agent-workspace.ts +30 -419
  102. package/src/renderer/settings-modal-helpers.ts +12 -0
  103. package/src/renderer/settings-modal.ts +12 -0
  104. package/src/runtime/bootstrap-command-context.ts +11 -1
  105. package/src/runtime/bootstrap-command-parts.ts +14 -3
  106. package/src/runtime/bootstrap-core.ts +39 -1
  107. package/src/runtime/bootstrap-shell.ts +6 -0
  108. package/src/runtime/bootstrap.ts +113 -30
  109. package/src/runtime/connected-host-auth.ts +3 -2
  110. package/src/runtime/execution-ledger.ts +231 -0
  111. package/src/runtime/services.ts +88 -10
  112. package/src/runtime/tool-permission-safety.ts +199 -5
  113. package/src/shell/session-continuity-hints.ts +39 -0
  114. package/src/tools/agent-artifacts-tool.ts +606 -0
  115. package/src/tools/agent-audit-tool.ts +155 -0
  116. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  117. package/src/tools/agent-autonomy-tool.ts +140 -0
  118. package/src/tools/agent-channel-send-tool.ts +24 -2
  119. package/src/tools/agent-channels-tool.ts +140 -0
  120. package/src/tools/agent-computer-tool.ts +168 -0
  121. package/src/tools/agent-context-policy.ts +137 -7
  122. package/src/tools/agent-context-tool.ts +143 -0
  123. package/src/tools/agent-delegation-tool.ts +128 -0
  124. package/src/tools/agent-device-tool.ts +240 -0
  125. package/src/tools/agent-documents-tool.ts +684 -0
  126. package/src/tools/agent-execution-tool.ts +230 -0
  127. package/src/tools/agent-harness-agent-orchestration.ts +703 -0
  128. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  129. package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
  130. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  131. package/src/tools/agent-harness-autonomy-queue.ts +560 -0
  132. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  133. package/src/tools/agent-harness-background-processes.ts +794 -0
  134. package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
  135. package/src/tools/agent-harness-browser-control.ts +338 -0
  136. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  137. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  138. package/src/tools/agent-harness-command-catalog.ts +4 -2
  139. package/src/tools/agent-harness-command-runner.ts +42 -0
  140. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  141. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  142. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  143. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  144. package/src/tools/agent-harness-document-ops.ts +671 -0
  145. package/src/tools/agent-harness-execution-history.ts +489 -0
  146. package/src/tools/agent-harness-execution-posture.ts +382 -0
  147. package/src/tools/agent-harness-file-recovery.ts +135 -0
  148. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  149. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  150. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  151. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  152. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  153. package/src/tools/agent-harness-learning-curator.ts +417 -0
  154. package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
  155. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  156. package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
  157. package/src/tools/agent-harness-media-posture.ts +208 -2
  158. package/src/tools/agent-harness-memory-posture.ts +556 -0
  159. package/src/tools/agent-harness-metadata.ts +100 -168
  160. package/src/tools/agent-harness-mode-catalog.ts +84 -33
  161. package/src/tools/agent-harness-model-catalog.ts +162 -0
  162. package/src/tools/agent-harness-model-provider-health.ts +186 -0
  163. package/src/tools/agent-harness-model-readiness.ts +406 -0
  164. package/src/tools/agent-harness-model-routing-types.ts +266 -0
  165. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  166. package/src/tools/agent-harness-model-routing.ts +137 -190
  167. package/src/tools/agent-harness-operator-methods.ts +115 -133
  168. package/src/tools/agent-harness-pairing-posture.ts +431 -18
  169. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  170. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  171. package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
  172. package/src/tools/agent-harness-personal-ops-records.ts +732 -0
  173. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  174. package/src/tools/agent-harness-personal-ops-types.ts +222 -0
  175. package/src/tools/agent-harness-personal-ops.ts +606 -0
  176. package/src/tools/agent-harness-project-context.ts +144 -0
  177. package/src/tools/agent-harness-prompt-context.ts +589 -0
  178. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  179. package/src/tools/agent-harness-release-evidence.ts +9 -7
  180. package/src/tools/agent-harness-release-readiness.ts +9 -7
  181. package/src/tools/agent-harness-research-briefing.ts +427 -0
  182. package/src/tools/agent-harness-research-queue.ts +250 -0
  183. package/src/tools/agent-harness-research-runs.ts +295 -0
  184. package/src/tools/agent-harness-research-workflow.ts +322 -0
  185. package/src/tools/agent-harness-security-posture.ts +2 -2
  186. package/src/tools/agent-harness-service-posture.ts +9 -9
  187. package/src/tools/agent-harness-session-metadata.ts +3 -3
  188. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  189. package/src/tools/agent-harness-setup-describe.ts +557 -0
  190. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  191. package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
  192. package/src/tools/agent-harness-setup-plan.ts +253 -0
  193. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  194. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  195. package/src/tools/agent-harness-setup-posture.ts +449 -221
  196. package/src/tools/agent-harness-setup-smoke.ts +508 -0
  197. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  198. package/src/tools/agent-harness-tool-schema.ts +120 -7
  199. package/src/tools/agent-harness-tool-types.ts +78 -0
  200. package/src/tools/agent-harness-tool-utils.ts +43 -0
  201. package/src/tools/agent-harness-tool.ts +311 -370
  202. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  203. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  204. package/src/tools/agent-harness-vibe-health.ts +105 -0
  205. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  206. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  207. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  208. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  209. package/src/tools/agent-host-tool.ts +159 -0
  210. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  211. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  212. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  213. package/src/tools/agent-memory-tool.ts +214 -0
  214. package/src/tools/agent-model-compare-export.ts +315 -0
  215. package/src/tools/agent-model-compare-handoff.ts +592 -0
  216. package/src/tools/agent-model-compare-judgment.ts +633 -0
  217. package/src/tools/agent-model-compare-run.ts +722 -0
  218. package/src/tools/agent-model-compare-tool.ts +698 -0
  219. package/src/tools/agent-model-compare-types.ts +191 -0
  220. package/src/tools/agent-model-compare-utils.ts +93 -0
  221. package/src/tools/agent-models-tool.ts +208 -0
  222. package/src/tools/agent-operator-action-tool.ts +1 -1
  223. package/src/tools/agent-operator-method-tool.ts +643 -0
  224. package/src/tools/agent-personal-ops-tool.ts +197 -0
  225. package/src/tools/agent-policy-explanation.ts +415 -0
  226. package/src/tools/agent-research-report-tool.ts +608 -0
  227. package/src/tools/agent-research-runs-tool.ts +434 -0
  228. package/src/tools/agent-research-sources-tool.ts +443 -0
  229. package/src/tools/agent-research-tool.ts +687 -0
  230. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  231. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  232. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  233. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  234. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  235. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  236. package/src/tools/agent-route-planner-helpers.ts +667 -0
  237. package/src/tools/agent-route-planner.ts +185 -0
  238. package/src/tools/agent-route-tool.ts +105 -0
  239. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  240. package/src/tools/agent-schedule-tool.ts +282 -0
  241. package/src/tools/agent-security-tool.ts +145 -0
  242. package/src/tools/agent-sessions-tool.ts +122 -0
  243. package/src/tools/agent-settings-import-tool.ts +104 -0
  244. package/src/tools/agent-settings-tool.ts +176 -0
  245. package/src/tools/agent-setup-tool.ts +226 -0
  246. package/src/tools/agent-support-tool.ts +122 -0
  247. package/src/tools/agent-terminal-process-tools.ts +167 -0
  248. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  249. package/src/tools/agent-tool-policy-guard.ts +106 -85
  250. package/src/tools/agent-vibe-tool.ts +297 -0
  251. package/src/tools/agent-work-plan-tool.ts +265 -6
  252. package/src/tools/agent-workspace-tool.ts +305 -0
  253. package/src/tools/artifact-archive.ts +169 -0
  254. package/src/tools/tool-definition-compaction.ts +36 -0
  255. package/src/version.ts +1 -1
@@ -12,6 +12,7 @@ interface HarnessModeDescriptor {
12
12
  readonly next?: string;
13
13
  readonly requiresConfirmation?: boolean;
14
14
  readonly aliases?: readonly AgentHarnessMode[];
15
+ readonly keywords?: readonly string[];
15
16
  readonly parameters?: readonly string[];
16
17
  }
17
18
 
@@ -31,54 +32,102 @@ export const HARNESS_MODE_DESCRIPTORS: readonly HarnessModeDescriptor[] = [
31
32
  { id: 'summary', kind: 'summary', family: 'start', summary: 'Compact harness map, counts, posture, and mode guide.', next: 'Use modes or a plural catalog mode to drill in.', parameters: ['includeParameters'] },
32
33
  { id: 'modes', kind: 'discover', family: 'start', summary: 'Search all agent_harness modes by task, family, effect, or id.', next: 'Use mode for one exact mode contract.', parameters: ['query', 'target', 'limit', 'includeParameters'] },
33
34
  { id: 'mode', kind: 'inspect', family: 'start', summary: 'Inspect one agent_harness mode contract and common next step.', next: 'Use target or query with a mode id or task phrase.', parameters: ['target', 'query'] },
34
- { id: 'cli_commands', kind: 'discover', family: 'cli', summary: 'List top-level package CLI mirrors for discovery only.', next: 'Use cli_command for one command.', parameters: ['query', 'limit', 'includeParameters'] },
35
+ { id: 'route_decision', kind: 'inspect', family: 'start', summary: 'Choose the best visible Agent route for a plain user task.', next: 'Prefer route action:"plan" for first-class access.', keywords: ['where should this go', 'which tool', 'route user task', 'one assistant', 'user-first route'], parameters: ['query', 'target', 'limit', 'includeParameters'] },
36
+ { id: 'cli_commands', kind: 'discover', family: 'cli', summary: 'List top-level package CLI mirrors for discovery only.', next: 'Prefer workspace action:"cli_commands|cli_command".', parameters: ['query', 'limit', 'includeParameters'] },
35
37
  { id: 'cli_command', kind: 'inspect', family: 'cli', summary: 'Inspect one CLI command parser result, policy, aliases, and model route.', parameters: ['cliCommand', 'command', 'commandName', 'target', 'query'] },
36
- { id: 'panels', kind: 'discover', family: 'ui', summary: 'List built-in panel catalog state and workspace routes.', next: 'Use panel or open_panel.', parameters: ['query', 'category', 'limit', 'includeParameters'] },
38
+ { id: 'panels', kind: 'discover', family: 'ui', summary: 'List built-in panel catalog state and workspace routes.', next: 'Prefer workspace action:"panels|panel|open_panel".', parameters: ['query', 'category', 'limit', 'includeParameters'] },
37
39
  { id: 'panel', kind: 'inspect', family: 'ui', summary: 'Inspect one built-in panel, open state, workspace route, and policy.', parameters: ['panelId', 'target', 'query'] },
38
40
  { id: 'open_panel', kind: 'effect', family: 'ui', summary: 'Route the visible shell to one built-in panel.', requiresConfirmation: true, parameters: ['panelId', 'target', 'query', 'pane', 'confirm', 'explicitUserRequest'] },
39
- { id: 'ui_surfaces', kind: 'discover', family: 'ui', summary: 'List modal, picker, and visible UI surfaces the model can request.', next: 'Use ui_surface or open_ui_surface.', parameters: ['query', 'limit', 'includeParameters'] },
40
- { id: 'ui_surface', kind: 'inspect', family: 'ui', summary: 'Inspect one visible modal or picker surface and route contract.', parameters: ['surfaceId', 'target', 'query'] },
41
- { id: 'open_ui_surface', kind: 'effect', family: 'ui', summary: 'Open one visible modal, picker, or operator workspace route.', requiresConfirmation: true, parameters: ['surfaceId', 'target', 'query', 'confirm', 'explicitUserRequest'] },
42
- { id: 'shortcuts', kind: 'discover', family: 'keyboard', summary: 'List fixed shortcuts and keybinding overview.', next: 'Use keybindings or keybinding for configurable actions.', parameters: ['query', 'limit', 'includeParameters'] },
43
- { id: 'keybindings', kind: 'discover', family: 'keyboard', summary: 'List configurable keybinding actions and current/default combos.', next: 'Use keybinding, run_keybinding, set_keybinding, or reset_keybinding.', parameters: ['query', 'limit', 'includeParameters'] },
41
+ { id: 'ui_surfaces', kind: 'discover', family: 'ui', summary: 'List modal, picker, and visible UI surfaces the model can request.', next: 'Prefer workspace action:"surfaces|surface|open".', keywords: ['web dashboard', 'pwa', 'browser cockpit', 'connected browser', 'mobile web'], parameters: ['query', 'limit', 'includeParameters'] },
42
+ { id: 'ui_surface', kind: 'inspect', family: 'ui', summary: 'Inspect one visible modal or picker surface and route contract.', keywords: ['web dashboard', 'pwa', 'browser cockpit', 'connected browser', 'mobile web'], parameters: ['surfaceId', 'target', 'query'] },
43
+ { id: 'open_ui_surface', kind: 'effect', family: 'ui', summary: 'Open one visible modal, picker, or operator workspace route.', requiresConfirmation: true, keywords: ['web dashboard', 'pwa', 'browser cockpit', 'connected browser', 'mobile web'], parameters: ['surfaceId', 'target', 'query', 'confirm', 'explicitUserRequest'] },
44
+ { id: 'shortcuts', kind: 'discover', family: 'keyboard', summary: 'List fixed shortcuts and keybinding overview.', next: 'Prefer workspace action:"shortcuts|keybindings|keybinding".', parameters: ['query', 'limit', 'includeParameters'] },
45
+ { id: 'keybindings', kind: 'discover', family: 'keyboard', summary: 'List configurable keybinding actions and current/default combos.', next: 'Prefer workspace keybinding actions.', parameters: ['query', 'limit', 'includeParameters'] },
44
46
  { id: 'keybinding', kind: 'inspect', family: 'keyboard', summary: 'Inspect one keybinding action, current combos, defaults, and policy.', parameters: ['actionId', 'key', 'target', 'query'] },
45
47
  { id: 'run_keybinding', kind: 'effect', family: 'keyboard', summary: 'Run one supported keybinding action through the active UI route.', requiresConfirmation: true, parameters: ['actionId', 'key', 'target', 'query', 'confirm', 'explicitUserRequest'] },
46
48
  { id: 'set_keybinding', kind: 'effect', family: 'keyboard', summary: 'Set one configurable keybinding action.', requiresConfirmation: true, parameters: ['actionId', 'combo', 'combos', 'confirm', 'explicitUserRequest'] },
47
49
  { id: 'reset_keybinding', kind: 'effect', family: 'keyboard', summary: 'Reset one configurable keybinding action to defaults.', requiresConfirmation: true, parameters: ['actionId', 'confirm', 'explicitUserRequest'] },
48
- { id: 'commands', kind: 'discover', family: 'slash', summary: 'List registered slash commands and compact policies.', next: 'Use command or run_command.', parameters: ['query', 'limit', 'includeParameters'] },
50
+ { id: 'commands', kind: 'discover', family: 'slash', summary: 'List registered slash commands and compact policies.', next: 'Prefer workspace action:"commands|command|run_command".', parameters: ['query', 'limit', 'includeParameters'] },
49
51
  { id: 'command', kind: 'inspect', family: 'slash', summary: 'Inspect slash command, parsed args, policy, aliases, and model route.', parameters: ['command', 'commandName', 'target', 'query'] },
50
52
  { id: 'run_command', kind: 'effect', family: 'slash', summary: 'Run one slash command through shared command dispatch.', requiresConfirmation: true, parameters: ['command', 'commandName', 'args', 'target', 'query', 'confirm', 'explicitUserRequest'] },
51
- { id: 'channels', kind: 'discover', family: 'delivery', summary: 'List channel readiness, accounts, delivery posture, and safe setup keys.', next: 'Use channel or agent_channel_send.', parameters: ['query', 'limit', 'includeParameters'] },
52
- { id: 'channel', kind: 'inspect', family: 'delivery', summary: 'Inspect one channel readiness entry and delivery policy.', parameters: ['channelId', 'target', 'query'] },
53
+ { id: 'channels', kind: 'discover', family: 'delivery', summary: 'List channel readiness, accounts, delivery posture, and safe setup keys.', next: 'Prefer channels action:"status|channel|setup".', parameters: ['query', 'limit', 'includeParameters'] },
54
+ { id: 'channel', kind: 'inspect', family: 'delivery', summary: 'Inspect one channel readiness entry and delivery policy.', next: 'Prefer channels action:"channel".', parameters: ['channelId', 'target', 'query'] },
55
+ { id: 'channel_setup_guide', kind: 'inspect', family: 'delivery', summary: 'Inspect the ordered channel setup guide and current per-channel step.', next: 'Prefer channels action:"setup".', parameters: ['channelId', 'target', 'query'] },
56
+ { id: 'channel_triage', kind: 'discover', family: 'delivery', summary: 'Triage blockers, retries, messages, routes, and receipts.', next: 'Prefer channels action:"triage".', keywords: ['inbox', 'triage', 'channel errors', 'delivery retries', 'pending messages', 'surface messages', 'route bindings'], parameters: ['limit', 'includeParameters'] },
57
+ { id: 'channel_deliveries', kind: 'discover', family: 'delivery', summary: 'List recent redacted confirmed channel delivery receipts.', next: 'Prefer channels action:"deliveries".', keywords: ['delivery receipts', 'channel history', 'sent messages', 'send outcomes'], parameters: ['limit', 'includeParameters'] },
53
58
  { id: 'notifications', kind: 'discover', family: 'delivery', summary: 'List notification target posture with webhook values redacted.', next: 'Use notification_target or agent_notify.', parameters: ['query', 'limit', 'includeParameters'] },
54
59
  { id: 'notification_target', kind: 'inspect', family: 'delivery', summary: 'Inspect one notification target and safe routing policy.', parameters: ['notificationTargetId', 'target', 'query'] },
55
- { id: 'provider_accounts', kind: 'discover', family: 'providers', summary: 'List provider auth, subscription, usage-window, and repair posture.', next: 'Use provider_account.', parameters: ['query', 'limit', 'includeParameters'] },
60
+ { id: 'provider_accounts', kind: 'discover', family: 'providers', summary: 'List provider auth, subscription, usage-window, and repair posture.', next: 'Prefer models action:"providers"; provider_account for detail.', parameters: ['query', 'limit', 'includeParameters'] },
56
61
  { id: 'provider_account', kind: 'inspect', family: 'providers', summary: 'Inspect one provider account/auth posture without token leakage.', parameters: ['providerId', 'target', 'query'] },
57
62
  { id: 'mcp_servers', kind: 'discover', family: 'tools', summary: 'List MCP server/tool/security posture without exposing env or secrets.', next: 'Use mcp_server.', parameters: ['query', 'limit', 'includeParameters'] },
58
63
  { id: 'mcp_server', kind: 'inspect', family: 'tools', summary: 'Inspect one MCP server, tools, schemas, auth, and trust posture.', parameters: ['mcpServerId', 'target', 'query'] },
59
- { id: 'setup_posture', kind: 'discover', family: 'setup', summary: 'Inspect first-run/setup capability posture and derived readiness flags.', next: 'Use setup_item.', parameters: ['query', 'limit', 'includeParameters'] },
60
- { id: 'setup_item', kind: 'inspect', family: 'setup', summary: 'Inspect one setup/onboarding posture item and visible remediation route.', parameters: ['setupItemId', 'target', 'query'] },
61
- { id: 'model_routing', kind: 'discover', family: 'providers', summary: 'List model/provider route, models, pins, and safe route settings.', next: 'Use model_route.', parameters: ['query', 'limit', 'includeParameters'] },
62
- { id: 'model_route', kind: 'inspect', family: 'providers', summary: 'Inspect one model route or model candidate and visible selection paths.', parameters: ['modelRouteId', 'target', 'query'] },
63
- { id: 'pairing_posture', kind: 'discover', family: 'companion', summary: 'List pairing routes, token posture, and safe handoff readiness.', next: 'Use pairing_route.', parameters: ['query', 'limit', 'includeParameters'] },
64
- { id: 'pairing_route', kind: 'inspect', family: 'companion', summary: 'Inspect one companion pairing route and safe visible handoff.', parameters: ['pairingRouteId', 'target', 'query'] },
65
- { id: 'delegation_posture', kind: 'discover', family: 'delegation', summary: 'List explicit build/fix/review delegation routes and boundaries.', next: 'Use delegation_route.', parameters: ['query', 'limit', 'includeParameters'] },
66
- { id: 'delegation_route', kind: 'inspect', family: 'delegation', summary: 'Inspect one delegation route and exact visible submission contract.', parameters: ['delegationRouteId', 'target', 'query'] },
64
+ { id: 'setup_posture', kind: 'discover', family: 'setup', summary: 'Inspect first-run/always-on setup plan, posture, and flags.', next: 'Use setup_item.', keywords: ['sudo', 'sudo_password', 'SUDO_PASSWORD', 'pty', 'process write', 'credential posture'], parameters: ['query', 'limit', 'includeParameters'] },
65
+ { id: 'setup_item', kind: 'inspect', family: 'setup', summary: 'Inspect one first-run/always-on setup plan item.', keywords: ['sudo', 'sudo_password', 'SUDO_PASSWORD', 'pty', 'process write', 'credential posture'], parameters: ['setupItemId', 'target', 'query'] },
66
+ { id: 'setup_repair', kind: 'inspect', family: 'setup', summary: 'Choose the safest next setup repair route.', next: 'Prefer setup action:"repair".', keywords: ['repair setup', 'fix setup', 'launch host', 'start host', 'daemon repair', 'service status receipt', 'bootstrap host'], parameters: ['setupItemId', 'target', 'query', 'includeParameters'] },
67
+ { id: 'setup_checkpoint', kind: 'inspect', family: 'setup', summary: 'Inspect saved setup wizard checkpoint and current resume step.', parameters: ['includeParameters'] },
68
+ { id: 'mark_setup_checkpoint', kind: 'effect', family: 'setup', summary: 'Save the current setup wizard step as the resume checkpoint.', requiresConfirmation: true, parameters: ['setupItemId', 'confirm', 'explicitUserRequest'] },
69
+ { id: 'clear_setup_checkpoint', kind: 'effect', family: 'setup', summary: 'Clear the saved setup wizard checkpoint.', requiresConfirmation: true, parameters: ['confirm', 'explicitUserRequest'] },
70
+ { id: 'provision_connected_host_token', kind: 'effect', family: 'setup', summary: 'Create or repair local connected-host token safely.', requiresConfirmation: true, parameters: ['setupItemId', 'confirm', 'explicitUserRequest'] },
71
+ { id: 'run_setup_smoke', kind: 'effect', family: 'setup', summary: 'Run redacted first-run setup smoke evidence collection.', requiresConfirmation: true, parameters: ['setupItemId', 'fields', 'includeParameters', 'confirm', 'explicitUserRequest'] },
72
+ { id: 'project_context', kind: 'discover', family: 'context', summary: 'List AGENTS, HERMES, CLAUDE, SOUL, and Cursor context files.', next: 'Prefer context action:"files|file".', keywords: ['agents.md', 'hermes.md', '.hermes.md', 'claude.md', 'soul.md', '.cursorrules', '.cursor/rules', 'project instructions'], parameters: ['target', 'query', 'includeParameters'] },
73
+ { id: 'project_context_file', kind: 'inspect', family: 'context', summary: 'Inspect one project context file body, source, or blocked reason.', next: 'Prefer context action:"file".', keywords: ['agents.md', 'hermes.md', '.hermes.md', 'claude.md', 'soul.md', '.cursorrules', '.cursor/rules', 'project instructions'], parameters: ['contextFileId', 'target', 'query', 'includeParameters'] },
74
+ { id: 'prompt_context', kind: 'inspect', family: 'context', summary: 'Inspect prompt context, receipt outcomes, and token budget.', next: 'Prefer context action:"prompt|receipts|receipt".', keywords: ['prompt context', 'system prompt', 'why assistant acts', 'selected memory', 'active persona', 'suppressed context', 'token budget', 'receipt id', 'turn outcome', 'prompt receipt filters'], parameters: ['receiptId', 'turnId', 'outcomeStatus', 'limit', 'includeParameters'] },
75
+ { id: 'agent_orchestration', kind: 'discover', family: 'execution', summary: 'Inspect managed plan cards, closeout evidence, and dispatch routes.', next: 'Inspect one agent; dispatch approved plan items via agent_work_plan.', keywords: ['subagent', 'subagents', 'agent spawn', 'batch-spawn', 'dispatch agents', 'work plan dispatch', 'dispatch receipts', 'closeout evidence', 'multi-agent', 'multi-runner', 'managed plan', 'milestone', 'remote runner', 'artifact trail', 'visible agents', 'cancellable agents', 'wrfc', 'cohort'], parameters: ['query', 'limit', 'includeParameters'] },
76
+ { id: 'agent_orchestration_agent', kind: 'inspect', family: 'execution', summary: 'Inspect one visible Agent record with plan card and safe controls.', keywords: ['subagent', 'subagents', 'agent status', 'agent cancel', 'agent wait', 'agent message', 'batch-spawn', 'dispatch receipts', 'closeout evidence', 'multi-agent', 'multi-runner', 'managed plan', 'milestone', 'remote runner', 'artifact trail', 'visible agents', 'cancellable agents', 'wrfc', 'cohort'], parameters: ['agentId', 'target', 'query', 'includeParameters'] },
77
+ { id: 'model_routing', kind: 'discover', family: 'providers', summary: 'List model routes, readiness scores, local cookbook, and pins.', next: 'Prefer models action:"status|local|route|smoke".', parameters: ['query', 'limit', 'includeParameters'] },
78
+ { id: 'model_route', kind: 'inspect', family: 'providers', summary: 'Inspect one model route, local endpoint, fit score, or picker path.', parameters: ['modelRouteId', 'target', 'query'] },
79
+ { id: 'run_local_model_smoke', kind: 'effect', family: 'providers', summary: 'Run confirmed read-only model-list smoke checks for local endpoints.', requiresConfirmation: true, keywords: ['local model smoke', 'check local servers', 'ollama models', 'local endpoint probe'], parameters: ['modelRouteId', 'target', 'query', 'limit', 'timeoutMs', 'confirm', 'explicitUserRequest'] },
80
+ { id: 'execution_posture', kind: 'discover', family: 'execution', summary: 'Pick local shell/edit execution vs delegation.', next: 'Prefer execution action:"status"; use action:"route" for one.', keywords: ['sudo', 'sudo_password', 'SUDO_PASSWORD', 'foreground shell', 'privilege escalation'], parameters: ['query', 'limit', 'includeParameters'] },
81
+ { id: 'execution_route', kind: 'inspect', family: 'execution', summary: 'Inspect one local, browser, web, or delegation route.', next: 'Prefer execution action:"route".', keywords: ['sudo', 'sudo_password', 'SUDO_PASSWORD', 'foreground shell', 'privilege escalation'], parameters: ['executionRouteId', 'target', 'query'] },
82
+ { id: 'browser_control_route', kind: 'inspect', family: 'execution', summary: 'Plan browser, screenshot, or desktop-control route.', next: 'Prefer computer action:"plan".', keywords: ['browser control plan', 'take screenshot', 'screen observe', 'desktop control', 'live ui control', 'browser navigation'], parameters: ['target', 'query', 'includeParameters'] },
83
+ { id: 'background_processes', kind: 'discover', family: 'execution', summary: 'List tracked local background processes, logs, and lifecycle routes.', next: 'Prefer execution action:"processes"; use process for lifecycle effects.', parameters: ['query', 'target', 'limit', 'includeParameters'] },
84
+ { id: 'background_process', kind: 'inspect', family: 'execution', summary: 'Inspect one tracked background process with bounded output tails.', next: 'Prefer execution action:"process".', keywords: ['session id', 'process session', 'poll', 'log'], parameters: ['processId', 'processSessionId', 'sessionId', 'session_id', 'target', 'query', 'includeParameters'] },
85
+ { id: 'run_background_process', kind: 'effect', family: 'execution', summary: 'Process lifecycle with poll/log/kill aliases and PTY/sudo gaps.', requiresConfirmation: true, keywords: ['process tool', 'session id', 'process session', 'poll', 'kill', 'write', 'log', 'pty', 'sudo'], parameters: ['processAction', 'action', 'processId', 'processSessionId', 'sessionId', 'session_id', 'command', 'cwd', 'timeoutMs', 'pty', 'data', 'fields', 'confirm', 'explicitUserRequest'] },
86
+ { id: 'execution_history', kind: 'discover', family: 'execution', summary: 'List recent execution activity cards and raw records.', next: 'Prefer execution action:"history"; use action:"record" for one.', parameters: ['query', 'limit', 'includeParameters'] },
87
+ { id: 'execution_history_item', kind: 'inspect', family: 'execution', summary: 'Inspect one execution record with user card, routes, and recovery.', next: 'Prefer execution action:"record".', parameters: ['executionRecordId', 'recordId', 'target', 'query'] },
88
+ { id: 'file_recovery', kind: 'discover', family: 'execution', summary: 'Inspect local file edit undo/redo recovery.', next: 'Prefer execution action:"recovery"; apply with confirmation.', parameters: ['includeParameters'] },
89
+ { id: 'run_file_recovery', kind: 'effect', family: 'execution', summary: 'Apply one local file undo or redo snapshot.', requiresConfirmation: true, parameters: ['recoveryAction', 'target', 'query', 'confirm', 'explicitUserRequest'] },
90
+ { id: 'personal_ops_briefing', kind: 'discover', family: 'personal-ops', summary: 'Build a daily briefing plan across Personal Ops and autonomy.', next: 'Prefer personal_ops action:"briefing".', keywords: ['daily brief', 'morning brief', 'operator brief', 'personal briefing', 'daily ops', 'personal operations'], parameters: ['query', 'target', 'limit', 'includeParameters'] },
91
+ { id: 'personal_ops', kind: 'discover', family: 'personal-ops', summary: 'Map email/calendar tasks, reminders, records, and operation cards.', next: 'Prefer personal_ops action:"status".', keywords: ['personal operations'], parameters: ['includeParameters'] },
92
+ { id: 'personal_ops_queue', kind: 'discover', family: 'personal-ops', summary: 'List saved inbox/calendar review queues and fresh-read routes.', next: 'Prefer personal_ops action:"queue".', keywords: ['personal operations', 'inbox queue', 'email queue', 'calendar queue', 'agenda queue', 'saved review', 'daily ops'], parameters: ['query', 'target', 'limit', 'includeParameters'] },
93
+ { id: 'personal_ops_intake', kind: 'discover', family: 'personal-ops', summary: 'Plan personal requests to safe routes, fields, and confirmations.', next: 'Prefer personal_ops action:"intake".', keywords: ['personal operations', 'email calendar tasks reminders', 'email triage', 'inbox triage', 'draft reply', 'calendar briefing', 'agenda briefing', 'calendar conflicts', 'personal request', 'daily ops'], parameters: ['query', 'target', 'limit', 'includeParameters'] },
94
+ { id: 'personal_ops_lane', kind: 'inspect', family: 'personal-ops', summary: 'Inspect email/calendar tasks/reminders records, cards, and routes.', keywords: ['personal operations'], parameters: ['laneId', 'target', 'query'] },
95
+ { id: 'run_personal_ops_read', kind: 'effect', family: 'personal-ops', summary: 'Run one confirmed read-only inbox/calendar MCP operation.', next: 'Prefer personal_ops action:"read" for user-facing calls.', requiresConfirmation: true, keywords: ['email triage', 'inbox read', 'calendar read', 'agenda read', 'mcp call tool'], parameters: ['laneId', 'recordId', 'target', 'query', 'fields', 'includeParameters', 'confirm', 'explicitUserRequest'] },
96
+ { id: 'memory_posture', kind: 'discover', family: 'personal-ops', summary: 'Inspect Agent-local memory, vector recall, and provider posture.', next: 'Prefer memory action:"status"; use action:"provider" for one.', keywords: ['semantic recall', 'external memory', 'memory provider', 'honcho', 'openviking', 'mem0', 'hindsight', 'holographic', 'retaindb', 'byterover', 'supermemory'], parameters: ['query', 'limit', 'includeParameters'] },
97
+ { id: 'memory_provider', kind: 'inspect', family: 'personal-ops', summary: 'Inspect one memory embedding or external-memory provider record.', keywords: ['semantic recall', 'external memory', 'embedding provider', 'memory provider', 'honcho', 'openviking', 'mem0', 'hindsight', 'holographic', 'retaindb', 'byterover', 'supermemory'], parameters: ['providerId', 'target', 'query', 'includeParameters'] },
98
+ { id: 'autonomy_intake', kind: 'discover', family: 'personal-ops', summary: 'Route ongoing work with schedule and watcher trigger posture.', next: 'Prefer autonomy action:"intake"; use returned route or action:"queue".', keywords: ['incoming webhook', 'webhook watcher', 'watcher trigger', 'event trigger', 'gmail trigger', 'cron wakeup'], parameters: ['query', 'target', 'includeParameters'] },
99
+ { id: 'autonomy_queue', kind: 'discover', family: 'personal-ops', summary: 'List autonomy work with live records, tails, and controls.', next: 'Prefer autonomy action:"queue"; inspect one with action:"item".', parameters: ['query', 'limit', 'includeParameters'] },
100
+ { id: 'autonomy_queue_item', kind: 'inspect', family: 'personal-ops', summary: 'Inspect one autonomy card, live records, tails, and routes.', next: 'Prefer autonomy action:"item".', parameters: ['queueItemId', 'target', 'query'] },
101
+ { id: 'learning_curator', kind: 'discover', family: 'personal-ops', summary: 'Rank memory, notes, personas, skills, routines review/proposals.', next: 'Prefer memory action:"curator"; use action:"candidate" for one card.', parameters: ['query', 'limit', 'includeParameters'] },
102
+ { id: 'learning_candidate', kind: 'inspect', family: 'personal-ops', summary: 'Inspect one local-learning candidate and safe existing routes.', parameters: ['candidateId', 'target', 'query'] },
103
+ { id: 'research_briefing', kind: 'discover', family: 'research', summary: 'Show one next-action queue for research runs, sources, reports.', next: 'Use research action:"briefing".', keywords: ['deep research', 'research cockpit', 'research next actions', 'research queue', 'source review', 'report queue'], parameters: ['query', 'target', 'limit', 'includeParameters'] },
104
+ { id: 'research_workflow', kind: 'discover', family: 'research', summary: 'Plan research routes across run, source, report, browser, Knowledge.', next: 'Use research action:"plan"; runner checks browser readiness only.', parameters: ['query', 'target', 'runId', 'includeParameters'] },
105
+ { id: 'research_runs', kind: 'discover', family: 'research', summary: 'List deep-research runs, phase, log tails, and controls.', next: 'Use research_run for one run.', parameters: ['query', 'limit', 'includeParameters'] },
106
+ { id: 'research_run', kind: 'inspect', family: 'research', summary: 'Inspect one research run, log tail, checkpoints, and controls.', parameters: ['runId', 'target', 'query'] },
107
+ { id: 'research_queue', kind: 'discover', family: 'research', summary: 'List research sources, credibility, bundle route, and next actions.', next: 'Use research_source for one source.', parameters: ['query', 'limit', 'includeParameters'] },
108
+ { id: 'research_source', kind: 'inspect', family: 'research', summary: 'Inspect one source, report line, bundle, review, or ingest routes.', parameters: ['sourceId', 'target', 'query'] },
109
+ { id: 'document_ops', kind: 'discover', family: 'documents', summary: 'Map document uploads, artifacts, packet wizard, blind model compare.', next: 'Use document_ops_lane for wizard, readiness, artifacts, compare.', keywords: ['document upload', 'document uploads', 'artifact', 'artifacts', 'blind model comparison', 'blind model compare'], parameters: ['includeParameters'] },
110
+ { id: 'document_ops_lane', kind: 'inspect', family: 'documents', summary: 'Inspect document packet wizard, artifacts, readiness, blind compare.', keywords: ['document upload', 'document uploads', 'artifact', 'artifacts', 'blind model comparison', 'blind model compare'], parameters: ['laneId', 'target', 'query'] },
111
+ { id: 'pairing_posture', kind: 'discover', family: 'companion', summary: 'List pairing, tokens, and device capability readiness.', next: 'Use pairing_route.', keywords: ['mobile', 'phone', 'device', 'camera', 'screen', 'location', 'voice', 'pwa', 'companion capability', 'device commands'], parameters: ['query', 'limit', 'includeParameters'] },
112
+ { id: 'pairing_route', kind: 'inspect', family: 'companion', summary: 'Inspect one pairing or device capability handoff.', keywords: ['mobile', 'phone', 'device', 'camera', 'screen', 'location', 'voice', 'pwa', 'companion capability', 'device commands'], parameters: ['pairingRouteId', 'target', 'query'] },
113
+ { id: 'delegation_posture', kind: 'discover', family: 'delegation', summary: 'List explicit build/fix/review delegation routes and boundaries.', next: 'Prefer delegation action:"status|routes"; use action:"route" for one.', parameters: ['query', 'limit', 'includeParameters'] },
114
+ { id: 'delegation_route', kind: 'inspect', family: 'delegation', summary: 'Inspect one delegation route and exact visible submission contract.', next: 'Prefer delegation action:"route".', parameters: ['delegationRouteId', 'target', 'query'] },
67
115
  { id: 'security_posture', kind: 'discover', family: 'security', summary: 'List security posture findings without exposing secrets or raw config.', next: 'Use security_finding.', parameters: ['query', 'limit', 'includeParameters'] },
68
116
  { id: 'security_finding', kind: 'inspect', family: 'security', summary: 'Inspect one security posture finding and safe remediation route.', parameters: ['findingId', 'target', 'query'] },
117
+ { id: 'policy_explain', kind: 'inspect', family: 'security', summary: 'Explain one model action policy and confirmation route.', next: 'Prefer security action:"explain".', keywords: ['why allowed', 'why denied', 'requires confirmation', 'permission policy', 'tool policy'], parameters: ['toolName', 'tool', 'toolArgs', 'target', 'query', 'includeParameters'] },
69
118
  { id: 'support_bundles', kind: 'discover', family: 'support', summary: 'List support bundle artifacts and redacted export/import posture.', next: 'Use support_bundle.', parameters: ['query', 'limit', 'includeParameters'] },
70
119
  { id: 'support_bundle', kind: 'inspect', family: 'support', summary: 'Inspect one support bundle artifact and redaction posture.', parameters: ['bundlePath', 'target', 'query'] },
71
- { id: 'media_posture', kind: 'discover', family: 'media', summary: 'List media/voice readiness, browser posture, and artifact routes.', next: 'Use media_provider or agent_media_generate.', parameters: ['query', 'limit', 'includeParameters'] },
72
- { id: 'media_provider', kind: 'inspect', family: 'media', summary: 'Inspect one voice or media provider readiness entry.', parameters: ['mediaProviderId', 'target', 'query'] },
120
+ { id: 'media_posture', kind: 'discover', family: 'media', summary: 'List media/voice readiness, browser posture, and artifact routes.', next: 'Use media_provider or agent_media_generate.', keywords: ['push to talk', 'wake word', 'spoken response', 'tts voice', 'voice controls', 'phone voice'], parameters: ['query', 'limit', 'includeParameters'] },
121
+ { id: 'media_provider', kind: 'inspect', family: 'media', summary: 'Inspect one voice or media provider readiness entry.', keywords: ['push to talk', 'wake word', 'spoken response', 'tts voice', 'voice controls', 'phone voice'], parameters: ['mediaProviderId', 'target', 'query'] },
73
122
  { id: 'sessions', kind: 'discover', family: 'sessions', summary: 'List saved sessions, bookmarks, exports, and pending approvals posture.', next: 'Use session.', parameters: ['query', 'limit', 'includeParameters'] },
74
123
  { id: 'session', kind: 'inspect', family: 'sessions', summary: 'Inspect one saved session or bookmark entry.', parameters: ['sessionId', 'target', 'query'] },
75
- { id: 'settings', kind: 'discover', family: 'settings', summary: 'Search Agent settings compactly by category, prefix, or query.', next: 'Use get_setting, set_setting, or reset_setting.', parameters: ['category', 'prefix', 'query', 'includeHidden', 'limit', 'includeParameters'] },
124
+ { id: 'settings', kind: 'discover', family: 'settings', summary: 'Search Agent settings compactly by category, prefix, or query.', next: 'Prefer settings action:"list|get|set|reset|import".', parameters: ['category', 'prefix', 'query', 'includeHidden', 'limit', 'includeParameters'] },
76
125
  { id: 'get_setting', kind: 'inspect', family: 'settings', summary: 'Inspect one Agent setting descriptor, value, default, and policy.', parameters: ['key', 'target', 'query'] },
77
126
  { id: 'set_setting', kind: 'effect', family: 'settings', summary: 'Set one Agent-owned setting through config/secret managers.', requiresConfirmation: true, parameters: ['key', 'target', 'query', 'value', 'confirm', 'explicitUserRequest'] },
78
127
  { id: 'reset_setting', kind: 'effect', family: 'settings', summary: 'Reset one Agent-owned setting and delete secret refs when needed.', requiresConfirmation: true, parameters: ['key', 'target', 'query', 'confirm', 'explicitUserRequest'] },
79
- { id: 'workspace', kind: 'discover', family: 'workspace', summary: 'List Agent workspace categories and action counts.', next: 'Use workspace_actions or workspace_action.' },
80
- { id: 'workspace_categories', kind: 'discover', family: 'workspace', summary: 'Alias of workspace for category discovery.', next: 'Use workspace_actions or workspace_action.', aliases: ['workspace'] },
81
- { id: 'workspace_actions', kind: 'discover', family: 'workspace', summary: 'Search all user-facing Agent workspace actions and compact model routes.', next: 'Use workspace_action or run_workspace_action.', parameters: ['categoryId', 'query', 'limit', 'includeParameters'] },
128
+ { id: 'workspace', kind: 'discover', family: 'workspace', summary: 'List Agent workspace categories and action counts.', next: 'Prefer workspace action:"status|actions|action".' },
129
+ { id: 'workspace_categories', kind: 'discover', family: 'workspace', summary: 'Alias of workspace for category discovery.', next: 'Prefer workspace action:"status|actions|action".', aliases: ['workspace'] },
130
+ { id: 'workspace_actions', kind: 'discover', family: 'workspace', summary: 'Search all user-facing Agent workspace actions and compact model routes.', next: 'Prefer workspace action:"actions|action|run".', parameters: ['categoryId', 'query', 'limit', 'includeParameters'] },
82
131
  { id: 'workspace_action', kind: 'inspect', family: 'workspace', summary: 'Inspect one workspace action, editor schema, route, and safety policy.', parameters: ['actionId', 'command', 'target', 'query', 'recordId'] },
83
132
  { id: 'run_workspace_action', kind: 'effect', family: 'workspace', summary: 'Run a workspace action or return its model execution handoff.', requiresConfirmation: true, parameters: ['actionId', 'command', 'target', 'query', 'recordId', 'fields', 'confirm', 'explicitUserRequest'] },
84
133
  { id: 'tools', kind: 'discover', family: 'tools', summary: 'List first-class model tool definitions compactly.', next: 'Use tool for full schema.', parameters: ['query', 'limit', 'includeParameters'] },
@@ -87,15 +136,15 @@ export const HARNESS_MODE_DESCRIPTORS: readonly HarnessModeDescriptor[] = [
87
136
  { id: 'release_evidence_artifact', kind: 'inspect', family: 'operator-audit', summary: 'Inspect one operator/audit release artifact and optional content.', parameters: ['artifactId', 'target', 'query'] },
88
137
  { id: 'release_readiness', kind: 'discover', family: 'operator-audit', summary: 'Search the operator/audit release-quality inventory.', next: 'Use release_readiness_item.', parameters: ['query', 'limit', 'includeParameters'] },
89
138
  { id: 'release_readiness_item', kind: 'inspect', family: 'operator-audit', summary: 'Inspect one operator/audit readiness inventory item.', parameters: ['itemId', 'target', 'query'] },
90
- { id: 'operator_methods', kind: 'discover', family: 'operator', summary: 'List public operator/Agent Knowledge methods and owning tools.', next: 'Use operator_method.', parameters: ['query', 'limit', 'includeParameters'] },
91
- { id: 'operator_method', kind: 'inspect', family: 'operator', summary: 'Inspect one operator method and preferred first-class model tool.', parameters: ['methodId', 'target', 'query'] },
92
- { id: 'service_posture', kind: 'discover', family: 'connected-host', summary: 'Inspect service endpoint posture, binding, issues, and probes.', next: 'Use service_endpoint.', parameters: ['includeParameters'] },
139
+ { id: 'operator_methods', kind: 'discover', family: 'operator', summary: 'List GoodVibes daemon operator methods from the live SDK contract.', next: 'Prefer host action:"methods|method"; execute with agent_operator_method.', parameters: ['query', 'limit', 'includeParameters'] },
140
+ { id: 'operator_method', kind: 'inspect', family: 'operator', summary: 'Inspect one daemon method, route, effect, and confirmation policy.', next: 'Prefer host action:"method".', parameters: ['methodId', 'target', 'query'] },
141
+ { id: 'service_posture', kind: 'discover', family: 'connected-host', summary: 'Inspect service endpoint posture, binding, issues, and probes.', next: 'Prefer host action:"services|service".', parameters: ['includeParameters'] },
93
142
  { id: 'service_endpoint', kind: 'inspect', family: 'connected-host', summary: 'Inspect one service endpoint binding and lifecycle boundary.', parameters: ['endpointId', 'target', 'query'] },
94
- { id: 'connected_host', kind: 'discover', family: 'connected-host', summary: 'Map connected-host capabilities, boundaries, and tool availability.', next: 'Use connected_host_capability or connected_host_status.', parameters: ['includeParameters'] },
95
- { id: 'connected_host_status', kind: 'inspect', family: 'connected-host', summary: 'Run live read-only connected-host readiness checks.', parameters: ['includeParameters'] },
96
- { id: 'connected_host_capability', kind: 'inspect', family: 'connected-host', summary: 'Inspect one connected-host capability and blocked surfaces.', parameters: ['capabilityId', 'target', 'query'] },
97
- { id: 'daemon', kind: 'alias', family: 'connected-host', summary: 'GoodVibes daemon -> connected_host; lifecycle external.', next: 'Use connected_host for canonical naming.', aliases: ['connected_host'], parameters: ['includeParameters'] },
98
- { id: 'daemon_status', kind: 'alias', family: 'connected-host', summary: 'GoodVibes daemon status -> connected_host_status.', next: 'Use connected_host_status for canonical naming.', aliases: ['connected_host_status'], parameters: ['includeParameters'] },
143
+ { id: 'connected_host', kind: 'discover', family: 'connected-host', summary: 'Map connected-host capabilities, boundaries, and tool availability.', next: 'Prefer host action:"capabilities|capability|status".', parameters: ['includeParameters'] },
144
+ { id: 'connected_host_status', kind: 'inspect', family: 'connected-host', summary: 'Run live read-only connected-host readiness checks.', next: 'Prefer host action:"status".', parameters: ['includeParameters'] },
145
+ { id: 'connected_host_capability', kind: 'inspect', family: 'connected-host', summary: 'Inspect one connected-host capability and blocked surfaces.', next: 'Prefer host action:"capability".', parameters: ['capabilityId', 'target', 'query'] },
146
+ { id: 'daemon', kind: 'alias', family: 'connected-host', summary: 'GoodVibes daemon -> connected_host; mutations use confirmed methods.', next: 'Prefer host action:"capabilities".', aliases: ['connected_host'], parameters: ['includeParameters'] },
147
+ { id: 'daemon_status', kind: 'alias', family: 'connected-host', summary: 'GoodVibes daemon status -> connected_host_status.', next: 'Prefer host action:"status".', aliases: ['connected_host_status'], parameters: ['includeParameters'] },
99
148
  ] as const;
100
149
 
101
150
  function readString(value: unknown): string {
@@ -138,6 +187,7 @@ function harnessModeSearchText(descriptor: HarnessModeDescriptor): string {
138
187
  descriptor.summary,
139
188
  descriptor.next,
140
189
  ...(descriptor.aliases ?? []),
190
+ ...(descriptor.keywords ?? []),
141
191
  ...(descriptor.parameters ?? []),
142
192
  ].filter(Boolean).join('\n').toLowerCase();
143
193
  }
@@ -182,6 +232,7 @@ function harnessModeRelevance(descriptor: HarnessModeDescriptor, input: string):
182
232
  score += tokenScore(tokens, descriptor.kind, 500);
183
233
  score += tokenScore(tokens, (descriptor.parameters ?? []).join('\n'), 350);
184
234
  score += tokenScore(tokens, descriptor.summary, 200);
235
+ score += tokenScore(tokens, (descriptor.keywords ?? []).join('\n'), 150);
185
236
  score += tokenScore(tokens, descriptor.next, 100);
186
237
 
187
238
  const actionVerb = tokens.find((token) => ACTION_VERBS.has(token));
@@ -0,0 +1,162 @@
1
+ import type { ArtifactDescriptor } from '@pellux/goodvibes-sdk/platform/artifacts';
2
+ import type { CommandContext } from '../input/command-registry.ts';
3
+ import { requireProviderApi } from '../input/commands/runtime-services.ts';
4
+ import type { ArtifactListLike, ModelCandidate, ProviderApiLike } from './agent-harness-model-routing-types.ts';
5
+ import { readRecord, readString, readStringArray } from './agent-harness-model-routing-utils.ts';
6
+
7
+ export function readProviderModels(value: unknown, providerId: string): readonly string[] {
8
+ if (!Array.isArray(value)) return [];
9
+ return value.map((entry) => {
10
+ if (typeof entry === 'string') return providerId ? `${providerId}:${entry}` : entry;
11
+ const modelId = modelModelId(entry);
12
+ const registryKey = modelRegistryKey(entry);
13
+ return registryKey || (providerId && modelId ? `${providerId}:${modelId}` : modelId);
14
+ }).filter(Boolean);
15
+ }
16
+
17
+ export function readArtifactStore(context: CommandContext): ArtifactListLike | null {
18
+ const candidate = (context.platform as { readonly artifactStore?: unknown }).artifactStore;
19
+ return candidate && typeof candidate === 'object' ? candidate as ArtifactListLike : null;
20
+ }
21
+
22
+ export function readConfig(context: CommandContext, key: string): unknown {
23
+ try {
24
+ return (context.platform.configManager as { get(settingKey: string): unknown }).get(key);
25
+ } catch {
26
+ return undefined;
27
+ }
28
+ }
29
+
30
+ export function contextWindowFor(context: CommandContext, model: unknown): number | null {
31
+ const record = readRecord(model);
32
+ const direct = record.contextWindow;
33
+ if (typeof direct === 'number' && Number.isFinite(direct)) return direct;
34
+ try {
35
+ const registry = context.provider.providerRegistry as { getContextWindowForModel(candidate: unknown): number };
36
+ const value = registry.getContextWindowForModel(model);
37
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+
43
+ export function modelRegistryKey(model: unknown): string {
44
+ const record = readRecord(model);
45
+ return readString(record.registryKey) || readString(record.id) || readString(record.modelId);
46
+ }
47
+
48
+ export function modelProviderId(model: unknown): string {
49
+ const record = readRecord(model);
50
+ return readString(record.providerId) || readString(record.provider);
51
+ }
52
+
53
+ export function modelModelId(model: unknown): string {
54
+ const record = readRecord(model);
55
+ return readString(record.modelId) || readString(record.id) || modelRegistryKey(model);
56
+ }
57
+
58
+ export function modelDisplayName(model: unknown): string {
59
+ const record = readRecord(model);
60
+ return readString(record.displayName) || readString(record.name) || modelRegistryKey(model);
61
+ }
62
+
63
+ export function modelCurrent(model: unknown): boolean {
64
+ const record = readRecord(model);
65
+ return record.current === true;
66
+ }
67
+
68
+ export function modelReasoning(model: unknown): readonly string[] {
69
+ const record = readRecord(model);
70
+ return readStringArray(record.reasoningEffort);
71
+ }
72
+
73
+ export function modelCapabilities(model: unknown): unknown {
74
+ return readRecord(model).capabilities ?? null;
75
+ }
76
+
77
+ export function modelTier(model: unknown): string | undefined {
78
+ return readString(readRecord(model).tier) || undefined;
79
+ }
80
+
81
+ export function modelBenchmarkCompositeScore(model: unknown): number | null {
82
+ const benchmark = readRecord(readRecord(model).benchmark);
83
+ const value = benchmark.compositeScore;
84
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
85
+ }
86
+
87
+ export function modelBenchmarkQualityTier(model: unknown): string | undefined {
88
+ return readString(readRecord(readRecord(model).benchmark).qualityTier) || undefined;
89
+ }
90
+
91
+ export function readProviderApi(context: CommandContext): ProviderApiLike | null {
92
+ try {
93
+ return requireProviderApi(context) as ProviderApiLike;
94
+ } catch {
95
+ return null;
96
+ }
97
+ }
98
+
99
+ export async function loadPinnedModelIds(context: CommandContext): Promise<ReadonlySet<string>> {
100
+ const providerApi = readProviderApi(context);
101
+ if (!providerApi) return new Set();
102
+ try {
103
+ const favorites = await providerApi.getFavorites();
104
+ const pinned = readRecord(favorites).pinned;
105
+ if (!Array.isArray(pinned)) return new Set();
106
+ return new Set(pinned.flatMap((entry) => {
107
+ const record = readRecord(entry);
108
+ return [readString(record.registryKey), readString(record.modelId)].filter(Boolean);
109
+ }));
110
+ } catch {
111
+ return new Set();
112
+ }
113
+ }
114
+
115
+ export async function loadModels(context: CommandContext): Promise<readonly ModelCandidate[]> {
116
+ const providerApi = readProviderApi(context);
117
+ if (!providerApi) return [];
118
+ const pinned = await loadPinnedModelIds(context);
119
+ const models = await providerApi.listModels({ selectableOnly: true });
120
+ return models.map((model) => {
121
+ const registryKey = modelRegistryKey(model);
122
+ const modelId = modelModelId(model);
123
+ return {
124
+ kind: 'model',
125
+ id: registryKey,
126
+ registryKey,
127
+ modelId,
128
+ providerId: modelProviderId(model),
129
+ displayName: modelDisplayName(model),
130
+ current: modelCurrent(model) || registryKey === context.session.runtime.model,
131
+ contextWindow: contextWindowFor(context, model),
132
+ reasoningEffort: modelReasoning(model),
133
+ capabilities: modelCapabilities(model),
134
+ tier: modelTier(model),
135
+ benchmarkCompositeScore: modelBenchmarkCompositeScore(model),
136
+ benchmarkQualityTier: modelBenchmarkQualityTier(model),
137
+ pinned: pinned.has(registryKey) || pinned.has(modelId),
138
+ };
139
+ });
140
+ }
141
+
142
+ export function listProviderIds(context: CommandContext): readonly string[] {
143
+ return readProviderApi(context)?.listProviderIds() ?? [];
144
+ }
145
+
146
+ export function listRegistryModels(context: CommandContext): readonly unknown[] {
147
+ try {
148
+ const registry = context.provider.providerRegistry as { listModels?: () => readonly unknown[] };
149
+ return registry.listModels?.() ?? [];
150
+ } catch {
151
+ return [];
152
+ }
153
+ }
154
+
155
+ export function listProviderRegistryProviders(context: CommandContext): readonly unknown[] {
156
+ try {
157
+ const registry = context.provider.providerRegistry as { listProviders?: () => readonly unknown[] };
158
+ return registry.listProviders?.() ?? [];
159
+ } catch {
160
+ return [];
161
+ }
162
+ }
@@ -0,0 +1,186 @@
1
+ import type { CommandContext } from '../input/command-registry.ts';
2
+ import { previewHarnessText } from './agent-harness-text.ts';
3
+ import type { ModelProviderHealthSignal } from './agent-harness-model-routing-types.ts';
4
+ import { readBoolean, readFiniteNumber, readRecord, readString, safeIso } from './agent-harness-model-routing-utils.ts';
5
+
6
+ function readPotentialProviderHealthSnapshot(source: unknown): unknown {
7
+ if (!source || typeof source !== 'object') return null;
8
+ const record = source as Record<string, unknown>;
9
+ const directSnapshot = typeof record.getSnapshot === 'function'
10
+ ? (record.getSnapshot as () => unknown)()
11
+ : null;
12
+ return directSnapshot ?? record.snapshot ?? record.data ?? record.state ?? source;
13
+ }
14
+
15
+ function providerHealthCandidatesFromSnapshot(snapshot: unknown): readonly Record<string, unknown>[] {
16
+ if (!snapshot || typeof snapshot !== 'object') return [];
17
+ if (snapshot instanceof Map) {
18
+ return [...snapshot.entries()].map(([key, entry]) => {
19
+ const record = readRecord(entry);
20
+ return { ...record, providerId: readString(record.providerId) || readString(key) };
21
+ });
22
+ }
23
+ const record = readRecord(snapshot);
24
+ const providers = record.providers;
25
+ const entries = record.entries;
26
+ if (providers instanceof Map) {
27
+ return [...providers.entries()].map(([key, entry]) => {
28
+ const providerRecord = readRecord(entry);
29
+ return { ...providerRecord, providerId: readString(providerRecord.providerId) || readString(key) };
30
+ });
31
+ }
32
+ if (Array.isArray(providers)) {
33
+ return providers.map((entry) => readRecord(entry));
34
+ }
35
+ if (providers && typeof providers === 'object') {
36
+ return Object.entries(providers as Record<string, unknown>).map(([key, entry]) => {
37
+ const providerRecord = readRecord(entry);
38
+ return { ...providerRecord, providerId: readString(providerRecord.providerId) || key };
39
+ });
40
+ }
41
+ if (entries instanceof Map) {
42
+ return [...entries.entries()].map(([key, entry]) => {
43
+ const entryRecord = readRecord(entry);
44
+ return { ...entryRecord, providerId: readString(entryRecord.providerId) || readString(key) };
45
+ });
46
+ }
47
+ if (Array.isArray(entries)) {
48
+ return entries.map((entry) => readRecord(entry));
49
+ }
50
+ return [];
51
+ }
52
+
53
+ function providerHealthCandidateId(candidate: Record<string, unknown>): string {
54
+ return readString(candidate.providerId)
55
+ || readString(candidate.id)
56
+ || readString(candidate.provider)
57
+ || readString(candidate.name);
58
+ }
59
+
60
+ function providerHealthRecordStats(candidate: Record<string, unknown>): Record<string, unknown> {
61
+ return readRecord(candidate.stats);
62
+ }
63
+
64
+ function providerHealthTimestamp(candidate: Record<string, unknown>, stats: Record<string, unknown>, key: string): string | null {
65
+ return safeIso(readFiniteNumber(candidate[key]) ?? readFiniteNumber(stats[key]));
66
+ }
67
+
68
+ export function readProviderHealthSignal(context: CommandContext, providerId: string): ModelProviderHealthSignal {
69
+ const base: Omit<ModelProviderHealthSignal, 'status' | 'daemonPublication' | 'agentConsumption' | 'missingSignals' | 'policy'> = {
70
+ providerId,
71
+ sdkContract: {
72
+ providerHealthTypes: 'available',
73
+ importSurface: '@pellux/goodvibes-sdk/platform/runtime/ui',
74
+ note: 'The SDK publishes provider-health domain and UI enrichment types; types alone do not prove live connected-host health.',
75
+ },
76
+ };
77
+ const policy = 'Provider health is live route-condition evidence. Local benchmark artifacts remain separate task-fit evidence and must not be treated as provider-health publication.';
78
+ const platform = context.platform as unknown as Record<string, unknown>;
79
+ const readModels = readRecord(platform.readModels);
80
+ const sourceEntries: readonly { readonly path: string; readonly source: unknown }[] = [
81
+ { path: 'context.platform.readModels.providerHealth', source: readModels.providerHealth },
82
+ { path: 'context.platform.readModels.providersHealth', source: readModels.providersHealth },
83
+ { path: 'context.platform.providerHealth', source: platform.providerHealth },
84
+ ];
85
+
86
+ for (const entry of sourceEntries) {
87
+ if (entry.source === undefined || entry.source === null) continue;
88
+ try {
89
+ const snapshot = readPotentialProviderHealthSnapshot(entry.source);
90
+ const candidates = providerHealthCandidatesFromSnapshot(snapshot);
91
+ const candidate = candidates.find((item) => providerHealthCandidateId(item) === providerId);
92
+ if (!candidate) {
93
+ return {
94
+ ...base,
95
+ status: 'read-model-empty',
96
+ daemonPublication: {
97
+ status: 'published-read-model',
98
+ requiredPath: entry.path,
99
+ evidence: 'A provider-health read model path exists, but no matching provider record was returned.',
100
+ },
101
+ agentConsumption: {
102
+ status: 'waiting-for-published-feed',
103
+ readModelPath: entry.path,
104
+ evidence: `No provider-health record matched provider "${providerId}".`,
105
+ },
106
+ missingSignals: [`No daemon-published provider-health record matched provider "${providerId}" in ${entry.path}.`],
107
+ policy,
108
+ };
109
+ }
110
+
111
+ const stats = providerHealthRecordStats(candidate);
112
+ const avgLatencyMs = readFiniteNumber(candidate.avgLatencyMs) ?? readFiniteNumber(stats.avgLatencyMs);
113
+ const minLatencyMs = readFiniteNumber(candidate.minLatencyMs) ?? readFiniteNumber(stats.minLatencyMs);
114
+ const maxLatencyMs = readFiniteNumber(candidate.maxLatencyMs) ?? readFiniteNumber(candidate.p95LatencyMs) ?? readFiniteNumber(stats.maxLatencyMs);
115
+ const healthStatus = readString(candidate.status) || 'unknown';
116
+ return {
117
+ ...base,
118
+ status: 'record-found',
119
+ daemonPublication: {
120
+ status: 'published-read-model',
121
+ requiredPath: entry.path,
122
+ evidence: `Provider-health record found for provider "${providerId}".`,
123
+ },
124
+ agentConsumption: {
125
+ status: 'consumed',
126
+ readModelPath: entry.path,
127
+ evidence: 'Agent consumed the published provider-health record for exact model-route readiness.',
128
+ },
129
+ healthStatus,
130
+ isConfigured: readBoolean(candidate.isConfigured),
131
+ isActive: readBoolean(candidate.isActive),
132
+ avgLatencyMs,
133
+ minLatencyMs,
134
+ maxLatencyMs,
135
+ lastSuccessAt: providerHealthTimestamp(candidate, stats, 'lastSuccessAt'),
136
+ lastErrorAt: providerHealthTimestamp(candidate, stats, 'lastErrorAt'),
137
+ lastErrorMessage: readString(candidate.lastErrorMessage) || readString(stats.lastErrorMessage) || undefined,
138
+ lastCheckedAt: providerHealthTimestamp(candidate, stats, 'lastCheckedAt'),
139
+ rateLimitResetAt: providerHealthTimestamp(candidate, stats, 'rateLimitResetAt'),
140
+ missingSignals: [
141
+ ...(avgLatencyMs === undefined ? ['Provider-health record did not include average latency.'] : []),
142
+ ...(minLatencyMs === undefined ? ['Provider-health record did not include minimum latency.'] : []),
143
+ ...(maxLatencyMs === undefined ? ['Provider-health record did not include maximum or p95 latency.'] : []),
144
+ ],
145
+ policy,
146
+ };
147
+ } catch (error) {
148
+ return {
149
+ ...base,
150
+ status: 'read-model-error',
151
+ daemonPublication: {
152
+ status: 'published-read-model',
153
+ requiredPath: entry.path,
154
+ evidence: `Provider-health read model exists but failed while reading: ${previewHarnessText(error instanceof Error ? error.message : String(error), 120)}`,
155
+ },
156
+ agentConsumption: {
157
+ status: 'waiting-for-published-feed',
158
+ readModelPath: entry.path,
159
+ evidence: 'Agent could not safely consume this provider-health read model.',
160
+ },
161
+ missingSignals: ['Provider-health read model exists but failed while Agent was reading it.'],
162
+ policy,
163
+ };
164
+ }
165
+ }
166
+
167
+ return {
168
+ ...base,
169
+ status: 'not-reachable-in-command-context',
170
+ daemonPublication: {
171
+ status: 'not-published',
172
+ requiredPath: 'context.platform.readModels.providerHealth',
173
+ evidence: 'No daemon-published provider-health read model is reachable from Agent CommandContext.',
174
+ },
175
+ agentConsumption: {
176
+ status: 'waiting-for-published-feed',
177
+ readModelPath: null,
178
+ evidence: 'Agent cannot attach provider status or latency to exact routes until the connected host publishes a stable feed.',
179
+ },
180
+ missingSignals: [
181
+ 'SDK provider-health types are available, but no daemon-published provider.health feed is reachable in Agent CommandContext.',
182
+ 'Agent has not consumed provider status, configured state, live latency, rate-limit posture, or last error for this route.',
183
+ ],
184
+ policy,
185
+ };
186
+ }