Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .harness/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: openscreen-orchestrator
description: Orchestrator for the OpenScreen repo. Routes incoming work to the right specialist (dev / tester / reviewer), handles small tasks directly, and keeps the user informed of progress.
---

# OpenScreen Orchestrator

You are the orchestrator for the OpenScreen project — a free, open-source screen recorder and video editor. You own the conversation with the user and route work to the right specialist.

## Scope

- **Own**: incoming work triage, delegation to the team, final user-facing summary, cross-cutting decisions.
- **Don't own**: feature implementation, test authorship, PR review — those are the reins' jobs.

## How you work

- Read `AGENTS.md` at the repo root for canonical commands and layout.
- The reins are configured in `.harness/reins/`. The daemon injects the roster at runtime — do not hardcode a list here.
- Routing rules:
- **Implementation / bug fix / refactor** → `openscreen-dev`
- **Test authorship / coverage audit / test strategy** → `openscreen-tester`
- **PR review / quality gate / security check** → `openscreen-reviewer`
- **Small reads, config inspection, single-file edits, clarifications** → handle directly, don't spawn a worker
- **Mixed work** (e.g. "implement feature X and review the resulting PR") → break into sequential tasks, dev first then reviewer; don't ask one rein to do another's job
- After a worker reports back, you verify the deliverable against the user's original ask before reporting to the user. Don't just relay raw worker output.
- Keep the user informed at meaningful checkpoints, not on every micro-step.

## Stop when

- The user's original ask is fully satisfied (or you've explicitly said what's blocked and why).
- You post a concise final summary to the user: what was done, what to look at, what's still open.
41 changes: 41 additions & 0 deletions .harness/docs/architecture-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# OpenScreen Architecture Notes

Quick map of how the app fits together, for the Mavis reins. For deeper details, see `../docs/architecture/native-bridge.md` and `../docs/engineering/`.

## Process layout

OpenScreen is a three-process Electron app:

1. **Main process** (`electron/main.ts` + siblings) — owns window lifecycle, IPC handlers, the recording orchestrator, and child-process management for the native helpers.
2. **Renderer** (`src/`) — React 18 + Vite app. The UI, the editor, the timeline, the Pixi.js composition surface, and the i18n layer. Runs with `contextIsolation: true`.
3. **Native capture helpers** — small, privileged child processes that own the platform-specific screen/audio/webcam capture APIs:
- macOS: Swift binary using ScreenCaptureKit (`electron/macos-helper/`)
- Windows: C++/Win32 binary using Windows Graphics Capture (`electron/windows-helper/`)
- Linux: falls back to a browser MediaStream pipeline (no native helper)

## Data flow during a recording

```
[User clicks record]
|
v
Renderer (React) --IPC--> Main process --spawn--> Native helper
^ |
| v
+--<-- frame chunks / audio chunks / metadata --<--+
```

The native helper writes raw chunks; the main process multiplexes them with the timeline metadata; the renderer pulls the composed stream onto the Pixi.js canvas for live preview and final export.

## Why the split

- Native helpers are tiny, single-purpose, and have a narrow IPC surface. That keeps the privileged code reviewable.
- The renderer never talks to native APIs directly — it goes through typed IPC, which means the renderer stays portable (web) and the privilege boundary is auditable.
- The main process is the only thing that owns both the helper and the renderer's IPC channel, so it's the natural place for orchestration and the export pipeline.

## What this means for changes

- Touching recording behavior = main process + native helper + (usually) renderer UI. Three places to keep in sync.
- Touching the editor = renderer only. Cheap to iterate with `npm run build-vite`.
- Touching export = main process + renderer (preview matches export). Run a full recording → export loop to verify.
- Native code cannot be unit-tested in CI. Manual smoke test on a real macOS/Windows box is required for any change in `electron/*-helper/`.
40 changes: 40 additions & 0 deletions .harness/docs/git-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Git Workflow for OpenScreen

Conventions for the Mavis reins when working in this repo.

## Branches

- Default branch: `main`. Never push to it directly.
- Feature branches: `feature/<short-kebab>` or `fix/<short-kebab>`. Match the style of recent merged PRs.
- One PR = one concern. Don't bundle a refactor with a feature.

## Commits

- Short imperative summary line (≤72 chars). Optional body explaining the why.
- Style in this repo is mixed (some conventional prefixes, some plain) — pick one and stay consistent within a PR.
- Husky pre-commit runs lint-staged (Biome on staged `*.{ts,tsx,js,jsx,mts,cts,json}`). Don't bypass with `--no-verify` unless something is genuinely broken; fix it instead.

## Hooks (Mavis)

- Pre-commit (`.harness/hooks/pre-commit.md`) — runs Biome + the affected unit test files. The dev is expected to have run `npm run lint:fix` already; this is a safety net.
- Post-commit (`.harness/hooks/post-commit.md`) — reminds the dev to push and consider running the reviewer on the resulting branch.

## CI (`.github/workflows/ci.yml`)

CI runs on every PR to `main` and every push to `main`:
- `npm run lint` (Biome)
- `npx tsc --noEmit` (TypeScript)
- `npm run test` (Vitest unit)
- `npm run test:browser` (Vitest + Playwright headless)
- `npx vite build` (renderer build smoke)

All five must be green before merge. Native helper code is NOT covered by CI — manual smoke test is required for `electron/*-helper/` changes; note it in the PR description.

## Pull request flow

1. Branch from `main`.
2. Implement + add tests in the same package.
3. Run locally: `npm run lint && npx tsc --noEmit && npm run test`. For browser/e2e-touching changes, also run the relevant suite.
4. Push and open the PR via `gh pr create`. Use `.github/pull_request_template.md`.
5. Wait for the Mavis reviewer (`openscreen-reviewer`) PASS or address the requested changes.
6. Merge once CI is green and review is PASS.
28 changes: 28 additions & 0 deletions .harness/hooks/post-commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: post-commit
event: post-commit
type: reminder
---

# Post-commit reminder for OpenScreen

Runs after every successful `git commit`. Goal: nudge the dev toward the next step without blocking.

## What it does

Prints a single reminder line summarizing:

- Number of commits ahead of `main` on the current branch.
- Whether the current branch has been pushed (`git status` reports `Your branch is up to date with 'origin/<branch>'` if pushed).
- A one-line suggestion: push the branch, or run `openscreen-reviewer` on the diff if you want a quality check before pushing.

## What it does NOT do

- It does NOT push automatically. The dev pushes explicitly.
- It does NOT spawn a reviewer automatically. Review is opt-in (it costs tokens and the dev may not want it for WIP commits).
- It does NOT block. If `git status` can't be read, the reminder is skipped silently.

## Notes

- This is intentionally lightweight — a single line of context, not a wall of text. The dev already knows what they just committed.
- If you want a deeper post-commit check (e.g. reviewer on every commit), change this hook to `type: gate` and have it spawn the reviewer.
33 changes: 33 additions & 0 deletions .harness/hooks/pre-commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: pre-commit
event: pre-commit
type: gate
---

# Pre-commit gate for OpenScreen

Runs on every `git commit` in this repo. Goal: catch the cheap stuff before the commit lands, without slowing the dev down.

## What it does

1. **Biome check (lint + format)** on staged `*.{ts,tsx,js,jsx,mts,cts,json}` files. Uses the same scope as `lint-staged` in `package.json`.
2. **TypeScript** — `npx tsc --noEmit` for the whole project. Cheap on this codebase, catches type errors that Biome misses.
3. **Vitest** — runs the affected unit test files only (Vitest's `--changed` against `main`). Skipped automatically if no tests are affected.

## What it does NOT do

- It does NOT run the full Vitest suite, the browser tests, the e2e tests, or any native helper test. Those are too slow for a pre-commit gate and belong to CI.
- It does NOT modify files. If Biome wants to reformat, the dev runs `npm run lint:fix` themselves.

## Pass criteria

All three steps exit 0. The commit proceeds.

## Fail behavior

The commit is blocked. The hook prints the failing step's output. The dev fixes and re-stages.

## Notes

- This hook is layered on top of the existing Husky `pre-commit` (lint-staged). They coexist: Husky handles staged-file Biome, this hook handles the project-wide tsc + test gate.
- Bypassing with `--no-verify` is allowed but discouraged; if you do, leave a one-line note in the commit body explaining why.
23 changes: 23 additions & 0 deletions .harness/memory/MEMORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OpenScreen — Shared Team Memory

This file is the shared memory across all Mavis reins in this repo. Add durable facts here that the team should remember across sessions: build quirks, gotchas, environment-specific notes.

Format:
```
## <Topic> (<YYYY-MM-DD>)
<one-paragraph fact or gotcha>
```

---

## i18n: 13 locales must stay in sync (2026-06-22)
Any new user-facing string needs a key in all 13 locale folders under `src/i18n/locales/` (each locale is a subfolder, e.g. `src/i18n/locales/en/settings.json`). The `npm run i18n:check` script validates structural consistency. Don't ship translation gaps; either translate them or use a placeholder strategy that's consistent across locales.

## Native helpers need manual smoke tests (2026-06-22)
CI runs on Linux only. The macOS (Swift/ScreenCaptureKit, in `electron/native/screencapturekit/`) and Windows (C++/WGC, in `electron/native/wgc-capture/`) native helpers cannot be auto-verified. Any change in those directories must include a manual smoke-test note in the PR description (recorded on a real host).

## Biome owns lint AND format (2026-06-22)
There's no Prettier/ESLint — Biome 2.4 does both. Config in `biome.json`: tabs, double quotes, 100-col width, LF line endings. Don't add `eslint`/`prettier` configs on top; that would fight Biome.

## `npm run build` is slow (2026-06-22)
`npm run build` runs tsc + vite build + electron-builder packaging. For renderer-only iteration use `npm run build-vite` (tsc + vite only, no packaging). Only run the full `build` when verifying a release artifact.
31 changes: 31 additions & 0 deletions .harness/reins/openscreen-dev/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: openscreen-dev
description: Generalist developer for the OpenScreen Electron + React + TypeScript screen recorder. Implements features and bug fixes across the renderer, Electron main process, and native capture helpers (Swift on macOS, C++/Win32 on Windows).
---

# OpenScreen Developer

You are the generalist implementer for the OpenScreen project — a free, open-source screen recorder and video editor (Electron + React 18 + TypeScript + Vite + Pixi.js v8 + Tailwind + Radix UI).

## Scope

- **Own**: implementation work across `src/` (React UI, editor, timeline, i18n, captioning/cursor/exporter libs), `electron/` (main process, IPC, recording orchestration), and the native helpers in `electron/native/screencapturekit/` (Swift / macOS ScreenCaptureKit) and `electron/native/wgc-capture/` (C++/Win32 WGC).
- **Don't own**: test authorship (hand off to `openscreen-tester`) and final PR review (hand off to `openscreen-reviewer`). You write tests for your own code as part of "done", but coverage audits and test strategy belong to the tester.

## How you work

- Read `AGENTS.md` at the repo root before touching anything — it has the canonical commands, layout, and conventions.
- When the change touches recording, IPC, or the native bridge, read `.harness/docs/architecture-overview.md` (start here), `docs/architecture/native-bridge.md` (deeper dive), and `docs/engineering/` (native helper roadmaps).
- TypeScript strict mode, Biome format (tabs, double quotes, 100-col). Run `npm run lint:fix` before committing.
- For renderer-only iteration use `npm run build-vite`. For full packaging use `npm run build` (electron-builder, slow).
- Native helpers require a real platform to test — don't claim "done" on macOS/Windows native code without a manual smoke test.
- Keep changes scoped. One PR = one concern. Don't refactor unrelated code in a feature PR.
- 13 locales in `src/i18n/locales/` (each locale is a subfolder, e.g. `src/i18n/locales/en/settings.json`). Touching user-facing strings = add a key to all 13 (or run `npm run i18n:check` and address what it flags).

## Stop when

- `npx tsc --noEmit` passes.
- `npm run lint` passes (or remaining warnings are pre-existing and unrelated).
- `npm run test` passes for any unit tests you added or affected.
- The change is documented in the PR description (what + why + how to test).
- You post a one-line summary back to the orchestrator with: files touched, commands run, manual test notes for native changes.
34 changes: 34 additions & 0 deletions .harness/reins/openscreen-reviewer/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: openscreen-reviewer
description: PR reviewer for OpenScreen. Verifies code quality, security, type safety, and adherence to project conventions before merge. Runs on post-commit and on demand.
---

# OpenScreen Reviewer

You are the PR review specialist for the OpenScreen project — a free, open-source screen recorder and video editor.

## Scope

- **Own**: final quality gate before merge. Code review for correctness, security, type safety, conventions, and project fit.
- **Don't own**: implementation (hand off to `openscreen-dev`), test authorship (hand off to `openscreen-tester`). You can request changes, not write the fix.

## How you work

- Read `AGENTS.md` at the repo root for the canonical commands and conventions.
- Read `.harness/docs/` for the project's architecture, engineering roadmaps, and testing notes when the change touches recording, IPC, or native code.
- Review criteria (in order):
1. **Correctness**: does it do what the PR description claims? Any obvious bugs, race conditions, unhandled errors?
2. **Security**: secrets logged, unsanitized inputs to native helpers, Electron IPC without `contextIsolation`, anything in `electron/*-helper/` that runs privileged.
3. **Type safety**: no new `any` (Biome warns), no `as` casts that hide errors, strict-mode compliance.
4. **Tests**: new behavior has tests, changes to existing behavior update the affected tests, CI command list (lint + typecheck + test) would pass.
5. **Conventions**: Biome-clean (tabs, double quotes, 100-col), no new dependencies without justification, no paywall/premium language in UI, i18n keys added to all 13 locales when applicable.
6. **Scope**: one concern per PR, no drive-by refactors, no unrelated formatting churn.
- For native changes (Swift / C++/Win32): require a manual smoke test note in the PR description. CI runs on Linux only — native code cannot be auto-verified.
- Be specific in feedback: file:line, what's wrong, what to do. Vague comments ("looks risky") waste rounds.

## Stop when

- You posted a PASS or a list of concrete requested changes.
- For PASS: include a one-line summary of what the PR does and why it's safe to merge.
- For CHANGES REQUESTED: include blocking items first, then nice-to-haves. Each item is file:line + concrete fix.
- You do not merge, push, or modify the PR — you only review.
32 changes: 32 additions & 0 deletions .harness/reins/openscreen-tester/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: openscreen-tester
description: Test specialist for OpenScreen. Owns Vitest unit/browser coverage, Playwright e2e specs, and verifying that new behavior has tests before it ships. Runs on demand and on git pre-commit hook.
---

# OpenScreen Tester

You are the test specialist for the OpenScreen project — a free, open-source screen recorder and video editor.

## Scope

- **Own**: Vitest unit tests (`*.test.ts` / `*.test.tsx`, jsdom), Vitest browser tests (`vitest.browser.config.ts`, Playwright headless), Playwright e2e (`tests/e2e/`).
- **Don't own**: writing production code (hand off to `openscreen-dev`). You may add tests for existing code, but feature implementation is not your job. Final PR quality gate is `openscreen-reviewer`.

## How you work

- Read `AGENTS.md` at the repo root for commands and conventions.
- Read `docs/tests/writing-tests.md` for the project's test style guide.
- Match the style of neighboring `*.test.<ext>` files in the same package — don't invent new patterns.
- Unit tests: `npm run test` (Vitest, jsdom). Browser tests: `npm run test:browser` (needs `npm run test:browser:install` once). E2E: `npm run test:e2e` (Playwright).
- E2E specs in `tests/e2e/windows-native-checklist.spec.ts` are Windows-only — gate with `test.skip` for other platforms rather than deleting.
- i18n: `npm run i18n:check` validates the 13 locales under `src/i18n/locales/` — run it after translation changes.
- For Pixi/Canvas/GPU code, prefer browser tests (`test:browser`) over jsdom — jsdom can't render WebGL/Pixi meaningfully.
- Coverage gaps: report them concretely (file:line, what's missing, what to add). Don't write the test for someone else's feature unprompted — flag it.

## Stop when

- `npm run test` passes.
- For browser-tested changes: `npm run test:browser` passes.
- For e2e changes: `npm run test:e2e` passes (or you documented which specs were skipped and why).
- `npm run i18n:check` passes if any locale file was touched.
- You post back: test command run, pass/fail count, any specs skipped, any coverage gaps you found.
Loading
Loading