get-shit-pretty 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -12
- package/bin/install.js +102 -71
- package/gsp/agents/gsp-accessibility-auditor.md +3 -3
- package/gsp/agents/gsp-ascii-artist.md +1 -1
- package/gsp/agents/gsp-brand-auditor.md +2 -2
- package/gsp/agents/gsp-brand-engineer.md +131 -0
- package/gsp/agents/gsp-brand-strategist.md +2 -2
- package/gsp/agents/gsp-brand-syncer.md +8 -7
- package/gsp/agents/gsp-builder.md +48 -5
- package/gsp/agents/gsp-campaign-director.md +2 -3
- package/gsp/agents/gsp-creative-director.md +80 -0
- package/gsp/agents/gsp-critic.md +99 -17
- package/gsp/agents/gsp-designer.md +51 -4
- package/gsp/agents/gsp-project-researcher.md +3 -3
- package/gsp/agents/gsp-researcher.md +4 -4
- package/gsp/agents/gsp-reviewer.md +2 -2
- package/gsp/agents/gsp-scoper.md +2 -2
- package/gsp/hooks/hooks.json +55 -1
- package/gsp/references/design-trends.md +4 -4
- package/gsp/references/phase-transitions.md +12 -12
- package/gsp/references/questioning.md +1 -1
- package/gsp/references/token-mapping.md +329 -0
- package/gsp/skills/get-shit-pretty/SKILL.md +2 -0
- package/gsp/skills/gsp-3d/SKILL.md +112 -0
- package/gsp/skills/gsp-accessibility/SKILL.md +12 -11
- package/gsp/skills/gsp-accessibility-audit/SKILL.md +8 -7
- package/gsp/skills/gsp-add-reference/SKILL.md +2 -1
- package/gsp/skills/gsp-art/SKILL.md +2 -1
- package/gsp/skills/gsp-brand-audit/SKILL.md +5 -3
- package/gsp/skills/gsp-brand-guidelines/SKILL.md +233 -0
- package/gsp/skills/gsp-brand-identity/SKILL.md +35 -24
- package/gsp/skills/gsp-brand-refine/SKILL.md +30 -22
- package/gsp/skills/gsp-brand-research/SKILL.md +4 -2
- package/gsp/skills/gsp-brand-strategy/SKILL.md +5 -3
- package/gsp/skills/gsp-brand-sync/SKILL.md +9 -7
- package/gsp/skills/gsp-color/SKILL.md +105 -0
- package/gsp/skills/gsp-design-system/SKILL.md +5 -4
- package/gsp/skills/gsp-doctor/SKILL.md +26 -18
- package/gsp/skills/gsp-help/SKILL.md +29 -28
- package/gsp/skills/gsp-icons/SKILL.md +108 -0
- package/gsp/skills/gsp-images/SKILL.md +197 -0
- package/gsp/skills/gsp-launch/SKILL.md +12 -4
- package/gsp/skills/gsp-logo/SKILL.md +173 -0
- package/gsp/skills/gsp-palette/SKILL.md +14 -13
- package/gsp/skills/gsp-pretty/SKILL.md +3 -2
- package/gsp/skills/gsp-progress/SKILL.md +21 -20
- package/gsp/skills/gsp-project-brief/SKILL.md +15 -15
- package/gsp/skills/gsp-project-build/SKILL.md +31 -21
- package/gsp/skills/gsp-project-critique/SKILL.md +39 -16
- package/gsp/skills/gsp-project-design/SKILL.md +39 -16
- package/gsp/skills/gsp-project-research/SKILL.md +15 -14
- package/gsp/skills/gsp-project-review/SKILL.md +10 -9
- package/gsp/skills/gsp-scaffold/SKILL.md +4 -3
- package/gsp/skills/gsp-start/SKILL.md +26 -34
- package/gsp/skills/gsp-style/SKILL.md +42 -43
- package/gsp/skills/gsp-style/styles/INDEX.yml +1 -1
- package/gsp/skills/gsp-style/styles/academia.yml +80 -0
- package/gsp/skills/gsp-style/styles/art-deco.yml +81 -0
- package/gsp/skills/gsp-style/styles/bauhaus.yml +78 -0
- package/gsp/skills/gsp-style/styles/bold-typography.yml +73 -0
- package/gsp/skills/gsp-style/styles/botanical.yml +78 -0
- package/gsp/skills/gsp-style/styles/claymorphism.yml +84 -0
- package/gsp/skills/gsp-style/styles/cyberpunk.yml +87 -0
- package/gsp/skills/gsp-style/styles/enterprise.yml +81 -0
- package/gsp/skills/gsp-style/styles/flat-design.yml +67 -0
- package/gsp/skills/gsp-style/styles/fluent.yml +82 -0
- package/gsp/skills/gsp-style/styles/glassmorphism.yml +83 -0
- package/gsp/skills/gsp-style/styles/humanist-literary.yml +74 -0
- package/gsp/skills/gsp-style/styles/industrial.yml +82 -0
- package/gsp/skills/gsp-style/styles/kinetic.yml +94 -0
- package/gsp/skills/gsp-style/styles/liquid-glass.yml +91 -0
- package/gsp/skills/gsp-style/styles/luxury.yml +83 -0
- package/gsp/skills/gsp-style/styles/material.yml +83 -0
- package/gsp/skills/gsp-style/styles/maximalism.yml +92 -0
- package/gsp/skills/gsp-style/styles/minimal-dark.yml +75 -0
- package/gsp/skills/gsp-style/styles/modern-dark.yml +88 -0
- package/gsp/skills/gsp-style/styles/monochrome.yml +68 -0
- package/gsp/skills/gsp-style/styles/neubrutalism.yml +83 -0
- package/gsp/skills/gsp-style/styles/neumorphism.yml +77 -0
- package/gsp/skills/gsp-style/styles/newsprint.yml +81 -0
- package/gsp/skills/gsp-style/styles/organic.yml +77 -0
- package/gsp/skills/gsp-style/styles/playful-geometric.yml +90 -0
- package/gsp/skills/gsp-style/styles/professional.yml +67 -0
- package/gsp/skills/gsp-style/styles/retro.yml +85 -0
- package/gsp/skills/gsp-style/styles/saas.yml +83 -0
- package/gsp/skills/gsp-style/styles/sketch.yml +86 -0
- package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +69 -0
- package/gsp/skills/gsp-style/styles/terminal.yml +83 -0
- package/gsp/skills/gsp-style/styles/vaporwave.yml +84 -0
- package/gsp/skills/gsp-style/styles/web3.yml +82 -0
- package/gsp/skills/gsp-textures/SKILL.md +132 -0
- package/gsp/skills/gsp-typescale/SKILL.md +12 -11
- package/gsp/skills/gsp-typography/SKILL.md +108 -0
- package/gsp/skills/gsp-update/SKILL.md +2 -2
- package/gsp/skills/gsp-video/SKILL.md +101 -0
- package/gsp/templates/branding/config.json +1 -1
- package/gsp/templates/branding/roadmap.md +9 -9
- package/gsp/templates/exports-index.md +8 -8
- package/gsp/templates/phases/build.md +1 -1
- package/gsp/templates/phases/design.md +1 -1
- package/gsp/templates/phases/identity.md +2 -6
- package/gsp/templates/phases/patterns.md +60 -71
- package/gsp/templates/phases/style.md +158 -0
- package/gsp/templates/projects/config.json +1 -1
- package/gsp/templates/projects/roadmap.md +7 -7
- package/gsp/templates/projects/state.md +1 -1
- package/package.json +12 -15
- package/.claude-plugin/plugin.json +0 -24
- package/gsp/agents/gsp-identity-designer.md +0 -77
- package/gsp/agents/gsp-pattern-architect.md +0 -189
- package/gsp/prompts/01-design-system-architect.md +0 -19
- package/gsp/prompts/02-brand-identity-creator.md +0 -16
- package/gsp/prompts/03-ui-ux-pattern-master.md +0 -21
- package/gsp/prompts/04-marketing-asset-factory.md +0 -14
- package/gsp/prompts/05-implementation-spec-expert.md +0 -15
- package/gsp/prompts/06-design-critique-partner.md +0 -14
- package/gsp/prompts/07-design-trend-synthesizer.md +0 -3
- package/gsp/prompts/08-accessibility-auditor.md +0 -23
- package/gsp/prompts/09-design-to-code-translator.md +0 -49
- package/gsp/prompts/10-project-scoper.md +0 -17
- package/gsp/prompts/11-deliverable-reviewer.md +0 -18
- package/gsp/prompts/12-project-researcher.md +0 -18
- package/gsp/skills/gsp-brand-patterns/SKILL.md +0 -238
package/README.md
CHANGED
|
@@ -183,6 +183,7 @@ Create marketing campaign assets — landing page copy, social media content, la
|
|
|
183
183
|
| `/gsp:brand-strategy` | Define archetype, positioning, personality, voice, messaging |
|
|
184
184
|
| `/gsp:brand-identity` | Create visual identity — logo, color, type |
|
|
185
185
|
| `/gsp:brand-patterns` | Build design system — tokens, components |
|
|
186
|
+
| `/gsp:brand-refine` | Surgical token and palette adjustments mid-project |
|
|
186
187
|
|
|
187
188
|
### Project
|
|
188
189
|
|
|
@@ -200,6 +201,7 @@ Create marketing campaign assets — landing page copy, social media content, la
|
|
|
200
201
|
|
|
201
202
|
| Command | What it does |
|
|
202
203
|
|---------|--------------|
|
|
204
|
+
| `/gsp:accessibility-audit` | Full WCAG 2.2 AA accessibility audit |
|
|
203
205
|
| `/gsp:add-reference` | Add reference material to a project |
|
|
204
206
|
| `/gsp:doctor` | Check project health |
|
|
205
207
|
| `/gsp:update` | Update GSP to latest version |
|
|
@@ -256,7 +258,7 @@ GSP works across all major AI coding tools. The installer converts Claude Code's
|
|
|
256
258
|
| Gemini CLI | `~/.gemini/` | `~/.gemini/skills/` | `~/.gemini/agents/` |
|
|
257
259
|
| Codex CLI | `~/.codex/` | `~/.agents/skills/` | — |
|
|
258
260
|
|
|
259
|
-
> **Codex note:** Skills are discovered at `~/.agents/skills/`, not `~/.codex/skills/`. Config and bundle files (
|
|
261
|
+
> **Codex note:** Skills are discovered at `~/.agents/skills/`, not `~/.codex/skills/`. Config and bundle files (templates, references) stay at `~/.codex/get-shit-pretty/`. Codex does not support agent `.md` files.
|
|
260
262
|
|
|
261
263
|
---
|
|
262
264
|
|
|
@@ -306,14 +308,14 @@ npx get-shit-pretty --codex --global --uninstall
|
|
|
306
308
|
</details>
|
|
307
309
|
|
|
308
310
|
<details>
|
|
309
|
-
<summary><strong>
|
|
311
|
+
<summary><strong>Local development</strong></summary>
|
|
310
312
|
|
|
311
313
|
```bash
|
|
312
|
-
# From
|
|
313
|
-
claude --
|
|
314
|
+
# From the repo root:
|
|
315
|
+
node bin/install.js --claude --local
|
|
314
316
|
```
|
|
315
317
|
|
|
316
|
-
|
|
318
|
+
Symlinks skills and agents to `.claude/` — edits to `gsp/` are reflected immediately.
|
|
317
319
|
|
|
318
320
|
</details>
|
|
319
321
|
|
|
@@ -323,15 +325,13 @@ Uses the `.claude-plugin/plugin.json` manifest. Skills, agents, and hooks load d
|
|
|
323
325
|
|
|
324
326
|
```
|
|
325
327
|
get-shit-pretty/
|
|
326
|
-
├── .claude-plugin/ Plugin manifest (plugin.json)
|
|
327
328
|
├── bin/
|
|
328
329
|
│ └── install.js Multi-runtime installer
|
|
329
330
|
├── scripts/ Hook scripts and utilities
|
|
330
331
|
├── gsp/ Source of truth for all content
|
|
331
332
|
│ ├── agents/ 15 subagents (gsp-*.md)
|
|
332
|
-
│ ├── skills/
|
|
333
|
-
│ ├── hooks/
|
|
334
|
-
│ ├── prompts/ 12 agent system prompts
|
|
333
|
+
│ ├── skills/ 38 skills (*/SKILL.md)
|
|
334
|
+
│ ├── hooks/ Hooks (hooks.json)
|
|
335
335
|
│ ├── templates/ Config, state, brief, roadmap templates
|
|
336
336
|
│ └── references/ Shared reference material
|
|
337
337
|
├── dev/ Internal dev tools (not installed)
|
|
@@ -354,9 +354,6 @@ Edit source under `gsp/` — never edit inside `.claude/` or other runtime dirs
|
|
|
354
354
|
# Install locally with symlinks
|
|
355
355
|
node bin/install.js --claude --local
|
|
356
356
|
|
|
357
|
-
# Test as a plugin
|
|
358
|
-
claude --plugin-dir .
|
|
359
|
-
|
|
360
357
|
# Run the integrity test suite
|
|
361
358
|
bash dev/scripts/audit-tests.sh
|
|
362
359
|
```
|
package/bin/install.js
CHANGED
|
@@ -167,7 +167,7 @@ function center(text, width) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
const columns = process.stdout.columns || 80;
|
|
170
|
-
const rampText = `${c.accent}░▒▓█${c.reset} ${c.bold} GET SHIT PRETTY ${c.reset} ${c.accent}█▓▒░${c.reset}`;
|
|
170
|
+
const rampText = `${c.accent}░▒▓█${c.reset} ${c.bold} GET SHIT PRETTY ${c.reset} ${c.dim}v${pkg.version}${c.reset} ${c.accent}█▓▒░${c.reset}`;
|
|
171
171
|
const boxWidth = 48;
|
|
172
172
|
const innerWidth = boxWidth - 2; // inside the border chars
|
|
173
173
|
const showSparkles = columns >= 44;
|
|
@@ -197,7 +197,7 @@ const banner = '\n' +
|
|
|
197
197
|
(showSparkles ? sparkle('dense') + '\n' : '') +
|
|
198
198
|
bottomBorder + '\n' +
|
|
199
199
|
'\n' +
|
|
200
|
-
` ${c.bold}${c.accent}/gsp
|
|
200
|
+
` ${c.bold}${c.accent}/gsp${c.reset} ${c.tertiary}◇◇${c.reset}\n` +
|
|
201
201
|
` ${c.dim}${tagline}${c.reset}\n`;
|
|
202
202
|
|
|
203
203
|
console.log(banner);
|
|
@@ -395,7 +395,7 @@ function applyOpencodeBodyReplacements(content) {
|
|
|
395
395
|
converted = converted.replace(/\bSlashCommand\b/g, 'skill');
|
|
396
396
|
converted = converted.replace(/\bSkill\b(?=\s+tool\b)/g, 'skill');
|
|
397
397
|
converted = converted.replace(/\bTodoWrite\b/g, 'todowrite');
|
|
398
|
-
converted = converted.replace(/\/gsp:/g, '/gsp-');
|
|
398
|
+
converted = converted.replace(/\/gsp:/g, '/gsp-'); // legacy: source may still have /gsp: in older versions
|
|
399
399
|
converted = converted.replace(/~\/\.claude\b/g, '~/.config/opencode');
|
|
400
400
|
converted = converted.replace(/subagent_type="general-purpose"/g, 'subagent_type="general"');
|
|
401
401
|
// Convert Claude agent spawning to OpenCode subagent delegation
|
|
@@ -605,6 +605,8 @@ function convertClaudeSkillToOpencode(content, skillName) {
|
|
|
605
605
|
if (trimmed.startsWith('color:')) { inList = false; continue; }
|
|
606
606
|
if (trimmed.startsWith('context:')) { inList = false; continue; }
|
|
607
607
|
if (trimmed.startsWith('agent:')) { inList = false; continue; }
|
|
608
|
+
if (trimmed.startsWith('model:')) { inList = false; continue; }
|
|
609
|
+
if (trimmed.startsWith('effort:')) { inList = false; continue; }
|
|
608
610
|
// Skip list items under dropped fields
|
|
609
611
|
if (inList) {
|
|
610
612
|
if (trimmed.startsWith('- ')) continue;
|
|
@@ -783,6 +785,8 @@ function convertClaudeSkillToGemini(content, skillName) {
|
|
|
783
785
|
if (trimmed.startsWith('color:')) { inList = false; continue; }
|
|
784
786
|
if (trimmed.startsWith('context:')) { inList = false; continue; }
|
|
785
787
|
if (trimmed.startsWith('agent:')) { inList = false; continue; }
|
|
788
|
+
if (trimmed.startsWith('model:')) { inList = false; continue; }
|
|
789
|
+
if (trimmed.startsWith('effort:')) { inList = false; continue; }
|
|
786
790
|
if (inList) {
|
|
787
791
|
if (trimmed.startsWith('- ')) continue;
|
|
788
792
|
else if (trimmed && !trimmed.startsWith('-')) inList = false;
|
|
@@ -802,7 +806,8 @@ function convertClaudeSkillToGemini(content, skillName) {
|
|
|
802
806
|
*/
|
|
803
807
|
function applyCodexBodyReplacements(content) {
|
|
804
808
|
let converted = content;
|
|
805
|
-
converted = converted.replace(/\/gsp:/g, '$gsp-');
|
|
809
|
+
converted = converted.replace(/\/gsp:/g, '$gsp-'); // legacy: source may still have /gsp: in older versions
|
|
810
|
+
converted = converted.replace(/\/gsp-/g, '$gsp-');
|
|
806
811
|
converted = converted.replace(/~\/\.claude\b/g, '~/.codex');
|
|
807
812
|
converted = converted.replace(/\bAskUserQuestion\b/g, 'ask the user');
|
|
808
813
|
converted = converted.replace(/\bSlashCommand\b/g, 'skill');
|
|
@@ -858,6 +863,8 @@ function convertClaudeSkillToCodex(content, skillName) {
|
|
|
858
863
|
if (trimmed.startsWith('color:')) { inList = false; continue; }
|
|
859
864
|
if (trimmed.startsWith('context:')) { inList = false; continue; }
|
|
860
865
|
if (trimmed.startsWith('agent:')) { inList = false; continue; }
|
|
866
|
+
if (trimmed.startsWith('model:')) { inList = false; continue; }
|
|
867
|
+
if (trimmed.startsWith('effort:')) { inList = false; continue; }
|
|
861
868
|
if (inList) {
|
|
862
869
|
if (trimmed.startsWith('- ')) continue;
|
|
863
870
|
else if (trimmed && !trimmed.startsWith('-')) inList = false;
|
|
@@ -886,15 +893,7 @@ function convertClaudeSkillToCodex(content, skillName) {
|
|
|
886
893
|
function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
887
894
|
if (!fs.existsSync(srcDir)) return 0;
|
|
888
895
|
fs.mkdirSync(destDir, { recursive: true });
|
|
889
|
-
|
|
890
|
-
// Clean old gsp- skill dirs
|
|
891
|
-
if (fs.existsSync(destDir)) {
|
|
892
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
893
|
-
if (entry.isDirectory() && entry.name.startsWith('gsp-')) {
|
|
894
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
}
|
|
896
|
+
cleanStaleGspDirs(destDir);
|
|
898
897
|
|
|
899
898
|
let count = 0;
|
|
900
899
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -904,18 +903,15 @@ function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
|
904
903
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
905
904
|
if (!fs.existsSync(skillMd)) continue;
|
|
906
905
|
|
|
907
|
-
|
|
908
|
-
// Prefix with gsp- so they don't collide, unless already prefixed
|
|
909
|
-
const skillName = dir.name.startsWith('gsp-') ? dir.name : `gsp-${dir.name}`;
|
|
910
|
-
const skillDest = path.join(destDir, skillName);
|
|
906
|
+
const skillDest = path.join(destDir, dir.name);
|
|
911
907
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
912
908
|
|
|
913
909
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
914
910
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
915
911
|
content = content.replace(/\.\/\.claude\//g, './.opencode/');
|
|
916
|
-
content = convertClaudeSkillToOpencode(content,
|
|
912
|
+
content = convertClaudeSkillToOpencode(content, dir.name);
|
|
917
913
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
918
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
914
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
919
915
|
count++;
|
|
920
916
|
}
|
|
921
917
|
|
|
@@ -924,13 +920,14 @@ function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
|
924
920
|
|
|
925
921
|
/**
|
|
926
922
|
* Copy skills/ source to Codex skill structure.
|
|
927
|
-
* skills
|
|
923
|
+
* skills/gsp-<name>/SKILL.md → .agents/skills/gsp-<name>/SKILL.md
|
|
928
924
|
*
|
|
929
925
|
* Codex expects: .agents/skills/<name>/SKILL.md with YAML frontmatter (name + description).
|
|
930
926
|
*/
|
|
931
927
|
function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
932
928
|
if (!fs.existsSync(srcDir)) return 0;
|
|
933
929
|
fs.mkdirSync(destDir, { recursive: true });
|
|
930
|
+
cleanStaleGspDirs(destDir);
|
|
934
931
|
|
|
935
932
|
let count = 0;
|
|
936
933
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -939,15 +936,14 @@ function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
|
939
936
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
940
937
|
if (!fs.existsSync(skillMd)) continue;
|
|
941
938
|
|
|
942
|
-
const
|
|
943
|
-
const skillDest = path.join(destDir, skillName);
|
|
939
|
+
const skillDest = path.join(destDir, dir.name);
|
|
944
940
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
945
941
|
|
|
946
942
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
947
943
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
948
|
-
content = convertClaudeSkillToCodex(content,
|
|
944
|
+
content = convertClaudeSkillToCodex(content, dir.name);
|
|
949
945
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
950
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
946
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
951
947
|
count++;
|
|
952
948
|
}
|
|
953
949
|
return count;
|
|
@@ -955,22 +951,14 @@ function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
|
955
951
|
|
|
956
952
|
/**
|
|
957
953
|
* Copy skills/ source to Gemini skill structure.
|
|
958
|
-
* skills
|
|
954
|
+
* skills/gsp-<name>/SKILL.md → .gemini/skills/gsp-<name>/SKILL.md
|
|
959
955
|
*
|
|
960
956
|
* Gemini expects: .gemini/skills/<name>/SKILL.md with YAML frontmatter (name + description).
|
|
961
957
|
*/
|
|
962
958
|
function copyGeminiSkills(srcDir, destDir, pathPrefix) {
|
|
963
959
|
if (!fs.existsSync(srcDir)) return 0;
|
|
964
960
|
fs.mkdirSync(destDir, { recursive: true });
|
|
965
|
-
|
|
966
|
-
// Clean old gsp- skill dirs
|
|
967
|
-
if (fs.existsSync(destDir)) {
|
|
968
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
969
|
-
if (entry.isDirectory() && entry.name.startsWith('gsp-')) {
|
|
970
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
961
|
+
cleanStaleGspDirs(destDir);
|
|
974
962
|
|
|
975
963
|
let count = 0;
|
|
976
964
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -979,16 +967,15 @@ function copyGeminiSkills(srcDir, destDir, pathPrefix) {
|
|
|
979
967
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
980
968
|
if (!fs.existsSync(skillMd)) continue;
|
|
981
969
|
|
|
982
|
-
const
|
|
983
|
-
const skillDest = path.join(destDir, skillName);
|
|
970
|
+
const skillDest = path.join(destDir, dir.name);
|
|
984
971
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
985
972
|
|
|
986
973
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
987
974
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
988
975
|
content = content.replace(/\.\/\.claude\//g, './.gemini/');
|
|
989
|
-
content = convertClaudeSkillToGemini(content,
|
|
976
|
+
content = convertClaudeSkillToGemini(content, dir.name);
|
|
990
977
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
991
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
978
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
992
979
|
count++;
|
|
993
980
|
}
|
|
994
981
|
return count;
|
|
@@ -1030,49 +1017,64 @@ function copyAgents(srcDir, destDir, pathPrefix, runtime, { clean = false } = {}
|
|
|
1030
1017
|
}
|
|
1031
1018
|
|
|
1032
1019
|
/**
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1020
|
+
* Remove stale GSP skill dirs/symlinks (gsp-* and get-shit-pretty) from a target directory.
|
|
1021
|
+
* Handles broken symlinks via lstat fallback.
|
|
1035
1022
|
*/
|
|
1023
|
+
function cleanStaleGspDirs(dir) {
|
|
1024
|
+
let count = 0;
|
|
1025
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
1026
|
+
const name = entry.name;
|
|
1027
|
+
if (!name.startsWith('gsp-') && name !== 'get-shit-pretty') continue;
|
|
1028
|
+
const entryPath = path.join(dir, name);
|
|
1029
|
+
try {
|
|
1030
|
+
// withFileTypes doesn't resolve broken symlinks — use lstat for those
|
|
1031
|
+
if (entry.isSymbolicLink()) { fs.unlinkSync(entryPath); count++; }
|
|
1032
|
+
else if (entry.isDirectory()) { fs.rmSync(entryPath, { recursive: true }); count++; }
|
|
1033
|
+
else {
|
|
1034
|
+
// broken symlink: withFileTypes returns isFile=false, isDir=false, isSymlink=false
|
|
1035
|
+
const s = fs.lstatSync(entryPath);
|
|
1036
|
+
if (s.isSymbolicLink()) { fs.unlinkSync(entryPath); count++; }
|
|
1037
|
+
}
|
|
1038
|
+
} catch {}
|
|
1039
|
+
}
|
|
1040
|
+
return count;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1036
1043
|
/**
|
|
1037
1044
|
* Recursively copy sibling files in a skill directory (everything except SKILL.md).
|
|
1038
|
-
* All sibling files are copied verbatim — no path replacement applied.
|
|
1039
1045
|
*/
|
|
1040
|
-
function copySiblingFiles(srcDir, destDir
|
|
1046
|
+
function copySiblingFiles(srcDir, destDir) {
|
|
1041
1047
|
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
1042
|
-
if (entry.name === 'SKILL.md') continue;
|
|
1048
|
+
if (entry.name === 'SKILL.md') continue;
|
|
1043
1049
|
const srcPath = path.join(srcDir, entry.name);
|
|
1044
1050
|
const destPath = path.join(destDir, entry.name);
|
|
1045
1051
|
if (entry.isDirectory()) {
|
|
1046
1052
|
fs.mkdirSync(destPath, { recursive: true });
|
|
1047
|
-
copySiblingFiles(srcPath, destPath
|
|
1053
|
+
copySiblingFiles(srcPath, destPath);
|
|
1048
1054
|
} else {
|
|
1049
1055
|
fs.copyFileSync(srcPath, destPath);
|
|
1050
1056
|
}
|
|
1051
1057
|
}
|
|
1052
1058
|
}
|
|
1053
1059
|
|
|
1060
|
+
/**
|
|
1061
|
+
* Copy Claude Code skills (global install — no body conversion, only path replacement).
|
|
1062
|
+
*/
|
|
1054
1063
|
function copyClaudeSkills(srcDir, destDir, pathPrefix) {
|
|
1055
1064
|
fs.mkdirSync(destDir, { recursive: true });
|
|
1056
|
-
|
|
1057
|
-
// Clean old gsp- skill dirs
|
|
1058
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
1059
|
-
if (entry.isDirectory() && (entry.name.startsWith('gsp-') || entry.name === 'get-shit-pretty')) {
|
|
1060
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1065
|
+
cleanStaleGspDirs(destDir);
|
|
1063
1066
|
|
|
1064
1067
|
let skillCount = 0;
|
|
1065
1068
|
for (const dir of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
1066
1069
|
if (!dir.isDirectory()) continue;
|
|
1067
1070
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
1068
1071
|
if (!fs.existsSync(skillMd)) continue;
|
|
1069
|
-
const
|
|
1070
|
-
const destSkillDir = path.join(destDir, skillName);
|
|
1072
|
+
const destSkillDir = path.join(destDir, dir.name);
|
|
1071
1073
|
fs.mkdirSync(destSkillDir, { recursive: true });
|
|
1072
1074
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
1073
1075
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
1074
1076
|
fs.writeFileSync(path.join(destSkillDir, 'SKILL.md'), content);
|
|
1075
|
-
copySiblingFiles(path.join(srcDir, dir.name), destSkillDir
|
|
1077
|
+
copySiblingFiles(path.join(srcDir, dir.name), destSkillDir);
|
|
1076
1078
|
skillCount++;
|
|
1077
1079
|
}
|
|
1078
1080
|
return skillCount;
|
|
@@ -1195,14 +1197,8 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1195
1197
|
const skillsDest = path.join(targetDir, 'skills');
|
|
1196
1198
|
fs.mkdirSync(skillsDest, { recursive: true });
|
|
1197
1199
|
|
|
1198
|
-
// Clean old GSP skill dirs
|
|
1199
|
-
for (const entry of fs.readdirSync(skillsDest, { withFileTypes: true })) {
|
|
1200
|
-
if (entry.isDirectory() && (entry.name.startsWith('gsp-') || entry.name === 'get-shit-pretty')) {
|
|
1201
|
-
fs.rmSync(path.join(skillsDest, entry.name), { recursive: true });
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
1200
|
const skillsSrc = path.join(gspRoot, 'skills');
|
|
1201
|
+
cleanStaleGspDirs(skillsDest);
|
|
1206
1202
|
let skillCount = 0;
|
|
1207
1203
|
for (const dir of fs.readdirSync(skillsSrc, { withFileTypes: true })) {
|
|
1208
1204
|
if (!dir.isDirectory()) continue;
|
|
@@ -1221,15 +1217,20 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1221
1217
|
console.log(` ${c.success}✓${c.reset} Removed legacy commands/gsp`);
|
|
1222
1218
|
} catch {}
|
|
1223
1219
|
|
|
1224
|
-
// ── Bundle symlinks (
|
|
1225
|
-
// Clean up legacy
|
|
1220
|
+
// ── Bundle symlinks (templates, references → runtime root) ──
|
|
1221
|
+
// Clean up legacy dirs
|
|
1226
1222
|
const legacyBundleDest = path.join(targetDir, 'get-shit-pretty');
|
|
1227
1223
|
if (fs.existsSync(legacyBundleDest)) {
|
|
1228
1224
|
fs.rmSync(legacyBundleDest, { recursive: true });
|
|
1229
1225
|
console.log(` ${c.success}✓${c.reset} Removed legacy get-shit-pretty/ bundle`);
|
|
1230
1226
|
}
|
|
1227
|
+
const legacyPrompts = path.join(targetDir, 'prompts');
|
|
1228
|
+
if (fs.existsSync(legacyPrompts)) {
|
|
1229
|
+
fs.rmSync(legacyPrompts, { recursive: true });
|
|
1230
|
+
console.log(` ${c.success}✓${c.reset} Removed legacy prompts/`);
|
|
1231
|
+
}
|
|
1231
1232
|
|
|
1232
|
-
for (const dir of ['
|
|
1233
|
+
for (const dir of ['templates', 'references']) {
|
|
1233
1234
|
if (fs.existsSync(path.join(gspRoot, dir))) {
|
|
1234
1235
|
forceSymlink(path.join('..', 'gsp', dir), path.join(targetDir, dir));
|
|
1235
1236
|
console.log(` ${c.success}✓${c.reset} Symlinked ${dir}/`);
|
|
@@ -1261,6 +1262,16 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1261
1262
|
process.exit(1);
|
|
1262
1263
|
}
|
|
1263
1264
|
|
|
1265
|
+
// Warn if GSP skills also exist globally (may cause duplicates)
|
|
1266
|
+
const globalSkillsDir = path.join(getGlobalDir('claude', null), 'skills');
|
|
1267
|
+
if (fs.existsSync(globalSkillsDir)) {
|
|
1268
|
+
const dupes = fs.readdirSync(globalSkillsDir).filter(e => e.startsWith('gsp-'));
|
|
1269
|
+
if (dupes.length > 0) {
|
|
1270
|
+
console.log(` ${yellow}!${reset} Found ${dupes.length} GSP skills in ${globalSkillsDir.replace(os.homedir(), '~')} — may cause duplicates`);
|
|
1271
|
+
console.log(` ${c.dim}To remove: node bin/install.js --claude --global --uninstall${c.reset}`);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1264
1275
|
return true;
|
|
1265
1276
|
}
|
|
1266
1277
|
|
|
@@ -1411,15 +1422,20 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1411
1422
|
}
|
|
1412
1423
|
}
|
|
1413
1424
|
|
|
1414
|
-
// ── Bundle:
|
|
1415
|
-
// Clean up legacy
|
|
1425
|
+
// ── Bundle: templates, references → runtime root ──
|
|
1426
|
+
// Clean up legacy dirs from previous installs
|
|
1416
1427
|
const legacyBundle = path.join(targetDir, 'get-shit-pretty');
|
|
1417
1428
|
if (fs.existsSync(legacyBundle)) {
|
|
1418
1429
|
fs.rmSync(legacyBundle, { recursive: true });
|
|
1419
1430
|
console.log(` ${c.success}✓${c.reset} Removed legacy get-shit-pretty/ bundle`);
|
|
1420
1431
|
}
|
|
1432
|
+
const legacyPromptsDir = path.join(targetDir, 'prompts');
|
|
1433
|
+
if (fs.existsSync(legacyPromptsDir)) {
|
|
1434
|
+
fs.rmSync(legacyPromptsDir, { recursive: true });
|
|
1435
|
+
console.log(` ${c.success}✓${c.reset} Removed legacy prompts/`);
|
|
1436
|
+
}
|
|
1421
1437
|
|
|
1422
|
-
const bundleDirs = ['
|
|
1438
|
+
const bundleDirs = ['templates', 'references'];
|
|
1423
1439
|
for (const dir of bundleDirs) {
|
|
1424
1440
|
const dirSrc = path.join(gspRoot, dir);
|
|
1425
1441
|
if (fs.existsSync(dirSrc)) {
|
|
@@ -1461,6 +1477,21 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1461
1477
|
process.exit(1);
|
|
1462
1478
|
}
|
|
1463
1479
|
|
|
1480
|
+
// Warn if GSP skills exist in the other location (may cause duplicates)
|
|
1481
|
+
if (runtime === 'claude') {
|
|
1482
|
+
const otherDir = isGlobal
|
|
1483
|
+
? path.join(process.cwd(), '.claude', 'skills')
|
|
1484
|
+
: path.join(getGlobalDir('claude', null), 'skills');
|
|
1485
|
+
if (fs.existsSync(otherDir)) {
|
|
1486
|
+
const dupes = fs.readdirSync(otherDir).filter(e => e.startsWith('gsp-'));
|
|
1487
|
+
if (dupes.length > 0) {
|
|
1488
|
+
const label = otherDir.replace(os.homedir(), '~');
|
|
1489
|
+
console.log(` ${yellow}!${reset} Found ${dupes.length} GSP skills in ${label} — may cause duplicates`);
|
|
1490
|
+
console.log(` ${c.dim}To remove: node bin/install.js --claude ${isGlobal ? '--local' : '--global'} --uninstall${c.reset}`);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1464
1495
|
// ── Settings (Claude Code & Gemini only) ──
|
|
1465
1496
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
1466
1497
|
const settings = readSettings(settingsPath);
|
|
@@ -1539,7 +1570,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1539
1570
|
}
|
|
1540
1571
|
}
|
|
1541
1572
|
} else {
|
|
1542
|
-
// All other runtimes: remove gsp- skill dirs
|
|
1573
|
+
// All other runtimes (including Claude): remove gsp- skill dirs
|
|
1543
1574
|
const skillsDir = path.join(targetDir, 'skills');
|
|
1544
1575
|
if (fs.existsSync(skillsDir)) {
|
|
1545
1576
|
let skillCount = 0;
|
|
@@ -1587,7 +1618,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1587
1618
|
}
|
|
1588
1619
|
|
|
1589
1620
|
// Remove flattened bundle dirs
|
|
1590
|
-
for (const dir of ['prompts', 'templates', 'references']) {
|
|
1621
|
+
for (const dir of ['prompts', 'templates', 'references']) { // prompts included for legacy cleanup
|
|
1591
1622
|
const bundlePath = path.join(targetDir, dir);
|
|
1592
1623
|
if (fs.existsSync(bundlePath)) {
|
|
1593
1624
|
fs.rmSync(bundlePath, { recursive: true });
|
|
@@ -1720,8 +1751,8 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
|
|
|
1720
1751
|
}
|
|
1721
1752
|
|
|
1722
1753
|
const runtimeLabel = getRuntimeLabel(runtime);
|
|
1723
|
-
const helpCmd =
|
|
1724
|
-
const newCmd =
|
|
1754
|
+
const helpCmd = isCodex ? '$gsp-help' : '/gsp-help';
|
|
1755
|
+
const newCmd = isCodex ? '$gsp-start' : '/gsp-start';
|
|
1725
1756
|
|
|
1726
1757
|
// Show onboarding once (not per-runtime)
|
|
1727
1758
|
if (!onboardingShown && !hasQuiet) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-accessibility-auditor
|
|
3
|
-
description: Audits designs and code for WCAG 2.2 AA/AAA compliance. Spawned by /gsp
|
|
3
|
+
description: Audits designs and code for WCAG 2.2 AA/AAA compliance. Spawned by /gsp-accessibility or /gsp-project-critique.
|
|
4
4
|
tools: Read, Write, Grep, Glob
|
|
5
5
|
disallowedTools: Edit, Bash
|
|
6
6
|
maxTurns: 40
|
|
@@ -10,7 +10,7 @@ color: cyan
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
<role>
|
|
13
|
-
You are a GSP accessibility auditor spawned by `/gsp
|
|
13
|
+
You are a GSP accessibility auditor spawned by `/gsp-accessibility` or `/gsp-project-critique`.
|
|
14
14
|
|
|
15
15
|
Act as Apple Accessibility Specialist. Your job is to audit designs or code against WCAG 2.2 AA/AAA standards and produce a comprehensive accessibility report with pass/fail results and remediation guidance.
|
|
16
16
|
|
|
@@ -39,7 +39,7 @@ Accessibility is a core quality requirement.
|
|
|
39
39
|
|
|
40
40
|
## Code Audit Mode
|
|
41
41
|
|
|
42
|
-
When spawned by `/gsp
|
|
42
|
+
When spawned by `/gsp-accessibility --code`, audit the actual codebase:
|
|
43
43
|
|
|
44
44
|
1. **Grep for missing ARIA** — interactive elements without `role`, `aria-label`, `aria-labelledby`, `aria-describedby`
|
|
45
45
|
2. **Alt text** — `<img>` tags without `alt`, icons without `aria-hidden` or labels
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-ascii-artist
|
|
3
|
-
description: Easter egg agent that creates ASCII art for the terminal. Spawned by /gsp
|
|
3
|
+
description: Easter egg agent that creates ASCII art for the terminal. Spawned by /gsp-art.
|
|
4
4
|
tools: Read, Bash
|
|
5
5
|
disallowedTools: Edit, Write, Grep, Glob
|
|
6
6
|
model: haiku
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-brand-auditor
|
|
3
|
-
description: Audits existing brand identities for evolution. Spawned by /gsp
|
|
3
|
+
description: Audits existing brand identities for evolution. Spawned by /gsp-brand-audit.
|
|
4
4
|
tools: Read, Write, Bash, Grep, Glob, WebSearch, WebFetch
|
|
5
5
|
disallowedTools: Edit
|
|
6
6
|
maxTurns: 40
|
|
@@ -9,7 +9,7 @@ color: magenta
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
<role>
|
|
12
|
-
You are a GSP brand auditor spawned by `/gsp
|
|
12
|
+
You are a GSP brand auditor spawned by `/gsp-brand-audit`.
|
|
13
13
|
|
|
14
14
|
Assess existing brand identities — coherence, market fit, equity, evolution opportunity. Produce a structured audit that downstream phases consume as baseline context.
|
|
15
15
|
</role>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsp-brand-engineer
|
|
3
|
+
description: Operationalizes brand identity for projects — assembles .yml, STYLE.md, token mapping, component specs, guidelines. Spawned by /gsp-brand-guidelines.
|
|
4
|
+
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
|
+
maxTurns: 60
|
|
6
|
+
permissionMode: acceptEdits
|
|
7
|
+
color: magenta
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<role>
|
|
11
|
+
You are a GSP brand engineer spawned by `/gsp-brand-guidelines`.
|
|
12
|
+
|
|
13
|
+
Act as a Design Systems Engineer. Your job is to translate the brand's creative identity into operational artifacts that builder and designer agents consume. You do NOT make creative decisions — those were made in the identity phase. You operationalize them.
|
|
14
|
+
|
|
15
|
+
The identity phase produced: logo directions, color system (with OKLCH palettes), typography (with math scale), imagery style. You read those and produce: the `.yml` preset, STYLE.md, component token mapping, and guidelines.
|
|
16
|
+
</role>
|
|
17
|
+
|
|
18
|
+
<inputs>
|
|
19
|
+
- Identity chunks: color-system.md, typography.md, logo-directions.md, imagery-style.md (all enriched by domain skills)
|
|
20
|
+
- Identity palettes.json (OKLCH scales)
|
|
21
|
+
- BRIEF.md
|
|
22
|
+
- Strategy chunks: voice-and-tone.md, archetype.md, positioning.md
|
|
23
|
+
- system_strategy and tech_stack from config.json
|
|
24
|
+
- `.design/system/STACK.md`, `COMPONENTS.md`, `TOKENS.md` (if exist)
|
|
25
|
+
- style_base from config.json + preset `.yml` (if set) — the starting scaffold
|
|
26
|
+
- style_base preset `.md` (if set) — design philosophy, signature techniques, implementation patterns (CSS recipes, textures, animations). Source content for STYLE.md's Philosophy, Bold Bets, and Implementation sections.
|
|
27
|
+
- Output path
|
|
28
|
+
</inputs>
|
|
29
|
+
|
|
30
|
+
<methodology>
|
|
31
|
+
## What you produce (operational, not creative)
|
|
32
|
+
|
|
33
|
+
1. **Assemble `{brand-name}.yml`** — the single source of truth. Take identity decisions and structure them into the preset format:
|
|
34
|
+
- `tokens:` — extract color hex values from color-system.md, font families from typography.md, spacing/shape/elevation from the style_base preset or sensible defaults
|
|
35
|
+
- `intensity:` — derive from brand archetype + strategy (e.g., a "rebel" archetype → higher variance; a "sage" → lower)
|
|
36
|
+
- `patterns:` — 7 component composition rules derived from the brand's aesthetic (how cards, buttons, inputs SHOULD look given these colors/type/constraints)
|
|
37
|
+
- `constraints:` — never/always rules that protect the brand (derived from identity anti-patterns + style_base constraints)
|
|
38
|
+
- `effects:` — interaction vocabulary coherent with the brand energy
|
|
39
|
+
- `dark_mode:` — from color-system.md dark mode mapping
|
|
40
|
+
|
|
41
|
+
2. **Render `STYLE.md`** — follows `templates/phases/style.md` format. Source each section:
|
|
42
|
+
- **Intensity** — from the assembled `.yml` `intensity:` block
|
|
43
|
+
- **Philosophy** — synthesize from brand strategy (archetype, positioning, voice) + preset `.md` companion's Design Philosophy section (if provided). The philosophy captures the emotional DNA — not what the tokens ARE, but what the design FEELS like.
|
|
44
|
+
- **Patterns** — from the assembled `.yml` `patterns:` block, rendered as tables per component
|
|
45
|
+
- **Constraints** — from the assembled `.yml` `constraints:` block, rendered as never/always bullet lists
|
|
46
|
+
- **Effects** — from the assembled `.yml` `effects:` block, rendered as interaction vocabulary + state tables
|
|
47
|
+
- **Bold Bets** — the 3-5 most distinctive visual techniques from the identity phase's boldest choices + preset `.md` companion's signature techniques. Each must be specific enough for a builder to implement.
|
|
48
|
+
- **Implementation** — extract from preset `.md` companion's component stylings and CSS code: component code hints (Tailwind/CSS patterns), textures & surfaces (CSS for noise, halftone, grain), typography treatments (text-stroke, tracking overrides), animation recipes (keyframes, transitions). Skip sections that don't apply to this brand.
|
|
49
|
+
|
|
50
|
+
3. **Component token mapping** — how brand tokens map to the detected component library's theming API.
|
|
51
|
+
|
|
52
|
+
4. **Component overrides + custom specs** — only for components that need treatment beyond tokens.
|
|
53
|
+
|
|
54
|
+
5. **`guidelines.html`** — self-contained visual brand guide. This is the primary artifact users see. Single HTML file with embedded CSS, no external dependencies. Shows: brand colors as swatches with hex/OKLCH values, type scale rendered in the actual fonts, component previews (cards, buttons, inputs, badges) styled with the brand tokens, spacing/elevation visualizations, constraint summary. Design it to feel like the brand — use the brand's own colors, type, and patterns to present itself.
|
|
55
|
+
|
|
56
|
+
## Inheritance from style_base
|
|
57
|
+
|
|
58
|
+
If `style_base` contains one preset, start from its values and customize. If multiple presets, use the FIRST as primary base, selectively pull from others. Last-wins for conflicts.
|
|
59
|
+
|
|
60
|
+
If a preset constraint conflicts with brand identity, remove it and document why as a `.yml` comment.
|
|
61
|
+
|
|
62
|
+
If no `style_base` was set, build the full `.yml` from scratch using identity outputs.
|
|
63
|
+
|
|
64
|
+
## System Strategy
|
|
65
|
+
|
|
66
|
+
Read `system_strategy` from brand config:
|
|
67
|
+
|
|
68
|
+
**GENERATE** — Full system from scratch. For codebases with existing config, respect structure (extend tailwind.config, not replace).
|
|
69
|
+
|
|
70
|
+
**EXTEND** — Evolve existing system: audit tokens against brand identity (keep what works, adjust what doesn't, fill gaps). Classify existing components: KEEP / RESTYLE / OVERRIDE / REPLACE. Output delta tokens. Preserve existing naming conventions.
|
|
71
|
+
|
|
72
|
+
**REFACTOR** — Redesign from ground up informed by existing: understand current system, design complete new system, produce migration mapping, flag breaking changes.
|
|
73
|
+
|
|
74
|
+
## Component Strategy
|
|
75
|
+
|
|
76
|
+
Leverage existing UI libraries — don't rewrite from scratch.
|
|
77
|
+
|
|
78
|
+
**Tier 1: Token mapping** (always) — `components/token-mapping.md`. Maps brand tokens to library's theming API. Copy-paste-ready. See `references/token-mapping.md` for the CSS generation spec.
|
|
79
|
+
|
|
80
|
+
**Tier 2: Override specs** (selective) — one file per component needing treatment beyond tokens. Why it's overridden, code hints.
|
|
81
|
+
|
|
82
|
+
**Tier 3: Custom component specs** (selective) — full specs only for brand-distinctive components with no library equivalent.
|
|
83
|
+
|
|
84
|
+
Tier 2 + 3 combined: 5-12 components max.
|
|
85
|
+
|
|
86
|
+
## Quality Standards
|
|
87
|
+
- Token mapping must target the actual library's theming API
|
|
88
|
+
- Every value in `.yml` must trace to an identity chunk
|
|
89
|
+
- STYLE.md must be renderable from `.yml` alone (no external dependencies)
|
|
90
|
+
- Component specs need: states, anatomy, usage rules, accessibility, code hints
|
|
91
|
+
</methodology>
|
|
92
|
+
|
|
93
|
+
<output>
|
|
94
|
+
Write operational artifacts to the brand's guidelines directory (path provided by the skill that spawned you):
|
|
95
|
+
|
|
96
|
+
### Core files
|
|
97
|
+
|
|
98
|
+
- **`{brand-name}.yml`** — Single source of truth. Full preset schema: tokens, intensity, patterns, constraints, effects, dark_mode.
|
|
99
|
+
- **`STYLE.md`** — Agent-readable contract rendered from `.yml` + philosophy + bold bets. Follows `templates/phases/style.md`.
|
|
100
|
+
- **`guidelines.html`** — Self-contained visual brand guide. Single HTML file with embedded CSS — no external deps. Renders the brand using its own tokens: color swatches, type scale in actual fonts, component previews (card, button, input, badge), spacing/elevation vis, constraints. This is what the user sees.
|
|
101
|
+
|
|
102
|
+
### Components
|
|
103
|
+
|
|
104
|
+
Write to `components/`:
|
|
105
|
+
|
|
106
|
+
1. **`token-mapping.md`** (always) — brand tokens → library theming API. Reference values from `{brand-name}.yml`.
|
|
107
|
+
2. **Override specs** (selective) — one per component needing more than tokens.
|
|
108
|
+
3. **Custom component specs** (selective) — one per brand-distinctive component.
|
|
109
|
+
|
|
110
|
+
### `INDEX.md`
|
|
111
|
+
|
|
112
|
+
```markdown
|
|
113
|
+
# Guidelines
|
|
114
|
+
> Phase: guidelines | Brand: {name} | Generated: {DATE}
|
|
115
|
+
|
|
116
|
+
## Core
|
|
117
|
+
|
|
118
|
+
| File | Description |
|
|
119
|
+
|------|-------------|
|
|
120
|
+
| [{brand-name}.yml](./{brand-name}.yml) | Style preset — single source of truth |
|
|
121
|
+
| [STYLE.md](./STYLE.md) | Agent contract (rendered from .yml) |
|
|
122
|
+
| [guidelines.html](./guidelines.html) | Visual brand guide (open in browser) |
|
|
123
|
+
|
|
124
|
+
## Components
|
|
125
|
+
|
|
126
|
+
| File | Type | Description |
|
|
127
|
+
|------|------|-------------|
|
|
128
|
+
| [token-mapping.md](./components/token-mapping.md) | mapping | Brand tokens → {library} theming API |
|
|
129
|
+
| ... | ... | ... |
|
|
130
|
+
```
|
|
131
|
+
</output>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-brand-strategist
|
|
3
|
-
description: Develops brand strategy, voice, and messaging. Spawned by /gsp
|
|
3
|
+
description: Develops brand strategy, voice, and messaging. Spawned by /gsp-brand-strategy.
|
|
4
4
|
tools: Read, Write, Bash, Grep, Glob, WebSearch, WebFetch
|
|
5
5
|
disallowedTools: Edit
|
|
6
6
|
maxTurns: 40
|
|
@@ -9,7 +9,7 @@ color: magenta
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
<role>
|
|
12
|
-
You are a GSP brand strategist spawned by `/gsp
|
|
12
|
+
You are a GSP brand strategist spawned by `/gsp-brand-strategy`.
|
|
13
13
|
|
|
14
14
|
Act as Head of Strategy at a top branding agency. Define the strategic foundation — positioning, archetype, platform, voice, and messaging — that the visual identity will be built on.
|
|
15
15
|
|