Commit Graph

57 Commits

  • Add TUI rendering for CustomMessageEntry
    - Add CustomMessageComponent with purple-tinted styling
    - Add theme colors: customMessageBg, customMessageText, customMessageLabel
    - Rename renderMessages to renderSessionContext taking SessionContext directly
    - renderInitialMessages now gets context from sessionManager
    - Skip rendering for display: false entries
  • Refactor SessionEventBase to pass sessionManager and modelRegistry
    Breaking changes to hook types:
    - SessionEventBase now passes sessionManager and modelRegistry directly
    - before_compact: passes preparation, previousCompactions (newest first)
    - before_switch: has targetSessionFile; switch: has previousSessionFile
    - Removed resolveApiKey (use modelRegistry.getApiKey())
    - getSessionFile() returns string | undefined for in-memory sessions
    
    Updated:
    - All session event emissions in agent-session.ts
    - Hook examples (custom-compaction.ts, auto-commit-on-exit.ts, confirm-destructive.ts)
    - Tests (compaction-hooks.test.ts, compaction-hooks-example.test.ts)
    - export-html.ts guards for in-memory sessions
  • fix: make OAuth login URL clickable in terminal
    Use OSC 8 hyperlink escape sequence to show 'Click here to login'
    as a clickable link instead of displaying the raw URL which spans
    multiple lines and is hard to click in terminals (especially WSL).
  • feat(coding-agent): Add --session-dir flag for custom session directory
    - Add --session-dir CLI flag to specify custom session directory
    - SessionManager API: second param of create(), continueRecent(), list(), open()
      changed from agentDir to sessionDir (direct directory, no cwd encoding)
    - When omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/)
    - --session now derives sessionDir from file's parent if --session-dir not provided
    - list() validates session header before processing files
    - Closes #313
    
    Co-authored-by: scutifer <scutifer@users.noreply.github.com>
  • Merge pull request #315 from mitsuhiko/model-switcher
    Reverse model switching and binding for dialog
  • Add /settings command with unified settings menu (#312)
    * Add /settings command with unified settings menu
    
    - Add SettingsList component to tui package with support for:
      - Inline value cycling (Enter/Space toggles)
      - Submenus for complex selections
      - Selection preservation when returning from submenu
    
    - Add /settings slash command consolidating:
      - Auto-compact (toggle)
      - Show images (toggle)
      - Queue mode (cycle)
      - Hide thinking (toggle)
      - Collapse changelog (toggle)
      - Thinking level (submenu)
      - Theme (submenu with preview)
    
    - Update AGENTS.md to clarify no inline imports rule
    
    Fixes #310
    
    * Add /settings to README slash commands table
    
    * Remove old settings slash commands, consolidate into /settings
    
    - Remove /thinking, /queue, /theme, /autocompact, /show-images commands
    - Remove unused selector methods and imports
    - Update README references to use /settings
  • Rename /clear to /new, update hook events to before_new/new
    Closes #305 - took direct rename approach instead of alias system
    
    Thanks @mitsuhiko for the nudge!
  • Refactor OAuth/API key handling: AuthStorage and ModelRegistry
    - Add AuthStorage class for credential storage (auth.json)
    - Add ModelRegistry class for model management with API key resolution
    - Add discoverAuthStorage() and discoverModels() discovery functions
    - Add migration from legacy oauth.json and settings.json apiKeys to auth.json
    - Remove configureOAuthStorage, defaultGetApiKey, findModel, discoverAvailableModels
    - Remove apiKeys from Settings type and SettingsManager methods
    - Rename getOAuthPath to getAuthPath
    - Update SDK, examples, docs, tests, and mom package
    
    Fixes #296
  • WIP: Rename model-config.ts to models-json.ts
    - loadCustomModels now takes file path instead of agentDir
  • docs: fix outdated custom tools paths and add missing header shortcut (#283)
    * docs: fix custom tools example paths to use index.ts structure
    
    * fix: add missing ctrl+g shortcut to startup header
    
    * docs: fix /session -> /resume for session switching references
  • Add before/after session events with cancellation support
    - Merge branch event into session with before_branch/branch reasons
    - Add before_switch, before_clear, shutdown reasons
    - before_* events can be cancelled with { cancel: true }
    - Update RPC commands to return cancelled status
    - Add shutdown event on process exit
    - New example hooks: confirm-destructive, dirty-repo-guard, auto-commit-on-exit
    
    fixes #278
  • Fix bash tool visual line truncation
    Use visual line counting (accounting for line wrapping) instead of logical
    line counting for bash tool output in collapsed mode. Now consistent with
    bash-execution.ts behavior.
    
    - Add shared truncateToVisualLines utility
    - Update tool-execution.ts to use Box for bash with visual truncation
    - Update bash-execution.ts to use shared utility
    - Pass TUI to ToolExecutionComponent for terminal width access
    
    Fixes #275
  • Refactor SessionManager to use static factory methods
    - Add factory methods: create(cwd), open(path), continueRecent(cwd), inMemory()
    - Add static list(cwd) for session listing
    - Make constructor private, pass cwd explicitly
    - Update SDK to take sessionManager instead of sessionFile options
    - Update main.ts to create SessionManager based on CLI flags
    - Update SessionSelectorComponent to take sessions[] instead of SessionManager
    - Update tests to use factory methods
  • 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
  • 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
  • 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
  • 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
  • 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 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
  • feat(coding-agent): implement new compaction system with overflow recovery
    Phase 1: Updated compaction.ts
    - findCutPoint now returns CutPointResult with isSplitTurn and turnStartIndex
    - Can cut at user, assistant, or bashExecution messages (never tool results)
    - Added turnPrefixSummary support for split turns (parallel summarization)
    - estimateTokens helper for context size estimation
    
    Phase 2: Updated session-manager.ts
    - CompactionEntry now has optional turnPrefixSummary field
    - loadSessionFromEntries injects both summaries when turn was split
    
    Phase 3: Updated agent-session.ts
    - Overflow detection via isContextOverflow after agent_end
    - Proactive compaction check on turn_end before next LLM call
    - _abortingForCompaction flag to skip saving aborted messages
    - Auto-retry after overflow recovery or proactive compaction
    - New event fields: reason (overflow/threshold), willRetry
    
    Phase 4: Updated interactive-mode.ts
    - Shows reason in compaction status (Context overflow detected...)
    - Shows retry status after compaction
    
    Tests updated for new CutPointResult return type.
  • Fix auto-compaction TUI integration and cut point logic
    - Trigger auto-compaction after agent_end instead of during message_end
    - Show CompactionComponent after auto-compaction (same as manual /compact)
    - Fix cut point to include bash executions before kept user message
    - Stop backward scan at compaction, assistant, user, or toolResult boundaries
  • Add auto-compaction events to AgentSession
    - Add AgentSessionEvent type extending AgentEvent with auto_compaction_start/end
    - Emit events when auto-compaction starts and completes
    - TUI shows loader during auto-compaction with escape to cancel
    - Rebuilds chat UI when auto-compaction succeeds