* Dev mode: spawn the studio dev server from the monorepo.
(dir: string, options?: StudioLaunchOptions)
| 747 | * Dev mode: spawn the studio dev server from the monorepo. |
| 748 | */ |
| 749 | async function runDevMode(dir: string, options?: StudioLaunchOptions): Promise<void> { |
| 750 | // Find monorepo root by navigating from packages/cli/src/commands/ |
| 751 | const thisFile = fileURLToPath(import.meta.url); |
| 752 | const repoRoot = resolve(dirname(thisFile), "..", "..", "..", ".."); |
| 753 | |
| 754 | // Symlink project into the studio's data directory |
| 755 | const projectsDir = join(repoRoot, "packages", "studio", "data", "projects"); |
| 756 | const pName = options?.projectName ?? basename(dir); |
| 757 | const { symlinkPath, createdSymlink } = linkProjectIntoStudioData(dir, projectsDir, pName); |
| 758 | |
| 759 | clack.intro(c.bold("hyperframes preview")); |
| 760 | |
| 761 | const s = clack.spinner(); |
| 762 | s.start("Starting studio..."); |
| 763 | |
| 764 | // Run the new consolidated studio (single Vite dev server with API plugin) |
| 765 | const studioPkgDir = join(repoRoot, "packages", "studio"); |
| 766 | const child = spawn("bun", ["run", "dev"], { |
| 767 | cwd: studioPkgDir, |
| 768 | stdio: ["ignore", "pipe", "pipe"], |
| 769 | }); |
| 770 | |
| 771 | attachStudioReadyHandler(child, s, pName, options); |
| 772 | removeSymlinkOnExit(createdSymlink, symlinkPath); |
| 773 | |
| 774 | // Kill the child's entire process tree on SIGTERM/SIGINT. Ctrl+C sends |
| 775 | // SIGINT to the foreground process group (covers the common case), but |
| 776 | // `kill <pid>` only targets this process — the child tree (Vite + Chrome) |
| 777 | // would survive without explicit cleanup. |
| 778 | // On Windows, killProcessTree is a no-op (pgrep/ps unavailable); Ctrl+C |
| 779 | // propagates via the console process group instead. |
| 780 | registerChildTreeShutdown(child); |
| 781 | return waitForChildClose(child); |
| 782 | } |
| 783 | |
| 784 | /** |
| 785 | * Check if @hyperframes/studio is installed locally in the project's node_modules. |
no test coverage detected