@pellux/goodvibes-tui 1.1.0 → 1.9.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 +85 -21
- package/README.md +28 -18
- package/docs/foundation-artifacts/operator-contract.json +4045 -1763
- package/package.json +2 -2
- package/src/audio/spoken-turn-controller.ts +12 -2
- package/src/audio/spoken-turn-wiring.ts +2 -1
- package/src/cli/help.ts +8 -1
- package/src/cli/service-posture.ts +2 -1
- package/src/cli/status.ts +2 -1
- package/src/cli/surface-command.ts +2 -2
- package/src/core/alert-gating.ts +67 -0
- package/src/core/approval-alert.ts +72 -0
- package/src/core/budget-breach-notifier.ts +106 -0
- package/src/core/composer-state.ts +11 -3
- package/src/core/conversation-line-cache.ts +27 -3
- package/src/core/conversation-rendering.ts +90 -14
- package/src/core/conversation.ts +18 -0
- package/src/core/focus-tracker.ts +41 -0
- package/src/core/long-task-notifier.ts +33 -6
- package/src/core/stream-event-wiring.ts +20 -1
- package/src/core/system-message-noise.ts +87 -0
- package/src/core/system-message-router.ts +104 -51
- package/src/core/turn-cancellation.ts +25 -0
- package/src/core/turn-event-wiring.ts +72 -3
- package/src/daemon/cli.ts +29 -2
- package/src/daemon/handlers/register.ts +8 -1
- package/src/daemon/service-commands.ts +329 -0
- package/src/export/cost-utils.ts +36 -0
- package/src/input/autocomplete.ts +27 -1
- package/src/input/command-registry.ts +84 -5
- package/src/input/commands/checkpoint-runtime.ts +280 -0
- package/src/input/commands/codebase-runtime.ts +232 -0
- package/src/input/commands/config.ts +43 -3
- package/src/input/commands/eval.ts +1 -1
- package/src/input/commands/health-runtime.ts +10 -2
- package/src/input/commands/image-runtime.ts +112 -0
- package/src/input/commands/intelligence-runtime.ts +11 -1
- package/src/input/commands/local-auth-runtime.ts +4 -1
- package/src/input/commands/local-runtime.ts +9 -3
- package/src/input/commands/marketplace-runtime.ts +2 -2
- package/src/input/commands/memory.ts +73 -35
- package/src/input/commands/operator-panel-runtime.ts +71 -31
- package/src/input/commands/planning-runtime.ts +116 -4
- package/src/input/commands/platform-sandbox-runtime.ts +1 -6
- package/src/input/commands/plugin-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +21 -0
- package/src/input/commands/provider-accounts-runtime.ts +1 -1
- package/src/input/commands/qrcode-runtime.ts +26 -6
- package/src/input/commands/recall-review.ts +35 -0
- package/src/input/commands/remote-runtime-setup.ts +5 -3
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/runtime-services.ts +54 -13
- package/src/input/commands/services-runtime.ts +1 -1
- package/src/input/commands/session-content.ts +20 -9
- package/src/input/commands/session-workflow.ts +16 -1
- package/src/input/commands/settings-sync-runtime.ts +16 -4
- package/src/input/commands/shell-core.ts +25 -8
- package/src/input/commands/skills-runtime.ts +2 -8
- package/src/input/commands/subscription-runtime.ts +2 -2
- package/src/input/commands/test-runtime.ts +277 -0
- package/src/input/commands/websearch-runtime.ts +101 -0
- package/src/input/commands/work-plan-runtime.ts +36 -10
- package/src/input/commands/workstream-runtime.ts +488 -0
- package/src/input/commands.ts +12 -0
- package/src/input/config-modal-types.ts +175 -0
- package/src/input/config-modal.ts +592 -0
- package/src/input/feed-context-factory.ts +10 -8
- package/src/input/handler-command-route.ts +37 -20
- package/src/input/handler-content-actions.ts +17 -2
- package/src/input/handler-feed-routes.ts +74 -114
- package/src/input/handler-feed.ts +79 -27
- package/src/input/handler-interactions.ts +1 -3
- package/src/input/handler-modal-routes.ts +136 -6
- package/src/input/handler-modal-stack.ts +14 -7
- package/src/input/handler-modal-token-routes.ts +16 -49
- package/src/input/handler-onboarding-daemon-adopt.ts +149 -0
- package/src/input/handler-onboarding.ts +71 -59
- package/src/input/handler-picker-routes.ts +26 -102
- package/src/input/handler-shortcuts.ts +74 -14
- package/src/input/handler-types.ts +2 -6
- package/src/input/handler-ui-state.ts +10 -22
- package/src/input/handler.ts +12 -29
- package/src/input/keybindings.ts +23 -8
- package/src/input/model-picker-types.ts +24 -6
- package/src/input/model-picker.ts +77 -2
- package/src/input/onboarding/onboarding-runtime-status.ts +10 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +8 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +4 -1
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +136 -0
- package/src/input/onboarding/onboarding-wizard-steps.ts +9 -6
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/panel-integration-actions.ts +9 -170
- package/src/input/panel-mouse-geometry.ts +97 -0
- package/src/input/panel-paste-flood-guard.ts +86 -0
- package/src/input/selection-modal.ts +11 -0
- package/src/input/session-picker-modal.ts +44 -4
- package/src/input/settings-modal-data.ts +146 -2
- package/src/input/settings-modal-mutations.ts +6 -4
- package/src/input/settings-modal-types.ts +4 -2
- package/src/main.ts +49 -51
- package/src/panels/agent-inspector-shared.ts +2 -1
- package/src/panels/base-panel.ts +22 -1
- package/src/panels/builtin/agent.ts +21 -107
- package/src/panels/builtin/development.ts +15 -61
- package/src/panels/builtin/knowledge.ts +8 -32
- package/src/panels/builtin/operations.ts +84 -428
- package/src/panels/builtin/session.ts +21 -112
- package/src/panels/builtin/shared.ts +18 -46
- package/src/panels/builtin-modals.ts +218 -0
- package/src/panels/builtin-panels.ts +5 -0
- package/src/panels/cost-tracker-panel.ts +36 -10
- package/src/panels/diff-panel.ts +12 -43
- package/src/panels/eval-registry.ts +60 -0
- package/src/panels/fleet-deep-link.ts +31 -0
- package/src/panels/fleet-panel-format.ts +62 -0
- package/src/panels/fleet-panel-worktree-detail.ts +48 -0
- package/src/panels/fleet-panel.ts +758 -0
- package/src/panels/fleet-read-model.ts +520 -0
- package/src/panels/fleet-steer.ts +125 -0
- package/src/panels/fleet-stop.ts +153 -0
- package/src/panels/fleet-tabs.ts +230 -0
- package/src/panels/fleet-transcript.ts +356 -0
- package/src/panels/index.ts +7 -31
- package/src/panels/modals/hooks-modal.ts +187 -0
- package/src/panels/modals/keybindings-modal.ts +166 -0
- package/src/panels/modals/knowledge-modal.ts +158 -0
- package/src/panels/modals/local-auth-modal.ts +132 -0
- package/src/panels/modals/marketplace-modal.ts +218 -0
- package/src/panels/modals/memory-modal.ts +180 -0
- package/src/panels/modals/modal-surface-helpers.ts +54 -0
- package/src/panels/modals/modal-theme.ts +42 -0
- package/src/panels/modals/pairing-modal.ts +163 -0
- package/src/panels/modals/planning-modal.ts +304 -0
- package/src/panels/modals/plugins-modal.ts +174 -0
- package/src/panels/modals/policy-modal.ts +256 -0
- package/src/panels/modals/provider-health-modal.ts +136 -0
- package/src/panels/modals/remote-modal.ts +115 -0
- package/src/panels/modals/sandbox-modal.ts +150 -0
- package/src/panels/modals/security-modal.ts +217 -0
- package/src/panels/modals/services-modal.ts +179 -0
- package/src/panels/modals/settings-sync-modal.ts +142 -0
- package/src/panels/modals/skills-modal.ts +189 -0
- package/src/panels/modals/subscription-modal.ts +172 -0
- package/src/panels/modals/work-plan-modal.ts +177 -0
- package/src/panels/panel-confirm-overlay.ts +72 -0
- package/src/panels/panel-manager.ts +123 -9
- package/src/panels/polish-core.ts +38 -25
- package/src/panels/project-planning-answer-actions.ts +8 -11
- package/src/panels/skills-panel.ts +7 -51
- package/src/panels/types.ts +37 -0
- package/src/permissions/hunk-selection.ts +179 -0
- package/src/permissions/prompt.ts +216 -13
- package/src/renderer/autocomplete-overlay.ts +28 -2
- package/src/renderer/compaction-history-modal.ts +19 -3
- package/src/renderer/compaction-preview.ts +13 -2
- package/src/renderer/compaction-quality.ts +100 -0
- package/src/renderer/compositor.ts +2 -3
- package/src/renderer/config-modal.ts +95 -0
- package/src/renderer/conversation-overlays.ts +10 -17
- package/src/renderer/fleet-tab-strip.ts +56 -0
- package/src/renderer/footer-tips.ts +15 -3
- package/src/renderer/fullscreen-primitives.ts +32 -22
- package/src/renderer/git-status.ts +43 -1
- package/src/renderer/help-overlay.ts +2 -2
- package/src/renderer/layout.ts +0 -4
- package/src/renderer/markdown.ts +7 -3
- package/src/renderer/modal-factory.ts +25 -20
- package/src/renderer/model-workspace.ts +62 -4
- package/src/renderer/overlay-box.ts +21 -17
- package/src/renderer/panel-workspace-bar.ts +8 -2
- package/src/renderer/process-indicator.ts +14 -3
- package/src/renderer/selection-modal-overlay.ts +6 -1
- package/src/renderer/session-picker-modal.ts +196 -3
- package/src/renderer/settings-modal-helpers.ts +2 -0
- package/src/renderer/settings-modal.ts +7 -0
- package/src/renderer/shell-surface.ts +8 -1
- package/src/renderer/status-glyphs.ts +14 -15
- package/src/renderer/system-message.ts +15 -3
- package/src/renderer/terminal-bg-probe.ts +339 -0
- package/src/renderer/terminal-escapes.ts +20 -0
- package/src/renderer/theme-mode-config.ts +67 -0
- package/src/renderer/theme.ts +91 -1
- package/src/renderer/thinking.ts +11 -3
- package/src/renderer/tool-call.ts +15 -9
- package/src/renderer/tool-result-summary.ts +148 -0
- package/src/renderer/turn-injection.ts +133 -0
- package/src/renderer/ui-factory.ts +154 -85
- package/src/renderer/ui-primitives.ts +30 -129
- package/src/runtime/bootstrap-command-context.ts +27 -1
- package/src/runtime/bootstrap-command-parts.ts +41 -10
- package/src/runtime/bootstrap-core.ts +47 -15
- package/src/runtime/bootstrap-hook-bridge.ts +7 -0
- package/src/runtime/bootstrap-shell.ts +48 -17
- package/src/runtime/bootstrap.ts +129 -22
- package/src/runtime/code-index-services.ts +135 -0
- package/src/runtime/legacy-daemon-migration.ts +516 -0
- package/src/runtime/memory-fold.ts +26 -0
- package/src/runtime/onboarding/derivation.ts +7 -2
- package/src/runtime/onboarding/snapshot.ts +27 -1
- package/src/runtime/onboarding/types.ts +31 -1
- package/src/runtime/operator-token-cleanup.ts +82 -1
- package/src/runtime/orchestrator-core-services.ts +59 -0
- package/src/runtime/process-lifecycle.ts +3 -1
- package/src/runtime/resume-notice.ts +209 -0
- package/src/runtime/services.ts +98 -46
- package/src/runtime/session-inbound-inputs.ts +252 -0
- package/src/runtime/session-spine-transport.ts +64 -0
- package/src/runtime/terminal-output-guard.ts +15 -8
- package/src/runtime/ui-services.ts +27 -3
- package/src/runtime/workstream-services.ts +327 -0
- package/src/runtime/wrfc-persistence.ts +124 -17
- package/src/shell/blocking-input.ts +68 -4
- package/src/shell/recovery-input-helpers.ts +170 -1
- package/src/shell/ui-openers.ts +171 -26
- package/src/utils/format-duration.ts +8 -18
- package/src/utils/splash-lines.ts +1 -1
- package/src/utils/terminal-width.ts +52 -0
- package/src/version.ts +1 -1
- package/src/panels/agent-inspector-panel.ts +0 -786
- package/src/panels/approval-panel.ts +0 -252
- package/src/panels/automation-control-panel.ts +0 -479
- package/src/panels/cockpit-panel.ts +0 -481
- package/src/panels/cockpit-read-model.ts +0 -238
- package/src/panels/communication-panel.ts +0 -256
- package/src/panels/control-plane-panel.ts +0 -470
- package/src/panels/debug-panel.ts +0 -615
- package/src/panels/docs-panel.ts +0 -384
- package/src/panels/eval-panel.ts +0 -627
- package/src/panels/file-explorer-panel.ts +0 -673
- package/src/panels/file-preview-panel.ts +0 -517
- package/src/panels/hooks-panel.ts +0 -401
- package/src/panels/incident-review-panel.ts +0 -406
- package/src/panels/intelligence-panel.ts +0 -383
- package/src/panels/knowledge-graph-panel.ts +0 -515
- package/src/panels/marketplace-panel.ts +0 -399
- package/src/panels/memory-panel.ts +0 -558
- package/src/panels/ops-control-panel.ts +0 -329
- package/src/panels/ops-strategy-panel.ts +0 -321
- package/src/panels/orchestration-panel.ts +0 -465
- package/src/panels/panel-list-panel.ts +0 -566
- package/src/panels/plan-dashboard-panel.ts +0 -707
- package/src/panels/policy-panel.ts +0 -517
- package/src/panels/project-planning-panel.ts +0 -731
- package/src/panels/provider-health-panel.ts +0 -678
- package/src/panels/provider-health-tracker.ts +0 -310
- package/src/panels/provider-health-views.ts +0 -567
- package/src/panels/qr-panel.ts +0 -280
- package/src/panels/remote-panel.ts +0 -534
- package/src/panels/routes-panel.ts +0 -241
- package/src/panels/sandbox-panel.ts +0 -456
- package/src/panels/security-panel.ts +0 -447
- package/src/panels/services-panel.ts +0 -329
- package/src/panels/session-browser-panel.ts +0 -496
- package/src/panels/settings-sync-panel.ts +0 -398
- package/src/panels/subscription-panel.ts +0 -342
- package/src/panels/symbol-outline-panel.ts +0 -619
- package/src/panels/system-messages-panel.ts +0 -364
- package/src/panels/tasks-panel.ts +0 -608
- package/src/panels/thinking-panel.ts +0 -333
- package/src/panels/tool-inspector-panel.ts +0 -537
- package/src/panels/work-plan-panel.ts +0 -540
- package/src/panels/worktree-panel.ts +0 -360
- package/src/panels/wrfc-panel.ts +0 -790
- package/src/renderer/agent-detail-modal.ts +0 -466
- package/src/renderer/live-tail-modal.ts +0 -156
- package/src/renderer/process-modal.ts +0 -671
- package/src/renderer/qr-renderer.ts +0 -120
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { createOAuthLocalListener } from '@pellux/goodvibes-sdk/platform/config';
|
|
1
|
+
import { createOAuthLocalListener, resolveDaemonEnabled } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import { beginOpenAICodexLogin, exchangeOpenAICodexCode } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
3
|
import { summarizeError, openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
4
|
import { getProviderIdFromModel } from '../config/provider-model.ts';
|
|
5
5
|
import { buildProviderAccountSnapshot } from '@/runtime/index.ts';
|
|
6
|
+
import { handleConnectExistingDaemonForHandler, handleMigrateLegacyDaemonServiceForHandler } from './handler-onboarding-daemon-adopt.ts';
|
|
7
|
+
import { detectLegacyUnit, resolveConfiguredServiceName } from '../runtime/legacy-daemon-migration.ts';
|
|
6
8
|
import { OnboardingWizardController, type OnboardingWizardAction, type OnboardingWizardApplyFeedback } from './onboarding/onboarding-wizard.ts';
|
|
7
9
|
import { handleCloudflareOnboardingActionForHandler, maybeProvisionCloudflareOnFinalApplyForHandler } from './handler-onboarding-cloudflare.ts';
|
|
8
10
|
import { applyOnboardingRequest, collectOnboardingSnapshot, deleteWizardProgress, verifyOnboardingRequest, writeOnboardingCheckMarker, writeWizardProgress } from '../runtime/onboarding/index.ts';
|
|
@@ -74,6 +76,41 @@ function formatRuntimeStoppedFailureMessage(
|
|
|
74
76
|
return `${binding.label} was disabled for ${disabledSurface}, but ${binding.host}:${binding.port} is still occupied. Settings were saved; another GoodVibes process or external service may still be running on that port.${statusDetail}`;
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Verification item(s) for one runtime endpoint given whether it is expected
|
|
81
|
+
* to be running. Shared by both the "nothing server-backed selected" early
|
|
82
|
+
* path and the full server-backed path so daemon-by-default (the loopback
|
|
83
|
+
* daemon can be `expected` even when nothing else was selected) is handled
|
|
84
|
+
* identically in both places.
|
|
85
|
+
*/
|
|
86
|
+
function buildEndpointVerificationItems(
|
|
87
|
+
handler: InputHandler,
|
|
88
|
+
request: OnboardingApplyRequest,
|
|
89
|
+
endpoint: OnboardingRuntimeEndpoint,
|
|
90
|
+
expected: boolean,
|
|
91
|
+
state: OnboardingExternalServiceState | undefined,
|
|
92
|
+
): OnboardingVerificationItem[] {
|
|
93
|
+
const idPrefix = endpoint === 'daemon' ? 'daemon' : 'http-listener';
|
|
94
|
+
if (expected) {
|
|
95
|
+
const active = isRuntimeEndpointActive(state, endpoint);
|
|
96
|
+
return [{
|
|
97
|
+
id: `runtime:${idPrefix}-active`,
|
|
98
|
+
status: active ? 'pass' : 'fail',
|
|
99
|
+
message: active
|
|
100
|
+
? formatRuntimeActiveSuccessMessage(endpoint, state)
|
|
101
|
+
: formatRuntimeActiveFailureMessage(handler, request, endpoint, state),
|
|
102
|
+
target: 'service',
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
105
|
+
if (!isRuntimeEndpointOccupyingConfiguredPort(state, endpoint)) return [];
|
|
106
|
+
return [{
|
|
107
|
+
id: `runtime:${idPrefix}-stopped`,
|
|
108
|
+
status: 'fail',
|
|
109
|
+
message: formatRuntimeStoppedFailureMessage(handler, request, endpoint, state),
|
|
110
|
+
target: 'service',
|
|
111
|
+
}];
|
|
112
|
+
}
|
|
113
|
+
|
|
77
114
|
function showOnboardingApplyFeedbackForHandler(handler: InputHandler, feedback: OnboardingWizardApplyFeedback): void {
|
|
78
115
|
handler.onboardingWizard.setApplyFeedback(feedback);
|
|
79
116
|
const reviewIndex = handler.onboardingWizard.steps.findIndex((step) => step.id === 'review');
|
|
@@ -185,6 +222,15 @@ export function handleModelPickerCommitForHandler(handler: InputHandler): boolea
|
|
|
185
222
|
}
|
|
186
223
|
|
|
187
224
|
export async function handleOnboardingActionForHandler(handler: InputHandler, action: OnboardingWizardAction): Promise<void> {
|
|
225
|
+
if (action === 'connect-existing-daemon') {
|
|
226
|
+
await handleConnectExistingDaemonForHandler(handler);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (action === 'migrate-legacy-daemon-service') {
|
|
230
|
+
const confirm = handler.onboardingWizard.getBooleanFieldValue('network.migrate-legacy-daemon-confirm', false);
|
|
231
|
+
await handleMigrateLegacyDaemonServiceForHandler(handler, confirm);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
188
234
|
if (action === 'start-openai-subscription') {
|
|
189
235
|
await handler.handleOpenAiSubscriptionStart();
|
|
190
236
|
return;
|
|
@@ -309,6 +355,7 @@ export async function handleOnboardingActionForHandler(handler: InputHandler, ac
|
|
|
309
355
|
handler.requestRender();
|
|
310
356
|
}
|
|
311
357
|
|
|
358
|
+
|
|
312
359
|
export async function refreshOnboardingHydrationForHandler(handler: InputHandler, options: {
|
|
313
360
|
readonly preserveValues?: boolean;
|
|
314
361
|
readonly targetStepId?: string;
|
|
@@ -336,6 +383,9 @@ export async function refreshOnboardingHydrationForHandler(handler: InputHandler
|
|
|
336
383
|
secretsManager: handler.uiServices.platform.secretsManager,
|
|
337
384
|
}),
|
|
338
385
|
},
|
|
386
|
+
legacyDaemon: {
|
|
387
|
+
detect: () => ({ ...detectLegacyUnit({ homeDir: handler.uiServices.environment.homeDirectory }), trackedServiceName: resolveConfiguredServiceName(handler.uiServices.platform.configManager) }),
|
|
388
|
+
},
|
|
339
389
|
});
|
|
340
390
|
if (!handler.onboardingWizard.active || hydrationSerial !== handler.onboardingHydrationSerial) return;
|
|
341
391
|
handler.onboardingWizard.hydrateRuntimeState({ snapshot }, { resetValues: !(options.preserveValues ?? false) });
|
|
@@ -572,7 +622,8 @@ export function getOnboardingRuntimePostureForHandler(handler: InputHandler, req
|
|
|
572
622
|
const serviceEnabled = getConfigValue('service.enabled') === true;
|
|
573
623
|
const serviceAutostart = getConfigValue('service.autostart') === true;
|
|
574
624
|
const restartOnFailure = getConfigValue('service.restartOnFailure') === true;
|
|
575
|
-
const
|
|
625
|
+
const daemonReader = { get: (key: string): boolean | string | number | undefined => getConfigValue(key) as boolean | string | number | undefined };
|
|
626
|
+
const daemonEnabled = resolveDaemonEnabled(daemonReader) || getConfigValue('controlPlane.enabled') === true;
|
|
576
627
|
const listenerEnabled = getConfigValue('danger.httpListener') === true;
|
|
577
628
|
const webEnabled = getConfigValue('web.enabled') === true;
|
|
578
629
|
const controlPlaneRemote = getConfigValue('controlPlane.hostMode') === 'network'
|
|
@@ -593,7 +644,10 @@ export function getOnboardingRuntimePostureForHandler(handler: InputHandler, req
|
|
|
593
644
|
restartOnFailure,
|
|
594
645
|
expectedDaemon: daemonEnabled || webEnabled,
|
|
595
646
|
expectedHttpListener: listenerEnabled,
|
|
596
|
-
|
|
647
|
+
// Daemon-by-default: the loopback session daemon can be expected to run
|
|
648
|
+
// even when nothing else was explicitly enabled here, so it does not
|
|
649
|
+
// belong in "did onboarding opt into a network-facing bundle."
|
|
650
|
+
serverBacked: serviceEnabled || listenerEnabled || webEnabled,
|
|
597
651
|
remoteExposure,
|
|
598
652
|
};
|
|
599
653
|
}
|
|
@@ -683,28 +737,20 @@ export function verifyOnboardingRuntimePostureForHandler(handler: InputHandler,
|
|
|
683
737
|
}];
|
|
684
738
|
}
|
|
685
739
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
if (isRuntimeEndpointOccupyingConfiguredPort(externalState, 'httpListener')) {
|
|
696
|
-
stoppedItems.push({
|
|
697
|
-
id: 'runtime:http-listener-stopped',
|
|
698
|
-
status: 'fail',
|
|
699
|
-
message: formatRuntimeStoppedFailureMessage(handler, request, 'httpListener', externalState),
|
|
700
|
-
target: 'service',
|
|
701
|
-
});
|
|
702
|
-
}
|
|
740
|
+
// Daemon-by-default: expectedDaemon can be true here (loopback daemon
|
|
741
|
+
// running for cross-surface visibility) even though nothing else was
|
|
742
|
+
// selected, so this is not simply "everything must be stopped."
|
|
743
|
+
const stoppedItems: OnboardingVerificationItem[] = [
|
|
744
|
+
...buildEndpointVerificationItems(handler, request, 'daemon', posture.expectedDaemon, externalState),
|
|
745
|
+
...buildEndpointVerificationItems(handler, request, 'httpListener', posture.expectedHttpListener, externalState),
|
|
746
|
+
];
|
|
703
747
|
if (externalState && stoppedItems.length === 0) {
|
|
704
748
|
stoppedItems.push({
|
|
705
749
|
id: 'runtime:external-services-stopped',
|
|
706
750
|
status: 'pass',
|
|
707
|
-
message:
|
|
751
|
+
message: posture.expectedDaemon
|
|
752
|
+
? 'HTTP listener is stopped for Local TUI Only; the background daemon is running as expected for cross-surface visibility on this machine.'
|
|
753
|
+
: 'Background daemon and HTTP listener are stopped for Local TUI Only.',
|
|
708
754
|
target: 'service',
|
|
709
755
|
});
|
|
710
756
|
}
|
|
@@ -742,44 +788,10 @@ export function verifyOnboardingRuntimePostureForHandler(handler: InputHandler,
|
|
|
742
788
|
});
|
|
743
789
|
}
|
|
744
790
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
status: daemonActive ? 'pass' : 'fail',
|
|
750
|
-
message: daemonActive
|
|
751
|
-
? formatRuntimeActiveSuccessMessage('daemon', externalState)
|
|
752
|
-
: formatRuntimeActiveFailureMessage(handler, request, 'daemon', externalState),
|
|
753
|
-
target: 'service',
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
if (!posture.expectedDaemon && isRuntimeEndpointOccupyingConfiguredPort(externalState, 'daemon')) {
|
|
757
|
-
items.push({
|
|
758
|
-
id: 'runtime:daemon-stopped',
|
|
759
|
-
status: 'fail',
|
|
760
|
-
message: formatRuntimeStoppedFailureMessage(handler, request, 'daemon', externalState),
|
|
761
|
-
target: 'service',
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
if (posture.expectedHttpListener) {
|
|
765
|
-
const httpListenerActive = isRuntimeEndpointActive(externalState, 'httpListener');
|
|
766
|
-
items.push({
|
|
767
|
-
id: 'runtime:http-listener-active',
|
|
768
|
-
status: httpListenerActive ? 'pass' : 'fail',
|
|
769
|
-
message: httpListenerActive
|
|
770
|
-
? formatRuntimeActiveSuccessMessage('httpListener', externalState)
|
|
771
|
-
: formatRuntimeActiveFailureMessage(handler, request, 'httpListener', externalState),
|
|
772
|
-
target: 'service',
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
if (!posture.expectedHttpListener && isRuntimeEndpointOccupyingConfiguredPort(externalState, 'httpListener')) {
|
|
776
|
-
items.push({
|
|
777
|
-
id: 'runtime:http-listener-stopped',
|
|
778
|
-
status: 'fail',
|
|
779
|
-
message: formatRuntimeStoppedFailureMessage(handler, request, 'httpListener', externalState),
|
|
780
|
-
target: 'service',
|
|
781
|
-
});
|
|
782
|
-
}
|
|
791
|
+
items.push(
|
|
792
|
+
...buildEndpointVerificationItems(handler, request, 'daemon', posture.expectedDaemon, externalState),
|
|
793
|
+
...buildEndpointVerificationItems(handler, request, 'httpListener', posture.expectedHttpListener, externalState),
|
|
794
|
+
);
|
|
783
795
|
|
|
784
796
|
return items;
|
|
785
797
|
}
|
|
@@ -5,7 +5,6 @@ import type { CapabilityFilter, CategoryFilter, ModelPickerModal } from './model
|
|
|
5
5
|
import { MODEL_PICKER_CHROME_LINES } from '../renderer/model-picker-overlay.ts';
|
|
6
6
|
import { resolveAndValidatePath } from '@pellux/goodvibes-sdk/platform/utils';
|
|
7
7
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
8
|
-
import type { ProcessEntry } from '../renderer/process-modal.ts';
|
|
9
8
|
import type { BlockActionId } from '../renderer/block-actions.ts';
|
|
10
9
|
|
|
11
10
|
type ModelPickerRouteState = {
|
|
@@ -23,13 +22,15 @@ export function handleModelPickerToken(state: ModelPickerRouteState, token: Inpu
|
|
|
23
22
|
|
|
24
23
|
if (token.type === 'key') {
|
|
25
24
|
if (token.logicalName === 'escape') {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
// W3-T2: search now starts focused by default (see
|
|
26
|
+
// ModelPickerModal.openAllModels() doc comment). Escape with an empty
|
|
27
|
+
// query used to only blurSearch() here, leaving the picker open and
|
|
28
|
+
// requiring a SECOND Escape to actually close it — confusing on a
|
|
29
|
+
// freshly-opened, untouched picker where there is nothing to "clear".
|
|
30
|
+
// Clearing a non-empty query is still a distinct first Escape (whether
|
|
31
|
+
// or not search is focused); an empty query falls through to the same
|
|
32
|
+
// effort/contextCap/previousMode/close cascade as before.
|
|
33
|
+
if (state.modelPicker.mode !== 'contextCap' && state.modelPicker.query.length > 0) {
|
|
33
34
|
state.modelPicker.clearQuery();
|
|
34
35
|
} else if (state.modelPicker.mode === 'effort') {
|
|
35
36
|
state.modelPicker.mode = 'model';
|
|
@@ -93,6 +94,13 @@ export function handleModelPickerToken(state: ModelPickerRouteState, token: Inpu
|
|
|
93
94
|
}
|
|
94
95
|
state.modelPicker.close();
|
|
95
96
|
if (state.modalStack[state.modalStack.length - 1] === 'modelPicker') state.modalStack.pop();
|
|
97
|
+
} else if (mode === 'embeddingProvider') {
|
|
98
|
+
const selectedProvider = state.modelPicker.embeddingProviders[idx];
|
|
99
|
+
if (selectedProvider) {
|
|
100
|
+
state.commandContext?.completeEmbeddingProviderSelection?.(selectedProvider.id);
|
|
101
|
+
}
|
|
102
|
+
state.modelPicker.close();
|
|
103
|
+
if (state.modalStack[state.modalStack.length - 1] === 'modelPicker') state.modalStack.pop();
|
|
96
104
|
} else if (mode === 'contextCap') {
|
|
97
105
|
const capModel = state.modelPicker.contextCapPendingModel;
|
|
98
106
|
if (capModel) {
|
|
@@ -123,7 +131,12 @@ export function handleModelPickerToken(state: ModelPickerRouteState, token: Inpu
|
|
|
123
131
|
}
|
|
124
132
|
if (state.modelPicker.canFocusSearch() && !state.modelPicker.searchFocused && state.modelPicker.selectedIndex === 0) {
|
|
125
133
|
state.modelPicker.focusSearch();
|
|
126
|
-
} else if (
|
|
134
|
+
} else if (state.modelPicker.searchFocused) {
|
|
135
|
+
// Symmetric with 'down' (below): search now starts focused by default
|
|
136
|
+
// (W3-T2), so 'up' must have a way out of it too, or it would be a
|
|
137
|
+
// silent no-op the very first time a user reaches for the list.
|
|
138
|
+
state.modelPicker.blurSearch();
|
|
139
|
+
} else {
|
|
127
140
|
const maxVis = Math.max(5, state.getViewportHeight() - MODEL_PICKER_CHROME_LINES - 4);
|
|
128
141
|
state.modelPicker.moveUp(maxVis);
|
|
129
142
|
}
|
|
@@ -201,99 +214,10 @@ function cycleCapabilityFilter(modelPicker: ModelPickerModal): void {
|
|
|
201
214
|
modelPicker.setCapabilityFilter(cycle[(cur + 1) % cycle.length]!);
|
|
202
215
|
}
|
|
203
216
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
moveDown: () => void;
|
|
209
|
-
getSelected: () => ProcessEntry | undefined;
|
|
210
|
-
close: () => void;
|
|
211
|
-
open: () => void;
|
|
212
|
-
killSelected: () => boolean;
|
|
213
|
-
refresh: () => void;
|
|
214
|
-
};
|
|
215
|
-
liveTailModal: {
|
|
216
|
-
open: (entry: ProcessEntry) => void;
|
|
217
|
-
};
|
|
218
|
-
agentDetailModal: {
|
|
219
|
-
open: (id: string) => void;
|
|
220
|
-
};
|
|
221
|
-
modalOpened: (name: string) => void;
|
|
222
|
-
requestRender: () => void;
|
|
223
|
-
handleEscape: () => void;
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
export function handleProcessModalToken(state: ProcessRouteState, token: InputToken): boolean {
|
|
227
|
-
if (!state.processModal.active) return false;
|
|
228
|
-
|
|
229
|
-
if (token.type === 'key') {
|
|
230
|
-
if (token.logicalName === 'escape') {
|
|
231
|
-
state.handleEscape();
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
if (token.logicalName === 'up') state.processModal.moveUp();
|
|
235
|
-
else if (token.logicalName === 'down') state.processModal.moveDown();
|
|
236
|
-
else if (token.logicalName === 'enter') {
|
|
237
|
-
const entry = state.processModal.getSelected();
|
|
238
|
-
if (entry) {
|
|
239
|
-
if (entry.type === 'agent') {
|
|
240
|
-
state.modalOpened('agentDetail');
|
|
241
|
-
state.processModal.close();
|
|
242
|
-
state.agentDetailModal.open(entry.id);
|
|
243
|
-
} else {
|
|
244
|
-
state.modalOpened('liveTail');
|
|
245
|
-
state.processModal.close();
|
|
246
|
-
state.liveTailModal.open(entry);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
} else if (token.type === 'text' && token.value === 'k') {
|
|
251
|
-
const killed = state.processModal.killSelected();
|
|
252
|
-
if (killed) state.processModal.refresh();
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
state.requestRender();
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
type LiveTailRouteState = {
|
|
260
|
-
liveTailModal: {
|
|
261
|
-
active: boolean;
|
|
262
|
-
scrollUp: () => void;
|
|
263
|
-
scrollDown: () => void;
|
|
264
|
-
killProcess: () => void;
|
|
265
|
-
close: () => void;
|
|
266
|
-
};
|
|
267
|
-
processModal: {
|
|
268
|
-
open: () => void;
|
|
269
|
-
};
|
|
270
|
-
requestRender: () => void;
|
|
271
|
-
handleEscape: () => void;
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
export function handleLiveTailToken(state: LiveTailRouteState, token: InputToken): boolean {
|
|
275
|
-
if (!state.liveTailModal.active) return false;
|
|
276
|
-
|
|
277
|
-
const killAndReturn = (): void => {
|
|
278
|
-
state.liveTailModal.killProcess();
|
|
279
|
-
state.handleEscape();
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
if (token.type === 'key') {
|
|
283
|
-
if (token.logicalName === 'escape') {
|
|
284
|
-
state.handleEscape();
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
if (token.logicalName === 'up') state.liveTailModal.scrollUp();
|
|
288
|
-
else if (token.logicalName === 'down') state.liveTailModal.scrollDown();
|
|
289
|
-
else if (token.logicalName === 'k') killAndReturn();
|
|
290
|
-
} else if (token.type === 'text' && token.value === 'k') {
|
|
291
|
-
killAndReturn();
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
state.requestRender();
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
217
|
+
// W6.2 e / W6.1 retirement: the process-modal and live-tail-modal token routes
|
|
218
|
+
// were removed with those modals (F2 now opens Fleet, which subsumes the live
|
|
219
|
+
// process tree). ProcessModal/AgentDetailModal/LiveTailModal were structurally
|
|
220
|
+
// unreachable after the F2 repoint and were deleted.
|
|
297
221
|
|
|
298
222
|
type EscapeOnlyModalRouteState = {
|
|
299
223
|
active: boolean;
|
|
@@ -55,13 +55,16 @@ export function handleGlobalShortcutToken(
|
|
|
55
55
|
): boolean {
|
|
56
56
|
if (token.type !== 'key') return false;
|
|
57
57
|
|
|
58
|
-
// Fast-path:
|
|
59
|
-
|
|
58
|
+
// Fast-path: BARE pageup/pagedown scroll the transcript. The `!token.ctrl`
|
|
59
|
+
// guard is load-bearing: Ctrl+PageUp/PageDown are the panel-tab-prev/next
|
|
60
|
+
// chords, so they must fall through to the keybinding lookup below instead of
|
|
61
|
+
// being swallowed here as a scroll.
|
|
62
|
+
if (token.logicalName === 'pageup' && !token.ctrl) {
|
|
60
63
|
if (state.panelFocused) return false;
|
|
61
64
|
state.scroll(-Math.max(1, viewportHeight - 2));
|
|
62
65
|
return true;
|
|
63
66
|
}
|
|
64
|
-
if (token.logicalName === 'pagedown') {
|
|
67
|
+
if (token.logicalName === 'pagedown' && !token.ctrl) {
|
|
65
68
|
if (state.panelFocused) return false;
|
|
66
69
|
state.scroll(Math.max(1, viewportHeight - 2));
|
|
67
70
|
return true;
|
|
@@ -72,6 +75,23 @@ export function handleGlobalShortcutToken(
|
|
|
72
75
|
return true;
|
|
73
76
|
}
|
|
74
77
|
|
|
78
|
+
// Bare F2 is also not in the keybinding table (hardcoded, like pageup/
|
|
79
|
+
// pagedown/escape above) — it must be handled here, GLOBALLY, rather than
|
|
80
|
+
// in handlePromptKeyToken (handler-feed-routes.ts) where it used to live.
|
|
81
|
+
// That location only ever runs when the panel workspace does NOT already
|
|
82
|
+
// own focus (handlePanelFocusToken, which runs before it, swallows every
|
|
83
|
+
// unclaimed key once panelFocused is true and reports it handled). The
|
|
84
|
+
// practical effect was that F2 could OPEN+focus the Fleet panel exactly
|
|
85
|
+
// once; every subsequent press while already focused vanished silently —
|
|
86
|
+
// "F2 pressed 4x never closed the panel" (UX-C evaluator finding). Routing
|
|
87
|
+
// it here, before handlePanelFocusToken ever sees the token, gives F2 the
|
|
88
|
+
// same toggle semantics as Ctrl+O below, matching how Ctrl+P/panel-picker
|
|
89
|
+
// was already reachable regardless of panelFocused.
|
|
90
|
+
if (token.logicalName === 'f2' && !token.ctrl && !token.meta) {
|
|
91
|
+
toggleFleetPanel(state);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
75
95
|
// O(1) lookup via inverted map.
|
|
76
96
|
const kb = state.keybindingsManager;
|
|
77
97
|
const action = kb.lookup(token);
|
|
@@ -101,6 +121,20 @@ export function handleGlobalShortcutToken(
|
|
|
101
121
|
case 'panel-close': {
|
|
102
122
|
const pm = state.panelManager;
|
|
103
123
|
const active = pm.getActivePanel();
|
|
124
|
+
// Wave-3: give the active panel a chance to consume Ctrl+X for an
|
|
125
|
+
// in-panel action (FleetPanel session-tab detach) before it closes the
|
|
126
|
+
// panel outright — see Panel.interceptPanelClose's doc comment.
|
|
127
|
+
if (active?.interceptPanelClose?.()) {
|
|
128
|
+
// UX-C fix: a consumed Ctrl+X (the Fleet panel's session-tab detach)
|
|
129
|
+
// used to leave panelFocused untouched, so focus stayed on the panel
|
|
130
|
+
// — the evaluator's "Ctrl+X detach landed focus in the panel and a
|
|
131
|
+
// typed question became nav keys". Detach is a leave-taking action:
|
|
132
|
+
// like the ordinary close below, it hands control back to the
|
|
133
|
+
// composer rather than leaving the user stranded on the fleet tree.
|
|
134
|
+
state.panelFocused = false;
|
|
135
|
+
state.requestRender();
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
104
138
|
if (active) {
|
|
105
139
|
pm.close(active.id);
|
|
106
140
|
state.requestRender();
|
|
@@ -150,27 +184,27 @@ export function handleGlobalShortcutToken(
|
|
|
150
184
|
// Alt+1..9: jump directly to the Nth workspace tab. Routed globally (like
|
|
151
185
|
// panel-tab-next/prev) so the jump works whether focus is on the prompt or
|
|
152
186
|
// the workspace; gated on visibility, matching cyclePanelTab semantics.
|
|
187
|
+
// UX-C: a chord jump is "I'm going panel-driving" (focus rule 1a) — the
|
|
188
|
+
// jump now also grabs keyboard focus, matching F2/Ctrl+O/Ctrl+P, so j/k
|
|
189
|
+
// land in the newly-active tab immediately instead of the composer.
|
|
153
190
|
const pm = state.panelManager;
|
|
154
191
|
if (pm.isVisible()) {
|
|
155
192
|
const index = Number(action.slice('panel-tab-'.length)) - 1;
|
|
156
193
|
pm.activateWorkspaceIndex(index);
|
|
194
|
+
pm.focusPanels();
|
|
195
|
+
state.panelFocused = true;
|
|
157
196
|
state.requestRender();
|
|
158
197
|
}
|
|
159
198
|
return true;
|
|
160
199
|
}
|
|
161
200
|
|
|
162
201
|
case 'panel-ops': {
|
|
163
|
-
// Ctrl+O:
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
state.commandContext.openOpsPanel();
|
|
170
|
-
} else {
|
|
171
|
-
state.panelManager.open('ops-control');
|
|
172
|
-
state.requestRender();
|
|
173
|
-
}
|
|
202
|
+
// Ctrl+O: TOGGLE the Fleet panel (UX-C — same semantics as F2 above; see
|
|
203
|
+
// toggleFleetPanel's doc comment). The former Ops Control panel was
|
|
204
|
+
// retired to an 'ops-control' -> 'fleet' alias (W6.1); rather than route
|
|
205
|
+
// through the now-aliased openOpsPanel callback (which opens without
|
|
206
|
+
// transferring focus), this operates on 'fleet' directly.
|
|
207
|
+
toggleFleetPanel(state);
|
|
174
208
|
return true;
|
|
175
209
|
}
|
|
176
210
|
|
|
@@ -348,3 +382,29 @@ export function handleGlobalShortcutToken(
|
|
|
348
382
|
return false;
|
|
349
383
|
}
|
|
350
384
|
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* toggleFleetPanel — the shared F2 / Ctrl+O TOGGLE (UX-C item 2): if the
|
|
388
|
+
* Fleet panel is open AND the panel workspace currently owns keyboard focus
|
|
389
|
+
* with Fleet as the active tab, the chord CLOSES it and returns focus to the
|
|
390
|
+
* composer; if Fleet is open but not the focused/active tab, the chord brings
|
|
391
|
+
* it to front and focuses it; if Fleet isn't open at all, the chord opens and
|
|
392
|
+
* focuses it. Uses `state.panelFocused` (not a panelManager query) for the
|
|
393
|
+
* focus check, consistent with every other case in this file and with what
|
|
394
|
+
* the mocked PanelManager test doubles in global-shortcuts.test.ts actually
|
|
395
|
+
* implement.
|
|
396
|
+
*/
|
|
397
|
+
function toggleFleetPanel(state: GlobalShortcutRouteState): void {
|
|
398
|
+
const pm = state.panelManager;
|
|
399
|
+
const fleetOpen = pm.getAllOpen().some((p) => p.id === 'fleet');
|
|
400
|
+
const fleetIsFocusedActive = fleetOpen && state.panelFocused && pm.getActivePanel()?.id === 'fleet';
|
|
401
|
+
if (fleetIsFocusedActive) {
|
|
402
|
+
pm.close('fleet');
|
|
403
|
+
state.panelFocused = false;
|
|
404
|
+
} else {
|
|
405
|
+
pm.open('fleet');
|
|
406
|
+
pm.focusPanels();
|
|
407
|
+
state.panelFocused = true;
|
|
408
|
+
}
|
|
409
|
+
state.requestRender();
|
|
410
|
+
}
|
|
@@ -23,14 +23,12 @@ import type { SelectionManager } from './selection.ts';
|
|
|
23
23
|
import type { InfiniteBuffer } from '../core/history.ts';
|
|
24
24
|
import type { AutocompleteEngine } from './autocomplete.ts';
|
|
25
25
|
import type { BookmarkModal } from './bookmark-modal.ts';
|
|
26
|
-
import type { AgentDetailModal } from '../renderer/agent-detail-modal.ts';
|
|
27
|
-
import type { LiveTailModal } from '../renderer/live-tail-modal.ts';
|
|
28
26
|
import type { SettingsModal } from './settings-modal.ts';
|
|
29
27
|
import type { McpWorkspace } from './mcp-workspace.ts';
|
|
30
28
|
import type { SessionPickerModal } from './session-picker-modal.ts';
|
|
29
|
+
import type { ConfigModal } from './config-modal.ts';
|
|
31
30
|
import type { ProfilePickerModal } from './profile-picker-modal.ts';
|
|
32
31
|
import type { ContextInspectorModal } from '../renderer/context-inspector.ts';
|
|
33
|
-
import type { ProcessModal } from '../renderer/process-modal.ts';
|
|
34
32
|
import type { FilePickerModal } from './file-picker.ts';
|
|
35
33
|
import type { BlockActionsMenu } from '../renderer/block-actions.ts';
|
|
36
34
|
import type { SelectionModal } from './selection-modal.ts';
|
|
@@ -105,14 +103,12 @@ export interface InputHandlerLike {
|
|
|
105
103
|
|
|
106
104
|
// ── Modal objects ─────────────────────────────────────────────────────────
|
|
107
105
|
bookmarkModal: BookmarkModal;
|
|
108
|
-
agentDetailModal: AgentDetailModal;
|
|
109
|
-
liveTailModal: LiveTailModal;
|
|
110
106
|
settingsModal: SettingsModal;
|
|
111
107
|
mcpWorkspace: McpWorkspace;
|
|
112
108
|
sessionPickerModal: SessionPickerModal;
|
|
113
109
|
profilePickerModal: ProfilePickerModal;
|
|
110
|
+
configModal: ConfigModal;
|
|
114
111
|
contextInspectorModal: ContextInspectorModal;
|
|
115
|
-
processModal: ProcessModal;
|
|
116
112
|
modelPicker: ModelPickerModal;
|
|
117
113
|
filePicker: FilePickerModal;
|
|
118
114
|
blockActionsMenu: BlockActionsMenu;
|
|
@@ -55,14 +55,12 @@ export type ActiveModalState = {
|
|
|
55
55
|
helpOverlayActive: boolean;
|
|
56
56
|
shortcutsOverlayActive: boolean;
|
|
57
57
|
bookmarkModal: { active: boolean; close: () => void };
|
|
58
|
-
agentDetailModal: { active: boolean; close: () => void };
|
|
59
|
-
liveTailModal: { active: boolean; close: () => void };
|
|
60
58
|
settingsModal: { active: boolean; close: () => void };
|
|
61
59
|
mcpWorkspace?: { active: boolean; close: () => void; reopen: () => void };
|
|
62
60
|
sessionPickerModal: { active: boolean; close: () => void };
|
|
63
61
|
profilePickerModal: { active: boolean; close: () => void };
|
|
62
|
+
configModal: { active: boolean; close: () => void };
|
|
64
63
|
contextInspectorModal: { active: boolean; close: () => void };
|
|
65
|
-
processModal: { active: boolean; close: () => void };
|
|
66
64
|
modelPicker: { active: boolean; close: () => void };
|
|
67
65
|
filePicker: { active: boolean; close: () => void };
|
|
68
66
|
blockActionsMenu: { active: boolean; close: () => void };
|
|
@@ -75,14 +73,12 @@ export function getActiveModalName(state: ActiveModalState): string | null {
|
|
|
75
73
|
if (state.helpOverlayActive) return 'help';
|
|
76
74
|
if (state.shortcutsOverlayActive) return 'shortcuts';
|
|
77
75
|
if (state.bookmarkModal.active) return 'bookmark';
|
|
78
|
-
if (state.agentDetailModal.active) return 'agentDetail';
|
|
79
|
-
if (state.liveTailModal.active) return 'liveTail';
|
|
80
76
|
if (state.settingsModal.active) return 'settings';
|
|
81
77
|
if (state.mcpWorkspace?.active) return 'mcpWorkspace';
|
|
82
78
|
if (state.sessionPickerModal.active) return 'sessionPicker';
|
|
83
79
|
if (state.profilePickerModal.active) return 'profilePicker';
|
|
80
|
+
if (state.configModal.active) return 'config';
|
|
84
81
|
if (state.contextInspectorModal.active) return 'contextInspector';
|
|
85
|
-
if (state.processModal.active) return 'process';
|
|
86
82
|
if (state.modelPicker.active) return 'modelPicker';
|
|
87
83
|
if (state.filePicker.active) return 'filePicker';
|
|
88
84
|
if (state.blockActionsMenu.active) return 'blockActions';
|
|
@@ -96,14 +92,12 @@ export type ModalCloseOps = {
|
|
|
96
92
|
resetHelp: () => void;
|
|
97
93
|
resetShortcuts: () => void;
|
|
98
94
|
closeBookmark: () => void;
|
|
99
|
-
closeAgentDetail: () => void;
|
|
100
|
-
closeLiveTail: () => void;
|
|
101
95
|
closeSettings: () => void;
|
|
102
96
|
closeMcpWorkspace: () => void;
|
|
103
97
|
closeSessionPicker: () => void;
|
|
104
98
|
closeProfilePicker: () => void;
|
|
99
|
+
closeConfigModal: () => void;
|
|
105
100
|
closeContextInspector: () => void;
|
|
106
|
-
closeProcess: () => void;
|
|
107
101
|
closeModelPicker: () => void;
|
|
108
102
|
closeFilePicker: () => void;
|
|
109
103
|
closeBlockActions: () => void;
|
|
@@ -123,12 +117,6 @@ export function closeModalByName(name: string, ops: ModalCloseOps): void {
|
|
|
123
117
|
case 'bookmark':
|
|
124
118
|
ops.closeBookmark();
|
|
125
119
|
break;
|
|
126
|
-
case 'agentDetail':
|
|
127
|
-
ops.closeAgentDetail();
|
|
128
|
-
break;
|
|
129
|
-
case 'liveTail':
|
|
130
|
-
ops.closeLiveTail();
|
|
131
|
-
break;
|
|
132
120
|
case 'settings':
|
|
133
121
|
ops.closeSettings();
|
|
134
122
|
break;
|
|
@@ -141,12 +129,12 @@ export function closeModalByName(name: string, ops: ModalCloseOps): void {
|
|
|
141
129
|
case 'profilePicker':
|
|
142
130
|
ops.closeProfilePicker();
|
|
143
131
|
break;
|
|
132
|
+
case 'config':
|
|
133
|
+
ops.closeConfigModal();
|
|
134
|
+
break;
|
|
144
135
|
case 'contextInspector':
|
|
145
136
|
ops.closeContextInspector();
|
|
146
137
|
break;
|
|
147
|
-
case 'process':
|
|
148
|
-
ops.closeProcess();
|
|
149
|
-
break;
|
|
150
138
|
case 'modelPicker':
|
|
151
139
|
ops.closeModelPicker();
|
|
152
140
|
break;
|
|
@@ -172,10 +160,10 @@ export type ModalOpenOps = {
|
|
|
172
160
|
openHelp: () => void;
|
|
173
161
|
openShortcuts: () => void;
|
|
174
162
|
openBookmark: () => void;
|
|
175
|
-
openProcess: () => void;
|
|
176
163
|
openContextInspector: () => void;
|
|
177
164
|
openMcpWorkspace?: () => void;
|
|
178
165
|
openOnboarding?: () => void;
|
|
166
|
+
openConfigModal?: () => void;
|
|
179
167
|
openCommandMode: () => void;
|
|
180
168
|
};
|
|
181
169
|
|
|
@@ -190,15 +178,15 @@ export function reopenModalByName(name: string, ops: ModalOpenOps): void {
|
|
|
190
178
|
case 'bookmark':
|
|
191
179
|
ops.openBookmark();
|
|
192
180
|
break;
|
|
193
|
-
case 'process':
|
|
194
|
-
ops.openProcess();
|
|
195
|
-
break;
|
|
196
181
|
case 'contextInspector':
|
|
197
182
|
ops.openContextInspector();
|
|
198
183
|
break;
|
|
199
184
|
case 'mcpWorkspace':
|
|
200
185
|
ops.openMcpWorkspace?.();
|
|
201
186
|
break;
|
|
187
|
+
case 'config':
|
|
188
|
+
ops.openConfigModal?.();
|
|
189
|
+
break;
|
|
202
190
|
case 'onboarding':
|
|
203
191
|
ops.openOnboarding?.();
|
|
204
192
|
break;
|