Skip to content

feat(electrobun): PR1 foundation — package skeletons + native-types wiring#310

Merged
goosewobbler merged 4 commits into
feat/electrobun-servicefrom
feat/electrobun-foundation
May 31, 2026
Merged

feat(electrobun): PR1 foundation — package skeletons + native-types wiring#310
goosewobbler merged 4 commits into
feat/electrobun-servicefrom
feat/electrobun-foundation

Conversation

@goosewobbler
Copy link
Copy Markdown
Contributor

First of a 4-PR stack (Foundation → MVP → Feature-complete → Ship) bootstrapping @wdio/electrobun-service per ROADMAP Phase 5. Targets the feat/electrobun-service integration branch; subsequent PRs stack on top.

Electrobun is a CDP-attach archetype (like Electron, unlike Wry-based Tauri/Dioxus), so this clones the Electron service pair — no Rust, no driver process.

What's in this PR

  • @wdio/native-types — new src/electrobun.ts (ElectrobunServiceAPI, options, mock, ElectrobunCapabilities as a plain interface, browser extension, window.__WDIO_ELECTROBUN__); wired into the WebdriverIO Browser/MultiRemoteBrowser/Capabilities/ServiceOption augmentation.
  • @wdio/electrobun-cdp-bridge — skeleton for the multi-target CDP client: constants (DEFAULT_PORT=9222 + the CEF 9222–9232 range), types (Debugger/Version + PageTarget/TargetClass/TargetRegistryEntry), barrel, README, export-shape test. The connection manager lands in the MVP PR.
  • @wdio/electrobun-service — skeleton mirroring @wdio/dioxus-service: launcher extends BaseLauncher (handles browser mode; native-mode spawn lands in MVP), worker stub, errors (cefRendererRequired / deeplinkUnsupportedOnPlatform), constants, serviceConfig, unit tests.
  • turbo.json — build-graph entries for both new packages.

Key decision baked in

CDP is only available under Electrobun's CEF renderer (the default WebKit webviews on macOS/Linux don't speak CDP), so the service requires apps built with defaultRenderer: 'cef' on all three OSes; WebKit-default apps are a documented unsupported gap.

Phase 0 spike — ✅ GO (macOS validated)

A throwaway CEF app was driven end-to-end (agent-os/specs/20260528-electrobun-service/RESEARCH_FINDINGS.md): Chromedriver attaches via debuggerAddress, multiple windows enumerate as separate CDP page targets, attach is observation-only, macOS deeplinks reach the handler. The findings refine the MVP design (port is pinnable; CEF is single-instance per --user-data-dir; Linux CDP still to be validated in CI).

Verification

  • typecheck + unit tests green for both packages (cdp-bridge 3/3 @ 100% cov, service 10/10)
  • Biome clean; service builds end-to-end
  • No regressions to @wdio/native-types

🤖 Generated with Claude Code

goosewobbler and others added 2 commits May 30, 2026 22:09
…iring

Bootstrap the Electrobun desktop testing service (ROADMAP Phase 5) as a
CDP-attach archetype, cloned from the Electron service pair. This is the
Foundation PR of a 4-PR stack (Foundation → MVP → Feature-complete → Ship)
that merges into the feat/electrobun-service integration branch.

- native-types: add src/electrobun.ts (ElectrobunServiceAPI, options,
  mock, capabilities as a plain interface, browser extension,
  window.__WDIO_ELECTROBUN__) and wire the WebdriverIO Browser /
  MultiRemoteBrowser / Capabilities / ServiceOption augmentation.
- @wdio/electrobun-cdp-bridge: skeleton for the multi-target CDP client —
  constants (DEFAULT_PORT=9222 + the CEF 9222–9232 auto-select range),
  types (Debugger/Version + PageTarget/TargetClass/TargetRegistryEntry),
  barrel, README, export-shape test. Connection manager lands in MVP.
- @wdio/electrobun-service: skeleton mirroring @wdio/dioxus-service —
  launcher extends BaseLauncher (handles browser mode; native-mode spawn
  + CEF port discovery land in MVP), worker service stub, errors
  (cefRendererRequired / deeplinkUnsupportedOnPlatform), constants,
  serviceConfig, session-free index, unit tests.
- turbo.json: build-graph entries for both new packages.

Decision baked in: CDP only works under Electrobun's CEF renderer, so the
service requires apps built with defaultRenderer:'cef' on all three OSes;
WebKit-default apps are a documented unsupported gap.

Verification: typecheck + unit tests green for both packages (bridge 3/3
@100% cov, service 10/10), Biome clean, no regressions to native-types.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capture the Phase 0 spike results in agent-os/specs (the tracked
research-findings convention). A throwaway CEF Electrobun app was built and
driven end-to-end on macOS, confirming the CDP-attach + Chromedriver
debuggerAddress model is viable.

Key results that refine PR2:
- Port is PINNABLE — --remote-debugging-port overrides CEF's 9222-9232 scan.
- CEF is single-instance per --user-data-dir → parallel workers need distinct
  user-data-dirs + pinned ports (biggest MVP item).
- Each window/view = one CDP page target (no shell); mock seam is
  Page.addScriptToEvaluateOnNewDocument over window.__electrobun.*.
- Chromedriver matches on major 147; deeplink works on macOS via open-url.
- Still unverified: Linux CDP (remote_debugging_port commented out) + Windows.
- Pin a known-good Electrobun release; 1.18.4-beta.3 ships two build defects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR bootstraps the @wdio/electrobun-service and @wdio/electrobun-cdp-bridge packages as skeleton foundations, wires Electrobun types into @wdio/native-types, and adds turbo.json build-graph entries — all modelled on the Electron service pair.

  • @wdio/native-types: new electrobun.ts with ElectrobunServiceAPI, options, mock shape, and ElectrobunCapabilities; module augmentation wired into Browser/MultiRemoteBrowser/Capabilities/ServiceOption.
  • @wdio/electrobun-cdp-bridge: constants (DEFAULT_PORT=9222, CEF range 9222–9232), types (Debugger/Version/PageTarget/TargetRegistryEntry), and an export-shape test; connection manager deferred to MVP PR.
  • @wdio/electrobun-service: ElectrobunLaunchService (handles browser mode; native spawn deferred), worker stub, error helpers (cefRendererRequired/deeplinkUnsupportedOnPlatform), and unit tests.

Confidence Score: 5/5

Safe to merge — all changed code is new skeleton/stub that either returns early or logs a warning; no existing functionality is altered.

The only findings are documentation inaccuracies and a mixed-mode mutation concern in new pre-release stub code. No existing packages or behaviour are touched beyond additive type augmentation in native-types.

launcher.ts and the remoteDebuggingPort JSDoc in electrobun.ts should both be corrected before the MVP PR builds on them.

Important Files Changed

Filename Overview
packages/electrobun-service/src/launcher.ts Browser-mode detection loops over all caps but mutates every cap's browserName regardless of per-cap mode; native mode is a no-op stub with correct port anchoring.
packages/native-types/src/electrobun.ts New Electrobun type surface wired into native-types; remoteDebuggingPort JSDoc slightly mischaracterises the pinning mechanism vs. research findings.
packages/electrobun-cdp-bridge/src/constants.ts Constants and error messages; JSDoc updated from previous review to accurately describe pinning strategy.
packages/electrobun-service/src/errors.ts cefRendererRequired (SevereServiceError) and deeplinkUnsupportedOnPlatform helpers; error messages are clear and platform-aware.
packages/electrobun-service/src/serviceConfig.ts Thin option-merge utility; shallow spread is appropriate since all fields are primitives.
packages/electrobun-service/src/constants.ts Port constants correct — DEFAULT_DEBUG_PORT_BASE=9333 is safely outside CEF's 9222-9232 scan range; REMOTE_DEBUGGING_PORT_ENV comment says 'discovered' inconsistently with the pinning model.
packages/native-types/src/index.ts Electrobun types wired into Browser/MultiRemoteBrowser/Capabilities/ServiceOption augmentation; follows existing Electron/Tauri/Dioxus pattern exactly.
turbo.json Build-graph entries added for both packages; electrobun-service only declares cdp-bridge as a dependency, omitting the native-core/native-types/native-spy chain that service depends on.
packages/electrobun-service/src/service.ts Worker stub; correctly resolves devServerUrl from capability options with global fallback.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[WDIO Runner] -->|onPrepare| B[ElectrobunLaunchService]
    B --> C{mode?}
    C -->|browser| D[Validate devServerUrl]
    D --> E[Set browserName='chrome' on all caps]
    E --> F[Return — skip binary/CDP setup]
    C -->|native| G[warn: not yet implemented]
    G --> H[Return]
    A -->|before hook| I[ElectrobunWorkerService]
    I --> J[Resolve devServerUrl from cap options or global]
    B -.->|extends| L[BaseLauncher native-core]
    L --> M[PortManager basePort=9333]
Loading

Fix All in Claude Code Fix All in Cursor

Reviews (3): Last reviewed commit: "docs(electrobun): clarify remoteDebuggin..." | Re-trigger Greptile

Comment thread packages/electrobun-service/src/launcher.ts
Comment thread packages/electrobun-cdp-bridge/src/constants.ts
Comment thread packages/electrobun-service/src/launcher.ts Outdated
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan
  range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach
  with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE
  (9333) as the allocation anchor. [P1]
- launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the
  testrunner config can carry reporter tokens / cloud credentials that shouldn't
  reach debug logs. [P2]
- cdp-bridge + service constants: correct the misleading "discovers by scanning
  rather than dictating" port comments — the launcher pins the port per worker by
  writing build.json; the 9222-9232 scan is CEF's fallback only. [P1]

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@goosewobbler
Copy link
Copy Markdown
Contributor Author

Addressed the Greptile findings in 1d124adf:

  • P1 (launcher port anchor): baseNativePort no longer sits in CEF's [9222,9232] auto-scan range — added DEFAULT_DEBUG_PORT_BASE (9333) as the PortManager anchor, with a note that Electrobun is CDP-attach (no native driver), so baseNativePort is nominal.
  • P1 (port comments): corrected the "discovers by scanning rather than dictating" wording in both constants.ts files — the launcher pins the port per worker by writing build.json; the 9222–9232 scan is CEF's fallback only (per RESEARCH_FINDINGS, confirmed by the CFFIXED_USER_HOME spike).
  • P2 (secret leak): dropped the full JSON.stringify(config/capabilities) debug dumps.

…ot discovered

The remoteDebuggingPort JSDoc still described port auto-discovery (a stale model);
the launcher allocates + pins a port per worker into the bundle's build.json. Reword
so users configuring parallel/multiremote runs aren't misled — each worker gets a
distinct auto-allocated, pinned port; this option only forces a fixed one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request May 31, 2026
…pare

Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a
single mode to all caps — browser mode forced browserName:'chrome' on every cap
(even native ones) if ANY cap was browser-mode. Fail fast with a clear
SevereServiceError on a mixed set instead of silently mis-handling a cap, and
require a consistent mode. Fixed in the final (feature-complete) launcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request May 31, 2026
…pare

Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a
single mode to all caps — browser mode forced browserName:'chrome' on every cap
(even native ones) if ANY cap was browser-mode. Fail fast with a clear
SevereServiceError on a mixed set instead of silently mis-handling a cap, and
require a consistent mode. Fixed in the final (feature-complete) launcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@goosewobbler goosewobbler merged commit 6577644 into feat/electrobun-service May 31, 2026
89 of 98 checks passed
goosewobbler added a commit that referenced this pull request May 31, 2026
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan
  range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach
  with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE
  (9333) as the allocation anchor. [P1]
- launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the
  testrunner config can carry reporter tokens / cloud credentials that shouldn't
  reach debug logs. [P2]
- cdp-bridge + service constants: correct the misleading "discovers by scanning
  rather than dictating" port comments — the launcher pins the port per worker by
  writing build.json; the 9222-9232 scan is CEF's fallback only. [P1]

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request May 31, 2026
…pare

Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a
single mode to all caps — browser mode forced browserName:'chrome' on every cap
(even native ones) if ANY cap was browser-mode. Fail fast with a clear
SevereServiceError on a mixed set instead of silently mis-handling a cap, and
require a consistent mode. Fixed in the final (feature-complete) launcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request May 31, 2026
…pare

Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a
single mode to all caps — browser mode forced browserName:'chrome' on every cap
(even native ones) if ANY cap was browser-mode. Fail fast with a clear
SevereServiceError on a mixed set instead of silently mis-handling a cap, and
require a consistent mode. Fixed in the final (feature-complete) launcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request Jun 1, 2026
- launcher: anchor PortManager ports clear of CEF's [9222, 9232] auto-scan
  range (baseNativePort was 9223, inside the range). Electrobun is CDP-attach
  with no native driver, so baseNativePort is nominal — added DEFAULT_DEBUG_PORT_BASE
  (9333) as the allocation anchor. [P1]
- launcher: drop the full JSON.stringify(config/capabilities) debug dumps — the
  testrunner config can carry reporter tokens / cloud credentials that shouldn't
  reach debug logs. [P2]
- cdp-bridge + service constants: correct the misleading "discovers by scanning
  rather than dictating" port comments — the launcher pins the port per worker by
  writing build.json; the 9222-9232 scan is CEF's fallback only. [P1]

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goosewobbler added a commit that referenced this pull request Jun 1, 2026
…pare

Greptile (PR #310 review summary, "mixed-mode mutation"): the launcher applies a
single mode to all caps — browser mode forced browserName:'chrome' on every cap
(even native ones) if ANY cap was browser-mode. Fail fast with a clear
SevereServiceError on a mixed set instead of silently mis-handling a cap, and
require a consistent mode. Fixed in the final (feature-complete) launcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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