82 Commits

Author SHA1 Message Date
James Anderson 746d6b5970 chore(ci): bump Node to 24 for native URLPattern support (#1283) 2026-05-16 19:33:46 +01:00
James Anderson 3e8db450f4 ci(nextjs-deploy): add test-path filter input (#1280)
Lets workflow_dispatch runs target a single suite (e.g.
test/e2e/edge-async-local-storage) instead of the full ~16-shard run,
shortening the iteration loop when investigating a specific failure.
The compat-ingest step is gated off for path-filtered runs so partial
snapshots don't drag the historical pass-rate trend.
2026-05-16 17:47:22 +00:00
James Anderson c7453909e2 fix(workflow): use correct workers.dev URL for compat ingest (#1241)
* fix: use vinext-web.vinext.workers.dev as the ingest URL

The default URL I picked (cloudflare.workers.dev) was a guess — workers
*.workers.dev URLs are namespaced under the account subdomain, which for
this account is vinext.workers.dev (see scripts/smoke-test.sh and the
deploy-examples workflow). curl was getting NXDOMAIN.

Still overridable via the COMPAT_INGEST_URL repo variable for custom
domains later.

* fix(workflow): also archive compat-ingest.json in the report artifact

When the live POST to /api/compatibility fails (DNS, expired secret,
rotated secret, etc.) we previously had no way to recover the run
without re-running the 40-minute suite. The ingest payload was being
generated but only the human-readable deploy-suite-report.json was
uploaded.

Add compat-ingest.json to the same artifact so a maintainer can
download it and curl it through manually.
2026-05-15 16:06:59 +00:00
James Anderson 1c0bdacda6 feat(apps/web): /compatibility page backed by D1 + deploy-suite ingest (#1239)
* feat(apps/web): /compatibility page backed by D1 + deploy-suite ingest

Adds a /compatibility page to apps/web that visualises Next.js
compatibility over time, populated by the nightly deploy-suite workflow.

  - D1 binding (`vinext-metrics`) with Drizzle schema and migrations.
    Tables are namespaced (`compat_runs`, `compat_file_results`) so
    future metric kinds can live alongside.
  - POST /api/compatibility ingest endpoint. Authenticates with a
    `COMPAT_INGEST_SECRET` worker secret and upserts by
    (kind, runKey).
  - GitHub-style contribution grid (one dot per test file) and a
    pass-rate-over-time line chart. Both are SVG, no chart libs.
    Pass rate excludes Next.js-skipped tests from the denominator.
  - Shared header/footer extracted into app/_components and rendered
    by the root layout. Nav uses next/link for soft client nav.
  - Workflow change: on top of the existing per-test pass/fail/skip
    aggregation, the report job now POSTs results to the ingest
    endpoint. Guarded to only run when (a) filter=all and
    (b) targeting main, so partial runs and branch spot-checks don't
    pollute the historical record.

The first nightly run after merge will seed the production D1.

* address review + add ISR with KV cache

Review fixes (apps/web/app/api/compatibility/route.ts):
  - constant-time secret comparison via SHA-256 + bytewise XOR
  - single-statement atomic upsert with onConflictDoUpdate (no
    SELECT->INSERT race for concurrent retried runs)
  - top-level try/catch with structured error body so workflow logs
    show why ingest failed instead of a generic 500
  - MAX_FILES=2000 cap in validation as defensive bound

Page perf (apps/web/app/compatibility/page.tsx):
  - latest-run and trend D1 queries run in parallel via Promise.all

ISR + KV:
  - new vinext-web-cache KV namespace bound as VINEXT_CACHE
  - worker installs KVCacheHandler once per isolate
  - both pages opt into ISR with revalidate = 300; compat page drops
    force-dynamic

* address bonk re-review

  - Drop the ?kind= query param. Only one kind exists today; gating it
    behind an unused param invited ISR cache pollution. Hardcoded to
    "deploy" with a comment pointing future kinds at a dedicated route.

  - Wrap the DELETE + chunked INSERTs in a single `db.batch()` so a
    crash mid-write can no longer leave a run with zero file results.
    D1 executes batch statements inside one transaction.

  - Resolve workflow expressions once via step-level `env:` and read
    them as `process.env.*` from the github-script body. Removes the
    fragile splicing of `${{ inputs.next-ref || 'v16.2.6' }}` into JS
    string literals (the nested single quotes were the worst offender).
2026-05-15 15:10:36 +00:00
James Anderson d9906b94d6 chore: add basic vinext site (#1236)
* chore: scaffold new next app with vinext

* basic app

* add to deploy workflow

* fmt
2026-05-15 13:41:10 +00:00
James Anderson 600580eec0 ci(e2e): cache WebKit apt archives and skip browser install on cache hit (#1228)
WebKit E2E jobs were dominated by two costs:

1. `playwright install --with-deps webkit` re-downloaded the browser
   binaries (or at least re-validated them) on every run even when the
   browser cache was hit, because the install step was unconditional.
2. The `--with-deps` flag always ran `apt-get install` for WebKit's
   system libraries (~30+ packages), and apt re-downloaded the .deb files
   on every run since runner archives aren't preserved across runs.

This commit:

- Splits browser install from system dep install so each can be cached
  on its own schedule.
- Gates the browser install on `cache-hit`, so cached runs skip the
  Playwright CLI entirely on the hot path.
- Adds a second cache for `/var/cache/apt/archives` (mirrored through
  `~/.cache/apt-archives`) so apt finds previously downloaded .deb files
  and skips redownloading them. The install itself still runs every
  time, but the slow network portion goes away.
- Keys both caches on the resolved Playwright version from pnpm-lock.yaml
  rather than the full lockfile hash, with a fallback `restore-keys` so
  unrelated lockfile churn doesn't invalidate the cache.

Chromium jobs also benefit from skipping the Playwright CLI on cache hits.
2026-05-15 10:39:18 +01:00
James Anderson bc8cee2385 fix(deploy-suite): extract CJS->ESM converter to standalone script (#1209)
* fix(deploy-suite): extract CJS->ESM converter to standalone script

The CJS->ESM next.config converter was inlined into scripts/e2e-deploy.sh
via 'node -e ...' with bash single-quote escapes ('"'"'). The escaping
rebalanced quotes such that later code (a comment containing '(e.g.') sat
outside any single-quoted bash region, causing 'bash -n' to fail with:

  scripts/e2e-deploy.sh: line 490: syntax error near unexpected token `('

The script died before doing anything in every deploy-suite shard, producing
2480 identical 'Custom deploy script failed: undefined (2)' failures and a
misleading 9.5% pass rate (almost all 'passes' were 'should skip next deploy'
no-ops). See run 25869359604.

- Extract the converter to scripts/cjs-to-esm-config.mjs (same regex
  pipeline, no behavioural change).
- Replace the inlined 'node -e' block with a plain 'node ./script.mjs'
  invocation.
- Add a 'bash -n scripts/*.sh' gate to the Check job so a future regression
  here can't ship green.

* Apply suggestion from @james-elicx
2026-05-14 16:04:09 +00:00
James Anderson 843df83de9 ci(deploy-suite): default to all suites and disable test retries (#1208)
The Next.js deploy suite defaulted to only running app router tests with
3 attempts per test (run-tests.js DEFAULT_NUM_RETRIES = 2). Switch the
default suite-filter to 'all' so nightly runs cover pages router too,
and pass --retries 0 so failures surface on the first attempt instead
of masking flakes behind retries.
2026-05-14 15:27:24 +00:00
James Anderson 747bb0ec76 ci: add Next.js deploy suite harness (#1189)
* ci: add Next.js Pages Router deploy suite harness

Add the workflow, scripts, and manifest generator for running the
Next.js Pages Router deploy test suite against vinext.

Triggers:
- Nightly cron (06:00 UTC) against main
- Manual dispatch with configurable vinext-ref, next-ref, and concurrency

Extracted from #922.

* refactor: align deploy suite harness with Next.js adapter testing docs

- Rename scripts to match Next.js convention: e2e-deploy.sh, e2e-logs.sh,
  e2e-cleanup.sh
- Split workflow into build + test jobs (build once, shard 16 ways) per
  the documented adapter testing pattern
- Generalize workflow from pages-only to configurable: add suite-filter
  input (pages/app/all, defaults to pages)
- Add --filter flag to manifest generator (replaces the pages-hardcoded
  version)
- Accept ADAPTER_DIR (Next.js docs convention) alongside VINEXT_DIR
- Rename workflow file to nextjs-deploy-suite.yml
- Use matrix.group strings ("1/16") instead of shard integers, matching
  the docs example

* ci: default suite-filter to app

* ci: bump Next.js default to v16.2.6, move cron to 02:00 UTC

* address review: add report job, clean up cache paths, document compat shims

- Add a report job that aggregates .results.json across all shards into
  a GitHub Actions summary (pass/fail/skip counts, failed test details,
  passed suite list) and uploads a JSON report artifact
- Upload test results from every shard (not just on failure)
- Remove redundant next.js/ from cache paths (already under .)
- Add comment explaining why IS_TURBOPACK_TEST=1 is needed
- Clean up stale PID file in e2e-cleanup.sh
- Add header comments to all scripts explaining their purpose and contract
- Document the hardcoded warning messages and .next/trace shim
- Document the YAML catalog parser assumptions
- Fix [[ ]] -> [ ] inconsistency in run-nextjs-deploy-suite.sh

* ci: add temporary PR trigger to test workflow [remove before merge]

* fix: address deploy script failures found in CI and local testing

Bugs found and fixed:

- IMMUTABLE_ASSET_TOKEN marker renamed to NEXT_SUPPORTS_IMMUTABLE_ASSETS
  to match what next-deploy.ts parseIdsFromCliOuput() actually parses.
  Without this, every test fails with 'Failed to get supportsImmutableAssets'.

- Deploy script now injects "type": "module" into test app package.json
  and generates a vite.config.ts. Without type:module, Rolldown emits .mjs
  files but the RSC plugin's cross-environment imports expect .js. This
  mirrors what `vinext init` does (steps 3 and 5).

- Added vp (Vite+) fallback to run_pnpm() for environments where pnpm
  and corepack are not available but vp is.

- Cleanup script now uses process group kills (kill -TERM -PID) and a
  port-based lsof fallback to handle orphaned child processes from
  vp/pnpm exec wrappers.

- Error cleanup trap now dumps the last 80 lines of the build log and
  last 40 lines of the server log to stderr, so failures are visible
  in CI output (previously only showed file sizes).

- Test job uses run-install: false since the workspace is already built
  in the cache from the build job.

Tested locally: deploy script succeeds, curl returns valid HTML, logs
script outputs all three required markers (BUILD_ID, DEPLOYMENT_ID,
NEXT_SUPPORTS_IMMUTABLE_ASSETS), cleanup kills the server.

* fix: use vinext init in deploy script, add next.config.js to CJS rename list

Replace the manual type:module / vite.config.ts / CJS rename logic in
e2e-deploy.sh with a single `vinext init --skip-check --force` call.
This runs after pnpm install (so deps are available) and before
vinext build.

Also add next.config.js to the CJS_CONFIG_FILES list in project.ts.
Without this, vinext init adds type:module but doesn't rename CJS
next.config.js files, causing 'module is not defined in ES module
scope' errors. This was the root cause of the CI failures — Next.js
test fixtures use module.exports in next.config.js.

All 61 init tests pass.

* fix: convert CJS next.config.js to ESM instead of renaming to .cjs

Next.js doesn't support next.config.cjs, so we can't rename it. Instead,
convert module.exports/require() to export default/import in-place after
vinext init adds "type": "module".

Also revert adding next.config.js to CJS_CONFIG_FILES — vinext init
should not rename it since it's not a generic config file.

Tolerate pnpm 10+ ERR_PNPM_IGNORED_BUILDS exit code 1 on install (the
install completes, packages are in node_modules, but pnpm exits non-zero
due to unapproved build scripts). Verify node_modules/vinext exists
as a safety check.

Tested against the real Next.js actions-streaming fixture: CJS
next.config.js converted, app builds, server starts, HTTP 200.

* fix: emit both IMMUTABLE_ASSET_TOKEN and NEXT_SUPPORTS_IMMUTABLE_ASSETS

v16.2.x parses IMMUTABLE_ASSET_TOKEN, canary renamed it to
NEXT_SUPPORTS_IMMUTABLE_ASSETS. Emit both for cross-version compat.

* fix: enable JSX in .js files, convert CJS next.config.ts to ESM

Add vinext:jsx-in-js transform plugin to handle JSX in plain .js files.
Next.js allows JSX in .js files (Babel/SWC handle it transparently),
but Vite 8's built-in vite:oxc plugin excludes .js files by default
(exclude: /\.js$/) AND infers lang: 'js' from the extension (which
disables JSX parsing). Neither can be fixed via config alone.

The plugin runs with enforce: 'pre' before vite:oxc, transforming .js
files with OXC using lang: 'jsx' so JSX is compiled before vite:oxc
sees the code. This unblocks ~60 test suites in the deploy suite.

Also extend the deploy script's CJS-to-ESM config converter to handle
next.config.ts files (not just .js), fixing ~6 more test failures.

Tested: 1284 tests pass (jsx-in-js + shims + routing + app-router),
zero regressions.

* ci: trigger clean workflow run

* fix: improve CJS-to-ESM converter for next.config files

The naive regex converter missed two patterns:
- require('mod')(args) produced invalid ESM (import X from 'mod'(args))
- require() calls inside function bodies were not converted

New converter handles:
- module.exports = X → export default X
- const X = require('mod') → import X from 'mod'
- const X = require('mod')(args) → import _X from 'mod'; const X = _X(args)
- require('mod') in expressions → (await import('mod')).default

Tested against bundle-analyzer, path, and inline require patterns.

* .

* Apply suggestion from @james-elicx

* fix: handle destructured requires in CJS converter, read port from file in cleanup

- Add pattern for const { a, b } = require('mod') → import { a, b } from 'mod'
- Read port from PORT_FILE in cleanup_on_error trap instead of using $PORT
  variable which may be unset if the script fails before port allocation
- Add TODO noting remaining CJS edge cases (dynamic require, require.resolve)

* Apply suggestions from code review

Co-authored-by: James Anderson <james@eli.cx>

* Apply suggestion from @james-elicx
2026-05-14 13:01:01 +00:00
Stephen Zhou 9126344cd8 fix: use loader for client reference (#1141)
* fix: split client chunk

* add test

* fix ci deps

* install deps

* use loader

* tweaks
2026-05-14 13:18:58 +01:00
Arpit Jain e33feeb946 ci(benchmarks): pin contents: read (#1188)
The benchmarks workflow uploads the artifact via
actions/upload-artifact (writes only to the run's artifact store, not
the repo) and POSTs results to benchmarks.vinext.workers.dev using
secrets.BENCHMARK_UPLOAD_TOKEN. The GitHub token is only used for the
checkout, so contents: read is sufficient. Top-level style matches
the rest of the repo.
2026-05-13 12:10:46 +01:00
James Anderson a27193fcaf chore: upgrade pnpm 10 to 11 and enable frozenLockfile (#1185)
* chore: upgrade pnpm 10 to 11 and enable frozenLockfile

- Bump packageManager from pnpm@10.32.1 to pnpm@11.1.1
- Migrate .npmrc settings to pnpm-workspace.yaml (pnpm 11 only reads auth/registry from .npmrc)
  - auto-install-peers=false -> autoInstallPeers: false
  - Remove playground save-exact=true (minor pnpm add preference, not needed for builds)
- Convert onlyBuiltDependencies list to allowBuilds map (pnpm 11 format)
- Add frozenLockfile: true and preferFrozenLockfile: true
- Delete .npmrc files (contained no auth settings)

* fix: handle pnpm 11 strictDepBuilds, preserve autoInstallPeers, remove minimumReleaseAgeExclude

- Add unrs-resolver: false to allowBuilds (reviewed, deny build scripts)
- Keep autoInstallPeers: false to match existing lockfile
- Remove minimumReleaseAgeExclude entirely
- Append allowBuilds to scaffolded project's pnpm-workspace.yaml after
  create-next-app so subsequent pnpm steps don't abort
2026-05-13 09:15:02 +00:00
dependabot[bot] e9d1749b95 chore(deps): bump next from 16.2.5 to 16.2.6 (#1183)
* bump nextjs

* .

---------

Co-authored-by: James <james@eli.cx>
2026-05-12 14:18:00 +00:00
James Anderson 0f05e53f1f bump setup-vp (#1135) 2026-05-07 14:35:08 +00:00
James Anderson ea096701da ci: pin pnpm in cna-test to vinext's package.json version (#1131)
The create-next-app job was failing with ERR_PNPM_UNEXPECTED_STORE.
create-next-app's bundled pnpm (10.x) installs node_modules linked to
the v10 store; vp's bundled pnpm recently bumped to v11, which then
refuses to add packages to the v10-linked node_modules.

Anchor the scaffolded project to vinext's own pinned pnpm version
(read from root package.json's packageManager field) and invoke that
pnpm directly via npx for the install step. This:

- keeps store layouts aligned between create-next-app's install and
  the subsequent vinext add
- stays in sync with future pnpm bumps without further CI edits
- bypasses vp's bundled pnpm only for this layering step; the rest of
  the job (vp exec, vp dlx) is unchanged
2026-05-07 11:14:19 +00:00
James Anderson b631b5da4a chore(deps): bump next.js version (#1112)
* chore(deps): bump next.js version

* fix tests
2026-05-06 17:32:01 +00:00
James Anderson ae8aa6f3a6 chore: coverage on main only + tweak cache keys (#1025) 2026-05-02 21:33:50 +00:00
James Anderson c1c81886d2 test: add coverage summaries for integration tests in ci (#1024) 2026-05-02 21:17:27 +00:00
Divanshu Chauhan (divkix) f972d45034 fix: resolve symlink paths in standalone BFS package copy (#724) (#942)
* fix: resolve symlink paths in standalone BFS package copy (#724)

When resolvePackageJsonPath finds a package via the lookup-paths
fallback, the returned path may be a symlink (e.g., under a hoisted
node_modules/ directory). Calling createRequire() on a symlink
path causes Node module resolution to miss transitive dependencies
because it walks up from the symlink ancestor directories rather
than the real (e.g., .pnpm/) path.

Fix: call fs.realpathSync() on the resolved package.json path
before using it for createRequire() and readPackageJson().

Also adds E2E test coverage for the standalone output mode.

* fix: address review feedback

Add standalone-output to CI E2E matrix, rename server header test
to reflect what it actually asserts, fix unused req parameter.
2026-04-28 21:19:09 +01:00
James Anderson 098240d474 chore(ci): change bonk opencode version (#937) 2026-04-28 09:19:17 +00:00
James Anderson a701d72bab chore(ci): change bonk perms back to normal (#936) 2026-04-28 09:02:43 +00:00
James Anderson 103aef2b2d chore(ci): change bigbonk permissions prereq (#935) 2026-04-28 08:46:16 +00:00
James Anderson 8747b3d1a0 chore(ci): change bonk back to opus 4.6 (#934)
* chore(ci): change bonk back to opus 4.6

* add nathan to bonk workflow

* boink
2026-04-28 08:01:00 +00:00
James Anderson ec4cdd4e23 chore(ci): switch bonk back to opus 4.7 (#904) 2026-04-25 22:03:30 +01:00
Nathan Nguyen f8e9d3a57b ci(bonk): bump opencode to 1.4.11 to unblock OAI through cf-ai-gateway (#903)
Bots throw "max_tokens not supported, use max_completion_tokens" on
1.4.6 with gpt-5.x reasoning models. opencode 1.4.6 predates the
cf-ai-gateway plugin's chat.params hook (PR #22864, landed in 1.4.7),
which strips maxOutputTokens for OpenAI reasoning models so the
@ai-sdk/openai-compatible default no longer leaks the rejected field.

The earlier ProviderInitError on 1.14.x was a separate regression in
opencode's npm install path: the major bump introduced loadOptions(dir)
via @npmcli/config inside Npm.add, which fails on CI runners and bubbles
up as InstallFailedError, then gets re-wrapped at provider.ts:1522 as
ProviderInitError with the original cause swallowed by the session
error path. Other Cloudflare repos (workers-sdk, workerd, kumo) hit the
same regression on anthropic and pinned 1.4.6 / 1.2.27 to dodge it.

1.4.11 is the last 1.4.x release: it has the chat.params max_tokens
patch and predates the loadOptions install regression. Same
ai-gateway-provider 3.1.2, same @ai-sdk pins as 1.4.6, so the install
path stays the known-good arborist.reify call shape that works for
workers-sdk + anthropic on 1.4.6.

Verified locally with opencode 1.14.25 + cf-ai-gateway/openai/gpt-5.4 +
fake creds: empty-cache short-circuit and loadOptions both reproduce
the silent ProviderInitError. 1.4.11 lacks both code paths.
2026-04-25 20:48:40 +00:00
Nathan Nguyen e7706ea31b ci(bonk): pin opencode to 1.4.6 to dodge cf-ai-gateway ProviderInitError (#902)
Every bonk and bigbonk run since opencode 1.14.25 throws
UnknownError: ProviderInitError during cf-ai-gateway SDK init,
regardless of model. Verified across gpt-5.5 (#898), gpt-5.4 (#900),
and the throw fires before any per-model code path runs.

workers-sdk hit the same regression and pinned opencode_version to
1.4.6 with an inline comment naming ProviderInitError as the cause.
Several other Cloudflare repos pin 1.2.27 / 1.4.6 for the same
reason. vinext is the only Cloudflare repo running OAI through
cf-ai-gateway, so the OAI-specific path stayed unobserved until #898
re-tried it on 1.14.25.

Pinning to 1.4.6 here reuses workers-sdk's known-good version. The
gpt-5.4 model from #900 stays; gpt-5.4 predates 1.4.6's bundled
snapshot by over a month, so registry resolution is fine.
2026-04-25 20:21:23 +00:00
Nathan Nguyen 5b5071cd5c ci(bonk): downgrade bots from gpt-5.5 to gpt-5.4 (#900)
bonk and bigbonk currently throw ProviderInitError on every invocation
after the gpt-5.5 switch in #898. The lookup-side regression that #899
patched was masked by the opencode bump (1.14.22 -> 1.14.25) but a
second failure now surfaces during SDK init for cloudflare-ai-gateway.
opencode swallows the underlying cause, and the gpt-5.5 path through
ai-gateway-provider has no working precedent in this repo, so iterating
on it would block PR review indefinitely.

Roll the model back to gpt-5.4, which has a known-good path through
opencode + ai-gateway-provider + Cloudflare AI Gateway, and remove the
opencode.json workaround introduced in #899. Reasoning effort stays at
"xhigh" per James's preference; opencode will fall back to its default
effort if gpt-5.4 doesn't accept it.

Once gpt-5.5 SDK init is fixed upstream (opencode + ai-gateway-provider
+ models.dev cloudflare-ai-gateway entry), we can roll forward again.
2026-04-25 19:54:48 +00:00
Nathan Nguyen 76690d4bcf Switch bonk and bigbonk workflows to GPT-5.5 xhigh variant (#898)
* ci(bonk): switch bonk workflow to GPT-5.5 xhigh variant

Updates the bonk workflow to use cloudflare-ai-gateway/openai/gpt-5.5
with reasoning effort variant xhigh, replacing the previous
claude-opus-4-7 model.

https://claude.ai/code/session_012n6RFuqfQGQY7AaayqLcaG

* ci(bonk): extend GPT-5.5 xhigh switch to bigbonk, agent defs, and docs

- bigbonk workflow: cloudflare-ai-gateway/openai/gpt-5.5 with variant xhigh (was claude-opus-4-7 + max)
- viguy and reviewer OpenCode agent definitions: openai/gpt-5.5 (was anthropic/claude-opus-4-7)
- CONTRIBUTING.md: update recommended setup and BigBonk description to GPT-5.5 xhigh

The Next.js tracker workflow and agent are intentionally left on Claude
Opus 4.7.

https://claude.ai/code/session_012n6RFuqfQGQY7AaayqLcaG

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-25 19:09:52 +00:00
James Anderson f37b783e73 switch bonk back to opus (#897) 2026-04-25 18:47:58 +00:00
James Anderson 3ddaefa23c bump opencode (#896) 2026-04-25 18:41:17 +00:00
James Anderson 2c837da309 try gpt 5.5 for bonk (#895) 2026-04-25 18:33:25 +00:00
James Anderson dbcca8c780 try gpt 5.5 for bonk (#894) 2026-04-25 18:26:06 +00:00
James Anderson 9ff25d8be0 fix knip issues (#890)
* fix knip issues

* run knip in ci

* .

* feedback
2026-04-24 21:15:32 +00:00
James Anderson 504447db68 bump opencode version (#881) 2026-04-24 08:56:24 +00:00
Nathan Nguyen 7bbb9b5f95 update bonk to opus 4.7 (#873)
* chore: upgrade workflows from claude-opus-4-6 to claude-opus-4-7

Update model references in bonk, bigbonk, and nextjs-tracker workflows
to use the latest Opus 4.7 model via the Cloudflare AI Gateway.

https://claude.ai/code/session_018pEfYehfR4YDA1Ekmu1vn3

* chore: upgrade opencode agents from claude-opus-4-6 to claude-opus-4-7

Update model references in reviewer, viguy, and nextjs-tracker agent
configs to use the latest Opus 4.7 model.

https://claude.ai/code/session_018pEfYehfR4YDA1Ekmu1vn3

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 08:04:53 +01:00
dependabot[bot] 41d363e8b2 chore(deps): bump vite-plus from 0.1.12 to 0.1.17 (#858)
* chore(deps): bump vite-plus from 0.1.12 to 0.1.17

Bumps [vite-plus](https://github.com/voidzero-dev/vite-plus/tree/HEAD/packages/cli) from 0.1.12 to 0.1.17.
- [Release notes](https://github.com/voidzero-dev/vite-plus/releases)
- [Commits](https://github.com/voidzero-dev/vite-plus/commits/v0.1.17/packages/cli)

---
updated-dependencies:
- dependency-name: vite-plus
  dependency-version: 0.1.17
  dependency-type: direct:production
...

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

* bump setup-vp

* update agents

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James <james@eli.cx>
2026-04-17 07:43:02 +00:00
Stephen Zhou cb42ba3b7b ci: disable ecosystem run in fork (#836) 2026-04-14 07:52:28 +01:00
Erez Rokah 25bbfa6937 chore: Harden CI supply chain (#826)
* chore: harden CI supply chain

- Pin voidzero-dev/setup-vp to commit SHA across all workflows
- Pin create-next-app and pkg-pr-new to exact versions

* pull setup-vp into setup action

---------

Co-authored-by: James <james@eli.cx>
2026-04-13 08:05:50 +00:00
James Anderson 49656ed5cf fix: security audit findings from issue #741 (#757) (#769)
* fix: security audit findings from issue #741

CI shell injection (high):
- publish.yml: use env var for inputs.bump in case statement
- nextjs-tracker.yml: use env vars for since_hours and dry_run inputs
- nextjs-tracker.yml: use env var in Skip step echo

Test file false positive (critical flag):
- tests/vite-hmr-websocket.test.ts: add gitleaks:allow for RFC 6455
  example WebSocket nonce (dGhlIHNhbXBsZSBub25jZQ==)

innerHTML / XSS (high):
- packages/vinext/src/shims/script.tsx: add security comment documenting
  that dangerouslySetInnerHTML is developer-supplied inline script only
- packages/vinext/src/shims/head.ts: document tag is bounded to
  RAW_CONTENT_TAGS (script/style), not user input

dangerouslySetInnerHTML in example (medium):
- examples/hackernews/components/comment.jsx: sanitize HN API HTML
  with DOMPurify before rendering
- examples/hackernews/package.json: add dompurify dependency
- pnpm-workspace.yaml: add dompurify and @types/dompurify to catalog

Non-literal RegExp (medium): documented as internal config values only,
no user input reaches any of the 6 flagged patterns. See safeRegExp()
in config-matchers.ts which already enforces ReDoS protection.

Deprecation cleanup:
- examples/hackernews/tsconfig.json: remove deprecated baseUrl option
  (moduleResolution: bundler handles resolution; all imports are relative)
- examples/hackernews/tsconfig.json: add noEmit: true to prevent TypeScript
  from attempting to write over existing .js files in lib/
- examples/hackernews/package.json: add missing @cloudflare/workers-types
  devDependency (was referenced in tsconfig types but not installed)

* fix: address bonk review comments

- Switch dompurify → isomorphic-dompurify so sanitize() works during
  SSR (DOMPurify is a no-op without window/document; isomorphic-dompurify
  bundles jsdom for server-side use)
- Revert package.json whitespace to 2-space indentation (was inadvertently
  changed to 4-space, creating noise in the diff)
- Replace dompurify + @types/dompurify catalog entries with
  isomorphic-dompurify (ships its own types, no separate @types needed)
- Add missing trailing newline to tsconfig.json

* fix: address bonk review comments on PR #769

- Switch from isomorphic-dompurify to sanitize-html, and move
  sanitization to the server-side data boundary (lib/get-comments.js).
  isomorphic-dompurify depends on jsdom which is Node.js-specific and
  does not work in the Cloudflare Workers runtime. sanitize-html is
  pure-JS (htmlparser2-based) with no DOM dependency and works in both
  Workers and Node.js. Sanitizing once at the data boundary means both
  the SSR'd initial HTML response and client re-renders receive safe text.
- Remove the DOMPurify import from comment.jsx; the client component no
  longer needs to sanitize since text is already clean when passed as a prop.
- Replace isomorphic-dompurify with sanitize-html in the workspace catalog.
- Remove inert eslint-disable-next-line comment from script.tsx; the project
  uses oxlint which ignores ESLint-specific inline suppression directives.

---------

Co-authored-by: Luke Percy <lpercyagile@gmail.com>
2026-04-03 12:47:24 +01:00
James Anderson f99ff7afa8 chore: try different opencode version for bonk (#738) 2026-04-01 12:15:02 +00:00
James Anderson 3c8ff6a7ac chore(ci): disable nextjs tracker for forks (#713) 2026-03-29 19:09:21 +00:00
Stephen Zhou 207588d164 feat: add instrumentation-client support (#679)
* feat: add instrumentation-client support

* trigger ci

* fix deps

* tweaks

* tweaks

* tweaks

* tweaks

* rebuild lockfile

* fix: add app-with-src to CI E2E matrix

---------

Co-authored-by: James <james@eli.cx>
2026-03-28 21:21:36 +00:00
Raed Alharbi a515f07a49 test: add static export E2E tests (#564) (#686)
* test: add static export E2E tests (#564)

Add Playwright E2E tests for `output: "export"` static builds covering
both App Router and Pages Router. Includes a lightweight static file
server with path traversal protection, proper error handling, and
startup validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update tests/e2e/static-export/serve-static.mjs

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
2026-03-28 09:06:06 +00:00
Steve Faulkner 2d03bc569d fix: inline commits into agent prompt to prevent codebase exploration (#693)
The agent kept launching a Task subagent to "explore the vinext codebase
structure" despite instructions not to, consuming the entire 30-minute
timeout. The task permission deny in the agent config was not effective.

Fix: embed the commits JSON directly into the prompt so the agent has
all data immediately and no reason to explore. Also add explicit
"do not explore, do not launch subagents" at the end of the prompt.
2026-03-26 13:54:57 -05:00
Steve Faulkner adfc2236cb fix: nextjs-tracker workflow fails because prompt_file is not a valid action input (#687)
The ask-bonk action doesn't support a prompt_file input. The prompt was
silently ignored, causing the scheduled run to fail with 'PROMPT input
is required'. Set the prompt as a multiline step output and reference it
via the prompt input instead.
2026-03-25 08:54:17 -05:00
Steve Faulkner 63cbaad7e0 feat: nextjs-tracker — daily workflow to track Next.js canary changes (#682)
Daily scheduled job that scans Next.js canary commits, uses an AI agent
to classify relevance to vinext, and opens labeled tracking issues for
anything that matters. Supports a dry-run mode for validation.
2026-03-24 21:11:19 -05:00
Steve Faulkner 47fec0c871 chore: upgrade vitest to v4 and enable agent reporter (#612)
* chore: bump pnpm to 10.32.1 and enable vitest agent reporter

* chore: upgrade GitHub Actions to Node 24 compatible versions

* perf: re-land unit/integration split and add CI sharding

- Restore unit/integration vitest project split (lost in vp migration)
- vitest 4 supports fileParallelism per-project (was global-only in v3),
  so unit tests now run in parallel (~11s) while integration stays serial
- Add 3-shard matrix for integration tests in CI, cutting wall time from
  ~4.5min to ~1.5min
- Move kv-cache-handler to integration to avoid flakiness under parallelism

* chore: remove unused deploy-preview slash command workflow

* ci: add sentinel job for stable branch protection rule
2026-03-20 16:20:42 -05:00
James Anderson f78dd2b39f chore: switch back to setup-vp@v1 (#587)
* chore: switch back to setup-vp@v1

* try commit hash

* back to v1
2026-03-19 10:01:45 +00:00
James Anderson a86b67dff4 feat: full next/compat/router support and fix vinext check scanner for shimmed modules (#584)
* feat: full next/compat/router support and fix check scanner for shimmed modules

- Export NextRouter interface from shims/router.ts so compat-router.ts can use it
- Add NextRouter | null return type to useRouter() in shims/compat-router.ts
- Add next/compat/router, next/form, next/web-vitals, next/constants to IMPORT_SUPPORT in check.ts so vinext check no longer flags them as unsupported
- Add integration fixture pages and components for next/compat/router in both pages-basic and app-basic fixtures
- Add integration tests in tests/pages-router.test.ts and tests/nextjs-compat/hooks.test.ts
- Add unit tests in tests/check.test.ts covering all four newly-registered imports

* test: update entry-templates snapshots for compat-router-test fixture page

* remove type assertion

* fix: add declare module for next/compat/router to fixture next-shims.d.ts files

* fix: add declare module for next/compat/router to internal next-shims.d.ts

* pin to vp setup 1.0.0
2026-03-19 08:47:40 +00:00
Steve Faulkner a6d6688663 fix: pass --no-git-checks to pnpm publish (#576)
The version bump step modifies package.json without committing, leaving
the working tree dirty. pnpm publish enforces git-checks by default and
refuses to publish. Pass --no-git-checks before the -- separator so
pnpm skips the check while --provenance still reaches npm.
2026-03-17 13:34:51 +00:00