#!/usr/bin/env bash # Set up gstack for local development — test skills from within this repo. # # Creates .claude/skills/gstack → (symlink to repo root) so Claude Code # discovers skills from your working tree. Changes take effect immediately. # # Also copies .env from the main worktree if this is a Conductor workspace # or git worktree (so API keys carry over automatically). # # Usage: bin/dev-setup # set up # bin/dev-teardown # clean up set -e REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" # 1. Copy .env from main worktree (if we're a worktree and don't have one) if [ ! -f "$REPO_ROOT/.env" ]; then MAIN_WORKTREE="$(git -C "$REPO_ROOT" worktree list --porcelain 2>/dev/null | head -1 | sed 's/^worktree //')" if [ -n "$MAIN_WORKTREE" ] && [ "$MAIN_WORKTREE" != "$REPO_ROOT" ] && [ -f "$MAIN_WORKTREE/.env" ]; then cp "$MAIN_WORKTREE/.env" "$REPO_ROOT/.env" echo "Copied .env from main worktree ($MAIN_WORKTREE)" fi fi # 2. Install dependencies if [ ! -d "$REPO_ROOT/node_modules" ]; then echo "Installing dependencies..." (cd "$REPO_ROOT" && bun install) fi # 3. Create .claude/skills/ inside the repo mkdir -p "$REPO_ROOT/.claude/skills" # 4. Symlink .claude/skills/gstack → repo root # This makes setup think it's inside a real .claude/skills/ directory GSTACK_LINK="$REPO_ROOT/.claude/skills/gstack" if [ -L "$GSTACK_LINK" ]; then echo "Updating existing symlink..." rm "$GSTACK_LINK" elif [ -d "$GSTACK_LINK" ]; then echo "Error: .claude/skills/gstack is a real directory, not a symlink." >&2 echo "Remove it manually if you want to use dev mode." >&2 exit 1 fi ln -s "$REPO_ROOT" "$GSTACK_LINK" # 5. Create .agents/skills/gstack → repo root (for Codex/Gemini/Cursor) mkdir -p "$REPO_ROOT/.agents/skills" AGENTS_LINK="$REPO_ROOT/.agents/skills/gstack" if [ -L "$AGENTS_LINK" ]; then rm "$AGENTS_LINK" elif [ -d "$AGENTS_LINK" ]; then echo "Warning: .agents/skills/gstack is a real directory, skipping." >&2 fi if [ ! -e "$AGENTS_LINK" ]; then ln -s "$REPO_ROOT" "$AGENTS_LINK" fi # 6. Do not call the user runtime installer from a development worktree. # # GStack 2 delegates skill placement to the standard Agent Skills installer, # and root ./setup installs only the optional per-user runtime. Development can # execute the checked-out binaries directly, so invoking ./setup here would # mutate user state without adding any workspace capability. # # Brain-aware (gbrain) blocks render into an untracked workspace dir. # # The worktree's SKILL.md files stay canonical (the guard above). If gbrain is # installed, render the :user variant (with GBRAIN_CONTEXT_LOAD + # GBRAIN_SAVE_RESULTS) into .claude/gstack-rendered (gitignored, per-workspace) # and repoint the workspace's SKILL.md symlinks at it. gen-skill-docs --out-dir # also rewrites the section-base path so section reads resolve to the render, not # the global install. Result: this workspace gets the full gbrain experience # while git stays clean. Production skill placement and updates remain owned by # the standard Agent Skills installer. GBRAIN_DETECT="$REPO_ROOT/bin/gstack-gbrain-detect" RENDER_DIR="$REPO_ROOT/.claude/gstack-rendered" if [ -x "$GBRAIN_DETECT" ] && "$GBRAIN_DETECT" --is-ok 2>/dev/null; then echo "" echo "gbrain detected — rendering brain-aware skills into .claude/gstack-rendered (workspace-only, untracked)..." rm -rf "$RENDER_DIR" if ( cd "$REPO_ROOT" && bun run gen:skill-docs:user --host claude --out-dir "$RENDER_DIR" >/dev/null 2>&1 ); then # Repoint each project-local SKILL.md symlink whose worktree target has a # rendered counterpart. The skill DIRECTORY name (basename of the symlink # target's dir) maps to RENDER_DIR//SKILL.md, which is robust to # frontmatter renames and the gstack- prefix on the link name. repointed=0 for skill_link in "$REPO_ROOT"/.claude/skills/*/SKILL.md; do [ -L "$skill_link" ] || continue target="$(readlink "$skill_link")" skilldir="$(basename "$(dirname "$target")")" rendered="$RENDER_DIR/$skilldir/SKILL.md" if [ -f "$rendered" ]; then ln -snf "$rendered" "$skill_link"; repointed=$((repointed + 1)); fi done echo " $repointed workspace skills now serve brain-aware blocks (worktree stays canonical)." else echo " warning: brain-aware render failed — workspace uses canonical skills." fi fi echo "" echo "Dev mode active. Skills resolve from this working tree." echo " .claude/skills/gstack → $REPO_ROOT" echo " .agents/skills/gstack → $REPO_ROOT" echo "Edit any SKILL.md and test immediately — no copy/deploy needed." echo "" echo "To refresh managed gbrain detection state, run:" echo " gstack-config gbrain-refresh" echo "Then use the standard Agent Skills installer for production skill updates." echo "" echo "To tear down: bin/dev-teardown"