diff --git a/CHANGELOG.md b/CHANGELOG.md index e922cbba..af371de4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,19 +5,38 @@ ### Fixed - Cookie import picker now returns JSON instead of HTML — `jsonResponse()` referenced `url` out of scope, crashing every API call - `help` command routed correctly (was unreachable due to META_COMMANDS dispatch ordering) +- Stale servers from global install no longer shadow local changes — removed legacy `~/.claude/skills/gstack` fallback from `resolveServerScript()` ### Added +- **Project-local browse state** — state file, logs, and all server state now live in `.gstack/` inside the project root (detected via `git rev-parse --show-toplevel`). No more `/tmp` state files. +- **Shared config module** (`browse/src/config.ts`) — centralizes path resolution for CLI and server, eliminates duplicated port/state logic +- **Random port selection** — server picks a random port 10000-60000 instead of scanning 9400-9409. No more CONDUCTOR_PORT magic offset. No more port collisions across workspaces. +- **Binary version tracking** — state file includes `binaryVersion` SHA; CLI auto-restarts the server when the binary is rebuilt +- **Legacy /tmp cleanup** — CLI scans for and removes old `/tmp/browse-server*.json` files, verifying PID ownership before sending signals - `help` command — agents can self-discover all commands and snapshot flags - Version-aware `find-browse` with META signal protocol — detects stale binaries and prompts agents to update - `browse/dist/find-browse` compiled binary with git SHA comparison against origin/main (4hr cached) - `.version` file written at build time for binary version tracking - Route-level tests for cookie picker (13 tests) and find-browse version check (10 tests) +- Config resolution tests (14 tests) covering git root detection, BROWSE_STATE_FILE override, ensureStateDir, readVersionHash, resolveServerScript, and version mismatch detection +- Browser interaction guidance in CLAUDE.md — prevents Claude from using mcp\_\_claude-in-chrome\_\_\* tools +- CONTRIBUTING.md with quick start, dev mode explanation, and instructions for testing branches in other repos ### Changed +- State file location: `.gstack/browse.json` (was `/tmp/browse-server.json`) +- Log files location: `.gstack/browse-{console,network,dialog}.log` (was `/tmp/browse-*.log`) +- Atomic state file writes: `.json.tmp` → rename (prevents partial reads) +- CLI passes `BROWSE_STATE_FILE` to spawned server (server derives all paths from it) - SKILL.md setup checks parse META signals and handle `META:UPDATE_AVAILABLE` - `jsonResponse`/`errorResponse` use options objects to prevent positional parameter confusion - Build script compiles both `browse` and `find-browse` binaries, cleans up `.bun-build` temp files +### Removed +- `CONDUCTOR_PORT` magic offset (`browse_port = CONDUCTOR_PORT - 45600`) +- Port scan range 9400-9409 +- Legacy fallback to `~/.claude/skills/gstack/browse/src/server.ts` +- `DEVELOPING_GSTACK.md` (renamed to CONTRIBUTING.md) + ## 0.3.1 — 2026-03-12 ### Phase 3.5: Browser cookie import diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1e182dc..d6969048 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,6 +78,70 @@ Tests run against the browse binary directly — they don't require dev mode. - **Conductor workspaces are independent.** Each workspace is its own clone. Run `bin/dev-setup` in the one you're working in. - **`.claude/skills/` is gitignored.** The symlinks never get committed. +## Testing a branch in another repo + +When you're developing gstack in one workspace and want to test your branch in a +different project (e.g. testing browse changes against your real app), there are +two cases depending on how gstack is installed in that project. + +### Global install only (no `.claude/skills/gstack/` in the project) + +Point your global install at the branch: + +```bash +cd ~/.claude/skills/gstack +git fetch origin +git checkout origin/ # e.g. origin/v0.3.2 +bun install # in case deps changed +bun run build # rebuild the binary +``` + +Now open Claude Code in the other project — it picks up skills from +`~/.claude/skills/` automatically. To go back to main when you're done: + +```bash +cd ~/.claude/skills/gstack +git checkout main && git pull +bun run build +``` + +### Vendored project copy (`.claude/skills/gstack/` checked into the project) + +Some projects vendor gstack by copying it into the repo (no `.git` inside the +copy). Project-local skills take priority over global, so you need to update +the vendored copy too. This is a three-step process: + +1. **Update your global install to the branch** (so you have the source): + ```bash + cd ~/.claude/skills/gstack + git fetch origin + git checkout origin/ # e.g. origin/v0.3.2 + bun install && bun run build + ``` + +2. **Replace the vendored copy** in the other project: + ```bash + cd /path/to/other-project + + # Remove old skill symlinks and vendored copy + for s in browse plan-ceo-review plan-eng-review review ship retro qa setup-browser-cookies; do + rm -f .claude/skills/$s + done + rm -rf .claude/skills/gstack + + # Copy from global install (strips .git so it stays vendored) + cp -Rf ~/.claude/skills/gstack .claude/skills/gstack + rm -rf .claude/skills/gstack/.git + + # Rebuild binary and re-create skill symlinks + cd .claude/skills/gstack && ./setup + ``` + +3. **Test your changes** — open Claude Code in that project and use the skills. + +To revert to main later, repeat steps 1-2 with `git checkout main && git pull` +instead of `git checkout origin/`. + ## Shipping your changes When you're happy with your skill edits: diff --git a/README.md b/README.md index d07a9463..4bcfe619 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ gstack is powerful with one Claude Code session. It is transformative with ten. [Conductor](https://conductor.build) runs multiple Claude Code sessions in parallel — each in its own isolated workspace. That means you can have one session running `/qa` on staging, another doing `/review` on a PR, a third implementing a feature, and seven more working on other branches. All at the same time. -gstack is Conductor-aware out of the box. Each workspace gets its own isolated browser instance (separate Chromium process, cookies, tabs, and logs) so `/browse` and `/qa` sessions never collide. No configuration needed — it just works. +Each workspace gets its own isolated browser instance automatically — separate Chromium process, cookies, tabs, and logs stored in `.gstack/` inside each project root. No port collisions, no shared state, no configuration needed. `/browse` and `/qa` sessions never interfere with each other, even across ten parallel workspaces. This is the setup I use. One person, ten parallel agents, each with the right cognitive mode for its task. That is not incremental improvement. That is a different way of building software. @@ -342,6 +342,8 @@ I want the plane landed. [Greptile](https://greptile.com) is a YC company that reviews your PRs automatically. It catches real bugs — race conditions, security issues, things that pass CI and blow up in production. It has genuinely saved my ass more than once. I love these guys. +**Setup:** Install Greptile on your GitHub repo at [greptile.com](https://greptile.com) — it takes about 30 seconds. Once it's reviewing your PRs, gstack picks up its comments automatically. No additional configuration. + The problem with any automated reviewer is triage. Greptile is good, but not every comment is a real issue. Some are false positives. Some flag things you already fixed three commits ago. Without a triage layer, the comments pile up and you start ignoring them — which defeats the purpose. gstack solves this. `/review` and `/ship` are now Greptile-aware. They read Greptile's comments, classify each one, and take action: