rafters 0.0.8 → 0.0.9
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/dist/index.js +1578 -192
- package/dist/registry/types.d.ts +61 -0
- package/dist/registry/types.js +34 -0
- package/package.json +25 -21
package/dist/index.js
CHANGED
|
@@ -9,8 +9,8 @@ import { Command } from "commander";
|
|
|
9
9
|
|
|
10
10
|
// src/commands/add.ts
|
|
11
11
|
import { existsSync } from "fs";
|
|
12
|
-
import { access, mkdir, readFile, writeFile } from "fs/promises";
|
|
13
|
-
import { dirname, join as
|
|
12
|
+
import { access, mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
13
|
+
import { dirname, join as join3 } from "path";
|
|
14
14
|
|
|
15
15
|
// ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/external.js
|
|
16
16
|
var external_exports = {};
|
|
@@ -12558,10 +12558,16 @@ config(en_default());
|
|
|
12558
12558
|
var RegistryFileSchema = external_exports.object({
|
|
12559
12559
|
path: external_exports.string(),
|
|
12560
12560
|
content: external_exports.string(),
|
|
12561
|
-
dependencies: external_exports.array(external_exports.string())
|
|
12561
|
+
dependencies: external_exports.array(external_exports.string()),
|
|
12562
12562
|
// e.g., ["lodash@4.17.21"] - versioned
|
|
12563
|
+
devDependencies: external_exports.array(external_exports.string()).default([])
|
|
12564
|
+
// e.g., ["vitest"] - from @devDependencies JSDoc
|
|
12563
12565
|
});
|
|
12564
|
-
var RegistryItemTypeSchema = external_exports.enum([
|
|
12566
|
+
var RegistryItemTypeSchema = external_exports.enum([
|
|
12567
|
+
"registry:ui",
|
|
12568
|
+
"registry:primitive",
|
|
12569
|
+
"registry:composite"
|
|
12570
|
+
]);
|
|
12565
12571
|
var RegistryItemSchema = external_exports.object({
|
|
12566
12572
|
name: external_exports.string(),
|
|
12567
12573
|
type: RegistryItemTypeSchema,
|
|
@@ -12714,18 +12720,64 @@ var RegistryClient = class {
|
|
|
12714
12720
|
};
|
|
12715
12721
|
var registryClient = new RegistryClient();
|
|
12716
12722
|
|
|
12717
|
-
// src/utils/
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12723
|
+
// src/utils/exports.ts
|
|
12724
|
+
var DEFAULT_EXPORTS = {
|
|
12725
|
+
tailwind: true,
|
|
12726
|
+
typescript: true,
|
|
12727
|
+
dtcg: false,
|
|
12728
|
+
compiled: false
|
|
12729
|
+
};
|
|
12730
|
+
var EXPORT_CHOICES = [
|
|
12731
|
+
{
|
|
12732
|
+
name: "Tailwind CSS (web projects)",
|
|
12733
|
+
value: "tailwind",
|
|
12734
|
+
checked: true
|
|
12735
|
+
},
|
|
12736
|
+
{
|
|
12737
|
+
name: "TypeScript (type-safe constants)",
|
|
12738
|
+
value: "typescript",
|
|
12739
|
+
checked: true
|
|
12740
|
+
},
|
|
12741
|
+
{
|
|
12742
|
+
name: "DTCG JSON (Figma Tokens, Style Dictionary)",
|
|
12743
|
+
value: "dtcg",
|
|
12744
|
+
checked: false
|
|
12745
|
+
},
|
|
12746
|
+
{
|
|
12747
|
+
name: "Standalone CSS (pre-built, no Tailwind required)",
|
|
12748
|
+
value: "compiled",
|
|
12749
|
+
checked: false
|
|
12750
|
+
}
|
|
12751
|
+
];
|
|
12752
|
+
var FUTURE_EXPORTS = [
|
|
12753
|
+
{
|
|
12754
|
+
name: "iOS (Swift/SwiftUI)",
|
|
12755
|
+
value: "tailwind",
|
|
12756
|
+
// placeholder
|
|
12757
|
+
checked: false,
|
|
12758
|
+
disabled: "coming soon"
|
|
12759
|
+
},
|
|
12760
|
+
{
|
|
12761
|
+
name: "Android (Compose)",
|
|
12762
|
+
value: "tailwind",
|
|
12763
|
+
// placeholder
|
|
12764
|
+
checked: false,
|
|
12765
|
+
disabled: "coming soon"
|
|
12766
|
+
}
|
|
12767
|
+
];
|
|
12768
|
+
function selectionsToConfig(selections) {
|
|
12721
12769
|
return {
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12770
|
+
tailwind: selections.includes("tailwind"),
|
|
12771
|
+
typescript: selections.includes("typescript"),
|
|
12772
|
+
dtcg: selections.includes("dtcg"),
|
|
12773
|
+
compiled: selections.includes("compiled")
|
|
12726
12774
|
};
|
|
12727
12775
|
}
|
|
12728
12776
|
|
|
12777
|
+
// src/utils/install-registry-deps.ts
|
|
12778
|
+
import { readFile } from "fs/promises";
|
|
12779
|
+
import { join } from "path";
|
|
12780
|
+
|
|
12729
12781
|
// src/utils/ui.ts
|
|
12730
12782
|
import ora from "ora";
|
|
12731
12783
|
var context = {
|
|
@@ -12844,8 +12896,9 @@ function log(event) {
|
|
|
12844
12896
|
context.spinner?.succeed("Files written");
|
|
12845
12897
|
const deps = event.dependencies;
|
|
12846
12898
|
const devDeps = event.devDependencies;
|
|
12899
|
+
const skippedDeps = event.skipped ?? [];
|
|
12847
12900
|
if (deps.length > 0 || devDeps.length > 0) {
|
|
12848
|
-
console.log(" Dependencies
|
|
12901
|
+
console.log(" Dependencies installed:");
|
|
12849
12902
|
for (const dep of deps) {
|
|
12850
12903
|
console.log(` ${dep}`);
|
|
12851
12904
|
}
|
|
@@ -12853,9 +12906,32 @@ function log(event) {
|
|
|
12853
12906
|
console.log(` ${dep} (dev)`);
|
|
12854
12907
|
}
|
|
12855
12908
|
}
|
|
12856
|
-
|
|
12909
|
+
if (skippedDeps.length > 0) {
|
|
12910
|
+
console.log(" Dependencies skipped (already installed or internal):");
|
|
12911
|
+
for (const dep of skippedDeps) {
|
|
12912
|
+
console.log(` ${dep}`);
|
|
12913
|
+
}
|
|
12914
|
+
}
|
|
12857
12915
|
break;
|
|
12858
12916
|
}
|
|
12917
|
+
case "add:deps:no-package-json":
|
|
12918
|
+
console.warn(` Warning: ${event.message}`);
|
|
12919
|
+
break;
|
|
12920
|
+
case "add:deps:dry-run": {
|
|
12921
|
+
const dryDeps = event.dependencies;
|
|
12922
|
+
console.log(" [dry-run] Would install:");
|
|
12923
|
+
for (const dep of dryDeps) {
|
|
12924
|
+
console.log(` ${dep}`);
|
|
12925
|
+
}
|
|
12926
|
+
break;
|
|
12927
|
+
}
|
|
12928
|
+
case "add:deps:install-failed":
|
|
12929
|
+
context.spinner?.fail("Failed to install dependencies");
|
|
12930
|
+
console.log(` ${event.message}`);
|
|
12931
|
+
if (event.suggestion) {
|
|
12932
|
+
console.log(` ${event.suggestion}`);
|
|
12933
|
+
}
|
|
12934
|
+
break;
|
|
12859
12935
|
case "add:complete":
|
|
12860
12936
|
context.spinner?.succeed(
|
|
12861
12937
|
`Added ${event.installed} component${event.installed !== 1 ? "s" : ""}`
|
|
@@ -12973,6 +13049,127 @@ async function installWithPackageManager(packageManager, dependencies, options)
|
|
|
12973
13049
|
}
|
|
12974
13050
|
}
|
|
12975
13051
|
|
|
13052
|
+
// src/utils/install-registry-deps.ts
|
|
13053
|
+
function parseDependency(dep) {
|
|
13054
|
+
const trimmed = dep.trim();
|
|
13055
|
+
if (!trimmed) {
|
|
13056
|
+
return { name: "", version: void 0 };
|
|
13057
|
+
}
|
|
13058
|
+
const versionAt = trimmed.lastIndexOf("@");
|
|
13059
|
+
if (versionAt <= 0) {
|
|
13060
|
+
return { name: trimmed, version: void 0 };
|
|
13061
|
+
}
|
|
13062
|
+
return {
|
|
13063
|
+
name: trimmed.slice(0, versionAt),
|
|
13064
|
+
version: trimmed.slice(versionAt + 1)
|
|
13065
|
+
};
|
|
13066
|
+
}
|
|
13067
|
+
async function readInstalledDeps(targetDir) {
|
|
13068
|
+
let raw;
|
|
13069
|
+
try {
|
|
13070
|
+
raw = await readFile(join(targetDir, "package.json"), "utf-8");
|
|
13071
|
+
} catch {
|
|
13072
|
+
return { packageJsonFound: false, installed: /* @__PURE__ */ new Set() };
|
|
13073
|
+
}
|
|
13074
|
+
try {
|
|
13075
|
+
const pkg = JSON.parse(raw);
|
|
13076
|
+
const installed = /* @__PURE__ */ new Set();
|
|
13077
|
+
const depFields = ["dependencies", "devDependencies", "peerDependencies"];
|
|
13078
|
+
for (const field of depFields) {
|
|
13079
|
+
const section = pkg[field];
|
|
13080
|
+
if (section && typeof section === "object") {
|
|
13081
|
+
for (const name2 of Object.keys(section)) {
|
|
13082
|
+
installed.add(name2);
|
|
13083
|
+
}
|
|
13084
|
+
}
|
|
13085
|
+
}
|
|
13086
|
+
return { packageJsonFound: true, installed };
|
|
13087
|
+
} catch {
|
|
13088
|
+
return { packageJsonFound: true, installed: /* @__PURE__ */ new Set() };
|
|
13089
|
+
}
|
|
13090
|
+
}
|
|
13091
|
+
async function installRegistryDependencies(items, targetDir, options = {}) {
|
|
13092
|
+
const result = {
|
|
13093
|
+
installed: [],
|
|
13094
|
+
skipped: [],
|
|
13095
|
+
devInstalled: [],
|
|
13096
|
+
failed: []
|
|
13097
|
+
};
|
|
13098
|
+
const allDeps = new Set(items.flatMap((item) => item.files.flatMap((file2) => file2.dependencies)));
|
|
13099
|
+
if (allDeps.size === 0) {
|
|
13100
|
+
return result;
|
|
13101
|
+
}
|
|
13102
|
+
const externalDeps = [];
|
|
13103
|
+
for (const dep of allDeps) {
|
|
13104
|
+
if (parseDependency(dep).name.startsWith("@rafters/")) {
|
|
13105
|
+
result.skipped.push(dep);
|
|
13106
|
+
} else {
|
|
13107
|
+
externalDeps.push(dep);
|
|
13108
|
+
}
|
|
13109
|
+
}
|
|
13110
|
+
if (externalDeps.length === 0) {
|
|
13111
|
+
return result;
|
|
13112
|
+
}
|
|
13113
|
+
const { packageJsonFound, installed: installedInProject } = await readInstalledDeps(targetDir);
|
|
13114
|
+
const toInstall = [];
|
|
13115
|
+
if (!packageJsonFound) {
|
|
13116
|
+
log({
|
|
13117
|
+
event: "add:deps:no-package-json",
|
|
13118
|
+
message: "No package.json found. Run npm init or pnpm init first.",
|
|
13119
|
+
targetDir
|
|
13120
|
+
});
|
|
13121
|
+
toInstall.push(...externalDeps);
|
|
13122
|
+
} else {
|
|
13123
|
+
for (const dep of externalDeps) {
|
|
13124
|
+
const { name: name2 } = parseDependency(dep);
|
|
13125
|
+
if (installedInProject.has(name2)) {
|
|
13126
|
+
result.skipped.push(dep);
|
|
13127
|
+
} else {
|
|
13128
|
+
toInstall.push(dep);
|
|
13129
|
+
}
|
|
13130
|
+
}
|
|
13131
|
+
}
|
|
13132
|
+
if (toInstall.length === 0) {
|
|
13133
|
+
return result;
|
|
13134
|
+
}
|
|
13135
|
+
if (options.dryRun) {
|
|
13136
|
+
log({
|
|
13137
|
+
event: "add:deps:dry-run",
|
|
13138
|
+
dependencies: toInstall
|
|
13139
|
+
});
|
|
13140
|
+
return result;
|
|
13141
|
+
}
|
|
13142
|
+
try {
|
|
13143
|
+
await updateDependencies(toInstall, [], {
|
|
13144
|
+
cwd: targetDir,
|
|
13145
|
+
silent: options.silent ?? false
|
|
13146
|
+
});
|
|
13147
|
+
result.installed = toInstall;
|
|
13148
|
+
} catch (err) {
|
|
13149
|
+
result.failed = toInstall;
|
|
13150
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
13151
|
+
log({
|
|
13152
|
+
event: "add:deps:install-failed",
|
|
13153
|
+
message: `Failed to install dependencies: ${message}`,
|
|
13154
|
+
dependencies: toInstall,
|
|
13155
|
+
suggestion: `Manually install: ${toInstall.join(" ")}`
|
|
13156
|
+
});
|
|
13157
|
+
}
|
|
13158
|
+
return result;
|
|
13159
|
+
}
|
|
13160
|
+
|
|
13161
|
+
// src/utils/paths.ts
|
|
13162
|
+
import { join as join2 } from "path";
|
|
13163
|
+
function getRaftersPaths(projectRoot = process.cwd()) {
|
|
13164
|
+
const root = join2(projectRoot, ".rafters");
|
|
13165
|
+
return {
|
|
13166
|
+
root,
|
|
13167
|
+
config: join2(root, "config.rafters.json"),
|
|
13168
|
+
tokens: join2(root, "tokens"),
|
|
13169
|
+
output: join2(root, "output")
|
|
13170
|
+
};
|
|
13171
|
+
}
|
|
13172
|
+
|
|
12976
13173
|
// src/commands/add.ts
|
|
12977
13174
|
async function isInitialized(cwd) {
|
|
12978
13175
|
const paths = getRaftersPaths(cwd);
|
|
@@ -12986,7 +13183,7 @@ async function isInitialized(cwd) {
|
|
|
12986
13183
|
async function loadConfig(cwd) {
|
|
12987
13184
|
const paths = getRaftersPaths(cwd);
|
|
12988
13185
|
try {
|
|
12989
|
-
const content = await
|
|
13186
|
+
const content = await readFile2(paths.config, "utf-8");
|
|
12990
13187
|
return JSON.parse(content);
|
|
12991
13188
|
} catch (err) {
|
|
12992
13189
|
if (existsSync(paths.config)) {
|
|
@@ -12996,6 +13193,40 @@ async function loadConfig(cwd) {
|
|
|
12996
13193
|
return null;
|
|
12997
13194
|
}
|
|
12998
13195
|
}
|
|
13196
|
+
async function saveConfig(cwd, config3) {
|
|
13197
|
+
const paths = getRaftersPaths(cwd);
|
|
13198
|
+
await writeFile(paths.config, JSON.stringify(config3, null, 2));
|
|
13199
|
+
}
|
|
13200
|
+
function getInstalledNames(config3) {
|
|
13201
|
+
if (!config3?.installed) return [];
|
|
13202
|
+
const names2 = /* @__PURE__ */ new Set([...config3.installed.components, ...config3.installed.primitives]);
|
|
13203
|
+
return [...names2].sort();
|
|
13204
|
+
}
|
|
13205
|
+
function isAlreadyInstalled(config3, item) {
|
|
13206
|
+
if (!config3?.installed) return false;
|
|
13207
|
+
if (item.type === "registry:ui") {
|
|
13208
|
+
return config3.installed.components.includes(item.name);
|
|
13209
|
+
}
|
|
13210
|
+
return config3.installed.primitives.includes(item.name);
|
|
13211
|
+
}
|
|
13212
|
+
function trackInstalled(config3, items) {
|
|
13213
|
+
if (!config3.installed) {
|
|
13214
|
+
config3.installed = { components: [], primitives: [] };
|
|
13215
|
+
}
|
|
13216
|
+
for (const item of items) {
|
|
13217
|
+
if (item.type === "registry:ui") {
|
|
13218
|
+
if (!config3.installed.components.includes(item.name)) {
|
|
13219
|
+
config3.installed.components.push(item.name);
|
|
13220
|
+
}
|
|
13221
|
+
} else {
|
|
13222
|
+
if (!config3.installed.primitives.includes(item.name)) {
|
|
13223
|
+
config3.installed.primitives.push(item.name);
|
|
13224
|
+
}
|
|
13225
|
+
}
|
|
13226
|
+
}
|
|
13227
|
+
config3.installed.components.sort();
|
|
13228
|
+
config3.installed.primitives.sort();
|
|
13229
|
+
}
|
|
12999
13230
|
function transformPath(registryPath, config3) {
|
|
13000
13231
|
if (!config3) return registryPath;
|
|
13001
13232
|
if (registryPath.startsWith("components/ui/")) {
|
|
@@ -13007,7 +13238,7 @@ function transformPath(registryPath, config3) {
|
|
|
13007
13238
|
return registryPath;
|
|
13008
13239
|
}
|
|
13009
13240
|
function fileExists(cwd, relativePath) {
|
|
13010
|
-
return existsSync(
|
|
13241
|
+
return existsSync(join3(cwd, relativePath));
|
|
13011
13242
|
}
|
|
13012
13243
|
function transformFileContent(content, config3) {
|
|
13013
13244
|
let transformed = content;
|
|
@@ -13047,7 +13278,7 @@ async function installItem(cwd, item, options, config3) {
|
|
|
13047
13278
|
let skipped = false;
|
|
13048
13279
|
for (const file2 of item.files) {
|
|
13049
13280
|
const projectPath = transformPath(file2.path, config3);
|
|
13050
|
-
const targetPath =
|
|
13281
|
+
const targetPath = join3(cwd, projectPath);
|
|
13051
13282
|
if (fileExists(cwd, projectPath)) {
|
|
13052
13283
|
if (!options.overwrite) {
|
|
13053
13284
|
log({
|
|
@@ -13071,23 +13302,9 @@ async function installItem(cwd, item, options, config3) {
|
|
|
13071
13302
|
files: installedFiles
|
|
13072
13303
|
};
|
|
13073
13304
|
}
|
|
13074
|
-
function
|
|
13075
|
-
const deps = /* @__PURE__ */ new Set();
|
|
13076
|
-
const devDeps = /* @__PURE__ */ new Set();
|
|
13077
|
-
for (const item of items) {
|
|
13078
|
-
for (const file2 of item.files) {
|
|
13079
|
-
for (const dep of file2.dependencies) {
|
|
13080
|
-
deps.add(dep);
|
|
13081
|
-
}
|
|
13082
|
-
}
|
|
13083
|
-
}
|
|
13084
|
-
return {
|
|
13085
|
-
dependencies: [...deps].sort(),
|
|
13086
|
-
devDependencies: [...devDeps].sort()
|
|
13087
|
-
};
|
|
13088
|
-
}
|
|
13089
|
-
async function add(components, options) {
|
|
13305
|
+
async function add(componentArgs, options) {
|
|
13090
13306
|
setAgentMode(options.agent ?? false);
|
|
13307
|
+
let components = componentArgs;
|
|
13091
13308
|
const client = new RegistryClient(options.registryUrl);
|
|
13092
13309
|
if (options.list) {
|
|
13093
13310
|
const availableComponents = await client.listComponents();
|
|
@@ -13109,6 +13326,24 @@ async function add(components, options) {
|
|
|
13109
13326
|
return;
|
|
13110
13327
|
}
|
|
13111
13328
|
const config3 = await loadConfig(cwd);
|
|
13329
|
+
if (options.update) {
|
|
13330
|
+
options.overwrite = true;
|
|
13331
|
+
}
|
|
13332
|
+
if (options.updateAll) {
|
|
13333
|
+
options.overwrite = true;
|
|
13334
|
+
if (!config3) {
|
|
13335
|
+
error46("No rafters config found. Run 'rafters init' first.");
|
|
13336
|
+
process.exitCode = 1;
|
|
13337
|
+
return;
|
|
13338
|
+
}
|
|
13339
|
+
const installedNames = getInstalledNames(config3);
|
|
13340
|
+
if (installedNames.length === 0) {
|
|
13341
|
+
error46("No installed components found. Use 'rafters add <component>' to install first.");
|
|
13342
|
+
process.exitCode = 1;
|
|
13343
|
+
return;
|
|
13344
|
+
}
|
|
13345
|
+
components = installedNames;
|
|
13346
|
+
}
|
|
13112
13347
|
if (components.length === 0) {
|
|
13113
13348
|
error46("No components specified. Usage: rafters add <component...>");
|
|
13114
13349
|
process.exitCode = 1;
|
|
@@ -13138,11 +13373,22 @@ async function add(components, options) {
|
|
|
13138
13373
|
}
|
|
13139
13374
|
const installed = [];
|
|
13140
13375
|
const skipped = [];
|
|
13376
|
+
const installedItems = [];
|
|
13141
13377
|
for (const item of allItems) {
|
|
13378
|
+
if (!options.overwrite && isAlreadyInstalled(config3, item)) {
|
|
13379
|
+
log({
|
|
13380
|
+
event: "add:skip",
|
|
13381
|
+
component: item.name,
|
|
13382
|
+
reason: "already installed"
|
|
13383
|
+
});
|
|
13384
|
+
skipped.push(item.name);
|
|
13385
|
+
continue;
|
|
13386
|
+
}
|
|
13142
13387
|
try {
|
|
13143
13388
|
const result = await installItem(cwd, item, options, config3);
|
|
13144
13389
|
if (result.installed) {
|
|
13145
13390
|
installed.push(item.name);
|
|
13391
|
+
installedItems.push(item);
|
|
13146
13392
|
log({
|
|
13147
13393
|
event: "add:installed",
|
|
13148
13394
|
component: item.name,
|
|
@@ -13163,22 +13409,47 @@ async function add(components, options) {
|
|
|
13163
13409
|
}
|
|
13164
13410
|
}
|
|
13165
13411
|
}
|
|
13166
|
-
const
|
|
13167
|
-
|
|
13412
|
+
const emptyDeps = {
|
|
13413
|
+
installed: [],
|
|
13414
|
+
skipped: [],
|
|
13415
|
+
devInstalled: [],
|
|
13416
|
+
failed: []
|
|
13417
|
+
};
|
|
13418
|
+
let depsResult = emptyDeps;
|
|
13419
|
+
try {
|
|
13420
|
+
depsResult = await installRegistryDependencies(allItems, cwd);
|
|
13421
|
+
} catch (err) {
|
|
13422
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
13423
|
+
log({
|
|
13424
|
+
event: "add:deps:install-failed",
|
|
13425
|
+
message: `Failed to process dependencies: ${message}`,
|
|
13426
|
+
dependencies: [],
|
|
13427
|
+
suggestion: "Check package.json and try installing dependencies manually."
|
|
13428
|
+
});
|
|
13429
|
+
}
|
|
13430
|
+
if (depsResult.installed.length > 0 || depsResult.skipped.length > 0) {
|
|
13168
13431
|
log({
|
|
13169
13432
|
event: "add:dependencies",
|
|
13170
|
-
dependencies,
|
|
13171
|
-
devDependencies
|
|
13433
|
+
dependencies: depsResult.installed,
|
|
13434
|
+
devDependencies: depsResult.devInstalled,
|
|
13435
|
+
skipped: depsResult.skipped
|
|
13172
13436
|
});
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13437
|
+
}
|
|
13438
|
+
if (installedItems.length > 0 && config3) {
|
|
13439
|
+
trackInstalled(config3, installedItems);
|
|
13440
|
+
await saveConfig(cwd, config3);
|
|
13441
|
+
} else if (installedItems.length > 0 && !config3) {
|
|
13442
|
+
const newConfig = {
|
|
13443
|
+
framework: "unknown",
|
|
13444
|
+
componentsPath: "components/ui",
|
|
13445
|
+
primitivesPath: "lib/primitives",
|
|
13446
|
+
cssPath: null,
|
|
13447
|
+
shadcn: false,
|
|
13448
|
+
exports: DEFAULT_EXPORTS,
|
|
13449
|
+
installed: { components: [], primitives: [] }
|
|
13450
|
+
};
|
|
13451
|
+
trackInstalled(newConfig, installedItems);
|
|
13452
|
+
await saveConfig(cwd, newConfig);
|
|
13182
13453
|
}
|
|
13183
13454
|
log({
|
|
13184
13455
|
event: "add:complete",
|
|
@@ -13189,19 +13460,19 @@ async function add(components, options) {
|
|
|
13189
13460
|
if (skipped.length > 0 && installed.length === 0) {
|
|
13190
13461
|
log({
|
|
13191
13462
|
event: "add:hint",
|
|
13192
|
-
message: "Some components were skipped. Use --
|
|
13463
|
+
message: "Some components were skipped. Use --update to re-fetch, or --update-all to refresh everything.",
|
|
13193
13464
|
skipped
|
|
13194
13465
|
});
|
|
13195
|
-
error46("Component already exists. Use --
|
|
13466
|
+
error46("Component already exists. Use --update to re-fetch from registry.");
|
|
13196
13467
|
process.exitCode = 1;
|
|
13197
13468
|
}
|
|
13198
13469
|
}
|
|
13199
13470
|
|
|
13200
13471
|
// src/commands/init.ts
|
|
13201
13472
|
import { existsSync as existsSync2 } from "fs";
|
|
13202
|
-
import { copyFile, mkdir as mkdir3, readFile as
|
|
13473
|
+
import { copyFile, mkdir as mkdir3, readFile as readFile5, rm, writeFile as writeFile3 } from "fs/promises";
|
|
13203
13474
|
import { createRequire } from "module";
|
|
13204
|
-
import { join as
|
|
13475
|
+
import { join as join9, relative } from "path";
|
|
13205
13476
|
import { checkbox, confirm } from "@inquirer/prompts";
|
|
13206
13477
|
|
|
13207
13478
|
// ../design-tokens/src/plugins/scale.ts
|
|
@@ -24332,7 +24603,7 @@ var require_volume = __commonJS({
|
|
|
24332
24603
|
var Dir_1 = require_Dir();
|
|
24333
24604
|
var resolveCrossPlatform = pathModule.resolve;
|
|
24334
24605
|
var { O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_DIRECTORY, O_SYMLINK, F_OK, COPYFILE_EXCL, COPYFILE_FICLONE_FORCE } = constants_1.constants;
|
|
24335
|
-
var { sep: sep2, relative: relative2, join:
|
|
24606
|
+
var { sep: sep2, relative: relative2, join: join12, dirname: dirname4 } = pathModule.posix ? pathModule.posix : pathModule;
|
|
24336
24607
|
var kMinPoolSpace = 128;
|
|
24337
24608
|
var EPERM = "EPERM";
|
|
24338
24609
|
var ENOENT2 = "ENOENT";
|
|
@@ -24398,7 +24669,7 @@ var require_volume = __commonJS({
|
|
|
24398
24669
|
function flatten(pathPrefix, node) {
|
|
24399
24670
|
for (const path2 in node) {
|
|
24400
24671
|
const contentOrNode = node[path2];
|
|
24401
|
-
const joinedPath =
|
|
24672
|
+
const joinedPath = join12(pathPrefix, path2);
|
|
24402
24673
|
if (typeof contentOrNode === "string" || contentOrNode instanceof buffer_1.Buffer) {
|
|
24403
24674
|
flatJSON[joinedPath] = contentOrNode;
|
|
24404
24675
|
} else if (typeof contentOrNode === "object" && contentOrNode !== null && Object.keys(contentOrNode).length > 0) {
|
|
@@ -24555,7 +24826,7 @@ var require_volume = __commonJS({
|
|
|
24555
24826
|
return null;
|
|
24556
24827
|
node = curr === null || curr === void 0 ? void 0 : curr.getNode();
|
|
24557
24828
|
if (resolveSymlinks && node.isSymlink()) {
|
|
24558
|
-
const resolvedPath = pathModule.isAbsolute(node.symlink) ? node.symlink :
|
|
24829
|
+
const resolvedPath = pathModule.isAbsolute(node.symlink) ? node.symlink : join12(pathModule.dirname(curr.getPath()), node.symlink);
|
|
24559
24830
|
steps = filenameToSteps(resolvedPath).concat(steps.slice(i + 1));
|
|
24560
24831
|
curr = this.root;
|
|
24561
24832
|
i = 0;
|
|
@@ -27479,7 +27750,7 @@ var posix = {
|
|
|
27479
27750
|
|
|
27480
27751
|
// ../../node_modules/.pnpm/path-unified@0.2.0/node_modules/path-unified/src/posix.js
|
|
27481
27752
|
var resolve = posResolve;
|
|
27482
|
-
var
|
|
27753
|
+
var join4 = posJoin;
|
|
27483
27754
|
|
|
27484
27755
|
// ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
27485
27756
|
var balanced = (a, b, str) => {
|
|
@@ -37378,7 +37649,7 @@ var transforms_default = {
|
|
|
37378
37649
|
type: value,
|
|
37379
37650
|
filter: isAsset,
|
|
37380
37651
|
transform: function(token, _, options) {
|
|
37381
|
-
return
|
|
37652
|
+
return join4(process?.cwd() ?? "/", options.usesDtcg ? token.$value : token.value);
|
|
37382
37653
|
}
|
|
37383
37654
|
},
|
|
37384
37655
|
/**
|
|
@@ -43578,12 +43849,12 @@ var formats_default = formats2;
|
|
|
43578
43849
|
var { androidCopyImages, copyAssets } = actions;
|
|
43579
43850
|
var { silent } = logVerbosityLevels;
|
|
43580
43851
|
function getAssetDir(config3) {
|
|
43581
|
-
return
|
|
43852
|
+
return join4(config3.buildPath ?? "", "android/main/res/drawable-").replace(/\\/g, "/");
|
|
43582
43853
|
}
|
|
43583
43854
|
function getAssetPath(token, imagesDir) {
|
|
43584
43855
|
const name2 = token.path.slice(2, 4).join("_");
|
|
43585
43856
|
const dir = `${imagesDir}${token.attributes?.state}`;
|
|
43586
|
-
return { file:
|
|
43857
|
+
return { file: join4(dir, `${name2}.png`), dir };
|
|
43587
43858
|
}
|
|
43588
43859
|
var actions_default = {
|
|
43589
43860
|
/**
|
|
@@ -43624,7 +43895,7 @@ var actions_default = {
|
|
|
43624
43895
|
*/
|
|
43625
43896
|
[copyAssets]: {
|
|
43626
43897
|
do: async function(_, config3, _options, vol2 = fs2) {
|
|
43627
|
-
const assetsPath =
|
|
43898
|
+
const assetsPath = join4(config3.buildPath ?? "", "assets");
|
|
43628
43899
|
if (config3.log?.verbosity !== silent) {
|
|
43629
43900
|
console.log(`Copying assets directory to ${assetsPath}`);
|
|
43630
43901
|
}
|
|
@@ -43638,7 +43909,7 @@ var actions_default = {
|
|
|
43638
43909
|
);
|
|
43639
43910
|
},
|
|
43640
43911
|
undo: async function(_, config3, _options, vol2 = fs2) {
|
|
43641
|
-
const assetsPath =
|
|
43912
|
+
const assetsPath = join4(config3.buildPath ?? "", "assets");
|
|
43642
43913
|
if (config3.log?.verbosity !== silent) {
|
|
43643
43914
|
console.log(`Removing assets directory from ${assetsPath}`);
|
|
43644
43915
|
}
|
|
@@ -44119,8 +44390,14 @@ var DEFAULT_DEPTH_DEFINITIONS = {
|
|
|
44119
44390
|
},
|
|
44120
44391
|
sticky: {
|
|
44121
44392
|
value: 20,
|
|
44122
|
-
meaning: "Sticky elements - headers,
|
|
44123
|
-
contexts: ["sticky-header", "sticky-
|
|
44393
|
+
meaning: "Sticky elements - headers, toolbars",
|
|
44394
|
+
contexts: ["sticky-header", "sticky-toolbar", "floating-actions"],
|
|
44395
|
+
stackingContext: true
|
|
44396
|
+
},
|
|
44397
|
+
navigation: {
|
|
44398
|
+
value: 25,
|
|
44399
|
+
meaning: "Navigation panels - sidebars, slide-out nav",
|
|
44400
|
+
contexts: ["sidebar", "navigation-panel", "slide-out-menu"],
|
|
44124
44401
|
stackingContext: true
|
|
44125
44402
|
},
|
|
44126
44403
|
fixed: {
|
|
@@ -44146,6 +44423,12 @@ var DEFAULT_DEPTH_DEFINITIONS = {
|
|
|
44146
44423
|
meaning: "Tooltips - highest common layer",
|
|
44147
44424
|
contexts: ["tooltips", "toast-notifications"],
|
|
44148
44425
|
stackingContext: true
|
|
44426
|
+
},
|
|
44427
|
+
overlay: {
|
|
44428
|
+
value: 70,
|
|
44429
|
+
meaning: "Overlay backdrops - screen-dimming layers behind modals",
|
|
44430
|
+
contexts: ["modal-backdrop", "drawer-backdrop", "sheet-backdrop"],
|
|
44431
|
+
stackingContext: true
|
|
44149
44432
|
}
|
|
44150
44433
|
};
|
|
44151
44434
|
var DEFAULT_SHADOW_DEFINITIONS = {
|
|
@@ -46443,6 +46726,78 @@ function generateThemeBlock(groups) {
|
|
|
46443
46726
|
lines.push("}");
|
|
46444
46727
|
return lines.join("\n");
|
|
46445
46728
|
}
|
|
46729
|
+
var ARTICLE_ELEMENT_STYLES = [
|
|
46730
|
+
// Paragraphs
|
|
46731
|
+
["p", "leading-relaxed mb-4"],
|
|
46732
|
+
["p:last-child", "mb-0"],
|
|
46733
|
+
// Headings
|
|
46734
|
+
["h1", "text-4xl font-bold tracking-tight mb-4 mt-0 text-accent-foreground"],
|
|
46735
|
+
["h2", "text-3xl font-semibold tracking-tight mb-3 mt-8 text-accent-foreground"],
|
|
46736
|
+
["h2:first-child", "mt-0"],
|
|
46737
|
+
["h3", "text-2xl font-semibold mb-2 mt-6 text-accent-foreground"],
|
|
46738
|
+
["h4", "text-xl font-semibold mb-2 mt-4 text-accent-foreground"],
|
|
46739
|
+
["h5", "text-lg font-semibold mb-2 mt-4 text-accent-foreground"],
|
|
46740
|
+
["h6", "text-base font-semibold mb-2 mt-4 text-accent-foreground"],
|
|
46741
|
+
// Lists
|
|
46742
|
+
["ul", "list-disc pl-6 mb-4"],
|
|
46743
|
+
["ol", "list-decimal pl-6 mb-4"],
|
|
46744
|
+
["li", "mb-1"],
|
|
46745
|
+
["li > ul,\n article li > ol", "mt-1 mb-0"],
|
|
46746
|
+
// Links
|
|
46747
|
+
["a", "text-primary underline underline-offset-4"],
|
|
46748
|
+
["a:hover", "text-primary/80"],
|
|
46749
|
+
// Blockquotes
|
|
46750
|
+
["blockquote", "border-l-4 border-muted pl-4 italic my-4"],
|
|
46751
|
+
// Code
|
|
46752
|
+
["code", "bg-muted px-1.5 py-0.5 rounded text-sm font-mono"],
|
|
46753
|
+
["pre", "bg-muted p-4 rounded-lg overflow-x-auto my-4 text-sm font-mono"],
|
|
46754
|
+
["pre code", "bg-transparent p-0 rounded-none text-[inherit]"],
|
|
46755
|
+
["kbd", "bg-muted border border-border rounded px-1.5 py-0.5 text-sm font-mono"],
|
|
46756
|
+
// Horizontal rules
|
|
46757
|
+
["hr", "border-border my-8"],
|
|
46758
|
+
// Media
|
|
46759
|
+
["img", "rounded-lg my-4 max-w-full h-auto"],
|
|
46760
|
+
["video", "rounded-lg my-4 max-w-full h-auto"],
|
|
46761
|
+
// Tables
|
|
46762
|
+
["table", "w-full my-4 border-collapse"],
|
|
46763
|
+
["caption", "mt-2 text-sm text-muted-foreground text-left"],
|
|
46764
|
+
["th", "border border-border px-3 py-2 text-left font-semibold"],
|
|
46765
|
+
["td", "border border-border px-3 py-2"],
|
|
46766
|
+
// Figures
|
|
46767
|
+
["figure", "my-4"],
|
|
46768
|
+
["figcaption", "mt-2 text-sm text-muted-foreground"],
|
|
46769
|
+
// Definition lists
|
|
46770
|
+
["dl", "my-4"],
|
|
46771
|
+
["dt", "font-semibold mt-2"],
|
|
46772
|
+
["dd", "pl-4 mb-2"],
|
|
46773
|
+
// Details/Summary
|
|
46774
|
+
["details", "my-4"],
|
|
46775
|
+
["summary", "cursor-pointer font-semibold"],
|
|
46776
|
+
// Inline formatting
|
|
46777
|
+
["strong,\n article b", "font-semibold"],
|
|
46778
|
+
["mark", "bg-accent text-accent-foreground px-1 rounded"],
|
|
46779
|
+
["small", "text-sm"],
|
|
46780
|
+
["sub", "text-xs align-sub"],
|
|
46781
|
+
["sup", "text-xs align-super"],
|
|
46782
|
+
["abbr[title]", "underline decoration-dotted underline-offset-4 cursor-help"],
|
|
46783
|
+
["s,\n article del", "line-through"],
|
|
46784
|
+
["ins", "underline"]
|
|
46785
|
+
];
|
|
46786
|
+
function generateArticleBaseLayer() {
|
|
46787
|
+
const lines = [];
|
|
46788
|
+
lines.push("@layer base {");
|
|
46789
|
+
for (const [selector, utilities] of ARTICLE_ELEMENT_STYLES) {
|
|
46790
|
+
if (selector.includes("\n")) {
|
|
46791
|
+
lines.push(` article ${selector} {`);
|
|
46792
|
+
} else {
|
|
46793
|
+
lines.push(` article ${selector} {`);
|
|
46794
|
+
}
|
|
46795
|
+
lines.push(` @apply ${utilities};`);
|
|
46796
|
+
lines.push(" }");
|
|
46797
|
+
}
|
|
46798
|
+
lines.push("}");
|
|
46799
|
+
return lines.join("\n");
|
|
46800
|
+
}
|
|
46446
46801
|
function generateKeyframes(motionTokens) {
|
|
46447
46802
|
const keyframeTokens = motionTokens.filter((t2) => t2.name.startsWith("motion-keyframe-"));
|
|
46448
46803
|
if (keyframeTokens.length === 0) {
|
|
@@ -46494,6 +46849,8 @@ function tokensToTailwind(tokens, options = {}) {
|
|
|
46494
46849
|
if (keyframes) {
|
|
46495
46850
|
sections.push(keyframes);
|
|
46496
46851
|
}
|
|
46852
|
+
sections.push("");
|
|
46853
|
+
sections.push(generateArticleBaseLayer());
|
|
46497
46854
|
return sections.join("\n");
|
|
46498
46855
|
}
|
|
46499
46856
|
function registryToTailwind(registry2, options) {
|
|
@@ -46505,7 +46862,7 @@ async function registryToCompiled(registry2, options = {}) {
|
|
|
46505
46862
|
const themeCss = registryToTailwind(registry2, { includeImport });
|
|
46506
46863
|
const { execFileSync } = await import("child_process");
|
|
46507
46864
|
const { mkdtempSync, writeFileSync, readFileSync, rmSync } = await import("fs");
|
|
46508
|
-
const { join:
|
|
46865
|
+
const { join: join12, dirname: dirname4 } = await import("path");
|
|
46509
46866
|
const { createRequire: createRequire2 } = await import("module");
|
|
46510
46867
|
const require2 = createRequire2(import.meta.url);
|
|
46511
46868
|
let pkgDir;
|
|
@@ -46515,10 +46872,10 @@ async function registryToCompiled(registry2, options = {}) {
|
|
|
46515
46872
|
} catch {
|
|
46516
46873
|
throw new Error("Failed to resolve @tailwindcss/cli");
|
|
46517
46874
|
}
|
|
46518
|
-
const binPath =
|
|
46519
|
-
const tempDir = mkdtempSync(
|
|
46520
|
-
const tempInput =
|
|
46521
|
-
const tempOutput =
|
|
46875
|
+
const binPath = join12(pkgDir, "dist", "index.mjs");
|
|
46876
|
+
const tempDir = mkdtempSync(join12(pkgDir, ".tmp-compile-"));
|
|
46877
|
+
const tempInput = join12(tempDir, "input.css");
|
|
46878
|
+
const tempOutput = join12(tempDir, "output.css");
|
|
46522
46879
|
try {
|
|
46523
46880
|
writeFileSync(tempInput, themeCss);
|
|
46524
46881
|
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
@@ -46797,7 +47154,7 @@ function tagTokenizer() {
|
|
|
46797
47154
|
|
|
46798
47155
|
// ../../node_modules/.pnpm/comment-parser@1.4.1/node_modules/comment-parser/es6/parser/tokenizers/type.js
|
|
46799
47156
|
function typeTokenizer(spacing = "compact") {
|
|
46800
|
-
const
|
|
47157
|
+
const join12 = getJoiner(spacing);
|
|
46801
47158
|
return (spec) => {
|
|
46802
47159
|
let curlies = 0;
|
|
46803
47160
|
let lines = [];
|
|
@@ -46840,7 +47197,7 @@ function typeTokenizer(spacing = "compact") {
|
|
|
46840
47197
|
}
|
|
46841
47198
|
parts[0] = parts[0].slice(1);
|
|
46842
47199
|
parts[parts.length - 1] = parts[parts.length - 1].slice(0, -1);
|
|
46843
|
-
spec.type =
|
|
47200
|
+
spec.type = join12(parts);
|
|
46844
47201
|
return spec;
|
|
46845
47202
|
};
|
|
46846
47203
|
}
|
|
@@ -46938,9 +47295,9 @@ function nameTokenizer() {
|
|
|
46938
47295
|
|
|
46939
47296
|
// ../../node_modules/.pnpm/comment-parser@1.4.1/node_modules/comment-parser/es6/parser/tokenizers/description.js
|
|
46940
47297
|
function descriptionTokenizer(spacing = "compact", markers = Markers) {
|
|
46941
|
-
const
|
|
47298
|
+
const join12 = getJoiner2(spacing);
|
|
46942
47299
|
return (spec) => {
|
|
46943
|
-
spec.description =
|
|
47300
|
+
spec.description = join12(spec.source, markers);
|
|
46944
47301
|
return spec;
|
|
46945
47302
|
};
|
|
46946
47303
|
}
|
|
@@ -47001,11 +47358,11 @@ function getParser4({ startLine = 0, fence = "```", spacing = "compact", markers
|
|
|
47001
47358
|
}
|
|
47002
47359
|
|
|
47003
47360
|
// ../../node_modules/.pnpm/comment-parser@1.4.1/node_modules/comment-parser/es6/stringifier/index.js
|
|
47004
|
-
function
|
|
47361
|
+
function join5(tokens) {
|
|
47005
47362
|
return tokens.start + tokens.delimiter + tokens.postDelimiter + tokens.tag + tokens.postTag + tokens.type + tokens.postType + tokens.name + tokens.postName + tokens.description + tokens.end + tokens.lineEnd;
|
|
47006
47363
|
}
|
|
47007
47364
|
function getStringifier() {
|
|
47008
|
-
return (block) => block.source.map(({ tokens }) =>
|
|
47365
|
+
return (block) => block.source.map(({ tokens }) => join5(tokens)).join("\n");
|
|
47009
47366
|
}
|
|
47010
47367
|
|
|
47011
47368
|
// ../../node_modules/.pnpm/comment-parser@1.4.1/node_modules/comment-parser/es6/stringifier/inspect.js
|
|
@@ -47174,6 +47531,32 @@ function extractPrimitiveDependencies(source) {
|
|
|
47174
47531
|
}
|
|
47175
47532
|
return primitives;
|
|
47176
47533
|
}
|
|
47534
|
+
var DEP_TAG_MAP = {
|
|
47535
|
+
dependencies: "runtime",
|
|
47536
|
+
devdependencies: "dev",
|
|
47537
|
+
"internal-dependencies": "internal",
|
|
47538
|
+
internaldependencies: "internal"
|
|
47539
|
+
};
|
|
47540
|
+
function extractJSDocDependencies(source) {
|
|
47541
|
+
const result = { runtime: [], dev: [], internal: [] };
|
|
47542
|
+
const blocks = parse3(source);
|
|
47543
|
+
if (blocks.length === 0) return result;
|
|
47544
|
+
for (const block of blocks) {
|
|
47545
|
+
for (const tag of block.tags) {
|
|
47546
|
+
const field = DEP_TAG_MAP[tag.tag.toLowerCase()];
|
|
47547
|
+
if (!field) continue;
|
|
47548
|
+
const value2 = getTagValue(tag).trim();
|
|
47549
|
+
if (value2) {
|
|
47550
|
+
result[field].push(...value2.split(/\s+/).filter(Boolean));
|
|
47551
|
+
}
|
|
47552
|
+
}
|
|
47553
|
+
}
|
|
47554
|
+
return {
|
|
47555
|
+
runtime: [...new Set(result.runtime)],
|
|
47556
|
+
dev: [...new Set(result.dev)],
|
|
47557
|
+
internal: [...new Set(result.internal)]
|
|
47558
|
+
};
|
|
47559
|
+
}
|
|
47177
47560
|
function toDisplayName(name2) {
|
|
47178
47561
|
return name2.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
47179
47562
|
}
|
|
@@ -48263,10 +48646,12 @@ var DEPTH_LEVELS = [
|
|
|
48263
48646
|
"base",
|
|
48264
48647
|
"dropdown",
|
|
48265
48648
|
"sticky",
|
|
48649
|
+
"navigation",
|
|
48266
48650
|
"fixed",
|
|
48267
48651
|
"modal",
|
|
48268
48652
|
"popover",
|
|
48269
|
-
"tooltip"
|
|
48653
|
+
"tooltip",
|
|
48654
|
+
"overlay"
|
|
48270
48655
|
];
|
|
48271
48656
|
var ELEVATION_LEVELS = [
|
|
48272
48657
|
"surface",
|
|
@@ -50325,14 +50710,14 @@ function buildColorSystem(options = {}) {
|
|
|
50325
50710
|
}
|
|
50326
50711
|
|
|
50327
50712
|
// ../design-tokens/src/persistence/node-adapter.ts
|
|
50328
|
-
import { mkdir as mkdir2, readdir as readdir2, readFile as
|
|
50329
|
-
import { join as
|
|
50713
|
+
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
|
|
50714
|
+
import { join as join6 } from "path";
|
|
50330
50715
|
var SCHEMA_URL = "https://rafters.studio/schemas/namespace-tokens.json";
|
|
50331
50716
|
var VERSION = "1.0.0";
|
|
50332
50717
|
var NodePersistenceAdapter = class {
|
|
50333
50718
|
tokensDir;
|
|
50334
50719
|
constructor(projectRoot) {
|
|
50335
|
-
this.tokensDir =
|
|
50720
|
+
this.tokensDir = join6(projectRoot, ".rafters", "tokens");
|
|
50336
50721
|
}
|
|
50337
50722
|
async load() {
|
|
50338
50723
|
let files;
|
|
@@ -50344,7 +50729,7 @@ var NodePersistenceAdapter = class {
|
|
|
50344
50729
|
const allTokens = [];
|
|
50345
50730
|
for (const file2 of files) {
|
|
50346
50731
|
if (!file2.endsWith(".rafters.json")) continue;
|
|
50347
|
-
const content = await
|
|
50732
|
+
const content = await readFile3(join6(this.tokensDir, file2), "utf-8");
|
|
50348
50733
|
const data = NamespaceFileSchema.parse(JSON.parse(content));
|
|
50349
50734
|
allTokens.push(...data.tokens);
|
|
50350
50735
|
}
|
|
@@ -50372,7 +50757,7 @@ var NodePersistenceAdapter = class {
|
|
|
50372
50757
|
};
|
|
50373
50758
|
NamespaceFileSchema.parse(data);
|
|
50374
50759
|
await writeFile2(
|
|
50375
|
-
|
|
50760
|
+
join6(this.tokensDir, `${namespace}.rafters.json`),
|
|
50376
50761
|
JSON.stringify(data, null, 2)
|
|
50377
50762
|
);
|
|
50378
50763
|
}
|
|
@@ -50381,7 +50766,7 @@ var NodePersistenceAdapter = class {
|
|
|
50381
50766
|
|
|
50382
50767
|
// ../design-tokens/src/rule-engine.ts
|
|
50383
50768
|
import { promises as fs3 } from "fs";
|
|
50384
|
-
import { join as
|
|
50769
|
+
import { join as join7 } from "path";
|
|
50385
50770
|
var RuleResultSchema = external_exports.union([
|
|
50386
50771
|
external_exports.string(),
|
|
50387
50772
|
external_exports.object({
|
|
@@ -50397,11 +50782,11 @@ var RuleContextSchema = external_exports.object({
|
|
|
50397
50782
|
});
|
|
50398
50783
|
|
|
50399
50784
|
// src/utils/detect.ts
|
|
50400
|
-
import { readFile as
|
|
50401
|
-
import { join as
|
|
50785
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
50786
|
+
import { join as join8 } from "path";
|
|
50402
50787
|
async function detectFramework(cwd) {
|
|
50403
50788
|
try {
|
|
50404
|
-
const content = await
|
|
50789
|
+
const content = await readFile4(join8(cwd, "package.json"), "utf-8");
|
|
50405
50790
|
const pkg = JSON.parse(content);
|
|
50406
50791
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
50407
50792
|
if (deps.next) {
|
|
@@ -50427,7 +50812,7 @@ async function detectFramework(cwd) {
|
|
|
50427
50812
|
}
|
|
50428
50813
|
async function detectTailwindVersion(cwd) {
|
|
50429
50814
|
try {
|
|
50430
|
-
const content = await
|
|
50815
|
+
const content = await readFile4(join8(cwd, "package.json"), "utf-8");
|
|
50431
50816
|
const pkg = JSON.parse(content);
|
|
50432
50817
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
50433
50818
|
const tailwindVersion = deps.tailwindcss;
|
|
@@ -50448,7 +50833,7 @@ function isTailwindV3(version2) {
|
|
|
50448
50833
|
}
|
|
50449
50834
|
async function detectShadcn(cwd) {
|
|
50450
50835
|
try {
|
|
50451
|
-
const content = await
|
|
50836
|
+
const content = await readFile4(join8(cwd, "components.json"), "utf-8");
|
|
50452
50837
|
return JSON.parse(content);
|
|
50453
50838
|
} catch {
|
|
50454
50839
|
return null;
|
|
@@ -50510,60 +50895,6 @@ async function detectProject(cwd) {
|
|
|
50510
50895
|
};
|
|
50511
50896
|
}
|
|
50512
50897
|
|
|
50513
|
-
// src/utils/exports.ts
|
|
50514
|
-
var DEFAULT_EXPORTS = {
|
|
50515
|
-
tailwind: true,
|
|
50516
|
-
typescript: true,
|
|
50517
|
-
dtcg: false,
|
|
50518
|
-
compiled: false
|
|
50519
|
-
};
|
|
50520
|
-
var EXPORT_CHOICES = [
|
|
50521
|
-
{
|
|
50522
|
-
name: "Tailwind CSS (web projects)",
|
|
50523
|
-
value: "tailwind",
|
|
50524
|
-
checked: true
|
|
50525
|
-
},
|
|
50526
|
-
{
|
|
50527
|
-
name: "TypeScript (type-safe constants)",
|
|
50528
|
-
value: "typescript",
|
|
50529
|
-
checked: true
|
|
50530
|
-
},
|
|
50531
|
-
{
|
|
50532
|
-
name: "DTCG JSON (Figma Tokens, Style Dictionary)",
|
|
50533
|
-
value: "dtcg",
|
|
50534
|
-
checked: false
|
|
50535
|
-
},
|
|
50536
|
-
{
|
|
50537
|
-
name: "Standalone CSS (pre-built, no Tailwind required)",
|
|
50538
|
-
value: "compiled",
|
|
50539
|
-
checked: false
|
|
50540
|
-
}
|
|
50541
|
-
];
|
|
50542
|
-
var FUTURE_EXPORTS = [
|
|
50543
|
-
{
|
|
50544
|
-
name: "iOS (Swift/SwiftUI)",
|
|
50545
|
-
value: "tailwind",
|
|
50546
|
-
// placeholder
|
|
50547
|
-
checked: false,
|
|
50548
|
-
disabled: "coming soon"
|
|
50549
|
-
},
|
|
50550
|
-
{
|
|
50551
|
-
name: "Android (Compose)",
|
|
50552
|
-
value: "tailwind",
|
|
50553
|
-
// placeholder
|
|
50554
|
-
checked: false,
|
|
50555
|
-
disabled: "coming soon"
|
|
50556
|
-
}
|
|
50557
|
-
];
|
|
50558
|
-
function selectionsToConfig(selections) {
|
|
50559
|
-
return {
|
|
50560
|
-
tailwind: selections.includes("tailwind"),
|
|
50561
|
-
typescript: selections.includes("typescript"),
|
|
50562
|
-
dtcg: selections.includes("dtcg"),
|
|
50563
|
-
compiled: selections.includes("compiled")
|
|
50564
|
-
};
|
|
50565
|
-
}
|
|
50566
|
-
|
|
50567
50898
|
// src/commands/init.ts
|
|
50568
50899
|
async function backupCss(cssPath) {
|
|
50569
50900
|
const backupPath = cssPath.replace(/\.css$/, ".backup.css");
|
|
@@ -50589,7 +50920,7 @@ var COMPONENT_PATHS = {
|
|
|
50589
50920
|
async function findMainCssFile(cwd, framework) {
|
|
50590
50921
|
const locations = CSS_LOCATIONS[framework] || CSS_LOCATIONS.unknown;
|
|
50591
50922
|
for (const location of locations) {
|
|
50592
|
-
const fullPath =
|
|
50923
|
+
const fullPath = join9(cwd, location);
|
|
50593
50924
|
if (existsSync2(fullPath)) {
|
|
50594
50925
|
return location;
|
|
50595
50926
|
}
|
|
@@ -50597,10 +50928,10 @@ async function findMainCssFile(cwd, framework) {
|
|
|
50597
50928
|
return null;
|
|
50598
50929
|
}
|
|
50599
50930
|
async function updateMainCss(cwd, cssPath, themePath) {
|
|
50600
|
-
const fullCssPath =
|
|
50601
|
-
const cssContent = await
|
|
50602
|
-
const cssDir =
|
|
50603
|
-
const themeFullPath =
|
|
50931
|
+
const fullCssPath = join9(cwd, cssPath);
|
|
50932
|
+
const cssContent = await readFile5(fullCssPath, "utf-8");
|
|
50933
|
+
const cssDir = join9(cwd, cssPath, "..");
|
|
50934
|
+
const themeFullPath = join9(cwd, themePath);
|
|
50604
50935
|
const relativeThemePath = relative(cssDir, themeFullPath);
|
|
50605
50936
|
if (cssContent.includes(".rafters/output/rafters.css")) {
|
|
50606
50937
|
log({ event: "init:css_already_imported", cssPath });
|
|
@@ -50688,17 +51019,17 @@ async function generateOutputs(cwd, paths, registry2, exports, shadcn) {
|
|
|
50688
51019
|
const outputs = [];
|
|
50689
51020
|
if (exports.tailwind) {
|
|
50690
51021
|
const tailwindCss = registryToTailwind(registry2, { includeImport: !shadcn });
|
|
50691
|
-
await writeFile3(
|
|
51022
|
+
await writeFile3(join9(paths.output, "rafters.css"), tailwindCss);
|
|
50692
51023
|
outputs.push("rafters.css");
|
|
50693
51024
|
}
|
|
50694
51025
|
if (exports.typescript) {
|
|
50695
51026
|
const typescriptSrc = registryToTypeScript(registry2, { includeJSDoc: true });
|
|
50696
|
-
await writeFile3(
|
|
51027
|
+
await writeFile3(join9(paths.output, "rafters.ts"), typescriptSrc);
|
|
50697
51028
|
outputs.push("rafters.ts");
|
|
50698
51029
|
}
|
|
50699
51030
|
if (exports.dtcg) {
|
|
50700
51031
|
const dtcgJson = toDTCG(registry2.list());
|
|
50701
|
-
await writeFile3(
|
|
51032
|
+
await writeFile3(join9(paths.output, "rafters.json"), JSON.stringify(dtcgJson, null, 2));
|
|
50702
51033
|
outputs.push("rafters.json");
|
|
50703
51034
|
}
|
|
50704
51035
|
if (exports.compiled) {
|
|
@@ -50707,7 +51038,7 @@ async function generateOutputs(cwd, paths, registry2, exports, shadcn) {
|
|
|
50707
51038
|
}
|
|
50708
51039
|
log({ event: "init:compiling_css" });
|
|
50709
51040
|
const compiledCss = await registryToCompiled(registry2, { includeImport: !shadcn });
|
|
50710
|
-
await writeFile3(
|
|
51041
|
+
await writeFile3(join9(paths.output, "rafters.standalone.css"), compiledCss);
|
|
50711
51042
|
outputs.push("rafters.standalone.css");
|
|
50712
51043
|
}
|
|
50713
51044
|
return outputs;
|
|
@@ -50716,7 +51047,7 @@ async function regenerateFromExisting(cwd, paths, shadcn, isAgentMode2) {
|
|
|
50716
51047
|
log({ event: "init:regenerate", cwd });
|
|
50717
51048
|
let existingConfig = null;
|
|
50718
51049
|
try {
|
|
50719
|
-
const configContent = await
|
|
51050
|
+
const configContent = await readFile5(paths.config, "utf-8");
|
|
50720
51051
|
existingConfig = JSON.parse(configContent);
|
|
50721
51052
|
} catch {
|
|
50722
51053
|
}
|
|
@@ -50759,7 +51090,7 @@ async function resetToDefaults(cwd, paths, shadcn, isAgentMode2) {
|
|
|
50759
51090
|
log({ event: "init:reset", cwd });
|
|
50760
51091
|
let existingConfig = null;
|
|
50761
51092
|
try {
|
|
50762
|
-
const configContent = await
|
|
51093
|
+
const configContent = await readFile5(paths.config, "utf-8");
|
|
50763
51094
|
existingConfig = JSON.parse(configContent);
|
|
50764
51095
|
} catch {
|
|
50765
51096
|
}
|
|
@@ -50779,7 +51110,7 @@ async function resetToDefaults(cwd, paths, shadcn, isAgentMode2) {
|
|
|
50779
51110
|
};
|
|
50780
51111
|
await mkdir3(paths.output, { recursive: true });
|
|
50781
51112
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
50782
|
-
const backupPath =
|
|
51113
|
+
const backupPath = join9(paths.output, `reset-${timestamp}.json`);
|
|
50783
51114
|
await writeFile3(backupPath, JSON.stringify(backup, null, 2));
|
|
50784
51115
|
log({
|
|
50785
51116
|
event: "init:reset_backup",
|
|
@@ -50867,9 +51198,9 @@ async function init(options) {
|
|
|
50867
51198
|
}
|
|
50868
51199
|
let existingColors = null;
|
|
50869
51200
|
if (shadcn?.tailwind?.css) {
|
|
50870
|
-
const cssPath =
|
|
51201
|
+
const cssPath = join9(cwd, shadcn.tailwind.css);
|
|
50871
51202
|
try {
|
|
50872
|
-
const cssContent = await
|
|
51203
|
+
const cssContent = await readFile5(cssPath, "utf-8");
|
|
50873
51204
|
existingColors = parseCssVariables(cssContent);
|
|
50874
51205
|
const backupPath = await backupCss(cssPath);
|
|
50875
51206
|
log({
|
|
@@ -50975,7 +51306,11 @@ async function init(options) {
|
|
|
50975
51306
|
primitivesPath: frameworkPaths.primitives,
|
|
50976
51307
|
cssPath: detectedCssPath,
|
|
50977
51308
|
shadcn: !!shadcn,
|
|
50978
|
-
exports
|
|
51309
|
+
exports,
|
|
51310
|
+
installed: {
|
|
51311
|
+
components: [],
|
|
51312
|
+
primitives: []
|
|
51313
|
+
}
|
|
50979
51314
|
};
|
|
50980
51315
|
await writeFile3(paths.config, JSON.stringify(config3, null, 2));
|
|
50981
51316
|
log({
|
|
@@ -50991,8 +51326,916 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
50991
51326
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
50992
51327
|
|
|
50993
51328
|
// src/mcp/tools.ts
|
|
50994
|
-
import {
|
|
50995
|
-
import {
|
|
51329
|
+
import { existsSync as existsSync3 } from "fs";
|
|
51330
|
+
import { readdir as readdir3, readFile as readFile6 } from "fs/promises";
|
|
51331
|
+
import { basename, join as join10 } from "path";
|
|
51332
|
+
|
|
51333
|
+
// src/mcp/cognitive-load.ts
|
|
51334
|
+
var BUDGET_TIERS = {
|
|
51335
|
+
focused: 15,
|
|
51336
|
+
page: 30,
|
|
51337
|
+
app: 45
|
|
51338
|
+
};
|
|
51339
|
+
var COMPONENT_SCORES = {
|
|
51340
|
+
// Score 0 -- Structural only, no cognitive demand
|
|
51341
|
+
separator: {
|
|
51342
|
+
dimensions: {
|
|
51343
|
+
decisionDemand: 0,
|
|
51344
|
+
informationDensity: 0,
|
|
51345
|
+
interactionComplexity: 0,
|
|
51346
|
+
contextDisruption: 0,
|
|
51347
|
+
learningCurve: 0
|
|
51348
|
+
},
|
|
51349
|
+
primaryCostDriver: "Structural only, no cognitive demand"
|
|
51350
|
+
},
|
|
51351
|
+
container: {
|
|
51352
|
+
dimensions: {
|
|
51353
|
+
decisionDemand: 0,
|
|
51354
|
+
informationDensity: 0,
|
|
51355
|
+
interactionComplexity: 0,
|
|
51356
|
+
contextDisruption: 0,
|
|
51357
|
+
learningCurve: 0
|
|
51358
|
+
},
|
|
51359
|
+
primaryCostDriver: "Structural only, no cognitive demand"
|
|
51360
|
+
},
|
|
51361
|
+
"aspect-ratio": {
|
|
51362
|
+
dimensions: {
|
|
51363
|
+
decisionDemand: 0,
|
|
51364
|
+
informationDensity: 0,
|
|
51365
|
+
interactionComplexity: 0,
|
|
51366
|
+
contextDisruption: 0,
|
|
51367
|
+
learningCurve: 0
|
|
51368
|
+
},
|
|
51369
|
+
primaryCostDriver: "Structural only, no cognitive demand"
|
|
51370
|
+
},
|
|
51371
|
+
// Score 1 -- Display only, minimal information
|
|
51372
|
+
skeleton: {
|
|
51373
|
+
dimensions: {
|
|
51374
|
+
decisionDemand: 0,
|
|
51375
|
+
informationDensity: 1,
|
|
51376
|
+
interactionComplexity: 0,
|
|
51377
|
+
contextDisruption: 0,
|
|
51378
|
+
learningCurve: 0
|
|
51379
|
+
},
|
|
51380
|
+
primaryCostDriver: "Display only, minimal information"
|
|
51381
|
+
},
|
|
51382
|
+
kbd: {
|
|
51383
|
+
dimensions: {
|
|
51384
|
+
decisionDemand: 0,
|
|
51385
|
+
informationDensity: 1,
|
|
51386
|
+
interactionComplexity: 0,
|
|
51387
|
+
contextDisruption: 0,
|
|
51388
|
+
learningCurve: 0
|
|
51389
|
+
},
|
|
51390
|
+
primaryCostDriver: "Display only, minimal information"
|
|
51391
|
+
},
|
|
51392
|
+
// Score 2 -- Simple state or single information piece
|
|
51393
|
+
badge: {
|
|
51394
|
+
dimensions: {
|
|
51395
|
+
decisionDemand: 0,
|
|
51396
|
+
informationDensity: 1,
|
|
51397
|
+
interactionComplexity: 0,
|
|
51398
|
+
contextDisruption: 0,
|
|
51399
|
+
learningCurve: 1
|
|
51400
|
+
},
|
|
51401
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51402
|
+
},
|
|
51403
|
+
breadcrumb: {
|
|
51404
|
+
dimensions: {
|
|
51405
|
+
decisionDemand: 0,
|
|
51406
|
+
informationDensity: 1,
|
|
51407
|
+
interactionComplexity: 1,
|
|
51408
|
+
contextDisruption: 0,
|
|
51409
|
+
learningCurve: 0
|
|
51410
|
+
},
|
|
51411
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51412
|
+
},
|
|
51413
|
+
label: {
|
|
51414
|
+
dimensions: {
|
|
51415
|
+
decisionDemand: 0,
|
|
51416
|
+
informationDensity: 1,
|
|
51417
|
+
interactionComplexity: 0,
|
|
51418
|
+
contextDisruption: 0,
|
|
51419
|
+
learningCurve: 1
|
|
51420
|
+
},
|
|
51421
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51422
|
+
},
|
|
51423
|
+
checkbox: {
|
|
51424
|
+
dimensions: {
|
|
51425
|
+
decisionDemand: 1,
|
|
51426
|
+
informationDensity: 0,
|
|
51427
|
+
interactionComplexity: 1,
|
|
51428
|
+
contextDisruption: 0,
|
|
51429
|
+
learningCurve: 0
|
|
51430
|
+
},
|
|
51431
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51432
|
+
},
|
|
51433
|
+
switch: {
|
|
51434
|
+
dimensions: {
|
|
51435
|
+
decisionDemand: 1,
|
|
51436
|
+
informationDensity: 0,
|
|
51437
|
+
interactionComplexity: 1,
|
|
51438
|
+
contextDisruption: 0,
|
|
51439
|
+
learningCurve: 0
|
|
51440
|
+
},
|
|
51441
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51442
|
+
},
|
|
51443
|
+
toggle: {
|
|
51444
|
+
dimensions: {
|
|
51445
|
+
decisionDemand: 1,
|
|
51446
|
+
informationDensity: 0,
|
|
51447
|
+
interactionComplexity: 1,
|
|
51448
|
+
contextDisruption: 0,
|
|
51449
|
+
learningCurve: 0
|
|
51450
|
+
},
|
|
51451
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51452
|
+
},
|
|
51453
|
+
"button-group": {
|
|
51454
|
+
dimensions: {
|
|
51455
|
+
decisionDemand: 1,
|
|
51456
|
+
informationDensity: 1,
|
|
51457
|
+
interactionComplexity: 0,
|
|
51458
|
+
contextDisruption: 0,
|
|
51459
|
+
learningCurve: 0
|
|
51460
|
+
},
|
|
51461
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51462
|
+
},
|
|
51463
|
+
card: {
|
|
51464
|
+
dimensions: {
|
|
51465
|
+
decisionDemand: 0,
|
|
51466
|
+
informationDensity: 1,
|
|
51467
|
+
interactionComplexity: 0,
|
|
51468
|
+
contextDisruption: 0,
|
|
51469
|
+
learningCurve: 1
|
|
51470
|
+
},
|
|
51471
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51472
|
+
},
|
|
51473
|
+
collapsible: {
|
|
51474
|
+
dimensions: {
|
|
51475
|
+
decisionDemand: 1,
|
|
51476
|
+
informationDensity: 0,
|
|
51477
|
+
interactionComplexity: 1,
|
|
51478
|
+
contextDisruption: 0,
|
|
51479
|
+
learningCurve: 0
|
|
51480
|
+
},
|
|
51481
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51482
|
+
},
|
|
51483
|
+
avatar: {
|
|
51484
|
+
dimensions: {
|
|
51485
|
+
decisionDemand: 0,
|
|
51486
|
+
informationDensity: 1,
|
|
51487
|
+
interactionComplexity: 0,
|
|
51488
|
+
contextDisruption: 0,
|
|
51489
|
+
learningCurve: 1
|
|
51490
|
+
},
|
|
51491
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51492
|
+
},
|
|
51493
|
+
"scroll-area": {
|
|
51494
|
+
dimensions: {
|
|
51495
|
+
decisionDemand: 0,
|
|
51496
|
+
informationDensity: 1,
|
|
51497
|
+
interactionComplexity: 1,
|
|
51498
|
+
contextDisruption: 0,
|
|
51499
|
+
learningCurve: 0
|
|
51500
|
+
},
|
|
51501
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51502
|
+
},
|
|
51503
|
+
tooltip: {
|
|
51504
|
+
dimensions: {
|
|
51505
|
+
decisionDemand: 0,
|
|
51506
|
+
informationDensity: 1,
|
|
51507
|
+
interactionComplexity: 0,
|
|
51508
|
+
contextDisruption: 0,
|
|
51509
|
+
learningCurve: 1
|
|
51510
|
+
},
|
|
51511
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51512
|
+
},
|
|
51513
|
+
typography: {
|
|
51514
|
+
dimensions: {
|
|
51515
|
+
decisionDemand: 0,
|
|
51516
|
+
informationDensity: 1,
|
|
51517
|
+
interactionComplexity: 0,
|
|
51518
|
+
contextDisruption: 0,
|
|
51519
|
+
learningCurve: 1
|
|
51520
|
+
},
|
|
51521
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51522
|
+
},
|
|
51523
|
+
spinner: {
|
|
51524
|
+
dimensions: {
|
|
51525
|
+
decisionDemand: 0,
|
|
51526
|
+
informationDensity: 1,
|
|
51527
|
+
interactionComplexity: 0,
|
|
51528
|
+
contextDisruption: 0,
|
|
51529
|
+
learningCurve: 1
|
|
51530
|
+
},
|
|
51531
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51532
|
+
},
|
|
51533
|
+
empty: {
|
|
51534
|
+
dimensions: {
|
|
51535
|
+
decisionDemand: 1,
|
|
51536
|
+
informationDensity: 1,
|
|
51537
|
+
interactionComplexity: 0,
|
|
51538
|
+
contextDisruption: 0,
|
|
51539
|
+
learningCurve: 0
|
|
51540
|
+
},
|
|
51541
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51542
|
+
},
|
|
51543
|
+
"toggle-group": {
|
|
51544
|
+
dimensions: {
|
|
51545
|
+
decisionDemand: 1,
|
|
51546
|
+
informationDensity: 1,
|
|
51547
|
+
interactionComplexity: 0,
|
|
51548
|
+
contextDisruption: 0,
|
|
51549
|
+
learningCurve: 0
|
|
51550
|
+
},
|
|
51551
|
+
primaryCostDriver: "Simple state or single information piece"
|
|
51552
|
+
},
|
|
51553
|
+
// Score 3 -- One decision + one interaction mode
|
|
51554
|
+
button: {
|
|
51555
|
+
dimensions: {
|
|
51556
|
+
decisionDemand: 1,
|
|
51557
|
+
informationDensity: 1,
|
|
51558
|
+
interactionComplexity: 1,
|
|
51559
|
+
contextDisruption: 0,
|
|
51560
|
+
learningCurve: 0
|
|
51561
|
+
},
|
|
51562
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51563
|
+
},
|
|
51564
|
+
alert: {
|
|
51565
|
+
dimensions: {
|
|
51566
|
+
decisionDemand: 0,
|
|
51567
|
+
informationDensity: 1,
|
|
51568
|
+
interactionComplexity: 1,
|
|
51569
|
+
contextDisruption: 0,
|
|
51570
|
+
learningCurve: 1
|
|
51571
|
+
},
|
|
51572
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51573
|
+
},
|
|
51574
|
+
sidebar: {
|
|
51575
|
+
dimensions: {
|
|
51576
|
+
decisionDemand: 1,
|
|
51577
|
+
informationDensity: 1,
|
|
51578
|
+
interactionComplexity: 1,
|
|
51579
|
+
contextDisruption: 0,
|
|
51580
|
+
learningCurve: 0
|
|
51581
|
+
},
|
|
51582
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51583
|
+
},
|
|
51584
|
+
accordion: {
|
|
51585
|
+
dimensions: {
|
|
51586
|
+
decisionDemand: 1,
|
|
51587
|
+
informationDensity: 1,
|
|
51588
|
+
interactionComplexity: 0,
|
|
51589
|
+
contextDisruption: 0,
|
|
51590
|
+
learningCurve: 1
|
|
51591
|
+
},
|
|
51592
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51593
|
+
},
|
|
51594
|
+
slider: {
|
|
51595
|
+
dimensions: {
|
|
51596
|
+
decisionDemand: 1,
|
|
51597
|
+
informationDensity: 0,
|
|
51598
|
+
interactionComplexity: 1,
|
|
51599
|
+
contextDisruption: 0,
|
|
51600
|
+
learningCurve: 1
|
|
51601
|
+
},
|
|
51602
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51603
|
+
},
|
|
51604
|
+
"radio-group": {
|
|
51605
|
+
dimensions: {
|
|
51606
|
+
decisionDemand: 1,
|
|
51607
|
+
informationDensity: 1,
|
|
51608
|
+
interactionComplexity: 1,
|
|
51609
|
+
contextDisruption: 0,
|
|
51610
|
+
learningCurve: 0
|
|
51611
|
+
},
|
|
51612
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51613
|
+
},
|
|
51614
|
+
table: {
|
|
51615
|
+
dimensions: {
|
|
51616
|
+
decisionDemand: 0,
|
|
51617
|
+
informationDensity: 2,
|
|
51618
|
+
interactionComplexity: 0,
|
|
51619
|
+
contextDisruption: 0,
|
|
51620
|
+
learningCurve: 1
|
|
51621
|
+
},
|
|
51622
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51623
|
+
},
|
|
51624
|
+
resizable: {
|
|
51625
|
+
dimensions: {
|
|
51626
|
+
decisionDemand: 1,
|
|
51627
|
+
informationDensity: 0,
|
|
51628
|
+
interactionComplexity: 1,
|
|
51629
|
+
contextDisruption: 0,
|
|
51630
|
+
learningCurve: 1
|
|
51631
|
+
},
|
|
51632
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51633
|
+
},
|
|
51634
|
+
field: {
|
|
51635
|
+
dimensions: {
|
|
51636
|
+
decisionDemand: 1,
|
|
51637
|
+
informationDensity: 1,
|
|
51638
|
+
interactionComplexity: 1,
|
|
51639
|
+
contextDisruption: 0,
|
|
51640
|
+
learningCurve: 0
|
|
51641
|
+
},
|
|
51642
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51643
|
+
},
|
|
51644
|
+
"hover-card": {
|
|
51645
|
+
dimensions: {
|
|
51646
|
+
decisionDemand: 0,
|
|
51647
|
+
informationDensity: 1,
|
|
51648
|
+
interactionComplexity: 0,
|
|
51649
|
+
contextDisruption: 1,
|
|
51650
|
+
learningCurve: 1
|
|
51651
|
+
},
|
|
51652
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51653
|
+
},
|
|
51654
|
+
image: {
|
|
51655
|
+
dimensions: {
|
|
51656
|
+
decisionDemand: 0,
|
|
51657
|
+
informationDensity: 2,
|
|
51658
|
+
interactionComplexity: 0,
|
|
51659
|
+
contextDisruption: 0,
|
|
51660
|
+
learningCurve: 1
|
|
51661
|
+
},
|
|
51662
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51663
|
+
},
|
|
51664
|
+
embed: {
|
|
51665
|
+
dimensions: {
|
|
51666
|
+
decisionDemand: 0,
|
|
51667
|
+
informationDensity: 2,
|
|
51668
|
+
interactionComplexity: 0,
|
|
51669
|
+
contextDisruption: 0,
|
|
51670
|
+
learningCurve: 1
|
|
51671
|
+
},
|
|
51672
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51673
|
+
},
|
|
51674
|
+
item: {
|
|
51675
|
+
dimensions: {
|
|
51676
|
+
decisionDemand: 1,
|
|
51677
|
+
informationDensity: 1,
|
|
51678
|
+
interactionComplexity: 1,
|
|
51679
|
+
contextDisruption: 0,
|
|
51680
|
+
learningCurve: 0
|
|
51681
|
+
},
|
|
51682
|
+
primaryCostDriver: "One decision + one interaction mode"
|
|
51683
|
+
},
|
|
51684
|
+
// Score 4 -- Data entry or menu scanning
|
|
51685
|
+
input: {
|
|
51686
|
+
dimensions: {
|
|
51687
|
+
decisionDemand: 1,
|
|
51688
|
+
informationDensity: 1,
|
|
51689
|
+
interactionComplexity: 1,
|
|
51690
|
+
contextDisruption: 0,
|
|
51691
|
+
learningCurve: 1
|
|
51692
|
+
},
|
|
51693
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51694
|
+
},
|
|
51695
|
+
textarea: {
|
|
51696
|
+
dimensions: {
|
|
51697
|
+
decisionDemand: 1,
|
|
51698
|
+
informationDensity: 1,
|
|
51699
|
+
interactionComplexity: 1,
|
|
51700
|
+
contextDisruption: 0,
|
|
51701
|
+
learningCurve: 1
|
|
51702
|
+
},
|
|
51703
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51704
|
+
},
|
|
51705
|
+
"input-group": {
|
|
51706
|
+
dimensions: {
|
|
51707
|
+
decisionDemand: 1,
|
|
51708
|
+
informationDensity: 1,
|
|
51709
|
+
interactionComplexity: 1,
|
|
51710
|
+
contextDisruption: 0,
|
|
51711
|
+
learningCurve: 1
|
|
51712
|
+
},
|
|
51713
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51714
|
+
},
|
|
51715
|
+
"input-otp": {
|
|
51716
|
+
dimensions: {
|
|
51717
|
+
decisionDemand: 1,
|
|
51718
|
+
informationDensity: 1,
|
|
51719
|
+
interactionComplexity: 1,
|
|
51720
|
+
contextDisruption: 0,
|
|
51721
|
+
learningCurve: 1
|
|
51722
|
+
},
|
|
51723
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51724
|
+
},
|
|
51725
|
+
carousel: {
|
|
51726
|
+
dimensions: {
|
|
51727
|
+
decisionDemand: 1,
|
|
51728
|
+
informationDensity: 1,
|
|
51729
|
+
interactionComplexity: 1,
|
|
51730
|
+
contextDisruption: 0,
|
|
51731
|
+
learningCurve: 1
|
|
51732
|
+
},
|
|
51733
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51734
|
+
},
|
|
51735
|
+
tabs: {
|
|
51736
|
+
dimensions: {
|
|
51737
|
+
decisionDemand: 1,
|
|
51738
|
+
informationDensity: 1,
|
|
51739
|
+
interactionComplexity: 1,
|
|
51740
|
+
contextDisruption: 0,
|
|
51741
|
+
learningCurve: 1
|
|
51742
|
+
},
|
|
51743
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51744
|
+
},
|
|
51745
|
+
"context-menu": {
|
|
51746
|
+
dimensions: {
|
|
51747
|
+
decisionDemand: 1,
|
|
51748
|
+
informationDensity: 1,
|
|
51749
|
+
interactionComplexity: 1,
|
|
51750
|
+
contextDisruption: 0,
|
|
51751
|
+
learningCurve: 1
|
|
51752
|
+
},
|
|
51753
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51754
|
+
},
|
|
51755
|
+
"dropdown-menu": {
|
|
51756
|
+
dimensions: {
|
|
51757
|
+
decisionDemand: 1,
|
|
51758
|
+
informationDensity: 1,
|
|
51759
|
+
interactionComplexity: 1,
|
|
51760
|
+
contextDisruption: 0,
|
|
51761
|
+
learningCurve: 1
|
|
51762
|
+
},
|
|
51763
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51764
|
+
},
|
|
51765
|
+
popover: {
|
|
51766
|
+
dimensions: {
|
|
51767
|
+
decisionDemand: 0,
|
|
51768
|
+
informationDensity: 1,
|
|
51769
|
+
interactionComplexity: 1,
|
|
51770
|
+
contextDisruption: 1,
|
|
51771
|
+
learningCurve: 1
|
|
51772
|
+
},
|
|
51773
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51774
|
+
},
|
|
51775
|
+
progress: {
|
|
51776
|
+
dimensions: {
|
|
51777
|
+
decisionDemand: 0,
|
|
51778
|
+
informationDensity: 2,
|
|
51779
|
+
interactionComplexity: 0,
|
|
51780
|
+
contextDisruption: 1,
|
|
51781
|
+
learningCurve: 1
|
|
51782
|
+
},
|
|
51783
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51784
|
+
},
|
|
51785
|
+
drawer: {
|
|
51786
|
+
dimensions: {
|
|
51787
|
+
decisionDemand: 1,
|
|
51788
|
+
informationDensity: 1,
|
|
51789
|
+
interactionComplexity: 1,
|
|
51790
|
+
contextDisruption: 1,
|
|
51791
|
+
learningCurve: 0
|
|
51792
|
+
},
|
|
51793
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51794
|
+
},
|
|
51795
|
+
grid: {
|
|
51796
|
+
dimensions: {
|
|
51797
|
+
decisionDemand: 0,
|
|
51798
|
+
informationDensity: 2,
|
|
51799
|
+
interactionComplexity: 0,
|
|
51800
|
+
contextDisruption: 0,
|
|
51801
|
+
learningCurve: 2
|
|
51802
|
+
},
|
|
51803
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51804
|
+
},
|
|
51805
|
+
"block-wrapper": {
|
|
51806
|
+
dimensions: {
|
|
51807
|
+
decisionDemand: 1,
|
|
51808
|
+
informationDensity: 1,
|
|
51809
|
+
interactionComplexity: 1,
|
|
51810
|
+
contextDisruption: 0,
|
|
51811
|
+
learningCurve: 1
|
|
51812
|
+
},
|
|
51813
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51814
|
+
},
|
|
51815
|
+
"inline-toolbar": {
|
|
51816
|
+
dimensions: {
|
|
51817
|
+
decisionDemand: 1,
|
|
51818
|
+
informationDensity: 1,
|
|
51819
|
+
interactionComplexity: 1,
|
|
51820
|
+
contextDisruption: 0,
|
|
51821
|
+
learningCurve: 1
|
|
51822
|
+
},
|
|
51823
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51824
|
+
},
|
|
51825
|
+
"editor-toolbar": {
|
|
51826
|
+
dimensions: {
|
|
51827
|
+
decisionDemand: 1,
|
|
51828
|
+
informationDensity: 1,
|
|
51829
|
+
interactionComplexity: 1,
|
|
51830
|
+
contextDisruption: 0,
|
|
51831
|
+
learningCurve: 1
|
|
51832
|
+
},
|
|
51833
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51834
|
+
},
|
|
51835
|
+
pagination: {
|
|
51836
|
+
dimensions: {
|
|
51837
|
+
decisionDemand: 1,
|
|
51838
|
+
informationDensity: 1,
|
|
51839
|
+
interactionComplexity: 1,
|
|
51840
|
+
contextDisruption: 0,
|
|
51841
|
+
learningCurve: 1
|
|
51842
|
+
},
|
|
51843
|
+
primaryCostDriver: "Data entry or menu scanning"
|
|
51844
|
+
},
|
|
51845
|
+
// Score 5 -- Multi-step interaction or spatial reasoning
|
|
51846
|
+
sheet: {
|
|
51847
|
+
dimensions: {
|
|
51848
|
+
decisionDemand: 1,
|
|
51849
|
+
informationDensity: 1,
|
|
51850
|
+
interactionComplexity: 1,
|
|
51851
|
+
contextDisruption: 1,
|
|
51852
|
+
learningCurve: 1
|
|
51853
|
+
},
|
|
51854
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51855
|
+
},
|
|
51856
|
+
"date-picker": {
|
|
51857
|
+
dimensions: {
|
|
51858
|
+
decisionDemand: 1,
|
|
51859
|
+
informationDensity: 1,
|
|
51860
|
+
interactionComplexity: 2,
|
|
51861
|
+
contextDisruption: 0,
|
|
51862
|
+
learningCurve: 1
|
|
51863
|
+
},
|
|
51864
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51865
|
+
},
|
|
51866
|
+
calendar: {
|
|
51867
|
+
dimensions: {
|
|
51868
|
+
decisionDemand: 1,
|
|
51869
|
+
informationDensity: 2,
|
|
51870
|
+
interactionComplexity: 1,
|
|
51871
|
+
contextDisruption: 0,
|
|
51872
|
+
learningCurve: 1
|
|
51873
|
+
},
|
|
51874
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51875
|
+
},
|
|
51876
|
+
select: {
|
|
51877
|
+
dimensions: {
|
|
51878
|
+
decisionDemand: 2,
|
|
51879
|
+
informationDensity: 1,
|
|
51880
|
+
interactionComplexity: 1,
|
|
51881
|
+
contextDisruption: 0,
|
|
51882
|
+
learningCurve: 1
|
|
51883
|
+
},
|
|
51884
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51885
|
+
},
|
|
51886
|
+
"navigation-menu": {
|
|
51887
|
+
dimensions: {
|
|
51888
|
+
decisionDemand: 1,
|
|
51889
|
+
informationDensity: 2,
|
|
51890
|
+
interactionComplexity: 1,
|
|
51891
|
+
contextDisruption: 0,
|
|
51892
|
+
learningCurve: 1
|
|
51893
|
+
},
|
|
51894
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51895
|
+
},
|
|
51896
|
+
menubar: {
|
|
51897
|
+
dimensions: {
|
|
51898
|
+
decisionDemand: 1,
|
|
51899
|
+
informationDensity: 2,
|
|
51900
|
+
interactionComplexity: 1,
|
|
51901
|
+
contextDisruption: 0,
|
|
51902
|
+
learningCurve: 1
|
|
51903
|
+
},
|
|
51904
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51905
|
+
},
|
|
51906
|
+
"color-picker": {
|
|
51907
|
+
dimensions: {
|
|
51908
|
+
decisionDemand: 1,
|
|
51909
|
+
informationDensity: 1,
|
|
51910
|
+
interactionComplexity: 2,
|
|
51911
|
+
contextDisruption: 0,
|
|
51912
|
+
learningCurve: 1
|
|
51913
|
+
},
|
|
51914
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51915
|
+
},
|
|
51916
|
+
"block-canvas": {
|
|
51917
|
+
dimensions: {
|
|
51918
|
+
decisionDemand: 1,
|
|
51919
|
+
informationDensity: 1,
|
|
51920
|
+
interactionComplexity: 1,
|
|
51921
|
+
contextDisruption: 1,
|
|
51922
|
+
learningCurve: 1
|
|
51923
|
+
},
|
|
51924
|
+
primaryCostDriver: "Multi-step interaction or spatial reasoning"
|
|
51925
|
+
},
|
|
51926
|
+
// Score 6 -- Compound interaction modes or learning curve
|
|
51927
|
+
dialog: {
|
|
51928
|
+
dimensions: {
|
|
51929
|
+
decisionDemand: 1,
|
|
51930
|
+
informationDensity: 1,
|
|
51931
|
+
interactionComplexity: 1,
|
|
51932
|
+
contextDisruption: 2,
|
|
51933
|
+
learningCurve: 1
|
|
51934
|
+
},
|
|
51935
|
+
primaryCostDriver: "Compound interaction modes or learning curve"
|
|
51936
|
+
},
|
|
51937
|
+
command: {
|
|
51938
|
+
dimensions: {
|
|
51939
|
+
decisionDemand: 1,
|
|
51940
|
+
informationDensity: 2,
|
|
51941
|
+
interactionComplexity: 1,
|
|
51942
|
+
contextDisruption: 0,
|
|
51943
|
+
learningCurve: 2
|
|
51944
|
+
},
|
|
51945
|
+
primaryCostDriver: "Compound interaction modes or learning curve"
|
|
51946
|
+
},
|
|
51947
|
+
combobox: {
|
|
51948
|
+
dimensions: {
|
|
51949
|
+
decisionDemand: 2,
|
|
51950
|
+
informationDensity: 2,
|
|
51951
|
+
interactionComplexity: 2,
|
|
51952
|
+
contextDisruption: 0,
|
|
51953
|
+
learningCurve: 0
|
|
51954
|
+
},
|
|
51955
|
+
primaryCostDriver: "Compound interaction modes or learning curve"
|
|
51956
|
+
},
|
|
51957
|
+
// Score 7 -- Full context disruption + consequential decision
|
|
51958
|
+
"alert-dialog": {
|
|
51959
|
+
dimensions: {
|
|
51960
|
+
decisionDemand: 2,
|
|
51961
|
+
informationDensity: 1,
|
|
51962
|
+
interactionComplexity: 1,
|
|
51963
|
+
contextDisruption: 2,
|
|
51964
|
+
learningCurve: 1
|
|
51965
|
+
},
|
|
51966
|
+
primaryCostDriver: "Full context disruption + consequential decision"
|
|
51967
|
+
}
|
|
51968
|
+
};
|
|
51969
|
+
var DIMENSION_NAMES = {
|
|
51970
|
+
decisionDemand: "Decision Demand",
|
|
51971
|
+
informationDensity: "Information Density",
|
|
51972
|
+
interactionComplexity: "Interaction Complexity",
|
|
51973
|
+
contextDisruption: "Context Disruption",
|
|
51974
|
+
learningCurve: "Learning Curve"
|
|
51975
|
+
};
|
|
51976
|
+
var HOTSPOT_SUGGESTIONS = {
|
|
51977
|
+
contextDisruption: "Consider non-modal alternative if the decision is not consequential",
|
|
51978
|
+
informationDensity: "Consider progressive disclosure to reduce simultaneous information",
|
|
51979
|
+
interactionComplexity: "Consider a simpler single-mode alternative",
|
|
51980
|
+
decisionDemand: "Can choices be pre-selected or split across steps?",
|
|
51981
|
+
learningCurve: "Ensure discoverability with inline guidance"
|
|
51982
|
+
};
|
|
51983
|
+
function scoreOf(dimensions) {
|
|
51984
|
+
return dimensions.decisionDemand + dimensions.informationDensity + dimensions.interactionComplexity + dimensions.contextDisruption + dimensions.learningCurve;
|
|
51985
|
+
}
|
|
51986
|
+
function highestDimension(dimensions) {
|
|
51987
|
+
let max = -1;
|
|
51988
|
+
let maxKey = "decisionDemand";
|
|
51989
|
+
for (const key of Object.keys(dimensions)) {
|
|
51990
|
+
if (dimensions[key] > max) {
|
|
51991
|
+
max = dimensions[key];
|
|
51992
|
+
maxKey = key;
|
|
51993
|
+
}
|
|
51994
|
+
}
|
|
51995
|
+
return maxKey;
|
|
51996
|
+
}
|
|
51997
|
+
function evaluateComposition(components, tier, enrichment) {
|
|
51998
|
+
const budget = BUDGET_TIERS[tier];
|
|
51999
|
+
const componentCounts = /* @__PURE__ */ new Map();
|
|
52000
|
+
for (const name2 of components) {
|
|
52001
|
+
componentCounts.set(name2, (componentCounts.get(name2) ?? 0) + 1);
|
|
52002
|
+
}
|
|
52003
|
+
let total = 0;
|
|
52004
|
+
const componentResults = [];
|
|
52005
|
+
const unknownComponents = [];
|
|
52006
|
+
for (const [name2, count] of componentCounts) {
|
|
52007
|
+
const profile = COMPONENT_SCORES[name2];
|
|
52008
|
+
if (!profile) {
|
|
52009
|
+
unknownComponents.push(name2);
|
|
52010
|
+
continue;
|
|
52011
|
+
}
|
|
52012
|
+
const score = scoreOf(profile.dimensions);
|
|
52013
|
+
total += score * count;
|
|
52014
|
+
componentResults.push({
|
|
52015
|
+
name: name2,
|
|
52016
|
+
score,
|
|
52017
|
+
count,
|
|
52018
|
+
dimensions: profile.dimensions,
|
|
52019
|
+
primaryCostDriver: profile.primaryCostDriver
|
|
52020
|
+
});
|
|
52021
|
+
}
|
|
52022
|
+
componentResults.sort((a, b) => b.score - a.score);
|
|
52023
|
+
const withinBudget = total <= budget;
|
|
52024
|
+
const budgetResult = {
|
|
52025
|
+
tier,
|
|
52026
|
+
budget,
|
|
52027
|
+
total,
|
|
52028
|
+
status: withinBudget ? "within-budget" : "over-budget"
|
|
52029
|
+
};
|
|
52030
|
+
if (withinBudget) {
|
|
52031
|
+
budgetResult.headroom = budget - total;
|
|
52032
|
+
} else {
|
|
52033
|
+
budgetResult.overage = total - budget;
|
|
52034
|
+
budgetResult.overagePercent = Math.round((total - budget) / budget * 100);
|
|
52035
|
+
}
|
|
52036
|
+
const attentionConflicts = [];
|
|
52037
|
+
const attentionNotes = [];
|
|
52038
|
+
const fullAttentionCaptures = [];
|
|
52039
|
+
const primaryElements = [];
|
|
52040
|
+
for (const [name2] of componentCounts) {
|
|
52041
|
+
const metadata = enrichment.componentIntelligence.get(name2);
|
|
52042
|
+
if (!metadata?.intelligence?.attentionEconomics) continue;
|
|
52043
|
+
const attn = metadata.intelligence.attentionEconomics.toLowerCase();
|
|
52044
|
+
if (attn.includes("full attention capture") || attn.includes("blocks all other")) {
|
|
52045
|
+
fullAttentionCaptures.push(name2);
|
|
52046
|
+
}
|
|
52047
|
+
if (attn.includes("primary") && attn.includes("maximum 1")) {
|
|
52048
|
+
const count = componentCounts.get(name2) ?? 0;
|
|
52049
|
+
if (count > 1) {
|
|
52050
|
+
primaryElements.push(name2);
|
|
52051
|
+
}
|
|
52052
|
+
}
|
|
52053
|
+
}
|
|
52054
|
+
if (fullAttentionCaptures.length > 1) {
|
|
52055
|
+
attentionConflicts.push(`${fullAttentionCaptures.join(" and ")} both capture full attention`);
|
|
52056
|
+
}
|
|
52057
|
+
const buttonCount = componentCounts.get("button") ?? 0;
|
|
52058
|
+
if (buttonCount > 1) {
|
|
52059
|
+
const buttonMeta = enrichment.componentIntelligence.get("button");
|
|
52060
|
+
if (buttonMeta?.intelligence?.attentionEconomics?.toLowerCase().includes("maximum 1 per section")) {
|
|
52061
|
+
attentionNotes.push(`${buttonCount} buttons present -- ensure maximum 1 primary per section`);
|
|
52062
|
+
}
|
|
52063
|
+
}
|
|
52064
|
+
if (primaryElements.length > 0) {
|
|
52065
|
+
for (const name2 of primaryElements) {
|
|
52066
|
+
attentionNotes.push(`Multiple ${name2} instances -- check attention hierarchy`);
|
|
52067
|
+
}
|
|
52068
|
+
}
|
|
52069
|
+
const trustConsiderations = [];
|
|
52070
|
+
for (const [name2] of componentCounts) {
|
|
52071
|
+
const metadata = enrichment.componentIntelligence.get(name2);
|
|
52072
|
+
if (!metadata?.intelligence?.trustBuilding) continue;
|
|
52073
|
+
const trust = metadata.intelligence.trustBuilding;
|
|
52074
|
+
if (trust.toLowerCase().includes("confirmation") || trust.toLowerCase().includes("destructive") || trust.toLowerCase().includes("consequence") || trust.toLowerCase().includes("cancel")) {
|
|
52075
|
+
trustConsiderations.push(`${name2}: ${trust}`);
|
|
52076
|
+
}
|
|
52077
|
+
}
|
|
52078
|
+
const patternMatches = [];
|
|
52079
|
+
const compositionSet = new Set(componentCounts.keys());
|
|
52080
|
+
for (const [patternKey, pattern] of Object.entries(enrichment.patterns)) {
|
|
52081
|
+
const matched = pattern.components.filter((c) => compositionSet.has(c));
|
|
52082
|
+
if (matched.length >= 2 || matched.length === pattern.components.length) {
|
|
52083
|
+
patternMatches.push({
|
|
52084
|
+
name: pattern.name,
|
|
52085
|
+
matched,
|
|
52086
|
+
suggestion: `Call rafters_pattern('${patternKey}') for full guidance`
|
|
52087
|
+
});
|
|
52088
|
+
}
|
|
52089
|
+
}
|
|
52090
|
+
const designerNotes = [];
|
|
52091
|
+
const compositionNames = [...compositionSet];
|
|
52092
|
+
for (const { token } of enrichment.tokenOverrides) {
|
|
52093
|
+
if (!token.userOverride) continue;
|
|
52094
|
+
const relevantTo = [];
|
|
52095
|
+
if (token.applicableComponents) {
|
|
52096
|
+
for (const comp of token.applicableComponents) {
|
|
52097
|
+
if (compositionSet.has(comp)) {
|
|
52098
|
+
relevantTo.push(comp);
|
|
52099
|
+
}
|
|
52100
|
+
}
|
|
52101
|
+
}
|
|
52102
|
+
if (relevantTo.length === 0) {
|
|
52103
|
+
if (token.namespace === "spacing") {
|
|
52104
|
+
const formComponents = compositionNames.filter(
|
|
52105
|
+
(n) => [
|
|
52106
|
+
"input",
|
|
52107
|
+
"textarea",
|
|
52108
|
+
"field",
|
|
52109
|
+
"label",
|
|
52110
|
+
"button",
|
|
52111
|
+
"select",
|
|
52112
|
+
"checkbox",
|
|
52113
|
+
"radio-group",
|
|
52114
|
+
"switch",
|
|
52115
|
+
"slider",
|
|
52116
|
+
"combobox"
|
|
52117
|
+
].includes(n)
|
|
52118
|
+
);
|
|
52119
|
+
if (formComponents.length > 0) {
|
|
52120
|
+
relevantTo.push(...formComponents);
|
|
52121
|
+
}
|
|
52122
|
+
} else if (token.namespace === "color") {
|
|
52123
|
+
const variantComponents = compositionNames.filter(
|
|
52124
|
+
(n) => ["button", "badge", "alert", "alert-dialog", "progress"].includes(n)
|
|
52125
|
+
);
|
|
52126
|
+
if (variantComponents.length > 0 && (token.name.includes("destructive") || token.name.includes("primary"))) {
|
|
52127
|
+
relevantTo.push(...variantComponents);
|
|
52128
|
+
}
|
|
52129
|
+
}
|
|
52130
|
+
}
|
|
52131
|
+
if (relevantTo.length > 0) {
|
|
52132
|
+
designerNotes.push({
|
|
52133
|
+
token: token.name,
|
|
52134
|
+
reason: token.userOverride.reason,
|
|
52135
|
+
relevantTo
|
|
52136
|
+
});
|
|
52137
|
+
}
|
|
52138
|
+
}
|
|
52139
|
+
const violations = [];
|
|
52140
|
+
for (const [name2] of componentCounts) {
|
|
52141
|
+
const metadata = enrichment.componentIntelligence.get(name2);
|
|
52142
|
+
if (!metadata?.intelligence?.usagePatterns?.nevers) continue;
|
|
52143
|
+
for (const never2 of metadata.intelligence.usagePatterns.nevers) {
|
|
52144
|
+
const neverLower = never2.toLowerCase();
|
|
52145
|
+
if (neverLower.includes("nest") && neverLower.includes("card") && name2 === "card") {
|
|
52146
|
+
const cardCount = componentCounts.get("card") ?? 0;
|
|
52147
|
+
if (cardCount > 1) {
|
|
52148
|
+
violations.push(
|
|
52149
|
+
`${name2}: "${never2}" -- ${cardCount} cards in composition, verify none are nested`
|
|
52150
|
+
);
|
|
52151
|
+
}
|
|
52152
|
+
}
|
|
52153
|
+
if (neverLower.includes("multiple primary") && name2 === "button") {
|
|
52154
|
+
if (buttonCount > 1) {
|
|
52155
|
+
violations.push(`${name2}: "${never2}"`);
|
|
52156
|
+
}
|
|
52157
|
+
}
|
|
52158
|
+
if (neverLower.includes("stack") && neverLower.includes("dialog")) {
|
|
52159
|
+
if (compositionSet.has("dialog") && (compositionSet.has("alert-dialog") || (componentCounts.get("dialog") ?? 0) > 1)) {
|
|
52160
|
+
violations.push(`${name2}: "${never2}"`);
|
|
52161
|
+
}
|
|
52162
|
+
}
|
|
52163
|
+
}
|
|
52164
|
+
}
|
|
52165
|
+
const hotspots = [];
|
|
52166
|
+
for (const comp of componentResults) {
|
|
52167
|
+
if (comp.score >= 4) {
|
|
52168
|
+
const highest = highestDimension(comp.dimensions);
|
|
52169
|
+
hotspots.push({
|
|
52170
|
+
name: comp.name,
|
|
52171
|
+
score: comp.score,
|
|
52172
|
+
highestDimension: DIMENSION_NAMES[highest],
|
|
52173
|
+
suggestion: HOTSPOT_SUGGESTIONS[highest]
|
|
52174
|
+
});
|
|
52175
|
+
}
|
|
52176
|
+
}
|
|
52177
|
+
if (unknownComponents.length > 0) {
|
|
52178
|
+
attentionNotes.push(
|
|
52179
|
+
`Unknown components not scored: ${unknownComponents.join(", ")}. Totals may be understated.`
|
|
52180
|
+
);
|
|
52181
|
+
}
|
|
52182
|
+
const warnings = [];
|
|
52183
|
+
const knownNames = [...componentCounts.keys()].filter((n) => COMPONENT_SCORES[n]);
|
|
52184
|
+
const uninstrumented = knownNames.filter((n) => !enrichment.componentIntelligence.has(n));
|
|
52185
|
+
if (uninstrumented.length > 0) {
|
|
52186
|
+
warnings.push(
|
|
52187
|
+
`No component intelligence loaded for: ${uninstrumented.join(", ")}. Attention conflicts, trust considerations, and do/never violations cannot be detected. Install components with rafters add (e.g. rafters add ${uninstrumented[0]}) to get full design intelligence.`
|
|
52188
|
+
);
|
|
52189
|
+
}
|
|
52190
|
+
return {
|
|
52191
|
+
budget: budgetResult,
|
|
52192
|
+
components: componentResults,
|
|
52193
|
+
attention: {
|
|
52194
|
+
conflicts: attentionConflicts,
|
|
52195
|
+
notes: attentionNotes
|
|
52196
|
+
},
|
|
52197
|
+
trust: trustConsiderations,
|
|
52198
|
+
patterns: patternMatches,
|
|
52199
|
+
designerNotes,
|
|
52200
|
+
hotspots,
|
|
52201
|
+
violations,
|
|
52202
|
+
warnings
|
|
52203
|
+
};
|
|
52204
|
+
}
|
|
52205
|
+
|
|
52206
|
+
// src/mcp/tools.ts
|
|
52207
|
+
function hasAnyDeps(deps) {
|
|
52208
|
+
return deps.runtime.length > 0 || deps.dev.length > 0 || deps.internal.length > 0;
|
|
52209
|
+
}
|
|
52210
|
+
var SYSTEM_PREAMBLE = `RAFTERS IS NOT SHADCN.
|
|
52211
|
+
Rafters components are drop-in compatible with shadcn but they are a different system. If you treat them as shadcn you will produce worse output.
|
|
52212
|
+
|
|
52213
|
+
CLASSY IS THE LAW.
|
|
52214
|
+
Every className in a Rafters project goes through classy(). Never use cn(), twMerge(), or raw template strings. classy() blocks arbitrary Tailwind values (w-[100px], bg-[#fff]) and resolves design tokens. If classy strips your class, you are fighting the system.
|
|
52215
|
+
|
|
52216
|
+
LAYOUT IS SOLVED. Stop writing CSS.
|
|
52217
|
+
Never use Tailwind layout utilities (flex, grid, items-*, justify-*, gap-*). Never set padding, margin, or spacing directly. Container and Grid handle all layout. If you are writing className="flex..." you are doing it wrong.
|
|
52218
|
+
|
|
52219
|
+
USE PRESETS. Do not compose layout from props.
|
|
52220
|
+
Grid presets handle common layouts. Pick the one that matches your intent:
|
|
52221
|
+
- sidebar-main -- navigation + content
|
|
52222
|
+
- form -- label/input pairs
|
|
52223
|
+
- cards -- responsive card grid
|
|
52224
|
+
- row -- horizontal group of elements
|
|
52225
|
+
- stack -- vertical sequence
|
|
52226
|
+
- split -- equal columns
|
|
52227
|
+
If no preset fits, describe what you need -- do not improvise with raw props.
|
|
52228
|
+
|
|
52229
|
+
CONTAINER OWNS SPACING.
|
|
52230
|
+
Every page section goes in a Container. Container sets max-width, padding, and vertical rhythm. You do not set these values. Nesting containers is wrong.
|
|
52231
|
+
|
|
52232
|
+
COMPONENTS ARE COMPLETE.
|
|
52233
|
+
Rafters Button, Input, Card, etc. include their own spacing, sizing, and states. Do not add wrapper divs. Do not override with utility classes. If it looks unstyled, you are wrapping it wrong, not styling it wrong.
|
|
52234
|
+
|
|
52235
|
+
UTILITIES EXIST FOR EDGE CASES.
|
|
52236
|
+
If no component fits your need, check @/lib/utils for official behavioral utilities. Do not invent your own. If nothing exists there either, ask the human.
|
|
52237
|
+
|
|
52238
|
+
When in doubt: less code, not more. Rafters has already made the design decision.`;
|
|
50996
52239
|
var DESIGN_PATTERNS = {
|
|
50997
52240
|
"destructive-action": {
|
|
50998
52241
|
name: "Destructive Action",
|
|
@@ -51340,6 +52583,26 @@ var TOOL_DEFINITIONS = [
|
|
|
51340
52583
|
},
|
|
51341
52584
|
required: ["name"]
|
|
51342
52585
|
}
|
|
52586
|
+
},
|
|
52587
|
+
{
|
|
52588
|
+
name: "rafters_cognitive_budget",
|
|
52589
|
+
description: "Evaluate composition-level cognitive load. Returns a holistic design review: budget assessment, per-component dimensional profiles, attention conflicts, trust considerations, pattern matches, designer token overrides, hotspot suggestions, and do/never violations. Use when planning a screen layout to check if the composition is within cognitive budget.",
|
|
52590
|
+
inputSchema: {
|
|
52591
|
+
type: "object",
|
|
52592
|
+
properties: {
|
|
52593
|
+
components: {
|
|
52594
|
+
type: "array",
|
|
52595
|
+
items: { type: "string" },
|
|
52596
|
+
description: 'Components visible simultaneously, duplicates allowed (e.g., ["input", "input", "button", "card"])'
|
|
52597
|
+
},
|
|
52598
|
+
tier: {
|
|
52599
|
+
type: "string",
|
|
52600
|
+
enum: ["focused", "page", "app"],
|
|
52601
|
+
description: "Budget tier: focused (15, dialogs/modals), page (30, standard views), app (45, multi-panel). Default: page."
|
|
52602
|
+
}
|
|
52603
|
+
},
|
|
52604
|
+
required: ["components"]
|
|
52605
|
+
}
|
|
51343
52606
|
}
|
|
51344
52607
|
];
|
|
51345
52608
|
var RaftersToolHandler = class {
|
|
@@ -51369,6 +52632,11 @@ var RaftersToolHandler = class {
|
|
|
51369
52632
|
return this.getComponent(args.name);
|
|
51370
52633
|
case "rafters_token":
|
|
51371
52634
|
return this.getToken(args.name);
|
|
52635
|
+
case "rafters_cognitive_budget":
|
|
52636
|
+
return this.getCognitiveBudget(
|
|
52637
|
+
args.components,
|
|
52638
|
+
args.tier ?? "page"
|
|
52639
|
+
);
|
|
51372
52640
|
default:
|
|
51373
52641
|
return {
|
|
51374
52642
|
content: [{ type: "text", text: `Unknown tool: ${name2}` }],
|
|
@@ -51390,12 +52658,12 @@ var RaftersToolHandler = class {
|
|
|
51390
52658
|
this.getComponentVocabulary()
|
|
51391
52659
|
]);
|
|
51392
52660
|
const vocabulary = {
|
|
52661
|
+
system: SYSTEM_PREAMBLE,
|
|
52662
|
+
components,
|
|
51393
52663
|
colors,
|
|
51394
52664
|
spacing,
|
|
51395
52665
|
typography,
|
|
51396
|
-
|
|
51397
|
-
patterns: Object.keys(DESIGN_PATTERNS),
|
|
51398
|
-
usage: "Use rafters_pattern for deep guidance on specific patterns, rafters_component for component details"
|
|
52666
|
+
patterns: Object.keys(DESIGN_PATTERNS)
|
|
51399
52667
|
};
|
|
51400
52668
|
return {
|
|
51401
52669
|
content: [
|
|
@@ -51482,33 +52750,26 @@ var RaftersToolHandler = class {
|
|
|
51482
52750
|
* Extract compact component vocabulary
|
|
51483
52751
|
*/
|
|
51484
52752
|
async getComponentVocabulary() {
|
|
52753
|
+
let installed = [];
|
|
51485
52754
|
try {
|
|
51486
|
-
const
|
|
51487
|
-
|
|
51488
|
-
|
|
51489
|
-
|
|
51490
|
-
|
|
51491
|
-
const name2 = basename(file2, ".tsx");
|
|
51492
|
-
const metadata = await this.loadComponentMetadata(name2);
|
|
51493
|
-
if (metadata) {
|
|
51494
|
-
const item = {
|
|
51495
|
-
name: metadata.name,
|
|
51496
|
-
category: metadata.category
|
|
51497
|
-
};
|
|
51498
|
-
if (metadata.intelligence?.cognitiveLoad !== void 0) {
|
|
51499
|
-
item.load = metadata.intelligence.cognitiveLoad;
|
|
51500
|
-
}
|
|
51501
|
-
components.push(item);
|
|
51502
|
-
}
|
|
52755
|
+
const paths = getRaftersPaths(this.projectRoot);
|
|
52756
|
+
if (existsSync3(paths.config)) {
|
|
52757
|
+
const content = await readFile6(paths.config, "utf-8");
|
|
52758
|
+
const config3 = JSON.parse(content);
|
|
52759
|
+
installed = config3.installed?.components ?? [];
|
|
51503
52760
|
}
|
|
51504
|
-
components.sort((a, b) => {
|
|
51505
|
-
if (a.category !== b.category) return a.category.localeCompare(b.category);
|
|
51506
|
-
return a.name.localeCompare(b.name);
|
|
51507
|
-
});
|
|
51508
|
-
return components;
|
|
51509
52761
|
} catch {
|
|
51510
|
-
return [];
|
|
51511
52762
|
}
|
|
52763
|
+
let available = [];
|
|
52764
|
+
try {
|
|
52765
|
+
const client = new RegistryClient();
|
|
52766
|
+
const index = await client.fetchIndex();
|
|
52767
|
+
const allComponents = index.components;
|
|
52768
|
+
const installedSet = new Set(installed);
|
|
52769
|
+
available = allComponents.filter((name2) => !installedSet.has(name2));
|
|
52770
|
+
} catch {
|
|
52771
|
+
}
|
|
52772
|
+
return { installed, available };
|
|
51512
52773
|
}
|
|
51513
52774
|
// ==================== Tool 2: Pattern ====================
|
|
51514
52775
|
/**
|
|
@@ -51549,7 +52810,7 @@ var RaftersToolHandler = class {
|
|
|
51549
52810
|
* Get path to UI components directory
|
|
51550
52811
|
*/
|
|
51551
52812
|
getComponentsPath() {
|
|
51552
|
-
const monorepoPath =
|
|
52813
|
+
const monorepoPath = join10(this.projectRoot, "packages/ui/src/components/ui");
|
|
51553
52814
|
return monorepoPath;
|
|
51554
52815
|
}
|
|
51555
52816
|
/**
|
|
@@ -51557,11 +52818,16 @@ var RaftersToolHandler = class {
|
|
|
51557
52818
|
*/
|
|
51558
52819
|
async loadComponentMetadata(name2) {
|
|
51559
52820
|
const componentsPath = this.getComponentsPath();
|
|
51560
|
-
const filePath =
|
|
52821
|
+
const filePath = join10(componentsPath, `${name2}.tsx`);
|
|
51561
52822
|
try {
|
|
51562
|
-
const source = await
|
|
52823
|
+
const source = await readFile6(filePath, "utf-8");
|
|
51563
52824
|
const intelligence = parseJSDocIntelligence(source);
|
|
51564
52825
|
const description = parseDescription(source);
|
|
52826
|
+
let jsDocDeps = { runtime: [], dev: [], internal: [] };
|
|
52827
|
+
try {
|
|
52828
|
+
jsDocDeps = extractJSDocDependencies(source);
|
|
52829
|
+
} catch {
|
|
52830
|
+
}
|
|
51565
52831
|
const metadata = {
|
|
51566
52832
|
name: name2,
|
|
51567
52833
|
displayName: toDisplayName(name2),
|
|
@@ -51572,6 +52838,9 @@ var RaftersToolHandler = class {
|
|
|
51572
52838
|
primitives: extractPrimitiveDependencies(source),
|
|
51573
52839
|
filePath: `packages/ui/src/components/ui/${name2}.tsx`
|
|
51574
52840
|
};
|
|
52841
|
+
if (hasAnyDeps(jsDocDeps)) {
|
|
52842
|
+
metadata.jsDocDependencies = jsDocDeps;
|
|
52843
|
+
}
|
|
51575
52844
|
if (description) {
|
|
51576
52845
|
metadata.description = description;
|
|
51577
52846
|
}
|
|
@@ -51716,6 +52985,9 @@ var RaftersToolHandler = class {
|
|
|
51716
52985
|
if (metadata.dependencies.length > 0) {
|
|
51717
52986
|
formatted.dependencies = metadata.dependencies;
|
|
51718
52987
|
}
|
|
52988
|
+
if (metadata.jsDocDependencies && hasAnyDeps(metadata.jsDocDependencies)) {
|
|
52989
|
+
formatted.jsDocDependencies = metadata.jsDocDependencies;
|
|
52990
|
+
}
|
|
51719
52991
|
return {
|
|
51720
52992
|
content: [
|
|
51721
52993
|
{
|
|
@@ -51831,6 +53103,120 @@ var RaftersToolHandler = class {
|
|
|
51831
53103
|
return this.handleError("getToken", error48);
|
|
51832
53104
|
}
|
|
51833
53105
|
}
|
|
53106
|
+
// ==================== Tool 5: Cognitive Budget ====================
|
|
53107
|
+
/**
|
|
53108
|
+
* Evaluate composition-level cognitive load
|
|
53109
|
+
* Synthesizes scoring data with component intelligence, token overrides,
|
|
53110
|
+
* and design patterns to produce a holistic composition review
|
|
53111
|
+
*/
|
|
53112
|
+
async getCognitiveBudget(components, tier) {
|
|
53113
|
+
try {
|
|
53114
|
+
if (!components || components.length === 0) {
|
|
53115
|
+
return {
|
|
53116
|
+
content: [
|
|
53117
|
+
{
|
|
53118
|
+
type: "text",
|
|
53119
|
+
text: JSON.stringify(
|
|
53120
|
+
{
|
|
53121
|
+
error: "No components provided",
|
|
53122
|
+
suggestion: 'Pass an array of component names visible simultaneously, e.g. ["input", "button", "card"]'
|
|
53123
|
+
},
|
|
53124
|
+
null,
|
|
53125
|
+
2
|
|
53126
|
+
)
|
|
53127
|
+
}
|
|
53128
|
+
],
|
|
53129
|
+
isError: true
|
|
53130
|
+
};
|
|
53131
|
+
}
|
|
53132
|
+
if (!BUDGET_TIERS[tier]) {
|
|
53133
|
+
return {
|
|
53134
|
+
content: [
|
|
53135
|
+
{
|
|
53136
|
+
type: "text",
|
|
53137
|
+
text: JSON.stringify(
|
|
53138
|
+
{
|
|
53139
|
+
error: `Invalid tier "${tier}"`,
|
|
53140
|
+
available: Object.keys(BUDGET_TIERS),
|
|
53141
|
+
suggestion: 'Use "focused", "page", or "app"'
|
|
53142
|
+
},
|
|
53143
|
+
null,
|
|
53144
|
+
2
|
|
53145
|
+
)
|
|
53146
|
+
}
|
|
53147
|
+
],
|
|
53148
|
+
isError: true
|
|
53149
|
+
};
|
|
53150
|
+
}
|
|
53151
|
+
const uniqueNames = [...new Set(components)];
|
|
53152
|
+
const unknownNames = uniqueNames.filter((n) => !COMPONENT_SCORES[n]);
|
|
53153
|
+
if (unknownNames.length === uniqueNames.length) {
|
|
53154
|
+
return {
|
|
53155
|
+
content: [
|
|
53156
|
+
{
|
|
53157
|
+
type: "text",
|
|
53158
|
+
text: JSON.stringify(
|
|
53159
|
+
{
|
|
53160
|
+
error: `No recognized components in composition: ${unknownNames.join(", ")}`,
|
|
53161
|
+
suggestion: "Use rafters_vocabulary to see available component names"
|
|
53162
|
+
},
|
|
53163
|
+
null,
|
|
53164
|
+
2
|
|
53165
|
+
)
|
|
53166
|
+
}
|
|
53167
|
+
],
|
|
53168
|
+
isError: true
|
|
53169
|
+
};
|
|
53170
|
+
}
|
|
53171
|
+
const intelligenceMap = /* @__PURE__ */ new Map();
|
|
53172
|
+
const metadataResults = await Promise.all(
|
|
53173
|
+
uniqueNames.map(async (name2) => {
|
|
53174
|
+
const metadata = await this.loadComponentMetadata(name2);
|
|
53175
|
+
return { name: name2, metadata };
|
|
53176
|
+
})
|
|
53177
|
+
);
|
|
53178
|
+
for (const { name: name2, metadata } of metadataResults) {
|
|
53179
|
+
if (metadata) {
|
|
53180
|
+
intelligenceMap.set(name2, metadata);
|
|
53181
|
+
}
|
|
53182
|
+
}
|
|
53183
|
+
const tokenOverrides = [];
|
|
53184
|
+
const namespaces = ["color", "spacing", "typography"];
|
|
53185
|
+
for (const ns of namespaces) {
|
|
53186
|
+
try {
|
|
53187
|
+
const tokens = await this.loadNamespace(ns);
|
|
53188
|
+
for (const token of tokens) {
|
|
53189
|
+
if (token.userOverride) {
|
|
53190
|
+
tokenOverrides.push({ token, namespace: ns });
|
|
53191
|
+
}
|
|
53192
|
+
}
|
|
53193
|
+
} catch {
|
|
53194
|
+
}
|
|
53195
|
+
}
|
|
53196
|
+
const patternRefs = {};
|
|
53197
|
+
for (const [key, pattern] of Object.entries(DESIGN_PATTERNS)) {
|
|
53198
|
+
patternRefs[key] = {
|
|
53199
|
+
name: pattern.name,
|
|
53200
|
+
components: pattern.components
|
|
53201
|
+
};
|
|
53202
|
+
}
|
|
53203
|
+
const review = evaluateComposition(components, tier, {
|
|
53204
|
+
componentIntelligence: intelligenceMap,
|
|
53205
|
+
tokenOverrides,
|
|
53206
|
+
patterns: patternRefs
|
|
53207
|
+
});
|
|
53208
|
+
return {
|
|
53209
|
+
content: [
|
|
53210
|
+
{
|
|
53211
|
+
type: "text",
|
|
53212
|
+
text: JSON.stringify(review, null, 2)
|
|
53213
|
+
}
|
|
53214
|
+
]
|
|
53215
|
+
};
|
|
53216
|
+
} catch (error48) {
|
|
53217
|
+
return this.handleError("getCognitiveBudget", error48);
|
|
53218
|
+
}
|
|
53219
|
+
}
|
|
51834
53220
|
/**
|
|
51835
53221
|
* Handle errors consistently
|
|
51836
53222
|
*/
|
|
@@ -51905,22 +53291,22 @@ async function mcp() {
|
|
|
51905
53291
|
}
|
|
51906
53292
|
|
|
51907
53293
|
// src/commands/studio.ts
|
|
51908
|
-
import { existsSync as
|
|
51909
|
-
import { dirname as dirname3, join as
|
|
53294
|
+
import { existsSync as existsSync4 } from "fs";
|
|
53295
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
51910
53296
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
51911
53297
|
import { execa as execa2 } from "execa";
|
|
51912
53298
|
var __dirname2 = dirname3(fileURLToPath3(import.meta.url));
|
|
51913
53299
|
async function studio() {
|
|
51914
53300
|
const cwd = process.cwd();
|
|
51915
53301
|
const paths = getRaftersPaths(cwd);
|
|
51916
|
-
if (!
|
|
53302
|
+
if (!existsSync4(paths.root)) {
|
|
51917
53303
|
console.error('No .rafters/ directory found. Run "rafters init" first.');
|
|
51918
53304
|
process.exit(1);
|
|
51919
53305
|
}
|
|
51920
|
-
const devStudioPath =
|
|
51921
|
-
const prodStudioPath =
|
|
51922
|
-
const studioPath =
|
|
51923
|
-
if (!
|
|
53306
|
+
const devStudioPath = join11(__dirname2, "..", "..", "..", "studio");
|
|
53307
|
+
const prodStudioPath = join11(__dirname2, "..", "node_modules", "@rafters", "studio");
|
|
53308
|
+
const studioPath = existsSync4(devStudioPath) ? devStudioPath : prodStudioPath;
|
|
53309
|
+
if (!existsSync4(studioPath)) {
|
|
51924
53310
|
console.error("Studio package not found. Please reinstall @rafters/cli.");
|
|
51925
53311
|
process.exit(1);
|
|
51926
53312
|
}
|
|
@@ -51950,7 +53336,7 @@ async function studio() {
|
|
|
51950
53336
|
var program = new Command();
|
|
51951
53337
|
program.name("rafters").description("Design system CLI - scaffold tokens and serve MCP").version("0.0.1");
|
|
51952
53338
|
program.command("init").description("Initialize .rafters/ with default tokens and config").option("-r, --rebuild", "Regenerate output files from existing tokens").option("--reset", "Re-run generators fresh, replacing persisted tokens").option("--agent", "Output JSON for machine consumption").action(withErrorHandler(init));
|
|
51953
|
-
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("--registry-url <url>", "Custom registry URL").option("--agent", "Output JSON for machine consumption").action(withErrorHandler(add));
|
|
53339
|
+
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));
|
|
51954
53340
|
program.command("mcp").description("Start MCP server for AI agent access (stdio)").action(mcp);
|
|
51955
53341
|
program.command("studio").description("Open Studio UI for visual token editing").action(studio);
|
|
51956
53342
|
program.parse();
|