Skip to content

Commit 5d8ec49

Browse files
Brooooooklynclaude
andcommitted
Merge origin/main into feat/email-mono (Worker handoff, self-hosted cleanup)
28 commits from main. Seven conflicts: - packages/deploy-cloudflare/src/version.ts: both sides extended the trigger snapshot at the same spots — kept main's `sourceConfigPath` reader, settings hash and traffic-preserve flags next to our `addresses` reader and replay. main's new `resolvePreservedTraffic` rebuilds the trigger config on every versioned deploy and would have dropped `addresses`; it now carries the key through. - packages/void/src/cli/deploy.ts: `discoverRootWranglerConfig` keeps our export and main's `wrangler.toml` refusal. - packages/void/AGENT_PROMPT.md: our docs sentence (with email) plus main's platform-forks paragraph. - platform/packages/api/test/integration/auth-email-verification.test.ts: main removed the preview-repo signup tests; ours sat after them. Dropped the removed test, kept every owner-email-change test. - platform/meta/operations.md: main replaced the inventory with a maintainer runbook; re-added a condensed Email section (invariants, the unexecuted one-time zone setup, deploy order, rollback, the two retroactive pre-checks). platform/meta/progress.md: main retired it; took main's. platform/packages/api/README.md: both admin rows kept. One auto-merge follow-up: main's new onboarding page test expected a raw `'` in `void connect '<url>'`; our `escapeHtml` escapes quotes (`&#39;`, rendered back by the browser). The test now expects the escaped form. Gates on the merged tree: fmt/lint 0, `vp run check` 0, unit 5103/5103, platform 3761/3761, platform runtime build 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SStP281NuirMSouULEE2pW
2 parents 990d116 + f41bfff commit 5d8ec49

159 files changed

Lines changed: 5049 additions & 3238 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ permissions: {}
1818
jobs:
1919
test:
2020
name: test (${{ matrix.os }}, ${{ matrix.shard }})
21-
runs-on: ${{ matrix.os }}
21+
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository == 'voidzero-dev/void' && 'blacksmith-4vcpu-ubuntu-2404' || matrix.os }}
2222
permissions:
2323
contents: read
2424
# No Cloudflare creds in this job. The credentialed live deploy e2e runs in the separate
@@ -29,7 +29,7 @@ jobs:
2929
matrix:
3030
# Windows runs on main pushes and on PRs labeled "test: windows",
3131
# unless a reusable workflow caller explicitly disables it.
32-
os: '${{ (((github.event_name == ''push'' && startsWith(github.ref, ''refs/heads/'')) || contains(github.event.pull_request.labels.*.name, ''test: windows'')) && !(github.event_name == ''workflow_call'' && inputs.skip_windows)) && fromJSON(''["blacksmith-4vcpu-ubuntu-2404","windows-latest"]'') || fromJSON(''["blacksmith-4vcpu-ubuntu-2404"]'') }}'
32+
os: '${{ (((github.event_name == ''push'' && startsWith(github.ref, ''refs/heads/'')) || contains(github.event.pull_request.labels.*.name, ''test: windows'')) && !(github.event_name == ''workflow_call'' && inputs.skip_windows)) && fromJSON(''["ubuntu-latest","windows-latest"]'') || fromJSON(''["ubuntu-latest"]'') }}'
3333
# Unit tests and two integration shards run on separate runners. Each integration
3434
# shard builds its own checkout first, so generated playground state is never shared.
3535
shard: [unit, '1/2', '2/2']
@@ -70,11 +70,12 @@ jobs:
7070
node-version-file: .node-version
7171
cache: true
7272

73-
# Both runner images already provide Chromium's shared-library dependencies. Avoid
74-
# `--with-deps` here: it runs apt on Linux and makes test startup depend on the external
75-
# Ubuntu mirrors even though no OS packages are needed by these runners.
73+
# The upstream Linux image and Windows already provide browser libraries.
74+
# Forks use GitHub's Ubuntu image and install Chromium's system dependencies.
7675
- run: vp exec playwright install chromium
77-
if: ${{ matrix.shard != 'unit' }}
76+
if: ${{ matrix.shard != 'unit' && (runner.os != 'Linux' || github.repository == 'voidzero-dev/void') }}
77+
- run: vp exec playwright install --with-deps chromium
78+
if: ${{ matrix.shard != 'unit' && runner.os == 'Linux' && github.repository != 'voidzero-dev/void' }}
7879

7980
- run: vp check
8081
if: ${{ matrix.shard == 'unit' }}

‎.github/workflows/platform-ci.yml‎

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ permissions: {}
2323
jobs:
2424
build-api-container:
2525
if: github.event_name == 'pull_request'
26-
runs-on: blacksmith-4vcpu-ubuntu-2404
26+
runs-on: ${{ github.repository == 'voidzero-dev/void' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
2727
timeout-minutes: 10
2828
permissions:
2929
contents: read
@@ -35,7 +35,7 @@ jobs:
3535
run: docker build --pull --tag void-api-build-container:ci platform/packages/api/container
3636

3737
lint-build-check:
38-
runs-on: blacksmith-4vcpu-ubuntu-2404
38+
runs-on: ${{ github.repository == 'voidzero-dev/void' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
3939
permissions:
4040
contents: read
4141
steps:
@@ -61,7 +61,7 @@ jobs:
6161
- run: vp run check:sdk
6262

6363
test:
64-
runs-on: blacksmith-4vcpu-ubuntu-2404
64+
runs-on: ${{ github.repository == 'voidzero-dev/void' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
6565
permissions:
6666
contents: read
6767
strategy:
@@ -82,23 +82,27 @@ jobs:
8282

8383
# The production guard. `platform-deploy.yml` migrates before it deploys the api worker, so a
8484
# push to `prod` applies a new schema while the previous release is still serving traffic. This
85-
# migrates a real Postgres with the migrations under test, then runs the `prod` branch's
85+
# migrates a real Postgres with the migrations under test, then runs the selected released ref's
8686
# integration tests against that schema: if the code that is live cannot run on the new schema,
87-
# the push must not ship. Accepted limits: the baseline is the `prod` branch head rather than the
88-
# deployed revision, and released migrations are assumed append-only (drizzle never re-applies an
89-
# applied entry and skips entries not newer than the last applied).
87+
# the push must not ship. Void Cloud defaults to `prod`; forks opt in by setting the repository
88+
# variable VOID_PLATFORM_PRODUCTION_REF to their released branch, tag, or commit. The selected
89+
# ref must represent the deployed version, and released migrations are assumed append-only
90+
# (drizzle never re-applies an entry and skips entries not newer than the last applied).
9091
#
9192
# It has teeth on PRs, where the code under test is a different commit from the one that is
92-
# live. The production deploy sets `require-schema-compat` for every trigger — including a
93-
# manual dispatch, which can be started from any ref and would otherwise skip the job. Staging
94-
# deploys skip it: they cannot break production, and they run on nearly every push to `main`.
93+
# live. The production deploy explicitly requests `require-schema-compat`, including on
94+
# manual dispatch. Fork reusable-workflow callers can request it with their own baseline.
95+
# Staging deploys run source checks without the production compatibility comparison.
9596
schema-compat:
96-
if: github.event_name == 'pull_request' || inputs.require-schema-compat
97-
runs-on: blacksmith-4vcpu-ubuntu-2404
97+
if: >-
98+
${{ inputs.require-schema-compat || (github.event_name == 'pull_request'
99+
&& (github.repository == 'voidzero-dev/void' || vars.VOID_PLATFORM_PRODUCTION_REF != '')) }}
100+
runs-on: ${{ github.repository == 'voidzero-dev/void' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
98101
timeout-minutes: 20
99102
permissions:
100103
contents: read
101104
env:
105+
PRODUCTION_REF: ${{ vars.VOID_PLATFORM_PRODUCTION_REF || 'prod' }}
102106
POSTGRES_USER: void_ci
103107
POSTGRES_PASSWORD: void_ci_pass
104108
POSTGRES_DB: void_schema_compat
@@ -121,6 +125,11 @@ jobs:
121125
--health-timeout=5s
122126
--health-retries=5
123127
steps:
128+
- name: Require a production baseline for fork deployment checks
129+
if: ${{ github.repository != 'voidzero-dev/void' && vars.VOID_PLATFORM_PRODUCTION_REF == '' }}
130+
run: |
131+
echo '::error::Set the repository variable VOID_PLATFORM_PRODUCTION_REF to the released platform ref before requesting schema compatibility checks.'
132+
exit 1
124133
# Phase 1 — apply the migrations under test to a real Postgres.
125134
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
126135
with:
@@ -134,32 +143,23 @@ jobs:
134143
env:
135144
DATABASE_URL: ${{ env.COMPAT_DATABASE_URL }}
136145

137-
# Phase 2 — the release that is live must still run on that schema. `prod` is that release.
138-
# PRs are checked against it; a push to `prod` checks itself, as in the old repository; a
139-
# manual dispatch from another ref is checked against `prod`.
146+
# Phase 2 — the selected released ref must still run on the migrated schema.
147+
# Forks opt in with VOID_PLATFORM_PRODUCTION_REF; Void Cloud defaults to prod.
140148
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
141149
with:
142-
ref: prod
150+
ref: ${{ env.PRODUCTION_REF }}
143151
persist-credentials: false
144-
- name: Does the baseline carry the platform?
145-
id: production
152+
- name: Require platform code in the baseline
146153
run: |
147-
if [ -d platform/packages/api ]; then
148-
echo 'usable=true' >> "$GITHUB_OUTPUT"
149-
else
150-
# Production still runs a pre-monorepo revision, so there is no platform code to test
151-
# against: the schema is checked, the code is not. That gap closes with the first
152-
# release from this repository, after which this branch stops being taken.
153-
echo 'usable=false' >> "$GITHUB_OUTPUT"
154-
echo '::warning::The compatibility baseline predates the platform, so the production code was not exercised against the migrated schema. This stops once prod carries the platform.'
154+
if [ ! -d platform/packages/api ]; then
155+
echo '::error::The selected production baseline does not contain the platform. Choose a released platform ref with VOID_PLATFORM_PRODUCTION_REF.'
156+
exit 1
155157
fi
156-
- if: steps.production.outputs.usable == 'true'
157-
uses: voidzero-dev/setup-vp@1b32467adbe183473499fd9d5d372c3ed9641754 # v1.18.0
158+
- uses: voidzero-dev/setup-vp@1b32467adbe183473499fd9d5d372c3ed9641754 # v1.18.0
158159
with:
159160
cache: true
160161
node-version-file: .node-version
161162
- name: Run the production ref's integration tests on the migrated schema
162-
if: steps.production.outputs.usable == 'true'
163163
run: |
164164
vp run build
165165
vp run --filter './platform/packages/**' build

‎.github/workflows/platform-deploy-staging.yml‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,23 @@ concurrency:
2424
permissions: {}
2525

2626
jobs:
27+
check-ref:
28+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
29+
runs-on: ubuntu-latest
30+
steps:
31+
# Actions string comparisons ignore case. Check before entering Staging.
32+
- name: Verify the exact staging branch
33+
run: test "$GITHUB_REF" = 'refs/heads/main'
34+
2735
ci:
28-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
36+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
37+
needs: check-ref
2938
uses: ./.github/workflows/platform-ci.yml
3039
permissions:
3140
contents: read
3241

3342
deploy:
34-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
43+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
3544
needs: ci
3645
runs-on: blacksmith-4vcpu-ubuntu-2404
3746
environment: Staging
@@ -55,11 +64,13 @@ jobs:
5564
STAGING_DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
5665

5766
smoke-test:
58-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
67+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
5968
needs: deploy
6069
uses: ./.github/workflows/platform-smoke-test.yml
6170
permissions:
6271
contents: read
72+
# Pass only the smoke-test credentials. The called job resolves their values
73+
# from Staging; omitting this mapping leaves them empty on reusable runs.
6374
secrets:
6475
CF_ACCESS_CLIENT_ID_STAGING: ${{ secrets.CF_ACCESS_CLIENT_ID_STAGING }}
6576
CF_ACCESS_CLIENT_SECRET_STAGING: ${{ secrets.CF_ACCESS_CLIENT_SECRET_STAGING }}

‎.github/workflows/platform-deploy.yml‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,27 @@ concurrency:
1616
permissions: {}
1717

1818
jobs:
19+
check-ref:
20+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/prod' }}
21+
runs-on: ubuntu-latest
22+
steps:
23+
# Actions string comparisons ignore case. Check before entering Prod.
24+
- name: Verify the exact production branch
25+
run: test "$GITHUB_REF" = 'refs/heads/prod'
26+
1927
ci:
20-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
28+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/prod' }}
29+
needs: check-ref
2130
uses: ./.github/workflows/platform-ci.yml
2231
with:
23-
# Every production trigger runs the schema-compatibility guard, whichever ref the
24-
# dispatch came from.
32+
# Automatic and manual production runs use the prod ref and must pass
33+
# the schema-compatibility guard.
2534
require-schema-compat: true
2635
permissions:
2736
contents: read
2837

2938
deploy:
30-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
39+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/prod' }}
3140
needs: ci
3241
runs-on: blacksmith-4vcpu-ubuntu-2404
3342
environment: Prod

‎.github/workflows/platform-smoke-test.yml‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,37 @@ on:
1616
permissions: {}
1717

1818
jobs:
19+
check-ref:
20+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
21+
runs-on: ubuntu-latest
22+
steps:
23+
# Reusable runs use the caller's ref. Reject case variants before secrets.
24+
- name: Verify the exact smoke-test branch
25+
run: test "$GITHUB_REF" = 'refs/heads/main'
26+
1927
smoke-test:
20-
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' }}
28+
if: ${{ vars.VOID_PLATFORM_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' }}
29+
needs: check-ref
2130
runs-on: blacksmith-4vcpu-ubuntu-2404
31+
# Configure all three credentials in Staging. Reusable callers must declare
32+
# these secret names explicitly for GitHub to resolve the environment values.
2233
environment: Staging
2334
timeout-minutes: 15
2435
permissions:
2536
contents: read
2637
steps:
38+
- name: Verify staging smoke-test credentials
39+
env:
40+
CF_ACCESS_CLIENT_ID_STAGING: ${{ secrets.CF_ACCESS_CLIENT_ID_STAGING }}
41+
CF_ACCESS_CLIENT_SECRET_STAGING: ${{ secrets.CF_ACCESS_CLIENT_SECRET_STAGING }}
42+
VOID_TOKEN_STAGING: ${{ secrets.VOID_TOKEN_STAGING }}
43+
run: |
44+
for name in CF_ACCESS_CLIENT_ID_STAGING CF_ACCESS_CLIENT_SECRET_STAGING VOID_TOKEN_STAGING; do
45+
if [[ -z "${!name}" ]]; then
46+
echo "::error::Missing $name. Configure it in the Staging environment."
47+
exit 1
48+
fi
49+
done
2750
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2851
with:
2952
persist-credentials: false

‎.npmrc‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎AGENTS.md‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The `void` package on npm has these previous versions: '0.0.1', '0.1.0', '0.1.2'
2424
- Run `vp test run` on tests relevant to the current feature only during feature development. Only run the full test suite when everything is done for final verification.
2525
- If there are tests hanging or running particularly slow, investigate right there and attempt to fix. Testing velocity is something that should be maintained or improved at every opportunity.
2626
- Documentation: after verification, update all docs if relevant and applicable:
27-
- `README.md` (this file)
27+
- `README.md`
2828
- affected packages's `README.md` or `AGENTS.md`
2929
- relevant docs md files in `docs`
3030
- `packages/void/skills/void` (if change affects skill/CLI guidance)
@@ -40,7 +40,7 @@ The `void` package on npm has these previous versions: '0.0.1', '0.1.0', '0.1.2'
4040
```
4141
vp run build # Build all packages
4242
vp run build:all # Build packages and playgrounds
43-
vp run build:core # Build only the core plugin
43+
vp run build:core # Build shared packages, CLI, and platform runtime
4444
vp test run # Run tests (unit + integration tests)
4545
vpr test:all # Format, lint, build, typecheck, and run all SDK/platform tests
4646
vp test run packages/void # Only test the core plugin
@@ -60,15 +60,18 @@ pnpm workspaces managed through Vite+. Shared dependency versions use the **pnpm
6060
| [`packages/deploy-cloudflare`](./packages/deploy-cloudflare) | `@void/deploy-cloudflare` | Direct Cloudflare config and verified upload primitives |
6161
| [`packages/edge`](./packages/edge) | `@void/edge` | Shared routing, headers, and static edge runtime |
6262
| [`packages/isr`](./packages/isr) | `@void/isr` | Shared ISR protocol, core logic, and direct runtime |
63+
| [`packages/platform`](./packages/platform/README.md) | `@void/platform` | Self-hosted installation contracts and packaged platform runtime |
6364
| [`packages/void`](./packages/void/AGENTS.md) | `void` | Core Vite plugin — routing, inference, migrations, CLI |
6465
| [`packages/react`](./packages/react/README.md) | `@void/react` | React framework adapter for Pages mode (SSR, Link, useForm) |
6566
| [`packages/vue`](./packages/vue/README.md) | `@void/vue` | Vue framework adapter for Pages mode (SSR, Link, useForm) |
6667
| [`packages/svelte`](./packages/svelte/README.md) | `@void/svelte` | Svelte 5 framework adapter for Pages mode (SSR, Link, useForm) |
6768
| [`packages/solid`](./packages/solid/README.md) | `@void/solid` | SolidJS framework adapter for Pages mode (SSR, Link, useForm) |
6869
| [`docs`](./docs) | (private) | Documentation site (VitePress) |
69-
| [`platform`](./platform/README.md) | (private) | Hosted control plane, routing, proxy, logs, and dashboard |
70+
| [`platform`](./platform/README.md) | (private) | Self-hosted platform source, routing, proxy, logs, and dashboard |
7071
| `playground/*` | (private) | local apps for testing |
7172

73+
The platform source is part of this repository. Its workspace-only packages keep `private: true` to prevent accidental npm publication; this does not mean the platform source is private. Use `docs/guide/platform-development.md` for contributor/fork setup and `docs/guide/self-hosted-platform.md` for installation.
74+
7275
Platform packages live under `platform/packages/*` and may depend on public/shared root packages. Public SDK packages under `packages/*` must not import from `platform/`.
7376

7477
## `void` Overview
@@ -92,14 +95,15 @@ The `void` package contains two parts:
9295

9396
**CLI (`void`)** — commands for local development DX and deployment:
9497

95-
- **`deploy`** — builds, validates migrations, packages, and uploads to Void
98+
- **`deploy`** — builds, validates migrations, and deploys to the configured Cloudflare or Void target
99+
- **`platform`** — installs, maintains, and administers a self-hosted Void platform
96100
- **`gen`** — scaffolds models, routes, middleware, SSR entries, cron jobs, and queue consumers
97101
- **`init`** — sets up agent instructions, skills, and reference prompts for coding agents
98102
- **`db`** — manages migrations and inspects the local D1 database
99103
- **`auth`** — login, logout, and token management
100-
- **`projects`** — link, create, and manage Void projects
101-
- **`domains`** — configure custom domains for deployed projects
102-
- **`secrets`** — manage production environment variables
104+
- **`project`** — link, create, and manage Void projects
105+
- **`domain`** — configure custom domains for deployed projects
106+
- **`secret`** — manage production environment variables
103107

104108
See [`packages/void/AGENTS.md`](./packages/void/AGENTS.md) for architecture, source layout, design decisions, package exports, route parsing rules, code generation, and agent integration.
105109

‎README.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ If you run a team platform, `void platform` also lets you give people access,
88
manage their projects, and investigate deployments from the terminal. Start with
99
[Platform Administration](./docs/guide/platform-administration.md).
1010

11+
The platform implementation is included in this repository. To change it or
12+
deploy a runtime from your own fork, follow
13+
[Platform Development](./docs/guide/platform-development.md).
14+
1115
```ts
1216
// vite.config.ts
1317
import { defineConfig } from 'vite';
@@ -40,6 +44,8 @@ pnpm void deploy # deploy to the saved Cloudflare or Void target
4044

4145
## Adding Void to an Existing Project
4246

47+
Already deploy the same Void app directly to Cloudflare? Run `void deploy`. If your project has a `wrangler.jsonc` or `wrangler.json` and no deployment destination, Void offers to link and deploy using the existing Worker and resources. Accept once, then use `void deploy` for future deployments. See [Deploy an existing Worker](./docs/integrations/cloudflare.md#deploy-an-existing-worker).
48+
4349
1. Install Void:
4450

4551
```sh

‎docs/.vitepress/config.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export default extendConfig(
240240
{ text: 'Deployment', link: '/guide/deployment' },
241241
{ text: 'Self-hosted Platform', link: '/guide/self-hosted-platform' },
242242
{ text: 'Platform Administration', link: '/guide/platform-administration' },
243+
{ text: 'Platform Development', link: '/guide/platform-development' },
243244
],
244245
},
245246
],

0 commit comments

Comments
 (0)