Files
jackwener--opencli/docs/guide/electron-app-cli.md
T
wehub-resource-sync 9b395f5cc3
E2E Headed Chrome / e2e-headed (macos-15) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (ubuntu-latest) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (windows-latest) (push) Has been cancelled
CI / build (macos-latest) (push) Has been cancelled
CI / build (ubuntu-latest) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
CI / unit-test (push) Has been cancelled
CI / bun-test (push) Has been cancelled
CI / adapter-test (push) Has been cancelled
CI / smoke-test (macos-latest) (push) Has been cancelled
CI / smoke-test (ubuntu-latest) (push) Has been cancelled
Security Audit / audit (push) Has been cancelled
Build Chrome Extension / build (push) Has been cancelled
Trigger Website Rebuild (Docs Updated) / dispatch (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:48 +08:00

200 lines
5.5 KiB
Markdown

---
description: How to turn a new Electron desktop app into an OpenCLI adapter
---
# Add a New Electron App CLI
This guide is the **fast entry point** for turning a new Electron desktop application into an OpenCLI adapter.
If you want the full background and deeper SOP, read:
- [CLI-ifying Electron Applications](/advanced/electron)
- [Chrome DevTools Protocol](/advanced/cdp)
- [TypeScript Adapter Guide](/developer/ts-adapter)
## When to use this guide
Use this workflow when the target app:
- is built with **Electron**, or at least exposes a working **Chrome DevTools Protocol (CDP)** endpoint
- can be launched with `--remote-debugging-port=<port>`
- should be automated through its real UI instead of a public HTTP API
If the app is **not** Electron and does **not** expose CDP, use the native desktop automation pattern instead. See [CLI-ifying Electron Applications](/advanced/electron#non-electron-pattern-applescript).
## The shortest path
### 1. Confirm the app is Electron
Typical macOS check:
```bash
ls /Applications/AppName.app/Contents/Frameworks/Electron\ Framework.framework
```
If Electron is present, the next step is usually to launch the app with a debugging port.
### 2. Launch it with CDP enabled
```bash
/Applications/AppName.app/Contents/MacOS/AppName --remote-debugging-port=<unique-port>
```
Then point OpenCLI at that CDP endpoint:
```bash
export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:<unique-port>"
```
### 3. Start with the 5-command pattern
For a new Electron adapter, implement these commands first in `clis/<app>/`:
- `status.js` — verify the app is reachable through CDP
- `dump.js` — inspect DOM and snapshot structure before guessing selectors
- `read.js` — extract the visible context you actually need
- `send.js` — inject text and submit through the real editor
- `new.js` — create a new session, tab, thread, or document
This is the standard baseline because it gives you:
- a connection check
- a reverse-engineering tool
- one read path
- one write path
- one session reset path
The full rationale and examples are in [CLI-ifying Electron Applications](/advanced/electron).
## Recommended implementation workflow
### Step 1: Build `status`
Goal: prove CDP connectivity before touching app-specific logic.
Typical checks:
- current URL
- document title
- app shell presence
If `status` is unstable, stop there and fix connectivity first.
### Step 2: Build `dump`
Do **not** guess selectors from the rendered UI.
Dump:
- `document.body.innerHTML`
- accessibility snapshot
- any stable attributes such as `data-testid`, `role`, `aria-*`, framework-specific markers
Use the dump to identify real containers, buttons, composers, and conversation regions.
### Step 3: Build `read`
Target only the app region that matters.
Good targets:
- message list
- editor history
- visible thread content
- selected document panel
Avoid dumping the entire page text into the final command output.
### Step 4: Build `send`
Most Electron apps use React-style controlled editors, so direct `.value = ...` assignments are often ignored.
Prefer editor-aware input patterns such as:
- focus the editable region
- use `document.execCommand('insertText', false, text)` when applicable
- use real key presses like `Enter`, `Meta+Enter`, or app-specific shortcuts
### Step 5: Build `new`
Many desktop apps rely on keyboard shortcuts for “new chat”, “new tab”, or “new note”.
Typical pattern:
```ts
const isMac = process.platform === 'darwin';
await page.pressKey(isMac ? 'Meta+N' : 'Control+N');
await page.wait(1);
```
## Where to put files
For a desktop adapter, the usual layout is:
```text
clis/<app>/status.js
clis/<app>/dump.js
clis/<app>/read.js
clis/<app>/send.js
clis/<app>/new.js
clis/<app>/utils.js
```
If the app grows beyond the baseline, add higher-level commands such as:
- `ask`
- `history`
- `model`
- `screenshot`
- `export`
## What to document when you add a new app
When the adapter is ready, also add:
- an adapter doc under `docs/adapters/desktop/`
- command list and examples
- launch instructions with `--remote-debugging-port`
- any required environment variables
- platform-specific caveats
Examples to study:
- `docs/adapters/desktop/codex.md`
- `docs/adapters/desktop/chatwise.md`
- `docs/adapters/desktop/discord.md`
## Common failure modes
### CDP endpoint exists, but commands are flaky
Usually one of these:
- the wrong window/tab is selected
- the app has not finished rendering
- selectors were guessed instead of discovered from `dump`
- the editor is controlled and ignores direct value assignment
### The app is Chromium-based but not truly controllable
Some desktop apps embed Chromium but do not expose a usable CDP surface.
In that case, switch to the non-Electron desktop automation approach instead of forcing the Electron pattern.
### You already have a browser workflow and wonder whether to reuse it
If the app exposes a normal web URL and the browser flow is enough, a browser adapter is usually simpler.
Use an Electron adapter only when the desktop app is the real integration surface.
## Recommended reading order
If you are starting from zero:
1. This page
2. [CLI-ifying Electron Applications](/advanced/electron)
3. [Chrome DevTools Protocol](/advanced/cdp)
4. [TypeScript Adapter Guide](/developer/ts-adapter)
5. One concrete desktop adapter doc under `docs/adapters/desktop/`
## Practical rule
Do not start with a large feature surface.
Start with:
- `status`
- `dump`
- `read`
- `send`
- `new`
Once those are stable, extend outward.