Skip to content

Commit d40e92d

Browse files
committed
Merge branch 'main' into editor-feats
2 parents 97fa47b + 57e7b7c commit d40e92d

File tree

484 files changed

+29483
-15443
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

484 files changed

+29483
-15443
lines changed

.claude/settings.local.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(pnpm typecheck:*)",
5+
"Bash(pnpm lint:*)",
6+
"Bash(pnpm build:*)"
7+
],
8+
"deny": [],
9+
"ask": []
10+
}
11+
}

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ jobs:
4646

4747
- uses: ./.github/actions/setup-js
4848

49+
- run: pnpm web exec next typegen
50+
4951
- name: Typecheck
5052
run: pnpm typecheck
5153

@@ -74,6 +76,8 @@ jobs:
7476
uses: actions/checkout@v4
7577

7678
- uses: dtolnay/rust-toolchain@stable
79+
with:
80+
components: rustfmt
7781

7882
- name: Check formatting
7983
run: cargo fmt --check
@@ -93,6 +97,7 @@ jobs:
9397
uses: dtolnay/rust-toolchain@stable
9498
with:
9599
targets: ${{ matrix.settings.target }}
100+
components: clippy
96101

97102
- name: Rust cache
98103
uses: swatinem/rust-cache@v2

.github/workflows/docker-build-web.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ jobs:
3838
echo "NEXT_PUBLIC_DOCKER_BUILD=true" >> .env
3939
echo "NEXT_PUBLIC_CAP_AWS_BUCKET=capso" >> .env
4040
echo "NEXT_PUBLIC_CAP_AWS_REGION=us-east-1" >> .env
41-
cat .env
4241
4342
- name: Login to GitHub Container Registry
4443
uses: docker/login-action@v3

.github/workflows/publish.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,29 @@ jobs:
213213
- name: Upload assets
214214
uses: crabnebula-dev/cloud-release@v0
215215
with:
216+
working-directory: apps/desktop
216217
command: release upload ${{ env.CN_APPLICATION }} "${{ needs.draft.outputs.version }}" --framework tauri
217218
api-key: ${{ secrets.CN_API_KEY }}
219+
env:
220+
TAURI_BUNDLE_PATH: ../..
221+
222+
- uses: matbour/setup-sentry-cli@8ef22a4ff03bcd1ebbcaa3a36a81482ca8e3872e
223+
224+
- name: Upload debug symbols to Sentry
225+
if: ${{ runner.os == 'macOS' }}
226+
shell: bash
227+
env:
228+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
229+
run: |
230+
sentry-cli debug-files upload -o ${{ env.SENTRY_ORG }} -p ${{ env.SENTRY_PROJECT }} target/Cap.dSYM
218231
219232
- name: Upload debug symbols to Sentry
220-
if: ${{ matrix.settings.runner == 'macos-latest' }}
233+
if: ${{ runner.os == 'Windows' }}
234+
shell: bash
221235
env:
222236
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
223-
working-directory: target
224237
run: |
225-
curl -sL https://sentry.io/get-cli/ | bash
226-
sentry-cli debug-files upload -o ${{ env.SENTRY_ORG }} -p ${{ env.SENTRY_PROJECT }} Cap.dSYM
238+
sentry-cli debug-files upload -o ${{ env.SENTRY_ORG }} -p ${{ env.SENTRY_PROJECT }} target/${{ matrix.settings.target }}/release/cap_desktop.pdb
227239
228240
done:
229241
needs: [draft, build]

AGENTS.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Repository Guidelines
2+
3+
## Project Structure & Modules
4+
- Turborepo monorepo:
5+
- `apps/desktop` (Tauri v2 + SolidStart), `apps/web` (Next.js), `apps/cli` (Rust CLI).
6+
- `packages/*` shared libs (e.g., `database`, `ui`, `ui-solid`, `utils`, `web-*`).
7+
- `crates/*` Rust media/recording/rendering/camera crates.
8+
- `scripts/*`, `infra/`, and `packages/local-docker/` for tooling and local services.
9+
10+
## Build, Test, Develop
11+
- Install: `pnpm install`; setup: `pnpm env-setup` then `pnpm cap-setup`.
12+
- Dev: `pnpm dev` (web+desktop). Desktop only: `pnpm dev:desktop`. Web only: `pnpm dev:web` or `cd apps/web && pnpm dev`.
13+
- Build: `pnpm build` (Turbo). Desktop release: `pnpm tauri:build`.
14+
- DB: `pnpm db:generate``pnpm db:push``pnpm db:studio`.
15+
- Docker: `pnpm docker:up | docker:stop | docker:clean`.
16+
- Quality: `pnpm lint`, `pnpm format`, `pnpm typecheck`. Rust: `cargo build -p <crate>`, `cargo test -p <crate>`.
17+
18+
## Coding Style & Naming
19+
- TypeScript: 2‑space indent; Biome formats/lints (`pnpm format`).
20+
- Rust: `rustfmt` + workspace clippy lints.
21+
- Naming: files kebab‑case (`user-menu.tsx`); components PascalCase; Rust modules snake_case, crates kebab‑case.
22+
- Runtime: Node 20, pnpm 10.x, Rust 1.88+, Docker for MySQL/MinIO.
23+
24+
## Testing
25+
- TS/JS: Vitest where present (e.g., desktop). Name tests `*.test.ts(x)` near sources.
26+
- Rust: `cargo test` per crate; tests in `src` or `tests`.
27+
- Prefer unit tests for logic and light smoke tests for flows; no strict coverage yet.
28+
29+
## Commits & PRs
30+
- Conventional style: `feat:`, `fix:`, `chore:`, `improve:`, `refactor:`, `docs:` (e.g., `fix: hide watermark for pro users`).
31+
- PRs: clear description, linked issues, screenshots/GIFs for UI, env/migration notes. Keep scope tight and update docs when behavior changes.
32+
33+
## Agent‑Specific Practices (inspired by CLAUDE.md)
34+
- Do not start extra servers; use `pnpm dev:web` or `pnpm dev:desktop` as needed.
35+
- Never edit auto‑generated files: `**/tauri.ts`, `**/queries.ts`, `apps/desktop/src-tauri/gen/**`.
36+
- Prefer existing scripts and Turbo filters over ad‑hoc commands; clear `.turbo` only when necessary.
37+
- Database flow: always `db:generate``db:push` before relying on new schema.
38+
- Keep secrets out of VCS; configure via `.env` from `pnpm env-setup`.
39+
- macOS note: desktop permissions (screen/mic) apply to the terminal running `pnpm dev:desktop`.
40+
41+
## Effect Usage
42+
- 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.
43+
- 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.
44+
- 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.
45+
- On the server, run effects through `EffectRuntime.runPromise` from `@/lib/server`, typically after `provideOptionalAuth`, so cookies and per-request context are attached automatically.
46+
- 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.

CLAUDE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,27 @@ Minimize `useEffect` usage: compute during render, handle logic in event handler
335335
- Loading: Use static skeletons that mirror content; no bouncing animations.
336336
- Performance: Memoize expensive work; code-split naturally; use Next/Image for remote assets.
337337

338+
## Effect Patterns
339+
340+
### Managed Runtimes
341+
- `apps/web/lib/server.ts` builds a `ManagedRuntime` from `Layer.mergeAll` so database, S3, policy, and tracing services are available to every request. Always run server-side effects through `EffectRuntime.runPromise`/`runPromiseExit` from this module so cookie-derived context and `VideoPasswordAttachment` are attached automatically.
342+
- `apps/web/lib/EffectRuntime.ts` exposes a browser runtime that merges the RPC client and tracing layers. Client code should lean on `useEffectQuery`, `useEffectMutation`, and `useRpcClient`; never call `ManagedRuntime.make` yourself inside components.
343+
344+
### API Route Construction
345+
- Next.js API folders under `apps/web/app/api/*` wrap Effect handlers with `@effect/platform`'s `HttpApi`/`HttpApiBuilder`. Follow the existing pattern: declare a contract class via `HttpApi.make`, configure groups/endpoints with `Schema`, and only export the `handler` returned by `apiToHandler(ApiLive)`.
346+
- Inside `HttpApiBuilder.group` blocks, acquire services (e.g., `Videos`, `S3Buckets`) with `yield*` inside `Effect.gen`. Provide layers using `Layer.provide` rather than manual `provideService` calls so dependencies stay declarative.
347+
- Map domain-level errors to transport errors with `HttpApiError.*`. Keep error translation exhaustive (`Effect.catchTags`, `Effect.tapErrorCause(Effect.logError)`) to preserve observability.
348+
- Use `HttpAuthMiddleware` for required auth and `provideOptionalAuth` when guests are allowed. The middleware/utility already hydrate `CurrentUser`, so avoid duplicating session lookups in route handlers.
349+
- Shared HTTP contracts that power the desktop app live in `packages/web-api-contract-effect`; update them alongside route changes to keep schemas in sync.
350+
351+
### Server Components & Effects
352+
- Server components that need Effect services should call `EffectRuntime.runPromise(effect.pipe(provideOptionalAuth))`. This keeps request cookies, tracing spans, and optional auth consistent with the API layer.
353+
- Prefer lifting Drizzle queries or other async work into `Effect.gen` blocks and reusing domain services (`Videos`, `VideosPolicy`, etc.) rather than writing ad-hoc logic.
354+
355+
### Client Integration
356+
- React Query hooks should wrap Effect workflows with `useEffectQuery`/`useEffectMutation` from `apps/web/lib/EffectRuntime.ts`; these helpers surface Fail/Die causes consistently and plug into tracing/span metadata.
357+
- When a mutation or query needs the RPC transport, resolve it through `useRpcClient()` and invoke the strongly-typed procedures exposed by `packages/web-domain` instead of reaching into fetch directly.
358+
338359
## Desktop (Solid + Tauri) Patterns
339360
- Data fetching: `@tanstack/solid-query` for server state.
340361
- IPC: Call generated `commands` and `events` from `tauri_specta`. Listen directly to generated events and prefer the typed interfaces.

0 commit comments

Comments
 (0)