@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.
Files changed (194) hide show
  1. package/CHANGELOG.md +85 -21
  2. package/README.md +20 -11
  3. package/docs/foundation-artifacts/operator-contract.json +1 -1
  4. package/package.json +2 -2
  5. package/src/core/alert-gating.ts +67 -0
  6. package/src/core/approval-alert.ts +72 -0
  7. package/src/core/budget-breach-notifier.ts +106 -0
  8. package/src/core/conversation-rendering.ts +19 -0
  9. package/src/core/conversation.ts +18 -0
  10. package/src/core/focus-tracker.ts +41 -0
  11. package/src/core/long-task-notifier.ts +33 -6
  12. package/src/core/system-message-router.ts +37 -51
  13. package/src/core/turn-cancellation.ts +20 -0
  14. package/src/core/turn-event-wiring.ts +64 -3
  15. package/src/export/cost-utils.ts +36 -0
  16. package/src/input/command-registry.ts +38 -1
  17. package/src/input/commands/checkpoint-runtime.ts +280 -0
  18. package/src/input/commands/codebase-runtime.ts +192 -0
  19. package/src/input/commands/eval.ts +1 -1
  20. package/src/input/commands/health-runtime.ts +1 -1
  21. package/src/input/commands/image-runtime.ts +112 -0
  22. package/src/input/commands/intelligence-runtime.ts +11 -1
  23. package/src/input/commands/local-auth-runtime.ts +4 -1
  24. package/src/input/commands/local-runtime.ts +9 -3
  25. package/src/input/commands/marketplace-runtime.ts +2 -2
  26. package/src/input/commands/memory.ts +6 -1
  27. package/src/input/commands/operator-panel-runtime.ts +40 -24
  28. package/src/input/commands/planning-runtime.ts +26 -3
  29. package/src/input/commands/platform-sandbox-runtime.ts +1 -6
  30. package/src/input/commands/plugin-runtime.ts +2 -2
  31. package/src/input/commands/policy-dispatch.ts +21 -0
  32. package/src/input/commands/provider-accounts-runtime.ts +1 -1
  33. package/src/input/commands/qrcode-runtime.ts +3 -3
  34. package/src/input/commands/recall-review.ts +35 -0
  35. package/src/input/commands/remote-runtime.ts +3 -3
  36. package/src/input/commands/runtime-services.ts +54 -13
  37. package/src/input/commands/services-runtime.ts +1 -1
  38. package/src/input/commands/session-workflow.ts +16 -1
  39. package/src/input/commands/settings-sync-runtime.ts +1 -1
  40. package/src/input/commands/shell-core.ts +15 -7
  41. package/src/input/commands/skills-runtime.ts +2 -8
  42. package/src/input/commands/subscription-runtime.ts +2 -2
  43. package/src/input/commands/test-runtime.ts +277 -0
  44. package/src/input/commands/websearch-runtime.ts +101 -0
  45. package/src/input/commands/work-plan-runtime.ts +36 -10
  46. package/src/input/commands/workstream-runtime.ts +338 -0
  47. package/src/input/commands.ts +12 -0
  48. package/src/input/config-modal-types.ts +161 -0
  49. package/src/input/config-modal.ts +377 -0
  50. package/src/input/feed-context-factory.ts +7 -8
  51. package/src/input/handler-command-route.ts +27 -17
  52. package/src/input/handler-feed-routes.ts +61 -23
  53. package/src/input/handler-feed.ts +47 -23
  54. package/src/input/handler-interactions.ts +1 -3
  55. package/src/input/handler-modal-routes.ts +65 -0
  56. package/src/input/handler-modal-stack.ts +3 -5
  57. package/src/input/handler-modal-token-routes.ts +16 -49
  58. package/src/input/handler-picker-routes.ts +11 -94
  59. package/src/input/handler-shortcuts.ts +24 -14
  60. package/src/input/handler-types.ts +2 -6
  61. package/src/input/handler-ui-state.ts +10 -22
  62. package/src/input/handler.ts +6 -28
  63. package/src/input/keybindings.ts +22 -8
  64. package/src/input/model-picker-types.ts +24 -6
  65. package/src/input/model-picker.ts +58 -0
  66. package/src/input/panel-integration-actions.ts +9 -170
  67. package/src/input/settings-modal-data.ts +95 -0
  68. package/src/input/settings-modal-mutations.ts +6 -4
  69. package/src/main.ts +24 -27
  70. package/src/panels/agent-inspector-shared.ts +2 -1
  71. package/src/panels/base-panel.ts +22 -1
  72. package/src/panels/builtin/agent.ts +21 -107
  73. package/src/panels/builtin/development.ts +15 -61
  74. package/src/panels/builtin/knowledge.ts +8 -32
  75. package/src/panels/builtin/operations.ts +84 -428
  76. package/src/panels/builtin/session.ts +21 -112
  77. package/src/panels/builtin/shared.ts +9 -43
  78. package/src/panels/builtin-modals.ts +218 -0
  79. package/src/panels/builtin-panels.ts +5 -0
  80. package/src/panels/cost-tracker-panel.ts +36 -10
  81. package/src/panels/diff-panel.ts +12 -43
  82. package/src/panels/eval-registry.ts +60 -0
  83. package/src/panels/fleet-panel.ts +800 -0
  84. package/src/panels/fleet-read-model.ts +477 -0
  85. package/src/panels/fleet-steer.ts +92 -0
  86. package/src/panels/fleet-stop.ts +125 -0
  87. package/src/panels/fleet-tabs.ts +230 -0
  88. package/src/panels/fleet-transcript.ts +356 -0
  89. package/src/panels/index.ts +7 -31
  90. package/src/panels/modals/hooks-modal.ts +187 -0
  91. package/src/panels/modals/keybindings-modal.ts +151 -0
  92. package/src/panels/modals/knowledge-modal.ts +158 -0
  93. package/src/panels/modals/local-auth-modal.ts +132 -0
  94. package/src/panels/modals/marketplace-modal.ts +218 -0
  95. package/src/panels/modals/memory-modal.ts +180 -0
  96. package/src/panels/modals/modal-surface-helpers.ts +54 -0
  97. package/src/panels/modals/modal-theme.ts +36 -0
  98. package/src/panels/modals/pairing-modal.ts +144 -0
  99. package/src/panels/modals/planning-modal.ts +282 -0
  100. package/src/panels/modals/plugins-modal.ts +174 -0
  101. package/src/panels/modals/policy-modal.ts +256 -0
  102. package/src/panels/modals/provider-health-modal.ts +136 -0
  103. package/src/panels/modals/remote-modal.ts +115 -0
  104. package/src/panels/modals/sandbox-modal.ts +150 -0
  105. package/src/panels/modals/security-modal.ts +217 -0
  106. package/src/panels/modals/services-modal.ts +179 -0
  107. package/src/panels/modals/settings-sync-modal.ts +142 -0
  108. package/src/panels/modals/skills-modal.ts +189 -0
  109. package/src/panels/modals/subscription-modal.ts +172 -0
  110. package/src/panels/modals/work-plan-modal.ts +149 -0
  111. package/src/panels/panel-confirm-overlay.ts +72 -0
  112. package/src/panels/panel-manager.ts +108 -5
  113. package/src/panels/project-planning-answer-actions.ts +4 -2
  114. package/src/panels/skills-panel.ts +7 -51
  115. package/src/panels/types.ts +13 -0
  116. package/src/permissions/hunk-selection.ts +179 -0
  117. package/src/permissions/prompt.ts +60 -4
  118. package/src/renderer/compaction-history-modal.ts +19 -3
  119. package/src/renderer/compaction-preview.ts +13 -2
  120. package/src/renderer/compaction-quality.ts +100 -0
  121. package/src/renderer/config-modal.ts +81 -0
  122. package/src/renderer/conversation-overlays.ts +10 -17
  123. package/src/renderer/fleet-tab-strip.ts +56 -0
  124. package/src/renderer/footer-tips.ts +10 -2
  125. package/src/renderer/git-status.ts +40 -0
  126. package/src/renderer/help-overlay.ts +2 -2
  127. package/src/renderer/model-workspace.ts +44 -1
  128. package/src/renderer/panel-workspace-bar.ts +8 -2
  129. package/src/renderer/turn-injection.ts +114 -0
  130. package/src/runtime/bootstrap-command-context.ts +21 -1
  131. package/src/runtime/bootstrap-command-parts.ts +34 -7
  132. package/src/runtime/bootstrap-core.ts +14 -4
  133. package/src/runtime/bootstrap-shell.ts +29 -16
  134. package/src/runtime/bootstrap.ts +11 -17
  135. package/src/runtime/code-index-services.ts +112 -0
  136. package/src/runtime/orchestrator-core-services.ts +49 -0
  137. package/src/runtime/process-lifecycle.ts +3 -1
  138. package/src/runtime/services.ts +91 -43
  139. package/src/runtime/ui-services.ts +8 -0
  140. package/src/runtime/workstream-services.ts +195 -0
  141. package/src/shell/blocking-input.ts +22 -1
  142. package/src/shell/ui-openers.ts +129 -17
  143. package/src/utils/format-duration.ts +8 -18
  144. package/src/utils/splash-lines.ts +1 -1
  145. package/src/version.ts +1 -1
  146. package/src/panels/agent-inspector-panel.ts +0 -786
  147. package/src/panels/approval-panel.ts +0 -252
  148. package/src/panels/automation-control-panel.ts +0 -479
  149. package/src/panels/cockpit-panel.ts +0 -481
  150. package/src/panels/cockpit-read-model.ts +0 -238
  151. package/src/panels/communication-panel.ts +0 -256
  152. package/src/panels/control-plane-panel.ts +0 -470
  153. package/src/panels/debug-panel.ts +0 -615
  154. package/src/panels/docs-panel.ts +0 -384
  155. package/src/panels/eval-panel.ts +0 -627
  156. package/src/panels/file-explorer-panel.ts +0 -673
  157. package/src/panels/file-preview-panel.ts +0 -517
  158. package/src/panels/hooks-panel.ts +0 -401
  159. package/src/panels/incident-review-panel.ts +0 -406
  160. package/src/panels/intelligence-panel.ts +0 -383
  161. package/src/panels/knowledge-graph-panel.ts +0 -515
  162. package/src/panels/marketplace-panel.ts +0 -399
  163. package/src/panels/memory-panel.ts +0 -558
  164. package/src/panels/ops-control-panel.ts +0 -329
  165. package/src/panels/ops-strategy-panel.ts +0 -321
  166. package/src/panels/orchestration-panel.ts +0 -465
  167. package/src/panels/panel-list-panel.ts +0 -566
  168. package/src/panels/plan-dashboard-panel.ts +0 -707
  169. package/src/panels/policy-panel.ts +0 -517
  170. package/src/panels/project-planning-panel.ts +0 -731
  171. package/src/panels/provider-health-panel.ts +0 -678
  172. package/src/panels/provider-health-tracker.ts +0 -310
  173. package/src/panels/provider-health-views.ts +0 -567
  174. package/src/panels/qr-panel.ts +0 -280
  175. package/src/panels/remote-panel.ts +0 -534
  176. package/src/panels/routes-panel.ts +0 -241
  177. package/src/panels/sandbox-panel.ts +0 -456
  178. package/src/panels/security-panel.ts +0 -447
  179. package/src/panels/services-panel.ts +0 -329
  180. package/src/panels/session-browser-panel.ts +0 -496
  181. package/src/panels/settings-sync-panel.ts +0 -398
  182. package/src/panels/subscription-panel.ts +0 -342
  183. package/src/panels/symbol-outline-panel.ts +0 -619
  184. package/src/panels/system-messages-panel.ts +0 -364
  185. package/src/panels/tasks-panel.ts +0 -608
  186. package/src/panels/thinking-panel.ts +0 -333
  187. package/src/panels/tool-inspector-panel.ts +0 -537
  188. package/src/panels/work-plan-panel.ts +0 -540
  189. package/src/panels/worktree-panel.ts +0 -360
  190. package/src/panels/wrfc-panel.ts +0 -790
  191. package/src/renderer/agent-detail-modal.ts +0 -466
  192. package/src/renderer/live-tail-modal.ts +0 -156
  193. package/src/renderer/process-modal.ts +0 -671
  194. package/src/renderer/qr-renderer.ts +0 -120
@@ -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
- const buildModelPickerTargets = (): ModelPickerTargetInfo[] => {
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 the panel list when nothing is open yet).
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
- } else {
306
- if (panelManager.getAllOpen().length === 0) {
307
- try {
308
- panelManager.open('panel-list');
309
- } catch {
310
- // non-fatal
311
- }
312
- }
313
- panelManager.show();
314
- panelManager.focusPanels();
315
- conversation.setSplashSuppressed(true);
316
- conversation.rebuildHistory();
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
- * Three families are exported, each matching a distinct behavior cluster.
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: debug-panel, provider-health-panel
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: tool-inspector-panel, agent-inspector-shared
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 processes';
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.1.0';
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;