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
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
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
Implements support for ${@:N} and ${@:N:L} syntax to slice argument arrays
in prompt templates, following bash conventions.
Syntax:
- ${@:N} - All arguments from Nth position onwards (1-indexed)
- ${@:N:L} - L arguments starting from Nth position
Features:
- Bash-style slicing familiar to shell users
- 1-indexed for consistency with $1, $2, etc.
- Processes before simple $@ to avoid conflicts
- No recursive substitution of patterns in arguments
- Comprehensive edge case handling
Examples:
- ${@:2} with ["a", "b", "c"] -> "b c"
- ${@:2:1} with ["a", "b", "c"] -> "b"
- ${@:99} with ["a", "b"] -> "" (empty, out of range)
Test coverage: 24 new tests, all passing (73 total)
Closes#769
- Add Focusable interface for components that need hardware cursor positioning
- Add CURSOR_MARKER (APC escape sequence) for marking cursor position in render output
- Editor and Input components implement Focusable and emit marker when focused
- TUI extracts cursor position from rendered output and positions hardware cursor
- Track hardwareCursorRow separately from cursorRow for differential rendering
- visibleWidth() and extractAnsiCode() now handle APC sequences
- Update overlay-test.ts example to demonstrate Focusable usage
- Add documentation for Focusable interface in docs/tui.md
Closes#719, closes#525