@mariozechner/pi-coding-agent 0.49.3 → 0.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/CHANGELOG.md +110 -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 +60 -37
  15. package/dist/core/agent-session.d.ts.map +1 -1
  16. package/dist/core/agent-session.js +272 -69
  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 +130 -0
  57. package/dist/core/package-manager.d.ts.map +1 -0
  58. package/dist/core/package-manager.js +1177 -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 +538 -204
  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 +7 -74
  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 +17 -82
  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 +182 -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 +168 -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
+ ```
@@ -4,6 +4,8 @@
4
4
 
5
5
  Extensions are TypeScript modules that extend pi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more.
6
6
 
7
+ > **Placement for /reload:** Put extensions in `~/.pi/agent/extensions/` (global) or `.pi/extensions/` (project-local) for auto-discovery. Use `pi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
8
+
7
9
  **Key capabilities:**
8
10
  - **Custom tools** - Register tools the LLM can call via `pi.registerTool()`
9
11
  - **Event interception** - Block or modify tool calls, inject context, customize compaction
@@ -46,6 +48,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
46
48
  - [Custom UI](#custom-ui)
47
49
  - [Error Handling](#error-handling)
48
50
  - [Mode Behavior](#mode-behavior)
51
+ - [Examples Reference](#examples-reference)
49
52
 
50
53
  ## Quick Start
51
54
 
@@ -102,6 +105,8 @@ pi -e ./my-extension.ts
102
105
 
103
106
  ## Extension Locations
104
107
 
108
+ > **Security:** Extensions run with your full system permissions and can execute arbitrary code. Only install from sources you trust.
109
+
105
110
  Extensions are auto-discovered from:
106
111
 
107
112
  | Location | Scope |
@@ -115,47 +120,18 @@ Additional paths via `settings.json`:
115
120
 
116
121
  ```json
117
122
  {
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
- }
123
+ "packages": [
124
+ "npm:@foo/bar@1.0.0",
125
+ "git:github.com/user/repo@v1"
126
+ ],
127
+ "extensions": [
128
+ "/path/to/local/extension.ts",
129
+ "/path/to/local/extension/dir"
130
+ ]
151
131
  }
152
132
  ```
153
133
 
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
134
+ To share extensions via npm or git as pi packages, see [packages.md](packages.md).
159
135
 
160
136
  ## Available Imports
161
137
 
@@ -303,6 +279,8 @@ exit (Ctrl+C, Ctrl+D)
303
279
 
304
280
  ### Session Events
305
281
 
282
+ See [session.md](session.md) for session storage internals and the SessionManager API.
283
+
306
284
  #### session_start
307
285
 
308
286
  Fired on initial session load.
@@ -313,8 +291,6 @@ pi.on("session_start", async (_event, ctx) => {
313
291
  });
314
292
  ```
315
293
 
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
294
  #### session_before_switch / session_switch
319
295
 
320
296
  Fired when starting a new session (`/new`) or switching sessions (`/resume`).
@@ -336,8 +312,6 @@ pi.on("session_switch", async (event, ctx) => {
336
312
  });
337
313
  ```
338
314
 
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
315
  #### session_before_fork / session_fork
342
316
 
343
317
  Fired when forking via `/fork`.
@@ -355,8 +329,6 @@ pi.on("session_fork", async (event, ctx) => {
355
329
  });
356
330
  ```
357
331
 
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
332
  #### session_before_compact / session_compact
361
333
 
362
334
  Fired on compaction. See [compaction.md](compaction.md) for details.
@@ -384,11 +356,9 @@ pi.on("session_compact", async (event, ctx) => {
384
356
  });
385
357
  ```
386
358
 
387
- **Examples:** [custom-compaction.ts](../examples/extensions/custom-compaction.ts), [trigger-compact.ts](../examples/extensions/trigger-compact.ts)
388
-
389
359
  #### session_before_tree / session_tree
390
360
 
391
- Fired on `/tree` navigation.
361
+ Fired on `/tree` navigation. See [tree.md](tree.md) for tree navigation concepts.
392
362
 
393
363
  ```typescript
394
364
  pi.on("session_before_tree", async (event, ctx) => {
@@ -403,8 +373,6 @@ pi.on("session_tree", async (event, ctx) => {
403
373
  });
404
374
  ```
405
375
 
406
- **Examples:** [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
407
-
408
376
  #### session_shutdown
409
377
 
410
378
  Fired on exit (Ctrl+C, Ctrl+D, SIGTERM).
@@ -415,8 +383,6 @@ pi.on("session_shutdown", async (_event, ctx) => {
415
383
  });
416
384
  ```
417
385
 
418
- **Examples:** [auto-commit-on-exit.ts](../examples/extensions/auto-commit-on-exit.ts)
419
-
420
386
  ### Agent Events
421
387
 
422
388
  #### before_agent_start
@@ -442,8 +408,6 @@ pi.on("before_agent_start", async (event, ctx) => {
442
408
  });
443
409
  ```
444
410
 
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
411
  #### agent_start / agent_end
448
412
 
449
413
  Fired once per user prompt.
@@ -456,8 +420,6 @@ pi.on("agent_end", async (event, ctx) => {
456
420
  });
457
421
  ```
458
422
 
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
423
  #### turn_start / turn_end
462
424
 
463
425
  Fired for each turn (one LLM response + tool calls).
@@ -472,11 +434,9 @@ pi.on("turn_end", async (event, ctx) => {
472
434
  });
473
435
  ```
474
436
 
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
437
  #### context
478
438
 
479
- Fired before each LLM call. Modify messages non-destructively.
439
+ Fired before each LLM call. Modify messages non-destructively. See [session.md](session.md) for message types.
480
440
 
481
441
  ```typescript
482
442
  pi.on("context", async (event, ctx) => {
@@ -486,8 +446,6 @@ pi.on("context", async (event, ctx) => {
486
446
  });
487
447
  ```
488
448
 
489
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
490
-
491
449
  ### Model Events
492
450
 
493
451
  #### model_select
@@ -499,20 +457,18 @@ pi.on("model_select", async (event, ctx) => {
499
457
  // event.model - newly selected model
500
458
  // event.previousModel - previous model (undefined if first selection)
501
459
  // event.source - "set" | "cycle" | "restore"
502
-
503
- const prev = event.previousModel
504
- ? `${event.previousModel.provider}/${event.previousModel.id}`
460
+
461
+ const prev = event.previousModel
462
+ ? `${event.previousModel.provider}/${event.previousModel.id}`
505
463
  : "none";
506
464
  const next = `${event.model.provider}/${event.model.id}`;
507
-
465
+
508
466
  ctx.ui.notify(`Model changed (${event.source}): ${prev} -> ${next}`, "info");
509
467
  });
510
468
  ```
511
469
 
512
470
  Use this to update UI elements (status bars, footers) or perform model-specific initialization when the active model changes.
513
471
 
514
- **Examples:** [model-status.ts](../examples/extensions/model-status.ts)
515
-
516
472
  ### Tool Events
517
473
 
518
474
  #### tool_call
@@ -531,8 +487,6 @@ pi.on("tool_call", async (event, ctx) => {
531
487
  });
532
488
  ```
533
489
 
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
490
  #### tool_result
537
491
 
538
492
  Fired after tool executes. **Can modify result.**
@@ -553,8 +507,6 @@ pi.on("tool_result", async (event, ctx) => {
553
507
  });
554
508
  ```
555
509
 
556
- **Examples:** [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
557
-
558
510
  ### User Bash Events
559
511
 
560
512
  #### user_bash
@@ -575,8 +527,6 @@ pi.on("user_bash", (event, ctx) => {
575
527
  });
576
528
  ```
577
529
 
578
- **Examples:** [ssh.ts](../examples/extensions/ssh.ts), [interactive-shell.ts](../examples/extensions/interactive-shell.ts)
579
-
580
530
  ### Input Events
581
531
 
582
532
  #### input
@@ -643,7 +593,7 @@ Current working directory.
643
593
 
644
594
  ### ctx.sessionManager
645
595
 
646
- Read-only access to session state:
596
+ Read-only access to session state. See [session.md](session.md) for the full SessionManager API and entry types.
647
597
 
648
598
  ```typescript
649
599
  ctx.sessionManager.getEntries() // All entries
@@ -811,8 +761,6 @@ pi.registerTool({
811
761
  });
812
762
  ```
813
763
 
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
764
  ### pi.sendMessage(message, options?)
817
765
 
818
766
  Inject a custom message into the session.
@@ -836,8 +784,6 @@ pi.sendMessage({
836
784
  - `"nextTurn"` - Queued for next user prompt. Does not interrupt or trigger anything.
837
785
  - `triggerTurn: true` - If agent is idle, trigger an LLM response immediately. Only applies to `"steer"` and `"followUp"` modes (ignored for `"nextTurn"`).
838
786
 
839
- **Examples:** [file-trigger.ts](../examples/extensions/file-trigger.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts)
840
-
841
787
  ### pi.sendUserMessage(content, options?)
842
788
 
843
789
  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 +829,6 @@ pi.on("session_start", async (_event, ctx) => {
883
829
  });
884
830
  ```
885
831
 
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
832
  ### pi.setSessionName(name)
889
833
 
890
834
  Set the session display name (shown in session selector instead of first message).
@@ -954,15 +898,13 @@ pi.registerCommand("deploy", {
954
898
  });
955
899
  ```
956
900
 
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
901
  ### pi.registerMessageRenderer(customType, renderer)
960
902
 
961
903
  Register a custom TUI renderer for messages with your `customType`. See [Custom UI](#custom-ui).
962
904
 
963
905
  ### pi.registerShortcut(shortcut, options)
964
906
 
965
- Register a keyboard shortcut.
907
+ Register a keyboard shortcut. See [keybindings.md](keybindings.md) for the shortcut format and built-in keybindings.
966
908
 
967
909
  ```typescript
968
910
  pi.registerShortcut("ctrl+shift+p", {
@@ -973,8 +915,6 @@ pi.registerShortcut("ctrl+shift+p", {
973
915
  });
974
916
  ```
975
917
 
976
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
977
-
978
918
  ### pi.registerFlag(name, options)
979
919
 
980
920
  Register a CLI flag.
@@ -992,8 +932,6 @@ if (pi.getFlag("--plan")) {
992
932
  }
993
933
  ```
994
934
 
995
- **Examples:** [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts)
996
-
997
935
  ### pi.exec(command, args, options?)
998
936
 
999
937
  Execute a shell command.
@@ -1003,8 +941,6 @@ const result = await pi.exec("git", ["status"], { signal, timeout: 5000 });
1003
941
  // result.stdout, result.stderr, result.code, result.killed
1004
942
  ```
1005
943
 
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
944
  ### pi.getActiveTools() / pi.getAllTools() / pi.setActiveTools(names)
1009
945
 
1010
946
  Manage active tools.
@@ -1016,11 +952,9 @@ const names = all.map(t => t.name); // Just names if needed
1016
952
  pi.setActiveTools(["read", "bash"]); // Switch to read-only
1017
953
  ```
1018
954
 
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
955
  ### pi.setModel(model)
1022
956
 
1023
- Set the current model. Returns `false` if no API key is available for the model.
957
+ 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
958
 
1025
959
  ```typescript
1026
960
  const model = ctx.modelRegistry.find("anthropic", "claude-sonnet-4-5");
@@ -1032,8 +966,6 @@ if (model) {
1032
966
  }
1033
967
  ```
1034
968
 
1035
- **Examples:** [preset.ts](../examples/extensions/preset.ts)
1036
-
1037
969
  ### pi.getThinkingLevel() / pi.setThinkingLevel(level)
1038
970
 
1039
971
  Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off").
@@ -1043,8 +975,6 @@ const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium"
1043
975
  pi.setThinkingLevel("high");
1044
976
  ```
1045
977
 
1046
- **Examples:** [preset.ts](../examples/extensions/preset.ts)
1047
-
1048
978
  ### pi.events
1049
979
 
1050
980
  Shared event bus for communication between extensions:
@@ -1054,6 +984,70 @@ pi.events.on("my:event", (data) => { ... });
1054
984
  pi.events.emit("my:event", { ... });
1055
985
  ```
1056
986
 
987
+ ### pi.registerProvider(name, config)
988
+
989
+ Register or override a model provider dynamically. Useful for proxies, custom endpoints, or team-wide model configurations.
990
+
991
+ ```typescript
992
+ // Register a new provider with custom models
993
+ pi.registerProvider("my-proxy", {
994
+ baseUrl: "https://proxy.example.com",
995
+ apiKey: "PROXY_API_KEY", // env var name or literal
996
+ api: "anthropic-messages",
997
+ models: [
998
+ {
999
+ id: "claude-sonnet-4-20250514",
1000
+ name: "Claude 4 Sonnet (proxy)",
1001
+ reasoning: false,
1002
+ input: ["text", "image"],
1003
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1004
+ contextWindow: 200000,
1005
+ maxTokens: 16384
1006
+ }
1007
+ ]
1008
+ });
1009
+
1010
+ // Override baseUrl for an existing provider (keeps all models)
1011
+ pi.registerProvider("anthropic", {
1012
+ baseUrl: "https://proxy.example.com"
1013
+ });
1014
+
1015
+ // Register provider with OAuth support for /login
1016
+ pi.registerProvider("corporate-ai", {
1017
+ baseUrl: "https://ai.corp.com",
1018
+ api: "openai-responses",
1019
+ models: [...],
1020
+ oauth: {
1021
+ name: "Corporate AI (SSO)",
1022
+ async login(callbacks) {
1023
+ // Custom OAuth flow
1024
+ callbacks.onAuth({ url: "https://sso.corp.com/..." });
1025
+ const code = await callbacks.onPrompt({ message: "Enter code:" });
1026
+ return { refresh: code, access: code, expires: Date.now() + 3600000 };
1027
+ },
1028
+ async refreshToken(credentials) {
1029
+ // Refresh logic
1030
+ return credentials;
1031
+ },
1032
+ getApiKey(credentials) {
1033
+ return credentials.access;
1034
+ }
1035
+ }
1036
+ });
1037
+ ```
1038
+
1039
+ **Config options:**
1040
+ - `baseUrl` - API endpoint URL. Required when defining models.
1041
+ - `apiKey` - API key or environment variable name. Required when defining models (unless `oauth` provided).
1042
+ - `api` - API type: `"anthropic-messages"`, `"openai-completions"`, `"openai-responses"`, etc.
1043
+ - `headers` - Custom headers to include in requests.
1044
+ - `authHeader` - If true, adds `Authorization: Bearer` header automatically.
1045
+ - `models` - Array of model definitions. If provided, replaces all existing models for this provider.
1046
+ - `oauth` - OAuth provider config for `/login` support. When provided, the provider appears in the login menu.
1047
+ - `streamSimple` - Custom streaming implementation for non-standard APIs.
1048
+
1049
+ See [custom-provider.md](custom-provider.md) for advanced topics: custom streaming APIs, OAuth details, model definition reference.
1050
+
1057
1051
  ## State Management
1058
1052
 
1059
1053
  Extensions with state should store it in tool result `details` for proper branching support:
@@ -1214,6 +1208,7 @@ The built-in limit is **50KB** (~10k tokens) and **2000 lines**, whichever is hi
1214
1208
  import {
1215
1209
  truncateHead, // Keep first N lines/bytes (good for file reads, search results)
1216
1210
  truncateTail, // Keep last N lines/bytes (good for logs, command output)
1211
+ truncateLine, // Truncate a single line to maxBytes with ellipsis
1217
1212
  formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
1218
1213
  DEFAULT_MAX_BYTES, // 50KB
1219
1214
  DEFAULT_MAX_LINES, // 2000
@@ -1272,7 +1267,7 @@ export default function (pi: ExtensionAPI) {
1272
1267
 
1273
1268
  ### Custom Rendering
1274
1269
 
1275
- Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API.
1270
+ 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
1271
 
1277
1272
  Tool output is wrapped in a `Box` that handles padding and background. Your render methods return `Component` instances (typically `Text`).
1278
1273
 
@@ -1388,12 +1383,6 @@ const text = await ctx.ui.editor("Edit:", "prefilled text");
1388
1383
  ctx.ui.notify("Done!", "info"); // "info" | "warning" | "error"
1389
1384
  ```
1390
1385
 
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
1386
  #### Timed Dialogs with Countdown
1398
1387
 
1399
1388
  Dialogs support a `timeout` option that auto-dismisses with a live countdown display:
@@ -1481,7 +1470,7 @@ const current = ctx.ui.getEditorText();
1481
1470
  ctx.ui.setEditorComponent((tui, theme, keybindings) => new VimEditor(tui, theme, keybindings));
1482
1471
  ctx.ui.setEditorComponent(undefined); // Restore default editor
1483
1472
 
1484
- // Theme management
1473
+ // Theme management (see themes.md for creating themes)
1485
1474
  const themes = ctx.ui.getAllThemes(); // [{ name: "dark", path: "/..." | undefined }, ...]
1486
1475
  const lightTheme = ctx.ui.getTheme("light"); // Load without switching
1487
1476
  const result = ctx.ui.setTheme("light"); // Switch by name
@@ -1492,14 +1481,6 @@ ctx.ui.setTheme(lightTheme!); // Or switch by Theme object
1492
1481
  ctx.ui.theme.fg("accent", "styled text"); // Access current theme
1493
1482
  ```
1494
1483
 
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
1484
  ### Custom Components
1504
1485
 
1505
1486
  For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
@@ -1558,8 +1539,6 @@ const result = await ctx.ui.custom<string | null>(
1558
1539
 
1559
1540
  See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for examples.
1560
1541
 
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
1542
  ### Custom Editor
1564
1543
 
1565
1544
  Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
@@ -1601,8 +1580,6 @@ export default function (pi: ExtensionAPI) {
1601
1580
 
1602
1581
  See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
1603
1582
 
1604
- **Examples:** [modal-editor.ts](../examples/extensions/modal-editor.ts)
1605
-
1606
1583
  ### Message Rendering
1607
1584
 
1608
1585
  Register a custom renderer for messages with your `customType`:
@@ -1636,7 +1613,7 @@ pi.sendMessage({
1636
1613
 
1637
1614
  ### Theme Colors
1638
1615
 
1639
- All render functions receive a `theme` object:
1616
+ All render functions receive a `theme` object. See [themes.md](themes.md) for creating custom themes and the full color palette.
1640
1617
 
1641
1618
  ```typescript
1642
1619
  // Foreground colors
@@ -1654,6 +1631,19 @@ theme.italic(text)
1654
1631
  theme.strikethrough(text)
1655
1632
  ```
1656
1633
 
1634
+ For syntax highlighting in custom tool renderers:
1635
+
1636
+ ```typescript
1637
+ import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
1638
+
1639
+ // Highlight code with explicit language
1640
+ const highlighted = highlightCode("const x = 1;", "typescript", theme);
1641
+
1642
+ // Auto-detect language from file path
1643
+ const lang = getLanguageFromPath("/path/to/file.rs"); // "rust"
1644
+ const highlighted = highlightCode(code, lang, theme);
1645
+ ```
1646
+
1657
1647
  ## Error Handling
1658
1648
 
1659
1649
  - Extension errors are logged, agent continues
@@ -1665,7 +1655,81 @@ theme.strikethrough(text)
1665
1655
  | Mode | UI Methods | Notes |
1666
1656
  |------|-----------|-------|
1667
1657
  | Interactive | Full TUI | Normal operation |
1668
- | RPC | JSON protocol | Host handles UI |
1658
+ | RPC (`--mode rpc`) | JSON protocol | Host handles UI, see [rpc.md](rpc.md) |
1659
+ | JSON (`--mode json`) | No-op | Event stream to stdout, see [json.md](json.md) |
1669
1660
  | Print (`-p`) | No-op | Extensions run but can't prompt |
1670
1661
 
1671
- In print mode, check `ctx.hasUI` before using UI methods.
1662
+ In non-interactive modes, check `ctx.hasUI` before using UI methods.
1663
+
1664
+ ## Examples Reference
1665
+
1666
+ All examples in [examples/extensions/](../examples/extensions/).
1667
+
1668
+ | Example | Description | Key APIs |
1669
+ |---------|-------------|----------|
1670
+ | **Tools** |||
1671
+ | `hello.ts` | Minimal tool registration | `registerTool` |
1672
+ | `question.ts` | Tool with user interaction | `registerTool`, `ui.select` |
1673
+ | `questionnaire.ts` | Multi-step wizard tool | `registerTool`, `ui.custom` |
1674
+ | `todo.ts` | Stateful tool with persistence | `registerTool`, `appendEntry`, `renderResult`, session events |
1675
+ | `truncated-tool.ts` | Output truncation example | `registerTool`, `truncateHead` |
1676
+ | `tool-override.ts` | Override built-in read tool | `registerTool` (same name as built-in) |
1677
+ | **Commands** |||
1678
+ | `pirate.ts` | Modify system prompt per-turn | `registerCommand`, `before_agent_start` |
1679
+ | `summarize.ts` | Conversation summary command | `registerCommand`, `ui.custom` |
1680
+ | `handoff.ts` | Cross-provider model handoff | `registerCommand`, `ui.editor`, `ui.custom` |
1681
+ | `qna.ts` | Q&A with custom UI | `registerCommand`, `ui.custom`, `setEditorText` |
1682
+ | `send-user-message.ts` | Inject user messages | `registerCommand`, `sendUserMessage` |
1683
+ | `shutdown-command.ts` | Graceful shutdown command | `registerCommand`, `shutdown()` |
1684
+ | **Events & Gates** |||
1685
+ | `permission-gate.ts` | Block dangerous commands | `on("tool_call")`, `ui.confirm` |
1686
+ | `protected-paths.ts` | Block writes to specific paths | `on("tool_call")` |
1687
+ | `confirm-destructive.ts` | Confirm session changes | `on("session_before_switch")`, `on("session_before_fork")` |
1688
+ | `dirty-repo-guard.ts` | Warn on dirty git repo | `on("session_before_*")`, `exec` |
1689
+ | `input-transform.ts` | Transform user input | `on("input")` |
1690
+ | `model-status.ts` | React to model changes | `on("model_select")`, `setStatus` |
1691
+ | `claude-rules.ts` | Load rules from files | `on("session_start")`, `on("before_agent_start")` |
1692
+ | `file-trigger.ts` | File watcher triggers messages | `sendMessage` |
1693
+ | **Compaction & Sessions** |||
1694
+ | `custom-compaction.ts` | Custom compaction summary | `on("session_before_compact")` |
1695
+ | `trigger-compact.ts` | Trigger compaction manually | `compact()` |
1696
+ | `git-checkpoint.ts` | Git stash on turns | `on("turn_end")`, `on("session_fork")`, `exec` |
1697
+ | `auto-commit-on-exit.ts` | Commit on shutdown | `on("session_shutdown")`, `exec` |
1698
+ | **UI Components** |||
1699
+ | `status-line.ts` | Footer status indicator | `setStatus`, session events |
1700
+ | `custom-footer.ts` | Replace footer entirely | `registerCommand`, `setFooter` |
1701
+ | `custom-header.ts` | Replace startup header | `on("session_start")`, `setHeader` |
1702
+ | `modal-editor.ts` | Vim-style modal editor | `setEditorComponent`, `CustomEditor` |
1703
+ | `rainbow-editor.ts` | Custom editor styling | `setEditorComponent` |
1704
+ | `widget-placement.ts` | Widget above/below editor | `setWidget` |
1705
+ | `overlay-test.ts` | Overlay components | `ui.custom` with overlay options |
1706
+ | `overlay-qa-tests.ts` | Comprehensive overlay tests | `ui.custom`, all overlay options |
1707
+ | `notify.ts` | Simple notifications | `ui.notify` |
1708
+ | `timed-confirm.ts` | Dialogs with timeout | `ui.confirm` with timeout/signal |
1709
+ | `mac-system-theme.ts` | Auto-switch theme | `setTheme`, `exec` |
1710
+ | **Complex Extensions** |||
1711
+ | `plan-mode/` | Full plan mode implementation | All event types, `registerCommand`, `registerShortcut`, `registerFlag`, `setStatus`, `setWidget`, `sendMessage`, `setActiveTools` |
1712
+ | `preset.ts` | Saveable presets (model, tools, thinking) | `registerCommand`, `registerShortcut`, `registerFlag`, `setModel`, `setActiveTools`, `setThinkingLevel`, `appendEntry` |
1713
+ | `tools.ts` | Toggle tools on/off UI | `registerCommand`, `setActiveTools`, `SettingsList`, session events |
1714
+ | **Remote & Sandbox** |||
1715
+ | `ssh.ts` | SSH remote execution | `registerFlag`, `on("user_bash")`, `on("before_agent_start")`, tool operations |
1716
+ | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
1717
+ | `sandbox/` | Sandboxed tool execution | Tool operations |
1718
+ | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
1719
+ | **Games** |||
1720
+ | `snake.ts` | Snake game | `registerCommand`, `ui.custom`, keyboard handling |
1721
+ | `space-invaders.ts` | Space Invaders game | `registerCommand`, `ui.custom` |
1722
+ | `doom-overlay/` | Doom in overlay | `ui.custom` with overlay |
1723
+ | **Providers** |||
1724
+ | `custom-provider-anthropic/` | Custom Anthropic proxy | `registerProvider` |
1725
+ | `custom-provider-gitlab-duo/` | GitLab Duo integration | `registerProvider` with OAuth |
1726
+ | **Messages & Communication** |||
1727
+ | `message-renderer.ts` | Custom message rendering | `registerMessageRenderer`, `sendMessage` |
1728
+ | `event-bus.ts` | Inter-extension events | `pi.events` |
1729
+ | **Session Metadata** |||
1730
+ | `session-name.ts` | Name sessions for selector | `setSessionName`, `getSessionName` |
1731
+ | `bookmark.ts` | Bookmark entries for /tree | `setLabel` |
1732
+ | **Misc** |||
1733
+ | `antigravity-image-gen.ts` | Image generation tool | `registerTool`, Google Antigravity |
1734
+ | `inline-bash.ts` | Inline bash in tool calls | `on("tool_call")` |
1735
+ | `with-deps/` | Extension with npm dependencies | Package structure with `package.json` |
Binary file
Binary file
Binary file