Commit graph

140 commits

Author SHA1 Message Date
Danila Poyarkov
a497fccd06
refactor: use configurable keybindings for all UI hints (#724)
Follow-up to #717. Replaces all remaining hardcoded keybinding hints with configurable ones.

- Add pasteImage to AppAction so it can be configured in keybindings.json
- Create keybinding-hints.ts with reusable helper functions:
  - editorKey(action) / appKey(keybindings, action) - get key display string
  - keyHint(action, desc) / appKeyHint(kb, action, desc) / rawKeyHint(key, desc) - styled hints
- Export helpers from components/index.ts for extensions
- Update all components to use configured keybindings
- Remove now-unused getDisplayString() from KeybindingsManager and EditorKeybindingsManager
- Use keybindings.matches() instead of matchesKey() for pasteImage in custom-editor.ts
2026-01-14 15:42:03 +01:00
Danila Poyarkov
7f2d2f106e
fix: use configurable expandTools keybinding instead of hardcoded ctrl+o (#717)
- Add expandTools to EditorAction in pi-tui so components can access it
- Update bash-execution, compaction-summary-message, branch-summary-message,
  and tool-execution to use getEditorKeybindings().getKeys('expandTools')
- Pass expandTools config to setEditorKeybindings in KeybindingsManager.create()
- Style keybinding with 'dim' color, description with 'muted' (matches startup hints)
2026-01-14 10:27:22 +01:00
thomasmhr
68f1e30f06 Add Alt+Up/Down to reorder enabled models in scoped-models selector
- Add move() pure function for swapping adjacent items
- Handle Alt+Up/Down in handleInput to reorder enabled models
- Selection follows the moved item
- Update footer hint with new shortcut

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 01:10:20 +01:00
thomasmhr
15e18f61ab Refactor scoped-models-selector with pure functions for state
- Replace mutable items[].enabled with EnabledIds type (null | string[])
- Extract state operations as pure functions (toggle, enableAll, clearAll, move, getSortedIds)
- Simplify component to UI wiring only
- Prepare for Alt+Up/Down model reordering feature

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 01:10:20 +01:00
ninlds
ec2b7b5a00 Add fuzzy search to settings list 2026-01-12 18:10:33 +01:00
Aliou Diallo
638fbc459b
feat(coding-agent): add page-up/down navigation to session selector (#662)
* feat(tui): add pageUp/pageDown key support and selectPageUp/selectPageDown actions

* feat(coding-agent): add page-up/down navigation to session selector
2026-01-12 17:01:46 +01:00
Mario Zechner
8f95a13e07 feat(coding-agent): add session naming via /name command and extension API
- Add SessionInfoEntry type for session metadata
- Add /name <name> command to set session display name
- Add pi.setSessionName() and pi.getSessionName() extension API
- Session selector shows name (in warning color) instead of first message when set
- Session name included in fuzzy search
- /session command displays name when set

closes #650
2026-01-12 16:56:39 +01:00
Aliou Diallo
4e6ae25505 fix(coding-agent): prevent session selector from closing immediately when current folder has no sessions
Remove auto-cancel in loadCurrentSessions() so users can press Tab to switch
to "all" scope. Add context-aware empty state messages.
2026-01-12 16:37:38 +01:00
Mario Zechner
50cd054edb Rework /scoped-models command UX
- Renamed from /models to /scoped-models
- Changes are now session-only by default (Ctrl+S to persist to settings)
- Added search with fuzzy filtering
- Hotkeys: Enter toggle, Ctrl+A enable all, Ctrl+X clear all, Ctrl+P toggle provider
- Ctrl+C clears search (or exits if empty), Escape exits
- Enabled models shown at top of list
- No checkmarks when all models enabled (no scope)
- First toggle when unscoped clears all and selects that model
- Uses current session thinking level instead of settings default
- Reads from session state first (preserves session-only changes across /scoped-models invocations)

Builds on #626
2026-01-12 00:53:52 +01:00
Mario Zechner
c16e21331a Preserve tree selection when returning from summary selector or abort 2026-01-12 00:15:12 +01:00
Armin Ronacher
62caf219a1 Hook up custom summarization on branch switch 2026-01-12 00:09:33 +01:00
Mario Zechner
9d49b4d4ed Merge branch 'tmp-2025-01-11' - resume scope toggle with async loading (#620) 2026-01-12 00:00:28 +01:00
Mario Zechner
302404684f feat(coding-agent): add resume scope toggle with async loading
- /resume and --resume now toggle between Current Folder and All sessions with Tab
- SessionManager.list() and listAll() are now async with optional progress callback
- Shows loading progress (e.g. Loading 5/42) while scanning sessions
- SessionInfo.cwd field shows session working directory in All view
- Lazy loading: All sessions only loaded when user presses Tab

closes #619

Co-authored-by: Thomas Mustier <mustierthomas@gmail.com>
2026-01-12 00:00:03 +01:00
Mario Zechner
df3f5f41c0 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
2026-01-11 23:12:31 +01:00
Thomas Mustier
e8d91f2bd4 feat(coding-agent): add resume scope toggle
refactor(coding-agent): refine session listing helpers
2026-01-11 20:51:20 +00:00
Carlos Gutierrez
49acd8e648 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
2026-01-11 19:36:36 +01:00
Mario Zechner
5db7cc693b fix: Model selector fuzzy search matches id + provider
Restores original behavior from 3de8e075. Allows multi-token queries
like 'opus anthropic' to match Anthropic models.
2026-01-11 18:04:57 +01:00
Mario Zechner
3592f9b7c9 fix: Model selector fuzzy search matches provider + id
Allows queries like 'anthropic opus' to match Anthropic models.
Previously only matched against model ID, so 'anthropic' token failed.
2026-01-11 18:00:52 +01:00
Mario Zechner
9655907624 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)
2026-01-11 17:56:11 +01:00
Armin Ronacher
5cf0490383 Add support for /model autocomplete 2026-01-10 20:32:16 +01:00
Jian Zhang
7a8ea9020f fix(coding-agent): show '(ctrl+o to collapse)' hint for bash output when expanded 2026-01-10 18:50:54 +08:00
Mario Zechner
22b2a18952
Merge pull request #600 from nicobailon/feature/footer-data-provider
feat(coding-agent): add FooterDataProvider for git branch and extension statuses
2026-01-09 22:46:23 +01:00
Mario Zechner
e8eb4c254a feat: add search parameter and auto-select to /model command
- /model <search> pre-filters selector or auto-selects on exact match
- Support provider/model syntax for disambiguation (e.g., /model openai/gpt-4)
- Auto-select logic moved to InteractiveMode to avoid selector UI flicker

Closes #587
2026-01-09 22:39:26 +01:00
Mario Zechner
e2d14cdc23 Add spacing before aborted messages 2026-01-09 21:48:43 +01:00
Nico Bailon
7b902612e9 feat(coding-agent): add FooterDataProvider for git branch and extension statuses
Expose data that extensions cannot otherwise access: git branch and
extension statuses from setStatus(). Token stats, model info, etc.
remain computable via ctx.sessionManager and ctx.model.
2026-01-09 07:39:30 -08:00
Mario Zechner
45a6c394ca Fix components not rebuilding content on theme change 2026-01-09 00:40:57 +01:00
Mario Zechner
f9064c2f69 feat(tui): add overlay compositing for ctx.ui.custom() (#558)
Adds overlay rendering capability to the TUI, enabling floating modal
components that render on top of existing content without clearing the screen.

- Add showOverlay(), hideOverlay(), hasOverlay() methods to TUI
- Implement ANSI-aware line compositing via extractSegments()
- Support overlay stack (multiple overlays, later on top)
- Add { overlay: true } option to ctx.ui.custom()
- Add overlay-test.ts example extension

Also fixes pre-existing bug where bash tool output cached visual lines
at fixed terminal width, causing crashes on terminal resize.

Co-authored-by: Nico Bailon <nico.bailon@gmail.com>
2026-01-08 22:40:42 +01:00
Mario Zechner
bbf0d92e8c feat(coding-agent): use built-in renderers for tool overrides without custom renderers
When overriding a built-in tool (read, bash, edit, write, grep, find, ls)
without providing renderCall/renderResult, the built-in renderer is now
used automatically. This allows wrapping built-in tools for logging or
access control without reimplementing the UI (syntax highlighting, diffs, etc.).
2026-01-08 18:52:33 +01:00
Thomas Mustier
01f15fcbd2 fix: show retry attempt count when aborting during retry
When aborting a retry attempt, surface the retry-aware abort message
in the assistant output and tool results instead of a generic "Aborted".

- Set errorMessage for aborted streaming messages
- Render abort message without forcing a leading newline when no content
2026-01-08 12:36:46 +00:00
Mario Zechner
09471ebc7d feat(coding-agent): add ctx.ui.setEditorComponent() extension API
- Add setEditorComponent() to ctx.ui for custom editor components
- Add CustomEditor base class for extensions (handles app keybindings)
- Add keybindings parameter to ctx.ui.custom() factory (breaking change)
- Add modal-editor.ts example (vim-like modes)
- Add rainbow-editor.ts example (animated text highlighting)
- Update docs: extensions.md, tui.md Pattern 7
- Clean up terminal on TUI render errors
2026-01-07 16:11:49 +01:00
Nico Bailon
77477f6166 feat(coding-agent): add timeout option to extension dialogs with live countdown
Extension UI dialogs (select, confirm, input) now support a timeout option
that auto-dismisses with a live countdown display. Simpler alternative to
manually managing AbortSignal for timed dialogs.

Also adds ExtensionUIDialogOptions type export and updates RPC mode to
forward timeout to clients.
2026-01-06 21:49:27 -08:00
Mario Zechner
c35a18b2b3 Export all UI components for extensions 2026-01-06 23:09:58 +01:00
Mario Zechner
d2f3b42deb fix: OAuth token refresh failure returns undefined instead of throwing
When OAuth refresh fails during model discovery, getApiKey() now returns
undefined instead of throwing. This allows the app to start and fall back
to other providers, so the user can /login to re-authenticate.

fixes #498
2026-01-06 20:57:42 +01:00
Mario Zechner
a1d0b1c151 Merge PR #492: Add blockImages setting
- Setting controls filtering at convertToLlm layer
- 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
2026-01-06 12:00:15 +01:00
Mario Zechner
1fc2a912d4 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
2026-01-06 11:59:09 +01:00
Kevin
6cb3135695 Fix status bar git branch detection in worktrees and submodules 2026-01-06 11:13:22 +01:00
Josh
b582a6b70d
feat(coding-agent): add blockImages setting to prevent image uploads 2026-01-06 00:34:23 -06:00
Mario Zechner
9c87eeb805 Fix Anthropic login not showing URL (showPrompt should not clear content) 2026-01-05 20:03:07 +01:00
Mario Zechner
9b12719ab1 Improve OAuth login UI with consistent dialog component
- Add LoginDialogComponent with proper borders (top/bottom DynamicBorder)
- Refactor all OAuth providers to use racing approach (browser callback vs manual paste)
- Add onEscape handler to Input component for cancellation
- Add abortable sleep for GitHub Copilot polling (instant cancel on Escape)
- Show OS-specific click hint (Cmd+click on macOS, Ctrl+click elsewhere)
- Clear content between login phases (fixes GitHub Copilot two-phase flow)
- Use InteractiveMode's showStatus/showError for result messages
- Reorder providers: Anthropic, ChatGPT, GitHub Copilot, Gemini CLI, Antigravity
2026-01-05 19:58:44 +01:00
Mario Zechner
c6fc084534 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
2026-01-05 01:43:35 +01:00
Helmut Januschka
c956a726ed 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
2026-01-04 18:13:28 +01:00
Mario Zechner
5c5084481b feat(coding-agent): clipboard image paste support via Ctrl+V (fixes #419) 2026-01-04 01:05:22 +01:00
Mario Zechner
f2b89d5ec5 Merge branch 'feat/ctrl-n-external-editor' - configurable keybindings (#405) 2026-01-03 22:51:12 +01:00
Mario Zechner
79c56475e0 Fix non-PNG images not displaying in Kitty protocol terminals
JPEG/GIF/WebP images were not rendering in terminals using the Kitty
graphics protocol (Kitty, Ghostty, WezTerm) because it requires PNG
format (f=100). Non-PNG images are now converted to PNG using sharp
before being sent to the terminal.
2026-01-03 16:58:57 +01:00
Helmut Januschka
7574fed2f2 feat: use keybindings in all selectors and lists
Update all selector/list components to use EditorKeybindingsManager:
- model-selector, session-selector, oauth-selector, user-message-selector
- hook-selector, hook-input, hook-editor, tree-selector
- select-list, settings-list, cancellable-loader

This allows users to configure selectUp, selectDown, selectConfirm,
selectCancel actions in keybindings.json
2026-01-03 08:23:56 +01:00
Helmut Januschka
8f2682578b feat: configurable keybindings for all editor and app actions
All keybindings configurable via ~/.pi/agent/keybindings.json

Editor actions:
- cursorUp, cursorDown, cursorLeft, cursorRight
- cursorWordLeft, cursorWordRight, cursorLineStart, cursorLineEnd
- deleteCharBackward, deleteCharForward, deleteWordBackward
- deleteToLineStart, deleteToLineEnd
- newLine, submit, tab
- selectUp, selectDown, selectConfirm, selectCancel

App actions:
- interrupt, clear, exit, suspend
- cycleThinkingLevel, cycleModelForward, cycleModelBackward
- selectModel, expandTools, toggleThinking, externalEditor

Also adds support for numpad Enter key (Kitty protocol codepoint 57414
and SS3 M sequence)

Example emacs-style keybindings.json:
{
  "cursorUp": ["up", "ctrl+p"],
  "cursorDown": ["down", "ctrl+n"],
  "cursorLeft": ["left", "ctrl+b"],
  "cursorRight": ["right", "ctrl+f"],
  "deleteCharForward": ["delete", "ctrl+d"],
  "cycleModelForward": "ctrl+o"
}
2026-01-03 08:23:56 +01:00
Mario Zechner
0f81b09625 Fix edit tool diff not showing in TUI
The async diff preview computation could race with tool execution,
causing editDiffPreview to contain an error (file already modified)
while the actual tool result had the correct diff in details.diff.

Fix: prioritize result.details.diff over editDiffPreview when the
tool has executed successfully. The preview is only used before
tool execution completes.
2026-01-03 04:23:59 +01:00
Mario Zechner
746ec9eb01 Add shell commands without context contribution (!! prefix)
Use !!command to execute bash commands that are shown in the TUI and
saved to session history but excluded from LLM context, compaction
summaries, and branch summaries.

- Add excludeFromContext field to BashExecutionMessage
- Filter excluded messages in convertToLlm()
- Parse !! prefix in interactive mode
- Use dim border color for excluded commands

fixes #414
2026-01-03 04:14:35 +01:00
Mario Zechner
42b1e06ad1 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
2026-01-03 01:59:08 +01:00
Mario Zechner
28fb502719 Add image auto-resize toggle to settings, changelog for #402 2026-01-03 00:42:02 +01:00