.agents/skills/cherry-electron-dev/references/electron-instance.md
Use this as the single runtime procedure for both cherry-electron-dev and
cherry-pr-test.
Choose the caller's policy before touching Electron:
| Policy | Use | Finish |
|---|---|---|
persistent | Ongoing development | Leave a healthy instance running |
ephemeral | A bounded PR test | Stop only the instance started by this test |
Treat pre-existing processes as user-owned. Preserve userData, databases,
caches, and preferences unless the user explicitly requests a reset.
Use .context/cherry-electron-dev/ for runtime state and artifacts. The
repository ignores this path, and mkdir -p creates it in Conductor and
ordinary clones:
mkdir -p .context/cherry-electron-dev
Track the active instance in .context/cherry-electron-dev/instance.json with:
persistent or ephemeral policy and user or agent ownershiplaunch_purpose (development, pr-test:<number>, or external)workflow_relation (started or borrowed)The file is a hint, not proof. Revalidate it before every UI operation.
At the start of a new workflow, an already-running instance is borrowed even
when the same agent launched it during an earlier instruction.
Reuse the record only when all checks pass:
/json/list contains the recorded Cherry Studio target.lsof -a -p <ELECTRON_PID> -d cwd -Fn
lsof -nP -a -p <ELECTRON_PID> -iTCP:<CDP_PORT> -sTCP:LISTEN
curl -fsS http://127.0.0.1:<CDP_PORT>/json/version | jq .
curl -fsS http://127.0.0.1:<CDP_PORT>/json/list | \
jq '.[] | {id, type, title, url}'
If the record is missing or stale, discover before launching:
ps -axo pid=,ppid=,pgid=,command= | \
rg -i 'Cherry Studio|CherryStudio|electron-vite|remote-debugging-port'
lsof -nP -iTCP -sTCP:LISTEN | rg 'Electron|Cherry|:9222|:5173'
lsof -a -p <ELECTRON_PID> -d cwd -Fn
ps -o pid=,ppid=,pgid=,command= -p <PID>,<PARENT_PID>
Ignore candidates that cannot be tied to this workspace. A packaged app and another checkout are not interchangeable. Never infer ownership from an open port alone.
If a candidate passes every applicable check, adopt it immediately instead of launching:
instance.json with its live identity and
workflow_relation: borrowed.user owned and persistent.Use the verified CDP endpoint exclusively. List targets and match URL and
title; never assume target index 0. The normal main target is titled
Cherry Studio and uses:
http://localhost:5173/windows/main/index.html
If the dev server selects another port, require the same
/windows/main/index.html path and record the exact URL. Re-list after windows
open or close. Do not navigate a target unless navigation is part of the test.
Use Playwright/CDP or optional agent-browser. Do not install a global CLI just
for a task, and do not launch another instance because one controller is
unavailable.
Never pass Electron, com.github.Electron, or a node_modules Electron.app
path to Computer Use or another app-control API. Shared Electron identifiers
can launch or select the wrong checkout.
Replace only when current-workspace code or required CDP access is unavailable. Before replacing a user-owned process, explain why and record its PID, command, cwd, parent/runner, PGID, and ports.
Send SIGTERM to the exact Electron main PID and wait up to eight seconds:
kill -TERM <ELECTRON_PID>
for _ in $(seq 1 16); do
kill -0 <ELECTRON_PID> 2>/dev/null || break
sleep 0.5
done
kill -0 <ELECTRON_PID> 2>/dev/null && echo "still running"
If Electron exits but its verified same-workspace runner remains, terminate
that PID separately. Never use broad pkill, kill arbitrary port owners, or
signal a process group before inspecting every member.
Do not escalate automatically to SIGKILL. Report the remaining PID and logs
and ask before forcing a process that may be migrating, backing up, or
preventing quit. Verify the old PID and ports are gone before replacement.
Read package.json for the current debug command. If its default CDP or
inspector port belongs to an unrelated process, choose free ports and change
only those arguments; do not kill the owner.
Prefer a managed terminal session. With a terminal tool such as
exec_command, request a PTY and short initial yield, retain its returned
session ID, and let this command continue:
pnpm debug 2>&1 | tee .context/cherry-electron-dev/electron.log
Do not run that command as an ordinary blocking call. If no managed-session tool exists, use a recorded background runner:
nohup pnpm debug >.context/cherry-electron-dev/electron.log 2>&1 &
echo $!
Immediately record the returned runner PID. Resolve and record the real Electron PID and PGID after launch.
Keep the existing development profile for persistent work. For an isolated
PR test, set a distinct CS_DEV_USER_DATA_SUFFIX and record it.
Wait for the selected CDP endpoint, then identify and record the exact target:
for _ in $(seq 1 60); do
curl -fsS http://127.0.0.1:<CDP_PORT>/json/version >/dev/null && break
sleep 0.5
done
curl -fsS http://127.0.0.1:<CDP_PORT>/json/list | \
jq '.[] | {id, type, title, url}'
Write instance.json only after PID, cwd, listener ownership, and target checks
pass. Give a new instance workflow_relation: started; never reclassify a
borrowed instance as newly started.
For persistent, leave healthy user-owned and agent-owned instances running.
For ephemeral, stop an instance only when all of these are true:
workflow_relation: started.ephemeral and agent owned.Leave every borrowed instance running, regardless of whether its existing
ownership is user or agent.
If an unexpected window or PID appears:
Never close all Electron processes to recover from a targeting mistake.
| Symptom | Action |
|---|---|
| CDP works but the page is missing | Re-list targets and match URL/title; splash, migration, settings, detached tabs, and mini-apps are separate targets. |
| Debug launch exits | Inspect the recorded log for a profile lock, native rebuild, database/startup failure, or port collision; confirm the old PID exited. |
| Splash or migration is stuck | Read startup logs and wait; do not bypass, reset, or force-close without understanding its phase. |
| CDP automation is unavailable | Use logs/source when sufficient. If UI evidence is essential, explain why and use the replacement procedure; never fall back to generic Electron control. |