Replace build-time shell utilities with Node filesystem operations and retire the native sandbox example in favor of existing isolation options. Upgrade glob matching and worker-test dependencies and refresh the lockfiles.
This adds experimental support for virtual models. A virtual model is a catalog entry that an extension registers with pi.registerVirtualModel(). It does not talk to a provider itself; for every request it picks a physical model and thinking level. The motivation is to make routing policies pluggable: plan on a strong model and implement on a cheap one, pick a model with a classifier, or move to a larger window when the context grows. Today this needs model switching by hand or hacks in prepareRequest.
The selection stays virtual: model_change records it, resume restores it, and each response records the physical model and thinking level that produced it. Router state can be stored on the session branch, so it follows /tree and forks and survives compaction. Context limits, compaction and image sizing use the physical model a request was routed to. examples/extensions/jev-router.ts shows a full router that uses the Jev classifier to pick Sol or Terra for planning and hands off to Luna after the first edit. docs/virtual-models.md describes the API.
This change makes system prompt text and tool changes part of the transcript rather than silently rewriting its starting conditions. This lets Pi record when instructions changed or tools became available, restore that state after resuming or navigating branches, and preserve cached prompt prefixes where the upstream supports it.
* feat(agent,coding-agent): add per-tool executionMode field to AgentTool and ToolDefinition
Add optional executionMode?: ToolExecutionMode to AgentTool and
ToolDefinition interfaces. Propagate through wrapToolDefinition and
createToolDefinitionFromAgentTool. No behavioral change yet — agent
loop will read this field in a follow-up.
* feat(agent): support per-tool executionMode override for sequential execution
When a tool defines executionMode='sequential', the agent loop
forces sequential execution of all tool calls in that batch,
even if the global config is parallel.
* feat(coding-agent): re-export ToolExecutionMode from @mariozechner/pi-agent-core
Makes the type available to extensions that want to set
executionMode on tool definitions.
* feat(coding-agent): add tic-tac-toe extension example with executionMode: sequential
Demonstrates per-tool executionMode: the agent plays via move/play
tool calls that share a cursor. Without sequential execution, play
can resolve before earlier moves finish, landing on the wrong cell.
Adds a new extension that generates images via Google Antigravity's
image models (gemini-3-pro-image, imagen-3). Features:
- Returns images as tool result attachments for inline terminal rendering
- Configurable save modes: none, project, global, custom
- Supports env vars (PI_IMAGE_SAVE_MODE, PI_IMAGE_SAVE_DIR) and config files
- Configurable aspect ratios (1:1, 16:9, etc.)
Requires OAuth login via /login for google-antigravity provider.
* feat(extensions): add inline-bash example for expanding !{command} in prompts
Adds an example extension that expands inline bash commands within user
prompts before sending to the agent. Uses the `input` event to transform
patterns like `!{pwd}` or `!{git status}` into their output.
Preserves existing `!command` whole-line bash behavior.
* docs(extensions): add inline-bash to README
* chore: fix stupid bug
* 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
Add OverlayOptions for configurable positioning (anchor, margins, offsets,
percentages). Add OverlayHandle for programmatic visibility control with
hide/setHidden/isHidden. Add visible callback for responsive overlays.
Extension API: ctx.ui.custom() now accepts overlayOptions and onHandle callback.
Examples: overlay-qa-tests.ts (10 test commands), doom-overlay (DOOM at 35 FPS).
Uses @anthropic-ai/sandbox-runtime to enforce filesystem and network
restrictions on bash commands (sandbox-exec on macOS, bubblewrap on Linux).
Features:
- Per-project config via .pi/sandbox.json
- Global config via ~/.pi/agent/sandbox.json
- Enabled by default with sensible defaults
- --no-sandbox flag to disable
- /sandbox command to view current config
- 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
- ExtensionAPI: setModel(), getThinkingLevel(), setThinkingLevel() methods
- New preset.ts example with plan/implement presets for model/thinking/tools switching
- Export all UI components from pi-coding-agent for extension use
- docs/tui.md: Common Patterns section with copy-paste code for SelectList, BorderedLoader, SettingsList, setStatus, setWidget, setFooter
- docs/tui.md: Key Rules section for extension UI development
- docs/extensions.md: Exhaustive example links for all ExtensionAPI methods and events
- System prompt now references docs/tui.md for TUI development
Fixes#509, relates to #347
Adds sendUserMessage() to the extension API, allowing extensions to send
actual user messages (role: user) rather than custom messages. Unlike
sendMessage(), this always triggers a turn and behaves as if the user
typed the message.
- Add SendUserMessageHandler type and sendUserMessage() to ExtensionAPI
- Wire handler through loader, runner, and all modes
- Implement via prompt() with expandPromptTemplates: false
- Add send-user-message.ts example with /ask, /steer, /followup commands
- Document in extensions.md
fixes#483