Version Packages - #1743
Open
RhysSullivan wants to merge 1 commit into
Open
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | c043a94 | Aug 28 2026, 04:44 AM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | c043a94 | Commit Preview URL Branch Preview URL |
Aug 28 2026, 04:43 AM |
RhysSullivan
force-pushed
the
changeset-release/main
branch
from
August 25, 2026 21:15
aae3e4d to
7832eb0
Compare
Contributor
Cloudflare preview
Sign-in is Cloudflare Access (one-time PIN to an allowed email). The preview has its own database and encryption key; it is destroyed when this PR closes. |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
RhysSullivan
force-pushed
the
changeset-release/main
branch
25 times, most recently
from
August 28, 2026 01:29
cceee22 to
1755c45
Compare
RhysSullivan
force-pushed
the
changeset-release/main
branch
22 times, most recently
from
August 28, 2026 04:14
4ab210a to
528a7e8
Compare
RhysSullivan
force-pushed
the
changeset-release/main
branch
from
August 28, 2026 04:42
528a7e8 to
c043a94
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@executor-js/cli@0.2.51
Patch Changes
55180cb]:@executor-js/config@1.6.1
Patch Changes
55180cb]:@executor-js/execution@1.6.1
Patch Changes
#1741
62748e8Thanks @RhysSullivan! - Opt-in per-integration search tools on the MCP surfaceConnecting with
?search_tools=true(stdio:executor mcp --search-tools) adds one minimally-describedsearch_<integration>MCP tool per connected integration, so the integration namespaces reach the model as tool names it can see without calling anything. Each call routes through the same flow astools.search({ namespace })insideexecute, and the tool list comes from the same inventory theexecutedescription shows. Off by default; a clean endpoint URL is unchanged.#1749
d4afe0cThanks @RhysSullivan! - Slim the per-integrationsearch_<integration>tool definitions to under half their size: one shared one-line description (the tool name already carries the namespace) and a single barequeryparameter, dropping thelimit/offsetknobs. A session pays for these definitions once per connected integration, so the surface now costs ~2k tokens instead of ~5k at 30 integrations; paging through a namespace belongs inexecute.Updated dependencies [
55180cb]:@executor-js/sdk@1.6.1
Patch Changes
#1784
55180cbThanks @RhysSullivan! - BuildStorageError.messagefrom the call-site label plus the driver's error code instead of the driver's raw text. The driver text is drizzle'sFailed query: <sql>\nparams: <bound values>, so error reporting grouped one storage defect by statement shape and printed bound parameters into issue titles. The full driver error stays oncause.Add
StorageConnectionError, aStorageFailurevariant for postgres.js connection faults (CONNECTION_ENDED,CONNECTION_CLOSED,CONNECTION_DESTROYED,CONNECT_TIMEOUT,ECONNREFUSED,ECONNRESET) and workerd's cross-request I/O rejection. It carries the faultcodeand aretryableflag so a lost socket can be told apart from a pool-lifetime bug.@executor-js/vite-plugin@0.0.61
Patch Changes
55180cb]:@executor-js/runtime-quickjs@1.6.1
Patch Changes
@executor-js/plugin-desktop-settings@1.6.1
Patch Changes
55180cb]:@executor-js/plugin-example@1.6.1
Patch Changes
55180cb]:@executor-js/plugin-file-secrets@1.6.1
Patch Changes
55180cb]:@executor-js/plugin-graphql@1.6.1
Patch Changes
9dff4e8,55180cb]:@executor-js/plugin-keychain@1.6.1
Patch Changes
55180cb]:@executor-js/plugin-mcp@1.6.1
Patch Changes
#1747
91062c2Thanks @RhysSullivan! - Load the MCP client SDK lazily on first outbound connection instead of at module evaluation. Runtimes that bundle the plugin (notably Cloudflare Workers) no longer pay the client package's module-eval memory and CPU on startup or on code paths that never dial an MCP server.#1716
9c35f26Thanks @xav-ie! - Closing a remote MCP connection now ends its streamable-http SSE requestOn a supplied
httpClientLayer, the fetch adapter wired the caller'sAbortSignalonly to the pending response promise, never to the response body, so closing a connection left the long-livedGETchannel in flight forever — one abandoned request per dial. Under Bun each holds one of the 256 concurrent-request slots, so a long-running process eventually exhausts the pool and every connection starts failing withMCP discovery timed out after 15000ms. The response stream is now interrupted when the signal aborts.Updated dependencies [
9dff4e8,55180cb]:@executor-js/plugin-onepassword@1.6.1
Patch Changes
9dff4e8,55180cb]:@executor-js/plugin-openapi@1.6.1
Patch Changes
#1755
7c12aeeThanks @RhysSullivan! - Make Microsoft Graph slice URLs first-class spec sources instead of a hidden substitution. Catalog tiles now point directly at the slice release assets, the stored specUrl is exactly what gets fetched, and selection narrowing travels visibly in the URL fragment; requesting the upstream monolith URL fetches the monolith, never a silently swapped slice.#1753
ddbf0feThanks @RhysSullivan! - Serve Microsoft Graph preset selections from precomputed slice release assets instead of the 43MB upstream monolith. The monolith fetch almost never survives a 128MB Workers isolate (production traces show one completion in 30 days), so covered selections — every catalog preset, plus any combination within the default bundle — now read a 4–19MB filtered document built offline by the graph-slices workflow, with the monolith path kept only as a fallback and for full-graph/custom-scope selections.#1751
0007474Thanks @RhysSullivan! - Preview OpenAPI spec-format selections (Microsoft Graph) through the streaming structural-split path instead of a whole-document parse, and guard generic whole-document parses by parsed-tree size (line count for block YAML, text size for JSON). Previewing a Graph preset URL previously parsed the 43MB source whole and killed the 128MB Workers isolate mid-request, surfacing as an empty 503; it now streams within budget, and oversized generic specs fail with an actionable error instead of taking down the isolate.Updated dependencies [
9dff4e8,55180cb]:@executor-js/plugin-toolkits@1.5.36
Patch Changes
9dff4e8,55180cb]:@executor-js/codemode-core@1.6.1
executor@1.6.1
Patch Changes
#1576
6535a74Thanks @GeiserX! - The CLI's server-connection store is written owner-only, and two of its tests now actually run~/.executor/server-connections.jsonholds live credentials for a hosted server — a bearer token, or an OAuth access token together with its long-lived refresh token, rewritten on every silent refresh. It was created with no explicit mode, so the process umask applied and it landed world-readable (0644 by default). Any other account on the machine — or anything that copies a home directory, such as a backup or a container layer — could read a durable credential until the user ranexecutor logout.It is now created
0600with a follow-upchmod, matching what the local-server manifest already does for the sibling secret it keeps underserver-control/. Both steps are needed:modeapplies only on create, and thechmodcovers rewriting a store that already exists with looser permissions — which is the common path here, since the file is rewritten on every token refresh.Separately, two tests in
server-profile.test.tswere written asit("…", () => Effect.gen(…)). AnEffectis not a thenable, so Vitest treated each as passing without ever running its body — a deliberately falsified assertion still passed. They are nowit.effectand execute for real. No production behaviour was wrong; the tests simply were not checking it.#1454
e8ea62cThanks @jadch! - Prevent concurrent SQLite data-migration runners from failing when another runner commits the same ledger stamp first.#1579
31e17c7Thanks @GeiserX! - The desktop settings store is written owner-onlysettings.jsonholdsserverProfiles, which carries a remote server's credential — a bearer token, or a basic-auth username and password — for any "Custom server" the user connects to.conf(under electron-store) defaults toconfigFileMode: 0o666, so with no explicit mode the file was created0644. On Linux, where~/.configis not reliably0700, that is readable by every other account on the machine. macOS is protected by~/Librarybeing0700and Windows by ACLs, so this is primarily a Linux-desktop exposure — but owner-only credential files are already this app's standard:local-auth.tswritesauth.jsonat0o600, and the sidecar manifest is chmodded the same way.One option is sufficient here, rather than the mode-plus-chmod pair used elsewhere:
atomicallychmods the temp inode only when the requested mode differs from its own default, and the atomic rename then carries the tight mode onto an already-loose file. Verified against the installedconf— with no option a fresh file lands0644; withconfigFileMode: 0o600a fresh file lands0600and an existing0644file becomes0600on the next write.#1582
e8e97c4Thanks @GeiserX! - An MCP health check no longer reportshealthywhen the connection's credential is missingRendering skips an auth placement whose value is unresolved — that is the renderer's documented behaviour, and callers own the missing-value policy. The MCP health check had no such policy, so it dialled unauthenticated, and any server that lists tools without auth answered.
discoverToolssucceeding maps straight tohealthy, so a connection whose credential was gone reported as healthy.Health status is the signal telling a user to re-authenticate, which makes
healthythe one answer it must never give in that state. The check now reportsexpiredwith the unresolved input names, mirroring the OpenAPI health check, which already did exactly this.The MCP tool-invocation path already refused for the same reason.
resolveToolsis deliberately left alone — its own comment records that discovery tolerating unresolved credentials is intended, since an open server lists tools unauthenticated.#1741
62748e8Thanks @RhysSullivan! - Opt-in per-integration search tools on the MCP surfaceConnecting with
?search_tools=true(stdio:executor mcp --search-tools) adds one minimally-describedsearch_<integration>MCP tool per connected integration, so the integration namespaces reach the model as tool names it can see without calling anything. Each call routes through the same flow astools.search({ namespace })insideexecute, and the tool list comes from the same inventory theexecutedescription shows. Off by default; a clean endpoint URL is unchanged.#1573
45ba141Thanks @GeiserX! - The MCP connection pool no longer keeps credentials in its cache keyA pooled remote MCP session is looked up by a key describing the connection's identity, and that key included the connection's resolved credential values — plus the headers and query params those same secrets had already been rendered into. The key is retained as a
Mapkey for the pool's lifetime, so the secret stayed readable in process memory long after the call that needed it had finished, with nothing left to read it.The key is now the SHA-256 digest of that identity rather than the identity itself. Reuse is unchanged, because equal identities still produce equal keys, and separation is unchanged too: a rotated access token, a different rendered auth header and a credential carried in a query param each still dial a fresh session instead of reusing one authenticated as somebody else. Hashing the whole identity rather than only the fields known to be sensitive means a field added later is covered without anyone having to remember it carries a secret.
Nothing reads the key back — the pool only compares it, and it reaches no log, span or error message — so nothing observable changes.
#1800
eac13e7Thanks @RhysSullivan! - Idle MCP session runtimes are actually reclaimedThe MCP session Durable Object has an idle timeout that disposes a session's execution runtime — the execution engine and its executor closure, the built tool catalog, and a live database handle — once the session has gone quiet. That timeout never ran.
The session arms an idle alarm on every request. The agents framework independently recomputes the Durable Object alarm from its own schedule table and keep-alive refcount, and when it finds neither it does not leave the alarm alone: it deletes it. It releases the last keep-alive reference at the end of every ordinary tool call, from a
waitUntilthat runs just after the response goes out — so the idle alarm the session had armed moments earlier was erased, and a session that had just served a request was left with no alarm at all. Its runtime then stayed resident until the platform evicted the whole object.Durable Objects are colocated many-to-one onto an isolate with a single heap, so runtimes that are never reclaimed accumulate there. When the heap is exhausted the allocation that fails is whichever comes next, anywhere in the isolate — which is why the failure tended to surface from storage rather than from the runtimes that had consumed the memory.
The idle deadline belongs to the session, not to the framework's scheduler, so it is now re-asserted after the framework has arranged whatever it needs — and only while a runtime is actually resident, since once there is nothing left to reclaim the framework's answer is correct.
Disposal also now emits a span carrying a per-isolate resident-runtime gauge, alongside the same gauge on runtime build, so the reclaim can be confirmed in production rather than inferred.
#1609
662ebe2Thanks @timkley! - Fix: declare the OAuth application type during dynamic client registrationDynamic OAuth registrations now identify HTTPS callbacks as web applications
and loopback HTTP callbacks as native applications. This lets strict OAuth
servers validate Executor's redirect URI against the correct client type.
#1570
e66a3d8Thanks @GeiserX! - The OAuth popup clears its result out oflocalStorageafter handing it overThe popup writes its result to
localStorageas the fallback completion channel, becausepostMessageis severed when a provider's consent page sets COOP andBroadcastChannelcan be partitioned or raced by the auto-close. Nothing removed that entry afterwards, so the payload — which carries the identity label, an email, and on failure the error preview — stayed parked in the user's browser profile.The entry is now cleared once the handover has had time to land, and on
pagehideas a backstop — the failure page never auto-closes so the user can read the error, and closing it by hand would otherwise cancel the pending timer and strand the entry. This cannot cost a listener the result: astorageevent capturesnewValueat dispatch, so an opener that has been notified already holds it.#1574
c8bb857Thanks @GeiserX! - The 1Password service-account token is cleared from the op-js global after each call@1password/op-jskeeps the service-account token on a module-level CLI instance (cli.serviceAccountToken) and reads it when it spawnsop. The CLI backend set that global before each call and never cleared it, so one reachable reference to the token stayed live for the rest of the process.It is now cleared as soon as the call that needed it is done, on success, failure and interruption alike. Authentication is unaffected: every read and write of that global already happens inside the backend's semaphore, so the next operation re-sets the token before it spawns anything.
This is hygiene rather than a boundary change. No unrelated
opchild ever received a stale token — every call routes through the same critical section that sets the correct one immediately before invoking — and the token is separately persisted in plaintext in the plugin's config blob, so an attacker's reach is unchanged. What it removes is a long-lived reachable reference that nothing needed to keep.#1749
d4afe0cThanks @RhysSullivan! - Slim the per-integrationsearch_<integration>tool definitions to under half their size: one shared one-line description (the tool name already carries the namespace) and a single barequeryparameter, dropping thelimit/offsetknobs. A session pays for these definitions once per connected integration, so the surface now costs ~2k tokens instead of ~5k at 30 integrations; paging through a namespace belongs inexecute.#1798
69b0e64Thanks @RhysSullivan! - The packed Worker toolchain is verified at build time, and an incomplete copy is now reported instead of silently ignored@cloudflare/worker-bundlercannot live inside the compiled binary: bunfs has nonode_modules, so a bare specifier is unresolvable there by construction. The build instead copies the package'sdist/next to the executable andnative-bindings.tspublishes that path asEXECUTOR_WORKER_BUNDLER_DIRfor consumers to load from.That handoff was described in two places that were free to drift, and did. The build writes
dist/index.bundled.js— the entry consumers actually load, packed so it has no bare imports of its own — while the runtime check only looked fordist/index.jsanddist/esbuild.wasm. Nothing verified the staged copy after the compile, so a partial staging produced a binary that looked fine on the build machine and failed on the user's, at startup. Worse, the runtime check failed open: when a file was missing it silently declined to set the environment variable, leaving a consumer to fall through to the bare specifier and crash.The required file list is now one shared contract used by both sides, so they cannot disagree. The build asserts the staged copy after compiling each target — every required file present, a size floor on the packed entry, and the
\0asmmagic on the wasm so a truncated copy cannot pass — turning a packaging slip into a failed build rather than a broken install. At runtime, a directory that is present but incomplete is reported on stderr naming the missing files, instead of being swallowed. An absent directory stays quiet, since that is the normal non-packaged path.Updated dependencies [
55180cb]:@executor-js/cloud@1.4.62
Patch Changes
9dff4e8,7c12aee,ddbf0fe,91062c2,9c35f26,62748e8,0007474,d4afe0c,55180cb]:@executor-js/host-selfhost@0.0.43
Patch Changes
9dff4e8,7c12aee,ddbf0fe,91062c2,9c35f26,62748e8,0007474,d4afe0c,55180cb]:@executor-js/local@1.6.1
Patch Changes
9dff4e8,7c12aee,ddbf0fe,91062c2,9c35f26,62748e8,0007474,d4afe0c,55180cb]:@executor-js/e2e@0.0.41
Patch Changes
7c12aee,ddbf0fe,91062c2,9c35f26,0007474,55180cb]:@executor-js/example-all-plugins@0.0.62
Patch Changes
7c12aee,ddbf0fe,91062c2,9c35f26,0007474,55180cb]:@executor-js/example-docs-sdk-quickstart@0.0.47
Patch Changes
7c12aee,ddbf0fe,0007474,55180cb]:@executor-js/analytics@0.1.8
Patch Changes
62748e8,d4afe0c]:@executor-js/api@1.4.64
Patch Changes
#1784
55180cbThanks @RhysSullivan! - BuildStorageError.messagefrom the call-site label plus the driver's error code instead of the driver's raw text. The driver text is drizzle'sFailed query: <sql>\nparams: <bound values>, so error reporting grouped one storage defect by statement shape and printed bound parameters into issue titles. The full driver error stays oncause.Add
StorageConnectionError, aStorageFailurevariant for postgres.js connection faults (CONNECTION_ENDED,CONNECTION_CLOSED,CONNECTION_DESTROYED,CONNECT_TIMEOUT,ECONNREFUSED,ECONNRESET) and workerd's cross-request I/O rejection. It carries the faultcodeand aretryableflag so a lost socket can be told apart from a pool-lifetime bug.Updated dependencies [
62748e8,d4afe0c,55180cb]:@executor-js/cloudflare@0.0.43
Patch Changes
62748e8,d4afe0c,55180cb]:@executor-js/mcp-apps-shell@1.4.12
Patch Changes
9dff4e8]:@executor-js/runtime-workerd-subprocess@0.0.16
Patch Changes
@executor-js/plugin-encrypted-secrets@0.0.43
Patch Changes
55180cb]:@executor-js/plugin-provider-service-split@0.0.15
Patch Changes
7c12aee,ddbf0fe,0007474,55180cb]:@executor-js/react@1.4.64
Patch Changes
#1746
9dff4e8Thanks @sergical! - The connection edit sheet now previews what agents actually readThe "What agents see" preview in the connection edit sheet rendered a
- \` —inventory line. That line left theexecutetool description when the inventory was slimmed to bare integration slugs, so the preview showed text no agent reads. The account label was also marked "Display-only", butconnections.list` returns it to agents alongside the description.The preview now mirrors the
connections.listitem for the connection (name,identityLabel,description), and the sheet copy says that both fields are agent-visible while the callable name stays as it was at connect time.Updated dependencies [
55180cb]:@executor-js/desktop@1.6.1