pi-ui-extend 0.1.11 → 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 +88 -16
- package/dist/app/cli/install.d.ts +14 -0
- package/dist/app/cli/install.js +19 -7
- package/dist/app/cli/startup-info.js +5 -2
- package/dist/app/cli/update.d.ts +7 -0
- package/dist/app/cli/update.js +11 -3
- 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/commands/shell-command.d.ts +7 -0
- package/dist/app/commands/shell-command.js +12 -4
- package/dist/app/extensions/extension-ui-controller.d.ts +16 -5
- package/dist/app/extensions/extension-ui-controller.js +99 -61
- package/dist/app/icons.d.ts +1 -0
- package/dist/app/icons.js +2 -0
- package/dist/app/input/input-action-controller.d.ts +1 -0
- package/dist/app/input/input-action-controller.js +8 -2
- package/dist/app/input/prompt-enhancer-controller.d.ts +7 -1
- package/dist/app/input/prompt-enhancer-controller.js +12 -3
- package/dist/app/input/voice-controller.d.ts +49 -1
- package/dist/app/input/voice-controller.js +16 -5
- 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 +4 -13
- 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 +30 -35
- package/dist/app/rendering/toast-controller.d.ts +11 -3
- package/dist/app/rendering/toast-controller.js +53 -12
- package/dist/app/rendering/toast-renderer.js +10 -13
- package/dist/app/rendering/tool-block-renderer.d.ts +1 -0
- package/dist/app/rendering/tool-block-renderer.js +3 -2
- package/dist/app/runtime.d.ts +2 -1
- package/dist/app/runtime.js +20 -10
- package/dist/app/screen/clipboard.d.ts +9 -0
- package/dist/app/screen/clipboard.js +19 -6
- package/dist/app/screen/file-link-opener.d.ts +8 -0
- package/dist/app/screen/file-link-opener.js +11 -3
- package/dist/app/screen/file-links.js +3 -3
- package/dist/app/screen/image-opener.d.ts +12 -0
- package/dist/app/screen/image-opener.js +13 -5
- 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/queued-message-controller.js +5 -1
- 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/terminal/nerd-font-controller.d.ts +16 -0
- package/dist/app/terminal/nerd-font-controller.js +20 -12
- 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 +9 -6
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.js +5 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +178 -0
- package/dist/schemas/pi-tools-suite-schema.js +219 -0
- package/dist/schemas/pix-schema.d.ts +66 -0
- package/dist/schemas/pix-schema.js +92 -0
- package/dist/terminal-width.d.ts +2 -0
- package/dist/terminal-width.js +134 -56
- 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/async-subagents/async-subagents.sample.jsonc +3 -0
- 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 +4 -0
- package/external/pi-tools-suite/src/todo/index.ts +185 -13
- package/external/pi-tools-suite/src/todo/state/selectors.ts +4 -0
- package/external/pi-tools-suite/src/todo/state/state-reducer.ts +23 -10
- package/external/pi-tools-suite/src/todo/todo.ts +12 -11
- 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 +12 -3
- package/schemas/pi-tools-suite.json +885 -0
- package/schemas/pix.json +302 -0
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
|
}
|
|
@@ -874,12 +930,14 @@ export class PiUiExtendApp {
|
|
|
874
930
|
}
|
|
875
931
|
toggleSuperCompactTools() {
|
|
876
932
|
this.superCompactTools = !this.superCompactTools;
|
|
877
|
-
if (!this.superCompactTools)
|
|
878
|
-
return;
|
|
879
933
|
for (const entry of this.entries) {
|
|
880
|
-
if (entry.kind !== "tool"
|
|
934
|
+
if (entry.kind !== "tool")
|
|
935
|
+
continue;
|
|
936
|
+
const defaultExpanded = resolveToolRule(entry.toolName, this.pixConfig.toolRenderer).defaultExpanded === true;
|
|
937
|
+
const nextExpanded = this.superCompactTools ? false : defaultExpanded;
|
|
938
|
+
if (entry.expanded === nextExpanded)
|
|
881
939
|
continue;
|
|
882
|
-
entry.expanded =
|
|
940
|
+
entry.expanded = nextExpanded;
|
|
883
941
|
this.touchEntry(entry);
|
|
884
942
|
}
|
|
885
943
|
}
|
|
@@ -926,6 +984,20 @@ export class PiUiExtendApp {
|
|
|
926
984
|
showToast(message, kind = "info", options) {
|
|
927
985
|
this.toastController.showToast(message, kind, options);
|
|
928
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
|
+
}
|
|
929
1001
|
clearToastTimers() {
|
|
930
1002
|
this.toastController.clearToastTimers();
|
|
931
1003
|
}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { installJetBrainsNerdFont, isJetBrainsNerdFontInstalled } from "../terminal/nerd-font-controller.js";
|
|
4
|
+
import { clipboardInstallHint, clipboardSupportAvailable } from "../screen/clipboard.js";
|
|
5
|
+
type PixInstallTestDeps = {
|
|
6
|
+
existsSync: typeof existsSync;
|
|
7
|
+
spawn: typeof spawn;
|
|
8
|
+
isJetBrainsNerdFontInstalled: typeof isJetBrainsNerdFontInstalled;
|
|
9
|
+
installJetBrainsNerdFont: typeof installJetBrainsNerdFont;
|
|
10
|
+
clipboardSupportAvailable: typeof clipboardSupportAvailable;
|
|
11
|
+
clipboardInstallHint: typeof clipboardInstallHint;
|
|
12
|
+
};
|
|
13
|
+
export declare function setPixInstallTestDeps(overrides?: Partial<PixInstallTestDeps>): void;
|
|
1
14
|
export type PixInstallCliOptions = {
|
|
2
15
|
checkOnly: boolean;
|
|
3
16
|
help: boolean;
|
|
@@ -10,3 +23,4 @@ export declare function formatPixInstallNextSteps(homeDir?: string): string;
|
|
|
10
23
|
export declare function pixInstallUsage(): string;
|
|
11
24
|
export declare function parsePixInstallArgs(argv: readonly string[]): PixInstallCliOptions;
|
|
12
25
|
export declare function runPixInstallCli(argv?: readonly string[], context?: PixInstallCliContext): Promise<number>;
|
|
26
|
+
export {};
|
package/dist/app/cli/install.js
CHANGED
|
@@ -5,6 +5,18 @@ import { join } from "node:path";
|
|
|
5
5
|
import { FONT_FAMILY_NAME, installJetBrainsNerdFont, isJetBrainsNerdFontInstalled, } from "../terminal/nerd-font-controller.js";
|
|
6
6
|
import { clipboardInstallHint, clipboardSupportAvailable } from "../screen/clipboard.js";
|
|
7
7
|
import { getPixConfigPath } from "../../config.js";
|
|
8
|
+
const defaultPixInstallDeps = {
|
|
9
|
+
existsSync,
|
|
10
|
+
spawn,
|
|
11
|
+
isJetBrainsNerdFontInstalled,
|
|
12
|
+
installJetBrainsNerdFont,
|
|
13
|
+
clipboardSupportAvailable,
|
|
14
|
+
clipboardInstallHint,
|
|
15
|
+
};
|
|
16
|
+
let pixInstallDeps = defaultPixInstallDeps;
|
|
17
|
+
export function setPixInstallTestDeps(overrides) {
|
|
18
|
+
pixInstallDeps = overrides ? { ...defaultPixInstallDeps, ...overrides } : defaultPixInstallDeps;
|
|
19
|
+
}
|
|
8
20
|
export function formatPixInstallNextSteps(homeDir = homedir()) {
|
|
9
21
|
const pixConfigPath = getPixConfigPath(homeDir);
|
|
10
22
|
const toolsConfigPath = join(homeDir, ".config", "pi", "pi-tools-suite.jsonc");
|
|
@@ -64,7 +76,7 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
64
76
|
const env = context.env ?? process.env;
|
|
65
77
|
let failures = 0;
|
|
66
78
|
console.log("Pix install checks");
|
|
67
|
-
if (await isJetBrainsNerdFontInstalled()) {
|
|
79
|
+
if (await pixInstallDeps.isJetBrainsNerdFontInstalled()) {
|
|
68
80
|
console.log(`✓ ${FONT_FAMILY_NAME} is installed`);
|
|
69
81
|
}
|
|
70
82
|
else if (options.checkOnly) {
|
|
@@ -73,7 +85,7 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
73
85
|
}
|
|
74
86
|
else {
|
|
75
87
|
try {
|
|
76
|
-
await installJetBrainsNerdFont();
|
|
88
|
+
await pixInstallDeps.installJetBrainsNerdFont();
|
|
77
89
|
console.log(`✓ Installed ${FONT_FAMILY_NAME}`);
|
|
78
90
|
}
|
|
79
91
|
catch (error) {
|
|
@@ -100,11 +112,11 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
100
112
|
failures += 1;
|
|
101
113
|
}
|
|
102
114
|
}
|
|
103
|
-
if (await clipboardSupportAvailable(env)) {
|
|
115
|
+
if (await pixInstallDeps.clipboardSupportAvailable(env)) {
|
|
104
116
|
console.log("✓ Clipboard support is available");
|
|
105
117
|
}
|
|
106
118
|
else {
|
|
107
|
-
console.log(`! Clipboard support is missing. ${clipboardInstallHint()}`);
|
|
119
|
+
console.log(`! Clipboard support is missing. ${pixInstallDeps.clipboardInstallHint()}`);
|
|
108
120
|
if (process.platform === "linux")
|
|
109
121
|
failures += 1;
|
|
110
122
|
}
|
|
@@ -113,7 +125,7 @@ export async function runPixInstallCli(argv = process.argv.slice(2), context = {
|
|
|
113
125
|
}
|
|
114
126
|
async function resolvePiCliStatus(env) {
|
|
115
127
|
const bundledBin = env.PIX_BUNDLED_PI_BIN;
|
|
116
|
-
if (bundledBin && (existsSync(join(bundledBin, process.platform === "win32" ? "pi.cmd" : "pi")) || existsSync(join(bundledBin, "pi")))) {
|
|
128
|
+
if (bundledBin && (pixInstallDeps.existsSync(join(bundledBin, process.platform === "win32" ? "pi.cmd" : "pi")) || pixInstallDeps.existsSync(join(bundledBin, "pi")))) {
|
|
117
129
|
return { available: true, detail: "bundled with Pix" };
|
|
118
130
|
}
|
|
119
131
|
if (commandExists("pi", env))
|
|
@@ -127,11 +139,11 @@ function commandExists(command, env = process.env) {
|
|
|
127
139
|
const pathValue = env.PATH ?? "";
|
|
128
140
|
const dirs = pathValue.split(process.platform === "win32" ? ";" : ":").filter(Boolean);
|
|
129
141
|
const names = process.platform === "win32" ? [command, `${command}.cmd`, `${command}.exe`, `${command}.bat`] : [command];
|
|
130
|
-
return dirs.some((dir) => names.some((name) => existsSync(join(dir, name))));
|
|
142
|
+
return dirs.some((dir) => names.some((name) => pixInstallDeps.existsSync(join(dir, name))));
|
|
131
143
|
}
|
|
132
144
|
async function runRequired(command, args) {
|
|
133
145
|
await new Promise((resolve, reject) => {
|
|
134
|
-
const child = spawn(command, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
146
|
+
const child = pixInstallDeps.spawn(command, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
135
147
|
let stderr = "";
|
|
136
148
|
child.stderr.on("data", (chunk) => {
|
|
137
149
|
stderr = `${stderr}${chunk.toString("utf8")}`.slice(-800);
|
|
@@ -158,9 +158,12 @@ function displayPath(pathValue, cwd) {
|
|
|
158
158
|
}
|
|
159
159
|
function formatPath(pathValue, cwd) {
|
|
160
160
|
if (!isAbsolute(pathValue))
|
|
161
|
-
return pathValue;
|
|
161
|
+
return displayPathSeparators(pathValue);
|
|
162
162
|
const rel = relative(cwd, pathValue);
|
|
163
|
-
return rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : basename(pathValue);
|
|
163
|
+
return displayPathSeparators(rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : basename(pathValue));
|
|
164
|
+
}
|
|
165
|
+
function displayPathSeparators(pathValue) {
|
|
166
|
+
return pathValue.replace(/\\/g, "/");
|
|
164
167
|
}
|
|
165
168
|
function unique(...groups) {
|
|
166
169
|
const seen = new Set();
|
package/dist/app/cli/update.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
type PixUpdateTestDeps = {
|
|
2
|
+
checkPixUpdate: typeof checkPixUpdate;
|
|
3
|
+
runCommand: typeof runCommand;
|
|
4
|
+
};
|
|
5
|
+
export declare function setPixUpdateTestDeps(overrides?: Partial<PixUpdateTestDeps>): void;
|
|
1
6
|
export type PixUpdateCliOptions = {
|
|
2
7
|
checkOnly: boolean;
|
|
3
8
|
force: boolean;
|
|
@@ -36,3 +41,5 @@ export declare function formatPixUpdateCheck(result: PixUpdateCheckResult): stri
|
|
|
36
41
|
export declare function formatPixStartupUpdateDialog(result: PixUpdateCheckResult): string;
|
|
37
42
|
export declare function getPixSelfUpdateCommand(packageName: string, latestVersion?: string, packageRoot?: string): PixSelfUpdateCommand | undefined;
|
|
38
43
|
export declare function runPixUpdateCli(argv?: readonly string[]): Promise<number>;
|
|
44
|
+
declare function runCommand(command: PixSelfUpdateCommand): Promise<void>;
|
|
45
|
+
export {};
|
package/dist/app/cli/update.js
CHANGED
|
@@ -5,6 +5,14 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { getAgentDir, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
const DEFAULT_UPDATE_TIMEOUT_MS = 10_000;
|
|
7
7
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
8
|
+
const defaultPixUpdateDeps = {
|
|
9
|
+
checkPixUpdate,
|
|
10
|
+
runCommand,
|
|
11
|
+
};
|
|
12
|
+
let pixUpdateDeps = defaultPixUpdateDeps;
|
|
13
|
+
export function setPixUpdateTestDeps(overrides) {
|
|
14
|
+
pixUpdateDeps = overrides ? { ...defaultPixUpdateDeps, ...overrides } : defaultPixUpdateDeps;
|
|
15
|
+
}
|
|
8
16
|
export function pixUpdateUsage() {
|
|
9
17
|
return `Usage: pix update [--check] [--force]
|
|
10
18
|
|
|
@@ -157,7 +165,7 @@ export async function runPixUpdateCli(argv = process.argv.slice(2)) {
|
|
|
157
165
|
console.log(pixUpdateUsage());
|
|
158
166
|
return 0;
|
|
159
167
|
}
|
|
160
|
-
const check = await checkPixUpdate();
|
|
168
|
+
const check = await pixUpdateDeps.checkPixUpdate();
|
|
161
169
|
console.log(formatPixUpdateCheck(check));
|
|
162
170
|
if (options.checkOnly)
|
|
163
171
|
return check.status === "unavailable" ? 1 : 0;
|
|
@@ -165,14 +173,14 @@ export async function runPixUpdateCli(argv = process.argv.slice(2)) {
|
|
|
165
173
|
return 0;
|
|
166
174
|
if ((check.status === "skipped" || check.status === "unavailable") && !options.force)
|
|
167
175
|
return 1;
|
|
168
|
-
const command = getPixSelfUpdateCommand(check.packageName, check.latestVersion);
|
|
176
|
+
const command = getPixSelfUpdateCommand(check.packageName, check.latestVersion, check.packageRoot);
|
|
169
177
|
if (!command) {
|
|
170
178
|
console.error(`pix cannot self-update this installation. ${sourceCheckoutUpdateHint()}`);
|
|
171
179
|
return 1;
|
|
172
180
|
}
|
|
173
181
|
console.log(`Updating Pix with ${command.display}...`);
|
|
174
182
|
try {
|
|
175
|
-
await runCommand(command);
|
|
183
|
+
await pixUpdateDeps.runCommand(command);
|
|
176
184
|
console.log("Updated Pix. Restart any running pix sessions.");
|
|
177
185
|
return 0;
|
|
178
186
|
}
|
|
@@ -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",
|