{"owner":"CapSoftware","repo":"Cap","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md"],"files":{"AGENTS.md":"# Repository Guidelines\n\n## Pre-Generation Invariants (read BEFORE writing any code)\n\nThese rules are enforced by CI (`cargo clippy -D warnings`, Biome). Fixing them afterwards is wasted effort — emit code in the correct shape the FIRST time. Every CI failure caused by one of these rules means the agent didn't read this section.\n\n### Zero-tolerance rules\n- **Default to no code comments. Add a comment only after solving a bug or working through a complex issue, and only when it captures non-obvious context that a future investigator or reviewer genuinely needs** — e.g. why the fix looks the way it does, the upstream/platform bug being worked around, a non-obvious invariant or trade-off chosen after investigation, or a link to the PR/issue that explains the decision. Bad cases that remain banned: narrating what the code does, restating types, JSDoc that paraphrases parameter names, \"TODO: refactor\" or \"this should be cleaner\" notes, and any comment that just describes the change you are currently making. When in doubt, prefer better naming/types over a comment. Applies to every language: Rust, TS, JS, Python, shell, SQL, TOML, etc.\n- **Never edit generated files**: `**/tauri.ts`, `apps/desktop/src-tauri/gen/**`, `packages/ui-solid/src/auto-imports.d.ts`, Drizzle migration SQL under `packages/database/migrations/`. These are regenerated (e.g. `tauri.ts` only on debug desktop runs) but stay committed because CI typecheck and fresh clones depend on them; commit binding changes alongside the Rust change that produced them. Note: `apps/desktop/src/utils/queries.ts` is hand-written, not generated — edit it normally.\n- **Never start additional dev servers** (`pnpm dev`, `pnpm dev:web`, `pnpm dev:desktop`, Docker services). Assume they are already running.\n\n### Post-edit checks (run before you say \"done\")\n- Prefer scoped, fast checks over full workspace gates. Do not run long full-repo checks by default.\n- Touched any Rust file → `cargo fmt --all` and `cargo check -p <crate>`. Add `--all-targets`, `--workspace`, or clippy only when explicitly requested, when preparing CI/PR final validation, or when the change needs broader coverage.\n- Touched any TS / JS / JSON / CSS / MD file → run the narrowest applicable formatter/linter on touched files first, such as `pnpm exec biome check --write <files>`. Use full `pnpm format`, `pnpm lint`, and `pnpm typecheck` only when explicitly requested or when the change spans shared types/packages.\n- Touched DB schema → `pnpm db:generate` before relying on it.\n\n### Rust — write the clippy-clean form the FIRST time\nAll patterns below are `deny` in the workspace `[workspace.lints]` in `Cargo.toml`. Do not emit the left column; always emit the right column.\n\n| ❌ Don't write | ✅ Write instead | Lint |\n|---|---|---|\n| `dbg!(x)` | `tracing::debug!(?x)` (or delete it) | `dbg_macro` |\n| `let _ = async_fn();` | `async_fn().await;` or `tokio::spawn(async_fn());` | `let_underscore_future` |\n| `a - b` for `Duration`/`Instant` | `a.saturating_sub(b)` | `unchecked_time_subtraction` |\n| `if a { if b { … } }` | `if a && b { … }` | `collapsible_if` |\n| `x.clone()` when `x: Copy` | `x` | `clone_on_copy` |\n| `iter.map(\\|x\\| foo(x))` | `iter.map(foo)` | `redundant_closure` |\n| `fn f(v: &Vec<T>)` / `fn f(s: &String)` | `fn f(v: &[T])` / `fn f(s: &str)` | `ptr_arg` |\n| `v.len() == 0` / `v.len() > 0` | `v.is_empty()` / `!v.is_empty()` | `len_zero` |\n| `let _ = unit_returning();` | `unit_returning();` | `let_unit_value` |\n| `opt.unwrap_or_else(\\|\\| 42)` (cheap default) | `opt.unwrap_or(42)` | `unnecessary_lazy_evaluations` |\n| `for i in 0..v.len() { v[i] … }` | `for item in &v { … }` or `.iter().enumerate()` | `needless_range_loop` |\n| `value.min(max).max(min)` | `value.clamp(min, max)` | `manual_clamp` |\n\nAdditionally, `unused_must_use = \"deny\"` applies to all Rust code: every `Result`, `Option`, and `#[must_use]` value must be explicitly handled (`?`, `.unwrap()`, `.ok()`, `let _ = …;` **is not allowed** for unit-returning calls — see `let_unit_value`; it is the correct escape hatch for `Result`-returning calls you consciously discard, e.g. `let _ = tx.send(msg);`).\n\n### TypeScript / JavaScript — write the Biome-clean form the FIRST time\n`biome.json` at repo root enforces (do not override locally):\n- **Indent: tab.** Not two spaces, not four spaces. New files and edits must use tabs.\n- **Quotes: double.** `\"foo\"`, never `'foo'`, for JS/TS string literals.\n- **`organizeImports: on`** — imports are sorted/grouped automatically; don't leave unused imports or hand-sort against the grain.\n- **Recommended lint ruleset is on**, with `suspicious.noShadowRestrictedNames` disabled. Everything else (unused vars, `noExplicitAny`, dead code, etc.) applies.\n- Desktop code under `apps/desktop/**` has a11y rules disabled; they are enforced everywhere else (`apps/web`, `packages/ui`, etc.).\n- CSS overrides: `noUnknownAtRules`, `noUnknownTypeSelector`, `noDescendingSpecificity` are off for `**/*.css`.\n\n### TypeScript — strictness\n- Avoid `any`. Use `unknown` + narrowing, or existing shared types from `@cap/utils`, `@cap/web-domain`, generated bindings, etc.\n- Do not introduce `@ts-expect-error` / `@ts-ignore` without a concrete reason. Prefer fixing the type.\n\n## Project Structure & Modules\n- Turborepo monorepo:\n  - `apps/desktop` (Tauri v2 + SolidStart), `apps/web` (Next.js), `apps/cli` (Rust CLI).\n  - `packages/*` shared libs (e.g., `database`, `ui`, `ui-solid`, `utils`, `web-*`).\n  - `crates/*` Rust media/recording/rendering/camera crates.\n  - `scripts/*`, `infra/`, and `packages/local-docker/` for tooling and local services.\n\n## Build, Test, Develop\n- Install: `pnpm install`; setup: `pnpm env-setup` then `pnpm cap-setup`.\n- Dev: `pnpm dev` (web+desktop). Desktop only: `pnpm dev:desktop`. Web only: `pnpm dev:web` or `cd apps/web && pnpm dev`.\n- Build: `pnpm build` (Turbo). Desktop release: `pnpm tauri:build`.\n- DB: `pnpm db:generate` → `pnpm db:push` → `pnpm db:studio`.\n- Docker: `pnpm docker:up | docker:stop | docker:clean`.\n- Quality: `pnpm lint`, `pnpm format`, `pnpm typecheck`. Rust: `cargo build -p <crate>`, `cargo test -p <crate>`.\n\n## Coding Style & Naming\n- TypeScript / JS / JSON / CSS: **tab indent** and **double-quoted** strings, enforced by Biome (see `biome.json`). Do not configure per-file overrides.\n- Rust: `rustfmt` default style + the denied clippy lints in the Pre-Generation Invariants above.\n- Naming: files kebab‑case (`user-menu.tsx`); React/Solid components PascalCase; hooks `useX`; Rust modules snake_case; crates kebab‑case.\n- Runtime: Node 20, pnpm 10.5.2, Rust 1.88+, Docker for MySQL/MinIO.\n\n(See **Pre-Generation Invariants** at the top of this file for the comments policy and the denied clippy/Biome patterns. Those are the source of truth — do not duplicate or weaken them here.)\n\n## Testing\n- TS/JS: Vitest where present (e.g., desktop). Name tests `*.test.ts(x)` near sources.\n- Rust: `cargo test` per crate; tests in `src` or `tests`.\n- Prefer unit tests for logic and light smoke tests for flows; no strict coverage yet.\n\n## Commits & PRs\n- Conventional style: `feat:`, `fix:`, `chore:`, `improve:`, `refactor:`, `docs:` (e.g., `fix: hide watermark for pro users`).\n- PRs: clear description, linked issues, screenshots/GIFs for UI, env/migration notes. Keep scope tight and update docs when behavior changes.\n\n## Agent‑Specific Practices\n- Do not start extra servers; use `pnpm dev:web` or `pnpm dev:desktop` as needed.\n- Prefer existing scripts and Turbo filters over ad‑hoc commands; clear `.turbo` only when necessary.\n- Database flow: always `db:generate` → `db:push` before relying on new schema.\n- Keep secrets out of VCS; configure via `.env` from `pnpm env-setup`.\n- macOS note: desktop permissions (screen/mic) apply to the terminal running `pnpm dev:desktop`.\n- All other agent-facing rules (comments policy, no editing generated files, clippy/Biome shape, post-edit gates) live in **Pre-Generation Invariants** at the top of this file.\n\n## Deep Investigation Default\nWhen asked to inspect, review, optimize, secure, or fix something, do not stop at the obvious local change. First trace the full path and run a second-pass blast-radius review:\n\n- identify the real root cause, not only the symptom\n- trace callers, side effects, async/runtime behavior, generated artifacts, caches, exports, old data, and platform-specific paths\n- compare old vs new behavior when reviewing a diff\n- call out what is verified vs merely plausible\n- consider likely follow-up reviewer or user reports before calling it done\n- verify the actual user-visible outcome where practical, not only compile/lint success\n\nPrefer the smallest correct fix, but only after checking whether the narrow fix misses related consequences.\n\n## Effect Usage\n- Next.js API routes in `apps/web/app/api/*` are built with `@effect/platform`'s `HttpApi` builder; copy the existing class/group/endpoint pattern instead of ad-hoc handlers.\n- Acquire backend services (e.g., `Videos`, `S3Buckets`) inside `Effect.gen` blocks and wire them through `Layer.provide`/`HttpApiBuilder.group`, translating domain errors to `HttpApiError` variants.\n- Convert the effectful API to a Next.js handler with `apiToHandler(ApiLive)` from `@/lib/server` and export the returned `handler`—avoid calling `runPromise` inside route files.\n- On the server, run effects through `EffectRuntime.runPromise` from `@/lib/server`, typically after `provideOptionalAuth`, so cookies and per-request context are attached automatically.\n- On the client, use `useEffectQuery`/`useEffectMutation` from `@/lib/EffectRuntime`; they already bind the managed runtime and tracing so you shouldn't call `EffectRuntime.run*` directly in components.\n\n## Code Formatting & Lint Checks\nBefore declaring any task complete, the agent should run the fastest useful check for every file type it touched and report anything skipped.\n\n- **Rust**: `cargo fmt --all` and `cargo check -p <crate>` for the touched crate. Add `--all-targets`, `--workspace`, or `cargo clippy -p <crate> --all-targets -- -D warnings` only for explicit requests, CI/PR final validation, or changes that need broader coverage.\n- **TS / JS / JSON / CSS / MD**: prefer scoped checks such as `pnpm exec biome check --write <files>`. Use full `pnpm format`, `pnpm lint`, and `pnpm typecheck` only when explicitly requested or when the change is broad enough to justify it.\n- If a scoped check fails, fix the violation in the source (do NOT suppress with `#[allow(...)]`, `// biome-ignore`, or `any` unless explicitly approved). The Pre-Generation Invariants show the correct form for every denied lint.\n","CLAUDE.md":"# CLAUDE.md\n\nRead `AGENTS.md` for repository instructions.\n"}}