Skip to content

fix: allow undo of clear authorship colors without disconnect#1

Open
deepshekhardas wants to merge 94 commits into
developfrom
fix/undo-clear-authorship
Open

fix: allow undo of clear authorship colors without disconnect#1
deepshekhardas wants to merge 94 commits into
developfrom
fix/undo-clear-authorship

Conversation

@deepshekhardas

@deepshekhardas deepshekhardas commented May 10, 2026

Copy link
Copy Markdown
Owner

Summary

Allows users to undo/redo clear authorship operations without being disconnected.

Changes

  1. Server-side fix (): Author validation now distinguishes between:

    • ops (attribute changes on existing text) — allows restoring other authors' attributes
    • / ops — still rejects if attributed to another author
  2. Client-side workaround removed (): Removed the stopgap that prevented events from being pushed onto the undo stack.

  3. Security fix: op rejection prevents pool injection attack where fabricated author IDs could be smuggled into the pad pool.

Tests

  • 6 backend tests covering multi-author undo, clear with empty author, restore own author, impersonation rejection, fabricated author rejection, and op pool injection prevention.
  • 2 frontend Playwright tests for multi-user and single-user undo flows.

Fixes ether#2802


Summary by cubic

Enables undo/redo of “Clear authorship colors” without disconnecting the user. The server now allows '=' ops to restore existing author IDs and rejects '+'/'-' ops with foreign authors to prevent impersonation and pool injection.

  • Bug Fixes
    • Removed client workaround that blocked clear-authorship events from the undo stack; added backend and Playwright coverage for multi-user undo.
    • Timeslider: Skip identity changesets to prevent playback errors.
    • Lists: Handle pasted bare
    • (defaults to bullet), reset numbering when switching bullet↔numbered lists, and correctly recognize indented lines to keep numbering stable.
    • Pad delete: Wait for server confirmation and await pad.remove(); fixes race that could leave pads undeleted.
    • Group delete: Ignore null session entries left after deleteSession to avoid “sessionID does not exist”.
    • Editor: PageDown now advances by a full page of lines.

Written for commit 02f11dd. Summary will update on new commits.

translatewiki and others added 30 commits February 19, 2026 13:03
Bumps [jsdom](https://github.com/jsdom/jsdom) from 28.0.0 to 28.1.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](jsdom/jsdom@28.0.0...28.1.0)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 28.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [underscore](https://github.com/jashkenas/underscore) from 1.13.7 to 1.13.8.
- [Commits](https://github.com/jashkenas/underscore/commits)

---
updated-dependencies:
- dependency-name: underscore
  dependency-version: 1.13.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [oidc-provider](https://github.com/panva/node-oidc-provider) from 9.6.0 to 9.6.1.
- [Release notes](https://github.com/panva/node-oidc-provider/releases)
- [Changelog](https://github.com/panva/node-oidc-provider/blob/main/CHANGELOG.md)
- [Commits](panva/node-oidc-provider@v9.6.0...v9.6.1)

---
updated-dependencies:
- dependency-name: oidc-provider
  dependency-version: 9.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
basically copy/pasting contributing.md but gives qodo a reference point, I'd of used a sym link but I don't know how well that would have worked so for now lets just add some cruft and see what happens..
* docs: add AGENTS.MD for AI and developer guidance

* docs: update project name from Etherpad Lite to Etherpad

* docs: fix incorrect test directory path in AGENTS.MD

* docs: correct test stack description in AGENTS.MD (Mocha is primary)

* docs: fix incorrect easysync documentation path in AGENTS.MD

* chore: add .pr_agent.toml to enable automatic PR review/description on push

* docs: remove nodejs version from README and AGENTS.MD (prefer package.json)

* docs: standardize all indentation to 2 spaces

* chore: update src/package.json node engine to match root (>=20.0.0)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) from 8.2.1 to 8.2.2.
- [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases)
- [Commits](express-rate-limit/express-rate-limit@v8.2.1...v8.2.2)

---
updated-dependencies:
- dependency-name: express-rate-limit
  dependency-version: 8.2.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](docker/setup-qemu-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…er#7358)

Bumps the dev-dependencies group with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [@types/formidable](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/formidable) | `3.4.6` | `3.5.0` |
| [@types/jquery](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jquery) | `3.5.33` | `4.0.0` |
| [@types/jsdom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jsdom) | `27.0.0` | `28.0.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.2.3` | `25.3.5` |
| [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) | `6.0.3` | `7.2.0` |
| [@types/whatwg-mimetype](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/whatwg-mimetype) | `3.0.2` | `5.0.0` |
| [eslint](https://github.com/eslint/eslint) | `10.0.0` | `10.0.3` |
| [sinon](https://github.com/sinonjs/sinon) | `21.0.1` | `21.0.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.55.0` | `8.56.1` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.55.0` | `8.56.1` |
| [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) | `0.5.0` | `0.5.2` |
| [i18next](https://github.com/i18next/i18next) | `25.8.8` | `25.8.16` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.564.0` | `0.577.0` |
| [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.71.1` | `7.71.2` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.5.4` | `16.5.6` |
| [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) | `7.13.0` | `7.13.1` |


Updates `@types/formidable` from 3.4.6 to 3.5.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/formidable)

Updates `@types/jquery` from 3.5.33 to 4.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jquery)

Updates `@types/jsdom` from 27.0.0 to 28.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jsdom)

Updates `@types/node` from 25.2.3 to 25.3.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/supertest` from 6.0.3 to 7.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/supertest)

Updates `@types/whatwg-mimetype` from 3.0.2 to 5.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/whatwg-mimetype)

Updates `eslint` from 10.0.0 to 10.0.3
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.0.0...v10.0.3)

Updates `sinon` from 21.0.1 to 21.0.2
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](sinonjs/sinon@v21.0.1...v21.0.2)

Updates `@typescript-eslint/eslint-plugin` from 8.55.0 to 8.56.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.55.0 to 8.56.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/parser)

Updates `eslint-plugin-react-refresh` from 0.5.0 to 0.5.2
- [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases)
- [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md)
- [Commits](ArnaudBarre/eslint-plugin-react-refresh@v0.5.0...v0.5.2)

Updates `i18next` from 25.8.8 to 25.8.16
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v25.8.8...v25.8.16)

Updates `lucide-react` from 0.564.0 to 0.577.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.577.0/packages/lucide-react)

Updates `react-hook-form` from 7.71.1 to 7.71.2
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.71.1...v7.71.2)

Updates `react-i18next` from 16.5.4 to 16.5.6
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v16.5.4...v16.5.6)

Updates `react-router-dom` from 7.13.0 to 7.13.1
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.13.1/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: "@types/formidable"
  dependency-version: 3.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@types/jquery"
  dependency-version: 4.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: "@types/jsdom"
  dependency-version: 28.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: "@types/node"
  dependency-version: 25.3.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@types/supertest"
  dependency-version: 7.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: "@types/whatwg-mimetype"
  dependency-version: 5.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: eslint
  dependency-version: 10.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: sinon
  dependency-version: 21.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.56.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.56.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: eslint-plugin-react-refresh
  dependency-version: 0.5.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: i18next
  dependency-version: 25.8.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: lucide-react
  dependency-version: 0.577.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: react-hook-form
  dependency-version: 7.71.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: react-i18next
  dependency-version: 16.5.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: react-router-dom
  dependency-version: 7.13.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [openapi-backend](https://github.com/openapistack/openapi-backend) from 5.15.0 to 5.16.1.
- [Release notes](https://github.com/openapistack/openapi-backend/releases)
- [Commits](openapistack/openapi-backend@5.15.0...5.16.1)

---
updated-dependencies:
- dependency-name: openapi-backend
  dependency-version: 5.16.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [jose](https://github.com/panva/jose) from 6.1.3 to 6.2.1.
- [Release notes](https://github.com/panva/jose/releases)
- [Changelog](https://github.com/panva/jose/blob/main/CHANGELOG.md)
- [Commits](panva/jose@v6.1.3...v6.2.1)

---
updated-dependencies:
- dependency-name: jose
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [ejs](https://github.com/mde/ejs) from 4.0.1 to 5.0.1.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/RELEASE_NOTES_v4.md)
- [Commits](mde/ejs@v4.0.1...v5.0.1)

---
updated-dependencies:
- dependency-name: ejs
  dependency-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [oidc-provider](https://github.com/panva/node-oidc-provider) from 9.6.1 to 9.7.0.
- [Release notes](https://github.com/panva/node-oidc-provider/releases)
- [Changelog](https://github.com/panva/node-oidc-provider/blob/main/CHANGELOG.md)
- [Commits](panva/node-oidc-provider@v9.6.1...v9.7.0)

---
updated-dependencies:
- dependency-name: oidc-provider
  dependency-version: 9.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [axios](https://github.com/axios/axios) from 1.13.5 to 1.13.6.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v1.13.5...v1.13.6)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.13.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…r#7366)

Bumps the dev-dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.3.5` | `25.4.0` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.0.18` | `4.1.0` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.56.1` | `8.57.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.56.1` | `8.57.0` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `5.1.4` | `6.0.0` |
| [i18next](https://github.com/i18next/i18next) | `25.8.16` | `25.8.18` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.5.6` | `16.5.8` |


Updates `@types/node` from 25.3.5 to 25.4.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `vitest` from 4.0.18 to 4.1.0
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.0/packages/vitest)

Updates `@typescript-eslint/eslint-plugin` from 8.56.1 to 8.57.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.56.1 to 8.57.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.0/packages/parser)

Updates `@vitejs/plugin-react` from 5.1.4 to 6.0.0
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.0/packages/plugin-react)

Updates `i18next` from 25.8.16 to 25.8.18
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v25.8.16...v25.8.18)

Updates `react-i18next` from 16.5.6 to 16.5.8
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v16.5.6...v16.5.8)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.57.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.57.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: i18next
  dependency-version: 25.8.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: react-i18next
  dependency-version: 16.5.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.27.3 to 0.27.4.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](evanw/esbuild@v0.27.3...v0.27.4)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.27.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) from 8.2.2 to 8.3.1.
- [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases)
- [Commits](express-rate-limit/express-rate-limit@v8.2.2...v8.3.1)

---
updated-dependencies:
- dependency-name: express-rate-limit
  dependency-version: 8.3.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…r#7368)

Bumps the dev-dependencies group with 3 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) and [vite-plugin-static-copy](https://github.com/sapphi-red/vite-plugin-static-copy).


Updates `@types/node` from 25.4.0 to 25.5.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitejs/plugin-react` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.1/packages/plugin-react)

Updates `vite-plugin-static-copy` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/sapphi-red/vite-plugin-static-copy/releases)
- [Changelog](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sapphi-red/vite-plugin-static-copy/compare/vite-plugin-static-copy@3.2.0...vite-plugin-static-copy@3.3.0)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: vite-plugin-static-copy
  dependency-version: 3.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
JohnMcLear and others added 29 commits April 1, 2026 18:40
The settings textarea content is populated asynchronously via socket.
On slow CI (especially Node 20 + Firefox), the default 20s timeout
isn't enough. Increase to 30s for all toBeEmpty checks.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Load tests are slow and don't need to run on every push. Schedule
daily at 08:00 UTC with manual trigger option.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Enforce 2-space indentation across codebase

Convert all 4-space indented source files to 2-space to match
.editorconfig and project contributor guidelines.

74 files converted: admin UI components, type definitions, security
modules, test files, helpers, and utilities.

No functional changes — 2882 insertions, 2882 deletions (pure
whitespace).

Fixes ether#7353

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Limit admin tests to chromium and firefox

Webkit is already tested in the dedicated frontend-tests workflow.
Running it again in admin tests causes flaky failures due to slow
socket connections and external API timeouts on webkit CI runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 3 to 5.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](pnpm/action-setup@v3...v5)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) from 8.3.1 to 8.3.2.
- [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases)
- [Commits](express-rate-limit/express-rate-limit@v8.3.1...v8.3.2)

---
updated-dependencies:
- dependency-name: express-rate-limit
  dependency-version: 8.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…es (ether#7428)

* build(deps-dev): bump the dev-dependencies group across 1 directory with 8 updates

Bumps the dev-dependencies group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.58.2` | `1.59.0` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.1` | `4.1.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.57.1` | `8.58.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.57.1` | `8.58.0` |
| [i18next](https://github.com/i18next/i18next) | `25.10.5` | `26.0.3` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.0.1` | `1.7.0` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.6.2` | `17.0.2` |



Updates `@playwright/test` from 1.58.2 to 1.59.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](microsoft/playwright@v1.58.2...v1.59.0)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](microsoft/TypeScript@v5.9.3...v6.0.2)

Updates `vitest` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest)

Updates `@typescript-eslint/eslint-plugin` from 8.57.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.57.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/parser)

Updates `i18next` from 25.10.5 to 26.0.3
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v25.10.5...v26.0.3)

Updates `lucide-react` from 1.0.1 to 1.7.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.7.0/packages/lucide-react)

Updates `react-i18next` from 16.6.2 to 17.0.2
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v16.6.2...v17.0.2)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.59.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: i18next
  dependency-version: 26.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: lucide-react
  dependency-version: 1.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: react-i18next
  dependency-version: 17.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix TypeScript 6 compatibility: add jQuery types and DOM lib

- Add @types/jquery dev dependency
- Add "DOM" to tsconfig lib for frontend files that use DOM APIs
- Add "types": ["node", "jquery"] to tsconfig for explicit type resolution
- Fix implicit any types in pad_utils.ts (evt parameter, this in .each)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r#7429)

* build(deps-dev): bump the dev-dependencies group with 8 updates

Bumps the dev-dependencies group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.58.2` | `1.59.1` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.1` | `4.1.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.57.1` | `8.58.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.57.1` | `8.58.0` |
| [i18next](https://github.com/i18next/i18next) | `25.10.5` | `26.0.3` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.0.1` | `1.7.0` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.6.2` | `17.0.2` |


Updates `@playwright/test` from 1.58.2 to 1.59.1
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](microsoft/playwright@v1.58.2...v1.59.1)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](microsoft/TypeScript@v5.9.3...v6.0.2)

Updates `vitest` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest)

Updates `@typescript-eslint/eslint-plugin` from 8.57.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.57.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/parser)

Updates `i18next` from 25.10.5 to 26.0.3
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v25.10.5...v26.0.3)

Updates `lucide-react` from 1.0.1 to 1.7.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.7.0/packages/lucide-react)

Updates `react-i18next` from 16.6.2 to 17.0.2
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v16.6.2...v17.0.2)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.59.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: vitest
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: i18next
  dependency-version: 26.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
- dependency-name: lucide-react
  dependency-version: 1.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: react-i18next
  dependency-version: 17.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: add explicit types to tsconfig for TypeScript 6 compatibility

TypeScript 6 no longer auto-includes @types/* packages as globals when
moduleDetection is set to "force". Explicitly list jquery, node, and
mocha in the types array so their global declarations are available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: John McLear <john@mclear.co.uk>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Drop webkit from CI workflow and Playwright config (Chrome + Firefox
  are the supported browsers)
- Set retries: 2 in CI to handle intermittent failures from timing
  sensitive operations (list attribute clearing, server restarts)
- Fix clearAuthorship helper to use force:true to bypass toolbar-overlay
  div that intermittently intercepts clicks after text selection
- Fix admin restartEtherpad helper: increase poll intervals, add
  explicit timeout, use toHaveValue with timeout instead of toBeEmpty
- Convert clear_authorship_color tests to use Playwright auto-retry
  assertions (toHaveAttribute) instead of one-shot getAttribute calls

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ether#7431)

When HTML containing <li> elements without a wrapping <ul> or <ol> is
pasted (e.g., from ChatGPT), the contentcollector crashes with
"TypeError: lineAttributes.list is undefined" because it assumes
_enterList() was already called by a parent list element.

The fix defaults bare <li> elements to bullet1 list type and properly
sets oldListTypeOrNull so the list state is cleaned up after the <li>
is processed. Also guards the .indexOf() call on lineAttributes.list.

Fixes: ether#6665

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ther#7432)

* fix: wait for server confirmation before navigating after pad delete

The delete pad handler navigated to '/' immediately after sending the
PAD_DELETE message. Firefox (and some mobile Chrome) would close the
WebSocket before the message reached the server, causing the delete to
silently fail.

Now the client waits for the server's {disconnect: 'deleted'} response
before navigating. Also awaits pad.remove() on the server side to
ensure the operation completes before the response is sent.

Fixes: ether#7306
Fixes: ether#7311

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: handle non-creator delete and add timeout fallback

- Listen for 'shout' event to show error when non-creator tries to
  delete (server sends shoutMessage instead of deleting)
- Add 5-second timeout fallback in case the server doesn't respond
  (socket dropped, server crashed, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…st (ether#7436)

When an ordered list followed directly after an unordered list (no blank
line between), all OL items showed "1" instead of incrementing. This was
because renumberList's applyNumberList function counted bullet items in
the position counter, so the first OL item got start=3 (after 2 bullet
items) instead of start=1, preventing the CSS counter-reset class from
being applied.

The fix resets the position counter when the list type changes at the
same level (e.g., bullet -> number).

Fixes: ether#5160

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: filter already-deleted sessions when deleting a group

deleteSession uses setSub(..., undefined) to remove session references
from group2sessions and author2sessions, but this can leave null entries
in the sessionIDs object. When deleteGroup later iterates Object.keys
of sessionIDs and calls deleteSession on each, it throws "sessionID
does not exist" for the already-deleted sessions.

Now deleteGroup filters out null/falsy session entries before attempting
to delete them.

Fixes: ether#5798

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add regression test for deleteGroup after deleteSession (ether#5798)

Creates a group, author, and session, then deletes the session first,
then deletes the group. Without the fix, deleteGroup would throw
"sessionID does not exist" when encountering the null session entry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.27.4 to 0.27.5.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](evanw/esbuild@v0.27.4...v0.27.5)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.27.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
PageDown was broken — it moved the caret to the last visible line of
the current viewport instead of advancing by one page. This caused it
to get "stuck" at the bottom of the viewport.

The old code set the caret to oldVisibleLineRange[1] - 1 (the last
visible line), which was essentially a no-op for scrolling. The fix
mirrors the PageUp logic: advance/retreat by numberOfLinesInViewport.

Also simplified the clamping logic for both selStart and selEnd.

Fixes: ether#6710

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.27.5 to 0.28.0.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](evanw/esbuild@v0.27.5...v0.28.0)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…r#7443)

Bumps the dev-dependencies group with 4 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon), [react-hook-form](https://github.com/react-hook-form/react-hook-form) and [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom).


Updates `@types/node` from 25.5.0 to 25.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/sinon` from 21.0.0 to 21.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon)

Updates `react-hook-form` from 7.72.0 to 7.72.1
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.72.0...v7.72.1)

Updates `react-router-dom` from 7.13.2 to 7.14.0
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.14.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.5.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: "@types/sinon"
  dependency-version: 21.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: react-hook-form
  dependency-version: 7.72.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: react-router-dom
  dependency-version: 7.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* docs: add detailed local test running guide to AGENTS.md

Expand the Testing & Validation section with step-by-step instructions
for running backend (Mocha), frontend E2E (Playwright), and admin panel
tests locally, including prerequisites and single-file examples.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add Playwright browser prerequisite check to AGENTS.md

Agents and developers should verify Playwright browsers and system
dependencies are installed before running frontend/admin tests to
avoid silent failures and timeouts (especially webkit).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: fix plugin test path and browser list per review

- Plugin tests are at repo-root node_modules/, not src/node_modules/
- Playwright runs chromium and firefox only (webkit is disabled)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: fix install-deps working directory to run from src/

Playwright is a devDependency of the src workspace, so install-deps
must also run from src/ to match the correct Playwright version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ests (ether#7434)

* fix: suppress internal error details from users in production mode

In production mode (NODE_ENV=production), the client-side error handler
now shows a generic "reload the page" message with just the ErrorId
instead of leaking internal details like error messages, file paths,
line numbers, stack traces, and user agent strings.

In development mode, the full error details are still shown for
debugging.

The basic_error_handler (pre-initialization errors) now always shows a
generic message and logs details to the console instead of displaying
them in the DOM.

The server-side jserror endpoint still receives full error details for
server-side logging — only the user-facing display is suppressed.

Fixes: ether#5765

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: secure-by-default error sanitization and dedup fixes

Address Qodo review concerns:
- Flip mode check to `!== 'development'` (secure by default) so errors
  before CLIENT_VARS handshake hide internal details
- Default server-side mode to 'development' when NODE_ENV is unset
- Replace DOM-based gritter dedup with in-memory Set so dedup works in
  production mode (where .error-msg element is absent)
- Add Playwright regression tests for error sanitization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert server-side mode default to preserve secure-by-default

Don't default mode to 'development' when NODE_ENV is unset — that would
defeat the client-side secure-by-default check. Let mode be undefined so
the client's `!== 'development'` check correctly hides error details.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: report early page load errors to server via sendBeacon

basic_error_handler now sends error details to ../jserror using
navigator.sendBeacon with FormData, matching the format expected by
the server's Formidable parser. Includes an errorId shown to the user
for correlation with server logs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* revert: restore original basic_error_handler with full error details

The basic_error_handler runs before the pad framework loads, so it
should show full details to help developers debug bootstrap failures.
Removes the sendBeacon reporting and error sanitization added in the
previous commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r#7445)

* fix: createDiffHTML API fails with "Not a changeset: undefined"

Root cause: An empty prototype override (`PadDiff.prototype._createDeletionChangeset = function() {}`)
silently replaced the real class method with a no-op returning undefined.
This caused `applyToAText(undefined, ...)` to throw "Not a changeset".

Also fixed a crash when `startRev === endRev`: the `self` property used
to access `_authors` was only initialized inside `_addAuthors()`, which
is never called when there are no changesets to process. Replaced all
`this.self!._authors` with direct `this._authors` access.

Fixes ether#6847

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address Qodo review — random pad ID and assert cleanup

- Use random ID instead of Date.now() to avoid collisions in parallel runs
- Assert HTTP 200 on deletePad in after() hook

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: skip identity changesets during timeslider playback

When a pad's revision history contains an identity changeset (Z:N>0$,
representing no actual change), the timeslider playback would crash or
break because broadcast.ts tried to apply it via mutateAttributionLines
and mutateTextLines.

Now all three applyChangeset call sites in broadcast.ts check for
identity changesets using the existing isIdentity() helper and skip
them. This also prevents errors when compose() produces an identity
changeset from multiple revisions that cancel each other out.

Fixes: ether#5214

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: move identity changeset check inside applyChangeset

Move the isIdentity() guard from the call sites into applyChangeset()
itself, so that identity changesets still advance currentRevision,
currentTime, slider position, and author UI — just skipping the
mutation (mutateAttributionLines/mutateTextLines). This prevents the
timeslider from getting stuck on a stale revision when an identity
changeset is encountered.

Also removes unused `identity` import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: improve timeslider identity changeset test coverage

- Verify slider position advances during playback (confirms revisions
  including identity changesets are processed, not skipped)
- Scrub through every revision individually instead of just rev 0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: timeslider playback test starts from rev 0

The test was starting playback from the latest revision, so the slider
had nowhere to advance — causing the position assertion to fail in CI.
Now navigates to #0 first so playback progresses through all revisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove stale identity-skip comment from goToRevision

The isIdentity() check was moved inside applyChangeset() but the old
comment remained at the call sites, creating a misleading code/comment
mismatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: consecutive numbering fails after indented sub-bullets

The applyNumberList() function in renumberList() checked
listType[0] === 'indent' but after regex exec, listType[0] is the
full match (e.g., "indent1"), never just "indent". Changed to
listType[1] which is the capture group containing just the type name.

This caused indent-type lines to not be recognized during renumbering,
breaking the numbering sequence when numbered lists followed indented
content.

Fixes ether#5718

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: assert sub-bullet indent and remove redundant waitForTimeout

- Assert .list-bullet2 exists after Tab to verify indent precondition
- Remove waitForTimeout(500) since toHaveAttribute already waits 5s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…2802)

When a user clears authorship colors and then undoes, the undo changeset
re-applies author attributes for all authors who contributed text. The
server was rejecting this because it treated any changeset containing
another author's ID as impersonation, disconnecting the user.

The fix distinguishes between:
- '+' ops (new text): still reject if attributed to another author
- '=' ops (attribute changes on existing text): allow restoring other
  authors' attributes, which is needed for undo of clear authorship

Also removes the client-side workaround in undomodule.ts that prevented
clear authorship from being undone at all, and adds backend + frontend
tests covering the multi-author undo scenario.

Fixes: ether#2802

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use toHaveAttribute with regex instead of raw getAttribute + toContain
- Check div/span attributes within pad body instead of broad selectors
- Use Playwright auto-retry (expect with timeout) instead of toHaveCount(0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add page.on('dialog') handler to accept the confirm dialog triggered
  by clearAuthorship when no text is selected (clears whole pad)
- Use auto-retrying toHaveAttribute assertions instead of raw getAttribute
- Increase cross-user sync timeouts to 15s for CI reliability
- Add retries: 2 to multi-user test for CI flakiness
- Scope assertions to pad body spans instead of broad selectors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace sequential waitForSocketEvent loops with single persistent
listeners that filter messages inline. This prevents race conditions
where messages arrive between off/on listener cycles, causing timeouts
on slower CI runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The '-' op attribs are discarded from the document but still get added
to the pad's attribute pool by moveOpsToNewPool. Without this check, an
attacker could inject a fabricated author ID into the pool via a '-' op,
then use a '=' op to attribute text to that fabricated author (bypassing
the pool existence check).

Now all non-'=' ops (+, -) with foreign author IDs are rejected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses Qodo review: linestylefilter skips attribs with empty values,
so a span with author='' has no class attribute at all. The previous
negative-lookahead regex on the class attribute failed against a null
attribute and was flaky in CI. Switch to not.toHaveClass(/author-/),
which also passes when the attribute is missing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 issues found across 131 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="admin/src/localization/i18n.ts">

<violation number="1" location="admin/src/localization/i18n.ts:31">
P2: Return immediately after the error callback to avoid invoking the backend callback twice when parsing fails.</violation>
</file>

<file name="admin/src/utils/Toast.tsx">

<violation number="1" location="admin/src/utils/Toast.tsx:11">
P3: Remove the debug `console.log()` from the component render path.</violation>
</file>

<file name="src/tsconfig.json">

<violation number="1" location="src/tsconfig.json:6">
P2: `compilerOptions.types` is declared twice; the later entry overrides the earlier one, leaving the first added config ineffective.</violation>
</file>

<file name="src/static/js/pluginfw/installer.ts">

<violation number="1" location="src/static/js/pluginfw/installer.ts:183">
P1: Avoid writing untrusted plugin names/keys into a normal object literal; this allows prototype-pollution keys (for example `__proto__`) to be assigned.</violation>
</file>

<file name="admin/src/pages/HelpPage.tsx">

<violation number="1" location="admin/src/pages/HelpPage.tsx:12">
P2: Add a cleanup function to remove the `reply:help` listener in `useEffect` to avoid accumulating duplicate socket handlers.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:103">
P2: The README now omits the minimum supported Node.js version, making the install requirement inaccurate. This can lead users to install unsupported Node versions and hit avoidable setup/runtime failures.</violation>
</file>

<file name="AGENTS.MD">

<violation number="1" location="AGENTS.MD:54">
P2: The contributor workflow should not require a specific maintainer’s fork; this should point contributors to their own fork.</violation>
</file>

<file name="best_practices.md">

<violation number="1" location="best_practices.md:1">
P2: This new file substantially duplicates `CONTRIBUTING.md`, creating a second source of truth for contributor policies. Consolidate into one canonical doc (or make this file a short pointer) to avoid future drift.</violation>
</file>

<file name="src/locales/ga.json">

<violation number="1" location="src/locales/ga.json:92">
P2: Missing translation key `pad.settings.fontType.normal` in the new `ga` locale file.</violation>
</file>

<file name="src/templates/javascript.html">

<violation number="1" location="src/templates/javascript.html:13">
P3: The displayed jQuery filename does not match the linked file path (`3.0.1` text vs `3.0.0` href), which makes the license listing inaccurate.</violation>
</file>

<file name="src/locales/nb.json">

<violation number="1" location="src/locales/nb.json:65">
P3: `$1` is not a supported interpolation format here, so the Norwegian label will render as literal text (`Drevet av $1`). Use plain text (or `{{...}}` with args) instead.</violation>
</file>

<file name="admin/package.json">

<violation number="1" location="admin/package.json:23">
P1: Upgrading `@vitejs/plugin-react` to v6 is incompatible with the current Vite 7 setup and existing inline `babel` plugin config, which can break install/build.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.

availablePlugins = pluginsLoaded.data;
const data = pluginsLoaded.data;
// Normalize: the registry may use numeric keys instead of plugin names
const normalized: MapArrayType<PackageInfo> = {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Avoid writing untrusted plugin names/keys into a normal object literal; this allows prototype-pollution keys (for example __proto__) to be assigned.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/static/js/pluginfw/installer.ts, line 183:

<comment>Avoid writing untrusted plugin names/keys into a normal object literal; this allows prototype-pollution keys (for example `__proto__`) to be assigned.</comment>

<file context>
@@ -174,7 +178,18 @@ export const getAvailablePlugins = async (maxCacheAge: number | false) => {
-  availablePlugins = pluginsLoaded.data;
+  const data = pluginsLoaded.data;
+  // Normalize: the registry may use numeric keys instead of plugin names
+  const normalized: MapArrayType<PackageInfo> = {};
+  for (const key in data) {
+    const entry = data[key];
</file context>
Suggested change
const normalized: MapArrayType<PackageInfo> = {};
const normalized: MapArrayType<PackageInfo> = Object.create(null);

Comment thread admin/package.json
"@vitejs/plugin-react": "^5.1.4",
"@typescript-eslint/eslint-plugin": "^8.58.0",
"@typescript-eslint/parser": "^8.58.0",
"@vitejs/plugin-react": "^6.0.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Upgrading @vitejs/plugin-react to v6 is incompatible with the current Vite 7 setup and existing inline babel plugin config, which can break install/build.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At admin/package.json, line 23:

<comment>Upgrading `@vitejs/plugin-react` to v6 is incompatible with the current Vite 7 setup and existing inline `babel` plugin config, which can break install/build.</comment>

<file context>
@@ -18,27 +18,27 @@
-    "@vitejs/plugin-react": "^5.1.4",
+    "@typescript-eslint/eslint-plugin": "^8.58.0",
+    "@typescript-eslint/parser": "^8.58.0",
+    "@vitejs/plugin-react": "^6.0.1",
     "babel-plugin-react-compiler": "19.1.0-rc.3",
-    "eslint": "^10.0.0",
</file context>

try {
json = JSON.parse(await localeJSON.text())
} catch(e) {
callback(new Error("Error loading"), null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Return immediately after the error callback to avoid invoking the backend callback twice when parsing fails.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At admin/src/localization/i18n.ts, line 31:

<comment>Return immediately after the error callback to avoid invoking the backend callback twice when parsing fails.</comment>

<file context>
@@ -6,52 +6,52 @@ import LanguageDetector from 'i18next-browser-languagedetector'
+    try {
+      json = JSON.parse(await localeJSON.text())
+    } catch(e) {
+      callback(new Error("Error loading"), null);
+    }
+
</file context>
Suggested change
callback(new Error("Error loading"), null);
return callback(new Error("Error loading"), null);

Comment thread src/tsconfig.json
"moduleDetection": "force",
"lib": ["ES2023"],
"lib": ["ES2023", "DOM"],
"types": ["node", "jquery"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: compilerOptions.types is declared twice; the later entry overrides the earlier one, leaving the first added config ineffective.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tsconfig.json, line 6:

<comment>`compilerOptions.types` is declared twice; the later entry overrides the earlier one, leaving the first added config ineffective.</comment>

<file context>
@@ -2,7 +2,8 @@
     "moduleDetection": "force",
-    "lib": ["ES2023"],
+    "lib": ["ES2023", "DOM"],
+    "types": ["node", "jquery"],
     /* Language and Environment */
     "target": "es6",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
</file context>

Comment on lines +12 to +16
settingsSocket?.on('reply:help', (data) => {
setHelpData(data)
});

settingsSocket?.emit('help');
}, [settingsSocket]);
settingsSocket?.emit('help');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Add a cleanup function to remove the reply:help listener in useEffect to avoid accumulating duplicate socket handlers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At admin/src/pages/HelpPage.tsx, line 12:

<comment>Add a cleanup function to remove the `reply:help` listener in `useEffect` to avoid accumulating duplicate socket handlers.</comment>

<file context>
@@ -4,67 +4,67 @@ import {useEffect, useState} from "react";
-        });
+  useEffect(() => {
+    if(!settingsSocket) return;
+    settingsSocket?.on('reply:help', (data) => {
+      setHelpData(data)
+    });
</file context>
Suggested change
settingsSocket?.on('reply:help', (data) => {
setHelpData(data)
});
settingsSocket?.emit('help');
}, [settingsSocket]);
settingsSocket?.emit('help');
const handleHelpReply = (data: HelpObj) => {
setHelpData(data)
};
settingsSocket.on('reply:help', handleHelpReply);
settingsSocket.emit('help');
return () => {
settingsSocket.off('reply:help', handleHelpReply);
};

Comment thread best_practices.md
@@ -0,0 +1,132 @@
# Contributor Guidelines

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This new file substantially duplicates CONTRIBUTING.md, creating a second source of truth for contributor policies. Consolidate into one canonical doc (or make this file a short pointer) to avoid future drift.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At best_practices.md, line 1:

<comment>This new file substantially duplicates `CONTRIBUTING.md`, creating a second source of truth for contributor policies. Consolidate into one canonical doc (or make this file a short pointer) to avoid future drift.</comment>

<file context>
@@ -0,0 +1,132 @@
+# Contributor Guidelines
+(Please talk to people on the mailing list before you change this page, see our section on [how to get in touch](https://github.com/ether/etherpad-lite#get-in-touch))
+
</file context>

Comment thread src/locales/ga.json
"pad.settings.colorcheck": "Dathanna údair",
"pad.settings.linenocheck": "Uimhreacha líne",
"pad.settings.rtlcheck": "Léigh ábhar ó dheis go clé?",
"pad.settings.fontType": "Cineál cló:",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Missing translation key pad.settings.fontType.normal in the new ga locale file.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/locales/ga.json, line 92:

<comment>Missing translation key `pad.settings.fontType.normal` in the new `ga` locale file.</comment>

<file context>
@@ -0,0 +1,189 @@
+	"pad.settings.colorcheck": "Dathanna údair",
+	"pad.settings.linenocheck": "Uimhreacha líne",
+	"pad.settings.rtlcheck": "Léigh ábhar ó dheis go clé?",
+	"pad.settings.fontType": "Cineál cló:",
+	"pad.settings.language": "Teanga:",
+	"pad.settings.deletePad": "Scrios Pad",
</file context>

Comment thread admin/src/utils/Toast.tsx
</Toast.Root>
<Toast.Viewport className="ToastViewport"/>
</>
console.log()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Remove the debug console.log() from the component render path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At admin/src/utils/Toast.tsx, line 11:

<comment>Remove the debug `console.log()` from the component render path.</comment>

<file context>
@@ -3,24 +3,24 @@ import {useStore} from "../store/store.ts";
-    </Toast.Root>
-        <Toast.Viewport className="ToastViewport"/>
-    </>
+  console.log()
+  return <>
+    <Toast.Root className={"ToastRoot "+resultingClass} open={toastState && toastState.open} onOpenChange={()=>{
</file context>

<body>
<table id="jslicense-labels1">
<tr>
<td><a href="/static/js/vendors/jquery-3.0.0.min.js">jquery-3.0.1.min.js</a></td>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The displayed jQuery filename does not match the linked file path (3.0.1 text vs 3.0.0 href), which makes the license listing inaccurate.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/templates/javascript.html, line 13:

<comment>The displayed jQuery filename does not match the linked file path (`3.0.1` text vs `3.0.0` href), which makes the license listing inaccurate.</comment>

<file context>
@@ -1,51 +1,51 @@
+  <body>
+    <table id="jslicense-labels1">
+      <tr>
+        <td><a href="/static/js/vendors/jquery-3.0.0.min.js">jquery-3.0.1.min.js</a></td>
+        <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+        <td><a href="/static/js/vendors/jquery.js">jquery.js</a></td>
</file context>
Suggested change
<td><a href="/static/js/vendors/jquery-3.0.0.min.js">jquery-3.0.1.min.js</a></td>
<td><a href="/static/js/vendors/jquery-3.0.0.min.js">jquery-3.0.0.min.js</a></td>

Comment thread src/locales/nb.json
"pad.delete.confirm": "Vil du virkelig slette denne paden?",
"pad.settings.about": "Om",
"pad.settings.poweredBy": "Drives av",
"pad.settings.poweredBy": "Drevet av $1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: $1 is not a supported interpolation format here, so the Norwegian label will render as literal text (Drevet av $1). Use plain text (or {{...}} with args) instead.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/locales/nb.json, line 65:

<comment>`$1` is not a supported interpolation format here, so the Norwegian label will render as literal text (`Drevet av $1`). Use plain text (or `{{...}}` with args) instead.</comment>

<file context>
@@ -49,8 +59,10 @@
+	"pad.delete.confirm": "Vil du virkelig slette denne paden?",
 	"pad.settings.about": "Om",
-	"pad.settings.poweredBy": "Drives av",
+	"pad.settings.poweredBy": "Drevet av $1",
 	"pad.importExport.import_export": "Importer/eksporter",
 	"pad.importExport.import": "Last opp tekstfil eller dokument",
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Undoing causes disconnect

4 participants