@pellux/goodvibes-tui 0.28.0 → 0.29.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 (118) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/src/input/commands/cost-runtime.ts +49 -0
  5. package/src/input/commands/operator-runtime.ts +5 -1
  6. package/src/input/commands.ts +2 -0
  7. package/src/input/handler-feed-routes.ts +12 -35
  8. package/src/input/handler-feed.ts +4 -8
  9. package/src/input/handler-shortcuts.ts +51 -0
  10. package/src/input/handler.ts +43 -6
  11. package/src/input/keybindings.ts +48 -8
  12. package/src/input/panel-integration-actions.ts +107 -1
  13. package/src/main.ts +5 -1
  14. package/src/panels/agent-inspector-panel.ts +125 -36
  15. package/src/panels/agent-inspector-shared.ts +144 -0
  16. package/src/panels/approval-panel.ts +67 -16
  17. package/src/panels/automation-control-panel.ts +368 -124
  18. package/src/panels/builtin/agent.ts +28 -37
  19. package/src/panels/builtin/development.ts +40 -32
  20. package/src/panels/builtin/knowledge.ts +15 -6
  21. package/src/panels/builtin/operations.ts +178 -117
  22. package/src/panels/builtin/session.ts +35 -9
  23. package/src/panels/builtin/shared.ts +98 -6
  24. package/src/panels/cockpit-panel.ts +232 -73
  25. package/src/panels/communication-panel.ts +58 -20
  26. package/src/panels/confirm-state.ts +8 -1
  27. package/src/panels/control-plane-panel.ts +351 -118
  28. package/src/panels/cost-tracker-panel.ts +165 -7
  29. package/src/panels/debug-panel.ts +312 -159
  30. package/src/panels/diff-panel.ts +203 -57
  31. package/src/panels/docs-panel.ts +152 -66
  32. package/src/panels/eval-panel.ts +220 -42
  33. package/src/panels/file-explorer-panel.ts +202 -122
  34. package/src/panels/file-preview-panel.ts +132 -57
  35. package/src/panels/git-panel.ts +309 -128
  36. package/src/panels/hooks-panel.ts +150 -22
  37. package/src/panels/incident-review-panel.ts +223 -35
  38. package/src/panels/index.ts +0 -4
  39. package/src/panels/intelligence-panel.ts +212 -86
  40. package/src/panels/knowledge-graph-panel.ts +461 -101
  41. package/src/panels/local-auth-panel.ts +240 -28
  42. package/src/panels/marketplace-panel.ts +193 -26
  43. package/src/panels/memory-panel.ts +78 -77
  44. package/src/panels/ops-control-panel.ts +146 -29
  45. package/src/panels/ops-strategy-panel.ts +72 -4
  46. package/src/panels/orchestration-panel.ts +231 -69
  47. package/src/panels/panel-list-panel.ts +154 -131
  48. package/src/panels/panel-manager.ts +97 -9
  49. package/src/panels/plan-dashboard-panel.ts +333 -17
  50. package/src/panels/plugins-panel.ts +184 -29
  51. package/src/panels/policy-panel.ts +210 -38
  52. package/src/panels/polish-core.ts +7 -2
  53. package/src/panels/polish.ts +23 -4
  54. package/src/panels/project-planning-answer-actions.ts +134 -0
  55. package/src/panels/project-planning-panel.ts +62 -113
  56. package/src/panels/provider-health-panel.ts +434 -518
  57. package/src/panels/provider-health-routes.ts +203 -0
  58. package/src/panels/provider-health-tracker.ts +194 -6
  59. package/src/panels/provider-health-views.ts +560 -0
  60. package/src/panels/qr-panel.ts +116 -30
  61. package/src/panels/remote-panel.ts +114 -36
  62. package/src/panels/routes-panel.ts +63 -22
  63. package/src/panels/sandbox-panel.ts +174 -42
  64. package/src/panels/scrollable-list-panel.ts +19 -135
  65. package/src/panels/security-panel.ts +133 -33
  66. package/src/panels/services-panel.ts +116 -64
  67. package/src/panels/session-browser-panel.ts +73 -2
  68. package/src/panels/session-maintenance.ts +4 -122
  69. package/src/panels/settings-sync-panel.ts +335 -72
  70. package/src/panels/skills-panel.ts +157 -89
  71. package/src/panels/subscription-panel.ts +86 -33
  72. package/src/panels/symbol-outline-panel.ts +248 -108
  73. package/src/panels/system-messages-panel.ts +114 -13
  74. package/src/panels/tasks-panel.ts +326 -139
  75. package/src/panels/thinking-panel.ts +43 -10
  76. package/src/panels/token-budget-panel.ts +194 -18
  77. package/src/panels/tool-inspector-panel.ts +144 -34
  78. package/src/panels/types.ts +40 -4
  79. package/src/panels/work-plan-panel.ts +280 -17
  80. package/src/panels/worktree-panel.ts +175 -42
  81. package/src/panels/wrfc-panel.ts +116 -24
  82. package/src/renderer/conversation-overlays.ts +25 -11
  83. package/src/renderer/footer-tips.ts +41 -0
  84. package/src/renderer/fullscreen-primitives.ts +22 -16
  85. package/src/renderer/help-overlay.ts +91 -14
  86. package/src/renderer/hint-grammar.ts +52 -0
  87. package/src/renderer/layout.ts +7 -7
  88. package/src/renderer/modal-factory.ts +23 -15
  89. package/src/renderer/model-picker-overlay.ts +21 -7
  90. package/src/renderer/overlay-box.ts +16 -10
  91. package/src/renderer/process-indicator.ts +3 -1
  92. package/src/renderer/progress.ts +5 -4
  93. package/src/renderer/search-overlay.ts +27 -6
  94. package/src/renderer/session-picker-modal.ts +6 -4
  95. package/src/renderer/settings-modal.ts +70 -10
  96. package/src/renderer/shell-surface.ts +41 -15
  97. package/src/renderer/status-glyphs.ts +11 -9
  98. package/src/renderer/theme.ts +60 -3
  99. package/src/renderer/ui-factory.ts +41 -30
  100. package/src/renderer/ui-primitives.ts +23 -2
  101. package/src/runtime/bootstrap-shell.ts +35 -18
  102. package/src/runtime/diagnostics/panels/index.ts +0 -3
  103. package/src/shell/ui-openers.ts +14 -22
  104. package/src/utils/format-duration.ts +2 -2
  105. package/src/utils/splash-lines.ts +44 -3
  106. package/src/version.ts +1 -1
  107. package/src/work-plans/work-plan-store.ts +13 -0
  108. package/src/panels/agent-logs-panel.ts +0 -635
  109. package/src/panels/agent-logs-shared.ts +0 -129
  110. package/src/panels/context-visualizer-panel.ts +0 -238
  111. package/src/panels/forensics-panel.ts +0 -378
  112. package/src/panels/provider-account-snapshot.ts +0 -259
  113. package/src/panels/provider-accounts-panel.ts +0 -255
  114. package/src/panels/provider-stats-panel.ts +0 -391
  115. package/src/panels/schedule-panel.ts +0 -365
  116. package/src/panels/watchers-panel.ts +0 -213
  117. package/src/runtime/diagnostics/panels/panel-resources.ts +0 -118
  118. package/src/runtime/diagnostics/panels/policy.ts +0 -177
@@ -1,14 +1,12 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
- import { AgentLogsPanel } from '../agent-logs-panel.ts';
3
- import { ContextVisualizerPanel } from '../context-visualizer-panel.ts';
2
+ import { AgentInspectorPanel } from '../agent-inspector-panel.ts';
4
3
  import { ThinkingPanel } from '../thinking-panel.ts';
5
4
  import { ToolInspectorPanel } from '../tool-inspector-panel.ts';
6
5
  import { WrfcPanel } from '../wrfc-panel.ts';
7
- import { SchedulePanel } from '../schedule-panel.ts';
8
6
  import { ProjectPlanningPanel } from '../project-planning-panel.ts';
9
7
  import { WorkPlanPanel } from '../work-plan-panel.ts';
10
8
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
11
- import { requireAutomationManager, requireUiServices } from './shared.ts';
9
+ import { requireUiServices } from './shared.ts';
12
10
 
13
11
  export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
14
12
  manager.registerType({
@@ -18,6 +16,7 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
18
16
  category: 'ai',
19
17
  description: 'Stream model reasoning tokens in real-time with collapsible blocks per turn',
20
18
  preload: true,
19
+ retainOnClose: true,
21
20
  factory: () => new ThinkingPanel(requireUiServices(deps).events.turns),
22
21
  });
23
22
 
@@ -28,47 +27,44 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
28
27
  category: 'ai',
29
28
  description: 'Chronological tool call inspector with expandable args/results and filtering',
30
29
  preload: true,
30
+ retainOnClose: true,
31
31
  factory: () => {
32
32
  const ui = requireUiServices(deps);
33
33
  return new ToolInspectorPanel(ui.events.tools, ui.events.turns);
34
34
  },
35
35
  });
36
36
 
37
+ // WO-110: agent-logs merged into inspector — one deep agent console with
38
+ // the correct JSONL parser + cancel, plus agent-logs' follow/pause/filter
39
+ // ergonomics. Registration moved here (category 'agent') from
40
+ // builtin/development.ts. (WO-113 retired the 'context' registration that
41
+ // previously lived here: ContextVisualizerPanel merged into TokenBudgetPanel,
42
+ // aliased in builtin/session.ts.)
37
43
  manager.registerType({
38
- id: 'context',
39
- name: 'Context',
40
- icon: 'C',
41
- category: 'ai',
42
- description: 'Context window visualizer: stacked bar showing token usage per section',
43
- preload: true,
44
- factory: () => new ContextVisualizerPanel(
45
- requireUiServices(deps).events.turns,
46
- deps.sessionMemoryStore,
47
- deps.configManager,
48
- deps.getOrchestratorUsage,
49
- deps.getCtxWindow ?? deps.contextWindow,
50
- requireUiServices(deps).readModels.session,
51
- () => deps.orchestrator?.lastInputTokens ?? 0,
52
- ),
53
- });
54
-
55
- manager.registerType({
56
- id: 'agent-logs',
57
- name: 'Agents',
58
- icon: 'A',
44
+ id: 'inspector',
45
+ name: 'Inspector',
46
+ icon: 'I',
59
47
  category: 'agent',
60
- description: 'View-only live session stream from running agents with per-agent switching',
48
+ description: 'Live per-agent console: timeline, tool calls, WRFC/cost badges, pause/filter/follow, and cancel',
61
49
  preload: true,
50
+ retainOnClose: true,
62
51
  factory: () => {
63
52
  const ui = requireUiServices(deps);
64
- return new AgentLogsPanel(ui.events.agents, {
53
+ return new AgentInspectorPanel({
65
54
  agentManager: ui.agents.agentManager,
55
+ agentMessageBus: ui.agents.agentMessageBus,
56
+ agentEvents: ui.events.agents,
66
57
  workingDirectory: ui.environment.workingDirectory,
58
+ cancelAgent: (agentId: string) => ui.agents.agentManager.cancel(agentId),
67
59
  requestRender: deps.requestRender,
68
60
  });
69
61
  },
70
62
  });
71
63
 
64
+ // Compat: '/panel open agent-logs' (and any saved layout/muscle memory)
65
+ // still resolves — redirected to the merged inspector console.
66
+ manager.registerAlias('agent-logs', 'inspector');
67
+
72
68
  manager.registerType({
73
69
  id: 'wrfc',
74
70
  name: 'WRFC',
@@ -76,6 +72,7 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
76
72
  category: 'agent',
77
73
  description: 'WRFC chain view: write, review, fix, and confirm cycle status',
78
74
  preload: true,
75
+ retainOnClose: true,
79
76
  factory: () => {
80
77
  const ui = requireUiServices(deps);
81
78
  return new WrfcPanel(ui.events.workflows, {
@@ -88,10 +85,12 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
88
85
  manager.registerType({
89
86
  id: 'work-plan',
90
87
  name: 'Work Plan',
91
- icon: 'L',
88
+ // WO-152: was 'L' (collided with panel-list).
89
+ icon: '◧',
92
90
  category: 'agent',
93
91
  description: 'Persistent workspace checklist for multi-step work and cross-session task tracking',
94
92
  preload: true,
93
+ retainOnClose: true,
95
94
  factory: () => new WorkPlanPanel(deps.workPlanStore),
96
95
  });
97
96
 
@@ -102,6 +101,7 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
102
101
  category: 'agent',
103
102
  description: 'Passive project planning artifacts: readiness, questions, decisions, language, task graph, and agent handoff metadata',
104
103
  preload: true,
104
+ retainOnClose: true,
105
105
  factory: () => new ProjectPlanningPanel({
106
106
  service: deps.projectPlanningService,
107
107
  projectId: deps.projectPlanningProjectId,
@@ -110,13 +110,4 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
110
110
  dismissPlanning: deps.dismissPlanning,
111
111
  }),
112
112
  });
113
-
114
- manager.registerType({
115
- id: 'schedule',
116
- name: 'Schedule',
117
- icon: 'Z',
118
- category: 'agent',
119
- description: 'Scheduled agent tasks: cron expressions, next run time, enable/disable, run history',
120
- factory: () => new SchedulePanel(requireAutomationManager(deps)),
121
- });
122
113
  }
@@ -2,14 +2,13 @@ import type { PanelManager } from '../panel-manager.ts';
2
2
  import { GitPanel } from '../git-panel.ts';
3
3
  import { DiffPanel } from '../diff-panel.ts';
4
4
  import { PlanDashboardPanel } from '../plan-dashboard-panel.ts';
5
- import { AgentInspectorPanel } from '../agent-inspector-panel.ts';
6
5
  import { CostTrackerPanel } from '../cost-tracker-panel.ts';
7
6
  import { IntelligencePanel } from '../intelligence-panel.ts';
8
7
  import { FileExplorerPanel } from '../file-explorer-panel.ts';
9
8
  import { FilePreviewPanel } from '../file-preview-panel.ts';
10
9
  import { SymbolOutlinePanel } from '../symbol-outline-panel.ts';
11
10
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
12
- import { requireUiServices } from './shared.ts';
11
+ import { requireUiServices, withUnconfiguredFallback } from './shared.ts';
13
12
 
14
13
  export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
15
14
  manager.registerType({
@@ -18,16 +17,27 @@ export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedB
18
17
  icon: 'G',
19
18
  category: 'development',
20
19
  description: 'Git status, staged/unstaged changes, and recent commits',
21
- factory: () => new GitPanel(requireUiServices(deps).environment.workingDirectory, deps.requestRender),
20
+ // sessionChangeTracker is optional: when a caller wires it into
21
+ // BuiltinPanelDeps, the Git panel highlights files touched this session.
22
+ factory: () => new GitPanel(
23
+ requireUiServices(deps).environment.workingDirectory,
24
+ deps.requestRender,
25
+ deps.sessionChangeTracker ? () => deps.sessionChangeTracker!.getChangedFiles() : undefined,
26
+ ),
22
27
  });
23
28
 
24
29
  manager.registerType({
25
30
  id: 'plan',
26
31
  name: 'Plan',
27
- icon: 'P',
32
+ // Distinct from Planning's 'P' (builtin/agent.ts) — interim glyph per
33
+ // WO-128; WO-152 owns the registry-wide icon-uniqueness assertion.
34
+ icon: '▤',
28
35
  category: 'agent',
29
36
  description: 'Active execution plan with phase progress and item status',
30
- factory: () => new PlanDashboardPanel(deps.planManager),
37
+ factory: () => {
38
+ const ui = requireUiServices(deps);
39
+ return new PlanDashboardPanel(ui.events.workflows, { planManager: deps.planManager });
40
+ },
31
41
  });
32
42
 
33
43
  manager.registerType({
@@ -39,39 +49,33 @@ export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedB
39
49
  factory: () => new DiffPanel(requireUiServices(deps).environment.workingDirectory),
40
50
  });
41
51
 
42
- manager.registerType({
43
- id: 'inspector',
44
- name: 'Inspector',
45
- icon: 'I',
46
- category: 'agent',
47
- description: "Detailed timeline view of a specific agent's messages and tool calls",
48
- factory: () => {
49
- const ui = requireUiServices(deps);
50
- return new AgentInspectorPanel({
51
- agentManager: ui.agents.agentManager,
52
- agentMessageBus: ui.agents.agentMessageBus,
53
- workingDirectory: ui.environment.workingDirectory,
54
- cancelAgent: (agentId: string) => ui.agents.agentManager.cancel(agentId),
55
- requestRender: deps.requestRender,
56
- });
57
- },
58
- });
52
+ // WO-110: 'inspector' registration moved to builtin/agent.ts (category
53
+ // 'agent') — it now absorbs the merged agent-logs capabilities.
59
54
 
60
- if (deps.getOrchestratorUsage) {
55
+ // WO-152: always registered (was gated behind `if (deps.getOrchestratorUsage)`,
56
+ // so `/panel open cost` reported "Unknown panel" on builds without usage
57
+ // tracking wired). Falls back to a "dependency not configured" empty state.
58
+ {
61
59
  const { getOrchestratorUsage, budgetThreshold } = deps;
62
60
  manager.registerType({
63
61
  id: 'cost',
64
62
  name: 'Cost',
65
63
  icon: '$',
66
- category: 'monitoring',
64
+ category: 'providers',
67
65
  description: 'Estimated costs per session, agent, and plan with budget alerts',
68
- factory: () => {
69
- const ui = requireUiServices(deps);
70
- return new CostTrackerPanel(ui.events.turns, ui.events.agents, getOrchestratorUsage, {
71
- budgetThreshold,
72
- getAgentStatus: (id) => ui.agents.agentManager.getStatus(id),
73
- });
74
- },
66
+ factory: withUnconfiguredFallback(
67
+ getOrchestratorUsage !== undefined,
68
+ 'cost', 'Cost', '$', 'providers',
69
+ ' Cost tracking not configured for this session.',
70
+ 'This runtime was not wired with orchestrator usage tracking at bootstrap, so no cost data is available.',
71
+ () => {
72
+ const ui = requireUiServices(deps);
73
+ return new CostTrackerPanel(ui.events.turns, ui.events.agents, getOrchestratorUsage!, {
74
+ budgetThreshold,
75
+ getAgentStatus: (id) => ui.agents.agentManager.getStatus(id),
76
+ });
77
+ },
78
+ ),
75
79
  });
76
80
  }
77
81
 
@@ -99,7 +103,11 @@ export function registerDevelopmentPanels(manager: PanelManager, deps: ResolvedB
99
103
  manager.registerType({
100
104
  id: 'preview',
101
105
  name: 'Preview',
102
- icon: 'V',
106
+ // WO-152: was 'V' in the registry vs the live panel's own 'P' (base-panel
107
+ // super() call) — a pre-existing registry/instance icon mismatch as well
108
+ // as a collision (project-planning and plugins both also used 'P').
109
+ // Unified to a single unique glyph in both places.
110
+ icon: '◑',
103
111
  category: 'development',
104
112
  description: 'Syntax-highlighted file preview',
105
113
  factory: () => new FilePreviewPanel(),
@@ -1,19 +1,22 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
2
  import { MemoryPanel } from '../memory-panel.ts';
3
3
  import { KnowledgeGraphPanel } from '../knowledge-graph-panel.ts';
4
- import type { ResolvedBuiltinPanelDeps } from './shared.ts';
4
+ import { requireKnowledgeApi, withUnconfiguredFallback, type ResolvedBuiltinPanelDeps } from './shared.ts';
5
5
 
6
6
  export function registerKnowledgePanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
7
- // KnowledgeGraphPanel is a no-arg panel — always register it regardless of memoryRegistry.
8
7
  manager.registerType({
9
8
  id: 'knowledge',
10
9
  name: 'Knowledge',
11
10
  icon: 'K',
12
11
  category: 'agent',
13
- description: 'Structured project knowledge: risks, runbooks, architecture notes, incidents, and durable facts',
14
- factory: () => new KnowledgeGraphPanel(),
12
+ description: 'Live SDK knowledge graph: nodes, sources, issue review queue, and search',
13
+ factory: () => new KnowledgeGraphPanel(requireKnowledgeApi(deps), () => manager.open('memory')),
15
14
  });
16
- if (deps.memoryRegistry) {
15
+ // WO-152: always registered (was gated behind `if (deps.memoryRegistry)`,
16
+ // so `/panel open memory` reported "Unknown panel" on builds without a
17
+ // memory registry wired). Falls back to a "dependency not configured"
18
+ // empty state.
19
+ {
17
20
  const { memoryRegistry } = deps;
18
21
  manager.registerType({
19
22
  id: 'memory',
@@ -21,7 +24,13 @@ export function registerKnowledgePanels(manager: PanelManager, deps: ResolvedBui
21
24
  icon: 'M',
22
25
  category: 'agent',
23
26
  description: 'Project memory: decisions, constraints, incidents, and patterns with provenance links',
24
- factory: () => new MemoryPanel(memoryRegistry),
27
+ factory: withUnconfiguredFallback(
28
+ memoryRegistry !== undefined,
29
+ 'memory', 'Memory', 'M', 'agent',
30
+ ' Memory registry not configured for this session.',
31
+ 'This runtime was not wired with a project memory registry at bootstrap, so no memory data is available.',
32
+ () => new MemoryPanel(memoryRegistry!),
33
+ ),
25
34
  });
26
35
  }
27
36
  }