- Add delete_port_forward Rust command to remove port forwards from state
- Update tauriCommands.ts to use delete_port_forward command
- Register delete_port_forward in lib.rs invoke handler
File attachments were embedded into AI messages without any PII
scanning, allowing credentials, tokens, and other sensitive data
to be forwarded to AI providers in plaintext.
Typed chat messages had the same gap: a user could type a password
or API key directly and it would be sent unscanned.
Changes:
- chat_message (Rust): defence-in-depth scan of all attachment body
content (between --- Attached: markers); hard rejects if PII found
- detect_pii (Rust): fix return type from pii::PiiDetectionResult
(spans/original_text) to db::models::PiiDetectionResult
(detections/total_pii_found) to match the TypeScript contract; the
LogUpload PII review workflow was receiving undefined for detections
- scan_text_for_pii (Rust): new command — scans arbitrary text for PII
without creating DB records; used for typed message warnings
- Triage/index.tsx: PendingFile now carries logFileId; handleSend gates
each text attachment through detectPiiCmd (hard block on PII found);
typed message text scanned via scanTextForPiiCmd with a one-time
warning — second send of same message proceeds as acknowledgment
Store compressed log content and raw image bytes in SQLite so attachments
are self-contained regardless of source file availability on disk.
DB (migrations 020-022):
- log_files.content_compressed BLOB — gzip-compressed extracted text
- image_attachments.image_data BLOB — raw image bytes
- Views v_log_files_with_issue and v_image_attachments_with_issue for
cross-incident queries with joined issue title
Rust backend:
- compress_text / decompress_text helpers (flate2 rust_backend / miniz_oxide)
with 100 MB decompression-bomb guard
- upload_log_file*, upload_log_file_by_content store content_compressed
- upload_image_attachment*, upload_paste_image store image_data
- New commands: get_log_file_content, list_all_log_files (analysis.rs)
- New commands: get_image_attachment_data, list_all_image_attachments (image.rs)
- All commands fall back to file_path for pre-migration records
Frontend:
- LogFileSummary, ImageAttachmentSummary types in tauriCommands.ts
- attachmentStore (Zustand) — loadAttachments, searchAttachments
- History page: Issues tab (existing) + Attachments tab (new)
with log/image tables, search bar, View modals, lazy thumbnails
Tests: 227 Rust (+16 new), 103 frontend (+9 new), tsc clean, clippy clean
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add migration 017_create_timeline_events with indexes
- Update TimelineEvent struct with issue_id, metadata, UTC string timestamps
- Add TimelineEvent::new() constructor with UUIDv7
- Add timeline_events field to IssueDetail
- Rewrite add_timeline_event to write to new table + audit_log (dual-write)
- Add get_timeline_events command for ordered retrieval
- Update get_issue to load timeline_events
- Update delete_issue to clean up timeline_events
- Register get_timeline_events in generate_handler
- Add migration tests for table, indexes, and cascade delete
- Fix flaky derive_aes_key test (env var race condition in parallel tests)
- Add build.rs to read version from git describe --tags
- Create update-version.mjs script to sync version across files
- Add get_app_version() command to Rust backend
- Update App.tsx to use custom version command
- Run version update in CI before Rust checks
- Add use_datastore_upload field to ProviderConfig for enabling datastore uploads
- Add upload_file_to_datastore and upload_file_to_datastore_any commands
- Add upload_log_file_by_content and upload_image_attachment_by_content commands for drag-and-drop without file paths
- Add multipart/form-data support for file uploads to GenAI datastore
- Add support for image/bmp MIME type in image validation
- Add x-generic-api-key header support for GenAI API authentication
This addresses:
- Paste fails to attach screenshot (clipboard)
- File upload fails with 500 error when using GenAI API
- GenAI datastore upload endpoint support for non-text files
- Add debug logging to OpenAI provider for troubleshooting
- Trim trailing periods from model names
- Fix HTTP error handling to capture response details
- Register missing AI provider commands (save/load/delete)
- Fix authenticateWithWebviewCmd to accept optional projectName parameter
Fixes two critical issues preventing Mac release builds from working:
1. Database encryption key auto-generation: Release builds now
auto-generate and persist the SQLCipher encryption key to
~/.../trcaa/.dbkey (mode 0600) instead of requiring the
TFTSR_DB_KEY env var. This prevents 'file is not a database'
errors when users don't set the env var.
2. Plain SQLite to encrypted migration: When a release build
encounters a plain SQLite database (from a previous debug build),
it now automatically migrates it to encrypted SQLCipher format
using ATTACH DATABASE + sqlcipher_export. Creates a backup at
.db.plain-backup before migration.
3. Credential encryption key auto-generation: Applied the same
pattern to TFTSR_ENCRYPTION_KEY for encrypting AI provider API
keys and integration tokens. Release builds now auto-generate
and persist to ~/.../trcaa/.enckey (mode 0600) instead of
failing with 'TFTSR_ENCRYPTION_KEY must be set'.
4. Refactored app data directory helper: Moved dirs_data_dir()
from lib.rs to state.rs as get_app_data_dir() so it can be
reused by both database and auth modules.
Testing:
- All unit tests pass (db::connection::tests + integrations::auth::tests)
- Verified manual migration from plain to encrypted database
- No clippy warnings
Impact: Users installing the Mac release build will now have a
working app out-of-the-box without needing to set environment
variables. Developers switching from debug to release builds will
have their databases automatically migrated.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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>
- AIProviders: hide top model row when custom_rest active (dropdown lower in form handles it);
clear auth header prefill on format switch; rename User ID / CORE ID → Email Address
- Dashboard + Ollama: add border-border/bg-card classes to Refresh buttons for dark-bg contrast
- Security + settingsStore: wire PII toggle state to persisted Zustand store so pattern
selections survive app restarts
- App: add Sun/Moon theme toggle button to sidebar footer (always visible when collapsed)
- system.rs: add install_ollama_from_bundle command (copies bundled binary to /usr/local/bin)
- auto-tag.yml: add Download Ollama step to all 4 platform build jobs with SHA256 verification
- tauri.conf.json: add resources/ollama/* to bundle resources
- docs: add install_ollama_from_bundle to IPC-Commands wiki
Security: CI download steps verify SHA256 against Ollama's published sha256sums.txt before bundling.
- Rename Cargo package from 'tftsr' to 'trcaa' — installed command
becomes 'trcaa' instead of 'tftsr'
- Update app data directories to ~/.local/share/trcaa (Linux),
~/Library/Application Support/trcaa (macOS), %APPDATA%/trcaa (Windows)
- Update bundle identifier to com.trcaa.app
- Auto-generate per-installation DB encryption key on first launch and
persist to <data_dir>/.dbkey (mode 0600 on Unix) — removes the hard
requirement for TFTSR_DB_KEY to be set before the app will start
Remove high-risk defaults and tighten data handling across auth, storage, IPC, provider calls, and capabilities so sensitive data is better protected by default. Also update README/wiki security guidance and add targeted tests for the new hardening behaviors.
Made-with: Cursor
Rename custom API format handling from custom_rest to custom_rest with backward compatibility, add guided model selection with custom entry in provider settings, and rebrand app naming to Troubleshooting and RCA Assistant across UI, metadata, and docs.
Made-with: Cursor
## Integration Settings Persistence
- Add database commands to save/load integration configs (base_url, username, project_name, space_key)
- Frontend now loads configs from DB on mount and saves changes automatically
- Fixes issue where settings were lost on app restart
## Persistent Browser Window Architecture
- Integration browser windows now stay open for user browsing and authentication
- Extract fresh cookies before each API call to handle token rotation
- Track open windows in app state (integration_webviews HashMap)
- Windows titled as "{Service} Browser (TFTSR)" for clarity
- Support easy navigation between app and browser windows (Cmd+Tab/Alt+Tab)
- Gracefully handle closed windows with automatic cleanup
## Bug Fixes
- Fix Rust formatting issues across 8 files
- Fix clippy warnings:
- Use is_some_and() instead of map_or() in openai.rs
- Use .to_string() instead of format!() in integrations.rs
- Add missing OptionalExtension import for .optional() method
## Tests
- Add test_integration_config_serialization
- Add test_webview_tracking
- Add test_token_auth_request_serialization
- All 6 integration tests passing
## Files Modified
- src-tauri/src/state.rs: Add integration_webviews tracking
- src-tauri/src/lib.rs: Register 3 new commands, initialize webviews HashMap
- src-tauri/src/commands/integrations.rs: Config persistence, fresh cookie extraction (+151 lines)
- src-tauri/src/integrations/webview_auth.rs: Persistent window behavior
- src/lib/tauriCommands.ts: TypeScript wrappers for new commands
- src/pages/Settings/Integrations.tsx: Load/save configs from DB
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement three authentication methods for Confluence, ServiceNow, and Azure DevOps:
1. **OAuth2** - Traditional OAuth flow for enterprise SSO environments
2. **Embedded Browser** - Webview-based login that captures session cookies/tokens
- Solves VPN constraints: users authenticate off-VPN via web UI
- Extracted credentials work on-VPN for API calls
- Based on confluence-publisher agent pattern
3. **Manual Token** - Direct API token/PAT input as fallback
**Changes:**
- Add webview_auth.rs module for embedded browser authentication
- Implement authenticate_with_webview and extract_cookies_from_webview commands
- Implement save_manual_token command with validation
- Add AuthMethod enum to support all three modes
- Add RadioGroup UI component for mode selection
- Complete rewrite of Integrations settings page with mode-specific UI
- Add secondary button variant for UI consistency
**VPN-friendly design:**
Users can authenticate via webview when off-VPN (web UI accessible), then use extracted cookies for API calls when on-VPN (API requires VPN). Addresses enterprise SSO limitations where OAuth app registration is blocked.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- db.rs: add get_issue_messages command (joins ai_conversations + ai_messages)
- tauriCommands.ts: fix updateIssueCmd to pass updates as nested object
(was spreading inline — Rust expects {issueId, updates}); fix addFiveWhyCmd
parameter names to match Rust (stepOrder, whyQuestion, answer, evidence);
add getIssueMessagesCmd and IssueMessage interface
- Dashboard: X button on each open issue row to close (mark resolved) inline
- Triage: restore conversation history from DB when revisiting existing issues;
detect close intent patterns and mark issue resolved + navigate home;
auto-save resolution step via addFiveWhyCmd when AI advances why level
- tests: add issueActions.test.ts covering IPC arg structure and close intent
Two startup crashes on first-party Tauri plugin init:
- tauri-plugin-updater registered with no plugins.updater config → removed
- tauri-plugin-cli was already removed in a prior commit
SQLCipher page size fix:
- cipher_page_size 4096 → 16384
- 4KB SQLCipher pages cause malloc() failures on Linux kernels with
16KB page size (Asahi Linux aarch64+16k, Apple Silicon)
- 16384 is a valid page size that works on both 4KB and 16KB page kernels
- New installs get a 16KB-page database; existing 4KB-page DBs must
be deleted for the new page size to take effect
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
tauri-plugin-cli was registered in lib.rs but tauri.conf.json had no
plugins.cli configuration, causing PluginInitialization panic at startup.
The CLI plugin is not needed for a GUI desktop app — removed.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>