@pellux/goodvibes-tui 1.16.1 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/CHANGELOG.md +89 -9
  2. package/README.md +1 -1
  3. package/docs/foundation-artifacts/operator-contract.json +1091 -271
  4. package/package.json +7 -7
  5. package/src/cli/completions/generate.ts +5 -4
  6. package/src/cli/config-overrides.ts +51 -11
  7. package/src/cli/doctor.ts +4 -5
  8. package/src/cli/entrypoint.ts +13 -8
  9. package/src/cli/help.ts +7 -6
  10. package/src/cli/launch-auto-update.ts +214 -0
  11. package/src/cli/parser.ts +5 -0
  12. package/src/cli/status.ts +13 -0
  13. package/src/cli/surface-command.ts +5 -5
  14. package/src/cli/tui-startup.ts +60 -97
  15. package/src/cli/types.ts +2 -0
  16. package/src/config/index.ts +1 -1
  17. package/src/config/tui-extension-settings.ts +33 -0
  18. package/src/core/composer-state.ts +1 -1
  19. package/src/core/conversation-line-cache.ts +3 -3
  20. package/src/core/conversation-rendering.ts +4 -4
  21. package/src/core/conversation.ts +2 -2
  22. package/src/core/long-task-notifier.ts +7 -7
  23. package/src/core/stream-event-wiring.ts +8 -6
  24. package/src/core/system-message-noise.ts +1 -1
  25. package/src/core/system-message-router.ts +6 -6
  26. package/src/core/turn-cancellation.ts +1 -1
  27. package/src/core/turn-event-wiring.ts +8 -8
  28. package/src/daemon/cli.ts +20 -5
  29. package/src/daemon/lifecycle.ts +41 -0
  30. package/src/daemon/service-commands.ts +5 -5
  31. package/src/export/cost-utils.ts +128 -6
  32. package/src/input/autocomplete.ts +2 -2
  33. package/src/input/command-registry.ts +34 -9
  34. package/src/input/commands/ci-runtime.ts +5 -1
  35. package/src/input/commands/codebase-runtime.ts +6 -6
  36. package/src/input/commands/cost-runtime.ts +1 -1
  37. package/src/input/commands/health-runtime.ts +2 -2
  38. package/src/input/commands/intelligence-runtime.ts +1 -1
  39. package/src/input/commands/local-auth-runtime.ts +1 -1
  40. package/src/input/commands/local-provider-runtime.ts +49 -10
  41. package/src/input/commands/local-runtime.ts +53 -5
  42. package/src/input/commands/memory.ts +2 -2
  43. package/src/input/commands/operator-panel-runtime.ts +5 -5
  44. package/src/input/commands/permissions-provenance.ts +1 -1
  45. package/src/input/commands/permissions-runtime.ts +99 -8
  46. package/src/input/commands/planning-runtime.ts +3 -3
  47. package/src/input/commands/platform-sandbox-runtime.ts +1 -1
  48. package/src/input/commands/provider-accounts-runtime.ts +71 -6
  49. package/src/input/commands/provider.ts +7 -5
  50. package/src/input/commands/recall-files-git.ts +13 -51
  51. package/src/input/commands/recall-files.ts +8 -11
  52. package/src/input/commands/recall-review.ts +2 -2
  53. package/src/input/commands/relay-runtime.ts +1 -1
  54. package/src/input/commands/remote-runtime.ts +1 -1
  55. package/src/input/commands/runtime-services.ts +4 -4
  56. package/src/input/commands/schedule-runtime.ts +14 -7
  57. package/src/input/commands/services-runtime.ts +1 -1
  58. package/src/input/commands/session-workflow.ts +2 -2
  59. package/src/input/commands/settings-sync-runtime.ts +2 -2
  60. package/src/input/commands/share-runtime.ts +1 -1
  61. package/src/input/commands/shell-core.ts +46 -68
  62. package/src/input/commands/subscription-runtime.ts +1 -1
  63. package/src/input/commands/update-runtime.ts +153 -96
  64. package/src/input/commands/work-plan-runtime.ts +1 -1
  65. package/src/input/commands/workstream-runtime.ts +2 -2
  66. package/src/input/commands.ts +0 -2
  67. package/src/input/config-modal-types.ts +3 -3
  68. package/src/input/config-modal.ts +10 -11
  69. package/src/input/feature-unit-layout.ts +93 -82
  70. package/src/input/feed-context-factory.ts +2 -2
  71. package/src/input/handler-command-route.ts +2 -2
  72. package/src/input/handler-content-actions.ts +1 -1
  73. package/src/input/handler-feed-routes.ts +7 -7
  74. package/src/input/handler-feed.ts +4 -4
  75. package/src/input/handler-interactions.ts +3 -2
  76. package/src/input/handler-modal-routes.ts +12 -4
  77. package/src/input/handler-modal-token-routes.ts +1 -1
  78. package/src/input/handler-onboarding-daemon-adopt.ts +2 -2
  79. package/src/input/handler-onboarding.ts +3 -2
  80. package/src/input/handler-picker-routes.ts +26 -13
  81. package/src/input/handler-shortcuts.ts +6 -6
  82. package/src/input/handler.ts +2 -2
  83. package/src/input/keybindings.ts +2 -2
  84. package/src/input/onboarding/onboarding-feature-units.ts +34 -27
  85. package/src/input/onboarding/onboarding-provider-key-fields.ts +112 -0
  86. package/src/input/onboarding/onboarding-wizard-apply.ts +22 -21
  87. package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +17 -0
  88. package/src/input/onboarding/onboarding-wizard-network-adopt.ts +2 -2
  89. package/src/input/onboarding/onboarding-wizard-steps.ts +30 -42
  90. package/src/input/panel-integration-actions.ts +2 -2
  91. package/src/input/panel-mouse-geometry.ts +1 -1
  92. package/src/input/panel-paste-flood-guard.ts +1 -1
  93. package/src/input/provider-key-intake.ts +167 -0
  94. package/src/input/sandbox-exec-config.ts +2 -2
  95. package/src/input/selection-modal.ts +1 -1
  96. package/src/input/settings-modal-activation.ts +5 -0
  97. package/src/input/settings-modal-adjustment.ts +4 -31
  98. package/src/input/settings-modal-data.ts +22 -21
  99. package/src/input/settings-modal-mutations.ts +12 -68
  100. package/src/input/settings-modal-types.ts +23 -16
  101. package/src/input/settings-modal.ts +74 -55
  102. package/src/main.ts +48 -48
  103. package/src/panels/agent-inspector-shared.ts +4 -4
  104. package/src/panels/base-panel.ts +2 -2
  105. package/src/panels/builtin/agent.ts +4 -4
  106. package/src/panels/builtin/development.ts +4 -4
  107. package/src/panels/builtin/knowledge.ts +1 -1
  108. package/src/panels/builtin/operations.ts +29 -10
  109. package/src/panels/builtin/session.ts +5 -5
  110. package/src/panels/builtin/shared.ts +4 -4
  111. package/src/panels/builtin-modals.ts +10 -10
  112. package/src/panels/builtin-panels.ts +1 -1
  113. package/src/panels/cost-tracker-panel.ts +124 -7
  114. package/src/panels/diff-panel.ts +5 -5
  115. package/src/panels/eval-registry.ts +2 -2
  116. package/src/panels/fleet-deep-link.ts +1 -1
  117. package/src/panels/fleet-panel-format.ts +44 -8
  118. package/src/panels/fleet-panel.ts +16 -16
  119. package/src/panels/fleet-read-model.ts +52 -13
  120. package/src/panels/fleet-steer.ts +2 -2
  121. package/src/panels/fleet-stop.ts +3 -3
  122. package/src/panels/fleet-tabs.ts +13 -14
  123. package/src/panels/fleet-transcript.ts +5 -5
  124. package/src/panels/git-panel.ts +2 -2
  125. package/src/panels/index.ts +4 -1
  126. package/src/panels/local-auth-panel.ts +1 -1
  127. package/src/panels/modals/hooks-modal.ts +1 -1
  128. package/src/panels/modals/keybindings-modal.ts +2 -2
  129. package/src/panels/modals/knowledge-modal.ts +1 -1
  130. package/src/panels/modals/marketplace-modal.ts +4 -4
  131. package/src/panels/modals/memory-modal.ts +4 -4
  132. package/src/panels/modals/modal-surface-helpers.ts +1 -1
  133. package/src/panels/modals/modal-theme.ts +1 -1
  134. package/src/panels/modals/pairing-modal.ts +2 -2
  135. package/src/panels/modals/planning-modal.ts +2 -2
  136. package/src/panels/modals/plugins-modal.ts +1 -1
  137. package/src/panels/modals/policy-modal.ts +1 -1
  138. package/src/panels/modals/security-modal.ts +1 -1
  139. package/src/panels/modals/skills-modal.ts +1 -1
  140. package/src/panels/modals/work-plan-modal.ts +3 -3
  141. package/src/panels/notifications-feed.ts +127 -0
  142. package/src/panels/notifications-panel.ts +160 -0
  143. package/src/panels/panel-manager.ts +9 -9
  144. package/src/panels/plugins-panel.ts +4 -4
  145. package/src/panels/project-planning-answer-actions.ts +1 -1
  146. package/src/panels/provider-health-routes.ts +2 -2
  147. package/src/panels/skills-panel.ts +4 -5
  148. package/src/panels/token-budget-panel.ts +11 -3
  149. package/src/panels/types.ts +5 -5
  150. package/src/permissions/broker-approval-card.ts +201 -0
  151. package/src/permissions/hunk-selection.ts +28 -4
  152. package/src/permissions/prompt.ts +244 -29
  153. package/src/renderer/autocomplete-overlay.ts +107 -54
  154. package/src/renderer/code-block.ts +2 -2
  155. package/src/renderer/compaction-history-modal.ts +1 -1
  156. package/src/renderer/compaction-preview.ts +1 -1
  157. package/src/renderer/compaction-quality.ts +1 -1
  158. package/src/renderer/compositor.ts +2 -2
  159. package/src/renderer/config-modal.ts +1 -1
  160. package/src/renderer/conversation-overlays.ts +1 -1
  161. package/src/renderer/footer-tips.ts +3 -3
  162. package/src/renderer/hint-grammar.ts +1 -1
  163. package/src/renderer/modal-factory.ts +1 -1
  164. package/src/renderer/model-picker-overlay.ts +1 -1
  165. package/src/renderer/model-workspace.ts +7 -2
  166. package/src/renderer/panel-composite.ts +2 -2
  167. package/src/renderer/panel-workspace-bar.ts +1 -1
  168. package/src/renderer/process-indicator.ts +1 -1
  169. package/src/renderer/selection-modal-overlay.ts +1 -1
  170. package/src/renderer/session-picker-modal.ts +2 -2
  171. package/src/renderer/settings-modal-helpers.ts +14 -5
  172. package/src/renderer/settings-modal.ts +127 -39
  173. package/src/renderer/shell-surface.ts +3 -0
  174. package/src/renderer/terminal-bg-probe.ts +1 -1
  175. package/src/renderer/theme.ts +3 -3
  176. package/src/renderer/tool-call.ts +1 -1
  177. package/src/renderer/tool-result-summary.ts +1 -1
  178. package/src/renderer/turn-injection.ts +7 -6
  179. package/src/renderer/ui-factory.ts +6 -1
  180. package/src/runtime/bootstrap-command-context.ts +4 -1
  181. package/src/runtime/bootstrap-command-parts.ts +6 -4
  182. package/src/runtime/bootstrap-core.ts +35 -35
  183. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  184. package/src/runtime/bootstrap-shell.ts +6 -5
  185. package/src/runtime/bootstrap.ts +34 -32
  186. package/src/runtime/channel-composition.ts +46 -0
  187. package/src/runtime/code-index-services.ts +3 -4
  188. package/src/runtime/daemon-attach-notices.ts +120 -0
  189. package/src/runtime/durability-services.ts +55 -0
  190. package/src/runtime/embedded-service-factories.ts +40 -0
  191. package/src/runtime/feature-settings.ts +147 -0
  192. package/src/runtime/index.ts +4 -21
  193. package/src/runtime/legacy-daemon-migration.ts +29 -19
  194. package/src/runtime/memory-fold.ts +1 -1
  195. package/src/runtime/notification-dispatch.ts +110 -0
  196. package/src/runtime/onboarding/apply.ts +3 -29
  197. package/src/runtime/onboarding/fast-path.ts +39 -6
  198. package/src/runtime/onboarding/provider-key-capture.ts +126 -0
  199. package/src/runtime/onboarding/snapshot.ts +0 -1
  200. package/src/runtime/onboarding/types.ts +9 -3
  201. package/src/runtime/provider-fallback.ts +55 -0
  202. package/src/runtime/provider-optimizer-wiring.ts +55 -0
  203. package/src/runtime/release-artifacts.ts +19 -103
  204. package/src/runtime/resume-notice.ts +1 -1
  205. package/src/runtime/services.ts +81 -82
  206. package/src/runtime/session-continuity-hints.ts +38 -0
  207. package/src/runtime/surface-feature-flags.ts +40 -9
  208. package/src/runtime/terminal-output-guard.ts +2 -2
  209. package/src/runtime/trust/workspace-registration.ts +10 -2
  210. package/src/runtime/trust/workspace-trust.ts +58 -31
  211. package/src/runtime/ui-services.ts +3 -1
  212. package/src/runtime/update-check.ts +15 -69
  213. package/src/runtime/workstream-services.ts +2 -2
  214. package/src/shell/blocking-input.ts +102 -6
  215. package/src/shell/ui-openers.ts +38 -6
  216. package/src/utils/format-duration.ts +1 -1
  217. package/src/verification/verification-ledger.ts +21 -4
  218. package/src/version.ts +1 -1
  219. package/src/input/commands/flags-runtime.ts +0 -328
@@ -1,25 +1,25 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
2
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
3
3
 
4
- // W6.1 (the purge): thinking, tools, inspector, and wrfc were registered here
4
+ // (the purge): thinking, tools, inspector, and wrfc were registered here
5
5
  // before the purge. thinking/tools were DELETE-disposition (no surviving
6
6
  // human surface — thinking already renders inline in the transcript, tool
7
7
  // results render inline plus per-node in Fleet); inspector/wrfc were
8
8
  // RETIRE-INTO-FLEET (their live console is subsumed by the Fleet panel,
9
9
  // operations.ts:84). See registerOperationsPanels for the fleet
10
- // registration and .goodvibes/audit/2026-07-04-wave6-briefs.json (W6.1) for
10
+ // registration and .goodvibes/audit/2026-07-04-wave6-briefs.json for
11
11
  // the full disposition map.
12
12
  export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
13
13
  // Compat: '/panel open agent-logs' and 'inspector' (and any saved
14
14
  // layout/muscle memory) still resolve — redirected straight to fleet.
15
- // Repointed from agent-logs->inspector (WO-110) now that inspector itself
15
+ // Repointed from agent-logs->inspector now that inspector itself
16
16
  // is retired; alias resolution is a single hop (PanelManager._resolveId),
17
17
  // so this must point at the real surviving id, not at another alias.
18
18
  manager.registerAlias('agent-logs', 'fleet');
19
19
  manager.registerAlias('inspector', 'fleet');
20
20
  manager.registerAlias('wrfc', 'fleet');
21
21
 
22
- // W6.1 (the purge) — group B (WO-P): 'work-plan' and 'project-planning'
22
+ // (the purge) — group B: 'work-plan' and 'project-planning'
23
23
  // migrated to the 'work-plan-modal' / 'planning-modal' config-modal surfaces.
24
24
  // Their surfaces AND panel→modal redirects are registered centrally in
25
25
  // registerBuiltinModals (builtin-modals.ts). Panel registrations retired here.
@@ -6,14 +6,14 @@ import { CostTrackerPanel } from '../cost-tracker-panel.ts';
6
6
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
7
7
  import { requireUiServices, withUnconfiguredFallback } from './shared.ts';
8
8
 
9
- // W6.1 (the purge): plan, intelligence, explorer, preview, and symbols were
9
+ // (the purge): plan, intelligence, explorer, preview, and symbols were
10
10
  // registered here before the purge. plan was RETIRE-INTO-FLEET (its
11
11
  // execution-plan view is subsumed by Fleet — operations.ts:84); the other
12
12
  // four were DELETE-disposition (no surviving human surface — intelligence's
13
13
  // read-model still backs the surviving `/intelligence` CLI subcommands, see
14
14
  // intelligence-runtime.ts; explorer/preview/symbols had no dedicated
15
15
  // read-model to preserve). See .goodvibes/audit/2026-07-04-wave6-briefs.json
16
- // (W6.1) for the full disposition map.
16
+ // for the full disposition map.
17
17
  export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
18
18
  manager.registerType({
19
19
  id: 'git',
@@ -56,10 +56,10 @@ export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedB
56
56
  ),
57
57
  });
58
58
 
59
- // WO-110: 'inspector' registration moved to builtin/agent.ts (category
59
+ // 'inspector' registration moved to builtin/agent.ts (category
60
60
  // 'agent') — it now absorbs the merged agent-logs capabilities.
61
61
 
62
- // WO-152: always registered (was gated behind `if (deps.getOrchestratorUsage)`,
62
+ // always registered (was gated behind `if (deps.getOrchestratorUsage)`,
63
63
  // so `/panel open cost` reported "Unknown panel" on builds without usage
64
64
  // tracking wired). Falls back to a "dependency not configured" empty state.
65
65
  {
@@ -1,7 +1,7 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
2
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
3
3
 
4
- // W6.1 (the purge) — group B: 'knowledge' and 'memory' migrated to the
4
+ // (the purge) — group B: 'knowledge' and 'memory' migrated to the
5
5
  // 'knowledge-modal' / 'memory-modal' config-modal surfaces. Both surfaces and
6
6
  // their panel→modal redirects are registered centrally in registerBuiltinModals
7
7
  // (src/panels/builtin-modals.ts). This registrar is intentionally empty
@@ -2,39 +2,40 @@ import type { PanelManager } from '../panel-manager.ts';
2
2
  import { FleetPanel } from '../fleet-panel.ts';
3
3
  import { createFleetReadModel } from '../fleet-read-model.ts';
4
4
  import { LocalAuthPanel } from '../local-auth-panel.ts';
5
+ import { NotificationsPanel } from '../notifications-panel.ts';
5
6
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
6
7
  import { requireUiServices } from './shared.ts';
7
8
 
8
- // WO-152: the former single 'monitoring' category (33 panels pre-merge) is
9
+ // the former single 'monitoring' category (33 panels pre-merge) is
9
10
  // split into five operator domains, applied per-registration below. Kept in
10
11
  // this file's original registration order (rather than physically regrouped
11
12
  // by category) because several registrations below close over shared local
12
13
  // state — `ui` — defined once near the top of this function.
13
14
  //
14
- // W6.1 (the purge): cockpit, approval, automation, routes, control-plane,
15
+ // (the purge): cockpit, approval, automation, routes, control-plane,
15
16
  // worktrees, tasks, orchestration, ops, ops-control, and communication were
16
17
  // RETIRE-INTO-FLEET (their live views are subsumed by the Fleet panel below
17
18
  // — each id now redirects there via registerAlias); debug and eval were
18
19
  // DELETE-disposition (no surviving human surface). See
19
- // .goodvibes/audit/2026-07-04-wave6-briefs.json (W6.1) for the full
20
+ // .goodvibes/audit/2026-07-04-wave6-briefs.json for the full
20
21
  // disposition map. The rosterReadModel/agent-lifecycle wiring that used to
21
22
  // feed CockpitPanel exclusively was removed along with it — Fleet reads the
22
23
  // process registry directly via fleetReadModel below, not via the roster
23
24
  // read-model.
24
25
  //
25
- // W6.1 MIGRATE-TO-MODAL: the Providers & Connectivity group (services,
26
+ // MIGRATE-TO-MODAL: the Providers & Connectivity group (services,
26
27
  // subscription, remote, provider-health) and Security group (settings-sync,
27
28
  // sandbox) migrated to config-modal surfaces registered in builtin-modals.ts
28
- // (WO-A); the Ecosystem & Governance group (plugins, skills, hooks, security,
29
+ //; the Ecosystem & Governance group (plugins, skills, hooks, security,
29
30
  // marketplace, policy, knowledge, memory, docs, qr-code, work-plan,
30
- // project-planning) migrated to config-modal surfaces (WO-P). All surfaces AND
31
+ // project-planning) migrated to config-modal surfaces. All surfaces AND
31
32
  // their panel-id redirects are registered centrally in registerBuiltinModals
32
33
  // (builtin-modals.ts) now — the interim ecosystem redirect bridge was deleted
33
34
  // with the group-B port. local-auth is a DELIBERATE EXCEPTION — see below.
34
35
  export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
35
36
  const ui = requireUiServices(deps);
36
37
 
37
- // W2.2: Fleet — the live unified process tree, read from the single
38
+ // Fleet — the live unified process tree, read from the single
38
39
  // process registry constructed once in runtime/services.ts (shared with
39
40
  // every other consumer rather than duplicated here; the registry owns its
40
41
  // own coalesced tick, so no manual lifecycle-event wiring is needed).
@@ -45,7 +46,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
45
46
  manager.registerType({
46
47
  id: 'fleet',
47
48
  name: 'Fleet',
48
- // W2.2: '⊟' verified free against the full icon registry at wiring time.
49
+ // '⊟' verified free against the full icon registry at wiring time.
49
50
  icon: '⊟',
50
51
  category: 'runtime-ops',
51
52
  description: 'Live unified process tree: agents, WRFC chains, workflows, watchers, and background processes, with interrupt/kill/steer controls',
@@ -82,11 +83,29 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
82
83
  manager.registerAlias('communication', 'fleet');
83
84
  manager.registerAlias('incident', 'fleet');
84
85
  // Re-pointed: forensics used to resolve to the (now-retired) incident
85
- // workspace (WO-114); both ids now land on fleet directly — alias
86
+ // workspace; both ids now land on fleet directly — alias
86
87
  // resolution is a single hop, so this cannot chain through 'incident'.
87
88
  manager.registerAlias('forensics', 'fleet');
88
89
 
89
- // local-auth is a DELIBERATE EXCEPTION to the W6.1 purge: it stays a
90
+ // Notifications — the visible home for the panel_only notification
91
+ // target: anything a NotificationRouter (SDK) routes there (including
92
+ // burst/batch-collapsed groups, shown with their real running count)
93
+ // renders here instead of having nowhere to go. See notifications-feed.ts
94
+ // for why this exists. Not preloaded (only 'tokens' preloads, per the
95
+ // panel-consolidation cleanup below) — the shared feed singleton
96
+ // accumulates independently of whether this view has been opened yet, so
97
+ // nothing is lost by instantiating it lazily on first open like every
98
+ // other panel here.
99
+ manager.registerType({
100
+ id: 'notifications',
101
+ name: 'Notifications',
102
+ icon: 'N',
103
+ category: 'runtime-ops',
104
+ description: 'Notifications routed to the panel-only target (quiet/balanced-mode operational chatter, burst- and batch-collapsed groups) with their real collapsed counts',
105
+ factory: () => new NotificationsPanel(),
106
+ });
107
+
108
+ // local-auth is a DELIBERATE EXCEPTION to the purge: it stays a
90
109
  // registered panel because it is the host for the masked password-entry
91
110
  // sub-mode (LocalAuthPanel.openMaskedEntry, driven by
92
111
  // ctx.openLocalAuthMaskedEntry — the only path that keeps a plaintext
@@ -3,7 +3,7 @@ import { TokenBudgetPanel } from '../token-budget-panel.ts';
3
3
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
4
4
  import { requireUiServices } from './shared.ts';
5
5
 
6
- // W6.1 (the purge): panel-list and system-messages were registered here
6
+ // (the purge): panel-list and system-messages were registered here
7
7
  // before the purge — both DELETE-disposition. panel-list was a picker over a
8
8
  // handful of panels (dead weight now that the registry is much smaller —
9
9
  // the picker itself is replaced by a live-registry selection modal on
@@ -14,7 +14,7 @@ import { requireUiServices } from './shared.ts';
14
14
  // conversation.addTypedSystemMessage for every kind/target combination — see
15
15
  // bootstrap-shell.ts and core/system-message-router.ts.
16
16
  //
17
- // W6.1 (the purge) — group B (WO-P): 'qr-code', 'sessions', and 'docs' also
17
+ // (the purge) — group B: 'qr-code', 'sessions', and 'docs' also
18
18
  // migrated. 'qr-code' → the 'pairing-modal' surface; 'docs' → the
19
19
  // 'keybindings-modal' surface (merged with the shortcuts-overlay content);
20
20
  // 'sessions' folds into the existing session-picker modal ('sessions' redirects
@@ -25,7 +25,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
25
25
  manager.registerType({
26
26
  id: 'tokens',
27
27
  name: 'Tokens',
28
- // WO-152: registry previously said 'K' while the live panel's own
28
+ // registry previously said 'K' while the live panel's own
29
29
  // super() call used 'T' — a pre-existing registry/instance mismatch as
30
30
  // well as a collision ('K' with knowledge/skills, 'T' with thinking).
31
31
  // Unified to a single unique glyph in both places.
@@ -35,7 +35,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
35
35
  // Preloaded (absorbed from the retired ContextVisualizerPanel) so turn
36
36
  // history and pressure accumulate in the background even before the user
37
37
  // opens the tab. The only builtin panel that still preloads post-purge
38
- // (W6.1) — see registerBuiltinPanels callers for the others' preload
38
+ // — see registerBuiltinPanels callers for the others' preload
39
39
  // removal.
40
40
  preload: true,
41
41
  retainOnClose: true,
@@ -58,7 +58,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
58
58
  },
59
59
  });
60
60
 
61
- // WO-113 compat: the retired 'context' panel id still resolves — redirected
61
+ // compat: the retired 'context' panel id still resolves — redirected
62
62
  // to the merged tokens console ('/panel open context', saved layouts).
63
63
  manager.registerAlias('context', 'tokens');
64
64
  }
@@ -55,7 +55,7 @@ export interface BuiltinPanelDeps {
55
55
  subscriptionManager?: SubscriptionManager;
56
56
  /** Shared service registry for services-backed panels. */
57
57
  serviceRegistry?: ServiceRegistry;
58
- /** Context window size in tokens. Unused since WO-113 folded ContextVisualizerPanel into TokenBudgetPanel (which reads getCtxWindow instead); kept for source compatibility. */
58
+ /** Context window size in tokens. Unused since folded ContextVisualizerPanel into TokenBudgetPanel (which reads getCtxWindow instead); kept for source compatibility. */
59
59
  contextWindow?: number;
60
60
  /** Main Orchestrator instance for TokenBudgetPanel.wire(). */
61
61
  orchestrator?: Orchestrator;
@@ -72,7 +72,7 @@ export interface BuiltinPanelDeps {
72
72
  /** ForensicsRegistry for the Forensics panel. */
73
73
  forensicsRegistry?: import('@/runtime/index.ts').ForensicsRegistry;
74
74
  /**
75
- * EvalRegistry for the `/eval` command surface. W6.1: 'eval' the panel was
75
+ * EvalRegistry for the `/eval` command surface.: 'eval' the panel was
76
76
  * deleted (DELETE-disposition), but this field is left in place — no
77
77
  * builtin panel factory reads it anymore, and it was never wired at
78
78
  * bootstrap in production either way (the eval CLI command reads its own
@@ -123,7 +123,7 @@ export interface BuiltinPanelDeps {
123
123
  workPlanStore?: import('../../work-plans/work-plan-store.ts').WorkPlanStore;
124
124
  /** Explicit UI-facing runtime services for agent/process/WRFC/remote panels and modals. */
125
125
  uiServices?: UiRuntimeServices;
126
- /** Shared plugin manager for plugin and security panels (widened past the read-only observer surface — WO-134 — so PluginsPanel can drive enable/disable/verify/lift-quarantine). */
126
+ /** Shared plugin manager for plugin and security panels (widened past the read-only observer surface — — so PluginsPanel can drive enable/disable/verify/lift-quarantine). */
127
127
  pluginManager?: PluginManagerControls;
128
128
  /** Shared hook dispatcher for the hooks control-room panel. */
129
129
  hookDispatcher?: Pick<HookDispatcher, 'listHooks' | 'getChains'>;
@@ -287,7 +287,7 @@ export function requireKnowledgeApi(deps: BuiltinPanelDeps): KnowledgeApi {
287
287
  }
288
288
 
289
289
  // ---------------------------------------------------------------------------
290
- // WO-152: always-register conditional panels with a "dependency not
290
+ // always-register conditional panels with a "dependency not
291
291
  // configured" empty state instead of skipping registration entirely.
292
292
  // ---------------------------------------------------------------------------
293
293
 
@@ -7,7 +7,7 @@ import { createProviderRuntimeInspectionQuery } from '../runtime/ui-service-quer
7
7
  import { createRuntimeProviderApi } from '@/runtime/index.ts';
8
8
  import { copyToClipboard } from '../utils/clipboard.ts';
9
9
  import { getOrCreateCompanionToken, buildCompanionConnectionInfo } from '@pellux/goodvibes-sdk/platform/pairing';
10
- // ── Group A: Providers & Connectivity + Security subset (WO-A) ───────────────
10
+ // ── Providers & Connectivity + Security subset ────────────────────────────────
11
11
  import { createServicesModalSurface } from './modals/services-modal.ts';
12
12
  import { createSubscriptionModalSurface } from './modals/subscription-modal.ts';
13
13
  import { createRemoteModalSurface } from './modals/remote-modal.ts';
@@ -15,7 +15,7 @@ import { createSettingsSyncModalSurface } from './modals/settings-sync-modal.ts'
15
15
  import { createProviderHealthModalSurface } from './modals/provider-health-modal.ts';
16
16
  import { createLocalAuthModalSurface } from './modals/local-auth-modal.ts';
17
17
  import { createSandboxModalSurface } from './modals/sandbox-modal.ts';
18
- // ── Group B: Ecosystem & Governance (WO-P, this work order) ──────────────────
18
+ // ── Ecosystem & Governance ─────────────────────────────────────────────────
19
19
  import { createMarketplaceModalSurface } from './modals/marketplace-modal.ts';
20
20
  import { createPluginsModalSurface } from './modals/plugins-modal.ts';
21
21
  import { createSkillsModalSurface } from './modals/skills-modal.ts';
@@ -30,22 +30,22 @@ import { createPairingModalSurface, type PairingModalConnectionInfo } from './mo
30
30
  import { createPlanningModalSurface } from './modals/planning-modal.ts';
31
31
 
32
32
  /**
33
- * Register the config-modal surfaces + their panel-id redirects (W6.1, the
34
- * purge). Called once at startup from registerBuiltinPanels, AFTER the panels'
33
+ * Register the config-modal surfaces + their panel-id redirects, from a prior
34
+ * panel-consolidation cleanup. Called once at startup from registerBuiltinPanels, AFTER the panels'
35
35
  * deps are resolved (the surfaces close over the same read-models the retired
36
- * panels used). For each MIGRATE-TO-MODAL surface this does two things:
36
+ * panels used). For each surface migrated from a standalone panel this does two things:
37
37
  * 1. registerModalSurface — the data + actions the config-modal host renders.
38
38
  * 2. registerModalRedirect — so `/panel open <old-id>`, saved layouts, and any
39
39
  * alias still resolve to the modal.
40
40
  *
41
- * Group A (WO-A) is the Providers & Connectivity + Security subset. Group B
42
- * (WO-P) is the Ecosystem & Governance set — the 12 ported config-modal
41
+ * The Providers & Connectivity + Security subset is registered first, followed by the
42
+ * Ecosystem & Governance set — the 12 ported config-modal
43
43
  * surfaces plus the `sessions` fold into the existing session-picker modal.
44
44
  */
45
45
  export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
46
46
  const ui = requireUiServices(deps);
47
47
 
48
- // ── Providers & Connectivity (WO-A) ─────────────────────────────────────────
48
+ // ── Providers & Connectivity ─────────────────────────────────────────────────
49
49
  manager.registerModalSurface(createServicesModalSurface(deps.serviceRegistry, deps.subscriptionManager));
50
50
  manager.registerModalRedirect('services', 'services-modal');
51
51
 
@@ -65,7 +65,7 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
65
65
  manager.registerModalRedirect('providers', 'providers-modal');
66
66
  manager.registerModalRedirect('accounts', 'providers-modal');
67
67
 
68
- // ── Security & Governance (WO-A subset) ─────────────────────────────────────
68
+ // ── Security & Governance ────────────────────────────────────────────────────
69
69
  manager.registerModalSurface(createSettingsSyncModalSurface(deps.configManager));
70
70
  manager.registerModalRedirect('settings-sync', 'settings-sync-modal');
71
71
 
@@ -77,7 +77,7 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
77
77
  manager.registerModalSurface(createSandboxModalSurface(deps.configManager, deps.sandboxSessionRegistry, deps.requestRender));
78
78
  manager.registerModalRedirect('sandbox', 'sandbox-modal');
79
79
 
80
- // ── Ecosystem & Governance (WO-P — group B) ─────────────────────────────────
80
+ // ── Ecosystem & Governance ───────────────────────────────────────────────────
81
81
  manager.registerModalSurface(createMarketplaceModalSurface({
82
82
  readModel: ui.readModels.marketplace,
83
83
  ecosystemPaths: {
@@ -19,7 +19,7 @@ export function registerBuiltinPanels(manager: PanelManager, deps: BuiltinPanelD
19
19
  registerAgentPanels(manager, resolved);
20
20
  registerSessionPanels(manager, resolved);
21
21
  registerKnowledgePanels(manager, resolved);
22
- // W6.1 (the purge): register MIGRATE-TO-MODAL surfaces + their panel-id
22
+ // (the purge): register MIGRATE-TO-MODAL surfaces + their panel-id
23
23
  // redirects. Must run after the panel registrations so a redirected id wins
24
24
  // over any lingering panel registration in open().
25
25
  registerBuiltinModals(manager, resolved);
@@ -22,15 +22,15 @@ import {
22
22
  DEFAULT_PANEL_PALETTE,
23
23
  type PanelWorkspaceSection,
24
24
  } from './polish.ts';
25
- import { calcSessionCost, isModelPriced, computeBudgetBreach, readBudgetAlertUsd, BUDGET_ALERT_USD_CONFIG_KEY, type BudgetAlertConfigAccess } from '../export/cost-utils.ts';
25
+ import { calcSessionCost, describePricingSource, isModelPriced, computeBudgetBreach, readBudgetAlertUsd, writeManualModelPrice, BUDGET_ALERT_USD_CONFIG_KEY, type BudgetAlertConfigAccess } from '../export/cost-utils.ts';
26
26
  import { abbreviateCount } from '../utils/format-number.ts';
27
27
  import { isTextBackspace } from '../input/delete-key-policy.ts';
28
28
 
29
29
  // Pricing lookups are provided by ../export/cost-utils.ts (single source of truth).
30
30
 
31
- /** unpriced=true renders an honest "unpriced" marker instead of a $0.00 that could be mistaken for a real zero cost. */
31
+ /** unpriced=true renders the explicit "price unknown" marker instead of a $0.00 that could be mistaken for a real zero cost. */
32
32
  function formatCost(usd: number, unpriced = false): string {
33
- if (unpriced) return 'unpriced';
33
+ if (unpriced) return 'price unknown';
34
34
  if (usd === 0) return '$0.00';
35
35
  if (usd < 0.0001) return '<$0.0001';
36
36
  if (usd < 0.01) return `$${usd.toFixed(4)}`;
@@ -127,6 +127,12 @@ export class CostTrackerPanel extends BasePanel {
127
127
  // secret so it is echoed directly.
128
128
  private budgetEntry: string | null = null;
129
129
 
130
+ // Draft buffer for the in-panel manual-price entry mode ('p' key): the one
131
+ // action away from any price display (and from the "price unknown" marker).
132
+ // Format: "input,output" in USD per 1M tokens; persists to the
133
+ // pricing.modelPrices settings key live on Enter.
134
+ private priceEntry: string | null = null;
135
+
130
136
  // Scroll offset for agent list
131
137
  private scrollOffset = 0;
132
138
 
@@ -347,11 +353,12 @@ export class CostTrackerPanel extends BasePanel {
347
353
  * `Panel.isCapturingTextBurst`.
348
354
  */
349
355
  isCapturingTextBurst(): boolean {
350
- return this.budgetEntry !== null;
356
+ return this.budgetEntry !== null || this.priceEntry !== null;
351
357
  }
352
358
 
353
359
  handleInput(key: string): boolean {
354
360
  if (this.budgetEntry !== null) return this.handleBudgetEntryInput(key);
361
+ if (this.priceEntry !== null) return this.handlePriceEntryInput(key);
355
362
 
356
363
  if (key === 'b') {
357
364
  const threshold = this.currentBudgetThreshold();
@@ -360,6 +367,16 @@ export class CostTrackerPanel extends BasePanel {
360
367
  return true;
361
368
  }
362
369
 
370
+ if (key === 'p') {
371
+ // One action from any price display: edit the manual price for the
372
+ // session's provider:model. Needs a wired config (production path) —
373
+ // without one the key falls through rather than opening a dead editor.
374
+ if (!this.configAccess) return false;
375
+ this.priceEntry = '';
376
+ this.markDirty();
377
+ return true;
378
+ }
379
+
363
380
  switch (key) {
364
381
  case 'up': return this.scroll(-1);
365
382
  case 'down': return this.scroll(1);
@@ -402,6 +419,52 @@ export class CostTrackerPanel extends BasePanel {
402
419
  return true; // absorb everything else while entry is active
403
420
  }
404
421
 
422
+ /** True when the session model can carry a manual price (pricing.modelPrices keys are `provider:model`). */
423
+ private canEditSessionModelPrice(): boolean {
424
+ return this.sessionModel !== 'unknown' && this.sessionModel.includes(':');
425
+ }
426
+
427
+ private handlePriceEntryInput(key: string): boolean {
428
+ if (key === 'escape') {
429
+ this.priceEntry = null;
430
+ this.markDirty();
431
+ return true;
432
+ }
433
+ if (key === 'enter' || key === 'return') {
434
+ const raw = (this.priceEntry ?? '').trim();
435
+ if (!this.canEditSessionModelPrice()) {
436
+ // The prompt already explains why; Enter just closes it.
437
+ this.priceEntry = null;
438
+ this.markDirty();
439
+ return true;
440
+ }
441
+ const parts = raw.split(/[\s,]+/).filter((part) => part.length > 0);
442
+ const input = Number(parts[0]);
443
+ const output = Number(parts[1]);
444
+ if (parts.length === 2 && Number.isFinite(input) && input >= 0 && Number.isFinite(output) && output >= 0) {
445
+ writeManualModelPrice(this.configAccess!, this.sessionModel, { input, output });
446
+ this.priceEntry = null;
447
+ }
448
+ // Malformed input keeps the editor open so the draft can be corrected.
449
+ this.markDirty();
450
+ return true;
451
+ }
452
+ if (isTextBackspace(key)) {
453
+ if (this.priceEntry && this.priceEntry.length > 0) {
454
+ this.priceEntry = this.priceEntry.slice(0, -1);
455
+ this.markDirty();
456
+ }
457
+ return true;
458
+ }
459
+ // Two USD amounts separated by a comma (or space) — digits, dots, comma, space.
460
+ if (key.length === 1 && /[0-9., ]/.test(key)) {
461
+ this.priceEntry = (this.priceEntry ?? '') + key;
462
+ this.markDirty();
463
+ return true;
464
+ }
465
+ return true; // absorb everything else while entry is active
466
+ }
467
+
405
468
  /**
406
469
  * Scroll the agent list. Over-consumption fix: only absorbs the key (and
407
470
  * only advances) when the agent list is actually long enough to scroll —
@@ -427,20 +490,29 @@ export class CostTrackerPanel extends BasePanel {
427
490
  render(width: number, height: number): Line[] {
428
491
  if (height <= 0 || width <= 0) return [];
429
492
  if (this.budgetEntry !== null) return this.renderBudgetEntryPrompt(width, height);
493
+ if (this.priceEntry !== null) return this.renderPriceEntryPrompt(width, height);
430
494
 
431
495
  const totalInputTokens = this.sessionUsage.input + this.sessionUsage.cacheRead + this.sessionUsage.cacheWrite;
432
496
  const sessionCost = calcSessionCost(this.sessionUsage.input, this.sessionUsage.output, this.sessionUsage.cacheRead, this.sessionUsage.cacheWrite, this.sessionModel);
433
497
  const budgetThreshold = this.currentBudgetThreshold();
434
498
  const overBudget = computeBudgetBreach(sessionCost, budgetThreshold);
435
499
  const sparkline = buildSparkline(this.costHistory);
436
- const costStr = formatCost(sessionCost, !isModelPriced(this.sessionModel));
500
+ const sessionPriced = isModelPriced(this.sessionModel);
501
+ const costStr = formatCost(sessionCost, !sessionPriced);
437
502
  const costFg = overBudget ? C.bad : C.cost;
503
+ // Dollars carry their source: "your price" for a manual entry,
504
+ // "catalog price, as of <date>" for the dated catalog, etc. The
505
+ // "price unknown" marker carries the one-key action to fix it instead.
506
+ const sourceDescription = sessionPriced ? describePricingSource(this.sessionModel) : null;
507
+ const sourceStr = sessionPriced
508
+ ? (sourceDescription ? ` (${sourceDescription})` : '')
509
+ : ' — press p to set a price';
438
510
  const budgetStr = budgetThreshold > 0
439
511
  ? ` / ${formatCost(budgetThreshold)}`
440
512
  : '';
441
513
  const alertStr = overBudget ? ' ! OVER BUDGET' : '';
442
514
  const sessionLines: Line[] = [
443
- this.renderKeyValue(width, ' Total', `${costStr}${budgetStr}${alertStr}`, costFg),
515
+ this.renderKeyValue(width, ' Total', `${costStr}${budgetStr}${alertStr}${sourceStr}`, costFg),
444
516
  ];
445
517
  // Budget meter — the single most important glance for this panel: how much
446
518
  // of the configured budget the session has consumed. Only shown when a
@@ -455,6 +527,13 @@ export class CostTrackerPanel extends BasePanel {
455
527
  { filled: meterFg, empty: C.separator, label: C.label },
456
528
  { prefix: ' Budget [', suffix: `] ${pctStr}` },
457
529
  ));
530
+ // Unpriced-spend honesty wherever budget state shows: a meter over a
531
+ // partially-unpriced session must say the % undercounts real spend.
532
+ const anyUnpricedSpend = (!sessionPriced && (totalInputTokens > 0 || this.sessionUsage.output > 0))
533
+ || Array.from(this.agents.values()).some((agent) => agent.inputTokens > 0 && !isModelPriced(agent.model));
534
+ if (anyUnpricedSpend) {
535
+ sessionLines.push(this.renderKeyValue(width, '', 'some spend has no known price and is not counted above', C.warn));
536
+ }
458
537
  }
459
538
  if (sparkline.length > 0) sessionLines.push(this.renderLabeledLine(width, ' Trend', sparkline, C.good));
460
539
  sessionLines.push(this.renderKeyValue(width, ' Input', formatTokens(this.sessionUsage.input), C.label));
@@ -481,9 +560,11 @@ export class CostTrackerPanel extends BasePanel {
481
560
  { keys: 'Up/Down', label: 'scroll agents' },
482
561
  { keys: 'PgUp/PgDn', label: 'page' },
483
562
  { keys: 'b', label: 'set budget' },
563
+ { keys: 'p', label: 'set model price' },
484
564
  ], DEFAULT_PANEL_PALETTE)
485
565
  : buildKeyboardHints(width, [
486
566
  { keys: 'b', label: 'set budget alert' },
567
+ { keys: 'p', label: 'set model price' },
487
568
  ], DEFAULT_PANEL_PALETTE);
488
569
  if (agentList.length > 0) {
489
570
  const planCost = agentList.reduce((sum, a) => sum + a.cost, 0);
@@ -562,7 +643,7 @@ export class CostTrackerPanel extends BasePanel {
562
643
  width,
563
644
  ' No agents spawned this session',
564
645
  'Agent-level cost estimates appear here once delegated or background agents start running.',
565
- // WO-160: 'b' already opens the in-panel budget-entry field (see
646
+ // 'b' already opens the in-panel budget-entry field (see
566
647
  // handleInput/handleBudgetEntryInput above) and is advertised in
567
648
  // the footer's 'b: set budget' hint, so the printed
568
649
  // '/cost budget <usd>' command was a redundant action substitute.
@@ -626,4 +707,40 @@ export class CostTrackerPanel extends BasePanel {
626
707
  return workspace.slice(0, height);
627
708
  }
628
709
 
710
+ // Non-masked entry for the 'p' manual-price key. Two USD-per-1M-token
711
+ // amounts (input,output); persists to pricing.modelPrices for the session's
712
+ // provider:model live. A model without a provider prefix cannot carry a
713
+ // manual price (the settings key is keyed provider:model) — the prompt says
714
+ // so instead of accepting a value it could not store.
715
+ private renderPriceEntryPrompt(width: number, height: number): Line[] {
716
+ const editable = this.canEditSessionModelPrice();
717
+ const draft = this.priceEntry ?? '';
718
+ const display = `${draft}█`;
719
+ const promptLines: Line[] = editable
720
+ ? [
721
+ buildPanelLine(width, [[` Set your manual price for ${this.sessionModel} (USD per 1M tokens).`, C.label]]),
722
+ buildPanelLine(width, [[' Format: input,output — for example 3.00,15.00', C.dim]]),
723
+ buildPanelLine(width, [['', C.label]]),
724
+ buildPanelLine(width, [[' Price ', C.label], [display, C.cost]]),
725
+ buildPanelLine(width, [['', C.label]]),
726
+ buildPanelLine(width, [[' [Enter] Save [Esc] Cancel [Backspace] Delete char', C.dim]]),
727
+ ]
728
+ : [
729
+ buildPanelLine(width, [[` The current model (${this.sessionModel}) has no provider prefix, so a`, C.label]]),
730
+ buildPanelLine(width, [[' manual price cannot be stored for it (prices are keyed provider:model).', C.label]]),
731
+ buildPanelLine(width, [['', C.label]]),
732
+ buildPanelLine(width, [[' [Esc] Close', C.dim]]),
733
+ ];
734
+ const workspace = buildPanelWorkspace(width, height, {
735
+ title: ' Cost Tracker — Model Price',
736
+ intro: editable
737
+ ? 'Your price wins over provider and catalog prices, immediately and everywhere.'
738
+ : 'Manual prices are stored per provider:model.',
739
+ sections: [{ lines: promptLines }],
740
+ palette: DEFAULT_PANEL_PALETTE,
741
+ });
742
+ while (workspace.length < height) workspace.push(createEmptyLine(width));
743
+ return workspace.slice(0, height);
744
+ }
745
+
629
746
  }
@@ -27,10 +27,10 @@ import {
27
27
  // that shares it, including the workspace-chrome aliases (info/dim/value/
28
28
  // empty) so the raw-hex count never grows. The title band itself is NOT
29
29
  // overridden — buildPanelWorkspace always falls back to the canonical
30
- // DEFAULT_PANEL_PALETTE.headerBg (WO-002: one title band everywhere).
30
+ // DEFAULT_PANEL_PALETTE.headerBg (one title band everywhere).
31
31
  // ---------------------------------------------------------------------------
32
32
 
33
- // Hunk blue is the shared DIFF_TONES token (WO-204) — diff-view.ts (conversation)
33
+ // Hunk blue is the shared DIFF_TONES token — diff-view.ts (conversation)
34
34
  // and git-panel.ts's inline diff converge onto this file's pre-existing value.
35
35
  const HUNK_BLUE: string = DIFF_TONES.hunk;
36
36
  // Context rows and line-number gutter use the shared theme's muted/dim
@@ -39,7 +39,7 @@ const CONTEXT_GRAY = UI_TONES.fg.muted;
39
39
  const FILENAME_WHITE = '#ffffff';
40
40
  // Add/del text colors are the shared DIFF_TONES tokens, whose values ARE this
41
41
  // panel's shipped colors — this panel is the reference diff look (diff-view
42
- // was unwired dead code until WO-204, so "majority of surfaces" was a mirage);
42
+ // was unwired dead code until, so "majority of surfaces" was a mirage);
43
43
  // the conversation surface converges onto these, not the reverse.
44
44
  const ADD_GREEN: string = DIFF_TONES.add;
45
45
  const ADD_BG = '#001a0d';
@@ -521,7 +521,7 @@ export class DiffPanel extends BasePanel {
521
521
  }
522
522
  }
523
523
 
524
- // W6.1 (the purge): 'o' used to open the currently selected file in the
524
+ // (the purge): 'o' used to open the currently selected file in the
525
525
  // preview panel via a staged pendingOpenPreview flag + a
526
526
  // handlePanelIntegrationAction cross-panel hook (the same bridge
527
527
  // FileExplorerPanel used). 'preview' is DELETE-disposition with no
@@ -597,7 +597,7 @@ export class DiffPanel extends BasePanel {
597
597
  width,
598
598
  ' No diff to display.',
599
599
  'Load a git diff or select a changed file to populate the workspace. w=working h=HEAD s=staged self-load right here.',
600
- // WO-160: corrected — bare /diff loads files changed *this
600
+ // corrected — bare /diff loads files changed *this
601
601
  // session* (falling back to the full HEAD diff when none are
602
602
  // tracked yet), not the working-tree diff the w key already
603
603
  // loads in-panel; the old summary text described the wrong
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * EvalRegistry — holds the latest evaluation harness run state.
3
3
  *
4
- * W6.1 (the purge): extracted out of eval-panel.ts. 'eval' was
4
+ * (the purge): extracted out of eval-panel.ts. 'eval' was
5
5
  * DELETE-disposition (no surviving human surface — the evaluation harness
6
6
  * is driven and reviewed via the `/eval` CLI command, input/commands/eval.ts)
7
7
  * but this registry is still a live consumer of `/eval run` output, so it
8
8
  * survives as a standalone read-model rather than being deleted with the
9
- * view. See .goodvibes/audit/2026-07-04-wave6-briefs.json (W6.1).
9
+ * view. See .goodvibes/audit/2026-07-04-wave6-briefs.json.
10
10
  */
11
11
 
12
12
  import type { EvalSuiteResult, EvalGateResult } from '@/runtime/index.ts';
@@ -1,5 +1,5 @@
1
1
  // ---------------------------------------------------------------------------
2
- // fleet-deep-link.ts — DEBT-5 item 4.
2
+ // fleet-deep-link.ts — item 4.
3
3
  //
4
4
  // PanelManager.open('fleet', pane, target) hands FleetPanel a
5
5
  // PanelDeepLinkTarget (a process id + optional ProcessKind) so a cross-panel