From cf6fabc0705e031ad8afcb3be6a6f658be2a0a01 Mon Sep 17 00:00:00 2001 From: arkon Date: Mon, 8 Jun 2026 15:41:46 +0200 Subject: [PATCH] fix(web): address self-review findings on #103 (master-safe defaults + hardening) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the branch genuinely master-mergeable and fix several review findings: - Defaults are now prod-safe: CODEMAN_INSTANCE defaults to '' (→ ~/.codeman, -L codeman) and the web port back to 3000, so an existing install upgrades cleanly. Port also honors a new CODEMAN_PORT env var. Run the beta isolated alongside prod with scripts/run-beta.sh (CODEMAN_INSTANCE=beta + PORT 5000). - .gitignore: anchor the root `public` symlink rule to `/public` (a bare `public` also swallowed src/web/public, silently un-staging new web assets); ignore the gesture wasm/model binaries explicitly instead. - span-displays: add a macOS-only guard (400 elsewhere instead of spawning a bash that fails invisibly); extract resolveSpanUrl() for unit testing. - server.ts: memoize asset-version stat() calls (~1s TTL) so each index render doesn't re-stat every script/link tag. - styles.css: hide the multi-monitor button in solo (detached) windows. - app.js: require two consecutive unanswered roll-calls before redocking, so a timer-throttled background popup isn't wrongly un-marked. - index.html: make the "skip to terminal" link base-href-safe (onclick scroll) so it doesn't navigate to the dashboard from a /session/:id window. - Tests: test/config/instance.test.ts, test/routes/system-span-displays.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 12 +++- CLAUDE.md | 6 +- scripts/fetch-gesture-assets.mjs | 4 +- scripts/run-beta.sh | 32 ++++++++++ src/cli.ts | 2 +- src/config/instance.ts | 22 ++++--- src/web/public/app.js | 15 ++++- src/web/public/index.html | 4 +- src/web/public/styles.css | 1 + src/web/routes/system-routes.ts | 28 +++++++-- src/web/server.ts | 44 ++++++++----- test/config/instance.test.ts | 79 ++++++++++++++++++++++++ test/routes/system-span-displays.test.ts | 76 +++++++++++++++++++++++ 13 files changed, 284 insertions(+), 41 deletions(-) create mode 100755 scripts/run-beta.sh create mode 100644 test/config/instance.test.ts create mode 100644 test/routes/system-span-displays.test.ts diff --git a/.gitignore b/.gitignore index c979337e..1950c2b8 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,17 @@ scripts/remotion/out/ # Artifacts that should not be tracked test-results/ tmp/ -public +# Root `public` (a symlink to scripts/remotion/public — local artifact). ANCHORED +# with a leading slash so it does NOT also match src/web/public (a bare `public` +# would swallow the whole web UI source dir and silently un-stage any new asset +# added there). No trailing slash so it still matches the symlink, not just dirs. +/public + +# Opt-in gesture overlay runtime assets: large MediaPipe wasm + model (~27 MB) +# fetched at build/install by scripts/fetch-gesture-assets.mjs, kept out of git. +# (The gesture bundle itself, gesture-codeman.js, IS tracked.) +src/web/public/gesture/wasm/ +src/web/public/gesture/*.task # Claude Code plan tracking plan.json diff --git a/CLAUDE.md b/CLAUDE.md index 56aa9fda..65bd5904 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,7 +30,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co 2. **Frontend changes**: Use Playwright to load the page and assert the UI renders correctly. Use `waitUntil: 'domcontentloaded'` (not `networkidle` — SSE keeps the connection open). Wait 3-4s for polling/async data to populate, then check element visibility, text content, and CSS values 3. **Only after verification passes**, proceed with COM -The production server caches static files for 1 year, `immutable` (`maxAge: '1y'` in `server.ts`). To avoid stale frontend after a deploy, `renderIndexHtml` runs `cacheBustAssets(html)` — it appends `?v=` to **every same-origin `.js`/`.css`** reference (re-stat'd per render; external/already-versioned/missing refs untouched). Because `index.html` is served `no-cache`, a **normal reload now picks up edited modules/styles — no hard refresh needed** (the gesture bundle is injected separately with its own `?v=`). If you add an asset referenced by an *absolute* URL or from JS rather than a `