From 2155c3cfaa1b4c44e7c6afa500a2f2da026c1491 Mon Sep 17 00:00:00 2001 From: Harshit Singh Bhandari Date: Sun, 21 Jun 2026 19:46:56 +0530 Subject: [PATCH] fix: pin all app state under ~/.ao, never ~/Library (#369) Electron's main process set app.setName(...) but never overrode userData, so Chromium runtime state (cache, cookies, local/session storage, crash dumps) defaulted to ~/Library/Application Support/. Older dev builds also wrote the daemon DB there. Pin userData to ~/.ao/electron so the entire app footprint lives under the canonical AO home alongside the daemon data dir and running.json; sessionData and crashDumps derive from userData, so the single override reparents them all. Document the ~/.ao-only rule as a hard boundary in AGENTS.md and CLAUDE.md. Closes #368 Co-authored-by: Claude Opus 4.8 --- AGENTS.md | 1 + CLAUDE.md | 9 +++++++++ frontend/src/main.ts | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 0739c8193..c75737245 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,6 +86,7 @@ For code entry points: - Keep generated OpenAPI/API DTO drift in mind: controller response shapes live in `backend/internal/httpd/controllers/dto.go` and tests may assert CLI/HTTP wire compatibility. - Do not add network calls to tests unless the package already has an integration/e2e pattern for them. Prefer `httptest`, fakes, and injected dependencies. - Do not commit local run state, daemon data, temporary worktrees, build outputs, or credentials. +- All app state lives under `~/.ao` only. The daemon's data dir, `running.json`, worktrees, and the Electron supervisor's `userData` (Chromium cache, cookies, local/session storage, crash dumps) must resolve under `~/.ao` (overridable via `AO_DATA_DIR`/`AO_RUN_FILE`). Never write to or read from `~/Library/Application Support` or any other OS default app-data location. `main.ts` pins Electron's `userData` to `~/.ao/electron`; do not remove that override or rely on Electron's default path. ## API contract changes diff --git a/CLAUDE.md b/CLAUDE.md index 50cc65c15..1678b2c7e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,15 @@ Read and follow [`AGENTS.md`](AGENTS.md) for repository layout, commands, coding conventions, and hard rules. +## App state lives under `~/.ao` only + +All app state, the daemon's data dir, `running.json`, worktrees, and the Electron +supervisor's `userData` (Chromium cache, cookies, local/session storage, crash +dumps), must resolve under `~/.ao` (overridable via `AO_DATA_DIR`/`AO_RUN_FILE`). +Never write to or read from `~/Library/Application Support` or any other OS-default +app-data location. `frontend/src/main.ts` pins Electron's `userData` to +`~/.ao/electron`; do not remove that override. See the hard rule in `AGENTS.md`. + ## Design System Always read [`DESIGN.md`](DESIGN.md) before making any visual or UI decision — diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 7ea9d3d8e..ed18a681b 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -19,6 +19,14 @@ declare const MAIN_WINDOW_VITE_NAME: string; // Must run before app ready so the About panel and default-menu role labels use it. app.setName("Agent Orchestrator"); +// Pin ALL Electron-owned state (Chromium cache, cookies, local/session storage, +// crash dumps) under the canonical AO home at ~/.ao instead of Electron's macOS +// default ~/Library/Application Support/. Keeps the app's entire footprint +// inside ~/.ao alongside the daemon's data dir and running.json. sessionData and +// crashDumps derive from userData, so this one override reparents them all. +// Must run before app ready. +app.setPath("userData", path.join(os.homedir(), ".ao", "electron")); + let mainWindow: BrowserWindow | null = null; let daemonProcess: ChildProcessWithoutNullStreams | null = null; let daemonStoppingProcess: ChildProcessWithoutNullStreams | null = null;