@astralyn/pi 0.82.6 → 0.83.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 (263) hide show
  1. package/CHANGELOG.md +61 -5099
  2. package/README.md +12 -111
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +9 -2
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/credential-print.d.ts +23 -0
  7. package/dist/cli/credential-print.d.ts.map +1 -0
  8. package/dist/cli/credential-print.js +116 -0
  9. package/dist/cli/credential-print.js.map +1 -0
  10. package/dist/cli/session-picker.d.ts.map +1 -1
  11. package/dist/cli/session-picker.js +11 -13
  12. package/dist/cli/session-picker.js.map +1 -1
  13. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  14. package/dist/core/agent-session-runtime.js +3 -0
  15. package/dist/core/agent-session-runtime.js.map +1 -1
  16. package/dist/core/agent-session.d.ts +1 -1
  17. package/dist/core/agent-session.d.ts.map +1 -1
  18. package/dist/core/agent-session.js +13 -6
  19. package/dist/core/agent-session.js.map +1 -1
  20. package/dist/core/extensions/runner.d.ts +1 -0
  21. package/dist/core/extensions/runner.d.ts.map +1 -1
  22. package/dist/core/extensions/runner.js +7 -0
  23. package/dist/core/extensions/runner.js.map +1 -1
  24. package/dist/core/extensions/types.d.ts +11 -0
  25. package/dist/core/extensions/types.d.ts.map +1 -1
  26. package/dist/core/extensions/types.js.map +1 -1
  27. package/dist/core/footer-data-provider.d.ts +10 -0
  28. package/dist/core/footer-data-provider.d.ts.map +1 -1
  29. package/dist/core/footer-data-provider.js +1 -1
  30. package/dist/core/footer-data-provider.js.map +1 -1
  31. package/dist/core/model-runtime.d.ts +2 -0
  32. package/dist/core/model-runtime.d.ts.map +1 -1
  33. package/dist/core/model-runtime.js.map +1 -1
  34. package/dist/core/package-manager.d.ts.map +1 -1
  35. package/dist/core/package-manager.js +13 -6
  36. package/dist/core/package-manager.js.map +1 -1
  37. package/dist/core/resource-loader.d.ts +15 -0
  38. package/dist/core/resource-loader.d.ts.map +1 -1
  39. package/dist/core/resource-loader.js +70 -9
  40. package/dist/core/resource-loader.js.map +1 -1
  41. package/dist/core/session-manager.d.ts.map +1 -1
  42. package/dist/core/session-manager.js +2 -2
  43. package/dist/core/session-manager.js.map +1 -1
  44. package/dist/core/tools/bash.d.ts +1 -5
  45. package/dist/core/tools/bash.d.ts.map +1 -1
  46. package/dist/core/tools/bash.js +16 -41
  47. package/dist/core/tools/bash.js.map +1 -1
  48. package/dist/core/tools/edit.d.ts.map +1 -1
  49. package/dist/core/tools/edit.js +42 -11
  50. package/dist/core/tools/edit.js.map +1 -1
  51. package/dist/core/tools/find.d.ts.map +1 -1
  52. package/dist/core/tools/find.js +40 -11
  53. package/dist/core/tools/find.js.map +1 -1
  54. package/dist/core/tools/grep.d.ts.map +1 -1
  55. package/dist/core/tools/grep.js +17 -8
  56. package/dist/core/tools/grep.js.map +1 -1
  57. package/dist/core/tools/ls.d.ts.map +1 -1
  58. package/dist/core/tools/ls.js +3 -3
  59. package/dist/core/tools/ls.js.map +1 -1
  60. package/dist/core/tools/read.d.ts.map +1 -1
  61. package/dist/core/tools/read.js +4 -4
  62. package/dist/core/tools/read.js.map +1 -1
  63. package/dist/core/tools/render-utils.d.ts +7 -0
  64. package/dist/core/tools/render-utils.d.ts.map +1 -1
  65. package/dist/core/tools/render-utils.js +11 -0
  66. package/dist/core/tools/render-utils.js.map +1 -1
  67. package/dist/core/tools/write.d.ts.map +1 -1
  68. package/dist/core/tools/write.js +2 -3
  69. package/dist/core/tools/write.js.map +1 -1
  70. package/dist/core/trust-manager.d.ts.map +1 -1
  71. package/dist/core/trust-manager.js +48 -9
  72. package/dist/core/trust-manager.js.map +1 -1
  73. package/dist/extensions/deepwiki/render.d.ts.map +1 -1
  74. package/dist/extensions/deepwiki/render.js +34 -22
  75. package/dist/extensions/deepwiki/render.js.map +1 -1
  76. package/dist/extensions/index.d.ts.map +1 -1
  77. package/dist/extensions/index.js +0 -2
  78. package/dist/extensions/index.js.map +1 -1
  79. package/dist/extensions/llama/provider.d.ts.map +1 -1
  80. package/dist/extensions/llama/provider.js +1 -1
  81. package/dist/extensions/llama/provider.js.map +1 -1
  82. package/dist/extensions/question/dialog.d.ts.map +1 -1
  83. package/dist/extensions/question/dialog.js +29 -10
  84. package/dist/extensions/question/dialog.js.map +1 -1
  85. package/dist/extensions/question/index.d.ts.map +1 -1
  86. package/dist/extensions/question/index.js +7 -2
  87. package/dist/extensions/question/index.js.map +1 -1
  88. package/dist/extensions/question/render.d.ts +4 -8
  89. package/dist/extensions/question/render.d.ts.map +1 -1
  90. package/dist/extensions/question/render.js +202 -29
  91. package/dist/extensions/question/render.js.map +1 -1
  92. package/dist/extensions/question/results.d.ts.map +1 -1
  93. package/dist/extensions/question/results.js +1 -0
  94. package/dist/extensions/question/results.js.map +1 -1
  95. package/dist/extensions/question/schema.d.ts.map +1 -1
  96. package/dist/extensions/question/schema.js +2 -2
  97. package/dist/extensions/question/schema.js.map +1 -1
  98. package/dist/extensions/question/types.d.ts +1 -0
  99. package/dist/extensions/question/types.d.ts.map +1 -1
  100. package/dist/extensions/question/types.js +1 -1
  101. package/dist/extensions/question/types.js.map +1 -1
  102. package/dist/extensions/router/stream.d.ts +1 -0
  103. package/dist/extensions/router/stream.d.ts.map +1 -1
  104. package/dist/extensions/router/stream.js +44 -13
  105. package/dist/extensions/router/stream.js.map +1 -1
  106. package/dist/extensions/subagent/constants.d.ts +1 -0
  107. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  108. package/dist/extensions/subagent/constants.js +1 -0
  109. package/dist/extensions/subagent/constants.js.map +1 -1
  110. package/dist/extensions/subagent/index.d.ts.map +1 -1
  111. package/dist/extensions/subagent/index.js +2 -0
  112. package/dist/extensions/subagent/index.js.map +1 -1
  113. package/dist/extensions/subagent/render.d.ts.map +1 -1
  114. package/dist/extensions/subagent/render.js +121 -48
  115. package/dist/extensions/subagent/render.js.map +1 -1
  116. package/dist/extensions/subagent/retry.d.ts +17 -0
  117. package/dist/extensions/subagent/retry.d.ts.map +1 -0
  118. package/dist/extensions/subagent/retry.js +41 -0
  119. package/dist/extensions/subagent/retry.js.map +1 -0
  120. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  121. package/dist/extensions/subagent/runner.js +33 -5
  122. package/dist/extensions/subagent/runner.js.map +1 -1
  123. package/dist/extensions/subagent/sdk-runner.d.ts +6 -0
  124. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  125. package/dist/extensions/subagent/sdk-runner.js +46 -24
  126. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  127. package/dist/extensions/subagent/types.d.ts +7 -0
  128. package/dist/extensions/subagent/types.d.ts.map +1 -1
  129. package/dist/extensions/subagent/types.js.map +1 -1
  130. package/dist/extensions/todo/index.d.ts.map +1 -1
  131. package/dist/extensions/todo/index.js +1 -1
  132. package/dist/extensions/todo/index.js.map +1 -1
  133. package/dist/extensions/todo/state.d.ts.map +1 -1
  134. package/dist/extensions/todo/state.js +10 -2
  135. package/dist/extensions/todo/state.js.map +1 -1
  136. package/dist/extensions/todo/view.d.ts +1 -1
  137. package/dist/extensions/todo/view.d.ts.map +1 -1
  138. package/dist/extensions/todo/view.js +179 -34
  139. package/dist/extensions/todo/view.js.map +1 -1
  140. package/dist/main.d.ts.map +1 -1
  141. package/dist/main.js +43 -0
  142. package/dist/main.js.map +1 -1
  143. package/dist/migrations.d.ts.map +1 -1
  144. package/dist/migrations.js +2 -1
  145. package/dist/migrations.js.map +1 -1
  146. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  147. package/dist/modes/interactive/components/armin.js +5 -0
  148. package/dist/modes/interactive/components/armin.js.map +1 -1
  149. package/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  150. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  151. package/dist/modes/interactive/components/bash-execution.js +4 -2
  152. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  153. package/dist/modes/interactive/components/countdown-timer.d.ts +13 -6
  154. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  155. package/dist/modes/interactive/components/countdown-timer.js +54 -17
  156. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  157. package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
  158. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  159. package/dist/modes/interactive/components/extension-selector.js +10 -6
  160. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  161. package/dist/modes/interactive/components/keybinding-hints.d.ts +11 -1
  162. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  163. package/dist/modes/interactive/components/keybinding-hints.js +56 -0
  164. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  165. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  166. package/dist/modes/interactive/components/model-selector.js +4 -1
  167. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  168. package/dist/modes/interactive/components/session-selector.d.ts +3 -0
  169. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/session-selector.js +52 -2
  171. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  172. package/dist/modes/interactive/components/tool-execution.d.ts +10 -0
  173. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/tool-execution.js +133 -18
  175. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  176. package/dist/modes/interactive/components/tool-group.d.ts +1 -0
  177. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  178. package/dist/modes/interactive/components/tool-group.js +5 -0
  179. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  180. package/dist/modes/interactive/components/tree-selector.d.ts +10 -1
  181. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  182. package/dist/modes/interactive/components/tree-selector.js +55 -2
  183. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  184. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  185. package/dist/modes/interactive/external-editor.js +40 -3
  186. package/dist/modes/interactive/external-editor.js.map +1 -1
  187. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  188. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  189. package/dist/modes/interactive/interactive-mode.js +92 -24
  190. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  191. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  192. package/dist/modes/interactive/theme/theme.js +3 -2
  193. package/dist/modes/interactive/theme/theme.js.map +1 -1
  194. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  195. package/dist/modes/rpc/rpc-mode.js +13 -0
  196. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  197. package/dist/utils/paths.d.ts +5 -0
  198. package/dist/utils/paths.d.ts.map +1 -1
  199. package/dist/utils/paths.js +7 -0
  200. package/dist/utils/paths.js.map +1 -1
  201. package/docs/bundled/README.md +13 -15
  202. package/docs/bundled/extensions/deepwiki.md +1 -1
  203. package/docs/bundled/extensions/question.md +7 -5
  204. package/docs/bundled/extensions/router.md +3 -4
  205. package/docs/bundled/extensions/statusline.md +0 -1
  206. package/docs/bundled/extensions/subagent.md +4 -3
  207. package/docs/bundled/extensions/todo.md +1 -1
  208. package/docs/bundled/themes.md +1 -1
  209. package/docs/bundled/tool-presentation.md +17 -16
  210. package/docs/compaction.md +25 -30
  211. package/docs/custom-provider.md +298 -583
  212. package/docs/docs.json +0 -8
  213. package/docs/extensions.md +132 -121
  214. package/docs/index.md +18 -74
  215. package/docs/json.md +20 -14
  216. package/docs/models.md +193 -151
  217. package/docs/providers.md +2 -1
  218. package/docs/quickstart.md +3 -3
  219. package/docs/rpc.md +166 -124
  220. package/docs/sdk.md +119 -178
  221. package/docs/security.md +1 -1
  222. package/docs/session-format.md +139 -119
  223. package/docs/skills.md +0 -1
  224. package/docs/themes.md +2 -2
  225. package/docs/tui.md +411 -549
  226. package/docs/usage.md +3 -11
  227. package/examples/README.md +6 -1
  228. package/examples/extensions/README.md +13 -33
  229. package/examples/extensions/custom-provider-anthropic/index.ts +9 -3
  230. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  231. package/examples/extensions/truncated-tool.ts +2 -2
  232. package/examples/sdk/12-full-control.ts +2 -0
  233. package/npm-shrinkwrap.json +25 -25
  234. package/package.json +5 -5
  235. package/dist/extensions/plan/constants.d.ts +0 -40
  236. package/dist/extensions/plan/constants.d.ts.map +0 -1
  237. package/dist/extensions/plan/constants.js +0 -69
  238. package/dist/extensions/plan/constants.js.map +0 -1
  239. package/dist/extensions/plan/index.d.ts +0 -3
  240. package/dist/extensions/plan/index.d.ts.map +0 -1
  241. package/dist/extensions/plan/index.js +0 -323
  242. package/dist/extensions/plan/index.js.map +0 -1
  243. package/dist/extensions/plan/schema.d.ts +0 -15
  244. package/dist/extensions/plan/schema.d.ts.map +0 -1
  245. package/dist/extensions/plan/schema.js +0 -13
  246. package/dist/extensions/plan/schema.js.map +0 -1
  247. package/dist/extensions/plan/state.d.ts +0 -29
  248. package/dist/extensions/plan/state.d.ts.map +0 -1
  249. package/dist/extensions/plan/state.js +0 -74
  250. package/dist/extensions/plan/state.js.map +0 -1
  251. package/dist/extensions/plan/storage.d.ts +0 -18
  252. package/dist/extensions/plan/storage.d.ts.map +0 -1
  253. package/dist/extensions/plan/storage.js +0 -58
  254. package/dist/extensions/plan/storage.js.map +0 -1
  255. package/dist/extensions/plan/view.d.ts +0 -36
  256. package/dist/extensions/plan/view.d.ts.map +0 -1
  257. package/dist/extensions/plan/view.js +0 -74
  258. package/dist/extensions/plan/view.js.map +0 -1
  259. package/docs/bundled/extensions/README.md +0 -19
  260. package/docs/bundled/extensions/plan.md +0 -33
  261. package/examples/extensions/plan-mode/README.md +0 -66
  262. package/examples/extensions/plan-mode/index.ts +0 -390
  263. package/examples/extensions/plan-mode/utils.ts +0 -168
package/docs/sdk.md CHANGED
@@ -53,11 +53,10 @@ The main factory function for a single `AgentSession`.
53
53
  import { createAgentSession, SessionManager } from "@astralyn/pi";
54
54
 
55
55
  // Minimal: defaults with DefaultResourceLoader
56
- const { session } = await createAgentSession();
56
+ const { session: defaultSession } = await createAgentSession();
57
57
 
58
58
  // Custom: override specific options
59
- const { session } = await createAgentSession({
60
- model: myModel,
59
+ const { session: customSession } = await createAgentSession({
61
60
  tools: ["read", "bash"],
62
61
  sessionManager: SessionManager.inMemory(),
63
62
  });
@@ -65,18 +64,18 @@ const { session } = await createAgentSession({
65
64
 
66
65
  ### AgentSession
67
66
 
68
- The session manages agent lifecycle, message history, model state, compaction, and event streaming.
67
+ The session manages agent lifecycle, message history, model state, compaction, and event streaming. Common API members include:
69
68
 
70
69
  ```typescript
71
70
  interface AgentSession {
72
71
  // Send a prompt and wait for completion
73
72
  prompt(text: string, options?: PromptOptions): Promise<void>;
74
73
 
75
- // Queue messages during streaming
76
- steer(text: string): Promise<void>;
77
- followUp(text: string): Promise<void>;
74
+ // Queue messages, optionally with image attachments
75
+ steer(text: string, images?: ImageContent[]): Promise<void>;
76
+ followUp(text: string, images?: ImageContent[]): Promise<void>;
78
77
 
79
- // Subscribe to events (returns unsubscribe function)
78
+ // Subscribe to events (returns an unsubscribe function)
80
79
  subscribe(listener: (event: AgentSessionEvent) => void): () => void;
81
80
 
82
81
  // Session info
@@ -86,7 +85,7 @@ interface AgentSession {
86
85
  // Model control
87
86
  setModel(model: Model): Promise<void>;
88
87
  setThinkingLevel(level: ThinkingLevel): void;
89
- cycleModel(): Promise<ModelCycleResult | undefined>;
88
+ cycleModel(direction?: "forward" | "backward"): Promise<ModelCycleResult | undefined>;
90
89
  cycleThinkingLevel(): ThinkingLevel | undefined;
91
90
 
92
91
  // State access
@@ -97,13 +96,16 @@ interface AgentSession {
97
96
  isStreaming: boolean;
98
97
 
99
98
  // In-place tree navigation within the current session file
100
- navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }): Promise<{ editorText?: string; cancelled: boolean }>;
101
-
102
- // Compaction
99
+ navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }): Promise<{
100
+ editorText?: string;
101
+ cancelled: boolean;
102
+ aborted?: boolean;
103
+ summaryEntry?: BranchSummaryEntry;
104
+ }>;
105
+
106
+ // Compaction and cancellation
103
107
  compact(customInstructions?: string): Promise<CompactionResult>;
104
108
  abortCompaction(): void;
105
-
106
- // Abort current operation
107
109
  abort(): Promise<void>;
108
110
 
109
111
  // Cleanup
@@ -130,8 +132,8 @@ import {
130
132
  SessionManager,
131
133
  } from "@astralyn/pi";
132
134
 
133
- const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
134
- const services = await createAgentSessionServices({ cwd });
135
+ const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, agentDir, sessionManager, sessionStartEvent }) => {
136
+ const services = await createAgentSessionServices({ cwd, agentDir });
135
137
  return {
136
138
  ...(await createAgentSessionFromServices({
137
139
  services,
@@ -161,8 +163,8 @@ const runtime = await createAgentSessionRuntime(createRuntime, {
161
163
  Important behavior:
162
164
 
163
165
  - `runtime.session` changes after those operations
164
- - event subscriptions are attached to a specific `AgentSession`, so re-subscribe after replacement
165
- - if you use extensions, call `runtime.session.bindExtensions(...)` again for the new session
166
+ - event subscriptions are attached to a specific `AgentSession`, so re-subscribe after replacement (or use `runtime.setRebindSession()`)
167
+ - if you use extensions, bind them again for the new session (or do so from the rebind callback)
166
168
  - creation returns diagnostics on `runtime.diagnostics`
167
169
  - if runtime creation or replacement fails, the method throws and the caller decides how to handle it
168
170
 
@@ -196,7 +198,7 @@ interface PromptOptions {
196
198
  - `true` when the prompt was accepted, queued, or handled immediately
197
199
  - `false` when prompt preflight rejected before acceptance
198
200
 
199
- It fires before `prompt()` resolves. `prompt()` still resolves only after the full accepted run finishes, including retries. Failures after acceptance are reported through the normal event and message stream, not through `preflightResult(false)`.
201
+ It fires before `prompt()` resolves. A prompt that starts a run resolves after the full accepted run finishes, including retries; a queued or immediately handled prompt resolves after acceptance or handling. Failures after acceptance are reported through the normal event and message stream, not through `preflightResult(false)`.
200
202
 
201
203
  The `prompt()` method handles prompt templates, extension commands, and message sending:
202
204
 
@@ -206,7 +208,7 @@ await session.prompt("What files are here?");
206
208
 
207
209
  // With images
208
210
  await session.prompt("What's in this image?", {
209
- images: [{ type: "image", source: { type: "base64", mediaType: "image/png", data: "..." } }]
211
+ images: [{ type: "image", mimeType: "image/png", data: "..." }],
210
212
  });
211
213
 
212
214
  // During streaming: must specify how to queue the message
@@ -218,17 +220,17 @@ await session.prompt("After you're done, also check X", { streamingBehavior: "fo
218
220
  - **Extension commands** (e.g., `/mycommand`): Execute immediately, even during streaming. They manage their own LLM interaction via `pi.sendMessage()`.
219
221
  - **File-based prompt templates** (from `.md` files): Expanded to their content before sending or queueing.
220
222
  - **During streaming without `streamingBehavior`**: Throws an error. Use `steer()` or `followUp()` directly, or specify the option.
221
- - **`preflightResult(true)`**: Means the prompt was accepted, queued, or handled immediately.
222
- - **`preflightResult(false)`**: Means preflight rejected before acceptance.
223
223
 
224
224
  For explicit queueing during streaming:
225
225
 
226
226
  ```typescript
227
+ const image = { type: "image" as const, mimeType: "image/png", data: "..." };
228
+
227
229
  // Queue a steering message for delivery after the current assistant turn finishes its tool calls
228
- await session.steer("New instruction");
230
+ await session.steer("New instruction", [image]);
229
231
 
230
- // Wait for agent to finish (delivered only when agent stops)
231
- await session.followUp("After you're done, also do this");
232
+ // Queue a follow-up for when there are no more tool calls or steering messages
233
+ await session.followUp("After you're done, also do this", [image]);
232
234
  ```
233
235
 
234
236
  Both `steer()` and `followUp()` expand file-based prompt templates but error on extension commands (extension commands cannot be queued).
@@ -302,6 +304,9 @@ session.subscribe((event) => {
302
304
  case "agent_end":
303
305
  // Agent finished (event.messages contains new messages)
304
306
  break;
307
+ case "agent_settled":
308
+ // Agent, retries, compaction, and queued continuations have settled
309
+ break;
305
310
 
306
311
  // Turn lifecycle (one LLM response + tool calls)
307
312
  case "turn_start":
@@ -311,7 +316,7 @@ session.subscribe((event) => {
311
316
  // event.toolResults: tool results from this turn
312
317
  break;
313
318
 
314
- // Session events (queue, compaction, retry)
319
+ // Session events (queue, compaction, retry, and persisted state)
315
320
  case "queue_update":
316
321
  console.log(event.steering, event.followUp);
317
322
  break;
@@ -322,6 +327,10 @@ session.subscribe((event) => {
322
327
  case "summarization_retry_scheduled":
323
328
  case "summarization_retry_attempt_start":
324
329
  case "summarization_retry_finished":
330
+ case "entry_appended":
331
+ case "session_info_changed":
332
+ case "thinking_level_changed":
333
+ case "bash_execution_update":
325
334
  break;
326
335
  }
327
336
  });
@@ -347,7 +356,7 @@ const { session } = await createAgentSession({
347
356
  - `.pi/skills/`
348
357
  - `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
349
358
  - Project prompts (`.pi/prompts/`)
350
- - Context files (`AGENTS.md` walking up from cwd)
359
+ - Context files (`AGENTS.md` or `CLAUDE.md`, walking up from cwd)
351
360
  - Session directory naming
352
361
 
353
362
  `agentDir` is used by `DefaultResourceLoader` for:
@@ -356,7 +365,7 @@ const { session } = await createAgentSession({
356
365
  - `skills/` under `agentDir` (for example `~/.pi/agent/skills/`)
357
366
  - `~/.agents/skills/`
358
367
  - Global prompts (`prompts/`)
359
- - Global context file (`AGENTS.md`)
368
+ - Global context file (`AGENTS.md` or `CLAUDE.md`)
360
369
  - Settings (`settings.json`)
361
370
  - Custom models (`models.json`)
362
371
  - Credentials (`auth.json`)
@@ -367,32 +376,33 @@ When you pass a custom `ResourceLoader`, `cwd` and `agentDir` no longer control
367
376
  ### Model
368
377
 
369
378
  ```typescript
370
- import { getModel } from "@earendil-works/pi-ai";
371
- import { ModelRuntime } from "@astralyn/pi";
379
+ import { getModel } from "@earendil-works/pi-ai/compat";
380
+ import { createAgentSession, ModelRuntime } from "@astralyn/pi";
372
381
 
373
382
  const modelRuntime = await ModelRuntime.create();
374
383
 
375
- // Find specific built-in model (doesn't check if API key exists)
384
+ // Find specific built-in models (doesn't check whether API keys exist)
376
385
  const opus = getModel("anthropic", "claude-opus-4-5");
377
- if (!opus) throw new Error("Model not found");
386
+ const sonnet = getModel("anthropic", "claude-sonnet-4-5");
387
+ if (!opus || !sonnet) throw new Error("Model not found");
378
388
 
379
389
  // Find any model by provider/id, including custom models from models.json
380
- // (doesn't check if API key exists)
390
+ // (doesn't check whether API keys exist)
381
391
  const customModel = modelRuntime.getModel("my-provider", "my-model");
382
392
 
383
- // Get only models that have valid authentication configured
393
+ // Get only models that have configured authentication
384
394
  const available = await modelRuntime.getAvailable();
385
395
 
386
396
  const { session } = await createAgentSession({
387
397
  model: opus,
388
398
  thinkingLevel: "medium", // off, minimal, low, medium, high, xhigh, max
389
-
399
+
390
400
  // Models for cycling (Ctrl+P in interactive mode)
391
401
  scopedModels: [
392
402
  { model: opus, thinkingLevel: "high" },
393
- { model: haiku, thinkingLevel: "off" },
403
+ { model: sonnet, thinkingLevel: "off" },
394
404
  ],
395
-
405
+
396
406
  modelRuntime,
397
407
  });
398
408
  ```
@@ -400,7 +410,7 @@ const { session } = await createAgentSession({
400
410
  If no model is provided:
401
411
  1. Tries to restore from session (if continuing)
402
412
  2. Uses default from settings
403
- 3. Falls back to first available model
413
+ 3. Prefers a known provider default among available models, then falls back to the first available model
404
414
 
405
415
  To match CLI model parsing, use the exported resolver helpers:
406
416
 
@@ -452,7 +462,7 @@ for (const provider of modelRuntime.getProviders()) {
452
462
  }
453
463
 
454
464
  // Runtime API key override (not persisted to disk)
455
- modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
465
+ await modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
456
466
 
457
467
  // Custom credential and model locations
458
468
  const customRuntime = await ModelRuntime.create({
@@ -465,7 +475,7 @@ const credentials = new InMemoryCredentialStore();
465
475
  const inMemoryRuntime = await ModelRuntime.create({ credentials });
466
476
 
467
477
  const { session } = await createAgentSession({
468
- modelRuntime: customRuntime,
478
+ modelRuntime: inMemoryRuntime,
469
479
  });
470
480
  ```
471
481
 
@@ -476,9 +486,11 @@ const { session } = await createAgentSession({
476
486
  Use a `ResourceLoader` to override the system prompt:
477
487
 
478
488
  ```typescript
479
- import { createAgentSession, DefaultResourceLoader } from "@astralyn/pi";
489
+ import { createAgentSession, DefaultResourceLoader, getAgentDir } from "@astralyn/pi";
480
490
 
481
491
  const loader = new DefaultResourceLoader({
492
+ cwd: process.cwd(),
493
+ agentDir: getAgentDir(),
482
494
  systemPromptOverride: () => "You are a helpful assistant.",
483
495
  });
484
496
  await loader.reload();
@@ -504,17 +516,17 @@ The `edit` tool returns `details.diff` for Pi's TUI display and `details.patch`
504
516
  import { createAgentSession } from "@astralyn/pi";
505
517
 
506
518
  // Read-only mode
507
- const { session } = await createAgentSession({
519
+ const { session: readOnlySession } = await createAgentSession({
508
520
  tools: ["read", "grep", "find", "ls"],
509
521
  });
510
522
 
511
523
  // Pick specific tools
512
- const { session } = await createAgentSession({
524
+ const { session: selectedToolsSession } = await createAgentSession({
513
525
  tools: ["read", "bash", "grep"],
514
526
  });
515
527
 
516
528
  // Disable one tool while keeping the rest available
517
- const { session } = await createAgentSession({
529
+ const { session: excludedToolsSession } = await createAgentSession({
518
530
  excludeTools: ["ask_question"],
519
531
  });
520
532
  ```
@@ -583,9 +595,11 @@ If you pass `tools`, include each custom or extension tool name you want enabled
583
595
  Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.pi/agent/extensions/`, `.pi/extensions/`, and settings.json extension sources.
584
596
 
585
597
  ```typescript
586
- import { createAgentSession, DefaultResourceLoader } from "@astralyn/pi";
598
+ import { createAgentSession, DefaultResourceLoader, getAgentDir } from "@astralyn/pi";
587
599
 
588
600
  const loader = new DefaultResourceLoader({
601
+ cwd: process.cwd(),
602
+ agentDir: getAgentDir(),
589
603
  additionalExtensionPaths: ["/path/to/my-extension.ts"],
590
604
  extensionFactories: [
591
605
  (pi) => {
@@ -605,7 +619,7 @@ Extensions can register tools, subscribe to events, add commands, and more. See
605
619
  **Named inline extensions:** By default, inline factories display as `<inline:1>`, `<inline:2>`, etc. in the startup Extensions list. To show a descriptive name instead, wrap the factory:
606
620
 
607
621
  ```typescript
608
- import type { InlineExtension } from "@astralyn/pi";
622
+ import { DefaultResourceLoader, getAgentDir, type InlineExtension } from "@astralyn/pi";
609
623
 
610
624
  const myProvider: InlineExtension = {
611
625
  name: "my-provider",
@@ -617,8 +631,11 @@ const myProvider: InlineExtension = {
617
631
  };
618
632
 
619
633
  const loader = new DefaultResourceLoader({
634
+ cwd: process.cwd(),
635
+ agentDir: getAgentDir(),
620
636
  extensionFactories: [myProvider],
621
637
  });
638
+ await loader.reload();
622
639
  ```
623
640
 
624
641
  This displays as `<inline:my-provider>` instead of `<inline:1>`. Bare factory functions are still accepted for backward compatibility.
@@ -626,10 +643,12 @@ This displays as `<inline:my-provider>` instead of `<inline:1>`. Bare factory fu
626
643
  **Event Bus:** Extensions can communicate via `pi.events`. Pass a shared `eventBus` to `DefaultResourceLoader` if you need to emit or listen from outside:
627
644
 
628
645
  ```typescript
629
- import { createEventBus, DefaultResourceLoader } from "@astralyn/pi";
646
+ import { createEventBus, DefaultResourceLoader, getAgentDir } from "@astralyn/pi";
630
647
 
631
648
  const eventBus = createEventBus();
632
649
  const loader = new DefaultResourceLoader({
650
+ cwd: process.cwd(),
651
+ agentDir: getAgentDir(),
633
652
  eventBus,
634
653
  });
635
654
  await loader.reload();
@@ -644,7 +663,9 @@ eventBus.on("my-extension:status", (data) => console.log(data));
644
663
  ```typescript
645
664
  import {
646
665
  createAgentSession,
666
+ createSyntheticSourceInfo,
647
667
  DefaultResourceLoader,
668
+ getAgentDir,
648
669
  type Skill,
649
670
  } from "@astralyn/pi";
650
671
 
@@ -653,10 +674,13 @@ const customSkill: Skill = {
653
674
  description: "Custom instructions",
654
675
  filePath: "/path/to/SKILL.md",
655
676
  baseDir: "/path/to",
656
- source: "custom",
677
+ sourceInfo: createSyntheticSourceInfo("/path/to/SKILL.md", { source: "sdk" }),
678
+ disableModelInvocation: false,
657
679
  };
658
680
 
659
681
  const loader = new DefaultResourceLoader({
682
+ cwd: process.cwd(),
683
+ agentDir: getAgentDir(),
660
684
  skillsOverride: (current) => ({
661
685
  skills: [...current.skills, customSkill],
662
686
  diagnostics: current.diagnostics,
@@ -672,9 +696,11 @@ const { session } = await createAgentSession({ resourceLoader: loader });
672
696
  ### Context Files
673
697
 
674
698
  ```typescript
675
- import { createAgentSession, DefaultResourceLoader } from "@astralyn/pi";
699
+ import { createAgentSession, DefaultResourceLoader, getAgentDir } from "@astralyn/pi";
676
700
 
677
701
  const loader = new DefaultResourceLoader({
702
+ cwd: process.cwd(),
703
+ agentDir: getAgentDir(),
678
704
  agentsFilesOverride: (current) => ({
679
705
  agentsFiles: [
680
706
  ...current.agentsFiles,
@@ -694,18 +720,23 @@ const { session } = await createAgentSession({ resourceLoader: loader });
694
720
  ```typescript
695
721
  import {
696
722
  createAgentSession,
723
+ createSyntheticSourceInfo,
697
724
  DefaultResourceLoader,
725
+ getAgentDir,
698
726
  type PromptTemplate,
699
727
  } from "@astralyn/pi";
700
728
 
701
729
  const customCommand: PromptTemplate = {
702
730
  name: "deploy",
703
731
  description: "Deploy the application",
704
- source: "(custom)",
732
+ filePath: "/virtual/prompts/deploy.md",
733
+ sourceInfo: createSyntheticSourceInfo("/virtual/prompts/deploy.md", { source: "sdk" }),
705
734
  content: "# Deploy\n\n1. Build\n2. Test\n3. Deploy",
706
735
  };
707
736
 
708
737
  const loader = new DefaultResourceLoader({
738
+ cwd: process.cwd(),
739
+ agentDir: getAgentDir(),
709
740
  promptsOverride: (current) => ({
710
741
  prompts: [...current.prompts, customCommand],
711
742
  diagnostics: current.diagnostics,
@@ -723,15 +754,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
723
754
  Sessions use a tree structure with `id`/`parentId` linking, enabling in-place branching.
724
755
 
725
756
  ```typescript
726
- import {
727
- type CreateAgentSessionRuntimeFactory,
728
- createAgentSession,
729
- createAgentSessionFromServices,
730
- createAgentSessionRuntime,
731
- createAgentSessionServices,
732
- getAgentDir,
733
- SessionManager,
734
- } from "@astralyn/pi";
757
+ import { createAgentSession, SessionManager } from "@astralyn/pi";
735
758
 
736
759
  // In-memory (no persistence)
737
760
  const { session } = await createAgentSession({
@@ -758,28 +781,12 @@ const { session: opened } = await createAgentSession({
758
781
 
759
782
  // List sessions
760
783
  const currentProjectSessions = await SessionManager.list(process.cwd());
761
- const allSessions = await SessionManager.listAll(process.cwd());
762
-
763
- // Session replacement API for /new, /resume, /fork, /clone, and import flows.
764
- const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
765
- const services = await createAgentSessionServices({ cwd });
766
- return {
767
- ...(await createAgentSessionFromServices({
768
- services,
769
- sessionManager,
770
- sessionStartEvent,
771
- })),
772
- services,
773
- diagnostics: services.diagnostics,
774
- };
775
- };
784
+ const allSessions = await SessionManager.listAll();
785
+ ```
776
786
 
777
- const runtime = await createAgentSessionRuntime(createRuntime, {
778
- cwd: process.cwd(),
779
- agentDir: getAgentDir(),
780
- sessionManager: SessionManager.create(process.cwd()),
781
- });
787
+ For active-session replacement, construct `runtime` as shown in [createAgentSessionRuntime() and AgentSessionRuntime](#createagentsessionruntime-and-agentsessionruntime), then use its replacement methods:
782
788
 
789
+ ```typescript
783
790
  // Replace the active session with a fresh one
784
791
  await runtime.newSession();
785
792
 
@@ -800,24 +807,28 @@ const sm = SessionManager.open("/path/to/session.jsonl");
800
807
 
801
808
  // Session listing
802
809
  const currentProjectSessions = await SessionManager.list(process.cwd());
803
- const allSessions = await SessionManager.listAll(process.cwd());
810
+ const allSessions = await SessionManager.listAll();
804
811
 
805
812
  // Tree traversal
806
813
  const entries = sm.getEntries(); // All entries (excludes header)
807
814
  const tree = sm.getTree(); // Full tree structure
808
- const path = sm.getPath(); // Path from root to current leaf
815
+ const path = sm.getBranch(); // Path from root to current leaf
809
816
  const leaf = sm.getLeafEntry(); // Current leaf entry
810
- const entry = sm.getEntry(id); // Get entry by ID
811
- const children = sm.getChildren(id); // Direct children of entry
812
817
 
813
- // Labels
814
- const label = sm.getLabel(id); // Get label for entry
815
- sm.appendLabelChange(id, "checkpoint"); // Set label
818
+ if (leaf) {
819
+ const entryId = leaf.id;
820
+ const entry = sm.getEntry(entryId); // Get entry by ID
821
+ const children = sm.getChildren(entryId); // Direct children of entry
822
+
823
+ // Labels
824
+ const label = sm.getLabel(entryId); // Get label for entry
825
+ sm.appendLabelChange(entryId, "checkpoint"); // Set label
816
826
 
817
- // Branching
818
- sm.branch(entryId); // Move leaf to earlier entry
819
- sm.branchWithSummary(id, "Summary..."); // Branch with context summary
820
- sm.createBranchedSession(leafId); // Extract path to new file
827
+ // Branching
828
+ sm.branch(entryId); // Move leaf to earlier entry
829
+ sm.branchWithSummary(entryId, "Summary..."); // Branch with context summary
830
+ const sessionFile = sm.createBranchedSession(entryId); // Path, or undefined in memory
831
+ }
821
832
  ```
822
833
 
823
834
  > See [examples/sdk/11-sessions.ts](../examples/sdk/11-sessions.ts) and [Session Format](session-format.md)
@@ -828,20 +839,20 @@ sm.createBranchedSession(leafId); // Extract path to new file
828
839
  import { createAgentSession, SettingsManager, SessionManager } from "@astralyn/pi";
829
840
 
830
841
  // Default: loads from files (global + project merged)
831
- const { session } = await createAgentSession({
832
- settingsManager: SettingsManager.create(),
842
+ const { session: defaultSettingsSession } = await createAgentSession({
843
+ settingsManager: SettingsManager.create(process.cwd()),
833
844
  });
834
845
 
835
846
  // With overrides
836
- const settingsManager = SettingsManager.create();
847
+ const settingsManager = SettingsManager.create(process.cwd());
837
848
  settingsManager.applyOverrides({
838
849
  compaction: { enabled: false },
839
850
  retry: { enabled: true, maxRetries: 5 },
840
851
  });
841
- const { session } = await createAgentSession({ settingsManager });
852
+ const { session: customSettingsSession } = await createAgentSession({ settingsManager });
842
853
 
843
854
  // In-memory (no file I/O, for testing)
844
- const { session } = await createAgentSession({
855
+ const { session: inMemorySettingsSession } = await createAgentSession({
845
856
  settingsManager: SettingsManager.inMemory({ compaction: { enabled: false } }),
846
857
  sessionManager: SessionManager.inMemory(),
847
858
  });
@@ -853,12 +864,12 @@ const { session } = await createAgentSession({
853
864
  ```
854
865
 
855
866
  **Static factories:**
856
- - `SettingsManager.create(cwd?, agentDir?)` - Load from files
867
+ - `SettingsManager.create(cwd, agentDir?)` - Load from files
857
868
  - `SettingsManager.inMemory(settings?)` - No file I/O
858
869
 
859
870
  **Project-specific settings:**
860
871
 
861
- Settings load from two locations and merge:
872
+ For a trusted project, settings load from two locations and merge:
862
873
  1. Global: `~/.pi/agent/settings.json`
863
874
  2. Project: `<cwd>/.pi/settings.json`
864
875
 
@@ -883,6 +894,7 @@ import {
883
894
  getAgentDir,
884
895
  } from "@astralyn/pi";
885
896
 
897
+ const cwd = process.cwd();
886
898
  const loader = new DefaultResourceLoader({
887
899
  cwd,
888
900
  agentDir: getAgentDir(),
@@ -922,7 +934,7 @@ interface LoadExtensionsResult {
922
934
  ## Complete Example
923
935
 
924
936
  ```typescript
925
- import { getModel } from "@earendil-works/pi-ai";
937
+ import { getModel } from "@earendil-works/pi-ai/compat";
926
938
  import { Type } from "typebox";
927
939
  import {
928
940
  createAgentSession,
@@ -938,7 +950,7 @@ const modelRuntime = await ModelRuntime.create({
938
950
  modelsPath: "/custom/agent/models.json",
939
951
  });
940
952
  if (process.env.MY_KEY) {
941
- modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY);
953
+ await modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY);
942
954
  }
943
955
 
944
956
  // Inline tool
@@ -997,43 +1009,17 @@ await session.prompt("Get status and list files.");
997
1009
 
998
1010
  ## Run Modes
999
1011
 
1000
- The SDK exports run mode utilities for building custom interfaces on top of `createAgentSession()`:
1012
+ The SDK exports run mode utilities that operate on an `AgentSessionRuntime`. Start with the [session-runtime example](../examples/sdk/13-session-runtime.ts) to create the runtime and rebind session-local work after replacement.
1001
1013
 
1002
1014
  ### InteractiveMode
1003
1015
 
1004
1016
  Full TUI interactive mode with editor, chat history, and all built-in commands:
1005
1017
 
1006
1018
  ```typescript
1007
- import {
1008
- type CreateAgentSessionRuntimeFactory,
1009
- createAgentSessionFromServices,
1010
- createAgentSessionRuntime,
1011
- createAgentSessionServices,
1012
- getAgentDir,
1013
- InteractiveMode,
1014
- SessionManager,
1015
- } from "@astralyn/pi";
1016
-
1017
- const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
1018
- const services = await createAgentSessionServices({ cwd });
1019
- return {
1020
- ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
1021
- services,
1022
- diagnostics: services.diagnostics,
1023
- };
1024
- };
1025
- const runtime = await createAgentSessionRuntime(createRuntime, {
1026
- cwd: process.cwd(),
1027
- agentDir: getAgentDir(),
1028
- sessionManager: SessionManager.create(process.cwd()),
1029
- });
1019
+ import { InteractiveMode } from "@astralyn/pi";
1030
1020
 
1031
1021
  const mode = new InteractiveMode(runtime, {
1032
- migratedProviders: [],
1033
- modelFallbackMessage: undefined,
1034
1022
  initialMessage: "Hello",
1035
- initialImages: [],
1036
- initialMessages: [],
1037
1023
  });
1038
1024
 
1039
1025
  await mode.run();
@@ -1041,34 +1027,12 @@ await mode.run();
1041
1027
 
1042
1028
  ### runPrintMode
1043
1029
 
1044
- Single-shot mode: send prompts, output result, exit:
1030
+ Single-shot mode: send prompts, output the result, dispose the runtime, and return an exit code:
1045
1031
 
1046
1032
  ```typescript
1047
- import {
1048
- type CreateAgentSessionRuntimeFactory,
1049
- createAgentSessionFromServices,
1050
- createAgentSessionRuntime,
1051
- createAgentSessionServices,
1052
- getAgentDir,
1053
- runPrintMode,
1054
- SessionManager,
1055
- } from "@astralyn/pi";
1033
+ import { runPrintMode } from "@astralyn/pi";
1056
1034
 
1057
- const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
1058
- const services = await createAgentSessionServices({ cwd });
1059
- return {
1060
- ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
1061
- services,
1062
- diagnostics: services.diagnostics,
1063
- };
1064
- };
1065
- const runtime = await createAgentSessionRuntime(createRuntime, {
1066
- cwd: process.cwd(),
1067
- agentDir: getAgentDir(),
1068
- sessionManager: SessionManager.create(process.cwd()),
1069
- });
1070
-
1071
- await runPrintMode(runtime, {
1035
+ const exitCode = await runPrintMode(runtime, {
1072
1036
  mode: "text",
1073
1037
  initialMessage: "Hello",
1074
1038
  initialImages: [],
@@ -1078,32 +1042,10 @@ await runPrintMode(runtime, {
1078
1042
 
1079
1043
  ### runRpcMode
1080
1044
 
1081
- JSON-RPC mode for subprocess integration:
1045
+ JSON-RPC mode for subprocess integration. It owns standard input/output and does not return normally:
1082
1046
 
1083
1047
  ```typescript
1084
- import {
1085
- type CreateAgentSessionRuntimeFactory,
1086
- createAgentSessionFromServices,
1087
- createAgentSessionRuntime,
1088
- createAgentSessionServices,
1089
- getAgentDir,
1090
- runRpcMode,
1091
- SessionManager,
1092
- } from "@astralyn/pi";
1093
-
1094
- const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
1095
- const services = await createAgentSessionServices({ cwd });
1096
- return {
1097
- ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
1098
- services,
1099
- diagnostics: services.diagnostics,
1100
- };
1101
- };
1102
- const runtime = await createAgentSessionRuntime(createRuntime, {
1103
- cwd: process.cwd(),
1104
- agentDir: getAgentDir(),
1105
- sessionManager: SessionManager.create(process.cwd()),
1106
- });
1048
+ import { runRpcMode } from "@astralyn/pi";
1107
1049
 
1108
1050
  await runRpcMode(runtime);
1109
1051
  ```
@@ -1133,7 +1075,7 @@ RPC mode is preferred when:
1133
1075
 
1134
1076
  ## Exports
1135
1077
 
1136
- The main entry point exports:
1078
+ Selected SDK exports from the main entry point include:
1137
1079
 
1138
1080
  ```typescript
1139
1081
  // Factory
@@ -1180,7 +1122,6 @@ type ExtensionAPI
1180
1122
  type ToolDefinition
1181
1123
  type Skill
1182
1124
  type PromptTemplate
1183
- type Tool
1184
1125
  ```
1185
1126
 
1186
1127
  For extension types, see [extensions.md](extensions.md) for the full API.
package/docs/security.md CHANGED
@@ -54,6 +54,6 @@ If you bind-mount a host workspace read/write, writes from inside the container
54
54
 
55
55
  ## Reporting Security Issues
56
56
 
57
- For issues that also affect upstream Pi, follow the [upstream security policy](https://github.com/earendil-works/pi/blob/main/SECURITY.md). This personal distribution does not operate a separate security-reporting process.
57
+ For issues that also affect upstream Pi, follow the [upstream security policy](https://github.com/earendil-works/pi/blob/main/SECURITY.md). This distribution does not operate a separate security-reporting process.
58
58
 
59
59
  Expected local-agent behavior, lack of a built-in sandbox, prompt injection from untrusted content, and behavior of user-installed extensions or skills are generally outside the security boundary unless the report demonstrates a real privilege-boundary bypass or shows how pi grants access that the local user did not already have.