mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 10:56:43 -08:00
* perf(tooling): compositing probe, report command and route-wide clip-mask guard Make the instrument that found the dashboard's clip masks part of the repository: `src/performance/compositing-probe.ts` reads the layer tree over CDP (bounds in device pixels, compositing reasons and owner nodes, waiting for Blink's layer debug info), classifies synthesized clip masks (no owner node and no compositing reason) and reads the renderer's `cc/tile_memory` from a memory-infra dump. `pnpm run perf:compositing` seeds one profile against the Xtream mock on a dedicated port, serves the artwork from memory, fixes the window at 1600x1000 and records tile and image memory, layer counts, the largest layers, masks and tile warnings for Live TV, the movie and series details, the dashboard (idle, crossfade, scrolled) and settings into dist/performance/compositing/<timestamp>/summary.json and a console table. Both helpers have node:test coverage in the performance harness. The dashboard-only compositing E2E becomes `compositing.e2e.ts` and guards Live TV, a movie detail, a series detail and the dashboard in one launch, with the backdrop-filtered controls confirmed as composited layers on the dashboard and the movie detail. The rule now lives where it triggers: a Rendering Cost section in the theme/style skill, a validation line in the UI design skill, a context map row, and a Compositing budget section in the performance journeys contract (budget, mask mechanism, instruments, why megabytes are evidence rather than a ratchet). Validation map and README mention the command. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(tooling): sample the dashboard idle reading with rotation paused The hero advances after 8 s, so a 9 s wait sampled the next slide one second into its zoom (backdrop scale 1.116 instead of 1.1, the previous slide's tiles still pooled): 224 MB read as idle, 122 MB with rotation paused and the zoom and tile pool settled. The warning delta and its checkpoint are now taken at one boundary after the sampling, so a "tile memory limits exceeded" line logged while the layers or the dump are read counts for that route instead of for none. The report's test artifacts go under dist/test-results like the other configs'. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(tooling): retry a memory dump that carries no renderer tile memory One reading of seven came back without `cc/tile_memory`: the dump's trace events reach the buffer shortly after the request resolves, and a process can skip a dump it is busy for. The capture now waits briefly before ending the trace and retries up to three times before a reading stays null. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(tooling): run the compositing report with motion enabled With the OS set to reduced motion the hero neither rotates nor renders its pause button, so the report's click timed out before the summary was written. The report now emulates `prefers-reduced-motion: no-preference`, which also keeps the idle and crossfade readings on the same animation set on every machine. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(tooling): sample the crossfade frozen, count split stderr lines, drop stale layer samples Review findings on the pushed head, plus the CI failure: - A layer that vanished between the LayerTree snapshot and its reasons query was kept with empty reasons; without an owner node it would pass for a synthesized mask. Such a snapshot is now discarded and retaken. - The crossfade reading sampled layers, owners and memory across the 700 ms fade, so the row depended on how long the sampling took. The page's animations are frozen 300 ms into the fade while the reading is taken, resumed afterwards, and the incoming slide's zoom is allowed to finish before the scrolled reading. - A stderr chunk can end mid-line; the warning counter now keeps the unfinished line for the next chunk. - The mock server's launch spec lists the new Playwright config. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
427 lines
22 KiB
Markdown
427 lines
22 KiB
Markdown
# IPTVnator - IPTV Player Application
|
|
|
|
<p align="center">
|
|
<img src="https://raw.githubusercontent.com/4gray/iptvnator/electron/src/assets/icons/favicon.256x256.png" alt="IPTVnator icon" title="Free IPTV player application" />
|
|
</p>
|
|
<p align="center">
|
|
<a href="https://github.com/4gray/iptvnator/releases"><img src="https://img.shields.io/github/release/4gray/iptvnator.svg?style=for-the-badge&logo=github" alt="Release"></a>
|
|
<a href="https://github.com/4gray/iptvnator/releases"><img src="https://img.shields.io/github/v/release/4gray/iptvnator?include_prereleases&label=pre-release&logo=github&style=for-the-badge" /></a>
|
|
<a href="https://github.com/4gray/iptvnator/actions/workflows/ci.yml"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/4gray/iptvnator/ci.yml?branch=master&style=for-the-badge&logo=github&label=CI"></a> <a href="https://github.com/4gray/iptvnator/releases"><img src="https://img.shields.io/github/downloads/4gray/iptvnator/total?style=for-the-badge&logo=github" alt="Releases"></a> <a href="https://app.codecov.io/gh/4gray/iptvnator"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/4gray/iptvnator?branch=master&style=for-the-badge&logo=codecov&logoColor=white"></a> <a href="https://t.me/iptvnator"><img src="https://img.shields.io/badge/telegram-iptvnator-blue?logo=telegram&style=for-the-badge" alt="Telegram"></a> <a href="https://bsky.app/profile/iptvnator.bsky.social"><img src="https://img.shields.io/badge/bluesky-iptvnator-darkblue?logo=bluesky&style=for-the-badge" alt="Bluesky"></a>
|
|
</p>
|
|
|
|
🌐 **[Website](https://4gray.github.io/iptvnator/)** | <a href="https://t.me/iptvnator">Telegram channel for discussions</a> | <a href="https://ko-fi.com/4gray" target="_blank">Buy me a coffee</a> | <a href="https://github.com/sponsors/4gray">GitHub Sponsors</a>
|
|
|
|
**IPTVnator** is a video player application that provides support for IPTV playlist playback (m3u, m3u8). The application allows users to import playlists using remote URLs or by uploading files from the local file system. Additionally, it supports EPG information in XMLTV format which can be provided via URL.
|
|
|
|
The application is a cross-platform, open-source project built with Electron and Angular.
|
|
|
|
⚠️ Note: IPTVnator does not provide any playlists or other digital content. The channels and pictures in the screenshots are for demonstration purposes only.
|
|
|
|
> [!IMPORTANT]
|
|
> **Official sources only.** IPTVnator is a free, open-source **player** — it never sells IPTV subscriptions, channels, or playlists. Websites offering "IPTVnator subscriptions/channels/premium/activated" builds are **not affiliated** with this project. Get the app only from the [official website](https://4gray.github.io/iptvnator/) or [GitHub Releases](https://github.com/4gray/iptvnator/releases). See [Beware of unofficial IPTVnator websites and IPTV services](https://4gray.github.io/iptvnator/blog/beware-unofficial-iptvnator-websites/) for details.
|
|
|
|

|
|
|
|
## Features
|
|
|
|
**Playlists & sources**
|
|
|
|
- M3U / M3U8 playlists from local files or remote URLs 📂, with automatic updates on startup
|
|
- Xtream Codes (XC) and Stalker / Ministra (STB) portal support
|
|
- Custom "User-Agent" header per playlist
|
|
|
|
**Playback**
|
|
|
|
- Built-in HTML5 player (HLS.js or Video.js) with a resizable, resumable inline view
|
|
- Optional unified IPTVnator controls for HTML5, Video.js, and ArtPlayer, enabled in **Settings → Playback** _(experimental)_
|
|
- External players — MPV, VLC, and IINA on macOS (`mpv.app` / `VLC.app` bundle paths supported) _(desktop)_
|
|
- Embedded MPV — native mpv rendered inside the app window on macOS, Windows & Linux 🖥️ _(experimental · desktop)_
|
|
- Dedicated radio player for `radio="true"` streams 📻
|
|
|
|
**Live TV & EPG**
|
|
|
|
- EPG / XMLTV TV guide with a live timeline ribbon and multi-channel grid _(desktop)_
|
|
- TV archive / catch-up / timeshift _(desktop)_
|
|
- Group-based channel list, channel-number selection, and search 🔍
|
|
|
|
**Movies & series (VOD)**
|
|
|
|
- Redesigned two-state detail pages (browse ↔ watch) with season tabs and resume positions
|
|
- Download manager for offline movies & episodes ⬇️ _(desktop)_
|
|
- "Recently added" feeds and category grids with sorting & pagination
|
|
|
|
**Discovery & metadata**
|
|
|
|
- Global search across live TV, movies, and series _(desktop)_
|
|
- TMDB enrichment (opt-in, requires your own TMDB API key) — plots, cast & crew, trailers, ratings, artwork, a "Similar" rail, clickable actor pages, and a trending dashboard rail _(trending rail: desktop)_
|
|
- Dashboard with recently watched & continue-watching
|
|
|
|
**Organization**
|
|
|
|
- Per-playlist and global favorites, aggregated across all playlists ⭐
|
|
- Recently viewed / watch history
|
|
- Command palette (`Ctrl/Cmd+K`) that also finds and opens individual settings
|
|
- Settings search from the header search box on the Settings page
|
|
|
|
**Platform**
|
|
|
|
- Cross-platform desktop (Electron) and installable PWA
|
|
- Desktop auto-updater and mobile remote control _(desktop)_
|
|
- Docker self-hosting for the PWA + web backend
|
|
- 19 languages ([translation files](apps/web/src/assets/i18n/)), light & dark themes, and keyboard shortcuts
|
|
|
|
## Keyboard shortcuts
|
|
|
|
Press `?` or `Shift+/` in the workspace to open the in-app shortcuts list.
|
|
|
|
| Area | Shortcut | Action |
|
|
| ----------------- | --------------------------- | ---------------------------------------------------------- |
|
|
| Global | `Ctrl/Cmd+K` | Open command palette |
|
|
| Global | `Ctrl/Cmd+F` | Open global search (desktop); on Settings, search settings |
|
|
| Global | `Ctrl/Cmd+R` | Open recently viewed in the desktop app |
|
|
| Global | `Enter` in workspace search | Submit the search; on Settings, open the best match |
|
|
| Global | `F11` | Toggle app window fullscreen in the desktop app |
|
|
| Navigation | `Ctrl/Cmd+B` | Toggle the live sidebar |
|
|
| Navigation | `0-9` | Select an M3U channel by number |
|
|
| Playback | `Space` / `K` | Play or pause playback |
|
|
| Playback | `F` | Toggle player fullscreen |
|
|
| Playback | `ArrowLeft` / `ArrowRight` | Seek VOD playback by 5 seconds |
|
|
| Playback | `ArrowUp` / `ArrowDown` | Adjust volume by 5% |
|
|
| Playback | `M` | Mute audio |
|
|
| Dialogs and lists | `ArrowUp` / `ArrowDown` | Move command palette selection |
|
|
| Dialogs and lists | `Enter` | Run the selected command or open a focused item |
|
|
| Dialogs and lists | `Escape` | Close dialogs and dismiss overlays |
|
|
|
|
The desktop app can also open at its last size, maximized, or fullscreen on
|
|
every launch (Settings → General → "Window on startup"), and `iptvnator
|
|
--fullscreen` forces a single fullscreen launch for TV or HTPC autostart
|
|
scripts without changing that setting.
|
|
|
|
## Screenshots:
|
|
|
|
| Dashboard with recently watched content | Live channels with inline player and EPG |
|
|
| :-------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: |
|
|
|  |  |
|
|
| Add playlist dialog for M3U, Xtream, and Stalker | Live category channel list |
|
|
|  |  |
|
|
| Global search across live TV, movies, and series | Manage visible live categories |
|
|
|  |  |
|
|
| Movie category grid with sorting and pagination | Recently added movies and series |
|
|
|  |  |
|
|
| VOD details with playback and download actions | Download manager |
|
|
|  |  |
|
|
| Multi-channel EPG grid | External MPV player support |
|
|
|  |  |
|
|
| Radio playback with dedicated audio player | Light theme |
|
|
|  |  |
|
|
| Application settings | |
|
|
|  | |
|
|
|
|
_Note: First version of the application which was developed as a PWA is available in an extra git branch._
|
|
|
|
## Self-hosted PWA
|
|
|
|
The Docker setup builds the Angular PWA and the monorepo web backend into one
|
|
image. The backend handles remote M3U parsing plus Xtream and Stalker proxy
|
|
requests under `/api`, so a separate `4gray/iptvnator-backend` container is not
|
|
required for the default self-hosted flow.
|
|
|
|
```bash
|
|
docker compose -f docker/docker-compose.yml up --build -d
|
|
```
|
|
|
|
The application is available at <http://localhost:4333>. See
|
|
[`docker/docker-compose.yml`](./docker/docker-compose.yml) for the ready-to-run
|
|
compose file and [`docker/README.md`](./docker/README.md) for environment
|
|
variables, reverse proxy notes, PWA limitations, and build details.
|
|
|
|
The self-hosted image runs the browser PWA rather than the Electron desktop app:
|
|
EPG/XMLTV panels, Embedded MPV, managed MPV/VLC launching, the download manager,
|
|
and Electron remote-control features are not available there. If browser
|
|
playback fails, copy the stream URL and open it manually in an external player
|
|
such as MPV, VLC, or IINA.
|
|
|
|
## Download
|
|
|
|
Download the latest version of the application for macOS, Windows, and Linux from the [release page](https://github.com/4gray/iptvnator/releases).
|
|
|
|
Alternatively, you can install the application using one of the following package managers:
|
|
|
|
### Nightly builds
|
|
|
|
Every merge into `master` is published as a prerelease in
|
|
[4gray/iptvnator-nightly](https://github.com/4gray/iptvnator-nightly). The
|
|
desktop app can follow them: **Settings → About → Update channel → Nightly**
|
|
offers each new build through the built-in updater (macOS, Windows, and the
|
|
Linux AppImage). Nightly builds are untested snapshots — they may break, and
|
|
their database changes are permanent, so switching back to **Stable** keeps
|
|
the installed nightly until the next stable release is newer. Back up your
|
|
playlists first, and mention the version and commit shown in *About* when
|
|
reporting a bug from a nightly.
|
|
|
|
### Homebrew
|
|
|
|
```shell
|
|
$ brew install iptvnator
|
|
```
|
|
|
|
### Snap
|
|
|
|
```shell
|
|
$ sudo snap install iptvnator
|
|
```
|
|
|
|
### Arch
|
|
|
|
Also available as an Arch PKG, [iptvnator-bin](https://aur.archlinux.org/packages/iptvnator-bin/), in the AUR (using your favourite AUR-helper, .e.g. `yay`)
|
|
|
|
```shell
|
|
$ yay -S iptvnator-bin
|
|
```
|
|
|
|
### Gentoo
|
|
|
|
You can install IPTVnator from the [gentoo-zh overlay](https://github.com/microcai/gentoo-zh)
|
|
|
|
```shell
|
|
sudo eselect repository enable gentoo-zh
|
|
sudo emerge --sync gentoo-zh
|
|
sudo emerge iptvnator-bin
|
|
```
|
|
|
|
### Linux Embedded MPV Support
|
|
|
|
Embedded MPV on Linux is experimental and currently supports x64 desktop
|
|
sessions where IPTVnator runs under X11 or Xwayland. Native Wayland embedding
|
|
is not supported yet. Linux package launchers request X11 with
|
|
`--ozone-platform=x11`, so Wayland desktops still need Xwayland available.
|
|
|
|
The Linux backend starts a system `mpv` executable with `--wid`, so `mpv` must
|
|
be installed and available on `PATH`. CI validates the Linux native addon and
|
|
standard packages on Ubuntu 22.04, with Flatpak packaging built on Ubuntu 24.04.
|
|
Expected user targets are Ubuntu/Debian `.deb`, Arch/Manjaro `pacman`, RPM
|
|
distributions, and AppImage on x64 systems with X11/Xwayland plus `mpv`
|
|
installed. Flatpak and Snap builds remain available, but embedded MPV is not
|
|
announced as supported there yet because those sandboxed formats do not expose
|
|
the host `mpv` executable to the embedded backend by default.
|
|
|
|
[](https://snapcraft.io/iptvnator)
|
|
|
|
<a href="https://github.com/sponsors/4gray" target="_blank"><img src="https://img.shields.io/badge/GitHub%20Sponsors-EA4AAA?style=for-the-badge&logo=githubsponsors&logoColor=white" alt="Sponsor on GitHub"></a>
|
|
<a href="https://ko-fi.com/4gray" target="_blank"><img src="https://img.shields.io/badge/Ko--fi-FF5E5B?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Support on Ko-fi"></a>
|
|
|
|
## Troubleshooting
|
|
|
|
### macOS: "App is damaged and can't be opened"
|
|
|
|
Older unsigned macOS builds may require removing the quarantine flag from the downloaded application:
|
|
|
|
```bash
|
|
xattr -c /Applications/IPTVnator.app
|
|
```
|
|
|
|
Alternatively, if the app is located in a different directory:
|
|
|
|
```bash
|
|
xattr -c ~/Downloads/IPTVnator.app
|
|
```
|
|
|
|
### Linux: chrome-sandbox Issues
|
|
|
|
If you encounter the following error when launching IPTVnator:
|
|
|
|
```
|
|
The SUID sandbox helper binary was found, but is not configured correctly.
|
|
Rather than run without sandboxing I'm aborting now.
|
|
You need to make sure that chrome-sandbox is owned by root and has mode 4755.
|
|
```
|
|
|
|
**Solution 1: Fix chrome-sandbox permissions (Recommended for .deb/.rpm installations)**
|
|
|
|
Navigate to the IPTVnator installation directory and run:
|
|
|
|
```bash
|
|
sudo chown root:root chrome-sandbox
|
|
sudo chmod 4755 chrome-sandbox
|
|
```
|
|
|
|
**Solution 2: Launch with --no-sandbox flag**
|
|
|
|
Edit the desktop launcher file to add the `--no-sandbox` flag:
|
|
|
|
1. Find your desktop file location:
|
|
- **Ubuntu/Debian**: `~/.local/share/applications/iptvnator.desktop`
|
|
- **System-wide**: `/usr/share/applications/iptvnator.desktop`
|
|
|
|
2. Edit the file and modify the `Exec` line:
|
|
|
|
```
|
|
Exec=iptvnator --no-sandbox %U
|
|
```
|
|
|
|
3. Save the file and relaunch the application from your application menu.
|
|
|
|
Alternatively, you can launch IPTVnator from the terminal with the flag:
|
|
|
|
```bash
|
|
iptvnator --no-sandbox
|
|
```
|
|
|
|
### GNU/Linux: Wayland startup failure
|
|
|
|
If IPTVnator exits on GNU/Linux with errors about failing to connect to
|
|
Wayland or initialize the Ozone platform, force X11/XWayland instead:
|
|
|
|
```bash
|
|
iptvnator --ozone-platform=x11
|
|
```
|
|
|
|
This workaround is mainly for older or problematic Linux graphics stacks. The
|
|
Snap package already includes this X11 override by default. For AppImage,
|
|
direct binaries, and other Linux package formats, pass the flag manually when
|
|
needed.
|
|
|
|
## How to Build and Develop
|
|
|
|
Requirements:
|
|
|
|
- Node.js 22.22.3 or newer within 22.x, or 24.15.0 or newer within 24.x
|
|
- pnpm 10.33.0 (via Corepack)
|
|
|
|
The repository's `.nvmrc` pins the Node.js version used by CI. With nvm,
|
|
run `nvm install` and `nvm use` from the repository root to use the same version
|
|
for local development.
|
|
|
|
1. Clone this repository and install project dependencies:
|
|
|
|
```
|
|
$ nvm install
|
|
$ nvm use
|
|
$ corepack enable
|
|
$ pnpm install
|
|
```
|
|
|
|
2. Start the application:
|
|
```
|
|
$ pnpm run serve:backend
|
|
```
|
|
|
|
This will open the Electron app in a separate window, while the Angular dev server will run at http://localhost:4200.
|
|
|
|
The equivalent Nx command is:
|
|
|
|
```
|
|
$ nx serve electron-backend
|
|
```
|
|
|
|
To start Electron with an empty, isolated data directory instead of your normal
|
|
`~/.iptvnator` folder, set `IPTVNATOR_E2E_DATA_DIR` for that run:
|
|
|
|
```
|
|
$ rm -rf .tmp/iptvnator-empty && mkdir -p .tmp/iptvnator-empty
|
|
$ IPTVNATOR_E2E_DATA_DIR="$PWD/.tmp/iptvnator-empty" pnpm run serve:backend
|
|
```
|
|
|
|
This redirects the SQLite database, Electron user data, and local config under
|
|
the given directory. Delete that directory whenever you want a fresh empty
|
|
state.
|
|
|
|
If you need startup diagnostics for a white screen or a frozen route, you can
|
|
also turn on opt-in Electron tracing. These logs are written to the Electron
|
|
terminal output so they still help when the renderer DevTools never open:
|
|
|
|
```
|
|
$ IPTVNATOR_TRACE_STARTUP=1 pnpm run serve:backend
|
|
```
|
|
|
|
Nx equivalent:
|
|
|
|
```
|
|
$ IPTVNATOR_TRACE_STARTUP=1 nx serve electron-backend
|
|
```
|
|
|
|
Useful narrower flags:
|
|
|
|
- `IPTVNATOR_TRACE_IPC=1` logs renderer `window.electron.*` calls reaching the
|
|
Electron bridge
|
|
- `IPTVNATOR_TRACE_DB=1` logs DB worker requests and request-scoped DB events
|
|
- `IPTVNATOR_TRACE_SQL=1` logs SQLite statements in both the main connection and
|
|
DB worker connection
|
|
- `IPTVNATOR_TRACE_WINDOW=1` logs BrowserWindow load, navigation, and
|
|
unresponsive events
|
|
- `IPTVNATOR_TRACE_RENDERER_CONSOLE=1` mirrors renderer console messages into
|
|
the Electron terminal output
|
|
|
|
Security-sensitive network compatibility flags are opt-in:
|
|
|
|
- `IPTVNATOR_ALLOW_PRIVATE_NETWORK_URLS=1` permits strict EPG fetches from
|
|
playlist metadata (`x-tvg-url`, `url-tvg`, or `tvg-url`) to resolve to
|
|
localhost, LAN, or other private addresses. Directly configured
|
|
Xtream/Stalker portals and private playlist servers remain supported without
|
|
this flag. Prefer the in-app source-scoped “Allow source” action for a trusted
|
|
EPG URL.
|
|
- `IPTVNATOR_ALLOW_INSECURE_TLS=1` disables certificate validation for remote
|
|
playlist imports and refreshes for the whole Electron process. Prefer the
|
|
in-app host-scoped trust action for a trusted provider with a self-signed or
|
|
otherwise invalid certificate.
|
|
|
|
If the local Nx daemon gets into a bad state before rerunning Electron, reset it:
|
|
|
|
```
|
|
$ pnpm nx reset
|
|
```
|
|
|
|
To run only the Angular app without Electron, use:
|
|
|
|
```
|
|
$ pnpm run serve:frontend
|
|
```
|
|
|
|
To see how many bytes the built web app puts on the initial load path (the
|
|
number the CI ratchet guards), build it and run the measurement:
|
|
|
|
```
|
|
$ pnpm nx build web
|
|
$ pnpm run perf:initial-bytes
|
|
```
|
|
|
|
The contract behind that number is in
|
|
[docs/architecture/performance-journeys.md](docs/architecture/performance-journeys.md).
|
|
|
|
To benchmark the "launch to usable", "open a source" and "start playback"
|
|
journeys (fresh Electron processes on a seeded profile against the local
|
|
Xtream mock, exact renderer counters plus wall-clock), run:
|
|
|
|
```
|
|
$ pnpm run perf:journeys
|
|
```
|
|
|
|
The journeys, their counters and the summary written under
|
|
`dist/performance/journeys/` are described in
|
|
[docs/architecture/performance-journeys.md](docs/architecture/performance-journeys.md).
|
|
`pnpm run perf:compositing` measures the renderer's tile memory and composited
|
|
layers on the dashboard, the detail pages, Live TV and settings (the
|
|
"compositing budget" section of the same document).
|
|
|
|
## Disclaimer
|
|
|
|
**IPTVnator doesn't provide any playlists or other digital content.**
|
|
|
|
## Trademark
|
|
|
|
The name **"IPTVnator"** and the IPTVnator logo are unregistered trademarks of the project owner. The MIT license covers the source code only — it does **not** grant rights to the name or logo. Forks and redistributions (including app-store submissions) must use a different name and their own icon. See [TRADEMARK.md](./TRADEMARK.md) for details.
|
|
|
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
|
|
[](#contributors)
|
|
|
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
|
|
## Developer and agent documentation
|
|
|
|
Start with the [task context map](docs/maintenance/agent-context-map.md) to find
|
|
the authoritative contract and validation for your area. Common agent rules are
|
|
in [AGENTS.md](AGENTS.md); Claude Code imports that same file. Development and
|
|
documentation-maintenance conventions live in the
|
|
[agent workflow](docs/development/agent-workflow.md).
|