Commit Graph

68 Commits

  • feat(coding-agent): add Ctrl+Z to suspend process (#267)
    * feat(tui): add isCtrlZ key detection and resetRenderState method
    
    * feat(coding-agent): add Ctrl+Z handler to suspend process
    
    * docs(coding-agent): add Ctrl+Z to keyboard shortcuts documentation
    
    * feat(tui): add force parameter to requestRender
  • Add configurable OAuth storage backend and respect --models in model selector
    - Add setOAuthStorage() and resetOAuthStorage() to pi-ai for custom storage backends
    - Configure coding-agent to use its own configurable OAuth path via getOAuthPath()
    - Model selector (/model command) now only shows models from --models scope when set
    - Rewrite OAuth documentation in pi-ai README with examples
    
    Fixes #255
  • Add Google Gemini CLI and Antigravity OAuth providers
    - Add google-gemini-cli provider: free Gemini 2.0/2.5 via Cloud Code Assist
    - Add google-antigravity provider: free Gemini 3, Claude, GPT-OSS via sandbox
    - Move OAuth infrastructure from coding-agent to ai package
    - Fix thinking signature handling for cross-model handoff
    - Fix OpenAI message ID length limit (max 64 chars)
    - Add GitHub Copilot overflow pattern detection
    - Add OAuth provider tests for context overflow and streaming
  • fix(coding-agent): clamp thinking level to model capabilities
    - setThinkingLevel() now clamps xhigh to high when model doesn't support it
    - Model changes automatically re-clamp the current thinking level
    - Fixed /model command to use session.setModel() instead of agent.setModel()
    - Footer and editor border color update after model/thinking changes
    
    Closes #253
  • fix(coding-agent): use key helpers for arrow keys and Enter
    Fixed arrow key and Enter detection in selector components to work
    with Kitty protocol when Caps Lock or Num Lock is enabled.
    
    Updated: oauth-selector, user-message-selector, hook-selector,
    hook-input, model-selector, session-selector
  • feat: add xhigh thinking level support for gpt-5.2 and gpt-5.2-codex
    - Add XHIGH_MODELS constant and getAvailableThinkingLevels() to AgentSession
    - Update ThinkingSelectorComponent to accept availableLevels parameter
    - Both shift+tab cycling and /thinking command now show xhigh for supported models
    - Update types.ts documentation to list supported models
  • Refactor subagent tool, fix custom tool discovery, fix JSON mode stdout flush
    Breaking changes:
    - Custom tools now require index.ts entry point in subdirectory
      (e.g., tools/mytool/index.ts instead of tools/mytool.ts)
    
    Subagent tool improvements:
    - Refactored to use Message[] from ai package instead of custom types
    - Extracted agent discovery to separate agents.ts module
    - Added parallel mode streaming (shows progress from all tasks)
    - Added turn count to usage stats footer
    - Removed redundant Query section from scout output
    
    Fixes:
    - JSON mode stdout flush: Fixed race condition where pi --mode json
      could exit before all output was written, causing consumers to
      miss final events
    
    Also:
    - Added signal/timeout support to pi.exec() for custom tools and hooks
    - Renamed pi-pods bin to avoid conflict with pi
  • Fix Escape key handling for Kitty keyboard protocol
    Add isEscape() helper that handles both raw (\x1b) and Kitty protocol
    (\x1b[27u) Escape sequences. Update all components that check for
    Escape key to use the new helper.
  • Skills standard compliance
    Implement Agent Skills standard (https://agentskills.io/specification):
    - Validate name (must match parent dir, lowercase, max 64 chars)
    - Validate description (required, max 1024 chars)
    - Warn on unknown frontmatter fields
    - Warn on name collisions (keep first)
    - Change prompt format to XML structure
    - Remove {baseDir} placeholder (use relative paths)
    - Add tests and update documentation
    
    fixes #231
  • Add Ctrl+D to exit when editor is empty
    - Add isCtrlD helper to keys.ts
    - CustomEditor intercepts Ctrl+D and only triggers callback when editor is empty
    - Single Ctrl+D with empty input exits immediately
    - Update CHANGELOG to frame as feature (Kitty protocol support) not fix
  • Add helper functions for key detection and update usage
    - Add isCtrlA/C/E/K/O/P/T/U/W helper functions that check both raw and Kitty formats
    - Add isAltBackspace helper function
    - Refactor editor.ts, input.ts, select-list.ts to use helper functions
    - Refactor custom-editor.ts, session-selector.ts, user-message-selector.ts
    - Add CHANGELOG entry for the Shift+Enter fix
  • Add Kitty keyboard protocol support for Shift+Enter and other modifier keys
    Enable the Kitty keyboard protocol on terminal start to receive enhanced
    key sequences that include modifier information. This fixes Shift+Enter
    not working in Ghostty, Kitty, WezTerm, and other modern terminals.
    
    Changes:
    - Enable Kitty protocol on start (\x1b[>1u), disable on stop (\x1b[<u)
    - Add centralized key definitions in packages/tui/src/keys.ts
    - Support both legacy and Kitty sequences for all modifier+key combos:
      - Shift+Enter, Alt+Enter for newlines
      - Shift+Tab for thinking level cycling
      - Ctrl+C, Ctrl+A, Ctrl+E, Ctrl+K, Ctrl+U, Ctrl+W, Ctrl+O, Ctrl+P, Ctrl+T
      - Alt+Backspace for word deletion
    - Export Keys constants and helper functions from @mariozechner/pi-tui
  • Add intra-line diff highlighting for edit tool
    - Extract diff rendering to dedicated diff.ts component
    - Show word-level changes with inverse highlighting when a single line is modified
    - Use diffWords for cleaner token grouping (includes adjacent whitespace)
    - Only apply intra-line diff when exactly 1 removed and 1 added line (true modification)
    - Multi-line changes show all removed then all added without incorrect pairing
    - Add theme.inverse() method for inverse text styling
  • Syntax highlighting improvements
    - Fix cli-highlight import (use static import instead of dynamic require)
    - Add syntax highlighting to read/write tool output
    - Update dark/light themes with VS Code default syntax colors
    - Add highlightCode and getLanguageFromPath exports
    - Upgrade @google/genai to 1.34.0 for IMAGE_RECITATION/IMAGE_OTHER FinishReason
    - Add AGENTS.md rule: never downgrade code to fix type errors from outdated deps
  • Custom tools with session lifecycle, examples for hooks and tools
    - Custom tools: TypeScript modules that extend pi with new tools
      - Custom TUI rendering via renderCall/renderResult
      - User interaction via pi.ui (select, confirm, input, notify)
      - Session lifecycle via onSession callback for state reconstruction
      - Examples: todo.ts, question.ts, hello.ts
    
    - Hook examples: permission-gate, git-checkpoint, protected-paths
    
    - Session lifecycle centralized in AgentSession
      - Works across all modes (interactive, print, RPC)
      - Unified session event for hooks (replaces session_start/session_switch)
    
    - Box component added to pi-tui
    
    - Examples bundled in npm and binary releases
    
    Fixes #190
  • Fix image limits test to use realistic payload sizes
    Previous test used compressed 8k images (0.01MB) which was meaningless.
    Now tests with actual large noise images that don't compress.
    
    Realistic payload limits discovered:
    - Anthropic: 6 x 3MB = ~18MB total (not 32MB as documented)
    - OpenAI: 2 x 15MB = ~30MB total
    - Gemini: 10 x 20MB = ~200MB total (very permissive)
    - Mistral: 4 x 10MB = ~40MB total
    - xAI: 1 x 20MB (strict request size limit)
    - Groq: 5 x 5760px images (5 image + pixel limit)
    - zAI: 2 x 15MB = ~30MB (50MB request limit)
    - OpenRouter: 2 x 5MB = ~10MB total
    
    Also fixed GEMINI_API_KEY env var (was GOOGLE_API_KEY).
    
    Related to #120
  • Add tool result streaming
    - Add AgentToolUpdateCallback type and optional onUpdate callback to AgentTool.execute()
    - Add tool_execution_update event with toolCallId, toolName, args, partialResult
    - Normalize tool_execution_end to always use AgentToolResult (no more string fallback)
    - Bash tool streams truncated rolling buffer output during execution
    - ToolExecutionComponent shows last N lines when collapsed (not first N)
    - Interactive mode handles tool_execution_update events
    - Update RPC docs and ai/agent READMEs
    
    fixes #44
  • GitHub Copilot: auto-enable models, fix gpt-5 API, normalize tool call IDs
    - Auto-enable all models after /login via POST /models/{model}/policy
    - Use openai-responses API for gpt-5/o3/o4 models (not accessible via completions)
    - Normalize tool call IDs when switching between github-copilot models with different APIs
      (fixes #198: openai-responses generates 450+ char IDs with special chars that break other models)
    - Update README with streamlined GitHub Copilot docs
  • feat: initial impl
    - add GitHub Copilot model discovery (env token fallback, headers,
    compat) plus fallback list and quoted provider keys in generated map
    - surface Copilot provider end-to-end (KnownProvider/default, env+OAuth
    token refresh/save, enterprise base URL swap, available only when
    creds/env exist)
    - tweak interactive OAuth UI to render instruction text and prompt
    placeholders
    
    gpt-5.2-high took about 35 minutes. It had a lot of trouble with `npm
    check`  and went off on a "let's adjust every tsconfig" side quest.
    Device code flow works, but the ai/scripts/generate-models.ts impl is
    wrong as models from months ago are missing and only those deprecated
    are accessible in the /models picker.
  • Fix image rendering artifacts and improve show-images selector
    - Image component returns correct number of lines (rows) for TUI accounting
    - Empty lines rendered first, then cursor moves up and image is drawn
    - This clears the space the image occupies before rendering
    - Add spacer before inline images in tool output
    - Create ShowImagesSelectorComponent with borders like other selectors
    - Use showSelector pattern for /show-images command
  • Add /show-images command to toggle inline image display
    - Add terminal.showImages setting to settings-manager.ts
    - Add /show-images slash command (only visible if terminal supports images)
    - ToolExecutionComponent checks both terminal support and user setting
    - Shows text fallback when inline images are disabled
  • Auto-retry on transient provider errors (overloaded, rate limit, 5xx)
    - Add retry logic with exponential backoff (2s, 4s, 8s) in AgentSession
    - Disable Anthropic SDK built-in retries (maxRetries: 0) to allow app-level handling
    - TUI shows retry status with Escape to cancel
    - RPC mode: add set_auto_retry, abort_retry commands and auto_retry_start/end events
    - Configurable via settings.json: retry.enabled, retry.maxRetries, retry.baseDelayMs
    - Exclude context overflow errors from retry (handled by compaction)
    
    fixes #157
  • Fix git branch indicator in subdirectories
    Walk up directory hierarchy to find .git/HEAD instead of only checking cwd.
    
    fixes #156
  • Fix branch selector for single message and --no-session mode
    - Allow branch selector to open with single user message (changed <= 1 to === 0 check)
    - Support in-memory branching for --no-session mode (no files created)
    - Add isEnabled() getter to SessionManager
    - Update sessionFile getter to return null when sessions disabled
    - Update SessionSwitchEvent types to allow null session files
    - Add branching tests for single message and --no-session scenarios
    
    fixes #163
  • fixes #161: disable theme watcher in print mode
    The theme file watcher was keeping the Node.js process alive indefinitely
    even in print mode where hot-reload is unnecessary. This fix adds an
    enableWatcher parameter to initTheme() and setTheme() functions, and only
    enables watchers in interactive mode.
    
    - Modified initTheme() to accept enableWatcher parameter (default: false)
    - Modified setTheme() to accept enableWatcher parameter (default: false)
    - Updated main.ts to only enable watchers in interactive mode
    - Updated InteractiveMode to enable watchers when changing themes
  • Add hooks system with pi.send() for external message injection
    - Hook discovery from ~/.pi/agent/hooks/, .pi/hooks/, --hook flag
    - Events: session_start, session_switch, agent_start/end, turn_start/end, tool_call, tool_result, branch
    - tool_call can block execution, tool_result can modify results
    - pi.send(text, attachments?) to inject messages from external sources
    - UI primitives: ctx.ui.select/confirm/input/notify
    - Context: ctx.exec(), ctx.cwd, ctx.sessionFile, ctx.hasUI
    - Docs shipped with npm package and binary builds
    - System prompt references docs folder
  • feat(coding-agent): implement hooks system
    - Add hooks infrastructure in core/hooks/ (loader, runner, types)
    - HookUIContext interface with mode-specific implementations
    - Interactive mode: TUI-based selector/input/confirm dialogs
    - RPC mode: JSON protocol for hook UI requests/responses
    - Print mode: no-op UI context (hooks run but can't prompt)
    - AgentSession.branch() now async, returns { selectedText, skipped }
    - Settings: hooks[] and hookTimeout configuration
    - Export hook types from package for hook authors
    
    Based on PR #147 proposal, adapted for new architecture.
  • Simplify compaction: remove proactive abort, use Agent.continue() for retry
    - Add agentLoopContinue() to pi-ai for resuming from existing context
    - Add Agent.continue() method and transport.continue() interface
    - Simplify AgentSession compaction to two cases: overflow (auto-retry) and threshold (no retry)
    - Remove proactive mid-turn compaction abort
    - Merge turn prefix summary into main summary
    - Add isCompacting property to AgentSession and RPC state
    - Block input during compaction in interactive mode
    - Show compaction count on session resume
    - Rename RPC.md to rpc.md for consistency
    
    Related to #128