Repository navigation
Architecture
GitPulse is a Tauri 2 desktop app: Rust owns privileged work, Svelte 5 owns rendering, and they meet at one machine-checked seam: invoke("cmd_*").
flowchart TB
subgraph Frontend["Svelte 5 + TypeScript"]
Views["4 views + Fleet + terminal dock"]
Stores["Domain stores with injectable deps"]
Canvas["GPU canvas graph"]
Guards["Async cancellation guards"]
end
subgraph IPC["Tauri 2 IPC"]
Bridge["invoke('cmd_*') — 139 handlers, check:ipc"]
end
subgraph Backend["Rust / Rayon"]
Git["Git sandbox"]
Graph["Lane solver"]
Analyzers["Coverage, health, LOC"]
Ledger["Event ledger"]
MCP["gitpulse-mcp"]
end
subgraph Local["Your machine"]
GitCLI["git"]
GhCLI["gh"]
LLM["Local LLMs on loopback"]
Manvi["manvi serve"]
end
Frontend --> Bridge --> Backend
Backend --> Local
The 139-handler count is the registered tauri::generate_handler! list in src-tauri/src/lib.rs, enforced by npm run check:ipc.
GitPulse/
├── src/ Svelte 5 + TypeScript
│ ├── lib/stores/ repo, graph, filter, theme, …
│ ├── lib/components/ UI
│ ├── lib/canvas/ commit-graph renderer
│ ├── lib/views/ routerless view registry (4 views)
│ └── lib/<domain>/ pure logic: files, diff, coverage, health, …
└── src-tauri/src/ Rust core
├── commands/ the only IPC entry points
├── engine/ git reader/writer, worktrees, sandbox
├── graph/ lanes, mainline pin, filter simplification
├── analyzer/ languages, LOC, coverage, deps
├── harness/ MANVI policy gate
├── mcp/ read-only MCP surface
├── ledger/ durable WAL
└── bin/ gitpulse-mcp, gitpulsed
There is no virtual-DOM router. View ids are the ViewTab union in src/lib/repos/persist.ts, registered in src/lib/views/viewRegistry.ts, rendered from App.svelte. Adding a view means changing all three.
A ViewTab is stored on the active repository's session and its pane lives inside {#key currentPath}. Fleet answers a question about the workspace. If it were a view it would be scoped wrong and destroyed on every repo switch — taking the live terminal PTY with it.
Fleet is swapped by hiding, never unmounting. Open state is a UI preference, not part of the persisted workspace blob.
| Binary | Transport | Role |
|---|---|---|
gitpulse-mcp |
MCP JSON-RPC over stdio | Read the control plane. Never mutates git. |
gitpulsed |
NDJSON, interval loop | Write attribution catch-up into the ledger when the GUI is closed. Serves no requests and never takes a lease. |
gitpulsed --interval 300 /path/to/repoCatch-up is idempotent against a ledger watermark; interrupting a cycle is safe.
Manvi (dc-verify, dc-store, dc-glob) and DevCouncil (devmap-*) crates are copied into src-tauri/vendored/ so a lone GitPulse checkout builds. Do not edit those copies. Fix upstream, then npm run vendor. npm run vendor:check reports an upstream that is not checked out as unavailable, never matches.
The IPC, serde field, version-manifest, coverage-floor, and a large set of drift tests under scripts/ exist because types alone cannot see a renamed event, a gate that does not wrap a writer, or a count in the docs that no longer matches the code.
Canonical write-up: docs/ARCHITECTURE.md and Development.
GitPulse is MIT-licensed · Source · Releases · Security advisories · Website
Using GitPulse
Agents & policy
Contributors
Project