rafters 0.0.68 → 0.0.70
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 +282 -392
- package/dist/registry/types.d.ts +2 -0
- package/dist/registry/types.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12635,7 +12635,7 @@ var RegistryFileSchema = external_exports.object({
|
|
|
12635
12635
|
devDependencies: external_exports.array(external_exports.string()).default([])
|
|
12636
12636
|
// e.g., ["vitest"] - from @devDependencies JSDoc
|
|
12637
12637
|
});
|
|
12638
|
-
var RegistryItemTypeSchema = external_exports.enum(["ui", "primitive", "composite"]);
|
|
12638
|
+
var RegistryItemTypeSchema = external_exports.enum(["ui", "primitive", "composite", "rule"]);
|
|
12639
12639
|
var RegistryItemIntelligenceSchema = external_exports.object({
|
|
12640
12640
|
cognitiveLoad: external_exports.number().optional(),
|
|
12641
12641
|
attentionEconomics: external_exports.string().optional(),
|
|
@@ -12668,134 +12668,94 @@ var RegistryIndexSchema = external_exports.object({
|
|
|
12668
12668
|
|
|
12669
12669
|
// src/registry/client.ts
|
|
12670
12670
|
var DEFAULT_REGISTRY_URL = "https://rafters.studio";
|
|
12671
|
+
var REGISTRY_SOURCE = {
|
|
12672
|
+
ui: { folder: "components", label: "Component" },
|
|
12673
|
+
primitive: { folder: "primitives", label: "Primitive" },
|
|
12674
|
+
composite: { folder: "composites", label: "Composite" },
|
|
12675
|
+
rule: { folder: "rules", label: "Rule" }
|
|
12676
|
+
};
|
|
12677
|
+
var FETCH_ORDER = Object.keys(REGISTRY_SOURCE);
|
|
12671
12678
|
var RegistryClient = class {
|
|
12672
12679
|
baseUrl;
|
|
12673
12680
|
cache = /* @__PURE__ */ new Map();
|
|
12681
|
+
fetchByType;
|
|
12682
|
+
/** Typed fetchers -- one shared body, specialized per type. */
|
|
12683
|
+
fetchComponent;
|
|
12684
|
+
fetchPrimitive;
|
|
12685
|
+
fetchComposite;
|
|
12686
|
+
fetchRule;
|
|
12674
12687
|
constructor(baseUrl = DEFAULT_REGISTRY_URL) {
|
|
12675
12688
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
12689
|
+
const fetchFrom = (type2) => async (name) => {
|
|
12690
|
+
const { folder, label } = REGISTRY_SOURCE[type2];
|
|
12691
|
+
const cacheKey = `${type2}:${name}`;
|
|
12692
|
+
const cached2 = this.cache.get(cacheKey);
|
|
12693
|
+
if (cached2) return cached2;
|
|
12694
|
+
const response = await fetch(`${this.baseUrl}/registry/${folder}/${name}.json`);
|
|
12695
|
+
if (response.status === 404) {
|
|
12696
|
+
throw new Error(`${label} "${name}" not found`);
|
|
12697
|
+
}
|
|
12698
|
+
if (!response.ok) {
|
|
12699
|
+
throw new Error(
|
|
12700
|
+
`Failed to fetch ${label.toLowerCase()} "${name}": ${response.status} ${response.statusText}`
|
|
12701
|
+
);
|
|
12702
|
+
}
|
|
12703
|
+
const item = RegistryItemSchema.parse(await response.json());
|
|
12704
|
+
this.cache.set(cacheKey, item);
|
|
12705
|
+
return item;
|
|
12706
|
+
};
|
|
12707
|
+
this.fetchByType = {
|
|
12708
|
+
ui: fetchFrom("ui"),
|
|
12709
|
+
primitive: fetchFrom("primitive"),
|
|
12710
|
+
composite: fetchFrom("composite"),
|
|
12711
|
+
rule: fetchFrom("rule")
|
|
12712
|
+
};
|
|
12713
|
+
this.fetchComponent = this.fetchByType.ui;
|
|
12714
|
+
this.fetchPrimitive = this.fetchByType.primitive;
|
|
12715
|
+
this.fetchComposite = this.fetchByType.composite;
|
|
12716
|
+
this.fetchRule = this.fetchByType.rule;
|
|
12676
12717
|
}
|
|
12677
12718
|
/**
|
|
12678
|
-
* Fetch the registry index
|
|
12719
|
+
* Fetch the registry index.
|
|
12679
12720
|
*/
|
|
12680
12721
|
async fetchIndex() {
|
|
12681
|
-
const
|
|
12682
|
-
const response = await fetch(url3);
|
|
12722
|
+
const response = await fetch(`${this.baseUrl}/registry/index.json`);
|
|
12683
12723
|
if (!response.ok) {
|
|
12684
12724
|
throw new Error(`Failed to fetch registry index: ${response.status} ${response.statusText}`);
|
|
12685
12725
|
}
|
|
12686
|
-
|
|
12687
|
-
return RegistryIndexSchema.parse(data);
|
|
12688
|
-
}
|
|
12689
|
-
/**
|
|
12690
|
-
* Fetch a component by name
|
|
12691
|
-
*/
|
|
12692
|
-
async fetchComponent(name) {
|
|
12693
|
-
const cacheKey = `component:${name}`;
|
|
12694
|
-
const cached2 = this.cache.get(cacheKey);
|
|
12695
|
-
if (cached2) {
|
|
12696
|
-
return cached2;
|
|
12697
|
-
}
|
|
12698
|
-
const url3 = `${this.baseUrl}/registry/components/${name}.json`;
|
|
12699
|
-
const response = await fetch(url3);
|
|
12700
|
-
if (response.status === 404) {
|
|
12701
|
-
throw new Error(`Component "${name}" not found`);
|
|
12702
|
-
}
|
|
12703
|
-
if (!response.ok) {
|
|
12704
|
-
throw new Error(
|
|
12705
|
-
`Failed to fetch component "${name}": ${response.status} ${response.statusText}`
|
|
12706
|
-
);
|
|
12707
|
-
}
|
|
12708
|
-
const data = await response.json();
|
|
12709
|
-
const item = RegistryItemSchema.parse(data);
|
|
12710
|
-
this.cache.set(cacheKey, item);
|
|
12711
|
-
return item;
|
|
12712
|
-
}
|
|
12713
|
-
/**
|
|
12714
|
-
* Fetch a primitive by name
|
|
12715
|
-
*/
|
|
12716
|
-
async fetchPrimitive(name) {
|
|
12717
|
-
const cacheKey = `primitive:${name}`;
|
|
12718
|
-
const cached2 = this.cache.get(cacheKey);
|
|
12719
|
-
if (cached2) {
|
|
12720
|
-
return cached2;
|
|
12721
|
-
}
|
|
12722
|
-
const url3 = `${this.baseUrl}/registry/primitives/${name}.json`;
|
|
12723
|
-
const response = await fetch(url3);
|
|
12724
|
-
if (response.status === 404) {
|
|
12725
|
-
throw new Error(`Primitive "${name}" not found`);
|
|
12726
|
-
}
|
|
12727
|
-
if (!response.ok) {
|
|
12728
|
-
throw new Error(
|
|
12729
|
-
`Failed to fetch primitive "${name}": ${response.status} ${response.statusText}`
|
|
12730
|
-
);
|
|
12731
|
-
}
|
|
12732
|
-
const data = await response.json();
|
|
12733
|
-
const item = RegistryItemSchema.parse(data);
|
|
12734
|
-
this.cache.set(cacheKey, item);
|
|
12735
|
-
return item;
|
|
12736
|
-
}
|
|
12737
|
-
/**
|
|
12738
|
-
* Fetch a composite by name
|
|
12739
|
-
*/
|
|
12740
|
-
async fetchComposite(name) {
|
|
12741
|
-
const cacheKey = `composite:${name}`;
|
|
12742
|
-
const cached2 = this.cache.get(cacheKey);
|
|
12743
|
-
if (cached2) {
|
|
12744
|
-
return cached2;
|
|
12745
|
-
}
|
|
12746
|
-
const url3 = `${this.baseUrl}/registry/composites/${name}.json`;
|
|
12747
|
-
const response = await fetch(url3);
|
|
12748
|
-
if (response.status === 404) {
|
|
12749
|
-
throw new Error(`Composite "${name}" not found`);
|
|
12750
|
-
}
|
|
12751
|
-
if (!response.ok) {
|
|
12752
|
-
throw new Error(
|
|
12753
|
-
`Failed to fetch composite "${name}": ${response.status} ${response.statusText}`
|
|
12754
|
-
);
|
|
12755
|
-
}
|
|
12756
|
-
const data = await response.json();
|
|
12757
|
-
const item = RegistryItemSchema.parse(data);
|
|
12758
|
-
this.cache.set(cacheKey, item);
|
|
12759
|
-
return item;
|
|
12726
|
+
return RegistryIndexSchema.parse(await response.json());
|
|
12760
12727
|
}
|
|
12761
12728
|
/**
|
|
12762
|
-
* Fetch a registry item by name
|
|
12763
|
-
* Tries
|
|
12729
|
+
* Fetch a registry item by name when the type is unknown.
|
|
12730
|
+
* Tries each source in order; a non-"not found" error (network, 5xx) aborts.
|
|
12764
12731
|
*/
|
|
12765
12732
|
async fetchItem(name) {
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
} catch {
|
|
12773
|
-
try {
|
|
12774
|
-
return await this.fetchComposite(name);
|
|
12775
|
-
} catch {
|
|
12776
|
-
throw err;
|
|
12777
|
-
}
|
|
12778
|
-
}
|
|
12733
|
+
for (const type2 of FETCH_ORDER) {
|
|
12734
|
+
try {
|
|
12735
|
+
return await this.fetchByType[type2](name);
|
|
12736
|
+
} catch (err) {
|
|
12737
|
+
if (err instanceof Error && err.message.includes("not found")) continue;
|
|
12738
|
+
throw err;
|
|
12779
12739
|
}
|
|
12780
|
-
throw err;
|
|
12781
12740
|
}
|
|
12741
|
+
throw new Error(`"${name}" not found in registry (component, primitive, composite, or rule)`);
|
|
12782
12742
|
}
|
|
12783
12743
|
/**
|
|
12784
|
-
* List all available components
|
|
12744
|
+
* List all available components.
|
|
12785
12745
|
*/
|
|
12786
12746
|
async listComponents() {
|
|
12787
12747
|
const index = await this.fetchIndex();
|
|
12788
12748
|
return index.components.map((name) => ({ name }));
|
|
12789
12749
|
}
|
|
12790
12750
|
/**
|
|
12791
|
-
* List all available composites
|
|
12751
|
+
* List all available composites.
|
|
12792
12752
|
*/
|
|
12793
12753
|
async listComposites() {
|
|
12794
12754
|
const index = await this.fetchIndex();
|
|
12795
12755
|
return index.composites.map((name) => ({ name }));
|
|
12796
12756
|
}
|
|
12797
12757
|
/**
|
|
12798
|
-
* Check if a component exists in the registry
|
|
12758
|
+
* Check if a component exists in the registry.
|
|
12799
12759
|
*/
|
|
12800
12760
|
async componentExists(name) {
|
|
12801
12761
|
try {
|
|
@@ -12806,7 +12766,7 @@ var RegistryClient = class {
|
|
|
12806
12766
|
}
|
|
12807
12767
|
}
|
|
12808
12768
|
/**
|
|
12809
|
-
* Check if a primitive exists in the registry
|
|
12769
|
+
* Check if a primitive exists in the registry.
|
|
12810
12770
|
*/
|
|
12811
12771
|
async primitiveExists(name) {
|
|
12812
12772
|
try {
|
|
@@ -12817,20 +12777,17 @@ var RegistryClient = class {
|
|
|
12817
12777
|
}
|
|
12818
12778
|
}
|
|
12819
12779
|
/**
|
|
12820
|
-
* Resolve all dependencies for
|
|
12821
|
-
* Returns items in installation order (dependencies first)
|
|
12780
|
+
* Resolve all dependencies for an item recursively.
|
|
12781
|
+
* Returns items in installation order (dependencies first).
|
|
12822
12782
|
*/
|
|
12823
12783
|
async resolveDependencies(name, resolved = /* @__PURE__ */ new Set()) {
|
|
12824
|
-
if (resolved.has(name))
|
|
12825
|
-
return [];
|
|
12826
|
-
}
|
|
12784
|
+
if (resolved.has(name)) return [];
|
|
12827
12785
|
const item = await this.fetchItem(name);
|
|
12828
12786
|
resolved.add(name);
|
|
12829
12787
|
const deps = [];
|
|
12830
12788
|
for (const dep of item.primitives) {
|
|
12831
12789
|
if (!resolved.has(dep)) {
|
|
12832
|
-
|
|
12833
|
-
deps.push(...depItems);
|
|
12790
|
+
deps.push(...await this.resolveDependencies(dep, resolved));
|
|
12834
12791
|
}
|
|
12835
12792
|
}
|
|
12836
12793
|
deps.push(item);
|
|
@@ -12954,7 +12911,7 @@ var FRAMEWORK_SPECS = {
|
|
|
12954
12911
|
components: "components/ui",
|
|
12955
12912
|
primitives: "lib/primitives",
|
|
12956
12913
|
composites: "composites",
|
|
12957
|
-
rules: "rules"
|
|
12914
|
+
rules: "lib/rules"
|
|
12958
12915
|
}
|
|
12959
12916
|
},
|
|
12960
12917
|
vite: {
|
|
@@ -12964,7 +12921,7 @@ var FRAMEWORK_SPECS = {
|
|
|
12964
12921
|
components: "src/components/ui",
|
|
12965
12922
|
primitives: "src/lib/primitives",
|
|
12966
12923
|
composites: "src/composites",
|
|
12967
|
-
rules: "src/rules"
|
|
12924
|
+
rules: "src/lib/rules"
|
|
12968
12925
|
}
|
|
12969
12926
|
},
|
|
12970
12927
|
remix: {
|
|
@@ -12974,7 +12931,7 @@ var FRAMEWORK_SPECS = {
|
|
|
12974
12931
|
components: "app/components/ui",
|
|
12975
12932
|
primitives: "app/lib/primitives",
|
|
12976
12933
|
composites: "app/composites",
|
|
12977
|
-
rules: "app/rules"
|
|
12934
|
+
rules: "app/lib/rules"
|
|
12978
12935
|
}
|
|
12979
12936
|
},
|
|
12980
12937
|
"react-router": {
|
|
@@ -12984,7 +12941,7 @@ var FRAMEWORK_SPECS = {
|
|
|
12984
12941
|
components: "app/components/ui",
|
|
12985
12942
|
primitives: "app/lib/primitives",
|
|
12986
12943
|
composites: "app/composites",
|
|
12987
|
-
rules: "app/rules"
|
|
12944
|
+
rules: "app/lib/rules"
|
|
12988
12945
|
}
|
|
12989
12946
|
},
|
|
12990
12947
|
astro: {
|
|
@@ -12994,7 +12951,7 @@ var FRAMEWORK_SPECS = {
|
|
|
12994
12951
|
components: "src/components/ui",
|
|
12995
12952
|
primitives: "src/lib/primitives",
|
|
12996
12953
|
composites: "src/composites",
|
|
12997
|
-
rules: "src/rules"
|
|
12954
|
+
rules: "src/lib/rules"
|
|
12998
12955
|
}
|
|
12999
12956
|
},
|
|
13000
12957
|
wc: {
|
|
@@ -13004,7 +12961,7 @@ var FRAMEWORK_SPECS = {
|
|
|
13004
12961
|
components: "src/components/ui",
|
|
13005
12962
|
primitives: "src/lib/primitives",
|
|
13006
12963
|
composites: "src/composites",
|
|
13007
|
-
rules: "src/rules"
|
|
12964
|
+
rules: "src/lib/rules"
|
|
13008
12965
|
}
|
|
13009
12966
|
},
|
|
13010
12967
|
vanilla: {
|
|
@@ -13014,7 +12971,7 @@ var FRAMEWORK_SPECS = {
|
|
|
13014
12971
|
components: "src/components/ui",
|
|
13015
12972
|
primitives: "src/lib/primitives",
|
|
13016
12973
|
composites: "src/composites",
|
|
13017
|
-
rules: "src/rules"
|
|
12974
|
+
rules: "src/lib/rules"
|
|
13018
12975
|
}
|
|
13019
12976
|
},
|
|
13020
12977
|
unknown: {
|
|
@@ -13023,7 +12980,7 @@ var FRAMEWORK_SPECS = {
|
|
|
13023
12980
|
components: "components/ui",
|
|
13024
12981
|
primitives: "lib/primitives",
|
|
13025
12982
|
composites: "composites",
|
|
13026
|
-
rules: "rules"
|
|
12983
|
+
rules: "lib/rules"
|
|
13027
12984
|
}
|
|
13028
12985
|
}
|
|
13029
12986
|
};
|
|
@@ -13671,6 +13628,9 @@ async function loadConfig(cwd) {
|
|
|
13671
13628
|
return null;
|
|
13672
13629
|
}
|
|
13673
13630
|
}
|
|
13631
|
+
function resolveRegistryUrl(options, config2) {
|
|
13632
|
+
return options.registryUrl ?? config2?.registryUrl;
|
|
13633
|
+
}
|
|
13674
13634
|
async function saveConfig(cwd, config2) {
|
|
13675
13635
|
const paths = getRaftersPaths(cwd);
|
|
13676
13636
|
await writeFile(paths.config, JSON.stringify(config2, null, 2));
|
|
@@ -13709,16 +13669,26 @@ function selectFilesForFramework(files, target) {
|
|
|
13709
13669
|
}
|
|
13710
13670
|
return { files, fallback: false };
|
|
13711
13671
|
}
|
|
13672
|
+
var TARGET_GATED_COMPOSITE_FILES = [
|
|
13673
|
+
{ suffix: "Composite.astro", target: "astro" }
|
|
13674
|
+
];
|
|
13675
|
+
function selectCompositeFiles(files, target) {
|
|
13676
|
+
return files.filter((file2) => {
|
|
13677
|
+
const gate = TARGET_GATED_COMPOSITE_FILES.find((g2) => file2.path.endsWith(g2.suffix));
|
|
13678
|
+
return gate ? gate.target === target : true;
|
|
13679
|
+
});
|
|
13680
|
+
}
|
|
13712
13681
|
var FOLDER_NAMES = /* @__PURE__ */ new Set(["composites"]);
|
|
13713
13682
|
function isAlreadyInstalled(config2, item) {
|
|
13714
13683
|
if (!config2?.installed) return false;
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
|
|
13718
|
-
|
|
13719
|
-
|
|
13720
|
-
|
|
13721
|
-
|
|
13684
|
+
const { components, primitives, composites: composites2, rules } = config2.installed;
|
|
13685
|
+
const bucketByType = {
|
|
13686
|
+
ui: components,
|
|
13687
|
+
primitive: primitives,
|
|
13688
|
+
composite: composites2 ?? [],
|
|
13689
|
+
rule: rules ?? []
|
|
13690
|
+
};
|
|
13691
|
+
return bucketByType[item.type].includes(item.name);
|
|
13722
13692
|
}
|
|
13723
13693
|
function isInstalledOnDisk(config2, item, cwd) {
|
|
13724
13694
|
if (!isAlreadyInstalled(config2, item)) return false;
|
|
@@ -13735,8 +13705,14 @@ function trackInstalled(config2, items) {
|
|
|
13735
13705
|
const installed = config2.installed;
|
|
13736
13706
|
if (!installed.composites) installed.composites = [];
|
|
13737
13707
|
if (!installed.rules) installed.rules = [];
|
|
13708
|
+
const bucketByType = {
|
|
13709
|
+
ui: installed.components,
|
|
13710
|
+
primitive: installed.primitives,
|
|
13711
|
+
composite: installed.composites,
|
|
13712
|
+
rule: installed.rules
|
|
13713
|
+
};
|
|
13738
13714
|
for (const item of items) {
|
|
13739
|
-
const bucket = item.type
|
|
13715
|
+
const bucket = bucketByType[item.type];
|
|
13740
13716
|
if (!bucket.includes(item.name)) bucket.push(item.name);
|
|
13741
13717
|
}
|
|
13742
13718
|
installed.components.sort();
|
|
@@ -13753,7 +13729,7 @@ function transformPath(registryPath, config2, cwd) {
|
|
|
13753
13729
|
["components/ui/", config2.componentsPath, "components/ui"],
|
|
13754
13730
|
["lib/primitives/", config2.primitivesPath, "lib/primitives"],
|
|
13755
13731
|
["composites/", config2.compositesPath, "composites"],
|
|
13756
|
-
["rules/", config2.rulesPath, "rules"]
|
|
13732
|
+
["rules/", config2.rulesPath, "lib/rules"]
|
|
13757
13733
|
];
|
|
13758
13734
|
for (const [prefix, field, fallback] of replacements) {
|
|
13759
13735
|
if (registryPath.startsWith(prefix)) {
|
|
@@ -13815,6 +13791,8 @@ async function installItem(cwd, item, options, config2) {
|
|
|
13815
13791
|
message: `No ${targetToExtension(target)} version available for ${item.name}. Installing React version.`
|
|
13816
13792
|
});
|
|
13817
13793
|
}
|
|
13794
|
+
} else if (item.type === "composite") {
|
|
13795
|
+
filesToInstall = selectCompositeFiles(item.files, getComponentTarget(config2));
|
|
13818
13796
|
}
|
|
13819
13797
|
for (const file2 of filesToInstall) {
|
|
13820
13798
|
const projectPath2 = transformPath(file2.path, config2, cwd);
|
|
@@ -13846,7 +13824,9 @@ async function installItem(cwd, item, options, config2) {
|
|
|
13846
13824
|
async function add(componentArgs, options) {
|
|
13847
13825
|
setAgentMode(options.agent ?? false);
|
|
13848
13826
|
let components = componentArgs;
|
|
13849
|
-
const
|
|
13827
|
+
const cwd = process.cwd();
|
|
13828
|
+
const config2 = await loadConfig(cwd);
|
|
13829
|
+
const client = new RegistryClient(resolveRegistryUrl(options, config2));
|
|
13850
13830
|
let folder;
|
|
13851
13831
|
const firstArg = components[0];
|
|
13852
13832
|
if (firstArg && FOLDER_NAMES.has(firstArg)) {
|
|
@@ -13876,14 +13856,12 @@ async function add(componentArgs, options) {
|
|
|
13876
13856
|
}
|
|
13877
13857
|
return;
|
|
13878
13858
|
}
|
|
13879
|
-
const cwd = process.cwd();
|
|
13880
13859
|
const initialized = await isInitialized(cwd);
|
|
13881
13860
|
if (!initialized) {
|
|
13882
13861
|
error46("Project not initialized. Run `rafters init` first.");
|
|
13883
13862
|
process.exitCode = 1;
|
|
13884
13863
|
return;
|
|
13885
13864
|
}
|
|
13886
|
-
const config2 = await loadConfig(cwd);
|
|
13887
13865
|
if (options.update) {
|
|
13888
13866
|
options.overwrite = true;
|
|
13889
13867
|
}
|
|
@@ -13988,6 +13966,7 @@ async function add(componentArgs, options) {
|
|
|
13988
13966
|
}
|
|
13989
13967
|
if (result.skipped && !result.installed) {
|
|
13990
13968
|
skipped.push(item.name);
|
|
13969
|
+
installedItems.push(item);
|
|
13991
13970
|
}
|
|
13992
13971
|
} catch (err) {
|
|
13993
13972
|
if (err instanceof Error) {
|
|
@@ -14034,7 +14013,7 @@ async function add(componentArgs, options) {
|
|
|
14034
14013
|
componentsPath: "components/ui",
|
|
14035
14014
|
primitivesPath: "lib/primitives",
|
|
14036
14015
|
compositesPath: "composites",
|
|
14037
|
-
rulesPath: "rules",
|
|
14016
|
+
rulesPath: "lib/rules",
|
|
14038
14017
|
cssPath: null,
|
|
14039
14018
|
shadcn: false,
|
|
14040
14019
|
exports: DEFAULT_EXPORTS,
|
|
@@ -21167,12 +21146,23 @@ var SemanticSelectionError = class extends Error {
|
|
|
21167
21146
|
this.name = "SemanticSelectionError";
|
|
21168
21147
|
}
|
|
21169
21148
|
};
|
|
21170
|
-
var STATE_USES = [
|
|
21149
|
+
var STATE_USES = [
|
|
21150
|
+
"hover",
|
|
21151
|
+
"active",
|
|
21152
|
+
"focus",
|
|
21153
|
+
"disabled",
|
|
21154
|
+
"border",
|
|
21155
|
+
"ring",
|
|
21156
|
+
"subtle"
|
|
21157
|
+
];
|
|
21171
21158
|
var STATE_RANK_STEP = {
|
|
21172
21159
|
hover: (rank, _l, s) => rank + s,
|
|
21173
21160
|
active: (rank, _l, s) => rank + 2 * s,
|
|
21174
21161
|
focus: (rank, _l, s) => rank + s,
|
|
21175
|
-
disabled: (_rank, ladder) => closestRankTo(ladder, 5)
|
|
21162
|
+
disabled: (_rank, ladder) => closestRankTo(ladder, 5),
|
|
21163
|
+
border: (rank, _l, s) => rank + 2 * s,
|
|
21164
|
+
ring: (rank) => rank,
|
|
21165
|
+
subtle: (rank, _l, s) => rank - 2 * s
|
|
21176
21166
|
};
|
|
21177
21167
|
function partnerForBase(pairs, base) {
|
|
21178
21168
|
if (!pairs) return void 0;
|
|
@@ -22863,142 +22853,12 @@ function registryToTailwind(registry2, options) {
|
|
|
22863
22853
|
const tokens = [...registry2.list()];
|
|
22864
22854
|
return tokensToTailwind(tokens, options, []);
|
|
22865
22855
|
}
|
|
22866
|
-
function generateVarsRootBlock(groups) {
|
|
22867
|
-
const lines = [];
|
|
22868
|
-
lines.push(":root {");
|
|
22869
|
-
if (groups.color.length > 0) {
|
|
22870
|
-
for (const token of groups.color) {
|
|
22871
|
-
const value = tokenValueToCSS(token);
|
|
22872
|
-
if (value === null) continue;
|
|
22873
|
-
lines.push(` --rafters-color-${token.name}: ${value};`);
|
|
22874
|
-
}
|
|
22875
|
-
lines.push("");
|
|
22876
|
-
}
|
|
22877
|
-
if (groups.spacing.length > 0) {
|
|
22878
|
-
for (const token of groups.spacing) {
|
|
22879
|
-
const value = tokenValueToCSS(token);
|
|
22880
|
-
if (value === null) continue;
|
|
22881
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22882
|
-
}
|
|
22883
|
-
lines.push("");
|
|
22884
|
-
}
|
|
22885
|
-
if (groups.typography.length > 0) {
|
|
22886
|
-
for (const token of groups.typography) {
|
|
22887
|
-
const value = tokenValueToCSS(token);
|
|
22888
|
-
if (value === null) continue;
|
|
22889
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22890
|
-
if (token.lineHeight) {
|
|
22891
|
-
lines.push(` --rafters-${token.name}--line-height: ${token.lineHeight};`);
|
|
22892
|
-
}
|
|
22893
|
-
}
|
|
22894
|
-
lines.push("");
|
|
22895
|
-
}
|
|
22896
|
-
if (groups.radius.length > 0) {
|
|
22897
|
-
for (const token of groups.radius) {
|
|
22898
|
-
const value = tokenValueToCSS(token);
|
|
22899
|
-
if (value === null) continue;
|
|
22900
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22901
|
-
}
|
|
22902
|
-
lines.push("");
|
|
22903
|
-
}
|
|
22904
|
-
if (groups.shadow.length > 0) {
|
|
22905
|
-
for (const token of groups.shadow) {
|
|
22906
|
-
const value = tokenValueToCSS(token);
|
|
22907
|
-
if (value === null) continue;
|
|
22908
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22909
|
-
}
|
|
22910
|
-
lines.push("");
|
|
22911
|
-
}
|
|
22912
|
-
if (groups.depth.length > 0) {
|
|
22913
|
-
for (const token of groups.depth) {
|
|
22914
|
-
const value = tokenValueToCSS(token);
|
|
22915
|
-
if (value === null) continue;
|
|
22916
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22917
|
-
}
|
|
22918
|
-
lines.push("");
|
|
22919
|
-
}
|
|
22920
|
-
if (groups.motion.length > 0) {
|
|
22921
|
-
for (const token of groups.motion) {
|
|
22922
|
-
if (token.name.startsWith("motion-duration-") && token.name !== "motion-duration-base")
|
|
22923
|
-
continue;
|
|
22924
|
-
if (token.name.startsWith("motion-easing-")) continue;
|
|
22925
|
-
const value = tokenValueToCSS(token);
|
|
22926
|
-
if (value === null) continue;
|
|
22927
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22928
|
-
}
|
|
22929
|
-
lines.push("");
|
|
22930
|
-
}
|
|
22931
|
-
if (groups.motion.length > 0) {
|
|
22932
|
-
for (const token of groups.motion) {
|
|
22933
|
-
if (token.name.startsWith("motion-duration-") && token.name !== "motion-duration-base") {
|
|
22934
|
-
const value = tokenValueToCSS(token);
|
|
22935
|
-
if (value === null) continue;
|
|
22936
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22937
|
-
}
|
|
22938
|
-
if (token.name.startsWith("motion-easing-")) {
|
|
22939
|
-
const value = tokenValueToCSS(token);
|
|
22940
|
-
if (value === null) continue;
|
|
22941
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22942
|
-
}
|
|
22943
|
-
}
|
|
22944
|
-
lines.push("");
|
|
22945
|
-
}
|
|
22946
|
-
if (groups.breakpoint.length > 0) {
|
|
22947
|
-
for (const token of groups.breakpoint) {
|
|
22948
|
-
const value = tokenValueToCSS(token);
|
|
22949
|
-
if (value === null) continue;
|
|
22950
|
-
if (isMediaQueryToken(token)) continue;
|
|
22951
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22952
|
-
}
|
|
22953
|
-
lines.push("");
|
|
22954
|
-
}
|
|
22955
|
-
if (groups.focus.length > 0) {
|
|
22956
|
-
for (const token of groups.focus) {
|
|
22957
|
-
const value = tokenValueToCSS(token);
|
|
22958
|
-
if (value === null) continue;
|
|
22959
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22960
|
-
}
|
|
22961
|
-
lines.push("");
|
|
22962
|
-
}
|
|
22963
|
-
if (groups.other.length > 0) {
|
|
22964
|
-
for (const token of groups.other) {
|
|
22965
|
-
const value = tokenValueToCSS(token);
|
|
22966
|
-
if (value === null) continue;
|
|
22967
|
-
lines.push(` --rafters-${token.name}: ${value};`);
|
|
22968
|
-
}
|
|
22969
|
-
lines.push("");
|
|
22970
|
-
}
|
|
22971
|
-
const animationTokens = groups.motion.filter((t) => t.name.startsWith("motion-animation-"));
|
|
22972
|
-
if (animationTokens.length > 0) {
|
|
22973
|
-
for (const token of animationTokens) {
|
|
22974
|
-
const animName = token.animationName || token.name.replace("motion-animation-", "");
|
|
22975
|
-
lines.push(` --rafters-animate-${animName}: ${token.value};`);
|
|
22976
|
-
}
|
|
22977
|
-
lines.push("");
|
|
22978
|
-
}
|
|
22979
|
-
lines.push("}");
|
|
22980
|
-
return lines.join("\n");
|
|
22981
|
-
}
|
|
22982
|
-
function registryToVars(registry2) {
|
|
22983
|
-
const tokens = [...registry2.list()];
|
|
22984
|
-
if (tokens.length === 0) {
|
|
22985
|
-
throw new Error("Registry is empty");
|
|
22986
|
-
}
|
|
22987
|
-
const groups = groupTokens(tokens);
|
|
22988
|
-
const sections = [];
|
|
22989
|
-
const varsBlock = generateVarsRootBlock(groups);
|
|
22990
|
-
sections.push(varsBlock);
|
|
22991
|
-
sections.push("");
|
|
22992
|
-
const rootBlock = generateRootBlock(groups.semantic);
|
|
22993
|
-
sections.push(rootBlock);
|
|
22994
|
-
return sections.join("\n");
|
|
22995
|
-
}
|
|
22996
22856
|
async function registryToCompiled(registry2, options = {}) {
|
|
22997
22857
|
const { minify = true, includeImport = true } = options;
|
|
22998
22858
|
const themeCss = registryToTailwind(registry2, { includeImport });
|
|
22999
22859
|
const { execFileSync } = await import("child_process");
|
|
23000
22860
|
const { mkdtempSync, writeFileSync: writeFileSync2, readFileSync: readFileSync3, rmSync } = await import("fs");
|
|
23001
|
-
const { join:
|
|
22861
|
+
const { join: join14, dirname: dirname4 } = await import("path");
|
|
23002
22862
|
const { createRequire: createRequire2 } = await import("module");
|
|
23003
22863
|
const require2 = createRequire2(import.meta.url);
|
|
23004
22864
|
let pkgDir;
|
|
@@ -23008,10 +22868,10 @@ async function registryToCompiled(registry2, options = {}) {
|
|
|
23008
22868
|
} catch {
|
|
23009
22869
|
throw new Error("Failed to resolve @tailwindcss/cli");
|
|
23010
22870
|
}
|
|
23011
|
-
const binPath =
|
|
23012
|
-
const tempDir = mkdtempSync(
|
|
23013
|
-
const tempInput =
|
|
23014
|
-
const tempOutput =
|
|
22871
|
+
const binPath = join14(pkgDir, "dist", "index.mjs");
|
|
22872
|
+
const tempDir = mkdtempSync(join14(pkgDir, ".tmp-compile-"));
|
|
22873
|
+
const tempInput = join14(tempDir, "input.css");
|
|
22874
|
+
const tempOutput = join14(tempDir, "output.css");
|
|
23015
22875
|
try {
|
|
23016
22876
|
writeFileSync2(tempInput, themeCss);
|
|
23017
22877
|
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
@@ -24363,12 +24223,12 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
24363
24223
|
never: ["Use for dividers within cards"]
|
|
24364
24224
|
},
|
|
24365
24225
|
panel: {
|
|
24366
|
-
light: { family: "neutral", position: "
|
|
24226
|
+
light: { family: "neutral", position: "200" },
|
|
24367
24227
|
dark: { family: "neutral", position: "800" },
|
|
24368
|
-
meaning: "
|
|
24228
|
+
meaning: "Persistent elevated chrome -- headers, docks, fixed toolbars",
|
|
24369
24229
|
contexts: ["panels", "toolbars", "headers", "docks"],
|
|
24370
24230
|
do: ["Use for persistent elevated chrome", "Pair with panel-foreground"],
|
|
24371
|
-
never: ["Use for page-level backgrounds", "
|
|
24231
|
+
never: ["Use for page-level backgrounds", "Use for transient surfaces"]
|
|
24372
24232
|
},
|
|
24373
24233
|
"panel-foreground": {
|
|
24374
24234
|
light: { family: "neutral", position: "950" },
|
|
@@ -24421,12 +24281,12 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
24421
24281
|
},
|
|
24422
24282
|
// Generic surface
|
|
24423
24283
|
surface: {
|
|
24424
|
-
light: { family: "neutral", position: "
|
|
24284
|
+
light: { family: "neutral", position: "100" },
|
|
24425
24285
|
dark: { family: "neutral", position: "900" },
|
|
24426
|
-
meaning: "
|
|
24427
|
-
contexts: ["
|
|
24428
|
-
do: ["Use for
|
|
24429
|
-
never: ["Use for page background"]
|
|
24286
|
+
meaning: "Base chrome surface -- toolbars, app shell, UI frame",
|
|
24287
|
+
contexts: ["chrome", "app-shell", "toolbars"],
|
|
24288
|
+
do: ["Use for application chrome"],
|
|
24289
|
+
never: ["Use for page background", "Use for content containers"]
|
|
24430
24290
|
},
|
|
24431
24291
|
"surface-foreground": {
|
|
24432
24292
|
light: { family: "neutral", position: "950" },
|
|
@@ -25511,9 +25371,9 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
25511
25371
|
// SIDEBAR TOKENS (shadcn compatible + extended)
|
|
25512
25372
|
// ============================================================================
|
|
25513
25373
|
sidebar: {
|
|
25514
|
-
light: { family: "neutral", position: "
|
|
25374
|
+
light: { family: "neutral", position: "100" },
|
|
25515
25375
|
dark: { family: "neutral", position: "900" },
|
|
25516
|
-
meaning: "Sidebar background",
|
|
25376
|
+
meaning: "Sidebar background -- almost on the surface",
|
|
25517
25377
|
contexts: ["navigation-sidebar", "side-panels"],
|
|
25518
25378
|
do: ["Use for sidebar backgrounds"],
|
|
25519
25379
|
never: ["Use for main content areas"]
|
|
@@ -27173,7 +27033,7 @@ function generateRadiusTokens(config2, radiusDefs) {
|
|
|
27173
27033
|
|
|
27174
27034
|
// ../design-tokens/src/generators/semantic.ts
|
|
27175
27035
|
var FOREGROUND_SUFFIXES = ["-foreground", "-text", "-contrast"];
|
|
27176
|
-
var STATE_SUFFIXES =
|
|
27036
|
+
var STATE_SUFFIXES = STATE_USES.map((s) => `-${s}`);
|
|
27177
27037
|
function toColorRef(mapping) {
|
|
27178
27038
|
return { family: mapping.light.family, position: mapping.light.position };
|
|
27179
27039
|
}
|
|
@@ -28874,7 +28734,7 @@ var scalePlugin = definePlugin({
|
|
|
28874
28734
|
});
|
|
28875
28735
|
|
|
28876
28736
|
// ../design-tokens/src/plugins/state.ts
|
|
28877
|
-
var StateTypeSchema = external_exports.enum(
|
|
28737
|
+
var StateTypeSchema = external_exports.enum(STATE_USES);
|
|
28878
28738
|
var StateInputSchema = external_exports.object({
|
|
28879
28739
|
from: external_exports.string(),
|
|
28880
28740
|
stateType: StateTypeSchema
|
|
@@ -29748,7 +29608,7 @@ async function init(options) {
|
|
|
29748
29608
|
|
|
29749
29609
|
// src/commands/mcp.ts
|
|
29750
29610
|
import { existsSync as existsSync6 } from "fs";
|
|
29751
|
-
import { basename as basename2, join as
|
|
29611
|
+
import { basename as basename2, join as join12, resolve as resolve4 } from "path";
|
|
29752
29612
|
|
|
29753
29613
|
// src/mcp/server.ts
|
|
29754
29614
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -29756,8 +29616,8 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
29756
29616
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
29757
29617
|
|
|
29758
29618
|
// src/mcp/tools.ts
|
|
29759
|
-
import {
|
|
29760
|
-
import { join as
|
|
29619
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
29620
|
+
import { join as join11 } from "path";
|
|
29761
29621
|
|
|
29762
29622
|
// ../composites/src/built-in-rules/email.ts
|
|
29763
29623
|
var email3 = external_exports.string().email();
|
|
@@ -29786,6 +29646,10 @@ var AppliedRuleSchema = external_exports.union([
|
|
|
29786
29646
|
var CompositeBlockSchema = external_exports.object({
|
|
29787
29647
|
id: external_exports.string().min(1),
|
|
29788
29648
|
type: external_exports.string().min(1),
|
|
29649
|
+
/** Signatures this block consumes / produces (rule names) -- the typed I/O edges.
|
|
29650
|
+
* Within a composite, an output named X feeds any block input named X. */
|
|
29651
|
+
input: external_exports.array(external_exports.string()).optional(),
|
|
29652
|
+
output: external_exports.array(external_exports.string()).optional(),
|
|
29789
29653
|
content: external_exports.unknown().optional(),
|
|
29790
29654
|
children: external_exports.array(external_exports.string()).optional(),
|
|
29791
29655
|
parentId: external_exports.string().optional(),
|
|
@@ -29815,6 +29679,60 @@ var CompositeFileSchema = external_exports.object({
|
|
|
29815
29679
|
blocks: external_exports.array(CompositeBlockSchema).min(1)
|
|
29816
29680
|
});
|
|
29817
29681
|
|
|
29682
|
+
// ../composites/src/discovery.ts
|
|
29683
|
+
function discoverComposites(entries) {
|
|
29684
|
+
const registry2 = /* @__PURE__ */ new Map();
|
|
29685
|
+
const errors = [];
|
|
29686
|
+
for (const entry of entries) {
|
|
29687
|
+
let parsed;
|
|
29688
|
+
try {
|
|
29689
|
+
parsed = JSON.parse(entry.raw);
|
|
29690
|
+
} catch (e) {
|
|
29691
|
+
errors.push({
|
|
29692
|
+
source: entry.source,
|
|
29693
|
+
error: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}`
|
|
29694
|
+
});
|
|
29695
|
+
continue;
|
|
29696
|
+
}
|
|
29697
|
+
const result = CompositeFileSchema.safeParse(parsed);
|
|
29698
|
+
if (!result.success) {
|
|
29699
|
+
errors.push({ source: entry.source, error: result.error.message });
|
|
29700
|
+
continue;
|
|
29701
|
+
}
|
|
29702
|
+
const { id } = result.data.manifest;
|
|
29703
|
+
if (registry2.has(id)) {
|
|
29704
|
+
errors.push({
|
|
29705
|
+
source: entry.source,
|
|
29706
|
+
error: `Duplicate composite id "${id}" (already registered)`
|
|
29707
|
+
});
|
|
29708
|
+
continue;
|
|
29709
|
+
}
|
|
29710
|
+
registry2.set(id, result.data);
|
|
29711
|
+
}
|
|
29712
|
+
reportUnresolvedReferences(registry2, errors);
|
|
29713
|
+
return { registry: registry2, errors };
|
|
29714
|
+
}
|
|
29715
|
+
var COMPOSITE_PREFIX = "composite:";
|
|
29716
|
+
function reportUnresolvedReferences(registry2, errors) {
|
|
29717
|
+
for (const [id, composite] of registry2) {
|
|
29718
|
+
const missing = /* @__PURE__ */ new Set();
|
|
29719
|
+
for (const block of composite.blocks) {
|
|
29720
|
+
if (block.type.startsWith(COMPOSITE_PREFIX)) {
|
|
29721
|
+
const refId = block.type.slice(COMPOSITE_PREFIX.length);
|
|
29722
|
+
if (!registry2.has(refId)) {
|
|
29723
|
+
missing.add(refId);
|
|
29724
|
+
}
|
|
29725
|
+
}
|
|
29726
|
+
}
|
|
29727
|
+
if (missing.size > 0) {
|
|
29728
|
+
errors.push({
|
|
29729
|
+
source: id,
|
|
29730
|
+
error: `Unresolved composite reference(s): ${[...missing].map((m3) => `composite:${m3}`).join(", ")}`
|
|
29731
|
+
});
|
|
29732
|
+
}
|
|
29733
|
+
}
|
|
29734
|
+
}
|
|
29735
|
+
|
|
29818
29736
|
// ../ui/src/primitives/typeahead.ts
|
|
29819
29737
|
function fuzzyScore(query, target) {
|
|
29820
29738
|
if (query.length === 0) return 1;
|
|
@@ -29872,17 +29790,56 @@ function search(query) {
|
|
|
29872
29790
|
// ../composites/src/to-mdx.ts
|
|
29873
29791
|
var import_escape_html = __toESM(require_escape_html(), 1);
|
|
29874
29792
|
|
|
29793
|
+
// ../composites/src/discovery-node.ts
|
|
29794
|
+
import { readdir, readFile as readFile5 } from "fs/promises";
|
|
29795
|
+
import { join as join8 } from "path";
|
|
29796
|
+
var COMPOSITE_SUFFIX = ".composite.json";
|
|
29797
|
+
async function readDir(directory) {
|
|
29798
|
+
const entries = [];
|
|
29799
|
+
let dirents;
|
|
29800
|
+
try {
|
|
29801
|
+
dirents = await readdir(directory, { withFileTypes: true });
|
|
29802
|
+
} catch {
|
|
29803
|
+
return entries;
|
|
29804
|
+
}
|
|
29805
|
+
for (const dirent of dirents) {
|
|
29806
|
+
const fullPath = join8(directory, dirent.name);
|
|
29807
|
+
if (dirent.isDirectory()) {
|
|
29808
|
+
entries.push(...await readDir(fullPath));
|
|
29809
|
+
continue;
|
|
29810
|
+
}
|
|
29811
|
+
if (dirent.isFile() && dirent.name.endsWith(COMPOSITE_SUFFIX)) {
|
|
29812
|
+
const raw = await readFile5(fullPath, "utf-8");
|
|
29813
|
+
entries.push({ raw, source: fullPath });
|
|
29814
|
+
}
|
|
29815
|
+
}
|
|
29816
|
+
return entries;
|
|
29817
|
+
}
|
|
29818
|
+
function nodeFsAdapter(...directories) {
|
|
29819
|
+
return async () => {
|
|
29820
|
+
const entries = [];
|
|
29821
|
+
for (const directory of directories) {
|
|
29822
|
+
entries.push(...await readDir(directory));
|
|
29823
|
+
}
|
|
29824
|
+
return entries;
|
|
29825
|
+
};
|
|
29826
|
+
}
|
|
29827
|
+
async function discoverFromDirs(...directories) {
|
|
29828
|
+
const adapter = nodeFsAdapter(...directories);
|
|
29829
|
+
return discoverComposites(await adapter());
|
|
29830
|
+
}
|
|
29831
|
+
|
|
29875
29832
|
// src/utils/workspaces.ts
|
|
29876
29833
|
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
29877
|
-
import { basename, dirname as dirname3, join as
|
|
29834
|
+
import { basename, dirname as dirname3, join as join10, resolve as resolve3 } from "path";
|
|
29878
29835
|
|
|
29879
29836
|
// src/utils/discover.ts
|
|
29880
29837
|
import { existsSync as existsSync4 } from "fs";
|
|
29881
|
-
import { dirname as dirname2, join as
|
|
29838
|
+
import { dirname as dirname2, join as join9, resolve as resolve2 } from "path";
|
|
29882
29839
|
function discoverProjectRoot(startDir) {
|
|
29883
29840
|
let current = resolve2(startDir);
|
|
29884
29841
|
for (; ; ) {
|
|
29885
|
-
const configPath =
|
|
29842
|
+
const configPath = join9(current, ".rafters", "config.rafters.json");
|
|
29886
29843
|
if (existsSync4(configPath)) {
|
|
29887
29844
|
return current;
|
|
29888
29845
|
}
|
|
@@ -29899,14 +29856,14 @@ function findMonorepoRoot(startDir, boundary) {
|
|
|
29899
29856
|
let current = resolve3(startDir);
|
|
29900
29857
|
const stopAt = boundary ? resolve3(boundary) : null;
|
|
29901
29858
|
for (; ; ) {
|
|
29902
|
-
const pnpmWorkspace =
|
|
29859
|
+
const pnpmWorkspace = join10(current, "pnpm-workspace.yaml");
|
|
29903
29860
|
if (existsSync5(pnpmWorkspace)) {
|
|
29904
29861
|
const patterns = parsePnpmWorkspaceYaml(readFileSync2(pnpmWorkspace, "utf-8"));
|
|
29905
29862
|
if (patterns.length > 0) {
|
|
29906
29863
|
return { root: current, patterns };
|
|
29907
29864
|
}
|
|
29908
29865
|
}
|
|
29909
|
-
const pkgJson =
|
|
29866
|
+
const pkgJson = join10(current, "package.json");
|
|
29910
29867
|
if (existsSync5(pkgJson)) {
|
|
29911
29868
|
const patterns = parsePackageJsonWorkspaces(readFileSync2(pkgJson, "utf-8"));
|
|
29912
29869
|
if (patterns.length > 0) {
|
|
@@ -29962,9 +29919,9 @@ function expandPattern(monorepoRoot, pattern) {
|
|
|
29962
29919
|
const trimmed = pattern.replace(/\/+$/, "");
|
|
29963
29920
|
if (trimmed.endsWith("/*")) {
|
|
29964
29921
|
const parentRel = trimmed.slice(0, -2);
|
|
29965
|
-
const parent =
|
|
29922
|
+
const parent = join10(monorepoRoot, parentRel);
|
|
29966
29923
|
if (!existsSync5(parent)) return [];
|
|
29967
|
-
return readdirSync2(parent).map((entry) =>
|
|
29924
|
+
return readdirSync2(parent).map((entry) => join10(parent, entry)).filter((path) => {
|
|
29968
29925
|
try {
|
|
29969
29926
|
return statSync2(path).isDirectory();
|
|
29970
29927
|
} catch {
|
|
@@ -29972,7 +29929,7 @@ function expandPattern(monorepoRoot, pattern) {
|
|
|
29972
29929
|
}
|
|
29973
29930
|
});
|
|
29974
29931
|
}
|
|
29975
|
-
const literal2 =
|
|
29932
|
+
const literal2 = join10(monorepoRoot, trimmed);
|
|
29976
29933
|
if (existsSync5(literal2)) {
|
|
29977
29934
|
try {
|
|
29978
29935
|
if (statSync2(literal2).isDirectory()) return [literal2];
|
|
@@ -29996,13 +29953,13 @@ function discoverWorkspaces(startDir = process.cwd(), options = {}) {
|
|
|
29996
29953
|
for (const dir of expandPattern(layout.root, pattern)) {
|
|
29997
29954
|
if (seen.has(dir)) continue;
|
|
29998
29955
|
seen.add(dir);
|
|
29999
|
-
const config2 =
|
|
29956
|
+
const config2 = join10(dir, ".rafters", "config.rafters.json");
|
|
30000
29957
|
if (existsSync5(config2)) {
|
|
30001
29958
|
workspaces.push({ name: basename(dir), root: dir });
|
|
30002
29959
|
}
|
|
30003
29960
|
}
|
|
30004
29961
|
}
|
|
30005
|
-
const rootConfig =
|
|
29962
|
+
const rootConfig = join10(layout.root, ".rafters", "config.rafters.json");
|
|
30006
29963
|
if (existsSync5(rootConfig) && !seen.has(layout.root)) {
|
|
30007
29964
|
workspaces.unshift({ name: basename(layout.root), root: layout.root });
|
|
30008
29965
|
}
|
|
@@ -30054,29 +30011,6 @@ var TOOL_DEFINITIONS = [
|
|
|
30054
30011
|
required: []
|
|
30055
30012
|
}
|
|
30056
30013
|
},
|
|
30057
|
-
{
|
|
30058
|
-
name: "rafters_rule",
|
|
30059
|
-
description: "Query validation rules or create new ones. Rules are named validation patterns (required, email, password, etc.) that composites can apply.",
|
|
30060
|
-
inputSchema: {
|
|
30061
|
-
type: "object",
|
|
30062
|
-
properties: {
|
|
30063
|
-
...WORKSPACE_PARAM,
|
|
30064
|
-
name: { type: "string", description: "Get a specific rule by name" },
|
|
30065
|
-
query: { type: "string", description: "Search rules by name/description" },
|
|
30066
|
-
create: {
|
|
30067
|
-
type: "object",
|
|
30068
|
-
properties: {
|
|
30069
|
-
name: { type: "string", description: "Rule name (kebab-case)" },
|
|
30070
|
-
description: { type: "string", description: "What this rule validates" },
|
|
30071
|
-
zodSchema: { type: "string", description: "Zod schema as a string" }
|
|
30072
|
-
},
|
|
30073
|
-
required: ["name", "description", "zodSchema"],
|
|
30074
|
-
description: "Create a new rule (provide all three fields)"
|
|
30075
|
-
}
|
|
30076
|
-
},
|
|
30077
|
-
required: []
|
|
30078
|
-
}
|
|
30079
|
-
},
|
|
30080
30014
|
{
|
|
30081
30015
|
name: "rafters_pattern",
|
|
30082
30016
|
description: 'Get design pattern guidance by querying composites. Search by what the pattern solves (e.g., "authentication", "data entry", "navigation") to get do/never rules, cognitive load, and designer intent.',
|
|
@@ -30129,20 +30063,22 @@ var RaftersToolHandler = class {
|
|
|
30129
30063
|
return this.handleWorkspaces();
|
|
30130
30064
|
case "rafters_composite":
|
|
30131
30065
|
return this.handleComposite(args);
|
|
30132
|
-
case "rafters_rule":
|
|
30133
|
-
return this.handleRule(args);
|
|
30134
30066
|
case "rafters_pattern":
|
|
30135
30067
|
return this.handlePattern(args);
|
|
30136
30068
|
case "rafters_component":
|
|
30137
30069
|
return this.handleComponent(args.name);
|
|
30138
|
-
default:
|
|
30139
|
-
const suggestion = name === "rafters_onboard" ? "rafters_onboard was removed. Token import is now a CLI operation: run `rafters init` (auto-detects and prompts) or `rafters import` (standalone)." : "Available tools: rafters_workspaces, rafters_composite, rafters_rule, rafters_pattern, rafters_component.";
|
|
30070
|
+
default:
|
|
30140
30071
|
return {
|
|
30141
30072
|
content: [
|
|
30142
|
-
{
|
|
30073
|
+
{
|
|
30074
|
+
type: "text",
|
|
30075
|
+
text: JSON.stringify({
|
|
30076
|
+
error: `Unknown tool: ${name}`,
|
|
30077
|
+
suggestion: "Available tools: rafters_workspaces, rafters_composite, rafters_pattern, rafters_component."
|
|
30078
|
+
})
|
|
30079
|
+
}
|
|
30143
30080
|
]
|
|
30144
30081
|
};
|
|
30145
|
-
}
|
|
30146
30082
|
}
|
|
30147
30083
|
}
|
|
30148
30084
|
/**
|
|
@@ -30193,42 +30129,30 @@ var RaftersToolHandler = class {
|
|
|
30193
30129
|
]
|
|
30194
30130
|
};
|
|
30195
30131
|
}
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30199
|
-
|
|
30200
|
-
|
|
30201
|
-
|
|
30202
|
-
|
|
30203
|
-
|
|
30204
|
-
|
|
30205
|
-
|
|
30206
|
-
|
|
30207
|
-
|
|
30208
|
-
register2(result.data);
|
|
30209
|
-
} catch {
|
|
30210
|
-
}
|
|
30211
|
-
}
|
|
30212
|
-
} catch {
|
|
30213
|
-
}
|
|
30132
|
+
/**
|
|
30133
|
+
* Recursively discover composites under the given directories via the shared
|
|
30134
|
+
* discovery core (node-fs adapter), then register each into the in-memory
|
|
30135
|
+
* registry. Duplicate ids -- across this call or against already-registered
|
|
30136
|
+
* composites -- are ignored: the first registration wins.
|
|
30137
|
+
*/
|
|
30138
|
+
async loadCompositesFromDirs(...dirs) {
|
|
30139
|
+
const { registry: registry2 } = await discoverFromDirs(...dirs);
|
|
30140
|
+
for (const composite of registry2.values()) {
|
|
30141
|
+
try {
|
|
30142
|
+
register2(composite);
|
|
30143
|
+
} catch {
|
|
30214
30144
|
}
|
|
30215
|
-
} catch {
|
|
30216
30145
|
}
|
|
30217
30146
|
}
|
|
30218
30147
|
async ensureCompositesLoaded(workspace) {
|
|
30219
30148
|
if (!this.builtInCompositesLoaded) {
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
|
|
30223
|
-
join10(process.cwd(), "node_modules/@rafters/composites/src", dir)
|
|
30224
|
-
);
|
|
30225
|
-
}
|
|
30149
|
+
await this.loadCompositesFromDirs(
|
|
30150
|
+
join11(process.cwd(), "node_modules/@rafters/composites/src/typography")
|
|
30151
|
+
);
|
|
30226
30152
|
this.builtInCompositesLoaded = true;
|
|
30227
30153
|
}
|
|
30228
30154
|
if (workspace && !this.compositesLoadedFor.has(workspace.root)) {
|
|
30229
|
-
|
|
30230
|
-
await this.loadCompositesFromDir(dir);
|
|
30231
|
-
}
|
|
30155
|
+
await this.loadCompositesFromDirs(...await this.compositeReadRoots(workspace.root));
|
|
30232
30156
|
this.compositesLoadedFor.add(workspace.root);
|
|
30233
30157
|
}
|
|
30234
30158
|
}
|
|
@@ -30243,11 +30167,11 @@ var RaftersToolHandler = class {
|
|
|
30243
30167
|
const paths = getRaftersPaths(workspaceRoot);
|
|
30244
30168
|
let config2 = null;
|
|
30245
30169
|
try {
|
|
30246
|
-
config2 = JSON.parse(await
|
|
30170
|
+
config2 = JSON.parse(await readFile6(paths.config, "utf-8"));
|
|
30247
30171
|
} catch {
|
|
30248
30172
|
}
|
|
30249
30173
|
if (!config2?.compositesPath) {
|
|
30250
|
-
return [
|
|
30174
|
+
return [join11(paths.root, "composites")];
|
|
30251
30175
|
}
|
|
30252
30176
|
return resolveReadSet(config2.compositesPath, workspaceRoot);
|
|
30253
30177
|
}
|
|
@@ -30280,49 +30204,15 @@ var RaftersToolHandler = class {
|
|
|
30280
30204
|
usagePatterns: c4.manifest.usagePatterns,
|
|
30281
30205
|
input: c4.input,
|
|
30282
30206
|
output: c4.output,
|
|
30283
|
-
blockCount: c4.blocks.length
|
|
30207
|
+
blockCount: c4.blocks.length,
|
|
30208
|
+
// Surface which blocks carry which validation rules. Rules compile to
|
|
30209
|
+
// native HTML5 constraint attributes at build, so agents need to see
|
|
30210
|
+
// them to reason about a composite's behavior. Only blocks with rules
|
|
30211
|
+
// are listed -- the array is empty when nothing is constrained.
|
|
30212
|
+
blockRules: c4.blocks.filter((b2) => b2.rules && b2.rules.length > 0).map((b2) => ({ id: b2.id, type: b2.type, rules: b2.rules }))
|
|
30284
30213
|
}));
|
|
30285
30214
|
return { content: [{ type: "text", text: JSON.stringify({ composites: result }, null, 2) }] };
|
|
30286
30215
|
}
|
|
30287
|
-
async handleRule(args) {
|
|
30288
|
-
const { name, query, create } = args;
|
|
30289
|
-
const builtInRules = [
|
|
30290
|
-
{ name: "required", description: "Field must have a value", source: "registry" },
|
|
30291
|
-
{ name: "email", description: "Must be a valid email address", source: "registry" },
|
|
30292
|
-
{
|
|
30293
|
-
name: "password",
|
|
30294
|
-
description: "Password strength requirements",
|
|
30295
|
-
source: "registry"
|
|
30296
|
-
},
|
|
30297
|
-
{ name: "url", description: "Must be a valid URL", source: "registry" },
|
|
30298
|
-
{
|
|
30299
|
-
name: "credentials",
|
|
30300
|
-
description: "Combined username/password validation",
|
|
30301
|
-
source: "registry"
|
|
30302
|
-
}
|
|
30303
|
-
];
|
|
30304
|
-
if (create) {
|
|
30305
|
-
return {
|
|
30306
|
-
content: [
|
|
30307
|
-
{
|
|
30308
|
-
type: "text",
|
|
30309
|
-
text: JSON.stringify({
|
|
30310
|
-
error: "Rule creation not yet implemented",
|
|
30311
|
-
suggestion: "Rules will be written to .rafters/rules/<name>.ts"
|
|
30312
|
-
})
|
|
30313
|
-
}
|
|
30314
|
-
]
|
|
30315
|
-
};
|
|
30316
|
-
}
|
|
30317
|
-
let rules = builtInRules;
|
|
30318
|
-
if (name) {
|
|
30319
|
-
rules = rules.filter((r) => r.name === name);
|
|
30320
|
-
} else if (query) {
|
|
30321
|
-
const q = query.toLowerCase();
|
|
30322
|
-
rules = rules.filter((r) => r.name.includes(q) || r.description.toLowerCase().includes(q));
|
|
30323
|
-
}
|
|
30324
|
-
return { content: [{ type: "text", text: JSON.stringify({ rules }, null, 2) }] };
|
|
30325
|
-
}
|
|
30326
30216
|
async handlePattern(args) {
|
|
30327
30217
|
const { solves, query, workspace } = args;
|
|
30328
30218
|
const resolved = this.resolve(workspace);
|
|
@@ -30462,7 +30352,7 @@ async function mcp(options) {
|
|
|
30462
30352
|
let defaultWorkspace;
|
|
30463
30353
|
if (options.projectRoot) {
|
|
30464
30354
|
const explicit = resolve4(options.projectRoot);
|
|
30465
|
-
const configPath =
|
|
30355
|
+
const configPath = join12(explicit, ".rafters", "config.rafters.json");
|
|
30466
30356
|
if (!existsSync6(configPath)) {
|
|
30467
30357
|
process.stderr.write(
|
|
30468
30358
|
`--project-root ${explicit} does not contain .rafters/config.rafters.json
|
|
@@ -30488,7 +30378,7 @@ import { resolve as resolve5 } from "path";
|
|
|
30488
30378
|
|
|
30489
30379
|
// ../studio/src/api/vite-plugin.ts
|
|
30490
30380
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
30491
|
-
import { join as
|
|
30381
|
+
import { join as join13 } from "path";
|
|
30492
30382
|
var REGISTRY_PLUGINS2 = [scalePlugin, contrastPlugin, statePlugin, invertPlugin];
|
|
30493
30383
|
var STUDIO_REASON_DEFAULT = "studio interactive edit";
|
|
30494
30384
|
var TokenResponseSchema = external_exports.object({
|
|
@@ -30514,7 +30404,7 @@ var ColorBuildOptionsSchema = external_exports.object({
|
|
|
30514
30404
|
states: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
30515
30405
|
});
|
|
30516
30406
|
var projectPath = process.env.RAFTERS_PROJECT_PATH || process.cwd();
|
|
30517
|
-
var outputPath =
|
|
30407
|
+
var outputPath = join13(projectPath, ".rafters", "output", "rafters.css");
|
|
30518
30408
|
var SetTokenMessageSchema = external_exports.object({
|
|
30519
30409
|
name: external_exports.string().min(1),
|
|
30520
30410
|
value: external_exports.union([external_exports.string(), ColorValueSchema, ColorReferenceSchema]),
|
|
@@ -30884,7 +30774,7 @@ function studioApiPlugin() {
|
|
|
30884
30774
|
return {
|
|
30885
30775
|
name: "rafters-studio-api",
|
|
30886
30776
|
async configureServer(server) {
|
|
30887
|
-
const tokensDir =
|
|
30777
|
+
const tokensDir = join13(projectPath, ".rafters", "tokens");
|
|
30888
30778
|
try {
|
|
30889
30779
|
registry2 = loadRegistryFromDir(tokensDir, REGISTRY_PLUGINS2);
|
|
30890
30780
|
initialized = true;
|
|
@@ -30902,7 +30792,7 @@ function studioApiPlugin() {
|
|
|
30902
30792
|
if (initialized) {
|
|
30903
30793
|
saveRegistryToDir(tokensDir, registry2);
|
|
30904
30794
|
}
|
|
30905
|
-
await writeFile3(outputPath,
|
|
30795
|
+
await writeFile3(outputPath, registryToTailwind(registry2));
|
|
30906
30796
|
server.ws.send({ type: "custom", event: "rafters:css-updated" });
|
|
30907
30797
|
} catch (error47) {
|
|
30908
30798
|
console.log(`[rafters] CSS regeneration failed: ${error47}`);
|
package/dist/registry/types.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare const RegistryItemTypeSchema: z.ZodEnum<{
|
|
|
25
25
|
ui: "ui";
|
|
26
26
|
primitive: "primitive";
|
|
27
27
|
composite: "composite";
|
|
28
|
+
rule: "rule";
|
|
28
29
|
}>;
|
|
29
30
|
type RegistryItemType = z.infer<typeof RegistryItemTypeSchema>;
|
|
30
31
|
/**
|
|
@@ -57,6 +58,7 @@ declare const RegistryItemSchema: z.ZodObject<{
|
|
|
57
58
|
ui: "ui";
|
|
58
59
|
primitive: "primitive";
|
|
59
60
|
composite: "composite";
|
|
61
|
+
rule: "rule";
|
|
60
62
|
}>;
|
|
61
63
|
description: z.ZodOptional<z.ZodString>;
|
|
62
64
|
primitives: z.ZodArray<z.ZodString>;
|
package/dist/registry/types.js
CHANGED
|
@@ -8,7 +8,7 @@ var RegistryFileSchema = z.object({
|
|
|
8
8
|
devDependencies: z.array(z.string()).default([])
|
|
9
9
|
// e.g., ["vitest"] - from @devDependencies JSDoc
|
|
10
10
|
});
|
|
11
|
-
var RegistryItemTypeSchema = z.enum(["ui", "primitive", "composite"]);
|
|
11
|
+
var RegistryItemTypeSchema = z.enum(["ui", "primitive", "composite", "rule"]);
|
|
12
12
|
var RegistryItemIntelligenceSchema = z.object({
|
|
13
13
|
cognitiveLoad: z.number().optional(),
|
|
14
14
|
attentionEconomics: z.string().optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rafters",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.70",
|
|
4
4
|
"description": "Design Intelligence CLI. Scaffold tokens, import existing shadcn/Tailwind v4 sources, add components, and serve an MCP server so AI agents read decisions instead of guessing.",
|
|
5
5
|
"homepage": "https://rafters.studio",
|
|
6
6
|
"license": "MIT",
|