@laith-wallace/crisp 1.0.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/.agents/skills/crisp-audit.md +158 -0
- package/.agents/skills/crisp-review.md +84 -0
- package/.agents/skills/crisp-teach.md +90 -0
- package/.agents/skills/feature-design.md +131 -0
- package/.agents/skills/handoff.md +219 -0
- package/.claude/skills/crisp-audit.md +158 -0
- package/.claude/skills/crisp-review.md +84 -0
- package/.claude/skills/crisp-teach.md +90 -0
- package/.claude/skills/feature-design.md +131 -0
- package/.claude/skills/handoff.md +219 -0
- package/.cursor/rules/crisp-audit.md +158 -0
- package/.cursor/rules/crisp-review.md +84 -0
- package/.cursor/rules/crisp-teach.md +90 -0
- package/.cursor/rules/feature-design.md +131 -0
- package/.cursor/rules/handoff.md +219 -0
- package/.gemini/skills/crisp-audit.md +158 -0
- package/.gemini/skills/crisp-review.md +84 -0
- package/.gemini/skills/crisp-teach.md +90 -0
- package/.gemini/skills/feature-design.md +131 -0
- package/.gemini/skills/handoff.md +219 -0
- package/README.md +66 -0
- package/bin/crisp.mjs +182 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# CRISP — Design Intelligence for AI Agents
|
|
2
|
+
|
|
3
|
+
Five skills that give your AI agent a senior product designer's eye. Drop them into Claude, Cursor, Copilot, or Gemini and get structured design reviews, feature specs, and developer handoffs grounded in the CRISP framework.
|
|
4
|
+
|
|
5
|
+
**CRISP** = Contextual · Responsive · Intelligent · Seamless · Powerful
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Skills
|
|
10
|
+
|
|
11
|
+
| Command | What it does |
|
|
12
|
+
|---------|-------------|
|
|
13
|
+
| `/crisp-teach` | Onboards the AI to your product — users, design system, benchmarks. Writes `.crisp.md` which all other commands read automatically. Run once per project. |
|
|
14
|
+
| `/crisp-review` | 30-second scan. Returns a grade A–F and your top 3 issues with specific fixes. Use during rapid iteration. |
|
|
15
|
+
| `/crisp-audit` | Full CRISP evaluation. Scores all five dimensions, rates violations P0–P3, and benchmarks against Stripe, Linear, Notion, Asana, and Slack. |
|
|
16
|
+
| `/feature-design` | Designs a new feature from scratch using CRISP principles — user flows, component decisions, compliance checks, and open questions. |
|
|
17
|
+
| `/handoff` | Converts a reviewed design into a developer-ready spec — states, tokens, interactions, edge cases, accessibility, and exact copy. |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
### Claude Code
|
|
24
|
+
```bash
|
|
25
|
+
npx skills add laith-wallace/crisp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Cursor
|
|
29
|
+
Copy the contents of `.cursor/rules/` into your project's `.cursor/rules/` folder.
|
|
30
|
+
|
|
31
|
+
### Other agents
|
|
32
|
+
- **GitHub Copilot / Antigravity** — copy from `.agents/skills/`
|
|
33
|
+
- **Gemini** — copy from `.gemini/skills/`
|
|
34
|
+
- **Manual** — copy any `.md` file from `files/` and add it to your agent's context
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## How it works
|
|
39
|
+
|
|
40
|
+
Run `/crisp-teach` first. The AI interviews you about your product, users, and design system, then writes a `.crisp.md` file to your project root. Every subsequent CRISP command reads that file automatically — so reviews and specs are grounded in your specific context, not generic advice.
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
/crisp-teach → writes .crisp.md
|
|
44
|
+
/crisp-review → reads .crisp.md, returns grade + top 3 issues
|
|
45
|
+
/crisp-audit → reads .crisp.md, full scored evaluation
|
|
46
|
+
/feature-design → reads .crisp.md, produces user flow + spec
|
|
47
|
+
/handoff → reads .crisp.md, produces dev-ready spec
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## The CRISP Framework
|
|
53
|
+
|
|
54
|
+
| Dimension | The test |
|
|
55
|
+
|-----------|----------|
|
|
56
|
+
| **C**ontextual | Can the user tell where they are and what this page does within 5 seconds? |
|
|
57
|
+
| **R**esponsive | Does the UI update immediately on every interaction? |
|
|
58
|
+
| **I**ntelligent | Are we showing insight, not raw data? |
|
|
59
|
+
| **S**eamless | Are we fitting into their day — not forcing them into ours? |
|
|
60
|
+
| **P**owerful | Is complexity hidden appropriately for each user type? |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT
|
package/bin/crisp.mjs
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import figlet from 'figlet';
|
|
5
|
+
import { existsSync, mkdirSync, copyFileSync } from 'node:fs';
|
|
6
|
+
import { join, dirname } from 'node:path';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const LIME = '#c8ff3c';
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const PKG_ROOT = join(__dirname, '..');
|
|
13
|
+
|
|
14
|
+
const SKILLS = [
|
|
15
|
+
{ value: 'crisp-teach', label: '/crisp-teach', hint: 'Onboard your AI to your product — writes .crisp.md' },
|
|
16
|
+
{ value: 'crisp-review', label: '/crisp-review', hint: '30-second design scan, A–F grade, top 3 issues' },
|
|
17
|
+
{ value: 'crisp-audit', label: '/crisp-audit', hint: 'Full CRISP evaluation across 5 dimensions' },
|
|
18
|
+
{ value: 'feature-design', label: '/feature-design', hint: 'Design new features using CRISP principles' },
|
|
19
|
+
{ value: 'handoff', label: '/handoff', hint: 'Convert designs to developer-ready specs' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const AGENTS = [
|
|
23
|
+
{
|
|
24
|
+
value: 'claude',
|
|
25
|
+
label: 'Claude Code',
|
|
26
|
+
hint: '~/.claude/skills/',
|
|
27
|
+
src: join(PKG_ROOT, '.claude', 'skills'),
|
|
28
|
+
dest: () => join(homedir(), '.claude', 'skills'),
|
|
29
|
+
detect: () => existsSync(join(homedir(), '.claude')),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
value: 'cursor',
|
|
33
|
+
label: 'Cursor',
|
|
34
|
+
hint: '.cursor/rules/ (current project)',
|
|
35
|
+
src: join(PKG_ROOT, '.cursor', 'rules'),
|
|
36
|
+
dest: () => join(process.cwd(), '.cursor', 'rules'),
|
|
37
|
+
detect: () => existsSync(join(process.cwd(), '.cursor')) || existsSync(join(homedir(), '.cursor')),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: 'antigravity',
|
|
41
|
+
label: 'Antigravity',
|
|
42
|
+
hint: '~/.agents/skills/',
|
|
43
|
+
src: join(PKG_ROOT, '.agents', 'skills'),
|
|
44
|
+
dest: () => join(homedir(), '.agents', 'skills'),
|
|
45
|
+
detect: () => existsSync(join(homedir(), '.agents')),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
value: 'gemini',
|
|
49
|
+
label: 'Gemini CLI',
|
|
50
|
+
hint: '~/.gemini/skills/',
|
|
51
|
+
src: join(PKG_ROOT, '.gemini', 'skills'),
|
|
52
|
+
dest: () => join(homedir(), '.gemini', 'skills'),
|
|
53
|
+
detect: () => existsSync(join(homedir(), '.gemini')),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: 'manual',
|
|
57
|
+
label: 'Manual copy',
|
|
58
|
+
hint: 'Show file paths — copy yourself',
|
|
59
|
+
src: join(PKG_ROOT, 'files'),
|
|
60
|
+
dest: () => null,
|
|
61
|
+
detect: () => false,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
function logo() {
|
|
66
|
+
const art = figlet.textSync('CRISP', { font: 'ANSI Shadow' });
|
|
67
|
+
return chalk.hex(LIME)(art);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function cancelIfNeeded(value) {
|
|
71
|
+
if (p.isCancel(value)) {
|
|
72
|
+
p.cancel('Installation cancelled.');
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function main() {
|
|
79
|
+
console.log('\n' + logo());
|
|
80
|
+
console.log(chalk.hex(LIME).dim(' Design Intelligence for AI Agents\n'));
|
|
81
|
+
|
|
82
|
+
p.intro(chalk.hex(LIME)('CRISP Installer'));
|
|
83
|
+
|
|
84
|
+
// Skill selection
|
|
85
|
+
const selectedSkills = cancelIfNeeded(
|
|
86
|
+
await p.multiselect({
|
|
87
|
+
message: 'Which skills do you want to install?',
|
|
88
|
+
options: SKILLS.map(s => ({ ...s, initialChecked: true })),
|
|
89
|
+
initialValues: SKILLS.map(s => s.value),
|
|
90
|
+
required: true,
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Agent selection — pre-select detected agents
|
|
95
|
+
const detectedValues = AGENTS.filter(a => a.detect()).map(a => a.value);
|
|
96
|
+
|
|
97
|
+
const selectedAgentValues = cancelIfNeeded(
|
|
98
|
+
await p.multiselect({
|
|
99
|
+
message: 'Install to which agents?',
|
|
100
|
+
options: AGENTS.map(a => ({
|
|
101
|
+
value: a.value,
|
|
102
|
+
label: a.label,
|
|
103
|
+
hint: a.detect()
|
|
104
|
+
? chalk.hex(LIME)('✓ detected') + chalk.dim(' ' + a.hint)
|
|
105
|
+
: chalk.dim(a.hint),
|
|
106
|
+
})),
|
|
107
|
+
initialValues: detectedValues.length > 0 ? detectedValues : ['manual'],
|
|
108
|
+
required: true,
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const selectedAgents = AGENTS.filter(a => selectedAgentValues.includes(a.value));
|
|
113
|
+
const results = {};
|
|
114
|
+
|
|
115
|
+
const spinner = p.spinner();
|
|
116
|
+
spinner.start('Installing skills…');
|
|
117
|
+
|
|
118
|
+
for (const agent of selectedAgents) {
|
|
119
|
+
results[agent.value] = { agent, files: [] };
|
|
120
|
+
|
|
121
|
+
if (agent.value === 'manual') continue;
|
|
122
|
+
|
|
123
|
+
const dest = agent.dest();
|
|
124
|
+
try {
|
|
125
|
+
mkdirSync(dest, { recursive: true });
|
|
126
|
+
} catch (e) {
|
|
127
|
+
results[agent.value].error = `Could not create ${dest}: ${e.message}`;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (const skill of selectedSkills) {
|
|
132
|
+
const src = join(agent.src, skill + '.md');
|
|
133
|
+
const dst = join(dest, skill + '.md');
|
|
134
|
+
try {
|
|
135
|
+
copyFileSync(src, dst);
|
|
136
|
+
results[agent.value].files.push({ skill, path: dst, ok: true });
|
|
137
|
+
} catch (e) {
|
|
138
|
+
results[agent.value].files.push({ skill, path: dst, ok: false, error: e.message });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
spinner.stop(chalk.hex(LIME)('Skills installed'));
|
|
144
|
+
|
|
145
|
+
// Summary
|
|
146
|
+
for (const [, { agent, files, error }] of Object.entries(results)) {
|
|
147
|
+
if (agent.value === 'manual') {
|
|
148
|
+
console.log('\n' + chalk.dim(' ── Manual copy ──'));
|
|
149
|
+
for (const skill of selectedSkills) {
|
|
150
|
+
const src = join(agent.src, skill + '.md');
|
|
151
|
+
console.log(' ' + chalk.dim(src));
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (error) {
|
|
157
|
+
console.log('\n' + chalk.red(` ✗ ${agent.label}: ${error}`));
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('\n' + chalk.dim(` ── ${agent.label} ──`));
|
|
162
|
+
for (const f of files) {
|
|
163
|
+
if (f.ok) {
|
|
164
|
+
console.log(' ' + chalk.hex(LIME)('✓') + ' ' + chalk.dim(f.path));
|
|
165
|
+
} else {
|
|
166
|
+
console.log(' ' + chalk.red('✗') + ' ' + f.skill + chalk.red(` — ${f.error}`));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
p.outro(
|
|
172
|
+
chalk.hex(LIME)('Done.') +
|
|
173
|
+
chalk.dim(' Run ') +
|
|
174
|
+
chalk.hex(LIME)('/crisp-teach') +
|
|
175
|
+
chalk.dim(' in your agent to get started.')
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
main().catch(e => {
|
|
180
|
+
console.error(chalk.red('Error: ' + e.message));
|
|
181
|
+
process.exit(1);
|
|
182
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@laith-wallace/crisp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CRISP design intelligence skills for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"crisp": "./bin/crisp.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
".claude/skills/",
|
|
12
|
+
".cursor/rules/",
|
|
13
|
+
".agents/skills/",
|
|
14
|
+
".gemini/skills/"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@clack/prompts": "^0.9.0",
|
|
21
|
+
"chalk": "^5.3.0",
|
|
22
|
+
"figlet": "^1.7.0"
|
|
23
|
+
},
|
|
24
|
+
"keywords": ["design", "ux", "ai", "skills", "claude", "cursor", "crisp"],
|
|
25
|
+
"author": "Laith Wallace",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/laith-wallace/crisp"
|
|
30
|
+
}
|
|
31
|
+
}
|