@pellux/goodvibes-agent 0.1.117 → 1.0.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 +20 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176093 -171065
- package/docs/README.md +11 -5
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +29 -15
- package/docs/knowledge-artifacts-and-multimodal.md +91 -0
- package/docs/project-planning.md +79 -0
- package/docs/providers-and-routing.md +46 -0
- package/docs/release-and-publishing.md +44 -9
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +2 -5
- package/src/agent/channel-delivery.ts +201 -0
- package/src/agent/media-generation.ts +159 -0
- package/src/agent/memory-prompt.ts +0 -1
- package/src/agent/note-registry.ts +329 -0
- package/src/agent/operator-actions.ts +343 -0
- package/src/agent/persona-registry.ts +15 -14
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +26 -25
- package/src/agent/routine-registry.ts +13 -12
- package/src/agent/routine-schedule-args.ts +2 -1
- package/src/agent/routine-schedule-format.ts +77 -53
- package/src/agent/routine-schedule-promotion.ts +34 -32
- package/src/agent/routine-schedule-receipts.ts +28 -26
- package/src/agent/runtime-profile-starters.ts +2 -2
- package/src/agent/runtime-profile.ts +18 -17
- package/src/agent/skill-registry.ts +25 -24
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +39 -33
- package/src/cli/agent-knowledge-format.ts +80 -67
- package/src/cli/agent-knowledge-methods.ts +1 -1
- package/src/cli/agent-knowledge-runtime.ts +32 -26
- package/src/cli/bundle-command.ts +13 -8
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +29 -11
- package/src/cli/local-library-command.ts +159 -73
- package/src/cli/management-commands.ts +98 -62
- package/src/cli/management.ts +52 -26
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -24
- package/src/cli/profiles-command.ts +52 -35
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +59 -39
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +46 -121
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-activation.ts +33 -7
- package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
- package/src/input/agent-workspace-basic-command-editors.ts +30 -10
- package/src/input/agent-workspace-categories.ts +276 -64
- package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
- package/src/input/agent-workspace-channel-command-editors.ts +23 -5
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +18 -2
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
- package/src/input/agent-workspace-editors.ts +140 -2
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-knowledge-url-editor.ts +4 -11
- package/src/input/agent-workspace-learned-behavior.ts +2 -2
- package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
- package/src/input/agent-workspace-library-command-editors.ts +2 -2
- package/src/input/agent-workspace-local-operations.ts +218 -0
- package/src/input/agent-workspace-local-selection.ts +75 -0
- package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
- package/src/input/agent-workspace-media-command-editors.ts +27 -0
- package/src/input/agent-workspace-memory-command-editors.ts +1 -1
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +38 -2
- package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
- package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
- package/src/input/agent-workspace-operations-command-editors.ts +80 -3
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
- package/src/input/agent-workspace-search.ts +169 -0
- package/src/input/agent-workspace-setup.ts +22 -11
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
- package/src/input/agent-workspace-snapshot.ts +112 -13
- package/src/input/agent-workspace-task-command-editors.ts +4 -4
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +92 -4
- package/src/input/agent-workspace-voice-media.ts +3 -6
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace.ts +136 -208
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-local-library-args.ts +52 -0
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +87 -99
- package/src/input/commands/agent-workspace-runtime.ts +23 -7
- package/src/input/commands/brief-runtime.ts +25 -24
- package/src/input/commands/channels-runtime.ts +145 -31
- package/src/input/commands/delegation-runtime.ts +29 -23
- package/src/input/commands/experience-runtime.ts +6 -4
- package/src/input/commands/guidance-runtime.ts +4 -4
- package/src/input/commands/health-runtime.ts +140 -115
- package/src/input/commands/knowledge.ts +57 -56
- package/src/input/commands/local-provider-runtime.ts +36 -18
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +7 -7
- package/src/input/commands/mcp-runtime.ts +118 -50
- package/src/input/commands/notify-runtime.ts +38 -9
- package/src/input/commands/operator-actions-runtime.ts +138 -0
- package/src/input/commands/operator-runtime.ts +6 -17
- package/src/input/commands/personas-runtime.ts +49 -59
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +29 -29
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +45 -6
- package/src/input/commands/recall-bundle.ts +11 -11
- package/src/input/commands/recall-capture.ts +13 -11
- package/src/input/commands/recall-query.ts +29 -21
- package/src/input/commands/recall-review.ts +2 -1
- package/src/input/commands/routines-runtime.ts +63 -72
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +4 -4
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +132 -93
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +32 -17
- package/src/input/commands/subscription-runtime.ts +53 -179
- package/src/input/commands/tasks-runtime.ts +20 -20
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +2 -2
- package/src/input/feed-context-factory.ts +2 -1
- package/src/input/file-picker.ts +3 -2
- package/src/input/handler-command-route.ts +4 -7
- package/src/input/handler-content-actions.ts +89 -1
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -3
- package/src/input/handler-interactions.ts +7 -5
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +24 -80
- package/src/input/handler-shortcuts.ts +15 -4
- package/src/input/handler.ts +47 -17
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +22 -11
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
- package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/onboarding/onboarding-wizard.ts +68 -0
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +22 -4
- package/src/input/settings-modal-behavior.ts +0 -3
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +2 -13
- package/src/input/settings-modal.ts +6 -52
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -8
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +1 -10
- package/src/panels/builtin/session.ts +9 -9
- package/src/panels/builtin/shared.ts +2 -2
- package/src/panels/cost-tracker-panel.ts +1 -1
- package/src/panels/docs-panel.ts +5 -3
- package/src/panels/index.ts +0 -1
- package/src/panels/knowledge-panel.ts +6 -5
- package/src/panels/memory-panel.ts +7 -6
- package/src/panels/panel-list-panel.ts +36 -80
- package/src/panels/project-planning-panel.ts +18 -11
- package/src/panels/provider-account-snapshot.ts +51 -25
- package/src/panels/provider-accounts-panel.ts +33 -18
- package/src/panels/provider-health-domains.ts +45 -4
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +1 -1
- package/src/panels/schedule-panel.ts +9 -17
- package/src/panels/security-panel.ts +8 -8
- package/src/panels/session-browser-panel.ts +10 -10
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +20 -13
- package/src/panels/tool-inspector-panel.ts +19 -12
- package/src/panels/work-plan-panel.ts +5 -5
- package/src/planning/project-planning-coordinator.ts +1 -1
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +228 -52
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/bookmark-modal.ts +19 -4
- package/src/renderer/buffer.ts +4 -2
- package/src/renderer/context-inspector.ts +50 -13
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +19 -6
- package/src/renderer/help-overlay.ts +106 -33
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +164 -50
- package/src/renderer/model-picker-overlay.ts +58 -2
- package/src/renderer/model-workspace.ts +104 -20
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +20 -4
- package/src/renderer/search-overlay.ts +25 -5
- package/src/renderer/selection-modal-overlay.ts +46 -14
- package/src/renderer/session-picker-modal.ts +18 -1
- package/src/renderer/settings-modal-helpers.ts +2 -40
- package/src/renderer/settings-modal.ts +83 -50
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +6 -6
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +9 -7
- package/src/runtime/bootstrap-core.ts +19 -1
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +31 -22
- package/src/runtime/connected-host-auth.ts +7 -2
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -1
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +80 -79
- package/src/runtime/onboarding/derivation.ts +5 -8
- package/src/runtime/onboarding/snapshot.ts +0 -15
- package/src/runtime/onboarding/types.ts +8 -19
- package/src/runtime/onboarding/verify.ts +32 -10
- package/src/runtime/operator-token-cleanup.ts +1 -1
- package/src/runtime/services.ts +91 -22
- package/src/runtime/store/selectors/index.ts +3 -3
- package/src/runtime/store/state.ts +1 -4
- package/src/runtime/surface-feature-flags.ts +41 -6
- package/src/runtime/ui-read-models.ts +3 -4
- package/src/runtime/ui-services.ts +6 -6
- package/src/shell/blocking-input.ts +2 -1
- package/src/shell/ui-openers.ts +3 -13
- package/src/tools/agent-analysis-registry-policy.ts +0 -1
- package/src/tools/agent-channel-send-tool.ts +133 -0
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
- package/src/tools/agent-knowledge-tool.ts +170 -0
- package/src/tools/agent-local-registry-tool.ts +269 -69
- package/src/tools/agent-media-generate-tool.ts +133 -0
- package/src/tools/agent-notify-tool.ts +143 -0
- package/src/tools/agent-operator-action-tool.ts +137 -0
- package/src/tools/agent-operator-briefing-tool.ts +217 -0
- package/src/tools/agent-reminder-schedule-tool.ts +237 -0
- package/src/tools/agent-tool-policy-guard.ts +8 -8
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -13
- package/src/panels/panel-picker.ts +0 -105
- package/src/panels/policy-panel.ts +0 -308
- package/src/renderer/panel-picker-overlay.ts +0 -202
|
@@ -3,6 +3,45 @@ import { ModalFactory } from './modal-factory.ts';
|
|
|
3
3
|
import type { ConversationManager } from '../core/conversation';
|
|
4
4
|
import { getOverlayContentBudget, getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay-viewport.ts';
|
|
5
5
|
|
|
6
|
+
const CONTEXT_INSPECTOR_TITLE = 'Context Inspector';
|
|
7
|
+
const CONTEXT_INSPECTOR_EMPTY_MESSAGE = 'No messages in conversation yet.';
|
|
8
|
+
const CONTEXT_INSPECTOR_CLOSE_HINTS = ['[Esc] Close'];
|
|
9
|
+
const CONTEXT_INSPECTOR_CONTEXT_HINTS = ['[*] >10% of context', '[Esc] Close'];
|
|
10
|
+
const CONTEXT_INSPECTOR_FULL_WARNING = 'WARNING: context is 80%+ full. Open Agent Workspace -> Conversation -> Compact conversation.';
|
|
11
|
+
const CONTEXT_INSPECTOR_COMPACT_GUIDANCE = 'Open Agent Workspace -> Conversation -> Compact conversation to summarise and reduce context size.';
|
|
12
|
+
|
|
13
|
+
function contextInspectorTotalText(
|
|
14
|
+
totalTokens: string,
|
|
15
|
+
messageCount: string | number,
|
|
16
|
+
capacity: string | null = null,
|
|
17
|
+
): string {
|
|
18
|
+
const capacityStr = capacity ? ` | Capacity: ${totalTokens} / ${capacity}` : '';
|
|
19
|
+
return `Total: ~${totalTokens} tokens (${messageCount} messages)${capacityStr}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function contextInspectorOlderMessagesText(count: string | number): string {
|
|
23
|
+
return `(${count} older messages not shown)`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function contextInspectorCompactionHintText(count: string | number, percent: string): string {
|
|
27
|
+
const suffix = typeof count === 'number' && count === 1 ? '' : 's';
|
|
28
|
+
return `Compaction hint: ${count} message${suffix} use ${percent} of context.`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function renderContextInspectorPackageText(): string {
|
|
32
|
+
return [
|
|
33
|
+
CONTEXT_INSPECTOR_TITLE,
|
|
34
|
+
CONTEXT_INSPECTOR_EMPTY_MESSAGE,
|
|
35
|
+
contextInspectorTotalText('<tokens>', '<messages>', '<window> (<percent>)'),
|
|
36
|
+
CONTEXT_INSPECTOR_FULL_WARNING,
|
|
37
|
+
contextInspectorOlderMessagesText('<count>'),
|
|
38
|
+
contextInspectorCompactionHintText('<count>', '<percent>'),
|
|
39
|
+
CONTEXT_INSPECTOR_COMPACT_GUIDANCE,
|
|
40
|
+
...CONTEXT_INSPECTOR_CLOSE_HINTS,
|
|
41
|
+
...CONTEXT_INSPECTOR_CONTEXT_HINTS,
|
|
42
|
+
].join('\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
6
45
|
// ─── ContextInspectorModal ────────────────────────────────────────────────────
|
|
7
46
|
|
|
8
47
|
/**
|
|
@@ -67,14 +106,14 @@ export function renderContextInspector(
|
|
|
67
106
|
|
|
68
107
|
if (messages.length === 0) {
|
|
69
108
|
return ModalFactory.createModal({
|
|
70
|
-
title:
|
|
109
|
+
title: CONTEXT_INSPECTOR_TITLE,
|
|
71
110
|
width: metrics.boxWidth,
|
|
72
111
|
margin: metrics.margin,
|
|
73
112
|
targetContentRows,
|
|
74
113
|
sections: [
|
|
75
|
-
{ type: 'text', content:
|
|
114
|
+
{ type: 'text', content: CONTEXT_INSPECTOR_EMPTY_MESSAGE },
|
|
76
115
|
],
|
|
77
|
-
hints:
|
|
116
|
+
hints: CONTEXT_INSPECTOR_CLOSE_HINTS,
|
|
78
117
|
}, width);
|
|
79
118
|
}
|
|
80
119
|
|
|
@@ -139,19 +178,17 @@ export function renderContextInspector(
|
|
|
139
178
|
const sections: import('./modal-factory.ts').ModalSection[] = [];
|
|
140
179
|
|
|
141
180
|
// Summary header
|
|
142
|
-
const capacityStr = contextWindow > 0
|
|
143
|
-
? ` | Capacity: ${fmtN(totalTokens)} / ${fmtN(contextWindow)} (${fmtPct(totalTokens / contextWindow)})`
|
|
144
|
-
: '';
|
|
181
|
+
const capacityStr = contextWindow > 0 ? `${fmtN(contextWindow)} (${fmtPct(totalTokens / contextWindow)})` : null;
|
|
145
182
|
sections.push({
|
|
146
183
|
type: 'text',
|
|
147
|
-
content:
|
|
184
|
+
content: contextInspectorTotalText(fmtN(totalTokens), messages.length, capacityStr),
|
|
148
185
|
style: { bold: true },
|
|
149
186
|
});
|
|
150
187
|
|
|
151
188
|
if (contextWindow > 0 && totalTokens / contextWindow >= 0.80) {
|
|
152
189
|
sections.push({
|
|
153
190
|
type: 'text',
|
|
154
|
-
content:
|
|
191
|
+
content: CONTEXT_INSPECTOR_FULL_WARNING,
|
|
155
192
|
style: { fg: '#ff9900', bold: true },
|
|
156
193
|
});
|
|
157
194
|
}
|
|
@@ -169,7 +206,7 @@ export function renderContextInspector(
|
|
|
169
206
|
if (startOffset > 0) {
|
|
170
207
|
sections.push({
|
|
171
208
|
type: 'text',
|
|
172
|
-
content:
|
|
209
|
+
content: contextInspectorOlderMessagesText(startOffset),
|
|
173
210
|
style: { dim: true },
|
|
174
211
|
});
|
|
175
212
|
}
|
|
@@ -198,22 +235,22 @@ export function renderContextInspector(
|
|
|
198
235
|
);
|
|
199
236
|
sections.push({
|
|
200
237
|
type: 'text',
|
|
201
|
-
content:
|
|
238
|
+
content: contextInspectorCompactionHintText(largeMsgs.length, largePct),
|
|
202
239
|
style: { fg: '#00ffcc' },
|
|
203
240
|
});
|
|
204
241
|
sections.push({
|
|
205
242
|
type: 'text',
|
|
206
|
-
content:
|
|
243
|
+
content: CONTEXT_INSPECTOR_COMPACT_GUIDANCE,
|
|
207
244
|
style: { dim: true },
|
|
208
245
|
});
|
|
209
246
|
}
|
|
210
247
|
|
|
211
248
|
return ModalFactory.createModal({
|
|
212
|
-
title:
|
|
249
|
+
title: CONTEXT_INSPECTOR_TITLE,
|
|
213
250
|
width: metrics.boxWidth,
|
|
214
251
|
margin: metrics.margin,
|
|
215
252
|
targetContentRows,
|
|
216
253
|
sections,
|
|
217
|
-
hints:
|
|
254
|
+
hints: CONTEXT_INSPECTOR_CONTEXT_HINTS,
|
|
218
255
|
}, width);
|
|
219
256
|
}
|
package/src/renderer/diff.ts
CHANGED
|
@@ -31,7 +31,7 @@ export class DiffEngine {
|
|
|
31
31
|
for (let y = 0; y < newBuffer.height; y++) {
|
|
32
32
|
// Skip rows that were not written in either the old or new buffer.
|
|
33
33
|
// If neither side touched the row, both must match the prior frame:
|
|
34
|
-
// old row
|
|
34
|
+
// old row had no write this frame (clean) and new row is also
|
|
35
35
|
// clean, so the on-screen content is still correct. No diff needed.
|
|
36
36
|
const newDirty = newBuffer.dirtyRows[y] ?? false;
|
|
37
37
|
const oldDirty = oldBuffer ? (oldBuffer.dirtyRows[y] ?? false) : true;
|
|
@@ -11,6 +11,20 @@ import {
|
|
|
11
11
|
} from './overlay-box.ts';
|
|
12
12
|
import { getOverlaySurfaceMetrics } from './overlay-viewport.ts';
|
|
13
13
|
|
|
14
|
+
const FILE_PICKER_TITLE = 'Select File';
|
|
15
|
+
const FILE_PICKER_SEARCH_PREFIX = '@ ';
|
|
16
|
+
const FILE_PICKER_EMPTY_MESSAGE = 'No matching files';
|
|
17
|
+
const FILE_PICKER_HINTS = '[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel';
|
|
18
|
+
|
|
19
|
+
export function renderFilePickerPackageText(): string {
|
|
20
|
+
return [
|
|
21
|
+
FILE_PICKER_TITLE,
|
|
22
|
+
FILE_PICKER_SEARCH_PREFIX.trim(),
|
|
23
|
+
FILE_PICKER_EMPTY_MESSAGE,
|
|
24
|
+
FILE_PICKER_HINTS,
|
|
25
|
+
].join('\n');
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
/**
|
|
15
29
|
* Render the file picker modal as Line[] for overlay in the viewport.
|
|
16
30
|
* Shows a bordered box with fuzzy-matched file results.
|
|
@@ -37,13 +51,13 @@ export function renderFilePickerOverlay(
|
|
|
37
51
|
|
|
38
52
|
// Title bar
|
|
39
53
|
const titleLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
40
|
-
putOverlayText(titleLine, layout.margin + 2, layout.width - 4,
|
|
54
|
+
putOverlayText(titleLine, layout.margin + 2, layout.width - 4, FILE_PICKER_TITLE, { fg: titleFg, bold: true });
|
|
41
55
|
lines.push(titleLine);
|
|
42
56
|
|
|
43
57
|
// Search input
|
|
44
58
|
const queryDisplay = picker.query || '';
|
|
45
59
|
const searchLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
46
|
-
const searchPrefix =
|
|
60
|
+
const searchPrefix = FILE_PICKER_SEARCH_PREFIX;
|
|
47
61
|
const queryText = fitDisplay(`${queryDisplay}${picker.searchFocused ? OVERLAY_GLYPHS.cursor : ''}`, Math.max(0, contentW - getDisplayWidth(searchPrefix)));
|
|
48
62
|
putOverlayText(searchLine, layout.margin + 2, getDisplayWidth(searchPrefix), searchPrefix, { fg: picker.searchFocused ? bodyFg : mutedFg });
|
|
49
63
|
putOverlayText(searchLine, layout.margin + 2 + getDisplayWidth(searchPrefix), contentW - getDisplayWidth(searchPrefix), queryText, { fg: picker.query.length > 0 || picker.searchFocused ? bodyFg : mutedFg });
|
|
@@ -54,8 +68,8 @@ export function renderFilePickerOverlay(
|
|
|
54
68
|
|
|
55
69
|
// Results
|
|
56
70
|
if (picker.results.length === 0) {
|
|
57
|
-
|
|
58
|
-
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(
|
|
71
|
+
const noResults = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
72
|
+
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(FILE_PICKER_EMPTY_MESSAGE, contentW), { fg: '244', dim: true });
|
|
59
73
|
lines.push(noResults);
|
|
60
74
|
} else {
|
|
61
75
|
const maxVisible = metrics.contentRows;
|
|
@@ -92,9 +106,8 @@ export function renderFilePickerOverlay(
|
|
|
92
106
|
}
|
|
93
107
|
|
|
94
108
|
// Bottom border with hints
|
|
95
|
-
const hints = '[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel';
|
|
96
109
|
const bottomLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
97
|
-
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(
|
|
110
|
+
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(FILE_PICKER_HINTS, layout.width - 4), { fg: mutedFg, dim: true });
|
|
98
111
|
lines.push(bottomLine);
|
|
99
112
|
|
|
100
113
|
return lines;
|
|
@@ -12,6 +12,105 @@ import { getOverlaySurfaceMetrics } from './overlay-viewport.ts';
|
|
|
12
12
|
import { getVisibleWindow } from './surface-layout.ts';
|
|
13
13
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
14
14
|
|
|
15
|
+
const FEATURED_HELP_COMMANDS: Array<[name: string, argHint: string, desc: string]> = [
|
|
16
|
+
['agent', '', 'Open workspace; press / there to search every action'],
|
|
17
|
+
['agent', 'setup', 'Open setup workspace for local behavior, channels, and voice'],
|
|
18
|
+
['agent', 'knowledge', 'Open isolated Agent Knowledge workspace actions'],
|
|
19
|
+
['agent', 'voice-media', 'Open voice, image, browser, and media workspace actions'],
|
|
20
|
+
['setup', '', 'Open Agent setup with current settings preloaded'],
|
|
21
|
+
['knowledge', 'status', 'Inspect isolated Agent Knowledge readiness'],
|
|
22
|
+
['memory', '', 'Manage Agent-local memory records'],
|
|
23
|
+
['personas', '', 'Manage serial Agent operating personas'],
|
|
24
|
+
['skills', '', 'Manage Agent-local skills and bundles'],
|
|
25
|
+
['routines', '', 'Manage reusable main-conversation routines'],
|
|
26
|
+
['workplan', '', 'Inspect shared work-plan state'],
|
|
27
|
+
['approval', '', 'Review and explicitly act on approvals'],
|
|
28
|
+
['automation', '', 'Run confirmed connected-host automation actions'],
|
|
29
|
+
['schedule', 'remind', 'Create confirmed reminders or inspect schedules'],
|
|
30
|
+
['delegate', '', 'Explicitly hand build/fix/review work to GoodVibes TUI'],
|
|
31
|
+
['mcp', '', 'Inspect MCP servers and tool readiness'],
|
|
32
|
+
['provider', '', 'Choose provider or model family'],
|
|
33
|
+
['model', '', 'Select the active model route'],
|
|
34
|
+
['subscription', '', 'Review provider logins and subscriptions'],
|
|
35
|
+
['secrets', '', 'Manage secret references without printing values'],
|
|
36
|
+
['bundle', 'inspect', 'Inspect Agent support bundles from the TUI'],
|
|
37
|
+
['compat', '', 'Inspect connected-host and Agent Knowledge compatibility'],
|
|
38
|
+
['health', '', 'Run Agent runtime and setup diagnostics'],
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const HELP_OVERLAY_STATIC_TEXT = [
|
|
42
|
+
'Core Navigation',
|
|
43
|
+
'Scroll / history recall',
|
|
44
|
+
'Scroll by full page',
|
|
45
|
+
'Search conversation (Ctrl+F)',
|
|
46
|
+
'Prompt And Editing',
|
|
47
|
+
'Submit message',
|
|
48
|
+
'Insert newline',
|
|
49
|
+
'Paste (image priority)',
|
|
50
|
+
'Undo / redo',
|
|
51
|
+
'Overlays And Workspace',
|
|
52
|
+
'Toggle help',
|
|
53
|
+
'Full keyboard shortcuts',
|
|
54
|
+
'Open the Agent operator workspace',
|
|
55
|
+
'Search all Agent workspace actions',
|
|
56
|
+
'Open selected action or form',
|
|
57
|
+
'Quick Start',
|
|
58
|
+
'Available Slash Commands',
|
|
59
|
+
'More Commands',
|
|
60
|
+
'Essentials',
|
|
61
|
+
'Show this help overlay',
|
|
62
|
+
'Keyboard shortcut reference',
|
|
63
|
+
'Select LLM model',
|
|
64
|
+
'Clear conversation',
|
|
65
|
+
] as const;
|
|
66
|
+
|
|
67
|
+
const SHORTCUT_OVERLAY_STATIC_TEXT = [
|
|
68
|
+
'Navigation',
|
|
69
|
+
'Scroll / history recall',
|
|
70
|
+
'Scroll by full page',
|
|
71
|
+
'Jump to start / end of line',
|
|
72
|
+
'Search conversation',
|
|
73
|
+
'Scroll conversation or hovered panel',
|
|
74
|
+
'Editing',
|
|
75
|
+
'Submit message',
|
|
76
|
+
'Insert newline',
|
|
77
|
+
'Open file picker',
|
|
78
|
+
'Slash command mode',
|
|
79
|
+
'Paste (image priority)',
|
|
80
|
+
'Undo / redo',
|
|
81
|
+
'Clear prompt',
|
|
82
|
+
'Delete word backward',
|
|
83
|
+
'Kill to end of line',
|
|
84
|
+
'Move to start of line',
|
|
85
|
+
'Next error / line end',
|
|
86
|
+
'Actions',
|
|
87
|
+
'Collapse/expand block',
|
|
88
|
+
'Bookmark block',
|
|
89
|
+
'Copy block to clipboard',
|
|
90
|
+
'Block file save disabled; copy or export',
|
|
91
|
+
'Copy selection',
|
|
92
|
+
'Process monitor',
|
|
93
|
+
'Help overlay',
|
|
94
|
+
'Exit',
|
|
95
|
+
'Workspace',
|
|
96
|
+
'Swap focus between input and active Agent workspace',
|
|
97
|
+
'Open the Agent operator workspace',
|
|
98
|
+
'Cycle Agent workspace category forward',
|
|
99
|
+
'Cycle Agent workspace category backward',
|
|
100
|
+
'Config: /keybindings to list and customize',
|
|
101
|
+
] as const;
|
|
102
|
+
|
|
103
|
+
export function renderHelpOverlayPackageText(): string {
|
|
104
|
+
return [
|
|
105
|
+
...HELP_OVERLAY_STATIC_TEXT,
|
|
106
|
+
...FEATURED_HELP_COMMANDS.flatMap(([name, argHint, desc]) => [
|
|
107
|
+
argHint ? `/${name} ${argHint}` : `/${name}`,
|
|
108
|
+
desc,
|
|
109
|
+
]),
|
|
110
|
+
...SHORTCUT_OVERLAY_STATIC_TEXT,
|
|
111
|
+
].join('\n');
|
|
112
|
+
}
|
|
113
|
+
|
|
15
114
|
function toModalSections(rows: readonly string[]): import('./modal-factory.ts').ModalSection[] {
|
|
16
115
|
return rows.map((row) => {
|
|
17
116
|
if (row === '') return { type: 'spacer' as const };
|
|
@@ -62,37 +161,11 @@ export function renderHelpOverlay(
|
|
|
62
161
|
` ${'?'.padEnd(20)} Toggle help`,
|
|
63
162
|
` ${'/shortcuts'.padEnd(20)} Full keyboard shortcuts`,
|
|
64
163
|
` ${kb('panel-picker').padEnd(20)} Open the Agent operator workspace`,
|
|
164
|
+
` ${'Workspace /'.padEnd(20)} Search all Agent workspace actions`,
|
|
165
|
+
` ${'Workspace Enter'.padEnd(20)} Open selected action or form`,
|
|
65
166
|
'',
|
|
66
167
|
];
|
|
67
168
|
|
|
68
|
-
// Featured commands shown in the Quick Start section.
|
|
69
|
-
// Each entry is [commandName, subcommandOrArgHint, description].
|
|
70
|
-
// Commands not registered in the live registry are omitted at render time.
|
|
71
|
-
const FEATURED_COMMANDS: Array<[name: string, argHint: string, desc: string]> = [
|
|
72
|
-
['agent', '', 'Open the Agent operator workspace'],
|
|
73
|
-
['agent', 'setup', 'Open setup, local behavior, channel, and voice workspaces'],
|
|
74
|
-
['agent', 'knowledge', 'Open isolated Agent Knowledge workflows'],
|
|
75
|
-
['agent', 'voice-media', 'Open voice, image, browser, and media setup'],
|
|
76
|
-
['setup', '', 'Open Agent setup with current settings preloaded'],
|
|
77
|
-
['knowledge', 'status', 'Inspect isolated Agent Knowledge readiness'],
|
|
78
|
-
['memory', '', 'Manage local Agent memory records'],
|
|
79
|
-
['personas', '', 'Manage serial Agent operating personas'],
|
|
80
|
-
['agent-skills', '', 'Manage local Agent skills and bundles'],
|
|
81
|
-
['routines', '', 'Manage reusable main-conversation routines'],
|
|
82
|
-
['workplan', '', 'Inspect shared work-plan state'],
|
|
83
|
-
['approval', '', 'Review and explicitly act on approvals'],
|
|
84
|
-
['schedule', 'remind', 'Create confirmed reminders or inspect schedules'],
|
|
85
|
-
['delegate', '', 'Explicitly hand build/fix/review work to GoodVibes TUI'],
|
|
86
|
-
['mcp', '', 'Inspect MCP servers and tool readiness'],
|
|
87
|
-
['provider', '', 'Choose provider or model family'],
|
|
88
|
-
['model', '', 'Select the active model route'],
|
|
89
|
-
['subscription', '', 'Review provider logins and subscriptions'],
|
|
90
|
-
['secrets', '', 'Manage secret references without printing values'],
|
|
91
|
-
['bundle', 'inspect', 'Inspect Agent support bundles from the TUI'],
|
|
92
|
-
['compat', '', 'Inspect connected-host and Agent Knowledge compatibility'],
|
|
93
|
-
['health', '', 'Run Agent runtime and setup diagnostics'],
|
|
94
|
-
];
|
|
95
|
-
|
|
96
169
|
// Build command rows from featured list, filtering out unregistered commands.
|
|
97
170
|
function featuredRow(name: string, argHint: string, desc: string): string {
|
|
98
171
|
const invocation = argHint ? `/${name} ${argHint}` : `/${name}`;
|
|
@@ -101,7 +174,7 @@ export function renderHelpOverlay(
|
|
|
101
174
|
|
|
102
175
|
const quickStartRows: string[] = [];
|
|
103
176
|
try {
|
|
104
|
-
for (const [name, argHint, desc] of
|
|
177
|
+
for (const [name, argHint, desc] of FEATURED_HELP_COMMANDS) {
|
|
105
178
|
if (!hasCommand(name)) continue; // omit if not in live registry
|
|
106
179
|
quickStartRows.push(featuredRow(name, argHint, desc));
|
|
107
180
|
}
|
|
@@ -110,7 +183,7 @@ export function renderHelpOverlay(
|
|
|
110
183
|
// unfiltered quick-start list so /help remains reachable.
|
|
111
184
|
logger.warn(`[help-overlay] registry traversal error during command filter; using unfiltered list: ${err}`);
|
|
112
185
|
quickStartRows.length = 0;
|
|
113
|
-
for (const [name, argHint, desc] of
|
|
186
|
+
for (const [name, argHint, desc] of FEATURED_HELP_COMMANDS) {
|
|
114
187
|
quickStartRows.push(featuredRow(name, argHint, desc));
|
|
115
188
|
}
|
|
116
189
|
}
|
|
@@ -128,7 +201,7 @@ export function renderHelpOverlay(
|
|
|
128
201
|
'knowledge',
|
|
129
202
|
'memory',
|
|
130
203
|
'personas',
|
|
131
|
-
'
|
|
204
|
+
'skills',
|
|
132
205
|
'routines',
|
|
133
206
|
'workplan',
|
|
134
207
|
'approval',
|
|
@@ -261,8 +334,8 @@ export function renderShortcutsOverlay(
|
|
|
261
334
|
' ' + '\u2500'.repeat(40),
|
|
262
335
|
row('Tab', 'Swap focus between input and active Agent workspace'),
|
|
263
336
|
row(kb('panel-picker'), 'Open the Agent operator workspace'),
|
|
264
|
-
row(kb('panel-tab-next'), '
|
|
265
|
-
row(kb('panel-tab-prev'), '
|
|
337
|
+
row(kb('panel-tab-next'), 'Cycle Agent workspace category forward'),
|
|
338
|
+
row(kb('panel-tab-prev'), 'Cycle Agent workspace category backward'),
|
|
266
339
|
'',
|
|
267
340
|
` Config: /keybindings to list and customize`,
|
|
268
341
|
];
|
|
@@ -3,6 +3,22 @@ import { getDisplayWidth } from '../utils/terminal-width.ts';
|
|
|
3
3
|
import type { HistorySearch } from '../input/input-history.ts';
|
|
4
4
|
import { createBottomBarLine, writeBottomBarText } from './bottom-bar.ts';
|
|
5
5
|
|
|
6
|
+
const HISTORY_SEARCH_PREFIX = '(reverse-i-search)`';
|
|
7
|
+
const HISTORY_SEARCH_FAILED_PREFIX = '(failed reverse-i-search)`';
|
|
8
|
+
const HISTORY_SEARCH_QUERY_SUFFIX = "': ";
|
|
9
|
+
|
|
10
|
+
function historySearchLabel(prefix: string, query: string): string {
|
|
11
|
+
return prefix + query + HISTORY_SEARCH_QUERY_SUFFIX;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function renderHistorySearchOverlayPackageText(): string {
|
|
15
|
+
return [
|
|
16
|
+
historySearchLabel(HISTORY_SEARCH_PREFIX, '<query>'),
|
|
17
|
+
historySearchLabel(HISTORY_SEARCH_FAILED_PREFIX, '<query>'),
|
|
18
|
+
'<matched-command-text>',
|
|
19
|
+
].join('\n');
|
|
20
|
+
}
|
|
21
|
+
|
|
6
22
|
/**
|
|
7
23
|
* Truncate `text` to at most `maxWidth` display columns, then pad with spaces
|
|
8
24
|
* to exactly `maxWidth` columns. CJK/emoji wide characters count as 2 columns.
|
|
@@ -42,13 +58,12 @@ export function renderHistorySearchOverlay(
|
|
|
42
58
|
const noMatch = historySearch.query.length > 0 && !hasMatch;
|
|
43
59
|
|
|
44
60
|
const prefix = noMatch
|
|
45
|
-
?
|
|
46
|
-
:
|
|
47
|
-
const queryPart = historySearch.query + "': ";
|
|
61
|
+
? HISTORY_SEARCH_FAILED_PREFIX
|
|
62
|
+
: HISTORY_SEARCH_PREFIX;
|
|
48
63
|
const matchText = hasMatch ? match?.entry ?? '' : '';
|
|
49
64
|
|
|
50
65
|
// Build the display string
|
|
51
|
-
const label = prefix
|
|
66
|
+
const label = historySearchLabel(prefix, historySearch.query);
|
|
52
67
|
const full = truncateToWidth(label + matchText, width);
|
|
53
68
|
|
|
54
69
|
const line = createBottomBarLine(width, { fg: '#000000', bg: '#00ffcc' });
|
|
@@ -4,6 +4,28 @@ import type { ProcessManager } from '@pellux/goodvibes-sdk/platform/tools';
|
|
|
4
4
|
import type { ProcessEntry } from './process-modal.ts';
|
|
5
5
|
import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay-viewport.ts';
|
|
6
6
|
|
|
7
|
+
const LIVE_TAIL_PROCESS_TAG = '[exec]';
|
|
8
|
+
const LIVE_TAIL_EMPTY_OUTPUT = '(no output yet)';
|
|
9
|
+
const LIVE_TAIL_SCROLL_HINT = '[Up/Down] Scroll';
|
|
10
|
+
const LIVE_TAIL_HINTS = [LIVE_TAIL_SCROLL_HINT, '[k] Stop process', '[Esc] Back'];
|
|
11
|
+
|
|
12
|
+
function liveTailTitle(label: string): string {
|
|
13
|
+
return `${LIVE_TAIL_PROCESS_TAG} ${label}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function liveTailScrollInfo(start: string | number, end: string | number, total: string | number): string {
|
|
17
|
+
return ` Lines ${start}-${end} of ${total} ${LIVE_TAIL_SCROLL_HINT}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function renderLiveTailModalPackageText(): string {
|
|
21
|
+
return [
|
|
22
|
+
liveTailTitle('<process>'),
|
|
23
|
+
LIVE_TAIL_EMPTY_OUTPUT,
|
|
24
|
+
liveTailScrollInfo('<start>', '<end>', '<total>'),
|
|
25
|
+
...LIVE_TAIL_HINTS,
|
|
26
|
+
].join('\n');
|
|
27
|
+
}
|
|
28
|
+
|
|
7
29
|
export interface LiveTailModalDeps {
|
|
8
30
|
readonly processManager: Pick<ProcessManager, 'stop' | 'getOutput'>;
|
|
9
31
|
}
|
|
@@ -45,7 +67,7 @@ export class LiveTailModal {
|
|
|
45
67
|
const output = this.deps.processManager.getOutput(this.entry.id);
|
|
46
68
|
if (!output) return '';
|
|
47
69
|
const combined = [output.stdout, output.stderr].filter(Boolean).join('\n').trim();
|
|
48
|
-
return combined ||
|
|
70
|
+
return combined || LIVE_TAIL_EMPTY_OUTPUT;
|
|
49
71
|
}
|
|
50
72
|
}
|
|
51
73
|
|
|
@@ -74,9 +96,9 @@ export function renderLiveTailModal(
|
|
|
74
96
|
const visibleLines = allLines.slice(startIdx, endIdx);
|
|
75
97
|
|
|
76
98
|
const maxLabelW = Math.max(20, width - 30);
|
|
77
|
-
const title =
|
|
99
|
+
const title = liveTailTitle(entry.label.slice(0, maxLabelW));
|
|
78
100
|
const scrollInfo = totalLines > maxOutputLines
|
|
79
|
-
?
|
|
101
|
+
? liveTailScrollInfo(startIdx + 1, Math.min(endIdx, totalLines), totalLines)
|
|
80
102
|
: '';
|
|
81
103
|
|
|
82
104
|
const sections: import('./modal-factory.ts').ModalSection[] = [];
|
|
@@ -84,7 +106,7 @@ export function renderLiveTailModal(
|
|
|
84
106
|
sections.push({ type: 'text', content: scrollInfo });
|
|
85
107
|
sections.push({ type: 'separator' });
|
|
86
108
|
}
|
|
87
|
-
sections.push({ type: 'text', content: visibleLines.join('\n') ||
|
|
109
|
+
sections.push({ type: 'text', content: visibleLines.join('\n') || LIVE_TAIL_EMPTY_OUTPUT });
|
|
88
110
|
|
|
89
111
|
return ModalFactory.createModal({
|
|
90
112
|
title,
|
|
@@ -92,6 +114,6 @@ export function renderLiveTailModal(
|
|
|
92
114
|
margin: 2,
|
|
93
115
|
targetContentRows,
|
|
94
116
|
sections,
|
|
95
|
-
hints:
|
|
117
|
+
hints: LIVE_TAIL_HINTS,
|
|
96
118
|
}, width);
|
|
97
119
|
}
|