rafters 0.0.55 → 0.0.57
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 +78 -47
- package/dist/index.js +30 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# rafters
|
|
2
2
|
|
|
3
|
-
Design Intelligence CLI.
|
|
3
|
+
Design Intelligence CLI. Encodes a designer's judgment into queryable data so AI agents read decisions instead of guessing at colors, spacing, hierarchy.
|
|
4
|
+
|
|
5
|
+
→ [rafters.studio](https://rafters.studio)
|
|
6
|
+
|
|
7
|
+
**60+ components across React, Astro, and Web Components.** Triple-target parity from one design system — the same Button, Card, Dialog, Combobox, Editor, etc. as a React component, an Astro component, AND a Web Component element class. Component code is installed into your project via `rafters add` (shadcn-style copy), not imported as a dependency, so you own and can fork what ships.
|
|
8
|
+
|
|
9
|
+
**Composite manifests sit above components.** A composite is a designer-authored JSON manifest that bundles components into reusable patterns (login-form, copy-button, heading, paragraph) with designer intent baked in: `solves`, `appliesWhen`, do/never rules, cognitive load rating, I/O contracts, and a typed block tree. Agents query the composite registry via MCP and assemble pre-made decisions instead of inventing new ones.
|
|
4
10
|
|
|
5
11
|
## Quick Start
|
|
6
12
|
|
|
@@ -8,24 +14,31 @@ Design Intelligence CLI. Scaffold tokens, add components, and serve an MCP serve
|
|
|
8
14
|
pnpm dlx rafters init
|
|
9
15
|
```
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
`init` detects your framework, reads your existing CSS (shadcn or Tailwind v4 `@theme` blocks), and produces a complete token system that imports your brand decisions and derives the rest mathematically.
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## What `init` does
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
On the first run against an existing project, `init` runs an import flow that lifts brand decisions out of your CSS into the token system. Every step emits a discrete event you can read with `--agent`:
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
- **Pre-generation base detection** — reads `--spacing` / `--spacing-base`, `--radius` / `--radius-base`, `--text-base` / `--font-size-base`, `--ring-width` / `--focus-ring-width` and threads them into the token generator BEFORE construction. The cascade flows correctly from the first generation; derived namespaces (spacing scale, shadow numerics, radius scale, focus tokens) all match the imported base.
|
|
24
|
+
- **Color import** — walks `:root` semantic declarations (`--primary`, `--background`, etc.) AND `@theme { ... }` multi-palette blocks (Tailwind v4 brand palette convention). Detects ramps (palette-0 through palette-950), runs a designer-driven role-walk in interactive mode or auto-assigns in `--agent` mode.
|
|
25
|
+
- **Font role-walk** — detects every font family loaded by the source (`@import url(google fonts)`, `@font-face`, named `--font-*` declarations) and assigns each to a typography role (`font-heading`, `font-body`, `font-code`). Custom fonts that don't fit a canonical role become their own tokens (`font-aurabesh`, `font-mydisplay`, etc.) so consumers can reference them via Tailwind utilities.
|
|
26
|
+
- **Motion is intentionally untouched** — rafters' motion system is research-backed (perceptual response curves, cognitive thresholds, reduced-motion accommodations); arbitrary `--duration-base` declarations in source are NOT auto-applied. Use `rafters set motion-duration-base ...` if you specifically need to override.
|
|
27
|
+
|
|
28
|
+
### Modes
|
|
18
29
|
|
|
19
30
|
```bash
|
|
20
|
-
pnpm dlx rafters init # Interactive
|
|
21
|
-
pnpm dlx rafters init --
|
|
22
|
-
pnpm dlx rafters init --
|
|
23
|
-
pnpm dlx rafters init --
|
|
31
|
+
pnpm dlx rafters init # Interactive prompts for role assignments
|
|
32
|
+
pnpm dlx rafters init --agent # Non-interactive; auto-assigns; emits JSON events
|
|
33
|
+
pnpm dlx rafters init --rebuild # Regenerate output files from existing .rafters/tokens
|
|
34
|
+
pnpm dlx rafters init --reset # Re-run generators from defaults, replacing tokens
|
|
24
35
|
```
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
### Detected frameworks
|
|
38
|
+
|
|
39
|
+
Next.js, Vite, Remix, React Router, Astro, Web Components, vanilla.
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
### Export formats
|
|
29
42
|
|
|
30
43
|
| Format | File | Default | Description |
|
|
31
44
|
|--------|------|---------|-------------|
|
|
@@ -34,19 +47,29 @@ pnpm dlx rafters init --agent # JSON output for CI/machine consumption
|
|
|
34
47
|
| DTCG JSON | `rafters.json` | No | W3C Design Tokens standard format |
|
|
35
48
|
| Standalone CSS | `rafters.standalone.css` | No | Pre-built, no Tailwind required |
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
Requires Tailwind v4. Tailwind v3 projects are rejected.
|
|
51
|
+
|
|
52
|
+
## Other commands
|
|
38
53
|
|
|
39
54
|
### `rafters add [components...]`
|
|
40
55
|
|
|
41
|
-
Add components from the
|
|
56
|
+
Add components from the rafters registry to your project.
|
|
42
57
|
|
|
43
58
|
```bash
|
|
44
59
|
pnpm dlx rafters add button dialog # Add specific components
|
|
45
|
-
pnpm dlx rafters add --list # List
|
|
60
|
+
pnpm dlx rafters add --list # List available components
|
|
46
61
|
pnpm dlx rafters add --overwrite # Replace existing files
|
|
47
62
|
```
|
|
48
63
|
|
|
49
|
-
|
|
64
|
+
Each component carries embedded design intelligence (cognitive load, accessibility, do/never guidance, variant patterns). Dependencies resolve automatically.
|
|
65
|
+
|
|
66
|
+
### `rafters set <name> <value>`
|
|
67
|
+
|
|
68
|
+
Override a token value with a recorded reason. The previous value and the why-gate land as `userOverride` metadata so future agents can read your intent.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pnpm dlx rafters set spacing-base 0.5rem --reason "denser layout for data-heavy UI"
|
|
72
|
+
```
|
|
50
73
|
|
|
51
74
|
### `rafters mcp`
|
|
52
75
|
|
|
@@ -58,89 +81,97 @@ pnpm dlx rafters mcp
|
|
|
58
81
|
|
|
59
82
|
### `rafters studio`
|
|
60
83
|
|
|
61
|
-
Launch Studio for visual token editing.
|
|
84
|
+
Launch Studio for visual token editing.
|
|
62
85
|
|
|
63
86
|
```bash
|
|
64
87
|
pnpm dlx rafters studio
|
|
65
88
|
```
|
|
66
89
|
|
|
67
|
-
## MCP
|
|
90
|
+
## MCP tools
|
|
68
91
|
|
|
69
|
-
Four tools
|
|
92
|
+
Four tools for agent ASSEMBLY (not design). Token design lives in Studio; import lives in `rafters init`. Agents read pre-made decisions; they do not author them.
|
|
70
93
|
|
|
71
94
|
### `rafters_composite`
|
|
72
95
|
|
|
73
|
-
Query composites by ID, search term, or category. Returns designer intent (solves, appliesWhen, do/never), I/O rules
|
|
96
|
+
Query composites by ID, search term, or category. Returns designer intent (solves, appliesWhen, do/never), I/O rules, and block structure.
|
|
74
97
|
|
|
75
98
|
```json
|
|
76
|
-
{ "id": "
|
|
77
|
-
{ "query": "form" } // Fuzzy search
|
|
78
|
-
{ "category": "typography" } // Filter
|
|
99
|
+
{ "id": "login-form" } // Get a specific composite
|
|
100
|
+
{ "query": "form" } // Fuzzy search across composites
|
|
101
|
+
{ "category": "typography" } // Filter
|
|
79
102
|
```
|
|
80
103
|
|
|
81
104
|
### `rafters_pattern`
|
|
82
105
|
|
|
83
|
-
Design pattern guidance by querying composites. Search by what the
|
|
106
|
+
Design pattern guidance by querying composites. Search by what the page or section SOLVES.
|
|
84
107
|
|
|
85
108
|
```json
|
|
86
|
-
{ "solves": "
|
|
87
|
-
{ "solves": "
|
|
88
|
-
{ "query": "
|
|
109
|
+
{ "solves": "authentication" }
|
|
110
|
+
{ "solves": "data entry" }
|
|
111
|
+
{ "query": "navigation" }
|
|
89
112
|
```
|
|
90
113
|
|
|
91
|
-
Returns composites with usagePatterns (do/never
|
|
114
|
+
Returns composites with usagePatterns (do/never), cognitive load, and intent.
|
|
92
115
|
|
|
93
116
|
### `rafters_rule`
|
|
94
117
|
|
|
95
|
-
Query validation rules or create new ones. Rules are named
|
|
118
|
+
Query validation rules or create new ones. Rules are named patterns composites apply to inputs.
|
|
96
119
|
|
|
97
120
|
```json
|
|
98
121
|
{} // List all rules
|
|
99
|
-
{ "name": "email" } // Get specific rule
|
|
100
|
-
{ "query": "pass" } // Search rules
|
|
122
|
+
{ "name": "email" } // Get a specific rule
|
|
101
123
|
```
|
|
102
124
|
|
|
103
|
-
|
|
125
|
+
Built-in: `required`, `email`, `password`, `url`, `credentials`.
|
|
104
126
|
|
|
105
127
|
### `rafters_component`
|
|
106
128
|
|
|
107
|
-
Full intelligence for a specific component
|
|
129
|
+
Full intelligence for a specific component: cognitive load, accessibility level, variants, sizes, do/never.
|
|
108
130
|
|
|
109
131
|
```json
|
|
110
132
|
{ "name": "button" }
|
|
111
133
|
```
|
|
112
134
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
Rafters is a Design Intelligence Protocol. AI agents don't have taste -- they guess at colors, spacing, hierarchy. Rafters encodes a designer's judgment into queryable data so AI reads decisions instead of guessing.
|
|
135
|
+
## Architecture
|
|
116
136
|
|
|
117
|
-
|
|
137
|
+
Four layers, stacked:
|
|
118
138
|
|
|
119
|
-
- **
|
|
120
|
-
- **
|
|
121
|
-
- **
|
|
139
|
+
- **Tokens** — primitive design values (color OKLCH, spacing scale, radius, typography, motion, focus, shadow, depth, elevation, breakpoints). 13 namespaces; dependency graph with human override tracking. Override a base (`spacing-base`, `radius-base`, `font-size-base`) and dependents recompute. Override a leaf and the override anchors the subtree.
|
|
140
|
+
- **Primitives** — 62 framework-agnostic building blocks (clipboard, focus-trap, portal, roving-focus, selection, serializer, slot, token-sheet, typeahead, etc.). Headless behaviors components compose against.
|
|
141
|
+
- **Components** — 60+ React + 71 Astro + 32 Web Component element classes. Triple-target parity. Each component carries embedded intelligence metadata: cognitive load rating, accessibility level, do/never, variant semantics, attention economics. Installed into your project via `rafters add` — you own the code.
|
|
142
|
+
- **Composites** — designer-authored JSON manifests that bundle components into reusable patterns (login-form, copy-button, heading, paragraph, etc.). Each manifest carries `solves`, `appliesWhen`, `usagePatterns` (do/never), `cognitiveLoad`, I/O contracts, and a typed block tree. The composite owns the variant/size decisions — agents render blocks verbatim instead of choosing aesthetics.
|
|
122
143
|
|
|
123
|
-
|
|
144
|
+
When a designer overrides a computed value, the system records the reason. Agents read the why before they read the what.
|
|
124
145
|
|
|
125
|
-
## Project
|
|
146
|
+
## Project structure
|
|
126
147
|
|
|
127
148
|
```
|
|
128
149
|
.rafters/
|
|
129
150
|
config.rafters.json # Framework paths and export settings
|
|
130
151
|
tokens/
|
|
131
|
-
color.rafters.json
|
|
132
|
-
spacing.rafters.json
|
|
133
|
-
typography.rafters.json
|
|
152
|
+
color.rafters.json
|
|
153
|
+
spacing.rafters.json
|
|
154
|
+
typography.rafters.json
|
|
155
|
+
radius.rafters.json
|
|
156
|
+
shadow.rafters.json
|
|
157
|
+
focus.rafters.json
|
|
158
|
+
motion.rafters.json
|
|
159
|
+
depth.rafters.json
|
|
160
|
+
elevation.rafters.json
|
|
161
|
+
breakpoint.rafters.json
|
|
162
|
+
semantic.rafters.json
|
|
163
|
+
fill.rafters.json
|
|
164
|
+
typography-composite.rafters.json
|
|
134
165
|
output/
|
|
135
|
-
rafters.css # Tailwind CSS
|
|
166
|
+
rafters.css # Tailwind v4 CSS variables
|
|
136
167
|
rafters.ts # TypeScript constants
|
|
137
168
|
```
|
|
138
169
|
|
|
139
170
|
## Requirements
|
|
140
171
|
|
|
141
|
-
- Node.js
|
|
172
|
+
- Node.js ≥ 24.12.0
|
|
142
173
|
- Tailwind CSS v4
|
|
143
|
-
- React
|
|
174
|
+
- React ≥ 19.0.0 (when using React components)
|
|
144
175
|
|
|
145
176
|
## License
|
|
146
177
|
|
package/dist/index.js
CHANGED
|
@@ -29084,6 +29084,20 @@ ${cssContent}`;
|
|
|
29084
29084
|
function isInteractive() {
|
|
29085
29085
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
29086
29086
|
}
|
|
29087
|
+
function resolveSourceCssPath(cwd, framework, detectedFramework, projectCssPath, shadcnCssPath, emit) {
|
|
29088
|
+
if (shadcnCssPath) {
|
|
29089
|
+
if (existsSync3(join7(cwd, shadcnCssPath))) return shadcnCssPath;
|
|
29090
|
+
const fallback = framework === detectedFramework ? projectCssPath : findCssPath(cwd, framework);
|
|
29091
|
+
emit({
|
|
29092
|
+
event: "init:shadcn_css_missing",
|
|
29093
|
+
configuredPath: shadcnCssPath,
|
|
29094
|
+
fallbackPath: fallback,
|
|
29095
|
+
message: "components.json points at a CSS file that does not exist. Falling back to the framework canonical location."
|
|
29096
|
+
});
|
|
29097
|
+
return fallback;
|
|
29098
|
+
}
|
|
29099
|
+
return framework === detectedFramework ? projectCssPath : findCssPath(cwd, framework);
|
|
29100
|
+
}
|
|
29087
29101
|
function slugifyFontName(name) {
|
|
29088
29102
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
29089
29103
|
}
|
|
@@ -29415,7 +29429,14 @@ async function init(options) {
|
|
|
29415
29429
|
log({ event: "init:exports_selected", exports });
|
|
29416
29430
|
}
|
|
29417
29431
|
const baseConfig = {};
|
|
29418
|
-
const sourceCssPathForBase =
|
|
29432
|
+
const sourceCssPathForBase = resolveSourceCssPath(
|
|
29433
|
+
cwd,
|
|
29434
|
+
framework,
|
|
29435
|
+
detectedFramework,
|
|
29436
|
+
project.cssPath,
|
|
29437
|
+
shadcn?.tailwind?.css,
|
|
29438
|
+
log
|
|
29439
|
+
);
|
|
29419
29440
|
if (sourceCssPathForBase !== null) {
|
|
29420
29441
|
try {
|
|
29421
29442
|
const cssForBase = await readFile4(join7(cwd, sourceCssPathForBase), "utf-8");
|
|
@@ -29478,8 +29499,15 @@ async function init(options) {
|
|
|
29478
29499
|
});
|
|
29479
29500
|
const outputs = await generateOutputs(cwd, paths, registry2, exports, shadcn);
|
|
29480
29501
|
let detectedCssPath = null;
|
|
29502
|
+
detectedCssPath = resolveSourceCssPath(
|
|
29503
|
+
cwd,
|
|
29504
|
+
framework,
|
|
29505
|
+
detectedFramework,
|
|
29506
|
+
project.cssPath,
|
|
29507
|
+
shadcn?.tailwind?.css,
|
|
29508
|
+
log
|
|
29509
|
+
);
|
|
29481
29510
|
if (!shadcn && exports.tailwind) {
|
|
29482
|
-
detectedCssPath = framework === detectedFramework ? project.cssPath : findCssPath(cwd, framework);
|
|
29483
29511
|
if (detectedCssPath) {
|
|
29484
29512
|
await updateMainCss(cwd, detectedCssPath, ".rafters/output/rafters.css");
|
|
29485
29513
|
} else {
|
|
@@ -29489,8 +29517,6 @@ async function init(options) {
|
|
|
29489
29517
|
searchedLocations: FRAMEWORK_SPECS[framework].cssLocations
|
|
29490
29518
|
});
|
|
29491
29519
|
}
|
|
29492
|
-
} else if (shadcn?.tailwind?.css) {
|
|
29493
|
-
detectedCssPath = shadcn.tailwind.css;
|
|
29494
29520
|
}
|
|
29495
29521
|
let componentTarget = frameworkToTarget(framework);
|
|
29496
29522
|
if (framework === "astro" && astroHasReact && isInteractive() && !isAgentMode2) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rafters",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "CLI
|
|
3
|
+
"version": "0.0.57",
|
|
4
|
+
"description": "Design Intelligence CLI. Scaffold tokens, import existing shadcn/Tailwind v4 sources, add components, and serve an MCP server so AI agents read decisions instead of guessing.",
|
|
5
|
+
"homepage": "https://rafters.studio",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"bin": {
|