Install
$ agentstack add skill-timurgaleev-vibestack-setup-memory Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
When to invoke
Use when: "setup memory", "setup secondbrain", "connect secondbrain", "start secondbrain", "install secondbrain", "configure memory for this machine".
Preamble
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l /dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
~/.vibestack/bin/vibe-learnings-search --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi
{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
/setup-memory — Persistent Memory Setup
You are setting up persistent memory for this coding agent. The underlying engine is secondbrain, a knowledge base that runs as both a CLI and an MCP tool on the user's local Mac.
Scope honesty: This skill's MCP registration step (5a) uses claude mcp add and targets Claude Code specifically. Other local hosts (Cursor, Codex CLI, etc.) will still get the secondbrain CLI on PATH — they can register secondbrain serve in their own MCP config manually after setup.
Audience: local-Mac users. openclaw/hermes agents typically run in cloud docker containers with their own memory engine; "sharing" a brain between them and local Claude Code is only possible through shared Postgres (Supabase).
User-invocable
When the user types /setup-memory, run this skill. Three shortcut modes:
/setup-memory— full flow (default)/setup-memory --repo— only flip the per-remote policy for the current repo/setup-memory --switch— only migrate the engine (PGLite ↔ Supabase)/setup-memory --resume-provision— re-enter a previously interrupted
Supabase auto-provision at the polling step
/setup-memory --cleanup-orphans— list + delete in-flight Supabase projects
Parse the invocation args yourself — these are prose hints to the skill, not implemented as a dispatcher binary.
Concurrent-run lock
At skill start:
mkdir ~/.vibestack/.setup-memory.lock.d 2>/dev/null || {
echo "Another /setup-memory instance is running. Wait for it, or remove the lock with:"
echo " rm -rf ~/.vibestack/.setup-memory.lock.d"
exit 1
}
Release the lock on normal exit AND in the SIGINT trap.
Step 1: Detect current state
SBRAIN_ON_PATH=false
SBRAIN_VERSION=""
SBRAIN_CONFIG_EXISTS=false
SBRAIN_ENGINE=""
SBRAIN_DOCTOR_OK=false
MEMORY_SYNC_MODE=""
command -v secondbrain >/dev/null 2>&1 && SBRAIN_ON_PATH=true
$SBRAIN_ON_PATH && SBRAIN_VERSION=$(secondbrain --version 2>/dev/null || echo "")
[ -f "$HOME/.secondbrain/config.json" ] && SBRAIN_CONFIG_EXISTS=true
if $SBRAIN_CONFIG_EXISTS; then
SBRAIN_ENGINE=$(python3 -c "import json; d=json.load(open('$HOME/.secondbrain/config.json')); print(d.get('engine',''))" 2>/dev/null || echo "")
fi
if $SBRAIN_ON_PATH; then
secondbrain doctor --json >/tmp/vibe-memory-doctor.json 2>/dev/null
STATUS=$(python3 -c "import json; d=json.load(open('/tmp/vibe-memory-doctor.json')); print(d.get('status',''))" 2>/dev/null || echo "")
[ "$STATUS" = "ok" ] || [ "$STATUS" = "warnings" ] && SBRAIN_DOCTOR_OK=true
fi
MEMORY_SYNC_MODE=$(vibe-config get memory_sync_mode 2>/dev/null || echo "")
echo "Detected: memory_engine=secondbrain on_path=$SBRAIN_ON_PATH version=${SBRAIN_VERSION:-none} engine=${SBRAIN_ENGINE:-none} doctor_ok=$SBRAIN_DOCTOR_OK sync=${MEMORY_SYNC_MODE:-off}"
Report the detected state in one line. Skip downstream steps that are already done.
Branch on the --repo, --switch, --resume-provision, --cleanup-orphans invocation flags here and skip to the matching step.
Also capture sbrain_local_status (one of ok, broken-db, broken-config, no-cli, missing-config), sbrain_mcp_name (the registered MCP name — memex, secondbrain, or other compliant brand) and sbrain_mcp_mode (local-stdio, remote-http, or empty) so Step 1.5 and Step 2 can branch on them. Compute them inline:
SBRAIN_LOCAL_STATUS="ok"
if ! $SBRAIN_ON_PATH; then
SBRAIN_LOCAL_STATUS="no-cli"
elif ! $SBRAIN_CONFIG_EXISTS; then
SBRAIN_LOCAL_STATUS="missing-config"
elif ! $SBRAIN_DOCTOR_OK; then
# Distinguish broken-db (config valid but engine unreachable) from broken-config
# (config malformed). Falls back to broken-db if json parse worked at Step 1.
if [ -n "$SBRAIN_ENGINE" ]; then SBRAIN_LOCAL_STATUS="broken-db"; else SBRAIN_LOCAL_STATUS="broken-config"; fi
fi
# Detect any compliant brain MCP — backend-agnostic per vibestack policy.
# `claude mcp list` lines look like:
# memex: https://brain.example.com/mcp (HTTP) - ✓ Connected
# secondbrain: /Users/foo/.bun/bin/secondbrain serve - ✓ Connected
# Match either name, strip the trailing colon, and infer mode from the (HTTP)
# marker. First match wins; downstream code should NOT assume the name is
# `secondbrain`.
_BRAIN_LINE=$(claude mcp list 2>/dev/null | awk '/^(memex|secondbrain):[[:space:]]/{print; exit}')
SBRAIN_MCP_NAME=$(printf '%s\n' "$_BRAIN_LINE" | awk '{name=$1; sub(/:$/, "", name); print name}')
SBRAIN_MCP_MODE=$(printf '%s\n' "$_BRAIN_LINE" | awk '{print (tolower($3)=="(http)")?"remote-http":"local-stdio"}')
[ -z "$_BRAIN_LINE" ] && SBRAIN_MCP_MODE=""
echo "sbrain_local_status=$SBRAIN_LOCAL_STATUS sbrain_mcp_name=${SBRAIN_MCP_NAME:-none} sbrain_mcp_mode=${SBRAIN_MCP_MODE:-none}"
Step 1.5: Broken-local-engine remediation
If SBRAIN_LOCAL_STATUS is broken-db or broken-config AND no shortcut flag was passed, the user has a non-working local engine (config exists but the engine it points at isn't reachable, OR the config itself is malformed). Fire a targeted AskUserQuestion BEFORE Step 2:
> D# — Your local secondbrain engine isn't responding. How do you want to fix it? > Project/branch/task: > ELI10: secondbrain has a config at ~/.secondbrain/config.json but the engine > it points at isn't reachable. That could be a transient outage (Postgres container > stopped, Tailscale down) OR a stale config you want to abandon. Different > remediation for each case. > Stakes if we pick wrong: "Switch to PGLite" overwrites your existing config > (one-way door if the user actually wanted the broken engine). "Retry" preserves > existing state for transient cases. > Recommendation: A (Retry) — always try the cheap option first; if engine is > just temporarily down it'll come back without any destructive change. > Note: options differ in kind, not coverage — no completeness score. > A) Retry — re-probe the engine (recommended; ~80ms) > ✅ Cheapest test: re-runs secondbrain doctor --json to see if engine is back > ✅ Zero side effects; existing config preserved > ❌ If engine is permanently dead, retries forever; user must choose another option > B) Switch to local PGLite (one-way — moves existing config to .bak) > ✅ Fastest path to a working local engine if user has abandoned the old one > ✅ ~30s; no accounts; private to this machine > ❌ Destructive — existing config moved to ~/.secondbrain/config.json.vibestack-bak-{ts} > C) Switch brain mode (continue to Step 2 path picker) > ✅ Lets user pick Path 1/2/3/4 to re-init from scratch > ✅ Preserves existing config until they explicitly init the new one > ❌ Longer flow if user just wants to repair to PGLite > D) Quit (do nothing) > ✅ No cons — this is a hard-stop choice > ❌ N/A > Net: A is the right starting move; B/C are explicit destructive paths; D bails.
If A (Retry): re-run the detect block from Step 1. If the new sbrain_local_status is ok, continue to Step 2. If still broken-db or broken-config, fire the same AskUserQuestion again (the user picks again).
If B (Switch to PGLite) — execute the rollback-safe init sequence:
BACKUP="$HOME/.secondbrain/config.json.vibestack-bak-$(date +%s)"
mv "$HOME/.secondbrain/config.json" "$BACKUP"
if ! secondbrain init --pglite --json; then
# Restore on failure
mv "$BACKUP" "$HOME/.secondbrain/config.json"
echo "secondbrain init failed. Your previous config was restored at $HOME/.secondbrain/config.json." >&2
echo "PGLite directory at ~/.secondbrain/pglite/ may be in a partial state — \`rm -rf ~/.secondbrain/pglite\` if needed before retrying." >&2
exit 1
fi
echo "Switched to local PGLite. Previous config saved at $BACKUP — review before deleting."
Then jump to Step 5a (MCP registration; the new PGLite engine is registered as local-stdio).
If C (Switch brain mode): continue to Step 2's normal path picker.
If D (Quit): STOP the skill cleanly.
For SBRAIN_LOCAL_STATUS values of no-cli or missing-config, do NOT fire Step 1.5 — fall through to Step 2 (where no-cli triggers Step 3 install and missing-config triggers Step 4 init).
Step 2: Pick a path (AskUserQuestion)
Only fire this if Step 1 shows no existing working config AND no shortcut flag was passed. Special case: if sbrain_mcp_mode=remote-http in the detect output (regardless of whether sbrain_mcp_name is memex, secondbrain, or another compliant brand), an HTTP MCP brain is already registered — skip directly to Step 5a verification (re-test the existing registration under its detected name) and Step 6 onward, treating this run as idempotent. Don't ask Step 2 again, and never register a parallel secondbrain entry pointing at the same URL — that creates a duplicate brain in claude mcp list.
The question title: "Where should your brain live?"
Options (present based on detected state):
- 1 — Supabase, I already have a connection string. Cloud-agent users
whose openclaw/hermes provisioned one already. Paste the Session Pooler URL from the Supabase dashboard (Settings → Database → Connection Pooler → Session). Trust-surface caveat: "Pasting this URL gives your local Claude Code full read/write access to every page your cloud agent can see. If that's not the trust level you want, pick PGLite local instead and accept the brains are disjoint."
- 2a — Supabase, auto-provision a new project. You'll need a Supabase
Personal Access Token (~90 seconds). Best choice for a shared team brain.
- 2b — Supabase, create manually. Walk through supabase.com signup
yourself; paste the URL back when ready.
- 3 — PGLite local. Zero accounts, ~30 seconds. Isolated brain on this
Mac only. Best for try-first.
- 4 — Remote secondbrain MCP. Someone else (or another machine of yours) is
already running secondbrain serve with HTTP transport. You paste the MCP URL
- a bearer token; this skill registers it as your MCP. No local brain DB,
no local install needed. Recommended when the brain is shared across machines or run by a teammate.
- Switch (only if Step 1 detected an existing engine): "You already have
a ` brain. Migrate it to the other engine?" → runs secondbrain migrate --to wrapped in timeout 180s`.
Do NOT silently pick; fire the AskUserQuestion.
Step 3: Install memory CLI (secondbrain)
SKIP entirely on Path 4 (Remote MCP). Path 4 doesn't need a local secondbrain binary — all calls go through MCP to the remote server. Jump to Step 4 (the Path 4 subsection).
For Paths 1, 2a, 2b, 3, switch — only if SBRAIN_ON_PATH=false:
# Try bun first, fall back to npm
if command -v bun >/dev/null 2>&1; then
bun install -g secondbrain
elif command -v npm >/dev/null 2>&1; then
npm install -g secondbrain
else
echo "ERROR: Neither bun nor npm found. Install one first."
exit 1
fi
After install, verify:
secondbrain --version
If secondbrain --version fails, check PATH:
# bun global bin
export PATH="$HOME/.bun/bin:$PATH"
secondbrain --version
If it still fails, surface the error and STOP — the environment is broken until the user fixes PATH. Do not continue the skill.
PATH-shadow validation. Even when secondbrain --version succeeds, another binary earlier on $PATH may be shadowing the one we just installed (a stale global from a prior install, a colleague's fork checked into ~/bin/, etc.). Validate that the resolved secondbrain lives in the expected install directory:
RESOLVED=$(command -v secondbrain)
EXPECTED_DIRS=("$HOME/.bun/install/global/node_modules/secondbrain" "$HOME/.npm/global/node_modules/secondbrain" "$(npm prefix -g 2>/dev/null)/lib/node_modules/secondbrain")
SHADOWED=true
for d in "${EXPECTED_DIRS[@]}"; do
if printf '%s' "$RESOLVED" | grep -q "$(dirname "$d")"; then SHADOWED=false; break; fi
done
if $SHADOWED; then
echo "WARN: \`secondbrain\` resolves to $RESOLVED, which is outside the expected global install paths."
echo " Another binary may be shadowing your install. Check \`type -a secondbrain\` and rearrange PATH if needed."
fi
The warning is non-blocking — the user may have intentionally installed a fork — but surface it before continuing so half-broken setups don't get silently wired.
Step 4: Initialize the brain
Path-specific.
Path 1 (Supabase, existing URL)
Collect the URL securely (never as argv):
printf "Paste Session Pooler URL: "
read -rs SBRAIN_POOLER_URL
echo
printf "URL received (redacted): %s\n" "$(echo "$SBRAIN_POOLER_URL" | sed 's#://[^@]*@#://***@#')"
Validate structurally (must start with postgresql:// and contain port 6543):
echo "$SBRAIN_POOLER_URL" | grep -qE '^postgresql://.+:6543/' || {
echo "ERROR: URL does not look like a Session Pooler URL (expected port 6543)."
echo "Get it from: Supabase dashboard → Settings → Database → Connection Pooler → Session"
exit 1
}
On success, hand off to the memory CLI via env var (never argv):
export SBRAIN_DATABASE_URL="$SBRAIN_POOLER_URL"
secondbrain init --non-interactive --json
unset SBRAIN_POOLER_URL SBRAIN_DATABASE_URL
The URL is now persisted in ~/.secondbrain/config.json at mode 0600 by the secondbrain CLI itself.
Path 2a (Supabase, auto-provision)
Show the PAT scope disclosure 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 secondbrain 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 collect securely:
printf "Paste PAT: "
read -rs SUPABASE_ACCESS_TOKEN
echo
export SUPABASE_ACCESS_TOKEN
Ask the tier prompt 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 — user picks their org based on its current tier.
List orgs:
curl -s -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
https://api.supabase.com/v1/organizations
If the orgs array is empty, surface: "Your Supabase account has no organizations. Create one at https://supabase.com/dashboard, then re-run /setup-memory." STOP.
If multiple orgs, use AskUserQuestion to pick one.
Ask the user for a region (default us-east-1).
Generate the DB password (never shown to the user):
export DB_PASS=$(openssl rand -base64 24)
Set up a SIGINT trap:
trap 'echo ""; echo "vibe-setup-memory: interrupted. In-flight ref: $INFLIGHT_REF"; \
echo "Resume: /setup-memory --resume-provision $INFLIGHT_REF"; \
echo "Delete: https://supabase.com/dashboard/project/$INFLIGHT_REF"; \
unset SUPABASE_ACCESS_TOKEN DB_PASS; \
rm -rf ~/.vibestack/.setup-memory.lock
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [timurgaleev](https://github.com/timurgaleev)
- **Source:** [timurgaleev/vibestack](https://github.com/timurgaleev/vibestack)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.