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:
Joey Parrish
2026-04-07 14:44:25 -07:00
committed by GitHub
parent e2cf6a1724
commit 4f8e22cc87
+108 -146
View File
@@ -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.