@earendil-works/pi-coding-agent 0.84.0 → 0.84.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -2
- package/README.md +1 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +14 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts +19 -0
- package/dist/cli/auth-check.d.ts.map +1 -0
- package/dist/cli/auth-check.js +50 -0
- package/dist/cli/auth-check.js.map +1 -0
- package/dist/cli/auth-command.d.ts +24 -0
- package/dist/cli/auth-command.d.ts.map +1 -0
- package/dist/cli/auth-command.js +103 -0
- package/dist/cli/auth-command.js.map +1 -0
- package/dist/cli/credential-print.d.ts +4 -14
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +38 -79
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +10 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +78 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +4 -0
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +32 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +3 -1
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +2 -2
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +12 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +8 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +13 -7
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +4 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +6 -2
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +6 -2
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +8 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +8 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +62 -22
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +10 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +113 -31
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +34 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +5 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +23 -5
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +4 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +5 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/create-harness.d.ts +26 -0
- package/dist/server/create-harness.d.ts.map +1 -0
- package/dist/server/create-harness.js +106 -0
- package/dist/server/create-harness.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +10 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +14 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/compaction.md +6 -6
- package/docs/custom-provider.md +1 -1
- package/docs/environment-variables.md +8 -2
- package/docs/extensions.md +7 -2
- package/docs/json.md +6 -4
- package/docs/keybindings.md +16 -6
- package/docs/providers.md +8 -1
- package/docs/rpc.md +15 -4
- package/docs/sdk.md +9 -0
- package/docs/settings.md +31 -0
- package/docs/terminal-setup.md +23 -2
- package/docs/themes.md +24 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +3 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +2 -0
- package/examples/extensions/subagent/agents.ts +40 -9
- package/examples/extensions/subagent/index.ts +21 -3
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +27 -78
- package/package.json +7 -7
|
@@ -69,6 +69,7 @@ import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
|
69
69
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
70
70
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
71
71
|
import { editInExternalEditor } from "./external-editor.js";
|
|
72
|
+
import { refreshModelCatalogs } from "./model-catalog-refresh.js";
|
|
72
73
|
import { getModelSearchText } from "./model-search.js";
|
|
73
74
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
74
75
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
@@ -169,7 +170,22 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
|
169
170
|
export function createInteractiveTui(options) {
|
|
170
171
|
const terminal = options.terminal ?? new ProcessTerminal();
|
|
171
172
|
if (options.tuiMode === "fullscreen") {
|
|
172
|
-
|
|
173
|
+
const styleSearchMatch = (text) => theme.bg("searchMatchBg", theme.fg("searchMatchText", text));
|
|
174
|
+
return new TuiAltScreen(terminal, options.showHardwareCursor, options.logDirectory, {
|
|
175
|
+
searchMatchStyle: (text) => theme.underline(styleSearchMatch(text)),
|
|
176
|
+
searchCurrentMatchStyle: (text) => theme.bold(theme.inverse(styleSearchMatch(text))),
|
|
177
|
+
openUrl: openBrowser,
|
|
178
|
+
onRightClickPaste: options.onRightClickPaste,
|
|
179
|
+
copySelection: async (text) => {
|
|
180
|
+
try {
|
|
181
|
+
await copyToClipboard(text);
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
});
|
|
173
189
|
}
|
|
174
190
|
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
175
191
|
}
|
|
@@ -181,12 +197,19 @@ export function createInteractiveTuiReference(getTui) {
|
|
|
181
197
|
const value = Reflect.get(tui, property, tui);
|
|
182
198
|
if (typeof value !== "function")
|
|
183
199
|
return value;
|
|
200
|
+
let methodTui = tui;
|
|
201
|
+
let method = value;
|
|
184
202
|
return (...args) => {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
203
|
+
const currentTui = getTui();
|
|
204
|
+
if (currentTui !== methodTui) {
|
|
205
|
+
const currentMethod = Reflect.get(currentTui, property, currentTui);
|
|
206
|
+
if (typeof currentMethod !== "function") {
|
|
207
|
+
throw new TypeError(`TUI property ${String(property)} is not callable`);
|
|
208
|
+
}
|
|
209
|
+
methodTui = currentTui;
|
|
210
|
+
method = currentMethod;
|
|
211
|
+
}
|
|
212
|
+
return Reflect.apply(method, methodTui, args);
|
|
190
213
|
};
|
|
191
214
|
},
|
|
192
215
|
set: (_target, property, value) => {
|
|
@@ -243,6 +266,7 @@ export class InteractiveMode {
|
|
|
243
266
|
// Status line tracking (for mutating immediately-sequential status updates)
|
|
244
267
|
lastStatusSpacer = undefined;
|
|
245
268
|
lastStatusText = undefined;
|
|
269
|
+
managedToolStatusStarted = false;
|
|
246
270
|
// Streaming message tracking
|
|
247
271
|
streamingComponent = undefined;
|
|
248
272
|
streamingMessage = undefined;
|
|
@@ -295,6 +319,9 @@ export class InteractiveMode {
|
|
|
295
319
|
// Custom header from extension (undefined = use built-in header)
|
|
296
320
|
customHeader = undefined;
|
|
297
321
|
options;
|
|
322
|
+
onRightClickPaste = () => {
|
|
323
|
+
void this.handleRightClickPaste();
|
|
324
|
+
};
|
|
298
325
|
autoTrustOnReloadCwd;
|
|
299
326
|
themeController;
|
|
300
327
|
// Convenience accessors
|
|
@@ -320,12 +347,14 @@ export class InteractiveMode {
|
|
|
320
347
|
});
|
|
321
348
|
this.runtimeHost.setRebindSession(async () => {
|
|
322
349
|
await this.rebindCurrentSession({ renderBeforeBind: true });
|
|
350
|
+
await this.themeController.applyFromSettings();
|
|
323
351
|
});
|
|
324
352
|
this.version = VERSION;
|
|
325
353
|
this.renderer = createInteractiveTui({
|
|
326
354
|
tuiMode,
|
|
327
355
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
328
356
|
logDirectory: getAgentDir(),
|
|
357
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
329
358
|
});
|
|
330
359
|
this.ui = createInteractiveTuiReference(() => this.renderer);
|
|
331
360
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
@@ -361,7 +390,12 @@ export class InteractiveMode {
|
|
|
361
390
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
362
391
|
// Register themes from resource loader and initialize
|
|
363
392
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
364
|
-
this.themeController = new InteractiveThemeController(this.ui,
|
|
393
|
+
this.themeController = new InteractiveThemeController(this.ui, {
|
|
394
|
+
getSettingsManager: () => this.settingsManager,
|
|
395
|
+
showError: (message) => this.showError(message),
|
|
396
|
+
onChanged: () => this.updateEditorBorderColor(),
|
|
397
|
+
initialThemeSetting: options.initialThemeSetting,
|
|
398
|
+
});
|
|
365
399
|
}
|
|
366
400
|
getAutocompleteSourceTag(sourceInfo) {
|
|
367
401
|
if (!sourceInfo) {
|
|
@@ -524,14 +558,14 @@ export class InteractiveMode {
|
|
|
524
558
|
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
525
559
|
}
|
|
526
560
|
}
|
|
527
|
-
stopInteractiveTui() {
|
|
528
|
-
if (this.renderer.mode === "fullscreen") {
|
|
561
|
+
stopInteractiveTui(fullscreenExitOutput) {
|
|
562
|
+
if (this.renderer.mode === "fullscreen" && fullscreenExitOutput === "transcript") {
|
|
529
563
|
while (this.renderer.hasOverlayEntries)
|
|
530
564
|
this.renderer.hideOverlay();
|
|
531
565
|
this.switchTuiMode("regular", false, false);
|
|
532
566
|
this.renderer.renderNow();
|
|
533
567
|
}
|
|
534
|
-
this.ui.stop();
|
|
568
|
+
this.ui.stop({ preserveScreen: this.renderer.mode === "fullscreen" });
|
|
535
569
|
}
|
|
536
570
|
switchTuiMode(mode, restoreProgress = true, startRenderer = true) {
|
|
537
571
|
const previousUi = this.renderer;
|
|
@@ -558,6 +592,7 @@ export class InteractiveMode {
|
|
|
558
592
|
showHardwareCursor,
|
|
559
593
|
logDirectory: getAgentDir(),
|
|
560
594
|
terminal,
|
|
595
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
561
596
|
});
|
|
562
597
|
nextUi.setClearOnShrink(clearOnShrink);
|
|
563
598
|
nextUi.onDebug = onDebug;
|
|
@@ -587,10 +622,6 @@ export class InteractiveMode {
|
|
|
587
622
|
this.registerSignalHandlers();
|
|
588
623
|
// Load changelog (only show new entries, skip for resumed sessions)
|
|
589
624
|
this.changelogMarkdown = this.getChangelogForDisplay();
|
|
590
|
-
// Ensure fd and rg are available (downloads if missing, adds to PATH via getBinDir)
|
|
591
|
-
// Both are needed: fd for autocomplete, rg for grep tool and bash commands
|
|
592
|
-
const [fdPath] = await Promise.all([ensureTool("fd"), ensureTool("rg")]);
|
|
593
|
-
this.fdPath = fdPath;
|
|
594
625
|
if (this.session.scopedModels.length > 0 && (this.options.verbose || !this.settingsManager.getQuietStartup())) {
|
|
595
626
|
const modelList = this.session.scopedModels
|
|
596
627
|
.map((sm) => {
|
|
@@ -634,9 +665,11 @@ export class InteractiveMode {
|
|
|
634
665
|
this.widgetContainerBelow,
|
|
635
666
|
this.footerContainer,
|
|
636
667
|
]);
|
|
668
|
+
// Accept text while startup completes, but only enable interrupt, exit, and submission feedback.
|
|
669
|
+
this.defaultEditor.onAction("app.clear", () => this.handleCtrlC());
|
|
670
|
+
this.defaultEditor.onCtrlD = () => this.handleCtrlD();
|
|
671
|
+
this.defaultEditor.onSubmit = (text) => this.handleStartupSubmit(text);
|
|
637
672
|
this.ui.setFocus(this.editor);
|
|
638
|
-
this.setupKeyHandlers();
|
|
639
|
-
this.setupEditorSubmitHandler();
|
|
640
673
|
// Start the UI before initializing extensions so session_start handlers can use interactive dialogs
|
|
641
674
|
this.ui.start();
|
|
642
675
|
this.isInitialized = true;
|
|
@@ -688,6 +721,18 @@ export class InteractiveMode {
|
|
|
688
721
|
this.headerContainer.addChild(this.builtInHeader);
|
|
689
722
|
}
|
|
690
723
|
this.ui.requestRender();
|
|
724
|
+
// Ensure fd and rg are available after mounting the TUI (downloads if missing, adds to PATH via getBinDir)
|
|
725
|
+
// so slow downloads do not make startup appear frozen.
|
|
726
|
+
// Both are needed: fd for autocomplete, rg for grep tool and bash commands.
|
|
727
|
+
const [fdPath] = await Promise.all([
|
|
728
|
+
ensureTool("fd", (status) => this.showManagedToolStatus(status)),
|
|
729
|
+
ensureTool("rg", (status) => this.showManagedToolStatus(status)),
|
|
730
|
+
]);
|
|
731
|
+
this.fdPath = fdPath;
|
|
732
|
+
// Enable the remaining input handlers only after managed-tool setup completes.
|
|
733
|
+
this.setupKeyHandlers();
|
|
734
|
+
this.setupEditorSubmitHandler();
|
|
735
|
+
this.ui.requestRender();
|
|
691
736
|
// Initialize extensions first so resources are shown before messages
|
|
692
737
|
await this.rebindCurrentSession();
|
|
693
738
|
// Render initial messages AFTER showing loaded resources
|
|
@@ -727,8 +772,7 @@ export class InteractiveMode {
|
|
|
727
772
|
if (!process.env.PI_OFFLINE) {
|
|
728
773
|
const controller = new AbortController();
|
|
729
774
|
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
730
|
-
void this.session.modelRuntime
|
|
731
|
-
.refresh({ signal: controller.signal })
|
|
775
|
+
void refreshModelCatalogs(this.session.modelRuntime, controller.signal)
|
|
732
776
|
.then(() => this.updateAvailableProviderCount())
|
|
733
777
|
.catch(() => { })
|
|
734
778
|
.finally(() => clearTimeout(timeout));
|
|
@@ -1484,7 +1528,7 @@ export class InteractiveMode {
|
|
|
1484
1528
|
const message = error instanceof Error ? error.message : String(error);
|
|
1485
1529
|
this.showError(`${prefix}: ${message}`);
|
|
1486
1530
|
stopThemeWatcher();
|
|
1487
|
-
this.stop();
|
|
1531
|
+
this.stop("transcript");
|
|
1488
1532
|
process.exit(1);
|
|
1489
1533
|
}
|
|
1490
1534
|
renderCurrentSessionState() {
|
|
@@ -2237,6 +2281,22 @@ export class InteractiveMode {
|
|
|
2237
2281
|
void this.handleClipboardPaste();
|
|
2238
2282
|
};
|
|
2239
2283
|
}
|
|
2284
|
+
async handleRightClickPaste() {
|
|
2285
|
+
const target = this.renderer.getFocusedComponent();
|
|
2286
|
+
const handleInput = target?.handleInput;
|
|
2287
|
+
if (!target || !handleInput)
|
|
2288
|
+
return;
|
|
2289
|
+
try {
|
|
2290
|
+
const text = await readClipboardText();
|
|
2291
|
+
if (!text || this.renderer.getFocusedComponent() !== target)
|
|
2292
|
+
return;
|
|
2293
|
+
handleInput.call(target, `\x1b[200~${text}\x1b[201~`);
|
|
2294
|
+
this.ui.requestRender();
|
|
2295
|
+
}
|
|
2296
|
+
catch {
|
|
2297
|
+
// Silently ignore clipboard errors (may not have permission, etc.)
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2240
2300
|
async handleClipboardPaste() {
|
|
2241
2301
|
try {
|
|
2242
2302
|
const image = await readClipboardImage();
|
|
@@ -2260,6 +2320,10 @@ export class InteractiveMode {
|
|
|
2260
2320
|
// Silently ignore clipboard errors (may not have permission, etc.)
|
|
2261
2321
|
}
|
|
2262
2322
|
}
|
|
2323
|
+
handleStartupSubmit(text) {
|
|
2324
|
+
this.editor.setText(text);
|
|
2325
|
+
this.showStatus("Startup is still in progress");
|
|
2326
|
+
}
|
|
2263
2327
|
setupEditorSubmitHandler() {
|
|
2264
2328
|
this.defaultEditor.onSubmit = async (text) => {
|
|
2265
2329
|
text = text.trim();
|
|
@@ -2735,6 +2799,19 @@ export class InteractiveMode {
|
|
|
2735
2799
|
: message.content.filter((c) => c.type === "text");
|
|
2736
2800
|
return textBlocks.map((c) => c.text).join("");
|
|
2737
2801
|
}
|
|
2802
|
+
/** Show a managed-tool status update in the chat. */
|
|
2803
|
+
showManagedToolStatus(status) {
|
|
2804
|
+
if (!this.managedToolStatusStarted) {
|
|
2805
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
2806
|
+
this.managedToolStatusStarted = true;
|
|
2807
|
+
}
|
|
2808
|
+
const message = status.type === "warning" ? `Warning: ${status.message}` : status.message;
|
|
2809
|
+
const color = status.type === "warning" ? "warning" : "dim";
|
|
2810
|
+
this.chatContainer.addChild(new Text(theme.fg(color, message), 1, 0));
|
|
2811
|
+
this.lastStatusSpacer = undefined;
|
|
2812
|
+
this.lastStatusText = undefined;
|
|
2813
|
+
this.ui.requestRender();
|
|
2814
|
+
}
|
|
2738
2815
|
/**
|
|
2739
2816
|
* Show a status message in the chat.
|
|
2740
2817
|
*
|
|
@@ -3106,7 +3183,7 @@ export class InteractiveMode {
|
|
|
3106
3183
|
this.ui.stop();
|
|
3107
3184
|
}
|
|
3108
3185
|
catch { }
|
|
3109
|
-
console.error(
|
|
3186
|
+
console.error(`${APP_NAME} exiting due to uncaughtException:`);
|
|
3110
3187
|
console.error(error);
|
|
3111
3188
|
process.exit(1);
|
|
3112
3189
|
}
|
|
@@ -3591,7 +3668,7 @@ export class InteractiveMode {
|
|
|
3591
3668
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3592
3669
|
thinkingLevel: this.session.thinkingLevel,
|
|
3593
3670
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
3594
|
-
currentTheme: this.
|
|
3671
|
+
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3595
3672
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3596
3673
|
availableThemes: getAvailableThemes(),
|
|
3597
3674
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
@@ -3610,6 +3687,7 @@ export class InteractiveMode {
|
|
|
3610
3687
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3611
3688
|
showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
|
|
3612
3689
|
tuiMode: this.ui.mode,
|
|
3690
|
+
fullscreenExitOutput: this.settingsManager.getFullscreenExitOutput(),
|
|
3613
3691
|
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
3614
3692
|
warnings: this.settingsManager.getWarnings(),
|
|
3615
3693
|
}, {
|
|
@@ -3665,7 +3743,7 @@ export class InteractiveMode {
|
|
|
3665
3743
|
},
|
|
3666
3744
|
onThemeChange: (themeSetting) => {
|
|
3667
3745
|
this.settingsManager.setTheme(themeSetting);
|
|
3668
|
-
void this.themeController.
|
|
3746
|
+
void this.themeController.setThemeSetting(themeSetting);
|
|
3669
3747
|
},
|
|
3670
3748
|
onThemePreview: (themeName) => this.themeController.preview(themeName),
|
|
3671
3749
|
onHideThinkingBlockChange: (hidden) => {
|
|
@@ -3764,6 +3842,9 @@ export class InteractiveMode {
|
|
|
3764
3842
|
this.statusContainer.clear();
|
|
3765
3843
|
this.showStatus(`TUI mode: ${mode}`);
|
|
3766
3844
|
},
|
|
3845
|
+
onFullscreenExitOutputChange: (output) => {
|
|
3846
|
+
this.settingsManager.setFullscreenExitOutput(output);
|
|
3847
|
+
},
|
|
3767
3848
|
onFullscreenScrollbarChange: (mode) => {
|
|
3768
3849
|
this.settingsManager.setFullscreenScrollbar(mode);
|
|
3769
3850
|
this.applyFullscreenScrollbarSetting();
|
|
@@ -3816,7 +3897,7 @@ export class InteractiveMode {
|
|
|
3816
3897
|
controller.abort();
|
|
3817
3898
|
}, 15_000);
|
|
3818
3899
|
try {
|
|
3819
|
-
const result = await this.session.modelRuntime
|
|
3900
|
+
const result = await refreshModelCatalogs(this.session.modelRuntime, controller.signal);
|
|
3820
3901
|
if (result.aborted && timedOut) {
|
|
3821
3902
|
this.showWarning("Model refresh timed out; searching cached models.");
|
|
3822
3903
|
}
|
|
@@ -3904,7 +3985,7 @@ export class InteractiveMode {
|
|
|
3904
3985
|
onSelect: (selection) => {
|
|
3905
3986
|
trustStore.setMany(selection.updates);
|
|
3906
3987
|
done();
|
|
3907
|
-
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart
|
|
3988
|
+
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart ${APP_NAME} for this to take effect.`);
|
|
3908
3989
|
},
|
|
3909
3990
|
onCancel: () => {
|
|
3910
3991
|
done();
|
|
@@ -4004,8 +4085,7 @@ export class InteractiveMode {
|
|
|
4004
4085
|
this.ui.requestRender();
|
|
4005
4086
|
},
|
|
4006
4087
|
});
|
|
4007
|
-
void this.session.modelRuntime
|
|
4008
|
-
.refresh({ signal: controller.signal })
|
|
4088
|
+
void refreshModelCatalogs(this.session.modelRuntime, controller.signal)
|
|
4009
4089
|
.then((result) => {
|
|
4010
4090
|
if (disposed)
|
|
4011
4091
|
return;
|
|
@@ -4559,7 +4639,7 @@ export class InteractiveMode {
|
|
|
4559
4639
|
this.ui.requestRender();
|
|
4560
4640
|
};
|
|
4561
4641
|
const dialog = new LoginDialogComponent(this.ui, providerOption.id, () => restoreEditor(), providerOption.name, `${providerOption.name} setup`);
|
|
4562
|
-
dialog.showInfo(`${providerOption.method?.name ?? "Authentication"} is configured outside
|
|
4642
|
+
dialog.showInfo(`${providerOption.method?.name ?? "Authentication"} is configured outside ${APP_NAME}.`, [], true);
|
|
4563
4643
|
this.editorContainer.clear();
|
|
4564
4644
|
this.editorContainer.addChild(dialog);
|
|
4565
4645
|
this.ui.setFocus(dialog);
|
|
@@ -4796,7 +4876,9 @@ export class InteractiveMode {
|
|
|
4796
4876
|
this.showStatus(`Session exported to: ${filePath}`);
|
|
4797
4877
|
}
|
|
4798
4878
|
else {
|
|
4799
|
-
const filePath = await this.session.exportToHtml(outputPath
|
|
4879
|
+
const filePath = await this.session.exportToHtml(outputPath, {
|
|
4880
|
+
themeName: theme.name,
|
|
4881
|
+
});
|
|
4800
4882
|
this.showStatus(`Session exported to: ${filePath}`);
|
|
4801
4883
|
}
|
|
4802
4884
|
}
|
|
@@ -4887,7 +4969,7 @@ export class InteractiveMode {
|
|
|
4887
4969
|
// Export to a temp file
|
|
4888
4970
|
const tmpFile = path.join(os.tmpdir(), "session.html");
|
|
4889
4971
|
try {
|
|
4890
|
-
await this.session.exportToHtml(tmpFile);
|
|
4972
|
+
await this.session.exportToHtml(tmpFile, { themeName: theme.name });
|
|
4891
4973
|
}
|
|
4892
4974
|
catch (error) {
|
|
4893
4975
|
this.showError(`Failed to export session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -5333,7 +5415,7 @@ export class InteractiveMode {
|
|
|
5333
5415
|
// Ignore, will be emitted as an event
|
|
5334
5416
|
}
|
|
5335
5417
|
}
|
|
5336
|
-
stop() {
|
|
5418
|
+
stop(fullscreenExitOutput = this.settingsManager.getFullscreenExitOutput()) {
|
|
5337
5419
|
this.disposeActiveSelector();
|
|
5338
5420
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
5339
5421
|
this.ui.terminal.setProgress(false);
|
|
@@ -5347,7 +5429,7 @@ export class InteractiveMode {
|
|
|
5347
5429
|
this.unsubscribe();
|
|
5348
5430
|
}
|
|
5349
5431
|
if (this.isInitialized) {
|
|
5350
|
-
this.stopInteractiveTui();
|
|
5432
|
+
this.stopInteractiveTui(fullscreenExitOutput);
|
|
5351
5433
|
this.isInitialized = false;
|
|
5352
5434
|
}
|
|
5353
5435
|
this.unregisterSignalHandlers();
|