@mariozechner/pi-coding-agent 0.34.2 → 0.35.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 (251) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +233 -105
  3. package/dist/cli/args.d.ts +3 -4
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +13 -18
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/config.d.ts +2 -2
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +3 -3
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +39 -50
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +166 -197
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  16. package/dist/core/compaction/branch-summarization.js +3 -3
  17. package/dist/core/compaction/branch-summarization.js.map +1 -1
  18. package/dist/core/compaction/compaction.d.ts +1 -1
  19. package/dist/core/compaction/compaction.d.ts.map +1 -1
  20. package/dist/core/compaction/compaction.js +6 -5
  21. package/dist/core/compaction/compaction.js.map +1 -1
  22. package/dist/core/event-bus.d.ts +9 -0
  23. package/dist/core/event-bus.d.ts.map +1 -0
  24. package/dist/core/event-bus.js +25 -0
  25. package/dist/core/event-bus.js.map +1 -0
  26. package/dist/core/exec.d.ts +1 -1
  27. package/dist/core/exec.d.ts.map +1 -1
  28. package/dist/core/exec.js +1 -1
  29. package/dist/core/exec.js.map +1 -1
  30. package/dist/core/extensions/index.d.ts +10 -0
  31. package/dist/core/extensions/index.d.ts.map +1 -0
  32. package/dist/core/extensions/index.js +9 -0
  33. package/dist/core/extensions/index.js.map +1 -0
  34. package/dist/core/extensions/loader.d.ts +21 -0
  35. package/dist/core/extensions/loader.d.ts.map +1 -0
  36. package/dist/core/extensions/loader.js +400 -0
  37. package/dist/core/extensions/loader.js.map +1 -0
  38. package/dist/core/extensions/runner.d.ts +88 -0
  39. package/dist/core/extensions/runner.d.ts.map +1 -0
  40. package/dist/core/{hooks → extensions}/runner.js +52 -141
  41. package/dist/core/extensions/runner.js.map +1 -0
  42. package/dist/core/extensions/types.d.ts +461 -0
  43. package/dist/core/extensions/types.d.ts.map +1 -0
  44. package/dist/core/{hooks → extensions}/types.js +7 -4
  45. package/dist/core/extensions/types.js.map +1 -0
  46. package/dist/core/extensions/wrapper.d.ts +25 -0
  47. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  48. package/dist/core/{hooks/tool-wrapper.js → extensions/wrapper.js} +39 -24
  49. package/dist/core/extensions/wrapper.js.map +1 -0
  50. package/dist/core/index.d.ts +2 -2
  51. package/dist/core/index.d.ts.map +1 -1
  52. package/dist/core/index.js +3 -2
  53. package/dist/core/index.js.map +1 -1
  54. package/dist/core/messages.d.ts +7 -7
  55. package/dist/core/messages.d.ts.map +1 -1
  56. package/dist/core/messages.js +4 -4
  57. package/dist/core/messages.js.map +1 -1
  58. package/dist/core/prompt-templates.d.ts +40 -0
  59. package/dist/core/prompt-templates.d.ts.map +1 -0
  60. package/dist/core/{slash-commands.js → prompt-templates.js} +31 -31
  61. package/dist/core/prompt-templates.js.map +1 -0
  62. package/dist/core/sdk.d.ts +29 -52
  63. package/dist/core/sdk.d.ts.map +1 -1
  64. package/dist/core/sdk.js +111 -211
  65. package/dist/core/sdk.js.map +1 -1
  66. package/dist/core/session-manager.d.ts +17 -17
  67. package/dist/core/session-manager.d.ts.map +1 -1
  68. package/dist/core/session-manager.js +25 -10
  69. package/dist/core/session-manager.js.map +1 -1
  70. package/dist/core/settings-manager.d.ts +3 -6
  71. package/dist/core/settings-manager.d.ts.map +1 -1
  72. package/dist/core/settings-manager.js +4 -11
  73. package/dist/core/settings-manager.js.map +1 -1
  74. package/dist/core/system-prompt.d.ts.map +1 -1
  75. package/dist/core/system-prompt.js +4 -2
  76. package/dist/core/system-prompt.js.map +1 -1
  77. package/dist/index.d.ts +4 -5
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +5 -6
  80. package/dist/index.js.map +1 -1
  81. package/dist/main.d.ts.map +1 -1
  82. package/dist/main.js +36 -33
  83. package/dist/main.js.map +1 -1
  84. package/dist/migrations.d.ts +7 -2
  85. package/dist/migrations.d.ts.map +1 -1
  86. package/dist/migrations.js +93 -4
  87. package/dist/migrations.js.map +1 -1
  88. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  89. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/bordered-loader.js +1 -1
  91. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  92. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  93. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  94. package/dist/modes/interactive/components/branch-summary-message.js +1 -1
  95. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  96. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  97. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  99. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  100. package/dist/modes/interactive/components/custom-editor.d.ts +2 -2
  101. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/custom-editor.js +4 -4
  103. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  104. package/dist/modes/interactive/components/custom-message.d.ts +18 -0
  105. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  106. package/dist/modes/interactive/components/{hook-message.js → custom-message.js} +3 -3
  107. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  108. package/dist/modes/interactive/components/dynamic-border.d.ts +2 -2
  109. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/dynamic-border.js +2 -2
  111. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  112. package/dist/modes/interactive/components/{hook-editor.d.ts → extension-editor.d.ts} +3 -3
  113. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  114. package/dist/modes/interactive/components/{hook-editor.js → extension-editor.js} +4 -4
  115. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  116. package/dist/modes/interactive/components/{hook-input.d.ts → extension-input.d.ts} +3 -3
  117. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  118. package/dist/modes/interactive/components/{hook-input.js → extension-input.js} +3 -3
  119. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  120. package/dist/modes/interactive/components/{hook-selector.d.ts → extension-selector.d.ts} +3 -3
  121. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  122. package/dist/modes/interactive/components/{hook-selector.js → extension-selector.js} +3 -3
  123. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  124. package/dist/modes/interactive/components/footer.d.ts +3 -3
  125. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  126. package/dist/modes/interactive/components/footer.js +8 -8
  127. package/dist/modes/interactive/components/footer.js.map +1 -1
  128. package/dist/modes/interactive/components/tool-execution.d.ts +3 -3
  129. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  130. package/dist/modes/interactive/components/tool-execution.js +9 -9
  131. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  132. package/dist/modes/interactive/interactive-mode.d.ts +37 -44
  133. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.js +143 -189
  135. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  136. package/dist/modes/print-mode.d.ts.map +1 -1
  137. package/dist/modes/print-mode.js +10 -33
  138. package/dist/modes/print-mode.js.map +1 -1
  139. package/dist/modes/rpc/rpc-client.d.ts +3 -3
  140. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  141. package/dist/modes/rpc/rpc-client.js +3 -3
  142. package/dist/modes/rpc/rpc-client.js.map +1 -1
  143. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  144. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  145. package/dist/modes/rpc/rpc-mode.js +33 -57
  146. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  147. package/dist/modes/rpc/rpc-types.d.ts +16 -16
  148. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  149. package/dist/modes/rpc/rpc-types.js.map +1 -1
  150. package/docs/extensions.md +1053 -0
  151. package/docs/rpc.md +4 -4
  152. package/docs/sdk.md +62 -93
  153. package/docs/session.md +22 -19
  154. package/docs/skills.md +1 -1
  155. package/docs/tui.md +1 -1
  156. package/examples/README.md +9 -15
  157. package/examples/extensions/README.md +141 -0
  158. package/examples/{hooks → extensions}/auto-commit-on-exit.ts +3 -3
  159. package/examples/extensions/chalk-logger.ts +26 -0
  160. package/examples/{hooks → extensions}/confirm-destructive.ts +3 -3
  161. package/examples/{hooks → extensions}/custom-compaction.ts +6 -6
  162. package/examples/{hooks → extensions}/dirty-repo-guard.ts +8 -4
  163. package/examples/{hooks → extensions}/file-trigger.ts +3 -3
  164. package/examples/{hooks → extensions}/git-checkpoint.ts +3 -3
  165. package/examples/{hooks → extensions}/handoff.ts +3 -3
  166. package/examples/extensions/hello.ts +25 -0
  167. package/examples/{hooks → extensions}/permission-gate.ts +3 -3
  168. package/examples/{hooks → extensions}/pirate.ts +5 -5
  169. package/examples/{hooks → extensions}/plan-mode.ts +6 -6
  170. package/examples/{hooks → extensions}/protected-paths.ts +3 -3
  171. package/examples/{hooks → extensions}/qna.ts +3 -3
  172. package/examples/{custom-tools/question/index.ts → extensions/question.ts} +13 -17
  173. package/examples/{hooks → extensions}/snake.ts +3 -3
  174. package/examples/{hooks → extensions}/status-line.ts +3 -3
  175. package/examples/{custom-tools → extensions}/subagent/README.md +15 -15
  176. package/examples/{custom-tools → extensions}/subagent/index.ts +22 -43
  177. package/examples/{custom-tools/todo/index.ts → extensions/todo.ts} +122 -39
  178. package/examples/{hooks → extensions}/tools.ts +5 -5
  179. package/examples/extensions/with-deps/index.ts +40 -0
  180. package/examples/extensions/with-deps/package-lock.json +31 -0
  181. package/examples/extensions/with-deps/package.json +16 -0
  182. package/examples/sdk/01-minimal.ts +1 -1
  183. package/examples/sdk/05-tools.ts +7 -41
  184. package/examples/sdk/06-extensions.ts +81 -0
  185. package/examples/sdk/08-prompt-templates.ts +42 -0
  186. package/examples/sdk/12-full-control.ts +10 -29
  187. package/examples/sdk/README.md +5 -5
  188. package/package.json +4 -4
  189. package/dist/core/custom-tools/index.d.ts +0 -7
  190. package/dist/core/custom-tools/index.d.ts.map +0 -1
  191. package/dist/core/custom-tools/index.js +0 -6
  192. package/dist/core/custom-tools/index.js.map +0 -1
  193. package/dist/core/custom-tools/loader.d.ts +0 -30
  194. package/dist/core/custom-tools/loader.d.ts.map +0 -1
  195. package/dist/core/custom-tools/loader.js +0 -276
  196. package/dist/core/custom-tools/loader.js.map +0 -1
  197. package/dist/core/custom-tools/types.d.ts +0 -144
  198. package/dist/core/custom-tools/types.d.ts.map +0 -1
  199. package/dist/core/custom-tools/types.js +0 -8
  200. package/dist/core/custom-tools/types.js.map +0 -1
  201. package/dist/core/custom-tools/wrapper.d.ts +0 -15
  202. package/dist/core/custom-tools/wrapper.d.ts.map +0 -1
  203. package/dist/core/custom-tools/wrapper.js +0 -23
  204. package/dist/core/custom-tools/wrapper.js.map +0 -1
  205. package/dist/core/hooks/index.d.ts +0 -6
  206. package/dist/core/hooks/index.d.ts.map +0 -1
  207. package/dist/core/hooks/index.js +0 -6
  208. package/dist/core/hooks/index.js.map +0 -1
  209. package/dist/core/hooks/loader.d.ts +0 -146
  210. package/dist/core/hooks/loader.d.ts.map +0 -1
  211. package/dist/core/hooks/loader.js +0 -275
  212. package/dist/core/hooks/loader.js.map +0 -1
  213. package/dist/core/hooks/runner.d.ts +0 -173
  214. package/dist/core/hooks/runner.d.ts.map +0 -1
  215. package/dist/core/hooks/runner.js.map +0 -1
  216. package/dist/core/hooks/tool-wrapper.d.ts +0 -17
  217. package/dist/core/hooks/tool-wrapper.d.ts.map +0 -1
  218. package/dist/core/hooks/tool-wrapper.js.map +0 -1
  219. package/dist/core/hooks/types.d.ts +0 -767
  220. package/dist/core/hooks/types.d.ts.map +0 -1
  221. package/dist/core/hooks/types.js.map +0 -1
  222. package/dist/core/slash-commands.d.ts +0 -40
  223. package/dist/core/slash-commands.d.ts.map +0 -1
  224. package/dist/core/slash-commands.js.map +0 -1
  225. package/dist/modes/interactive/components/hook-editor.d.ts.map +0 -1
  226. package/dist/modes/interactive/components/hook-editor.js.map +0 -1
  227. package/dist/modes/interactive/components/hook-input.d.ts.map +0 -1
  228. package/dist/modes/interactive/components/hook-input.js.map +0 -1
  229. package/dist/modes/interactive/components/hook-message.d.ts +0 -18
  230. package/dist/modes/interactive/components/hook-message.d.ts.map +0 -1
  231. package/dist/modes/interactive/components/hook-message.js.map +0 -1
  232. package/dist/modes/interactive/components/hook-selector.d.ts.map +0 -1
  233. package/dist/modes/interactive/components/hook-selector.js.map +0 -1
  234. package/docs/custom-tools.md +0 -514
  235. package/docs/extension-loading.md +0 -1004
  236. package/docs/hooks.md +0 -979
  237. package/docs/session-tree-plan.md +0 -441
  238. package/examples/custom-tools/README.md +0 -114
  239. package/examples/custom-tools/hello/index.ts +0 -21
  240. package/examples/hooks/README.md +0 -60
  241. package/examples/hooks/todo/index.ts +0 -134
  242. package/examples/sdk/06-hooks.ts +0 -61
  243. package/examples/sdk/08-slash-commands.ts +0 -42
  244. /package/examples/{custom-tools → extensions}/subagent/agents/planner.md +0 -0
  245. /package/examples/{custom-tools → extensions}/subagent/agents/reviewer.md +0 -0
  246. /package/examples/{custom-tools → extensions}/subagent/agents/scout.md +0 -0
  247. /package/examples/{custom-tools → extensions}/subagent/agents/worker.md +0 -0
  248. /package/examples/{custom-tools → extensions}/subagent/agents.ts +0 -0
  249. /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/implement-and-review.md +0 -0
  250. /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/implement.md +0 -0
  251. /package/examples/{custom-tools/subagent/commands → extensions/subagent/prompts}/scout-and-plan.md +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,206 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.35.0] - 2026-01-05
4
+
5
+ This release unifies hooks and custom tools into a single "extensions" system and renames "slash commands" to "prompt templates". ([#454](https://github.com/badlogic/pi-mono/issues/454))
6
+
7
+ **Before migrating, read:**
8
+ - [docs/extensions.md](docs/extensions.md) - Full API reference
9
+ - [README.md](README.md) - Extensions section with examples
10
+ - [examples/extensions/](examples/extensions/) - Working examples
11
+
12
+ ### Extensions Migration
13
+
14
+ Hooks and custom tools are now unified as **extensions**. Both were TypeScript modules exporting a factory function that receives an API object. Now there's one concept, one discovery location, one CLI flag, one settings.json entry.
15
+
16
+ **Automatic migration:**
17
+ - `commands/` directories are automatically renamed to `prompts/` on startup (both `~/.pi/agent/commands/` and `.pi/commands/`)
18
+
19
+ **Manual migration required:**
20
+ 1. Move files from `hooks/` and `tools/` directories to `extensions/` (deprecation warnings shown on startup)
21
+ 2. Update imports and type names in your extension code
22
+ 3. Update `settings.json` if you have explicit hook and custom tool paths configured
23
+
24
+ **Directory changes:**
25
+ ```
26
+ # Before
27
+ ~/.pi/agent/hooks/*.ts → ~/.pi/agent/extensions/*.ts
28
+ ~/.pi/agent/tools/*.ts → ~/.pi/agent/extensions/*.ts
29
+ .pi/hooks/*.ts → .pi/extensions/*.ts
30
+ .pi/tools/*.ts → .pi/extensions/*.ts
31
+ ```
32
+
33
+ **Extension discovery rules** (in `extensions/` directories):
34
+ 1. **Direct files:** `extensions/*.ts` or `*.js` → loaded directly
35
+ 2. **Subdirectory with index:** `extensions/myext/index.ts` → loaded as single extension
36
+ 3. **Subdirectory with package.json:** `extensions/myext/package.json` with `"pi"` field → loads declared paths
37
+
38
+ ```json
39
+ // extensions/my-package/package.json
40
+ {
41
+ "name": "my-extension-package",
42
+ "dependencies": { "zod": "^3.0.0" },
43
+ "pi": {
44
+ "extensions": ["./src/main.ts", "./src/tools.ts"]
45
+ }
46
+ }
47
+ ```
48
+
49
+ No recursion beyond one level. Complex packages must use the `package.json` manifest. Dependencies are resolved via jiti, and extensions can be published to and installed from npm.
50
+
51
+ **Type renames:**
52
+ - `HookAPI` → `ExtensionAPI`
53
+ - `HookContext` → `ExtensionContext`
54
+ - `HookCommandContext` → `ExtensionCommandContext`
55
+ - `HookUIContext` → `ExtensionUIContext`
56
+ - `CustomToolAPI` → `ExtensionAPI` (merged)
57
+ - `CustomToolContext` → `ExtensionContext` (merged)
58
+ - `CustomToolUIContext` → `ExtensionUIContext`
59
+ - `CustomTool` → `ToolDefinition`
60
+ - `CustomToolFactory` → `ExtensionFactory`
61
+ - `HookMessage` → `CustomMessage`
62
+
63
+ **Import changes:**
64
+ ```typescript
65
+ // Before (hook)
66
+ import type { HookAPI, HookContext } from "@mariozechner/pi-coding-agent";
67
+ export default function (pi: HookAPI) { ... }
68
+
69
+ // Before (custom tool)
70
+ import type { CustomToolFactory } from "@mariozechner/pi-coding-agent";
71
+ const factory: CustomToolFactory = (pi) => ({ name: "my_tool", ... });
72
+ export default factory;
73
+
74
+ // After (both are now extensions)
75
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
76
+ export default function (pi: ExtensionAPI) {
77
+ pi.on("tool_call", async (event, ctx) => { ... });
78
+ pi.registerTool({ name: "my_tool", ... });
79
+ }
80
+ ```
81
+
82
+ **Custom tools now have full context access.** Tools registered via `pi.registerTool()` now receive the same `ctx` object that event handlers receive. Previously, custom tools had limited context. Now all extension code shares the same capabilities:
83
+
84
+ - `pi.registerTool()` - Register tools the LLM can call
85
+ - `pi.registerCommand()` - Register commands like `/mycommand`
86
+ - `pi.registerShortcut()` - Register keyboard shortcuts (shown in `/hotkeys`)
87
+ - `pi.registerFlag()` - Register CLI flags (shown in `--help`)
88
+ - `pi.registerMessageRenderer()` - Custom TUI rendering for message types
89
+ - `pi.on()` - Subscribe to lifecycle events (tool_call, session_start, etc.)
90
+ - `pi.sendMessage()` - Inject messages into the conversation
91
+ - `pi.appendEntry()` - Persist custom data in session (survives restart/branch)
92
+ - `pi.exec()` - Run shell commands
93
+ - `pi.getActiveTools()` / `pi.setActiveTools()` - Dynamic tool enable/disable
94
+ - `pi.getAllTools()` - List all available tools
95
+ - `pi.events` - Event bus for cross-extension communication
96
+ - `ctx.ui.confirm()` / `select()` / `input()` - User prompts
97
+ - `ctx.ui.notify()` - Toast notifications
98
+ - `ctx.ui.setStatus()` - Persistent status in footer (multiple extensions can set their own)
99
+ - `ctx.ui.setWidget()` - Widget display above editor
100
+ - `ctx.ui.setTitle()` - Set terminal window title
101
+ - `ctx.ui.custom()` - Full TUI component with keyboard handling
102
+ - `ctx.ui.editor()` - Multi-line text editor with external editor support
103
+ - `ctx.sessionManager` - Read session entries, get branch history
104
+
105
+ **Settings changes:**
106
+ ```json
107
+ // Before
108
+ {
109
+ "hooks": ["./my-hook.ts"],
110
+ "customTools": ["./my-tool.ts"]
111
+ }
112
+
113
+ // After
114
+ {
115
+ "extensions": ["./my-extension.ts"]
116
+ }
117
+ ```
118
+
119
+ **CLI changes:**
120
+ ```bash
121
+ # Before
122
+ pi --hook ./safety.ts --tool ./todo.ts
123
+
124
+ # After
125
+ pi --extension ./safety.ts -e ./todo.ts
126
+ ```
127
+
128
+ ### Prompt Templates Migration
129
+
130
+ "Slash commands" (markdown files defining reusable prompts invoked via `/name`) are renamed to "prompt templates" to avoid confusion with extension-registered commands.
131
+
132
+ **Automatic migration:** The `commands/` directory is automatically renamed to `prompts/` on startup (if `prompts/` doesn't exist). Works for both regular directories and symlinks.
133
+
134
+ **Directory changes:**
135
+ ```
136
+ ~/.pi/agent/commands/*.md → ~/.pi/agent/prompts/*.md
137
+ .pi/commands/*.md → .pi/prompts/*.md
138
+ ```
139
+
140
+ **SDK type renames:**
141
+ - `FileSlashCommand` → `PromptTemplate`
142
+ - `LoadSlashCommandsOptions` → `LoadPromptTemplatesOptions`
143
+
144
+ **SDK function renames:**
145
+ - `discoverSlashCommands()` → `discoverPromptTemplates()`
146
+ - `loadSlashCommands()` → `loadPromptTemplates()`
147
+ - `expandSlashCommand()` → `expandPromptTemplate()`
148
+ - `getCommandsDir()` → `getPromptsDir()`
149
+
150
+ **SDK option renames:**
151
+ - `CreateAgentSessionOptions.slashCommands` → `.promptTemplates`
152
+ - `AgentSession.fileCommands` → `.promptTemplates`
153
+ - `PromptOptions.expandSlashCommands` → `.expandPromptTemplates`
154
+
155
+ ### SDK Migration
156
+
157
+ **Discovery functions:**
158
+ - `discoverAndLoadHooks()` → `discoverAndLoadExtensions()`
159
+ - `discoverAndLoadCustomTools()` → merged into `discoverAndLoadExtensions()`
160
+ - `loadHooks()` → `loadExtensions()`
161
+ - `loadCustomTools()` → merged into `loadExtensions()`
162
+
163
+ **Runner and wrapper:**
164
+ - `HookRunner` → `ExtensionRunner`
165
+ - `wrapToolsWithHooks()` → `wrapToolsWithExtensions()`
166
+ - `wrapToolWithHooks()` → `wrapToolWithExtensions()`
167
+
168
+ **CreateAgentSessionOptions:**
169
+ - `.hooks` → removed (use `.additionalExtensionPaths` for paths)
170
+ - `.additionalHookPaths` → `.additionalExtensionPaths`
171
+ - `.preloadedHooks` → `.preloadedExtensions`
172
+ - `.customTools` type changed: `Array<{ path?; tool: CustomTool }>` → `ToolDefinition[]`
173
+ - `.additionalCustomToolPaths` → merged into `.additionalExtensionPaths`
174
+ - `.slashCommands` → `.promptTemplates`
175
+
176
+ **AgentSession:**
177
+ - `.hookRunner` → `.extensionRunner`
178
+ - `.fileCommands` → `.promptTemplates`
179
+ - `.sendHookMessage()` → `.sendCustomMessage()`
180
+
181
+ ### Session Migration
182
+
183
+ **Automatic.** Session version bumped from 2 to 3. Existing sessions are migrated on first load:
184
+ - Message role `"hookMessage"` → `"custom"`
185
+
186
+ ### Breaking Changes
187
+
188
+ - **Settings:** `hooks` and `customTools` arrays replaced with single `extensions` array
189
+ - **CLI:** `--hook` and `--tool` flags replaced with `--extension` / `-e`
190
+ - **Directories:** `hooks/`, `tools/` → `extensions/`; `commands/` → `prompts/`
191
+ - **Types:** See type renames above
192
+ - **SDK:** See SDK migration above
193
+
194
+ ### Changed
195
+
196
+ - Extensions can have their own `package.json` with dependencies (resolved via jiti)
197
+ - Documentation: `docs/hooks.md` and `docs/custom-tools.md` merged into `docs/extensions.md`
198
+ - Examples: `examples/hooks/` and `examples/custom-tools/` merged into `examples/extensions/`
199
+ - README: Extensions section expanded with custom tools, commands, events, state persistence, shortcuts, flags, and UI examples
200
+ - SDK: `customTools` option now accepts `ToolDefinition[]` directly (simplified from `Array<{ path?, tool }>`)
201
+ - SDK: `extensions` option accepts `ExtensionFactory[]` for inline extensions
202
+ - SDK: `additionalExtensionPaths` replaces both `additionalHookPaths` and `additionalCustomToolPaths`
203
+
3
204
  ## [0.34.2] - 2026-01-04
4
205
 
5
206
  ## [0.34.1] - 2026-01-04
@@ -41,6 +242,9 @@
41
242
  - Tool registry now contains all built-in tools (read, bash, edit, write, grep, find, ls) even when `--tools` limits the initially active set. Hooks can enable any tool from the registry via `pi.setActiveTools()`.
42
243
  - System prompt now automatically rebuilds when tools change via `setActiveTools()`, updating tool descriptions and guidelines to match the new tool set
43
244
  - Hook errors now display full stack traces for easier debugging
245
+ - Event bus (`pi.events`) for tool/hook communication: shared pub/sub between custom tools and hooks
246
+ - Custom tools now have `pi.sendMessage()` to send messages directly to the agent session without needing the event bus
247
+ - `sendMessage()` supports `deliverAs: "nextTurn"` to queue messages for the next user prompt
44
248
 
45
249
  ### Changed
46
250