registry
v0.0.1Package registry service for Riot
riot add registry registry = "0.0.1" - Last release
- Apr 2, 2026
- License
- Apache-2.0
- Dependencies
- 1
- Dependents
- 0
- Installs
- 0
- Published versions
- 1
- Owner
-
@leostera
README Expand Collapse
riot-package-registry
Cloudflare Worker scaffold for Riot's package publication service.
Production endpoint: https://api.pkgs.ml
Local development
- Install dependencies with
bun install. - Create a
.envfile next towrangler.toml. - Run
bun run dev.
Apply Wrangler D1 migrations before first run:
bun run migrate
For production databases:
bun run migrate:remote
Backups and rollback
The control-plane database is Cloudflare D1 (riot-registry).
Database-first rollback
-
D1 Time Travel is enabled and should be the primary point-in-time recovery path:
wrangler d1 time-travel info riot-registry wrangler d1 time-travel restore riot-registry --timestamp 2026-03-30T10:20:00Z
Exported backups (Cloudflare Workflows)
services/registry includes a D1BackupWorkflow that exports D1 to R2 using
Cloudflare’s D1 REST export API and stores *.sql snapshots in
ML_PKGS_BACKUPS (Cloudflare R2 bucket ml-pkgs-backups) at:
{prefix}/{accountId}/{databaseId}/{YYYY-MM-DD}/{timestamp}-*.sql.
- The workflow is scheduled by cron in
wrangler.toml(default daily at midnight UTC). - Enable it with
D1_BACKUP_ENABLED=true. - Configure:
D1_BACKUP_ACCOUNT_ID=<cloudflare-account-id>
D1_BACKUP_DATABASE_ID=3a482dd8-a28f-4f87-a143-46153d492819
D1_BACKUP_BUCKET_PREFIX=registry-database-backups
D1_REST_API_TOKEN=<cloudflare-api-token>
The token only needs Cloudflare D1:Read / export-capable permissions for the
target account/database.
Wrangler reads .env during local development, and the Worker expects at least:
CDN_BASE_URL=https://cdn.pkgs.ml
INDEX_BASE_PATH=index/v1
GITHUB_TOKEN=
ROOT_AUTH_TOKEN=
GITHUB_OAUTH_CLIENT_ID=
GITHUB_OAUTH_CLIENT_SECRET=
AUTH_COOKIE_DOMAIN=pkgs.ml
PKGS_WEB_BASE_URL=https://pkgs.ml
If GITHUB_TOKEN can read private repositories, the registry can publish from
those upstreams. This is useful for on-premise or private testing setups.
Current surface
GET /returns service metadata.GET /v1/packages/<locator>/resolve?ref=<selector>materializes or reuses a source-backed package snapshot.GET /v1/packages/<locator>/manifest/<sha>.jsonreads immutable manifests from R2.GET /v1/packages/<locator>/source/<sha>.tar.gzredirects to immutable source archives oncdn.pkgs.ml.GET /v1/auth/github/start?return_to=<url>starts GitHub OAuth login.GET /v1/auth/github/callback?code=<code>&state=<state>completes GitHub OAuth, creates a user session, and redirects back topkgs.ml.POST /v1/auth/logoutclears the session cookie.GET /v1/mereturns the authenticated user session, if one exists.GET /v1/search?q=<query>returns one search result per indexed package, backed by D1 + FTS5.GET /v1/me/tokenslists publish tokens for the authenticated user.POST /v1/me/tokenscreates a new publish token and returns the plaintext token once.DELETE /v1/me/tokens/<token-id>revokes a publish token.POST /v1/packages/<locator>/publish?ref=<selector>publishes a named package release, synchronously updates the sparse package index undercdn.pkgs.ml/index/v1, updates the registry search database, and accepts eitherAuthorization: Bearer <ROOT_AUTH_TOKEN>or a user publish token created through/v1/me/tokens.
Legacy compatibility aliases under registry.pkgs.ml and /api/v1//package/.../-/... remain available during the transition.
The Worker stores request logs and registry control-plane metadata in D1:
auth, sessions, API tokens, package claims, published releases, request logs,
search, and derived web views. Runtime D1 access is implemented with
drizzle-orm, while schema changes are managed only through Wrangler D1 SQL
migrations in services/registry/migrations/.
Live smoke tests
Set a live registry base URL in .env to run end-to-end smoke tests against a
deployed Worker:
REGISTRY_E2E_BASE_URL=https://api.pkgs.ml
REGISTRY_E2E_PACKAGE_LOCATOR=github.com/leostera/riot-new/packages/kernel
REGISTRY_E2E_ROOT_AUTH_TOKEN=
REGISTRY_E2E_PUBLISH_PACKAGE_LOCATOR=github.com/owner/repo/path/to/public-package
REGISTRY_E2E_SESSION_COOKIE=pkgs_session=...
REGISTRY_E2E_GITHUB_LOGIN=leostera
REGISTRY_INDEX_E2E_CDN_BASE_URL=https://cdn.pkgs.ml
REGISTRY_INDEX_E2E_BASE_PATH=index/v1
Then run:
bun run test:e2e
The live tests are skipped when REGISTRY_E2E_BASE_URL is not set.
The live publish smoke test is skipped unless REGISTRY_E2E_ROOT_AUTH_TOKEN is
set. If REGISTRY_E2E_PUBLISH_PACKAGE_LOCATOR is omitted, it defaults to
REGISTRY_E2E_PACKAGE_LOCATOR. The authenticated token-management smoke tests
are skipped unless both REGISTRY_E2E_SESSION_COOKIE and
REGISTRY_E2E_GITHUB_LOGIN are set.
bun run test only runs the local unit suite. The live registry smoke tests are
kept behind bun run test:e2e.
riot-package-registry
Cloudflare Worker scaffold for Riot's package publication service.
Production endpoint: https://api.pkgs.ml
Local development
- Install dependencies with
bun install. - Create a
.envfile next towrangler.toml. - Run
bun run dev.
Apply Wrangler D1 migrations before first run:
bun run migrate
For production databases:
bun run migrate:remote
Backups and rollback
The control-plane database is Cloudflare D1 (riot-registry).
Database-first rollback
-
D1 Time Travel is enabled and should be the primary point-in-time recovery path:
wrangler d1 time-travel info riot-registry wrangler d1 time-travel restore riot-registry --timestamp 2026-03-30T10:20:00Z
Exported backups (Cloudflare Workflows)
services/registry includes a D1BackupWorkflow that exports D1 to R2 using
Cloudflare’s D1 REST export API and stores *.sql snapshots in
ML_PKGS_BACKUPS (Cloudflare R2 bucket ml-pkgs-backups) at:
{prefix}/{accountId}/{databaseId}/{YYYY-MM-DD}/{timestamp}-*.sql.
- The workflow is scheduled by cron in
wrangler.toml(default daily at midnight UTC). - Enable it with
D1_BACKUP_ENABLED=true. - Configure:
D1_BACKUP_ACCOUNT_ID=<cloudflare-account-id>
D1_BACKUP_DATABASE_ID=3a482dd8-a28f-4f87-a143-46153d492819
D1_BACKUP_BUCKET_PREFIX=registry-database-backups
D1_REST_API_TOKEN=<cloudflare-api-token>
The token only needs Cloudflare D1:Read / export-capable permissions for the
target account/database.
Wrangler reads .env during local development, and the Worker expects at least:
CDN_BASE_URL=https://cdn.pkgs.ml
INDEX_BASE_PATH=index/v1
GITHUB_TOKEN=
ROOT_AUTH_TOKEN=
GITHUB_OAUTH_CLIENT_ID=
GITHUB_OAUTH_CLIENT_SECRET=
AUTH_COOKIE_DOMAIN=pkgs.ml
PKGS_WEB_BASE_URL=https://pkgs.ml
If GITHUB_TOKEN can read private repositories, the registry can publish from
those upstreams. This is useful for on-premise or private testing setups.
Current surface
GET /returns service metadata.GET /v1/packages/<locator>/resolve?ref=<selector>materializes or reuses a source-backed package snapshot.GET /v1/packages/<locator>/manifest/<sha>.jsonreads immutable manifests from R2.GET /v1/packages/<locator>/source/<sha>.tar.gzredirects to immutable source archives oncdn.pkgs.ml.GET /v1/auth/github/start?return_to=<url>starts GitHub OAuth login.GET /v1/auth/github/callback?code=<code>&state=<state>completes GitHub OAuth, creates a user session, and redirects back topkgs.ml.POST /v1/auth/logoutclears the session cookie.GET /v1/mereturns the authenticated user session, if one exists.GET /v1/search?q=<query>returns one search result per indexed package, backed by D1 + FTS5.GET /v1/me/tokenslists publish tokens for the authenticated user.POST /v1/me/tokenscreates a new publish token and returns the plaintext token once.DELETE /v1/me/tokens/<token-id>revokes a publish token.POST /v1/packages/<locator>/publish?ref=<selector>publishes a named package release, synchronously updates the sparse package index undercdn.pkgs.ml/index/v1, updates the registry search database, and accepts eitherAuthorization: Bearer <ROOT_AUTH_TOKEN>or a user publish token created through/v1/me/tokens.
Legacy compatibility aliases under registry.pkgs.ml and /api/v1//package/.../-/... remain available during the transition.
The Worker stores request logs and registry control-plane metadata in D1:
auth, sessions, API tokens, package claims, published releases, request logs,
search, and derived web views. Runtime D1 access is implemented with
drizzle-orm, while schema changes are managed only through Wrangler D1 SQL
migrations in services/registry/migrations/.
Live smoke tests
Set a live registry base URL in .env to run end-to-end smoke tests against a
deployed Worker:
REGISTRY_E2E_BASE_URL=https://api.pkgs.ml
REGISTRY_E2E_PACKAGE_LOCATOR=github.com/leostera/riot-new/packages/kernel
REGISTRY_E2E_ROOT_AUTH_TOKEN=
REGISTRY_E2E_PUBLISH_PACKAGE_LOCATOR=github.com/owner/repo/path/to/public-package
REGISTRY_E2E_SESSION_COOKIE=pkgs_session=...
REGISTRY_E2E_GITHUB_LOGIN=leostera
REGISTRY_INDEX_E2E_CDN_BASE_URL=https://cdn.pkgs.ml
REGISTRY_INDEX_E2E_BASE_PATH=index/v1
Then run:
bun run test:e2e
The live tests are skipped when REGISTRY_E2E_BASE_URL is not set.
The live publish smoke test is skipped unless REGISTRY_E2E_ROOT_AUTH_TOKEN is
set. If REGISTRY_E2E_PUBLISH_PACKAGE_LOCATOR is omitted, it defaults to
REGISTRY_E2E_PACKAGE_LOCATOR. The authenticated token-management smoke tests
are skipped unless both REGISTRY_E2E_SESSION_COOKIE and
REGISTRY_E2E_GITHUB_LOGIN are set.
bun run test only runs the local unit suite. The live registry smoke tests are
kept behind bun run test:e2e.