rafters 0.0.31 → 0.0.33

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.
Files changed (2) hide show
  1. package/dist/index.js +123 -27
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13431,30 +13431,33 @@ function transformFileContent(content, config3, fileType = "component") {
13431
13431
  let transformed = content;
13432
13432
  const componentsPath = config3?.componentsPath ?? "components/ui";
13433
13433
  const primitivesPath = config3?.primitivesPath ?? "lib/primitives";
13434
+ const stripSourceRoot = (p2) => p2.replace(/^(src|app)\//, "");
13435
+ const aliasComponents = stripSourceRoot(componentsPath);
13436
+ const aliasPrimitives = stripSourceRoot(primitivesPath);
13434
13437
  transformed = transformed.replace(
13435
13438
  /from\s+['"]\.\.\/\.\.\/primitives\/([^'"]+)['"]/g,
13436
- `from '@/${primitivesPath}/$1'`
13439
+ `from '@/${aliasPrimitives}/$1'`
13437
13440
  );
13438
13441
  transformed = transformed.replace(
13439
13442
  /from\s+['"]\.\.\/primitives\/([^'"]+)['"]/g,
13440
- `from '@/${primitivesPath}/$1'`
13443
+ `from '@/${aliasPrimitives}/$1'`
13441
13444
  );
13442
- const siblingPath = fileType === "primitive" ? primitivesPath : componentsPath;
13443
- transformed = transformed.replace(/from\s+['"]\.\/([^'"]+)['"]/g, `from '@/${siblingPath}/$1'`);
13444
- const libPath = dirname(primitivesPath);
13445
+ const aliasSibling = fileType === "primitive" ? aliasPrimitives : aliasComponents;
13446
+ transformed = transformed.replace(/from\s+['"]\.\/([^'"]+)['"]/g, `from '@/${aliasSibling}/$1'`);
13447
+ const aliasLib = stripSourceRoot(dirname(primitivesPath));
13445
13448
  transformed = transformed.replace(
13446
13449
  /from\s+['"]\.\.\/lib\/([^'"]+)['"]/g,
13447
- `from '@/${libPath}/$1'`
13450
+ `from '@/${aliasLib}/$1'`
13448
13451
  );
13449
- const componentsMatch = componentsPath.match(/^(.*)components\/ui$/);
13450
- const hooksPath = componentsMatch ? `${componentsMatch[1]}hooks`.replace(/^\//, "") : "hooks";
13452
+ const componentsMatch = aliasComponents.match(/^(.*)components\/ui$/);
13453
+ const aliasHooks = componentsMatch ? `${componentsMatch[1]}hooks`.replace(/^\//, "") : "hooks";
13451
13454
  transformed = transformed.replace(
13452
13455
  /from\s+['"]\.\.\/hooks\/([^'"]+)['"]/g,
13453
- `from '@/${hooksPath}/$1'`
13456
+ `from '@/${aliasHooks}/$1'`
13454
13457
  );
13455
13458
  transformed = transformed.replace(
13456
13459
  /from\s+['"]\.\.\/(?!lib\/|hooks\/)([^'"]+)['"]/g,
13457
- `from '@/${componentsPath}/$1'`
13460
+ `from '@/${aliasComponents}/$1'`
13458
13461
  );
13459
13462
  return transformed;
13460
13463
  }
@@ -46876,7 +46879,7 @@ function generateThemeInlineBlock(semanticTokens) {
46876
46879
  lines.push("}");
46877
46880
  return lines.join("\n");
46878
46881
  }
46879
- function generateRootBlock(semanticTokens) {
46882
+ function generateRootBlock(semanticTokens, darkMode = "class") {
46880
46883
  const semanticMappings = getSemanticMappingsFromTokens(semanticTokens);
46881
46884
  const lines = [];
46882
46885
  lines.push(":root {");
@@ -46893,17 +46896,20 @@ function generateRootBlock(semanticTokens) {
46893
46896
  }
46894
46897
  lines.push("}");
46895
46898
  lines.push("");
46896
- lines.push("@media (prefers-color-scheme: dark) {");
46897
- lines.push(" :root {");
46898
- for (const name2 of Object.keys(semanticMappings)) {
46899
- lines.push(` --${name2}: var(--rafters-dark-${name2});`);
46899
+ if (darkMode === "class") {
46900
+ lines.push("@custom-variant dark (&:where(.dark, .dark *));");
46901
+ lines.push("");
46902
+ lines.push(".dark {");
46903
+ } else {
46904
+ lines.push("@media (prefers-color-scheme: dark) {");
46905
+ lines.push(" :root {");
46900
46906
  }
46901
- lines.push(" }");
46902
- lines.push("}");
46903
- lines.push("");
46904
- lines.push(".dark {");
46905
46907
  for (const name2 of Object.keys(semanticMappings)) {
46906
- lines.push(` --${name2}: var(--rafters-dark-${name2});`);
46908
+ const indent2 = darkMode === "media" ? " " : " ";
46909
+ lines.push(`${indent2}--${name2}: var(--rafters-dark-${name2});`);
46910
+ }
46911
+ if (darkMode === "media") {
46912
+ lines.push(" }");
46907
46913
  }
46908
46914
  lines.push("}");
46909
46915
  lines.push("");
@@ -46924,7 +46930,8 @@ function generateThemeBlock(groups) {
46924
46930
  for (const token of groups.spacing) {
46925
46931
  const value2 = tokenValueToCSS(token);
46926
46932
  if (value2 === null) continue;
46927
- lines.push(` --spacing-${token.name}: ${value2};`);
46933
+ const key = token.name.replace(/^spacing-/, "");
46934
+ lines.push(` --spacing-${key}: ${value2};`);
46928
46935
  }
46929
46936
  lines.push("");
46930
46937
  }
@@ -46943,7 +46950,8 @@ function generateThemeBlock(groups) {
46943
46950
  for (const token of groups.radius) {
46944
46951
  const value2 = tokenValueToCSS(token);
46945
46952
  if (value2 === null) continue;
46946
- lines.push(` --radius-${token.name}: ${value2};`);
46953
+ const key = token.name.replace(/^radius-/, "");
46954
+ lines.push(` --radius-${key}: ${value2};`);
46947
46955
  }
46948
46956
  lines.push("");
46949
46957
  }
@@ -46951,7 +46959,8 @@ function generateThemeBlock(groups) {
46951
46959
  for (const token of groups.shadow) {
46952
46960
  const value2 = tokenValueToCSS(token);
46953
46961
  if (value2 === null) continue;
46954
- lines.push(` --shadow-${token.name}: ${value2};`);
46962
+ const key = token.name.replace(/^shadow-/, "");
46963
+ lines.push(` --shadow-${key}: ${value2};`);
46955
46964
  }
46956
46965
  lines.push("");
46957
46966
  }
@@ -47126,7 +47135,7 @@ function tokensToTailwind(tokens, options = {}) {
47126
47135
  const themeInlineBlock = generateThemeInlineBlock(groups.semantic);
47127
47136
  sections.push(themeInlineBlock);
47128
47137
  sections.push("");
47129
- const rootBlock = generateRootBlock(groups.semantic);
47138
+ const rootBlock = generateRootBlock(groups.semantic, options.darkMode ?? "class");
47130
47139
  sections.push(rootBlock);
47131
47140
  sections.push("");
47132
47141
  const keyframes = generateKeyframes(groups.motion);
@@ -58443,10 +58452,10 @@ async function ensureTailwindCli(cwd) {
58443
58452
  );
58444
58453
  }
58445
58454
  }
58446
- async function generateOutputs(cwd, paths, registry2, exports, shadcn) {
58455
+ async function generateOutputs(cwd, paths, registry2, exports, shadcn, darkMode = "class") {
58447
58456
  const outputs = [];
58448
58457
  if (exports.tailwind) {
58449
- const tailwindCss = registryToTailwind(registry2, { includeImport: !shadcn });
58458
+ const tailwindCss = registryToTailwind(registry2, { includeImport: !shadcn, darkMode });
58450
58459
  await writeFile3(join9(paths.output, "rafters.css"), tailwindCss);
58451
58460
  outputs.push("rafters.css");
58452
58461
  }
@@ -58631,6 +58640,91 @@ async function resetToDefaults(cwd, paths, shadcn, isAgentMode2, framework) {
58631
58640
  path: paths.output
58632
58641
  });
58633
58642
  }
58643
+ async function writeRaftersSkill(cwd) {
58644
+ const skillDir = join9(cwd, ".claude", "skills", "rafters-frontend");
58645
+ await mkdir3(skillDir, { recursive: true });
58646
+ const skill = `---
58647
+ name: rafters-frontend
58648
+ description: Use when building frontend UI in a Rafters project -- enforces Container, Grid, typography components, and design token usage.
58649
+ ---
58650
+
58651
+ ## Layout Is Solved
58652
+
58653
+ Container and Grid handle ALL layout. You do not write layout code.
58654
+
58655
+ \`\`\`tsx
58656
+ // WRONG
58657
+ <div className={classy("flex gap-4 p-6")}>
58658
+
58659
+ // RIGHT
58660
+ <Container>
58661
+ <Grid preset="sidebar-main">
58662
+ <aside>Sidebar</aside>
58663
+ <main>Content</main>
58664
+ </Grid>
58665
+ </Container>
58666
+ \`\`\`
58667
+
58668
+ **Never use:** flex, grid, gap-*, p-*, m-*, items-*, justify-*
58669
+
58670
+ ### Grid Presets
58671
+
58672
+ | Preset | Use for |
58673
+ |---|---|
58674
+ | sidebar-main | Navigation + content |
58675
+ | form | Label/input pairs |
58676
+ | cards | Responsive card grid |
58677
+ | row | Horizontal group |
58678
+ | stack | Vertical sequence |
58679
+ | split | Equal columns |
58680
+
58681
+ ## Typography -- Components, Not Utilities
58682
+
58683
+ | Instead of | Use |
58684
+ |---|---|
58685
+ | \`<p className="text-sm text-muted-foreground">\` | \`<Muted>\` |
58686
+ | \`<p>\` | \`<P>\` |
58687
+ | \`<h1 className="text-4xl font-bold">\` | \`<H1>\` |
58688
+ | \`<h2>\` | \`<H2>\` |
58689
+ | \`<h3>\` | \`<H3>\` |
58690
+ | \`<span className="text-xs">\` | \`<Small>\` |
58691
+ | \`<span className="text-lg font-semibold">\` | \`<Large>\` |
58692
+
58693
+ ## Color -- Tokens, Not Values
58694
+
58695
+ Use semantic tokens as Tailwind classes: \`bg-primary\`, \`text-destructive\`, \`border-success\`.
58696
+ Never use hex, HSL, or palette internals.
58697
+
58698
+ ## A Correct Page
58699
+
58700
+ \`\`\`tsx
58701
+ import { Container, Grid } from "@rafters/ui"
58702
+ import { H1, Lead } from "@rafters/ui/components/ui/typography"
58703
+ import { Card } from "@rafters/ui/components/ui/card"
58704
+ import { Button } from "@rafters/ui/components/ui/button"
58705
+
58706
+ export default function Page() {
58707
+ return (
58708
+ <Container>
58709
+ <H1>Title</H1>
58710
+ <Lead>Description.</Lead>
58711
+ <Grid preset="cards">
58712
+ <Card>...</Card>
58713
+ <Card>...</Card>
58714
+ </Grid>
58715
+ <Grid preset="row">
58716
+ <Button variant="secondary">Cancel</Button>
58717
+ <Button>Save</Button>
58718
+ </Grid>
58719
+ </Container>
58720
+ )
58721
+ }
58722
+ \`\`\`
58723
+
58724
+ No flex. No gap. No padding. No text utilities.
58725
+ `;
58726
+ await writeFile3(join9(skillDir, "SKILL.md"), skill);
58727
+ }
58634
58728
  async function init(options) {
58635
58729
  setAgentMode(options.agent ?? false);
58636
58730
  const isAgentMode2 = options.agent ?? false;
@@ -58750,6 +58844,7 @@ async function init(options) {
58750
58844
  }
58751
58845
  };
58752
58846
  await writeFile3(paths.config, JSON.stringify(config3, null, 2));
58847
+ await writeRaftersSkill(cwd);
58753
58848
  const existingCssPath = detectedCssPath ?? (shadcn?.tailwind?.css || null);
58754
58849
  if (existingCssPath) {
58755
58850
  try {
@@ -60975,7 +61070,8 @@ var RaftersToolHandler = class _RaftersToolHandler {
60975
61070
  const shadcn = config3?.shadcn ?? false;
60976
61071
  await mkdir4(paths.output, { recursive: true });
60977
61072
  if (exports.tailwind) {
60978
- const css3 = registryToTailwind(registry2, { includeImport: !shadcn });
61073
+ const darkMode = config3?.darkMode ?? "class";
61074
+ const css3 = registryToTailwind(registry2, { includeImport: !shadcn, darkMode });
60979
61075
  await writeFile4(join10(paths.output, "rafters.css"), css3);
60980
61076
  }
60981
61077
  if (exports.typescript) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rafters",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "CLI for Rafters design system - scaffold tokens and add components",
5
5
  "license": "MIT",
6
6
  "type": "module",