Skip to content

Latest commit

 

History

History
216 lines (153 loc) · 9.26 KB

File metadata and controls

216 lines (153 loc) · 9.26 KB

OpenSpec Instructions

These instructions are for AI assistants working in this project.

Always open @/openspec/AGENTS.md when the request:

  • Mentions planning or proposals (words like proposal, spec, change, plan)
  • Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
  • Sounds ambiguous and you need the authoritative spec before coding

Use @/openspec/AGENTS.md to learn:

  • How to create and apply change proposals
  • Spec format and conventions
  • Project structure and guidelines

Keep this managed block so 'openspec update' can refresh the instructions.

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project

W3C WebCodecs API for Node.js using FFmpeg. Browser-compatible video/audio encoding/decoding with MP4 muxing/demuxing extensions.

CRITICAL: Check docs/specs/ before modifying C++ or codec behavior. W3C WebCodecs spec is the source of truth.

Core Principles

  • Safety over velocity — C++ segfault crashes entire Node process
  • RAII mandatory — Use src/ffmpeg_raii.h wrappers (AVFramePtr, AVPacketPtr), never raw av_*_alloc/free
  • Thread paranoiaAVCodecContext is NOT thread-safe; isolate from main thread in AsyncWorker
  • Spec compliance — Throw exact DOMException types per W3C spec (use error_builder.h)

Required Skills

  • C++ (src/*.cc, src/*.h): /dev-cpp (Google C++ Style Guide)
  • TypeScript (lib/*.ts, test/*.ts): /dev-ts (Google TypeScript Style Guide)
  • FFmpeg C++ review: Custom ffmpeg-cpp-sentinel agent (automatically available)

Commands

ALWAYS use npm run scripts. Never use npx, tsx, or direct tool invocations.

# Build
npm run build          # Full (native + TS), auto-runs after Write/Edit
npm run build:native   # C++ only
npm run build:debug    # Debug symbols

# Test
npm run check          # Lint + test (CI equivalent)
npm test               # All tests (unit + guardrails)
npm run test:unit      # Fast iteration

# Lint
npm run lint           # All (cpp + ts + types + md)
npm run lint:cpp       # cpplint only
npm run lint:ts        # biome only

# Output filters (spec reporter)
npm run test:failures  # ✖ only
npm run test:summary   # ℹ stats only

PostToolUse hook: Write|Edit → auto-format + build TypeScript (see output for errors)

Architecture

Two-layer design:

  • lib/ (TypeScript) → W3C spec compliance, state validation, EventTarget
  • src/ (C++17 N-API) → FFmpeg operations, async workers

Critical files:

  • src/ffmpeg_raii.h — RAII wrappers (prevents leaks)
  • src/error_builder.h — DOMException builder
  • lib/resource-manager.ts — W3C reclamation (10s inactive timeout)
  • lib/binding.ts — Platform addon loader

Pattern: TS handles state/validation, C++ handles FFmpeg ops. Clean separation.

FFmpeg Rules

  • Version: 5.0+ required (common.h enforces)
  • Return values: Always check, use FFmpegErrorString() for messages
  • Packet/frame ratio: NEVER assume 1:1 relationship
  • Timebase: Handle conversions explicitly (check W3C spec)

Codec Strings Reference

H.264: avc1.42001e (Baseline), avc1.4d001e (Main), avc1.64001e (High)
H.265: hvc1.*, hev1.*
VP9:   vp09.00.10.08
AV1:   av01.0.04M.08
AAC:   mp4a.40.2

C++ Debugging Protocol

STOP before editing code. Triage FIRST:

  1. Linker warnings ("built for macOS-X but linking with Y") = ABI issue, NOT code bug
  2. Crash in trivial code (constructor, allocation) = problem is ELSEWHERE
  3. Crash "moves around" when you edit = memory corruption or ABI mismatch
# Diagnose linked libraries
otool -L ./build/Release/*.node  # macOS
ldd ./build/Release/*.node       # Linux

Loop detection: Edited same file 3+ times for same crash → STOP. Root cause is elsewhere. Fix: Adjust binding.gyp, rebuild deps. Do NOT modify source as first response.

Code Review Standards

MANDATORY requirements for ALL code changes. Reviewers MUST enforce, contributors MUST follow.

API Design & TypeScript

  • ALWAYS update JSDoc in source files — TypeScript definitions auto-generated by tsc; JSDoc becomes .d.ts documentation
  • NEVER skip type tests — Add type-level assertions in test/types/*.test-d.ts via tsd to prevent regression
  • Accept both simple and complex forms — Use TypeScript overloads for progressive complexity (see VideoFrame constructor in lib/video-frame.ts:73-79)
  • Match FFmpeg naming conventions — Public APIs expand abbreviations (createConfiguration not createCfg), internal code mirrors FFmpeg (av_*)
  • Include @example blocks in JSDoc — Show real usage for all public APIs, document defaults explicitly
  • Safety over convenience — Validate inputs at TypeScript layer before passing to C++; prevent segfaults proactively

Testing Requirements

  • ALWAYS require tests for new features — NO exceptions; use test/golden/ for integration, test/unit/ for isolated behavior
  • ALWAYS test error paths — Deliberately trigger errors (invalid configs, closed states, null buffers) - see test/golden/video-encoder.test.ts:31-46
  • Edge case coverage MANDATORY — Test boundary conditions (zero-size frames, maximum values, null/undefined)
  • W3C compliance tests separate — Use test/golden/w3c-*.test.ts pattern for spec behavior verification
  • Run npm run check before review — Lint + tests must pass; NO "works on my machine" exceptions

Code Organization & Refactoring

  • Reduce duplication proactively — Extract common patterns to utilities (lib/transfer.ts, lib/is.ts) during review
  • Move logic to appropriate layer — Validation in TypeScript (lib/), FFmpeg ops in C++ (src/)
  • Use RAII wrappers MANDATORYsrc/ffmpeg_raii.h (AVFramePtr, AVPacketPtr) prevents leaks; raw av_*_alloc/free FORBIDDEN
  • Fix related bugs during review — If you discover a bug while reviewing, file issue or fix immediately; NO "out of scope" excuses

Documentation Standards

  • JSDoc for ALL public APIs — Include:
    • @example with working code snippets (not pseudocode)
    • FFmpeg/W3C upstream references where applicable
    • Default values and range constraints
    • Relationship to W3C spec sections (link to docs/specs/)
  • Comment FFmpeg quirks — Document non-obvious behavior (packet/frame ratio, timebase conversions, hardware acceleration caveats)
  • Explain departures from spec — If extending W3C API, mark clearly as "Node.js extension" with rationale (see Muxer/Demuxer classes)

Platform & Compatibility

  • Verify platform-specific code — Test macOS/Linux/Windows variations (ABI issues, library paths in lib/binding.ts)
  • Check upstream FFmpeg version — Ensure features exist in FFmpeg 5.0+ (minimum supported version per common.h)
  • NEVER assume upstream behavior — Validate FFmpeg return codes, check for null pointers, handle version differences

Security & Safety (CRITICAL)

  • NO secrets in test fixtures — Reject commits with .env, credentials.json, API keys in test/fixtures/
  • Validate ALL external inputs — Check buffer sizes, codec strings, frame dimensions at TS layer BEFORE C++
  • Copyright/licensing verification — Ensure new dependencies have MIT-compatible licenses, check package.json
  • FFmpeg error handling MANDATORY — ALWAYS check av_* return values, use FFmpegErrorString() for messages (src/error_builder.h)

Performance

  • Leverage FFmpeg optimizations — Use hardware acceleration flags (hwaccel), let FFmpeg choose SIMD paths
  • AVOID premature TypeScript optimization — Keep TS layer readable; C++ layer is where performance matters
  • Benchmark regressions — Run test/stress/ benchmarks for changes affecting encode/decode hot paths

Deprecation Protocol

  • Use @deprecated JSDoc tag — Mark deprecated APIs with replacement instructions
  • Provide migration timeline — Specify version when deprecated feature will be removed
  • Keep deprecated code functional — Don't break existing users until major version bump
  • Example:
    /**
     * @deprecated Use getReclaimableCodecs() instead. Will be removed in v1.0.0
     */

Review Checklist (Enforce EVERY item)

Before approving ANY pull request, verify:

  1. JSDoc updated in source files (lib/*.ts) with @example blocks
  2. Type tests added/updated (test/types/*.test-d.ts via tsd)
  3. Integration tests in test/golden/ OR unit tests in test/unit/
  4. Error path tests included (invalid inputs, closed states)
  5. W3C spec compliance verified (check docs/specs/)
  6. FFmpeg version compatibility checked (5.0+ minimum)
  7. Platform-specific code tested (macOS/Linux at minimum)
  8. No duplication (refactored to utilities if needed)
  9. Security: no secrets, all inputs validated at TS layer
  10. npm run check passes (lint + all tests)
  11. Build passes (npm run build produces valid .d.ts and native addon)
  12. No raw FFmpeg allocations (av_*_alloc/free); RAII wrappers only

CI Testing

Test GitHub Actions locally:

act -l  # List jobs
act push -j build-native --container-architecture linux/amd64 -W .github/workflows/ci.yml