mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-13 15:46:46 +03:00
docs: Improve AGENTS.md for AI agent onboarding (#9921)
- Lead with Common Failures section covering the most likely CI gotchas - Two mandatory registrations for new source files (uncompiled.js + build/types/) - Export annotation rules with link to docs/design/current/export.md - `@suppress warning`, zero runtime deps, lib/device/ sensitivity - Shallow directory map with self-maintenance instruction - High-stakes warnings section - Drop deep lib/ subdirectory listing that goes stale This is ~30 lines shorter, a couple hundred words shorter, and is hopefully more focused and less brittle. Co-authored-by: Claude Code (Claude Sonnet 4.6) <noreply@anthropic.com>
This commit is contained in:
@@ -1,179 +1,141 @@
|
||||
# Shaka Player — AI Agent Instructions
|
||||
|
||||
Shaka Player is an open-source JavaScript library for adaptive media playback
|
||||
(DASH, HLS, MSF), published on npm as `shaka-player`. See [README.md](README.md)
|
||||
for full details. The public API is exposed under the global `shaka` namespace.
|
||||
|
||||
GitHub: https://github.com/shaka-project/shaka-player
|
||||
|
||||
## Attribution
|
||||
|
||||
Read [AGENT-ATTRIBUTION.md](AGENT-ATTRIBUTION.md) for attribution details.
|
||||
|
||||
## Project Overview
|
||||
## Common Failures
|
||||
|
||||
Shaka Player is an open-source JavaScript library for adaptive media playback
|
||||
(DASH, HLS, MSF). It is maintained by Google and is published on npm as
|
||||
`shaka-player`. The public API is exposed under the global `shaka` namespace.
|
||||
**Read this section before making any change.**
|
||||
|
||||
GitHub: https://github.com/shaka-project/shaka-player
|
||||
**New source file: two mandatory registrations.**
|
||||
|
||||
Adding a new class or plugin requires two separate registrations or it may fail to load:
|
||||
1. Add a `goog.require('shaka.YourModule')` entry to
|
||||
`shaka-player.uncompiled.js` only for self-registering modules (e.g. plugins)
|
||||
that no other file `goog.require`s directly. This keeps uncompiled/dev mode
|
||||
working.
|
||||
2. Add the source file to the appropriate `build/types/` file(s)
|
||||
(determines which compiled build variants include it).
|
||||
|
||||
**Export annotations.**
|
||||
|
||||
Closure Compiler renames symbols aggressively. Getting annotations wrong
|
||||
may silently break the public API:
|
||||
|
||||
- API symbol public to the library (callable by app code): must have `@export`
|
||||
- Internal symbol public to other classes (used within the library, not by
|
||||
apps): no export annotation
|
||||
- Abstract interface for generated externs: `@exportInterface`
|
||||
- Event/typedef visible in docs only: `@exportDoc`
|
||||
- `@expose`: deprecated, do not use
|
||||
|
||||
See [docs/design/current/export.md](docs/design/current/export.md) for the full
|
||||
rules.
|
||||
|
||||
**`@suppress` is a red flag.**
|
||||
Avoid `@suppress` entirely if possible. Any use must have a detailed comment
|
||||
explaining why it is unavoidable. Maintainers will scrutinize every instance.
|
||||
|
||||
**Linter, including spell-checker.**
|
||||
This check must pass before committing:
|
||||
|
||||
```bash
|
||||
# Compiler, linter, spell check, and other checks
|
||||
python3 build/check.py
|
||||
```
|
||||
|
||||
Unknown words fail the spell-checker; add legitimate new terms to
|
||||
`project-words.txt`.
|
||||
|
||||
**Zero runtime npm dependencies.**
|
||||
Shaka Player currently ships with zero runtime npm dependencies. Do not
|
||||
introduce any. New development/test dependencies are rare and require
|
||||
justification.
|
||||
|
||||
**`lib/device/` is sensitive.**
|
||||
Device-specific code in `lib/device/` may only break on CE (consumer
|
||||
electronics) hardware, which is only tested in the nightly device lab CI.
|
||||
Changes here need extra care and justification. Maintainers can choose to
|
||||
trigger a run in the lab for any PR.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
Shallow overview of top-level directories. **If you add, remove, or rename a
|
||||
top-level directory as part of a change, update this section.**
|
||||
|
||||
```
|
||||
shaka-player/
|
||||
├── lib/ # Core library source (JS, Closure-annotated)
|
||||
│ ├── abr/ # Adaptive bitrate logic
|
||||
│ ├── ads/ # Ad insertion (IMA, etc.)
|
||||
│ ├── cast/ # Chromecast sender/receiver
|
||||
│ ├── cea/ # Closed captions (CEA-608/708)
|
||||
│ ├── config/ # Configuration utilities
|
||||
│ ├── dash/ # DASH manifest parser
|
||||
│ ├── debug/ # Logging
|
||||
│ ├── deprecate/ # Deprecation helpers
|
||||
│ ├── device/ # Device-specific overrides (Tizen, WebOS, Xbox, etc.)
|
||||
│ ├── drm/ # DRM (Widevine, PlayReady, FairPlay)
|
||||
│ ├── hls/ # HLS manifest parser
|
||||
│ ├── lcevc/ # LCEVC video enhancement
|
||||
│ ├── media/ # Core media engine (buffering, segments, timelines)
|
||||
│ ├── msf/ # MOQT Streaming Format
|
||||
│ ├── net/ # Networking plugins (fetch, data URI, etc.)
|
||||
│ ├── offline/ # Offline download/storage
|
||||
│ ├── polyfill/ # Browser polyfills
|
||||
│ ├── queue/ # Media queuing
|
||||
│ ├── text/ # Text tracks / subtitles
|
||||
│ ├── transmuxer/ # Container transmuxing
|
||||
│ ├── util/ # General utilities
|
||||
│ └── player.js # Main Player class
|
||||
├── ui/ # UI layer (controls, buttons, LESS styles)
|
||||
├── externs/ # Closure Compiler extern definitions
|
||||
│ ├── shaka/ # Shaka's own public interface types
|
||||
│ └── *.js # Browser/platform externs
|
||||
├── build/ # Build and tooling scripts (Python + Node.js)
|
||||
│ ├── all.py # Main build entry point
|
||||
│ ├── build.py # Closure compilation
|
||||
│ ├── check.py # Style/type checking
|
||||
│ ├── test.py # Test runner wrapper
|
||||
│ ├── generateExterns.js # Generates .externs.js from compiled output
|
||||
│ ├── generateLocalizations.py # Generates localization JS from JSON
|
||||
│ ├── generateTsDefs.py # Generates .d.ts from compiled externs
|
||||
│ ├── types/ # Build variant definition files (+@complete, -@networking, etc.)
|
||||
│ ├── wrapper.template.js # IIFE wrapper for compiled output (see below)
|
||||
│ └── *.py # Other helper scripts (compiler, stats, docs, etc.)
|
||||
├── conditional/ # Conditional build helpers (e.g. dummy Cast proxy)
|
||||
├── demo/ # Demo app (Closure-based)
|
||||
├── test/ # Jasmine unit + integration tests (Karma)
|
||||
├── dist/ # Build output (compiled JS, source maps, .d.ts, externs)
|
||||
├── docs/ # JSDoc API documentation
|
||||
├── third_party/ # Third-party code
|
||||
├── shaka-player.uncompiled.js # Entry point listing all goog.require'd modules
|
||||
└── package.json
|
||||
lib/ Core library source (JS, Closure-annotated)
|
||||
ui/ UI layer (controls, buttons, LESS styles)
|
||||
externs/ Closure Compiler extern definitions
|
||||
shaka/ Shaka's own public interface types
|
||||
build/ Build and tooling scripts (Python + Node.js)
|
||||
types/ Build variant definitions -- edit when adding source files
|
||||
test/ Jasmine tests, mirroring lib/ structure
|
||||
demo/ Demo application
|
||||
docs/ JSDoc output and design documents
|
||||
dist/ Build output (do not edit)
|
||||
third_party/ Third-party code
|
||||
default-receiver/ Default Cast receiver app
|
||||
app-engine/ App Engine deployment config
|
||||
```
|
||||
|
||||
## Current Build System
|
||||
## Build System
|
||||
|
||||
The build system is **Python + Java (Closure Compiler)**. Node.js is also used
|
||||
for some tooling scripts.
|
||||
|
||||
### Key commands
|
||||
The build system is **Python + Java (Closure Compiler)**. Key commands:
|
||||
|
||||
```bash
|
||||
# Full build (lint, type-check, compile, docs)
|
||||
python3 build/all.py
|
||||
|
||||
# Compile only
|
||||
python3 build/build.py
|
||||
|
||||
# Style and type checks only (no output)
|
||||
python3 build/check.py
|
||||
|
||||
# Run tests (wraps Karma)
|
||||
python3 build/test.py [--quick] [--filter="<regex>"] [--browsers Chrome]
|
||||
python3 build/test.py --uncompiled # test against uncompiled sources
|
||||
python3 build/test.py --quick # unit tests only, skip integration tests
|
||||
|
||||
# Build docs
|
||||
python3 build/docs.py
|
||||
|
||||
# Regenerate deps.js (needed when using uncompiled library)
|
||||
python3 build/gendeps.py
|
||||
|
||||
# Bundle size analysis
|
||||
python3 build/stats.py -s # function sizes
|
||||
python3 build/stats.py -c # class dependencies
|
||||
python3 build/all.py # full build (lint, type-check, compile, docs)
|
||||
python3 build/build.py # compile only
|
||||
python3 build/check.py # lint + type checks, no output
|
||||
python3 build/test.py [--quick] [--filter="<regex>"] [--uncompiled]
|
||||
python3 build/build.py +@complete -@ui # example: compile without UI
|
||||
```
|
||||
|
||||
### Configurable builds
|
||||
|
||||
`build.py` supports a `+`/`-` system for including/excluding feature modules:
|
||||
|
||||
```bash
|
||||
python3 build/build.py +@complete # everything
|
||||
python3 build/build.py +@complete -@networking # no networking plugins
|
||||
python3 build/build.py +@complete -@ui # no UI
|
||||
```
|
||||
|
||||
Build variant definitions live in `build/types/`. The default build is
|
||||
`+@complete`.
|
||||
|
||||
### Output artifacts (`dist/`)
|
||||
|
||||
Each build variant produces a family of files. The variants are:
|
||||
`compiled` (default, no UI), `ui`, `dash`, `hls`, `experimental`.
|
||||
|
||||
| Pattern | Description |
|
||||
|---------|-------------|
|
||||
| `shaka-player.{variant}.js` | Minified production bundle |
|
||||
| `shaka-player.{variant}.debug.js` | Unminified bundle with source maps |
|
||||
| `shaka-player.{variant}.d.ts` | TypeScript declarations |
|
||||
| `shaka-player.{variant}.externs.js` | Closure externs for downstream Closure users |
|
||||
| `shaka-player.{variant}-es2021.js` | ES2021 target variant (same family) |
|
||||
| `controls.css` | UI stylesheet |
|
||||
Build variant definitions (which source files go in which bundle) live in
|
||||
`build/types/`. Must be updated when adding new source files.
|
||||
|
||||
## Closure Compiler & Module System
|
||||
|
||||
All source files use **Google Closure Compiler** patterns:
|
||||
All source files use `goog.provide`/`goog.require` with JSDoc type annotations.
|
||||
The compiler runs in `ADVANCED_OPTIMIZATIONS` mode. See
|
||||
[docs/design/current/export.md](docs/design/current/export.md) for export
|
||||
annotation rules (`@export`, `@exportInterface`, `@exportDoc`).
|
||||
|
||||
- `goog.provide('shaka.Foo')` — declares a namespace/class
|
||||
- `goog.require('shaka.Bar')` — declares a dependency
|
||||
- Types are expressed entirely in **JSDoc** annotations (`@type`, `@param`,
|
||||
`@return`, `@implements`, etc.)
|
||||
- The compiler runs in `ADVANCED_OPTIMIZATIONS` mode, performing whole-program
|
||||
dead code elimination, renaming, and inlining
|
||||
|
||||
The **`externs/shaka/`** directory is an abuse of the Closure externs mechanism
|
||||
to define Shaka's own public interface types (e.g.
|
||||
`shaka.extern.Player.Configuration`). These are not true extern files — they
|
||||
represent public API structure that Closure must not rename.
|
||||
|
||||
## Output Wrapper
|
||||
|
||||
The compiled bundle is wrapped in an IIFE that provides compatibility with
|
||||
CommonJS, AMD, and direct `<script>` usage. See `build/wrapper.template.js`.
|
||||
|
||||
This functionality must be preserved (or replicated) in any new build system.
|
||||
The compiled bundle is wrapped in an IIFE for CJS/AMD/script compatibility.
|
||||
See `build/wrapper.template.js`. Preserve this in any new build system.
|
||||
|
||||
## Test System
|
||||
|
||||
- **Framework**: Jasmine
|
||||
- **Runner**: Karma (via `build/test.py`, which wraps `karma start`)
|
||||
- **Config**: `karma.conf.js`
|
||||
- Test files live in `test/`, mirroring the `lib/` structure
|
||||
- Integration tests require a compiled library; unit tests can run uncompiled
|
||||
- Key test flags: `--quick`, `--filter`, `--uncompiled`, `--random`, `--browsers`
|
||||
|
||||
## UI Layer
|
||||
|
||||
- UI source: `ui/` — all standard JS (Closure-annotated)
|
||||
- Styling: **LESS** files in `ui/less/`, compiled to `dist/controls.css`
|
||||
- Localization strings: generated by `build/generateLocalizations.py`
|
||||
Jasmine tests run via Karma (`karma.conf.js`). Test files under `test/` mirror
|
||||
`lib/` directory structure. Key flags: `--quick`, `--filter`, `--uncompiled`,
|
||||
`--random`, `--browsers`.
|
||||
|
||||
## ESLint
|
||||
|
||||
Config: `eslint.config.mjs`
|
||||
Custom rules in `build/eslint-plugin-shaka-rules/`.
|
||||
Run via `python3 build/check.py` or directly with `npx eslint`.
|
||||
Config: `eslint.config.mjs`. Custom rules: `build/eslint-plugin-shaka-rules/`.
|
||||
Run via `python3 build/check.py` (preferred) or `npx eslint`.
|
||||
|
||||
## Externs Structure
|
||||
## High-Stakes Warnings
|
||||
|
||||
- `externs/*.js` — browser/platform API externs
|
||||
- `externs/shaka/*.js` — Shaka's own interface/typedef definitions
|
||||
- `ui/externs/*.js` — UI layer interface/typedef definitions (same pattern as `externs/shaka/`)
|
||||
**Adding a new source file** requires two registrations (see Common Failures
|
||||
above). Forgetting one can result in new sources not being loaded or failing
|
||||
to compile.
|
||||
|
||||
## Node Version Requirement
|
||||
**Changing `externs/shaka/`** is a public API change. These files define the
|
||||
types that application code depends on. Any modification will receive close
|
||||
scrutiny from maintainers.
|
||||
|
||||
Node.js >= 18 for tests only (see `package.json` `"engines"` field).
|
||||
**Adding npm dependencies** — zero runtime dependencies is a hard-won property
|
||||
of this project. Do not add runtime deps. New development/test deps are rare;
|
||||
justify thoroughly in the PR.
|
||||
|
||||
**Touching `lib/device/`** — breakage may only appear on CE hardware in the
|
||||
nightly device lab. Flag any device-specific changes clearly in the PR.
|
||||
Maintainers can choose to trigger a run in the lab for any PR.
|
||||
|
||||
Reference in New Issue
Block a user