@urbicon-ui/design 6.1.8

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/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # @urbicon-ui/design
2
+
3
+ The **`urbicon` CLI** — version-pinned design validation and design-manifest
4
+ tooling for projects built with [Urbicon UI](https://ui.urbicon.de).
5
+
6
+ It is the local, version-correct half of the Urbicon design loop: the knowledge
7
+ and rules are the ones shipped with the `@urbicon-ui/*` version you installed, and
8
+ the filesystem operations (reading/writing your project's `design.manifest.md`)
9
+ run on your machine — things a public, stateless remote MCP server structurally
10
+ cannot do. Under the hood it wraps the zero-dependency
11
+ [`@urbicon-ui/design-engine`](../design-engine/); the same engine backs the remote
12
+ `validate_design` MCP tool, so local and remote verdicts agree.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ bun add -d @urbicon-ui/design # dev tooling — not a runtime dependency
18
+ ```
19
+
20
+ This exposes the `urbicon` command (a self-contained, Node-runnable bundle — no
21
+ Bun required at the consumer side).
22
+
23
+ ## Onboarding a consumer project
24
+
25
+ ```bash
26
+ bun add -d @urbicon-ui/design # then:
27
+ bunx urbicon init # wire the project into the design loop
28
+ ```
29
+
30
+ `urbicon init` is idempotent and non-destructive. It:
31
+
32
+ 1. **Gives the agent context** — inserts a managed `<!-- urbicon:start … -->` block into
33
+ `AGENTS.md` (or `--agents-file CLAUDE.md`) describing the tools, the design loop, and the
34
+ token rules. The single biggest lever on whether generated UI stays on-system.
35
+ 2. **Seeds the design memory** — scaffolds `design.manifest.md` (never overwriting an existing one).
36
+ 3. With `--hook`, merges the PostToolUse [gate](#enforcement--hook--ci) into `.claude/settings.json`;
37
+ with `--ci`, writes the design-gate workflow.
38
+
39
+ Then run the guided intake — `bunx urbicon verb adopt` (brownfield) or `onboard` (greenfield) —
40
+ to fill the manifest with this project's design intent. From there an agent can `urbicon context`
41
+ to read the intent, `urbicon find` / `get-component` to discover the catalog, compose, and
42
+ `urbicon validate` what it produced.
43
+
44
+ > The component knowledge is **local and version-pinned**: `@urbicon-ui/design` pulls in the
45
+ > [`@urbicon-ui/design-content`](../design-content/) bundle, so `find` / `get-component` match the
46
+ > library version you installed — no extra install, no skew against the latest-only hosted MCP.
47
+
48
+ ## Commands
49
+
50
+ | Command | What it does | Replaces (remote) |
51
+ | --- | --- | --- |
52
+ | `urbicon init` | Wire a project into the design loop (AGENTS.md block, manifest scaffold, `--hook`/`--ci`). | — (local only) |
53
+ | `urbicon validate [paths...]` | Lint `.svelte` markup against the design rules. The CI gate. | mirror of `validate_design` |
54
+ | `urbicon hook` | PostToolUse adapter — validate the just-edited file, block on failure. | — (local only) |
55
+ | `urbicon find [query]` | Fuzzy component discovery over the version-pinned catalog. | `find_components` |
56
+ | `urbicon get-component <slug>` | A component's API (its `llm.txt`) from the bundle. | `get_component` |
57
+ | `urbicon context` | Print the project's `design.manifest.md` summary. | `get_design_context` |
58
+ | `urbicon record-decision …` | Append an ADR to the manifest. | `record_design_decision` |
59
+ | `urbicon sync-manifest` | Re-index `data-design-pattern` markers into the manifest. | `sync_design_manifest` |
60
+ | `urbicon verbs` | List the design verbs (recipes over the design loop). | the MCP prompts |
61
+ | `urbicon verb <name>` | Print one verb recipe to stdout. | the MCP prompts |
62
+
63
+ The three manifest commands move off the remote server deliberately: a public
64
+ remote server has no access to your repo's filesystem, so manifest upkeep belongs
65
+ on the consumer side (this CLI, or the agent's own write tools). See
66
+ [docs/internal/DESIGN-MCP-V2.md](../../docs/internal/DESIGN-MCP-V2.md).
67
+
68
+ ### validate
69
+
70
+ ```bash
71
+ urbicon validate src/ # lint a whole tree (CI)
72
+ urbicon validate App.svelte --strict # fail on warnings too, not just errors
73
+ urbicon validate src/ --slop-floor 40 # also fail files scoring < 40/100 on slop
74
+ cat Page.svelte | urbicon validate - # lint stdin
75
+ urbicon validate src/ --json # machine-readable: { ok, slopFloor, results }
76
+ urbicon validate src/ --record # also append a drift entry to the history (CI)
77
+ ```
78
+
79
+ `validate` reads `## Token Overrides` from your `design.manifest.md` (if present)
80
+ and treats those token cores as valid, so a token your project defines on top of
81
+ Urbicon's is not flagged as hallucinated — the local, manifest-sourced counterpart
82
+ to the remote `validate_design(extraTokens)`. It only relaxes the
83
+ token-hallucination warning, never the error gates. `--record` appends one
84
+ `ValidationHistoryEntry` per run to the sidecar `design.manifest.history.ndjson`
85
+ so drift is measurable over time (CI opts in; the editor hook stays silent).
86
+
87
+ The linter scores two independent axes (DESIGN-MCP-V2 §6): **correctness** (raw
88
+ colours, `dark:`/`focus:`, hallucinated tokens — deterministic, always the
89
+ blocking gate) and **slop** (20 "looks generic" heuristics — advisory by default,
90
+ because they are FP-prone). `--slop-floor <n>` opts the slop axis into the gate:
91
+ any file scoring below `n` fails, checked per file so one generic page cannot hide
92
+ behind clean ones. Leave it off and slop stays informational.
93
+
94
+ Exit codes — designed for hooks and CI:
95
+
96
+ | Code | Meaning |
97
+ | --- | --- |
98
+ | `0` | Clean, or only warnings/notes |
99
+ | `1` | Failed — `validate` found errors (with `--strict`, warnings too), or a command could not complete (e.g. a manifest write error) |
100
+ | `2` | Usage error — bad flags / unreadable input |
101
+
102
+ `--skip-heuristics` runs only the deterministic rules (no distribution notes).
103
+
104
+ ### context / record-decision / sync-manifest
105
+
106
+ ```bash
107
+ urbicon context # summarise ./design.manifest.md
108
+ urbicon context --json # the parsed manifest (+ history) as JSON
109
+
110
+ urbicon record-decision \
111
+ --title "Tabs for settings" \
112
+ --decision "Use Tab over Sidebar" \
113
+ --rationale "Three groups, shallow nesting"
114
+
115
+ urbicon sync-manifest # scan ./src for data-design-pattern markers
116
+ urbicon sync-manifest --src app --manifest app/design.manifest.md
117
+ ```
118
+
119
+ `context` summarises the whole manifest — the product intent (audience, voice,
120
+ references, anti-references), the token overrides, the pattern-usage index, the
121
+ recorded ADRs — and, when a `*.history.ndjson` sidecar exists, the recent
122
+ validation-drift trend. All commands default the manifest to
123
+ `./design.manifest.md` and the scan root to `./src`; override with `--manifest`
124
+ / `--src`.
125
+
126
+ The manifest is a plain Markdown file with these sections (`urbicon` creates a
127
+ scaffold on first write):
128
+
129
+ ```markdown
130
+ ## Product Intent
131
+ **Audience:** who uses this — context, constraints, expertise
132
+ **Voice:** three adjectives, comma-separated
133
+ **References:** / **Anti-references:** bullet (or comma) lists
134
+
135
+ ## Token Overrides
136
+ - `surface-brand` # project tokens `urbicon validate` should accept
137
+
138
+ ## Pattern Usages # auto-generated by sync-manifest
139
+ ## Design Decisions # append-only ADRs from record-decision
140
+ ```
141
+
142
+ ## Design verbs
143
+
144
+ Ten recipes that string the knowledge, the linter, and the manifest into one loop —
145
+ the same single source served remotely as MCP prompts (DESIGN-MCP-V2 §8). They ship
146
+ in this package under `skill/`, so they run offline and version-locked.
147
+
148
+ ```bash
149
+ urbicon verbs # list them
150
+ urbicon verb compose # print one recipe — pipe it to an agent, or read it inline
151
+ ```
152
+
153
+ | Verb | Use-case |
154
+ | --- | --- |
155
+ | `onboard` / `adopt` | seed the manifest for a greenfield / brownfield project |
156
+ | `compose` / `redesign` / `polish` | build / rework / tighten a page (gated on linter + rubric) |
157
+ | `critique` / `fix` | judge without changing / repair correctness defects |
158
+ | `retheme` / `audit` / `migrate` | rebrand / check consistency / roll out a change app-wide |
159
+
160
+ `skill/SKILL.md` is the router (intent → verb). Every recipe opens by reading the
161
+ manifest and closes by writing the decision back.
162
+
163
+ ## Enforcement — hook + CI
164
+
165
+ The gate runs in two places a stateless remote server structurally cannot reach:
166
+ at edit time (a Claude Code hook) and in CI. Ready-to-copy templates ship in
167
+ [`templates/`](./templates/).
168
+
169
+ **Edit-time hook.** Wire `urbicon hook` as a `PostToolUse` hook so every edited
170
+ `.svelte` file is validated the moment it is written — the loop becomes enforced,
171
+ not something the agent must remember. On a failure the hook exits 2 and the
172
+ findings are fed back to the agent to fix; a clean edit is silent. Merge
173
+ [`templates/claude-settings.json`](./templates/claude-settings.json) into your
174
+ `.claude/settings.json`:
175
+
176
+ ```json
177
+ {
178
+ "hooks": {
179
+ "PostToolUse": [
180
+ { "matcher": "Edit|MultiEdit|Write", "hooks": [{ "type": "command", "command": "urbicon hook" }] }
181
+ ]
182
+ }
183
+ }
184
+ ```
185
+
186
+ Add `--slop-floor 40` to the command to gate the slop axis too. (`urbicon hook`
187
+ reads the edited path from the hook event on stdin — it does not take path
188
+ arguments.)
189
+
190
+ **CI.** Run `urbicon validate` over your source tree; a non-zero exit fails the
191
+ build. Copy [`templates/ci-github.yml`](./templates/ci-github.yml), or add one step
192
+ to an existing workflow:
193
+
194
+ ```bash
195
+ bunx urbicon validate src/ --json # correctness gate (blocking)
196
+ # add --slop-floor 40 to also gate the slop axis — one run, correctness is always on
197
+ ```
198
+
199
+ ## Notes
200
+
201
+ - Bundled to `dist/cli.js` at publish time (`bun build --target node`, shebang
202
+ preserved). In the monorepo, run the TypeScript source directly:
203
+ `bun run packages/design/src/cli/index.ts <command>`.
204
+ - `validate` / `hook` / `context` / `record-decision` / `sync-manifest` / `init` are
205
+ content-free (engine + your repo only); `verbs` / `verb` read the recipes shipped
206
+ under `skill/` (package-relative, still no content-bundle dependency).
207
+ - `find` / `get-component` read the version-pinned
208
+ [`@urbicon-ui/design-content`](../design-content/) bundle (a runtime dependency). Icon
209
+ search (`find_icons`) and the guided onboarding *interview* stay on the remote MCP and the
210
+ `adopt` / `onboard` verbs respectively.
211
+
212
+ ## Related
213
+
214
+ - [`@urbicon-ui/design-engine`](../design-engine/) — the deterministic engine this CLI wraps
215
+ - [`@urbicon-ui/mcp-server`](../mcp-server/) — the remote MCP adapter over the same engine