From 7568db88fa39248602997c34c5d5f36af58bcf99 Mon Sep 17 00:00:00 2001 From: Kacper Wojciechowski <39823706+jog1t@users.noreply.github.com> Date: Tue, 8 Apr 2025 20:17:08 +0200 Subject: [PATCH] refactor(rivet): add auth to inspector --- .../actor-core-cli/src/commands/deploy.tsx | 647 +++++++++--------- packages/actor-core-cli/src/ui/Workflow.tsx | 3 +- packages/actor-core-cli/src/workflow.tsx | 27 +- packages/platforms/rivet/src/actor_handler.ts | 48 +- .../platforms/rivet/src/manager_handler.ts | 23 + packages/platforms/rivet/src/rivet_client.ts | 12 +- yarn.lock | 168 +---- 7 files changed, 425 insertions(+), 503 deletions(-) diff --git a/packages/actor-core-cli/src/commands/deploy.tsx b/packages/actor-core-cli/src/commands/deploy.tsx index ac92ed62d..156051ea2 100644 --- a/packages/actor-core-cli/src/commands/deploy.tsx +++ b/packages/actor-core-cli/src/commands/deploy.tsx @@ -25,7 +25,9 @@ export const deploy = new Command() new Argument("", "The platform to deploy to").choices(["rivet"]), ) .addArgument(new Argument("", "Location of the app.ts file")) - .addOption(new Option("-r, --root [path]", "Location of the project").default("./")) + .addOption( + new Option("-r, --root [path]", "Location of the project").default("./"), + ) .addOption(new Option("-p, --path [path]", "Location of the app.ts file")) .addOption(new Option("--skip-manager", "Skip deploying ActorCore manager")) .addOption(new Option("--env ", "Specify environment to deploy to")) @@ -34,31 +36,34 @@ export const deploy = new Command() "afterAll", "\nMissing your favorite platform?\nLet us know! https://github.com/rivet-gg/actor-core/issues/new", ) - .action(async (platform, appPath: string, opts: { - root: string; - port?: string; - skipManager: boolean, - env?: string, - version?: string, - }) => { - const cwd = path.join(process.cwd(), opts.root); - - const exec = $({ - cwd, - env: { ...process.env, npm_config_yes: "true" }, - }); - - await workflow( - "Deploy actors to Rivet", - async function* (ctx) { - const { config, cli } = yield* ctx.task( - "Prepare", - async function* (ctx) { - const config = yield* validateConfigTask(ctx, cwd, appPath); - - const cli = yield* ctx.task( - "Locale rivet-cli", - async function* (ctx) { + .action( + async ( + platform, + appPath: string, + opts: { + root: string; + port?: string; + skipManager: boolean; + env?: string; + version?: string; + }, + ) => { + const cwd = path.join(process.cwd(), opts.root); + + const exec = $({ + cwd, + env: { ...process.env, npm_config_yes: "true" }, + }); + + await workflow( + "Deploy actors to Rivet", + async function* (ctx) { + const { config, cli } = yield* ctx.task( + "Prepare", + async function* (ctx) { + const config = yield* validateConfigTask(ctx, cwd, appPath); + + const cli = yield* ctx.task("Locale rivet-cli", async (ctx) => { let cliLocation = process.env.RIVET_CLI_PATH || null; if (!cliLocation) { @@ -84,57 +89,55 @@ export const deploy = new Command() } return ["npx", "@rivet-gg/cli@latest"]; - }, - ); + }); - return { config, cli }; - }, - ); - - const { accessToken, projectName, envName, endpoint } = yield* ctx.task( - "Auth with Rivet", - async function* (ctx) { - const { stdout } = await exec`${cli} metadata auth-status`; - const isLogged = stdout === "true"; - - let endpoint: string | undefined; - if (!isLogged) { - const isUsingCloud = yield* ctx.prompt( - "Are you using Rivet Cloud?", - { - type: "confirm", - }, - ); - - endpoint = "https://api.rivet.gg"; - if (!isUsingCloud) { - endpoint = yield* ctx.prompt("What is the API endpoint?", { - type: "text", - defaultValue: "http://localhost:8080", - validate: (input) => { - if (z.string().url().safeParse(input).success === false) { - return "Please provide a valid URL"; - } - return true; + return { config, cli }; + }, + ); + + const { accessToken, projectName, envName, endpoint } = + yield* ctx.task("Auth with Rivet", async function* (ctx) { + const { stdout } = await exec`${cli} metadata auth-status`; + const isLogged = stdout === "true"; + + let endpoint: string | undefined; + if (!isLogged) { + const isUsingCloud = yield* ctx.prompt( + "Are you using Rivet Cloud?", + { + type: "confirm", }, - }); + ); + + endpoint = "https://api.rivet.gg"; + if (!isUsingCloud) { + endpoint = yield* ctx.prompt("What is the API endpoint?", { + type: "text", + defaultValue: "http://localhost:8080", + validate: (input) => { + if (z.string().url().safeParse(input).success === false) { + return "Please provide a valid URL"; + } + return true; + }, + }); + } + + await exec`${cli} login --api-endpoint=${endpoint}`; + } else { + const { stdout } = await exec`${cli} metadata api-endpoint`; + endpoint = stdout; } - await exec`${cli} login --api-endpoint=${endpoint}`; - } else { - const { stdout } = await exec`${cli} metadata api-endpoint`; - endpoint = stdout; - } - - const { stdout: accessToken } = - await exec`${cli} metadata access-token`; - - const envName = - opts.env ?? - (yield* ctx.task("Select environment", async function* (ctx) { - const { stdout } = await exec`${cli} env ls --json`; - const envs = JSON.parse(stdout); - return yield* ctx.prompt("Select environment", { + const { stdout: accessToken } = + await exec`${cli} metadata access-token`; + + const { stdout: rawEnvs } = await exec`${cli} env ls --json`; + const envs = JSON.parse(rawEnvs); + + const envName = + opts.env ?? + (yield* ctx.prompt("Select environment", { type: "select", choices: envs.map( (env: { display_name: string; name_id: string }) => ({ @@ -142,290 +145,292 @@ export const deploy = new Command() value: env.name_id, }), ), - }); - })); + })); - const { stdout: projectName } = - await exec`${cli} metadata project-name-id`; + const { stdout: projectName } = + await exec`${cli} metadata project-name-id`; - return { accessToken, projectName, envName, endpoint }; - }, - ); + return { accessToken, projectName, envName, endpoint }; + }); - const Rivet = new RivetClient({ - token: accessToken, - environment: endpoint, - }); + const Rivet = new RivetClient({ + token: accessToken, + environment: endpoint, + }); - const RivetHttp = createRivetApi(endpoint, accessToken); + const RivetHttp = createRivetApi(endpoint, accessToken); - let manager = undefined; - if (!opts.skipManager) { - manager = yield* ctx.task("Deploy ActorCore", async function* (ctx) { - yield fs.mkdir(path.join(cwd, ".actorcore"), { - recursive: true, - }); + let manager = undefined; + if (!opts.skipManager) { + manager = yield* ctx.task( + "Deploy ActorCore", + async function* (ctx) { + yield fs.mkdir(path.join(cwd, ".actorcore"), { + recursive: true, + }); - const entrypoint = path.join(cwd, ".actorcore", "manager.js"); - // Calculate relative path from entrypoint to appPath - const relativePath = path.relative( - path.dirname(entrypoint), - path.join(cwd, appPath) - ); - yield fs.writeFile( - entrypoint, - dedent` + const entrypoint = path.join(cwd, ".actorcore", "manager.js"); + // Calculate relative path from entrypoint to appPath + const relativePath = path.relative( + path.dirname(entrypoint), + path.join(cwd, appPath), + ); + yield fs.writeFile( + entrypoint, + dedent` import { createManagerHandler } from "@actor-core/rivet"; import { app } from "${relativePath}"; export default createManagerHandler({ app }); `, - ); - - const output = - await exec`${cli} publish manager --env ${envName} --tags access=private ${entrypoint}`; - if (output.exitCode !== 0) { - throw ctx.error("Failed to deploy ActorCore.", { - hint: "Check the logs above for more information.", - }); - } - - const { actors: managers } = await Rivet.actor.list({ - tagsJson: JSON.stringify({ name: "manager" }), - environment: envName, - project: projectName, - includeDestroyed: false, - }); + ); - if (managers.length > 1) { - yield* ctx.warn( - "More than 1 manager actor is running. We recommend manually stopping one of them.", - ); - } + const output = + await exec`${cli} publish manager --env ${envName} --tags access=private ${entrypoint}`; + if (output.exitCode !== 0) { + throw ctx.error("Failed to deploy ActorCore.", { + hint: "Check the logs above for more information.", + }); + } - if (managers.length > 0) { - for (const manager of managers) { - await Rivet.actor.upgrade(manager.id, { - project: projectName, + const { actors: managers } = await Rivet.actor.list({ + tagsJson: JSON.stringify({ name: "manager" }), environment: envName, - body: { - buildTags: { - name: "manager", - current: "true", - }, - }, + project: projectName, + includeDestroyed: false, }); - } - const manager = managers.find( - (m) => !!createActorEndpoint(m.network), - ); + if (managers.length > 1) { + yield* ctx.warn( + "More than 1 manager actor is running. We recommend manually stopping one of them.", + ); + } - if (!manager) { - throw ctx.error("Failed to find ActorCore Endpoint.", { - hint: "Any existing manager actor is not running or not accessible.", - }); - } + if (managers.length > 0) { + for (const manager of managers) { + await Rivet.actor.upgrade(manager.id, { + project: projectName, + environment: envName, + body: { + buildTags: { + name: "manager", + current: "true", + }, + }, + }); + } - return manager; - } else { - const serviceToken = await getServiceToken(RivetHttp, { - project: projectName, - env: envName, - }); + const manager = managers.find( + (m) => !!createActorEndpoint(m.network), + ); - const { regions } = await Rivet.actor.regions.list({ - project: projectName, - environment: envName, - }); + if (!manager) { + throw ctx.error("Failed to find ActorCore Endpoint.", { + hint: "Any existing manager actor is not running or not accessible.", + }); + } - // find closest region - const region = regions.find( - (r) => r.id === "atl" || r.id === "local", - ); + return manager; + } else { + const serviceToken = await getServiceToken(RivetHttp, { + project: projectName, + env: envName, + }); + + const { regions } = await Rivet.actor.regions.list({ + project: projectName, + environment: envName, + }); + + // find closest region + const region = regions.find( + (r) => r.id === "atl" || r.id === "local", + ); - if (!region) { - throw ctx.error( - "No closest region found. Please contact support.", - ); - } + if (!region) { + throw ctx.error( + "No closest region found. Please contact support.", + ); + } - const { actor } = await Rivet.actor.create({ - project: projectName, - environment: envName, - body: { - region: region.id, - tags: { name: "manager", owner: "rivet" }, - buildTags: { name: "manager", current: "true" }, - runtime: { - environment: { - RIVET_SERVICE_TOKEN: serviceToken, - }, - }, - network: { - mode: "bridge", - ports: { - http: { - protocol: "https", - routing: { - guard: {}, + const { actor } = await Rivet.actor.create({ + project: projectName, + environment: envName, + body: { + region: region.id, + tags: { name: "manager", owner: "rivet" }, + buildTags: { name: "manager", current: "true" }, + runtime: { + environment: { + RIVET_SERVICE_TOKEN: serviceToken, }, }, + network: { + mode: "bridge", + ports: { + http: { + protocol: "https", + routing: { + guard: {}, + }, + }, + }, + }, + lifecycle: { + durable: true, + }, }, - }, - lifecycle: { - durable: true, - }, - }, - }); - return actor; - } - }); - } - - for (const [idx, actorName] of Object.keys( - config.app.config.actors, - ).entries()) { - yield* ctx.task( - `Deploy & upload "${actorName}" build (${idx + 1}/${ - Object.keys(config.app.config.actors).length - })`, - async function* (ctx) { - yield fs.mkdir(path.join(cwd, ".actorcore"), { - recursive: true, - }); + }); + return actor; + } + }, + ); + } + + for (const [idx, actorName] of Object.keys( + config.app.config.actors, + ).entries()) { + yield* ctx.task( + `Deploy & upload "${actorName}" build (${idx + 1}/${ + Object.keys(config.app.config.actors).length + })`, + async function* (ctx) { + yield fs.mkdir(path.join(cwd, ".actorcore"), { + recursive: true, + }); - const entrypoint = path.join( - cwd, - ".actorcore", - `entrypoint-${actorName}.js`, - ); - // Calculate relative path from entrypoint to appPath - const relativePath = path.relative( - path.dirname(entrypoint), - path.join(cwd, appPath) - ); - yield fs.writeFile( - entrypoint, - dedent` + const entrypoint = path.join( + cwd, + ".actorcore", + `entrypoint-${actorName}.js`, + ); + // Calculate relative path from entrypoint to appPath + const relativePath = path.relative( + path.dirname(entrypoint), + path.join(cwd, appPath), + ); + yield fs.writeFile( + entrypoint, + dedent` import { createActorHandler } from "@actor-core/rivet"; import { app } from "${relativePath}"; export default createActorHandler({ app }); `, - ); + ); - const actorTags = { - access: "public", - framework: "actor-core", - "framework-version": VERSION, - }; + const actorTags = { + access: "public", + framework: "actor-core", + "framework-version": VERSION, + }; - const tagsArray = Object.entries(actorTags) - .map(([key, value]) => `${key}=${value}`) - .join(","); + const tagsArray = Object.entries(actorTags) + .map(([key, value]) => `${key}=${value}`) + .join(","); - const output = - await exec`${cli} publish --env=${envName} --tags=${tagsArray} ${actorName} ${entrypoint}`; + const output = + await exec`${cli} publish --env=${envName} --tags=${tagsArray} ${actorName} ${entrypoint}`; - if (output.exitCode !== 0) { - throw ctx.error("Failed to deploy & upload actors.", { - hint: "Check the logs above for more information.", - }); - } + if (output.exitCode !== 0) { + throw ctx.error("Failed to deploy & upload actors.", { + hint: "Check the logs above for more information.", + }); + } - await Rivet.actor.upgradeAll({ - project: projectName, - environment: envName, - body: { - tags: { name: actorName }, - buildTags: { - name: actorName, - current: "true", + await Rivet.actor.upgradeAll({ + project: projectName, + environment: envName, + body: { + tags: { name: actorName }, + buildTags: { + name: actorName, + current: "true", + }, }, - }, - }); - }, - ); - } - - const managerEndpoint = manager - ? createActorEndpoint(manager.network) - : undefined; - const actorName = Object.keys(config.app.config.actors)[0]; - const hub = endpoint.includes("localhost") - ? `${endpoint}/ui` - : "https://hub.rivet.gg"; - - yield ctx.render( - - - Build uploaded successfully! - - - {opts.skipManager ? ( - <> - ▸ ActorCore Manager: - - - Manager deployment was skipped. - - - ) : managerEndpoint ? ( - <> - ▸ Connect to your Actor: - - - - {dedent`const client = createClient("${managerEndpoint}");`} - - - - {dedent`const ${actorName} = await client.${actorName}.get();`} - - - - ) : ( - <> - ▸ Connect to your Actor: - - - - Failed to deploy Actor Manager. Please check the logs in - Rivet Hub for more information. - - - - )} - + }); + }, + ); + } + + const managerEndpoint = manager + ? createActorEndpoint(manager.network) + : undefined; + const actorName = Object.keys(config.app.config.actors)[0]; + const hub = endpoint?.includes("localhost") + ? `${endpoint}/ui` + : "https://hub.rivet.gg"; + + yield ctx.render( + + + Build uploaded successfully! + - ▸ Resources - - - {!opts.skipManager && managerEndpoint ? ( - Endpoint - ) : null} - Builds - Actors - Documentation - - - {!opts.skipManager && managerEndpoint ? ( - {managerEndpoint} - ) : null} - {`${hub}/projects/${projectName}/environments/${envName}/builds`} - {`${hub}/projects/${projectName}/environments/${envName}/actors`} - - https://actorcore.org/ + {opts.skipManager ? ( + <> + ▸ ActorCore Manager: + + + Manager deployment was skipped. + + + ) : managerEndpoint ? ( + <> + ▸ Connect to your Actor: + + + + {dedent`const client = createClient("${managerEndpoint}");`} + + + + {dedent`const ${actorName} = await client.${actorName}.get();`} + + + + ) : ( + <> + ▸ Connect to your Actor: + + + + Failed to deploy Actor Manager. Please check the logs in + Rivet Hub for more information. + + + + )} + + + ▸ Resources + + + {!opts.skipManager && managerEndpoint ? ( + Endpoint + ) : null} + Builds + Actors + Documentation + + + {!opts.skipManager && managerEndpoint ? ( + {managerEndpoint} + ) : null} + {`${hub}/projects/${projectName}/environments/${envName}/builds`} + {`${hub}/projects/${projectName}/environments/${envName}/actors`} + + https://actorcore.org/ + - - , - ); - }, - { showLabel: false }, - ).render(); - }); + , + ); + }, + { showLabel: false }, + ).render(); + }, + ); diff --git a/packages/actor-core-cli/src/ui/Workflow.tsx b/packages/actor-core-cli/src/ui/Workflow.tsx index 602243537..2be643a1a 100644 --- a/packages/actor-core-cli/src/ui/Workflow.tsx +++ b/packages/actor-core-cli/src/ui/Workflow.tsx @@ -170,8 +170,7 @@ export function Task({ if ("__taskProgress" in task) { return ( <> - {task.meta.opts?.showLabel === false && - task.status !== "error" ? null : ( + {task.meta.opts?.showLabel === false ? null : ( ((resolve) => setTimeout(resolve, ms)), task: runner.bind(null, { ...meta, - parent: meta.parent, + parent: meta.id, name: "", }) as Context["task"], render(children: React.ReactNode) { @@ -296,7 +296,7 @@ export function workflow( withResolvers>(); yield WorkflowAction.prompt( - { ...meta, id, name: question }, + { ...meta, parent: meta.id, id, name: question }, question, { answer: null, @@ -308,7 +308,7 @@ export function workflow( const result = await promise; yield WorkflowAction.prompt( - { ...meta, id, name: question }, + { ...meta, parent: meta.id, id, name: question }, question, { answer: result, @@ -349,7 +349,7 @@ export function workflow( } if ("__taskProgress" in task) { - const parent = task.meta?.parent || title; + const parent = task.meta?.parent || id; parentMap.set(task.meta.id, parent); // Propagate errors up the tree if (task.status === "error") { @@ -359,7 +359,6 @@ export function workflow( yield WorkflowAction.progress( { id: parentTask, - name: parentTask, parent: grandParent || null, }, "error", @@ -437,17 +436,21 @@ export function workflow( , ); - - if ("__taskProgress" in task && task.status === "error") { - renderUtils.unmount(); - process.exit(1); - break; - } } for (const hook of hooks.afterAll) { hook({ tasks, logs }); } + + const hadError = tasks.some( + (task) => "__taskProgress" in task && task.status === "error", + ); + + if (hadError) { + await renderUtils.waitUntilExit(); + renderUtils.unmount(); + process.exit(1); + } }, }; } diff --git a/packages/platforms/rivet/src/actor_handler.ts b/packages/platforms/rivet/src/actor_handler.ts index a4b996796..264024260 100644 --- a/packages/platforms/rivet/src/actor_handler.ts +++ b/packages/platforms/rivet/src/actor_handler.ts @@ -7,6 +7,7 @@ import type { RivetHandler } from "./util"; import { PartitionTopologyActor } from "actor-core/topologies/partition"; import { ConfigSchema, type InputConfig } from "./config"; import { RivetActorDriver } from "./actor_driver"; +import { rivetRequest } from "./rivet_client"; export function createActorHandler(inputConfig: InputConfig): RivetHandler { const driverConfig = ConfigSchema.parse(inputConfig); @@ -24,6 +25,9 @@ export function createActorHandler(inputConfig: InputConfig): RivetHandler { throw "Invalid port"; } + const endpoint = Deno.env.get("RIVET_API_ENDPOINT"); + if (!endpoint) throw new Error("missing RIVET_API_ENDPOINT"); + // Setup actor driver if (!driverConfig.drivers) driverConfig.drivers = {}; if (!driverConfig.drivers.actor) { @@ -37,8 +41,48 @@ export function createActorHandler(inputConfig: InputConfig): RivetHandler { driverConfig.app.config.inspector = { enabled: true, - // TODO: Add permission check - onRequest: async () => true, + onRequest: async (c) => { + const url = new URL(c.req.url); + const token = url.searchParams.get("token"); + + if (!token) { + return false; + } + + try { + const response = await rivetRequest( + { endpoint, token }, + "GET", + "/cloud/auth/inspect", + ); + return "agent" in response; + } catch (e) { + return false; + } + }, + }; + + const corsConfig = driverConfig.app.config.cors; + + // Enable CORS for Rivet domains + driverConfig.app.config.cors = { + ...driverConfig.app.config.cors, + origin: (origin, c) => { + const isRivetOrigin = + origin.endsWith(".rivet.gg") || origin.includes("localhost:"); + const configOrigin = corsConfig?.origin; + + if (isRivetOrigin) { + return origin; + } + if (typeof configOrigin === "function") { + return configOrigin(origin, c); + } + if (typeof configOrigin === "string") { + return configOrigin; + } + return null; + }, }; // Create actor topology diff --git a/packages/platforms/rivet/src/manager_handler.ts b/packages/platforms/rivet/src/manager_handler.ts index 3ad735e38..984c3912e 100644 --- a/packages/platforms/rivet/src/manager_handler.ts +++ b/packages/platforms/rivet/src/manager_handler.ts @@ -40,6 +40,29 @@ export function createManagerHandler(inputConfig: InputConfig): RivetHandler { enabled: false, }; + const corsConfig = driverConfig.app.config.cors; + + // Enable CORS for Rivet domains + driverConfig.app.config.cors = { + ...driverConfig.app.config.cors, + origin: (origin, c) => { + const isRivetOrigin = + origin.endsWith(".rivet.gg") || origin.includes("localhost:"); + const configOrigin = corsConfig?.origin; + + if (isRivetOrigin) { + return origin; + } + if (typeof configOrigin === "function") { + return configOrigin(origin, c); + } + if (typeof configOrigin === "string") { + return configOrigin; + } + return null; + }, + }; + // Setup manager driver if (!driverConfig.drivers) driverConfig.drivers = {}; if (!driverConfig.drivers.manager) { diff --git a/packages/platforms/rivet/src/rivet_client.ts b/packages/platforms/rivet/src/rivet_client.ts index 3ef7c890c..188a9f5bb 100644 --- a/packages/platforms/rivet/src/rivet_client.ts +++ b/packages/platforms/rivet/src/rivet_client.ts @@ -1,8 +1,8 @@ export interface RivetClientConfig { endpoint: string; token: string; - project: string; - environment: string; + project?: string; + environment?: string; } export async function rivetRequest( @@ -12,8 +12,12 @@ export async function rivetRequest( body?: RequestBody, ): Promise { const urlBuilder = new URL(url, config.endpoint); - urlBuilder.searchParams.append("project", config.project); - urlBuilder.searchParams.append("environment", config.environment); + if (config.project) { + urlBuilder.searchParams.append("project", config.project); + } + if (config.environment) { + urlBuilder.searchParams.append("environment", config.environment); + } const response = await fetch(urlBuilder, { method, diff --git a/yarn.lock b/yarn.lock index fd0e94c98..f6916473e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,7 +5,7 @@ __metadata: version: 8 cacheKey: 10c0 -"@actor-core/bun@workspace:*, @actor-core/bun@workspace:packages/platforms/bun": +"@actor-core/bun@workspace:packages/platforms/bun": version: 0.0.0-use.local resolution: "@actor-core/bun@workspace:packages/platforms/bun" dependencies: @@ -69,7 +69,7 @@ __metadata: languageName: unknown linkType: soft -"@actor-core/cloudflare-workers@workspace:*, @actor-core/cloudflare-workers@workspace:packages/platforms/cloudflare-workers": +"@actor-core/cloudflare-workers@workspace:packages/platforms/cloudflare-workers": version: 0.0.0-use.local resolution: "@actor-core/cloudflare-workers@workspace:packages/platforms/cloudflare-workers" dependencies: @@ -129,7 +129,7 @@ __metadata: languageName: unknown linkType: soft -"@actor-core/nodejs@workspace:*, @actor-core/nodejs@workspace:^, @actor-core/nodejs@workspace:packages/platforms/nodejs": +"@actor-core/nodejs@workspace:^, @actor-core/nodejs@workspace:packages/platforms/nodejs": version: 0.0.0-use.local resolution: "@actor-core/nodejs@workspace:packages/platforms/nodejs" dependencies: @@ -182,7 +182,7 @@ __metadata: languageName: unknown linkType: soft -"@actor-core/rivet@workspace:*, @actor-core/rivet@workspace:packages/platforms/rivet": +"@actor-core/rivet@workspace:packages/platforms/rivet": version: 0.0.0-use.local resolution: "@actor-core/rivet@workspace:packages/platforms/rivet" dependencies: @@ -2581,7 +2581,7 @@ __metadata: languageName: node linkType: hard -"@types/bun@npm:^1.2.2, @types/bun@npm:^1.2.4": +"@types/bun@npm:^1.2.2": version: 1.2.8 resolution: "@types/bun@npm:1.2.8" dependencies: @@ -2599,7 +2599,7 @@ __metadata: languageName: node linkType: hard -"@types/deno@npm:^2.0.0, @types/deno@npm:^2.2.0": +"@types/deno@npm:^2.0.0": version: 2.2.0 resolution: "@types/deno@npm:2.2.0" checksum: 10c0/cb45bbffe66a3008224a509c6bcb338921cc68b9045363f77ba5d84650d879b8fd4c810db24369a93fbce4a8e2855808bb141c0447feb47d911a7512ba374bde @@ -3608,89 +3608,6 @@ __metadata: languageName: node linkType: hard -"chat-room-bun@workspace:templates/chat-room-bun": - version: 0.0.0-use.local - resolution: "chat-room-bun@workspace:templates/chat-room-bun" - dependencies: - "@actor-core/bun": "workspace:*" - "@actor-core/cli": "workspace:*" - "@types/bun": "npm:^1.2.4" - "@types/node": "npm:^22.13.9" - "@types/prompts": "npm:^2" - actor-core: "workspace:*" - prompts: "npm:^2.4.2" - tsx: "npm:^3.12.7" - typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"chat-room-cloudflare-workers@workspace:templates/chat-room-cloudflare-workers": - version: 0.0.0-use.local - resolution: "chat-room-cloudflare-workers@workspace:templates/chat-room-cloudflare-workers" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/cloudflare-workers": "workspace:*" - "@cloudflare/workers-types": "npm:^4.20250129.0" - "@types/node": "npm:^22.13.9" - "@types/prompts": "npm:^2" - actor-core: "workspace:*" - prompts: "npm:^2.4.2" - tsx: "npm:^3.12.7" - typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" - wrangler: "npm:^3.101.0" - languageName: unknown - linkType: soft - -"chat-room-nodejs@workspace:templates/chat-room-nodejs": - version: 0.0.0-use.local - resolution: "chat-room-nodejs@workspace:templates/chat-room-nodejs" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/nodejs": "workspace:*" - "@types/node": "npm:^22.13.9" - "@types/prompts": "npm:^2" - actor-core: "workspace:*" - prompts: "npm:^2.4.2" - tsx: "npm:^3.12.7" - typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"chat-room-noop@workspace:templates/chat-room-noop": - version: 0.0.0-use.local - resolution: "chat-room-noop@workspace:templates/chat-room-noop" - dependencies: - "@actor-core/cli": "workspace:*" - "@types/node": "npm:^22.13.9" - "@types/prompts": "npm:^2" - actor-core: "workspace:*" - prompts: "npm:^2.4.2" - tsx: "npm:^3.12.7" - typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"chat-room-rivet@workspace:templates/chat-room-rivet": - version: 0.0.0-use.local - resolution: "chat-room-rivet@workspace:templates/chat-room-rivet" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/rivet": "workspace:*" - "@types/deno": "npm:^2.2.0" - "@types/node": "npm:^22.13.9" - "@types/prompts": "npm:^2" - actor-core: "workspace:*" - prompts: "npm:^2.4.2" - tsx: "npm:^3.12.7" - typescript: "npm:^5.5.2" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - "chat-room@workspace:examples/chat-room": version: 0.0.0-use.local resolution: "chat-room@workspace:examples/chat-room" @@ -3964,79 +3881,6 @@ __metadata: languageName: node linkType: hard -"counter-bun@workspace:templates/counter-bun": - version: 0.0.0-use.local - resolution: "counter-bun@workspace:templates/counter-bun" - dependencies: - "@actor-core/bun": "workspace:*" - "@actor-core/cli": "workspace:*" - "@types/bun": "npm:^1.2.4" - "@types/node": "npm:^22.13.9" - actor-core: "workspace:*" - tsx: "npm:^3.12.7" - typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"counter-cloudflare-workers@workspace:templates/counter-cloudflare-workers": - version: 0.0.0-use.local - resolution: "counter-cloudflare-workers@workspace:templates/counter-cloudflare-workers" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/cloudflare-workers": "workspace:*" - "@cloudflare/workers-types": "npm:^4.20250129.0" - "@types/node": "npm:^22.13.9" - actor-core: "workspace:*" - tsx: "npm:^3.12.7" - typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" - wrangler: "npm:^3.101.0" - languageName: unknown - linkType: soft - -"counter-nodejs@workspace:templates/counter-nodejs": - version: 0.0.0-use.local - resolution: "counter-nodejs@workspace:templates/counter-nodejs" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/nodejs": "workspace:*" - "@types/node": "npm:^22.13.9" - actor-core: "workspace:*" - tsx: "npm:^3.12.7" - typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"counter-noop@workspace:templates/counter-noop": - version: 0.0.0-use.local - resolution: "counter-noop@workspace:templates/counter-noop" - dependencies: - "@actor-core/cli": "workspace:*" - "@types/node": "npm:^22.13.9" - actor-core: "workspace:*" - tsx: "npm:^3.12.7" - typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - -"counter-rivet@workspace:templates/counter-rivet": - version: 0.0.0-use.local - resolution: "counter-rivet@workspace:templates/counter-rivet" - dependencies: - "@actor-core/cli": "workspace:*" - "@actor-core/rivet": "workspace:*" - "@types/deno": "npm:^2.2.0" - "@types/node": "npm:^22.13.9" - actor-core: "workspace:*" - tsx: "npm:^3.12.7" - typescript: "npm:^5.7.3" - vitest: "npm:^3.0.9" - languageName: unknown - linkType: soft - "counter@workspace:examples/counter": version: 0.0.0-use.local resolution: "counter@workspace:examples/counter"