@mariozechner/pi-coding-agent 0.47.0 → 0.48.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 +32 -1
- package/README.md +34 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +44 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +11 -4
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +21 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +5 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +18 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +8 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +43 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +9 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +21 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -3
- package/dist/core/tools/index.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 +52 -14
- package/dist/main.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 +2 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +2 -2
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +3 -3
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +5 -3
- package/dist/modes/interactive/components/session-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 +12 -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 +3 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +120 -78
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +23 -3
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +6 -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 +6 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +6 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +14 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/photon.d.ts +28 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +51 -0
- package/dist/utils/photon.js.map +1 -0
- package/docs/extensions.md +32 -4
- package/docs/rpc.md +2 -0
- package/docs/sdk.md +1 -1
- package/docs/tree.md +20 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -65,6 +65,7 @@ export class InteractiveMode {
|
|
|
65
65
|
keybindings;
|
|
66
66
|
version;
|
|
67
67
|
isInitialized = false;
|
|
68
|
+
hasRenderedInitialMessages = false;
|
|
68
69
|
onInputCallback;
|
|
69
70
|
loadingAnimation = undefined;
|
|
70
71
|
defaultWorkingMessage = "Working...";
|
|
@@ -136,7 +137,8 @@ export class InteractiveMode {
|
|
|
136
137
|
this.statusContainer = new Container();
|
|
137
138
|
this.widgetContainer = new Container();
|
|
138
139
|
this.keybindings = KeybindingsManager.create();
|
|
139
|
-
|
|
140
|
+
const editorPaddingX = this.settingsManager.getEditorPaddingX();
|
|
141
|
+
this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, { paddingX: editorPaddingX });
|
|
140
142
|
this.editor = this.defaultEditor;
|
|
141
143
|
this.editorContainer = new Container();
|
|
142
144
|
this.editorContainer.addChild(this.editor);
|
|
@@ -204,6 +206,7 @@ export class InteractiveMode {
|
|
|
204
206
|
const extensionCommands = (this.session.extensionRunner?.getRegisteredCommands() ?? []).map((cmd) => ({
|
|
205
207
|
name: cmd.name,
|
|
206
208
|
description: cmd.description ?? "(extension command)",
|
|
209
|
+
getArgumentCompletions: cmd.getArgumentCompletions,
|
|
207
210
|
}));
|
|
208
211
|
// Build skill commands from session.skills (if enabled)
|
|
209
212
|
this.skillCommands.clear();
|
|
@@ -230,53 +233,67 @@ export class InteractiveMode {
|
|
|
230
233
|
// Setup autocomplete with fd tool for file path completion
|
|
231
234
|
this.fdPath = await ensureTool("fd");
|
|
232
235
|
this.setupAutocomplete(this.fdPath);
|
|
233
|
-
// Add header with keybindings from config
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
this.
|
|
267
|
-
|
|
236
|
+
// Add header with keybindings from config (unless silenced)
|
|
237
|
+
if (!this.settingsManager.getQuietStartup()) {
|
|
238
|
+
const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
239
|
+
// Build startup instructions using keybinding hint helpers
|
|
240
|
+
const kb = this.keybindings;
|
|
241
|
+
const hint = (action, desc) => appKeyHint(kb, action, desc);
|
|
242
|
+
const instructions = [
|
|
243
|
+
hint("interrupt", "to interrupt"),
|
|
244
|
+
hint("clear", "to clear"),
|
|
245
|
+
rawKeyHint(`${appKey(kb, "clear")} twice`, "to exit"),
|
|
246
|
+
hint("exit", "to exit (empty)"),
|
|
247
|
+
hint("suspend", "to suspend"),
|
|
248
|
+
keyHint("deleteToLineEnd", "to delete to end"),
|
|
249
|
+
hint("cycleThinkingLevel", "to cycle thinking"),
|
|
250
|
+
rawKeyHint(`${appKey(kb, "cycleModelForward")}/${appKey(kb, "cycleModelBackward")}`, "to cycle models"),
|
|
251
|
+
hint("selectModel", "to select model"),
|
|
252
|
+
hint("expandTools", "to expand tools"),
|
|
253
|
+
hint("toggleThinking", "to toggle thinking"),
|
|
254
|
+
hint("externalEditor", "for external editor"),
|
|
255
|
+
rawKeyHint("/", "for commands"),
|
|
256
|
+
rawKeyHint("!", "to run bash"),
|
|
257
|
+
rawKeyHint("!!", "to run bash (no context)"),
|
|
258
|
+
hint("followUp", "to queue follow-up"),
|
|
259
|
+
hint("dequeue", "to edit all queued messages"),
|
|
260
|
+
hint("pasteImage", "to paste image"),
|
|
261
|
+
rawKeyHint("drop files", "to attach"),
|
|
262
|
+
].join("\n");
|
|
263
|
+
this.builtInHeader = new Text(`${logo}\n${instructions}`, 1, 0);
|
|
264
|
+
// Setup UI layout
|
|
265
|
+
this.ui.addChild(new Spacer(1));
|
|
266
|
+
this.ui.addChild(this.builtInHeader);
|
|
267
|
+
this.ui.addChild(new Spacer(1));
|
|
268
|
+
// Add changelog if provided
|
|
269
|
+
if (this.changelogMarkdown) {
|
|
270
|
+
this.ui.addChild(new DynamicBorder());
|
|
271
|
+
if (this.settingsManager.getCollapseChangelog()) {
|
|
272
|
+
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
273
|
+
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
274
|
+
const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
|
|
275
|
+
this.ui.addChild(new Text(condensedText, 1, 0));
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.ui.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
279
|
+
this.ui.addChild(new Spacer(1));
|
|
280
|
+
this.ui.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, getMarkdownTheme()));
|
|
281
|
+
this.ui.addChild(new Spacer(1));
|
|
282
|
+
}
|
|
283
|
+
this.ui.addChild(new DynamicBorder());
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// Minimal header when silenced
|
|
288
|
+
this.builtInHeader = new Text("", 0, 0);
|
|
289
|
+
if (this.changelogMarkdown) {
|
|
290
|
+
// Still show changelog notification even in silent mode
|
|
291
|
+
this.ui.addChild(new Spacer(1));
|
|
268
292
|
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
269
293
|
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
270
294
|
const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
|
|
271
295
|
this.ui.addChild(new Text(condensedText, 1, 0));
|
|
272
296
|
}
|
|
273
|
-
else {
|
|
274
|
-
this.ui.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
275
|
-
this.ui.addChild(new Spacer(1));
|
|
276
|
-
this.ui.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, getMarkdownTheme()));
|
|
277
|
-
this.ui.addChild(new Spacer(1));
|
|
278
|
-
}
|
|
279
|
-
this.ui.addChild(new DynamicBorder());
|
|
280
297
|
}
|
|
281
298
|
this.ui.addChild(this.chatContainer);
|
|
282
299
|
this.ui.addChild(this.pendingMessagesContainer);
|
|
@@ -421,33 +438,38 @@ export class InteractiveMode {
|
|
|
421
438
|
* Initialize the extension system with TUI-based UI context.
|
|
422
439
|
*/
|
|
423
440
|
async initExtensions() {
|
|
424
|
-
// Show
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
this.
|
|
441
|
+
// Show discovery info unless silenced
|
|
442
|
+
if (!this.settingsManager.getQuietStartup()) {
|
|
443
|
+
// Show loaded project context files
|
|
444
|
+
const contextFiles = loadProjectContextFiles();
|
|
445
|
+
if (contextFiles.length > 0) {
|
|
446
|
+
const contextList = contextFiles.map((f) => theme.fg("dim", ` ${f.path}`)).join("\n");
|
|
447
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", "Loaded context:\n") + contextList, 0, 0));
|
|
448
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
449
|
+
}
|
|
450
|
+
// Show loaded skills (already discovered by SDK)
|
|
451
|
+
const skills = this.session.skills;
|
|
452
|
+
if (skills.length > 0) {
|
|
453
|
+
const skillList = skills.map((s) => theme.fg("dim", ` ${s.filePath}`)).join("\n");
|
|
454
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", "Loaded skills:\n") + skillList, 0, 0));
|
|
455
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
456
|
+
}
|
|
457
|
+
// Show skill warnings if any
|
|
458
|
+
const skillWarnings = this.session.skillWarnings;
|
|
459
|
+
if (skillWarnings.length > 0) {
|
|
460
|
+
const warningList = skillWarnings
|
|
461
|
+
.map((w) => theme.fg("warning", ` ${w.skillPath}: ${w.message}`))
|
|
462
|
+
.join("\n");
|
|
463
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", "Skill warnings:\n") + warningList, 0, 0));
|
|
464
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
465
|
+
}
|
|
466
|
+
// Show loaded prompt templates
|
|
467
|
+
const templates = this.session.promptTemplates;
|
|
468
|
+
if (templates.length > 0) {
|
|
469
|
+
const templateList = templates.map((t) => theme.fg("dim", ` /${t.name} ${t.source}`)).join("\n");
|
|
470
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", "Loaded prompt templates:\n") + templateList, 0, 0));
|
|
471
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
472
|
+
}
|
|
451
473
|
}
|
|
452
474
|
const extensionRunner = this.session.extensionRunner;
|
|
453
475
|
if (!extensionRunner) {
|
|
@@ -463,7 +485,9 @@ export class InteractiveMode {
|
|
|
463
485
|
this.session
|
|
464
486
|
.sendCustomMessage(message, options)
|
|
465
487
|
.then(() => {
|
|
466
|
-
if
|
|
488
|
+
// Don't rebuild if initial render hasn't happened yet
|
|
489
|
+
// (renderInitialMessages will handle it)
|
|
490
|
+
if (!wasStreaming && message.display && this.hasRenderedInitialMessages) {
|
|
467
491
|
this.rebuildChatFromMessages();
|
|
468
492
|
}
|
|
469
493
|
})
|
|
@@ -547,7 +571,12 @@ export class InteractiveMode {
|
|
|
547
571
|
return { cancelled: false };
|
|
548
572
|
},
|
|
549
573
|
navigateTree: async (targetId, options) => {
|
|
550
|
-
const result = await this.session.navigateTree(targetId, {
|
|
574
|
+
const result = await this.session.navigateTree(targetId, {
|
|
575
|
+
summarize: options?.summarize,
|
|
576
|
+
customInstructions: options?.customInstructions,
|
|
577
|
+
replaceInstructions: options?.replaceInstructions,
|
|
578
|
+
label: options?.label,
|
|
579
|
+
});
|
|
551
580
|
if (result.cancelled) {
|
|
552
581
|
return { cancelled: true };
|
|
553
582
|
}
|
|
@@ -566,12 +595,14 @@ export class InteractiveMode {
|
|
|
566
595
|
});
|
|
567
596
|
// Set up extension-registered shortcuts
|
|
568
597
|
this.setupExtensionShortcuts(extensionRunner);
|
|
569
|
-
// Show loaded extensions
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
598
|
+
// Show loaded extensions (unless silenced)
|
|
599
|
+
if (!this.settingsManager.getQuietStartup()) {
|
|
600
|
+
const extensionPaths = extensionRunner.getExtensionPaths();
|
|
601
|
+
if (extensionPaths.length > 0) {
|
|
602
|
+
const extList = extensionPaths.map((p) => theme.fg("dim", ` ${p}`)).join("\n");
|
|
603
|
+
this.chatContainer.addChild(new Text(theme.fg("muted", "Loaded extensions:\n") + extList, 0, 0));
|
|
604
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
605
|
+
}
|
|
575
606
|
}
|
|
576
607
|
// Emit session_start event
|
|
577
608
|
await extensionRunner.emit({
|
|
@@ -1490,6 +1521,11 @@ export class InteractiveMode {
|
|
|
1490
1521
|
});
|
|
1491
1522
|
this.footer.invalidate();
|
|
1492
1523
|
}
|
|
1524
|
+
else if (event.errorMessage) {
|
|
1525
|
+
// Compaction failed (e.g., quota exceeded, API error)
|
|
1526
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
1527
|
+
this.chatContainer.addChild(new Text(theme.fg("error", event.errorMessage), 1, 0));
|
|
1528
|
+
}
|
|
1493
1529
|
void this.flushCompactionQueue({ willRetry: event.willRetry });
|
|
1494
1530
|
this.ui.requestRender();
|
|
1495
1531
|
break;
|
|
@@ -1677,6 +1713,7 @@ export class InteractiveMode {
|
|
|
1677
1713
|
this.ui.requestRender();
|
|
1678
1714
|
}
|
|
1679
1715
|
renderInitialMessages() {
|
|
1716
|
+
this.hasRenderedInitialMessages = true;
|
|
1680
1717
|
// Get aligned messages and entries from session context
|
|
1681
1718
|
const context = this.sessionManager.buildSessionContext();
|
|
1682
1719
|
this.renderSessionContext(context, {
|
|
@@ -2107,6 +2144,7 @@ export class InteractiveMode {
|
|
|
2107
2144
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
2108
2145
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
2109
2146
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
2147
|
+
editorPaddingX: this.settingsManager.getEditorPaddingX(),
|
|
2110
2148
|
}, {
|
|
2111
2149
|
onAutoCompactChange: (enabled) => {
|
|
2112
2150
|
this.session.setAutoCompactionEnabled(enabled);
|
|
@@ -2173,6 +2211,10 @@ export class InteractiveMode {
|
|
|
2173
2211
|
onDoubleEscapeActionChange: (action) => {
|
|
2174
2212
|
this.settingsManager.setDoubleEscapeAction(action);
|
|
2175
2213
|
},
|
|
2214
|
+
onEditorPaddingXChange: (padding) => {
|
|
2215
|
+
this.settingsManager.setEditorPaddingX(padding);
|
|
2216
|
+
this.defaultEditor.setPaddingX(padding);
|
|
2217
|
+
},
|
|
2176
2218
|
onCancel: () => {
|
|
2177
2219
|
done();
|
|
2178
2220
|
this.ui.requestRender();
|