Commit Graph

183 Commits

  • Clean up browser-extension references from monorepo
    - Update README.md to reference sitegeist repo
    - Update CLAUDE.md to replace browser-extension with web-ui
    - Update packages/web-ui/README.md examples to point to sitegeist
    - Remove browser-extension exclude from tsconfig.json
    - Remove browser-extension from .claude/settings.local.json permissions
  • Remove browser-extension package (migrated to separate sitegeist repo)
    - Remove packages/browser-extension directory
    - Update package.json scripts to remove browser-ext from build and dev
    - Extension now lives at https://github.com/badlogic/sitegeist
    - Uses file: dependencies to pi-ai and pi-web-ui for development
  • Fix navigation tracking and ChatPanel window width initialization
    Navigation tracking fixes:
    - Filter out chrome-extension:// URLs to avoid triggering on extension internal pages
    - Fixes "Could not establish connection" errors when sidepanel URL updates
    - Remove unused currentTabUrl/currentTabIndex tracking variables
    
    ChatPanel layout fixes:
    - Fix windowWidth initialization (was 0 due to too-early evaluation)
    - Set windowWidth in connectedCallback after DOM connection
    - Add requestAnimationFrame to ensure width is measured after layout
    - Add debug logging for troubleshooting layout issues
    - Now properly respects BREAKPOINT (800px) for mobile vs desktop layout
  • Simplify navigation tracking - insert message on every active tab URL change
    - Remove complex agent busy state tracking
    - Remove checkAndInsertNavMessage helper and onBeforeSend logic
    - Directly insert navigation messages when tab URL changes (chrome.tabs.onUpdated)
    - Also insert when user switches to a different tab (chrome.tabs.onActivated)
    - Much simpler: every URL change = navigation message, no conditions
    - Fixes issue where browser_javascript navigation wasn't detected
  • Insert navigation messages when agent finishes working (after tool execution)
    - Track agent busy state: isStreaming OR pendingToolCalls.size > 0
    - When agent transitions from busy to idle, check for URL changes
    - Extract checkAndInsertNavMessage() helper function
    - Call helper from both onBeforeSend (user submit) and agent state subscription (post-tool)
    - Fixes issue where browser_javascript tool navigates page but no nav message inserted
    - Navigation messages now appear after tools that change window.location.href
  • Only insert navigation messages on user message submit, not during idle browsing
    - Remove automatic navigation message insertion from tab change listeners
    - Tab listeners now only track current tab state (currentTabUrl, currentTabIndex)
    - Navigation messages are only inserted via onBeforeSend callback when user submits
    - Prevents spam of navigation messages when user is just browsing without interacting with agent
  • Improve navigation message visibility and favicon handling
    - Add fallback favicon using Google's favicon service (s2/favicons API)
    - If both tab.favIconUrl and Google service fail, gracefully hide broken image
    - Enhance navigation message styling for better visibility:
      - Use accent colors (bg-accent/50 with border-accent) instead of muted secondary
      - Increase padding (px-3 py-2) and add vertical margin (my-2)
      - Add shadow-sm for subtle depth
      - Make title font-medium for better contrast
      - Use border-2 instead of border for more prominence
  • Fix SessionListDialog behavior and document PersistentStorageDialog bug
    - Fix SessionListDialog to not reload when user selects a session after deleting others
      - Track if dialog closed via selection vs other means
      - Only call delete callback if not closed via selection
      - Batch deletions to avoid reload on every delete
    - Comment out PersistentStorageDialog in both web-ui example and browser extension (TODO: fix)
    - Add Known Bugs section to both README.md files documenting PersistentStorageDialog issue
    - Clean up navigation tracking variable names in browser extension
  • Fix new session button and improve navigation message styling
    - Add ?new=true query param to prevent auto-loading latest session
    - Style navigation message as clickable badge with background
    - Add cursor-pointer, truncate, and max-width for proper text overflow
    - Click navigation message to open page in new tab
    - Show URL on hover
  • Add navigation message tracking to browser extension
    - Add onBeforeSend callback to ChatPanel and AgentInterface
    - Add onBeforeToolCall callback (for future permission dialogs)
    - Create NavigationMessage custom message type
    - Add browserMessageTransformer that converts nav messages to <system> tags
    - Track last submitted URL and tab index
    - Auto-insert navigation message when URL/tab changes on user submit
    - Navigation message shows favicon + page title in UI
    - LLM receives: <system>Navigated to [title] (tab X): [url]</system>
  • Add custom message extension system with typed renderers and message transformer
    - Implement CustomMessages interface for type-safe message extension via declaration merging
    - Add MessageRenderer<T> with generic typing for custom message rendering
    - Add messageTransformer to Agent for filtering/transforming messages before LLM
    - Move message filtering from transports to Agent (separation of concerns)
    - Add message renderer registry with typed role support
    - Update web-ui example with SystemNotificationMessage demo
    - Add custom transformer that converts notifications to <system> tags
    - Add SessionListDialog onDelete callback for active session cleanup
    - Handle non-existent session IDs in URL (redirect to new session)
    - Update both web-ui example and browser extension with session fixes
  • Refactor agent architecture and add session storage
    Major architectural improvements:
    - Renamed AgentSession → Agent (state/ → agent/)
    - Removed id field from AgentState
    - Fixed transport abstraction to pass messages directly instead of using callbacks
    - Eliminated circular dependencies in transport creation
    
    Transport changes:
    - Changed signature: run(messages, userMessage, config, signal)
    - Removed getMessages callback from ProviderTransport and AppTransport
    - Transports now filter attachments internally
    
    Session storage:
    - Added SessionRepository with IndexedDB backend
    - Auto-save sessions after first exchange
    - Auto-generate titles from first user message
    - Session list dialog with search and delete
    - Persistent storage permission dialog
    - Browser extension now auto-loads last session
    
    UI improvements:
    - ChatPanel creates single AgentInterface instance in setAgent()
    - Added drag & drop file upload to MessageEditor
    - Fixed artifacts panel auto-opening on session load
    - Added "Drop files here" i18n strings
    - Changed "Continue Without Saving" → "Continue Anyway"
    
    Web example:
    - Complete rewrite of main.ts with clean architecture
    - Added check script to package.json
    - Session management with URL state
    - Editable session titles
    
    Browser extension:
    - Added full session storage support
    - History and new session buttons
    - Auto-load most recent session on open
    - Session titles in header
  • Enable thinking selector in MessageEditor
    - Import Select component from mini-lit and Brain icon from lucide
    - Add thinkingLevel property to track current thinking level (off/minimal/low/medium/high)
    - Enable showThinkingSelector (was disabled before)
    - Add onThinkingChange callback for thinking level changes
    - Render Select component with thinking level options when model supports reasoning
    - Position thinking selector on left side next to attachment button
    - Add i18n translations for Off/Minimal/Low/Medium/High in English and German
    - Rename showThinking → showThinkingSelector in AgentInterface and ChatPanel for consistency
    - Remove showDebugToggle property from AgentInterface (unused)
    - Clean up browser-javascript tool output message (remove CSP note)
  • Add Anthropic prompt caching, pluggable storage, and CORS proxy support
    Storage Architecture:
    - New pluggable storage system with backends (LocalStorage, ChromeStorage, IndexedDB)
    - SettingsRepository for app settings (proxy config, etc.)
    - ProviderKeysRepository for API key management
    - AppStorage with global accessors (getAppStorage, setAppStorage, initAppStorage)
    
    Transport Refactoring:
    - Renamed DirectTransport → ProviderTransport (calls LLM providers with optional CORS proxy)
    - Renamed ProxyTransport → AppTransport (uses app server with user auth)
    - Updated TransportMode: "direct" → "provider", "proxy" → "app"
    
    CORS Proxy Integration:
    - ProviderTransport checks proxy.enabled/proxy.url from storage
    - When enabled, modifies model baseUrl to route through proxy: {proxyUrl}/?url={originalBaseUrl}
    - ProviderKeyInput test function also honors proxy settings
    - Settings dialog with Proxy tab (Switch toggle, URL input, explanatory description)
    
    Anthropic Prompt Caching:
    - System prompt cached with cache_control markers (both OAuth and regular API keys)
    - Last user message cached to cache conversation history
    - Saves 90% on input tokens for cached content (10x cost reduction)
    
    Settings Dialog Improvements:
    - Configurable tab system with SettingsTab base class
    - ApiKeysTab and ProxyTab as custom elements
    - Switch toggle for proxy enable (instead of Checkbox)
    - Explanatory paragraphs for each tab
    - ApiKeyPromptDialog reuses ProviderKeyInput component
    
    Removed:
    - Deprecated ApiKeysDialog (replaced by ProviderKeyInput in SettingsDialog)
    - Old storage-adapter and key-store (replaced by new storage architecture)
  • Integrate JailJS for CSP-restricted execution in browser extension
    Major changes:
    - Migrate browser-extension to use web-ui package (85% code reduction)
    - Add JailJS content script with ES6+ transform support
    - Expose DOM constructors (Event, KeyboardEvent, etc.) to JailJS
    - Support top-level await by wrapping code in async IIFE
    - Add returnFile() support in JailJS execution
    - Refactor KeyStore into pluggable storage-adapter pattern
    - Make ChatPanel configurable with sandboxUrlProvider and additionalTools
    - Update jailjs to 0.1.1
    
    Files deleted (33 duplicate files):
    - All browser-extension components, dialogs, state, tools, utils
    - Now using web-ui versions via @mariozechner/pi-web-ui
    
    Files added:
    - packages/browser-extension/src/content.ts (JailJS content script)
    - packages/web-ui/src/state/storage-adapter.ts
    - packages/web-ui/src/state/key-store.ts
    
    Browser extension now has only 5 source files (down from 38).
  • Add JavaScript REPL tool to web-ui package
    - Created javascript-repl.ts tool with SandboxedIframe for code execution
    - Integrated into ChatPanel replacing calculate and getCurrentTime tools
    - REPL provides full browser API access with external library support
    - Auto-registers renderer for tool output display
    - Uses srcdoc instead of sandbox.html (no CSP restrictions in web apps)
  • Fix race condition in web-ui SandboxedIframe
    Fixed loadContent() and execute() to set srcdoc at the correct time:
    - loadContent(): Now sets srcdoc after creating iframe (was missing entirely)
    - execute(): Now sets srcdoc after setting up message listeners and creating iframe (was setting before iframe existed)
    
    This prevents missing postMessage events from the sandboxed iframe.
  • feat: add cross-browser extension with AI reading assistant
    - Create Pi Reader browser extension for Chrome/Firefox
    - Chrome uses Side Panel API, Firefox uses Sidebar Action API
    - Supports both browsers with separate manifests and unified codebase
    - Built with mini-lit components and Tailwind CSS v4
    - Features model selection dialog with Ollama support
    - Hot reload development server watches both browser builds
    - Add useDefineForClassFields: false to fix LitElement reactivity
  • refactor(ai): improve error handling and stop reason types
    - Add 'aborted' as a distinct stop reason separate from 'error'
    - Change AssistantMessage.error to errorMessage for clarity
    - Update error event to include reason field ('error' | 'aborted')
    - Map provider-specific safety/refusal reasons to 'error' stop reason
    - Reorganize utility functions into utils/ directory
    - Rename agent.ts to agent-loop.ts for better clarity
    - Fix error handling in all providers to properly distinguish abort from error