Align runtime naming with the current architecture by replacing PM-prefixed runtime services/env wiring with runtime-host terminology while keeping legacy PM env vars as fallbacks for compatibility.
Unified · Split
| @@ -104,7 +104,7 @@ Important boundary: · 103 unmodified lines | |||
| 104 | 104 | ||
| 105 | ### Modes | 105 | ### Modes |
| 106 | 106 | ||
| 107 | - local-lite: PM daemon + in-memory hot state + file durability | 107 | - local-lite: Runtime Host daemon + in-memory hot state + file durability |
| 108 | - remote: SQL-backed target (Postgres remote, SQLite local) | 108 | - remote: SQL-backed target (Postgres remote, SQLite local) |
| 109 | 109 | ||
| 110 | ### Runtime targets | 110 | ### Runtime targets |
| @@ -265,7 +265,7 @@ Secrets/credentials: · 154 unmodified lines | |||
| 265 | --- | 265 | --- |
| 266 | 266 | ||
| 267 | ## 12) Security posture | 267 | ## 12) Security posture |
| 268 | - PM binds to loopback by default. | 268 | - Runtime Host binds to loopback by default. |
| 269 | - Runtime callbacks require internal token validation. | 269 | - Runtime callbacks require internal token validation. |
| 270 | - Secrets do not pass through model args/transcripts. | 270 | - Secrets do not pass through model args/transcripts. |
| 271 | - Credential refs in state; secret values in secure stores. | 271 | - Credential refs in state; secret values in secure stores. |
| @@ -279,7 +279,7 @@ Secrets/credentials: · 7 unmodified lines | |||
| 279 | v2/ | 279 | v2/ |
| 280 | apps/ | 280 | apps/ |
| 281 | cli/ | 281 | cli/ |
| 282 | pm/ | 282 | runtime-host/ |
| 283 | web/ | 283 | web/ |
| 284 | packages/ | 284 | packages/ |
| 285 | schema/ | 285 | schema/ |
| @@ -340,7 +340,7 @@ Rules: · 54 unmodified lines | |||
| 340 | 340 | ||
| 341 | ### Phase 1: local-lite execute vertical slice | 341 | ### Phase 1: local-lite execute vertical slice |
| 342 | 342 | ||
| 343 | - PM execute path with persisted run lifecycle | 343 | - Runtime Host execute path with persisted run lifecycle |
| 344 | - runtime callback path wired through shared invocation service | 344 | - runtime callback path wired through shared invocation service |
| 345 | - openapi + in_memory providers | 345 | - openapi + in_memory providers |
| 346 | 346 | ||
| @@ -403,7 +403,7 @@ Implemented in `v2` so far: · 56 unmodified lines | |||
| 403 | - local in-process JS runner with `tools.*` proxy | 403 | - local in-process JS runner with `tools.*` proxy |
| 404 | - Deno subprocess runtime path with IPC tool-call proxying and tests | 404 | - Deno subprocess runtime path with IPC tool-call proxying and tests |
| 405 | - runtime adapter contract + registry scaffold | 405 | - runtime adapter contract + registry scaffold |
| 406 | - PM execute lifecycle scaffold via MCP execute path | 406 | - Runtime Host execute lifecycle scaffold via MCP execute path |
| 407 | 407 | ||
| 408 | Still missing: | 408 | Still missing: |
| 409 | 409 | ||
| @@ -417,7 +417,7 @@ Still missing: · 7 unmodified lines | |||
| 417 | 417 | ||
| 418 | ## 19) Immediate next steps | 418 | ## 19) Immediate next steps |
| 419 | 419 | ||
| 420 | 1. Land shared `ToolInvocationService` contract in v2 and wire PM execute callback path through it. | 420 | 1. Land shared `ToolInvocationService` contract in v2 and wire Runtime Host execute callback path through it. |
| 421 | 2. Add `CredentialResolver` interfaces and local/remote implementations; integrate at invocation-time only. | 421 | 2. Add `CredentialResolver` interfaces and local/remote implementations; integrate at invocation-time only. |
| 422 | 3. Implement control handlers for sources (`add/list/remove`) and route both host API and `tools.executor.*` through same code path. | 422 | 3. Implement control handlers for sources (`add/list/remove`) and route both host API and `tools.executor.*` through same code path. |
| 423 | 4. Implement cloudflare-worker-loader runtime dispatch adapter in v2 and wire callback endpoints. | 423 | 4. Implement cloudflare-worker-loader runtime dispatch adapter in v2 and wire callback endpoints. |
| @@ -26,13 +26,19 @@ Supported commands: · 25 unmodified lines | |||
| 26 | - `executor workspace use <workspace-id>` | 26 | - `executor workspace use <workspace-id>` |
| 27 | - `executor run execute --code ...` | 27 | - `executor run execute --code ...` |
| 28 | - `executor run execute --file ...` | 28 | - `executor run execute --file ...` |
| 29 | - `executor run bootstrap openapi --spec-url ... --source-base-url ...` | 29 | |
| 30 | - `executor run bootstrap github` | 30 | Control-plane management from CLI should happen through `run execute` and discovered |
| 31 | source tool paths (for example, add Executor's own OpenAPI source, then call its | ||
| 32 | tool paths to manage other sources). | ||
| 31 | 33 | ||
| 32 | Run locally: | 34 | Run locally: |
| 33 | 35 | ||
| 34 | - `bun run --cwd apps/cli start -- target show` | 36 | - `bun run --cwd apps/cli start -- target show` |
| 35 | - `bun run --cwd apps/cli start -- run execute --target local --code "return 1"` | 37 | - `bun run --cwd apps/cli start -- run execute --target local --code "return 1"` |
| 36 | - `bun run --cwd apps/cli start -- run bootstrap github --target local` | ||
| 37 | - `bun run --cwd apps/cli start -- --help` | 38 | - `bun run --cwd apps/cli start -- --help` |
| 38 | - `bun run --cwd apps/cli start -- server start --port 8788` | 39 | - `bun run --cwd apps/cli start -- server start --port 8788` |
| 40 | |||
| 41 | Seed Executor's own OpenAPI source (example): | ||
| 42 | |||
| 43 | - `bun run --cwd apps/cli start -- run execute --target local --workspace ws_local --code "const workspaceId='ws_local'; const res=await fetch('http://127.0.0.1:8788/v1/workspaces/'+workspaceId+'/sources',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({id:'src_executor_openapi',name:'executor:openapi',kind:'openapi',endpoint:'http://127.0.0.1:8788/v1/openapi.json',enabled:true,configJson:JSON.stringify({baseUrl:'http://127.0.0.1:8788'})})}); return await res.json();"` | ||
| 44 | - Then use `tools.discover(...)` in `run execute` to locate and call source tool paths. | ||
| @@ -36,20 +36,6 @@ type WorkspaceRecord = { · 35 unmodified lines | |||
| 36 | id: string; | 36 | id: string; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | type SourceRecord = { | ||
| 40 | id: string; | ||
| 41 | name: string; | ||
| 42 | endpoint: string; | ||
| 43 | configJson: string; | ||
| 44 | }; | ||
| 45 | |||
| 46 | type SourceToolSummaryRecord = { | ||
| 47 | toolId: string; | ||
| 48 | method: string; | ||
| 49 | path: string; | ||
| 50 | name: string; | ||
| 51 | }; | ||
| 52 | |||
| 53 | type DeviceAuthorizationResponse = { | 39 | type DeviceAuthorizationResponse = { |
| 54 | device_code: string; | 40 | device_code: string; |
| 55 | user_code: string; | 41 | user_code: string; |
| @@ -78,10 +64,6 @@ type CommonTargetOptions = { · 22 unmodified lines | |||
| 78 | 64 | ||
| 79 | const DEFAULT_LOCAL_BASE_URL = "http://127.0.0.1:8788"; | 65 | const DEFAULT_LOCAL_BASE_URL = "http://127.0.0.1:8788"; |
| 80 | const DEFAULT_WORKOS_AUTH_BASE_URL = "https://api.workos.com"; | 66 | const DEFAULT_WORKOS_AUTH_BASE_URL = "https://api.workos.com"; |
| 81 | const DEFAULT_GITHUB_OPENAPI_SPEC_URL = | ||
| 82 | "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json"; | ||
| 83 | const DEFAULT_GITHUB_API_BASE_URL = "https://api.github.com"; | ||
| 84 | const DEFAULT_GITHUB_OPENAPI_SOURCE_ID = "src_github_openapi"; | ||
| 85 | const CONFIG_PATH = join(homedir(), ".config", "executor", "cli.json"); | 67 | const CONFIG_PATH = join(homedir(), ".config", "executor", "cli.json"); |
| 86 | 68 | ||
| 87 | const toErrorMessage = (cause: unknown): string => | 69 | const toErrorMessage = (cause: unknown): string => |
| @@ -518,6 +500,8 @@ class ExecutorServerClient { · 430 unmodified lines | |||
| 518 | const childEnv = { | 500 | const childEnv = { |
| 519 | ...cleanEnv(), | 501 | ...cleanEnv(), |
| 520 | PORT: localPort, | 502 | PORT: localPort, |
| 503 | EXECUTOR_RUNTIME_KIND: | ||
| 504 | process.env.EXECUTOR_LOCAL_RUNTIME_KIND?.trim() || "local-inproc", | ||
| 521 | PM_RUNTIME_KIND: | 505 | PM_RUNTIME_KIND: |
| 522 | process.env.EXECUTOR_LOCAL_RUNTIME_KIND?.trim() || "local-inproc", | 506 | process.env.EXECUTOR_LOCAL_RUNTIME_KIND?.trim() || "local-inproc", |
| 523 | }; | 507 | }; |
| @@ -597,87 +581,6 @@ const ensureWorkspaceId = async ( · 73 unmodified lines | |||
| 597 | return workspaceId; | 581 | return workspaceId; |
| 598 | }; | 582 | }; |
| 599 | 583 | ||
| 600 | const deriveSourceName = (kind: string, endpoint: string): string => { | ||
| 601 | try { | ||
| 602 | const url = new URL(endpoint); | ||
| 603 | const host = url.hostname.replace(/^api\./, ""); | ||
| 604 | return `${kind}:${host}`; | ||
| 605 | } catch { | ||
| 606 | return `${kind}:source`; | ||
| 607 | } | ||
| 608 | }; | ||
| 609 | |||
| 610 | const bootstrapOpenApiSource = async (input: { | ||
| 611 | client: ExecutorServerClient; | ||
| 612 | config: ExecutorCliConfig; | ||
| 613 | workspaceOverride?: string; | ||
| 614 | specUrl: string; | ||
| 615 | baseUrl: string; | ||
| 616 | name?: string; | ||
| 617 | sourceId?: string; | ||
| 618 | }): Promise<{ | ||
| 619 | workspaceId: string; | ||
| 620 | source: SourceRecord; | ||
| 621 | tools: Array<SourceToolSummaryRecord>; | ||
| 622 | sampleToolPath: string | null; | ||
| 623 | }> => { | ||
| 624 | const workspaceId = await ensureWorkspaceId( | ||
| 625 | input.client, | ||
| 626 | input.config, | ||
| 627 | input.workspaceOverride, | ||
| 628 | ); | ||
| 629 | const normalizedSpecUrl = input.specUrl.trim(); | ||
| 630 | const normalizedBaseUrl = input.baseUrl.trim(); | ||
| 631 | |||
| 632 | if (normalizedSpecUrl.length === 0) { | ||
| 633 | throw new Error("OpenAPI bootstrap requires --spec-url."); | ||
| 634 | } | ||
| 635 | |||
| 636 | if (normalizedBaseUrl.length === 0) { | ||
| 637 | throw new Error("OpenAPI bootstrap requires --source-base-url."); | ||
| 638 | } | ||
| 639 | |||
| 640 | const source = await input.client.runControlPlane((api) => | ||
| 641 | api.sources.upsert({ | ||
| 642 | path: { workspaceId }, | ||
| 643 | payload: { | ||
| 644 | ...(input.sourceId && input.sourceId.trim().length > 0 | ||
| 645 | ? { id: input.sourceId.trim() } | ||
| 646 | : {}), | ||
| 647 | name: | ||
| 648 | input.name && input.name.trim().length > 0 | ||
| 649 | ? input.name.trim() | ||
| 650 | : deriveSourceName("openapi", normalizedBaseUrl), | ||
| 651 | kind: "openapi", | ||
| 652 | endpoint: normalizedSpecUrl, | ||
| 653 | status: "connected", | ||
| 654 | enabled: true, | ||
| 655 | configJson: JSON.stringify({ baseUrl: normalizedBaseUrl }), | ||
| 656 | }, | ||
| 657 | }), | ||
| 658 | ) as SourceRecord; | ||
| 659 | |||
| 660 | const tools = await input.client.runControlPlane((api) => | ||
| 661 | api.tools.listSourceTools({ | ||
| 662 | path: { | ||
| 663 | workspaceId, | ||
| 664 | sourceId: source.id, | ||
| 665 | }, | ||
| 666 | }), | ||
| 667 | ) as Array<SourceToolSummaryRecord>; | ||
| 668 | |||
| 669 | const sampleToolPath = tools[0]?.toolId | ||
| 670 | ? `source.${source.id}.${tools[0].toolId}` | ||
| 671 | : null; | ||
| 672 | |||
| 673 | return { | ||
| 674 | workspaceId, | ||
| 675 | source, | ||
| 676 | tools, | ||
| 677 | sampleToolPath, | ||
| 678 | }; | ||
| 679 | }; | ||
| 680 | |||
| 681 | const postForm = async ( | 584 | const postForm = async ( |
| 682 | url: string, | 585 | url: string, |
| 683 | params: Record<string, string>, | 586 | params: Record<string, string>, |
| @@ -859,8 +762,9 @@ const commonTargetOptions = () => ({ · 175 unmodified lines | |||
| 859 | }); | 762 | }); |
| 860 | 763 | ||
| 861 | const startEmbeddedLocalServer = async (port: number): Promise<void> => { | 764 | const startEmbeddedLocalServer = async (port: number): Promise<void> => { |
| 862 | process.env.PM_RUNTIME_KIND = | 765 | process.env.EXECUTOR_RUNTIME_KIND = |
| 863 | process.env.EXECUTOR_LOCAL_RUNTIME_KIND?.trim() || "local-inproc"; | 766 | process.env.EXECUTOR_LOCAL_RUNTIME_KIND?.trim() || "local-inproc"; |
| 767 | process.env.PM_RUNTIME_KIND = process.env.EXECUTOR_RUNTIME_KIND; | ||
| 864 | 768 | ||
| 865 | const { | 769 | const { |
| 866 | createLocalPrincipal, | 770 | createLocalPrincipal, |
| @@ -1254,134 +1158,8 @@ const runExecuteCommand = Command.make( · 387 unmodified lines | |||
| 1254 | Command.withDescription("Execute TypeScript code through Executor runtime"), | 1158 | Command.withDescription("Execute TypeScript code through Executor runtime"), |
| 1255 | ); | 1159 | ); |
| 1256 | 1160 | ||
| 1257 | const runBootstrapOpenApiCommand = Command.make( | ||
| 1258 | "openapi", | ||
| 1259 | { | ||
| 1260 | ...commonTargetOptions(), | ||
| 1261 | specUrl: Options.text("spec-url"), | ||
| 1262 | sourceBaseUrl: Options.text("source-base-url"), | ||
| 1263 | name: Options.text("name").pipe(Options.optional), | ||
| 1264 | sourceId: Options.text("source-id").pipe(Options.optional), | ||
| 1265 | }, | ||
| 1266 | (input) => | ||
| 1267 | Effect.tryPromise({ | ||
| 1268 | try: async () => { | ||
| 1269 | const common: CommonTargetOptions = { | ||
| 1270 | target: input.target, | ||
| 1271 | workspace: input.workspace, | ||
| 1272 | baseUrl: input.baseUrl, | ||
| 1273 | json: input.json, | ||
| 1274 | }; | ||
| 1275 | |||
| 1276 | await withClient(common, async ({ client, config, workspaceOverride, asJson }) => { | ||
| 1277 | const setup = await bootstrapOpenApiSource({ | ||
| 1278 | client, | ||
| 1279 | config, | ||
| 1280 | workspaceOverride, | ||
| 1281 | specUrl: input.specUrl, | ||
| 1282 | baseUrl: input.sourceBaseUrl, | ||
| 1283 | name: optionToUndefined(input.name), | ||
| 1284 | sourceId: optionToUndefined(input.sourceId), | ||
| 1285 | }); | ||
| 1286 | |||
| 1287 | printOutput( | ||
| 1288 | { | ||
| 1289 | ok: true, | ||
| 1290 | workspaceId: setup.workspaceId, | ||
| 1291 | source: { | ||
| 1292 | id: setup.source.id, | ||
| 1293 | name: setup.source.name, | ||
| 1294 | endpoint: setup.source.endpoint, | ||
| 1295 | configJson: setup.source.configJson, | ||
| 1296 | }, | ||
| 1297 | toolCount: setup.tools.length, | ||
| 1298 | sampleToolPath: setup.sampleToolPath, | ||
| 1299 | }, | ||
| 1300 | asJson, | ||
| 1301 | ); | ||
| 1302 | }); | ||
| 1303 | }, | ||
| 1304 | catch: toErrorMessage, | ||
| 1305 | }), | ||
| 1306 | ).pipe( | ||
| 1307 | Command.withDescription("Bootstrap an OpenAPI source with runtime base URL"), | ||
| 1308 | ); | ||
| 1309 | |||
| 1310 | const runBootstrapGithubCommand = Command.make( | ||
| 1311 | "github", | ||
| 1312 | { | ||
| 1313 | ...commonTargetOptions(), | ||
| 1314 | name: Options.text("name").pipe(Options.optional), | ||
| 1315 | sourceId: Options.text("source-id").pipe(Options.optional), | ||
| 1316 | specUrl: Options.text("spec-url").pipe(Options.withDefault(DEFAULT_GITHUB_OPENAPI_SPEC_URL)), | ||
| 1317 | sourceBaseUrl: Options.text("source-base-url").pipe(Options.withDefault(DEFAULT_GITHUB_API_BASE_URL)), | ||
| 1318 | }, | ||
| 1319 | (input) => | ||
| 1320 | Effect.tryPromise({ | ||
| 1321 | try: async () => { | ||
| 1322 | const common: CommonTargetOptions = { | ||
| 1323 | target: input.target, | ||
| 1324 | workspace: input.workspace, | ||
| 1325 | baseUrl: input.baseUrl, | ||
| 1326 | json: input.json, | ||
| 1327 | }; | ||
| 1328 | |||
| 1329 | await withClient(common, async ({ client, config, workspaceOverride, asJson }) => { | ||
| 1330 | const setup = await bootstrapOpenApiSource({ | ||
| 1331 | client, | ||
| 1332 | config, | ||
| 1333 | workspaceOverride, | ||
| 1334 | specUrl: input.specUrl, | ||
| 1335 | baseUrl: input.sourceBaseUrl, | ||
| 1336 | name: optionToUndefined(input.name) ?? "github:openapi", | ||
| 1337 | sourceId: optionToUndefined(input.sourceId) ?? DEFAULT_GITHUB_OPENAPI_SOURCE_ID, | ||
| 1338 | }); | ||
| 1339 | |||
| 1340 | const suggestedTool = | ||
| 1341 | setup.tools.find((tool) => | ||
| 1342 | tool.toolId.includes("issues-and-pull-requests"), | ||
| 1343 | ) | ||
| 1344 | ?? setup.tools[0] | ||
| 1345 | ?? null; | ||
| 1346 | |||
| 1347 | printOutput( | ||
| 1348 | { | ||
| 1349 | ok: true, | ||
| 1350 | workspaceId: setup.workspaceId, | ||
| 1351 | source: { | ||
| 1352 | id: setup.source.id, | ||
| 1353 | name: setup.source.name, | ||
| 1354 | endpoint: setup.source.endpoint, | ||
| 1355 | configJson: setup.source.configJson, | ||
| 1356 | }, | ||
| 1357 | toolCount: setup.tools.length, | ||
| 1358 | suggestedToolPath: suggestedTool | ||
| 1359 | ? `source.${setup.source.id}.${suggestedTool.toolId}` | ||
| 1360 | : null, | ||
| 1361 | executeHint: suggestedTool | ||
| 1362 | ? `executor run execute --code \"return await tools['source.${setup.source.id}.${suggestedTool.toolId}']({ q: 'repo:owner/repo is:issue state:open', per_page: 5 });\"` | ||
| 1363 | : null, | ||
| 1364 | }, | ||
| 1365 | asJson, | ||
| 1366 | ); | ||
| 1367 | }); | ||
| 1368 | }, | ||
| 1369 | catch: toErrorMessage, | ||
| 1370 | }), | ||
| 1371 | ).pipe( | ||
| 1372 | Command.withDescription("Bootstrap GitHub OpenAPI source for public issue queries"), | ||
| 1373 | ); | ||
| 1374 | |||
| 1375 | const runBootstrapCommand = Command.make("bootstrap").pipe( | ||
| 1376 | Command.withSubcommands([ | ||
| 1377 | runBootstrapOpenApiCommand, | ||
| 1378 | runBootstrapGithubCommand, | ||
| 1379 | ] as any), | ||
| 1380 | Command.withDescription("Bootstrap source setup shortcuts for execution workflows"), | ||
| 1381 | ); | ||
| 1382 | |||
| 1383 | const runCommand = Command.make("run").pipe( | 1161 | const runCommand = Command.make("run").pipe( |
| 1384 | Command.withSubcommands([runExecuteCommand, runBootstrapCommand] as any), | 1162 | Command.withSubcommands([runExecuteCommand] as any), |
| 1385 | Command.withDescription("Code execution commands"), | 1163 | Command.withDescription("Code execution commands"), |
| 1386 | ); | 1164 | ); |
| 1387 | 1165 | ||
| @@ -30,19 +30,19 @@ import { · 29 unmodified lines | |||
| 30 | type ToolRegistryDiscoverOutput, | 30 | type ToolRegistryDiscoverOutput, |
| 31 | } from "@executor-v2/engine"; | 31 | } from "@executor-v2/engine"; |
| 32 | import { | 32 | import { |
| 33 | PmActorLive, | 33 | RuntimeHostActorLive, |
| 34 | createKeychainSecretMaterialStore, | 34 | createKeychainSecretMaterialStore, |
| 35 | createPmApprovalsService, | 35 | createRuntimeHostApprovalsService, |
| 36 | createPmCredentialsService, | 36 | createRuntimeHostCredentialsService, |
| 37 | createPmExecuteRuntimeRun, | 37 | createRuntimeHostExecuteRuntimeRun, |
| 38 | createPmMcpHandler, | 38 | createRuntimeHostMcpHandler, |
| 39 | createPmOrganizationsService, | 39 | createRuntimeHostOrganizationsService, |
| 40 | createPmPersistentToolApprovalPolicy, | 40 | createRuntimeHostPersistentToolApprovalPolicy, |
| 41 | createPmPoliciesService, | 41 | createRuntimeHostPoliciesService, |
| 42 | createPmResolveToolCredentials, | 42 | createRuntimeHostResolveToolCredentials, |
| 43 | createPmStorageService, | 43 | createRuntimeHostStorageService, |
| 44 | createPmToolsService, | 44 | createRuntimeHostToolsService, |
| 45 | createPmWorkspacesService, | 45 | createRuntimeHostWorkspacesService, |
| 46 | createSqlSecretMaterialStore, | 46 | createSqlSecretMaterialStore, |
| 47 | parseSecretMaterialBackendKind, | 47 | parseSecretMaterialBackendKind, |
| 48 | } from "@executor-v2/control-plane-runtime"; | 48 | } from "@executor-v2/control-plane-runtime"; |
| @@ -585,25 +585,25 @@ const createControlPlaneRuntime = async (): Promise<ControlPlaneRuntime> => { · 536 unmodified lines | |||
| 585 | ]; | 585 | ]; |
| 586 | const runtimeAdapters = makeRuntimeAdapterRegistry(runtimeAdapterList); | 586 | const runtimeAdapters = makeRuntimeAdapterRegistry(runtimeAdapterList); |
| 587 | const defaultRuntimeKind = | 587 | const defaultRuntimeKind = |
| 588 | webServerEnvironment.pmRuntimeKind | 588 | webServerEnvironment.executorRuntimeKind |
| 589 | ?? runtimeAdapterList[0]?.kind | 589 | ?? runtimeAdapterList[0]?.kind |
| 590 | ?? "local-inproc"; | 590 | ?? "local-inproc"; |
| 591 | const requireToolApprovals = webServerEnvironment.pmRequireToolApprovals; | 591 | const requireToolApprovals = webServerEnvironment.executorRuntimeRequireToolApprovals; |
| 592 | const defaultToolExposureMode = | 592 | const defaultToolExposureMode = |
| 593 | parseExecuteToolExposureMode(webServerEnvironment.pmToolExposureMode) | 593 | parseExecuteToolExposureMode(webServerEnvironment.executorRuntimeToolExposureMode) |
| 594 | ?? defaultExecuteToolExposureMode; | 594 | ?? defaultExecuteToolExposureMode; |
| 595 | const toolProviderRegistry = makeToolProviderRegistry([ | 595 | const toolProviderRegistry = makeToolProviderRegistry([ |
| 596 | makeOpenApiToolProvider(), | 596 | makeOpenApiToolProvider(), |
| 597 | makeMcpToolProvider(), | 597 | makeMcpToolProvider(), |
| 598 | makeGraphqlToolProvider(), | 598 | makeGraphqlToolProvider(), |
| 599 | ]); | 599 | ]); |
| 600 | const persistentApprovalPolicy = createPmPersistentToolApprovalPolicy( | 600 | const persistentApprovalPolicy = createRuntimeHostPersistentToolApprovalPolicy( |
| 601 | persistence.rows, | 601 | persistence.rows, |
| 602 | { | 602 | { |
| 603 | requireApprovals: requireToolApprovals, | 603 | requireApprovals: requireToolApprovals, |
| 604 | }, | 604 | }, |
| 605 | ); | 605 | ); |
| 606 | const resolveCredentials = createPmResolveToolCredentials( | 606 | const resolveCredentials = createRuntimeHostResolveToolCredentials( |
| 607 | persistence.rows, | 607 | persistence.rows, |
| 608 | secretMaterialStore, | 608 | secretMaterialStore, |
| 609 | ); | 609 | ); |
| @@ -722,20 +722,20 @@ const createControlPlaneRuntime = async (): Promise<ControlPlaneRuntime> => { · 112 unmodified lines | |||
| 722 | 722 | ||
| 723 | const controlPlaneService = makeControlPlaneService({ | 723 | const controlPlaneService = makeControlPlaneService({ |
| 724 | sources: sourcesService, | 724 | sources: sourcesService, |
| 725 | credentials: createPmCredentialsService(persistence.rows, secretMaterialStore), | 725 | credentials: createRuntimeHostCredentialsService(persistence.rows, secretMaterialStore), |
| 726 | policies: createPmPoliciesService(persistence.rows), | 726 | policies: createRuntimeHostPoliciesService(persistence.rows), |
| 727 | organizations: createPmOrganizationsService(persistence.rows), | 727 | organizations: createRuntimeHostOrganizationsService(persistence.rows), |
| 728 | workspaces: createPmWorkspacesService(persistence.rows), | 728 | workspaces: createRuntimeHostWorkspacesService(persistence.rows), |
| 729 | tools: createPmToolsService(sourceStore, toolArtifactStore), | 729 | tools: createRuntimeHostToolsService(sourceStore, toolArtifactStore), |
| 730 | storage: createPmStorageService(persistence.rows, { | 730 | storage: createRuntimeHostStorageService(persistence.rows, { |
| 731 | stateRootDir, | 731 | stateRootDir, |
| 732 | }), | 732 | }), |
| 733 | approvals: createPmApprovalsService(persistence.rows), | 733 | approvals: createRuntimeHostApprovalsService(persistence.rows), |
| 734 | }); | 734 | }); |
| 735 | 735 | ||
| 736 | const controlPlaneWebHandler = makeControlPlaneWebHandler( | 736 | const controlPlaneWebHandler = makeControlPlaneWebHandler( |
| 737 | Layer.succeed(ControlPlaneService, controlPlaneService), | 737 | Layer.succeed(ControlPlaneService, controlPlaneService), |
| 738 | PmActorLive(persistence.rows), | 738 | RuntimeHostActorLive(persistence.rows), |
| 739 | ); | 739 | ); |
| 740 | 740 | ||
| 741 | const rememberRunWorkspace = (runId: string, workspaceId: string): void => { | 741 | const rememberRunWorkspace = (runId: string, workspaceId: string): void => { |
| @@ -772,7 +772,7 @@ const createControlPlaneRuntime = async (): Promise<ControlPlaneRuntime> => { · 30 unmodified lines | |||
| 772 | toolProviderRegistry, | 772 | toolProviderRegistry, |
| 773 | approvalPolicy: persistentApprovalPolicy, | 773 | approvalPolicy: persistentApprovalPolicy, |
| 774 | }); | 774 | }); |
| 775 | const executeRuntimeRun = createPmExecuteRuntimeRun({ | 775 | const executeRuntimeRun = createRuntimeHostExecuteRuntimeRun({ |
| 776 | defaultRuntimeKind, | 776 | defaultRuntimeKind, |
| 777 | runtimeAdapters, | 777 | runtimeAdapters, |
| 778 | toolRegistry, | 778 | toolRegistry, |
| @@ -784,7 +784,7 @@ const createControlPlaneRuntime = async (): Promise<ControlPlaneRuntime> => { · 5 unmodified lines | |||
| 784 | return runId; | 784 | return runId; |
| 785 | }, | 785 | }, |
| 786 | }); | 786 | }); |
| 787 | const next = createPmMcpHandler(runExecutor.executeRun, { | 787 | const next = createRuntimeHostMcpHandler(runExecutor.executeRun, { |
| 788 | toolRegistry, | 788 | toolRegistry, |
| 789 | defaultToolExposureMode, | 789 | defaultToolExposureMode, |
| 790 | }); | 790 | }); |
| @@ -8,9 +8,18 @@ const webServerEnvConfig = configSchema("WebServerEnvironment", { · 7 unmodified lines | |||
| 8 | env: "CONTROL_PLANE_POSTGRES_CONNECTION_TARGET", | 8 | env: "CONTROL_PLANE_POSTGRES_CONNECTION_TARGET", |
| 9 | optional: true, | 9 | optional: true, |
| 10 | }), | 10 | }), |
| 11 | pmRuntimeKind: server({ env: "PM_RUNTIME_KIND", optional: true }), | 11 | executorRuntimeKind: server({ env: "EXECUTOR_RUNTIME_KIND", optional: true }), |
| 12 | pmRequireToolApprovals: server({ env: "PM_REQUIRE_TOOL_APPROVALS", optional: true }), | 12 | legacyPmRuntimeKind: server({ env: "PM_RUNTIME_KIND", optional: true }), |
| 13 | pmToolExposureMode: server({ env: "PM_TOOL_EXPOSURE_MODE", optional: true }), | 13 | executorRuntimeRequireToolApprovals: server({ |
| 14 | env: "EXECUTOR_RUNTIME_REQUIRE_TOOL_APPROVALS", | ||
| 15 | optional: true, | ||
| 16 | }), | ||
| 17 | legacyPmRequireToolApprovals: server({ env: "PM_REQUIRE_TOOL_APPROVALS", optional: true }), | ||
| 18 | executorRuntimeToolExposureMode: server({ | ||
| 19 | env: "EXECUTOR_RUNTIME_TOOL_EXPOSURE_MODE", | ||
| 20 | optional: true, | ||
| 21 | }), | ||
| 22 | legacyPmToolExposureMode: server({ env: "PM_TOOL_EXPOSURE_MODE", optional: true }), | ||
| 14 | cloudflareSandboxCallbackSecret: server({ | 23 | cloudflareSandboxCallbackSecret: server({ |
| 15 | env: "CLOUDFLARE_SANDBOX_CALLBACK_SECRET", | 24 | env: "CLOUDFLARE_SANDBOX_CALLBACK_SECRET", |
| 16 | optional: true, | 25 | optional: true, |
| @@ -36,14 +45,18 @@ const webServerEnvConfig = configSchema("WebServerEnvironment", { · 19 unmodified lines | |||
| 36 | }); | 45 | }); |
| 37 | 46 | ||
| 38 | const env = webServerEnvConfig.server; | 47 | const env = webServerEnvConfig.server; |
| 48 | const executorRuntimeRequireToolApprovalsRaw = | ||
| 49 | trim(env.executorRuntimeRequireToolApprovals) | ||
| 50 | ?? trim(env.legacyPmRequireToolApprovals); | ||
| 39 | 51 | ||
| 40 | export const webServerEnvironment = { | 52 | export const webServerEnvironment = { |
| 41 | nodeEnv: trim(env.nodeEnv) ?? "development", | 53 | nodeEnv: trim(env.nodeEnv) ?? "development", |
| 42 | databaseUrl: trim(env.databaseUrl), | 54 | databaseUrl: trim(env.databaseUrl), |
| 43 | controlPlanePostgresConnectionTarget: trim(env.controlPlanePostgresConnectionTarget)?.toLowerCase(), | 55 | controlPlanePostgresConnectionTarget: trim(env.controlPlanePostgresConnectionTarget)?.toLowerCase(), |
| 44 | pmRuntimeKind: trim(env.pmRuntimeKind), | 56 | executorRuntimeKind: trim(env.executorRuntimeKind) ?? trim(env.legacyPmRuntimeKind), |
| 45 | pmRequireToolApprovals: isTruthy(env.pmRequireToolApprovals), | 57 | executorRuntimeRequireToolApprovals: isTruthy(executorRuntimeRequireToolApprovalsRaw), |
| 46 | pmToolExposureMode: trim(env.pmToolExposureMode), | 58 | executorRuntimeToolExposureMode: |
| 59 | trim(env.executorRuntimeToolExposureMode) ?? trim(env.legacyPmToolExposureMode), | ||
| 47 | cloudflareSandboxCallbackSecret: trim(env.cloudflareSandboxCallbackSecret), | 60 | cloudflareSandboxCallbackSecret: trim(env.cloudflareSandboxCallbackSecret), |
| 48 | executorPublicOrigin: trim(env.executorPublicOrigin), | 61 | executorPublicOrigin: trim(env.executorPublicOrigin), |
| 49 | vercelProjectProductionUrl: trim(env.vercelProjectProductionUrl), | 62 | vercelProjectProductionUrl: trim(env.vercelProjectProductionUrl), |
| @@ -84,14 +84,17 @@ const resolveActorFromSnapshot = ( · 83 unmodified lines | |||
| 84 | }); | 84 | }); |
| 85 | }); | 85 | }); |
| 86 | 86 | ||
| 87 | export const PmActorLive = (rows: ActorRows) => | 87 | export const RuntimeHostActorLive = (rows: ActorRows) => |
| 88 | { | 88 | { |
| 89 | const localAdminFallbackValue = | ||
| 90 | process.env.EXECUTOR_RUNTIME_ALLOW_LOCAL_ADMIN?.trim().toLowerCase() | ||
| 91 | ?? process.env.PM_ALLOW_LOCAL_ADMIN?.trim().toLowerCase() | ||
| 92 | ?? ""; | ||
| 93 | |||
| 89 | const localAdminFallbackEnabled = | 94 | const localAdminFallbackEnabled = |
| 90 | (process.env.PM_ALLOW_LOCAL_ADMIN?.trim().toLowerCase() ?? "") === "" | 95 | localAdminFallbackValue === "" |
| 91 | ? process.env.NODE_ENV !== "production" | 96 | ? process.env.NODE_ENV !== "production" |
| 92 | : ["1", "true", "yes"].includes( | 97 | : ["1", "true", "yes"].includes(localAdminFallbackValue); |
| 93 | process.env.PM_ALLOW_LOCAL_ADMIN?.trim().toLowerCase() ?? "", | ||
| 94 | ); | ||
| 95 | 98 | ||
| 96 | return ControlPlaneActorResolverLive({ | 99 | return ControlPlaneActorResolverLive({ |
| 97 | resolveActor: (input) => resolveActorFromSnapshot(rows, input.headers, localAdminFallbackEnabled), | 100 | resolveActor: (input) => resolveActorFromSnapshot(rows, input.headers, localAdminFallbackEnabled), |
| @@ -47,14 +47,14 @@ const toPersistentApprovalRecord = (approval: Approval): PersistentToolApprovalR · 46 unmodified lines | |||
| 47 | reason: approval.reason, | 47 | reason: approval.reason, |
| 48 | }); | 48 | }); |
| 49 | 49 | ||
| 50 | export type PmPersistentToolApprovalPolicyOptions = { | 50 | export type RuntimeHostPersistentToolApprovalPolicyOptions = { |
| 51 | requireApprovals?: boolean; | 51 | requireApprovals?: boolean; |
| 52 | retryAfterMs?: number; | 52 | retryAfterMs?: number; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | export const createPmPersistentToolApprovalPolicy = ( | 55 | export const createRuntimeHostPersistentToolApprovalPolicy = ( |
| 56 | rows: ApprovalRows, | 56 | rows: ApprovalRows, |
| 57 | options: PmPersistentToolApprovalPolicyOptions = {}, | 57 | options: RuntimeHostPersistentToolApprovalPolicyOptions = {}, |
| 58 | ): ToolApprovalPolicy => { | 58 | ): ToolApprovalPolicy => { |
| 59 | const store: PersistentToolApprovalStore = { | 59 | const store: PersistentToolApprovalStore = { |
| 60 | findByRunAndCall: (input) => | 60 | findByRunAndCall: (input) => |
| @@ -106,7 +106,7 @@ export const createPmPersistentToolApprovalPolicy = ( · 45 unmodified lines | |||
| 106 | }); | 106 | }); |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | export const createPmApprovalsService = ( | 109 | export const createRuntimeHostApprovalsService = ( |
| 110 | rows: ApprovalRows, | 110 | rows: ApprovalRows, |
| 111 | ): ControlPlaneApprovalsServiceShape => | 111 | ): ControlPlaneApprovalsServiceShape => |
| 112 | makeControlPlaneApprovalsService({ | 112 | makeControlPlaneApprovalsService({ |
| @@ -163,7 +163,7 @@ const buildSecretHeaders = ( · 162 unmodified lines | |||
| 163 | return {}; | 163 | return {}; |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | export const createPmResolveToolCredentials = ( | 166 | export const createRuntimeHostResolveToolCredentials = ( |
| 167 | rows: CredentialResolverRows, | 167 | rows: CredentialResolverRows, |
| 168 | secretMaterialStore: SecretMaterialStore, | 168 | secretMaterialStore: SecretMaterialStore, |
| 169 | ): ResolveToolCredentials => | 169 | ): ResolveToolCredentials => |
| @@ -73,7 +73,7 @@ const uniqueHandles = (handles: ReadonlyArray<string | null | undefined>): Array · 72 unmodified lines | |||
| 73 | return next; | 73 | return next; |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | export const createPmCredentialsService = ( | 76 | export const createRuntimeHostCredentialsService = ( |
| 77 | rows: CredentialRows, | 77 | rows: CredentialRows, |
| 78 | secretMaterialStore: SecretMaterialStore, | 78 | secretMaterialStore: SecretMaterialStore, |
| 79 | ): ControlPlaneCredentialsServiceShape => | 79 | ): ControlPlaneCredentialsServiceShape => |
| @@ -1,14 +1,14 @@ | |||
| 1 | export { PmActorLive } from "./actor"; | 1 | export { RuntimeHostActorLive } from "./actor"; |
| 2 | export { | 2 | export { |
| 3 | createPmApprovalsService, | 3 | createRuntimeHostApprovalsService, |
| 4 | createPmPersistentToolApprovalPolicy, | 4 | createRuntimeHostPersistentToolApprovalPolicy, |
| 5 | } from "./approvals-service"; | 5 | } from "./approvals-service"; |
| 6 | export { createPmResolveToolCredentials } from "./credential-resolver"; | 6 | export { createRuntimeHostResolveToolCredentials } from "./credential-resolver"; |
| 7 | export { createPmCredentialsService } from "./credentials-service"; | 7 | export { createRuntimeHostCredentialsService } from "./credentials-service"; |
| 8 | export { createPmMcpHandler } from "./mcp-handler"; | 8 | export { createRuntimeHostMcpHandler } from "./mcp-handler"; |
| 9 | export { createPmOrganizationsService } from "./organizations-service"; | 9 | export { createRuntimeHostOrganizationsService } from "./organizations-service"; |
| 10 | export { createPmPoliciesService } from "./policies-service"; | 10 | export { createRuntimeHostPoliciesService } from "./policies-service"; |
| 11 | export { createPmExecuteRuntimeRun } from "./runtime-execution-port"; | 11 | export { createRuntimeHostExecuteRuntimeRun } from "./runtime-execution-port"; |
| 12 | export { | 12 | export { |
| 13 | createKeychainSecretMaterialStore, | 13 | createKeychainSecretMaterialStore, |
| 14 | createSqlSecretMaterialStore, | 14 | createSqlSecretMaterialStore, |
| @@ -19,6 +19,6 @@ export { · 4 unmodified lines | |||
| 19 | type SecretMaterialScope, | 19 | type SecretMaterialScope, |
| 20 | type SecretMaterialStore, | 20 | type SecretMaterialStore, |
| 21 | } from "./secret-material-store"; | 21 | } from "./secret-material-store"; |
| 22 | export { createPmStorageService } from "./storage-service"; | 22 | export { createRuntimeHostStorageService } from "./storage-service"; |
| 23 | export { createPmToolsService } from "./tools-service"; | 23 | export { createRuntimeHostToolsService } from "./tools-service"; |
| 24 | export { createPmWorkspacesService } from "./workspaces-service"; | 24 | export { createRuntimeHostWorkspacesService } from "./workspaces-service"; |
| @@ -14,7 +14,7 @@ import { · 13 unmodified lines | |||
| 14 | import { handleMcpHttpRequest } from "@executor-v2/mcp-gateway"; | 14 | import { handleMcpHttpRequest } from "@executor-v2/mcp-gateway"; |
| 15 | import * as Effect from "effect/Effect"; | 15 | import * as Effect from "effect/Effect"; |
| 16 | 16 | ||
| 17 | export type PmMcpHandlerOptions = { | 17 | export type RuntimeHostMcpHandlerOptions = { |
| 18 | toolRegistry: ToolRegistry; | 18 | toolRegistry: ToolRegistry; |
| 19 | defaultToolExposureMode?: ExecuteToolExposureMode; | 19 | defaultToolExposureMode?: ExecuteToolExposureMode; |
| 20 | }; | 20 | }; |
| @@ -48,9 +48,9 @@ const resolveExecuteToolDescription = async ( · 27 unmodified lines | |||
| 48 | } | 48 | } |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | export const createPmMcpHandler = ( | 51 | export const createRuntimeHostMcpHandler = ( |
| 52 | executeRun: (input: ExecuteRunInput) => Effect.Effect<ExecuteRunResult>, | 52 | executeRun: (input: ExecuteRunInput) => Effect.Effect<ExecuteRunResult>, |
| 53 | options: PmMcpHandlerOptions, | 53 | options: RuntimeHostMcpHandlerOptions, |
| 54 | ): ((request: Request) => Promise<Response>) => { | 54 | ): ((request: Request) => Promise<Response>) => { |
| 55 | const runClient = createExecutorRunClient((input) => | 55 | const runClient = createExecutorRunClient((input) => |
| 56 | Effect.runPromise(executeRun(input)), | 56 | Effect.runPromise(executeRun(input)), |
| @@ -67,7 +67,7 @@ export const createPmMcpHandler = ( · 10 unmodified lines | |||
| 67 | ); | 67 | ); |
| 68 | 68 | ||
| 69 | return handleMcpHttpRequest(request, { | 69 | return handleMcpHttpRequest(request, { |
| 70 | serverName: "executor-v2-pm", | 70 | serverName: "executor-v2-runtime-host", |
| 71 | serverVersion: "0.0.0", | 71 | serverVersion: "0.0.0", |
| 72 | runClient, | 72 | runClient, |
| 73 | executeToolDescription, | 73 | executeToolDescription, |
| @@ -33,7 +33,7 @@ const sortOrganizations = ( · 32 unmodified lines | |||
| 33 | return leftName.localeCompare(rightName); | 33 | return leftName.localeCompare(rightName); |
| 34 | }); | 34 | }); |
| 35 | 35 | ||
| 36 | export const createPmOrganizationsService = ( | 36 | export const createRuntimeHostOrganizationsService = ( |
| 37 | rows: OrganizationRows, | 37 | rows: OrganizationRows, |
| 38 | ): ControlPlaneOrganizationsServiceShape => | 38 | ): ControlPlaneOrganizationsServiceShape => |
| 39 | makeControlPlaneOrganizationsService({ | 39 | makeControlPlaneOrganizationsService({ |
| @@ -24,7 +24,7 @@ const sortPolicies = (policies: ReadonlyArray<Policy>): Array<Policy> => · 23 unmodified lines | |||
| 24 | return leftPattern.localeCompare(rightPattern); | 24 | return leftPattern.localeCompare(rightPattern); |
| 25 | }); | 25 | }); |
| 26 | 26 | ||
| 27 | export const createPmPoliciesService = ( | 27 | export const createRuntimeHostPoliciesService = ( |
| 28 | rows: PolicyRows, | 28 | rows: PolicyRows, |
| 29 | ): ControlPlanePoliciesServiceShape => | 29 | ): ControlPlanePoliciesServiceShape => |
| 30 | makeControlPlanePoliciesService({ | 30 | makeControlPlanePoliciesService({ |
| @@ -9,14 +9,14 @@ import { · 8 unmodified lines | |||
| 9 | } from "@executor-v2/engine"; | 9 | } from "@executor-v2/engine"; |
| 10 | import * as Effect from "effect/Effect"; | 10 | import * as Effect from "effect/Effect"; |
| 11 | 11 | ||
| 12 | export type PmRuntimeExecutionPortOptions = { | 12 | export type RuntimeHostExecutionPortOptions = { |
| 13 | defaultRuntimeKind: string; | 13 | defaultRuntimeKind: string; |
| 14 | runtimeAdapters: RuntimeAdapterRegistry; | 14 | runtimeAdapters: RuntimeAdapterRegistry; |
| 15 | toolRegistry: ToolRegistry; | 15 | toolRegistry: ToolRegistry; |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | export const createPmExecuteRuntimeRun = ( | 18 | export const createRuntimeHostExecuteRuntimeRun = ( |
| 19 | options: PmRuntimeExecutionPortOptions, | 19 | options: RuntimeHostExecutionPortOptions, |
| 20 | ): ExecuteRuntimeRun => { | 20 | ): ExecuteRuntimeRun => { |
| 21 | const runtimeToolCallService = createRuntimeToolCallService(options.toolRegistry); | 21 | const runtimeToolCallService = createRuntimeToolCallService(options.toolRegistry); |
| 22 | 22 | ||
| @@ -35,14 +35,14 @@ export const createPmExecuteRuntimeRun = ( · 12 unmodified lines | |||
| 35 | ), | 35 | ), |
| 36 | ); | 36 | ); |
| 37 | 37 | ||
| 38 | const isAvailable = yield* runtimeAdapter.isAvailable(); | 38 | const isAvailable = yield* runtimeAdapter.isAvailable(); |
| 39 | if (!isAvailable) { | 39 | if (!isAvailable) { |
| 40 | return yield* new RuntimeExecutionPortError({ | 40 | return yield* new RuntimeExecutionPortError({ |
| 41 | operation: "runtime_available", | 41 | operation: "runtime_available", |
| 42 | message: `Runtime '${options.defaultRuntimeKind}' is not available in this pm process.`, | 42 | message: `Runtime '${options.defaultRuntimeKind}' is not available in this runtime host process.`, |
| 43 | details: null, | 43 | details: null, |
| 44 | }); | 44 | }); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | return yield* runtimeAdapter | 47 | return yield* runtimeAdapter |
| 48 | .execute({ | 48 | .execute({ |
| @@ -136,7 +136,7 @@ const loadStorageScope = ( · 135 unmodified lines | |||
| 136 | }), | 136 | }), |
| 137 | ); | 137 | ); |
| 138 | 138 | ||
| 139 | export const createPmStorageService = ( | 139 | export const createRuntimeHostStorageService = ( |
| 140 | rows: StorageRows, | 140 | rows: StorageRows, |
| 141 | options: { | 141 | options: { |
| 142 | stateRootDir: string; | 142 | stateRootDir: string; |
| @@ -141,7 +141,7 @@ const listSourceTools = ( · 140 unmodified lines | |||
| 141 | return yield* parseArtifactManifest(source, artifact); | 141 | return yield* parseArtifactManifest(source, artifact); |
| 142 | }); | 142 | }); |
| 143 | 143 | ||
| 144 | export const createPmToolsService = ( | 144 | export const createRuntimeHostToolsService = ( |
| 145 | sourceStore: SourceStore, | 145 | sourceStore: SourceStore, |
| 146 | toolArtifactStore: ToolArtifactStore, | 146 | toolArtifactStore: ToolArtifactStore, |
| 147 | ): ControlPlaneToolsServiceShape => | 147 | ): ControlPlaneToolsServiceShape => |
| @@ -25,7 +25,7 @@ const sortWorkspaces = (workspaces: ReadonlyArray<Workspace>): Array<Workspace> · 24 unmodified lines | |||
| 25 | return leftName.localeCompare(rightName); | 25 | return leftName.localeCompare(rightName); |
| 26 | }); | 26 | }); |
| 27 | 27 | ||
| 28 | export const createPmWorkspacesService = ( | 28 | export const createRuntimeHostWorkspacesService = ( |
| 29 | rows: WorkspaceRows, | 29 | rows: WorkspaceRows, |
| 30 | ): ControlPlaneWorkspacesServiceShape => | 30 | ): ControlPlaneWorkspacesServiceShape => |
| 31 | makeControlPlaneWorkspacesService({ | 31 | makeControlPlaneWorkspacesService({ |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | "CONTROL_PLANE_POSTGRES_MAX_CONNECTIONS", | 19 | "CONTROL_PLANE_POSTGRES_MAX_CONNECTIONS", |
| 20 | "DATABASE_URL", | 20 | "DATABASE_URL", |
| 21 | "MCP_AUTHORIZATION_SERVER", | 21 | "MCP_AUTHORIZATION_SERVER", |
| 22 | "EXECUTOR_RUNTIME_KIND", | ||
| 22 | "PM_RUNTIME_KIND", | 23 | "PM_RUNTIME_KIND", |
| 23 | "VITE_CONVEX_URL", | 24 | "VITE_CONVEX_URL", |
| 24 | "WORKOS_API_KEY", | 25 | "WORKOS_API_KEY", |