Adds deleteWordForward action bound to Alt+D, which deletes from cursor
to the end of the current word and saves to kill ring for later yanking.
Consecutive forward kills append to the same kill ring entry.
Add kill ring functionality with:
- Ctrl+W/U/K save deleted text to kill ring
- Ctrl+Y yanks (pastes) most recent deletion
- Alt+Y cycles through kill ring (after Ctrl+Y)
- Consecutive deletions accumulate into single entry
In legacy terminal mode (non-Kitty protocol), Alt+key is sent as ESC
followed by the key character. This was only supported for specific keys
(space, backspace, arrows) but not for regular letters.
Add support for Alt+letter sequences to enable keybindings like Alt+Y.
- Replace hardcoded pi->CC tool mappings with single CC tool name list
- Case-insensitive lookup: if tool name matches CC tool, use CC casing
- Remove broken find->Glob mapping (round-trip failed)
- Add test coverage for tool name normalization
When an assistant message has stopReason 'error', its tool calls are now
excluded from pending tool tracking. This prevents synthetic tool results
from being generated for calls that will be dropped by provider-specific
converters (e.g., Codex drops tool calls from errored messages).
Previously, this mismatch caused OpenAI to reject requests with 'No tool
call found for function call output with call_id ...' errors.
fixes#812
Bedrock Claude models require max_tokens to exceed thinking.budget_tokens.
This constraint was handled for anthropic-messages API but missing for
bedrock-converse-stream, causing compaction failures.
Extracted adjustMaxTokensForThinking() helper that:
- Adds thinking budget on top of desired output tokens
- Reduces thinking budget if insufficient room (min 1024 output tokens)
- Applied to both anthropic-messages and bedrock-converse-stream APIs
Instead of skipping unsigned tool calls entirely (which lobotomizes context),
convert them to text with an explicit note telling the model this is historical
context from a different model and not a format to mimic.
This preserves tool call/result context when switching from providers without
thought signatures (e.g. Claude via Antigravity) to Gemini 3.
When auto-compaction fails (e.g., quota exceeded), emit the error via
the auto_compaction_end event instead of throwing. The UI now displays
the error message, allowing users to take action (switch models, wait
for quota reset, etc.) instead of crashing.
fixes#792
Multiple agents may work on different files in the same worktree.
Added rules to prevent agents from accidentally committing or
destroying each other's work.
When 429/500 errors occur during tool execution, empty assistant messages
with stopReason='error' get persisted. These break the tool_use -> tool_result
chain for Claude/Gemini APIs.
Added centralized filtering in transformMessages to skip assistant messages
with empty content and no tool calls. Provider-level filters remain for
defense-in-depth.
* feat(coding-agent): add startup.quiet setting to silence startup output
* feat(coding-agent): add startup.quiet setting to silence startup output
Adds a new setting `startup.quiet` that when set to `true` hides:
- Version and keybinding hints header
- Loaded context/skills/templates/extensions discovery info
- Model scope line
Changelog notifications are still shown so users know about updates.
Usage in ~/.pi/agent/settings.json:
{
"startup": {
"quiet": true
}
}
* refactor: flatten startup.quiet to quietStartup on Settings
When --no-extensions was used, extensionsResult.extensions was an empty
array. The condition in buildSessionOptions() checked .length > 0,
so preloadedExtensions was not set. This caused createAgentSession()
to fall through to extension discovery.
Remove the .length > 0 condition so the empty result is passed through,
signaling that extension loading was already handled.
Fixes#776
- Update ExtensionCommandContext.navigateTree type signature
- Pass new options through in print-mode and rpc-mode handlers
- Update docs/extensions.md, docs/sdk.md, docs/tree.md
- Add changelog entry
Previous commit broke Node.js/tsx by using the ESM entry point which
doesn't work with Node. This creates a wrapper module that:
- Uses require() for lazy loading (works in both Node and Bun)
- Gracefully handles load failures (returns original image)
- Works in Node.js, tsx, and Bun compiled binaries
- Import photon-node from ESM entry point (photon_rs_bg.js) instead of CJS
entry, allowing Bun to embed WASM in compiled binaries
- Add photon.d.ts for TypeScript support of ESM entry
- Add scripts/build-binaries.sh for local binary builds
- Simplify GitHub workflow to use the build script
- Add binaries/ to gitignore
When using `--session <UUID>`, the session lookup now:
1. Searches locally first (current project's session directory)
2. Falls back to global search across all projects
3. If found in different project, prompts user to fork the session
4. If not found anywhere, shows clear error instead of silently creating
a broken session with malformed path
Adds `SessionManager.forkFrom()` to create a forked session from another
project, preserving full conversation history with updated cwd.
Fixes cursor visibility issues in JetBrains IDE terminals (IntelliJ, PyCharm) where
the hardware cursor either blinks or becomes invisible depending on settings.
Fixes#771
Previously, OpenAI-compatible provider settings (like developer role support)
were detected only from the baseUrl. When using custom URLs (e.g., proxies),
detection failed. Now checks model.provider first, then falls back to URL.
Fixes#774