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+['"](
|
|
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 ディレクティブ関連
|
package/lib/font-manager.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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);
|