Commit Graph

45 Commits

  • 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
  • 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
  • Export serializeConversation and document in compaction.md
    Shows how to convert messages to text for custom summarization.
  • Rework custom tools API with CustomToolContext
    - CustomAgentTool renamed to CustomTool
    - ToolAPI renamed to CustomToolAPI
    - ToolContext renamed to CustomToolContext
    - ToolSessionEvent renamed to CustomToolSessionEvent
    - Added CustomToolContext parameter to execute() and onSession()
    - CustomToolFactory now returns CustomTool<any, any> for type compatibility
    - dispose() replaced with onSession({ reason: 'shutdown' })
    - Added wrapCustomTool() to convert CustomTool to AgentTool
    - Session exposes setToolUIContext() instead of leaking internals
    - Fix ToolExecutionComponent to sync with toolOutputExpanded state
    - Update all custom tool examples for new API
  • Add ReadonlySessionManager and refactor branch summarization
    - Add ReadonlySessionManager interface to session-manager.ts
    - Re-export from hooks/index.ts
    - Add collectEntriesForBranchSummary() to extract entries for summarization
    - Don't stop at compaction boundaries (include their summaries as context)
    - Add token budget support to prepareBranchEntries()
    - Walk entries newest-to-oldest to prioritize recent context
    - Use options object for generateBranchSummary()
    - Handle compaction entries as context summaries
    - Export new types: CollectEntriesResult, GenerateBranchSummaryOptions
  • Improve branch summarization with preparation and file ops extraction
    - Add prepareBranchEntries() to extract messages and file operations
    - Extract read/write/edit operations from tool calls
    - Append static file operations section to summary
    - Improve prompt for branch summarization
    - Skip toolResult messages (context already in assistant message)
    - Export new types: BranchPreparation, FileOperations
  • Refactor: move compaction code to src/core/compaction/
    - Move compaction.ts to src/core/compaction/compaction.ts
    - Extract branch summarization to src/core/compaction/branch-summarization.ts
    - Add index.ts to re-export all compaction utilities
    - Update all imports across the codebase
  • 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.
  • Implement before_agent_start hook event
    - Add BeforeAgentStartEvent and BeforeAgentStartEventResult types
    - Add emitBeforeAgentStart to HookRunner
    - Call in AgentSession.prompt() before agent.prompt()
    - Hook can return a message to inject into context (persisted + visible)
    - Add test hook demonstrating custom message rendering and before_agent_start
  • 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
  • WIP: Major cleanup - move Attachment to consumers, simplify agent API
    - Removed Attachment from agent package (now in web-ui/coding-agent)
    - Agent.prompt now takes (text, images?: ImageContent[])
    - Removed transports from web-ui (duplicate of agent package)
    - Updated coding-agent to use local message types
    - Updated mom package for new agent API
    
    Remaining: Fix AgentInterface.ts to compose UserMessageWithAttachments
  • Add CustomMessageEntry for hook-injected messages in LLM context
    - CustomMessageEntry<T> type with customType, content, display, details
    - appendCustomMessageEntry() in SessionManager
    - buildSessionContext() includes custom_message entries as user messages
    - Exported CustomEntry and CustomMessageEntry from main index
    
    CustomEntry is for hook state (not in context).
    CustomMessageEntry is for hook-injected content (in context).
  • Make CompactionEntry and CompactionResult generic with details field
    - CompactionEntry<T> and CompactionResult<T> now have optional details?: T
    - appendCompaction() accepts optional details parameter
    - Hooks can return compaction.details to store custom data
    - Enables structured compaction with ArtifactIndex (see #314)
    - Fix CompactionResult export location (now from compaction.ts)
    - Update plan with remaining compaction refactor items
  • Session tree: simplify types, add branching API, comprehensive tests
    Types:
    - SessionEntryBase with type field, extended by all entry types
    - CustomEntry for hooks (type: 'custom', customType, data)
    - Remove XXXContent types and TreeNode (redundant)
    
    API:
    - Rename saveXXX to appendXXX with JSDoc explaining tree semantics
    - Rename branchInPlace to branch() with better docs
    - Add createBranchedSession(leafId) replacing index-based version
    - Add getTree() returning SessionTreeNode[] for tree traversal
    - Add appendCustomEntry(customType, data) for hooks
    
    Tests:
    - tree-traversal.test.ts: 28 tests covering append, getPath, getTree,
      branch, branchWithSummary, createBranchedSession
    - save-entry.test.ts: custom entry integration
    
    Docs:
    - Class-level JSDoc explaining append-only tree model
    - Method docs explaining leaf advancement and branching
    - CHANGELOG.md entry for all changes
  • Refactor session manager: migration chain, validation, tests
    - Add migrateV1ToV2/migrateToCurrentVersion for extensible migrations
    - createSummaryMessage now takes timestamp from entry
    - loadEntriesFromFile validates session header
    - findMostRecentSession only returns valid session files (reads first 512 bytes)
    - Remove ConversationEntry alias
    - Fix mom context.ts TreeNode type
    
    Tests:
    - migration.test.ts: v1 migration, idempotency
    - build-context.test.ts: 14 tests covering trivial, compaction, branches
    - file-operations.test.ts: loadEntriesFromFile, findMostRecentSession
  • Fix SessionEntry type to exclude SessionHeader
    - SessionEntry now only contains conversation entries (messages, compaction, etc.)
    - SessionHeader is separate, not part of SessionEntry
    - FileEntry = SessionHeader | SessionEntry (for file storage)
    - getEntries() filters out header, returns SessionEntry[]
    - Added getHeader() for accessing session metadata
    - Updated compaction and tests to not expect header in entries
    - Updated mom package to use FileEntry for internal storage
  • Session tree structure with id/parentId linking
    - Add TreeNode base type with id, parentId, timestamp
    - Add *Content types for clean input/output separation
    - Entry types are now TreeNode & *Content intersections
    - SessionManager assigns id/parentId on save, tracks leafId
    - Add migrateSessionEntries() for v1 to v2 conversion
    - Migration runs on load, rewrites file
    - buildSessionContext() uses tree traversal from leaf
    - Compaction returns CompactionResult (content only)
    - Hooks return compaction content, not full entries
    - Add firstKeptEntryId to before_compact hook event
    - Update mom package for tree fields
    - Better error messages for compaction failures
  • 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
  • WIP: Rename model-config.ts to models-json.ts
    - loadCustomModels now takes file path instead of agentDir
  • Add before/after session events with cancellation support
    - Merge branch event into session with before_branch/branch reasons
    - Add before_switch, before_clear, shutdown reasons
    - before_* events can be cancelled with { cancel: true }
    - Update RPC commands to return cancelled status
    - Add shutdown event on process exit
    - New example hooks: confirm-destructive, dirty-repo-guard, auto-commit-on-exit
    
    fixes #278
  • Fix SDK tools to respect cwd option
    Core tools now properly use the cwd passed to createAgentSession().
    Added tool factory functions for SDK users who specify custom cwd with explicit tools.
    
    Fixes #279
  • Add SDK usage examples
    12 examples showing increasing levels of customization:
    - 01-minimal: all defaults
    - 02-custom-model: model and thinking level
    - 03-custom-prompt: replace or modify prompt
    - 04-skills: discover, filter, merge skills
    - 05-tools: built-in tools, custom tools
    - 06-hooks: logging, blocking, result modification
    - 07-context-files: AGENTS.md files
    - 08-slash-commands: file-based commands
    - 09-api-keys-and-oauth: API key resolution, OAuth config
    - 10-settings: compaction, retry, terminal settings
    - 11-sessions: persistence options
    - 12-full-control: replace everything
    
    Also exports FileSlashCommand type from index.ts
  • Add agentDir parameter to model config functions and OAuth storage
    - loadAndMergeModels(agentDir) - loads models.json from agentDir
    - getAvailableModels(agentDir) - uses agentDir for model discovery
    - findModel(provider, id, agentDir) - uses agentDir for model lookup
    - configureOAuthStorage(agentDir) - configures OAuth to use agentDir/oauth.json
    - createAgentSession calls configureOAuthStorage with options.agentDir
    - Export configureOAuthStorage from SDK
  • 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
  • Refactor main.ts to use SDK createAgentSession
    - Add continueSession, restoreFromSession, additionalHookPaths,
      additionalCustomToolPaths, scopedModels to CreateAgentSessionOptions
    - Return CreateAgentSessionResult with session, customToolsResult,
      and modelFallbackMessage
    - main.ts now focuses on CLI arg parsing and mode routing
    - Reduced main.ts from ~490 to ~340 lines
  • Add SDK for programmatic AgentSession usage
    - Add src/core/sdk.ts with createAgentSession() factory and discovery functions
    - Update loaders to accept cwd/agentDir parameters (skills, hooks, custom-tools, slash-commands, system-prompt)
    - Export SDK from package index
    
    Addresses #272
  • 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
  • Export OAuth and model config functions for AgentSession scripts
    Exports getAvailableModels, getApiKeyForModel, findModel, login, logout,
    and getOAuthProviders from @mariozechner/pi-coding-agent so scripts using
    AgentSession directly can reuse OAuth token storage and model resolution.
    
    Fixes #245
  • Subagent: markdown rendering in expanded view, chain streaming shows all steps
    - Export getMarkdownTheme() from coding-agent for custom tools
    - Chain/parallel modes now use Markdown component in expanded view
    - Chain streaming updates include all previous steps (not just current)
    - Strip {previous} placeholder from task preview in renderCall
  • Add type guards for tool_result event narrowing
    - Export isBashToolResult, isReadToolResult, etc. type guards
    - Update hooks.md with type guard usage examples
    - Document custom tool handling in hooks.md
  • Expose full tool result content and details in hook tool_result event
    Breaking change: ToolResultEvent now exposes content and typed details
    instead of just a result string. Hook handlers returning { result: ... }
    must change to { content: [...] }.
    
    - ToolResultEvent is now a discriminated union based on toolName
    - Each built-in tool has typed details (BashToolDetails, etc.)
    - Export tool details types and TruncationResult
    - Update hooks.md documentation
    
    Closes #233
  • Skills standard compliance
    Implement Agent Skills standard (https://agentskills.io/specification):
    - Validate name (must match parent dir, lowercase, max 64 chars)
    - Validate description (required, max 1024 chars)
    - Warn on unknown frontmatter fields
    - Warn on name collisions (keep first)
    - Change prompt format to XML structure
    - Remove {baseDir} placeholder (use relative paths)
    - Add tests and update documentation
    
    fixes #231
  • 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
  • coding-agent, mom: add skills API export and mom skills auto-discovery
    coding-agent:
    - Export loadSkillsFromDir, formatSkillsForPrompt, and related types
    - Refactor skills.ts to expose public API
    
    mom:
    - Add skills auto-discovery from workspace/skills and channel/skills
    - Fix skill loading to use host paths (not Docker container paths)
    - Update README and system prompt with SKILL.md format docs
  • mom: refactor to use AgentSession for context management
    - Export AgentSession, SessionManager, SettingsManager, compaction from coding-agent
    - Create MomSessionManager for channel-based context.jsonl storage
    - Create MomSettingsManager for mom-specific settings
    - Refactor agent.ts to use AgentSession instead of ephemeral Agent
    - Split logging: tool results go to context.jsonl, human messages to log.jsonl
    - Enable auto-compaction and overflow detection from coding-agent
    
    Part of #115
  • Add hooks system with pi.send() for external message injection
    - Hook discovery from ~/.pi/agent/hooks/, .pi/hooks/, --hook flag
    - Events: session_start, session_switch, agent_start/end, turn_start/end, tool_call, tool_result, branch
    - tool_call can block execution, tool_result can modify results
    - pi.send(text, attachments?) to inject messages from external sources
    - UI primitives: ctx.ui.select/confirm/input/notify
    - Context: ctx.exec(), ctx.cwd, ctx.sessionFile, ctx.hasUI
    - Docs shipped with npm package and binary builds
    - System prompt references docs folder
  • 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.