feat(coding-agent): add hook API for CLI flags, shortcuts, and tool control

Hook API additions:
- pi.getTools() / pi.setTools(toolNames) - dynamically enable/disable tools
- pi.registerFlag(name, options) / pi.getFlag(name) - register custom CLI flags
- pi.registerShortcut(shortcut, options) - register keyboard shortcuts

Plan mode hook (examples/hooks/plan-mode.ts):
- /plan command or Shift+P shortcut to toggle
- --plan CLI flag to start in plan mode
- Read-only tools: read, bash, grep, find, ls
- Bash restricted to non-destructive commands (blocks rm, mv, git commit, etc.)
- Interactive prompt after each response: execute, stay, or refine
- Shows plan indicator in footer when active
- State persists across sessions
This commit is contained in:
Helmut Januschka 2026-01-03 09:52:13 +01:00
parent 57bba4e32b
commit db312d2eed
13 changed files with 636 additions and 46 deletions

View file

@ -168,6 +168,43 @@ export class HookRunner {
return this.hooks.map((h) => h.path);
}
/**
* Get all CLI flags registered by hooks.
*/
getFlags(): Map<string, import("./loader.js").HookFlag> {
const allFlags = new Map<string, import("./loader.js").HookFlag>();
for (const hook of this.hooks) {
for (const [name, flag] of hook.flags) {
allFlags.set(name, flag);
}
}
return allFlags;
}
/**
* Set a flag value (after CLI parsing).
*/
setFlagValue(name: string, value: boolean | string): void {
for (const hook of this.hooks) {
if (hook.flags.has(name)) {
hook.setFlagValue(name, value);
}
}
}
/**
* Get all keyboard shortcuts registered by hooks.
*/
getShortcuts(): Map<string, import("./loader.js").HookShortcut> {
const allShortcuts = new Map<string, import("./loader.js").HookShortcut>();
for (const hook of this.hooks) {
for (const [key, shortcut] of hook.shortcuts) {
allShortcuts.set(key, shortcut);
}
}
return allShortcuts;
}
/**
* Subscribe to hook errors.
* @returns Unsubscribe function