Learnings: platform and stack
Platform + stack concepts: Tauri 2, IPC, CLI-agent subprocesses, ast-grep, agent talks, rusqlite, provider APIs, auto-updater, DORA, calibration, workspaces, CF Pages, GEO, release chaining.
Desktop Tauri 2 / Rust app that reviews agent-generated code diffs using pluggable LLM providers, running fully offline as a macOS binary.
Tauri 2
- What: Rust-backed desktop app framework that renders a native webview instead of bundling Chromium.
- Why here: the entire product is one offline macOS binary; no server means no auth, no hosting cost, and reviews of private code never leave the machine.
- Gotcha (from code): GUI-launched Tauri apps on macOS don’t inherit shell
$PATH—claudeandgeminibinaries are found via a customresolve_cli_path()that walks known install locations. (apps/desktop/src-tauri/src/commands/review.rs:20) - Source: https://v2.tauri.app/
Tauri IPC (invoke / commands)
- What: The bridge that lets TypeScript call Rust functions via
invoke("command_name", args). - Why here: every feature crosses this bridge — the typed wrappers in
tauri-ipc.tsare the app’s real API surface. - Gotcha (from code): All
invoke()calls must be wrapped inisTauriAvailable()so the React app still renders in a plain browser duringnpm run dev. (apps/desktop/src/lib/tauri-ipc.ts:40) - Source: https://v2.tauri.app/develop/calling-rust/
CLI-agent subprocess execution (claude -p / gemini -p)
- What: Shelling out to an installed CLI agent instead of calling a provider API directly.
- Why here: reviews ride the user’s existing CLI subscriptions instead of API keys, which is why usage telemetry (not billing) is the cost lens.
- Gotcha (from code): CLI output is prose, not guaranteed JSON —
run_agent_jsonusesextract_json_from_outputto find the JSON block; if none is found the review errors out. (apps/desktop/src-tauri/src/commands/review.rs:721–740) - Source: https://code.claude.com/docs/en/overview
ast-grep (sg) structural code scanner
- What: A fast AST-pattern search tool (external binary
sg) that matches code structure, not just text. - Why here: deterministic evidence for review findings — structural matches don’t hallucinate.
- Gotcha (from code):
sgis optional —resolve_sg_path()returnsNoneif the binary isn’t installed and the evidence step silently skips; patterns are defined as inlineAstGrepRulestructs, not YAML rule files. (apps/desktop/src-tauri/src/commands/evidence_pattern.rs:134–154) - Source: https://ast-grep.github.io/
Agent Talks protocol (inter-session handoff)
- What: A structured JSON field (
talk) that review agents embed in their output, persisted to theagent_talksSQLite table and injected as context into the next agent’s prompt. - Why here: sequential review agents (specialists → coordinator) need cheap context handoff without re-reading the repo.
- Gotcha (from code): The
talkkey is stripped fromoutput_structuredbefore storage to avoid double-persistence; staleness threshold is 1 hour (STALENESS_SECS). (apps/desktop/src-tauri/src/talk.rs:5–10,db/schema.rs:589) - Source: TBD
Rust trait-based adapter pattern
- What: A
traitdefines a shared contract (like a TypeScript interface); concrete structs implement it. - Why here: one indexer serves five agent CLIs whose log formats disagree about everything, including whether token counts are deltas or cumulative.
- Gotcha (from code):
SessionSourceAdapteris implemented byClaudeCodeAdapter,CodexAdapter, andCursorAdapter— each parses a different agent’s JSONL/JSON session format. (apps/desktop/src-tauri/src/commands/session_adapters.rs:43–542) - Source: https://doc.rust-lang.org/book/ch10-02-traits.html
rusqlite / SQLite in Rust
- What: Rust bindings to SQLite; the
bundledfeature compiles SQLite into the binary. - Why here: the local-first promise rests on SQLite being the only datastore.
- Gotcha (from code):
bundledfeature adds ~2 MB and noticeably slows cold Rust builds; avoids macOS system-SQLite version mismatch errors. (apps/desktop/src-tauri/Cargo.toml:15) - Source: https://docs.rs/rusqlite/latest/rusqlite/
OpenAI-compatible chat completions API
- What: The
/v1/chat/completionsHTTP shape that Anthropic, OpenAI, and OpenRouter all expose. - Why here: one request shape covers all three configurable providers, so provider choice is config, not code.
- Gotcha (from code): Provider presets all use a
/v1base URL —PROVIDER_PRESETSmaps provider names tobaseUrl+model; the Anthropic preset points atapi.anthropic.com/v1, which accepts the OpenAI shape. (apps/desktop/src/lib/review-service.ts:112–128) - Source: https://platform.openai.com/docs/api-reference/chat
Tauri auto-updater (tauri-plugin-updater)
- What: Plugin that checks GitHub Releases for a
latest.jsonmanifest and applies delta updates. - Why here: releases are pull-based — the running app updates itself from GitHub Releases, so main must stay releasable.
- Gotcha (from code):
tauri-actionrepackages the.apptarball after signing, making the bundled.sigstale — the release workflow re-signs the final tarball and uploads.sig+latest.jsonexplicitly. (.github/workflows/release.yml:78–103) - Source: https://v2.tauri.app/plugin/updater/
PostHog analytics from a desktop binary
- What: Product analytics via direct HTTP POST to PostHog’s ingestion endpoint, with no server intermediary.
- Why here: the only outbound telemetry in an otherwise offline app; worth knowing exactly what leaves.
- Gotcha (from code): The hardcoded
POSTHOG_KEYandPOSTHOG_HOSTsit in a client-side TS file — the key is public by design (PostHog’s browser SDK model), but the project slug is visible in source. (apps/desktop/src/lib/analytics.ts:25–61) - Source: https://posthog.com/docs/libraries/js
DORA software delivery metrics
- What: Delivery-performance metrics covering deployment frequency, lead time, failed-deployment recovery time, and change failure rate.
- Why here: release-health signal for the Repo surface derived without any CI integration.
- Gotcha (from code): Intel derives DORA locally from git tags and revert/hotfix-shaped commits, so the UI labels the numbers as git-derived release health rather than production incident truth. (
apps/desktop/src/pages/Intel.tsx) - Source: https://dora.dev/guides/dora-metrics/
Outcome calibration
- What: Checking whether a confidence score or risk signal matches observed outcomes over time.
- Why here: the taste verdict and Unpacked trust actions are only honest if confidence tracks observed outcomes.
- Gotcha (from code): Repo Unpacked’s outcome trend only uses stored local reviews, QA runs, procedure gates, and findings; it is a bounded recent-vs-prior signal, not a learned predictor yet. (
apps/desktop/src-tauri/src/commands/unpack.rs) - Source: https://pmc.ncbi.nlm.nih.gov/articles/PMC10529246/
npm workspaces (monorepo)
- What: Node’s built-in multi-package monorepo support via
workspacesinpackage.json. - Why here: desktop app + landing page in one repo; one lockfile discipline or deploys break.
- Gotcha (from code): A stale
pnpm-lock.yamlcoexisted withpackage-lock.json; Cloudflare Pages picked up the pnpm lockfile and failed because it was out of sync. (pnpm-lock.yamlstill exists at repo root alongsidepackage-lock.json) - Source: https://docs.npmjs.com/cli/using-npm/workspaces
Cloudflare Pages deployment
- What: Static-site and SSR hosting on Cloudflare’s edge network, triggered by git push.
- Why here: the landing page’s entire ops story; misconfig here fails silently while GitHub CI stays green.
- Gotcha (from code):
root_dirwas set toapps/desktopinstead ofapps/landing-page— CF Pages silently built the wrong target; Vite outputs toout/notdist/, so the destination dir config must match. (apps/landing-page-astro/wrangler.toml) - Source: https://developers.cloudflare.com/pages/
Rust (systems language basics)
- What: Memory-safe compiled language without a GC; used here for the Tauri backend.
- Why here: the backend language — indexing, review orchestration, and all DB access are Rust.
- Source: https://doc.rust-lang.org/book/
GitHub Actions workflow chaining (GITHUB_TOKEN anti-recursion)
- What: workflows triggered by events that a GITHUB_TOKEN created do NOT cascade to other workflows — a documented anti-recursion safeguard;
workflow_dispatchis the one event that still fires. - Why here: the auto-release workflow creates the release with GITHUB_TOKEN, so it must dispatch the binary-build workflow explicitly or nothing builds.
- Gotcha (from code): the comment block at the top of
auto-release.ymlis the canonical explanation; atauri.conf.jsonversion bump on main is the trigger. - Source: https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
GEO — AI-crawler discoverability
- What: making a site legible to AI answer engines (GPTBot, ClaudeBot, Perplexity): FAQ blocks, robots rules, structured data.
- Why here: the landing FAQ exists for AI search answers as much as humans — and its claims must match reality (an FAQ said keys live in the OS keychain; they live in local app settings).
- Gotcha (from code): copy on marketing surfaces IS a review target — the review engine caught the keychain contradiction as a finding. (
apps/landing-page-astro/src/components/FAQ.astro) - Source: https://isitagentready.com
PTY-backed agent terminals (portable-pty + xterm.js)
- What: a pseudo-terminal gives a child process a real TTY (colors, resize, interactive prompts); xterm.js renders the byte stream in the webview.
- Why here: Work runs real Codex streams through local PTY execution while the primary interface presents the goal, lifecycle, evidence, and prompts rather than terminal chrome.
- Gotcha (from code): agent status is driven by Codex-Warp structured events when present, with conservative terminal-output detection only as fallback; resize must be forwarded to the PTY or full-screen TUIs corrupt. (
commands/agent_terminal.rs; specopenspec/specs/agent-panel/) - Source: https://xtermjs.org/
GitHub PR polling watchers (T-Rex)
- What: per-repo background tasks that poll GitHub PRs and run the review pipeline on new heads, with per-watcher error recovery and retry.
- Why here: review-on-arrival for agent-authored PRs without any CI integration or webhook infrastructure — polling is the only option for a local desktop app.
- Gotcha (from code): watchers resume from DB rows on app start (
resume_enabled_watchers); pre-flight validatesghauth + token before enabling; base branch is inferred per-PR rather than assumedmain. (commands/trex_watcher.rs) - Source: https://docs.github.com/en/rest/pulls