rafters 0.0.69 → 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 +281 -261
- 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;
|
|
12726
|
+
return RegistryIndexSchema.parse(await response.json());
|
|
12712
12727
|
}
|
|
12713
12728
|
/**
|
|
12714
|
-
* Fetch a
|
|
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;
|
|
12760
|
-
}
|
|
12761
|
-
/**
|
|
12762
|
-
* Fetch a registry item by name
|
|
12763
|
-
* Tries component, then primitive, then composite
|
|
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;
|
|
@@ -22868,7 +22858,7 @@ async function registryToCompiled(registry2, options = {}) {
|
|
|
22868
22858
|
const themeCss = registryToTailwind(registry2, { includeImport });
|
|
22869
22859
|
const { execFileSync } = await import("child_process");
|
|
22870
22860
|
const { mkdtempSync, writeFileSync: writeFileSync2, readFileSync: readFileSync3, rmSync } = await import("fs");
|
|
22871
|
-
const { join:
|
|
22861
|
+
const { join: join14, dirname: dirname4 } = await import("path");
|
|
22872
22862
|
const { createRequire: createRequire2 } = await import("module");
|
|
22873
22863
|
const require2 = createRequire2(import.meta.url);
|
|
22874
22864
|
let pkgDir;
|
|
@@ -22878,10 +22868,10 @@ async function registryToCompiled(registry2, options = {}) {
|
|
|
22878
22868
|
} catch {
|
|
22879
22869
|
throw new Error("Failed to resolve @tailwindcss/cli");
|
|
22880
22870
|
}
|
|
22881
|
-
const binPath =
|
|
22882
|
-
const tempDir = mkdtempSync(
|
|
22883
|
-
const tempInput =
|
|
22884
|
-
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");
|
|
22885
22875
|
try {
|
|
22886
22876
|
writeFileSync2(tempInput, themeCss);
|
|
22887
22877
|
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
@@ -24233,12 +24223,12 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
24233
24223
|
never: ["Use for dividers within cards"]
|
|
24234
24224
|
},
|
|
24235
24225
|
panel: {
|
|
24236
|
-
light: { family: "neutral", position: "
|
|
24226
|
+
light: { family: "neutral", position: "200" },
|
|
24237
24227
|
dark: { family: "neutral", position: "800" },
|
|
24238
|
-
meaning: "
|
|
24228
|
+
meaning: "Persistent elevated chrome -- headers, docks, fixed toolbars",
|
|
24239
24229
|
contexts: ["panels", "toolbars", "headers", "docks"],
|
|
24240
24230
|
do: ["Use for persistent elevated chrome", "Pair with panel-foreground"],
|
|
24241
|
-
never: ["Use for page-level backgrounds", "
|
|
24231
|
+
never: ["Use for page-level backgrounds", "Use for transient surfaces"]
|
|
24242
24232
|
},
|
|
24243
24233
|
"panel-foreground": {
|
|
24244
24234
|
light: { family: "neutral", position: "950" },
|
|
@@ -24291,12 +24281,12 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
24291
24281
|
},
|
|
24292
24282
|
// Generic surface
|
|
24293
24283
|
surface: {
|
|
24294
|
-
light: { family: "neutral", position: "
|
|
24284
|
+
light: { family: "neutral", position: "100" },
|
|
24295
24285
|
dark: { family: "neutral", position: "900" },
|
|
24296
|
-
meaning: "
|
|
24297
|
-
contexts: ["
|
|
24298
|
-
do: ["Use for
|
|
24299
|
-
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"]
|
|
24300
24290
|
},
|
|
24301
24291
|
"surface-foreground": {
|
|
24302
24292
|
light: { family: "neutral", position: "950" },
|
|
@@ -25381,9 +25371,9 @@ var DEFAULT_SEMANTIC_COLOR_MAPPINGS = {
|
|
|
25381
25371
|
// SIDEBAR TOKENS (shadcn compatible + extended)
|
|
25382
25372
|
// ============================================================================
|
|
25383
25373
|
sidebar: {
|
|
25384
|
-
light: { family: "neutral", position: "
|
|
25374
|
+
light: { family: "neutral", position: "100" },
|
|
25385
25375
|
dark: { family: "neutral", position: "900" },
|
|
25386
|
-
meaning: "Sidebar background",
|
|
25376
|
+
meaning: "Sidebar background -- almost on the surface",
|
|
25387
25377
|
contexts: ["navigation-sidebar", "side-panels"],
|
|
25388
25378
|
do: ["Use for sidebar backgrounds"],
|
|
25389
25379
|
never: ["Use for main content areas"]
|
|
@@ -27043,7 +27033,7 @@ function generateRadiusTokens(config2, radiusDefs) {
|
|
|
27043
27033
|
|
|
27044
27034
|
// ../design-tokens/src/generators/semantic.ts
|
|
27045
27035
|
var FOREGROUND_SUFFIXES = ["-foreground", "-text", "-contrast"];
|
|
27046
|
-
var STATE_SUFFIXES =
|
|
27036
|
+
var STATE_SUFFIXES = STATE_USES.map((s) => `-${s}`);
|
|
27047
27037
|
function toColorRef(mapping) {
|
|
27048
27038
|
return { family: mapping.light.family, position: mapping.light.position };
|
|
27049
27039
|
}
|
|
@@ -28744,7 +28734,7 @@ var scalePlugin = definePlugin({
|
|
|
28744
28734
|
});
|
|
28745
28735
|
|
|
28746
28736
|
// ../design-tokens/src/plugins/state.ts
|
|
28747
|
-
var StateTypeSchema = external_exports.enum(
|
|
28737
|
+
var StateTypeSchema = external_exports.enum(STATE_USES);
|
|
28748
28738
|
var StateInputSchema = external_exports.object({
|
|
28749
28739
|
from: external_exports.string(),
|
|
28750
28740
|
stateType: StateTypeSchema
|
|
@@ -29618,7 +29608,7 @@ async function init(options) {
|
|
|
29618
29608
|
|
|
29619
29609
|
// src/commands/mcp.ts
|
|
29620
29610
|
import { existsSync as existsSync6 } from "fs";
|
|
29621
|
-
import { basename as basename2, join as
|
|
29611
|
+
import { basename as basename2, join as join12, resolve as resolve4 } from "path";
|
|
29622
29612
|
|
|
29623
29613
|
// src/mcp/server.ts
|
|
29624
29614
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -29626,8 +29616,8 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
29626
29616
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
29627
29617
|
|
|
29628
29618
|
// src/mcp/tools.ts
|
|
29629
|
-
import {
|
|
29630
|
-
import { join as
|
|
29619
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
29620
|
+
import { join as join11 } from "path";
|
|
29631
29621
|
|
|
29632
29622
|
// ../composites/src/built-in-rules/email.ts
|
|
29633
29623
|
var email3 = external_exports.string().email();
|
|
@@ -29656,6 +29646,10 @@ var AppliedRuleSchema = external_exports.union([
|
|
|
29656
29646
|
var CompositeBlockSchema = external_exports.object({
|
|
29657
29647
|
id: external_exports.string().min(1),
|
|
29658
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(),
|
|
29659
29653
|
content: external_exports.unknown().optional(),
|
|
29660
29654
|
children: external_exports.array(external_exports.string()).optional(),
|
|
29661
29655
|
parentId: external_exports.string().optional(),
|
|
@@ -29685,6 +29679,60 @@ var CompositeFileSchema = external_exports.object({
|
|
|
29685
29679
|
blocks: external_exports.array(CompositeBlockSchema).min(1)
|
|
29686
29680
|
});
|
|
29687
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
|
+
|
|
29688
29736
|
// ../ui/src/primitives/typeahead.ts
|
|
29689
29737
|
function fuzzyScore(query, target) {
|
|
29690
29738
|
if (query.length === 0) return 1;
|
|
@@ -29742,17 +29790,56 @@ function search(query) {
|
|
|
29742
29790
|
// ../composites/src/to-mdx.ts
|
|
29743
29791
|
var import_escape_html = __toESM(require_escape_html(), 1);
|
|
29744
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
|
+
|
|
29745
29832
|
// src/utils/workspaces.ts
|
|
29746
29833
|
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
29747
|
-
import { basename, dirname as dirname3, join as
|
|
29834
|
+
import { basename, dirname as dirname3, join as join10, resolve as resolve3 } from "path";
|
|
29748
29835
|
|
|
29749
29836
|
// src/utils/discover.ts
|
|
29750
29837
|
import { existsSync as existsSync4 } from "fs";
|
|
29751
|
-
import { dirname as dirname2, join as
|
|
29838
|
+
import { dirname as dirname2, join as join9, resolve as resolve2 } from "path";
|
|
29752
29839
|
function discoverProjectRoot(startDir) {
|
|
29753
29840
|
let current = resolve2(startDir);
|
|
29754
29841
|
for (; ; ) {
|
|
29755
|
-
const configPath =
|
|
29842
|
+
const configPath = join9(current, ".rafters", "config.rafters.json");
|
|
29756
29843
|
if (existsSync4(configPath)) {
|
|
29757
29844
|
return current;
|
|
29758
29845
|
}
|
|
@@ -29769,14 +29856,14 @@ function findMonorepoRoot(startDir, boundary) {
|
|
|
29769
29856
|
let current = resolve3(startDir);
|
|
29770
29857
|
const stopAt = boundary ? resolve3(boundary) : null;
|
|
29771
29858
|
for (; ; ) {
|
|
29772
|
-
const pnpmWorkspace =
|
|
29859
|
+
const pnpmWorkspace = join10(current, "pnpm-workspace.yaml");
|
|
29773
29860
|
if (existsSync5(pnpmWorkspace)) {
|
|
29774
29861
|
const patterns = parsePnpmWorkspaceYaml(readFileSync2(pnpmWorkspace, "utf-8"));
|
|
29775
29862
|
if (patterns.length > 0) {
|
|
29776
29863
|
return { root: current, patterns };
|
|
29777
29864
|
}
|
|
29778
29865
|
}
|
|
29779
|
-
const pkgJson =
|
|
29866
|
+
const pkgJson = join10(current, "package.json");
|
|
29780
29867
|
if (existsSync5(pkgJson)) {
|
|
29781
29868
|
const patterns = parsePackageJsonWorkspaces(readFileSync2(pkgJson, "utf-8"));
|
|
29782
29869
|
if (patterns.length > 0) {
|
|
@@ -29832,9 +29919,9 @@ function expandPattern(monorepoRoot, pattern) {
|
|
|
29832
29919
|
const trimmed = pattern.replace(/\/+$/, "");
|
|
29833
29920
|
if (trimmed.endsWith("/*")) {
|
|
29834
29921
|
const parentRel = trimmed.slice(0, -2);
|
|
29835
|
-
const parent =
|
|
29922
|
+
const parent = join10(monorepoRoot, parentRel);
|
|
29836
29923
|
if (!existsSync5(parent)) return [];
|
|
29837
|
-
return readdirSync2(parent).map((entry) =>
|
|
29924
|
+
return readdirSync2(parent).map((entry) => join10(parent, entry)).filter((path) => {
|
|
29838
29925
|
try {
|
|
29839
29926
|
return statSync2(path).isDirectory();
|
|
29840
29927
|
} catch {
|
|
@@ -29842,7 +29929,7 @@ function expandPattern(monorepoRoot, pattern) {
|
|
|
29842
29929
|
}
|
|
29843
29930
|
});
|
|
29844
29931
|
}
|
|
29845
|
-
const literal2 =
|
|
29932
|
+
const literal2 = join10(monorepoRoot, trimmed);
|
|
29846
29933
|
if (existsSync5(literal2)) {
|
|
29847
29934
|
try {
|
|
29848
29935
|
if (statSync2(literal2).isDirectory()) return [literal2];
|
|
@@ -29866,13 +29953,13 @@ function discoverWorkspaces(startDir = process.cwd(), options = {}) {
|
|
|
29866
29953
|
for (const dir of expandPattern(layout.root, pattern)) {
|
|
29867
29954
|
if (seen.has(dir)) continue;
|
|
29868
29955
|
seen.add(dir);
|
|
29869
|
-
const config2 =
|
|
29956
|
+
const config2 = join10(dir, ".rafters", "config.rafters.json");
|
|
29870
29957
|
if (existsSync5(config2)) {
|
|
29871
29958
|
workspaces.push({ name: basename(dir), root: dir });
|
|
29872
29959
|
}
|
|
29873
29960
|
}
|
|
29874
29961
|
}
|
|
29875
|
-
const rootConfig =
|
|
29962
|
+
const rootConfig = join10(layout.root, ".rafters", "config.rafters.json");
|
|
29876
29963
|
if (existsSync5(rootConfig) && !seen.has(layout.root)) {
|
|
29877
29964
|
workspaces.unshift({ name: basename(layout.root), root: layout.root });
|
|
29878
29965
|
}
|
|
@@ -29924,29 +30011,6 @@ var TOOL_DEFINITIONS = [
|
|
|
29924
30011
|
required: []
|
|
29925
30012
|
}
|
|
29926
30013
|
},
|
|
29927
|
-
{
|
|
29928
|
-
name: "rafters_rule",
|
|
29929
|
-
description: "Query validation rules or create new ones. Rules are named validation patterns (required, email, password, etc.) that composites can apply.",
|
|
29930
|
-
inputSchema: {
|
|
29931
|
-
type: "object",
|
|
29932
|
-
properties: {
|
|
29933
|
-
...WORKSPACE_PARAM,
|
|
29934
|
-
name: { type: "string", description: "Get a specific rule by name" },
|
|
29935
|
-
query: { type: "string", description: "Search rules by name/description" },
|
|
29936
|
-
create: {
|
|
29937
|
-
type: "object",
|
|
29938
|
-
properties: {
|
|
29939
|
-
name: { type: "string", description: "Rule name (kebab-case)" },
|
|
29940
|
-
description: { type: "string", description: "What this rule validates" },
|
|
29941
|
-
zodSchema: { type: "string", description: "Zod schema as a string" }
|
|
29942
|
-
},
|
|
29943
|
-
required: ["name", "description", "zodSchema"],
|
|
29944
|
-
description: "Create a new rule (provide all three fields)"
|
|
29945
|
-
}
|
|
29946
|
-
},
|
|
29947
|
-
required: []
|
|
29948
|
-
}
|
|
29949
|
-
},
|
|
29950
30014
|
{
|
|
29951
30015
|
name: "rafters_pattern",
|
|
29952
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.',
|
|
@@ -29999,20 +30063,22 @@ var RaftersToolHandler = class {
|
|
|
29999
30063
|
return this.handleWorkspaces();
|
|
30000
30064
|
case "rafters_composite":
|
|
30001
30065
|
return this.handleComposite(args);
|
|
30002
|
-
case "rafters_rule":
|
|
30003
|
-
return this.handleRule(args);
|
|
30004
30066
|
case "rafters_pattern":
|
|
30005
30067
|
return this.handlePattern(args);
|
|
30006
30068
|
case "rafters_component":
|
|
30007
30069
|
return this.handleComponent(args.name);
|
|
30008
|
-
default:
|
|
30009
|
-
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:
|
|
30010
30071
|
return {
|
|
30011
30072
|
content: [
|
|
30012
|
-
{
|
|
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
|
+
}
|
|
30013
30080
|
]
|
|
30014
30081
|
};
|
|
30015
|
-
}
|
|
30016
30082
|
}
|
|
30017
30083
|
}
|
|
30018
30084
|
/**
|
|
@@ -30063,42 +30129,30 @@ var RaftersToolHandler = class {
|
|
|
30063
30129
|
]
|
|
30064
30130
|
};
|
|
30065
30131
|
}
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
30071
|
-
|
|
30072
|
-
|
|
30073
|
-
|
|
30074
|
-
|
|
30075
|
-
|
|
30076
|
-
|
|
30077
|
-
|
|
30078
|
-
register2(result.data);
|
|
30079
|
-
} catch {
|
|
30080
|
-
}
|
|
30081
|
-
}
|
|
30082
|
-
} catch {
|
|
30083
|
-
}
|
|
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 {
|
|
30084
30144
|
}
|
|
30085
|
-
} catch {
|
|
30086
30145
|
}
|
|
30087
30146
|
}
|
|
30088
30147
|
async ensureCompositesLoaded(workspace) {
|
|
30089
30148
|
if (!this.builtInCompositesLoaded) {
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
30093
|
-
join10(process.cwd(), "node_modules/@rafters/composites/src", dir)
|
|
30094
|
-
);
|
|
30095
|
-
}
|
|
30149
|
+
await this.loadCompositesFromDirs(
|
|
30150
|
+
join11(process.cwd(), "node_modules/@rafters/composites/src/typography")
|
|
30151
|
+
);
|
|
30096
30152
|
this.builtInCompositesLoaded = true;
|
|
30097
30153
|
}
|
|
30098
30154
|
if (workspace && !this.compositesLoadedFor.has(workspace.root)) {
|
|
30099
|
-
|
|
30100
|
-
await this.loadCompositesFromDir(dir);
|
|
30101
|
-
}
|
|
30155
|
+
await this.loadCompositesFromDirs(...await this.compositeReadRoots(workspace.root));
|
|
30102
30156
|
this.compositesLoadedFor.add(workspace.root);
|
|
30103
30157
|
}
|
|
30104
30158
|
}
|
|
@@ -30113,11 +30167,11 @@ var RaftersToolHandler = class {
|
|
|
30113
30167
|
const paths = getRaftersPaths(workspaceRoot);
|
|
30114
30168
|
let config2 = null;
|
|
30115
30169
|
try {
|
|
30116
|
-
config2 = JSON.parse(await
|
|
30170
|
+
config2 = JSON.parse(await readFile6(paths.config, "utf-8"));
|
|
30117
30171
|
} catch {
|
|
30118
30172
|
}
|
|
30119
30173
|
if (!config2?.compositesPath) {
|
|
30120
|
-
return [
|
|
30174
|
+
return [join11(paths.root, "composites")];
|
|
30121
30175
|
}
|
|
30122
30176
|
return resolveReadSet(config2.compositesPath, workspaceRoot);
|
|
30123
30177
|
}
|
|
@@ -30150,49 +30204,15 @@ var RaftersToolHandler = class {
|
|
|
30150
30204
|
usagePatterns: c4.manifest.usagePatterns,
|
|
30151
30205
|
input: c4.input,
|
|
30152
30206
|
output: c4.output,
|
|
30153
|
-
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 }))
|
|
30154
30213
|
}));
|
|
30155
30214
|
return { content: [{ type: "text", text: JSON.stringify({ composites: result }, null, 2) }] };
|
|
30156
30215
|
}
|
|
30157
|
-
async handleRule(args) {
|
|
30158
|
-
const { name, query, create } = args;
|
|
30159
|
-
const builtInRules = [
|
|
30160
|
-
{ name: "required", description: "Field must have a value", source: "registry" },
|
|
30161
|
-
{ name: "email", description: "Must be a valid email address", source: "registry" },
|
|
30162
|
-
{
|
|
30163
|
-
name: "password",
|
|
30164
|
-
description: "Password strength requirements",
|
|
30165
|
-
source: "registry"
|
|
30166
|
-
},
|
|
30167
|
-
{ name: "url", description: "Must be a valid URL", source: "registry" },
|
|
30168
|
-
{
|
|
30169
|
-
name: "credentials",
|
|
30170
|
-
description: "Combined username/password validation",
|
|
30171
|
-
source: "registry"
|
|
30172
|
-
}
|
|
30173
|
-
];
|
|
30174
|
-
if (create) {
|
|
30175
|
-
return {
|
|
30176
|
-
content: [
|
|
30177
|
-
{
|
|
30178
|
-
type: "text",
|
|
30179
|
-
text: JSON.stringify({
|
|
30180
|
-
error: "Rule creation not yet implemented",
|
|
30181
|
-
suggestion: "Rules will be written to .rafters/rules/<name>.ts"
|
|
30182
|
-
})
|
|
30183
|
-
}
|
|
30184
|
-
]
|
|
30185
|
-
};
|
|
30186
|
-
}
|
|
30187
|
-
let rules = builtInRules;
|
|
30188
|
-
if (name) {
|
|
30189
|
-
rules = rules.filter((r) => r.name === name);
|
|
30190
|
-
} else if (query) {
|
|
30191
|
-
const q = query.toLowerCase();
|
|
30192
|
-
rules = rules.filter((r) => r.name.includes(q) || r.description.toLowerCase().includes(q));
|
|
30193
|
-
}
|
|
30194
|
-
return { content: [{ type: "text", text: JSON.stringify({ rules }, null, 2) }] };
|
|
30195
|
-
}
|
|
30196
30216
|
async handlePattern(args) {
|
|
30197
30217
|
const { solves, query, workspace } = args;
|
|
30198
30218
|
const resolved = this.resolve(workspace);
|
|
@@ -30332,7 +30352,7 @@ async function mcp(options) {
|
|
|
30332
30352
|
let defaultWorkspace;
|
|
30333
30353
|
if (options.projectRoot) {
|
|
30334
30354
|
const explicit = resolve4(options.projectRoot);
|
|
30335
|
-
const configPath =
|
|
30355
|
+
const configPath = join12(explicit, ".rafters", "config.rafters.json");
|
|
30336
30356
|
if (!existsSync6(configPath)) {
|
|
30337
30357
|
process.stderr.write(
|
|
30338
30358
|
`--project-root ${explicit} does not contain .rafters/config.rafters.json
|
|
@@ -30358,7 +30378,7 @@ import { resolve as resolve5 } from "path";
|
|
|
30358
30378
|
|
|
30359
30379
|
// ../studio/src/api/vite-plugin.ts
|
|
30360
30380
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
30361
|
-
import { join as
|
|
30381
|
+
import { join as join13 } from "path";
|
|
30362
30382
|
var REGISTRY_PLUGINS2 = [scalePlugin, contrastPlugin, statePlugin, invertPlugin];
|
|
30363
30383
|
var STUDIO_REASON_DEFAULT = "studio interactive edit";
|
|
30364
30384
|
var TokenResponseSchema = external_exports.object({
|
|
@@ -30384,7 +30404,7 @@ var ColorBuildOptionsSchema = external_exports.object({
|
|
|
30384
30404
|
states: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
30385
30405
|
});
|
|
30386
30406
|
var projectPath = process.env.RAFTERS_PROJECT_PATH || process.cwd();
|
|
30387
|
-
var outputPath =
|
|
30407
|
+
var outputPath = join13(projectPath, ".rafters", "output", "rafters.css");
|
|
30388
30408
|
var SetTokenMessageSchema = external_exports.object({
|
|
30389
30409
|
name: external_exports.string().min(1),
|
|
30390
30410
|
value: external_exports.union([external_exports.string(), ColorValueSchema, ColorReferenceSchema]),
|
|
@@ -30754,7 +30774,7 @@ function studioApiPlugin() {
|
|
|
30754
30774
|
return {
|
|
30755
30775
|
name: "rafters-studio-api",
|
|
30756
30776
|
async configureServer(server) {
|
|
30757
|
-
const tokensDir =
|
|
30777
|
+
const tokensDir = join13(projectPath, ".rafters", "tokens");
|
|
30758
30778
|
try {
|
|
30759
30779
|
registry2 = loadRegistryFromDir(tokensDir, REGISTRY_PLUGINS2);
|
|
30760
30780
|
initialized = true;
|
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",
|