Skill Tracer
Skills › gstack › setup-gbrain › brain-init.md

brain-init.md

269 lines · setup-gbrain/sections/brain-init.md at 3f79d81

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1<!-- AUTO-GENERATED from brain-init.md.tmpl — do not edit directly -->
2<!-- Regenerate: bun run gen:skill-docs -->
3Path-specific. Run ONLY the sub-section below for the path picked in Step 2
4(or the Switch flow when Step 2 chose engine migration).
5

<!-- AUTO-GENERATED from brain-init.md.tmpl — do not edit directly --> <!-- Regenerate: bun run gen:skill-docs --> Path-specific. Run ONLY the sub-section below for the path picked in Step 2 (or the Switch flow when Step 2 chose engine migration).

Raw lines 1 to 5
6### Path 1 (Supabase, existing URL)
7
8Source the secret-read helper, collect URL with `read -s` + redacted preview:
9
10```bash
11. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
12read_secret_to_env GBRAIN_POOLER_URL "Paste Session Pooler URL: " \
13 --echo-redacted 's#://[^@]*@#://***@#'
14```
16Then validate structurally:
18```bash
19printf '%s' "$GBRAIN_POOLER_URL" | ~/.claude/skills/gstack/bin/gstack-gbrain-supabase-verify -
20```
22If the verify exit code is 3 (direct-connection URL), the verifier's own
23message explains the fix; surface it and re-prompt for a Session Pooler URL.
25On success, hand off to gbrain via env var (never argv):
27```bash
28GBRAIN_DATABASE_URL="$GBRAIN_POOLER_URL" gbrain init --non-interactive --json
29```
31Then `unset GBRAIN_POOLER_URL GBRAIN_DATABASE_URL` immediately. The URL is
32now persisted in `~/.gbrain/config.json` at mode 0600 by gbrain itself.

Path 1 (Supabase, existing URL)

Source the secret-read helper, collect URL with read -s + redacted preview:

. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
read_secret_to_env GBRAIN_POOLER_URL "Paste Session Pooler URL: " \
  --echo-redacted 's#://[^@]*@#://***@#'

Then validate structurally:

printf '%s' "$GBRAIN_POOLER_URL" | ~/.claude/skills/gstack/bin/gstack-gbrain-supabase-verify -

If the verify exit code is 3 (direct-connection URL), the verifier's own message explains the fix; surface it and re-prompt for a Session Pooler URL.

On success, hand off to gbrain via env var (never argv):

GBRAIN_DATABASE_URL="$GBRAIN_POOLER_URL" gbrain init --non-interactive --json

Then unset GBRAIN_POOLER_URL GBRAIN_DATABASE_URL immediately. The URL is now persisted in ~/.gbrain/config.json at mode 0600 by gbrain itself.

Raw lines 6 to 33
Runs code bin/gstack-gbrain-lib.sh :11
Runs code bin/gstack-gbrain-supabase-verify :19
34### Path 2a (Supabase, auto-provision)
36Show this PAT scope disclosure verbatim BEFORE collecting the token:
38> *This Supabase Personal Access Token grants full read/write/delete access
39> to every project in your Supabase account, not just the `gbrain` one we're
40> about to create. Supabase doesn't currently support scoped tokens. We use
41> this PAT only to: create one project, poll it until healthy, read the
42> Session Pooler URL — then discard it from process memory. The token
43> remains valid on Supabase's side until you manually revoke it at
44> https://supabase.com/dashboard/account/tokens — we recommend revoking
45> immediately after setup completes.*
47Then:
49```bash
50. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
51read_secret_to_env SUPABASE_ACCESS_TOKEN "Paste PAT: "
52```
54Ask the tier question via AskUserQuestion: "Which Supabase tier?" Present
55Free (2-project limit, pauses after 7d inactivity) vs Pro ($25/mo, no
56pauses, recommended for real use). Explain that tier is **org-level** (per
57the Management API contract) — user picks their org based on its current
58tier. Pro may require them to upgrade the org first at supabase.com.
60List orgs, pick one (AskUserQuestion if multiple):
62```bash
63orgs=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision list-orgs --json)
64```
66If the `.orgs` array is empty, surface: "Your Supabase account has no
67organizations. Create one at https://supabase.com/dashboard, then re-run
68`/setup-gbrain`." STOP.
70Ask the user for a region (default `us-east-1`; valid values are the 18
71enum values in the Supabase Management API — list a few common ones, let
72them pick "Other" for a full list).
74Generate the DB password (never shown to the user):
76```bash
77export DB_PASS=$(openssl rand -base64 24)
78```
80Set up a SIGINT trap so an interrupted provision can be resumed or deleted:
82```bash
83trap 'echo ""; echo "gstack-gbrain: interrupted. In-flight ref: $INFLIGHT_REF"; \
84 echo "Resume: /setup-gbrain --resume-provision $INFLIGHT_REF"; \
85 echo "Delete: https://supabase.com/dashboard/project/$INFLIGHT_REF"; \
86 unset SUPABASE_ACCESS_TOKEN DB_PASS; exit 130' INT TERM
87```
89Create + wait + fetch:
91```bash
92result=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision \
93 create gbrain "$REGION" "$ORG_SLUG" --json)
94INFLIGHT_REF=$(echo "$result" | jq -r .ref)
95~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision wait "$INFLIGHT_REF" --json
96pooler=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision \
97 pooler-url "$INFLIGHT_REF" --json)
98GBRAIN_DATABASE_URL=$(echo "$pooler" | jq -r .pooler_url)
99export GBRAIN_DATABASE_URL
100gbrain init --non-interactive --json
101unset SUPABASE_ACCESS_TOKEN DB_PASS GBRAIN_DATABASE_URL INFLIGHT_REF
102trap - INT TERM
103```
105After success, emit the PAT revocation reminder:
107> "Setup complete. Revoke the PAT you pasted at
108> https://supabase.com/dashboard/account/tokens — we've already discarded
109> it from memory and don't need it again. The gbrain project will continue
110> working because it uses its own embedded database password."

Path 2a (Supabase, auto-provision)

Show this PAT scope disclosure verbatim BEFORE collecting the token:

*This Supabase Personal Access Token grants full read/write/delete access to every project in your Supabase account, not just the gbrain one we're about to create. Supabase doesn't currently support scoped tokens. We use this PAT only to: create one project, poll it until healthy, read the Session Pooler URL — then discard it from process memory. The token remains valid on Supabase's side until you manually revoke it at https://supabase.com/dashboard/account/tokens — we recommend revoking immediately after setup completes.*

Then:

. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
read_secret_to_env SUPABASE_ACCESS_TOKEN "Paste PAT: "

Ask the tier question via AskUserQuestion: "Which Supabase tier?" Present Free (2-project limit, pauses after 7d inactivity) vs Pro ($25/mo, no pauses, recommended for real use). Explain that tier is org-level (per the Management API contract) — user picks their org based on its current tier. Pro may require them to upgrade the org first at supabase.com.

List orgs, pick one (AskUserQuestion if multiple):

orgs=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision list-orgs --json)

If the .orgs array is empty, surface: "Your Supabase account has no organizations. Create one at https://supabase.com/dashboard, then re-run /setup-gbrain." STOP.

Ask the user for a region (default us-east-1; valid values are the 18 enum values in the Supabase Management API — list a few common ones, let them pick "Other" for a full list).

Generate the DB password (never shown to the user):

export DB_PASS=$(openssl rand -base64 24)

Set up a SIGINT trap so an interrupted provision can be resumed or deleted:

trap 'echo ""; echo "gstack-gbrain: interrupted. In-flight ref: $INFLIGHT_REF"; \
      echo "Resume: /setup-gbrain --resume-provision $INFLIGHT_REF"; \
      echo "Delete: https://supabase.com/dashboard/project/$INFLIGHT_REF"; \
      unset SUPABASE_ACCESS_TOKEN DB_PASS; exit 130' INT TERM

Create + wait + fetch:

result=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision \
  create gbrain "$REGION" "$ORG_SLUG" --json)
INFLIGHT_REF=$(echo "$result" | jq -r .ref)
~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision wait "$INFLIGHT_REF" --json
pooler=$(~/.claude/skills/gstack/bin/gstack-gbrain-supabase-provision \
  pooler-url "$INFLIGHT_REF" --json)
GBRAIN_DATABASE_URL=$(echo "$pooler" | jq -r .pooler_url)
export GBRAIN_DATABASE_URL
gbrain init --non-interactive --json
unset SUPABASE_ACCESS_TOKEN DB_PASS GBRAIN_DATABASE_URL INFLIGHT_REF
trap - INT TERM

After success, emit the PAT revocation reminder:

"Setup complete. Revoke the PAT you pasted at https://supabase.com/dashboard/account/tokens — we've already discarded it from memory and don't need it again. The gbrain project will continue working because it uses its own embedded database password."
Raw lines 34 to 111
Runs code bin/gstack-gbrain-lib.sh :50
Involves a person AskUserQuestion :54
Runs code bin/gstack-gbrain-supabase-provision :63
Involves a person Ask the user :70
112### Path 2b (Supabase, manual)
114Walk the user through the supabase.com steps:
1151. Login at https://supabase.com/dashboard
1162. Click "New Project," name it `gbrain`, pick a region, and copy the
117 generated database password — the pooler URL in step 4 must carry it
118 (replace any `[YOUR-PASSWORD]` placeholder before pasting)
1193. Wait ~2 min for the project to initialize
1204. Settings → Database → Connection Pooler → Session → copy the URL (port
121 6543)
123Then follow the same secret-read + verify + init flow as Path 1.

Path 2b (Supabase, manual)

Walk the user through the supabase.com steps:

  1. Login at https://supabase.com/dashboard
  2. Click "New Project," name it gbrain, pick a region, and copy the generated database password — the pooler URL in step 4 must carry it (replace any [YOUR-PASSWORD] placeholder before pasting)
  3. Wait ~2 min for the project to initialize
  4. Settings → Database → Connection Pooler → Session → copy the URL (port 6543)

Then follow the same secret-read + verify + init flow as Path 1.

Raw lines 112 to 124
125### Path 3 (PGLite local)
127```bash
128# gstack default: voyage-code-3 (1024d) when VOYAGE_API_KEY is set — code
129# retrieval beats general-purpose embeddings on real code queries (validated
130# A/B). Without the key, gbrain auto-selects (OpenAI 1536d when available).
131# Never select gbrain's legacy zeroentropyai recipe for a new brain: its hosted
132# API's sunset date (September 4, 2026) has passed; the wireup helper warns existing installs.
133set -- # flags ride the positional params — unquoted $VAR breaks under zsh word-splitting
134if [ -n "${VOYAGE_API_KEY:-}" ]; then
135 set -- --embedding-model voyage:voyage-code-3 --embedding-dimensions 1024
136fi
137gbrain init --pglite --json "$@"
138```
140Done. No network, no secrets (beyond Voyage embedding API calls during sync, if
141`VOYAGE_API_KEY` is set — ~$0.18 per 1M tokens, pennies per repo).

Path 3 (PGLite local)

# gstack default: voyage-code-3 (1024d) when VOYAGE_API_KEY is set — code
# retrieval beats general-purpose embeddings on real code queries (validated
# A/B). Without the key, gbrain auto-selects (OpenAI 1536d when available).
# Never select gbrain's legacy zeroentropyai recipe for a new brain: its hosted
# API's sunset date (September 4, 2026) has passed; the wireup helper warns existing installs.
set --  # flags ride the positional params — unquoted $VAR breaks under zsh word-splitting
if [ -n "${VOYAGE_API_KEY:-}" ]; then
  set -- --embedding-model voyage:voyage-code-3 --embedding-dimensions 1024
fi
gbrain init --pglite --json "$@"

Done. No network, no secrets (beyond Voyage embedding API calls during sync, if VOYAGE_API_KEY is set — ~$0.18 per 1M tokens, pennies per repo).

Raw lines 125 to 142
143### Path 4 (Remote gbrain MCP — HTTP transport with bearer token)
145For users whose brain runs on another machine (Tailscale, ngrok, internal
146LAN, or a teammate's server). No local gbrain CLI install, no local DB.
147This skill registers the remote MCP and stops; ingestion + indexing happens
148on the brain host.
150**4a. Collect MCP URL.** Prompt the user:
152```
153Paste your gbrain MCP URL (e.g. https://wintermute.tail554574.ts.net:3131/mcp):
154```
156Read with plain `read -r` (no secret hygiene needed — the URL alone isn't
157a credential). Validate it starts with `https://` (require TLS for any
158non-loopback host); refuse `http://` for non-localhost.
160**4b. Collect bearer token via the secret-read helper (never argv).**
162```bash
163. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
164read_secret_to_env GBRAIN_MCP_TOKEN "Paste bearer token: " \
165 --echo-redacted 's/.\{6\}$/***REDACTED***/'
166```
168**4c. Verify via gstack-gbrain-mcp-verify.** Run the helper; capture the
169classified JSON output:
171```bash
172verify_json=$(GBRAIN_MCP_TOKEN="$GBRAIN_MCP_TOKEN" \
173 ~/.claude/skills/gstack/bin/gstack-gbrain-mcp-verify "$MCP_URL")
174status=$(echo "$verify_json" | jq -r .status)
175```
177If `status != "success"`, the helper has already classified the failure
178into NETWORK / AUTH / MALFORMED and emitted a one-line remediation hint.
179Surface the hint above the raw error from `error_text` and **STOP** with
180a clear "fix and re-run /setup-gbrain" message. Do NOT continue to Step 5a
181on a failed verify — partial registration would leave the user with a
182half-broken state.
184Capture two values from the verify output for downstream steps:
185- `SERVER_VERSION` (e.g., `0.27.1`) — written to the CLAUDE.md block in Step 8.
186- `URL_FORM_SUPPORTED` (`true|false`) — passed to `gstack-artifacts-init` in
187 Step 7 to control which form of the brain-admin hookup command is printed.
189**4d. (Path 4) Offer local PGLite for code search.** Ask:
191> D# — Want symbol-aware code search on this machine?
192> Project/branch/task: <one-sentence grounding using detected slug + branch>
193> ELI10: The remote brain at `<MCP_URL>` is great for cross-machine knowledge,
194> but symbol queries like `gbrain code-def` / `code-refs` / `code-callers` need
195> a local index of THIS machine's code. We can spin up a tiny isolated PGLite
196> database (~30 seconds, no accounts, ~120 MB disk) just for code, separate
197> from your remote brain. Transcripts and artifacts continue routing through
198> the artifacts repo to the remote brain — local PGLite stays code-only.
199> Stakes: without it, semantic code search in this repo's worktrees falls
200> back to Grep.
201> Recommendation: A — 30 seconds, no ongoing cost, unlocks the symbol tools.
202> Completeness: A=10/10 (full split-engine), B=7/10 (remote-only).
203> A) Yes, set up local PGLite for code (recommended)
204> ✅ Unlocks `gbrain code-def`, `code-refs`, `code-callers` per worktree
205> ✅ Independent engine — won't disturb remote brain or share transcripts
206> B) No, remote MCP only
207> ✅ Zero local state — only `~/.claude.json` MCP registration
208> ❌ Symbol code queries fall back to Grep in this repo's worktrees
209> Net: A = full split-engine; B = remote-only.
211**If A (Yes)**: install + init local PGLite with rollback-safe semantics:
213```bash
214~/.claude/skills/gstack/bin/gstack-gbrain-install || exit $?
215# At this point the local gbrain CLI is on PATH. Init PGLite, but back up any
216# existing ~/.gbrain/config.json first (rollback if init fails).
217if [ -f "$HOME/.gbrain/config.json" ]; then
218 BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)"
219 mv "$HOME/.gbrain/config.json" "$BACKUP"
220fi
221# gstack default for local code-search PGLite: voyage-code-3 (1024d) when
222# VOYAGE_API_KEY is set. It wins the A/B over voyage-4-large and OpenAI
223# text-embedding-3-large on this codebase's symbol queries. Falls back to
224# gbrain's auto-selected provider when the key isn't present.
225set -- # flags ride the positional params — unquoted $VAR breaks under zsh word-splitting
226if [ -n "${VOYAGE_API_KEY:-}" ]; then
227 set -- --embedding-model voyage:voyage-code-3 --embedding-dimensions 1024
228fi
229if ! gbrain init --pglite --json "$@"; then
230 if [ -n "${BACKUP:-}" ] && [ -f "$BACKUP" ]; then mv "$BACKUP" "$HOME/.gbrain/config.json"; fi
231 echo "gbrain init failed. Existing config (if any) was restored. PGLite at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` to reset." >&2
232 echo "Continuing setup without local code search; you can re-run /setup-gbrain to retry." >&2
233fi
234```
236Then continue to Step 5a. The remote-http MCP registration in 5a runs
237unchanged; the local PGLite is independent of MCP registration (Claude Code talks
238to the remote brain via MCP for queries; `gbrain` CLI talks to local PGLite
239for code-def/refs/callers).
241**If B (No)**: skip the install + init. The local engine stays absent.
242`gbrain_local_status` will be `missing-config` (or `no-cli` if gbrain isn't
243installed). `/sync-gbrain` will SKIP the code stage cleanly.
245**4e. Skip Steps 3, 4 (other paths) and 5 (local doctor) when B was picked.**
246When A was picked, Step 3 already ran (via gstack-gbrain-install) and Step 4
247already ran (via `gbrain init --pglite`); jump straight to Step 5a. When B
248was picked, Steps 3/4/5 are no-ops; also skip Step 7.5 (transcript ingest)
249since memory-stage routes through the artifacts pipeline in remote-http mode.
251The bearer token (`GBRAIN_MCP_TOKEN`) stays in process env until Step 5a's
252`claude mcp add --header` consumes it; then `unset GBRAIN_MCP_TOKEN`
253immediately. Token security trade-off documented in
254`setup-gbrain/memory.md`: brief argv exposure during `claude mcp add`,
255resting state in `~/.claude.json` mode 0600.

Path 4 (Remote gbrain MCP — HTTP transport with bearer token)

For users whose brain runs on another machine (Tailscale, ngrok, internal LAN, or a teammate's server). No local gbrain CLI install, no local DB. This skill registers the remote MCP and stops; ingestion + indexing happens on the brain host.

4a. Collect MCP URL. Prompt the user:

Paste your gbrain MCP URL (e.g. https://wintermute.tail554574.ts.net:3131/mcp):

Read with plain read -r (no secret hygiene needed — the URL alone isn't a credential). Validate it starts with https:// (require TLS for any non-loopback host); refuse http:// for non-localhost.

4b. Collect bearer token via the secret-read helper (never argv).

. ~/.claude/skills/gstack/bin/gstack-gbrain-lib.sh
read_secret_to_env GBRAIN_MCP_TOKEN "Paste bearer token: " \
  --echo-redacted 's/.\{6\}$/***REDACTED***/'

4c. Verify via gstack-gbrain-mcp-verify. Run the helper; capture the classified JSON output:

verify_json=$(GBRAIN_MCP_TOKEN="$GBRAIN_MCP_TOKEN" \
  ~/.claude/skills/gstack/bin/gstack-gbrain-mcp-verify "$MCP_URL")
status=$(echo "$verify_json" | jq -r .status)

If status != "success", the helper has already classified the failure into NETWORK / AUTH / MALFORMED and emitted a one-line remediation hint. Surface the hint above the raw error from error_text and STOP with a clear "fix and re-run /setup-gbrain" message. Do NOT continue to Step 5a on a failed verify — partial registration would leave the user with a half-broken state.

Capture two values from the verify output for downstream steps:

  • SERVER_VERSION (e.g., 0.27.1) — written to the CLAUDE.md block in Step 8.
  • URL_FORM_SUPPORTED (true|false) — passed to gstack-artifacts-init in Step 7 to control which form of the brain-admin hookup command is printed.

4d. (Path 4) Offer local PGLite for code search. Ask:

D# — Want symbol-aware code search on this machine? Project/branch/task: <one-sentence grounding using detected slug + branch> ELI10: The remote brain at <MCP_URL> is great for cross-machine knowledge, but symbol queries like gbrain code-def / code-refs / code-callers need a local index of THIS machine's code. We can spin up a tiny isolated PGLite database (~30 seconds, no accounts, ~120 MB disk) just for code, separate from your remote brain. Transcripts and artifacts continue routing through the artifacts repo to the remote brain — local PGLite stays code-only. Stakes: without it, semantic code search in this repo's worktrees falls back to Grep. Recommendation: A — 30 seconds, no ongoing cost, unlocks the symbol tools. Completeness: A=10/10 (full split-engine), B=7/10 (remote-only). A) Yes, set up local PGLite for code (recommended) ✅ Unlocks gbrain code-def, code-refs, code-callers per worktree ✅ Independent engine — won't disturb remote brain or share transcripts B) No, remote MCP only ✅ Zero local state — only ~/.claude.json MCP registration ❌ Symbol code queries fall back to Grep in this repo's worktrees Net: A = full split-engine; B = remote-only.

If A (Yes): install + init local PGLite with rollback-safe semantics:

~/.claude/skills/gstack/bin/gstack-gbrain-install || exit $?
# At this point the local gbrain CLI is on PATH. Init PGLite, but back up any
# existing ~/.gbrain/config.json first (rollback if init fails).
if [ -f "$HOME/.gbrain/config.json" ]; then
  BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)"
  mv "$HOME/.gbrain/config.json" "$BACKUP"
fi
# gstack default for local code-search PGLite: voyage-code-3 (1024d) when
# VOYAGE_API_KEY is set. It wins the A/B over voyage-4-large and OpenAI
# text-embedding-3-large on this codebase's symbol queries. Falls back to
# gbrain's auto-selected provider when the key isn't present.
set --  # flags ride the positional params — unquoted $VAR breaks under zsh word-splitting
if [ -n "${VOYAGE_API_KEY:-}" ]; then
  set -- --embedding-model voyage:voyage-code-3 --embedding-dimensions 1024
fi
if ! gbrain init --pglite --json "$@"; then
  if [ -n "${BACKUP:-}" ] && [ -f "$BACKUP" ]; then mv "$BACKUP" "$HOME/.gbrain/config.json"; fi
  echo "gbrain init failed. Existing config (if any) was restored. PGLite at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` to reset." >&2
  echo "Continuing setup without local code search; you can re-run /setup-gbrain to retry." >&2
fi

Then continue to Step 5a. The remote-http MCP registration in 5a runs unchanged; the local PGLite is independent of MCP registration (Claude Code talks to the remote brain via MCP for queries; gbrain CLI talks to local PGLite for code-def/refs/callers).

If B (No): skip the install + init. The local engine stays absent. gbrain_local_status will be missing-config (or no-cli if gbrain isn't installed). /sync-gbrain will SKIP the code stage cleanly.

4e. Skip Steps 3, 4 (other paths) and 5 (local doctor) when B was picked. When A was picked, Step 3 already ran (via gstack-gbrain-install) and Step 4 already ran (via gbrain init --pglite); jump straight to Step 5a. When B was picked, Steps 3/4/5 are no-ops; also skip Step 7.5 (transcript ingest) since memory-stage routes through the artifacts pipeline in remote-http mode.

The bearer token (GBRAIN_MCP_TOKEN) stays in process env until Step 5a's claude mcp add --header consumes it; then unset GBRAIN_MCP_TOKEN immediately. Token security trade-off documented in setup-gbrain/memory.md: brief argv exposure during claude mcp add, resting state in ~/.claude.json mode 0600.

Raw lines 143 to 256
Uses an outside tool MCP :143
Runs code bin/gstack-gbrain-lib.sh :163
Runs code bin/gstack-gbrain-mcp-verify :173
Project instruction file CLAUDE.md :185
Runs code bin/gstack-gbrain-install :214
Names a skill sync-gbrain :243
257### Switch (from detect's existing-engine state)
259```bash
260# Going PGLite → Supabase, collect URL first (Path 1 flow), then:
261timeout 180s gbrain migrate --to supabase --url "$URL" --json
262# Going Supabase → PGLite:
263timeout 180s gbrain migrate --to pglite --json
264```
266If `timeout` returns 124 (exit code for timeout): surface this message
267("Migration didn't complete in 3 minutes — another gstack session may be
268holding a lock on the source brain. Close other workspaces and re-run
269`/setup-gbrain --switch`. Your original brain is untouched."). STOP.

Switch (from detect's existing-engine state)

# Going PGLite → Supabase, collect URL first (Path 1 flow), then:
timeout 180s gbrain migrate --to supabase --url "$URL" --json
# Going Supabase → PGLite:
timeout 180s gbrain migrate --to pglite --json

If timeout returns 124 (exit code for timeout): surface this message ("Migration didn't complete in 3 minutes — another gstack session may be holding a lock on the source brain. Close other workspaces and re-run /setup-gbrain --switch. Your original brain is untouched."). STOP.

Raw lines 257 to 269