# AGENTS.md ## Overview Privacy-first video editor, with a focus on simplicity and ease of use. ## Lib vs Utils - `lib/` - domain logic (specific to this app) - `utils/` - small helper utils (generic, could be copy-pasted into any other app) ## Core Editor System The editor uses a **singleton EditorCore** that manages all editor state through specialized managers. ### Architecture ``` EditorCore (singleton) ├── playback: PlaybackManager ├── timeline: TimelineManager ├── scene: SceneManager ├── project: ProjectManager ├── media: MediaManager └── renderer: RendererManager ``` ### When to Use What #### In React Components **Always use the `useEditor()` hook:** ```typescript import { useEditor } from '@/hooks/use-editor'; function MyComponent() { const editor = useEditor(); const tracks = editor.timeline.getTracks(); // Call methods editor.timeline.addTrack({ type: 'media' }); // Display data (auto re-renders on changes) return
{tracks.length} tracks
; } ``` The hook: - Returns the singleton instance - Subscribes to all manager changes - Automatically re-renders when state changes #### Outside React Components **Use `EditorCore.getInstance()` directly:** ```typescript // In utilities, event handlers, or non-React code import { EditorCore } from "@/core"; const editor = EditorCore.getInstance(); await editor.export({ format: "mp4", quality: "high" }); ``` ## Actions System Actions are the trigger layer for user-initiated operations. The single source of truth is `@/lib/actions/definitions.ts`. **To add a new action:** 1. Add it to `ACTIONS` in `@/lib/actions/definitions.ts`: ```typescript export const ACTIONS = { "my-action": { description: "What the action does", category: "editing", defaultShortcuts: ["ctrl+m"], }, // ... }; ``` 2. Add handler in `@/hooks/use-editor-actions.ts`: ```typescript useActionHandler( "my-action", () => { // implementation }, undefined, ); ``` **In components, use `invokeAction()` for user-triggered operations:** ```typescript import { invokeAction } from '@/lib/actions'; // Good - uses action system const handleSplit = () => invokeAction("split-selected"); // Avoid - bypasses UX layer (toasts, validation feedback) const handleSplit = () => editor.timeline.splitElements({ ... }); ``` Direct `editor.xxx()` calls are for internal use (commands, tests, complex multi-step operations). ## Commands System Commands handle undo/redo. They live in `@/lib/commands/` organized by domain (timeline, media, scene). Each command extends `Command` from `@/lib/commands/base-command` and implements: - `execute()` - saves current state, then does the mutation - `undo()` - restores the saved state Actions and commands work together: actions are "what triggered this", commands are "how to do it (and undo it)". # Frontend Agent Guide (React + Clean UI) This repository uses **test-first development** and **clean UI/code** principles. AI agents must follow these rules when planning, coding, and refactoring. --- ## 1) Core Principles ### Test-first is mandatory Follow **Red → Green → Refactor** where practical: 1. **Red:** Write a failing test that captures the behavior. 2. **Green:** Implement the simplest code to pass. 3. **Refactor:** Improve structure/readability with tests green. UI work that is purely presentational may start with a minimal component and then tests, but behavior changes must be test-first. ### Clean code and clean UI always - Prefer **clarity over cleverness**. - Use **small components**, **meaningful names**, **single responsibility**. - Keep UI structure simple; avoid deeply nested layouts. - Avoid over-engineering; introduce abstractions only when pressure appears. ### Minimal scope - Implement only what’s needed for the current task/tests. - No premature “future-proofing.” ### Never use `any` - **Do not use `any` as a type.** - Prefer precise types or generics. --- ## 2) Workflow Rules (How the agent works) ### Before coding - Identify the smallest behavior to add. - Decide where it belongs (component, hook, util, store). - Write/adjust tests first for behavior changes. ### While coding - Keep changes small and incremental. - Run tests frequently and keep them green. ### After coding - Refactor for readability and structure. - Ensure linting/formatting pass. - Update docs only if behavior/usage changed. --- ## 3) Project Architecture Expectations (React) ### Component structure - **UI components**: presentational, no side effects. - **Feature components**: orchestrate UI + hooks/state. - **Hooks**: encapsulate shared logic. - **Utilities**: pure functions. ### Dependency direction - Features can use shared UI/components/utils. - Shared UI must not depend on feature-specific logic. ### State - Prefer local state where possible. - Use a shared store only when state must be shared across major areas. --- ## 4) Testing Strategy (React) ### Preferred test types 1. **Unit tests**: pure utils, hooks (default). 2. **Component tests**: React Testing Library for behavior. 3. **E2E tests**: only for high-level flows. ### What to test - Behavior and user interactions, not implementation details. - Edge cases and failure paths. ### Testing rules - Every new behavior must include tests. - Tests must be deterministic. - Avoid snapshot tests for logic-heavy components. --- ## 5) Clean Code Rules (Non-negotiable) ### Naming - Use intention-revealing names. - Avoid ambiguous abbreviations. ### Functions & components - Keep functions small. - Keep components focused. - Avoid prop drilling if a context or store is more appropriate. ### Error handling - Fail fast; show user-friendly messages where needed. - No silent failures. ### Comments - Use comments sparingly, only for _why_, not _what_. ### Formatting - Follow repo lint/format rules. - No unused variables or dead code. --- ## 6) React Conventions ### Props & types - Use typed props and shared types in `types/` or local `types.ts`. - Avoid widening types; keep them as narrow as possible. ### Accessibility - Use semantic HTML. - Ensure keyboard navigability for interactive elements. ### Styling - Follow repo styling approach consistently. - Keep styles co-located with components when possible. --- ## 7) Implementation Guidelines ### When adding new UI behavior 1. Write a test describing the interaction. 2. Implement the smallest change to pass. 3. Refactor for clarity and reusability. ### When fixing a bug 1. Add a failing test. 2. Fix with minimal change. 3. Refactor if needed. --- ## 8) Agent Output Expectations When producing changes, the agent should: - Include tests with each behavior change. - Keep patches focused and minimal. - Summarize what changed and why. --- ## 9) Quality Gate Checklist (must pass) - [ ] All tests pass (`unit`, `component`, `e2e` as applicable) - [ ] Lint/format checks pass - [ ] No flaky or time-dependent tests - [ ] No new unused exports or dead code - [ ] Accessibility reviewed for interactive changes --- ## 10) Default Commands (adjust if repo differs) Prefer these commands if they exist: - `npm test` / `pnpm test` - `npm run test:watch` - `npm run test:e2e` - `npm run lint` - `npm run format` Follow `package.json` scripts if different. --- ## 11) Anti-Patterns to Avoid - Writing behavior before tests (unless purely presentational). - Mixing unrelated refactors with feature work. - Over-mocking your own code. - Snapshot tests for logic-heavy UI. - Large shared “utils” dumping grounds. --- ## 12) When uncertain - Choose the simplest interpretation. - Write tests that document the behavior. - Keep changes minimal and reversible. --- ## 13) Commit message - Follow commit message convention standard