Commit Graph

201 Commits

  • Implement unified storage architecture
    - Replace fragmented storage backends with single IndexedDBStorageBackend
    - Create multi-store StorageBackend interface (storeName parameter)
    - Remove old backends: IndexedDBBackend, LocalStorageBackend, SessionIndexedDBBackend, WebExtensionStorageBackend
    - Remove old repositories: ProviderKeysRepository, SessionRepository, SettingsRepository
    - Simplify AppStorage to directly expose storage methods (getSetting/setSetting, getProviderKey/setProviderKey)
    - Create SessionsRepository for session-specific operations
    - Update all consumers to use new simplified API
    - Update example app to use new storage architecture
    - Benefits: 10GB+ quota (vs 10MB chrome.storage), single database, consistent API
  • Fix spinner showing on aborted tool calls in javascript-repl and artifacts renderers
    When isStreaming is false and there's no result (aborted state), show 'complete' state instead of 'inprogress' to avoid showing the spinner.
  • Prevent default and stop propagation when clicking artifact pill
    This prevents the collapsible header from toggling when the pill is clicked.
  • Make renderHeader and renderCollapsibleHeader accept string | TemplateResult
    - Update renderHeader and renderCollapsibleHeader in renderer-registry.ts to accept `text: string | TemplateResult`
    - Remove duplicated renderCollapsibleHeaderWithPill helper in artifacts-tool-renderer.ts
    - Update all artifact renderer calls to use renderHeaderWithPill() inline
    - Remove all separate pill rendering below headers
    
    This allows artifact pills to be rendered inline with header text without code duplication.
  • Add clickable artifact pills to tool renderer
    - Create ArtifactPill component (similar to SkillPill)
    - Renders filename as clickable pill with FileCode2 icon
    - Clicking pill opens artifacts panel and selects that artifact
    - Update ArtifactsToolRenderer to accept artifactsPanel reference
    - Pass artifactsPanel from ChatPanel to renderer on initialization
    - Display artifact pill below header for all commands
    - Pill only clickable when artifactsPanel reference is available
  • Update artifacts-tool-renderer to use collapsible headers
    - All actions except DELETE now use collapsible headers
    - CREATE/UPDATE/REWRITE/GET/LOGS: code/output collapsed by default
    - DELETE: keeps simple non-collapsible header
    - Fix isStreaming parameter usage for proper spinner state
    - Add smooth 300ms animation on expand/collapse
    - Full header is clickable to toggle collapse state
  • Make entire collapsible header clickable
    - Changed outer div to button element
    - Added w-full and text-left classes
    - Now click anywhere on header (icon, text, chevron) to expand/collapse
  • Add collapsible tool renderers with animated expand/collapse
    - Add renderCollapsibleHeader() to renderer-registry
      - Places chevron on right, spinner on left
      - Toggles between ChevronRight (collapsed) and ChevronDown (expanded)
      - Uses max-h-0/max-h-[2000px] with transition-all for smooth animation
      - Dynamically adds/removes mt-3 to avoid margin when collapsed
    
    - Update javascript-repl renderer to use collapsible sections
      - Code and console output hidden by default
      - Only file attachments remain visible
      - 300ms smooth animation on expand/collapse
    
    - Export renderCollapsibleHeader from web-ui index
  • Refactor artifacts renderer and add Console component
    - Extract ArtifactsToolRenderer from ArtifactsPanel into standalone renderer
    - Fix ChatPanel to register ArtifactsToolRenderer instead of panel
    - Implement command-specific rendering logic (create/update/rewrite/get/logs/delete)
    - Create reusable Console component with copy button and autoscroll toggle
    - Replace custom console implementation with ExpandableSection and Console
    - Fix Lit reactivity for HtmlArtifact logs using spread operator
    - Add Lucide icons (FileCode2, ChevronsDown, Lock) for UI consistency
    - Follow skill.ts patterns with renderHeader and state handling
    - Add i18n strings for all artifact actions and console features
  • Rename ChromeStorageBackend to WebExtensionStorageBackend for cross-browser support
    - Rename chrome-storage-backend.ts to web-extension-storage-backend.ts
    - Update to use globalThis.browser || globalThis.chrome for Firefox/Chrome compatibility
    - Export both names for backward compatibility
    - Fix tsc --preserveWatchOutput in web-ui dev script to prevent console clearing
    
    This fixes the "browser is not defined" error in Chrome extensions.
  • Make mini-lit a peer dependency in pi-web-ui
    - Move mini-lit from dependencies to peerDependencies
    - Keep in devDependencies for development
    - Prevents bundlers from including mini-lit when consuming pi-web-ui
    - Consumer (sitegeist) provides mini-lit, esbuild bundles it once
    - Fixes duplicate mini-lit bundling issue permanently
  • 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.