diff --git a/SKILL.md b/SKILL.md index e12be621..942c714e 100644 --- a/SKILL.md +++ b/SKILL.md @@ -7,6 +7,32 @@ description: | responsive layouts, test forms and uploads, handle dialogs, and assert element states. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. + + gstack also includes development workflow skills. When you notice the user is at + these stages, suggest the appropriate skill: + - Brainstorming a new idea → suggest /office-hours + - Reviewing a plan (strategy) → suggest /plan-ceo-review + - Reviewing a plan (architecture) → suggest /plan-eng-review + - Reviewing a plan (design) → suggest /plan-design-review + - Creating a design system → suggest /design-consultation + - Debugging errors → suggest /debug + - Testing the app → suggest /qa + - Code review before merge → suggest /review + - Visual design audit → suggest /design-review + - Ready to deploy / create PR → suggest /ship + - Post-ship doc updates → suggest /document-release + - Weekly retrospective → suggest /retro + + If the user pushes back on skill suggestions ("stop suggesting things", + "I don't need suggestions", "too aggressive"): + 1. Stop suggesting for the rest of this session + 2. Run: gstack-config set proactive false + 3. Say: "Got it — I'll stop suggesting skills. Just tell me to be proactive + again if you change your mind." + + If the user says "be proactive again" or "turn on suggestions": + 1. Run: gstack-config set proactive true + 2. Say: "Proactive suggestions are back on." allowed-tools: - Bash - Read @@ -26,8 +52,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` @@ -145,6 +173,10 @@ ATTEMPTED: [what you tried] RECOMMENDATION: [what the user should do next] ``` +If `PROACTIVE` is `false`: do NOT proactively suggest other gstack skills during this session. +Only run skills the user explicitly invokes. This preference persists across sessions via +`gstack-config`. + # gstack browse: QA Testing & Dogfooding Persistent headless Chromium. First call auto-starts (~3s), then ~100-200ms per command. diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index dd2b2345..68f18ce9 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -7,6 +7,32 @@ description: | responsive layouts, test forms and uploads, handle dialogs, and assert element states. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. + + gstack also includes development workflow skills. When you notice the user is at + these stages, suggest the appropriate skill: + - Brainstorming a new idea → suggest /office-hours + - Reviewing a plan (strategy) → suggest /plan-ceo-review + - Reviewing a plan (architecture) → suggest /plan-eng-review + - Reviewing a plan (design) → suggest /plan-design-review + - Creating a design system → suggest /design-consultation + - Debugging errors → suggest /debug + - Testing the app → suggest /qa + - Code review before merge → suggest /review + - Visual design audit → suggest /design-review + - Ready to deploy / create PR → suggest /ship + - Post-ship doc updates → suggest /document-release + - Weekly retrospective → suggest /retro + + If the user pushes back on skill suggestions ("stop suggesting things", + "I don't need suggestions", "too aggressive"): + 1. Stop suggesting for the rest of this session + 2. Run: gstack-config set proactive false + 3. Say: "Got it — I'll stop suggesting skills. Just tell me to be proactive + again if you change your mind." + + If the user says "be proactive again" or "turn on suggestions": + 1. Run: gstack-config set proactive true + 2. Say: "Proactive suggestions are back on." allowed-tools: - Bash - Read @@ -16,6 +42,10 @@ allowed-tools: {{PREAMBLE}} +If `PROACTIVE` is `false`: do NOT proactively suggest other gstack skills during this session. +Only run skills the user explicitly invokes. This preference persists across sessions via +`gstack-config`. + # gstack browse: QA Testing & Dogfooding Persistent headless Chromium. First call auto-starts (~3s), then ~100-200ms per command. diff --git a/browse/SKILL.md b/browse/SKILL.md index bf695d3b..d9a7d76a 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -27,8 +27,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/debug/SKILL.md b/debug/SKILL.md index 4448453a..c75394d3 100644 --- a/debug/SKILL.md +++ b/debug/SKILL.md @@ -4,6 +4,8 @@ version: 1.0.0 description: | Systematic debugging with root cause investigation. Four phases: investigate, analyze, hypothesize, implement. Iron Law: no fixes without root cause. + Use when asked to "debug this", "fix this bug", "why is this broken", + "investigate this error", or "root cause analysis". allowed-tools: - Bash - Read @@ -26,8 +28,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/debug/SKILL.md.tmpl b/debug/SKILL.md.tmpl index 312d2420..c7b49fe3 100644 --- a/debug/SKILL.md.tmpl +++ b/debug/SKILL.md.tmpl @@ -4,6 +4,8 @@ version: 1.0.0 description: | Systematic debugging with root cause investigation. Four phases: investigate, analyze, hypothesize, implement. Iron Law: no fixes without root cause. + Use when asked to "debug this", "fix this bug", "why is this broken", + "investigate this error", or "root cause analysis". allowed-tools: - Bash - Read diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index c5c5bc29..ea3f8724 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -30,8 +30,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 473e419b..27c4da0e 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -30,8 +30,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/document-release/SKILL.md b/document-release/SKILL.md index 88af49fb..2dd4343f 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -28,8 +28,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index fec01e26..a7e5dc4e 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -6,6 +6,8 @@ description: | demand reality, status quo, desperate specificity, narrowest wedge, observation, and future-fit. Builder mode: design thinking brainstorming for side projects, hackathons, learning, and open source. Saves a design doc. + Use when asked to "brainstorm this", "I have an idea", "help me think through + this", "office hours", or "is this worth building". Use before /plan-ceo-review or /plan-eng-review. allowed-tools: - Bash @@ -29,8 +31,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/office-hours/SKILL.md.tmpl b/office-hours/SKILL.md.tmpl index 4eec04b6..825855db 100644 --- a/office-hours/SKILL.md.tmpl +++ b/office-hours/SKILL.md.tmpl @@ -6,6 +6,8 @@ description: | demand reality, status quo, desperate specificity, narrowest wedge, observation, and future-fit. Builder mode: design thinking brainstorming for side projects, hackathons, learning, and open source. Saves a design doc. + Use when asked to "brainstorm this", "I have an idea", "help me think through + this", "office hours", or "is this worth building". Use before /plan-ceo-review or /plan-eng-review. allowed-tools: - Bash diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index cc56b66d..0bec262e 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -28,8 +28,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index fce76143..0657b01a 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -28,8 +28,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index a5684dd7..24d725ac 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -25,8 +25,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/qa/SKILL.md b/qa/SKILL.md index 2d12fca8..30e17cb5 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -31,8 +31,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/retro/SKILL.md b/retro/SKILL.md index bb6bcbe9..83dc47d6 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -26,8 +26,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 325b4d13..1b723505 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -105,8 +105,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" \`\`\` diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 3ae00a6b..138f8cc9 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -24,8 +24,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/ship/SKILL.md b/ship/SKILL.md index 1315be7d..ebea1e7c 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -26,8 +26,10 @@ touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true _CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") echo "LAKE_INTRO: $_LAKE_SEEN" ``` diff --git a/test/skill-validation.test.ts b/test/skill-validation.test.ts index 118158d6..3605c2ae 100644 --- a/test/skill-validation.test.ts +++ b/test/skill-validation.test.ts @@ -1213,3 +1213,29 @@ describe('Codex skill', () => { expect(content).toContain('codex-review'); }); }); + +// --- Trigger phrase validation --- +// Ensures all user-facing skills have "Use when" trigger phrases in their description +// frontmatter, so Claude Code's skill selector can route natural language to the right skill. + +describe('Skill trigger phrases', () => { + const SKILLS_REQUIRING_TRIGGERS = [ + 'qa', 'qa-only', 'ship', 'review', 'debug', 'office-hours', + 'plan-ceo-review', 'plan-eng-review', 'plan-design-review', + 'design-review', 'design-consultation', 'retro', 'document-release', + 'codex', 'browse', 'setup-browser-cookies', + ]; + + for (const skill of SKILLS_REQUIRING_TRIGGERS) { + test(`${skill}/SKILL.md has "Use when" trigger phrases`, () => { + const skillPath = path.join(ROOT, skill, 'SKILL.md'); + if (!fs.existsSync(skillPath)) return; + const content = fs.readFileSync(skillPath, 'utf-8'); + // Extract frontmatter (between --- markers) + const match = content.match(/^---\n([\s\S]*?)\n---/); + expect(match).toBeTruthy(); + const frontmatter = match![1]; + expect(frontmatter.toLowerCase()).toContain('use when'); + }); + } +});