@mariozechner/pi-coding-agent 0.45.7 → 0.47.0
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 +59 -0
- package/README.md +24 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +11 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +81 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +6 -5
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +17 -0
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +52 -23
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +0 -33
- package/dist/core/export-html/template.js +171 -18
- package/dist/core/export-html/tool-renderer.d.ts +35 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +57 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +41 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +24 -1
- 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 +1 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +4 -12
- package/dist/core/keybindings.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/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +4 -27
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +6 -37
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +19 -14
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +30 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +82 -10
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +16 -13
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +1 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +7 -0
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +13 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +70 -9
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -3
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +2 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +4 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +4 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -2
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +5 -5
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +3 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +15 -9
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +2 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +6 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +61 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +4 -3
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +21 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +146 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +7 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +35 -8
- package/dist/modes/interactive/components/session-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 +14 -8
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +7 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +143 -4
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +63 -126
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +12 -14
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts +2 -2
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +102 -122
- package/dist/utils/image-resize.js.map +1 -1
- package/docs/extensions.md +51 -0
- package/docs/rpc.md +15 -15
- package/docs/tui.md +26 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/overlay-test.ts +8 -3
- package/examples/extensions/plan-mode/README.md +1 -1
- package/examples/extensions/plan-mode/index.ts +2 -2
- package/examples/extensions/question.ts +1 -1
- package/examples/extensions/questionnaire.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -8
- package/examples/extensions/subagent/agents.ts +3 -32
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +6 -5
- package/dist/utils/vips.d.ts +0 -11
- package/dist/utils/vips.d.ts.map +0 -1
- package/dist/utils/vips.js +0 -35
- package/dist/utils/vips.js.map +0 -1
|
@@ -7,9 +7,9 @@ import * as fs from "node:fs";
|
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { getOAuthProviders, } from "@mariozechner/pi-ai";
|
|
10
|
-
import { CombinedAutocompleteProvider, Container, fuzzyFilter,
|
|
10
|
+
import { CombinedAutocompleteProvider, Container, fuzzyFilter, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, Text, TruncatedText, TUI, visibleWidth, } from "@mariozechner/pi-tui";
|
|
11
11
|
import { spawn, spawnSync } from "child_process";
|
|
12
|
-
import { APP_NAME, getAuthPath, getDebugLogPath, isBunBinary, VERSION } from "../../config.js";
|
|
12
|
+
import { APP_NAME, getAuthPath, getDebugLogPath, isBunBinary, isBunRuntime, VERSION } from "../../config.js";
|
|
13
13
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
14
14
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
15
15
|
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
@@ -33,6 +33,7 @@ import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
|
33
33
|
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
34
34
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
35
35
|
import { FooterComponent } from "./components/footer.js";
|
|
36
|
+
import { appKey, appKeyHint, editorKey, keyHint, rawKeyHint } from "./components/keybinding-hints.js";
|
|
36
37
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
37
38
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
38
39
|
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
@@ -66,7 +67,7 @@ export class InteractiveMode {
|
|
|
66
67
|
isInitialized = false;
|
|
67
68
|
onInputCallback;
|
|
68
69
|
loadingAnimation = undefined;
|
|
69
|
-
defaultWorkingMessage = "Working...
|
|
70
|
+
defaultWorkingMessage = "Working...";
|
|
70
71
|
lastSigintTime = 0;
|
|
71
72
|
lastEscapeTime = 0;
|
|
72
73
|
changelogMarkdown = undefined;
|
|
@@ -135,7 +136,7 @@ export class InteractiveMode {
|
|
|
135
136
|
this.statusContainer = new Container();
|
|
136
137
|
this.widgetContainer = new Container();
|
|
137
138
|
this.keybindings = KeybindingsManager.create();
|
|
138
|
-
this.defaultEditor = new CustomEditor(getEditorTheme(), this.keybindings);
|
|
139
|
+
this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings);
|
|
139
140
|
this.editor = this.defaultEditor;
|
|
140
141
|
this.editorContainer = new Container();
|
|
141
142
|
this.editorContainer.addChild(this.editor);
|
|
@@ -231,82 +232,30 @@ export class InteractiveMode {
|
|
|
231
232
|
this.setupAutocomplete(this.fdPath);
|
|
232
233
|
// Add header with keybindings from config
|
|
233
234
|
const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
234
|
-
//
|
|
235
|
-
const formatStartupKey = (keys) => {
|
|
236
|
-
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
237
|
-
return keyArray.join("/");
|
|
238
|
-
};
|
|
235
|
+
// Build startup instructions using keybinding hint helpers
|
|
239
236
|
const kb = this.keybindings;
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
"
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
"
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"\n" +
|
|
263
|
-
theme.fg("dim", exit) +
|
|
264
|
-
theme.fg("muted", " to exit (empty)") +
|
|
265
|
-
"\n" +
|
|
266
|
-
theme.fg("dim", suspend) +
|
|
267
|
-
theme.fg("muted", " to suspend") +
|
|
268
|
-
"\n" +
|
|
269
|
-
theme.fg("dim", deleteToLineEnd) +
|
|
270
|
-
theme.fg("muted", " to delete to end") +
|
|
271
|
-
"\n" +
|
|
272
|
-
theme.fg("dim", cycleThinkingLevel) +
|
|
273
|
-
theme.fg("muted", " to cycle thinking") +
|
|
274
|
-
"\n" +
|
|
275
|
-
theme.fg("dim", `${cycleModelForward}/${cycleModelBackward}`) +
|
|
276
|
-
theme.fg("muted", " to cycle models") +
|
|
277
|
-
"\n" +
|
|
278
|
-
theme.fg("dim", selectModel) +
|
|
279
|
-
theme.fg("muted", " to select model") +
|
|
280
|
-
"\n" +
|
|
281
|
-
theme.fg("dim", expandTools) +
|
|
282
|
-
theme.fg("muted", " to expand tools") +
|
|
283
|
-
"\n" +
|
|
284
|
-
theme.fg("dim", toggleThinking) +
|
|
285
|
-
theme.fg("muted", " to toggle thinking") +
|
|
286
|
-
"\n" +
|
|
287
|
-
theme.fg("dim", externalEditor) +
|
|
288
|
-
theme.fg("muted", " for external editor") +
|
|
289
|
-
"\n" +
|
|
290
|
-
theme.fg("dim", "/") +
|
|
291
|
-
theme.fg("muted", " for commands") +
|
|
292
|
-
"\n" +
|
|
293
|
-
theme.fg("dim", "!") +
|
|
294
|
-
theme.fg("muted", " to run bash") +
|
|
295
|
-
"\n" +
|
|
296
|
-
theme.fg("dim", "!!") +
|
|
297
|
-
theme.fg("muted", " to run bash (no context)") +
|
|
298
|
-
"\n" +
|
|
299
|
-
theme.fg("dim", followUp) +
|
|
300
|
-
theme.fg("muted", " to queue follow-up") +
|
|
301
|
-
"\n" +
|
|
302
|
-
theme.fg("dim", dequeue) +
|
|
303
|
-
theme.fg("muted", " to edit all queued messages") +
|
|
304
|
-
"\n" +
|
|
305
|
-
theme.fg("dim", "ctrl+v") +
|
|
306
|
-
theme.fg("muted", " to paste image") +
|
|
307
|
-
"\n" +
|
|
308
|
-
theme.fg("dim", "drop files") +
|
|
309
|
-
theme.fg("muted", " to attach");
|
|
237
|
+
const hint = (action, desc) => appKeyHint(kb, action, desc);
|
|
238
|
+
const instructions = [
|
|
239
|
+
hint("interrupt", "to interrupt"),
|
|
240
|
+
hint("clear", "to clear"),
|
|
241
|
+
rawKeyHint(`${appKey(kb, "clear")} twice`, "to exit"),
|
|
242
|
+
hint("exit", "to exit (empty)"),
|
|
243
|
+
hint("suspend", "to suspend"),
|
|
244
|
+
keyHint("deleteToLineEnd", "to delete to end"),
|
|
245
|
+
hint("cycleThinkingLevel", "to cycle thinking"),
|
|
246
|
+
rawKeyHint(`${appKey(kb, "cycleModelForward")}/${appKey(kb, "cycleModelBackward")}`, "to cycle models"),
|
|
247
|
+
hint("selectModel", "to select model"),
|
|
248
|
+
hint("expandTools", "to expand tools"),
|
|
249
|
+
hint("toggleThinking", "to toggle thinking"),
|
|
250
|
+
hint("externalEditor", "for external editor"),
|
|
251
|
+
rawKeyHint("/", "for commands"),
|
|
252
|
+
rawKeyHint("!", "to run bash"),
|
|
253
|
+
rawKeyHint("!!", "to run bash (no context)"),
|
|
254
|
+
hint("followUp", "to queue follow-up"),
|
|
255
|
+
hint("dequeue", "to edit all queued messages"),
|
|
256
|
+
hint("pasteImage", "to paste image"),
|
|
257
|
+
rawKeyHint("drop files", "to attach"),
|
|
258
|
+
].join("\n");
|
|
310
259
|
this.builtInHeader = new Text(`${logo}\n${instructions}`, 1, 0);
|
|
311
260
|
// Setup UI layout
|
|
312
261
|
this.ui.addChild(new Spacer(1));
|
|
@@ -493,6 +442,13 @@ export class InteractiveMode {
|
|
|
493
442
|
this.chatContainer.addChild(new Text(theme.fg("warning", "Skill warnings:\n") + warningList, 0, 0));
|
|
494
443
|
this.chatContainer.addChild(new Spacer(1));
|
|
495
444
|
}
|
|
445
|
+
// Show loaded prompt templates
|
|
446
|
+
const templates = this.session.promptTemplates;
|
|
447
|
+
if (templates.length > 0) {
|
|
448
|
+
const templateList = templates.map((t) => theme.fg("dim", ` /${t.name} ${t.source}`)).join("\n");
|
|
449
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", "Loaded prompt templates:\n") + templateList, 0, 0));
|
|
450
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
451
|
+
}
|
|
496
452
|
const extensionRunner = this.session.extensionRunner;
|
|
497
453
|
if (!extensionRunner) {
|
|
498
454
|
return; // No extensions loaded
|
|
@@ -793,7 +749,12 @@ export class InteractiveMode {
|
|
|
793
749
|
setStatus: (key, text) => this.setExtensionStatus(key, text),
|
|
794
750
|
setWorkingMessage: (message) => {
|
|
795
751
|
if (this.loadingAnimation) {
|
|
796
|
-
|
|
752
|
+
if (message) {
|
|
753
|
+
this.loadingAnimation.setMessage(message);
|
|
754
|
+
}
|
|
755
|
+
else {
|
|
756
|
+
this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${appKey(this.keybindings, "interrupt")} to interrupt)`);
|
|
757
|
+
}
|
|
797
758
|
}
|
|
798
759
|
},
|
|
799
760
|
setWidget: (key, content) => this.setExtensionWidget(key, content),
|
|
@@ -916,7 +877,7 @@ export class InteractiveMode {
|
|
|
916
877
|
*/
|
|
917
878
|
showExtensionEditor(title, prefill) {
|
|
918
879
|
return new Promise((resolve) => {
|
|
919
|
-
this.extensionEditor = new ExtensionEditorComponent(this.ui, title, prefill, (value) => {
|
|
880
|
+
this.extensionEditor = new ExtensionEditorComponent(this.ui, this.keybindings, title, prefill, (value) => {
|
|
920
881
|
this.hideExtensionEditor();
|
|
921
882
|
resolve(value);
|
|
922
883
|
}, () => {
|
|
@@ -1280,19 +1241,6 @@ export class InteractiveMode {
|
|
|
1280
1241
|
await this.shutdown();
|
|
1281
1242
|
return;
|
|
1282
1243
|
}
|
|
1283
|
-
// Handle skill commands (/skill:name [args])
|
|
1284
|
-
if (text.startsWith("/skill:")) {
|
|
1285
|
-
const spaceIndex = text.indexOf(" ");
|
|
1286
|
-
const commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
1287
|
-
const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
|
|
1288
|
-
const skillPath = this.skillCommands.get(commandName);
|
|
1289
|
-
if (skillPath) {
|
|
1290
|
-
this.editor.addToHistory?.(text);
|
|
1291
|
-
this.editor.setText("");
|
|
1292
|
-
await this.handleSkillCommand(skillPath, args);
|
|
1293
|
-
return;
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
1244
|
// Handle bash command (! for normal, !! for excluded from context)
|
|
1297
1245
|
if (text.startsWith("!")) {
|
|
1298
1246
|
const isExcluded = text.startsWith("!!");
|
|
@@ -1508,7 +1456,7 @@ export class InteractiveMode {
|
|
|
1508
1456
|
// Show compacting indicator with reason
|
|
1509
1457
|
this.statusContainer.clear();
|
|
1510
1458
|
const reasonText = event.reason === "overflow" ? "Context overflow detected, " : "";
|
|
1511
|
-
this.autoCompactionLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), `${reasonText}Auto-compacting... (
|
|
1459
|
+
this.autoCompactionLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), `${reasonText}Auto-compacting... (${appKey(this.keybindings, "interrupt")} to cancel)`);
|
|
1512
1460
|
this.statusContainer.addChild(this.autoCompactionLoader);
|
|
1513
1461
|
this.ui.requestRender();
|
|
1514
1462
|
break;
|
|
@@ -1555,7 +1503,7 @@ export class InteractiveMode {
|
|
|
1555
1503
|
// Show retry indicator
|
|
1556
1504
|
this.statusContainer.clear();
|
|
1557
1505
|
const delaySeconds = Math.round(event.delayMs / 1000);
|
|
1558
|
-
this.retryLoader = new Loader(this.ui, (spinner) => theme.fg("warning", spinner), (text) => theme.fg("muted", text), `Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s... (
|
|
1506
|
+
this.retryLoader = new Loader(this.ui, (spinner) => theme.fg("warning", spinner), (text) => theme.fg("muted", text), `Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s... (${appKey(this.keybindings, "interrupt")} to cancel)`);
|
|
1559
1507
|
this.statusContainer.addChild(this.retryLoader);
|
|
1560
1508
|
this.ui.requestRender();
|
|
1561
1509
|
break;
|
|
@@ -1789,6 +1737,9 @@ export class InteractiveMode {
|
|
|
1789
1737
|
type: "session_shutdown",
|
|
1790
1738
|
});
|
|
1791
1739
|
}
|
|
1740
|
+
// Wait for any pending renders to complete
|
|
1741
|
+
// requestRender() uses process.nextTick(), so we wait one tick
|
|
1742
|
+
await new Promise((resolve) => process.nextTick(resolve));
|
|
1792
1743
|
this.stop();
|
|
1793
1744
|
process.exit(0);
|
|
1794
1745
|
}
|
|
@@ -1971,11 +1922,10 @@ export class InteractiveMode {
|
|
|
1971
1922
|
this.ui.requestRender();
|
|
1972
1923
|
}
|
|
1973
1924
|
showNewVersionNotification(newVersion) {
|
|
1974
|
-
const
|
|
1975
|
-
? theme.fg("
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
theme.fg("accent", "npm install -g @mariozechner/pi-coding-agent");
|
|
1925
|
+
const action = isBunBinary
|
|
1926
|
+
? `Download from: ${theme.fg("accent", "https://github.com/badlogic/pi-mono/releases/latest")}`
|
|
1927
|
+
: `Run: ${theme.fg("accent", `${isBunRuntime ? "bun" : "npm"} install -g @mariozechner/pi-coding-agent`)}`;
|
|
1928
|
+
const updateInstruction = theme.fg("muted", `New version ${newVersion} is available. `) + action;
|
|
1979
1929
|
this.chatContainer.addChild(new Spacer(1));
|
|
1980
1930
|
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
1981
1931
|
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", "Update Available"))}\n${updateInstruction}`, 1, 0));
|
|
@@ -2503,7 +2453,7 @@ export class InteractiveMode {
|
|
|
2503
2453
|
this.session.abortBranchSummary();
|
|
2504
2454
|
};
|
|
2505
2455
|
this.chatContainer.addChild(new Spacer(1));
|
|
2506
|
-
summaryLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text),
|
|
2456
|
+
summaryLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), `Summarizing branch... (${appKey(this.keybindings, "interrupt")} to cancel)`);
|
|
2507
2457
|
this.statusContainer.addChild(summaryLoader);
|
|
2508
2458
|
this.ui.requestRender();
|
|
2509
2459
|
}
|
|
@@ -2863,18 +2813,6 @@ export class InteractiveMode {
|
|
|
2863
2813
|
this.chatContainer.addChild(new Text(info, 1, 0));
|
|
2864
2814
|
this.ui.requestRender();
|
|
2865
2815
|
}
|
|
2866
|
-
async handleSkillCommand(skillPath, args) {
|
|
2867
|
-
try {
|
|
2868
|
-
const content = fs.readFileSync(skillPath, "utf-8");
|
|
2869
|
-
// Strip YAML frontmatter if present
|
|
2870
|
-
const body = content.replace(/^---\n[\s\S]*?\n---\n/, "").trim();
|
|
2871
|
-
const message = args ? `${body}\n\n---\n\nUser: ${args}` : body;
|
|
2872
|
-
await this.session.prompt(message);
|
|
2873
|
-
}
|
|
2874
|
-
catch (err) {
|
|
2875
|
-
this.showError(`Failed to load skill: ${err instanceof Error ? err.message : String(err)}`);
|
|
2876
|
-
}
|
|
2877
|
-
}
|
|
2878
2816
|
handleChangelogCommand() {
|
|
2879
2817
|
const changelogPath = getChangelogPath();
|
|
2880
2818
|
const allEntries = parseChangelog(changelogPath);
|
|
@@ -2893,30 +2831,28 @@ export class InteractiveMode {
|
|
|
2893
2831
|
this.ui.requestRender();
|
|
2894
2832
|
}
|
|
2895
2833
|
/**
|
|
2896
|
-
*
|
|
2834
|
+
* Capitalize keybinding for display (e.g., "ctrl+c" -> "Ctrl+C").
|
|
2897
2835
|
*/
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
.map((
|
|
2836
|
+
capitalizeKey(key) {
|
|
2837
|
+
return key
|
|
2838
|
+
.split("/")
|
|
2839
|
+
.map((k) => k
|
|
2902
2840
|
.split("+")
|
|
2903
2841
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
2904
2842
|
.join("+"))
|
|
2905
2843
|
.join("/");
|
|
2906
2844
|
}
|
|
2907
2845
|
/**
|
|
2908
|
-
* Get display string for an app keybinding action.
|
|
2846
|
+
* Get capitalized display string for an app keybinding action.
|
|
2909
2847
|
*/
|
|
2910
2848
|
getAppKeyDisplay(action) {
|
|
2911
|
-
|
|
2912
|
-
return this.formatKeyDisplay(display);
|
|
2849
|
+
return this.capitalizeKey(appKey(this.keybindings, action));
|
|
2913
2850
|
}
|
|
2914
2851
|
/**
|
|
2915
|
-
* Get display string for an editor keybinding action.
|
|
2852
|
+
* Get capitalized display string for an editor keybinding action.
|
|
2916
2853
|
*/
|
|
2917
2854
|
getEditorKeyDisplay(action) {
|
|
2918
|
-
|
|
2919
|
-
return this.formatKeyDisplay(keys);
|
|
2855
|
+
return this.capitalizeKey(editorKey(action));
|
|
2920
2856
|
}
|
|
2921
2857
|
handleHotkeysCommand() {
|
|
2922
2858
|
// Navigation keybindings
|
|
@@ -3146,7 +3082,8 @@ export class InteractiveMode {
|
|
|
3146
3082
|
};
|
|
3147
3083
|
// Show compacting status
|
|
3148
3084
|
this.chatContainer.addChild(new Spacer(1));
|
|
3149
|
-
const
|
|
3085
|
+
const cancelHint = `(${appKey(this.keybindings, "interrupt")} to cancel)`;
|
|
3086
|
+
const label = isAuto ? `Auto-compacting context... ${cancelHint}` : `Compacting context... ${cancelHint}`;
|
|
3150
3087
|
const compactingLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), label);
|
|
3151
3088
|
this.statusContainer.addChild(compactingLoader);
|
|
3152
3089
|
this.ui.requestRender();
|