Commit graph

1046 commits

Author SHA1 Message Date
Mario Zechner
affa618b43 docs: add note about macOS Finder image copy behavior 2026-01-04 20:52:51 +01:00
Mario Zechner
2a332f7064 docs: add changelog entries for symbol key support (#450) 2026-01-04 20:38:27 +01:00
Kao Félix
b836a9d2ee
feat(tui): add symbol key support to keybinding system (#450)
- Added SymbolKey type with 32 symbol keys
- Added symbol key constants to Key helper (Key.backtick, Key.comma, Key.period, etc.)
- Updated matchesKey() and parseKey() to handle symbol key input
- Added documentation in coding-agent README with examples
2026-01-04 20:37:08 +01:00
Mario Zechner
61cadc226c Add [Unreleased] section for next cycle 2026-01-04 20:30:34 +01:00
Mario Zechner
dc2f5d43cc Release v0.34.0 2026-01-04 20:29:50 +01:00
Mario Zechner
00fa8b71c8 revert: remove unnecessary themeOverride params from theme functions
The optional theme parameter was added as a workaround for tsx dev mode,
but that's a dev-only issue. Users running the built package don't need it.
2026-01-04 20:27:46 +01:00
Mario Zechner
7302fe5063 docs: remove dev-only changelog entry 2026-01-04 20:26:29 +01:00
Mario Zechner
5318b42bd2 docs: update CHANGELOG and hooks.md with missing items
- tools.ts example hook
- Multiple messages from before_agent_start
- getSettingsListTheme/getSelectListTheme optional theme param
- Hook error stack traces
2026-01-04 19:01:35 +01:00
Mario Zechner
b06bd1d24c fix(tools.ts): sync with active tools when no saved state
Hook was showing all tools as enabled even though only 4 were active.
Now initializes from pi.getActiveTools() to match actual state.
2026-01-04 18:50:45 +01:00
Mario Zechner
31438fdf2a fix(tools): wrap ALL registry tools with hooks, not just active ones
wrappedToolRegistry was only containing activeToolsArray (4 tools).
Now wraps all tools from the registry so hooks can enable any tool.
2026-01-04 18:47:57 +01:00
Mario Zechner
2849623afc fix(tools): tool registry now contains ALL built-in tools
- createAllTools() populates registry with all 7 built-in tools
- --tools flag only sets initially active tools (default: read/bash/edit/write)
- Hooks can enable any tool from registry via setActiveTools()
- System prompt rebuilds with correct tool guidelines when tools change
- Document tsx module resolution workaround in README
2026-01-04 18:44:41 +01:00
Mario Zechner
c447e62662 fix(theme): add optional themeOverride param to getSettingsListTheme/getSelectListTheme
When hooks are loaded via jiti, they get a separate module instance from
the main app. This means the global 'theme' variable in the hook's module
is never initialized. Adding an optional theme parameter allows hooks to
pass the theme from ctx.ui.custom() callback.

Usage in hooks:
  getSettingsListTheme(theme)  // theme from ctx.ui.custom callback
2026-01-04 18:39:00 +01:00
Mario Zechner
6390ff87ef fix(hooks): add stack traces to hook errors, fix tools.ts theme bug
- HookError now includes optional stack field
- Hook error display shows stack trace in dim color below error message
- tools.ts: create SettingsListTheme using the theme passed to ctx.ui.custom()
  instead of using getSettingsListTheme() which depends on global theme
2026-01-04 18:33:28 +01:00
Mario Zechner
e4dd21a3b2 feat(hooks): add systemPromptAppend to before_agent_start, full tool registry
- before_agent_start handlers can return systemPromptAppend to dynamically
  append text to the system prompt for that turn
- Multiple hooks' systemPromptAppend strings are concatenated
- Multiple hooks' messages are now all injected (not just first)
- Tool registry now contains ALL built-in tools (read, bash, edit, write,
  grep, find, ls) regardless of --tools flag
- --tools only sets initially active tools, hooks can enable any via
  setActiveTools()
- System prompt automatically rebuilds when tools change, updating tool
  descriptions and guidelines
- Add pirate.ts example hook demonstrating systemPromptAppend
- Update hooks.md with systemPromptAppend documentation
2026-01-04 18:21:26 +01:00
Mario Zechner
892acedb6b feat(hooks): add tools.ts example hook for interactive tool enable/disable
- /tools command opens SettingsList-based selector for all loaded tools
- Space/Enter toggles individual tools between enabled/disabled
- Changes apply immediately on toggle (like /settings)
- Tool selection persisted to session via appendEntry()
- State restored from current branch on session_start, session_tree, session_branch
- Uses getBranch() to respect branch-specific tool configuration
- Export getSettingsListTheme and getSelectListTheme for hooks to use
2026-01-04 18:13:30 +01:00
Mario Zechner
ddf8bfceee fix(hooks): deep copy messages in context event before passing to hooks
The context event handler documentation promised a deep copy but the
implementation passed the original array reference. This could cause
hooks to accidentally mutate session messages.

Uses structuredClone() for fast native deep copying.
2026-01-04 18:13:30 +01:00
Helmut Januschka
8ecb1d6c0b refactor: address PR feedback - merge setWidget, use KeyId for shortcuts
1. Merge setWidget and setWidgetComponent into single overloaded method
   - Accepts either string[] or component factory function
   - Uses single Map<string, Component> internally
   - String arrays wrapped in Container with Text components

2. Use KeyId type for registerShortcut instead of plain string
   - Import Key from @mariozechner/pi-tui
   - Update plan-mode example to use Key.shift('p')
   - Type-safe shortcut registration

3. Fix tool API docs
   - Both built-in and custom tools can be enabled/disabled
   - Removed incorrect 'custom tools always active' statement

4. Use matchesKey instead of matchShortcut (already done in rebase)
2026-01-04 18:13:30 +01:00
Helmut Januschka
c1d7f8d962 fix: use robust matchShortcut from TUI library
- Add matchShortcut() function to @mariozechner/pi-tui
- Handles Kitty protocol, legacy terminal sequences, and lock keys
- Supports special keys (enter, tab, space, backspace, escape)
- Replace custom implementation in interactive-mode.ts
- Remove unused imports
2026-01-04 18:13:29 +01:00
Helmut Januschka
277d7bd83b fix: remove inline imports and debug logging
- Convert all inline import() types to top-level imports
- Remove debug console.error statements from plan-mode hook
2026-01-04 18:13:29 +01:00
Helmut Januschka
a169029a16 fix(plan-mode): handle non-tool steps and clean up todo text
- Non-tool turns (analysis, explanation) now mark step complete at turn_end
- Clean up extracted step text: remove markdown, truncate to 50 chars
- Remove redundant action words (Use, Run, Execute, etc.)
- Track toolsCalledThisTurn flag to distinguish tool vs non-tool turns
2026-01-04 18:13:29 +01:00
Helmut Januschka
fdcc044491 fix(plan-mode): track step completion via tool_result events
- No longer relies on agent outputting [STEP N DONE] tags
- Each successful tool_result marks the next uncompleted step done
- Much more reliable than expecting LLM to follow tag format
- Simplified execution context (no special instructions needed)
2026-01-04 18:13:29 +01:00
Helmut Januschka
361292d4de fix(plan-mode): use step numbers instead of random IDs
- Steps are numbered 1, 2, 3... which is easier for agent to track
- Agent outputs [STEP 1 DONE], [STEP 2 DONE] instead of [DONE:abc123]
- Clearer instructions in execution context
2026-01-04 18:13:29 +01:00
Helmut Januschka
20ce41e767 fix(plan-mode): make DONE tag instruction clearer
- Number steps and show id=xxx format
- Clearer instruction to output [DONE:id] after each step
2026-01-04 18:13:29 +01:00
Helmut Januschka
609d1751c5 debug: add logging to plan-mode hook to trace context filtering 2026-01-04 18:13:29 +01:00
Helmut Januschka
274d4a6247 fix(hooks): fix ContextEventResult.messages type to AgentMessage[]
- Was incorrectly typed as Message[] which caused filtered messages to be ignored
- Context event filter in plan-mode hook should now properly remove stale [PLAN MODE ACTIVE] messages
2026-01-04 18:13:29 +01:00
Helmut Januschka
650d8f2615 fix(plan-mode): use context event to filter stale plan mode messages
- Filter out old [PLAN MODE ACTIVE] and [EXECUTING PLAN] messages
- Fresh context injected via before_agent_start with current state
- Agent now correctly sees tools are enabled when executing
- Reverted to ID-based tracking with [DONE:id] tags
- Simplified execution message (no need to override old context)
2026-01-04 18:13:29 +01:00
Helmut Januschka
f1792d04c4 fix(plan-mode): make execution mode clearer to agent
- Add explicit [PLAN MODE DISABLED - EXECUTE NOW] message
- Emphasize FULL access to all tools in execution context
- List remaining steps in execution context
- Prevents agent from thinking it's still restricted
2026-01-04 18:13:29 +01:00
Helmut Januschka
ce88ebcd68 feat(hooks): add setWidgetComponent for custom TUI components
- New ctx.ui.setWidgetComponent(key, factory) method
- Allows custom Component to render as widget without taking focus
- Unlike custom(), widget components render inline above editor
- Components are disposed when cleared or replaced
- Falls back to no-op in RPC/print modes
2026-01-04 18:13:29 +01:00
Helmut Januschka
9b53b89bd5 fix(widgets): add max line limit and document multi-hook behavior
- Limit total widget lines to 10 to prevent viewport overflow/flicker
- Show '... (widget truncated)' when limit exceeded
- Document that multiple hooks stack widgets vertically
- Add caution about keeping widgets small
2026-01-04 18:13:29 +01:00
Helmut Januschka
f6b728a6e5 refactor(plan-mode): use smart keyword matching instead of IDs
- Remove ugly [DONE:id] tags - users no longer see IDs
- Track progress via keyword matching on tool results
- Extract significant keywords from todo text
- Match tool name + input against todo keywords
- Sequential preference: first uncompleted item gets bonus score
- Much cleaner UX - progress tracked silently in background
2026-01-04 18:13:29 +01:00
Helmut Januschka
4ecf3f9422 refactor(hooks): address PR feedback
- Rename getTools/setTools to getActiveTools/setActiveTools
- Add getAllTools to enumerate all configured tools
- Remove text_delta event (use turn_end/agent_end instead)
- Add shortcut conflict detection:
  - Skip shortcuts that conflict with built-in shortcuts (with warning)
  - Log warnings when hooks register same shortcut (last wins)
- Add note about prompt cache invalidation in setActiveTools
- Update plan-mode hook to use agent_end for [DONE:id] parsing
2026-01-04 18:13:29 +01:00
Helmut Januschka
5b634ddf75 feat(plan-mode): show final completed list in chat when plan finishes
Displays all completed items with strikethrough markdown when
all todos are done.
2026-01-04 18:13:29 +01:00
Helmut Januschka
e27a2c226c fix(plan-mode): buffer text_delta to handle split [DONE:id] patterns
The [DONE:id] pattern may be split across multiple streaming chunks.
Now accumulates text in a buffer and scans for complete patterns.
2026-01-04 18:13:28 +01:00
Helmut Januschka
d1eea3ac4e feat(hooks): add text_delta event for streaming text monitoring
- New text_delta hook event fires for each chunk of streaming text
- Enables real-time monitoring of agent output
- Plan-mode hook now updates todo progress as [DONE:id] tags stream in
- Each todo item has unique ID for reliable tracking
2026-01-04 18:13:28 +01:00
Helmut Januschka
7a03f57fbe feat(plan-mode): use ID-based todo tracking with [DONE:id] tags
- Each todo item gets a unique ID (e.g., abc123)
- Agent marks items complete by outputting [DONE:id]
- IDs shown in chat and in execution context
- Agent instructed to output [DONE:id] after each step
- Removed unreliable tool-counting heuristics
2026-01-04 18:13:28 +01:00
Helmut Januschka
e781c9a466 feat(plan-mode): show todo list in chat after planning, widget during execution
- After agent creates plan: show todo list as a message in chat
- During execution: show widget under Working indicator with checkboxes
- Check off items as they complete with strikethrough
2026-01-04 18:13:28 +01:00
Helmut Januschka
c09f8644be fix(plan-mode): fix todo extraction from assistant messages
- AssistantMessage.content is an array, not string
- Handle markdown bold formatting in numbered lists
- Extract text content blocks properly
2026-01-04 18:13:28 +01:00
Helmut Januschka
dd7c01a47c fix(plan-mode): show widget after extracting todos and in plan mode 2026-01-04 18:13:28 +01:00
Helmut Januschka
dc44816051 feat(hooks): add setWidget API for multi-line status displays
- ctx.ui.setWidget(key, lines) for multi-line displays above editor
- Widgets appear below 'Working...' indicator, above editor
- Supports ANSI styling including strikethrough
- Added theme.strikethrough() method
- Plan-mode hook now shows todo list with checkboxes
- Completed items show checked box and strikethrough text
2026-01-04 18:13:28 +01:00
Helmut Januschka
537d672f17 feat(plan-mode): add todo list extraction and progress tracking
- Extract numbered steps from agent's plan response
- Track progress during execution with footer indicator (📋 2/5)
- /todos command to view current plan progress
- State persists across sessions including todo progress
- Agent prompted to format plans as numbered lists for tracking
2026-01-04 18:13:28 +01:00
Helmut Januschka
09048681b8 docs: update changelog with full hook API additions 2026-01-04 18:13:28 +01:00
Helmut Januschka
056f40b00b feat(coding-agent): show hook shortcuts in /hotkeys command 2026-01-04 18:13:28 +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
Helmut Januschka
059292ead1 WIP: Add hook API for dynamic tool control with plan-mode hook example
- Add pi.getTools() and pi.setTools(toolNames) to HookAPI
- Hooks can now enable/disable tools dynamically
- Changes take effect on next agent turn

New example hook: plan-mode.ts
- Claude Code-style read-only exploration mode
- /plan command toggles plan mode on/off
- Plan mode tools: read, bash, grep, find, ls
- Edit/write tools disabled in plan mode
- Injects context telling agent about restrictions
- After each response, prompts to execute/stay/refine
- State persists across sessions
2026-01-04 18:13:28 +01:00
Armin Ronacher
5b95ccf830
Add consistent, configurable image placeholders (#442)
* Add consistent, configurable image placeholders

* Kill the placeholders
2026-01-04 18:12:55 +01:00
Aliou Diallo
0d477d39f9
fix(tui): expand paste markers when opening external editor (#444)
* fix(tui): expand paste markers when opening external editor

Add getExpandedText() method to Editor that substitutes paste markers
with actual content. Use it in Ctrl-G external editor flow so users
see full pasted content instead of [paste #N ...] placeholders.

* docs: add changelog entries for #444
2026-01-04 18:11:42 +01:00
Can Bölük
6ddfd1be13
fix(coding-agent): resolved UTF-8 corruption in bash executor output (#433)
- Fixed UTF-8 text corruption in bash executor by replacing Buffer.toString() with streaming TextDecoder.
2026-01-04 03:15:50 +01:00
Mario Zechner
7e2a99b485 Add [Unreleased] section for next cycle 2026-01-04 01:08:11 +01:00
Mario Zechner
faa10b9a7e Release v0.33.0 2026-01-04 01:07:24 +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