Skip to main content

gstack

Enables fast web browsing for Claude Code with a headless Chromium daemon, allowing navigation, content extraction, and interaction with web pages.

Install this skill

or
0/100

Security score

The gstack skill was audited on May 10, 2026 and we found 98 security issues across 4 threat categories, including 1 high-severity. Review the findings below before installing.

Categories Tested

Security Issues

low line 27

Command substitution pattern

SourceSKILL.md
25
26```bash
27_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
28[ -n "$_UPD" ] && echo "$_UPD" || true
29mkdir -p ~/.gstack/sessions
low line 31

Command substitution pattern

SourceSKILL.md
29mkdir -p ~/.gstack/sessions
30touch ~/.gstack/sessions/"$PPID"
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
low line 33

Command substitution pattern

SourceSKILL.md
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
low line 34

Command substitution pattern

SourceSKILL.md
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
36echo "BRANCH: $_BRANCH"
low line 35

Command substitution pattern

SourceSKILL.md
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
36echo "BRANCH: $_BRANCH"
37_SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false")
low line 37

Command substitution pattern

SourceSKILL.md
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
36echo "BRANCH: $_BRANCH"
37_SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false")
38echo "PROACTIVE: $_PROACTIVE"
39echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
low line 44

Command substitution pattern

SourceSKILL.md
42REPO_MODE=${REPO_MODE:-unknown}
43echo "REPO_MODE: $REPO_MODE"
44_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
low line 46

Command substitution pattern

SourceSKILL.md
44_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
47_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
48_TEL_START=$(date +%s)
low line 47

Command substitution pattern

SourceSKILL.md
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
47_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
48_TEL_START=$(date +%s)
49_SESSION_ID="$$-$(date +%s)"
low line 52

Command substitution pattern

SourceSKILL.md
50echo "TELEMETRY: ${_TEL:-off}"
51echo "TEL_PROMPTED: $_TEL_PROMPTED"
52_EXPLAIN_LEVEL=$(~/.claude/skills/gstack/bin/gstack-config get explain_level 2>/dev/null || echo "default")
53if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
54echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
low line 55

Command substitution pattern

SourceSKILL.md
53if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
54echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
55_QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false")
56echo "QUESTION_TUNING: $_QUESTION_TUNING"
57mkdir -p ~/.gstack/analytics
low line 59

Command substitution pattern

SourceSKILL.md
57mkdir -p ~/.gstack/analytics
58if [ "$_TEL" != "off" ]; then
59echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
60fi
61for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
low line 61

Command substitution pattern

SourceSKILL.md
59echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
60fi
61for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
62 if [ -f "$_PF" ]; then
63 if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
low line 70

Command substitution pattern

SourceSKILL.md
68 break
69done
70eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
71_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
72if [ -f "$_LEARN_FILE" ]; then
low line 73

Command substitution pattern

SourceSKILL.md
71_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
72if [ -f "$_LEARN_FILE" ]; then
73 _LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
74 echo "LEARNINGS: $_LEARN_COUNT entries loaded"
75 if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
low line 86

Command substitution pattern

SourceSKILL.md
84 _HAS_ROUTING="yes"
85fi
86_ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false")
87echo "HAS_ROUTING: $_HAS_ROUTING"
88echo "ROUTING_DECLINED: $_ROUTING_DECLINED"
low line 97

Command substitution pattern

SourceSKILL.md
95echo "VENDORED_GSTACK: $_VENDORED"
96echo "MODEL_OVERLAY: claude"
97_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
98_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
99echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
low line 98

Command substitution pattern

SourceSKILL.md
96echo "MODEL_OVERLAY: claude"
97_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
98_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
99echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
100echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
low line 260

Command substitution pattern

SourceSKILL.md
258Always run (regardless of choice):
259```bash
260eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
261touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}
262```
low line 295

Command substitution pattern

SourceSKILL.md
293_GBRAIN_CONFIG="$HOME/.gbrain/config.json"
294if [ -f "$_GBRAIN_CONFIG" ] && command -v gbrain >/dev/null 2>&1; then
295 _GBRAIN_VERSION_OK=$(gbrain --version 2>/dev/null | grep -c '^gbrain ' || echo 0)
296 if [ "$_GBRAIN_VERSION_OK" -gt 0 ] 2>/dev/null; then
297 _GBRAIN_PIN_PATH=""
low line 298

Command substitution pattern

SourceSKILL.md
296 if [ "$_GBRAIN_VERSION_OK" -gt 0 ] 2>/dev/null; then
297 _GBRAIN_PIN_PATH=""
298 _REPO_TOP=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
299 if [ -n "$_REPO_TOP" ] && [ -f "$_REPO_TOP/.gbrain-source" ]; then
300 _GBRAIN_PIN_PATH="$_REPO_TOP/.gbrain-source"
low line 315

Command substitution pattern

SourceSKILL.md
313fi
314
315_BRAIN_SYNC_MODE=$("$_BRAIN_CONFIG_BIN" get artifacts_sync_mode 2>/dev/null || echo off)
316
317# Detect remote-MCP mode (Path 4 of /setup-gbrain). Local artifacts sync is
low line 323

Command substitution pattern

SourceSKILL.md
321_GBRAIN_MCP_MODE="none"
322if command -v jq >/dev/null 2>&1 && [ -f "$HOME/.claude.json" ]; then
323 _GBRAIN_MCP_TYPE=$(jq -r '.mcpServers.gbrain.type // .mcpServers.gbrain.transport // empty' "$HOME/.claude.json" 2>/dev/null)
324 case "$_GBRAIN_MCP_TYPE" in
325 url|http|sse) _GBRAIN_MCP_MODE="remote-http" ;;
low line 331

Command substitution pattern

SourceSKILL.md
329
330if [ -f "$_BRAIN_REMOTE_FILE" ] && [ ! -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" = "off" ]; then
331 _BRAIN_NEW_URL=$(head -1 "$_BRAIN_REMOTE_FILE" 2>/dev/null | tr -d '[:space:]')
332 if [ -n "$_BRAIN_NEW_URL" ]; then
333 echo "ARTIFACTS_SYNC: artifacts repo detected: $_BRAIN_NEW_URL"
low line 343

Command substitution pattern

SourceSKILL.md
341 _BRAIN_DO_PULL=1
342 if [ -f "$_BRAIN_LAST_PULL_FILE" ]; then
343 _BRAIN_LAST=$(cat "$_BRAIN_LAST_PULL_FILE" 2>/dev/null || echo 0)
344 _BRAIN_AGE=$(( _BRAIN_NOW - _BRAIN_LAST ))
345 [ "$_BRAIN_AGE" -lt 86400 ] && _BRAIN_DO_PULL=0
low line 344

Command substitution pattern

SourceSKILL.md
342 if [ -f "$_BRAIN_LAST_PULL_FILE" ]; then
343 _BRAIN_LAST=$(cat "$_BRAIN_LAST_PULL_FILE" 2>/dev/null || echo 0)
344 _BRAIN_AGE=$(( _BRAIN_NOW - _BRAIN_LAST ))
345 [ "$_BRAIN_AGE" -lt 86400 ] && _BRAIN_DO_PULL=0
346 fi
low line 348

Command substitution pattern

SourceSKILL.md
346 fi
347 if [ "$_BRAIN_DO_PULL" = "1" ]; then
348 ( cd "$_GSTACK_HOME" && git fetch origin >/dev/null 2>&1 && git merge --ff-only "origin/$(git rev-parse --abbrev-ref HEAD)" >/dev/null 2>&1 ) || true
349 echo "$_BRAIN_NOW" > "$_BRAIN_LAST_PULL_FILE"
350 fi
low line 357

Command substitution pattern

SourceSKILL.md
355 # Remote-MCP mode: local artifacts sync is a no-op (brain admin's server
356 # pulls from GitHub/GitLab). Show the user this is by design, not broken.
357 _GBRAIN_HOST=$(jq -r '.mcpServers.gbrain.url // empty' "$HOME/.claude.json" 2>/dev/null | sed -E 's|^https?://([^/:]+).*|\1|')
358 echo "ARTIFACTS_SYNC: remote-mode (managed by brain server ${_GBRAIN_HOST:-remote})"
359elif [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
low line 361

Command substitution pattern

SourceSKILL.md
359elif [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
360 _BRAIN_QUEUE_DEPTH=0
361 [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ')
362 _BRAIN_LAST_PUSH="never"
363 [ -f "$_GSTACK_HOME/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(cat "$_GSTACK_HOME/.brain-last-push" 2>/dev/null || echo never)
low line 363

Command substitution pattern

SourceSKILL.md
361 [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ')
362 _BRAIN_LAST_PUSH="never"
363 [ -f "$_GSTACK_HOME/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(cat "$_GSTACK_HOME/.brain-last-push" 2>/dev/null || echo never)
364 echo "ARTIFACTS_SYNC: mode=$_BRAIN_SYNC_MODE | last_push=$_BRAIN_LAST_PUSH | queue=$_BRAIN_QUEUE_DEPTH"
365else
low line 456

Command substitution pattern

SourceSKILL.md
454```bash
455_TEL_END=$(date +%s)
456_TEL_DUR=$(( _TEL_END - _TEL_START ))
457rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
458# Session timeline: record skill completion (local-only, never sent anywhere)
low line 459

Command substitution pattern

SourceSKILL.md
457rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
458# Session timeline: record skill completion (local-only, never sent anywhere)
459~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true
460# Local analytics (gated on telemetry setting)
461if [ "$_TEL" != "off" ]; then
low line 462

Command substitution pattern

SourceSKILL.md
460# Local analytics (gated on telemetry setting)
461if [ "$_TEL" != "off" ]; then
462echo '{"skill":"SKILL_NAME","duration_s":"'"$_TEL_DUR"'","outcome":"OUTCOME","browse":"USED_BROWSE","session":"'"$_SESSION_ID"'","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
463fi
464# Remote telemetry (opt-in, requires binary)
low line 541

Command substitution pattern

SourceSKILL.md
539
540```bash
541_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
542B=""
543[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse"
low line 562

Command substitution pattern

SourceSKILL.md
560 tmpfile=$(mktemp)
561 curl -fsSL "https://bun.sh/install" -o "$tmpfile"
562 actual_sha=$(shasum -a 256 "$tmpfile" | awk '{print $1}')
563 if [ "$actual_sha" != "$BUN_INSTALL_SHA" ]; then
564 echo "ERROR: bun install script checksum mismatch" >&2
medium line 561

Curl to non-GitHub URL

SourceSKILL.md
559 BUN_INSTALL_SHA="bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd"
560 tmpfile=$(mktemp)
561 curl -fsSL "https://bun.sh/install" -o "$tmpfile"
562 actual_sha=$(shasum -a 256 "$tmpfile" | awk '{print $1}')
563 if [ "$actual_sha" != "$BUN_INSTALL_SHA" ]; then
low line 27

Access to home directory dotfiles

SourceSKILL.md
25
26```bash
27_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
28[ -n "$_UPD" ] && echo "$_UPD" || true
29mkdir -p ~/.gstack/sessions
low line 29

Access to home directory dotfiles

SourceSKILL.md
27_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
28[ -n "$_UPD" ] && echo "$_UPD" || true
29mkdir -p ~/.gstack/sessions
30touch ~/.gstack/sessions/"$PPID"
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
low line 30

Access to home directory dotfiles

SourceSKILL.md
28[ -n "$_UPD" ] && echo "$_UPD" || true
29mkdir -p ~/.gstack/sessions
30touch ~/.gstack/sessions/"$PPID"
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
low line 31

Access to home directory dotfiles

SourceSKILL.md
29mkdir -p ~/.gstack/sessions
30touch ~/.gstack/sessions/"$PPID"
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
low line 32

Access to home directory dotfiles

SourceSKILL.md
30touch ~/.gstack/sessions/"$PPID"
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
low line 33

Access to home directory dotfiles

SourceSKILL.md
31_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
low line 34

Access to home directory dotfiles

SourceSKILL.md
32find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
33_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
34_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
36echo "BRANCH: $_BRANCH"
low line 37

Access to home directory dotfiles

SourceSKILL.md
35_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
36echo "BRANCH: $_BRANCH"
37_SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false")
38echo "PROACTIVE: $_PROACTIVE"
39echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
low line 41

Access to home directory dotfiles

SourceSKILL.md
39echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
40echo "SKILL_PREFIX: $_SKILL_PREFIX"
41source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
42REPO_MODE=${REPO_MODE:-unknown}
43echo "REPO_MODE: $REPO_MODE"
low line 44

Access to home directory dotfiles

SourceSKILL.md
42REPO_MODE=${REPO_MODE:-unknown}
43echo "REPO_MODE: $REPO_MODE"
44_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
low line 46

Access to home directory dotfiles

SourceSKILL.md
44_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
47_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
48_TEL_START=$(date +%s)
low line 47

Access to home directory dotfiles

SourceSKILL.md
45echo "LAKE_INTRO: $_LAKE_SEEN"
46_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
47_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
48_TEL_START=$(date +%s)
49_SESSION_ID="$$-$(date +%s)"
low line 52

Access to home directory dotfiles

SourceSKILL.md
50echo "TELEMETRY: ${_TEL:-off}"
51echo "TEL_PROMPTED: $_TEL_PROMPTED"
52_EXPLAIN_LEVEL=$(~/.claude/skills/gstack/bin/gstack-config get explain_level 2>/dev/null || echo "default")
53if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
54echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
low line 55

Access to home directory dotfiles

SourceSKILL.md
53if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
54echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
55_QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false")
56echo "QUESTION_TUNING: $_QUESTION_TUNING"
57mkdir -p ~/.gstack/analytics
low line 57

Access to home directory dotfiles

SourceSKILL.md
55_QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false")
56echo "QUESTION_TUNING: $_QUESTION_TUNING"
57mkdir -p ~/.gstack/analytics
58if [ "$_TEL" != "off" ]; then
59echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
low line 59

Access to home directory dotfiles

SourceSKILL.md
57mkdir -p ~/.gstack/analytics
58if [ "$_TEL" != "off" ]; then
59echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
60fi
61for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
low line 61

Access to home directory dotfiles

SourceSKILL.md
59echo '{"skill":"gstack","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
60fi
61for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
62 if [ -f "$_PF" ]; then
63 if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
low line 63

Access to home directory dotfiles

SourceSKILL.md
61for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
62 if [ -f "$_PF" ]; then
63 if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
64 ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true
65 fi
low line 64

Access to home directory dotfiles

SourceSKILL.md
62 if [ -f "$_PF" ]; then
63 if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
64 ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true
65 fi
66 rm -f "$_PF" 2>/dev/null || true
low line 70

Access to home directory dotfiles

SourceSKILL.md
68 break
69done
70eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
71_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
72if [ -f "$_LEARN_FILE" ]; then
low line 76

Access to home directory dotfiles

SourceSKILL.md
74 echo "LEARNINGS: $_LEARN_COUNT entries loaded"
75 if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
76 ~/.claude/skills/gstack/bin/gstack-learnings-search --limit 3 2>/dev/null || true
77 fi
78else
low line 81

Access to home directory dotfiles

SourceSKILL.md
79 echo "LEARNINGS: 0"
80fi
81~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"gstack","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null &
82_HAS_ROUTING="no"
83if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then
low line 86

Access to home directory dotfiles

SourceSKILL.md
84 _HAS_ROUTING="yes"
85fi
86_ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false")
87echo "HAS_ROUTING: $_HAS_ROUTING"
88echo "ROUTING_DECLINED: $_ROUTING_DECLINED"
low line 97

Access to home directory dotfiles

SourceSKILL.md
95echo "VENDORED_GSTACK: $_VENDORED"
96echo "MODEL_OVERLAY: claude"
97_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
98_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
99echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
low line 98

Access to home directory dotfiles

SourceSKILL.md
96echo "MODEL_OVERLAY: claude"
97_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
98_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
99echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
100echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
medium line 106

Access to home directory dotfiles

SourceSKILL.md
104## Plan Mode Safe Operations
105
106In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`codex review`, writes to `~/.gstack/`, writes to the plan file, and `open` for generated artifacts.
107
108## Skill Invocation During Plan Mode
medium line 114

Access to home directory dotfiles

SourceSKILL.md
112If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
113
114If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay `~/.claude/skills/gstack/[skill-name]/SKILL.md`.
115
116If output shows `UPGRADE_AVAILABLE <old> <new>`: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined).
medium line 116

Access to home directory dotfiles

SourceSKILL.md
114If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay `~/.claude/skills/gstack/[skill-name]/SKILL.md`.
115
116If output shows `UPGRADE_AVAILABLE <old> <new>`: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined).
117
118If output shows `JUST_UPGRADED <from> <to>`: print "Running gstack v{to} (just updated!)". If `SPAWNED_SESSION` is true, skip feature discovery.
medium line 121

Access to home directory dotfiles

SourceSKILL.md
119
120Feature discovery, max one prompt per session:
121- Missing `~/.claude/skills/gstack/.feature-prompted-continuous-checkpoint`: AskUserQuestion for Continuous checkpoint auto-commits. If accepted, run `~/.claude/skills/gstack/bin/gstack-config set checkpoint_mode continuous`. Always touch marker.
122- Missing `~/.claude/skills/gstack/.feature-prompted-model-overlay`: inform "Model overlays are active. MODEL_OVERLAY shows the patch." Always touch marker.
123
medium line 122

Access to home directory dotfiles

SourceSKILL.md
120Feature discovery, max one prompt per session:
121- Missing `~/.claude/skills/gstack/.feature-prompted-continuous-checkpoint`: AskUserQuestion for Continuous checkpoint auto-commits. If accepted, run `~/.claude/skills/gstack/bin/gstack-config set checkpoint_mode continuous`. Always touch marker.
122- Missing `~/.claude/skills/gstack/.feature-prompted-model-overlay`: inform "Model overlays are active. MODEL_OVERLAY shows the patch." Always touch marker.
123
124After upgrade prompts, continue workflow.
medium line 135

Access to home directory dotfiles

SourceSKILL.md
133
134If A: leave `explain_level` unset (defaults to `default`).
135If B: run `~/.claude/skills/gstack/bin/gstack-config set explain_level terse`.
136
137Always run (regardless of choice):
low line 139

Access to home directory dotfiles

SourceSKILL.md
137Always run (regardless of choice):
138```bash
139rm -f ~/.gstack/.writing-style-prompt-pending
140touch ~/.gstack/.writing-style-prompted
141```
low line 140

Access to home directory dotfiles

SourceSKILL.md
138```bash
139rm -f ~/.gstack/.writing-style-prompt-pending
140touch ~/.gstack/.writing-style-prompted
141```
142
low line 149

Access to home directory dotfiles

SourceSKILL.md
147```bash
148open https://garryslist.org/posts/boil-the-ocean
149touch ~/.gstack/.completeness-intro-seen
150```
151
medium line 162

Access to home directory dotfiles

SourceSKILL.md
160- B) No thanks
161
162If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community`
163
164If B: ask follow-up:
medium line 172

Access to home directory dotfiles

SourceSKILL.md
170- B) No thanks, fully off
171
172If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous`
173If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off`
174
medium line 173

Access to home directory dotfiles

SourceSKILL.md
171
172If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous`
173If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off`
174
175Always run:
low line 177

Access to home directory dotfiles

SourceSKILL.md
175Always run:
176```bash
177touch ~/.gstack/.telemetry-prompted
178```
179
medium line 190

Access to home directory dotfiles

SourceSKILL.md
188- B) Turn it off — I'll type /commands myself
189
190If A: run `~/.claude/skills/gstack/bin/gstack-config set proactive true`
191If B: run `~/.claude/skills/gstack/bin/gstack-config set proactive false`
192
medium line 191

Access to home directory dotfiles

SourceSKILL.md
189
190If A: run `~/.claude/skills/gstack/bin/gstack-config set proactive true`
191If B: run `~/.claude/skills/gstack/bin/gstack-config set proactive false`
192
193Always run:
low line 195

Access to home directory dotfiles

SourceSKILL.md
193Always run:
194```bash
195touch ~/.gstack/.proactive-prompted
196```
197
medium line 236

Access to home directory dotfiles

SourceSKILL.md
234Then commit the change: `git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"`
235
236If B: run `~/.claude/skills/gstack/bin/gstack-config set routing_declined true` and say they can re-enable with `gstack-config set routing_declined false`.
237
238This only happens once per project. Skip if `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`.
medium line 240

Access to home directory dotfiles

SourceSKILL.md
238This only happens once per project. Skip if `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`.
239
240If `VENDORED_GSTACK` is `yes`, warn once via AskUserQuestion unless `~/.gstack/.vendoring-warned-$SLUG` exists:
241
242> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated.
medium line 252

Access to home directory dotfiles

SourceSKILL.md
2501. Run `git rm -r .claude/skills/gstack/`
2512. Run `echo '.claude/skills/gstack/' >> .gitignore`
2523. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`)
2534. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"`
2545. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`"
medium line 254

Access to home directory dotfiles

SourceSKILL.md
2523. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`)
2534. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"`
2545. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`"
255
256If B: say "OK, you're on your own to keep the vendored copy up to date."
low line 260

Access to home directory dotfiles

SourceSKILL.md
258Always run (regardless of choice):
259```bash
260eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
261touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}
262```
low line 261

Access to home directory dotfiles

SourceSKILL.md
259```bash
260eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
261touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}
262```
263
low line 284

Access to home directory dotfiles

SourceSKILL.md
282 _BRAIN_REMOTE_FILE="$HOME/.gstack-brain-remote.txt"
283fi
284_BRAIN_SYNC_BIN="~/.claude/skills/gstack/bin/gstack-brain-sync"
285_BRAIN_CONFIG_BIN="~/.claude/skills/gstack/bin/gstack-config"
286
low line 285

Access to home directory dotfiles

SourceSKILL.md
283fi
284_BRAIN_SYNC_BIN="~/.claude/skills/gstack/bin/gstack-brain-sync"
285_BRAIN_CONFIG_BIN="~/.claude/skills/gstack/bin/gstack-config"
286
287# /sync-gbrain context-load: teach the agent to use gbrain when it's available.
medium line 389

Access to home directory dotfiles

SourceSKILL.md
387```
388
389If A/B and `~/.gstack/.git` is missing, ask whether to run `gstack-artifacts-init`. Do not block the skill.
390
391At skill END before telemetry:
low line 394

Access to home directory dotfiles

SourceSKILL.md
392
393```bash
394"~/.claude/skills/gstack/bin/gstack-brain-sync" --discover-new 2>/dev/null || true
395"~/.claude/skills/gstack/bin/gstack-brain-sync" --once 2>/dev/null || true
396```
low line 395

Access to home directory dotfiles

SourceSKILL.md
393```bash
394"~/.claude/skills/gstack/bin/gstack-brain-sync" --discover-new 2>/dev/null || true
395"~/.claude/skills/gstack/bin/gstack-brain-sync" --once 2>/dev/null || true
396```
397
low line 440

Access to home directory dotfiles

SourceSKILL.md
438
439```bash
440~/.claude/skills/gstack/bin/gstack-learnings-log '{"skill":"SKILL_NAME","type":"operational","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"observed"}'
441```
442
medium line 450

Access to home directory dotfiles

SourceSKILL.md
448
449**PLAN MODE EXCEPTION — ALWAYS RUN:** This command writes telemetry to
450`~/.gstack/analytics/`, matching preamble analytics writes.
451
452Run this bash:
low line 457

Access to home directory dotfiles

SourceSKILL.md
455_TEL_END=$(date +%s)
456_TEL_DUR=$(( _TEL_END - _TEL_START ))
457rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
458# Session timeline: record skill completion (local-only, never sent anywhere)
459~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true
low line 459

Access to home directory dotfiles

SourceSKILL.md
457rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
458# Session timeline: record skill completion (local-only, never sent anywhere)
459~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true
460# Local analytics (gated on telemetry setting)
461if [ "$_TEL" != "off" ]; then
low line 462

Access to home directory dotfiles

SourceSKILL.md
460# Local analytics (gated on telemetry setting)
461if [ "$_TEL" != "off" ]; then
462echo '{"skill":"SKILL_NAME","duration_s":"'"$_TEL_DUR"'","outcome":"OUTCOME","browse":"USED_BROWSE","session":"'"$_SESSION_ID"'","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
463fi
464# Remote telemetry (opt-in, requires binary)
low line 465

Access to home directory dotfiles

SourceSKILL.md
463fi
464# Remote telemetry (opt-in, requires binary)
465if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then
466 ~/.claude/skills/gstack/bin/gstack-telemetry-log \
467 --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \
low line 466

Access to home directory dotfiles

SourceSKILL.md
464# Remote telemetry (opt-in, requires binary)
465if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then
466 ~/.claude/skills/gstack/bin/gstack-telemetry-log \
467 --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \
468 --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null &
medium line 476

Access to home directory dotfiles

SourceSKILL.md
474## Plan Status Footer
475
476In plan mode before ExitPlanMode: if the plan file lacks `## GSTACK REVIEW REPORT`, run `~/.claude/skills/gstack/bin/gstack-review-read` and append the standard runs/status/findings table. With `NO_REVIEWS` or empty, append a 5-row placeholder with verdict "NO REVIEWS YET — run `/autoplan`". If a richer report exists, skip.
477
478PLAN MODE EXCEPTION — always allowed (it's the plan file).
medium line 784

Access to home directory dotfiles

SourceSKILL.md
782
783The snapshot is your primary tool for understanding and interacting with pages.
784`$B` is the browse binary (resolved from `$_ROOT/.claude/skills/gstack/browse/dist/browse` or `~/.claude/skills/gstack/browse/dist/browse`).
785
786**Syntax:** `$B snapshot [flags]`
high line 110

Urgency-based manipulation

SourceSKILL.md
108## Skill Invocation During Plan Mode
109
110If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
111
112If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
Scanned on May 10, 2026
View Security Dashboard
Installation guide →