superskills 0.1.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/LICENSE +21 -0
- package/README.md +363 -0
- package/bin/superskills +6 -0
- package/dist/catalog/index.d.ts +11 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +203 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/tools-catalog.json +243 -0
- package/dist/catalog/types.d.ts +59 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/catalog/types.js +2 -0
- package/dist/catalog/types.js.map +1 -0
- package/dist/catalog/ui.d.ts +4 -0
- package/dist/catalog/ui.d.ts.map +1 -0
- package/dist/catalog/ui.js +86 -0
- package/dist/catalog/ui.js.map +1 -0
- package/dist/cli/colors.d.ts +8 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +11 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/discovery/analyze.d.ts +5 -0
- package/dist/discovery/analyze.d.ts.map +1 -0
- package/dist/discovery/analyze.js +190 -0
- package/dist/discovery/analyze.js.map +1 -0
- package/dist/discovery/core.d.ts +16 -0
- package/dist/discovery/core.d.ts.map +1 -0
- package/dist/discovery/core.js +51 -0
- package/dist/discovery/core.js.map +1 -0
- package/dist/discovery/index.d.ts +4 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +233 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/schema.d.ts +111 -0
- package/dist/discovery/schema.d.ts.map +1 -0
- package/dist/discovery/schema.js +87 -0
- package/dist/discovery/schema.js.map +1 -0
- package/dist/discovery/types.d.ts +56 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +2 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +523 -0
- package/dist/index.js.map +1 -0
- package/dist/scaffold/index.d.ts +4 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +262 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/templates/claude-md.d.ts +4 -0
- package/dist/scaffold/templates/claude-md.d.ts.map +1 -0
- package/dist/scaffold/templates/claude-md.js +229 -0
- package/dist/scaffold/templates/claude-md.js.map +1 -0
- package/dist/scaffold/templates/claude-settings.d.ts +3 -0
- package/dist/scaffold/templates/claude-settings.d.ts.map +1 -0
- package/dist/scaffold/templates/claude-settings.js +48 -0
- package/dist/scaffold/templates/claude-settings.js.map +1 -0
- package/dist/scaffold/templates/env-example.d.ts +3 -0
- package/dist/scaffold/templates/env-example.d.ts.map +1 -0
- package/dist/scaffold/templates/env-example.js +103 -0
- package/dist/scaffold/templates/env-example.js.map +1 -0
- package/dist/scaffold/templates/package-json.d.ts +2 -0
- package/dist/scaffold/templates/package-json.d.ts.map +1 -0
- package/dist/scaffold/templates/package-json.js +56 -0
- package/dist/scaffold/templates/package-json.js.map +1 -0
- package/dist/scaffold/templates/project-files.d.ts +4 -0
- package/dist/scaffold/templates/project-files.d.ts.map +1 -0
- package/dist/scaffold/templates/project-files.js +459 -0
- package/dist/scaffold/templates/project-files.js.map +1 -0
- package/dist/scaffold/templates/skill-agents.d.ts +4 -0
- package/dist/scaffold/templates/skill-agents.d.ts.map +1 -0
- package/dist/scaffold/templates/skill-agents.js +68 -0
- package/dist/scaffold/templates/skill-agents.js.map +1 -0
- package/dist/scaffold/templates/skill-commands.d.ts +3 -0
- package/dist/scaffold/templates/skill-commands.d.ts.map +1 -0
- package/dist/scaffold/templates/skill-commands.js +509 -0
- package/dist/scaffold/templates/skill-commands.js.map +1 -0
- package/dist/scaffold/templates/teammate-prompts.d.ts +8 -0
- package/dist/scaffold/templates/teammate-prompts.d.ts.map +1 -0
- package/dist/scaffold/templates/teammate-prompts.js +506 -0
- package/dist/scaffold/templates/teammate-prompts.js.map +1 -0
- package/dist/scaffold/types.d.ts +68 -0
- package/dist/scaffold/types.d.ts.map +1 -0
- package/dist/scaffold/types.js +2 -0
- package/dist/scaffold/types.js.map +1 -0
- package/dist/scaffold/ui.d.ts +5 -0
- package/dist/scaffold/ui.d.ts.map +1 -0
- package/dist/scaffold/ui.js +127 -0
- package/dist/scaffold/ui.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +8 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createStrategyPrompt, createDesignPrompt, createTrustPrompt, createEfficiencyPrompt, createTestingPrompt } from './teammate-prompts.js';
|
|
2
|
+
const AGENTS = [
|
|
3
|
+
{
|
|
4
|
+
name: 'strategy',
|
|
5
|
+
tools: ['Read', 'Grep', 'Glob'],
|
|
6
|
+
description: 'Use proactively after commits to check EIID alignment and suggest new opportunities across all four layers',
|
|
7
|
+
memory: 'project',
|
|
8
|
+
promptFn: createStrategyPrompt
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: 'design',
|
|
12
|
+
tools: ['Read', 'Grep', 'Glob', 'Bash'],
|
|
13
|
+
model: 'sonnet',
|
|
14
|
+
memory: 'project',
|
|
15
|
+
description: 'Use proactively for UI setup with shadcnblocks/shadcn, design tokens, and design reviews',
|
|
16
|
+
promptFn: createDesignPrompt
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'trust',
|
|
20
|
+
tools: ['Read', 'Grep', 'Glob', 'Bash'],
|
|
21
|
+
description: 'Use proactively to audit security and compliance',
|
|
22
|
+
promptFn: createTrustPrompt
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'efficiency',
|
|
26
|
+
tools: ['Read', 'Grep', 'Glob', 'Bash'],
|
|
27
|
+
model: 'haiku',
|
|
28
|
+
description: 'Use proactively to check performance and costs',
|
|
29
|
+
promptFn: createEfficiencyPrompt
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'testing',
|
|
33
|
+
tools: ['Read', 'Grep', 'Glob', 'Bash'],
|
|
34
|
+
memory: 'project',
|
|
35
|
+
description: 'Use proactively to verify behavior with tests',
|
|
36
|
+
promptFn: createTestingPrompt
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
function generateFrontmatter(agent) {
|
|
40
|
+
const lines = ['---'];
|
|
41
|
+
lines.push(`name: ${agent.name}`);
|
|
42
|
+
lines.push(`description: ${agent.description}`);
|
|
43
|
+
lines.push(`tools: ${agent.tools.join(', ')}`);
|
|
44
|
+
if (agent.model)
|
|
45
|
+
lines.push(`model: ${agent.model}`);
|
|
46
|
+
if (agent.memory)
|
|
47
|
+
lines.push(`memory: ${agent.memory}`);
|
|
48
|
+
lines.push('---');
|
|
49
|
+
return lines.join('\n');
|
|
50
|
+
}
|
|
51
|
+
export function generateSkillAgents(discovery, tools) {
|
|
52
|
+
const files = {};
|
|
53
|
+
for (const agent of AGENTS) {
|
|
54
|
+
const frontmatter = generateFrontmatter(agent);
|
|
55
|
+
const prompt = agent.promptFn(discovery, tools);
|
|
56
|
+
const content = `${frontmatter}
|
|
57
|
+
|
|
58
|
+
# ${agent.name}
|
|
59
|
+
|
|
60
|
+
${agent.description}
|
|
61
|
+
|
|
62
|
+
${prompt}
|
|
63
|
+
`;
|
|
64
|
+
files[`.claude/agents/${agent.name}.md`] = content;
|
|
65
|
+
}
|
|
66
|
+
return files;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=skill-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-agents.js","sourceRoot":"","sources":["../../../src/scaffold/templates/skill-agents.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAW/B,MAAM,MAAM,GAAgB;IAC1B;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,WAAW,EAAE,4GAA4G;QACzH,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,oBAAoB;KAC/B;IACD;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QACvC,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,0FAA0F;QACvG,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QACvC,WAAW,EAAE,kDAAkD;QAC/D,QAAQ,EAAE,iBAAiB;KAC5B;IACD;QACE,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QACvC,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,gDAAgD;QAC7D,QAAQ,EAAE,sBAAsB;KACjC;IACD;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QACvC,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,+CAA+C;QAC5D,QAAQ,EAAE,mBAAmB;KAC9B;CACF,CAAC;AAEF,SAAS,mBAAmB,CAAC,KAAgB;IAC3C,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,SAA0B,EAC1B,KAAuB;IAEvB,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,GAAG,WAAW;;IAE9B,KAAK,CAAC,IAAI;;EAEZ,KAAK,CAAC,WAAW;;EAEjB,MAAM;CACP,CAAC;QACE,KAAK,CAAC,kBAAkB,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-commands.d.ts","sourceRoot":"","sources":["../../../src/scaffold/templates/skill-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAggBhE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxF"}
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
const INIT_SKILLS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'strategy-start',
|
|
4
|
+
description: 'Define a project from scratch. Maps business problem to EIID framework, writes CLAUDE.md.',
|
|
5
|
+
content: () => `# /strategy-start
|
|
6
|
+
|
|
7
|
+
Start a new project or redefine the strategic foundation for this one.
|
|
8
|
+
|
|
9
|
+
No API key needed. Claude Code does the analysis directly.
|
|
10
|
+
|
|
11
|
+
## Before Starting
|
|
12
|
+
|
|
13
|
+
1. Read the codebase: CLAUDE.md, package.json, README.md, source files, .env.example
|
|
14
|
+
2. If CLAUDE.md already has an EIID mapping, suggest \`/strategy-init\` instead
|
|
15
|
+
3. Use existing files as context. Do not ask what the code already tells you.
|
|
16
|
+
|
|
17
|
+
## Conversation
|
|
18
|
+
|
|
19
|
+
Ask about what you do not know. Skip what you can infer. Four things needed:
|
|
20
|
+
|
|
21
|
+
1. **The problem.** What costs time, money, or attention today?
|
|
22
|
+
2. **The data.** What systems, APIs, files, data sources exist?
|
|
23
|
+
3. **The people.** Who needs the output? Where are they? (email, Slack, WhatsApp, Telegram)
|
|
24
|
+
4. **The outcome.** What does success look like?
|
|
25
|
+
|
|
26
|
+
One round of questions. Two at most.
|
|
27
|
+
|
|
28
|
+
## EIID Mapping
|
|
29
|
+
|
|
30
|
+
Build the four-layer mapping:
|
|
31
|
+
|
|
32
|
+
- **Enrichment**: existing data, missing data, sources to connect
|
|
33
|
+
- **Inference**: patterns to detect, predictions, anomalies to flag
|
|
34
|
+
- **Interpretation**: actionable insights to surface
|
|
35
|
+
- **Delivery**: channels, triggers, timing
|
|
36
|
+
|
|
37
|
+
## Output
|
|
38
|
+
|
|
39
|
+
Update CLAUDE.md with: Context, Problem, Desired Outcome, EIID mapping, Architecture Decisions section.
|
|
40
|
+
|
|
41
|
+
Then suggest: \`/strategy-init\` to validate and prioritize, plus which other skills to activate.
|
|
42
|
+
|
|
43
|
+
## Rules
|
|
44
|
+
|
|
45
|
+
- One conversation, then write. Do not iterate endlessly.
|
|
46
|
+
- Concrete items, not vague categories. "Gmail inbox" not "email data".
|
|
47
|
+
- CLAUDE.md is the deliverable.
|
|
48
|
+
- Do not suggest tools or tech stack.
|
|
49
|
+
`
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'strategy-init',
|
|
53
|
+
description: 'Validate EIID mapping, set priorities, write first decision to CLAUDE.md',
|
|
54
|
+
content: (discovery) => `# /strategy-init
|
|
55
|
+
|
|
56
|
+
Validate the EIID mapping and set project priorities.
|
|
57
|
+
|
|
58
|
+
## Steps
|
|
59
|
+
|
|
60
|
+
1. Read CLAUDE.md and understand the current EIID mapping
|
|
61
|
+
2. Validate that each EIID layer has concrete, actionable items:
|
|
62
|
+
- **Enrichment**: Are data sources identified? Are there gaps?
|
|
63
|
+
- **Inference**: Are patterns specific and measurable?
|
|
64
|
+
- **Interpretation**: Are insights clearly defined?
|
|
65
|
+
- **Delivery**: Are channels configured? Are triggers defined?
|
|
66
|
+
3. Ask the user to prioritize: which EIID layer to focus on first
|
|
67
|
+
4. Write the first strategic decision to CLAUDE.md in the Architecture Decisions section
|
|
68
|
+
|
|
69
|
+
## Project Context
|
|
70
|
+
|
|
71
|
+
**Problem:** ${discovery.problem}
|
|
72
|
+
**Desired Outcome:** ${discovery.desiredOutcome}
|
|
73
|
+
|
|
74
|
+
## Output
|
|
75
|
+
|
|
76
|
+
Append to CLAUDE.md:
|
|
77
|
+
|
|
78
|
+
\`\`\`markdown
|
|
79
|
+
### [Date] - Initial Strategy Validation
|
|
80
|
+
|
|
81
|
+
**Context:** Project initialized via SuperSkills
|
|
82
|
+
**Decision:** [Priority layer] is the first focus area
|
|
83
|
+
**Consequences:** [What this means for development order]
|
|
84
|
+
\`\`\`
|
|
85
|
+
`
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'design-init',
|
|
89
|
+
description: 'Configure brand, shadcn/shadcnblocks, design tokens, and SHADCNBLOCKS_API_KEY',
|
|
90
|
+
content: () => `# /design-init
|
|
91
|
+
|
|
92
|
+
Set up the design system for this project. Uses shadcnblocks (1351 blocks) and shadcn base components.
|
|
93
|
+
|
|
94
|
+
## Steps
|
|
95
|
+
|
|
96
|
+
1. **SHADCNBLOCKS_API_KEY** (optional, only for pro blocks):
|
|
97
|
+
- Most blocks are FREE and work without a key
|
|
98
|
+
- If the user has a pro key: save to \`.env.local\` as SHADCNBLOCKS_API_KEY
|
|
99
|
+
- If not: continue normally — free blocks cover most use cases
|
|
100
|
+
|
|
101
|
+
2. **Verify components.json** has the shadcnblocks registry:
|
|
102
|
+
\`\`\`json
|
|
103
|
+
{
|
|
104
|
+
"registries": {
|
|
105
|
+
"@shadcnblocks": {
|
|
106
|
+
"url": "https://shadcnblocks.com/r",
|
|
107
|
+
"headers": {
|
|
108
|
+
"Authorization": "Bearer \${SHADCNBLOCKS_API_KEY}"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
3. **Ask the user for brand assets:**
|
|
116
|
+
- Color palette (primary, secondary, accent, destructive) in HSL
|
|
117
|
+
- Font family (sans, mono)
|
|
118
|
+
- Logo path (if available)
|
|
119
|
+
|
|
120
|
+
4. **Set up global design tokens** in \`src/app/globals.css\`:
|
|
121
|
+
- CSS custom properties for ALL colors in HSL format:
|
|
122
|
+
--background, --foreground, --card, --card-foreground, --popover, --popover-foreground,
|
|
123
|
+
--primary, --primary-foreground, --secondary, --secondary-foreground, --muted,
|
|
124
|
+
--muted-foreground, --accent, --accent-foreground, --destructive, --destructive-foreground,
|
|
125
|
+
--border, --input, --ring, --radius
|
|
126
|
+
- Both :root (light) and .dark (dark) variants
|
|
127
|
+
- NO hardcoded hex or rgb anywhere in the file
|
|
128
|
+
|
|
129
|
+
5. **Configure tailwind.config.ts** to extend from CSS variables:
|
|
130
|
+
- colors read from var(--primary), var(--secondary), etc.
|
|
131
|
+
- borderRadius reads from var(--radius)
|
|
132
|
+
- fontFamily from user choices
|
|
133
|
+
|
|
134
|
+
6. **Initialize shadcn**: \`npx shadcn init\`
|
|
135
|
+
|
|
136
|
+
7. **Install base shadcn components**:
|
|
137
|
+
\`\`\`bash
|
|
138
|
+
npx shadcn add button card input label badge dialog dropdown-menu table
|
|
139
|
+
\`\`\`
|
|
140
|
+
|
|
141
|
+
8. **Ask about shadcnblocks layouts** to install:
|
|
142
|
+
- Dashboard: \`npx shadcn add @shadcnblocks/sidebar10\`
|
|
143
|
+
- Auth pages: \`npx shadcn add @shadcnblocks/login1\`
|
|
144
|
+
- Settings: \`npx shadcn add @shadcnblocks/settings1\`
|
|
145
|
+
- Hero: \`npx shadcn add @shadcnblocks/hero125\`
|
|
146
|
+
- Pricing: \`npx shadcn add @shadcnblocks/pricing3\`
|
|
147
|
+
Install what the user selects.
|
|
148
|
+
|
|
149
|
+
## HARD RULES (enforce from day one)
|
|
150
|
+
|
|
151
|
+
- **shadcnblocks FIRST**: If a block exists for the use case, use it
|
|
152
|
+
- **shadcn base SECOND**: Standard components for everything else
|
|
153
|
+
- **NEVER custom CSS classes**: No .my-card, no .custom-header
|
|
154
|
+
- **ZERO inline arbitrary values**: No text-[#FF5733], no p-[13px]
|
|
155
|
+
- **All colors from tokens**: Components read from CSS variables via Tailwind theme
|
|
156
|
+
|
|
157
|
+
## Output
|
|
158
|
+
|
|
159
|
+
- \`components.json\` with shadcnblocks registry
|
|
160
|
+
- \`src/app/globals.css\` with full token set
|
|
161
|
+
- \`tailwind.config.ts\` extending from tokens
|
|
162
|
+
- shadcn components and blocks installed
|
|
163
|
+
- Update CLAUDE.md with design decisions
|
|
164
|
+
`
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'trust-init',
|
|
168
|
+
description: 'Configure auth flow, RLS policies, CORS, and data sensitivity levels',
|
|
169
|
+
content: (discovery) => `# /trust-init
|
|
170
|
+
|
|
171
|
+
Set up security foundations for this project.
|
|
172
|
+
|
|
173
|
+
## Steps
|
|
174
|
+
|
|
175
|
+
1. Ask the user about authentication requirements:
|
|
176
|
+
- Auth method: Supabase Auth (email/password, OAuth, magic link)
|
|
177
|
+
- Protected routes: which pages require auth
|
|
178
|
+
- Role-based access: admin, user, etc.
|
|
179
|
+
|
|
180
|
+
2. Configure Supabase Row Level Security (RLS):
|
|
181
|
+
- Create initial RLS policies for main tables
|
|
182
|
+
- Enable RLS on all tables by default
|
|
183
|
+
- Create helper functions for auth checks
|
|
184
|
+
|
|
185
|
+
3. Ask about data sensitivity:
|
|
186
|
+
- PII fields to protect
|
|
187
|
+
- Data retention requirements
|
|
188
|
+
- GDPR requirements (consent, export, deletion)
|
|
189
|
+
|
|
190
|
+
4. Configure CORS:
|
|
191
|
+
- Allowed origins for production
|
|
192
|
+
- API route protection middleware
|
|
193
|
+
|
|
194
|
+
5. Set up environment variable validation:
|
|
195
|
+
- Verify all required env vars are set at startup
|
|
196
|
+
|
|
197
|
+
## Project Context
|
|
198
|
+
|
|
199
|
+
**Industry:** ${discovery.context.industry || 'Not specified'}
|
|
200
|
+
**Data Sources:** ${discovery.availableData.join(', ') || 'Not specified'}
|
|
201
|
+
|
|
202
|
+
## Output
|
|
203
|
+
|
|
204
|
+
- Supabase migration with RLS policies
|
|
205
|
+
- Auth middleware for Next.js
|
|
206
|
+
- Environment variable validation
|
|
207
|
+
- Update CLAUDE.md with security decisions
|
|
208
|
+
`
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: 'efficiency-init',
|
|
212
|
+
description: 'Set performance budgets, configure bundle analysis, and monitoring',
|
|
213
|
+
content: () => `# /efficiency-init
|
|
214
|
+
|
|
215
|
+
Set up performance monitoring and budgets.
|
|
216
|
+
|
|
217
|
+
## Steps
|
|
218
|
+
|
|
219
|
+
1. Ask the user for performance targets:
|
|
220
|
+
- LCP target (default: < 2.5s)
|
|
221
|
+
- Bundle size limit (default: < 200KB gzipped)
|
|
222
|
+
- API response time target (default: < 500ms)
|
|
223
|
+
|
|
224
|
+
2. Configure bundle analysis:
|
|
225
|
+
- Add \`@next/bundle-analyzer\` to dev dependencies
|
|
226
|
+
- Add \`analyze\` script to package.json
|
|
227
|
+
|
|
228
|
+
3. Set up performance tracking:
|
|
229
|
+
- Add Web Vitals reporting in layout.tsx
|
|
230
|
+
- Configure Vercel Analytics (if using Vercel)
|
|
231
|
+
|
|
232
|
+
4. Review current dependencies for optimization:
|
|
233
|
+
- Check for heavy imports that should be dynamic
|
|
234
|
+
- Verify tree-shaking is working
|
|
235
|
+
|
|
236
|
+
## Output
|
|
237
|
+
|
|
238
|
+
- Performance budget documented in CLAUDE.md
|
|
239
|
+
- Bundle analyzer configured
|
|
240
|
+
- Web Vitals reporting set up
|
|
241
|
+
- Update CLAUDE.md with performance decisions
|
|
242
|
+
`
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: 'testing-init',
|
|
246
|
+
description: 'Set up vitest + Playwright, define critical scenarios, write first smoke test',
|
|
247
|
+
content: () => `# /testing-init
|
|
248
|
+
|
|
249
|
+
Set up the testing infrastructure.
|
|
250
|
+
|
|
251
|
+
## Steps
|
|
252
|
+
|
|
253
|
+
1. Configure vitest:
|
|
254
|
+
- Verify vitest config in package.json or vitest.config.ts
|
|
255
|
+
- Set up test directory structure: \`tests/unit/\`, \`tests/e2e/\`
|
|
256
|
+
- Add test scripts to package.json
|
|
257
|
+
|
|
258
|
+
2. Configure Playwright:
|
|
259
|
+
- Run \`npx playwright install\`
|
|
260
|
+
- Verify playwright.config.ts exists
|
|
261
|
+
- Set up base URL for local development
|
|
262
|
+
|
|
263
|
+
3. Ask the user for critical test scenarios:
|
|
264
|
+
- What are the most important user flows?
|
|
265
|
+
- What must never break?
|
|
266
|
+
|
|
267
|
+
4. Write first tests:
|
|
268
|
+
- Unit smoke test: verify core utilities work
|
|
269
|
+
- E2E smoke test: verify home page loads and renders
|
|
270
|
+
- Add to CI if available
|
|
271
|
+
|
|
272
|
+
5. Run tests to verify setup:
|
|
273
|
+
- \`npm test\` for vitest
|
|
274
|
+
- \`npx playwright test\` for E2E
|
|
275
|
+
|
|
276
|
+
## Output
|
|
277
|
+
|
|
278
|
+
- vitest configured and running
|
|
279
|
+
- Playwright configured with sample E2E test
|
|
280
|
+
- Critical scenarios documented
|
|
281
|
+
- Update CLAUDE.md with testing strategy
|
|
282
|
+
`
|
|
283
|
+
}
|
|
284
|
+
];
|
|
285
|
+
const REVIEW_SKILLS = [
|
|
286
|
+
{
|
|
287
|
+
name: 'strategy-review',
|
|
288
|
+
description: 'Full EIID alignment analysis + proactive opportunity scan',
|
|
289
|
+
content: (discovery) => `# /strategy-review
|
|
290
|
+
|
|
291
|
+
Perform a full strategic review and opportunity scan.
|
|
292
|
+
|
|
293
|
+
## Part 1: Alignment Check
|
|
294
|
+
|
|
295
|
+
1. Read CLAUDE.md for current strategic context
|
|
296
|
+
2. Scan all source files for EIID alignment:
|
|
297
|
+
- Are enrichment sources being used?
|
|
298
|
+
- Are inference patterns implemented?
|
|
299
|
+
- Are insights being generated?
|
|
300
|
+
- Are delivery channels active?
|
|
301
|
+
3. Check for scope creep:
|
|
302
|
+
- Features not in original EIID mapping
|
|
303
|
+
- Dependencies not in the tools catalog
|
|
304
|
+
4. Review recent commits for strategic drift
|
|
305
|
+
|
|
306
|
+
## Part 2: Opportunity Scan
|
|
307
|
+
|
|
308
|
+
This is the more valuable part. Look at the codebase and suggest:
|
|
309
|
+
|
|
310
|
+
- **Enrichment opportunities**: Data sources available but not connected. Data collected but not used for inference. Cross-referencing opportunities between existing sources.
|
|
311
|
+
- **Inference opportunities**: Patterns detectable from existing data but not analyzed. Predictions the data supports but no one has built. Anomaly detection that would catch problems early.
|
|
312
|
+
- **Interpretation opportunities**: Insights generated but not surfaced clearly. New angles on existing data (trends, comparisons, outlier explanations). Context that would make insights more actionable.
|
|
313
|
+
- **Delivery opportunities**: Channels users frequent but the system does not reach. Timing improvements. Trigger conditions currently missed.
|
|
314
|
+
|
|
315
|
+
Examples of good findings:
|
|
316
|
+
- "Supplier data is available but not used for delay prediction. Enrichment opportunity."
|
|
317
|
+
- "Order anomaly patterns could predict customer churn. Inference opportunity."
|
|
318
|
+
- "Email reports work but Slack would reach the ops team faster. Delivery opportunity."
|
|
319
|
+
|
|
320
|
+
## Project Context
|
|
321
|
+
|
|
322
|
+
**Problem:** ${discovery.problem}
|
|
323
|
+
**Desired Outcome:** ${discovery.desiredOutcome}
|
|
324
|
+
**Opportunities (from discovery):** ${discovery.strategicAnalysis.opportunities.join(', ')}
|
|
325
|
+
|
|
326
|
+
## Output
|
|
327
|
+
|
|
328
|
+
Append findings to CLAUDE.md Architecture Decisions section.
|
|
329
|
+
Each finding gets a **Type** (alignment-check | opportunity | drift-warning) and a **Layer** (enrichment | inference | interpretation | delivery).
|
|
330
|
+
`
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: 'design-review',
|
|
334
|
+
description: 'Audit shadcnblocks/shadcn usage, hard rule violations, a11y, responsive',
|
|
335
|
+
content: () => `# /design-review
|
|
336
|
+
|
|
337
|
+
Audit the UI against the five hard rules, accessibility, and responsive design.
|
|
338
|
+
|
|
339
|
+
## Hard Rule Violations (check first)
|
|
340
|
+
|
|
341
|
+
Scan ALL component files (\`src/app/**/*.tsx\`, \`src/components/**/*.tsx\`) for:
|
|
342
|
+
|
|
343
|
+
1. **shadcnblocks FIRST**: Is there a UI section that could be replaced by a shadcnblocks block? (hero, pricing, dashboard, auth, settings, e-commerce, features, testimonials, FAQ, footer, navbar, sidebar, stats, CTA, contact, blog, 404)
|
|
344
|
+
2. **shadcn base SECOND**: Is there a custom component that duplicates shadcn functionality?
|
|
345
|
+
3. **No custom CSS classes**: Search for className strings containing custom class names (not Tailwind utilities)
|
|
346
|
+
4. **Token compliance**: Search for hardcoded hex (#xxx), rgb(), hsl() values in component files. These must come from CSS variables.
|
|
347
|
+
5. **No arbitrary values**: Search for Tailwind arbitrary value syntax: \`-\\[.*\\]\` in className strings
|
|
348
|
+
|
|
349
|
+
## Accessibility (WCAG 2.1 AA)
|
|
350
|
+
|
|
351
|
+
- Color contrast ratios (4.5:1 normal text, 3:1 large text)
|
|
352
|
+
- Keyboard navigation (focus states, tab order)
|
|
353
|
+
- Screen reader compatibility (semantic HTML, ARIA)
|
|
354
|
+
- Touch targets (44x44px minimum)
|
|
355
|
+
- Alt text on images
|
|
356
|
+
- Labels on form inputs
|
|
357
|
+
|
|
358
|
+
## Responsive
|
|
359
|
+
|
|
360
|
+
- Verify mobile layout (320px minimum)
|
|
361
|
+
- Check breakpoint consistency (sm/md/lg/xl)
|
|
362
|
+
|
|
363
|
+
## Output
|
|
364
|
+
|
|
365
|
+
Per issue:
|
|
366
|
+
|
|
367
|
+
**File:** path/to/file.tsx:line
|
|
368
|
+
**Rule Violated:** Rule [1-5] or a11y or responsive
|
|
369
|
+
**Issue:** Brief description
|
|
370
|
+
**Fix:** What to change (include exact shadcn/shadcnblocks command if applicable)
|
|
371
|
+
|
|
372
|
+
Update CLAUDE.md with design review findings.
|
|
373
|
+
`
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: 'trust-audit',
|
|
377
|
+
description: 'Full OWASP Top 10 + GDPR compliance checklist',
|
|
378
|
+
content: (discovery) => `# /trust-audit
|
|
379
|
+
|
|
380
|
+
Perform a comprehensive security and compliance audit.
|
|
381
|
+
|
|
382
|
+
## Steps
|
|
383
|
+
|
|
384
|
+
1. **OWASP Top 10 scan:**
|
|
385
|
+
- Broken access control: check all API routes for auth
|
|
386
|
+
- Injection: check for unsanitized user input in queries
|
|
387
|
+
- XSS: check for unescaped user content in templates
|
|
388
|
+
- SSRF: check for user-provided URLs
|
|
389
|
+
- Security misconfiguration: check CORS, headers, debug mode
|
|
390
|
+
|
|
391
|
+
2. **Secrets scan:**
|
|
392
|
+
- Search for hardcoded API keys, passwords, tokens
|
|
393
|
+
- Verify .env.local is in .gitignore
|
|
394
|
+
- Check for secrets in git history
|
|
395
|
+
|
|
396
|
+
3. **GDPR compliance:**
|
|
397
|
+
- Consent mechanisms present
|
|
398
|
+
- Data export capability
|
|
399
|
+
- Data deletion capability
|
|
400
|
+
- Privacy policy referenced
|
|
401
|
+
- Data minimization practiced
|
|
402
|
+
|
|
403
|
+
4. **Dependency audit:**
|
|
404
|
+
- Run \`npm audit\`
|
|
405
|
+
- Check for known vulnerabilities
|
|
406
|
+
|
|
407
|
+
## Project Context
|
|
408
|
+
|
|
409
|
+
**Industry:** ${discovery.context.industry || 'Not specified'}
|
|
410
|
+
**Data Handled:** ${discovery.availableData.join(', ') || 'Not specified'}
|
|
411
|
+
|
|
412
|
+
## Output
|
|
413
|
+
|
|
414
|
+
Security report with severity levels. Update CLAUDE.md with audit findings.
|
|
415
|
+
`
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
name: 'efficiency-review',
|
|
419
|
+
description: 'Bundle size, Core Web Vitals, N+1 queries, and cost report',
|
|
420
|
+
content: () => `# /efficiency-review
|
|
421
|
+
|
|
422
|
+
Perform a comprehensive efficiency audit.
|
|
423
|
+
|
|
424
|
+
## Steps
|
|
425
|
+
|
|
426
|
+
1. **Bundle analysis:**
|
|
427
|
+
- Run \`npx next build\` and check output sizes
|
|
428
|
+
- Identify largest dependencies
|
|
429
|
+
- Check for unnecessary imports
|
|
430
|
+
|
|
431
|
+
2. **Core Web Vitals:**
|
|
432
|
+
- Check LCP: largest content paint targets
|
|
433
|
+
- Check CLS: layout shift sources
|
|
434
|
+
- Check FID: main thread blocking
|
|
435
|
+
|
|
436
|
+
3. **Database queries:**
|
|
437
|
+
- Search for N+1 patterns (queries in loops)
|
|
438
|
+
- Check for missing indexes
|
|
439
|
+
- Verify batch operations where possible
|
|
440
|
+
|
|
441
|
+
4. **API cost estimate:**
|
|
442
|
+
- Count LLM call sites
|
|
443
|
+
- Estimate tokens per call
|
|
444
|
+
- Check for caching opportunities
|
|
445
|
+
|
|
446
|
+
5. **Caching opportunities:**
|
|
447
|
+
- Static data that could be cached
|
|
448
|
+
- Repeated API calls
|
|
449
|
+
- Expensive computations
|
|
450
|
+
|
|
451
|
+
## Output
|
|
452
|
+
|
|
453
|
+
Efficiency report with metrics and recommendations. Update CLAUDE.md with performance findings.
|
|
454
|
+
`
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: 'testing-verify',
|
|
458
|
+
description: 'Run full test suite and report failures',
|
|
459
|
+
content: () => `# /testing-verify
|
|
460
|
+
|
|
461
|
+
Run the complete test suite and report results.
|
|
462
|
+
|
|
463
|
+
## Steps
|
|
464
|
+
|
|
465
|
+
1. Run unit tests:
|
|
466
|
+
\`\`\`bash
|
|
467
|
+
npm test -- --run
|
|
468
|
+
\`\`\`
|
|
469
|
+
|
|
470
|
+
2. Run E2E tests (if Playwright is configured):
|
|
471
|
+
\`\`\`bash
|
|
472
|
+
npx playwright test
|
|
473
|
+
\`\`\`
|
|
474
|
+
|
|
475
|
+
3. Run type checking:
|
|
476
|
+
\`\`\`bash
|
|
477
|
+
npx tsc --noEmit
|
|
478
|
+
\`\`\`
|
|
479
|
+
|
|
480
|
+
4. Report results:
|
|
481
|
+
- Total tests: passed / failed / skipped
|
|
482
|
+
- Failed test details with file paths
|
|
483
|
+
- Type errors with file paths
|
|
484
|
+
- Suggestions for fixing failures
|
|
485
|
+
|
|
486
|
+
5. If any tests fail, do NOT mark the task as complete.
|
|
487
|
+
|
|
488
|
+
## Output
|
|
489
|
+
|
|
490
|
+
Test report with pass/fail counts. Update CLAUDE.md with test coverage status.
|
|
491
|
+
`
|
|
492
|
+
}
|
|
493
|
+
];
|
|
494
|
+
function generateSkillFrontmatter(skill) {
|
|
495
|
+
return `---
|
|
496
|
+
name: ${skill.name}
|
|
497
|
+
description: ${skill.description}
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
`;
|
|
501
|
+
}
|
|
502
|
+
export function generateSkillCommands(discovery) {
|
|
503
|
+
const files = {};
|
|
504
|
+
for (const skill of [...INIT_SKILLS, ...REVIEW_SKILLS]) {
|
|
505
|
+
files[`.claude/skills/${skill.name}/SKILL.md`] = generateSkillFrontmatter(skill) + skill.content(discovery);
|
|
506
|
+
}
|
|
507
|
+
return files;
|
|
508
|
+
}
|
|
509
|
+
//# sourceMappingURL=skill-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-commands.js","sourceRoot":"","sources":["../../../src/scaffold/templates/skill-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DiscoveryResult } from '../../discovery/types.js';
|
|
2
|
+
import type { SelectionResult } from '../../catalog/types.js';
|
|
3
|
+
export declare function createStrategyPrompt(discovery: DiscoveryResult): string;
|
|
4
|
+
export declare function createDesignPrompt(discovery: DiscoveryResult): string;
|
|
5
|
+
export declare function createTrustPrompt(discovery: DiscoveryResult): string;
|
|
6
|
+
export declare function createEfficiencyPrompt(discovery: DiscoveryResult, tools?: SelectionResult): string;
|
|
7
|
+
export declare function createTestingPrompt(discovery: DiscoveryResult): string;
|
|
8
|
+
//# sourceMappingURL=teammate-prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teammate-prompts.d.ts","sourceRoot":"","sources":["../../../src/scaffold/templates/teammate-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAsHvE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAuHrE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAwFpE;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,MAAM,CAuFlG;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CA4FtE"}
|