Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
# Auto-migrate legacy ~/.gstack/projects/ data to project-local .gstack/ (once per project)
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" || true
if [ -n "${PROJECT_DATA_DIR:-}" ] && [ -d "$HOME/.gstack/projects/${SLUG:-}" ] && [ ! -f "${PROJECT_DATA_DIR}/.migrated" ]; then
~/.claude/skills/gstack/bin/gstack-migrate-local 2>/dev/null && touch "${PROJECT_DATA_DIR}/.migrated" 2>/dev/null || true
fi
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
Expand Down
23 changes: 15 additions & 8 deletions autoplan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
# Auto-migrate legacy ~/.gstack/projects/ data to project-local .gstack/ (once per project)
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" || true
if [ -n "${PROJECT_DATA_DIR:-}" ] && [ -d "$HOME/.gstack/projects/${SLUG:-}" ] && [ ! -f "${PROJECT_DATA_DIR}/.migrated" ]; then
~/.claude/skills/gstack/bin/gstack-migrate-local 2>/dev/null && touch "${PROJECT_DATA_DIR}/.migrated" 2>/dev/null || true
fi
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
Expand Down Expand Up @@ -515,9 +520,11 @@ Execute every other section at full depth. When the loaded skill's instructions
After /office-hours completes, re-run the design doc check:
```bash
setopt +o nomatch 2>/dev/null || true # zsh compat
SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null || basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-' || echo 'no-branch')
DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1)
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)"
DESIGN=$(ls -t "$PROJECT_DATA_DIR"/designs/*-$BRANCH-design-*.md 2>/dev/null | head -1)
[ -z "$DESIGN" ] && DESIGN=$(ls -t "$PROJECT_DATA_DIR"/designs/*-design-*.md 2>/dev/null | head -1)
# Fallback: legacy global path
[ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 2>/dev/null | head -1)
[ -z "$DESIGN" ] && DESIGN=$(ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1)
[ -n "$DESIGN" ] && echo "Design doc found: $DESIGN" || echo "No design doc found"
```
Expand Down Expand Up @@ -655,10 +662,10 @@ instructions instead of reviewing the plan.
Before doing anything, save the plan file's current state to an external file:

```bash
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p "$PROJECT_DATA_DIR"
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-')
DATETIME=$(date +%Y%m%d-%H%M%S)
echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md"
echo "RESTORE_PATH=$PROJECT_DATA_DIR/plans/${BRANCH}-autoplan-restore-${DATETIME}.md"
```

Write the plan file's full contents to the restore path with this header:
Expand All @@ -680,7 +687,7 @@ Then prepend a one-line HTML comment to the plan file:
### Step 2: Read context

- Read CLAUDE.md, TODOS.md, git log -30, git diff against the base branch --stat
- Discover design docs: `ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1`
- Discover design docs: `ls -t "$PROJECT_DATA_DIR"/designs/*-design-*.md 2>/dev/null || ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1`
- Detect UI scope: grep the plan for view/rendering terms (component, screen, form,
button, modal, layout, dashboard, sidebar, nav, dialog). Require 2+ matches. Exclude
false positives ("page" alone, "UI" in acronyms).
Expand Down Expand Up @@ -952,7 +959,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.

- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
- Evals: always include all relevant suites (P1)
- Test plan: generate artifact at `~/.gstack/projects/$SLUG/{user}-{branch}-test-plan-{datetime}.md`
- Test plan: generate artifact at `.gstack/plans/{user}-{branch}-test-plan-{datetime}.md`
- TODOS.md: collect all deferred scope expansions from Phase 1, auto-write

**Required execution checklist (Eng):**
Expand Down Expand Up @@ -1056,7 +1063,7 @@ produced. Check the plan file and conversation for each item.
- [ ] Scope challenge with actual code analysis (not just "scope is fine")
- [ ] Architecture ASCII diagram produced
- [ ] Test diagram mapping codepaths to test coverage
- [ ] Test plan artifact written to disk at ~/.gstack/projects/$SLUG/
- [ ] Test plan artifact written to disk at .gstack/
- [ ] "NOT in scope" section written
- [ ] "What already exists" section written
- [ ] Failure modes registry with critical gap assessment
Expand Down
8 changes: 4 additions & 4 deletions autoplan/SKILL.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Before doing anything, save the plan file's current state to an external file:
{{SLUG_SETUP}}
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-')
DATETIME=$(date +%Y%m%d-%H%M%S)
echo "RESTORE_PATH=$HOME/.gstack/projects/$SLUG/${BRANCH}-autoplan-restore-${DATETIME}.md"
echo "RESTORE_PATH=$PROJECT_DATA_DIR/plans/${BRANCH}-autoplan-restore-${DATETIME}.md"
```

Write the plan file's full contents to the restore path with this header:
Expand All @@ -184,7 +184,7 @@ Then prepend a one-line HTML comment to the plan file:
### Step 2: Read context

- Read CLAUDE.md, TODOS.md, git log -30, git diff against the base branch --stat
- Discover design docs: `ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1`
- Discover design docs: `ls -t "$PROJECT_DATA_DIR"/designs/*-design-*.md 2>/dev/null || ls -t ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null | head -1`
- Detect UI scope: grep the plan for view/rendering terms (component, screen, form,
button, modal, layout, dashboard, sidebar, nav, dialog). Require 2+ matches. Exclude
false positives ("page" alone, "UI" in acronyms).
Expand Down Expand Up @@ -456,7 +456,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.

- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
- Evals: always include all relevant suites (P1)
- Test plan: generate artifact at `~/.gstack/projects/$SLUG/{user}-{branch}-test-plan-{datetime}.md`
- Test plan: generate artifact at `.gstack/plans/{user}-{branch}-test-plan-{datetime}.md`
- TODOS.md: collect all deferred scope expansions from Phase 1, auto-write

**Required execution checklist (Eng):**
Expand Down Expand Up @@ -560,7 +560,7 @@ produced. Check the plan file and conversation for each item.
- [ ] Scope challenge with actual code analysis (not just "scope is fine")
- [ ] Architecture ASCII diagram produced
- [ ] Test diagram mapping codepaths to test coverage
- [ ] Test plan artifact written to disk at ~/.gstack/projects/$SLUG/
- [ ] Test plan artifact written to disk at .gstack/
- [ ] "NOT in scope" section written
- [ ] "What already exists" section written
- [ ] Failure modes registry with critical gap assessment
Expand Down
5 changes: 5 additions & 0 deletions benchmark/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
# Auto-migrate legacy ~/.gstack/projects/ data to project-local .gstack/ (once per project)
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" || true
if [ -n "${PROJECT_DATA_DIR:-}" ] && [ -d "$HOME/.gstack/projects/${SLUG:-}" ] && [ ! -f "${PROJECT_DATA_DIR}/.migrated" ]; then
~/.claude/skills/gstack/bin/gstack-migrate-local 2>/dev/null && touch "${PROJECT_DATA_DIR}/.migrated" 2>/dev/null || true
fi
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
Expand Down
Binary file modified bin/gstack-global-discover
Binary file not shown.
198 changes: 198 additions & 0 deletions bin/gstack-migrate-local
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#!/usr/bin/env bash
# gstack-migrate-local — migrate + reorganize project data into .gstack/ subdirectories
#
# Handles two migration scenarios:
# 1. Legacy global: ~/.gstack/projects/$SLUG/* → .gstack/{designs,plans,...}/
# 2. Local flat: .gstack/*-design-*.md → .gstack/designs/ (reorganize in place)
#
# Idempotent — safe to run multiple times. Non-destructive (skips existing files).
#
# Usage: gstack-migrate-local [--dry-run]
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
eval "$("$SCRIPT_DIR/gstack-slug" 2>/dev/null)"

OLD="$HOME/.gstack/projects/$SLUG"
NEW="$PROJECT_DATA_DIR"
DRY_RUN=false
[ "${1:-}" = "--dry-run" ] && DRY_RUN=true

MOVED=0

migrate() {
local src="$1" dst_dir="$2"
[ -e "$src" ] || return 0
local name
name=$(basename "$src")
# Skip if source and destination are the same path
local abs_src abs_dst
abs_src=$(cd "$(dirname "$src")" && pwd)/$(basename "$src")
abs_dst="$dst_dir/$name"
[ "$abs_src" = "$abs_dst" ] && return 0
if [ -e "$dst_dir/$name" ]; then
# Target exists — remove source duplicate if it's a file (dedup)
if [ -f "$src" ] && [ -f "$dst_dir/$name" ]; then
$DRY_RUN || rm -f "$src"
fi
return 0
fi
if $DRY_RUN; then
echo " WOULD MOVE: $name → $dst_dir/"
else
mkdir -p "$dst_dir"
mv "$src" "$dst_dir/"
fi
MOVED=$((MOVED + 1))
}

migrate_dir() {
local src="$1" dst="$2"
[ -d "$src" ] || return 0
if [ -d "$dst" ]; then
# Merge contents
for f in "$src"/*; do
[ -e "$f" ] && migrate "$f" "$dst"
done
$DRY_RUN || rmdir "$src" 2>/dev/null || true
else
if $DRY_RUN; then
echo " WOULD MOVE: $(basename "$src")/ → $(dirname "$dst")/"
else
mkdir -p "$(dirname "$dst")"
mv "$src" "$dst"
fi
MOVED=$((MOVED + 1))
fi
}

# ═══════════════════════════════════════════════════════════
# Phase 1: Migrate from legacy global ~/.gstack/projects/$SLUG/
# ═══════════════════════════════════════════════════════════

if [ -d "$OLD" ]; then
# Design docs
for f in "$OLD"/*-design-*.md "$OLD"/*-design-audit-*.md; do
[ -e "$f" ] && migrate "$f" "$NEW/designs"
done

# Test plans, autoplan, eng review
for f in "$OLD"/*-test-plan-*.md "$OLD"/*-eng-review-*.md "$OLD"/*-autoplan-restore-*.md "$OLD"/*-ship-test-plan-*.md; do
[ -e "$f" ] && migrate "$f" "$NEW/plans"
done

# CEO plans directory
[ -d "$OLD/ceo-plans" ] && migrate_dir "$OLD/ceo-plans" "$NEW/plans/ceo-plans"

# Review logs
for f in "$OLD"/*-reviews.jsonl; do
[ -e "$f" ] && migrate "$f" "$NEW"
done

# Test outcomes
for f in "$OLD"/*-test-outcome-*.md; do
[ -e "$f" ] && migrate "$f" "$NEW"
done

# Evals directory
[ -d "$OLD/evals" ] && migrate_dir "$OLD/evals" "$NEW/evals"

# Greptile history
[ -e "$OLD/greptile-history.md" ] && migrate "$OLD/greptile-history.md" "$NEW"

# Deploy confirmation fingerprint
[ -e "$OLD/land-deploy-confirmed" ] && migrate "$OLD/land-deploy-confirmed" "$NEW"

# CEO handoff files
for f in "$OLD"/*-ceo-handoff-*.md; do
[ -e "$f" ] && migrate "$f" "$NEW"
done

# repo-mode.json → .gstack/local/ (machine-local cache)
[ -e "$OLD/repo-mode.json" ] && migrate "$OLD/repo-mode.json" "$NEW/local"

# Clean up empty legacy directory
$DRY_RUN || rmdir "$OLD" 2>/dev/null || true
fi

# ═══════════════════════════════════════════════════════════
# Phase 2: Reorganize flat files in .gstack/ root → subdirectories
# ═══════════════════════════════════════════════════════════

if [ -d "$NEW" ]; then
# Design docs at root → designs/
for f in "$NEW"/*-design-*.md "$NEW"/*-design-audit-*.md "$NEW"/*-architecture*.md; do
[ -e "$f" ] && migrate "$f" "$NEW/designs"
done

# Test plans at root → plans/
for f in "$NEW"/*-test-plan-*.md "$NEW"/*-eng-review-*.md "$NEW"/*-autoplan-restore-*.md "$NEW"/*-ship-test-plan-*.md; do
[ -e "$f" ] && migrate "$f" "$NEW/plans"
done

# Implementation plans / roadmaps at root → plans/
for f in "$NEW"/*-implementation-plan*.md "$NEW"/*-delivery-roadmap*.md; do
[ -e "$f" ] && migrate "$f" "$NEW/plans"
done

# CEO plans at root → plans/ceo-plans/
[ -d "$NEW/ceo-plans" ] && [ "$NEW/ceo-plans" != "$NEW/plans/ceo-plans" ] && \
migrate_dir "$NEW/ceo-plans" "$NEW/plans/ceo-plans"

# repo-mode.json at root → local/
[ -e "$NEW/repo-mode.json" ] && migrate "$NEW/repo-mode.json" "$NEW/local"

# browse.json at root → local/ (old browse daemon location)
[ -e "$NEW/browse.json" ] && migrate "$NEW/browse.json" "$NEW/local"
for f in "$NEW"/browse-console.log "$NEW"/browse-network.log "$NEW"/browse-dialog.log "$NEW"/browse-server.log; do
[ -e "$f" ] && migrate "$f" "$NEW/local"
done
fi

# ═══════════════════════════════════════════════════════════
# Phase 3: Ensure .gitignore and project .gitignore are correct
# ═══════════════════════════════════════════════════════════

if ! $DRY_RUN; then
mkdir -p "$NEW"

# Ensure .gstack/.gitignore has local/ and .migrated
GITIGNORE="$NEW/.gitignore"
CONTENT=""
[ -f "$GITIGNORE" ] && CONTENT=$(cat "$GITIGNORE")
UPDATED=false
if ! echo "$CONTENT" | grep -q '^local/$' 2>/dev/null; then
CONTENT="${CONTENT:+$CONTENT
}local/"
UPDATED=true
fi
if ! echo "$CONTENT" | grep -q '^\.migrated$' 2>/dev/null; then
CONTENT="${CONTENT:+$CONTENT
}.migrated"
UPDATED=true
fi
$UPDATED && echo "$CONTENT" > "$GITIGNORE"

# Remove blanket .gstack/ from project .gitignore
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
if [ -n "$GIT_ROOT" ] && [ -f "$GIT_ROOT/.gitignore" ]; then
if grep -q '^\.gstack/\?$' "$GIT_ROOT/.gitignore" 2>/dev/null; then
sed -i.bak '/^\.gstack\/\?$/d' "$GIT_ROOT/.gitignore"
rm -f "$GIT_ROOT/.gitignore.bak"
fi
fi
fi

# ═══════════════════════════════════════════════════════════
# Summary
# ═══════════════════════════════════════════════════════════

if [ "$MOVED" -eq 0 ]; then
exit 0
fi

if $DRY_RUN; then
echo "Dry run: $MOVED items would be migrated. Run without --dry-run to execute."
else
echo "gstack: migrated $MOVED items to $NEW"
fi
7 changes: 6 additions & 1 deletion bin/gstack-repo-mode
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ if [ -n "$OVERRIDE" ] && [ "$OVERRIDE" != "null" ]; then
fi

# Check cache (7-day TTL)
CACHE_DIR="$HOME/.gstack/projects/$SLUG"
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
if [ -n "$GIT_ROOT" ]; then
CACHE_DIR="$GIT_ROOT/.gstack/local"
else
CACHE_DIR="$HOME/.gstack/projects/$SLUG"
fi
CACHE_FILE="$CACHE_DIR/repo-mode.json"
if [ -f "$CACHE_FILE" ]; then
CACHE_AGE=$(( $(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0) ))
Expand Down
5 changes: 2 additions & 3 deletions bin/gstack-review-log
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
eval "$("$SCRIPT_DIR/gstack-slug" 2>/dev/null)"
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
mkdir -p "$GSTACK_HOME/projects/$SLUG"
mkdir -p "$PROJECT_DATA_DIR"

# Validate: input must be parseable JSON (reject malformed or injection attempts)
INPUT="$1"
Expand All @@ -15,4 +14,4 @@ if ! printf '%s' "$INPUT" | bun -e "JSON.parse(await Bun.stdin.text())" 2>/dev/n
exit 1
fi

echo "$INPUT" >> "$GSTACK_HOME/projects/$SLUG/$BRANCH-reviews.jsonl"
echo "$INPUT" >> "$PROJECT_DATA_DIR/$BRANCH-reviews.jsonl"
10 changes: 8 additions & 2 deletions bin/gstack-review-read
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
eval "$("$SCRIPT_DIR/gstack-slug" 2>/dev/null)"
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
cat "$GSTACK_HOME/projects/$SLUG/$BRANCH-reviews.jsonl" 2>/dev/null || echo "NO_REVIEWS"
# Try project-local first, fall back to legacy global path
if [ -f "$PROJECT_DATA_DIR/$BRANCH-reviews.jsonl" ]; then
cat "$PROJECT_DATA_DIR/$BRANCH-reviews.jsonl"
elif [ -f "$HOME/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl" ]; then
cat "$HOME/.gstack/projects/$SLUG/$BRANCH-reviews.jsonl"
else
echo "NO_REVIEWS"
fi
echo "---CONFIG---"
"$SCRIPT_DIR/gstack-config" get skip_eng_review 2>/dev/null || echo "false"
echo "---HEAD---"
Expand Down
7 changes: 7 additions & 0 deletions bin/gstack-slug
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,12 @@ BRANCH=$(printf '%s' "${RAW_BRANCH:-}" | tr -cd 'a-zA-Z0-9._-')
# Fallback when git context is absent
SLUG="${SLUG:-$(basename "$PWD" | tr -cd 'a-zA-Z0-9._-')}"
BRANCH="${BRANCH:-unknown}"
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
if [ -n "$GIT_ROOT" ]; then
PROJECT_DATA_DIR="$GIT_ROOT/.gstack"
else
PROJECT_DATA_DIR="$HOME/.gstack/projects/$SLUG"
fi
echo "SLUG=$SLUG"
echo "BRANCH=$BRANCH"
echo "PROJECT_DATA_DIR=$PROJECT_DATA_DIR"
5 changes: 5 additions & 0 deletions browse/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
# Auto-migrate legacy ~/.gstack/projects/ data to project-local .gstack/ (once per project)
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" || true
if [ -n "${PROJECT_DATA_DIR:-}" ] && [ -d "$HOME/.gstack/projects/${SLUG:-}" ] && [ ! -f "${PROJECT_DATA_DIR}/.migrated" ]; then
~/.claude/skills/gstack/bin/gstack-migrate-local 2>/dev/null && touch "${PROJECT_DATA_DIR}/.migrated" 2>/dev/null || true
fi
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
Expand Down
Loading