Commit graph

314 commits

Author SHA1 Message Date
Mario Zechner
d51770a63d fix(coding-agent): prevent full re-renders during write tool streaming
Move line count from header to footer to avoid changing the first line
during streaming, which was triggering full screen re-renders in the
TUI's differential rendering logic.
2026-01-02 01:11:06 +01:00
Mario Zechner
03159d2f4b Add agent state methods to CustomToolContext and fix abort signature
CustomToolContext now has:
- isIdle() - check if agent is streaming
- hasQueuedMessages() - check if user has queued messages
- abort() - abort current operation (fire-and-forget)

Changed abort() signature from Promise<void> to void in both
HookContext and CustomToolContext. The abort is fire-and-forget:
it calls session.abort() without awaiting, so the abort signal
is set immediately while waitForIdle() runs in the background.

Fixes #388
2026-01-02 00:31:23 +01:00
Mario Zechner
0d9fddec1e Split HookContext and HookCommandContext to prevent deadlocks
HookContext (all events):
- isIdle() - read-only state check
- hasQueuedMessages() - read-only state check
- abort() - fire-and-forget, does not wait

HookCommandContext (slash commands only):
- waitForIdle() - waits for agent to finish
- newSession(options?) - create new session
- branch(entryId) - branch from entry
- navigateTree(targetId, options?) - navigate session tree

Session control methods moved from HookAPI (pi.*) to HookCommandContext (ctx.*)
because they can deadlock when called from event handlers that run inside
the agent loop (tool_call, tool_result, context events).
2026-01-02 00:24:58 +01:00
Mario Zechner
ccdd7bd283 Add session management and agent state methods to hooks API
HookAPI additions:
- pi.newSession(options?) - create new session with optional setup callback
- pi.branch(entryId) - branch from a specific entry
- pi.navigateTree(targetId, options?) - navigate the session tree

HookContext additions:
- ctx.isIdle() - check if agent is streaming
- ctx.waitForIdle() - wait for agent to finish
- ctx.abort() - abort current operation
- ctx.hasQueuedMessages() - check for queued user messages

These enable hooks to programmatically manage sessions (handoff, templates)
and check agent state before showing interactive UI.

Fixes #388
2026-01-01 23:56:24 +01:00
Mario Zechner
484d7e06bb Consolidate session events: remove session_before_new/session_new, add reason field to switch events
- Remove session_before_new and session_new hook events
- Add reason: 'new' | 'resume' to session_before_switch and session_switch events
- Remove 'new' reason from custom tool onSession (use 'switch' for both /new and /resume)
- Rename reset() to newSession(options?) in AgentSession
- Add NewSessionOptions with optional parentSession for lineage tracking
- Rename branchedFrom to parentSession in SessionHeader
- Rename RPC reset command to new_session with optional parentSession
- Update example hooks to use new event structure
- Update documentation and changelog

Based on discussion in #293
2026-01-01 23:31:26 +01:00
Mario Zechner
6267720660 Add theme-configurable HTML export colors (from PR #387)
- Add optional 'export' section to theme JSON with pageBg, cardBg, infoBg
- If not specified, colors are auto-derived from userMessageBg
- Add export colors to dark.json and light.json
- Update theme-schema.json and TypeBox schema
- Add documentation to docs/theme.md
- Add margin-top back to tool-output for spacing between header and content
2026-01-01 22:21:40 +01:00
Mario Zechner
dccdf91b8c Add ctx.ui.theme getter for styling status text with theme colors
- Add theme property to HookUIContext interface
- Implement in interactive, RPC, and no-op contexts
- Add status-line.ts example hook
- Document styling with theme colors in hooks.md
2026-01-01 21:58:01 +01:00
Prateek Sunal
9b2aa4a683
Hooks can render custom status (#385)
* Add ctx.ui.setStatus(key, text) API for hooks to display status in footer

- Add setStatus to HookUIContext interface
- Implement in interactive mode (FooterComponent)
- Implement in RPC mode (fire-and-forget)
- Add no-op implementations for headless contexts
- Multiple statuses displayed on single line, sorted by key
- Supports ANSI styling (hooks handle their own colors)

* Remove setStatus from changelog for now

* Fix hook status API to follow TUI rules

- Sanitize status text: replace newlines, tabs, carriage returns with spaces
- Truncate combined status line to terminal width using truncateToWidth
- Update JSDoc to document sanitization and truncation behavior
- Remove unused createHookUIContext method
- Add missing setStatus to test mock

* Add setStatus to changelog

* Use dim ellipsis for hook status truncation for consistency with footer style

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-01-01 21:35:37 +01:00
Mario Zechner
506e63a969 Add thinkingText theme token, fix streaming toggle bug
- Add configurable thinkingText color for thinking blocks (defaults to muted)
- Make 'Thinking...' label italic when collapsed
- Fix Ctrl+T during streaming hiding the current message
- Track streamingMessage to properly re-render on toggle

Based on #366 by @paulbettner
2026-01-01 00:25:04 +01:00
Mario Zechner
6f7c10e323 Add setEditorText/getEditorText to hook UI context, improve custom() API
- Add setEditorText() and getEditorText() to HookUIContext for prompt generator pattern
- custom() now accepts async factories for fire-and-forget work
- Add CancellableLoader component to tui package
- Add BorderedLoader component for hooks with cancel UI
- Export HookAPI, HookContext, HookFactory from main package
- Update all examples to import from packages instead of relative paths
- Update hooks.md and custom-tools.md documentation

fixes #350
2026-01-01 00:04:56 +01:00
Mario Zechner
f0ab8db40f Expand pi.sendMessage and registerMessageRenderer docs in hooks.md
- sendMessage: document storage timing, LLM context, TUI display
- registerMessageRenderer: document renderer signature, return null for default
2025-12-31 14:34:30 +01:00
Mario Zechner
17ed3fa605 Update rpc.md to match actual implementation
- AppMessage -> AgentMessage
- compact response shows full CompactionResult fields
- auto_compaction_start includes reason field
- auto_compaction_end includes willRetry field
- Fix source file references
2025-12-31 13:53:45 +01:00
Mario Zechner
ee64d29487 Fix sdk.md and rpc.md to match actual API
- Remove incorrect prompt(AppMessage) overload
- Change AppMessage to AgentMessage
- Change null to undefined for optional returns
- sendHookMessage returns Promise<void>
- Update rpc.md for entryId change
2025-12-31 13:50:01 +01:00
Mario Zechner
8fb936853b Add sdk.md intro, update CHANGELOG for branch() change 2025-12-31 13:48:22 +01:00
Mario Zechner
8e1e99ca05 Change branch() to use entryId instead of entryIndex
- AgentSession.branch(entryId: string) now takes entry ID
- SessionBeforeBranchEvent.entryId replaces entryIndex
- getUserMessagesForBranching() returns entryId
- Update RPC types and client
- Update UserMessageSelectorComponent
- Update hook examples and tests
- Update docs (hooks.md, sdk.md)
2025-12-31 13:47:34 +01:00
Mario Zechner
027d39aa33 Update custom-compaction example to use serializeConversation
Also fix docs to show convertToLlm is needed first.
2025-12-31 13:24:23 +01:00
Mario Zechner
75269add96 Export serializeConversation and document in compaction.md
Shows how to convert messages to text for custom summarization.
2025-12-31 13:21:55 +01:00
Mario Zechner
84b663276d Add creation hints to docs and update system prompt
- System prompt now instructs to read docs AND examples, follow cross-refs
- Each doc starts with 'pi can create X. Ask it to build one.'
2025-12-31 13:16:44 +01:00
Mario Zechner
4a37760f17 Fix tui.md theme colors - add comprehensive list 2025-12-31 13:09:19 +01:00
Mario Zechner
feca0976eb Update tui.md theming section to show getMarkdownTheme usage 2025-12-31 13:06:52 +01:00
Mario Zechner
20fbf40fac Add tui.md and improve TUI documentation
- New tui.md covers component system for hooks and custom tools
- Update hooks.md intro with 'Key capabilities' highlighting UI
- Update custom-tools.md intro with 'Key capabilities' highlighting UI
- Reference tui.md from both docs
2025-12-31 13:05:59 +01:00
Mario Zechner
29e0ed9cd1 Improve hooks.md UI documentation
- Add 'Key capabilities' section highlighting UI features
- Expand ctx.ui docs with custom component details
- Reference snake.ts example for custom UI
2025-12-31 13:02:28 +01:00
Mario Zechner
88e39471ea 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.
2025-12-31 12:57:54 +01:00
Mario Zechner
bab343b8bc Update hooks.md: clarify session_before_tree, document all sessionManager methods 2025-12-31 12:44:52 +01:00
Mario Zechner
57b066f135 Add source file references to compaction.md and clarify session_before_tree behavior 2025-12-31 12:41:53 +01:00
Mario Zechner
d103af4ca2 Fix: cumulative file tracking applies to both compaction and branch summarization 2025-12-31 12:38:25 +01:00
Mario Zechner
67af9d707f Clarify that compaction/branch details are hook-customizable 2025-12-31 12:36:28 +01:00
Mario Zechner
dfc63a7bac Note settings.json for compaction settings in compaction.md 2025-12-31 12:35:45 +01:00
Mario Zechner
679343de55 Add compaction.md and rewrite hooks.md
- New compaction.md covers auto-compaction and branch summarization
- Explains cut points, split turns, data model, file tracking
- Documents session_before_compact and session_before_tree hooks

- Rewritten hooks.md matches actual API (separate event names)
- Correct ctx.ui.custom() signature (returns handle, not callback)
- Documents all session events including tree events
- Adds sessionManager and modelRegistry usage
- Updates all examples to use correct API
2025-12-31 12:33:13 +01:00
Mario Zechner
19c4182c21 Reorder execute params: (toolCallId, params, onUpdate, ctx, signal?)
Optional signal now at the end for cleaner API
2025-12-31 12:14:28 +01:00
Mario Zechner
4c9c453646 Update CHANGELOG, README, and custom-tools.md for new CustomTool API
- Add custom tools API rework to CHANGELOG breaking changes
- Update docs/custom-tools.md with new types and signatures
- Update README quick example with correct execute signature
2025-12-31 12:10:37 +01:00
Mario Zechner
ff78ac2f84 Replace custom tool dispose() with shutdown session event
Breaking change: CustomAgentTool.dispose() removed. Use onSession with
reason 'shutdown' instead for cleanup.

- Add 'shutdown' to SessionEvent.reason for custom tools
- Remove dispose() method from CustomAgentTool interface
- Make emitToolSessionEvent() public on AgentSession
- Emit shutdown event to tools in InteractiveMode.shutdown()
- Update custom-tools.md with new API and examples
2025-12-31 02:55:45 +01:00
Mario Zechner
450d77fb79 Update hooks.md and session.md for consolidated HookContext
- HookEventContext renamed to HookContext (used for events and commands)
- RegisteredCommand.handler: (ctx) -> (args, ctx)
- before_compact: previousCompactions -> branchEntries, model moved to ctx.model
- ctx.exec -> pi.exec in examples
- ctx.sessionFile -> ctx.sessionManager.getSessionFile()
- CompactionPreparation: document turnPrefixMessages, isSplitTurn, previousSummary
- session.md: clarify details field for compaction/branch summary
2025-12-31 02:40:31 +01:00
Mario Zechner
d36e0ea2ab Update SDK and RPC docs, remove outdated files
- Remove hooks-v2.md, session-tree.md, UNRELEASED_OLD.md
- sdk.md: Update hook API (sendMessage, appendEntry, registerCommand, etc.)
- sdk.md: Update SessionManager with tree API
- sdk.md: Update AgentSession interface
- rpc.md: Fix attachments -> images in prompt command
2025-12-31 00:46:52 +01:00
Mario Zechner
a9479458ee Update CHANGELOG.md and docs for session tree release
CHANGELOG.md:
- Add /tree command, context event, before_agent_start event
- Add ui.custom(), branch summarization, selectedBg theme color
- Add snake game example hook
- Add external contributions: CRLF fix, bash on Unix, clickable OAuth, error messages
- Update theme requirements (50 total colors)

session.md:
- Complete rewrite for v2 tree structure
- Document all entry types with examples
- Add SessionManager API reference

hooks.md:
- Replace pi.send() with pi.sendMessage()
- Add pi.appendEntry(), pi.registerCommand(), pi.registerMessageRenderer()
- Move exec() from ctx to pi.exec()
- Add ui.custom() for custom TUI components
- Add context and before_agent_start events
- Update before_compact event fields
- Add ctx.sessionManager and ctx.modelRegistry
2025-12-31 00:39:20 +01:00
Mario Zechner
c0bf7800d9 Update session-tree-plan.md: tree selector details, theme.md done, add Before Release section 2025-12-30 22:42:25 +01:00
Mario Zechner
ae351257b6 Fix tree selector: proper selectedBg theme color, correct filter logic
- Add selectedBg theme color for active line highlight
- Fix filter modes:
  - no-tools: default minus tool results (still hides label/custom)
  - user-only: just user messages
  - labeled-only: just labeled entries
  - all: everything
- Update theme.md with new color tokens (50 total)
2025-12-30 22:42:25 +01:00
Mario Zechner
e7d438b59d Mark tree selector improvements as complete in plan 2025-12-30 22:42:25 +01:00
Mario Zechner
04ce66951e Add tree selector improvement notes to plan 2025-12-30 22:42:25 +01:00
Mario Zechner
4a9c53347e Update session-tree-plan.md with completed items
- Branch Summary Design: complete with fromId, fromHook, details fields
- Entry Labels: UI display and /label command complete in tree-selector
- UI Commands: /branch and /tree complete
2025-12-30 22:42:24 +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
59ce62bffc Tree spec 2025-12-30 22:42:22 +01:00
Mario Zechner
f43969b31a Update plan: mark before_agent_start as complete 2025-12-30 22:42:22 +01:00
Mario Zechner
bbdc350394 Add reference to #330 (Dynamic Context Pruning) in plan
Documents why context event was added and notes the type
inconsistency between ContextEvent (AgentMessage[]) and
ContextEventResult (Message[])
2025-12-30 22:42:22 +01:00
Mario Zechner
ae614f93e3 Add investigation item for context event vs before_agent_start
Reference: #324

Documents:
- Current context event behavior (AgentMessage[], transient)
- Proposed before_agent_start event (persistent, TUI visible)
- Key differences table
- Open design questions
- Need to verify AgentMessage vs Message abstraction level
2025-12-30 22:42:22 +01:00
Mario Zechner
1721bb8398 Mark Hook API Changes as complete in plan 2025-12-30 22:42:21 +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
77fe3f1a13 Add context event for non-destructive message modification before LLM calls
- Add contextTransform option to Agent (runs before messageTransformer)
- Deep copy messages before passing to contextTransform (modifications are ephemeral)
- Add ContextEvent and ContextEventResult types
- Add emitContext() to HookRunner (chains multiple handlers)
- Wire up in sdk.ts when creating Agent with hooks

Enables dynamic context pruning: hooks can modify messages sent to LLM
without changing session data. See discussion #330.
2025-12-30 22:42:20 +01:00
Mario Zechner
9e165d1d81 Add context event TODO with dynamic context pruning example
Reference: https://github.com/badlogic/pi-mono/discussions/330
2025-12-30 22:42:20 +01:00
Mario Zechner
e25aef0594 Update plan: move exec to HookAPI, sessionManager/modelRegistry to contexts
- exec() moves from HookEventContext/HookCommandContext to HookAPI
- sessionManager/modelRegistry move from SessionEventBase to HookEventContext
- HookCommandContext keeps sessionManager/modelRegistry (command handlers need them)
- Both sendMessage and exec accessed via pi closure in command handlers
2025-12-30 22:42:19 +01:00