Commit Graph

328 Commits

  • 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)
  • Serialize conversation to text for summarization
    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
  • Add system prompt to compaction summarization
    - 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
  • Add file tracking and iterative summary merging to compaction
    - 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)
  • Add fromHook field to CompactionEntry and BranchSummaryEntry
    - fromHook: true = hook generated, skip file extraction
    - fromHook: undefined/false = pi generated, extract files (backward compatible)
    - branchWithSummary now accepts fromHook parameter
    - File extraction only runs for !entry.fromHook entries
  • Add preamble to branch summary for context
    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.
  • Fix branch summarization: use convertToLlm instead of messagesToText
    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.
  • Return defensive copies from SettingsManager getters
    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