# 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