mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-30 20:49:22 +00:00
merge main and harden canonical media recovery
This commit is contained in:
+16
-5
@@ -118,17 +118,28 @@ Before starting any task, committing, or pushing, you **MUST** run `git pull --r
|
||||
> [!CAUTION]
|
||||
> **AI AGENTS MUST FOLLOW THIS EXACT SEQUENCE WHEN RELEASING A NEW VERSION OR TAGGING.**
|
||||
>
|
||||
> **🚫 NO MANUAL VERSION BUMPING**: You MUST **NEVER** manually modify the version strings in `package.json`, `extension/manifest.base.json`, or `website/version.json`. The GitHub Actions CI pipeline automatically extracts the version from the git tag (e.g. `v2.0.5` -> `2.0.5`), injects it into all target files, and commits the updates back to `main` with `[skip ci]`. Manual bumps will cause merge conflicts and build failures.
|
||||
> **🚫 NO INDEPENDENT VERSION EDITS**: Never edit only one version source. The
|
||||
> annotated SemVer tag workflow extracts the version, updates every source,
|
||||
> validates them, and pushes its generated `[skip ci]` version commit directly
|
||||
> to `main`.
|
||||
> - **Website Versioning**: **NEVER** manually modify generated version strings in `website/www/`. The website build injects version data from `website/version.json` into generated output.
|
||||
1. **MANDATORY SYNTAX & LINT CHECKS**: Before staging, committing, or pushing any changes, you **MUST** run both checks on every modified JavaScript file:
|
||||
- **Syntax Validation**: Run `node -c` on every single modified JavaScript file (e.g., `node -c extension/background.js` and `node -c extension/content.js`). **NEVER** commit or push code that fails this check.
|
||||
- **ESLint Validation**: Run `npm run lint` (or `npx eslint .`). The output must show **zero errors and zero warnings**. ESLint is configured to catch undefined variables, unused vars, unreachable code, and other semantic issues. **NEVER** commit or push code that fails this check.
|
||||
2. Commit all verified code changes and push to `main`.
|
||||
3. Create and push a new tag. **MANDATORY**: Tags MUST start with a `v` (e.g., `v1.4.0`). The GitHub Actions release workflow is strictly configured to ignore any tags without the `v` prefix.
|
||||
2. Commit and push the verified product/release-note changes to `main`, then
|
||||
wait for `verify`, `node20`, and `e2e` on the exact `origin/main` commit.
|
||||
Markdown-only changes do not require browser or release gates.
|
||||
3. From a clean, fast-forwarded `main`, create an annotated exact SemVer tag
|
||||
(`git tag -a v1.4.0 -m "Release v1.4.0"`) on that same commit and push it once.
|
||||
- **🚫 TAG IMMUTABILITY**: Once a tag is pushed to `origin`, it is **PERMANENT**. You MUST **NEVER** reuse, move, or force-push an existing tag — not even to "fix" a mistake. If a release is missing a fix, increment the version and create a **new** tag (e.g., `v1.7.0` → `v1.7.1`). Tags are immutable identifiers; moving them breaks CI pipelines, corrupts the release history, and causes unreproducible builds.
|
||||
- **🚫 WHEN NOT TO TAG**: Do NOT create a release tag for changes that do NOT affect the shipped extension or server artifacts. Website text changes, documentation updates (`.md` files), and landing page content do NOT require a version tag. Tags trigger the full CI pipeline (Docker build, extension packaging, GitHub Release) — running this for a typo fix wastes CI resources and creates meaningless releases. Only tag when extension code (`extension/`), server code (`server/`), or shared protocol constants (`shared/`) have changed.
|
||||
4. The CI will extract the version from the tag (e.g., `v1.4.0` → `1.4.0`), inject it into all source files, build the extension artifacts, publish the Docker image, and create a GitHub Release.
|
||||
5. Verify the release builds on GitHub Actions.
|
||||
4. The release workflow validates the tag, prepares and validates every version
|
||||
source, pushes the generated version commit to `main`, and builds Chrome,
|
||||
Firefox, website, and relay outputs from that exact prepared commit.
|
||||
5. It creates a draft release, verifies archives, AMO output, checksums,
|
||||
attestations, relay platforms/digest, and health before making the GitHub
|
||||
Release public.
|
||||
6. Verify GitHub assets, attestations, GHCR platforms/digest, and health smoke.
|
||||
|
||||
### 🚫 Force Push Policy
|
||||
> [!CAUTION]
|
||||
|
||||
@@ -51,7 +51,9 @@ notification, command ACK, or relay media event.
|
||||
|
||||
Force Sync remains a two-phase ACK protocol. A valid `PREPARE` is temporary
|
||||
room-wide choreography; the next authorized `EXECUTE` commits the latest target
|
||||
visible to peers to canonical state. Per-sender
|
||||
visible to peers to canonical state before the shared Force Sync timeout. The
|
||||
offline queue replays an adjacent `PREPARE`/`EXECUTE` pair in one paced batch and
|
||||
retains both if delivery fails. Per-sender
|
||||
`seq`, peer heartbeats, and the reconnect queue remain separate mechanisms.
|
||||
|
||||
## 3.2 Offline Media Intent
|
||||
|
||||
@@ -5,6 +5,36 @@ All notable changes to the KoalaSync browser extension and relay server.
|
||||
|
||||
---
|
||||
|
||||
## [v3.1.5] — 2026-08-25
|
||||
|
||||
This patch fixes room-exit cleanup and excessive popup width.
|
||||
|
||||
### Fixed
|
||||
- **Room exit cleanup** — Fully unhooks the selected tab after manual leaves, inactivity timeouts, and room closures.
|
||||
- **Popup width** — Prevents dynamic content from stretching the popup on ultrawide displays.
|
||||
|
||||
## [v3.1.4] — 2026-08-21
|
||||
|
||||
This patch restores player detection on pages that use boxless CSS wrappers,
|
||||
including Crunchyroll, without adding site-specific matching.
|
||||
|
||||
### Fixed
|
||||
- **Extension: Crunchyroll playback synchronization** — Detects and controls
|
||||
Crunchyroll's visible Bitmovin HTML5 player even though the page wraps it in
|
||||
a boxless `display: contents` ancestor. The general fix keeps equivalent
|
||||
players selectable on other sites while continuing to reject hidden players,
|
||||
preloads, ads and background videos.
|
||||
- **Extension: Player discovery during iframe churn** — Keeps stable nested
|
||||
player frames discoverable when rapidly replaced ad frames make Chromium
|
||||
reject an aggregate frame sweep, without restoring the `webNavigation`
|
||||
permission or injecting globally into unselected tabs.
|
||||
|
||||
### Testing
|
||||
- **Regression coverage** — Adds unit and browser E2E coverage for visible
|
||||
players inside `display: contents` wrappers.
|
||||
|
||||
---
|
||||
|
||||
## [v3.1.3] — 2026-08-18
|
||||
|
||||
This release adds generic control for HTML5 players inside nested and cross-origin
|
||||
|
||||
+7
-2
@@ -121,8 +121,9 @@ Only accepted, sanitized room controls update canonical state:
|
||||
established playback state.
|
||||
- a valid `force_sync_prepare` records only temporary coordination state. The
|
||||
next authorized `force_sync_execute` commits the latest room-wide prepared
|
||||
target as playing. The latest valid prepare is also the only post-demotion
|
||||
execute exemption in Host Control mode.
|
||||
target as playing before `FORCE_SYNC_TIMEOUT` expires. Expired targets are
|
||||
cleared and cannot alter canonical state. The latest valid prepare is also
|
||||
the only post-demotion execute exemption in Host Control mode.
|
||||
|
||||
`peer_status` heartbeats are observations and never rewrite canonical intent.
|
||||
Per-sender `seq` still orders commands from one sender; canonical `revision`
|
||||
@@ -168,6 +169,10 @@ This requires no event, capability, ACK, protocol-version, or minimum-version
|
||||
change. Old relays receive ordinary `play`/`pause`/`seek`; old peers see only the
|
||||
same existing relayed events.
|
||||
|
||||
Queued adjacent `force_sync_prepare` and `force_sync_execute` entries replay in
|
||||
one paced batch. If either send fails, the full pair remains queued so a later
|
||||
retry refreshes the prepared target before executing it.
|
||||
|
||||
## Ephemeral encrypted chat
|
||||
|
||||
Relays advertise chat support with `"chat-v1"` in `room_data.capabilities` and keep
|
||||
|
||||
+3
-1
@@ -35,7 +35,9 @@ The build script performs the following actions:
|
||||
The system enforces a strict `protocolVersion` check during the `JOIN_ROOM` handshake.
|
||||
- The version is defined in `shared/constants.js`.
|
||||
- If the extension and server versions mismatch, the server will reject the connection with an `Incompatible protocol version` error.
|
||||
- **Never manually bump version numbers**. The CI pipeline automatically injects the version from the git tag into `manifest.base.json`, `shared/constants.js`, and `package.json` during release builds. Run the build script to synchronize other constant updates.
|
||||
- Never edit release versions independently. The annotated SemVer tag workflow
|
||||
updates and validates every version source, then pushes its generated version
|
||||
commit directly to `main` before building the release.
|
||||
|
||||
> [!CAUTION]
|
||||
> **NEVER** edit the files inside `extension/shared/` directly. They will be overwritten the next time the build script is run. Always edit the files in the root `shared/` directory and then run the build script.
|
||||
|
||||
@@ -20,7 +20,7 @@ This document tracks which streaming platforms and media servers are supported b
|
||||
| **Disney+** | ✅ Full | ⚠️ Partial | ❌ | — | — | — | Series title only (e.g. "The Simpsons"), no episode info. |
|
||||
| **Prime Video** | ✅ Full | ✅ Full | ❌ | — | — | — | — |
|
||||
| **HBO Max / Max** | Not tested | Not tested | Not tested | — | — | — | — |
|
||||
| **Crunchyroll** | Not tested | Not tested | Not tested | — | — | — | — |
|
||||
| **Crunchyroll** (`crunchyroll.com`) | ✅ Full | ⚠️ Partial | ❌ | 2026-08-21 | Shik3i | v3.1.4 | Manual testing on the live service confirmed playback synchronization with its top-level Bitmovin HTML5 player. The Media Session exposes the episode as `E1 - Prologue` and the series as artist metadata, but the current episode parser does not recognize the abbreviated `E1` form for episode auto-sync. |
|
||||
| **Vimeo** | Not tested | Not tested | Not tested | — | — | — | — |
|
||||
| **Dailymotion** | Not tested | Not tested | Not tested | — | — | — | — |
|
||||
| **ARD / ZDF Mediathek** | Not tested | Not tested | Not tested | — | — | — | — |
|
||||
@@ -81,3 +81,8 @@ The currently verified cross-origin service topologies are:
|
||||
- **YummyAnime:** `yummyanime.tv` top page → same-origin wrapper → `thealloha.club` player.
|
||||
|
||||
These embedded origins are implementation details of the services and may change independently. If the browser withholds access to a newly used player origin, KoalaSync asks for that origin through its normal site-access flow.
|
||||
|
||||
Crunchyroll currently exposes its Bitmovin `<video>` directly in the top-level
|
||||
document. Its application layout uses a `display: contents` wrapper, which has
|
||||
no box of its own even while the descendant player is visible; v3.1.4 handles
|
||||
that standards-compliant layout without a Crunchyroll-specific host rule.
|
||||
|
||||
+48
-24
@@ -4,30 +4,38 @@ This document describes the deployment and release process for KoalaSync.
|
||||
|
||||
## Tag-Based Releases
|
||||
|
||||
KoalaSync uses a fully automated release pipeline triggered by Git tags.
|
||||
KoalaSync uses an automated release pipeline triggered by immutable annotated
|
||||
Git tags.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **DO NOT** manually bump the version numbers in any files (such as `package.json`, `manifest.base.json`, `shared/constants.js`, etc.) before creating a release.
|
||||
> Bumping versions manually is redundant, leads to conflicts, and is completely handled by the CI/CD pipeline.
|
||||
> **DO NOT** edit individual version files before tagging. The workflow extracts
|
||||
> the exact SemVer version from the tag and updates every release-version source
|
||||
> atomically. Markdown-only changes do not require browser or release gates.
|
||||
|
||||
### How it Works
|
||||
|
||||
When you push a Git tag matching `v*` (e.g., `v2.5.1`), the GitHub Actions release workflow (`.github/workflows/release.yml`) is triggered. The workflow performs the following actions:
|
||||
When an annotated tag matching exact `vMAJOR.MINOR.PATCH` is pushed, the GitHub
|
||||
Actions workflow performs these ordered gates:
|
||||
|
||||
1. **Extracts the version** from the tag (e.g., `2.5.1` from `v2.5.1`).
|
||||
2. **Injects the version** automatically into the following files:
|
||||
- `extension/manifest.base.json`
|
||||
- `shared/constants.js` (updates `APP_VERSION`)
|
||||
- `package.json`
|
||||
- `package-lock.json` (root package metadata)
|
||||
- `website/version.json`
|
||||
- `website/template.html` (updates `softwareVersion` schema)
|
||||
- `README.md` (updates badge and announcement banner)
|
||||
- `website/sitemap.xml` (updates `lastmod` dates)
|
||||
3. **Commits and pushes** these version updates back to the `main` branch automatically with the commit message `chore(release): update versions to vX.X.X [skip ci]`.
|
||||
4. **Builds the extension** for both Chrome and Firefox and publishes the zipped archives with a `SHA256SUMS` checksum file and signed provenance attestations.
|
||||
5. **Builds the website** and uploads website artifacts.
|
||||
6. **Builds and publishes** the Docker image for the relay server to the GitHub Container Registry (`ghcr.io`).
|
||||
1. Validates that the tag is an annotated exact `vMAJOR.MINOR.PATCH` tag, points
|
||||
at current `origin/main`, and has successful `verify`, `node20`, and `e2e`
|
||||
checks. Invalid tags are rejected before any write.
|
||||
2. Extracts the validated version and uses the tagged commit timestamp so
|
||||
repeated preparation is deterministic.
|
||||
3. Updates and validates all version sources: `extension/manifest.base.json`,
|
||||
`shared/constants.js`, `package.json`, root metadata in `package-lock.json`,
|
||||
`website/version.json`, `website/template.html`, `website/llms.txt`, and both
|
||||
the README badge and release banner.
|
||||
4. Creates `chore(release): update versions to vX.Y.Z [skip ci]` and pushes it
|
||||
directly to `main`. A failed push stops every dependent release job.
|
||||
5. Checks out that exact prepared commit for full verification, cross-browser
|
||||
E2E, the unpublished relay health smoke, Chrome/Firefox/AMO/checksum/archive
|
||||
validation, website output, and the relay container build.
|
||||
6. Creates an attested **draft** GitHub Release after extension checks pass.
|
||||
7. Publishes the canonical lowercase image `ghcr.io/shik3i/koalasync`, then
|
||||
verifies both platforms, attestation identity, digest, tag source, and a
|
||||
running health check.
|
||||
8. Makes the GitHub Release public only after every preceding job succeeds.
|
||||
|
||||
---
|
||||
|
||||
@@ -35,18 +43,34 @@ When you push a Git tag matching `v*` (e.g., `v2.5.1`), the GitHub Actions relea
|
||||
|
||||
To release a new version (e.g., `v2.5.1`), follow these steps:
|
||||
|
||||
1. Make sure your local repository is synced on `main`:
|
||||
1. Fast-forward local `main`, confirm a clean tree at exact `origin/main`, and
|
||||
wait for `verify`, `node20`, and `e2e` on that commit:
|
||||
```bash
|
||||
git checkout main
|
||||
git pull origin main
|
||||
git pull --ff-only origin main
|
||||
test -z "$(git status --porcelain=v1)"
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"
|
||||
```
|
||||
2. Create a local Git tag:
|
||||
2. Create an **annotated** exact SemVer tag on that commit. Do not run
|
||||
`prepare:release`; the tag workflow owns version updates:
|
||||
```bash
|
||||
git tag v2.5.1
|
||||
git tag -a v2.5.1 -m "Release v2.5.1"
|
||||
```
|
||||
3. Push the tag to GitHub:
|
||||
3. Verify the tag target, then push it once:
|
||||
```bash
|
||||
test "$(git rev-parse v2.5.1^{commit})" = "$(git rev-parse origin/main)"
|
||||
git push origin v2.5.1
|
||||
```
|
||||
|
||||
The release pipeline will take care of the rest! You can monitor the progress under the **Actions** tab of the GitHub repository.
|
||||
Never reuse or move a published tag. Monitor every release job and verify both
|
||||
the public GitHub assets and GHCR digest before calling the release complete.
|
||||
|
||||
`npm run release:gate -- MAJOR.MINOR.PATCH [--candidate]` remains an optional
|
||||
Linux/AMD64 parity diagnostic when release code changes. It prepares the target
|
||||
version only inside an isolated clone. It is not required for Markdown-only
|
||||
changes and does not replace the tag workflow's own gates.
|
||||
|
||||
The relay registry reference is always the canonical lowercase
|
||||
`ghcr.io/shik3i/koalasync`. Docker repository names reject uppercase characters;
|
||||
`release:gate` rejects workflows that derive this reference from the
|
||||
case-preserving `${{ github.repository }}` value.
|
||||
|
||||
Reference in New Issue
Block a user