getResolvedThemeColors and getThemeExportColors now fall back to
currentThemeName before getDefaultTheme(), so exports respect the
user's selected theme.
Add markdown.codeBlockIndent setting to customize indentation prefix for
rendered code blocks. Default remains 2 spaces for visual clarity, but
setting to empty string removes indentation for easier copy/paste of
code snippets to scripts, editors, or other tools.
Changes:
- tui: add optional codeBlockIndent to MarkdownTheme interface
- coding-agent: add MarkdownSettings with codeBlockIndent property
- coding-agent: compose theme with settings at call sites (no global state)
- coding-agent: update message components to accept optional MarkdownTheme
Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
Fixes OpenAI Responses 400 error 'reasoning without following item' by
skipping errored/aborted assistant messages entirely rather than filtering
at the provider level. This covers openai-responses, openai-codex-responses,
and future providers.
Removes strictResponsesPairing compat option (no longer needed).
Closes#838
Split OpenAICompat into OpenAICompletionsCompat and OpenAIResponsesCompat
for type-safe API-specific compat settings. Added strictResponsesPairing
option to suppress orphaned reasoning/tool calls on incomplete turns,
fixing 400 errors on Azure's Responses API which requires strict pairing.
Closes#768
* Support shell command execution for API key resolution in models.json
Add ! prefix support to apiKey field in models.json to execute shell commands
and use stdout as the API key. This allows users to store API keys in secure
credential managers like macOS Keychain, 1Password, Bitwarden, or HashiCorp Vault.
Example: "apiKey": "!security find-generic-password -ws 'anthropic'"
The apiKey field now supports three formats:
- !command - executes shell command, uses trimmed stdout
- ENV_VAR_NAME - uses environment variable value
- literal - uses value directly
fixes#697
* feat(coding-agent): cache API key command results for process lifetime
Shell commands (! prefix) are now executed once and cached. Environment
variables and literal values are not cached, so changes are picked up.
Addresses review feedback on #762.
---------
Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
Components with search inputs now implement Focusable interface and
propagate focus state to their child Input components. This allows
the hardware cursor to be positioned correctly for IME candidate
window placement.
Affected components:
- ModelSelectorComponent
- ScopedModelsSelectorComponent
- SessionSelectorComponent (and SessionList)
- ExtensionInputComponent
- LoginDialogComponent
- TreeSelectorComponent (and LabelInput)
fixes#827
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.
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
The Editor component now accepts TUI as the first constructor parameter,
enabling it to query terminal dimensions. When content exceeds available
height, the editor scrolls vertically keeping the cursor visible.
Features:
- Max editor height is 30% of terminal rows (minimum 5 lines)
- Page Up/Down keys scroll by page size
- Scroll indicators show lines above/below: ─── ↑ 5 more ───
Breaking change: Editor constructor signature changed from
new Editor(theme)
to
new Editor(tui, theme)
fixes#732
When stdin is piped (not a TTY), read the content and treat it as the
first message. Since interactive mode requires a TTY for keyboard input,
print mode is automatically enabled.
- echo foo | pi -> equivalent to pi -p foo
- echo foo | pi -p -> equivalent to pi -p foo
- RPC mode unaffected (uses stdin for JSON-RPC)
fixes#708