@oh-my-pi/pi-coding-agent 3.37.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +103 -0
- package/README.md +44 -3
- package/docs/extensions.md +29 -4
- package/docs/sdk.md +3 -3
- package/package.json +5 -5
- package/src/cli/args.ts +8 -0
- package/src/config.ts +5 -15
- package/src/core/agent-session.ts +217 -51
- package/src/core/auth-storage.ts +456 -47
- package/src/core/bash-executor.ts +79 -14
- package/src/core/custom-commands/types.ts +1 -1
- package/src/core/custom-tools/types.ts +1 -1
- package/src/core/export-html/index.ts +33 -1
- package/src/core/export-html/template.css +99 -0
- package/src/core/export-html/template.generated.ts +1 -1
- package/src/core/export-html/template.js +133 -8
- package/src/core/extensions/index.ts +22 -4
- package/src/core/extensions/loader.ts +152 -214
- package/src/core/extensions/runner.ts +139 -79
- package/src/core/extensions/types.ts +143 -19
- package/src/core/extensions/wrapper.ts +5 -8
- package/src/core/hooks/types.ts +1 -1
- package/src/core/index.ts +2 -1
- package/src/core/keybindings.ts +4 -1
- package/src/core/model-registry.ts +4 -4
- package/src/core/model-resolver.ts +35 -26
- package/src/core/sdk.ts +96 -76
- package/src/core/settings-manager.ts +45 -14
- package/src/core/system-prompt.ts +5 -15
- package/src/core/tools/bash.ts +115 -54
- package/src/core/tools/find.ts +86 -7
- package/src/core/tools/grep.ts +27 -6
- package/src/core/tools/index.ts +15 -6
- package/src/core/tools/ls.ts +49 -18
- package/src/core/tools/render-utils.ts +2 -1
- package/src/core/tools/task/worker.ts +35 -12
- package/src/core/tools/web-search/auth.ts +37 -32
- package/src/core/tools/web-search/providers/anthropic.ts +35 -22
- package/src/index.ts +101 -9
- package/src/main.ts +60 -20
- package/src/migrations.ts +47 -2
- package/src/modes/index.ts +2 -2
- package/src/modes/interactive/components/assistant-message.ts +25 -7
- package/src/modes/interactive/components/bash-execution.ts +5 -0
- package/src/modes/interactive/components/branch-summary-message.ts +5 -0
- package/src/modes/interactive/components/compaction-summary-message.ts +5 -0
- package/src/modes/interactive/components/countdown-timer.ts +38 -0
- package/src/modes/interactive/components/custom-editor.ts +8 -0
- package/src/modes/interactive/components/custom-message.ts +5 -0
- package/src/modes/interactive/components/footer.ts +2 -5
- package/src/modes/interactive/components/hook-input.ts +29 -20
- package/src/modes/interactive/components/hook-selector.ts +52 -38
- package/src/modes/interactive/components/index.ts +39 -0
- package/src/modes/interactive/components/login-dialog.ts +160 -0
- package/src/modes/interactive/components/model-selector.ts +10 -2
- package/src/modes/interactive/components/session-selector.ts +5 -1
- package/src/modes/interactive/components/settings-defs.ts +9 -0
- package/src/modes/interactive/components/status-line/segments.ts +3 -3
- package/src/modes/interactive/components/tool-execution.ts +9 -16
- package/src/modes/interactive/components/tree-selector.ts +1 -6
- package/src/modes/interactive/interactive-mode.ts +466 -215
- package/src/modes/interactive/theme/theme.ts +50 -2
- package/src/modes/print-mode.ts +78 -31
- package/src/modes/rpc/rpc-mode.ts +186 -78
- package/src/modes/rpc/rpc-types.ts +10 -3
- package/src/prompts/system-prompt.md +36 -28
- package/src/utils/clipboard.ts +90 -50
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/tools-manager.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,109 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [4.0.1] - 2026-01-10
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added usage limit error detection to enable automatic credential switching when Codex accounts hit rate limits
|
|
9
|
+
- Added Codex usage API integration to proactively check account limits before credential selection
|
|
10
|
+
- Added credential backoff tracking to temporarily skip rate-limited accounts during selection
|
|
11
|
+
- Multi-credential usage-aware selection for OpenAI Codex OAuth accounts with automatic fallback when rate limits are reached
|
|
12
|
+
- Consistent session-to-credential hashing (FNV-1a) for stable credential assignment across sessions
|
|
13
|
+
- Codex usage API integration to detect and cache rate limit status per account
|
|
14
|
+
- Automatic mid-session credential switching when usage limits are hit
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Changed credential selection to use deterministic FNV-1a hashing for consistent session-to-credential mapping
|
|
19
|
+
- Changed OAuth credential resolution to try credentials in priority order, skipping blocked ones
|
|
20
|
+
|
|
21
|
+
## [4.0.0] - 2026-01-10
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Exported `InteractiveModeOptions` type for programmatic SDK usage
|
|
26
|
+
- Exported additional UI components for extensions: `ArminComponent`, `AssistantMessageComponent`, `BashExecutionComponent`, `BranchSummaryMessageComponent`, `CompactionSummaryMessageComponent`, `CustomEditor`, `CustomMessageComponent`, `FooterComponent`, `ExtensionEditorComponent`, `ExtensionInputComponent`, `ExtensionSelectorComponent`, `LoginDialogComponent`, `ModelSelectorComponent`, `OAuthSelectorComponent`, `SessionSelectorComponent`, `SettingsSelectorComponent`, `ShowImagesSelectorComponent`, `ThemeSelectorComponent`, `ThinkingSelectorComponent`, `ToolExecutionComponent`, `TreeSelectorComponent`, `UserMessageComponent`, `UserMessageSelectorComponent`
|
|
27
|
+
- Exported `renderDiff`, `truncateToVisualLines`, and related types for extension use
|
|
28
|
+
- `setFooter()` and `setHeader()` methods on `ExtensionUIContext` for custom footer/header components
|
|
29
|
+
- `setEditorComponent()` method on `ExtensionUIContext` for custom editor components
|
|
30
|
+
- `supportsUsageInStreaming` model config option to control `stream_options: { include_usage: true }` behavior
|
|
31
|
+
- Terminal setup documentation for Kitty keyboard protocol configuration (Ghostty, wezterm, Windows Terminal)
|
|
32
|
+
- Documentation for paid Cloud Code Assist subscriptions via `GOOGLE_CLOUD_PROJECT` env var
|
|
33
|
+
- Environment variables reference section in README
|
|
34
|
+
- `--no-tools` flag to disable all built-in tools, enabling extension-only setups
|
|
35
|
+
- `--no-extensions` flag to disable extension discovery while still allowing explicit `-e` paths
|
|
36
|
+
- `blockImages` setting to prevent images from being sent to LLM providers
|
|
37
|
+
- `thinkingBudgets` setting to customize token budgets per thinking level
|
|
38
|
+
- `PI_SKIP_VERSION_CHECK` environment variable to disable new version notifications at startup
|
|
39
|
+
- Anthropic OAuth support via `/login` to authenticate with Claude Pro/Max subscription
|
|
40
|
+
- OpenCode Zen provider support via `OPENCODE_API_KEY` env var and `opencode/<model-id>` syntax
|
|
41
|
+
- Session picker (`pi -r`) and `--session` flag support searching/resuming by session ID (UUID prefix)
|
|
42
|
+
- Session ID forwarding to LLM providers for session-based caching (used by OpenAI Codex for prompt caching)
|
|
43
|
+
- `dequeue` keybinding (`Alt+Up`) to restore queued steering/follow-up messages back into the editor
|
|
44
|
+
- Pluggable operations for built-in tools enabling remote execution via SSH or other transports (`ReadOperations`, `WriteOperations`, `EditOperations`, `BashOperations`, `LsOperations`, `GrepOperations`, `FindOperations`)
|
|
45
|
+
- `/model <search>` pre-filters the model selector or auto-selects on exact match; use `provider/model` syntax to disambiguate
|
|
46
|
+
- Managed binaries directory (`~/.omp/bin/`) for fd and rg tools
|
|
47
|
+
- `FooterDataProvider` for custom footers with `getGitBranch()`, `getExtensionStatuses()`, and `onBranchChange()`
|
|
48
|
+
- `ctx.ui.custom()` accepts `{ overlay: true }` option for floating modal components
|
|
49
|
+
- `ctx.ui.getAllThemes()`, `ctx.ui.getTheme(name)`, `ctx.ui.setTheme(name | Theme)` for theme management
|
|
50
|
+
- `setActiveTools()` for dynamic tool management
|
|
51
|
+
- `setModel()`, `getThinkingLevel()`, `setThinkingLevel()` methods for runtime model and thinking level changes
|
|
52
|
+
- `ctx.shutdown()` for requesting graceful shutdown
|
|
53
|
+
- `pi.sendUserMessage()` for sending user messages from extensions
|
|
54
|
+
- Extension UI dialogs (`select`, `confirm`, `input`) support `timeout` option with live countdown display
|
|
55
|
+
- Extension UI dialogs accept optional `AbortSignal` to programmatically dismiss dialogs
|
|
56
|
+
- Async extension factories for dynamic imports and lazy-loaded dependencies
|
|
57
|
+
- `user_bash` event for intercepting user `!`/`!!` commands
|
|
58
|
+
- Built-in renderers used automatically for tool overrides without custom `renderCall`/`renderResult`
|
|
59
|
+
- `InteractiveMode`, `runPrintMode()`, `runRpcMode()` exported for building custom run modes
|
|
60
|
+
- Copy link button on messages for deep linking to specific entries
|
|
61
|
+
- Codex injection info display showing system prompt modifications
|
|
62
|
+
- URL parameter support for `leafId` and `targetId` deep linking
|
|
63
|
+
- Wayland clipboard support for `/copy` command using wl-copy with xclip/xsel fallback
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- Bash tool output truncation now recalculates on terminal resize instead of using cached width
|
|
68
|
+
- Web search tool headers updated to match Claude Code client format for better compatibility
|
|
69
|
+
- `discoverSkills()` return type documented as `{ skills: Skill[], warnings: SkillWarning[] }` in SDK docs
|
|
70
|
+
- Default model for OpenCode provider changed from `claude-sonnet-4-5` to `claude-opus-4-5`
|
|
71
|
+
- Terminal color mode detection defaults to truecolor for modern terminals instead of 256color
|
|
72
|
+
- System prompt restructured with XML tags and clearer instructions format
|
|
73
|
+
- `before_agent_start` event receives `systemPrompt` in the event object and returns `systemPrompt` (full replacement) instead of `systemPromptAppend`
|
|
74
|
+
- `discoverSkills()` returns `{ skills: Skill[], warnings: SkillWarning[] }` instead of `Skill[]`
|
|
75
|
+
- `ctx.ui.custom()` factory signature changed from `(tui, theme, done)` to `(tui, theme, keybindings, done)`
|
|
76
|
+
- `ExtensionRunner.initialize()` signature changed from options object to positional params `(actions, contextActions, commandContextActions?, uiContext?)`
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- Wayland clipboard copy (`wl-copy`) no longer blocks when the process doesn't exit promptly
|
|
81
|
+
- Empty `--tools` flag now correctly enables all built-in tools instead of disabling them
|
|
82
|
+
- Bash tool handles spawn errors gracefully instead of crashing the agent
|
|
83
|
+
- Components properly rebuild their content on theme change via `invalidate()` override
|
|
84
|
+
- `setTheme()` triggers a full rerender so previously rendered components update with new theme colors
|
|
85
|
+
- Session ID updates correctly when branching sessions
|
|
86
|
+
- External edits to `settings.json` while pi is running are preserved when pi saves settings
|
|
87
|
+
- Default thinking level from settings applies correctly when `enabledModels` is configured
|
|
88
|
+
- LM Studio compatibility for OpenAI Responses tool strict mapping
|
|
89
|
+
- Symlinked directories in `prompts/` folders are followed when loading prompt templates
|
|
90
|
+
- String `systemPrompt` in `createAgentSession()` works as a full replacement instead of having context files and skills appended
|
|
91
|
+
- Update notification for bun binary installs shows release download URL instead of npm command
|
|
92
|
+
- ESC key works during "Working..." state after auto-retry
|
|
93
|
+
- Abort messages show correct retry attempt count
|
|
94
|
+
- Antigravity provider returning 429 errors despite available quota
|
|
95
|
+
- Malformed thinking text in Gemini/Antigravity responses where thinking content appeared as regular text
|
|
96
|
+
- `--no-skills` flag correctly prevents skills from loading in interactive mode
|
|
97
|
+
- Overflow-based compaction skips if error came from a different model or was already handled
|
|
98
|
+
- OpenAI Codex context window reduced from 400k to 272k tokens to match Codex CLI defaults
|
|
99
|
+
- Context overflow detection recognizes `context_length_exceeded` errors
|
|
100
|
+
- Key presses no longer dropped when input is batched over SSH
|
|
101
|
+
- Clipboard image support works on Alpine Linux and other musl-based distros
|
|
102
|
+
- Queued steering/follow-up messages no longer wipe unsent editor input
|
|
103
|
+
- OAuth token refresh failure no longer crashes app at startup
|
|
104
|
+
- Status bar shows correct git branch when running in a git worktree
|
|
105
|
+
- Ctrl+V clipboard image paste works on Wayland sessions
|
|
106
|
+
- Extension directories in `settings.json` respect `package.json` manifests
|
|
107
|
+
|
|
5
108
|
## [3.37.1] - 2026-01-10
|
|
6
109
|
|
|
7
110
|
## [3.37.0] - 2026-01-10
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows-
|
|
|
9
9
|
- [Getting Started](#getting-started)
|
|
10
10
|
- [Installation](#installation)
|
|
11
11
|
- [Windows Setup](#windows-setup)
|
|
12
|
+
- [Terminal Setup](#terminal-setup)
|
|
12
13
|
- [API Keys & OAuth](#api-keys--oauth)
|
|
13
14
|
- [Quick Start](#quick-start)
|
|
14
15
|
- [Usage](#usage)
|
|
@@ -106,6 +107,30 @@ For most users, [Git for Windows](https://git-scm.com/download/win) is sufficien
|
|
|
106
107
|
}
|
|
107
108
|
```
|
|
108
109
|
|
|
110
|
+
### Terminal Setup
|
|
111
|
+
|
|
112
|
+
Pi uses the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) for reliable modifier key detection. Most modern terminals support this protocol, but some require configuration.
|
|
113
|
+
|
|
114
|
+
**Kitty, iTerm2:** Work out of the box.
|
|
115
|
+
|
|
116
|
+
**Ghostty:** Add to your Ghostty config (`~/.config/ghostty/config`):
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
keybind = alt+backspace=text:\x1b\x7f
|
|
120
|
+
keybind = shift+enter=text:\n
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**wezterm:** Create `~/.wezterm.lua`:
|
|
124
|
+
|
|
125
|
+
```lua
|
|
126
|
+
local wezterm = require 'wezterm'
|
|
127
|
+
local config = wezterm.config_builder()
|
|
128
|
+
config.enable_kitty_keyboard = true
|
|
129
|
+
return config
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Windows Terminal:** Does not support the Kitty keyboard protocol. Shift+Enter cannot be distinguished from Enter. Use Ctrl+Enter for multi-line input instead. All other keybindings work correctly.
|
|
133
|
+
|
|
109
134
|
### API Keys & OAuth
|
|
110
135
|
|
|
111
136
|
**Option 1: Auth file** (recommended)
|
|
@@ -169,6 +194,7 @@ omp
|
|
|
169
194
|
- Gemini CLI uses the production Cloud Code Assist endpoint (standard Gemini models)
|
|
170
195
|
- Antigravity uses a sandbox endpoint with access to Gemini 3, Claude (sonnet/opus thinking), and GPT-OSS models
|
|
171
196
|
- Both are free with any Google account, subject to rate limits
|
|
197
|
+
- Paid Cloud Code Assist subscriptions: set `GOOGLE_CLOUD_PROJECT` or `GOOGLE_CLOUD_PROJECT_ID` env var to your project ID
|
|
172
198
|
|
|
173
199
|
Credentials stored in `~/.omp/agent/auth.json`. Use `/logout` to clear.
|
|
174
200
|
|
|
@@ -196,7 +222,7 @@ The agent reads, writes, and edits files, and executes commands via bash.
|
|
|
196
222
|
| Command | Description |
|
|
197
223
|
| ------------------------- | --------------------------------------------------------------------------- |
|
|
198
224
|
| `/settings` | Open settings menu (thinking, theme, queue mode, toggles) |
|
|
199
|
-
| `/model` | Switch models mid-session
|
|
225
|
+
| `/model` | Switch models mid-session. Use `/model <search>` or `provider/model` to prefilter/disambiguate. |
|
|
200
226
|
| `/export [file\|--copy]` | Export session to HTML file or copy to clipboard |
|
|
201
227
|
| `/share` | Upload session as secret GitHub gist, get shareable URL (requires `gh` CLI) |
|
|
202
228
|
| `/session` | Show session info: path, message counts, token usage, cost |
|
|
@@ -239,7 +265,7 @@ The agent reads, writes, and edits files, and executes commands via bash.
|
|
|
239
265
|
| Key | Action |
|
|
240
266
|
| ------------------------- | ---------------------------- |
|
|
241
267
|
| Enter | Send message |
|
|
242
|
-
| Shift+Enter
|
|
268
|
+
| Shift+Enter | New line (Ctrl+Enter on Windows Terminal) |
|
|
243
269
|
| Ctrl+W / Option+Backspace | Delete word backwards |
|
|
244
270
|
| Ctrl+U | Delete to start of line |
|
|
245
271
|
| Ctrl+K | Delete to end of line |
|
|
@@ -320,8 +346,11 @@ omp -r # Short form
|
|
|
320
346
|
omp --no-session # Ephemeral mode (don't save)
|
|
321
347
|
|
|
322
348
|
omp --session /path/to/file.jsonl # Use specific session file
|
|
349
|
+
omp --session a8ec1c2a # Resume by session ID (partial UUID)
|
|
323
350
|
```
|
|
324
351
|
|
|
352
|
+
**Resuming by session ID:** The `--session` flag accepts a session UUID (or prefix). Session IDs are visible in filenames under `~/.omp/agent/sessions/<project>/` (e.g., `2025-12-13T17-47-46-817Z_a8ec1c2a-5a5f-4699-88cb-03e7d3cb9292.jsonl`). The UUID is the part after the underscore. You can also search by session ID in the `omp -r` picker.
|
|
353
|
+
|
|
325
354
|
### Context Compaction
|
|
326
355
|
|
|
327
356
|
Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent ones.
|
|
@@ -493,6 +522,7 @@ Add custom models (Ollama, vLLM, LM Studio, etc.) via `~/.omp/agent/models.json`
|
|
|
493
522
|
| `supportsStore` | Whether provider supports `store` field |
|
|
494
523
|
| `supportsDeveloperRole` | Use `developer` vs `system` role |
|
|
495
524
|
| `supportsReasoningEffort` | Support for `reasoning_effort` parameter |
|
|
525
|
+
| `supportsUsageInStreaming` | Whether provider supports `stream_options: { include_usage: true }`. Default: `true` |
|
|
496
526
|
| `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
|
|
497
527
|
|
|
498
528
|
**Live reload:** The file reloads each time you open `/model`. Edit during session; no restart needed.
|
|
@@ -831,9 +861,11 @@ omp [options] [@files...] [messages...]
|
|
|
831
861
|
| `--continue`, `-c` | Continue most recent session |
|
|
832
862
|
| `--resume`, `-r` | Select session to resume |
|
|
833
863
|
| `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling. Supports glob patterns (e.g., `anthropic/*`, `*sonnet*:high`) and fuzzy matching (e.g., `sonnet,haiku:low`) |
|
|
864
|
+
| `--no-tools` | Disable all built-in tools |
|
|
834
865
|
| `--tools <tools>` | Comma-separated tool list (default: `read,bash,edit,write`) |
|
|
835
866
|
| `--thinking <level>` | Thinking level: `off`, `minimal`, `low`, `medium`, `high` |
|
|
836
|
-
| `--
|
|
867
|
+
| `--extension <path>`, `-e` | Load an extension file (can be used multiple times) |
|
|
868
|
+
| `--no-extensions` | Disable extension discovery (explicit `-e` paths still work) |
|
|
837
869
|
| `--no-skills` | Disable skills discovery and loading |
|
|
838
870
|
| `--skills <patterns>` | Comma-separated glob patterns to filter skills (e.g., `git-*,docker`) |
|
|
839
871
|
| `--export <file> [output]` | Export session to HTML |
|
|
@@ -892,6 +924,15 @@ omp --tools read,grep,find,ls -p "Review the architecture"
|
|
|
892
924
|
omp --export session.jsonl output.html
|
|
893
925
|
```
|
|
894
926
|
|
|
927
|
+
### Environment Variables
|
|
928
|
+
|
|
929
|
+
| Variable | Description |
|
|
930
|
+
|----------|-------------|
|
|
931
|
+
| `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc. | API keys for providers (see [API Keys & OAuth](#api-keys--oauth)) |
|
|
932
|
+
| `PI_CODING_AGENT_DIR` | Override the agent config directory (default: `~/.omp/agent`) |
|
|
933
|
+
| `PI_SKIP_VERSION_CHECK` | Skip new version check at startup (useful for Nix or other package manager installs) |
|
|
934
|
+
| `VISUAL`, `EDITOR` | External editor for Ctrl+G (e.g., `vim`, `code --wait`) |
|
|
935
|
+
|
|
895
936
|
---
|
|
896
937
|
|
|
897
938
|
## Tools
|
package/docs/extensions.md
CHANGED
|
@@ -260,7 +260,7 @@ pi starts
|
|
|
260
260
|
▼
|
|
261
261
|
user sends prompt ─────────────────────────────────────────┐
|
|
262
262
|
│ │
|
|
263
|
-
├─► before_agent_start (can inject message,
|
|
263
|
+
├─► before_agent_start (can inject message, modify system prompt)
|
|
264
264
|
├─► agent_start │
|
|
265
265
|
│ │
|
|
266
266
|
│ ┌─── turn (repeats while LLM calls tools) ───┐ │
|
|
@@ -311,6 +311,8 @@ pi.on("session_start", async (_event, ctx) => {
|
|
|
311
311
|
});
|
|
312
312
|
```
|
|
313
313
|
|
|
314
|
+
**Examples:** [claude-rules.ts](../examples/extensions/claude-rules.ts), [custom-header.ts](../examples/extensions/custom-header.ts), [file-trigger.ts](../examples/extensions/file-trigger.ts), [status-line.ts](../examples/extensions/status-line.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
|
|
315
|
+
|
|
314
316
|
#### session_before_switch / session_switch
|
|
315
317
|
|
|
316
318
|
Fired when starting a new session (`/new`) or switching sessions (`/resume`).
|
|
@@ -332,6 +334,8 @@ pi.on("session_switch", async (event, ctx) => {
|
|
|
332
334
|
});
|
|
333
335
|
```
|
|
334
336
|
|
|
337
|
+
**Examples:** [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [status-line.ts](../examples/extensions/status-line.ts), [todo.ts](../examples/extensions/todo.ts)
|
|
338
|
+
|
|
335
339
|
#### session_before_branch / session_branch
|
|
336
340
|
|
|
337
341
|
Fired when branching via `/branch`.
|
|
@@ -349,6 +353,8 @@ pi.on("session_branch", async (event, ctx) => {
|
|
|
349
353
|
});
|
|
350
354
|
```
|
|
351
355
|
|
|
356
|
+
**Examples:** [confirm-destructive.ts](../examples/extensions/confirm-destructive.ts), [dirty-repo-guard.ts](../examples/extensions/dirty-repo-guard.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
|
|
357
|
+
|
|
352
358
|
#### session_before_compact / session_compact
|
|
353
359
|
|
|
354
360
|
Fired on compaction. See [compaction.md](compaction.md) for details.
|
|
@@ -376,6 +382,8 @@ pi.on("session_compact", async (event, ctx) => {
|
|
|
376
382
|
});
|
|
377
383
|
```
|
|
378
384
|
|
|
385
|
+
**Examples:** [custom-compaction.ts](../examples/extensions/custom-compaction.ts)
|
|
386
|
+
|
|
379
387
|
#### session_before_tree / session_tree
|
|
380
388
|
|
|
381
389
|
Fired on `/tree` navigation.
|
|
@@ -393,6 +401,8 @@ pi.on("session_tree", async (event, ctx) => {
|
|
|
393
401
|
});
|
|
394
402
|
```
|
|
395
403
|
|
|
404
|
+
**Examples:** [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
|
|
405
|
+
|
|
396
406
|
#### session_shutdown
|
|
397
407
|
|
|
398
408
|
Fired on exit (Ctrl+C, Ctrl+D, SIGTERM).
|
|
@@ -403,16 +413,19 @@ pi.on("session_shutdown", async (_event, ctx) => {
|
|
|
403
413
|
});
|
|
404
414
|
```
|
|
405
415
|
|
|
416
|
+
**Examples:** [auto-commit-on-exit.ts](../examples/extensions/auto-commit-on-exit.ts)
|
|
417
|
+
|
|
406
418
|
### Agent Events
|
|
407
419
|
|
|
408
420
|
#### before_agent_start
|
|
409
421
|
|
|
410
|
-
Fired after user submits prompt, before agent loop. Can inject a message and/or
|
|
422
|
+
Fired after user submits prompt, before agent loop. Can inject a message and/or modify the system prompt.
|
|
411
423
|
|
|
412
424
|
```typescript
|
|
413
425
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
414
426
|
// event.prompt - user's prompt text
|
|
415
427
|
// event.images - attached images (if any)
|
|
428
|
+
// event.systemPrompt - current system prompt
|
|
416
429
|
|
|
417
430
|
return {
|
|
418
431
|
// Inject a persistent message (stored in session, sent to LLM)
|
|
@@ -421,12 +434,14 @@ pi.on("before_agent_start", async (event, ctx) => {
|
|
|
421
434
|
content: "Additional context for the LLM",
|
|
422
435
|
display: true,
|
|
423
436
|
},
|
|
424
|
-
//
|
|
425
|
-
|
|
437
|
+
// Replace the system prompt for this turn (chained across extensions)
|
|
438
|
+
systemPrompt: event.systemPrompt + "\n\nExtra instructions for this turn...",
|
|
426
439
|
};
|
|
427
440
|
});
|
|
428
441
|
```
|
|
429
442
|
|
|
443
|
+
**Examples:** [claude-rules.ts](../examples/extensions/claude-rules.ts), [pirate.ts](../examples/extensions/pirate.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts), [preset.ts](../examples/extensions/preset.ts), [ssh.ts](../examples/extensions/ssh.ts)
|
|
444
|
+
|
|
430
445
|
#### agent_start / agent_end
|
|
431
446
|
|
|
432
447
|
Fired once per user prompt.
|
|
@@ -439,6 +454,8 @@ pi.on("agent_end", async (event, ctx) => {
|
|
|
439
454
|
});
|
|
440
455
|
```
|
|
441
456
|
|
|
457
|
+
**Examples:** [chalk-logger.ts](../examples/extensions/chalk-logger.ts), [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts)
|
|
458
|
+
|
|
442
459
|
#### turn_start / turn_end
|
|
443
460
|
|
|
444
461
|
Fired for each turn (one LLM response + tool calls).
|
|
@@ -453,6 +470,8 @@ pi.on("turn_end", async (event, ctx) => {
|
|
|
453
470
|
});
|
|
454
471
|
```
|
|
455
472
|
|
|
473
|
+
**Examples:** [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts), [status-line.ts](../examples/extensions/status-line.ts)
|
|
474
|
+
|
|
456
475
|
#### context
|
|
457
476
|
|
|
458
477
|
Fired before each LLM call. Modify messages non-destructively.
|
|
@@ -465,6 +484,8 @@ pi.on("context", async (event, ctx) => {
|
|
|
465
484
|
});
|
|
466
485
|
```
|
|
467
486
|
|
|
487
|
+
**Examples:** [plan-mode.ts](../examples/extensions/plan-mode.ts)
|
|
488
|
+
|
|
468
489
|
### Tool Events
|
|
469
490
|
|
|
470
491
|
#### tool_call
|
|
@@ -483,6 +504,8 @@ pi.on("tool_call", async (event, ctx) => {
|
|
|
483
504
|
});
|
|
484
505
|
```
|
|
485
506
|
|
|
507
|
+
**Examples:** [chalk-logger.ts](../examples/extensions/chalk-logger.ts), [permission-gate.ts](../examples/extensions/permission-gate.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts), [protected-paths.ts](../examples/extensions/protected-paths.ts)
|
|
508
|
+
|
|
486
509
|
#### tool_result
|
|
487
510
|
|
|
488
511
|
Fired after tool executes. **Can modify result.**
|
|
@@ -503,6 +526,8 @@ pi.on("tool_result", async (event, ctx) => {
|
|
|
503
526
|
});
|
|
504
527
|
```
|
|
505
528
|
|
|
529
|
+
**Examples:** [git-checkpoint.ts](../examples/extensions/git-checkpoint.ts), [plan-mode.ts](../examples/extensions/plan-mode.ts)
|
|
530
|
+
|
|
506
531
|
## ExtensionContext
|
|
507
532
|
|
|
508
533
|
Every handler receives `ctx: ExtensionContext`:
|
package/docs/sdk.md
CHANGED
|
@@ -532,7 +532,7 @@ Hook API methods:
|
|
|
532
532
|
import { createAgentSession, discoverSkills, type Skill } from "@oh-my-pi/pi-coding-agent";
|
|
533
533
|
|
|
534
534
|
// Discover and filter
|
|
535
|
-
const allSkills = discoverSkills();
|
|
535
|
+
const { skills: allSkills, warnings } = discoverSkills();
|
|
536
536
|
const filtered = allSkills.filter((s) => s.name.includes("search"));
|
|
537
537
|
|
|
538
538
|
// Custom skill
|
|
@@ -554,7 +554,7 @@ const { session } = await createAgentSession({
|
|
|
554
554
|
});
|
|
555
555
|
|
|
556
556
|
// Discovery with settings filter
|
|
557
|
-
const skills = discoverSkills(process.cwd(), undefined, {
|
|
557
|
+
const { skills } = discoverSkills(process.cwd(), undefined, {
|
|
558
558
|
ignoredSkills: ["browser-*"], // glob patterns to exclude
|
|
559
559
|
includeSkills: ["search-*"], // glob patterns to include (empty = all)
|
|
560
560
|
});
|
|
@@ -753,7 +753,7 @@ const model = modelRegistry.find("provider", "id"); // Find specific model
|
|
|
753
753
|
const builtIn = getModel("anthropic", "claude-opus-4-5"); // Built-in only
|
|
754
754
|
|
|
755
755
|
// Skills
|
|
756
|
-
const skills = discoverSkills(cwd, agentDir, skillsSettings);
|
|
756
|
+
const { skills, warnings } = discoverSkills(cwd, agentDir, skillsSettings);
|
|
757
757
|
|
|
758
758
|
// Hooks (async - loads TypeScript)
|
|
759
759
|
const hooks = await discoverHooks(cwd, agentDir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"prepublishOnly": "bun run generate-template && bun run clean && bun run build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@oh-my-pi/pi-ai": "
|
|
43
|
-
"@oh-my-pi/pi-agent-core": "
|
|
44
|
-
"@oh-my-pi/pi-git-tool": "
|
|
45
|
-
"@oh-my-pi/pi-tui": "
|
|
42
|
+
"@oh-my-pi/pi-ai": "4.0.1",
|
|
43
|
+
"@oh-my-pi/pi-agent-core": "4.0.1",
|
|
44
|
+
"@oh-my-pi/pi-git-tool": "4.0.1",
|
|
45
|
+
"@oh-my-pi/pi-tui": "4.0.1",
|
|
46
46
|
"@openai/agents": "^0.3.7",
|
|
47
47
|
"@sinclair/typebox": "^0.34.46",
|
|
48
48
|
"ajv": "^8.17.1",
|
package/src/cli/args.ts
CHANGED
|
@@ -30,8 +30,10 @@ export interface Args {
|
|
|
30
30
|
sessionDir?: string;
|
|
31
31
|
models?: string[];
|
|
32
32
|
tools?: string[];
|
|
33
|
+
noTools?: boolean;
|
|
33
34
|
hooks?: string[];
|
|
34
35
|
extensions?: string[];
|
|
36
|
+
noExtensions?: boolean;
|
|
35
37
|
print?: boolean;
|
|
36
38
|
export?: string;
|
|
37
39
|
noSkills?: boolean;
|
|
@@ -96,6 +98,8 @@ export function parseArgs(args: string[], extensionFlags?: Map<string, { type: "
|
|
|
96
98
|
result.sessionDir = args[++i];
|
|
97
99
|
} else if (arg === "--models" && i + 1 < args.length) {
|
|
98
100
|
result.models = args[++i].split(",").map((s) => s.trim());
|
|
101
|
+
} else if (arg === "--no-tools") {
|
|
102
|
+
result.noTools = true;
|
|
99
103
|
} else if (arg === "--tools" && i + 1 < args.length) {
|
|
100
104
|
const toolNames = args[++i].split(",").map((s) => s.trim());
|
|
101
105
|
const validTools: string[] = [];
|
|
@@ -132,6 +136,8 @@ export function parseArgs(args: string[], extensionFlags?: Map<string, { type: "
|
|
|
132
136
|
} else if ((arg === "--extension" || arg === "-e") && i + 1 < args.length) {
|
|
133
137
|
result.extensions = result.extensions ?? [];
|
|
134
138
|
result.extensions.push(args[++i]);
|
|
139
|
+
} else if (arg === "--no-extensions") {
|
|
140
|
+
result.noExtensions = true;
|
|
135
141
|
} else if (arg === "--no-skills") {
|
|
136
142
|
result.noSkills = true;
|
|
137
143
|
} else if (arg === "--skills" && i + 1 < args.length) {
|
|
@@ -189,11 +195,13 @@ ${chalk.bold("Options:")}
|
|
|
189
195
|
--no-session Don't save session (ephemeral)
|
|
190
196
|
--models <patterns> Comma-separated model patterns for Ctrl+P cycling
|
|
191
197
|
Supports globs (anthropic/*, *sonnet*) and fuzzy matching
|
|
198
|
+
--no-tools Disable all built-in tools
|
|
192
199
|
--tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)
|
|
193
200
|
Available: read, bash, edit, write, grep, find, ls
|
|
194
201
|
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
|
|
195
202
|
--hook <path> Load a hook/extension file (can be used multiple times)
|
|
196
203
|
--extension, -e <path> Load an extension file (can be used multiple times)
|
|
204
|
+
--no-extensions Disable extension discovery (explicit -e paths still work)
|
|
197
205
|
--no-skills Disable skills discovery and loading
|
|
198
206
|
--skills <patterns> Comma-separated glob patterns to filter skills (e.g., git-*,docker)
|
|
199
207
|
--export <file> Export session file to HTML and exit
|
package/src/config.ts
CHANGED
|
@@ -45,21 +45,6 @@ export function getPackageDir(): string {
|
|
|
45
45
|
return process.cwd();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/** Get path to README.md (optional, may not exist in binary) */
|
|
49
|
-
export function getReadmePath(): string {
|
|
50
|
-
return resolve(join(getPackageDir(), "README.md"));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Get path to docs directory (optional, may not exist in binary) */
|
|
54
|
-
export function getDocsPath(): string {
|
|
55
|
-
return resolve(join(getPackageDir(), "docs"));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Get path to examples directory (optional, may not exist in binary) */
|
|
59
|
-
export function getExamplesPath(): string {
|
|
60
|
-
return resolve(join(getPackageDir(), "examples"));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
48
|
/** Get path to CHANGELOG.md (optional, may not exist in binary) */
|
|
64
49
|
export function getChangelogPath(): string {
|
|
65
50
|
return resolve(join(getPackageDir(), "CHANGELOG.md"));
|
|
@@ -99,6 +84,11 @@ export function getToolsDir(): string {
|
|
|
99
84
|
return join(getAgentDir(), "tools");
|
|
100
85
|
}
|
|
101
86
|
|
|
87
|
+
/** Get path to managed binaries directory (fd, rg) */
|
|
88
|
+
export function getBinDir(): string {
|
|
89
|
+
return join(getAgentDir(), "bin");
|
|
90
|
+
}
|
|
91
|
+
|
|
102
92
|
/** Get path to slash commands directory */
|
|
103
93
|
export function getCommandsDir(): string {
|
|
104
94
|
return join(getAgentDir(), "commands");
|