@mariozechner/pi-coding-agent 0.32.3 → 0.33.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +76 -2
  3. package/dist/core/export-html/template.css +34 -4
  4. package/dist/core/export-html/template.js +17 -4
  5. package/dist/core/keybindings.d.ts +59 -0
  6. package/dist/core/keybindings.d.ts.map +1 -0
  7. package/dist/core/keybindings.js +149 -0
  8. package/dist/core/keybindings.js.map +1 -0
  9. package/dist/modes/interactive/components/custom-editor.d.ts +11 -12
  10. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  11. package/dist/modes/interactive/components/custom-editor.js +48 -72
  12. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  13. package/dist/modes/interactive/components/hook-editor.d.ts.map +1 -1
  14. package/dist/modes/interactive/components/hook-editor.js +5 -4
  15. package/dist/modes/interactive/components/hook-editor.js.map +1 -1
  16. package/dist/modes/interactive/components/hook-input.d.ts.map +1 -1
  17. package/dist/modes/interactive/components/hook-input.js +4 -3
  18. package/dist/modes/interactive/components/hook-input.js.map +1 -1
  19. package/dist/modes/interactive/components/hook-selector.d.ts.map +1 -1
  20. package/dist/modes/interactive/components/hook-selector.js +6 -5
  21. package/dist/modes/interactive/components/hook-selector.js.map +1 -1
  22. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  23. package/dist/modes/interactive/components/model-selector.js +6 -5
  24. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  25. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  26. package/dist/modes/interactive/components/oauth-selector.js +6 -5
  27. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  28. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  29. package/dist/modes/interactive/components/session-selector.js +6 -9
  30. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  31. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  32. package/dist/modes/interactive/components/tree-selector.js +14 -15
  33. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  34. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  35. package/dist/modes/interactive/components/user-message-selector.js +6 -11
  36. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  37. package/dist/modes/interactive/interactive-mode.d.ts +21 -1
  38. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  39. package/dist/modes/interactive/interactive-mode.js +175 -45
  40. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  41. package/docs/tui.md +18 -15
  42. package/examples/custom-tools/subagent/README.md +2 -2
  43. package/examples/hooks/snake.ts +7 -7
  44. package/examples/hooks/todo/index.ts +2 -2
  45. package/package.json +5 -4
package/docs/tui.md CHANGED
@@ -130,27 +130,30 @@ const image = new Image(
130
130
 
131
131
  ## Keyboard Input
132
132
 
133
- Use key detection helpers:
133
+ Use `matchesKey()` for key detection:
134
134
 
135
135
  ```typescript
136
- import {
137
- isEnter, isEscape, isTab,
138
- isArrowUp, isArrowDown, isArrowLeft, isArrowRight,
139
- isCtrlC, isCtrlO, isBackspace, isDelete,
140
- // ... and more
141
- } from "@mariozechner/pi-tui";
136
+ import { matchesKey, Key } from "@mariozechner/pi-tui";
142
137
 
143
138
  handleInput(data: string) {
144
- if (isArrowUp(data)) {
139
+ if (matchesKey(data, Key.up)) {
145
140
  this.selectedIndex--;
146
- } else if (isEnter(data)) {
141
+ } else if (matchesKey(data, Key.enter)) {
147
142
  this.onSelect?.(this.selectedIndex);
148
- } else if (isEscape(data)) {
143
+ } else if (matchesKey(data, Key.escape)) {
149
144
  this.onCancel?.();
145
+ } else if (matchesKey(data, Key.ctrl("c"))) {
146
+ // Ctrl+C
150
147
  }
151
148
  }
152
149
  ```
153
150
 
151
+ **Key identifiers** (use `Key.*` for autocomplete, or string literals):
152
+ - Basic keys: `Key.enter`, `Key.escape`, `Key.tab`, `Key.space`, `Key.backspace`, `Key.delete`, `Key.home`, `Key.end`
153
+ - Arrow keys: `Key.up`, `Key.down`, `Key.left`, `Key.right`
154
+ - With modifiers: `Key.ctrl("c")`, `Key.shift("tab")`, `Key.alt("left")`, `Key.ctrlShift("p")`
155
+ - String format also works: `"enter"`, `"ctrl+c"`, `"shift+tab"`, `"ctrl+shift+p"`
156
+
154
157
  ## Line Width
155
158
 
156
159
  **Critical:** Each line from `render()` must not exceed the `width` parameter.
@@ -175,7 +178,7 @@ Example: Interactive selector
175
178
 
176
179
  ```typescript
177
180
  import {
178
- isEnter, isEscape, isArrowUp, isArrowDown,
181
+ matchesKey, Key,
179
182
  truncateToWidth, visibleWidth
180
183
  } from "@mariozechner/pi-tui";
181
184
 
@@ -193,15 +196,15 @@ class MySelector {
193
196
  }
194
197
 
195
198
  handleInput(data: string): void {
196
- if (isArrowUp(data) && this.selected > 0) {
199
+ if (matchesKey(data, Key.up) && this.selected > 0) {
197
200
  this.selected--;
198
201
  this.invalidate();
199
- } else if (isArrowDown(data) && this.selected < this.items.length - 1) {
202
+ } else if (matchesKey(data, Key.down) && this.selected < this.items.length - 1) {
200
203
  this.selected++;
201
204
  this.invalidate();
202
- } else if (isEnter(data)) {
205
+ } else if (matchesKey(data, Key.enter)) {
203
206
  this.onSelect?.(this.items[this.selected]);
204
- } else if (isEscape(data)) {
207
+ } else if (matchesKey(data, Key.escape)) {
205
208
  this.onCancel?.();
206
209
  }
207
210
  }
@@ -16,7 +16,7 @@ Delegate tasks to specialized subagents with isolated context windows.
16
16
  ```
17
17
  subagent/
18
18
  ├── README.md # This file
19
- ├── subagent.ts # The custom tool (entry point)
19
+ ├── index.ts # The custom tool (entry point)
20
20
  ├── agents.ts # Agent discovery logic
21
21
  ├── agents/ # Sample agent definitions
22
22
  │ ├── scout.md # Fast recon, returns compressed context
@@ -36,7 +36,7 @@ From the repository root, symlink the files:
36
36
  ```bash
37
37
  # Symlink the tool (must be in a subdirectory with index.ts)
38
38
  mkdir -p ~/.pi/agent/tools/subagent
39
- ln -sf "$(pwd)/packages/coding-agent/examples/custom-tools/subagent/subagent.ts" ~/.pi/agent/tools/subagent/index.ts
39
+ ln -sf "$(pwd)/packages/coding-agent/examples/custom-tools/subagent/index.ts" ~/.pi/agent/tools/subagent/index.ts
40
40
  ln -sf "$(pwd)/packages/coding-agent/examples/custom-tools/subagent/agents.ts" ~/.pi/agent/tools/subagent/agents.ts
41
41
 
42
42
  # Symlink agents
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import type { HookAPI } from "@mariozechner/pi-coding-agent";
6
- import { isArrowDown, isArrowLeft, isArrowRight, isArrowUp, isEscape, visibleWidth } from "@mariozechner/pi-tui";
6
+ import { matchesKey, visibleWidth } from "@mariozechner/pi-tui";
7
7
 
8
8
  const GAME_WIDTH = 40;
9
9
  const GAME_HEIGHT = 15;
@@ -150,7 +150,7 @@ class SnakeComponent {
150
150
  handleInput(data: string): void {
151
151
  // If paused (resuming), wait for any key
152
152
  if (this.paused) {
153
- if (isEscape(data) || data === "q" || data === "Q") {
153
+ if (matchesKey(data, "escape") || data === "q" || data === "Q") {
154
154
  // Quit without clearing save
155
155
  this.dispose();
156
156
  this.onClose();
@@ -163,7 +163,7 @@ class SnakeComponent {
163
163
  }
164
164
 
165
165
  // ESC to pause and save
166
- if (isEscape(data)) {
166
+ if (matchesKey(data, "escape")) {
167
167
  this.dispose();
168
168
  this.onSave(this.state);
169
169
  this.onClose();
@@ -179,13 +179,13 @@ class SnakeComponent {
179
179
  }
180
180
 
181
181
  // Arrow keys or WASD
182
- if (isArrowUp(data) || data === "w" || data === "W") {
182
+ if (matchesKey(data, "up") || data === "w" || data === "W") {
183
183
  if (this.state.direction !== "down") this.state.nextDirection = "up";
184
- } else if (isArrowDown(data) || data === "s" || data === "S") {
184
+ } else if (matchesKey(data, "down") || data === "s" || data === "S") {
185
185
  if (this.state.direction !== "up") this.state.nextDirection = "down";
186
- } else if (isArrowRight(data) || data === "d" || data === "D") {
186
+ } else if (matchesKey(data, "right") || data === "d" || data === "D") {
187
187
  if (this.state.direction !== "left") this.state.nextDirection = "right";
188
- } else if (isArrowLeft(data) || data === "a" || data === "A") {
188
+ } else if (matchesKey(data, "left") || data === "a" || data === "A") {
189
189
  if (this.state.direction !== "right") this.state.nextDirection = "left";
190
190
  }
191
191
 
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { HookAPI, Theme } from "@mariozechner/pi-coding-agent";
9
- import { isCtrlC, isEscape, truncateToWidth } from "@mariozechner/pi-tui";
9
+ import { matchesKey, truncateToWidth } from "@mariozechner/pi-tui";
10
10
 
11
11
  interface Todo {
12
12
  id: number;
@@ -35,7 +35,7 @@ class TodoListComponent {
35
35
  }
36
36
 
37
37
  handleInput(data: string): void {
38
- if (isEscape(data) || isCtrlC(data)) {
38
+ if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
39
39
  this.onClose();
40
40
  }
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-coding-agent",
3
- "version": "0.32.3",
3
+ "version": "0.33.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -38,9 +38,10 @@
38
38
  "prepublishOnly": "npm run clean && npm run build"
39
39
  },
40
40
  "dependencies": {
41
- "@mariozechner/pi-agent-core": "^0.32.3",
42
- "@mariozechner/pi-ai": "^0.32.3",
43
- "@mariozechner/pi-tui": "^0.32.3",
41
+ "@crosscopy/clipboard": "^0.2.8",
42
+ "@mariozechner/pi-agent-core": "^0.33.0",
43
+ "@mariozechner/pi-ai": "^0.33.0",
44
+ "@mariozechner/pi-tui": "^0.33.0",
44
45
  "chalk": "^5.5.0",
45
46
  "cli-highlight": "^2.1.11",
46
47
  "diff": "^8.0.2",