pi-ui-extend 0.1.13 → 0.1.15
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 +1 -1
- package/dist/app/app.d.ts +5 -0
- package/dist/app/app.js +82 -12
- package/dist/app/commands/command-controller.js +1 -0
- package/dist/app/commands/command-host.d.ts +3 -0
- package/dist/app/commands/command-model-actions.d.ts +2 -0
- package/dist/app/commands/command-model-actions.js +40 -4
- package/dist/app/commands/command-navigation-actions.js +3 -0
- package/dist/app/commands/command-registry.d.ts +1 -0
- package/dist/app/commands/command-registry.js +8 -0
- package/dist/app/extensions/extension-ui-controller.d.ts +16 -5
- package/dist/app/extensions/extension-ui-controller.js +99 -61
- package/dist/app/input/input-action-controller.d.ts +1 -0
- package/dist/app/input/input-action-controller.js +8 -2
- package/dist/app/logger.d.ts +25 -0
- package/dist/app/logger.js +90 -0
- package/dist/app/model/model-usage-status.js +30 -15
- package/dist/app/popup/menu-items-controller.d.ts +2 -0
- package/dist/app/popup/menu-items-controller.js +45 -6
- package/dist/app/popup/popup-action-controller.d.ts +2 -1
- package/dist/app/popup/popup-action-controller.js +7 -4
- package/dist/app/popup/popup-menu-controller.d.ts +36 -23
- package/dist/app/popup/popup-menu-controller.js +68 -322
- package/dist/app/rendering/conversation-entry-renderer.js +3 -3
- package/dist/app/rendering/conversation-viewport.d.ts +10 -2
- package/dist/app/rendering/conversation-viewport.js +157 -16
- package/dist/app/rendering/editor-panels.js +4 -2
- package/dist/app/rendering/popup-menu-renderer.d.ts +50 -0
- package/dist/app/rendering/popup-menu-renderer.js +307 -0
- package/dist/app/rendering/render-controller.js +5 -13
- package/dist/app/rendering/status-line-renderer.d.ts +1 -1
- package/dist/app/rendering/status-line-renderer.js +27 -24
- package/dist/app/rendering/toast-controller.d.ts +11 -3
- package/dist/app/rendering/toast-controller.js +53 -12
- package/dist/app/runtime.d.ts +2 -1
- package/dist/app/runtime.js +20 -10
- package/dist/app/screen/mouse-controller.d.ts +2 -2
- package/dist/app/screen/mouse-controller.js +27 -48
- package/dist/app/screen/screen-styler.d.ts +1 -1
- package/dist/app/screen/screen-styler.js +9 -7
- package/dist/app/screen/scroll-controller.d.ts +11 -9
- package/dist/app/screen/scroll-controller.js +50 -45
- package/dist/app/session/lazy-session-manager.d.ts +11 -0
- package/dist/app/session/lazy-session-manager.js +539 -0
- package/dist/app/session/pix-system-message.d.ts +16 -0
- package/dist/app/session/pix-system-message.js +64 -0
- package/dist/app/session/session-event-controller.d.ts +11 -0
- package/dist/app/session/session-event-controller.js +58 -2
- package/dist/app/session/session-history.d.ts +18 -0
- package/dist/app/session/session-history.js +72 -3
- package/dist/app/session/session-lifecycle-controller.d.ts +6 -2
- package/dist/app/session/session-lifecycle-controller.js +7 -2
- package/dist/app/session/tabs-controller.d.ts +13 -1
- package/dist/app/session/tabs-controller.js +248 -27
- package/dist/app/todo/todo-model.d.ts +3 -1
- package/dist/app/todo/todo-model.js +14 -2
- package/dist/app/types.d.ts +5 -2
- package/dist/app/workspace/workspace-actions-controller.d.ts +2 -0
- package/dist/app/workspace/workspace-actions-controller.js +12 -0
- package/dist/config.d.ts +5 -1
- package/dist/config.js +73 -25
- package/dist/default-pix-config.js +2 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +1 -0
- package/dist/schemas/pi-tools-suite-schema.js +1 -0
- package/dist/schemas/pix-schema.d.ts +2 -1
- package/dist/schemas/pix-schema.js +5 -4
- package/dist/terminal-width.d.ts +2 -0
- package/dist/terminal-width.js +64 -3
- package/external/pi-tools-suite/README.md +1 -0
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +12 -3
- package/external/pi-tools-suite/src/antigravity-auth/commands.ts +2 -4
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +2 -2
- package/external/pi-tools-suite/src/antigravity-auth/index.ts +8 -2
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +102 -50
- package/external/pi-tools-suite/src/antigravity-auth/status.ts +81 -2
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +29 -8
- package/external/pi-tools-suite/src/config.ts +8 -0
- package/external/pi-tools-suite/src/dcp/index.ts +16 -1
- package/external/pi-tools-suite/src/dcp/state.ts +35 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +3 -0
- package/external/pi-tools-suite/src/todo/index.ts +181 -11
- package/external/pi-tools-suite/src/todo/state/state-reducer.ts +23 -10
- package/external/pi-tools-suite/src/todo/todo.ts +10 -5
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +33 -6
- package/external/pi-tools-suite/src/todo/tool/types.ts +9 -1
- package/external/pi-tools-suite/src/todo/view/format.ts +2 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +2 -1
- package/external/pi-tools-suite/src/usage/index.ts +5 -2
- package/external/pi-tools-suite/src/usage/lib/google.ts +6 -13
- package/package.json +1 -1
- package/schemas/pi-tools-suite.json +4 -0
- package/schemas/pix.json +6 -2
package/README.md
CHANGED
|
@@ -215,7 +215,7 @@ Type `/` in the prompt to open the command picker. Commands that accept argument
|
|
|
215
215
|
| `/settings` | — | Show current session, model, theme, and key settings. |
|
|
216
216
|
| `/model` | `[provider/model[:thinking]]` | Select the active model. Without arguments, opens the model picker. With a reference like `anthropic/claude-sonnet-4-20250514:medium`, sets the model and optional thinking level directly. |
|
|
217
217
|
| `/scoped-models` | `[refs…\|reset]` | Show or set the models used by the model selector and cycling. Pass one or more `provider/model[:thinking]` references separated by spaces or commas. Use `reset` to restore the default favorites. |
|
|
218
|
-
| `/thinking` | `[level]` | Select the thinking level. Without arguments, opens the thinking picker. Accepts an explicit level (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`). |
|
|
218
|
+
| `/thinking` | `[level\|auto]` | Select the thinking level. Without arguments, opens the thinking picker. Accepts an explicit level (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`) or `auto`, which chooses a supported level per prompt. |
|
|
219
219
|
| `/enhance` | — | Improve the current prompt draft using the prompt enhancer model. |
|
|
220
220
|
| `/export` | `[path]` | Export the session. Defaults to HTML. Pass a `.jsonl` path to export as JSONL. |
|
|
221
221
|
| `/import` | `<path.jsonl>` | Import and resume a session from a JSONL file. |
|
package/dist/app/app.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export declare class PiUiExtendApp {
|
|
|
58
58
|
private resumeSessions;
|
|
59
59
|
private resumeLoading;
|
|
60
60
|
constructor(options: AppOptions);
|
|
61
|
+
private createRuntime;
|
|
61
62
|
start(): Promise<void>;
|
|
62
63
|
private checkPixUpdateOnStartup;
|
|
63
64
|
private bindCurrentSession;
|
|
@@ -67,6 +68,7 @@ export declare class PiUiExtendApp {
|
|
|
67
68
|
private afterSessionReplacement;
|
|
68
69
|
private requireRuntime;
|
|
69
70
|
private restoreSessionStatus;
|
|
71
|
+
private activeExtensionUiScope;
|
|
70
72
|
private setInput;
|
|
71
73
|
private resetInputAfterProgrammaticEdit;
|
|
72
74
|
private restoreTabInputState;
|
|
@@ -77,6 +79,8 @@ export declare class PiUiExtendApp {
|
|
|
77
79
|
private resetSessionView;
|
|
78
80
|
private loadSessionHistory;
|
|
79
81
|
private openSearchResultInNewTab;
|
|
82
|
+
private scrollToUserMessageJumpTarget;
|
|
83
|
+
private findUserEntryBySessionEntryId;
|
|
80
84
|
private loadSessionHistoryAsync;
|
|
81
85
|
private handleSessionEvent;
|
|
82
86
|
private findEntry;
|
|
@@ -93,6 +97,7 @@ export declare class PiUiExtendApp {
|
|
|
93
97
|
private toggleTerminalBellSound;
|
|
94
98
|
private refreshModelUsageStatusFromClick;
|
|
95
99
|
private showToast;
|
|
100
|
+
private toastNotifierForScope;
|
|
96
101
|
private clearToastTimers;
|
|
97
102
|
private render;
|
|
98
103
|
private scheduleRender;
|
package/dist/app/app.js
CHANGED
|
@@ -16,6 +16,7 @@ import { createId } from "./id.js";
|
|
|
16
16
|
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
|
+
import { PopupMenuRenderer } from "./rendering/popup-menu-renderer.js";
|
|
19
20
|
import { AppPromptEnhancerController } from "./input/prompt-enhancer-controller.js";
|
|
20
21
|
import { AppAutocompleteController } from "./input/autocomplete-controller.js";
|
|
21
22
|
import { AppQueuedMessageController } from "./session/queued-message-controller.js";
|
|
@@ -136,6 +137,7 @@ export class PiUiExtendApp {
|
|
|
136
137
|
get mouseSelection() { return app.mouseController.mouseSelection; },
|
|
137
138
|
});
|
|
138
139
|
this.toastController = new AppToastController({
|
|
140
|
+
activeScope: () => this.activeExtensionUiScope(),
|
|
139
141
|
render: () => this.render(),
|
|
140
142
|
});
|
|
141
143
|
this.nerdFontController = new NerdFontController({
|
|
@@ -157,12 +159,12 @@ export class PiUiExtendApp {
|
|
|
157
159
|
options: this.options,
|
|
158
160
|
blinkController: this.blinkController,
|
|
159
161
|
runtime: () => this.runtime,
|
|
160
|
-
createRuntimeForNewSession: () =>
|
|
161
|
-
createRuntimeForSession: (sessionPath) =>
|
|
162
|
+
createRuntimeForNewSession: () => this.createRuntime(newTabRuntimeOptions(this.options)),
|
|
163
|
+
createRuntimeForSession: (sessionPath) => this.createRuntime({
|
|
162
164
|
...this.options,
|
|
163
165
|
noSession: false,
|
|
164
166
|
sessionPath,
|
|
165
|
-
}
|
|
167
|
+
}),
|
|
166
168
|
activateRuntime: (runtime) => this.activateRuntime(runtime),
|
|
167
169
|
disposeRuntime: (runtime) => this.terminalController.disposeRuntime(runtime),
|
|
168
170
|
isRunning: () => this.running,
|
|
@@ -175,13 +177,14 @@ export class PiUiExtendApp {
|
|
|
175
177
|
syncUserSessionEntryMetadata: () => this.workspaceActions.syncUserSessionEntryMetadata(),
|
|
176
178
|
captureInputState: () => ({ text: this.inputEditor.text, cursor: this.inputEditor.cursor }),
|
|
177
179
|
restoreInputState: (state) => this.restoreTabInputState(state.text, state.cursor),
|
|
180
|
+
closeMenusForTabSwitch: () => this.popupMenus.closeMenusForTabSwitch(),
|
|
178
181
|
captureDeferredUserMessages: () => this.queuedMessages.captureDeferredUserMessages(),
|
|
179
182
|
restoreDeferredUserMessages: (messages) => this.queuedMessages.restoreDeferredUserMessages(messages),
|
|
180
183
|
addEntry: (entry) => this.addEntry(entry),
|
|
181
184
|
showToast: (message, kind) => this.showToast(message, kind),
|
|
182
185
|
render: () => this.render(),
|
|
183
186
|
});
|
|
184
|
-
this.pixConfig = loadPixConfig();
|
|
187
|
+
this.pixConfig = loadPixConfig(this.options.cwd);
|
|
185
188
|
setAppIconTheme(this.pixConfig.iconTheme.name);
|
|
186
189
|
this.terminalBellSoundController = new TerminalBellSoundController();
|
|
187
190
|
this.promptEnhancer = new AppPromptEnhancerController({
|
|
@@ -218,13 +221,19 @@ export class PiUiExtendApp {
|
|
|
218
221
|
getEntries: () => this.entries,
|
|
219
222
|
getResumeSessions: () => this.resumeSessions,
|
|
220
223
|
});
|
|
221
|
-
|
|
224
|
+
const popupMenuRenderer = new PopupMenuRenderer({
|
|
222
225
|
theme: this.theme,
|
|
223
226
|
screenStyler: this.screenStyler,
|
|
224
227
|
get entries() { return app.entries; },
|
|
225
228
|
get session() { return app.runtime?.session; },
|
|
226
229
|
get resumeLoading() { return app.resumeLoading; },
|
|
227
230
|
get resumeSessionCount() { return app.resumeSessions.length; },
|
|
231
|
+
});
|
|
232
|
+
this.popupMenus = new AppPopupMenuController({
|
|
233
|
+
get entries() { return app.entries; },
|
|
234
|
+
get session() { return app.runtime?.session; },
|
|
235
|
+
get resumeLoading() { return app.resumeLoading; },
|
|
236
|
+
get resumeSessionCount() { return app.resumeSessions.length; },
|
|
228
237
|
isRunning: () => this.running,
|
|
229
238
|
getInput: () => this.input,
|
|
230
239
|
setInput: (value) => this.setInput(value),
|
|
@@ -241,7 +250,7 @@ export class PiUiExtendApp {
|
|
|
241
250
|
setStatus: (status) => this.setStatus(status),
|
|
242
251
|
restoreSessionStatus: () => this.restoreSessionStatus(),
|
|
243
252
|
render: () => this.render(),
|
|
244
|
-
});
|
|
253
|
+
}, popupMenuRenderer);
|
|
245
254
|
this.statusLineRenderer = new StatusLineRenderer({
|
|
246
255
|
theme: this.theme,
|
|
247
256
|
screenStyler: this.screenStyler,
|
|
@@ -277,10 +286,12 @@ export class PiUiExtendApp {
|
|
|
277
286
|
});
|
|
278
287
|
this.extensionUiController = new ExtensionUiController({
|
|
279
288
|
theme: this.theme,
|
|
289
|
+
activeExtensionUiScope: () => this.activeExtensionUiScope(),
|
|
280
290
|
isRunning: () => this.running,
|
|
281
291
|
render: () => this.render(),
|
|
282
|
-
showToast: (message, kind) => this.showToast(message, kind),
|
|
292
|
+
showToast: (message, kind, options) => this.showToast(message, kind, options),
|
|
283
293
|
toastNotifier: this.toastNotifier,
|
|
294
|
+
toastNotifierForScope: (scopeKey) => this.toastNotifierForScope(scopeKey),
|
|
284
295
|
menuController: this.popupMenus.menuController,
|
|
285
296
|
setStatus: (status) => this.setStatus(status),
|
|
286
297
|
restoreSessionStatus: () => this.restoreSessionStatus(),
|
|
@@ -328,11 +339,14 @@ export class PiUiExtendApp {
|
|
|
328
339
|
showToast: (message, kind) => this.showToast(message, kind),
|
|
329
340
|
render: () => this.render(),
|
|
330
341
|
isRunning: () => this.running,
|
|
342
|
+
forkSessionEntryInNewTab: (sessionEntryId) => this.tabsController.forkSessionEntryInNewTab(sessionEntryId),
|
|
331
343
|
});
|
|
332
344
|
this.sessionEvents = new AppSessionEventController({
|
|
333
345
|
entries: this.entries,
|
|
334
346
|
runtime: () => this.runtime,
|
|
335
347
|
conversationViewport: () => this.conversationViewport,
|
|
348
|
+
conversationViewportColumns: () => this.terminalColumns(),
|
|
349
|
+
onHistoryWindowPruned: (edge, lineCount) => this.scrollController.adjustForHistoryWindowPrune(edge, lineCount),
|
|
336
350
|
isRunning: () => this.running,
|
|
337
351
|
render: () => this.render(),
|
|
338
352
|
scheduleRender: () => this.scheduleRender(),
|
|
@@ -408,6 +422,9 @@ export class PiUiExtendApp {
|
|
|
408
422
|
terminalColumns: () => this.terminalColumns(),
|
|
409
423
|
terminalRows: () => this.terminalRows(),
|
|
410
424
|
tabPanelRows: (terminalRows) => this.tabsController.tabPanelRows(terminalRows),
|
|
425
|
+
hasOlderSessionHistory: () => this.sessionEvents.hasOlderSessionHistory(),
|
|
426
|
+
isLoadingOlderSessionHistory: () => this.sessionEvents.isLoadingOlderSessionHistory(),
|
|
427
|
+
loadOlderSessionHistory: (options) => this.sessionEvents.loadOlderSessionHistory(options),
|
|
411
428
|
render: () => this.render(),
|
|
412
429
|
});
|
|
413
430
|
this.commandController = new AppCommandController({
|
|
@@ -421,6 +438,10 @@ export class PiUiExtendApp {
|
|
|
421
438
|
this.pixConfig.autocomplete.modelRef = modelRef;
|
|
422
439
|
this.autocompleteController.dispose();
|
|
423
440
|
},
|
|
441
|
+
ignoreContextFiles: () => this.pixConfig.ignoreContextFiles,
|
|
442
|
+
setIgnoreContextFiles: (ignoreContextFiles) => {
|
|
443
|
+
this.pixConfig.ignoreContextFiles = ignoreContextFiles;
|
|
444
|
+
},
|
|
424
445
|
enhancePrompt: () => this.promptEnhancer.enhancePrompt(),
|
|
425
446
|
isRunning: () => this.running,
|
|
426
447
|
stop: () => this.stop(),
|
|
@@ -452,6 +473,7 @@ export class PiUiExtendApp {
|
|
|
452
473
|
setDirectPopupMenuQuery: (query) => {
|
|
453
474
|
this.popupMenus.setDirectQuery(query);
|
|
454
475
|
},
|
|
476
|
+
refreshUserMessageJumpMenuItems: () => this.menuItems.refreshUserMessageJumpMenuItems(),
|
|
455
477
|
getResumeLoading: () => this.resumeLoading,
|
|
456
478
|
getResumeSessions: () => this.resumeSessions,
|
|
457
479
|
setResumeLoading: (loading) => {
|
|
@@ -481,6 +503,7 @@ export class PiUiExtendApp {
|
|
|
481
503
|
bindCurrentSession: () => this.bindCurrentSession(),
|
|
482
504
|
loadSessionHistory: () => this.loadSessionHistory(),
|
|
483
505
|
scrollToConversationEntry: (entryId) => this.scrollController.scrollToConversationEntry(entryId),
|
|
506
|
+
scrollToUserMessageJumpTarget: (target) => this.scrollToUserMessageJumpTarget(target),
|
|
484
507
|
}, this.popupMenus, this.commandController, this.menuItems, this.queuedMessages, this.workspaceActions);
|
|
485
508
|
this.mouseController = new AppMouseController({
|
|
486
509
|
terminalColumns: () => this.terminalColumns(),
|
|
@@ -519,10 +542,11 @@ export class PiUiExtendApp {
|
|
|
519
542
|
closeTab: (tabId) => {
|
|
520
543
|
void this.tabsController.closeTab(tabId);
|
|
521
544
|
},
|
|
522
|
-
toastEntry: (toastId) => this.toastController.
|
|
545
|
+
toastEntry: (toastId) => this.toastController.entry(toastId),
|
|
523
546
|
showToast: (message, kind, options) => this.showToast(message, kind, options),
|
|
524
547
|
dismissToast: (toastId) => this.toastController.dismissToast(toastId),
|
|
525
548
|
refreshModelUsageStatus: () => this.refreshModelUsageStatusFromClick(),
|
|
549
|
+
refreshUserMessageJumpMenuItems: () => this.menuItems.refreshUserMessageJumpMenuItems(),
|
|
526
550
|
queueInputFromStatus: () => {
|
|
527
551
|
void this.inputActions.queueInputFromEditor().catch((error) => {
|
|
528
552
|
this.addEntry({ id: createId("error"), kind: "error", text: `Queue input failed: ${error instanceof Error ? error.message : String(error)}` });
|
|
@@ -653,7 +677,7 @@ export class PiUiExtendApp {
|
|
|
653
677
|
});
|
|
654
678
|
this.sessionLifecycle = new AppSessionLifecycleController({
|
|
655
679
|
options: this.options,
|
|
656
|
-
createRuntime: () =>
|
|
680
|
+
createRuntime: () => this.createRuntime(this.options),
|
|
657
681
|
entries: this.entries,
|
|
658
682
|
runtime: () => this.runtime,
|
|
659
683
|
setRuntime: (runtime) => {
|
|
@@ -671,8 +695,8 @@ export class PiUiExtendApp {
|
|
|
671
695
|
loadRequestHistory: () => this.requestHistory.load(),
|
|
672
696
|
startSubagentsPolling: () => this.subagentsWidgetController.startPolling(),
|
|
673
697
|
closeSdkMenuForBind: () => this.popupMenus.closeSdkMenu(undefined, { render: false, restoreStatus: false }),
|
|
674
|
-
clearExtensionWidgets: () => this.extensionUiController.clearWidgets(),
|
|
675
|
-
createExtensionUIContext: () => this.extensionUiController.createExtensionUIContext(),
|
|
698
|
+
clearExtensionWidgets: (scopeKey, options) => this.extensionUiController.clearWidgets(scopeKey, options),
|
|
699
|
+
createExtensionUIContext: (scopeKey) => this.extensionUiController.createExtensionUIContext(scopeKey),
|
|
676
700
|
extensionShutdownHandler: () => this.extensionShutdownHandler,
|
|
677
701
|
createExtensionCommandContextActions: (runtime) => this.extensionActions.createCommandContextActions(runtime),
|
|
678
702
|
handleExtensionError: (error) => this.extensionActions.handleExtensionError(error),
|
|
@@ -715,6 +739,11 @@ export class PiUiExtendApp {
|
|
|
715
739
|
});
|
|
716
740
|
this.slashCommands = this.commandController.slashCommands;
|
|
717
741
|
}
|
|
742
|
+
createRuntime(options) {
|
|
743
|
+
return createPixRuntime(options, {
|
|
744
|
+
eventBus: this.createExtensionEventBus(),
|
|
745
|
+
});
|
|
746
|
+
}
|
|
718
747
|
async start() {
|
|
719
748
|
await this.sessionLifecycle.start();
|
|
720
749
|
this.modelUsageController.startPolling();
|
|
@@ -766,6 +795,12 @@ export class PiUiExtendApp {
|
|
|
766
795
|
if (this.runtime)
|
|
767
796
|
this.setSessionStatus(this.runtime.session);
|
|
768
797
|
}
|
|
798
|
+
activeExtensionUiScope() {
|
|
799
|
+
const session = this.runtime?.session;
|
|
800
|
+
if (!session)
|
|
801
|
+
return undefined;
|
|
802
|
+
return session.sessionFile ?? session.sessionId;
|
|
803
|
+
}
|
|
769
804
|
setInput(value) {
|
|
770
805
|
if (value !== this.input) {
|
|
771
806
|
this.requestHistory.resetNavigation();
|
|
@@ -818,7 +853,11 @@ export class PiUiExtendApp {
|
|
|
818
853
|
this.sessionLifecycle.resetSessionView();
|
|
819
854
|
}
|
|
820
855
|
loadSessionHistory() {
|
|
821
|
-
this.
|
|
856
|
+
void this.sessionEvents.loadSessionHistoryAsync({
|
|
857
|
+
isCancelled: () => !this.running,
|
|
858
|
+
render: () => this.render(),
|
|
859
|
+
lazyOlderHistory: true,
|
|
860
|
+
});
|
|
822
861
|
}
|
|
823
862
|
async openSearchResultInNewTab(result) {
|
|
824
863
|
const opened = await this.tabsController.openSessionInNewTab(result.session.path);
|
|
@@ -838,6 +877,23 @@ export class PiUiExtendApp {
|
|
|
838
877
|
this.showToast("Opened search result", "success");
|
|
839
878
|
this.setSessionStatus(this.runtime?.session);
|
|
840
879
|
}
|
|
880
|
+
async scrollToUserMessageJumpTarget(target) {
|
|
881
|
+
if (target.entryId && this.scrollController.scrollToConversationEntry(target.entryId))
|
|
882
|
+
return true;
|
|
883
|
+
if (!target.sessionEntryId)
|
|
884
|
+
return false;
|
|
885
|
+
let entry = this.findUserEntryBySessionEntryId(target.sessionEntryId);
|
|
886
|
+
while (!entry && this.sessionEvents.hasOlderSessionHistory() && !this.sessionEvents.isLoadingOlderSessionHistory()) {
|
|
887
|
+
const loaded = await this.sessionEvents.loadOlderSessionHistory({ render: false });
|
|
888
|
+
if (!loaded)
|
|
889
|
+
break;
|
|
890
|
+
entry = this.findUserEntryBySessionEntryId(target.sessionEntryId);
|
|
891
|
+
}
|
|
892
|
+
return entry ? this.scrollController.scrollToConversationEntry(entry.id) : false;
|
|
893
|
+
}
|
|
894
|
+
findUserEntryBySessionEntryId(sessionEntryId) {
|
|
895
|
+
return this.entries.find((entry) => entry.kind === "user" && entry.sessionEntryId === sessionEntryId);
|
|
896
|
+
}
|
|
841
897
|
async loadSessionHistoryAsync(options) {
|
|
842
898
|
return this.sessionEvents.loadSessionHistoryAsync(options);
|
|
843
899
|
}
|
|
@@ -928,6 +984,20 @@ export class PiUiExtendApp {
|
|
|
928
984
|
showToast(message, kind = "info", options) {
|
|
929
985
|
this.toastController.showToast(message, kind, options);
|
|
930
986
|
}
|
|
987
|
+
toastNotifierForScope(scopeKey) {
|
|
988
|
+
const options = () => {
|
|
989
|
+
if (scopeKey === undefined)
|
|
990
|
+
return {};
|
|
991
|
+
return { scopeKey };
|
|
992
|
+
};
|
|
993
|
+
return {
|
|
994
|
+
show: (message, kind = "info") => this.showToast(message, kind, options()),
|
|
995
|
+
success: (message) => this.showToast(message, "success", options()),
|
|
996
|
+
error: (message) => this.showToast(message, "error", options()),
|
|
997
|
+
warning: (message) => this.showToast(message, "warning", options()),
|
|
998
|
+
info: (message) => this.showToast(message, "info", options()),
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
931
1001
|
clearToastTimers() {
|
|
932
1002
|
this.toastController.clearToastTimers();
|
|
933
1003
|
}
|
|
@@ -30,6 +30,7 @@ export class AppCommandController {
|
|
|
30
30
|
runModelSlashCommand: (argumentsText) => this.modelActions.runModelSlashCommand(argumentsText),
|
|
31
31
|
runDefaultModelSlashCommand: (argumentsText) => this.modelActions.runDefaultModelSlashCommand(argumentsText),
|
|
32
32
|
runAutocompleteSlashCommand: (argumentsText) => this.modelActions.runAutocompleteSlashCommand(argumentsText),
|
|
33
|
+
runNoContextFilesSlashCommand: (argumentsText) => this.modelActions.runNoContextFilesSlashCommand(argumentsText),
|
|
33
34
|
runScopedModelsCommand: (argumentsText) => this.modelActions.runScopedModelsCommand(argumentsText),
|
|
34
35
|
runThinkingSlashCommand: (argumentsText) => this.modelActions.runThinkingSlashCommand(argumentsText),
|
|
35
36
|
runDefaultThinkingSlashCommand: (argumentsText) => this.modelActions.runDefaultThinkingSlashCommand(argumentsText),
|
|
@@ -11,6 +11,8 @@ export type CommandControllerHost = {
|
|
|
11
11
|
promptEnhancerModelRef(): string;
|
|
12
12
|
autocompleteModelRef(): string;
|
|
13
13
|
setAutocompleteModelRef(modelRef: string): void;
|
|
14
|
+
ignoreContextFiles(): boolean;
|
|
15
|
+
setIgnoreContextFiles(ignoreContextFiles: boolean): void;
|
|
14
16
|
enhancePrompt(): Promise<void>;
|
|
15
17
|
isRunning(): boolean;
|
|
16
18
|
stop(): void | Promise<void>;
|
|
@@ -37,6 +39,7 @@ export type CommandControllerHost = {
|
|
|
37
39
|
setDirectPopupMenuPreserveStatus(preserveStatus: boolean): void;
|
|
38
40
|
getDirectPopupMenuQuery(): string;
|
|
39
41
|
setDirectPopupMenuQuery(query: string): void;
|
|
42
|
+
refreshUserMessageJumpMenuItems(): Promise<void>;
|
|
40
43
|
getResumeLoading(): boolean;
|
|
41
44
|
getResumeSessions(): readonly SessionInfo[];
|
|
42
45
|
setResumeLoading(loading: boolean): void;
|
|
@@ -7,11 +7,13 @@ export declare class ModelCommandActions {
|
|
|
7
7
|
runModelSlashCommand(argumentsText: string): Promise<void>;
|
|
8
8
|
runDefaultModelSlashCommand(argumentsText: string): Promise<void>;
|
|
9
9
|
runAutocompleteSlashCommand(argumentsText: string): Promise<void>;
|
|
10
|
+
runNoContextFilesSlashCommand(argumentsText: string): Promise<void>;
|
|
10
11
|
runScopedModelsCommand(argumentsText: string): Promise<void>;
|
|
11
12
|
runThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
12
13
|
runDefaultThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
13
14
|
runModelCommand(model: SessionModel): Promise<void>;
|
|
14
15
|
runThinkingCommand(level: ThinkingLevel): Promise<void>;
|
|
16
|
+
private addPersistentSystemEntry;
|
|
15
17
|
private saveDefaultModel;
|
|
16
18
|
private saveDefaultThinking;
|
|
17
19
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getIdleRuntime, getRuntime } from "./command-runtime.js";
|
|
2
|
-
import { savePixAutocompleteModel, savePixDefaultModel, savePixDefaultThinking } from "../../config.js";
|
|
2
|
+
import { getProjectPixConfigPath, savePixAutocompleteModel, savePixDefaultModel, savePixDefaultThinking, saveProjectPixIgnoreContextFiles } from "../../config.js";
|
|
3
3
|
import { createId } from "../id.js";
|
|
4
4
|
import { isThinkingLevel, parseScopedModelRef } from "../model/model-ref.js";
|
|
5
|
+
import { appendPixSystemDisplayEntry } from "../session/pix-system-message.js";
|
|
5
6
|
export class ModelCommandActions {
|
|
6
7
|
host;
|
|
7
8
|
constructor(host) {
|
|
@@ -24,6 +25,7 @@ export class ModelCommandActions {
|
|
|
24
25
|
`model: ${currentModel}`,
|
|
25
26
|
`prompt enhancer model: ${this.host.promptEnhancerModelRef()}`,
|
|
26
27
|
`autocomplete model: ${this.host.autocompleteModelRef() || "disabled"}`,
|
|
28
|
+
`context files: ${this.host.ignoreContextFiles() ? "disabled" : "enabled"}`,
|
|
27
29
|
`thinking: ${runtime.session.thinkingLevel}`,
|
|
28
30
|
`theme: ${settings.getTheme() ?? this.host.options.themeName}`,
|
|
29
31
|
`skill commands: ${settings.getEnableSkillCommands() ? "enabled" : "disabled"}`,
|
|
@@ -33,7 +35,7 @@ export class ModelCommandActions {
|
|
|
33
35
|
"scoped models:",
|
|
34
36
|
scopedModelText,
|
|
35
37
|
"",
|
|
36
|
-
"Use /model, /thinking, /scoped-models, /export, /import, /reload for editable settings in pix.",
|
|
38
|
+
"Use /model, /thinking, /no-context-files, /scoped-models, /export, /import, /reload for editable settings in pix.",
|
|
37
39
|
].join("\n");
|
|
38
40
|
this.host.addEntry({ id: createId("system"), kind: "system", text });
|
|
39
41
|
this.host.setSessionStatus(runtime.session);
|
|
@@ -68,7 +70,7 @@ export class ModelCommandActions {
|
|
|
68
70
|
await this.runModelCommand(model);
|
|
69
71
|
if (parsed.thinkingLevel !== undefined) {
|
|
70
72
|
runtime.session.setThinkingLevel(parsed.thinkingLevel);
|
|
71
|
-
this.
|
|
73
|
+
this.addPersistentSystemEntry(runtime.session, `Selected thinking level ${runtime.session.thinkingLevel}`);
|
|
72
74
|
this.host.setSessionStatus(runtime.session);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
@@ -125,6 +127,36 @@ export class ModelCommandActions {
|
|
|
125
127
|
this.host.addEntry({ id: createId("system"), kind: "system", text: `Autocomplete model set to ${saved.modelRef}.` });
|
|
126
128
|
this.host.setSessionStatus(runtime.session);
|
|
127
129
|
}
|
|
130
|
+
async runNoContextFilesSlashCommand(argumentsText) {
|
|
131
|
+
const value = argumentsText.trim().toLowerCase();
|
|
132
|
+
if (!value) {
|
|
133
|
+
this.host.addEntry({
|
|
134
|
+
id: createId("system"),
|
|
135
|
+
kind: "system",
|
|
136
|
+
text: [
|
|
137
|
+
`Context file loading is currently ${this.host.ignoreContextFiles() ? "disabled" : "enabled"} for this project.`,
|
|
138
|
+
"Usage: /no-context-files <on|off>",
|
|
139
|
+
].join("\n"),
|
|
140
|
+
});
|
|
141
|
+
this.host.setSessionStatus(this.host.runtime()?.session);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (value !== "on" && value !== "off")
|
|
145
|
+
throw new Error("Usage: /no-context-files <on|off>");
|
|
146
|
+
const ignoreContextFiles = value === "on";
|
|
147
|
+
const saved = saveProjectPixIgnoreContextFiles(this.host.options.cwd, ignoreContextFiles);
|
|
148
|
+
this.host.setIgnoreContextFiles(saved);
|
|
149
|
+
this.host.addEntry({
|
|
150
|
+
id: createId("system"),
|
|
151
|
+
kind: "system",
|
|
152
|
+
text: [
|
|
153
|
+
`Context file loading ${saved ? "disabled" : "enabled"} for this project.`,
|
|
154
|
+
`Saved ignoreContextFiles=${saved ? "true" : "false"} to ${getProjectPixConfigPath(this.host.options.cwd)}.`,
|
|
155
|
+
"Start a new session or restart Pix for the change to affect loaded AGENTS.md/CLAUDE.md context.",
|
|
156
|
+
].join("\n"),
|
|
157
|
+
});
|
|
158
|
+
this.host.setSessionStatus(this.host.runtime()?.session);
|
|
159
|
+
}
|
|
128
160
|
async runScopedModelsCommand(argumentsText) {
|
|
129
161
|
const runtime = getIdleRuntime(this.host, "scoped-models");
|
|
130
162
|
if (!runtime)
|
|
@@ -246,9 +278,13 @@ export class ModelCommandActions {
|
|
|
246
278
|
this.host.setStatus(`selecting thinking ${level}`);
|
|
247
279
|
this.host.render();
|
|
248
280
|
runtime.session.setThinkingLevel(level);
|
|
249
|
-
this.
|
|
281
|
+
this.addPersistentSystemEntry(runtime.session, `Selected thinking level ${runtime.session.thinkingLevel}`);
|
|
250
282
|
this.host.setSessionStatus(runtime.session);
|
|
251
283
|
}
|
|
284
|
+
addPersistentSystemEntry(session, text) {
|
|
285
|
+
appendPixSystemDisplayEntry(session, text);
|
|
286
|
+
this.host.addEntry({ id: createId("system"), kind: "system", text });
|
|
287
|
+
}
|
|
252
288
|
saveDefaultModel(modelRef) {
|
|
253
289
|
const saved = savePixDefaultModel(modelRef);
|
|
254
290
|
if (!saved)
|
|
@@ -98,6 +98,9 @@ export class NavigationCommandActions {
|
|
|
98
98
|
const runtime = getRuntime(this.host, "jump");
|
|
99
99
|
if (!runtime)
|
|
100
100
|
return;
|
|
101
|
+
this.host.setStatus("scanning session messages…");
|
|
102
|
+
this.host.render();
|
|
103
|
+
await this.host.refreshUserMessageJumpMenuItems();
|
|
101
104
|
this.host.openDirectPopupMenu("user-message-jump", { preserveStatus: true });
|
|
102
105
|
this.host.setDirectPopupMenuQuery(argumentsText.trim());
|
|
103
106
|
this.host.render();
|
|
@@ -5,6 +5,7 @@ export type CommandRegistryActions = {
|
|
|
5
5
|
runModelSlashCommand(argumentsText: string): Promise<void>;
|
|
6
6
|
runDefaultModelSlashCommand(argumentsText: string): Promise<void>;
|
|
7
7
|
runAutocompleteSlashCommand(argumentsText: string): Promise<void>;
|
|
8
|
+
runNoContextFilesSlashCommand(argumentsText: string): Promise<void>;
|
|
8
9
|
runScopedModelsCommand(argumentsText: string): Promise<void>;
|
|
9
10
|
runThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
10
11
|
runDefaultThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
@@ -32,6 +32,14 @@ export function createSlashCommands(actions, host) {
|
|
|
32
32
|
allowArguments: true,
|
|
33
33
|
run: (argumentsText) => actions.runAutocompleteSlashCommand(argumentsText),
|
|
34
34
|
},
|
|
35
|
+
{
|
|
36
|
+
name: "no-context-files",
|
|
37
|
+
description: "Set project AGENTS.md/CLAUDE.md loading off or on",
|
|
38
|
+
kind: "builtin",
|
|
39
|
+
keywords: ["context", "agents", "claude", "project", "config"],
|
|
40
|
+
allowArguments: true,
|
|
41
|
+
run: (argumentsText) => actions.runNoContextFilesSlashCommand(argumentsText),
|
|
42
|
+
},
|
|
35
43
|
{
|
|
36
44
|
name: "scoped-models",
|
|
37
45
|
description: "Show or set models used by the model selector/cycling",
|
|
@@ -7,10 +7,14 @@ export type ExtensionTerminalInputResult = {
|
|
|
7
7
|
};
|
|
8
8
|
export type ExtensionUiControllerHost = {
|
|
9
9
|
readonly theme: Theme;
|
|
10
|
+
activeExtensionUiScope?(): string | undefined;
|
|
10
11
|
isRunning(): boolean;
|
|
11
12
|
render(): void;
|
|
12
|
-
showToast(message: string, kind?: ToastKind
|
|
13
|
+
showToast(message: string, kind?: ToastKind, options?: {
|
|
14
|
+
scopeKey?: string;
|
|
15
|
+
}): void;
|
|
13
16
|
readonly toastNotifier: ToastNotifier;
|
|
17
|
+
toastNotifierForScope?(scopeKey: string | undefined): ToastNotifier;
|
|
14
18
|
readonly menuController: PixMenuController;
|
|
15
19
|
setStatus(status: string): void;
|
|
16
20
|
restoreSessionStatus(): void;
|
|
@@ -23,22 +27,24 @@ export declare class ExtensionUiController {
|
|
|
23
27
|
private readonly host;
|
|
24
28
|
private readonly extensionWidgets;
|
|
25
29
|
private readonly terminalInputHandlers;
|
|
26
|
-
private
|
|
27
|
-
private readonly aboveInputRenderer;
|
|
30
|
+
private readonly activeCustomUis;
|
|
28
31
|
constructor(host: ExtensionUiControllerHost);
|
|
29
32
|
get widgets(): ReadonlyMap<string, ExtensionWidgetRegistration>;
|
|
30
33
|
createExtensionTheme(): ExtensionWidgetTheme;
|
|
31
34
|
setWidget(key: string, content: unknown, options?: {
|
|
32
35
|
placement?: WidgetPlacement;
|
|
36
|
+
scopeKey?: string;
|
|
37
|
+
}): void;
|
|
38
|
+
clearWidgets(scopeKey?: string, options?: {
|
|
39
|
+
cancelCustomUi?: boolean;
|
|
33
40
|
}): void;
|
|
34
|
-
clearWidgets(): void;
|
|
35
41
|
suppressWidget(key: string): void;
|
|
36
42
|
handleTerminalInput(data: string): ExtensionTerminalInputResult;
|
|
37
43
|
renderActiveCustomUi(width: number): string[] | undefined;
|
|
38
44
|
activeCustomUiUsesEditor(): boolean;
|
|
39
45
|
handleCustomUiMouse(event: ExtensionInputMouseEvent): boolean;
|
|
40
46
|
widgetTuiHandle(): WidgetTuiHandle;
|
|
41
|
-
createExtensionUIContext(): PixExtensionUIContext;
|
|
47
|
+
createExtensionUIContext(scopeKey?: string): PixExtensionUIContext;
|
|
42
48
|
private setAboveInputWidget;
|
|
43
49
|
private clearAboveInputWidget;
|
|
44
50
|
private selectDialog;
|
|
@@ -53,5 +59,10 @@ export declare class ExtensionUiController {
|
|
|
53
59
|
private cancelActiveCustomUi;
|
|
54
60
|
private rejectActiveCustomUi;
|
|
55
61
|
private finishActiveCustomUi;
|
|
62
|
+
private activeCustomUiForActiveScope;
|
|
63
|
+
private activeScopeKey;
|
|
64
|
+
private normalizeScopeKey;
|
|
65
|
+
private scopedWidgetKey;
|
|
66
|
+
private unscopedWidgetKey;
|
|
56
67
|
private invalidateWidget;
|
|
57
68
|
}
|