@pellux/goodvibes-tui 1.1.0 → 1.7.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 (194) hide show
  1. package/CHANGELOG.md +85 -21
  2. package/README.md +20 -11
  3. package/docs/foundation-artifacts/operator-contract.json +1 -1
  4. package/package.json +2 -2
  5. package/src/core/alert-gating.ts +67 -0
  6. package/src/core/approval-alert.ts +72 -0
  7. package/src/core/budget-breach-notifier.ts +106 -0
  8. package/src/core/conversation-rendering.ts +19 -0
  9. package/src/core/conversation.ts +18 -0
  10. package/src/core/focus-tracker.ts +41 -0
  11. package/src/core/long-task-notifier.ts +33 -6
  12. package/src/core/system-message-router.ts +37 -51
  13. package/src/core/turn-cancellation.ts +20 -0
  14. package/src/core/turn-event-wiring.ts +64 -3
  15. package/src/export/cost-utils.ts +36 -0
  16. package/src/input/command-registry.ts +38 -1
  17. package/src/input/commands/checkpoint-runtime.ts +280 -0
  18. package/src/input/commands/codebase-runtime.ts +192 -0
  19. package/src/input/commands/eval.ts +1 -1
  20. package/src/input/commands/health-runtime.ts +1 -1
  21. package/src/input/commands/image-runtime.ts +112 -0
  22. package/src/input/commands/intelligence-runtime.ts +11 -1
  23. package/src/input/commands/local-auth-runtime.ts +4 -1
  24. package/src/input/commands/local-runtime.ts +9 -3
  25. package/src/input/commands/marketplace-runtime.ts +2 -2
  26. package/src/input/commands/memory.ts +6 -1
  27. package/src/input/commands/operator-panel-runtime.ts +40 -24
  28. package/src/input/commands/planning-runtime.ts +26 -3
  29. package/src/input/commands/platform-sandbox-runtime.ts +1 -6
  30. package/src/input/commands/plugin-runtime.ts +2 -2
  31. package/src/input/commands/policy-dispatch.ts +21 -0
  32. package/src/input/commands/provider-accounts-runtime.ts +1 -1
  33. package/src/input/commands/qrcode-runtime.ts +3 -3
  34. package/src/input/commands/recall-review.ts +35 -0
  35. package/src/input/commands/remote-runtime.ts +3 -3
  36. package/src/input/commands/runtime-services.ts +54 -13
  37. package/src/input/commands/services-runtime.ts +1 -1
  38. package/src/input/commands/session-workflow.ts +16 -1
  39. package/src/input/commands/settings-sync-runtime.ts +1 -1
  40. package/src/input/commands/shell-core.ts +15 -7
  41. package/src/input/commands/skills-runtime.ts +2 -8
  42. package/src/input/commands/subscription-runtime.ts +2 -2
  43. package/src/input/commands/test-runtime.ts +277 -0
  44. package/src/input/commands/websearch-runtime.ts +101 -0
  45. package/src/input/commands/work-plan-runtime.ts +36 -10
  46. package/src/input/commands/workstream-runtime.ts +338 -0
  47. package/src/input/commands.ts +12 -0
  48. package/src/input/config-modal-types.ts +161 -0
  49. package/src/input/config-modal.ts +377 -0
  50. package/src/input/feed-context-factory.ts +7 -8
  51. package/src/input/handler-command-route.ts +27 -17
  52. package/src/input/handler-feed-routes.ts +61 -23
  53. package/src/input/handler-feed.ts +47 -23
  54. package/src/input/handler-interactions.ts +1 -3
  55. package/src/input/handler-modal-routes.ts +65 -0
  56. package/src/input/handler-modal-stack.ts +3 -5
  57. package/src/input/handler-modal-token-routes.ts +16 -49
  58. package/src/input/handler-picker-routes.ts +11 -94
  59. package/src/input/handler-shortcuts.ts +24 -14
  60. package/src/input/handler-types.ts +2 -6
  61. package/src/input/handler-ui-state.ts +10 -22
  62. package/src/input/handler.ts +6 -28
  63. package/src/input/keybindings.ts +22 -8
  64. package/src/input/model-picker-types.ts +24 -6
  65. package/src/input/model-picker.ts +58 -0
  66. package/src/input/panel-integration-actions.ts +9 -170
  67. package/src/input/settings-modal-data.ts +95 -0
  68. package/src/input/settings-modal-mutations.ts +6 -4
  69. package/src/main.ts +24 -27
  70. package/src/panels/agent-inspector-shared.ts +2 -1
  71. package/src/panels/base-panel.ts +22 -1
  72. package/src/panels/builtin/agent.ts +21 -107
  73. package/src/panels/builtin/development.ts +15 -61
  74. package/src/panels/builtin/knowledge.ts +8 -32
  75. package/src/panels/builtin/operations.ts +84 -428
  76. package/src/panels/builtin/session.ts +21 -112
  77. package/src/panels/builtin/shared.ts +9 -43
  78. package/src/panels/builtin-modals.ts +218 -0
  79. package/src/panels/builtin-panels.ts +5 -0
  80. package/src/panels/cost-tracker-panel.ts +36 -10
  81. package/src/panels/diff-panel.ts +12 -43
  82. package/src/panels/eval-registry.ts +60 -0
  83. package/src/panels/fleet-panel.ts +800 -0
  84. package/src/panels/fleet-read-model.ts +477 -0
  85. package/src/panels/fleet-steer.ts +92 -0
  86. package/src/panels/fleet-stop.ts +125 -0
  87. package/src/panels/fleet-tabs.ts +230 -0
  88. package/src/panels/fleet-transcript.ts +356 -0
  89. package/src/panels/index.ts +7 -31
  90. package/src/panels/modals/hooks-modal.ts +187 -0
  91. package/src/panels/modals/keybindings-modal.ts +151 -0
  92. package/src/panels/modals/knowledge-modal.ts +158 -0
  93. package/src/panels/modals/local-auth-modal.ts +132 -0
  94. package/src/panels/modals/marketplace-modal.ts +218 -0
  95. package/src/panels/modals/memory-modal.ts +180 -0
  96. package/src/panels/modals/modal-surface-helpers.ts +54 -0
  97. package/src/panels/modals/modal-theme.ts +36 -0
  98. package/src/panels/modals/pairing-modal.ts +144 -0
  99. package/src/panels/modals/planning-modal.ts +282 -0
  100. package/src/panels/modals/plugins-modal.ts +174 -0
  101. package/src/panels/modals/policy-modal.ts +256 -0
  102. package/src/panels/modals/provider-health-modal.ts +136 -0
  103. package/src/panels/modals/remote-modal.ts +115 -0
  104. package/src/panels/modals/sandbox-modal.ts +150 -0
  105. package/src/panels/modals/security-modal.ts +217 -0
  106. package/src/panels/modals/services-modal.ts +179 -0
  107. package/src/panels/modals/settings-sync-modal.ts +142 -0
  108. package/src/panels/modals/skills-modal.ts +189 -0
  109. package/src/panels/modals/subscription-modal.ts +172 -0
  110. package/src/panels/modals/work-plan-modal.ts +149 -0
  111. package/src/panels/panel-confirm-overlay.ts +72 -0
  112. package/src/panels/panel-manager.ts +108 -5
  113. package/src/panels/project-planning-answer-actions.ts +4 -2
  114. package/src/panels/skills-panel.ts +7 -51
  115. package/src/panels/types.ts +13 -0
  116. package/src/permissions/hunk-selection.ts +179 -0
  117. package/src/permissions/prompt.ts +60 -4
  118. package/src/renderer/compaction-history-modal.ts +19 -3
  119. package/src/renderer/compaction-preview.ts +13 -2
  120. package/src/renderer/compaction-quality.ts +100 -0
  121. package/src/renderer/config-modal.ts +81 -0
  122. package/src/renderer/conversation-overlays.ts +10 -17
  123. package/src/renderer/fleet-tab-strip.ts +56 -0
  124. package/src/renderer/footer-tips.ts +10 -2
  125. package/src/renderer/git-status.ts +40 -0
  126. package/src/renderer/help-overlay.ts +2 -2
  127. package/src/renderer/model-workspace.ts +44 -1
  128. package/src/renderer/panel-workspace-bar.ts +8 -2
  129. package/src/renderer/turn-injection.ts +114 -0
  130. package/src/runtime/bootstrap-command-context.ts +21 -1
  131. package/src/runtime/bootstrap-command-parts.ts +34 -7
  132. package/src/runtime/bootstrap-core.ts +14 -4
  133. package/src/runtime/bootstrap-shell.ts +29 -16
  134. package/src/runtime/bootstrap.ts +11 -17
  135. package/src/runtime/code-index-services.ts +112 -0
  136. package/src/runtime/orchestrator-core-services.ts +49 -0
  137. package/src/runtime/process-lifecycle.ts +3 -1
  138. package/src/runtime/services.ts +91 -43
  139. package/src/runtime/ui-services.ts +8 -0
  140. package/src/runtime/workstream-services.ts +195 -0
  141. package/src/shell/blocking-input.ts +22 -1
  142. package/src/shell/ui-openers.ts +129 -17
  143. package/src/utils/format-duration.ts +8 -18
  144. package/src/utils/splash-lines.ts +1 -1
  145. package/src/version.ts +1 -1
  146. package/src/panels/agent-inspector-panel.ts +0 -786
  147. package/src/panels/approval-panel.ts +0 -252
  148. package/src/panels/automation-control-panel.ts +0 -479
  149. package/src/panels/cockpit-panel.ts +0 -481
  150. package/src/panels/cockpit-read-model.ts +0 -238
  151. package/src/panels/communication-panel.ts +0 -256
  152. package/src/panels/control-plane-panel.ts +0 -470
  153. package/src/panels/debug-panel.ts +0 -615
  154. package/src/panels/docs-panel.ts +0 -384
  155. package/src/panels/eval-panel.ts +0 -627
  156. package/src/panels/file-explorer-panel.ts +0 -673
  157. package/src/panels/file-preview-panel.ts +0 -517
  158. package/src/panels/hooks-panel.ts +0 -401
  159. package/src/panels/incident-review-panel.ts +0 -406
  160. package/src/panels/intelligence-panel.ts +0 -383
  161. package/src/panels/knowledge-graph-panel.ts +0 -515
  162. package/src/panels/marketplace-panel.ts +0 -399
  163. package/src/panels/memory-panel.ts +0 -558
  164. package/src/panels/ops-control-panel.ts +0 -329
  165. package/src/panels/ops-strategy-panel.ts +0 -321
  166. package/src/panels/orchestration-panel.ts +0 -465
  167. package/src/panels/panel-list-panel.ts +0 -566
  168. package/src/panels/plan-dashboard-panel.ts +0 -707
  169. package/src/panels/policy-panel.ts +0 -517
  170. package/src/panels/project-planning-panel.ts +0 -731
  171. package/src/panels/provider-health-panel.ts +0 -678
  172. package/src/panels/provider-health-tracker.ts +0 -310
  173. package/src/panels/provider-health-views.ts +0 -567
  174. package/src/panels/qr-panel.ts +0 -280
  175. package/src/panels/remote-panel.ts +0 -534
  176. package/src/panels/routes-panel.ts +0 -241
  177. package/src/panels/sandbox-panel.ts +0 -456
  178. package/src/panels/security-panel.ts +0 -447
  179. package/src/panels/services-panel.ts +0 -329
  180. package/src/panels/session-browser-panel.ts +0 -496
  181. package/src/panels/settings-sync-panel.ts +0 -398
  182. package/src/panels/subscription-panel.ts +0 -342
  183. package/src/panels/symbol-outline-panel.ts +0 -619
  184. package/src/panels/system-messages-panel.ts +0 -364
  185. package/src/panels/tasks-panel.ts +0 -608
  186. package/src/panels/thinking-panel.ts +0 -333
  187. package/src/panels/tool-inspector-panel.ts +0 -537
  188. package/src/panels/work-plan-panel.ts +0 -540
  189. package/src/panels/worktree-panel.ts +0 -360
  190. package/src/panels/wrfc-panel.ts +0 -790
  191. package/src/renderer/agent-detail-modal.ts +0 -466
  192. package/src/renderer/live-tail-modal.ts +0 -156
  193. package/src/renderer/process-modal.ts +0 -671
  194. package/src/renderer/qr-renderer.ts +0 -120
@@ -8,9 +8,8 @@ import { truncateDisplay, getDisplayWidth } from '../utils/terminal-width.ts';
8
8
  import { GitService } from '@pellux/goodvibes-sdk/platform/git';
9
9
  import { BasePanel } from './base-panel.ts';
10
10
  import { UI_TONES, DIFF_TONES } from '../renderer/ui-primitives.ts';
11
- import { FilePreviewPanel } from './file-preview-panel.ts';
12
- import type { PanelIntegrationContext } from './types.ts';
13
11
  import { logger } from '@pellux/goodvibes-sdk/platform/utils';
12
+ import { PanelConfirmOverlay } from './panel-confirm-overlay.ts';
14
13
  import {
15
14
  buildBodyText,
16
15
  buildEmptyState,
@@ -262,14 +261,12 @@ export class DiffPanel extends BasePanel {
262
261
  private selectedFile = 0;
263
262
  private scrollOffset = 0;
264
263
 
265
- /** Set by the 'o' key; consumed by handlePanelIntegrationAction on the next dispatch. */
266
- private pendingOpenPreview = false;
267
-
268
264
  /** One-line confirmation for the 'w'/'h'/'s' self-load hotkeys — otherwise a
269
265
  * reload that produces identical content is visually indistinguishable
270
266
  * from the keypress doing nothing at all. */
271
267
  private hotkeyStatus: string | null = null;
272
268
 
269
+ public readonly confirmOverlay = new PanelConfirmOverlay(() => this.markDirty()); // armed by a command handler (e.g. /rewind); see panel-confirm-overlay.ts
273
270
  constructor(
274
271
  workingDirectory: string,
275
272
  private readonly requestRender: () => void = () => {},
@@ -502,6 +499,7 @@ export class DiffPanel extends BasePanel {
502
499
  }
503
500
 
504
501
  handleInput(key: string): boolean {
502
+ if (this.confirmOverlay.handleInput(key)) return true; // confirm takes priority (git-panel.ts:284-303 precedent)
505
503
  switch (key) {
506
504
  case 'up': this.scrollUp(); return true;
507
505
  case 'down': this.scrollDown(); return true;
@@ -519,48 +517,17 @@ export class DiffPanel extends BasePanel {
519
517
  case 'w': this.runHotkeyReload('working tree', () => this.showGitDiff()); return true;
520
518
  case 'h': this.runHotkeyReload('HEAD', () => this.showGitDiff('HEAD')); return true;
521
519
  case 's': this.runHotkeyReload('staged', () => this.showStagedDiff()); return true;
522
- case 'o': {
523
- if (!this.currentEntry()) return false;
524
- this.pendingOpenPreview = true;
525
- return true;
526
- }
527
520
  default: return false;
528
521
  }
529
522
  }
530
523
 
531
- /**
532
- * Cross-panel integration hook 'o' opens the currently selected file in
533
- * the preview panel via the same open/focus bridge FileExplorerPanel uses
534
- * (src/input/panel-integration-actions.ts), without this panel needing to
535
- * know about PanelManager pane/focus mechanics beyond what ctx exposes.
536
- */
537
- handlePanelIntegrationAction(_key: string, ctx: PanelIntegrationContext): boolean {
538
- if (!this.pendingOpenPreview) return false;
539
- this.pendingOpenPreview = false;
540
- const entry = this.currentEntry();
541
- if (!entry) return false;
542
-
543
- const pm = ctx.panelManager;
544
- let previewPanel = pm.getPanel('preview');
545
- if (previewPanel instanceof FilePreviewPanel) {
546
- const pane = pm.getPaneOf('preview');
547
- pm.activateById('preview');
548
- if (pane) pm.focusPane(pane);
549
- } else {
550
- const targetPane: 'top' | 'bottom' = pm.isBottomPaneVisible()
551
- ? (pm.getFocusedPane() === 'top' ? 'bottom' : 'top')
552
- : 'bottom';
553
- const opened = pm.open('preview', targetPane);
554
- pm.show();
555
- pm.focusPane(targetPane);
556
- previewPanel = opened instanceof FilePreviewPanel ? opened : null;
557
- }
558
- if (previewPanel instanceof FilePreviewPanel) {
559
- previewPanel.openFile(entry.filePath);
560
- return true;
561
- }
562
- return false;
563
- }
524
+ // W6.1 (the purge): 'o' used to open the currently selected file in the
525
+ // preview panel via a staged pendingOpenPreview flag + a
526
+ // handlePanelIntegrationAction cross-panel hook (the same bridge
527
+ // FileExplorerPanel used). 'preview' is DELETE-disposition with no
528
+ // successor surface (no file-picker-overlay preview to repoint to
529
+ // either — verified), so the key and the hook were removed rather than
530
+ // repointed; diff no longer has an 'o' action.
564
531
 
565
532
  private scrollUp(): void {
566
533
  if (this.scrollOffset > 0) {
@@ -618,6 +585,8 @@ export class DiffPanel extends BasePanel {
618
585
  return this.trackedRender(() => {
619
586
  if (height <= 0 || width <= 0) return [];
620
587
 
588
+ const confirmLines = this.confirmOverlay.renderLines(width);
589
+ if (confirmLines) return buildPanelWorkspace(width, height, { title: 'Diff Workspace', palette: COLOR, sections: [{ title: 'Confirmation', lines: confirmLines }] });
621
590
  if (this.entries.length === 0) {
622
591
  return buildPanelWorkspace(width, height, {
623
592
  title: 'Diff Workspace',
@@ -0,0 +1,60 @@
1
+ /**
2
+ * EvalRegistry — holds the latest evaluation harness run state.
3
+ *
4
+ * W6.1 (the purge): extracted out of eval-panel.ts. 'eval' was
5
+ * DELETE-disposition (no surviving human surface — the evaluation harness
6
+ * is driven and reviewed via the `/eval` CLI command, input/commands/eval.ts)
7
+ * but this registry is still a live consumer of `/eval run` output, so it
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).
10
+ */
11
+
12
+ import type { EvalSuiteResult, EvalGateResult } from '@/runtime/index.ts';
13
+
14
+ export class EvalRegistry {
15
+ private _suiteResults: EvalSuiteResult[] = [];
16
+ private _gateResults: EvalGateResult[] = [];
17
+ private _running = false;
18
+ private _lastRunAt: number | null = null;
19
+ private readonly _subscribers = new Set<() => void>();
20
+
21
+ push(result: EvalSuiteResult): void {
22
+ const idx = this._suiteResults.findIndex((r) => r.suite === result.suite);
23
+ if (idx >= 0) {
24
+ this._suiteResults[idx] = result;
25
+ } else {
26
+ this._suiteResults.push(result);
27
+ }
28
+ this._lastRunAt = Date.now();
29
+ this._notify();
30
+ }
31
+
32
+ pushGate(gate: EvalGateResult): void {
33
+ const idx = this._gateResults.findIndex((g) => g.suite === gate.suite);
34
+ if (idx >= 0) {
35
+ this._gateResults[idx] = gate;
36
+ } else {
37
+ this._gateResults.push(gate);
38
+ }
39
+ this._notify();
40
+ }
41
+
42
+ setRunning(running: boolean): void {
43
+ this._running = running;
44
+ this._notify();
45
+ }
46
+
47
+ isRunning(): boolean { return this._running; }
48
+ getLastRunAt(): number | null { return this._lastRunAt; }
49
+ getSuiteResults(): EvalSuiteResult[] { return this._suiteResults; }
50
+ getGateResults(): EvalGateResult[] { return this._gateResults; }
51
+
52
+ subscribe(cb: () => void): () => void {
53
+ this._subscribers.add(cb);
54
+ return () => this._subscribers.delete(cb);
55
+ }
56
+
57
+ private _notify(): void {
58
+ for (const cb of this._subscribers) cb();
59
+ }
60
+ }