@zhushanwen/pi-unified-hooks 0.0.1
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/README.md +55 -0
- package/index.ts +1 -0
- package/package.json +24 -0
- package/src/hooks/tool-error-handler.ts +15 -0
- package/src/index.ts +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# unified-hooks — Unified Hooks Extension
|
|
2
|
+
|
|
3
|
+
Collect scattered hooks in one place for easy maintenance. Each hook is a self-contained module that can be enabled/disabled independently.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
ln -s /path/to/xyz-pi-extensions/unified-hooks ~/.pi/agent/extensions/unified-hooks
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Available Hooks
|
|
12
|
+
|
|
13
|
+
### edit-whitespace-autofix
|
|
14
|
+
|
|
15
|
+
When edit tool fails due to whitespace mismatch, injects a steering message that tells the AI to fix whitespace and retry.
|
|
16
|
+
|
|
17
|
+
**Trigger patterns:**
|
|
18
|
+
- `Could not find the exact text`
|
|
19
|
+
- `oldText must match exactly`
|
|
20
|
+
- `Could not find edits[`
|
|
21
|
+
|
|
22
|
+
**Behavior:**
|
|
23
|
+
1. Detect whitespace mismatch error from edit tool
|
|
24
|
+
2. Extract the file path from tool args
|
|
25
|
+
3. Inject steer message with `fix_whitespace.py --fix <file>` command
|
|
26
|
+
4. AI automatically fixes whitespace and retries the edit
|
|
27
|
+
|
|
28
|
+
### tool-error-handler
|
|
29
|
+
|
|
30
|
+
Logs all tool execution errors to console for debugging.
|
|
31
|
+
|
|
32
|
+
## Adding New Hooks
|
|
33
|
+
|
|
34
|
+
1. Create `src/hooks/my-hook.ts`:
|
|
35
|
+
```typescript
|
|
36
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
37
|
+
|
|
38
|
+
export function setupMyHook(pi: ExtensionAPI): void {
|
|
39
|
+
pi.on("tool_execution_end", async (event) => {
|
|
40
|
+
if (event.toolName === "edit" && event.isError) {
|
|
41
|
+
// Your logic
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
2. Register in `src/index.ts` hookModules array
|
|
48
|
+
|
|
49
|
+
3. Type check: `npx tsc --noEmit`
|
|
50
|
+
|
|
51
|
+
## Important API Notes
|
|
52
|
+
|
|
53
|
+
- Use `pi.sendUserMessage()` in event handlers, **not** `ctx.sendUserMessage()` (only available in command context)
|
|
54
|
+
- `tool_execution_end` event has `{ toolCallId, toolName, args, result, isError }`
|
|
55
|
+
- Inject direct instructions in steer messages, don't try to invoke `/skill-name` via text
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./src/index.ts";
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zhushanwen/pi-unified-hooks",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Unified hooks extension - collect scattered hooks in one place for easy maintenance",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pi",
|
|
9
|
+
"extension",
|
|
10
|
+
"hooks"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"typebox": "*",
|
|
15
|
+
"@mariozechner/pi-coding-agent": "*"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src/",
|
|
19
|
+
"index.ts"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"typecheck": "npx tsc --noEmit"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Error Handler Hook
|
|
3
|
+
*
|
|
4
|
+
* Logs tool execution errors for debugging. Can be extended to handle
|
|
5
|
+
* specific error patterns with contextual recovery.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
9
|
+
|
|
10
|
+
export function setupToolErrorHandler(pi: ExtensionAPI): void {
|
|
11
|
+
pi.on("tool_execution_end", async (event) => {
|
|
12
|
+
if (!event.isError) return;
|
|
13
|
+
console.log(`[unified-hooks] ${event.toolName} error (callId=${event.toolCallId})`);
|
|
14
|
+
});
|
|
15
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Hooks Extension
|
|
3
|
+
*
|
|
4
|
+
* Collects scattered hooks in one place for easy maintenance.
|
|
5
|
+
* Each hook is a self-contained module that can be enabled/disabled independently.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
9
|
+
|
|
10
|
+
// Re-export hook modules for easy access
|
|
11
|
+
export { setupToolErrorHandler } from "./hooks/tool-error-handler";
|
|
12
|
+
|
|
13
|
+
import { setupToolErrorHandler } from "./hooks/tool-error-handler";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extension factory - registers all unified hooks
|
|
17
|
+
*/
|
|
18
|
+
export default function unifiedHooksExtension(pi: ExtensionAPI): void {
|
|
19
|
+
// Initialize hook registry
|
|
20
|
+
const hooks: Array<{ name: string; enabled: boolean }> = [];
|
|
21
|
+
|
|
22
|
+
// edit-stale-content-guard removed: pi-hashline-edit replaces built-in edit
|
|
23
|
+
// with hash-anchor mode, making oldText-based guard unreachable
|
|
24
|
+
const hookModules = [
|
|
25
|
+
{ name: "tool-error-handler", setup: setupToolErrorHandler },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
for (const hook of hookModules) {
|
|
29
|
+
try {
|
|
30
|
+
hook.setup(pi);
|
|
31
|
+
hooks.push({ name: hook.name, enabled: true });
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error(`[unified-hooks] Failed to setup ${hook.name}:`, err);
|
|
34
|
+
hooks.push({ name: hook.name, enabled: false });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Log hook status on session start for debugging
|
|
39
|
+
pi.on("session_start", () => {
|
|
40
|
+
const enabled = hooks.filter((h) => h.enabled).map((h) => h.name);
|
|
41
|
+
const disabled = hooks.filter((h) => !h.enabled).map((h) => h.name);
|
|
42
|
+
console.log(
|
|
43
|
+
`[unified-hooks] Loaded: ${enabled.join(", ") || "(none)"}${
|
|
44
|
+
disabled.length ? ` | Failed: ${disabled.join(", ")}` : ""
|
|
45
|
+
}`
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
}
|