Files
ArtPlayer/AGENTS.md

363 lines
15 KiB
Markdown

# AGENTS.md
## Compatibility Refactor
2026-09-16 user scope update: stop autonomous refactor implementation and hand off for
the user's extended self-testing. Read [refactor/self-test-handoff.md](refactor/self-test-handoff.md)
first. Remaining tasks are deferred, not passed; do not resume long tests, new fixes,
full matrices, release preparation, or formal reviews without a new user instruction.
Existing compatibility requirements and future publication gates remain in force.
The compatibility modernization plan is maintained in [refactor/README.md](refactor/README.md).
For refactor work, read its compatibility contract, task plan, and progress log before editing.
Use `refactor/tasks.json` as the task status source and regenerate the readable plan with
`node refactor/scripts/plan.mjs --write`; validate it with `node refactor/scripts/plan.mjs --check`.
Preserve existing public APIs, event behavior, types, DOM/CSS hooks, and distribution entrypoints.
The planned TypeScript migration permits incremental JS/TS coexistence; it does not authorize
changing consumer APIs or treating planned validation as completed validation.
Apply [refactor/quality-contract.md](refactor/quality-contract.md) to every implementation task:
the user authorizes improving unreasonable internals while preserving old public contracts.
Refactor responsibilities and dependencies alongside TypeScript migration, add meaningful
risk-based tests, and update package architecture/maintenance documentation in the same change.
The user requires one separate local Git commit for each completed refactor task.
Include the task ID in the commit subject and include its implementation, tests, documentation,
and status updates together. Verify the commit before starting the next task. Do not bundle
multiple newly completed tasks or include unrelated work. This does not authorize pushing or publishing.
Use Yarn Classic 1.22.22 as packageManager and maintain only the root yarn.lock.
Core public declarations are authored in packages/artplayer/public/ and generated
with yarn build:types into the existing types/ entrypoints. Do not hand-edit the
generated core declarations; yarn check:types is read-only and rejects drift.
Use Node from .node-version; frozen Yarn installs and strict toolchain checks are required.
Bun remains an isolated evaluation and must not replace Yarn without a new user decision.
The user also authorizes installing needed dependencies and adding or improving reasonable
project scripts for the refactor without asking again for routine tooling choices.
Record their purpose and versions, use the appropriate workspace/dependency category, update
the lockfile when applicable, and verify compatibility and reproducible execution.
After implementation and its necessary tests, hand off the results and wait for the
user to guide and start the review phase. Do not automatically begin REVIEW-01/02/03,
including an early first review. Follow [refactor/release-reviews.md](refactor/release-reviews.md):
the three review rounds and closure of blocking findings remain required before candidate publication.
Connected Chrome interaction checks complement committed automated browser tests; neither
connection availability nor mocks replace actual playback or required device evidence.
If Chrome is unavailable, use the Codex in-app browser for supported real-page tests.
The user explicitly authorizes this fallback; record the actual browser/version and limitations.
Do not block ordinary browser checks solely on the Chrome extension connection.
Each review fix remains a separate task and commit. Revalidate changed candidate contents.
The user explicitly includes GitHub CI/CD modernization in this refactor.
Follow [refactor/github-ci-cd.md](refactor/github-ci-cd.md) for PR checks, regression matrices,
artifacts, Pages and npm workflows. Distinguish local configuration from verified remote runs.
The user requires every workspace package to move to its own next major version for this
refactor (M.m.p -> (M+1).0.0). Follow refactor/version-policy.md; independent versions and
old API compatibility remain mandatory. This version policy is not publication authorization.
## Project Summary
ArtPlayer is a monorepo for a modern HTML5 video player and its ecosystem packages.
- Homepage: `https://artplayer.org`
- Local dev site: `http://localhost:8082`
- API docs: `https://artplayer.org/document`
- Packaging model: workspace monorepo with per-package versioning and per-package build output
The repository contains:
- `packages/artplayer`: the core player
- `packages/artplayer-plugin-*`: UI and playback plugins
- `packages/artplayer-proxy-*`: proxy renderers and playback adapters
- `packages/artplayer-tool-*`: helper tools
- `packages/artplayer-vitepress`: docs site package
- `docs/`: local demo site, examples, compiled assets, generated docs
- `scripts/`: custom build/dev/doc tooling
## Working Style For This Repo
- Verify the real implementation before editing docs or examples.
- Prefer changing the source package first, then regenerate build artifacts only when needed.
- Keep package APIs small and consistent with existing ArtPlayer plugin conventions.
- Preserve the existing visual and API style of sibling packages instead of inventing a new pattern.
- When touching demo examples, make sure the example still works in `http://localhost:8082`.
- Do not hand-edit `dist/`, `docs/compiled/`, or `docs/uncompiled/` unless a build step generated them.
- Desktop editor sources live in `packages/artplayer-vitepress/browser/`; `docs/assets/js/common.js`,
`bootstrap.js`, `loader.js`, `mobile.js` and `packages/artplayer-vitepress/docs/public/main.js`
are generated with `yarn build:site-assets`. `editor-libraries.ts` is generated by `yarn build:ts`.
## Primary Commands
Use the repo scripts rather than ad hoc bundler commands.
### Development
```bash
yarn dev
```
Starts the local dev site on port `8082` and interactively selects a package to watch. The selected package is built into:
- `docs/uncompiled/<package>/`
### Production Build
```bash
yarn build
```
Interactive build for one package. Outputs:
- `packages/<name>/dist/*.js|*.legacy.js|*.mjs`
- copied artifacts into `docs/compiled/`
Build all packages:
```bash
yarn build all
```
### Other Project Scripts
```bash
yarn build:i18n
yarn build:ts
yarn build:docs
yarn build:llm
yarn build:test
yarn lint
yarn build:all
```
Notes:
- `yarn lint` is read-only; `yarn lint:fix` explicitly fixes the same source/type/script range.
- `yarn ci:check` runs strict toolchain/plan/lint/tests; `yarn ci:build` generates outputs and checks imports.
- See `refactor/ci-setup.md` for CI and separate Pages deployment; remote activation is tracked separately.
- `yarn build:all` is expensive; use it when a change truly spans builds/docs/types/lint together.
## Useful Local URLs
- Root demo index: `http://localhost:8082`
- Demo by package/example:
- `http://localhost:8082/?libs=./uncompiled/<package>/index.js&example=<example>`
- Docs: `http://localhost:8082/document/`
For proxy/plugin work, prefer validating on the local demo page rather than reasoning only from source.
## Repository Layout
### Core package
- `packages/artplayer/src/index.ts`: player entry
- `packages/artplayer/src/player/`: playback mixins and player-facing behavior
- `packages/artplayer/src/control/`: bottom controls
- `packages/artplayer/src/setting/`: settings panel
- `packages/artplayer/src/contextmenu/`: context menu items
- `packages/artplayer/src/plugins/`: built-in plugins
- `packages/artplayer/src/utils/`: shared helpers, component base classes, DOM utilities
- `packages/artplayer/public/`: public TypeScript declaration sources
- `packages/artplayer/types/`: generated public declarations and compatibility documentation
### Ecosystem packages
Migrated ecosystem packages follow this pattern:
```text
packages/<package>/
src/index.ts
src/*.ts # internal modules; see the package maintenance map
src/*.less # optional
types/*.d.ts # public compatibility declarations
ARCHITECTURE.md # maintenance map, or a maintenance section in README.md
README.md
package.json
dist/*
```
Read the package maintenance map before changing module ownership. Some packages
also expose accurate types through `/runtime`, with `.d.mts`/`.d.cts` declarations.
Do not replace historical root declarations with internal implementation types;
follow [the approved type policy](refactor/type-compatibility-policy.md) and each
package's recorded compatibility decisions. Check package.json for exact exports.
### Demo and docs assets
- `docs/assets/example/*.js`: runnable browser examples
- `docs/assets/ts/*.js`: TypeScript demo assets targeted by lint/docs flows
- `docs/uncompiled/`: dev output
- `docs/compiled/`: production-copied output
- `docs/document/`: generated docs content
## Architecture Notes
### Core player
ArtPlayer composes many subsystems during construction. Common integration points:
- `art.template`
- `art.events`
- `art.controls`
- `art.setting`
- `art.contextmenu`
- `art.layers`
- `art.plugins`
- `art.player`
When extending behavior, prefer integrating with these existing systems rather than bypassing them.
### Control and setting components
Controls and setting entries are managed through component registries.
Relevant implementation:
- `packages/artplayer/src/control/index.ts`
- `packages/artplayer/src/setting/index.ts`
- `packages/artplayer/src/utils/component.ts`
Important behavior:
- `art.controls.update(...)` and `art.setting.update(...)` replace existing entries by `name`
- `art.controls.remove(name)` and `art.setting.remove(name)` are the correct cleanup APIs
- selector-style controls rely on `default` flags to determine highlighted items
If a plugin conditionally shows UI, it must also clean that UI up when the condition no longer holds.
### Plugin shape
Standard plugin/export shape:
```js
export default function somePlugin(option = {}) {
return (art) => {
return {
name: 'somePlugin',
}
}
}
```
Naming conventions:
- package: `artplayer-plugin-<name>`
- global: `artplayerPlugin<Name>`
- exported function name should match the global naming convention
### Proxy packages
Proxy packages usually return a non-video element or video-like shim and emulate media element behavior for ArtPlayer.
Examples:
- `packages/artplayer-proxy-canvas`
- `packages/artplayer-proxy-mediabunny`
When editing proxy packages:
- keep the HTMLMediaElement-like surface coherent
- keep event ordering stable
- treat `loadedmetadata`, `loadeddata`, `canplay`, `seeked`, `waiting`, and `pause/play` semantics carefully
- ensure UI state is updated and cleaned up when source topology changes
### HLS / adaptive playback controls
The reference implementation for adaptive selector UI is:
- `packages/artplayer-plugin-hls-control/src/index.ts`
- `packages/artplayer-plugin-dash-control/src/index.ts` (SDK 4.x/5.x capability adapter)
If adding HLS-like quality/audio selection elsewhere:
- follow the selector format used there
- derive highlighted items from actual current tracks, not only from mode flags
- avoid stale selectors when changing to streams without the same topology
## Build and Artifact Rules
- Always edit source first: core runtime in `src/`, core declarations in `public/`;
other packages retain `types/` until their own declaration source migration.
- Rebuild package artifacts after source changes that should ship.
- Do not treat `dist/` as source of truth.
- If a change affects demo behavior, also verify the matching file in `docs/assets/example/`.
For package-specific builds, the normal flow is:
1. `yarn dev` and pick the package for fast local iteration
2. validate in `http://localhost:8082`
3. `yarn build` and pick the package when ready to update shippable artifacts
## Documentation Expectations
If a public package API changes, check whether these also need updates:
- the package `README.md`
- `docs/assets/example/<name>.js`
- `types/<name>.d.ts`
- any generated compiled outputs if you built the package
Keep examples realistic and runnable. Prefer local demo URLs or stable public sample streams.
## Code Quality Expectations
- Follow the existing TypeScript style for migrated production modules and the
existing JavaScript style for tests, launchers and documented legacy exceptions.
- Use ASCII unless a file already requires otherwise.
- Match the minimal-comment style of neighboring files.
- Avoid unnecessary abstraction; this codebase generally prefers direct implementation.
- Respect current browser targets:
- modern build: `es2020`
- legacy build: `es2015`
## Validation Checklist
For most package changes, validate as many of these as apply:
- source file lint passes
- local demo page loads
- expected events fire once and in the correct order
- controls/settings render correctly
- cleanup works after restart, source switch, or destroy
- package build succeeds
For playback/proxy changes specifically:
- test initial load
- test play/pause
- test seek
- test switching source or track topology
- test whether UI reflects the actual selected track/quality
## Notes Specific To `artplayer-proxy-mediabunny`
This package now depends on modern `mediabunny` and supports HLS through `mediabunny` input handling.
Files to understand first:
- `packages/artplayer-proxy-mediabunny/ARCHITECTURE.md`
- `packages/artplayer-proxy-mediabunny/src/index.ts`
- `packages/artplayer-proxy-mediabunny/src/VideoShim.ts`
- `packages/artplayer-proxy-mediabunny/src/MediaBunnyEngine.ts`
- `packages/artplayer-proxy-mediabunny/src/input.ts`
- `packages/artplayer-proxy-mediabunny/src/m3u8.ts`
Key expectations:
- HLS source detection should happen in `input.ts`
- track selection should use actual pairable audio/video relationships
- selector UI should mirror the behavior of `artplayer-plugin-hls-control`
- selector cleanup is required when a later source no longer supports the same controls
- avoid duplicate readiness events during load and track switches
For sustained playback, use `yarn test:mediabunny-soak` with explicit artifacts and
media; see [the long-test procedure](refactor/changes/2026-09-16-PKG-MB-09-hour-soak.md).
It shares port 8084 with ordinary browser tests. Do not start another browser
server or change the measured source, artifacts or media during a live run.
Use its live process handle and per-case progress samples to check progress;
an old report or a start snapshot does not prove current execution or completion.
## When Unsure
Start with the nearest sibling implementation instead of inventing a new pattern:
- control/setting UI: `artplayer-plugin-hls-control`, `artplayer-plugin-dash-control`
- proxy behavior: `artplayer-proxy-canvas`, `artplayer-proxy-mediabunny`
- component lifecycle: `packages/artplayer/src/utils/component.ts`
If a change spans source, examples, and packaging, make all three consistent in the same pass.