- Show ├─ for non-last siblings, └─ for last sibling
- Show │ gutter for descendants of non-last siblings
- Properly handle multiple roots display shift
- At indent 0: stay flat unless parent branches
- At indent 1: children go to indent 2 (visual grouping)
- At indent 2+: stay flat for single-child chains
- Remove gutter/connector complexity for now
- Only indent when parent has siblings (branch point)
- gutterLevels array tracks which levels need │ vs spaces
- connector: none/branch/last for ├─/└─ display
- Tool results show formatted call info like [read: path:1-10], [bash: cmd]
- Skip assistant messages with stopReason error/aborted
- Skip assistant messages with only tool calls (no text)
- Format built-in tools like tool-execution.ts (read, write, edit, bash, grep, find, ls)
- Custom tools show truncated JSON args
- Label editing with 'l' key
- Ctrl+O cycles through filters: default -> user-only -> labeled-only -> all
- Preserve cursor position when toggling filters
- Labels shown at front of node
- Normalize tabs/newlines in content
- extractContent limited to 200 chars for performance
- truncateToWidth on all rendered lines
- Iterative flattenTree to avoid stack overflow
- Linear chain optimization (no indent for single-child chains)
- Add TreeSelectorComponent with ASCII tree visualization
- Add AgentSession.navigateTree() for switching branches
- Add session_before_tree/session_tree hook events
- Add SessionManager.resetLeaf() for navigating to root
- Change leafId from string to string|null for consistency with parentId
- Support optional branch summarization when switching
- Update buildSessionContext() to handle null leafId
- Add /tree to slash commands in interactive mode
Major changes:
- Replace monolithic SessionEvent with reason discriminator with individual
event types: session_start, session_before_switch, session_switch,
session_before_new, session_new, session_before_branch, session_branch,
session_before_compact, session_compact, session_shutdown
- Each event has dedicated result type (SessionBeforeSwitchResult, etc.)
- HookHandler type now allows bare return statements (void in return type)
- HookAPI.on() has proper overloads for each event with correct typing
Additional fixes:
- AgentSession now always subscribes to agent in constructor (was only
subscribing when external subscribe() called, breaking internal handlers)
- Standardize on undefined over null throughout codebase
- HookUIContext methods return undefined instead of null
- SessionManager methods return undefined instead of null
- Simplify hook exports to 'export type * from types.js'
- Add detailed JSDoc for skipConversationRestore vs cancel
- Fix createBranchedSession to rebuild index in persist mode
- newSession() now returns the session file path
Updated all example hooks, tests, and emission sites to use new event types.
When custom renderer returns a component with its own background,
don't wrap it in another background box. The nested bg resets
were causing padding to lose its background color.
- agentLoop now accepts AgentMessage[] instead of single message
- agent.prompt() accepts AgentMessage | AgentMessage[]
- Emits message_start/end for each message in the array
- AgentSession.prompt() builds array with hook message + user message
- TUI now receives events for before_agent_start injected messages
Hook commands now always execute immediately, even during streaming.
If a command needs to interact with the LLM, it uses pi.sendMessage()
which handles queueing automatically.
This simplifies the API and eliminates the issue of queued slash
commands being sent to the LLM instead of executing.
- Add BeforeAgentStartEvent and BeforeAgentStartEventResult types
- Add emitBeforeAgentStart to HookRunner
- Call in AgentSession.prompt() before agent.prompt()
- Hook can return a message to inject into context (persisted + visible)
- Add test hook demonstrating custom message rendering and before_agent_start
- CompactionSummaryMessageComponent now extends Box, uses customMessageBg
- New BranchSummaryMessageComponent for branch summaries
- Both use same background color as HookMessageComponent for consistency
- Added Spacer before compaction/branch components in chat
- addMessageToChat: exhaustive switch for all AgentMessage roles
- renderSessionContext: delegates to addMessageToChat, special handling for assistant tool calls and tool results
- export-html formatMessage: exhaustive switch for all AgentMessage roles
- Removed isHookMessage, isBashExecutionMessage type guards in favor of role checks
- Fixed imports and removed unused getLatestCompactionEntry
Two bugs:
1. createCustomMessage was returning role: 'user' instead of preserving
the hook message structure (role: 'hookMessage', customType, etc.)
2. rebuildChatFromMessages wasn't clearing the container before rebuilding
Usage: npm run release:patch|minor|major
Automates:
- Check for uncommitted changes
- Bump version
- Update CHANGELOGs: [Unreleased] -> [version] - date
- Commit and tag
- Publish to npm
- Add new [Unreleased] sections
- Push
- StreamFn type now allows returning Promise
- agent-loop awaits streamFn result
- createStreamFn takes getProxyUrl callback, reads settings on each call
- createStreamFn(proxyUrl?) returns a sync streamFn that applies proxy
- Example reads proxy settings once when creating Agent
- Matches old ProviderTransport behavior