Commit Graph

44 Commits

  • feat(coding-agent): add "none" option to doubleEscapeAction setting
    Allows disabling double-escape behavior entirely for users who
    accidentally trigger the tree/fork selector.
    
    Fixes #973
  • fix: autocompleteMaxVisible setting not persisting
    Missing markModified() call caused the setting to be lost on reload.
  • feat(coding-agent): add pi config TUI to manage resources
    Adds a new 'pi config' command with a TUI to list and toggle package
    resources (extensions, skills, prompts, themes).
    
    - Displays resources grouped by source (packages, user, project)
    - Subgroups by resource type (Extensions, Skills, Prompts, Themes)
    - Toggle enabled/disabled state with space
    - Filter resources by typing
    - Supports +pattern for force-include, !pattern for exclude
    - Properly reads exclusion patterns from settings.json
    
    fixes #938
  • feat(coding-agent): package deduplication and collision detection
    - Package deduplication: same package in global+project, project wins
    - Collision detection for skills, prompts, and themes with ResourceCollision type
    - PathMetadata tracking with parent directory lookup for file paths
    - Display improvements: section headers, sorted groups, accent colors for packages
    - pi list shows full paths below package names
    - Extension loader discovers files in directories without index.ts
    - In-memory SettingsManager properly tracks project settings
    
    fixes #645
  • feat(coding-agent): add packages array with filtering support
    - Add PackageSource type for npm/git sources with optional filtering
    - Migrate npm:/git: sources from extensions to packages array
    - Add getPackages(), setPackages(), setProjectPackages() methods
    - Update package-manager to resolve from packages array
    - Support selective loading: extensions, skills, prompts, themes per package
    - Update pi list to show packages
    - Add migration tests for settings
    
    closes #645
  • feat(coding-agent): ResourceLoader, package management, and /reload command (#645)
    - Add ResourceLoader interface and DefaultResourceLoader implementation
    - Add PackageManager for npm/git extension sources with install/remove/update
    - Add session.reload() and session.bindExtensions() APIs
    - Add /reload command in interactive mode
    - Add CLI flags: --skill, --theme, --prompt-template, --no-themes, --no-prompt-templates
    - Add pi install/remove/update commands for extension management
    - Refactor settings.json to use arrays for skills, prompts, themes
    - Remove legacy SkillsSettings source flags and filters
    - Update SDK examples and documentation for ResourceLoader pattern
    - Add theme registration and loadThemeFromPath for dynamic themes
    - Add getShellEnv to include bin dir in PATH for bash commands
  • feat(tui, coding-agent): add configurable code block indent setting (#855)
    Add markdown.codeBlockIndent setting to customize indentation prefix for
    rendered code blocks. Default remains 2 spaces for visual clarity, but
    setting to empty string removes indentation for easier copy/paste of
    code snippets to scripts, editors, or other tools.
    
    Changes:
    - tui: add optional codeBlockIndent to MarkdownTheme interface
    - coding-agent: add MarkdownSettings with codeBlockIndent property
    - coding-agent: compose theme with settings at call sites (no global state)
    - coding-agent: update message components to accept optional MarkdownTheme
    
    Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
  • fix(tui): always position cursor for IME
    # Conflicts:
    #	packages/coding-agent/CHANGELOG.md
  • fix(ai): filter empty error assistant messages in transformMessages
    When 429/500 errors occur during tool execution, empty assistant messages
    with stopReason='error' get persisted. These break the tool_use -> tool_result
    chain for Claude/Gemini APIs.
    
    Added centralized filtering in transformMessages to skip assistant messages
    with empty content and no tool calls. Provider-level filters remain for
    defense-in-depth.
  • feat(coding-agent): add startup.quiet setting to silence startup output (#777)
    * feat(coding-agent): add startup.quiet setting to silence startup output
    
    * feat(coding-agent): add startup.quiet setting to silence startup output
    
    Adds a new setting `startup.quiet` that when set to `true` hides:
    - Version and keybinding hints header
    - Loaded context/skills/templates/extensions discovery info
    - Model scope line
    
    Changelog notifications are still shown so users know about updates.
    
    Usage in ~/.pi/agent/settings.json:
    {
      "startup": {
        "quiet": true
      }
    }
    
    * refactor: flatten startup.quiet to quietStartup on Settings
  • Rename /branch command to /fork
    - RPC: branch -> fork, get_branch_messages -> get_fork_messages
    - SDK: branch() -> fork(), getBranchMessages() -> getForkMessages()
    - AgentSession: branch() -> fork(), getUserMessagesForBranching() -> getUserMessagesForForking()
    - Extension events: session_before_branch -> session_before_fork, session_branch -> session_fork
    - Settings: doubleEscapeAction 'branch' -> 'fork'
    
    fixes #641
  • Add /models command for enabling/disabling Ctrl+P model cycling
    - New /models command with toggle UI for each available model
    - Changes persist to enabledModels in settings.json
    - Updates take effect immediately for Ctrl+P cycling
  • feat: Add skill slash commands and fuzzy matching for all commands
    - Skills registered as /skill:name commands for quick access
    - Toggle via /settings or skills.enableSkillCommands in settings.json
    - Fuzzy matching for all slash command autocomplete (type /skbra for /skill:brave-search)
    - Moved fuzzy module from coding-agent to tui package for reuse
    
    Closes #630 by @Dwsy (reimplemented with fixes)
  • fix: preserve externally-added settings when saving
    When a user edits settings.json while pi is running (e.g., adding
    enabledModels), those settings would be lost when pi saved other
    changes (e.g., changing thinking level via Shift+Tab).
    
    The fix re-reads the file before saving and merges the current file
    contents with in-memory changes, so external edits are preserved.
    
    Adds test coverage for SettingsManager.
  • Add blockImages setting to prevent images from being sent to LLM providers
    - Setting controls filtering at convertToLlm layer (defense-in-depth)
    - Images are always stored in session, filtered dynamically based on current setting
    - Toggle mid-session works: LLM sees/doesn't see images already in session
    - Fixed SettingsManager.save() to handle inMemory mode for all setters
    
    Closes #492
  • Merge hooks and custom-tools into unified extensions system (#454)
    Breaking changes:
    - Settings: 'hooks' and 'customTools' arrays replaced with 'extensions'
    - CLI: '--hook' and '--tool' flags replaced with '--extension' / '-e'
    - API: HookMessage renamed to CustomMessage, role 'hookMessage' to 'custom'
    - API: FileSlashCommand renamed to PromptTemplate
    - API: discoverSlashCommands() renamed to discoverPromptTemplates()
    - Directories: commands/ renamed to prompts/ for prompt templates
    
    Migration:
    - Session version bumped to 3 (auto-migrates v2 sessions)
    - Old 'hookMessage' role entries converted to 'custom'
    
    Structural changes:
    - src/core/hooks/ and src/core/custom-tools/ merged into src/core/extensions/
    - src/core/slash-commands.ts renamed to src/core/prompt-templates.ts
    - examples/hooks/ and examples/custom-tools/ merged into examples/extensions/
    - docs/hooks.md and docs/custom-tools.md merged into docs/extensions.md
    
    New test coverage:
    - test/extensions-runner.test.ts (10 tests)
    - test/extensions-discovery.test.ts (26 tests)
    - test/prompt-templates.test.ts
  • feat(coding-agent): configurable double-escape action (tree vs branch)
    Add doubleEscapeAction setting to choose whether double-escape with an
    empty editor opens /tree (default) or /branch.
    
    - Add setting to Settings interface and SettingsManager
    - Add to /settings UI for easy toggling
    - Update interactive-mode to respect the setting
    - Document in README.md settings table
    
    fixes #404
  • feat(coding-agent): complete steer()/followUp() migration
    - Update settings-manager with steeringMode/followUpMode (migrates old queueMode)
    - Update sdk.ts to use new mode options
    - Update settings-selector UI to show both modes
    - Add Alt+Enter keybind for follow-up messages
    - Update RPC API: steer/follow_up commands, set_steering_mode/set_follow_up_mode
    - Update rpc-client with new methods
    - Delete dead code: queue-mode-selector.ts
    - Update tests for new API
    - Update mom/context.ts stubs
    - Update web-ui example
  • 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.
  • 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
  • Use reserveTokens for branch summary (tokens left for prompt + response)
    - tokenBudget = contextWindow - reserveTokens
    - Default 16384, same as compaction
    - Consistent naming with CompactionSettings.reserveTokens
  • Use token-based maxTokens instead of fraction-based reserveFraction
    - BranchSummarySettings.maxTokens (default 100000) instead of reserveFraction
    - More intuitive and consistent with CompactionSettings.keepRecentTokens
  • Use AgentMessage in BranchPreparation and add BranchSummarySettings
    - BranchPreparation now uses AgentMessage[] instead of custom type
    - Reuse getMessageFromEntry pattern from compaction.ts
    - Add BranchSummarySettings with reserveFraction to settings.json
    - Add getBranchSummarySettings() to SettingsManager
    - Use settings for reserveFraction instead of hardcoded value
  • 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
  • Add project-specific settings and SettingsManager factories
    - SettingsManager now loads .pi/settings.json from cwd (project settings)
    - Project settings merge with global settings (deep merge for objects)
    - Setters only modify global settings, project settings are read-only
    - Add static factories: SettingsManager.create(cwd?, agentDir?), SettingsManager.inMemory(settings?)
    - Add applyOverrides() for programmatic overrides
    - Replace 'settings' option with 'settingsManager' in CreateAgentSessionOptions
    - Update examples to use new pattern
    
    Incorporates PR #276 approach
  • feat(coding-agent): add --skills CLI flag for filtering skills
    Adds glob pattern support for skill filtering:
    - --skills <patterns> CLI flag (comma-separated glob patterns)
    - includeSkills setting in settings.json
    - ignoredSkills now supports glob patterns
    - ignoredSkills takes precedence over includeSkills and --skills
    
    Closes #268
  • 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 /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
  • Add skills system with Claude Code compatibility (#171)
    * Add skills system with Claude Code compatibility
    
    * consolidate skills into single module, merge loaders, add <available_skills> XML tags
    
    * add Codex CLI skills compatibility, skip hidden/symlinks
  • 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
  • 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.