Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 60 additions & 16 deletions .claude/commands/repo-maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -2278,25 +2278,31 @@ fi

**同期対象ファイルの分類:**

| カテゴリ | ファイル | 同期ポリシー |
| ------------ | --------------------------------------------- | ---------------------------- |
| マネージド | `.github/workflows/claude.yml` | 常に config の最新版で上書き |
| マネージド | `.github/workflows/claude-code-review.yml` | 常に config の最新版で上書き |
| マネージド | `.github/workflows/quality-gate-fallback.yml` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/block_git_no_verify.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/pre_git_quality_gates.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/post_git_push_ci.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/post_commit_adr_reminder.py` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/development-standards.md` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/git-conventions.md` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/release-types.md` | 常に config の最新版で上書き |
| テンプレート | `.github/workflows/security.yml` | 差分表示 → 確認後に上書き |
| テンプレート | `.github/workflows/ci.yml` | 差分表示 → 確認後に上書き |
| テンプレート | `.github/ISSUE_TEMPLATE/*` | 欠落ファイルのみ追加 |
| テンプレート | `.github/pull_request_template.md` | 欠落時のみ追加 |
| カテゴリ | ファイル | 同期ポリシー |
| ------------ | --------------------------------------------- | ------------------------------ |
| マネージド | `.github/workflows/claude.yml` | 常に config の最新版で上書き |
| マネージド | `.github/workflows/claude-code-review.yml` | 常に config の最新版で上書き |
| マネージド | `.github/workflows/quality-gate-fallback.yml` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/block_git_no_verify.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/pre_git_quality_gates.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/post_git_push_ci.py` | 常に config の最新版で上書き |
| マネージド | `.claude/hooks/post_commit_adr_reminder.py` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/development-standards.md` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/git-conventions.md` | 常に config の最新版で上書き |
| マネージド | `.claude/rules/release-types.md` | 常に config の最新版で上書き |
| テンプレート | `.github/workflows/security.yml` | 差分表示 → 確認後に上書き |
| テンプレート | `.github/workflows/ci.yml` | 差分表示 → 確認後に上書き |
| テンプレート | `.github/ISSUE_TEMPLATE/*` | 欠落ファイルのみ追加 |
| テンプレート | `.github/pull_request_template.md` | 欠落時のみ追加 |
| テンプレート | `vitest.config.ts` | 欠落時のみ追加 (Vitest 採用時) |
| テンプレート | `eslint.config.mjs` | 欠落時のみ追加 (flat config) |
| テンプレート | `biome.json` | 欠落時のみ追加 (Biome 採用時) |
| テンプレート | `commitlint.config.js` | 欠落時のみ追加 |

`quality-gate-fallback.yml` は `setup-team-protection.sh` がブランチ保護に登録する `Quality Gate` 必須チェックとセットで配布する。ci.yml が paths フィルタ等でスキップされた場合に PR が `Expected — Waiting for status to be reported` のまま blocked にならないよう、Pass を emit する役割を持つ。

モダンツール 4 種 (`vitest.config.ts` / `eslint.config.mjs` / `biome.json` / `commitlint.config.js`) は `templates/testing/` `templates/eslint/` `templates/` 配下のテンプレートを欠落時のみ配置する。既存設定がある repo はそのまま尊重される。

**マネージドファイル**: config リポジトリが正規のソースであり、プロジェクト側でカスタマイズしない前提のファイル。
**テンプレートファイル**: プロジェクト固有のカスタマイズが入る可能性があるため、差分確認を挟む。

Expand Down Expand Up @@ -2440,6 +2446,44 @@ if [ -f "$PR_TEMPLATE_SRC" ] && [ ! -f "$PR_TEMPLATE_DST" ]; then
cp "$PR_TEMPLATE_SRC" "$PR_TEMPLATE_DST"
UPDATED+=(".github/pull_request_template.md (新規追加)")
fi

# モダンツール 4 種: 採用判定 + 欠落時のみ配置 (path-mapping)
# vitest: package.json の devDependencies に vitest があれば配置候補
# eslint flat config: eslint.config.* が無く、かつ ESLint を使っている場合
# biome: package.json に @biomejs/biome があれば配置候補
# commitlint: commit-msg フックを使う or commitlint 依存があれば配置候補
declare -A MODERN_TOOLS=(
["templates/testing/vitest.config.ts"]="vitest.config.ts"
["templates/eslint/eslint.config.mjs"]="eslint.config.mjs"
["templates/biome.json"]="biome.json"
["templates/commitlint.config.js"]="commitlint.config.js"
)
for src_rel in "${!MODERN_TOOLS[@]}"; do
dst_rel="${MODERN_TOOLS[$src_rel]}"
src_file="$CONFIG_REPO/$src_rel"
dst_file="./$dst_rel"
[ ! -f "$src_file" ] && continue
# 既存の同等ファイルが既にある場合はスキップ (拡張子違いを含む)
case "$dst_rel" in
vitest.config.ts)
ls vitest.config.{ts,js,mjs,cjs} >/dev/null 2>&1 && continue
jq -e '.devDependencies.vitest // .dependencies.vitest' package.json >/dev/null 2>&1 || continue
;;
eslint.config.mjs)
ls eslint.config.{mjs,js,cjs,ts} .eslintrc{.js,.json,.cjs,.yml,.yaml} >/dev/null 2>&1 && continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Detect every ESLint config variant before copying template

The skip check for eslint.config.mjs is incomplete: ls eslint.config.{mjs,js,cjs,ts} .eslintrc{.js,.json,.cjs,.yml,.yaml} misses valid existing configs such as .eslintrc (no extension) and eslint.config.mts/cts. In repos using one of those files, /repo-maintenance will still add a new eslint.config.mjs, which can silently change which ruleset ESLint uses and break existing lint behavior despite this block being documented as “skip when equivalent config exists.”

Useful? React with 👍 / 👎.

jq -e '.devDependencies.eslint // .dependencies.eslint' package.json >/dev/null 2>&1 || continue
;;
biome.json)
ls biome.json{,c} >/dev/null 2>&1 && continue
jq -e '.devDependencies["@biomejs/biome"] // .dependencies["@biomejs/biome"]' package.json >/dev/null 2>&1 || continue
;;
commitlint.config.js)
ls commitlint.config.{js,ts,mjs,cjs} .commitlintrc{,.js,.json,.yml,.yaml} >/dev/null 2>&1 && continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip commitlint template when alternate rc files already exist

The commitlint guard only checks commitlint.config.{js,ts,mjs,cjs} and .commitlintrc{,.js,.json,.yml,.yaml}, but commitlint also supports .commitlintrc.cjs, .commitlintrc.mjs, .commitlintrc.ts, .commitlintrc.cts, and .commitlintrc.mts. Repos already configured with these filenames will be treated as “missing config,” and this step will inject a second config file, risking unexpected rule resolution changes in commit hooks.

Useful? React with 👍 / 👎.

;;
esac
cp "$src_file" "$dst_file"
UPDATED+=("$dst_rel (新規追加, モダンツールテンプレート)")
done
```

**結果パターン:**
Expand Down
10 changes: 9 additions & 1 deletion .claude/commands/setup-husky.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,15 @@ fi
]
}

.commitlintrc.json(リポジトリルート)
commitlint.config.js(リポジトリルート、推奨)

`templates/commitlint.config.js` をコピーして使用:

```bash
cp /path/to/config/templates/commitlint.config.js ./commitlint.config.js
```

最小構成のみ必要な場合は `.commitlintrc.json` でも可:

{
"extends": ["@commitlint/config-conventional"]
Expand Down
19 changes: 19 additions & 0 deletions .claude/commands/setup-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,25 @@ npm install -D @stryker-mutator/core @stryker-mutator/jest-runner @stryker-mutat
- `jest.setup.js` - テスト前セットアップ
- `jest.polyfills.js` - Web API ポリフィル

### 4.1.b Vitest を選択する場合

Jest の代わりに Vitest を使うプロジェクトでは、`templates/testing/vitest.config.ts` をコピー:

```bash
cp /path/to/config/templates/testing/vitest.config.ts ./vitest.config.ts
npm install -D vitest @vitest/coverage-v8 jsdom
npm install -D @vitejs/plugin-react # React 使用時
mkdir -p tests && cat > tests/setup.ts <<'EOF'
import '@testing-library/jest-dom/vitest';
EOF
```

Vitest 採用基準:

- Vite ベースのプロジェクト (高速 HMR / ESM ネイティブ)
- React 19 / Next.js 15+ で Jest の互換性問題に直面した場合
- TypeScript first / モダンな ESM プロジェクト

### 4.2 Standard Level 追加

- `playwright.config.ts` - Playwright E2E 設定
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import eslintConfigPrettier from 'eslint-config-prettier';

export default [
{
ignores: ['node_modules/', 'dist/', 'coverage/', '*.min.js'],
ignores: ['node_modules/', 'dist/', 'coverage/', '*.min.js', 'templates/'],
},
js.configs.recommended,
eslintConfigPrettier,
Expand Down
48 changes: 48 additions & 0 deletions templates/biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.8/schema.json",
"_comment": "Biome 統合フォーマッタ + リンタテンプレート。npm install -D --save-exact @biomejs/biome の後、'npx biome init' で生成される設定を本テンプレートで上書き推奨",
"files": {
"includes": [
"**",
"!**/node_modules",
"!**/.next",
"!**/dist",
"!**/build",
"!**/coverage",
"!**/public",
"!**/.vercel",
"!**/*.min.js",
"!**/*.generated.*",
"!**/database.types.ts",
"!**/pnpm-lock.yaml",
"!**/package-lock.json",
"!**/yarn.lock",
"!**/tsconfig.tsbuildinfo"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "always",
"trailingCommas": "all"
}
},
"json": {
"formatter": {
"trailingCommas": "none"
}
}
}
24 changes: 24 additions & 0 deletions templates/commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// commitlint テンプレート (Conventional Commits)
//
// 使い方:
// 1. プロジェクトルートに `commitlint.config.js` としてコピー
// 2. 必要な依存をインストール:
// npm install -D @commitlint/cli @commitlint/config-conventional
// 3. .husky/commit-msg に以下を追加 (setup-husky 実行で自動設定):
// npx --no-install commitlint --edit "$1"
//
// 許可される type:
// feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
//
// scope は project 固有。CLAUDE.md / AGENTS.md の git-conventions を参照。
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// Subject 末尾のピリオド禁止 (デフォルト: error)
'subject-full-stop': [2, 'never', '.'],
// 本文の最大行長 (日本語コミットの場合は緩和推奨)
'body-max-line-length': [1, 'always', 100],
// フッターの最大行長
'footer-max-line-length': [1, 'always', 100],
},
};
55 changes: 55 additions & 0 deletions templates/eslint/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* ESLint flat config テンプレート (TypeScript / Next.js プロジェクト向け)
*
* 使い方:
* 1. プロジェクトルートに `eslint.config.mjs` としてコピー
* 2. 必要な依存をインストール:
* npm install -D eslint typescript-eslint
* 3. (オプション) Next.js プロジェクトの場合:
* npm install -D eslint-config-next
* → 下記 Next.js セクションのコメントを外す
* 4. (オプション) 複雑度ルールを有効化:
* → complexityRules import のコメントを外す
*
* 参考: keito4/config の eslint/complexity-rules.mjs を ./eslint/ に
* コピーして import すると複雑度ガードが有効になる
*/
import tseslint from 'typescript-eslint';
// import { complexityRules } from './eslint/complexity-rules.mjs';
// import nextCoreWebVitals from 'eslint-config-next/core-web-vitals';
// import nextTypescript from 'eslint-config-next/typescript';

export default [
{
ignores: [
'node_modules/**',
'.next/**',
'dist/**',
'build/**',
'coverage/**',
'public/**',
'.vercel/**',
'**/*.generated.*',
'**/database.types.ts',
],
},
...tseslint.configs.recommended,
// ...nextCoreWebVitals,
// ...nextTypescript,
{
files: ['**/*.{ts,tsx}'],
rules: {
// 警告は許容、未使用変数は _ 接頭辞で許可
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
// 複雑度ルールを取り込む場合:
// ...complexityRules,
},
},
];
57 changes: 57 additions & 0 deletions templates/testing/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Vitest config テンプレート
//
// 使い方:
// 1. プロジェクトルートに `vitest.config.ts` としてコピー
// 2. 必要な依存をインストール:
// npm install -D vitest @vitest/coverage-v8 jsdom
// npm install -D @vitejs/plugin-react # React 使用時
// 3. tests/setup.ts を作成 (testing-library/jest-dom 等)
// 4. package.json scripts に追加:
// "test": "vitest run"
// "test:watch": "vitest"
// "test:coverage": "vitest run --coverage"
//
// プロジェクト固有のカスタマイズが必要な箇所はコメントで明記している。
import { defineConfig } from 'vitest/config';
import path from 'node:path';

// React プロジェクトの場合は以下を有効化:
// import react from '@vitejs/plugin-react';

export default defineConfig({
// plugins: [react()],
test: {
// jsdom: ブラウザ DOM シミュレーション (React/UI テストで使用)
// node: API/サーバサイドのみのプロジェクトでは 'node' に変更
environment: 'jsdom',
globals: true,
setupFiles: ['./tests/setup.ts'],
include: ['{src,tests,lib}/**/*.{test,spec}.{ts,tsx,js,jsx}'],
exclude: ['node_modules/**', '.next/**', 'dist/**', 'tests/e2e/**', 'tests/regression/**'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html', 'lcov'],
include: ['src/**/*.{ts,tsx}', 'lib/**/*.ts'],
exclude: [
'**/*.d.ts',
'**/*.test.{ts,tsx}',
'**/*.spec.{ts,tsx}',
'**/types.ts',
'**/types/**',
'**/__tests__/**',
'**/__mocks__/**',
],
thresholds: {
lines: 70,
functions: 70,
branches: 70,
statements: 70,
},
},
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});
Loading