@shortwind/cli 0.1.0-beta.14 → 0.1.0-beta.16

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.
@@ -445,7 +445,14 @@ function blockSectionValues(selector) {
445
445
  }
446
446
  const THEME_LIGHT_VALUES = blockSectionValues(":root");
447
447
  const THEME_DARK_VALUES = blockSectionValues(".dark");
448
- function buildThemeSupplement(css, missing) {
448
+ function darkSection(lines) {
449
+ return [
450
+ ".dark {",
451
+ ...lines,
452
+ "}"
453
+ ];
454
+ }
455
+ function buildThemeSupplement(missing) {
449
456
  const tokens = missing.filter((t) => THEME_LIGHT_VALUES.has(t));
450
457
  if (tokens.length === 0) return null;
451
458
  const light = tokens.map((t) => ` --${t}: ${THEME_LIGHT_VALUES.get(t)};`);
@@ -457,13 +464,44 @@ function buildThemeSupplement(css, missing) {
457
464
  ...light,
458
465
  "}"
459
466
  ];
460
- if (dark.length > 0) {
461
- if (/@custom-variant\s+dark|\.dark\s*\{/.test(css)) lines.push(".dark {", ...dark, "}");
462
- else if (/@media\s*\(\s*prefers-color-scheme\s*:\s*dark\s*\)/.test(css)) lines.push("@media (prefers-color-scheme: dark) {", " :root {", ...dark.map((l) => ` ${l}`), " }", "}");
463
- }
467
+ if (dark.length > 0) lines.push(...darkSection(dark));
464
468
  lines.push("@theme inline {", ...mapping, "}", "/* end shortwind theme-supplement */");
465
469
  return lines.join("\n");
466
470
  }
471
+ const DARK_CLASS_VARIANT = "@custom-variant dark (&:is(.dark *));";
472
+ const CUSTOM_VARIANT_RE = /@custom-variant\s+dark\b/;
473
+ function ensureDarkClassVariant(css) {
474
+ if (CUSTOM_VARIANT_RE.test(css)) return css;
475
+ const m = css.match(TAILWIND_IMPORT_RE);
476
+ if (!m) return css;
477
+ const at = (m.index ?? 0) + m[0].length;
478
+ return `${css.slice(0, at)}\n${DARK_CLASS_VARIANT}${css.slice(at)}`;
479
+ }
480
+ const DARK_PROMOTE_MARKER = "/* shortwind:dark-promote";
481
+ const MEDIA_DARK_ROOT_RE = /@media\s*\(\s*prefers-color-scheme\s*:\s*dark\s*\)\s*\{\s*:root\s*\{([^}]*)\}\s*\}/;
482
+ function convertMediaDarkToClass(css) {
483
+ if (css.includes("/* shortwind:dark-promote")) return {
484
+ css,
485
+ converted: false
486
+ };
487
+ const decls = [...(css.match(MEDIA_DARK_ROOT_RE)?.[1] ?? "").matchAll(/--([\w-]+)\s*:\s*([^;]+);/g)].map((d) => ` --${d[1]}: ${d[2].trim()};`);
488
+ if (decls.length === 0) return {
489
+ css,
490
+ converted: false
491
+ };
492
+ const without = css.replace(MEDIA_DARK_ROOT_RE, "").replace(/\n{3,}/g, "\n\n");
493
+ const block = [
494
+ `${DARK_PROMOTE_MARKER} — dark tokens moved out of the system-preference media query so a .dark toggle is the single source of truth. */`,
495
+ ".dark {",
496
+ ...decls,
497
+ "}",
498
+ "/* end shortwind dark-promote */"
499
+ ].join("\n");
500
+ return {
501
+ css: `${without.replace(/\s*$/, "")}\n\n${block}\n`,
502
+ converted: true
503
+ };
504
+ }
467
505
  const TONE_MARKER = "/* shortwind:tones";
468
506
  const TONES = [
469
507
  {
@@ -496,7 +534,7 @@ const TONES = [
496
534
  fg: "var(--primary)"
497
535
  }
498
536
  ];
499
- function buildToneBlock(css) {
537
+ function buildToneBlock() {
500
538
  const rule = (name, bg, fg) => `[data-tone="${name}"] { --tone-bg: ${bg}; --tone-fg: ${fg}; }`;
501
539
  const lines = [
502
540
  `${TONE_MARKER} — semantic tones for tone-aware recipes (@badge, …). Set on an element:`,
@@ -506,8 +544,7 @@ function buildToneBlock(css) {
506
544
  const darkTones = TONES.filter((t) => t.darkBg && t.darkFg);
507
545
  if (darkTones.length > 0) {
508
546
  const darkRules = darkTones.map((t) => " " + rule(t.name, t.darkBg, t.darkFg));
509
- if (/@custom-variant\s+dark|\.dark\s*\{/.test(css)) lines.push(".dark {", ...darkRules, "}");
510
- else if (/@media\s*\(\s*prefers-color-scheme\s*:\s*dark\s*\)/.test(css)) lines.push("@media (prefers-color-scheme: dark) {", ...darkRules, "}");
547
+ lines.push(...darkSection(darkRules));
511
548
  }
512
549
  lines.push("/* end shortwind tones */");
513
550
  return lines.join("\n");
@@ -700,7 +737,7 @@ async function init(options) {
700
737
  if (theme.action === "skipped" && theme.themePath && skillRegistry) {
701
738
  const css = await readFile(theme.themePath, "utf8");
702
739
  missingThemeTokens = findMissingThemeTokens(css, skillRegistry.flattened);
703
- const supplement = buildThemeSupplement(css, missingThemeTokens);
740
+ const supplement = buildThemeSupplement(missingThemeTokens);
704
741
  if (supplement) {
705
742
  await writeFile(theme.themePath, `${css.replace(/\s*$/, "")}\n\n${supplement}\n`);
706
743
  supplementedThemeTokens = missingThemeTokens;
@@ -708,13 +745,18 @@ async function init(options) {
708
745
  themeAction = "supplemented";
709
746
  }
710
747
  }
748
+ if (theme.themePath) {
749
+ const css = await readFile(theme.themePath, "utf8");
750
+ const { css: next } = convertMediaDarkToClass(ensureDarkClassVariant(css));
751
+ if (next !== css) await writeFile(theme.themePath, next);
752
+ }
711
753
  let tonesPath = null;
712
754
  let tonesAction = "skipped";
713
755
  if (theme.themePath) {
714
756
  const css = await readFile(theme.themePath, "utf8");
715
757
  tonesPath = theme.themePath;
716
758
  if (!css.includes("/* shortwind:tones")) {
717
- await writeFile(theme.themePath, `${css.replace(/\s*$/, "")}\n\n${buildToneBlock(css)}\n`);
759
+ await writeFile(theme.themePath, `${css.replace(/\s*$/, "")}\n\n${buildToneBlock()}\n`);
718
760
  tonesAction = "written";
719
761
  }
720
762
  }
@@ -767,7 +809,7 @@ function cliVersion() {
767
809
  }
768
810
  }
769
811
  function pickPackages(bundler) {
770
- const base = ["@shortwind/tailwind"];
812
+ const base = ["@shortwind/cli", "@shortwind/tailwind"];
771
813
  switch (bundler) {
772
814
  case "vite": return [...base, "@shortwind/vite"];
773
815
  case "next": return [...base, "@shortwind/next"];
@@ -883,7 +925,7 @@ async function wireVscodeClassRegex(vscodePath) {
883
925
  parse(next);
884
926
  await writeFile(vscodePath, next.endsWith("\n") ? next : next + "\n");
885
927
  }
886
- const HUSKY_LINE = "npx @shortwind/cli build";
928
+ const HUSKY_LINE = "npx shortwind build";
887
929
  async function installHuskyHook(cwd, huskyPath) {
888
930
  if (!existsSync(path.join(cwd, ".git"))) return null;
889
931
  await mkdir(path.dirname(huskyPath), { recursive: true });
@@ -893,7 +935,7 @@ async function installHuskyHook(cwd, huskyPath) {
893
935
  }
894
936
  const current = await readFile(huskyPath, "utf8");
895
937
  if (current.includes(HUSKY_LINE)) return huskyPath;
896
- await writeFile(huskyPath, current.endsWith("\n") ? current + HUSKY_LINE + "\n" : current + "\nnpx @shortwind/cli build\n", { mode: 493 });
938
+ await writeFile(huskyPath, current.endsWith("\n") ? current + HUSKY_LINE + "\n" : current + "\nnpx shortwind build\n", { mode: 493 });
897
939
  return huskyPath;
898
940
  }
899
941
  async function writeSkillMd(skillPath, recipesDir, families, bundler) {
@@ -2555,4 +2597,4 @@ function formatBenchTable(result) {
2555
2597
  //#endregion
2556
2598
  export { createRegistrySource as A, readConfig as C, init as D, cliVersion as E, extractHeader as F, rewriteHeaderSha as I, sealRecipeFile as L, detectProject as M, buildHeaderLine as N, readLockfile as O, computeBodySha as P, verifyFetchedFamily as R, installedFamilies as S, DEFAULT_REGISTRY as T, reseal as _, extractClassUsages as a, remove as b, verify as c, dev as d, BuildError as f, preset as g, ls as h, DEFAULT_CONTENT as i, resolvePresetFamilies as j, writeLockfile as k, UpgradeError as l, formatLsText as m, formatBenchTable as n, formatFindingsText as o, build as p, ALL_RULES as r, lint as s, bench as t, upgrade as u, NewFamilyError as v, renameFamilyInSource as w, add as x, newFamily as y };
2557
2599
 
2558
- //# sourceMappingURL=bench-DQtfv5aq.js.map
2600
+ //# sourceMappingURL=bench-DG0TCu9M.js.map