@mariozechner/pi-coding-agent 0.49.3 → 0.50.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 (207) hide show
  1. package/CHANGELOG.md +99 -1
  2. package/README.md +310 -1230
  3. package/dist/cli/args.d.ts +5 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +57 -23
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/config-selector.d.ts +14 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +31 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/session-picker.d.ts.map +1 -1
  12. package/dist/cli/session-picker.js +1 -1
  13. package/dist/cli/session-picker.js.map +1 -1
  14. package/dist/core/agent-session.d.ts +53 -34
  15. package/dist/core/agent-session.d.ts.map +1 -1
  16. package/dist/core/agent-session.js +262 -67
  17. package/dist/core/agent-session.js.map +1 -1
  18. package/dist/core/auth-storage.d.ts +8 -18
  19. package/dist/core/auth-storage.d.ts.map +1 -1
  20. package/dist/core/auth-storage.js +39 -55
  21. package/dist/core/auth-storage.js.map +1 -1
  22. package/dist/core/bash-executor.d.ts.map +1 -1
  23. package/dist/core/bash-executor.js +2 -1
  24. package/dist/core/bash-executor.js.map +1 -1
  25. package/dist/core/diagnostics.d.ts +15 -0
  26. package/dist/core/diagnostics.d.ts.map +1 -0
  27. package/dist/core/diagnostics.js +2 -0
  28. package/dist/core/diagnostics.js.map +1 -0
  29. package/dist/core/export-html/template.css +9 -0
  30. package/dist/core/export-html/template.js +6 -4
  31. package/dist/core/extensions/index.d.ts +1 -1
  32. package/dist/core/extensions/index.d.ts.map +1 -1
  33. package/dist/core/extensions/index.js.map +1 -1
  34. package/dist/core/extensions/loader.d.ts +1 -1
  35. package/dist/core/extensions/loader.d.ts.map +1 -1
  36. package/dist/core/extensions/loader.js +10 -1
  37. package/dist/core/extensions/loader.js.map +1 -1
  38. package/dist/core/extensions/runner.d.ts +9 -3
  39. package/dist/core/extensions/runner.d.ts.map +1 -1
  40. package/dist/core/extensions/runner.js +39 -12
  41. package/dist/core/extensions/runner.js.map +1 -1
  42. package/dist/core/extensions/types.d.ts +112 -1
  43. package/dist/core/extensions/types.d.ts.map +1 -1
  44. package/dist/core/extensions/types.js.map +1 -1
  45. package/dist/core/footer-data-provider.d.ts +9 -2
  46. package/dist/core/footer-data-provider.d.ts.map +1 -1
  47. package/dist/core/footer-data-provider.js +13 -0
  48. package/dist/core/footer-data-provider.js.map +1 -1
  49. package/dist/core/model-registry.d.ts +42 -2
  50. package/dist/core/model-registry.d.ts.map +1 -1
  51. package/dist/core/model-registry.js +154 -44
  52. package/dist/core/model-registry.js.map +1 -1
  53. package/dist/core/model-resolver.d.ts.map +1 -1
  54. package/dist/core/model-resolver.js +3 -2
  55. package/dist/core/model-resolver.js.map +1 -1
  56. package/dist/core/package-manager.d.ts +129 -0
  57. package/dist/core/package-manager.d.ts.map +1 -0
  58. package/dist/core/package-manager.js +1148 -0
  59. package/dist/core/package-manager.js.map +1 -0
  60. package/dist/core/prompt-templates.d.ts +6 -0
  61. package/dist/core/prompt-templates.d.ts.map +1 -1
  62. package/dist/core/prompt-templates.js +114 -54
  63. package/dist/core/prompt-templates.js.map +1 -1
  64. package/dist/core/resource-loader.d.ts +160 -0
  65. package/dist/core/resource-loader.d.ts.map +1 -0
  66. package/dist/core/resource-loader.js +604 -0
  67. package/dist/core/resource-loader.js.map +1 -0
  68. package/dist/core/sdk.d.ts +14 -105
  69. package/dist/core/sdk.d.ts.map +1 -1
  70. package/dist/core/sdk.js +52 -304
  71. package/dist/core/sdk.js.map +1 -1
  72. package/dist/core/session-manager.d.ts.map +1 -1
  73. package/dist/core/session-manager.js +45 -1
  74. package/dist/core/session-manager.js.map +1 -1
  75. package/dist/core/settings-manager.d.ts +34 -16
  76. package/dist/core/settings-manager.d.ts.map +1 -1
  77. package/dist/core/settings-manager.js +104 -25
  78. package/dist/core/settings-manager.js.map +1 -1
  79. package/dist/core/skills.d.ts +18 -10
  80. package/dist/core/skills.d.ts.map +1 -1
  81. package/dist/core/skills.js +126 -93
  82. package/dist/core/skills.js.map +1 -1
  83. package/dist/core/system-prompt.d.ts +3 -27
  84. package/dist/core/system-prompt.d.ts.map +1 -1
  85. package/dist/core/system-prompt.js +16 -103
  86. package/dist/core/system-prompt.js.map +1 -1
  87. package/dist/core/tools/bash.d.ts.map +1 -1
  88. package/dist/core/tools/bash.js +2 -1
  89. package/dist/core/tools/bash.js.map +1 -1
  90. package/dist/core/tools/read.d.ts.map +1 -1
  91. package/dist/core/tools/read.js +4 -4
  92. package/dist/core/tools/read.js.map +1 -1
  93. package/dist/index.d.ts +12 -7
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +8 -6
  96. package/dist/index.js.map +1 -1
  97. package/dist/main.d.ts.map +1 -1
  98. package/dist/main.js +209 -97
  99. package/dist/main.js.map +1 -1
  100. package/dist/modes/interactive/components/bordered-loader.d.ts +5 -1
  101. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/bordered-loader.js +29 -9
  103. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  104. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  105. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  106. package/dist/modes/interactive/components/config-selector.js +468 -0
  107. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  108. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  109. package/dist/modes/interactive/components/footer.js +4 -0
  110. package/dist/modes/interactive/components/footer.js.map +1 -1
  111. package/dist/modes/interactive/components/index.d.ts +1 -0
  112. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  113. package/dist/modes/interactive/components/index.js +1 -0
  114. package/dist/modes/interactive/components/index.js.map +1 -1
  115. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  116. package/dist/modes/interactive/components/oauth-selector.js +3 -4
  117. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  118. package/dist/modes/interactive/components/session-selector.d.ts +18 -1
  119. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  120. package/dist/modes/interactive/components/session-selector.js +195 -87
  121. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  122. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  123. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  124. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  125. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  126. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  127. package/dist/modes/interactive/components/tool-execution.js +5 -5
  128. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  129. package/dist/modes/interactive/interactive-mode.d.ts +42 -2
  130. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  131. package/dist/modes/interactive/interactive-mode.js +535 -200
  132. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  133. package/dist/modes/interactive/theme/dark.json +1 -1
  134. package/dist/modes/interactive/theme/light.json +1 -1
  135. package/dist/modes/interactive/theme/theme-schema.json +8 -1
  136. package/dist/modes/interactive/theme/theme.d.ts +8 -1
  137. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  138. package/dist/modes/interactive/theme/theme.js +72 -25
  139. package/dist/modes/interactive/theme/theme.js.map +1 -1
  140. package/dist/modes/print-mode.d.ts.map +1 -1
  141. package/dist/modes/print-mode.js +25 -89
  142. package/dist/modes/print-mode.js.map +1 -1
  143. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  144. package/dist/modes/rpc/rpc-mode.js +32 -92
  145. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  146. package/dist/utils/git.d.ts +2 -0
  147. package/dist/utils/git.d.ts.map +1 -0
  148. package/dist/utils/git.js +6 -0
  149. package/dist/utils/git.js.map +1 -0
  150. package/dist/utils/shell.d.ts +1 -0
  151. package/dist/utils/shell.d.ts.map +1 -1
  152. package/dist/utils/shell.js +14 -1
  153. package/dist/utils/shell.js.map +1 -1
  154. package/dist/utils/sleep.d.ts +5 -0
  155. package/dist/utils/sleep.d.ts.map +1 -0
  156. package/dist/utils/sleep.js +17 -0
  157. package/dist/utils/sleep.js.map +1 -0
  158. package/docs/compaction.md +23 -21
  159. package/docs/custom-provider.md +538 -0
  160. package/docs/development.md +69 -0
  161. package/docs/extensions.md +180 -118
  162. package/docs/images/doom-extension.png +0 -0
  163. package/docs/images/interactive-mode.png +0 -0
  164. package/docs/images/tree-view.png +0 -0
  165. package/docs/json.md +79 -0
  166. package/docs/keybindings.md +162 -0
  167. package/docs/models.md +193 -0
  168. package/docs/packages.md +163 -0
  169. package/docs/prompt-templates.md +67 -0
  170. package/docs/providers.md +147 -0
  171. package/docs/sdk.md +111 -178
  172. package/docs/session.md +167 -16
  173. package/docs/settings.md +216 -0
  174. package/docs/shell-aliases.md +13 -0
  175. package/docs/skills.md +111 -202
  176. package/docs/terminal-setup.md +65 -0
  177. package/docs/themes.md +295 -0
  178. package/docs/tui.md +36 -5
  179. package/docs/windows.md +17 -0
  180. package/examples/README.md +1 -0
  181. package/examples/extensions/README.md +22 -2
  182. package/examples/extensions/bookmark.ts +50 -0
  183. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  184. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  185. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  186. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  187. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  188. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  189. package/examples/extensions/doom-overlay/doom/build.sh +1 -1
  190. package/examples/extensions/event-bus.ts +43 -0
  191. package/examples/extensions/message-renderer.ts +59 -0
  192. package/examples/extensions/session-name.ts +27 -0
  193. package/examples/extensions/with-deps/package-lock.json +2 -2
  194. package/examples/extensions/with-deps/package.json +1 -1
  195. package/examples/sdk/02-custom-model.ts +3 -3
  196. package/examples/sdk/03-custom-prompt.ts +20 -9
  197. package/examples/sdk/04-skills.ts +26 -27
  198. package/examples/sdk/06-extensions.ts +15 -6
  199. package/examples/sdk/07-context-files.ts +22 -18
  200. package/examples/sdk/08-prompt-templates.ts +19 -14
  201. package/examples/sdk/09-api-keys-and-oauth.ts +5 -12
  202. package/examples/sdk/10-settings.ts +3 -3
  203. package/examples/sdk/12-full-control.ts +16 -7
  204. package/examples/sdk/README.md +24 -30
  205. package/package.json +4 -4
  206. package/docs/theme.md +0 -617
  207. package/examples/extensions/chalk-logger.ts +0 -26
@@ -0,0 +1,69 @@
1
+ # Development
2
+
3
+ See [AGENTS.md](../../../AGENTS.md) for additional guidelines.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/badlogic/pi-mono
9
+ cd pi-mono
10
+ npm install
11
+ npm run build
12
+ ```
13
+
14
+ Run from source:
15
+
16
+ ```bash
17
+ ./pi-test.sh
18
+ ```
19
+
20
+ ## Forking / Rebranding
21
+
22
+ Configure via `package.json`:
23
+
24
+ ```json
25
+ {
26
+ "piConfig": {
27
+ "name": "pi",
28
+ "configDir": ".pi"
29
+ }
30
+ }
31
+ ```
32
+
33
+ Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, config paths, and environment variable names.
34
+
35
+ ## Path Resolution
36
+
37
+ Three execution modes: npm install, standalone binary, tsx from source.
38
+
39
+ **Always use `src/config.ts`** for package assets:
40
+
41
+ ```typescript
42
+ import { getPackageDir, getThemeDir } from "./config.js";
43
+ ```
44
+
45
+ Never use `__dirname` directly for package assets.
46
+
47
+ ## Debug Command
48
+
49
+ `/debug` (hidden) writes to `~/.pi/agent/pi-debug.log`:
50
+ - Rendered TUI lines with ANSI codes
51
+ - Last messages sent to the LLM
52
+
53
+ ## Testing
54
+
55
+ ```bash
56
+ ./test.sh # Run non-LLM tests (no API keys needed)
57
+ npm test # Run all tests
58
+ npm test -- test/specific.test.ts # Run specific test
59
+ ```
60
+
61
+ ## Project Structure
62
+
63
+ ```
64
+ packages/
65
+ ai/ # LLM provider abstraction
66
+ agent/ # Agent loop and message types
67
+ tui/ # Terminal UI components
68
+ coding-agent/ # CLI and interactive mode
69
+ ```
@@ -46,6 +46,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
46
46
  - [Custom UI](#custom-ui)
47
47
  - [Error Handling](#error-handling)
48
48
  - [Mode Behavior](#mode-behavior)
49
+ - [Examples Reference](#examples-reference)
49
50
 
50
51
  ## Quick Start
51
52
 
@@ -102,6 +103,8 @@ pi -e ./my-extension.ts
102
103
 
103
104
  ## Extension Locations
104
105
 
106
+ > **Security:** Extensions run with your full system permissions and can execute arbitrary code. Only install from sources you trust.
107
+
105
108
  Extensions are auto-discovered from:
106
109
 
107
110
  | Location | Scope |
@@ -115,47 +118,18 @@ Additional paths via `settings.json`:
115
118
 
116
119
  ```json
117
120
  {
118
- "extensions": ["/path/to/extension.ts", "/path/to/extension/dir"]
119
- }
120
- ```
121
-
122
- **Discovery rules:**
123
-
124
- 1. **Direct files:** `extensions/*.ts` or `*.js` → loaded directly
125
- 2. **Subdirectory with index:** `extensions/myext/index.ts` → loaded as single extension
126
- 3. **Subdirectory with package.json:** `extensions/myext/package.json` with `"pi"` field → loads declared paths
127
-
128
- ```
129
- ~/.pi/agent/extensions/
130
- ├── simple.ts # Direct file (auto-discovered)
131
- ├── my-tool/
132
- │ └── index.ts # Subdirectory with index (auto-discovered)
133
- └── my-extension-pack/
134
- ├── package.json # Declares multiple extensions
135
- ├── node_modules/ # Dependencies installed here
136
- └── src/
137
- ├── safety-gates.ts # First extension
138
- └── custom-tools.ts # Second extension
139
- ```
140
-
141
- ```json
142
- // my-extension-pack/package.json
143
- {
144
- "name": "my-extension-pack",
145
- "dependencies": {
146
- "zod": "^3.0.0"
147
- },
148
- "pi": {
149
- "extensions": ["./src/safety-gates.ts", "./src/custom-tools.ts"]
150
- }
121
+ "packages": [
122
+ "npm:@foo/bar@1.0.0",
123
+ "git:github.com/user/repo@v1"
124
+ ],
125
+ "extensions": [
126
+ "/path/to/local/extension.ts",
127
+ "/path/to/local/extension/dir"
128
+ ]
151
129
  }
152
130
  ```
153
131
 
154
- The `package.json` approach enables:
155
- - Multiple extensions from one package
156
- - Third-party npm dependencies (resolved via jiti)
157
- - Nested source structure (no depth limit within the package)
158
- - Deployment to and installation from npm
132
+ To share extensions via npm or git as pi packages, see [packages.md](packages.md).
159
133
 
160
134
  ## Available Imports
161
135
 
@@ -303,6 +277,8 @@ exit (Ctrl+C, Ctrl+D)
303
277
 
304
278
  ### Session Events
305
279
 
280
+ See [session.md](session.md) for session storage internals and the SessionManager API.
281
+
306
282
  #### session_start
307
283
 
308
284
  Fired on initial session load.
@@ -313,8 +289,6 @@ pi.on("session_start", async (_event, ctx) => {
313
289
  });
314
290
  ```
315
291
 
316
- **Examples:** [claude-rules.ts](../examples/extensions/claude-rules.ts), [custom-header.ts](../examples/extensions/custom-header.ts), [file-trigger.ts](../examples/extensions/file-trigger.ts), [status-line.ts](../examples/extensions/status-line.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
317
-
318
292
  #### session_before_switch / session_switch
319
293
 
320
294
  Fired when starting a new session (`/new`) or switching sessions (`/resume`).
@@ -336,8 +310,6 @@ pi.on("session_switch", async (event, ctx) => {
336
310
  });
337
311
  ```
338
312
 
339
- **Examples:** [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [status-line.ts](../examples/extensions/status-line.ts), [todo.ts](../examples/extensions/todo.ts)
340
-
341
313
  #### session_before_fork / session_fork
342
314
 
343
315
  Fired when forking via `/fork`.
@@ -355,8 +327,6 @@ pi.on("session_fork", async (event, ctx) => {
355
327
  });
356
328
  ```
357
329
 
358
- **Examples:** [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
359
-
360
330
  #### session_before_compact / session_compact
361
331
 
362
332
  Fired on compaction. See [compaction.md](compaction.md) for details.
@@ -384,11 +354,9 @@ pi.on("session_compact", async (event, ctx) => {
384
354
  });
385
355
  ```
386
356
 
387
- **Examples:** [custom-compaction.ts](../examples/extensions/custom-compaction.ts), [trigger-compact.ts](../examples/extensions/trigger-compact.ts)
388
-
389
357
  #### session_before_tree / session_tree
390
358
 
391
- Fired on `/tree` navigation.
359
+ Fired on `/tree` navigation. See [tree.md](tree.md) for tree navigation concepts.
392
360
 
393
361
  ```typescript
394
362
  pi.on("session_before_tree", async (event, ctx) => {
@@ -403,8 +371,6 @@ pi.on("session_tree", async (event, ctx) => {
403
371
  });
404
372
  ```
405
373
 
406
- **Examples:** [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
407
-
408
374
  #### session_shutdown
409
375
 
410
376
  Fired on exit (Ctrl+C, Ctrl+D, SIGTERM).
@@ -415,8 +381,6 @@ pi.on("session_shutdown", async (_event, ctx) => {
415
381
  });
416
382
  ```
417
383
 
418
- **Examples:** [auto-commit-on-exit.ts](../examples/extensions/auto-commit-on-exit.ts)
419
-
420
384
  ### Agent Events
421
385
 
422
386
  #### before_agent_start
@@ -442,8 +406,6 @@ pi.on("before_agent_start", async (event, ctx) => {
442
406
  });
443
407
  ```
444
408
 
445
- **Examples:** [claude-rules.ts](../examples/extensions/claude-rules.ts), [pirate.ts](../examples/extensions/pirate.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [ssh.ts](../examples/extensions/ssh.ts)
446
-
447
409
  #### agent_start / agent_end
448
410
 
449
411
  Fired once per user prompt.
@@ -456,8 +418,6 @@ pi.on("agent_end", async (event, ctx) => {
456
418
  });
457
419
  ```
458
420
 
459
- **Examples:** [chalk-logger.ts](../examples/extensions/chalk-logger.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
460
-
461
421
  #### turn_start / turn_end
462
422
 
463
423
  Fired for each turn (one LLM response + tool calls).
@@ -472,11 +432,9 @@ pi.on("turn_end", async (event, ctx) => {
472
432
  });
473
433
  ```
474
434
 
475
- **Examples:** [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [status-line.ts](../examples/extensions/status-line.ts)
476
-
477
435
  #### context
478
436
 
479
- Fired before each LLM call. Modify messages non-destructively.
437
+ Fired before each LLM call. Modify messages non-destructively. See [session.md](session.md) for message types.
480
438
 
481
439
  ```typescript
482
440
  pi.on("context", async (event, ctx) => {
@@ -486,8 +444,6 @@ pi.on("context", async (event, ctx) => {
486
444
  });
487
445
  ```
488
446
 
489
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
490
-
491
447
  ### Model Events
492
448
 
493
449
  #### model_select
@@ -499,20 +455,18 @@ pi.on("model_select", async (event, ctx) => {
499
455
  // event.model - newly selected model
500
456
  // event.previousModel - previous model (undefined if first selection)
501
457
  // event.source - "set" | "cycle" | "restore"
502
-
503
- const prev = event.previousModel
504
- ? `${event.previousModel.provider}/${event.previousModel.id}`
458
+
459
+ const prev = event.previousModel
460
+ ? `${event.previousModel.provider}/${event.previousModel.id}`
505
461
  : "none";
506
462
  const next = `${event.model.provider}/${event.model.id}`;
507
-
463
+
508
464
  ctx.ui.notify(`Model changed (${event.source}): ${prev} -> ${next}`, "info");
509
465
  });
510
466
  ```
511
467
 
512
468
  Use this to update UI elements (status bars, footers) or perform model-specific initialization when the active model changes.
513
469
 
514
- **Examples:** [model-status.ts](../examples/extensions/model-status.ts)
515
-
516
470
  ### Tool Events
517
471
 
518
472
  #### tool_call
@@ -531,8 +485,6 @@ pi.on("tool_call", async (event, ctx) => {
531
485
  });
532
486
  ```
533
487
 
534
- **Examples:** [chalk-logger.ts](../examples/extensions/chalk-logger.ts), [permission-gate.ts](../examples/extensions/permission-gate.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [protected-paths.ts](../examples/extensions/protected-paths.ts)
535
-
536
488
  #### tool_result
537
489
 
538
490
  Fired after tool executes. **Can modify result.**
@@ -553,8 +505,6 @@ pi.on("tool_result", async (event, ctx) => {
553
505
  });
554
506
  ```
555
507
 
556
- **Examples:** [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
557
-
558
508
  ### User Bash Events
559
509
 
560
510
  #### user_bash
@@ -575,8 +525,6 @@ pi.on("user_bash", (event, ctx) => {
575
525
  });
576
526
  ```
577
527
 
578
- **Examples:** [ssh.ts](../examples/extensions/ssh.ts), [interactive-shell.ts](../examples/extensions/interactive-shell.ts)
579
-
580
528
  ### Input Events
581
529
 
582
530
  #### input
@@ -643,7 +591,7 @@ Current working directory.
643
591
 
644
592
  ### ctx.sessionManager
645
593
 
646
- Read-only access to session state:
594
+ Read-only access to session state. See [session.md](session.md) for the full SessionManager API and entry types.
647
595
 
648
596
  ```typescript
649
597
  ctx.sessionManager.getEntries() // All entries
@@ -811,8 +759,6 @@ pi.registerTool({
811
759
  });
812
760
  ```
813
761
 
814
- **Examples:** [hello.ts](../examples/extensions/hello.ts), [question.ts](../examples/extensions/question.ts), [questionnaire.ts](../examples/extensions/questionnaire.ts), [todo.ts](../examples/extensions/todo.ts), [truncated-tool.ts](../examples/extensions/truncated-tool.ts)
815
-
816
762
  ### pi.sendMessage(message, options?)
817
763
 
818
764
  Inject a custom message into the session.
@@ -836,8 +782,6 @@ pi.sendMessage({
836
782
  - `"nextTurn"` - Queued for next user prompt. Does not interrupt or trigger anything.
837
783
  - `triggerTurn: true` - If agent is idle, trigger an LLM response immediately. Only applies to `"steer"` and `"followUp"` modes (ignored for `"nextTurn"`).
838
784
 
839
- **Examples:** [file-trigger.ts](../examples/extensions/file-trigger.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
840
-
841
785
  ### pi.sendUserMessage(content, options?)
842
786
 
843
787
  Send a user message to the agent. Unlike `sendMessage()` which sends custom messages, this sends an actual user message that appears as if typed by the user. Always triggers a turn.
@@ -883,8 +827,6 @@ pi.on("session_start", async (_event, ctx) => {
883
827
  });
884
828
  ```
885
829
 
886
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [snake.ts](../examples/extensions/snake.ts), [tools.ts](../examples/extensions/tools.ts)
887
-
888
830
  ### pi.setSessionName(name)
889
831
 
890
832
  Set the session display name (shown in session selector instead of first message).
@@ -954,15 +896,13 @@ pi.registerCommand("deploy", {
954
896
  });
955
897
  ```
956
898
 
957
- **Examples:** [custom-footer.ts](../examples/extensions/custom-footer.ts), [custom-header.ts](../examples/extensions/custom-header.ts), [handoff.ts](../examples/extensions/handoff.ts), [pirate.ts](../examples/extensions/pirate.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [qna.ts](../examples/extensions/qna.ts), [send-user-message.ts](../examples/extensions/send-user-message.ts), [snake.ts](../examples/extensions/snake.ts), [summarize.ts](../examples/extensions/summarize.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
958
-
959
899
  ### pi.registerMessageRenderer(customType, renderer)
960
900
 
961
901
  Register a custom TUI renderer for messages with your `customType`. See [Custom UI](#custom-ui).
962
902
 
963
903
  ### pi.registerShortcut(shortcut, options)
964
904
 
965
- Register a keyboard shortcut.
905
+ Register a keyboard shortcut. See [keybindings.md](keybindings.md) for the shortcut format and built-in keybindings.
966
906
 
967
907
  ```typescript
968
908
  pi.registerShortcut("ctrl+shift+p", {
@@ -973,8 +913,6 @@ pi.registerShortcut("ctrl+shift+p", {
973
913
  });
974
914
  ```
975
915
 
976
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
977
-
978
916
  ### pi.registerFlag(name, options)
979
917
 
980
918
  Register a CLI flag.
@@ -992,8 +930,6 @@ if (pi.getFlag("--plan")) {
992
930
  }
993
931
  ```
994
932
 
995
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
996
-
997
933
  ### pi.exec(command, args, options?)
998
934
 
999
935
  Execute a shell command.
@@ -1003,8 +939,6 @@ const result = await pi.exec("git", ["status"], { signal, timeout: 5000 });
1003
939
  // result.stdout, result.stderr, result.code, result.killed
1004
940
  ```
1005
941
 
1006
- **Examples:** [auto-commit-on-exit.ts](../examples/extensions/auto-commit-on-exit.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts)
1007
-
1008
942
  ### pi.getActiveTools() / pi.getAllTools() / pi.setActiveTools(names)
1009
943
 
1010
944
  Manage active tools.
@@ -1016,11 +950,9 @@ const names = all.map(t => t.name); // Just names if needed
1016
950
  pi.setActiveTools(["read", "bash"]); // Switch to read-only
1017
951
  ```
1018
952
 
1019
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [tools.ts](../examples/extensions/tools.ts)
1020
-
1021
953
  ### pi.setModel(model)
1022
954
 
1023
- Set the current model. Returns `false` if no API key is available for the model.
955
+ Set the current model. Returns `false` if no API key is available for the model. See [models.md](models.md) for configuring custom models.
1024
956
 
1025
957
  ```typescript
1026
958
  const model = ctx.modelRegistry.find("anthropic", "claude-sonnet-4-5");
@@ -1032,8 +964,6 @@ if (model) {
1032
964
  }
1033
965
  ```
1034
966
 
1035
- **Examples:** [preset.ts](../examples/extensions/preset.ts)
1036
-
1037
967
  ### pi.getThinkingLevel() / pi.setThinkingLevel(level)
1038
968
 
1039
969
  Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off").
@@ -1043,8 +973,6 @@ const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium"
1043
973
  pi.setThinkingLevel("high");
1044
974
  ```
1045
975
 
1046
- **Examples:** [preset.ts](../examples/extensions/preset.ts)
1047
-
1048
976
  ### pi.events
1049
977
 
1050
978
  Shared event bus for communication between extensions:
@@ -1054,6 +982,70 @@ pi.events.on("my:event", (data) => { ... });
1054
982
  pi.events.emit("my:event", { ... });
1055
983
  ```
1056
984
 
985
+ ### pi.registerProvider(name, config)
986
+
987
+ Register or override a model provider dynamically. Useful for proxies, custom endpoints, or team-wide model configurations.
988
+
989
+ ```typescript
990
+ // Register a new provider with custom models
991
+ pi.registerProvider("my-proxy", {
992
+ baseUrl: "https://proxy.example.com",
993
+ apiKey: "PROXY_API_KEY", // env var name or literal
994
+ api: "anthropic-messages",
995
+ models: [
996
+ {
997
+ id: "claude-sonnet-4-20250514",
998
+ name: "Claude 4 Sonnet (proxy)",
999
+ reasoning: false,
1000
+ input: ["text", "image"],
1001
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1002
+ contextWindow: 200000,
1003
+ maxTokens: 16384
1004
+ }
1005
+ ]
1006
+ });
1007
+
1008
+ // Override baseUrl for an existing provider (keeps all models)
1009
+ pi.registerProvider("anthropic", {
1010
+ baseUrl: "https://proxy.example.com"
1011
+ });
1012
+
1013
+ // Register provider with OAuth support for /login
1014
+ pi.registerProvider("corporate-ai", {
1015
+ baseUrl: "https://ai.corp.com",
1016
+ api: "openai-responses",
1017
+ models: [...],
1018
+ oauth: {
1019
+ name: "Corporate AI (SSO)",
1020
+ async login(callbacks) {
1021
+ // Custom OAuth flow
1022
+ callbacks.onAuth({ url: "https://sso.corp.com/..." });
1023
+ const code = await callbacks.onPrompt({ message: "Enter code:" });
1024
+ return { refresh: code, access: code, expires: Date.now() + 3600000 };
1025
+ },
1026
+ async refreshToken(credentials) {
1027
+ // Refresh logic
1028
+ return credentials;
1029
+ },
1030
+ getApiKey(credentials) {
1031
+ return credentials.access;
1032
+ }
1033
+ }
1034
+ });
1035
+ ```
1036
+
1037
+ **Config options:**
1038
+ - `baseUrl` - API endpoint URL. Required when defining models.
1039
+ - `apiKey` - API key or environment variable name. Required when defining models (unless `oauth` provided).
1040
+ - `api` - API type: `"anthropic-messages"`, `"openai-completions"`, `"openai-responses"`, etc.
1041
+ - `headers` - Custom headers to include in requests.
1042
+ - `authHeader` - If true, adds `Authorization: Bearer` header automatically.
1043
+ - `models` - Array of model definitions. If provided, replaces all existing models for this provider.
1044
+ - `oauth` - OAuth provider config for `/login` support. When provided, the provider appears in the login menu.
1045
+ - `streamSimple` - Custom streaming implementation for non-standard APIs.
1046
+
1047
+ See [custom-provider.md](custom-provider.md) for advanced topics: custom streaming APIs, OAuth details, model definition reference.
1048
+
1057
1049
  ## State Management
1058
1050
 
1059
1051
  Extensions with state should store it in tool result `details` for proper branching support:
@@ -1214,6 +1206,7 @@ The built-in limit is **50KB** (~10k tokens) and **2000 lines**, whichever is hi
1214
1206
  import {
1215
1207
  truncateHead, // Keep first N lines/bytes (good for file reads, search results)
1216
1208
  truncateTail, // Keep last N lines/bytes (good for logs, command output)
1209
+ truncateLine, // Truncate a single line to maxBytes with ellipsis
1217
1210
  formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
1218
1211
  DEFAULT_MAX_BYTES, // 50KB
1219
1212
  DEFAULT_MAX_LINES, // 2000
@@ -1272,7 +1265,7 @@ export default function (pi: ExtensionAPI) {
1272
1265
 
1273
1266
  ### Custom Rendering
1274
1267
 
1275
- Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API.
1268
+ Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how built-in tools render.
1276
1269
 
1277
1270
  Tool output is wrapped in a `Box` that handles padding and background. Your render methods return `Component` instances (typically `Text`).
1278
1271
 
@@ -1388,12 +1381,6 @@ const text = await ctx.ui.editor("Edit:", "prefilled text");
1388
1381
  ctx.ui.notify("Done!", "info"); // "info" | "warning" | "error"
1389
1382
  ```
1390
1383
 
1391
- **Examples:**
1392
- - `ctx.ui.select()`: [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [permission-gate.ts](../examples/extensions/permission-gate.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [question.ts](../examples/extensions/question.ts), [questionnaire.ts](../examples/extensions/questionnaire.ts)
1393
- - `ctx.ui.confirm()`: [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts)
1394
- - `ctx.ui.editor()`: [handoff.ts](../examples/extensions/handoff.ts)
1395
- - `ctx.ui.setEditorText()`: [handoff.ts](../examples/extensions/handoff.ts), [qna.ts](../examples/extensions/qna.ts)
1396
-
1397
1384
  #### Timed Dialogs with Countdown
1398
1385
 
1399
1386
  Dialogs support a `timeout` option that auto-dismisses with a live countdown display:
@@ -1481,7 +1468,7 @@ const current = ctx.ui.getEditorText();
1481
1468
  ctx.ui.setEditorComponent((tui, theme, keybindings) => new VimEditor(tui, theme, keybindings));
1482
1469
  ctx.ui.setEditorComponent(undefined); // Restore default editor
1483
1470
 
1484
- // Theme management
1471
+ // Theme management (see themes.md for creating themes)
1485
1472
  const themes = ctx.ui.getAllThemes(); // [{ name: "dark", path: "/..." | undefined }, ...]
1486
1473
  const lightTheme = ctx.ui.getTheme("light"); // Load without switching
1487
1474
  const result = ctx.ui.setTheme("light"); // Switch by name
@@ -1492,14 +1479,6 @@ ctx.ui.setTheme(lightTheme!); // Or switch by Theme object
1492
1479
  ctx.ui.theme.fg("accent", "styled text"); // Access current theme
1493
1480
  ```
1494
1481
 
1495
- **Examples:**
1496
- - `ctx.ui.setStatus()`: [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [status-line.ts](../examples/extensions/status-line.ts)
1497
- - `ctx.ui.setWidget()`: [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
1498
- - `ctx.ui.setFooter()`: [custom-footer.ts](../examples/extensions/custom-footer.ts)
1499
- - `ctx.ui.setHeader()`: [custom-header.ts](../examples/extensions/custom-header.ts)
1500
- - `ctx.ui.setEditorComponent()`: [modal-editor.ts](../examples/extensions/modal-editor.ts)
1501
- - `ctx.ui.setTheme()`: [mac-system-theme.ts](../examples/extensions/mac-system-theme.ts)
1502
-
1503
1482
  ### Custom Components
1504
1483
 
1505
1484
  For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
@@ -1558,8 +1537,6 @@ const result = await ctx.ui.custom<string | null>(
1558
1537
 
1559
1538
  See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for examples.
1560
1539
 
1561
- **Examples:** [handoff.ts](../examples/extensions/handoff.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [qna.ts](../examples/extensions/qna.ts), [snake.ts](../examples/extensions/snake.ts), [summarize.ts](../examples/extensions/summarize.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts), [overlay-test.ts](../examples/extensions/overlay-test.ts)
1562
-
1563
1540
  ### Custom Editor
1564
1541
 
1565
1542
  Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
@@ -1601,8 +1578,6 @@ export default function (pi: ExtensionAPI) {
1601
1578
 
1602
1579
  See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
1603
1580
 
1604
- **Examples:** [modal-editor.ts](../examples/extensions/modal-editor.ts)
1605
-
1606
1581
  ### Message Rendering
1607
1582
 
1608
1583
  Register a custom renderer for messages with your `customType`:
@@ -1636,7 +1611,7 @@ pi.sendMessage({
1636
1611
 
1637
1612
  ### Theme Colors
1638
1613
 
1639
- All render functions receive a `theme` object:
1614
+ All render functions receive a `theme` object. See [themes.md](themes.md) for creating custom themes and the full color palette.
1640
1615
 
1641
1616
  ```typescript
1642
1617
  // Foreground colors
@@ -1654,6 +1629,19 @@ theme.italic(text)
1654
1629
  theme.strikethrough(text)
1655
1630
  ```
1656
1631
 
1632
+ For syntax highlighting in custom tool renderers:
1633
+
1634
+ ```typescript
1635
+ import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
1636
+
1637
+ // Highlight code with explicit language
1638
+ const highlighted = highlightCode("const x = 1;", "typescript", theme);
1639
+
1640
+ // Auto-detect language from file path
1641
+ const lang = getLanguageFromPath("/path/to/file.rs"); // "rust"
1642
+ const highlighted = highlightCode(code, lang, theme);
1643
+ ```
1644
+
1657
1645
  ## Error Handling
1658
1646
 
1659
1647
  - Extension errors are logged, agent continues
@@ -1665,7 +1653,81 @@ theme.strikethrough(text)
1665
1653
  | Mode | UI Methods | Notes |
1666
1654
  |------|-----------|-------|
1667
1655
  | Interactive | Full TUI | Normal operation |
1668
- | RPC | JSON protocol | Host handles UI |
1656
+ | RPC (`--mode rpc`) | JSON protocol | Host handles UI, see [rpc.md](rpc.md) |
1657
+ | JSON (`--mode json`) | No-op | Event stream to stdout, see [json.md](json.md) |
1669
1658
  | Print (`-p`) | No-op | Extensions run but can't prompt |
1670
1659
 
1671
- In print mode, check `ctx.hasUI` before using UI methods.
1660
+ In non-interactive modes, check `ctx.hasUI` before using UI methods.
1661
+
1662
+ ## Examples Reference
1663
+
1664
+ All examples in [examples/extensions/](../examples/extensions/).
1665
+
1666
+ | Example | Description | Key APIs |
1667
+ |---------|-------------|----------|
1668
+ | **Tools** |||
1669
+ | `hello.ts` | Minimal tool registration | `registerTool` |
1670
+ | `question.ts` | Tool with user interaction | `registerTool`, `ui.select` |
1671
+ | `questionnaire.ts` | Multi-step wizard tool | `registerTool`, `ui.custom` |
1672
+ | `todo.ts` | Stateful tool with persistence | `registerTool`, `appendEntry`, `renderResult`, session events |
1673
+ | `truncated-tool.ts` | Output truncation example | `registerTool`, `truncateHead` |
1674
+ | `tool-override.ts` | Override built-in read tool | `registerTool` (same name as built-in) |
1675
+ | **Commands** |||
1676
+ | `pirate.ts` | Modify system prompt per-turn | `registerCommand`, `before_agent_start` |
1677
+ | `summarize.ts` | Conversation summary command | `registerCommand`, `ui.custom` |
1678
+ | `handoff.ts` | Cross-provider model handoff | `registerCommand`, `ui.editor`, `ui.custom` |
1679
+ | `qna.ts` | Q&A with custom UI | `registerCommand`, `ui.custom`, `setEditorText` |
1680
+ | `send-user-message.ts` | Inject user messages | `registerCommand`, `sendUserMessage` |
1681
+ | `shutdown-command.ts` | Graceful shutdown command | `registerCommand`, `shutdown()` |
1682
+ | **Events & Gates** |||
1683
+ | `permission-gate.ts` | Block dangerous commands | `on("tool_call")`, `ui.confirm` |
1684
+ | `protected-paths.ts` | Block writes to specific paths | `on("tool_call")` |
1685
+ | `confirm-destructive.ts` | Confirm session changes | `on("session_before_switch")`, `on("session_before_fork")` |
1686
+ | `dirty-repo-guard.ts` | Warn on dirty git repo | `on("session_before_*")`, `exec` |
1687
+ | `input-transform.ts` | Transform user input | `on("input")` |
1688
+ | `model-status.ts` | React to model changes | `on("model_select")`, `setStatus` |
1689
+ | `claude-rules.ts` | Load rules from files | `on("session_start")`, `on("before_agent_start")` |
1690
+ | `file-trigger.ts` | File watcher triggers messages | `sendMessage` |
1691
+ | **Compaction & Sessions** |||
1692
+ | `custom-compaction.ts` | Custom compaction summary | `on("session_before_compact")` |
1693
+ | `trigger-compact.ts` | Trigger compaction manually | `compact()` |
1694
+ | `git-checkpoint.ts` | Git stash on turns | `on("turn_end")`, `on("session_fork")`, `exec` |
1695
+ | `auto-commit-on-exit.ts` | Commit on shutdown | `on("session_shutdown")`, `exec` |
1696
+ | **UI Components** |||
1697
+ | `status-line.ts` | Footer status indicator | `setStatus`, session events |
1698
+ | `custom-footer.ts` | Replace footer entirely | `registerCommand`, `setFooter` |
1699
+ | `custom-header.ts` | Replace startup header | `on("session_start")`, `setHeader` |
1700
+ | `modal-editor.ts` | Vim-style modal editor | `setEditorComponent`, `CustomEditor` |
1701
+ | `rainbow-editor.ts` | Custom editor styling | `setEditorComponent` |
1702
+ | `widget-placement.ts` | Widget above/below editor | `setWidget` |
1703
+ | `overlay-test.ts` | Overlay components | `ui.custom` with overlay options |
1704
+ | `overlay-qa-tests.ts` | Comprehensive overlay tests | `ui.custom`, all overlay options |
1705
+ | `notify.ts` | Simple notifications | `ui.notify` |
1706
+ | `timed-confirm.ts` | Dialogs with timeout | `ui.confirm` with timeout/signal |
1707
+ | `mac-system-theme.ts` | Auto-switch theme | `setTheme`, `exec` |
1708
+ | **Complex Extensions** |||
1709
+ | `plan-mode/` | Full plan mode implementation | All event types, `registerCommand`, `registerShortcut`, `registerFlag`, `setStatus`, `setWidget`, `sendMessage`, `setActiveTools` |
1710
+ | `preset.ts` | Saveable presets (model, tools, thinking) | `registerCommand`, `registerShortcut`, `registerFlag`, `setModel`, `setActiveTools`, `setThinkingLevel`, `appendEntry` |
1711
+ | `tools.ts` | Toggle tools on/off UI | `registerCommand`, `setActiveTools`, `SettingsList`, session events |
1712
+ | **Remote & Sandbox** |||
1713
+ | `ssh.ts` | SSH remote execution | `registerFlag`, `on("user_bash")`, `on("before_agent_start")`, tool operations |
1714
+ | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
1715
+ | `sandbox/` | Sandboxed tool execution | Tool operations |
1716
+ | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
1717
+ | **Games** |||
1718
+ | `snake.ts` | Snake game | `registerCommand`, `ui.custom`, keyboard handling |
1719
+ | `space-invaders.ts` | Space Invaders game | `registerCommand`, `ui.custom` |
1720
+ | `doom-overlay/` | Doom in overlay | `ui.custom` with overlay |
1721
+ | **Providers** |||
1722
+ | `custom-provider-anthropic/` | Custom Anthropic proxy | `registerProvider` |
1723
+ | `custom-provider-gitlab-duo/` | GitLab Duo integration | `registerProvider` with OAuth |
1724
+ | **Messages & Communication** |||
1725
+ | `message-renderer.ts` | Custom message rendering | `registerMessageRenderer`, `sendMessage` |
1726
+ | `event-bus.ts` | Inter-extension events | `pi.events` |
1727
+ | **Session Metadata** |||
1728
+ | `session-name.ts` | Name sessions for selector | `setSessionName`, `getSessionName` |
1729
+ | `bookmark.ts` | Bookmark entries for /tree | `setLabel` |
1730
+ | **Misc** |||
1731
+ | `antigravity-image-gen.ts` | Image generation tool | `registerTool`, Google Antigravity |
1732
+ | `inline-bash.ts` | Inline bash in tool calls | `on("tool_call")` |
1733
+ | `with-deps/` | Extension with npm dependencies | Package structure with `package.json` |
Binary file
Binary file
Binary file