History

Merge pull request #284 from RhysSullivan/worktree-publish-execution-cli

feat(release): publish execution, cli, and kernel packages to npm

Rhys Sullivan committed 6 months ago

Commit 599ae332 parents 96dc18a 905973b35 files · +772 −66Browse files

Unified · Split

35 files
  1. .changeset/config.json +17 −12
  2. apps/cli/src/main.ts +4 −1
  3. apps/cloud/package.json +1 −0
  4. apps/cloud/src/mcp-session.e2e.node.test.ts +2 −1
  5. apps/cloud/src/services/__test-harness__/api-harness.ts +2 −1
  6. apps/local/package.json +1 −0
  7. apps/local/src/server/main.ts +2 −1
  8. bun.lock +27 −9
  9. package.json +1 −1
  10. packages/core/cli/README.md +57 −0
  11. packages/core/cli/package.json +24 −3
  12. packages/core/cli/src/commands/generate.ts +1 −1
  13. packages/core/cli/src/generators/types.ts +1 −1
  14. packages/core/cli/src/utils/get-config.ts +1 −1
  15. packages/core/cli/tsup.config.ts +17 −0
  16. packages/core/execution/README.md +94 −0
  17. packages/core/execution/package.json +37 −4
  18. packages/core/execution/src/engine.ts +2 −4
  19. packages/core/execution/src/promise.ts +120 −0
  20. packages/core/execution/src/tool-invoker.test.ts +9 −6
  21. packages/core/execution/tsconfig.json +5 −1
  22. packages/core/execution/tsup.config.ts +13 −0
  23. packages/core/sdk/package.json +1 −0
  24. packages/core/storage-core/README.md +64 −0
  25. packages/core/storage-core/package.json +54 −5
  26. packages/core/storage-core/tsup.config.ts +14 −0
  27. packages/kernel/core/README.md +40 −0
  28. packages/kernel/core/package.json +28 −2
  29. packages/kernel/core/tsconfig.json +5 −1
  30. packages/kernel/core/tsup.config.ts +12 −0
  31. packages/kernel/runtime-quickjs/README.md +60 −0
  32. packages/kernel/runtime-quickjs/package.json +28 −2
  33. packages/kernel/runtime-quickjs/tsconfig.json +5 −1
  34. packages/kernel/runtime-quickjs/tsup.config.ts +12 −0
  35. scripts/publish-packages.ts +11 −8
.changeset/config.json+17−12
@@ -2,20 +2,33 @@ · 1 unmodified line
22 "$schema": "https://unpkg.com/@changesets/config@3.1.3/schema.json",
33 "changelog": false,
44 "commit": false,
5− "fixed": [],
5+ "fixed": [
6+ [
7+ "@executor/sdk",
8+ "@executor/storage-core",
9+ "@executor/codemode-core",
10+ "@executor/runtime-quickjs",
11+ "@executor/execution",
12+ "@executor/cli",
13+ "@executor/plugin-file-secrets",
14+ "@executor/plugin-google-discovery",
15+ "@executor/plugin-graphql",
16+ "@executor/plugin-keychain",
17+ "@executor/plugin-mcp",
18+ "@executor/plugin-onepassword",
19+ "@executor/plugin-openapi"
20+ ]
21+ ],
622 "linked": [],
723 "access": "public",
824 "baseBranch": "main",
925 "updateInternalDependencies": "patch",
1026 "ignore": [
1127 "@executor/local",
12− "@executor/execution",
1328 "@executor/storage-file",
1429 "@executor/host-mcp",
15− "@executor/codemode-core",
1630 "@executor/ir",
1731 "@executor/runtime-deno-subprocess",
18− "@executor/runtime-quickjs",
1932 "@executor/marketing",
2033 "@executor/runtime-dynamic-worker",
2134 "@executor/runtime-secure-exec",
@@ -23,14 +36,6 @@ · 1 unmodified line
2336 "@executor/api",
2437 "@executor/config",
2538 "@executor/storage-postgres",
26− "@executor/sdk",
27− "@executor/plugin-file-secrets",
28− "@executor/plugin-google-discovery",
29− "@executor/plugin-graphql",
30− "@executor/plugin-keychain",
31− "@executor/plugin-mcp",
32− "@executor/plugin-onepassword",
33− "@executor/plugin-openapi",
3439 "@executor/plugin-workos-vault",
3540 "@executor/example-promise-sdk"
3641 ]
apps/cli/src/main.ts+4−1
@@ -41,6 +41,7 @@ import * as Cause from "effect/Cause"; · 40 unmodified lines
4141
4242 import { ExecutorApi } from "@executor/api";
4343 import { startServer, runMcpStdioServer, getExecutor } from "@executor/local";
44+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
4445
4546 // Embedded web UI — baked into compiled binaries via `with { type: "file" }`
4647 import embeddedWebUI from "./embedded-web-ui.gen";
@@ -154,7 +155,9 @@ const runForegroundSession = (input: { · 107 unmodified lines
154155 const runStdioMcpSession = () =>
155156 Effect.gen(function* () {
156157 const executor = yield* Effect.promise(() => getExecutor());
157− yield* Effect.promise(() => runMcpStdioServer({ executor }));
158+ yield* Effect.promise(() =>
159+ runMcpStdioServer({ executor, codeExecutor: makeQuickJsExecutor() }),
160+ );
158161 });
159162
160163 // ---------------------------------------------------------------------------
apps/cloud/package.json+1−0
@@ -38,6 +38,7 @@ · 37 unmodified lines
3838 "@executor/plugin-workos-vault": "workspace:*",
3939 "@executor/react": "workspace:*",
4040 "@executor/runtime-dynamic-worker": "workspace:*",
41+ "@executor/runtime-quickjs": "workspace:*",
4142 "@executor/sdk": "workspace:*",
4243 "@executor/storage-core": "workspace:*",
4344 "@executor/storage-postgres": "workspace:*",
apps/cloud/src/mcp-session.e2e.node.test.ts+2−1
@@ -23,6 +23,7 @@ import type { ClientCapabilities } from "@modelcontextprotocol/sdk/types.js"; · 22 unmodified lines
2323
2424 import { createExecutorMcpServer } from "@executor/host-mcp";
2525 import { createExecutionEngine } from "@executor/execution";
26+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
2627 import {
2728 ElicitationResponse,
2829 FormElicitation,
@@ -134,7 +135,7 @@ const openSession = ( · 105 unmodified lines
134135 Effect.acquireRelease(
135136 Effect.gen(function* () {
136137 const executor = yield* buildScopedExecutor(orgId, `Org ${orgId}`, options);
137− const engine = createExecutionEngine({ executor });
138+ const engine = createExecutionEngine({ executor, codeExecutor: makeQuickJsExecutor() });
138139 const mcpServer = yield* Effect.promise(() => createExecutorMcpServer({ engine }));
139140 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
140141 const client = new Client(
apps/cloud/src/services/__test-harness__/api-harness.ts+2−1
@@ -31,6 +31,7 @@ import { · 30 unmodified lines
3131 ExecutorService,
3232 } from "@executor/api/server";
3333 import { createExecutionEngine } from "@executor/execution";
34+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
3435 import {
3536 Scope,
3637 ScopeId,
@@ -215,7 +216,7 @@ const TestApiLive = HttpApiBuilder.api(ProtectedCloudApi).pipe( · 178 unmodified lines
215216 const buildAppForScope = (scopeId: string, scopeName: string) =>
216217 Effect.gen(function* () {
217218 const executor = yield* createTestScopedExecutor(scopeId, scopeName);
218− const engine = createExecutionEngine({ executor });
219+ const engine = createExecutionEngine({ executor, codeExecutor: makeQuickJsExecutor() });
219220 const services = Layer.mergeAll(
220221 Layer.succeed(ExecutorService, executor),
221222 Layer.succeed(ExecutionEngineService, engine),
apps/local/package.json+1−0
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 "@executor/plugin-onepassword": "workspace:*",
3434 "@executor/plugin-openapi": "workspace:*",
3535 "@executor/react": "workspace:*",
36+ "@executor/runtime-quickjs": "workspace:*",
3637 "@executor/sdk": "workspace:*",
3738 "@executor/storage-file": "workspace:*",
3839 "@modelcontextprotocol/sdk": "^1.12.1",
apps/local/src/server/main.ts+2−1
@@ -10,6 +10,7 @@ import { Context, Effect, Layer, ManagedRuntime } from "effect"; · 9 unmodified lines
1010 import { addGroup } from "@executor/api";
1111 import { CoreHandlers, ExecutorService, ExecutionEngineService } from "@executor/api/server";
1212 import { createExecutionEngine } from "@executor/execution";
13+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
1314 import {
1415 OpenApiGroup,
1516 OpenApiHandlers,
@@ -78,7 +79,7 @@ const closeServerHandlers = async (handlers: ServerHandlers): Promise<void> => { · 62 unmodified lines
7879
7980 export const createServerHandlers = async (): Promise<ServerHandlers> => {
8081 const executor = await getExecutor();
81− const engine = createExecutionEngine({ executor });
82+ const engine = createExecutionEngine({ executor, codeExecutor: makeQuickJsExecutor() });
8283
8384 const pluginExtensions = Layer.mergeAll(
8485 Layer.succeed(OpenApiExtensionService, executor.openapi),
bun.lock+27−9
@@ -61,6 +61,7 @@ · 60 unmodified lines
6161 "@executor/plugin-workos-vault": "workspace:*",
6262 "@executor/react": "workspace:*",
6363 "@executor/runtime-dynamic-worker": "workspace:*",
64+ "@executor/runtime-quickjs": "workspace:*",
6465 "@executor/sdk": "workspace:*",
6566 "@executor/storage-core": "workspace:*",
6667 "@executor/storage-postgres": "workspace:*",
@@ -139,6 +140,7 @@ · 72 unmodified lines
139140 "@executor/plugin-onepassword": "workspace:*",
140141 "@executor/plugin-openapi": "workspace:*",
141142 "@executor/react": "workspace:*",
143+ "@executor/runtime-quickjs": "workspace:*",
142144 "@executor/sdk": "workspace:*",
143145 "@executor/storage-file": "workspace:*",
144146 "@modelcontextprotocol/sdk": "^1.12.1",
@@ -242,12 +244,13 @@ · 97 unmodified lines
242244 "executor": "./dist/index.js",
243245 },
244246 "dependencies": {
245− "@executor/sdk": "workspace:*",
246− "@executor/storage-core": "workspace:*",
247247 "commander": "^12.1.0",
248+ "effect": "catalog:",
248249 "jiti": "^2.6.1",
249250 },
250251 "devDependencies": {
252+ "@executor/sdk": "workspace:*",
253+ "@executor/storage-core": "workspace:*",
251254 "@types/node": "catalog:",
252255 "tsup": "catalog:",
253256 "typescript": "catalog:",
@@ -284,17 +287,19 @@ · 30 unmodified lines
284287 },
285288 "packages/core/execution": {
286289 "name": "@executor/execution",
287− "version": "1.4.3",
290+ "version": "0.0.1",
288291 "dependencies": {
289292 "@executor/codemode-core": "workspace:*",
290− "@executor/runtime-quickjs": "workspace:*",
291293 "@executor/sdk": "workspace:*",
292294 "effect": "catalog:",
293295 },
294296 "devDependencies": {
295297 "@effect/vitest": "catalog:",
298+ "@executor/runtime-quickjs": "workspace:*",
296299 "@types/node": "catalog:",
297300 "bun-types": "catalog:",
301+ "tsup": "catalog:",
302+ "typescript": "catalog:",
298303 "vitest": "catalog:",
299304 },
300305 },
@@ -315,16 +320,25 @@ · 14 unmodified lines
315320 },
316321 "packages/core/storage-core": {
317322 "name": "@executor/storage-core",
318− "version": "0.0.0",
323+ "version": "0.0.1",
319324 "dependencies": {
320− "@effect/vitest": "catalog:",
321325 "@standard-schema/spec": "^1.0.0",
322326 "effect": "catalog:",
323− "vitest": "catalog:",
324327 },
325328 "devDependencies": {
329+ "@effect/vitest": "catalog:",
330+ "tsup": "catalog:",
326331 "typescript": "catalog:",
332+ "vitest": "catalog:",
327333 },
334+ "peerDependencies": {
335+ "@effect/vitest": "catalog:",
336+ "vitest": "catalog:",
337+ },
338+ "optionalPeers": [
339+ "@effect/vitest",
340+ "vitest",
341+ ],
328342 },
329343 "packages/core/storage-drizzle": {
330344 "name": "@executor/storage-drizzle",
@@ -397,7 +411,7 @@ · 66 unmodified lines
397411 },
398412 "packages/kernel/core": {
399413 "name": "@executor/codemode-core",
400− "version": "1.4.3",
414+ "version": "0.0.1",
401415 "dependencies": {
402416 "@babel/parser": "^7.29.2",
403417 "@standard-schema/spec": "^1.0.0",
@@ -408,6 +422,8 @@ · 4 unmodified lines
408422 "devDependencies": {
409423 "@types/node": "catalog:",
410424 "bun-types": "catalog:",
425+ "tsup": "catalog:",
426+ "typescript": "catalog:",
411427 "vitest": "catalog:",
412428 },
413429 },
@@ -455,7 +471,7 @@ · 41 unmodified lines
455471 },
456472 "packages/kernel/runtime-quickjs": {
457473 "name": "@executor/runtime-quickjs",
458− "version": "1.4.3",
474+ "version": "0.0.1",
459475 "dependencies": {
460476 "@executor/codemode-core": "workspace:*",
461477 "effect": "catalog:",
@@ -465,6 +481,8 @@ · 3 unmodified lines
465481 "@effect/vitest": "catalog:",
466482 "@types/node": "catalog:",
467483 "bun-types": "catalog:",
484+ "tsup": "catalog:",
485+ "typescript": "catalog:",
468486 "vitest": "catalog:",
469487 },
470488 },
package.json+1−1
@@ -33,7 +33,7 @@ · 32 unmodified lines
3333 "dev:cli": "bun run apps/cli/src/main.ts",
3434 "test": "turbo run test",
3535 "test:release:bootstrap": "vitest run tests/release-bootstrap-smoke.test.ts",
36− "build:packages": "bun run --filter='@executor/sdk' build && bun run --filter='@executor/plugin-*' build",
36+ "build:packages": "bun run --filter='@executor/storage-core' build && bun run --filter='@executor/codemode-core' build && bun run --filter='@executor/runtime-quickjs' build && bun run --filter='@executor/sdk' build && bun run --filter='@executor/execution' build && bun run --filter='@executor/cli' build && bun run --filter='@executor/plugin-*' build",
3737 "typecheck": "turbo run typecheck",
3838 "typecheck:slow": "turbo run typecheck:slow",
3939 "ci": "bun run lint && bun run typecheck && bun run test",
packages/core/cli/README.md+57−0
@@ -0,0 +1,57 @@
1+# @executor/cli
2+
3+Command-line tool for `@executor/sdk` projects. Generates Drizzle schema files from the plugins registered in your `executor.config.ts` so database migrations stay in sync with the executor you actually run.
4+
5+## Install
6+
7+```sh
8+bun add -d @executor/cli
9+# or
10+npm install --save-dev @executor/cli
11+```
12+
13+The binary is installed as `executor`.
14+
15+## Quick start
16+
17+Create an `executor.config.ts` alongside your app code:
18+
19+```ts
20+import { defineExecutorConfig } from "@executor/sdk";
21+import { mcpPlugin } from "@executor/plugin-mcp";
22+import { openApiPlugin } from "@executor/plugin-openapi";
23+
24+export default defineExecutorConfig({
25+ dialect: "postgres",
26+ plugins: [mcpPlugin(), openApiPlugin()],
27+});
28+```
29+
30+Then generate a Drizzle schema from it:
31+
32+```sh
33+bunx executor generate --output ./src/db/executor-schema.ts
34+# or
35+npx executor generate --output ./src/db/executor-schema.ts
36+```
37+
38+The generator walks every plugin in the config, collects their schema contributions, and emits a single Drizzle schema file ready to hand to `drizzle-kit`.
39+
40+## Commands
41+
42+```
43+executor generate [options]
44+ --cwd <dir> Project directory (default: cwd)
45+ --config <path> Path to executor.config.ts (default: auto-discover)
46+ --output <path> Output file for the generated schema
47+```
48+
49+Run `executor --help` to see the current command list.
50+
51+## Status
52+
53+Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/RhysSullivan/executor).
54+
55+## License
56+
57+MIT
packages/core/cli/package.json+24−3
@@ -2,7 +2,16 @@ · 1 unmodified line
22 "name": "@executor/cli",
33 "version": "0.0.1",
44 "description": "CLI for the executor SDK — schema generation, migrations",
5+ "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/core/cli",
6+ "bugs": {
7+ "url": "https://github.com/RhysSullivan/executor/issues"
8+ },
59 "license": "MIT",
10+ "repository": {
11+ "type": "git",
12+ "url": "git+https://github.com/RhysSullivan/executor.git",
13+ "directory": "packages/core/cli"
14+ },
615 "type": "module",
716 "bin": {
817 "executor": "./dist/index.js"
@@ -13,19 +22,31 @@ · 4 unmodified lines
1322 "exports": {
1423 ".": "./src/index.ts"
1524 },
25+ "publishConfig": {
26+ "access": "public",
27+ "exports": {
28+ ".": {
29+ "import": {
30+ "types": "./dist/index.d.ts",
31+ "default": "./dist/index.js"
32+ }
33+ }
34+ }
35+ },
1636 "scripts": {
17− "build": "tsup src/index.ts --format esm --dts",
37+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
1838 "dev": "node --import jiti/register src/index.ts",
1939 "test": "vitest run",
2040 "typecheck": "tsc --noEmit"
2141 },
2242 "dependencies": {
23− "@executor/sdk": "workspace:*",
24− "@executor/storage-core": "workspace:*",
2543 "commander": "^12.1.0",
44+ "effect": "catalog:",
2645 "jiti": "^2.6.1"
2746 },
2847 "devDependencies": {
48+ "@executor/sdk": "workspace:*",
49+ "@executor/storage-core": "workspace:*",
2950 "@types/node": "catalog:",
3051 "tsup": "catalog:",
3152 "typescript": "catalog:",
packages/core/cli/src/commands/generate.ts+1−1
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs"; · 1 unmodified line
22 import fs from "node:fs/promises";
33 import path from "node:path";
44 import { Command } from "commander";
5−import { collectSchemas } from "@executor/sdk";
5+import { collectSchemas } from "@executor/sdk/core";
66 import { getConfig } from "../utils/get-config.js";
77 import { generateDrizzleSchema } from "../generators/drizzle.js";
88
packages/core/cli/src/generators/types.ts+1−1
@@ -1,5 +1,5 @@
11 import type { DBSchema } from "@executor/storage-core";
2−import type { ExecutorDialect } from "@executor/sdk";
2+import type { ExecutorDialect } from "@executor/sdk/core";
33
44 export interface SchemaGeneratorResult {
55 code?: string;
packages/core/cli/src/utils/get-config.ts+1−1
@@ -1,7 +1,7 @@
11 import { existsSync } from "node:fs";
22 import path from "node:path";
33 import { createJiti } from "jiti";
4−import type { ExecutorCliConfig } from "@executor/sdk";
4+import type { ExecutorCliConfig } from "@executor/sdk/core";
55
66 const defaultPaths = [
77 "executor.config.ts",
packages/core/cli/tsup.config.ts+17−0
@@ -0,0 +1,17 @@
1+import { defineConfig } from "tsup";
2+
3+export default defineConfig({
4+ entry: {
5+ index: "src/index.ts",
6+ },
7+ format: ["esm"],
8+ dts: false,
9+ sourcemap: true,
10+ clean: true,
11+ external: [
12+ /^effect/,
13+ /^@effect\//,
14+ "commander",
15+ "jiti",
16+ ],
17+});
packages/core/execution/README.md+94−0
@@ -0,0 +1,94 @@
1+# @executor/execution
2+
3+Sandboxed JavaScript execution for an executor. Hands a `tools.<namespace>.<name>(...)` proxy into a code sandbox so an agent (or any caller) can run generated TypeScript/JavaScript that invokes the executor's registered tools.
4+
5+Supports pause/resume for elicitation-driven flows: tools that need user input (OAuth, form fill, approval) suspend the sandbox, surface a `PausedExecution`, and resume on a `ResumeResponse`.
6+
7+## Install
8+
9+```sh
10+bun add @executor/sdk @executor/execution @executor/runtime-quickjs
11+# or
12+npm install @executor/sdk @executor/execution @executor/runtime-quickjs
13+```
14+
15+`@executor/runtime-quickjs` is the sandbox runtime. It's not a dependency of `@executor/execution` — you bring your own so consumers with a different runtime don't ship ~13 MB of WASM they never use.
16+
17+## Usage
18+
19+```ts
20+import { createExecutor } from "@executor/sdk";
21+import { createExecutionEngine } from "@executor/execution";
22+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
23+
24+const executor = await createExecutor({
25+ scope: { name: "my-app" },
26+});
27+
28+const engine = createExecutionEngine({
29+ executor,
30+ codeExecutor: makeQuickJsExecutor({
31+ timeoutMs: 2_000,
32+ memoryLimitBytes: 32 * 1024 * 1024,
33+ }),
34+});
35+
36+const result = await engine.execute(
37+ `
38+ const pets = await tools.petstore.findPetsByStatus({ status: "available" });
39+ return pets.length;
40+ `,
41+ {
42+ onElicitation: async (ctx) => {
43+ // A tool asked for user input mid-execution. Your UI decides what to do.
44+ console.log("tool needs input:", ctx.request);
45+ return { action: "decline" };
46+ },
47+ },
48+);
49+
50+console.log(result);
51+// { result: 12, logs: [...] }
52+```
53+
54+## Pause/resume for elicitation
55+
56+When the host doesn't support inline elicitation, use `executeWithPause` to intercept the first request as a pause point:
57+
58+```ts
59+const started = await engine.executeWithPause(code);
60+
61+if (started.status === "paused") {
62+ const { id, elicitationContext } = started.execution;
63+ // Render the elicitation request in your UI. Later:
64+ const resumed = await engine.resume(id, {
65+ action: "accept",
66+ content: { name: "Ada" },
67+ });
68+}
69+```
70+
71+## Workflow description for LLMs
72+
73+```ts
74+const docs = await engine.getDescription();
75+// Returns the canonical "use tools.search(), then tools.describe.tool(), then call …"
76+// workflow prose + per-namespace tool listing. Feed this to an LLM so it knows
77+// how to drive the sandbox.
78+```
79+
80+## Using with Effect
81+
82+If you're building on `@executor/sdk` (the raw Effect entry), import from the `/core` subpath. The returned engine is Effect-native: `execute`, `executeWithPause`, and `resume` all become `Effect.Effect<...>`, and `onElicitation` is an `ElicitationHandler` returning `Effect.Effect<ElicitationResponse>`.
83+
84+```ts
85+import { createExecutionEngine } from "@executor/execution";
86+```
87+
88+## Status
89+
90+Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/RhysSullivan/executor).
91+
92+## License
93+
94+MIT
packages/core/execution/package.json+37−4
@@ -1,26 +1,59 @@
11 {
22 "name": "@executor/execution",
3− "version": "1.4.3",
4− "private": true,
3+ "version": "0.0.1",
4+ "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/core/execution",
5+ "bugs": {
6+ "url": "https://github.com/RhysSullivan/executor/issues"
7+ },
8+ "license": "MIT",
9+ "repository": {
10+ "type": "git",
11+ "url": "git+https://github.com/RhysSullivan/executor.git",
12+ "directory": "packages/core/execution"
13+ },
14+ "files": [
15+ "dist"
16+ ],
517 "type": "module",
618 "exports": {
7− ".": "./src/index.ts"
19+ ".": "./src/index.ts",
20+ "./promise": "./src/promise.ts"
21+ },
22+ "publishConfig": {
23+ "access": "public",
24+ "exports": {
25+ ".": {
26+ "import": {
27+ "types": "./dist/promise.d.ts",
28+ "default": "./dist/index.js"
29+ }
30+ },
31+ "./core": {
32+ "import": {
33+ "types": "./dist/index.d.ts",
34+ "default": "./dist/core.js"
35+ }
36+ }
37+ }
838 },
939 "scripts": {
40+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
1041 "typecheck": "tsgo --noEmit",
1142 "test": "vitest run",
1243 "typecheck:slow": "bunx tsc --noEmit -p tsconfig.json"
1344 },
1445 "dependencies": {
1546 "@executor/codemode-core": "workspace:*",
16− "@executor/runtime-quickjs": "workspace:*",
1747 "@executor/sdk": "workspace:*",
1848 "effect": "catalog:"
1949 },
2050 "devDependencies": {
2151 "@effect/vitest": "catalog:",
52+ "@executor/runtime-quickjs": "workspace:*",
2253 "@types/node": "catalog:",
2354 "bun-types": "catalog:",
55+ "tsup": "catalog:",
56+ "typescript": "catalog:",
2457 "vitest": "catalog:"
2558 }
2659 }
packages/core/execution/src/engine.ts+2−4
@@ -8,7 +8,6 @@ import type { · 7 unmodified lines
88 ElicitationContext,
99 } from "@executor/sdk";
1010 import type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from "@executor/codemode-core";
11−import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
1211
1312 import {
1413 makeExecutorToolInvoker,
@@ -25,7 +24,7 @@ import { buildExecuteDescription } from "./description"; · 10 unmodified lines
2524
2625 export type ExecutionEngineConfig = {
2726 readonly executor: Executor;
28− readonly codeExecutor?: CodeExecutor;
27+ readonly codeExecutor: CodeExecutor;
2928 };
3029
3130 export type ExecutionResult =
@@ -292,8 +291,7 @@ const runEffect = <A>(effect: Effect.Effect<A, unknown>): Promise<A> => · 260 unmodified lines
292291 Effect.runPromise(effect as Effect.Effect<A, never>);
293292
294293 export const createExecutionEngine = (config: ExecutionEngineConfig): ExecutionEngine => {
295− const { executor } = config;
296− const codeExecutor = config.codeExecutor ?? makeQuickJsExecutor();
294+ const { executor, codeExecutor } = config;
297295 const pausedExecutions = new Map<string, InternalPausedExecution>();
298296 let nextId = 0;
299297
packages/core/execution/src/promise.ts+120−0
@@ -0,0 +1,120 @@
1+// ---------------------------------------------------------------------------
2+// @executor/execution/promise — Promise-native surface for the execution
3+// engine. Accepts a Promise-style Executor (from @executor/sdk) and an
4+// async `onElicitation` handler — no Effect imports required by callers.
5+//
6+// Under the hood the engine is Effect-based, so we wrap the incoming
7+// Promise executor into the minimal Effect shape the engine consumes,
8+// and bridge the elicitation handler via `Effect.tryPromise`.
9+// ---------------------------------------------------------------------------
10+
11+import { Effect } from "effect";
12+
13+import type {
14+ ElicitationContext,
15+ ElicitationResponse,
16+ Executor as PromiseExecutor,
17+} from "@executor/sdk";
18+import type { CodeExecutor, ExecuteResult } from "@executor/codemode-core";
19+
20+import {
21+ createExecutionEngine as createEffectExecutionEngine,
22+ type ExecutionResult,
23+ type PausedExecution,
24+ type ResumeResponse,
25+} from "./engine";
26+
27+export type ElicitationHandler = (
28+ ctx: ElicitationContext,
29+) => Promise<ElicitationResponse>;
30+
31+export type ExecutionEngineConfig = {
32+ readonly executor: PromiseExecutor;
33+ readonly codeExecutor: CodeExecutor;
34+};
35+
36+export type ExecutionEngine = {
37+ readonly execute: (
38+ code: string,
39+ options: { readonly onElicitation: ElicitationHandler },
40+ ) => Promise<ExecuteResult>;
41+ readonly executeWithPause: (code: string) => Promise<ExecutionResult>;
42+ readonly resume: (
43+ executionId: string,
44+ response: ResumeResponse,
45+ ) => Promise<ExecutionResult | null>;
46+ readonly getDescription: () => Promise<string>;
47+};
48+
49+/**
50+ * Wrap a Promise-style executor into the Effect shape the engine consumes.
51+ * Only the four method families the engine actually touches need wrapping:
52+ * `tools.{invoke,list,schema}` and `sources.list`.
53+ */
54+const wrapPromiseExecutor = (pe: PromiseExecutor): any => ({
55+ scope: (pe as any).scope,
56+ tools: {
57+ invoke: (id: unknown, args: unknown, options: unknown) =>
58+ Effect.tryPromise({
59+ try: () => (pe.tools as any).invoke(id, args, options),
60+ catch: (cause) => cause,
61+ }),
62+ list: (filter?: unknown) =>
63+ Effect.tryPromise({
64+ try: () => (pe.tools as any).list(filter),
65+ catch: (cause) => cause,
66+ }).pipe(Effect.orDie),
67+ schema: (id: unknown) =>
68+ Effect.tryPromise({
69+ try: () => (pe.tools as any).schema(id),
70+ catch: (cause) => cause,
71+ }),
72+ definitions: () =>
73+ Effect.tryPromise({
74+ try: () => (pe.tools as any).definitions(),
75+ catch: (cause) => cause,
76+ }).pipe(Effect.orDie),
77+ },
78+ sources: {
79+ list: () =>
80+ Effect.tryPromise({
81+ try: () => (pe.sources as any).list(),
82+ catch: (cause) => cause,
83+ }).pipe(Effect.orDie),
84+ },
85+});
86+
87+export const createExecutionEngine = (
88+ config: ExecutionEngineConfig,
89+): ExecutionEngine => {
90+ const engine = createEffectExecutionEngine({
91+ executor: wrapPromiseExecutor(config.executor),
92+ codeExecutor: config.codeExecutor,
93+ });
94+ return {
95+ execute: (code, options) =>
96+ engine.execute(code, {
97+ onElicitation: (ctx) =>
98+ Effect.tryPromise(() => options.onElicitation(ctx)).pipe(
99+ Effect.orDie,
100+ ),
101+ }),
102+ executeWithPause: (code) => engine.executeWithPause(code),
103+ resume: (executionId, response) => engine.resume(executionId, response),
104+ getDescription: () => engine.getDescription(),
105+ };
106+};
107+
108+// ---------------------------------------------------------------------------
109+// Re-exports — plain types/helpers that don't carry Effect signatures.
110+// ---------------------------------------------------------------------------
111+
112+export {
113+ formatExecuteResult,
114+ formatPausedExecution,
115+} from "./engine";
116+
117+export type { ExecutionResult, PausedExecution, ResumeResponse };
118+
119+export { buildExecuteDescription } from "./description";
120+export { ExecutionToolError } from "./errors";
packages/core/execution/src/tool-invoker.test.ts+9−6
@@ -8,9 +8,12 @@ import { · 7 unmodified lines
88 definePlugin,
99 makeTestConfig,
1010 } from "@executor/sdk";
11+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
1112 import { createExecutionEngine } from "./engine";
1213 import { describeTool, searchTools } from "./tool-invoker";
1314
15+const codeExecutor = makeQuickJsExecutor();
16+
1417 const RepoInputSchema = {
1518 type: "object",
1619 properties: {
@@ -148,7 +151,7 @@ describe("tool discovery", () => { · 131 unmodified lines
148151 expect(crmOnly.map((match) => match.path)).toEqual(["crm.listContacts"]);
149152
150153 const sandboxResult = yield* Effect.promise(() =>
151− createExecutionEngine({ executor }).execute(
154+ createExecutionEngine({ executor, codeExecutor }).execute(
152155 'return await tools.search({ namespace: "crm", query: "create contact", limit: 5 });',
153156 { onElicitation: acceptAll },
154157 ),
@@ -165,7 +168,7 @@ describe("tool discovery", () => { · 10 unmodified lines
165168 const executor = yield* makeSearchExecutor();
166169
167170 const listed = yield* Effect.promise(() =>
168− createExecutionEngine({ executor }).execute("return await tools.executor.sources.list();", {
171+ createExecutionEngine({ executor, codeExecutor }).execute("return await tools.executor.sources.list();", {
169172 onElicitation: acceptAll,
170173 }),
171174 );
@@ -178,7 +181,7 @@ describe("tool discovery", () => { · 6 unmodified lines
178181 );
179182
180183 const searched = yield* Effect.promise(() =>
181− createExecutionEngine({ executor }).execute(
184+ createExecutionEngine({ executor, codeExecutor }).execute(
182185 'return await tools.search({ query: "list contacts", namespace: "crm", limit: 5 });',
183186 { onElicitation: acceptAll },
184187 ),
@@ -205,7 +208,7 @@ describe("tool discovery", () => { · 20 unmodified lines
205208 it.effect("rejects malformed discover calls inside the sandbox", () =>
206209 Effect.gen(function* () {
207210 const executor = yield* makeSearchExecutor();
208− const engine = createExecutionEngine({ executor });
211+ const engine = createExecutionEngine({ executor, codeExecutor });
209212
210213 const invalid = yield* Effect.promise(() =>
211214 engine.execute(
@@ -327,7 +330,7 @@ describe("pause/resume with multiple elicitations", () => { · 115 unmodified lines
327330 () =>
328331 Effect.gen(function* () {
329332 const executor = yield* makeElicitingExecutor();
330− const engine = createExecutionEngine({ executor });
333+ const engine = createExecutionEngine({ executor, codeExecutor });
331334
332335 const code = "return await tools.api.multiApproval({});";
333336
@@ -361,7 +364,7 @@ describe("pause/resume with multiple elicitations", () => { · 27 unmodified lines
361364 // sandbox fiber.
362365 it("resume returns across separate runPromise boundaries for a single-elicit tool (HTTP-like)", async () => {
363366 const executor = await Effect.runPromise(makeElicitingExecutor());
364− const engine = createExecutionEngine({ executor });
367+ const engine = createExecutionEngine({ executor, codeExecutor });
365368
366369 const code = "return await tools.api.singleApproval({});";
367370
packages/core/execution/tsconfig.json+5−1
@@ -5,7 +5,11 @@ · 4 unmodified lines
55 "moduleResolution": "Bundler",
66 "strict": true,
77 "skipLibCheck": true,
8− "noEmit": true,
8+ "outDir": "dist",
9+ "rootDir": "src",
10+ "declaration": true,
11+ "declarationMap": true,
12+ "sourceMap": true,
913 "lib": ["ES2022"],
1014 "types": ["bun-types", "node"],
1115 "noUnusedLocals": true,
packages/core/execution/tsup.config.ts+13−0
@@ -0,0 +1,13 @@
1+import { defineConfig } from "tsup";
2+
3+export default defineConfig({
4+ entry: {
5+ index: "src/promise.ts",
6+ core: "src/index.ts",
7+ },
8+ format: ["esm"],
9+ dts: false,
10+ sourcemap: true,
11+ clean: true,
12+ external: [/^@executor\//, /^effect/, /^@effect\//],
13+});
packages/core/sdk/package.json+1−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 "type": "module",
1818 "exports": {
1919 ".": "./src/index.ts",
20+ "./core": "./src/index.ts",
2021 "./promise": "./src/promise.ts"
2122 },
2223 "publishConfig": {
packages/core/storage-core/README.md+64−0
@@ -0,0 +1,64 @@
1+# @executor/storage-core
2+
3+Storage adapter interface for the executor. Defines the shared `DBAdapter`, `DBSchema`, and query-operator types every persistence backend implements, plus helpers for typed queries and an in-memory conformance test suite.
4+
5+Most callers don't depend on this directly — `@executor/sdk` re-exports the public surface. Install this when you're authoring a new storage adapter and want to conform to the contract.
6+
7+## Install
8+
9+```sh
10+bun add @executor/storage-core
11+# or
12+npm install @executor/storage-core
13+```
14+
15+## Usage
16+
17+Implement an adapter:
18+
19+```ts
20+import { createAdapter, type DBAdapter } from "@executor/storage-core";
21+
22+const myAdapter: DBAdapter = createAdapter({
23+ // ... your backend's query / mutation hooks
24+});
25+```
26+
27+Or grab typed query helpers for an existing schema:
28+
29+```ts
30+import { typedAdapter, type DBSchema } from "@executor/storage-core";
31+
32+const schema = {
33+ secrets: {
34+ fields: {
35+ id: { type: "string", required: true },
36+ value: { type: "string", required: true },
37+ },
38+ },
39+} satisfies DBSchema;
40+
41+const db = typedAdapter(myAdapter, schema);
42+```
43+
44+## Conformance tests
45+
46+If you're building an adapter, use the shared conformance suite to verify your backend matches the contract:
47+
48+```ts
49+import { describeDbAdapterConformance } from "@executor/storage-core/testing";
50+
51+describeDbAdapterConformance({
52+ makeAdapter: async () => myAdapter,
53+});
54+```
55+
56+The suite runs against any `describe` from your test runner. `vitest` and `@effect/vitest` are declared as optional peer dependencies — install whichever you use.
57+
58+## Status
59+
60+Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/RhysSullivan/executor).
61+
62+## License
63+
64+MIT
packages/core/storage-core/package.json+54−5
@@ -1,25 +1,74 @@
11 {
22 "name": "@executor/storage-core",
3− "version": "0.0.0",
4− "private": true,
3+ "version": "0.0.1",
4+ "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/core/storage-core",
5+ "bugs": {
6+ "url": "https://github.com/RhysSullivan/executor/issues"
7+ },
8+ "license": "MIT",
9+ "repository": {
10+ "type": "git",
11+ "url": "git+https://github.com/RhysSullivan/executor.git",
12+ "directory": "packages/core/storage-core"
13+ },
14+ "files": [
15+ "dist"
16+ ],
517 "type": "module",
618 "exports": {
719 ".": "./src/index.ts",
820 "./testing": "./src/testing/conformance.ts",
921 "./testing/memory": "./src/testing/memory.ts"
1022 },
23+ "publishConfig": {
24+ "access": "public",
25+ "exports": {
26+ ".": {
27+ "import": {
28+ "types": "./dist/index.d.ts",
29+ "default": "./dist/index.js"
30+ }
31+ },
32+ "./testing": {
33+ "import": {
34+ "types": "./dist/testing/conformance.d.ts",
35+ "default": "./dist/testing/conformance.js"
36+ }
37+ },
38+ "./testing/memory": {
39+ "import": {
40+ "types": "./dist/testing/memory.d.ts",
41+ "default": "./dist/testing/memory.js"
42+ }
43+ }
44+ }
45+ },
1146 "scripts": {
47+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
1248 "test": "vitest run",
1349 "typecheck": "tsgo --noEmit",
1450 "typecheck:slow": "tsc --noEmit"
1551 },
1652 "dependencies": {
17− "@effect/vitest": "catalog:",
1853 "@standard-schema/spec": "^1.0.0",
19− "effect": "catalog:",
54+ "effect": "catalog:"
55+ },
56+ "peerDependencies": {
57+ "@effect/vitest": "catalog:",
2058 "vitest": "catalog:"
2159 },
60+ "peerDependenciesMeta": {
61+ "@effect/vitest": {
62+ "optional": true
63+ },
64+ "vitest": {
65+ "optional": true
66+ }
67+ },
2268 "devDependencies": {
23− "typescript": "catalog:"
69+ "@effect/vitest": "catalog:",
70+ "tsup": "catalog:",
71+ "typescript": "catalog:",
72+ "vitest": "catalog:"
2473 }
2574 }
packages/core/storage-core/tsup.config.ts+14−0
@@ -0,0 +1,14 @@
1+import { defineConfig } from "tsup";
2+
3+export default defineConfig({
4+ entry: {
5+ index: "src/index.ts",
6+ "testing/conformance": "src/testing/conformance.ts",
7+ "testing/memory": "src/testing/memory.ts",
8+ },
9+ format: ["esm"],
10+ dts: false,
11+ sourcemap: true,
12+ clean: true,
13+ external: [/^@executor\//, /^effect/, /^@effect\//, "vitest"],
14+});
packages/kernel/core/README.md+40−0
@@ -0,0 +1,40 @@
1+# @executor/codemode-core
2+
3+Core primitives for "code mode" — the pattern where an LLM writes TypeScript/JavaScript that calls into a pre-registered set of tools, executed in a sandbox. This package provides the shared type surface (`Tool`, `SandboxToolInvoker`, `CodeExecutor`), JSON Schema helpers, and error types used by every runtime that implements the contract.
4+
5+Most callers depend on this transitively through `@executor/execution` and a sandbox runtime like `@executor/runtime-quickjs`. Install directly when you're authoring a new runtime.
6+
7+## Install
8+
9+```sh
10+bun add @executor/codemode-core
11+# or
12+npm install @executor/codemode-core
13+```
14+
15+## Usage
16+
17+Implement a runtime that satisfies `CodeExecutor`:
18+
19+```ts
20+import type { CodeExecutor, SandboxToolInvoker } from "@executor/codemode-core";
21+import { Effect } from "effect";
22+
23+export const makeMyRuntime = (): CodeExecutor => ({
24+ execute: (code: string, invoker: SandboxToolInvoker) =>
25+ Effect.gen(function* () {
26+ // Spin up your sandbox, expose `invoker` as `tools.<path>(...)`, run the code,
27+ // collect logs, and return an ExecuteResult.
28+ }),
29+});
30+```
31+
32+The runtime is passed a `SandboxToolInvoker` that bridges sandbox-side tool calls back to the executor. The sandbox-visible API is whatever you decide — `@executor/runtime-quickjs` exposes a `tools` proxy object; a runtime targeting Cloudflare Workers might use something else.
33+
34+## Status
35+
36+Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/RhysSullivan/executor).
37+
38+## License
39+
40+MIT
packages/kernel/core/package.json+28−2
@@ -1,12 +1,36 @@
11 {
22 "name": "@executor/codemode-core",
3− "version": "1.4.3",
4− "private": true,
3+ "version": "0.0.1",
4+ "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/kernel/core",
5+ "bugs": {
6+ "url": "https://github.com/RhysSullivan/executor/issues"
7+ },
8+ "license": "MIT",
9+ "repository": {
10+ "type": "git",
11+ "url": "git+https://github.com/RhysSullivan/executor.git",
12+ "directory": "packages/kernel/core"
13+ },
14+ "files": [
15+ "dist"
16+ ],
517 "type": "module",
618 "exports": {
719 ".": "./src/index.ts"
820 },
21+ "publishConfig": {
22+ "access": "public",
23+ "exports": {
24+ ".": {
25+ "import": {
26+ "types": "./dist/index.d.ts",
27+ "default": "./dist/index.js"
28+ }
29+ }
30+ }
31+ },
932 "scripts": {
33+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
1034 "typecheck": "tsgo --noEmit",
1135 "test": "vitest run",
1236 "test:watch": "vitest",
@@ -22,6 +46,8 @@ · 9 unmodified lines
2246 "devDependencies": {
2347 "@types/node": "catalog:",
2448 "bun-types": "catalog:",
49+ "tsup": "catalog:",
50+ "typescript": "catalog:",
2551 "vitest": "catalog:"
2652 }
2753 }
packages/kernel/core/tsconfig.json+5−1
@@ -5,7 +5,11 @@ · 4 unmodified lines
55 "moduleResolution": "Bundler",
66 "strict": true,
77 "skipLibCheck": true,
8− "noEmit": true,
8+ "outDir": "dist",
9+ "rootDir": "src",
10+ "declaration": true,
11+ "declarationMap": true,
12+ "sourceMap": true,
913 "lib": ["ES2022"],
1014 "types": ["bun-types", "node"],
1115 "noUnusedLocals": true,
packages/kernel/core/tsup.config.ts+12−0
@@ -0,0 +1,12 @@
1+import { defineConfig } from "tsup";
2+
3+export default defineConfig({
4+ entry: {
5+ index: "src/index.ts",
6+ },
7+ format: ["esm"],
8+ dts: false,
9+ sourcemap: true,
10+ clean: true,
11+ external: [/^@executor\//, /^effect/, /^@effect\//],
12+});
packages/kernel/runtime-quickjs/README.md+60−0
@@ -0,0 +1,60 @@
1+# @executor/runtime-quickjs
2+
3+[QuickJS](https://github.com/justjake/quickjs-emscripten) sandbox runtime for `@executor/execution`. Runs untrusted TypeScript/JavaScript in a WASM-backed interpreter with configurable timeout, memory limit, and stack size — safe enough to execute LLM-generated code that calls your registered tools.
4+
5+## Install
6+
7+```sh
8+bun add @executor/execution @executor/runtime-quickjs
9+# or
10+npm install @executor/execution @executor/runtime-quickjs
11+```
12+
13+## Usage
14+
15+Pass a `makeQuickJsExecutor()` as the `codeExecutor` when building the execution engine:
16+
17+```ts
18+import { createExecutor } from "@executor/sdk";
19+import { createExecutionEngine } from "@executor/execution";
20+import { makeQuickJsExecutor } from "@executor/runtime-quickjs";
21+
22+const executor = await createExecutor({ scope: { name: "my-app" } });
23+
24+const engine = createExecutionEngine({
25+ executor,
26+ codeExecutor: makeQuickJsExecutor({
27+ timeoutMs: 2_000,
28+ memoryLimitBytes: 32 * 1024 * 1024,
29+ maxStackSizeBytes: 1 * 1024 * 1024,
30+ }),
31+});
32+```
33+
34+### Options
35+
36+| Option | Default | Description |
37+| ------------------- | ---------- | -------------------------------------------- |
38+| `timeoutMs` | `5_000` | Max wall-clock time per execution |
39+| `memoryLimitBytes` | `64 * 1MB` | Max memory the VM can allocate |
40+| `maxStackSizeBytes` | `1 * 1MB` | Max call-stack depth |
41+
42+### Swapping the QuickJS build
43+
44+```ts
45+import { setQuickJSModule } from "@executor/runtime-quickjs";
46+import { newQuickJSAsyncWASMModuleFromVariant } from "quickjs-emscripten";
47+import variant from "@jitl/quickjs-ng-wasmfile-release-sync";
48+
49+setQuickJSModule(await newQuickJSAsyncWASMModuleFromVariant(variant));
50+```
51+
52+Use this when you want a different WASM variant (e.g. debug builds, QuickJS-NG) than the default bundled one.
53+
54+## Status
55+
56+Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/RhysSullivan/executor).
57+
58+## License
59+
60+MIT
packages/kernel/runtime-quickjs/package.json+28−2
@@ -1,12 +1,36 @@
11 {
22 "name": "@executor/runtime-quickjs",
3− "version": "1.4.3",
4− "private": true,
3+ "version": "0.0.1",
4+ "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/kernel/runtime-quickjs",
5+ "bugs": {
6+ "url": "https://github.com/RhysSullivan/executor/issues"
7+ },
8+ "license": "MIT",
9+ "repository": {
10+ "type": "git",
11+ "url": "git+https://github.com/RhysSullivan/executor.git",
12+ "directory": "packages/kernel/runtime-quickjs"
13+ },
14+ "files": [
15+ "dist"
16+ ],
517 "type": "module",
618 "exports": {
719 ".": "./src/index.ts"
820 },
21+ "publishConfig": {
22+ "access": "public",
23+ "exports": {
24+ ".": {
25+ "import": {
26+ "types": "./dist/index.d.ts",
27+ "default": "./dist/index.js"
28+ }
29+ }
30+ }
31+ },
932 "scripts": {
33+ "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
1034 "typecheck": "tsgo --noEmit",
1135 "test": "vitest run",
1236 "test:watch": "vitest",
@@ -21,6 +45,8 @@ · 8 unmodified lines
2145 "@effect/vitest": "catalog:",
2246 "@types/node": "catalog:",
2347 "bun-types": "catalog:",
48+ "tsup": "catalog:",
49+ "typescript": "catalog:",
2450 "vitest": "catalog:"
2551 }
2652 }
packages/kernel/runtime-quickjs/tsconfig.json+5−1
@@ -5,7 +5,11 @@ · 4 unmodified lines
55 "moduleResolution": "Bundler",
66 "strict": true,
77 "skipLibCheck": true,
8− "noEmit": true,
8+ "outDir": "dist",
9+ "rootDir": "src",
10+ "declaration": true,
11+ "declarationMap": true,
12+ "sourceMap": true,
913 "lib": ["ES2022"],
1014 "types": ["bun-types", "node"],
1115 "noUnusedLocals": true,
packages/kernel/runtime-quickjs/tsup.config.ts+12−0
@@ -0,0 +1,12 @@
1+import { defineConfig } from "tsup";
2+
3+export default defineConfig({
4+ entry: {
5+ index: "src/index.ts",
6+ },
7+ format: ["esm"],
8+ dts: false,
9+ sourcemap: true,
10+ clean: true,
11+ external: [/^@executor\//, /^effect/, /^@effect\//, "quickjs-emscripten"],
12+});
scripts/publish-packages.ts+11−8
@@ -38,7 +38,12 @@ const PUBLISHED_SCOPE = "@executor-js"; · 37 unmodified lines
3838 * directory under `packages/plugins/` does not accidentally ship to npm.
3939 */
4040 const PUBLIC_PACKAGE_DIRS = [
41+ "packages/core/storage-core",
42+ "packages/kernel/core",
43+ "packages/kernel/runtime-quickjs",
4144 "packages/core/sdk",
45+ "packages/core/execution",
46+ "packages/core/cli",
4247 "packages/plugins/file-secrets",
4348 "packages/plugins/google-discovery",
4449 "packages/plugins/graphql",
@@ -267,13 +272,13 @@ const applyPublishConfig = async (pkgDir: string): Promise<() => Promise<void>> · 222 unmodified lines
267272
268273 const publishPackage = async (
269274 pkgDir: string,
270− channel: Channel,
271275 dryRun: boolean,
272276 publishable: ReadonlySet<string>,
273277 publishableVersions: ReadonlyMap<string, string>,
274278 ) => {
275279 const { name: internalName, version } = await readPackageMeta(pkgDir);
276280 const publishedName = internalName.replace(`${INTERNAL_SCOPE}/`, `${PUBLISHED_SCOPE}/`);
281+ const channel = resolveChannel(version);
277282
278283 if (!existsSync(join(pkgDir, "dist"))) {
279284 throw new Error(`Missing dist/ in ${pkgDir}. Did you run 'bun run build:packages'?`);
@@ -326,12 +331,10 @@ const publishPackage = async ( · 46 unmodified lines
326331 const main = async () => {
327332 const { dryRun } = parseArgs(process.argv.slice(2));
328333
329− // Use the sdk package version as the source of truth for the channel. All
330− // published packages version together (they're not in the changeset ignore
331− // list), so they share a release channel.
332− const sdkMeta = await readPackageMeta(join(repoRoot, "packages/core/sdk"));
333− const channel = resolveChannel(sdkMeta.version);
334− console.log(`Publishing ${PUBLISHED_SCOPE} packages (${channel})${dryRun ? " [dry-run]" : ""}`);
334+ // Each package's own version determines its dist-tag (pre-release versions
335+ // with `-` publish to `beta`, everything else to `latest`). Packages are
336+ // only skipped when their current version is already on npm.
337+ console.log(`Publishing ${PUBLISHED_SCOPE} packages${dryRun ? " [dry-run]" : ""}`);
335338
336339 await $`bun run build:packages`.cwd(repoRoot);
337340
@@ -351,7 +354,7 @@ const main = async () => { · 13 unmodified lines
351354 }
352355
353356 for (const relDir of PUBLIC_PACKAGE_DIRS) {
354− await publishPackage(join(repoRoot, relDir), channel, dryRun, publishable, publishableVersions);
357+ await publishPackage(join(repoRoot, relDir), dryRun, publishable, publishableVersions);
355358 }
356359 };
357360