sparkle-design-cli 2.2.1 → 2.2.3

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/lib/constants.js CHANGED
@@ -71,8 +71,19 @@ export const REGEX = {
71
71
  // prefix and a path separator just before the filename. This preserves user-
72
72
  // authored files like `custom-sparkle-design.css` that would otherwise be
73
73
  // deleted by a loose suffix match.
74
+ //
75
+ // ※ path prefix は `(?:\.{1,2}\/(?:[^"']*\/)?)?` で「`./` または `../` +
76
+ // 任意の中間ディレクトリ(省略可)」を表す。以前は中間ディレクトリ部分が
77
+ // 必須(`(?:\.{1,2}\/)[^"']*\/`)だったため、CLI 自身が書く正規形
78
+ // `@import "./sparkle-design.css"`(中間ディレクトリなし)にマッチせず、
79
+ // generate を再実行するたびに import が重複挿入されていた(issue #59)。
80
+ // en: The path prefix `(?:\.{1,2}\/(?:[^"']*\/)?)?` means an optional
81
+ // `./` / `../` followed by optional intermediate directories. The previous
82
+ // pattern required a second slash, so the CLI's own canonical output
83
+ // `@import "./sparkle-design.css"` never matched and every re-run of
84
+ // `generate` inserted a duplicate import (issue #59).
74
85
  SPARKLE_IMPORT:
75
- /\/\*\s*Sparkle Design[^*]*\*\/\s*\n?|@import\s+['"](?:(?:\.{1,2}\/)[^"']*\/)?sparkle-design\.css['"];?\s*\n?/g,
86
+ /\/\*\s*Sparkle Design[^*]*\*\/\s*\n?|@import\s+['"](?:\.{1,2}\/(?:[^"']*\/)?)?sparkle-design\.css['"];?\s*\n?/g,
76
87
  TAILWIND_IMPORT: /@import\s+['"]tailwindcss['"];?/,
77
88
 
78
89
  // @source ディレクティブ関連
@@ -154,10 +154,7 @@ function createSparkleImportBlock(
154
154
  // downstream `@import "./sparkle-design.css"` silently drop in some
155
155
  // PostCSS toolchains, which removes Sparkle tokens from the output.
156
156
  // We now emit @import blocks first, then any @source directives.
157
- parts.push(
158
- COMMENTS.SPARKLE_IMPORT,
159
- buildSparkleImportStatement(globalsPath, sparkleDesignPath)
160
- );
157
+ parts.push(COMMENTS.SPARKLE_IMPORT, buildSparkleImportStatement(globalsPath, sparkleDesignPath));
161
158
 
162
159
  // カスタムCSS import を sparkle-design.css の後に配置
163
160
  const customBlock = createCustomCssImportBlock(customCssPath, globalsPath);
@@ -285,7 +282,13 @@ export function updateGlobalsWithFonts(
285
282
 
286
283
  try {
287
284
  // 1. globals.css を読み込む
288
- let globalsContent = fs.readFileSync(globalsPath, 'utf8');
285
+ // 再構築結果との比較用に元の内容を保持する(issue #59: 変更がない場合は
286
+ // 書き込まず no-op にして、生成物をコミット管理しているリポジトリで
287
+ // 毎回ノイズ diff(mtime 更新・formatter との競合)が出ないようにする)。
288
+ // en: Keep the original content so we can skip the write when the
289
+ // reconstruction is byte-identical (issue #59 idempotency).
290
+ const originalContent = fs.readFileSync(globalsPath, 'utf8');
291
+ let globalsContent = originalContent;
289
292
 
290
293
  // 2. 既存のimportを削除
291
294
  globalsContent = removeExistingImports(globalsContent);
@@ -340,7 +343,13 @@ export function updateGlobalsWithFonts(
340
343
  tailwindInfo
341
344
  );
342
345
 
343
- // 6. 更新したglobals.cssを書き込む
346
+ // 6. 再構築結果が元の内容と同一なら書き込まない(冪等 no-op、issue #59)
347
+ // en: Skip the write when nothing would change (idempotent no-op, #59).
348
+ if (reconstructedContent === originalContent) {
349
+ return { status: 'skipped', reason: 'already-up-to-date', globalsPath, sourcePackages };
350
+ }
351
+
352
+ // 7. 更新したglobals.cssを書き込む
344
353
  fs.writeFileSync(globalsPath, reconstructedContent, 'utf8');
345
354
  console.log(MESSAGES.GLOBALS_UPDATED(globalsPath));
346
355
  // `globalsPath` / `sourcePackages` は generate のサマリ出力(issue #56)が
@@ -643,7 +652,12 @@ export function manageFontImports(
643
652
  sparkleDesignPath
644
653
  );
645
654
 
646
- if (result.status === 'skipped') {
655
+ // `already-up-to-date`(globals.css は正規形のまま変更不要、issue #59)の
656
+ // 場合も、後続の「sparkle-design.css からの legacy フォント import 除去」は
657
+ // 実行する必要があるため early return しない。
658
+ // en: `already-up-to-date` (no-op write, issue #59) must still fall through
659
+ // to the legacy font-import stripping below.
660
+ if (result.status === 'skipped' && result.reason !== 'already-up-to-date') {
647
661
  return result;
648
662
  }
649
663
  if (result.status === 'failed') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sparkle-design-cli",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "Sparkle Design CLI — プロジェクトセットアップ、CSS・フォント生成、アンチパターン検査、AI エージェント(Claude Code / Cursor / Codex)向けのガードと hook 設定まで一括で行う sparkle-design 公式 CLI。",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",
@@ -60,6 +60,7 @@
60
60
  /* フォントウェイト */
61
61
  --font-weight-char-normal: 400;
62
62
  --font-weight-char-bold: 700;
63
+ --font-weight-icon: 500;
63
64
  --font-weight-icon-fill-0: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
64
65
  --font-weight-icon-fill-1: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
65
66
 
@@ -682,6 +683,7 @@
682
683
  /* アイコンスタイル */
683
684
  font-family: var(--font-family-icon);
684
685
  font-size: var(--font-size-12);
686
+ font-weight: var(--font-weight-icon);
685
687
  font-variation-settings: var(--font-weight-icon-fill-0);
686
688
  font-display: optional;
687
689
  letter-spacing: var(--letter-spacing-normal);
@@ -690,6 +692,7 @@
690
692
  .icon-1-fill-1 {
691
693
  font-family: var(--font-family-icon);
692
694
  font-size: var(--font-size-12);
695
+ font-weight: var(--font-weight-icon);
693
696
  font-variation-settings: var(--font-weight-icon-fill-1);
694
697
  font-display: optional;
695
698
  letter-spacing: var(--letter-spacing-normal);
@@ -698,6 +701,7 @@
698
701
  .icon-2-fill-0 {
699
702
  font-family: var(--font-family-icon);
700
703
  font-size: var(--font-size-14);
704
+ font-weight: var(--font-weight-icon);
701
705
  font-variation-settings: var(--font-weight-icon-fill-0);
702
706
  font-display: optional;
703
707
  letter-spacing: var(--letter-spacing-normal);
@@ -706,6 +710,7 @@
706
710
  .icon-2-fill-1 {
707
711
  font-family: var(--font-family-icon);
708
712
  font-size: var(--font-size-14);
713
+ font-weight: var(--font-weight-icon);
709
714
  font-variation-settings: var(--font-weight-icon-fill-1);
710
715
  font-display: optional;
711
716
  letter-spacing: var(--letter-spacing-normal);
@@ -714,6 +719,7 @@
714
719
  .icon-3-fill-0 {
715
720
  font-family: var(--font-family-icon);
716
721
  font-size: var(--font-size-16);
722
+ font-weight: var(--font-weight-icon);
717
723
  font-variation-settings: var(--font-weight-icon-fill-0);
718
724
  font-display: optional;
719
725
  letter-spacing: var(--letter-spacing-normal);
@@ -722,6 +728,7 @@
722
728
  .icon-3-fill-1 {
723
729
  font-family: var(--font-family-icon);
724
730
  font-size: var(--font-size-16);
731
+ font-weight: var(--font-weight-icon);
725
732
  font-variation-settings: var(--font-weight-icon-fill-1);
726
733
  font-display: optional;
727
734
  letter-spacing: var(--letter-spacing-normal);
@@ -730,6 +737,7 @@
730
737
  .icon-4-fill-0 {
731
738
  font-family: var(--font-family-icon);
732
739
  font-size: var(--font-size-18);
740
+ font-weight: var(--font-weight-icon);
733
741
  font-variation-settings: var(--font-weight-icon-fill-0);
734
742
  font-display: optional;
735
743
  letter-spacing: var(--letter-spacing-normal);
@@ -738,6 +746,7 @@
738
746
  .icon-4-fill-1 {
739
747
  font-family: var(--font-family-icon);
740
748
  font-size: var(--font-size-18);
749
+ font-weight: var(--font-weight-icon);
741
750
  font-variation-settings: var(--font-weight-icon-fill-1);
742
751
  font-display: optional;
743
752
  letter-spacing: var(--letter-spacing-normal);
@@ -746,6 +755,7 @@
746
755
  .icon-5-fill-0 {
747
756
  font-family: var(--font-family-icon);
748
757
  font-size: var(--font-size-20);
758
+ font-weight: var(--font-weight-icon);
749
759
  font-variation-settings: var(--font-weight-icon-fill-0);
750
760
  font-display: optional;
751
761
  letter-spacing: var(--letter-spacing-normal);
@@ -754,6 +764,7 @@
754
764
  .icon-5-fill-1 {
755
765
  font-family: var(--font-family-icon);
756
766
  font-size: var(--font-size-20);
767
+ font-weight: var(--font-weight-icon);
757
768
  font-variation-settings: var(--font-weight-icon-fill-1);
758
769
  font-display: optional;
759
770
  letter-spacing: var(--letter-spacing-normal);
@@ -762,6 +773,7 @@
762
773
  .icon-6-fill-0 {
763
774
  font-family: var(--font-family-icon);
764
775
  font-size: var(--font-size-24);
776
+ font-weight: var(--font-weight-icon);
765
777
  font-variation-settings: var(--font-weight-icon-fill-0);
766
778
  font-display: optional;
767
779
  letter-spacing: var(--letter-spacing-normal);
@@ -770,6 +782,7 @@
770
782
  .icon-6-fill-1 {
771
783
  font-family: var(--font-family-icon);
772
784
  font-size: var(--font-size-24);
785
+ font-weight: var(--font-weight-icon);
773
786
  font-variation-settings: var(--font-weight-icon-fill-1);
774
787
  font-display: optional;
775
788
  letter-spacing: var(--letter-spacing-normal);
@@ -778,6 +791,7 @@
778
791
  .icon-7-fill-0 {
779
792
  font-family: var(--font-family-icon);
780
793
  font-size: var(--font-size-28);
794
+ font-weight: var(--font-weight-icon);
781
795
  font-variation-settings: var(--font-weight-icon-fill-0);
782
796
  font-display: optional;
783
797
  letter-spacing: var(--letter-spacing-normal);
@@ -786,6 +800,7 @@
786
800
  .icon-7-fill-1 {
787
801
  font-family: var(--font-family-icon);
788
802
  font-size: var(--font-size-28);
803
+ font-weight: var(--font-weight-icon);
789
804
  font-variation-settings: var(--font-weight-icon-fill-1);
790
805
  font-display: optional;
791
806
  letter-spacing: var(--letter-spacing-normal);
@@ -794,6 +809,7 @@
794
809
  .icon-8-fill-0 {
795
810
  font-family: var(--font-family-icon);
796
811
  font-size: var(--font-size-32);
812
+ font-weight: var(--font-weight-icon);
797
813
  font-variation-settings: var(--font-weight-icon-fill-0);
798
814
  font-display: optional;
799
815
  letter-spacing: var(--letter-spacing-normal);
@@ -802,6 +818,7 @@
802
818
  .icon-8-fill-1 {
803
819
  font-family: var(--font-family-icon);
804
820
  font-size: var(--font-size-32);
821
+ font-weight: var(--font-weight-icon);
805
822
  font-variation-settings: var(--font-weight-icon-fill-1);
806
823
  font-display: optional;
807
824
  letter-spacing: var(--letter-spacing-normal);
@@ -810,6 +827,7 @@
810
827
  .icon-9-fill-0 {
811
828
  font-family: var(--font-family-icon);
812
829
  font-size: var(--font-size-36);
830
+ font-weight: var(--font-weight-icon);
813
831
  font-variation-settings: var(--font-weight-icon-fill-0);
814
832
  font-display: optional;
815
833
  letter-spacing: var(--letter-spacing-normal);
@@ -818,6 +836,7 @@
818
836
  .icon-9-fill-1 {
819
837
  font-family: var(--font-family-icon);
820
838
  font-size: var(--font-size-36);
839
+ font-weight: var(--font-weight-icon);
821
840
  font-variation-settings: var(--font-weight-icon-fill-1);
822
841
  font-display: optional;
823
842
  letter-spacing: var(--letter-spacing-normal);
@@ -826,6 +845,7 @@
826
845
  .icon-10-fill-0 {
827
846
  font-family: var(--font-family-icon);
828
847
  font-size: var(--font-size-42);
848
+ font-weight: var(--font-weight-icon);
829
849
  font-variation-settings: var(--font-weight-icon-fill-0);
830
850
  font-display: optional;
831
851
  letter-spacing: var(--letter-spacing-normal);
@@ -834,6 +854,7 @@
834
854
  .icon-10-fill-1 {
835
855
  font-family: var(--font-family-icon);
836
856
  font-size: var(--font-size-42);
857
+ font-weight: var(--font-weight-icon);
837
858
  font-variation-settings: var(--font-weight-icon-fill-1);
838
859
  font-display: optional;
839
860
  letter-spacing: var(--letter-spacing-normal);
@@ -842,6 +863,7 @@
842
863
  .icon-11-fill-0 {
843
864
  font-family: var(--font-family-icon);
844
865
  font-size: var(--font-size-48);
866
+ font-weight: var(--font-weight-icon);
845
867
  font-variation-settings: var(--font-weight-icon-fill-0);
846
868
  font-display: optional;
847
869
  letter-spacing: var(--letter-spacing-normal);
@@ -850,6 +872,7 @@
850
872
  .icon-11-fill-1 {
851
873
  font-family: var(--font-family-icon);
852
874
  font-size: var(--font-size-48);
875
+ font-weight: var(--font-weight-icon);
853
876
  font-variation-settings: var(--font-weight-icon-fill-1);
854
877
  font-display: optional;
855
878
  letter-spacing: var(--letter-spacing-normal);
@@ -858,6 +881,7 @@
858
881
  .icon-12-fill-0 {
859
882
  font-family: var(--font-family-icon);
860
883
  font-size: var(--font-size-54);
884
+ font-weight: var(--font-weight-icon);
861
885
  font-variation-settings: var(--font-weight-icon-fill-0);
862
886
  font-display: optional;
863
887
  letter-spacing: var(--letter-spacing-normal);
@@ -866,6 +890,7 @@
866
890
  .icon-12-fill-1 {
867
891
  font-family: var(--font-family-icon);
868
892
  font-size: var(--font-size-54);
893
+ font-weight: var(--font-weight-icon);
869
894
  font-variation-settings: var(--font-weight-icon-fill-1);
870
895
  font-display: optional;
871
896
  letter-spacing: var(--letter-spacing-normal);