@mariozechner/pi-coding-agent 0.31.0 → 0.32.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 +51 -0
- package/README.md +56 -5
- package/dist/cli/file-processor.d.ts +5 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +28 -8
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/core/agent-session.d.ts +41 -16
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +90 -41
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +6 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +16 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/custom-tools/types.d.ts +1 -1
- package/dist/core/custom-tools/types.d.ts.map +1 -1
- package/dist/core/custom-tools/types.js.map +1 -1
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +1 -0
- package/dist/core/hooks/index.js.map +1 -1
- package/dist/core/hooks/loader.d.ts +4 -1
- package/dist/core/hooks/loader.d.ts.map +1 -1
- package/dist/core/hooks/loader.js +2 -2
- package/dist/core/hooks/loader.js.map +1 -1
- package/dist/core/hooks/runner.d.ts +2 -2
- package/dist/core/hooks/runner.d.ts.map +1 -1
- package/dist/core/hooks/runner.js +3 -3
- package/dist/core/hooks/runner.js.map +1 -1
- package/dist/core/hooks/types.d.ts +10 -4
- package/dist/core/hooks/types.d.ts.map +1 -1
- package/dist/core/hooks/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +85 -49
- package/dist/core/model-registry.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/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +9 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +17 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +41 -6
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/index.d.ts +9 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +6 -6
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/read.d.ts +5 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +22 -5
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -5
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +7 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/hook-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-editor.js +3 -3
- package/dist/modes/interactive/components/hook-editor.js.map +1 -1
- package/dist/modes/interactive/components/hook-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-input.js +3 -3
- package/dist/modes/interactive/components/hook-input.js.map +1 -1
- package/dist/modes/interactive/components/hook-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-selector.js +3 -3
- package/dist/modes/interactive/components/hook-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 +8 -3
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -3
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +37 -6
- package/dist/modes/interactive/components/settings-selector.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 +66 -19
- 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 +3 -3
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +12 -4
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +18 -6
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +21 -12
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +25 -6
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/image-resize.d.ts +29 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +111 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/docs/hooks.md +16 -9
- package/examples/README.md +6 -0
- package/examples/custom-tools/README.md +2 -0
- package/examples/hooks/README.md +1 -0
- package/examples/hooks/file-trigger.ts +1 -1
- package/examples/hooks/todo/index.ts +134 -0
- package/package.json +6 -5
- package/dist/modes/interactive/components/queue-mode-selector.d.ts +0 -10
- package/dist/modes/interactive/components/queue-mode-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/queue-mode-selector.js +0 -42
- package/dist/modes/interactive/components/queue-mode-selector.js.map +0 -1
|
@@ -194,6 +194,9 @@ export class InteractiveMode {
|
|
|
194
194
|
theme.fg("dim", "!") +
|
|
195
195
|
theme.fg("muted", " to run bash") +
|
|
196
196
|
"\n" +
|
|
197
|
+
theme.fg("dim", "alt+enter") +
|
|
198
|
+
theme.fg("muted", " to queue follow-up") +
|
|
199
|
+
"\n" +
|
|
197
200
|
theme.fg("dim", "drop files") +
|
|
198
201
|
theme.fg("muted", " to attach");
|
|
199
202
|
const header = new Text(`${logo}\n${instructions}`, 1, 0);
|
|
@@ -230,6 +233,9 @@ export class InteractiveMode {
|
|
|
230
233
|
// Start the UI
|
|
231
234
|
this.ui.start();
|
|
232
235
|
this.isInitialized = true;
|
|
236
|
+
// Set terminal title
|
|
237
|
+
const cwdBasename = path.basename(process.cwd());
|
|
238
|
+
this.ui.terminal.setTitle(`pi - ${cwdBasename}`);
|
|
233
239
|
// Initialize hooks with TUI-based UI context
|
|
234
240
|
await this.initHooksAndCustomTools();
|
|
235
241
|
// Subscribe to agent events
|
|
@@ -312,10 +318,10 @@ export class InteractiveMode {
|
|
|
312
318
|
}
|
|
313
319
|
hookRunner.initialize({
|
|
314
320
|
getModel: () => this.session.model,
|
|
315
|
-
sendMessageHandler: (message,
|
|
321
|
+
sendMessageHandler: (message, options) => {
|
|
316
322
|
const wasStreaming = this.session.isStreaming;
|
|
317
323
|
this.session
|
|
318
|
-
.sendHookMessage(message,
|
|
324
|
+
.sendHookMessage(message, options)
|
|
319
325
|
.then(() => {
|
|
320
326
|
// For non-streaming cases with display=true, update UI
|
|
321
327
|
// (streaming cases update via message_end event)
|
|
@@ -388,7 +394,7 @@ export class InteractiveMode {
|
|
|
388
394
|
abort: () => {
|
|
389
395
|
this.session.abort();
|
|
390
396
|
},
|
|
391
|
-
|
|
397
|
+
hasPendingMessages: () => this.session.pendingMessageCount > 0,
|
|
392
398
|
uiContext,
|
|
393
399
|
hasUI: true,
|
|
394
400
|
});
|
|
@@ -420,7 +426,7 @@ export class InteractiveMode {
|
|
|
420
426
|
modelRegistry: this.session.modelRegistry,
|
|
421
427
|
model: this.session.model,
|
|
422
428
|
isIdle: () => !this.session.isStreaming,
|
|
423
|
-
|
|
429
|
+
hasPendingMessages: () => this.session.pendingMessageCount > 0,
|
|
424
430
|
abort: () => {
|
|
425
431
|
this.session.abort();
|
|
426
432
|
},
|
|
@@ -596,8 +602,9 @@ export class InteractiveMode {
|
|
|
596
602
|
this.editor.onEscape = () => {
|
|
597
603
|
if (this.loadingAnimation) {
|
|
598
604
|
// Abort and restore queued messages to editor
|
|
599
|
-
const
|
|
600
|
-
const
|
|
605
|
+
const { steering, followUp } = this.session.clearQueue();
|
|
606
|
+
const allQueued = [...steering, ...followUp];
|
|
607
|
+
const queuedText = allQueued.join("\n\n");
|
|
601
608
|
const currentText = this.editor.getText();
|
|
602
609
|
const combinedText = [queuedText, currentText].filter((t) => t.trim()).join("\n\n");
|
|
603
610
|
this.editor.setText(combinedText);
|
|
@@ -613,10 +620,15 @@ export class InteractiveMode {
|
|
|
613
620
|
this.updateEditorBorderColor();
|
|
614
621
|
}
|
|
615
622
|
else if (!this.editor.getText().trim()) {
|
|
616
|
-
// Double-escape with empty editor triggers /branch
|
|
623
|
+
// Double-escape with empty editor triggers /tree or /branch based on setting
|
|
617
624
|
const now = Date.now();
|
|
618
625
|
if (now - this.lastEscapeTime < 500) {
|
|
619
|
-
this.
|
|
626
|
+
if (this.settingsManager.getDoubleEscapeAction() === "tree") {
|
|
627
|
+
this.showTreeSelector();
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
this.showUserMessageSelector();
|
|
631
|
+
}
|
|
620
632
|
this.lastEscapeTime = 0;
|
|
621
633
|
}
|
|
622
634
|
else {
|
|
@@ -636,6 +648,7 @@ export class InteractiveMode {
|
|
|
636
648
|
this.editor.onCtrlO = () => this.toggleToolOutputExpansion();
|
|
637
649
|
this.editor.onCtrlT = () => this.toggleThinkingBlockVisibility();
|
|
638
650
|
this.editor.onCtrlG = () => this.openExternalEditor();
|
|
651
|
+
this.editor.onAltEnter = () => this.handleAltEnter();
|
|
639
652
|
this.editor.onChange = (text) => {
|
|
640
653
|
const wasBashMode = this.isBashMode;
|
|
641
654
|
this.isBashMode = text.trimStart().startsWith("!");
|
|
@@ -775,9 +788,9 @@ export class InteractiveMode {
|
|
|
775
788
|
return;
|
|
776
789
|
}
|
|
777
790
|
}
|
|
778
|
-
// Queue
|
|
791
|
+
// Queue steering message if agent is streaming (interrupts current work)
|
|
779
792
|
if (this.session.isStreaming) {
|
|
780
|
-
await this.session.
|
|
793
|
+
await this.session.steer(text);
|
|
781
794
|
this.updatePendingMessagesDisplay();
|
|
782
795
|
this.editor.addToHistory(text);
|
|
783
796
|
this.editor.setText("");
|
|
@@ -1226,6 +1239,23 @@ export class InteractiveMode {
|
|
|
1226
1239
|
// Send SIGTSTP to process group (pid=0 means all processes in group)
|
|
1227
1240
|
process.kill(0, "SIGTSTP");
|
|
1228
1241
|
}
|
|
1242
|
+
async handleAltEnter() {
|
|
1243
|
+
const text = this.editor.getText().trim();
|
|
1244
|
+
if (!text)
|
|
1245
|
+
return;
|
|
1246
|
+
// Alt+Enter queues a follow-up message (waits until agent finishes)
|
|
1247
|
+
if (this.session.isStreaming) {
|
|
1248
|
+
await this.session.followUp(text);
|
|
1249
|
+
this.updatePendingMessagesDisplay();
|
|
1250
|
+
this.editor.addToHistory(text);
|
|
1251
|
+
this.editor.setText("");
|
|
1252
|
+
this.ui.requestRender();
|
|
1253
|
+
}
|
|
1254
|
+
// If not streaming, Alt+Enter acts like regular Enter (trigger onSubmit)
|
|
1255
|
+
else if (this.editor.onSubmit) {
|
|
1256
|
+
this.editor.onSubmit(text);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1229
1259
|
updateEditorBorderColor() {
|
|
1230
1260
|
if (this.isBashMode) {
|
|
1231
1261
|
this.editor.borderColor = theme.getBashModeBorderColor();
|
|
@@ -1357,12 +1387,17 @@ export class InteractiveMode {
|
|
|
1357
1387
|
}
|
|
1358
1388
|
updatePendingMessagesDisplay() {
|
|
1359
1389
|
this.pendingMessagesContainer.clear();
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1390
|
+
const steeringMessages = this.session.getSteeringMessages();
|
|
1391
|
+
const followUpMessages = this.session.getFollowUpMessages();
|
|
1392
|
+
if (steeringMessages.length > 0 || followUpMessages.length > 0) {
|
|
1362
1393
|
this.pendingMessagesContainer.addChild(new Spacer(1));
|
|
1363
|
-
for (const message of
|
|
1364
|
-
const
|
|
1365
|
-
this.pendingMessagesContainer.addChild(new TruncatedText(
|
|
1394
|
+
for (const message of steeringMessages) {
|
|
1395
|
+
const text = theme.fg("dim", `Steering: ${message}`);
|
|
1396
|
+
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
1397
|
+
}
|
|
1398
|
+
for (const message of followUpMessages) {
|
|
1399
|
+
const text = theme.fg("dim", `Follow-up: ${message}`);
|
|
1400
|
+
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
1366
1401
|
}
|
|
1367
1402
|
}
|
|
1368
1403
|
}
|
|
@@ -1398,13 +1433,16 @@ export class InteractiveMode {
|
|
|
1398
1433
|
const selector = new SettingsSelectorComponent({
|
|
1399
1434
|
autoCompact: this.session.autoCompactionEnabled,
|
|
1400
1435
|
showImages: this.settingsManager.getShowImages(),
|
|
1401
|
-
|
|
1436
|
+
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
1437
|
+
steeringMode: this.session.steeringMode,
|
|
1438
|
+
followUpMode: this.session.followUpMode,
|
|
1402
1439
|
thinkingLevel: this.session.thinkingLevel,
|
|
1403
1440
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
1404
1441
|
currentTheme: this.settingsManager.getTheme() || "dark",
|
|
1405
1442
|
availableThemes: getAvailableThemes(),
|
|
1406
1443
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
1407
1444
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
1445
|
+
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
1408
1446
|
}, {
|
|
1409
1447
|
onAutoCompactChange: (enabled) => {
|
|
1410
1448
|
this.session.setAutoCompactionEnabled(enabled);
|
|
@@ -1418,8 +1456,14 @@ export class InteractiveMode {
|
|
|
1418
1456
|
}
|
|
1419
1457
|
}
|
|
1420
1458
|
},
|
|
1421
|
-
|
|
1422
|
-
this.
|
|
1459
|
+
onAutoResizeImagesChange: (enabled) => {
|
|
1460
|
+
this.settingsManager.setImageAutoResize(enabled);
|
|
1461
|
+
},
|
|
1462
|
+
onSteeringModeChange: (mode) => {
|
|
1463
|
+
this.session.setSteeringMode(mode);
|
|
1464
|
+
},
|
|
1465
|
+
onFollowUpModeChange: (mode) => {
|
|
1466
|
+
this.session.setFollowUpMode(mode);
|
|
1423
1467
|
},
|
|
1424
1468
|
onThinkingLevelChange: (level) => {
|
|
1425
1469
|
this.session.setThinkingLevel(level);
|
|
@@ -1455,6 +1499,9 @@ export class InteractiveMode {
|
|
|
1455
1499
|
onCollapseChangelogChange: (collapsed) => {
|
|
1456
1500
|
this.settingsManager.setCollapseChangelog(collapsed);
|
|
1457
1501
|
},
|
|
1502
|
+
onDoubleEscapeActionChange: (action) => {
|
|
1503
|
+
this.settingsManager.setDoubleEscapeAction(action);
|
|
1504
|
+
},
|
|
1458
1505
|
onCancel: () => {
|
|
1459
1506
|
done();
|
|
1460
1507
|
this.ui.requestRender();
|
|
@@ -1835,7 +1882,7 @@ export class InteractiveMode {
|
|
|
1835
1882
|
handleSessionCommand() {
|
|
1836
1883
|
const stats = this.session.getSessionStats();
|
|
1837
1884
|
let info = `${theme.bold("Session Info")}\n\n`;
|
|
1838
|
-
info += `${theme.fg("dim", "File:")} ${stats.sessionFile}\n`;
|
|
1885
|
+
info += `${theme.fg("dim", "File:")} ${stats.sessionFile ?? "In-memory"}\n`;
|
|
1839
1886
|
info += `${theme.fg("dim", "ID:")} ${stats.sessionId}\n\n`;
|
|
1840
1887
|
info += `${theme.bold("Messages")}\n`;
|
|
1841
1888
|
info += `${theme.fg("dim", "User:")} ${stats.userMessages}\n`;
|