@pellux/goodvibes-agent 0.1.101 → 0.1.103

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 (43) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +10 -0
  3. package/docs/README.md +1 -1
  4. package/docs/getting-started.md +17 -3
  5. package/package.json +1 -18
  6. package/src/cli/help.ts +86 -0
  7. package/src/cli/local-library-command.ts +516 -0
  8. package/src/cli/management.ts +17 -0
  9. package/src/cli/memory-command.ts +646 -0
  10. package/src/cli/package-verification.ts +10 -0
  11. package/src/cli/parser.ts +8 -0
  12. package/src/cli/types.ts +3 -0
  13. package/src/input/agent-workspace-setup.ts +2 -2
  14. package/src/input/agent-workspace-snapshot.ts +4 -4
  15. package/src/input/agent-workspace-types.ts +2 -2
  16. package/src/input/command-registry.ts +0 -8
  17. package/src/input/feed-context-factory.ts +1 -3
  18. package/src/input/handler-feed.ts +1 -4
  19. package/src/input/handler-interactions.ts +0 -1
  20. package/src/input/handler-modal-stack.ts +0 -1
  21. package/src/input/handler-modal-token-routes.ts +0 -11
  22. package/src/input/handler-picker-routes.ts +11 -20
  23. package/src/input/handler-ui-state.ts +0 -6
  24. package/src/input/handler.ts +1 -17
  25. package/src/main.ts +0 -6
  26. package/src/panels/builtin/agent.ts +0 -17
  27. package/src/panels/index.ts +0 -2
  28. package/src/renderer/agent-workspace.ts +3 -3
  29. package/src/renderer/conversation-overlays.ts +0 -6
  30. package/src/renderer/live-tail-modal.ts +10 -69
  31. package/src/renderer/process-modal.ts +28 -530
  32. package/src/runtime/bootstrap-command-parts.ts +0 -28
  33. package/src/runtime/bootstrap-core.ts +1 -1
  34. package/src/runtime/bootstrap.ts +3 -12
  35. package/src/runtime/services.ts +3 -4
  36. package/src/tools/{wrfc-agent-guard.ts → agent-tool-policy-guard.ts} +0 -6
  37. package/src/version.ts +1 -1
  38. package/src/panels/agent-inspector-panel.ts +0 -521
  39. package/src/panels/agent-inspector-shared.ts +0 -94
  40. package/src/panels/agent-logs-panel.ts +0 -559
  41. package/src/panels/agent-logs-shared.ts +0 -129
  42. package/src/renderer/agent-detail-modal.ts +0 -331
  43. package/src/renderer/process-summary.ts +0 -67
package/src/cli/parser.ts CHANGED
@@ -21,6 +21,14 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
21
21
  provider: 'providers',
22
22
  profiles: 'profiles',
23
23
  profile: 'profiles',
24
+ personas: 'personas',
25
+ persona: 'personas',
26
+ skills: 'skills',
27
+ skill: 'skills',
28
+ 'agent-skills': 'skills',
29
+ memory: 'memory',
30
+ memories: 'memory',
31
+ recall: 'memory',
24
32
  routines: 'routines',
25
33
  routine: 'routines',
26
34
  auth: 'auth',
package/src/cli/types.ts CHANGED
@@ -7,6 +7,9 @@ export type GoodVibesCliCommand =
7
7
  | 'models'
8
8
  | 'providers'
9
9
  | 'profiles'
10
+ | 'personas'
11
+ | 'skills'
12
+ | 'memory'
10
13
  | 'routines'
11
14
  | 'auth'
12
15
  | 'compat'
@@ -11,7 +11,7 @@ export interface AgentWorkspaceSetupChecklistItem {
11
11
  export interface AgentWorkspaceSetupChecklistInput {
12
12
  readonly provider: string;
13
13
  readonly model: string;
14
- readonly daemonBaseUrl: string;
14
+ readonly runtimeBaseUrl: string;
15
15
  readonly sessionMemoryCount: number;
16
16
  readonly routineCount: number;
17
17
  readonly enabledRoutineCount: number;
@@ -39,7 +39,7 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
39
39
  id: 'runtime',
40
40
  label: 'GoodVibes runtime',
41
41
  status: 'ready',
42
- detail: `Agent will connect to ${input.daemonBaseUrl}; runtime ownership stays outside this product.`,
42
+ detail: `Agent will connect to ${input.runtimeBaseUrl}; runtime ownership stays outside this product.`,
43
43
  command: '/health',
44
44
  },
45
45
  {
@@ -252,7 +252,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
252
252
  const ttsVoice = readConfigString(context, 'tts.voice', '(voice default)');
253
253
  const ttsLlmProvider = readConfigString(context, 'tts.llmProvider', '');
254
254
  const ttsLlmModel = readConfigString(context, 'tts.llmModel', '');
255
- const daemonBaseUrl = `http://${host}:${port}`;
255
+ const runtimeBaseUrl = `http://${host}:${port}`;
256
256
  const channels = buildAgentWorkspaceChannels(context);
257
257
  const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
258
258
  context,
@@ -262,7 +262,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
262
262
  const setupChecklist = buildAgentWorkspaceSetupChecklist({
263
263
  provider,
264
264
  model,
265
- daemonBaseUrl,
265
+ runtimeBaseUrl,
266
266
  sessionMemoryCount,
267
267
  routineCount: routineSnapshot.count,
268
268
  enabledRoutineCount: routineSnapshot.enabled,
@@ -285,8 +285,8 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
285
285
  sessionId: context.session?.runtime?.sessionId ?? 'unknown',
286
286
  workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? 'unavailable',
287
287
  homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? 'unavailable',
288
- daemonBaseUrl,
289
- daemonOwnership: 'external',
288
+ runtimeBaseUrl,
289
+ runtimeOwnership: 'external',
290
290
  sessionMemoryCount,
291
291
  localRoutineCount: routineSnapshot.count,
292
292
  enabledRoutineCount: routineSnapshot.enabled,
@@ -120,8 +120,8 @@ export interface AgentWorkspaceRuntimeSnapshot {
120
120
  readonly sessionId: string;
121
121
  readonly workingDirectory: string;
122
122
  readonly homeDirectory: string;
123
- readonly daemonBaseUrl: string;
124
- readonly daemonOwnership: 'external';
123
+ readonly runtimeBaseUrl: string;
124
+ readonly runtimeOwnership: 'external';
125
125
  readonly sessionMemoryCount: number;
126
126
  readonly localRoutineCount: number;
127
127
  readonly enabledRoutineCount: number;
@@ -108,19 +108,11 @@ export interface CommandShellUiOpeners {
108
108
  showPanel?: (panelId: string, pane?: 'top' | 'bottom') => void;
109
109
  focusPanels?: () => void;
110
110
  focusPrompt?: () => void;
111
- openOpsPanel?: () => void;
112
- openCockpitPanel?: () => void;
113
- openOrchestrationPanel?: () => void;
114
- openForensicsPanel?: () => void;
115
- openIncidentPanel?: () => void;
116
111
  openPolicyPanel?: () => void;
117
- openHooksPanel?: () => void;
118
- openCommunicationPanel?: () => void;
119
112
  openMcpWorkspace?: () => void;
120
113
  openAgentWorkspace?: () => void;
121
114
  openSecurityPanel?: () => void;
122
115
  openKnowledgePanel?: () => void;
123
- openRemotePanel?: () => void;
124
116
  openSubscriptionPanel?: () => void;
125
117
  }
126
118
 
@@ -25,7 +25,6 @@ import type { ConversationManager } from '../core/conversation';
25
25
  import type { ProcessModal } from '../renderer/process-modal.ts';
26
26
  import type { LiveTailModal } from '../renderer/live-tail-modal.ts';
27
27
  import type { BlockActionsMenu } from '../renderer/block-actions.ts';
28
- import type { AgentDetailModal } from '../renderer/agent-detail-modal.ts';
29
28
  import type { ContextInspectorModal } from '../renderer/context-inspector.ts';
30
29
  import type { BookmarkModal } from './bookmark-modal.ts';
31
30
  import type { SettingsModal } from './settings-modal.ts';
@@ -83,7 +82,7 @@ export interface FeedContextMutableInit {
83
82
  * - `selectionModal`, `bookmarkModal`, `settingsModal`, `sessionPickerModal`,
84
83
  * `profilePickerModal` — modal objects constructed once
85
84
  * - `filePicker`, `modelPicker`, `processModal`, `liveTailModal`,
86
- * `agentDetailModal`, `contextInspectorModal`, `blockActionsMenu`,
85
+ * `contextInspectorModal`, `blockActionsMenu`,
87
86
  * `searchManager`, `historySearch`, `onboardingWizard` — service objects constructed once
88
87
  * - `panelManager`, `keybindingsManager` — from uiServices, stable
89
88
  * - `modalStack` — reference to the handler's shared array
@@ -117,7 +116,6 @@ export interface FeedContextStableRefs {
117
116
  onboardingWizard: OnboardingWizardController;
118
117
  processModal: ProcessModal;
119
118
  liveTailModal: LiveTailModal;
120
- agentDetailModal: AgentDetailModal;
121
119
  contextInspectorModal: ContextInspectorModal;
122
120
  blockActionsMenu: BlockActionsMenu;
123
121
  searchManager: SearchManager;
@@ -12,7 +12,6 @@ import type { BlockMeta, ConversationManager } from '../core/conversation';
12
12
  import { ProcessModal } from '../renderer/process-modal.ts';
13
13
  import { LiveTailModal } from '../renderer/live-tail-modal.ts';
14
14
  import { BlockActionsMenu } from '../renderer/block-actions.ts';
15
- import { AgentDetailModal } from '../renderer/agent-detail-modal.ts';
16
15
  import { ContextInspectorModal } from '../renderer/context-inspector.ts';
17
16
  import { BookmarkModal } from './bookmark-modal.ts';
18
17
  import { SettingsModal } from './settings-modal.ts';
@@ -73,7 +72,7 @@ import type { ModelPickerTarget } from './model-picker.ts';
73
72
  * - `selectionModal`, `bookmarkModal`, `settingsModal`, `sessionPickerModal`,
74
73
  * `profilePickerModal` — modal objects constructed once in InputHandler constructor
75
74
  * - `filePicker`, `modelPicker`, `onboardingWizard`, `processModal`, `liveTailModal`,
76
- * `agentDetailModal`, `contextInspectorModal`, `blockActionsMenu`, `searchManager`, `historySearch` —
75
+ * `contextInspectorModal`, `blockActionsMenu`, `searchManager`, `historySearch` —
77
76
  * service objects constructed once
78
77
  * - `panelManager`, `keybindingsManager` — from uiServices, stable for app lifetime
79
78
  * - `modalStack` — reference to the handler's shared array (mutated in place)
@@ -121,7 +120,6 @@ export interface InputFeedContext {
121
120
  readonly onboardingWizard: OnboardingWizardController;
122
121
  readonly processModal: ProcessModal;
123
122
  readonly liveTailModal: LiveTailModal;
124
- readonly agentDetailModal: AgentDetailModal;
125
123
  readonly contextInspectorModal: ContextInspectorModal;
126
124
  readonly blockActionsMenu: BlockActionsMenu;
127
125
  readonly searchManager: SearchManager;
@@ -211,7 +209,6 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
211
209
  handleEscape: context.handleEscape,
212
210
  liveTailModal: context.liveTailModal,
213
211
  processModal: context.processModal,
214
- agentDetailModal: context.agentDetailModal,
215
212
  contextInspectorModal: context.contextInspectorModal,
216
213
  modalOpened: context.modalOpened,
217
214
  filePicker: context.filePicker,
@@ -235,7 +235,6 @@ export function handleEscapeForHandler(handler: InputHandler): void {
235
235
  helpOverlayActive: handler.helpOverlayActive,
236
236
  shortcutsOverlayActive: handler.shortcutsOverlayActive,
237
237
  bookmarkModal: handler.bookmarkModal,
238
- agentDetailModal: handler.agentDetailModal,
239
238
  liveTailModal: handler.liveTailModal,
240
239
  settingsModal: handler.settingsModal,
241
240
  mcpWorkspace: handler.mcpWorkspace,
@@ -121,7 +121,6 @@ export function handleEscape(state: EscapeState): {
121
121
  shortcutsScrollOffset = 0;
122
122
  },
123
123
  closeBookmark: () => state.bookmarkModal.close(),
124
- closeAgentDetail: () => state.agentDetailModal.close(),
125
124
  closeLiveTail: () => state.liveTailModal.close(),
126
125
  closeSettings: () => state.settingsModal.close(),
127
126
  closeMcpWorkspace: () => state.mcpWorkspace?.close(),
@@ -12,7 +12,6 @@ import { handleMcpWorkspaceToken, type McpWorkspace } from './mcp-workspace.ts';
12
12
  import type { CommandContext } from './command-registry.ts';
13
13
  import type { LiveTailModal } from '../renderer/live-tail-modal.ts';
14
14
  import type { ProcessModal } from '../renderer/process-modal.ts';
15
- import type { AgentDetailModal } from '../renderer/agent-detail-modal.ts';
16
15
  import type { ContextInspectorModal } from '../renderer/context-inspector.ts';
17
16
  import type { FilePickerModal } from './file-picker.ts';
18
17
  import type { BlockActionsMenu, BlockActionId } from '../renderer/block-actions.ts';
@@ -65,7 +64,6 @@ export type ModalTokenRouteState = {
65
64
  handleEscape: () => void;
66
65
  liveTailModal: LiveTailModal;
67
66
  processModal: ProcessModal;
68
- agentDetailModal: AgentDetailModal;
69
67
  contextInspectorModal: ContextInspectorModal;
70
68
  modalOpened: (name: string) => void;
71
69
  filePicker: FilePickerModal;
@@ -240,14 +238,6 @@ export function handleModalTokenRoutes(state: ModalTokenRouteState, token: Input
240
238
  return withState(state, true);
241
239
  }
242
240
 
243
- if (handleEscapeOnlyModalToken({
244
- active: state.agentDetailModal.active,
245
- requestRender: state.requestRender,
246
- handleEscape: state.handleEscape,
247
- }, token)) {
248
- return withState(state, true);
249
- }
250
-
251
241
  if (handleEscapeOnlyModalToken({
252
242
  active: state.contextInspectorModal.active,
253
243
  requestRender: state.requestRender,
@@ -259,7 +249,6 @@ export function handleModalTokenRoutes(state: ModalTokenRouteState, token: Input
259
249
  if (handleProcessModalToken({
260
250
  processModal: state.processModal,
261
251
  liveTailModal: state.liveTailModal,
262
- agentDetailModal: state.agentDetailModal,
263
252
  modalOpened: state.modalOpened,
264
253
  requestRender: state.requestRender,
265
254
  handleEscape: state.handleEscape,
@@ -204,15 +204,12 @@ type ProcessRouteState = {
204
204
  getSelected: () => ProcessEntry | undefined;
205
205
  close: () => void;
206
206
  open: () => void;
207
- killSelected: () => boolean;
207
+ stopSelected: () => boolean;
208
208
  refresh: () => void;
209
209
  };
210
210
  liveTailModal: {
211
211
  open: (entry: ProcessEntry) => void;
212
212
  };
213
- agentDetailModal: {
214
- open: (id: string) => void;
215
- };
216
213
  modalOpened: (name: string) => void;
217
214
  requestRender: () => void;
218
215
  handleEscape: () => void;
@@ -231,20 +228,14 @@ export function handleProcessModalToken(state: ProcessRouteState, token: InputTo
231
228
  else if (token.logicalName === 'enter') {
232
229
  const entry = state.processModal.getSelected();
233
230
  if (entry) {
234
- if (entry.type === 'agent') {
235
- state.modalOpened('agentDetail');
236
- state.processModal.close();
237
- state.agentDetailModal.open(entry.id);
238
- } else {
239
- state.modalOpened('liveTail');
240
- state.processModal.close();
241
- state.liveTailModal.open(entry);
242
- }
231
+ state.modalOpened('liveTail');
232
+ state.processModal.close();
233
+ state.liveTailModal.open(entry);
243
234
  }
244
235
  }
245
236
  } else if (token.type === 'text' && token.value === 'k') {
246
- const killed = state.processModal.killSelected();
247
- if (killed) state.processModal.refresh();
237
+ const stopped = state.processModal.stopSelected();
238
+ if (stopped) state.processModal.refresh();
248
239
  }
249
240
 
250
241
  state.requestRender();
@@ -256,7 +247,7 @@ type LiveTailRouteState = {
256
247
  active: boolean;
257
248
  scrollUp: () => void;
258
249
  scrollDown: () => void;
259
- killProcess: () => boolean;
250
+ stopProcess: () => boolean;
260
251
  close: () => void;
261
252
  };
262
253
  processModal: {
@@ -269,8 +260,8 @@ type LiveTailRouteState = {
269
260
  export function handleLiveTailToken(state: LiveTailRouteState, token: InputToken): boolean {
270
261
  if (!state.liveTailModal.active) return false;
271
262
 
272
- const killAndReturn = (): void => {
273
- if (state.liveTailModal.killProcess()) state.handleEscape();
263
+ const stopAndReturn = (): void => {
264
+ if (state.liveTailModal.stopProcess()) state.handleEscape();
274
265
  };
275
266
 
276
267
  if (token.type === 'key') {
@@ -280,9 +271,9 @@ export function handleLiveTailToken(state: LiveTailRouteState, token: InputToken
280
271
  }
281
272
  if (token.logicalName === 'up') state.liveTailModal.scrollUp();
282
273
  else if (token.logicalName === 'down') state.liveTailModal.scrollDown();
283
- else if (token.logicalName === 'k') killAndReturn();
274
+ else if (token.logicalName === 'k') stopAndReturn();
284
275
  } else if (token.type === 'text' && token.value === 'k') {
285
- killAndReturn();
276
+ stopAndReturn();
286
277
  }
287
278
 
288
279
  state.requestRender();
@@ -55,7 +55,6 @@ export type ActiveModalState = {
55
55
  helpOverlayActive: boolean;
56
56
  shortcutsOverlayActive: boolean;
57
57
  bookmarkModal: { active: boolean; close: () => void };
58
- agentDetailModal: { active: boolean; close: () => void };
59
58
  liveTailModal: { active: boolean; close: () => void };
60
59
  settingsModal: { active: boolean; close: () => void };
61
60
  mcpWorkspace?: { active: boolean; close: () => void; reopen: () => void };
@@ -76,7 +75,6 @@ export function getActiveModalName(state: ActiveModalState): string | null {
76
75
  if (state.helpOverlayActive) return 'help';
77
76
  if (state.shortcutsOverlayActive) return 'shortcuts';
78
77
  if (state.bookmarkModal.active) return 'bookmark';
79
- if (state.agentDetailModal.active) return 'agentDetail';
80
78
  if (state.liveTailModal.active) return 'liveTail';
81
79
  if (state.settingsModal.active) return 'settings';
82
80
  if (state.mcpWorkspace?.active) return 'mcpWorkspace';
@@ -98,7 +96,6 @@ export type ModalCloseOps = {
98
96
  resetHelp: () => void;
99
97
  resetShortcuts: () => void;
100
98
  closeBookmark: () => void;
101
- closeAgentDetail: () => void;
102
99
  closeLiveTail: () => void;
103
100
  closeSettings: () => void;
104
101
  closeMcpWorkspace: () => void;
@@ -126,9 +123,6 @@ export function closeModalByName(name: string, ops: ModalCloseOps): void {
126
123
  case 'bookmark':
127
124
  ops.closeBookmark();
128
125
  break;
129
- case 'agentDetail':
130
- ops.closeAgentDetail();
131
- break;
132
126
  case 'liveTail':
133
127
  ops.closeLiveTail();
134
128
  break;
@@ -21,14 +21,12 @@ import type { BlockMeta, ConversationManager } from '../core/conversation';
21
21
  import { ProcessModal } from '../renderer/process-modal.ts';
22
22
  import { LiveTailModal } from '../renderer/live-tail-modal.ts';
23
23
  import { BlockActionsMenu } from '../renderer/block-actions.ts';
24
- import { AgentDetailModal } from '../renderer/agent-detail-modal.ts';
25
24
  import { ContextInspectorModal } from '../renderer/context-inspector.ts';
26
25
  import { BookmarkModal } from './bookmark-modal.ts';
27
26
  import { SettingsModal } from './settings-modal.ts';
28
27
  import { McpWorkspace } from './mcp-workspace.ts';
29
28
  import { AgentWorkspace } from './agent-workspace.ts';
30
29
  import { SessionPickerModal } from './session-picker-modal.ts';
31
- import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
32
30
  import { ProfilePickerModal } from './profile-picker-modal.ts';
33
31
  import { OnboardingWizardController, type OnboardingWizardAction, type OnboardingWizardMode } from './onboarding/onboarding-wizard.ts';
34
32
  import {
@@ -155,7 +153,6 @@ export class InputHandler {
155
153
  public searchManager = new SearchManager();
156
154
  public processModal: ProcessModal;
157
155
  public liveTailModal: LiveTailModal;
158
- public agentDetailModal: AgentDetailModal;
159
156
  public contextInspectorModal = new ContextInspectorModal();
160
157
  public bookmarkModal: BookmarkModal;
161
158
  public blockActionsMenu = new BlockActionsMenu();
@@ -220,8 +217,7 @@ export class InputHandler {
220
217
  public scroll: (delta: number) => void,
221
218
  public exitApp: () => void,
222
219
  public readonly uiServices: Pick<UiRuntimeServices,
223
- 'agents'
224
- | 'environment'
220
+ 'environment'
225
221
  | 'platform'
226
222
  | 'providers'
227
223
  | 'sessions'
@@ -235,22 +231,11 @@ export class InputHandler {
235
231
  uiServices.providers.providerRegistry,
236
232
  );
237
233
  this.processModal = new ProcessModal({
238
- agentManager: uiServices.agents.agentManager,
239
234
  processManager: uiServices.shell.processManager,
240
- wrfcController: uiServices.agents.wrfcController,
241
- agentEntries: 'hidden',
242
235
  });
243
236
  this.liveTailModal = new LiveTailModal({
244
- agentManager: uiServices.agents.agentManager,
245
237
  processManager: uiServices.shell.processManager,
246
238
  });
247
- this.agentDetailModal = new AgentDetailModal({
248
- agentManager: uiServices.agents.agentManager,
249
- agentMessageBus: uiServices.agents.agentMessageBus,
250
- sessionLogPathResolver: (agentId) => uiServices.environment.shellPaths.resolveProjectPath(GOODVIBES_AGENT_SURFACE_ROOT, 'sessions', `${agentId}.jsonl`),
251
- // SDK 0.23.0: supply wrfcController so the modal can show constraint data
252
- wrfcController: uiServices.agents.wrfcController,
253
- });
254
239
  this.bookmarkModal = new BookmarkModal(uiServices.shell.bookmarkManager);
255
240
  this.sessionPickerModal = new SessionPickerModal(uiServices.sessions.sessionManager);
256
241
  this.profilePickerModal = new ProfilePickerModal(uiServices.shell.profileManager);
@@ -294,7 +279,6 @@ export class InputHandler {
294
279
  onboardingWizard: this.onboardingWizard,
295
280
  processModal: this.processModal,
296
281
  liveTailModal: this.liveTailModal,
297
- agentDetailModal: this.agentDetailModal,
298
282
  contextInspectorModal: this.contextInspectorModal,
299
283
  blockActionsMenu: this.blockActionsMenu,
300
284
  searchManager: this.searchManager,
package/src/main.ts CHANGED
@@ -398,11 +398,6 @@ async function main() {
398
398
  scroll,
399
399
  exitApp,
400
400
  {
401
- agents: {
402
- agentManager,
403
- agentMessageBus: ctx.services.agentMessageBus,
404
- wrfcController: ctx.services.wrfcController,
405
- },
406
401
  providers: {
407
402
  benchmarkStore: ctx.services.benchmarkStore,
408
403
  favoritesStore: ctx.services.favoritesStore,
@@ -450,7 +445,6 @@ async function main() {
450
445
  input.setConversationManager(conversation);
451
446
  input.setContentWidth(getPromptContentWidth());
452
447
  input.filePicker.setOnUpdate(() => render());
453
- input.agentDetailModal.setOnRefresh(() => render());
454
448
  input.processModal.setOnRefresh(() => render());
455
449
 
456
450
  // Model picker callback is handled in bootstrap.ts — do not duplicate here.
@@ -1,5 +1,4 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
- import { AgentLogsPanel } from '../agent-logs-panel.ts';
3
2
  import { ContextVisualizerPanel } from '../context-visualizer-panel.ts';
4
3
  import { ThinkingPanel } from '../thinking-panel.ts';
5
4
  import { ToolInspectorPanel } from '../tool-inspector-panel.ts';
@@ -50,22 +49,6 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
50
49
  ),
51
50
  });
52
51
 
53
- manager.registerType({
54
- id: 'agent-logs',
55
- name: 'Agents',
56
- icon: 'A',
57
- category: 'agent',
58
- description: 'View-only stream for explicit delegated build/review session records',
59
- preload: true,
60
- factory: () => {
61
- const ui = requireUiServices(deps);
62
- return new AgentLogsPanel(ui.events.agents, {
63
- agentManager: ui.agents.agentManager,
64
- workingDirectory: ui.environment.workingDirectory,
65
- });
66
- },
67
- });
68
-
69
52
  manager.registerType({
70
53
  id: 'work-plan',
71
54
  name: 'Work Plan',
@@ -4,8 +4,6 @@ export { BasePanel } from './base-panel.ts';
4
4
  export { PanelManager } from './panel-manager.ts';
5
5
  export { TokenBudgetPanel } from './token-budget-panel.ts';
6
6
  export { CostTrackerPanel } from './cost-tracker-panel.ts';
7
- export { AgentInspectorPanel } from './agent-inspector-panel.ts';
8
- export { AgentLogsPanel } from './agent-logs-panel.ts';
9
7
  export { ProviderHealthPanel } from './provider-health-panel.ts';
10
8
  export { ProviderHealthTracker } from './provider-health-tracker.ts';
11
9
  export type { ProviderHealth, ProviderStatus } from './provider-health-tracker.ts';
@@ -194,8 +194,8 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
194
194
  );
195
195
  } else if (category.id === 'setup') {
196
196
  base.push(
197
- { text: `GoodVibes runtime: ${snapshot.daemonBaseUrl}`, fg: PALETTE.info },
198
- { text: `Runtime owner: ${snapshot.daemonOwnership}; Agent connects but never starts or restarts it`, fg: PALETTE.good },
197
+ { text: `GoodVibes runtime: ${snapshot.runtimeBaseUrl}`, fg: PALETTE.info },
198
+ { text: `Runtime owner: ${snapshot.runtimeOwnership}; Agent connects but never starts or restarts it`, fg: PALETTE.good },
199
199
  ...setupChecklistLines(snapshot),
200
200
  { text: '' },
201
201
  { text: `Workspace: ${snapshot.workingDirectory}`, fg: PALETTE.muted },
@@ -216,7 +216,7 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
216
216
  ...snapshot.channels.filter((channel) => !channel.enabled),
217
217
  ].slice(0, 6);
218
218
  base.push(
219
- { text: `GoodVibes runtime: ${snapshot.daemonBaseUrl}`, fg: PALETTE.info },
219
+ { text: `GoodVibes runtime: ${snapshot.runtimeBaseUrl}`, fg: PALETTE.info },
220
220
  { text: `Readiness: ${readyCount}/${snapshot.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} default target(s) configured.`, fg: PALETTE.info },
221
221
  { text: `Ready channels: ${readyChannels.join(', ') || 'none'}.`, fg: readyChannels.length > 0 ? PALETTE.good : PALETTE.warn },
222
222
  { text: `Needs default target: ${needsTarget.map((channel) => `${channel.label} -> ${channel.defaultTargetKeys.join('|')}`).join(', ') || 'none'}.`, fg: needsTarget.length > 0 ? PALETTE.warn : PALETTE.muted },
@@ -9,7 +9,6 @@ import { renderSelectionModalOverlay } from './selection-modal-overlay.ts';
9
9
  import { renderSearchOverlay } from './search-overlay.ts';
10
10
  import { renderHistorySearchOverlay } from './history-search-overlay.ts';
11
11
  import { renderProcessModal } from './process-modal.ts';
12
- import { renderAgentDetailModal } from './agent-detail-modal.ts';
13
12
  import { renderLiveTailModal } from './live-tail-modal.ts';
14
13
  import { renderContextInspector } from './context-inspector.ts';
15
14
  import { renderSettingsModal } from './settings-modal.ts';
@@ -74,11 +73,6 @@ export function applyConversationOverlays(
74
73
  next = overlayViewportBottom(next, lines, conversationWidth, viewportHeight, bottomDockInset);
75
74
  }
76
75
 
77
- if (input.agentDetailModal.active) {
78
- const lines = renderAgentDetailModal(input.agentDetailModal, conversationWidth);
79
- next = overlayViewportBottom(next, lines, conversationWidth, viewportHeight, bottomDockInset);
80
- }
81
-
82
76
  if (input.liveTailModal.active) {
83
77
  const lines = renderLiveTailModal(input.liveTailModal, conversationWidth, viewportHeight);
84
78
  next = overlayViewportBottom(next, lines, conversationWidth, viewportHeight, bottomDockInset);
@@ -1,28 +1,16 @@
1
1
  import { type Line } from '../types/grid.ts';
2
2
  import { ModalFactory } from './modal-factory.ts';
3
3
  import type { ProcessManager } from '@pellux/goodvibes-sdk/platform/tools';
4
- import type { AgentManager } from '@pellux/goodvibes-sdk/platform/tools';
5
4
  import type { ProcessEntry } from './process-modal.ts';
6
5
  import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay-viewport.ts';
7
6
 
8
7
  export interface LiveTailModalDeps {
9
- readonly agentManager: Pick<AgentManager, 'getStatus'>;
10
8
  readonly processManager: Pick<ProcessManager, 'stop' | 'getOutput'>;
11
9
  }
12
10
 
13
- // ─── LiveTailModal ────────────────────────────────────────────────────────────
14
-
15
- /**
16
- * LiveTailModal — manages state for the live output peek modal.
17
- *
18
- * Shows streaming stdout/stderr from a selected shell process or agent
19
- * progress notes. Auto-scrolls to the bottom unless the user scrolled up.
20
- */
21
11
  export class LiveTailModal {
22
12
  public active = false;
23
13
  public entry: ProcessEntry | null = null;
24
-
25
- /** Number of lines scrolled up from the bottom (0 = at bottom). */
26
14
  public scrollOffset = 0;
27
15
 
28
16
  constructor(private readonly deps: LiveTailModalDeps) {}
@@ -40,64 +28,27 @@ export class LiveTailModal {
40
28
  }
41
29
 
42
30
  scrollUp(): void {
43
- this.scrollOffset++;
31
+ this.scrollOffset += 1;
44
32
  }
45
33
 
46
34
  scrollDown(): void {
47
35
  this.scrollOffset = Math.max(0, this.scrollOffset - 1);
48
36
  }
49
37
 
50
- /**
51
- * Stop the current shell process when it is an exec entry.
52
- * Agent entries are read-only in GoodVibes Agent; build execution and
53
- * cancellation belong to GoodVibes TUI/shared-session owners.
54
- */
55
- killProcess(): boolean {
38
+ stopProcess(): boolean {
56
39
  if (!this.entry) return false;
57
-
58
- if (this.entry.type === 'exec') {
59
- return this.deps.processManager.stop(this.entry.id);
60
- }
61
- return false;
40
+ return this.deps.processManager.stop(this.entry.id);
62
41
  }
63
42
 
64
- /** Retrieve the current output text for the watched process. */
65
43
  getOutput(): string {
66
44
  if (!this.entry) return '';
67
-
68
- if (this.entry.type === 'exec') {
69
- const out = this.deps.processManager.getOutput(this.entry.id);
70
- if (!out) return '';
71
- const combined = [out.stdout, out.stderr].filter(Boolean).join('\n').trim();
72
- return combined || '(no output yet)';
73
- } else {
74
- // For agents, show progress note and status
75
- const rec = this.deps.agentManager.getStatus(this.entry.id);
76
- if (!rec) return '(process not found)';
77
- const parts: string[] = [
78
- `Task: ${rec.task}`,
79
- `Status: ${rec.status}`,
80
- `Tool calls: ${rec.toolCallCount}`,
81
- ];
82
- if (rec.progress) parts.push(`Progress: ${rec.progress}`);
83
- if (rec.error) parts.push(`Error: ${rec.error}`);
84
- return parts.join('\n');
85
- }
45
+ const output = this.deps.processManager.getOutput(this.entry.id);
46
+ if (!output) return '';
47
+ const combined = [output.stdout, output.stderr].filter(Boolean).join('\n').trim();
48
+ return combined || '(no output yet)';
86
49
  }
87
50
  }
88
51
 
89
- // ─── renderLiveTailModal ──────────────────────────────────────────────────────
90
-
91
- /**
92
- * Render the live-tail peek modal as Line[] for overlay in the viewport.
93
- *
94
- * Shows a scrollable view of the process output. scrollOffset=0 means the
95
- * bottom of the output is visible (auto-scroll behaviour).
96
- *
97
- * @param modal LiveTailModal state
98
- * @param width Terminal width
99
- * @param maxOutputLines Maximum lines to show inside the box (default: 16)
100
- */
101
52
  export function renderLiveTailModal(
102
53
  modal: LiveTailModal,
103
54
  width: number,
@@ -115,35 +66,25 @@ export function renderLiveTailModal(
115
66
 
116
67
  const output = modal.getOutput();
117
68
  const allLines = output.split('\n');
118
-
119
- // Apply scroll: scrollOffset=0 → show tail; larger → scroll toward head
120
69
  const totalLines = allLines.length;
121
- // Clamp scrollOffset so we never scroll past the top of the content
122
70
  const maxScroll = Math.max(0, totalLines - maxOutputLines);
123
71
  const clampedOffset = Math.min(modal.scrollOffset, maxScroll);
124
72
  const endIdx = Math.max(maxOutputLines, totalLines - clampedOffset);
125
73
  const startIdx = Math.max(0, endIdx - maxOutputLines);
126
74
  const visibleLines = allLines.slice(startIdx, endIdx);
127
75
 
128
- const typeTag = entry.type === 'agent' ? '[agent]' : '[exec]';
129
76
  const maxLabelW = Math.max(20, width - 30);
130
- const title = `${typeTag} ${entry.label.slice(0, maxLabelW)}`;
131
-
132
- // Build scroll indicator for text section header
77
+ const title = `[exec] ${entry.label.slice(0, maxLabelW)}`;
133
78
  const scrollInfo = totalLines > maxOutputLines
134
79
  ? ` Lines ${startIdx + 1}-${Math.min(endIdx, totalLines)} of ${totalLines} [Up/Down] Scroll`
135
80
  : '';
136
81
 
137
- const contentText = visibleLines.join('\n') || '(no output yet)';
138
-
139
82
  const sections: import('./modal-factory.ts').ModalSection[] = [];
140
-
141
83
  if (scrollInfo) {
142
84
  sections.push({ type: 'text', content: scrollInfo });
143
85
  sections.push({ type: 'separator' });
144
86
  }
145
-
146
- sections.push({ type: 'text', content: contentText });
87
+ sections.push({ type: 'text', content: visibleLines.join('\n') || '(no output yet)' });
147
88
 
148
89
  return ModalFactory.createModal({
149
90
  title,
@@ -151,6 +92,6 @@ export function renderLiveTailModal(
151
92
  margin: 2,
152
93
  targetContentRows,
153
94
  sections,
154
- hints: ['[Up/Down] Scroll', '[k] Stop exec only', '[Esc] Back'],
95
+ hints: ['[Up/Down] Scroll', '[k] Stop process', '[Esc] Back'],
155
96
  }, width);
156
97
  }