* fix(deps): upgrade vulnerable transitive dependencies
Dependabot audit fixes:
- brace-expansion 5.0.7 -> 5.0.8 (CVE-2026-14257, GHSA-mh99-v99m-4gvg)
High severity: DoS via unbounded expansion length causing OOM crash
- valibot 1.2.0/1.4.1 -> 1.4.2 (CVE-2026-59952)
Medium: record() issue paths can make flatten() throw
- node-tar 7.5.x -> 7.5.21+ (GHSA-r292-9mhp-454m)
Medium: Uncontrolled recursion in mapHas/filesFilter
- astro 6.4.8 -> 7.1.0 (CVE-2026-59729, CVE-2026-59727)
Medium/Low: XSS via unescaped spread attributes / transition directives
- quinn-proto 0.11.13 -> 0.11.15 (GHSA-4w2j-m93h-cj5j)
High: Remote memory exhaustion in quinn-proto
Not addressed (no upstream fix):
- failure 0.1.8 (CRITICAL, 2 alerts) - deprecated Rust crate, used transitively
GHSA-jq66-xq47-j9f3, GHSA-r98r-j25q-rmpr
* fix(ci): dependabot auto-merge waits for CI, fix unscoped filter (#27)
CRITICAL: previously auto-merge ran on PR open with no CI check.
.github/workflows/dependabot-auto-merge.yml called pulls.merge
directly, merging dependabot PRs before typecheck/lint/test ran.
Combined with develop having zero branch protection, broken
dep PRs could land on the default branch.
Two fixes:
1. Filter on ecosystem via PR label (npm vs cargo), not the
bogus 'contains(@)' check that excluded unscoped packages.
2. Pre-check getCombinedStatusForRef before merging. Skips
with info log if state is not 'success'; will retry on next
push (synchronize event).
Cargo updates now always require human review (was the original
intent, but broken by the @ filter). PR titles without a parseable
'semver-from-to' line are treated as major and skipped.
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR1.
Co-authored-by: bot <ci@local>
* chore(deps,ci): dependabot desktop/main + .codecov.yml + CI merge + MSW error + coverage scope (#28)
* chore(deps): add dependabot desktop/main entry + .codecov.yml
desktop/main/ has its own pnpm-workspace.yaml and pnpm-lock.yaml,
so the root npm entry at / does not cover it. All 30+ deps in
the Nuxt 4 desktop app (tauri plugins, koa, etc.) were invisible
to Dependabot.
.codecov.yml added with:
- project status OFF (1.17% baseline, target: auto would block
every PR per AGENTS.md)
- patch status informational at 50% (new code should be tested
but not block)
- server flag target 80% informational
- PR comments disabled (solo dev, low signal at 32 tests)
- ignore patterns for .nuxt/, prisma/client/, proto/, test/
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR2.
* chore(ci): merge test+coverage jobs, MSW error, scope coverage to backend
Three changes:
1. ci.yml: delete the separate coverage job (duplicate setup
vs test job — 14 CI-min wasted per push). Add coverage step
to test job so vitest run --coverage happens once. Codecov
upload moves to test job.
2. server/test/mocks/index.ts: onUnhandledRequest: 'warn' →
'error'. Unmocked HTTP calls now fail the test instead of
producing stderr noise. Forces explicit handler registration.
Escape hatch: resetTestMocks([...unmockedHandlers]) for
intentional bypass.
3. server/vitest.config.ts: include 'server/**/*.ts' →
'server/server/**/*.ts'. The 1.17% coverage baseline is
inflated by ~3-5K LOC of frontend (pages/, components/,
composables/) that is untestable outside Playwright E2E.
New scope reflects only Nitro backend coverage.
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR3.
---------
Co-authored-by: bot <ci@local>
* fix(ts): guard 39 unchecked-indexed sites in auth/metadata/backend (#29)
* fix(ts): guard 39 unchecked-indexed sites in auth/metadata/backend
AGENTS.md deferred 'noUncheckedIndexedAccess' guard work. 30+
files listed but most had already been fixed during PR #25
(SonarCloud sweep). Remaining 9 backend files with 39 errors
fixed in this PR:
- auth/mfa/webauthn/finish.post.ts: passkey may be undefined
after findIndex; add guard, also fix counter assignment
- auth/passkey/finish.post.ts: same pattern as webauthn
- admin/import/massversion/index.post.ts: version may be
undefined inside for loop
- admin/game/image/index.delete.ts: mImageLibraryObjectIds[0]
may be undefined after splice, set to null only if a next
image exists
- auth/totp.ts: uint8array[i] is number | undefined
- clients/event-handler.ts: parts[0] may be undefined
- metadata/igdb.ts: response[0] may be undefined
- metadata/pcgamingwiki.ts: cargoquery[i].title may be
undefined
- system-data/index.ts: cpus[cpu].times may be undefined
- utils/prioritylist.ts: pop() may return undefined; throw
on empty list (matches the contract)
Not in this PR (follow-up work, ~57 frontend errors):
Enabling noUncheckedIndexedAccess in user-facing tsconfig.json
surfaces errors in components/, pages/, composables/. These are
mostly route.params.id, undefined-check on array access in
template helpers, and exactOptionalPropertyTypes mismatches.
Per plan risk: bulk-guard with @ts-expect-error OR fix
file-by-file. Recommend a follow-up PR per tier.
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR4.
* style: prettier format passkey + webauthn finish.post.ts (#34)
Co-authored-by: bot <ci@local>
---------
Co-authored-by: bot <ci@local>
* test(server): add H3 event stubs and createMockH3Event factory (#30)
* test(server): add H3 event stubs and createMockH3Event factory
Expanded test/setup.ts with 14 more H3/Nuxt globals:
- Request accessors: readFormDataBody, getCookie, getRequestURL, getRequestIP
- Response mutators: setHeader, setCookie, deleteCookie, setResponseStatus, setResponseHeaders
- Response senders: sendRedirect, sendStream, sendError, sendNoContent
- Plugin helpers: defineNitroPlugin, defineNitroErrorHandler
Added server/test/utils/h3.ts with createMockH3Event factory.
Returns a partial H3Event with vi.fn spies for setHeader/sendError/
setCookie/etc. so handlers can be tested without booting Nuxt.
Supports method/url/body/query/headers/cookies/routerParams overrides.
Added server/test/unit/h3-factory.test.ts with 2 tests for the
factory itself. 28 tests pass (up from 26).
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR5.
* test: prettier format setup.ts + fix await in h3-factory test (#35)
Co-authored-by: bot <ci@local>
* test: make 'accepts overrides' it() async for await resolves (#37)
Co-authored-by: bot <ci@local>
---------
Co-authored-by: bot <ci@local>
* chore(deps): consolidate tar override entries across workspaces (#31)
Root pnpm-workspace.yaml had 4 tar override entries:
tar@<7.5.7: '>=7.5.7'
tar@<7.5.8: '>=7.5.8'
tar@<=7.5.2: '>=7.5.3'
tar@<=7.5.3: '>=7.5.4'
desktop/main/pnpm-workspace.yaml had 3:
tar@<7.5.7: '>=7.5.7'
tar@<=7.5.2: '>=7.5.3'
tar@<=7.5.3: '>=7.5.4'
Drift: root had 7.5.8 ceiling, desktop did not.
Consolidate both to single entry:
tar@<=7.5.20: '>=7.5.21'
Latest tar at time of consolidation is 7.5.21+ (CVE-free).
Maintenance burden drops from 7 entries to 2.
pnpm audit confirms 14 pre-existing vulns unchanged (no
regression). pnpm install + typecheck + test all pass.
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR6.
Co-authored-by: bot <ci@local>
* test(server): add pure-function unit tests (array, tuple, colors, utils, prioritylist) (#32)
5 new test files in test/unit/, +31 tests, 57 total pass:
- array.test.ts (10 tests): sum() — empty, positive, mixed, single,
no-mutation. lastItem() — empty, single, multi, object refs.
- tuple.test.ts (2 tests): x/y storage, toString format.
- colors.test.ts (6 tests): getBarColor — 0/70/71/90/91/100
boundary cases.
- utils.test.ts (5 tests): getPercentage — value/total, 0/total,
>100%, div-by-zero (documents current Infinity behavior), fractional.
- prioritylist.test.ts (8 tests): PriorityList — empty, insertion
order, priority sort, pop, cache invalidation, find. PriorityListIndexed
— index by property, remove from index on pop, empty-pop TypeError
(pins current behavior; PR4 will add explicit guard).
Coverage:
- prioritylist.ts: 93.75% lines (was 0%)
- utils/ (array/colors/tuple/utils): 94.73% lines
- overall: 1.17% → 1.9% lines
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR7.
Co-authored-by: bot <ci@local>
* test(server): add security-surface tests (TOTP base64, session memory) (#33)
* test(server): add security-surface tests (TOTP base64, session memory)
2 new test files in test/unit/, +19 tests, 45 total pass:
- auth-totp.test.ts (9 tests): dropEncodeArrayBase64/dropDecodeArrayBase64
round-trip. ASCII 'Hello' = 'SGVsbG8='. Binary sequences.
Empty array. Both directions.
- session-memory.test.ts (10 tests): setSession/getSession, update,
remove, getNumberActiveSessions, cleanupSessions, findSessions
by userId, by data, no-match.
Coverage:
- auth/totp.ts: 0% → covered (base64 functions)
- session/memory.ts: 0% → 80%+
- overall: 1.17% → 2.01% lines
Note on the getNumberActiveSessions test: it documents a pre-existing
bug where the implementation uses session.expiresAt.getDate() (day of
month) instead of Date.now() (timestamp). Test pins current behavior
so a future fix is a deliberate change.
Refs plan at .opencode/plans/hyperplan-dep-tdd-coverage.md PR8.
* test: prettier format auth-totp.test.ts (#36)
Co-authored-by: bot <ci@local>
---------
Co-authored-by: bot <ci@local>
* fix(deps): add @eslint/config-array override for minimatch compat
pnpm install on develop re-resolved lockfile to use minimatch@3.1.5
transitively from @eslint/config-array@0.21.2. ESLint 9 calls
`expand` on the Minimatch class which doesn't exist in 3.x.
`TypeError: expand is not a function` causes Lint to exit 2,
breaking ci.yml and server-ci.yml.
Add override `@eslint/config-array@<0.21.3: ">=0.21.3"` to force
the newer config-array that uses minimatch 10.x. ESLint 9 fully
compatible. Also re-ran prettier --write to normalize quote style
(matches other entries in pnpm-workspace.yaml after PR31 consolidated
overrides).pn
Refs PR #26 (dep-audit-fixes).
---------
Co-authored-by: John Smith <you@example.com>
Co-authored-by: bot <ci@local>
Binary-only crate blocked 11 integration tests from compiling. Tests
referenced 'downpour::*' which only resolves against a lib crate.
- Add cli/src/lib.rs re-exporting cli, commands, logging, manifest,
operator_builder as pub modules
- Update main.rs to consume the same API via 'downpour::'
- Make CompressionOption Copy + Clone for roundtrip ergonomics
- Add is_empty() + len() to DepotManifest and Config for testable
contracts
- Make S3Config fields pub for inspection in tests
- Rewrite tests/manifest_test.rs and tests/config_test.rs to match
the actual API (previous tests were aspirational — never compiled)
Result: 10 integration tests pass (was 0).
Refs: cli-ci.yml 'binary-only crate' comment block.
Auto-merged via batch dependabot merge. Pre-existing CI failures (CodeQL Swift, OSV-Scanner scan-pr, cargo test binary-only crate) are not caused by this dep bump.
Auto-merged via batch dependabot merge. Pre-existing CI failures (CodeQL Swift, OSV-Scanner scan-pr, cargo test binary-only crate) are not caused by this dep bump.
Auto-merged via batch dependabot merge. Pre-existing CI failures (CodeQL Swift, OSV-Scanner scan-pr, cargo test binary-only crate) are not caused by this dep bump.
Auto-merged via batch dependabot merge. Pre-existing CI failures (CodeQL Swift, OSV-Scanner scan-pr, cargo test binary-only crate) are not caused by this dep bump.
EditorConfig CI was reporting 22 files with trailing-ws and no-final-newline
violations. Fixed via sed batch:
- Strip trailing whitespace from end of each line
- Append final newline if file doesn't end with one
Down from 28 errors to 6. Remaining 6 are indent/style issues (B2).