rafters 0.0.55 → 0.0.56
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 +74 -46
- package/dist/index.js +31 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
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)
|
|
4
6
|
|
|
5
7
|
## Quick Start
|
|
6
8
|
|
|
@@ -8,24 +10,31 @@ Design Intelligence CLI. Scaffold tokens, add components, and serve an MCP serve
|
|
|
8
10
|
pnpm dlx rafters init
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
`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.
|
|
14
|
+
|
|
15
|
+
## What `init` does
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
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`:
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
- **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.
|
|
20
|
+
- **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.
|
|
21
|
+
- **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.
|
|
22
|
+
- **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.
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
### Modes
|
|
18
25
|
|
|
19
26
|
```bash
|
|
20
|
-
pnpm dlx rafters init # Interactive
|
|
21
|
-
pnpm dlx rafters init --
|
|
22
|
-
pnpm dlx rafters init --
|
|
23
|
-
pnpm dlx rafters init --
|
|
27
|
+
pnpm dlx rafters init # Interactive prompts for role assignments
|
|
28
|
+
pnpm dlx rafters init --agent # Non-interactive; auto-assigns; emits JSON events
|
|
29
|
+
pnpm dlx rafters init --rebuild # Regenerate output files from existing .rafters/tokens
|
|
30
|
+
pnpm dlx rafters init --reset # Re-run generators from defaults, replacing tokens
|
|
24
31
|
```
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
### Detected frameworks
|
|
34
|
+
|
|
35
|
+
Next.js, Vite, Remix, React Router, Astro, Web Components, vanilla.
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
### Export formats
|
|
29
38
|
|
|
30
39
|
| Format | File | Default | Description |
|
|
31
40
|
|--------|------|---------|-------------|
|
|
@@ -34,19 +43,29 @@ pnpm dlx rafters init --agent # JSON output for CI/machine consumption
|
|
|
34
43
|
| DTCG JSON | `rafters.json` | No | W3C Design Tokens standard format |
|
|
35
44
|
| Standalone CSS | `rafters.standalone.css` | No | Pre-built, no Tailwind required |
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
Requires Tailwind v4. Tailwind v3 projects are rejected.
|
|
47
|
+
|
|
48
|
+
## Other commands
|
|
38
49
|
|
|
39
50
|
### `rafters add [components...]`
|
|
40
51
|
|
|
41
|
-
Add components from the
|
|
52
|
+
Add components from the rafters registry to your project.
|
|
42
53
|
|
|
43
54
|
```bash
|
|
44
55
|
pnpm dlx rafters add button dialog # Add specific components
|
|
45
|
-
pnpm dlx rafters add --list # List
|
|
56
|
+
pnpm dlx rafters add --list # List available components
|
|
46
57
|
pnpm dlx rafters add --overwrite # Replace existing files
|
|
47
58
|
```
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
Each component carries embedded design intelligence (cognitive load, accessibility, do/never guidance, variant patterns). Dependencies resolve automatically.
|
|
61
|
+
|
|
62
|
+
### `rafters set <name> <value>`
|
|
63
|
+
|
|
64
|
+
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.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm dlx rafters set spacing-base 0.5rem --reason "denser layout for data-heavy UI"
|
|
68
|
+
```
|
|
50
69
|
|
|
51
70
|
### `rafters mcp`
|
|
52
71
|
|
|
@@ -58,89 +77,98 @@ pnpm dlx rafters mcp
|
|
|
58
77
|
|
|
59
78
|
### `rafters studio`
|
|
60
79
|
|
|
61
|
-
Launch Studio for visual token editing.
|
|
80
|
+
Launch Studio for visual token editing.
|
|
62
81
|
|
|
63
82
|
```bash
|
|
64
83
|
pnpm dlx rafters studio
|
|
65
84
|
```
|
|
66
85
|
|
|
67
|
-
## MCP
|
|
86
|
+
## MCP tools
|
|
68
87
|
|
|
69
|
-
Four tools
|
|
88
|
+
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
89
|
|
|
71
90
|
### `rafters_composite`
|
|
72
91
|
|
|
73
|
-
Query composites by ID, search term, or category. Returns designer intent (solves, appliesWhen, do/never), I/O rules
|
|
92
|
+
Query composites by ID, search term, or category. Returns designer intent (solves, appliesWhen, do/never), I/O rules, and block structure.
|
|
74
93
|
|
|
75
94
|
```json
|
|
76
|
-
{ "id": "
|
|
77
|
-
{ "query": "form" } // Fuzzy search
|
|
78
|
-
{ "category": "typography" } // Filter
|
|
95
|
+
{ "id": "login-form" } // Get a specific composite
|
|
96
|
+
{ "query": "form" } // Fuzzy search across composites
|
|
97
|
+
{ "category": "typography" } // Filter
|
|
79
98
|
```
|
|
80
99
|
|
|
81
100
|
### `rafters_pattern`
|
|
82
101
|
|
|
83
|
-
Design pattern guidance by querying composites. Search by what the
|
|
102
|
+
Design pattern guidance by querying composites. Search by what the page or section SOLVES.
|
|
84
103
|
|
|
85
104
|
```json
|
|
86
|
-
{ "solves": "
|
|
87
|
-
{ "solves": "
|
|
88
|
-
{ "query": "
|
|
105
|
+
{ "solves": "authentication" }
|
|
106
|
+
{ "solves": "data entry" }
|
|
107
|
+
{ "query": "navigation" }
|
|
89
108
|
```
|
|
90
109
|
|
|
91
|
-
Returns composites with usagePatterns (do/never
|
|
110
|
+
Returns composites with usagePatterns (do/never), cognitive load, and intent.
|
|
92
111
|
|
|
93
112
|
### `rafters_rule`
|
|
94
113
|
|
|
95
|
-
Query validation rules or create new ones. Rules are named
|
|
114
|
+
Query validation rules or create new ones. Rules are named patterns composites apply to inputs.
|
|
96
115
|
|
|
97
116
|
```json
|
|
98
117
|
{} // List all rules
|
|
99
|
-
{ "name": "email" } // Get specific rule
|
|
100
|
-
{ "query": "pass" } // Search rules
|
|
118
|
+
{ "name": "email" } // Get a specific rule
|
|
101
119
|
```
|
|
102
120
|
|
|
103
|
-
|
|
121
|
+
Built-in: `required`, `email`, `password`, `url`, `credentials`.
|
|
104
122
|
|
|
105
123
|
### `rafters_component`
|
|
106
124
|
|
|
107
|
-
Full intelligence for a specific component
|
|
125
|
+
Full intelligence for a specific component: cognitive load, accessibility level, variants, sizes, do/never.
|
|
108
126
|
|
|
109
127
|
```json
|
|
110
128
|
{ "name": "button" }
|
|
111
129
|
```
|
|
112
130
|
|
|
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.
|
|
131
|
+
## Architecture
|
|
116
132
|
|
|
117
133
|
Three layers:
|
|
118
134
|
|
|
119
|
-
- **What
|
|
120
|
-
- **Where
|
|
121
|
-
- **Why
|
|
135
|
+
- **What (Components)** — React components with embedded intelligence metadata
|
|
136
|
+
- **Where (Tokens)** — token dependency graph with human override tracking
|
|
137
|
+
- **Why (Decisions)** — composite manifests, do/never patterns, cognitive load scores, trust-building patterns
|
|
138
|
+
|
|
139
|
+
The token system uses OKLCH color space, modular scales based on musical ratios, and a dependency engine that derives related values from primitive bases. Override a base — `spacing-base`, `radius-base`, `font-size-base` — and dependents recompute. Override a leaf (`primary` color, `spacing-4`) and the override anchors the subtree against future upstream changes.
|
|
122
140
|
|
|
123
|
-
|
|
141
|
+
When a designer overrides a computed value, the system records the reason. Agents read the why before they read the what.
|
|
124
142
|
|
|
125
|
-
## Project
|
|
143
|
+
## Project structure
|
|
126
144
|
|
|
127
145
|
```
|
|
128
146
|
.rafters/
|
|
129
147
|
config.rafters.json # Framework paths and export settings
|
|
130
148
|
tokens/
|
|
131
|
-
color.rafters.json
|
|
132
|
-
spacing.rafters.json
|
|
133
|
-
typography.rafters.json
|
|
149
|
+
color.rafters.json
|
|
150
|
+
spacing.rafters.json
|
|
151
|
+
typography.rafters.json
|
|
152
|
+
radius.rafters.json
|
|
153
|
+
shadow.rafters.json
|
|
154
|
+
focus.rafters.json
|
|
155
|
+
motion.rafters.json
|
|
156
|
+
depth.rafters.json
|
|
157
|
+
elevation.rafters.json
|
|
158
|
+
breakpoint.rafters.json
|
|
159
|
+
semantic.rafters.json
|
|
160
|
+
fill.rafters.json
|
|
161
|
+
typography-composite.rafters.json
|
|
134
162
|
output/
|
|
135
|
-
rafters.css # Tailwind CSS
|
|
163
|
+
rafters.css # Tailwind v4 CSS variables
|
|
136
164
|
rafters.ts # TypeScript constants
|
|
137
165
|
```
|
|
138
166
|
|
|
139
167
|
## Requirements
|
|
140
168
|
|
|
141
|
-
- Node.js
|
|
169
|
+
- Node.js ≥ 24.12.0
|
|
142
170
|
- Tailwind CSS v4
|
|
143
|
-
- React
|
|
171
|
+
- React ≥ 19.0.0 (when using React components)
|
|
144
172
|
|
|
145
173
|
## License
|
|
146
174
|
|
package/dist/index.js
CHANGED
|
@@ -28494,6 +28494,7 @@ function firstFamilyFromStack(value) {
|
|
|
28494
28494
|
for (const raw of parts) {
|
|
28495
28495
|
const stripped = stripQuotes(raw.trim());
|
|
28496
28496
|
if (stripped === "" || GENERIC_KEYWORDS.has(stripped.toLowerCase())) continue;
|
|
28497
|
+
if (stripped.startsWith("var(") || stripped.includes("var(--")) continue;
|
|
28497
28498
|
return stripped;
|
|
28498
28499
|
}
|
|
28499
28500
|
return null;
|
|
@@ -29084,6 +29085,20 @@ ${cssContent}`;
|
|
|
29084
29085
|
function isInteractive() {
|
|
29085
29086
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
29086
29087
|
}
|
|
29088
|
+
function resolveSourceCssPath(cwd, framework, detectedFramework, projectCssPath, shadcnCssPath, emit) {
|
|
29089
|
+
if (shadcnCssPath) {
|
|
29090
|
+
if (existsSync3(join7(cwd, shadcnCssPath))) return shadcnCssPath;
|
|
29091
|
+
const fallback = framework === detectedFramework ? projectCssPath : findCssPath(cwd, framework);
|
|
29092
|
+
emit({
|
|
29093
|
+
event: "init:shadcn_css_missing",
|
|
29094
|
+
configuredPath: shadcnCssPath,
|
|
29095
|
+
fallbackPath: fallback,
|
|
29096
|
+
message: "components.json points at a CSS file that does not exist. Falling back to the framework canonical location."
|
|
29097
|
+
});
|
|
29098
|
+
return fallback;
|
|
29099
|
+
}
|
|
29100
|
+
return framework === detectedFramework ? projectCssPath : findCssPath(cwd, framework);
|
|
29101
|
+
}
|
|
29087
29102
|
function slugifyFontName(name) {
|
|
29088
29103
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
29089
29104
|
}
|
|
@@ -29415,7 +29430,14 @@ async function init(options) {
|
|
|
29415
29430
|
log({ event: "init:exports_selected", exports });
|
|
29416
29431
|
}
|
|
29417
29432
|
const baseConfig = {};
|
|
29418
|
-
const sourceCssPathForBase =
|
|
29433
|
+
const sourceCssPathForBase = resolveSourceCssPath(
|
|
29434
|
+
cwd,
|
|
29435
|
+
framework,
|
|
29436
|
+
detectedFramework,
|
|
29437
|
+
project.cssPath,
|
|
29438
|
+
shadcn?.tailwind?.css,
|
|
29439
|
+
log
|
|
29440
|
+
);
|
|
29419
29441
|
if (sourceCssPathForBase !== null) {
|
|
29420
29442
|
try {
|
|
29421
29443
|
const cssForBase = await readFile4(join7(cwd, sourceCssPathForBase), "utf-8");
|
|
@@ -29478,8 +29500,15 @@ async function init(options) {
|
|
|
29478
29500
|
});
|
|
29479
29501
|
const outputs = await generateOutputs(cwd, paths, registry2, exports, shadcn);
|
|
29480
29502
|
let detectedCssPath = null;
|
|
29503
|
+
detectedCssPath = resolveSourceCssPath(
|
|
29504
|
+
cwd,
|
|
29505
|
+
framework,
|
|
29506
|
+
detectedFramework,
|
|
29507
|
+
project.cssPath,
|
|
29508
|
+
shadcn?.tailwind?.css,
|
|
29509
|
+
log
|
|
29510
|
+
);
|
|
29481
29511
|
if (!shadcn && exports.tailwind) {
|
|
29482
|
-
detectedCssPath = framework === detectedFramework ? project.cssPath : findCssPath(cwd, framework);
|
|
29483
29512
|
if (detectedCssPath) {
|
|
29484
29513
|
await updateMainCss(cwd, detectedCssPath, ".rafters/output/rafters.css");
|
|
29485
29514
|
} else {
|
|
@@ -29489,8 +29518,6 @@ async function init(options) {
|
|
|
29489
29518
|
searchedLocations: FRAMEWORK_SPECS[framework].cssLocations
|
|
29490
29519
|
});
|
|
29491
29520
|
}
|
|
29492
|
-
} else if (shadcn?.tailwind?.css) {
|
|
29493
|
-
detectedCssPath = shadcn.tailwind.css;
|
|
29494
29521
|
}
|
|
29495
29522
|
let componentTarget = frameworkToTarget(framework);
|
|
29496
29523
|
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.56",
|
|
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": {
|