@pellux/goodvibes-tui 1.1.0 → 1.7.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 +20 -11
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +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/conversation-rendering.ts +19 -0
- 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/system-message-router.ts +37 -51
- package/src/core/turn-cancellation.ts +20 -0
- package/src/core/turn-event-wiring.ts +64 -3
- package/src/export/cost-utils.ts +36 -0
- package/src/input/command-registry.ts +38 -1
- package/src/input/commands/checkpoint-runtime.ts +280 -0
- package/src/input/commands/codebase-runtime.ts +192 -0
- package/src/input/commands/eval.ts +1 -1
- package/src/input/commands/health-runtime.ts +1 -1
- 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 +6 -1
- package/src/input/commands/operator-panel-runtime.ts +40 -24
- package/src/input/commands/planning-runtime.ts +26 -3
- 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 +3 -3
- package/src/input/commands/recall-review.ts +35 -0
- 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-workflow.ts +16 -1
- package/src/input/commands/settings-sync-runtime.ts +1 -1
- package/src/input/commands/shell-core.ts +15 -7
- 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 +338 -0
- package/src/input/commands.ts +12 -0
- package/src/input/config-modal-types.ts +161 -0
- package/src/input/config-modal.ts +377 -0
- package/src/input/feed-context-factory.ts +7 -8
- package/src/input/handler-command-route.ts +27 -17
- package/src/input/handler-feed-routes.ts +61 -23
- package/src/input/handler-feed.ts +47 -23
- package/src/input/handler-interactions.ts +1 -3
- package/src/input/handler-modal-routes.ts +65 -0
- package/src/input/handler-modal-stack.ts +3 -5
- package/src/input/handler-modal-token-routes.ts +16 -49
- package/src/input/handler-picker-routes.ts +11 -94
- package/src/input/handler-shortcuts.ts +24 -14
- package/src/input/handler-types.ts +2 -6
- package/src/input/handler-ui-state.ts +10 -22
- package/src/input/handler.ts +6 -28
- package/src/input/keybindings.ts +22 -8
- package/src/input/model-picker-types.ts +24 -6
- package/src/input/model-picker.ts +58 -0
- package/src/input/panel-integration-actions.ts +9 -170
- package/src/input/settings-modal-data.ts +95 -0
- package/src/input/settings-modal-mutations.ts +6 -4
- package/src/main.ts +24 -27
- 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 +9 -43
- 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-panel.ts +800 -0
- package/src/panels/fleet-read-model.ts +477 -0
- package/src/panels/fleet-steer.ts +92 -0
- package/src/panels/fleet-stop.ts +125 -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 +151 -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 +36 -0
- package/src/panels/modals/pairing-modal.ts +144 -0
- package/src/panels/modals/planning-modal.ts +282 -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 +149 -0
- package/src/panels/panel-confirm-overlay.ts +72 -0
- package/src/panels/panel-manager.ts +108 -5
- package/src/panels/project-planning-answer-actions.ts +4 -2
- package/src/panels/skills-panel.ts +7 -51
- package/src/panels/types.ts +13 -0
- package/src/permissions/hunk-selection.ts +179 -0
- package/src/permissions/prompt.ts +60 -4
- 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/config-modal.ts +81 -0
- package/src/renderer/conversation-overlays.ts +10 -17
- package/src/renderer/fleet-tab-strip.ts +56 -0
- package/src/renderer/footer-tips.ts +10 -2
- package/src/renderer/git-status.ts +40 -0
- package/src/renderer/help-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +44 -1
- package/src/renderer/panel-workspace-bar.ts +8 -2
- package/src/renderer/turn-injection.ts +114 -0
- package/src/runtime/bootstrap-command-context.ts +21 -1
- package/src/runtime/bootstrap-command-parts.ts +34 -7
- package/src/runtime/bootstrap-core.ts +14 -4
- package/src/runtime/bootstrap-shell.ts +29 -16
- package/src/runtime/bootstrap.ts +11 -17
- package/src/runtime/code-index-services.ts +112 -0
- package/src/runtime/orchestrator-core-services.ts +49 -0
- package/src/runtime/process-lifecycle.ts +3 -1
- package/src/runtime/services.ts +91 -43
- package/src/runtime/ui-services.ts +8 -0
- package/src/runtime/workstream-services.ts +195 -0
- package/src/shell/blocking-input.ts +22 -1
- package/src/shell/ui-openers.ts +129 -17
- package/src/utils/format-duration.ts +8 -18
- package/src/utils/splash-lines.ts +1 -1
- 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
package/src/shell/ui-openers.ts
CHANGED
|
@@ -10,8 +10,10 @@ import type { FeatureFlagManager } from '@/runtime/index.ts';
|
|
|
10
10
|
import type { McpRegistry } from '@pellux/goodvibes-sdk/platform/mcp';
|
|
11
11
|
import type { SubscriptionManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
12
12
|
import type { SecretsManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
13
|
+
import type { MemoryEmbeddingProviderRegistry } from '@pellux/goodvibes-sdk/platform/state';
|
|
13
14
|
import type { ServiceInspectionQuery } from '../runtime/ui-service-queries.ts';
|
|
14
|
-
import type { ModelPickerTargetInfo } from '../input/model-picker.ts';
|
|
15
|
+
import type { EmbeddingProviderPickerEntry, ModelPickerTargetInfo } from '../input/model-picker.ts';
|
|
16
|
+
import type { SelectionItem } from '../input/selection-modal.ts';
|
|
15
17
|
import { syncServiceSettingToPlatform } from './service-settings-sync.ts';
|
|
16
18
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
17
19
|
|
|
@@ -28,6 +30,8 @@ type WireShellUiOpenersOptions = {
|
|
|
28
30
|
subscriptionManager: SubscriptionManager;
|
|
29
31
|
secretsManager?: Pick<SecretsManager, 'delete' | 'get' | 'set'>;
|
|
30
32
|
serviceRegistry: Pick<ServiceInspectionQuery, 'getAll'>;
|
|
33
|
+
/** B29: backs the model picker's 'embeddings' target and its own item-list mode. */
|
|
34
|
+
memoryEmbeddingRegistry: Pick<MemoryEmbeddingProviderRegistry, 'getDefaultProviderId' | 'setDefaultProvider' | 'status'>;
|
|
31
35
|
workingDirectory: string;
|
|
32
36
|
homeDirectory: string;
|
|
33
37
|
getConfiguredProviderIds: () => string[];
|
|
@@ -93,6 +97,7 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
93
97
|
subscriptionManager,
|
|
94
98
|
secretsManager,
|
|
95
99
|
serviceRegistry,
|
|
100
|
+
memoryEmbeddingRegistry,
|
|
96
101
|
workingDirectory,
|
|
97
102
|
homeDirectory,
|
|
98
103
|
getConfiguredProviderIds,
|
|
@@ -125,6 +130,7 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
125
130
|
if (target === 'helper') return String(configManager.get('helper.globalModel') || runtime.model);
|
|
126
131
|
if (target === 'tool') return String(configManager.get('tools.llmModel') || runtime.model);
|
|
127
132
|
if (target === 'tts') return String(configManager.get('tts.llmModel') || runtime.model);
|
|
133
|
+
if (target === 'embeddings') return memoryEmbeddingRegistry.getDefaultProviderId();
|
|
128
134
|
return runtime.model;
|
|
129
135
|
};
|
|
130
136
|
|
|
@@ -134,10 +140,29 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
134
140
|
if (target === 'helper') return String(configManager.get('helper.globalProvider') || runtime.provider);
|
|
135
141
|
if (target === 'tool') return String(configManager.get('tools.llmProvider') || runtime.provider);
|
|
136
142
|
if (target === 'tts') return String(configManager.get('tts.llmProvider') || runtime.provider);
|
|
143
|
+
if (target === 'embeddings') return memoryEmbeddingRegistry.getDefaultProviderId();
|
|
137
144
|
return runtime.provider;
|
|
138
145
|
};
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Fetch the embedding-provider status list once per picker-open and shape
|
|
149
|
+
* it into the picker's own tiny item type. Uses the registry's async
|
|
150
|
+
* `.status()` (not the sync `.list()`) specifically because `.list()` does
|
|
151
|
+
* not carry `configured` — and unconfigured providers must be shown
|
|
152
|
+
* honestly, not hidden.
|
|
153
|
+
*/
|
|
154
|
+
async function resolveEmbeddingProviderEntries(): Promise<EmbeddingProviderPickerEntry[]> {
|
|
155
|
+
const statuses = await memoryEmbeddingRegistry.status();
|
|
156
|
+
return statuses.map((status) => ({
|
|
157
|
+
id: status.id,
|
|
158
|
+
label: status.label,
|
|
159
|
+
dimensions: status.dimensions,
|
|
160
|
+
configured: status.configured,
|
|
161
|
+
...(status.detail ? { detail: status.detail } : {}),
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const buildModelPickerTargets = (embeddingEntries: EmbeddingProviderPickerEntry[]): ModelPickerTargetInfo[] => {
|
|
141
166
|
const mainProvider = getProviderIdFromModel(configManager.get('provider.model') || runtime.provider).trim();
|
|
142
167
|
const mainModel = String(configManager.get('provider.model') || runtime.model || '').trim();
|
|
143
168
|
const helperProvider = String(configManager.get('helper.globalProvider') ?? '').trim();
|
|
@@ -146,6 +171,11 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
146
171
|
const toolModel = String(configManager.get('tools.llmModel') ?? '').trim();
|
|
147
172
|
const ttsProvider = String(configManager.get('tts.llmProvider') ?? '').trim();
|
|
148
173
|
const ttsModel = String(configManager.get('tts.llmModel') ?? '').trim();
|
|
174
|
+
const embeddingProviderId = memoryEmbeddingRegistry.getDefaultProviderId();
|
|
175
|
+
const embeddingEntry = embeddingEntries.find((entry) => entry.id === embeddingProviderId);
|
|
176
|
+
const embeddingNote = embeddingEntry
|
|
177
|
+
? `${embeddingEntry.id} · ${embeddingEntry.dimensions}d${embeddingEntry.configured ? '' : ' · unconfigured'}`
|
|
178
|
+
: `${embeddingProviderId} · unregistered`;
|
|
149
179
|
|
|
150
180
|
return [
|
|
151
181
|
{
|
|
@@ -184,6 +214,16 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
184
214
|
enabled: true,
|
|
185
215
|
inherited: ttsProvider.length === 0 && ttsModel.length === 0,
|
|
186
216
|
},
|
|
217
|
+
{
|
|
218
|
+
target: 'embeddings',
|
|
219
|
+
label: 'Embeddings',
|
|
220
|
+
description: 'Embedding provider used for memory search and the code index. Not an LLM route — no model concept.',
|
|
221
|
+
provider: embeddingProviderId,
|
|
222
|
+
model: '',
|
|
223
|
+
enabled: true,
|
|
224
|
+
inherited: false,
|
|
225
|
+
configuredNote: embeddingNote,
|
|
226
|
+
},
|
|
187
227
|
];
|
|
188
228
|
};
|
|
189
229
|
|
|
@@ -199,8 +239,10 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
199
239
|
input.modelPicker.pinnedIds = new Set(pinned);
|
|
200
240
|
});
|
|
201
241
|
void input.modelPicker.loadRecentModels().catch(() => {}); // best-effort: prefetch for UI, failure is non-visible
|
|
242
|
+
const embeddingEntries = await resolveEmbeddingProviderEntries();
|
|
243
|
+
input.modelPicker.embeddingProviders = embeddingEntries;
|
|
202
244
|
input.modalOpened('modelPicker');
|
|
203
|
-
input.modelPicker.setTargetInfos(buildModelPickerTargets());
|
|
245
|
+
input.modelPicker.setTargetInfos(buildModelPickerTargets(embeddingEntries));
|
|
204
246
|
input.modelPicker.openAllModels(models, getCurrentModelForPickerTarget());
|
|
205
247
|
render();
|
|
206
248
|
})().catch((error: unknown) => {
|
|
@@ -219,8 +261,10 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
219
261
|
input.modelPicker.configuredProviders = configuredIds;
|
|
220
262
|
const secretProviderIds = await resolveSecretProviderIds();
|
|
221
263
|
input.modelPicker.configuredViaMap = buildConfiguredViaMap(providers, configuredIds, subscriptionManager, secretProviderIds);
|
|
264
|
+
const embeddingEntries = await resolveEmbeddingProviderEntries();
|
|
265
|
+
input.modelPicker.embeddingProviders = embeddingEntries;
|
|
222
266
|
input.modalOpened('modelPicker');
|
|
223
|
-
input.modelPicker.setTargetInfos(buildModelPickerTargets());
|
|
267
|
+
input.modelPicker.setTargetInfos(buildModelPickerTargets(embeddingEntries));
|
|
224
268
|
input.modelPicker.openProviders(providers, getCurrentProviderForPickerTarget());
|
|
225
269
|
render();
|
|
226
270
|
})().catch((error: unknown) => {
|
|
@@ -229,6 +273,15 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
229
273
|
});
|
|
230
274
|
};
|
|
231
275
|
|
|
276
|
+
commandContext.completeEmbeddingProviderSelection = (providerId: string) => {
|
|
277
|
+
try {
|
|
278
|
+
memoryEmbeddingRegistry.setDefaultProvider(providerId);
|
|
279
|
+
} catch (error: unknown) {
|
|
280
|
+
commandContext.print?.(`Failed to set embedding provider: ${summarizeError(error)}`);
|
|
281
|
+
}
|
|
282
|
+
render();
|
|
283
|
+
};
|
|
284
|
+
|
|
232
285
|
commandContext.openSelection = (title, items, opts, callback) => {
|
|
233
286
|
input.openSelection(title, items, opts, callback);
|
|
234
287
|
};
|
|
@@ -281,6 +334,47 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
281
334
|
render();
|
|
282
335
|
};
|
|
283
336
|
|
|
337
|
+
// W6.1 (the purge): open a MIGRATE-TO-MODAL surface by name. Fed from both
|
|
338
|
+
// ctx.openModal(name) (migrated command front-doors) and PanelManager's
|
|
339
|
+
// open()-time modal-redirect callback (a legacy panel id resolving to a modal
|
|
340
|
+
// name). Surfaces are registered in builtin-modals.ts; a name with no
|
|
341
|
+
// registered surface degrades honestly to a print rather than a blank modal.
|
|
342
|
+
// The stack name is the stable 'config' slot (one config modal at a time —
|
|
343
|
+
// opening another swaps the surface), so Esc close/return and the modal-stack
|
|
344
|
+
// machinery need only the single 'config' case (handler-ui-state.ts).
|
|
345
|
+
// Some panel-id redirects (and migrated front-doors) resolve to a NATIVE
|
|
346
|
+
// modal that is not a ConfigModalSurface — e.g. `sessions` -> `sessionPicker`,
|
|
347
|
+
// where 'sessionPicker' is the real session-picker modal opened by
|
|
348
|
+
// commandContext.openSessionPicker below, NOT a registered config surface.
|
|
349
|
+
// getModalSurface can never find these, so consult this small name->opener
|
|
350
|
+
// dispatch FIRST. Each entry reuses the same opener the front-door command
|
|
351
|
+
// uses (no duplicated open logic); resolved lazily so wiring order does not
|
|
352
|
+
// matter. Any name that is neither a native modal nor a registered surface
|
|
353
|
+
// still falls through to the honest "not available" print below.
|
|
354
|
+
const nativeModalOpeners: Record<string, () => void> = {
|
|
355
|
+
// openSessionPicker is wired below in this same function; call it lazily
|
|
356
|
+
// (optional-chained for the type, always present at invoke time).
|
|
357
|
+
sessionPicker: () => commandContext.openSessionPicker?.(),
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
commandContext.openModal = (name: string) => {
|
|
361
|
+
const openNative = nativeModalOpeners[name];
|
|
362
|
+
if (openNative) {
|
|
363
|
+
openNative();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const surface = panelManager.getModalSurface(name);
|
|
367
|
+
if (!surface) {
|
|
368
|
+
commandContext.print(`'${name}' is not available yet in this build.`);
|
|
369
|
+
render();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
input.modalOpened('config');
|
|
373
|
+
input.configModal.open(surface, render);
|
|
374
|
+
render();
|
|
375
|
+
};
|
|
376
|
+
panelManager.setOpenModalCallback(commandContext.openModal);
|
|
377
|
+
|
|
284
378
|
commandContext.openMcpWorkspace = () => {
|
|
285
379
|
input.openMcpWorkspace(commandContext);
|
|
286
380
|
render();
|
|
@@ -296,25 +390,43 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
296
390
|
// Focus ownership lives in PanelManager (focusTarget); read it there rather
|
|
297
391
|
// than tracking a parallel input.panelFocused flag. Toggle semantics: if the
|
|
298
392
|
// workspace is visible AND already focused, hide it; otherwise reveal and
|
|
299
|
-
// focus it (opening
|
|
393
|
+
// focus it (opening a picker when nothing is open yet).
|
|
300
394
|
if (panelManager.isVisible() && panelManager.getFocusTarget() === 'panel') {
|
|
301
395
|
panelManager.hide();
|
|
302
396
|
panelManager.focusPrompt();
|
|
303
397
|
conversation.setSplashSuppressed(false);
|
|
304
398
|
conversation.rebuildHistory();
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
panelManager.
|
|
315
|
-
|
|
316
|
-
|
|
399
|
+
render();
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (panelManager.getAllOpen().length === 0) {
|
|
403
|
+
// W6.1 (the purge): 'panel-list' (a browse-all-panels picker PANEL)
|
|
404
|
+
// was DELETE-disposition — a picker over a handful of panels is dead
|
|
405
|
+
// weight now. Its replacement is this selection MODAL, built from the
|
|
406
|
+
// live registry (PanelManager.getRegisteredTypes()) rather than a
|
|
407
|
+
// hardcoded list, so it can never list a retired/deleted id.
|
|
408
|
+
const items: SelectionItem[] = panelManager.getRegisteredTypes().map((entry) => ({
|
|
409
|
+
id: entry.id,
|
|
410
|
+
label: `${entry.icon} ${entry.name}`,
|
|
411
|
+
detail: entry.description,
|
|
412
|
+
category: entry.category,
|
|
413
|
+
primaryAction: 'select',
|
|
414
|
+
}));
|
|
415
|
+
commandContext.openSelection?.('Open Panel', items, { allowSearch: true }, (result) => {
|
|
416
|
+
if (!result) return;
|
|
417
|
+
panelManager.open(result.item.id);
|
|
418
|
+
panelManager.show();
|
|
419
|
+
panelManager.focusPanels();
|
|
420
|
+
conversation.setSplashSuppressed(true);
|
|
421
|
+
conversation.rebuildHistory();
|
|
422
|
+
render();
|
|
423
|
+
});
|
|
424
|
+
return;
|
|
317
425
|
}
|
|
426
|
+
panelManager.show();
|
|
427
|
+
panelManager.focusPanels();
|
|
428
|
+
conversation.setSplashSuppressed(true);
|
|
429
|
+
conversation.rebuildHistory();
|
|
318
430
|
render();
|
|
319
431
|
};
|
|
320
432
|
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared ms-duration formatters for the panel layer.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Two families are exported, each matching a distinct behavior cluster.
|
|
5
5
|
* DO NOT replace these with formatElapsed from utils/format-elapsed.ts —
|
|
6
6
|
* formatElapsed floors to integer seconds and lacks the null/'?ms' guards
|
|
7
7
|
* that the latency panels require.
|
|
8
|
+
*
|
|
9
|
+
* W6.1 (the purge): formatShortDuration (used only by incident-review-panel
|
|
10
|
+
* and eval-panel, both removed — RETIRE-INTO-FLEET and DELETE respectively)
|
|
11
|
+
* was removed as a genuinely orphaned export — no remaining caller anywhere
|
|
12
|
+
* in src/.
|
|
8
13
|
*/
|
|
9
14
|
|
|
10
15
|
/**
|
|
11
16
|
* Format a latency value in milliseconds with sub-second precision.
|
|
12
17
|
*
|
|
13
|
-
* Used by:
|
|
18
|
+
* Used by: provider-health-panel
|
|
14
19
|
*
|
|
15
20
|
* ms <= 0 → 'n/a'
|
|
16
21
|
* ms >= 10000 → '12.3s' (one decimal)
|
|
@@ -27,7 +32,7 @@ export function formatLatencyMs(ms: number): string {
|
|
|
27
32
|
/**
|
|
28
33
|
* Format a task/agent duration with minute-rolling notation.
|
|
29
34
|
*
|
|
30
|
-
* Used by:
|
|
35
|
+
* Used by: agent-inspector-shared
|
|
31
36
|
*
|
|
32
37
|
* ms < 1000 → '500ms'
|
|
33
38
|
* ms < 60000 → '3.5s'
|
|
@@ -38,18 +43,3 @@ export function formatDuration(ms: number): string {
|
|
|
38
43
|
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
|
39
44
|
return `${Math.floor(ms / 60000)}m${Math.floor((ms % 60000) / 1000)}s`;
|
|
40
45
|
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Format a short eval/forensics duration; treats undefined as '?ms'.
|
|
44
|
-
*
|
|
45
|
-
* Used by: incident-review-panel, eval-panel
|
|
46
|
-
*
|
|
47
|
-
* undefined → '?ms'
|
|
48
|
-
* ms < 1000 → '500ms'
|
|
49
|
-
* else → '1.5s'
|
|
50
|
-
*/
|
|
51
|
-
export function formatShortDuration(ms: number | undefined): string {
|
|
52
|
-
if (ms === undefined) return '?ms';
|
|
53
|
-
if (ms < 1000) return `${ms}ms`;
|
|
54
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
55
|
-
}
|
|
@@ -24,7 +24,7 @@ const versionLine = (version: string) =>
|
|
|
24
24
|
` ✦ v${version} █ terminal AI assistant █ 自動コード ✦`;
|
|
25
25
|
|
|
26
26
|
/** Fixed hint line — the three primary shell entry points. */
|
|
27
|
-
const HINT_LINE = 'Ctrl+P panels / ? help / F2
|
|
27
|
+
const HINT_LINE = 'Ctrl+P panels / ? help / F2 fleet';
|
|
28
28
|
|
|
29
29
|
export interface SplashOptions {
|
|
30
30
|
workingDir?: string;
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '1.
|
|
9
|
+
let _version = '1.7.0';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
|
|
12
12
|
_version = pkg.version ?? _version;
|