From 9c429d83ae78411a705bb941de4c7258e818f962 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:00:27 -0700 Subject: [PATCH 1/9] feat: add gstack-settings-hook for atomic Claude Code hook management DRY helper for adding/removing SessionStart hooks in ~/.claude/settings.json. Handles missing files, deduplication, malformed JSON, and atomic writes (.tmp + rename) to prevent corruption on crash or disk-full. Part of team-install-mode feature (credit: Jared Friedman). Co-Authored-By: Claude Opus 4.6 (1M context) --- bin/gstack-settings-hook | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100755 bin/gstack-settings-hook diff --git a/bin/gstack-settings-hook b/bin/gstack-settings-hook new file mode 100755 index 0000000000..93a537f008 --- /dev/null +++ b/bin/gstack-settings-hook @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# gstack-settings-hook — add/remove SessionStart hooks in Claude Code settings.json +# +# Usage: +# gstack-settings-hook add # add SessionStart hook +# gstack-settings-hook remove # remove SessionStart hook +# +# Requires: bun (already a gstack hard dependency) +# Writes atomically: .tmp + rename to prevent corruption on crash/disk-full. + +set -euo pipefail + +ACTION="${1:-}" +HOOK_CMD="${2:-}" +SETTINGS_FILE="${GSTACK_SETTINGS_FILE:-$HOME/.claude/settings.json}" + +if [ -z "$ACTION" ] || [ -z "$HOOK_CMD" ]; then + echo "Usage: gstack-settings-hook {add|remove} " >&2 + exit 1 +fi + +if ! command -v bun >/dev/null 2>&1; then + echo "Error: bun is required but not installed." >&2 + exit 1 +fi + +case "$ACTION" in + add) + bun -e " + const fs = require('fs'); + const settingsPath = '$SETTINGS_FILE'; + const hookCmd = $(printf '%s' "$HOOK_CMD" | bun -e "process.stdout.write(JSON.stringify(require('fs').readFileSync('/dev/stdin','utf8')))"); + + let settings = {}; + try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch {} + + if (!settings.hooks) settings.hooks = {}; + if (!settings.hooks.SessionStart) settings.hooks.SessionStart = []; + + // Dedup: check if hook command already registered + const exists = settings.hooks.SessionStart.some(entry => + entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gstack-session-update')) + ); + + if (!exists) { + settings.hooks.SessionStart.push({ + hooks: [{ type: 'command', command: hookCmd }] + }); + } + + const tmp = settingsPath + '.tmp'; + fs.writeFileSync(tmp, JSON.stringify(settings, null, 2) + '\n'); + fs.renameSync(tmp, settingsPath); + " 2>/dev/null + ;; + remove) + [ -f "$SETTINGS_FILE" ] || exit 0 + bun -e " + const fs = require('fs'); + const settingsPath = '$SETTINGS_FILE'; + + let settings = {}; + try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch { process.exit(0); } + + if (settings.hooks && settings.hooks.SessionStart) { + settings.hooks.SessionStart = settings.hooks.SessionStart.filter(entry => + !(entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gstack-session-update'))) + ); + if (settings.hooks.SessionStart.length === 0) delete settings.hooks.SessionStart; + if (Object.keys(settings.hooks).length === 0) delete settings.hooks; + } + + const tmp = settingsPath + '.tmp'; + fs.writeFileSync(tmp, JSON.stringify(settings, null, 2) + '\n'); + fs.renameSync(tmp, settingsPath); + " 2>/dev/null + ;; + *) + echo "Unknown action: $ACTION (expected add or remove)" >&2 + exit 1 + ;; +esac From ebf1d62408b2dcb855807777c611a0c7b26d9adb Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:00:31 -0700 Subject: [PATCH 2/9] feat: add gstack-session-update for automatic team updates SessionStart hook target that auto-updates gstack at session start. Background fork (zero latency), throttled to once/hour, with lockfile (mkdir + PID), stale lock recovery, GIT_TERMINAL_PROMPT=0, and debug logging to ~/.gstack/analytics/session-update.log. Part of team-install-mode feature (credit: Jared Friedman). Co-Authored-By: Claude Opus 4.6 (1M context) --- bin/gstack-session-update | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100755 bin/gstack-session-update diff --git a/bin/gstack-session-update b/bin/gstack-session-update new file mode 100755 index 0000000000..66bd44028e --- /dev/null +++ b/bin/gstack-session-update @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# gstack-session-update — auto-update gstack on session start (team mode) +# +# Called by Claude Code SessionStart hook. Must be fast, silent, non-fatal. +# The entire update runs in background (forked). The hook itself exits +# immediately so session startup is never delayed. +# +# Exit 0 always — errors must never block a Claude Code session. + +set +e + +GSTACK_DIR="${GSTACK_DIR:-$HOME/.claude/skills/gstack}" +STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}" +THROTTLE_FILE="$STATE_DIR/.last-session-update" +LOCK_DIR="$STATE_DIR/.setup-lock" +LOG_FILE="$STATE_DIR/analytics/session-update.log" +THROTTLE_SECONDS=3600 # 1 hour + +log_entry() { + mkdir -p "$(dirname "$LOG_FILE")" + echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $1" >> "$LOG_FILE" 2>/dev/null || true +} + +# ── Guard: gstack must be a git repo ── +if [ ! -d "$GSTACK_DIR/.git" ]; then + exit 0 +fi + +# ── Guard: team mode must be enabled ── +AUTO=$("$GSTACK_DIR/bin/gstack-config" get auto_upgrade 2>/dev/null || true) +if [ "$AUTO" != "true" ]; then + exit 0 +fi + +# ── Throttle: skip if checked recently ── +if [ -f "$THROTTLE_FILE" ]; then + LAST=$(cat "$THROTTLE_FILE" 2>/dev/null || echo 0) + NOW=$(date +%s) + ELAPSED=$(( NOW - LAST )) + if [ "$ELAPSED" -lt "$THROTTLE_SECONDS" ]; then + exit 0 + fi +fi + +# ── Fork to background: zero latency on session start ── +( + # Prevent git from prompting for credentials (would hang the background process) + export GIT_TERMINAL_PROMPT=0 + + mkdir -p "$STATE_DIR" + + # ── Acquire lockfile (skip if another session is running setup) ── + if ! mkdir "$LOCK_DIR" 2>/dev/null; then + # Lock exists — check if stale (PID dead) + if [ -f "$LOCK_DIR/pid" ]; then + LOCK_PID=$(cat "$LOCK_DIR/pid" 2>/dev/null || echo 0) + if [ "$LOCK_PID" -gt 0 ] 2>/dev/null && ! kill -0 "$LOCK_PID" 2>/dev/null; then + # Stale lock — remove and re-acquire + rm -rf "$LOCK_DIR" 2>/dev/null + mkdir "$LOCK_DIR" 2>/dev/null || { log_entry "SKIP lock_contested"; exit 0; } + else + log_entry "SKIP locked_by=$LOCK_PID" + exit 0 + fi + else + log_entry "SKIP locked_no_pid" + exit 0 + fi + fi + + # Write PID for stale lock detection + echo $$ > "$LOCK_DIR/pid" 2>/dev/null + + # Clean up lock on exit + trap 'rm -rf "$LOCK_DIR" 2>/dev/null' EXIT + + # ── Pull latest ── + OLD_HEAD=$(git -C "$GSTACK_DIR" rev-parse HEAD 2>/dev/null) + git -C "$GSTACK_DIR" pull --ff-only -q 2>/dev/null + PULL_EXIT=$? + NEW_HEAD=$(git -C "$GSTACK_DIR" rev-parse HEAD 2>/dev/null) + + # Record check time regardless of outcome + date +%s > "$THROTTLE_FILE" 2>/dev/null + + if [ "$PULL_EXIT" -ne 0 ]; then + log_entry "PULL_FAILED exit=$PULL_EXIT" + exit 0 + fi + + # ── If HEAD moved, run setup -q ── + if [ "$OLD_HEAD" != "$NEW_HEAD" ]; then + log_entry "UPDATING old=$OLD_HEAD new=$NEW_HEAD" + + # bun must be available for setup + if command -v bun >/dev/null 2>&1; then + ( cd "$GSTACK_DIR" && ./setup -q ) >/dev/null 2>&1 || { + log_entry "SETUP_FAILED" + } + else + log_entry "SETUP_SKIPPED bun_missing" + fi + + # Write marker so next skill preamble shows "just upgraded" + OLD_VER=$(git -C "$GSTACK_DIR" show "$OLD_HEAD:VERSION" 2>/dev/null || echo "unknown") + echo "$OLD_VER" > "$STATE_DIR/just-upgraded-from" 2>/dev/null + rm -f "$STATE_DIR/last-update-check" 2>/dev/null + rm -f "$STATE_DIR/update-snoozed" 2>/dev/null + + log_entry "UPDATED from=$OLD_VER to=$(cat "$GSTACK_DIR/VERSION" 2>/dev/null || echo unknown)" + else + log_entry "UP_TO_DATE head=$OLD_HEAD" + fi +) & + +exit 0 From 85f844b3c90a28729107a39ab08d8415b3041891 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:00:34 -0700 Subject: [PATCH 3/9] feat: add --team, --no-team, -q flags to setup --team enables auto_upgrade and registers SessionStart hook via gstack-settings-hook. --no-team reverses it. -q/--quiet suppresses all informational output (for hook-triggered setup runs). --local now prints a deprecation warning. Replaces ~20 echo calls with log() helper for quiet mode support. Part of team-install-mode feature (credit: Jared Friedman). Co-Authored-By: Claude Opus 4.6 (1M context) --- setup | 81 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/setup b/setup index 7e74c64f26..a81f6b00a7 100755 --- a/setup +++ b/setup @@ -27,11 +27,17 @@ case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*|Windows_NT) IS_WINDOWS=1 ;; esac +# ─── Quiet mode helper ──────────────────────────────────────── +QUIET=0 +log() { [ "$QUIET" -eq 0 ] && echo "$@" || true; } + # ─── Parse flags ────────────────────────────────────────────── HOST="claude" LOCAL_INSTALL=0 SKILL_PREFIX=1 SKILL_PREFIX_FLAG=0 +TEAM_MODE=0 +NO_TEAM_MODE=0 while [ $# -gt 0 ]; do case "$1" in --host) [ -z "$2" ] && echo "Missing value for --host (expected claude, codex, kiro, or auto)" >&2 && exit 1; HOST="$2"; shift 2 ;; @@ -39,6 +45,9 @@ while [ $# -gt 0 ]; do --local) LOCAL_INSTALL=1; shift ;; --prefix) SKILL_PREFIX=1; SKILL_PREFIX_FLAG=1; shift ;; --no-prefix) SKILL_PREFIX=0; SKILL_PREFIX_FLAG=1; shift ;; + --team) TEAM_MODE=1; shift ;; + --no-team) NO_TEAM_MODE=1; shift ;; + -q|--quiet) QUIET=1; shift ;; *) shift ;; esac done @@ -59,8 +68,10 @@ if [ "$SKILL_PREFIX_FLAG" -eq 0 ]; then elif [ "$_saved_prefix" = "false" ]; then SKILL_PREFIX=0 else - # No saved preference — prompt interactively (or default flat for non-TTY) - if [ -t 0 ]; then + # No saved preference — prompt interactively (or default flat for non-TTY/quiet) + if [ "$QUIET" -eq 1 ]; then + SKILL_PREFIX=0 + elif [ -t 0 ]; then echo "" echo "Skill naming: how should gstack skills appear?" echo "" @@ -87,8 +98,10 @@ else "$GSTACK_CONFIG" set skill_prefix "$([ "$SKILL_PREFIX" -eq 1 ] && echo true || echo false)" 2>/dev/null || true fi -# --local: install to .claude/skills/ in the current working directory +# --local: install to .claude/skills/ in the current working directory (deprecated) if [ "$LOCAL_INSTALL" -eq 1 ]; then + echo "Warning: --local is deprecated. Use global install + --team instead." >&2 + echo " See: https://github.com/garrytan/gstack#team-mode" >&2 if [ "$HOST" = "codex" ]; then echo "Error: --local is only supported for Claude Code (not Codex)." >&2 exit 1 @@ -138,7 +151,7 @@ migrate_direct_codex_install() { exit 1 fi - echo "Migrating direct Codex install to $migrated_dir to avoid duplicate skill discovery..." + log "Migrating direct Codex install to $migrated_dir to avoid duplicate skill discovery..." mv "$gstack_dir" "$migrated_dir" SOURCE_GSTACK_DIR="$migrated_dir" INSTALL_GSTACK_DIR="$migrated_dir" @@ -179,7 +192,7 @@ elif [ -f "$SOURCE_GSTACK_DIR/bun.lock" ] && [ "$SOURCE_GSTACK_DIR/bun.lock" -nt fi if [ "$NEEDS_BUILD" -eq 1 ]; then - echo "Building browse binary..." + log "Building browse binary..." ( cd "$SOURCE_GSTACK_DIR" bun install @@ -205,7 +218,7 @@ AGENTS_DIR="$SOURCE_GSTACK_DIR/.agents/skills" NEEDS_AGENTS_GEN=1 if [ "$NEEDS_AGENTS_GEN" -eq 1 ] && [ "$NEEDS_BUILD" -eq 0 ]; then - echo "Generating .agents/ skill docs..." + log "Generating .agents/ skill docs..." ( cd "$SOURCE_GSTACK_DIR" bun install --frozen-lockfile 2>/dev/null || bun install @@ -215,7 +228,7 @@ fi # 1c. Generate .factory/ Factory Droid skill docs if [ "$INSTALL_FACTORY" -eq 1 ] && [ "$NEEDS_BUILD" -eq 0 ]; then - echo "Generating .factory/ skill docs..." + log "Generating .factory/ skill docs..." ( cd "$SOURCE_GSTACK_DIR" bun install --frozen-lockfile 2>/dev/null || bun install @@ -604,16 +617,16 @@ if [ "$INSTALL_CLAUDE" -eq 1 ]; then ln -snf "gstack/open-gstack-browser" "$_OGB_LINK" fi if [ "$LOCAL_INSTALL" -eq 1 ]; then - echo "gstack ready (project-local)." - echo " skills: $INSTALL_SKILLS_DIR" + log "gstack ready (project-local)." + log " skills: $INSTALL_SKILLS_DIR" else - echo "gstack ready (claude)." + log "gstack ready (claude)." fi - echo " browse: $BROWSE_BIN" + log " browse: $BROWSE_BIN" else - echo "gstack ready (claude)." - echo " browse: $BROWSE_BIN" - echo " (skipped skill symlinks — not inside .claude/skills/)" + log "gstack ready (claude)." + log " browse: $BROWSE_BIN" + log " (skipped skill symlinks — not inside .claude/skills/)" fi fi @@ -633,9 +646,9 @@ if [ "$INSTALL_CODEX" -eq 1 ]; then # Install generated Codex-format skills (not Claude source dirs) link_codex_skill_dirs "$SOURCE_GSTACK_DIR" "$CODEX_SKILLS" - echo "gstack ready (codex)." - echo " browse: $BROWSE_BIN" - echo " codex skills: $CODEX_SKILLS" + log "gstack ready (codex)." + log " browse: $BROWSE_BIN" + log " codex skills: $CODEX_SKILLS" fi # 6. Install for Kiro CLI (copy from .agents/skills, rewrite paths) @@ -740,7 +753,39 @@ fi # 9. First-time welcome + legacy cleanup if [ ! -f "$HOME/.gstack/.welcome-seen" ]; then - echo " Welcome! Run /gstack-upgrade anytime to stay current." + log " Welcome! Run /gstack-upgrade anytime to stay current." touch "$HOME/.gstack/.welcome-seen" fi rm -f /tmp/gstack-latest-version + +# 10. Team mode: register/unregister SessionStart hook +SETTINGS_HOOK="$SOURCE_GSTACK_DIR/bin/gstack-settings-hook" +HOOK_CMD="$SOURCE_GSTACK_DIR/bin/gstack-session-update" + +if [ "$TEAM_MODE" -eq 1 ]; then + "$GSTACK_CONFIG" set auto_upgrade true 2>/dev/null || true + + # Register SessionStart hook in Claude Code settings + if [ -x "$SETTINGS_HOOK" ]; then + "$SETTINGS_HOOK" add "$HOOK_CMD" 2>/dev/null || true + fi + + log "" + log "Team mode enabled: gstack will auto-update at the start of each Claude Code session." + log " Hook: $HOOK_CMD" + log " To disable: ./setup --no-team" + log "" + log "Bootstrap your repo:" + log " cd && $SOURCE_GSTACK_DIR/bin/gstack-team-init required" +fi + +if [ "$NO_TEAM_MODE" -eq 1 ]; then + "$GSTACK_CONFIG" set auto_upgrade false 2>/dev/null || true + + # Remove SessionStart hook from Claude Code settings + if [ -x "$SETTINGS_HOOK" ]; then + "$SETTINGS_HOOK" remove "$HOOK_CMD" 2>/dev/null || true + fi + + log "Team mode disabled: auto-update hook removed." +fi From b1570a315fb88792e8b8e5a423d5410000dd09a9 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:00:38 -0700 Subject: [PATCH 4/9] feat: add gstack-team-init for repo-level team bootstrapping Two modes: 'optional' (gentle CLAUDE.md suggestion) and 'required' (CLAUDE.md enforcement + .claude/hooks/check-gstack.sh PreToolUse hook that blocks work without gstack installed). Atomic JSON writes, idempotent, prints git add instructions. Part of team-install-mode feature (credit: Jared Friedman). Co-Authored-By: Claude Opus 4.6 (1M context) --- bin/gstack-team-init | 172 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100755 bin/gstack-team-init diff --git a/bin/gstack-team-init b/bin/gstack-team-init new file mode 100755 index 0000000000..6195c7b67a --- /dev/null +++ b/bin/gstack-team-init @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# gstack-team-init — generate repo-level bootstrap files for team mode +# +# Usage: +# gstack-team-init optional # gentle CLAUDE.md suggestion, one-time offer +# gstack-team-init required # CLAUDE.md enforcement + PreToolUse hook +# +# Run from the root of your team's repo (not from the gstack directory). + +set -euo pipefail + +MODE="${1:-}" + +if [ "$MODE" != "optional" ] && [ "$MODE" != "required" ]; then + echo "Usage: gstack-team-init {optional|required}" >&2 + echo "" >&2 + echo " optional — suggest gstack install once per developer (gentle)" >&2 + echo " required — enforce gstack install, block work without it" >&2 + exit 1 +fi + +# Must be in a git repo +if ! git rev-parse --show-toplevel >/dev/null 2>&1; then + echo "Error: not in a git repository. Run from your project root." >&2 + exit 1 +fi + +REPO_ROOT=$(git rev-parse --show-toplevel) +CLAUDE_MD="$REPO_ROOT/CLAUDE.md" +GENERATED=() + +# ── CLAUDE.md snippet ────────────────────────────────────────── + +if [ "$MODE" = "optional" ]; then + SNIPPET='## gstack (recommended) + +This project uses [gstack](https://github.com/garrytan/gstack) for AI-assisted workflows. +Install it for the best experience: + +```bash +git clone --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack +cd ~/.claude/skills/gstack && ./setup --team +``` + +Skills like /qa, /ship, /review, /investigate, and /browse become available after install. +Use /browse for all web browsing. Use ~/.claude/skills/gstack/... for gstack file paths.' +else + SNIPPET='## gstack (REQUIRED — global install) + +**Before doing ANY work, verify gstack is installed:** + +```bash +test -d ~/.claude/skills/gstack/bin && echo "GSTACK_OK" || echo "GSTACK_MISSING" +``` + +If GSTACK_MISSING: STOP. Do not proceed. Tell the user: + +> gstack is required for all AI-assisted work in this repo. +> Install it: +> ```bash +> git clone --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack +> cd ~/.claude/skills/gstack && ./setup --team +> ``` +> Then restart your AI coding tool. + +Do not skip skills, ignore gstack errors, or work around missing gstack. + +Using gstack skills: After install, skills like /qa, /ship, /review, /investigate, +and /browse are available. Use /browse for all web browsing. +Use ~/.claude/skills/gstack/... for gstack file paths (the global path).' +fi + +# Check if CLAUDE.md already has a gstack section +if [ -f "$CLAUDE_MD" ] && grep -q "## gstack" "$CLAUDE_MD" 2>/dev/null; then + echo "CLAUDE.md already has a gstack section. Skipping CLAUDE.md update." + echo " To replace it, remove the existing ## gstack section and re-run." +else + if [ -f "$CLAUDE_MD" ]; then + echo "" >> "$CLAUDE_MD" + fi + echo "$SNIPPET" >> "$CLAUDE_MD" + GENERATED+=("CLAUDE.md") + echo " + CLAUDE.md — added gstack $MODE section" +fi + +# ── Required mode: enforcement hook ──────────────────────────── + +if [ "$MODE" = "required" ]; then + HOOKS_DIR="$REPO_ROOT/.claude/hooks" + SETTINGS="$REPO_ROOT/.claude/settings.json" + + # Create enforcement hook script + mkdir -p "$HOOKS_DIR" + cat > "$HOOKS_DIR/check-gstack.sh" << 'HOOK_EOF' +#!/bin/bash +# Block skill usage when gstack is not installed globally. + +if [ ! -d "$HOME/.claude/skills/gstack/bin" ]; then + cat >&2 <<'MSG' +BLOCKED: gstack is not installed globally. + +gstack is required for AI-assisted work in this repo. + +Install it: + git clone --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack + cd ~/.claude/skills/gstack && ./setup --team + +Then restart your AI coding tool. +MSG + echo '{"permissionDecision":"deny","message":"gstack is required but not installed. See stderr for install instructions."}' + exit 0 +fi + +echo '{}' +HOOK_EOF + chmod +x "$HOOKS_DIR/check-gstack.sh" + GENERATED+=(".claude/hooks/check-gstack.sh") + echo " + .claude/hooks/check-gstack.sh — enforcement hook" + + # Add hook to project-level settings.json + if command -v bun >/dev/null 2>&1; then + bun -e " + const fs = require('fs'); + const settingsPath = '$SETTINGS'; + + let settings = {}; + try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch {} + + if (!settings.hooks) settings.hooks = {}; + if (!settings.hooks.PreToolUse) settings.hooks.PreToolUse = []; + + // Dedup + const exists = settings.hooks.PreToolUse.some(entry => + entry.matcher === 'Skill' && + entry.hooks && entry.hooks.some(h => h.command && h.command.includes('check-gstack')) + ); + + if (!exists) { + settings.hooks.PreToolUse.push({ + matcher: 'Skill', + hooks: [{ + type: 'command', + command: '\"\$CLAUDE_PROJECT_DIR/.claude/hooks/check-gstack.sh\"' + }] + }); + } + + const tmp = settingsPath + '.tmp'; + fs.writeFileSync(tmp, JSON.stringify(settings, null, 2) + '\n'); + fs.renameSync(tmp, settingsPath); + " 2>/dev/null + GENERATED+=(".claude/settings.json") + echo " + .claude/settings.json — PreToolUse hook registered" + else + echo " ! bun not found — manually add the PreToolUse hook to .claude/settings.json" + fi +fi + +# ── Summary ──────────────────────────────────────────────────── + +echo "" +echo "Team mode ($MODE) initialized." +echo "" +if [ ${#GENERATED[@]} -gt 0 ]; then + echo "Commit the generated files:" + echo " git add ${GENERATED[*]}" + echo " git commit -m \"chore: require gstack for AI-assisted work\"" +fi +echo "" +echo "Each developer then runs:" +echo " git clone --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack" +echo " cd ~/.claude/skills/gstack && ./setup --team" From e4c75bae6001ba2a14932daa0ff27f905afd6178 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:01:22 -0700 Subject: [PATCH 5/9] docs: deprecate vendoring, document team mode, clean up uninstall - README: replace "Step 2: Add to your repo" vendoring instructions with team mode (./setup --team + gstack-team-init) - CLAUDE.md: rename "Vendored symlink awareness" to "Dev symlink awareness", add deprecation note - CONTRIBUTING.md: remove vendoring language from prefix section - bin/gstack-uninstall: clean up SessionStart hook on uninstall Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 12 +++++++----- CONTRIBUTING.md | 2 +- README.md | 18 +++++++++++++++--- bin/gstack-uninstall | 7 +++++++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9480e572d7..b6aad00423 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -186,10 +186,10 @@ failure modes. The sidebar spans 5 files across 2 codebases (extension + server) with non-obvious ordering dependencies. The doc exists to prevent the kind of silent failures that come from not understanding the cross-component flow. -## Vendored symlink awareness +## Dev symlink awareness When developing gstack, `.claude/skills/gstack` may be a symlink back to this -working directory (gitignored). This means skill changes are **live immediately** — +working directory (gitignored). This means skill changes are **live immediately**, great for rapid iteration, risky during big refactors where half-written skills could break other Claude Code sessions using gstack concurrently. @@ -204,9 +204,11 @@ symlink or a real copy. If it's a symlink to your working directory, be aware th with a SKILL.md symlink inside (e.g., `qa/SKILL.md -> gstack/qa/SKILL.md`). This ensures Claude discovers them as top-level skills, not nested under `gstack/`. Names are either short (`qa`) or namespaced (`gstack-qa`), controlled by -`skill_prefix` in `~/.gstack/config.yaml`. When vendoring into a project, run -`./setup` after symlinking to create the per-skill directories. Pass `--no-prefix` -or `--prefix` to skip the interactive prompt. +`skill_prefix` in `~/.gstack/config.yaml`. Pass `--no-prefix` or `--prefix` to +skip the interactive prompt. + +**Note:** Vendoring gstack into a project's repo is deprecated. Use global install ++ `./setup --team` instead. See README.md for team mode instructions. **For plan reviews:** When reviewing plans that modify skill templates or the gen-skill-docs pipeline, consider whether the changes should be tested in isolation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 55cdccd062..15378e2192 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -367,7 +367,7 @@ to `gstack/...`, so they'll resolve to the global install automatically. ### Switching prefix mode -If you vendored gstack with one prefix setting and want to switch: +If you installed gstack with one prefix setting and want to switch: ```bash cd .claude/skills/gstack && ./setup --no-prefix # switch to /qa, /ship diff --git a/README.md b/README.md index 69b73024d9..12a74ba571 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,23 @@ Open Claude Code and paste this. Claude does the rest. > Install gstack: run **`git clone --single-branch --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup`** then add a "gstack" section to CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, and lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /design-shotgun, /design-html, /review, /ship, /land-and-deploy, /canary, /benchmark, /browse, /connect-chrome, /qa, /qa-only, /design-review, /setup-browser-cookies, /setup-deploy, /retro, /investigate, /document-release, /codex, /cso, /autoplan, /plan-devex-review, /devex-review, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade, /learn. Then ask the user if they also want to add gstack to the current project so teammates get it. -### Step 2: Add to your repo so teammates get it (optional) +### Step 2: Team mode — auto-update for shared repos (recommended) -> Add gstack to this project: run **`cp -Rf ~/.claude/skills/gstack .claude/skills/gstack && rm -rf .claude/skills/gstack/.git && cd .claude/skills/gstack && ./setup`** then add a "gstack" section to this project's CLAUDE.md that says to use the /browse skill from gstack for all web browsing, never use mcp\_\_claude-in-chrome\_\_\* tools, lists the available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /design-shotgun, /design-html, /review, /ship, /land-and-deploy, /canary, /benchmark, /browse, /connect-chrome, /qa, /qa-only, /design-review, /setup-browser-cookies, /setup-deploy, /retro, /investigate, /document-release, /codex, /cso, /autoplan, /plan-devex-review, /devex-review, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade, /learn, and tells Claude that if gstack skills aren't working, run `cd .claude/skills/gstack && ./setup` to build the binary and register skills. +Every developer installs globally, updates happen automatically: -Real files get committed to your repo (not a submodule), so `git clone` just works. Everything lives inside `.claude/`. Nothing touches your PATH or runs in the background. +```bash +cd ~/.claude/skills/gstack && ./setup --team +``` + +Then bootstrap your repo so teammates get it: + +```bash +cd +~/.claude/skills/gstack/bin/gstack-team-init required # or: optional +git add .claude/ CLAUDE.md && git commit -m "require gstack for AI-assisted work" +``` + +No vendored files in your repo, no version drift, no manual upgrades. Every Claude Code session starts with a fast auto-update check (throttled to once/hour, network-failure-safe, completely silent). > **Contributing or need full history?** The commands above use `--depth 1` for a fast install. If you plan to contribute or need full git history, do a full clone instead: > ```bash diff --git a/bin/gstack-uninstall b/bin/gstack-uninstall index 2cf3d5288d..4f7b0fc1ea 100755 --- a/bin/gstack-uninstall +++ b/bin/gstack-uninstall @@ -227,6 +227,13 @@ if [ -n "$_GIT_ROOT" ]; then fi fi +# ─── Remove SessionStart hook from Claude Code settings ───── +SETTINGS_HOOK="$(dirname "$0")/gstack-settings-hook" +SESSION_UPDATE="$(dirname "$0")/gstack-session-update" +if [ -x "$SETTINGS_HOOK" ]; then + "$SETTINGS_HOOK" remove "$SESSION_UPDATE" 2>/dev/null && REMOVED+=("SessionStart hook") || true +fi + # ─── Remove global state ──────────────────────────────────── if [ "$KEEP_STATE" -eq 0 ] && [ -d "$STATE_DIR" ]; then rm -rf "$STATE_DIR" From e60bbc0911d17586e011d7af779bb26760c46678 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:05:43 -0700 Subject: [PATCH 6/9] feat: add vendoring deprecation detection to skill preamble Detects vendored gstack in CWD (.claude/skills/gstack/ that's not a symlink and has VERSION or .git). Outputs VENDORED_GSTACK: yes/no. Adds generateVendoringDeprecation() section that offers one-time migration to team mode via AskUserQuestion. Part of team-install-mode feature (credit: Jared Friedman). Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/resolvers/preamble.ts | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/scripts/resolvers/preamble.ts b/scripts/resolvers/preamble.ts index 56989befa5..5db714f800 100644 --- a/scripts/resolvers/preamble.ts +++ b/scripts/resolvers/preamble.ts @@ -89,6 +89,14 @@ fi _ROUTING_DECLINED=$(${ctx.paths.binDir}/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" \`\`\``; } @@ -226,6 +234,40 @@ Say "No problem. You can add routing rules later by running \`gstack-config set This only happens once per project. If \`HAS_ROUTING\` is \`yes\` or \`ROUTING_DECLINED\` is \`true\`, skip this entirely.`; } +function generateVendoringDeprecation(ctx: TemplateContext): string { + return `If \`VENDORED_GSTACK\` is \`yes\`: This project has a vendored copy of gstack at +\`.claude/skills/gstack/\`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for \`~/.gstack/.vendoring-warned-$SLUG\` marker): + +> This project has gstack vendored in \`.claude/skills/gstack/\`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run \`git rm -r .claude/skills/gstack/\` +2. Run \`echo '.claude/skills/gstack/' >> .gitignore\` +3. Run \`${ctx.paths.binDir}/gstack-team-init required\` (or \`optional\`) +4. Run \`git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"\` +5. Tell the user: "Done. Each developer now runs: \`cd ~/.claude/skills/gstack && ./setup --team\`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +\`\`\`bash +eval "$(${ctx.paths.binDir}/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-\${SLUG:-unknown} +\`\`\` + +This only happens once per project. If the marker file exists, skip entirely.`; +} + function generateAskUserFormat(_ctx: TemplateContext): string { return `## AskUserQuestion Format @@ -675,6 +717,7 @@ export function generatePreamble(ctx: TemplateContext): string { generateTelemetryPrompt(ctx), generateProactivePrompt(ctx), generateRoutingInjection(ctx), + generateVendoringDeprecation(ctx), generateVoiceDirective(tier), ...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection()] : []), ...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []), From 173e98c0b9a95022fbd40abfef48a6ffd4c2e1ef Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:05:48 -0700 Subject: [PATCH 7/9] chore: regenerate SKILL.md files with vendoring deprecation preamble Co-Authored-By: Claude Opus 4.6 (1M context) --- SKILL.md | 40 ++++++++++++++++++++++++++++++++++ autoplan/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ benchmark/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ browse/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ canary/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ checkpoint/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ codex/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ cso/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ design-consultation/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ design-html/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ design-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ design-shotgun/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ devex-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ document-release/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ health/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ investigate/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ land-and-deploy/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ learn/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ office-hours/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ open-gstack-browser/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ plan-ceo-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ plan-design-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ plan-devex-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ plan-eng-review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ qa-only/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ qa/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ retro/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ review/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ setup-browser-cookies/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ setup-deploy/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ ship/SKILL.md | 40 ++++++++++++++++++++++++++++++++++ 31 files changed, 1240 insertions(+) diff --git a/SKILL.md b/SKILL.md index 258a7e4a03..bb065fbc6a 100644 --- a/SKILL.md +++ b/SKILL.md @@ -80,6 +80,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -206,6 +214,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice **Tone:** direct, concrete, sharp, never corporate, never academic. Sound like a builder, not a consultant. Name the file, the function, the command. No filler, no throat-clearing. diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index bcfb622460..39600cc4a2 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -90,6 +90,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -216,6 +224,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index 156ae8cfd2..36acde515c 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -83,6 +83,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -209,6 +217,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice **Tone:** direct, concrete, sharp, never corporate, never academic. Sound like a builder, not a consultant. Name the file, the function, the command. No filler, no throat-clearing. diff --git a/browse/SKILL.md b/browse/SKILL.md index d224b30946..16e0bf921f 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -82,6 +82,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -208,6 +216,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice **Tone:** direct, concrete, sharp, never corporate, never academic. Sound like a builder, not a consultant. Name the file, the function, the command. No filler, no throat-clearing. diff --git a/canary/SKILL.md b/canary/SKILL.md index e7153e939f..47f90a6482 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -82,6 +82,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -208,6 +216,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/checkpoint/SKILL.md b/checkpoint/SKILL.md index 2967f14c43..5c38062f88 100644 --- a/checkpoint/SKILL.md +++ b/checkpoint/SKILL.md @@ -85,6 +85,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -211,6 +219,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/codex/SKILL.md b/codex/SKILL.md index 5706dd8c32..ac34d85ecd 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -84,6 +84,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -210,6 +218,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/cso/SKILL.md b/cso/SKILL.md index 20efe14b90..3ebe8f19b8 100644 --- a/cso/SKILL.md +++ b/cso/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 92067d7450..83f1ec7b17 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/design-html/SKILL.md b/design-html/SKILL.md index c50b37ed15..a77611a1da 100644 --- a/design-html/SKILL.md +++ b/design-html/SKILL.md @@ -89,6 +89,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -215,6 +223,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 9b78080e89..3b5fcd0940 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/design-shotgun/SKILL.md b/design-shotgun/SKILL.md index 7de41cf30c..70bb16c697 100644 --- a/design-shotgun/SKILL.md +++ b/design-shotgun/SKILL.md @@ -84,6 +84,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -210,6 +218,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/devex-review/SKILL.md b/devex-review/SKILL.md index 18ba792faa..2d368ada4e 100644 --- a/devex-review/SKILL.md +++ b/devex-review/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/document-release/SKILL.md b/document-release/SKILL.md index a4f2617ec0..d482c436fb 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -84,6 +84,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -210,6 +218,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/health/SKILL.md b/health/SKILL.md index ee42db1f03..7747a94a47 100644 --- a/health/SKILL.md +++ b/health/SKILL.md @@ -84,6 +84,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -210,6 +218,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/investigate/SKILL.md b/investigate/SKILL.md index f69914a18f..6cf5a58c76 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -99,6 +99,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -225,6 +233,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index b1e75902b6..a9706c10f7 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -81,6 +81,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -207,6 +215,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/learn/SKILL.md b/learn/SKILL.md index 9afca4c417..f351ff610f 100644 --- a/learn/SKILL.md +++ b/learn/SKILL.md @@ -84,6 +84,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -210,6 +218,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index c3cceba3ee..fb8a6e8504 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -91,6 +91,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -217,6 +225,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/open-gstack-browser/SKILL.md b/open-gstack-browser/SKILL.md index 31757899e2..f45deda6ed 100644 --- a/open-gstack-browser/SKILL.md +++ b/open-gstack-browser/SKILL.md @@ -81,6 +81,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -207,6 +215,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 4d1253cbad..5a45b7f059 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index b0f7f3a67d..b0600ed111 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -85,6 +85,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -211,6 +219,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/plan-devex-review/SKILL.md b/plan-devex-review/SKILL.md index e954f737cd..d5a865e6eb 100644 --- a/plan-devex-review/SKILL.md +++ b/plan-devex-review/SKILL.md @@ -89,6 +89,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -215,6 +223,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index de21a370a8..77bd4b242c 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -87,6 +87,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -213,6 +221,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index e49088c719..8ad0c2cf0a 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -83,6 +83,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -209,6 +217,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/qa/SKILL.md b/qa/SKILL.md index 06e23e6f5b..4c3e59edd7 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -89,6 +89,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -215,6 +223,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/retro/SKILL.md b/retro/SKILL.md index 6b059aee9f..a3c17e9564 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -82,6 +82,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -208,6 +216,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/review/SKILL.md b/review/SKILL.md index b16de75225..4284e4276a 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -85,6 +85,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -211,6 +219,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 549c4d258a..db60823467 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -79,6 +79,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -205,6 +213,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice **Tone:** direct, concrete, sharp, never corporate, never academic. Sound like a builder, not a consultant. Name the file, the function, the command. No filler, no throat-clearing. diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index 0dfd1df453..06c55330a1 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -85,6 +85,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -211,6 +219,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. diff --git a/ship/SKILL.md b/ship/SKILL.md index 25afbb0329..e1384af528 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -86,6 +86,14 @@ fi _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") echo "HAS_ROUTING: $_HAS_ROUTING" echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +# Vendoring deprecation: detect if CWD has a vendored gstack copy +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" ``` If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills AND do not @@ -212,6 +220,38 @@ Say "No problem. You can add routing rules later by running `gstack-config set r This only happens once per project. If `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`, skip this entirely. +If `VENDORED_GSTACK` is `yes`: This project has a vendored copy of gstack at +`.claude/skills/gstack/`. Vendoring is deprecated. We will not keep vendored copies +up to date, so this project's gstack will fall behind. + +Use AskUserQuestion (one-time per project, check for `~/.gstack/.vendoring-warned-$SLUG` marker): + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> We won't keep this copy up to date, so you'll fall behind on new features and fixes. +> +> Want to migrate to team mode? It takes about 30 seconds. + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +This only happens once per project. If the marker file exists, skip entirely. + ## Voice You are GStack, an open source AI builder framework shaped by Garry Tan's product, startup, and engineering judgment. Encode how he thinks, not his biography. From 5acec62d336daed2fab22e95b273dd96c384f1cb Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:06:33 -0700 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20team=20mode=20(v0.15.7.0)=20?= =?UTF-8?q?=E2=80=94=20credit=20Jared=20Friedman?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 20 ++++++++++++++++++++ VERSION | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77edebf8cc..3a0bef9943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [0.15.7.0] - 2026-04-04 — Team Mode + +Teams can now keep every developer on the same gstack version automatically. No more vendoring 342 files into your repo. No more version drift across branches. No more "who upgraded gstack last?" Slack threads. One command, every developer is current. + +Hat tip to Jared Friedman for the design. + +### Added + +- **`./setup --team`.** Registers a `SessionStart` hook in `~/.claude/settings.json` that auto-updates gstack at the start of each Claude Code session. Runs in background (zero latency), throttled to once/hour, network-failure-safe, completely silent. `./setup --no-team` reverses it. +- **`./setup -q` / `--quiet`.** Suppresses all informational output. Used by the session-update hook but also useful for CI and scripted installs. +- **`gstack-team-init` command.** Generates repo-level bootstrap files in two flavors: `optional` (gentle CLAUDE.md suggestion, one-time offer per developer) or `required` (CLAUDE.md enforcement + PreToolUse hook that blocks work without gstack installed). +- **`gstack-settings-hook` helper.** DRY utility for adding/removing hooks in Claude Code's `settings.json`. Atomic writes (.tmp + rename) prevent corruption. +- **`gstack-session-update` script.** The SessionStart hook target. Background fork, PID-based lockfile with stale recovery, `GIT_TERMINAL_PROMPT=0` to prevent credential prompt hangs, debug log at `~/.gstack/analytics/session-update.log`. +- **Vendoring deprecation in preamble.** Every skill now detects vendored gstack copies in the project and offers one-time migration to team mode. "Want me to do it for you?" beats "here are 4 manual steps." + +### Changed + +- **Vendoring is deprecated.** README no longer recommends copying gstack into your repo. Global install + `--team` is the way. `--local` flag still works but prints a deprecation warning. +- **Uninstall cleans up hooks.** `gstack-uninstall` now removes the SessionStart hook from `~/.claude/settings.json`. + ## [0.15.6.0] - 2026-04-04 — Declarative Multi-Host Platform Adding a new coding agent to gstack used to mean touching 9 files and knowing the internals of `gen-skill-docs.ts`. Now it's one TypeScript config file and a re-export. Zero code changes elsewhere. Tests auto-parameterize. diff --git a/VERSION b/VERSION index 5703576917..b8bd194360 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.15.6.0 +0.15.7.0 From 499a131520499c2ae246aca1c1a57a3bee96a3e2 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 4 Apr 2026 21:20:18 -0700 Subject: [PATCH 9/9] test: add integration tests for team mode (20 tests) Covers gstack-settings-hook (add, remove, dedup, preserve existing, atomic write), gstack-session-update (guards, throttle, non-fatal), gstack-team-init (optional, required, enforcement hook, idempotent), and setup flags (-q, --local deprecation). Co-Authored-By: Claude Opus 4.6 (1M context) --- test/team-mode.test.ts | 276 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 test/team-mode.test.ts diff --git a/test/team-mode.test.ts b/test/team-mode.test.ts new file mode 100644 index 0000000000..e2b030fb4b --- /dev/null +++ b/test/team-mode.test.ts @@ -0,0 +1,276 @@ +import { describe, test, expect, beforeEach, afterEach } from 'bun:test'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import { execSync } from 'child_process'; + +const ROOT = path.resolve(import.meta.dir, '..'); +const SETTINGS_HOOK = path.join(ROOT, 'bin', 'gstack-settings-hook'); +const SESSION_UPDATE = path.join(ROOT, 'bin', 'gstack-session-update'); +const TEAM_INIT = path.join(ROOT, 'bin', 'gstack-team-init'); + +function mkTmpDir(): string { + return fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-team-test-')); +} + +function run(cmd: string, opts: { cwd?: string; env?: Record } = {}): { stdout: string; stderr: string; exitCode: number } { + try { + const stdout = execSync(cmd, { + cwd: opts.cwd, + env: { ...process.env, ...opts.env }, + encoding: 'utf-8', + timeout: 10000, + }); + return { stdout, stderr: '', exitCode: 0 }; + } catch (e: any) { + return { stdout: e.stdout || '', stderr: e.stderr || '', exitCode: e.status ?? 1 }; + } +} + +describe('gstack-settings-hook', () => { + let tmpDir: string; + let settingsFile: string; + + beforeEach(() => { + tmpDir = mkTmpDir(); + settingsFile = path.join(tmpDir, 'settings.json'); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + test('add creates settings.json if missing', () => { + const result = run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + expect(result.exitCode).toBe(0); + const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8')); + expect(settings.hooks.SessionStart).toHaveLength(1); + expect(settings.hooks.SessionStart[0].hooks[0].command).toBe('/path/to/gstack-session-update'); + }); + + test('add preserves existing settings', () => { + fs.writeFileSync(settingsFile, JSON.stringify({ effortLevel: 'high', permissions: { defaultMode: 'auto' } }, null, 2)); + const result = run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + expect(result.exitCode).toBe(0); + const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8')); + expect(settings.effortLevel).toBe('high'); + expect(settings.permissions.defaultMode).toBe('auto'); + expect(settings.hooks.SessionStart).toHaveLength(1); + }); + + test('add deduplicates (running twice does not double-add)', () => { + run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8')); + expect(settings.hooks.SessionStart).toHaveLength(1); + }); + + test('remove removes the hook', () => { + run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + const result = run(`${SETTINGS_HOOK} remove /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + expect(result.exitCode).toBe(0); + const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8')); + expect(settings.hooks).toBeUndefined(); + }); + + test('remove is safe when settings.json does not exist', () => { + const result = run(`${SETTINGS_HOOK} remove /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + expect(result.exitCode).toBe(0); + }); + + test('remove preserves other hooks', () => { + fs.writeFileSync(settingsFile, JSON.stringify({ + hooks: { + SessionStart: [ + { hooks: [{ type: 'command', command: '/path/to/gstack-session-update' }] }, + { hooks: [{ type: 'command', command: '/other/hook' }] }, + ], + }, + }, null, 2)); + run(`${SETTINGS_HOOK} remove /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8')); + expect(settings.hooks.SessionStart).toHaveLength(1); + expect(settings.hooks.SessionStart[0].hooks[0].command).toBe('/other/hook'); + }); + + test('atomic write (no partial file on success)', () => { + run(`${SETTINGS_HOOK} add /path/to/gstack-session-update`, { + env: { GSTACK_SETTINGS_FILE: settingsFile }, + }); + // .tmp file should not exist after successful write + expect(fs.existsSync(settingsFile + '.tmp')).toBe(false); + // File should be valid JSON + expect(() => JSON.parse(fs.readFileSync(settingsFile, 'utf-8'))).not.toThrow(); + }); +}); + +describe('gstack-session-update', () => { + let tmpDir: string; + let gstackDir: string; + let stateDir: string; + + beforeEach(() => { + tmpDir = mkTmpDir(); + gstackDir = path.join(tmpDir, 'gstack'); + stateDir = path.join(tmpDir, 'state'); + fs.mkdirSync(gstackDir, { recursive: true }); + fs.mkdirSync(stateDir, { recursive: true }); + + // Init a git repo to pass the .git guard + execSync('git init', { cwd: gstackDir }); + execSync('git commit --allow-empty -m "init"', { cwd: gstackDir }); + fs.writeFileSync(path.join(gstackDir, 'VERSION'), '0.1.0'); + + // Create a minimal gstack-config that returns auto_upgrade=true + const binDir = path.join(gstackDir, 'bin'); + fs.mkdirSync(binDir, { recursive: true }); + fs.writeFileSync(path.join(binDir, 'gstack-config'), '#!/bin/bash\necho "true"'); + fs.chmodSync(path.join(binDir, 'gstack-config'), 0o755); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + test('exits 0 when .git is missing', () => { + fs.rmSync(path.join(gstackDir, '.git'), { recursive: true }); + const result = run(SESSION_UPDATE, { + env: { GSTACK_DIR: gstackDir, GSTACK_STATE_DIR: stateDir }, + }); + expect(result.exitCode).toBe(0); + }); + + test('exits 0 when auto_upgrade is not true', () => { + // Override gstack-config to return false + fs.writeFileSync(path.join(gstackDir, 'bin', 'gstack-config'), '#!/bin/bash\necho "false"'); + const result = run(SESSION_UPDATE, { + env: { GSTACK_DIR: gstackDir, GSTACK_STATE_DIR: stateDir }, + }); + expect(result.exitCode).toBe(0); + }); + + test('throttle: skips when checked recently', () => { + // Write a recent throttle timestamp + const throttleFile = path.join(stateDir, '.last-session-update'); + fs.writeFileSync(throttleFile, String(Math.floor(Date.now() / 1000))); + + const result = run(SESSION_UPDATE, { + env: { GSTACK_DIR: gstackDir, GSTACK_STATE_DIR: stateDir }, + }); + expect(result.exitCode).toBe(0); + // No log file should be created (throttled before forking) + }); + + test('always exits 0 (non-fatal)', () => { + // Even with a broken setup, should exit 0 + const result = run(SESSION_UPDATE, { + env: { GSTACK_DIR: '/nonexistent/path', GSTACK_STATE_DIR: stateDir }, + }); + expect(result.exitCode).toBe(0); + }); +}); + +describe('gstack-team-init', () => { + let tmpDir: string; + + beforeEach(() => { + tmpDir = mkTmpDir(); + execSync('git init', { cwd: tmpDir }); + execSync('git commit --allow-empty -m "init"', { cwd: tmpDir }); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + test('errors without a mode argument', () => { + const result = run(TEAM_INIT, { cwd: tmpDir }); + expect(result.exitCode).not.toBe(0); + expect(result.stderr).toContain('Usage'); + }); + + test('errors outside a git repo', () => { + const nonGitDir = mkTmpDir(); + const result = run(`${TEAM_INIT} optional`, { cwd: nonGitDir }); + expect(result.exitCode).not.toBe(0); + expect(result.stderr).toContain('not in a git repository'); + fs.rmSync(nonGitDir, { recursive: true, force: true }); + }); + + test('optional: creates CLAUDE.md with recommended section', () => { + const result = run(`${TEAM_INIT} optional`, { cwd: tmpDir }); + expect(result.exitCode).toBe(0); + const claude = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8'); + expect(claude).toContain('## gstack (recommended)'); + expect(claude).toContain('./setup --team'); + }); + + test('required: creates CLAUDE.md with required section', () => { + const result = run(`${TEAM_INIT} required`, { cwd: tmpDir }); + expect(result.exitCode).toBe(0); + const claude = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8'); + expect(claude).toContain('## gstack (REQUIRED'); + expect(claude).toContain('GSTACK_MISSING'); + }); + + test('required: creates enforcement hook', () => { + run(`${TEAM_INIT} required`, { cwd: tmpDir }); + const hookPath = path.join(tmpDir, '.claude', 'hooks', 'check-gstack.sh'); + expect(fs.existsSync(hookPath)).toBe(true); + const hook = fs.readFileSync(hookPath, 'utf-8'); + expect(hook).toContain('BLOCKED: gstack is not installed'); + // Should be executable + const stat = fs.statSync(hookPath); + expect(stat.mode & 0o111).toBeGreaterThan(0); + }); + + test('required: creates project settings.json with PreToolUse hook', () => { + run(`${TEAM_INIT} required`, { cwd: tmpDir }); + const settingsPath = path.join(tmpDir, '.claude', 'settings.json'); + expect(fs.existsSync(settingsPath)).toBe(true); + const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8')); + expect(settings.hooks.PreToolUse).toHaveLength(1); + expect(settings.hooks.PreToolUse[0].matcher).toBe('Skill'); + expect(settings.hooks.PreToolUse[0].hooks[0].command).toContain('check-gstack'); + }); + + test('idempotent: running twice does not duplicate CLAUDE.md section', () => { + run(`${TEAM_INIT} optional`, { cwd: tmpDir }); + run(`${TEAM_INIT} optional`, { cwd: tmpDir }); + const claude = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8'); + const matches = claude.match(/## gstack/g); + expect(matches).toHaveLength(1); + }); +}); + +describe('setup --team / --no-team / -q', () => { + test('setup -q produces no stdout', () => { + const result = run(`${path.join(ROOT, 'setup')} -q`, { cwd: ROOT }); + // -q should suppress informational output (may still have some output from build) + // The key test is that the "Skill naming:" prompt and "gstack ready" messages are suppressed + expect(result.stdout).not.toContain('Skill naming:'); + expect(result.stdout).not.toContain('gstack ready'); + }); + + test('setup --local prints deprecation warning', () => { + // stderr capture: run via bash redirect so we can capture stderr + const result = run(`bash -c '${path.join(ROOT, 'setup')} --local -q 2>&1'`, { cwd: ROOT }); + expect(result.stdout).toContain('deprecated'); + }); +});