feat: proactive skill suggestions + opt-out + trigger phrase tests

- Preamble reads proactive config via gstack-config
- Root SKILL.md.tmpl has lifecycle map (stage → skill suggestion)
- Users can opt out ("stop suggesting") / opt in ("be proactive again")
- Restored trigger phrase validation tests (16 skills × "Use when" check)
- Added missing "Use when" trigger phrases to /debug and /office-hours

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-18 22:16:07 -07:00
parent 34e40475a8
commit 7d89a16b6d
19 changed files with 124 additions and 0 deletions
+26
View File
@@ -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');
});
}
});