@earendil-works/pi-coding-agent 0.79.6 → 0.79.8
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 +50 -0
- package/README.md +11 -10
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +37 -36
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +1 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +3 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +2 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +1 -2
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -2
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +5 -5
- package/dist/modes/interactive/components/config-selector.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/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +4 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +175 -15
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +44 -4
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +24 -56
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts +7 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -0
- package/dist/modes/interactive/model-search.js +6 -0
- package/dist/modes/interactive/model-search.js.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +30 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +113 -0
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +2 -1
- package/dist/modes/interactive/theme/theme.d.ts +5 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +34 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +42 -12
- package/dist/package-manager-cli.js.map +1 -1
- package/docs/extensions.md +14 -0
- package/docs/packages.md +5 -4
- package/docs/rpc.md +4 -0
- package/docs/sdk.md +2 -1
- package/docs/themes.md +1 -1
- package/docs/tui.md +1 -1
- 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/preset.ts +10 -4
- package/examples/extensions/provider-payload.ts +5 -5
- package/examples/extensions/sandbox/index.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/agents.ts +2 -2
- package/examples/extensions/subagent/index.ts +9 -3
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +60 -39
- package/package.json +6 -6
|
@@ -10,7 +10,7 @@ import { getProviders, } from "@earendil-works/pi-ai";
|
|
|
10
10
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import { spawn, spawnSync } from "child_process";
|
|
13
|
-
import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
13
|
+
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
14
14
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
15
15
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
16
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
@@ -63,7 +63,9 @@ import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
|
63
63
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
64
64
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
65
65
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
66
|
-
import {
|
|
66
|
+
import { getModelSearchText } from "./model-search.js";
|
|
67
|
+
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
68
|
+
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
67
69
|
function isExpandable(obj) {
|
|
68
70
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
69
71
|
}
|
|
@@ -216,6 +218,7 @@ export class InteractiveMode {
|
|
|
216
218
|
customHeader = undefined;
|
|
217
219
|
options;
|
|
218
220
|
autoTrustOnReloadCwd;
|
|
221
|
+
themeController;
|
|
219
222
|
// Convenience accessors
|
|
220
223
|
get session() {
|
|
221
224
|
return this.runtimeHost.session;
|
|
@@ -266,23 +269,7 @@ export class InteractiveMode {
|
|
|
266
269
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
267
270
|
// Register themes from resource loader and initialize
|
|
268
271
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
async detectThemeIfUnset() {
|
|
272
|
-
if (this.settingsManager.getTheme()) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });
|
|
276
|
-
const result = setTheme(detection.theme, true);
|
|
277
|
-
if (!result.success) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
if (detection.confidence === "high") {
|
|
281
|
-
this.settingsManager.setTheme(detection.theme);
|
|
282
|
-
await this.settingsManager.flush();
|
|
283
|
-
}
|
|
284
|
-
this.updateEditorBorderColor();
|
|
285
|
-
this.ui.requestRender();
|
|
272
|
+
this.themeController = new InteractiveThemeController(this.ui, this.settingsManager, (message) => this.showError(message), () => this.updateEditorBorderColor());
|
|
286
273
|
}
|
|
287
274
|
getAutocompleteSourceTag(sourceInfo) {
|
|
288
275
|
if (!sourceInfo) {
|
|
@@ -342,10 +329,11 @@ export class InteractiveMode {
|
|
|
342
329
|
const items = models.map((m) => ({
|
|
343
330
|
id: m.id,
|
|
344
331
|
provider: m.provider,
|
|
332
|
+
name: m.name,
|
|
345
333
|
label: `${m.provider}/${m.id}`,
|
|
346
334
|
}));
|
|
347
|
-
// Fuzzy filter by model ID + provider
|
|
348
|
-
const filtered = fuzzyFilter(items, prefix,
|
|
335
|
+
// Fuzzy filter by model ID + provider in either order.
|
|
336
|
+
const filtered = fuzzyFilter(items, prefix, getModelSearchText);
|
|
349
337
|
if (filtered.length === 0)
|
|
350
338
|
return null;
|
|
351
339
|
return filtered.map((item) => ({
|
|
@@ -467,7 +455,7 @@ export class InteractiveMode {
|
|
|
467
455
|
// Start the UI before initializing extensions so session_start handlers can use interactive dialogs
|
|
468
456
|
this.ui.start();
|
|
469
457
|
this.isInitialized = true;
|
|
470
|
-
await this.
|
|
458
|
+
await this.themeController.applyFromSettings();
|
|
471
459
|
// Add header with keybindings from config (unless silenced)
|
|
472
460
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
473
461
|
const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
@@ -1636,16 +1624,13 @@ export class InteractiveMode {
|
|
|
1636
1624
|
getTheme: (name) => getThemeByName(name),
|
|
1637
1625
|
setTheme: (themeOrName) => {
|
|
1638
1626
|
if (themeOrName instanceof Theme) {
|
|
1639
|
-
setThemeInstance(themeOrName);
|
|
1640
|
-
this.ui.requestRender();
|
|
1641
|
-
return { success: true };
|
|
1627
|
+
return this.themeController.setThemeInstance(themeOrName);
|
|
1642
1628
|
}
|
|
1643
|
-
const result =
|
|
1629
|
+
const result = this.themeController.setThemeName(themeOrName);
|
|
1644
1630
|
if (result.success) {
|
|
1645
1631
|
if (this.settingsManager.getTheme() !== themeOrName) {
|
|
1646
1632
|
this.settingsManager.setTheme(themeOrName);
|
|
1647
1633
|
}
|
|
1648
|
-
this.ui.requestRender();
|
|
1649
1634
|
}
|
|
1650
1635
|
return result;
|
|
1651
1636
|
},
|
|
@@ -2691,7 +2676,7 @@ export class InteractiveMode {
|
|
|
2691
2676
|
if (this.chatContainer.children.length > 0) {
|
|
2692
2677
|
this.chatContainer.addChild(new Spacer(1));
|
|
2693
2678
|
}
|
|
2694
|
-
this.chatContainer.addChild(new Text(theme.fg("warning",
|
|
2679
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `This project is not trusted. Project ${CONFIG_DIR_NAME} resources and packages are ignored. Use /trust to save a trust decision, then restart pi.`), 1, 0));
|
|
2695
2680
|
}
|
|
2696
2681
|
async getUserInput() {
|
|
2697
2682
|
const queuedInput = this.pendingUserInputs.shift();
|
|
@@ -2749,6 +2734,7 @@ export class InteractiveMode {
|
|
|
2749
2734
|
// which the stdout/stderr error handler turns into emergencyTerminalExit;
|
|
2750
2735
|
// the render loop is already idle, so this cannot hot-spin (see #4144).
|
|
2751
2736
|
await this.runtimeHost.dispose();
|
|
2737
|
+
this.themeController.disableAutoSync();
|
|
2752
2738
|
await this.ui.terminal.drainInput(1000);
|
|
2753
2739
|
this.stop();
|
|
2754
2740
|
process.exit(0);
|
|
@@ -2758,6 +2744,7 @@ export class InteractiveMode {
|
|
|
2758
2744
|
// the final frame while the process is exiting.
|
|
2759
2745
|
// Drain any in-flight Kitty key release events before stopping.
|
|
2760
2746
|
// This prevents escape sequences from leaking to the parent shell over slow SSH.
|
|
2747
|
+
this.themeController.disableAutoSync();
|
|
2761
2748
|
await this.ui.terminal.drainInput(1000);
|
|
2762
2749
|
this.stop();
|
|
2763
2750
|
await this.runtimeHost.dispose();
|
|
@@ -3057,7 +3044,6 @@ export class InteractiveMode {
|
|
|
3057
3044
|
showError(errorMessage) {
|
|
3058
3045
|
this.chatContainer.addChild(new Spacer(1));
|
|
3059
3046
|
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), 1, 0));
|
|
3060
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
3061
3047
|
this.ui.requestRender();
|
|
3062
3048
|
}
|
|
3063
3049
|
showWarning(warningMessage) {
|
|
@@ -3089,7 +3075,7 @@ export class InteractiveMode {
|
|
|
3089
3075
|
this.ui.requestRender();
|
|
3090
3076
|
}
|
|
3091
3077
|
showPackageUpdateNotification(packages) {
|
|
3092
|
-
const action = theme.fg("accent", `${APP_NAME} update`);
|
|
3078
|
+
const action = theme.fg("accent", `${APP_NAME} update --extensions`);
|
|
3093
3079
|
const updateInstruction = theme.fg("muted", "Package updates are available. Run ") + action;
|
|
3094
3080
|
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
|
3095
3081
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -3296,7 +3282,8 @@ export class InteractiveMode {
|
|
|
3296
3282
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3297
3283
|
thinkingLevel: this.session.thinkingLevel,
|
|
3298
3284
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
3299
|
-
currentTheme: this.settingsManager.
|
|
3285
|
+
currentTheme: this.settingsManager.getThemeSetting() || "dark",
|
|
3286
|
+
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3300
3287
|
availableThemes: getAvailableThemes(),
|
|
3301
3288
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
3302
3289
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
@@ -3362,21 +3349,11 @@ export class InteractiveMode {
|
|
|
3362
3349
|
this.footer.invalidate();
|
|
3363
3350
|
this.updateEditorBorderColor();
|
|
3364
3351
|
},
|
|
3365
|
-
onThemeChange: (
|
|
3366
|
-
|
|
3367
|
-
this.
|
|
3368
|
-
this.ui.invalidate();
|
|
3369
|
-
if (!result.success) {
|
|
3370
|
-
this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to dark theme.`);
|
|
3371
|
-
}
|
|
3372
|
-
},
|
|
3373
|
-
onThemePreview: (themeName) => {
|
|
3374
|
-
const result = setTheme(themeName, true);
|
|
3375
|
-
if (result.success) {
|
|
3376
|
-
this.ui.invalidate();
|
|
3377
|
-
this.ui.requestRender();
|
|
3378
|
-
}
|
|
3352
|
+
onThemeChange: (themeSetting) => {
|
|
3353
|
+
this.settingsManager.setTheme(themeSetting);
|
|
3354
|
+
void this.themeController.applyFromSettings();
|
|
3379
3355
|
},
|
|
3356
|
+
onThemePreview: (themeName) => this.themeController.preview(themeName),
|
|
3380
3357
|
onHideThinkingBlockChange: (hidden) => {
|
|
3381
3358
|
this.hideThinkingBlock = hidden;
|
|
3382
3359
|
this.settingsManager.setHideThinkingBlock(hidden);
|
|
@@ -4231,11 +4208,7 @@ export class InteractiveMode {
|
|
|
4231
4208
|
}
|
|
4232
4209
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
4233
4210
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
4234
|
-
|
|
4235
|
-
const themeResult = themeName ? setTheme(themeName, true) : { success: true };
|
|
4236
|
-
if (!themeResult.success) {
|
|
4237
|
-
this.showError(`Failed to load theme "${themeName}": ${themeResult.error}\nFell back to dark theme.`);
|
|
4238
|
-
}
|
|
4211
|
+
await this.themeController.applyFromSettings();
|
|
4239
4212
|
const editorPaddingX = this.settingsManager.getEditorPaddingX();
|
|
4240
4213
|
const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
|
|
4241
4214
|
this.defaultEditor.setPaddingX(editorPaddingX);
|
|
@@ -4782,12 +4755,6 @@ export class InteractiveMode {
|
|
|
4782
4755
|
this.ui.requestRender();
|
|
4783
4756
|
}
|
|
4784
4757
|
async handleCompactCommand(customInstructions) {
|
|
4785
|
-
const entries = this.sessionManager.getEntries();
|
|
4786
|
-
const messageCount = entries.filter((e) => e.type === "message").length;
|
|
4787
|
-
if (messageCount < 2) {
|
|
4788
|
-
this.showWarning("Nothing to compact (no messages yet)");
|
|
4789
|
-
return;
|
|
4790
|
-
}
|
|
4791
4758
|
if (this.loadingAnimation) {
|
|
4792
4759
|
this.loadingAnimation.stop();
|
|
4793
4760
|
this.loadingAnimation = undefined;
|
|
@@ -4808,6 +4775,7 @@ export class InteractiveMode {
|
|
|
4808
4775
|
this.loadingAnimation.stop();
|
|
4809
4776
|
this.loadingAnimation = undefined;
|
|
4810
4777
|
}
|
|
4778
|
+
this.themeController.disableAutoSync();
|
|
4811
4779
|
this.clearExtensionTerminalInputListeners();
|
|
4812
4780
|
this.footer.dispose();
|
|
4813
4781
|
this.footerDataProvider.dispose();
|