rafters 0.4.1 → 0.4.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/README.md +0 -8
- package/dist/index.js +35 -885
- package/dist/registry/types.d.ts +0 -49
- package/dist/registry/types.js +1 -7
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -79,14 +79,6 @@ Start the MCP server for AI agent access via stdio transport.
|
|
|
79
79
|
pnpm dlx rafters mcp
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
### `rafters studio`
|
|
83
|
-
|
|
84
|
-
Launch Studio for visual token editing.
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
pnpm dlx rafters studio
|
|
88
|
-
```
|
|
89
|
-
|
|
90
82
|
## MCP tools
|
|
91
83
|
|
|
92
84
|
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.
|
package/dist/index.js
CHANGED
|
@@ -16836,12 +16836,6 @@ function assembleWcagAccessibility(scale2, reference) {
|
|
|
16836
16836
|
}
|
|
16837
16837
|
};
|
|
16838
16838
|
}
|
|
16839
|
-
function rebakeAccessibility(value) {
|
|
16840
|
-
if (!("scale" in value) || !Array.isArray(value.scale)) return value;
|
|
16841
|
-
const reference = value.scale[5] ?? value.scale[0];
|
|
16842
|
-
if (!reference) return value;
|
|
16843
|
-
return { ...value, accessibility: assembleWcagAccessibility(value.scale, reference) };
|
|
16844
|
-
}
|
|
16845
16839
|
|
|
16846
16840
|
// ../color-utils/src/internal/math.ts
|
|
16847
16841
|
function clamp2(value, min, max2) {
|
|
@@ -21059,7 +21053,7 @@ ${sourceDirectives}
|
|
|
21059
21053
|
${themeBody}`;
|
|
21060
21054
|
const { execFileSync } = await import("child_process");
|
|
21061
21055
|
const { mkdtempSync, writeFileSync: writeFileSync2, readFileSync: readFileSync5, rmSync } = await import("fs");
|
|
21062
|
-
const { join:
|
|
21056
|
+
const { join: join15, dirname: dirname4 } = await import("path");
|
|
21063
21057
|
const { createRequire: createRequire2 } = await import("module");
|
|
21064
21058
|
const require2 = createRequire2(import.meta.url);
|
|
21065
21059
|
let pkgDir;
|
|
@@ -21069,10 +21063,10 @@ ${themeBody}`;
|
|
|
21069
21063
|
} catch {
|
|
21070
21064
|
throw new Error("Failed to resolve @tailwindcss/cli");
|
|
21071
21065
|
}
|
|
21072
|
-
const binPath =
|
|
21073
|
-
const tempDir = mkdtempSync(
|
|
21074
|
-
const tempInput =
|
|
21075
|
-
const tempOutput =
|
|
21066
|
+
const binPath = join15(pkgDir, "dist", "index.mjs");
|
|
21067
|
+
const tempDir = mkdtempSync(join15(pkgDir, ".tmp-compile-"));
|
|
21068
|
+
const tempInput = join15(tempDir, "input.css");
|
|
21069
|
+
const tempOutput = join15(tempDir, "output.css");
|
|
21076
21070
|
try {
|
|
21077
21071
|
writeFileSync2(tempInput, input);
|
|
21078
21072
|
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
@@ -21256,7 +21250,7 @@ async function registryToDocumentation(registry2, options = {}) {
|
|
|
21256
21250
|
const themeBody = registryToTailwind(registry2, { includeImport: false });
|
|
21257
21251
|
const candidates = deriveCandidates(themeBody);
|
|
21258
21252
|
const { mkdtempSync, writeFileSync: writeFileSync2, rmSync } = await import("fs");
|
|
21259
|
-
const { join:
|
|
21253
|
+
const { join: join15, dirname: dirname4 } = await import("path");
|
|
21260
21254
|
const { createRequire: createRequire2 } = await import("module");
|
|
21261
21255
|
const require2 = createRequire2(import.meta.url);
|
|
21262
21256
|
let pkgDir;
|
|
@@ -21268,8 +21262,8 @@ async function registryToDocumentation(registry2, options = {}) {
|
|
|
21268
21262
|
"Failed to resolve @tailwindcss/cli -- install it to generate documentation CSS"
|
|
21269
21263
|
);
|
|
21270
21264
|
}
|
|
21271
|
-
const tempDir = mkdtempSync(
|
|
21272
|
-
const candidateFile =
|
|
21265
|
+
const tempDir = mkdtempSync(join15(pkgDir, ".tmp-doc-compile-"));
|
|
21266
|
+
const candidateFile = join15(tempDir, "candidates.txt");
|
|
21273
21267
|
writeFileSync2(candidateFile, candidates.join("\n"));
|
|
21274
21268
|
const sourceDirectives = [
|
|
21275
21269
|
`@source "${candidateFile}";`,
|
|
@@ -21278,12 +21272,12 @@ async function registryToDocumentation(registry2, options = {}) {
|
|
|
21278
21272
|
const input = `@import "tailwindcss" source(none);
|
|
21279
21273
|
${sourceDirectives}
|
|
21280
21274
|
${themeBody}`;
|
|
21281
|
-
const tempInput =
|
|
21282
|
-
const tempOutput =
|
|
21275
|
+
const tempInput = join15(tempDir, "input.css");
|
|
21276
|
+
const tempOutput = join15(tempDir, "output.css");
|
|
21283
21277
|
try {
|
|
21284
21278
|
writeFileSync2(tempInput, input);
|
|
21285
21279
|
const { execFileSync } = await import("child_process");
|
|
21286
|
-
const binPath =
|
|
21280
|
+
const binPath = join15(pkgDir, "dist", "index.mjs");
|
|
21287
21281
|
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
21288
21282
|
if (minify) args.push("--minify");
|
|
21289
21283
|
execFileSync("node", args, { stdio: "pipe", timeout: 6e4, cwd: pkgDir });
|
|
@@ -28324,43 +28318,43 @@ function resolveContentSources(cwd, fields) {
|
|
|
28324
28318
|
}
|
|
28325
28319
|
async function regenerateOutputs(registry2, input, hooks2 = {}) {
|
|
28326
28320
|
const {
|
|
28327
|
-
outputDir
|
|
28321
|
+
outputDir,
|
|
28328
28322
|
exports,
|
|
28329
28323
|
contentSources = [],
|
|
28330
28324
|
darkMode = "class",
|
|
28331
28325
|
includeImport = true
|
|
28332
28326
|
} = input;
|
|
28333
|
-
await mkdir(
|
|
28327
|
+
await mkdir(outputDir, { recursive: true });
|
|
28334
28328
|
const written = [];
|
|
28335
28329
|
if (exports.tailwind) {
|
|
28336
28330
|
const css = registryToTailwind(registry2, { includeImport, darkMode });
|
|
28337
|
-
await writeFile(join(
|
|
28331
|
+
await writeFile(join(outputDir, "rafters.css"), css);
|
|
28338
28332
|
written.push("rafters.css");
|
|
28339
28333
|
}
|
|
28340
28334
|
if (exports.typescript) {
|
|
28341
28335
|
const ts = registryToTypeScript(registry2, { includeJSDoc: true });
|
|
28342
|
-
await writeFile(join(
|
|
28336
|
+
await writeFile(join(outputDir, "rafters.ts"), ts);
|
|
28343
28337
|
written.push("rafters.ts");
|
|
28344
28338
|
}
|
|
28345
28339
|
if (exports.dtcg) {
|
|
28346
28340
|
const dtcg = toDTCG([...registry2.list()]);
|
|
28347
|
-
await writeFile(join(
|
|
28341
|
+
await writeFile(join(outputDir, "rafters.json"), JSON.stringify(dtcg, null, 2));
|
|
28348
28342
|
written.push("rafters.json");
|
|
28349
28343
|
}
|
|
28350
28344
|
if (exports.compiled) {
|
|
28351
28345
|
const compiled = await registryToCompiled(registry2, { contentSources });
|
|
28352
|
-
await writeFile(join(
|
|
28346
|
+
await writeFile(join(outputDir, "rafters.standalone.css"), compiled);
|
|
28353
28347
|
written.push("rafters.standalone.css");
|
|
28354
28348
|
}
|
|
28355
28349
|
if (exports.documentation) {
|
|
28356
28350
|
const doc = await registryToDocumentation(registry2, { contentSources });
|
|
28357
|
-
await writeFile(join(
|
|
28351
|
+
await writeFile(join(outputDir, "rafters.documentation.css"), doc);
|
|
28358
28352
|
written.push("rafters.documentation.css");
|
|
28359
28353
|
}
|
|
28360
28354
|
const writtenSet = new Set(written);
|
|
28361
28355
|
for (const filename of KNOWN_OUTPUT_FILENAMES) {
|
|
28362
28356
|
if (writtenSet.has(filename)) continue;
|
|
28363
|
-
const filePath = join(
|
|
28357
|
+
const filePath = join(outputDir, filename);
|
|
28364
28358
|
if (!existsSync(filePath)) continue;
|
|
28365
28359
|
try {
|
|
28366
28360
|
await unlink(filePath);
|
|
@@ -28829,13 +28823,7 @@ var RegistryItemSchema = external_exports.object({
|
|
|
28829
28823
|
primitives: external_exports.array(external_exports.string()),
|
|
28830
28824
|
files: external_exports.array(RegistryFileSchema),
|
|
28831
28825
|
rules: external_exports.array(external_exports.string()).default([]),
|
|
28832
|
-
|
|
28833
|
-
intelligence: RegistryItemIntelligenceSchema.optional(),
|
|
28834
|
-
// Per-target facets. zod v4's `z.record(enum, ...)` demands EVERY enum key be
|
|
28835
|
-
// present; a component built for only some targets must parse, so this is a
|
|
28836
|
-
// partial record (only the built targets appear).
|
|
28837
|
-
facets: external_exports.partialRecord(ComponentTargetSchema, FacetSchema).default({}),
|
|
28838
|
-
parent: external_exports.string().optional()
|
|
28826
|
+
intelligence: RegistryItemIntelligenceSchema.optional()
|
|
28839
28827
|
});
|
|
28840
28828
|
var RegistryIndexSchema = external_exports.object({
|
|
28841
28829
|
name: external_exports.string(),
|
|
@@ -30332,14 +30320,14 @@ async function installItem(cwd, item, options, config2, substrateKinds = []) {
|
|
|
30332
30320
|
filesToInstall = selectCompositeFiles(item.files, getComponentTarget(config2));
|
|
30333
30321
|
}
|
|
30334
30322
|
for (const file2 of filesToInstall) {
|
|
30335
|
-
const
|
|
30336
|
-
const targetPath = join7(cwd,
|
|
30337
|
-
if (fileExists(cwd,
|
|
30323
|
+
const projectPath = item.type === "substrate" ? substrateProjectPath(file2.path, config2, cwd) : transformPath(file2.path, config2, cwd);
|
|
30324
|
+
const targetPath = join7(cwd, projectPath);
|
|
30325
|
+
if (fileExists(cwd, projectPath)) {
|
|
30338
30326
|
if (!options.overwrite) {
|
|
30339
30327
|
log({
|
|
30340
30328
|
event: "add:skip",
|
|
30341
30329
|
component: item.name,
|
|
30342
|
-
file:
|
|
30330
|
+
file: projectPath,
|
|
30343
30331
|
reason: "exists"
|
|
30344
30332
|
});
|
|
30345
30333
|
skipped = true;
|
|
@@ -30353,7 +30341,7 @@ async function installItem(cwd, item, options, config2, substrateKinds = []) {
|
|
|
30353
30341
|
installPath: file2.path
|
|
30354
30342
|
});
|
|
30355
30343
|
await writeFile2(targetPath, transformedContent, "utf-8");
|
|
30356
|
-
installedFiles.push(
|
|
30344
|
+
installedFiles.push(projectPath);
|
|
30357
30345
|
}
|
|
30358
30346
|
return {
|
|
30359
30347
|
installed: installedFiles.length > 0,
|
|
@@ -30845,8 +30833,8 @@ import { dirname as dirname2, join as join9, resolve as resolve3 } from "path";
|
|
|
30845
30833
|
function discoverProjectRoot(startDir) {
|
|
30846
30834
|
let current = resolve3(startDir);
|
|
30847
30835
|
for (; ; ) {
|
|
30848
|
-
const
|
|
30849
|
-
if (existsSync4(
|
|
30836
|
+
const configPath = join9(current, ".rafters", "config.rafters.json");
|
|
30837
|
+
if (existsSync4(configPath)) {
|
|
30850
30838
|
return current;
|
|
30851
30839
|
}
|
|
30852
30840
|
const parent = dirname2(current);
|
|
@@ -31004,15 +30992,16 @@ function assembleGraph(items) {
|
|
|
31004
30992
|
if (src?.accessibility !== void 0) intel.accessibility = src.accessibility;
|
|
31005
30993
|
if (src?.attentionEconomics !== void 0) intel.attentionEconomics = src.attentionEconomics;
|
|
31006
30994
|
if (src?.trustBuilding !== void 0) intel.trustBuilding = src.trustBuilding;
|
|
30995
|
+
const raw = item;
|
|
31007
30996
|
const gn = {
|
|
31008
30997
|
id: item.name,
|
|
31009
30998
|
kind,
|
|
31010
30999
|
intel,
|
|
31011
|
-
facets:
|
|
31012
|
-
composesWith:
|
|
31000
|
+
facets: raw["facets"] ?? {},
|
|
31001
|
+
composesWith: raw["composites"] ?? [],
|
|
31013
31002
|
parts: []
|
|
31014
31003
|
};
|
|
31015
|
-
if (
|
|
31004
|
+
if (typeof raw["parent"] === "string") gn.parent = raw["parent"];
|
|
31016
31005
|
nodes.set(item.name, gn);
|
|
31017
31006
|
}
|
|
31018
31007
|
for (const node of nodes.values()) {
|
|
@@ -31817,9 +31806,9 @@ var RaftersToolHandler = class {
|
|
|
31817
31806
|
if (!parsedPaths.success) {
|
|
31818
31807
|
const issue2 = parsedPaths.error.issues[0];
|
|
31819
31808
|
const field = issue2 && issue2.path.length > 0 ? issue2.path.join(".") : "a path field";
|
|
31820
|
-
const
|
|
31809
|
+
const configPath = workspace ? getRaftersPaths(workspace.root).config : "config.rafters.json";
|
|
31821
31810
|
return {
|
|
31822
|
-
configError: `malformed config at ${
|
|
31811
|
+
configError: `malformed config at ${configPath}: ${field} ${issue2?.message ?? "is invalid"}`
|
|
31823
31812
|
};
|
|
31824
31813
|
}
|
|
31825
31814
|
const parsedTarget = ComponentTargetSchema.safeParse(config2?.componentTarget);
|
|
@@ -33173,8 +33162,8 @@ async function mcp(options) {
|
|
|
33173
33162
|
let defaultWorkspace;
|
|
33174
33163
|
if (options.projectRoot) {
|
|
33175
33164
|
const explicit = resolve5(options.projectRoot);
|
|
33176
|
-
const
|
|
33177
|
-
if (!existsSync8(
|
|
33165
|
+
const configPath = join14(explicit, ".rafters", "config.rafters.json");
|
|
33166
|
+
if (!existsSync8(configPath)) {
|
|
33178
33167
|
process.stderr.write(
|
|
33179
33168
|
`--project-root ${explicit} does not contain .rafters/config.rafters.json
|
|
33180
33169
|
`
|
|
@@ -33193,844 +33182,6 @@ async function mcp(options) {
|
|
|
33193
33182
|
await startMcpServer(workspaces, defaultWorkspace);
|
|
33194
33183
|
}
|
|
33195
33184
|
|
|
33196
|
-
// src/commands/studio.ts
|
|
33197
|
-
import { existsSync as existsSync9 } from "fs";
|
|
33198
|
-
import { resolve as resolve6 } from "path";
|
|
33199
|
-
|
|
33200
|
-
// ../studio/src/api/vite-plugin.ts
|
|
33201
|
-
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
33202
|
-
import { isAbsolute as isAbsolute4, join as join15 } from "path";
|
|
33203
|
-
var REGISTRY_PLUGINS3 = [scalePlugin, contrastPlugin, statePlugin, invertPlugin];
|
|
33204
|
-
var STUDIO_REASON_DEFAULT = "studio interactive edit";
|
|
33205
|
-
var TokenResponseSchema = external_exports.object({
|
|
33206
|
-
ok: external_exports.literal(true),
|
|
33207
|
-
token: TokenSchema
|
|
33208
|
-
});
|
|
33209
|
-
var TokensResponseSchema = external_exports.object({
|
|
33210
|
-
tokens: external_exports.array(TokenSchema),
|
|
33211
|
-
initialized: external_exports.boolean()
|
|
33212
|
-
});
|
|
33213
|
-
var ErrorResponseSchema = external_exports.object({
|
|
33214
|
-
ok: external_exports.literal(false),
|
|
33215
|
-
error: external_exports.string()
|
|
33216
|
-
});
|
|
33217
|
-
var ColorBuildResponseSchema = external_exports.object({
|
|
33218
|
-
ok: external_exports.literal(true),
|
|
33219
|
-
colorValue: ColorValueSchema
|
|
33220
|
-
});
|
|
33221
|
-
var ColorBuildOptionsSchema = external_exports.object({
|
|
33222
|
-
token: external_exports.string().optional(),
|
|
33223
|
-
value: external_exports.string().optional(),
|
|
33224
|
-
use: external_exports.string().optional(),
|
|
33225
|
-
states: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
33226
|
-
});
|
|
33227
|
-
var projectPath = process.env.RAFTERS_PROJECT_PATH || process.cwd();
|
|
33228
|
-
var outputDir = join15(projectPath, ".rafters", "output");
|
|
33229
|
-
var configPath = join15(projectPath, ".rafters", "config.rafters.json");
|
|
33230
|
-
var FontsConfigSchema = external_exports.object({
|
|
33231
|
-
path: external_exports.union([external_exports.string(), external_exports.null()]).optional(),
|
|
33232
|
-
imports: external_exports.array(external_exports.string()).optional()
|
|
33233
|
-
});
|
|
33234
|
-
var RaftersConfigSchema = external_exports.object({
|
|
33235
|
-
intent: external_exports.string().optional(),
|
|
33236
|
-
fonts: FontsConfigSchema.optional(),
|
|
33237
|
-
source: external_exports.string().optional(),
|
|
33238
|
-
darkMode: external_exports.enum(["class", "media"]).optional(),
|
|
33239
|
-
framework: external_exports.string().optional(),
|
|
33240
|
-
cssPath: external_exports.union([external_exports.string(), external_exports.null()]).optional(),
|
|
33241
|
-
exports: external_exports.record(external_exports.string(), external_exports.boolean()).optional()
|
|
33242
|
-
}).passthrough();
|
|
33243
|
-
var KNOWN_INTENTS = ["efficient"];
|
|
33244
|
-
async function readRaftersConfig() {
|
|
33245
|
-
try {
|
|
33246
|
-
const raw = JSON.parse(await readFile8(configPath, "utf8"));
|
|
33247
|
-
if ("shadcn" in raw && !("source" in raw)) {
|
|
33248
|
-
if (raw.shadcn === true) raw.source = "shadcn";
|
|
33249
|
-
delete raw.shadcn;
|
|
33250
|
-
}
|
|
33251
|
-
const result = RaftersConfigSchema.safeParse(raw);
|
|
33252
|
-
if (!result.success) {
|
|
33253
|
-
console.log(`[rafters] Config validation failed: ${result.error.message}`);
|
|
33254
|
-
return null;
|
|
33255
|
-
}
|
|
33256
|
-
return result.data;
|
|
33257
|
-
} catch {
|
|
33258
|
-
return null;
|
|
33259
|
-
}
|
|
33260
|
-
}
|
|
33261
|
-
function validateFontsPath(path) {
|
|
33262
|
-
if (path === null || path === void 0) return null;
|
|
33263
|
-
if (isAbsolute4(path)) return "fonts path must be relative";
|
|
33264
|
-
return null;
|
|
33265
|
-
}
|
|
33266
|
-
function validateIntent(intent) {
|
|
33267
|
-
if (!KNOWN_INTENTS.includes(intent)) {
|
|
33268
|
-
return `unknown intent "${intent}". Known: ${KNOWN_INTENTS.join(", ")}`;
|
|
33269
|
-
}
|
|
33270
|
-
return null;
|
|
33271
|
-
}
|
|
33272
|
-
async function loadStudioConfig() {
|
|
33273
|
-
const raw = await readRaftersConfig();
|
|
33274
|
-
return raw;
|
|
33275
|
-
}
|
|
33276
|
-
var SetTokenMessageSchema = external_exports.object({
|
|
33277
|
-
name: external_exports.string().min(1),
|
|
33278
|
-
value: external_exports.union([external_exports.string(), ColorValueSchema, ColorReferenceSchema]),
|
|
33279
|
-
persist: external_exports.boolean().optional(),
|
|
33280
|
-
reason: external_exports.string().optional()
|
|
33281
|
-
});
|
|
33282
|
-
var ConfigPatchSchema = external_exports.object({
|
|
33283
|
-
intent: external_exports.string().min(1).optional(),
|
|
33284
|
-
darkMode: external_exports.enum(["class", "media"]).optional(),
|
|
33285
|
-
fonts: FontsConfigSchema.optional()
|
|
33286
|
-
}).refine((patch) => Object.keys(patch).length > 0, {
|
|
33287
|
-
message: "patch must set at least one of: intent, darkMode, fonts"
|
|
33288
|
-
});
|
|
33289
|
-
function ridOf(rawData) {
|
|
33290
|
-
const rid = rawData?.__rid;
|
|
33291
|
-
return typeof rid === "string" ? rid : void 0;
|
|
33292
|
-
}
|
|
33293
|
-
var TokenPatchSchema = TokenSchema.pick({
|
|
33294
|
-
value: true,
|
|
33295
|
-
trustLevel: true,
|
|
33296
|
-
elevationLevel: true,
|
|
33297
|
-
motionIntent: true,
|
|
33298
|
-
accessibilityLevel: true,
|
|
33299
|
-
description: true
|
|
33300
|
-
}).extend({
|
|
33301
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33302
|
-
});
|
|
33303
|
-
var ColorNamespacePatchSchema = external_exports.object({
|
|
33304
|
-
value: external_exports.union([
|
|
33305
|
-
external_exports.string().regex(/^oklch\(/, "Color value must be oklch() format"),
|
|
33306
|
-
ColorValueSchema
|
|
33307
|
-
]),
|
|
33308
|
-
scalePosition: external_exports.number().min(0).max(10).optional(),
|
|
33309
|
-
description: external_exports.string().optional(),
|
|
33310
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33311
|
-
});
|
|
33312
|
-
var SemanticNamespacePatchSchema = external_exports.object({
|
|
33313
|
-
value: ColorReferenceSchema,
|
|
33314
|
-
trustLevel: external_exports.enum(["low", "medium", "high", "critical"]).optional(),
|
|
33315
|
-
consequence: external_exports.enum(["reversible", "significant", "permanent", "destructive"]).optional(),
|
|
33316
|
-
description: external_exports.string().optional(),
|
|
33317
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33318
|
-
});
|
|
33319
|
-
var SpacingNamespacePatchSchema = external_exports.object({
|
|
33320
|
-
value: external_exports.string().regex(/^-?\d+(\.\d+)?rem$/, 'Spacing value must be rem (e.g., "1rem", "0.25rem")'),
|
|
33321
|
-
scalePosition: external_exports.number().min(0).max(12).optional(),
|
|
33322
|
-
description: external_exports.string().optional(),
|
|
33323
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33324
|
-
});
|
|
33325
|
-
var TypographyNamespacePatchSchema = external_exports.object({
|
|
33326
|
-
value: external_exports.string().min(1),
|
|
33327
|
-
lineHeight: external_exports.string().optional(),
|
|
33328
|
-
description: external_exports.string().optional(),
|
|
33329
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33330
|
-
});
|
|
33331
|
-
var BreakpointNamespacePatchSchema = external_exports.object({
|
|
33332
|
-
value: external_exports.string().regex(/^\d+(\.\d+)?(px|rem)$/, "Breakpoint must be px or rem value"),
|
|
33333
|
-
viewportAware: external_exports.boolean().optional(),
|
|
33334
|
-
containerQueryAware: external_exports.boolean().optional(),
|
|
33335
|
-
description: external_exports.string().optional(),
|
|
33336
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33337
|
-
});
|
|
33338
|
-
var RadiusNamespacePatchSchema = external_exports.object({
|
|
33339
|
-
value: external_exports.union([
|
|
33340
|
-
external_exports.literal("0"),
|
|
33341
|
-
external_exports.literal("9999px"),
|
|
33342
|
-
external_exports.string().regex(/^\d+(\.\d+)?rem$/, 'Radius must be rem value, "0", or "9999px"')
|
|
33343
|
-
]),
|
|
33344
|
-
scalePosition: external_exports.number().optional(),
|
|
33345
|
-
description: external_exports.string().optional(),
|
|
33346
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33347
|
-
});
|
|
33348
|
-
var ShadowNamespacePatchSchema = external_exports.object({
|
|
33349
|
-
value: external_exports.string().min(1),
|
|
33350
|
-
shadowToken: external_exports.string().optional(),
|
|
33351
|
-
description: external_exports.string().optional(),
|
|
33352
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33353
|
-
});
|
|
33354
|
-
var DepthNamespacePatchSchema = external_exports.object({
|
|
33355
|
-
value: external_exports.string().regex(/^-?\d+$/, "Depth value must be numeric z-index"),
|
|
33356
|
-
elevationLevel: external_exports.enum(["surface", "raised", "overlay", "sticky", "modal", "popover", "tooltip"]).optional(),
|
|
33357
|
-
description: external_exports.string().optional(),
|
|
33358
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33359
|
-
});
|
|
33360
|
-
var MotionNamespacePatchSchema = external_exports.object({
|
|
33361
|
-
value: external_exports.union([
|
|
33362
|
-
external_exports.string().regex(/^\d+ms$/, "Duration must be in ms"),
|
|
33363
|
-
external_exports.string().regex(/^cubic-bezier\(/, "Easing must be cubic-bezier()")
|
|
33364
|
-
]),
|
|
33365
|
-
motionIntent: external_exports.enum(["enter", "exit", "emphasis", "transition"]).optional(),
|
|
33366
|
-
easingName: TokenSchema.shape.easingName,
|
|
33367
|
-
reducedMotionAware: external_exports.boolean().optional(),
|
|
33368
|
-
description: external_exports.string().optional(),
|
|
33369
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33370
|
-
});
|
|
33371
|
-
var ElevationNamespacePatchSchema = external_exports.object({
|
|
33372
|
-
value: external_exports.string(),
|
|
33373
|
-
elevationLevel: external_exports.enum(["surface", "raised", "overlay", "sticky", "modal", "popover", "tooltip"]).optional(),
|
|
33374
|
-
shadowToken: external_exports.string().optional(),
|
|
33375
|
-
description: external_exports.string().optional(),
|
|
33376
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33377
|
-
});
|
|
33378
|
-
var FocusNamespacePatchSchema = external_exports.object({
|
|
33379
|
-
value: external_exports.string().min(1),
|
|
33380
|
-
focusRingWidth: external_exports.string().optional(),
|
|
33381
|
-
focusRingColor: external_exports.string().optional(),
|
|
33382
|
-
focusRingOffset: external_exports.string().optional(),
|
|
33383
|
-
focusRingStyle: external_exports.string().optional(),
|
|
33384
|
-
accessibilityLevel: external_exports.enum(["AA", "AAA"]).optional(),
|
|
33385
|
-
description: external_exports.string().optional(),
|
|
33386
|
-
userOverride: TokenSchema.shape.userOverride.optional()
|
|
33387
|
-
});
|
|
33388
|
-
var namespacePatchSchemas = {
|
|
33389
|
-
color: ColorNamespacePatchSchema,
|
|
33390
|
-
semantic: SemanticNamespacePatchSchema,
|
|
33391
|
-
spacing: SpacingNamespacePatchSchema,
|
|
33392
|
-
typography: TypographyNamespacePatchSchema,
|
|
33393
|
-
breakpoint: BreakpointNamespacePatchSchema,
|
|
33394
|
-
radius: RadiusNamespacePatchSchema,
|
|
33395
|
-
shadow: ShadowNamespacePatchSchema,
|
|
33396
|
-
depth: DepthNamespacePatchSchema,
|
|
33397
|
-
motion: MotionNamespacePatchSchema,
|
|
33398
|
-
elevation: ElevationNamespacePatchSchema,
|
|
33399
|
-
focus: FocusNamespacePatchSchema
|
|
33400
|
-
};
|
|
33401
|
-
function getNamespacePatchSchema(namespace) {
|
|
33402
|
-
return namespacePatchSchemas[namespace] ?? TokenPatchSchema;
|
|
33403
|
-
}
|
|
33404
|
-
var MAX_BODY_SIZE = 1024 * 1024;
|
|
33405
|
-
function readJsonBody(req) {
|
|
33406
|
-
return new Promise((resolve7, reject) => {
|
|
33407
|
-
let body = "";
|
|
33408
|
-
let size = 0;
|
|
33409
|
-
req.on("data", (chunk) => {
|
|
33410
|
-
size += chunk.length;
|
|
33411
|
-
if (size > MAX_BODY_SIZE) {
|
|
33412
|
-
reject(new Error("Request body too large"));
|
|
33413
|
-
return;
|
|
33414
|
-
}
|
|
33415
|
-
body += chunk.toString();
|
|
33416
|
-
});
|
|
33417
|
-
req.on("end", () => {
|
|
33418
|
-
try {
|
|
33419
|
-
resolve7(body ? JSON.parse(body) : {});
|
|
33420
|
-
} catch {
|
|
33421
|
-
reject(new Error("Invalid JSON body"));
|
|
33422
|
-
}
|
|
33423
|
-
});
|
|
33424
|
-
req.on("error", reject);
|
|
33425
|
-
});
|
|
33426
|
-
}
|
|
33427
|
-
async function handleBuildColor(req, res) {
|
|
33428
|
-
let body;
|
|
33429
|
-
try {
|
|
33430
|
-
body = await readJsonBody(req);
|
|
33431
|
-
} catch (error47) {
|
|
33432
|
-
res.statusCode = 400;
|
|
33433
|
-
const message = error47 instanceof Error ? error47.message : "Invalid JSON body";
|
|
33434
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33435
|
-
return;
|
|
33436
|
-
}
|
|
33437
|
-
const inputSchema = external_exports.object({
|
|
33438
|
-
oklch: OKLCHSchema,
|
|
33439
|
-
options: ColorBuildOptionsSchema.optional()
|
|
33440
|
-
});
|
|
33441
|
-
const inputResult = inputSchema.safeParse(body);
|
|
33442
|
-
if (!inputResult.success) {
|
|
33443
|
-
res.statusCode = 400;
|
|
33444
|
-
const issues = inputResult.error.issues;
|
|
33445
|
-
const message = issues[0] ? `${issues[0].path.join(".") || "oklch"}: ${issues[0].message}` : inputResult.error.message;
|
|
33446
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33447
|
-
return;
|
|
33448
|
-
}
|
|
33449
|
-
const { oklch: oklch2, options } = inputResult.data;
|
|
33450
|
-
try {
|
|
33451
|
-
const cleanOptions = {};
|
|
33452
|
-
if (options) {
|
|
33453
|
-
for (const [k, v] of Object.entries(options)) {
|
|
33454
|
-
if (v !== void 0) cleanOptions[k] = v;
|
|
33455
|
-
}
|
|
33456
|
-
}
|
|
33457
|
-
const colorValue = buildColorValue(
|
|
33458
|
-
oklch2,
|
|
33459
|
-
cleanOptions
|
|
33460
|
-
);
|
|
33461
|
-
const outputResult = ColorValueSchema.safeParse(colorValue);
|
|
33462
|
-
if (!outputResult.success) {
|
|
33463
|
-
console.log(`[rafters] ColorValue validation failed: ${outputResult.error.message}`);
|
|
33464
|
-
res.statusCode = 500;
|
|
33465
|
-
res.end(JSON.stringify({ ok: false, error: "ColorValue generation failed validation" }));
|
|
33466
|
-
return;
|
|
33467
|
-
}
|
|
33468
|
-
const response = ColorBuildResponseSchema.parse({ ok: true, colorValue: outputResult.data });
|
|
33469
|
-
res.end(JSON.stringify(response));
|
|
33470
|
-
} catch (error47) {
|
|
33471
|
-
console.log(`[rafters] Color build failed: ${error47}`);
|
|
33472
|
-
res.statusCode = 500;
|
|
33473
|
-
res.end(JSON.stringify({ ok: false, error: String(error47) }));
|
|
33474
|
-
}
|
|
33475
|
-
}
|
|
33476
|
-
async function handlePostToken(req, res, name, registry2) {
|
|
33477
|
-
let body;
|
|
33478
|
-
try {
|
|
33479
|
-
body = await readJsonBody(req);
|
|
33480
|
-
} catch (error47) {
|
|
33481
|
-
res.statusCode = 400;
|
|
33482
|
-
const message = error47 instanceof Error ? error47.message : "Invalid JSON body";
|
|
33483
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33484
|
-
return;
|
|
33485
|
-
}
|
|
33486
|
-
const existingToken = registry2.get(name);
|
|
33487
|
-
if (!existingToken) {
|
|
33488
|
-
const createSchema = external_exports.object({
|
|
33489
|
-
namespace: external_exports.string().min(1),
|
|
33490
|
-
category: external_exports.string().min(1),
|
|
33491
|
-
value: external_exports.union([external_exports.string(), ColorValueSchema, ColorReferenceSchema]),
|
|
33492
|
-
userOverride: external_exports.object({
|
|
33493
|
-
previousValue: external_exports.union([external_exports.string(), ColorValueSchema, ColorReferenceSchema]),
|
|
33494
|
-
reason: external_exports.string().min(1, "Reason is required. Every token needs a why."),
|
|
33495
|
-
context: external_exports.string().optional()
|
|
33496
|
-
}),
|
|
33497
|
-
description: external_exports.string().optional()
|
|
33498
|
-
});
|
|
33499
|
-
const createResult = createSchema.safeParse(body);
|
|
33500
|
-
if (!createResult.success) {
|
|
33501
|
-
res.statusCode = 400;
|
|
33502
|
-
const issues = createResult.error.issues;
|
|
33503
|
-
const message = issues[0] ? `${issues[0].path.join(".") || "body"}: ${issues[0].message}` : createResult.error.message;
|
|
33504
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33505
|
-
return;
|
|
33506
|
-
}
|
|
33507
|
-
const newToken = {
|
|
33508
|
-
name,
|
|
33509
|
-
namespace: createResult.data.namespace,
|
|
33510
|
-
category: createResult.data.category,
|
|
33511
|
-
value: createResult.data.value,
|
|
33512
|
-
userOverride: createResult.data.userOverride,
|
|
33513
|
-
containerQueryAware: true,
|
|
33514
|
-
description: createResult.data.description
|
|
33515
|
-
};
|
|
33516
|
-
const tokenResult2 = TokenSchema.safeParse(newToken);
|
|
33517
|
-
if (!tokenResult2.success) {
|
|
33518
|
-
res.statusCode = 400;
|
|
33519
|
-
res.end(JSON.stringify({ ok: false, error: tokenResult2.error.message }));
|
|
33520
|
-
return;
|
|
33521
|
-
}
|
|
33522
|
-
try {
|
|
33523
|
-
registry2.define(tokenResult2.data);
|
|
33524
|
-
const response = TokenResponseSchema.parse({ ok: true, token: registry2.get(name) });
|
|
33525
|
-
res.statusCode = 201;
|
|
33526
|
-
res.end(JSON.stringify(response));
|
|
33527
|
-
} catch (error47) {
|
|
33528
|
-
res.statusCode = 500;
|
|
33529
|
-
res.end(JSON.stringify({ ok: false, error: String(error47) }));
|
|
33530
|
-
}
|
|
33531
|
-
return;
|
|
33532
|
-
}
|
|
33533
|
-
const namespaceSchema = getNamespacePatchSchema(existingToken.namespace);
|
|
33534
|
-
const patchResult = namespaceSchema.safeParse(body);
|
|
33535
|
-
if (!patchResult.success) {
|
|
33536
|
-
res.statusCode = 400;
|
|
33537
|
-
const issues = patchResult.error.issues;
|
|
33538
|
-
const message = issues[0] ? `${issues[0].path.join(".") || "value"}: ${issues[0].message}` : patchResult.error.message;
|
|
33539
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33540
|
-
return;
|
|
33541
|
-
}
|
|
33542
|
-
const mergedToken = {
|
|
33543
|
-
...existingToken,
|
|
33544
|
-
...patchResult.data
|
|
33545
|
-
};
|
|
33546
|
-
if (mergedToken.value && typeof mergedToken.value === "object" && "scale" in mergedToken.value) {
|
|
33547
|
-
mergedToken.value = rebakeAccessibility(mergedToken.value);
|
|
33548
|
-
}
|
|
33549
|
-
const tokenResult = TokenSchema.safeParse(mergedToken);
|
|
33550
|
-
if (!tokenResult.success) {
|
|
33551
|
-
res.statusCode = 400;
|
|
33552
|
-
const issues = tokenResult.error.issues;
|
|
33553
|
-
const message = issues[0] ? `${issues[0].path.join(".") || "token"}: ${issues[0].message}` : tokenResult.error.message;
|
|
33554
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33555
|
-
return;
|
|
33556
|
-
}
|
|
33557
|
-
try {
|
|
33558
|
-
const merged = tokenResult.data;
|
|
33559
|
-
const patchOverride = patchResult.data.userOverride;
|
|
33560
|
-
const reason = patchOverride?.reason ?? STUDIO_REASON_DEFAULT;
|
|
33561
|
-
registry2.define(merged);
|
|
33562
|
-
registry2.set(merged.name, merged.value, { reason });
|
|
33563
|
-
const updatedToken = registry2.get(name);
|
|
33564
|
-
const response = TokenResponseSchema.parse({ ok: true, token: updatedToken });
|
|
33565
|
-
res.end(JSON.stringify(response));
|
|
33566
|
-
} catch (error47) {
|
|
33567
|
-
console.log(`[rafters] Token update failed for "${name}": ${error47}`);
|
|
33568
|
-
res.statusCode = 500;
|
|
33569
|
-
res.end(JSON.stringify({ ok: false, error: String(error47) }));
|
|
33570
|
-
}
|
|
33571
|
-
}
|
|
33572
|
-
var TokenArraySchema = external_exports.array(TokenSchema);
|
|
33573
|
-
var NamespaceParamSchema = external_exports.string().min(1).optional();
|
|
33574
|
-
function handleGetTokens(url3, res, registry2, initialized) {
|
|
33575
|
-
try {
|
|
33576
|
-
const parsedUrl = new URL(url3, "http://localhost");
|
|
33577
|
-
const namespaceParam = parsedUrl.searchParams.get("namespace");
|
|
33578
|
-
const namespaceResult = NamespaceParamSchema.safeParse(namespaceParam ?? void 0);
|
|
33579
|
-
if (namespaceParam !== null && !namespaceResult.success) {
|
|
33580
|
-
res.statusCode = 400;
|
|
33581
|
-
res.end(JSON.stringify({ ok: false, error: "Invalid namespace parameter" }));
|
|
33582
|
-
return;
|
|
33583
|
-
}
|
|
33584
|
-
let tokens = registry2.list();
|
|
33585
|
-
if (namespaceParam && namespaceResult.success && namespaceResult.data) {
|
|
33586
|
-
tokens = tokens.filter((t) => t.namespace === namespaceResult.data);
|
|
33587
|
-
}
|
|
33588
|
-
const tokensResult = external_exports.array(TokenSchema).safeParse(tokens);
|
|
33589
|
-
if (!tokensResult.success) {
|
|
33590
|
-
console.log(`[rafters] Tokens list failed validation: ${tokensResult.error.message}`);
|
|
33591
|
-
res.statusCode = 500;
|
|
33592
|
-
res.end(JSON.stringify({ ok: false, error: "Token validation failed" }));
|
|
33593
|
-
return;
|
|
33594
|
-
}
|
|
33595
|
-
const response = TokensResponseSchema.parse({
|
|
33596
|
-
tokens: tokensResult.data,
|
|
33597
|
-
initialized
|
|
33598
|
-
});
|
|
33599
|
-
res.end(JSON.stringify(response));
|
|
33600
|
-
} catch (error47) {
|
|
33601
|
-
console.log(`[rafters] Failed to list tokens: ${error47}`);
|
|
33602
|
-
res.statusCode = 500;
|
|
33603
|
-
res.end(JSON.stringify({ ok: false, error: "Failed to retrieve tokens" }));
|
|
33604
|
-
}
|
|
33605
|
-
}
|
|
33606
|
-
async function handlePostTokens(req, res, registry2) {
|
|
33607
|
-
let body;
|
|
33608
|
-
try {
|
|
33609
|
-
body = await readJsonBody(req);
|
|
33610
|
-
} catch (error47) {
|
|
33611
|
-
res.statusCode = 400;
|
|
33612
|
-
const message = error47 instanceof Error ? error47.message : "Invalid JSON body";
|
|
33613
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33614
|
-
return;
|
|
33615
|
-
}
|
|
33616
|
-
const tokensResult = TokenArraySchema.safeParse(body);
|
|
33617
|
-
if (!tokensResult.success) {
|
|
33618
|
-
res.statusCode = 400;
|
|
33619
|
-
const issues = tokensResult.error.issues;
|
|
33620
|
-
const message = issues[0] ? `${issues[0].path.join(".") || "tokens"}: ${issues[0].message}` : tokensResult.error.message;
|
|
33621
|
-
res.end(JSON.stringify({ ok: false, error: message }));
|
|
33622
|
-
return;
|
|
33623
|
-
}
|
|
33624
|
-
const tokens = tokensResult.data;
|
|
33625
|
-
for (const token of tokens) {
|
|
33626
|
-
if (!registry2.has(token.name)) {
|
|
33627
|
-
res.statusCode = 404;
|
|
33628
|
-
res.end(JSON.stringify({ ok: false, error: `Token "${token.name}" not found` }));
|
|
33629
|
-
return;
|
|
33630
|
-
}
|
|
33631
|
-
}
|
|
33632
|
-
try {
|
|
33633
|
-
for (const token of tokens) {
|
|
33634
|
-
const reason = token.userOverride?.reason ?? STUDIO_REASON_DEFAULT;
|
|
33635
|
-
registry2.define(token);
|
|
33636
|
-
registry2.set(token.name, token.value, { reason });
|
|
33637
|
-
}
|
|
33638
|
-
const updatedTokens = tokens.map((t) => registry2.get(t.name)).filter(Boolean);
|
|
33639
|
-
const response = TokensResponseSchema.parse({
|
|
33640
|
-
tokens: updatedTokens,
|
|
33641
|
-
initialized: true
|
|
33642
|
-
});
|
|
33643
|
-
res.end(JSON.stringify(response));
|
|
33644
|
-
} catch (error47) {
|
|
33645
|
-
console.log(`[rafters] Batch token update failed: ${error47}`);
|
|
33646
|
-
res.statusCode = 500;
|
|
33647
|
-
res.end(JSON.stringify({ ok: false, error: String(error47) }));
|
|
33648
|
-
}
|
|
33649
|
-
}
|
|
33650
|
-
function studioApiPlugin() {
|
|
33651
|
-
let registry2;
|
|
33652
|
-
let initialized = false;
|
|
33653
|
-
return {
|
|
33654
|
-
name: "rafters-studio-api",
|
|
33655
|
-
async configureServer(server) {
|
|
33656
|
-
const tokensDir = join15(projectPath, ".rafters", "tokens");
|
|
33657
|
-
try {
|
|
33658
|
-
registry2 = loadRegistryFromDir(tokensDir, REGISTRY_PLUGINS3);
|
|
33659
|
-
initialized = true;
|
|
33660
|
-
} catch (error47) {
|
|
33661
|
-
const message = error47 instanceof Error ? error47.message : String(error47);
|
|
33662
|
-
console.log(`[rafters] Failed to initialize: ${message}`);
|
|
33663
|
-
if (message.includes("ENOENT")) {
|
|
33664
|
-
console.log(`[rafters] No project found at ${projectPath}. Run 'rafters init' first.`);
|
|
33665
|
-
}
|
|
33666
|
-
registry2 = new TokenRegistry([], REGISTRY_PLUGINS3);
|
|
33667
|
-
initialized = false;
|
|
33668
|
-
}
|
|
33669
|
-
const regenerate = async () => {
|
|
33670
|
-
const config2 = await loadStudioConfig();
|
|
33671
|
-
const exports = config2?.exports ?? {
|
|
33672
|
-
tailwind: true,
|
|
33673
|
-
typescript: true,
|
|
33674
|
-
dtcg: false,
|
|
33675
|
-
compiled: false,
|
|
33676
|
-
documentation: false
|
|
33677
|
-
};
|
|
33678
|
-
await regenerateOutputs(
|
|
33679
|
-
registry2,
|
|
33680
|
-
{
|
|
33681
|
-
outputDir,
|
|
33682
|
-
exports,
|
|
33683
|
-
contentSources: config2 ? resolveContentSources(projectPath, config2) : [],
|
|
33684
|
-
darkMode: config2?.darkMode ?? "class",
|
|
33685
|
-
includeImport: config2?.source !== "shadcn"
|
|
33686
|
-
},
|
|
33687
|
-
{ notify: () => server.ws.send({ type: "custom", event: "rafters:css-updated" }) }
|
|
33688
|
-
);
|
|
33689
|
-
};
|
|
33690
|
-
const persistAndNotify = async () => {
|
|
33691
|
-
try {
|
|
33692
|
-
if (initialized) {
|
|
33693
|
-
saveRegistryToDir(tokensDir, registry2);
|
|
33694
|
-
}
|
|
33695
|
-
await regenerate();
|
|
33696
|
-
} catch (error47) {
|
|
33697
|
-
console.log(`[rafters] CSS regeneration failed: ${error47}`);
|
|
33698
|
-
}
|
|
33699
|
-
};
|
|
33700
|
-
const reloadAndRegenerate = async () => {
|
|
33701
|
-
try {
|
|
33702
|
-
registry2 = loadRegistryFromDir(tokensDir, REGISTRY_PLUGINS3);
|
|
33703
|
-
initialized = true;
|
|
33704
|
-
} catch {
|
|
33705
|
-
}
|
|
33706
|
-
try {
|
|
33707
|
-
await regenerate();
|
|
33708
|
-
} catch (error47) {
|
|
33709
|
-
console.log(`[rafters] CSS regeneration failed: ${error47}`);
|
|
33710
|
-
}
|
|
33711
|
-
};
|
|
33712
|
-
{
|
|
33713
|
-
const trackedClassDirs = /* @__PURE__ */ new Set();
|
|
33714
|
-
const syncWatchTargets = async () => {
|
|
33715
|
-
const watchConfig = await loadStudioConfig();
|
|
33716
|
-
const classDirs = watchConfig ? resolveContentSources(projectPath, watchConfig) : [];
|
|
33717
|
-
const newDirs = classDirs.filter((d2) => !trackedClassDirs.has(d2));
|
|
33718
|
-
if (newDirs.length > 0) {
|
|
33719
|
-
server.watcher.add(newDirs.map((dir) => join15(dir, "**/*.classes.ts")));
|
|
33720
|
-
for (const d2 of newDirs) trackedClassDirs.add(d2);
|
|
33721
|
-
}
|
|
33722
|
-
};
|
|
33723
|
-
server.watcher.add([join15(tokensDir, "*.rafters.json"), configPath]);
|
|
33724
|
-
await syncWatchTargets();
|
|
33725
|
-
let debounce = null;
|
|
33726
|
-
const onChange = (changed) => {
|
|
33727
|
-
const watched = changed.endsWith(".classes.ts") || changed.endsWith(".rafters.json") || changed === configPath;
|
|
33728
|
-
if (!watched) return;
|
|
33729
|
-
if (debounce) clearTimeout(debounce);
|
|
33730
|
-
debounce = setTimeout(() => {
|
|
33731
|
-
const isConfigChange = changed === configPath;
|
|
33732
|
-
const run = isConfigChange ? syncWatchTargets().then(reloadAndRegenerate) : reloadAndRegenerate();
|
|
33733
|
-
void run;
|
|
33734
|
-
}, 150);
|
|
33735
|
-
};
|
|
33736
|
-
server.watcher.on("change", onChange);
|
|
33737
|
-
server.watcher.on("add", onChange);
|
|
33738
|
-
server.watcher.on("unlink", onChange);
|
|
33739
|
-
}
|
|
33740
|
-
server.ws.on("rafters:set-token", async (rawData, client) => {
|
|
33741
|
-
const parsed = SetTokenMessageSchema.safeParse(rawData);
|
|
33742
|
-
if (!parsed.success) {
|
|
33743
|
-
client.send("rafters:token-updated", {
|
|
33744
|
-
ok: false,
|
|
33745
|
-
error: `Invalid message: ${parsed.error.message}`
|
|
33746
|
-
});
|
|
33747
|
-
return;
|
|
33748
|
-
}
|
|
33749
|
-
const data = parsed.data;
|
|
33750
|
-
const shouldPersist = data.persist !== false;
|
|
33751
|
-
const existingToken = registry2.get(data.name);
|
|
33752
|
-
const isColorFamily = existingToken?.namespace === "color" && typeof data.value === "object" && data.value !== null && "scale" in data.value;
|
|
33753
|
-
let enrichmentPromise = null;
|
|
33754
|
-
if (isColorFamily) {
|
|
33755
|
-
const colorValue = data.value;
|
|
33756
|
-
const base = colorValue.scale?.[5];
|
|
33757
|
-
if (base) {
|
|
33758
|
-
const l = base.l.toFixed(3);
|
|
33759
|
-
const c4 = base.c.toFixed(3);
|
|
33760
|
-
const h = Math.round(base.h);
|
|
33761
|
-
enrichmentPromise = fetch(`https://api.rafters.studio/color/${l}-${c4}-${h}?sync=true`).then((r) => r.ok ? r.json() : null).catch(() => null);
|
|
33762
|
-
}
|
|
33763
|
-
}
|
|
33764
|
-
const reason = data.reason ?? STUDIO_REASON_DEFAULT;
|
|
33765
|
-
try {
|
|
33766
|
-
registry2.set(data.name, data.value, { reason });
|
|
33767
|
-
if (shouldPersist) {
|
|
33768
|
-
await persistAndNotify();
|
|
33769
|
-
}
|
|
33770
|
-
client.send("rafters:token-updated", {
|
|
33771
|
-
ok: true,
|
|
33772
|
-
name: data.name,
|
|
33773
|
-
persisted: shouldPersist
|
|
33774
|
-
});
|
|
33775
|
-
if (enrichmentPromise) {
|
|
33776
|
-
const enrichment = await enrichmentPromise;
|
|
33777
|
-
if (enrichment && typeof enrichment === "object" && "color" in enrichment) {
|
|
33778
|
-
const apiColor = enrichment.color;
|
|
33779
|
-
if (apiColor?.intelligence) {
|
|
33780
|
-
const current = registry2.get(data.name);
|
|
33781
|
-
if (current && typeof current.value === "object" && current.value !== null) {
|
|
33782
|
-
const enrichedValue = {
|
|
33783
|
-
...current.value,
|
|
33784
|
-
intelligence: apiColor.intelligence
|
|
33785
|
-
};
|
|
33786
|
-
registry2.set(data.name, enrichedValue, {
|
|
33787
|
-
reason: `${reason} (enriched by api.rafters.studio)`
|
|
33788
|
-
});
|
|
33789
|
-
await persistAndNotify();
|
|
33790
|
-
client.send("rafters:color-enriched", {
|
|
33791
|
-
name: data.name,
|
|
33792
|
-
intelligence: apiColor.intelligence
|
|
33793
|
-
});
|
|
33794
|
-
}
|
|
33795
|
-
}
|
|
33796
|
-
}
|
|
33797
|
-
}
|
|
33798
|
-
} catch (error47) {
|
|
33799
|
-
console.log(`[rafters] Token update failed for "${data.name}": ${error47}`);
|
|
33800
|
-
client.send("rafters:token-updated", { ok: false, error: String(error47) });
|
|
33801
|
-
}
|
|
33802
|
-
});
|
|
33803
|
-
server.ws.on("rafters:get-config", async (rawData, client) => {
|
|
33804
|
-
const __rid = ridOf(rawData);
|
|
33805
|
-
const reply = (msg) => client.send("rafters:config", { ...msg, __rid });
|
|
33806
|
-
const config2 = await readRaftersConfig();
|
|
33807
|
-
if (!config2) {
|
|
33808
|
-
reply({ ok: false, error: `config not found at ${configPath}` });
|
|
33809
|
-
return;
|
|
33810
|
-
}
|
|
33811
|
-
reply({ ok: true, config: config2 });
|
|
33812
|
-
});
|
|
33813
|
-
server.ws.on("rafters:set-config", async (rawData, client) => {
|
|
33814
|
-
const __rid = ridOf(rawData);
|
|
33815
|
-
const reply = (msg) => client.send("rafters:config", { ...msg, __rid });
|
|
33816
|
-
const parsed = ConfigPatchSchema.safeParse(rawData);
|
|
33817
|
-
if (!parsed.success) {
|
|
33818
|
-
reply({ ok: false, error: `Invalid patch: ${parsed.error.message}` });
|
|
33819
|
-
return;
|
|
33820
|
-
}
|
|
33821
|
-
const patch = parsed.data;
|
|
33822
|
-
if (patch.intent !== void 0) {
|
|
33823
|
-
const intentError = validateIntent(patch.intent);
|
|
33824
|
-
if (intentError) {
|
|
33825
|
-
reply({ ok: false, error: intentError });
|
|
33826
|
-
return;
|
|
33827
|
-
}
|
|
33828
|
-
}
|
|
33829
|
-
if (patch.fonts?.path !== void 0) {
|
|
33830
|
-
const pathError = validateFontsPath(patch.fonts.path);
|
|
33831
|
-
if (pathError) {
|
|
33832
|
-
reply({ ok: false, error: pathError });
|
|
33833
|
-
return;
|
|
33834
|
-
}
|
|
33835
|
-
}
|
|
33836
|
-
const config2 = await readRaftersConfig();
|
|
33837
|
-
if (!config2) {
|
|
33838
|
-
reply({ ok: false, error: `config not found at ${configPath}` });
|
|
33839
|
-
return;
|
|
33840
|
-
}
|
|
33841
|
-
const updated = { ...config2 };
|
|
33842
|
-
if (patch.intent !== void 0) updated.intent = patch.intent;
|
|
33843
|
-
if (patch.darkMode !== void 0) updated.darkMode = patch.darkMode;
|
|
33844
|
-
if (patch.fonts !== void 0) {
|
|
33845
|
-
const merged = { ...config2.fonts };
|
|
33846
|
-
if (patch.fonts.path !== void 0) merged.path = patch.fonts.path;
|
|
33847
|
-
if (patch.fonts.imports !== void 0) merged.imports = patch.fonts.imports;
|
|
33848
|
-
updated.fonts = merged;
|
|
33849
|
-
}
|
|
33850
|
-
try {
|
|
33851
|
-
await writeFile6(configPath, `${JSON.stringify(updated, null, 2)}
|
|
33852
|
-
`);
|
|
33853
|
-
reply({ ok: true, config: updated });
|
|
33854
|
-
} catch (error47) {
|
|
33855
|
-
console.log(`[rafters] Config update failed: ${error47}`);
|
|
33856
|
-
reply({ ok: false, error: String(error47) });
|
|
33857
|
-
}
|
|
33858
|
-
});
|
|
33859
|
-
server.middlewares.use(async (req, res, next) => {
|
|
33860
|
-
let pathname;
|
|
33861
|
-
try {
|
|
33862
|
-
pathname = new URL(req.url ?? "", "http://localhost").pathname;
|
|
33863
|
-
} catch {
|
|
33864
|
-
next();
|
|
33865
|
-
return;
|
|
33866
|
-
}
|
|
33867
|
-
if ((pathname === "/api/" || pathname === "/api") && req.method === "GET") {
|
|
33868
|
-
res.setHeader("Content-Type", "application/json");
|
|
33869
|
-
res.end(
|
|
33870
|
-
JSON.stringify({
|
|
33871
|
-
name: "Rafters Studio API",
|
|
33872
|
-
initialized,
|
|
33873
|
-
tokenCount: registry2.list().length,
|
|
33874
|
-
rules: {
|
|
33875
|
-
whyGate: "Every POST to /api/tokens/:name requires userOverride.reason.",
|
|
33876
|
-
gets: "Returns full Token with all intelligence metadata.",
|
|
33877
|
-
sets: "Value + reason in. API fills the Token shape. CSS updates via HMR.",
|
|
33878
|
-
colors: "POST /api/color/build with OKLCH to get a ColorValue."
|
|
33879
|
-
},
|
|
33880
|
-
endpoints: {
|
|
33881
|
-
"GET /api/tokens": "All tokens (optional ?namespace= filter)",
|
|
33882
|
-
"GET /api/tokens/:name": "One token with full data",
|
|
33883
|
-
"POST /api/tokens/:name": "Update token (namespace-validated patch)",
|
|
33884
|
-
"POST /api/tokens": "Batch update tokens",
|
|
33885
|
-
"POST /api/color/build": "OKLCH -> full ColorValue",
|
|
33886
|
-
"POST /api/shutdown": "Gracefully stop the studio"
|
|
33887
|
-
}
|
|
33888
|
-
})
|
|
33889
|
-
);
|
|
33890
|
-
return;
|
|
33891
|
-
}
|
|
33892
|
-
if (pathname === "/api/shutdown" && req.method === "POST") {
|
|
33893
|
-
res.setHeader("Content-Type", "application/json");
|
|
33894
|
-
res.end(JSON.stringify({ ok: true, message: "Shutting down" }));
|
|
33895
|
-
console.log("[rafters] Studio shutting down...");
|
|
33896
|
-
setTimeout(() => server.close(), 100);
|
|
33897
|
-
return;
|
|
33898
|
-
}
|
|
33899
|
-
if (pathname === "/api/color/build") {
|
|
33900
|
-
res.setHeader("Content-Type", "application/json");
|
|
33901
|
-
if (req.method !== "POST") {
|
|
33902
|
-
res.statusCode = 405;
|
|
33903
|
-
res.setHeader("Allow", "POST");
|
|
33904
|
-
res.end(JSON.stringify({ ok: false, error: "Method not allowed" }));
|
|
33905
|
-
return;
|
|
33906
|
-
}
|
|
33907
|
-
handleBuildColor(req, res).catch((error47) => {
|
|
33908
|
-
console.log(`[rafters] Unhandled error in POST /api/color/build: ${error47}`);
|
|
33909
|
-
if (!res.headersSent) {
|
|
33910
|
-
res.statusCode = 500;
|
|
33911
|
-
res.end(JSON.stringify({ ok: false, error: "Internal server error" }));
|
|
33912
|
-
}
|
|
33913
|
-
});
|
|
33914
|
-
return;
|
|
33915
|
-
}
|
|
33916
|
-
const tokenMatch = pathname.match(/^\/api\/tokens\/(.+)$/);
|
|
33917
|
-
if (tokenMatch) {
|
|
33918
|
-
let name;
|
|
33919
|
-
try {
|
|
33920
|
-
name = decodeURIComponent(tokenMatch[1] ?? "");
|
|
33921
|
-
} catch {
|
|
33922
|
-
res.statusCode = 400;
|
|
33923
|
-
res.setHeader("Content-Type", "application/json");
|
|
33924
|
-
res.end(JSON.stringify({ ok: false, error: "Invalid token name encoding" }));
|
|
33925
|
-
return;
|
|
33926
|
-
}
|
|
33927
|
-
res.setHeader("Content-Type", "application/json");
|
|
33928
|
-
if (req.method !== "GET" && req.method !== "POST") {
|
|
33929
|
-
res.statusCode = 405;
|
|
33930
|
-
res.setHeader("Allow", "GET, POST");
|
|
33931
|
-
res.end(JSON.stringify({ ok: false, error: "Method not allowed" }));
|
|
33932
|
-
return;
|
|
33933
|
-
}
|
|
33934
|
-
if (req.method === "POST") {
|
|
33935
|
-
try {
|
|
33936
|
-
await handlePostToken(req, res, name, registry2);
|
|
33937
|
-
if (res.statusCode < 400) await persistAndNotify();
|
|
33938
|
-
} catch (error47) {
|
|
33939
|
-
console.log(`[rafters] Unhandled error in POST /api/tokens/${name}: ${error47}`);
|
|
33940
|
-
if (!res.headersSent) {
|
|
33941
|
-
res.statusCode = 500;
|
|
33942
|
-
res.end(JSON.stringify({ ok: false, error: "Internal server error" }));
|
|
33943
|
-
}
|
|
33944
|
-
}
|
|
33945
|
-
return;
|
|
33946
|
-
}
|
|
33947
|
-
const token = registry2.get(name);
|
|
33948
|
-
if (!token) {
|
|
33949
|
-
const errorResponse = ErrorResponseSchema.parse({
|
|
33950
|
-
ok: false,
|
|
33951
|
-
error: `Token "${name}" not found`
|
|
33952
|
-
});
|
|
33953
|
-
res.statusCode = 404;
|
|
33954
|
-
res.end(JSON.stringify(errorResponse));
|
|
33955
|
-
return;
|
|
33956
|
-
}
|
|
33957
|
-
const tokenResult = TokenSchema.safeParse(token);
|
|
33958
|
-
if (!tokenResult.success) {
|
|
33959
|
-
console.log(
|
|
33960
|
-
`[rafters] Token "${name}" failed validation: ${tokenResult.error.message}`
|
|
33961
|
-
);
|
|
33962
|
-
const errorResponse = ErrorResponseSchema.parse({
|
|
33963
|
-
ok: false,
|
|
33964
|
-
error: `Token "${name}" has invalid structure`
|
|
33965
|
-
});
|
|
33966
|
-
res.statusCode = 500;
|
|
33967
|
-
res.end(JSON.stringify(errorResponse));
|
|
33968
|
-
return;
|
|
33969
|
-
}
|
|
33970
|
-
const response = TokenResponseSchema.parse({ ok: true, token: tokenResult.data });
|
|
33971
|
-
res.end(JSON.stringify(response));
|
|
33972
|
-
return;
|
|
33973
|
-
}
|
|
33974
|
-
if (pathname === "/api/tokens") {
|
|
33975
|
-
res.setHeader("Content-Type", "application/json");
|
|
33976
|
-
if (req.method !== "GET" && req.method !== "POST") {
|
|
33977
|
-
res.statusCode = 405;
|
|
33978
|
-
res.setHeader("Allow", "GET, POST");
|
|
33979
|
-
res.end(JSON.stringify({ ok: false, error: "Method not allowed" }));
|
|
33980
|
-
return;
|
|
33981
|
-
}
|
|
33982
|
-
if (req.method === "POST") {
|
|
33983
|
-
try {
|
|
33984
|
-
await handlePostTokens(req, res, registry2);
|
|
33985
|
-
if (res.statusCode < 400) await persistAndNotify();
|
|
33986
|
-
} catch (error47) {
|
|
33987
|
-
console.log(`[rafters] Unhandled error in POST /api/tokens: ${error47}`);
|
|
33988
|
-
if (!res.headersSent) {
|
|
33989
|
-
res.statusCode = 500;
|
|
33990
|
-
res.end(JSON.stringify({ ok: false, error: "Internal server error" }));
|
|
33991
|
-
}
|
|
33992
|
-
}
|
|
33993
|
-
return;
|
|
33994
|
-
}
|
|
33995
|
-
handleGetTokens(req.url ?? "", res, registry2, initialized);
|
|
33996
|
-
return;
|
|
33997
|
-
}
|
|
33998
|
-
next();
|
|
33999
|
-
});
|
|
34000
|
-
}
|
|
34001
|
-
};
|
|
34002
|
-
}
|
|
34003
|
-
|
|
34004
|
-
// src/commands/studio.ts
|
|
34005
|
-
import { createServer } from "vite";
|
|
34006
|
-
async function studio() {
|
|
34007
|
-
const cwd = process.cwd();
|
|
34008
|
-
const paths = getRaftersPaths(cwd);
|
|
34009
|
-
if (!existsSync9(paths.root)) {
|
|
34010
|
-
console.error('No .rafters/ directory found. Run "rafters init" first.');
|
|
34011
|
-
process.exit(1);
|
|
34012
|
-
}
|
|
34013
|
-
console.log("Starting Rafters Studio...");
|
|
34014
|
-
console.log(`Project: ${cwd}`);
|
|
34015
|
-
console.log(`Tokens: ${paths.tokens}`);
|
|
34016
|
-
console.log("");
|
|
34017
|
-
process.env.RAFTERS_PROJECT_PATH = cwd;
|
|
34018
|
-
process.env.RAFTERS_TOKENS_PATH = paths.tokens;
|
|
34019
|
-
const server = await createServer({
|
|
34020
|
-
plugins: [studioApiPlugin()],
|
|
34021
|
-
server: {
|
|
34022
|
-
port: 7777
|
|
34023
|
-
},
|
|
34024
|
-
resolve: {
|
|
34025
|
-
alias: {
|
|
34026
|
-
"@rafters-output": resolve6(cwd, ".rafters", "output")
|
|
34027
|
-
}
|
|
34028
|
-
}
|
|
34029
|
-
});
|
|
34030
|
-
await server.listen();
|
|
34031
|
-
server.printUrls();
|
|
34032
|
-
}
|
|
34033
|
-
|
|
34034
33185
|
// src/index.ts
|
|
34035
33186
|
var program = new Command();
|
|
34036
33187
|
program.name("rafters").description("Design system CLI - scaffold tokens and serve MCP").version(VERSION);
|
|
@@ -34040,7 +33191,6 @@ program.command("init").description("Initialize .rafters/ with default tokens an
|
|
|
34040
33191
|
).option("--agent", "Output JSON for machine consumption").action(withErrorHandler(init));
|
|
34041
33192
|
program.command("add").description("Add rafters components to the project").argument("[components...]", "Component names to add").option("--list", "List available components").option("--overwrite", "Overwrite existing component files").option("--update", "Re-fetch named components from registry").option("--update-all", "Re-fetch all installed components from registry").option("--registry-url <url>", "Custom registry URL").option("--agent", "Output JSON for machine consumption").action(withErrorHandler(add));
|
|
34042
33193
|
program.command("mcp").description("Start MCP server for AI agent access (stdio)").option("--project-root <path>", "Explicit project root (skips .rafters/ discovery)").action(mcp);
|
|
34043
|
-
program.command("studio").description("Open Studio UI for visual token editing").action(studio);
|
|
34044
33194
|
program.command("agents").description(
|
|
34045
33195
|
"Write or update the rafters contract block in AGENTS.md for non-Claude-Code agent hosts"
|
|
34046
33196
|
).action(withErrorHandler(agents));
|
package/dist/registry/types.d.ts
CHANGED
|
@@ -186,7 +186,6 @@ declare const RegistryItemSchema: z.ZodObject<{
|
|
|
186
186
|
devDependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
187
187
|
}, z.core.$strip>>;
|
|
188
188
|
rules: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
189
|
-
composites: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
190
189
|
intelligence: z.ZodOptional<z.ZodObject<{
|
|
191
190
|
cognitiveLoad: z.ZodOptional<z.ZodNumber>;
|
|
192
191
|
attentionEconomics: z.ZodOptional<z.ZodString>;
|
|
@@ -198,54 +197,6 @@ declare const RegistryItemSchema: z.ZodObject<{
|
|
|
198
197
|
nevers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
199
198
|
}, z.core.$strip>>;
|
|
200
199
|
}, z.core.$strip>>;
|
|
201
|
-
facets: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
|
|
202
|
-
react: "react";
|
|
203
|
-
astro: "astro";
|
|
204
|
-
vue: "vue";
|
|
205
|
-
svelte: "svelte";
|
|
206
|
-
wc: "wc";
|
|
207
|
-
}> & z.core.$partial, z.ZodObject<{
|
|
208
|
-
props: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
209
|
-
type: z.ZodLiteral<"enum">;
|
|
210
|
-
values: z.ZodArray<z.ZodString>;
|
|
211
|
-
default: z.ZodOptional<z.ZodString>;
|
|
212
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
213
|
-
constraint: z.ZodOptional<z.ZodObject<{
|
|
214
|
-
when: z.ZodObject<{
|
|
215
|
-
prop: z.ZodString;
|
|
216
|
-
matches: z.ZodString;
|
|
217
|
-
}, z.core.$strip>;
|
|
218
|
-
requires: z.ZodObject<{
|
|
219
|
-
prop: z.ZodString;
|
|
220
|
-
}, z.core.$strip>;
|
|
221
|
-
}, z.core.$strip>>;
|
|
222
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
223
|
-
type: z.ZodLiteral<"boolean">;
|
|
224
|
-
default: z.ZodOptional<z.ZodBoolean>;
|
|
225
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
226
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
227
|
-
type: z.ZodLiteral<"string">;
|
|
228
|
-
default: z.ZodOptional<z.ZodString>;
|
|
229
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
230
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
231
|
-
type: z.ZodLiteral<"number">;
|
|
232
|
-
default: z.ZodOptional<z.ZodNumber>;
|
|
233
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
234
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
235
|
-
type: z.ZodLiteral<"grammar">;
|
|
236
|
-
grammar: z.ZodArray<z.ZodString>;
|
|
237
|
-
vocab: z.ZodString;
|
|
238
|
-
onInvalid: z.ZodLiteral<"silent-noop">;
|
|
239
|
-
default: z.ZodOptional<z.ZodString>;
|
|
240
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
241
|
-
type: z.ZodLiteral<"deprecated">;
|
|
242
|
-
deprecatedFor: z.ZodString;
|
|
243
|
-
}, z.core.$strip>], "type">>;
|
|
244
|
-
slots: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
245
|
-
events: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
246
|
-
snippet: z.ZodString;
|
|
247
|
-
}, z.core.$strip>>>;
|
|
248
|
-
parent: z.ZodOptional<z.ZodString>;
|
|
249
200
|
}, z.core.$strip>;
|
|
250
201
|
type RegistryItem = z.infer<typeof RegistryItemSchema>;
|
|
251
202
|
/**
|
package/dist/registry/types.js
CHANGED
|
@@ -77,13 +77,7 @@ var RegistryItemSchema = z.object({
|
|
|
77
77
|
primitives: z.array(z.string()),
|
|
78
78
|
files: z.array(RegistryFileSchema),
|
|
79
79
|
rules: z.array(z.string()).default([]),
|
|
80
|
-
|
|
81
|
-
intelligence: RegistryItemIntelligenceSchema.optional(),
|
|
82
|
-
// Per-target facets. zod v4's `z.record(enum, ...)` demands EVERY enum key be
|
|
83
|
-
// present; a component built for only some targets must parse, so this is a
|
|
84
|
-
// partial record (only the built targets appear).
|
|
85
|
-
facets: z.partialRecord(ComponentTargetSchema, FacetSchema).default({}),
|
|
86
|
-
parent: z.string().optional()
|
|
80
|
+
intelligence: RegistryItemIntelligenceSchema.optional()
|
|
87
81
|
});
|
|
88
82
|
var RegistryIndexSchema = z.object({
|
|
89
83
|
name: z.string(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rafters",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
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
5
|
"homepage": "https://rafters.studio",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,8 +46,7 @@
|
|
|
46
46
|
"commander": "^13.0.0",
|
|
47
47
|
"css-tree": "^3.2.1",
|
|
48
48
|
"execa": "^9.6.1",
|
|
49
|
-
"ora": "^9.0.0"
|
|
50
|
-
"vite": "^8.0.0"
|
|
49
|
+
"ora": "^9.0.0"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
52
|
"@playwright/test": "catalog:",
|
|
@@ -56,7 +55,6 @@
|
|
|
56
55
|
"@rafters/design-tokens": "workspace:*",
|
|
57
56
|
"@rafters/math-utils": "workspace:*",
|
|
58
57
|
"@rafters/shared": "workspace:*",
|
|
59
|
-
"@rafters/studio": "workspace:*",
|
|
60
58
|
"@types/css-tree": "^2.3.11",
|
|
61
59
|
"@types/node": "catalog:",
|
|
62
60
|
"playwright-bdd": "catalog:",
|