Skip to content

Ship @executor-js/* beta from monorepo with promise wrapper - #142

Merged
RhysSullivan merged 4 commits into
mainfrom
sdk-consolidation
Apr 10, 2026
Merged

Ship @executor-js/* beta from monorepo with promise wrapper#142
RhysSullivan merged 4 commits into
mainfrom
sdk-consolidation

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Publishes 8 @executor-js/* packages (sdk + 7 plugins) from this monorepo, with a promise-shaped wrapper as the default published entry and pluggable storage exposed on it. Source code stays on the internal @executor/* scope and keeps bare imports — the @executor@executor-js scope rename and promise/Effect entry-point swap both happen at pack time, so dev imports don't contort to accommodate the publish flow.

What ships

  • @executor-js/sdk — default import is a promise-based createExecutor / definePlugin surface (no Effect knowledge required). ./core subpath exposes the raw Effect primitives for advanced users.
  • 7 plugin packages (file-secrets, google-discovery, graphql, keychain, mcp, onepassword, openapi) — same dual-entry shape: default import is a promise wrapper, ./core is the Effect plugin.
  • Pluggable storage on the promise createExecutor: user-supplied tools / sources / secrets / policies stores (promise-shaped ToolRegistry / SourceRegistry / SecretStore / PolicyEngine interfaces). Promise ↔ Effect adapter layer converts to/from the internal Effect services.
  • examples/promise-sdk — runnable end-to-end example demonstrating the promise API with MCP + OpenAPI + GraphQL plugins and a custom plugin.

Dev vs published shape

Dev imports stay simple — everything uses bare @executor/sdk and bare @executor/plugin-*, resolving to the Effect sources (what internal code actually needs). At pack time scripts/publish-packages.ts applies two transformations:

  1. Scope rename: @executor/*@executor-js/* in package.json (name + dep blocks, with workspace:* resolved to concrete versions) and in compiled dist/ artifacts.
  2. publishConfig.exports swap: the packed tarball's exports map has . pointing at the built promise wrapper bundle and ./core pointing at the Effect bundle — so published consumers get promise-by-default while dev still sees Effect-by-default.

Both transformations are reverted after pack, so the working tree is never left in a published-shape state. @executor/api and @executor/react are left on the internal scope because they're unpublished optional peers.

Notable changes

  • New: scripts/publish-packages.ts — walks the 8 publishable package dirs, handles the scope rename + publishConfig application + bun pm pack + npm publish dance. Works around bun pm pack not substituting publishConfig.exports on its own.
  • New: src/promise.ts + src/promise-executor.ts in packages/core/sdk/ (and a matching src/promise.ts in each plugin) — hand-written promise/Effect adapter layer with Effect.tryPromise + orDie for never-error methods and typed-error passthrough for methods with tagged errors.
  • New: tsup.config.ts per publishable package, dual-entry { index: src/promise.ts, core: src/index.ts } so both bundles land in dist/.
  • Dev exports: bare @executor/sdk and bare @executor/plugin-* now point at the Effect entry (source of truth for internal code). A dev-only ./promise subpath exists for the example. The old ./core subpath is removed from dev so the working tree stays free of /core imports — the publish-time swap re-introduces it for consumers.
  • Release plumbing: .github/workflows/release.yml gains a publish-packages step. RELEASING.md documents the flow. All 8 packages bump to 0.0.1-beta.5.

Supersedes

Closes the earlier 4-branch Graphite stack: #112, #115, #116, #138.

Test plan

  • bun run build:packages — all 8 packages build to dist/
  • bun run release:publish:packages:dry-run — produces tarballs with rewritten scope + swapped exports
  • Published 0.0.1-beta.5 to npm and smoke-tested against an external project using both bare and /core entry points
  • bun run typecheck across the workspace — remaining failures are pre-existing and unrelated to this PR
  • SDK vitest suite (23/23 pass)
  • CI

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 9, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 1e30334 Apr 10 2026, 01:40 AM

Undoes the earlier core/sdk package split and ships a single
@executor-js/sdk with two subpath entry points, matching the plugin
layout:

- @executor-js/sdk          → promise-based wrapper (default import)
- @executor-js/sdk/core     → raw Effect-based primitives

Internally the packages stay under `@executor/*` (workspace scope).
scripts/publish-packages.ts rewrites the scope to `@executor-js/*` at
pack time — in both package.json (name, deps, peer deps) and the
compiled dist/ artifacts — and resolves `workspace:*` dep specifiers
to concrete versions before pack. This keeps the diff vs main small,
and `@executor/api` / `@executor/react` (unpublished optional peers)
are left alone so source code and the workspace graph are unchanged.

The promise wrapper (src/promise.ts + src/promise-executor.ts) lives
alongside the Effect sources in packages/core/sdk/src/, so for that
directory the only new files are the two wrappers — no renames vs main.
tsup builds a dual-entry bundle
({ index: src/promise.ts, core: src/index.ts }) and publishConfig
rewrites exports to point at the packed dist/ at publish time.

Also:
- Add scripts/publish-packages.ts. Works around bun pm pack not
  substituting publishConfig overrides by rewriting package.json in
  place during pack and restoring it after.
- Remove the separate packages/core/core package and the
  packages/published/ folder that the earlier stack introduced.
- Bump all 8 publishable packages to 0.0.1-beta.4.
- add optional tools/sources/secrets/policies to promise ExecutorConfig,
  adapting user-supplied promise-shaped impls into Effect services
- fix onepassword promise entry to export onepasswordPlugin (was types-only)
- rewrite plugin READMEs to lead with async/await, demote Effect to a
  "Using with Effect" aside rather than an "Effect entry point" lead
- bump 8 public packages to 0.0.1-beta.5
Rewires dev exports so internal code treats @executor/sdk (and the 7
plugin packages) as normal packages: bare imports resolve to the
Effect-based entry, no more /core subpath gymnastics in the source.

- @executor/sdk dev exports: `.` -> src/index.ts (Effect),
  `./promise` -> src/promise.ts. publishConfig unchanged, so the
  published package still ships `.` as the promise wrapper and
  `./core` as the raw Effect primitives.
- 7 plugin packages follow the same pattern: dev `.` now points at
  the plugin's Effect entry, `./promise` added, `./core` dropped.
  publishConfigs unchanged.
- Rewrote 82 `@executor/sdk/core` imports and 9 `@executor/plugin-*/core`
  imports to bare paths across packages, apps, and READMEs.
- examples/promise-sdk imports from `/promise` subpaths since dev
  bare is now Effect. Published consumers still get the promise API
  at the bare path via the publishConfig swap at pack time.

No changes to scripts/publish-packages.ts or tsup configs — the
existing publish-time exports override is what flips dev's
bare-Effect into published bare-promise.
@RhysSullivan RhysSullivan changed the title consolidate @executor-js/core + @executor-js/sdk into one package Ship @executor-js/* beta from monorepo with promise wrapper Apr 10, 2026
@RhysSullivan
RhysSullivan merged commit 36a79e6 into main Apr 10, 2026
2 checks passed
RhysSullivan added a commit that referenced this pull request May 31, 2026
* consolidate @executor-js/core + @executor-js/sdk into one package

Undoes the earlier core/sdk package split and ships a single
@executor-js/sdk with two subpath entry points, matching the plugin
layout:

- @executor-js/sdk          → promise-based wrapper (default import)
- @executor-js/sdk/core     → raw Effect-based primitives

Internally the packages stay under `@executor/*` (workspace scope).
scripts/publish-packages.ts rewrites the scope to `@executor-js/*` at
pack time — in both package.json (name, deps, peer deps) and the
compiled dist/ artifacts — and resolves `workspace:*` dep specifiers
to concrete versions before pack. This keeps the diff vs main small,
and `@executor/api` / `@executor/react` (unpublished optional peers)
are left alone so source code and the workspace graph are unchanged.

The promise wrapper (src/promise.ts + src/promise-executor.ts) lives
alongside the Effect sources in packages/core/sdk/src/, so for that
directory the only new files are the two wrappers — no renames vs main.
tsup builds a dual-entry bundle
({ index: src/promise.ts, core: src/index.ts }) and publishConfig
rewrites exports to point at the packed dist/ at publish time.

Also:
- Add scripts/publish-packages.ts. Works around bun pm pack not
  substituting publishConfig overrides by rewriting package.json in
  place during pack and restoring it after.
- Remove the separate packages/core/core package and the
  packages/published/ folder that the earlier stack introduced.
- Bump all 8 publishable packages to 0.0.1-beta.4.

* expose pluggable storage on promise createExecutor, refresh READMEs

- add optional tools/sources/secrets/policies to promise ExecutorConfig,
  adapting user-supplied promise-shaped impls into Effect services
- fix onepassword promise entry to export onepasswordPlugin (was types-only)
- rewrite plugin READMEs to lead with async/await, demote Effect to a
  "Using with Effect" aside rather than an "Effect entry point" lead
- bump 8 public packages to 0.0.1-beta.5

* Drop /core subpath; internal imports use bare @executor/sdk

Rewires dev exports so internal code treats @executor/sdk (and the 7
plugin packages) as normal packages: bare imports resolve to the
Effect-based entry, no more /core subpath gymnastics in the source.

- @executor/sdk dev exports: `.` -> src/index.ts (Effect),
  `./promise` -> src/promise.ts. publishConfig unchanged, so the
  published package still ships `.` as the promise wrapper and
  `./core` as the raw Effect primitives.
- 7 plugin packages follow the same pattern: dev `.` now points at
  the plugin's Effect entry, `./promise` added, `./core` dropped.
  publishConfigs unchanged.
- Rewrote 82 `@executor/sdk/core` imports and 9 `@executor/plugin-*/core`
  imports to bare paths across packages, apps, and READMEs.
- examples/promise-sdk imports from `/promise` subpaths since dev
  bare is now Effect. Published consumers still get the promise API
  at the bare path via the publishConfig swap at pack time.

No changes to scripts/publish-packages.ts or tsup configs — the
existing publish-time exports override is what flips dev's
bare-Effect into published bare-promise.

* fix unused import
@RhysSullivan
RhysSullivan deleted the sdk-consolidation branch June 11, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant