Repository navigation
Description
Steps to reproduce
- Windows desktop app 2.4.0, open a project that has saved project actions (any action whose command is a plain shell command).
- In the session header, open the project-actions dropdown (the one with "Add new action" / "添加新操作").
- Click Auto-discover dev server ("自动发现开发服务器") — a synthetic item at the bottom of that menu, not one of the saved actions.
- A terminal tab opens, labelled "Auto-discover dev server", and it runs the first saved project action's command.
In my case the first saved action is a PowerShell command that shells out to gh workflow run update-daily-report.yml --ref main. Clicking the discover item printed:
✓ Created workflow_dispatch event for update-daily-report.yml at main
https://github.com/.../actions/runs/39423716119
and actually started a GitHub Actions run. It was 100% reproducible: every click on the discover item runs that action, never anything related to dev-server discovery.
What you expected
Clicking "Auto-discover dev server" either finds/starts a dev server or shows a preview of one — it should never execute one of the project's saved actions.
What happened instead
The first saved project action was executed in a terminal tab that is labelled as the dev-server discovery item. The tab title and its content disagree, and a real workflow got triggered by a click that had nothing to do with it.
Where does it happen?
Desktop app (Windows)
OpenChamber version
2.4.0
OpenCode version and model/provider (if relevant)
opencode 2.0.32 (bundled CLI), no model involved
Screenshots / recordings (optional)
The terminal tab is titled "自动发现开发服务器" while showing the gh workflow run output of the first saved action.
Logs (optional)
Bundle evidence, resources/web-dist/assets/main-*.js: the discovery item is synthetic and has no command of its own —
Ie = useMemo(() => ({
id: "__openchamber_auto_discover_preview__",
name: t("projectActions.actions.autoDiscover"),
command: "",
icon: "scan-2",
autoOpenUrl: true
}), [t]),
Pe = we ? [...A, Ie] : AIt is appended after the saved actions and then goes through the same select/trust/run path as a real action, so with an empty command the run resolves to the first saved action (index 0). Adding a second saved action did not change the outcome — the first one still runs. This project currently has two saved actions: a daily-report workflow trigger and a summary workflow trigger.
Activity
openchamber-bot commentedon Oct 20, 2026
For the maintainer:
fix-ready— cause tracedThe reporter's conclusion is right — the discover item runs a saved action's command — but not their mechanism: the empty
commandnever reaches the terminal. Clicking the item runs discovery (packages/ui/src/components/layout/useProjectActionsRunner.ts:763-782), which callsdetectDevServerCommand(packages/ui/src/lib/detectDevServer.ts:32). Its first step,findDevServerAction(detectDevServer.ts:100-116), treats the first saved action whose lowercasedname + commandmerely containsdev,start,preview, orserve— bare substrings, no word boundary (detectDevServer.ts:22-27,106-108) — as "the dev server" and returns its command, which then executes in the tab labelled "Auto-discover dev server" (useProjectActionsRunner.ts:776,848-851). This is the only code path by which auto-discover ever executes a saved action, so the mechanism is confirmed for the symptom; the specific substring that matched in the reporter's action (a PowerShell wrapper plausibly containsStart-Process/Start-Job→ "start", or the action's name does) is plausible-but-unconfirmed since their exact name/command isn't visible here.Reusing a dev-like saved action for discovery is deliberate (#2743 describes exactly this detection), but a bare substring check lets
startinsideStart-Processor prose match, and the run executes with real side effects and no confirmation. Directions are yours: word-boundary/anchored matching, preferring package.json scripts, or confirming before running a guessed action.Code path
ProjectActionsButton.tsx:97-104— a dropdown item click callsrunner.select+runner.toggle;runner.actionsincludes the synthetic discover item (useProjectActionsRunner.ts:399-413).useProjectActionsRunner.ts:763-782—action.id === AUTO_DISCOVER_ACTION_ID→ fetch saved actions + package.json scripts, calldetectDevServerCommand.detectDevServer.ts:40-48—findDevServerActionruns first; on a match itscommandbecomes the "discovered dev server".detectDevServer.ts:100-116— first action whosename + commandincludes any ofdev/start/preview/servewins; no word boundary, first match, index order — matching "always the first saved action".useProjectActionsRunner.ts:787-851— the returned command is normalized and executed in a terminal tab labelled with the discover item's name; package.json and static-site fallbacks are never consulted once an action "matches".If you paste the exact name and command of your first saved action, the matched substring can be confirmed.