This commit implements two major features: 1. Integration Search as Primary AI Data Source - Confluence, ServiceNow, and Azure DevOps searches execute before AI queries - Search results injected as system context for AI providers - Parallel search execution for performance - Webview-based fetch for HttpOnly cookie support - Persistent browser windows maintain authenticated sessions 2. AI Tool-Calling (Function Calling) - Allows AI to automatically execute functions during conversation - Implemented for OpenAI-compatible providers and Custom REST provider - Created add_ado_comment tool for updating Azure DevOps tickets - Iterative tool-calling loop supports multi-step workflows - Extensible architecture for adding new tools Key Files: - src-tauri/src/ai/tools.rs (NEW) - Tool definitions - src-tauri/src/integrations/*_search.rs (NEW) - Integration search modules - src-tauri/src/integrations/webview_fetch.rs (NEW) - HttpOnly cookie workaround - src-tauri/src/commands/ai.rs - Tool execution and integration search - src-tauri/src/ai/openai.rs - Tool-calling for OpenAI and Custom REST provider - All providers updated with tools parameter support Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
10 KiB
Ticket Summary - Persistent Browser Windows for Integration Authentication
Description
Implement persistent browser window sessions for integration authentication (Confluence, Azure DevOps, ServiceNow). Browser windows now persist across application restarts, eliminating the need to extract HttpOnly cookies via JavaScript (which fails due to browser security restrictions).
This follows a Playwright-style "piggyback" authentication approach where the browser window maintains its own internal cookie store, allowing the user to log in once and have the session persist indefinitely until they manually close the window.
Acceptance Criteria
- Integration browser windows persist to database when created
- Browser windows are automatically restored on app startup
- Cookies are maintained automatically by the browser's internal store (no JavaScript extraction of HttpOnly cookies)
- Windows can be manually closed by the user, which removes them from persistence
- Database migration creates
persistent_webviewstable - Window close events are handled to update database and in-memory tracking
Work Implemented
1. Database Migration for Persistent Webviews
Files Modified:
src-tauri/src/db/migrations.rs:154-167
Changes:
- Added migration
013_create_persistent_webviewsto create thepersistent_webviewstable - Table schema includes:
id(TEXT PRIMARY KEY)service(TEXT with CHECK constraint for 'confluence', 'servicenow', 'azuredevops')webview_label(TEXT - the Tauri window identifier)base_url(TEXT - the integration base URL)last_active(TEXT timestamp, defaults to now)window_x,window_y,window_width,window_height(INTEGER - for future window position persistence)- UNIQUE constraint on
service(one browser window per integration)
2. Webview Persistence on Creation
Files Modified:
src-tauri/src/commands/integrations.rs:531-591
Changes:
- Modified
authenticate_with_webviewcommand to persist webview state to database after creation - Stores service name, webview label, and base URL
- Logs persistence operation for debugging
- Sets up window close event handler to remove webview from tracking and database
- Event handler properly clones Arc fields for
'staticlifetime requirement - Updated success message to inform user that window persists across restarts
3. Webview Restoration on App Startup
Files Modified:
src-tauri/src/commands/integrations.rs:793-865- Addedrestore_persistent_webviewsfunctionsrc-tauri/src/lib.rs:60-84- Added.setup()hook to call restoration
Changes:
- Added
restore_persistent_webviewsasync function that:- Queries
persistent_webviewstable for all saved webviews - Recreates each webview window by calling
authenticate_with_webview - Updates in-memory tracking map
- Removes from database if restoration fails
- Logs all operations for debugging
- Queries
- Updated
lib.rsto call restoration in.setup()hook:- Clones Arc fields from
AppStatefor'staticlifetime - Spawns async task to restore webviews
- Logs warnings if restoration fails
- Clones Arc fields from
4. Window Close Event Handling
Files Modified:
src-tauri/src/commands/integrations.rs:559-591
Changes:
- Added
on_window_eventlistener to detect window close events - On
CloseRequestedevent:- Spawns async task to clean up
- Removes service from in-memory
integration_webviewsmap - Deletes entry from
persistent_webviewsdatabase table - Logs all cleanup operations
- Properly handles Arc cloning to avoid lifetime issues in spawned task
5. Removed Auto-Close Behavior
Files Modified:
src-tauri/src/commands/integrations.rs:606-618
Changes:
- Removed automatic window closing in
extract_cookies_from_webview - Windows now stay open after cookie extraction
- Updated success message to inform user that window persists for future use
6. Frontend UI Update - Removed "Complete Login" Button
Files Modified:
src/pages/Settings/Integrations.tsx:371-409- Updated webview authentication UIsrc/pages/Settings/Integrations.tsx:140-165- SimplifiedhandleConnectWebviewsrc/pages/Settings/Integrations.tsx:167-200- RemovedhandleCompleteWebviewLoginfunctionsrc/pages/Settings/Integrations.tsx:16-26- Removed unusedextractCookiesFromWebviewCmdimportsrc/pages/Settings/Integrations.tsx:670-677- Updated authentication method comparison text
Changes:
- Removed "Complete Login" button that tried to extract cookies via JavaScript
- Updated UI to show success message when browser opens, explaining persistence
- Removed confusing two-step flow (open browser → complete login)
- New flow: click "Open Browser" → log in → leave window open (that's it!)
- Updated description text to explain persistent window behavior
- Mark integration as "connected" immediately when browser opens
- Removed unused function and import for cookie extraction
7. Unused Import Cleanup
Files Modified:
src-tauri/src/integrations/webview_auth.rs:2src-tauri/src/lib.rs:13- Addeduse tauri::Manager;
Changes:
- Removed unused
Listenerimport from webview_auth.rs - Added
Managertrait import to lib.rs for.state()method
Testing Needed
Manual Testing
-
Initial Browser Window Creation
- Navigate to Settings > Integrations
- Configure a Confluence integration with base URL
- Click "Open Browser" button
- Verify browser window opens with Confluence login page
- Complete login in the browser window
- Verify window stays open after login
-
Window Persistence Across Restarts
- With Confluence browser window open, close the main application
- Relaunch the application
- Verify Confluence browser window is automatically restored
- Verify you are still logged in (cookies maintained)
- Navigate to different pages in Confluence to verify session works
-
Manual Window Close
- With browser window open, manually close it (X button)
- Restart the application
- Verify browser window does NOT reopen (removed from persistence)
-
Database Verification
- Open database:
sqlite3 ~/Library/Application\ Support/trcaa/data.db - Run:
SELECT * FROM persistent_webviews; - Verify entry exists when window is open
- Close window and verify entry is removed
- Open database:
-
Multiple Integration Windows
- Open browser window for Confluence
- Open browser window for Azure DevOps
- Restart application
- Verify both windows are restored
- Close one window
- Verify only one is removed from database
- Restart and verify remaining window still restores
-
Cookie Persistence (No HttpOnly Extraction Needed)
- Log into Confluence browser window
- Close main application
- Relaunch application
- Navigate to a Confluence page that requires authentication
- Verify you are still logged in (cookies maintained by browser)
Automated Testing
# Type checking
npx tsc --noEmit
# Rust compilation
cargo check --manifest-path src-tauri/Cargo.toml
# Rust tests
cargo test --manifest-path src-tauri/Cargo.toml
# Rust linting
cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
Edge Cases to Test
- Application crash while browser window is open (verify restoration on next launch)
- Database corruption (verify graceful handling of restore failures)
- Window already exists when trying to create duplicate (verify existing window is focused)
- Network connectivity lost during window restoration (verify error handling)
- Multiple rapid window open/close cycles (verify database consistency)
Architecture Notes
Design Decision: Persistent Windows vs Cookie Extraction
Problem: HttpOnly cookies cannot be accessed via JavaScript (document.cookie), which broke the original cookie extraction approach for Confluence and other services.
Solution: Instead of extracting cookies, keep the browser window alive across app restarts:
- Browser maintains its own internal cookie store (includes HttpOnly cookies)
- Cookies are automatically sent with all HTTP requests from the browser
- No need for JavaScript extraction or manual token management
- Matches Playwright's approach of persistent browser contexts
Lifecycle Flow
- Window Creation: User clicks "Open Browser" →
authenticate_with_webviewcreates window → State saved to database - App Running: Window stays open, user can browse freely, cookies maintained by browser
- Window Close: User closes window → Event handler removes from database and memory
- App Restart:
restore_persistent_webviewsqueries database → Recreates all windows → Windows resume with original cookies
Database Schema
CREATE TABLE persistent_webviews (
id TEXT PRIMARY KEY,
service TEXT NOT NULL CHECK(service IN ('confluence','servicenow','azuredevops')),
webview_label TEXT NOT NULL,
base_url TEXT NOT NULL,
last_active TEXT NOT NULL DEFAULT (datetime('now')),
window_x INTEGER,
window_y INTEGER,
window_width INTEGER,
window_height INTEGER,
UNIQUE(service)
);
Future Enhancements
- Save and restore window position/size (columns already exist in schema)
- Add "last_active" timestamp updates on window focus events
- Implement "Close All Windows" command for cleanup
- Add visual indicator in main UI showing which integrations have active browser windows
- Implement session timeout logic (close windows after X days of inactivity)
Related Files
src-tauri/src/db/migrations.rs- Database schema migrationsrc-tauri/src/commands/integrations.rs- Webview persistence and restoration logicsrc-tauri/src/integrations/webview_auth.rs- Browser window creationsrc-tauri/src/lib.rs- App startup hook for restorationsrc-tauri/src/state.rs- AppState structure withintegration_webviewsmap
Security Considerations
- Cookie storage remains in the browser's internal secure store (not extracted to database)
- Database only stores window metadata (service, label, URL)
- No credential information persisted beyond what the browser already maintains
- Audit log still tracks all integration API calls separately
Migration Path
Users upgrading to this version will:
- See new database migration
013_create_persistent_webviewsapplied automatically - Existing integrations continue to work (migration is additive only)
- First time opening a browser window will persist it for future sessions
- No manual action required from users