diff --git a/.claude/settings.json b/.claude/settings.json index ce162fab..430c72ad 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -12,7 +12,14 @@ "Edit(**/credentials.json)", "Edit(**/token.json)", "Write(**/credentials.json)", - "Write(**/token.json)" + "Write(**/token.json)", + "Bash(git push *)", + "Bash(gh pr create *)", + "Bash(rm -rf *)", + "Bash(git reset --hard *)", + "Bash(git checkout -- . *)", + "Bash(git clean -f *)", + "Bash(git branch -D *)" ] } } diff --git a/.claude/skills/git/SKILL.md b/.claude/skills/git/SKILL.md index 1831bcc6..df267f9b 100644 --- a/.claude/skills/git/SKILL.md +++ b/.claude/skills/git/SKILL.md @@ -61,6 +61,19 @@ disable-model-invocation: true - ステージングから除外するのではなく、**汎用値(example.com 等)へ書き換える**(fixture 内の実ドメインは除外しても解決しない)。書き換え後にテストが通ることを確認してからコミットする - 判断が難しい場合(実データが検証に不可欠に見える等)はユーザーに確認する +# パッケージのコミット順序(依存元優先) + +複数パッケージにまたがる変更をコミットする場合、必ず**リーフからルートへ**コミットする。依存順序が不明な場合は `yarn lerna list --graph` で確認する。ルート設定ファイル(`package.json`、lint 設定等)の変更はティア 0 より先にコミットする。 + +| ティア | パッケージ | +| ------ | ---------- | +| 0 | `shared`, `readtext`, `fs`, `html-distiller`, `google-auth`, `puppeteer-general-actions`, `roar` | +| 1 | `cli-core`, `dealer`, `notion`, `proc-talk`, `puppeteer-scroll`, `google-sheets`, `filematch` | +| 2 | `puppeteer-page-scan`, `puppeteer-dealer`, `page-cluster`, `remote-inspector`, `backlog-projects` | +| 3 | `puppeteer-screenshot`, `beholder`, `a11y-check-core`, `replicator` | +| 4 | `archaeologist`, `print`, `a11y-check-axe-scenario`, `a11y-check-scenarios` | +| 5 | `a11y-check` | + # コミットメッセージの形式 - 英語で記述すること diff --git a/.claude/skills/grill-me/SKILL.md b/.claude/skills/grill-me/SKILL.md index 562876d7..a0e00565 100644 --- a/.claude/skills/grill-me/SKILL.md +++ b/.claude/skills/grill-me/SKILL.md @@ -1,7 +1,7 @@ --- name: grill-me description: ユーザーの計画・考えを徹底的に grill し、共通認識を構築するスキル -disable-model-invocation: true +when_to_use: ユーザーが「計画を詰めたい」「設計を固めたい」「/grill-me」と指示した場合。また、実装に入る前にスコープ・アプローチ・トレードオフの合意が会話文脈で成立していないと判断した場合は自発的に起動する --- この計画のあらゆる側面について、私たちが共通の認識に達するまで、徹底的に私に質問を投げかけてください。設計のツリーを枝分かれの先まで一つひとつたどり、決定事項間の依存関係を順番に解決していきましょう。各質問に対し、あなたの推奨する回答も併せて提示してください。質問は一度に一つずつ、AskUserQuestion ツールを使って投げかけてください。もしコードベースを探索することで答えが得られる質問であれば、質問する代わりにコードベースを調査してください。 diff --git a/.claude/skills/impl/SKILL.md b/.claude/skills/impl/SKILL.md index b564382d..db7db0f0 100644 --- a/.claude/skills/impl/SKILL.md +++ b/.claude/skills/impl/SKILL.md @@ -10,7 +10,13 @@ disable-model-invocation: true 2. **ブランチ確認**: 現在のブランチを確認し、`dev` / `main` / エピックの base branch 上にいる場合は `git checkout -b` でサブブランチを切ってから進む。git worktree かどうかの確認は行わない(エージェントは worktree 起動が前提のため、あえてチェックしない) 3. **索引確認**: ARCHITECTURE.md の索引(Reading paths / 不変条件・負の知識 / 境界と所有権)を確認し、該当する Reading path に従って対象コードを読んでから実装に入る(索引が無いリポジトリではこのステップをスキップ) 4. 合意した計画の通りに実装する -5. `/code-review medium` を実行し、指摘を fix all +5. **`/code-review medium`(ユーザー実行が必須)**: `/code-review` は `disable-model-invocation` のため Claude からは起動できない。以下を提示してユーザーに実行を依頼し、**結果が返るまでここで待つ**。返ってきた指摘を fix all + + ``` + /code-review medium + ``` + + 自分で代替レビューを書いて済ませたり、「起動できないので次へ進む」と判断してこのステップを飛ばすことは**禁止** 6. `/qa-engineer` を実行し、指摘を fix all 7. `/product-manager` を実行し、指摘を fix all(ドキュメント整合 — JSDoc・コメント原則・索引と実装の一致 — のチェックを含む) 8. `yarn lint` を実行し、エラーを修正 @@ -22,4 +28,5 @@ disable-model-invocation: true - **fix all の範囲**: コードレベル・テスト追加・ドキュメント修正の指摘はその場で適用。仕様変更やスコープ拡張を伴う指摘はユーザーに許可を取る - **ループバック**: いずれかのステップで重大な方向転換や巨大なコード変更が発生したら、ステップ 5(`/code-review medium`)からやり直す +- **ステップのスキップ禁止**: 特にステップ 5 の `/code-review` は Claude から起動できないが、それは「飛ばしてよい理由」ではない。ユーザーに実行を依頼して待つのが正しい進め方。ユーザーが明示的に「スキップして」と言った場合のみ飛ばす - **スコープ厳守**: grill-me で合意したスコープを勝手に拡張しない diff --git a/.claude/skills/npm-publish/SKILL.md b/.claude/skills/npm-publish/SKILL.md new file mode 100644 index 00000000..2ec09f59 --- /dev/null +++ b/.claude/skills/npm-publish/SKILL.md @@ -0,0 +1,223 @@ +--- +name: npm-publish +description: npm パッケージのリリース(dev→main マージ、バージョニング、tag push、publish workflow 監視、publish 結果検証、dev への同期) +when_to_use: ユーザーが「リリースして」「publish して」「バージョン上げて」「/npm-publish」と指示した場合 +disable-model-invocation: true +--- + +# 前提 + +- リリースは `main` ブランチから行う。`dev` の変更を `main` にマージしてから実行する +- タグ push(`v-release`)で publish workflow が発火し、npm へ自動 publish される(OIDC Trusted Publishing) +- **publish は取り消せない**。各ステップでユーザーの確認を取る +- **`yarn release` / `git push --tags` / `git push origin dev` はユーザーが実行する**。エージェントは実行せず `!` プレフィックス付きのコマンドを提示し、完了報告を待つ + +# 対象パッケージ + +このリポジトリが publish するパッケージ(independent モードのためバージョンは個別に上がる): + +| ディレクトリ | npm パッケージ名 | +|---|---| +| `packages/@d-zero/a11y-check` | `@d-zero/a11y-check` | +| `packages/@d-zero/a11y-check-axe-scenario` | `@d-zero/a11y-check-axe-scenario` | +| `packages/@d-zero/a11y-check-core` | `@d-zero/a11y-check-core` | +| `packages/@d-zero/a11y-check-scenarios` | `@d-zero/a11y-check-scenarios` | +| `packages/@d-zero/archaeologist` | `@d-zero/archaeologist` | +| `packages/@d-zero/backlog-projects` | `@d-zero/backlog-projects` | +| `packages/@d-zero/beholder` | `@d-zero/beholder` | +| `packages/@d-zero/cli-core` | `@d-zero/cli-core` | +| `packages/@d-zero/dealer` | `@d-zero/dealer` | +| `packages/@d-zero/filematch` | `@d-zero/filematch` | +| `packages/@d-zero/fs` | `@d-zero/fs` | +| `packages/@d-zero/google-auth` | `@d-zero/google-auth` | +| `packages/@d-zero/google-sheets` | `@d-zero/google-sheets` | +| `packages/@d-zero/html-distiller` | `@d-zero/html-distiller` | +| `packages/@d-zero/notion` | `@d-zero/notion` | +| `packages/@d-zero/page-cluster` | `@d-zero/page-cluster` | +| `packages/@d-zero/print` | `@d-zero/print` | +| `packages/@d-zero/proc-talk` | `@d-zero/proc-talk` | +| `packages/@d-zero/puppeteer-dealer` | `@d-zero/puppeteer-dealer` | +| `packages/@d-zero/puppeteer-general-actions` | `@d-zero/puppeteer-general-actions` | +| `packages/@d-zero/puppeteer-page-scan` | `@d-zero/puppeteer-page-scan` | +| `packages/@d-zero/puppeteer-screenshot` | `@d-zero/puppeteer-screenshot` | +| `packages/@d-zero/puppeteer-scroll` | `@d-zero/puppeteer-scroll` | +| `packages/@d-zero/readtext` | `@d-zero/readtext` | +| `packages/@d-zero/remote-inspector` | `@d-zero/remote-inspector` | +| `packages/@d-zero/replicator` | `@d-zero/replicator` | +| `packages/@d-zero/roar` | `@d-zero/roar` | +| `packages/@d-zero/shared` | `@d-zero/shared` | + +# 手順 + +## 1. ワーキングツリーの状態確認 + +`git status` で未コミットの変更・未追跡ファイルがないか確認する。 + +- クリーンなら次へ +- 変更があればユーザーに報告し、`git stash` / コミット / 中断のいずれかを尋ねる。指示に従ってから次へ + +汚れたまま先に進むとマージ・バージョニングが意図しない差分を巻き込むため、ここは省略しない。 + +## 2. main と dev の最新化 + +```bash +git fetch origin +git checkout main +git pull origin main +git checkout dev +git pull origin dev +git checkout main +``` + +両ブランチをローカルで最新にしてから `main` に戻る。`dev` をローカルで最新にしておくのは、手順 11 の `main` → `dev` 同期でそのまま使うため。 + +いずれかの `pull` がコンフリクトやリジェクトで失敗したらユーザーに報告して指示を仰ぐ。 + +## 3. 未マージ PR の確認 + +リリースに含めるべき PR が残っていないか確認し、あればユーザーに提示して続行可否を尋ねる。 + +```bash +gh pr list --base dev --state open +``` + +## 4. dev → main マージ + +`dev` が `main` より進んでいる場合、差分コミットをユーザーに提示してからマージする。 + +```bash +git log --oneline main..dev +git merge dev --no-edit +``` + +コンフリクトが発生したらユーザーに報告して指示を仰ぐ。 + +## 5. lockfile の同期確認 + +```bash +yarn install +git diff yarn.lock +``` + +差分が出たらユーザーに報告し、コミットしてから次へ。CI の `yarn install --immutable` が失敗するのを防ぐため必須。 + +## 6. 事前チェック + +```bash +yarn lint +yarn build +yarn test +``` + +すべてパスすること。`yarn release` は内部の `prerelease` スクリプト(`yarn build; yarn test`)で build / test を再度走らせるが、`lerna version` の途中で失敗するより事前に落としたほうが安全なので省略しない。失敗があれば修正してから次へ。`main` の CI が green かも併せて確認する。 + +```bash +gh run list --branch main --limit 5 +``` + +## 7. リリース内容の提示 + +現在のバージョンと前回タグからの差分をユーザーに提示し、リリース種別(graduate / alpha / beta / rc)の判断材料にする。 + +```bash +git describe --tags --abbrev=0 +git log --oneline $(git describe --tags --abbrev=0)..HEAD +``` + +independent モードではパッケージごとにバージョンが異なるため、各パッケージの現行バージョン(`packages/@d-zero/*/package.json` の `version`)も提示する。 + +## 8. バージョニングと tag push(ユーザー実行) + +`lerna version` はインタラクティブなため Claude からは実行できない。リリース種別を確認したうえで、`!` プレフィックス付きでユーザーに実行を依頼し、**完了報告を待つ**。 + +``` +! yarn release # graduate(正式リリース) +! yarn release:alpha # alpha プレリリース +! yarn release:beta # beta プレリリース +! yarn release:rc # RC プレリリース +``` + +続けてタグを push する。 + +``` +! git push --tags +``` + +`release:trigger` スクリプトが `git push origin main --follow-tags` と `v-release` タグの強制更新まで済ませているため、`git push --tags` は通常 "Everything up-to-date" になる。取りこぼしがないことの確認として実行しておく。 + +ユーザーから完了報告を受けたら、実際にタグが push されたことを確認してから次へ進む。 + +```bash +git ls-remote --tags origin +``` + +## 9. publish workflow の監視 + +`v-release` タグ push で `publish.yml` が発火する。バックグラウンド実行で完了を待つ。 + +```bash +gh run watch --exit-status +``` + +失敗したらログ URL をユーザーに提示し、「12. 失敗時の対処」へ。 + +## 10. dist-tag の判定ロジック(参考) + +`publish.yml` は `packages/@d-zero/shared/package.json` の `version` を読み、以下で dist-tag を決める: + +- `-alpha` を含む → `alpha` +- `-beta` を含む → `beta` +- `-rc` を含む → `rc` +- それ以外で `-` を含む → `next` +- 上記以外 → `latest` + +手順 12 の検証で、実際に付いた dist-tag がこのロジック通りかを確認する材料にする。 + +## 11. publish 結果の検証 + +workflow が success でも publish が意図通りとは限らない。**「対象パッケージ」の全 28 パッケージについて**実際の npm 上の状態を確認する。 + +```bash +npm view version +npm view dist-tags +``` + +確認項目: + +- バージョンが手順 8 で上げた値と一致しているか +- dist-tag が手順 10 のロジック通りか(正式リリースは `latest`、プレリリースは `alpha` / `beta` / `rc` / `next`) +- provenance が付与されているか(npm の該当バージョンページ、または `npm view --json` の `dist.attestations`) + +independent モードでは**一部のパッケージだけ publish される(部分 publish)**ことがある。28 パッケージ全てを個別に確認し、漏れがあればユーザーに報告する。 + +**ここが success の判定点**。npm 上の状態を確認するまでリリース完了と判断してはいけない。 + +## 12. main → dev の同期 + +publish の成功を確認した後、バージョン更新コミットを `dev` に取り込む。 + +```bash +git checkout dev +git merge main --no-edit +``` + +コンフリクトが発生したらユーザーに報告して指示を仰ぐ。マージできたら push をユーザーに依頼する。 + +``` +! git push origin dev +``` + +`dev` はブランチ保護がかかっており、`maintain` ロールでは直接 push できない場合がある。push が拒否されたら、`dev` への取り込みを PR 経由に切り替える(`git checkout -b chore/sync-main` してから `.claude/skills/pr/SKILL.md` の手順へ)。 + +## 13. 失敗時の対処 + +- **sigstore の transient 409**: workflow 側に retry ステップがあるため、まず retry の結果を確認する。それでも失敗する場合は `gh run rerun` で再実行 +- **部分 publish**: 成功したパッケージは publish 済みで巻き戻せない。未 publish のパッケージのみを対象に、`v-release` タグを打ち直して workflow を再発火させる(`lerna publish from-package` は未 publish のバージョンのみを対象にするため、成功済みパッケージは二重 publish されない) +- **誤ったバージョンを publish した**: unpublish は原則不可。`npm deprecate @ "<理由>"` で非推奨化し、修正版を新バージョンとして publish する。この判断は必ずユーザーに確認を取る +- **publish が失敗したまま中断する場合**: 手順 12 の `dev` 同期は行わない。`main` にバージョン更新コミットだけが残るため、次回リリース時にそこから再開する + +# 注意 + +- **`v-release` タグの作成・削除は CODEOWNERS のみ**(GitHub Rulesets で保護)。権限がない場合は手順 8 で失敗するため、実行者がタグ権限者か事前に確認する +- **publish は取り消せない**。手順 5・6 の事前チェックを省略しない +- **`.yarnrc.yml` の `npmMinimalAgeGate: 7d` を一時的に外していないか確認する**。サプライチェーン対策の設定を戻し忘れたまま publish すると保護が効かない状態でリリースすることになる diff --git a/.claude/skills/qa-engineer/SKILL.md b/.claude/skills/qa-engineer/SKILL.md index 1e5bab89..473359fb 100644 --- a/.claude/skills/qa-engineer/SKILL.md +++ b/.claude/skills/qa-engineer/SKILL.md @@ -147,6 +147,12 @@ assert result == 42 - 設定 → パース → 処理 → 出力のフルパイプラインを検証するテスト - 設定駆動の機能: 設定値を供給し振る舞いの差異をアサートするテスト +**tools での具体例:** + +- `puppeteer-general-actions` / `puppeteer-scroll` → `puppeteer-page-scan` → `puppeteer-screenshot` → `archaeologist` / `print` という CLI パイプライン。末端の `puppeteer-general-actions` の変更が `archaeologist` の出力まで正しく伝播するかは、各パッケージのユニットテストだけでは検証できない +- `dealer` → `puppeteer-dealer` → `a11y-check-core` → `a11y-check-axe-scenario` / `a11y-check-scenarios` → `a11y-check` という診断パイプライン。同様にエンドツーエンドの統合テストが必要 +- `@d-zero/shared` のサブパスエクスポート変更は 20 以上のパッケージに波及する。`shared` 単体のユニットテストが通っていても、実際に依存する主要パッケージ(`cli-core`、`puppeteer-page-scan` 等)から import して壊れていないかを確認するテストが要る + ### 8. カバレッジ改善の提案 テストカバレッジを向上させるための具体的な提案を行う。 diff --git a/CLAUDE.md b/CLAUDE.md index 4e13372d..0eb8d447 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,7 +22,7 @@ D-ZERO 株式会社の Web 開発・テスト・自動化ツール群(`@d-zero - `yarn watch` — `lerna run watch --parallel` - `yarn test` — Vitest によるテスト実行 - `yarn lint` — eslint / prettier / textlint / cspell を直列実行 -- `yarn release` / `yarn release:alpha` 等 — リリース用。**ユーザーのみ実行可**(エージェントは実行しない) +- `yarn release` / `yarn release:alpha` 等 — リリース用。**ユーザーのみ実行可**(エージェントは実行しない)。手順は `.claude/skills/npm-publish/SKILL.md` に従う - **git worktree からのビルドは `NX_WORKSPACE_ROOT_PATH` 必須**: リポジトリ内部にネストした worktree(`.claude/worktrees/*` 等)から素の `yarn build` を実行すると、Nx がルートをメインチェックアウトに誤解決し、成功表示のまま成果物がメイン側に書かれる(worktree の `lib/` は生成されない)。`NX_WORKSPACE_ROOT_PATH= yarn build` でルートを明示すること ### コマンド制約 @@ -53,6 +53,21 @@ D-ZERO 株式会社の Web 開発・テスト・自動化ツール群(`@d-zero - リリース時は `v-release` タグの強制更新を伴い、タグ push で Actions のリリース([publish.yml](.github/workflows/publish.yml))が開始される - 単一パッケージの破壊的変更でもリポジトリ全体の major bump にはならない +## 依存関係の追加 + +- バージョンは固定で追加する(`yarn add foo@1.2.3`)。`^` / `~` を付けない +- **追加したら `.github/renovate.json` の `packageRules` を確認する**。そのパッケージが既存の `groupName` グループに入るべきか、新しいグループを作るべきかを判断する + - `config:recommended` は `group:monorepos` を含むため、**同一 monorepo から公開されるパッケージ群(`@vitest/*`、`@tiptap/*`、`playwright` 系など)は設定なしで自動的に束ねられる**。手で書く必要はない + - 手当てが必要なのは Renovate が推測できない**ベンダー横断の結合**。tools では既に以下がグループ化済み: + - `google-apis`: `googleapis` + `google-auth-library` + `gaxios` + - `image-processing`: `pixelmatch` + `pngjs` + `jimp` と各型定義 + - 本体と型定義のペア(`debug` + `@types/debug`、`diff` + `@types/diff` 等) + - `resolutions` で固定している `google-auth-library` とその利用側 + - 自前の `@d-zero/*` config 系パッケージ群 + - 判断基準は「**片方だけバージョンが上がった状態でビルドと型チェックが通るか**」。通らないなら同じ `groupName` にまとめる +- グループ化を怠ると、Renovate が個別に PR を作り、片方だけマージされた中間状態で CI が赤になる。結果として**両方の PR がマージできなくなる** +- グルーピングの現状は `git branch -r --list 'origin/renovate/*'` で確認できる。`*-monorepo` サフィックスのブランチは `group:monorepos` による自動グループ + ## コーディング規約 - **`@d-zero/shared` はサブパスエクスポート**: `@d-zero/shared/parse-url` のような形式で import すること(ルート import は不可) @@ -82,13 +97,14 @@ D-ZERO 株式会社の Web 開発・テスト・自動化ツール群(`@d-zero タスクに応じて `.claude/skills/` 配下のスキルを参照すること。 -| スキル | パス | 用途 | -| --------------- | ----------------------------------------- | -------------------------------------------------------------- | -| Product Manager | `.claude/skills/product-manager/SKILL.md` | リポジトリ分析、ドキュメント整合チェック、PR レビュー | -| QA Engineer | `.claude/skills/qa-engineer/SKILL.md` | コードレビュー、テスト品質チェック、カバレッジ改善 | -| Impl | `.claude/skills/impl/SKILL.md` | 合意済み計画の実装・検証・PR 作成までのオーケストレーション | -| git | `.claude/skills/git/SKILL.md` | コミット作成ルール(粒度、メッセージ形式、コミット前チェック) | -| pr | `.claude/skills/pr/SKILL.md` | PR 作成(プリフライト、base 追従、CI 監視) | -| grill-me | `.claude/skills/grill-me/SKILL.md` | 計画・設計の合意形成(実装前の徹底質問) | - -コミットは必ず `.claude/skills/git/SKILL.md`、PR 作成は `.claude/skills/pr/SKILL.md` の手順に従うこと。 +| スキル | パス | 用途 | +| --------------- | ----------------------------------------- | ---------------------------------------------------------------------- | +| Product Manager | `.claude/skills/product-manager/SKILL.md` | リポジトリ分析、ドキュメント整合チェック、PR レビュー | +| QA Engineer | `.claude/skills/qa-engineer/SKILL.md` | コードレビュー、テスト品質チェック、カバレッジ改善 | +| Impl | `.claude/skills/impl/SKILL.md` | 合意済み計画の実装・検証・PR 作成までのオーケストレーション | +| git | `.claude/skills/git/SKILL.md` | コミット作成ルール(粒度、メッセージ形式、コミット前チェック) | +| pr | `.claude/skills/pr/SKILL.md` | PR 作成(プリフライト、base 追従、CI 監視) | +| grill-me | `.claude/skills/grill-me/SKILL.md` | 計画・設計の合意形成(実装前の徹底質問) | +| npm publish | `.claude/skills/npm-publish/SKILL.md` | リリース(dev→main、バージョニング、tag push、publish 検証、dev 同期) | + +コミットは必ず `.claude/skills/git/SKILL.md`、PR 作成は `.claude/skills/pr/SKILL.md`、リリースは `.claude/skills/npm-publish/SKILL.md` の手順に従うこと。