@code-yeongyu/senpi 2026.6.10 → 2026.6.12-2

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 (197) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/README.md +18 -18
  3. package/dist/cli/startup-ui.d.ts +10 -0
  4. package/dist/cli/startup-ui.d.ts.map +1 -1
  5. package/dist/cli/startup-ui.js +72 -1
  6. package/dist/cli/startup-ui.js.map +1 -1
  7. package/dist/core/bash-executor.d.ts.map +1 -1
  8. package/dist/core/bash-executor.js +31 -7
  9. package/dist/core/bash-executor.js.map +1 -1
  10. package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts +0 -1
  11. package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/compaction/degradation-monitor.js +0 -1
  13. package/dist/core/extensions/builtin/compaction/degradation-monitor.js.map +1 -1
  14. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  15. package/dist/core/extensions/builtin/compaction/index.js +4 -4
  16. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  17. package/dist/core/extensions/builtin/compaction/policy.d.ts +0 -5
  18. package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
  19. package/dist/core/extensions/builtin/compaction/policy.js +0 -4
  20. package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
  21. package/dist/core/extensions/builtin/compaction/speculative.d.ts +0 -6
  22. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  23. package/dist/core/extensions/builtin/compaction/speculative.js +0 -3
  24. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  25. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts +1 -1
  26. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +10 -2
  28. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  29. package/dist/core/extensions/builtin/permission-system/cli.d.ts +0 -3
  30. package/dist/core/extensions/builtin/permission-system/cli.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/permission-system/cli.js +0 -13
  32. package/dist/core/extensions/builtin/permission-system/cli.js.map +1 -1
  33. package/dist/core/extensions/types.d.ts +1 -0
  34. package/dist/core/extensions/types.d.ts.map +1 -1
  35. package/dist/core/extensions/types.js.map +1 -1
  36. package/dist/core/model-registry.d.ts +0 -3
  37. package/dist/core/model-registry.d.ts.map +1 -1
  38. package/dist/core/model-registry.js +1 -3
  39. package/dist/core/model-registry.js.map +1 -1
  40. package/dist/core/model-resolver.d.ts +1 -0
  41. package/dist/core/model-resolver.d.ts.map +1 -1
  42. package/dist/core/model-resolver.js +20 -5
  43. package/dist/core/model-resolver.js.map +1 -1
  44. package/dist/core/resolve-config-value.d.ts +0 -4
  45. package/dist/core/resolve-config-value.d.ts.map +1 -1
  46. package/dist/core/resolve-config-value.js +0 -15
  47. package/dist/core/resolve-config-value.js.map +1 -1
  48. package/dist/core/settings-manager.d.ts +6 -0
  49. package/dist/core/settings-manager.d.ts.map +1 -1
  50. package/dist/core/settings-manager.js +17 -0
  51. package/dist/core/settings-manager.js.map +1 -1
  52. package/dist/core/tools/edit-diff.d.ts +0 -5
  53. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  54. package/dist/core/tools/edit-diff.js +0 -7
  55. package/dist/core/tools/edit-diff.js.map +1 -1
  56. package/dist/core/tools/index.d.ts +0 -5
  57. package/dist/core/tools/index.d.ts.map +1 -1
  58. package/dist/core/tools/index.js +0 -67
  59. package/dist/core/tools/index.js.map +1 -1
  60. package/dist/core/tools/output-accumulator.d.ts +3 -5
  61. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  62. package/dist/core/tools/output-accumulator.js +38 -34
  63. package/dist/core/tools/output-accumulator.js.map +1 -1
  64. package/dist/core/tools/tail-window.d.ts +15 -0
  65. package/dist/core/tools/tail-window.d.ts.map +1 -0
  66. package/dist/core/tools/tail-window.js +75 -0
  67. package/dist/core/tools/tail-window.js.map +1 -0
  68. package/dist/main.d.ts.map +1 -1
  69. package/dist/main.js +8 -1
  70. package/dist/main.js.map +1 -1
  71. package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  72. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  73. package/dist/modes/interactive/components/first-time-setup.js +101 -0
  74. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  75. package/dist/modes/interactive/components/index.d.ts +1 -0
  76. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  77. package/dist/modes/interactive/components/index.js +1 -0
  78. package/dist/modes/interactive/components/index.js.map +1 -1
  79. package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  80. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  81. package/dist/modes/interactive/components/tool-execution.js +45 -0
  82. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  83. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  84. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  85. package/dist/modes/interactive/interactive-mode.js +12 -5
  86. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  87. package/dist/modes/interactive/theme/theme.d.ts +0 -4
  88. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  89. package/dist/modes/interactive/theme/theme.js +0 -7
  90. package/dist/modes/interactive/theme/theme.js.map +1 -1
  91. package/dist/modes/rpc/rpc-types.d.ts +0 -1
  92. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  93. package/dist/modes/rpc/rpc-types.js.map +1 -1
  94. package/docs/compaction-guide.md +9 -9
  95. package/docs/compaction.md +2 -2
  96. package/docs/containerization.md +22 -22
  97. package/docs/custom-provider.md +13 -13
  98. package/docs/development.md +4 -2
  99. package/docs/extensions.md +18 -19
  100. package/docs/index.md +4 -4
  101. package/docs/json.md +21 -15
  102. package/docs/keybindings.md +6 -3
  103. package/docs/models.md +6 -6
  104. package/docs/packages.md +11 -11
  105. package/docs/prompt-templates.md +2 -2
  106. package/docs/providers.md +9 -9
  107. package/docs/rpc.md +14 -13
  108. package/docs/sdk.md +13 -9
  109. package/docs/security.md +7 -7
  110. package/docs/session-format.md +4 -4
  111. package/docs/sessions.md +14 -14
  112. package/docs/settings.md +13 -11
  113. package/docs/skills.md +8 -8
  114. package/docs/terminal-setup.md +2 -2
  115. package/docs/termux.md +3 -3
  116. package/docs/tui.md +4 -4
  117. package/docs/usage.md +51 -58
  118. package/node_modules/@earendil-works/pi-agent-core/README.md +4 -3
  119. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +0 -2
  120. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  121. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js +0 -4
  122. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  123. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +1 -1
  124. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  125. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  126. package/node_modules/@earendil-works/pi-ai/README.md +2 -4
  127. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts +0 -1
  128. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts.map +1 -1
  129. package/node_modules/@earendil-works/pi-ai/dist/api-registry.js +0 -3
  130. package/node_modules/@earendil-works/pi-ai/dist/api-registry.js.map +1 -1
  131. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  132. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +104 -454
  133. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  134. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +162 -475
  135. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  136. package/node_modules/@earendil-works/pi-ai/dist/models.js +12 -5
  137. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  138. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  139. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +11 -2
  140. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  141. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts +0 -4
  142. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  143. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js +0 -13
  144. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js.map +1 -1
  145. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +0 -6
  146. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  147. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +0 -14
  148. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  149. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts +4 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  151. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +54 -8
  152. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
  153. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +0 -4
  154. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  155. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +0 -6
  156. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  157. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  158. package/node_modules/@earendil-works/pi-tui/README.md +1 -2
  159. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +2 -0
  160. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  161. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +80 -7
  162. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +1 -0
  164. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
  165. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +72 -1
  166. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
  167. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -2
  168. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  169. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -2
  170. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  171. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
  172. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  173. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -7
  174. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  175. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -4
  176. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  177. package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -7
  178. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  179. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  180. package/npm-shrinkwrap.json +12 -12
  181. package/package.json +4 -4
  182. package/dist/core/experimental.d.ts +0 -2
  183. package/dist/core/experimental.d.ts.map +0 -1
  184. package/dist/core/experimental.js +0 -4
  185. package/dist/core/experimental.js.map +0 -1
  186. package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts +0 -11
  187. package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts.map +0 -1
  188. package/dist/core/extensions/builtin/compaction/overflow-detection.js +0 -40
  189. package/dist/core/extensions/builtin/compaction/overflow-detection.js.map +0 -1
  190. package/dist/core/extensions/builtin/system-messages.d.ts +0 -47
  191. package/dist/core/extensions/builtin/system-messages.d.ts.map +0 -1
  192. package/dist/core/extensions/builtin/system-messages.js +0 -117
  193. package/dist/core/extensions/builtin/system-messages.js.map +0 -1
  194. package/dist/core/index.d.ts +0 -13
  195. package/dist/core/index.d.ts.map +0 -1
  196. package/dist/core/index.js +0 -13
  197. package/dist/core/index.js.map +0 -1
@@ -13,7 +13,7 @@ For TypeScript definitions in your project, inspect `node_modules/@code-yeongyu/
13
13
 
14
14
  ## Overview
15
15
 
16
- Pi has two summarization mechanisms:
16
+ Senpi has two summarization mechanisms:
17
17
 
18
18
  | Mechanism | Trigger | Purpose |
19
19
  |-----------|---------|---------|
@@ -76,7 +76,7 @@ What the LLM sees:
76
76
  prompt from cmp messages from firstKeptEntryId
77
77
  ```
78
78
 
79
- On repeated compactions, the summarized span starts at the previous compaction's kept boundary (`firstKeptEntryId`), not at the compaction entry itself, falling back to the entry after the previous compaction if that kept entry cannot be found in the path. This preserves messages that survived the earlier compaction by including them in the next summarization pass as well. Pi also recalculates `tokensBefore` from the rebuilt session context before writing the new `CompactionEntry`, so the token count reflects the actual pre-compaction context being replaced.
79
+ On repeated compactions, the summarized span starts at the previous compaction's kept boundary (`firstKeptEntryId`), not at the compaction entry itself, falling back to the entry after the previous compaction if that kept entry cannot be found in the path. This preserves messages that survived the earlier compaction by including them in the next summarization pass as well. Senpi also recalculates `tokensBefore` from the rebuilt session context before writing the new `CompactionEntry`, so the token count reflects the actual pre-compaction context being replaced.
80
80
 
81
81
  ### Split Turns
82
82
 
@@ -3,18 +3,18 @@
3
3
  Pi runs with all permissions by default, but in some cases, you will want to have more control over what directories Pi can write to and which accesses it has.
4
4
 
5
5
  There are two general options. You can either
6
- 1. run the whole `pi` process inside an isolated environment, or
7
- 2. run `pi` on the host and route tool execution into an isolated environment.
6
+ 1. run the whole `senpi` process inside an isolated environment, or
7
+ 2. run `senpi` on the host and route tool execution into an isolated environment.
8
8
 
9
9
  ## Choose a pattern
10
10
 
11
11
  | Pattern | What is isolated | Best for | Notes |
12
12
  | --- | --- | --- | --- |
13
- | OpenShell | Whole `pi` process in a policy-controlled sandbox | Local or remote managed sandbox | Requires an OpenShell gateway |
13
+ | OpenShell | Whole `senpi` process in a policy-controlled sandbox | Local or remote managed sandbox | Requires an OpenShell gateway |
14
14
  | Gondolin extension | Built-in tools and `!` commands | Local micro-VM isolation while keeping auth on host | See [`examples/extensions/gondolin/`](../examples/extensions/gondolin/). |
15
- | Plain Docker | Whole `pi` process in a local container | Simple local isolation | Provider API keys enter the container. |
15
+ | Plain Docker | Whole `senpi` process in a local container | Simple local isolation | Provider API keys enter the container. |
16
16
 
17
- Extensions run wherever the `pi` process runs. If you run host `pi` with a tool-routing extension, other custom extension tools still run on the host unless they also delegate their operations.
17
+ Extensions run wherever the `senpi` process runs. If you run host `senpi` with a tool-routing extension, other custom extension tools still run on the host unless they also delegate their operations.
18
18
 
19
19
  ## OpenShell
20
20
 
@@ -29,21 +29,21 @@ openshell gateway add <gateway-url> --name <name>
29
29
  openshell gateway select <name>
30
30
  ```
31
31
 
32
- Launch `pi` inside an OpenShell sandbox:
32
+ Launch `senpi` inside an OpenShell sandbox:
33
33
 
34
34
  ```bash
35
- openshell sandbox create --name pi-sandbox --from pi -- pi
35
+ openshell sandbox create --name senpi-sandbox --from senpi -- senpi
36
36
  ```
37
37
 
38
- In this pattern, the whole `pi` process runs inside the sandbox.
38
+ In this pattern, the whole `senpi` process runs inside the sandbox.
39
39
  Built-in tools, `!` commands, and extension tools execute inside the OpenShell boundary.
40
40
 
41
41
  If the gateway is remote, project files are not bind-mounted from the host, meaning writes in the sandbox are not reflected on your machine.
42
42
  Clone the repository inside the sandbox or use OpenShell file transfer commands:
43
43
 
44
44
  ```bash
45
- openshell sandbox upload pi-sandbox ./repo /workspace
46
- openshell sandbox download pi-sandbox /workspace/repo ./repo-out
45
+ openshell sandbox upload senpi-sandbox ./repo /workspace
46
+ openshell sandbox download senpi-sandbox /workspace/repo ./repo-out
47
47
  ```
48
48
 
49
49
  OpenShell providers can keep raw model API keys outside the sandbox.
@@ -53,13 +53,13 @@ Configure Pi to use the corresponding OpenAI-compatible or Anthropic-compatible
53
53
  ## Gondolin
54
54
 
55
55
  [Gondolin](https://github.com/earendil-works/gondolin) is a local Linux micro-VM.
56
- Use the [example extension](../examples/extensions/gondolin) when you want `pi` on the host but all built-in tools routed into the VM.
56
+ Use the [example extension](../examples/extensions/gondolin) when you want `senpi` on the host but all built-in tools routed into the VM.
57
57
 
58
58
  Setup:
59
59
 
60
60
  ```bash
61
- cp -R packages/coding-agent/examples/extensions/gondolin ~/.pi/agent/extensions/gondolin
62
- cd ~/.pi/agent/extensions/gondolin
61
+ cp -R packages/coding-agent/examples/extensions/gondolin ~/.senpi/agent/extensions/gondolin
62
+ cd ~/.senpi/agent/extensions/gondolin
63
63
  npm install --ignore-scripts
64
64
  ```
65
65
 
@@ -67,7 +67,7 @@ Run from the project you want mounted:
67
67
 
68
68
  ```bash
69
69
  cd /path/to/project
70
- pi -e ~/.pi/agent/extensions/gondolin
70
+ senpi -e ~/.senpi/agent/extensions/gondolin
71
71
  ```
72
72
 
73
73
  The extension mounts the host cwd at `/workspace` in the VM and overrides `read`, `write`, `edit`, `bash`, `grep`, `find`, and `ls`.
@@ -78,9 +78,9 @@ Requirements: Node.js >= 23.6.0 for `@earendil-works/gondolin`, plus QEMU (requi
78
78
 
79
79
  ## Plain Docker
80
80
 
81
- Run the whole `pi` process in Docker when you want the simplest local container boundary.
81
+ Run the whole `senpi` process in Docker when you want the simplest local container boundary.
82
82
 
83
- `Dockerfile.pi`:
83
+ `Dockerfile.senpi`:
84
84
 
85
85
  ```dockerfile
86
86
  FROM node:24-bookworm-slim
@@ -88,24 +88,24 @@ FROM node:24-bookworm-slim
88
88
  RUN apt-get update \
89
89
  && apt-get install -y --no-install-recommends bash ca-certificates git ripgrep \
90
90
  && rm -rf /var/lib/apt/lists/*
91
- RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent
91
+ RUN npm install -g --ignore-scripts @code-yeongyu/senpi
92
92
 
93
93
  WORKDIR /workspace
94
- ENTRYPOINT ["pi"]
94
+ ENTRYPOINT ["senpi"]
95
95
  ```
96
96
 
97
97
  Build and run:
98
98
 
99
99
  ```bash
100
- docker build -t pi-sandbox -f Dockerfile.pi .
100
+ docker build -t senpi-sandbox -f Dockerfile.senpi .
101
101
 
102
102
  docker run --rm -it \
103
103
  -e ANTHROPIC_API_KEY \
104
104
  -v "$PWD:/workspace" \
105
- -v pi-agent-home:/root/.pi/agent \
106
- pi-sandbox
105
+ -v senpi-agent-home:/root/.senpi/agent \
106
+ senpi-sandbox
107
107
  ```
108
108
 
109
109
  The `-v "$PWD:/workspace"` mounts your current directory into the container at /workspace such that reads and writes in `/workspace` inside Docker directly affect your host files, like in the Gondolin example.
110
110
 
111
- Use a named volume for `/root/.pi/agent` if you want container-local settings and sessions. Mounting your host `~/.pi/agent` exposes host auth and session files to the container.
111
+ Use a named volume for `/root/.senpi/agent` if you want container-local settings and sessions. Mounting your host `~/.senpi/agent` exposes host auth and session files to the container.
@@ -372,12 +372,12 @@ interface OAuthCredentials {
372
372
  For providers with non-standard APIs, implement `streamSimple`. Study the existing provider implementations before writing your own:
373
373
 
374
374
  **Reference implementations:**
375
- - [anthropic.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
376
- - [mistral.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
377
- - [openai-completions.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
378
- - [openai-responses.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
379
- - [google.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
380
- - [amazon-bedrock.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
375
+ - [anthropic.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
376
+ - [mistral.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
377
+ - [openai-completions.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
378
+ - [openai-responses.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
379
+ - [google.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
380
+ - [amazon-bedrock.ts](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
381
381
 
382
382
  ### Stream Pattern
383
383
 
@@ -535,14 +535,14 @@ calculateCost(model, output.usage);
535
535
 
536
536
  ### Context Overflow Errors
537
537
 
538
- When a request exceeds the model's context window, pi can recover automatically by compacting the conversation and retrying. This recovery only kicks in if pi recognizes the failure as an overflow.
538
+ When a request exceeds the model's context window, senpi can recover automatically by compacting the conversation and retrying. This recovery only kicks in if senpi recognizes the failure as an overflow.
539
539
 
540
540
  Detection runs on the finalized assistant message:
541
541
 
542
542
  - `stopReason === "error"`
543
- - `errorMessage` matches one of pi's known overflow patterns (see [`packages/ai/src/utils/overflow.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/utils/overflow.ts))
543
+ - `errorMessage` matches one of senpi's known overflow patterns (see [`packages/ai/src/utils/overflow.ts`](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/utils/overflow.ts))
544
544
 
545
- If your provider returns overflow errors with a message pi does not recognize, normalize the error from the same extension that registers the provider. Use a `message_end` handler to rewrite the assistant message so its `errorMessage` starts with a phrase pi recognizes. The generic fallback `context_length_exceeded` is the safest choice.
545
+ If your provider returns overflow errors with a message senpi does not recognize, normalize the error from the same extension that registers the provider. Use a `message_end` handler to rewrite the assistant message so its `errorMessage` starts with a phrase senpi recognizes. The generic fallback `context_length_exceeded` is the safest choice.
546
546
 
547
547
  ```typescript
548
548
  const MY_PROVIDER_OVERFLOW_PATTERN = /your provider's overflow phrase/i;
@@ -574,7 +574,7 @@ export default function (pi: ExtensionAPI) {
574
574
  }
575
575
  ```
576
576
 
577
- `message_end` runs before pi tracks the assistant message for auto-compaction, so the rewritten `errorMessage` is what pi checks. With this in place, pi will:
577
+ `message_end` runs before senpi tracks the assistant message for auto-compaction, so the rewritten `errorMessage` is what senpi checks. With this in place, senpi will:
578
578
 
579
579
  1. Detect the overflow from `errorMessage`.
580
580
  2. Drop the failed assistant message from live context.
@@ -584,7 +584,7 @@ export default function (pi: ExtensionAPI) {
584
584
  Guard the rewrite carefully:
585
585
 
586
586
  - Scope it to your provider (`message.provider` and `ctx.model?.provider`) so unrelated errors from other providers are untouched.
587
- - Match a provider-specific pattern, not pi's generic overflow patterns. Rewriting rate-limit or throttling errors (`rate limit`, `too many requests`) would falsely trigger compaction instead of pi's normal retry-with-backoff path.
587
+ - Match a provider-specific pattern, not senpi's generic overflow patterns. Rewriting rate-limit or throttling errors (`rate limit`, `too many requests`) would falsely trigger compaction instead of senpi's normal retry-with-backoff path.
588
588
  - Skip when `errorMessage` already includes `context_length_exceeded` so the handler is idempotent.
589
589
 
590
590
  ### Registration
@@ -603,7 +603,7 @@ pi.registerProvider("my-provider", {
603
603
 
604
604
  ## Testing Your Implementation
605
605
 
606
- Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/earendil-works/pi-mono/tree/main/packages/ai/test):
606
+ Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/code-yeongyu/senpi/tree/main/packages/ai/test):
607
607
 
608
608
  | Test | Purpose |
609
609
  |------|---------|
@@ -612,7 +612,7 @@ Test your provider against the same test suites used by built-in providers. Copy
612
612
  | `abort.test.ts` | AbortSignal handling |
613
613
  | `empty.test.ts` | Empty/minimal responses |
614
614
  | `context-overflow.test.ts` | Context window limits |
615
- | `image-limits.test.ts` | Image input handling |
615
+ | `images.test.ts` | Image input handling |
616
616
  | `unicode-surrogate.test.ts` | Unicode edge cases |
617
617
  | `tool-call-without-result.test.ts` | Tool call edge cases |
618
618
  | `image-tool-result.test.ts` | Images in tool results |
@@ -41,7 +41,7 @@ Three execution modes: npm install, standalone binary (`bun build --compile`), t
41
41
  **Always use `src/config.ts`** for package assets:
42
42
 
43
43
  ```typescript
44
- import { getPackageDir, getThemeDir } from "./config.js";
44
+ import { getPackageDir, getThemesDir } from "./config.js";
45
45
  ```
46
46
 
47
47
  Never use `__dirname` directly for package assets.
@@ -56,10 +56,12 @@ Never use `__dirname` directly for package assets.
56
56
 
57
57
  ```bash
58
58
  npm test # Vitest across workspaces (skips live-API; default test runner)
59
- ./pi-test.sh # Live-API integration suite (env-gated; requires API keys)
59
+ ./pi-test.sh # Launch the CLI from source via tsx for manual testing (--no-env unsets API keys)
60
60
  npm run check # Biome + tsgo + browser-smoke + web-ui check (pre-commit equivalent)
61
61
  ```
62
62
 
63
+ Live-API tests are env-gated vitest tests. Set `PI_ENABLE_LIVE_API_TESTS=1` (or a per-provider flag from `packages/ai/test/live-api-gates.ts`) plus the provider API keys, then run `npm test`.
64
+
63
65
  Run a specific test:
64
66
 
65
67
  ```bash
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Extensions
4
4
 
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.
5
+ Extensions are TypeScript modules that extend senpi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more.
6
6
 
7
7
  > **Placement for /reload:** Put extensions in `~/.senpi/agent/extensions/` (global) or `.senpi/extensions/` (project-local) for auto-discovery. Use `senpi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
8
8
 
@@ -102,14 +102,14 @@ export default function (pi: ExtensionAPI) {
102
102
  Test with `--extension` (or `-e`) flag:
103
103
 
104
104
  ```bash
105
- pi -e ./my-extension.ts
105
+ senpi -e ./my-extension.ts
106
106
  ```
107
107
 
108
108
  ## Extension Locations
109
109
 
110
110
  > **Security:** Extensions run with your full system permissions and can execute arbitrary code. Only install from sources you trust.
111
111
 
112
- Extensions are auto-discovered from trusted locations. Project-local `.pi/extensions` entries load only after the project is trusted.
112
+ Extensions are auto-discovered from trusted locations. Project-local `.senpi/extensions` entries load only after the project is trusted.
113
113
 
114
114
  | Location | Scope |
115
115
  |----------|-------|
@@ -268,7 +268,7 @@ Run `npm install` in the extension directory, then imports from `node_modules/`
268
268
  ### Lifecycle Overview
269
269
 
270
270
  ```
271
- pi starts
271
+ senpi starts
272
272
 
273
273
  ├─► project_trust (user/global and CLI extensions only, before project resources load)
274
274
  ├─► session_start { reason: "startup" }
@@ -339,7 +339,7 @@ exit (Ctrl+C, Ctrl+D, SIGHUP, SIGTERM)
339
339
 
340
340
  #### project_trust
341
341
 
342
- Fired before pi decides whether to trust a project with dynamic configs (`.pi` or `.agents/skills`). It runs during startup and when session replacement (for example `/resume`) enters a cwd whose trust has not been resolved in the current process. Only user/global extensions and CLI `-e` extensions participate; project-local extensions are not loaded until after trust is resolved.
342
+ Fired before senpi decides whether to trust a project with dynamic configs (`.senpi` or `.agents/skills`). It runs during startup and when session replacement (for example `/resume`) enters a cwd whose trust has not been resolved in the current process. Only user/global extensions and CLI `-e` extensions participate; project-local extensions are not loaded until after trust is resolved.
343
343
 
344
344
  ```typescript
345
345
  pi.on("project_trust", async (event, ctx) => {
@@ -352,7 +352,7 @@ pi.on("project_trust", async (event, ctx) => {
352
352
  });
353
353
  ```
354
354
 
355
- A `project_trust` handler must return `{ trusted: "yes" | "no" | "undecided" }`. A user/global or CLI extension that returns `"yes"` or `"no"` owns the decision; the first yes/no decision wins and suppresses the built-in trust prompt. Use `remember: true` to persist a yes/no decision; otherwise it applies only to the current process. Return `"undecided"` to let later handlers or the built-in trust flow decide. Check `ctx.hasUI` before prompting. If no handler returns yes/no, normal trust resolution continues: saved `trust.json` decisions apply first, then `defaultProjectTrust` controls whether pi asks, trusts, or declines by default.
355
+ A `project_trust` handler must return `{ trusted: "yes" | "no" | "undecided" }`. A user/global or CLI extension that returns `"yes"` or `"no"` owns the decision; the first yes/no decision wins and suppresses the built-in trust prompt. Use `remember: true` to persist a yes/no decision; otherwise it applies only to the current process. Return `"undecided"` to let later handlers or the built-in trust flow decide. Check `ctx.hasUI` before prompting. If no handler returns yes/no, normal trust resolution continues: saved `trust.json` decisions apply first, then `defaultProjectTrust` controls whether senpi asks, trusts, or declines by default.
356
356
 
357
357
  ### Resource Events
358
358
 
@@ -494,7 +494,7 @@ pi.on("before_agent_start", async (event, ctx) => {
494
494
  // event.systemPrompt - current chained system prompt for this handler
495
495
  // (includes changes from earlier before_agent_start handlers)
496
496
  // event.systemPromptOptions - structured options used to build the system prompt
497
- // .customPrompt - any custom system prompt (from --system-prompt, SYSTEM.md, or custom templates)
497
+ // .customPrompt - any custom system prompt (from --system-prompt or custom templates)
498
498
  // .selectedTools - tools currently active in the prompt
499
499
  // .toolSnippets - one-line descriptions for each tool
500
500
  // .promptGuidelines - custom guideline bullets
@@ -516,7 +516,7 @@ pi.on("before_agent_start", async (event, ctx) => {
516
516
  });
517
517
  ```
518
518
 
519
- The `systemPromptOptions` field gives extensions access to the same structured data Pi uses to build the system prompt. This lets you inspect what Pi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
519
+ The `systemPromptOptions` field gives extensions access to the same structured data senpi uses to build the system prompt. This lets you inspect what senpi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
520
520
 
521
521
  Inside `before_agent_start`, `event.systemPrompt` and `ctx.getSystemPrompt()` both reflect the chained system prompt as of the current handler. Later `before_agent_start` handlers can still modify it again.
522
522
 
@@ -622,7 +622,7 @@ pi.on("context", async (event, ctx) => {
622
622
 
623
623
  Fired after the provider-specific payload is built, right before the request is sent. Handlers run in extension load order. Returning `undefined` keeps the payload unchanged. Returning any other value replaces the payload for later handlers and for the actual request.
624
624
 
625
- This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports Pi's system prompt string rather than the final serialized provider payload.
625
+ This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports senpi's system prompt string rather than the final serialized provider payload.
626
626
 
627
627
  ```typescript
628
628
  pi.on("before_provider_request", (event, ctx) => {
@@ -806,7 +806,7 @@ pi.on("user_bash", (event, ctx) => {
806
806
  // Option 1: Provide custom operations (e.g., SSH)
807
807
  return { operations: remoteBashOps };
808
808
 
809
- // Option 2: Wrap pi's built-in local bash backend
809
+ // Option 2: Wrap senpi's built-in local bash backend
810
810
  const local = createLocalBashOperations();
811
811
  return {
812
812
  operations: {
@@ -945,7 +945,7 @@ Control flow helpers.
945
945
 
946
946
  ### ctx.shutdown()
947
947
 
948
- Request a graceful shutdown of pi.
948
+ Request a graceful shutdown of senpi.
949
949
 
950
950
  - **Interactive mode:** Deferred until the agent becomes idle (after processing all queued steering and follow-up messages).
951
951
  - **RPC mode:** Deferred until the next idle state (after completing the current command response, when waiting for the next command).
@@ -990,7 +990,7 @@ ctx.compact({
990
990
 
991
991
  ### ctx.getSystemPrompt()
992
992
 
993
- Returns Pi's current system prompt string.
993
+ Returns senpi's current system prompt string.
994
994
 
995
995
  - During `before_agent_start`, this reflects chained system-prompt changes made so far for the current turn.
996
996
  - It does not include later `context` message mutations.
@@ -1010,7 +1010,7 @@ Command handlers receive `ExtensionCommandContext`, which extends `ExtensionCont
1010
1010
 
1011
1011
  ### ctx.getSystemPromptOptions()
1012
1012
 
1013
- Returns the base inputs Pi currently uses to build the system prompt.
1013
+ Returns the base inputs senpi currently uses to build the system prompt.
1014
1014
 
1015
1015
  ```typescript
1016
1016
  const options = ctx.getSystemPromptOptions();
@@ -1345,7 +1345,7 @@ pi.sendUserMessage("What is 2+2?");
1345
1345
  // With content array (text + images)
1346
1346
  pi.sendUserMessage([
1347
1347
  { type: "text", text: "Describe this image:" },
1348
- { type: "image", source: { type: "base64", mediaType: "image/png", data: "..." } },
1348
+ { type: "image", data: "base64-encoded-data", mimeType: "image/png" },
1349
1349
  ]);
1350
1350
 
1351
1351
  // During streaming - must specify delivery mode
@@ -1874,13 +1874,13 @@ Extensions can override built-in tools (`read`, `bash`, `edit`, `write`, `grep`,
1874
1874
 
1875
1875
  ```bash
1876
1876
  # Extension's read tool replaces built-in read
1877
- pi -e ./tool-override.ts
1877
+ senpi -e ./tool-override.ts
1878
1878
  ```
1879
1879
 
1880
1880
  Alternatively, use `--no-builtin-tools` to start without any built-in tools while keeping extension tools enabled:
1881
1881
  ```bash
1882
1882
  # No built-in tools, only extension tools
1883
- pi --no-builtin-tools -e ./my-extension.ts
1883
+ senpi --no-builtin-tools -e ./my-extension.ts
1884
1884
  ```
1885
1885
 
1886
1886
  See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.ts) for a complete example that overrides `read` with logging and access control.
@@ -1931,7 +1931,7 @@ pi.registerTool({
1931
1931
 
1932
1932
  **Operations interfaces:** `ReadOperations`, `WriteOperations`, `EditOperations`, `BashOperations`, `LsOperations`, `GrepOperations`, `FindOperations`
1933
1933
 
1934
- For `user_bash`, extensions can reuse pi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
1934
+ For `user_bash`, extensions can reuse senpi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
1935
1935
 
1936
1936
  The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
1937
1937
 
@@ -2270,7 +2270,7 @@ ctx.ui.setFooter((tui, theme) => ({
2270
2270
  ctx.ui.setFooter(undefined); // Restore built-in footer
2271
2271
 
2272
2272
  // Terminal title
2273
- ctx.ui.setTitle("pi - my-project");
2273
+ ctx.ui.setTitle("senpi - my-project");
2274
2274
 
2275
2275
  // Editor text
2276
2276
  ctx.ui.setEditorText("Prefill text");
@@ -2636,7 +2636,6 @@ All examples in [examples/extensions/](../examples/extensions/).
2636
2636
  | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
2637
2637
  | `sandbox/` | Sandboxed tool execution | Tool operations |
2638
2638
  | `gondolin/` | Route built-in tools and `!` commands into a Gondolin micro-VM | Tool operations, built-in tool overrides, `on("user_bash")` |
2639
- | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
2640
2639
  | **Games** |||
2641
2640
  | `snake.ts` | Snake game | `registerCommand`, `ui.custom`, keyboard handling |
2642
2641
  | `space-invaders.ts` | Space Invaders game | `registerCommand`, `ui.custom` |
package/docs/index.md CHANGED
@@ -10,13 +10,13 @@ Install with npm:
10
10
  npm install -g @code-yeongyu/senpi
11
11
  ```
12
12
 
13
- To uninstall pi itself, use npm for curl and npm installs:
13
+ To uninstall senpi itself, use the package manager that installed it:
14
14
 
15
15
  ```bash
16
- npm uninstall -g @earendil-works/pi-coding-agent
16
+ npm uninstall -g @code-yeongyu/senpi
17
17
  ```
18
18
 
19
- For pnpm, Yarn, or Bun installs, use the matching global remove command: `pnpm remove -g @earendil-works/pi-coding-agent`, `yarn global remove @earendil-works/pi-coding-agent`, or `bun uninstall -g @earendil-works/pi-coding-agent`.
19
+ For pnpm, Yarn, or Bun installs, use the matching global remove command: `pnpm remove -g @code-yeongyu/senpi`, `yarn global remove @code-yeongyu/senpi`, or `bun uninstall -g @code-yeongyu/senpi`.
20
20
 
21
21
  Then run it in a project directory:
22
22
 
@@ -34,7 +34,7 @@ For the full first-run flow, see [Quickstart](quickstart.md).
34
34
  - [Using Senpi](usage.md) - interactive mode, slash commands, context files, and CLI reference.
35
35
  - [Providers](providers.md) - subscription and API-key setup for built-in providers.
36
36
  - [Security](security.md) - project trust, sandbox boundaries, and vulnerability reporting.
37
- - [Containerization](containerization.md) - sandbox pi with OpenShell, Gondolin, or Docker.
37
+ - [Containerization](containerization.md) - sandbox senpi with OpenShell, Gondolin, or Docker.
38
38
  - [Settings](settings.md) - global and project settings.
39
39
  - [Keybindings](keybindings.md) - default shortcuts and custom keybindings.
40
40
  - [Sessions](sessions.md) - session management, branching, and tree navigation.
package/docs/json.md CHANGED
@@ -4,31 +4,37 @@
4
4
  senpi --mode json "Your prompt"
5
5
  ```
6
6
 
7
- Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.
7
+ Outputs all session events as JSON lines to stdout. Useful for integrating senpi into other tools or custom UIs.
8
8
 
9
9
  ## Event Types
10
10
 
11
- Events are defined in [`AgentSessionEvent`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
11
+ Events are defined in [`AgentSessionEvent`](../src/core/agent-session.ts):
12
12
 
13
13
  ```typescript
14
14
  type AgentSessionEvent =
15
+ // All AgentEvent variants; agent_end additionally carries willRetry: boolean
15
16
  | AgentEvent
16
17
  | { type: "queue_update"; steering: readonly string[]; followUp: readonly string[] }
17
18
  | { type: "compaction_start"; reason: "manual" | "threshold" | "overflow" }
18
- | { type: "compaction_end"; reason: "manual" | "threshold" | "overflow"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string }
19
+ | { type: "compaction_progress"; reason: "manual" | "threshold" | "overflow"; delta?: string; text?: string }
20
+ | { type: "compaction_end"; reason: "manual" | "threshold" | "overflow"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; requestId?: string; accepted?: boolean; rejectionCause?: "cancelled-by-extension" | "would-overflow" | "circuit-breaker" | "per-turn-cap"; errorMessage?: string }
21
+ | { type: "session_info_changed"; name: string | undefined }
22
+ | { type: "thinking_level_changed"; level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" }
23
+ | SystemPromptChangeEvent // type: "system_prompt_change"
24
+ | ExtensionToolHookLifecycleEvent // type: "tool_hook_status"
19
25
  | { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }
20
26
  | { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string };
21
27
  ```
22
28
 
23
- `queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
29
+ `queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start`, `compaction_progress`, and `compaction_end` cover both manual and automatic compaction. `session_info_changed` fires when the session display name changes, `thinking_level_changed` when the thinking level changes, `system_prompt_change` (see `SystemPromptChangeEvent` in [`extensions/types.ts`](../src/core/extensions/types.ts)) when a model switch changes the active system prompt, and `tool_hook_status` (see `ExtensionToolHookLifecycleEvent` in [`extensions/runner.ts`](../src/core/extensions/runner.ts)) for extension tool hook start/end phases.
24
30
 
25
- Base events from [`AgentEvent`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts#L179):
31
+ Base events from [`AgentEvent`](../../agent/src/types.ts):
26
32
 
27
33
  ```typescript
28
34
  type AgentEvent =
29
35
  // Agent lifecycle
30
36
  | { type: "agent_start" }
31
- | { type: "agent_end"; messages: AgentMessage[] }
37
+ | { type: "agent_end"; messages: AgentMessage[] } // in JSON mode also: willRetry: boolean
32
38
  // Turn lifecycle
33
39
  | { type: "turn_start" }
34
40
  | { type: "turn_end"; message: AgentMessage; toolResults: ToolResultMessage[] }
@@ -44,16 +50,16 @@ type AgentEvent =
44
50
 
45
51
  ## Message Types
46
52
 
47
- Base messages from [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts#L134):
48
- - `UserMessage` (line 134)
49
- - `AssistantMessage` (line 140)
50
- - `ToolResultMessage` (line 152)
53
+ Base messages from [`packages/ai/src/types.ts`](../../ai/src/types.ts):
54
+ - `UserMessage`
55
+ - `AssistantMessage`
56
+ - `ToolResultMessage`
51
57
 
52
- Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
53
- - `BashExecutionMessage` (line 29)
54
- - `CustomMessage` (line 46)
55
- - `BranchSummaryMessage` (line 55)
56
- - `CompactionSummaryMessage` (line 62)
58
+ Extended messages from [`packages/coding-agent/src/core/messages.ts`](../src/core/messages.ts):
59
+ - `BashExecutionMessage`
60
+ - `CustomMessage`
61
+ - `BranchSummaryMessage`
62
+ - `CompactionSummaryMessage`
57
63
 
58
64
  ## Output Format
59
65
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  All keyboard shortcuts can be customized via `~/.senpi/agent/keybindings.json`. Each action can be bound to one or more keys.
4
4
 
5
- The config file uses the same namespaced keybinding ids that pi uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
5
+ The config file uses the same namespaced keybinding ids that senpi uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
6
6
 
7
7
  Older configs using pre-namespaced ids such as `cursorUp` or `expandTools` are migrated automatically to the namespaced ids on startup.
8
8
 
9
- After editing `keybindings.json`, run `/reload` in pi to apply the changes without restarting the session.
9
+ After editing `keybindings.json`, run `/reload` in senpi to apply the changes without restarting the session.
10
10
 
11
11
  ## Key Format
12
12
 
@@ -88,6 +88,8 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
88
88
  | `app.suspend` | `ctrl+z` (none on Windows) | Suspend to background |
89
89
  | `app.editor.external` | `ctrl+g` | Open in external editor (`$VISUAL` or `$EDITOR`) |
90
90
  | `app.clipboard.pasteImage` | `ctrl+v` (`alt+v` on Windows) | Paste image from clipboard |
91
+ | `app.history.search` | `ctrl+r` | Search prompt history across sessions |
92
+ | `app.sessions.observe` | `ctrl+s` | Observe session transcripts |
91
93
 
92
94
  ### Sessions
93
95
 
@@ -145,6 +147,7 @@ Used inside the favorite models selector (opened via `/favorite-models`).
145
147
  | Keybinding id | Default | Description |
146
148
  |--------|---------|-------------|
147
149
  | `app.models.save` | `ctrl+s` | Save current favorite model selection to settings |
150
+ | `app.models.toggleFavorite` | `ctrl+f` | Toggle favorite status of the selected model |
148
151
  | `app.models.enableAll` | `ctrl+a` | Favorite all models (or all matching the current search) |
149
152
  | `app.models.clearAll` | `ctrl+x` | Clear all models (or all matching the current search) |
150
153
  | `app.models.toggleProvider` | `ctrl+p` | Toggle favorite models for the current provider |
@@ -165,7 +168,7 @@ Create `~/.senpi/agent/keybindings.json`:
165
168
 
166
169
  Each action can have a single key or an array of keys. User config overrides defaults.
167
170
 
168
- On native Windows, `app.suspend` has no default binding because Windows terminals do not support Unix job control. If you bind it manually, pi shows a status message instead of suspending. In WSL, the normal Linux `ctrl+z`/`fg` behavior still applies.
171
+ On native Windows, `app.suspend` has no default binding because Windows terminals do not support Unix job control. If you bind it manually, senpi shows a status message instead of suspending. In WSL, the normal Linux `ctrl+z`/`fg` behavior still applies.
169
172
 
170
173
  ### Emacs Example
171
174
 
package/docs/models.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Custom Models
2
2
 
3
- Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.pi/agent/models.json`.
3
+ Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.senpi/agent/models.json`.
4
4
 
5
5
  ## Table of Contents
6
6
 
@@ -36,7 +36,7 @@ For local models (Ollama, LM Studio, vLLM), only `id` is required per model:
36
36
 
37
37
  The `apiKey` is required but Ollama ignores it, so any value works.
38
38
 
39
- Some OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so pi sends the system prompt as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too.
39
+ Some OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so senpi sends the system prompt as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too.
40
40
 
41
41
  You can set `compat` at the provider level to apply to all models, or at the model level to override a specific model. This commonly applies to Ollama, vLLM, SGLang, and similar OpenAI-compatible servers.
42
42
 
@@ -168,7 +168,7 @@ The `apiKey` and `headers` fields support command execution, environment interpo
168
168
 
169
169
  Legacy uppercase env-var-like values such as `MY_API_KEY` are migrated to `$MY_API_KEY` on startup.
170
170
 
171
- For `models.json`, shell commands are resolved at request time. pi intentionally does not apply built-in TTL, stale reuse, or recovery logic for arbitrary commands. Different commands need different caching and failure strategies, and pi cannot infer the right one.
171
+ For `models.json`, shell commands are resolved at request time. senpi intentionally does not apply built-in TTL, stale reuse, or recovery logic for arbitrary commands. Different commands need different caching and failure strategies, and senpi cannot infer the right one.
172
172
 
173
173
  If your command is slow, expensive, rate-limited, or should keep using a previous value on transient failures, wrap it in your own script or command that implements the caching or TTL behavior you want.
174
174
 
@@ -201,7 +201,7 @@ If your command is slow, expensive, rate-limited, or should keep using a previou
201
201
  | `name` | No | `id` | Human-readable model label. Used for matching (`--model` patterns) and shown as secondary model detail text. |
202
202
  | `api` | No | provider's `api` | Override provider's API for this model |
203
203
  | `reasoning` | No | `false` | Supports extended thinking |
204
- | `thinkingLevelMap` | No | omitted | Maps pi thinking levels to provider values and marks unsupported levels (see below) |
204
+ | `thinkingLevelMap` | No | omitted | Maps senpi thinking levels to provider values and marks unsupported levels (see below) |
205
205
  | `input` | No | `["text"]` | Input types: `["text"]` or `["text", "image"]` |
206
206
  | `contextWindow` | No | `128000` | Context window size in tokens |
207
207
  | `maxTokens` | No | `16384` | Maximum output tokens |
@@ -214,7 +214,7 @@ Current behavior:
214
214
 
215
215
  ### Thinking Level Map
216
216
 
217
- Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
217
+ Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are senpi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
218
218
 
219
219
  Values are tristate:
220
220
 
@@ -327,7 +327,7 @@ Behavior notes:
327
327
 
328
328
  For providers or proxies using `api: "anthropic-messages"`, use `compat` to control Anthropic-specific request compatibility.
329
329
 
330
- By default pi sends per-tool `eager_input_streaming: true`. If a proxy or Anthropic-compatible backend rejects that field, set `supportsEagerToolInputStreaming` to `false`. Pi will omit `tools[].eager_input_streaming` and send the legacy `fine-grained-tool-streaming-2025-05-14` beta header for tool-enabled requests instead.
330
+ By default senpi sends per-tool `eager_input_streaming: true`. If a proxy or Anthropic-compatible backend rejects that field, set `supportsEagerToolInputStreaming` to `false`. Senpi will omit `tools[].eager_input_streaming` and send the legacy `fine-grained-tool-streaming-2025-05-14` beta header for tool-enabled requests instead.
331
331
 
332
332
  Some Anthropic models require adaptive thinking (`thinking.type: "adaptive"` plus `output_config.effort`) instead of the legacy budget-based thinking payload. Built-in models set this automatically. For custom providers or aliases that route to those models, set `forceAdaptiveThinking` to `true`.
333
333