@pellux/goodvibes-agent 0.1.116 → 1.0.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 (285) hide show
  1. package/CHANGELOG.md +48 -661
  2. package/README.md +64 -57
  3. package/bin/goodvibes-agent.ts +16 -2
  4. package/dist/package/main.js +199180 -192185
  5. package/docs/README.md +15 -8
  6. package/docs/channels-remote-and-api.md +50 -0
  7. package/docs/connected-host.md +59 -0
  8. package/docs/getting-started.md +61 -50
  9. package/docs/knowledge-artifacts-and-multimodal.md +91 -0
  10. package/docs/project-planning.md +79 -0
  11. package/docs/providers-and-routing.md +46 -0
  12. package/docs/release-and-publishing.md +48 -11
  13. package/docs/tools-and-commands.md +123 -0
  14. package/docs/voice-and-live-tts.md +51 -0
  15. package/package.json +3 -6
  16. package/src/agent/behavior-discovery-summary.ts +1 -3
  17. package/src/agent/channel-delivery.ts +201 -0
  18. package/src/agent/media-generation.ts +159 -0
  19. package/src/agent/memory-prompt.ts +0 -1
  20. package/src/agent/note-registry.ts +329 -0
  21. package/src/agent/operator-actions.ts +343 -0
  22. package/src/agent/persona-discovery.ts +1 -3
  23. package/src/agent/persona-registry.ts +19 -16
  24. package/src/agent/record-labels.ts +107 -0
  25. package/src/agent/reminder-schedule-format.ts +33 -24
  26. package/src/agent/reminder-schedule.ts +27 -26
  27. package/src/agent/routine-registry.ts +54 -14
  28. package/src/agent/routine-schedule-args.ts +2 -1
  29. package/src/agent/routine-schedule-format.ts +77 -53
  30. package/src/agent/routine-schedule-promotion.ts +35 -33
  31. package/src/agent/routine-schedule-receipts.ts +29 -27
  32. package/src/agent/runtime-profile-starters.ts +5 -5
  33. package/src/agent/runtime-profile.ts +91 -12
  34. package/src/agent/skill-registry.ts +210 -32
  35. package/src/cli/agent-knowledge-args.ts +5 -1
  36. package/src/cli/agent-knowledge-command.ts +40 -34
  37. package/src/cli/agent-knowledge-format.ts +80 -67
  38. package/src/cli/agent-knowledge-methods.ts +1 -1
  39. package/src/cli/agent-knowledge-runtime.ts +32 -26
  40. package/src/cli/bundle-command.ts +14 -9
  41. package/src/cli/config-overrides.ts +37 -36
  42. package/src/cli/entrypoint.ts +16 -7
  43. package/src/cli/external-runtime.ts +10 -4
  44. package/src/cli/help.ts +54 -29
  45. package/src/cli/local-library-command.ts +203 -83
  46. package/src/cli/management-commands.ts +105 -68
  47. package/src/cli/management.ts +55 -74
  48. package/src/cli/memory-command.ts +66 -32
  49. package/src/cli/parser.ts +37 -3
  50. package/src/cli/profiles-command.ts +166 -31
  51. package/src/cli/provider-auth-routes.ts +2 -1
  52. package/src/cli/routines-command.ts +176 -40
  53. package/src/cli/service-posture.ts +16 -16
  54. package/src/cli/status.ts +56 -135
  55. package/src/core/conversation-message-snapshot.ts +131 -0
  56. package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
  57. package/src/input/agent-workspace-access-command-editors.ts +170 -0
  58. package/src/input/agent-workspace-activation.ts +35 -8
  59. package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
  60. package/src/input/agent-workspace-basic-command-editors.ts +502 -9
  61. package/src/input/agent-workspace-categories.ts +423 -51
  62. package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
  63. package/src/input/agent-workspace-channel-command-editors.ts +65 -0
  64. package/src/input/agent-workspace-channels.ts +35 -2
  65. package/src/input/agent-workspace-command-editor.ts +41 -3
  66. package/src/input/agent-workspace-config-reader.ts +16 -0
  67. package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
  68. package/src/input/agent-workspace-editors.ts +166 -1
  69. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
  70. package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
  71. package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
  72. package/src/input/agent-workspace-learned-behavior.ts +67 -0
  73. package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
  74. package/src/input/agent-workspace-library-command-editors.ts +35 -0
  75. package/src/input/agent-workspace-local-operations.ts +218 -0
  76. package/src/input/agent-workspace-local-selection.ts +75 -0
  77. package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
  78. package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
  79. package/src/input/agent-workspace-media-command-editors.ts +27 -0
  80. package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
  81. package/src/input/agent-workspace-memory-command-editors.ts +180 -0
  82. package/src/input/agent-workspace-memory-editor.ts +2 -2
  83. package/src/input/agent-workspace-navigation.ts +81 -0
  84. package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
  85. package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
  86. package/src/input/agent-workspace-operations-command-editors.ts +196 -0
  87. package/src/input/agent-workspace-panel-route.ts +43 -0
  88. package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
  89. package/src/input/agent-workspace-provider-command-editors.ts +93 -0
  90. package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
  91. package/src/input/agent-workspace-requirements.ts +11 -0
  92. package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
  93. package/src/input/agent-workspace-search.ts +169 -0
  94. package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
  95. package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
  96. package/src/input/agent-workspace-session-command-editors.ts +249 -0
  97. package/src/input/agent-workspace-setup.ts +37 -16
  98. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
  99. package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
  100. package/src/input/agent-workspace-snapshot.ts +162 -21
  101. package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
  102. package/src/input/agent-workspace-task-command-editors.ts +47 -0
  103. package/src/input/agent-workspace-token.ts +18 -2
  104. package/src/input/agent-workspace-types.ts +212 -4
  105. package/src/input/agent-workspace-voice-media.ts +4 -7
  106. package/src/input/agent-workspace-web-research-editor.ts +104 -0
  107. package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
  108. package/src/input/agent-workspace.ts +178 -240
  109. package/src/input/command-registry.ts +5 -2
  110. package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
  111. package/src/input/commands/agent-skills-runtime.ts +149 -72
  112. package/src/input/commands/agent-workspace-runtime.ts +23 -6
  113. package/src/input/commands/brief-runtime.ts +55 -25
  114. package/src/input/commands/channels-runtime.ts +147 -33
  115. package/src/input/commands/compat-runtime.ts +32 -0
  116. package/src/input/commands/delegation-runtime.ts +29 -23
  117. package/src/input/commands/experience-runtime.ts +6 -4
  118. package/src/input/commands/guidance-runtime.ts +4 -4
  119. package/src/input/commands/health-runtime.ts +149 -126
  120. package/src/input/commands/knowledge.ts +82 -60
  121. package/src/input/commands/local-provider-runtime.ts +43 -21
  122. package/src/input/commands/local-runtime.ts +138 -16
  123. package/src/input/commands/local-setup-review.ts +10 -20
  124. package/src/input/commands/mcp-runtime.ts +63 -46
  125. package/src/input/commands/notify-runtime.ts +38 -9
  126. package/src/input/commands/operator-actions-runtime.ts +138 -0
  127. package/src/input/commands/operator-runtime.ts +6 -76
  128. package/src/input/commands/personas-runtime.ts +46 -31
  129. package/src/input/commands/planning-runtime.ts +1 -1
  130. package/src/input/commands/platform-access-runtime.ts +35 -98
  131. package/src/input/commands/product-runtime.ts +2 -2
  132. package/src/input/commands/provider-accounts-runtime.ts +60 -39
  133. package/src/input/commands/qrcode-runtime.ts +50 -9
  134. package/src/input/commands/recall-bundle.ts +11 -11
  135. package/src/input/commands/recall-capture.ts +13 -11
  136. package/src/input/commands/recall-query.ts +29 -21
  137. package/src/input/commands/recall-review.ts +2 -1
  138. package/src/input/commands/routines-runtime.ts +99 -45
  139. package/src/input/commands/runtime-services.ts +1 -14
  140. package/src/input/commands/schedule-runtime.ts +33 -20
  141. package/src/input/commands/security-runtime.ts +6 -11
  142. package/src/input/commands/session-content.ts +80 -78
  143. package/src/input/commands/session-workflow.ts +134 -104
  144. package/src/input/commands/session.ts +3 -174
  145. package/src/input/commands/shell-core.ts +38 -17
  146. package/src/input/commands/subscription-runtime.ts +54 -185
  147. package/src/input/commands/support-bundle-runtime.ts +53 -0
  148. package/src/input/commands/tasks-runtime.ts +21 -21
  149. package/src/input/commands/work-plan-runtime.ts +33 -8
  150. package/src/input/commands.ts +6 -2
  151. package/src/input/feed-context-factory.ts +2 -2
  152. package/src/input/file-picker.ts +3 -2
  153. package/src/input/handler-command-route.ts +4 -7
  154. package/src/input/handler-content-actions.ts +89 -26
  155. package/src/input/handler-feed-routes.ts +19 -12
  156. package/src/input/handler-feed.ts +6 -5
  157. package/src/input/handler-interactions.ts +9 -36
  158. package/src/input/handler-modal-stack.ts +3 -3
  159. package/src/input/handler-onboarding.ts +52 -91
  160. package/src/input/handler-shortcuts.ts +16 -7
  161. package/src/input/handler.ts +50 -23
  162. package/src/input/input-history.ts +5 -6
  163. package/src/input/keybindings.ts +27 -16
  164. package/src/input/mcp-workspace.ts +90 -26
  165. package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
  166. package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
  167. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
  168. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  169. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
  170. package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
  171. package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
  172. package/src/input/onboarding/onboarding-wizard.ts +87 -2
  173. package/src/input/profile-picker-modal.ts +31 -12
  174. package/src/input/session-picker-modal.ts +21 -4
  175. package/src/input/settings-modal-agent-policy.ts +6 -6
  176. package/src/input/settings-modal-behavior.ts +0 -3
  177. package/src/input/settings-modal-subscriptions.ts +3 -3
  178. package/src/input/settings-modal-types.ts +2 -13
  179. package/src/input/settings-modal.ts +20 -66
  180. package/src/input/submission-intent.ts +0 -1
  181. package/src/input/submission-router.ts +3 -3
  182. package/src/main.ts +18 -10
  183. package/src/panels/approval-panel.ts +8 -8
  184. package/src/panels/automation-control-panel.ts +4 -4
  185. package/src/panels/base-panel.ts +1 -1
  186. package/src/panels/builtin/agent.ts +1 -1
  187. package/src/panels/builtin/operations.ts +3 -12
  188. package/src/panels/builtin/session.ts +32 -24
  189. package/src/panels/builtin/shared.ts +7 -7
  190. package/src/panels/cost-tracker-panel.ts +1 -1
  191. package/src/panels/docs-panel.ts +5 -3
  192. package/src/panels/index.ts +0 -1
  193. package/src/panels/knowledge-panel.ts +6 -5
  194. package/src/panels/memory-panel.ts +7 -6
  195. package/src/panels/panel-list-panel.ts +36 -80
  196. package/src/panels/project-planning-panel.ts +19 -12
  197. package/src/panels/provider-account-snapshot.ts +51 -25
  198. package/src/panels/provider-accounts-panel.ts +33 -18
  199. package/src/panels/provider-health-domains.ts +48 -7
  200. package/src/panels/provider-health-panel.ts +5 -4
  201. package/src/panels/qr-panel.ts +44 -20
  202. package/src/panels/schedule-panel.ts +9 -17
  203. package/src/panels/security-panel.ts +8 -8
  204. package/src/panels/session-browser-panel.ts +10 -10
  205. package/src/panels/subscription-panel.ts +6 -6
  206. package/src/panels/system-messages-panel.ts +3 -3
  207. package/src/panels/tasks-panel.ts +21 -14
  208. package/src/panels/tool-inspector-panel.ts +19 -12
  209. package/src/panels/work-plan-panel.ts +5 -5
  210. package/src/planning/project-planning-coordinator.ts +3 -3
  211. package/src/provider-auth-route-display.ts +9 -0
  212. package/src/renderer/agent-workspace-style.ts +34 -0
  213. package/src/renderer/agent-workspace.ts +254 -57
  214. package/src/renderer/autocomplete-overlay.ts +25 -6
  215. package/src/renderer/block-actions.ts +1 -3
  216. package/src/renderer/bookmark-modal.ts +19 -4
  217. package/src/renderer/buffer.ts +4 -2
  218. package/src/renderer/context-inspector.ts +50 -13
  219. package/src/renderer/diff.ts +1 -1
  220. package/src/renderer/file-picker-overlay.ts +19 -6
  221. package/src/renderer/help-overlay.ts +112 -34
  222. package/src/renderer/history-search-overlay.ts +19 -4
  223. package/src/renderer/live-tail-modal.ts +27 -5
  224. package/src/renderer/mcp-workspace.ts +176 -43
  225. package/src/renderer/model-picker-overlay.ts +58 -3
  226. package/src/renderer/model-workspace.ts +104 -22
  227. package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
  228. package/src/renderer/process-modal.ts +27 -6
  229. package/src/renderer/profile-picker-modal.ts +21 -5
  230. package/src/renderer/search-overlay.ts +25 -5
  231. package/src/renderer/selection-modal-overlay.ts +46 -14
  232. package/src/renderer/session-picker-modal.ts +18 -1
  233. package/src/renderer/settings-modal-helpers.ts +2 -40
  234. package/src/renderer/settings-modal.ts +88 -55
  235. package/src/renderer/system-message.ts +1 -1
  236. package/src/renderer/tool-call.ts +20 -11
  237. package/src/runtime/agent-runtime-events.ts +129 -0
  238. package/src/runtime/bootstrap-command-context.ts +7 -1
  239. package/src/runtime/bootstrap-command-parts.ts +11 -8
  240. package/src/runtime/bootstrap-core.ts +23 -65
  241. package/src/runtime/bootstrap-hook-bridge.ts +7 -18
  242. package/src/runtime/bootstrap-shell.ts +46 -8
  243. package/src/runtime/bootstrap.ts +36 -46
  244. package/src/runtime/connected-host-auth.ts +47 -0
  245. package/src/runtime/diagnostics/panels/index.ts +2 -2
  246. package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
  247. package/src/runtime/diagnostics/panels/policy.ts +7 -7
  248. package/src/runtime/index.ts +2 -5
  249. package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
  250. package/src/runtime/onboarding/apply.ts +288 -74
  251. package/src/runtime/onboarding/derivation.ts +10 -13
  252. package/src/runtime/onboarding/snapshot.ts +2 -17
  253. package/src/runtime/onboarding/types.ts +34 -20
  254. package/src/runtime/onboarding/verify.ts +105 -4
  255. package/src/runtime/operator-token-cleanup.ts +3 -3
  256. package/src/runtime/services.ts +95 -11
  257. package/src/runtime/store/selectors/index.ts +3 -3
  258. package/src/runtime/store/state.ts +1 -4
  259. package/src/runtime/surface-feature-flags.ts +41 -6
  260. package/src/runtime/ui-read-models.ts +3 -4
  261. package/src/runtime/ui-services.ts +6 -6
  262. package/src/shell/blocking-input.ts +2 -1
  263. package/src/shell/service-settings-sync.ts +7 -7
  264. package/src/shell/ui-openers.ts +17 -38
  265. package/src/tools/agent-analysis-registry-policy.ts +0 -1
  266. package/src/tools/agent-channel-send-tool.ts +133 -0
  267. package/src/tools/agent-context-policy.ts +1 -1
  268. package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
  269. package/src/tools/agent-knowledge-tool.ts +170 -0
  270. package/src/tools/agent-local-registry-tool.ts +279 -73
  271. package/src/tools/agent-media-generate-tool.ts +133 -0
  272. package/src/tools/agent-notify-tool.ts +143 -0
  273. package/src/tools/agent-operator-action-tool.ts +137 -0
  274. package/src/tools/agent-operator-briefing-tool.ts +217 -0
  275. package/src/tools/agent-reminder-schedule-tool.ts +237 -0
  276. package/src/tools/agent-tool-policy-guard.ts +13 -15
  277. package/src/tools/agent-work-plan-tool.ts +256 -0
  278. package/src/version.ts +1 -1
  279. package/docs/connected-services.md +0 -51
  280. package/src/cli/package-verification.ts +0 -274
  281. package/src/input/commands/policy-dispatch.ts +0 -339
  282. package/src/input/commands/policy.ts +0 -17
  283. package/src/panels/panel-picker.ts +0 -105
  284. package/src/panels/policy-panel.ts +0 -308
  285. package/src/renderer/panel-picker-overlay.ts +0 -202
@@ -7,9 +7,10 @@ GoodVibes Agent's current installable public alpha version is recorded in `packa
7
7
  - registry package: `@pellux/goodvibes-agent`
8
8
  - executable: `goodvibes-agent`
9
9
  - SDK dependency: exact pin to `@pellux/goodvibes-sdk@0.33.35`
10
- - runtime: Bun
10
+ - runtime: Bun `1.3.10` or newer
11
11
  - source language: TypeScript
12
- - connected services ownership: outside Agent
12
+ - package docs: every Markdown file under `docs/*.md`
13
+ - connected host ownership: outside Agent
13
14
 
14
15
  End users install and run GoodVibes Agent with Bun:
15
16
 
@@ -18,7 +19,7 @@ bun add -g @pellux/goodvibes-agent
18
19
  goodvibes-agent --help
19
20
  ```
20
21
 
21
- Do not add non-Bun install instructions for this product. The package is hosted on the public package registry, but the supported install and smoke path is the normal Bun global command above, followed by `goodvibes-agent` launching the TUI.
22
+ Do not add non-Bun install instructions for this product. The package is hosted on the public package registry, but the supported install and smoke path is the normal Bun global command above, followed by `goodvibes-agent` launching the TUI. The package-facing text policy rejects non-Bun Agent install/run snippets, references to other `@pellux/goodvibes-*` packages outside Agent and the SDK, and versioned Agent or SDK package references that drift from `package.json`.
22
23
 
23
24
  ## Required Gates
24
25
 
@@ -34,34 +35,70 @@ bun pm pack --dry-run
34
35
  git diff --check
35
36
  ```
36
37
 
37
- `bun run publish:package` publishes from a staged package directory to the package registry. If `NPM_CONFIG_USERCONFIG` is already set, the registry publish command uses it. Otherwise the script creates a temporary 0600 registry userconfig from `NODE_AUTH_TOKEN` or `NPM_TOKEN`, uses it for that publish command, and removes it with the staging directory. The publish script is idempotent for reruns: if the exact package version is already present on the registry, it reports that state and exits successfully instead of failing the release retry.
38
+ Shared release metadata verification requires `publish:check` to keep release metadata and package-facing text checks, package runtime build, npm pack dry-run, forbidden/required tarball path assertions, and the tarball size cap before reporting success.
38
39
 
39
- The GitHub release workflow publishes to npm only when the repository variable `PUBLISH_NPM` is `true` and the repository secret `NPM_TOKEN` is configured. Without those repository settings, the workflow still validates and creates the GitHub release, but npm publish must be run from a local environment with an exported token.
40
+ Shared release metadata verification also requires `build:package-runtime` to keep the clean `dist/package/main.js` build, Bun compile compatibility patch, build-machine path-leak guards, empty-entrypoint guard, and runtime build success summary.
40
41
 
41
- Branch CI is the only workflow that runs the full test suite and release gates. It runs `bun run test` once for the release SHA, along with typecheck, architecture, performance, build, publish, and packed install checks. The release workflow must not run tests or duplicate those gates; it verifies that branch CI passed for the exact checked-out SHA and then performs only package packing, GitHub Release creation, and optional npm publish.
42
+ Shared release metadata verification requires `scripts/bun-compile-compat.ts` to keep the css-tree JSON-import rewrites, jsdom XHR worker and stylesheet path-leak patches, sql.js wasm embedding, idempotent patch skip, unexpected-shape warning, and successful patch diagnostic that keep Bun-compiled Agent runtimes self-contained.
43
+
44
+ Shared release metadata verification requires the `prebuild` and `version` package scripts to run `scripts/prebuild.ts`; that script must keep the workspace-locked project-surface sync and Bun compile compatibility patch, while `scripts/project-surfaces.ts` must preserve exact semver reads plus `src/version.ts` and README badge synchronization.
45
+
46
+ `bun run publish:package` publishes from a staged package directory to the package registry. It re-runs the shared package policy checks against the source tree, filters forbidden package paths during staging, and verifies the staged package docs, required package paths, and metadata before invoking npm. If `NPM_CONFIG_USERCONFIG` is already set, the registry publish command uses it. Otherwise the script creates a temporary 0600 registry userconfig from `NODE_AUTH_TOKEN` or `NPM_TOKEN`, uses it for that publish command, and removes it with the staging directory. The publish script is idempotent for reruns: if the exact package version is already present on the registry, it reports that state and exits successfully instead of failing the release retry. Shared release metadata verification requires those staged source/staged policy checks, forbidden-path filtering, docs checks, auth handoff, idempotent lookup, dry-run pack, public publish, and cleanup markers to remain in the publish script.
47
+
48
+ `bun run release` requires product release notes instead of raw git-log output. Pass `--notes-file ./release-notes.md` or set `GOODVIBES_AGENT_RELEASE_NOTES` before a real release. The 1.0 release candidate uses `--notes-file release/1.0-release-notes.md`, and release metadata verification requires that artifact to exist, contain product-facing notes, and be staged with the release readiness and live-verification evidence. Release notes should describe what changed for Agent users: TUI behavior, setup, Agent Knowledge, local behavior libraries, connected-host compatibility, package/install behavior, and safety policy. Do not use commit hashes as the shipped changelog content.
49
+
50
+ Before it mutates version metadata or creates a tag, `bun run release` checks the declared `release/1.0-*` evidence files for existence, non-empty content, final newlines, trailing whitespace, and space-before-tab indentation, then enforces the non-test release gates: typecheck, architecture check, performance check, build, publish check, packed install smoke, verification ledger, pack dry-run, and `git diff --check`. Dry-run previews run the same evidence text hygiene check without writing files, commits, or tags. After it writes the release version, `src/version.ts` fallback, and changelog section, it verifies release metadata and package-facing text policy again, then reruns evidence hygiene and diff hygiene before creating the commit and tag. That package policy check proves `package.json`, `CHANGELOG.md`, and the `src/version.ts` fallback literals agree on the Agent and SDK versions, that the package manifest keeps the required Agent runtime/docs files, exclusions, release/publish script entrypoints, and local CI gate entrypoints without explicitly including forbidden Agent/TUI boundary paths or leaving existing forbidden paths reachable through broad includes, that the local release script still requires product notes, real-release validation, post-mutation package policy, docs staging, and annotated tags, that the GitHub setup action uses the same Bun version as `packageManager`, and that package-facing text is present and still follows Agent docs, rendered CLI help, parser-backed CLI command snippets, parser/type/alias/help/handler/top-level help command coverage, exported package-text source coverage, autocomplete overlay text, context inspector text, in-app help overlays, file/bookmark picker text, live process output text, MCP workspace text, model picker/workspace text, profile/session picker text, process/runtime activity text, search overlays, shared selection/picker chrome, setup/onboarding wizard text, settings workspace text, slash-command registry text, Agent workspace catalog text, route boundaries, install policy, and version pins. The generated changelog heading uses the operator's local release date in `YYYY-MM-DD` form, not UTC rollover time. The prebuild version sync refuses missing, ranged, or otherwise non-exact Agent or SDK versions instead of writing placeholder fallbacks. The release commit stages those metadata files plus every package-facing `docs/*.md` page, so release docs cannot drift outside the tag. The full test suite remains a branch-CI responsibility and must already be green for the release SHA.
51
+
52
+ `--skip-validation` is only allowed with `--dry-run`. Real releases must run the validation gates above.
53
+
54
+ `--dry-run` is non-mutating and may be used from a dirty or non-main worktree to preview the next version and generated changelog section. For the 1.0 cut, preview with `bun run scripts/release.ts --dry-run --major --notes-file release/1.0-release-notes.md`. Real releases still require a clean worktree on `main`.
55
+
56
+ The GitHub release workflow publishes to npm only when the repository variable `PUBLISH_NPM` is `true` and the repository secret `NPM_TOKEN` is configured. Without those repository settings, the workflow still validates and creates the GitHub release, but npm publish must be run from a local environment with an exported token. After optional npm publish, the workflow installs the exact registry version into an isolated Bun home, seeds a connected-host token sentinel, captures stdout and stderr for `--version`, `--help`, and `status --json`, and fails without printing that sentinel. Shared release metadata verification requires those publish, exact-version registry lookup, install smoke, and token-sentinel markers to remain in the release workflow.
57
+
58
+ Branch CI is the only workflow that runs the full test suite and release gates. It runs `bun run test` once for the release SHA, along with typecheck, architecture, performance, build, publish, packed install, and verification ledger checks. The release workflow must not run tests or duplicate those gates; shared release metadata verification rejects duplicated release-workflow gates and requires the workflow to verify that branch CI and its test job passed for the exact checked-out SHA before package packing, GitHub Release creation, and optional npm publish. It also requires the release workflow to preserve tag/package version matching, single-tarball packing, changelog excerpt extraction, and GitHub Release tarball attachment markers.
59
+
60
+ Shared release metadata verification requires the package build scripts to keep exact TypeScript and Bun compile commands for the Agent entrypoint and platform binary names. It also requires `scripts/build.ts` to keep the prebuild/compatibility patch, multi-target matrix, sqlite-vec native addon externalization/copy policy, same-platform hard failure, cross-target warning, and build summary/failure exit behavior.
61
+
62
+ Shared release metadata verification requires branch CI to run the compiled binary smoke after `bun run build`, and `scripts/post-build-smoke.ts` must keep the default `dist/goodvibes-agent` binary path, optional `--binary` override, isolated temp cwd, `--version` launch, sqlite-vec/`$bunfs` module-resolution leak guards, Agent version-prefix assertion, failure diagnostics, and cleanup.
63
+
64
+ Shared release metadata verification requires `architecture:check` to keep the Agent/TUI product-boundary rules: no runtime imports from `goodvibes-tui/src`, no coding-TUI git/worktree header posture in the Agent shell, isolated Agent Knowledge client/routes, typed operator contracts, explicit dependency ownership, source-size limits, and no explicit `any` or process-global test mocks.
65
+
66
+ Shared release metadata verification requires `perf:check` to load `release/1.0-performance-snapshot.json`, validate its render samples and extra SLO/queue/tool/compaction/integration metrics, run the CI performance-budget evaluation, print the formatted report, and exit from the budget result. The 1.0 performance snapshot is staged with release metadata so the tag carries the exact non-live fixture used by the branch-CI performance gate.
67
+
68
+ Shared release metadata verification requires `verification:ledger` to keep JSON and Markdown evidence output plus inventory coverage for settings schema, feature flags, slash commands, built-in panels, top-level CLI commands, external surfaces, and onboarding capability bundles, including local-signal, local-behavior, and external-outcome accounting.
69
+
70
+ Shared release metadata verification requires `verification:live` to keep the external-outcome audit for release candidates: compiled CLI checks, connected-host token/URL discovery, connected-host status/health/model routes, isolated Agent Knowledge status/ask/search routes, SDK-version mismatch skip policy, JSON/Markdown report artifacts, strict mode, and Agent Knowledge contamination guards.
42
71
 
43
72
  Do not add targeted `bun test` passes or separate release-only test gates to CI, release, or aggregate scripts. Tests that matter for release must be included in the single full branch-CI suite.
44
73
 
74
+ Shared release metadata verification requires the `test` script to keep using `scripts/run-tests.ts`, and that runner must discover all `.test`/`.spec` TypeScript files under `src`, sort them deterministically, run one `bun test` invocation with an isolated `.test-tmp/suite` temp root, fail when no tests are found, and propagate the Bun test exit code.
75
+
45
76
  Also run the package install smoke from a packed artifact. It must prove:
46
77
 
47
78
  - the installed command is on `PATH`
48
79
  - the bin target is `bin/goodvibes-agent.ts`
49
80
  - the Bun shebang survives pack/install
50
81
  - the bundled runtime `dist/package/main.js` is present and non-empty
82
+ - every shared required package path is installed as a non-empty file
83
+ - every package-facing `docs/*.md` page is installed and non-empty
51
84
  - Bun global install uses `bun add -g`
52
85
  - `goodvibes-agent --help` works
53
86
  - `goodvibes-agent --version` reports the package version
54
87
  - the installed TUI launches in a PTY and does not exit immediately
55
- - connected-service commands fail clearly when GoodVibes services are unavailable or unauthenticated
56
- - no token value is printed
88
+ - connected-host commands fail clearly when GoodVibes host is unavailable or unauthenticated
89
+ - a seeded connected-host token sentinel is never printed in captured command output, PTY transcript, or failure diagnostics
90
+
91
+ Shared release metadata verification requires the install-check script to keep those packed artifact, Bun global install, installed CLI/status, blocked lifecycle command, PTY launch, required-path, runtime, token-sentinel, and cleanup markers.
57
92
 
58
93
  ## Do Not Ship
59
94
 
60
- Do not publish if package-facing docs or install commands refer to another package name, another executable, or Agent-owned connected-service lifecycle.
95
+ Do not publish if package-facing docs or install commands refer to another package name, another executable, or Agent-owned connected-host lifecycle.
96
+
97
+ Do not publish if `README.md` or `docs/README.md` omits a package-facing docs page, or links a docs page that is not included by the package `files` manifest.
61
98
 
62
- Do not publish if Agent Knowledge commands can fall back to default Knowledge/Wiki or another product-specific knowledge route. Agent Knowledge must use the isolated `/api/goodvibes-agent/knowledge/*` segment.
99
+ Do not publish if Agent Knowledge commands can fall back to default knowledge or another product-specific knowledge route. Agent Knowledge must use the isolated `/api/goodvibes-agent/knowledge/*` segment.
63
100
 
64
- Do not ship GoodVibes service binaries from this package. If Agent later gets compiled artifacts, they must use Agent artifact names and remain separate from connected-service ownership.
101
+ Do not ship connected-host binaries from this package. If Agent later gets compiled artifacts, they must use Agent artifact names and remain separate from connected-host ownership.
65
102
 
66
103
  ## Product Rule
67
104
 
@@ -0,0 +1,123 @@
1
+ # Tools and Commands
2
+
3
+ GoodVibes Agent is an operator assistant TUI. Its command set is centered on main-conversation assistant work, isolated Agent Knowledge, local memory/notes/routines/skills/personas, approvals, automation visibility, and explicit delegation to GoodVibes TUI for build work.
4
+
5
+ ## Product Boundaries
6
+
7
+ - Normal chat stays in the main Agent conversation.
8
+ - Agent Knowledge uses only `/api/goodvibes-agent/knowledge/*`.
9
+ - Agent never falls back to default knowledge or arbitrary non-Agent knowledge spaces.
10
+ - Local memory, notes, routines, skills, and personas remain Agent-local until a stable shared registry contract exists.
11
+ - Runtime hosting is external. Agent connects to it and reports health; it does not start, stop, restart, or install it.
12
+ - Delegated review is not a default reasoning path. It is requested only when the user explicitly asks for build, implementation, fix, or review work.
13
+ - Code-building work is delegated to GoodVibes TUI through public shared-session/task contracts.
14
+
15
+ ## TUI-First Operator Surface
16
+
17
+ The Agent workspace is the product surface. Slash commands are power-user routes inside the TUI, and package CLI subcommands are scriptable mirrors. New user-facing features should appear in the workspace first.
18
+
19
+ High-signal Agent TUI paths:
20
+
21
+ - `/help` for registry-driven command discovery.
22
+ - `/health` and `/auth` for runtime/auth/SDK diagnostics inside the TUI.
23
+ - `/model` and `/provider` for provider/model selection and visibility.
24
+ - `/agent` for the fullscreen operator workspace: setup, provider/model, Agent Knowledge, memory, notes, personas, skills, routines, channels, MCP/tools, secrets, voice/media, work state, automation, and build delegation.
25
+ - Agent Workspace -> Research for read-only web research, URL inspection, source triage, and explicit source-to-Agent-Knowledge handoff.
26
+ - Agent Workspace -> Notes for local source-triage notes, temporary decisions, and operator handoff. Notes do not write memory or Agent Knowledge by themselves; reviewed notes can prefill memory, skills, routines, personas, or an isolated Agent Knowledge URL ingest.
27
+ - `/knowledge` for isolated Agent Knowledge ask, search, status, source/node/issue inspection, connector inspection, and confirmed ingest/reindex actions.
28
+ - `/memory`, `/routines`, `/skills`, and `/personas` for Agent-local context and reusable operator behavior.
29
+ - `/plan` for Agent-owned workspace planning state in the main conversation.
30
+ - `/workplan` for durable task status over public work-plan routes.
31
+ - `/approvals` for pending approval visibility and explicit approval actions.
32
+ - `/schedule` for schedule visibility plus narrow explicit-user-action flows.
33
+ - `/channels` for channel readiness and one-message confirmed channel delivery.
34
+ - `/media` for media provider readiness and confirmed image/video artifact generation.
35
+ - `/delegate` for explicit build/fix/review handoff to GoodVibes TUI.
36
+ - `/mcp`, `/config`, `/settings`, and setup workspaces for Agent-local configuration.
37
+
38
+ The installed `goodvibes-agent` command launches the TUI by default. Subcommands such as `status`, `compat`, `knowledge ...`, `ask <question>`, and `search <query>` are secondary scriptable equivalents for diagnostics and automation over the same Agent workspace features.
39
+
40
+ Host-management and coding-first commands that would imply connected-host lifecycle ownership, separate Agent job creation, execution-isolation ownership, worktree control, or implicit delegated review must remain blocked, read-only, or delegation-only unless they are intentionally adapted to Agent policy.
41
+
42
+ The main composer supports inline context references. Type `@path/to/file`, `@path/to/folder`, or `@https://example.test/page` in a normal prompt to add bounded context for that turn. `!@path/to/file` remains the raw file-injection form. These references do not ingest anything into Agent Knowledge unless the user explicitly runs a Knowledge ingest action.
43
+
44
+ The Research workspace submits web research and URL inspection forms to the normal main conversation. These requests are read-only by default, may use connected web tools when the user asks, and do not ingest sources. Use confirmed Agent Knowledge ingest actions only after a source should become durable Agent-owned knowledge.
45
+
46
+ Local memory capture/add commands are explicit Agent-local actions. Deletes, imports/exports, record linking, review-state changes, and promotion across memory scopes require `--yes`.
47
+
48
+ ## Agent Knowledge
49
+
50
+ `/knowledge ask <query>` asks the isolated Agent Knowledge environment for a source-backed answer through `/api/goodvibes-agent/knowledge/ask`.
51
+
52
+ `/knowledge search <query>` searches the same isolated Agent environment through `/api/goodvibes-agent/knowledge/search`.
53
+
54
+ `/knowledge ingest-url <url> --yes` ingests into Agent Knowledge through `/api/goodvibes-agent/knowledge/ingest/url`. Knowledge ingestion, imports, issue review, reindex, and consolidation are Agent-owned mutations and require `--yes`.
55
+
56
+ The Knowledge workspace exposes status, source library, connector review, ask, search, and confirmed ingest forms. Scriptable equivalents such as `goodvibes-agent knowledge list --kind sources|nodes|issues`, `goodvibes-agent knowledge get <id>`, `goodvibes-agent knowledge connectors`, and `goodvibes-agent knowledge map` are read-only CLI inspection paths over the same isolated Agent route family.
57
+
58
+ Workspace ingest forms are the primary user workflow. Scriptable equivalents such as `goodvibes-agent knowledge import-urls <path> --yes`, `goodvibes-agent knowledge import-bookmarks <path> --yes`, and `goodvibes-agent knowledge reindex --yes` are confirmed Agent Knowledge maintenance paths. They call only `/api/goodvibes-agent/knowledge/*`.
59
+
60
+ The Agent command layer rejects flags that would route knowledge work into another space, including `--space`, `--knowledge-space`, `--knowledge-space-id`, and `--include-all-spaces`. If Agent Knowledge is unavailable, the command fails closed instead of querying a default store.
61
+
62
+ ## Media Artifacts
63
+
64
+ Agent Workspace -> Voice & Media is the primary media path. Use `Generate media` for a confirmed form that calls configured media providers and stores outputs as GoodVibes artifacts.
65
+
66
+ `/media providers` lists media provider readiness. `/media generate [--provider <id>] [--model <id>] [--mime <mime>] <prompt> --yes` is the power-user mirror for confirmed image/video generation. Media generation output returns artifact ids and metadata; it does not print inline base64 and does not write to default knowledge or non-Agent knowledge segments.
67
+
68
+ ## Planning
69
+
70
+ `/plan` inspects or seeds Agent workspace planning state. The planning loop belongs to the main Agent conversation: the Agent asks focused questions, records decisions and gaps, and keeps execution separate until the user gives an explicit action.
71
+
72
+ The SDK planning service may expose a namespace such as `project:<projectId>` because that is the stable contract shape. In Agent UI and docs this is treated as a planning namespace, not as permission to query default knowledge or another product knowledge segment.
73
+
74
+ Use `/workplan` when the work already has concrete tasks and needs durable status tracking rather than another planning interview.
75
+
76
+ ## Delegation
77
+
78
+ `/delegate` is for explicit build, fix, review, or implementation work. It sends a single delegated request to GoodVibes TUI/shared-session routes with the original user ask and execution intent. Agent does not create coding-role Agent jobs and does not run delegated review by default.
79
+
80
+ Use `/delegate --review` only when the user explicitly asks for review or when the delegated build/fix/review request explicitly calls for review.
81
+
82
+ ## Approvals And Automation
83
+
84
+ Approvals and automation are safe by default:
85
+
86
+ - list/status views are read-only;
87
+ - mutating routes require exact commands and explicit confirmation such as `--yes`;
88
+ - no chat turn silently runs approval, schedule, or automation mutations;
89
+ - unavailable routes return structured errors rather than fallback behavior.
90
+
91
+ Workspace forms are the primary path for approval and automation actions:
92
+
93
+ - Agent Workspace -> Work & Approvals -> Approve request / Deny request / Cancel request
94
+ - Agent Workspace -> Automation -> Run job now / Pause job / Resume job
95
+ - Agent Workspace -> Automation -> Cancel run / Retry run / Run schedule now
96
+
97
+ Power-user slash mirrors are exact and confirmation-gated:
98
+
99
+ - `/approval approve <approval-id> [--note <text>] [--remember|--no-remember] --yes`
100
+ - `/approval deny <approval-id> [--note <text>] [--remember|--no-remember] --yes`
101
+ - `/approval cancel <approval-id> [--note <text>] [--remember|--no-remember] --yes`
102
+ - `/automation job run <job-id> --yes`
103
+ - `/automation job pause <job-id> --yes`
104
+ - `/automation job resume <job-id> --yes`
105
+ - `/automation run cancel <run-id> --yes`
106
+ - `/automation run retry <run-id> --yes`
107
+ - `/automation schedule run <schedule-id> --yes`
108
+ - `/schedule run <schedule-id> --yes`
109
+
110
+ Routine promotion is an explicit scheduling bridge: local routines stay local during normal use, and promotion creates a schedule only after a user runs the exact command with `--yes`. The generated scheduled prompt keeps Agent Knowledge isolated and forbids default knowledge or non-Agent knowledge fallback. Delivery is opt-in with explicit flags such as `--delivery-channel`, `--delivery-route`, `--delivery-webhook`, or `--delivery-link`; no delivery target is inferred from chat.
111
+
112
+ ## Channels
113
+
114
+ Agent Workspace -> Channels is the primary channel path. It shows readiness, setup, account, policy, and status views without rendering secret values. `Send channel message` opens a confirmed form for one delivery target.
115
+
116
+ `/channels send --channel <surface[:route[:label]]> --message <text> --yes` sends one explicit message through configured delivery strategies. `--route`, `--webhook`, and `--link` are alternate one-target forms. Channel sends do not create routes, authorize accounts, manage connected-host hosting, use default knowledge, use non-Agent knowledge segments, create separate Agent jobs, or run delegated review.
117
+
118
+ ## Related Docs
119
+
120
+ - [Getting started](getting-started.md)
121
+ - [Connected host](connected-host.md)
122
+ - [Knowledge, artifacts, and multimodal](knowledge-artifacts-and-multimodal.md)
123
+ - [Release and publishing](release-and-publishing.md)
@@ -0,0 +1,51 @@
1
+ # Voice and Live TTS
2
+
3
+ GoodVibes Agent supports spoken turns as an Agent TUI feature. Text output remains primary; voice is an additional local playback path for a normal assistant turn.
4
+
5
+ ## Commands
6
+
7
+ ```text
8
+ /tts <prompt>
9
+ /tts stop
10
+ /config tts
11
+ /config tts.provider
12
+ /config tts.voice
13
+ /config tts.llmProvider
14
+ /config tts.llmModel
15
+ ```
16
+
17
+ `/tts <prompt>` submits the prompt through the normal Agent conversation path. It uses the active chat provider/model unless a separate spoken-turn model override is configured.
18
+
19
+ `/tts stop` cancels queued spoken output and active playback without cancelling the text transcript.
20
+
21
+ `/config tts` opens the fullscreen configuration workspace for streaming provider, voice, and spoken-turn model routing.
22
+
23
+ ## Playback Requirements
24
+
25
+ Live playback streams audio to a local player. Install one of:
26
+
27
+ - `mpv`;
28
+ - `ffplay`.
29
+
30
+ If neither player is on `PATH`, the Agent still submits and renders the normal text response. Audio is skipped with a concise status message.
31
+
32
+ ## Provider Routing
33
+
34
+ Voice uses providers that advertise streaming TTS capability through the runtime. Agent does not hardcode provider behavior.
35
+
36
+ Useful setup path:
37
+
38
+ ```text
39
+ /config tts.provider
40
+ /config tts.voice
41
+ /config tts.llmProvider
42
+ /config tts.llmModel
43
+ ```
44
+
45
+ Leaving `tts.voice` empty lets the provider choose its default voice.
46
+
47
+ ## Knowledge Boundary
48
+
49
+ Spoken responses are conversation output. They are not automatically written to Agent Knowledge, local memory, default knowledge, or any other product segment.
50
+
51
+ If a spoken result should become durable, store it through an explicit Agent memory command or an Agent Knowledge ingestion path.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.116",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -17,14 +17,12 @@
17
17
  "!src/test",
18
18
  "!src/**/*.test.ts",
19
19
  "!src/**/__tests__",
20
+ "!src/cli/package-verification.ts",
20
21
  "!src/verification",
21
22
  "tsconfig.json",
22
23
  "README.md",
23
24
  "CHANGELOG.md",
24
- "docs/README.md",
25
- "docs/getting-started.md",
26
- "docs/connected-services.md",
27
- "docs/release-and-publishing.md"
25
+ "docs/*.md"
28
26
  ],
29
27
  "scripts": {
30
28
  "dev": "bun run src/main.ts",
@@ -54,7 +52,6 @@
54
52
  "build:all": "bun run scripts/build.ts --all",
55
53
  "perf:check": "bun run scripts/perf-check.ts",
56
54
  "architecture:check": "bun run scripts/check-architecture.ts",
57
- "foundation:artifacts": "bun run scripts/export-foundation-artifacts.ts",
58
55
  "verification:ledger": "bun run scripts/verification-ledger.ts",
59
56
  "verification:live": "bun run scripts/verify-live.ts"
60
57
  },
@@ -126,12 +126,10 @@ function definitions(shellPaths: Pick<ShellPathService, 'workingDirectory' | 'ho
126
126
  roots: [
127
127
  { root: join(cwd, '.goodvibes', 'personas'), origin: 'project-local' },
128
128
  { root: join(cwd, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'project-local' },
129
- { root: join(cwd, '.goodvibes', 'agents'), origin: 'project-local' },
130
129
  { root: join(homeDir, '.goodvibes', 'personas'), origin: 'global' },
131
130
  { root: join(homeDir, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'global' },
132
- { root: join(homeDir, '.goodvibes', 'agents'), origin: 'global' },
133
131
  ],
134
- markers: ['PERSONA.md', 'persona.md', 'AGENT.md', 'agent.md'],
132
+ markers: ['PERSONA.md', 'persona.md'],
135
133
  frontmatterBodyKey: 'system_prompt',
136
134
  };
137
135
  const skills: DiscoveryKindDefinition = {
@@ -0,0 +1,201 @@
1
+ import type {
2
+ ChannelDeliveryRequest,
3
+ ChannelDeliveryRouter,
4
+ ChannelDeliverySurfaceKind,
5
+ ChannelDeliveryTarget,
6
+ } from '@pellux/goodvibes-sdk/platform/channels';
7
+
8
+ type AgentChannelDeliveryRouter = Pick<ChannelDeliveryRouter, 'deliver' | 'listStrategies'>;
9
+ type AgentChannelDeliverySurfaceKind = ChannelDeliverySurfaceKind | 'telephony';
10
+ type AgentChannelDeliveryTarget = Omit<ChannelDeliveryTarget, 'surfaceKind'> & {
11
+ readonly surfaceKind?: AgentChannelDeliverySurfaceKind;
12
+ };
13
+ type AgentChannelDeliveryRequest = Omit<ChannelDeliveryRequest, 'target'> & {
14
+ readonly target: AgentChannelDeliveryTarget;
15
+ };
16
+
17
+ export interface AgentChannelDeliveryInput {
18
+ readonly message: string;
19
+ readonly title?: string;
20
+ readonly channel?: string;
21
+ readonly route?: string;
22
+ readonly webhook?: string;
23
+ readonly link?: string;
24
+ }
25
+
26
+ export interface AgentChannelDeliveryPreview {
27
+ readonly message: string;
28
+ readonly title: string;
29
+ readonly target: AgentChannelDeliveryTarget;
30
+ readonly request: AgentChannelDeliveryRequest;
31
+ }
32
+
33
+ export interface AgentChannelDeliveryResult {
34
+ readonly responseId?: string;
35
+ readonly message: string;
36
+ readonly title: string;
37
+ readonly target: AgentChannelDeliveryTarget;
38
+ readonly strategyCount: number;
39
+ }
40
+
41
+ const DELIVERY_SURFACE_KINDS: readonly AgentChannelDeliverySurfaceKind[] = [
42
+ 'tui',
43
+ 'web',
44
+ 'slack',
45
+ 'discord',
46
+ 'ntfy',
47
+ 'webhook',
48
+ 'telegram',
49
+ 'google-chat',
50
+ 'signal',
51
+ 'whatsapp',
52
+ 'telephony',
53
+ 'imessage',
54
+ 'msteams',
55
+ 'bluebubbles',
56
+ 'mattermost',
57
+ 'matrix',
58
+ 'service',
59
+ ];
60
+
61
+ function readText(value: string | undefined): string | undefined {
62
+ const trimmed = value?.trim();
63
+ return trimmed ? trimmed : undefined;
64
+ }
65
+
66
+ function isDeliverySurfaceKind(value: string): value is AgentChannelDeliverySurfaceKind {
67
+ return DELIVERY_SURFACE_KINDS.includes(value as AgentChannelDeliverySurfaceKind);
68
+ }
69
+
70
+ function parseChannelTarget(raw: string): AgentChannelDeliveryTarget {
71
+ const [surfaceKind = '', routeId, label] = raw.split(':');
72
+ if (!isDeliverySurfaceKind(surfaceKind)) {
73
+ throw new Error(`Unsupported delivery channel "${surfaceKind}".`);
74
+ }
75
+ return {
76
+ kind: 'surface',
77
+ surfaceKind,
78
+ ...(readText(routeId) ? { routeId: readText(routeId) } : {}),
79
+ ...(readText(label) ? { label: readText(label) } : {}),
80
+ };
81
+ }
82
+
83
+ function parseRouteTarget(raw: string): AgentChannelDeliveryTarget {
84
+ const [routeId = '', label] = raw.split(':');
85
+ const normalizedRouteId = readText(routeId);
86
+ if (!normalizedRouteId) throw new Error('Route delivery target requires a route id.');
87
+ return {
88
+ kind: 'surface',
89
+ routeId: normalizedRouteId,
90
+ ...(readText(label) ? { label: readText(label) } : {}),
91
+ };
92
+ }
93
+
94
+ function parseWebhookTarget(raw: string): AgentChannelDeliveryTarget {
95
+ const normalized = readText(raw);
96
+ if (!normalized) throw new Error('Webhook delivery target requires a URL.');
97
+ try {
98
+ const url = new URL(normalized);
99
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') throw new Error('bad protocol');
100
+ } catch {
101
+ throw new Error('Webhook delivery target must be a valid http(s) URL.');
102
+ }
103
+ return { kind: 'webhook', address: normalized };
104
+ }
105
+
106
+ function parseLinkTarget(raw: string): AgentChannelDeliveryTarget {
107
+ const normalized = readText(raw);
108
+ if (!normalized) throw new Error('Link delivery target requires a URL or label.');
109
+ return { kind: 'link', address: normalized };
110
+ }
111
+
112
+ function selectedTargetInputs(input: AgentChannelDeliveryInput): readonly string[] {
113
+ return [input.channel, input.route, input.webhook, input.link].map(readText).filter((value): value is string => Boolean(value));
114
+ }
115
+
116
+ export function buildAgentChannelDeliveryPreview(input: AgentChannelDeliveryInput): AgentChannelDeliveryPreview {
117
+ const message = readText(input.message);
118
+ if (!message) throw new Error('Channel delivery message is required.');
119
+ const targets = selectedTargetInputs(input);
120
+ if (targets.length === 0) throw new Error('Choose one delivery target: channel, route, webhook, or link.');
121
+ if (targets.length > 1) throw new Error('Choose exactly one delivery target.');
122
+
123
+ const channel = readText(input.channel);
124
+ const route = readText(input.route);
125
+ const webhook = readText(input.webhook);
126
+ const link = readText(input.link);
127
+ const target = channel
128
+ ? parseChannelTarget(channel)
129
+ : route
130
+ ? parseRouteTarget(route)
131
+ : webhook
132
+ ? parseWebhookTarget(webhook)
133
+ : parseLinkTarget(link ?? '');
134
+ const title = readText(input.title) ?? 'GoodVibes Agent message';
135
+ return {
136
+ message,
137
+ title,
138
+ target,
139
+ request: {
140
+ target,
141
+ body: message,
142
+ title,
143
+ jobId: 'agent-channel-send',
144
+ runId: `agent-channel-send-${Date.now()}`,
145
+ status: 'completed',
146
+ includeLinks: true,
147
+ metadata: {
148
+ product: 'goodvibes-agent',
149
+ source: 'agent-channel-send',
150
+ },
151
+ },
152
+ };
153
+ }
154
+
155
+ export async function deliverAgentChannelMessage(
156
+ router: AgentChannelDeliveryRouter,
157
+ input: AgentChannelDeliveryInput,
158
+ ): Promise<AgentChannelDeliveryResult> {
159
+ const preview = buildAgentChannelDeliveryPreview(input);
160
+ const responseId = await router.deliver(preview.request as ChannelDeliveryRequest);
161
+ return {
162
+ responseId,
163
+ message: preview.message,
164
+ title: preview.title,
165
+ target: preview.target,
166
+ strategyCount: router.listStrategies().length,
167
+ };
168
+ }
169
+
170
+ function formatTarget(target: AgentChannelDeliveryTarget): string {
171
+ if (target.kind === 'surface') {
172
+ const base = target.surfaceKind ?? 'route';
173
+ const details = [
174
+ target.routeId ? `route ${target.routeId}` : '',
175
+ target.label ? `label ${target.label}` : '',
176
+ ].filter(Boolean);
177
+ return `${base}${details.length > 0 ? ` (${details.join(', ')})` : ''}`;
178
+ }
179
+ return target.address ? `${target.kind} ${target.address}` : target.kind;
180
+ }
181
+
182
+ export function formatAgentChannelDeliveryPreview(preview: AgentChannelDeliveryPreview, strategyCount: number): string {
183
+ return [
184
+ 'Agent channel delivery preview',
185
+ ` title ${preview.title}`,
186
+ ` target ${formatTarget(preview.target)}`,
187
+ ` strategies ${strategyCount}`,
188
+ ` message ${preview.message}`,
189
+ ' policy external delivery requires an explicit user request and confirmation',
190
+ ].join('\n');
191
+ }
192
+
193
+ export function formatAgentChannelDeliveryResult(result: AgentChannelDeliveryResult): string {
194
+ return [
195
+ 'Agent channel delivery sent',
196
+ ` title ${result.title}`,
197
+ ` target ${formatTarget(result.target)}`,
198
+ ` strategies ${result.strategyCount}`,
199
+ ...(result.responseId ? [` response ${result.responseId}`] : []),
200
+ ].join('\n');
201
+ }