@pellux/goodvibes-tui 2.0.14 → 2.0.16

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 (464) hide show
  1. package/.goodvibes/GOODVIBES.md +1 -1
  2. package/.goodvibes/agents/reviewer.md +8 -8
  3. package/.goodvibes/skills/add-provider/SKILL.md +22 -22
  4. package/CHANGELOG.md +49 -0
  5. package/README.md +64 -44
  6. package/docs/README.md +6 -6
  7. package/docs/foundation-artifacts/README.md +5 -5
  8. package/docs/foundation-artifacts/operator-contract.json +123 -123
  9. package/package.json +12 -10
  10. package/scripts/postinstall.js +3 -3
  11. package/src/audio/activation-sound.ts +7 -7
  12. package/src/audio/capture.ts +7 -7
  13. package/src/audio/onnxruntime-assets.d.ts +1 -1
  14. package/src/audio/player.ts +4 -4
  15. package/src/audio/spoken-turn-wiring.ts +4 -4
  16. package/src/audio/voice-capture-wiring.ts +5 -5
  17. package/src/audio/voice-input-session.ts +3 -3
  18. package/src/audio/wake-inference.ts +13 -8
  19. package/src/audio/wake-runtime.ts +10 -10
  20. package/src/cli/completions/generate.ts +2 -2
  21. package/src/cli/doctor.ts +13 -13
  22. package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
  23. package/src/cli/entrypoint.ts +3 -3
  24. package/src/cli/help.ts +6 -6
  25. package/src/cli/hooks-command.ts +4 -4
  26. package/src/cli/hooks-report.ts +4 -4
  27. package/src/cli/launch-auto-update.ts +17 -17
  28. package/src/cli/management-commands.ts +8 -8
  29. package/src/cli/management-utils.ts +3 -3
  30. package/src/cli/management.ts +1 -1
  31. package/src/cli/plugin-bundles-command.ts +10 -10
  32. package/src/cli/plugin-command.ts +9 -9
  33. package/src/cli/service-posture.ts +1 -1
  34. package/src/cli/status.ts +10 -10
  35. package/src/cli/surface-command.ts +4 -4
  36. package/src/cli/tui-startup.ts +23 -23
  37. package/src/config/run-daemon-config-migration.ts +3 -3
  38. package/src/config/secret-config.ts +10 -10
  39. package/src/config/surface.ts +1 -1
  40. package/src/config/tui-extension-settings.ts +8 -8
  41. package/src/core/active-model-identity.ts +7 -7
  42. package/src/core/approval-alert.ts +5 -5
  43. package/src/core/bookmark-navigation.ts +3 -3
  44. package/src/core/budget-breach-notifier.ts +6 -6
  45. package/src/core/compaction-receipt.ts +8 -8
  46. package/src/core/composer-state.ts +2 -2
  47. package/src/core/context-usage.ts +1 -1
  48. package/src/core/conversation-compaction-render.ts +3 -3
  49. package/src/core/conversation-event-navigation.ts +2 -2
  50. package/src/core/conversation-fold.ts +9 -9
  51. package/src/core/conversation-line-cache.ts +14 -14
  52. package/src/core/conversation-render-context.ts +6 -6
  53. package/src/core/conversation-rendering.ts +27 -30
  54. package/src/core/conversation-search-expansion.ts +6 -6
  55. package/src/core/conversation-splash-state.ts +3 -3
  56. package/src/core/conversation-turn-structure.ts +13 -13
  57. package/src/core/conversation-types.ts +3 -3
  58. package/src/core/conversation-user-receipts.ts +5 -5
  59. package/src/core/conversation.ts +17 -17
  60. package/src/core/format-user-error.ts +5 -5
  61. package/src/core/long-task-notifier.ts +9 -9
  62. package/src/core/memory-diagnostics-gateway.ts +8 -8
  63. package/src/core/memory-provenance.ts +5 -5
  64. package/src/core/model-routing-chip.ts +3 -3
  65. package/src/core/pairing-tailscale-gateway.ts +3 -3
  66. package/src/core/permission-mode.ts +5 -5
  67. package/src/core/power-chip-source.ts +3 -3
  68. package/src/core/power-status.ts +8 -8
  69. package/src/core/rewind-receipt.ts +6 -6
  70. package/src/core/session-resume-core.ts +8 -8
  71. package/src/core/stream-event-wiring.ts +36 -36
  72. package/src/core/stream-stall-watchdog.ts +4 -4
  73. package/src/core/system-message-noise.ts +7 -7
  74. package/src/core/system-message-router.ts +10 -10
  75. package/src/core/terminal-notifier.ts +5 -5
  76. package/src/core/turn-budget-outcome.ts +5 -5
  77. package/src/core/turn-cancellation.ts +3 -3
  78. package/src/core/turn-event-wiring.ts +16 -16
  79. package/src/core/voice-capture-status.ts +2 -2
  80. package/src/core/voice-provision-gateway.ts +12 -12
  81. package/src/core/voice-provision-status.ts +19 -19
  82. package/src/core/voice-stt-gateway.ts +6 -6
  83. package/src/core/wake-provision-runner.ts +7 -7
  84. package/src/core/wake-provision-status.ts +17 -17
  85. package/src/core/workstream-notification.ts +8 -8
  86. package/src/export/gist-uploader.ts +7 -7
  87. package/src/input/autocomplete.ts +3 -3
  88. package/src/input/bookmark-modal.ts +1 -1
  89. package/src/input/command-args-hint.ts +2 -2
  90. package/src/input/command-reference.ts +9 -9
  91. package/src/input/command-registry.ts +32 -32
  92. package/src/input/commands/acp-runtime.ts +6 -6
  93. package/src/input/commands/calendar-runtime.ts +9 -9
  94. package/src/input/commands/channel-pairing.ts +11 -11
  95. package/src/input/commands/channel-runtime.ts +1 -1
  96. package/src/input/commands/checkin-runtime.ts +4 -4
  97. package/src/input/commands/checkpoint-runtime.ts +4 -4
  98. package/src/input/commands/ci-runtime.ts +4 -4
  99. package/src/input/commands/cluster-runtime.ts +3 -3
  100. package/src/input/commands/codebase-runtime.ts +16 -16
  101. package/src/input/commands/config.ts +6 -6
  102. package/src/input/commands/connection-status.ts +12 -12
  103. package/src/input/commands/context-window.ts +2 -2
  104. package/src/input/commands/cost-attribution-format.ts +4 -4
  105. package/src/input/commands/cost-runtime.ts +2 -2
  106. package/src/input/commands/devices-runtime.ts +7 -7
  107. package/src/input/commands/diff-runtime.ts +2 -2
  108. package/src/input/commands/editor-runtime.ts +1 -1
  109. package/src/input/commands/eval.ts +4 -4
  110. package/src/input/commands/experience-runtime.ts +1 -1
  111. package/src/input/commands/git-runtime.ts +3 -3
  112. package/src/input/commands/graph-runtime.ts +3 -3
  113. package/src/input/commands/guidance-runtime.ts +1 -1
  114. package/src/input/commands/health-metrics-format.ts +2 -2
  115. package/src/input/commands/health-runtime.ts +8 -8
  116. package/src/input/commands/hosted-runtime.ts +13 -13
  117. package/src/input/commands/image-runtime.ts +6 -6
  118. package/src/input/commands/intelligence-runtime.ts +2 -2
  119. package/src/input/commands/local-auth-runtime.ts +3 -3
  120. package/src/input/commands/local-provider-runtime.ts +3 -3
  121. package/src/input/commands/local-runtime.ts +7 -7
  122. package/src/input/commands/mail-runtime.ts +9 -9
  123. package/src/input/commands/mcp-runtime.ts +1 -1
  124. package/src/input/commands/memory.ts +13 -13
  125. package/src/input/commands/notify-runtime.ts +1 -1
  126. package/src/input/commands/operator-panel-runtime.ts +8 -8
  127. package/src/input/commands/operator-rpc.ts +3 -3
  128. package/src/input/commands/operator-runtime.ts +3 -3
  129. package/src/input/commands/palette-runtime.ts +1 -1
  130. package/src/input/commands/payment-card-intake.ts +17 -17
  131. package/src/input/commands/permissions-provenance.ts +7 -7
  132. package/src/input/commands/permissions-runtime.ts +1 -1
  133. package/src/input/commands/planning-runtime.ts +19 -19
  134. package/src/input/commands/platform-services-runtime.ts +2 -2
  135. package/src/input/commands/policy-dispatch.ts +6 -6
  136. package/src/input/commands/power-runtime.ts +6 -6
  137. package/src/input/commands/principals-runtime.ts +3 -3
  138. package/src/input/commands/product-runtime.ts +3 -3
  139. package/src/input/commands/profile-render.ts +13 -13
  140. package/src/input/commands/profile-runtime.ts +13 -13
  141. package/src/input/commands/profile-types.ts +13 -13
  142. package/src/input/commands/provider-accounts-runtime.ts +5 -5
  143. package/src/input/commands/provider.ts +10 -10
  144. package/src/input/commands/qrcode-runtime.ts +3 -3
  145. package/src/input/commands/queue-runtime.ts +6 -6
  146. package/src/input/commands/recall-files-config.ts +4 -4
  147. package/src/input/commands/recall-files-git.ts +3 -3
  148. package/src/input/commands/recall-files.ts +12 -12
  149. package/src/input/commands/recall-query.ts +3 -3
  150. package/src/input/commands/recall-review.ts +3 -3
  151. package/src/input/commands/recall-shared.ts +1 -1
  152. package/src/input/commands/relay-runtime.ts +5 -5
  153. package/src/input/commands/remote-runtime.ts +3 -3
  154. package/src/input/commands/review-runtime.ts +8 -8
  155. package/src/input/commands/rewind-runtime.ts +21 -21
  156. package/src/input/commands/runtime-services.ts +1 -2
  157. package/src/input/commands/schedule-nl.ts +2 -2
  158. package/src/input/commands/schedule-runtime.ts +2 -2
  159. package/src/input/commands/secret-runtime.ts +3 -3
  160. package/src/input/commands/session-content.ts +7 -7
  161. package/src/input/commands/session-picker-filter.ts +3 -3
  162. package/src/input/commands/session-workflow.ts +10 -10
  163. package/src/input/commands/session.ts +15 -15
  164. package/src/input/commands/settings-sync-runtime.ts +2 -2
  165. package/src/input/commands/share-runtime.ts +4 -4
  166. package/src/input/commands/shell-core.ts +11 -11
  167. package/src/input/commands/tasks-runtime.ts +4 -4
  168. package/src/input/commands/test-runtime.ts +6 -6
  169. package/src/input/commands/tts-runtime.ts +4 -4
  170. package/src/input/commands/update-runtime.ts +27 -27
  171. package/src/input/commands/websearch-runtime.ts +2 -2
  172. package/src/input/commands/work-plan-runtime.ts +2 -2
  173. package/src/input/commands/workstream-attempt-dependents.ts +4 -4
  174. package/src/input/commands/workstream-attempts.ts +16 -16
  175. package/src/input/commands/workstream-runtime.ts +36 -36
  176. package/src/input/commands/worktree-runtime.ts +6 -6
  177. package/src/input/composer-capture.ts +5 -5
  178. package/src/input/concealed-input.ts +2 -2
  179. package/src/input/config-modal-types.ts +16 -16
  180. package/src/input/config-modal.ts +30 -30
  181. package/src/input/daemon-owned-settings-descriptions.ts +4 -4
  182. package/src/input/delete-key-policy.ts +1 -1
  183. package/src/input/exec-env-scrub-config.ts +7 -7
  184. package/src/input/feature-unit-layout.ts +5 -5
  185. package/src/input/feed-context-factory.ts +38 -38
  186. package/src/input/file-picker.ts +1 -1
  187. package/src/input/handler-command-route.ts +2 -2
  188. package/src/input/handler-content-actions.ts +8 -8
  189. package/src/input/handler-feed-routes.ts +13 -13
  190. package/src/input/handler-feed.ts +31 -31
  191. package/src/input/handler-interactions.ts +2 -2
  192. package/src/input/handler-modal-routes.ts +13 -13
  193. package/src/input/handler-modal-stack.ts +1 -1
  194. package/src/input/handler-modal-token-routes.ts +1 -1
  195. package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
  196. package/src/input/handler-picker-routes.ts +7 -7
  197. package/src/input/handler-prompt-buffer.ts +1 -1
  198. package/src/input/handler-shortcuts.ts +12 -12
  199. package/src/input/handler-types.ts +3 -3
  200. package/src/input/handler-ui-state.ts +1 -1
  201. package/src/input/handler.ts +9 -9
  202. package/src/input/input-history.ts +1 -1
  203. package/src/input/keybindings.ts +13 -13
  204. package/src/input/kill-ring.ts +7 -11
  205. package/src/input/model-picker-filter.ts +3 -3
  206. package/src/input/model-picker-items.ts +5 -5
  207. package/src/input/model-picker-types.ts +2 -2
  208. package/src/input/model-picker.ts +18 -18
  209. package/src/input/onboarding/onboarding-feature-units.ts +9 -13
  210. package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
  211. package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
  212. package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
  213. package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
  214. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
  215. package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
  216. package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
  217. package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
  218. package/src/input/panel-integration-actions.ts +3 -3
  219. package/src/input/panel-mouse-geometry.ts +1 -1
  220. package/src/input/panel-paste-flood-guard.ts +9 -9
  221. package/src/input/payments-config.ts +15 -15
  222. package/src/input/profile-picker-modal.ts +1 -1
  223. package/src/input/provider-key-intake.ts +9 -9
  224. package/src/input/relay-settings-descriptions.ts +3 -3
  225. package/src/input/sandbox-exec-config.ts +9 -9
  226. package/src/input/search.ts +18 -18
  227. package/src/input/selection-modal-queue.ts +10 -10
  228. package/src/input/selection-modal.ts +2 -2
  229. package/src/input/session-picker-modal.ts +7 -7
  230. package/src/input/settings-modal-activation.ts +1 -1
  231. package/src/input/settings-modal-adjustment.ts +2 -2
  232. package/src/input/settings-modal-commit.ts +6 -6
  233. package/src/input/settings-modal-connections.ts +2 -2
  234. package/src/input/settings-modal-data.ts +29 -29
  235. package/src/input/settings-modal-mutations.ts +7 -7
  236. package/src/input/settings-modal-reset.ts +3 -3
  237. package/src/input/settings-modal-search.ts +6 -6
  238. package/src/input/settings-modal-secrets.ts +3 -3
  239. package/src/input/settings-modal-types.ts +16 -16
  240. package/src/input/settings-modal.ts +4 -4
  241. package/src/input/voice-local-settings.ts +3 -3
  242. package/src/input/worktree-setup-config.ts +8 -8
  243. package/src/main.ts +15 -15
  244. package/src/panels/agent-inspector-shared.ts +5 -5
  245. package/src/panels/base-panel.ts +3 -3
  246. package/src/panels/builtin/agent.ts +3 -3
  247. package/src/panels/builtin/development.ts +4 -4
  248. package/src/panels/builtin/knowledge.ts +1 -1
  249. package/src/panels/builtin/operations.ts +12 -12
  250. package/src/panels/builtin/session.ts +8 -8
  251. package/src/panels/builtin/shared.ts +6 -6
  252. package/src/panels/builtin-modals.ts +8 -8
  253. package/src/panels/confirm-state.ts +5 -5
  254. package/src/panels/cost-tracker-panel.ts +22 -22
  255. package/src/panels/diff-panel.ts +20 -20
  256. package/src/panels/diff-review-model.ts +5 -5
  257. package/src/panels/diff-review-panel.ts +5 -5
  258. package/src/panels/eval-registry.ts +2 -2
  259. package/src/panels/expandable-list-panel.ts +5 -5
  260. package/src/panels/fleet-acts.ts +20 -20
  261. package/src/panels/fleet-deep-link.ts +5 -5
  262. package/src/panels/fleet-gateway.ts +12 -12
  263. package/src/panels/fleet-observed-render.ts +11 -11
  264. package/src/panels/fleet-panel-format.ts +14 -14
  265. package/src/panels/fleet-panel-worktree-detail.ts +8 -8
  266. package/src/panels/fleet-panel.ts +34 -34
  267. package/src/panels/fleet-read-model.ts +49 -49
  268. package/src/panels/fleet-spawn.ts +15 -15
  269. package/src/panels/fleet-steer.ts +7 -7
  270. package/src/panels/fleet-stop.ts +5 -5
  271. package/src/panels/fleet-tabs.ts +14 -14
  272. package/src/panels/fleet-transcript.ts +26 -26
  273. package/src/panels/git-panel.ts +8 -8
  274. package/src/panels/hosted-session-feed.ts +13 -13
  275. package/src/panels/hosted-session-panel.ts +7 -7
  276. package/src/panels/index.ts +1 -1
  277. package/src/panels/local-auth-panel.ts +15 -15
  278. package/src/panels/memory-consolidation-gateway.ts +8 -8
  279. package/src/panels/modals/devices-modal.ts +8 -8
  280. package/src/panels/modals/hooks-modal.ts +1 -1
  281. package/src/panels/modals/keybindings-modal.ts +5 -5
  282. package/src/panels/modals/knowledge-modal.ts +2 -2
  283. package/src/panels/modals/local-auth-modal.ts +4 -4
  284. package/src/panels/modals/marketplace-modal.ts +3 -3
  285. package/src/panels/modals/memory-modal.ts +19 -19
  286. package/src/panels/modals/modal-surface-helpers.ts +1 -1
  287. package/src/panels/modals/modal-theme.ts +3 -3
  288. package/src/panels/modals/pairing-modal.ts +19 -19
  289. package/src/panels/modals/planning-modal.ts +11 -11
  290. package/src/panels/modals/plugins-modal.ts +1 -1
  291. package/src/panels/modals/policy-modal.ts +4 -4
  292. package/src/panels/modals/provider-health-modal.ts +1 -1
  293. package/src/panels/modals/remote-modal.ts +1 -1
  294. package/src/panels/modals/sandbox-modal.ts +2 -2
  295. package/src/panels/modals/security-modal.ts +4 -4
  296. package/src/panels/modals/services-modal.ts +1 -1
  297. package/src/panels/modals/work-plan-modal.ts +4 -4
  298. package/src/panels/notifications-feed.ts +6 -6
  299. package/src/panels/notifications-panel.ts +6 -6
  300. package/src/panels/panel-confirm-overlay.ts +4 -4
  301. package/src/panels/panel-manager.ts +13 -13
  302. package/src/panels/plugins-panel.ts +6 -6
  303. package/src/panels/polish-core.ts +2 -2
  304. package/src/panels/polish-tables.ts +2 -2
  305. package/src/panels/polish.ts +1 -1
  306. package/src/panels/project-planning-answer-actions.ts +3 -3
  307. package/src/panels/scrollable-list-panel.ts +15 -15
  308. package/src/panels/search-focus.ts +1 -1
  309. package/src/panels/session-maintenance.ts +1 -1
  310. package/src/panels/skills-panel.ts +3 -3
  311. package/src/panels/token-budget-panel.ts +11 -11
  312. package/src/panels/types.ts +14 -14
  313. package/src/panels/workstream-graph-render.ts +5 -5
  314. package/src/panels/wrfc-panel-format.ts +1 -1
  315. package/src/permissions/broker-approval-card.ts +13 -13
  316. package/src/permissions/hunk-selection.ts +13 -13
  317. package/src/permissions/prompt.ts +22 -22
  318. package/src/permissions/sandbox-exec-gate.ts +5 -5
  319. package/src/providers/provider-classification.ts +1 -1
  320. package/src/providers/reasoning-effort-surface.ts +12 -12
  321. package/src/renderer/ansi-sanitize.ts +5 -6
  322. package/src/renderer/autocomplete-overlay.ts +5 -5
  323. package/src/renderer/block-actions-overlay.ts +1 -1
  324. package/src/renderer/bookmark-modal.ts +1 -1
  325. package/src/renderer/code-block.ts +2 -2
  326. package/src/renderer/compaction-history-modal.ts +4 -4
  327. package/src/renderer/compaction-preview.ts +5 -5
  328. package/src/renderer/compaction-quality.ts +5 -5
  329. package/src/renderer/composer-fragments.ts +6 -6
  330. package/src/renderer/compositor.ts +9 -9
  331. package/src/renderer/config-modal.ts +3 -3
  332. package/src/renderer/context-inspector.ts +1 -1
  333. package/src/renderer/context-status-hint.ts +10 -10
  334. package/src/renderer/conversation-layout.ts +2 -2
  335. package/src/renderer/conversation-overlays.ts +2 -2
  336. package/src/renderer/conversation-surface.ts +6 -6
  337. package/src/renderer/diff.ts +4 -4
  338. package/src/renderer/fleet-tab-strip.ts +2 -2
  339. package/src/renderer/footer-tips.ts +4 -4
  340. package/src/renderer/fullscreen-primitives.ts +1 -1
  341. package/src/renderer/git-status.ts +5 -5
  342. package/src/renderer/header-line.ts +5 -5
  343. package/src/renderer/help-overlay.ts +5 -5
  344. package/src/renderer/hint-grammar.ts +2 -2
  345. package/src/renderer/layout.ts +1 -1
  346. package/src/renderer/markdown-inline.ts +3 -3
  347. package/src/renderer/markdown-table.ts +7 -7
  348. package/src/renderer/modal-factory.ts +3 -3
  349. package/src/renderer/model-picker-overlay.ts +2 -2
  350. package/src/renderer/model-workspace.ts +7 -7
  351. package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
  352. package/src/renderer/overlay-box.ts +1 -1
  353. package/src/renderer/panel-composite.ts +5 -5
  354. package/src/renderer/panel-workspace-bar.ts +1 -1
  355. package/src/renderer/process-indicator.ts +8 -8
  356. package/src/renderer/profile-picker-modal.ts +3 -3
  357. package/src/renderer/prompt-content-width.ts +1 -1
  358. package/src/renderer/search-overlay.ts +3 -3
  359. package/src/renderer/selection-modal-overlay.ts +6 -6
  360. package/src/renderer/semantic-diff.ts +6 -7
  361. package/src/renderer/session-picker-modal.ts +24 -24
  362. package/src/renderer/settings-modal-connections.ts +3 -3
  363. package/src/renderer/settings-modal-helpers.ts +16 -16
  364. package/src/renderer/settings-modal.ts +10 -10
  365. package/src/renderer/shell-surface.ts +8 -8
  366. package/src/renderer/status-glyphs.ts +6 -6
  367. package/src/renderer/syntax-highlighter.ts +2 -3
  368. package/src/renderer/system-message.ts +3 -3
  369. package/src/renderer/tab-strip.ts +2 -2
  370. package/src/renderer/term-caps.ts +12 -12
  371. package/src/renderer/terminal-bg-probe.ts +10 -10
  372. package/src/renderer/terminal-escapes.ts +1 -1
  373. package/src/renderer/theme-mode-config.ts +3 -3
  374. package/src/renderer/theme.ts +34 -34
  375. package/src/renderer/thinking.ts +1 -1
  376. package/src/renderer/tool-call.ts +5 -5
  377. package/src/renderer/tool-result-expanded-lines.ts +3 -3
  378. package/src/renderer/tool-result-summary.ts +6 -6
  379. package/src/renderer/turn-injection.ts +9 -9
  380. package/src/renderer/ui-factory.ts +33 -33
  381. package/src/renderer/ui-primitives.ts +4 -4
  382. package/src/runtime/bootstrap-command-parts.ts +3 -3
  383. package/src/runtime/bootstrap-core.ts +21 -21
  384. package/src/runtime/bootstrap-hook-bridge.ts +8 -8
  385. package/src/runtime/bootstrap-shell.ts +9 -9
  386. package/src/runtime/bootstrap.ts +16 -16
  387. package/src/runtime/client/approval-updates.ts +3 -3
  388. package/src/runtime/client/build-floors.ts +7 -7
  389. package/src/runtime/client/daemon-attach-handshake.ts +5 -5
  390. package/src/runtime/client/fleet-union.ts +7 -7
  391. package/src/runtime/client/host-service-status.ts +2 -2
  392. package/src/runtime/client/hosted-exit.ts +4 -4
  393. package/src/runtime/client/hosted-roster.ts +4 -4
  394. package/src/runtime/client/hosted-session-stream.ts +5 -5
  395. package/src/runtime/client/hosted-sessions.ts +8 -8
  396. package/src/runtime/client/operator-endpoint.ts +14 -14
  397. package/src/runtime/client/spine-adoption.ts +8 -8
  398. package/src/runtime/context-accounting-source.ts +4 -4
  399. package/src/runtime/context.ts +2 -2
  400. package/src/runtime/conversation-rewind-port.ts +6 -6
  401. package/src/runtime/credential-composition.ts +2 -2
  402. package/src/runtime/daemon-attach-notices.ts +6 -6
  403. package/src/runtime/diagnostics/panels/index.ts +1 -1
  404. package/src/runtime/diagnostics/panels/ops.ts +2 -2
  405. package/src/runtime/disposal-wiring.ts +6 -6
  406. package/src/runtime/index.ts +11 -11
  407. package/src/runtime/install-self-check-startup.ts +4 -4
  408. package/src/runtime/install-self-check.ts +6 -6
  409. package/src/runtime/interaction-seams.ts +4 -4
  410. package/src/runtime/knowledge-services.ts +2 -2
  411. package/src/runtime/legacy-daemon-migration.ts +37 -37
  412. package/src/runtime/legacy-daemon-reconcile.ts +30 -30
  413. package/src/runtime/memory-governance-services.ts +3 -3
  414. package/src/runtime/memory-spine-transport.ts +3 -3
  415. package/src/runtime/notification-dispatch.ts +4 -4
  416. package/src/runtime/onboarding/apply.ts +1 -1
  417. package/src/runtime/onboarding/derivation.ts +1 -1
  418. package/src/runtime/onboarding/fast-path.ts +7 -7
  419. package/src/runtime/onboarding/progress.ts +2 -2
  420. package/src/runtime/onboarding/provider-key-capture.ts +4 -4
  421. package/src/runtime/onboarding/snapshot.ts +2 -2
  422. package/src/runtime/onboarding/state.ts +4 -4
  423. package/src/runtime/onboarding/types.ts +4 -4
  424. package/src/runtime/orchestrator-core-services.ts +5 -5
  425. package/src/runtime/path-shadow-startup.ts +3 -3
  426. package/src/runtime/perf/panel-contracts.ts +1 -1
  427. package/src/runtime/power-keepawake-remote.ts +6 -6
  428. package/src/runtime/process-lifecycle.ts +14 -14
  429. package/src/runtime/provider-fallback.ts +3 -3
  430. package/src/runtime/recovery-autosave.ts +3 -3
  431. package/src/runtime/recovery-decisions.ts +19 -19
  432. package/src/runtime/recovery-offer-wiring.ts +4 -4
  433. package/src/runtime/recovery-prompt.ts +20 -20
  434. package/src/runtime/relay-reachability-bridge.ts +3 -3
  435. package/src/runtime/release-artifacts.ts +1 -1
  436. package/src/runtime/resume-notice.ts +20 -20
  437. package/src/runtime/runtime-services-types.ts +20 -20
  438. package/src/runtime/services.ts +20 -20
  439. package/src/runtime/session-continuity-hints.ts +1 -1
  440. package/src/runtime/session-inbound-inputs.ts +12 -12
  441. package/src/runtime/session-resume-liveness-confirm.ts +4 -4
  442. package/src/runtime/session-spine-transport.ts +3 -3
  443. package/src/runtime/store/domains/panels.ts +2 -2
  444. package/src/runtime/store/domains/ui-perf.ts +2 -2
  445. package/src/runtime/store/index.ts +1 -1
  446. package/src/runtime/store/selectors/index.ts +1 -1
  447. package/src/runtime/store/state.ts +2 -2
  448. package/src/runtime/ui-services.ts +3 -3
  449. package/src/runtime/workspace-checkpointing.ts +3 -3
  450. package/src/runtime/wrfc-persistence.ts +15 -15
  451. package/src/scripts/process-messages.ts +1 -1
  452. package/src/shell/blocking-input.ts +9 -9
  453. package/src/shell/recovery-input-helpers.ts +2 -2
  454. package/src/shell/retry-affordance.ts +9 -9
  455. package/src/shell/ui-openers.ts +14 -14
  456. package/src/shell/voice-capture-shell.ts +3 -3
  457. package/src/tools/wrfc-agent-guard.ts +4 -4
  458. package/src/utils/browser.ts +2 -2
  459. package/src/utils/format-duration.ts +3 -3
  460. package/src/utils/format-number.ts +2 -2
  461. package/src/utils/splash-lines.ts +4 -4
  462. package/src/utils/terminal-width.ts +6 -6
  463. package/src/verification/verification-ledger.ts +25 -25
  464. package/src/version.ts +3 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-tui",
3
- "version": "2.0.14",
4
- "description": "Terminal-native GoodVibes client for coding, operations, knowledge and channel workflows — a pure client of the GoodVibes daemon.",
3
+ "version": "2.0.16",
4
+ "description": "Terminal-native GoodVibes client for coding, operations, knowledge and channel workflows; a pure client of the GoodVibes daemon.",
5
5
  "type": "module",
6
6
  "main": "src/main.ts",
7
7
  "bin": {
@@ -27,12 +27,12 @@
27
27
  "dev:watch": "bun --watch src/main.ts",
28
28
  "prebuild": "bun run scripts/prebuild.ts",
29
29
  "build": "bun build src/main.ts --compile --outfile dist/goodvibes",
30
- "build:linux-x64": "bun build src/main.ts --compile --target=bun-linux-x64 --outfile dist/goodvibes-linux-x64",
31
- "build:linux-arm64": "bun build src/main.ts --compile --target=bun-linux-arm64 --outfile dist/goodvibes-linux-arm64",
32
- "build:macos-x64": "bun build src/main.ts --compile --target=bun-darwin-x64 --outfile dist/goodvibes-macos-x64",
33
- "build:macos-arm64": "bun build src/main.ts --compile --target=bun-darwin-arm64 --outfile dist/goodvibes-macos-arm64",
30
+ "build:linux-x64": "goodvibes-build-binaries --target linux-x64",
31
+ "build:linux-arm64": "goodvibes-build-binaries --target linux-arm64",
32
+ "build:macos-x64": "goodvibes-build-binaries --target darwin-x64",
33
+ "build:macos-arm64": "goodvibes-build-binaries --target darwin-arm64",
34
34
  "smoke:tui": "goodvibes-post-build-smoke",
35
- "build:windows": "bun build src/main.ts --compile --target=bun-windows-x64 --outfile dist/goodvibes-windows.exe",
35
+ "build:windows": "goodvibes-build-binaries --target windows-x64",
36
36
  "build:all-shell": "bun run build:linux-x64 && bun run build:linux-arm64 && bun run build:macos-x64 && bun run build:macos-arm64 && bun run build:windows",
37
37
  "typecheck": "bunx tsc --noEmit",
38
38
  "typecheck:test": "bunx tsc --noEmit -p tsconfig.test.json",
@@ -52,6 +52,7 @@
52
52
  "platform:publish:dry-run": "bun run scripts/publish-platform-packages.ts --dry-run",
53
53
  "publish:dry-run:github": "GOODVIBES_PUBLIC_PACKAGE_NAME=@mgd34msu/goodvibes-tui GOODVIBES_PUBLISH_REGISTRY=https://npm.pkg.github.com bun run scripts/publish-package.ts --dry-run",
54
54
  "publish:check": "bun run scripts/publish-check.ts",
55
+ "verify:tag-version": "bun run scripts/verify-release-tag-version.ts",
55
56
  "package:install-check": "bun run scripts/package-install-check.ts",
56
57
  "build:prod": "goodvibes-build-binaries",
57
58
  "build:all": "goodvibes-build-binaries --all",
@@ -95,11 +96,11 @@
95
96
  "@anthropic-ai/bedrock-sdk": "^0.29.1",
96
97
  "@anthropic-ai/sdk": "^0.92.0",
97
98
  "@ast-grep/napi": "^0.42.0",
98
- "@pellux/goodvibes-sdk": "2.0.17",
99
- "@pellux/goodvibes-terminal-shell": "2.0.17",
99
+ "@pellux/goodvibes-sdk": "2.0.20",
100
+ "@pellux/goodvibes-terminal-shell": "2.0.20",
100
101
  "bash-language-server": "^5.6.0",
101
102
  "fuse.js": "^7.1.0",
102
- "@pellux/goodvibes-daemon": "1.28.19",
103
+ "@pellux/goodvibes-daemon": "1.28.21",
103
104
  "graphql": "^16.13.2",
104
105
  "jszip": "^3.10.1",
105
106
  "node-edge-tts": "^1.2.10",
@@ -120,6 +121,7 @@
120
121
  "zustand": "^5.0.12"
121
122
  },
122
123
  "devDependencies": {
124
+ "@pellux/goodvibes-toolchain": "2.0.20",
123
125
  "@types/bun": "^1.3.10",
124
126
  "typescript": "^5.9.3"
125
127
  },
@@ -66,7 +66,7 @@ async function downloadText(url) {
66
66
  *
67
67
  * The daemon binary is NOT here any more. The daemon is its own product with
68
68
  * its own npm package (`goodvibes-daemon`), which this package declares as a
69
- * dependency — so an npm install still brings the whole suite, and the daemon's
69
+ * dependency, so an npm install still brings the whole suite, and the daemon's
70
70
  * own postinstall places the daemon's own binary. Two packages each placing
71
71
  * a copy of `goodvibes-daemon` is exactly how a machine ends up with two.
72
72
  */
@@ -234,7 +234,7 @@ function deployBundledFiles() {
234
234
  * Put the wake-word model on the machine as part of installing.
235
235
  *
236
236
  * Everything needed to detect "hey goodvibes" already shipped, and provisioning
237
- * was reachable only by typing `/voice wake setup` — so the ordinary outcome of
237
+ * was reachable only by typing `/voice wake setup`, so the ordinary outcome of
238
238
  * installing was a wake word that could not start. The pins (URLs, byte counts,
239
239
  * checksums) live in the SDK's wake-word manifest and stay there; this calls the
240
240
  * SDK's install policy, which:
@@ -252,7 +252,7 @@ function deployBundledFiles() {
252
252
  * It honours the same skip switches as the binary install (`--no-download`,
253
253
  * GOODVIBES_SKIP_BINARY_DOWNLOAD) plus its own
254
254
  * GOODVIBES_SKIP_WAKE_MODEL_DOWNLOAD, and it stays out of a source checkout for
255
- * the same reason the binary install does — a repo clone is a development tree,
255
+ * the same reason the binary install does, a repo clone is a development tree,
256
256
  * not an installation.
257
257
  */
258
258
  async function installWakeWordModel() {
@@ -1,17 +1,17 @@
1
1
  /**
2
- * activation-sound.ts — the sound a confirmed wake makes.
2
+ * activation-sound.ts, the sound a confirmed wake makes.
3
3
  *
4
4
  * A wake takes the microphone from "scoring frames nobody hears" to "recording
5
- * what you say next", and the user needs to know the moment that happened —
5
+ * what you say next", and the user needs to know the moment that happened,
6
6
  * otherwise the only feedback is a transcript arriving seconds later, and a
7
7
  * false accept is indistinguishable from nothing having happened at all. So the
8
8
  * sound is played AT the wake, before transcription, per
9
9
  * `voice.wake.activationSound`:
10
10
  *
11
- * - `chime` — a short two-tone WAV synthesised here. No asset file to ship,
11
+ * - `chime` , a short two-tone WAV synthesised here. No asset file to ship,
12
12
  * install, provision or lose, and nothing to fetch at runtime.
13
- * - `custom` — the file named by `voice.wake.activationSoundPath`.
14
- * - `none` — silent.
13
+ * - `custom`, the file named by `voice.wake.activationSoundPath`.
14
+ * - `none` , silent.
15
15
  *
16
16
  * Playback reuses the streaming player the spoken-turn path already owns
17
17
  * (player.ts), so a host with mpv or ffplay needs nothing extra and a host with
@@ -32,7 +32,7 @@ const CHIME_SAMPLE_RATE = 16000;
32
32
  const CHIME_TONES_HZ = [880, 1320] as const;
33
33
  /** Milliseconds per tone. Short enough not to overlap the start of an utterance. */
34
34
  const CHIME_TONE_MS = 70;
35
- /** Peak amplitude on the int16 magnitude scale — audible without being startling. */
35
+ /** Peak amplitude on the int16 magnitude scale, audible without being startling. */
36
36
  const CHIME_PEAK = 6000;
37
37
  /**
38
38
  * Fade applied to each end of each tone, in samples. Without it the abrupt start
@@ -83,7 +83,7 @@ export interface ActivationSoundPlayerDeps {
83
83
  * sound that fails to play must not delay or cancel that.
84
84
  *
85
85
  * `settings.activationSound` arrives already resolved against surface capability
86
- * — the SDK downgrades `custom` to `chime` on a surface that cannot read a local
86
+ *, the SDK downgrades `custom` to `chime` on a surface that cannot read a local
87
87
  * file, and this surface can, so `custom` here means a real path.
88
88
  */
89
89
  export function playActivationSound(sound: WakeActivationSound, deps: ActivationSoundPlayerDeps): void {
@@ -1,18 +1,18 @@
1
1
  /**
2
- * capture.ts — the ONE place this terminal opens a microphone.
2
+ * capture.ts, the ONE place this terminal opens a microphone.
3
3
  *
4
4
  * Two consumers sit on it and they share this single device path: push-to-talk
5
5
  * voice input (src/audio/voice-input-session.ts) and wake-word detection
6
6
  * (src/audio/wake-runtime.ts). A wake does not END a capture session, it starts
7
- * one — the SDK listener keeps the same stream open and switches it to recording
8
- * the utterance that follows — so a second opener would drop the beginning of a
7
+ * one, the SDK listener keeps the same stream open and switches it to recording
8
+ * the utterance that follows, so a second opener would drop the beginning of a
9
9
  * sentence and race the operating system for a device that is already held.
10
10
  *
11
11
  * The framing arithmetic, the recorder argv and the utterance policy all live in
12
12
  * the SDK (`@pellux/goodvibes-sdk/platform/voice/capture`), because getting any
13
13
  * of them subtly wrong is SILENT: a container header out of byte alignment, or a
14
14
  * short frame, still "works" and simply never detects. What is local is the one
15
- * thing that cannot be shared — actually starting a process. That mirrors
15
+ * thing that cannot be shared, actually starting a process. That mirrors
16
16
  * playback exactly (see player.ts): resolve a command off PATH, spawn it, and
17
17
  * treat "no tool installed" as a reported state rather than an exception.
18
18
  */
@@ -31,7 +31,7 @@ import {
31
31
  /**
32
32
  * Whether a command is runnable from PATH. Same scan `player.ts` uses for
33
33
  * mpv/ffplay (`resolveStreamingAudioPlayerCommand` -> `findExecutable`): every
34
- * PATH entry, X_OK access, Windows extensions included — kept identical so a
34
+ * PATH entry, X_OK access, Windows extensions included, kept identical so a
35
35
  * host where playback finds its tool and capture does not is a real difference
36
36
  * in what is installed, never a difference in how the two looked.
37
37
  */
@@ -70,7 +70,7 @@ export const spawnRecorderProcess: CaptureSpawn = (command, args): CaptureChildP
70
70
  // Adapted rather than returned directly: the SDK's port declares the signal as
71
71
  // a plain `string` (it is shared with a browser bundle that has no
72
72
  // NodeJS.Signals) and node's narrower union is not assignable to it. The two
73
- // event listeners are branched explicitly for the same reason — node's `on` is
73
+ // event listeners are branched explicitly for the same reason, node's `on` is
74
74
  // overloaded per event name and takes no union.
75
75
  return {
76
76
  stdout: child.stdout,
@@ -103,7 +103,7 @@ export function createTuiCaptureOpener(options: TuiCaptureOpenerOptions = {}): A
103
103
  platform: options.platform ?? process.platform,
104
104
  // FALSE here, and correct: a recorder subprocess captures raw PCM and filters
105
105
  // nothing. The suppression stage is applied by the SDK's own wrapper inside
106
- // WakeListener and PushToTalkSession, which ask this opener for raw frames —
106
+ // WakeListener and PushToTalkSession, which ask this opener for raw frames,
107
107
  // so `speex` arriving at the RECORDER directly, unwrapped by either, is still
108
108
  // refused rather than passed through unfiltered.
109
109
  speexAvailable: false,
@@ -2,7 +2,7 @@
2
2
  * The two onnxruntime-web assets the wake engine needs on disk.
3
3
  *
4
4
  * Both are imported with `with { type: 'file' }`, which resolves to a PATH
5
- * string rather than module contents — a real filesystem path when the shell
5
+ * string rather than module contents, a real filesystem path when the shell
6
6
  * runs from source, and a `/$bunfs/root/...` path inside a compiled binary,
7
7
  * where the bytes are embedded. Declared here because these are asset
8
8
  * specifiers, not typed modules: onnxruntime-web publishes them for exactly
@@ -43,7 +43,7 @@ export interface LocalStreamingAudioPlayerOptions {
43
43
  readonly env?: NodeJS.ProcessEnv;
44
44
  readonly spawnProcess?: SpawnProcessFactory;
45
45
  /**
46
- * Injected player command — the test seam companion to `spawnProcess`.
46
+ * Injected player command, the test seam companion to `spawnProcess`.
47
47
  * When set, the constructor uses it verbatim instead of scanning PATH, so
48
48
  * deterministic fake-sink tests never depend on mpv/ffplay being installed
49
49
  * on the machine running them. Pass null to model "no player found".
@@ -101,7 +101,7 @@ export class LocalStreamingAudioPlayer implements StreamingAudioPlayer {
101
101
  }
102
102
 
103
103
  // An intentional interrupt (turn cancel / quit chord / /tts stop) has
104
- // already torn the process down via `abort` and must cut immediately —
104
+ // already torn the process down via `abort` and must cut immediately,
105
105
  // do not wait on a graceful drain. A natural end-of-speech, by contrast,
106
106
  // closes stdin and waits for the sink to play out every buffered sample
107
107
  // so the tail of the response is never truncated.
@@ -163,7 +163,7 @@ export function resolveStreamingAudioPlayerCommand(env: NodeJS.ProcessEnv = proc
163
163
  }
164
164
 
165
165
  // ffplay -autoexit quits as soon as its input ends, before the audio output
166
- // buffer has drained — that clips the tail of the response. `apad` appends a
166
+ // buffer has drained, that clips the tail of the response. `apad` appends a
167
167
  // short run of silence so the real audio is fully played out and only the
168
168
  // trailing silence gets trimmed.
169
169
  const FFPLAY_APAD = ['-af', 'apad=pad_dur=0.3'] as const;
@@ -177,7 +177,7 @@ function buildPlayerArgs(command: StreamingAudioPlayerCommand, format?: string):
177
177
  }
178
178
 
179
179
  /**
180
- * awaitReady — resolves once the spawned player has actually started (its
180
+ * awaitReady, resolves once the spawned player has actually started (its
181
181
  * 'spawn' event), rejects if it fails to start ('error'), and resolves early
182
182
  * if the caller aborts during startup so an intentional interrupt is never
183
183
  * blocked. This is the readiness gate that keeps the first audio byte from
@@ -20,18 +20,18 @@ export interface WireSpokenTurnRuntimeOptions {
20
20
  readonly events: UiRuntimeEvents;
21
21
  readonly notify: (message: string) => void;
22
22
  /**
23
- * Optional player factory — injected in tests to avoid spawning real
23
+ * Optional player factory, injected in tests to avoid spawning real
24
24
  * subprocesses. Defaults to LocalStreamingAudioPlayer.
25
25
  */
26
26
  readonly playerFactory?: () => StreamingAudioPlayer;
27
27
  }
28
28
 
29
29
  /**
30
- * wireSpokenTurnRuntime — wires the spoken-turn pipeline against the runtime
30
+ * wireSpokenTurnRuntime, wires the spoken-turn pipeline against the runtime
31
31
  * event bus.
32
32
  *
33
33
  * Always-speak mode: when `ui.voiceEnabled` is true in config, every
34
- * TURN_SUBMITTED event arms the turn for spoken output automatically — the
34
+ * TURN_SUBMITTED event arms the turn for spoken output automatically, the
35
35
  * user does not need to prefix the prompt with /tts. The availability check
36
36
  * inside SpokenTurnController still gates gracefully when no player is found.
37
37
  */
@@ -39,7 +39,7 @@ export function wireSpokenTurnRuntime(options: WireSpokenTurnRuntimeOptions): Sp
39
39
  const player = options.playerFactory ? options.playerFactory() : new LocalStreamingAudioPlayer();
40
40
  // The TUI's subprocess-based player already satisfies the SDK's AudioSink
41
41
  // interface unchanged (see docs/decisions/2026-07-06-spoken-turn-tts-policy-sdk-hoist.md
42
- // in the SDK repo) — only the option name (`sink` not `player`) and the
42
+ // in the SDK repo), only the option name (`sink` not `player`) and the
43
43
  // attribution `source` are new.
44
44
  const controller = new SpokenTurnController({
45
45
  voiceService: options.voiceService,
@@ -1,11 +1,11 @@
1
1
  /**
2
- * voice-capture-wiring.ts — composes the terminal's two voice consumers over ONE
2
+ * voice-capture-wiring.ts, composes the terminal's two voice consumers over ONE
3
3
  * capture path.
4
4
  *
5
5
  * Push-to-talk and wake detection are not two audio stacks. They share the
6
6
  * opener built here (capture.ts), the transcription gateway (core/voice-stt-gateway.ts)
7
- * and the same `voice.wake.*` capture rows — device, recorder, noise
8
- * suppression, ceiling — so a device that works for one works for the other and
7
+ * and the same `voice.wake.*` capture rows, device, recorder, noise
8
+ * suppression, ceiling, so a device that works for one works for the other and
9
9
  * a change in /settings applies to both.
10
10
  *
11
11
  * This is the composition root the shell calls once. It owns nothing the shell
@@ -30,7 +30,7 @@ import { wakeProvisionStatus } from '@pellux/goodvibes-sdk/platform/voice';
30
30
 
31
31
  export interface VoiceCaptureWiringDeps {
32
32
  readonly configManager: ConfigManager;
33
- /** `<root>/voice` — the managed root the wake tree hangs off (same root /voice setup uses). */
33
+ /** `<root>/voice`, the managed root the wake tree hangs off (same root /voice setup uses). */
34
34
  readonly managedVoiceRoot: string;
35
35
  /** A directory this surface owns for the extracted onnxruntime assets. */
36
36
  readonly assetDirectory: string;
@@ -56,7 +56,7 @@ export interface VoiceCaptureWiring {
56
56
  * standing condition they already know about.
57
57
  */
58
58
  readonly status: () => VoiceCaptureIndicatorState | null;
59
- /** Teardown, for the shell's `unsubs` registry — releases any open device. */
59
+ /** Teardown, for the shell's `unsubs` registry, releases any open device. */
60
60
  readonly unsubs: readonly (() => void)[];
61
61
  }
62
62
 
@@ -1,7 +1,7 @@
1
1
  /**
2
- * voice-input-session.ts — push-to-talk voice input for the terminal.
2
+ * voice-input-session.ts, push-to-talk voice input for the terminal.
3
3
  *
4
- * PRESS TO START, PRESS AGAIN TO STOP — not press-and-hold. A terminal receives
4
+ * PRESS TO START, PRESS AGAIN TO STOP, not press-and-hold. A terminal receives
5
5
  * discrete key EVENTS, not held-key state: there is no key-release event to
6
6
  * observe, so a genuine hold would have to be faked with a timer that guesses
7
7
  * when the user let go. The binding's description says "press to start, press
@@ -63,7 +63,7 @@ const PHASE_INDICATOR: Partial<Record<PushToTalkPhase, VoiceCaptureIndicatorStat
63
63
  /**
64
64
  * Wire push-to-talk. One session object is reused across presses (the SDK session
65
65
  * is restartable after both a stop and a failure), so a device is opened per
66
- * press and released on every path out of it — including the failing ones.
66
+ * press and released on every path out of it, including the failing ones.
67
67
  */
68
68
  export function wireVoiceInputRuntime(deps: VoiceInputRuntimeDeps): VoiceInputRuntime {
69
69
  let session: PushToTalkSession | null = null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * wake-inference.ts — the terminal's inference runtime for the wake engine.
2
+ * wake-inference.ts, the terminal's inference runtime for the wake engine.
3
3
  *
4
4
  * The SDK engine never imports an inference runtime; it declares the shape of a
5
5
  * session ({@link WakeInferenceSession}) and takes one from the host. This is
@@ -13,7 +13,7 @@
13
13
  * `/$bunfs/root/ort-wasm-simd-threaded.mjs`, which is not something bun embeds
14
14
  * for a dynamic path import, and session creation fails at runtime with
15
15
  * "Cannot find module". So both assets are imported with `with { type: 'file' }`
16
- * — embedded in the binary, handed to us as a path — written into a directory
16
+ *, embedded in the binary, handed to us as a path, written into a directory
17
17
  * this surface owns, and `ort.env.wasm.wasmPaths` is pointed at that directory.
18
18
  * The same code path runs from source, where the imports resolve to the real
19
19
  * files in node_modules and the copy is a no-op after the first launch.
@@ -24,7 +24,7 @@
24
24
  * rather than trusting a stale extraction from a previous version.
25
25
  */
26
26
 
27
- import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
27
+ import { mkdirSync, readFileSync } from 'node:fs';
28
28
  import { join } from 'node:path';
29
29
  import * as ort from 'onnxruntime-web/wasm';
30
30
  import glueAssetPath from 'onnxruntime-web/ort-wasm-simd-threaded.mjs' with { type: 'file' };
@@ -36,10 +36,11 @@ import type {
36
36
  WakeTensor,
37
37
  } from '@pellux/goodvibes-sdk/platform/voice';
38
38
  import { WakeWordEngine } from '@pellux/goodvibes-sdk/platform/voice';
39
+ import { atomicWriteFileSync } from '@pellux/goodvibes-sdk/platform/config';
39
40
 
40
41
  /**
41
42
  * The runtime asks for its glue and its wasm by these exact names, relative to
42
- * `ort.env.wasm.wasmPaths` — so the extracted copies must keep them.
43
+ * `ort.env.wasm.wasmPaths`, so the extracted copies must keep them.
43
44
  */
44
45
  const ORT_ASSETS = [
45
46
  { source: glueAssetPath, name: 'ort-wasm-simd-threaded.mjs' },
@@ -51,7 +52,7 @@ let configuredAssetDirectory: string | null = null;
51
52
 
52
53
  /**
53
54
  * Copy the onnxruntime-web assets into `directory` and return the value
54
- * `ort.env.wasm.wasmPaths` wants — a directory prefix WITH its trailing slash,
55
+ * `ort.env.wasm.wasmPaths` wants, a directory prefix WITH its trailing slash,
55
56
  * which the runtime concatenates a file name onto. Without the slash it looks
56
57
  * for a sibling of the directory and reports a missing module.
57
58
  */
@@ -67,7 +68,11 @@ export function extractOnnxRuntimeAssets(directory: string): string {
67
68
  // Absent, or unreadable: either way it gets written below.
68
69
  }
69
70
  if (existing !== null && existing.equals(bytes)) continue;
70
- writeFileSync(target, bytes);
71
+ // The directory is shared by every TUI process for this user; a plain
72
+ // write can leave a torn file for a concurrent process's WASM loader.
73
+ // The SDK's atomicWriteFileSync now accepts raw bytes directly (sdk
74
+ // 2.0.18), so it does the temp-then-rename instead of this file inlining it.
75
+ atomicWriteFileSync(target, bytes, { mkdirp: true });
71
76
  }
72
77
  return `${directory}/`;
73
78
  }
@@ -138,7 +143,7 @@ export interface WakeEngineFactoryOptions {
138
143
  /**
139
144
  * The provisioned speech gate, present only when `voice.wake.vadThreshold` asks
140
145
  * for one. Absent means the engine scores every frame, which is what the
141
- * shipped default of 0 asks for — not a gate that failed to load, because that
146
+ * shipped default of 0 asks for, not a gate that failed to load, because that
142
147
  * case is a startup blocker upstream of here.
143
148
  */
144
149
  readonly vadPath?: string;
@@ -152,7 +157,7 @@ export interface WakeEngineFactoryOptions {
152
157
  * Build the `createEngine` callback the SDK listener drives.
153
158
  *
154
159
  * The listener calls it on EVERY start including a restart, because a restart
155
- * exists to recover from a runtime that died — so the sessions are created here
160
+ * exists to recover from a runtime that died, so the sessions are created here
156
161
  * per call rather than captured once.
157
162
  */
158
163
  export function createWakeEngineFactory(options: WakeEngineFactoryOptions): () => Promise<WakeWordEngine> {
@@ -1,11 +1,11 @@
1
1
  /**
2
- * wake-runtime.ts — wake-word detection on the terminal.
2
+ * wake-runtime.ts, wake-word detection on the terminal.
3
3
  *
4
4
  * The SDK owns the policy that would otherwise be rewritten per surface: the
5
5
  * front end, the patience/cooldown rules, keeping ONE stream open across a wake
6
6
  * so the utterance that follows is not clipped, resetting the engine afterwards
7
7
  * so the command just spoken is not scored again, and the supervisor's restart
8
- * and latch decisions. What is local is everything that touches this machine —
8
+ * and latch decisions. What is local is everything that touches this machine,
9
9
  * the recorder subprocess (capture.ts), the inference runtime (wake-inference.ts),
10
10
  * transcription over the daemon (core/voice-stt-gateway.ts), the activation sound, and
11
11
  * the shell's indicator row.
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * - **ENABLING NEVER DOWNLOADS.** The model ships with the installation, so on a
16
16
  * normal machine `start()` below finds the artifacts already there and needs
17
- * nothing else — that is the whole point of provisioning at install time. What
17
+ * nothing else, that is the whole point of provisioning at install time. What
18
18
  * it must never do is FETCH: the check here is read-only and content-verified,
19
19
  * and a host whose artifacts are missing or torn gets told which and gets the
20
20
  * recovery command named, instead of a switch that silently pulls 6 MB. A
@@ -65,7 +65,7 @@ export interface WakeRuntimeDeps {
65
65
  /** Runtime toggling: `voice.wake.enabled` and `voice.wake.surfaces.tui`. */
66
66
  readonly subscribeConfig: (key: string, listener: () => void) => () => void;
67
67
  readonly openCapture: AudioCaptureOpener;
68
- /** Managed root the wake tree hangs off — `<managed>/wake` (SDK resolveManagedWakePaths). */
68
+ /** Managed root the wake tree hangs off, `<managed>/wake` (SDK resolveManagedWakePaths). */
69
69
  readonly managedRoot: string;
70
70
  /** Directory this surface owns for the extracted onnxruntime assets. */
71
71
  readonly assetDirectory: string;
@@ -95,7 +95,7 @@ export interface WakeRuntimeDeps {
95
95
 
96
96
  /**
97
97
  * What this runtime reads out of provisioning: whether the wake models are usable
98
- * at all, and whether the SPEECH GATE's own artifact is there — they are separate
98
+ * at all, and whether the SPEECH GATE's own artifact is there, they are separate
99
99
  * answers, because `voice.wake.vadThreshold` defaults to 0 and a detector runs
100
100
  * perfectly well with no gate provisioned.
101
101
  */
@@ -200,7 +200,7 @@ export function wireWakeRuntime(deps: WakeRuntimeDeps): WakeRuntime {
200
200
  if (settings.autoSubmit) deps.submitTurn(text);
201
201
  else {
202
202
  deps.writeDraft(text);
203
- deps.notify('[Wake] Transcript placed in the composer (voice.wake.autoSubmit is off — press Enter to send it).');
203
+ deps.notify('[Wake] Transcript placed in the composer (voice.wake.autoSubmit is off: press Enter to send it).');
204
204
  deps.render();
205
205
  }
206
206
  } catch (error) {
@@ -215,14 +215,14 @@ export function wireWakeRuntime(deps: WakeRuntimeDeps): WakeRuntime {
215
215
  deps.notify(
216
216
  `[Wake] voice.wake.enabled is on, but the wake models are not provisioned (${provision.reason ?? 'not-provisioned'}), `
217
217
  + 'so nothing is listening. Installing goodvibes provisions them and a running daemon retries at boot, so this '
218
- + 'means the download has not succeeded yet — run /voice wake setup to fetch and verify them now.',
218
+ + 'means the download has not succeeded yet; run /voice wake setup to fetch and verify them now.',
219
219
  );
220
220
  deps.render();
221
221
  return;
222
222
  }
223
223
  const paths = resolveManagedWakePaths(deps.managedRoot);
224
224
  // The SDK resolves `voice.wake.models` to files: the pinned id inside the
225
- // managed tree, any other id against voice.wake.customModelDir — and when that
225
+ // managed tree, any other id against voice.wake.customModelDir, and when that
226
226
  // row is empty, against the managed `custom` directory, which is the fallback
227
227
  // the row's description promises and the one a host would otherwise get wrong
228
228
  // by looking in the process's working directory.
@@ -249,7 +249,7 @@ export function wireWakeRuntime(deps: WakeRuntimeDeps): WakeRuntime {
249
249
  models: modelFiles.map((model) => ({ id: model.id, path: model.path })),
250
250
  settings,
251
251
  // The speech gate, when the row asks for one. `voice.wake.vadThreshold`
252
- // above 0 with the artifact missing never reaches here — it is a blocker
252
+ // above 0 with the artifact missing never reaches here, it is a blocker
253
253
  // from resolveWakeRuntimeSettings, so the detector does not start at all
254
254
  // rather than starting with the gate quietly absent.
255
255
  ...(settings.vadThreshold > 0 ? { vadPath: paths.vadPath } : {}),
@@ -273,7 +273,7 @@ export function wireWakeRuntime(deps: WakeRuntimeDeps): WakeRuntime {
273
273
  // Reported to the user, not only logged: a detector that stopped
274
274
  // listening is exactly the thing a silent log entry hides.
275
275
  deps.notify(restarting
276
- ? `[Wake] The capture stream ended (${error.message}) — ${failureDetail}.`
276
+ ? `[Wake] The capture stream ended (${error.message}): ${failureDetail}.`
277
277
  : `[Wake] The wake-word detector stopped: ${failureDetail}. It stays off until voice.wake.enabled is turned off and on again.`);
278
278
  deps.render();
279
279
  },
@@ -10,7 +10,7 @@
10
10
  * command are derived from the usage strings documented in help.ts's
11
11
  * COMMAND_HELP table (read-only reference; no mutation of existing files).
12
12
  *
13
- * Deferred wiring (one-line changes to existing files — NOT done here):
13
+ * Deferred wiring (one-line changes to existing files, NOT done here):
14
14
  * src/cli/completion.ts: replace renderCompletion() body with
15
15
  * ```
16
16
  * import { generateCompletion } from './completions/generate.ts';
@@ -629,7 +629,7 @@ export function generateFish(surface: CompletionSurface): string {
629
629
  }
630
630
 
631
631
  // ---------------------------------------------------------------------------
632
- // Dispatcher — mirrors the existing renderCompletion(shell) API
632
+ // Dispatcher, mirrors the existing renderCompletion(shell) API
633
633
  // ---------------------------------------------------------------------------
634
634
 
635
635
  /**
package/src/cli/doctor.ts CHANGED
@@ -9,14 +9,14 @@ import type { GoodVibesCliOutputFormat } from '@pellux/goodvibes-terminal-shell'
9
9
  import { buildHooksValidation } from './hooks-report.ts';
10
10
 
11
11
  // ---------------------------------------------------------------------------
12
- // `goodvibes doctor <explain|routing|hooks>` — the diagnostician subcommands.
12
+ // `goodvibes doctor <explain|routing|hooks>`, the diagnostician subcommands.
13
13
  // Each one explains a decision the platform already makes, reading the LIVE
14
14
  // config and reusing the platform's OWN decision machinery. None of them
15
15
  // changes config or fires a real action:
16
- // explain — walks the real PermissionManager to say why a tool/command
16
+ // explain , walks the real PermissionManager to say why a tool/command
17
17
  // would be allowed / asked / denied under the current mode.
18
- // routing — prints which model/provider serves which role, from live config.
19
- // hooks — lists registered hooks, from where, and their validation status
18
+ // routing , prints which model/provider serves which role, from live config.
19
+ // hooks , lists registered hooks, from where, and their validation status
20
20
  // (reuses the hooks-validate core in hooks-report.ts).
21
21
  // ---------------------------------------------------------------------------
22
22
 
@@ -124,7 +124,7 @@ function reasonExplanation(result: PermissionCheckResult, mode: string, toolKey:
124
124
  case 'mode_allow_all':
125
125
  if (mode === 'plan') return 'Plan mode allows read-class tools.';
126
126
  if (mode === 'accept-edits') return 'Accept-edits mode allows read-class tools.';
127
- return 'Permission mode is "allow-all" — every tool call is auto-approved.';
127
+ return 'Permission mode is "allow-all": every tool call is auto-approved.';
128
128
  case 'mode_denied': return 'The active permission mode denies this tool class.';
129
129
  case 'plan_mode': return 'Plan mode refuses mutating / execute / delegate tools and steers the model to present a plan instead.';
130
130
  case 'mode_accept_edits': return 'Accept-edits mode auto-approves file write/edit tools.';
@@ -134,7 +134,7 @@ function reasonExplanation(result: PermissionCheckResult, mode: string, toolKey:
134
134
  case 'session_cached_allow': return 'A remembered session decision ([A] allow-always) approves this call.';
135
135
  case 'session_cached_deny': return 'A remembered session decision denies this call.';
136
136
  case 'user_approved':
137
- case 'user_denied': return 'This reaches a Human-in-the-Loop approval prompt — the outcome depends on your response at the prompt.';
137
+ case 'user_denied': return 'This reaches a Human-in-the-Loop approval prompt; the outcome depends on your response at the prompt.';
138
138
  default: return 'Decided by the platform permission machinery.';
139
139
  }
140
140
  }
@@ -205,7 +205,7 @@ async function explain(options: DoctorSubcommandOptions): Promise<CliCommandOutp
205
205
 
206
206
  const a = result.analysis;
207
207
  const lines: string[] = [
208
- 'GoodVibes doctor — explain permission decision',
208
+ 'GoodVibes doctor: explain permission decision',
209
209
  ` subject : ${args.join(' ')}`,
210
210
  ` resolved as : ${target.interpretation}`,
211
211
  ` tool : ${target.tool} (category: ${category})`,
@@ -222,7 +222,7 @@ async function explain(options: DoctorSubcommandOptions): Promise<CliCommandOutp
222
222
  ` summary : ${a.summary}`,
223
223
  ...a.reasons.slice(0, 3).map((r) => ` reason : ${r}`),
224
224
  '',
225
- 'Layers walked (priority order — the platform PermissionManager decides; this shows the order it walks):',
225
+ 'Layers walked (priority order: the platform PermissionManager decides; this shows the order it walks):',
226
226
  ...LAYER_NAMES.map((name, i) => ` ${i === decidedIdx ? '▶' : ' '} ${i + 1}. ${name}${i === decidedIdx ? ' ← DECIDED HERE' : ''}`),
227
227
  '',
228
228
  `Decision: ${verdict}`,
@@ -284,7 +284,7 @@ function buildRoutingRoles(config: ConfigManager): RoutingRole[] {
284
284
  provider: emptyProvider(toolProvider),
285
285
  model: toolModel || '(unset)',
286
286
  keys: ['tools.llmEnabled', 'tools.llmProvider', 'tools.llmModel'],
287
- ...(config.get('tools.llmEnabled') === true ? {} : { note: 'disabled — no tool-LLM route active' }),
287
+ ...(config.get('tools.llmEnabled') === true ? {} : { note: 'disabled: no tool-LLM route active' }),
288
288
  },
289
289
  {
290
290
  role: 'Helper (cache/compaction/commit-message/etc.)',
@@ -292,7 +292,7 @@ function buildRoutingRoles(config: ConfigManager): RoutingRole[] {
292
292
  provider: emptyProvider(helperProvider),
293
293
  model: helperModel || '(unset)',
294
294
  keys: ['helper.enabled', 'helper.globalProvider', 'helper.globalModel'],
295
- ...(config.get('helper.enabled') === true ? {} : { note: 'disabled — helper tasks stay on the main model' }),
295
+ ...(config.get('helper.enabled') === true ? {} : { note: 'disabled: helper tasks stay on the main model' }),
296
296
  },
297
297
  {
298
298
  role: 'Narration LLM (TTS phrasing)',
@@ -312,7 +312,7 @@ function routing(options: DoctorSubcommandOptions): CliCommandOutput {
312
312
  return { output: JSON.stringify({ roles }, null, 2), exitCode: 0 };
313
313
  }
314
314
  const lines: string[] = [
315
- 'GoodVibes doctor — model / provider routing (live config)',
315
+ 'GoodVibes doctor: model / provider routing (live config)',
316
316
  '',
317
317
  ];
318
318
  for (const role of roles) {
@@ -345,11 +345,11 @@ function hooks(options: DoctorSubcommandOptions): CliCommandOutput {
345
345
  }
346
346
 
347
347
  const lines: string[] = [
348
- 'GoodVibes doctor — registered hooks',
348
+ 'GoodVibes doctor: registered hooks',
349
349
  ` source file : ${report.path}`,
350
350
  ];
351
351
  if (!report.present) {
352
- lines.push(' no hooks file present — nothing registered.');
352
+ lines.push(' no hooks file present: nothing registered.');
353
353
  return { output: lines.join('\n'), exitCode: 0 };
354
354
  }
355
355
  if (report.reason && report.checks.length === 0 && report.topLevelIssues.length === 0) {
@@ -3,7 +3,7 @@ import { join } from 'node:path';
3
3
 
4
4
  /**
5
5
  * The TUI's own `.goodvibes/` directory (logs, overflow buffers, exec output,
6
- * cache, session state, etc.) is transient scratch space, not project source —
6
+ * cache, session state, etc.) is transient scratch space, not project source,
7
7
  * but nothing else in the codebase excludes it from the *project's* git
8
8
  * history. Any `git add -A` (write-quit's auto-commit, a WRFC chain's own
9
9
  * commit, etc.) sweeps the whole tree in unless the project's .gitignore
@@ -17,7 +17,7 @@ const GOODVIBES_IGNORE_PATTERN = /(^|\n)[ \t]*\/?\.goodvibes\/?\*?[ \t]*(\n|$)/;
17
17
  * Ensures the project's .gitignore excludes .goodvibes/, appending the rule
18
18
  * exactly once if it is verifiably absent.
19
19
  *
20
- * @returns true only the FIRST time the rule is actually written this call —
20
+ * @returns true only the FIRST time the rule is actually written this call,
21
21
  * i.e. this specific invocation just appended/created it. Every subsequent
22
22
  * launch (rule already present) and every no-op case (not a git repo, or the
23
23
  * write failed) return false. The caller uses this to print a one-time
@@ -38,7 +38,7 @@ export function ensureGoodvibesGitignore(projectRoot: string): boolean {
38
38
  appendFileSync(gitignorePath, separator + rule);
39
39
  return true;
40
40
  } catch {
41
- // Best-effort only — never block startup on a gitignore write failure.
41
+ // Best-effort only, never block startup on a gitignore write failure.
42
42
  return false;
43
43
  }
44
44
  }
@@ -112,9 +112,9 @@ export async function prepareShellCliRuntime(
112
112
  } = resolveShellEntrypointOwnership(roots, cli.flags.workingDir ?? (cli.command === 'tui' ? cli.commandArgs[0] : undefined));
113
113
  configureActivityLogger(join(bootstrapWorkingDir, '.goodvibes', 'logs'));
114
114
  // Only prints the first time the rule is actually appended (not on every
115
- // launch) — see ensureGoodvibesGitignore's return-value doc.
115
+ // launch), see ensureGoodvibesGitignore's return-value doc.
116
116
  if (ensureGoodvibesGitignore(bootstrapWorkingDir)) {
117
- console.log("[goodvibes] added '.goodvibes/' to .gitignore — this directory holds transient TUI state (logs, session cache, exec output), not project source.");
117
+ console.log("[goodvibes] added '.goodvibes/' to .gitignore: this directory holds transient TUI state (logs, session cache, exec output), not project source.");
118
118
  }
119
119
  const daemonConfigMigration = runDaemonConfigMigration(bootstrapHomeDirectory);
120
120
  if (daemonConfigMigration?.migrated && (daemonConfigMigration.marker.moved.length + daemonConfigMigration.marker.discarded.length) > 0) {
@@ -250,7 +250,7 @@ export async function prepareShellCliRuntime(
250
250
  ? renderOnboardingCliStatus(statusOptions)
251
251
  : renderCliStatus(statusOptions));
252
252
  // Advisory findings are notes on an otherwise-usable install and must
253
- // never make a healthy install report failure — only a must-fix finding
253
+ // never make a healthy install report failure, only a must-fix finding
254
254
  // exits non-zero; --strict (for CI) flips advisories to failures too.
255
255
  process.exit(cli.command === 'doctor' ? resolveDoctorExitCode(snapshot.findings, cli.flags.strict) : 0);
256
256
  }