- Add PackageSource type for npm/git sources with optional filtering
- Migrate npm:/git: sources from extensions to packages array
- Add getPackages(), setPackages(), setProjectPackages() methods
- Update package-manager to resolve from packages array
- Support selective loading: extensions, skills, prompts, themes per package
- Update pi list to show packages
- Add migration tests for settings
closes#645
Header values in models.json now resolve using the same logic as apiKey:
- Environment variable names are resolved to their values
- Shell commands prefixed with ! are executed
- Literal values are used directly
This is a minor breaking change: if a header value accidentally matches
an env var name, it will now resolve to that env var's value.
Fixes#909
- Add ResourceLoader interface and DefaultResourceLoader implementation
- Add PackageManager for npm/git extension sources with install/remove/update
- Add session.reload() and session.bindExtensions() APIs
- Add /reload command in interactive mode
- Add CLI flags: --skill, --theme, --prompt-template, --no-themes, --no-prompt-templates
- Add pi install/remove/update commands for extension management
- Refactor settings.json to use arrays for skills, prompts, themes
- Remove legacy SkillsSettings source flags and filters
- Update SDK examples and documentation for ResourceLoader pattern
- Add theme registration and loadThemeFromPath for dynamic themes
- Add getShellEnv to include bin dir in PATH for bash commands
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
Undo snapshots are captured for all edit operations:
- Word insertion, backspace, forward delete
- Word/line deletion (Ctrl+W, Ctrl+U, Ctrl+K, Alt+D)
- Yank/yank-pop, paste, autocomplete completion
- Cursor movement starts a new undo unit
- setText() pushes snapshot when content changes
Additionally, history browsing captures the undo state on first entry.
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>
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.
Fixes cursor visibility issues in JetBrains IDE terminals (IntelliJ, PyCharm) where
the hardware cursor either blinks or becomes invisible depending on settings.
Fixes#771
- Add minimax to KnownProvider and Api types
- Add MINIMAX_API_KEY to getEnvApiKey()
- Generate MiniMax-M2 and MiniMax-M2.1 models
- Add context overflow detection pattern
- Add tests to all required test files
- Update README and CHANGELOG with attribution
Also fixes:
- Bedrock duplicate toolResult ID when content has multiple blocks
- Sandbox extension unused parameter lint warning
Adds support for Amazon Bedrock with Claude models including:
- Full streaming support via Converse API
- Reasoning/thinking support for Claude models
- Cross-region inference model ID handling
- Multiple AWS credential sources (profile, IAM keys, API keys)
- Image support in messages and tool results
- Unicode surrogate sanitization
Also adds 'Adding a New Provider' documentation to AGENTS.md and README.
Co-authored-by: nickchan2 <nickchan2@users.noreply.github.com>
- Add SessionInfoEntry type for session metadata
- Add /name <name> command to set session display name
- Add pi.setSessionName() and pi.getSessionName() extension API
- Session selector shows name (in warning color) instead of first message when set
- Session name included in fuzzy search
- /session command displays name when set
closes#650
- Renamed from /models to /scoped-models
- Changes are now session-only by default (Ctrl+S to persist to settings)
- Added search with fuzzy filtering
- Hotkeys: Enter toggle, Ctrl+A enable all, Ctrl+X clear all, Ctrl+P toggle provider
- Ctrl+C clears search (or exits if empty), Escape exits
- Enabled models shown at top of list
- No checkmarks when all models enabled (no scope)
- First toggle when unscoped clears all and selects that model
- Uses current session thinking level instead of settings default
- Reads from session state first (preserves session-only changes across /scoped-models invocations)
Builds on #626
- /resume and --resume now toggle between Current Folder and All sessions with Tab
- SessionManager.list() and listAll() are now async with optional progress callback
- Shows loading progress (e.g. Loading 5/42) while scanning sessions
- SessionInfo.cwd field shows session working directory in All view
- Lazy loading: All sessions only loaded when user presses Tab
closes#619
Co-authored-by: Thomas Mustier <mustierthomas@gmail.com>
- New /models command with toggle UI for each available model
- Changes persist to enabledModels in settings.json
- Updates take effect immediately for Ctrl+P cycling
The problem: I wanted to be able to select my session (either from
`/resume` or `--resume`) with different keybindings.
The issue: when running `pi --resume`, custom keybindings from
`~/.pi/agent/keybindings.json` were not being applied to the session
picker. This happened because `KeybindingsManager.create()` was only
called when `InteractiveMode` initialized, but the session picker runs
before that in `main.ts`.
The session picker uses `getEditorKeybindings()` for navigation
(selectUp/selectDown etc.), which returns the global default keybindings
if `setEditorKeybindings()` hasn't been called yet.
Fix: Call `KeybindingsManager.create()` inside the `--resume` block
before showing the session picker. This loads user keybindings and sets
them globally.
The current fix results in double-init of keybindings when entering
interactive mode which _should_ be harmless, since it's the same same
config loaded twice, but is minimal and only affects the `--resume`
path.
I considered passing keybindings from `main()` to `InteractiveMode` -
it's cleaner but requires API changes.
Also documented the `select*` keybindings in README.md.
- Skills registered as /skill:name commands for quick access
- Toggle via /settings or skills.enableSkillCommands in settings.json
- Fuzzy matching for all slash command autocomplete (type /skbra for /skill:brave-search)
- Moved fuzzy module from coding-agent to tui package for reuse
Closes#630 by @Dwsy (reimplemented with fixes)