- 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.
Unified · Split
| @@ -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", |
| @@ -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; |
| @@ -15,6 +15,8 @@ import type { DrizzleDb } from "@executor/storage-postgres"; · 14 unmodified lines | |||
| 15 | import * as sharedSchema from "@executor/storage-postgres/schema"; | 15 | import * as sharedSchema from "@executor/storage-postgres/schema"; |
| 16 | 16 | ||
| 17 | import { UserStoreService } from "./auth/context"; | 17 | import { UserStoreService } from "./auth/context"; |
| 18 | import { resolveOrganization } from "./auth/resolve-organization"; | ||
| 19 | import { WorkOSAuth } from "./auth/workos"; | ||
| 18 | import { server } from "./env"; | 20 | import { server } from "./env"; |
| 19 | import { createOrgExecutor } from "./services/executor"; | 21 | import { createOrgExecutor } from "./services/executor"; |
| 20 | import { DbService } from "./services/db"; | 22 | import { 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 | ||
| @@ -5,12 +5,14 @@ · 4 unmodified lines | |||
| 5 | import { env } from "cloudflare:workers"; | 5 | import { env } from "cloudflare:workers"; |
| 6 | import { createRemoteJWKSet, jwtVerify } from "jose"; | 6 | import { createRemoteJWKSet, jwtVerify } from "jose"; |
| 7 | 7 | ||
| 8 | import { server } from "./env"; | ||
| 9 | |||
| 8 | // --------------------------------------------------------------------------- | 10 | // --------------------------------------------------------------------------- |
| 9 | // Constants | 11 | // Constants |
| 10 | // --------------------------------------------------------------------------- | 12 | // --------------------------------------------------------------------------- |
| 11 | 13 | ||
| 12 | const AUTHKIT_DOMAIN = "https://signin.executor.sh"; | 14 | const AUTHKIT_DOMAIN = server.MCP_AUTHKIT_DOMAIN; |
| 13 | const RESOURCE_ORIGIN = "https://executor.sh"; | 15 | const RESOURCE_ORIGIN = server.MCP_RESOURCE_ORIGIN; |
| 14 | const JWKS_URL = new URL(`${AUTHKIT_DOMAIN}/oauth2/jwks`); | 16 | const JWKS_URL = new URL(`${AUTHKIT_DOMAIN}/oauth2/jwks`); |
| 15 | 17 | ||
| 16 | const jwks = createRemoteJWKSet(JWKS_URL); | 18 | const jwks = createRemoteJWKSet(JWKS_URL); |
| @@ -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", |
| @@ -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", |
| @@ -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": { |
| @@ -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 | } | ||
| @@ -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 | } |
| @@ -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"); |
| @@ -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 | ||
| 15 | const 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 | */ |
| 29 | const looksLikeFunctionDeclaration = (source: string): boolean => | 32 | const 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. |
| @@ -0,0 +1,14 @@ | |||
| 1 | diff --git a/dist/index.mjs b/dist/index.mjs | ||
| 2 | index 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; | ||