feat(midscene-studio): scaffold native shell app#2329
Conversation
…s review feedback Rename the shell app apps/electron-playground -> apps/midscene-studio (package name, HTML title, dev env var, docs/plan path) and apply the review follow-ups: - wait-for-electron-build: drop the freshnessWindowMs bypass so only strictly newer mtimes count as a fresh build - main: remove the process.cwd() fallback in getAppIconPath and cache the nativeImage - renderer: point the Playground component at the single app-level midscene-icon.png and delete the duplicate renderer copy - electron-contract: add JSDoc to ElectronShellApi and IPC_CHANNELS - sync-static-assets: rm the target dir before cp so stale files are not left behind Validated with pnpm --filter midscene-studio build and pnpm run lint.
Rename the shell app apps/midscene-studio -> apps/studio (package name, docs/plan filename and contents) and flatten the renderer component tree by removing the incut-area-all-in-one directory layer so every shell component lives directly under src/renderer/components. - Move IncutAreaAllInOne, MainContent, Playground, Sidebar, globals.css up into src/renderer/components and drop the redundant barrel index.ts - Rename the asset helper to asset-urls.ts to avoid a file-vs-directory collision with the sibling assets/ folder - Update App.tsx and IncutAreaAllInOne.tsx imports to the new sibling paths, and tighten the midscene-icon.png relative path in asset-urls - Refresh docs/plan to reference apps/studio and pnpm --filter studio Validated with pnpm --filter studio build and pnpm run lint.
Strip the incut-export naming from the shell app so the component and asset map names reflect their actual role instead of the design-tool provenance. - Rename the root layout component IncutAreaAllInOne -> ShellLayout (directory, default export, barrel re-export, App.tsx usage) - Rename the asset URL map incutAssetUrls -> assetUrls and update all three importers (MainContent, Playground, Sidebar) - Drop the data-incut-root attribute left behind by the design export Validated with pnpm --filter studio build, pnpm --filter studio test, and pnpm run lint.
…ents These attributes were left behind by the design-export pipeline and are never read by any runtime or test. Remove them now so the renderer tree reads cleanly during review.
A round of "fix it while we are here" cleanup surfaced by PR review. - Sidebar: drop dead referenceId/id/iconId fields left over from the design export (types, mock data, SectionHeader props, DeviceRow) - ShellLayout: remove orphan globals.css; tailwind and the base reset are already owned by App.css, so this file only duplicated them - main: simplify toggleMaximizeWindow handler to a flat if/else - wait-for-electron-build: narrow readMtimeMs catch to ENOENT so real IO errors no longer get swallowed into a stale-build state - rsbuild.config: extract the renderer dev port into a named constant with a note pointing at the matching package.json dev script Validated with pnpm --filter studio build, pnpm --filter studio test, and pnpm run lint.
Three targeted fixes from the self-review pass on 7ceead9: - Collapse the renderer dev port to a single source of truth. scripts/renderer-dev-config.mjs now owns host/port/URL and is imported by rsbuild.config.ts, wait-for-electron-build.mjs and a new launch-electron-dev.mjs launcher that injects the env var for electron. The dev script in package.json no longer hardcodes the URL, so the port lives in exactly one place. - Wrap the non-ENOENT throw in readMtimeMs with a contextual Error (file path + original message via cause), so unexpected IO failures during the dev gate point directly at the offending file. - Add a regression test that createFreshBuildChecker propagates a non-ENOENT reader error instead of treating it as a missing file, locking in the narrowed catch behavior. Validated with pnpm --filter studio build, pnpm --filter studio test, and pnpm run lint.
|
why not tauri 2.0? |
Remove docs/plan/studio-phase-1.md from git tracking and add docs/ to .gitignore.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0746a5f278
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| child.on('exit', (code, signal) => { | ||
| if (signal) { | ||
| process.kill(process.pid, signal); |
There was a problem hiding this comment.
Ensure wrapper exits after child signal termination
This branch re-sends the child’s terminating signal to the current process, but the script has already registered SIGINT/SIGTERM handlers, so the signal is handled by forwardSignal instead of terminating the process. When Electron is stopped by signal (for example Ctrl+C or concurrently -k teardown), the wrapper can stay alive and hang shutdown. Please explicitly exit (or remove signal handlers before re-raising) in this path.
Useful? React with 👍 / 👎.
Summary
apps/midscene-studiowith three rsbuild environments (
renderer,main,preload), a typed IPCbridge, and a light-themed two-pane layout.
apps/midscene-studio/assets) and sync theminto
dist/assetsviascripts/sync-static-assets.mjs, so the runtime nolonger depends on remote design-export URLs.
wait-for-electron-buildfreshness check,drop the
process.cwd()fallback ingetAppIconPath, cache the nativeImage,deduplicate
midscene-icon.png, and add JSDoc to theElectronShellApicontract.
This is phase 1 of Midscene Studio — pure shell scaffolding, no device or
agent runtime yet. Phase 2 will plug in real device discovery and agent
hosting from the main process without reorganizing the layering.
Test plan
window opens, title bar controls (minimize / maximize / close) work, and
the Playground / Sidebar / MainContent render with local assets