Skip to content

Make spec-detected auth methods immutable in the add flow#1188

Merged
RhysSullivan merged 2 commits into
mainfrom
lock-detected-auth-tabs
Jun 28, 2026
Merged

Make spec-detected auth methods immutable in the add flow#1188
RhysSullivan merged 2 commits into
mainfrom
lock-detected-auth-tabs

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Problem

In the add-integration flow, an auth method seeded from spec/probe detection rendered the full None / API key / OAuth selector with editable fields. Nothing stopped a user from switching a detected method (say a Bearer-token API) to OAuth, which blanks the fields to empty provider.example.com endpoints. The result is a broken integration whose auth no longer matches what the provider actually supports. The detected type came from the spec, so it should not be a free-form choice.

Change

Spec/probe-detected methods are now immutable in the add flow. They render as a disabled, read-only summary:

  • a lock icon on the method header,
  • the auth kind named explicitly (OAuth / API key / No auth), since a detection label like MCP's "Detected" doesn't say which it is,
  • the detected config shown read-only (API-key placement, or the OAuth endpoints/scopes the spec declared),
  • a muted, non-interactive (aria-disabled, non-selectable, cursor-not-allowed) block,
  • the affordance "Pulled from spec. Remove to override."

The only way to change a detected method is to remove the row (the header's X) and add a custom one. Methods a user adds by hand keep the full editable selector.

This lives in the shared AuthMethodListEditor, so the OpenAPI and MCP add flows both pick it up. Detection is keyed off an explicit per-row flag rather than the seed slug, because MCP seeds a detected method with a label but no slug.

Also fixes PlacementLine: its inline-flex container trimmed the whitespace at child edges, dropping the space after Authorization: and the trailing space in a Bearer prefix, so the preview read Authorization:Bearer••••••. It now renders as plain inline with preserved whitespace (Authorization: Bearer ••••••). This also corrects the same preview in the connect modal and the editable placement editor.

Recordings

MCP add flow (OAuth-detected server): detected method locked and named, a hand-added method stays editable.

Detected auth · an MCP probe's OAuth method is immutable in the add flow (selfhost)

OpenAPI add flow (spec with both API key and OAuth): both detected methods locked and named, a hand-added method stays editable.

Detected auth · OpenAPI spec-detected methods are immutable in the add flow (selfhost)

Tests

New selfhost browser scenario e2e/selfhost/detected-auth-immutable-ui.test.ts covers both surfaces: it asserts detected methods are read-only, named, with no kind selector and the remove-to-override hint, and that a hand-added method exposes the full selector.

Two additions to the e2e setup sharing one idea: the interfaces you develop
the product with are the same ones the generated tests drive, and every run is
watchable.

Authoring loop (src/journey/, scripts/cli.ts):
- `bun run cli browse <target> <step>` drives the live web UI one step at a
  time (real logged-in Chromium), each step replaying the whole flow and
  printing the page's controls plus a screenshot. Steps span the browser, a
  terminal (`run`), and HTTP (`request`), interleaved in one session.
- `bun run cli promote <target> "<name>"` turns the recorded journey into a
  committed scenario() and runs it. One Step DSL is the source of truth for
  both live execution and codegen, so the generated test drives the same
  surfaces the exploration drove and cannot quietly diverge.

Cross-OS packaged desktop (setup/desktop-*, desktop-vm/, src/vm/desktop.ts):
- desktop-macos / desktop-linux / desktop-windows run the real electron-builder
  bundle inside a guest, drive it over a CDP tunnel, and film the console into
  runs/<target>/ alongside test.ts and step screenshots. One shared scenario and
  driver; only launch and capture differ per OS:
    macOS:   autologin Aqua session, launchctl asuser, screencapture
    linux:   Xvfb + openbox, xdotool window resize, ffmpeg x11grab
    windows: dockur (QEMU) interactive session, QEMU screendump
- macOS and Linux auto-provision a tart guest and build the bundle locally (the
  executor binary cross-compiles via BUN_TARGET); Windows attaches to a dockur
  host configured through E2E_DESKTOP_WIN_* env. The desktop targets are not in
  the default test chain and skip honestly without a guest.

Also:
- Force tart SSH to password-only (PubkeyAuthentication=no, IdentitiesOnly=yes)
  so a loaded SSH agent does not exhaust the guest's MaxAuthTries, an
  intermittent failure the existing cli-{os} lanes also hit.
- build-sidecar keys the executable-bit chmod on the build target, not the
  host, so a windows-target cross-build no longer fails looking for a unix
  executor binary.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 28, 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 Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 456f125 Commit Preview URL

Branch Preview URL
Jun 28 2026, 07:43 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 28, 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 456f125 Jun 28 2026, 07:43 PM

@github-actions

github-actions Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@greptile-apps

greptile-apps Bot commented Jun 28, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes spec/probe-detected auth methods immutable in the AuthMethodListEditor add flow, preventing users from silently retyping a spec-declared method into a kind the provider doesn't support. Detected rows now render as a read-only, locked summary with the auth kind named explicitly and a "Pulled from spec. Remove to override." escape hatch; manually-added rows retain the full editable selector. The change is shared across the OpenAPI and MCP add flows through the common editor component.

  • Adds the seeded flag to AuthMethodRow and a DetectedMethodSummary read-only view; useAuthMethodList seeds detected rows as immutable while addRow produces fully-editable rows.
  • Introduces a new selfhost e2e scenario (detected-auth-immutable-ui.test.ts) covering both MCP OAuth-detected and OpenAPI multi-scheme surfaces, with in-PR recordings as visual proof.
  • Extends the e2e infrastructure with tart VM provisioning, a CDP page client for cross-OS desktop testing, and new vitest projects for desktop-{macos,linux,windows} and cli-{macos,linux,windows}.

Confidence Score: 5/5

Safe to merge; the change narrows user choice at the UI layer without touching any auth submission or connection logic.

The functional change is confined to how detected auth rows are rendered — no auth submission path, storage, or connection wiring is touched. The UI correctly prevents users from editing detected rows, and the new e2e scenarios with in-PR recordings validate both the MCP and OpenAPI surfaces. The two findings are cosmetic edge cases that do not affect any current user path.

packages/react/src/components/auth-method-list-editor.tsx — minor edge cases in DetectedMethodSummary for empty OAuth fields and the unguarded setRowAt.

Important Files Changed

Filename Overview
packages/react/src/components/auth-method-list-editor.tsx Core change: adds seeded/detected row flag, DetectedMethodSummary read-only view, and useAuthMethodList hook. The immutability invariant is enforced at the UI level only; setRowAt can still mutate seeded rows if called externally. Minor edge case: OAuth disabled block can render empty when no URLs/scopes are present and oauthMetadata is not discovered.
packages/react/src/lib/auth-placements.tsx Unchanged in logic; PlacementLine and authMethodsFromDescriptors are consumed by the new DetectedMethodSummary. No issues.
e2e/selfhost/detected-auth-immutable-ui.test.ts New browser scenario covering MCP and OpenAPI detected-auth immutability. Assertions are well-scoped; the final waitFor in the MCP hand-added step trivially passes since the first row's hint is still visible.
apps/desktop/scripts/build-sidecar.ts Fixes cross-compile chmod: now checks the target package string for windows instead of the host platform, correctly skipping chmod on .exe outputs during cross-compilation.
e2e/src/vm/desktop.ts New file providing SSH/SCP/tunnel plumbing and a minimal CDP page client for driving the packaged desktop app inside a GUI guest VM. Well-structured with per-OS recording paths.
e2e/src/vm/tart.ts New tart VM provider for macOS/Linux guests on Apple Silicon; handles provision, SSH, tunnel, reboot, and teardown. Reconnecting tunnel logic handles reboot-persistence tests correctly.
e2e/vitest.config.ts Adds desktop-macos, desktop-linux, desktop-windows, and cli-os projects; all scoped to appropriate test directories with generous timeouts.
e2e/targets/registry.ts Registry updated to include new desktop-os targets, all mapping to desktopTarget. Clean and consistent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Seeds["AuthMethodSeed[]\n(from spec/probe detection)"] -->|useAuthMethodList| Rows["AuthMethodRow[]\nseeded: true | false"]

    Rows --> RenderCheck{row.seeded?}

    RenderCheck -->|"true (detected)"| DetectedSummary["DetectedMethodSummary\nread-only, aria-disabled\nlock icon + kind label\nPulled from spec hint"]
    RenderCheck -->|"false (user-added)"| EditableEditor["AuthTemplateEditor\nfull kind selector\neditable fields"]

    DetectedSummary --> KindCheck{value.kind}
    KindCheck -->|none| NoneText["No credential text"]
    KindCheck -->|apikey| PlacementLines["PlacementLine[] (or null)"]
    KindCheck -->|oauth| OAuthCheck{oauthMetadata}
    OAuthCheck -->|discovered| DiscoveryText["Discovery text"]
    OAuthCheck -->|other| SpecFields["authorizationUrl / tokenUrl / scopes"]

    AddRow["addRow()"] -->|seeded: false| Rows
    RemoveRow["removeRowAt(i)"] -->|removes row| Rows
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    Seeds["AuthMethodSeed[]\n(from spec/probe detection)"] -->|useAuthMethodList| Rows["AuthMethodRow[]\nseeded: true | false"]

    Rows --> RenderCheck{row.seeded?}

    RenderCheck -->|"true (detected)"| DetectedSummary["DetectedMethodSummary\nread-only, aria-disabled\nlock icon + kind label\nPulled from spec hint"]
    RenderCheck -->|"false (user-added)"| EditableEditor["AuthTemplateEditor\nfull kind selector\neditable fields"]

    DetectedSummary --> KindCheck{value.kind}
    KindCheck -->|none| NoneText["No credential text"]
    KindCheck -->|apikey| PlacementLines["PlacementLine[] (or null)"]
    KindCheck -->|oauth| OAuthCheck{oauthMetadata}
    OAuthCheck -->|discovered| DiscoveryText["Discovery text"]
    OAuthCheck -->|other| SpecFields["authorizationUrl / tokenUrl / scopes"]

    AddRow["addRow()"] -->|seeded: false| Rows
    RemoveRow["removeRowAt(i)"] -->|removes row| Rows
Loading

Reviews (2): Last reviewed commit: "Make spec-detected auth methods immutabl..." | Re-trigger Greptile

Comment on lines +48 to +51
// Restore the unix executable bit — keyed on the TARGET, not the host. A
// windows-target cross-build (BUN_TARGET=bun-windows-x64 on macOS/linux) stages
// `executor.exe`, which needs no bit; chmod'ing a non-existent `executor` there
// would ENOENT.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Em-dash character in code comment

AGENTS.md prohibits em-dashes () in all contexts: "prose, docs, code comments, commit messages, or PRs. Use commas, colons, parentheses, or separate sentences instead." Line 48 uses one (// Restore the unix executable bit — keyed on the TARGET), as do comments in e2e/AGENTS.md ("the real test, not a transcript of one — develop the flow"), e2e/setup/desktop-linux.globalsetup.ts ("no launchctl — just background processes"), e2e/scripts/cli.ts, and several other new files throughout this PR.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread packages/react/src/components/auth-method-list-editor.tsx
@pkg-pr-new

pkg-pr-new Bot commented Jun 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1188

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1188

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1188

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1188

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1188

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1188

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1188

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1188

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1188

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1188

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1188

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1188

executor

npm i https://pkg.pr.new/executor@1188

commit: 456f125

@RhysSullivan RhysSullivan force-pushed the lock-detected-auth-tabs branch from c9bb8ea to b9be1ff Compare June 28, 2026 19:35
A method seeded from spec/probe detection rendered the full None/API key/
OAuth selector and editable fields, so a user could silently switch a
detected method (e.g. a Bearer-token API) to OAuth with empty endpoints and
end up with a broken integration.

Detected methods now render read-only in a disabled state: a lock icon, the
auth kind named explicitly (OAuth / API key / No auth, since MCP seeds a
detected method as just "Detected"), the declared config shown read-only,
and "Pulled from spec. Remove to override." The only action is to remove the
row and add a custom one; hand-added methods stay fully editable. This lives
in the shared AuthMethodListEditor, so the OpenAPI and MCP add flows both get
it. Detection is keyed off an explicit row flag rather than the seed slug,
since MCP seeds a detected method without one.

Also fix PlacementLine: its inline-flex container trimmed the whitespace at
child edges, dropping the space after "Authorization:" and the trailing space
in a "Bearer " prefix and rendering "Authorization:Bearer••••••". Render it
as plain inline with preserved whitespace.
@RhysSullivan RhysSullivan force-pushed the lock-detected-auth-tabs branch from b9be1ff to 456f125 Compare June 28, 2026 19:40
@RhysSullivan RhysSullivan merged commit da78dff into main Jun 28, 2026
14 of 16 checks passed
@RhysSullivan RhysSullivan deleted the lock-detected-auth-tabs branch June 28, 2026 23:18
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