- Add image_attachments table to database schema (migration 013) - Implement image upload, list, delete, and clipboard paste commands - Add image file PII detection with user approval workflow - Register image attachment commands in Tauri IPC - Update TypeScript types and frontend components - Add unit tests for image attachment functionality - Update README and wiki documentation
5.5 KiB
AGENTS.md
Commands & Tools
Development
- Full dev server:
cargo tauri dev(requiressource ~/.cargo/envfirst) - Frontend only:
npm run dev(Vite at localhost:1420) - Production build:
cargo tauri build→src-tauri/target/release/bundle/
Testing & Verification
Order matters:
cargo fmt --manifest-path src-tauri/Cargo.toml --checkcargo clippy --manifest-path src-tauri/Cargo.toml -- -D warningscargo test --manifest-path src-tauri/Cargo.tomlnpx tsc --noEmitnpm run test:run
Single Rust test: cargo test --manifest-path src-tauri/Cargo.toml pii::detector
Single Rust test by name: cargo test --manifest-path src-tauri/Cargo.toml test_detect_ipv4
Architecture Highlights
Rust Backend (Tauri 2)
- State:
AppStatewrapsMutex<Connection>+Mutex<AppSettings>— lock inside{ }blocks and release before.await - IPC entry point:
src-tauri/src/lib.rs→run()registers all handlers ingenerate_handler![] - AI providers:
ai/provider.rs::create_provider()dispatches onprovider_type(ornamefallback) - PII before AI: Every external send must call
apply_redactions()and log SHA-256 hash viaaudit::log::write_audit_event() - DB encryption:
debug_assertions→ plain SQLite; release → SQLCipher. Keys fromTFTSR_DB_KEY/TFTSR_ENCRYPTION_KEYenv vars
Frontend (React + TypeScript)
- IPC layer:
src/lib/tauriCommands.ts— single source of truth for typedinvoke()wrappers - Stores (Zustand):
sessionStore.ts: Ephemeral triage session (not persisted)settingsStore.ts: AI providers, theme, Ollama URL — persisted tolocalStorageas"tftsr-settings"historyStore.ts: Read-only cache of past issues
- Domain prompts:
src/lib/domain Prompts.ts— 8 IT domains injected as first message in triage conversations
Key Data Types
- IssueDetail (Rust): Nested struct —
detail.issue.title, NOTdetail.title - IssueDetail (TS): Mirrors Rust — use
issue.title,issue.status, etc. - PII spans:
PiiDetector::detect()returns non-overlapping spans (longest wins on overlap), applies in reverse order
CI/CD
Branch protection: master requires PR + sarman approval + all 5 CI checks green
Gitea Actions workflows (.gitea/workflows/):
test.yml: rustfmt · clippy · cargo test (64) · tsc · vitest (13) — every push/PRauto-tag.yml: Auto-tag + multi-platform release build on push tomaster
Runners:
amd64-docker-runner: linux/amd64 + windows/amd64 buildsarm64-native-runner: native linux/arm64 builds
CI test binary requirement: npm run test:e2e needs TAURI_BINARY_PATH=./src-tauri/target/release/tftsr
Database & Settings
DB path: ~/.local/share/tftsr/tftsr.db (Linux), override via TFTSR_DATA_DIR
SQLite schema: db/migrations.rs tracks 10 migrations; schema in _migrations table
Environment variables:
TFTSR_DATA_DIR: DB location overrideTFTSR_DB_KEY: SQLCipher encryption key (required release)TFTSR_ENCRYPTION_KEY: API key encryption (required release)RUST_LOG: tracing level (debug,info,warn,error)
PII Detection & Redaction
Patterns detected: IPv4/IPv6, emails, tokens, passwords, SSNs, credit cards
Flow:
detect_pii(log_file_id)→Vec<PiiSpan>(sorted, non-overlapping)- UI shows diff viewer for approval
apply_redactions(log_file_id, approved_span_ids)→ creates redacted file- Mandatory: SHA-256 hash of redacted content logged via
audit::log::write_audit_event()before any AI send
AI Providers
Supported: OpenAI (compatible), Anthropic, Google Gemini, Mistral, Ollama (local)
Adding a provider:
- Implement
Providertrait inai/*.rs - Add match arm in
ai/provider.rs::create_provider()
Ollama defaults: http://localhost:11434, default model llama3.2:3b (≥8 GB RAM) or llama3.1:8b (≥16 GB RAM)
Wiki Maintenance
Source of truth: docs/wiki/ — automated sync to Gitea wiki on every push to master
Update these files when changing code:
| Area | Wiki file |
|---|---|
| Tauri commands | IPC-Commands.md |
| DB schema/migrations | Database.md |
| AI providers | AI-Providers.md |
| PII detection | PII-Detection.md |
| CI/CD changes | CICD-Pipeline.md |
| Architecture | Architecture.md |
| Security changes | Security-Model.md |
| Dev setup | Development-Setup.md |
Common Gotchas
- Mutex deadlock: Never hold
MutexGuardacross.await— release before async calls - PII enforcement: Redaction + hash audit is mandatory before any network send
- Testing order: Run
cargo check/cargo fmt/cargo clippybeforecargo test(order matters for CI) - DB encryption: Release builds require
TFTSR_DB_KEYandTFTSR_ENCRYPTION_KEYor will fail at runtime - Type mismatch:
get_issue()returnsIssueDetailwith nestedissuefield in both Rust and TS - Integration stubs:
integrations/modules are v0.2 stubs — not functionally complete - Rust version: 1.88+ required (for
cookie_store,time,darling) - Linux deps: Must install webkit2gtk4.1 + libsoup3 + openssl before
cargo build
Prerequisites (Linux/Fedora)
sudo dnf install -y glib2-devel gtk3-devel webkit2gtk4.1-devel \
libsoup3-devel openssl-devel librsvg2-devel
Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && source ~/.cargo/env
Node: 22+ (via package manager)