@mariozechner/pi-coding-agent 0.60.0 → 0.61.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 +40 -0
- package/README.md +1 -1
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +1 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bedrock.d.ts.map +1 -1
- package/dist/bun/register-bedrock.js +3 -84
- package/dist/bun/register-bedrock.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +2 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +17 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +61 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +7 -3
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/template.css +43 -13
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +107 -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/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +4 -4
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +45 -33
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +4 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +9 -2
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +85 -13
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/keybindings.d.ts +268 -51
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +221 -143
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +23 -14
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +12 -10
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +3 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +37 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +6 -3
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -5
- 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 -4
- 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 +1 -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 +2 -2
- 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 +2 -2
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +8 -8
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +6 -6
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +9 -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 +5 -5
- 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 +8 -8
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +3 -36
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +5 -44
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +6 -6
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +12 -8
- 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 +6 -6
- package/dist/modes/interactive/components/oauth-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 -4
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +32 -35
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +51 -6
- 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 +15 -15
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +6 -6
- package/dist/modes/interactive/components/user-message-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 +140 -87
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +49 -37
- 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 +4 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/child-process.d.ts +11 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +78 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +11 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/extensions.md +44 -7
- package/docs/keybindings.md +101 -112
- package/docs/providers.md +7 -0
- package/docs/rpc.md +4 -4
- package/docs/sdk.md +2 -2
- package/examples/extensions/antigravity-image-gen.ts +5 -3
- 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/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/subagent/index.ts +7 -5
- package/examples/extensions/tool-override.ts +9 -7
- package/examples/extensions/truncated-tool.ts +6 -3
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
package/docs/keybindings.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Each action can be bound to one or more keys.
|
|
4
4
|
|
|
5
|
+
The config file uses the same namespaced keybinding ids that pi uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
|
|
6
|
+
|
|
7
|
+
Older configs using pre-namespaced ids such as `cursorUp` or `expandTools` are migrated automatically to the namespaced ids on startup.
|
|
8
|
+
|
|
5
9
|
After editing `keybindings.json`, run `/reload` in pi to apply the changes without restarting the session.
|
|
6
10
|
|
|
7
11
|
## Key Format
|
|
@@ -18,127 +22,112 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
|
|
|
18
22
|
|
|
19
23
|
## All Actions
|
|
20
24
|
|
|
21
|
-
### Cursor Movement
|
|
25
|
+
### TUI Editor Cursor Movement
|
|
22
26
|
|
|
23
|
-
|
|
|
27
|
+
| Keybinding id | Default | Description |
|
|
24
28
|
|--------|---------|-------------|
|
|
25
|
-
| `cursorUp` | `up` | Move cursor up |
|
|
26
|
-
| `cursorDown` | `down` | Move cursor down |
|
|
27
|
-
| `cursorLeft` | `left`, `ctrl+b` | Move cursor left |
|
|
28
|
-
| `cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
|
29
|
-
| `cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
|
30
|
-
| `cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
|
31
|
-
| `cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
|
32
|
-
| `cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
|
33
|
-
| `jumpForward` | `ctrl+]` | Jump forward to character |
|
|
34
|
-
| `jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
|
35
|
-
| `pageUp` | `pageUp` | Scroll up by page |
|
|
36
|
-
| `pageDown` | `pageDown` | Scroll down by page |
|
|
37
|
-
|
|
38
|
-
### Deletion
|
|
39
|
-
|
|
40
|
-
|
|
|
29
|
+
| `tui.editor.cursorUp` | `up` | Move cursor up |
|
|
30
|
+
| `tui.editor.cursorDown` | `down` | Move cursor down |
|
|
31
|
+
| `tui.editor.cursorLeft` | `left`, `ctrl+b` | Move cursor left |
|
|
32
|
+
| `tui.editor.cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
|
33
|
+
| `tui.editor.cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
|
34
|
+
| `tui.editor.cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
|
35
|
+
| `tui.editor.cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
|
36
|
+
| `tui.editor.cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
|
37
|
+
| `tui.editor.jumpForward` | `ctrl+]` | Jump forward to character |
|
|
38
|
+
| `tui.editor.jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
|
39
|
+
| `tui.editor.pageUp` | `pageUp` | Scroll up by page |
|
|
40
|
+
| `tui.editor.pageDown` | `pageDown` | Scroll down by page |
|
|
41
|
+
|
|
42
|
+
### TUI Editor Deletion
|
|
43
|
+
|
|
44
|
+
| Keybinding id | Default | Description |
|
|
41
45
|
|--------|---------|-------------|
|
|
42
|
-
| `deleteCharBackward` | `backspace` | Delete character backward |
|
|
43
|
-
| `deleteCharForward` | `delete`, `ctrl+d` | Delete character forward |
|
|
44
|
-
| `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
|
|
45
|
-
| `deleteWordForward` | `alt+d`, `alt+delete` | Delete word forward |
|
|
46
|
-
| `deleteToLineStart` | `ctrl+u` | Delete to line start |
|
|
47
|
-
| `deleteToLineEnd` | `ctrl+k` | Delete to line end |
|
|
46
|
+
| `tui.editor.deleteCharBackward` | `backspace` | Delete character backward |
|
|
47
|
+
| `tui.editor.deleteCharForward` | `delete`, `ctrl+d` | Delete character forward |
|
|
48
|
+
| `tui.editor.deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
|
|
49
|
+
| `tui.editor.deleteWordForward` | `alt+d`, `alt+delete` | Delete word forward |
|
|
50
|
+
| `tui.editor.deleteToLineStart` | `ctrl+u` | Delete to line start |
|
|
51
|
+
| `tui.editor.deleteToLineEnd` | `ctrl+k` | Delete to line end |
|
|
48
52
|
|
|
49
|
-
###
|
|
53
|
+
### TUI Input
|
|
50
54
|
|
|
51
|
-
|
|
|
55
|
+
| Keybinding id | Default | Description |
|
|
52
56
|
|--------|---------|-------------|
|
|
53
|
-
| `newLine` | `shift+enter` | Insert new line |
|
|
54
|
-
| `submit` | `enter` | Submit input |
|
|
55
|
-
| `tab` | `tab` | Tab / autocomplete |
|
|
57
|
+
| `tui.input.newLine` | `shift+enter` | Insert new line |
|
|
58
|
+
| `tui.input.submit` | `enter` | Submit input |
|
|
59
|
+
| `tui.input.tab` | `tab` | Tab / autocomplete |
|
|
56
60
|
|
|
57
|
-
### Kill Ring
|
|
61
|
+
### TUI Kill Ring
|
|
58
62
|
|
|
59
|
-
|
|
|
63
|
+
| Keybinding id | Default | Description |
|
|
60
64
|
|--------|---------|-------------|
|
|
61
|
-
| `yank` | `ctrl+y` | Paste most recently deleted text |
|
|
62
|
-
| `yankPop` | `alt+y` | Cycle through deleted text after yank |
|
|
63
|
-
| `undo` | `ctrl+-` | Undo last edit |
|
|
65
|
+
| `tui.editor.yank` | `ctrl+y` | Paste most recently deleted text |
|
|
66
|
+
| `tui.editor.yankPop` | `alt+y` | Cycle through deleted text after yank |
|
|
67
|
+
| `tui.editor.undo` | `ctrl+-` | Undo last edit |
|
|
64
68
|
|
|
65
|
-
### Clipboard
|
|
69
|
+
### TUI Clipboard and Selection
|
|
66
70
|
|
|
67
|
-
|
|
|
71
|
+
| Keybinding id | Default | Description |
|
|
68
72
|
|--------|---------|-------------|
|
|
69
|
-
| `copy` | `ctrl+c` | Copy selection |
|
|
70
|
-
| `
|
|
73
|
+
| `tui.input.copy` | `ctrl+c` | Copy selection |
|
|
74
|
+
| `tui.select.up` | `up` | Move selection up |
|
|
75
|
+
| `tui.select.down` | `down` | Move selection down |
|
|
76
|
+
| `tui.select.pageUp` | `pageUp` | Page up in list |
|
|
77
|
+
| `tui.select.pageDown` | `pageDown` | Page down in list |
|
|
78
|
+
| `tui.select.confirm` | `enter` | Confirm selection |
|
|
79
|
+
| `tui.select.cancel` | `escape`, `ctrl+c` | Cancel selection |
|
|
71
80
|
|
|
72
81
|
### Application
|
|
73
82
|
|
|
74
|
-
|
|
|
83
|
+
| Keybinding id | Default | Description |
|
|
75
84
|
|--------|---------|-------------|
|
|
76
|
-
| `interrupt` | `escape` | Cancel / abort |
|
|
77
|
-
| `clear` | `ctrl+c` | Clear editor |
|
|
78
|
-
| `exit` | `ctrl+d` | Exit (when editor empty) |
|
|
79
|
-
| `suspend` | `ctrl+z` | Suspend to background |
|
|
80
|
-
| `
|
|
85
|
+
| `app.interrupt` | `escape` | Cancel / abort |
|
|
86
|
+
| `app.clear` | `ctrl+c` | Clear editor |
|
|
87
|
+
| `app.exit` | `ctrl+d` | Exit (when editor empty) |
|
|
88
|
+
| `app.suspend` | `ctrl+z` | Suspend to background |
|
|
89
|
+
| `app.editor.external` | `ctrl+g` | Open in external editor (`$VISUAL` or `$EDITOR`) |
|
|
90
|
+
| `app.clipboard.pasteImage` | `ctrl+v` (`alt+v` on Windows) | Paste image from clipboard |
|
|
81
91
|
|
|
82
|
-
###
|
|
92
|
+
### Sessions
|
|
83
93
|
|
|
84
|
-
|
|
|
94
|
+
| Keybinding id | Default | Description |
|
|
85
95
|
|--------|---------|-------------|
|
|
86
|
-
| `
|
|
87
|
-
| `tree` | *(none)* | Open session tree navigator (`/tree`) |
|
|
88
|
-
| `fork` | *(none)* | Fork current session (`/fork`) |
|
|
89
|
-
| `resume` | *(none)* | Open session resume picker (`/resume`) |
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
|
94
|
-
|
|
95
|
-
| `
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
### Display
|
|
101
|
-
|
|
102
|
-
| Action | Default | Description |
|
|
96
|
+
| `app.session.new` | *(none)* | Start a new session (`/new`) |
|
|
97
|
+
| `app.session.tree` | *(none)* | Open session tree navigator (`/tree`) |
|
|
98
|
+
| `app.session.fork` | *(none)* | Fork current session (`/fork`) |
|
|
99
|
+
| `app.session.resume` | *(none)* | Open session resume picker (`/resume`) |
|
|
100
|
+
| `app.session.togglePath` | `ctrl+p` | Toggle path display |
|
|
101
|
+
| `app.session.toggleSort` | `ctrl+s` | Toggle sort mode |
|
|
102
|
+
| `app.session.toggleNamedFilter` | `ctrl+n` | Toggle named-only filter |
|
|
103
|
+
| `app.session.rename` | `ctrl+r` | Rename session |
|
|
104
|
+
| `app.session.delete` | `ctrl+d` | Delete session |
|
|
105
|
+
| `app.session.deleteNoninvasive` | `ctrl+backspace` | Delete session when query is empty |
|
|
106
|
+
|
|
107
|
+
### Models and Thinking
|
|
108
|
+
|
|
109
|
+
| Keybinding id | Default | Description |
|
|
103
110
|
|--------|---------|-------------|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
111
|
+
| `app.model.select` | `ctrl+l` | Open model selector |
|
|
112
|
+
| `app.model.cycleForward` | `ctrl+p` | Cycle to next model |
|
|
113
|
+
| `app.model.cycleBackward` | `shift+ctrl+p` | Cycle to previous model |
|
|
114
|
+
| `app.thinking.cycle` | `shift+tab` | Cycle thinking level |
|
|
115
|
+
| `app.thinking.toggle` | `ctrl+t` | Collapse or expand thinking blocks |
|
|
106
116
|
|
|
107
|
-
### Message Queue
|
|
117
|
+
### Display and Message Queue
|
|
108
118
|
|
|
109
|
-
|
|
|
119
|
+
| Keybinding id | Default | Description |
|
|
110
120
|
|--------|---------|-------------|
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
|
|
114
|
-
### Selection (Lists, Pickers)
|
|
115
|
-
|
|
116
|
-
| Action | Default | Description |
|
|
117
|
-
|--------|---------|-------------|
|
|
118
|
-
| `selectUp` | `up` | Move selection up |
|
|
119
|
-
| `selectDown` | `down` | Move selection down |
|
|
120
|
-
| `selectPageUp` | `pageUp` | Page up in list |
|
|
121
|
-
| `selectPageDown` | `pageDown` | Page down in list |
|
|
122
|
-
| `selectConfirm` | `enter` | Confirm selection |
|
|
123
|
-
| `selectCancel` | `escape`, `ctrl+c` | Cancel selection |
|
|
121
|
+
| `app.tools.expand` | `ctrl+o` | Collapse or expand tool output |
|
|
122
|
+
| `app.message.followUp` | `alt+enter` | Queue follow-up message |
|
|
123
|
+
| `app.message.dequeue` | `alt+up` | Restore queued messages to editor |
|
|
124
124
|
|
|
125
125
|
### Tree Navigation
|
|
126
126
|
|
|
127
|
-
|
|
|
128
|
-
|--------|---------|-------------|
|
|
129
|
-
| `treeFoldOrUp` | `ctrl+left`, `alt+left` | Fold current branch segment, or jump to the previous segment start |
|
|
130
|
-
| `treeUnfoldOrDown` | `ctrl+right`, `alt+right` | Unfold current branch segment, or jump to the next segment start or branch end |
|
|
131
|
-
|
|
132
|
-
### Session Picker
|
|
133
|
-
|
|
134
|
-
| Action | Default | Description |
|
|
127
|
+
| Keybinding id | Default | Description |
|
|
135
128
|
|--------|---------|-------------|
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `toggleSessionNamedFilter` | `ctrl+n` | Toggle named-only filter |
|
|
139
|
-
| `renameSession` | `ctrl+r` | Rename session |
|
|
140
|
-
| `deleteSession` | `ctrl+d` | Delete session |
|
|
141
|
-
| `deleteSessionNoninvasive` | `ctrl+backspace` | Delete session (when query empty) |
|
|
129
|
+
| `app.tree.foldOrUp` | `ctrl+left`, `alt+left` | Fold current branch segment, or jump to the previous segment start |
|
|
130
|
+
| `app.tree.unfoldOrDown` | `ctrl+right`, `alt+right` | Unfold current branch segment, or jump to the next segment start or branch end |
|
|
142
131
|
|
|
143
132
|
## Custom Configuration
|
|
144
133
|
|
|
@@ -146,9 +135,9 @@ Create `~/.pi/agent/keybindings.json`:
|
|
|
146
135
|
|
|
147
136
|
```json
|
|
148
137
|
{
|
|
149
|
-
"cursorUp": ["up", "ctrl+p"],
|
|
150
|
-
"cursorDown": ["down", "ctrl+n"],
|
|
151
|
-
"deleteWordBackward": ["ctrl+w", "alt+backspace"]
|
|
138
|
+
"tui.editor.cursorUp": ["up", "ctrl+p"],
|
|
139
|
+
"tui.editor.cursorDown": ["down", "ctrl+n"],
|
|
140
|
+
"tui.editor.deleteWordBackward": ["ctrl+w", "alt+backspace"]
|
|
152
141
|
}
|
|
153
142
|
```
|
|
154
143
|
|
|
@@ -158,15 +147,15 @@ Each action can have a single key or an array of keys. User config overrides def
|
|
|
158
147
|
|
|
159
148
|
```json
|
|
160
149
|
{
|
|
161
|
-
"cursorUp": ["up", "ctrl+p"],
|
|
162
|
-
"cursorDown": ["down", "ctrl+n"],
|
|
163
|
-
"cursorLeft": ["left", "ctrl+b"],
|
|
164
|
-
"cursorRight": ["right", "ctrl+f"],
|
|
165
|
-
"cursorWordLeft": ["alt+left", "alt+b"],
|
|
166
|
-
"cursorWordRight": ["alt+right", "alt+f"],
|
|
167
|
-
"deleteCharForward": ["delete", "ctrl+d"],
|
|
168
|
-
"deleteCharBackward": ["backspace", "ctrl+h"],
|
|
169
|
-
"newLine": ["shift+enter", "ctrl+j"]
|
|
150
|
+
"tui.editor.cursorUp": ["up", "ctrl+p"],
|
|
151
|
+
"tui.editor.cursorDown": ["down", "ctrl+n"],
|
|
152
|
+
"tui.editor.cursorLeft": ["left", "ctrl+b"],
|
|
153
|
+
"tui.editor.cursorRight": ["right", "ctrl+f"],
|
|
154
|
+
"tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
|
|
155
|
+
"tui.editor.cursorWordRight": ["alt+right", "alt+f"],
|
|
156
|
+
"tui.editor.deleteCharForward": ["delete", "ctrl+d"],
|
|
157
|
+
"tui.editor.deleteCharBackward": ["backspace", "ctrl+h"],
|
|
158
|
+
"tui.input.newLine": ["shift+enter", "ctrl+j"]
|
|
170
159
|
}
|
|
171
160
|
```
|
|
172
161
|
|
|
@@ -174,11 +163,11 @@ Each action can have a single key or an array of keys. User config overrides def
|
|
|
174
163
|
|
|
175
164
|
```json
|
|
176
165
|
{
|
|
177
|
-
"cursorUp": ["up", "alt+k"],
|
|
178
|
-
"cursorDown": ["down", "alt+j"],
|
|
179
|
-
"cursorLeft": ["left", "alt+h"],
|
|
180
|
-
"cursorRight": ["right", "alt+l"],
|
|
181
|
-
"cursorWordLeft": ["alt+left", "alt+b"],
|
|
182
|
-
"cursorWordRight": ["alt+right", "alt+w"]
|
|
166
|
+
"tui.editor.cursorUp": ["up", "alt+k"],
|
|
167
|
+
"tui.editor.cursorDown": ["down", "alt+j"],
|
|
168
|
+
"tui.editor.cursorLeft": ["left", "alt+h"],
|
|
169
|
+
"tui.editor.cursorRight": ["right", "alt+l"],
|
|
170
|
+
"tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
|
|
171
|
+
"tui.editor.cursorWordRight": ["alt+right", "alt+w"]
|
|
183
172
|
}
|
|
184
173
|
```
|
package/docs/providers.md
CHANGED
|
@@ -147,6 +147,13 @@ Also supports ECS task roles (`AWS_CONTAINER_CREDENTIALS_*`) and IRSA (`AWS_WEB_
|
|
|
147
147
|
pi --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
+
Prompt caching is enabled automatically for Claude models whose ID contains a recognizable model name (base models and system-defined inference profiles). For application inference profiles (whose ARNs don't contain the model name), set `AWS_BEDROCK_FORCE_CACHE=1` to enable cache points:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
export AWS_BEDROCK_FORCE_CACHE=1
|
|
154
|
+
pi --provider amazon-bedrock --model arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123
|
|
155
|
+
```
|
|
156
|
+
|
|
150
157
|
If you are connecting to a Bedrock API proxy, the following environment variables can be used:
|
|
151
158
|
|
|
152
159
|
```bash
|
package/docs/rpc.md
CHANGED
|
@@ -58,7 +58,7 @@ With images:
|
|
|
58
58
|
{"type": "prompt", "message": "New instruction", "streamingBehavior": "steer"}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
- `"steer"`:
|
|
61
|
+
- `"steer"`: Queue the message while the agent is running. It is delivered after the current assistant turn finishes executing its tool calls, before the next LLM call.
|
|
62
62
|
- `"followUp"`: Wait until the agent finishes. Message is delivered only when agent stops.
|
|
63
63
|
|
|
64
64
|
If the agent is streaming and no `streamingBehavior` is specified, the command returns an error.
|
|
@@ -76,7 +76,7 @@ The `images` field is optional. Each image uses `ImageContent` format: `{"type":
|
|
|
76
76
|
|
|
77
77
|
#### steer
|
|
78
78
|
|
|
79
|
-
Queue a steering message
|
|
79
|
+
Queue a steering message while the agent is running. It is delivered after the current assistant turn finishes executing its tool calls, before the next LLM call. Skill commands and prompt templates are expanded. Extension commands are not allowed (use `prompt` instead).
|
|
80
80
|
|
|
81
81
|
```json
|
|
82
82
|
{"type": "steer", "message": "Stop and do this instead"}
|
|
@@ -321,8 +321,8 @@ Control how steering messages (from `steer`) are delivered.
|
|
|
321
321
|
```
|
|
322
322
|
|
|
323
323
|
Modes:
|
|
324
|
-
- `"all"`: Deliver all steering messages
|
|
325
|
-
- `"one-at-a-time"`: Deliver one steering message per
|
|
324
|
+
- `"all"`: Deliver all steering messages after the current assistant turn finishes executing its tool calls
|
|
325
|
+
- `"one-at-a-time"`: Deliver one steering message per completed assistant turn (default)
|
|
326
326
|
|
|
327
327
|
Response:
|
|
328
328
|
```json
|
package/docs/sdk.md
CHANGED
|
@@ -78,7 +78,7 @@ interface AgentSession {
|
|
|
78
78
|
prompt(text: string, options?: PromptOptions): Promise<void>;
|
|
79
79
|
|
|
80
80
|
// Queue messages during streaming
|
|
81
|
-
steer(text: string): Promise<void>; //
|
|
81
|
+
steer(text: string): Promise<void>; // Queue for delivery after the current assistant turn finishes its tool calls
|
|
82
82
|
followUp(text: string): Promise<void>; // Wait: delivered only when agent finishes
|
|
83
83
|
|
|
84
84
|
// Subscribe to events (returns unsubscribe function)
|
|
@@ -150,7 +150,7 @@ await session.prompt("After you're done, also check X", { streamingBehavior: "fo
|
|
|
150
150
|
For explicit queueing during streaming:
|
|
151
151
|
|
|
152
152
|
```typescript
|
|
153
|
-
//
|
|
153
|
+
// Queue a steering message for delivery after the current assistant turn finishes its tool calls
|
|
154
154
|
await session.steer("New instruction");
|
|
155
155
|
|
|
156
156
|
// Wait for agent to finish (delivered only when agent stops)
|
|
@@ -30,7 +30,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
30
30
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
31
31
|
import { join } from "node:path";
|
|
32
32
|
import { StringEnum } from "@mariozechner/pi-ai";
|
|
33
|
-
import { type ExtensionAPI, getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
33
|
+
import { type ExtensionAPI, getAgentDir, withFileMutationQueue } from "@mariozechner/pi-coding-agent";
|
|
34
34
|
import { type Static, Type } from "@sinclair/typebox";
|
|
35
35
|
|
|
36
36
|
const PROVIDER = "google-antigravity";
|
|
@@ -228,12 +228,14 @@ function imageExtension(mimeType: string): string {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
async function saveImage(base64Data: string, mimeType: string, outputDir: string): Promise<string> {
|
|
231
|
-
await mkdir(outputDir, { recursive: true });
|
|
232
231
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
233
232
|
const ext = imageExtension(mimeType);
|
|
234
233
|
const filename = `image-${timestamp}-${randomUUID().slice(0, 8)}.${ext}`;
|
|
235
234
|
const filePath = join(outputDir, filename);
|
|
236
|
-
await
|
|
235
|
+
await withFileMutationQueue(filePath, async () => {
|
|
236
|
+
await mkdir(outputDir, { recursive: true });
|
|
237
|
+
await writeFile(filePath, Buffer.from(base64Data, "base64"));
|
|
238
|
+
});
|
|
237
239
|
return filePath;
|
|
238
240
|
}
|
|
239
241
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.12.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -19,7 +19,7 @@ import * as path from "node:path";
|
|
|
19
19
|
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
20
20
|
import type { Message } from "@mariozechner/pi-ai";
|
|
21
21
|
import { StringEnum } from "@mariozechner/pi-ai";
|
|
22
|
-
import { type ExtensionAPI, getMarkdownTheme } from "@mariozechner/pi-coding-agent";
|
|
22
|
+
import { type ExtensionAPI, getMarkdownTheme, withFileMutationQueue } from "@mariozechner/pi-coding-agent";
|
|
23
23
|
import { Container, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
|
24
24
|
import { Type } from "@sinclair/typebox";
|
|
25
25
|
import { type AgentConfig, type AgentScope, discoverAgents } from "./agents.js";
|
|
@@ -207,11 +207,13 @@ async function mapWithConcurrencyLimit<TIn, TOut>(
|
|
|
207
207
|
return results;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
function writePromptToTempFile(agentName: string, prompt: string): { dir: string; filePath: string } {
|
|
211
|
-
const tmpDir = fs.
|
|
210
|
+
async function writePromptToTempFile(agentName: string, prompt: string): Promise<{ dir: string; filePath: string }> {
|
|
211
|
+
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "pi-subagent-"));
|
|
212
212
|
const safeName = agentName.replace(/[^\w.-]+/g, "_");
|
|
213
213
|
const filePath = path.join(tmpDir, `prompt-${safeName}.md`);
|
|
214
|
-
|
|
214
|
+
await withFileMutationQueue(filePath, async () => {
|
|
215
|
+
await fs.promises.writeFile(filePath, prompt, { encoding: "utf-8", mode: 0o600 });
|
|
216
|
+
});
|
|
215
217
|
return { dir: tmpDir, filePath };
|
|
216
218
|
}
|
|
217
219
|
|
|
@@ -274,7 +276,7 @@ async function runSingleAgent(
|
|
|
274
276
|
|
|
275
277
|
try {
|
|
276
278
|
if (agent.systemPrompt.trim()) {
|
|
277
|
-
const tmp = writePromptToTempFile(agent.name, agent.systemPrompt);
|
|
279
|
+
const tmp = await writePromptToTempFile(agent.name, agent.systemPrompt);
|
|
278
280
|
tmpPromptDir = tmp.dir;
|
|
279
281
|
tmpPromptPath = tmp.filePath;
|
|
280
282
|
args.push("--append-system-prompt", tmpPromptPath);
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import type { TextContent } from "@mariozechner/pi-ai";
|
|
24
|
-
import { type ExtensionAPI, getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
24
|
+
import { type ExtensionAPI, getAgentDir, withFileMutationQueue } from "@mariozechner/pi-coding-agent";
|
|
25
25
|
import { Type } from "@sinclair/typebox";
|
|
26
|
-
import {
|
|
27
|
-
import { access, readFile } from "fs/promises";
|
|
26
|
+
import { constants, readFileSync } from "fs";
|
|
27
|
+
import { access, appendFile, readFile } from "fs/promises";
|
|
28
28
|
import { join, resolve } from "path";
|
|
29
29
|
|
|
30
30
|
const LOG_FILE = join(getAgentDir(), "read-access.log");
|
|
@@ -44,14 +44,16 @@ function isBlockedPath(path: string): boolean {
|
|
|
44
44
|
return BLOCKED_PATTERNS.some((pattern) => pattern.test(path));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function logAccess(path: string, allowed: boolean, reason?: string) {
|
|
47
|
+
async function logAccess(path: string, allowed: boolean, reason?: string) {
|
|
48
48
|
const timestamp = new Date().toISOString();
|
|
49
49
|
const status = allowed ? "ALLOWED" : "BLOCKED";
|
|
50
50
|
const msg = reason ? ` (${reason})` : "";
|
|
51
51
|
const line = `[${timestamp}] ${status}: ${path}${msg}\n`;
|
|
52
52
|
|
|
53
53
|
try {
|
|
54
|
-
|
|
54
|
+
await withFileMutationQueue(LOG_FILE, async () => {
|
|
55
|
+
await appendFile(LOG_FILE, line);
|
|
56
|
+
});
|
|
55
57
|
} catch {
|
|
56
58
|
// Ignore logging errors
|
|
57
59
|
}
|
|
@@ -77,7 +79,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
77
79
|
|
|
78
80
|
// Check if path is blocked
|
|
79
81
|
if (isBlockedPath(absolutePath)) {
|
|
80
|
-
logAccess(absolutePath, false, "matches blocked pattern");
|
|
82
|
+
await logAccess(absolutePath, false, "matches blocked pattern");
|
|
81
83
|
return {
|
|
82
84
|
content: [
|
|
83
85
|
{
|
|
@@ -90,7 +92,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
// Log allowed access
|
|
93
|
-
logAccess(absolutePath, true);
|
|
95
|
+
await logAccess(absolutePath, true);
|
|
94
96
|
|
|
95
97
|
// Perform the actual read (simplified implementation)
|
|
96
98
|
try {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* built-in `grep` tool in src/core/tools/grep.ts for a more complete implementation.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
17
18
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
18
19
|
import {
|
|
19
20
|
DEFAULT_MAX_BYTES,
|
|
@@ -21,11 +22,11 @@ import {
|
|
|
21
22
|
formatSize,
|
|
22
23
|
type TruncationResult,
|
|
23
24
|
truncateHead,
|
|
25
|
+
withFileMutationQueue,
|
|
24
26
|
} from "@mariozechner/pi-coding-agent";
|
|
25
27
|
import { Text } from "@mariozechner/pi-tui";
|
|
26
28
|
import { Type } from "@sinclair/typebox";
|
|
27
29
|
import { execSync } from "child_process";
|
|
28
|
-
import { mkdtempSync, writeFileSync } from "fs";
|
|
29
30
|
import { tmpdir } from "os";
|
|
30
31
|
import { join } from "path";
|
|
31
32
|
|
|
@@ -108,9 +109,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
108
109
|
|
|
109
110
|
if (truncation.truncated) {
|
|
110
111
|
// Save full output to a temp file so LLM can access it if needed
|
|
111
|
-
const tempDir =
|
|
112
|
+
const tempDir = await mkdtemp(join(tmpdir(), "pi-rg-"));
|
|
112
113
|
const tempFile = join(tempDir, "output.txt");
|
|
113
|
-
|
|
114
|
+
await withFileMutationQueue(tempFile, async () => {
|
|
115
|
+
await writeFile(tempFile, output, "utf8");
|
|
116
|
+
});
|
|
114
117
|
|
|
115
118
|
details.truncation = truncation;
|
|
116
119
|
details.fullOutputPath = tempFile;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.25.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-coding-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@mariozechner/jiti": "^2.6.2",
|
|
43
|
-
"@mariozechner/pi-agent-core": "^0.
|
|
44
|
-
"@mariozechner/pi-ai": "^0.
|
|
45
|
-
"@mariozechner/pi-tui": "^0.
|
|
43
|
+
"@mariozechner/pi-agent-core": "^0.61.0",
|
|
44
|
+
"@mariozechner/pi-ai": "^0.61.0",
|
|
45
|
+
"@mariozechner/pi-tui": "^0.61.0",
|
|
46
46
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
47
47
|
"chalk": "^5.5.0",
|
|
48
48
|
"cli-highlight": "^2.1.11",
|