Commit Graph

236 Commits

  • Fix edit tool failing on files with UTF-8 BOM
    Strip BOM before matching (LLM won't include invisible BOM in oldText),
    restore on write.
    
    Based on #394 by @prathamdby
  • fix(coding-agent): prevent full re-renders during write tool streaming
    Move line count from header to footer to avoid changing the first line
    during streaming, which was triggering full screen re-renders in the
    TUI's differential rendering logic.
  • Add agent state methods to CustomToolContext and fix abort signature
    CustomToolContext now has:
    - isIdle() - check if agent is streaming
    - hasQueuedMessages() - check if user has queued messages
    - abort() - abort current operation (fire-and-forget)
    
    Changed abort() signature from Promise<void> to void in both
    HookContext and CustomToolContext. The abort is fire-and-forget:
    it calls session.abort() without awaiting, so the abort signal
    is set immediately while waitForIdle() runs in the background.
    
    Fixes #388
  • Split HookContext and HookCommandContext to prevent deadlocks
    HookContext (all events):
    - isIdle() - read-only state check
    - hasQueuedMessages() - read-only state check
    - abort() - fire-and-forget, does not wait
    
    HookCommandContext (slash commands only):
    - waitForIdle() - waits for agent to finish
    - newSession(options?) - create new session
    - branch(entryId) - branch from entry
    - navigateTree(targetId, options?) - navigate session tree
    
    Session control methods moved from HookAPI (pi.*) to HookCommandContext (ctx.*)
    because they can deadlock when called from event handlers that run inside
    the agent loop (tool_call, tool_result, context events).
  • Add session management and agent state methods to hooks API
    HookAPI additions:
    - pi.newSession(options?) - create new session with optional setup callback
    - pi.branch(entryId) - branch from a specific entry
    - pi.navigateTree(targetId, options?) - navigate the session tree
    
    HookContext additions:
    - ctx.isIdle() - check if agent is streaming
    - ctx.waitForIdle() - wait for agent to finish
    - ctx.abort() - abort current operation
    - ctx.hasQueuedMessages() - check for queued user messages
    
    These enable hooks to programmatically manage sessions (handoff, templates)
    and check agent state before showing interactive UI.
    
    Fixes #388
  • Consolidate session events: remove session_before_new/session_new, add reason field to switch events
    - Remove session_before_new and session_new hook events
    - Add reason: 'new' | 'resume' to session_before_switch and session_switch events
    - Remove 'new' reason from custom tool onSession (use 'switch' for both /new and /resume)
    - Rename reset() to newSession(options?) in AgentSession
    - Add NewSessionOptions with optional parentSession for lineage tracking
    - Rename branchedFrom to parentSession in SessionHeader
    - Rename RPC reset command to new_session with optional parentSession
    - Update example hooks to use new event structure
    - Update documentation and changelog
    
    Based on discussion in #293
  • Add theme-configurable HTML export colors (from PR #387)
    - Add optional 'export' section to theme JSON with pageBg, cardBg, infoBg
    - If not specified, colors are auto-derived from userMessageBg
    - Add export colors to dark.json and light.json
    - Update theme-schema.json and TypeBox schema
    - Add documentation to docs/theme.md
    - Add margin-top back to tool-output for spacing between header and content
  • Fix markdown code block default color to use --text not --mdCodeBlock
    The mdCodeBlock color was being applied to all text in code blocks,
    overriding hljs syntax highlighting for unspanned text.
  • Fix hljs color mappings to match TUI theme
    - Add .hljs-function for syntaxFunction
    - Separate .hljs-punctuation to use syntaxPunctuation (was using syntaxOperator)
  • Fix HTML escaping in markdown code blocks
    Move HTML tag escaping from pre-parse to custom renderers.
    This preserves < in code blocks while still escaping in text content.
  • Add ctx.ui.theme getter for styling status text with theme colors
    - Add theme property to HookUIContext interface
    - Implement in interactive, RPC, and no-op contexts
    - Add status-line.ts example hook
    - Document styling with theme colors in hooks.md
  • Fix markdown code block syntax highlighting
    Marked v15 removed the highlight option from setOptions.
    Use marked.use() with a custom renderer instead.
  • Fix tool-output spacing by removing pre-wrap from container
    The white-space: pre-wrap on .tool-output was preserving template
    literal whitespace (newlines and indentation). The pre elements
    inside still have pre-wrap for actual code content.
  • Hooks can render custom status (#385)
    * Add ctx.ui.setStatus(key, text) API for hooks to display status in footer
    
    - Add setStatus to HookUIContext interface
    - Implement in interactive mode (FooterComponent)
    - Implement in RPC mode (fire-and-forget)
    - Add no-op implementations for headless contexts
    - Multiple statuses displayed on single line, sorted by key
    - Supports ANSI styling (hooks handle their own colors)
    
    * Remove setStatus from changelog for now
    
    * Fix hook status API to follow TUI rules
    
    - Sanitize status text: replace newlines, tabs, carriage returns with spaces
    - Truncate combined status line to terminal width using truncateToWidth
    - Update JSDoc to document sanitization and truncation behavior
    - Remove unused createHookUIContext method
    - Add missing setStatus to test mock
    
    * Add setStatus to changelog
    
    * Use dim ellipsis for hook status truncation for consistency with footer style
    
    ---------
    
    Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
  • Fix export HTML styling issues
    - Match help-bar font size (11px) with header-info
    - Add newline after 'Available Tools' header
    - Remove excessive margin-top from tool-output
  • Refactor export-html and add /share command
    - Split template into separate files: template.html, template.css, template.js
    - Add tree visualization sidebar for session navigation
    - Fix HTML sanitization to prevent <style> tags breaking DOM
    - Add DOM node caching for faster re-renders
    - Fix tree indentation to match tree-selector.ts
    - Add /share command to upload session as GitHub gist
    - Support shittycodingagent.ai/session?{gistId} URLs
    
    Closes #375, closes #380
  • Show edit diff before tool execution (fixes #393)
    - Extract diff computation from edit.ts into shared edit-diff.ts
    - ToolExecutionComponent computes and caches diff when args are complete
    - Diff is visible while permission hooks block, before tool executes
  • Fix export-html tree sidebar to match TUI tree-selector
    - Show tool results in default filter (not hidden)
    - Branch summary shows summary text inline
    - Custom message support in tree with customType label
    - Remove extra padding from tree nodes (use line-height)
    - Remove border styling from active/in-path nodes
    - Consistent 18px line-height for tree entries
  • Fix export-html message stats and help bar
    - Fix entry type names: branch_summary, custom_message (snake_case)
    - Fix toolResult role (was 'tool')
    - Count all entry types: user, assistant, tool results, custom, compactions, branch summaries
    - Use global stats for tokens/cost (all entries), not just current branch
    - Make help bar more prominent (12px, full opacity)
    - Remove Esc shortcut from help bar
  • Fix export-html header stats and UX
    - Header h1 font size now 12px (matches body)
    - Token/cost stats now computed for all entries, not just current branch
    - Token display matches footer format: ↑input ↓output Rcache Wcache
    - Cost display uses 3 decimal places like footer
    - Scroll to target uses requestAnimationFrame for DOM readiness
    - Initial load and Escape scroll to bottom, tree clicks scroll to target
  • Fix export-html spacing to use line-height based system
    - Add --line-height CSS variable (18px = 12px font * 1.5)
    - Convert all padding/margin to use var(--line-height)
    - Remove fractional values for terminal-like consistency
    - Fix gap between consecutive tool executions
    - Remove extra padding from error-text and model-change
    - Fix thinking toggle to show 'Thinking ...' when collapsed
    - Remove top padding after timestamps in assistant messages
    - Remove bottom padding from assistant-text
  • Fix export-html styling and behavior
    - 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
  • Add image support and mobile UX improvements to export-html
    - 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
  • Polish export-html tree styling
    - Add subtle border between sidebar and content
    - Use selectedBg for tree node hover state
    - Add left border accent for active and in-path nodes
  • Improve export-html styling with derived export colors
    - 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
  • WIP: Rewrite export-html with tree sidebar, client-side rendering
    - 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
  • fix: enabledModels now supports glob patterns for OAuth providers
    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 setEditorText/getEditorText to hook UI context, improve custom() API
    - 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
  • Fix hook tool_result event not emitted for tool errors
    Tools are supposed to throw on error. What needs fixing is that we need to report tool_result for erroneous tool executions as well.
    
    Fixes #374
  • fix(coding-agent): save initial model and thinking level to session
    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
  • Change branch() to use entryId instead of entryIndex
    - AgentSession.branch(entryId: string) now takes entry ID
    - SessionBeforeBranchEvent.entryId replaces entryIndex
    - getUserMessagesForBranching() returns entryId
    - Update RPC types and client
    - Update UserMessageSelectorComponent
    - Update hook examples and tests
    - Update docs (hooks.md, sdk.md)
  • Add creation hints to docs and update system prompt
    - System prompt now instructs to read docs AND examples, follow cross-refs
    - Each doc starts with 'pi can create X. Ask it to build one.'
  • Add examples path to system prompt
    Agent can now find examples at the documented path for
    hooks, custom tools, and SDK usage.
  • Remove hook execution timeouts
    - 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.
  • Reorder execute params: (toolCallId, params, onUpdate, ctx, signal?)
    Optional signal now at the end for cleaner API
  • Rework custom tools API with CustomToolContext
    - 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
  • Replace custom tool dispose() with shutdown session event
    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
  • refactor(coding-agent): fix compaction for branched sessions, consolidate hook context types
    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
  • Extract shared compaction/branch-summarization utils
    - 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
  • Use convertToLlm before serializing, include thinking, remove truncation
    - 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)