- Add ~/.pi/agent/models.json config for custom providers (Ollama, vLLM, etc.)
- Support all 4 API types (openai-completions, openai-responses, anthropic-messages, google-generative-ai)
- Live reload models.json on /model selector open
- Smart model defaults per provider (claude-sonnet-4-5, gpt-5.1-codex, etc.)
- Graceful session fallback when saved model missing or no API key
- Validation errors show precise file/field info in CLI and TUI
- Agent knows its own README.md path for self-documentation
- Added gpt-5.1-codex (400k context, 128k output, reasoning)
Fixes#21
- Model selector now only shows models with configured API keys
- Added yellow hint in model selector UI explaining the filtering
- Updated README.md to document the filtering behavior in both API Keys and /model sections
- Bumped version to 0.7.11
- Add /branch slash command to create conversation branches
- New UserMessageSelectorComponent shows all user messages chronologically
- Selecting a message creates new session with messages before selection
- Selected message is placed in editor for modification/resubmission
- SessionManager.createBranchedSession() creates new session files
- Updated README.md and CHANGELOG.md with /branch documentation
- Sync all packages to version 0.7.7
- Rewrite sync-versions.js to handle ALL inter-package dependencies automatically
- Fix web-ui dependency on pi-ai (was 0.6.0, now 0.7.7)
- Move agent fix changelog entry to coding-agent CHANGELOG
- Remove redundant agent CHANGELOG.md
- Improve README.md with clearer lockstep versioning docs
- Add /changelog command to display full changelog in TUI (newest last)
- Fix changelog description (not a scrollable viewer, just displays in chat)
- Update CHANGELOG for 0.7.7 release
- BREAKING: Renamed AGENT.md to AGENTS.md for project context files
- Added automatic changelog viewer on startup for new sessions
- Added settings manager to track last shown changelog version
- BREAKING: Store provider and modelId separately in session files (fixes#4)
- Fixed markdown list rendering when items contain inline code with cyan formatting
- Added dynamic border component for TUI
- Updated changelog with entries for #4 and #5
- Remove statusContainer.clear() from clearEditor()
- Loading animation should only be removed when agent finishes
- Ctrl+C once should only clear editor text, not status
- Add generateDiffString() function in edit tool to create unified diffs with line numbers and 4 lines of context
- Store only the formatted diff string in tool result details instead of full file contents
- Update tool-execution renderer to parse and colorize the diff string
- Filter out message_update events from session saving to prevent verbose session files
- Add markdown nested list and table rendering tests
Changed export success/error messages to match the style used for thinking level changes:
- Use Spacer(1) instead of empty Text for proper blank line spacing
- Use chalk.dim() for success message instead of chalk.green()
- Add left padding (1, 0) to match other system messages
- Removed checkmark/x symbols for cleaner look
Now "Session exported to: filename.html" appears dimmed with proper spacing, just like "Thinking level: off"
- Add exportSessionToHtml function that generates beautifully formatted HTML exports
- HTML includes session metadata, all messages, tool calls, tool results, thinking blocks, and images
- Support for ANSI color codes in tool output (converted to HTML)
- Self-contained with inline CSS (dark theme, responsive design, print-friendly)
- Add /export slash command to TUI with optional filename parameter
- Add agent and coding-agent to dev script for watch mode
- Increment coding-agent version to 0.6.1
Usage: /export [optional-filename.html]
Tool results now use content blocks and can include both text and images.
All providers (Anthropic, Google, OpenAI Completions, OpenAI Responses)
correctly pass images from tool results to LLMs.
- Update ToolResultMessage type to use content blocks
- Add placeholder text for image-only tool results in Google/Anthropic
- OpenAI providers send tool result + follow-up user message with images
- Fix Anthropic JSON parsing for empty tool arguments
- Add comprehensive tests for image-only and text+image tool results
- Update README with tool result content blocks API
- SessionManager now collects text from all user and assistant messages
- Added allMessagesText field containing concatenated message text
- Search now matches against all messages in a session
- More powerful session discovery (e.g., search "write file" finds any session discussing file writing)
- Add search input at top - filters sessions as you type
- Add scrolling with max 5 visible sessions at a time
- Add scroll indicator showing position (e.g., (3/15))
- Add blank line spacing between session items
- Ctrl+C now exits process (process.exit(0)) instead of canceling
- Escape still cancels and returns to main menu
- Enter in search box selects current session
- Custom SessionList component with 2 lines per item
- First line: message text (bold when selected)
- Second line: metadata (time · message count) in dim
- Blue › cursor for selected item
- Added "Resume Session" header
- Handle Ctrl+C (‹x03›) in SelectList for consistency
- Improved date formatting (38 minutes ago, 8 hours ago, etc.)
- Add SIGINT handler to allow Ctrl+C to exit during session selection
- Remove hardcoded 60-char truncation, let SelectList handle dynamic truncation
- Simplify date format (5m, 2h, 3d instead of "5m ago")
- Make metadata more compact (5msg instead of "5 msgs")
- New SessionSelectorComponent to browse and select sessions
- Lists sessions sorted by last modified date
- Shows first message, created/modified dates, message count
- Automatically truncates long messages and formats dates
- Adds --resume/-r flag to CLI
- Session selector integrates with main flow
Session manager changes:
- Add ThinkingLevelChangeEntry and ModelChangeEntry types
- Add saveThinkingLevelChange() and saveModelChange() methods
- Update loadThinkingLevel() to also check for thinking_level_change events
(not just session headers)
TUI changes:
- Pass SessionManager to TuiRenderer constructor
- Call saveThinkingLevelChange() when user changes thinking level via /thinking
- Store session manager as instance variable for future use
This ensures thinking level changes during a session are persisted
and correctly restored on --continue.
Thinking selector fix:
- Replace hardcoded 50-character borders with DynamicBorder component
that adjusts to viewport width
- Prevents crash when terminal is resized narrow
Text/Markdown rendering fixes:
- Fix Markdown wrapSingleLine to check if adding next character would
exceed width BEFORE adding it (was checking AFTER, causing lines to
be 1 character too long)
- Add word truncation in Text component for words longer than
contentWidth (prevents long unbreakable words from exceeding width)
These fixes prevent "Rendered line exceeds terminal width" errors.
Update streaming component with final message in message_end event.
The final message includes the stopReason, which allows the component
to render "Aborted" text for aborted text generation.
Now behavior is consistent:
- Abort during text generation (no tool calls) → shows red "Aborted"
- Abort during tool call streaming → tool components turn red
Two fixes for rendering aborted tools in --continue mode:
1. In renderInitialMessages: Check if assistant message was aborted/errored
and immediately mark tool execution components as failed instead of
leaving them in pending state.
2. In AssistantMessageComponent: Don't show "Aborted" text when there are
tool calls in the message, since the tool execution components will
show the error state themselves. This prevents duplicate error messages.
Now aborted tools show properly as red with "Operation aborted" message,
without the duplicate "Aborted" text above them.
When user presses Esc during tool argument streaming, the assistant
message ends with stopReason="aborted" but tool execution never starts.
Now we check for aborted/error stopReasons in message_end and update
all pending tool execution components to show red error state with
"Operation aborted" message.
This fixes the issue where tool components stayed stuck in blue/pending
state after aborting during JSON streaming.
Replace tabs with 3 spaces for consistent rendering and width calculation:
- Updated visibleWidth() to normalize tabs before measuring
- Updated Text and Markdown components to replace tabs when rendering
- Updated tool-execution display for read/write tools to replace tabs
This fixes background color rendering issues when displaying files with tab indentation.
- Save and restore thinking level when continuing sessions
- Fix thinking level confirmation message spacing and styling
- Fix thinking text wrapping to preserve ANSI formatting across lines
- Show tool execution components immediately when tool calls appear in streaming
- Update components with streaming arguments as they come in
- Handle incomplete/partial arguments gracefully with optional chaining
- Fix error handling: tools now throw exceptions instead of returning error messages
- Fix bash abort handling to properly reject on abort/timeout
- Clean up error display
- StreamingMessageComponent was just a wrapper around AssistantMessageComponent
- AssistantMessageComponent now handles its own stats rendering
- Made AssistantMessageComponent updatable with updateContent()
- Removed duplicate stats handling code from tui-renderer
- All stats are now managed by the component itself
- Create UserMessageComponent - handles user messages with spacing
- Create AssistantMessageComponent - handles complete assistant messages
- Create ThinkingSelectorComponent - wraps selector with borders
- Add setSelectedIndex to SelectList for preselecting current level
- Simplify tui-renderer by using dedicated components
- Much cleaner architecture - each message type is now a component