super-ux 0.4.0 → 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/CHANGELOG.md +47 -0
- package/README.md +45 -28
- package/bin/super-ux.js +140 -31
- package/cursor/rules/super-ux.mdc +9 -6
- package/cursor/rules/ux-foundation.mdc +47 -0
- package/cursor/rules/ux-scenarios.mdc +6 -1
- package/package.json +25 -5
- package/templates/foundation.md +39 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,53 @@ All notable changes to this project are documented in this file. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions
|
|
5
5
|
follow [SemVer](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.7.0] - 2026-07-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Best-practices catalog** (`skills/references/best-practices.md`) — a
|
|
12
|
+
living, tag-indexed catalog (48 entries seeded from "48 Laws of
|
|
13
|
+
Subscription App Success", Botsi 2025): each practice has an ID (BP-NNN),
|
|
14
|
+
own-words summary, mechanism, applicability, and tags (stage / mechanism /
|
|
15
|
+
domain / effect) so agents can select what fits the product. Growable per
|
|
16
|
+
in-file rules.
|
|
17
|
+
- Integration: `ux-scenarios` consults the catalog when drafting (practices
|
|
18
|
+
applied only when they serve a traced job); `ux-foundation` uses it for
|
|
19
|
+
journey opportunities; `ux-audit` gains an optional practices pass
|
|
20
|
+
(suggestion findings `[BP-NNN]`, never blockers); `/ux` menu gains a
|
|
21
|
+
"Best-practices review" action.
|
|
22
|
+
|
|
23
|
+
## [0.6.0] - 2026-07-20
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **ux-foundation skill** — the WHY layer: personas, Jobs to Be Done (with
|
|
28
|
+
forces and success metrics), customer journey maps (stage / action /
|
|
29
|
+
touchpoint / emotion / pain / opportunity), user stories (INVEST,
|
|
30
|
+
Given/When/Then acceptance criteria). New file contract
|
|
31
|
+
`docs/ux/foundation.md`, template, `/ux-foundation` command, Cursor rule.
|
|
32
|
+
- **ux-contract v2** — scenarios gain a `Traces:` field (story/job/journey
|
|
33
|
+
stage) and traceability rules: every must/should story covered, every
|
|
34
|
+
scenario serves a story or job; orphans are findings.
|
|
35
|
+
- **Full-context audits** — `ux-audit` loads traced acceptance criteria as
|
|
36
|
+
checks and judges whether the implementation serves the job, not just
|
|
37
|
+
renders elements; new `coverage` scope audits the chain itself; fix plans
|
|
38
|
+
prioritized by Frequency × Severity × Solvability.
|
|
39
|
+
- **`/ux` action menu** — single entry point now reports status across all
|
|
40
|
+
three layers and offers the applicable actions (init/update foundation,
|
|
41
|
+
build scenarios, validate chain, audit, coverage audit, plan fixes) with
|
|
42
|
+
one recommended default.
|
|
43
|
+
|
|
44
|
+
## [0.5.0] - 2026-07-19
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- Installer menu is now a real multi-select: arrow keys / j k to move, space
|
|
49
|
+
or number to toggle, `a` selects all three targets at once, enter installs
|
|
50
|
+
the whole selection in one run (own questions asked up front, the external
|
|
51
|
+
skills-CLI picker runs last). Non-TTY stdin gets a text fallback
|
|
52
|
+
(`1,3` / `all` / `q`). Zero dependencies (stdlib raw-mode).
|
|
53
|
+
|
|
7
54
|
## [0.4.0] - 2026-07-19
|
|
8
55
|
|
|
9
56
|
### Added
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# super-ux
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/super-ux)
|
|
4
|
+
[](https://github.com/ssheleg/super-ux/actions/workflows/validate.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
Scenario-driven UI development for AI agents (Claude Code + Cursor).
|
|
4
8
|
|
|
5
9
|
AI agents generate poor interfaces because they build UI without a model of
|
|
@@ -13,25 +17,29 @@ the codebase.
|
|
|
13
17
|
|
|
14
18
|
```mermaid
|
|
15
19
|
flowchart LR
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
W[Personas + JTBD\n+ journeys + stories] --> B[Derive scenarios\nwith Traces]
|
|
21
|
+
A[Feature idea] --> V{Which job? Which stage?\nValidate vs base}
|
|
22
|
+
W --> V
|
|
23
|
+
V -->|approved| D[Design & build UI]
|
|
19
24
|
D --> E[Update scenarios\nin the same change]
|
|
20
|
-
E --> F[/ux-audit:
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
E --> F[/ux-audit: code vs scenarios\nwith story acceptance criteria/]
|
|
26
|
+
B --> F
|
|
27
|
+
F --> G[Report + findings]
|
|
28
|
+
G --> H[Prioritized fix plan\nFreq × Severity × Solvability] --> D
|
|
23
29
|
```
|
|
24
30
|
|
|
25
31
|
## What's inside
|
|
26
32
|
|
|
27
33
|
| Piece | Purpose |
|
|
28
34
|
|---|---|
|
|
29
|
-
| skill `ux-
|
|
30
|
-
| skill `ux-
|
|
31
|
-
|
|
|
32
|
-
| `/ux
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
+
| skill `ux-foundation` | The WHY layer (`docs/ux/foundation.md`): personas, Jobs to Be Done with forces, customer journey maps, user stories with Given/When/Then acceptance criteria |
|
|
36
|
+
| skill `ux-scenarios` | Maintain `docs/ux/scenarios.md`: scenarios derived from stories/journeys with `Traces:`, updated on every change, validated for conflicts, coverage, and traceability |
|
|
37
|
+
| skill `ux-audit` | Batched audit loop with full context: code vs every scenario + its story's acceptance criteria; verdicts PASS/PARTIAL/FAIL/BLOCKED with `file:line` evidence; `coverage` scope audits the chain itself |
|
|
38
|
+
| `/ux` | **The one command**: sets up whatever is missing, then status across all layers + a menu of applicable actions with one recommended default. Idempotent |
|
|
39
|
+
| `/ux-foundation` `/ux-init` `/ux-update` `/ux-audit` `/ux-rule` | Direct controls; `/ux-rule` installs the hard rule into the project's CLAUDE.md |
|
|
40
|
+
| `cursor/rules/*.mdc` | The same methodology for Cursor (always-on hard rule + three agent-requested rules) |
|
|
41
|
+
| `templates/` | Skeletons for the foundation, scenario base, audit report, and the CLAUDE.md rule snippet |
|
|
42
|
+
| [best-practices.md](plugins/super-ux/skills/references/best-practices.md) | Living, tag-indexed catalog of proven UX/growth practices (seeded with 48 subscription-app laws); agents filter by stage/domain tags and apply what serves a traced job |
|
|
35
43
|
|
|
36
44
|
The format all of them share is locked in
|
|
37
45
|
[scenario-format.md](plugins/super-ux/skills/references/scenario-format.md):
|
|
@@ -80,9 +88,10 @@ methods below.
|
|
|
80
88
|
npx super-ux
|
|
81
89
|
```
|
|
82
90
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
Multi-select menu (space to toggle, `a` = everything at once, enter to
|
|
92
|
+
install): skills for any of 70+ agents (delegates to the `skills` CLI picker
|
|
93
|
+
— choose agents and global/project there), Cursor rules into a project, and
|
|
94
|
+
the Claude Code plugin user-globally — any combination in one run.
|
|
86
95
|
|
|
87
96
|
### Cursor
|
|
88
97
|
|
|
@@ -98,16 +107,20 @@ rules after a new release.
|
|
|
98
107
|
|
|
99
108
|
## Typical cycle
|
|
100
109
|
|
|
101
|
-
1. `/ux` — first run sets everything up
|
|
102
|
-
interview
|
|
103
|
-
|
|
110
|
+
1. `/ux` — first run sets everything up: foundation first (greenfield:
|
|
111
|
+
interview about personas, jobs, journeys; existing code:
|
|
112
|
+
reverse-engineer them), then scenarios derived from the stories with
|
|
113
|
+
full traceability.
|
|
104
114
|
2. Work normally; every user-facing change updates the base in the same
|
|
105
115
|
change (the always-on rule catches it; `/ux-update` for manual control).
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
New feature ideas are validated against the chain first: which job,
|
|
117
|
+
which journey stage, which story.
|
|
118
|
+
3. `/ux` any time — status across layers + action menu; `/ux-audit` —
|
|
119
|
+
batched verification of code vs scenarios (with acceptance criteria);
|
|
120
|
+
`/ux-audit coverage` — chain gaps. Reports land in
|
|
121
|
+
`docs/ux/audits/YYYY-MM-DD.md`.
|
|
122
|
+
4. Findings become a prioritized fix plan (Frequency × Severity ×
|
|
123
|
+
Solvability) via your planning workflow; build; repeat.
|
|
111
124
|
|
|
112
125
|
## Development
|
|
113
126
|
|
|
@@ -119,11 +132,15 @@ is semver; bump `marketplace.json` + `plugin.json` + `CHANGELOG.md` together
|
|
|
119
132
|
## По-русски (коротко)
|
|
120
133
|
|
|
121
134
|
Проблема: агенты генерируют плохие интерфейсы, потому что строят UI без
|
|
122
|
-
модели поведения пользователя. super-ux
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
135
|
+
модели поведения пользователя. super-ux строит цепочку: **персоны → JTBD →
|
|
136
|
+
карта пути → user stories → UX-сценарии → аудиты → планы фиксов**.
|
|
137
|
+
Foundation (`docs/ux/foundation.md`) отвечает на «зачем», сценарии
|
|
138
|
+
(`docs/ux/scenarios.md`) — источник правды поведения, трассируются к
|
|
139
|
+
stories. Всё пишется и валидируется **до** интерфейса, обновляется тем же
|
|
140
|
+
изменением, что и поведение. Аудиты (`/ux-audit`) проверяют код против
|
|
141
|
+
сценариев вместе с acceptance criteria, вердикты PASS/PARTIAL/FAIL/BLOCKED
|
|
142
|
+
с доказательствами `file:line`; `/ux-audit coverage` ищет дыры в самой
|
|
143
|
+
цепочке. Установка: в
|
|
127
144
|
Claude Code — `/plugin marketplace add ssheleg/super-ux`, в Cursor —
|
|
128
145
|
`npx super-ux --cursor <проект>`. Дальше одна команда — `/ux`: сама ставит
|
|
129
146
|
правило и базу, а при повторных запусках показывает статус и следующий шаг.
|
package/bin/super-ux.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
/*
|
|
3
3
|
* super-ux installer CLI.
|
|
4
4
|
*
|
|
5
|
-
* No arguments: interactive menu (
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* No arguments: interactive multi-select menu (arrow keys + space, `a` for
|
|
6
|
+
* all) covering: skills for any agent via the `skills` CLI picker, Cursor
|
|
7
|
+
* rules into a project, Claude Code plugin user-globally. Non-TTY stdin gets
|
|
8
|
+
* a text fallback ("1,3" / "all"). Flags keep the non-interactive paths:
|
|
9
|
+
* --cursor [dir] [--force].
|
|
8
10
|
*/
|
|
9
11
|
'use strict';
|
|
10
12
|
|
|
@@ -16,15 +18,21 @@ const { spawnSync } = require('child_process');
|
|
|
16
18
|
const ROOT = path.resolve(__dirname, '..');
|
|
17
19
|
const REPO = 'ssheleg/super-ux';
|
|
18
20
|
|
|
21
|
+
const MENU_ITEMS = [
|
|
22
|
+
{ key: 'skills', label: 'Skills for any AI agent (Claude Code, Codex, Cursor, 70+ — opens agent picker)' },
|
|
23
|
+
{ key: 'cursor', label: 'Cursor rules (always-on hard rule + docs/ux skeleton) into a project' },
|
|
24
|
+
{ key: 'claude', label: 'Claude Code plugin (skills + /ux commands, user-global)' },
|
|
25
|
+
];
|
|
26
|
+
|
|
19
27
|
function usage() {
|
|
20
28
|
console.log(`super-ux installer
|
|
21
29
|
|
|
22
30
|
Usage:
|
|
23
|
-
npx super-ux interactive menu
|
|
31
|
+
npx super-ux interactive menu (multi-select)
|
|
24
32
|
npx super-ux --cursor [project-dir] [--force] Cursor rules, non-interactive
|
|
25
33
|
npx super-ux --help
|
|
26
34
|
|
|
27
|
-
Menu
|
|
35
|
+
Menu items (select any combination, 'a' = all):
|
|
28
36
|
1. Skills for any AI agent (Claude Code, Codex, Cursor, 70+) — delegates to
|
|
29
37
|
'npx skills add ${REPO}' with its agent/global/project picker.
|
|
30
38
|
2. Cursor rules: cursor/rules/*.mdc -> <project>/.cursor/rules/ plus the
|
|
@@ -85,12 +93,13 @@ function run(cmd, args) {
|
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
function installSkillsCli() {
|
|
88
|
-
console.log(
|
|
96
|
+
console.log(`\n--- Skills for any agent: delegating to the skills CLI picker ---`);
|
|
89
97
|
const status = run('npx', ['--yes', 'skills', 'add', REPO]);
|
|
90
|
-
if (status !== 'ok')
|
|
98
|
+
if (status !== 'ok') console.error(`warning: 'npx skills add ${REPO}' ${status}`);
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
function installClaudePlugin() {
|
|
102
|
+
console.log(`\n--- Claude Code plugin ---`);
|
|
94
103
|
const probe = spawnSync('claude', ['--version'], { stdio: 'ignore' });
|
|
95
104
|
if (probe.error && probe.error.code === 'ENOENT') {
|
|
96
105
|
console.log(`claude CLI not found. Run inside Claude Code instead:
|
|
@@ -104,14 +113,13 @@ function installClaudePlugin() {
|
|
|
104
113
|
if (run('claude', ['plugin', 'install', 'super-ux@super-ux']) === 'ok') {
|
|
105
114
|
console.log('Claude Code plugin installed (scope: user). Restart sessions to pick it up; then run /ux in any project.');
|
|
106
115
|
} else {
|
|
107
|
-
|
|
116
|
+
console.error('warning: claude plugin install failed — see output above');
|
|
108
117
|
}
|
|
109
118
|
}
|
|
110
119
|
|
|
111
120
|
function makePrompter() {
|
|
112
121
|
// A persistent 'line' listener with a buffer: with piped stdin, lines that
|
|
113
|
-
// arrive between two questions are kept instead of being lost
|
|
114
|
-
// what plain sequential rl.question() does).
|
|
122
|
+
// arrive between two questions are kept instead of being lost.
|
|
115
123
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
116
124
|
const buffered = [];
|
|
117
125
|
let pending = null;
|
|
@@ -148,30 +156,131 @@ function makePrompter() {
|
|
|
148
156
|
};
|
|
149
157
|
}
|
|
150
158
|
|
|
159
|
+
function parseSelection(input, count) {
|
|
160
|
+
const value = input.trim().toLowerCase();
|
|
161
|
+
if (value === '' || value === 'q' || value === 'quit') return [];
|
|
162
|
+
if (value === 'a' || value === 'all' || value === '*') {
|
|
163
|
+
return Array.from({ length: count }, (_, i) => i);
|
|
164
|
+
}
|
|
165
|
+
const picked = new Set();
|
|
166
|
+
for (const part of value.split(/[\s,]+/)) {
|
|
167
|
+
if (part === '') continue;
|
|
168
|
+
const n = Number(part);
|
|
169
|
+
if (!Number.isInteger(n) || n < 1 || n > count) return null;
|
|
170
|
+
picked.add(n - 1);
|
|
171
|
+
}
|
|
172
|
+
return [...picked].sort();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function selectInteractive(items) {
|
|
176
|
+
// Raw-mode checkbox list: up/down or j/k move, space or 1..9 toggle,
|
|
177
|
+
// a = toggle all, enter = confirm, q/esc/ctrl+c = quit.
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
const selected = new Set();
|
|
180
|
+
let cursor = 0;
|
|
181
|
+
let rendered = false;
|
|
182
|
+
|
|
183
|
+
const line = (i) =>
|
|
184
|
+
`${i === cursor ? '❯' : ' '} ${selected.has(i) ? '◉' : '◯'} ${i + 1}) ${items[i].label}`;
|
|
185
|
+
|
|
186
|
+
const render = () => {
|
|
187
|
+
if (rendered) process.stdout.write(`\x1b[${items.length + 1}A`);
|
|
188
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
189
|
+
process.stdout.write(`\x1b[2K${line(i)}\n`);
|
|
190
|
+
}
|
|
191
|
+
process.stdout.write(
|
|
192
|
+
'\x1b[2K ↑/↓ move · space/number toggle · a all · enter confirm · q quit\n'
|
|
193
|
+
);
|
|
194
|
+
rendered = true;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const finish = (result) => {
|
|
198
|
+
process.stdin.setRawMode(false);
|
|
199
|
+
process.stdin.pause();
|
|
200
|
+
process.stdin.removeListener('keypress', onKeypress);
|
|
201
|
+
resolve(result);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const onKeypress = (str, key) => {
|
|
205
|
+
const name = key && key.name;
|
|
206
|
+
if ((key && key.ctrl && name === 'c') || name === 'escape' || str === 'q') {
|
|
207
|
+
finish([]);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (name === 'up' || str === 'k') cursor = (cursor - 1 + items.length) % items.length;
|
|
211
|
+
else if (name === 'down' || str === 'j') cursor = (cursor + 1) % items.length;
|
|
212
|
+
else if (name === 'space') {
|
|
213
|
+
if (selected.has(cursor)) selected.delete(cursor);
|
|
214
|
+
else selected.add(cursor);
|
|
215
|
+
} else if (str === 'a') {
|
|
216
|
+
if (selected.size === items.length) selected.clear();
|
|
217
|
+
else for (let i = 0; i < items.length; i += 1) selected.add(i);
|
|
218
|
+
} else if (str && /^[1-9]$/.test(str) && Number(str) <= items.length) {
|
|
219
|
+
const idx = Number(str) - 1;
|
|
220
|
+
if (selected.has(idx)) selected.delete(idx);
|
|
221
|
+
else selected.add(idx);
|
|
222
|
+
cursor = idx;
|
|
223
|
+
} else if (name === 'return') {
|
|
224
|
+
finish([...selected].sort());
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
render();
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
readline.emitKeypressEvents(process.stdin);
|
|
231
|
+
process.stdin.setRawMode(true);
|
|
232
|
+
process.stdin.resume();
|
|
233
|
+
process.stdin.on('keypress', onKeypress);
|
|
234
|
+
render();
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function selectFallback(items, prompter) {
|
|
239
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
240
|
+
console.log(` ${i + 1}) ${items[i].label}`);
|
|
241
|
+
}
|
|
242
|
+
const answer = await prompter.ask(`Select [e.g. 1,3 | all | q]: `);
|
|
243
|
+
const picked = parseSelection(answer, items.length);
|
|
244
|
+
if (picked === null) fail(`invalid selection '${answer.trim()}'`);
|
|
245
|
+
return picked;
|
|
246
|
+
}
|
|
247
|
+
|
|
151
248
|
async function menu() {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (choice === '1') {
|
|
162
|
-
prompter.close();
|
|
163
|
-
installSkillsCli();
|
|
164
|
-
} else if (choice === '2') {
|
|
165
|
-
const dir = (await prompter.ask('Project directory [.]: ')).trim() || '.';
|
|
166
|
-
prompter.close();
|
|
167
|
-
installCursor(path.resolve(dir), false);
|
|
168
|
-
} else if (choice === '3') {
|
|
169
|
-
prompter.close();
|
|
170
|
-
installClaudePlugin();
|
|
249
|
+
console.log('super-ux — scenario-driven UI development. Select what to install:\n');
|
|
250
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
251
|
+
|
|
252
|
+
// ONE prompter for the whole flow: with piped stdin, all pending lines are
|
|
253
|
+
// buffered by its persistent listener; a second prompter would lose them.
|
|
254
|
+
let prompter = null;
|
|
255
|
+
let picked;
|
|
256
|
+
if (interactive) {
|
|
257
|
+
picked = await selectInteractive(MENU_ITEMS);
|
|
171
258
|
} else {
|
|
172
|
-
prompter
|
|
173
|
-
|
|
259
|
+
prompter = makePrompter();
|
|
260
|
+
picked = await selectFallback(MENU_ITEMS, prompter);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (picked.length === 0) {
|
|
264
|
+
if (prompter) prompter.close();
|
|
265
|
+
console.log('Nothing selected.');
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const keys = picked.map((i) => MENU_ITEMS[i].key);
|
|
270
|
+
|
|
271
|
+
// Gather all our own questions BEFORE running anything, so they don't
|
|
272
|
+
// interleave with the external skills-CLI picker.
|
|
273
|
+
let cursorDir = null;
|
|
274
|
+
if (keys.includes('cursor')) {
|
|
275
|
+
if (!prompter) prompter = makePrompter();
|
|
276
|
+
const dir = (await prompter.ask('Cursor rules — project directory [.]: ')).trim() || '.';
|
|
277
|
+
cursorDir = path.resolve(dir);
|
|
174
278
|
}
|
|
279
|
+
if (prompter) prompter.close();
|
|
280
|
+
|
|
281
|
+
if (keys.includes('cursor')) installCursor(cursorDir, false);
|
|
282
|
+
if (keys.includes('claude')) installClaudePlugin();
|
|
283
|
+
if (keys.includes('skills')) installSkillsCli();
|
|
175
284
|
}
|
|
176
285
|
|
|
177
286
|
function main() {
|
|
@@ -5,13 +5,16 @@ alwaysApply: true
|
|
|
5
5
|
|
|
6
6
|
# UX scenarios — hard rule (super-ux)
|
|
7
7
|
|
|
8
|
-
- `docs/ux/scenarios.md` is the source of truth for all user-facing behavior
|
|
8
|
+
- `docs/ux/scenarios.md` is the source of truth for all user-facing behavior;
|
|
9
|
+
`docs/ux/foundation.md` (personas, JTBD, journeys, user stories) is the WHY
|
|
10
|
+
layer scenarios trace to.
|
|
9
11
|
- Any change that touches user-facing behavior MUST update
|
|
10
12
|
`docs/ux/scenarios.md` in the same change (add/adjust scenarios, statuses,
|
|
11
13
|
coverage). New user-facing behavior with no scenario is a blocker, not a
|
|
12
14
|
warning.
|
|
13
|
-
- Any new feature or project STARTS with
|
|
14
|
-
|
|
15
|
-
only then design and
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
- Any new feature or project STARTS with the chain: which job does it serve,
|
|
16
|
+
which journey stage, which story — then scenarios, validated against the
|
|
17
|
+
existing base (conflicts, overlaps, gaps), approved — only then design and
|
|
18
|
+
build UI. An idea serving no job is challenged, not silently accepted.
|
|
19
|
+
- Workflows: `ux-foundation` rule (WHY layer), `ux-scenarios` rule
|
|
20
|
+
(scenario base), `ux-audit` rule (evidence-backed audits).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Maintain docs/ux/foundation.md (personas, Jobs to Be Done, customer journeys, user stories): apply when defining who the users are and why they use the product, during product discovery, or when scenarios need a WHY layer to trace to"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ux-foundation — The WHY Layer
|
|
7
|
+
|
|
8
|
+
`docs/ux/foundation.md` holds the chain scenarios trace to: **Personas
|
|
9
|
+
(P-NN) → Jobs to Be Done (JTBD-NN) → Customer journeys (JRN-NN) → User
|
|
10
|
+
stories (ST-NNN)**. IDs sequential, never reused; dropped entries kept, not
|
|
11
|
+
deleted.
|
|
12
|
+
|
|
13
|
+
## Formats (ux-contract v2)
|
|
14
|
+
|
|
15
|
+
- **Persona `P-NN`:** 1–3 sentences, grounded in data/observation,
|
|
16
|
+
recognizable by a real user.
|
|
17
|
+
- **JTBD `JTBD-NN`:** `When <situation>, I want to <motivation>, so I can
|
|
18
|
+
<outcome>` + personas + type (functional|emotional|social) + forces
|
|
19
|
+
(push/pull/anxiety/habit) + success metric (user outcome, never a
|
|
20
|
+
feature).
|
|
21
|
+
- **Journey `JRN-NN`** (persona × job): stage table — `# | Stage | User
|
|
22
|
+
action | Touchpoint | Emotion (1-5) | Pain | Opportunity`; end-to-end
|
|
23
|
+
(before/during/after product); opportunity priority = Frequency ×
|
|
24
|
+
Severity × Solvability.
|
|
25
|
+
- **Story `ST-NNN`:** `As <persona>, I want <capability>, so that
|
|
26
|
+
<benefit>` + Traces (JTBD, JRN/stage) + Given/When/Then acceptance
|
|
27
|
+
criteria + priority (must|should|could) + status
|
|
28
|
+
(proposed|validated|delivered|dropped). Quality bar: INVEST.
|
|
29
|
+
|
|
30
|
+
## Workflows
|
|
31
|
+
|
|
32
|
+
- **Init (interview):** greenfield — ask one question at a time: who uses
|
|
33
|
+
it; what situation triggers the job; what outcome = success; walk the
|
|
34
|
+
path end-to-end; derive stories from pains and outcomes.
|
|
35
|
+
- **Init (reverse):** existing product — reverse-engineer jobs/personas
|
|
36
|
+
from the UI and scenarios; tag entries observed vs inferred; flag
|
|
37
|
+
features serving no job and jobs with no support.
|
|
38
|
+
- **Update:** locate by ID, update, mark dropped (never delete), then
|
|
39
|
+
cascade: list scenarios tracing to changed IDs and update them in the
|
|
40
|
+
same change.
|
|
41
|
+
- **Validate:** integrity (IDs, references), quality (no features in JTBD,
|
|
42
|
+
INVEST, observable criteria), coverage (persona→job→journey→story chain
|
|
43
|
+
complete; must/should stories have scenarios).
|
|
44
|
+
|
|
45
|
+
Evidence beats opinion: mark unvalidated guesses as assumptions
|
|
46
|
+
(desirability/viability/feasibility/usability) and test risky ones before
|
|
47
|
+
building on them.
|
|
@@ -14,7 +14,12 @@ Title, then header comment, then: **Index** table
|
|
|
14
14
|
(`| ID | Title | Feature | Persona | Status | Last audit |`), **Personas**
|
|
15
15
|
(1–3 sentences each), **Scenarios** grouped by feature.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
When `docs/ux/foundation.md` exists, scenarios derive from it: draft per
|
|
18
|
+
user story / journey stage, fill `Traces:` (e.g. `ST-001 (JTBD-01,
|
|
19
|
+
JRN-01/#2)`), enforce traceability — every must/should story covered by ≥1
|
|
20
|
+
scenario, every scenario serves ≥1 story or job.
|
|
21
|
+
|
|
22
|
+
Scenario entry fields (exact names): `Persona`, `Feature`, `Traces`, `Entry point`,
|
|
18
23
|
`Preconditions`, `Steps` (numbered, one user action each), `Expected result`
|
|
19
24
|
(observable), `UI elements` (every button/field/link/dialog/toast involved —
|
|
20
25
|
this is what audits check), `States covered` (loading|empty|error|success),
|
package/package.json
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "super-ux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Scenario-driven UI development for AI agents (Claude Code + Cursor): scenario base, scenario-first hard rule, evidence-backed UX audits. This package is the installer CLI.",
|
|
5
|
-
"bin": {
|
|
6
|
-
|
|
5
|
+
"bin": {
|
|
6
|
+
"super-ux": "bin/super-ux.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"cursor",
|
|
11
|
+
"templates",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
7
16
|
"repository": "github:ssheleg/super-ux",
|
|
8
17
|
"homepage": "https://github.com/ssheleg/super-ux",
|
|
9
18
|
"license": "MIT",
|
|
10
19
|
"author": "ssheleg",
|
|
11
|
-
"engines": {
|
|
12
|
-
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=16"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ux",
|
|
25
|
+
"scenarios",
|
|
26
|
+
"audit",
|
|
27
|
+
"ui",
|
|
28
|
+
"user-flows",
|
|
29
|
+
"scenario-driven",
|
|
30
|
+
"claude-code",
|
|
31
|
+
"cursor"
|
|
32
|
+
]
|
|
13
33
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# UX Foundation
|
|
2
|
+
|
|
3
|
+
<!-- Managed with super-ux (ux-contract v2). The WHY layer: personas, jobs
|
|
4
|
+
to be done, customer journeys, user stories. Update when the understanding
|
|
5
|
+
of users changes; scenarios in scenarios.md trace to the IDs defined here. -->
|
|
6
|
+
|
|
7
|
+
## Personas
|
|
8
|
+
|
|
9
|
+
<!-- ### P-01: <name>
|
|
10
|
+
1-3 sentences: who they are, what they know, what they want. Grounded in
|
|
11
|
+
data/observation, recognizable by a real user. -->
|
|
12
|
+
|
|
13
|
+
## Jobs to Be Done
|
|
14
|
+
|
|
15
|
+
<!-- ### JTBD-01: <short job name>
|
|
16
|
+
- **Statement:** When <situation>, I want to <motivation>, so I can <expected outcome>.
|
|
17
|
+
- **Personas:** P-01
|
|
18
|
+
- **Type:** functional | emotional | social
|
|
19
|
+
- **Forces:** push: <...>; pull: <...>; anxiety: <...>; habit: <...>
|
|
20
|
+
- **Success metric:** <observable user outcome, not a feature>
|
|
21
|
+
-->
|
|
22
|
+
|
|
23
|
+
## Customer journeys
|
|
24
|
+
|
|
25
|
+
<!-- ### JRN-01: <persona> — <job> (JTBD-01)
|
|
26
|
+
| # | Stage | User action | Touchpoint | Emotion (1-5) | Pain | Opportunity |
|
|
27
|
+
|---|-------|------------|------------|---------------|------|-------------|
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
## User stories
|
|
31
|
+
|
|
32
|
+
<!-- ### ST-001: <short name>
|
|
33
|
+
- **Story:** As <persona>, I want <capability>, so that <benefit>.
|
|
34
|
+
- **Traces:** JTBD-01, JRN-01/#2
|
|
35
|
+
- **Acceptance criteria:**
|
|
36
|
+
- Given <precondition>, when <action>, then <observable result>.
|
|
37
|
+
- **Priority:** must | should | could
|
|
38
|
+
- **Status:** proposed
|
|
39
|
+
-->
|