get-shit-pretty 0.6.2 → 0.7.0
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 +7 -12
- package/bin/install.js +125 -84
- package/gsp/agents/gsp-accessibility-auditor.md +4 -4
- package/gsp/agents/gsp-ascii-artist.md +2 -2
- package/gsp/agents/gsp-brand-auditor.md +3 -3
- package/gsp/agents/gsp-brand-engineer.md +131 -0
- package/gsp/agents/gsp-brand-strategist.md +3 -3
- package/gsp/agents/gsp-brand-syncer.md +8 -7
- package/gsp/agents/gsp-builder.md +49 -6
- package/gsp/agents/gsp-campaign-director.md +3 -4
- package/gsp/agents/gsp-creative-director.md +80 -0
- package/gsp/agents/gsp-critic.md +100 -18
- package/gsp/agents/gsp-designer.md +52 -5
- package/gsp/agents/gsp-project-researcher.md +4 -4
- package/gsp/agents/gsp-researcher.md +5 -5
- package/gsp/agents/gsp-reviewer.md +3 -3
- package/gsp/agents/gsp-scoper.md +3 -3
- package/gsp/hooks/hooks.json +5 -5
- package/gsp/skills/get-shit-pretty/SKILL.md +10 -9
- package/gsp/skills/gsp-accessibility/SKILL.md +12 -12
- package/gsp/skills/gsp-accessibility-audit/SKILL.md +8 -9
- package/gsp/skills/gsp-add-reference/SKILL.md +6 -1
- package/gsp/skills/gsp-art/SKILL.md +6 -1
- package/gsp/skills/gsp-brand-audit/SKILL.md +5 -5
- package/gsp/skills/gsp-brand-guidelines/SKILL.md +233 -0
- package/gsp/skills/gsp-brand-guidelines/token-mapping.md +329 -0
- package/gsp/skills/gsp-brand-identity/SKILL.md +29 -20
- package/gsp/skills/gsp-brand-refine/SKILL.md +30 -23
- package/gsp/skills/gsp-brand-research/SKILL.md +4 -4
- package/gsp/{references → skills/gsp-brand-research}/design-trends.md +4 -4
- package/gsp/skills/gsp-brand-strategy/SKILL.md +7 -7
- package/gsp/skills/gsp-brand-sync/SKILL.md +10 -10
- package/gsp/skills/gsp-brand-sync/chunk-format.md +79 -0
- package/gsp/skills/gsp-color/SKILL.md +73 -0
- package/gsp/skills/gsp-color/chunk-format.md +79 -0
- package/gsp/skills/{gsp-palette/SKILL.md → gsp-color/domains/palette.md} +31 -101
- package/gsp/skills/gsp-color/domains/system.md +123 -0
- package/gsp/skills/gsp-design-system/SKILL.md +9 -4
- package/gsp/skills/gsp-doctor/SKILL.md +25 -18
- package/gsp/skills/gsp-help/SKILL.md +30 -29
- package/gsp/skills/gsp-icons/SKILL.md +108 -0
- package/gsp/skills/gsp-icons/chunk-format.md +79 -0
- package/gsp/skills/gsp-launch/SKILL.md +3 -4
- package/gsp/skills/gsp-logo/SKILL.md +173 -0
- package/gsp/skills/gsp-logo/chunk-format.md +79 -0
- package/gsp/skills/gsp-phase-transition/SKILL.md +124 -0
- package/gsp/skills/gsp-pretty/SKILL.md +2 -2
- package/gsp/skills/gsp-progress/SKILL.md +20 -20
- package/gsp/skills/gsp-project-brief/SKILL.md +8 -9
- package/gsp/skills/gsp-project-build/SKILL.md +30 -25
- package/gsp/skills/gsp-project-critique/SKILL.md +17 -18
- package/gsp/{references → skills/gsp-project-critique}/visual-taste.md +1 -1
- package/gsp/skills/gsp-project-design/SKILL.md +18 -18
- package/gsp/skills/gsp-project-research/SKILL.md +6 -7
- package/gsp/skills/gsp-project-review/SKILL.md +8 -10
- package/gsp/skills/gsp-scaffold/SKILL.md +3 -3
- package/gsp/skills/gsp-start/SKILL.md +15 -15
- package/gsp/{references → skills/gsp-start}/questioning.md +1 -1
- package/gsp/skills/gsp-style/SKILL.md +43 -45
- package/gsp/skills/gsp-style/chunk-format.md +79 -0
- package/gsp/skills/gsp-style/style-preset-schema.md +124 -0
- 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-typography/SKILL.md +70 -0
- package/gsp/skills/gsp-typography/chunk-format.md +79 -0
- package/gsp/skills/gsp-typography/domains/pairing.md +109 -0
- package/gsp/skills/gsp-typography/domains/scale.md +227 -0
- package/gsp/skills/gsp-typography/domains/system.md +108 -0
- package/gsp/skills/gsp-update/SKILL.md +1 -2
- package/gsp/skills/gsp-visuals/SKILL.md +82 -0
- package/gsp/skills/gsp-visuals/chunk-format.md +79 -0
- package/gsp/skills/gsp-visuals/domains/3d.md +127 -0
- package/gsp/skills/gsp-visuals/domains/imagery.md +145 -0
- package/gsp/skills/gsp-visuals/domains/textures.md +138 -0
- package/gsp/skills/gsp-visuals/domains/video.md +107 -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/brief.md +1 -1
- package/gsp/templates/phases/build.md +1 -1
- package/gsp/templates/phases/critique.md +1 -1
- package/gsp/templates/phases/design.md +2 -2
- package/gsp/templates/phases/discover.md +1 -1
- package/gsp/templates/phases/identity.md +1 -1
- package/gsp/templates/phases/launch.md +1 -1
- package/gsp/templates/phases/patterns.md +60 -71
- package/gsp/templates/phases/research.md +1 -1
- package/gsp/templates/phases/review.md +1 -1
- package/gsp/templates/phases/strategy.md +1 -1
- 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 +1 -2
- package/.claude-plugin/plugin.json +0 -24
- package/gsp/agents/gsp-identity-designer.md +0 -74
- 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/references/phase-transitions.md +0 -132
- package/gsp/references/style-preset-schema.md +0 -63
- package/gsp/skills/gsp-brand-patterns/SKILL.md +0 -240
- package/gsp/skills/gsp-typescale/SKILL.md +0 -234
- /package/gsp/{references → skills/gsp-accessibility-audit}/wcag-checklist.md +0 -0
- /package/gsp/{references → skills/gsp-art}/terminal-art.md +0 -0
- /package/gsp/{references → skills/gsp-brand-audit}/chunk-format.md +0 -0
- /package/gsp/{references → skills/gsp-brand-guidelines}/design-tokens.md +0 -0
- /package/gsp/{references → skills/gsp-brand-strategy}/brand-archetypes.md +0 -0
- /package/gsp/{references → skills/gsp-brand-strategy}/brand-prism.md +0 -0
- /package/gsp/{references → skills/gsp-brand-strategy}/positioning-frameworks.md +0 -0
- /package/gsp/{references → skills/gsp-brand-strategy}/voice-tone.md +0 -0
- /package/gsp/{references → skills/gsp-color/references}/color-composition.md +0 -0
- /package/gsp/{references → skills/gsp-project-build}/visual-effects.md +0 -0
- /package/gsp/{references → skills/gsp-project-critique}/anti-patterns.md +0 -0
- /package/gsp/{references → skills/gsp-project-critique}/nielsen-heuristics.md +0 -0
- /package/gsp/{references → skills/gsp-project-design}/apple-hig-patterns.md +0 -0
- /package/gsp/{references → skills/gsp-project-design}/block-patterns.md +0 -0
- /package/gsp/{references → skills/gsp-typography/references}/typography-scales.md +0 -0
package/README.md
CHANGED
|
@@ -258,7 +258,7 @@ GSP works across all major AI coding tools. The installer converts Claude Code's
|
|
|
258
258
|
| Gemini CLI | `~/.gemini/` | `~/.gemini/skills/` | `~/.gemini/agents/` |
|
|
259
259
|
| Codex CLI | `~/.codex/` | `~/.agents/skills/` | — |
|
|
260
260
|
|
|
261
|
-
> **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.
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
@@ -308,14 +308,14 @@ npx get-shit-pretty --codex --global --uninstall
|
|
|
308
308
|
</details>
|
|
309
309
|
|
|
310
310
|
<details>
|
|
311
|
-
<summary><strong>
|
|
311
|
+
<summary><strong>Local development</strong></summary>
|
|
312
312
|
|
|
313
313
|
```bash
|
|
314
|
-
# From
|
|
315
|
-
claude --
|
|
314
|
+
# From the repo root:
|
|
315
|
+
node bin/install.js --claude --local
|
|
316
316
|
```
|
|
317
317
|
|
|
318
|
-
|
|
318
|
+
Symlinks skills and agents to `.claude/` — edits to `gsp/` are reflected immediately.
|
|
319
319
|
|
|
320
320
|
</details>
|
|
321
321
|
|
|
@@ -325,15 +325,13 @@ Uses the `.claude-plugin/plugin.json` manifest. Skills, agents, and hooks load d
|
|
|
325
325
|
|
|
326
326
|
```
|
|
327
327
|
get-shit-pretty/
|
|
328
|
-
├── .claude-plugin/ Plugin manifest (plugin.json)
|
|
329
328
|
├── bin/
|
|
330
329
|
│ └── install.js Multi-runtime installer
|
|
331
330
|
├── scripts/ Hook scripts and utilities
|
|
332
331
|
├── gsp/ Source of truth for all content
|
|
333
332
|
│ ├── agents/ 15 subagents (gsp-*.md)
|
|
334
|
-
│ ├── skills/
|
|
335
|
-
│ ├── hooks/
|
|
336
|
-
│ ├── prompts/ 12 agent system prompts
|
|
333
|
+
│ ├── skills/ 38 skills (*/SKILL.md)
|
|
334
|
+
│ ├── hooks/ Hooks (hooks.json)
|
|
337
335
|
│ ├── templates/ Config, state, brief, roadmap templates
|
|
338
336
|
│ └── references/ Shared reference material
|
|
339
337
|
├── dev/ Internal dev tools (not installed)
|
|
@@ -356,9 +354,6 @@ Edit source under `gsp/` — never edit inside `.claude/` or other runtime dirs
|
|
|
356
354
|
# Install locally with symlinks
|
|
357
355
|
node bin/install.js --claude --local
|
|
358
356
|
|
|
359
|
-
# Test as a plugin
|
|
360
|
-
claude --plugin-dir .
|
|
361
|
-
|
|
362
357
|
# Run the integrity test suite
|
|
363
358
|
bash dev/scripts/audit-tests.sh
|
|
364
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
|
|
@@ -806,7 +806,8 @@ function convertClaudeSkillToGemini(content, skillName) {
|
|
|
806
806
|
*/
|
|
807
807
|
function applyCodexBodyReplacements(content) {
|
|
808
808
|
let converted = content;
|
|
809
|
-
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-');
|
|
810
811
|
converted = converted.replace(/~\/\.claude\b/g, '~/.codex');
|
|
811
812
|
converted = converted.replace(/\bAskUserQuestion\b/g, 'ask the user');
|
|
812
813
|
converted = converted.replace(/\bSlashCommand\b/g, 'skill');
|
|
@@ -892,15 +893,7 @@ function convertClaudeSkillToCodex(content, skillName) {
|
|
|
892
893
|
function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
893
894
|
if (!fs.existsSync(srcDir)) return 0;
|
|
894
895
|
fs.mkdirSync(destDir, { recursive: true });
|
|
895
|
-
|
|
896
|
-
// Clean old gsp- skill dirs
|
|
897
|
-
if (fs.existsSync(destDir)) {
|
|
898
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
899
|
-
if (entry.isDirectory() && entry.name.startsWith('gsp-')) {
|
|
900
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
}
|
|
896
|
+
cleanStaleGspDirs(destDir);
|
|
904
897
|
|
|
905
898
|
let count = 0;
|
|
906
899
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -910,18 +903,15 @@ function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
|
910
903
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
911
904
|
if (!fs.existsSync(skillMd)) continue;
|
|
912
905
|
|
|
913
|
-
|
|
914
|
-
// Prefix with gsp- so they don't collide, unless already prefixed
|
|
915
|
-
const skillName = dir.name.startsWith('gsp-') ? dir.name : `gsp-${dir.name}`;
|
|
916
|
-
const skillDest = path.join(destDir, skillName);
|
|
906
|
+
const skillDest = path.join(destDir, dir.name);
|
|
917
907
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
918
908
|
|
|
919
909
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
920
910
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
921
911
|
content = content.replace(/\.\/\.claude\//g, './.opencode/');
|
|
922
|
-
content = convertClaudeSkillToOpencode(content,
|
|
912
|
+
content = convertClaudeSkillToOpencode(content, dir.name);
|
|
923
913
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
924
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
914
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
925
915
|
count++;
|
|
926
916
|
}
|
|
927
917
|
|
|
@@ -930,13 +920,14 @@ function copyOpencodeSkills(srcDir, destDir, pathPrefix) {
|
|
|
930
920
|
|
|
931
921
|
/**
|
|
932
922
|
* Copy skills/ source to Codex skill structure.
|
|
933
|
-
* skills
|
|
923
|
+
* skills/gsp-<name>/SKILL.md → .agents/skills/gsp-<name>/SKILL.md
|
|
934
924
|
*
|
|
935
925
|
* Codex expects: .agents/skills/<name>/SKILL.md with YAML frontmatter (name + description).
|
|
936
926
|
*/
|
|
937
927
|
function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
938
928
|
if (!fs.existsSync(srcDir)) return 0;
|
|
939
929
|
fs.mkdirSync(destDir, { recursive: true });
|
|
930
|
+
cleanStaleGspDirs(destDir);
|
|
940
931
|
|
|
941
932
|
let count = 0;
|
|
942
933
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -945,15 +936,14 @@ function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
|
945
936
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
946
937
|
if (!fs.existsSync(skillMd)) continue;
|
|
947
938
|
|
|
948
|
-
const
|
|
949
|
-
const skillDest = path.join(destDir, skillName);
|
|
939
|
+
const skillDest = path.join(destDir, dir.name);
|
|
950
940
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
951
941
|
|
|
952
942
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
953
943
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
954
|
-
content = convertClaudeSkillToCodex(content,
|
|
944
|
+
content = convertClaudeSkillToCodex(content, dir.name);
|
|
955
945
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
956
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
946
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
957
947
|
count++;
|
|
958
948
|
}
|
|
959
949
|
return count;
|
|
@@ -961,22 +951,14 @@ function copyCodexSkillsFromSource(srcDir, destDir, pathPrefix) {
|
|
|
961
951
|
|
|
962
952
|
/**
|
|
963
953
|
* Copy skills/ source to Gemini skill structure.
|
|
964
|
-
* skills
|
|
954
|
+
* skills/gsp-<name>/SKILL.md → .gemini/skills/gsp-<name>/SKILL.md
|
|
965
955
|
*
|
|
966
956
|
* Gemini expects: .gemini/skills/<name>/SKILL.md with YAML frontmatter (name + description).
|
|
967
957
|
*/
|
|
968
958
|
function copyGeminiSkills(srcDir, destDir, pathPrefix) {
|
|
969
959
|
if (!fs.existsSync(srcDir)) return 0;
|
|
970
960
|
fs.mkdirSync(destDir, { recursive: true });
|
|
971
|
-
|
|
972
|
-
// Clean old gsp- skill dirs
|
|
973
|
-
if (fs.existsSync(destDir)) {
|
|
974
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
975
|
-
if (entry.isDirectory() && entry.name.startsWith('gsp-')) {
|
|
976
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
961
|
+
cleanStaleGspDirs(destDir);
|
|
980
962
|
|
|
981
963
|
let count = 0;
|
|
982
964
|
const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
@@ -985,16 +967,15 @@ function copyGeminiSkills(srcDir, destDir, pathPrefix) {
|
|
|
985
967
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
986
968
|
if (!fs.existsSync(skillMd)) continue;
|
|
987
969
|
|
|
988
|
-
const
|
|
989
|
-
const skillDest = path.join(destDir, skillName);
|
|
970
|
+
const skillDest = path.join(destDir, dir.name);
|
|
990
971
|
fs.mkdirSync(skillDest, { recursive: true });
|
|
991
972
|
|
|
992
973
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
993
974
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
994
975
|
content = content.replace(/\.\/\.claude\//g, './.gemini/');
|
|
995
|
-
content = convertClaudeSkillToGemini(content,
|
|
976
|
+
content = convertClaudeSkillToGemini(content, dir.name);
|
|
996
977
|
fs.writeFileSync(path.join(skillDest, 'SKILL.md'), content);
|
|
997
|
-
copySiblingFiles(path.join(srcDir, dir.name), skillDest
|
|
978
|
+
copySiblingFiles(path.join(srcDir, dir.name), skillDest);
|
|
998
979
|
count++;
|
|
999
980
|
}
|
|
1000
981
|
return count;
|
|
@@ -1036,49 +1017,64 @@ function copyAgents(srcDir, destDir, pathPrefix, runtime, { clean = false } = {}
|
|
|
1036
1017
|
}
|
|
1037
1018
|
|
|
1038
1019
|
/**
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1020
|
+
* Remove stale GSP skill dirs/symlinks (gsp-* and get-shit-pretty) from a target directory.
|
|
1021
|
+
* Handles broken symlinks via lstat fallback.
|
|
1041
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
|
+
|
|
1042
1043
|
/**
|
|
1043
1044
|
* Recursively copy sibling files in a skill directory (everything except SKILL.md).
|
|
1044
|
-
* All sibling files are copied verbatim — no path replacement applied.
|
|
1045
1045
|
*/
|
|
1046
|
-
function copySiblingFiles(srcDir, destDir
|
|
1046
|
+
function copySiblingFiles(srcDir, destDir) {
|
|
1047
1047
|
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
1048
|
-
if (entry.name === 'SKILL.md') continue;
|
|
1048
|
+
if (entry.name === 'SKILL.md') continue;
|
|
1049
1049
|
const srcPath = path.join(srcDir, entry.name);
|
|
1050
1050
|
const destPath = path.join(destDir, entry.name);
|
|
1051
1051
|
if (entry.isDirectory()) {
|
|
1052
1052
|
fs.mkdirSync(destPath, { recursive: true });
|
|
1053
|
-
copySiblingFiles(srcPath, destPath
|
|
1053
|
+
copySiblingFiles(srcPath, destPath);
|
|
1054
1054
|
} else {
|
|
1055
1055
|
fs.copyFileSync(srcPath, destPath);
|
|
1056
1056
|
}
|
|
1057
1057
|
}
|
|
1058
1058
|
}
|
|
1059
1059
|
|
|
1060
|
+
/**
|
|
1061
|
+
* Copy Claude Code skills (global install — no body conversion, only path replacement).
|
|
1062
|
+
*/
|
|
1060
1063
|
function copyClaudeSkills(srcDir, destDir, pathPrefix) {
|
|
1061
1064
|
fs.mkdirSync(destDir, { recursive: true });
|
|
1062
|
-
|
|
1063
|
-
// Clean old gsp- skill dirs
|
|
1064
|
-
for (const entry of fs.readdirSync(destDir, { withFileTypes: true })) {
|
|
1065
|
-
if (entry.isDirectory() && (entry.name.startsWith('gsp-') || entry.name === 'get-shit-pretty')) {
|
|
1066
|
-
fs.rmSync(path.join(destDir, entry.name), { recursive: true });
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1065
|
+
cleanStaleGspDirs(destDir);
|
|
1069
1066
|
|
|
1070
1067
|
let skillCount = 0;
|
|
1071
1068
|
for (const dir of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
1072
1069
|
if (!dir.isDirectory()) continue;
|
|
1073
1070
|
const skillMd = path.join(srcDir, dir.name, 'SKILL.md');
|
|
1074
1071
|
if (!fs.existsSync(skillMd)) continue;
|
|
1075
|
-
const
|
|
1076
|
-
const destSkillDir = path.join(destDir, skillName);
|
|
1072
|
+
const destSkillDir = path.join(destDir, dir.name);
|
|
1077
1073
|
fs.mkdirSync(destSkillDir, { recursive: true });
|
|
1078
1074
|
let content = fs.readFileSync(skillMd, 'utf8');
|
|
1079
1075
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
1080
1076
|
fs.writeFileSync(path.join(destSkillDir, 'SKILL.md'), content);
|
|
1081
|
-
copySiblingFiles(path.join(srcDir, dir.name), destSkillDir
|
|
1077
|
+
copySiblingFiles(path.join(srcDir, dir.name), destSkillDir);
|
|
1082
1078
|
skillCount++;
|
|
1083
1079
|
}
|
|
1084
1080
|
return skillCount;
|
|
@@ -1201,22 +1197,34 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1201
1197
|
const skillsDest = path.join(targetDir, 'skills');
|
|
1202
1198
|
fs.mkdirSync(skillsDest, { recursive: true });
|
|
1203
1199
|
|
|
1204
|
-
// Clean old GSP skill dirs
|
|
1205
|
-
for (const entry of fs.readdirSync(skillsDest, { withFileTypes: true })) {
|
|
1206
|
-
if (entry.isDirectory() && (entry.name.startsWith('gsp-') || entry.name === 'get-shit-pretty')) {
|
|
1207
|
-
fs.rmSync(path.join(skillsDest, entry.name), { recursive: true });
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
1200
|
const skillsSrc = path.join(gspRoot, 'skills');
|
|
1201
|
+
cleanStaleGspDirs(skillsDest);
|
|
1212
1202
|
let skillCount = 0;
|
|
1213
1203
|
for (const dir of fs.readdirSync(skillsSrc, { withFileTypes: true })) {
|
|
1214
1204
|
if (!dir.isDirectory()) continue;
|
|
1215
1205
|
forceSymlink(path.join('..', '..', 'gsp', 'skills', dir.name), path.join(skillsDest, dir.name));
|
|
1216
1206
|
skillCount++;
|
|
1217
1207
|
}
|
|
1208
|
+
// ── Dev skill symlinks (local only — not shipped in npm package) ──
|
|
1209
|
+
const devSkillsSrc = path.join(cwd, 'dev', 'skills');
|
|
1210
|
+
let devSkillCount = 0;
|
|
1211
|
+
try {
|
|
1212
|
+
if (fs.existsSync(devSkillsSrc)) {
|
|
1213
|
+
for (const dir of fs.readdirSync(devSkillsSrc, { withFileTypes: true })) {
|
|
1214
|
+
if (!dir.isDirectory()) continue;
|
|
1215
|
+
forceSymlink(path.join('..', '..', 'dev', 'skills', dir.name), path.join(skillsDest, dir.name));
|
|
1216
|
+
devSkillCount++;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
} catch {
|
|
1220
|
+
console.log(` ${c.secondary}! Could not read dev/skills/ — skipping dev skills${c.reset}`);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1218
1223
|
if (skillCount > 0) {
|
|
1219
|
-
|
|
1224
|
+
const msg = devSkillCount > 0
|
|
1225
|
+
? `Symlinked ${skillCount} skills + ${devSkillCount} dev`
|
|
1226
|
+
: `Symlinked ${skillCount} skills`;
|
|
1227
|
+
console.log(` ${c.success}✓${c.reset} ${msg}`);
|
|
1220
1228
|
} else { failures.push('skills'); }
|
|
1221
1229
|
|
|
1222
1230
|
// Clean up legacy commands/gsp dir (may be broken symlink)
|
|
@@ -1227,19 +1235,25 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1227
1235
|
console.log(` ${c.success}✓${c.reset} Removed legacy commands/gsp`);
|
|
1228
1236
|
} catch {}
|
|
1229
1237
|
|
|
1230
|
-
// ── Bundle symlinks (
|
|
1231
|
-
// Clean up legacy
|
|
1238
|
+
// ── Bundle symlinks (templates → runtime root) ──
|
|
1239
|
+
// Clean up legacy dirs
|
|
1232
1240
|
const legacyBundleDest = path.join(targetDir, 'get-shit-pretty');
|
|
1233
1241
|
if (fs.existsSync(legacyBundleDest)) {
|
|
1234
1242
|
fs.rmSync(legacyBundleDest, { recursive: true });
|
|
1235
1243
|
console.log(` ${c.success}✓${c.reset} Removed legacy get-shit-pretty/ bundle`);
|
|
1236
1244
|
}
|
|
1245
|
+
for (const legacyDir of ['prompts', 'references']) {
|
|
1246
|
+
const legacyPath = path.join(targetDir, legacyDir);
|
|
1247
|
+
try {
|
|
1248
|
+
fs.lstatSync(legacyPath);
|
|
1249
|
+
fs.rmSync(legacyPath, { recursive: true });
|
|
1250
|
+
console.log(` ${c.success}✓${c.reset} Removed legacy ${legacyDir}/`);
|
|
1251
|
+
} catch {}
|
|
1252
|
+
}
|
|
1237
1253
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
console.log(` ${c.success}✓${c.reset} Symlinked ${dir}/`);
|
|
1242
|
-
}
|
|
1254
|
+
if (fs.existsSync(path.join(gspRoot, 'templates'))) {
|
|
1255
|
+
forceSymlink(path.join('..', 'gsp', 'templates'), path.join(targetDir, 'templates'));
|
|
1256
|
+
console.log(` ${c.success}✓${c.reset} Symlinked templates/`);
|
|
1243
1257
|
}
|
|
1244
1258
|
|
|
1245
1259
|
// Write VERSION from package.json (local dev uses repo root VERSION via symlinks)
|
|
@@ -1267,6 +1281,16 @@ function installLocalSymlinks(targetDir, src) {
|
|
|
1267
1281
|
process.exit(1);
|
|
1268
1282
|
}
|
|
1269
1283
|
|
|
1284
|
+
// Warn if GSP skills also exist globally (may cause duplicates)
|
|
1285
|
+
const globalSkillsDir = path.join(getGlobalDir('claude', null), 'skills');
|
|
1286
|
+
if (fs.existsSync(globalSkillsDir)) {
|
|
1287
|
+
const dupes = fs.readdirSync(globalSkillsDir).filter(e => e.startsWith('gsp-'));
|
|
1288
|
+
if (dupes.length > 0) {
|
|
1289
|
+
console.log(` ${yellow}!${reset} Found ${dupes.length} GSP skills in ${globalSkillsDir.replace(os.homedir(), '~')} — may cause duplicates`);
|
|
1290
|
+
console.log(` ${c.dim}To remove: node bin/install.js --claude --global --uninstall${c.reset}`);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1270
1294
|
return true;
|
|
1271
1295
|
}
|
|
1272
1296
|
|
|
@@ -1417,23 +1441,25 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1417
1441
|
}
|
|
1418
1442
|
}
|
|
1419
1443
|
|
|
1420
|
-
// ── Bundle:
|
|
1421
|
-
// Clean up legacy
|
|
1444
|
+
// ── Bundle: templates, references → runtime root ──
|
|
1445
|
+
// Clean up legacy dirs from previous installs
|
|
1422
1446
|
const legacyBundle = path.join(targetDir, 'get-shit-pretty');
|
|
1423
1447
|
if (fs.existsSync(legacyBundle)) {
|
|
1424
1448
|
fs.rmSync(legacyBundle, { recursive: true });
|
|
1425
1449
|
console.log(` ${c.success}✓${c.reset} Removed legacy get-shit-pretty/ bundle`);
|
|
1426
1450
|
}
|
|
1451
|
+
const legacyPromptsDir = path.join(targetDir, 'prompts');
|
|
1452
|
+
if (fs.existsSync(legacyPromptsDir)) {
|
|
1453
|
+
fs.rmSync(legacyPromptsDir, { recursive: true });
|
|
1454
|
+
console.log(` ${c.success}✓${c.reset} Removed legacy prompts/`);
|
|
1455
|
+
}
|
|
1427
1456
|
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
console.log(` ${c.success}✓${c.reset} Installed ${dir}/`);
|
|
1435
|
-
} else { failures.push(dir); }
|
|
1436
|
-
}
|
|
1457
|
+
const templatesSrc = path.join(gspRoot, 'templates');
|
|
1458
|
+
if (fs.existsSync(templatesSrc)) {
|
|
1459
|
+
copyWithPathReplacement(templatesSrc, path.join(targetDir, 'templates'), pathPrefix, runtime);
|
|
1460
|
+
if (verifyInstalled(path.join(targetDir, 'templates'), 'templates')) {
|
|
1461
|
+
console.log(` ${c.success}✓${c.reset} Installed templates/`);
|
|
1462
|
+
} else { failures.push('templates'); }
|
|
1437
1463
|
}
|
|
1438
1464
|
|
|
1439
1465
|
// Write VERSION file
|
|
@@ -1467,6 +1493,21 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
1467
1493
|
process.exit(1);
|
|
1468
1494
|
}
|
|
1469
1495
|
|
|
1496
|
+
// Warn if GSP skills exist in the other location (may cause duplicates)
|
|
1497
|
+
if (runtime === 'claude') {
|
|
1498
|
+
const otherDir = isGlobal
|
|
1499
|
+
? path.join(process.cwd(), '.claude', 'skills')
|
|
1500
|
+
: path.join(getGlobalDir('claude', null), 'skills');
|
|
1501
|
+
if (fs.existsSync(otherDir)) {
|
|
1502
|
+
const dupes = fs.readdirSync(otherDir).filter(e => e.startsWith('gsp-'));
|
|
1503
|
+
if (dupes.length > 0) {
|
|
1504
|
+
const label = otherDir.replace(os.homedir(), '~');
|
|
1505
|
+
console.log(` ${yellow}!${reset} Found ${dupes.length} GSP skills in ${label} — may cause duplicates`);
|
|
1506
|
+
console.log(` ${c.dim}To remove: node bin/install.js --claude ${isGlobal ? '--local' : '--global'} --uninstall${c.reset}`);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1470
1511
|
// ── Settings (Claude Code & Gemini only) ──
|
|
1471
1512
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
1472
1513
|
const settings = readSettings(settingsPath);
|
|
@@ -1545,7 +1586,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1545
1586
|
}
|
|
1546
1587
|
}
|
|
1547
1588
|
} else {
|
|
1548
|
-
// All other runtimes: remove gsp- skill dirs
|
|
1589
|
+
// All other runtimes (including Claude): remove gsp- skill dirs
|
|
1549
1590
|
const skillsDir = path.join(targetDir, 'skills');
|
|
1550
1591
|
if (fs.existsSync(skillsDir)) {
|
|
1551
1592
|
let skillCount = 0;
|
|
@@ -1593,7 +1634,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1593
1634
|
}
|
|
1594
1635
|
|
|
1595
1636
|
// Remove flattened bundle dirs
|
|
1596
|
-
for (const dir of ['prompts', 'templates', 'references']) {
|
|
1637
|
+
for (const dir of ['prompts', 'templates', 'references']) { // prompts included for legacy cleanup
|
|
1597
1638
|
const bundlePath = path.join(targetDir, dir);
|
|
1598
1639
|
if (fs.existsSync(bundlePath)) {
|
|
1599
1640
|
fs.rmSync(bundlePath, { recursive: true });
|
|
@@ -1726,8 +1767,8 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
|
|
|
1726
1767
|
}
|
|
1727
1768
|
|
|
1728
1769
|
const runtimeLabel = getRuntimeLabel(runtime);
|
|
1729
|
-
const helpCmd =
|
|
1730
|
-
const newCmd =
|
|
1770
|
+
const helpCmd = isCodex ? '$gsp-help' : '/gsp-help';
|
|
1771
|
+
const newCmd = isCodex ? '$gsp-start' : '/gsp-start';
|
|
1731
1772
|
|
|
1732
1773
|
// Show onboarding once (not per-runtime)
|
|
1733
1774
|
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
|
|
@@ -58,7 +58,7 @@ Write your audit as chunks to the output directory (path provided by the skill t
|
|
|
58
58
|
|
|
59
59
|
### Chunk files
|
|
60
60
|
|
|
61
|
-
Write each chunk following the
|
|
61
|
+
Write each chunk following the standard chunk format:
|
|
62
62
|
|
|
63
63
|
1. **`accessibility-audit.md`** (~100-150 lines) — Perceivable, Operable, Understandable, Robust checklists (pass/fail per criterion with notes), Mobile accessibility, Cognitive accessibility, summary (total pass/fail/not-applicable counts, overall conformance level), accessibility statement draft
|
|
64
64
|
2. **`accessibility-fixes.md`** (~50-100 lines) — Violations table (issue, severity Critical/Major/Minor, WCAG criterion, remediation steps). Only Critical and Major severity items.
|
|
@@ -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
|
|
@@ -19,7 +19,7 @@ You are a creative who happens to work in a grid of fixed-width cells. Every pie
|
|
|
19
19
|
</role>
|
|
20
20
|
|
|
21
21
|
<reference>
|
|
22
|
-
@
|
|
22
|
+
@skills/gsp-art/terminal-art.md
|
|
23
23
|
</reference>
|
|
24
24
|
|
|
25
25
|
<methodology>
|
|
@@ -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>
|
|
@@ -38,7 +38,7 @@ Assess existing brand identities — coherence, market fit, equity, evolution op
|
|
|
38
38
|
<output>
|
|
39
39
|
Write 5 chunks + INDEX.md to the audit directory (path provided by the skill that spawned you).
|
|
40
40
|
|
|
41
|
-
Each chunk follows
|
|
41
|
+
Each chunk follows the standard chunk format.
|
|
42
42
|
|
|
43
43
|
1. **`brand-inventory.md`** — structured inventory of all current assets (logo, colors with hex, typefaces, voice samples, messaging, positioning)
|
|
44
44
|
2. **`coherence-assessment.md`** — strategy coherence (1-5), strategy↔visual alignment (1-5), key disconnects
|