Commit Graph

176 Commits

  • feat(hooks): add setWidgetComponent for custom TUI components
    - New ctx.ui.setWidgetComponent(key, factory) method
    - Allows custom Component to render as widget without taking focus
    - Unlike custom(), widget components render inline above editor
    - Components are disposed when cleared or replaced
    - Falls back to no-op in RPC/print modes
  • fix(widgets): add max line limit and document multi-hook behavior
    - Limit total widget lines to 10 to prevent viewport overflow/flicker
    - Show '... (widget truncated)' when limit exceeded
    - Document that multiple hooks stack widgets vertically
    - Add caution about keeping widgets small
  • refactor(hooks): address PR feedback
    - Rename getTools/setTools to getActiveTools/setActiveTools
    - Add getAllTools to enumerate all configured tools
    - Remove text_delta event (use turn_end/agent_end instead)
    - Add shortcut conflict detection:
      - Skip shortcuts that conflict with built-in shortcuts (with warning)
      - Log warnings when hooks register same shortcut (last wins)
    - Add note about prompt cache invalidation in setActiveTools
    - Update plan-mode hook to use agent_end for [DONE:id] parsing
  • feat(hooks): add text_delta event for streaming text monitoring
    - New text_delta hook event fires for each chunk of streaming text
    - Enables real-time monitoring of agent output
    - Plan-mode hook now updates todo progress as [DONE:id] tags stream in
    - Each todo item has unique ID for reliable tracking
  • feat(hooks): add setWidget API for multi-line status displays
    - ctx.ui.setWidget(key, lines) for multi-line displays above editor
    - Widgets appear below 'Working...' indicator, above editor
    - Supports ANSI styling including strikethrough
    - Added theme.strikethrough() method
    - Plan-mode hook now shows todo list with checkboxes
    - Completed items show checked box and strikethrough text
  • feat(coding-agent): add hook API for CLI flags, shortcuts, and tool control
    Hook API additions:
    - pi.getTools() / pi.setTools(toolNames) - dynamically enable/disable tools
    - pi.registerFlag(name, options) / pi.getFlag(name) - register custom CLI flags
    - pi.registerShortcut(shortcut, options) - register keyboard shortcuts
    
    Plan mode hook (examples/hooks/plan-mode.ts):
    - /plan command or Shift+P shortcut to toggle
    - --plan CLI flag to start in plan mode
    - Read-only tools: read, bash, grep, find, ls
    - Bash restricted to non-destructive commands (blocks rm, mv, git commit, etc.)
    - Interactive prompt after each response: execute, stay, or refine
    - Shows plan indicator in footer when active
    - State persists across sessions
  • WIP: Add hook API for dynamic tool control with plan-mode hook example
    - Add pi.getTools() and pi.setTools(toolNames) to HookAPI
    - Hooks can now enable/disable tools dynamically
    - Changes take effect on next agent turn
    
    New example hook: plan-mode.ts
    - Claude Code-style read-only exploration mode
    - /plan command toggles plan mode on/off
    - Plan mode tools: read, bash, grep, find, ls
    - Edit/write tools disabled in plan mode
    - Injects context telling agent about restrictions
    - After each response, prompts to execute/stay/refine
    - State persists across sessions
  • Fix slash commands and hook commands during streaming
    - Hook commands now execute immediately during streaming (they manage their own LLM interaction via pi.sendMessage())
    - File-based slash commands are expanded and queued via steer/followUp during streaming
    - prompt() accepts new streamingBehavior option ('steer' or 'followUp') for explicit queueing during streaming
    - steer() and followUp() now expand file-based slash commands and error on hook commands
    - RPC prompt command accepts optional streamingBehavior field
    - Updated docs: rpc.md, sdk.md, CHANGELOG.md
    
    fixes #420
  • docs: update README.md, hooks.md, and CHANGELOG for steer()/followUp() API
    - Fix settings-selector descriptions to explain one-at-a-time vs all
    - Update README.md message queuing section, settings example, and table
    - Update hooks.md: hasPendingMessages, sendMessage options, triggerTurn example
    - Add Theme/ThemeColor export and hasPendingMessages rename to CHANGELOG
  • Add todo hook companion to todo custom tool
    - /todos command displays all todos on current branch with custom UI
    - Update hooks.md to clarify components must not be wrapped in Box/Container
    - Cross-reference tool and hook in example READMEs
  • Update docs for ctx.ui.editor() and handoff example
    - Added ctx.ui.editor() to hooks.md and custom-tools.md
    - Added ctx.ui.editor() to CHANGELOG.md
    - Added handoff.ts to examples/hooks/README.md
  • 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
  • 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
  • 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>
  • Add thinkingText theme token, fix streaming toggle bug
    - 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/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
  • Expand pi.sendMessage and registerMessageRenderer docs in hooks.md
    - sendMessage: document storage timing, LLM context, TUI display
    - registerMessageRenderer: document renderer signature, return null for default
  • Update rpc.md to match actual implementation
    - AppMessage -> AgentMessage
    - compact response shows full CompactionResult fields
    - auto_compaction_start includes reason field
    - auto_compaction_end includes willRetry field
    - Fix source file references
  • Fix sdk.md and rpc.md to match actual API
    - Remove incorrect prompt(AppMessage) overload
    - Change AppMessage to AgentMessage
    - Change null to undefined for optional returns
    - sendHookMessage returns Promise<void>
    - Update rpc.md for entryId change
  • 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)
  • Update custom-compaction example to use serializeConversation
    Also fix docs to show convertToLlm is needed first.
  • Export serializeConversation and document in compaction.md
    Shows how to convert messages to text for custom summarization.
  • 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 tui.md and improve TUI documentation
    - New tui.md covers component system for hooks and custom tools
    - Update hooks.md intro with 'Key capabilities' highlighting UI
    - Update custom-tools.md intro with 'Key capabilities' highlighting UI
    - Reference tui.md from both docs
  • Improve hooks.md UI documentation
    - Add 'Key capabilities' section highlighting UI features
    - Expand ctx.ui docs with custom component details
    - Reference snake.ts example for custom UI
  • 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.
  • Add compaction.md and rewrite hooks.md
    - New compaction.md covers auto-compaction and branch summarization
    - Explains cut points, split turns, data model, file tracking
    - Documents session_before_compact and session_before_tree hooks
    
    - Rewritten hooks.md matches actual API (separate event names)
    - Correct ctx.ui.custom() signature (returns handle, not callback)
    - Documents all session events including tree events
    - Adds sessionManager and modelRegistry usage
    - Updates all examples to use correct API
  • Reorder execute params: (toolCallId, params, onUpdate, ctx, signal?)
    Optional signal now at the end for cleaner API
  • Update CHANGELOG, README, and custom-tools.md for new CustomTool API
    - Add custom tools API rework to CHANGELOG breaking changes
    - Update docs/custom-tools.md with new types and signatures
    - Update README quick example with correct execute signature
  • 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
  • Update hooks.md and session.md for consolidated HookContext
    - HookEventContext renamed to HookContext (used for events and commands)
    - RegisteredCommand.handler: (ctx) -> (args, ctx)
    - before_compact: previousCompactions -> branchEntries, model moved to ctx.model
    - ctx.exec -> pi.exec in examples
    - ctx.sessionFile -> ctx.sessionManager.getSessionFile()
    - CompactionPreparation: document turnPrefixMessages, isSplitTurn, previousSummary
    - session.md: clarify details field for compaction/branch summary
  • Update SDK and RPC docs, remove outdated files
    - Remove hooks-v2.md, session-tree.md, UNRELEASED_OLD.md
    - sdk.md: Update hook API (sendMessage, appendEntry, registerCommand, etc.)
    - sdk.md: Update SessionManager with tree API
    - sdk.md: Update AgentSession interface
    - rpc.md: Fix attachments -> images in prompt command
  • Update CHANGELOG.md and docs for session tree release
    CHANGELOG.md:
    - Add /tree command, context event, before_agent_start event
    - Add ui.custom(), branch summarization, selectedBg theme color
    - Add snake game example hook
    - Add external contributions: CRLF fix, bash on Unix, clickable OAuth, error messages
    - Update theme requirements (50 total colors)
    
    session.md:
    - Complete rewrite for v2 tree structure
    - Document all entry types with examples
    - Add SessionManager API reference
    
    hooks.md:
    - Replace pi.send() with pi.sendMessage()
    - Add pi.appendEntry(), pi.registerCommand(), pi.registerMessageRenderer()
    - Move exec() from ctx to pi.exec()
    - Add ui.custom() for custom TUI components
    - Add context and before_agent_start events
    - Update before_compact event fields
    - Add ctx.sessionManager and ctx.modelRegistry
  • Fix tree selector: proper selectedBg theme color, correct filter logic
    - 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)