@mohammadhprp/system-prompt 0.11.2 → 0.12.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.
Files changed (30) hide show
  1. package/framework/agents/researcher.md +1 -1
  2. package/framework/mcps/github-mcp/README.md +1 -1
  3. package/framework/mcps/github-mcp/configs/.env.example +1 -1
  4. package/framework/plugins/ponytail/README.md +1 -1
  5. package/framework/plugins/ponytail/capabilities.md +1 -1
  6. package/framework/references/standards/pull-requests.md +1 -1
  7. package/framework/skills/README.md +1 -1
  8. package/framework/skills/diagram-design/SKILL.md +1 -1
  9. package/framework/skills/taste/SKILL.md +47 -0
  10. package/framework/skills/taste/examples.md +73 -0
  11. package/framework/skills/taste/references/brandkit.md +793 -0
  12. package/framework/skills/taste/references/design-taste-frontend-v1.md +221 -0
  13. package/framework/skills/taste/references/design-taste-frontend.md +1201 -0
  14. package/framework/skills/taste/references/full-output-enforcement.md +44 -0
  15. package/framework/skills/taste/references/gpt-taste.md +69 -0
  16. package/framework/skills/taste/references/high-end-visual-design.md +93 -0
  17. package/framework/skills/taste/references/image-to-code.md +1223 -0
  18. package/framework/skills/taste/references/imagegen-frontend-mobile.md +1460 -0
  19. package/framework/skills/taste/references/imagegen-frontend-web.md +982 -0
  20. package/framework/skills/taste/references/industrial-brutalist-ui.md +87 -0
  21. package/framework/skills/taste/references/minimalist-ui.md +80 -0
  22. package/framework/skills/taste/references/redesign-existing-projects.md +173 -0
  23. package/framework/skills/taste/references/stitch-design-taste-design.md +121 -0
  24. package/framework/skills/taste/references/stitch-design-taste.md +179 -0
  25. package/package.json +1 -1
  26. package/src/agent-configs.js +6 -2
  27. package/src/catalog.js +1 -0
  28. package/src/cli.js +82 -2
  29. package/src/doctor.js +84 -0
  30. package/src/installer.js +337 -154
@@ -0,0 +1,179 @@
1
+ # Stitch Design Taste — Semantic Design System Skill
2
+
3
+ ## Overview
4
+ This skill generates `DESIGN.md` files optimized for Google Stitch screen generation. It translates the battle-tested anti-slop frontend engineering directives into Stitch's native semantic design language — descriptive, natural-language rules paired with precise values that Stitch's AI agent can interpret to produce premium, non-generic interfaces.
5
+
6
+ The generated `DESIGN.md` serves as the **single source of truth** for prompting Stitch to generate new screens that align with a curated, high-agency design language. Stitch interprets design through **"Visual Descriptions"** supported by specific color values, typography specs, and component behaviors.
7
+
8
+ ## Prerequisites
9
+ - Access to Google Stitch via [labs.google/stitch](https://labs.google/stitch)
10
+ - Optionally: Stitch MCP Server for programmatic integration with Cursor, Antigravity, or Gemini CLI
11
+
12
+ ## The Goal
13
+ Generate a `DESIGN.md` file that encodes:
14
+ 1. **Visual atmosphere** — the mood, density, and design philosophy
15
+ 2. **Color calibration** — neutrals, accents, and banned patterns with hex codes
16
+ 3. **Typographic architecture** — font stacks, scale hierarchy, and anti-patterns
17
+ 4. **Component behaviors** — buttons, cards, inputs with interaction states
18
+ 5. **Layout principles** — grid systems, spacing philosophy, responsive strategy
19
+ 6. **Motion philosophy** — animation engine specs, spring physics, perpetual micro-interactions
20
+ 7. **Anti-patterns** — explicit list of banned AI design clichés
21
+
22
+ ## Analysis & Synthesis Instructions
23
+
24
+ ### 1. Define the Atmosphere
25
+ Evaluate the target project's intent. Use evocative adjectives from the taste spectrum:
26
+ - **Density:** "Art Gallery Airy" (1–3) → "Daily App Balanced" (4–7) → "Cockpit Dense" (8–10)
27
+ - **Variance:** "Predictable Symmetric" (1–3) → "Offset Asymmetric" (4–7) → "Artsy Chaotic" (8–10)
28
+ - **Motion:** "Static Restrained" (1–3) → "Fluid CSS" (4–7) → "Cinematic Choreography" (8–10)
29
+
30
+ Default baseline: Variance 8, Motion 6, Density 4. Adapt dynamically based on user's vibe description.
31
+
32
+ ### 2. Map the Color Palette
33
+ For each color provide: **Descriptive Name** + **Hex Code** + **Functional Role**.
34
+
35
+ **Mandatory constraints:**
36
+ - Maximum 1 accent color. Saturation below 80%
37
+ - The "AI Purple/Blue Neon" aesthetic is strictly BANNED — no purple button glows, no neon gradients
38
+ - Use absolute neutral bases (Zinc/Slate) with high-contrast singular accents
39
+ - Stick to one palette for the entire output — no warm/cool gray fluctuation
40
+ - Never use pure black (`#000000`) — use Off-Black, Zinc-950, or Charcoal
41
+
42
+ ### 3. Establish Typography Rules
43
+ - **Display/Headlines:** Track-tight, controlled scale. Not screaming. Hierarchy through weight and color, not just massive size
44
+ - **Body:** Relaxed leading, max 65 characters per line
45
+ - **Font Selection:** `Inter` is BANNED for premium/creative contexts. Force unique character: `Geist`, `Outfit`, `Cabinet Grotesk`, or `Satoshi`
46
+ - **Serif Ban:** Generic serif fonts (`Times New Roman`, `Georgia`, `Garamond`, `Palatino`) are BANNED. If serif is needed for editorial/creative contexts, use only distinctive modern serifs: `Fraunces`, `Gambarino`, `Editorial New`, or `Instrument Serif`. Serif is always BANNED in dashboards or software UIs
47
+ - **Dashboard Constraint:** Use Sans-Serif pairings exclusively (`Geist` + `Geist Mono` or `Satoshi` + `JetBrains Mono`)
48
+ - **High-Density Override:** When density exceeds 7, all numbers must use Monospace
49
+
50
+ ### 4. Define the Hero Section
51
+ The Hero is the first impression and must be creative, striking, and never generic:
52
+ - **Inline Image Typography:** Embed small, contextual photos or visuals directly between words or letters in the headline. Images sit inline at type-height, rounded, acting as visual punctuation. This is the signature creative technique
53
+ - **No Overlapping:** Text must never overlap images or other text. Every element occupies its own clean spatial zone
54
+ - **No Filler Text:** "Scroll to explore", "Swipe down", scroll arrow icons, bouncing chevrons are BANNED. The content should pull users in naturally
55
+ - **Asymmetric Structure:** Centered Hero layouts BANNED when variance exceeds 4
56
+ - **CTA Restraint:** Maximum one primary CTA. No secondary "Learn more" links
57
+
58
+ ### 5. Describe Component Stylings
59
+ For each component type, describe shape, color, shadow depth, and interaction behavior:
60
+ - **Buttons:** Tactile push feedback on active state. No neon outer glows. No custom mouse cursors
61
+ - **Cards:** Use ONLY when elevation communicates hierarchy. Tint shadows to background hue. For high-density layouts, replace cards with border-top dividers or negative space
62
+ - **Inputs/Forms:** Label above input, helper text optional, error text below. Standard gap spacing
63
+ - **Loading States:** Skeletal loaders matching layout dimensions — no generic circular spinners
64
+ - **Empty States:** Composed compositions indicating how to populate data
65
+ - **Error States:** Clear, inline error reporting
66
+
67
+ ### 6. Define Layout Principles
68
+ - No overlapping elements — every element occupies its own clear spatial zone. No absolute-positioned content stacking
69
+ - Centered Hero sections are BANNED when variance exceeds 4 — force Split Screen, Left-Aligned, or Asymmetric Whitespace
70
+ - The generic "3 equal cards horizontally" feature row is BANNED — use 2-column Zig-Zag, asymmetric grid, or horizontal scroll
71
+ - CSS Grid over Flexbox math — never use `calc()` percentage hacks
72
+ - Contain layouts using max-width constraints (e.g., 1400px centered)
73
+ - Full-height sections must use `min-h-[100dvh]` — never `h-screen` (iOS Safari catastrophic jump)
74
+
75
+ ### 7. Define Responsive Rules
76
+ Every design must work across all viewports:
77
+ - **Mobile-First Collapse (< 768px):** All multi-column layouts collapse to single column. No exceptions
78
+ - **No Horizontal Scroll:** Horizontal overflow on mobile is a critical failure
79
+ - **Typography Scaling:** Headlines scale via `clamp()`. Body text minimum `1rem`/`14px`
80
+ - **Touch Targets:** All interactive elements minimum `44px` tap target
81
+ - **Image Behavior:** Inline typography images (photos between words) stack below headline on mobile
82
+ - **Navigation:** Desktop horizontal nav collapses to clean mobile menu
83
+ - **Spacing:** Vertical section gaps reduce proportionally (`clamp(3rem, 8vw, 6rem)`)
84
+
85
+ ### 8. Encode Motion Philosophy
86
+ - **Spring Physics default:** `stiffness: 100, damping: 20` — premium, weighty feel. No linear easing
87
+ - **Perpetual Micro-Interactions:** Every active component should have an infinite loop state (Pulse, Typewriter, Float, Shimmer)
88
+ - **Staggered Orchestration:** Never mount lists instantly — use cascade delays for waterfall reveals
89
+ - **Performance:** Animate exclusively via `transform` and `opacity`. Never animate `top`, `left`, `width`, `height`. Grain/noise filters on fixed pseudo-elements only
90
+
91
+ ### 9. List Anti-Patterns (AI Tells)
92
+ Encode these as explicit "NEVER DO" rules in the DESIGN.md:
93
+ - No emojis anywhere
94
+ - No `Inter` font
95
+ - No generic serif fonts (`Times New Roman`, `Georgia`, `Garamond`) — distinctive modern serifs only if needed
96
+ - No pure black (`#000000`)
97
+ - No neon/outer glow shadows
98
+ - No oversaturated accents
99
+ - No excessive gradient text on large headers
100
+ - No custom mouse cursors
101
+ - No overlapping elements — clean spatial separation always
102
+ - No 3-column equal card layouts
103
+ - No generic names ("John Doe", "Acme", "Nexus")
104
+ - No fake round numbers (`99.99%`, `50%`)
105
+ - No AI copywriting clichés ("Elevate", "Seamless", "Unleash", "Next-Gen")
106
+ - No filler UI text: "Scroll to explore", "Swipe down", scroll arrows, bouncing chevrons
107
+ - No broken Unsplash links — use `picsum.photos` or SVG avatars
108
+ - No centered Hero sections (for high-variance projects)
109
+
110
+ ## Output Format (DESIGN.md Structure)
111
+
112
+ ```markdown
113
+ # Design System: [Project Title]
114
+
115
+ ## 1. Visual Theme & Atmosphere
116
+ (Evocative description of the mood, density, variance, and motion intensity.
117
+ Example: "A restrained, gallery-airy interface with confident asymmetric layouts
118
+ and fluid spring-physics motion. The atmosphere is clinical yet warm — like a
119
+ well-lit architecture studio.")
120
+
121
+ ## 2. Color Palette & Roles
122
+ - **Canvas White** (#F9FAFB) — Primary background surface
123
+ - **Pure Surface** (#FFFFFF) — Card and container fill
124
+ - **Charcoal Ink** (#18181B) — Primary text, Zinc-950 depth
125
+ - **Muted Steel** (#71717A) — Secondary text, descriptions, metadata
126
+ - **Whisper Border** (rgba(226,232,240,0.5)) — Card borders, 1px structural lines
127
+ - **[Accent Name]** (#XXXXXX) — Single accent for CTAs, active states, focus rings
128
+ (Max 1 accent. Saturation < 80%. No purple/neon.)
129
+
130
+ ## 3. Typography Rules
131
+ - **Display:** [Font Name] — Track-tight, controlled scale, weight-driven hierarchy
132
+ - **Body:** [Font Name] — Relaxed leading, 65ch max-width, neutral secondary color
133
+ - **Mono:** [Font Name] — For code, metadata, timestamps, high-density numbers
134
+ - **Banned:** Inter, generic system fonts for premium contexts. Serif fonts banned in dashboards.
135
+
136
+ ## 4. Component Stylings
137
+ * **Buttons:** Flat, no outer glow. Tactile -1px translate on active. Accent fill for primary, ghost/outline for secondary.
138
+ * **Cards:** Generously rounded corners (2.5rem). Diffused whisper shadow. Used only when elevation serves hierarchy. High-density: replace with border-top dividers.
139
+ * **Inputs:** Label above, error below. Focus ring in accent color. No floating labels.
140
+ * **Loaders:** Skeletal shimmer matching exact layout dimensions. No circular spinners.
141
+ * **Empty States:** Composed, illustrated compositions — not just "No data" text.
142
+
143
+ ## 5. Layout Principles
144
+ (Grid-first responsive architecture. Asymmetric splits for Hero sections.
145
+ Strict single-column collapse below 768px. Max-width containment.
146
+ No flexbox percentage math. Generous internal padding.)
147
+
148
+ ## 6. Motion & Interaction
149
+ (Spring physics for all interactive elements. Staggered cascade reveals.
150
+ Perpetual micro-loops on active dashboard components. Hardware-accelerated
151
+ transforms only. Isolated Client Components for CPU-heavy animations.)
152
+
153
+ ## 7. Anti-Patterns (Banned)
154
+ (Explicit list of forbidden patterns: no emojis, no Inter, no pure black,
155
+ no neon glows, no 3-column equal grids, no AI copywriting clichés,
156
+ no generic placeholder names, no broken image links.)
157
+ ```
158
+
159
+ ## Best Practices
160
+ - **Be Descriptive:** "Deep Charcoal Ink (#18181B)" — not just "dark text"
161
+ - **Be Functional:** Explain what each element is used for
162
+ - **Be Consistent:** Same terminology throughout the document
163
+ - **Be Precise:** Include exact hex codes, rem values, pixel values in parentheses
164
+ - **Be Opinionated:** This is not a neutral template — it enforces a specific, premium aesthetic
165
+
166
+ ## Tips for Success
167
+ 1. Start with the atmosphere — understand the vibe before detailing tokens
168
+ 2. Look for patterns — identify consistent spacing, sizing, and styling
169
+ 3. Think semantically — name colors by purpose, not just appearance
170
+ 4. Consider hierarchy — document how visual weight communicates importance
171
+ 5. Encode the bans — anti-patterns are as important as the rules themselves
172
+
173
+ ## Common Pitfalls to Avoid
174
+ - Using technical jargon without translation ("rounded-xl" instead of "generously rounded corners")
175
+ - Omitting hex codes or using only descriptive names
176
+ - Forgetting functional roles of design elements
177
+ - Being too vague in atmosphere descriptions
178
+ - Ignoring the anti-pattern list — these are what make the output premium
179
+ - Defaulting to generic "safe" designs instead of enforcing the curated aesthetic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohammadhprp/system-prompt",
3
- "version": "0.11.2",
3
+ "version": "0.12.0",
4
4
  "description": "AI Coding Agent Framework — interactive bootstrap CLI",
5
5
  "keywords": [
6
6
  "ai",
@@ -15,8 +15,12 @@ export async function loadMcpConfigs(selectedIds) {
15
15
  if (parsed.mcp) {
16
16
  Object.assign(entries, parsed.mcp);
17
17
  }
18
- } catch {
19
- console.warn(` ⚠ No opencode.json config found for MCP: ${id}`);
18
+ } catch (error) {
19
+ if (error.code === 'ENOENT') {
20
+ console.warn(` ⚠ No opencode.json config found for MCP: ${id}`);
21
+ continue;
22
+ }
23
+ throw error;
20
24
  }
21
25
  }
22
26
  return entries;
package/src/catalog.js CHANGED
@@ -30,6 +30,7 @@ export const categories = {
30
30
  { id: 'skill-creator', name: 'Skill Creator', description: 'Create and evaluate new agent skills' },
31
31
  { id: 'spec-driven-eval', name: 'Spec-Driven Eval', description: 'Score how completely an implementation fulfills a PRD/spec, case by case, into a single comparable grade' },
32
32
  { id: 'technical-design-doc-creator', name: 'Technical Design Doc Creator', description: 'Create comprehensive Technical Design Documents with mandatory and optional sections through interactive discovery' },
33
+ { id: 'taste', name: 'Taste', description: 'Unified design-quality skill spanning anti-slop frontend, image generation and image-to-code, brand kits, minimalist and industrial UI, and Google Stitch design systems' },
33
34
  { id: 'tlc-spec-driven', name: 'TLC Spec-Driven', description: 'Feature planning and implementation with adaptive phases, EARS testable requirements, atomic commits, and independent verification' },
34
35
  { id: 'web-design-guidelines', name: 'Web Design Guidelines', description: 'Review UI code for Web Interface Guidelines compliance: accessibility, interaction patterns, and design best practices' }
35
36
  ],
package/src/cli.js CHANGED
@@ -3,6 +3,57 @@ import { resolve } from 'node:path';
3
3
 
4
4
  import { categories } from './catalog.js';
5
5
  import { getPackageVersion, install, loadLockFile } from './installer.js';
6
+ import { doctor } from './doctor.js';
7
+
8
+ const CATEGORY_FLAGS = new Set(Object.keys(categories));
9
+
10
+ export function parseArgs(argv) {
11
+ const options = {
12
+ targetDir: '.opencode',
13
+ selections: {},
14
+ all: false,
15
+ dryRun: false,
16
+ force: false,
17
+ doctor: false,
18
+ includeAgentsMd: true,
19
+ };
20
+ for (let index = 0; index < argv.length; index += 1) {
21
+ const arg = argv[index];
22
+ if (arg === '--all') options.all = true;
23
+ else if (arg === '--dry-run') options.dryRun = true;
24
+ else if (arg === '--force') options.force = true;
25
+ else if (arg === '--doctor') options.doctor = true;
26
+ else if (arg === '--no-agents-md') options.includeAgentsMd = false;
27
+ else if (arg === '--target') {
28
+ const value = argv[++index];
29
+ if (!value || value.startsWith('--')) throw new Error('Missing value for --target');
30
+ options.targetDir = value;
31
+ }
32
+ else if (arg.startsWith('--target=')) {
33
+ const value = arg.slice('--target='.length);
34
+ if (!value) throw new Error('Missing value for --target');
35
+ options.targetDir = value;
36
+ }
37
+ else if (arg.startsWith('--')) {
38
+ const [flag, inlineValue] = arg.slice(2).split('=', 2);
39
+ if (!CATEGORY_FLAGS.has(flag)) throw new Error(`Unknown option: ${arg}`);
40
+ const value = inlineValue ?? argv[++index];
41
+ if (!value) throw new Error(`Missing value for --${flag}`);
42
+ options.selections[flag] = value.split(',').filter(Boolean);
43
+ } else {
44
+ throw new Error(`Unknown argument: ${arg}`);
45
+ }
46
+ }
47
+ options.nonInteractive = options.all || Object.keys(options.selections).length > 0;
48
+ return options;
49
+ }
50
+
51
+ function allSelections() {
52
+ return Object.fromEntries(Object.entries(categories).map(([category, config]) => [
53
+ category,
54
+ config.items.filter(item => !item.removed).map(item => item.id),
55
+ ]));
56
+ }
6
57
 
7
58
  function buildSummary(selections) {
8
59
  const lines = [];
@@ -86,12 +137,38 @@ function formatDiff(diff) {
86
137
  return lines.join('\n');
87
138
  }
88
139
 
89
- export async function main() {
140
+ export async function main(argv = process.argv.slice(2)) {
141
+ const args = parseArgs(argv);
142
+ if (args.doctor) {
143
+ const healthy = await doctor(args.targetDir);
144
+ if (!healthy) process.exitCode = 1;
145
+ return healthy;
146
+ }
147
+
90
148
  const version = await getPackageVersion();
91
149
  intro(`System prompt (v${version})`);
92
150
 
93
151
  const agentType = 'opencode';
94
- const targetDir = '.opencode';
152
+ const targetDir = args.targetDir;
153
+
154
+ if (args.nonInteractive) {
155
+ const selections = args.all ? allSelections() : args.selections;
156
+ const absTarget = resolve(process.cwd(), targetDir);
157
+ const oldLock = await loadLockFile(absTarget);
158
+ if (!args.dryRun) console.log(`Installing selected components into ${absTarget}`);
159
+ await install({
160
+ targetDir,
161
+ agentType,
162
+ selections,
163
+ includeAgentsMd: args.includeAgentsMd,
164
+ oldSelections: oldLock?.selections,
165
+ oldLock,
166
+ force: args.force,
167
+ dryRun: args.dryRun,
168
+ });
169
+ console.log(args.dryRun ? 'Dry run complete.' : 'Installation complete.');
170
+ return;
171
+ }
95
172
 
96
173
  const categoryOptions = Object.entries(categories).map(([key, cat]) => {
97
174
  const visible = cat.items.filter(i => !i.removed);
@@ -239,6 +316,9 @@ export async function main() {
239
316
  selections,
240
317
  includeAgentsMd,
241
318
  oldSelections: oldLock?.selections,
319
+ oldLock,
320
+ force: args.force,
321
+ dryRun: args.dryRun,
242
322
  });
243
323
 
244
324
  s.stop('Installation complete!');
package/src/doctor.js ADDED
@@ -0,0 +1,84 @@
1
+ import { resolve } from 'node:path';
2
+ import { access, readFile } from 'node:fs/promises';
3
+ import { createHash } from 'node:crypto';
4
+
5
+ import { categories } from './catalog.js';
6
+ import { loadLockFile } from './installer.js';
7
+
8
+ async function exists(path) {
9
+ try {
10
+ await access(path);
11
+ return true;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ export async function inspectInstallation(targetDir) {
18
+ const absTarget = resolve(process.cwd(), targetDir);
19
+ const issues = [];
20
+ let lock;
21
+
22
+ try {
23
+ lock = await loadLockFile(absTarget);
24
+ } catch (error) {
25
+ issues.push(error.message);
26
+ return { targetDir: absTarget, issues };
27
+ }
28
+
29
+ if (!lock) {
30
+ issues.push('No system-prompt-lock.json found.');
31
+ return { targetDir: absTarget, issues };
32
+ }
33
+
34
+ for (const [path, expected] of Object.entries(lock.managedFiles || {})) {
35
+ try {
36
+ const actual = createHash('sha256').update(await readFile(resolve(absTarget, path))).digest('hex');
37
+ if (actual !== expected) issues.push(`Modified managed file: ${path}`);
38
+ } catch (error) {
39
+ if (error.code === 'ENOENT') issues.push(`Missing managed file: ${path}`);
40
+ else throw error;
41
+ }
42
+ }
43
+
44
+ for (const [category, ids] of Object.entries(lock.selections)) {
45
+ const config = categories[category];
46
+ for (const id of ids) {
47
+ const item = config.items.find(entry => entry.id === id);
48
+ const relativePath = ['agents', 'commands', 'memory', 'modes', 'standards', 'templates'].includes(category)
49
+ ? `${config.sourceDir.replace(/^framework\//, '')}/${id}.md`
50
+ : `${config.sourceDir.replace(/^framework\//, '')}/${id}`;
51
+ if (!item || !(await exists(resolve(absTarget, relativePath)))) {
52
+ issues.push(`Missing installed ${category} item: ${id}`);
53
+ }
54
+ }
55
+ }
56
+
57
+ if (lock.agentType === 'opencode') {
58
+ for (const file of ['opencode.json', 'tui.json']) {
59
+ const path = resolve(absTarget, file);
60
+ if (!(await exists(path))) {
61
+ issues.push(`Missing generated file: ${file}`);
62
+ continue;
63
+ }
64
+ try {
65
+ JSON.parse(await readFile(path, 'utf-8'));
66
+ } catch {
67
+ issues.push(`Invalid JSON: ${file}`);
68
+ }
69
+ }
70
+ }
71
+
72
+ return { targetDir: absTarget, issues };
73
+ }
74
+
75
+ export async function doctor(targetDir = '.opencode', output = console.log) {
76
+ const result = await inspectInstallation(targetDir);
77
+ output(`Checking ${result.targetDir}`);
78
+ if (result.issues.length === 0) {
79
+ output('No issues found.');
80
+ return true;
81
+ }
82
+ for (const issue of result.issues) output(` ⚠ ${issue}`);
83
+ return false;
84
+ }