@pellux/goodvibes-agent 1.4.4 → 1.5.1
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.
- package/CHANGELOG.md +22 -0
- package/README.md +52 -7
- package/dist/package/main.js +7491 -12253
- package/docs/README.md +2 -2
- package/docs/channels-remote-and-api.md +1 -1
- package/docs/getting-started.md +2 -2
- package/docs/release-and-publishing.md +1 -1
- package/docs/tools-and-commands.md +5 -5
- package/package.json +4 -2
- package/release/live-verification/live-verification.json +13 -13
- package/release/live-verification/live-verification.md +15 -15
- package/release/performance-snapshot.json +2 -2
- package/release/release-notes.md +5 -7
- package/release/release-readiness.json +6 -6
- package/src/agent/behavior-discovery-summary.ts +4 -18
- package/src/agent/calendar-registry.ts +322 -0
- package/src/agent/competitive-feature-inventory.ts +268 -130
- package/src/agent/document-registry.ts +5 -1
- package/src/agent/email/email-service.ts +350 -0
- package/src/agent/email/imap-client.ts +596 -0
- package/src/agent/email/smtp-client.ts +453 -0
- package/src/agent/ics-calendar.ts +662 -0
- package/src/agent/ics-timezone.ts +172 -0
- package/src/agent/markdown-frontmatter.ts +31 -0
- package/src/agent/memory-safety.ts +1 -1
- package/src/agent/note-registry.ts +3 -9
- package/src/agent/persona-discovery.ts +3 -15
- package/src/agent/persona-registry.ts +1 -10
- package/src/agent/research-source-registry.ts +5 -1
- package/src/agent/routine-discovery.ts +3 -15
- package/src/agent/runtime-profile.ts +3 -0
- package/src/agent/skill-discovery.ts +3 -15
- package/src/agent/skill-draft-proposer.ts +203 -0
- package/src/agent/skill-draft-runner.ts +201 -0
- package/src/agent/skill-registry.ts +36 -1
- package/src/agent/skill-standard.ts +99 -0
- package/src/agent/vibe-file.ts +7 -22
- package/src/cli/completion.ts +1 -1
- package/src/cli/config-overrides.ts +10 -1
- package/src/cli/redaction.ts +17 -5
- package/src/config/provider-model.ts +2 -1
- package/src/config/secret-config.ts +13 -6
- package/src/core/activity-feed.ts +97 -0
- package/src/core/away-digest.ts +161 -0
- package/src/core/conversation-rendering.ts +7 -3
- package/src/core/conversation.ts +22 -15
- package/src/core/hardware-profile.ts +362 -0
- package/src/core/last-seen-store.ts +78 -0
- package/src/core/plain-language.ts +52 -0
- package/src/core/setup-incomplete-hint.ts +90 -0
- package/src/core/system-message-router.ts +38 -87
- package/src/input/agent-workspace-basic-command-editor-submission.ts +60 -220
- package/src/input/agent-workspace-basic-command-editors.ts +39 -141
- package/src/input/agent-workspace-categories.ts +40 -125
- package/src/input/agent-workspace-command-editor.ts +4 -0
- package/src/input/agent-workspace-host-category.ts +0 -5
- package/src/input/agent-workspace-local-editor-submission.ts +3 -1
- package/src/input/agent-workspace-navigation.ts +10 -3
- package/src/input/agent-workspace-onboarding-actions.ts +132 -0
- package/src/input/agent-workspace-onboarding-categories.ts +29 -26
- package/src/input/agent-workspace-onboarding-finish.ts +11 -4
- package/src/input/agent-workspace-onboarding-state.ts +111 -0
- package/src/input/agent-workspace-profile-editor-submission.ts +260 -0
- package/src/input/agent-workspace-profile-editors.ts +155 -0
- package/src/input/agent-workspace-subscription-editor.ts +7 -0
- package/src/input/agent-workspace-types.ts +5 -1
- package/src/input/agent-workspace.ts +65 -39
- package/src/input/command-registry.ts +18 -5
- package/src/input/commands/agent-runtime-profile-runtime.ts +2 -1
- package/src/input/commands/agent-skills-runtime.ts +60 -3
- package/src/input/commands/calendar-runtime.ts +209 -0
- package/src/input/commands/channels-runtime.ts +1 -0
- package/src/input/commands/command-error.ts +9 -0
- package/src/input/commands/compat-runtime.ts +1 -0
- package/src/input/commands/config.ts +1 -0
- package/src/input/commands/conversation-runtime.ts +1 -1
- package/src/input/commands/delegation-runtime.ts +5 -6
- package/src/input/commands/email-runtime.ts +387 -0
- package/src/input/commands/experience-runtime.ts +17 -4
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-runtime.ts +6 -1
- package/src/input/commands/knowledge-format.ts +73 -0
- package/src/input/commands/knowledge.ts +9 -74
- package/src/input/commands/local-provider-runtime.ts +2 -1
- package/src/input/commands/local-runtime.ts +10 -4
- package/src/input/commands/mcp-runtime.ts +7 -0
- package/src/input/commands/notify-runtime.ts +17 -1
- package/src/input/commands/onboarding-runtime.ts +1 -0
- package/src/input/commands/operator-actions-runtime.ts +1 -0
- package/src/input/commands/operator-runtime.ts +3 -0
- package/src/input/commands/personas-runtime.ts +1 -0
- package/src/input/commands/platform-access-runtime.ts +40 -17
- package/src/input/commands/product-runtime.ts +6 -1
- package/src/input/commands/provider-accounts-runtime.ts +3 -2
- package/src/input/commands/qrcode-runtime.ts +1 -0
- package/src/input/commands/routines-runtime.ts +1 -0
- package/src/input/commands/runtime-services.ts +0 -13
- package/src/input/commands/security-runtime.ts +1 -0
- package/src/input/commands/session-content.ts +1 -0
- package/src/input/commands/shell-core.ts +5 -2
- package/src/input/commands/subscription-runtime.ts +33 -9
- package/src/input/commands/support-bundle-runtime.ts +8 -1
- package/src/input/commands/tasks-runtime.ts +1 -0
- package/src/input/commands/tts-runtime.ts +1 -0
- package/src/input/commands/vibe-runtime.ts +1 -0
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +3 -12
- package/src/input/handler-command-route.ts +7 -60
- package/src/input/handler-feed-routes.ts +0 -194
- package/src/input/handler-feed.ts +2 -54
- package/src/input/handler-interactions.ts +0 -2
- package/src/input/handler-modal-stack.ts +0 -9
- package/src/input/handler-picker-routes.ts +24 -1
- package/src/input/handler-shortcuts.ts +11 -40
- package/src/input/handler-ui-state.ts +13 -0
- package/src/input/handler.ts +8 -35
- package/src/input/keybindings.ts +40 -17
- package/src/input/model-picker-local-fit.ts +130 -0
- package/src/input/shell-passthrough.ts +58 -0
- package/src/input/submission-router.ts +0 -5
- package/src/main.ts +129 -90
- package/src/renderer/activity-sidebar.ts +186 -0
- package/src/renderer/agent-workspace-context-lines.ts +5 -48
- package/src/renderer/agent-workspace-style.ts +1 -1
- package/src/renderer/agent-workspace.ts +14 -2
- package/src/renderer/compositor.ts +37 -125
- package/src/renderer/conversation-overlays.ts +3 -3
- package/src/renderer/help-overlay.ts +7 -5
- package/src/renderer/model-workspace.ts +101 -86
- package/src/{panels → renderer}/polish.ts +3 -3
- package/src/renderer/shell-surface.ts +4 -5
- package/src/renderer/status-token.ts +31 -11
- package/src/renderer/tab-strip.ts +1 -1
- package/src/renderer/tool-call.ts +7 -8
- package/src/renderer/tool-labels.ts +92 -0
- package/src/renderer/ui-factory.ts +48 -96
- package/src/runtime/bootstrap-command-context.ts +0 -5
- package/src/runtime/bootstrap-command-parts.ts +6 -15
- package/src/runtime/bootstrap-core.ts +34 -13
- package/src/runtime/bootstrap-hook-bridge.ts +3 -1
- package/src/runtime/bootstrap-shell.ts +3 -50
- package/src/runtime/bootstrap.ts +3 -4
- package/src/runtime/context.ts +1 -1
- package/src/runtime/diagnostics/panels/index.ts +0 -1
- package/src/runtime/diagnostics/panels/policy.ts +1 -1
- package/src/runtime/execution-ledger.ts +16 -1
- package/src/runtime/index.ts +6 -1
- package/src/runtime/onboarding/index.ts +1 -0
- package/src/runtime/onboarding/onboarding-state.ts +200 -0
- package/src/{panels → runtime}/provider-account-snapshot.ts +5 -2
- package/src/runtime/services.ts +16 -4
- package/src/runtime/terminal-output-guard.ts +7 -0
- package/src/runtime/tool-permission-safety.ts +1 -1
- package/src/runtime/ui/model-picker/data-provider.ts +1 -1
- package/src/runtime/ui/model-picker/health-enrichment.ts +2 -2
- package/src/runtime/ui/model-picker/types.ts +2 -2
- package/src/runtime/ui/provider-health/data-provider.ts +3 -3
- package/src/runtime/ui/provider-health/types.ts +2 -2
- package/src/runtime/ui-services.ts +0 -2
- package/src/shell/agent-workspace-fullscreen.ts +0 -1
- package/src/shell/autonomy-surfacing.ts +272 -0
- package/src/shell/session-continuity-hints.ts +0 -6
- package/src/shell/startup-wiring.ts +221 -0
- package/src/shell/ui-openers.ts +18 -29
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-harness-background-processes.ts +4 -4
- package/src/tools/agent-harness-browser-cockpit-route.ts +3 -3
- package/src/tools/agent-harness-command-runner.ts +6 -1
- package/src/tools/agent-harness-document-ops.ts +26 -53
- package/src/tools/agent-harness-execution-history.ts +1 -13
- package/src/tools/agent-harness-execution-posture.ts +0 -15
- package/src/tools/agent-harness-keybinding-metadata.ts +28 -29
- package/src/tools/agent-harness-local-model-cookbook.ts +24 -1
- package/src/tools/agent-harness-metadata.ts +16 -0
- package/src/tools/agent-harness-mode-catalog.ts +2 -9
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-setup-posture-utils.ts +1 -1
- package/src/tools/agent-harness-tool-schema.ts +13 -14
- package/src/tools/agent-harness-tool.ts +27 -23
- package/src/tools/agent-harness-ui-surface-metadata.ts +10 -20
- package/src/tools/agent-harness-workspace-action-runner.ts +3 -4
- package/src/tools/agent-workspace-tool.ts +2 -33
- package/src/utils/terminal-width.ts +9 -3
- package/src/version.ts +1 -1
- package/src/input/agent-workspace-panel-route.ts +0 -44
- package/src/input/panel-integration-actions.ts +0 -26
- package/src/panels/approval-panel.ts +0 -149
- package/src/panels/automation-control-panel.ts +0 -212
- package/src/panels/base-panel.ts +0 -254
- package/src/panels/builtin/agent.ts +0 -58
- package/src/panels/builtin/knowledge.ts +0 -26
- package/src/panels/builtin/operations.ts +0 -121
- package/src/panels/builtin/session.ts +0 -138
- package/src/panels/builtin/shared.ts +0 -275
- package/src/panels/builtin/usage.ts +0 -21
- package/src/panels/builtin-panels.ts +0 -23
- package/src/panels/confirm-state.ts +0 -61
- package/src/panels/context-visualizer-panel.ts +0 -204
- package/src/panels/cost-tracker-panel.ts +0 -444
- package/src/panels/docs-panel.ts +0 -285
- package/src/panels/index.ts +0 -25
- package/src/panels/knowledge-panel.ts +0 -417
- package/src/panels/memory-panel.ts +0 -226
- package/src/panels/panel-list-panel.ts +0 -464
- package/src/panels/panel-manager.ts +0 -570
- package/src/panels/provider-accounts-panel.ts +0 -233
- package/src/panels/provider-health-domains.ts +0 -208
- package/src/panels/provider-health-panel.ts +0 -720
- package/src/panels/provider-health-tracker.ts +0 -115
- package/src/panels/provider-stats-panel.ts +0 -366
- package/src/panels/qr-panel.ts +0 -207
- package/src/panels/schedule-panel.ts +0 -321
- package/src/panels/scrollable-list-panel.ts +0 -491
- package/src/panels/search-focus.ts +0 -32
- package/src/panels/security-panel.ts +0 -295
- package/src/panels/session-browser-panel.ts +0 -395
- package/src/panels/session-maintenance.ts +0 -125
- package/src/panels/subscription-panel.ts +0 -263
- package/src/panels/system-messages-panel.ts +0 -230
- package/src/panels/tasks-panel.ts +0 -344
- package/src/panels/thinking-panel.ts +0 -304
- package/src/panels/token-budget-panel.ts +0 -475
- package/src/panels/tool-inspector-panel.ts +0 -436
- package/src/panels/types.ts +0 -54
- package/src/renderer/panel-composite.ts +0 -158
- package/src/renderer/panel-tab-bar.ts +0 -69
- package/src/renderer/panel-workspace-bar.ts +0 -42
- package/src/runtime/diagnostics/panels/panel-resources.ts +0 -118
- package/src/tools/agent-harness-panel-metadata.ts +0 -211
- /package/src/runtime/perf/{panel-health-monitor.ts → component-health.ts} +0 -0
|
@@ -3,9 +3,10 @@ import { LAYOUT, TOOL_STATUS } from './layout.ts';
|
|
|
3
3
|
import { getDisplayWidth, truncateDisplay } from '../utils/terminal-width.ts';
|
|
4
4
|
import type { ToolCall } from '@pellux/goodvibes-sdk/platform/types';
|
|
5
5
|
import { stripDangerousAnsi } from './ansi-sanitize.ts';
|
|
6
|
+
import { friendlyToolLabel } from './tool-labels.ts';
|
|
6
7
|
|
|
7
8
|
const TOOL_NAME_MIN_WIDTH = 8;
|
|
8
|
-
const TOOL_NAME_MAX_WIDTH =
|
|
9
|
+
const TOOL_NAME_MAX_WIDTH = 30;
|
|
9
10
|
|
|
10
11
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
11
12
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
@@ -137,11 +138,11 @@ function extractKeyArg(toolCall: ToolCall): string {
|
|
|
137
138
|
if (url) return url;
|
|
138
139
|
}
|
|
139
140
|
// Agent
|
|
140
|
-
if (typeof args.task === 'string') return args.task.slice(0, 40);
|
|
141
|
+
if (typeof args.task === 'string') return [...args.task].slice(0, 40).join('');
|
|
141
142
|
if (typeof args.mode === 'string') return args.mode;
|
|
142
143
|
// Fallback: first string value
|
|
143
144
|
for (const val of Object.values(args)) {
|
|
144
|
-
if (typeof val === 'string' && val.length > 0) return val.slice(0, 40);
|
|
145
|
+
if (typeof val === 'string' && val.length > 0) return [...val].slice(0, 40).join('');
|
|
145
146
|
}
|
|
146
147
|
return '';
|
|
147
148
|
}
|
|
@@ -200,13 +201,11 @@ export function renderToolCallBlock(
|
|
|
200
201
|
}
|
|
201
202
|
col += 2; // icon + space
|
|
202
203
|
|
|
203
|
-
//
|
|
204
|
-
const rawName = toolCall.name
|
|
205
|
-
? toolCall.name.split('__').pop()!
|
|
206
|
-
: toolCall.name;
|
|
204
|
+
// Human phrase for the tool ("Searching the web") instead of the raw name.
|
|
205
|
+
const rawName = friendlyToolLabel(toolCall.name);
|
|
207
206
|
const keyArg = stripDangerousAnsi(extractKeyArg(toolCall));
|
|
208
207
|
const suffixText = status === 'error' && errorMsg
|
|
209
|
-
? `- ${stripDangerousAnsi(errorMsg).slice(0, 40)}`
|
|
208
|
+
? `- ${[...stripDangerousAnsi(errorMsg)].slice(0, 40).join('')}`
|
|
210
209
|
: status === 'done' && resultSummary
|
|
211
210
|
? `(${stripDangerousAnsi(resultSummary)})`
|
|
212
211
|
: '';
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Friendly tool labels — turn internal tool names into the phrase a person
|
|
3
|
+
* would say. Shown on tool-call lines in the conversation; the raw tool name
|
|
4
|
+
* is still discoverable in the Agent workspace tool catalog.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const TOOL_LABELS: Record<string, string> = {
|
|
8
|
+
// SDK file/shell/web tools
|
|
9
|
+
read: 'Reading files',
|
|
10
|
+
write: 'Writing a file',
|
|
11
|
+
edit: 'Editing a file',
|
|
12
|
+
exec: 'Running a command',
|
|
13
|
+
fetch: 'Fetching a web page',
|
|
14
|
+
web_search: 'Searching the web',
|
|
15
|
+
find: 'Searching files',
|
|
16
|
+
analyze: 'Analyzing code',
|
|
17
|
+
inspect: 'Inspecting files',
|
|
18
|
+
|
|
19
|
+
// Agent first-class tools
|
|
20
|
+
personal_ops: 'Checking your inbox & calendar',
|
|
21
|
+
research: 'Researching',
|
|
22
|
+
agent_research_runs: 'Researching',
|
|
23
|
+
agent_research_sources: 'Reviewing sources',
|
|
24
|
+
agent_research_report: 'Writing a research report',
|
|
25
|
+
schedule: 'Checking schedules',
|
|
26
|
+
agent_schedule_edit: 'Updating a schedule',
|
|
27
|
+
agent_autonomy_schedule: 'Scheduling background work',
|
|
28
|
+
agent_reminder_schedule: 'Setting a reminder',
|
|
29
|
+
autonomy: 'Checking background work',
|
|
30
|
+
channels: 'Checking message channels',
|
|
31
|
+
agent_channel_send: 'Sending a message',
|
|
32
|
+
notify: 'Sending a notification',
|
|
33
|
+
memory: 'Recalling memory',
|
|
34
|
+
agent_knowledge: 'Searching knowledge',
|
|
35
|
+
agent_knowledge_ingest: 'Saving to knowledge',
|
|
36
|
+
agent_learning_consolidation: 'Consolidating what I learned',
|
|
37
|
+
agent_local_registry: 'Checking notes & routines',
|
|
38
|
+
models: 'Checking models',
|
|
39
|
+
agent_model_compare: 'Comparing models',
|
|
40
|
+
settings: 'Adjusting settings',
|
|
41
|
+
agent_settings_import: 'Importing settings',
|
|
42
|
+
setup: 'Checking setup',
|
|
43
|
+
security: 'Reviewing safety',
|
|
44
|
+
sessions: 'Looking at past conversations',
|
|
45
|
+
computer: 'Using the browser',
|
|
46
|
+
device: 'Checking this device',
|
|
47
|
+
host: 'Checking the assistant service',
|
|
48
|
+
execution: 'Managing background work',
|
|
49
|
+
terminal_process: 'Watching a process',
|
|
50
|
+
support: 'Preparing a support bundle',
|
|
51
|
+
vibe: 'Reading your VIBE profile',
|
|
52
|
+
workspace: 'Driving the workspace',
|
|
53
|
+
agent_harness: 'Checking app internals',
|
|
54
|
+
route: 'Choosing the best route',
|
|
55
|
+
delegation: 'Handing work off',
|
|
56
|
+
audit: 'Reviewing evidence',
|
|
57
|
+
context: 'Reading project context',
|
|
58
|
+
agent_documents: 'Working on a document',
|
|
59
|
+
agent_artifacts: 'Managing saved files',
|
|
60
|
+
agent_media_generate: 'Generating media',
|
|
61
|
+
agent_operator_method: 'Calling the assistant service',
|
|
62
|
+
agent_operator_briefing: 'Preparing a briefing',
|
|
63
|
+
agent_operator_action: 'Running an approved action',
|
|
64
|
+
agent_work_plan: 'Organizing work',
|
|
65
|
+
agent_review_packet_presets: 'Preparing a review packet',
|
|
66
|
+
agent_review_packet_share: 'Sharing a review packet',
|
|
67
|
+
propose_skill_drafts: 'Proposing skill drafts',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Exported catalog of all registered tool IDs and their human phrases.
|
|
72
|
+
* Tests import this to enumerate the full set of tool IDs for coverage checks.
|
|
73
|
+
*/
|
|
74
|
+
export const TOOL_LABELS_CATALOG: Readonly<Record<string, string>> = TOOL_LABELS;
|
|
75
|
+
|
|
76
|
+
function humanize(name: string): string {
|
|
77
|
+
const short = name.includes('__') ? name.split('__').pop()! : name;
|
|
78
|
+
return (short
|
|
79
|
+
.replace(/^agent[_-]/, '')
|
|
80
|
+
.replace(/[_-]+/g, ' ')
|
|
81
|
+
.trim())
|
|
82
|
+
.replace(/^./, (c) => c.toUpperCase());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Return the human phrase for a tool call, falling back to a humanized
|
|
87
|
+
* version of the raw name for unknown tools (including MCP tools).
|
|
88
|
+
*/
|
|
89
|
+
export function friendlyToolLabel(toolName: string): string {
|
|
90
|
+
const short = toolName.includes('__') ? toolName.split('__').pop()! : toolName;
|
|
91
|
+
return TOOL_LABELS[short] ?? TOOL_LABELS[toolName] ?? humanize(toolName);
|
|
92
|
+
}
|
|
@@ -215,113 +215,65 @@ export class UIFactory {
|
|
|
215
215
|
const bottomLine = createBaseLine();
|
|
216
216
|
for (let x = 0; x < boxWidth; x++) bottomLine[boxStartX + x] = { char: GLYPHS.surface.bottom, fg: BORDER_COLOR, bg: '', bold: false, dim: false, underline: false, italic: false, strikethrough: false };
|
|
217
217
|
lines.push(bottomLine);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (composerMode) composerTokens.push({ text: ` ${GLYPHS.status.active} ${composerMode} `, fg: '#38bdf8', bold: true });
|
|
221
|
-
if (composerPendingRisk && composerPendingRisk !== 'none') {
|
|
222
|
-
const riskColor = composerPendingRisk === 'approval-wait'
|
|
223
|
-
? '#f59e0b'
|
|
224
|
-
: composerPendingRisk === 'shell'
|
|
225
|
-
? '#ef4444'
|
|
226
|
-
: composerPendingRisk === 'remote'
|
|
227
|
-
? '#a78bfa'
|
|
228
|
-
: '#f59e0b';
|
|
229
|
-
composerTokens.push({ text: ` risk:${composerPendingRisk} `, fg: riskColor, bold: true });
|
|
230
|
-
}
|
|
231
|
-
if (composerStatus && composerStatus !== 'idle') composerTokens.push({ text: ` state:${composerStatus} `, fg: '244', dim: true });
|
|
232
|
-
if (composerFlags && composerFlags.length > 0) composerTokens.push({ text: ` flags:${composerFlags.join(',')} `, fg: '244', dim: true });
|
|
233
|
-
if (composerTokens.length > 0) {
|
|
234
|
-
const postureLine = createBaseLine();
|
|
235
|
-
let px = 2;
|
|
236
|
-
for (const token of composerTokens) {
|
|
237
|
-
for (const ch of token.text) {
|
|
238
|
-
if (px >= width) break;
|
|
239
|
-
postureLine[px] = {
|
|
240
|
-
char: ch,
|
|
241
|
-
fg: token.fg,
|
|
242
|
-
bg: '',
|
|
243
|
-
bold: token.bold ?? false,
|
|
244
|
-
dim: token.dim ?? false,
|
|
245
|
-
underline: false,
|
|
246
|
-
italic: false,
|
|
247
|
-
strikethrough: false,
|
|
248
|
-
};
|
|
249
|
-
px += getDisplayWidth(ch);
|
|
250
|
-
}
|
|
251
|
-
if (px >= width) break;
|
|
252
|
-
}
|
|
253
|
-
lines.push(postureLine);
|
|
254
|
-
lines.push(createBaseLine());
|
|
255
|
-
}
|
|
218
|
+
|
|
219
|
+
// ── Status line: model · context meter · tokens, with alerts on the right ──
|
|
256
220
|
const isRecentlyCopied = Date.now() - lastCopyTime < 2000;
|
|
257
|
-
|
|
258
|
-
const u = usage as { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; up?: number; down?: number };
|
|
221
|
+
const u = usage as { input?: number; output?: number; up?: number; down?: number };
|
|
259
222
|
const inp = u.input ?? u.up ?? 0;
|
|
260
223
|
const out = u.output ?? u.down ?? 0;
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const tokenLine = ` Token Usage [ Input: ${fmtNum(inp)}${tokenSep}Output: ${fmtNum(out)}${tokenSep}Cache Read: ${fmtNum(cr)}${tokenSep}Cache Write: ${fmtNum(cw)}${tokenSep}Total: ${fmtNum(total)} ]`;
|
|
266
|
-
const copiedNotice = isRecentlyCopied ? ` [COPIED] ` : '';
|
|
267
|
-
const statsLine = ' ' + tokenLine + ' '.repeat(Math.max(0, width - 4 - getDisplayWidth(tokenLine) - getDisplayWidth(copiedNotice))) + copiedNotice;
|
|
268
|
-
lines.push(this.stringToLine(statsLine, width, { fg: isRecentlyCopied ? '81' : '244', bold: isRecentlyCopied }));
|
|
269
|
-
// Context usage progress bar
|
|
224
|
+
const statusTokens: Array<{ text: string; fg: string; bold?: boolean }> = [];
|
|
225
|
+
if (model) {
|
|
226
|
+
statusTokens.push({ text: provider ? `${model} · ${provider}` : model, fg: '245' });
|
|
227
|
+
}
|
|
270
228
|
if (contextWindow && contextWindow > 0) {
|
|
271
229
|
const ctxTokens = lastInputTokens ?? 0;
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
230
|
+
const pct = Math.min(100, Math.round((ctxTokens / contextWindow) * 100));
|
|
231
|
+
const filled = Math.round((pct / 100) * 6);
|
|
232
|
+
const meter = GLYPHS.meter.filled.repeat(filled) + GLYPHS.meter.empty.repeat(6 - filled);
|
|
233
|
+
const meterFg = pct >= 85 ? '#ef4444' : pct >= 65 ? '#f59e0b' : '240';
|
|
234
|
+
statusTokens.push({ text: `context ${meter} ${pct}%`, fg: meterFg, bold: pct >= 85 });
|
|
235
|
+
}
|
|
236
|
+
if (inp > 0 || out > 0) {
|
|
237
|
+
statusTokens.push({ text: `↑${fmtNum(inp)} ↓${fmtNum(out)}`, fg: '240' });
|
|
238
|
+
}
|
|
239
|
+
if (composerPendingRisk === 'approval-wait') {
|
|
240
|
+
statusTokens.push({ text: 'waiting for your approval', fg: '#f59e0b', bold: true });
|
|
278
241
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
242
|
+
const rightNotice = isRecentlyCopied
|
|
243
|
+
? { text: `copied ${GLYPHS.status.success} `, fg: '81', bold: true }
|
|
244
|
+
: dangerMode
|
|
245
|
+
? { text: '⚠ auto-approve is on ', fg: '#ef4444', bold: true }
|
|
246
|
+
: null;
|
|
247
|
+
const statusLine = createBaseLine();
|
|
248
|
+
let sx = 3;
|
|
249
|
+
const writeStatusText = (text: string, fg: string, bold = false) => {
|
|
250
|
+
for (const ch of text) {
|
|
251
|
+
if (sx >= width - 1) break;
|
|
252
|
+
statusLine[sx] = { char: ch, fg, bg: '', bold, dim: false, underline: false, italic: false, strikethrough: false };
|
|
253
|
+
sx += getDisplayWidth(ch);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
statusTokens.forEach((token, index) => {
|
|
257
|
+
if (index > 0) writeStatusText(` ${GLYPHS.navigation.pipeSeparator} `, '238');
|
|
258
|
+
writeStatusText(token.text, token.fg, token.bold ?? false);
|
|
259
|
+
});
|
|
260
|
+
if (rightNotice) {
|
|
261
|
+
let col = Math.max(sx + 2, width - getDisplayWidth(rightNotice.text));
|
|
262
|
+
for (const ch of rightNotice.text) {
|
|
263
|
+
if (col >= width) break;
|
|
264
|
+
statusLine[col] = { char: ch, fg: rightNotice.fg, bg: '', bold: rightNotice.bold ?? false, dim: false, underline: false, italic: false, strikethrough: false };
|
|
265
|
+
col += getDisplayWidth(ch);
|
|
289
266
|
}
|
|
290
|
-
if (toolCount) ctxParts.push(`${toolCount} tools`);
|
|
291
|
-
if (hitlMode) ctxParts.push(`hitl:${hitlMode}`);
|
|
292
|
-
if (composerMode) ctxParts.push(`mode:${composerMode}`);
|
|
293
|
-
if (composerStatus && composerStatus !== 'idle') ctxParts.push(`status:${composerStatus}`);
|
|
294
|
-
if (composerFlags && composerFlags.length > 0) ctxParts.push(composerFlags.join(','));
|
|
295
|
-
const ctxLine = ' ' + ctxParts.join(` ${GLYPHS.navigation.pipeSeparator} `);
|
|
296
|
-
lines.push(createBaseLine());
|
|
297
|
-
lines.push(this.stringToLine(truncateDisplay(ctxLine, width), width, { fg: '240', dim: true }));
|
|
298
|
-
lines.push(createBaseLine());
|
|
299
267
|
}
|
|
268
|
+
lines.push(statusLine);
|
|
269
|
+
|
|
270
|
+
// ── Hints line ──
|
|
300
271
|
if (showExitNotice) {
|
|
301
|
-
|
|
302
|
-
lines.push(this.stringToLine(fitDisplay(notice, width), width, { fg: '196', bold: true }));
|
|
272
|
+
lines.push(this.stringToLine(fitDisplay(' Press Ctrl+C again to exit ', width), width, { fg: '196', bold: true }));
|
|
303
273
|
} else {
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
const helpW = getDisplayWidth(help);
|
|
307
|
-
const dangerW = getDisplayWidth(dangerWarn);
|
|
308
|
-
const spacerW = Math.max(0, width - helpW - dangerW);
|
|
309
|
-
const combinedLine = help + ' '.repeat(spacerW) + dangerWarn;
|
|
310
|
-
const line = this.stringToLine(truncateDisplay(combinedLine, width), width, { fg: '240', dim: true });
|
|
311
|
-
// Overlay the danger warning in red bold
|
|
312
|
-
if (dangerMode && dangerW > 0) {
|
|
313
|
-
let col = helpW + spacerW;
|
|
314
|
-
for (const ch of dangerWarn) {
|
|
315
|
-
if (col >= width) break;
|
|
316
|
-
const cw = getDisplayWidth(ch);
|
|
317
|
-
line[col] = { char: ch, fg: '#ef4444', bg: '', bold: true, dim: false, underline: false, italic: false, strikethrough: false };
|
|
318
|
-
if (cw === 2 && col + 1 < width) line[col + 1] = { ...line[col], char: '' };
|
|
319
|
-
col += cw;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
lines.push(line);
|
|
274
|
+
const hints = ` /help commands ${GLYPHS.navigation.pipeSeparator} Ctrl+P settings ${GLYPHS.navigation.pipeSeparator} Ctrl+O activity `;
|
|
275
|
+
lines.push(this.stringToLine(truncateDisplay(hints, width), width, { fg: '240', dim: true }));
|
|
323
276
|
}
|
|
324
|
-
lines.push(createBaseLine());
|
|
325
277
|
return lines;
|
|
326
278
|
}
|
|
327
279
|
|
|
@@ -4,7 +4,6 @@ import type { ConversationManager } from '../core/conversation';
|
|
|
4
4
|
import type { KnowledgeApi } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
5
5
|
import type { HookApi } from '@pellux/goodvibes-sdk/platform/hooks';
|
|
6
6
|
import type { McpApi } from '@pellux/goodvibes-sdk/platform/mcp';
|
|
7
|
-
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
8
7
|
import type { ProviderApi } from '@pellux/goodvibes-sdk/platform/providers';
|
|
9
8
|
import type { OpsApi } from '@/runtime/index.ts';
|
|
10
9
|
import type { MutableRuntimeState } from '@/runtime/index.ts';
|
|
@@ -116,7 +115,6 @@ export type CreateBootstrapCommandContextOptions = {
|
|
|
116
115
|
mcpApi?: McpApi;
|
|
117
116
|
opsApi?: OpsApi;
|
|
118
117
|
directTransport?: DirectTransport;
|
|
119
|
-
panelManager: PanelManager;
|
|
120
118
|
worktreeRegistry: WorktreeRegistry;
|
|
121
119
|
sandboxSessionRegistry: SandboxSessionRegistry;
|
|
122
120
|
loadSystemPrompt: () => string;
|
|
@@ -192,7 +190,6 @@ export function createBootstrapCommandContext(
|
|
|
192
190
|
mcpApi,
|
|
193
191
|
opsApi,
|
|
194
192
|
directTransport,
|
|
195
|
-
panelManager,
|
|
196
193
|
worktreeRegistry,
|
|
197
194
|
sandboxSessionRegistry,
|
|
198
195
|
loadSystemPrompt,
|
|
@@ -247,7 +244,6 @@ export function createBootstrapCommandContext(
|
|
|
247
244
|
const workspace = createBootstrapCommandWorkspaceSection({
|
|
248
245
|
keybindingsManager,
|
|
249
246
|
fileUndoManager,
|
|
250
|
-
panelManager,
|
|
251
247
|
processManager,
|
|
252
248
|
profileManager,
|
|
253
249
|
bookmarkManager,
|
|
@@ -277,7 +273,6 @@ export function createBootstrapCommandContext(
|
|
|
277
273
|
conversation,
|
|
278
274
|
runtime,
|
|
279
275
|
requestRender,
|
|
280
|
-
panelManager,
|
|
281
276
|
loadSystemPrompt,
|
|
282
277
|
activatePlan,
|
|
283
278
|
requestPermission,
|
|
@@ -6,7 +6,6 @@ import type { KnowledgeApi } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
|
6
6
|
import type { AgentPromptContextReceiptStore } from '../agent/prompt-context-receipts.ts';
|
|
7
7
|
import type { HookApi } from '@pellux/goodvibes-sdk/platform/hooks';
|
|
8
8
|
import type { McpApi } from '@pellux/goodvibes-sdk/platform/mcp';
|
|
9
|
-
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
10
9
|
import type { ProviderApi } from '@pellux/goodvibes-sdk/platform/providers';
|
|
11
10
|
import type { OpsApi } from '@/runtime/index.ts';
|
|
12
11
|
import type { MutableRuntimeState } from '@/runtime/index.ts';
|
|
@@ -62,7 +61,6 @@ export interface BootstrapCommandActionOptions {
|
|
|
62
61
|
readonly conversation: ConversationManager;
|
|
63
62
|
readonly runtime: MutableRuntimeState;
|
|
64
63
|
readonly requestRender: () => void;
|
|
65
|
-
readonly panelManager: PanelManager;
|
|
66
64
|
readonly loadSystemPrompt: () => string;
|
|
67
65
|
readonly activatePlan: (planId: string, task: string) => void;
|
|
68
66
|
readonly requestPermission: PermissionRequestHandler;
|
|
@@ -76,7 +74,6 @@ export interface BootstrapCommandSectionOptions {
|
|
|
76
74
|
readonly runtime: MutableRuntimeState;
|
|
77
75
|
readonly keybindingsManager?: KeybindingsManager;
|
|
78
76
|
readonly processManager?: import('@pellux/goodvibes-sdk/platform/tools').ProcessManager;
|
|
79
|
-
readonly panelManager: PanelManager;
|
|
80
77
|
readonly requestRender: () => void;
|
|
81
78
|
readonly requestPermission: PermissionRequestHandler;
|
|
82
79
|
readonly toolRegistry: ToolRegistry;
|
|
@@ -158,7 +155,6 @@ export function createBootstrapCommandActions(
|
|
|
158
155
|
| 'print'
|
|
159
156
|
| 'exit'
|
|
160
157
|
| 'reloadSystemPrompt'
|
|
161
|
-
| 'showPanel'
|
|
162
158
|
| 'openMcpWorkspace'
|
|
163
159
|
| 'openAgentWorkspace'
|
|
164
160
|
| 'dismissAgentWorkspace'
|
|
@@ -172,17 +168,14 @@ export function createBootstrapCommandActions(
|
|
|
172
168
|
conversation,
|
|
173
169
|
runtime,
|
|
174
170
|
requestRender,
|
|
175
|
-
panelManager,
|
|
176
171
|
loadSystemPrompt,
|
|
177
172
|
activatePlan,
|
|
178
173
|
requestPermission,
|
|
179
174
|
completeModelSelectionSideEffect,
|
|
180
175
|
} = options;
|
|
181
176
|
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
panelManager.hide();
|
|
185
|
-
conversation.log(`Panel route "${panelId}" is handled through Agent Workspace. Use /agent for current operator controls.`, { fg: '214' });
|
|
177
|
+
const pointToWorkspace = (what: string) => {
|
|
178
|
+
conversation.log(`${what} lives in the Agent workspace — press Ctrl+P or run /agent.`, { fg: '214' });
|
|
186
179
|
requestRender();
|
|
187
180
|
};
|
|
188
181
|
|
|
@@ -246,18 +239,17 @@ export function createBootstrapCommandActions(
|
|
|
246
239
|
},
|
|
247
240
|
exit: () => unwiredShellAction('exit'),
|
|
248
241
|
reloadSystemPrompt: loadSystemPrompt,
|
|
249
|
-
showPanel,
|
|
250
242
|
openMcpWorkspace: () => unwiredShellAction('openMcpWorkspace'),
|
|
251
243
|
openAgentWorkspace: () => unwiredShellAction('openAgentWorkspace'),
|
|
252
244
|
dismissAgentWorkspace: () => unwiredShellAction('dismissAgentWorkspace'),
|
|
253
245
|
openSecurityPanel: () => {
|
|
254
|
-
|
|
246
|
+
pointToWorkspace('Security review');
|
|
255
247
|
},
|
|
256
248
|
openKnowledgePanel: () => {
|
|
257
|
-
|
|
249
|
+
pointToWorkspace('Knowledge');
|
|
258
250
|
},
|
|
259
251
|
openSubscriptionPanel: () => {
|
|
260
|
-
|
|
252
|
+
pointToWorkspace('Provider subscriptions');
|
|
261
253
|
},
|
|
262
254
|
};
|
|
263
255
|
}
|
|
@@ -295,7 +287,7 @@ export function createBootstrapCommandProviderSection(
|
|
|
295
287
|
export function createBootstrapCommandWorkspaceSection(
|
|
296
288
|
options: Pick<
|
|
297
289
|
BootstrapCommandSectionOptions,
|
|
298
|
-
'keybindingsManager' | 'fileUndoManager' | '
|
|
290
|
+
'keybindingsManager' | 'fileUndoManager' | 'profileManager' | 'bookmarkManager'
|
|
299
291
|
| 'processManager' | 'projectPlanningService' | 'projectPlanningProjectId' | 'workPlanStore'
|
|
300
292
|
>,
|
|
301
293
|
shellServices: BootstrapCommandShellServices,
|
|
@@ -303,7 +295,6 @@ export function createBootstrapCommandWorkspaceSection(
|
|
|
303
295
|
return {
|
|
304
296
|
keybindingsManager: options.keybindingsManager,
|
|
305
297
|
fileUndoManager: options.fileUndoManager,
|
|
306
|
-
panelManager: options.panelManager,
|
|
307
298
|
processManager: options.processManager,
|
|
308
299
|
profileManager: options.profileManager,
|
|
309
300
|
bookmarkManager: options.bookmarkManager,
|
|
@@ -6,8 +6,8 @@ import { getProviderIdFromModel } from '../config/provider-model.ts';
|
|
|
6
6
|
import { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
7
7
|
import { registerAllTools } from '@pellux/goodvibes-sdk/platform/tools';
|
|
8
8
|
import { PermissionManager, createPermissionConfigReader } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
9
|
-
import { Notifier } from '@pellux/goodvibes-sdk/platform/integrations';
|
|
10
|
-
|
|
9
|
+
import { Notifier, WebhookNotifier } from '@pellux/goodvibes-sdk/platform/integrations';
|
|
10
|
+
|
|
11
11
|
import { Compositor } from '../renderer/compositor.ts';
|
|
12
12
|
import type { PermissionRequestHandler } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
13
13
|
import type { SystemMessageRouter } from '../core/system-message-router.ts';
|
|
@@ -94,6 +94,26 @@ export interface BootstrapCoreState {
|
|
|
94
94
|
|
|
95
95
|
export type CompanionMessagePayload = Extract<SessionEvent, { type: 'COMPANION_MESSAGE_RECEIVED' }>;
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Registers the webhook notifier for the runtime session.
|
|
99
|
+
*
|
|
100
|
+
* Configures the provided WebhookNotifier with the given URL list, attaches it
|
|
101
|
+
* to the runtime bus so it receives SESSION_NOTIFICATION events, and pushes a
|
|
102
|
+
* detach() cleanup into runtimeUnsubs for shutdown. When webhookUrls is empty
|
|
103
|
+
* this function is a complete no-op.
|
|
104
|
+
*/
|
|
105
|
+
export function registerWebhookNotifier(
|
|
106
|
+
webhookNotifier: WebhookNotifier,
|
|
107
|
+
webhookUrls: string[],
|
|
108
|
+
runtimeBus: RuntimeEventBus,
|
|
109
|
+
runtimeUnsubs: Array<() => void>,
|
|
110
|
+
): void {
|
|
111
|
+
if (webhookUrls.length === 0) return;
|
|
112
|
+
webhookNotifier.setUrls(webhookUrls);
|
|
113
|
+
webhookNotifier.attachToRuntimeBus(runtimeBus);
|
|
114
|
+
runtimeUnsubs.push(() => webhookNotifier.detach());
|
|
115
|
+
}
|
|
116
|
+
|
|
97
117
|
export function companionMessageToOrchestratorInputOptions(
|
|
98
118
|
payload: CompanionMessagePayload,
|
|
99
119
|
): OrchestratorUserInputOptions {
|
|
@@ -161,7 +181,7 @@ export async function initializeBootstrapCore(
|
|
|
161
181
|
sessionId: userSessionId,
|
|
162
182
|
authenticatedAt: Date.now(),
|
|
163
183
|
lastSeenAt: Date.now(),
|
|
164
|
-
capabilities: ['session', '
|
|
184
|
+
capabilities: ['session', 'commands', 'automation'],
|
|
165
185
|
metadata: {
|
|
166
186
|
product: 'goodvibes-agent',
|
|
167
187
|
surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
|
|
@@ -176,7 +196,6 @@ export async function initializeBootstrapCore(
|
|
|
176
196
|
hookDispatcher,
|
|
177
197
|
hookWorkbench,
|
|
178
198
|
memoryStore,
|
|
179
|
-
panelManager,
|
|
180
199
|
routeBindings,
|
|
181
200
|
sessionBroker: sharedSessionBroker,
|
|
182
201
|
surfaceRegistry,
|
|
@@ -215,13 +234,7 @@ export async function initializeBootstrapCore(
|
|
|
215
234
|
getControlPlaneRecentEvents,
|
|
216
235
|
});
|
|
217
236
|
|
|
218
|
-
const conversation = new ConversationManager(() =>
|
|
219
|
-
const width = getTerminalSize(stdout).width;
|
|
220
|
-
if (panelManager.isVisible() && panelManager.getAllOpen().length > 0) {
|
|
221
|
-
return Math.max(1, panelManager.getLeftWidth(width) - 1);
|
|
222
|
-
}
|
|
223
|
-
return width;
|
|
224
|
-
});
|
|
237
|
+
const conversation = new ConversationManager(() => getTerminalSize(stdout).width);
|
|
225
238
|
conversation.setConfigManager(configManager);
|
|
226
239
|
getConversationTitle = () => conversation.title;
|
|
227
240
|
|
|
@@ -321,6 +334,11 @@ export async function initializeBootstrapCore(
|
|
|
321
334
|
});
|
|
322
335
|
|
|
323
336
|
const bootstrapUnsubs: Array<() => void> = [];
|
|
337
|
+
// D5 fix: stop the heartbeat watcher on shutdown so the setInterval is cleared.
|
|
338
|
+
// Registered here (after declaration) rather than inside the watcher block above.
|
|
339
|
+
if (configManager.get('watchers.enabled')) {
|
|
340
|
+
bootstrapUnsubs.push(() => watcherRegistry.stopWatcher('runtime-heartbeat'));
|
|
341
|
+
}
|
|
324
342
|
await memoryStore.init();
|
|
325
343
|
bootstrapUnsubs.push(() => {
|
|
326
344
|
void memoryStore.save();
|
|
@@ -420,8 +438,11 @@ export async function initializeBootstrapCore(
|
|
|
420
438
|
|
|
421
439
|
const webhookUrls = (configManager.getCategory('notifications') as { webhookUrls?: string[] }).webhookUrls ?? [];
|
|
422
440
|
if (webhookUrls.length > 0) {
|
|
423
|
-
|
|
424
|
-
|
|
441
|
+
// Reuse the services.webhookNotifier instance (constructed no-arg in services.ts).
|
|
442
|
+
// Configure it with the resolved URL list via setUrls(), attach it to the runtime
|
|
443
|
+
// bus so it receives SESSION_NOTIFICATION events, and register detach() in
|
|
444
|
+
// runtimeUnsubs so the bus subscription is cleaned up on shutdown.
|
|
445
|
+
registerWebhookNotifier(services.webhookNotifier, webhookUrls, runtimeBus, runtimeUnsubs);
|
|
425
446
|
domainDispatch.syncIntegration({
|
|
426
447
|
id: 'webhooks',
|
|
427
448
|
displayName: 'Webhooks',
|
|
@@ -52,9 +52,11 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
|
|
|
52
52
|
options.writeLastSessionPointer(sessionId);
|
|
53
53
|
void options.sharedSessionBroker.reopenSession(sessionId).catch((err) => { logger.debug('session broker reopen session failed', { err }); });
|
|
54
54
|
options.conversation.log(`Resumed session: ${sessionId}`, { fg: '135' });
|
|
55
|
-
const ignoredPanels = meta.returnContext?.openPanels?.slice(0, 4) ?? [];
|
|
56
55
|
const returnContextMode = getReturnContextMode(options.configManager);
|
|
57
56
|
if (returnContextMode !== 'off' && meta.returnContext) {
|
|
57
|
+
// N1 fix: compute ignoredPanels inside the guard so it is only evaluated
|
|
58
|
+
// when returnContext is present and the mode is not 'off'.
|
|
59
|
+
const ignoredPanels = meta.returnContext.openPanels?.slice(0, 4) ?? [];
|
|
58
60
|
for (const line of formatReturnContextForDisplay(meta.returnContext)) {
|
|
59
61
|
if (line.startsWith('Open panels:')) continue;
|
|
60
62
|
options.conversation.log(`Resume: ${line}`, { fg: '244' });
|
|
@@ -13,8 +13,7 @@ import { CommandRegistry } from '../input/command-registry.ts';
|
|
|
13
13
|
import { registerBuiltinCommands } from '../input/commands.ts';
|
|
14
14
|
import { InputHistory } from '../input/input-history.ts';
|
|
15
15
|
import type { PermissionRequestHandler } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
16
|
-
import {
|
|
17
|
-
import { SystemMessagesPanel } from '../panels/system-messages-panel.ts';
|
|
16
|
+
import { ActivityFeed } from '../core/activity-feed.ts';
|
|
18
17
|
import { createSystemMessageRouter, type SystemMessageRouter } from '../core/system-message-router.ts';
|
|
19
18
|
import { getConfigSnapshot } from '../config/index.ts';
|
|
20
19
|
import { createBootstrapCommandContext } from './bootstrap-command-context.ts';
|
|
@@ -24,7 +23,6 @@ import { loadBootstrapSystemPrompt } from '@/runtime/index.ts';
|
|
|
24
23
|
import { createShellPlanRuntime, createShellRemoteCommandService } from '@/runtime/index.ts';
|
|
25
24
|
import { createRuntimeFoundationClients } from '@/runtime/index.ts';
|
|
26
25
|
import type { ControlPlaneRecentEvent } from '@pellux/goodvibes-sdk/platform/control-plane';
|
|
27
|
-
import type { BuiltinPanelDeps } from '../panels/builtin/shared.ts';
|
|
28
26
|
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
29
27
|
import type { ForensicsRegistry } from '@/runtime/index.ts';
|
|
30
28
|
import type { PolicyRuntimeState } from '@/runtime/index.ts';
|
|
@@ -125,7 +123,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
125
123
|
completeModelSelectionSideEffect,
|
|
126
124
|
} = options;
|
|
127
125
|
|
|
128
|
-
const
|
|
126
|
+
const activityFeed = new ActivityFeed();
|
|
129
127
|
const resumeSession = createResumeSessionHandler({
|
|
130
128
|
runtimeBus,
|
|
131
129
|
runtime,
|
|
@@ -141,54 +139,10 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
141
139
|
});
|
|
142
140
|
|
|
143
141
|
let commandContextRef: CommandContext | null = null;
|
|
144
|
-
registerBuiltinPanels(services.panelManager, {
|
|
145
|
-
configManager,
|
|
146
|
-
getOrchestratorUsage: () => orchestrator.usage as { input: number; output: number; cacheRead: number; cacheWrite: number; model?: string },
|
|
147
|
-
toolRegistry,
|
|
148
|
-
providerRegistry: services.providerRegistry,
|
|
149
|
-
contextWindow: services.providerRegistry.getContextWindowForModel(services.providerRegistry.getCurrentModel()),
|
|
150
|
-
orchestrator,
|
|
151
|
-
getCtxWindow: () => services.providerRegistry.getContextWindowForModel(services.providerRegistry.getCurrentModel()),
|
|
152
|
-
resumeSession,
|
|
153
|
-
requestRender,
|
|
154
|
-
submitPlanningAnswer: (answer) => {
|
|
155
|
-
submitPlanningAnswerWithShellFallback(answer, {
|
|
156
|
-
getSubmitInput: () => commandContextRef?.submitInput,
|
|
157
|
-
addSystemMessage: (message) => conversation.addSystemMessage(message),
|
|
158
|
-
requestRender,
|
|
159
|
-
});
|
|
160
|
-
},
|
|
161
|
-
dismissPlanning: () => {
|
|
162
|
-
services.panelManager.close('project-planning');
|
|
163
|
-
commandContextRef?.focusPrompt?.();
|
|
164
|
-
requestRender();
|
|
165
|
-
},
|
|
166
|
-
forensicsRegistry,
|
|
167
|
-
policyRuntimeState,
|
|
168
|
-
approvalBroker: services.approvalBroker,
|
|
169
|
-
sessionBroker: services.sessionBroker,
|
|
170
|
-
automationManager: services.automationManager,
|
|
171
|
-
getControlPlaneRecentEvents,
|
|
172
|
-
tokenAuditor: services.tokenAuditor,
|
|
173
|
-
componentHealthMonitor: services.componentHealthMonitor,
|
|
174
|
-
worktreeRegistry: services.worktreeRegistry,
|
|
175
|
-
sandboxSessionRegistry: services.sandboxSessionRegistry,
|
|
176
|
-
systemMessagesPanel,
|
|
177
|
-
memoryRegistry: services.memoryRegistry,
|
|
178
|
-
agentKnowledgeService: services.agentKnowledgeService,
|
|
179
|
-
uiServices,
|
|
180
|
-
pluginManager: services.pluginManager,
|
|
181
|
-
hookDispatcher: services.hookDispatcher,
|
|
182
|
-
hookActivityTracker: services.hookActivityTracker,
|
|
183
|
-
hookWorkbench: services.hookWorkbench,
|
|
184
|
-
mcpRegistry: services.mcpRegistry,
|
|
185
|
-
connectedHostTokenDir: join(services.homeDirectory, '.goodvibes', 'daemon'),
|
|
186
|
-
});
|
|
187
|
-
services.panelManager.prewarmRegistered();
|
|
188
142
|
|
|
189
143
|
const systemMessageRouter = createSystemMessageRouter(
|
|
190
144
|
conversation,
|
|
191
|
-
|
|
145
|
+
activityFeed,
|
|
192
146
|
(kind) => {
|
|
193
147
|
const ui = getConfigSnapshot(configManager).ui;
|
|
194
148
|
if (kind === 'wrfc') return ui.wrfcMessages;
|
|
@@ -287,7 +241,6 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
287
241
|
mcpApi,
|
|
288
242
|
opsApi,
|
|
289
243
|
directTransport,
|
|
290
|
-
panelManager: services.panelManager,
|
|
291
244
|
worktreeRegistry: services.worktreeRegistry,
|
|
292
245
|
sandboxSessionRegistry: services.sandboxSessionRegistry,
|
|
293
246
|
loadSystemPrompt: () => loadBootstrapSystemPrompt(configManager),
|