From d0d37f4a58e3b5229251fdd0c6a33dc2e8092464 Mon Sep 17 00:00:00 2001 From: Valerii Kovalskii Date: Wed, 22 Jul 2026 08:17:28 +0300 Subject: [PATCH] docs: update CLAUDE.md for the super-app + signed-desktop reality Bring the project guide in line with this release cycle: - super-app framing (Overview landing + in-browser Workspace/Terminal) and two-channel shipping (npm CLI + signed/notarized macOS DMG) - current source map (terminal.js, workspace-layouts/commands.js, shell-path.js, overview/workspace/calendar frontend, desktop/ shell + preload IPC) - architecture decisions: crash-safe route dispatch, prototype-safe findSessionFile, thin desktop shell, view-aware chrome, running-agents tree from activeSessions, full-pane layout round-trip, no window.prompt in Electron - new API/WS route groups (browser terminal, workspace layouts/commands, projects) - Publishing: manual npm workflow_dispatch + signed-DMG runbook with the codesign timestamp/proxy gotcha; versioning examples bumped to 7.x Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 572c217..653d6b4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,23 +4,42 @@ Codbash (`codbash-app` on npm) is a zero-dependency Node.js browser dashboard for managing AI coding agent sessions. Supports 7 agents: Claude Code, Codex, Cursor, OpenCode, Kiro CLI, Kilo CLI, Copilot Chat. Single `npm i -g codbash-app && codbash run` opens a local web UI. +It ships in **two channels from one codebase**: the npm CLI (browser UI) and a **signed + notarized macOS desktop app** (Electron shell in `desktop/` wrapping the unmodified server). Latest release: **7.14.7**. + +The dashboard has grown into a "super-app": an **Overview** landing view (headline stats + recent sessions + live terminals grouped by project) and an in-browser **Workspace / Terminal** (xterm.js + optional `@lydell/node-pty` over a hand-rolled WebSocket) with tabs, 1–4 splits, saved layouts, and per-project spawning. + ## Project structure ``` bin/cli.js CLI entry point (run/list/stats/search/show/handoff/convert/export/import/update/restart/stop) src/ - server.js HTTP server + all API routes - data.js Session loading, search index, cost calculation, active detection for all 6 agents - terminals.js Terminal detection (iTerm2/Terminal.app/Warp/Kitty/cmux) + launch/focus + server.js HTTP server + all API routes + terminal WebSocket + data.js Session loading, search index, cost calculation, active detection for all agents + terminals.js Native terminal detection (iTerm2/Terminal.app/Warp/Kitty/cmux) + launch/focus + terminal.js Browser-terminal pty session (spawn/resolveCwd) for the Workspace view + workspace-layouts.js Saved Workspace layouts (panes: cmd/prefill/cwd) persisted to disk + workspace-commands.js Saved Workspace quick-commands + shell-path.js Repairs a stripped PATH from the login shell (GUI-launch agent detection) + agents-detect.js Detects which agent CLIs are installed + projects.js Project launcher registry (add/list/remove) html.js Assembles HTML by inlining CSS+JS into template - migrate.js Export/import sessions as tar.gz + migrate.js Export/import sessions as tar.gz (merges history, never overwrites) convert.js Cross-agent session conversion (Claude <-> Codex) handoff.js Generate context documents for session handoff between agents changelog.js In-app changelog data frontend/ index.html HTML template with {{STYLES}} and {{SCRIPT}} placeholders styles.css All CSS including dark/light/monokai themes - app.js All frontend JavaScript (no build step, plain browser JS) + app.js Core frontend JS (routing, cards, delete, keyboard nav) — plain browser JS + overview.js Overview landing view (default): stats + recent sessions + live terminals + workspace.js In-browser Workspace/Terminal (xterm.js, tabs, splits, layouts, running tree) + calendar.js Calendar/heatmap sidebar + view routing + (analytics/detail/cloud/leaderboard/recommended/heatmap/sidebar-config).js +desktop/ Electron desktop app (signed + notarized macOS DMG) + main.js Electron main: spawns the unmodified server as a Node child + IPC + preload.js contextBridge -> window.codbashDesktop (isDesktop, pickFolder) + scripts/notarize.js afterSign notarization hook (keychain profile or APPLE_* env) + RELEASE.md Signed-release build/notarize runbook (READ before cutting a DMG) docs/ README_RU.md Russian translation README_ZH.md Chinese translation @@ -51,6 +70,12 @@ docs/ - **Active session detection** — reads Claude PID files + scans `ps` for all agent processes (claude, codex, opencode, kiro-cli, cursor-agent) - **Cursor sessions** — always show "Open in Cursor" button, never "Focus Terminal". Check tool type BEFORE active status. - **cmux support** — walks parent process chain (up to 6 levels) to detect cmux, then activates via AppleScript +- **Crash-safety** — every HTTP route dispatch is wrapped in try/catch → 500 (one bad session never takes down the server); `findSessionFile` looks up its index with `Object.prototype.hasOwnProperty.call(...)` to avoid prototype-pollution DoS; delete / bulk-delete validate `SAFE_SESSION_ID` +- **Desktop app is a thin shell** — `desktop/main.js` spawns the *unmodified* server as a Node child and points a `BrowserWindow` at it. Keep the server desktop-agnostic; desktop-only capabilities are exposed through `preload.js` (`window.codbashDesktop`) and detected at runtime in the frontend (e.g. the native folder picker is only wired up when `window.codbashDesktop.pickFolder` exists) +- **View-aware chrome** — `render()` stamps `document.body` with `data-view`; the session toolbar is hidden in Overview/Workspace via `body[data-view="workspace"|"overview"] .toolbar { display:none }` +- **Running-agents sidebar tree** (Workspace) is built from `activeSessions` grouped by real `cwd` and labeled by agent — do NOT reconstruct it from static project config +- **Saved layouts round-trip the full pane** — `sanitizePane` preserves `cmd` + `prefill` + `cwd` (not just `cmd`); dropping any of these silently loses the user's launch command on restore +- **No `window.prompt` in Electron** — use `codbashPrompt()` (app.js) for any text input; the native prompt is a no-op in the desktop shell ## API routes @@ -77,6 +102,19 @@ POST /api/convert Convert session between agents POST /api/bulk-delete Delete multiple sessions DELETE /api/session/:id Delete single session GET /api/session/:id/export Download session as Markdown + +# Workspace / browser terminal +WS /ws/terminal Browser-terminal pty (hand-rolled upgrade, no `ws` dep; token-gated) +GET /api/terminal/status Terminal availability + per-process WS token +GET/POST/DELETE /api/terminal/layouts[/:id] Saved Workspace layouts (panes: cmd/prefill/cwd) +GET/POST/DELETE /api/terminal/commands[/:id] Saved Workspace quick-commands +# Projects launcher +GET/POST/DELETE /api/projects/manual[/:id] Manually-added project folders +POST /api/projects/clone git clone into a project folder +# Misc (added this line) +GET /api/agents/installed Which agent CLIs are installed +GET /api/settings Read/write user settings +# (auth, cloud sync, github, leaderboard, repo-refresh route groups also exist) ``` ## Important conventions @@ -86,6 +124,8 @@ GET /api/session/:id/export Download session as Markdown - localStorage keys: `codedash-stars`, `codedash-tags`, `codedash-terminal`, `codedash-theme`, `codedash-layout`, `codedash-last-version` - System messages from Codex/Kiro (AGENTS.md, permissions, exit) are filtered via `isSystemMessage()` - Cursor `` wrappers are stripped in `loadCursorDetail()` +- **GUI-launch PATH repair** — when the desktop app opens from Finder/Dock macOS hands it a stripped `PATH`, so installed agent CLIs go undetected. `src/shell-path.js` re-derives `PATH` from the user's login shell on startup (opt out: `CODBASH_NO_PATH_REPAIR=1`) +- Session cards carry a native-terminal launch button (resume the agent's last project session; Cursor cards open in Cursor; hidden for copilot-chat) ## Git workflow @@ -123,8 +163,8 @@ gh pr merge --squash **IMPORTANT: Do not bump versions aggressively.** -- **Patch** (6.0.x): bug fixes, small CSS tweaks, typos — most changes go here -- **Minor** (6.x.0): new features that don't break existing functionality — new views, new CLI commands, new agent support +- **Patch** (7.14.x): bug fixes, small CSS tweaks, typos — most changes go here +- **Minor** (7.x.0): new features that don't break existing functionality — new views, new CLI commands, new agent support - **Major** (x.0.0): breaking changes only — changed API format, removed features, Node version bump, major rewrites Group multiple small fixes into ONE patch release instead of publishing each fix separately. Aim for 1-3 releases per work session, not 20+. @@ -133,13 +173,19 @@ Before bumping minor/major, ask: "Does this really warrant a version bump, or ca ## Publishing +Two independent channels, one codebase. Bump the version once (in `package.json`, `desktop/package.json`, and `src/changelog.js`) on a `release/` branch → PR → merge to main, then publish each channel. + +**npm CLI:** ```bash -# From a release branch: -git checkout -b release/6.x.x -# Bump version in package.json, commit, push, create PR -# After merge to main: git checkout main && git pull npm publish --access public ``` +`.github/workflows/publish.yml` is **manual** (`workflow_dispatch`), NOT auto-on-release — it fails early if `NPM_TOKEN` is missing. Never persist the npm publish token: write a transient `.npmrc`, publish, delete it. + +**macOS desktop (signed + notarized DMG)** — follow `desktop/RELEASE.md`. Key gotchas: +- Sign with Developer ID (team **A933C2TJXU**); notarize via the macOS keychain profile `codbash-notary` (`notarize.js` reads `APPLE_KEYCHAIN_PROFILE`). Do NOT store Apple credentials in the repo (public) — keychain only. +- **Timestamp gotcha**: `codesign --timestamp` ignores `HTTPS_PROXY` (uses the system network stack), so a corporate proxy blocks `timestamp.apple.com` → "The timestamp service is not available". Build over VPN with proxy env unset (`env -u HTTPS_PROXY -u HTTP_PROXY -u ALL_PROXY …`). Apple's TSA also rate-limits per-IP under burst — switch VPN endpoint or wait if throttled. +- electron-builder: the CLI target arg overrides the config `arch` array — pass `--arm64 --x64` explicitly. `identity` must be WITHOUT the `Developer ID Application:` prefix. +- Notarize + `stapler staple` each DMG *after* signing; stapling mutates the DMG, so regenerate blockmaps + `latest-mac.yml` afterward. `spctl -a -t open` on a raw DMG is a false negative (the container isn't code-signed) — verify with a quarantined mount instead. Package name: `codbash-app`, binary name: `codbash` (legacy alias `codedash` also works)