- Reduce from 1840 to 817 lines (55% smaller)
- Move all scattered example references to Examples Reference table at end
- Add missing setHeader() API documentation
- Add all 50 examples organized by category (Tools, Commands, Events, UI, etc.)
- Fix tui.md hooks->extensions terminology
- Add resetApiProviders() to clear and re-register built-in providers
- Add createAssistantMessageEventStream() factory for extensions
- Add streamSimple support in ProviderConfig for custom API implementations
- Call resetApiProviders() on /reload to clean up extension providers
- Add custom-provider.md documentation
- Add custom-provider.ts example with full Anthropic implementation
- Update extensions.md with streamSimple config option
- Package deduplication: same package in global+project, project wins
- Collision detection for skills, prompts, and themes with ResourceCollision type
- PathMetadata tracking with parent directory lookup for file paths
- Display improvements: section headers, sorted groups, accent colors for packages
- pi list shows full paths below package names
- Extension loader discovers files in directories without index.ts
- In-memory SettingsManager properly tracks project settings
fixes#645
- 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
- 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
- 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
- Skill commands (/skill:name) now expanded in AgentSession instead of
interactive mode, enabling them in RPC and print modes
- Input event can now intercept /skill:name before expansion
- Updated extensions.md with clearer input event docs and processing order
- Updated rpc.md: hook -> extension terminology, added skill expansion mentions
- Added PR attribution to changelog entries for #761
* feat(coding-agent): add input event for extension input interception
Extensions can now intercept, transform, or handle user input before the
agent processes it. Three result types: continue (pass through), transform
(modify text/images), handled (respond without LLM). Handlers chain
transforms and short-circuit on handled. Source field identifies origin.
* fix: make source public, use if/else over ternary
* fix: remove response field, extension handles own UI
* feat: add summarize extension example
Demonstrates custom UI with markdown rendering and external model
integration for conversation summarization.
* chore: update examples/extensions/README.md with summarize.ts
Breaking change: pi.getAllTools() now returns Array<{ name, description }>
instead of string[]. Extensions needing just names can use .map(t => t.name).
Removes redundant getToolInfo() method added in original PR.
Fixes#647
- 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
Fires when the model changes via /model command, model cycling (Ctrl+P),
or session restore. Includes source field and previousModel.
Add model-status.ts example extension demonstrating status bar updates.
closes#628
Demonstrates running interactive commands (vim, git rebase, htop, etc.)
with full terminal access using user_bash event and ctx.ui.custom().
- Auto-detects interactive commands from built-in list
- !i prefix to force interactive mode
- Configurable via INTERACTIVE_COMMANDS/INTERACTIVE_EXCLUDE env vars
closes#532
- user_bash event for intercepting ! and !! commands (#528)
- Extensions can return { operations } or { result } to redirect/replace
- executeBashWithOperations() for custom BashOperations execution
- session.recordBashResult() for extensions handling bash themselves
- Theme API: getAllThemes(), getTheme(), setTheme() on ctx.ui
- mac-system-theme.ts example: sync with macOS dark/light mode
- Updated ssh.ts to use user_bash event
- Add systemPrompt to BeforeAgentStartEvent so extensions can see current prompt
- Change systemPromptAppend to systemPrompt in BeforeAgentStartEventResult for full replacement
- Extensions can now chain modifications (each sees the result of previous)
- Update ssh.ts to replace local cwd with remote cwd in system prompt
- Update pirate.ts, claude-rules.ts, preset.ts to use new API
fixes#575
When overriding a built-in tool (read, bash, edit, write, grep, find, ls)
without providing renderCall/renderResult, the built-in renderer is now
used automatically. This allows wrapping built-in tools for logging or
access control without reimplementing the UI (syntax highlighting, diffs, etc.).
- Add setActiveTools() to ExtensionAPI for dynamic tool management
- Extensions can now override, wrap, or disable built-in tools
- Add tool-override.ts example demonstrating the pattern
- Update documentation for tool override capabilities
- Replace per-extension closures with shared ExtensionRuntime
- Split context actions: ExtensionContextActions (required) + ExtensionCommandContextActions (optional)
- Rename LoadedExtension to Extension, remove setter methods
- Change runner.initialize() from options object to positional params
- Derive hasUI from uiContext presence (no separate param)
- Add warning when extensions override built-in tools
- RPC and print modes now provide full command context actions
BREAKING CHANGE: Extension system types and initialization API changed.
See CHANGELOG.md for migration details.
Extension UI dialogs (select, confirm, input) now support a timeout option
that auto-dismisses with a live countdown display. Simpler alternative to
manually managing AbortSignal for timed dialogs.
Also adds ExtensionUIDialogOptions type export and updates RPC mode to
forward timeout to clients.