@pellux/goodvibes-agent 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +7 -7
- package/dist/package/main.js +7450 -12285
- 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/performance-snapshot.json +2 -2
- package/release/release-notes.md +11 -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 +63 -158
- 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/submission-router.ts +0 -5
- package/src/main.ts +111 -89
- 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
|
@@ -27,19 +27,14 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
handleIndicatorFocusToken,
|
|
29
29
|
handleMouseToken,
|
|
30
|
-
handlePanelFocusToken,
|
|
31
30
|
handlePromptKeyToken,
|
|
32
31
|
handlePromptTextToken,
|
|
33
|
-
type PanelMouseLayout,
|
|
34
32
|
} from './handler-feed-routes.ts';
|
|
35
33
|
import type { WrappedPromptInfo } from './handler-prompt-buffer.ts';
|
|
36
34
|
import { handleModalTokenRoutes } from './handler-modal-token-routes.ts';
|
|
37
35
|
import { handleCommandModeToken } from './handler-command-route.ts';
|
|
38
36
|
import { handleGlobalShortcutToken } from './handler-shortcuts.ts';
|
|
39
|
-
import type { Panel } from '../panels/types.ts';
|
|
40
|
-
import { handlePanelIntegrationAction } from './panel-integration-actions.ts';
|
|
41
37
|
import { SelectionManager } from './selection.ts';
|
|
42
|
-
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
43
38
|
import type { KeybindingsManager } from './keybindings.ts';
|
|
44
39
|
import type { ModelPickerTarget } from './model-picker.ts';
|
|
45
40
|
|
|
@@ -51,7 +46,7 @@ import type { ModelPickerTarget } from './model-picker.ts';
|
|
|
51
46
|
* **Mutable per-feed** (synced from handler at the top of every feed() call, and
|
|
52
47
|
* updated inside action closures via syncFeedContextMutableFields):
|
|
53
48
|
* - `prompt`, `cursorPos` — current text buffer state
|
|
54
|
-
* - `commandMode`, `
|
|
49
|
+
* - `commandMode`, `indicatorFocused` — focus-mode flags
|
|
55
50
|
* - `helpOverlayActive`, `helpScrollOffset` — help overlay visibility and scroll
|
|
56
51
|
* - `shortcutsOverlayActive`, `shortcutsScrollOffset` — shortcuts overlay state
|
|
57
52
|
* - `nextPasteId`, `nextImageId` — monotonically increasing ID counters
|
|
@@ -72,7 +67,7 @@ import type { ModelPickerTarget } from './model-picker.ts';
|
|
|
72
67
|
* - `filePicker`, `modelPicker`, `processModal`, `liveTailModal`,
|
|
73
68
|
* `contextInspectorModal`, `blockActionsMenu`, `searchManager`, `historySearch` —
|
|
74
69
|
* service objects constructed once
|
|
75
|
-
* - `
|
|
70
|
+
* - `keybindingsManager` — from uiServices, stable for app lifetime
|
|
76
71
|
* - `modalStack` — reference to the handler's shared array (mutated in place)
|
|
77
72
|
* - `getHistory`, `getViewportHeight`, `getScrollTop`, `scroll`, `exitApp` — stable
|
|
78
73
|
* callbacks bound in the InputHandler constructor
|
|
@@ -86,7 +81,6 @@ export interface InputFeedContext {
|
|
|
86
81
|
cursorPos: number;
|
|
87
82
|
inputScrollTop: number;
|
|
88
83
|
commandMode: boolean;
|
|
89
|
-
panelFocused: boolean;
|
|
90
84
|
indicatorFocused: boolean;
|
|
91
85
|
helpOverlayActive: boolean;
|
|
92
86
|
helpScrollOffset: number;
|
|
@@ -120,8 +114,6 @@ export interface InputFeedContext {
|
|
|
120
114
|
readonly contextInspectorModal: ContextInspectorModal;
|
|
121
115
|
readonly blockActionsMenu: BlockActionsMenu;
|
|
122
116
|
readonly searchManager: SearchManager;
|
|
123
|
-
readonly panelManager: PanelManager;
|
|
124
|
-
panelMouseLayout: PanelMouseLayout | null;
|
|
125
117
|
readonly keybindingsManager: KeybindingsManager;
|
|
126
118
|
readonly modalStack: string[];
|
|
127
119
|
inputHistory: InputHistory | null;
|
|
@@ -147,7 +139,6 @@ export interface InputFeedContext {
|
|
|
147
139
|
readonly executeBlockAction: (id: string) => void;
|
|
148
140
|
readonly cycleAgentWorkspaceCategory: (direction: 'next' | 'prev') => void;
|
|
149
141
|
readonly dismissAgentWorkspace: () => boolean;
|
|
150
|
-
readonly onPanelInputConsumed: (activePanel: Panel | null, key: string) => void;
|
|
151
142
|
readonly getWrappedPromptInfo: (contentWidth: number) => WrappedPromptInfo;
|
|
152
143
|
readonly moveCursorVertical: (direction: -1 | 1) => boolean;
|
|
153
144
|
readonly handlePathCompletion: () => boolean;
|
|
@@ -236,16 +227,7 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
236
227
|
}
|
|
237
228
|
|
|
238
229
|
if (token.type === 'key') {
|
|
239
|
-
if (
|
|
240
|
-
context.panelFocused
|
|
241
|
-
&& (!context.panelManager.isVisible()
|
|
242
|
-
|| context.panelManager.getAllOpen().length === 0
|
|
243
|
-
|| context.panelManager.getActivePanel() === null)
|
|
244
|
-
) {
|
|
245
|
-
context.panelFocused = false;
|
|
246
|
-
}
|
|
247
230
|
const shortcutState = {
|
|
248
|
-
panelFocused: context.panelFocused,
|
|
249
231
|
prompt: context.prompt,
|
|
250
232
|
cursorPos: context.cursorPos,
|
|
251
233
|
commandMode: context.commandMode,
|
|
@@ -272,36 +254,16 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
272
254
|
handleEscape: context.handleEscape,
|
|
273
255
|
cycleAgentWorkspaceCategory: context.cycleAgentWorkspaceCategory,
|
|
274
256
|
dismissAgentWorkspace: context.dismissAgentWorkspace,
|
|
275
|
-
panelManager: context.panelManager,
|
|
276
257
|
keybindingsManager: context.keybindingsManager,
|
|
277
258
|
};
|
|
278
259
|
if (handleGlobalShortcutToken(shortcutState, token, viewportHeight)) {
|
|
279
260
|
context.prompt = shortcutState.prompt;
|
|
280
261
|
context.cursorPos = shortcutState.cursorPos;
|
|
281
262
|
context.commandMode = shortcutState.commandMode;
|
|
282
|
-
context.panelFocused = shortcutState.panelFocused;
|
|
283
263
|
continue;
|
|
284
264
|
}
|
|
285
265
|
}
|
|
286
266
|
|
|
287
|
-
const panelRoute = handlePanelFocusToken({
|
|
288
|
-
panelFocused: context.panelFocused,
|
|
289
|
-
commandMode: context.commandMode,
|
|
290
|
-
searchActive: context.searchManager.active,
|
|
291
|
-
autocompleteActive: !!context.autocomplete?.isActive,
|
|
292
|
-
requestRender: context.requestRender,
|
|
293
|
-
handlePathCompletion: context.handlePathCompletion,
|
|
294
|
-
cycleAgentWorkspaceCategory: context.cycleAgentWorkspaceCategory,
|
|
295
|
-
dismissAgentWorkspace: context.dismissAgentWorkspace,
|
|
296
|
-
panelManager: context.panelManager,
|
|
297
|
-
keybindingsManager: context.keybindingsManager,
|
|
298
|
-
onPanelInputConsumed: context.onPanelInputConsumed,
|
|
299
|
-
}, token);
|
|
300
|
-
context.panelFocused = panelRoute.panelFocused;
|
|
301
|
-
if (panelRoute.handled) {
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
267
|
const indicatorRoute = handleIndicatorFocusToken({
|
|
306
268
|
indicatorFocused: context.indicatorFocused,
|
|
307
269
|
modalOpened: context.modalOpened,
|
|
@@ -348,8 +310,6 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
348
310
|
modalStack: context.modalStack,
|
|
349
311
|
commandRegistry: context.commandRegistry,
|
|
350
312
|
commandContext: context.commandContext,
|
|
351
|
-
panelFocused: context.panelFocused,
|
|
352
|
-
panelManager: context.panelManager,
|
|
353
313
|
conversationManager: context.conversationManager,
|
|
354
314
|
requestRender: context.requestRender,
|
|
355
315
|
handleEscape: context.handleEscape,
|
|
@@ -365,7 +325,6 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
365
325
|
context.commandMode = commandState.commandMode;
|
|
366
326
|
context.prompt = commandState.prompt;
|
|
367
327
|
context.cursorPos = commandState.cursorPos;
|
|
368
|
-
context.panelFocused = commandState.panelFocused;
|
|
369
328
|
context.nextPasteId = commandState.nextPasteId;
|
|
370
329
|
context.nextImageId = commandState.nextImageId;
|
|
371
330
|
continue;
|
|
@@ -411,8 +370,6 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
411
370
|
const mouseRoute = handleMouseToken({
|
|
412
371
|
conversationManager: context.conversationManager,
|
|
413
372
|
selection: context.selection,
|
|
414
|
-
panelManager: context.panelManager,
|
|
415
|
-
panelMouseLayout: context.panelMouseLayout,
|
|
416
373
|
mouseDownRow: context.mouseDownRow,
|
|
417
374
|
mouseDownCol: context.mouseDownCol,
|
|
418
375
|
scrollTop,
|
|
@@ -433,12 +390,3 @@ export function feedInputTokens(context: InputFeedContext, tokens: readonly Inpu
|
|
|
433
390
|
|
|
434
391
|
context.requestRender();
|
|
435
392
|
}
|
|
436
|
-
|
|
437
|
-
export function defaultPanelInputConsumer(
|
|
438
|
-
panelManager: PanelManager,
|
|
439
|
-
activePanel: Panel | null,
|
|
440
|
-
key: string,
|
|
441
|
-
commandContext?: CommandContext,
|
|
442
|
-
): void {
|
|
443
|
-
handlePanelIntegrationAction(panelManager, activePanel, key, commandContext);
|
|
444
|
-
}
|
|
@@ -167,7 +167,6 @@ export function handleEscapeForHandler(handler: InputHandler): void {
|
|
|
167
167
|
commandMode: handler.commandMode,
|
|
168
168
|
modalStack: handler.modalStack,
|
|
169
169
|
modalReturnFocus: handler.modalReturnFocus,
|
|
170
|
-
panelFocused: handler.panelFocused,
|
|
171
170
|
indicatorFocused: handler.indicatorFocused,
|
|
172
171
|
prompt: handler.prompt,
|
|
173
172
|
cursorPos: handler.cursorPos,
|
|
@@ -188,7 +187,6 @@ export function handleEscapeForHandler(handler: InputHandler): void {
|
|
|
188
187
|
handler.shortcutsOverlayActive = result.shortcutsOverlayActive;
|
|
189
188
|
handler.shortcutsScrollOffset = result.shortcutsScrollOffset;
|
|
190
189
|
handler.selectionCallback = result.selectionCallback;
|
|
191
|
-
handler.panelFocused = result.panelFocused;
|
|
192
190
|
handler.indicatorFocused = result.indicatorFocused;
|
|
193
191
|
handler.modalReturnFocus = result.modalReturnFocus;
|
|
194
192
|
}
|
|
@@ -9,7 +9,6 @@ import type { SelectionResult } from './selection-modal.ts';
|
|
|
9
9
|
export type ModalStackState = ActiveModalState & {
|
|
10
10
|
modalStack: string[];
|
|
11
11
|
modalReturnFocus?: 'prompt' | 'indicator';
|
|
12
|
-
panelFocused: boolean;
|
|
13
12
|
indicatorFocused: boolean;
|
|
14
13
|
};
|
|
15
14
|
|
|
@@ -61,7 +60,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
61
60
|
shortcutsOverlayActive: boolean;
|
|
62
61
|
shortcutsScrollOffset: number;
|
|
63
62
|
selectionCallback: ((result: SelectionResult | null) => void) | null;
|
|
64
|
-
panelFocused: boolean;
|
|
65
63
|
indicatorFocused: boolean;
|
|
66
64
|
modalReturnFocus: NonNullable<ModalStackState['modalReturnFocus']>;
|
|
67
65
|
} {
|
|
@@ -73,7 +71,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
73
71
|
let shortcutsOverlayActive = state.shortcutsOverlayActive;
|
|
74
72
|
let shortcutsScrollOffset = state.shortcutsScrollOffset;
|
|
75
73
|
let selectionCallback = state.selectionCallback;
|
|
76
|
-
let panelFocused = state.panelFocused;
|
|
77
74
|
let indicatorFocused = state.indicatorFocused;
|
|
78
75
|
let modalReturnFocus: NonNullable<ModalStackState['modalReturnFocus']> = state.modalReturnFocus ?? 'prompt';
|
|
79
76
|
|
|
@@ -84,7 +81,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
84
81
|
shortcutsOverlayActive,
|
|
85
82
|
commandMode,
|
|
86
83
|
}) !== null) return;
|
|
87
|
-
panelFocused = false;
|
|
88
84
|
indicatorFocused = modalReturnFocus === 'indicator';
|
|
89
85
|
modalReturnFocus = 'prompt';
|
|
90
86
|
state.modalReturnFocus = 'prompt';
|
|
@@ -102,7 +98,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
102
98
|
shortcutsOverlayActive,
|
|
103
99
|
shortcutsScrollOffset,
|
|
104
100
|
selectionCallback,
|
|
105
|
-
panelFocused,
|
|
106
101
|
indicatorFocused,
|
|
107
102
|
modalReturnFocus,
|
|
108
103
|
};
|
|
@@ -185,7 +180,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
185
180
|
shortcutsOverlayActive,
|
|
186
181
|
shortcutsScrollOffset,
|
|
187
182
|
selectionCallback,
|
|
188
|
-
panelFocused,
|
|
189
183
|
indicatorFocused,
|
|
190
184
|
modalReturnFocus,
|
|
191
185
|
};
|
|
@@ -210,7 +204,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
210
204
|
shortcutsOverlayActive,
|
|
211
205
|
shortcutsScrollOffset,
|
|
212
206
|
selectionCallback,
|
|
213
|
-
panelFocused,
|
|
214
207
|
indicatorFocused,
|
|
215
208
|
modalReturnFocus,
|
|
216
209
|
};
|
|
@@ -229,7 +222,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
229
222
|
shortcutsOverlayActive,
|
|
230
223
|
shortcutsScrollOffset,
|
|
231
224
|
selectionCallback,
|
|
232
|
-
panelFocused,
|
|
233
225
|
indicatorFocused,
|
|
234
226
|
modalReturnFocus,
|
|
235
227
|
};
|
|
@@ -245,7 +237,6 @@ export function handleEscape(state: EscapeState): {
|
|
|
245
237
|
shortcutsOverlayActive,
|
|
246
238
|
shortcutsScrollOffset,
|
|
247
239
|
selectionCallback,
|
|
248
|
-
panelFocused,
|
|
249
240
|
indicatorFocused,
|
|
250
241
|
modalReturnFocus,
|
|
251
242
|
};
|
|
@@ -3,6 +3,7 @@ import type { InputToken } from '@pellux/goodvibes-sdk/platform/core';
|
|
|
3
3
|
import type { CommandContext } from './command-registry.ts';
|
|
4
4
|
import type { CapabilityFilter, CategoryFilter, ModelPickerModal } from './model-picker.ts';
|
|
5
5
|
import { MODEL_PICKER_CHROME_LINES } from '../renderer/model-picker-overlay.ts';
|
|
6
|
+
import { isLocalFitRecommendation, isProviderSignInRow } from '../input/model-picker-local-fit.ts';
|
|
6
7
|
import { resolveAndValidatePath } from '@pellux/goodvibes-sdk/platform/utils';
|
|
7
8
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
8
9
|
import type { ProcessEntry } from '../renderer/process-modal.ts';
|
|
@@ -59,6 +60,28 @@ export function handleModelPickerToken(state: ModelPickerRouteState, token: Inpu
|
|
|
59
60
|
if (mode === 'model') {
|
|
60
61
|
const selected = state.modelPicker.getSelected();
|
|
61
62
|
if (selected) {
|
|
63
|
+
// Sign-in row: route to provider picker instead of committing a model.
|
|
64
|
+
if (isProviderSignInRow(selected)) {
|
|
65
|
+
state.modelPicker.close();
|
|
66
|
+
if (state.modalStack[state.modalStack.length - 1] === 'modelPicker') state.modalStack.pop();
|
|
67
|
+
state.commandContext?.openProviderPicker?.();
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// Local fit rec: the model is not installed — do not commit it as the
|
|
71
|
+
// active model. Print a plain-language guide and close the picker.
|
|
72
|
+
if (isLocalFitRecommendation(selected)) {
|
|
73
|
+
state.modelPicker.close();
|
|
74
|
+
if (state.modalStack[state.modalStack.length - 1] === 'modelPicker') state.modalStack.pop();
|
|
75
|
+
state.commandContext?.print?.(
|
|
76
|
+
[
|
|
77
|
+
`${selected.displayName} is not installed yet.`,
|
|
78
|
+
'To use a local model, add a custom provider:',
|
|
79
|
+
' /provider add <name> <baseURL> (e.g. /provider add ollama http://localhost:11434/v1)',
|
|
80
|
+
'Or sign in to a cloud provider via the provider picker.',
|
|
81
|
+
].join('\n'),
|
|
82
|
+
);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
62
85
|
const currentEffort = state.commandContext?.session.runtime.reasoningEffort ?? 'medium';
|
|
63
86
|
if (state.modelPicker.target === 'main' && selected.reasoningEffort && selected.reasoningEffort.length > 0) {
|
|
64
87
|
state.modelPicker.showEffortPicker(selected, currentEffort);
|
|
@@ -162,7 +185,7 @@ export function handleModelPickerToken(state: ModelPickerRouteState, token: Inpu
|
|
|
162
185
|
if (ch === ' ' && state.modelPicker.mode === 'model') {
|
|
163
186
|
const selected = state.modelPicker.getSelected();
|
|
164
187
|
if (selected && state.modelPicker.isLocalModel(selected)) state.modelPicker.enterContextCapMode(selected);
|
|
165
|
-
else
|
|
188
|
+
else state.modelPicker.appendChar(ch);
|
|
166
189
|
} else if (ch.length === 1 && ch >= ' ') {
|
|
167
190
|
state.modelPicker.appendChar(ch);
|
|
168
191
|
}
|
|
@@ -4,7 +4,6 @@ import type { SearchManager } from './search.ts';
|
|
|
4
4
|
import type { HistorySearch } from './input-history.ts';
|
|
5
5
|
import type { ConversationManager } from '../core/conversation';
|
|
6
6
|
import type { AutocompleteEngine } from './autocomplete.ts';
|
|
7
|
-
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
8
7
|
import type { KeybindingsManager } from './keybindings.ts';
|
|
9
8
|
|
|
10
9
|
type WrappedPromptInfo = {
|
|
@@ -14,8 +13,6 @@ type WrappedPromptInfo = {
|
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
export type GlobalShortcutRouteState = {
|
|
17
|
-
panelFocused: boolean;
|
|
18
|
-
panelManager: PanelManager;
|
|
19
16
|
keybindingsManager: KeybindingsManager;
|
|
20
17
|
prompt: string;
|
|
21
18
|
cursorPos: number;
|
|
@@ -54,17 +51,15 @@ export function handleGlobalShortcutToken(
|
|
|
54
51
|
|
|
55
52
|
// Fast-path: bare pageup/pagedown have no keybinding entry.
|
|
56
53
|
if (token.logicalName === 'pageup') {
|
|
57
|
-
if (state.panelFocused) return false;
|
|
58
54
|
state.scroll(-Math.max(1, viewportHeight - 2));
|
|
59
55
|
return true;
|
|
60
56
|
}
|
|
61
57
|
if (token.logicalName === 'pagedown') {
|
|
62
|
-
if (state.panelFocused) return false;
|
|
63
58
|
state.scroll(Math.max(1, viewportHeight - 2));
|
|
64
59
|
return true;
|
|
65
60
|
}
|
|
66
61
|
// Bare escape is also not in the keybinding table.
|
|
67
|
-
if (token.logicalName === 'escape'
|
|
62
|
+
if (token.logicalName === 'escape') {
|
|
68
63
|
state.handleEscape();
|
|
69
64
|
return true;
|
|
70
65
|
}
|
|
@@ -78,56 +73,32 @@ export function handleGlobalShortcutToken(
|
|
|
78
73
|
state.handleCopy();
|
|
79
74
|
return true;
|
|
80
75
|
|
|
81
|
-
case 'clear-cancel':
|
|
82
|
-
state.handleCtrlC();
|
|
83
|
-
return true;
|
|
84
|
-
|
|
85
76
|
case 'screen-clear':
|
|
86
77
|
state.commandContext?.clearScreen?.();
|
|
87
78
|
return true;
|
|
88
79
|
|
|
89
|
-
case '
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
const pm = state.panelManager;
|
|
95
|
-
for (const p of pm.getAllOpen()) pm.close(p.id);
|
|
96
|
-
pm.hide();
|
|
97
|
-
state.panelFocused = false;
|
|
80
|
+
case 'workspace-close-all':
|
|
81
|
+
case 'workspace-close':
|
|
82
|
+
state.dismissAgentWorkspace();
|
|
98
83
|
state.requestRender();
|
|
99
84
|
return true;
|
|
100
|
-
}
|
|
101
85
|
|
|
102
|
-
case '
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
const pm = state.panelManager;
|
|
108
|
-
const active = pm.getActivePanel();
|
|
109
|
-
if (active) {
|
|
110
|
-
pm.close(active.id);
|
|
111
|
-
state.requestRender();
|
|
112
|
-
}
|
|
113
|
-
state.panelFocused = false;
|
|
86
|
+
case 'workspace-picker':
|
|
87
|
+
state.commandContext?.openWorkspacePicker?.();
|
|
88
|
+
state.requestRender();
|
|
114
89
|
return true;
|
|
115
|
-
}
|
|
116
90
|
|
|
117
|
-
case '
|
|
118
|
-
state.commandContext?.
|
|
119
|
-
state.panelFocused = false;
|
|
91
|
+
case 'sidebar-toggle':
|
|
92
|
+
state.commandContext?.toggleActivitySidebar?.();
|
|
120
93
|
state.requestRender();
|
|
121
94
|
return true;
|
|
122
95
|
|
|
123
|
-
case '
|
|
96
|
+
case 'workspace-tab-next':
|
|
124
97
|
state.cycleAgentWorkspaceCategory('next');
|
|
125
|
-
state.panelFocused = false;
|
|
126
98
|
return true;
|
|
127
99
|
|
|
128
|
-
case '
|
|
100
|
+
case 'workspace-tab-prev':
|
|
129
101
|
state.cycleAgentWorkspaceCategory('prev');
|
|
130
|
-
state.panelFocused = false;
|
|
131
102
|
return true;
|
|
132
103
|
|
|
133
104
|
case 'history-search':
|
|
@@ -125,6 +125,19 @@ export type ModalOpenOps = {
|
|
|
125
125
|
openCommandMode: () => void;
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Reopen the modal that was previously on top of the stack after it has been
|
|
130
|
+
* popped (so the one beneath it can resurface).
|
|
131
|
+
*
|
|
132
|
+
* INVARIANT: modals omitted from this switch are intentionally absent because
|
|
133
|
+
* they remain `.active` as underlays when something stacks above them — they
|
|
134
|
+
* never close themselves on stack push, so they need no explicit reopen.
|
|
135
|
+
* Only the self-closing set (help, shortcuts, bookmark, process,
|
|
136
|
+
* contextInspector, mcpWorkspace, agentWorkspace, command) is handled here.
|
|
137
|
+
*
|
|
138
|
+
* NOTE: any future modal that closes itself on overlay push MUST be added to
|
|
139
|
+
* this switch, or it will silently fail to reopen when the stack unwinds.
|
|
140
|
+
*/
|
|
128
141
|
export function reopenModalByName(name: string, ops: ModalOpenOps): void {
|
|
129
142
|
switch (name) {
|
|
130
143
|
case 'help':
|
package/src/input/handler.ts
CHANGED
|
@@ -44,10 +44,8 @@ import {
|
|
|
44
44
|
import {
|
|
45
45
|
handleIndicatorFocusToken,
|
|
46
46
|
handleMouseToken,
|
|
47
|
-
handlePanelFocusToken,
|
|
48
47
|
handlePromptKeyToken,
|
|
49
48
|
handlePromptTextToken,
|
|
50
|
-
type PanelMouseLayout,
|
|
51
49
|
} from './handler-feed-routes.ts';
|
|
52
50
|
import {
|
|
53
51
|
ensureInputCursorVisible,
|
|
@@ -67,10 +65,7 @@ import { handleCommandModeToken } from './handler-command-route.ts';
|
|
|
67
65
|
import { handleGlobalShortcutToken } from './handler-shortcuts.ts';
|
|
68
66
|
import { feedInputTokens } from './handler-feed.ts';
|
|
69
67
|
import { buildInitialFeedContext, syncFeedContextMutableFields } from './feed-context-factory.ts';
|
|
70
|
-
import { handlePanelIntegrationAction as runPanelIntegrationAction } from './panel-integration-actions.ts';
|
|
71
|
-
import type { Panel } from '../panels/types.ts';
|
|
72
68
|
import type { UiRuntimeServices } from '../runtime/ui-services.ts';
|
|
73
|
-
export { handlePanelIntegrationAction } from './panel-integration-actions.ts';
|
|
74
69
|
import type { ModelPickerTarget } from './model-picker.ts';
|
|
75
70
|
|
|
76
71
|
type SelectionModalCallback = (result: SelectionResult | null) => void;
|
|
@@ -93,8 +88,6 @@ export class InputHandler {
|
|
|
93
88
|
public commandMode = false;
|
|
94
89
|
/** True when the process indicator bar has keyboard focus. */
|
|
95
90
|
public indicatorFocused = false;
|
|
96
|
-
/** True when keyboard focus is on the active panel (arrow/enter go to panel, not prompt). */
|
|
97
|
-
public panelFocused = false;
|
|
98
91
|
|
|
99
92
|
public tokenizer = new InputTokenizer();
|
|
100
93
|
public pasteRegistry = new Map<string, string>();
|
|
@@ -202,12 +195,12 @@ export class InputHandler {
|
|
|
202
195
|
this.feedContext = buildInitialFeedContext(
|
|
203
196
|
{
|
|
204
197
|
prompt: this.prompt, cursorPos: this.cursorPos, inputScrollTop: this.inputScrollTop, commandMode: this.commandMode,
|
|
205
|
-
|
|
198
|
+
indicatorFocused: this.indicatorFocused,
|
|
206
199
|
helpOverlayActive: this.helpOverlayActive, helpScrollOffset: this.helpScrollOffset,
|
|
207
200
|
shortcutsOverlayActive: this.shortcutsOverlayActive, shortcutsScrollOffset: this.shortcutsScrollOffset,
|
|
208
201
|
nextPasteId: this.nextPasteId, nextImageId: this.nextImageId,
|
|
209
202
|
mouseDownRow: this.mouseDownRow, mouseDownCol: this.mouseDownCol,
|
|
210
|
-
contentWidth: this.contentWidth,
|
|
203
|
+
contentWidth: this.contentWidth,
|
|
211
204
|
selectionCallback: this.selectionCallback,
|
|
212
205
|
},
|
|
213
206
|
{
|
|
@@ -236,7 +229,6 @@ export class InputHandler {
|
|
|
236
229
|
modalStack: this.modalStack,
|
|
237
230
|
inputHistory: this.inputHistory,
|
|
238
231
|
conversationManager: this.conversationManager,
|
|
239
|
-
panelManager: this.uiServices.shell.panelManager,
|
|
240
232
|
keybindingsManager: this.uiServices.shell.keybindingsManager,
|
|
241
233
|
getHistory: this.getHistory,
|
|
242
234
|
getViewportHeight: this.getViewportHeight,
|
|
@@ -261,7 +253,6 @@ export class InputHandler {
|
|
|
261
253
|
executeBlockAction: (id: string) => this.executeBlockAction(id),
|
|
262
254
|
cycleAgentWorkspaceCategory: (direction: 'next' | 'prev') => this.cycleAgentWorkspaceCategory(direction),
|
|
263
255
|
dismissAgentWorkspace: () => this.dismissAgentWorkspace(),
|
|
264
|
-
onPanelInputConsumed: (activePanel: Panel | null, key: string) => this.handlePanelIntegrationAction(activePanel, key),
|
|
265
256
|
getWrappedPromptInfo: (contentWidth: number) => this.getWrappedPromptInfo(contentWidth),
|
|
266
257
|
moveCursorVertical: (direction: -1 | 1) => this.moveCursorVertical(direction),
|
|
267
258
|
handlePathCompletion: () => this.handlePathCompletion(),
|
|
@@ -280,12 +271,11 @@ export class InputHandler {
|
|
|
280
271
|
public syncFeedContextMutableFields(): void {
|
|
281
272
|
const h = this;
|
|
282
273
|
syncFeedContextMutableFields({ prompt: h.prompt, cursorPos: h.cursorPos, inputScrollTop: h.inputScrollTop, commandMode: h.commandMode,
|
|
283
|
-
|
|
274
|
+
indicatorFocused: h.indicatorFocused, helpOverlayActive: h.helpOverlayActive,
|
|
284
275
|
helpScrollOffset: h.helpScrollOffset, shortcutsOverlayActive: h.shortcutsOverlayActive,
|
|
285
276
|
shortcutsScrollOffset: h.shortcutsScrollOffset, selectionCallback: h.selectionCallback,
|
|
286
277
|
nextPasteId: h.nextPasteId, nextImageId: h.nextImageId, mouseDownRow: h.mouseDownRow,
|
|
287
|
-
mouseDownCol: h.mouseDownCol, contentWidth: h.contentWidth,
|
|
288
|
-
panelMouseLayout: h.panelMouseLayout }, this.feedContext);
|
|
278
|
+
mouseDownCol: h.mouseDownCol, contentWidth: h.contentWidth }, this.feedContext);
|
|
289
279
|
}
|
|
290
280
|
|
|
291
281
|
/** Wire in the InputHistory instance. Optional; disables history navigation if unset. */
|
|
@@ -360,14 +350,12 @@ export class InputHandler {
|
|
|
360
350
|
return true;
|
|
361
351
|
}
|
|
362
352
|
public openMcpWorkspace(context: CommandContext): void {
|
|
363
|
-
this.panelFocused = false;
|
|
364
353
|
this.indicatorFocused = false;
|
|
365
354
|
this.modalOpened('mcpWorkspace');
|
|
366
355
|
this.mcpWorkspace.open(context);
|
|
367
356
|
this.requestRender();
|
|
368
357
|
}
|
|
369
358
|
public openAgentWorkspace(context: CommandContext, categoryId?: string, onlyGroup?: string): void {
|
|
370
|
-
this.panelFocused = false;
|
|
371
359
|
this.indicatorFocused = false;
|
|
372
360
|
this.modalOpened('agentWorkspace');
|
|
373
361
|
this.agentWorkspace.open(
|
|
@@ -390,7 +378,6 @@ export class InputHandler {
|
|
|
390
378
|
public dismissAgentWorkspace(): boolean {
|
|
391
379
|
if (!this.agentWorkspace.active) return false;
|
|
392
380
|
this.closeAgentWorkspaceModal();
|
|
393
|
-
this.panelFocused = false;
|
|
394
381
|
this.indicatorFocused = false;
|
|
395
382
|
this.requestRender();
|
|
396
383
|
return true;
|
|
@@ -503,7 +490,6 @@ export class InputHandler {
|
|
|
503
490
|
context.cursorPos = this.cursorPos;
|
|
504
491
|
context.inputScrollTop = this.inputScrollTop;
|
|
505
492
|
context.commandMode = this.commandMode;
|
|
506
|
-
context.panelFocused = this.panelFocused;
|
|
507
493
|
context.indicatorFocused = this.indicatorFocused;
|
|
508
494
|
context.helpOverlayActive = this.helpOverlayActive;
|
|
509
495
|
context.helpScrollOffset = this.helpScrollOffset;
|
|
@@ -515,7 +501,6 @@ export class InputHandler {
|
|
|
515
501
|
context.mouseDownRow = this.mouseDownRow;
|
|
516
502
|
context.mouseDownCol = this.mouseDownCol;
|
|
517
503
|
context.contentWidth = this.contentWidth;
|
|
518
|
-
context.panelMouseLayout = this.panelMouseLayout;
|
|
519
504
|
// Sync semi-stable refs that may be wired after construction.
|
|
520
505
|
context.commandRegistry = this.commandRegistry;
|
|
521
506
|
context.commandContext = this.commandContext;
|
|
@@ -532,7 +517,6 @@ export class InputHandler {
|
|
|
532
517
|
this.cursorPos = context.cursorPos;
|
|
533
518
|
this.inputScrollTop = context.inputScrollTop;
|
|
534
519
|
this.commandMode = context.commandMode;
|
|
535
|
-
this.panelFocused = context.panelFocused;
|
|
536
520
|
this.indicatorFocused = context.indicatorFocused;
|
|
537
521
|
this.helpOverlayActive = context.helpOverlayActive;
|
|
538
522
|
this.helpScrollOffset = context.helpScrollOffset;
|
|
@@ -583,17 +567,12 @@ export class InputHandler {
|
|
|
583
567
|
|
|
584
568
|
/** Content width for wrapping — set by main.ts via setContentWidth(). */
|
|
585
569
|
public contentWidth = 76;
|
|
586
|
-
public panelMouseLayout: PanelMouseLayout | null = null;
|
|
587
570
|
|
|
588
571
|
/** Set the content width used for wrapping calculations. Call from main.ts. */
|
|
589
572
|
public setContentWidth(w: number): void {
|
|
590
573
|
this.contentWidth = w;
|
|
591
574
|
}
|
|
592
575
|
|
|
593
|
-
public setPanelMouseLayout(layout: PanelMouseLayout | null): void {
|
|
594
|
-
this.panelMouseLayout = layout;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
576
|
/**
|
|
598
577
|
* Move cursor up or down by one WRAPPED line.
|
|
599
578
|
* Uses the segment table to navigate visual lines, not raw \n lines.
|
|
@@ -726,15 +705,10 @@ export class InputHandler {
|
|
|
726
705
|
return true;
|
|
727
706
|
}
|
|
728
707
|
|
|
729
|
-
/**
|
|
730
|
-
* Word-wrap a single line to fit within maxW columns.
|
|
731
|
-
* Breaks at spaces; words wider than maxW are force-broken.
|
|
732
|
-
*/
|
|
733
708
|
public cycleAgentWorkspaceCategory(direction: 'next' | 'prev'): void {
|
|
734
709
|
const context = this.commandContext;
|
|
735
710
|
if (!this.agentWorkspace.active) {
|
|
736
711
|
if (!context) return;
|
|
737
|
-
this.panelFocused = false;
|
|
738
712
|
this.indicatorFocused = false;
|
|
739
713
|
this.modalOpened('agentWorkspace');
|
|
740
714
|
this.agentWorkspace.open(
|
|
@@ -745,15 +719,14 @@ export class InputHandler {
|
|
|
745
719
|
);
|
|
746
720
|
}
|
|
747
721
|
this.agentWorkspace.cycleCategory(direction);
|
|
748
|
-
this.panelFocused = false;
|
|
749
722
|
this.indicatorFocused = false;
|
|
750
723
|
this.requestRender();
|
|
751
724
|
}
|
|
752
725
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
726
|
+
/**
|
|
727
|
+
* Word-wrap a single line to fit within maxW columns.
|
|
728
|
+
* Breaks at spaces; words wider than maxW are force-broken.
|
|
729
|
+
*/
|
|
757
730
|
public wordWrapLine(line: string, maxW: number): string[] {
|
|
758
731
|
return wordWrapLine(line, maxW);
|
|
759
732
|
}
|