@code-yeongyu/senpi 2026.6.10 → 2026.6.13
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.
- package/CHANGELOG.md +68 -1
- package/README.md +21 -21
- package/dist/cli/startup-ui.d.ts +10 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +72 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +31 -7
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts +0 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.js +0 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +4 -4
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.d.ts +0 -5
- package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.js +0 -4
- package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +0 -6
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +0 -3
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +10 -2
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/cli.d.ts +0 -3
- package/dist/core/extensions/builtin/permission-system/cli.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/cli.js +0 -13
- package/dist/core/extensions/builtin/permission-system/cli.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +10 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +0 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +3 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +43 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/project-trust.js +2 -2
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +0 -4
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +0 -15
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +11 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +0 -7
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/index.d.ts +0 -5
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +0 -67
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -5
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +38 -34
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/tail-window.d.ts +15 -0
- package/dist/core/tools/tail-window.d.ts.map +1 -0
- package/dist/core/tools/tail-window.js +75 -0
- package/dist/core/tools/tail-window.js.map +1 -0
- package/dist/core/trust-manager.d.ts +8 -3
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +26 -11
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/aborted-error-label.d.ts +2 -0
- package/dist/modes/interactive/aborted-error-label.d.ts.map +1 -0
- package/dist/modes/interactive/aborted-error-label.js +8 -0
- package/dist/modes/interactive/aborted-error-label.js.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.js +101 -0
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +45 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +4 -4
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +18 -18
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +0 -7
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/event-output-buffer.d.ts +10 -0
- package/dist/modes/rpc/event-output-buffer.d.ts.map +1 -0
- package/dist/modes/rpc/event-output-buffer.js +27 -0
- package/dist/modes/rpc/event-output-buffer.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js +9 -11
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +17 -7
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +10 -3
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +14 -0
- package/dist/utils/shell.js.map +1 -1
- package/docs/compaction-guide.md +9 -9
- package/docs/compaction.md +2 -2
- package/docs/containerization.md +22 -22
- package/docs/custom-provider.md +13 -13
- package/docs/development.md +4 -2
- package/docs/extensions.md +18 -19
- package/docs/index.md +4 -4
- package/docs/json.md +21 -15
- package/docs/keybindings.md +6 -3
- package/docs/models.md +6 -6
- package/docs/packages.md +11 -11
- package/docs/prompt-templates.md +2 -2
- package/docs/providers.md +9 -9
- package/docs/rpc.md +14 -13
- package/docs/sdk.md +13 -9
- package/docs/security.md +14 -10
- package/docs/session-format.md +4 -4
- package/docs/sessions.md +14 -14
- package/docs/settings.md +14 -12
- package/docs/skills.md +8 -8
- package/docs/terminal-setup.md +2 -2
- package/docs/termux.md +3 -3
- package/docs/tui.md +4 -4
- package/docs/usage.md +52 -59
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-agent-core/README.md +4 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +0 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js +0 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +7 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/README.md +2 -4
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.js +0 -3
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +252 -470
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +533 -740
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +12 -5
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +29 -16
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts +0 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js +0 -13
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +0 -6
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +0 -14
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts +4 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +59 -19
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -5
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -8
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +1 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +93 -9
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +3 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +89 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +15 -8
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -7
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +72 -16
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -4
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -7
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +5 -5
- package/dist/core/experimental.d.ts +0 -2
- package/dist/core/experimental.d.ts.map +0 -1
- package/dist/core/experimental.js +0 -4
- package/dist/core/experimental.js.map +0 -1
- package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts +0 -11
- package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts.map +0 -1
- package/dist/core/extensions/builtin/compaction/overflow-detection.js +0 -40
- package/dist/core/extensions/builtin/compaction/overflow-detection.js.map +0 -1
- package/dist/core/extensions/builtin/system-messages.d.ts +0 -47
- package/dist/core/extensions/builtin/system-messages.d.ts.map +0 -1
- package/dist/core/extensions/builtin/system-messages.js +0 -117
- package/dist/core/extensions/builtin/system-messages.js.map +0 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -13
- package/dist/core/index.js.map +0 -1
package/docs/extensions.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Extensions
|
|
4
4
|
|
|
5
|
-
Extensions are TypeScript modules that extend
|
|
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
|
-
|
|
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 `.
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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",
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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("
|
|
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
|
|
13
|
+
To uninstall senpi itself, use the package manager that installed it:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npm uninstall -g @
|
|
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 @
|
|
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
|
|
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
|
|
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`](
|
|
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: "
|
|
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`](
|
|
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`](
|
|
48
|
-
- `UserMessage`
|
|
49
|
-
- `AssistantMessage`
|
|
50
|
-
- `ToolResultMessage`
|
|
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`](
|
|
53
|
-
- `BashExecutionMessage`
|
|
54
|
-
- `CustomMessage`
|
|
55
|
-
- `BranchSummaryMessage`
|
|
56
|
-
- `CompactionSummaryMessage`
|
|
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
|
|
package/docs/keybindings.md
CHANGED
|
@@ -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
|
|
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
|
|
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,
|
|
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 `~/.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/docs/packages.md
CHANGED
|
@@ -26,14 +26,14 @@ senpi install https://github.com/user/repo # raw URLs work too
|
|
|
26
26
|
senpi install /absolute/path/to/package
|
|
27
27
|
senpi install ./relative/path/to/package
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
senpi remove npm:@foo/bar
|
|
30
|
+
senpi list # show installed packages from settings
|
|
31
|
+
senpi update # update senpi, update packages, and reconcile pinned git refs
|
|
32
|
+
senpi update --extensions # update packages and reconcile pinned git refs only
|
|
33
|
+
senpi update --self # update senpi only
|
|
34
|
+
senpi update --self --force # reinstall senpi even if current
|
|
35
|
+
senpi update npm:@foo/bar # update one package
|
|
36
|
+
senpi update --extension npm:@foo/bar
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
These commands manage senpi packages, not the senpi CLI installation. To uninstall senpi itself, see [Quickstart](quickstart.md#uninstall).
|
|
@@ -43,8 +43,8 @@ By default, `install` and `remove` write to global settings (`~/.senpi/agent/set
|
|
|
43
43
|
To try a package without installing it, use `--extension` or `-e`. This installs to a temporary directory for the current run only:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
senpi -e npm:@foo/bar
|
|
47
|
+
senpi -e git:github.com/user/repo
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## Package Sources
|
|
@@ -58,7 +58,7 @@ npm:@scope/pkg@1.2.3
|
|
|
58
58
|
npm:pkg
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
- Versioned specs are pinned and skipped by package updates (`
|
|
61
|
+
- Versioned specs are pinned and skipped by package updates (`senpi update`, `senpi update --extensions`).
|
|
62
62
|
- Global installs use `npm install -g`.
|
|
63
63
|
- Project installs go under `.senpi/npm/`.
|
|
64
64
|
- Set `npmCommand` in `settings.json` to pin npm package lookup and install operations to a specific wrapper command such as `mise` or `asdf`.
|
package/docs/prompt-templates.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
>
|
|
1
|
+
> senpi can create prompt templates. Ask it to build one for your workflow.
|
|
2
2
|
|
|
3
3
|
# Prompt Templates
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ Prompt templates are Markdown snippets that expand into full prompts. Type `/nam
|
|
|
6
6
|
|
|
7
7
|
## Locations
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Senpi loads prompt templates from:
|
|
10
10
|
|
|
11
11
|
- Global: `~/.senpi/agent/prompts/*.md`
|
|
12
12
|
- Project: `.senpi/prompts/*.md` (only after the project is trusted)
|
package/docs/providers.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Providers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Senpi supports subscription-based providers via OAuth and API key providers via environment variables or auth file. For each provider, senpi knows all available models. The list is updated with every senpi release.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
@@ -43,7 +43,7 @@ Use `/login` in interactive mode and select a provider to store an API key in `a
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
46
|
-
|
|
46
|
+
senpi
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
| Provider | Environment Variable | `auth.json` key |
|
|
@@ -78,7 +78,7 @@ pi
|
|
|
78
78
|
| Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` | `xiaomi-token-plan-ams` |
|
|
79
79
|
| Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
|
|
80
80
|
|
|
81
|
-
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/
|
|
81
|
+
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/code-yeongyu/senpi/blob/main/packages/ai/src/env-api-keys.ts).
|
|
82
82
|
|
|
83
83
|
#### Auth File
|
|
84
84
|
|
|
@@ -169,14 +169,14 @@ export AWS_REGION=us-west-2
|
|
|
169
169
|
Also supports ECS task roles (`AWS_CONTAINER_CREDENTIALS_*`) and IRSA (`AWS_WEB_IDENTITY_TOKEN_FILE`).
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
|
|
172
|
+
senpi --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
Prompt caching is enabled automatically for Claude models whose ID contains a recognizable model name (base models and system-defined inference profiles). For application inference profiles (whose ARNs don't contain the model name), set `AWS_BEDROCK_FORCE_CACHE=1` to enable cache points:
|
|
176
176
|
|
|
177
177
|
```bash
|
|
178
178
|
export AWS_BEDROCK_FORCE_CACHE=1
|
|
179
|
-
|
|
179
|
+
senpi --provider amazon-bedrock --model arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
If you are connecting to a Bedrock API proxy, the following environment variables can be used:
|
|
@@ -200,7 +200,7 @@ export AWS_BEDROCK_FORCE_HTTP1=1
|
|
|
200
200
|
export CLOUDFLARE_API_KEY=... # or use /login
|
|
201
201
|
export CLOUDFLARE_ACCOUNT_ID=...
|
|
202
202
|
export CLOUDFLARE_GATEWAY_ID=... # create at dash.cloudflare.com → AI → AI Gateway
|
|
203
|
-
|
|
203
|
+
senpi --provider cloudflare-ai-gateway --model "claude-sonnet-4-5"
|
|
204
204
|
```
|
|
205
205
|
|
|
206
206
|
Routes to OpenAI, Anthropic, and Workers AI through Cloudflare AI Gateway. Workers AI uses the Unified API (`/compat`) and prefixed model IDs (`workers-ai/@cf/...`). OpenAI uses the OpenAI passthrough route (`/openai`) with native OpenAI model IDs such as `gpt-5.1`. Anthropic uses the Anthropic passthrough route (`/anthropic`) with native Anthropic model IDs such as `claude-sonnet-4-5`.
|
|
@@ -214,7 +214,7 @@ AI Gateway authentication uses `CLOUDFLARE_API_KEY` as `cf-aig-authorization`. U
|
|
|
214
214
|
| Stored BYOK | Cloudflare token only | Cloudflare injects provider keys stored in the AI Gateway dashboard |
|
|
215
215
|
| Inline BYOK | Cloudflare token plus upstream `Authorization` header | The request supplies the upstream provider key |
|
|
216
216
|
|
|
217
|
-
For normal
|
|
217
|
+
For normal senpi usage, prefer unified billing or stored BYOK. Inline BYOK requires configuring an additional upstream `Authorization` header for the Cloudflare AI Gateway provider, for example via a `models.json` provider/model override.
|
|
218
218
|
|
|
219
219
|
### Cloudflare Workers AI
|
|
220
220
|
|
|
@@ -223,10 +223,10 @@ For normal pi usage, prefer unified billing or stored BYOK. Inline BYOK requires
|
|
|
223
223
|
```bash
|
|
224
224
|
export CLOUDFLARE_API_KEY=... # or use /login
|
|
225
225
|
export CLOUDFLARE_ACCOUNT_ID=...
|
|
226
|
-
|
|
226
|
+
senpi --provider cloudflare-workers-ai --model "@cf/moonshotai/kimi-k2.6"
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
-
|
|
229
|
+
Senpi automatically sets `x-session-affinity` for [prefix caching](https://developers.cloudflare.com/workers-ai/features/prompt-caching/) discounts.
|
|
230
230
|
|
|
231
231
|
### Google Vertex AI
|
|
232
232
|
|
package/docs/rpc.md
CHANGED
|
@@ -7,7 +7,7 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
|
|
|
7
7
|
## Starting RPC Mode
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
senpi --mode rpc [options]
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Common options:
|
|
@@ -695,7 +695,7 @@ Response:
|
|
|
695
695
|
}
|
|
696
696
|
```
|
|
697
697
|
|
|
698
|
-
The current session name is available via `get_state` in the `sessionName` field. To set the initial name when starting RPC mode, pass `--name <name>` or `-n <name>` to the `
|
|
698
|
+
The current session name is available via `get_state` in the `sessionName` field. To set the initial name when starting RPC mode, pass `--name <name>` or `-n <name>` to the `senpi --mode rpc` process.
|
|
699
699
|
|
|
700
700
|
### Commands
|
|
701
701
|
|
|
@@ -715,9 +715,9 @@ Response:
|
|
|
715
715
|
"success": true,
|
|
716
716
|
"data": {
|
|
717
717
|
"commands": [
|
|
718
|
-
{"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.senpi/agent/extensions/session.ts"},
|
|
719
|
-
{"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "
|
|
720
|
-
{"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "
|
|
718
|
+
{"name": "session-name", "description": "Set or clear session name", "source": "extension", "sourceInfo": {"path": "/home/user/.senpi/agent/extensions/session.ts", "source": "auto", "scope": "user", "origin": "top-level"}},
|
|
719
|
+
{"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "sourceInfo": {"path": "/home/user/myproject/.senpi/prompts/fix-tests.md", "source": "auto", "scope": "project", "origin": "top-level"}},
|
|
720
|
+
{"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "sourceInfo": {"path": "/home/user/.senpi/agent/skills/brave-search/SKILL.md", "source": "auto", "scope": "user", "origin": "top-level"}}
|
|
721
721
|
]
|
|
722
722
|
}
|
|
723
723
|
}
|
|
@@ -730,11 +730,12 @@ Each command has:
|
|
|
730
730
|
- `"extension"`: Registered via `pi.registerCommand()` in an extension
|
|
731
731
|
- `"prompt"`: Loaded from a prompt template `.md` file
|
|
732
732
|
- `"skill"`: Loaded from a skill directory (name is prefixed with `skill:`)
|
|
733
|
-
- `
|
|
734
|
-
- `
|
|
735
|
-
- `"
|
|
736
|
-
- `"
|
|
737
|
-
- `
|
|
733
|
+
- `sourceInfo`: Provenance metadata for the owning resource (present for all sources, including extensions):
|
|
734
|
+
- `path`: Absolute file path to the command source
|
|
735
|
+
- `source`: Source identifier string (for example `"auto"` for auto-discovered locations, `"local"` for settings entries, `"cli"` for CLI paths, `"builtin"`, `"sdk"`, or a package source)
|
|
736
|
+
- `scope`: `"user"`, `"project"`, or `"temporary"`
|
|
737
|
+
- `origin`: `"package"` or `"top-level"`
|
|
738
|
+
- `baseDir`: Base directory of the owning resource (optional)
|
|
738
739
|
|
|
739
740
|
**Note**: Built-in TUI commands (`/settings`, `/hotkeys`, etc.) are not included. They are handled only in interactive mode and would not execute if sent via `prompt`.
|
|
740
741
|
|
|
@@ -1133,7 +1134,7 @@ Set the terminal window/tab title. Fire-and-forget.
|
|
|
1133
1134
|
"type": "extension_ui_request",
|
|
1134
1135
|
"id": "uuid-8",
|
|
1135
1136
|
"method": "setTitle",
|
|
1136
|
-
"title": "
|
|
1137
|
+
"title": "senpi - my project"
|
|
1137
1138
|
}
|
|
1138
1139
|
```
|
|
1139
1140
|
|
|
@@ -1320,7 +1321,7 @@ import subprocess
|
|
|
1320
1321
|
import json
|
|
1321
1322
|
|
|
1322
1323
|
proc = subprocess.Popen(
|
|
1323
|
-
["
|
|
1324
|
+
["senpi", "--mode", "rpc", "--no-session"],
|
|
1324
1325
|
stdin=subprocess.PIPE,
|
|
1325
1326
|
stdout=subprocess.PIPE,
|
|
1326
1327
|
text=True
|
|
@@ -1359,7 +1360,7 @@ For a complete example of handling the extension UI protocol, see [`examples/rpc
|
|
|
1359
1360
|
const { spawn } = require("child_process");
|
|
1360
1361
|
const { StringDecoder } = require("string_decoder");
|
|
1361
1362
|
|
|
1362
|
-
const agent = spawn("
|
|
1363
|
+
const agent = spawn("senpi", ["--mode", "rpc", "--no-session"]);
|
|
1363
1364
|
|
|
1364
1365
|
function attachJsonlReader(stream, onLine) {
|
|
1365
1366
|
const decoder = new StringDecoder("utf8");
|