# Aurora Dockside — Build Session Log A record of the conversation that produced this project: an Electron + React + TypeScript desktop GUI for managing [DDEV](https://ddev.com) local development environments, built as an independent clone of [DDEV Manager](https://github.com/DDEV-Manager/ddev-manager) (Tauri + React + Rust). ## Origin The session started with an unrelated request — install and configure DDEV itself (Homebrew, OrbStack as the container runtime, mkcert for trusted local HTTPS). Partway through, the idea came up: rather than using the existing DDEV Manager app, build an equivalent from scratch, in our own code. ### Tech stack decisions (asked up front) - **Framework**: Electron + React + TypeScript, chosen over matching the original's Tauri/Rust stack — no Rust toolchain required. - **Scope**: Full feature parity with DDEV Manager, built incrementally (each step runnable/testable) rather than scaffolding everything blind. - **Package manager**: pnpm, enabled via `corepack enable`. - **Name**: Aurora Dockside (chosen by the user over a couple of suggested alternatives). A formal plan was written (Plan Mode) covering architecture (Electron main process owns all `ddev` CLI execution; typed `window.api` surface via contextBridge; TanStack Query + Zustand on the renderer side) and a 9-step build order before any code was written. ## Build steps (each committed separately, each verified against a real running DDEV project — not just typechecked) 1. **Scaffold** — `electron-vite` + React 19 + TypeScript template via `@quick-start/create-electron`, git-initialized on `main`. 2. **Tailwind CSS 4, Vitest, core libraries** — Tailwind via the Vite plugin, Vitest + React Testing Library, Zustand, TanStack Query, Lucide icons. Stripped the electron-vite demo boilerplate. 3. **Core project management** — `ddev.ts` CLI wrapper (execFile + JSON envelope parsing), IPC handlers, typed preload API, TanStack Query hooks, two-pane UI (project list + detail panel). Includes a PATH fallback in the main process, since GUI apps launched outside a terminal don't inherit the shell's PATH and can't find Homebrew's `ddev` binary otherwise. 4. **Terminal panel, status bar, toasts** — long-running commands (start/stop/restart) now spawn via a `commandRunner.ts` module and stream stdout/stderr to the renderer over IPC instead of waiting for the whole command to finish. Cancel support kills the tracked child process by operation id. 5. **Database tools** — snapshot create/list/restore/delete, DB import/export via native file dialogs. `ddev snapshot restore` has no project-name flag (unlike other ddev commands), so it runs with `cwd` set to the project's approot instead. 6. **Add-on management** — registry browser (~270 third-party add-ons) with search, install/remove via `ddev add-on get/remove`. Verified working with the project stopped. 7. **Log viewer** — `ddev logs -f` streamed over a dedicated IPC channel (decoupled from the terminal/status-bar model, since log tailing runs indefinitely rather than completing). Service switcher, text filter. 8. **Project creation wizard** — native directory picker, project name, project type selector, optional docroot, streamed `ddev config`. 9. **Settings** — theme (light/dark/system, persisted), zoom controls via a small main-process IPC (`webContents.setZoomLevel`), keyboard shortcuts (Cmd/Ctrl+N, +comma, +=/-/0). 10. **Packaging** — cleaned up `electron-builder.yml` (correct appId/ productName, removed irrelevant camera/mic/Documents/Downloads Info.plist entries, removed a placeholder auto-update publish config). Verified with a real `pnpm build:unpack` run, launching the packaged (unsigned, no Developer ID cert available) `.app` directly and confirming it could still find and run `ddev`. Scoped down from full parity, on purpose: composer/wp-cli-based CMS scaffolding for Drupal/Laravel/Shopware, and auto-update infrastructure. ## Bugs found via live testing (not just code review) Every feature was verified by actually driving the running app — mostly via a small CDP (Chrome DevTools Protocol) driver script that clicked real buttons in the real Electron window, since a lot of this app's correctness depends on real subprocess/IPC/timing behavior that static review can't catch. This caught several real defects: - **`window.prompt()` doesn't work in Electron's renderer** — it returns `null` immediately with no dialog, unlike `window.confirm()` which does show a real native dialog. The snapshot-naming UI was rewritten to use an inline text input instead. - **`ddev addon list --installed` omits the `raw` JSON key entirely** when nothing is installed (unlike `ddev list`/`ddev snapshot --list`, which include `raw: null`). The shared JSON-parsing helper treated a missing `raw` as an error, so after removing the last add-on the query would error on refetch and React Query kept showing the stale cached row. Fixed by splitting the helper into a strict variant (for `describe`, where missing data really is an error) and a lenient list variant. - **Log filtering operated on raw stream chunks, not lines** — a single chunk of stdout/stderr can bundle many lines or split one across chunk boundaries, so filtering by chunk let unrelated lines through. Fixed by buffering partial lines per stream and only filtering once full lines are assembled. - **A `react-hooks/set-state-in-effect` lint violation** in the log-stream hook, from resetting state synchronously inside an effect body. Fixed by keying the streaming component by `service` so switching services remounts it — state resets via fresh `useState` initializers instead, which is the React-recommended pattern for this. ## Post-launch bug reports and fixes After the initial 9-step build was declared done, real usage surfaced three more gaps: 1. **"I created a new container for wordpress, only wp-content was created."** — `ddev config --project-type=wordpress` only scaffolds the DDEV-managed `wp-config.php` bridge and `wp-content/uploads`; it never downloads WordPress core (`wp-admin/`, `wp-includes/`, `index.php`, etc.). Fixed the user's existing project directly (`ddev wp core download`), then added the missing step to the wizard. 2. **"Now I get 403 Forbidden. Shouldn't we have an option to set admin username, password, and email while setting it up?"** — right call: `wp core download` only fetches files, `wp core install` is what actually creates the database tables and admin user. The wizard's WordPress path now chains `configure → start → wp core download → wp core install`, with site title/admin username/password/email fields shown only for that project type. wp-cli needs the containers running, so this path always starts the project regardless of the generic "start after creating" checkbox. 3. **"What about the ability to delete the site? I can create all day long but not able to delete them from the software."** — a real gap; the original DDEV Manager has this and it hadn't been built yet. Added a Delete button (`ddev delete --yes`, keeping ddev's default database snapshot as a safety net) with a confirmation dialog that clarifies it only removes DDEV's registration/containers/database, not the project's files on disk. 4. Also added, per a follow-up request: a **WP Admin quick-link** button for running WordPress-type projects, opening `{primary_url}/wp-admin/` directly. All three were verified end-to-end against a fresh throwaway project: full configure→start→download→install chain producing a genuinely working site (200 on the homepage, correct login redirect on `/wp-admin`), and delete actually removing the project from `ddev list`. Two apparent bugs that came up during that verification turned out to be the *test script* reading DOM state before React had re-rendered, or before ddev's multi-step delete (build + start + snapshot + teardown) had actually finished — not real defects. ## Final artifact A packaged, distributable build was produced on request: - `dist/aurora-dockside-1.0.0.dmg` — installer - `dist/Aurora Dockside-1.0.0-arm64-mac.zip` — zipped `.app` Both unsigned (no Developer ID certificate on this machine) — macOS Gatekeeper requires right-click → Open on first launch. ## Repository state 10 commits on `main`, one per build step plus the post-launch fixes: ``` Scaffold Aurora Dockside with electron-vite + React + TypeScript Wire up Tailwind CSS 4, Vitest, and core app libraries Add core DDEV project management (list/describe/start/stop/restart) Add streaming terminal panel, status bar, and toast notifications Add database tools: snapshots and import/export (step 4) Add add-on management: registry browser, install, remove (step 5) Add streaming log viewer with service switching and filtering (step 6) Add project creation wizard (step 7) Add settings: theme, zoom controls, keyboard shortcuts (step 8) Finalize packaging config and verify a real build (step 9) Fix WordPress scaffolding gap; add delete project + WP admin link ``` *(Note: some project files show further edits beyond this log's cutoff — work continued in the project after this session.)*