History

Split promise and effect public APIs

Rhys Sullivan committed 7 months ago

Commit f1ed20d1 parent 6fb3ea933 files · +973 −805Browse files

Unified · Split

33 files
  1. apps/executor/src/cli/dev.ts +1 −1
  2. apps/executor/src/cli/main.ts +5 −5
  3. apps/executor/src/server/server.real-ingestion.test.ts +2 −2
  4. apps/executor/src/server/server.test.ts +4 −2
  5. packages/clients/react/src/index.test.tsx +3 −3
  6. packages/clients/react/src/index.ts +17 −22
  7. packages/platform/api/package.json +1 −0
  8. packages/platform/api/src/client.ts +190 −13
  9. packages/platform/api/src/effect.ts +19 −0
  10. packages/platform/api/src/executions/http.ts +3 −5
  11. packages/platform/api/src/executor-context.ts +3 −3
  12. packages/platform/api/src/http.ts +2 −2
  13. packages/platform/api/src/index.ts +0 −14
  14. packages/platform/api/src/local/http.ts +6 −6
  15. packages/platform/api/src/oauth/http.ts +2 −2
  16. packages/platform/api/src/policies/http.ts +6 −10
  17. packages/platform/api/src/sources/http.ts +22 −26
  18. packages/platform/sdk-file/package.json +3 −1
  19. packages/platform/sdk-file/src/client.ts +5 −0
  20. packages/platform/sdk-file/src/effect.ts +28 −0
  21. packages/platform/sdk-file/src/index.ts +14 −4
  22. packages/platform/sdk-file/src/runtime.ts +2 −0
  23. packages/platform/sdk/package.json +1 −0
  24. packages/platform/sdk/src/effect.ts +1 −0
  25. packages/platform/sdk/src/executor-effect.ts +533 −0
  26. packages/platform/sdk/src/executor.test.ts +8 −4
  27. packages/platform/sdk/src/executor.ts +70 −664
  28. packages/platform/sdk/src/runtime/execution/http.test.ts +3 −3
  29. packages/platform/sdk/src/runtime/execution/mcp-resume.test.ts +3 −3
  30. packages/platform/sdk/src/runtime/execution/runtime-config.test.ts +4 −4
  31. packages/platform/sdk/src/runtime/execution/test-http-client.ts +5 −1
  32. packages/platform/sdk/src/runtime/executor-runtime.test.ts +4 −2
  33. packages/platform/server/src/index.ts +3 −3
apps/executor/src/cli/dev.ts+1−1
@@ -1,4 +1,4 @@
1−import type { ExecutorApiClient } from "@executor/platform-api";
1+import type { ExecutorApiEffectClient as ExecutorApiClient } from "@executor/platform-api/effect";
22 import { ScopeIdSchema } from "@executor/platform-sdk/schema";
33 import * as Effect from "effect/Effect";
44
apps/executor/src/cli/main.ts+5−5
@@ -10,9 +10,9 @@ import { · 9 unmodified lines
1010 NodeRuntime,
1111 } from "@effect/platform-node";
1212 import {
13− createExecutorApiClient,
14− type ExecutorApiClient,
15−} from "@executor/platform-api";
13+ createExecutorApiEffectClient as createExecutorApiClient,
14+ type ExecutorApiEffectClient as ExecutorApiClient,
15+} from "@executor/platform-api/effect";
1616 import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal";
1717 import {
1818 EXECUTOR_SOURCES_ADD_HELP_LINES,
@@ -20,8 +20,8 @@ import { · 1 unmodified line
2020 } from "@executor/platform-sdk/runtime";
2121 import {
2222 createExecutorEffect,
23− type Executor,
24−} from "@executor/platform-sdk";
23+ type ExecutorEffect as Executor,
24+} from "@executor/platform-sdk/effect";
2525 import { createLocalExecutorBackend } from "@executor/platform-sdk-file";
2626 import {
2727 ExecutionIdSchema,
apps/executor/src/server/server.real-ingestion.test.ts+2−2
@@ -4,8 +4,8 @@ import { describe, expect, it } from "@effect/vitest"; · 3 unmodified lines
44 import * as Effect from "effect/Effect";
55
66 import {
7− createExecutorApiClient,
8−} from "@executor/platform-api";
7+ createExecutorApiEffectClient as createExecutorApiClient,
8+} from "@executor/platform-api/effect";
99 import { type SourceDiscoveryKind } from "@executor/platform-sdk/schema";
1010 import { createLocalExecutorServer } from "@executor/server";
1111
apps/executor/src/server/server.test.ts+4−2
@@ -20,9 +20,11 @@ import { startMcpElicitationDemoServer } from "@executor/mcp-elicitation-demo"; · 19 unmodified lines
2020 import { makeToolInvokerFromTools, toTool } from "@executor/codemode-core";
2121 import { startOpenApiTestServer } from "@executor/effect-test-utils";
2222 import {
23− createExecutorApiClient,
2423 executorOpenApiSpec,
2524 } from "@executor/platform-api";
25+import {
26+ createExecutorApiEffectClient as createExecutorApiClient,
27+} from "@executor/platform-api/effect";
2628 import {
2729 catalogSyncResultFromMcpManifest,
2830 type ResolveExecutionEnvironment,
@@ -33,7 +35,7 @@ import { · 4 unmodified lines
3335 resolveLocalWorkspaceContext,
3436 writeLocalSourceArtifact,
3537 writeProjectLocalExecutorConfig,
36−} from "@executor/platform-sdk-file";
38+} from "@executor/platform-sdk-file/effect";
3739 import { SourceIdSchema } from "@executor/platform-sdk/schema";
3840 import { makeSesExecutor } from "@executor/runtime-ses";
3941 import { Client } from "@modelcontextprotocol/sdk/client/index.js";
packages/clients/react/src/index.test.tsx+3−3
@@ -16,10 +16,10 @@ import { · 15 unmodified lines
1616 } from "@executor/effect-test-utils";
1717 import {
1818 createExecutorApiLayer,
19−} from "@executor/platform-api";
20−import { createExecutorEffect } from "@executor/platform-sdk";
19+} from "@executor/platform-api/http";
20+import { createExecutorEffect } from "@executor/platform-sdk/effect";
2121 import type { ExecutorRuntime } from "@executor/platform-sdk/runtime";
22−import { createLocalExecutorRuntime as createExecutorRuntime } from "@executor/platform-sdk-file";
22+import { createLocalExecutorRuntime as createExecutorRuntime } from "@executor/platform-sdk-file/runtime";
2323 import type {
2424 LocalInstallation,
2525 Source,
packages/clients/react/src/index.ts+17−22
@@ -36,7 +36,6 @@ import type { · 35 unmodified lines
3636 } from "@executor/platform-sdk/schema";
3737 import * as Cause from "effect/Cause";
3838 import * as Effect from "effect/Effect";
39−import * as Exit from "effect/Exit";
4039 import * as Option from "effect/Option";
4140 import * as Runtime from "effect/Runtime";
4241 import * as React from "react";
@@ -189,12 +188,12 @@ const encodeWorkspaceOauthClientsKey = ( · 146 unmodified lines
189188 [enabled, workspaceId, accountId, providerKey] satisfies WorkspaceOauthClientsKeyParts,
190189 );
191190
192−const causeMessage = (cause: Cause.Cause<unknown>): Error =>
193− new Error(Cause.pretty(cause));
194−
195191 const toError = (cause: unknown): Error =>
196192 cause instanceof Error ? cause : new Error(String(cause));
197193
194+const causeMessage = (cause: Cause.Cause<unknown>): Error =>
195+ new Error(Cause.pretty(cause));
196+
198197 const shouldLogExecutorDevErrors = (): boolean => {
199198 if (typeof window === "undefined") {
200199 return false;
@@ -238,36 +237,32 @@ const logExecutorDevError = (label: string, details: Record<string, unknown>): v · 37 unmodified lines
238237 const runControlPlane = async <A>(input: {
239238 baseUrl?: string;
240239 accountId?: string;
241− execute: (client: ExecutorApiClient) => Effect.Effect<A, unknown, never>;
240+ execute: (client: ExecutorApiClient) => Promise<A>;
242241 }): Promise<A> => {
243242 const baseUrl = input.baseUrl ?? apiBaseUrl;
244243 const accountId = input.accountId;
245244
246− const exit = await Effect.runPromiseExit(
247− createExecutorApiClient({
245+ try {
246+ const client = await createExecutorApiClient({
248247 baseUrl,
249248 ...(accountId !== undefined ? { accountId } : {}),
250− }).pipe(Effect.flatMap(input.execute)),
251− );
252−
253− if (Exit.isSuccess(exit)) {
254− return exit.value;
249+ });
250+ return await input.execute(client);
251+ } catch (cause) {
252+ const error = toError(cause);
253+ logExecutorDevError("control-plane request failed", {
254+ baseUrl,
255+ accountId,
256+ error: describeExecutorDevError(error),
257+ });
258+ throw error;
255259 }
256−
257− const error = Cause.squash(exit.cause);
258− logExecutorDevError("control-plane request failed", {
259− baseUrl,
260− accountId,
261− error: describeExecutorDevError(error),
262− cause: Cause.pretty(exit.cause),
263− });
264− throw error;
265260 };
266261
267262 const controlPlaneRequest = <A>(input: {
268263 baseUrl?: string;
269264 accountId?: string;
270− execute: (client: ExecutorApiClient) => Effect.Effect<A, unknown, never>;
265+ execute: (client: ExecutorApiClient) => Promise<A>;
271266 }): Effect.Effect<A, Error> =>
272267 Effect.tryPromise({
273268 try: () => runControlPlane(input),
packages/platform/api/package.json+1−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 ".": "./src/index.ts",
77 "./api": "./src/api.ts",
88 "./client": "./src/client.ts",
9+ "./effect": "./src/effect.ts",
910 "./http": "./src/http.ts",
1011 "./errors": "./src/errors.ts",
1112 "./local/api": "./src/local/api.ts",
packages/platform/api/src/client.ts+190−13
@@ -1,19 +1,196 @@
1−import {
2− FetchHttpClient,
3− HttpApiClient,
4−} from "@effect/platform";
51 import * as Effect from "effect/Effect";
62
7−import { ExecutorApi } from "./api";
3+import {
4+ createExecutorApiEffectClient,
5+ type ExecutorApiEffectClient,
6+} from "./effect";
7+
8+type StripResponse<T> = T extends readonly [infer Value, unknown] ? Value : T;
9+type RemoveWithResponse<T> = T extends object ? Omit<T, "withResponse"> : T;
10+type MethodInput<F extends (input: any) => Effect.Effect<any, any, any>> = RemoveWithResponse<
11+ Parameters<F>[0]
12+>;
13+type MethodOutput<F extends (input: any) => Effect.Effect<any, any, any>> = StripResponse<
14+ Effect.Effect.Success<ReturnType<F>>
15+>;
16+type PromiseMethod<F extends (input: any) => Effect.Effect<any, any, any>> = (
17+ input: MethodInput<F>,
18+) => Promise<MethodOutput<F>>;
19+
20+export type ExecutorApiClient = {
21+ local: {
22+ installation: PromiseMethod<ExecutorApiEffectClient["local"]["installation"]>;
23+ config: PromiseMethod<ExecutorApiEffectClient["local"]["config"]>;
24+ listSecrets: PromiseMethod<ExecutorApiEffectClient["local"]["listSecrets"]>;
25+ createSecret: PromiseMethod<ExecutorApiEffectClient["local"]["createSecret"]>;
26+ updateSecret: PromiseMethod<ExecutorApiEffectClient["local"]["updateSecret"]>;
27+ deleteSecret: PromiseMethod<ExecutorApiEffectClient["local"]["deleteSecret"]>;
28+ };
29+ policies: {
30+ list: PromiseMethod<ExecutorApiEffectClient["policies"]["list"]>;
31+ create: PromiseMethod<ExecutorApiEffectClient["policies"]["create"]>;
32+ get: PromiseMethod<ExecutorApiEffectClient["policies"]["get"]>;
33+ update: PromiseMethod<ExecutorApiEffectClient["policies"]["update"]>;
34+ remove: PromiseMethod<ExecutorApiEffectClient["policies"]["remove"]>;
35+ };
36+ sources: {
37+ discover: PromiseMethod<ExecutorApiEffectClient["sources"]["discover"]>;
38+ connect: PromiseMethod<ExecutorApiEffectClient["sources"]["connect"]>;
39+ connectBatch: PromiseMethod<ExecutorApiEffectClient["sources"]["connectBatch"]>;
40+ listWorkspaceOauthClients: PromiseMethod<
41+ ExecutorApiEffectClient["sources"]["listWorkspaceOauthClients"]
42+ >;
43+ createWorkspaceOauthClient: PromiseMethod<
44+ ExecutorApiEffectClient["sources"]["createWorkspaceOauthClient"]
45+ >;
46+ removeWorkspaceOauthClient: PromiseMethod<
47+ ExecutorApiEffectClient["sources"]["removeWorkspaceOauthClient"]
48+ >;
49+ removeProviderAuthGrant: PromiseMethod<
50+ ExecutorApiEffectClient["sources"]["removeProviderAuthGrant"]
51+ >;
52+ list: PromiseMethod<ExecutorApiEffectClient["sources"]["list"]>;
53+ create: PromiseMethod<ExecutorApiEffectClient["sources"]["create"]>;
54+ get: PromiseMethod<ExecutorApiEffectClient["sources"]["get"]>;
55+ update: PromiseMethod<ExecutorApiEffectClient["sources"]["update"]>;
56+ remove: PromiseMethod<ExecutorApiEffectClient["sources"]["remove"]>;
57+ inspection: PromiseMethod<ExecutorApiEffectClient["sources"]["inspection"]>;
58+ inspectionTool: PromiseMethod<ExecutorApiEffectClient["sources"]["inspectionTool"]>;
59+ inspectionDiscover: PromiseMethod<
60+ ExecutorApiEffectClient["sources"]["inspectionDiscover"]
61+ >;
62+ credentialPage: PromiseMethod<ExecutorApiEffectClient["sources"]["credentialPage"]>;
63+ credentialSubmit: PromiseMethod<ExecutorApiEffectClient["sources"]["credentialSubmit"]>;
64+ credentialComplete: PromiseMethod<
65+ ExecutorApiEffectClient["sources"]["credentialComplete"]
66+ >;
67+ providerOauthComplete: PromiseMethod<
68+ ExecutorApiEffectClient["sources"]["providerOauthComplete"]
69+ >;
70+ };
71+ oauth: {
72+ startSourceAuth: PromiseMethod<ExecutorApiEffectClient["oauth"]["startSourceAuth"]>;
73+ sourceAuthCallback: PromiseMethod<ExecutorApiEffectClient["oauth"]["sourceAuthCallback"]>;
74+ };
75+ executions: {
76+ create: PromiseMethod<ExecutorApiEffectClient["executions"]["create"]>;
77+ get: PromiseMethod<ExecutorApiEffectClient["executions"]["get"]>;
78+ resume: PromiseMethod<ExecutorApiEffectClient["executions"]["resume"]>;
79+ };
80+};
881
9−export const createExecutorApiClient = (input: {
82+const isResponseTuple = <Value>(
83+ value: Value | readonly [Value, unknown],
84+): value is readonly [Value, unknown] =>
85+ Array.isArray(value) && value.length === 2;
86+
87+function stripResponse<Value>(value: Value | readonly [Value, unknown]): Value {
88+ return isResponseTuple(value) ? value[0] : value;
89+}
90+
91+const wrapMethod = <
92+ F extends (input: any) => Effect.Effect<any, unknown, never>,
93+>(
94+ effectClientPromise: Promise<ExecutorApiEffectClient>,
95+ select: (client: ExecutorApiEffectClient) => F,
96+): PromiseMethod<F> => {
97+ const wrapped = (input: MethodInput<F>): Promise<MethodOutput<F>> =>
98+ effectClientPromise
99+ .then((client) => Effect.runPromise(select(client)(input)))
100+ .then(stripResponse);
101+
102+ return wrapped;
103+};
104+
105+export const createExecutorApiClient = async (input: {
10106 baseUrl: string;
11107 accountId?: string;
12−}) =>
13− HttpApiClient.make(ExecutorApi, {
14− baseUrl: input.baseUrl,
15− }).pipe(Effect.provide(FetchHttpClient.layer));
108+}): Promise<ExecutorApiClient> => {
109+ const effectClientPromise = Effect.runPromise(
110+ createExecutorApiEffectClient(input),
111+ );
16112
17−export type ExecutorApiClient = Effect.Effect.Success<
18− ReturnType<typeof createExecutorApiClient>
19−>;
113+ return {
114+ local: {
115+ installation: wrapMethod(effectClientPromise, (client) => client.local.installation),
116+ config: wrapMethod(effectClientPromise, (client) => client.local.config),
117+ listSecrets: wrapMethod(effectClientPromise, (client) => client.local.listSecrets),
118+ createSecret: wrapMethod(effectClientPromise, (client) => client.local.createSecret),
119+ updateSecret: wrapMethod(effectClientPromise, (client) => client.local.updateSecret),
120+ deleteSecret: wrapMethod(effectClientPromise, (client) => client.local.deleteSecret),
121+ },
122+ policies: {
123+ list: wrapMethod(effectClientPromise, (client) => client.policies.list),
124+ create: wrapMethod(effectClientPromise, (client) => client.policies.create),
125+ get: wrapMethod(effectClientPromise, (client) => client.policies.get),
126+ update: wrapMethod(effectClientPromise, (client) => client.policies.update),
127+ remove: wrapMethod(effectClientPromise, (client) => client.policies.remove),
128+ },
129+ sources: {
130+ discover: wrapMethod(effectClientPromise, (client) => client.sources.discover),
131+ connect: wrapMethod(effectClientPromise, (client) => client.sources.connect),
132+ connectBatch: wrapMethod(effectClientPromise, (client) => client.sources.connectBatch),
133+ listWorkspaceOauthClients: wrapMethod(
134+ effectClientPromise,
135+ (client) => client.sources.listWorkspaceOauthClients,
136+ ),
137+ createWorkspaceOauthClient: wrapMethod(
138+ effectClientPromise,
139+ (client) => client.sources.createWorkspaceOauthClient,
140+ ),
141+ removeWorkspaceOauthClient: wrapMethod(
142+ effectClientPromise,
143+ (client) => client.sources.removeWorkspaceOauthClient,
144+ ),
145+ removeProviderAuthGrant: wrapMethod(
146+ effectClientPromise,
147+ (client) => client.sources.removeProviderAuthGrant,
148+ ),
149+ list: wrapMethod(effectClientPromise, (client) => client.sources.list),
150+ create: wrapMethod(effectClientPromise, (client) => client.sources.create),
151+ get: wrapMethod(effectClientPromise, (client) => client.sources.get),
152+ update: wrapMethod(effectClientPromise, (client) => client.sources.update),
153+ remove: wrapMethod(effectClientPromise, (client) => client.sources.remove),
154+ inspection: wrapMethod(effectClientPromise, (client) => client.sources.inspection),
155+ inspectionTool: wrapMethod(
156+ effectClientPromise,
157+ (client) => client.sources.inspectionTool,
158+ ),
159+ inspectionDiscover: wrapMethod(
160+ effectClientPromise,
161+ (client) => client.sources.inspectionDiscover,
162+ ),
163+ credentialPage: wrapMethod(
164+ effectClientPromise,
165+ (client) => client.sources.credentialPage,
166+ ),
167+ credentialSubmit: wrapMethod(
168+ effectClientPromise,
169+ (client) => client.sources.credentialSubmit,
170+ ),
171+ credentialComplete: wrapMethod(
172+ effectClientPromise,
173+ (client) => client.sources.credentialComplete,
174+ ),
175+ providerOauthComplete: wrapMethod(
176+ effectClientPromise,
177+ (client) => client.sources.providerOauthComplete,
178+ ),
179+ },
180+ oauth: {
181+ startSourceAuth: wrapMethod(
182+ effectClientPromise,
183+ (client) => client.oauth.startSourceAuth,
184+ ),
185+ sourceAuthCallback: wrapMethod(
186+ effectClientPromise,
187+ (client) => client.oauth.sourceAuthCallback,
188+ ),
189+ },
190+ executions: {
191+ create: wrapMethod(effectClientPromise, (client) => client.executions.create),
192+ get: wrapMethod(effectClientPromise, (client) => client.executions.get),
193+ resume: wrapMethod(effectClientPromise, (client) => client.executions.resume),
194+ },
195+ };
196+};
packages/platform/api/src/effect.ts+19−0
@@ -0,0 +1,19 @@
1+import {
2+ FetchHttpClient,
3+ HttpApiClient,
4+} from "@effect/platform";
5+import * as Effect from "effect/Effect";
6+
7+import { ExecutorApi } from "./api";
8+
9+export const createExecutorApiEffectClient = (input: {
10+ baseUrl: string;
11+ accountId?: string;
12+}) =>
13+ HttpApiClient.make(ExecutorApi, {
14+ baseUrl: input.baseUrl,
15+ }).pipe(Effect.provide(FetchHttpClient.layer));
16+
17+export type ExecutorApiEffectClient = Effect.Effect.Success<
18+ ReturnType<typeof createExecutorApiEffectClient>
19+>;
packages/platform/api/src/executions/http.ts+3−5
@@ -11,19 +11,17 @@ export const ExecutorExecutionsLive = HttpApiBuilder.group( · 10 unmodified lines
1111 handlers
1212 .handle("create", ({ path, payload }) =>
1313 resolveRequestedLocalWorkspace("executions.create", path.workspaceId).pipe(
14− Effect.flatMap((executor) => executor.effect.executions.create(payload)),
14+ Effect.flatMap((executor) => executor.executions.create(payload)),
1515 ),
1616 )
1717 .handle("get", ({ path }) =>
1818 resolveRequestedLocalWorkspace("executions.get", path.workspaceId).pipe(
19− Effect.flatMap((executor) => executor.effect.executions.get(path.executionId)),
19+ Effect.flatMap((executor) => executor.executions.get(path.executionId)),
2020 ),
2121 )
2222 .handle("resume", ({ path, payload }) =>
2323 resolveRequestedLocalWorkspace("executions.resume", path.workspaceId).pipe(
24− Effect.flatMap((executor) =>
25− executor.effect.executions.resume(path.executionId, payload)
26− ),
24+ Effect.flatMap((executor) => executor.executions.resume(path.executionId, payload)),
2725 ),
2826 ),
2927 );
packages/platform/api/src/executor-context.ts+3−3
@@ -1,4 +1,4 @@
1−import type { Executor } from "@executor/platform-sdk";
1+import type { ExecutorEffect } from "@executor/platform-sdk/effect";
22 import type { ScopeId as WorkspaceId } from "@executor/platform-sdk/schema";
33 import {
44 ControlPlaneBadRequestError,
@@ -11,9 +11,9 @@ import * as Layer from "effect/Layer"; · 6 unmodified lines
1111
1212 export class ControlPlaneExecutor extends Context.Tag(
1313 "@executor/platform-api/ControlPlaneExecutor",
14−)<ControlPlaneExecutor, Executor>() {}
14+)<ControlPlaneExecutor, ExecutorEffect>() {}
1515
16−export const createControlPlaneExecutorLayer = (executor: Executor) =>
16+export const createControlPlaneExecutorLayer = (executor: ExecutorEffect) =>
1717 Layer.succeed(ControlPlaneExecutor, executor);
1818
1919 export const getControlPlaneExecutor = () => ControlPlaneExecutor;
packages/platform/api/src/http.ts+2−2
@@ -1,6 +1,6 @@
11 import { HttpApiBuilder } from "@effect/platform";
22 import * as Layer from "effect/Layer";
3−import type { Executor } from "@executor/platform-sdk";
3+import type { ExecutorEffect } from "@executor/platform-sdk/effect";
44
55 import { ExecutorApi } from "./api";
66 import { createControlPlaneExecutorLayer } from "./executor-context";
@@ -20,7 +20,7 @@ export const ExecutorApiLive = HttpApiBuilder.api(ExecutorApi).pipe( · 13 unmodified lines
2020
2121 export type ExecutorApiRuntimeContext = Layer.Layer.Context<typeof ExecutorApiLive>;
2222
23−export const createExecutorApiLayer = (executor: Executor) =>
23+export const createExecutorApiLayer = (executor: ExecutorEffect) =>
2424 ExecutorApiLive.pipe(
2525 Layer.provide(createControlPlaneExecutorLayer(executor)),
2626 );
packages/platform/api/src/index.ts+0−14
@@ -17,13 +17,6 @@ export { · 16 unmodified lines
1717 ControlPlaneUnauthorizedError,
1818 } from "./errors";
1919
20−export {
21− ExecutorApiLive,
22− type ExecutorApiRuntimeContext,
23− type BuiltExecutorApiLayer,
24− createExecutorApiLayer,
25−} from "./http";
26−
2720 export {
2821 CreateExecutionPayloadSchema,
2922 ExecutionsApi,
@@ -31,7 +24,6 @@ export { · 1 unmodified line
3124 type CreateExecutionPayload,
3225 type ResumeExecutionPayload,
3326 } from "./executions/api";
34−export { ExecutorExecutionsLive } from "./executions/http";
3527
3628 export {
3729 LocalApi,
@@ -44,7 +36,6 @@ export { · 6 unmodified lines
4436 type UpdateSecretResult,
4537 type DeleteSecretResult,
4638 } from "./local/api";
47−export { ExecutorLocalLive } from "./local/http";
4839
4940 export {
5041 OAuthApi,
@@ -59,7 +50,6 @@ export { · 8 unmodified lines
5950 type CompleteSourceOAuthResult,
6051 type SourceOAuthPopupResult,
6152 } from "./oauth/api";
62−export { ExecutorOAuthLive } from "./oauth/http";
6353
6454 export {
6555 ConnectSourceBatchPayloadSchema,
@@ -80,7 +70,6 @@ export { · 14 unmodified lines
8070 type DiscoverSourcePayload,
8171 type UpdateSourcePayload,
8272 } from "./sources/api";
83−export { ExecutorSourcesLive } from "./sources/http";
8473
8574 export {
8675 CreatePolicyPayloadSchema,
@@ -89,6 +78,3 @@ export { · 2 unmodified lines
8978 type CreatePolicyPayload,
9079 type UpdatePolicyPayload,
9180 } from "./policies/api";
92−export { ExecutorPoliciesLive } from "./policies/http";
93−
94−export { resolveRequestedLocalWorkspace } from "./local-context";
packages/platform/api/src/local/http.ts+6−6
@@ -19,35 +19,35 @@ export const ExecutorLocalLive = HttpApiBuilder.group( · 18 unmodified lines
1919 handlers
2020 .handle("installation", () =>
2121 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
22− executor.effect.local.installation().pipe(
22+ executor.local.installation().pipe(
2323 Effect.mapError(toStorageError("local.installation")),
2424 )
2525 )
2626 )
2727 .handle("config", () =>
2828 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
29− executor.effect.local.config().pipe(
29+ executor.local.config().pipe(
3030 Effect.mapError(toStorageError("local.config")),
3131 )
3232 )
3333 )
3434 .handle("listSecrets", () =>
3535 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
36− executor.effect.secrets.list().pipe(
36+ executor.secrets.list().pipe(
3737 Effect.mapError(toStorageError("local.listSecrets")),
3838 )
3939 )
4040 )
4141 .handle("createSecret", ({ payload }) =>
4242 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
43− executor.effect.secrets.create(payload).pipe(
43+ executor.secrets.create(payload).pipe(
4444 Effect.mapError(toStorageError("local.createSecret")),
4545 )
4646 )
4747 )
4848 .handle("updateSecret", ({ path, payload }) =>
4949 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
50− executor.effect.secrets.update({
50+ executor.secrets.update({
5151 secretId: path.secretId,
5252 payload,
5353 }).pipe(Effect.mapError(toStorageError("local.updateSecret")))
@@ -55,7 +55,7 @@ export const ExecutorLocalLive = HttpApiBuilder.group( · 1 unmodified line
5555 )
5656 .handle("deleteSecret", ({ path }) =>
5757 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
58− executor.effect.secrets.remove(path.secretId).pipe(
58+ executor.secrets.remove(path.secretId).pipe(
5959 Effect.mapError(toStorageError("local.deleteSecret")),
6060 )
6161 )
packages/platform/api/src/oauth/http.ts+2−2
@@ -241,7 +241,7 @@ export const ExecutorOAuthLive = HttpApiBuilder.group( · 240 unmodified lines
241241 Effect.flatMap((executor) =>
242242 Effect.gen(function* () {
243243 const request = yield* HttpServerRequest.HttpServerRequest;
244− return yield* executor.effect.oauth.startSourceAuth({
244+ return yield* executor.oauth.startSourceAuth({
245245 baseUrl: resolveRequestOrigin(request),
246246 displayName: payload.name,
247247 provider: {
@@ -271,7 +271,7 @@ export const ExecutorOAuthLive = HttpApiBuilder.group( · 23 unmodified lines
271271 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
272272 Effect.gen(function* () {
273273 const completed = yield* Effect.either(
274− executor.effect.oauth.completeSourceAuth({
274+ executor.oauth.completeSourceAuth({
275275 state: urlParams.state,
276276 code: urlParams.code,
277277 error: urlParams.error,
packages/platform/api/src/policies/http.ts+6−10
@@ -11,7 +11,7 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 10 unmodified lines
1111 handlers
1212 .handle("list", ({ path }) =>
1313 resolveRequestedLocalWorkspace("policies.list", path.workspaceId).pipe(
14− Effect.flatMap((executor) => executor.effect.policies.list()),
14+ Effect.flatMap((executor) => executor.policies.list()),
1515 ),
1616 )
1717 .handle("create", ({ path, payload }) =>
@@ -19,12 +19,12 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line
1919 "policies.create",
2020 path.workspaceId,
2121 ).pipe(
22− Effect.flatMap((executor) => executor.effect.policies.create(payload)),
22+ Effect.flatMap((executor) => executor.policies.create(payload)),
2323 ),
2424 )
2525 .handle("get", ({ path }) =>
2626 resolveRequestedLocalWorkspace("policies.get", path.workspaceId).pipe(
27− Effect.flatMap((executor) => executor.effect.policies.get(path.policyId)),
27+ Effect.flatMap((executor) => executor.policies.get(path.policyId)),
2828 ),
2929 )
3030 .handle("update", ({ path, payload }) =>
@@ -32,9 +32,7 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line
3232 "policies.update",
3333 path.workspaceId,
3434 ).pipe(
35− Effect.flatMap((executor) =>
36− executor.effect.policies.update(path.policyId, payload)
37− ),
35+ Effect.flatMap((executor) => executor.policies.update(path.policyId, payload)),
3836 ),
3937 )
4038 .handle("remove", ({ path }) =>
@@ -42,10 +40,8 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line
4240 "policies.remove",
4341 path.workspaceId,
4442 ).pipe(
45− Effect.flatMap((executor) => executor.effect.policies.remove(path.policyId)),
46− Effect.map((result) => ({
47− removed: result.removed,
48− })),
43+ Effect.flatMap((executor) => executor.policies.remove(path.policyId)),
44+ Effect.map((removed) => ({ removed })),
4945 ),
5046 ),
5147 );
packages/platform/api/src/sources/http.ts+22−26
@@ -713,7 +713,7 @@ const credentialSubmitErrorResponse = (input: { · 712 unmodified lines
713713 input.workspaceId,
714714 ).pipe(
715715 Effect.flatMap((executor) =>
716− executor.effect.local.credentials.get({
716+ executor.local.credentials.get({
717717 sourceId: input.sourceId,
718718 interactionId: input.interactionId,
719719 }),
@@ -749,7 +749,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 29 unmodified lines
749749 handlers
750750 .handle("discover", ({ payload }) =>
751751 Effect.flatMap(getControlPlaneExecutor(), (executor) =>
752− executor.effect.sources.discover({
752+ executor.sources.discover({
753753 url: payload.url,
754754 probeAuth: payload.probeAuth,
755755 }).pipe(
@@ -770,14 +770,14 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 14 unmodified lines
770770 const baseUrl = resolveRequestOrigin(request);
771771
772772 if (isInteractiveConnectPayload(payload)) {
773− return yield* executor.effect.sources.connect(
773+ return yield* executor.sources.connect(
774774 toExecutorMcpSourceInput(payload, baseUrl),
775775 );
776776 }
777777
778778 const sourceInput = toExecutorSourceInput(payload);
779779 if (sourceInput) {
780− return yield* executor.effect.sources.add(sourceInput, {
780+ return yield* executor.sources.add(sourceInput, {
781781 baseUrl,
782782 });
783783 }
@@ -804,7 +804,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 20 unmodified lines
804804 Effect.flatMap((executor) =>
805805 Effect.gen(function* () {
806806 const request = yield* HttpServerRequest.HttpServerRequest;
807− return yield* executor.effect.sources.connectBatch({
807+ return yield* executor.sources.connectBatch({
808808 ...payload,
809809 baseUrl: resolveRequestOrigin(request),
810810 });
@@ -822,7 +822,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 11 unmodified lines
822822 path.workspaceId,
823823 ).pipe(
824824 Effect.flatMap((executor) =>
825− executor.effect.sources.oauthClients.list(urlParams.providerKey).pipe(
825+ executor.sources.oauthClients.list(urlParams.providerKey).pipe(
826826 Effect.catchAll((cause) =>
827827 Effect.fail(
828828 toBadRequestError("sources.listWorkspaceOauthClients", cause),
@@ -838,7 +838,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 9 unmodified lines
838838 path.workspaceId,
839839 ).pipe(
840840 Effect.flatMap((executor) =>
841− executor.effect.sources.oauthClients.create(payload).pipe(
841+ executor.sources.oauthClients.create(payload).pipe(
842842 Effect.catchAll((cause) =>
843843 Effect.fail(
844844 toBadRequestError(
@@ -857,7 +857,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 12 unmodified lines
857857 path.workspaceId,
858858 ).pipe(
859859 Effect.flatMap((executor) =>
860− executor.effect.sources.oauthClients.remove(path.oauthClientId).pipe(
860+ executor.sources.oauthClients.remove(path.oauthClientId).pipe(
861861 Effect.map((result) => ({ removed: result })),
862862 Effect.catchAll((cause) =>
863863 Effect.fail(
@@ -877,7 +877,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 13 unmodified lines
877877 path.workspaceId,
878878 ).pipe(
879879 Effect.flatMap((executor) =>
880− executor.effect.sources.providerGrants.remove(path.grantId).pipe(
880+ executor.sources.providerGrants.remove(path.grantId).pipe(
881881 Effect.map((result) => ({ removed: result })),
882882 Effect.catchAll((cause) =>
883883 Effect.fail(
@@ -893,17 +893,17 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 9 unmodified lines
893893 )
894894 .handle("list", ({ path }) =>
895895 resolveRequestedLocalWorkspace("sources.list", path.workspaceId).pipe(
896− Effect.flatMap((executor) => executor.effect.sources.list()),
896+ Effect.flatMap((executor) => executor.sources.list()),
897897 ),
898898 )
899899 .handle("create", ({ path, payload }) =>
900900 resolveRequestedLocalWorkspace("sources.create", path.workspaceId).pipe(
901− Effect.flatMap((executor) => executor.effect.sources.create(payload)),
901+ Effect.flatMap((executor) => executor.sources.create(payload)),
902902 ),
903903 )
904904 .handle("get", ({ path }) =>
905905 resolveRequestedLocalWorkspace("sources.get", path.workspaceId).pipe(
906− Effect.flatMap((executor) => executor.effect.sources.get(path.sourceId)),
906+ Effect.flatMap((executor) => executor.sources.get(path.sourceId)),
907907 ),
908908 )
909909 .handle("inspection", ({ path }) =>
@@ -911,9 +911,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 1 unmodified line
911911 "sources.inspection",
912912 path.workspaceId,
913913 ).pipe(
914− Effect.flatMap((executor) =>
915− executor.effect.sources.inspection.get(path.sourceId),
916− ),
914+ Effect.flatMap((executor) => executor.sources.inspection.get(path.sourceId)),
917915 ),
918916 )
919917 .handle("inspectionTool", ({ path }) =>
@@ -922,7 +920,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines
922920 path.workspaceId,
923921 ).pipe(
924922 Effect.flatMap((executor) =>
925− executor.effect.sources.inspection.tool({
923+ executor.sources.inspection.tool({
926924 sourceId: path.sourceId,
927925 toolPath: path.toolPath,
928926 }),
@@ -935,7 +933,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 6 unmodified lines
935933 path.workspaceId,
936934 ).pipe(
937935 Effect.flatMap((executor) =>
938− executor.effect.sources.inspection.discover({
936+ executor.sources.inspection.discover({
939937 sourceId: path.sourceId,
940938 payload,
941939 }),
@@ -944,15 +942,13 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines
944942 )
945943 .handle("update", ({ path, payload }) =>
946944 resolveRequestedLocalWorkspace("sources.update", path.workspaceId).pipe(
947− Effect.flatMap((executor) =>
948− executor.effect.sources.update(path.sourceId, payload)
949− ),
945+ Effect.flatMap((executor) => executor.sources.update(path.sourceId, payload)),
950946 ),
951947 )
952948 .handle("remove", ({ path }) =>
953949 resolveRequestedLocalWorkspace("sources.remove", path.workspaceId).pipe(
954− Effect.flatMap((executor) => executor.effect.sources.remove(path.sourceId)),
955− Effect.map((result) => ({ removed: result.removed })),
950+ Effect.flatMap((executor) => executor.sources.remove(path.sourceId)),
951+ Effect.map((removed) => ({ removed })),
956952 ),
957953 )
958954 .handle("credentialPage", ({ path, urlParams }) =>
@@ -961,7 +957,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines
961957 path.workspaceId,
962958 ).pipe(
963959 Effect.flatMap((executor) =>
964− executor.effect.local.credentials.get({
960+ executor.local.credentials.get({
965961 sourceId: path.sourceId,
966962 interactionId: urlParams.interactionId,
967963 }),
@@ -1006,7 +1002,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 38 unmodified lines
10061002 path.workspaceId,
10071003 ).pipe(
10081004 Effect.flatMap((executor) =>
1009− executor.effect.local.credentials.submit({
1005+ executor.local.credentials.submit({
10101006 sourceId: path.sourceId,
10111007 interactionId: urlParams.interactionId,
10121008 action:
@@ -1081,7 +1077,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 68 unmodified lines
10811077 path.workspaceId,
10821078 ).pipe(
10831079 Effect.flatMap((executor) =>
1084− executor.effect.local.credentials.complete({
1080+ executor.local.credentials.complete({
10851081 sourceId: path.sourceId,
10861082 state: urlParams.state,
10871083 code: urlParams.code,
@@ -1136,7 +1132,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 48 unmodified lines
11361132 ).pipe(
11371133 Effect.flatMap((executor) =>
11381134 Effect.gen(function* () {
1139− const completed = yield* executor.effect.oauth.completeProviderCallback({
1135+ const completed = yield* executor.oauth.completeProviderCallback({
11401136 scopeId: path.workspaceId,
11411137 state: urlParams.state,
11421138 code: urlParams.code,
packages/platform/sdk-file/package.json+3−1
@@ -3,7 +3,9 @@ · 2 unmodified lines
33 "private": true,
44 "type": "module",
55 "exports": {
6− ".": "./src/index.ts"
6+ ".": "./src/client.ts",
7+ "./effect": "./src/effect.ts",
8+ "./runtime": "./src/runtime.ts"
79 },
810 "scripts": {
911 "fixture:release:capture": "bun run ./src/capture-release-workspace-fixture.ts",
packages/platform/sdk-file/src/client.ts+5−0
@@ -0,0 +1,5 @@
1+export type { CreateLocalExecutorBackendOptions } from "./index";
2+export {
3+ createLocalExecutor,
4+ createLocalExecutorBackend,
5+} from "./index";
packages/platform/sdk-file/src/effect.ts+28−0
@@ -0,0 +1,28 @@
1+export type { CreateLocalExecutorBackendOptions } from "./index";
2+export {
3+ buildLocalSourceArtifact,
4+ createLocalExecutorEffect,
5+ createLocalExecutorServicesEffect,
6+ deriveLocalInstallation,
7+ getOrProvisionLocalInstallation,
8+ loadLocalExecutorConfig,
9+ loadLocalExecutorStateSnapshot,
10+ loadLocalInstallation,
11+ loadLocalWorkspaceState,
12+ readLocalSourceArtifact,
13+ refreshSourceTypeDeclarationInBackground,
14+ refreshWorkspaceSourceTypeDeclarationsInBackground,
15+ removeLocalSourceArtifact,
16+ resolveConfigRelativePath,
17+ resolveLocalWorkspaceContext,
18+ syncSourceTypeDeclarationNode,
19+ syncWorkspaceSourceTypeDeclarationsNode,
20+ writeLocalExecutorStateSnapshot,
21+ writeLocalSourceArtifact,
22+ writeLocalWorkspaceState,
23+ writeProjectLocalExecutorConfig,
24+} from "./index";
25+export type {
26+ LoadedLocalExecutorConfig,
27+ ResolvedLocalWorkspaceContext,
28+} from "./index";
packages/platform/sdk-file/src/index.ts+14−4
@@ -3,8 +3,6 @@ import { NodeFileSystem } from "@effect/platform-node"; · 2 unmodified lines
33 import {
44 createExecutor,
55 createExecutorBackend,
6− createExecutorEffect,
7− type CreateExecutorOptions,
86 type Executor,
97 type ExecutorBackend,
108 type ExecutorBackendServices,
@@ -12,6 +10,11 @@ import { · 1 unmodified line
1210 type ExecutorSourceTypeDeclarationsBackend,
1311 type ExecutorScopeDescriptor,
1412 } from "@executor/platform-sdk";
13+import {
14+ createExecutorEffect,
15+ type ExecutorEffect,
16+ type CreateExecutorEffectOptions as CreateExecutorOptions,
17+} from "@executor/platform-sdk/effect";
1518 import type {
1619 LocalExecutorConfig,
1720 LocalInstallation,
@@ -307,7 +310,7 @@ export const createLocalExecutorRuntime = ( · 289 unmodified lines
307310
308311 export const createLocalExecutorEffect = (
309312 options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {},
310−): Effect.Effect<Executor, Error> =>
313+): Effect.Effect<ExecutorEffect, Error> =>
311314 createExecutorEffect({
312315 backend: createLocalExecutorBackend(options),
313316 executionResolver: options.executionResolver,
@@ -318,7 +321,14 @@ export const createLocalExecutorEffect = ( · 4 unmodified lines
318321
319322 export const createLocalExecutor = (
320323 options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {},
321−): Promise<Executor> => Effect.runPromise(createLocalExecutorEffect(options));
324+): Promise<Executor> =>
325+ createExecutor({
326+ backend: createLocalExecutorBackend(options),
327+ executionResolver: options.executionResolver,
328+ createInternalToolMap: options.createInternalToolMap,
329+ resolveSecretMaterial: options.resolveSecretMaterial,
330+ getLocalServerBaseUrl: options.getLocalServerBaseUrl,
331+ });
322332
323333 export {
324334 deriveLocalInstallation,
packages/platform/sdk-file/src/runtime.ts+2−0
@@ -0,0 +1,2 @@
1+export type { CreateLocalExecutorBackendOptions } from "./index";
2+export { createLocalExecutorRuntime } from "./index";
packages/platform/sdk/package.json+1−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 ".": "./src/index.ts",
77 "./backend": "./src/backend.ts",
88 "./contracts": "./src/contracts.ts",
9+ "./effect": "./src/effect.ts",
910 "./executor": "./src/executor.ts",
1011 "./errors": "./src/errors.ts",
1112 "./operations": "./src/operations.ts",
packages/platform/sdk/src/effect.ts+1−0
@@ -0,0 +1 @@
1+export * from "./executor-effect";
packages/platform/sdk/src/executor-effect.ts+533−0
@@ -0,0 +1,533 @@
1+import * as Effect from "effect/Effect";
2+
3+import type {
4+ ScopeId,
5+ Execution,
6+ ExecutionEnvelope,
7+ ExecutionInteraction,
8+ LocalInstallation,
9+ LocalScopePolicy,
10+ ProviderAuthGrant,
11+ ScopeOauthClient,
12+ Source,
13+} from "./schema";
14+import { ExecutionIdSchema } from "./schema";
15+import type {
16+ CreateExecutionPayload,
17+ ResumeExecutionPayload,
18+} from "./executions/contracts";
19+import type {
20+ CreateSecretPayload,
21+ CreateSecretResult,
22+ DeleteSecretResult,
23+ InstanceConfig,
24+ SecretListItem,
25+ UpdateSecretPayload,
26+ UpdateSecretResult,
27+} from "./local/contracts";
28+import {
29+ completeSourceCredentialSetup,
30+ getLocalInstallation,
31+ getSourceCredentialInteraction,
32+ submitSourceCredentialInteraction,
33+} from "./local/operations";
34+import {
35+ createLocalSecret,
36+ deleteLocalSecret,
37+ getLocalInstanceConfig,
38+ listLocalSecrets,
39+ updateLocalSecret,
40+} from "./local/secrets";
41+import type {
42+ CreatePolicyPayload,
43+ UpdatePolicyPayload,
44+} from "./policies/contracts";
45+import {
46+ createPolicy,
47+ getPolicy,
48+ listPolicies,
49+ removePolicy,
50+ updatePolicy,
51+} from "./policies/operations";
52+import type {
53+ CreateScopeOauthClientPayload,
54+ CreateSourcePayload,
55+ UpdateSourcePayload,
56+} from "./sources/contracts";
57+import { discoverSource } from "./sources/discovery";
58+import {
59+ discoverSourceInspectionTools,
60+ getSourceInspection,
61+ getSourceInspectionToolDetail,
62+} from "./sources/inspection";
63+import {
64+ createSource,
65+ getSource,
66+ listSources,
67+ removeSource,
68+ updateSource,
69+} from "./sources/operations";
70+import type { ExecutorBackend } from "./backend";
71+import {
72+ provideExecutorRuntime,
73+ type CreateScopeInternalToolMap,
74+ type ExecutorRuntime,
75+ type ExecutorRuntimeOptions,
76+ type ResolveExecutionEnvironment,
77+ type ResolveSecretMaterial,
78+ RuntimeSourceAuthServiceTag,
79+} from "./runtime";
80+import {
81+ createExecution,
82+ getExecution,
83+ resumeExecution,
84+} from "./runtime/execution/service";
85+import type {
86+ CompleteProviderOauthCallbackResult,
87+ CompleteSourceCredentialSetupResult,
88+ CompleteSourceOAuthSessionResult,
89+ ConnectGoogleDiscoveryBatchInput,
90+ ConnectGoogleDiscoveryBatchResult,
91+ ConnectMcpSourceInput,
92+ ExecutorAddSourceInput,
93+ ExecutorSourceAddResult,
94+ McpSourceConnectResult,
95+ StartSourceOAuthSessionInput,
96+ StartSourceOAuthSessionResult,
97+} from "./runtime/sources/source-auth-service";
98+
99+type DistributiveOmit<T, Keys extends PropertyKey> = T extends unknown
100+ ? Omit<T, Keys>
101+ : never;
102+type ProvidedEffect<T extends Effect.Effect<any, any, any>> = Effect.Effect<
103+ Effect.Effect.Success<T>,
104+ Effect.Effect.Error<T>,
105+ never
106+>;
107+type MappedProvidedEffect<
108+ T extends Effect.Effect<any, any, any>,
109+ A,
110+> = Effect.Effect<A, Effect.Effect.Error<T>, never>;
111+
112+export type ExecutorSourceInput = DistributiveOmit<
113+ ExecutorAddSourceInput,
114+ "scopeId" | "actorScopeId" | "executionId" | "interactionId"
115+>;
116+
117+export type ExecutorSourceBatchInput = DistributiveOmit<
118+ ConnectGoogleDiscoveryBatchInput,
119+ "scopeId" | "actorScopeId" | "executionId" | "interactionId"
120+>;
121+
122+export type ExecutorMcpSourceInput = DistributiveOmit<
123+ ConnectMcpSourceInput,
124+ "scopeId" | "actorScopeId"
125+>;
126+
127+export type ExecutorSourceOAuthInput = DistributiveOmit<
128+ StartSourceOAuthSessionInput,
129+ "scopeId" | "actorScopeId"
130+>;
131+
132+export type ExecutorEffect = {
133+ runtime: ExecutorRuntime;
134+ installation: LocalInstallation;
135+ scopeId: ScopeId;
136+ actorScopeId: ScopeId;
137+ resolutionScopeIds: ReadonlyArray<ScopeId>;
138+ close: () => Promise<void>;
139+ local: {
140+ installation: () => ProvidedEffect<ReturnType<typeof getLocalInstallation>>;
141+ config: () => ProvidedEffect<ReturnType<typeof getLocalInstanceConfig>>;
142+ credentials: {
143+ get: (input: {
144+ sourceId: Source["id"];
145+ interactionId: ExecutionInteraction["id"];
146+ }) => ProvidedEffect<ReturnType<typeof getSourceCredentialInteraction>>;
147+ submit: (input: {
148+ sourceId: Source["id"];
149+ interactionId: ExecutionInteraction["id"];
150+ action: "submit" | "continue" | "cancel";
151+ token?: string | null;
152+ }) => ProvidedEffect<
153+ ReturnType<typeof submitSourceCredentialInteraction>
154+ >;
155+ complete: (input: {
156+ sourceId: Source["id"];
157+ state: string;
158+ code?: string | null;
159+ error?: string | null;
160+ errorDescription?: string | null;
161+ }) => MappedProvidedEffect<
162+ ReturnType<typeof completeSourceCredentialSetup>,
163+ CompleteSourceCredentialSetupResult
164+ >;
165+ };
166+ };
167+ secrets: {
168+ list: () => ProvidedEffect<ReturnType<typeof listLocalSecrets>>;
169+ create: (
170+ payload: CreateSecretPayload,
171+ ) => ProvidedEffect<ReturnType<typeof createLocalSecret>>;
172+ update: (input: {
173+ secretId: string;
174+ payload: UpdateSecretPayload;
175+ }) => ProvidedEffect<ReturnType<typeof updateLocalSecret>>;
176+ remove: (
177+ secretId: string,
178+ ) => MappedProvidedEffect<
179+ ReturnType<typeof deleteLocalSecret>,
180+ DeleteSecretResult
181+ >;
182+ };
183+ policies: {
184+ list: () => ProvidedEffect<ReturnType<typeof listPolicies>>;
185+ create: (
186+ payload: CreatePolicyPayload,
187+ ) => ProvidedEffect<ReturnType<typeof createPolicy>>;
188+ get: (policyId: string) => ProvidedEffect<ReturnType<typeof getPolicy>>;
189+ update: (
190+ policyId: string,
191+ payload: UpdatePolicyPayload,
192+ ) => ProvidedEffect<ReturnType<typeof updatePolicy>>;
193+ remove: (
194+ policyId: string,
195+ ) => MappedProvidedEffect<ReturnType<typeof removePolicy>, boolean>;
196+ };
197+ sources: {
198+ add: (
199+ input: ExecutorSourceInput,
200+ options?: {
201+ baseUrl?: string | null;
202+ },
203+ ) => Effect.Effect<ExecutorSourceAddResult, Error, never>;
204+ connect: (
205+ payload: ExecutorMcpSourceInput,
206+ ) => Effect.Effect<McpSourceConnectResult, Error, never>;
207+ connectBatch: (
208+ payload: ExecutorSourceBatchInput,
209+ ) => Effect.Effect<ConnectGoogleDiscoveryBatchResult, Error, never>;
210+ discover: (input: {
211+ url: string;
212+ probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"];
213+ }) => ProvidedEffect<ReturnType<typeof discoverSource>>;
214+ list: () => ProvidedEffect<ReturnType<typeof listSources>>;
215+ create: (
216+ payload: CreateSourcePayload,
217+ ) => ProvidedEffect<ReturnType<typeof createSource>>;
218+ get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSource>>;
219+ update: (
220+ sourceId: Source["id"],
221+ payload: UpdateSourcePayload,
222+ ) => ProvidedEffect<ReturnType<typeof updateSource>>;
223+ remove: (
224+ sourceId: Source["id"],
225+ ) => MappedProvidedEffect<ReturnType<typeof removeSource>, boolean>;
226+ inspection: {
227+ get: (
228+ sourceId: Source["id"],
229+ ) => ProvidedEffect<ReturnType<typeof getSourceInspection>>;
230+ tool: (input: {
231+ sourceId: Source["id"];
232+ toolPath: string;
233+ }) => ProvidedEffect<ReturnType<typeof getSourceInspectionToolDetail>>;
234+ discover: (input: {
235+ sourceId: Source["id"];
236+ payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"];
237+ }) => ProvidedEffect<
238+ ReturnType<typeof discoverSourceInspectionTools>
239+ >;
240+ };
241+ oauthClients: {
242+ list: (
243+ providerKey: string,
244+ ) => Effect.Effect<ReadonlyArray<ScopeOauthClient>, Error, never>;
245+ create: (
246+ payload: CreateScopeOauthClientPayload,
247+ ) => Effect.Effect<ScopeOauthClient, Error, never>;
248+ remove: (
249+ oauthClientId: ScopeOauthClient["id"],
250+ ) => Effect.Effect<boolean, Error, never>;
251+ };
252+ providerGrants: {
253+ remove: (
254+ grantId: ProviderAuthGrant["id"],
255+ ) => Effect.Effect<boolean, Error, never>;
256+ };
257+ };
258+ oauth: {
259+ startSourceAuth: (
260+ input: ExecutorSourceOAuthInput,
261+ ) => Effect.Effect<StartSourceOAuthSessionResult, Error, never>;
262+ completeSourceAuth: (input: {
263+ state: string;
264+ code?: string | null;
265+ error?: string | null;
266+ errorDescription?: string | null;
267+ }) => Effect.Effect<CompleteSourceOAuthSessionResult, Error, never>;
268+ completeProviderCallback: (input: {
269+ scopeId?: ScopeId;
270+ actorScopeId?: ScopeId | null;
271+ state: string;
272+ code?: string | null;
273+ error?: string | null;
274+ errorDescription?: string | null;
275+ }) => Effect.Effect<CompleteProviderOauthCallbackResult, Error, never>;
276+ };
277+ executions: {
278+ create: (
279+ payload: CreateExecutionPayload,
280+ ) => ProvidedEffect<ReturnType<typeof createExecution>>;
281+ get: (
282+ executionId: Execution["id"],
283+ ) => ProvidedEffect<ReturnType<typeof getExecution>>;
284+ resume: (
285+ executionId: Execution["id"],
286+ payload: ResumeExecutionPayload,
287+ ) => ProvidedEffect<ReturnType<typeof resumeExecution>>;
288+ };
289+};
290+
291+export type CreateExecutorEffectOptions = ExecutorRuntimeOptions & {
292+ backend: ExecutorBackend;
293+};
294+
295+const fromRuntime = (runtime: ExecutorRuntime): ExecutorEffect => {
296+ const installation = runtime.localInstallation;
297+ const scopeId = installation.scopeId;
298+ const actorScopeId = installation.actorScopeId;
299+ const provide = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
300+ provideExecutorRuntime(effect, runtime);
301+ const provideSourceAuth = <A, E>(
302+ execute: (
303+ service: Effect.Effect.Success<typeof RuntimeSourceAuthServiceTag>,
304+ ) => Effect.Effect<A, E, any>,
305+ ) => provide(Effect.flatMap(RuntimeSourceAuthServiceTag, execute));
306+ const createSdkSourceSession = () => {
307+ const id = crypto.randomUUID();
308+ return {
309+ executionId: ExecutionIdSchema.make(`exec_sdk_${id}`),
310+ interactionId: `executor.sdk.${id}` as never,
311+ };
312+ };
313+
314+ return {
315+ runtime,
316+ installation,
317+ scopeId,
318+ actorScopeId,
319+ resolutionScopeIds: installation.resolutionScopeIds,
320+ close: () => runtime.close(),
321+ local: {
322+ installation: () => provide(getLocalInstallation()),
323+ config: () => provide(getLocalInstanceConfig()),
324+ credentials: {
325+ get: ({ sourceId, interactionId }) =>
326+ provide(
327+ getSourceCredentialInteraction({
328+ scopeId,
329+ sourceId,
330+ interactionId,
331+ }),
332+ ),
333+ submit: ({ sourceId, interactionId, action, token }) =>
334+ provide(
335+ submitSourceCredentialInteraction({
336+ scopeId,
337+ sourceId,
338+ interactionId,
339+ action,
340+ token,
341+ }),
342+ ),
343+ complete: ({ sourceId, state, code, error, errorDescription }) =>
344+ provide(
345+ completeSourceCredentialSetup({
346+ scopeId,
347+ sourceId,
348+ state,
349+ code,
350+ error,
351+ errorDescription,
352+ }),
353+ ),
354+ },
355+ },
356+ secrets: {
357+ list: () => provide(listLocalSecrets()),
358+ create: (payload) => provide(createLocalSecret(payload)),
359+ update: (input) => provide(updateLocalSecret(input)),
360+ remove: (secretId) => provide(deleteLocalSecret(secretId)),
361+ },
362+ policies: {
363+ list: () => provide(listPolicies(scopeId)),
364+ create: (payload) => provide(createPolicy({ scopeId, payload })),
365+ get: (policyId) =>
366+ provide(getPolicy({ scopeId, policyId: policyId as never })),
367+ update: (policyId, payload) =>
368+ provide(updatePolicy({ scopeId, policyId: policyId as never, payload })),
369+ remove: (policyId) =>
370+ provide(removePolicy({ scopeId, policyId: policyId as never })).pipe(
371+ Effect.map((result) => result.removed),
372+ ),
373+ },
374+ sources: {
375+ add: (input, options) =>
376+ provideSourceAuth((service) => {
377+ const session = createSdkSourceSession();
378+ return service.addExecutorSource(
379+ {
380+ ...input,
381+ scopeId,
382+ actorScopeId,
383+ executionId: session.executionId,
384+ interactionId: session.interactionId,
385+ },
386+ options,
387+ );
388+ }),
389+ connect: (payload) =>
390+ provideSourceAuth((service) =>
391+ service.connectMcpSource({
392+ ...payload,
393+ scopeId,
394+ actorScopeId,
395+ }),
396+ ),
397+ connectBatch: (payload) =>
398+ provideSourceAuth((service) => {
399+ const session = createSdkSourceSession();
400+ return service.connectGoogleDiscoveryBatch({
401+ ...payload,
402+ scopeId,
403+ actorScopeId,
404+ executionId: session.executionId,
405+ interactionId: session.interactionId,
406+ });
407+ }),
408+ discover: (input) => provide(discoverSource(input)),
409+ list: () => provide(listSources({ scopeId, actorScopeId })),
410+ create: (payload) => provide(createSource({ scopeId, actorScopeId, payload })),
411+ get: (sourceId) => provide(getSource({ scopeId, sourceId, actorScopeId })),
412+ update: (sourceId, payload) =>
413+ provide(updateSource({ scopeId, sourceId, actorScopeId, payload })),
414+ remove: (sourceId) =>
415+ provide(removeSource({ scopeId, sourceId })).pipe(
416+ Effect.map((result) => result.removed),
417+ ),
418+ inspection: {
419+ get: (sourceId) => provide(getSourceInspection({ scopeId, sourceId })),
420+ tool: ({ sourceId, toolPath }) =>
421+ provide(
422+ getSourceInspectionToolDetail({
423+ scopeId,
424+ sourceId,
425+ toolPath,
426+ }),
427+ ),
428+ discover: ({ sourceId, payload }) =>
429+ provide(
430+ discoverSourceInspectionTools({
431+ scopeId,
432+ sourceId,
433+ payload,
434+ }),
435+ ),
436+ },
437+ oauthClients: {
438+ list: (providerKey) =>
439+ provideSourceAuth((service) =>
440+ service.listScopeOauthClients({
441+ scopeId,
442+ providerKey,
443+ }),
444+ ),
445+ create: (payload) =>
446+ provideSourceAuth((service) =>
447+ service.createScopeOauthClient({
448+ scopeId,
449+ providerKey: payload.providerKey,
450+ label: payload.label,
451+ oauthClient: payload.oauthClient,
452+ }),
453+ ),
454+ remove: (oauthClientId) =>
455+ provideSourceAuth((service) =>
456+ service.removeScopeOauthClient({
457+ scopeId,
458+ oauthClientId,
459+ }),
460+ ),
461+ },
462+ providerGrants: {
463+ remove: (grantId) =>
464+ provideSourceAuth((service) =>
465+ service.removeProviderAuthGrant({
466+ scopeId,
467+ grantId,
468+ }),
469+ ),
470+ },
471+ },
472+ oauth: {
473+ startSourceAuth: (input) =>
474+ provideSourceAuth((service) =>
475+ service.startSourceOAuthSession({
476+ ...input,
477+ scopeId,
478+ actorScopeId,
479+ }),
480+ ),
481+ completeSourceAuth: ({ state, code, error, errorDescription }) =>
482+ provideSourceAuth((service) =>
483+ service.completeSourceOAuthSession({
484+ state,
485+ code,
486+ error,
487+ errorDescription,
488+ }),
489+ ),
490+ completeProviderCallback: (input) =>
491+ provideSourceAuth((service) =>
492+ service.completeProviderOauthCallback({
493+ ...input,
494+ scopeId: input.scopeId ?? scopeId,
495+ actorScopeId: input.actorScopeId ?? actorScopeId,
496+ }),
497+ ),
498+ },
499+ executions: {
500+ create: (payload) =>
501+ provide(
502+ createExecution({
503+ scopeId,
504+ payload,
505+ createdByScopeId: actorScopeId,
506+ }),
507+ ),
508+ get: (executionId) => provide(getExecution({ scopeId, executionId })),
509+ resume: (executionId, payload) =>
510+ provide(
511+ resumeExecution({
512+ scopeId,
513+ executionId,
514+ payload,
515+ resumedByScopeId: actorScopeId,
516+ }),
517+ ),
518+ },
519+ };
520+};
521+
522+export const createExecutorEffect = (
523+ options: CreateExecutorEffectOptions,
524+): Effect.Effect<ExecutorEffect, Error> =>
525+ Effect.map(
526+ options.backend.createRuntime({
527+ executionResolver: options.executionResolver,
528+ createInternalToolMap: options.createInternalToolMap,
529+ resolveSecretMaterial: options.resolveSecretMaterial,
530+ getLocalServerBaseUrl: options.getLocalServerBaseUrl,
531+ }),
532+ fromRuntime,
533+ );
packages/platform/sdk/src/executor.test.ts+8−4
@@ -30,19 +30,23 @@ import { · 29 unmodified lines
3030
3131 import {
3232 createExecutorBackend,
33− createExecutorEffect,
34− type Executor,
3533 } from "./index";
34+import {
35+ createExecutorEffect,
36+ type ExecutorEffect as Executor,
37+} from "./effect";
3638 import {
3739 type LocalInstallation,
3840 ScopeIdSchema,
3941 } from "./schema";
4042 import {
4143 createLocalExecutorServicesEffect,
42−} from "../../sdk-file/src/index";
44+} from "../../sdk-file/src/effect";
4345 import {
44− ExecutorApi,
4546 createExecutorApiLayer,
47+} from "../../api/src/http";
48+import {
49+ ExecutorApi,
4650 } from "../../api/src/index";
4751
4852 type LocalExecutorServices = Effect.Effect.Success<
packages/platform/sdk/src/executor.ts+70−664
@@ -1,705 +1,111 @@
11 import * as Effect from "effect/Effect";
22
3−import type {
4− ScopeId,
5− Execution,
6− ExecutionEnvelope,
7− ExecutionInteraction,
8− LocalInstallation,
9− LocalScopePolicy,
10− ProviderAuthGrant,
11− Source,
12− ScopeOauthClient,
13−} from "./schema";
143 import {
15− ExecutionIdSchema,
16−} from "./schema";
17−import type {
18− CreateExecutionPayload,
19− ResumeExecutionPayload,
20−} from "./executions/contracts";
21−import type {
22− CreateSecretPayload,
23− CreateSecretResult,
24− DeleteSecretResult,
25− InstanceConfig,
26− SecretListItem,
27− UpdateSecretPayload,
28− UpdateSecretResult,
29−} from "./local/contracts";
30−import {
31− completeSourceCredentialSetup,
32− getLocalInstallation,
33− getSourceCredentialInteraction,
34− submitSourceCredentialInteraction,
35−} from "./local/operations";
36−import {
37− createLocalSecret,
38− deleteLocalSecret,
39− getLocalInstanceConfig,
40− listLocalSecrets,
41− updateLocalSecret,
42−} from "./local/secrets";
43−import type {
44− CreatePolicyPayload,
45− UpdatePolicyPayload,
46−} from "./policies/contracts";
47−import {
48− createPolicy,
49− getPolicy,
50− listPolicies,
51− removePolicy,
52− updatePolicy,
53−} from "./policies/operations";
54−import type {
55− CreateSourcePayload,
56− CreateScopeOauthClientPayload,
57− UpdateSourcePayload,
58−} from "./sources/contracts";
59−import {
60− discoverSource,
61−} from "./sources/discovery";
62−import {
63− discoverSourceInspectionTools,
64− getSourceInspection,
65− getSourceInspectionToolDetail,
66−} from "./sources/inspection";
67−import {
68− createSource,
69− getSource,
70− listSources,
71− removeSource,
72− updateSource,
73−} from "./sources/operations";
74−import type {
75− ExecutorBackend,
76−} from "./backend";
77−import {
78− provideExecutorRuntime,
79− type ExecutorRuntime,
80− type ExecutorRuntimeOptions,
81− type CreateScopeInternalToolMap,
82− type ResolveExecutionEnvironment,
83− type ResolveSecretMaterial,
84− RuntimeSourceAuthServiceTag,
85−} from "./runtime";
86−import {
87− createExecution,
88− getExecution,
89− resumeExecution,
90−} from "./runtime/execution/service";
91−import type {
92− CompleteProviderOauthCallbackResult,
93− CompleteSourceCredentialSetupResult,
94− CompleteSourceOAuthSessionResult,
95− ConnectGoogleDiscoveryBatchInput,
96− ConnectGoogleDiscoveryBatchResult,
97− ConnectMcpSourceInput,
98− ExecutorAddSourceInput,
99− ExecutorSourceAddResult,
100− McpSourceConnectResult,
101− StartSourceOAuthSessionInput,
102− StartSourceOAuthSessionResult,
103−} from "./runtime/sources/source-auth-service";
104−
105−type DistributiveOmit<T, Keys extends PropertyKey> = T extends unknown ? Omit<T, Keys> : never;
106−type ProvidedEffect<T extends Effect.Effect<any, any, any>> = Effect.Effect<
107− Effect.Effect.Success<T>,
108− Effect.Effect.Error<T>,
109− never
110−>;
111−
112−export type ExecutorSourceInput = DistributiveOmit<
113− ExecutorAddSourceInput,
114− "scopeId" | "actorScopeId" | "executionId" | "interactionId"
115−>;
116−
117−export type ExecutorSourceBatchInput = DistributiveOmit<
118− ConnectGoogleDiscoveryBatchInput,
119− "scopeId" | "actorScopeId" | "executionId" | "interactionId"
120−>;
4+ createExecutorEffect,
5+ type CreateExecutorEffectOptions,
6+ type ExecutorEffect,
7+ type ExecutorMcpSourceInput,
8+ type ExecutorSourceBatchInput,
9+ type ExecutorSourceInput,
10+ type ExecutorSourceOAuthInput,
11+} from "./executor-effect";
12112
122−export type ExecutorMcpSourceInput = DistributiveOmit<
123− ConnectMcpSourceInput,
124− "scopeId" | "actorScopeId"
125−>;
126−
127−export type ExecutorSourceOAuthInput = DistributiveOmit<
128− StartSourceOAuthSessionInput,
129− "scopeId" | "actorScopeId"
130−>;
131−
132−export type Executor = {
133− runtime: ExecutorRuntime;
134− installation: LocalInstallation;
135− scopeId: ScopeId;
136− actorScopeId: ScopeId;
137− resolutionScopeIds: ReadonlyArray<ScopeId>;
138− provide: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, any>;
139− run: <A, E, R>(effect: Effect.Effect<A, E, R>) => Promise<A>;
140− close: () => Promise<void>;
141− effect: {
142− local: {
143− installation: () => ProvidedEffect<ReturnType<typeof getLocalInstallation>>;
144− config: () => ProvidedEffect<ReturnType<typeof getLocalInstanceConfig>>;
145− credentials: {
146− get: (input: {
147− sourceId: Source["id"];
148− interactionId: ExecutionInteraction["id"];
149− }) => ProvidedEffect<ReturnType<typeof getSourceCredentialInteraction>>;
150− submit: (input: {
151− sourceId: Source["id"];
152− interactionId: ExecutionInteraction["id"];
153− action: "submit" | "continue" | "cancel";
154− token?: string | null;
155− }) => ProvidedEffect<ReturnType<typeof submitSourceCredentialInteraction>>;
156− complete: (input: {
157− sourceId: Source["id"];
158− state: string;
159− code?: string | null;
160− error?: string | null;
161− errorDescription?: string | null;
162− }) => ProvidedEffect<ReturnType<typeof completeSourceCredentialSetup>>;
163− };
164− };
165− secrets: {
166− list: () => ProvidedEffect<ReturnType<typeof listLocalSecrets>>;
167− create: (payload: CreateSecretPayload) => ProvidedEffect<ReturnType<typeof createLocalSecret>>;
168− update: (input: {
169− secretId: string;
170− payload: UpdateSecretPayload;
171− }) => ProvidedEffect<ReturnType<typeof updateLocalSecret>>;
172− remove: (secretId: string) => ProvidedEffect<ReturnType<typeof deleteLocalSecret>>;
173− };
174− policies: {
175− list: () => ProvidedEffect<ReturnType<typeof listPolicies>>;
176− create: (payload: CreatePolicyPayload) => ProvidedEffect<ReturnType<typeof createPolicy>>;
177− get: (policyId: string) => ProvidedEffect<ReturnType<typeof getPolicy>>;
178− update: (
179− policyId: string,
180− payload: UpdatePolicyPayload,
181− ) => ProvidedEffect<ReturnType<typeof updatePolicy>>;
182− remove: (policyId: string) => ProvidedEffect<ReturnType<typeof removePolicy>>;
183− };
184− sources: {
185− add: (
186− input: ExecutorSourceInput,
187− options?: {
188− baseUrl?: string | null;
189− },
190− ) => Effect.Effect<ExecutorSourceAddResult, Error, never>;
191− connect: (payload: ExecutorMcpSourceInput) => Effect.Effect<McpSourceConnectResult, Error, never>;
192− connectBatch: (
193− payload: ExecutorSourceBatchInput,
194− ) => Effect.Effect<ConnectGoogleDiscoveryBatchResult, Error, never>;
195− discover: (input: {
196− url: string;
197− probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"];
198− }) => ProvidedEffect<ReturnType<typeof discoverSource>>;
199− list: () => ProvidedEffect<ReturnType<typeof listSources>>;
200− create: (payload: CreateSourcePayload) => ProvidedEffect<ReturnType<typeof createSource>>;
201− get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSource>>;
202− update: (
203− sourceId: Source["id"],
204− payload: UpdateSourcePayload,
205− ) => ProvidedEffect<ReturnType<typeof updateSource>>;
206− remove: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof removeSource>>;
207− inspection: {
208− get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSourceInspection>>;
209− tool: (input: {
210− sourceId: Source["id"];
211− toolPath: string;
212− }) => ProvidedEffect<ReturnType<typeof getSourceInspectionToolDetail>>;
213− discover: (input: {
214− sourceId: Source["id"];
215− payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"];
216− }) => ProvidedEffect<ReturnType<typeof discoverSourceInspectionTools>>;
217− };
218− oauthClients: {
219− list: (
220− providerKey: string,
221− ) => Effect.Effect<ReadonlyArray<ScopeOauthClient>, Error, never>;
222− create: (
223− payload: CreateScopeOauthClientPayload,
224− ) => Effect.Effect<ScopeOauthClient, Error, never>;
225− remove: (
226− oauthClientId: ScopeOauthClient["id"],
227− ) => Effect.Effect<boolean, Error, never>;
228− };
229− providerGrants: {
230− remove: (grantId: ProviderAuthGrant["id"]) => Effect.Effect<boolean, Error, never>;
231− };
232− };
233− oauth: {
234− startSourceAuth: (
235− input: ExecutorSourceOAuthInput,
236− ) => Effect.Effect<StartSourceOAuthSessionResult, Error, never>;
237− completeSourceAuth: (input: {
238− state: string;
239− code?: string | null;
240− error?: string | null;
241− errorDescription?: string | null;
242− }) => Effect.Effect<CompleteSourceOAuthSessionResult, Error, never>;
243− completeProviderCallback: (input: {
244− scopeId?: ScopeId;
245− actorScopeId?: ScopeId | null;
246− state: string;
247− code?: string | null;
248− error?: string | null;
249− errorDescription?: string | null;
250− }) => Effect.Effect<CompleteProviderOauthCallbackResult, Error, never>;
251− };
252− executions: {
253− create: (payload: CreateExecutionPayload) => ProvidedEffect<ReturnType<typeof createExecution>>;
254− get: (executionId: Execution["id"]) => ProvidedEffect<ReturnType<typeof getExecution>>;
255− resume: (
256− executionId: Execution["id"],
257− payload: ResumeExecutionPayload,
258− ) => ProvidedEffect<ReturnType<typeof resumeExecution>>;
259− };
260− };
261− local: {
262− installation: () => Promise<LocalInstallation>;
263− config: () => Promise<InstanceConfig>;
264− credentials: {
265− get: (input: {
266− sourceId: Source["id"];
267− interactionId: ExecutionInteraction["id"];
268− }) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceCredentialInteraction>>>;
269− submit: (input: {
270− sourceId: Source["id"];
271− interactionId: ExecutionInteraction["id"];
272− action: "submit" | "continue" | "cancel";
273− token?: string | null;
274− }) => Promise<Effect.Effect.Success<ReturnType<typeof submitSourceCredentialInteraction>>>;
275− complete: (input: {
276− sourceId: Source["id"];
277− state: string;
278− code?: string | null;
279− error?: string | null;
280− errorDescription?: string | null;
281− }) => Promise<CompleteSourceCredentialSetupResult>;
282− };
283− };
284− secrets: {
285− list: () => Promise<ReadonlyArray<SecretListItem>>;
286− create: (payload: CreateSecretPayload) => Promise<CreateSecretResult>;
287− update: (input: {
288− secretId: string;
289− payload: UpdateSecretPayload;
290− }) => Promise<UpdateSecretResult>;
291− remove: (secretId: string) => Promise<DeleteSecretResult>;
292− };
293− policies: {
294− list: () => Promise<ReadonlyArray<LocalScopePolicy>>;
295− create: (payload: CreatePolicyPayload) => Promise<LocalScopePolicy>;
296− get: (policyId: string) => Promise<LocalScopePolicy>;
297− update: (
298− policyId: string,
299− payload: UpdatePolicyPayload,
300− ) => Promise<LocalScopePolicy>;
301− remove: (policyId: string) => Promise<boolean>;
302− };
303− sources: {
304− add: (
305− input: ExecutorSourceInput,
306− options?: {
307− baseUrl?: string | null;
308− },
309− ) => Promise<ExecutorSourceAddResult>;
310− connect: (payload: ExecutorMcpSourceInput) => Promise<McpSourceConnectResult>;
311− connectBatch: (payload: ExecutorSourceBatchInput) => Promise<ConnectGoogleDiscoveryBatchResult>;
312− discover: (input: {
313− url: string;
314− probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"];
315− }) => Promise<Effect.Effect.Success<ReturnType<typeof discoverSource>>>;
316− list: () => Promise<ReadonlyArray<Source>>;
317− create: (payload: CreateSourcePayload) => Promise<Source>;
318− get: (sourceId: Source["id"]) => Promise<Source>;
319− update: (sourceId: Source["id"], payload: UpdateSourcePayload) => Promise<Source>;
320− remove: (sourceId: Source["id"]) => Promise<boolean>;
321− inspection: {
322− get: (sourceId: Source["id"]) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceInspection>>>;
323− tool: (input: {
324− sourceId: Source["id"];
325− toolPath: string;
326− }) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceInspectionToolDetail>>>;
327− discover: (input: {
328− sourceId: Source["id"];
329− payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"];
330− }) => Promise<Effect.Effect.Success<ReturnType<typeof discoverSourceInspectionTools>>>;
331− };
332− oauthClients: {
333− list: (providerKey: string) => Promise<ReadonlyArray<ScopeOauthClient>>;
334− create: (
335− payload: CreateScopeOauthClientPayload,
336− ) => Promise<ScopeOauthClient>;
337− remove: (oauthClientId: ScopeOauthClient["id"]) => Promise<boolean>;
338− };
339− providerGrants: {
340− remove: (grantId: ProviderAuthGrant["id"]) => Promise<boolean>;
341− };
342− };
343− oauth: {
344− startSourceAuth: (input: ExecutorSourceOAuthInput) => Promise<StartSourceOAuthSessionResult>;
345− completeSourceAuth: (input: {
346− state: string;
347− code?: string | null;
348− error?: string | null;
349− errorDescription?: string | null;
350− }) => Promise<CompleteSourceOAuthSessionResult>;
351− completeProviderCallback: (input: {
352− scopeId?: ScopeId;
353− actorScopeId?: ScopeId | null;
354− state: string;
355− code?: string | null;
356− error?: string | null;
357− errorDescription?: string | null;
358− }) => Promise<CompleteProviderOauthCallbackResult>;
359− };
360− executions: {
361− create: (payload: CreateExecutionPayload) => Promise<ExecutionEnvelope>;
362− get: (executionId: Execution["id"]) => Promise<ExecutionEnvelope>;
363− resume: (
364− executionId: Execution["id"],
365− payload: ResumeExecutionPayload,
366− ) => Promise<ExecutionEnvelope>;
367− };
368−};
13+type Promiseify<T> = T extends Effect.Effect<infer A, any, any>
14+ ? Promise<A>
15+ : T extends (...args: infer Args) => infer Result
16+ ? (...args: Args) => Promiseify<Result>
17+ : T extends Promise<infer A>
18+ ? Promise<A>
19+ : T extends object
20+ ? { [Key in keyof T]: Promiseify<T[Key]> }
21+ : T;
36922
370−export type CreateExecutorOptions = ExecutorRuntimeOptions & {
371− backend: ExecutorBackend;
23+export type Executor = Omit<Promiseify<ExecutorEffect>, "runtime">;
24+export type CreateExecutorOptions = CreateExecutorEffectOptions;
25+export type {
26+ ExecutorMcpSourceInput,
27+ ExecutorSourceBatchInput,
28+ ExecutorSourceInput,
29+ ExecutorSourceOAuthInput,
37230 };
37331
374−const fromRuntime = (runtime: ExecutorRuntime): Executor => {
375− const installation = runtime.localInstallation;
376− const scopeId = installation.scopeId;
377− const actorScopeId = installation.actorScopeId;
378− const provide = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
379− provideExecutorRuntime(effect, runtime);
380− const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
381− Effect.runPromise(provide(effect) as Effect.Effect<A, E, never>);
382− const provideSourceAuth = <A, E>(
383− execute: (
384− service: Effect.Effect.Success<typeof RuntimeSourceAuthServiceTag>,
385− ) => Effect.Effect<A, E, any>,
386− ) => provide(Effect.flatMap(RuntimeSourceAuthServiceTag, execute));
387− const createSdkSourceSession = () => {
388− const id = crypto.randomUUID();
389− return {
390− executionId: ExecutionIdSchema.make(`exec_sdk_${id}`),
391− interactionId: `executor.sdk.${id}` as never,
392− };
393− };
394− const effect = {
395− local: {
396− installation: () => provide(getLocalInstallation()),
397− config: () => provide(getLocalInstanceConfig()),
398− credentials: {
399− get: ({ sourceId, interactionId }) =>
400− provide(
401− getSourceCredentialInteraction({
402− scopeId,
403− sourceId,
404− interactionId,
405− }),
406− ),
407− submit: ({ sourceId, interactionId, action, token }) =>
408− provide(
409− submitSourceCredentialInteraction({
410− scopeId,
411− sourceId,
412− interactionId,
413− action,
414− token,
415− }),
416− ),
417− complete: ({ sourceId, state, code, error, errorDescription }) =>
418− provide(
419− completeSourceCredentialSetup({
420− scopeId,
421− sourceId,
422− state,
423− code,
424− error,
425− errorDescription,
426− }),
427− ),
428− },
429− },
430− secrets: {
431− list: () => provide(listLocalSecrets()),
432− create: (payload: CreateSecretPayload) => provide(createLocalSecret(payload)),
433− update: (input: { secretId: string; payload: UpdateSecretPayload }) =>
434− provide(updateLocalSecret(input)),
435− remove: (secretId: string) => provide(deleteLocalSecret(secretId)),
436− },
437− policies: {
438− list: () => provide(listPolicies(scopeId)),
439− create: (payload: CreatePolicyPayload) =>
440− provide(createPolicy({ scopeId, payload })),
441− get: (policyId: string) =>
442− provide(getPolicy({ scopeId, policyId: policyId as never })),
443− update: (policyId: string, payload: UpdatePolicyPayload) =>
444− provide(updatePolicy({ scopeId, policyId: policyId as never, payload })),
445− remove: (policyId: string) =>
446− provide(removePolicy({ scopeId, policyId: policyId as never })),
447− },
448− sources: {
449− add: (input: ExecutorSourceInput, options?: { baseUrl?: string | null }) =>
450− provideSourceAuth((service) => {
451− const session = createSdkSourceSession();
452− return service.addExecutorSource(
453− {
454− ...input,
455− scopeId,
456− actorScopeId: actorScopeId,
457− executionId: session.executionId,
458− interactionId: session.interactionId,
459− },
460− options,
461− );
462− }),
463− connect: (payload: ExecutorMcpSourceInput) =>
464− provideSourceAuth((service) =>
465− service.connectMcpSource({
466− ...payload,
467− scopeId,
468− actorScopeId: actorScopeId,
469− }),
470− ),
471− connectBatch: (payload: ExecutorSourceBatchInput) =>
472− provideSourceAuth((service) => {
473− const session = createSdkSourceSession();
474− return service.connectGoogleDiscoveryBatch({
475− ...payload,
476− scopeId,
477− actorScopeId: actorScopeId,
478− executionId: session.executionId,
479− interactionId: session.interactionId,
480− });
481− }),
482− discover: (input: {
483− url: string;
484− probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"];
485− }) => provide(discoverSource(input)),
486− list: () => provide(listSources({ scopeId, actorScopeId })),
487− create: (payload: CreateSourcePayload) =>
488− provide(createSource({ scopeId, actorScopeId, payload })),
489− get: (sourceId: Source["id"]) =>
490− provide(getSource({ scopeId, sourceId, actorScopeId })),
491− update: (sourceId: Source["id"], payload: UpdateSourcePayload) =>
492− provide(updateSource({ scopeId, sourceId, actorScopeId, payload })),
493− remove: (sourceId: Source["id"]) =>
494− provide(removeSource({ scopeId, sourceId })),
495− inspection: {
496− get: (sourceId: Source["id"]) =>
497− provide(getSourceInspection({ scopeId, sourceId })),
498− tool: ({ sourceId, toolPath }: { sourceId: Source["id"]; toolPath: string }) =>
499− provide(
500− getSourceInspectionToolDetail({
501− scopeId,
502− sourceId,
503− toolPath,
504− }),
505− ),
506− discover: ({
507− sourceId,
508− payload,
509− }: {
510− sourceId: Source["id"];
511− payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"];
512− }) =>
513− provide(
514− discoverSourceInspectionTools({
515− scopeId,
516− sourceId,
517− payload,
518− }),
519− ),
520− },
521− oauthClients: {
522− list: (providerKey: string) =>
523− provideSourceAuth((service) =>
524− service.listScopeOauthClients({
525− scopeId,
526− providerKey,
527− }),
528− ),
529− create: (payload: CreateScopeOauthClientPayload) =>
530− provideSourceAuth((service) =>
531− service.createScopeOauthClient({
532− scopeId,
533− providerKey: payload.providerKey,
534− label: payload.label,
535− oauthClient: payload.oauthClient,
536− }),
537− ),
538− remove: (oauthClientId: ScopeOauthClient["id"]) =>
539− provideSourceAuth((service) =>
540− service.removeScopeOauthClient({
541− scopeId,
542− oauthClientId,
543− }),
544− ),
545− },
546− providerGrants: {
547− remove: (grantId: ProviderAuthGrant["id"]) =>
548− provideSourceAuth((service) =>
549− service.removeProviderAuthGrant({
550− scopeId,
551− grantId,
552− }),
553− ),
554− },
555− },
556− oauth: {
557− startSourceAuth: (input: ExecutorSourceOAuthInput) =>
558− provideSourceAuth((service) =>
559− service.startSourceOAuthSession({
560− ...input,
561− scopeId,
562− actorScopeId: actorScopeId,
563− }),
564− ),
565− completeSourceAuth: ({ state, code, error, errorDescription }) =>
566− provideSourceAuth((service) =>
567− service.completeSourceOAuthSession({
568− state,
569− code,
570− error,
571− errorDescription,
572− }),
573− ),
574− completeProviderCallback: (input) =>
575− provideSourceAuth((service) =>
576− service.completeProviderOauthCallback({
577− ...input,
578− scopeId: input.scopeId ?? scopeId,
579− actorScopeId: input.actorScopeId ?? actorScopeId,
580− }),
581− ),
582− },
583− executions: {
584− create: (payload: CreateExecutionPayload) =>
585− provide(
586− createExecution({
587− scopeId,
588− payload,
589− createdByScopeId: actorScopeId,
590− }),
591− ),
592− get: (executionId: Execution["id"]) =>
593− provide(getExecution({ scopeId, executionId })),
594− resume: (executionId: Execution["id"], payload: ResumeExecutionPayload) =>
595− provide(
596− resumeExecution({
597− scopeId,
598− executionId,
599− payload,
600− resumedByScopeId: actorScopeId,
601− }),
602− ),
603− },
604− } satisfies Executor["effect"];
32+const toPromiseExecutor = (executor: ExecutorEffect): Executor => {
33+ const run = <A, E>(effect: Effect.Effect<A, E, never>) =>
34+ Effect.runPromise(effect);
60535
60636 return {
607− runtime,
608− installation,
609− scopeId,
610− actorScopeId,
611− resolutionScopeIds: installation.resolutionScopeIds,
612− provide,
613− run,
614− close: () => runtime.close(),
615− effect,
37+ installation: executor.installation,
38+ scopeId: executor.scopeId,
39+ actorScopeId: executor.actorScopeId,
40+ resolutionScopeIds: executor.resolutionScopeIds,
41+ close: () => executor.close(),
61642 local: {
617− installation: () => run(effect.local.installation()),
618− config: () => run(effect.local.config()),
43+ installation: () => run(executor.local.installation()),
44+ config: () => run(executor.local.config()),
61945 credentials: {
620− get: ({ sourceId, interactionId }) =>
621− run(effect.local.credentials.get({ sourceId, interactionId })),
622− submit: ({ sourceId, interactionId, action, token }) =>
623− run(effect.local.credentials.submit({ sourceId, interactionId, action, token })),
624− complete: ({ sourceId, state, code, error, errorDescription }) =>
625− run(effect.local.credentials.complete({ sourceId, state, code, error, errorDescription })),
46+ get: (input) => run(executor.local.credentials.get(input)),
47+ submit: (input) => run(executor.local.credentials.submit(input)),
48+ complete: (input) => run(executor.local.credentials.complete(input)),
62649 },
62750 },
62851 secrets: {
629− list: () => run(effect.secrets.list()),
630− create: (payload) => run(effect.secrets.create(payload)),
631− update: (input) => run(effect.secrets.update(input)),
632− remove: (secretId) => run(effect.secrets.remove(secretId)),
52+ list: () => run(executor.secrets.list()),
53+ create: (payload) => run(executor.secrets.create(payload)),
54+ update: (input) => run(executor.secrets.update(input)),
55+ remove: (secretId) => run(executor.secrets.remove(secretId)),
63356 },
63457 policies: {
635− list: () => run(effect.policies.list()),
636− create: (payload) => run(effect.policies.create(payload)),
637− get: (policyId) => run(effect.policies.get(policyId)),
58+ list: () => run(executor.policies.list()),
59+ create: (payload) => run(executor.policies.create(payload)),
60+ get: (policyId) => run(executor.policies.get(policyId)),
63861 update: (policyId, payload) =>
639− run(effect.policies.update(policyId, payload)),
640− remove: async (policyId) =>
641− (await run(effect.policies.remove(policyId))).removed,
62+ run(executor.policies.update(policyId, payload)),
63+ remove: (policyId) => run(executor.policies.remove(policyId)),
64264 },
64365 sources: {
644− add: (input, options) => run(effect.sources.add(input, options)),
645− connect: (payload) => run(effect.sources.connect(payload)),
646− connectBatch: (payload) => run(effect.sources.connectBatch(payload)),
647− discover: (input) => run(effect.sources.discover(input)),
648− list: () => run(effect.sources.list()),
649− create: (payload) => run(effect.sources.create(payload)),
650− get: (sourceId) => run(effect.sources.get(sourceId)),
66+ add: (input, options) => run(executor.sources.add(input, options)),
67+ connect: (payload) => run(executor.sources.connect(payload)),
68+ connectBatch: (payload) => run(executor.sources.connectBatch(payload)),
69+ discover: (input) => run(executor.sources.discover(input)),
70+ list: () => run(executor.sources.list()),
71+ create: (payload) => run(executor.sources.create(payload)),
72+ get: (sourceId) => run(executor.sources.get(sourceId)),
65173 update: (sourceId, payload) =>
652− run(effect.sources.update(sourceId, payload)),
653− remove: async (sourceId) =>
654− (await run(effect.sources.remove(sourceId))).removed,
74+ run(executor.sources.update(sourceId, payload)),
75+ remove: (sourceId) => run(executor.sources.remove(sourceId)),
65576 inspection: {
656− get: (sourceId) => run(effect.sources.inspection.get(sourceId)),
657− tool: ({ sourceId, toolPath }) =>
658− run(effect.sources.inspection.tool({ sourceId, toolPath })),
659− discover: ({ sourceId, payload }) =>
660− run(effect.sources.inspection.discover({ sourceId, payload })),
77+ get: (sourceId) => run(executor.sources.inspection.get(sourceId)),
78+ tool: (input) => run(executor.sources.inspection.tool(input)),
79+ discover: (input) => run(executor.sources.inspection.discover(input)),
66180 },
66281 oauthClients: {
66382 list: (providerKey) =>
664− run(effect.sources.oauthClients.list(providerKey)),
665− create: (payload) => run(effect.sources.oauthClients.create(payload)),
83+ run(executor.sources.oauthClients.list(providerKey)),
84+ create: (payload) => run(executor.sources.oauthClients.create(payload)),
66685 remove: (oauthClientId) =>
667− run(effect.sources.oauthClients.remove(oauthClientId)),
86+ run(executor.sources.oauthClients.remove(oauthClientId)),
66887 },
66988 providerGrants: {
67089 remove: (grantId) =>
671− run(effect.sources.providerGrants.remove(grantId)),
90+ run(executor.sources.providerGrants.remove(grantId)),
67291 },
67392 },
67493 oauth: {
675− startSourceAuth: (input) => run(effect.oauth.startSourceAuth(input)),
676− completeSourceAuth: ({ state, code, error, errorDescription }) =>
677− run(effect.oauth.completeSourceAuth({ state, code, error, errorDescription })),
94+ startSourceAuth: (input) => run(executor.oauth.startSourceAuth(input)),
95+ completeSourceAuth: (input) =>
96+ run(executor.oauth.completeSourceAuth(input)),
67897 completeProviderCallback: (input) =>
679− run(effect.oauth.completeProviderCallback(input)),
98+ run(executor.oauth.completeProviderCallback(input)),
68099 },
681100 executions: {
682− create: (payload) => run(effect.executions.create(payload)),
683− get: (executionId) => run(effect.executions.get(executionId)),
101+ create: (payload) => run(executor.executions.create(payload)),
102+ get: (executionId) => run(executor.executions.get(executionId)),
684103 resume: (executionId, payload) =>
685− run(effect.executions.resume(executionId, payload)),
104+ run(executor.executions.resume(executionId, payload)),
686105 },
687106 };
688107 };
689108
690−export const createExecutorEffect = (
691− options: CreateExecutorOptions,
692−): Effect.Effect<Executor, Error> =>
693− Effect.map(
694− options.backend.createRuntime({
695− executionResolver: options.executionResolver,
696− createInternalToolMap: options.createInternalToolMap,
697− resolveSecretMaterial: options.resolveSecretMaterial,
698− getLocalServerBaseUrl: options.getLocalServerBaseUrl,
699− }),
700− fromRuntime,
701− );
702−
703109 export const createExecutor = async (
704110 options: CreateExecutorOptions,
705−): Promise<Executor> => Effect.runPromise(createExecutorEffect(options));
111+): Promise<Executor> => toPromiseExecutor(await Effect.runPromise(createExecutorEffect(options)));
packages/platform/sdk/src/runtime/execution/http.test.ts+3−3
@@ -27,7 +27,7 @@ import { · 26 unmodified lines
2727
2828 import {
2929 createLocalExecutorRuntime as createExecutorRuntime,
30−} from "../../../../sdk-file/src/index";
30+} from "../../../../sdk-file/src/runtime";
3131 import {
3232 withExecutorApiClient,
3333 } from "./test-http-client";
@@ -100,7 +100,7 @@ describe("execution-http", () => { · 66 unmodified lines
100100 (client) =>
101101 client.executions.create({
102102 path: {
103− scopeId: installation.scopeId,
103+ workspaceId: installation.scopeId,
104104 },
105105 payload: {
106106 code: "return await tools.math.add({ a: 20, b: 22 });",
@@ -120,7 +120,7 @@ describe("execution-http", () => { · 13 unmodified lines
120120 (client) =>
121121 client.executions.get({
122122 path: {
123− scopeId: installation.scopeId,
123+ workspaceId: installation.scopeId,
124124 executionId: createExecution.execution.id,
125125 },
126126 }),
packages/platform/sdk/src/runtime/execution/mcp-resume.test.ts+3−3
@@ -58,7 +58,7 @@ import { · 57 unmodified lines
5858 } from "../index";
5959 import {
6060 createLocalExecutorRuntime as createExecutorRuntime,
61−} from "../../../../sdk-file/src/index";
61+} from "../../../../sdk-file/src/runtime";
6262 import {
6363 withExecutorApiClient,
6464 } from "./test-http-client";
@@ -353,7 +353,7 @@ describe("execution-mcp-resume", () => { · 288 unmodified lines
353353 (client) =>
354354 client.executions.create({
355355 path: {
356− scopeId: installation.scopeId,
356+ workspaceId: installation.scopeId,
357357 },
358358 payload: {
359359 code: 'return await tools.source.form.gated_echo({ value: "from-control-plane" });',
@@ -387,7 +387,7 @@ describe("execution-mcp-resume", () => { · 27 unmodified lines
387387 (client) =>
388388 client.executions.resume({
389389 path: {
390− scopeId: installation.scopeId,
390+ workspaceId: installation.scopeId,
391391 executionId: created.execution.id,
392392 },
393393 payload: {
packages/platform/sdk/src/runtime/execution/runtime-config.test.ts+4−4
@@ -19,7 +19,7 @@ import * as Effect from "effect/Effect"; · 18 unmodified lines
1919
2020 import {
2121 createLocalExecutorRuntime as createExecutorRuntime,
22−} from "../../../../sdk-file/src/index";
22+} from "../../../../sdk-file/src/runtime";
2323 import {
2424 withExecutorApiClient,
2525 } from "./test-http-client";
@@ -74,7 +74,7 @@ describe("execution runtime config", () => { · 48 unmodified lines
7474 (client) =>
7575 client.executions.create({
7676 path: {
77− scopeId: installation.scopeId,
77+ workspaceId: installation.scopeId,
7878 },
7979 payload: {
8080 code: 'await fetch("https://example.com"); return 1;',
@@ -106,7 +106,7 @@ describe("execution runtime config", () => { · 25 unmodified lines
106106 (client) =>
107107 client.executions.create({
108108 path: {
109− scopeId: installation.scopeId,
109+ workspaceId: installation.scopeId,
110110 },
111111 payload: {
112112 code: 'await fetch("https://example.com"); return 1;',
@@ -138,7 +138,7 @@ describe("execution runtime config", () => { · 25 unmodified lines
138138 (client) =>
139139 client.executions.create({
140140 path: {
141− scopeId: installation.scopeId,
141+ workspaceId: installation.scopeId,
142142 },
143143 payload: {
144144 code: 'return typeof Deno !== "undefined";',
packages/platform/sdk/src/runtime/execution/test-http-client.ts+5−1
@@ -8,13 +8,17 @@ import { · 7 unmodified lines
88 } from "@effect/platform-node";
99 import {
1010 ExecutorApi,
11− createExecutorApiLayer,
1211 } from "../../../../api/src/index";
12+import {
13+ createExecutorApiLayer,
14+} from "../../../../api/src/http";
1315 import * as Effect from "effect/Effect";
1416 import * as Layer from "effect/Layer";
1517
1618 import {
1719 createExecutorEffect,
20+} from "../../effect";
21+import {
1822 type ExecutorRuntime,
1923 } from "../../index";
2024
packages/platform/sdk/src/runtime/executor-runtime.test.ts+4−2
@@ -81,7 +81,6 @@ import { · 80 unmodified lines
8181 } from "./effect-errors";
8282 import {
8383 buildLocalSourceArtifact,
84− createLocalExecutorRuntime as createExecutorRuntime,
8584 deriveLocalInstallation,
8685 readLocalSourceArtifact,
8786 resolveLocalWorkspaceContext,
@@ -89,7 +88,10 @@ import { · 1 unmodified line
8988 writeLocalSourceArtifact,
9089 writeProjectLocalExecutorConfig,
9190 writeLocalWorkspaceState,
92−} from "../../../sdk-file/src/index";
91+} from "../../../sdk-file/src/effect";
92+import {
93+ createLocalExecutorRuntime as createExecutorRuntime,
94+} from "../../../sdk-file/src/runtime";
9395 import {
9496 decodeSourceCredentialInteraction,
9597 submitSourceCredentialInteraction,
packages/platform/server/src/index.ts+3−3
@@ -10,13 +10,13 @@ import { FileSystem, HttpApiBuilder, HttpServer } from "@effect/platform"; · 9 unmodified lines
1010 import { NodeFileSystem } from "@effect/platform-node";
1111 import {
1212 createExecutorApiLayer,
13−} from "@executor/platform-api";
13+} from "@executor/platform-api/http";
1414 import { createExecutorMcpRequestHandler } from "@executor/executor-mcp";
1515 import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal";
1616 import {
1717 createExecutorEffect,
18− type Executor,
19−} from "@executor/platform-sdk";
18+ type ExecutorEffect as Executor,
19+} from "@executor/platform-sdk/effect";
2020 import { createLocalExecutorBackend } from "@executor/platform-sdk-file";
2121 import {
2222 type ResolveExecutionEnvironment,