Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6e768da
Send a default User-Agent on remote MCP requests (#2254)
RhysSullivan Oct 10, 2026
9fa93c2
Test the default MCP User-Agent (#2255)
RhysSullivan Oct 10, 2026
8e4a8a4
Send the default User-Agent on the MCP endpoint probe (#2258)
RhysSullivan Oct 10, 2026
a54b513
Test the MCP probe User-Agent (#2259)
RhysSullivan Oct 10, 2026
90e415c
Link eligible orgs to Executor v2's import from the sidebar (#2266)
RhysSullivan Oct 12, 2026
2da6542
Test the v2 import sidebar link (#2267)
RhysSullivan Oct 12, 2026
49bd295
Tell users when their organization has moved to Executor v2 (#2269)
RhysSullivan Oct 12, 2026
6682324
Test the moved-to-v2 notice (#2270)
RhysSullivan Oct 12, 2026
a1274eb
Keep the v2 moved notice inside its dialog for long organization name…
RhysSullivan Oct 12, 2026
906bee5
Check a long organization name stays inside the v2 moved notice (#2280)
RhysSullivan Oct 12, 2026
9ac276e
Build the self-host image on Bun 1.4.4 for the Brotli decoder fix (CV…
RobertoVillegas Oct 22, 2026
4c753d3
Version Packages (#2336)
RhysSullivan Oct 22, 2026
4998ad0
Forward MCP requests of organizations moved to v2 (#2287)
RhysSullivan Oct 23, 2026
fb8f45a
Freeze organizations moving to v2 (#2337)
RhysSullivan Oct 23, 2026
4b9869f
Test the freeze of organizations moving to v2 (#2338)
RhysSullivan Oct 23, 2026
b0d1089
Hand a moved workspace's signed-in member to v2 with a signed token (…
RhysSullivan Oct 23, 2026
7957647
Test the v2 session handoff redirect (#2357)
RhysSullivan Oct 23, 2026
f08d88d
Forward passthrough MCP requests of moved organizations to v2 (#2388)
RhysSullivan Oct 25, 2026
12ffa47
Test forwarding passthrough MCP requests to v2 (#2389)
RhysSullivan Oct 25, 2026
bfc9152
Keep the cloud e2e worker off the production PostHog project (#2394)
RhysSullivan Oct 25, 2026
10f40d1
Give the cap-eviction scenario an idle window it can cross the cap in…
RhysSullivan Oct 25, 2026
dc3eac8
Keep the admin MFA rate-limit burst inside one limiter window (#2396)
RhysSullivan Oct 25, 2026
083209a
Answer not found for requests that land mid-destroy on an MCP session…
RhysSullivan Oct 25, 2026
9dd64da
Test a request landing after destroy wiped an MCP session's storage (…
RhysSullivan Oct 25, 2026
56aec8b
Keep DCR OAuth requests within the client's registered scopes (#2402)
RhysSullivan Oct 27, 2026
3cf6e54
Test DCR registered-scope reuse and start narrowing (#2403)
RhysSullivan Oct 27, 2026
e988b63
Merge remote-tracking branch 'upstream/main' into sync-upstream-20261…
github-actions[bot] Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/account-scoped-tool-policies.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/connection-oauth-default.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/cross-session-resume-org-write.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/dcr-registered-scopes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@executor-js/sdk": patch
---

Keep OAuth requests within the scopes a dynamically registered client was registered for. DCR clients now persist the scopes their registration asked for (`oauth_client.origin_requested_scopes`) and the scopes the server registered, from the registration response (`oauth_client.origin_scopes`, RFC 7591 §3.2.1). Reuse picks a client only when its registration covers the requested scopes, so reconnecting after a server adds scopes registers a new client instead of pairing the old one with scopes the server refuses with `invalid_scope`. `oauth.start` narrows discovered scopes to the server-registered set and fails with a clear error when declared scopes fall outside it. Clients registered before this release have no recorded scopes and are registered again on their next connect; existing connections keep refreshing through them.
5 changes: 0 additions & 5 deletions .changeset/fair-admin-integrations.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/mcp-destroy-stale-session-meta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@executor-js/cloud": patch
---

An MCP request that reaches a session while the session is being torn down now gets the "Session not found" protocol error instead of a 500.
5 changes: 0 additions & 5 deletions .changeset/oauth-discovered-scope-budget.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/organization-settings-verification.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/quiet-connection-setup.md

This file was deleted.

6 changes: 0 additions & 6 deletions .changeset/toolkit-list-scope.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/trusted-oauth-token-regions.md

This file was deleted.

7 changes: 7 additions & 0 deletions .changeset/v1-move-freeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@executor-js/sdk": patch
"@executor-js/api": patch
"@executor-js/cloud": patch
---

Hosts can pause every change to a workspace with `workspaceWriteGate`: connection and OAuth writes, OAuth completion (before the code is exchanged) and OAuth token refreshes are refused with the host's message, while reads and tool calls keep working. The OAuth callback popup now shows why a refusal the user can act on happened. Executor Cloud uses this to freeze an organization while it moves to Executor v2, refuses changes to it once it has moved, and opens a moved organization's dashboard in v2.
5 changes: 5 additions & 0 deletions .changeset/v2-forward-passthrough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@executor-js/cloud": patch
---

Executor Cloud forwards MCP requests that use `mode=passthrough` for a workspace that has moved to Executor v2, instead of refusing them. v2 serves its own tools for them.
5 changes: 5 additions & 0 deletions .changeset/v2-session-handoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@executor-js/cloud": patch
---

Executor Cloud hands a signed-in member of a workspace that has moved to Executor v2 to v2 with a short-lived signed token, so v2 opens the workspace without asking them to sign in again. It is off until `V2_SESSION_HANDOFF_SECRET` is set.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ jobs:
- name: Run cloud shard
if: matrix.target == 'cloud'
env:
MCP_SESSION_TIMEOUT_MS: "3000"
# Long enough for the cap-eviction scenario to hold more sessions
# resident than the e2e cap (see e2e/setup/resident-runtime-cap.ts).
MCP_SESSION_TIMEOUT_MS: "8000"
# Still 18x shorter than production, but long enough for a cold Vite
# resume route to compile under a fully loaded CI runner.
MCP_PAUSED_SESSION_IDLE_TIMEOUT_MS: "30000"
Expand Down
18 changes: 18 additions & 0 deletions apps/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# executor

## 1.6.11

### Patch Changes

- [#2066](https://github.com/UsefulSoftwareCo/executor/pull/2066) [`c6d1083`](https://github.com/UsefulSoftwareCo/executor/commit/c6d10838f741ece700922fb2469782f79753b7f7) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Prefer browser sign-in when a matching OAuth client is available, while preserving a user’s chosen method when clients finish loading.

- [#2254](https://github.com/UsefulSoftwareCo/executor/pull/2254) [`6e768da`](https://github.com/UsefulSoftwareCo/executor/commit/6e768da9dad13c7c469d2c2071bf542157f1033c) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Send a default User-Agent on remote MCP requests so servers that reject requests without one accept the connection. A configured User-Agent header still wins.

- [#2258](https://github.com/UsefulSoftwareCo/executor/pull/2258) [`8e4a8a4`](https://github.com/UsefulSoftwareCo/executor/commit/8e4a8a40048e8252f4d7f182456da62ca1d5c296) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Send the default User-Agent on the MCP endpoint probe and its OAuth metadata request too, so adding a server that rejects requests without one no longer fails. A configured User-Agent still wins.

- [#2050](https://github.com/UsefulSoftwareCo/executor/pull/2050) [`24adb12`](https://github.com/UsefulSoftwareCo/executor/commit/24adb127f304e2b145b462c3805a9e11b2a524e0) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Accept Slack bot and user OAuth token envelopes during sign-in and token refresh.

- Updated dependencies [[`2e5aa16`](https://github.com/UsefulSoftwareCo/executor/commit/2e5aa16bedb4ba74448b3f9338754764b40519a0), [`4a08d8d`](https://github.com/UsefulSoftwareCo/executor/commit/4a08d8db6f74612e07f17494e222ff038d8af944), [`c03c9ad`](https://github.com/UsefulSoftwareCo/executor/commit/c03c9adc1fcd4a3f2b0a839878f7310f5fc835b4)]:
- @executor-js/sdk@1.6.11
- @executor-js/local@1.6.11
- @executor-js/api@1.4.74
- @executor-js/runtime-quickjs@1.6.11

## 1.6.10

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "executor",
"version": "1.6.10",
"version": "1.6.11",
"private": true,
"bin": {
"executor": "./bin/executor.ts"
Expand Down
29 changes: 29 additions & 0 deletions apps/cloud/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# @executor-js/cloud

## 1.4.72

### Patch Changes

- [#2099](https://github.com/UsefulSoftwareCo/executor/pull/2099) [`9e143d9`](https://github.com/UsefulSoftwareCo/executor/commit/9e143d99c28f4c26d9e2cb1b136658048fecd3cb) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - An admin who resumes a paused execution from a different MCP session (for example after the client reconnects) keeps workspace-write access. The forwarded resume now carries the requester's access to the session that owns the execution, so a pending `addServer`, `addSpec`, or similar write no longer fails with `org_write_denied`.

- [#2119](https://github.com/UsefulSoftwareCo/executor/pull/2119) [`4a52307`](https://github.com/UsefulSoftwareCo/executor/commit/4a52307c0bdc7606107c22e15574c24d0254777c) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Require authenticator verification for organization settings while preserving shared workspace reads and API-key access.

- [#2266](https://github.com/UsefulSoftwareCo/executor/pull/2266) [`90e415c`](https://github.com/UsefulSoftwareCo/executor/commit/90e415c98c5414e019695e8501439755a8bc838a) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Link eligible single-member free organizations to Executor v2's workspace import from the sidebar.

- [#2269](https://github.com/UsefulSoftwareCo/executor/pull/2269) [`49bd295`](https://github.com/UsefulSoftwareCo/executor/commit/49bd2959b4dd203b2a413304f7b3d4d5238d50a4) Thanks [@RhysSullivan](https://github.com/RhysSullivan)! - Tell users when their organization has moved to Executor v2, with a link to it in v2 and a way to say why they are staying on v1.

- Updated dependencies [[`29413d8`](https://github.com/UsefulSoftwareCo/executor/commit/29413d8dafaeabfd9b9f10e5fddd1f5b735ffa30), [`31b24b8`](https://github.com/UsefulSoftwareCo/executor/commit/31b24b8564899b137106baf28f66fb3f15c33633), [`2e5aa16`](https://github.com/UsefulSoftwareCo/executor/commit/2e5aa16bedb4ba74448b3f9338754764b40519a0), [`4a08d8d`](https://github.com/UsefulSoftwareCo/executor/commit/4a08d8db6f74612e07f17494e222ff038d8af944), [`c03c9ad`](https://github.com/UsefulSoftwareCo/executor/commit/c03c9adc1fcd4a3f2b0a839878f7310f5fc835b4)]:
- @executor-js/react@1.4.74
- @executor-js/sdk@1.6.11
- @executor-js/plugin-toolkits@1.5.46
- @executor-js/mcp-apps-shell@1.4.22
- @executor-js/plugin-graphql@1.6.11
- @executor-js/plugin-mcp@1.6.11
- @executor-js/plugin-openapi@1.6.11
- @executor-js/plugin-workos-vault@0.0.2
- @executor-js/api@1.4.74
- @executor-js/execution@1.6.11
- @executor-js/vite-plugin@0.0.71
- @executor-js/cloudflare@0.0.53
- @executor-js/host-mcp@1.4.4
- @executor-js/runtime-dynamic-worker@1.4.4
- @executor-js/runtime-quickjs@1.6.11

## 1.4.71

### Patch Changes
Expand Down
9 changes: 9 additions & 0 deletions apps/cloud/drizzle/0021_org_moved_to_v2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE "org_moved_to_v2" (
"org_id" text PRIMARY KEY NOT NULL,
"state" text NOT NULL,
"v2_org_id" text,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "org_moved_to_v2_state_check" CHECK ("org_moved_to_v2"."state" in ('moving', 'moved'))
);
--> statement-breakpoint
ALTER TABLE "org_moved_to_v2" ADD CONSTRAINT "org_moved_to_v2_org_id_organizations_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;
32 changes: 32 additions & 0 deletions apps/cloud/drizzle/0022_org_moved_to_v2_slug.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-- `org_moved_to_v2` gains the v2 organization's slug (v2 writes it with
-- `moved`; the v1 dashboard redirects to `/org/<slug>` on v2) and a third
-- state, `rolled_back` (v2 gave the organization back; v1 serves it as if
-- there were no row). The constraint swap is safe online: the table holds at
-- most one row per organization that started a move.
ALTER TABLE "org_moved_to_v2" DROP CONSTRAINT "org_moved_to_v2_state_check";--> statement-breakpoint
ALTER TABLE "org_moved_to_v2" ADD COLUMN "v2_org_slug" text;--> statement-breakpoint
ALTER TABLE "org_moved_to_v2" ADD CONSTRAINT "org_moved_to_v2_state_check" CHECK ("org_moved_to_v2"."state" in ('moving', 'moved', 'rolled_back'));--> statement-breakpoint
-- v2 writes this table as `v1_import_writer`, with
-- INSERT INTO org_moved_to_v2 (org_id, state, v2_org_id, v2_org_slug) VALUES (...)
-- ON CONFLICT (org_id) DO UPDATE SET state = excluded.state,
-- v2_org_id = excluded.v2_org_id, v2_org_slug = excluded.v2_org_slug
-- which needs INSERT and UPDATE on the table and SELECT on the columns the
-- upsert names (the conflict target and the `excluded` reads). It gets nothing
-- else: no DELETE, no SELECT of `updated_at`, nothing on any other table, and
-- only USAGE on the schema, which PlanetScale does not give PUBLIC.
--
-- The grant runs only when the role already exists. When the role is created
-- after this migration has run, run these three statements once, after
-- `CREATE ROLE v1_import_writer ...`:
-- GRANT USAGE ON SCHEMA public TO v1_import_writer;
-- GRANT INSERT, UPDATE ON org_moved_to_v2 TO v1_import_writer;
-- GRANT SELECT (org_id, state, v2_org_id, v2_org_slug) ON org_moved_to_v2 TO v1_import_writer;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'v1_import_writer') THEN
-- PlanetScale gives PUBLIC no USAGE on `public`, so the role needs its own.
GRANT USAGE ON SCHEMA public TO v1_import_writer;
GRANT INSERT, UPDATE ON org_moved_to_v2 TO v1_import_writer;
GRANT SELECT (org_id, state, v2_org_id, v2_org_slug) ON org_moved_to_v2 TO v1_import_writer;
END IF;
END $$;
2 changes: 2 additions & 0 deletions apps/cloud/drizzle/0023_wild_gwen_stacy.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE "oauth_client" ADD COLUMN "origin_requested_scopes" text;--> statement-breakpoint
ALTER TABLE "oauth_client" ADD COLUMN "origin_scopes" text;
Loading