Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/agents/dependabot-fixer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ You follow the rules in `CLAUDE.md`. Implementation work goes through Workflow s

1. **Read the PR live.** `gh pr view <n>`, `gh pr diff <n>`. Note the branch and head sha. Dependabot branches are named `dependabot/...`.
2. **Read the failing checks.** Delegate the diagnosis to the `ci-triager` agent. Do not diagnose from memory. Ask it for the failing job, root cause and owning file.
3. **Run the blocked-upgrades check first.** Run the `/deps-check` skill. If the bump is a blocked one (TypeScript 7 or ESLint 10 while the peer range is still old), **stop and report.** Do not work around it. Do not use overrides or `--legacy-peer-deps`. Do not close #272, #386 or #387.
3. **Check peer compatibility.** For npm install failures, use `/deps-check` to identify which installed package excludes the proposed version. Keep blocked PRs open.
4. **Read the changelog and migration notes** of the bumped package. Use the release notes on the package's GitHub page or on the registry. Note every breaking change.
5. **Fix real breakages in code.** Change call sites to match the new API. Do not add `@ts-ignore`, `eslint-disable`, `//nolint`, overrides, or loosened configs. Do not delete or weaken tests (system rule 1). If a test must change, stop and ask the maintainer.
6. **Regenerate lock files with the tool, never by hand.**
Expand Down
20 changes: 4 additions & 16 deletions .claude/skills/deps-check/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
---
name: deps-check
description: "Use at session start, or when a dependency upgrade is proposed, to check the blocked dependency upgrades listed in CLAUDE.md (TypeScript 7 and ESLint 10) against the npm registry."
description: "Identify which published peer dependency blocks a proposed npm upgrade."
---

This is the session-start check from `CLAUDE.md`. Run it every session. It only reads the registry. It changes nothing.

## Steps

1. Run the registry checks:
```sh
npm view @typescript-eslint/parser@latest version peerDependencies.typescript
npm view @typescript-eslint/parser@canary version peerDependencies.typescript
npm view eslint-plugin-react@latest version peerDependencies.eslint
```
2. TypeScript 7 entry. It is blocked while the peer range ends `<7` (for example `<6.1.0`). Report blocked or unblocked, with the version and the peer range seen for both `@latest` and `@canary`. Unblocked means a release accepts TypeScript 7.
3. ESLint 10 entry. It is blocked while the `eslint-plugin-react` peer range lacks `^10`. Report blocked or unblocked, with the version and the peer range seen. Other plugins already accept `^10`: `eslint-plugin-react-hooks@7.1.1` and `@typescript-eslint/*@8.69.0`.
4. Report one line per entry: name, blocked or unblocked, version, peer range. Then say what blocks it, in one line.
5. If an entry is unblocked, list its unblock steps from `CLAUDE.md`. Do not perform them unless the maintainer asks.
- TypeScript 7: do T055 and T056 in `specs/009-remediate-security-dependabot/tasks.md`. Bump `typescript` and `@typescript-eslint/*` in `web/package.json`. Fix real type errors, with no `@ts-ignore`. Merge Dependabot #272. Mark the tasks `[X]`. Delete the TypeScript entry from `CLAUDE.md`.
- ESLint 10: bump `eslint` and `@eslint/js` together in `web/package.json`. Fix real lint errors, with no `eslint-disable`. Merge #386, and #387 if it is open. Delete the ESLint entry from `CLAUDE.md`.
6. Never close #272, #386 or #387. Never use `--legacy-peer-deps` or overrides to get around a peer range.
1. Read the failed install or `npm ls` output. Identify the proposed version and the package declaring the conflicting peer range.
2. Use `npm view <package>@<version> peerDependencies` for the locked version and `npm view <package>@latest version peerDependencies` for the current release.
3. Report which release admits the upgrade, or which range still blocks it. Preserve npm's peer checks and keep blocked PRs open.
8 changes: 7 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,8 @@ jobs:
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with: { node-version: "24", cache: "npm", cache-dependency-path: web/package-lock.json }
- run: npm ci
- name: Verify dashboard lint rules and compiler version
run: bash scripts/check-lint-toolchain.sh
- uses: ./.github/actions/go-cache
with:
key-suffix: web-i18n
Expand Down Expand Up @@ -1087,7 +1089,7 @@ jobs:
fi
echo "ok $code"
done
- name: eslint
- name: ESLint and Oxlint
run: npm run lint
- run: npm run build
- name: unit tests + coverage
Expand Down Expand Up @@ -1177,6 +1179,10 @@ jobs:
- name: install chromium
# Skips the browser download on a cache hit; still apt-installs deps.
run: npx playwright install --with-deps chromium
- name: build production dashboard for plain HTTP browser check
run: npm run build
- name: TypeScript editor on plain HTTP
run: npx playwright test --config=e2e/http/playwright.config.ts
- name: playwright (mock)
run: npm run test:e2e:mock
- name: upload playwright report
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ test/e2e/.kube/
web/node_modules/
web/node_modules
web/dist/
web/*.tsbuildinfo
web/build/
web/.vite/
web/.turbo/
Expand Down
11 changes: 8 additions & 3 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<!--
Sync Impact Report
- 2.2.0 → 2.2.1 (PATCH). Principle III names the Oxlint rules that enforce the existing
explicit-any and floating-promise requirements in the TypeScript 7 dashboard.
The corresponding configuration lives in `web/.oxlintrc.json`.

Previous report (2.1.0 → 2.2.0)
- Version change: 2.1.0 → 2.2.0
- Bump rationale: MINOR. Principle IV is materially expanded with a completed-feature
folder-naming rule: a finished feature's `specs/<NNN>-<slug>/` is renamed to
Expand Down Expand Up @@ -113,10 +118,10 @@ stale mirror actively misleads, so it cannot be allowed to drift from the source
Code MUST follow the idioms of its language and the project's established tooling
rather than working around them. Go code wraps errors with `%w` so `errors.Is`/`errors.As`
keep working up the call stack; TypeScript runs under `strict` mode with
`@typescript-eslint/no-explicit-any` and `@typescript-eslint/no-floating-promises`
`typescript/no-explicit-any` and `typescript/no-floating-promises`
enforced — an unavoidable `any` gets a one-line comment explaining why, and a
fire-and-forget `Promise` is resolved with `await` or explicit `void`, never suppressed.
When `golangci-lint` or ESLint flags something, the code MUST be fixed, not silenced.
Findings from `golangci-lint`, ESLint and Oxlint MUST be fixed at source.
In-source suppression directives are absolutely forbidden — no `//nolint`, no `//#nosec`,
no `//lint:ignore`, no `// eslint-disable-next-line`, no `// @ts-ignore`. Narrowly-scoped,
maintainer-authorized config-level exclusions in `.golangci.yml` are permitted in two
Expand Down Expand Up @@ -312,4 +317,4 @@ explicitly in the plan's Complexity Tracking section or the change MUST be redes
to comply. Use `CLAUDE.md` for the day-to-day runtime guidance this constitution
intentionally leaves at a higher level of abstraction.

**Version**: 2.2.0 | **Ratified**: 2026-08-11 | **Last Amended**: 2026-09-01
**Version**: 2.2.1 | **Ratified**: 2026-08-11 | **Last Amended**: 2026-11-11
16 changes: 2 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@ Architecture, commands, and binding rules for AI agents. Humans: [`README.md`](R

**Gameplane:** Kubernetes-native game server control panel (CubeCoders AMP alternative); identical on single-node k3s and multi-node clusters. **Status:** Pre-v1 release (`v0.4.0`); v1 scope feature-complete, stabilizing.

## ⏳ Session start: blocked dependency upgrades (delete an entry once unblocked)

Run every session.

**TypeScript 7** — `npm view @typescript-eslint/parser@latest version peerDependencies.typescript` and same for `@canary`.
- Blocked while the peer range ends `<7` (e.g. `<6.1.0`): Dependabot #272 fails `npm ci` (`ERESOLVE`). No workarounds/overrides/code fixes; don't close #272.
- Unblocked (a release accepts TS 7): do T055/T056 in `specs/009-remediate-security-dependabot/tasks.md` — bump `typescript` + `@typescript-eslint/*` in `web/package.json`, fix real type errors (no `@ts-ignore`), merge #272, mark tasks `[X]`, delete this entry.

**ESLint 10** — `npm view eslint-plugin-react@latest version peerDependencies.eslint`.
- Blocked while the range lacks `^10`: upgrading `eslint` 9.39.5 to 10.x fails `npm ci` because `eslint-plugin-react@7.37.5` peers `^3 || … || ^9.7`. Keep `eslint` and `@eslint/js` on major 9 together: `@eslint/js@10.0.1` declares an optional peer on `eslint@^10.0.0`, which conflicts when ESLint 9 is installed. Other plugins already accept `^10` (`eslint-plugin-react-hooks@7.1.1`, `@typescript-eslint/*@8.69.0`). Do not bypass peer checks with `--legacy-peer-deps` or overrides.
- Unblocked: bump `eslint` + `@eslint/js` together in `web/package.json`, fix real lint errors (no `eslint-disable`), merge #386 (and #387 if open), delete this entry.

## System prompt overrides

1. **Verify & tests:** always verify work. Get human sign-off before changing tests, production code, or design specs. Never delete/weaken a test without explicit sign-off — fix the code.
Expand Down Expand Up @@ -76,7 +64,7 @@ After cloning: `git submodule update --init modules` (required for `make dev-up`
- **Dev containers:** `make devcontainers` (regenerate every profile and the `website/` and `modules/` copies after editing `.devcontainer/versions.toml`, `.devcontainer/profiles.toml`, `.devcontainer/devcontainer-lock.json`, `.devcontainer/setup.sh` or a `system-deps.toml`), `make check-devcontainers` (drift check). Profile table: `docs/contributing.md`.
- **Tests (CI only — never run locally, see Rule 8):** `make test`, `make test-integration` (envtest operator+api), `make test-e2e` (~10–20 min), `make test-e2e-bucket BUCKET=(operator|api-auth|api-roles|api-rbac|api-agent|api-mods|ratelimit|bot-fast|bot-heavy|multicluster|upgrade)`.
- **E2E conventions:** register new tests in `test/e2e/buckets.sh`; `t.Parallel()` + unique names; guard shared resources (`ociPushMu` for module pushes, `ensureResticRepo(t)` for shared backup repos). Rate limits per cluster: IP burst 10 (5/min), user burst 6 (3/min) — cap an API bucket at ~7 admin logins.
- **Lint:** `make lint` = gofmt, go vet, golangci-lint, ESLint, `check-specs`, `check-doc-versions`, `check-links`.
- **Lint:** `make lint` = gofmt, go vet, golangci-lint, ESLint, Oxlint, `check-specs`, `check-doc-versions`, `check-links`.

**Coverage minimums:** netguard 91, gameaction 91, gameproto 90, telemetryschema 90, i18n 90, gp-module 80, operator 72, api 80, agent 90, svcutil 90; audit-syslog-bridge, telemetry-receiver, sentinel, capture-sidecar, mcp-server, tunnel 70; web 92 lines / 76 functions / 82 branches / 92 statements.

Expand Down Expand Up @@ -146,4 +134,4 @@ After cloning: `git submodule update --init modules` (required for `make dev-up`

- `docs/agent-architecture.md` — read before editing code; maps tasks/features to docs (use instead of repo-wide greps).
- `docs/architecture.md`, `docs/security.md` (threat model); `docs/module-authoring.md`; `mcp-server/README.md`; `audit-syslog-bridge/README.md`.
- Configs: `.golangci.yml`, `web/eslint.config.js`, `.editorconfig`.
- Configs: `.golangci.yml`, `web/eslint.config.js`, `web/.oxlintrc.json`, `.editorconfig`.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ reaches `1.0.0`. Pre-1.0 minor versions may contain breaking changes.

## [Unreleased]

### Added

- The Files editor checks the open JavaScript or TypeScript file against the
standard library and provides inline diagnostics, completions, and Peek
Definition. The browser downloads the compiler on first use (about 12.7 MiB
gzipped). These features also work over plain HTTP on LAN browsers that
support WebAssembly JavaScript Promise Integration (PR #902).
- Placement settings now underline JSON syntax errors as you type (PR #902).

### Changed

- The dashboard builds with TypeScript 7.0.2 and uses Monaco Editor 0.57.0.
ESLint 10 runs the React Hooks and FormatJS checks, and Oxlint checks React
and TypeScript code for issues such as unhandled promises. The translation
migration uses Babel and preserves JSX comments, escaped entities, Unicode,
and line endings (PR #902).

## [0.4.0] — 2026-11-10

A pre-v1 release with every change made since v0.3.0: an independent central
Expand Down
9 changes: 6 additions & 3 deletions docs/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,19 @@ React 18 + TypeScript strict + Vite dashboard (`web/package.json` version
- `react-aria` — peer dependency of HeroUI, providing accessibility primitives (via `react-aria-components`) used by HeroUI atoms.

**Editors / terminals**
- `@monaco-editor/react` `^4.7.0` — the `Editor` component in `src/routes/tabs/Files.tsx` (in-browser file editor) and `Placement.tsx`; given its own `manualChunks` bundle in `vite.config.ts`.
- `@monaco-editor/react` wraps Monaco for the Files and Placement editors. Vite bundles their language support and workers as same-origin assets.
- `@xterm/xterm` `^6.0.0` + `@xterm/addon-fit` `^0.11.0` — `Terminal`/`FitAddon` in `src/routes/tabs/useConsoleTerminal.ts`, driving the live server console (`Console.tsx`); also chunked separately in `vite.config.ts`. <!-- doc-versions: dependency -->

**Styling / build**
- `tailwindcss` `^4.3.3`, `autoprefixer` `^10.5.4`, `postcss` `^8.5.26` (dev) — `postcss.config.js` wires Tailwind + autoprefixer; `tailwind.config.ts` defines the design tokens used throughout `src/styles` and Tailwind classes app-wide.
- `vite` `^8.2.2`, `@vitejs/plugin-react` `^6.1.1` (dev) — `vite.config.ts` drives the dev server (with the API/WS proxy to the in-cluster API used by `make web-dev`), production build, and is the engine behind `vitest.config.ts`.
- `typescript` `^6.0.3` (dev) — strict-mode compile per `tsconfig.json`; `npm run build` is `tsc -b && vite build`.
- `typescript` `^7.0.2` (dev) provides the native `tsc` used for the dashboard build and Playwright type checks. The i18n migration script reads TSX syntax with Babel.
- Opening a JavaScript or TypeScript file starts Microsoft's TypeScript language server in a WebAssembly worker. The browser package is pinned to `7.1.0-dev.20261030.1`, the version Microsoft tested in Playground v2. The worker checks the open file against TypeScript's standard library in browser memory. [Microsoft's Playground implementation](https://github.com/microsoft/TypeScript-Website/pull/3653)
- On plain HTTP, the editor sends changes to the worker with ordinary browser messages. Autocomplete and type checking require WebAssembly JavaScript Promise Integration (Chrome and Edge 137+, Firefox 153+, or Safari 27+). A secure, cross-origin-isolated page can also use shared memory, including on older browsers. With neither capability, users can still edit, highlight, and save files. [Browser support](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Suspending#browser_compatibility)

**Lint** (dev, all wired directly in `eslint.config.js`)
- `eslint` `^9.39.5`, `@eslint/js` `^10.0.1`, `@typescript-eslint/eslint-plugin` `^8.68.0`, `@typescript-eslint/parser` `^8.68.0`, `eslint-plugin-react` `^7.37.5`, `eslint-plugin-react-hooks` `^7.1.1`, `globals` `^17.11.0` — flat-config ESLint enforcing `strict`, `@typescript-eslint/no-explicit-any: error`, `@typescript-eslint/no-floating-promises: error`, run via `npm run lint`.
- `eslint` `^10.14.0` and `@eslint/js` `^10.0.1` check JavaScript. Babel parses TypeScript and JSX for `eslint-plugin-react-hooks` and `eslint-plugin-formatjs`.
- `oxlint` and `oxlint-tsgolint` check React and TypeScript code, including unhandled promises. Run both linters with `npm run lint` in `web/`. [Oxlint configuration](../web/.oxlintrc.json)

**Testing — unit tier (Vitest)**
- `vitest` `^4.1.11`, `@vitest/coverage-v8` `^4.1.10` (dev) — `vitest.config.ts` (jsdom environment, coverage thresholds), run via `npm test`/`test:cover`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These PRs have failing checks or require a separate gated phase and are NOT merg

```
Go: #263 (sigstore/sigstore 1.10.9, 3 modules) — 1 FAILING CHECK, cause not yet diagnosed
Go: #272 (TypeScript 7.0.2, MAJOR, 4 FAILING CHECKS) — DEFERRED to separate gated phase
npm: #272 (TypeScript 7.0.2, MAJOR, 4 FAILING CHECKS) — DEFERRED to separate gated phase
npm: #268 (@eslint/js 10.0.1, MAJOR, 1 FAILING CHECK) — DEFERRED to separate gated phase
```

Expand Down Expand Up @@ -136,9 +136,7 @@ grep '"vitest"' web/package.json # example for PR #278

### Exception #272: TypeScript 7.0.2 (npm, MAJOR, 4 failing checks)

**Status**: Major version bump with 4 failing checks; likely requires type annotations or config updates in the frontend code.
**Action**: **DEFERRED to a separate gated phase**. This PR will be merged only after all non-major Dependabot PRs (#262–#281 except #268/#272) are on master and passing. A dedicated TypeScript 7 migration task will then be created with explicit scope and review criteria.
**Rationale**: TypeScript major version bumps often require manual type annotation changes. This PR is intentionally isolated to avoid compounding failure modes when other packages have unrelated issues.
The main wave deferred #272 for investigation. T054 traced the install failure to the lint plugin's TypeScript peer range. The replacement migration and its merge criteria are recorded under T054 below.

### Exception #268: @eslint/js 10.0.1 (npm, MAJOR, 1 failing check)

Expand Down Expand Up @@ -284,14 +282,10 @@ remediation above is correct either way.

---

## T054 — PR #272 diagnosis (typescript 6.0.3 → 7.0.2): BLOCKED upstream
## T054 — Original PR #272 install failure (TypeScript 6.0.3 → 7.0.2)

**Status**: blocked by an upstream peer-dependency constraint. No code change on our side
can clear it today. #272 stays open.

**Failing checks**: `web`, `web e2e (mock)`, `e2e web live` — all three fail at the
dependency-install step, before any TypeScript is compiled. There are no type errors to fix
because `tsc` never runs.
On 2026-08-29, `npm ci` failed on the standalone Dependabot update. The `web`,
`web e2e (mock)`, and `e2e web live` jobs all stopped before running `tsc`.

**Verbatim CI excerpt** (job 99082482156, run 33245283178):

Expand All @@ -306,31 +300,23 @@ npm error peer typescript@">=4.8.4 <6.1.0" from @typescript-eslint/eslint-plugin
npm error Conflicting peer dependency: typescript@6.0.3
```

**Root cause**: `@typescript-eslint/*` declares `peerDependencies.typescript` as
`>=4.8.4 <6.1.0`, which excludes all of TypeScript 7.

**No upgrade path exists yet.** Verified live against `registry.npmjs.org` on 2026-08-29 —
every published dist-tag of `@typescript-eslint/eslint-plugin`:
The installed `@typescript-eslint/eslint-plugin` required TypeScript `>=4.8.4 <6.1.0`.
The npm registry listed these alternatives on 2026-08-29:

| dist-tag | version | peer `typescript` |
|---|---|---|
| `latest` | 8.68.0 | `>=4.8.4 <6.1.0` |
| `canary` | 8.68.1-alpha.6 | `>=4.8.4 <6.1.0` |
| `rc-v8` | 8.0.0-alpha.62 | (none declared) |

So even the canary channel still caps at TypeScript 6. Bumping the plugin cannot help, and
the alpha `rc-v*` tags are pre-release lines that declare no peer at all — not a basis for a
production toolchain.

**Rejected workarounds**: `--legacy-peer-deps` / `--force` would install a plugin whose
type-checking internals genuinely do not understand TypeScript 7's AST, silently degrading
lint and type diagnostics. An `overrides` entry pinning the peer would do the same. Neither
is a fix; both trade a loud failure for a silent one.
Forcing the install would have bypassed the peer check while leaving the dashboard
dependent on the old compiler API.

**Disposition**: #272 stays open and unmerged pending a `@typescript-eslint` release that
declares TypeScript 7 support. This is the same shape of blocker as #263 — an upstream
dependency that has not yet caught up — and is tracked as an exception, not a defect in this
repo. T055/T056 cannot proceed until upstream ships.
**Superseding migration.** [PR #902](https://github.com/GameplanePanel/Gameplane/pull/902)
implements T055. The dashboard builds with TypeScript 7.0.2, Oxlint runs the type-aware
rules, and Babel parses TSX for the localization codemod. T056 remains open pending CI,
code-owner approval, and merge of #902. After it merges, close #272 as superseded if
Dependabot has left it open.

---

Expand Down
Loading
Loading