@vaclav-synacek/pi-coding-agent-termux 0.45.7-1 → 0.46.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 +30 -0
- 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.map +1 -1
- package/dist/core/agent-session.js +2 -2
- 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/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/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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +38 -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.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +3 -3
- 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 +14 -8
- 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.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +5 -2
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +58 -95
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- 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/examples/extensions/plan-mode/README.md +1 -1
- package/examples/extensions/plan-mode/index.ts +2 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -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,7 +7,7 @@ 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
12
|
import { APP_NAME, getAuthPath, getDebugLogPath, isBunBinary, VERSION } from "../../config.js";
|
|
13
13
|
import { FooterDataProvider } from "../../core/footer-data-provider.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;
|
|
@@ -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
|
}, () => {
|
|
@@ -1508,7 +1469,7 @@ export class InteractiveMode {
|
|
|
1508
1469
|
// Show compacting indicator with reason
|
|
1509
1470
|
this.statusContainer.clear();
|
|
1510
1471
|
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... (
|
|
1472
|
+
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
1473
|
this.statusContainer.addChild(this.autoCompactionLoader);
|
|
1513
1474
|
this.ui.requestRender();
|
|
1514
1475
|
break;
|
|
@@ -1555,7 +1516,7 @@ export class InteractiveMode {
|
|
|
1555
1516
|
// Show retry indicator
|
|
1556
1517
|
this.statusContainer.clear();
|
|
1557
1518
|
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... (
|
|
1519
|
+
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
1520
|
this.statusContainer.addChild(this.retryLoader);
|
|
1560
1521
|
this.ui.requestRender();
|
|
1561
1522
|
break;
|
|
@@ -2503,7 +2464,7 @@ export class InteractiveMode {
|
|
|
2503
2464
|
this.session.abortBranchSummary();
|
|
2504
2465
|
};
|
|
2505
2466
|
this.chatContainer.addChild(new Spacer(1));
|
|
2506
|
-
summaryLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text),
|
|
2467
|
+
summaryLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), `Summarizing branch... (${appKey(this.keybindings, "interrupt")} to cancel)`);
|
|
2507
2468
|
this.statusContainer.addChild(summaryLoader);
|
|
2508
2469
|
this.ui.requestRender();
|
|
2509
2470
|
}
|
|
@@ -2868,7 +2829,10 @@ export class InteractiveMode {
|
|
|
2868
2829
|
const content = fs.readFileSync(skillPath, "utf-8");
|
|
2869
2830
|
// Strip YAML frontmatter if present
|
|
2870
2831
|
const body = content.replace(/^---\n[\s\S]*?\n---\n/, "").trim();
|
|
2871
|
-
const
|
|
2832
|
+
const skillDir = path.dirname(skillPath);
|
|
2833
|
+
const header = `Skill location: ${skillPath}\nReferences are relative to ${skillDir}.`;
|
|
2834
|
+
const skillMessage = `${header}\n\n${body}`;
|
|
2835
|
+
const message = args ? `${skillMessage}\n\n---\n\nUser: ${args}` : skillMessage;
|
|
2872
2836
|
await this.session.prompt(message);
|
|
2873
2837
|
}
|
|
2874
2838
|
catch (err) {
|
|
@@ -2893,30 +2857,28 @@ export class InteractiveMode {
|
|
|
2893
2857
|
this.ui.requestRender();
|
|
2894
2858
|
}
|
|
2895
2859
|
/**
|
|
2896
|
-
*
|
|
2860
|
+
* Capitalize keybinding for display (e.g., "ctrl+c" -> "Ctrl+C").
|
|
2897
2861
|
*/
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
.map((
|
|
2862
|
+
capitalizeKey(key) {
|
|
2863
|
+
return key
|
|
2864
|
+
.split("/")
|
|
2865
|
+
.map((k) => k
|
|
2902
2866
|
.split("+")
|
|
2903
2867
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
2904
2868
|
.join("+"))
|
|
2905
2869
|
.join("/");
|
|
2906
2870
|
}
|
|
2907
2871
|
/**
|
|
2908
|
-
* Get display string for an app keybinding action.
|
|
2872
|
+
* Get capitalized display string for an app keybinding action.
|
|
2909
2873
|
*/
|
|
2910
2874
|
getAppKeyDisplay(action) {
|
|
2911
|
-
|
|
2912
|
-
return this.formatKeyDisplay(display);
|
|
2875
|
+
return this.capitalizeKey(appKey(this.keybindings, action));
|
|
2913
2876
|
}
|
|
2914
2877
|
/**
|
|
2915
|
-
* Get display string for an editor keybinding action.
|
|
2878
|
+
* Get capitalized display string for an editor keybinding action.
|
|
2916
2879
|
*/
|
|
2917
2880
|
getEditorKeyDisplay(action) {
|
|
2918
|
-
|
|
2919
|
-
return this.formatKeyDisplay(keys);
|
|
2881
|
+
return this.capitalizeKey(editorKey(action));
|
|
2920
2882
|
}
|
|
2921
2883
|
handleHotkeysCommand() {
|
|
2922
2884
|
// Navigation keybindings
|
|
@@ -3146,7 +3108,8 @@ export class InteractiveMode {
|
|
|
3146
3108
|
};
|
|
3147
3109
|
// Show compacting status
|
|
3148
3110
|
this.chatContainer.addChild(new Spacer(1));
|
|
3149
|
-
const
|
|
3111
|
+
const cancelHint = `(${appKey(this.keybindings, "interrupt")} to cancel)`;
|
|
3112
|
+
const label = isAuto ? `Auto-compacting context... ${cancelHint}` : `Compacting context... ${cancelHint}`;
|
|
3150
3113
|
const compactingLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), label);
|
|
3151
3114
|
this.statusContainer.addChild(compactingLoader);
|
|
3152
3115
|
this.ui.requestRender();
|