@mariozechner/pi-coding-agent 0.32.3 → 0.34.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 +56 -1
- package/README.md +76 -3
- package/dist/cli/args.d.ts +5 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +24 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +65 -9
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/custom-tools/loader.d.ts.map +1 -1
- package/dist/core/custom-tools/loader.js +1 -0
- package/dist/core/custom-tools/loader.js.map +1 -1
- package/dist/core/export-html/template.css +34 -4
- package/dist/core/export-html/template.js +17 -4
- 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.map +1 -1
- package/dist/core/hooks/loader.d.ts +56 -1
- package/dist/core/hooks/loader.d.ts.map +1 -1
- package/dist/core/hooks/loader.js +54 -2
- package/dist/core/hooks/loader.js.map +1 -1
- package/dist/core/hooks/runner.d.ts +33 -5
- package/dist/core/hooks/runner.d.ts.map +1 -1
- package/dist/core/hooks/runner.js +100 -9
- package/dist/core/hooks/runner.js.map +1 -1
- package/dist/core/hooks/types.d.ts +135 -3
- package/dist/core/hooks/types.d.ts.map +1 -1
- package/dist/core/hooks/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +59 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +149 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/sdk.d.ts +3 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +102 -27
- package/dist/core/sdk.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +32 -7
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +13 -12
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +50 -68
- 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 +5 -4
- 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 +4 -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 +6 -5
- 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 +6 -5
- 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 -5
- package/dist/modes/interactive/components/oauth-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 +6 -9
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +14 -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 -11
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +34 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +300 -64
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +3 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -0
- 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 +16 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +6 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/hooks.md +114 -4
- package/docs/tui.md +18 -15
- package/examples/custom-tools/subagent/README.md +2 -2
- package/examples/hooks/README.md +3 -0
- package/examples/hooks/pirate.ts +44 -0
- package/examples/hooks/plan-mode.ts +548 -0
- package/examples/hooks/snake.ts +7 -7
- package/examples/hooks/todo/index.ts +2 -2
- package/examples/hooks/tools.ts +145 -0
- package/package.json +5 -4
package/examples/hooks/snake.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
|
6
|
-
import {
|
|
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 (
|
|
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 (
|
|
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 (
|
|
182
|
+
if (matchesKey(data, "up") || data === "w" || data === "W") {
|
|
183
183
|
if (this.state.direction !== "down") this.state.nextDirection = "up";
|
|
184
|
-
} else if (
|
|
184
|
+
} else if (matchesKey(data, "down") || data === "s" || data === "S") {
|
|
185
185
|
if (this.state.direction !== "up") this.state.nextDirection = "down";
|
|
186
|
-
} else if (
|
|
186
|
+
} else if (matchesKey(data, "right") || data === "d" || data === "D") {
|
|
187
187
|
if (this.state.direction !== "left") this.state.nextDirection = "right";
|
|
188
|
-
} else if (
|
|
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 {
|
|
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 (
|
|
38
|
+
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
|
|
39
39
|
this.onClose();
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools Hook
|
|
3
|
+
*
|
|
4
|
+
* Provides a /tools command to enable/disable tools interactively.
|
|
5
|
+
* Tool selection persists across session reloads and respects branch navigation.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* 1. Copy this file to ~/.pi/agent/hooks/ or your project's .pi/hooks/
|
|
9
|
+
* 2. Use /tools to open the tool selector
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
|
|
13
|
+
import type { HookAPI, HookContext } from "@mariozechner/pi-coding-agent/hooks";
|
|
14
|
+
import { Container, type SettingItem, SettingsList } from "@mariozechner/pi-tui";
|
|
15
|
+
|
|
16
|
+
// State persisted to session
|
|
17
|
+
interface ToolsState {
|
|
18
|
+
enabledTools: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function toolsHook(pi: HookAPI) {
|
|
22
|
+
// Track enabled tools
|
|
23
|
+
let enabledTools: Set<string> = new Set();
|
|
24
|
+
let allTools: string[] = [];
|
|
25
|
+
|
|
26
|
+
// Persist current state
|
|
27
|
+
function persistState() {
|
|
28
|
+
pi.appendEntry<ToolsState>("tools-config", {
|
|
29
|
+
enabledTools: Array.from(enabledTools),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Apply current tool selection
|
|
34
|
+
function applyTools() {
|
|
35
|
+
pi.setActiveTools(Array.from(enabledTools));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Find the last tools-config entry in the current branch
|
|
39
|
+
function restoreFromBranch(ctx: HookContext) {
|
|
40
|
+
allTools = pi.getAllTools();
|
|
41
|
+
|
|
42
|
+
// Get entries in current branch only
|
|
43
|
+
const branchEntries = ctx.sessionManager.getBranch();
|
|
44
|
+
let savedTools: string[] | undefined;
|
|
45
|
+
|
|
46
|
+
for (const entry of branchEntries) {
|
|
47
|
+
if (entry.type === "custom" && entry.customType === "tools-config") {
|
|
48
|
+
const data = entry.data as ToolsState | undefined;
|
|
49
|
+
if (data?.enabledTools) {
|
|
50
|
+
savedTools = data.enabledTools;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (savedTools) {
|
|
56
|
+
// Restore saved tool selection (filter to only tools that still exist)
|
|
57
|
+
enabledTools = new Set(savedTools.filter((t: string) => allTools.includes(t)));
|
|
58
|
+
applyTools();
|
|
59
|
+
} else {
|
|
60
|
+
// No saved state - sync with currently active tools
|
|
61
|
+
enabledTools = new Set(pi.getActiveTools());
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Register /tools command
|
|
66
|
+
pi.registerCommand("tools", {
|
|
67
|
+
description: "Enable/disable tools",
|
|
68
|
+
handler: async (_args, ctx) => {
|
|
69
|
+
// Refresh tool list
|
|
70
|
+
allTools = pi.getAllTools();
|
|
71
|
+
|
|
72
|
+
await ctx.ui.custom((tui, theme, done) => {
|
|
73
|
+
// Build settings items for each tool
|
|
74
|
+
const items: SettingItem[] = allTools.map((tool) => ({
|
|
75
|
+
id: tool,
|
|
76
|
+
label: tool,
|
|
77
|
+
currentValue: enabledTools.has(tool) ? "enabled" : "disabled",
|
|
78
|
+
values: ["enabled", "disabled"],
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
const container = new Container();
|
|
82
|
+
container.addChild(
|
|
83
|
+
new (class {
|
|
84
|
+
render(_width: number) {
|
|
85
|
+
return [theme.fg("accent", theme.bold("Tool Configuration")), ""];
|
|
86
|
+
}
|
|
87
|
+
invalidate() {}
|
|
88
|
+
})(),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const settingsList = new SettingsList(
|
|
92
|
+
items,
|
|
93
|
+
Math.min(items.length + 2, 15),
|
|
94
|
+
getSettingsListTheme(),
|
|
95
|
+
(id, newValue) => {
|
|
96
|
+
// Update enabled state and apply immediately
|
|
97
|
+
if (newValue === "enabled") {
|
|
98
|
+
enabledTools.add(id);
|
|
99
|
+
} else {
|
|
100
|
+
enabledTools.delete(id);
|
|
101
|
+
}
|
|
102
|
+
applyTools();
|
|
103
|
+
persistState();
|
|
104
|
+
},
|
|
105
|
+
() => {
|
|
106
|
+
// Close dialog
|
|
107
|
+
done(undefined);
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
container.addChild(settingsList);
|
|
112
|
+
|
|
113
|
+
const component = {
|
|
114
|
+
render(width: number) {
|
|
115
|
+
return container.render(width);
|
|
116
|
+
},
|
|
117
|
+
invalidate() {
|
|
118
|
+
container.invalidate();
|
|
119
|
+
},
|
|
120
|
+
handleInput(data: string) {
|
|
121
|
+
settingsList.handleInput?.(data);
|
|
122
|
+
tui.requestRender();
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return component;
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Restore state on session start
|
|
132
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
133
|
+
restoreFromBranch(ctx);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Restore state when navigating the session tree
|
|
137
|
+
pi.on("session_tree", async (_event, ctx) => {
|
|
138
|
+
restoreFromBranch(ctx);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Restore state after branching
|
|
142
|
+
pi.on("session_branch", async (_event, ctx) => {
|
|
143
|
+
restoreFromBranch(ctx);
|
|
144
|
+
});
|
|
145
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-coding-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.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
|
-
"@
|
|
42
|
-
"@mariozechner/pi-
|
|
43
|
-
"@mariozechner/pi-
|
|
41
|
+
"@crosscopy/clipboard": "^0.2.8",
|
|
42
|
+
"@mariozechner/pi-agent-core": "^0.34.0",
|
|
43
|
+
"@mariozechner/pi-ai": "^0.34.0",
|
|
44
|
+
"@mariozechner/pi-tui": "^0.34.0",
|
|
44
45
|
"chalk": "^5.5.0",
|
|
45
46
|
"cli-highlight": "^2.1.11",
|
|
46
47
|
"diff": "^8.0.2",
|