super-ux 0.19.0 → 0.23.2

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 CHANGED
@@ -1,5 +1,197 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.23.2 — 2026-07-28
4
+
5
+ Open-source hygiene pass — the repo is public, so the files a first-time
6
+ contributor looks for now exist.
7
+
8
+ ### Added
9
+ - `SECURITY.md` — what the skill and its installer actually run (two `claude`
10
+ calls, explicit argv, no network from the linter), what they write, and private
11
+ reporting.
12
+ - `CODE_OF_CONDUCT.md` and a pull-request template that asks for the command
13
+ output rather than a "tests pass" claim.
14
+ - README now points at the security policy and the code of conduct alongside
15
+ contributing.
16
+
17
+ ## 0.23.1 — 2026-07-28
18
+
19
+ ### Changed
20
+ - Consistent American spelling across every agent-facing file (`labour` →
21
+ `labor`, `honour` → `honor`, `neighbouring` → `neighboring`) — the docs
22
+ were mixing both, which reads as sloppy in a repo whose whole pitch is that
23
+ small inconsistencies compound.
24
+ - Reflowed three paragraphs left ragged by the previous pass's mechanical
25
+ edits (`figma-integration.md` intro, the `ux-flows` build gate), and the
26
+ build gate now names the style pack alongside the chain and the Figma
27
+ mockups.
28
+
29
+ ## 0.23.0 — 2026-07-28
30
+
31
+ Production pass over the public repo: every file read again, the remaining
32
+ contradictions fixed, and the front door rewritten for people who have never
33
+ seen this project.
34
+
35
+ ### Fixed
36
+ - **The hard rule described a three-layer chain.** The most-copied text in the
37
+ project — the rule installed into every `CLAUDE.md`, the always-on Cursor
38
+ rule, the README, `/ux-rule`, the `ux-flows` build gate — said
39
+ "foundation → flows → scenarios" while `screens.md` has been a first-class
40
+ layer with its own same-change rule since 0.16.0. All five copies now say
41
+ foundation → flows → **screens** → scenarios.
42
+ - **`ux-foundation` didn't know about a section it owns.** The contract gives
43
+ `foundation.md` a Design tooling block (Figma on/off + file URL), but
44
+ neither the skill nor its Cursor rule ever mentioned it, so the field was
45
+ only ever filled by whoever happened to read the template. Both now cover it
46
+ — and state that everything else visual (design system, style pack, frame
47
+ links) belongs to `screens.md`.
48
+ - The README's mermaid diagram used `\n` for line breaks, which GitHub renders
49
+ literally; it is `<br/>` now — and the diagram shows the current chain
50
+ (foundation → flows → screens → scenarios → build → audit → plan) instead of
51
+ the pre-flows one.
52
+ - `/ux`'s own description advertised "foundation/scenarios/audits"; menu item 3
53
+ said "design user flows" without mentioning that it also registers screens.
54
+ Inspect now also reports unexecuted plans in `docs/ux/plans/`.
55
+ - `ux-flows` Design had visual identity, wireframes, and Figma crammed into one
56
+ numbered step; identity is now its own step, before anything gets drawn.
57
+
58
+ ### Added
59
+ - **[CONTRIBUTING.md](CONTRIBUTING.md)** — repo layout (including *why* the
60
+ contracts are duplicated per skill), the edit → sync → validate loop, the
61
+ conventions, how to test a change from a packed tarball rather than the
62
+ working tree, and the release checklist.
63
+ - Issue templates for bug reports and ideas, both asking for the thing that
64
+ actually resolves a report: the file that says otherwise, and the check that
65
+ would fail.
66
+ - Validator check: the plugin description in `marketplace.json` must equal the
67
+ one in `plugin.json` — the ecosystem requires both copies, so the duplication
68
+ gets a check instead of trust.
69
+ - `package.json` gains a `bugs` URL; `.gitignore` covers `npm pack` tarballs.
70
+
71
+ ### Changed
72
+ - **README restructured for a first-time reader**: what goes wrong and what
73
+ super-ux does about it, the chain diagram, what you get, quick start per
74
+ channel, the hard rule, the typical cycle, companions, then the internals
75
+ (skills, commands, and a second table for the contracts). Value first,
76
+ reference last.
77
+ - Manifest descriptions rewritten to describe the current system — the whole
78
+ chain, the four skills, the linter, and the style pack — instead of the
79
+ 0.17-era feature list.
80
+ - The historical `docs/superpowers/` spec and plan carry a banner marking them
81
+ as v0.1.0 provenance, with pointers to the live contract; they described two
82
+ skills and four commands and are not maintained.
83
+
84
+ ## 0.22.0 — 2026-07-28
85
+
86
+ ### Added
87
+ - **The visual layer has an owner: the `sheleg-design` companion.** super-ux
88
+ decided what every screen must contain and which craft floors it had to
89
+ clear, then left the actual look to be invented frame by frame — the visual
90
+ half of the drift this system exists to prevent. New reference
91
+ [`visual-identity.md`](plugins/super-ux/skills/references/visual-identity.md)
92
+ makes one **style pack** the identity for the whole product: picked with the
93
+ sheleg-design skill (`workbench` for product UI, dashboards and tools;
94
+ `instrument-console`; `editorial-luxury`; or a new pack authored on its
95
+ contract), recorded once, obeyed everywhere. A cinematic scroll-driven
96
+ landing also takes that skill's motion methodology.
97
+ - **`Style pack` field** in `screens.md` → Design system (contract + template).
98
+ One owner per fact: the pack is named there and referenced from everywhere
99
+ else, with its token file location beside it.
100
+ - **Wired into every design entry point** — `ux-flows` Design (before a frame
101
+ is drawn, not after), `/ux` step 0 beside the Figma question, `/ux-flows`,
102
+ the Figma design loop (pack tokens become the Figma variable collections),
103
+ the Cursor `ux-flows` rule, the hard rule in `templates/claude-rule.md` and
104
+ `/ux-rule`, and the seeded `docs/ux/README.md`.
105
+ - **Audited like any other record.** When a `Style pack` is recorded, the deep
106
+ audit's practice pass checks the built UI honors it — tokens referenced
107
+ instead of raw values, the pack's bans respected, dark mode from its twin;
108
+ a screen ignoring the recorded pack is `drifted`. No pack and an improvised
109
+ visual layer → the companion is suggested once, as an opportunity finding.
110
+ - Validator guard: the hard rule embedded in `/ux-rule` must be byte-identical
111
+ to `templates/claude-rule.md`. They had already drifted apart in wording —
112
+ two copies of a rule is the exact failure the plugin preaches against.
113
+
114
+ ### Changed
115
+ - Recommendation, not dependency, in both directions: one offer with its
116
+ one-time install, then the user's answer stands and the chain continues on
117
+ platform defaults. A project that already has a design system records that
118
+ instead — two identities are worse than any one.
119
+ - Conflict rule stated where both sides live (`practice-selection.md`,
120
+ `ux-design-principles.md`): the style pack owns identity and wins on look;
121
+ BP-079..090 are floors (contrast, tap targets, line length, spacing rhythm)
122
+ and win on safety. The conflict and its resolution go in the compliance
123
+ table.
124
+ - README gains a Companions table (sheleg-design at VISUALIZE/BUILD,
125
+ task-pipeline after a plan) and the hard rule gains its style-pack bullet.
126
+
127
+ ## 0.21.0 — 2026-07-28
128
+
129
+ Full-repo consistency pass: every file read, every contradiction between the
130
+ contract, the skills, the Cursor rules, the templates, and the tooling fixed.
131
+
132
+ ### Fixed
133
+ - **`npx super-ux --cursor` crashed for every npm user.** `package.json`
134
+ `files[]` never shipped `plugins/super-ux/scripts/ux_lint.py`, so the CLI
135
+ installed the rules and templates and then died with an ENOENT stack trace
136
+ while copying the linter (reproduced against a packed 0.20.0 tarball). The
137
+ script is now in `files[]`, and a missing linter degrades to a warning with
138
+ a download link instead of a crash.
139
+ - **The linter mis-read story priorities.** `ST-NNN` bodies were scanned with
140
+ a fixed 600-character window, so a neighboring story's `**Priority:**`
141
+ line leaked into the previous story and produced false "must/should story
142
+ has no scenario" warnings. The scan now stops at the next heading.
143
+ - **The UX-plan example rendered broken.** The `` ```markdown `` block in the
144
+ contract contained a nested three-backtick fence, which closed the outer
145
+ block early and inverted the rest of the section; it is a four-backtick
146
+ fence now.
147
+ - Duplicate `refs(flows, "SCR")` computation in the linter collapsed into one.
148
+ - `release.yml` referenced a `pipeline.example.json` path that does not exist
149
+ in this repo and installed `jsonschema` the stdlib-only validator never
150
+ used.
151
+
152
+ ### Changed
153
+ - **One owner per fact:** `**Design system:**` is gone from `foundation.md` →
154
+ Design tooling (it contradicted `screens.md`, `figma-integration.md`, and
155
+ the templates). Foundation records the Figma on/off choice and the file
156
+ URL; `screens.md` → Design system records the library, tokens, components,
157
+ and assets. `figma-structure.md` and `system-map.md` say the same thing.
158
+ - Cursor rules resynced with ux-contract v4: `ux-flows` documented a stale
159
+ `Screens & states` table (it is `Screens traversed` + the `screens.md`
160
+ entry shape); `ux-scenarios` was missing the `Alt paths` field and the
161
+ monetization entries of the per-product checklist; `ux-audit` said "git SHA
162
+ of scenarios.md" (the contract says `docs/ux`) and never mentioned
163
+ flow/screen conformance or the `coverage` scope; `super-ux` told Cursor
164
+ users to run `/ux-lint`, a Claude-Code-only command.
165
+ - `/ux` reports every layer (it said "all three"); `/ux-init` is incremental —
166
+ existing layers are left untouched and only the missing ones initialized,
167
+ instead of talking about "both files" from a two-file era; README no longer
168
+ says the skills CLI installs "both skills".
169
+ - `docs/ux/plans/` is created by the installers, `/ux-rule`, and `/ux`
170
+ alongside `audits/` — the contract has required the directory since v4.
171
+ - `install.sh --help` described seeding one file; it seeds the whole skeleton
172
+ plus the linter. README's Development section documents the four-way
173
+ version sync and the `sync_references.py` step.
174
+
175
+ ### Added
176
+ - Validator check: every asset `bin/super-ux.js` copies must be covered by
177
+ `package.json` `files[]`, parsed from the CLI source rather than a
178
+ hand-kept list — the packaging regression above cannot come back silently.
179
+ - `templates/flows.md` carries the contract's `Wireframe` field.
180
+
181
+ ## 0.20.0 — 2026-07-28
182
+
183
+ ### Changed
184
+ - Skill descriptions restructured English-first: every Russian trigger now sits
185
+ beside its English equivalent (`"user flow" / "юзер флоу"`) instead of forming
186
+ a Russian-only tail, and the `/ux` routing table follows the same pairing.
187
+ - README is English-only: the Russian section is gone, replaced by a plain
188
+ statement of what the skill gives you and an author/links block.
189
+
190
+ ### Added
191
+ - Validator enforces the three description canon rules on every skill —
192
+ `Use when` opening, Russian trigger aliases present, front-matter under 1024
193
+ characters. Twelve new checks; all four skills pass.
194
+
3
195
  ## 0.19.0 — 2026-07-25
4
196
 
5
197
  Review pass — the contracts were not reaching non-Claude agents.
package/README.md CHANGED
@@ -4,74 +4,52 @@
4
4
  [![CI](https://github.com/ssheleg/super-ux/actions/workflows/validate.yml/badge.svg)](https://github.com/ssheleg/super-ux/actions/workflows/validate.yml)
5
5
  [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
6
6
 
7
- Scenario-driven UI development for AI agents (Claude Code + Cursor).
8
-
9
- AI agents generate poor interfaces because they build UI without a model of
10
- user behavior: screens appear feature by feature, while error states, empty
11
- states, and cross-feature flows get invented ad hoc or skipped. **super-ux**
12
- fixes the process, not the symptom a versioned base of UX scenarios becomes
13
- the source of truth for all user-facing behavior. Scenarios are written and
14
- validated *before* UI is built, updated in the same change as any behavior
15
- change, and used as the checklist for recurring, evidence-backed audits of
16
- the codebase.
7
+ **Scenario-driven UI development for AI agents** Claude Code, Cursor, and
8
+ 70+ other agents.
9
+
10
+ Coding agents build bad interfaces for one reason: they write UI without a
11
+ model of user behavior. Screens appear feature by feature; error states,
12
+ empty states, and cross-feature flows get invented ad hoc or skipped, and
13
+ three prompts later the agent quietly rewrites something you already
14
+ approved. super-ux fixes the process, not the symptom: a versioned design
15
+ chain in `docs/ux/` becomes the source of truth, written and approved
16
+ *before* UI exists, updated in the same change as any behavior change, and
17
+ used as the checklist for evidence-backed audits of the code.
17
18
 
18
19
  ```mermaid
19
20
  flowchart LR
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]
24
- D --> E[Update scenarios\nin the same change]
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
21
+ F["Foundation<br/>personas · JTBD<br/>journeys · stories"] --> L["Flows<br/>task analysis<br/>+ branches"]
22
+ L --> S["Screens<br/>states · elements<br/>Figma frames"]
23
+ S --> C["Scenarios<br/>action → response<br/>alt + error paths"]
24
+ C --> B["Build UI<br/>only now"]
25
+ B --> A["Audit<br/>code vs the chain<br/>file:line evidence"]
26
+ A --> P["Fix plan<br/>Freq × Severity<br/>× Solvability"]
27
+ P --> B
28
+ B -.->|same change| C
29
29
  ```
30
30
 
31
- ## What's inside
32
-
33
- | Piece | Purpose |
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-flows` | The HOW layer + UI map: `docs/ux/flows.md` (task analysis, mermaid user flows referencing screens) and `docs/ux/screens.md` — the design map: every screen and state with its **Figma frame link**, wireframe, code coverage, scenarios, and resources, kept in sync on every interface change (default-on Figma mockups apply the visual-craft practices); heuristic UX evaluation and traced redesign proposals |
37
- | skill `ux-scenarios` | Maintain `docs/ux/scenarios.md`: use-case scenarios (action → system response, alt paths) covering every flow node/edge, `Traces:` to stories and flows, validated for conflicts, coverage, and traceability |
38
- | 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 |
39
- | `/ux` | **The one command**: sets up whatever is missing, then status across all layers + a menu of applicable actions with one recommended default. Idempotent |
40
- | `docs/ux/lint.py` + `/ux-lint` | Deterministic linter: missing Figma frames, unresolved SCR/story traces, orphans, built screens without coverage, index desync, ID gaps, broken links — run after changes and in CI so drift can't merge |
41
- | [system-map.md](plugins/super-ux/skills/references/system-map.md) | The whole system on one page pipeline, files, skills, and the four sync rules; every skill points here |
42
- | `/ux-foundation` `/ux-flows` `/ux-init` `/ux-update` `/ux-audit` `/ux-rule` `/ux-lint` | Direct controls; `/ux-rule` installs the hard rule into the project's CLAUDE.md |
43
- | [ux-design-principles.md](plugins/super-ux/skills/references/ux-design-principles.md) | How the agent thinks: the design pipeline (forward + backwards), task analysis, flow rules, heuristics PRN-01..16, improvement procedure, anti-patterns |
44
- | `cursor/rules/*.mdc` | The same methodology for Cursor (always-on hard rule + four agent-requested rules) |
45
- | `templates/` | Skeletons for the foundation, scenario base, audit report, and the CLAUDE.md rule snippet |
46
- | [component-guidelines.md](plugins/super-ux/skills/references/component-guidelines.md) | When to use which control (radios/select/switch, sheet/alert, modal/disclosure, combobox, nav bar/rail, FAB, dates, toasts) + platform rules — from Apple HIG, Material 3, W3C ARIA APG, GOV.UK (BP-101..115) |
47
- | [best-practices.md](plugins/super-ux/skills/references/best-practices.md) | Living, tag-indexed catalog of 115 proven UX/growth practices — subscription-app laws, mobile/web/voice interface guidance (HIG 2025, M3 Expressive, NN/g, Baymard, WCAG 2.2), monetization economics (RevenueCat/PLG 2025 benchmarks, ASO, freemium boundaries, web2app), visual craft (typography, color, spacing, microcopy), Figma file structure (BP-091..100); selected deterministically via [practice-selection.md](plugins/super-ux/skills/references/practice-selection.md) |
48
- | [figma-integration.md](plugins/super-ux/skills/references/figma-integration.md) · [figma-structure.md](plugins/super-ux/skills/references/figma-structure.md) | Optional Figma surface (default-on): when/how to mock up, and how to structure the file so frames named `SCR-NN/<Screen>/<state>` map 1:1 to `screens.md` — deterministic lookup, checkable drift |
49
-
50
- The format all of them share is locked in
51
- [scenario-format.md](plugins/super-ux/skills/references/scenario-format.md):
52
- scenario entries with stable `SCN-NNN` IDs, personas, per-feature and
53
- per-product completeness checklists, the `draft → validated → implemented`
54
- lifecycle, audit verdicts and severities.
55
-
56
- ## The hard rule
57
-
58
- - `docs/ux/scenarios.md` is the source of truth for all user-facing
59
- behavior; foundation (WHY) and flows (HOW) are the layers it traces to.
60
- - Any change touching user-facing behavior or interface updates **in the
61
- same change**: scenarios, affected flows, the affected screens in
62
- `docs/ux/screens.md` (the UI map — states, elements, coverage), and (Figma
63
- on) the Figma frames plus their links. Code that diverges from a screen's
64
- record, or a stale Figma link, is drift the audit flags.
65
- - Any new feature or project **starts** with the chain: which job, which
66
- journey stage, which story — then flows and scenarios, validated and
67
- approved.
68
- - **Do not write interface code until the UX workflow is done first** — the
69
- foundation → flows → scenarios chain designed and approved, and (when
70
- Figma is enabled, the default) the UI mocked up in Figma with every screen
71
- linked to its frame. Building UI before this is the mistake super-ux
72
- exists to prevent.
73
-
74
- ## Install
31
+ Every layer traces to the one above it. New product? Build it forward. Existing
32
+ codebase? The same artifacts get filled in backwards from the code, tagged
33
+ `inferred` until you confirm them — the gap between "is" and "should" becomes
34
+ your improvement backlog.
35
+
36
+ ## What you get
37
+
38
+ - **Context stops evaporating.** You describe who the product is for and what
39
+ job it does once; every later prompt inherits that instead of re-deriving it
40
+ from the diff.
41
+ - **Scenarios become acceptance criteria.** "Make it nicer" can no longer mean
42
+ "silently change the error handling" a file says what the error handling
43
+ does, and the audit checks the code against it.
44
+ - **Drift gets caught, deterministically.** A linter fails on missing Figma
45
+ frames, broken traces, orphan screens, and index desync; audits report what
46
+ no longer matches with `file:line` evidence. That is the review pass you'd
47
+ otherwise never run.
48
+ - **Designer artifacts without being a designer.** Personas, jobs to be done,
49
+ journeys, flows, screen states, wireframes, Figma frames — produced in your
50
+ repo, in the vocabulary a design review actually uses.
51
+
52
+ ## Quick start
75
53
 
76
54
  ### Claude Code
77
55
 
@@ -80,51 +58,142 @@ lifecycle, audit verdicts and severities.
80
58
  /plugin install super-ux@super-ux
81
59
  ```
82
60
 
83
- Then in your project: `/ux`. That's it it installs the hard rule, seeds
84
- `docs/ux/`, builds the scenario base if empty, and on every later run just
85
- reports status and the next action.
61
+ Then in your project, run `/ux` and answer in plain words. First run installs
62
+ the hard rule, seeds `docs/ux/`, and builds the chain; every later run reports
63
+ status and recommends one next action. You never pick a skill or a layer —
64
+ routing is the agent's job.
65
+
66
+ ### Cursor
67
+
68
+ ```sh
69
+ npx super-ux --cursor /path/to/your/project
70
+ ```
71
+
72
+ Copies the rules into `.cursor/rules/` (one always-on hard rule + four
73
+ agent-requested rules), seeds `docs/ux/`, and installs the linter. An existing
74
+ scenario base is never overwritten; re-run with `--force` after a release to
75
+ refresh rules and linter only.
86
76
 
87
- ### Any agent via the skills CLI (70+ agents)
77
+ ### Any agent (70+, via the skills CLI)
88
78
 
89
79
  ```sh
90
- npx skills add ssheleg/super-ux # both skills, current project
80
+ npx skills add ssheleg/super-ux # all four skills, current project
91
81
  npx skills add ssheleg/super-ux -g # user-global
92
82
  npx skills add ssheleg/super-ux --skill ux-audit # one skill
93
83
  ```
94
84
 
95
85
  [vercel-labs/skills](https://github.com/vercel-labs/skills) discovers the
96
86
  skills through this repo's marketplace manifest and installs them for Claude
97
- Code, Cursor, Codex, OpenCode and others. Note: this installs the skills
98
- only — the `/ux` commands and the Cursor always-on hard rule come with the
99
- methods below.
87
+ Code, Cursor, Codex, OpenCode and others. This channel ships the skills only —
88
+ the `/ux` commands come with the plugin, the always-on hard rule with the
89
+ Cursor install.
100
90
 
101
- ### Interactive (pick agent + scope)
91
+ ### Interactive (pick channels and agents)
102
92
 
103
93
  ```sh
104
94
  npx super-ux
105
95
  ```
106
96
 
107
- Multi-select menu (space to toggle, `a` = everything at once, enter to
108
- install): skills for any of 70+ agents (delegates to the `skills` CLI picker
109
- choose agents and global/project there), Cursor rules into a project, and
110
- the Claude Code plugin user-globally any combination in one run.
97
+ Multi-select menu (space toggles, `a` selects everything, enter installs):
98
+ skills for any of 70+ agents, Cursor rules into a project, and the Claude Code
99
+ plugin user-globally any combination in one run. Also works straight from
100
+ GitHub: `npx github:ssheleg/super-ux --cursor <dir>`, or clone and run
101
+ `./install.sh --cursor <dir>`.
111
102
 
112
- ### Cursor
103
+ ## The hard rule
113
104
 
114
- ```sh
115
- npx super-ux --cursor /path/to/your/project
116
- ```
105
+ Installed into your project's `CLAUDE.md` (and as the always-on Cursor rule):
117
106
 
118
- (also works: `npx github:ssheleg/super-ux --cursor <dir>` straight from the
119
- repo, or clone and run `./install.sh --cursor <dir>` same behavior.) Copies the
120
- rules into `.cursor/rules/` and seeds `docs/ux/`. An existing scenario base
121
- is never overwritten; re-run with `--force` to update rules after a new
122
- release.
107
+ - `docs/ux/scenarios.md` is the source of truth for all user-facing behavior;
108
+ foundation (WHY), flows (HOW), and screens (the UI map) are the layers it
109
+ traces to.
110
+ - Any change touching user-facing behavior or interface updates **in the same
111
+ change**: scenarios, affected flows, the affected screens in
112
+ `docs/ux/screens.md`, and — when Figma is on — the frames plus their links.
113
+ Code that diverges from a screen's record, or a stale Figma link, is drift
114
+ the audit flags.
115
+ - Any new feature or project **starts** with the chain: which job, which
116
+ journey stage, which story — then flows, screens, and scenarios, validated
117
+ against the existing base and approved.
118
+ - **Do not write interface code until that workflow is done** — chain designed
119
+ and approved, and (Figma on, the default) the UI mocked up with every screen
120
+ linked to its frame. Building UI before this is the mistake super-ux exists
121
+ to prevent.
122
+ - One **style pack** is the visual identity for the whole product, recorded in
123
+ `docs/ux/screens.md` → Design system. Inventing a palette, type pairing, or
124
+ motion per screen is drift too.
125
+ - Run `python3 docs/ux/lint.py` after any UX change and in CI — it must pass.
126
+
127
+ ## Typical cycle
128
+
129
+ 1. **`/ux`** — first run sets everything up: foundation first (greenfield:
130
+ an interview about personas, jobs, journeys; existing code:
131
+ reverse-engineering them), then flows, screens, and scenarios derived from
132
+ the stories with full traceability.
133
+ 2. **Work normally.** Every user-facing change updates the chain in the same
134
+ change — the always-on rule catches it, `/ux-update` gives manual control.
135
+ New feature ideas get validated against the chain first: which job, which
136
+ journey stage, which story. An idea serving no job is challenged, not
137
+ silently built.
138
+ 3. **`/ux-audit`** — batched verification of code against every scenario plus
139
+ its story's acceptance criteria. `deep` adds heuristic, practice, and chain
140
+ coverage passes; `coverage` audits the chain itself. Reports land in
141
+ `docs/ux/audits/YYYY-MM-DD.md`.
142
+ 4. **Fix plan.** Findings become `docs/ux/plans/…`: the target interface per
143
+ screen plus a traced CREATE/MODIFY/DELETE table, prioritized by Frequency ×
144
+ Severity × Solvability — written to be executable without the conversation
145
+ that produced it. Build, then re-audit.
146
+
147
+ ## Companions (recommended, never required)
148
+
149
+ super-ux owns structure and behavior, and deliberately stops at two edges.
150
+ Each companion is offered once with its one-time install; the chain works
151
+ fine without either.
152
+
153
+ | When | Companion | What it adds |
154
+ |---|---|---|
155
+ | At VISUALIZE / BUILD — a frame or a screen is about to be drawn | **[sheleg-design](https://github.com/ssheleg/sheleg-design-skill)** | The look: one locked style pack (palette, type, texture, motion tokens, bans) with ready token CSS — `workbench` for product UI, dashboards and tools; `instrument-console`; `editorial-luxury`; or a new pack on its contract. Plus the motion methodology for cinematic scroll-driven landings. The pack is recorded in `screens.md`; its tokens become the Figma variables *and* the code tokens. `npx sheleg-design-skill` |
156
+ | After an audit or an Improve pass produced a UX plan | **[task-pipeline](https://github.com/ssheleg/task-pipeline)** | Executes the plan end-to-end through gated stages: spec → plan → subagent build → tests → deploy → docs. `/task-pipeline docs/ux/plans/<file>` |
157
+
158
+ The boundary that keeps them from fighting: BP-079..090 are craft **floors**
159
+ (contrast, line length, tap targets, spacing rhythm) and always win on safety;
160
+ the style pack owns **identity** and wins on look. Both decisions land in the
161
+ compliance table. Full protocol:
162
+ [visual-identity.md](plugins/super-ux/skills/references/visual-identity.md).
163
+
164
+ ## What's inside
123
165
 
124
- ### Updating everything
166
+ Four skills, one entry point, and a set of contracts they all obey.
125
167
 
126
- Global channels (run after each release, then restart the Claude Code
127
- session so the plugin reloads):
168
+ | Piece | Purpose |
169
+ |---|---|
170
+ | 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, the monetization model |
171
+ | skill `ux-flows` | The HOW layer + the UI map: `docs/ux/flows.md` (task analysis, mermaid flows referencing screens by ID) and `docs/ux/screens.md` — every screen and state with its Figma frame, wireframe, code coverage, scenarios and resources. Also heuristic evaluation and traced redesign proposals |
172
+ | skill `ux-scenarios` | `docs/ux/scenarios.md`: use-case scenarios (action → observable response, alt and error paths) covering every flow node and edge, `Traces:` to stories and flows, validated for conflicts, coverage and traceability |
173
+ | skill `ux-audit` | Batched audit with full context: code vs every scenario plus its story's acceptance criteria; verdicts PASS / PARTIAL / FAIL / BLOCKED with `file:line` evidence; depths `quick` / `standard` / `deep`; a `coverage` scope that audits the chain itself |
174
+ | `/ux` | **The one command**: sets up whatever is missing, reports status across every layer, then offers only the applicable actions with one marked recommended. Idempotent |
175
+ | `/ux-init` `/ux-foundation` `/ux-flows` `/ux-update` `/ux-audit` `/ux-rule` `/ux-lint` | Direct controls for when you know exactly what you want; `/ux-rule` installs the hard rule into `CLAUDE.md` |
176
+ | `docs/ux/lint.py` + `/ux-lint` | The deterministic half: missing Figma frames, unresolved SCR/story traces, orphans, built screens without coverage, index desync, ID gaps, broken links. Stdlib-only, exit 1 on problems — wire it into CI so drift can't merge |
177
+ | `cursor/rules/*.mdc` | The same methodology for Cursor: one always-on hard rule + four agent-requested rules |
178
+ | `templates/` | Seeds for `docs/ux/`: foundation, flows, screens, scenario base, the folder README, the audit-report skeleton, and the CLAUDE.md rule snippet |
179
+
180
+ The contracts every skill reads:
181
+
182
+ | Reference | Holds |
183
+ |---|---|
184
+ | [scenario-format.md](plugins/super-ux/skills/references/scenario-format.md) | **The contract (ux-contract v4).** File layout, every field name, stable IDs (`P` `JTBD` `JRN` `ST` `FLW` `SCR` `SCN`), completeness checklists, the `draft → validated → implemented` lifecycle, audit verdicts and severities, the UX-plan format |
185
+ | [system-map.md](plugins/super-ux/skills/references/system-map.md) | The whole system on one page — pipeline, files, skills, companions, and the four sync rules; every skill points here |
186
+ | [ux-design-principles.md](plugins/super-ux/skills/references/ux-design-principles.md) | How the agent thinks: the design pipeline (forward and backwards), task analysis, flow rules, heuristics PRN-01..16, the improvement procedure, anti-patterns |
187
+ | [best-practices.md](plugins/super-ux/skills/references/best-practices.md) | Living, tag-indexed catalog of 115 proven practices — subscription-app laws, mobile/web/voice guidance (Apple HIG 2025, M3 Expressive, NN/g, Baymard, WCAG 2.2), monetization economics (RevenueCat/PLG 2025 benchmarks, ASO, freemium boundaries, web2app), visual craft, Figma structure |
188
+ | [practice-selection.md](plugins/super-ux/skills/references/practice-selection.md) | The deterministic bridge: product profile → mandatory consideration sets → per-artifact checklists → a compliance table where every pulled practice gets a verdict. No silent skips, no cargo cult |
189
+ | [component-guidelines.md](plugins/super-ux/skills/references/component-guidelines.md) | Which control for which job (radios/select/switch, sheet/alert, modal/disclosure, combobox, nav bar/rail, FAB, dates, toasts) and the platform rules — Apple HIG, Material 3, W3C ARIA APG, GOV.UK |
190
+ | [visual-identity.md](plugins/super-ux/skills/references/visual-identity.md) | The visual layer and its owner: one style pack for the whole product, where it's recorded, how it meets Figma and code, and the division of labor with the craft floors |
191
+ | [figma-integration.md](plugins/super-ux/skills/references/figma-integration.md) · [figma-structure.md](plugins/super-ux/skills/references/figma-structure.md) | The optional Figma surface (on by default): when and how to mock up, and how to structure the file so frames named `SCR-NN/<Screen>/<state>` map 1:1 to `screens.md` — deterministic lookup, checkable drift |
192
+
193
+ ## Keeping installs current
194
+
195
+ Global channels (run after a release, then restart the Claude Code session so
196
+ the plugin reloads):
128
197
 
129
198
  ```sh
130
199
  claude plugin marketplace update super-ux && \
@@ -132,67 +201,41 @@ claude plugin update super-ux@super-ux && \
132
201
  npx --yes skills update ux-audit ux-flows ux-foundation ux-scenarios --global --yes
133
202
  ```
134
203
 
135
- Cursor rules + the seeded `docs/ux/lint.py` are per-project (Cursor has no
136
- global rules dir) — refresh each project you use:
204
+ Cursor rules and the seeded `docs/ux/lint.py` are per-project (Cursor has no
205
+ global rules directory) — refresh each project you use:
137
206
 
138
207
  ```sh
139
208
  npx super-ux@latest --cursor /path/to/your/project --force
140
209
  ```
141
210
 
142
- `--force` overwrites the rule files and the linter; your scenario base
143
- (`docs/ux/scenarios.md`) and the rest of `docs/ux/` are never touched.
144
- Check the published version any time with `npm view super-ux version`.
211
+ `--force` replaces the rule files and the linter; your scenario base and the
212
+ rest of `docs/ux/` are never touched. Check the published version with
213
+ `npm view super-ux version`.
145
214
 
146
- ## For the user: one command, plain words
215
+ ## Contributing
147
216
 
148
- You don't need to know the layers or skills. Run `/ux` and say what you
149
- want in your own words "стартуем новый продукт", "добавить фичу", "UX
150
- неудобный, улучши", "проверь что всё работает", "что чинить в первую
151
- очередь". The agent asks at most one clarifying question, picks the right
152
- workflow itself, and only shows you human decisions (approve scenarios,
153
- pick a plan). Everything below this line is internals for the agent.
217
+ Issues and pull requests are welcome see [CONTRIBUTING.md](CONTRIBUTING.md)
218
+ for the repo layout, the validator, and the release checklist. Everyone taking
219
+ part is expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md); to report a
220
+ vulnerability, see [SECURITY.md](SECURITY.md). In short:
221
+ `python3 test/validate.py` must pass (CI runs it on every push and PR), and
222
+ edits to `plugins/super-ux/skills/references/` need
223
+ `python3 test/sync_references.py` to refresh the per-skill copies.
154
224
 
155
- ## Typical cycle
225
+ ## Author
156
226
 
157
- 1. `/ux`first run sets everything up: foundation first (greenfield:
158
- interview about personas, jobs, journeys; existing code:
159
- reverse-engineer them), then scenarios derived from the stories with
160
- full traceability.
161
- 2. Work normally; every user-facing change updates the base in the same
162
- change (the always-on rule catches it; `/ux-update` for manual control).
163
- New feature ideas are validated against the chain first: which job,
164
- which journey stage, which story.
165
- 3. `/ux` any time — status across layers + action menu; `/ux-audit` —
166
- batched verification of code vs scenarios (with acceptance criteria);
167
- `/ux-audit coverage` — chain gaps. Reports land in
168
- `docs/ux/audits/YYYY-MM-DD.md`.
169
- 4. Findings become a concrete UX plan (`docs/ux/plans/…`): target interface
170
- per screen + traced CREATE/MODIFY/DELETE change table, prioritized by
171
- Frequency × Severity × Solvability — offered for autonomous execution
172
- via task-pipeline (or your planning workflow); build; repeat.
173
-
174
- ## Development
175
-
176
- `python3 test/validate.py` checks repo consistency (manifests, versions,
177
- front-matter, templates, links); CI runs it on every push and PR. Versioning
178
- is semver; bump `marketplace.json` + `plugin.json` + `CHANGELOG.md` together
179
- — the validator enforces the sync.
180
-
181
- ## По-русски (коротко)
182
-
183
- Проблема: агенты генерируют плохие интерфейсы, потому что строят UI без
184
- модели поведения пользователя. super-ux строит цепочку: **персоны → JTBD →
185
- карта пути → user stories → UX-сценарии → аудиты → планы фиксов**.
186
- Foundation (`docs/ux/foundation.md`) отвечает на «зачем», сценарии
187
- (`docs/ux/scenarios.md`) — источник правды поведения, трассируются к
188
- stories. Всё пишется и валидируется **до** интерфейса, обновляется тем же
189
- изменением, что и поведение. Аудиты (`/ux-audit`) проверяют код против
190
- сценариев вместе с acceptance criteria, вердикты PASS/PARTIAL/FAIL/BLOCKED
191
- с доказательствами `file:line`; `/ux-audit coverage` ищет дыры в самой
192
- цепочке. Установка: в
193
- Claude Code — `/plugin marketplace add ssheleg/super-ux`, в Cursor —
194
- `npx super-ux --cursor <проект>`. Дальше одна команда — `/ux`: сама ставит
195
- правило и базу, а при повторных запусках показывает статус и следующий шаг.
227
+ Built by ssheleg [sshlg.me](https://sshlg.me)
228
+
229
+ - X / Twitter [@fuck_this_year](https://x.com/fuck_this_year)
230
+ - Telegram — [@sshlg](https://t.me/sshlg)
231
+
232
+ Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills):
233
+ `super-ux`, `task-pipeline`, `make-skill`, `sheleg-design`, `seo-aeo-audit`.
234
+ One command installs all five for every agent you use:
235
+
236
+ ```bash
237
+ npx sshlg-skills install
238
+ ```
196
239
 
197
240
  ## License
198
241
 
package/bin/super-ux.js CHANGED
@@ -74,7 +74,9 @@ function installCursor(target, force) {
74
74
  }
75
75
  }
76
76
 
77
- fs.mkdirSync(path.join(target, 'docs', 'ux', 'audits'), { recursive: true });
77
+ for (const dir of ['audits', 'plans']) {
78
+ fs.mkdirSync(path.join(target, 'docs', 'ux', dir), { recursive: true });
79
+ }
78
80
  for (const tpl of ['scenarios', 'foundation', 'flows', 'screens', 'README']) {
79
81
  const dst = path.join(target, 'docs', 'ux', `${tpl}.md`);
80
82
  if (fs.existsSync(dst)) {
@@ -85,9 +87,19 @@ function installCursor(target, force) {
85
87
  }
86
88
  }
87
89
  // The linter is code, not a template — refresh it to the shipped version.
90
+ // Shipped via package.json files[]; if that ever regresses, warn instead of
91
+ // dying on an ENOENT stack trace after the rules are already installed.
92
+ const lintSrc = path.join(ROOT, 'plugins', 'super-ux', 'scripts', 'ux_lint.py');
88
93
  const lintDst = path.join(target, 'docs', 'ux', 'lint.py');
89
- fs.copyFileSync(path.join(ROOT, 'plugins', 'super-ux', 'scripts', 'ux_lint.py'), lintDst);
90
- console.log(`sync: ${lintDst}`);
94
+ if (fs.existsSync(lintSrc)) {
95
+ fs.copyFileSync(lintSrc, lintDst);
96
+ console.log(`sync: ${lintDst}`);
97
+ } else {
98
+ console.error(
99
+ `warning: linter not found in this package (${lintSrc}); docs/ux/lint.py was not installed.\n` +
100
+ ` Get it from https://github.com/${REPO}/blob/main/plugins/super-ux/scripts/ux_lint.py`
101
+ );
102
+ }
91
103
 
92
104
  console.log(`done: ${installed} installed, ${skipped} skipped`);
93
105
  }
@@ -12,7 +12,8 @@ alwaysApply: true
12
12
  and (Figma on) its frame link. A screen that changes in code changes here in
13
13
  the SAME change.
14
14
  - Run the linter after any UX change and before calling work done:
15
- `python3 docs/ux/lint.py` (or `/ux-lint`). It must pass — drift must not merge.
15
+ `python3 docs/ux/lint.py`. It must pass — drift must not merge; wire it
16
+ into CI/pre-commit.
16
17
  - Any change that touches user-facing behavior MUST update
17
18
  `docs/ux/scenarios.md` in the same change (add/adjust scenarios, statuses,
18
19
  coverage). New user-facing behavior with no scenario is a blocker, not a
@@ -22,10 +23,15 @@ alwaysApply: true
22
23
  against the existing base (conflicts, overlaps, gaps), approved. An idea
23
24
  serving no job is challenged, not silently accepted.
24
25
  - Do NOT write interface code until the UX workflow is done first: the
25
- foundation → flows → scenarios chain is designed and approved, and — when
26
- Figma is enabled (default) — the UI is mocked up in Figma with every
27
- screen linked to its frame. Building UI before this is the exact mistake
28
- super-ux exists to prevent.
26
+ foundation → flows → screens → scenarios chain is designed and approved,
27
+ and — when Figma is enabled (default) — the UI is mocked up in Figma with
28
+ every screen linked to its frame. Building UI before this is the exact
29
+ mistake super-ux exists to prevent.
30
+ - Visual identity is one locked style pack, recorded once in `screens.md` →
31
+ Design system and used by every frame and every built screen — picked with
32
+ the **sheleg-design** companion skill (`npx sheleg-design-skill`) when the
33
+ project has no design system of its own. Recommended, never forced; a
34
+ palette invented per screen is visual drift.
29
35
  - Workflows: `ux-foundation` rule (WHY), `ux-flows` rule (flows + Figma
30
- mockups), `ux-scenarios` rule (scenario base), `ux-audit` rule
36
+ mockups + style pack), `ux-scenarios` rule (scenario base), `ux-audit` rule
31
37
  (evidence-backed audits).
@@ -15,8 +15,9 @@ verdict BLOCKED with the exact reason. Never guess, never a courtesy PASS.
15
15
 
16
16
  ## Loop
17
17
 
18
- 1. Read the base; scope = all | feature:<name> | ID range; note the git SHA
19
- of scenarios.md for the report header; skip retired scenarios.
18
+ 1. Read the base (and foundation/flows/screens when they exist); scope =
19
+ all | feature:<name> | ID range | coverage; note the git SHA of `docs/ux`
20
+ for the report header; skip retired scenarios.
20
21
  2. Batch by feature, ~5–8 scenarios per batch; list batches up front.
21
22
  3. Per scenario check against the code: entry point reachable; every step
22
23
  implemented; every listed UI element present and wired; every listed
@@ -26,6 +27,12 @@ verdict BLOCKED with the exact reason. Never guess, never a courtesy PASS.
26
27
  `[AUD-YYYY-MM-DD-NN] (critical|major|minor) description -> suggested fix`.
27
28
  4. Verdicts: PASS (complete), PARTIAL (flow exists, gaps), FAIL (missing or
28
29
  broken), BLOCKED (cannot verify — say why).
30
+ When `flows.md`/`screens.md` exist, also check conformance: every flow
31
+ node reachable and every edge (error edges included) wired; every
32
+ registered screen's states rendered and its `Coverage` accurate — code
33
+ that diverges from a screen's record is a `drifted` finding. Scope
34
+ `coverage` audits the chain itself (orphan stories/flows/screens/
35
+ scenarios, journey stages without scenarios, personas unused).
29
36
  5. Write the report batch by batch: header (scope, method, base SHA),
30
37
  Summary (totals, top issues, prioritized next actions), per-batch
31
38
  verdicts with evidence, findings-register table.
@@ -20,8 +20,14 @@ Fields: `Traces` (story/job IDs), `Goal` (observable end state), `Entry
20
20
  points` (ALL of them), `Success exit`, `Task analysis` (numbered
21
21
  user-visible micro-steps), mermaid `flowchart` (screens as
22
22
  `Screen: <name>`, decisions as diamonds, `*_err` error nodes with labeled
23
- recovery edges), `Screens & states` table (each screen:
24
- loading/empty/error/success + key elements, one primary action).
23
+ recovery edges), `Screens traversed` table (`| Screen | States used here |`
24
+ SCR-IDs only; the full per-screen spec lives once in `screens.md`).
25
+
26
+ Each screen entry in `screens.md`: `Used by`, `Purpose`, `Elements` (mark
27
+ the ONE primary action), `States` table (`| State | Trigger | Figma frame |
28
+ Behavior |` — a row per loading/empty/error/success that applies),
29
+ `Wireframe`, `Coverage` (file:line), `Scenarios`, `Resources`, `Status`
30
+ (designed|built|drifted|retired).
25
31
 
26
32
  ## Design rules
27
33
 
@@ -33,9 +39,20 @@ loading/empty/error/success + key elements, one primary action).
33
39
  - Wireframes optional (`docs/ux/wireframes/FLW-NN.md`, ASCII hierarchy +
34
40
  primary action, not pixels); storyboard only when usage context drives
35
41
  design.
42
+ - Visual identity BEFORE any frame: `screens.md` → Design system →
43
+ `Style pack`. Empty and no design system in the project → pick a pack with
44
+ the **sheleg-design** companion skill (`workbench` for product UI /
45
+ dashboards / tools, `instrument-console`, `editorial-luxury`, or a new
46
+ pack on its contract; cinematic scroll pages also take its motion
47
+ methodology) and record the pack + token file. Missing → offer the
48
+ one-time install once (`npx sheleg-design-skill`) and continue on platform
49
+ defaults; recommend, don't force. The pack owns palette/type/motion and
50
+ its bans; BP-079..090 stay the floors it must clear. Never invent a look
51
+ per screen.
36
52
  - Figma mockups optional (default on): if the foundation's Design tooling
37
53
  enables Figma and a Figma MCP is available, mirror each screen into a
38
- frame applying visual-craft practices (BP-079..090), and link every
54
+ frame built on the pack's tokens (they become the Figma variable
55
+ collections) applying visual-craft practices (BP-079..090), and link every
39
56
  screen row to its frame; ask the user once at the start of design.
40
57
  - Backwards mode (existing product): reconstruct flows as they ARE from
41
58
  code with file:line evidence, tag `inferred` until confirmed; gaps
@@ -42,6 +42,13 @@ deleted.
42
42
  INVEST, observable criteria), coverage (persona→job→journey→story chain
43
43
  complete; must/should stories have scenarios).
44
44
 
45
+ Two more sections this file owns, filled when they apply: **Monetization**
46
+ (model + value metric + free boundary + money moments + acquisition
47
+ coherence — each money moment becomes a first-class flow) and **Design
48
+ tooling** (the Figma on/off choice, default on, plus the project's Figma file
49
+ URL — asked once per project). Everything else about the visual layer, the
50
+ design system and the style pack, lives in `docs/ux/screens.md`.
51
+
45
52
  Evidence beats opinion: mark unvalidated guesses as assumptions
46
53
  (desirability/viability/feasibility/usability) and test risky ones before
47
54
  building on them.
@@ -21,8 +21,10 @@ JRN-01/#2)`), enforce traceability — every must/should story covered by ≥1
21
21
  scenario, every scenario serves ≥1 story or job.
22
22
 
23
23
  Scenario entry fields (exact names): `Persona`, `Feature`, `Traces`, `Entry point`,
24
- `Preconditions`, `Steps` (numbered, one user action each), `Expected result`
25
- (observable), `UI elements` (every button/field/link/dialog/toast involved —
24
+ `Preconditions`, `Steps` (numbered, one user action each, paired with the
25
+ observable system response), `Expected result` (observable), `Alt paths`
26
+ (meaningful non-error deviations — skip/dismiss/alternate route — omit only
27
+ when none exist), `UI elements` (every button/field/link/dialog/toast involved —
26
28
  this is what audits check), `States covered` (loading|empty|error|success),
27
29
  `Errors & recovery` (each failure: what the user sees, how they recover),
28
30
  `Status` (draft|validated|implemented|retired), `Coverage` (file:line or
@@ -35,7 +37,10 @@ never deleted. Lifecycle: draft → validated (human approval) → implemented
35
37
  Per-feature completeness: happy path, every error path, empty state, visible
36
38
  loading, destructive-action confirmation, returning-user variant.
37
39
  Per-product: first-run onboarding, every core flow, settings, multi-entity
38
- flows (e.g. second project), account/data lifecycle.
40
+ flows (e.g. second project), account/data lifecycle, and — when the product
41
+ earns money — the monetization flows: paywall (first-session placement),
42
+ trial start/end, upgrade-at-limit, cancel + winback, rating prompt after
43
+ success moments.
39
44
 
40
45
  ## Workflows
41
46
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "super-ux",
3
- "version": "0.19.0",
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.",
3
+ "version": "0.23.2",
4
+ "description": "Scenario-driven UI development for AI agents (Claude Code, Cursor, 70+ agents): a versioned design chain in docs/ux/, a scenario-first hard rule, a deterministic drift linter, and evidence-backed UX audits. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "super-ux": "bin/super-ux.js"
7
7
  },
@@ -9,12 +9,16 @@
9
9
  "bin",
10
10
  "cursor",
11
11
  "templates",
12
+ "plugins/super-ux/scripts/ux_lint.py",
12
13
  "README.md",
13
14
  "LICENSE",
14
15
  "CHANGELOG.md"
15
16
  ],
16
17
  "repository": "github:ssheleg/super-ux",
17
18
  "homepage": "https://github.com/ssheleg/super-ux",
19
+ "bugs": {
20
+ "url": "https://github.com/ssheleg/super-ux/issues"
21
+ },
18
22
  "license": "MIT",
19
23
  "author": "ssheleg",
20
24
  "engines": {
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env python3
2
+ """super-ux linter — checks a target project's docs/ux/ for integrity and drift.
3
+
4
+ Deterministic enforcement of the ux-contract: run it after any UX change and
5
+ before calling the work done, and wire it into the project's CI/pre-commit.
6
+ It turns the prose rules (same-change, no lost Figma, no orphans, no drift)
7
+ into a check that fails.
8
+
9
+ Usage:
10
+ python3 docs/ux/lint.py # lint ./docs/ux
11
+ python3 docs/ux/lint.py <dir> # lint <dir> (a docs/ux directory or its parent)
12
+ python3 docs/ux/lint.py --strict # warnings also fail (exit 1)
13
+
14
+ Exit codes: 0 clean (warnings allowed unless --strict), 1 problems found,
15
+ 2 no UX docs at all (run /ux first). Stdlib only; tolerant parsing — reports
16
+ what it can and never crashes on malformed markdown.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import re
22
+ import sys
23
+ from pathlib import Path
24
+
25
+ ERRORS: list[str] = []
26
+ WARNS: list[str] = []
27
+
28
+
29
+ def err(msg: str) -> None:
30
+ ERRORS.append(msg)
31
+
32
+
33
+ def warn(msg: str) -> None:
34
+ WARNS.append(msg)
35
+
36
+
37
+ def read(path: Path) -> str:
38
+ try:
39
+ text = path.read_text(encoding="utf-8")
40
+ except OSError:
41
+ return ""
42
+ # Strip HTML comments so template examples (shipped commented-out) and
43
+ # notes are never parsed as real entries.
44
+ return re.sub(r"<!--.*?-->", "", text, flags=re.DOTALL)
45
+
46
+
47
+ def find_ux_dir(arg: str | None) -> Path | None:
48
+ base = Path(arg) if arg else Path.cwd()
49
+ for cand in (base, base / "docs" / "ux", base.parent if base.name else base):
50
+ if (cand / "scenarios.md").exists() or (cand / "foundation.md").exists():
51
+ return cand
52
+ return None
53
+
54
+
55
+ def ids(text: str, prefix: str) -> list[str]:
56
+ """All '### PREFIX-NN:' entry ids, in order."""
57
+ return re.findall(rf"^###\s+({prefix}-\d+):", text, re.MULTILINE)
58
+
59
+
60
+ def index_ids(text: str, prefix: str) -> set[str]:
61
+ """Ids appearing in a leading '| PREFIX-NN |' index-table cell."""
62
+ return set(re.findall(rf"^\|\s*({prefix}-\d+)\s*\|", text, re.MULTILINE))
63
+
64
+
65
+ def refs(text: str, prefix: str) -> set[str]:
66
+ """Every PREFIX-NN token mentioned anywhere."""
67
+ return set(re.findall(rf"\b({prefix}-\d+)\b", text))
68
+
69
+
70
+ def check_unique_and_gaps(entry_ids: list[str], label: str) -> None:
71
+ seen: dict[str, int] = {}
72
+ for i in entry_ids:
73
+ seen[i] = seen.get(i, 0) + 1
74
+ for i, n in seen.items():
75
+ if n > 1:
76
+ err(f"{label}: duplicate id {i} ({n} entries)")
77
+ nums = sorted(int(i.split("-")[1]) for i in seen)
78
+ if nums:
79
+ missing = [n for n in range(1, max(nums) + 1) if n not in nums]
80
+ if missing:
81
+ warn(f"{label}: id gaps (retired entries should stay): {missing}")
82
+
83
+
84
+ def figma_enabled(foundation: str) -> bool | None:
85
+ """True/False from foundation Design tooling; None if unstated (default-on)."""
86
+ m = re.search(r"\*\*Figma:\*\*\s*(enabled|disabled)", foundation, re.IGNORECASE)
87
+ if not m:
88
+ return None
89
+ return m.group(1).lower() == "enabled"
90
+
91
+
92
+ def screen_blocks(text: str) -> dict[str, str]:
93
+ """Map SCR-id -> its section body (from its header to the next ### / ##)."""
94
+ out: dict[str, str] = {}
95
+ parts = re.split(r"^###\s+(SCR-\d+):", text, flags=re.MULTILINE)
96
+ # parts = [pre, id1, body1, id2, body2, ...]
97
+ for i in range(1, len(parts), 2):
98
+ sid = parts[i]
99
+ body = parts[i + 1] if i + 1 < len(parts) else ""
100
+ body = re.split(r"^##\s", body, maxsplit=1, flags=re.MULTILINE)[0]
101
+ out[sid] = body
102
+ return out
103
+
104
+
105
+ def check_links(ux: Path) -> None:
106
+ link_re = re.compile(r"\[[^\]]*\]\(([^)\s]+)\)")
107
+ for md in sorted(ux.rglob("*.md")):
108
+ text = read(md)
109
+ for target in link_re.findall(text):
110
+ if target.startswith(("http://", "https://", "#", "mailto:")):
111
+ continue
112
+ resolved = (md.parent / target.split("#", 1)[0]).resolve()
113
+ if not resolved.exists():
114
+ warn(f"{md.name}: broken link -> {target}")
115
+
116
+
117
+ def main() -> int:
118
+ args = [a for a in sys.argv[1:] if not a.startswith("-")]
119
+ strict = "--strict" in sys.argv[1:]
120
+ ux = find_ux_dir(args[0] if args else None)
121
+ if ux is None:
122
+ print("no UX docs found (docs/ux/scenarios.md). Run /ux to set up.")
123
+ return 2
124
+
125
+ foundation = read(ux / "foundation.md")
126
+ flows = read(ux / "flows.md")
127
+ screens = read(ux / "screens.md")
128
+ scenarios = read(ux / "scenarios.md")
129
+
130
+ has_flows = bool(ids(flows, "FLW"))
131
+ has_screens = bool(ids(screens, "SCR"))
132
+ has_stories = bool(ids(foundation, "ST"))
133
+
134
+ # --- ID integrity ---
135
+ for text, pref, label in [
136
+ (scenarios, "SCN", "scenarios.md"),
137
+ (flows, "FLW", "flows.md"),
138
+ (screens, "SCR", "screens.md"),
139
+ (foundation, "ST", "foundation.md/stories"),
140
+ (foundation, "JTBD", "foundation.md/jobs"),
141
+ ]:
142
+ entry_ids = ids(text, pref)
143
+ if entry_ids:
144
+ check_unique_and_gaps(entry_ids, label)
145
+
146
+ # --- Index <-> entries sync (scenarios, screens) ---
147
+ for text, pref, name in [(scenarios, "SCN", "scenarios.md"), (screens, "SCR", "screens.md")]:
148
+ entries = set(ids(text, pref))
149
+ if not entries:
150
+ continue
151
+ idx = index_ids(text, pref)
152
+ for missing in sorted(entries - idx):
153
+ warn(f"{name}: {missing} has no index row")
154
+ for ghost in sorted(idx - entries):
155
+ err(f"{name}: index lists {ghost} but no entry exists")
156
+
157
+ # --- Flows reference existing screens ---
158
+ if has_flows and has_screens:
159
+ screen_ids = set(ids(screens, "SCR"))
160
+ used = refs(flows, "SCR")
161
+ for miss in sorted(used - screen_ids):
162
+ err(f"flows.md references {miss} but screens.md has no such screen")
163
+ for orphan in sorted(screen_ids - used):
164
+ warn(f"screens.md: {orphan} is used by no flow (orphan)")
165
+
166
+ # --- Scenario traces resolve ---
167
+ if ids(scenarios, "SCN"):
168
+ story_ids = set(ids(foundation, "ST"))
169
+ flow_ids = set(ids(flows, "FLW"))
170
+ traced_st = refs(scenarios, "ST")
171
+ traced_flw = refs(scenarios, "FLW")
172
+ if has_stories:
173
+ for miss in sorted(traced_st - story_ids):
174
+ warn(f"scenarios.md: traces to {miss} which is not in foundation.md")
175
+ if has_flows:
176
+ for miss in sorted(traced_flw - flow_ids):
177
+ warn(f"scenarios.md: traces to {miss} which is not in flows.md")
178
+
179
+ # --- must/should stories have a scenario ---
180
+ if has_stories and ids(scenarios, "SCN"):
181
+ traced = refs(scenarios, "ST")
182
+ for m in re.finditer(r"^###\s+(ST-\d+):", foundation, re.MULTILINE):
183
+ sid = m.group(1)
184
+ # Only this story's own body: stop at the next heading, so a
185
+ # neighbor's Priority line is never read as this story's.
186
+ tail = re.split(r"^#{2,3}\s", foundation[m.end():], maxsplit=1, flags=re.MULTILINE)[0]
187
+ if re.search(r"\*\*Priority:\*\*\s*(must|should)", tail, re.IGNORECASE):
188
+ if sid not in traced:
189
+ warn(f"foundation.md: {sid} (must/should) has no scenario tracing to it")
190
+
191
+ # --- Screen-level: Figma frames, coverage, drift status ---
192
+ if has_screens:
193
+ fig = figma_enabled(foundation)
194
+ for sid, body in screen_blocks(screens).items():
195
+ status_m = re.search(r"\*\*Status:\*\*\s*(designed|built|drifted|retired)", body)
196
+ status = status_m.group(1) if status_m else None
197
+ if status == "retired":
198
+ continue
199
+ # every state row present in the States table
200
+ state_rows = re.findall(r"^\s*\|\s*(loading|empty|error|success)\s*\|(.*)\|\s*$",
201
+ body, re.MULTILINE | re.IGNORECASE)
202
+ if fig is not False: # enabled or default-on
203
+ for state, rest in state_rows:
204
+ cells = [c.strip() for c in rest.split("|")]
205
+ frame = cells[1] if len(cells) >= 2 else ""
206
+ if not frame or frame in ("-", "—", "<frame deep-link>", "<frame link>"):
207
+ err(f"screens.md: {sid} state '{state}' has no Figma frame link")
208
+ cov_m = re.search(r"\*\*Coverage:\*\*\s*(.+)", body)
209
+ cov = cov_m.group(1).strip() if cov_m else ""
210
+ if status == "built" and (not cov or cov.lower().startswith("none")):
211
+ warn(f"screens.md: {sid} is 'built' but has no Coverage")
212
+
213
+ check_links(ux)
214
+
215
+ # --- Report ---
216
+ for e in ERRORS:
217
+ print(f"ERROR: {e}")
218
+ for w in WARNS:
219
+ print(f"warn: {w}")
220
+ total = len(ERRORS) + len(WARNS)
221
+ if not total:
222
+ print(f"OK — docs/ux is consistent ({ux})")
223
+ return 0
224
+ print(f"\n{len(ERRORS)} error(s), {len(WARNS)} warning(s)")
225
+ if ERRORS or (strict and WARNS):
226
+ return 1
227
+ return 0
228
+
229
+
230
+ if __name__ == "__main__":
231
+ sys.exit(main())
@@ -12,7 +12,7 @@ Personas · JTBD · Journeys · Stories → Flows → Screens → Scenario
12
12
 
13
13
  | File | Holds |
14
14
  |------|-------|
15
- | `foundation.md` | WHO & WHY: personas, jobs-to-be-done, journeys, user stories, monetization, Figma on/off |
15
+ | `foundation.md` | WHO & WHY: personas, jobs-to-be-done, journeys, user stories, monetization, Figma on/off + file URL |
16
16
  | `flows.md` | HOW: user-flow diagrams (screens, branches, error paths), referencing screens by `SCR-ID` |
17
17
  | `screens.md` | THE UI MAP: every screen and state with its Figma frame link, wireframe, code coverage, scenarios, resources |
18
18
  | `scenarios.md` | WHAT EXACTLY: use-case scenarios — the source of truth for behavior |
@@ -29,7 +29,9 @@ Personas · JTBD · Journeys · Stories → Flows → Screens → Scenario
29
29
  `scenarios.md`, affected flows, the affected screens in `screens.md`,
30
30
  and (Figma on) the Figma frame plus its link — together, not later.
31
31
  3. **No drift.** Code that diverges from a screen's record, or a stale Figma
32
- link, is a bug to fix.
32
+ link, is a bug to fix. The same goes for the look: one style pack is
33
+ recorded in `screens.md` → Design system (pick it with the
34
+ **sheleg-design** skill) and every screen obeys it.
33
35
  4. **Lint it.** Run `python3 docs/ux/lint.py` after changes and in CI.
34
36
 
35
37
  Maintained with the super-ux plugin. In Claude Code, run `/ux`.
@@ -14,10 +14,15 @@
14
14
  serve, which journey stage, which story — then flows and scenarios,
15
15
  validated against the existing base, approved.
16
16
  - **Do NOT write interface code until the UX workflow is done first:** the
17
- foundation → flows → scenarios chain is designed and approved, and — when
18
- Figma is enabled (default) — the UI is mocked up in Figma with every
19
- screen linked to its frame. Building UI before this is the exact mistake
20
- super-ux exists to prevent.
17
+ foundation → flows → screens → scenarios chain is designed and approved,
18
+ and — when Figma is enabled (default) — the UI is mocked up in Figma with
19
+ every screen linked to its frame. Building UI before this is the exact
20
+ mistake super-ux exists to prevent.
21
+ - Visual identity is ONE locked style pack, recorded in `docs/ux/screens.md`
22
+ → Design system and obeyed by every Figma frame and every built screen —
23
+ picked with the **sheleg-design** companion skill when the project has no
24
+ design system of its own (recommended, not required). Inventing a palette,
25
+ type pairing, or motion per screen is visual drift.
21
26
  - After any UX change and before calling the work done, run the linter
22
27
  `python3 docs/ux/lint.py` — it must pass (errors are drift/broken
23
28
  structure; wire it into CI/pre-commit).
@@ -27,4 +27,6 @@ flowchart TD
27
27
  |--------|------------------|
28
28
  | SCR-01 <name> | success |
29
29
  | SCR-02 <name> | error, success |
30
+ - **Wireframe:** wireframes/FLW-01.md (optional; per-screen wireframes live
31
+ under the screen's SCR-ID in screens.md)
30
32
  -->
@@ -13,6 +13,11 @@ whose code diverges from its record here is a "drifted" finding. -->
13
13
 
14
14
  ## Design system
15
15
 
16
+ <!-- Style pack = the locked visual identity every frame and built screen obeys.
17
+ Pick it with the sheleg-design companion skill (workbench for product UI /
18
+ dashboards / tools, instrument-console, editorial-luxury, or a new pack on its
19
+ contract) before drawing anything; record its token file below. -->
20
+ - **Style pack:** <pack name, or "none — platform defaults">
16
21
  - **Figma library:** <url/name, or "none — platform defaults">
17
22
  - **Tokens in code:** <where color/type/spacing tokens live, e.g. src/theme/tokens.ts>
18
23
  - **Component source:** <shared UI components dir, e.g. src/components/>