History

Update cloud environment configuration and enhance session management

- Added MCP_AUTHKIT_DOMAIN and MCP_RESOURCE_ORIGIN to environment variables for better configuration management. - Updated the McpSessionDO class to utilize the new environment variables for AUTHKIT_DOMAIN and RESOURCE_ORIGIN. - Improved the session handling by integrating the resolveOrganization helper for organization resolution. - Modified package.json files to include a new patched dependency for @cloudflare/vite-plugin. - Adjusted development scripts across various apps to include the --no-tls flag for consistency.

Rhys Sullivan committed 7 months ago

Commit c688e1b1 parent 5693f5d12 files · +72 −14Browse files

Unified · Split

12 files
  1. apps/cloud/package.json +1 −1
  2. apps/cloud/src/env.ts +4 −0
  3. apps/cloud/src/mcp-session.ts +4 −3
  4. apps/cloud/src/mcp.ts +4 −2
  5. apps/local/package.json +1 −1
  6. apps/marketing/package.json +1 −1
  7. bun.lock +1 −0
  8. opencode.json +10 −0
  9. package.json +2 −1
  10. packages/kernel/runtime-dynamic-worker/src/normalize.test.ts +16 −0
  11. packages/kernel/runtime-dynamic-worker/src/normalize.ts +14 −5
  12. patches/@cloudflare%2Fvite-plugin@1.31.2.patch +14 −0
apps/cloud/package.json+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5 "type": "module",5 "type": "module",
6 "scripts": {6 "scripts": {
7 "dev": "bun run dev:proxy && concurrently -n db,vite -c blue,green \"bun run dev:db\" \"bun run dev:vite\"",7 "dev": "bun run dev:proxy && concurrently -n db,vite -c blue,green \"bun run dev:db\" \"bun run dev:vite\"",
8 "dev:proxy": "portless proxy start --port 1355 || true",8 "dev:proxy": "portless proxy start --port 1355 --no-tls || true",
9 "dev:db": "bun run scripts/dev-db.ts",9 "dev:db": "bun run scripts/dev-db.ts",
10 "dev:vite": "CLOUDFLARE_INCLUDE_PROCESS_ENV=true op run --env-file=.env.op -- portless run --name executor-cloud vite dev",10 "dev:vite": "CLOUDFLARE_INCLUDE_PROCESS_ENV=true op run --env-file=.env.op -- portless run --name executor-cloud vite dev",
11 "db:generate": "drizzle-kit generate",11 "db:generate": "drizzle-kit generate",
apps/cloud/src/env.ts+4−0
@@ -10,6 +10,8 @@ const serverShape = { · 9 unmodified lines
10 WORKOS_CLIENT_ID: Env.string("WORKOS_CLIENT_ID"),10 WORKOS_CLIENT_ID: Env.string("WORKOS_CLIENT_ID"),
11 WORKOS_COOKIE_PASSWORD: Env.string("WORKOS_COOKIE_PASSWORD"),11 WORKOS_COOKIE_PASSWORD: Env.string("WORKOS_COOKIE_PASSWORD"),
12 VITE_PUBLIC_SITE_URL: Env.stringOr("VITE_PUBLIC_SITE_URL", ""),12 VITE_PUBLIC_SITE_URL: Env.stringOr("VITE_PUBLIC_SITE_URL", ""),
13 MCP_AUTHKIT_DOMAIN: Env.stringOr("MCP_AUTHKIT_DOMAIN", "https://signin.executor.sh"),
14 MCP_RESOURCE_ORIGIN: Env.stringOr("MCP_RESOURCE_ORIGIN", "https://executor.sh"),
13 AUTUMN_SECRET_KEY: Env.stringOr("AUTUMN_SECRET_KEY", ""),15 AUTUMN_SECRET_KEY: Env.stringOr("AUTUMN_SECRET_KEY", ""),
14 SENTRY_DSN: Env.stringOr("SENTRY_DSN", ""),16 SENTRY_DSN: Env.stringOr("SENTRY_DSN", ""),
15 AXIOM_TOKEN: Env.stringOr("AXIOM_TOKEN", ""),17 AXIOM_TOKEN: Env.stringOr("AXIOM_TOKEN", ""),
@@ -27,6 +29,8 @@ type ServerEnv = SharedEnv & · 11 unmodified lines
27 WORKOS_CLIENT_ID: string;29 WORKOS_CLIENT_ID: string;
28 WORKOS_COOKIE_PASSWORD: string;30 WORKOS_COOKIE_PASSWORD: string;
29 VITE_PUBLIC_SITE_URL: string;31 VITE_PUBLIC_SITE_URL: string;
32 MCP_AUTHKIT_DOMAIN: string;
33 MCP_RESOURCE_ORIGIN: string;
30 AUTUMN_SECRET_KEY: string;34 AUTUMN_SECRET_KEY: string;
31 SENTRY_DSN: string;35 SENTRY_DSN: string;
32 AXIOM_TOKEN: string;36 AXIOM_TOKEN: string;
apps/cloud/src/mcp-session.ts+4−3
@@ -15,6 +15,8 @@ import type { DrizzleDb } from "@executor/storage-postgres"; · 14 unmodified lines
15import * as sharedSchema from "@executor/storage-postgres/schema";15import * as sharedSchema from "@executor/storage-postgres/schema";
16 16
17import { UserStoreService } from "./auth/context";17import { UserStoreService } from "./auth/context";
18import { resolveOrganization } from "./auth/resolve-organization";
19import { WorkOSAuth } from "./auth/workos";
18import { server } from "./env";20import { server } from "./env";
19import { createOrgExecutor } from "./services/executor";21import { createOrgExecutor } from "./services/executor";
20import { DbService } from "./services/db";22import { DbService } from "./services/db";
@@ -105,11 +107,10 @@ export class McpSessionDO extends DurableObject { · 84 unmodified lines
105 107
106 const DbLive = Layer.succeed(DbService, this.dbHandle.db);108 const DbLive = Layer.succeed(DbService, this.dbHandle.db);
107 const UserStoreLive = UserStoreService.Live.pipe(Layer.provide(DbLive));109 const UserStoreLive = UserStoreService.Live.pipe(Layer.provide(DbLive));
108 const Services = Layer.mergeAll(DbLive, UserStoreLive);110 const Services = Layer.mergeAll(DbLive, UserStoreLive, WorkOSAuth.Default);
109 111
110 const program = Effect.gen(function* () {112 const program = Effect.gen(function* () {
111 const users = yield* UserStoreService;113 const org = yield* resolveOrganization(token.organizationId);
112 const org = yield* users.use((store) => store.getOrganization(token.organizationId));
113 if (!org)114 if (!org)
114 return yield* new OrganizationNotFoundError({ organizationId: token.organizationId });115 return yield* new OrganizationNotFoundError({ organizationId: token.organizationId });
115 116
apps/cloud/src/mcp.ts+4−2
@@ -5,12 +5,14 @@ · 4 unmodified lines
5import { env } from "cloudflare:workers";5import { env } from "cloudflare:workers";
6import { createRemoteJWKSet, jwtVerify } from "jose";6import { createRemoteJWKSet, jwtVerify } from "jose";
7 7
8import { server } from "./env";
9
8// ---------------------------------------------------------------------------10// ---------------------------------------------------------------------------
9// Constants11// Constants
10// ---------------------------------------------------------------------------12// ---------------------------------------------------------------------------
11 13
12const AUTHKIT_DOMAIN = "https://signin.executor.sh";14const AUTHKIT_DOMAIN = server.MCP_AUTHKIT_DOMAIN;
13const RESOURCE_ORIGIN = "https://executor.sh";15const RESOURCE_ORIGIN = server.MCP_RESOURCE_ORIGIN;
14const JWKS_URL = new URL(`${AUTHKIT_DOMAIN}/oauth2/jwks`);16const JWKS_URL = new URL(`${AUTHKIT_DOMAIN}/oauth2/jwks`);
15 17
16const jwks = createRemoteJWKSet(JWKS_URL);18const jwks = createRemoteJWKSet(JWKS_URL);
apps/local/package.json+1−1
@@ -7,7 +7,7 @@ · 6 unmodified lines
7 ".": "./src/index.ts"7 ".": "./src/index.ts"
8 },8 },
9 "scripts": {9 "scripts": {
10 "dev": "portless run --name executor-local bunx --bun vite dev",10 "dev": "portless run --no-tls --name executor-local bunx --bun vite dev",
11 "build": "bunx --bun vite build",11 "build": "bunx --bun vite build",
12 "start": "bun run src/serve.ts",12 "start": "bun run src/serve.ts",
13 "typecheck": "tsgo --noEmit",13 "typecheck": "tsgo --noEmit",
apps/marketing/package.json+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 "version": "0.0.4",3 "version": "0.0.4",
4 "type": "module",4 "type": "module",
5 "scripts": {5 "scripts": {
6 "dev": "portless run --name executor-marketing astro dev",6 "dev": "portless run --no-tls --name executor-marketing astro dev",
7 "build": "astro build",7 "build": "astro build",
8 "preview": "astro preview",8 "preview": "astro preview",
9 "deploy": "astro build && npx wrangler deploy --config dist/server/wrangler.json",9 "deploy": "astro build && npx wrangler deploy --config dist/server/wrangler.json",
bun.lock+1−0
@@ -686,6 +686,7 @@ · 685 unmodified lines
686 },686 },
687 },687 },
688 "patchedDependencies": {688 "patchedDependencies": {
689 "@cloudflare/vite-plugin@1.31.2": "patches/@cloudflare%2Fvite-plugin@1.31.2.patch",
689 "postgres@3.4.9": "patches/postgres@3.4.9.patch",690 "postgres@3.4.9": "patches/postgres@3.4.9.patch",
690 },691 },
691 "catalog": {692 "catalog": {
opencode.json+10−0
@@ -0,0 +1,10 @@
1{
2 "$schema": "https://opencode.ai/config.json",
3 "mcp": {
4 "executor": {
5 "type": "remote",
6 "url": "http://executor-cloud.localhost:1355/mcp",
7 "enabled": true
8 }
9 }
10}
package.json+2−1
@@ -104,6 +104,7 @@ · 103 unmodified lines
104 "tsup": "^8.5.0"104 "tsup": "^8.5.0"
105 },105 },
106 "patchedDependencies": {106 "patchedDependencies": {
107 "postgres@3.4.9": "patches/postgres@3.4.9.patch"107 "postgres@3.4.9": "patches/postgres@3.4.9.patch",
108 "@cloudflare/vite-plugin@1.31.2": "patches/@cloudflare%2Fvite-plugin@1.31.2.patch"
108 }109 }
109}110}
packages/kernel/runtime-dynamic-worker/src/normalize.test.ts+16−0
@@ -12,6 +12,11 @@ describe("normalizeCode", () => { · 11 unmodified lines
12 expect(normalizeCode(code)).toBe(code);12 expect(normalizeCode(code)).toBe(code);
13 });13 });
14 14
15 it("strips export default from an async arrow", () => {
16 const code = "export default async () => 42";
17 expect(normalizeCode(code)).toBe("async () => 42");
18 });
19
15 it("wraps a bare expression in an async arrow", () => {20 it("wraps a bare expression in an async arrow", () => {
16 const result = normalizeCode("1 + 2");21 const result = normalizeCode("1 + 2");
17 expect(result).toContain("async () =>");22 expect(result).toContain("async () =>");
@@ -30,6 +35,17 @@ describe("normalizeCode", () => { · 12 unmodified lines
30 expect(result).toContain("return run();");35 expect(result).toContain("return run();");
31 });36 });
32 37
38 it("wraps an exported default named async function declaration", () => {
39 const result = normalizeCode("export default async function run() { return 'ok'; }");
40 expect(result).toContain("async function run()");
41 expect(result).toContain("return run();");
42 });
43
44 it("wraps an exported default anonymous async function declaration", () => {
45 const result = normalizeCode("export default async function () { return 'ok'; }");
46 expect(result).toBe("async () => (async function () { return 'ok'; })()");
47 });
48
33 it("strips markdown code fences", () => {49 it("strips markdown code fences", () => {
34 const code = "```js\nasync () => 42\n```";50 const code = "```js\nasync () => 42\n```";
35 expect(normalizeCode(code)).toBe("async () => 42");51 expect(normalizeCode(code)).toBe("async () => 42");
packages/kernel/runtime-dynamic-worker/src/normalize.ts+14−5
@@ -12,6 +12,9 @@ const stripCodeFences = (code: string): string => { · 11 unmodified lines
12 return match ? match[1]! : code;12 return match ? match[1]! : code;
13};13};
14 14
15const stripDefaultExport = (source: string): string =>
16 source.replace(/^export\s+default\s+/, "").trim();
17
15/**18/**
16 * Detect whether `source` is already an async arrow function expression.19 * Detect whether `source` is already an async arrow function expression.
17 *20 *
@@ -27,7 +30,7 @@ const looksLikeArrowFunction = (source: string): boolean => · 9 unmodified lines
27 * Detect a single named function declaration (sync or async).30 * Detect a single named function declaration (sync or async).
28 */31 */
29const looksLikeFunctionDeclaration = (source: string): boolean =>32const looksLikeFunctionDeclaration = (source: string): boolean =>
30 /^(async\s+)?function\s+[a-zA-Z_$]/.test(source);33 /^(async\s+)?function(?:\s+[a-zA-Z_$][a-zA-Z0-9_$]*)?\s*\(/.test(source);
31 34
32/**35/**
33 * Normalize user code into an async arrow function body.36 * Normalize user code into an async arrow function body.
@@ -39,15 +42,21 @@ export const normalizeCode = (code: string): string => { · 5 unmodified lines
39 if (!trimmed) return "async () => {}";42 if (!trimmed) return "async () => {}";
40 43
41 const source = trimmed.trim();44 const source = trimmed.trim();
45 const withoutDefaultExport = stripDefaultExport(source);
42 46
43 // Already an arrow function — pass through.47 // Already an arrow function — pass through.
44 if (looksLikeArrowFunction(source)) return source;48 if (looksLikeArrowFunction(withoutDefaultExport)) return withoutDefaultExport;
45 49
46 // Single named function declaration — wrap and call.50 // Single named function declaration — wrap and call.
47 if (looksLikeFunctionDeclaration(source)) {51 if (looksLikeFunctionDeclaration(withoutDefaultExport)) {
48 const nameMatch = source.match(/^(?:async\s+)?function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/);52 const nameMatch = withoutDefaultExport.match(
53 /^(?:async\s+)?function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/,
54 );
49 const name = nameMatch?.[1] ?? "fn";55 const name = nameMatch?.[1] ?? "fn";
50 return `async () => {\n${source}\nreturn ${name}();\n}`;56 if (!nameMatch) {
57 return `async () => (${withoutDefaultExport})()`;
58 }
59 return `async () => {\n${withoutDefaultExport}\nreturn ${name}();\n}`;
51 }60 }
52 61
53 // Treat everything else as statement(s) — wrap in an async arrow.62 // Treat everything else as statement(s) — wrap in an async arrow.
patches/@cloudflare%2Fvite-plugin@1.31.2.patch+14−0
@@ -0,0 +1,14 @@
1diff --git a/dist/index.mjs b/dist/index.mjs
2index 800006118105cd58707159d0a98dc5329a719dc3..9048678fce39d66d56b5bad63b7c7c94a5e3dc94 100644
3--- a/dist/index.mjs
4+++ b/dist/index.mjs
5@@ -11166,7 +11166,8 @@ function toMiniflareRequest(request$1) {
6 headers: [["accept-encoding", "identity"], ...request$1.headers],
7 body: request$1.body,
8 duplex: "half",
9- signal: request$1.signal
10+ signal: request$1.signal,
11+ credentials: "omit"
12 });
13 }
14 const isRolldown = "rolldownVersion" in vite;