@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
@@ -24,7 +24,7 @@ const GRADIENT_CYCLE_FRAMES = 50;
24
24
  * Ms since the last STREAM_DELTA before the whimsical phrase rotation freezes
25
25
  * and createThinkingFragment shows an honest "stalled Ns" / "reconnecting"
26
26
  * label instead. Deliberately much shorter than the 30s stream-stall-watchdog
27
- * hint threshold (stream-stall-watchdog.ts) — that threshold gates a
27
+ * hint threshold (stream-stall-watchdog.ts), that threshold gates a
28
28
  * low-priority system message about a likely-dead connection; this one gates
29
29
  * a cosmetic label so the UI stops claiming "Vibing..." within a couple of
30
30
  * seconds of real silence, well before the stall is confirmed as a problem.
@@ -35,7 +35,7 @@ const THINKING_STALL_FREEZE_MS = 2_500;
35
35
  * Stall/reconnect state for the live thinking indicator, computed by the
36
36
  * caller every render frame from streamMetrics (see stream-event-wiring.ts).
37
37
  * `reconnect` is populated only once the SDK's STREAM_RETRY event fires
38
- * (structurally consumed — absent from SDK 0.35.0's TurnEvent union today).
38
+ * (structurally consumed, absent from SDK 0.35.0's TurnEvent union today).
39
39
  */
40
40
  export interface ThinkingStallInfo {
41
41
  /** Ms since the last STREAM_DELTA (or STREAM_START if none yet this turn). */
@@ -61,7 +61,7 @@ function fmtCost(usd: number): string {
61
61
  */
62
62
  export class UIFactory {
63
63
  /**
64
- * The header row. Delegates to renderHeaderLine (header-line.ts) — extracted
64
+ * The header row. Delegates to renderHeaderLine (header-line.ts), extracted
65
65
  * when the header gained the failover divergence marker and this file was
66
66
  * already on the 800-line source gate.
67
67
  *
@@ -85,7 +85,7 @@ export class UIFactory {
85
85
  strikethrough = false
86
86
  ): Line[] {
87
87
  // A historical user-message pill: it carries its own dark bodyBg, so its fg
88
- // reads fg.secondary/state.reasoning (light-on-dark) — this is conversation
88
+ // reads fg.secondary/state.reasoning (light-on-dark), this is conversation
89
89
  // content, not the transparent-terminal chrome, so it is not part of the
90
90
  // light-terminal chrome flip.
91
91
  return renderConversationFragment(text, width, {
@@ -111,12 +111,12 @@ export class UIFactory {
111
111
  });
112
112
  }
113
113
 
114
- /** The mid-turn queue as an editable list — see composer-fragments.ts. */
114
+ /** The mid-turn queue as an editable list, see composer-fragments.ts. */
115
115
  public static createQueuedMessageList(width: number, items: readonly { readonly id: string; readonly text: string }[]): Line[] {
116
116
  return renderQueuedMessageList(width, items);
117
117
  }
118
118
 
119
- /** The optional "used N memories" provenance chip — see composer-fragments.ts. */
119
+ /** The optional "used N memories" provenance chip, see composer-fragments.ts. */
120
120
  public static createMemoryProvenanceChip(width: number, count: number, entries: readonly MemoryProvenanceEntry[], expanded: boolean): Line[] {
121
121
  return renderMemoryProvenanceChip(width, count, entries, expanded);
122
122
  }
@@ -150,10 +150,10 @@ export class UIFactory {
150
150
  // Session permission mode (config value). Rendered as a leading pill in the
151
151
  // posture block; undefined suppresses the pill (e.g. bare test callers).
152
152
  permissionMode?: string,
153
- // The web surface's reachable URL, when that surface is enabled — a
153
+ // The web surface's reachable URL, when that surface is enabled, a
154
154
  // persistent low-priority context segment; undefined suppresses it.
155
155
  webSurfaceUrl?: string,
156
- // True while power.keepAwake holds — renders the always-visible
156
+ // True while power.keepAwake holds, renders the always-visible
157
157
  // "sleep disabled" chip in the posture block (the danger-mode idiom: a
158
158
  // persistent, colored surface indicator, the safety mechanism itself).
159
159
  powerKeepAwake?: boolean,
@@ -180,7 +180,7 @@ export class UIFactory {
180
180
  promptLines.forEach((text, i) => {
181
181
  const contentW = boxWidth - 4;
182
182
  const prefix = i === 0 ? ' › ' : ' ';
183
- // Render text without cursor insertion — cursor is overlaid after
183
+ // Render text without cursor insertion, cursor is overlaid after
184
184
  const rawText = `${prefix}${text}`;
185
185
  const paddedText = fitDisplay(rawText, contentW);
186
186
  const contentLine = createBaseLine();
@@ -218,7 +218,7 @@ export class UIFactory {
218
218
  }
219
219
  }
220
220
  } else if (promptFocused && i === promptLines.length - 1) {
221
- // No cursorPos provided — show block at end (fallback)
221
+ // No cursorPos provided, show block at end (fallback)
222
222
  const endX = boxStartX + 2 + prefix.length + text.length;
223
223
  if (endX < boxStartX + boxWidth - 2) {
224
224
  contentLine[endX] = { char: GLYPHS.surface.cursor, fg: '252', bg: promptFocused ? BG_COLOR : '#334155', bold: false, dim: false, underline: false, italic: false, strikethrough: false };
@@ -226,11 +226,11 @@ export class UIFactory {
226
226
  }
227
227
 
228
228
  // focus visibility (item 1c): when the panel workspace owns focus
229
- // and the composer is empty, name the state and the way back — the
229
+ // and the composer is empty, name the state and the way back, the
230
230
  // dimmed prompt alone (TEXT_COLOR/BG_COLOR above) told you nothing was
231
231
  // wrong, but not why keystrokes weren't landing here.
232
232
  if (!promptFocused && text === '' && i === 0) {
233
- const hintText = 'panel focused — Esc returns';
233
+ const hintText = 'panel focused: Esc returns';
234
234
  const hintStartX = boxStartX + 2 + prefix.length;
235
235
  let hx = hintStartX;
236
236
  for (const ch of hintText) {
@@ -296,7 +296,7 @@ export class UIFactory {
296
296
  // (light-terminal-aware); state.info reads on both light and dark terminals.
297
297
  const t = activeUiTones();
298
298
  const composerTokens: Array<{ text: string; fg: string; bold?: boolean; dim?: boolean }> = [];
299
- // Permission-mode pill — always shown so the active session posture (normal
299
+ // Permission-mode pill, always shown so the active session posture (normal
300
300
  // / plan / accept-edits / auto) is visible at a glance. Tone: normal reads
301
301
  // dim/neutral, plan reads info (read-only, safe), accept-edits and auto read
302
302
  // as caution (raised autonomy). Cycled by Shift+Tab, toggled by /plan.
@@ -305,7 +305,7 @@ export class UIFactory {
305
305
  const modeFg = modeTone === 'caution' ? t.chrome.warn : modeTone === 'info' ? t.state.info : '244';
306
306
  composerTokens.push({ text: ` mode:${permissionModeLabel(permissionMode)} `, fg: modeFg, bold: modeTone !== 'neutral', dim: modeTone === 'neutral' });
307
307
  }
308
- // Context-usage chip — always-visible compaction-pressure indicator so the
308
+ // Context-usage chip, always-visible compaction-pressure indicator so the
309
309
  // user sees compaction approaching before it happens. Colored by proximity
310
310
  // to the auto-compact threshold (fraction; falls back to 0.85 when unset).
311
311
  if (contextWindow && contextWindow > 0) {
@@ -325,7 +325,7 @@ export class UIFactory {
325
325
  : t.chrome.warn;
326
326
  composerTokens.push({ text: ` risk:${composerPendingRisk} `, fg: riskColor, bold: true });
327
327
  }
328
- // "sleep disabled" chip — always visible while keep-awake holds, in the
328
+ // "sleep disabled" chip, always visible while keep-awake holds, in the
329
329
  // danger-mode idiom (a persistent warn-tone indicator; the chip is the
330
330
  // safety mechanism, so there is no timer and no AC-only variant).
331
331
  if (powerKeepAwake) composerTokens.push({ text: ` ${SLEEP_DISABLED_CHIP} `, fg: t.chrome.warn, bold: true });
@@ -353,7 +353,7 @@ export class UIFactory {
353
353
  }
354
354
  lines.push(postureLine);
355
355
  } else if (compact && powerKeepAwake) {
356
- // The keep-awake chip is a safety indicator — it survives compact height
356
+ // The keep-awake chip is a safety indicator, it survives compact height
357
357
  // even though the rest of the posture row (mode/ctx/risk/state/flags) is
358
358
  // dropped at height < 30. Its own compact-surviving slot.
359
359
  const chipLine = createBaseLine();
@@ -377,7 +377,7 @@ export class UIFactory {
377
377
  const tokenSep = ` ${GLYPHS.navigation.pipeSeparator} `;
378
378
  // 'n/a' (not 'unpriced') to stay compact in the single-line footer and
379
379
  // match the existing "no priceable data" convention used elsewhere
380
- // (cockpit-panel formatCost, agent-inspector-shared) — the footer has no
380
+ // (cockpit-panel formatCost, agent-inspector-shared), the footer has no
381
381
  // room for a longer marker before truncation kicks in.
382
382
  const mainCostStr = model
383
383
  ? isModelPriced(model)
@@ -387,7 +387,7 @@ export class UIFactory {
387
387
  // Honest total = your main session + the delegated fleet. We show a SPLIT
388
388
  // ("you ~$X · fleet ~$Y") rather than one summed figure: the two costs are
389
389
  // tracked and attributed to different actors, and the split directly answers
390
- // "where did the money go" — the exact confusion in the eval where the footer
390
+ // "where did the money go", the exact confusion in the eval where the footer
391
391
  // showed only the main session (~$0.046) while the fleet cost ~10x more
392
392
  // ($0.446). The fleet segment appears only when there is a real fleet cost, so
393
393
  // the idle single-session footer is unchanged.
@@ -405,7 +405,7 @@ export class UIFactory {
405
405
  const copiedNotice = isRecentlyCopied ? ` [COPIED] ` : '';
406
406
  const statsLine = ' ' + tokenLine + ' '.repeat(Math.max(0, width - 4 - getDisplayWidth(tokenLine) - getDisplayWidth(copiedNotice))) + copiedNotice;
407
407
  lines.push(this.stringToLine(statsLine, width, { fg: isRecentlyCopied ? '81' : '244', bold: isRecentlyCopied }));
408
- // Context usage progress bar — suppressed in compact mode.
408
+ // Context usage progress bar, suppressed in compact mode.
409
409
  if (!compact && contextWindow && contextWindow > 0) {
410
410
  const ctxTokens = lastInputTokens ?? 0;
411
411
  const label = ' Context Usage: ';
@@ -421,7 +421,7 @@ export class UIFactory {
421
421
  lines.push(this.createProgressBarLine(label, ctxPct, barWidth, width, suffix, thresholdFraction));
422
422
  }
423
423
  // Context info line (working dir, model+provider, tools, hitl).
424
- // Suppressed in compact mode. mode/status/flags are intentionally omitted —
424
+ // Suppressed in compact mode. mode/status/flags are intentionally omitted,
425
425
  // the posture block above owns them, so they are not duplicated here.
426
426
  if (!compact && (workingDir || model)) {
427
427
  const home = typeof process !== 'undefined' ? process.env.HOME ?? '' : '';
@@ -433,25 +433,25 @@ export class UIFactory {
433
433
  // segment is character-truncated mid-word. cwd/model are the essential
434
434
  // orientation segments (priority 0); the spine liveness marker is the
435
435
  // daemon-honesty signal and must outlive the two decorative segments
436
- // (tool count, notify mode) — it is ordered ahead of them too, so a
436
+ // (tool count, notify mode), it is ordered ahead of them too, so a
437
437
  // narrow line drops "N tools"/"notify:x" whole before spine is at risk.
438
438
  const ctxParts: PrioritizedSegment[] = [];
439
439
  if (displayDir) ctxParts.push({ text: displayDir, priority: 0 });
440
440
  if (model) {
441
441
  ctxParts.push({ text: model + (provider ? ` (${provider})` : ''), priority: 0 });
442
442
  }
443
- // Divergence marker — its own segment so a narrow line drops it WHOLE
443
+ // Divergence marker, its own segment so a narrow line drops it WHOLE
444
444
  // (joinPrioritizedSegments breaks priority ties toward the later
445
445
  // segment) rather than truncating it into a half-word. Priority 0: it
446
446
  // outranks every decorative segment, and what survives without it is
447
447
  // still the SERVING backend, never a claim about the configured one.
448
448
  if (modelNote) ctxParts.push({ text: modelNote, priority: 0 });
449
- // Cross-surface spine posture — plain words, no blame. Adopted mode only.
449
+ // Cross-surface spine posture, plain words, no blame. Adopted mode only.
450
450
  if (sessionSpineStatus) ctxParts.push({ text: `spine:${sessionSpineStatus}`, priority: 1 });
451
- // Web surface reachability — plain, persistent; dropped first under width pressure.
451
+ // Web surface reachability, plain, persistent; dropped first under width pressure.
452
452
  if (webSurfaceUrl) ctxParts.push({ text: `web:${webSurfaceUrl}`, priority: 2 });
453
453
  if (toolCount) ctxParts.push({ text: `${toolCount} tools`, priority: 2 });
454
- // Labeled "notify" (not "hitl") — /mode (aliased /hitl) governs UX
454
+ // Labeled "notify" (not "hitl"), /mode (aliased /hitl) governs UX
455
455
  // notification verbosity (quiet/balanced/operator), not tool
456
456
  // auto-approval, so it must not share vocabulary with the DANGER MODE
457
457
  // risk banner rendered a few lines below. Lowest priority: dropped first.
@@ -494,19 +494,19 @@ export class UIFactory {
494
494
  // wording (approval/reconnecting/pre-first-token/stalled/thinking) are no
495
495
  // longer minted here. They come from the SDK presentation contract's
496
496
  // waitingPhrase() (@pellux/goodvibes-sdk/platform/presentation, already
497
- // adopted by the agent) — see createThinkingFragment
497
+ // adopted by the agent), see createThinkingFragment
498
498
  // below. This renderer still decides WHICH state applies from its own
499
499
  // stall/reconnect/approval signals (computeStallInfo/computeRenderStallInfo
500
500
  // stay renderer-local per the extraction decision record); only the exact
501
501
  // wording is shared.
502
502
 
503
- // Gradient colors for thinking text — cyan→purple in dark, teal→purple in
503
+ // Gradient colors for thinking text, cyan→purple in dark, teal→purple in
504
504
  // light (matches splash/brand). Read live per render inside
505
505
  // createThinkingFragment via activeUiTones() rather than baked into a static
506
506
  // field, so a mode flip re-resolves without a module reload.
507
507
 
508
508
  /**
509
- * Per-frame stall info from stream metrics — computed from lastDeltaAtMs every render (not
509
+ * Per-frame stall info from stream metrics, computed from lastDeltaAtMs every render (not
510
510
  * from any event) so it degrades gracefully with zero new SDK events. Undefined until the
511
511
  * first delta clock exists this turn.
512
512
  */
@@ -525,11 +525,11 @@ export class UIFactory {
525
525
  * never advanced during tool execution (the model isn't producing tokens
526
526
  * then), so without this gate any tool call longer than
527
527
  * THINKING_STALL_FREEZE_MS would make the thinking fragment print
528
- * "Stalled Ns..." directly above the ticking "executing (Ns)" tool row — a
528
+ * "Stalled Ns..." directly above the ticking "executing (Ns)" tool row, a
529
529
  * false positive during ordinary tool execution (see stream-event-wiring.ts
530
530
  * TOOL_EXECUTING/TOOL_SUCCEEDED/TOOL_FAILED/TOOL_CANCELLED handlers).
531
- * Genuine no-delta silence while waiting on the provider — including the
532
- * pre-first-token case, where lastDeltaAtMs is seeded at STREAM_START —
531
+ * Genuine no-delta silence while waiting on the provider, including the
532
+ * pre-first-token case, where lastDeltaAtMs is seeded at STREAM_START,
533
533
  * still stall-detects normally here, since no tool is active then; that is
534
534
  * the honest stall case this indicator exists for.
535
535
  */
@@ -548,7 +548,7 @@ export class UIFactory {
548
548
  const tones = activeUiTones();
549
549
  // Freeze the whimsical phrase rotation once real silence has gone on
550
550
  // long enough to be misleading (THINKING_STALL_FREEZE_MS). Decide WHICH
551
- // honest waiting state applies (renderer-local — this signal computation
551
+ // honest waiting state applies (renderer-local, this signal computation
552
552
  // stays here per the extraction decision record), then defer the exact
553
553
  // wording to the SDK presentation contract's waitingPhrase() (which
554
554
  // mirrors the agent's adoption). Precedence matches the contract:
@@ -567,7 +567,7 @@ export class UIFactory {
567
567
  frame,
568
568
  });
569
569
  // Token-rate and time-to-first-token readouts are meaningless while waiting on the user, and a
570
- // "tok/s" figure next to an approval prompt reads as if the model were still working — suppress
570
+ // "tok/s" figure next to an approval prompt reads as if the model were still working, suppress
571
571
  // them; keep the elapsed timer since "how long the approval has waited" is honest.
572
572
  const speedSuffix = (!approvalPending && tokenSpeed !== undefined && tokenSpeed > 0) ? ` (${Math.round(tokenSpeed)} tok/s)` : '';
573
573
  const elapsedSuffix = elapsedMs !== undefined ? ` (${formatElapsed(elapsedMs)})` : '';
@@ -1,11 +1,11 @@
1
1
  // ---------------------------------------------------------------------------
2
- // ui-primitives.ts — glyph registry + tone-token table.
2
+ // ui-primitives.ts, glyph registry + tone-token table.
3
3
  //
4
4
  // These four tables (GLYPHS, UI_TONES, DIFF_TONES, SPINNER_FRAMES) are
5
5
  // no longer minted locally. They are the SDK presentation contract
6
6
  // (@pellux/goodvibes-sdk/platform/presentation, already
7
7
  // adopted by the agent), consumed here so the TUI and the agent
8
- // share ONE source (Mike's move-to-SDK ruling — machinery needed by 2+
8
+ // share ONE source (Mike's move-to-SDK ruling, machinery needed by 2+
9
9
  // surfaces => SDK). The TUI was the reference these values were lifted from
10
10
  // verbatim, so this swap is byte-identical. See
11
11
  // docs/decisions/2026-07-05-presentation-contract-sdk-extraction.md in the SDK.
@@ -27,9 +27,9 @@ import {
27
27
  export { GLYPHS, DIFF_TONES, SPINNER_FRAMES };
28
28
 
29
29
  /**
30
- * UI_TONES — the single chrome/color-token source for src/renderer and
30
+ * UI_TONES, the single chrome/color-token source for src/renderer and
31
31
  * src/panels. Concrete (dark-mode) values; resolveUiTones(mode) in theme.ts
32
- * is the single mode-resolved read path — this object is the 'dark' entry
32
+ * is the single mode-resolved read path, this object is the 'dark' entry
33
33
  * (== resolveTones('dark') from the SDK presentation contract).
34
34
  */
35
35
  export const UI_TONES = TONE_TOKENS;
@@ -215,7 +215,7 @@ export function createBootstrapCommandActions(
215
215
  const showPanel = (panelId: string, pane?: 'top' | 'bottom', target?: PanelDeepLinkTarget) => {
216
216
  // (the purge): a MIGRATE-TO-MODAL id resolves to a modal, not a panel.
217
217
  // panelManager.open() fires the injected openModal callback and returns a
218
- // no-op sentinel — so skip panelManager.show() (which would reveal an empty
218
+ // no-op sentinel, so skip panelManager.show() (which would reveal an empty
219
219
  // panel workspace behind the modal) when this id redirects. Keeps every
220
220
  // showPanel-based front-door (openHooksPanel/openSecurityPanel/… and the
221
221
  // migrated command runtimes) opening the modal cleanly.
@@ -272,7 +272,7 @@ export function createBootstrapCommandActions(
272
272
  // the preference. Every other route into this callback (model-only
273
273
  // commit, context-cap commit) carries a level merely carried over
274
274
  // from the previous model; storing that is what used to ratchet the
275
- // preference down for good — one hop through a model that caps at
275
+ // preference down for good, one hop through a model that caps at
276
276
  // 'medium' and 'xhigh' was gone from config, so hopping back could
277
277
  // not restore it.
278
278
  //
@@ -344,7 +344,7 @@ export function createBootstrapCommandActions(
344
344
  showPanel('memory');
345
345
  },
346
346
  // remote/subscription migrated to config-modal surfaces. open() hits
347
- // the modal redirect and invokes the openModal callback — do NOT go through
347
+ // the modal redirect and invokes the openModal callback, do NOT go through
348
348
  // showPanel here, which would additionally reveal + focus an (empty) panel
349
349
  // workspace behind the fullscreen modal.
350
350
  openRemotePanel: () => {
@@ -118,14 +118,14 @@ export interface BootstrapCoreState {
118
118
  readonly requestRender: () => void;
119
119
  readonly setRenderRequest: (fn: () => void) => void;
120
120
  readonly runtimeSessionIdRef: { value: string };
121
- /** Cross-surface identity mirror; dormant for local-only, and for the SDK's 'embedded' HostServiceMode, which no product-facing setting can select — this product only ever adopts an external daemon or runs local-only (see the ADOPT ONLY guard in bootstrap.ts) (docs/decisions/2026-07-06-session-spine-mode-branch-is-permanent.md). Activated by bootstrap.ts only for an adopted 'external' daemon. */
121
+ /** Cross-surface identity mirror; dormant for local-only, and for the SDK's 'embedded' HostServiceMode, which no product-facing setting can select, this product only ever adopts an external daemon or runs local-only (see the ADOPT ONLY guard in bootstrap.ts) (docs/decisions/2026-07-06-session-spine-mode-branch-is-permanent.md). Activated by bootstrap.ts only for an adopted 'external' daemon. */
122
122
  readonly sessionSpine: SessionSpineClient;
123
123
  /** Inbound steer/follow-up delivery; dormant until bootstrap.ts activates it. */
124
124
  readonly sessionInboundInputs: SessionInboundInputPoller;
125
- /** Cache-backed read facade; bootstrap.ts drives its mode (external/local-only in this product — 'embedded' is a HostServiceMode value with no product-facing setting to select it here) from the same HostServiceMode as the spine above. */
125
+ /** Cache-backed read facade; bootstrap.ts drives its mode (external/local-only in this product, 'embedded' is a HostServiceMode value with no product-facing setting to select it here) from the same HostServiceMode as the spine above. */
126
126
  readonly sessionUnionCache: SessionUnionCache;
127
127
  /**
128
- * WRFC chain persistence — call `rehydrate()` once after the SystemMessageRouter
128
+ * WRFC chain persistence, call `rehydrate()` once after the SystemMessageRouter
129
129
  * is wired so interrupted chains from a previous process are surfaced to the operator.
130
130
  */
131
131
  readonly wrfcPersistence: WrfcPersistence;
@@ -136,7 +136,7 @@ export type CompanionMessagePayload = Extract<SessionEvent, { type: 'COMPANION_M
136
136
  // --- Operator narration of inbound channel events ---
137
137
 
138
138
  /** Narrate an inbound channel event (GitHub, Slack, ntfy, etc.) that triggered an
139
- * agent turn, via the SystemMessageRouter — null for internal/companion sources. */
139
+ * agent turn, via the SystemMessageRouter, null for internal/companion sources. */
140
140
  export function narrateInboundEvent(event: {
141
141
  source: string;
142
142
  metadata: Readonly<Record<string, unknown>> | undefined;
@@ -144,7 +144,7 @@ export function narrateInboundEvent(event: {
144
144
  const { source, metadata } = event;
145
145
  if (!source) return null;
146
146
 
147
- // Derive the effective surface — prefer metadata.surface, fall back to source.
147
+ // Derive the effective surface, prefer metadata.surface, fall back to source.
148
148
  const surface = typeof metadata?.surface === 'string' ? metadata.surface : source;
149
149
 
150
150
  // Internal / companion sources do not need operator narration.
@@ -260,7 +260,7 @@ export async function initializeBootstrapCore(
260
260
  services.benchmarkStore.initBenchmarks();
261
261
  providerRegistry.initCatalog();
262
262
  // Wire cost-utils to the live catalog AND the ONE pricing resolver so every
263
- // cost surface distinguishes real pricing from unpriced and names its source ("your price" vs "catalog price, as of <date>") — see cost-utils.
263
+ // cost surface distinguishes real pricing from unpriced and names its source ("your price" vs "catalog price, as of <date>"), see cost-utils.
264
264
  wireCostPricing(providerRegistry);
265
265
  services.keybindingsManager.loadFromDisk();
266
266
  domainDispatch.syncControlPlaneState({
@@ -296,7 +296,7 @@ export async function initializeBootstrapCore(
296
296
  surfaceRegistry,
297
297
  watcherRegistry,
298
298
  } = services;
299
- // Dormant for local-only, and for the SDK's 'embedded' HostServiceMode — no product-facing
299
+ // Dormant for local-only, and for the SDK's 'embedded' HostServiceMode, no product-facing
300
300
  // setting can select it (SDK-internal embedder/test machinery); bootstrap.ts activates this spine only for an adopted 'external' daemon.
301
301
  const sessionSpine = new SessionSpineClient({ participant: TUI_SPINE_PARTICIPANT, recordKind: 'tui' });
302
302
  // Cache-backed read facade over the local broker (passthrough until bootstrap.ts
@@ -381,7 +381,7 @@ export async function initializeBootstrapCore(
381
381
  credentialEnvScrub: { allowlist: readExecEnvScrubAllowlist(configManager) },
382
382
  // Register context_accounting against OUR holder (the Orchestrator-backed source bound at bootstrap.ts). See runtime/context-accounting-source.ts.
383
383
  contextAccountingHolder: services.contextAccountingHolder,
384
- // First contained (sandboxed) command run announces "commands now run contained" once — recorded and surfaced now.
384
+ // First contained (sandboxed) command run announces "commands now run contained" once, recorded and surfaced now.
385
385
  onSandboxedRun: createSandboxContainmentNotice({ configManager, notify: (text) => conversation.log(`[Sandbox] ${text}`, { fg: '135' }) }),
386
386
  }); registerClientPhoneTool(toolRegistry, services.devices); // the `phone` tool follows the LOOP, so it is registered here; the posture runtime it used to call is the daemon's now and this tool reaches it over the devices.* verbs (see the SDK's client/phone-tool.ts)
387
387
  // Note: installWrfcAgentToolGuard is called after routeOrBuffer is defined (further below) so the onTrace callback routes guard decisions through the pre-router buffer.
@@ -426,7 +426,7 @@ export async function initializeBootstrapCore(
426
426
  await runBootMemoryFold(memoryStore, services.memoryEmbeddingRegistry, workingDir, logger);
427
427
 
428
428
  const renderRequestRef = { value: (): void => {} };
429
- // Coalescing render scheduler — collapses N requestRender() calls into 1 and
429
+ // Coalescing render scheduler, collapses N requestRender() calls into 1 and
430
430
  // enforces a 16ms minimum interval to cap repaints at ~60fps. renderScheduled stays
431
431
  // set for the ENTIRE window (until run() executes), so requestRender() calls arriving
432
432
  // on later event-loop ticks within the same 16ms window coalesce into the one
@@ -435,8 +435,8 @@ export async function initializeBootstrapCore(
435
435
  let renderScheduled = false;
436
436
  let lastRenderTime = 0;
437
437
  const RENDER_INTERVAL_MS = 16;
438
- // run() performs the actual render. It clears renderScheduled FIRST — even if the
439
- // render callback throws — otherwise a single render exception would wedge the entire
438
+ // run() performs the actual render. It clears renderScheduled FIRST, even if the
439
+ // render callback throws, otherwise a single render exception would wedge the entire
440
440
  // TUI (no future requestRender() would schedule anything); we log at error so the
441
441
  // next requestRender() can still reschedule.
442
442
  const run = (): void => {
@@ -449,7 +449,7 @@ export async function initializeBootstrapCore(
449
449
  }
450
450
  // Debounced spine heartbeat on turn/render activity (no-op while dormant, i.e. local-only, or
451
451
  // the SDK's 'embedded' mode, for which no product-facing setting exists): a cheap synchronous
452
- // no-op unless its own internal window has elapsed (at most one wire call per heartbeatMinIntervalMs) — safe on the hot path.
452
+ // no-op unless its own internal window has elapsed (at most one wire call per heartbeatMinIntervalMs), safe on the hot path.
453
453
  sessionSpine.heartbeat(runtimeSessionIdRef.value);
454
454
  };
455
455
  const requestRender = (): void => {
@@ -458,7 +458,7 @@ export async function initializeBootstrapCore(
458
458
  setImmediate(() => {
459
459
  const elapsed = Date.now() - lastRenderTime;
460
460
  if (elapsed < RENDER_INTERVAL_MS) {
461
- // Too soon — debounce to the tail of the current 16ms window. The flag
461
+ // Too soon, debounce to the tail of the current 16ms window. The flag
462
462
  // stays set until run() fires, so window-local requests coalesce here.
463
463
  setTimeout(run, RENDER_INTERVAL_MS - elapsed);
464
464
  } else {
@@ -470,7 +470,7 @@ export async function initializeBootstrapCore(
470
470
  // client approval raiser calls, so the UI layer patching this patches that.
471
471
  const permissionPromptRef = services.localPromptRef as { requestPermission: PermissionRequestHandler };
472
472
  // Trust-at-consequence-time: raised by trustGatedAsk on the first non-read
473
- // request in an undecided workspace; overridden once the UI layer exists — same ref-patching pattern as permissionPromptRef above.
473
+ // request in an undecided workspace; overridden once the UI layer exists, same ref-patching pattern as permissionPromptRef above.
474
474
  const trustPromptRef = { requestTrustDecision: (async () => 'restricted') as () => Promise<WorkspaceTrustLevel> };
475
475
  approvalBroker.start().catch((err) => logger.warn('approval broker start failed at bootstrap', { err }));
476
476
  sharedSessionBroker.start().catch((err) => logger.warn('shared session broker start failed at bootstrap', { err }));
@@ -539,7 +539,7 @@ export async function initializeBootstrapCore(
539
539
  }
540
540
  };
541
541
 
542
- // Startup TLS banner — emitted via wrfcBuffer.push() because the
542
+ // Startup TLS banner, emitted via wrfcBuffer.push() because the
543
543
  // SystemMessageRouter is not attached yet at this point in bootstrap. The
544
544
  // smart-ref setter on systemMessageRouterRef auto-flushes the buffer when
545
545
  // the router attaches, so the message will appear in the WRFC panel on startup.
@@ -616,7 +616,7 @@ export async function initializeBootstrapCore(
616
616
  getLastUserMessage: () => conversation.getLastUserMessage(),
617
617
  onTrace: ({ kind, reason, task }) => {
618
618
  const shortTask = task.length > 80 ? `${task.slice(0, 77)}...` : task;
619
- routeOrBuffer(`[WRFC] Guard: ${reason} — task: "${shortTask}" (${kind})`, 'low');
619
+ routeOrBuffer(`[WRFC] Guard: ${reason}; task: "${shortTask}" (${kind})`, 'low');
620
620
  },
621
621
  });
622
622
 
@@ -629,7 +629,7 @@ export async function initializeBootstrapCore(
629
629
  // which (a) adds the user message to the conversation view and (b) fires a real LLM
630
630
  // turn whose STREAM_DELTA / TURN_COMPLETED events flow to both TUI and companion SSE.
631
631
  //
632
- // The fallback (ref not yet set) adds the message to the conversation view only —
632
+ // The fallback (ref not yet set) adds the message to the conversation view only,
633
633
  // this path is unreachable in practice because the event bus is not connected to
634
634
  // any live HTTP traffic until after the orchestrator is wired in bootstrap.ts.
635
635
  const orchestratorHandleUserInputRef: {
@@ -661,7 +661,7 @@ export async function initializeBootstrapCore(
661
661
  },
662
662
  ));
663
663
 
664
- // Inbound steer delivery — see createBootstrapInboundInputPoller's doc comment.
664
+ // Inbound steer delivery, see createBootstrapInboundInputPoller's doc comment.
665
665
  const sessionInboundInputs = createBootstrapInboundInputPoller({
666
666
  runtimeSessionIdRef, routeOrBuffer, orchestratorHandleUserInputRef, conversation, requestRender,
667
667
  });
@@ -674,7 +674,7 @@ export async function initializeBootstrapCore(
674
674
  // webhook URL added mid-session reached long-task notifications (which read
675
675
  // ctx.services.webhookNotifier directly) but never reached this instance's
676
676
  // AGENT_FAILED/WORKFLOW_CHAIN_FAILED/WORKFLOW_CHAIN_PASSED runtime-bus
677
- // listeners until restart — and if the session started with zero URLs
677
+ // listeners until restart, and if the session started with zero URLs
678
678
  // configured, attachToRuntimeBus was never even called, so those listeners
679
679
  // never existed at all for the rest of the session. Always attaching
680
680
  // (regardless of initial URL count) and seeding the shared instance fixes
@@ -729,7 +729,7 @@ export async function initializeBootstrapCore(
729
729
  runtimeSessionIdRef.value = runtime.sessionId;
730
730
  services.liveSessionIdRef.value = runtime.sessionId; // the session an ask raised on the daemon belongs to
731
731
  // The live conversation, for this process's own /rewind AND for the daemon's
732
- // questions about it — only the process holding the messages can count or
732
+ // questions about it, only the process holding the messages can count or
733
733
  // drop them (conversation-rewind-port.ts, the SDK's client/conversation-rewind-host.ts).
734
734
  registerSessionConversation(runtime.sessionId, conversation);
735
735
  void sharedSessionBroker.createSession({
@@ -743,7 +743,7 @@ export async function initializeBootstrapCore(
743
743
  lastSeenAt: Date.now(),
744
744
  },
745
745
  }).catch((err) => { logger.debug('session broker create session failed at bootstrap', { err }); });
746
- // Fire-and-forget spine mirror — a permanent parallel-write posture alongside (never
746
+ // Fire-and-forget spine mirror, a permanent parallel-write posture alongside (never
747
747
  // instead of) the still-authoritative local SharedSessionBroker above. Dormant/queued
748
748
  // until bootstrap.ts's deferred task activates it for an adopted 'external' daemon.
749
749
  sessionSpine.register({ sessionId: runtime.sessionId, project: services.workingDirectory, title: 'Terminal UI session' });
@@ -25,14 +25,14 @@ export interface ResumeSessionOptions {
25
25
  readonly onSessionIdChanged?: (sessionId: string) => void;
26
26
  readonly sharedSessionBroker: Pick<SharedSessionBroker, 'reopenSession'>;
27
27
  /** Fire-and-forget daemon-spine mirror. Reopen (not register) is the
28
- * ONLY resume-time verb — see the SDK session-spine client.ts header doc. */
28
+ * ONLY resume-time verb, see the SDK session-spine client.ts header doc. */
29
29
  readonly sessionSpine: Pick<SessionSpineClient, 'reopen'>;
30
30
  readonly project: string;
31
31
  readonly writeLastSessionPointer: (sessionId: string) => void;
32
32
  readonly hookDispatcher: HookDispatcher;
33
33
  readonly sessionManager: SessionManager;
34
34
  readonly panelManager: PanelManager;
35
- /** The app's declare-once session-storage handle — the same one /session resume threads. */
35
+ /** The app's declare-once session-storage handle, the same one /session resume threads. */
36
36
  readonly surface: SessionSurface;
37
37
  /**
38
38
  * Multi-instance guard for this seam. Resolves false when the operator
@@ -47,7 +47,7 @@ export interface ResumeSessionOptions {
47
47
  /**
48
48
  * Reselects the resumed session's saved model through the live provider
49
49
  * registry (matches session-workflow.ts's `/session resume` reselection
50
- * fallback — see core/session-resume-core.ts). Optional so a caller without
50
+ * fallback, see core/session-resume-core.ts). Optional so a caller without
51
51
  * a provider API wired still gets the direct-assignment behavior this seam
52
52
  * always had.
53
53
  */
@@ -58,7 +58,7 @@ export interface ResumeSessionOptions {
58
58
  * Delegates the mechanical resume sequence to resumeSessionCore (the same
59
59
  * routine session-workflow.ts's `/session resume` calls) so the two seams
60
60
  * cannot diverge on restoreTurnAnchors, resetAll-before-fromJSON, model
61
- * reselection, or the modal-redirect panel-reopen skip — see
61
+ * reselection, or the modal-redirect panel-reopen skip, see
62
62
  * core/session-resume-core.ts's header doc for the full list of divergences
63
63
  * this closes. Everything below the resumeSessionCore call is plumbing only
64
64
  * this seam performs (hook fire, session-spine mirror, shared-broker
@@ -71,12 +71,12 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
71
71
  // for the text path: never fork a session another terminal is holding
72
72
  // open without the operator saying so.
73
73
  if (options.confirmLiveResume && !(await options.confirmLiveResume(sessionId))) {
74
- options.conversation.log('Resume cancelled — the session is still open in another terminal.', { fg: '244' });
74
+ options.conversation.log('Resume cancelled: the session is still open in another terminal.', { fg: '244' });
75
75
  options.requestRender();
76
76
  return;
77
77
  }
78
78
  // Pre-read purely for the emitSessionResumed announcement's turnCount,
79
- // which reports the raw saved-snapshot size — resumeSessionCore performs
79
+ // which reports the raw saved-snapshot size, resumeSessionCore performs
80
80
  // its own load() right after this (SessionManager.load is a cheap JSONL
81
81
  // parse; the tiny duplicate read keeps this announcement's meaning
82
82
  // unchanged rather than repurposing it to a post-replay count).
@@ -104,11 +104,11 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
104
104
  options.onSessionIdChanged?.(sessionId);
105
105
  options.writeLastSessionPointer(sessionId);
106
106
  void options.sharedSessionBroker.reopenSession(sessionId).catch((err) => { logger.debug('session broker reopen session failed', { err }); });
107
- // Fire-and-forget spine mirror (reopen:true — the user resume verb).
107
+ // Fire-and-forget spine mirror (reopen:true, the user resume verb).
108
108
  options.sessionSpine.reopen({ sessionId, project: options.project, title: options.conversation.title || meta.title });
109
109
  options.conversation.log(`Resumed session: ${sessionId}`, { fg: '135' });
110
110
  if (panels.movedToModal.length > 0) {
111
- options.conversation.log(`Resume: ${panels.movedToModal.join(', ')} moved to a modal — reopen via its command instead of as a panel.`, { fg: '244' });
111
+ options.conversation.log(`Resume: ${panels.movedToModal.join(', ')} moved to a modal; reopen via its command instead of as a panel.`, { fg: '244' });
112
112
  }
113
113
  if (panels.notReopened.length > 0) {
114
114
  options.conversation.log(`Resume: …and ${panels.notReopened.length} more not reopened (/panels to open)`, { fg: '244' });
@@ -96,7 +96,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
96
96
 
97
97
  // after any resume seam replays historical messages into `conversation`,
98
98
  // the freshly-constructed `orchestrator` still has its zeroed default usage
99
- // (SDK gap — Orchestrator.usage is never persisted/reseeded). Recompute it
99
+ // (SDK gap, Orchestrator.usage is never persisted/reseeded). Recompute it
100
100
  // from the replayed history so the footer doesn't show Input: 0 post-resume.
101
101
  const hydrateSessionUsage = (): void => {
102
102
  const { usage, lastInputTokens } = sumConversationUsage(conversation.getMessageSnapshot());
@@ -105,7 +105,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
105
105
  };
106
106
  // Built before resumeSession below so its providerApi.selectModel is
107
107
  // available for the resume handler's model-reselection step (matches
108
- // session-workflow.ts's /session resume — see core/session-resume-core.ts).
108
+ // session-workflow.ts's /session resume, see core/session-resume-core.ts).
109
109
  const foundationClients = createRuntimeFoundationClients({
110
110
  runtimeServices: services,
111
111
  tasksReadModel: uiServices.readModels.tasks,
@@ -156,7 +156,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
156
156
 
157
157
  // initial cost-budget alert threshold (USD; 0/unset = disabled).
158
158
  // Once the session starts, the real control surface is the CostTrackerPanel
159
- // itself — the in-panel 'b' key and /cost budget <usd> both call
159
+ // itself, the in-panel 'b' key and /cost budget <usd> both call
160
160
  // CostTrackerPanel.setBudgetThreshold() directly on the live panel instance,
161
161
  // which now writes through to the behavior.budgetAlertUsd config key
162
162
  // so the background budget-breach notifier reads the same value. The env
@@ -221,7 +221,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
221
221
  openPanel: (panelId: string) => { services.panelManager.open(panelId); },
222
222
  knowledgeApi,
223
223
  // Fleet acts (pick / conflict / discard) surface receipts through the command
224
- // context's print and reuse its one-key jump affordance — both late-bound
224
+ // context's print and reuse its one-key jump affordance, both late-bound
225
225
  // (the command context is assigned to commandContextRef after bootstrap, and
226
226
  // main.ts patches armFixSessionAttach onto it).
227
227
  fleetActsNotify: (message: string) => { commandContextRef?.print?.(message); requestRender(); },
@@ -239,7 +239,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
239
239
  },
240
240
  {
241
241
  // Suppress stale WRFC replay re-notifications for chains that can no
242
- // longer act — gone (killed/removed → getChain null) or terminal
242
+ // longer act, gone (killed/removed → getChain null) or terminal
243
243
  // (passed/failed). (item 1c.)
244
244
  isChainTerminal: (chainId) => {
245
245
  const chain = services.wrfcController.getChain(chainId);
@@ -286,7 +286,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
286
286
  workspaceTrustManager: services.workspaceTrustManager,
287
287
  // Registration half is stateless (reads the shared registry on demand), so
288
288
  // it is constructed here for the command context rather than threaded through
289
- // RuntimeServices — no early-load requirement like the trust gate has.
289
+ // RuntimeServices, no early-load requirement like the trust gate has.
290
290
  workspaceRegistrationManager: new WorkspaceRegistrationManager({ shellPaths: services.shellPaths }),
291
291
  memoryRegistry: services.memoryRegistry,
292
292
  integrationHelpers: services.integrationHelpers,
@@ -322,7 +322,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
322
322
  isPassiveCodeInjectionFlagEnabled: () => services.featureFlags.isEnabled('agent-passive-code-injection'),
323
323
  featureFlagManager: services.featureFlags,
324
324
  // Expose the MAIN session's per-turn passive-injection ring
325
- // so `/recall injections` (no agent id) renders it — see recall-review.ts.
325
+ // so `/recall injections` (no agent id) renders it, see recall-review.ts.
326
326
  getMainSessionTurnInjections: () => orchestrator.getTurnInjections(),
327
327
  changeTracker: services.sessionChangeTracker,
328
328
  planManager: services.planManager,
@@ -347,7 +347,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
347
347
  activatePlan: (_planId, task) => {
348
348
  setTimeout(() => {
349
349
  void (async () => {
350
- // Refresh the recall snapshot before this plan-driven turn — see
350
+ // Refresh the recall snapshot before this plan-driven turn, see
351
351
  // the matching comment in main.ts's submitInput.
352
352
  await refreshMemoryRecallSnapshot(services);
353
353
  orchestrator.handleUserInput(task).catch((err) => {
@@ -370,7 +370,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
370
370
  }).catch(() => { /* non-fatal */ });
371
371
  // FIX 2: the header's git segment otherwise only refreshes on
372
372
  // TURN_COMPLETED/TOOL_SUCCEEDED/TOOL_FAILED (see turn-event-wiring.ts's
373
- // refreshGit()) — if the user runs `git init` externally and never submits
373
+ // refreshGit()), if the user runs `git init` externally and never submits
374
374
  // another turn, the header stays stuck on the startup-time fallback
375
375
  // indefinitely. Poll at the same 5s cadence GitPanel already uses for its
376
376
  // own self-poll (git-panel.ts) so the two mechanisms are cadence-consistent.