sparkle-design-cli 2.5.0-beta.2 → 2.5.0-beta.4
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/README.md +38 -0
- package/bin/sparkle-design.js +136 -2
- package/docs/anti-patterns.md +21 -0
- package/lib/anti-pattern-rules.js +344 -3
- package/lib/auth.js +302 -0
- package/lib/check.js +2 -0
- package/lib/migrate.js +460 -0
- package/lib/token-migration.js +3 -1
- package/package.json +1 -1
- package/templates/sparkle-variables/README.md +6 -2
- package/templates/sparkle-variables/scripts/validate-tokens.mjs +161 -0
- package/templates/sparkle-variables/sparkle-design.template.css +3 -25
package/README.md
CHANGED
|
@@ -73,6 +73,12 @@ npx sparkle-design-cli check src --format json
|
|
|
73
73
|
|
|
74
74
|
# 現在有効なアンチパターンルールを一覧表示(プラグイン由来のものも含む)
|
|
75
75
|
npx sparkle-design-cli rules
|
|
76
|
+
|
|
77
|
+
# 旧セマンティックトークンを新トークンへ移行(既定は dry-run。--write で書き換え)
|
|
78
|
+
npx --yes sparkle-design-cli migrate
|
|
79
|
+
|
|
80
|
+
# Artifact Registry の npm registry 用トークンを ~/.npmrc に書く(beta)
|
|
81
|
+
npx --yes sparkle-design-cli@beta auth
|
|
76
82
|
```
|
|
77
83
|
|
|
78
84
|
### generate: 基本的な使用方法
|
|
@@ -197,6 +203,38 @@ npx sparkle-design-cli rules --format json
|
|
|
197
203
|
|
|
198
204
|
AI エージェントや CI からこの `lint:sparkle` を呼ぶ運用にすると、ガイドラインの注意書きだけに頼らず機械的に検査できます。
|
|
199
205
|
|
|
206
|
+
### migrate: 新セマンティックトークンへの移行
|
|
207
|
+
|
|
208
|
+
`check` が警告する旧セマンティックトークン(`bg-primary-600` / `var(--radius-halfModal)` など)を新トークンへ書き換えます。
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
npx --yes sparkle-design-cli migrate # src を dry-run(変更内容を diff 形式で表示するだけ)
|
|
212
|
+
npx --yes sparkle-design-cli migrate --write # [自動変換可] の箇所だけ書き換える
|
|
213
|
+
npx --yes sparkle-design-cli migrate --include 'src/components/**/*.tsx'
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- **既定は dry-run** で、`--write` を付けたときだけファイルを書き換えます。探索範囲は `check` と同じです(既定 `src`、パスを並べて指定可)
|
|
217
|
+
- 書き換えるのは移行先が一意に決まり値も変わらない `[自動変換可]` だけです。`[要判断]`(候補が複数ある等)と `[構造変更あり]` は報告するだけで置換しません
|
|
218
|
+
|
|
219
|
+
分類の考え方は [docs/anti-patterns.md](docs/anti-patterns.md#新セマンティックトークンへの移行beta-期間中) を参照してください。
|
|
220
|
+
|
|
221
|
+
### auth: Artifact Registry の認証(beta)
|
|
222
|
+
|
|
223
|
+
社内パッケージの配信先を Google Artifact Registry(AR)に移行するための準備です(goodpatch/sparkle-design-internal#261)。Google の資格情報から AR 用のアクセストークンを取得し、ユーザー単位の `~/.npmrc` に書きます。
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
gcloud auth login # 初回のみ(ADC を使う場合は gcloud auth application-default login)
|
|
227
|
+
npx --yes sparkle-design-cli@beta auth # プロジェクトの .npmrc の @goodpatch:registry が対象
|
|
228
|
+
pnpm install
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- 対象の registry は `--registry <url>`、無ければプロジェクトの `.npmrc`(親ディレクトリも辿る)の `@goodpatch:registry=` です。プロジェクトの `.npmrc` には registry 行だけを置けばよく、そのままコミットできます
|
|
232
|
+
- トークンの取得は ADC → `gcloud auth print-access-token` の順です。どちらも使えなければ `gcloud auth login` を案内して終了します
|
|
233
|
+
- **トークンは約 60 分で失効します。** `pnpm install` が 401 で落ちたら(npm は `npm adduser` を案内しますが、AR では解決しません)もう一度 `auth` を実行してください
|
|
234
|
+
- 同じ registry の行は置き換えるので、何度実行しても `~/.npmrc` に行は積み上がりません。`always-auth` は書きません
|
|
235
|
+
- トークンは Artifact Registry(`<location>-npm.pkg.dev`)以外には書きません。`cloud-platform` スコープの Google トークンなので、ほかのホストに渡すと資格情報の漏えいになるためです
|
|
236
|
+
- トークンを画面に出さず、refresh token などの長期クレデンシャルもコピーしません(gcloud の管理下に置いたまま)
|
|
237
|
+
|
|
200
238
|
### setup: プロジェクトのフルセットアップ
|
|
201
239
|
|
|
202
240
|
`sparkle-design-cli setup` は、Sparkle Design の導入に必要な作業をまとめて行います:
|
package/bin/sparkle-design.js
CHANGED
|
@@ -7,8 +7,19 @@ import { runStopHook } from '../lib/stop-hook.js';
|
|
|
7
7
|
import { PLUGIN_SPEC_MARKDOWN } from '../lib/plugin-api.js';
|
|
8
8
|
import { loadAntiPatternPlugins } from '../lib/load-plugins.js';
|
|
9
9
|
import { runRules } from '../lib/rules-report.js';
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
import { runAuth } from '../lib/auth.js';
|
|
11
|
+
import { runMigrate } from '../lib/migrate.js';
|
|
12
|
+
|
|
13
|
+
const SUBCOMMANDS = new Set([
|
|
14
|
+
'generate',
|
|
15
|
+
'check',
|
|
16
|
+
'rules',
|
|
17
|
+
'migrate',
|
|
18
|
+
'setup',
|
|
19
|
+
'auth',
|
|
20
|
+
'stop-hook',
|
|
21
|
+
'plugin-spec',
|
|
22
|
+
]);
|
|
12
23
|
|
|
13
24
|
function requireOptionValue(args, index, flags) {
|
|
14
25
|
const value = args[index + 1];
|
|
@@ -170,6 +181,67 @@ function parseRulesOptions(args) {
|
|
|
170
181
|
return options;
|
|
171
182
|
}
|
|
172
183
|
|
|
184
|
+
/**
|
|
185
|
+
* `migrate` のオプション。
|
|
186
|
+
*
|
|
187
|
+
* 既定は dry-run。`--write` を付けたときだけファイルを書き換える(不可逆操作を
|
|
188
|
+
* デフォルトにしない)。`--dry-run` は既定と同じだが、明示したい人のために受け付ける。
|
|
189
|
+
* 両方指定は意図が矛盾するのでその場で失敗させる。
|
|
190
|
+
* en: Dry-run by default; only `--write` rewrites files. `--dry-run` together
|
|
191
|
+
* with `--write` is contradictory and fails fast.
|
|
192
|
+
*/
|
|
193
|
+
function parseMigrateOptions(args) {
|
|
194
|
+
const options = { targets: [], includes: [], write: false, dryRun: false, help: false };
|
|
195
|
+
|
|
196
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
197
|
+
const arg = args[i];
|
|
198
|
+
if (arg === '-h' || arg === '--help') {
|
|
199
|
+
options.help = true;
|
|
200
|
+
} else if (arg === '--write') {
|
|
201
|
+
options.write = true;
|
|
202
|
+
} else if (arg === '--dry-run') {
|
|
203
|
+
options.dryRun = true;
|
|
204
|
+
} else if (arg === '--include') {
|
|
205
|
+
options.includes.push(requireOptionValue(args, i, '--include'));
|
|
206
|
+
i += 1;
|
|
207
|
+
} else if (arg.startsWith('-')) {
|
|
208
|
+
throw new Error(`Unknown option for migrate: ${arg}`);
|
|
209
|
+
} else {
|
|
210
|
+
options.targets.push(arg);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (options.write && options.dryRun) {
|
|
215
|
+
throw new Error('--write と --dry-run は同時に指定できません');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return options;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* `auth` のオプション。未知のフラグはその場で失敗させる(他のサブコマンドと同じ)。
|
|
223
|
+
* en: Unknown flags fail fast, same as the other subcommands.
|
|
224
|
+
*/
|
|
225
|
+
function parseAuthOptions(args) {
|
|
226
|
+
const options = { registry: null, help: false };
|
|
227
|
+
|
|
228
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
229
|
+
const arg = args[i];
|
|
230
|
+
if (arg === '-h' || arg === '--help') {
|
|
231
|
+
options.help = true;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (arg === '--registry') {
|
|
235
|
+
options.registry = requireOptionValue(args, i, '--registry');
|
|
236
|
+
i += 1;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
throw new Error(`Unknown option for auth: ${arg}`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return options;
|
|
243
|
+
}
|
|
244
|
+
|
|
173
245
|
function showHelp() {
|
|
174
246
|
console.log(`
|
|
175
247
|
Sparkle Design CLI
|
|
@@ -181,7 +253,9 @@ Commands:
|
|
|
181
253
|
generate sparkle.config.json から CSS を生成
|
|
182
254
|
check Sparkle Design のアンチパターンを検査
|
|
183
255
|
rules 現在有効なアンチパターンルールを一覧表示(プラグイン由来のものも含む)
|
|
256
|
+
migrate 旧セマンティックトークンを新トークンへ移行(既定は dry-run。--write で書き換え)
|
|
184
257
|
setup Sparkle Design プロジェクトをセットアップ(パッケージ導入 + 初期ファイル + AI ガード + generate)
|
|
258
|
+
auth Artifact Registry の npm registry 用アクセストークンを ~/.npmrc に書く(beta)
|
|
185
259
|
stop-hook AI assistant の Stop hook 用 internal subcommand(severity=error の findings か、
|
|
186
260
|
実行に失敗して未検査のルールがあるときに exit 2 で 1 度だけ停止をブロック / 再発火は自動回避。
|
|
187
261
|
warning / info はブロックせず件数の要約を stderr に出す)
|
|
@@ -203,6 +277,12 @@ Check:
|
|
|
203
277
|
sparkle-design-cli check src --format json
|
|
204
278
|
sparkle-design-cli check src/components src/features
|
|
205
279
|
|
|
280
|
+
Migrate:
|
|
281
|
+
sparkle-design-cli migrate # src を dry-run(変更内容を表示するだけ)
|
|
282
|
+
sparkle-design-cli migrate --include 'src/components/**/*.tsx'
|
|
283
|
+
sparkle-design-cli migrate --write # [自動変換可] の箇所だけ書き換える
|
|
284
|
+
sparkle-design-cli migrate src/app src/features --write
|
|
285
|
+
|
|
206
286
|
Rules:
|
|
207
287
|
sparkle-design-cli rules # 有効なルールを severity 別に一覧表示
|
|
208
288
|
sparkle-design-cli rules --format json # CI / AI 向け
|
|
@@ -211,6 +291,10 @@ Plugin spec:
|
|
|
211
291
|
sparkle-design-cli plugin-spec # アンチパターン拡張プラグインの契約仕様を出力
|
|
212
292
|
sparkle-design-cli plugin-spec --list # 現在のプロジェクトで発見されたプラグインを表示
|
|
213
293
|
|
|
294
|
+
Auth (beta):
|
|
295
|
+
sparkle-design-cli auth # プロジェクトの .npmrc の @goodpatch:registry を対象に認証
|
|
296
|
+
sparkle-design-cli auth --registry https://asia-northeast1-npm.pkg.dev/<project>/<repository>/
|
|
297
|
+
|
|
214
298
|
Setup:
|
|
215
299
|
sparkle-design-cli setup # フルセットアップ(推奨・新規導入時)
|
|
216
300
|
sparkle-design-cli setup --assistant claude # Claude 向けガードも同時にセットアップ
|
|
@@ -275,6 +359,36 @@ Check options:
|
|
|
275
359
|
(warning / info は報告のみで exit code に影響しない)
|
|
276
360
|
--format <text|json> 出力形式 (default: text)
|
|
277
361
|
|
|
362
|
+
Migrate options:
|
|
363
|
+
-h, --help このヘルプメッセージを表示
|
|
364
|
+
[path ...] 探索するパス(default: src。check と同じ探索範囲。
|
|
365
|
+
.js / .jsx / .ts / .tsx / .css、node_modules と .git は除外)
|
|
366
|
+
--dry-run ファイルを変更せず、変更内容を diff 形式で表示する(既定)
|
|
367
|
+
--write [自動変換可] の箇所だけを書き換える
|
|
368
|
+
--include <glob> 対象を cwd からの相対パス(cwd の外は絶対パス)が glob に
|
|
369
|
+
マッチするファイルに絞る(複数指定可。** / * / ? / {a,b} に対応)
|
|
370
|
+
|
|
371
|
+
Migrate の分類:
|
|
372
|
+
自動変換可 bg- / text- / border- などの用途と variant 接頭辞(hover: 等)から移行先が
|
|
373
|
+
一意に決まり、値も変わらないもの。--write のときだけ置換する
|
|
374
|
+
要判断 移行先候補が複数ある / 対応する新トークンが無いもの。候補を表示するだけで置換しない
|
|
375
|
+
構造変更あり トークンの差し替えでは済まない(マークアップ変更を伴う)もの。指摘するだけで置換しない
|
|
376
|
+
対応表は check の移行ルールと共通(lib/token-migration.js)。check で抑制コメント
|
|
377
|
+
(sparkle-disable-line <rule-id>)を付けた箇所は migrate でも書き換えない
|
|
378
|
+
|
|
379
|
+
Auth options:
|
|
380
|
+
-h, --help このヘルプメッセージを表示
|
|
381
|
+
--registry <url> 対象の registry(default: プロジェクトの .npmrc の @goodpatch:registry)
|
|
382
|
+
|
|
383
|
+
Auth の動作:
|
|
384
|
+
1. Google の資格情報(ADC → gcloud auth print-access-token の順)からアクセストークンを取得
|
|
385
|
+
どちらも無い / 期限切れなら gcloud auth login を案内して終了
|
|
386
|
+
2. ユーザー単位の ~/.npmrc(NPM_CONFIG_USERCONFIG があればそちら)に、同じ registry の行を
|
|
387
|
+
置き換えて書く(プロジェクトの .npmrc は registry 行のみのまま、コミットできる状態を保つ)
|
|
388
|
+
3. 有効期限(約 60 分)を表示する。切れたらもう一度 auth を実行する
|
|
389
|
+
トークンは Artifact Registry(<location>-npm.pkg.dev)にだけ書き、画面には出しません。
|
|
390
|
+
refresh token などの長期クレデンシャルは gcloud の管理下に置いたままで、コピーしません。
|
|
391
|
+
|
|
278
392
|
Setup options:
|
|
279
393
|
-h, --help このヘルプメッセージを表示
|
|
280
394
|
--assistant <name> claude / codex / cursor / generic (default: generic)
|
|
@@ -410,6 +524,16 @@ async function main() {
|
|
|
410
524
|
return;
|
|
411
525
|
}
|
|
412
526
|
|
|
527
|
+
if (command === 'auth') {
|
|
528
|
+
const options = parseAuthOptions(args.slice(1));
|
|
529
|
+
if (options.help) {
|
|
530
|
+
showHelp();
|
|
531
|
+
process.exit(0);
|
|
532
|
+
}
|
|
533
|
+
await runAuth(options);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
|
|
413
537
|
if (command === 'stop-hook') {
|
|
414
538
|
// setup で各 agent の hook 設定ファイルから呼ばれる internal subcommand。
|
|
415
539
|
// 以降の引数はすべて lint 対象 path。setup が書き出す hook は 1 つだが、
|
|
@@ -440,6 +564,16 @@ async function main() {
|
|
|
440
564
|
return;
|
|
441
565
|
}
|
|
442
566
|
|
|
567
|
+
if (command === 'migrate') {
|
|
568
|
+
const options = parseMigrateOptions(args.slice(1));
|
|
569
|
+
if (options.help) {
|
|
570
|
+
showHelp();
|
|
571
|
+
process.exit(0);
|
|
572
|
+
}
|
|
573
|
+
runMigrate({ targets: options.targets, includes: options.includes, write: options.write });
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
443
577
|
if (command === 'plugin-spec') {
|
|
444
578
|
await runPluginSpec(args.slice(1));
|
|
445
579
|
return;
|
package/docs/anti-patterns.md
CHANGED
|
@@ -55,6 +55,27 @@ src/Card.tsx:8 [warning] [legacy-color-token] 旧セマンティックカラー
|
|
|
55
55
|
>
|
|
56
56
|
> 旧→新の対応表は `lib/token-migration.js` に一元化してあり、`test/token-migration.test.js` が**実際に生成した CSS を読んで**「表に書いた移行先が実在し、旧トークンと同じ実値に解決される」ことを検証しています。表とトークン定義が食い違ったらテストが落ちるので、案内が嘘になりません。検出パターンがマッチする文字列は必ず対応表で解決できることも全数検証しています(片方だけ更新すると「検出したのに黙って捨てる」穴になるため)。
|
|
57
57
|
|
|
58
|
+
### `migrate` で書き換える
|
|
59
|
+
|
|
60
|
+
`check` が提示する移行先のうち `[自動変換可]` のものは、`migrate` サブコマンドでまとめて書き換えられます。対応表は `check` と同じ `lib/token-migration.js` を使うので、`check` の案内と `migrate` の書き換え先が食い違うことはありません。
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx --yes sparkle-design-cli migrate # dry-run。変更内容を diff 形式で表示するだけ
|
|
64
|
+
npx --yes sparkle-design-cli migrate --write # [自動変換可] の箇所だけ書き換える
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| 分類 | `migrate` の挙動 |
|
|
68
|
+
| ------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| 自動変換可 | 用途(`bg-` / `text-` / `border-` …)と variant 接頭辞から移行先が一意に決まり、値も変わらない。`--write` のときだけ置換する |
|
|
70
|
+
| 要判断 | 移行先候補が複数ある / 対応する新トークンが無い。候補を列挙するだけで置換しない |
|
|
71
|
+
| 構造変更あり | トークンの差し替えでは済まない(マークアップ変更を伴う)。該当箇所を指摘するだけ |
|
|
72
|
+
|
|
73
|
+
- variant 接頭辞(`hover:` / `group-hover:` / `dark:` …)、opacity modifier(`/50`)、important(`!`)は置換後もそのまま残ります
|
|
74
|
+
- `check` で報告しないもの(そのファイル自身が宣言している変数・行頭から始まるブロックコメント)は `migrate` も書き換えません。`sparkle-disable-line legacy-color-token` などの抑制コメントを付けた箇所も書き換えません(誤検出を抑制した箇所を黙って書き換えないため)
|
|
75
|
+
- 書き換えた後に 2 回目を実行しても、`migrate` の `[自動変換可]` は 0 件になります(新トークンは検出パターンにマッチしない)
|
|
76
|
+
- **`check` が `[自動変換可]` と案内しても、`migrate` が `[要判断]` として書き換えずに残す箇所があります。** 検出はファイル全体への正規表現なので、パス(`'/img/fill-primary-600.svg'` / `"bg-primary-600/hero.png"`)、import / require の specifier、`url()` の中のようなクラス名でない文字列にもマッチします。`check` は報告するだけなので案内を変えていませんが、`migrate` は資産パスや import を壊さないよう、これらと数値・角括弧以外の modifier(`/data.json` など)付きのものを書き換えません。クラス名として使っている箇所なら手で置き換えてください
|
|
77
|
+
- `--include <glob>` で対象を cwd からの相対パスで絞れます(`**` / `*` / `?` / `{a,b}`)
|
|
78
|
+
|
|
58
79
|
## 余白のスケール(`use-figma-spacing-scale`)
|
|
59
80
|
|
|
60
81
|
Figma の余白は 17 段(0 / 2 / 4 / 6 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48 / 56 / 72 / 88 / 104 / 120 px)です。Tailwind の 1 ステップは 4px なので、`p-4` = 16px、`p-6` = 24px が対応します。このスケールから外れた値を `info` で報告し、前後の候補を提示します。
|