From 9060f99faa634ac1ace58663ad9c495e0f14e822 Mon Sep 17 00:00:00 2001 From: Sam Goodwin Date: Wed, 5 Aug 2026 14:37:51 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20alchemy=20deployment=20=E2=80=94=20the?= =?UTF-8?q?=20cloudflare-os=20package=20with=20the=20OperatingSystem=20res?= =?UTF-8?q?ource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .gitignore | 3 + README.md | 18 +- packages/alchemy/README.md | 231 ++ .../examples/0-quickstart/alchemy.run.ts | 55 + .../1-builtin-gatekeepers/alchemy.run.ts | 49 + .../2-custom-gatekeeper/alchemy.run.ts | 62 + .../examples/2-custom-gatekeeper/src/env.d.ts | 20 + .../2-custom-gatekeeper/src/worker.ts | 264 ++ packages/alchemy/examples/README.md | 22 + packages/alchemy/package.json | 69 + packages/alchemy/scripts/fix-text-modules.mjs | 44 + .../alchemy/scripts/prepare-worker-tree.mjs | 58 + packages/alchemy/src/Gatekeeper.ts | 148 + packages/alchemy/src/OperatingSystem.ts | 763 +++++ .../alchemy/src/gatekeepers/cloudflare.ts | 25 + .../alchemy/src/gatekeepers/confluence.ts | 26 + packages/alchemy/src/gatekeepers/context.ts | 36 + packages/alchemy/src/gatekeepers/github.ts | 26 + packages/alchemy/src/gatekeepers/google.ts | 26 + .../alchemy/src/gatekeepers/homeassistant.ts | 18 + packages/alchemy/src/gatekeepers/index.ts | 22 + packages/alchemy/src/gatekeepers/linear.ts | 26 + .../alchemy/src/gatekeepers/mcp-portal.ts | 58 + packages/alchemy/src/gatekeepers/mcp.ts | 31 + packages/alchemy/src/gatekeepers/notion.ts | 26 + packages/alchemy/src/gatekeepers/scheduler.ts | 26 + packages/alchemy/src/gatekeepers/slack.ts | 26 + packages/alchemy/src/gatekeepers/spotify.ts | 26 + packages/alchemy/src/gatekeepers/supabase.ts | 26 + packages/alchemy/src/gatekeepers/zoominfo.ts | 60 + packages/alchemy/src/index.ts | 23 + packages/alchemy/src/paths.ts | 57 + packages/alchemy/src/wrangler.ts | 71 + packages/alchemy/test/OperatingSystem.test.ts | 81 + packages/alchemy/tsconfig.json | 13 + packages/alchemy/vitest.config.ts | 13 + plans/alchemy-deploy.md | 458 +++ pnpm-lock.yaml | 2887 +++++++++++++++-- pnpm-workspace.yaml | 18 + 39 files changed, 5560 insertions(+), 351 deletions(-) create mode 100644 packages/alchemy/README.md create mode 100644 packages/alchemy/examples/0-quickstart/alchemy.run.ts create mode 100644 packages/alchemy/examples/1-builtin-gatekeepers/alchemy.run.ts create mode 100644 packages/alchemy/examples/2-custom-gatekeeper/alchemy.run.ts create mode 100644 packages/alchemy/examples/2-custom-gatekeeper/src/env.d.ts create mode 100644 packages/alchemy/examples/2-custom-gatekeeper/src/worker.ts create mode 100644 packages/alchemy/examples/README.md create mode 100644 packages/alchemy/package.json create mode 100644 packages/alchemy/scripts/fix-text-modules.mjs create mode 100644 packages/alchemy/scripts/prepare-worker-tree.mjs create mode 100644 packages/alchemy/src/Gatekeeper.ts create mode 100644 packages/alchemy/src/OperatingSystem.ts create mode 100644 packages/alchemy/src/gatekeepers/cloudflare.ts create mode 100644 packages/alchemy/src/gatekeepers/confluence.ts create mode 100644 packages/alchemy/src/gatekeepers/context.ts create mode 100644 packages/alchemy/src/gatekeepers/github.ts create mode 100644 packages/alchemy/src/gatekeepers/google.ts create mode 100644 packages/alchemy/src/gatekeepers/homeassistant.ts create mode 100644 packages/alchemy/src/gatekeepers/index.ts create mode 100644 packages/alchemy/src/gatekeepers/linear.ts create mode 100644 packages/alchemy/src/gatekeepers/mcp-portal.ts create mode 100644 packages/alchemy/src/gatekeepers/mcp.ts create mode 100644 packages/alchemy/src/gatekeepers/notion.ts create mode 100644 packages/alchemy/src/gatekeepers/scheduler.ts create mode 100644 packages/alchemy/src/gatekeepers/slack.ts create mode 100644 packages/alchemy/src/gatekeepers/spotify.ts create mode 100644 packages/alchemy/src/gatekeepers/supabase.ts create mode 100644 packages/alchemy/src/gatekeepers/zoominfo.ts create mode 100644 packages/alchemy/src/index.ts create mode 100644 packages/alchemy/src/paths.ts create mode 100644 packages/alchemy/src/wrangler.ts create mode 100644 packages/alchemy/test/OperatingSystem.test.ts create mode 100644 packages/alchemy/tsconfig.json create mode 100644 packages/alchemy/vitest.config.ts create mode 100644 plans/alchemy-deploy.md diff --git a/.gitignore b/.gitignore index cbedc770..b92bd33f 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ wrangler.dev.jsonc .dev.vars.* **/.dev.vars **/.dev.vars.* + +# alchemy deploy artifacts (bundles, logs, local state) +.alchemy/ diff --git a/README.md b/README.md index e0c2f295..10472771 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Then visit: http://localhost:8787 This runs the whole stack locally on wrangler and workerd. This is not meant for production use, but is a quick way to see what the product does. -Alternatively, you can [deploy to your Cloudflare account](https://github.com/cloudflare/cloudflare-os-starter). +Alternatively, you can deploy to your Cloudflare account with [alchemy](packages/alchemy/README.md) (recommended), or via the [starter repo](https://github.com/cloudflare/cloudflare-os-starter). (More options at the end of this readme.) @@ -173,13 +173,21 @@ This differs from most agent harnesses, where MCP servers are configured upfront ### Deploy to your Cloudflare account -We've built an online flow that helps you deploy to your own Cloudflare account: +The recommended way to deploy your own instance is the starter repo, which +pins an upstream release and deploys it with [alchemy](https://alchemy.run) — +one typed `OperatingSystem` resource provisions every worker, binding, +build, and storage resource: -https://os.cloudflare.app +https://github.com/cloudflare/cloudflare-os-starter -Or, for more sophisticated deployment, with your gatekeepers and potentially code changes, check out our deployment starter repo: +The resource itself lives in this repo as the +[`cloudflare-os` package](packages/alchemy/README.md), with +[runnable examples](packages/alchemy/examples/README.md) (a zero-config +quickstart, configuring built-in gatekeepers, writing a custom gatekeeper). -https://github.com/cloudflare/cloudflare-os-starter +Alternatively, we've built an online flow that helps you deploy to your own Cloudflare account: + +https://os.cloudflare.app ### Run locally diff --git a/packages/alchemy/README.md b/packages/alchemy/README.md new file mode 100644 index 00000000..318f2e41 --- /dev/null +++ b/packages/alchemy/README.md @@ -0,0 +1,231 @@ +# cloudflare-os + +Deploy [Cloudflare OS](https://github.com/cloudflare/cloudflare-os) to your +own Cloudflare account with [alchemy](https://alchemy.run) — one +`OperatingSystem` resource provisions and wires the whole system: + +- the **router** (the public origin: static frontend assets, SPA fallback, + custom domain) and the **workshop backend** (the kernel: browser + rendering, dynamic Worker loader, Workers AI, Durable Objects), +- one Worker per enabled **gatekeeper**, with `GATEKEEPER_*` service + bindings both runtimes discover, +- the KV namespaces and R2 bucket, every build step (vite, capnweb-validate, + configurator UIs), and — in gateway mode — an **AI Gateway** with a + least-privilege access token and Secrets-Store-backed provider keys. + +`alchemy destroy` tears all of it down again. + +## Quick start + +```typescript +// alchemy.run.ts +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Config from "effect/Config"; +import * as Effect from "effect/Effect"; +import { OperatingSystem } from "cloudflare-os"; +import { GitHub } from "cloudflare-os/gatekeepers"; + +export default Alchemy.Stack( + "AcmeOS", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + const os = yield* OperatingSystem("OS", { + domain: "os.acme.com", // omit → the router's workers.dev URL + admins: ["sam"], + auth: { gatekeepers: ["github"], disablePasswordAuth: true }, + gatekeepers: [ + GitHub({ + clientId: Config.string("GITHUB_CLIENT_ID"), + clientSecret: Config.redacted("GITHUB_CLIENT_SECRET"), + }), + ], + ai: { + providers: { anthropic: Config.redacted("ANTHROPIC_API_KEY") }, + }, + }); + + return { url: os.url }; + }), +); +``` + +```sh +pnpm exec alchemy deploy +``` + +Every prop is optional: `OperatingSystem("OS")` alone deploys a fully +working OS (password auth, BYOK model keys, the default gatekeepers) at the +router's `workers.dev` URL. To deploy **your own instance**, start from the +[starter repo](https://github.com/cloudflare/cloudflare-os-starter) — its +`alchemy.run.ts` is a complete customized deployment. The +[examples here](./examples/README.md) are for working on this repo: the +[quickstart](./examples/0-quickstart/alchemy.run.ts) deploys straight from a +checkout (`pnpm --dir packages/alchemy run deploy`). + +## Gatekeepers + +Each gatekeeper deploys as **its own Worker**. Built-ins are configured with +the plugin functions in [`cloudflare-os/gatekeepers`](./src/gatekeepers) — +their entry module, compatibility flags, Durable Object migrations, KV +bindings, and vars all **derive from the package's `wrangler.jsonc` at +deploy time**, so a manifest names only what wrangler doesn't know: + +```typescript +import { Context, GitHub, HomeAssistant, Mcp } from "cloudflare-os/gatekeepers"; + +gatekeepers: [ + GitHub({ clientId, clientSecret }), // credentialed: configuring = installing + Context({ sharingDomain: "production" }), // reconfigure a default by name + Mcp({ enabled: false }), // opt out of a default + HomeAssistant(), // opt in to a config-free non-default +] +``` + +`context`, `scheduler`, and `mcp` deploy by default, even when the +`gatekeepers` prop is omitted. + +### Custom gatekeepers + +A custom gatekeeper is a Worker implementing the **gatekeeper contract** +from `@gadgets/workshop-shared/gatekeeper` — capability-passing RPC, not +HTTP. One Worker module, several exports (workerd requires every named +export of an entry module to be a class): + +| export | consumed by | role | +| --- | --- | --- | +| `GatekeeperVendor` | the backend's `GATEKEEPER_` binding at `entrypoint: "GatekeeperVendor"` | the vendor API — the only externally-bound entrypoint | +| account / verifier / resource classes | `ctx.exports` loopback | capabilities the vendor mints and hands back as RPC stubs | +| `default` (`fetch`) | the router at `/gatekeeper//*` | browser plumbing only: OAuth landings, configurator iframes, logos | + +The chain: the backend calls `GatekeeperVendor` → `connectAccount()` / +`createAccount()` yields a `GatekeeperUser` (an account capability) → +`getGatekeeperClassFor(url)` yields a Durable Object class per bound +resource → its `startSession()` returns the session object — the +capability gadgets and agents actually call, typed by the vendor's own +`getTypeScriptTypes()`. + +```typescript +// src/worker.ts — the vendor entrypoint (abridged; the account, verifier, +// and resource-DO classes complete the contract — see the example) +import { WorkerEntrypoint } from "cloudflare:workers"; +import type { GatekeeperUser, SupportedResource, VendorDescription } + from "@gadgets/workshop-shared/gatekeeper"; +import type { AcmeEnv } from "../alchemy.run.ts"; + +export class GatekeeperVendor extends WorkerEntrypoint { + async describe(): Promise { + return { displayName: "Acme", url: "https://acme.example", + logo: AVATAR, tagline: "…", autoProvisionsAccount: true }; + } + async createAccount(): Promise> { + // mint an account capability from this module's own exports + return this.ctx.exports.AcmeAccount({ props: { label: "…" } }); + } + async getSupportedResources(): Promise { /* … */ } + async getTypeScriptTypes(): Promise { /* the session .d.ts */ } + // credentialed vendors implement connectAccount() (OAuth) instead of + // autoProvisionsAccount + createAccount() — see packages/gatekeeper-github +} +``` + +The stack declares the Worker with typed bindings (`InferEnv`) and its +resource DO class, then wires it in: + +```typescript +export const AcmeWorker = Cloudflare.Worker("AcmeWorker", { + main: "./src/worker.ts", + compatibility: { date: "2026-02-02", flags: ["enable_ctx_exports"] }, + env: { + CACHE: Cloudflare.KV.Namespace("Cache"), + ACME_API_TOKEN: Config.redacted("ACME_API_TOKEN"), + AcmeThing: Cloudflare.DurableObject("AcmeThing"), // drives its migration + }, +}); + +gatekeepers: [Gatekeeper({ name: "acme", worker: yield* AcmeWorker })] +``` + +[examples/2-custom-gatekeeper](./examples/2-custom-gatekeeper) is the +complete, typechecked version of this vendor. A gatekeeper that lives in +its own package following the standard capnweb layout (`wrangler.jsonc` + +`capnweb-validate`) can instead be wired with +`Gatekeeper({ name: "acme", package: "my-acme-gatekeeper" })` — the same +wrangler derivation as the built-ins. + +> An Effect-native gatekeeper (capability bindings, typed errors) is not +> offered yet: alchemy's Effect workers can't export the named entrypoint +> and capability classes above, and the vendor API's capability-passing +> semantics need a proper Effect bridge. Both are on the upstream list. + +## Sign-in & admins + +Three sign-in modes, chosen by `auth`: + +```typescript +// 1. Password accounts (default — no auth prop). Users self-register; +// `admins` are local usernames. +admins: ["admin"] + +// 2. OAuth gatekeeper sign-in: "Continue with GitHub/Google/…" for +// gatekeepers listed here (they must be deployed with credentials). +// Identities are OAuth-verified emails — `admins` too. +auth: { gatekeepers: ["github"], disablePasswordAuth: true }, +admins: ["sam@acme.com"] + +// 3. Cloudflare Access: identity is verified before requests reach the +// Worker. `admins` are the emails in the Access JWT. +auth: { access: { aud: "", iss: "https://.cloudflareaccess.com" } }, +admins: ["sam@acme.com"] +``` + +`admins` gates `/admin` (branding, connector policies) and is always +interpreted in the active sign-in system's identity namespace. + +> Note: `auth.access` *validates* an Access application — it does not +> create one. Create the self-hosted app for your hostname in Zero Trust +> and copy its audience tag. Provisioning the Access application and its +> admin policy from this stack (alchemy has the Access resources) is a +> natural follow-up. + +## AI Gateway: provisioned, not referenced + +The presence of the `ai` prop is the opt-in (omit it → BYOK mode, where +users bring their own model keys): + +```typescript +ai: { + gateway: { cacheTtl: 60 }, // Cloudflare.AI.GatewayProps, verbatim + providers: { // stored keys, provisioned on the gateway + anthropic: Config.redacted("ANTHROPIC_API_KEY"), + openai: Config.redacted("OPENAI_API_KEY"), + }, + workersAi: true, // or "direct" to skip gateway cost logs + limits: { dailyLlmCallLimit: 200 }, // per-user quotas (backend-enforced) +} +``` + +This provisions the gateway, a Run+Read `AccountApiToken` for the backend, +a Secrets Store, and one `AI.ProviderKey` per `providers` entry — nothing to +create in the dashboard, and the keys are never bound into any Worker. + +## Extending the deployment + +- `backend.env` — extra bindings/vars on the backend Worker. +- `backend.services` — extra service bindings with a named entrypoint and + workerd `ctx.props` (e.g. a private error-reporter Worker; see the + [starter repo](https://github.com/cloudflare/cloudflare-os-starter)). +- `frontend.env` — extra build-time env for the vite build. + +All outputs are real alchemy resources (`os.router`, `os.backend`, +`os.gatekeepers`, `os.blueprints`, …), so you can compose further — point a +DNS record at `os.url`, bind `os.backend` from your own Workers, add +alerting. + +## Status + +Early access, like the OS itself. The resource graph is verified against +alchemy's plan engine; see +[`plans/alchemy-deploy.md`](../../plans/alchemy-deploy.md) for the design, +current limitations (a `.svg` Text-module shim, service-binding `ctx.props` +pending an upstream schema fix), and the upstream punch list. diff --git a/packages/alchemy/examples/0-quickstart/alchemy.run.ts b/packages/alchemy/examples/0-quickstart/alchemy.run.ts new file mode 100644 index 00000000..7933e393 --- /dev/null +++ b/packages/alchemy/examples/0-quickstart/alchemy.run.ts @@ -0,0 +1,55 @@ +// Deploy this checkout of Cloudflare OS to your Cloudflare account: +// +// pnpm --dir packages/alchemy run deploy +// +// Configuration comes from the environment (a `.env` works too): +// - GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET (optional: GitHub gatekeeper + sign-in) +// - ANTHROPIC_API_KEY (optional: AI gateway stored key) +// - OS_DOMAIN (optional: custom domain on the router) +// +// With nothing configured this still deploys a fully working OS (password +// auth, BYOK model keys, the default-on gatekeepers) at the router's +// workers.dev URL. +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Config from "effect/Config"; +import * as Effect from "effect/Effect"; +import * as Option from "effect/Option"; +import { OperatingSystem, type GatekeeperDeployment } from "cloudflare-os"; +import { GitHub } from "cloudflare-os/gatekeepers"; + +export default Alchemy.Stack( + "CloudflareOS", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + const domain = Option.getOrUndefined( + yield* Config.option(Config.string("OS_DOMAIN")), + ); + const github = Option.getOrUndefined( + yield* Config.option(Config.string("GITHUB_CLIENT_ID")), + ); + const anthropic = Option.getOrUndefined( + yield* Config.option(Config.redacted("ANTHROPIC_API_KEY")), + ); + + const gatekeepers: GatekeeperDeployment[] = []; + if (github !== undefined) { + gatekeepers.push( + GitHub({ + clientId: github, + clientSecret: yield* Config.redacted("GITHUB_CLIENT_SECRET"), + }), + ); + } + + const os = yield* OperatingSystem("OS", { + domain, + admins: ["admin"], + auth: github !== undefined ? { gatekeepers: ["github"] } : undefined, + gatekeepers, + ai: anthropic !== undefined ? { providers: { anthropic } } : undefined, + }); + + return { url: os.url }; + }), +); diff --git a/packages/alchemy/examples/1-builtin-gatekeepers/alchemy.run.ts b/packages/alchemy/examples/1-builtin-gatekeepers/alchemy.run.ts new file mode 100644 index 00000000..aa76cbea --- /dev/null +++ b/packages/alchemy/examples/1-builtin-gatekeepers/alchemy.run.ts @@ -0,0 +1,49 @@ +// Configuring built-in gatekeepers. +// +// pnpm exec alchemy deploy ./examples/1-builtin-gatekeepers/alchemy.run.ts +// +// Requires GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET in the environment +// (create the OAuth app with callback /gatekeeper/github/oauth). +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Config from "effect/Config"; +import * as Effect from "effect/Effect"; +import { OperatingSystem } from "cloudflare-os"; +import { + Context, + GitHub, + HomeAssistant, + Mcp, +} from "cloudflare-os/gatekeepers"; + +export default Alchemy.Stack( + "BuiltinGatekeepersExample", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + const os = yield* OperatingSystem("OS", { + admins: ["admin"], + // Sign in with GitHub, and turn password accounts off. + auth: { gatekeepers: ["github"], disablePasswordAuth: true }, + gatekeepers: [ + // Credentialed gatekeepers install by being configured. The entry, + // compat flags, and Durable Objects all derive from the package's + // wrangler.jsonc at deploy time — this is the whole configuration. + GitHub({ + clientId: Config.string("GITHUB_CLIENT_ID"), + clientSecret: Config.redacted("GITHUB_CLIENT_SECRET"), + }), + + // `context`, `scheduler`, and `mcp` deploy by default. Reconfigure + // a default by listing it (same name replaces it)… + Context({ sharingDomain: "production" }), + // …or opt out entirely. + Mcp({ enabled: false }), + + // Config-free but non-default gatekeepers opt in by being listed. + HomeAssistant(), + ], + }); + + return { url: os.url }; + }), +); diff --git a/packages/alchemy/examples/2-custom-gatekeeper/alchemy.run.ts b/packages/alchemy/examples/2-custom-gatekeeper/alchemy.run.ts new file mode 100644 index 00000000..417853a6 --- /dev/null +++ b/packages/alchemy/examples/2-custom-gatekeeper/alchemy.run.ts @@ -0,0 +1,62 @@ +// A custom gatekeeper deployed as its own Worker and wired into the OS. +// The Worker (./src/worker.ts) implements the real gatekeeper contract — +// the `GatekeeperVendor` entrypoint plus the account/verifier/resource +// capability classes. +// +// pnpm exec alchemy deploy ./examples/2-custom-gatekeeper/alchemy.run.ts +// +// Requires ACME_API_TOKEN in the environment. +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Config from "effect/Config"; +import * as Effect from "effect/Effect"; +import { Gatekeeper, OperatingSystem } from "cloudflare-os"; + +/** Cache for upstream Acme API responses. */ +export const Cache = Cloudflare.KV.Namespace("Cache"); + +/** + * The gatekeeper Worker. Bindings are declared on `env` and `InferEnv` + * derives the runtime type, so the handlers can never drift from the + * infrastructure. `AcmeThing` is the per-resource Durable Object class the + * account mints via `ctx.exports` — declaring it here drives its SQLite + * migration. + */ +export const AcmeWorker = Cloudflare.Worker("AcmeWorker", { + main: "./src/worker.ts", + compatibility: { date: "2026-02-02", flags: ["enable_ctx_exports"] }, + env: { + CACHE: Cache, + ACME_API_TOKEN: Config.redacted("ACME_API_TOKEN"), + AcmeThing: Cloudflare.DurableObject("AcmeThing"), + }, +}); + +/** + * The Worker's typed env. `BASE_URL` is added by the OperatingSystem + * composite (every gatekeeper receives `/gatekeeper/`), so it + * is declared here rather than inferred. + */ +export type AcmeEnv = Cloudflare.InferEnv & { + BASE_URL: string; +}; + +export default Alchemy.Stack( + "CustomGatekeeperExample", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + const worker = yield* AcmeWorker; + + const os = yield* OperatingSystem("OS", { + admins: ["admin"], + gatekeepers: [ + // Wires the Worker into the OS: GATEKEEPER_ACME service bindings on + // the router (default entrypoint, HTTP) and the backend + // (`GatekeeperVendor` entrypoint, capability RPC), plus BASE_URL. + Gatekeeper({ name: "acme", worker }), + ], + }); + + return { url: os.url, gatekeeper: worker.url }; + }), +); diff --git a/packages/alchemy/examples/2-custom-gatekeeper/src/env.d.ts b/packages/alchemy/examples/2-custom-gatekeeper/src/env.d.ts new file mode 100644 index 00000000..494a89ae --- /dev/null +++ b/packages/alchemy/examples/2-custom-gatekeeper/src/env.d.ts @@ -0,0 +1,20 @@ +// Types `ctx.exports` for same-module loopback (accounts, verifiers, and +// the resource DO are minted as capabilities from this module's own +// exports). Must stay a global script — no top-level import/export — for +// the declaration merges to apply. Same shape as +// packages/integration-tests/fixtures/gatekeeper-test/src/env.d.ts. + +declare namespace Cloudflare { + interface GlobalProps { + mainModule: typeof import("./worker.js"); + durableNamespaces: "AcmeThing"; + } +} + +interface ExecutionContext { + readonly exports: Cloudflare.Exports; +} + +interface DurableObjectState { + readonly exports: Cloudflare.Exports; +} diff --git a/packages/alchemy/examples/2-custom-gatekeeper/src/worker.ts b/packages/alchemy/examples/2-custom-gatekeeper/src/worker.ts new file mode 100644 index 00000000..c790e522 --- /dev/null +++ b/packages/alchemy/examples/2-custom-gatekeeper/src/worker.ts @@ -0,0 +1,264 @@ +/// +// A minimal but REAL custom gatekeeper, modeled on +// `packages/integration-tests/fixtures/gatekeeper-test`. One Worker module, +// several exports — workerd requires every named export of an entry module +// to be a class, and this layout is the gatekeeper contract: +// +// - `GatekeeperVendor` the ONE entrypoint consumed externally: the +// workshop backend binds this Worker with +// `entrypoint: "GatekeeperVendor"` and speaks +// capability-passing RPC to it. +// - `AcmeAccount`, WorkerEntrypoint / DurableObject classes the +// `AcmeVerifier`, vendor mints and hands back as capabilities — +// `AcmeThing` reached via `ctx.exports` loopback, never bound. +// - `default` the HTTP surface the router forwards at +// /gatekeeper/acme/* (OAuth landings, configurator +// iframes, logos). This vendor needs none of that. +// +// The interfaces come from `@gadgets/workshop-shared/gatekeeper` — see that +// file for the full contract documentation, and `packages/gatekeeper-github` +// for a production OAuth implementation. +import { + DurableObject, + RpcTarget, + WorkerEntrypoint, + type RpcStub, +} from "cloudflare:workers"; +import type { + AccountDescription, + ActionKind, + ApprovalQueue, + Gatekeeper, + GatekeeperConnectCallback, + GatekeeperUser, + GatekeeperUserVerifier, + ResourceConfiguratorFrame, + ResourceDescription, + SupportedResource, + VendorDescription, +} from "@gadgets/workshop-shared/gatekeeper"; +import type { AcmeEnv } from "../alchemy.run.ts"; + +const VENDOR_HOST = "acme.example"; + +const SUPPORTED_RESOURCES: SupportedResource[] = [ + { + urlPattern: `https://${VENDOR_HOST}/things/*`, + title: "Acme Thing", + description: "A thing in Acme, addressable by URL.", + }, +]; + +// The session API surfaced to gadgets and the coding agent. The Workshop +// parses this to build the agent's type database. +const TYPES_CODE = ` +/** A session on one Acme thing. */ +interface AcmeThingSession { + /** Read the thing's current status from the Acme API. */ + getStatus(): Promise; +} +`; + +const AVATAR = { + url: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", +}; + +type AccountProps = { label: string }; +type ThingProps = AccountProps & { resourceUrl: string }; + +// --------------------------------------------------------------------------- +// The vendor entrypoint — what `GATEKEEPER_ACME` at `GatekeeperVendor` calls. + +export class GatekeeperVendor extends WorkerEntrypoint { + async describe(): Promise { + return { + displayName: "Acme", + url: `https://${VENDOR_HOST}`, + logo: AVATAR, + tagline: "Acme things, mediated by the approval queue.", + // Accounts are minted on demand — no OAuth. A credentialed vendor + // implements connectAccount() instead: return the URL of your OAuth + // flow, then invoke `callback.complete()` when it finishes (see + // packages/gatekeeper-github). + autoProvisionsAccount: true, + }; + } + + async createAccount(): Promise> { + const label = `acme-${crypto.randomUUID().slice(0, 8)}@${VENDOR_HOST}`; + return this.ctx.exports.AcmeAccount({ props: { label } }); + } + + async connectAccount( + _callback: Fetcher, + ): Promise<{ url: string }> { + throw new Error("Acme auto-provisions accounts; there is no connect flow."); + } + + async getSupportedResources(): Promise { + return SUPPORTED_RESOURCES; + } + + async getTypeScriptTypes(): Promise { + return TYPES_CODE; + } +} + +// --------------------------------------------------------------------------- +// One connected account. Handed back to the Workshop as a capability; it +// binds resources by URL and mints per-resource Gatekeeper classes. + +export class AcmeAccount + extends WorkerEntrypoint + implements GatekeeperUser +{ + async describe(): Promise { + return { + displayName: this.ctx.props.label.split("@")[0], + uniqueName: this.ctx.props.label, + avatar: AVATAR, + }; + } + + async getSupportedResources(): Promise { + return SUPPORTED_RESOURCES; + } + + // The owner pasted a URL; the returned DO class becomes a Gatekeeper + // facet under that gadget's Overseer. + async getGatekeeperClassFor(url: string): Promise<{ + class: DurableObjectClass>; + resource: SupportedResource; + }> { + const parsed = new URL(url); + if (parsed.host !== VENDOR_HOST || !parsed.pathname.startsWith("/things/")) { + throw new Error(`Not an Acme resource URL: ${url}`); + } + return { + class: this.ctx.exports.AcmeThing({ + props: { label: this.ctx.props.label, resourceUrl: url }, + }), + resource: SUPPORTED_RESOURCES[0], + }; + } + + async getVerifier(): Promise> { + return this.ctx.exports.AcmeVerifier({ props: this.ctx.props }); + } + + async ensureResources(_resourceUrlPatterns: string[]): Promise<{ url?: string }> { + return {}; + } + + async getAuthenticatedEmail(): Promise { + return null; + } + + async revoke(): Promise {} + + startResourceConfigurator( + _resourceUrlPattern: string, + ): Promise { + throw new Error("Acme has no resource configurator; bind a URL directly."); + } + + reconnect(): Promise<{ url: string }> { + throw new Error("Acme has no credentials to reconnect."); + } +} + +/** Identifies which account is asking (see GatekeeperUserVerifier's docs). */ +export interface AcmeVerifierApi extends GatekeeperUserVerifier { + identify(): Promise; +} + +export class AcmeVerifier + extends WorkerEntrypoint + implements AcmeVerifierApi +{ + async identify(): Promise { + return this.ctx.props.label; + } +} + +// --------------------------------------------------------------------------- +// One bound resource: a Durable Object running as a facet under the gadget's +// Overseer. Its session object is the capability gadgets actually call. + +/** Matches the `AcmeThingSession` interface in {@link TYPES_CODE}. */ +export class AcmeSession extends RpcTarget { + constructor( + private env: AcmeEnv, + private resourceUrl: string, + ) { + super(); + } + + async getStatus(): Promise { + const cached = await this.env.CACHE.get(`status:${this.resourceUrl}`); + if (cached !== null) return cached; + const response = await fetch(`https://api.${VENDOR_HOST}/status`, { + headers: { authorization: `Bearer ${this.env.ACME_API_TOKEN}` }, + }); + const status = await response.text(); + await this.env.CACHE.put(`status:${this.resourceUrl}`, status, { + expirationTtl: 60, + }); + return status; + } +} + +export class AcmeThing + extends DurableObject + implements Gatekeeper +{ + async describe(): Promise { + const name = new URL(this.ctx.props.resourceUrl).pathname.split("/").pop()!; + return { + url: this.ctx.props.resourceUrl, + title: `Acme Thing ${name}`, + snippet: `The Acme thing ${name}.`, + suggestedBindingName: "ACME_THING", + tsType: "AcmeThingSession", + }; + } + + async getTypeScriptTypes(): Promise { + return TYPES_CODE; + } + + async getAutoApprovableActions(): Promise { + return []; + } + + async startSession(_approvalQueue: RpcStub): Promise { + return new AcmeSession(this.env, this.ctx.props.resourceUrl); + } + + async addObserver(_id: string, _user: Fetcher): Promise { + // Every account may observe; a real vendor checks the verifier here and + // throws to refuse. + } + + async removeObserver(_id: string): Promise {} + + async applyAction(_action: number): Promise { + throw new Error("Acme submits no actions."); + } + + async rejectAction(_action: number): Promise {} + + async revertAction(_action: number): Promise { + throw new Error("Acme submits no actions."); + } +} + +// --------------------------------------------------------------------------- +// The HTTP surface the router forwards at /gatekeeper/acme/*. This vendor +// has no OAuth landing or configurator, so it only answers a health probe. + +export default { + async fetch(_request: Request, env: AcmeEnv): Promise { + return new Response(`Acme gatekeeper at ${env.BASE_URL}`); + }, +}; diff --git a/packages/alchemy/examples/README.md b/packages/alchemy/examples/README.md new file mode 100644 index 00000000..4668d30e --- /dev/null +++ b/packages/alchemy/examples/README.md @@ -0,0 +1,22 @@ +# Examples + +Three ways to configure and extend a Cloudflare OS deployment. Each example +is a self-contained stack — run one with: + +```sh +pnpm exec alchemy deploy ./examples//alchemy.run.ts +``` + +| example | shows | +| --- | --- | +| [0-quickstart](./0-quickstart/alchemy.run.ts) | Zero-config full OS deploy, configured entirely through environment variables (custom domain, GitHub sign-in, AI gateway key) — what `pnpm run deploy` runs | +| [1-builtin-gatekeepers](./1-builtin-gatekeepers/alchemy.run.ts) | Configuring built-in gatekeepers: OAuth credentials install one, defaults opt out, config-free ones opt in | +| [2-custom-gatekeeper](./2-custom-gatekeeper/alchemy.run.ts) | A complete minimal custom gatekeeper: the `GatekeeperVendor` entrypoint, account/verifier/resource capability classes, and a session — typechecked against `@gadgets/workshop-shared/gatekeeper` | + +A custom gatekeeper can also be a **package** following the standard capnweb +layout (`wrangler.jsonc` + `capnweb-validate` build) — then +`Gatekeeper({ name, package: "my-gatekeeper" })` derives everything from its +wrangler config, exactly like the built-ins. See any `packages/gatekeeper-*` +for the full gatekeeper RPC contract; example 2 implements the +contract end to end (with an auto-provisioning vendor; OAuth vendors +implement `connectAccount()` instead — see `packages/gatekeeper-github`). diff --git a/packages/alchemy/package.json b/packages/alchemy/package.json new file mode 100644 index 00000000..689e46db --- /dev/null +++ b/packages/alchemy/package.json @@ -0,0 +1,69 @@ +{ + "name": "cloudflare-os", + "version": "0.1.0", + "description": "Deploy Cloudflare OS to your own Cloudflare account with alchemy \u2014 one OperatingSystem resource provisions the router, backend, gatekeepers, storage, and AI gateway.", + "license": "MIT", + "type": "module", + "main": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./gatekeepers": "./src/gatekeepers/index.ts", + "./package.json": "./package.json" + }, + "repository": { + "type": "git", + "url": "https://github.com/cloudflare/cloudflare-os", + "directory": "packages/alchemy" + }, + "scripts": { + "types:check": "tsc --noEmit", + "clean": "rm -rf dist", + "test:e2e": "vitest run", + "deploy": "alchemy deploy ./examples/0-quickstart/alchemy.run.ts", + "destroy": "alchemy destroy ./examples/0-quickstart/alchemy.run.ts" + }, + "peerDependencies": { + "alchemy": ">=2.0.0-beta.67", + "effect": ">=4.0.0-beta.100 || >=4.0.0" + }, + "dependencies": { + "@gadgets/cloudflare-gatekeeper": "workspace:*", + "@gadgets/confluence-gatekeeper": "workspace:*", + "@gadgets/gatekeeper-context": "workspace:*", + "@gadgets/gatekeeper-scheduler": "workspace:*", + "@gadgets/github-gatekeeper": "workspace:*", + "@gadgets/google-gatekeeper": "workspace:*", + "@gadgets/homeassistant-gatekeeper": "workspace:*", + "@gadgets/linear-gatekeeper": "workspace:*", + "@gadgets/mcp-gatekeeper": "workspace:*", + "@gadgets/mcp-portal-gatekeeper": "workspace:*", + "@gadgets/notion-gatekeeper": "workspace:*", + "@gadgets/router": "workspace:*", + "@gadgets/slack-gatekeeper": "workspace:*", + "@gadgets/spotify-gatekeeper": "workspace:*", + "@gadgets/supabase-gatekeeper": "workspace:*", + "@gadgets/workshop-backend": "workspace:*", + "@gadgets/workshop-frontend": "workspace:*", + "@gadgets/zoominfo-gatekeeper": "workspace:*", + "esbuild": "^0.28.1", + "jsonc-parser": "^3.3.1" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20260702.1", + "@effect/vitest": "4.0.0-beta.103", + "@gadgets/workshop-shared": "workspace:*", + "@types/node": "26.1.0", + "alchemy": ">=2.0.0-beta.67", + "effect": "4.0.0-beta.103", + "typescript": "^5.9.3", + "vitest": "^4.1.10", + "@effect/platform-node": "4.0.0-beta.103", + "ws": "^8.20.0" + }, + "files": [ + "src", + "scripts", + "examples", + "README.md" + ] +} diff --git a/packages/alchemy/scripts/fix-text-modules.mjs b/packages/alchemy/scripts/fix-text-modules.mjs new file mode 100644 index 00000000..46a100fb --- /dev/null +++ b/packages/alchemy/scripts/fix-text-modules.mjs @@ -0,0 +1,44 @@ +// Rewrites `.svg` Text-module imports in a built worker tree to `.svg.txt`. +// +// The wrangler configs in this repo declare `.svg` files as Text modules +// (`rules: [{ type: "Text", globs: ["**/*.txt", "**/*.svg"] }]`). Alchemy's +// bundler currently hardcodes Text handling to `.txt`/`.html`/`.sql`, so an +// `.svg` import would fail to resolve. Until alchemy honors wrangler-style +// module rules (TODO upstream: alchemy-run/alchemy — configurable Text rules +// + `.svg` content type), this script copies each `x.svg` to `x.svg.txt` and +// rewrites import specifiers accordingly. Idempotent. +import { readdirSync, readFileSync, writeFileSync, copyFileSync, statSync } from "node:fs"; +import { join } from "node:path"; + +const root = process.argv[2]; +if (!root) { + console.error("usage: fix-text-modules.mjs "); + process.exit(1); +} + +const walk = (dir) => + readdirSync(dir).flatMap((name) => { + const file = join(dir, name); + return statSync(file).isDirectory() ? walk(file) : [file]; + }); + +let files; +try { + files = walk(root); +} catch { + process.exit(0); // nothing to fix +} + +for (const file of files) { + if (file.endsWith(".svg")) { + copyFileSync(file, `${file}.txt`); + } +} +for (const file of files) { + if (!/\.(ts|tsx|js|mjs)$/.test(file)) continue; + const source = readFileSync(file, "utf8"); + const fixed = source.replace(/(from\s+["'][^"']*\.svg)(["'])/g, "$1.txt$2"); + if (fixed !== source) { + writeFileSync(file, fixed); + } +} diff --git a/packages/alchemy/scripts/prepare-worker-tree.mjs b/packages/alchemy/scripts/prepare-worker-tree.mjs new file mode 100644 index 00000000..6866cfa4 --- /dev/null +++ b/packages/alchemy/scripts/prepare-worker-tree.mjs @@ -0,0 +1,58 @@ +// Prepares a capnweb-validate output tree for alchemy's rolldown bundler. +// Two fixes, both in place so every import path stays identical: +// +// 1. `.svg` Text modules → `.svg.txt`. The wrangler configs declare `.svg` +// as Text; alchemy's bundler hardcodes Text to `.txt/.html/.sql`. +// (TODO upstream: honor wrangler-style module rules.) +// 2. TC39 class decorators → lowered JS. capnweb-validate emits +// `@__validateRpcClass(...)` decorators; wrangler's esbuild lowers them +// but rolldown passes them through, and workerd's parser rejects +// decorator syntax (`ScriptStartupError: Invalid or unexpected token`). +// Each `.ts` file is esbuild-transformed (target es2022) in place. +// (TODO upstream: enable decorator lowering in alchemy's bundler.) +// +// Idempotent: already-lowered files contain no decorators and transform to +// themselves; `.svg.txt` copies are overwritten. +import { copyFileSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; +import { createRequire } from "node:module"; +import { join } from "node:path"; + +const require = createRequire(import.meta.url); +const esbuild = require("esbuild"); + +const root = process.argv[2]; +if (!root) { + console.error("usage: prepare-worker-tree.mjs "); + process.exit(1); +} + +const walk = (dir) => + readdirSync(dir).flatMap((name) => { + const file = join(dir, name); + return statSync(file).isDirectory() ? walk(file) : [file]; + }); + +let files; +try { + files = walk(root); +} catch { + process.exit(0); // nothing to prepare +} + +for (const file of files) { + if (file.endsWith(".svg")) { + copyFileSync(file, `${file}.txt`); + } +} + +for (const file of files) { + if (!/\.(ts|tsx)$/.test(file) || file.endsWith(".d.ts")) continue; + const source = readFileSync(file, "utf8"); + const fixed = source.replace(/(from\s+["'][^"']*\.svg)(["'])/g, "$1.txt$2"); + const { code } = await esbuild.transform(fixed, { + loader: file.endsWith(".tsx") ? "tsx" : "ts", + format: "esm", + target: "es2022", + }); + writeFileSync(file, code); +} diff --git a/packages/alchemy/src/Gatekeeper.ts b/packages/alchemy/src/Gatekeeper.ts new file mode 100644 index 00000000..e8a72df3 --- /dev/null +++ b/packages/alchemy/src/Gatekeeper.ts @@ -0,0 +1,148 @@ +import type * as Cloudflare from "alchemy/Cloudflare"; +import type * as Effect from "effect/Effect"; + +/** A deployed `Cloudflare.Worker` resource. */ +type Worker = Effect.Success>; + +/** + * A configuration value that may be a secret. Deploy tooling passes secrets + * through opaquely — the `object` arm admits wrapper types like effect's + * `Redacted`/`Config` or alchemy `Output` references. Plain strings listed + * in {@link PackagedGatekeeper.secrets} are encrypted at deploy time. + */ +export type SecretInput = string | object; + +/** + * An environment value on the gatekeeper Worker: a plain var, a JSON var, + * or an opaque wrapper (secret, config reference, output reference). + */ +export type EnvInput = string | number | boolean | readonly string[] | object; + +/** + * Substituted in {@link GatekeeperDeployment.vendorProps} values with the + * deployment's public origin (e.g. `https://os.acme.com`). + */ +export const PUBLIC_BASE_URL = "{PUBLIC_BASE_URL}"; + +/** Fields shared by every gatekeeper deployment variant. */ +export interface GatekeeperDeploymentBase { + /** + * The gatekeeper's short name, e.g. `"confluence"`. Determines the + * `GATEKEEPER_` service-binding name (uppercased, `-` → `_`) both + * runtimes discover by prefix scan, and the `/gatekeeper/` route on + * the router. + */ + name: string; + /** + * Properties for the backend's vendor service binding (workerd + * `ctx.props`). String values containing {@link PUBLIC_BASE_URL} have the + * placeholder substituted with the deployment's public origin. + */ + vendorProps?: Record; + /** + * Deploy this gatekeeper even when the OS configuration doesn't list it + * (the ambient core: context, scheduler, mcp). + */ + defaultEnabled?: boolean; + /** + * Set `false` to opt a {@link defaultEnabled} gatekeeper out of a + * deployment (e.g. `Mcp({ enabled: false })`). + */ + enabled?: boolean; +} + +/** + * A gatekeeper built from a package following the standard layout: a + * capnweb Worker whose sources are re-emitted by `capnweb-validate build`, + * with an optional package.json pre-build script. + * + * The package's own `wrangler.jsonc` is the source of truth for how the + * worker deploys — the entry module, compatibility date and flags, Durable + * Object migrations, KV bindings, and vars are all **derived from it at + * deploy time**, never copied here. A manifest only adds what wrangler + * doesn't know: the pre-build script, configuration-driven env/secrets, and + * OS wiring (vendor props, default enablement). + */ +export interface PackagedGatekeeper extends GatekeeperDeploymentBase { + /** + * The npm package containing the Worker's source and its + * `wrangler.jsonc`. Deploy tooling resolves it to locate sources, derive + * the deploy config, and run builds. + */ + package: string; + /** + * package.json script run before the standard `capnweb-validate` build + * (e.g. `"build:configurator"`, `"build:app"`). Today these scripts are + * absent from wrangler's `build.command`, so the manifest must name them. + * Omitted → no pre-build. + */ + prebuild?: string; + /** + * Configuration-driven environment for the Worker — merged over the vars + * derived from `wrangler.jsonc`. The composite adds `BASE_URL` + * (`/gatekeeper/`) itself — do not include it here. + */ + env?: Record; + /** + * Names of {@link env} keys whose values are secrets. Plain-string values + * under these keys are encrypted (`secret_text`) at deploy time; wrapper + * values (`Redacted`, config references) are secret regardless. + */ + secrets?: readonly string[]; +} + +/** + * A gatekeeper backed by a Worker the caller declares — the Effect-native + * path. Any alchemy Worker works: an Effect-native `Cloudflare.Worker` + * class, a plain `Cloudflare.Worker(id, { main })` declaration, or an + * already-yielded Worker resource. The Worker owns its own build, bindings, + * Durable Objects, and env; the composite only wires it into the OS + * (`GATEKEEPER_` service bindings on router + backend, the `BASE_URL` + * var, vendor `ctx.props`). + * + * @example An Effect-native gatekeeper + * ```typescript + * class Jira extends Cloudflare.Worker()( + * "Jira", + * { main: import.meta.url }, + * Effect.gen(function* () { + * // resolve bindings, return { fetch, GatekeeperVendor entrypoint, ... } + * }), + * ) {} + * + * gatekeepers: [Gatekeeper({ name: "jira", worker: Jira })] + * ``` + */ +export interface WorkerGatekeeper extends GatekeeperDeploymentBase { + /** + * The Worker implementing the gatekeeper contract (a `GatekeeperVendor` + * entrypoint plus the standard HTTP surface). Accepts a Worker resource + * or any Effect yielding one — including `Cloudflare.Worker` classes. + */ + worker: Worker | Effect.Effect; +} + +/** + * Everything the {@link OperatingSystem} composite needs to deploy one + * gatekeeper as its own Worker and wire it into the OS instance — either a + * {@link PackagedGatekeeper} (standard capnweb package layout) or a + * {@link WorkerGatekeeper} (any alchemy Worker). + */ +export type GatekeeperDeployment = PackagedGatekeeper | WorkerGatekeeper; + +/** Does this deployment bring its own Worker declaration? */ +export const isWorkerGatekeeper = ( + manifest: GatekeeperDeployment, +): manifest is WorkerGatekeeper => "worker" in manifest; + +/** + * Identity constructor for a {@link GatekeeperDeployment} — purely for + * discoverability and inference at call sites: + * + * ```typescript + * gatekeepers: [Gatekeeper({ name: "jira", worker: Jira })] + * ``` + */ +export const Gatekeeper = ( + manifest: M, +): M => manifest; diff --git a/packages/alchemy/src/OperatingSystem.ts b/packages/alchemy/src/OperatingSystem.ts new file mode 100644 index 00000000..2e523e4e --- /dev/null +++ b/packages/alchemy/src/OperatingSystem.ts @@ -0,0 +1,763 @@ +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Command from "alchemy/Command"; +import type { Input, InputProps } from "alchemy/Input"; +import * as Namespace from "alchemy/Namespace"; +import * as Output from "alchemy/Output"; +import * as Effect from "effect/Effect"; +import { cast } from "effect/Function"; +import * as Redacted from "effect/Redacted"; +import { + isWorkerGatekeeper, + PUBLIC_BASE_URL, + type GatekeeperDeployment, +} from "./Gatekeeper.ts"; +import { Context } from "./gatekeepers/context.ts"; +import { Mcp } from "./gatekeepers/mcp.ts"; +import { Scheduler } from "./gatekeepers/scheduler.ts"; +import { ownScript, packageDir } from "./paths.ts"; +import { readWranglerConfig } from "./wrangler.ts"; + +/** The `Cloudflare.AI.Gateway` resource (derived — no deep import). */ +type AIGateway = Effect.Success>; +/** The props accepted by `Cloudflare.AI.Gateway`, passed through verbatim. */ +type GatewayProps = Parameters[1]; +/** A deployed `Cloudflare.Worker` resource. */ +type Worker = Effect.Success>; +/** A deployed `Cloudflare.KV.Namespace` resource. */ +type KvNamespace = Effect.Success< + ReturnType +>; +/** A deployed `Cloudflare.R2.Bucket` resource. */ +type R2Bucket = Effect.Success>; +/** The `env` prop shape of `Cloudflare.Worker`. */ +type WorkerEnv = Cloudflare.WorkerBindingProps; + +/** Compatibility date shared by every worker in the fleet. */ +export const COMPATIBILITY_DATE = "2026-02-02"; + +/** The `GATEKEEPER_` binding name both runtimes discover by prefix. */ +export const gatekeeperBindingName = (name: string): string => + `GATEKEEPER_${name.toUpperCase().replaceAll("-", "_")}`; + +/** + * The gatekeepers deployed even when the `gatekeepers` prop doesn't list + * them — the ambient core (context library, scheduled tasks, MCP). Opt out + * by listing the gatekeeper with `enabled: false`, e.g. + * `Mcp({ enabled: false })`. + */ +const defaultGatekeepers = (): GatekeeperDeployment[] => [ + Context(), + Scheduler(), + Mcp(), +]; + +/** Sign-in configuration. Deliberately env-only — never admin-editable. */ +export interface AuthProps { + /** + * Vendor ids allowed as sign-in methods (`AUTH_GATEKEEPERS`), e.g. + * `["cloudflare", "google", "github"]`. Each listed gatekeeper must be + * deployed with OAuth credentials. + */ + gatekeepers?: string[]; + /** + * Turn off username/password auth. Only honored when {@link gatekeepers} + * is non-empty. + */ + disablePasswordAuth?: boolean; + /** Cloudflare Access SSO validation (`CF_ACCESS_AUD` / `CF_ACCESS_ISS`). */ + access?: { + /** The Access application's audience tag (`CF_ACCESS_AUD`). */ + aud: string; + /** The Access team's issuer URL (`CF_ACCESS_ISS`). */ + iss: string; + }; +} + +/** + * AI Gateway mode. The presence of this prop is the opt-in: the composite + * PROVISIONS the gateway, its Run+Read access token, and (when + * {@link AIProps.providers} is set) a Secrets-Store-backed stored key per + * provider. Omit the prop entirely for BYOK mode (per-user provider keys). + */ +export interface AIProps { + /** + * Gateway configuration ({@link GatewayProps}, passed through verbatim) or + * an existing `Cloudflare.AI.Gateway` resource from elsewhere in the + * stack. Omitted → a gateway is provisioned with defaults. + */ + gateway?: GatewayProps | AIGateway; + /** + * Provider credentials, keyed by provider slug (`anthropic`, `openai`, + * `google`, ...). Each entry is stored in the account Secrets Store and + * attached to the gateway as its default key for that provider — never + * bound into any Worker. The keys of this record become + * `CF_AI_GATEWAY_PROVIDERS` (the model menu the backend offers). + */ + providers?: Record>; + /** + * Workers AI routing: `true` routes Workers AI through the gateway + * (default), `"direct"` calls the Workers AI REST endpoint directly + * (`CF_AI_GATEWAY_WAI_DIRECT`), a string names a different gateway id + * (`CF_AI_GATEWAY_WAI`). + */ + workersAi?: boolean | "direct" | (string & {}); + /** + * App-level per-user quotas enforced by the backend's billing flow — + * distinct from the gateway's own `rateLimiting*`/`spendLimits` props. + */ + limits?: { + /** Enable the Cloudflare free-tier/top-up billing flow. */ + enableCloudflareLimits?: boolean; + /** Max free-tier LLM calls per user per day (`DAILY_LLM_CALL_LIMIT`). */ + dailyLlmCallLimit?: number; + /** Min connected-account balance in USD (`MINIMUM_CLOUDFLARE_BALANCE`). */ + minimumCloudflareBalance?: number; + }; +} + +/** + * An extra service binding on the backend Worker pointing at a Worker the + * caller's stack owns (e.g. the starter repo's private error reporter). + */ +export interface BackendServiceBinding { + /** The binding name on the backend's env (e.g. `ERROR_REPORTER`). */ + binding: string; + /** The target Worker resource, deployed by the caller's stack. */ + worker: Worker; + /** Named entrypoint on the target Worker. Omitted → default entrypoint. */ + entrypoint?: string; + /** + * Properties exposed to the target via workerd's `ctx.props`. String + * values containing `{PUBLIC_BASE_URL}` have the placeholder substituted + * with the deployment's public origin. + */ + props?: Record; +} + +/** Caller extensions to the workshop-backend Worker. */ +export interface BackendProps { + /** + * Extra env for the backend Worker — vars, secrets, resources, bindings — + * merged over the composite's own entries. + */ + env?: Record; + /** Extra service bindings — see {@link BackendServiceBinding}. */ + services?: BackendServiceBinding[]; +} + +/** Caller extensions to the frontend build. */ +export interface FrontendProps { + /** + * Extra build-time environment for the vite build (e.g. + * `VITE_FRONTEND_ERROR_REPORTING: "true"`), merged over the composite's + * own entries. + */ + env?: Record; +} + +export interface OperatingSystemProps { + /** + * The OS's public origin hostname (e.g. `os.acme.com`), attached to the + * router as a custom domain. Omitted → the router's `workers.dev` URL is + * the public origin. + */ + domain?: string; + /** + * Identities granted the admin role (`ADMINS`), gating `/admin` + * (branding, connector policies). The values are usernames in whatever + * sign-in system the deployment uses: local account usernames under + * password auth, the OAuth-verified email under gatekeeper sign-in + * (`auth.gatekeepers`), or the Access-JWT email under Cloudflare Access + * (`auth.access`). + */ + admins?: string[]; + /** Sign-in configuration — see {@link AuthProps}. */ + auth?: AuthProps; + /** + * Gatekeepers to deploy, as manifests from each gatekeeper package's + * `deploy` module — e.g. `GitHub({ clientId, clientSecret })` from + * `@gadgets/github-gatekeeper/deploy`. The ambient core (context, + * scheduler, mcp) deploys by default; opt out with + * `Mcp({ enabled: false })`. An entry with the same name as a default + * replaces it. Custom gatekeepers are any package exporting a + * `GatekeeperDeployment`. + */ + gatekeepers?: GatekeeperDeployment[]; + /** + * AI Gateway mode — see {@link AIProps}. Presence is the opt-in; omit for + * BYOK (per-user provider keys). + */ + ai?: AIProps; + /** Caller extensions to the backend Worker — see {@link BackendProps}. */ + backend?: BackendProps; + /** Caller extensions to the frontend build — see {@link FrontendProps}. */ + frontend?: FrontendProps; +} + +const OBSERVABILITY = { + enabled: true, + logs: { enabled: true, invocationLogs: false }, +}; + +const TEXT_RULES = [{ globs: ["**/*.txt", "**/*.svg.txt", "**/*.svg"] }]; + +/** Memo scope shared by every worker build: sources + cross-package deps. */ +const SHARED_MEMO_INCLUDE = [ + "src/**", + "package.json", + "*.mjs", + "../backend-utils/src/**", + "../workshop-shared/src/**", + "../configurator-ui/src/**", + "../mcp-shared/src/**", + "../../scripts/build-gatekeeper-configurator.mjs", +]; + +/** Wrap plain-string secrets so they deploy as `secret_text`, not vars. */ +const asSecret = (value: unknown): unknown => + typeof value === "string" ? Redacted.make(value) : value; + +/** Substitute `{PUBLIC_BASE_URL}` in a manifest string with the origin. */ +const substituteBaseUrl = ( + template: string, + baseUrl: Input, +): Input => { + if (!template.includes(PUBLIC_BASE_URL)) return template; + if (typeof baseUrl === "string") { + return template.replaceAll(PUBLIC_BASE_URL, baseUrl); + } + return Output.map(baseUrl as Output.Output, (url) => + template.replaceAll(PUBLIC_BASE_URL, url), + ); +}; + +const appendPath = (base: Input, path: string): Input => + typeof base === "string" + ? `${base}${path}` + : Output.map(base as Output.Output, (u) => `${u}${path}`); + +const pascal = (name: string): string => + name + .split(/[-_]/) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(""); + +/** + * Merge user-supplied gatekeeper manifests over the default-enabled core. + * A user entry replaces a default with the same name; `enabled: false` + * entries are dropped. + */ +const resolveGatekeepers = ( + manifests: GatekeeperDeployment[] | undefined, +): GatekeeperDeployment[] => { + const byName = new Map(); + for (const manifest of defaultGatekeepers()) { + byName.set(manifest.name, manifest); + } + for (const manifest of manifests ?? []) { + byName.set(manifest.name, manifest); + } + return [...byName.values()].filter((m) => m.enabled !== false); +}; + +/** Build + deploy one gatekeeper worker (namespaced `Gatekeepers//`). */ +const makeGatekeeperWorker = ( + manifest: GatekeeperDeployment, + sharedDepsHash: Input, +) => + Effect.gen(function* () { + if (isWorkerGatekeeper(manifest)) { + // The Effect-native path: the caller's Worker declaration owns its + // build, bindings, DOs, and env — we only wire it into the OS. + return Effect.isEffect(manifest.worker) + ? yield* manifest.worker + : manifest.worker; + } + + const dir = packageDir(manifest.package); + // The package's wrangler.jsonc is the source of truth: entry module, + // compat date/flags, DO migrations, KV bindings, and vars all derive + // from it, so upstream changes are picked up without touching manifests. + const wrangler = yield* readWranglerConfig(dir); + const prepareTree = `node ${JSON.stringify(ownScript("prepare-worker-tree.mjs"))} .wrangler/validate/src`; + const prebuild = manifest.prebuild ? `pnpm run ${manifest.prebuild} && ` : ""; + + const build = yield* Command.Build("Build", { + command: `${prebuild}pnpm exec capnweb-validate build --out .wrangler/validate && ${prepareTree}`, + cwd: dir, + // `&&` chains need a real shell — without it the chain is parsed into + // argv and `&&` reaches the first program as a literal argument. + shell: true, + outdir: ".wrangler/validate", + // Sequences the shared workspace-dep build (typed-storage's `dist/`) + // before this one; also folds it into the memo hash. + env: { SHARED_DEPS_HASH: sharedDepsHash }, + memo: { include: SHARED_MEMO_INCLUDE, lockfile: true }, + }); + + const env: Record = { + ...wrangler.vars, + // Sequences the build before the Worker's bundle (the Worker depends + // on the build through this Output). `main` itself must stay a plain + // string — the engine's precreate stub needs it before dependencies + // resolve. + BUILD_HASH: Output.map(build.hash.output, (hash) => hash ?? ""), + }; + const secretKeys = new Set(manifest.secrets ?? []); + for (const [key, value] of Object.entries(manifest.env ?? {})) { + env[key] = secretKeys.has(key) ? asSecret(value) : value; + } + for (const className of wrangler.durableObjects) { + env[className] = Cloudflare.DurableObject(className); + } + for (const binding of wrangler.kvNamespaces) { + env[binding] = yield* Cloudflare.KV.Namespace(pascal(binding.toLowerCase())); + } + + // The worker's logical id is the gatekeeper name (not a generic + // "Worker"): template-form `bind` sids derive from it, so a shared id + // would collapse every backend→gatekeeper vendor bind into one. + const worker = yield* Cloudflare.Worker(pascal(manifest.name), { + // wrangler's `main` already points into the capnweb-validate output; + // the BUILD_HASH env entry above sequences the build before bundling. + main: wrangler.main, + compatibility: { + date: wrangler.compatibilityDate ?? COMPATIBILITY_DATE, + flags: wrangler.compatibilityFlags, + }, + rules: TEXT_RULES, + observability: OBSERVABILITY, + env: env as WorkerEnv, + }); + + return worker; + }).pipe( + Namespace.push(pascal(manifest.name)), + Namespace.push("Gatekeepers"), + ); + +/** + * The deployed Cloudflare OS — the public origin plus the Workers, storage, + * and optional AI Gateway the composite provisioned. + */ +export type OperatingSystem = { + /** The OS's public origin. */ + url: Worker["url"]; + /** The public router Worker (static assets + custom domain). */ + router: Worker; + /** The workshop-backend Worker (the kernel). */ + backend: Worker; + /** Gatekeeper Workers keyed by short name (e.g. `"github"`). */ + gatekeepers: Record; + /** Blueprint metadata KV namespace. */ + blueprints: KvNamespace; + /** Avatar KV namespace. */ + avatars: KvNamespace; + /** Blueprint content R2 bucket. */ + blueprintContent: R2Bucket; + /** + * The AI Gateway, when {@link OperatingSystemProps.ai} opted into gateway + * mode; otherwise `undefined` (BYOK). + */ + gateway: AIGateway | undefined; +}; + +/** + * Cloudflare OS as a single alchemy resource: provisions the storage (KV, + * R2), every enabled gatekeeper worker, the workshop backend (browser + * rendering, dynamic worker loader, Workers AI, Durable Objects), the + * frontend build, the public router (static assets + custom domain), and — + * in gateway mode — the AI Gateway with its access token and stored + * provider keys. + * + * @example + * ```typescript + * import GitHub from "@gadgets/github-gatekeeper/deploy"; + * import Mcp from "@gadgets/mcp-gatekeeper/deploy"; + * + * const os = yield* OperatingSystem("OS", { + * domain: "os.acme.com", + * admins: ["sam"], + * auth: { gatekeepers: ["github"], disablePasswordAuth: true }, + * gatekeepers: [ + * GitHub({ + * clientId: Config.string("GITHUB_CLIENT_ID"), + * clientSecret: Config.redacted("GITHUB_CLIENT_SECRET"), + * }), + * Mcp({ enabled: false }), // opt out of a default + * ], + * ai: { providers: { anthropic: Config.redacted("ANTHROPIC_API_KEY") } }, + * }); + * return { url: os.url }; + * ``` + */ +export const OperatingSystem = ( + id: string, + // `domain`, `auth`, `gatekeepers`, `ai`, `backend`, and `frontend` + // determine the shape of the resource graph, so they are static; every + // other prop accepts Inputs. + props: InputProps< + OperatingSystemProps, + "domain" | "auth" | "gatekeepers" | "ai" | "backend" | "frontend" + > = {}, +): Effect.Effect => + Effect.gen(function* () { + const gatekeeperSet = resolveGatekeepers(props.gatekeepers); + + // ── Storage ──────────────────────────────────────────────────────── + const blueprints = yield* Cloudflare.KV.Namespace("Blueprints"); + const avatars = yield* Cloudflare.KV.Namespace("Avatars"); + const blueprintContent = yield* Cloudflare.R2.Bucket("BlueprintContent"); + + // ── Frontend build (served by the router as static assets) ───────── + const frontendDir = packageDir("@gadgets/workshop-frontend"); + const frontend = yield* Command.Build("Frontend", { + command: "pnpm run build", + cwd: frontendDir, + outdir: "dist", + env: { VITE_CF_ACCESS_MODE: "true", ...props.frontend?.env }, + memo: { + include: [ + "src/**", + "public/**", + "index.html", + "package.json", + "vite.config.ts", + "tsconfig*.json", + "../workshop-shared/src/**", + "../configurator-ui/src/**", + "../error-reporting/src/**", + ], + lockfile: true, + }, + }); + + // ── AI gateway mode (presence of `ai` is the opt-in) ─────────────── + const ai = props.ai ? yield* makeAI(props.ai) : undefined; + + // ── Shared workspace deps that resolve through built output ──────── + // `@gadgets/typed-storage` is the one workspace package whose exports + // point at `dist/` (everything else exports `src/`); build it once so + // the backend and gatekeeper bundles can resolve it — rolldown would + // otherwise silently externalize the import and the script fails + // startup validation with `No such module`. + const sharedDeps = yield* Command.Build("SharedDeps", { + command: "pnpm run build", + cwd: packageDir("@gadgets/typed-storage"), + outdir: "dist", + memo: { include: ["src/**", "package.json", "tsconfig.json"], lockfile: true }, + }); + const sharedDepsHash = Output.map( + sharedDeps.hash.output, + (hash) => hash ?? "", + ); + + // ── Gatekeeper workers ───────────────────────────────────────────── + const gatekeepers: Record = {}; + for (const manifest of gatekeeperSet) { + gatekeepers[manifest.name] = yield* makeGatekeeperWorker( + manifest, + sharedDepsHash, + ); + } + + // ── Router (the public origin) ───────────────────────────────────── + // Created BEFORE the backend so its `url` can flow into the backend's + // env as a plain Input (custom domain, or the workers.dev URL the + // engine resolves from the precreate stub). The router's own service + // bindings reference the backend, so they are attached post-hoc via + // `bind` — bindings exist precisely to close that cycle. + // Entry, compat date, and the assets routing config (SPA fallback + + // the contract-tested run_worker_first list) derive from the router + // package's wrangler.jsonc. + const routerDir = packageDir("@gadgets/router"); + const routerWrangler = yield* readWranglerConfig(routerDir); + const router = yield* Cloudflare.Worker("Router", { + main: routerWrangler.main, + compatibility: { + date: routerWrangler.compatibilityDate ?? COMPATIBILITY_DATE, + flags: routerWrangler.compatibilityFlags, + }, + observability: OBSERVABILITY, + domain: props.domain, + // `cast` (effect/Function's typed identity) mirrors StaticSite.ts: + // the `assets` union doesn't distribute Input<> over its members, so + // Output-valued `directory`/`hash` fail structural matching without it. + assets: cast({ + directory: frontend.outdir, + hash: Output.map(frontend.hash.output, (hash) => hash ?? ""), + notFoundHandling: routerWrangler.assets?.notFoundHandling, + runWorkerFirst: routerWrangler.assets?.runWorkerFirst, + }), + }); + + /** The OS's public origin: the custom domain, or the router's URL. */ + const publicBaseUrl: Input = + typeof props.domain === "string" + ? `https://${props.domain}` + : Output.map( + router.url as Output.Output, + (url) => url ?? "", + ); + + /** Substitute `{PUBLIC_BASE_URL}` across a props record. */ + const substituteProps = ( + record: Record, + ): Record> => + Object.fromEntries( + Object.entries(record).map(([key, template]) => [ + key, + substituteBaseUrl(template, publicBaseUrl), + ]), + ); + + // ── Workshop backend (the kernel) ────────────────────────────────── + const backendDir = packageDir("@gadgets/workshop-backend"); + // Entry, compat date/flags, and DO migrations derive from the + // package's wrangler.jsonc — the checked-in deploy contract. + const backendWrangler = yield* readWranglerConfig(backendDir); + const prepareTree = `node ${JSON.stringify(ownScript("prepare-worker-tree.mjs"))} .wrangler/validate/src`; + const backendBuild = yield* Command.Build("BackendBuild", { + command: + "node build-browser-runtime.mjs && node scripts/build-format-blueprints.mjs && " + + `pnpm exec capnweb-validate build --out .wrangler/validate && ${prepareTree}`, + cwd: backendDir, + // `&&` chains need a real shell (see the gatekeeper build above). + shell: true, + outdir: ".wrangler/validate", + // Sequences the shared workspace-dep build before this one. + env: { SHARED_DEPS_HASH: sharedDepsHash }, + memo: { + include: [ + "src/**", + "format-blueprints/**", + "build-browser-runtime.mjs", + "scripts/build-format-blueprints.mjs", + "package.json", + "../backend-utils/src/**", + "../workshop-shared/src/**", + "../typed-storage/src/**", + "../error-reporting/src/**", + "../mcp-shared/src/**", + ], + lockfile: true, + }, + }); + + const backendEnv: Record = { + BLUEPRINTS: blueprints, + AVATARS: avatars, + BLUEPRINT_CONTENT: blueprintContent, + BROWSER: Cloudflare.Workers.Browser("BROWSER"), + // Always bound in prod: the webFetch agent tool's toMarkdown needs it, + // gateway mode or not. + WORKERS_AI: Cloudflare.Workers.AI("WORKERS_AI"), + // Sequences the backend build before bundling (see the gatekeeper + // builds — `main` must stay static for the precreate stub). + BUILD_HASH: Output.map(backendBuild.hash.output, (hash) => hash ?? ""), + PUBLIC_BASE_URL: publicBaseUrl, + }; + // Backend reaches gatekeepers through the `GatekeeperVendor` entrypoint + // (capability RPC), unlike the router's default entrypoint. Vendor + // `ctx.props` (e.g. context's sharingDomain) ride the binding; note the + // Cloudflare API's schema doesn't carry `props` on live uploads yet + // (`alchemy dev` delivers them) — pending the distilled patch. + for (const manifest of gatekeeperSet) { + const worker = gatekeepers[manifest.name]!; + backendEnv[gatekeeperBindingName(manifest.name)] = + Cloudflare.WorkerEntrypoint(worker, { + entrypoint: "GatekeeperVendor", + ...(manifest.vendorProps + ? { props: substituteProps(manifest.vendorProps) } + : {}), + }); + } + // Caller-owned service bindings (e.g. a private error reporter). + for (const service of props.backend?.services ?? []) { + backendEnv[service.binding] = Cloudflare.WorkerEntrypoint( + service.worker, + { + entrypoint: service.entrypoint, + ...(service.props ? { props: substituteProps(service.props) } : {}), + }, + ); + } + // Durable Object classes are reached via `ctx.exports` + // (`enable_ctx_exports`); the bindings exist to declare the classes and + // their SQLite migrations, derived from wrangler.jsonc's history. + for (const className of backendWrangler.durableObjects) { + backendEnv[className] = Cloudflare.DurableObject(className); + } + if (props.admins !== undefined) backendEnv.ADMINS = props.admins; + const auth = props.auth; + if (auth?.gatekeepers?.length) { + backendEnv.AUTH_GATEKEEPERS = auth.gatekeepers.join(","); + if (auth.disablePasswordAuth) backendEnv.DISABLE_PASSWORD_AUTH = "true"; + } + if (auth?.access) { + backendEnv.CF_ACCESS_AUD = auth.access.aud; + backendEnv.CF_ACCESS_ISS = auth.access.iss; + } + Object.assign(backendEnv, ai?.backendEnv); + Object.assign(backendEnv, props.backend?.env); + + const backend = yield* Cloudflare.Worker("Backend", { + main: backendWrangler.main, + compatibility: { + date: backendWrangler.compatibilityDate ?? COMPATIBILITY_DATE, + flags: backendWrangler.compatibilityFlags, + }, + rules: TEXT_RULES, + observability: OBSERVABILITY, + env: backendEnv as WorkerEnv, + }); + + // Dynamic Workers: gadget server code runs in loader-created isolates. + yield* backend.bind("Loader", { + bindings: [{ type: "worker_loader", name: "LOADER" }], + }); + + // ── Router service bindings (attached post-hoc via `bind`: the router + // was created before the backend so its URL could flow into the + // backend's env — bindings close the resulting cycle) ───────────── + yield* router.bind`${backend}`({ + bindings: [ + { + type: "service", + name: "WORKSHOP_BACKEND", + service: backend.workerName, + }, + ], + }); + for (const [name, worker] of Object.entries(gatekeepers)) { + // Default entrypoint: whole HTTP requests are forwarded. + yield* router.bind`${worker}`({ + bindings: [ + { + type: "service", + name: gatekeeperBindingName(name), + service: worker.workerName, + }, + ], + }); + } + + // Each gatekeeper's public base path (`/gatekeeper/`), + // attached via `bind` — the gatekeepers were created before the router. + for (const manifest of gatekeeperSet) { + const worker = gatekeepers[manifest.name]!; + yield* worker.bind("BaseUrl", { + bindings: [ + { + type: "plain_text", + name: "BASE_URL", + text: appendPath(publicBaseUrl, `/gatekeeper/${manifest.name}`), + }, + ], + }); + } + + return { + /** The OS's public origin. */ + url: router.url, + router, + backend, + gatekeepers, + blueprints, + avatars, + blueprintContent, + gateway: ai?.gateway, + }; + }).pipe(Namespace.push(id)); + +const isGatewayResource = ( + value: GatewayProps | AIGateway, +): value is AIGateway => + (value as { Type?: unknown }).Type === "Cloudflare.AI.Gateway"; + +/** Provision the AI Gateway, its Run+Read token, and stored provider keys. */ +const makeAI = (ai: AIProps) => + Effect.gen(function* () { + const { accountId } = yield* yield* Cloudflare.CloudflareEnvironment; + + const providers = Object.entries(ai.providers ?? {}); + + // Stored provider keys resolve out of the account Secrets Store, which + // must be attached to the gateway via `storeId`. + const store = providers.length + ? yield* Cloudflare.SecretsStore.Store("KeyStore") + : undefined; + + if (ai.gateway !== undefined && isGatewayResource(ai.gateway) && store) { + // Stored keys resolve out of the store attached to the gateway via + // `storeId`; we can't retrofit that onto a gateway we don't manage. + throw new Error( + "ai.providers requires the OperatingSystem to provision the gateway: " + + "pass gateway props (or omit `gateway`) instead of an existing " + + "Gateway resource, or attach your own SecretsStore + ProviderKeys " + + "to that gateway and set CF_AI_GATEWAY_PROVIDERS yourself.", + ); + } + + const gateway = + ai.gateway !== undefined && isGatewayResource(ai.gateway) + ? ai.gateway + : yield* Cloudflare.AI.Gateway("Gateway", { + ...(ai.gateway as GatewayProps | undefined), + ...(store ? { storeId: store.storeId } : {}), + }); + + // Least-privilege token for the backend: Run to route inference, Read + // to retrieve per-log costs for user-visible accounting. + const token = yield* Cloudflare.ApiToken.AccountApiToken("GatewayToken", { + policies: [ + { + effect: "allow", + permissionGroups: ["AI Gateway Run", "AI Gateway Read"], + resources: { [`com.cloudflare.api.account.${accountId}`]: "*" }, + }, + ], + }); + + for (const [slug, value] of providers) { + yield* Cloudflare.AI.ProviderKey(`${pascal(slug)}Key`, { + gatewayId: gateway.gatewayId as unknown as string, + providerSlug: slug, + store: { + storeId: store!.storeId as unknown as string, + accountId: store!.accountId as unknown as string, + }, + value, + defaultConfig: true, + }); + } + + const backendEnv: Record = { + CF_AI_GATEWAY: gateway.gatewayId, + CF_AI_GATEWAY_ACCOUNT_ID: gateway.accountId, + CF_AI_GATEWAY_API_TOKEN: token.value, + }; + if (providers.length) { + backendEnv.CF_AI_GATEWAY_PROVIDERS = providers + .map(([slug]) => slug) + .join(","); + } + if (ai.workersAi === "direct") { + backendEnv.CF_AI_GATEWAY_WAI_DIRECT = "true"; + } else if (typeof ai.workersAi === "string") { + backendEnv.CF_AI_GATEWAY_WAI = ai.workersAi; + } + if (ai.limits?.enableCloudflareLimits) { + backendEnv.ENABLE_CLOUDFLARE_LIMITS = "true"; + } + if (ai.limits?.dailyLlmCallLimit !== undefined) { + backendEnv.DAILY_LLM_CALL_LIMIT = String(ai.limits.dailyLlmCallLimit); + } + if (ai.limits?.minimumCloudflareBalance !== undefined) { + backendEnv.MINIMUM_CLOUDFLARE_BALANCE = String( + ai.limits.minimumCloudflareBalance, + ); + } + + return { gateway, token, backendEnv }; + }).pipe(Namespace.push("AI")); diff --git a/packages/alchemy/src/gatekeepers/cloudflare.ts b/packages/alchemy/src/gatekeepers/cloudflare.ts new file mode 100644 index 00000000..49e735f4 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/cloudflare.ts @@ -0,0 +1,25 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the cloudflare gatekeeper. */ +export interface CloudflareConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the cloudflare gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_CLOUDFLARE` bindings + `/gatekeeper/cloudflare` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Cloudflare = (config: CloudflareConfig): GatekeeperDeployment => ({ + name: "cloudflare", + package: "@gadgets/cloudflare-gatekeeper", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Cloudflare; diff --git a/packages/alchemy/src/gatekeepers/confluence.ts b/packages/alchemy/src/gatekeepers/confluence.ts new file mode 100644 index 00000000..04cfb050 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/confluence.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the confluence gatekeeper. */ +export interface ConfluenceConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the confluence gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_CONFLUENCE` bindings + `/gatekeeper/confluence` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Confluence = (config: ConfluenceConfig): GatekeeperDeployment => ({ + name: "confluence", + package: "@gadgets/confluence-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Confluence; diff --git a/packages/alchemy/src/gatekeepers/context.ts b/packages/alchemy/src/gatekeepers/context.ts new file mode 100644 index 00000000..93115634 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/context.ts @@ -0,0 +1,36 @@ +import { + PUBLIC_BASE_URL, + type GatekeeperDeployment, +} from "../Gatekeeper.ts"; + +/** Configuration for the context gatekeeper. */ +export interface ContextConfig { + /** Set `false` to opt out of this default-enabled gatekeeper. */ + enabled?: boolean; + /** + * Isolates Context data shared by this deployment. Deployments with the + * same sharing domain can share collections. + * @default the deployment's public origin + */ + sharingDomain?: string; +} + +/** + * Deploy the context-library gatekeeper (ambient, core) as its own Worker, + * wired into the OS (`GATEKEEPER_CONTEXT` bindings + `/gatekeeper/context` + * route). Deploys by default; disable with `Context({ enabled: false })`. + * The entry, compat flags, Durable Objects, and its KV namespace derive + * from the package's `wrangler.jsonc` at deploy time. + */ +export const Context = (config: ContextConfig = {}): GatekeeperDeployment => ({ + name: "context", + package: "@gadgets/gatekeeper-context", + prebuild: "build:app", + // The gatekeeper reads the sharing domain from its vendor binding's + // ctx.props; by default collections are shared per-origin. + vendorProps: { sharingDomain: config.sharingDomain ?? PUBLIC_BASE_URL }, + defaultEnabled: true, + enabled: config.enabled, +}); + +export default Context; diff --git a/packages/alchemy/src/gatekeepers/github.ts b/packages/alchemy/src/gatekeepers/github.ts new file mode 100644 index 00000000..81e4378c --- /dev/null +++ b/packages/alchemy/src/gatekeepers/github.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the github gatekeeper. */ +export interface GitHubConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the github gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_GITHUB` bindings + `/gatekeeper/github` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const GitHub = (config: GitHubConfig): GatekeeperDeployment => ({ + name: "github", + package: "@gadgets/github-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default GitHub; diff --git a/packages/alchemy/src/gatekeepers/google.ts b/packages/alchemy/src/gatekeepers/google.ts new file mode 100644 index 00000000..8ca2aa8a --- /dev/null +++ b/packages/alchemy/src/gatekeepers/google.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the google gatekeeper. */ +export interface GoogleConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the google gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_GOOGLE` bindings + `/gatekeeper/google` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Google = (config: GoogleConfig): GatekeeperDeployment => ({ + name: "google", + package: "@gadgets/google-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Google; diff --git a/packages/alchemy/src/gatekeepers/homeassistant.ts b/packages/alchemy/src/gatekeepers/homeassistant.ts new file mode 100644 index 00000000..a50cc754 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/homeassistant.ts @@ -0,0 +1,18 @@ +import type { GatekeeperDeployment } from "../Gatekeeper.ts"; + +/** + * Deploy the Home Assistant gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_HOMEASSISTANT` bindings + `/gatekeeper/homeassistant` + * route). Zero-config to deploy — each user connects their own HA instance + * by pasting its URL and a long-lived access token — but a niche consumer + * surface, so it deploys only when listed. The entry, compat flags, and + * Durable Objects derive from the package's `wrangler.jsonc` at deploy + * time. + */ +export const HomeAssistant = (): GatekeeperDeployment => ({ + name: "homeassistant", + package: "@gadgets/homeassistant-gatekeeper", + prebuild: "build:configurator", +}); + +export default HomeAssistant; diff --git a/packages/alchemy/src/gatekeepers/index.ts b/packages/alchemy/src/gatekeepers/index.ts new file mode 100644 index 00000000..2617caa7 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/index.ts @@ -0,0 +1,22 @@ +// One module per built-in gatekeeper, each exporting a plugin function that +// returns the gatekeeper's `GatekeeperDeployment` manifest. +// +// These live here (rather than in each gatekeeper package) as the +// conservative choice — the gatekeeper packages' export surfaces stay +// untouched. Moving each module into its package (`@gadgets//deploy`) +// so the gatekeeper owns its deployment is the natural follow-up proposal. +export { Cloudflare, type CloudflareConfig } from "./cloudflare.ts"; +export { Confluence, type ConfluenceConfig } from "./confluence.ts"; +export { Context, type ContextConfig } from "./context.ts"; +export { GitHub, type GitHubConfig } from "./github.ts"; +export { Google, type GoogleConfig } from "./google.ts"; +export { HomeAssistant } from "./homeassistant.ts"; +export { Linear, type LinearConfig } from "./linear.ts"; +export { Mcp, type McpConfig } from "./mcp.ts"; +export { McpPortal, type McpPortalConfig } from "./mcp-portal.ts"; +export { Notion, type NotionConfig } from "./notion.ts"; +export { Scheduler, type SchedulerConfig } from "./scheduler.ts"; +export { Slack, type SlackConfig } from "./slack.ts"; +export { Spotify, type SpotifyConfig } from "./spotify.ts"; +export { Supabase, type SupabaseConfig } from "./supabase.ts"; +export { ZoomInfo, type ZoomInfoConfig } from "./zoominfo.ts"; diff --git a/packages/alchemy/src/gatekeepers/linear.ts b/packages/alchemy/src/gatekeepers/linear.ts new file mode 100644 index 00000000..475f9b8e --- /dev/null +++ b/packages/alchemy/src/gatekeepers/linear.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the linear gatekeeper. */ +export interface LinearConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the linear gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_LINEAR` bindings + `/gatekeeper/linear` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Linear = (config: LinearConfig): GatekeeperDeployment => ({ + name: "linear", + package: "@gadgets/linear-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Linear; diff --git a/packages/alchemy/src/gatekeepers/mcp-portal.ts b/packages/alchemy/src/gatekeepers/mcp-portal.ts new file mode 100644 index 00000000..4df6e693 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/mcp-portal.ts @@ -0,0 +1,58 @@ +import type { + EnvInput, + GatekeeperDeployment, + SecretInput, +} from "../Gatekeeper.ts"; + +/** Configuration for the MCP Server Portals gatekeeper. */ +export interface McpPortalConfig { + /** The portal endpoint every user reaches MCP servers through (`MCP_PORTAL_URL`). */ + url: string; + /** Display name for the portal (`MCP_PORTAL_NAME`). */ + name?: string; + /** Auth mode expected by the portal (`MCP_PORTAL_AUTH`). */ + auth?: string; + /** + * Static bearer token, when the portal uses token auth + * (`MCP_PORTAL_TOKEN`). Deployed as a secret on the worker. + */ + token?: SecretInput; + /** + * Whether to trust tool annotations reported by the portal + * (`MCP_PORTAL_TRUST_ANNOTATIONS`). + */ + trustAnnotations?: boolean; + /** + * Allow a plaintext-HTTP portal endpoint (`MCP_ALLOW_INSECURE`). + * @default false — the package's wrangler.jsonc default + */ + allowInsecure?: boolean; +} + +/** + * Deploy the MCP Server Portals gatekeeper as its own Worker, wired into the + * OS (`GATEKEEPER_MCP_PORTAL` bindings + `/gatekeeper/mcp-portal` route). + * Configuring it is what installs it: an admin points the whole deployment + * at one portal URL and every user reaches the organization's approved MCP + * servers through it. The entry, compat flags, and Durable Objects derive + * from the package's `wrangler.jsonc` at deploy time. + */ +export const McpPortal = (config: McpPortalConfig): GatekeeperDeployment => { + const env: Record = { MCP_PORTAL_URL: config.url }; + if (config.name !== undefined) env.MCP_PORTAL_NAME = config.name; + if (config.auth !== undefined) env.MCP_PORTAL_AUTH = config.auth; + if (config.token !== undefined) env.MCP_PORTAL_TOKEN = config.token; + if (config.trustAnnotations !== undefined) { + env.MCP_PORTAL_TRUST_ANNOTATIONS = String(config.trustAnnotations); + } + if (config.allowInsecure) env.MCP_ALLOW_INSECURE = "true"; + return { + name: "mcp-portal", + package: "@gadgets/mcp-portal-gatekeeper", + prebuild: "build:configurator", + env, + secrets: ["MCP_PORTAL_TOKEN"], + }; +}; + +export default McpPortal; diff --git a/packages/alchemy/src/gatekeepers/mcp.ts b/packages/alchemy/src/gatekeepers/mcp.ts new file mode 100644 index 00000000..b1266317 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/mcp.ts @@ -0,0 +1,31 @@ +import type { GatekeeperDeployment } from "../Gatekeeper.ts"; + +/** Configuration for the mcp gatekeeper. */ +export interface McpConfig { + /** Set `false` to opt out of this default-enabled gatekeeper. */ + enabled?: boolean; + /** + * Allow plaintext-HTTP MCP endpoints (`MCP_ALLOW_INSECURE`). + * @default false — the package's wrangler.jsonc default + */ + allowInsecure?: boolean; +} + +/** + * Deploy the connect-any-MCP-server gatekeeper (core) as its own Worker, + * wired into the OS (`GATEKEEPER_MCP` bindings + `/gatekeeper/mcp` route). + * Deploys by default; disable with `Mcp({ enabled: false })`. The entry, + * compat flags, and Durable Objects derive from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Mcp = (config: McpConfig = {}): GatekeeperDeployment => ({ + name: "mcp", + package: "@gadgets/mcp-gatekeeper", + prebuild: "build:configurator", + // Only override the wrangler-declared default when opting in. + env: config.allowInsecure ? { MCP_ALLOW_INSECURE: "true" } : undefined, + defaultEnabled: true, + enabled: config.enabled, +}); + +export default Mcp; diff --git a/packages/alchemy/src/gatekeepers/notion.ts b/packages/alchemy/src/gatekeepers/notion.ts new file mode 100644 index 00000000..0eada366 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/notion.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the notion gatekeeper. */ +export interface NotionConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the notion gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_NOTION` bindings + `/gatekeeper/notion` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Notion = (config: NotionConfig): GatekeeperDeployment => ({ + name: "notion", + package: "@gadgets/notion-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Notion; diff --git a/packages/alchemy/src/gatekeepers/scheduler.ts b/packages/alchemy/src/gatekeepers/scheduler.ts new file mode 100644 index 00000000..ca8cf286 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/scheduler.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment } from "../Gatekeeper.ts"; + +/** Configuration for the scheduler gatekeeper. */ +export interface SchedulerConfig { + /** Set `false` to opt out of this default-enabled gatekeeper. */ + enabled?: boolean; +} + +/** + * Deploy the scheduled-tasks gatekeeper (ambient, core) as its own Worker, + * wired into the OS (`GATEKEEPER_SCHEDULER` bindings + + * `/gatekeeper/scheduler` route). Deploys by default; disable with + * `Scheduler({ enabled: false })`. The entry, compat flags, and Durable + * Objects derive from the package's `wrangler.jsonc` at deploy time. + */ +export const Scheduler = ( + config: SchedulerConfig = {}, +): GatekeeperDeployment => ({ + name: "scheduler", + package: "@gadgets/gatekeeper-scheduler", + prebuild: "build:app", + defaultEnabled: true, + enabled: config.enabled, +}); + +export default Scheduler; diff --git a/packages/alchemy/src/gatekeepers/slack.ts b/packages/alchemy/src/gatekeepers/slack.ts new file mode 100644 index 00000000..6887d06a --- /dev/null +++ b/packages/alchemy/src/gatekeepers/slack.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the slack gatekeeper. */ +export interface SlackConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the slack gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_SLACK` bindings + `/gatekeeper/slack` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Slack = (config: SlackConfig): GatekeeperDeployment => ({ + name: "slack", + package: "@gadgets/slack-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Slack; diff --git a/packages/alchemy/src/gatekeepers/spotify.ts b/packages/alchemy/src/gatekeepers/spotify.ts new file mode 100644 index 00000000..7dfa19ac --- /dev/null +++ b/packages/alchemy/src/gatekeepers/spotify.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the spotify gatekeeper. */ +export interface SpotifyConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the spotify gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_SPOTIFY` bindings + `/gatekeeper/spotify` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Spotify = (config: SpotifyConfig): GatekeeperDeployment => ({ + name: "spotify", + package: "@gadgets/spotify-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Spotify; diff --git a/packages/alchemy/src/gatekeepers/supabase.ts b/packages/alchemy/src/gatekeepers/supabase.ts new file mode 100644 index 00000000..653e6539 --- /dev/null +++ b/packages/alchemy/src/gatekeepers/supabase.ts @@ -0,0 +1,26 @@ +import type { GatekeeperDeployment, SecretInput } from "../Gatekeeper.ts"; + +/** Configuration for the supabase gatekeeper. */ +export interface SupabaseConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; +} + +/** + * Deploy the supabase gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_SUPABASE` bindings + `/gatekeeper/supabase` route). + * Supplying the OAuth credentials is what installs it. Everything else + * (entry, compat flags, Durable Objects) derives from the package's + * `wrangler.jsonc` at deploy time. + */ +export const Supabase = (config: SupabaseConfig): GatekeeperDeployment => ({ + name: "supabase", + package: "@gadgets/supabase-gatekeeper", + prebuild: "build:configurator", + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); + +export default Supabase; diff --git a/packages/alchemy/src/gatekeepers/zoominfo.ts b/packages/alchemy/src/gatekeepers/zoominfo.ts new file mode 100644 index 00000000..2082ad8f --- /dev/null +++ b/packages/alchemy/src/gatekeepers/zoominfo.ts @@ -0,0 +1,60 @@ +import type { + EnvInput, + GatekeeperDeployment, + SecretInput, +} from "../Gatekeeper.ts"; + +/** Configuration for the zoominfo gatekeeper. */ +export interface ZoomInfoConfig { + /** The OAuth app's client ID. Deployed as a secret on the worker. */ + clientId: SecretInput; + /** The OAuth app's client secret. Deployed as a secret on the worker. */ + clientSecret: SecretInput; + /** + * Override for ZoomInfo's GTM API base URL (`ZOOMINFO_API_BASE_URL`). + * @default ZoomInfo's production API endpoint + */ + apiBaseUrl?: string; + /** + * Override for the OAuth authorize URL (`ZOOMINFO_AUTHORIZE_URL`). + * @default ZoomInfo's production authorize endpoint + */ + authorizeUrl?: string; + /** + * Override for the OAuth token URL (`ZOOMINFO_TOKEN_URL`). + * @default ZoomInfo's production token endpoint + */ + tokenUrl?: string; +} + +/** + * Deploy the zoominfo gatekeeper as its own Worker, wired into the OS + * (`GATEKEEPER_ZOOMINFO` bindings + `/gatekeeper/zoominfo` route). + * Supplying the OAuth credentials is what installs it. The entry, compat + * flags, and Durable Objects derive from the package's `wrangler.jsonc` at + * deploy time. + */ +export const ZoomInfo = (config: ZoomInfoConfig): GatekeeperDeployment => { + const env: Record = { + CLIENT_ID: config.clientId, + CLIENT_SECRET: config.clientSecret, + }; + if (config.apiBaseUrl !== undefined) { + env.ZOOMINFO_API_BASE_URL = config.apiBaseUrl; + } + if (config.authorizeUrl !== undefined) { + env.ZOOMINFO_AUTHORIZE_URL = config.authorizeUrl; + } + if (config.tokenUrl !== undefined) { + env.ZOOMINFO_TOKEN_URL = config.tokenUrl; + } + return { + name: "zoominfo", + package: "@gadgets/zoominfo-gatekeeper", + prebuild: "build:configurator", + env, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], + }; +}; + +export default ZoomInfo; diff --git a/packages/alchemy/src/index.ts b/packages/alchemy/src/index.ts new file mode 100644 index 00000000..78728bef --- /dev/null +++ b/packages/alchemy/src/index.ts @@ -0,0 +1,23 @@ +export { + COMPATIBILITY_DATE, + gatekeeperBindingName, + OperatingSystem, + type AIProps, + type AuthProps, + type BackendProps, + type BackendServiceBinding, + type FrontendProps, + type OperatingSystemProps, +} from "./OperatingSystem.ts"; +export { + Gatekeeper, + isWorkerGatekeeper, + PUBLIC_BASE_URL, + type EnvInput, + type GatekeeperDeployment, + type GatekeeperDeploymentBase, + type PackagedGatekeeper, + type SecretInput, + type WorkerGatekeeper, +} from "./Gatekeeper.ts"; +export * as Gatekeepers from "./gatekeepers/index.ts"; diff --git a/packages/alchemy/src/paths.ts b/packages/alchemy/src/paths.ts new file mode 100644 index 00000000..f0820b49 --- /dev/null +++ b/packages/alchemy/src/paths.ts @@ -0,0 +1,57 @@ +import { existsSync } from "node:fs"; +import { createRequire } from "node:module"; +import * as NodePath from "node:path"; +import { pathToFileURL } from "node:url"; + +const ownRequire = createRequire(import.meta.url); +// Resolve from the user's project first: packaged gatekeepers named in +// manifests (e.g. a starter repo's own workspace package) are dependencies +// of the project running the stack, not of this package. +const projectRequire = createRequire( + pathToFileURL(NodePath.join(process.cwd(), "package.json")), +); + +/** + * Find a package's directory by scanning the resolver's `node_modules` + * candidate paths for its `package.json` on disk. Deliberately avoids + * `require.resolve("/package.json")`: packages with an `exports` map + * that omits `./package.json` (e.g. `@gadgets/typed-storage`) reject that + * subpath, and resolving the package entry itself can fail when it points + * at not-yet-built output — the very output this resolution exists to build. + */ +const findPackageDir = ( + require: NodeJS.Require, + pkg: string, +): string | undefined => { + for (const base of require.resolve.paths(pkg) ?? []) { + const candidate = NodePath.join(base, pkg, "package.json"); + if (existsSync(candidate)) return NodePath.dirname(candidate); + } + return undefined; +}; + +/** + * Directory containing a package (the dirname of its `package.json`), + * resolved from the deploying project first, then from this package's own + * dependencies (the `@gadgets/*` workspace packages). + */ +export const packageDir = (pkg: string): string => { + const dir = findPackageDir(projectRequire, pkg) ?? findPackageDir(ownRequire, pkg); + if (dir === undefined) { + throw new Error( + `Cannot resolve package "${pkg}" from ${process.cwd()} or from cloudflare-os's own dependencies.`, + ); + } + return dir; +}; + +/** + * Absolute path to a script shipped inside this package (used by build + * commands that post-process worker build output). + */ +export const ownScript = (name: string): string => + NodePath.join( + NodePath.dirname(ownRequire.resolve("cloudflare-os/package.json")), + "scripts", + name, + ); diff --git a/packages/alchemy/src/wrangler.ts b/packages/alchemy/src/wrangler.ts new file mode 100644 index 00000000..4da865a3 --- /dev/null +++ b/packages/alchemy/src/wrangler.ts @@ -0,0 +1,71 @@ +import { readFileSync } from "node:fs"; +import * as NodePath from "node:path"; +import * as Effect from "effect/Effect"; +import { parse as parseJsonc } from "jsonc-parser"; + +/** + * The deploy-relevant subset of a gatekeeper package's `wrangler.jsonc` — + * the single source of truth for how the worker deploys today. Deriving + * these at deploy time (instead of copying them into manifests) means an + * upstream change to a package's flags, migrations, or entrypoint is picked + * up automatically. + */ +export interface WranglerConfig { + /** Worker entry module, resolved to an absolute path. */ + main: string; + /** `compatibility_date`. */ + compatibilityDate: string | undefined; + /** `compatibility_flags`. */ + compatibilityFlags: string[]; + /** All `new_sqlite_classes` across the ordered migration history. */ + durableObjects: string[]; + /** KV binding names from `kv_namespaces`. */ + kvNamespaces: string[]; + /** Plain vars from `vars`. */ + vars: Record; + /** Static-assets routing config from `assets`, when declared. */ + assets: + | { notFoundHandling: string | undefined; runWorkerFirst: string[] | boolean | undefined } + | undefined; +} + +interface RawWranglerConfig { + main?: string; + compatibility_date?: string; + compatibility_flags?: string[]; + migrations?: { new_sqlite_classes?: string[] }[]; + kv_namespaces?: { binding: string }[]; + vars?: Record; + assets?: { + not_found_handling?: string; + run_worker_first?: string[] | boolean; + }; +} + +/** Parse `/wrangler.jsonc` into its deploy-relevant subset. */ +export const readWranglerConfig = ( + dir: string, +): Effect.Effect => + Effect.sync(() => { + const file = NodePath.join(dir, "wrangler.jsonc"); + const raw = parseJsonc(readFileSync(file, "utf8")) as RawWranglerConfig; + if (typeof raw?.main !== "string") { + throw new Error(`${file} has no "main" — not a deployable worker config`); + } + return { + main: NodePath.join(dir, raw.main), + compatibilityDate: raw.compatibility_date, + compatibilityFlags: raw.compatibility_flags ?? [], + durableObjects: (raw.migrations ?? []).flatMap( + (migration) => migration.new_sqlite_classes ?? [], + ), + kvNamespaces: (raw.kv_namespaces ?? []).map((kv) => kv.binding), + vars: raw.vars ?? {}, + assets: raw.assets + ? { + notFoundHandling: raw.assets.not_found_handling, + runWorkerFirst: raw.assets.run_worker_first, + } + : undefined, + }; + }); diff --git a/packages/alchemy/test/OperatingSystem.test.ts b/packages/alchemy/test/OperatingSystem.test.ts new file mode 100644 index 00000000..d093d36e --- /dev/null +++ b/packages/alchemy/test/OperatingSystem.test.ts @@ -0,0 +1,81 @@ +// Live end-to-end test: deploys a full Cloudflare OS to the real account +// (default-on gatekeepers, no domain — served at the router's workers.dev +// URL), verifies the deployed system serves, and destroys it. +// +// pnpm --dir packages/alchemy test:e2e +// +// Uses the same alchemy profile/state as `alchemy deploy`. Set NO_DESTROY=1 +// to keep the deployment around between runs while iterating. +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Test from "alchemy/Test/Vitest"; +import * as Effect from "effect/Effect"; +import * as HttpClient from "effect/unstable/http/HttpClient"; +import { expect } from "vitest"; +import { OperatingSystem } from "../src/index.ts"; + +const { test, beforeAll, afterAll, deploy, destroy } = Test.make({ + providers: Cloudflare.providers(), + state: Cloudflare.state(), +}); + +const Stack = Alchemy.Stack( + "CloudflareOsE2E", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + // Everything defaulted: password auth, BYOK AI, the default-on + // gatekeepers (context, scheduler, mcp), workers.dev origin. + const os = yield* OperatingSystem("OS"); + return { url: os.url.as() }; + }), +); + +const stack = beforeAll(deploy(Stack), { timeout: 1_800_000 }); +afterAll.skipIf(!!process.env.NO_DESTROY)(destroy(Stack), { + timeout: 900_000, +}); + +test( + "serves the frontend at the public origin", + Effect.gen(function* () { + const { url } = yield* stack; + const response = yield* Test.getWhenReady(`${url}/`, { times: 25 }); + expect(response.status).toBe(200); + const body = yield* response.text; + // The workshop-frontend SPA shell, served by the router's ASSETS + // binding with the vite build's output. + expect(body).toContain('
'); + expect(body).toContain("Cloudflare OS"); + }), +); + +test( + "routes /api to the workshop backend", + Effect.gen(function* () { + const { url } = yield* stack; + // `/api` is the backend's capnweb PublicApi endpoint. A plain GET is + // not a valid RPC/WebSocket request, but any deliberate client + // response proves the whole chain: router `run_worker_first` → + // WORKSHOP_BACKEND service binding → backend booted with its KV, R2, + // browser, loader, and Durable Object bindings resolved. + const response = yield* Test.getWhenReady(`${url}/api`, { times: 25 }); + expect(response.status).toBeLessThan(500); + }), +); + +test( + "routes /gatekeeper/* to gatekeeper workers", + Effect.gen(function* () { + const { url } = yield* stack; + const client = yield* HttpClient.HttpClient; + // The mcp gatekeeper's HTTP surface answers under + // /gatekeeper/mcp/* (forwarded whole by the router's GATEKEEPER_MCP + // service binding). Any non-5xx response — including a structured + // 4xx for an unknown path — proves the gatekeeper worker deployed + // and the router reaches it. (Plain client: 404 here is a real + // answer, not a cold-start signal, and the edge is already warm from + // the previous tests.) + const response = yield* client.get(`${url}/gatekeeper/mcp/connect`); + expect(response.status).toBeLessThan(500); + }), +); diff --git a/packages/alchemy/tsconfig.json b/packages/alchemy/tsconfig.json new file mode 100644 index 00000000..5ce48687 --- /dev/null +++ b/packages/alchemy/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "target": "ES2022", + "lib": ["esnext"], + "module": "ESNext", + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "types": ["node"] + }, + "include": ["src", "examples", "alchemy.run.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/alchemy/vitest.config.ts b/packages/alchemy/vitest.config.ts new file mode 100644 index 00000000..659192fa --- /dev/null +++ b/packages/alchemy/vitest.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["test/**/*.test.ts"], + // Live-cloud tests: one full OS deploy in beforeAll, destroyed in + // afterAll. Keep files sequential so two suites never deploy the same + // stage concurrently. + fileParallelism: false, + testTimeout: 180_000, + hookTimeout: 1_800_000, + }, +}); diff --git a/plans/alchemy-deploy.md b/plans/alchemy-deploy.md new file mode 100644 index 00000000..b273ac1a --- /dev/null +++ b/plans/alchemy-deploy.md @@ -0,0 +1,458 @@ +# Alchemy as the default deploy: the `OperatingSystem` resource + +*Status: **implemented** in `packages/alchemy` (npm name `cloudflare-os`) with a +dogfood stack at the repo-root `alchemy.run.ts`. Verified: package + stack +typecheck clean, and `alchemy plan` builds the full resource graph against the +real state store. Not yet verified: a live `alchemy deploy` end-to-end. +Reference clone of alchemy lives at `.alchemy-reference/` (git-excluded, not a +submodule).* + +## Goal + +Make deploying Cloudflare OS to your own account a single alchemy resource: + +```typescript +// alchemy.run.ts (in YOUR company's repo — no fork of cloudflare-os needed) +import * as Alchemy from "alchemy"; +import * as Cloudflare from "alchemy/Cloudflare"; +import * as Effect from "effect/Effect"; +import * as Config from "effect/Config"; +import { OperatingSystem } from "cloudflare-os"; +import GitHub from "@gadgets/github-gatekeeper/deploy"; +import Google from "@gadgets/google-gatekeeper/deploy"; +import HomeAssistant from "@gadgets/homeassistant-gatekeeper/deploy"; +import Mcp from "@gadgets/mcp-gatekeeper/deploy"; + +export default Alchemy.Stack( + "AcmeOS", + { providers: Cloudflare.providers(), state: Cloudflare.state() }, + Effect.gen(function* () { + const os = yield* OperatingSystem("OS", { + domain: "os.acme.com", + admins: ["sam"], + + auth: { + gatekeepers: ["google", "github"], // AUTH_GATEKEEPERS + disablePasswordAuth: true, + }, + + // Gatekeepers are plugins: each package OWNS its deployment manifest + // (exported from `/deploy`, plain data, no alchemy dependency). + // The core trio (context, scheduler, mcp) deploys by default. + gatekeepers: [ + GitHub({ + clientId: Config.string("GITHUB_CLIENT_ID"), + clientSecret: Config.redacted("GITHUB_CLIENT_SECRET"), + }), + Google({ + clientId: Config.string("GOOGLE_CLIENT_ID"), + clientSecret: Config.redacted("GOOGLE_CLIENT_SECRET"), + }), + Mcp({ enabled: false }), // opt OUT of a default + HomeAssistant(), // opt IN to a non-default zero-config gatekeeper + ], + + // presence of `ai` = gateway mode; the Gateway is provisioned, not referenced + ai: { + gateway: { cacheTtl: 60 }, // Cloudflare.AI.GatewayProps, verbatim + limits: { dailyLlmCallLimit: 200 }, // app-level per-user quotas (backend-enforced) + }, + }); + + return { url: os.url }; + }), +); +``` + +`bun alchemy deploy` provisions everything: 2+ KV namespaces, the R2 bucket, one Worker +per enabled gatekeeper, the workshop-backend Worker (browser rendering, worker loader, +Workers AI, DO migrations), the frontend build, and the router Worker with static assets +and the custom domain. `bun alchemy destroy` tears it all down. + +## Output attributes + +```typescript +const os = yield* OperatingSystem("OS", { ... }); + +os.url // public origin (https://os.acme.com or workers.dev URL) +os.router // the router Worker resource +os.backend // the workshop-backend Worker resource +os.gatekeepers // { github: Worker, google: Worker, context: Worker, ... } +os.blueprints, os.avatars // KV namespaces +os.blueprintContent // R2 bucket +``` + +Everything is a real alchemy resource, so users can compose further — e.g. point a +`Cloudflare.DNS.Record` at `os.url`, bind `os.backend` from their own Workers, or add +alerting on the router. + +## Class form (matching the `StaticSite`/`Worker` convention) + +```typescript +export default class OS extends OperatingSystem()("OS", { + domain: "os.acme.com", + admins: ["sam"], + gatekeepers: { context: true, scheduler: true }, +}) {} + +// elsewhere +const os = yield* OS; +``` + +## Gatekeepers: plugin functions, derived from wrangler.jsonc + +**Each gatekeeper is its own Worker** (unchanged from production: both runtimes +discover them by prefix-scanning `GATEKEEPER_*` service bindings — the README calls +them "drivers"). Each has a plugin function in +`packages/alchemy/src/gatekeepers/.ts` (one file per gatekeeper, exported from +`cloudflare-os/gatekeepers`), returning a `GatekeeperDeployment` manifest. + +> Placement note: the conservative choice for now is to keep these modules inside the +> `cloudflare-os` package rather than adding `deploy.ts` exports to the gatekeeper +> packages we don't own. Moving each module into its package so the gatekeeper owns +> its deployment is the natural follow-up proposal upstream. + +**Manifests are not copies of config that exists elsewhere.** The package's +`wrangler.jsonc` is the deploy contract, and the composite parses it at deploy time +(`src/wrangler.ts`, jsonc-parser) to derive the entry module, compatibility +date/flags, DO migrations, KV bindings, and vars — for gatekeepers, the backend, and +the router (including the contract-tested `run_worker_first` list). A manifest names +only what wrangler doesn't know: + +```typescript +// src/gatekeepers/github.ts — everything else derives from wrangler.jsonc +export const GitHub = (config: GitHubConfig): GatekeeperDeployment => ({ + name: "github", + package: "@gadgets/github-gatekeeper", + prebuild: "build:configurator", // the pre-build wrangler's build.command lacks + env: { CLIENT_ID: config.clientId, CLIENT_SECRET: config.clientSecret }, + secrets: ["CLIENT_ID", "CLIENT_SECRET"], +}); +``` + +`OperatingSystemProps.gatekeepers` is `GatekeeperDeployment[]`: + +- The core trio (`Context()`, `Scheduler()`, `Mcp()`) is merged in by default + (`defaultEnabled: true`); opt out with `Mcp({ enabled: false })`. A user entry with + the same `name` replaces a default. +- Credentialed gatekeepers install by being listed — their config functions require + the credentials, so **missing credentials are a type error**. +- `context` accepts `sharingDomain` (defaults to the `{PUBLIC_BASE_URL}` placeholder, + substituted at deploy time; the starter pins it to `"production"`). Manifest + `vendorProps` become the backend vendor binding's workerd `ctx.props`. +- `gatekeeper-email` ships no manifest (`NOT_INSTALLABLE`: needs a zone with Email + Routing). + +**Two ways to bring a custom gatekeeper** (`GatekeeperDeployment` is a union): + +1. **Packaged** — any package following the standard capnweb layout with a + `wrangler.jsonc`; the same derivation applies: + `Gatekeeper({ name: "custom", package: "custom-gatekeeper", env: {...} })`. +2. **Effectful** — any alchemy Worker, including Effect-native + `Cloudflare.Worker` classes; the Worker owns its build/bindings/DOs and the + composite only wires it in (`GATEKEEPER_*` bindings, `BASE_URL`, vendor props): + `Gatekeeper({ name: "jira", worker: Jira })`. + +Note on terms: **gadgets** (user-built apps) are not Workers at all — they run as +Dynamic Worker facets loaded at runtime by the backend through `LOADER`, invisible to +IaC. Gatekeepers are the deployed Workers. + +Typing follows alchemy doctrine: plain interfaces everywhere, `InputProps` applied +once at the `OperatingSystem` boundary (structure-determining props — `domain`, +`auth`, `gatekeepers`, `ai`, `backend`, `frontend` — are marked static, the +`StaticSite` idiom). + +## AI Gateway: provisioned, not referenced + +Gateway mode is pure IaC — the composite *provisions* the gateway and its access +token; the user never copies an id or pastes a pre-made token. The `ai` key itself is +the opt-in (omit it → BYOK mode, today's default): + +```typescript +ai: {} // gateway mode, defaults +ai: { + gateway: { cacheTtl: 60, spendLimits: { enabled: true, rules: [...] } }, + providers: { // keyed record of provider credentials + anthropic: Config.redacted("ANTHROPIC_API_KEY"), + openai: Config.redacted("OPENAI_API_KEY"), + }, + workersAi: "direct", // CF_AI_GATEWAY_WAI / _WAI_DIRECT + limits: { enableCloudflareLimits: true, dailyLlmCallLimit: 200 }, +} +ai: { gateway: myGateway } // BYO Cloudflare.AI.Gateway resource (still IaC) +``` + +`providers` is a record, not a string list, because the strings alone are only half the +story: `CF_AI_GATEWAY_PROVIDERS` is merely the *menu* the backend shows +(`ai-gateway.ts:37`), while the actual upstream credentials live on the gateway — +gateway-mode requests carry only `cf-aig-authorization` and no provider key +(`ai-models.ts`), so the gateway resolves each provider's key from its Secrets-Store- +backed **stored keys**. Today self-hosters set those up by hand in the dashboard; here +they're provisioned. From the record the composite derives: + +- `CF_AI_GATEWAY_PROVIDERS` ← the record's keys, joined +- `Cloudflare.SecretsStore.Store("KeyStore")` ← provisioned and attached to the + gateway as `storeId` +- one `Cloudflare.AI.ProviderKey` per entry (`defaultConfig: true`) — the key lives in + the Secrets Store, attached to the gateway, never bound into any Worker +- `workersAi` stays a separate flag: Workers AI authenticates with the gateway's own + account token, no stored key involved + +Two limit layers, deliberately distinct: + +- **`ai.gateway`** is `Cloudflare.AI.GatewayProps` verbatim (no re-typing) — Cloudflare + enforces these at the gateway: `rateLimiting*`, `spendLimits` cost caps, `cacheTtl`, + DLP, logpush, otel. +- **`ai.limits`** are app-level *per-user* quotas the gateway cannot express, enforced + by workshop-backend's billing/top-up flow (`docs/ai-gateway-billing.md`): + `ENABLE_CLOUDFLARE_LIMITS`, `DAILY_LLM_CALL_LIMIT`, `MINIMUM_CLOUDFLARE_BALANCE`. + +Under the hood (namespace `OS/AI/`): + +- `Cloudflare.AI.Gateway("Gateway", …)` — the gateway itself; `gatewayId` and + `accountId` are output attributes. +- `Cloudflare.ApiToken.AccountApiToken("GatewayToken", …)` scoped to the + **AI Gateway Run + AI Gateway Read** permission groups — the same pattern alchemy's + own `*Http` capability layers use to mint least-privilege tokens at deploy time. +- Backend env is wired entirely from those outputs: `CF_AI_GATEWAY` ← gateway id, + `CF_AI_GATEWAY_ACCOUNT_ID` ← gateway's account, `CF_AI_GATEWAY_API_TOKEN` ← the + minted token's secret value (deployed as `secret_text`), plus + `CF_AI_GATEWAY_PROVIDERS` / `CF_AI_GATEWAY_WAI` / `CF_AI_GATEWAY_WAI_DIRECT` from + the props. + +Destroy the stack and the gateway *and* its token are revoked with it. Omit `ai` +entirely and the OS runs in BYOK mode (per-user provider keys), unchanged from today. + +## What `OperatingSystem` closes over + +Following the `Cloudflare.Website.StaticSite` composite pattern: one function returning +an Effect, children declared under `Namespace.push(id)`, aggregate outputs returned. +Logical tree: + +``` +OS/ +├── Frontend Command.Build – vite build (VITE_CF_ACCESS_MODE from auth config) +├── Blueprints KV.Namespace +├── Avatars KV.Namespace +├── BlueprintContent R2.Bucket +├── Backend/ +│ ├── Blueprints Command.Build – build-format-blueprints.mjs (⚠ not in wrangler build.command today) +│ ├── BrowserRuntime Command.Build – build-browser-runtime.mjs +│ ├── Validate Command.Build – capnweb-validate build +│ └── Worker Cloudflare.Worker (async mode: main → .wrangler/validate/src/server.ts) +├── Gatekeepers/ +│ ├── GitHub/ +│ │ ├── Configurator Command.Build – build-gatekeeper-configurator.mjs +│ │ ├── Validate Command.Build – capnweb-validate build +│ │ └── Worker Cloudflare.Worker +│ └── … (one subtree per enabled gatekeeper; context/scheduler add build-app.mjs, +│ context adds its CONTEXT_COLLECTIONS KV.Namespace) +├── AI/ (only when `ai` is set) +│ ├── Gateway Cloudflare.AI.Gateway (storeId ← KeyStore) +│ ├── GatewayToken ApiToken.AccountApiToken (AI Gateway Run + Read) +│ ├── KeyStore SecretsStore.Store (only when `providers` is set) +│ └── Key AI.ProviderKey, one per `providers` entry +└── Router Cloudflare.Worker (assets: Frontend outdir, SPA fallback, + run_worker_first, custom domain) +``` + +Key wiring, all of which the exploration confirmed against `run-dev-server.js`, +`scripts/release/manifest-lib.mjs`, and the golden manifest: + +- **Backend env**: `BLUEPRINTS`/`AVATARS` (KV), `BLUEPRINT_CONTENT` (R2), `BROWSER` + (browser rendering), `LOADER` (worker loader), `WORKERS_AI` (always bound — webFetch's + toMarkdown needs it), `PUBLIC_BASE_URL`, `ADMINS`, auth vars + (`AUTH_GATEKEEPERS`, `DISABLE_PASSWORD_AUTH`, `CF_ACCESS_AUD/ISS`), the + `CF_AI_GATEWAY*` vars derived from the provisioned Gateway + token outputs (see the + AI Gateway section), limits vars, plus one `GATEKEEPER_*` service binding per gatekeeper at entrypoint + `GatekeeperVendor` (context additionally gets `props: { sharingDomain }`). +- **Router env**: `WORKSHOP_BACKEND` service binding, `GATEKEEPER_*` service bindings at + the default entrypoint, `ASSETS` from the frontend build with + `not_found_handling: "single-page-application"` and the `run_worker_first` list that + `packages/router/__tests__/router.test.ts` contract-tests. +- **Gatekeeper env**: `BASE_URL = ${PUBLIC_BASE_URL}/gatekeeper/`, + `CLIENT_ID`/`CLIENT_SECRET` secrets where applicable, per-gatekeeper extras + (`MCP_ALLOW_INSECURE`, portal vars, zoominfo URL overrides). +- **Compat flags/dates and Text-module rules** copied per worker from today's + wrangler.jsonc files (`allow_irrevocable_stub_storage`, `nodejs_als`/`nodejs_compat`, + `global_fetch_strictly_public`, `enhanced_error_serialization`; + `rules: [{ type: "Text", globs: ["**/*.txt", "**/*.svg"] }]`). +- **DO migrations**: full ordered history per worker (backend v0–v2, google v0–v3, + etc.), derived from declared DO classes. +- **`PUBLIC_BASE_URL`**: `https://${domain}` when `domain` is set; otherwise the + router's workers.dev URL, which alchemy can resolve *before* upload (account + subdomain + deterministic worker name — same machinery as `Cloudflare.Worker.URL`), + so the router→gatekeeper URL "cycle" never actually materializes. +- **Builds are memoized** via `Command.Build`'s content-hash `memo` (include each + package's `src/**` + the shared packages it imports + the lockfile), so re-deploys + with no changes skip straight through — same behavior as the release pipeline's + content-addressed manifest, but for free from the alchemy engine. + +## Package + +New public package in this monorepo: + +``` +packages/alchemy/ +├── package.json name: "cloudflare-os" (bikeshed below) +├── scripts/ +│ └── fix-text-modules.mjs post-build shim: .svg → .svg.txt Text modules +├── src/ +│ ├── index.ts exports OperatingSystem, Gatekeeper, Gatekeepers ns +│ ├── OperatingSystem.ts the composite + AI subtree + backend/router/frontend +│ ├── Gatekeeper.ts GatekeeperDeployment union (packaged | worker) + helper +│ ├── gatekeepers/ one plugin module per built-in (google.ts, github.ts, …) +│ ├── wrangler.ts wrangler.jsonc reader (the deploy contract, derived) +│ └── paths.ts package-dir resolution (user project first, then own deps) +└── tsconfig.json +``` + +No other package in the monorepo is touched. + +Caller extension points on `OperatingSystemProps` (driven by the starter repo's +needs): `backend.env` (extra backend bindings/vars), `backend.services` (service +bindings with named entrypoint + `ctx.props`, e.g. the starter's private +`ERROR_REPORTER`), and `frontend.env` (extra vite build env, e.g. +`VITE_FRONTEND_ERROR_REPORTING`). + +- `alchemy` and `effect` are **peer dependencies**. The workspace packages + (`@gadgets/workshop-backend` etc.) are regular dependencies so `main:` entrypoints + and build scripts resolve from `node_modules` in the consumer's repo — this is what + lets a company deploy *without forking cloudflare-os* and still ride `pnpm update`. +- The repo root also gets its own thin `alchemy.run.ts` (dogfood: deploys this repo's + checkout, replacing the starter-repo flow for source users). + +Name bikeshed (pick one): + +| option | import | notes | +|---|---|---| +| `cloudflare-os` (recommended) | `from "cloudflare-os"` | matches the product name; cleanest | +| `@cloudflare/os` | `from "@cloudflare/os"` | needs the org scope; likely fine for CF | +| `@gadgets/alchemy` | `from "@gadgets/alchemy"` | matches current internal scope, but `@gadgets` reads as placeholder | + +## Upstream punch list (alchemy) — verified against 2.0.0-beta.67 + +What the implementation confirmed, with the workaround each item ships with: + +1. ~~**Named-entrypoint service bindings.**~~ **Landed upstream** as + `Cloudflare.WorkerEntrypoint` + ([alchemy#1097](https://github.com/alchemy-run/alchemy/pull/1097)): the + composite now declares vendor bindings as plain typed `env` entries + (`Backend/GATEKEEPER_*` rows), the router was moved ahead of the backend + so `PUBLIC_BASE_URL` rides `env` too, and the router's own service + bindings close the cycle via `bind`. Until a release ships, the repo + consumes a **local build** through `pnpm-workspace.yaml` overrides + (`file:` tarballs in `.alchemy-reference/` for alchemy + its + not-yet-published `@distilled.cloud/*` deps) — drop the overrides block + when the npm release lands. Still pending: **`props` on live uploads** + (workerd `ctx.props`; `gatekeeper-context` reads `sharingDomain` from it) + — typed and delivered in `alchemy dev`, dropped at encode on live + deploys until the distilled `workers` Smithy patch adds the field. +2. **Wrangler-style Text module rules in bundle mode.** The rolldown plugin + hardcodes Text = `.txt/.html/.sql`; every OAuth gatekeeper imports its logo + `.svg` as a Text module. → make `WorkerProps.rules` feed the bundler (and + add `.svg` to `contentTypeForModule`). *Workaround in place: + `scripts/fix-text-modules.mjs` rewrites `.svg` imports to `.svg.txt` in the + capnweb-validate output.* +3. **`Input<>` distribution over `WorkerAssetsConfig`.** Output-valued + `directory`/`hash` fail structural matching against the assets union — + `StaticSite` casts, and so does `OperatingSystem`. → fix the union's Input + distribution. +4. **Binding-less hosted DO classes** (nice-to-have). All cloudflare-os DOs are + reached via `ctx.exports`; the implementation declares a namespace binding + per class (harmless, unused) purely to drive migrations. A + `durableObjects: [...]` Worker prop would drop the fake bindings. +5. **`Command` should warn on shell syntax without `shell: true`.** A command + like `a && b` without the `shell` prop is argv-parsed, so `&&` reaches the + first program as a literal argument — the chain silently truncates to its + first step and exits 0. The live e2e caught this as a baffling + `OutputNotFound`; a warning (or shell auto-detection) when the command + contains `&&`/`||`/`|`/`;` would kill the trap. *Fixed here by passing + `shell: true` on every chained build.* +6. **Decorator lowering in the bundler.** capnweb-validate output uses TC39 + class decorators; wrangler's esbuild lowers them, but alchemy's rolldown + emits them raw and workerd rejects the syntax + (`ScriptStartupError: Invalid or unexpected token`). Enable oxc's + decorator transform in the worker bundle pipeline. *Worked around here: + `scripts/prepare-worker-tree.mjs` esbuild-transforms the validate tree in + place (also handles the `.svg` Text rename), found by the live e2e.* +7. **`main` must be static at precreate.** Routing `main` through a build + Output (for sequencing) crashes the precreate stub + (`isPythonMain` reads an unresolved value). Either support Input `main` + at precreate or document the pattern: keep `main` static and sequence + builds through an env Output (`BUILD_HASH` here). +8. **Effect workers can't export custom named entrypoints.** The Effect + virtual entry emits only the default entrypoint + DO/Workflow classes, + so a pure Effect worker cannot satisfy a `GatekeeperVendor`-style named + `WorkerEntrypoint` binding. Wanted: (a) arbitrary named-entrypoint + exports on `Cloudflare.Worker`, and (b) longer-term, a capnweb↔Effect + bridge — capability-passing RPC maps naturally onto Effect (stubs as + Scope-managed resources). Until then, Effect-style gatekeepers use a + hybrid entry: a plain `GatekeeperVendor extends WorkerEntrypoint` whose + method bodies run Effect via a ManagedRuntime. + +## Testing + +Live end-to-end coverage lives at +`packages/alchemy/test/OperatingSystem.test.ts`, built on **alchemy's own +test harness** (`alchemy/Test/Vitest` — the published vitest adapter of the +`Test.make({ providers, state })` pattern from alchemy's AGENTS.md): + +- `beforeAll(deploy(Stack))` deploys a full default OS (no domain, password + auth, the default-on gatekeepers) to the real account; `afterAll(destroy)` + tears it down (`NO_DESTROY=1` keeps it for iteration). +- Assertions ride alchemy's `getWhenReady` helper (retries through the + workers.dev cold-start window, but lets deliberate 4xx through): + `/` serves the SPA shell (router assets + vite build), `/api` answers + non-5xx (router → backend service binding, backend booted with all + bindings), `/gatekeeper/mcp/*` answers non-5xx (router → gatekeeper + binding). +- Run with `pnpm --dir packages/alchemy test:e2e`. The script is + deliberately `test:e2e` (not `test`) so the repo's recursive `pnpm test` + never deploys to a real account by accident. +- Follow-up: drive the capnweb `PublicApi` over WebSocket (create an + account, run a prompt) for true interaction coverage. + +## Open questions + +1. **Adoption of existing deployments.** Instances deployed via os.cloudflare.app or + the starter repo have live DOs with migration tag history (`v0`…`vN`). Alchemy's + `--adopt` covers resource ownership; migration-tag alignment on the first + alchemy-managed PUT needs a test against a real legacy instance. +2. **`gatekeeper-slack` observability** is disabled today only because its + wrangler.jsonc lacks the stanza. Proposal: normalize (observability on for all + workers, one prop to opt out) rather than replicate the oversight. +3. **Ambient/admin config** (`AdminSettings` DO, provisioning policy) stays runtime + state, not IaC — deliberately out of scope for `OperatingSystem`. Confirm. +4. **`alchemy dev`** — phase 2. The local provider system (workerd-backed + `LocalWorkerProvider`) could eventually replace `run-dev-server.js`'s generated + `wrangler.dev.jsonc` fleet with the same `OperatingSystem` resource running locally. + Not in scope for the first cut, but the composite is designed so nothing blocks it. + +## The starter repo (cloudflare-os-starter) + +The starter's `deployment.jsonc` + `scripts/deploy.mjs` collapse into one +`alchemy.run.ts` (drafted in the local clone at +`~/workspaces/cloudflare-os-starter`, a separate repo needing its own commit): + +- `packages/custom-gatekeeper/deploy.ts` — the third-party plugin template; the + custom gatekeeper flows through the same `gatekeepers: [...]` list as built-ins. +- The private error reporter stays a caller-owned `Cloudflare.Worker`, bound via + `backend.services` with `entrypoint: "ErrorReporter"` + `ctx.props`. +- Access-mode sign-in via `auth.access`; context pinned to + `Context({ sharingDomain: "production" })`. +- Requires the submodule pin to include this repo's changes, plus + `cloudflare-os/packages/*` in the starter's pnpm workspace (replacing the current + two-package allowlist) and alchemy/effect devDependencies. +- Verified by typechecking an identical-shape stack against this repo's install + (the two-repo symlink check double-loads alchemy and is not meaningful). + +## Phasing + +1. **Alchemy PRs**: entrypoint+props service bindings; binding-less DO classes. +2. **`packages/alchemy`**: `Gatekeeper` + `OperatingSystem` + presets; root + `alchemy.run.ts`; deploy a real instance from this repo and diff the resulting + worker settings against the golden manifest (`scripts/testdata/golden-manifest.json`). +3. **Consumer template**: a `create-cloudflare-os` style starter (or update the + existing starter repo) whose entire content is `package.json` + `alchemy.run.ts` + + `.env.example`. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df0720a6..e5ba00b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,17 @@ settings: excludeLinksFromLockfile: false overrides: + alchemy: file:.alchemy-reference/alchemy-local.tgz + '@distilled.cloud/aws': file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz + '@distilled.cloud/cloudflare-runtime': file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz + '@distilled.cloud/cloudflare-rolldown-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz + '@distilled.cloud/cloudflare-vite-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz + '@distilled.cloud/cloudflare': file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz + '@distilled.cloud/axiom': file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz + '@distilled.cloud/neon': file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz + '@distilled.cloud/planetscale': file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz + wrangler: 4.115.0 workerd: '>=1.20260623.1' js-yaml@4.1.1: ^4.2.0 '@codemirror/commands': 6.10.3 @@ -33,8 +44,102 @@ importers: specifier: ^7.3.6 version: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) + + packages/alchemy: + dependencies: + '@gadgets/cloudflare-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-cloudflare + '@gadgets/confluence-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-confluence + '@gadgets/gatekeeper-context': + specifier: workspace:* + version: link:../gatekeeper-context + '@gadgets/gatekeeper-scheduler': + specifier: workspace:* + version: link:../gatekeeper-scheduler + '@gadgets/github-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-github + '@gadgets/google-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-google + '@gadgets/homeassistant-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-homeassistant + '@gadgets/linear-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-linear + '@gadgets/mcp-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-mcp + '@gadgets/mcp-portal-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-mcp-portal + '@gadgets/notion-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-notion + '@gadgets/router': + specifier: workspace:* + version: link:../router + '@gadgets/slack-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-slack + '@gadgets/spotify-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-spotify + '@gadgets/supabase-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-supabase + '@gadgets/workshop-backend': + specifier: workspace:* + version: link:../workshop-backend + '@gadgets/workshop-frontend': + specifier: workspace:* + version: link:../workshop-frontend + '@gadgets/zoominfo-gatekeeper': + specifier: workspace:* + version: link:../gatekeeper-zoominfo + alchemy: + specifier: file:../../.alchemy-reference/alchemy-local.tgz + version: file:.alchemy-reference/alchemy-local.tgz(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(@types/react@19.2.17)(effect@4.0.0-beta.103)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))(workerd@1.20260731.1)(ws@8.21.1) + esbuild: + specifier: ^0.28.1 + version: 0.28.1 + jsonc-parser: + specifier: ^3.3.1 + version: 3.3.1 + devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20260702.1 + version: 4.20260702.1 + '@effect/platform-node': + specifier: 4.0.0-beta.103 + version: 4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1) + '@effect/vitest': + specifier: 4.0.0-beta.103 + version: 4.0.0-beta.103(effect@4.0.0-beta.103)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + '@gadgets/workshop-shared': + specifier: workspace:* + version: link:../workshop-shared + '@types/node': + specifier: 26.1.0 + version: 26.1.0 + effect: + specifier: 4.0.0-beta.103 + version: 4.0.0-beta.103 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^4.1.10 + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + ws: + specifier: ^8.20.0 + version: 8.21.1 packages/backend-utils: dependencies: @@ -44,13 +149,13 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.16.20 - version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) '@cloudflare/workers-types': specifier: ^4.20260702.1 version: 4.20260702.1 vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) packages/configurator-ui: devDependencies: @@ -59,7 +164,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.2.4 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) packages/error-reporting: devDependencies: @@ -68,7 +173,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) packages/gatekeeper-cloudflare: dependencies: @@ -83,14 +188,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-confluence: dependencies: @@ -105,7 +210,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) node-html-parser: specifier: ^7.1.0 version: 7.1.0 @@ -115,10 +220,10 @@ importers: version: 5.9.3 vitest: specifier: ^3.2.7 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-context: dependencies: @@ -139,7 +244,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) isomorphic-git: specifier: ^1.40.0 version: 1.40.0 @@ -200,7 +305,7 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^4.7.0 - version: 4.7.0(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.7.0(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) emoji-mart: specifier: ^5.6.0 version: 5.6.0 @@ -212,10 +317,10 @@ importers: version: 19.2.8(react@19.2.8) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.2.17)(react@19.2.8)(supports-color@10.2.2) + version: 10.1.0(@types/react@19.2.17)(react@19.2.8) remark-gfm: specifier: ^4.0.1 - version: 4.0.1(supports-color@10.2.2) + version: 4.0.1 tailwindcss: specifier: ^4.3.3 version: 4.3.3 @@ -233,13 +338,13 @@ importers: version: 2.3.3(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(supports-color@10.2.2)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) vitest: specifier: ^3.2.7 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-email: dependencies: @@ -257,7 +362,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) postal-mime: specifier: ^2.7.5 version: 2.7.5 @@ -266,8 +371,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-github: dependencies: @@ -285,14 +390,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-google: dependencies: @@ -310,7 +415,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) mimetext: specifier: ^3.0.28 version: 3.0.28 @@ -322,8 +427,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-homeassistant: dependencies: @@ -338,14 +443,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-linear: dependencies: @@ -363,14 +468,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-mcp: dependencies: @@ -391,17 +496,17 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 vitest: specifier: ^3.2.4 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.92.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-mcp-portal: dependencies: @@ -422,17 +527,17 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 vitest: specifier: ^3.2.4 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.92.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-notion: dependencies: @@ -447,17 +552,17 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 vitest: specifier: ^3.2.7 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-scheduler: dependencies: @@ -475,7 +580,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) temporal-polyfill: specifier: 1.0.2 version: 1.0.2 @@ -485,7 +590,7 @@ importers: version: 2.9.0(@date-fns/tz@1.5.0)(@phosphor-icons/react@2.1.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3) '@cloudflare/vitest-pool-workers': specifier: ^0.16.20 - version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) '@cloudflare/workers-types': specifier: ^4.20260702.1 version: 4.20260702.1 @@ -506,10 +611,10 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^4.7.0 - version: 4.7.0(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.7.0(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) jsdom: specifier: ^26.1.0 - version: 26.1.0(supports-color@10.2.2) + version: 26.1.0 miniflare: specifier: 4.20260625.0 version: 4.20260625.0 @@ -536,10 +641,10 @@ importers: version: 2.3.3(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(supports-color@10.2.2)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) packages/gatekeeper-slack: dependencies: @@ -554,14 +659,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-spotify: dependencies: @@ -576,14 +681,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-supabase: dependencies: @@ -601,14 +706,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/gatekeeper-zoominfo: dependencies: @@ -623,14 +728,14 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) devDependencies: typescript: specifier: ^5.9.3 version: 5.9.3 wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/integration-tests: dependencies: @@ -658,10 +763,10 @@ importers: version: 5.9.3 vitest: specifier: ^3.2.4 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) wrangler: - specifier: ~4.104.0 - version: 4.104.0(@cloudflare/workers-types@4.20260702.1) + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@4.20260702.1) packages/mcp-shared: dependencies: @@ -683,13 +788,13 @@ importers: version: 5.9.3 vitest: specifier: ^3.2.4 - version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + version: 3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) packages/router: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.16.18 - version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + version: 0.16.20(@cloudflare/workers-types@5.20260804.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) jsonc-parser: specifier: ^3.3.1 version: 3.3.1 @@ -698,34 +803,34 @@ importers: version: 5.9.3 vitest: specifier: ^4.1.9 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) wrangler: - specifier: ^4.103.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/typed-storage: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.16.20 - version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + version: 0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) '@cloudflare/workers-types': specifier: ^4.20260702.1 version: 4.20260702.1 vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) packages/workshop-backend: dependencies: '@cloudflare/puppeteer': specifier: ^1.2.0 - version: 1.2.0(supports-color@10.2.2) + version: 1.2.0 '@earendil-works/pi-agent-core': specifier: 0.83.0 - version: 0.83.0(supports-color@10.2.2)(ws@8.21.1)(zod@4.4.3) + version: 0.83.0(ws@8.21.1)(zod@4.4.3) '@earendil-works/pi-ai': specifier: 0.83.0 - version: 0.83.0(supports-color@10.2.2)(ws@8.21.1)(zod@4.4.3) + version: 0.83.0(ws@8.21.1)(zod@4.4.3) '@gadgets/backend-utils': specifier: workspace:* version: link:../backend-utils @@ -743,7 +848,7 @@ importers: version: 0.8.0 capnweb-validate: specifier: 0.2.1 - version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) diff: specifier: ^8.0.4 version: 8.0.4 @@ -756,7 +861,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.16.20 - version: 0.16.20(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + version: 0.16.20(@cloudflare/workers-types@5.20260804.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) esbuild: specifier: ^0.28.1 version: 0.28.1 @@ -765,10 +870,10 @@ importers: version: 5.9.3 vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) wrangler: - specifier: ^4.115.0 - version: 4.115.0 + specifier: 4.115.0 + version: 4.115.0(@cloudflare/workers-types@5.20260804.1) packages/workshop-frontend: dependencies: @@ -810,16 +915,16 @@ importers: version: 19.2.8(react@19.2.8) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.2.17)(react@19.2.8)(supports-color@10.2.2) + version: 10.1.0(@types/react@19.2.17)(react@19.2.8) remark-gfm: specifier: ^4.0.1 - version: 4.0.1(supports-color@10.2.2) + version: 4.0.1 tailwindcss: specifier: ^4.3.3 version: 4.3.3 vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(supports-color@10.2.2)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) y-monaco: specifier: ^0.1.6 version: 0.1.6(monaco-editor@0.52.2)(yjs@13.6.31) @@ -832,7 +937,7 @@ importers: devDependencies: '@tanstack/router-plugin': specifier: ^1.168.23 - version: 1.168.23(@tanstack/react-router@1.170.18(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(esbuild@0.28.1)(rollup@4.62.3)(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 1.168.23(@tanstack/react-router@1.170.18(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) '@types/react': specifier: ^19.2.17 version: 19.2.17 @@ -841,10 +946,10 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^4.7.0 - version: 4.7.0(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.7.0(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) jsdom: specifier: ^26.1.0 - version: 26.1.0(supports-color@10.2.2) + version: 26.1.0 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -853,7 +958,7 @@ importers: version: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) packages/workshop-shared: dependencies: @@ -870,6 +975,13 @@ importers: packages: + '@alcalzone/ansi-tokenize@0.2.5': + resolution: {integrity: sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw==} + engines: {node: '>=18'} + + '@alchemy.run/node-utils@0.0.5': + resolution: {integrity: sha512-5agdhQxWBodxa5hDRyjnpx91RTU3g+qd5fxYB7uNDCaOzB0XC47UU/KHR6zf6jhz/NXf61gJS+vhYwn8NHeRoQ==} + '@anthropic-ai/sdk@0.91.1': resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==} hasBin: true @@ -882,6 +994,10 @@ packages: '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + '@aws-crypto/sha256-browser@5.2.0': resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} @@ -906,30 +1022,69 @@ packages: Deprecated due to Document number parsing bug in JSON, see https://github.com/aws/aws-sdk-js-v3/issues/8246. Newer version available. + '@aws-sdk/core@3.977.5': + resolution: {integrity: sha512-O5otOc1c6UZh5HsHAaPdYBcUUR9HL6mtnKqvc8nxN/CKDGUBUpsdh0q8K04Uz/dd1i0TaGyIQuQNqoO7+ad2TQ==} + engines: {node: '>=20.0.0'} + deprecated: |- + Deprecated due to Document number parsing bug in JSON, see + https://github.com/aws/aws-sdk-js-v3/issues/8246. Newer version available. + + '@aws-sdk/credential-provider-cognito-identity@3.972.65': + resolution: {integrity: sha512-1DfK/WvYHlalaejpsmG+oQESu5QC06ylhIgSH8YUt+ZHJdh7/bJsQDVUpbN+tE9GkJG7id+m3+nop+oEw2m9Rw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-env@3.972.65': resolution: {integrity: sha512-lJT2aRw9wCV8jPHyFJjdZLD4HTydL6/22AnCSOB8e/LqOc55nEJGLHkJQeSxhn8QiqyjFwPKQFtMw0ovjRUY/g==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-env@3.972.66': + resolution: {integrity: sha512-bOzP2+zdJ0XrghywB4FaJXtGZCx9yS0AGps+VJ5yEgg30wVyHNmVDBwVDXcRypzQY5iLGCS3NSn0nsuISqjFCQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.67': resolution: {integrity: sha512-N7fw/15hSwI/CPxe5ohOyb7O4ge9f5me1gVIn8OIkBRB0squ8OJqQyDyH/HoL+Sb1W5xdC88jVC+bHkw73iu+Q==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.68': + resolution: {integrity: sha512-lkunS8X+H6V76WE+t/uGQm/U8v0JXK5mLfNFTUAMlE1kqaCjwlmqKJrgCVtqjK/vqnlrSWsLK4Lr4NANBWlfTQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.973.10': resolution: {integrity: sha512-Zh9XRaPnDN9buO7GfWBubS22R6Nq5D6hbyYEMN05LiOnXugm/8WDjUx6y756bSPbdn3aJB2qG4zFW3bN82QhoQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.973.11': + resolution: {integrity: sha512-KoDEolYtLHG/8C+IiZpXbJWyBOMkrHV+j66Kb9PBXmLv5euGb7aELvuCmLenoGAV6gBW2wM7TsG/1e5iulH4kA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.72': resolution: {integrity: sha512-zZapIKwaHp7TdTf9hbH1I3CVUdEupmt7FXO/BoTQGC+4h6NkXKWpqF2p5WyfpjurDLHCpSyh+BzMlAg8arqWLA==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.73': + resolution: {integrity: sha512-tjsxMkTAFkmiV9ycmymapb9nLECWVOwFs0bZMQ9gB9bnbY8/HwfukHZlWbXZZp7qkPU6EXAfOcMm3DioFFEywA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.76': resolution: {integrity: sha512-1yzLmRiYSgGC25v7ZZEwJn/auhHHTIHgFOmzL2f36hf1+7jSLcX+1QrAz4760WEzPiiQl8xmlpFhHfl2OoyVzA==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.77': + resolution: {integrity: sha512-l4nitYCN/Ls57vtUfdextCjTjW41JD7lQiAnuR0RTbdByFc/6OmEAzwGd+lrp6CUtiXGQL1FCaYiamfHASrwBw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.65': resolution: {integrity: sha512-e5DbbNteOSalN58U83G6kFa4ECLEuGbGqNBHIXE7zYXA/m4GHblIGjFbSH7wYv6gBV8iNSDcRZBKfQZF5vF9nw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.66': + resolution: {integrity: sha512-YOnX6bIhdjx0QfaENu2PB0eFm5MEc9ft8XNGQ+NxMfeLSq9aE+XjWCwDupEnV4UWv5ZFpBLJbTREIx7KNOoqpQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.973.10': + resolution: {integrity: sha512-IsXnQ35j5VE+3ZK6aIhT5ypB+Jim3zRwVz0nYuVwyBKZyu/SYx+O2/LQpng8c2EiuwyqceabsDlYrICHDlJPsA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-sso@3.973.9': resolution: {integrity: sha512-0V0u4t+KBku9fbh5CPCaC5hUWwSzDafp8nCuDy817zWbp2gz80jO44rMQkiwnZ+k54B+tjAtzRy00DJRGTKGBg==} engines: {node: '>=20.0.0'} @@ -938,6 +1093,14 @@ packages: resolution: {integrity: sha512-e4dwiRltGAaQ+2yxw57Hj0l/BF3BHiG14+QpYE7bGYBlpAq/fkIri2BDhjWon8c0mhhtd2txQBAkQb9BcTStFg==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-web-identity@3.972.72': + resolution: {integrity: sha512-nj9Zlsy7ya+fy+jhWTJwgfr7YdtDM4xHyZvgKuftuny0UgROVx9lxwvsWJSLvpKk4lig0m0tHng3k1fEnt0LeA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-providers@3.1102.0': + resolution: {integrity: sha512-CGSqj/g324UXVPTb29RQN/ihrm4etVvQywKMSPTjPEs4tTSbrQnDXJQBzswDDzA/K5H4ZVU8rwXsebLhrlNLCA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/eventstream-handler-node@3.972.31': resolution: {integrity: sha512-/BRzvkp46mF6eXBL/l9WKPQQfifLlUPaWli6n9/T/WDLUg8he7TCyuNFnk6RvHP5j5W/kMj5Gxw7W778LJaXDA==} engines: {node: '>=20.0.0'} @@ -954,6 +1117,10 @@ packages: resolution: {integrity: sha512-wU5NPnj62Sb7A8xn/Zb+xThe05P3otNtDl37iOIi5DDMeCesNeCckaG+eXWGUs12Z9R34I8CD05TaTe6SIa61g==} engines: {node: '>=20.0.0'} + '@aws-sdk/nested-clients@3.997.40': + resolution: {integrity: sha512-hEdHT0PBR4fkGxWhwKG5EtEYKnAM7HKkp0vD10ufk4YcXejH4r4q6G/XhPzjUc6Yxo5kBS2vHg7llj4ViR9VTQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/signature-v4-multi-region@3.996.43': resolution: {integrity: sha512-lKekx8bLBXSv4O+cslk9Zfnw2XKSkWBs3uWL5QGhH2ZAQfNS7FE0vcSSN2vD/AhxX54ZTywWxR4STThoeOXlBA==} engines: {node: '>=20.0.0'} @@ -966,6 +1133,10 @@ packages: resolution: {integrity: sha512-THf3MkgY3fNJZ3zdgSenLqR7gSE68KccCj1RCKretlG73Ppszvues02VpCUO9NlB/tZDC483FvGCld+AiPCkvg==} engines: {node: '>=20.0.0'} + '@aws-sdk/token-providers@3.1102.0': + resolution: {integrity: sha512-Ua700vVvM1q105yABSUQWkCK6FeTrNfU6ORGetJe5BzkZWY7QhkF7SVTOlmDGWRDNd6jbyY0Dv5e+E4bMBEmLg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/types@3.974.2': resolution: {integrity: sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==} engines: {node: '>=20.0.0'} @@ -1100,8 +1271,28 @@ packages: '@types/react': optional: true + '@chevrotain/cst-dts-gen@10.5.0': + resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} + + '@chevrotain/gast@10.5.0': + resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} + + '@chevrotain/types@10.5.0': + resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} + + '@chevrotain/utils@10.5.0': + resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} + + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + '@cloudflare/kumo@2.9.0': - resolution: {integrity: sha512-WkJNwJrT/VDfBFckscrhnxKbAu9hRC/iWxzUB4tWu1OAHo3hx4PQ0cbT6wxoye54jns6m13Acq7SIzw5uY0Qcw==, tarball: https://registry.npmjs.org/@cloudflare/kumo/-/kumo-2.9.0.tgz} + resolution: {integrity: sha512-WkJNwJrT/VDfBFckscrhnxKbAu9hRC/iWxzUB4tWu1OAHo3hx4PQ0cbT6wxoye54jns6m13Acq7SIzw5uY0Qcw==} hasBin: true peerDependencies: '@phosphor-icons/react': ^2.1.10 @@ -1116,15 +1307,15 @@ packages: optional: true '@cloudflare/kv-asset-handler@0.5.0': - resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==, tarball: https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz} + resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} engines: {node: '>=22.0.0'} '@cloudflare/puppeteer@1.2.0': - resolution: {integrity: sha512-2DKqSnB/TWVuoLTQzK5t0tQEoI+YGQYt/UisHCVr2fpW34D0H20n4HRmvtj/iVZDw0q2Y6LTqfEFh8ps9G/TiA==, tarball: https://registry.npmjs.org/@cloudflare/puppeteer/-/puppeteer-1.2.0.tgz} + resolution: {integrity: sha512-2DKqSnB/TWVuoLTQzK5t0tQEoI+YGQYt/UisHCVr2fpW34D0H20n4HRmvtj/iVZDw0q2Y6LTqfEFh8ps9G/TiA==} engines: {node: '>=18'} '@cloudflare/unenv-preset@2.16.1': - resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==, tarball: https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz} + resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} peerDependencies: unenv: 2.0.0-rc.24 workerd: '>=1.20260623.1' @@ -1133,44 +1324,47 @@ packages: optional: true '@cloudflare/vitest-pool-workers@0.16.20': - resolution: {integrity: sha512-buw0YgsAMT7s60wcmyxbtciEJjMJzKcWzayDMPhWaqMqfQzW+0WPLV67Lobn4C80nkNQhYocEJPnrEhLWnOf+A==, tarball: https://registry.npmjs.org/@cloudflare/vitest-pool-workers/-/vitest-pool-workers-0.16.20.tgz} + resolution: {integrity: sha512-buw0YgsAMT7s60wcmyxbtciEJjMJzKcWzayDMPhWaqMqfQzW+0WPLV67Lobn4C80nkNQhYocEJPnrEhLWnOf+A==} peerDependencies: '@vitest/runner': ^4.1.0 '@vitest/snapshot': ^4.1.0 vitest: ^4.1.0 '@cloudflare/workerd-darwin-64@1.20260731.1': - resolution: {integrity: sha512-+fw/+9EinH1teyOM3IqdqNrmtrW4Ve20iyG6V4vPR9UhUkxTPQvffg8LXf/IFwdEBUfUTHXHX2W+qiGC1SXUzQ==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260731.1.tgz} + resolution: {integrity: sha512-+fw/+9EinH1teyOM3IqdqNrmtrW4Ve20iyG6V4vPR9UhUkxTPQvffg8LXf/IFwdEBUfUTHXHX2W+qiGC1SXUzQ==} engines: {node: '>=16'} cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20260731.1': - resolution: {integrity: sha512-6LisxhmgX7Vb948xZpaM1o2o4liknkh881XwNzNf8c6fsA+Wi6BMbxq2uqd+Tnluo+tVxt91dNt9nE0E1VWFhg==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260731.1.tgz} + resolution: {integrity: sha512-6LisxhmgX7Vb948xZpaM1o2o4liknkh881XwNzNf8c6fsA+Wi6BMbxq2uqd+Tnluo+tVxt91dNt9nE0E1VWFhg==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] '@cloudflare/workerd-linux-64@1.20260731.1': - resolution: {integrity: sha512-jKU3YvgGkt84ppRLnQQjM+x4kh6+fAz1or4emiCw2upV4a4lQNvvdgOi9x1fshLzKsvGyRoZHWI9+QgzNPZTQA==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260731.1.tgz} + resolution: {integrity: sha512-jKU3YvgGkt84ppRLnQQjM+x4kh6+fAz1or4emiCw2upV4a4lQNvvdgOi9x1fshLzKsvGyRoZHWI9+QgzNPZTQA==} engines: {node: '>=16'} cpu: [x64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20260731.1': - resolution: {integrity: sha512-ajVOENiXNH4/5GwQ/BDSsTemjWFZmuGENhknv6ti1Efwj8JqBeSAUEwcQB73syjN+NtVb21GpEMox8VNex7Meg==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260731.1.tgz} + resolution: {integrity: sha512-ajVOENiXNH4/5GwQ/BDSsTemjWFZmuGENhknv6ti1Efwj8JqBeSAUEwcQB73syjN+NtVb21GpEMox8VNex7Meg==} engines: {node: '>=16'} cpu: [arm64] os: [linux] '@cloudflare/workerd-windows-64@1.20260731.1': - resolution: {integrity: sha512-kf6LFxWRnZ2x0psXsmENSxwuBCFg59HilUQy07VCIfeEGeW89KfCvZxngBBmkYAXN9EpkTL3RY87ZxmjRaONsw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260731.1.tgz} + resolution: {integrity: sha512-kf6LFxWRnZ2x0psXsmENSxwuBCFg59HilUQy07VCIfeEGeW89KfCvZxngBBmkYAXN9EpkTL3RY87ZxmjRaONsw==} engines: {node: '>=16'} cpu: [x64] os: [win32] '@cloudflare/workers-types@4.20260702.1': - resolution: {integrity: sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==, tarball: https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz} + resolution: {integrity: sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==} + + '@cloudflare/workers-types@5.20260804.1': + resolution: {integrity: sha512-B1dwxpN6e5RZXZkE5zpZj+ooNeNZ1mwavLIyHDYe10ojhlGTwDfe8sAl7R1mMXc1cyIsbr+jKVdvmMEyVcdTdg==} '@codemirror/autocomplete@6.20.3': resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==} @@ -1243,6 +1437,76 @@ packages: '@date-fns/tz@1.5.0': resolution: {integrity: sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==} + '@distilled.cloud/aws@file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz': + resolution: {integrity: sha512-RZcv6if7uUFgXNJfQOxZsWpOKhvIhMk+D1B3UDFY9gaWLHenwtrLnUS2QU7vspzyyXOVPMCa1zuxGv5LNTJJOA==, tarball: file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz} + version: 0.29.1 + peerDependencies: + effect: '>=4.0.0-beta.102 || >=4.0.0' + + '@distilled.cloud/axiom@file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz': + resolution: {integrity: sha512-j2ZPrxiYklUmvNbBAXiPhqfrwiQlWRvuJqc+65AybnD2Nui6+QfZwc6VwBJ5xnZr7p/Hh3vsgfG46w9S8w04+Q==, tarball: file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz} + version: 0.31.0 + + '@distilled.cloud/cloudflare-rolldown-plugin@file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz': + resolution: {integrity: sha512-QDyEhqE1sIqt6jP2Q85c7C7mWrKzIDvXcGEe8oBmUZnKjlY0p1ZJQ+6BHQOAuojQNPMtW89qizqGXY9OOk4u4w==, tarball: file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz} + version: 0.15.0 + peerDependencies: + rolldown: ~1.1.5 + vite: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + rolldown: + optional: true + vite: + optional: true + + '@distilled.cloud/cloudflare-runtime@file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz': + resolution: {integrity: sha512-LAXLhy6HviGMmC3t03bTyFcMcMP2CukasPYhmy/BhK+EHOMKu+3oxSUk1d7fgpF79w/luVHC4aHvt6Z9Mzjk5g==, tarball: file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz} + version: 0.15.0 + peerDependencies: + '@distilled.cloud/cloudflare': ^0.30.3 + '@effect/platform-bun': '>=4.0.0-beta.102 || >=4.0.0' + '@effect/platform-node': '>=4.0.0-beta.102 || >=4.0.0' + effect: '>=4.0.0-beta.102 || >=4.0.0' + peerDependenciesMeta: + '@effect/platform-bun': + optional: true + '@effect/platform-node': + optional: true + + '@distilled.cloud/cloudflare-vite-plugin@file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz': + resolution: {integrity: sha512-p/Jw3OOFNOI4+/U+1DjmL8nYjNxaXMk0AC9hkwK07Z63WFvLk7PS0OHM0cuEG0KkN3rlz+udEvznNGr8P6YqeA==, tarball: file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz} + version: 0.15.0 + peerDependencies: + '@distilled.cloud/cloudflare': ^0.30.3 + '@distilled.cloud/cloudflare-runtime': 0.15.0 + '@effect/platform-bun': '>=4.0.0-beta.102 || >=4.0.0' + '@effect/platform-node': '>=4.0.0-beta.102 || >=4.0.0' + effect: '>=4.0.0-beta.102 || >=4.0.0' + vite: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@effect/platform-bun': + optional: true + '@effect/platform-node': + optional: true + + '@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz': + resolution: {integrity: sha512-e6Gl8TNzhgZzdznplwv8LpAlDo8t/qonkx4O9lyPZG3zw7HcPWMI1sFbzH+hDUU+rUPx42I6O+W3XFGh3l0CUQ==, tarball: file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz} + version: 0.0.0 + + '@distilled.cloud/core@file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz': + resolution: {integrity: sha512-MsElmo2qHW1No/dEuMyUG5HAzmKgcQhiu+hz92iwvyDSdrr1OnG0sQ6L/BSIM5sGMRpjbAUTIkXafKtZ2M18Lg==, tarball: file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz} + version: 0.0.0 + peerDependencies: + effect: '>=4.0.0-beta.102 || >=4.0.0' + + '@distilled.cloud/neon@file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz': + resolution: {integrity: sha512-hiolPjT2oT32OJAWw6eom4+m7BZwbHdVFxM9bUVl7vthaA+fZ7n2imuW7Ur2TDqc4ZWZU4tj9CK0DhxjBdH6Cw==, tarball: file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz} + version: 0.31.0 + + '@distilled.cloud/planetscale@file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz': + resolution: {integrity: sha512-avw5DaGLQ24ExhxHsvXduWpn6tDR/E2i3jSL1LbibBOtGng0QfrlxPyoHU40lCSUhp+V380xqk0MiuVTvX4p8w==, tarball: file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz} + version: 0.31.0 + '@earendil-works/pi-agent-core@0.83.0': resolution: {integrity: sha512-RorGp9OH5l3ElpuC5a5ZQ2eWcchZGXflXRzVGkV99y3y6tT+LLNyxoYIdVKvTKWEObwhExeQbTH0fI2tE4iX4g==} engines: {node: '>=22.19.0'} @@ -1252,9 +1516,66 @@ packages: engines: {node: '>=22.19.0'} hasBin: true + '@effect/platform-bun@4.0.0-beta.103': + resolution: {integrity: sha512-/ay1/lhE9FUKEiDRQs56463eJ9u9ivtUtOCi2eeqI8Aooau7PupKNtV5zKjoRBCLInZMAX7JezT46NW5AdACBQ==} + peerDependencies: + effect: ^4.0.0-beta.103 + + '@effect/platform-node-shared@4.0.0-beta.103': + resolution: {integrity: sha512-0aCZMBid5ifqmY55TkfCDLaGTIM8qu3bNFUW7qL9vh/7jFOkaIAMX2MA8muG4deqW17XWxawddWu4v0fK+UW3g==} + engines: {node: '>=18.0.0'} + peerDependencies: + effect: ^4.0.0-beta.103 + + '@effect/platform-node@4.0.0-beta.103': + resolution: {integrity: sha512-VD8fbpendwFokMwzC7/MxazjhEVDihPC5NZtomYEyZwGaA1LXMvwP1y8pfXwfshUkG56TN4EMQqzu72c0B9FhA==} + engines: {node: '>=18.0.0'} + peerDependencies: + effect: ^4.0.0-beta.103 + ioredis: ^5.7.0 + + '@effect/sql-d1@4.0.0-beta.103': + resolution: {integrity: sha512-rCt6rL6HX5T8OftQN4l5pI3hqahdakVgcbbR1Oir+AsfttSn3qB6sU4cmYm2q6XdknzMWdE+yt469t/8fIBXDw==} + peerDependencies: + effect: ^4.0.0-beta.103 + + '@effect/sql-sqlite-do@4.0.0-beta.103': + resolution: {integrity: sha512-j5LIAJK2ozwz2FNJzR48oM5Q9KBv9qNmCFCvAmDC5UbMuX222D76QCpPkJVjActq6o8IS5TD5Ft+F0FxjspwwQ==} + peerDependencies: + effect: ^4.0.0-beta.103 + + '@effect/vitest@4.0.0-beta.103': + resolution: {integrity: sha512-Kz3gemVuJNAZ3e4V6A7BwAP87x2Av8LyHOlCjy9jbZzlncwJXO7Olk1Sje3hdKaet3wEl51A/0/89xJ2IYSgNg==} + peerDependencies: + effect: ^4.0.0-beta.103 + vitest: ^4.1.0 + + '@electric-sql/pglite-socket@0.0.20': + resolution: {integrity: sha512-J5nLGsicnD9wJHnno9r+DGxfcZWh+YJMCe0q/aCgtG6XOm9Z7fKeite8IZSNXgZeGltSigM9U/vAWZQWdgcSFg==} + hasBin: true + peerDependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite-tools@0.2.20': + resolution: {integrity: sha512-BK50ZnYa3IG7ztXhtgYf0Q7zijV32Iw1cYS8C+ThdQlwx12V5VZ9KRJ42y82Hyb4PkTxZQklVQA9JHyUlex33A==} + peerDependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite@0.3.15': + resolution: {integrity: sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ==} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/runtime@1.11.3': resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@emoji-mart/data@1.2.1': resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==} @@ -1438,6 +1759,12 @@ packages: '@modelcontextprotocol/sdk': optional: true + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -1749,6 +2076,9 @@ packages: cpu: [x64] os: [win32] + '@ioredis/commands@1.10.0': + resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1798,6 +2128,63 @@ packages: '@lezer/yaml@1.0.4': resolution: {integrity: sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==} + '@libsql/client@0.17.4': + resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==} + + '@libsql/core@0.17.4': + resolution: {integrity: sha512-LqF9gIvnJ38nmAH1y/ChizHqDO/MO1wLgA96XrraulEEbqXxLjleSH92YWTolbuJKgPUmGu4aJk9W3UnAcxLOQ==} + + '@libsql/darwin-arm64@0.5.29': + resolution: {integrity: sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==} + cpu: [arm64] + os: [darwin] + + '@libsql/darwin-x64@0.5.29': + resolution: {integrity: sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==} + cpu: [x64] + os: [darwin] + + '@libsql/hrana-client@0.10.0': + resolution: {integrity: sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==} + + '@libsql/isomorphic-ws@0.1.5': + resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} + + '@libsql/linux-arm-gnueabihf@0.5.29': + resolution: {integrity: sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm-musleabihf@0.5.29': + resolution: {integrity: sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm64-gnu@0.5.29': + resolution: {integrity: sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-arm64-musl@0.5.29': + resolution: {integrity: sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-x64-gnu@0.5.29': + resolution: {integrity: sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==} + cpu: [x64] + os: [linux] + + '@libsql/linux-x64-musl@0.5.29': + resolution: {integrity: sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==} + cpu: [x64] + os: [linux] + + '@libsql/win32-x64-msvc@0.5.29': + resolution: {integrity: sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==} + cpu: [x64] + os: [win32] + '@marijn/find-cluster-break@1.0.3': resolution: {integrity: sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==} @@ -1827,18 +2214,145 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@mrleebo/prisma-ast@0.13.1': + resolution: {integrity: sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==} + engines: {node: '>=16'} + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} + cpu: [x64] + os: [win32] + + '@napi-rs/wasm-runtime@1.2.2': + resolution: {integrity: sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.3 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.3 + + '@neon-rs/load@0.0.4': + resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} + + '@nodable/entities@3.0.0': + resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} + + '@octokit/core@7.0.7': + resolution: {integrity: sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==} + engines: {node: '>= 20'} + + '@octokit/endpoint@11.0.4': + resolution: {integrity: sha512-f1cOWoHPmxryJFknxbtDdjODWfV8A9tc8Aae6ermXPNgHFZ/x91AtHIz4gicEjL8hkJiip+u21QHJORfBv/qiA==} + engines: {node: '>= 20'} + + '@octokit/graphql@9.0.4': + resolution: {integrity: sha512-5s15CCiY8XXQ+FG+b1YQcl6Z2FA++nwAz/tg2VUrTmnMncP+2nnGUEYANImdnxsA2Fnq+Mbl7hDjUTw7cFAwcg==} + engines: {node: '>= 20'} + + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} + + '@octokit/openapi-types@28.0.0': + resolution: {integrity: sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==} + + '@octokit/openapi-webhooks-types@12.1.0': + resolution: {integrity: sha512-WiuzhOsiOvb7W3Pvmhf8d2C6qaLHXrWiLBP4nJ/4kydu+wpagV5Fkz9RfQwV2afYzv3PB+3xYgp4mAdNGjDprA==} + + '@octokit/plugin-paginate-rest@14.0.0': + resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-request-log@6.0.0': + resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-rest-endpoint-methods@17.0.0': + resolution: {integrity: sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/request-error@7.1.1': + resolution: {integrity: sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.13': + resolution: {integrity: sha512-v2269YxL9Yf+x3d+gRI63FP0vFQEiWgLyBzxe/Y+0yFDg2B/Tzf5dhh9VNfccVAQnfcfwQWyk/y6Bn7rUXXs7A==} + engines: {node: '>= 20'} + + '@octokit/rest@22.0.1': + resolution: {integrity: sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==} + engines: {node: '>= 20'} + + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + + '@octokit/types@17.0.0': + resolution: {integrity: sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==} + + '@octokit/webhooks-methods@6.0.0': + resolution: {integrity: sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ==} + engines: {node: '>= 20'} + + '@octokit/webhooks@14.2.0': + resolution: {integrity: sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw==} + engines: {node: '>= 20'} + '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/api@1.9.1': - resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} - engines: {node: '>=8.0.0'} - '@opentelemetry/semantic-conventions@1.43.0': resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + '@oxlint/binding-android-arm-eabi@1.76.0': resolution: {integrity: sha512-ZHIE5Zt9AsPDcY4nOlofXt0YfneEeo+QrKMPcPzLf2Z6Q8VtV2W73d7SFJ920WUwyik783u/doKCs3KXdwG+7w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1977,6 +2491,18 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@prisma/debug@7.2.0': + resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} + + '@prisma/dev@0.20.0': + resolution: {integrity: sha512-ovlBYwWor0OzG+yH4J3Ot+AneD818BttLA+Ii7wjbcLHUrnC4tbUPVGyNd3c/+71KETPKZfjhkTSpdS15dmXNQ==} + + '@prisma/get-platform@7.2.0': + resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} + + '@prisma/query-plan-executor@7.2.0': + resolution: {integrity: sha512-EOZmNzcV8uJ0mae3DhTsiHgoNCuu1J9mULQpGCh62zN3PxPTd+qI9tJvk5jOst8WHKQNwJWR3b39t0XvfBB0WQ==} + '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -2004,31 +2530,134 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + '@puppeteer/browsers@2.13.2': + resolution: {integrity: sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==} + engines: {node: '>=18'} + hasBin: true + '@puppeteer/browsers@2.2.4': resolution: {integrity: sha512-BdG2qiI1dn89OTUUsx2GZSpUzW+DRffR1wlMJyKxVHYrhnKoELSDxDd+2XImUkuWPEKk76H5FcM/gPFrEK1Tfw==} engines: {node: '>=18'} hasBin: true - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - - '@rollup/rollup-android-arm-eabi@4.62.3': - resolution: {integrity: sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.62.3': - resolution: {integrity: sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==} + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.62.3': - resolution: {integrity: sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==} + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.62.3': - resolution: {integrity: sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==} + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/rollup-android-arm-eabi@4.62.3': + resolution: {integrity: sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.62.3': + resolution: {integrity: sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.62.3': + resolution: {integrity: sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.62.3': + resolution: {integrity: sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==} cpu: [x64] os: [darwin] @@ -2201,6 +2830,10 @@ packages: resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} + '@smithy/node-config-provider@4.5.16': + resolution: {integrity: sha512-N4XTMCO77u8jXq9Ms1pbFM3M9zD+ScKnvB+M7//VyawM8L6xW3/mqAPp/uMOYprW+q/b1Qen6qUKVwxTb2ymiQ==} + engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.7.3': resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==} engines: {node: '>=18.0.0'} @@ -2209,6 +2842,10 @@ packages: resolution: {integrity: sha512-Nmd/Nl35zfYrd+a6OO2cDJb3GPh9bgTjIUhcM+JFfjpp8/osCgboDV5nCT1I01Pv6R13eSKDKLSoVa5ZB6Zsfw==} engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.6.16': + resolution: {integrity: sha512-apuIuit7x6ZM0nJxuKf24MCkflwnSyD6wePOPGkhntEl0gLaIYLlZTQtzCB+j3kWOTpqx0D1o6JZ15NTk4f8xQ==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.6.12': resolution: {integrity: sha512-I6KLtq3H0qqSuV9vLglfi8puHqzygzWHOnI4z/Rdoo+q50vvo18vBRdPAvvEtcaKROz7Zn6qnPa14kRfPH6PcQ==} engines: {node: '>=18.0.0'} @@ -2217,6 +2854,10 @@ packages: resolution: {integrity: sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==} engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.5.16': + resolution: {integrity: sha512-80e25qWKD6hJh5BenAutni2Z6dj2AiZKmht21pcROmzWzQja8yl+KqsuDSia++hwk1Ne6RrDEBwP6I+A4R0XAg==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} @@ -2389,6 +3030,12 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/aws-lambda@8.10.162': + resolution: {integrity: sha512-Fn658grtLOci1oxi1391vvDWJRKNGWRSqfxRkmN/Iy3c0tQH1USMKEXcPYHLvope+ZgTFocx9FRQJx1muBL6qw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -2445,6 +3092,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -2528,18 +3178,80 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + alchemy@file:.alchemy-reference/alchemy-local.tgz: + resolution: {integrity: sha512-l/tl6jra+UDyVYU2H37k3ZhV/tyEWPpLvRn5DPoyJlTvHu5+PQxGJYh1Nqn2GswXmXxItZ/G4H7EERvM80JLpg==, tarball: file:.alchemy-reference/alchemy-local.tgz} + version: 2.0.0-beta.67 + hasBin: true + peerDependencies: + '@aws/durable-execution-sdk-js': ^2.1.0 + '@effect/platform-bun': '>=4.0.0-beta.102 || >=4.0.0' + '@effect/platform-node': '>=4.0.0-beta.102 || >=4.0.0' + '@effect/sql-mysql2': '>=4.0.0-beta.102 || >=4.0.0' + '@effect/sql-pg': '>=4.0.0-beta.102 || >=4.0.0' + '@vercel/nft': ^1.10.2 + drizzle-kit: 1.0.0-rc.4 + drizzle-orm: 1.0.0-rc.4 + effect: '>=4.0.0-beta.102 || >=4.0.0' + mongodb: ^6.10.0 + mysql2: ^3.15.3 + pg: ^8.13.0 + vite: ^8.0.7 + ws: ^8.20.0 + peerDependenciesMeta: + '@aws/durable-execution-sdk-js': + optional: true + '@effect/platform-bun': + optional: true + '@effect/platform-node': + optional: true + '@effect/sql-mysql2': + optional: true + '@effect/sql-pg': + optional: true + '@vercel/nft': + optional: true + drizzle-kit: + optional: true + drizzle-orm: + optional: true + mongodb: + optional: true + mysql2: + optional: true + pg: + optional: true + vite: + optional: true + ws: + optional: true + + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + ansis@4.3.1: resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} engines: {node: '>=14'} + anynum@1.0.1: + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -2551,6 +3263,10 @@ packages: async-lock@1.4.1: resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + auto-bind@5.0.1: + resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -2621,6 +3337,9 @@ packages: resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} engines: {node: '>=10.0.0'} + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -2686,6 +3405,9 @@ packages: capnweb: optional: true + capnweb@0.6.1: + resolution: {integrity: sha512-fmhV26QPd1ewf5R74h55oVZnGwIcSaRMzbfLQUy8+zOBjuTmT3KXoT8wxHvnp1m9Ht9BoUUS5ZwNLoVLfQTyBg==} + capnweb@0.8.0: resolution: {integrity: sha512-BK/TuXUiyfLSKsmjojn70yN7oYG/JJzoURZ3tckjg5Zj2KcygPm0A5jyOlswK7SYB4f0Gh9tt+RZ132b80iLfA==} @@ -2700,6 +3422,10 @@ packages: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -2716,6 +3442,9 @@ packages: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} + chevrotain@10.5.0: + resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} + chokidar@5.0.0: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} @@ -2726,14 +3455,34 @@ packages: clean-git-ref@2.0.1: resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + cnfast@0.0.8: resolution: {integrity: sha512-EjXKMfGfdwtV4AcNSQ6AwQaVzpC1B7IxeiwA3FlhTXz+YFlMKVi4c1JX9tgD2QOlahQXjB8KUXrBaYG+3v871Q==} hasBin: true + code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2747,9 +3496,17 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + convert-to-spaces@2.0.1: + resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cookie-es@3.1.1: resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} @@ -2760,6 +3517,9 @@ packages: core-js-pure@3.49.0: resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -2843,10 +3603,18 @@ packages: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -2884,12 +3652,18 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + effect@4.0.0-beta.103: + resolution: {integrity: sha512-pE8TxF4m2tQzVI+77dIlm3s+81TACV1AiX1JEkvY+zVuxgQQ8aGSkqXNJF6b/ST+coCSk5cUdbULpQ7sm4oHyw==} + electron-to-chromium@1.5.398: resolution: {integrity: sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==} emoji-mart@5.6.0: resolution: {integrity: sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2908,6 +3682,10 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} @@ -2929,6 +3707,9 @@ packages: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} + es-toolkit@1.50.0: + resolution: {integrity: sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==} + esbuild@0.28.1: resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} @@ -2938,6 +3719,10 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} @@ -2997,9 +3782,36 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true + fast-check@4.9.0: + resolution: {integrity: sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==} + engines: {node: '>=12.17.0'} + fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fast-xml-builder@1.3.0: + resolution: {integrity: sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==} + + fast-xml-parser@5.10.1: + resolution: {integrity: sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==} + hasBin: true + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -3020,10 +3832,17 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-my-way-ts@0.1.6: + resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -3066,10 +3885,17 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -3082,6 +3908,10 @@ packages: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} engines: {node: '>= 14'} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} @@ -3100,6 +3930,12 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + grammex@3.1.13: + resolution: {integrity: sha512-LnPnhOBLEJEVKS8WFDVaA397L9Kq55Q9oSITJiVLHVdhAclfUkWzQv74KhvZHKL2Q09Pb1XdsrOsZ4LfTFFTEg==} + + graphmatch@1.1.1: + resolution: {integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg==} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -3131,6 +3967,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hono@4.11.4: + resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==} + engines: {node: '>=16.9.0'} + html-encoding-sniffer@4.0.0: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} @@ -3145,6 +3985,9 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -3164,9 +4007,33 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@7.0.0: + resolution: {integrity: sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==} + engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} + + ink@6.8.0: + resolution: {integrity: sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA==} + engines: {node: '>=20'} + peerDependencies: + '@types/react': '>=19.0.0' + react: '>=19.0.0' + react-devtools-core: '>=6.1.2' + peerDependenciesMeta: + '@types/react': + optional: true + react-devtools-core: + optional: true + inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} @@ -3174,6 +4041,10 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + ioredis@5.11.1: + resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} + engines: {node: '>=12.22.0'} + ip-address@10.4.0: resolution: {integrity: sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==} engines: {node: '>= 12'} @@ -3191,13 +4062,30 @@ packages: is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ci@2.0.0: + resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==} + engines: {node: '>=20'} + hasBin: true + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -3213,6 +4101,12 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-unsafe@2.0.0: + resolution: {integrity: sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -3268,6 +4162,9 @@ packages: resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} engines: {node: '>=16'} + json-with-bigint@3.5.10: + resolution: {integrity: sha512-Vcx+JVNEBts/xfcoCS69sKrOhOk/3TVlvlT+XzUOefVKnnrbYSCKpDCm10pohsJFtsJVYnwa/cXRZ4eElzaM6w==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -3276,6 +4173,9 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwa@2.0.1: resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} @@ -3286,11 +4186,28 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + kubernetes-types@1.30.0: + resolution: {integrity: sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==} + lib0@0.2.117: resolution: {integrity: sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==} engines: {node: '>=16'} hasBin: true + libsodium-wrappers@0.8.4: + resolution: {integrity: sha512-mu8aAWucZjTB5O/BtGXtW4e1agy7uHxNYG7zPthmmD1jU43LCDmSWZLN4JhflbdPXj3yDO4lxM1O9hLDgIOXDw==} + + libsodium@0.8.4: + resolution: {integrity: sha512-lMcYaRi0zcs7tarATsQUYC7rstliIXZuoq0c6zXSgNtSNtdvBgkSegjWhpMJAXzKX3SUSwIp7+zEsob+j3LuRw==} + + libsql@0.5.29: + resolution: {integrity: sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==} + cpu: [x64, arm64, wasm32, arm] + os: [darwin, linux, win32] + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -3365,6 +4282,13 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -3439,6 +4363,10 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -3535,18 +4463,22 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + engines: {node: '>=16'} + hasBin: true + mimetext@3.0.28: resolution: {integrity: sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g==} + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - miniflare@4.20260623.0: - resolution: {integrity: sha512-p2YTeH01jMiMOjO4v9hb/+GJndja5LCxecGOWCaT9F414PRXgdddLDsK6MnqhGBB5tlU/WoBYIG1XZte5pQzOQ==} - engines: {node: '>=22.0.0'} - hasBin: true - miniflare@4.20260625.0: resolution: {integrity: sha512-3kKXwRUObJsnBYPBgR0NiNZYKF/yv8GFyha1cx2EeAEraxNODgRVcyeRo+F1ok1tg5Mg7iUpOWSkknQTHuFhwA==} engines: {node: '>=22.0.0'} @@ -3589,6 +4521,16 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msgpackr-extract@3.0.4: + resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} + hasBin: true + + msgpackr@2.0.5: + resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==} + + multipasta@0.2.8: + resolution: {integrity: sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q==} + nanoid@3.3.16: resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3607,6 +4549,10 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + node-html-parser@7.1.0: resolution: {integrity: sha512-iJo8b2uYGT40Y8BTyy5ufL6IVbN8rbm/1QK2xffXU/1a/v3AAa0d1YAoqBNYqaS4R/HajkWIpIfdE6KcyFh1AQ==} @@ -3627,6 +4573,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + oniguruma-parser@0.12.2: resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} @@ -3682,6 +4632,14 @@ packages: partial-json@0.1.7: resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + patch-console@2.0.0: + resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-expression-matcher@1.6.2: + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} + engines: {node: '>=14.0.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -3734,6 +4692,9 @@ packages: engines: {node: '>=14'} hasBin: true + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -3742,6 +4703,12 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promise-limit@2.7.0: + resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + property-information@7.2.0: resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} @@ -3763,6 +4730,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pure-rand@8.4.2: + resolution: {integrity: sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-day-picker@9.14.0: resolution: {integrity: sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==} engines: {node: '>=18'} @@ -3780,6 +4753,12 @@ packages: '@types/react': '>=18' react: '>=18' + react-reconciler@0.33.0: + resolution: {integrity: sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^19.2.0 + react-refresh@0.17.0: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} @@ -3788,6 +4767,9 @@ packages: resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@4.7.0: resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3796,6 +4778,14 @@ packages: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + regex-recursion@6.0.2: resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} @@ -3805,6 +4795,9 @@ packages: regex@6.1.0: resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + regexp-to-ast@0.5.0: + resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} + remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} @@ -3817,6 +4810,9 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remeda@2.33.4: + resolution: {integrity: sha512-ygHswjlc/opg2VrtiYvUOPLjxjtdKvjGz1/plDhkG66hjNjFr1xmfrs2ClNFo/E6TyUFiwYNh53bKV26oBoMGQ==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -3824,10 +4820,27 @@ packages: reselect@5.2.0: resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==} + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.62.3: resolution: {integrity: sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3836,6 +4849,12 @@ packages: rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -3872,6 +4891,9 @@ packages: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + sha.js@2.4.12: resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} engines: {node: '>= 0.10'} @@ -3900,12 +4922,26 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -3932,9 +4968,16 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + state-local@1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} @@ -3951,7 +4994,18 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string_decoder@1.3.0: + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.2.2: + resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} + engines: {node: '>=20'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} stringify-entities@4.0.4: @@ -3961,9 +5015,16 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strnum@2.4.1: + resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} + style-mod@4.1.3: resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} @@ -3980,6 +5041,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + tailwindcss@4.3.3: resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} @@ -4005,6 +5070,10 @@ packages: temporal-utils@1.0.1: resolution: {integrity: sha512-HAixuesxFQIUaQk3ptX2jhfO/FsOkgVkDDMawvp6n/fkB1q6BKfs3lURw9I+pK/2e2e/q/vrLrxmeqauBoyGMQ==} + terminal-size@4.0.1: + resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==} + engines: {node: '>=18'} + terser@5.49.0: resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} engines: {node: '>=10'} @@ -4061,6 +5130,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toml@4.3.0: + resolution: {integrity: sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A==} + engines: {node: '>=20'} + tough-cookie@5.1.2: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} @@ -4092,6 +5165,10 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-fest@5.8.0: + resolution: {integrity: sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==} + engines: {node: '>=20'} + typebox@1.3.7: resolution: {integrity: sha512-meKuifc33Pccx0O6PdIzYMq3Og8zvP4TIi/a+Bw3AEMZMxOD0+RHGQvpglEe6Zdy3wZ8nqn/j95h8LUZLk/6Hg==} @@ -4114,6 +5191,10 @@ packages: resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} engines: {node: '>=20.18.1'} + undici@8.10.0: + resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} + engines: {node: '>=22.19.0'} + unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} @@ -4135,6 +5216,9 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + universal-user-agent@7.0.3: + resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + unplugin@3.3.0: resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4179,6 +5263,21 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} + hasBin: true + + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -4359,31 +5458,15 @@ packages: engines: {node: '>=8'} hasBin: true + widest-line@6.0.0: + resolution: {integrity: sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==} + engines: {node: '>=20'} + workerd@1.20260731.1: resolution: {integrity: sha512-tjdy+FLIZlTwsA3DKrWvCBq+SMiMlB/axFXciEYGJUx4XdHqh4d2j7QAkfoC5MpVsOGesE3qDmiLs5Vnb8On1w==} engines: {node: '>=16'} hasBin: true - wrangler@4.104.0: - resolution: {integrity: sha512-xCfbg2Oj93Bc7EMryFaSeRGDgV96dzrWoaK5q2q5XLEvumO4mysNP/1MDue0GUozEJAI6Z6vrGyYPLmfET/0sg==} - engines: {node: '>=22.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20260623.1 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrangler@4.105.0: - resolution: {integrity: sha512-7dXFH6OLj1Fv0y6ZeRPUxFTkp+duWD7/xxVi/1c0vfOeEYwIFKWB7cdqnY05DvY1Ta3BnqAwRkXfLs8PDj538g==} - engines: {node: '>=22.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20260625.1 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - wrangler@4.115.0: resolution: {integrity: sha512-+upG2VW66M1sjb43yzgUZ6Ss8iYpJ6+7F3U4GF8TY5EYd+08sYdS54d24AEwCnhuef3J9KlSPusqiqR9WYy1UA==} engines: {node: '>=22.0.0'} @@ -4398,6 +5481,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -4429,6 +5516,10 @@ packages: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} + xml-naming@0.3.0: + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} + engines: {node: '>=16.0.0'} + xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} @@ -4472,12 +5563,18 @@ packages: resolution: {integrity: sha512-Eq+5BRfbeGyqGVrTJL3bEcr8gKkxPuyuoHmAwpk52fDb8kOVMrfVSTRPd6yiGgX5Fskb96qCRjzjbRjrL4YEnw==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} youch@4.1.0-beta.10: resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + zeptomatch@2.1.0: + resolution: {integrity: sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA==} + zod-to-json-schema@3.25.2: resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: @@ -4494,6 +5591,13 @@ packages: snapshots: + '@alcalzone/ansi-tokenize@0.2.5': + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + '@alchemy.run/node-utils@0.0.5': {} + '@anthropic-ai/sdk@0.91.1(zod@4.4.3)': dependencies: json-schema-to-ts: 3.1.1 @@ -4508,6 +5612,12 @@ snapshots: '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.974.2 + tslib: 2.8.1 + '@aws-crypto/sha256-browser@5.2.0': dependencies: '@aws-crypto/sha256-js': 5.2.0 @@ -4562,6 +5672,25 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 + '@aws-sdk/core@3.977.5': + dependencies: + '@aws-sdk/types': 3.974.2 + '@aws-sdk/xml-builder': 3.972.37 + '@aws/lambda-invoke-store': 0.3.0 + '@smithy/core': 3.31.1 + '@smithy/signature-v4': 5.6.12 + '@smithy/types': 4.16.1 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-cognito-identity@3.972.65': + dependencies: + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-env@3.972.65': dependencies: '@aws-sdk/core': 3.977.4 @@ -4570,6 +5699,14 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-env@3.972.66': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.67': dependencies: '@aws-sdk/core': 3.977.4 @@ -4580,6 +5717,16 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.68': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/fetch-http-handler': 5.6.13 + '@smithy/node-http-handler': 4.9.13 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-ini@3.973.10': dependencies: '@aws-sdk/core': 3.977.4 @@ -4596,6 +5743,22 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-ini@3.973.11': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/credential-provider-env': 3.972.66 + '@aws-sdk/credential-provider-http': 3.972.68 + '@aws-sdk/credential-provider-login': 3.972.73 + '@aws-sdk/credential-provider-process': 3.972.66 + '@aws-sdk/credential-provider-sso': 3.973.10 + '@aws-sdk/credential-provider-web-identity': 3.972.72 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/credential-provider-imds': 4.4.16 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-login@3.972.72': dependencies: '@aws-sdk/core': 3.977.4 @@ -4605,6 +5768,15 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-login@3.972.73': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-node@3.972.76': dependencies: '@aws-sdk/credential-provider-env': 3.972.65 @@ -4619,6 +5791,20 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-node@3.972.77': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.66 + '@aws-sdk/credential-provider-http': 3.972.68 + '@aws-sdk/credential-provider-ini': 3.973.11 + '@aws-sdk/credential-provider-process': 3.972.66 + '@aws-sdk/credential-provider-sso': 3.973.10 + '@aws-sdk/credential-provider-web-identity': 3.972.72 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/credential-provider-imds': 4.4.16 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-process@3.972.65': dependencies: '@aws-sdk/core': 3.977.4 @@ -4627,6 +5813,24 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-process@3.972.66': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.973.10': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/token-providers': 3.1102.0 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-sso@3.973.9': dependencies: '@aws-sdk/core': 3.977.4 @@ -4646,6 +5850,34 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-web-identity@3.972.72': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + + '@aws-sdk/credential-providers@3.1102.0': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/credential-provider-cognito-identity': 3.972.65 + '@aws-sdk/credential-provider-env': 3.972.66 + '@aws-sdk/credential-provider-http': 3.972.68 + '@aws-sdk/credential-provider-ini': 3.973.11 + '@aws-sdk/credential-provider-login': 3.972.73 + '@aws-sdk/credential-provider-node': 3.972.77 + '@aws-sdk/credential-provider-process': 3.972.66 + '@aws-sdk/credential-provider-sso': 3.973.10 + '@aws-sdk/credential-provider-web-identity': 3.972.72 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/credential-provider-imds': 4.4.16 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/eventstream-handler-node@3.972.31': dependencies: '@aws-sdk/types': 3.974.2 @@ -4681,6 +5913,17 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/nested-clients@3.997.40': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/signature-v4-multi-region': 3.996.43 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/fetch-http-handler': 5.6.13 + '@smithy/node-http-handler': 4.9.13 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/signature-v4-multi-region@3.996.43': dependencies: '@aws-sdk/types': 3.974.2 @@ -4706,6 +5949,15 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@aws-sdk/token-providers@3.1102.0': + dependencies: + '@aws-sdk/core': 3.977.5 + '@aws-sdk/nested-clients': 3.997.40 + '@aws-sdk/types': 3.974.2 + '@smithy/core': 3.31.1 + '@smithy/types': 4.16.1 + tslib: 2.8.1 + '@aws-sdk/types@3.974.2': dependencies: '@smithy/types': 4.16.1 @@ -4730,20 +5982,20 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7(supports-color@10.2.2)': + '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) + '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4768,19 +6020,19 @@ snapshots: '@babel/helper-globals@7.29.7': {} - '@babel/helper-module-imports@7.29.7(supports-color@10.2.2)': + '@babel/helper-module-imports@7.29.7': dependencies: - '@babel/traverse': 7.29.7(supports-color@10.2.2) + '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/helper-module-imports': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -4801,14 +6053,14 @@ snapshots: dependencies: '@babel/types': 7.29.7 - '@babel/plugin-transform-react-jsx-self@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))': + '@babel/plugin-transform-react-jsx-self@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-react-jsx-source@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))': + '@babel/plugin-transform-react-jsx-source@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/runtime-corejs3@7.29.7': @@ -4823,7 +6075,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/types': 7.29.7 - '@babel/traverse@7.29.7(supports-color@10.2.2)': + '@babel/traverse@7.29.7': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -4831,7 +6083,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/template': 7.29.7 '@babel/types': 7.29.7 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -4865,6 +6117,33 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 + '@chevrotain/cst-dts-gen@10.5.0': + dependencies: + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/gast@10.5.0': + dependencies: + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/types@10.5.0': {} + + '@chevrotain/utils@10.5.0': {} + + '@clack/core@1.4.3': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + '@cloudflare/kumo@2.9.0(@date-fns/tz@1.5.0)(@phosphor-icons/react@2.1.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(zod@4.4.3)': dependencies: '@base-ui/react': 1.6.0(@date-fns/tz@1.5.0)(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -4889,10 +6168,10 @@ snapshots: '@cloudflare/kv-asset-handler@0.5.0': {} - '@cloudflare/puppeteer@1.2.0(supports-color@10.2.2)': + '@cloudflare/puppeteer@1.2.0': dependencies: - '@puppeteer/browsers': 2.2.4(supports-color@10.2.2) - debug: 4.4.3(supports-color@10.2.2) + '@puppeteer/browsers': 2.2.4 + debug: 4.4.3 devtools-protocol: 0.0.1299070 ws: 8.21.1 transitivePeerDependencies: @@ -4909,30 +6188,30 @@ snapshots: optionalDependencies: workerd: 1.20260731.1 - '@cloudflare/vitest-pool-workers@0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))': + '@cloudflare/vitest-pool-workers@0.16.20(@cloudflare/workers-types@4.20260702.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))': dependencies: '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 cjs-module-lexer: 1.2.3 esbuild: 0.28.1 miniflare: 4.20260625.0 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) - wrangler: 4.105.0(@cloudflare/workers-types@4.20260702.1) + vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + wrangler: 4.115.0(@cloudflare/workers-types@4.20260702.1) zod: 3.25.76 transitivePeerDependencies: - '@cloudflare/workers-types' - bufferutil - utf-8-validate - '@cloudflare/vitest-pool-workers@0.16.20(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))': + '@cloudflare/vitest-pool-workers@0.16.20(@cloudflare/workers-types@5.20260804.1)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))': dependencies: '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 cjs-module-lexer: 1.2.3 esbuild: 0.28.1 miniflare: 4.20260625.0 - vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) - wrangler: 4.105.0(@cloudflare/workers-types@4.20260702.1) + vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + wrangler: 4.115.0(@cloudflare/workers-types@5.20260804.1) zod: 3.25.76 transitivePeerDependencies: - '@cloudflare/workers-types' @@ -4956,6 +6235,8 @@ snapshots: '@cloudflare/workers-types@4.20260702.1': {} + '@cloudflare/workers-types@5.20260804.1': {} + '@codemirror/autocomplete@6.20.3': dependencies: '@codemirror/language': 6.12.4 @@ -5077,9 +6358,105 @@ snapshots: '@date-fns/tz@1.5.0': {} - '@earendil-works/pi-agent-core@0.83.0(supports-color@10.2.2)(ws@8.21.1)(zod@4.4.3)': + '@distilled.cloud/aws@file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz(effect@4.0.0-beta.103)': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/credential-providers': 3.1102.0 + '@aws-sdk/types': 3.974.2 + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@smithy/shared-ini-file-loader': 4.6.16 + '@smithy/types': 4.16.1 + '@smithy/util-base64': 4.5.16 + aws4fetch: 1.0.20 + effect: 4.0.0-beta.103 + fast-xml-parser: 5.10.1 + + '@distilled.cloud/axiom@file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz': dependencies: - '@earendil-works/pi-ai': 0.83.0(supports-color@10.2.2)(ws@8.21.1)(zod@4.4.3) + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@distilled.cloud/cloudflare-rolldown-plugin@file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz(rolldown@1.1.5)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(workerd@1.20260731.1)': + dependencies: + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260731.1) + magic-string: 0.30.21 + unenv: 2.0.0-rc.24 + optionalDependencies: + rolldown: 1.1.5 + vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) + transitivePeerDependencies: + - workerd + + '@distilled.cloud/cloudflare-runtime@file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103)': + dependencies: + '@alchemy.run/node-utils': 0.0.5 + '@distilled.cloud/cloudflare': file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz + '@puppeteer/browsers': 2.13.2 + effect: 4.0.0-beta.103 + sharp: 0.34.5 + workerd: 1.20260731.1 + optionalDependencies: + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + '@effect/platform-node': 4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1) + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@distilled.cloud/cloudflare-vite-plugin@file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz(@distilled.cloud/cloudflare-runtime@file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103))(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103)(rolldown@1.1.5)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(workerd@1.20260731.1)': + dependencies: + '@distilled.cloud/cloudflare': file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz + '@distilled.cloud/cloudflare-rolldown-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz(rolldown@1.1.5)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(workerd@1.20260731.1) + '@distilled.cloud/cloudflare-runtime': file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) + optionalDependencies: + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + '@effect/platform-node': 4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1) + transitivePeerDependencies: + - rolldown + - workerd + + '@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz': + dependencies: + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@distilled.cloud/core@file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103)': + dependencies: + effect: 4.0.0-beta.103 + + '@distilled.cloud/neon@file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz': + dependencies: + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@distilled.cloud/planetscale@file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz': + dependencies: + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@earendil-works/pi-agent-core@0.83.0(ws@8.21.1)(zod@4.4.3)': + dependencies: + '@earendil-works/pi-ai': 0.83.0(ws@8.21.1)(zod@4.4.3) diff: 8.0.4 ignore: 7.0.5 typebox: 1.3.7 @@ -5092,16 +6469,16 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.83.0(supports-color@10.2.2)(ws@8.21.1)(zod@4.4.3)': + '@earendil-works/pi-ai@0.83.0(ws@8.21.1)(zod@4.4.3)': dependencies: '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) '@aws-sdk/client-bedrock-runtime': 3.1048.0 - '@google/genai': 1.52.0(supports-color@10.2.2) + '@google/genai': 1.52.0 '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) '@opentelemetry/api': 1.9.0 '@smithy/node-http-handler': 4.7.3 - http-proxy-agent: 7.0.2(supports-color@10.2.2) - https-proxy-agent: 7.0.6(supports-color@10.2.2) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 openai: 6.26.0(ws@8.21.1)(zod@4.4.3) partial-json: 0.1.7 typebox: 1.3.7 @@ -5113,11 +6490,79 @@ snapshots: - ws - zod + '@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103)': + dependencies: + '@effect/platform-node-shared': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/platform-node-shared@4.0.0-beta.103(effect@4.0.0-beta.103)': + dependencies: + '@types/ws': 8.18.1 + effect: 4.0.0-beta.103 + ws: 8.21.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1)': + dependencies: + '@effect/platform-node-shared': 4.0.0-beta.103(effect@4.0.0-beta.103) + effect: 4.0.0-beta.103 + ioredis: 5.11.1 + mime: 4.1.0 + undici: 8.10.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/sql-d1@4.0.0-beta.103(effect@4.0.0-beta.103)': + dependencies: + '@cloudflare/workers-types': 5.20260804.1 + effect: 4.0.0-beta.103 + + '@effect/sql-sqlite-do@4.0.0-beta.103(effect@4.0.0-beta.103)': + dependencies: + effect: 4.0.0-beta.103 + + '@effect/vitest@4.0.0-beta.103(effect@4.0.0-beta.103)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))': + dependencies: + effect: 4.0.0-beta.103 + vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + + '@electric-sql/pglite-socket@0.0.20(@electric-sql/pglite@0.3.15)': + dependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite-tools@0.2.20(@electric-sql/pglite@0.3.15)': + dependencies: + '@electric-sql/pglite': 0.3.15 + + '@electric-sql/pglite@0.3.15': {} + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.11.3': dependencies: tslib: 2.8.1 optional: true + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + '@emoji-mart/data@1.2.1': {} '@esbuild/aix-ppc64@0.28.1': @@ -5215,9 +6660,9 @@ snapshots: '@floating-ui/utils@0.2.12': {} - '@google/genai@1.52.0(supports-color@10.2.2)': + '@google/genai@1.52.0': dependencies: - google-auth-library: 10.9.1(supports-color@10.2.2) + google-auth-library: 10.9.1 p-retry: 4.6.2 protobufjs: 7.6.5 ws: 8.21.1 @@ -5226,6 +6671,10 @@ snapshots: - supports-color - utf-8-validate + '@hono/node-server@1.19.9(hono@4.11.4)': + dependencies: + hono: 4.11.4 + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.34.5': @@ -5426,6 +6875,8 @@ snapshots: '@img/sharp-win32-x64@0.35.2': optional: true + '@ioredis/commands@1.10.0': {} + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5500,6 +6951,64 @@ snapshots: '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 + '@libsql/client@0.17.4': + dependencies: + '@libsql/core': 0.17.4 + '@libsql/hrana-client': 0.10.0 + js-base64: 3.9.2 + libsql: 0.5.29 + promise-limit: 2.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/core@0.17.4': + dependencies: + js-base64: 3.9.2 + + '@libsql/darwin-arm64@0.5.29': + optional: true + + '@libsql/darwin-x64@0.5.29': + optional: true + + '@libsql/hrana-client@0.10.0': + dependencies: + '@libsql/isomorphic-ws': 0.1.5 + js-base64: 3.9.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/isomorphic-ws@0.1.5': + dependencies: + '@types/ws': 8.18.1 + ws: 8.21.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/linux-arm-gnueabihf@0.5.29': + optional: true + + '@libsql/linux-arm-musleabihf@0.5.29': + optional: true + + '@libsql/linux-arm64-gnu@0.5.29': + optional: true + + '@libsql/linux-arm64-musl@0.5.29': + optional: true + + '@libsql/linux-x64-gnu@0.5.29': + optional: true + + '@libsql/linux-x64-musl@0.5.29': + optional: true + + '@libsql/win32-x64-msvc@0.5.29': + optional: true + '@marijn/find-cluster-break@1.0.3': {} '@mistralai/mistralai@2.2.6(@opentelemetry/api@1.9.0)': @@ -5539,13 +7048,137 @@ snapshots: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - '@opentelemetry/api@1.9.0': {} + '@mrleebo/prisma-ast@0.13.1': + dependencies: + chevrotain: 10.5.0 + lilconfig: 2.1.0 + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + optional: true - '@opentelemetry/api@1.9.1': + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': optional: true + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + optional: true + + '@napi-rs/wasm-runtime@1.2.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@neon-rs/load@0.0.4': {} + + '@nodable/entities@3.0.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@octokit/auth-token@6.0.0': {} + + '@octokit/core@7.0.7': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.4 + '@octokit/request': 10.0.13 + '@octokit/request-error': 7.1.1 + '@octokit/types': 17.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@11.0.4': + dependencies: + '@octokit/types': 17.0.0 + universal-user-agent: 7.0.3 + + '@octokit/graphql@9.0.4': + dependencies: + '@octokit/request': 10.0.13 + '@octokit/types': 17.0.0 + universal-user-agent: 7.0.3 + + '@octokit/openapi-types@27.0.0': {} + + '@octokit/openapi-types@28.0.0': {} + + '@octokit/openapi-webhooks-types@12.1.0': {} + + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.7)': + dependencies: + '@octokit/core': 7.0.7 + '@octokit/types': 16.0.0 + + '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.7)': + dependencies: + '@octokit/core': 7.0.7 + + '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.7)': + dependencies: + '@octokit/core': 7.0.7 + '@octokit/types': 16.0.0 + + '@octokit/request-error@7.1.1': + dependencies: + '@octokit/types': 17.0.0 + + '@octokit/request@10.0.13': + dependencies: + '@octokit/endpoint': 11.0.4 + '@octokit/request-error': 7.1.1 + '@octokit/types': 17.0.0 + content-type: 2.0.0 + json-with-bigint: 3.5.10 + universal-user-agent: 7.0.3 + + '@octokit/rest@22.0.1': + dependencies: + '@octokit/core': 7.0.7 + '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.7) + '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.7) + '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.7) + + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + + '@octokit/types@17.0.0': + dependencies: + '@octokit/openapi-types': 28.0.0 + + '@octokit/webhooks-methods@6.0.0': {} + + '@octokit/webhooks@14.2.0': + dependencies: + '@octokit/openapi-webhooks-types': 12.1.0 + '@octokit/request-error': 7.1.1 + '@octokit/webhooks-methods': 6.0.0 + + '@opentelemetry/api@1.9.0': {} + '@opentelemetry/semantic-conventions@1.43.0': {} + '@oxc-project/types@0.139.0': {} + '@oxlint/binding-android-arm-eabi@1.76.0': optional: true @@ -5620,6 +7253,36 @@ snapshots: '@poppinss/exception@1.2.3': {} + '@prisma/debug@7.2.0': {} + + '@prisma/dev@0.20.0(typescript@5.9.3)': + dependencies: + '@electric-sql/pglite': 0.3.15 + '@electric-sql/pglite-socket': 0.0.20(@electric-sql/pglite@0.3.15) + '@electric-sql/pglite-tools': 0.2.20(@electric-sql/pglite@0.3.15) + '@hono/node-server': 1.19.9(hono@4.11.4) + '@mrleebo/prisma-ast': 0.13.1 + '@prisma/get-platform': 7.2.0 + '@prisma/query-plan-executor': 7.2.0 + foreground-child: 3.3.1 + get-port-please: 3.2.0 + hono: 4.11.4 + http-status-codes: 2.3.0 + pathe: 2.0.3 + proper-lockfile: 4.1.2 + remeda: 2.33.4 + std-env: 3.10.0 + valibot: 1.2.0(typescript@5.9.3) + zeptomatch: 2.1.0 + transitivePeerDependencies: + - typescript + + '@prisma/get-platform@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/query-plan-executor@7.2.0': {} + '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -5640,12 +7303,27 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@2.2.4(supports-color@10.2.2)': + '@puppeteer/browsers@2.13.2': + dependencies: + debug: 4.4.3 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.5.0 + semver: 7.8.5 + tar-fs: 3.1.3 + yargs: 17.7.3 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@puppeteer/browsers@2.2.4': dependencies: - debug: 4.4.3(supports-color@10.2.2) - extract-zip: 2.0.1(supports-color@10.2.2) + debug: 4.4.3 + extract-zip: 2.0.1 progress: 2.0.3 - proxy-agent: 6.5.0(supports-color@10.2.2) + proxy-agent: 6.5.0 semver: 7.8.5 tar-fs: 3.1.3 unbzip2-stream: 1.4.3 @@ -5656,8 +7334,59 @@ snapshots: - react-native-b4a - supports-color + '@rolldown/binding-android-arm64@1.1.5': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.5': + optional: true + + '@rolldown/binding-darwin-x64@1.1.5': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.5': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.5': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.5': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.5': + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.5': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.2.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.5': + optional: true + '@rolldown/pluginutils@1.0.0-beta.27': {} + '@rolldown/pluginutils@1.0.1': {} + '@rollup/rollup-android-arm-eabi@4.62.3': optional: true @@ -5796,6 +7525,11 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/node-config-provider@4.5.16': + dependencies: + '@smithy/core': 3.31.1 + tslib: 2.8.1 + '@smithy/node-http-handler@4.7.3': dependencies: '@smithy/core': 3.31.1 @@ -5808,6 +7542,11 @@ snapshots: '@smithy/types': 4.16.1 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.6.16': + dependencies: + '@smithy/core': 3.31.1 + tslib: 2.8.1 + '@smithy/signature-v4@5.6.12': dependencies: '@smithy/core': 3.31.1 @@ -5818,6 +7557,11 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/util-base64@4.5.16': + dependencies: + '@smithy/core': 3.31.1 + tslib: 2.8.1 + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 @@ -5927,11 +7671,11 @@ snapshots: seroval: 1.6.0 seroval-plugins: 1.6.0(seroval@1.6.0) - '@tanstack/router-generator@1.167.21(supports-color@10.2.2)': + '@tanstack/router-generator@1.167.21': dependencies: '@babel/types': 7.29.7 '@tanstack/router-core': 1.171.15 - '@tanstack/router-utils': 1.162.2(supports-color@10.2.2) + '@tanstack/router-utils': 1.162.2 '@tanstack/virtual-file-routes': 1.162.0 jiti: 2.7.0 magic-string: 0.30.21 @@ -5940,16 +7684,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.23(@tanstack/react-router@1.170.18(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(esbuild@0.28.1)(rollup@4.62.3)(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))': + '@tanstack/router-plugin@1.168.23(@tanstack/react-router@1.170.18(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/template': 7.29.7 '@babel/types': 7.29.7 '@tanstack/router-core': 1.171.15 - '@tanstack/router-generator': 1.167.21(supports-color@10.2.2) - '@tanstack/router-utils': 1.162.2(supports-color@10.2.2) + '@tanstack/router-generator': 1.167.21 + '@tanstack/router-utils': 1.162.2 chokidar: 5.0.0 - unplugin: 3.3.0(esbuild@0.28.1)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) zod: 4.4.3 optionalDependencies: '@tanstack/react-router': 1.170.18(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -5964,13 +7708,13 @@ snapshots: - supports-color - unloader - '@tanstack/router-utils@1.162.2(supports-color@10.2.2)': + '@tanstack/router-utils@1.162.2': dependencies: '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 '@babel/types': 7.29.7 ansis: 4.3.1 - babel-dead-code-elimination: 1.0.12(supports-color@10.2.2) + babel-dead-code-elimination: 1.0.12 diff: 8.0.4 pathe: 2.0.3 tinyglobby: 0.2.17 @@ -5983,6 +7727,13 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aws-lambda@8.10.162': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.7 @@ -6049,6 +7800,10 @@ snapshots: '@types/unist@3.0.3': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 26.1.0 + '@types/yauzl@2.10.3': dependencies: '@types/node': 26.1.0 @@ -6056,11 +7811,11 @@ snapshots: '@ungap/structured-clone@1.3.3': {} - '@vitejs/plugin-react@4.7.0(supports-color@10.2.2)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))': + '@vitejs/plugin-react@4.7.0(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) - '@babel/plugin-transform-react-jsx-source': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + '@babel/core': 7.29.7 + '@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-react-jsx-source': 7.29.7(@babel/core@7.29.7) '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 @@ -6159,14 +7914,81 @@ snapshots: agent-base@7.1.4: {} + alchemy@file:.alchemy-reference/alchemy-local.tgz(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(@types/react@19.2.17)(effect@4.0.0-beta.103)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)))(workerd@1.20260731.1)(ws@8.21.1): + dependencies: + '@alchemy.run/node-utils': 0.0.5 + '@aws-sdk/credential-providers': 3.1102.0 + '@clack/prompts': 1.7.0 + '@distilled.cloud/aws': file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz(effect@4.0.0-beta.103) + '@distilled.cloud/axiom': file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz + '@distilled.cloud/cloudflare': file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz + '@distilled.cloud/cloudflare-rolldown-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz(rolldown@1.1.5)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(workerd@1.20260731.1) + '@distilled.cloud/cloudflare-runtime': file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103) + '@distilled.cloud/cloudflare-vite-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz(@distilled.cloud/cloudflare-runtime@file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103))(@distilled.cloud/cloudflare@file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz)(@effect/platform-bun@4.0.0-beta.103(effect@4.0.0-beta.103))(@effect/platform-node@4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1))(effect@4.0.0-beta.103)(rolldown@1.1.5)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))(workerd@1.20260731.1) + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz(effect@4.0.0-beta.103) + '@distilled.cloud/neon': file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz + '@distilled.cloud/planetscale': file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz + '@effect/sql-d1': 4.0.0-beta.103(effect@4.0.0-beta.103) + '@effect/sql-sqlite-do': 4.0.0-beta.103(effect@4.0.0-beta.103) + '@effect/vitest': 4.0.0-beta.103(effect@4.0.0-beta.103)(vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0))) + '@libsql/client': 0.17.4 + '@octokit/rest': 22.0.1 + '@octokit/webhooks': 14.2.0 + '@prisma/dev': 0.20.0(typescript@5.9.3) + '@smithy/node-config-provider': 4.5.16 + '@smithy/shared-ini-file-loader': 4.6.16 + '@smithy/types': 4.16.1 + '@types/aws-lambda': 8.10.162 + aws4fetch: 1.0.20 + capnweb: 0.6.1 + effect: 4.0.0-beta.103 + fast-glob: 3.3.3 + fast-xml-parser: 5.10.1 + ink: 6.8.0(@types/react@19.2.17)(react@19.2.8) + jszip: 3.10.1 + libsodium-wrappers: 0.8.4 + pathe: 2.0.3 + picomatch: 4.0.5 + react: 19.2.8 + rolldown: 1.1.5 + undici: 7.28.0 + yaml: 2.9.0 + optionalDependencies: + '@effect/platform-bun': 4.0.0-beta.103(effect@4.0.0-beta.103) + '@effect/platform-node': 4.0.0-beta.103(effect@4.0.0-beta.103)(ioredis@5.11.1) + vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) + ws: 8.21.1 + transitivePeerDependencies: + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - react-devtools-core + - react-native-b4a + - supports-color + - typescript + - utf-8-validate + - vitest + - workerd + + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + ansis@4.3.1: {} + anynum@1.0.1: {} + assertion-error@2.0.1: {} ast-types@0.13.4: @@ -6175,6 +7997,8 @@ snapshots: async-lock@1.4.1: {} + auto-bind@5.0.1: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -6183,11 +8007,11 @@ snapshots: b4a@1.8.1: {} - babel-dead-code-elimination@1.0.12(supports-color@10.2.2): + babel-dead-code-elimination@1.0.12: dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) + '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -6229,6 +8053,8 @@ snapshots: basic-ftp@5.3.1: {} + before-after-hook@4.0.0: {} + bignumber.js@9.3.1: {} blake3-wasm@2.1.5: {} @@ -6286,10 +8112,10 @@ snapshots: caniuse-lite@1.0.30001806: {} - capnweb-validate@0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): + capnweb-validate@0.2.1(capnweb@0.8.0)(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): dependencies: typescript: 5.9.3 - unplugin: 3.3.0(esbuild@0.28.1)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) optionalDependencies: capnweb: 0.8.0 transitivePeerDependencies: @@ -6303,6 +8129,8 @@ snapshots: - vite - webpack + capnweb@0.6.1: {} + capnweb@0.8.0: {} ccount@2.0.1: {} @@ -6317,6 +8145,8 @@ snapshots: chai@6.2.2: {} + chalk@5.6.2: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -6327,6 +8157,15 @@ snapshots: check-error@2.1.3: {} + chevrotain@10.5.0: + dependencies: + '@chevrotain/cst-dts-gen': 10.5.0 + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + '@chevrotain/utils': 10.5.0 + lodash: 4.17.21 + regexp-to-ast: 0.5.0 + chokidar@5.0.0: dependencies: readdirp: 5.0.0 @@ -6335,14 +8174,31 @@ snapshots: clean-git-ref@2.0.1: {} + cli-boxes@3.0.0: {} + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.2.2 + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cluster-key-slot@1.1.1: {} + cnfast@0.0.8: {} + code-excerpt@4.0.0: + dependencies: + convert-to-spaces: 2.0.1 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -6353,14 +8209,20 @@ snapshots: commander@2.20.3: {} + content-type@2.0.0: {} + convert-source-map@2.0.0: {} + convert-to-spaces@2.0.1: {} + cookie-es@3.1.1: {} cookie@1.1.1: {} core-js-pure@3.49.0: {} + core-util-is@1.0.3: {} + crc-32@1.2.2: {} crelt@1.0.7: {} @@ -6409,11 +8271,9 @@ snapshots: date-fns@4.4.0: {} - debug@4.4.3(supports-color@10.2.2): + debug@4.4.3: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 10.2.2 decimal.js@10.6.0: {} @@ -6439,8 +8299,12 @@ snapshots: escodegen: 2.1.0 esprima: 4.0.1 + denque@2.1.0: {} + dequal@2.0.3: {} + detect-libc@2.0.2: {} + detect-libc@2.1.2: {} devlop@1.1.0: @@ -6481,10 +8345,25 @@ snapshots: dependencies: safe-buffer: 5.2.1 + effect@4.0.0-beta.103: + dependencies: + '@standard-schema/spec': 1.1.0 + fast-check: 4.9.0 + find-my-way-ts: 0.1.6 + ini: 7.0.0 + kubernetes-types: 1.30.0 + msgpackr: 2.0.5 + multipasta: 0.2.8 + toml: 4.3.0 + uuid: 14.0.1 + yaml: 2.9.0 + electron-to-chromium@1.5.398: {} emoji-mart@5.6.0: {} + emoji-regex@10.6.0: {} + emoji-regex@8.0.0: {} end-of-stream@1.4.5: @@ -6500,6 +8379,8 @@ snapshots: entities@6.0.1: {} + environment@1.1.0: {} + error-stack-parser-es@1.0.5: {} es-define-property@1.0.1: {} @@ -6514,6 +8395,8 @@ snapshots: dependencies: es-errors: 1.3.0 + es-toolkit@1.50.0: {} + esbuild@0.28.1: optionalDependencies: '@esbuild/aix-ppc64': 0.28.1 @@ -6545,6 +8428,8 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@5.0.0: {} escodegen@2.1.0: @@ -6587,9 +8472,9 @@ snapshots: extend@3.0.2: {} - extract-zip@2.0.1(supports-color@10.2.2): + extract-zip@2.0.1: dependencies: - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -6597,8 +8482,48 @@ snapshots: transitivePeerDependencies: - supports-color + fast-check@4.9.0: + dependencies: + pure-rand: 8.4.2 + fast-fifo@1.3.2: {} + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fast-xml-builder@1.3.0: + dependencies: + path-expression-matcher: 1.6.2 + xml-naming: 0.3.0 + + fast-xml-parser@5.10.1: + dependencies: + '@nodable/entities': 3.0.0 + fast-xml-builder: 1.3.0 + is-unsafe: 2.0.0 + path-expression-matcher: 1.6.2 + strnum: 2.4.1 + xml-naming: 0.3.0 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -6616,10 +8541,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-my-way-ts@0.1.6: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -6638,17 +8570,17 @@ snapshots: function-bind@1.1.2: {} - gaxios@7.3.0(supports-color@10.2.2): + gaxios@7.3.0: dependencies: extend: 3.0.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) + https-proxy-agent: 7.0.6 node-fetch: 3.3.2 transitivePeerDependencies: - supports-color - gcp-metadata@8.1.2(supports-color@10.2.2): + gcp-metadata@8.1.2: dependencies: - gaxios: 7.3.0(supports-color@10.2.2) + gaxios: 7.3.0 google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -6658,6 +8590,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -6671,6 +8605,8 @@ snapshots: hasown: 2.0.4 math-intrinsics: 1.1.0 + get-port-please@3.2.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -6680,22 +8616,26 @@ snapshots: dependencies: pump: 3.0.4 - get-uri@6.0.5(supports-color@10.2.2): + get-uri@6.0.5: dependencies: basic-ftp: 5.3.1 data-uri-to-buffer: 6.0.2 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + globrex@0.1.2: {} - google-auth-library@10.9.1(supports-color@10.2.2): + google-auth-library@10.9.1: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.3.0(supports-color@10.2.2) - gcp-metadata: 8.1.2(supports-color@10.2.2) + gaxios: 7.3.0 + gcp-metadata: 8.1.2 google-logging-utils: 1.1.3 jws: 4.0.1 transitivePeerDependencies: @@ -6707,6 +8647,10 @@ snapshots: graceful-fs@4.2.11: {} + grammex@3.1.13: {} + + graphmatch@1.1.1: {} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 @@ -6737,7 +8681,7 @@ snapshots: stringify-entities: 4.0.4 zwitch: 2.0.4 - hast-util-to-jsx-runtime@2.3.6(supports-color@10.2.2): + hast-util-to-jsx-runtime@2.3.6: dependencies: '@types/estree': 1.0.9 '@types/hast': 3.0.5 @@ -6746,9 +8690,9 @@ snapshots: devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.1(supports-color@10.2.2) - mdast-util-mdx-jsx: 3.2.0(supports-color@10.2.2) - mdast-util-mdxjs-esm: 2.0.1(supports-color@10.2.2) + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 property-information: 7.2.0 space-separated-tokens: 2.0.2 style-to-js: 1.1.21 @@ -6763,6 +8707,8 @@ snapshots: he@1.2.0: {} + hono@4.11.4: {} + html-encoding-sniffer@4.0.0: dependencies: whatwg-encoding: 3.1.1 @@ -6771,17 +8717,19 @@ snapshots: html-void-elements@3.0.0: {} - http-proxy-agent@7.0.2(supports-color@10.2.2): + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.6(supports-color@10.2.2): + http-status-codes@2.3.0: {} + + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -6795,12 +8743,64 @@ snapshots: ignore@7.0.5: {} + immediate@3.0.6: {} + + indent-string@5.0.0: {} + inherits@2.0.4: {} + ini@7.0.0: {} + + ink@6.8.0(@types/react@19.2.17)(react@19.2.8): + dependencies: + '@alcalzone/ansi-tokenize': 0.2.5 + ansi-escapes: 7.3.0 + ansi-styles: 6.2.3 + auto-bind: 5.0.1 + chalk: 5.6.2 + cli-boxes: 3.0.0 + cli-cursor: 4.0.0 + cli-truncate: 5.2.0 + code-excerpt: 4.0.0 + es-toolkit: 1.50.0 + indent-string: 5.0.0 + is-in-ci: 2.0.0 + patch-console: 2.0.0 + react: 19.2.8 + react-reconciler: 0.33.0(react@19.2.8) + scheduler: 0.27.0 + signal-exit: 3.0.7 + slice-ansi: 8.0.0 + stack-utils: 2.0.6 + string-width: 8.2.2 + terminal-size: 4.0.1 + type-fest: 5.8.0 + widest-line: 6.0.0 + wrap-ansi: 9.0.2 + ws: 8.21.1 + yoga-layout: 3.2.1 + optionalDependencies: + '@types/react': 19.2.17 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + inline-style-parser@0.2.7: {} internmap@2.0.3: {} + ioredis@5.11.1: + dependencies: + '@ioredis/commands': 1.10.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3 + denque: 2.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + ip-address@10.4.0: {} is-alphabetical@2.0.1: {} @@ -6814,10 +8814,22 @@ snapshots: is-decimal@2.0.1: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.6.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-in-ci@2.0.0: {} + is-number@7.0.0: {} is-plain-obj@4.1.0: {} @@ -6828,6 +8840,10 @@ snapshots: dependencies: which-typed-array: 1.1.22 + is-unsafe@2.0.0: {} + + isarray@1.0.0: {} + isarray@2.0.5: {} isbot@5.2.1: {} @@ -6860,14 +8876,14 @@ snapshots: js-tokens@9.0.1: {} - jsdom@26.1.0(supports-color@10.2.2): + jsdom@26.1.0: dependencies: cssstyle: 4.6.0 data-urls: 5.0.0 decimal.js: 10.6.0 html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2(supports-color@10.2.2) - https-proxy-agent: 7.0.6(supports-color@10.2.2) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.24 parse5: 7.3.0 @@ -6898,10 +8914,19 @@ snapshots: '@babel/runtime': 7.29.7 ts-algebra: 2.0.0 + json-with-bigint@3.5.10: {} + json5@2.2.3: {} jsonc-parser@3.3.1: {} + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + jwa@2.0.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -6915,10 +8940,37 @@ snapshots: kleur@4.1.5: {} + kubernetes-types@1.30.0: {} + lib0@0.2.117: dependencies: isomorphic.js: 0.2.5 + libsodium-wrappers@0.8.4: + dependencies: + libsodium: 0.8.4 + + libsodium@0.8.4: {} + + libsql@0.5.29: + dependencies: + '@neon-rs/load': 0.0.4 + detect-libc: 2.0.2 + optionalDependencies: + '@libsql/darwin-arm64': 0.5.29 + '@libsql/darwin-x64': 0.5.29 + '@libsql/linux-arm-gnueabihf': 0.5.29 + '@libsql/linux-arm-musleabihf': 0.5.29 + '@libsql/linux-arm64-gnu': 0.5.29 + '@libsql/linux-arm64-musl': 0.5.29 + '@libsql/linux-x64-gnu': 0.5.29 + '@libsql/linux-x64-musl': 0.5.29 + '@libsql/win32-x64-msvc': 0.5.29 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lightningcss-android-arm64@1.32.0: optional: true @@ -6968,6 +9020,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@2.1.0: {} + + lodash@4.17.21: {} + long@5.3.2: {} longest-streak@3.1.0: {} @@ -6997,14 +9053,14 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - mdast-util-from-markdown@2.0.3(supports-color@10.2.2): + mdast-util-from-markdown@2.0.3: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 mdast-util-to-string: 4.0.0 - micromark: 4.0.2(supports-color@10.2.2) + micromark: 4.0.2 micromark-util-decode-numeric-character-reference: 2.0.2 micromark-util-decode-string: 2.0.1 micromark-util-normalize-identifier: 2.0.1 @@ -7022,67 +9078,67 @@ snapshots: mdast-util-find-and-replace: 3.0.2 micromark-util-character: 2.1.1 - mdast-util-gfm-footnote@2.1.0(supports-color@10.2.2): + mdast-util-gfm-footnote@2.1.0: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 micromark-util-normalize-identifier: 2.0.1 transitivePeerDependencies: - supports-color - mdast-util-gfm-strikethrough@2.0.0(supports-color@10.2.2): + mdast-util-gfm-strikethrough@2.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-gfm-table@2.0.0(supports-color@10.2.2): + mdast-util-gfm-table@2.0.0: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-gfm-task-list-item@2.0.0(supports-color@10.2.2): + mdast-util-gfm-task-list-item@2.0.0: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-gfm@3.1.0(supports-color@10.2.2): + mdast-util-gfm@3.1.0: dependencies: - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0(supports-color@10.2.2) - mdast-util-gfm-strikethrough: 2.0.0(supports-color@10.2.2) - mdast-util-gfm-table: 2.0.0(supports-color@10.2.2) - mdast-util-gfm-task-list-item: 2.0.0(supports-color@10.2.2) + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-mdx-expression@2.0.1(supports-color@10.2.2): + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.5 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-mdx-jsx@3.2.0(supports-color@10.2.2): + mdast-util-mdx-jsx@3.2.0: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.5 @@ -7090,7 +9146,7 @@ snapshots: '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 parse-entities: 4.0.2 stringify-entities: 4.0.4 @@ -7099,13 +9155,13 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-mdxjs-esm@2.0.1(supports-color@10.2.2): + mdast-util-mdxjs-esm@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.5 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -7143,6 +9199,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.3.0 @@ -7312,10 +9370,10 @@ snapshots: micromark-util-types@2.0.2: {} - micromark@4.0.2(supports-color@10.2.2): + micromark@4.0.2: dependencies: '@types/debug': 4.1.13 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -7345,6 +9403,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@4.1.0: {} + mimetext@3.0.28: dependencies: '@babel/runtime': 7.29.7 @@ -7352,19 +9412,9 @@ snapshots: js-base64: 3.9.2 mime-types: 2.1.35 - mimic-response@3.1.0: {} + mimic-fn@2.1.0: {} - miniflare@4.20260623.0: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - sharp: 0.34.5 - undici: 7.28.0 - workerd: 1.20260731.1 - ws: 8.21.0 - youch: 4.1.0-beta.10 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + mimic-response@3.1.0: {} miniflare@4.20260625.0: dependencies: @@ -7414,6 +9464,24 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.4: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 + optional: true + + msgpackr@2.0.5: + optionalDependencies: + msgpackr-extract: 3.0.4 + + multipasta@0.2.8: {} + nanoid@3.3.16: {} netmask@2.1.1: {} @@ -7426,6 +9494,11 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true + node-html-parser@7.1.0: dependencies: css-select: 5.2.2 @@ -7445,6 +9518,10 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + oniguruma-parser@0.12.2: {} oniguruma-to-es@4.3.6: @@ -7485,16 +9562,16 @@ snapshots: '@types/retry': 0.12.0 retry: 0.13.1 - pac-proxy-agent@7.2.0(supports-color@10.2.2): + pac-proxy-agent@7.2.0: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) - get-uri: 6.0.5(supports-color@10.2.2) - http-proxy-agent: 7.0.2(supports-color@10.2.2) - https-proxy-agent: 7.0.6(supports-color@10.2.2) + debug: 4.4.3 + get-uri: 6.0.5 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5(supports-color@10.2.2) + socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -7521,6 +9598,10 @@ snapshots: partial-json@0.1.7: {} + patch-console@2.0.0: {} + + path-expression-matcher@1.6.2: {} + path-key@3.1.1: {} path-to-regexp@6.3.0: {} @@ -7553,10 +9634,20 @@ snapshots: prettier@3.9.6: {} + process-nextick-args@2.0.1: {} + process@0.11.10: {} progress@2.0.3: {} + promise-limit@2.7.0: {} + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + property-information@7.2.0: {} protobufjs@7.6.5: @@ -7573,16 +9664,16 @@ snapshots: '@types/node': 26.1.0 long: 5.3.2 - proxy-agent@6.5.0(supports-color@10.2.2): + proxy-agent@6.5.0: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) - http-proxy-agent: 7.0.2(supports-color@10.2.2) - https-proxy-agent: 7.0.6(supports-color@10.2.2) + debug: 4.4.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0(supports-color@10.2.2) + pac-proxy-agent: 7.2.0 proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5(supports-color@10.2.2) + socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -7595,6 +9686,10 @@ snapshots: punycode@2.3.1: {} + pure-rand@8.4.2: {} + + queue-microtask@1.2.3: {} + react-day-picker@9.14.0(react@19.2.8): dependencies: '@date-fns/tz': 1.5.0 @@ -7608,17 +9703,17 @@ snapshots: react: 19.2.8 scheduler: 0.27.0 - react-markdown@10.1.0(@types/react@19.2.17)(react@19.2.8)(supports-color@10.2.2): + react-markdown@10.1.0(@types/react@19.2.17)(react@19.2.8): dependencies: '@types/hast': 3.0.5 '@types/mdast': 4.0.4 '@types/react': 19.2.17 devlop: 1.1.0 - hast-util-to-jsx-runtime: 2.3.6(supports-color@10.2.2) + hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.1 react: 19.2.8 - remark-parse: 11.0.0(supports-color@10.2.2) + remark-parse: 11.0.0 remark-rehype: 11.1.2 unified: 11.0.5 unist-util-visit: 5.1.0 @@ -7626,10 +9721,25 @@ snapshots: transitivePeerDependencies: - supports-color + react-reconciler@0.33.0(react@19.2.8): + dependencies: + react: 19.2.8 + scheduler: 0.27.0 + react-refresh@0.17.0: {} react@19.2.8: {} + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@4.7.0: dependencies: abort-controller: 3.0.0 @@ -7640,6 +9750,12 @@ snapshots: readdirp@5.0.0: {} + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + regex-recursion@6.0.2: dependencies: regex-utilities: 2.3.0 @@ -7650,21 +9766,23 @@ snapshots: dependencies: regex-utilities: 2.3.0 - remark-gfm@4.0.1(supports-color@10.2.2): + regexp-to-ast@0.5.0: {} + + remark-gfm@4.0.1: dependencies: '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0(supports-color@10.2.2) + mdast-util-gfm: 3.1.0 micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0(supports-color@10.2.2) + remark-parse: 11.0.0 remark-stringify: 11.0.0 unified: 11.0.5 transitivePeerDependencies: - supports-color - remark-parse@11.0.0(supports-color@10.2.2): + remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.3(supports-color@10.2.2) + mdast-util-from-markdown: 2.0.3 micromark-util-types: 2.0.2 unified: 11.0.5 transitivePeerDependencies: @@ -7684,12 +9802,44 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + remeda@2.33.4: {} + require-directory@2.1.1: {} reselect@5.2.0: {} + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + retry@0.12.0: {} + retry@0.13.1: {} + reusify@1.1.0: {} + + rolldown@1.1.5: + dependencies: + '@oxc-project/types': 0.139.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 + rollup@4.62.3: dependencies: '@types/estree': 1.0.9 @@ -7723,6 +9873,12 @@ snapshots: rrweb-cssom@0.8.0: {} + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -7752,6 +9908,8 @@ snapshots: gopd: 1.2.0 has-property-descriptors: 1.0.2 + setimmediate@1.0.5: {} + sha.js@2.4.12: dependencies: inherits: 2.0.4 @@ -7840,6 +9998,10 @@ snapshots: siginfo@2.0.0: {} + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + simple-concat@1.0.1: {} simple-get@4.0.1: @@ -7848,12 +10010,19 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + sisteransi@1.0.5: {} + + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + smart-buffer@4.2.0: {} - socks-proxy-agent@8.0.5(supports-color@10.2.2): + socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 socks: 2.8.9 transitivePeerDependencies: - supports-color @@ -7874,8 +10043,14 @@ snapshots: space-separated-tokens@2.0.2: {} + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + standard-as-callback@2.1.0: {} + state-local@1.0.7: {} std-env@3.10.0: {} @@ -7897,6 +10072,21 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string-width@8.2.2: + dependencies: + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -7910,10 +10100,18 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 + strnum@2.4.1: + dependencies: + anynum: 1.0.1 + style-mod@4.1.3: {} style-to-js@1.1.21: @@ -7928,6 +10126,8 @@ snapshots: symbol-tree@3.2.4: {} + tagged-tag@1.0.0: {} + tailwindcss@4.3.3: {} tapable@2.3.3: {} @@ -7971,6 +10171,8 @@ snapshots: temporal-utils@1.0.1: {} + terminal-size@4.0.1: {} + terser@5.49.0: dependencies: '@jridgewell/source-map': 0.3.11 @@ -8021,6 +10223,8 @@ snapshots: dependencies: is-number: 7.0.0 + toml@4.3.0: {} + tough-cookie@5.1.2: dependencies: tldts: 6.1.86 @@ -8041,6 +10245,10 @@ snapshots: tslib@2.8.1: {} + type-fest@5.8.0: + dependencies: + tagged-tag: 1.0.0 + typebox@1.3.7: {} typed-array-buffer@1.0.3: @@ -8060,6 +10268,8 @@ snapshots: undici@7.28.0: {} + undici@8.10.0: {} + unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 @@ -8097,13 +10307,16 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - unplugin@3.3.0(esbuild@0.28.1)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): + universal-user-agent@7.0.3: {} + + unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.62.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 optionalDependencies: esbuild: 0.28.1 + rolldown: 1.1.5 rollup: 4.62.3 vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) @@ -8117,6 +10330,14 @@ snapshots: dependencies: react: 19.2.8 + util-deprecate@1.0.2: {} + + uuid@14.0.1: {} + + valibot@1.2.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -8127,10 +10348,10 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0): + vite-node@3.2.4(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) @@ -8155,9 +10376,9 @@ snapshots: optionalDependencies: rollup: 4.62.3 - vite-tsconfig-paths@6.1.1(supports-color@10.2.2)(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): dependencies: - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) @@ -8181,7 +10402,7 @@ snapshots: terser: 5.49.0 yaml: 2.9.0 - vitest@3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0(supports-color@10.2.2))(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0): + vitest@3.2.7(@types/debug@4.1.13)(@types/node@26.1.0)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.7 @@ -8192,7 +10413,7 @@ snapshots: '@vitest/spy': 3.2.7 '@vitest/utils': 3.2.7 chai: 5.3.3 - debug: 4.4.3(supports-color@10.2.2) + debug: 4.4.3 expect-type: 1.4.0 magic-string: 0.30.21 pathe: 2.0.3 @@ -8204,12 +10425,12 @@ snapshots: tinypool: 1.1.1 tinyrainbow: 2.0.0 vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) - vite-node: 3.2.4(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(supports-color@10.2.2)(terser@5.49.0)(yaml@2.9.0) + vite-node: 3.2.4(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.13 '@types/node': 26.1.0 - jsdom: 26.1.0(supports-color@10.2.2) + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -8224,7 +10445,7 @@ snapshots: - tsx - yaml - vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): + vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@26.1.0)(jsdom@26.1.0)(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 '@vitest/mocker': 4.1.10(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) @@ -8249,36 +10470,7 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 '@types/node': 26.1.0 - jsdom: 26.1.0(supports-color@10.2.2) - transitivePeerDependencies: - - msw - - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.0)(jsdom@26.1.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)): - dependencies: - '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.10 - '@vitest/runner': 4.1.10 - '@vitest/snapshot': 4.1.10 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 - es-module-lexer: 2.3.1 - expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.1.4 - pathe: 2.0.3 - picomatch: 4.0.5 - std-env: 4.2.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.1 - vite: 7.3.6(@types/node@26.1.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.49.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@types/node': 26.1.0 - jsdom: 26.1.0(supports-color@10.2.2) + jsdom: 26.1.0 transitivePeerDependencies: - msw @@ -8324,6 +10516,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + widest-line@6.0.0: + dependencies: + string-width: 8.2.2 + workerd@1.20260731.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20260731.1 @@ -8332,30 +10528,13 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260731.1 '@cloudflare/workerd-windows-64': 1.20260731.1 - wrangler@4.104.0(@cloudflare/workers-types@4.20260702.1): - dependencies: - '@cloudflare/kv-asset-handler': 0.5.0 - '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260731.1) - blake3-wasm: 2.1.5 - esbuild: 0.28.1 - miniflare: 4.20260623.0 - path-to-regexp: 6.3.0 - unenv: 2.0.0-rc.24 - workerd: 1.20260731.1 - optionalDependencies: - '@cloudflare/workers-types': 4.20260702.1 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - wrangler@4.105.0(@cloudflare/workers-types@4.20260702.1): + wrangler@4.115.0(@cloudflare/workers-types@4.20260702.1): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260731.1) blake3-wasm: 2.1.5 esbuild: 0.28.1 - miniflare: 4.20260625.0 + miniflare: 4.20260722.1 path-to-regexp: 6.3.0 unenv: 2.0.0-rc.24 workerd: 1.20260731.1 @@ -8366,7 +10545,7 @@ snapshots: - bufferutil - utf-8-validate - wrangler@4.115.0: + wrangler@4.115.0(@cloudflare/workers-types@5.20260804.1): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260731.1) @@ -8377,6 +10556,7 @@ snapshots: unenv: 2.0.0-rc.24 workerd: 1.20260731.1 optionalDependencies: + '@cloudflare/workers-types': 5.20260804.1 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil @@ -8388,6 +10568,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} ws@8.21.0: {} @@ -8396,6 +10582,8 @@ snapshots: xml-name-validator@5.0.0: {} + xml-naming@0.3.0: {} + xmlchars@2.2.0: {} y-monaco@0.1.6(monaco-editor@0.52.2)(yjs@13.6.31): @@ -8436,6 +10624,8 @@ snapshots: dependencies: lib0: 0.2.117 + yoga-layout@3.2.1: {} + youch-core@0.3.3: dependencies: '@poppinss/exception': 1.2.3 @@ -8449,6 +10639,11 @@ snapshots: cookie: 1.1.1 youch-core: 0.3.3 + zeptomatch@2.1.0: + dependencies: + grammex: 3.1.13 + graphmatch: 1.1.1 + zod-to-json-schema@3.25.2(zod@4.4.3): dependencies: zod: 4.4.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a6d91545..ad0f74e3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,22 @@ packages: - packages/* overrides: + # Local build of alchemy with the WorkerEntrypoint feature (#1097) and its + # not-yet-published @distilled.cloud deps; remove once released to npm. + alchemy: file:.alchemy-reference/alchemy-local.tgz + '@distilled.cloud/aws': file:.alchemy-reference/distilled.cloud-aws-0.29.1.tgz + '@distilled.cloud/cloudflare-runtime': file:.alchemy-reference/distilled.cloud-cloudflare-runtime-0.15.0.tgz + '@distilled.cloud/cloudflare-rolldown-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-rolldown-plugin-0.15.0.tgz + '@distilled.cloud/cloudflare-vite-plugin': file:.alchemy-reference/distilled.cloud-cloudflare-vite-plugin-0.15.0.tgz + '@distilled.cloud/core': file:.alchemy-reference/distilled.cloud-core-0.0.0.tgz + '@distilled.cloud/cloudflare': file:.alchemy-reference/distilled.cloud-cloudflare-0.0.0.tgz + '@distilled.cloud/axiom': file:.alchemy-reference/distilled.cloud-axiom-0.31.0.tgz + '@distilled.cloud/neon': file:.alchemy-reference/distilled.cloud-neon-0.31.0.tgz + '@distilled.cloud/planetscale': file:.alchemy-reference/distilled.cloud-planetscale-0.31.0.tgz + # Pin while the local-alchemy overrides above force a full re-resolution: + # without this, every package's wrangler jumps to latest-in-range and the + # lockfile churns repo-wide. Remove together with the block above. + wrangler: 4.115.0 workerd: ">=1.20260623.1" # Pin js-yaml to the patched release (CVE-2026-53550); 4.1.1 (via @mdxeditor/editor) is vulnerable. js-yaml@4.1.1: ^4.2.0 @@ -29,6 +45,8 @@ allowBuilds: '@google/genai': true core-js-pure: true esbuild: true + # msgpackr-extract is an optional native accelerator (via alchemy); the JS fallback is fine. + msgpackr-extract: false protobufjs: true sharp: true workerd: true