Skip to content

Commit 8ec80de

Browse files
authored
Merge pull request #742 from RhysSullivan/rs/release-1.4.16
Release CLI 1.4.16
2 parents 1be1b70 + 59cfe71 commit 8ec80de

2 files changed

Lines changed: 64 additions & 88 deletions

File tree

.changeset/executor-1.4.16.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"executor": patch
3+
---
4+
5+
CLI 1.4.16. See `apps/cli/release-notes/next.md` for the user-facing changelog.

apps/cli/release-notes/next.md

Lines changed: 59 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,95 @@
11
## Highlights
22

3-
### Install paths fixed
3+
### Unified credential bindings
44

5-
`npm i -g executor` and `bun i -g executor` both work cleanly on a fresh machine. For machines without node, `curl … install.sh | bash` does the same thing.
5+
Source credentials (OAuth tokens, header secrets, client-credential pairs) are now stored as **scoped credential bindings** instead of plugin-specific shapes. Two consequences for users:
66

7-
> 1.4.13 and 1.4.14 were partial releases that didn't make it to npm cleanly. If you tried `npm i -g executor@latest` and got an older version, that's why. 1.4.15 is the first complete release of the new packaging.
7+
- One consistent UI for editing credentials across OpenAPI, MCP, and GraphQL sources. The old per-plugin credential forms are gone, replaced with a shared slot UI in `@executor-js/react` (`credential-bindings`, `credential-slot-bindings`, `oauth-sign-in`).
8+
- Existing OpenAPI / MCP / GraphQL / google-discovery credentials are migrated into the new binding rows automatically on first launch (drizzle migrations `0007`, `0008`, `0010` for `apps/local`). No user action required.
89

9-
### MCP sources honor upstream `destructiveHint`
10+
### See where a secret or connection is used
1011

11-
MCP sources now read `destructiveHint` from upstream tool annotations. Tools marked destructive will require approval before running, surfaced via MCP elicitation. Refresh existing sources (or remove + re-add) to pick up annotations on tools added before this change.
12+
A new `executor.usages` surface lets plugins declare every place they reference a secret or connection. The local UI uses it to:
1213

13-
### Set tool policies from the Tools page
14+
- Show a "used in N sources / M bindings" summary on the secret detail page.
15+
- Surface a clear "this secret is in use, remove the references first" toast (backed by the new `SecretInUseError` / `ConnectionInUseError`) instead of letting the delete fail silently.
1416

15-
The local UI gains a **Policies** tab for managing approval rules, plus a per-row action menu on the Tools tree. Hover any tool or category and pick **Always run / Require approval / Block / Clear** — leaf rows save a rule for the exact tool id, group rows save a `prefix.*` wildcard. New rules are auto-placed by specificity so a freshly-added group rule never silently shadows an existing leaf rule. The same menu is available from the tool detail header and from any source-detail page.
17+
Plugin authors implement `usagesForSecret` / `usagesForConnection`; the executor fans out and concatenates.
1618

17-
### Per-user OAuth for OpenAPI and MCP sources
19+
### MCP source detection works on more servers
1820

19-
OpenAPI and MCP sources now carry first-class **Connections** — a per-user sign-in state decoupled from the source definition itself.
21+
Adding an MCP source now succeeds against servers that previously failed to probe.
2022

21-
- Save an OAuth2 OpenAPI or MCP source **before** signing in; users sign in later from the source page.
22-
- Each connection refreshes independently, with concurrent refreshes deduped across the SDK. When a refresh can't recover, the SDK surfaces an explicit `reauth-required` signal instead of silently failing.
23-
- The Edit OpenAPI Source page has a new **Connections** pane showing every user who has signed in and their status. Each source in the sidebar now shows a live connection badge.
24-
- Existing OpenAPI + MCP + google-discovery OAuth rows migrate into Connections automatically on first launch — no user action required.
23+
- Bearer-auth MCP servers are detected on the initial probe instead of being misclassified as plain HTTP. Probe error messages also tell you what shape of auth challenge came back.
24+
- 401 challenges that advertise `resource_metadata=` are recognized as MCP-spec OAuth signals.
25+
- Probes accept RFC 6750-compliant body forms for the access-token check, so servers that don't honor the `Authorization` header on the probe path still discover correctly.
26+
- A live-snapshot regression suite covers 29 real public MCP servers; new probes are checked against those snapshots before shipping.
27+
- The MCP connection pool now keys by source identity, so two MCP sources pointing at the same upstream URL with different credentials no longer collide on one shared connection.
2528

26-
### OpenAPI: client-credentials, non-JSON bodies, source refresh
29+
### TypeScript code runs in dynamic-worker and QuickJS runtimes
2730

28-
- Full **OAuth2 client-credentials** flow end-to-end.
29-
- **Non-JSON request bodies** dispatch correctly by content type; Executor honors OAS3 `encoding` and multi-content operations, and lets the caller pick which content type to send.
30-
- Relative OAuth2 URLs resolve against the source's `baseUrl`.
31-
- Refresh a source by re-fetching its origin URL from the edit page.
31+
Both runtimes strip TypeScript syntax before evaluation, so tools that pass TS source (annotations, `as` casts, type aliases, etc.) execute without a separate compile step. Previously you had to hand-strip types or precompile.
3232

33-
### Layered scope isolation
33+
### OpenAPI source UX
3434

35-
Multi-tenant deployments get a proper security primitive. Every read and write now passes through a layered `ScopeStack`, with the write scope declared explicitly. Plugins have adopted the API; the UI exposes it via `CreatableSecretPicker`; and WorkOS sources enforce tenant-ownership on every access. Per-scope blob and secret lookups are batched into single `IN` queries, so the extra check doesn't cost a round-trip.
35+
- Source-add screens reworked: cleaner flow, the freeform combobox lists the URL you typed first, scoped credential UI clarified.
36+
- OpenAPI import size limit removed — large specs (Stripe, GitHub, etc.) import without truncation.
37+
- The OpenAPI source edit page lets you change the OAuth2 token / authorization endpoint URLs without removing and re-adding the source.
38+
- Source favicons render again on the sources list (regression from the source-credential cutover).
39+
- `listSourceBindings` no longer 500s when called after a source has been removed.
3640

37-
### Natural CLI for tool discovery and invocation
41+
### OAuth reliability
3842

39-
Call tools by path instead of writing TypeScript:
43+
A pile of small fixes to the OAuth flow, individually unspectacular, collectively meaning fewer mysterious "Sign in" failures:
4044

41-
```bash
42-
executor call github issues create '{"owner":"octocat","repo":"Hello-World","title":"Hi"}'
43-
executor tools search "send email"
44-
executor tools sources
45-
executor tools describe github.issues.create
46-
```
47-
48-
`executor call <path> --help` browses namespaces → resources → methods, with `--match <text> --limit <n>` to narrow huge namespaces. Errors are normalized for agent consumption, and the resume / help UX is cleaner for non-interactive flows.
49-
50-
### Daemon lifecycle
51-
52-
```bash
53-
executor daemon run
54-
executor daemon status
55-
executor daemon stop
56-
executor daemon restart
57-
```
58-
59-
`executor call`, `executor resume`, and `executor tools …` auto-start a local daemon if one isn't running. The daemon pointer is scope-aware, and if the default port is busy the CLI transparently picks an open one — so two projects can run side-by-side without collisions.
45+
- DCR registration declares the requested scopes in the body so providers that key on body-scope (rather than `scope=` on the auth URL) issue refresh tokens with the right grants.
46+
- Refresh requests use the exact scopes from the original token grant; servers that reject scope upgrades on refresh stop returning `invalid_scope`.
47+
- `id_token` values returned alongside an access token are stripped before validation (some providers send malformed JWTs in this slot, which used to fail the whole exchange).
48+
- The `scope` parameter is omitted entirely when empty, instead of being sent as `scope=`.
49+
- OAuth endpoint URLs from discovery / DCR are validated; obviously-broken metadata fails fast with a clear message rather than later in the popup. Exposed as `assertSupportedOAuthEndpointUrl` / `isSupportedOAuthEndpointUrl` for plugin use.
50+
- Token-endpoint failures now include the upstream HTTP status + body summary in the surfaced error.
51+
- Popup handling: the popup is reserved before the start request fires, and close events are detected reliably, so cancelling sign-in no longer leaves the UI stuck waiting.
6052

61-
`executor daemon run` now backgrounds by default. Pass `--foreground` to keep it attached for log inspection.
53+
### Source-registration tools require approval
6254

63-
### OpenTelemetry everywhere
55+
Tools that register new sources (e.g. `addSource` on the OpenAPI plugin) now go through the standard approval gate by default, the same way destructive tools do. Safer to point an agent at a workspace that has source-mutating tools available.
6456

65-
Tool dispatch, plugins, storage, schema, and transport are now fully instrumented with OTEL spans, and the runtime is threaded through dispatch so spans actually export in all runtimes.
57+
### Migration safety for older CLI builds
6658

67-
## New presets
59+
If an older `executor` build opens a data directory that has been migrated by a newer build, you now get an explicit "this data directory was created by a newer version" error instead of a low-level SQLite schema mismatch crash. Drizzle migration preflight checks were also tightened so partially-applied migrations are caught earlier.
6860

69-
- **Notion** is now a featured MCP preset.
61+
### SDK additions
7062

71-
## Performance
63+
For plugin authors and embedders:
7264

73-
- `buildExecuteDescription` no longer calls `executor.tools.list`, making tool-description generation measurably faster on large workspaces.
74-
- Per-scope blob and secret lookups now use a single `IN` query instead of N per-scope round-trips.
65+
- `Usage`, `UsagesForSecretInput`, `UsagesForConnectionInput` — the usages contract.
66+
- `CredentialBindingKind`, `CredentialBindingValue`, `ConfiguredCredentialBinding`, `ConfiguredCredentialValue`, `ScopedSecretCredentialInput`, `CredentialBindingRef`, `SetCredentialBindingInput`, `RemoveCredentialBindingInput`, `ReplaceCredentialBindingsInput`, `ResolvedCredentialSlot`, `CredentialBindingId` — the new credential bindings surface.
67+
- `SecretInUseError`, `ConnectionInUseError` — typed errors for blocked deletes.
68+
- `RefreshSourceInput`, `RemoveSourceInput`, `RemoveSecretInput`, `RemoveToolPolicyInput`, `CredentialBindingRow` — new typed inputs / row types.
69+
- `ScopedDBAdapter`, `ScopedTypedAdapter` — type exports for scope-aware storage adapters.
70+
- Plugin `clientConfig` is threaded through `vite-plugin` into the client bundle, so plugins can hand SDK-side config to their React surface without a separate config endpoint.
71+
- Schema compile perf: a new lint rule + hoisted `Schema` compilers keep parse-paths fast.
7572

7673
## Fixes
7774

78-
- Upgrade: preserve legacy OAuth connection backfills after the `connection.kind` column is removed.
79-
- OpenAPI: refreshing or editing sources with legacy inline secret/OAuth config now materializes the new source binding rows instead of dropping credentials.
80-
- Keychain: skip provider registration when the OS backend is unreachable (no more startup failure when running headless on Linux without a keyring).
81-
- Local database: fail early with guidance when an older Executor build opens a data directory migrated by a newer build, instead of surfacing a low-level SQLite schema error.
82-
- Local server: return 404 for missing static assets instead of serving HTML.
83-
- Tests: Windows compatibility across the suite.
75+
- `executeWithPause` now settles correctly when the running fiber fails — previously a fiber failure could leave the execution hanging instead of surfacing the error. (#523)
76+
- `isDevMode` correctly identifies the compiled bun binary, so installed CLI builds no longer misdetect themselves as running from source. Thanks @grfwings (#699)
77+
- Drizzle migration handling parses migration metadata with a typed schema and reports outdated-client failures cleanly. Thanks @grfwings (#741)
78+
- Frontend errors and API-client decode failures are now reported through the existing error-reporting path instead of being swallowed silently.
79+
- Source forms keep local error messages on screen instead of clearing them on the next render.
80+
- "Remove in-use source" surfaces a toast instead of a silent failure. (#530)
8481

8582
## Breaking changes
8683

87-
### `executor call` no longer accepts inline code
84+
### SDK: `makeTestConfig` import path moved
8885

89-
The old TypeScript-as-argument forms are gone:
86+
The deep import path moved from `@executor-js/core/sdk/testing` to `@executor-js/core/sdk/test-config`. The package-root re-export is unchanged:
9087

91-
```bash
92-
executor call '<code>'
93-
executor call --file script.ts
94-
executor call --stdin
88+
```ts
89+
// still works
90+
import { makeTestConfig } from "@executor-js/core/sdk";
9591
```
9692

97-
Migrate to explicit tool paths:
98-
99-
```bash
100-
# before
101-
executor call 'return await tools.github.issues.list({ owner, repo })'
102-
# after
103-
executor call github issues list '{"owner":"octocat","repo":"Hello-World"}'
104-
```
105-
106-
`tools.discover(...)` becomes `executor tools search "<query>"`.
107-
108-
### `sources.add` CLI form simplified
109-
110-
Use the dedicated tool:
111-
112-
```bash
113-
executor call openapi addSource '{
114-
"spec": "https://petstore3.swagger.io/api/v3/openapi.json",
115-
"namespace": "petstore",
116-
"baseUrl": "https://petstore3.swagger.io/api/v3"
117-
}'
118-
```
119-
120-
Pass `baseUrl` when the OpenAPI document has relative `servers` entries.
121-
122-
### SDK: layered scope
93+
### SDK: per-plugin credential shapes replaced by credential bindings
12394

124-
Every SDK write now takes an explicit scope. If you have plugins or host code calling the SDK directly, they'll need to adopt the new layered-scope API (see the in-tree plugins for reference — they've all been migrated). This does not affect users of the CLI or web UI.
95+
If you authored a plugin that stored OAuth tokens or other credentials directly under a plugin-specific column, migrate to the unified `CredentialBinding*` surface. The in-tree plugins (OpenAPI, MCP, GraphQL, google-discovery) have all been ported — see them for reference. End users of the CLI / web UI are unaffected; existing rows migrate automatically.

0 commit comments

Comments
 (0)