pi-ui-extend 0.1.9 → 0.1.11
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/README.md +23 -2
- package/dist/app/app.d.ts +4 -0
- package/dist/app/app.js +74 -7
- package/dist/app/cli/install.d.ts +2 -0
- package/dist/app/cli/install.js +16 -1
- package/dist/app/commands/command-controller.js +4 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-model-actions.d.ts +5 -0
- package/dist/app/commands/command-model-actions.js +104 -0
- package/dist/app/commands/command-navigation-actions.d.ts +6 -1
- package/dist/app/commands/command-navigation-actions.js +37 -14
- package/dist/app/commands/command-registry.d.ts +4 -0
- package/dist/app/commands/command-registry.js +32 -0
- package/dist/app/commands/command-session-actions.d.ts +1 -0
- package/dist/app/commands/command-session-actions.js +15 -5
- package/dist/app/commands/shell-controller.d.ts +1 -0
- package/dist/app/commands/shell-controller.js +1 -1
- package/dist/app/constants.d.ts +1 -1
- package/dist/app/constants.js +1 -1
- package/dist/app/icons.js +1 -1
- package/dist/app/input/autocomplete-controller.d.ts +52 -0
- package/dist/app/input/autocomplete-controller.js +352 -0
- package/dist/app/input/input-action-controller.d.ts +1 -0
- package/dist/app/input/input-action-controller.js +21 -0
- package/dist/app/input/input-controller.d.ts +1 -0
- package/dist/app/input/input-controller.js +2 -0
- package/dist/app/input/input-paste-handler.d.ts +1 -0
- package/dist/app/input/input-paste-handler.js +22 -18
- package/dist/app/input/voice-controller.d.ts +2 -0
- package/dist/app/input/voice-controller.js +27 -15
- package/dist/app/model/model-usage-status.d.ts +9 -0
- package/dist/app/model/model-usage-status.js +124 -34
- package/dist/app/popup/popup-action-controller.js +1 -1
- package/dist/app/process.d.ts +17 -0
- package/dist/app/process.js +68 -0
- package/dist/app/rendering/conversation-entry-renderer.js +17 -6
- package/dist/app/rendering/conversation-tool-renderer.js +3 -2
- package/dist/app/rendering/editor-layout-renderer.d.ts +1 -0
- package/dist/app/rendering/editor-layout-renderer.js +11 -1
- package/dist/app/rendering/message-content.js +65 -7
- package/dist/app/rendering/render-controller.js +6 -1
- package/dist/app/rendering/render-text.d.ts +3 -0
- package/dist/app/rendering/render-text.js +51 -3
- package/dist/app/rendering/status-line-renderer.d.ts +5 -1
- package/dist/app/rendering/status-line-renderer.js +69 -25
- package/dist/app/rendering/tool-block-renderer.js +13 -31
- package/dist/app/runtime.d.ts +6 -1
- package/dist/app/runtime.js +35 -2
- package/dist/app/screen/clipboard.d.ts +2 -2
- package/dist/app/screen/clipboard.js +13 -18
- package/dist/app/screen/mouse-controller.d.ts +5 -2
- package/dist/app/screen/mouse-controller.js +16 -1
- package/dist/app/screen/screen-styler.d.ts +4 -1
- package/dist/app/screen/screen-styler.js +3 -2
- package/dist/app/screen/status-controller.d.ts +3 -0
- package/dist/app/screen/status-controller.js +23 -8
- package/dist/app/session/queued-message-controller.d.ts +7 -1
- package/dist/app/session/queued-message-controller.js +32 -21
- package/dist/app/session/resume-session-loader.d.ts +15 -0
- package/dist/app/session/resume-session-loader.js +204 -0
- package/dist/app/session/session-event-controller.d.ts +5 -1
- package/dist/app/session/session-event-controller.js +72 -5
- package/dist/app/session/session-history.js +4 -3
- package/dist/app/session/session-lifecycle-controller.d.ts +5 -0
- package/dist/app/session/session-lifecycle-controller.js +9 -1
- package/dist/app/session/tabs-controller.d.ts +10 -1
- package/dist/app/session/tabs-controller.js +101 -5
- package/dist/app/terminal/nerd-font-controller.js +16 -17
- package/dist/app/terminal/terminal-controller.d.ts +1 -0
- package/dist/app/terminal/terminal-controller.js +1 -0
- package/dist/app/types.d.ts +14 -0
- package/dist/app/workspace/workspace-actions-controller.d.ts +1 -1
- package/dist/app/workspace/workspace-actions-controller.js +3 -3
- package/dist/app/workspace/workspace-undo.d.ts +1 -1
- package/dist/app/workspace/workspace-undo.js +22 -20
- package/dist/config.d.ts +27 -0
- package/dist/config.js +174 -1
- package/dist/default-pix-config.js +38 -353
- package/dist/input-editor.d.ts +7 -1
- package/dist/input-editor.js +47 -6
- package/dist/markdown-format.d.ts +1 -0
- package/dist/markdown-format.js +26 -1
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +1 -0
- package/external/pi-tools-suite/src/dcp/prompts.ts +1 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +45 -195
- package/external/pi-tools-suite/src/lib/lsp.ts +2 -1
- package/external/pi-tools-suite/src/lsp/_shared/output.ts +8 -7
- package/external/pi-tools-suite/src/lsp/manager.ts +4 -4
- package/external/pi-tools-suite/src/repo-discovery/index.ts +49 -2
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +9 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,23 @@ The npm package is currently named `pi-ui-extend` and installs the `pix` CLI.
|
|
|
14
14
|
- Pix extension UI helpers for toasts, menus, and rows above the input editor.
|
|
15
15
|
- Bundled `pi-tools-suite` payload. On startup, Pix links it into Pi's standard user extension directory.
|
|
16
16
|
|
|
17
|
+
## Why use Pix instead of bare Pi?
|
|
18
|
+
|
|
19
|
+
Pix keeps the same Pi agent engine and SDK, but replaces the default terminal experience with a faster, more interactive coding cockpit:
|
|
20
|
+
|
|
21
|
+
- **Tabs for real work.** Keep several workspace-scoped Pi sessions open in one terminal, switch between tasks instantly, and restore tab state after restart.
|
|
22
|
+
- **A readable tool-call UI.** Tool output is grouped into clickable rows, so long reads, patches, shell logs, and errors can be collapsed or expanded instead of flooding the conversation.
|
|
23
|
+
- **Local shell without leaving the chat.** Prefix a command with `!` to run it in an ephemeral in-chat shell block, or use `!!` for raw TTY programs.
|
|
24
|
+
- **Voice prompts.** Dictate prompts locally in Russian or English with Vosk; no cloud speech service is required.
|
|
25
|
+
- **Prompt drafting assistance.** Inline AI autocomplete suggests the next words while you type, and `/enhance` rewrites a rough draft into a clearer agent prompt.
|
|
26
|
+
- **Workspace safety net.** Pix tracks supported file mutations and lets you roll back the latest workspace change with `/undo`.
|
|
27
|
+
- **Clickable files and images.** File paths in the conversation become clickable links that open in Zed, including line and column when available; image labels can be opened in the system viewer.
|
|
28
|
+
- **Session power tools.** Search across saved sessions, fork from an earlier message, clone the current branch, rename sessions, export/import JSONL, or share a private gist.
|
|
29
|
+
- **Queued follow-ups.** Add the next prompt while the agent is still running; Pix sends it automatically when the current turn finishes.
|
|
30
|
+
- **Live status panels.** Built-in panels surface todo state, async sub-agent activity, model/context usage, and compression stats above the editor.
|
|
31
|
+
- **Renderer-aware extensions.** Pix extensions can draw rows above/below the input, show stackable toasts, open searchable popup menus, and react through an isolated event bus.
|
|
32
|
+
- **Nicer terminal ergonomics.** Mouse scrolling, PageUp/PageDown scrollback, tab attention, status lines, terminal-output buffering, Nerd Font icons, and fallback icon mode are handled by the Pix renderer.
|
|
33
|
+
|
|
17
34
|
## Requirements
|
|
18
35
|
|
|
19
36
|
- Node.js `>=22.19.0 <25` (`24.16.0` is pinned for development).
|
|
@@ -43,6 +60,12 @@ pix install --check
|
|
|
43
60
|
|
|
44
61
|
`pix install` checks the icon font, `pi` CLI availability, and clipboard helpers. The `pix` launcher also prepends Pix's bundled dependency bin directory to `PATH`, so a package-manager install can use the bundled Pi CLI even when a separate global `pi` command is not present.
|
|
45
62
|
|
|
63
|
+
After the setup check, review the user config files:
|
|
64
|
+
|
|
65
|
+
- `~/.config/pi/pix.jsonc`: choose the voice-input language with `dictation.language` and keep only the `dictation.languages` models you want enabled.
|
|
66
|
+
- `~/.config/pi/pi-tools-suite.jsonc`: enable/configure your LSP servers under `lsp.servers` and adjust pi-tools-suite modules or sub-agent presets if needed.
|
|
67
|
+
- In Pix, run `/opencode-import` to import opencode accounts. For Antigravity OAuth accounts, run `/antigravity-import` or add another account with `/antigravity-add-account`.
|
|
68
|
+
|
|
46
69
|
On startup, Pix ensures the bundled suite is available at:
|
|
47
70
|
|
|
48
71
|
```text
|
|
@@ -153,8 +176,6 @@ Useful environment variables:
|
|
|
153
176
|
- `PIX_DISABLE_TERMINAL_OUTPUT_BUFFER=1` or `PIX_TERMINAL_OUTPUT_BUFFER=0`: disable Pix terminal output region buffering.
|
|
154
177
|
- `PIX_USE_FALLBACK_ICONS=1` or `PIX_ICON_THEME=fallback`: use plain fallback icons when Nerd Font glyphs are unavailable.
|
|
155
178
|
- `PIX_ICON_THEME=nerdFont`: force the Nerd Font icon theme.
|
|
156
|
-
- `PIX_ANTIGRAVITY_GOOGLE_CLIENT_ID` / `ANTIGRAVITY_GOOGLE_CLIENT_ID`: Google OAuth client ID used for Antigravity quota/login integrations.
|
|
157
|
-
- `PIX_ANTIGRAVITY_GOOGLE_CLIENT_SECRET` / `ANTIGRAVITY_GOOGLE_CLIENT_SECRET`: Google OAuth client secret used for Antigravity quota/login integrations.
|
|
158
179
|
|
|
159
180
|
Pix user configuration is read from:
|
|
160
181
|
|
package/dist/app/app.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare class PiUiExtendApp {
|
|
|
31
31
|
private readonly nerdFontController;
|
|
32
32
|
private readonly popupActions;
|
|
33
33
|
private readonly promptEnhancer;
|
|
34
|
+
private readonly autocompleteController;
|
|
34
35
|
private readonly mouseController;
|
|
35
36
|
private readonly popupMenus;
|
|
36
37
|
private readonly voiceController;
|
|
@@ -48,6 +49,7 @@ export declare class PiUiExtendApp {
|
|
|
48
49
|
private get input();
|
|
49
50
|
private set input(value);
|
|
50
51
|
private running;
|
|
52
|
+
private scheduledRenderTimer;
|
|
51
53
|
private todoPanelExpanded;
|
|
52
54
|
private subagentsPanelExpanded;
|
|
53
55
|
private allThinkingExpanded;
|
|
@@ -85,6 +87,7 @@ export declare class PiUiExtendApp {
|
|
|
85
87
|
private setSessionStatus;
|
|
86
88
|
private setSessionActivity;
|
|
87
89
|
private toolDefaultExpanded;
|
|
90
|
+
private toggleSuperCompactTools;
|
|
88
91
|
private stopBlinking;
|
|
89
92
|
private stop;
|
|
90
93
|
private toggleTerminalBellSound;
|
|
@@ -92,6 +95,7 @@ export declare class PiUiExtendApp {
|
|
|
92
95
|
private showToast;
|
|
93
96
|
private clearToastTimers;
|
|
94
97
|
private render;
|
|
98
|
+
private scheduleRender;
|
|
95
99
|
private renderStatusLine;
|
|
96
100
|
private terminalColumns;
|
|
97
101
|
private terminalRows;
|
package/dist/app/app.js
CHANGED
|
@@ -17,6 +17,7 @@ import { NerdFontController } from "./terminal/nerd-font-controller.js";
|
|
|
17
17
|
import { AppPopupActionController } from "./popup/popup-action-controller.js";
|
|
18
18
|
import { AppPopupMenuController } from "./popup/popup-menu-controller.js";
|
|
19
19
|
import { AppPromptEnhancerController } from "./input/prompt-enhancer-controller.js";
|
|
20
|
+
import { AppAutocompleteController } from "./input/autocomplete-controller.js";
|
|
20
21
|
import { AppQueuedMessageController } from "./session/queued-message-controller.js";
|
|
21
22
|
import { AppRequestHistory } from "./session/request-history.js";
|
|
22
23
|
import { AppRenderController } from "./rendering/render-controller.js";
|
|
@@ -46,6 +47,7 @@ import { setAppIconTheme } from "./icons.js";
|
|
|
46
47
|
const TERMINAL_BELL_ATTENTION_EVENT = "pix:terminal-bell:attention";
|
|
47
48
|
const SUBAGENTS_LIVE_STATE_EVENT = "pi-tools-suite:async-subagents:live-state";
|
|
48
49
|
const TODO_STATE_EVENT = "pi-tools-suite:todo:state";
|
|
50
|
+
const COALESCED_RENDER_DELAY_MS = 16;
|
|
49
51
|
export class PiUiExtendApp {
|
|
50
52
|
entries = [];
|
|
51
53
|
options;
|
|
@@ -78,6 +80,7 @@ export class PiUiExtendApp {
|
|
|
78
80
|
nerdFontController;
|
|
79
81
|
popupActions;
|
|
80
82
|
promptEnhancer;
|
|
83
|
+
autocompleteController;
|
|
81
84
|
mouseController;
|
|
82
85
|
popupMenus;
|
|
83
86
|
voiceController;
|
|
@@ -111,6 +114,7 @@ export class PiUiExtendApp {
|
|
|
111
114
|
get input() { return this.inputEditor.text; }
|
|
112
115
|
set input(value) { this.inputEditor.setText(value); }
|
|
113
116
|
running = false;
|
|
117
|
+
scheduledRenderTimer;
|
|
114
118
|
todoPanelExpanded = true;
|
|
115
119
|
subagentsPanelExpanded = true;
|
|
116
120
|
allThinkingExpanded = false;
|
|
@@ -143,6 +147,7 @@ export class PiUiExtendApp {
|
|
|
143
147
|
theme: this.theme,
|
|
144
148
|
blinkController: this.blinkController,
|
|
145
149
|
runtimeSession: () => this.runtime?.session,
|
|
150
|
+
render: () => this.scheduleRender(),
|
|
146
151
|
});
|
|
147
152
|
this.modelUsageController = new AppModelUsageController({
|
|
148
153
|
runtimeSession: () => this.runtime?.session,
|
|
@@ -170,6 +175,8 @@ export class PiUiExtendApp {
|
|
|
170
175
|
syncUserSessionEntryMetadata: () => this.workspaceActions.syncUserSessionEntryMetadata(),
|
|
171
176
|
captureInputState: () => ({ text: this.inputEditor.text, cursor: this.inputEditor.cursor }),
|
|
172
177
|
restoreInputState: (state) => this.restoreTabInputState(state.text, state.cursor),
|
|
178
|
+
captureDeferredUserMessages: () => this.queuedMessages.captureDeferredUserMessages(),
|
|
179
|
+
restoreDeferredUserMessages: (messages) => this.queuedMessages.restoreDeferredUserMessages(messages),
|
|
173
180
|
addEntry: (entry) => this.addEntry(entry),
|
|
174
181
|
showToast: (message, kind) => this.showToast(message, kind),
|
|
175
182
|
render: () => this.render(),
|
|
@@ -191,6 +198,13 @@ export class PiUiExtendApp {
|
|
|
191
198
|
toast: this.toastNotifier,
|
|
192
199
|
render: () => this.render(),
|
|
193
200
|
});
|
|
201
|
+
this.autocompleteController = new AppAutocompleteController({
|
|
202
|
+
runtime: () => this.runtime,
|
|
203
|
+
inputEditor: () => this.inputEditor,
|
|
204
|
+
autocompleteConfig: () => this.pixConfig.autocomplete,
|
|
205
|
+
isRunning: () => this.running,
|
|
206
|
+
render: () => this.render(),
|
|
207
|
+
});
|
|
194
208
|
this.voiceController = new AppVoiceController({
|
|
195
209
|
insertTranscript: (text) => this.insertVoiceTranscript(text),
|
|
196
210
|
setPartialTranscript: (text) => this.setVoicePartialTranscript(text),
|
|
@@ -251,6 +265,7 @@ export class PiUiExtendApp {
|
|
|
251
265
|
terminalBellSoundStatusWidgetEnabled: () => this.terminalBellSoundController.isEnabled(),
|
|
252
266
|
voiceStatusWidgetText: () => this.voiceController.statusWidgetText(),
|
|
253
267
|
voiceStatusWidgetActive: () => this.voiceController.statusWidgetActive(),
|
|
268
|
+
queueableInputActive: () => this.inputEditor.promptText.trimEnd().length > 0 || this.inputEditor.images.length > 0,
|
|
254
269
|
userMessageJumpMenuActive: () => this.popupMenus.directMenu === "user-message-jump",
|
|
255
270
|
allThinkingExpandedActive: () => this.allThinkingExpanded,
|
|
256
271
|
superCompactToolsActive: () => this.superCompactTools,
|
|
@@ -291,12 +306,12 @@ export class PiUiExtendApp {
|
|
|
291
306
|
cwd: this.options.cwd,
|
|
292
307
|
sessionFile: () => this.runtime?.session.sessionFile,
|
|
293
308
|
isRunning: () => this.running,
|
|
294
|
-
render: () => this.
|
|
309
|
+
render: () => this.scheduleRender(),
|
|
295
310
|
});
|
|
296
311
|
this.todoWidgetController = new AppTodoWidgetController({
|
|
297
312
|
sessionFile: () => this.runtime?.session.sessionFile,
|
|
298
313
|
isRunning: () => this.running,
|
|
299
|
-
render: () => this.
|
|
314
|
+
render: () => this.scheduleRender(),
|
|
300
315
|
});
|
|
301
316
|
this.workspaceActions = new AppWorkspaceActionsController({
|
|
302
317
|
entries: this.entries,
|
|
@@ -320,13 +335,11 @@ export class PiUiExtendApp {
|
|
|
320
335
|
conversationViewport: () => this.conversationViewport,
|
|
321
336
|
isRunning: () => this.running,
|
|
322
337
|
render: () => this.render(),
|
|
338
|
+
scheduleRender: () => this.scheduleRender(),
|
|
323
339
|
setStatus: (status) => this.setStatus(status),
|
|
324
340
|
restoreSessionStatus: () => this.restoreSessionStatus(),
|
|
325
341
|
setSessionStatus: (session) => this.setSessionStatus(session),
|
|
326
342
|
setSessionActivity: (activity) => this.setSessionActivity(activity),
|
|
327
|
-
flushDeferredUserMessages: () => {
|
|
328
|
-
void this.queuedMessages.flushDeferredUserMessages();
|
|
329
|
-
},
|
|
330
343
|
updateQueuedMessageStatus: () => this.queuedMessages.updateQueuedMessageStatus(),
|
|
331
344
|
prepareWorkspaceMutation: (toolName, args) => this.workspaceActions.prepareWorkspaceMutation(toolName, args),
|
|
332
345
|
workspaceMutationFromToolExecution: (input) => this.workspaceActions.workspaceMutationFromToolExecution(input),
|
|
@@ -355,6 +368,7 @@ export class PiUiExtendApp {
|
|
|
355
368
|
setInput: (value) => this.inputEditor.setText(value),
|
|
356
369
|
insertInput: (value) => this.inputEditor.insert(value),
|
|
357
370
|
attachImage: (data, mimeType) => this.inputEditor.attachImage(data, mimeType),
|
|
371
|
+
onDeferredUserMessagesChanged: () => this.tabsController.persistActiveDeferredUserMessages(),
|
|
358
372
|
});
|
|
359
373
|
this.editorLayoutRenderer = new EditorLayoutRenderer({
|
|
360
374
|
theme: this.theme,
|
|
@@ -365,6 +379,7 @@ export class PiUiExtendApp {
|
|
|
365
379
|
get subagentsPanelExpanded() { return app.subagentsPanelExpanded; },
|
|
366
380
|
get subagentsWidgetState() { return app.subagentsWidgetController.widgetState; },
|
|
367
381
|
get voicePartialText() { return app.voicePartialText; },
|
|
382
|
+
get autocompleteSuggestion() { return app.autocompleteController.suggestionText(); },
|
|
368
383
|
renderExtensionInputComponent: (width) => this.extensionUiController.renderActiveCustomUi(width),
|
|
369
384
|
extensionInputUsesEditor: () => this.extensionUiController.activeCustomUiUsesEditor(),
|
|
370
385
|
widgetTuiHandle: () => this.extensionUiController.widgetTuiHandle(),
|
|
@@ -401,6 +416,11 @@ export class PiUiExtendApp {
|
|
|
401
416
|
getInput: () => this.input,
|
|
402
417
|
setInput: (value) => this.setInput(value),
|
|
403
418
|
promptEnhancerModelRef: () => this.pixConfig.promptEnhancer.modelRef,
|
|
419
|
+
autocompleteModelRef: () => this.pixConfig.autocomplete.modelRef,
|
|
420
|
+
setAutocompleteModelRef: (modelRef) => {
|
|
421
|
+
this.pixConfig.autocomplete.modelRef = modelRef;
|
|
422
|
+
this.autocompleteController.dispose();
|
|
423
|
+
},
|
|
404
424
|
enhancePrompt: () => this.promptEnhancer.enhancePrompt(),
|
|
405
425
|
isRunning: () => this.running,
|
|
406
426
|
stop: () => this.stop(),
|
|
@@ -414,6 +434,9 @@ export class PiUiExtendApp {
|
|
|
414
434
|
modelRef: (model) => this.menuItems.modelRef(model),
|
|
415
435
|
getFavoriteScopedModels: () => this.menuItems.getFavoriteScopedModels(),
|
|
416
436
|
setSessionStatus: (session) => this.setSessionStatus(session),
|
|
437
|
+
queueUserMessage: (text) => {
|
|
438
|
+
this.queuedMessages.deferUserMessage(this.queuedMessages.createSubmittedUserMessage(text, text, []));
|
|
439
|
+
},
|
|
417
440
|
resetSessionView: () => this.resetSessionView(),
|
|
418
441
|
loadSessionHistory: () => this.loadSessionHistory(),
|
|
419
442
|
afterSessionReplacement: (message) => this.afterSessionReplacement(message),
|
|
@@ -430,6 +453,7 @@ export class PiUiExtendApp {
|
|
|
430
453
|
this.popupMenus.setDirectQuery(query);
|
|
431
454
|
},
|
|
432
455
|
getResumeLoading: () => this.resumeLoading,
|
|
456
|
+
getResumeSessions: () => this.resumeSessions,
|
|
433
457
|
setResumeLoading: (loading) => {
|
|
434
458
|
this.resumeLoading = loading;
|
|
435
459
|
},
|
|
@@ -499,12 +523,20 @@ export class PiUiExtendApp {
|
|
|
499
523
|
showToast: (message, kind, options) => this.showToast(message, kind, options),
|
|
500
524
|
dismissToast: (toastId) => this.toastController.dismissToast(toastId),
|
|
501
525
|
refreshModelUsageStatus: () => this.refreshModelUsageStatusFromClick(),
|
|
526
|
+
queueInputFromStatus: () => {
|
|
527
|
+
void this.inputActions.queueInputFromEditor().catch((error) => {
|
|
528
|
+
this.addEntry({ id: createId("error"), kind: "error", text: `Queue input failed: ${error instanceof Error ? error.message : String(error)}` });
|
|
529
|
+
this.showToast("Queue input failed", "error");
|
|
530
|
+
this.setSessionStatus(this.runtime?.session);
|
|
531
|
+
this.render();
|
|
532
|
+
});
|
|
533
|
+
},
|
|
502
534
|
toggleAllThinkingExpanded: () => {
|
|
503
535
|
this.allThinkingExpanded = !this.allThinkingExpanded;
|
|
504
536
|
this.render();
|
|
505
537
|
},
|
|
506
538
|
toggleSuperCompactTools: () => {
|
|
507
|
-
this.
|
|
539
|
+
this.toggleSuperCompactTools();
|
|
508
540
|
this.render();
|
|
509
541
|
},
|
|
510
542
|
toggleTerminalBellSound: () => this.toggleTerminalBellSound(),
|
|
@@ -543,6 +575,7 @@ export class PiUiExtendApp {
|
|
|
543
575
|
setSessionActivity: (activity) => this.setSessionActivity(activity),
|
|
544
576
|
restoreSessionStatus: () => this.restoreSessionStatus(),
|
|
545
577
|
render: () => this.render(),
|
|
578
|
+
scheduleRender: () => this.scheduleRender(),
|
|
546
579
|
});
|
|
547
580
|
this.inputActions = new AppInputActionController({
|
|
548
581
|
runtime: () => this.runtime,
|
|
@@ -587,6 +620,7 @@ export class PiUiExtendApp {
|
|
|
587
620
|
handleDirectPopupInput: (char) => this.popupMenus.handleDirectPopupInput(char),
|
|
588
621
|
autocompleteModel: () => this.popupMenus.autocompleteModel(),
|
|
589
622
|
autocompleteThinking: () => this.popupMenus.autocompleteThinking(),
|
|
623
|
+
acceptAutocompleteSuggestion: () => this.autocompleteController.acceptSuggestion(),
|
|
590
624
|
autocompleteSlashCommand: () => this.popupMenus.autocompleteSlashCommand(),
|
|
591
625
|
toggleVoiceRecording: () => {
|
|
592
626
|
void this.voiceController.toggleRecording();
|
|
@@ -609,6 +643,7 @@ export class PiUiExtendApp {
|
|
|
609
643
|
stopSubagentsPolling: () => this.subagentsWidgetController.stopPolling(),
|
|
610
644
|
stopModelUsagePolling: () => this.modelUsageController.stopPolling(),
|
|
611
645
|
stopVoiceInput: () => this.voiceController.dispose(),
|
|
646
|
+
stopAutocomplete: () => this.autocompleteController.dispose(),
|
|
612
647
|
stopShellCommand: () => this.shellController.dispose(),
|
|
613
648
|
unsubscribeSession: () => {
|
|
614
649
|
this.sessionLifecycle.unsubscribeSession();
|
|
@@ -660,6 +695,7 @@ export class PiUiExtendApp {
|
|
|
660
695
|
this.mouseController.statusThinkingTarget = undefined;
|
|
661
696
|
this.mouseController.statusContextTarget = undefined;
|
|
662
697
|
this.mouseController.statusModelUsageTarget = undefined;
|
|
698
|
+
this.mouseController.statusDraftQueueTarget = undefined;
|
|
663
699
|
this.mouseController.statusUserJumpTarget = undefined;
|
|
664
700
|
this.mouseController.statusThinkingExpandTarget = undefined;
|
|
665
701
|
this.mouseController.statusCompactToolsTarget = undefined;
|
|
@@ -672,6 +708,7 @@ export class PiUiExtendApp {
|
|
|
672
708
|
},
|
|
673
709
|
scrollReset: () => this.scrollController.reset(),
|
|
674
710
|
loadSessionHistoryEntries: () => this.sessionEvents.loadSessionHistory(),
|
|
711
|
+
loadSessionHistoryEntriesAsync: (options) => this.sessionEvents.loadSessionHistoryAsync(options),
|
|
675
712
|
syncUserSessionEntryMetadata: () => this.workspaceActions.syncUserSessionEntryMetadata(),
|
|
676
713
|
restoreTabsAfterStartup: () => this.tabsController.restoreAfterStartup(),
|
|
677
714
|
render: () => this.render(),
|
|
@@ -735,15 +772,18 @@ export class PiUiExtendApp {
|
|
|
735
772
|
this.popupMenus.resetInputMenuDismissals();
|
|
736
773
|
}
|
|
737
774
|
this.input = value;
|
|
775
|
+
this.autocompleteController.dispose();
|
|
738
776
|
}
|
|
739
777
|
resetInputAfterProgrammaticEdit() {
|
|
740
778
|
this.requestHistory.resetNavigation();
|
|
741
779
|
this.popupMenus.resetInputMenuDismissals();
|
|
780
|
+
this.autocompleteController.dispose();
|
|
742
781
|
}
|
|
743
782
|
restoreTabInputState(text, cursor) {
|
|
744
783
|
this.requestHistory.resetNavigation();
|
|
745
784
|
this.popupMenus.resetInputMenuDismissals();
|
|
746
785
|
this.inputEditor.setText(text, cursor);
|
|
786
|
+
this.autocompleteController.dispose();
|
|
747
787
|
}
|
|
748
788
|
async clearPersistedInputDraft() {
|
|
749
789
|
await this.tabsController.setInputStateForTab(this.tabsController.activeInputTabId(), { text: "", cursor: 0 });
|
|
@@ -768,7 +808,7 @@ export class PiUiExtendApp {
|
|
|
768
808
|
if (this.voicePartialText === text)
|
|
769
809
|
return;
|
|
770
810
|
this.voicePartialText = text;
|
|
771
|
-
this.
|
|
811
|
+
this.scheduleRender();
|
|
772
812
|
}
|
|
773
813
|
addVoiceSystemMessage(message) {
|
|
774
814
|
this.addEntry({ id: createId("system"), kind: "system", text: message });
|
|
@@ -828,8 +868,21 @@ export class PiUiExtendApp {
|
|
|
828
868
|
this.statusController.setSessionActivity(activity);
|
|
829
869
|
}
|
|
830
870
|
toolDefaultExpanded(toolName) {
|
|
871
|
+
if (this.superCompactTools)
|
|
872
|
+
return false;
|
|
831
873
|
return resolveToolRule(toolName, this.pixConfig.toolRenderer).defaultExpanded === true;
|
|
832
874
|
}
|
|
875
|
+
toggleSuperCompactTools() {
|
|
876
|
+
this.superCompactTools = !this.superCompactTools;
|
|
877
|
+
if (!this.superCompactTools)
|
|
878
|
+
return;
|
|
879
|
+
for (const entry of this.entries) {
|
|
880
|
+
if (entry.kind !== "tool" || !entry.expanded)
|
|
881
|
+
continue;
|
|
882
|
+
entry.expanded = false;
|
|
883
|
+
this.touchEntry(entry);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
833
886
|
stopBlinking() {
|
|
834
887
|
this.blinkController.dispose();
|
|
835
888
|
}
|
|
@@ -877,8 +930,22 @@ export class PiUiExtendApp {
|
|
|
877
930
|
this.toastController.clearToastTimers();
|
|
878
931
|
}
|
|
879
932
|
render() {
|
|
933
|
+
if (this.scheduledRenderTimer) {
|
|
934
|
+
clearTimeout(this.scheduledRenderTimer);
|
|
935
|
+
this.scheduledRenderTimer = undefined;
|
|
936
|
+
}
|
|
937
|
+
this.autocompleteController.observeInput();
|
|
880
938
|
this.renderController.render();
|
|
881
939
|
}
|
|
940
|
+
scheduleRender() {
|
|
941
|
+
if (!this.running || this.scheduledRenderTimer)
|
|
942
|
+
return;
|
|
943
|
+
this.scheduledRenderTimer = setTimeout(() => {
|
|
944
|
+
this.scheduledRenderTimer = undefined;
|
|
945
|
+
this.renderController.render();
|
|
946
|
+
}, COALESCED_RENDER_DELAY_MS);
|
|
947
|
+
this.scheduledRenderTimer.unref?.();
|
|
948
|
+
}
|
|
882
949
|
renderStatusLine() {
|
|
883
950
|
this.renderController.renderStatusLine();
|
|
884
951
|
}
|
|
@@ -4,7 +4,9 @@ export type PixInstallCliOptions = {
|
|
|
4
4
|
};
|
|
5
5
|
export type PixInstallCliContext = {
|
|
6
6
|
env?: NodeJS.ProcessEnv;
|
|
7
|
+
homeDir?: string;
|
|
7
8
|
};
|
|
9
|
+
export declare function formatPixInstallNextSteps(homeDir?: string): string;
|
|
8
10
|
export declare function pixInstallUsage(): string;
|
|
9
11
|
export declare function parsePixInstallArgs(argv: readonly string[]): PixInstallCliOptions;
|
|
10
12
|
export declare function runPixInstallCli(argv?: readonly string[], context?: PixInstallCliContext): Promise<number>;
|
package/dist/app/cli/install.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
5
|
import { FONT_FAMILY_NAME, installJetBrainsNerdFont, isJetBrainsNerdFontInstalled, } from "../terminal/nerd-font-controller.js";
|
|
5
6
|
import { clipboardInstallHint, clipboardSupportAvailable } from "../screen/clipboard.js";
|
|
7
|
+
import { getPixConfigPath } from "../../config.js";
|
|
8
|
+
export function formatPixInstallNextSteps(homeDir = homedir()) {
|
|
9
|
+
const pixConfigPath = getPixConfigPath(homeDir);
|
|
10
|
+
const toolsConfigPath = join(homeDir, ".config", "pi", "pi-tools-suite.jsonc");
|
|
11
|
+
return [
|
|
12
|
+
"",
|
|
13
|
+
"Next steps:",
|
|
14
|
+
` 1. Edit ${pixConfigPath} and set dictation.language / dictation.languages for voice input.`,
|
|
15
|
+
` 2. Edit ${toolsConfigPath} and enable the LSP servers you use under lsp.servers.`,
|
|
16
|
+
" 3. Start pix, then run /opencode-import to import opencode accounts.",
|
|
17
|
+
" For Antigravity accounts, run /antigravity-import or /antigravity-add-account.",
|
|
18
|
+
].join("\n");
|
|
19
|
+
}
|
|
6
20
|
export function pixInstallUsage() {
|
|
7
21
|
return `Usage: pix install [--check]
|
|
8
22
|
pix setup [--check]
|
|
@@ -86,7 +100,7 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
86
100
|
failures += 1;
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
|
-
if (clipboardSupportAvailable(env)) {
|
|
103
|
+
if (await clipboardSupportAvailable(env)) {
|
|
90
104
|
console.log("✓ Clipboard support is available");
|
|
91
105
|
}
|
|
92
106
|
else {
|
|
@@ -94,6 +108,7 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
94
108
|
if (process.platform === "linux")
|
|
95
109
|
failures += 1;
|
|
96
110
|
}
|
|
111
|
+
console.log(formatPixInstallNextSteps(context.homeDir));
|
|
97
112
|
return failures === 0 ? 0 : 1;
|
|
98
113
|
}
|
|
99
114
|
async function resolvePiCliStatus(env) {
|
|
@@ -28,13 +28,17 @@ export class AppCommandController {
|
|
|
28
28
|
return {
|
|
29
29
|
runSettingsCommand: () => this.modelActions.runSettingsCommand(),
|
|
30
30
|
runModelSlashCommand: (argumentsText) => this.modelActions.runModelSlashCommand(argumentsText),
|
|
31
|
+
runDefaultModelSlashCommand: (argumentsText) => this.modelActions.runDefaultModelSlashCommand(argumentsText),
|
|
32
|
+
runAutocompleteSlashCommand: (argumentsText) => this.modelActions.runAutocompleteSlashCommand(argumentsText),
|
|
31
33
|
runScopedModelsCommand: (argumentsText) => this.modelActions.runScopedModelsCommand(argumentsText),
|
|
32
34
|
runThinkingSlashCommand: (argumentsText) => this.modelActions.runThinkingSlashCommand(argumentsText),
|
|
35
|
+
runDefaultThinkingSlashCommand: (argumentsText) => this.modelActions.runDefaultThinkingSlashCommand(argumentsText),
|
|
33
36
|
runEnhanceCommand: () => this.host.enhancePrompt(),
|
|
34
37
|
runExportCommand: (argumentsText) => this.sessionActions.runExportCommand(argumentsText),
|
|
35
38
|
runImportCommand: (argumentsText) => this.sessionActions.runImportCommand(argumentsText),
|
|
36
39
|
runShareCommand: () => this.sessionActions.runShareCommand(),
|
|
37
40
|
runCopyCommand: () => this.sessionActions.runCopyCommand(),
|
|
41
|
+
runQueueCommand: (argumentsText) => this.sessionActions.runQueueCommand(argumentsText),
|
|
38
42
|
runNameCommand: (argumentsText) => this.sessionActions.runNameCommand(argumentsText),
|
|
39
43
|
runSessionInfoCommand: () => this.sessionActions.runSessionInfoCommand(),
|
|
40
44
|
runUsageCommand: () => this.sessionActions.runUsageCommand(),
|
|
@@ -9,6 +9,8 @@ export type CommandControllerHost = {
|
|
|
9
9
|
getInput(): string;
|
|
10
10
|
setInput(value: string): void;
|
|
11
11
|
promptEnhancerModelRef(): string;
|
|
12
|
+
autocompleteModelRef(): string;
|
|
13
|
+
setAutocompleteModelRef(modelRef: string): void;
|
|
12
14
|
enhancePrompt(): Promise<void>;
|
|
13
15
|
isRunning(): boolean;
|
|
14
16
|
stop(): void | Promise<void>;
|
|
@@ -22,6 +24,7 @@ export type CommandControllerHost = {
|
|
|
22
24
|
modelRef(model: SessionModel): string;
|
|
23
25
|
getFavoriteScopedModels(): ScopedSessionModel[];
|
|
24
26
|
setSessionStatus(session: AgentSession | undefined): void;
|
|
27
|
+
queueUserMessage(text: string): void;
|
|
25
28
|
resetSessionView(): void;
|
|
26
29
|
loadSessionHistory(): void;
|
|
27
30
|
afterSessionReplacement(message?: string): void;
|
|
@@ -35,6 +38,7 @@ export type CommandControllerHost = {
|
|
|
35
38
|
getDirectPopupMenuQuery(): string;
|
|
36
39
|
setDirectPopupMenuQuery(query: string): void;
|
|
37
40
|
getResumeLoading(): boolean;
|
|
41
|
+
getResumeSessions(): readonly SessionInfo[];
|
|
38
42
|
setResumeLoading(loading: boolean): void;
|
|
39
43
|
setResumeSessions(sessions: SessionInfo[]): void;
|
|
40
44
|
openResumeMenuWithQuery(query: string): void;
|
|
@@ -5,8 +5,13 @@ export declare class ModelCommandActions {
|
|
|
5
5
|
constructor(host: CommandControllerHost);
|
|
6
6
|
runSettingsCommand(): Promise<void>;
|
|
7
7
|
runModelSlashCommand(argumentsText: string): Promise<void>;
|
|
8
|
+
runDefaultModelSlashCommand(argumentsText: string): Promise<void>;
|
|
9
|
+
runAutocompleteSlashCommand(argumentsText: string): Promise<void>;
|
|
8
10
|
runScopedModelsCommand(argumentsText: string): Promise<void>;
|
|
9
11
|
runThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
12
|
+
runDefaultThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
10
13
|
runModelCommand(model: SessionModel): Promise<void>;
|
|
11
14
|
runThinkingCommand(level: ThinkingLevel): Promise<void>;
|
|
15
|
+
private saveDefaultModel;
|
|
16
|
+
private saveDefaultThinking;
|
|
12
17
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getIdleRuntime, getRuntime } from "./command-runtime.js";
|
|
2
|
+
import { savePixAutocompleteModel, savePixDefaultModel, savePixDefaultThinking } from "../../config.js";
|
|
2
3
|
import { createId } from "../id.js";
|
|
3
4
|
import { isThinkingLevel, parseScopedModelRef } from "../model/model-ref.js";
|
|
4
5
|
export class ModelCommandActions {
|
|
@@ -22,6 +23,7 @@ export class ModelCommandActions {
|
|
|
22
23
|
`session: ${runtime.session.sessionFile ?? "in-memory"}`,
|
|
23
24
|
`model: ${currentModel}`,
|
|
24
25
|
`prompt enhancer model: ${this.host.promptEnhancerModelRef()}`,
|
|
26
|
+
`autocomplete model: ${this.host.autocompleteModelRef() || "disabled"}`,
|
|
25
27
|
`thinking: ${runtime.session.thinkingLevel}`,
|
|
26
28
|
`theme: ${settings.getTheme() ?? this.host.options.themeName}`,
|
|
27
29
|
`skill commands: ${settings.getEnableSkillCommands() ? "enabled" : "disabled"}`,
|
|
@@ -70,6 +72,59 @@ export class ModelCommandActions {
|
|
|
70
72
|
this.host.setSessionStatus(runtime.session);
|
|
71
73
|
}
|
|
72
74
|
}
|
|
75
|
+
async runDefaultModelSlashCommand(argumentsText) {
|
|
76
|
+
const modelRef = argumentsText.trim();
|
|
77
|
+
if (!modelRef) {
|
|
78
|
+
const selected = await this.host.showMenu(this.host.getModelMenuItems(""), {
|
|
79
|
+
title: "Select default model",
|
|
80
|
+
placeholder: "Search models",
|
|
81
|
+
emptyText: "No matching models",
|
|
82
|
+
});
|
|
83
|
+
if (!selected) {
|
|
84
|
+
this.host.setSessionStatus(this.host.runtime()?.session);
|
|
85
|
+
this.host.render();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.saveDefaultModel(this.host.modelRef(selected.model));
|
|
89
|
+
this.host.render();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const runtime = getRuntime(this.host, "default-model");
|
|
93
|
+
if (!runtime)
|
|
94
|
+
return;
|
|
95
|
+
const parsed = parseScopedModelRef(modelRef);
|
|
96
|
+
if (!parsed)
|
|
97
|
+
throw new Error("Model must use provider/model[:thinking] format");
|
|
98
|
+
runtime.services.modelRegistry.refresh();
|
|
99
|
+
const model = runtime.services.modelRegistry.find(parsed.provider, parsed.modelId);
|
|
100
|
+
if (!model)
|
|
101
|
+
throw new Error(`Model not found: ${parsed.provider}/${parsed.modelId}`);
|
|
102
|
+
this.saveDefaultModel(modelRef);
|
|
103
|
+
this.host.setSessionStatus(runtime.session);
|
|
104
|
+
}
|
|
105
|
+
async runAutocompleteSlashCommand(argumentsText) {
|
|
106
|
+
const modelRef = argumentsText.trim();
|
|
107
|
+
if (!modelRef) {
|
|
108
|
+
const saved = savePixAutocompleteModel("");
|
|
109
|
+
this.host.setAutocompleteModelRef(saved.modelRef);
|
|
110
|
+
this.host.addEntry({ id: createId("system"), kind: "system", text: saved.modelRef ? `Autocomplete model set to ${saved.modelRef}` : "Inline autocomplete disabled." });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const runtime = getRuntime(this.host, "autocomplete");
|
|
114
|
+
if (!runtime)
|
|
115
|
+
return;
|
|
116
|
+
const parsed = parseScopedModelRef(modelRef);
|
|
117
|
+
if (!parsed)
|
|
118
|
+
throw new Error("Model must use provider/model[:thinking] format, or run /autocomplete with no arguments to disable");
|
|
119
|
+
runtime.services.modelRegistry.refresh();
|
|
120
|
+
const model = runtime.services.modelRegistry.find(parsed.provider, parsed.modelId);
|
|
121
|
+
if (!model)
|
|
122
|
+
throw new Error(`Model not found: ${parsed.provider}/${parsed.modelId}`);
|
|
123
|
+
const saved = savePixAutocompleteModel(modelRef);
|
|
124
|
+
this.host.setAutocompleteModelRef(saved.modelRef);
|
|
125
|
+
this.host.addEntry({ id: createId("system"), kind: "system", text: `Autocomplete model set to ${saved.modelRef}.` });
|
|
126
|
+
this.host.setSessionStatus(runtime.session);
|
|
127
|
+
}
|
|
73
128
|
async runScopedModelsCommand(argumentsText) {
|
|
74
129
|
const runtime = getIdleRuntime(this.host, "scoped-models");
|
|
75
130
|
if (!runtime)
|
|
@@ -152,6 +207,27 @@ export class ModelCommandActions {
|
|
|
152
207
|
throw new Error(`Unknown thinking level: ${level}`);
|
|
153
208
|
await this.runThinkingCommand(level);
|
|
154
209
|
}
|
|
210
|
+
async runDefaultThinkingSlashCommand(argumentsText) {
|
|
211
|
+
const level = argumentsText.trim();
|
|
212
|
+
if (!level) {
|
|
213
|
+
const selected = await this.host.showMenu(this.host.getThinkingMenuItems(""), {
|
|
214
|
+
title: "Select default thinking level",
|
|
215
|
+
placeholder: "Search thinking levels",
|
|
216
|
+
emptyText: "No matching thinking levels",
|
|
217
|
+
});
|
|
218
|
+
if (!selected) {
|
|
219
|
+
this.host.setSessionStatus(this.host.runtime()?.session);
|
|
220
|
+
this.host.render();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.saveDefaultThinking(selected.level);
|
|
224
|
+
this.host.render();
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (!isThinkingLevel(level))
|
|
228
|
+
throw new Error(`Unknown thinking level: ${level}`);
|
|
229
|
+
this.saveDefaultThinking(level);
|
|
230
|
+
}
|
|
155
231
|
async runModelCommand(model) {
|
|
156
232
|
const runtime = getRuntime(this.host, "model");
|
|
157
233
|
if (!runtime)
|
|
@@ -173,4 +249,32 @@ export class ModelCommandActions {
|
|
|
173
249
|
this.host.addEntry({ id: createId("system"), kind: "system", text: `Selected thinking level ${runtime.session.thinkingLevel}` });
|
|
174
250
|
this.host.setSessionStatus(runtime.session);
|
|
175
251
|
}
|
|
252
|
+
saveDefaultModel(modelRef) {
|
|
253
|
+
const saved = savePixDefaultModel(modelRef);
|
|
254
|
+
if (!saved)
|
|
255
|
+
throw new Error("Model must use provider/model[:thinking] format");
|
|
256
|
+
this.host.addEntry({
|
|
257
|
+
id: createId("system"),
|
|
258
|
+
kind: "system",
|
|
259
|
+
text: `Default model set to ${formatDefaultModelRef(saved)}. New sessions will use it unless --model is provided.`,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
saveDefaultThinking(level) {
|
|
263
|
+
const runtime = getRuntime(this.host, "default-thinking");
|
|
264
|
+
if (!runtime)
|
|
265
|
+
return;
|
|
266
|
+
const fallbackModelRef = runtime.session.model ? this.host.modelRef(runtime.session.model) : undefined;
|
|
267
|
+
const saved = savePixDefaultThinking(level, fallbackModelRef);
|
|
268
|
+
if (!saved)
|
|
269
|
+
throw new Error("Set /default-model first or select a session model before setting default thinking");
|
|
270
|
+
this.host.addEntry({
|
|
271
|
+
id: createId("system"),
|
|
272
|
+
kind: "system",
|
|
273
|
+
text: `Default thinking level set to ${saved.thinking ?? level} for ${saved.modelRef}. New sessions will use it unless --model is provided.`,
|
|
274
|
+
});
|
|
275
|
+
this.host.setSessionStatus(runtime.session);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function formatDefaultModelRef(defaultModel) {
|
|
279
|
+
return defaultModel.thinking ? `${defaultModel.modelRef}:${defaultModel.thinking}` : defaultModel.modelRef;
|
|
176
280
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { SessionInfo } from "@earendil-works/pi-coding-agent";
|
|
1
2
|
import type { CommandControllerHost } from "./command-host.js";
|
|
3
|
+
import { type ResumeSessionLoaderOptions } from "../session/resume-session-loader.js";
|
|
2
4
|
import type { PopupMenuPlacement } from "../types.js";
|
|
3
5
|
export declare class NavigationCommandActions {
|
|
4
6
|
private readonly host;
|
|
5
|
-
|
|
7
|
+
private readonly resumeSessionLoader;
|
|
8
|
+
private resumeLoadId;
|
|
9
|
+
constructor(host: CommandControllerHost, resumeSessionLoader?: (options: ResumeSessionLoaderOptions) => Promise<readonly SessionInfo[]>);
|
|
6
10
|
runForkCommand(argumentsText: string): Promise<void>;
|
|
7
11
|
runCloneCommand(): Promise<void>;
|
|
8
12
|
runTreeCommand(argumentsText: string): Promise<void>;
|
|
@@ -14,6 +18,7 @@ export declare class NavigationCommandActions {
|
|
|
14
18
|
preserveStatus?: boolean;
|
|
15
19
|
placement?: PopupMenuPlacement;
|
|
16
20
|
}): Promise<void>;
|
|
21
|
+
private loadResumeSessionsInBackground;
|
|
17
22
|
private formatSessionTree;
|
|
18
23
|
private describeSessionTreeEntry;
|
|
19
24
|
}
|