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