- Fix UTF-8 decoding with TextDecoder for base64 session data
- Use toolOutput color for expand hints (not borderAccent)
- Remove '- click to expand' text to match TUI
- Ctrl+O toggles expanded state (not visibility) on tool outputs
- Edit diffs always visible (not affected by Ctrl+O)
- Remove Ctrl+F override to allow browser search
- Replace tabs with 3 spaces in all tool outputs
- Fix syntax highlighting default color to use --text
- Add more hljs token selectors (property, punctuation, operator)
- Compaction uses customMessageBg/Label/Text colors
- Model change uses dim color without background
- Scroll to end on initial load
- Pointer cursor on expandable elements
- Display images from read tool results (base64 encoded)
- Add ellipsis for truncated tree entries
- Make mobile hamburger button more subtle
- Add X close button in sidebar header on mobile
- Hide hamburger when sidebar is open
- Add deriveExportColors() to compute page/card/info backgrounds from userMessageBg
- Use luminance detection to adapt colors for light/dark themes
- Use info-bg for model-change, compaction, system-prompt sections
- Use selectedBg for hover states and summary backgrounds
- Add scroll-to-message with highlight when clicking tree nodes
- Fix mobile overlay to close sidebar on click
- Wider sidebar (400px) with search and filter controls
- Add tree sidebar with search and filter (Default/All/Labels)
- Client-side markdown/syntax highlighting via vendored marked.js + highlight.js
- Base64 encode session data to avoid escaping issues
- Reuse theme.ts color tokens via getResolvedThemeColors()
- Sticky sidebar, responsive mobile layout with overlay
- Click tree node to scroll to message
- Keyboard shortcuts: Esc to reset, Ctrl/Cmd+F to search
Added glob pattern support (e.g., github-copilot/*, *sonnet*) to --models
and enabledModels. Patterns are matched against both provider/modelId and
just modelId, so *sonnet* works without requiring anthropic/*sonnet*.
The existing fuzzy substring matching for non-glob patterns is preserved.
fixes#337
- Add configurable thinkingText color for thinking blocks (defaults to muted)
- Make 'Thinking...' label italic when collapsed
- Fix Ctrl+T during streaming hiding the current message
- Track streamingMessage to properly re-render on toggle
Based on #366 by @paulbettner
- Add setEditorText() and getEditorText() to HookUIContext for prompt generator pattern
- custom() now accepts async factories for fire-and-forget work
- Add CancellableLoader component to tui package
- Add BorderedLoader component for hooks with cancel UI
- Export HookAPI, HookContext, HookFactory from main package
- Update all examples to import from packages instead of relative paths
- Update hooks.md and custom-tools.md documentation
fixes#350
When creating a new session, initial model and thinking level were set
on the agent but never saved to session file. This caused --resume to
default thinking level to 'off'.
fixes#342
- Remove timeout logic from HookRunner
- Remove hookTimeout from Settings interface
- Remove getHookTimeout/setHookTimeout methods
- Update CHANGELOG.md and hooks.md
Timeouts were inconsistently applied and caused issues with
legitimate slow operations (LLM calls, user prompts). Users can
use Ctrl+C to abort hung hooks.
- CustomAgentTool renamed to CustomTool
- ToolAPI renamed to CustomToolAPI
- ToolContext renamed to CustomToolContext
- ToolSessionEvent renamed to CustomToolSessionEvent
- Added CustomToolContext parameter to execute() and onSession()
- CustomToolFactory now returns CustomTool<any, any> for type compatibility
- dispose() replaced with onSession({ reason: 'shutdown' })
- Added wrapCustomTool() to convert CustomTool to AgentTool
- Session exposes setToolUIContext() instead of leaking internals
- Fix ToolExecutionComponent to sync with toolOutputExpanded state
- Update all custom tool examples for new API
Breaking change: CustomAgentTool.dispose() removed. Use onSession with
reason 'shutdown' instead for cleanup.
- Add 'shutdown' to SessionEvent.reason for custom tools
- Remove dispose() method from CustomAgentTool interface
- Make emitToolSessionEvent() public on AgentSession
- Emit shutdown event to tools in InteractiveMode.shutdown()
- Update custom-tools.md with new API and examples
Compaction API:
- prepareCompaction() now takes (pathEntries, settings) only
- CompactionPreparation restructured: removed cutPoint/messagesToKeep/boundaryStart, added turnPrefixMessages/isSplitTurn/previousSummary/fileOps/settings
- compact() now takes (preparation, model, apiKey, customInstructions?, signal?)
- Fixed token overflow by using getPath() instead of getEntries()
Hook types:
- HookEventContext renamed to HookContext
- HookCommandContext removed, RegisteredCommand.handler takes (args, ctx)
- HookContext now includes model field
- SessionBeforeCompactEvent: removed previousCompactions/model, added branchEntries
- SessionBeforeTreeEvent: removed model (use ctx.model)
- HookRunner.initialize() added for modes to set up callbacks
- Add selectedBg theme color for active line highlight
- Fix filter modes:
- no-tools: default minus tool results (still hides label/custom)
- user-only: just user messages
- labeled-only: just labeled entries
- all: everything
- Update theme.md with new color tokens (50 total)
- New utils.ts with shared functions:
- FileOperations type and createFileOps()
- extractFileOpsFromMessage()
- computeFileLists()
- formatFileOperations()
- serializeConversation()
- SUMMARIZATION_SYSTEM_PROMPT
- branch-summarization.ts now uses:
- Serialization approach (conversation as text, not LLM messages)
- completeSimple with system prompt
- Shared utility functions
- serializeConversation now takes Message[] (after convertToLlm)
- Handles all custom message types via convertToLlm
- Includes thinking blocks as [Assistant thinking]
- Removes truncation of tool args and results (already token-budgeted)
Instead of passing conversation as LLM messages (which makes the model
try to continue it), serialize to text wrapped in <conversation> tags.
- serializeConversation() formats messages as [User]/[Assistant]/[Tool result]
- Tool calls shown as function(args) format
- Tool results truncated to prevent bloat
- Conversation wrapped in <conversation> tags in the prompt
- SUMMARIZATION_SYSTEM_PROMPT explains the task clearly
- Tells model to NOT continue conversation, ONLY output summary
- Updated prompts to reference 'messages above' for clarity
- Pass systemPrompt to completeSimple
- CompactionDetails type with readFiles/modifiedFiles
- extractFileOperations collects from tool calls and previous compaction details
- UPDATE_SUMMARIZATION_PROMPT for merging with previous summary
- generateSummary now accepts previousSummary for iterative updates
- compact() extracts files, passes previousSummary, returns details
- Only merges from !fromHook compaction entries (backward compatible)
Both auto_compaction_end and executeCompaction were manually adding
CompactionSummaryMessageComponent instead of using addMessageToChat,
which caused missing spacers. Now both use addMessageToChat for
consistent spacing and expansion state handling.
Prepends: 'The user explored a different conversation branch before
returning here. Summary of that exploration:'
This helps the LLM understand the summary is background context from
a different path, not the current thread being continued.
The old messagesToText only extracted text content, losing all tool calls.
Now uses convertToLlm like compaction does, preserving the full conversation
including tool calls, which is essential for generating useful summaries.
getHookPaths(), getCustomToolPaths(), and getSkillsSettings() now return
copies of arrays instead of references to internal state. This prevents
callers from accidentally mutating settings without going through setters.
Fixes#361
Both now use consistent sections:
- Goal
- Constraints & Preferences
- Progress (Done/In Progress/Blocked)
- Key Decisions
- Next Steps
- Critical Context (compaction only)
Prompts instruct LLM to use EXACT format and preserve file paths/function names.