diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fda72d1..d7ec612c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [1.12.2.0] - 2026-04-24 + +## **`/setup-gbrain` polish: PATH parsing, repo init order, MCP user scope.** + +Small refinements to the /setup-gbrain onboarding path. + +### Fixed +- `bin/gstack-gbrain-install`: parse `gbrain --version` output with `awk '{print $NF}'` so the D19 PATH-shadow check compares just the version number. +- `bin/gstack-brain-init`: omit `--source` from `gh repo create`. Later steps handle `git init` + remote setup explicitly. +- `setup-gbrain` Step 9: smoke test uses `gbrain put ` with body piped on stdin. +- `setup-gbrain` Step 5a: MCP registers with `--scope user` and an absolute path to the gbrain binary, so `mcp__gbrain__*` tools are available in every Claude Code session on the machine. + +### Changed +- `test/gstack-brain-init-gh-mock.test.ts`: asserts `--source` is absent from the `gh repo create` call. + ## [1.12.1.0] - 2026-04-24 ## **Plan-mode review skills run the review directly, no more "exit and rerun" prompt.** diff --git a/VERSION b/VERSION index 2255ba16..b3dd6a99 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.12.1.0 +1.12.2.0 diff --git a/bin/gstack-brain-init b/bin/gstack-brain-init index 6399c12c..3ed48559 100755 --- a/bin/gstack-brain-init +++ b/bin/gstack-brain-init @@ -86,7 +86,10 @@ if [ -z "$REMOTE_URL" ]; then read -r REPLY || REPLY="" if [ -z "$REPLY" ]; then echo "Creating GitHub repo: $DEFAULT_NAME ..." - if ! gh repo create "$DEFAULT_NAME" --private --description "gstack session memory" --source "$GSTACK_HOME" 2>/dev/null; then + # Note: --source omitted intentionally. gh requires --source to point at + # an existing git repo, but we don't init $GSTACK_HOME until after the + # remote is chosen. Create bare, then fetch URL. + if ! gh repo create "$DEFAULT_NAME" --private --description "gstack session memory" 2>/dev/null; then # Maybe the repo already exists; try to fetch its URL. REMOTE_URL=$(gh repo view "$DEFAULT_NAME" --json sshUrl -q .sshUrl 2>/dev/null || echo "") if [ -z "$REMOTE_URL" ]; then diff --git a/bin/gstack-gbrain-install b/bin/gstack-gbrain-install index c5bfa991..c247ff2d 100755 --- a/bin/gstack-gbrain-install +++ b/bin/gstack-gbrain-install @@ -151,7 +151,7 @@ if ! command -v gbrain >/dev/null 2>&1; then fail "bun link completed but 'gbrain' is not on PATH. Ensure ~/.bun/bin is in your PATH." fi -actual_version=$(gbrain --version 2>/dev/null | head -1 | tr -d '[:space:]' || true) +actual_version=$(gbrain --version 2>/dev/null | head -1 | awk '{print $NF}' | tr -d '[:space:]' || true) if [ -z "$actual_version" ]; then fail "gbrain is on PATH but 'gbrain --version' produced no output — the binary may be broken." fi diff --git a/package.json b/package.json index 3f6a0e00..89af11ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.12.1.0", + "version": "1.12.2.0", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/setup-gbrain/SKILL.md b/setup-gbrain/SKILL.md index 9db96bd4..639ab11b 100644 --- a/setup-gbrain/SKILL.md +++ b/setup-gbrain/SKILL.md @@ -1283,17 +1283,33 @@ doctor output and STOP. Only if `which claude` resolves. Ask: "Give Claude Code a typed tool surface for gbrain? (recommended yes)" -If yes: +If yes, register at **user scope** with an **absolute path** to the gbrain +binary. User scope makes the MCP available in every Claude Code session on +this machine, not just the current workspace. Absolute path avoids PATH +resolution issues when Claude Code spawns `gbrain serve` as a subprocess. ```bash -claude mcp add gbrain -- gbrain serve -claude mcp list | grep gbrain # verify +GBRAIN_BIN=$(command -v gbrain) +[ -z "$GBRAIN_BIN" ] && GBRAIN_BIN="$HOME/.bun/bin/gbrain" +claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve +claude mcp list | grep gbrain # verify: should show "✓ Connected" +``` + +If the user already had a local-scope registration from an earlier run, +remove it first so both scopes don't conflict: +```bash +claude mcp remove gbrain 2>/dev/null || true ``` If `claude` is not on PATH: emit "MCP registration skipped — this skill is Claude-Code-targeted; register `gbrain serve` in your agent's MCP config manually." Continue to step 6. +**Heads-up for the user:** an already-open Claude Code session will not +pick up the new MCP tools until restart. Tell them: "Restart any open +Claude Code sessions to see `mcp__gbrain__*` tools — they're loaded at +session start, not mid-session." + --- ## Step 6: Per-remote policy (D3 triad, gated repo-import) @@ -1368,9 +1384,9 @@ Find-and-replace (or append) this section in CLAUDE.md: ## Step 9: Smoke test ```bash -gbrain put_page --title "setup-gbrain smoke test" --tags "meta" \ - <<<"Set up on $(date)" -gbrain search "smoke test" | grep -i "setup-gbrain smoke test" +SLUG="setup-gbrain-smoke-test-$(date +%s)" +echo "Set up on $(date). Smoke test for /setup-gbrain." | gbrain put "$SLUG" +gbrain search "smoke test" | grep -i "$SLUG" ``` Confirms the round trip. On failure, surface `gbrain doctor --json` output diff --git a/setup-gbrain/SKILL.md.tmpl b/setup-gbrain/SKILL.md.tmpl index 1abe7a46..685e15e0 100644 --- a/setup-gbrain/SKILL.md.tmpl +++ b/setup-gbrain/SKILL.md.tmpl @@ -285,17 +285,33 @@ doctor output and STOP. Only if `which claude` resolves. Ask: "Give Claude Code a typed tool surface for gbrain? (recommended yes)" -If yes: +If yes, register at **user scope** with an **absolute path** to the gbrain +binary. User scope makes the MCP available in every Claude Code session on +this machine, not just the current workspace. Absolute path avoids PATH +resolution issues when Claude Code spawns `gbrain serve` as a subprocess. ```bash -claude mcp add gbrain -- gbrain serve -claude mcp list | grep gbrain # verify +GBRAIN_BIN=$(command -v gbrain) +[ -z "$GBRAIN_BIN" ] && GBRAIN_BIN="$HOME/.bun/bin/gbrain" +claude mcp add --scope user gbrain -- "$GBRAIN_BIN" serve +claude mcp list | grep gbrain # verify: should show "✓ Connected" +``` + +If the user already had a local-scope registration from an earlier run, +remove it first so both scopes don't conflict: +```bash +claude mcp remove gbrain 2>/dev/null || true ``` If `claude` is not on PATH: emit "MCP registration skipped — this skill is Claude-Code-targeted; register `gbrain serve` in your agent's MCP config manually." Continue to step 6. +**Heads-up for the user:** an already-open Claude Code session will not +pick up the new MCP tools until restart. Tell them: "Restart any open +Claude Code sessions to see `mcp__gbrain__*` tools — they're loaded at +session start, not mid-session." + --- ## Step 6: Per-remote policy (D3 triad, gated repo-import) @@ -370,9 +386,9 @@ Find-and-replace (or append) this section in CLAUDE.md: ## Step 9: Smoke test ```bash -gbrain put_page --title "setup-gbrain smoke test" --tags "meta" \ - <<<"Set up on $(date)" -gbrain search "smoke test" | grep -i "setup-gbrain smoke test" +SLUG="setup-gbrain-smoke-test-$(date +%s)" +echo "Set up on $(date). Smoke test for /setup-gbrain." | gbrain put "$SLUG" +gbrain search "smoke test" | grep -i "$SLUG" ``` Confirms the round trip. On failure, surface `gbrain doctor --json` output diff --git a/test/gstack-brain-init-gh-mock.test.ts b/test/gstack-brain-init-gh-mock.test.ts index 7d3e85c8..ff7d98cb 100644 --- a/test/gstack-brain-init-gh-mock.test.ts +++ b/test/gstack-brain-init-gh-mock.test.ts @@ -134,8 +134,10 @@ describe('gstack-brain-init uses gh CLI when present + authed', () => { expect(createCall).toContain('gstack-brain-testuser'); expect(createCall).toContain('--private'); expect(createCall).toContain('--description'); - expect(createCall).toContain('--source'); - expect(createCall).toContain(tmpHome); + // --source is intentionally omitted: gh requires the source dir to already + // be a git repo, but brain-init doesn't `git init $GSTACK_HOME` until later. + // Creating bare and wiring up the remote explicitly avoids that ordering bug. + expect(createCall).not.toContain('--source'); }); test('falls back to gh repo view when create reports already-exists', () => {