Commit graph

159 commits

Author SHA1 Message Date
Mario Zechner
7c103ddc55 refactor(coding-agent): simplify tree indentation
- At indent 0: stay flat unless parent branches
- At indent 1: children go to indent 2 (visual grouping)
- At indent 2+: stay flat for single-child chains
- Remove gutter/connector complexity for now
2025-12-30 22:42:23 +01:00
Mario Zechner
6fbc3a01ef refactor(coding-agent): cleaner tree gutter/indent logic
- Only indent when parent has siblings (branch point)
- gutterLevels array tracks which levels need │ vs spaces
- connector: none/branch/last for ├─/└─ display
2025-12-30 22:42:23 +01:00
Mario Zechner
1d90592df1 fix(coding-agent): always show error/aborted assistant messages in tree 2025-12-30 22:42:23 +01:00
Mario Zechner
5726770d1f fix(coding-agent): always show current leaf in tree selector even if aborted/error 2025-12-30 22:42:22 +01:00
Mario Zechner
2922020382 feat(coding-agent): improve tree selector tool display
- Tool results show formatted call info like [read: path:1-10], [bash: cmd]
- Skip assistant messages with stopReason error/aborted
- Skip assistant messages with only tool calls (no text)
- Format built-in tools like tool-execution.ts (read, write, edit, bash, grep, find, ls)
- Custom tools show truncated JSON args
2025-12-30 22:42:22 +01:00
Mario Zechner
b153b528e8 feat(coding-agent): show tool name instead of result content in tree selector 2025-12-30 22:42:22 +01:00
Mario Zechner
6b7ad0ed4b feat(coding-agent): reimplement tree selector features
- Label editing with 'l' key
- Ctrl+O cycles through filters: default -> user-only -> labeled-only -> all
- Preserve cursor position when toggling filters
- Labels shown at front of node
- Normalize tabs/newlines in content
- extractContent limited to 200 chars for performance
- truncateToWidth on all rendered lines
- Iterative flattenTree to avoid stack overflow
- Linear chain optimization (no indent for single-child chains)
2025-12-30 22:42:22 +01:00
Mario Zechner
1f4594598b feat(coding-agent): add search to /tree selector
- Type to filter nodes by matching tokens in content
- Search field always visible above tree
- Backspace removes chars, Escape clears search
- Restructured layout: title, border, help+search, border, tree, border
2025-12-30 22:42:22 +01:00
Mario Zechner
4958271dd3 feat(coding-agent): implement /tree command for session tree navigation
- Add TreeSelectorComponent with ASCII tree visualization
- Add AgentSession.navigateTree() for switching branches
- Add session_before_tree/session_tree hook events
- Add SessionManager.resetLeaf() for navigating to root
- Change leafId from string to string|null for consistency with parentId
- Support optional branch summarization when switching
- Update buildSessionContext() to handle null leafId
- Add /tree to slash commands in interactive mode
2025-12-30 22:42:22 +01:00
Mario Zechner
d6283f99dc refactor(hooks): split session events into individual typed events
Major changes:
- Replace monolithic SessionEvent with reason discriminator with individual
  event types: session_start, session_before_switch, session_switch,
  session_before_new, session_new, session_before_branch, session_branch,
  session_before_compact, session_compact, session_shutdown
- Each event has dedicated result type (SessionBeforeSwitchResult, etc.)
- HookHandler type now allows bare return statements (void in return type)
- HookAPI.on() has proper overloads for each event with correct typing

Additional fixes:
- AgentSession now always subscribes to agent in constructor (was only
  subscribing when external subscribe() called, breaking internal handlers)
- Standardize on undefined over null throughout codebase
- HookUIContext methods return undefined instead of null
- SessionManager methods return undefined instead of null
- Simplify hook exports to 'export type * from types.js'
- Add detailed JSDoc for skipConversationRestore vs cancel
- Fix createBranchedSession to rebuild index in persist mode
- newSession() now returns the session file path

Updated all example hooks, tests, and emission sites to use new event types.
2025-12-30 22:42:22 +01:00
Mario Zechner
26e1c9d91c Fix nested background issue in HookMessageComponent
When custom renderer returns a component with its own background,
don't wrap it in another background box. The nested bg resets
were causing padding to lose its background color.
2025-12-30 22:42:22 +01:00
Mario Zechner
4ff5f61ffc Add BranchSummaryMessageComponent, unify styling with hook messages
- CompactionSummaryMessageComponent now extends Box, uses customMessageBg
- New BranchSummaryMessageComponent for branch summaries
- Both use same background color as HookMessageComponent for consistency
- Added Spacer before compaction/branch components in chat
2025-12-30 22:42:21 +01:00
Mario Zechner
b921298af7 Use exhaustive switch on message.role throughout coding-agent
- addMessageToChat: exhaustive switch for all AgentMessage roles
- renderSessionContext: delegates to addMessageToChat, special handling for assistant tool calls and tool results
- export-html formatMessage: exhaustive switch for all AgentMessage roles
- Removed isHookMessage, isBashExecutionMessage type guards in favor of role checks
- Fixed imports and removed unused getLatestCompactionEntry
2025-12-30 22:42:21 +01:00
Mario Zechner
1113c95931 Fix import path in hook-message.ts 2025-12-30 22:42:20 +01:00
Mario Zechner
204d27581b Cleanup: unify HookMessage naming and simplify SessionContext
- Rename HookAppMessage to HookMessage, isHookAppMessage to isHookMessage
- Remove entries array from SessionContext (use isHookMessage type guard instead)
- HookMessage.content now accepts string directly (not just array)
- Fix streamMessage type in AgentState (AppMessage, not Message)
- Rename CustomMessageComponent to HookMessageComponent
- Fix test hook to use pi.sendMessage
2025-12-30 22:42:20 +01:00
Mario Zechner
14ad8d6228 Add ui.custom() for custom hook components with keyboard focus
- Add custom() to HookUIContext: returns { close, requestRender }
- Component receives keyboard input via handleInput()
- CustomMessageComponent default rendering now limits to 5 lines when collapsed
- Add snake.ts example hook with /snake command
2025-12-30 22:42:19 +01:00
Mario Zechner
a8866d7a83 Refactor: shared exec utility, rename CustomMessageRenderer to HookMessageRenderer
- Extract execCommand to src/core/exec.ts, shared by hooks and custom-tools
- Rename CustomMessageRenderer -> HookMessageRenderer
- Rename registerCustomMessageRenderer -> registerMessageRenderer
- Renderer now receives HookMessage instead of CustomMessageEntry
- CustomMessageComponent now has setExpanded() and responds to Ctrl+E toggle
- Re-export ExecOptions/ExecResult from exec.ts for backward compatibility
2025-12-30 22:42:19 +01:00
Mario Zechner
d43a5e47a1 Update CHANGELOG with CustomMessageEntry and hook rendering API 2025-12-30 22:42:18 +01:00
Kao Félix
a7efe3d4c1 fix: use consistent model comparison including provider 2025-12-25 22:10:08 +01:00
Mario Zechner
4edfff41a7
Merge pull request #315 from mitsuhiko/model-switcher
Reverse model switching and binding for dialog
2025-12-25 18:33:42 +01:00
Armin Ronacher
b576a527c7 Reverse model switching and binding for dialog 2025-12-25 18:07:36 +01:00
Mario Zechner
b4f7a957c4
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
2025-12-25 15:39:42 +01:00
Mario Zechner
54018b6cc0 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
2025-12-25 03:48:36 +01:00
Mario Zechner
1c31d91c83 WIP: Rename model-config.ts to models-json.ts
- loadCustomModels now takes file path instead of agentDir
2025-12-25 01:15:17 +01:00
Mario Zechner
ac5f4a77cc Fix model selector not showing models with settings.json API keys
Fixes #295
2025-12-24 21:23:44 +01:00
Mario Zechner
7ad8a8c447 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
2025-12-22 17:01:04 +01:00
Mario Zechner
ace8ea3d5b 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
2025-12-22 01:29:54 +01:00
Mario Zechner
d5fd685901 Enable more biome lints and fix things 2025-12-21 22:56:20 +01:00
Aliou Diallo
8868d623fc
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
2025-12-21 20:19:32 +01:00
Aliou Diallo
fe853ed869 feat(coding-agent): add Ctrl+G to open external editor 2025-12-21 12:07:05 +01:00
Mario Zechner
299986f06b Release v0.25.2 2025-12-21 02:59:03 +01:00
Mario Zechner
a81dc5eaca 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
2025-12-20 22:00:53 +01:00
Mario Zechner
c359023c3f 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
2025-12-20 21:34:18 +01:00
Mario Zechner
3266cac0f1 Fix coloring in footer when context usage is colored 2025-12-20 21:34:18 +01:00
Mario Zechner
8d1229b5ec 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
2025-12-19 21:53:04 +01:00
Mario Zechner
ad9d68e488 Fix footer overflow on narrow terminals, add /arminsayshi easter egg 2025-12-19 21:35:09 +01:00
theBucky
4f981d8ebc 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
2025-12-19 19:59:13 +01:00
Aliou Diallo
95dcd04e7c
fix(coding-agent): properly cleanup terminal on Ctrl+C in session selector (#247) 2025-12-19 19:04:00 +01:00
Mario Zechner
f8b6164ecd 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.
2025-12-19 04:54:02 +01:00
Ahmed Kamal
727a7ab018 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
2025-12-18 19:39:41 +02:00
Ahmed Kamal
c3c2bffc68 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
2025-12-18 19:29:40 +02:00
Ahmed Kamal
4a4531f887 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
2025-12-18 19:20:30 +02:00
Mario Zechner
5117187362 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
2025-12-18 16:49:44 +01:00
Mario Zechner
1a944f50f9 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
2025-12-18 16:01:01 +01:00
Mario Zechner
909989066a Fix TUI performance regression: add caching to Box, use Text directly for built-in tools 2025-12-17 16:39:23 +01:00
Mario Zechner
e7097d911a 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
2025-12-17 16:03:23 +01:00
Mario Zechner
e1ce9c1f49 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
2025-12-16 23:48:59 +01:00
Mario Zechner
7ac832586f 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
2025-12-16 14:53:17 +01:00
Mario Zechner
3de8e0757d Fix model selector fuzzy search to match provider and support multi-token queries 2025-12-15 18:05:32 +01:00
Mario Zechner
e4e234ecff 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
2025-12-13 23:53:28 +01:00