sparkle-design-cli 2.2.2 → 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.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",