v1.12.2.0 fix: /setup-gbrain day-two fixes (MCP scope, version parse, gh repo create order, smoke test) (#1187)

* fix: parse gbrain --version without "gbrain" prefix

Installer's D19 PATH-shadow check compared `expected_version` from
package.json against `actual_version` from `gbrain --version`. The
output is "gbrain 0.18.2" with a literal prefix; `tr -d '[:space:]'`
left "gbrain0.18.2" which never matched "0.18.2", causing every
fresh install to exit 3 with a false-positive shadowing error.

Use `awk '{print $NF}'` to grab just the last whitespace-separated
token before stripping whitespace.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(brain-init): drop --source flag before git init

gstack-brain-init used `gh repo create --source $GSTACK_HOME` before
running `git init` on that directory. gh requires --source to point at
an existing git repo, so the call fails with "not a git repository"
on first run. The fallback path (gh repo view) could only recover if
the repo was somehow pre-created — which it wasn't.

Fix: omit --source from `gh repo create`. The script's later steps
(git init, remote add, push) wire up the remote explicitly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(setup-gbrain): smoke test command + MCP user scope with absolute path

Three Step 5a/9 defects found running /setup-gbrain end-to-end:

1. Step 9 smoke test used `gbrain put_page --title ... --tags ...`,
   which doesn't exist. The real command is `gbrain put <slug>` with
   body piped on stdin. Updated to match.

2. Step 5a registered MCP with `claude mcp add gbrain -- gbrain serve`.
   Default scope is local (per-workspace), so other projects never saw
   gbrain. Cross-session memory is the whole point — user scope is
   correct.

3. Step 5a passed `gbrain` by bare name, relying on PATH being resolved
   when Claude Code spawns the subprocess. Fragile across shell configs.
   Use absolute path from `command -v gbrain` with ~/.bun/bin/gbrain
   fallback.

Also: remove any stale local-scope registration before re-adding, and
tell the user that open Claude Code sessions need a restart to see
the new mcp__gbrain__* tools (loaded at session start, not mid-session).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump version and changelog (v1.12.1.0)

Also updates test/gstack-brain-init-gh-mock.test.ts to match the fixed
behavior of bin/gstack-brain-init (the assertion previously required
`--source`, which was the bug being fixed in 04185d8f).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: tighten CHANGELOG entry for v1.12.1.0

Shorter, matter-of-fact list of the fixes. No preamble.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-04-24 07:51:46 -07:00
committed by GitHub
parent aeea57f96a
commit 6209163900
8 changed files with 70 additions and 18 deletions
+15
View File
@@ -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 <slug>` 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.**
+1 -1
View File
@@ -1 +1 @@
1.12.1.0
1.12.2.0
+4 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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",
+22 -6
View File
@@ -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
+22 -6
View File
@@ -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
+4 -2
View File
@@ -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', () => {