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
51 changes: 51 additions & 0 deletions .claude/hooks/format-and-lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# PostToolUse hook: 編集されたファイルを自動整形(Prettier)し、ESLint で検査する。
# モノレポ対応: functions/ 配下のファイルは functions/ を cwd にして実行する
# (functions/.eslintrc.js の parserOptions.project が cwd 依存のため)。
# 整形は副作用として行い、lint は情報提供のみ。何があってもブロックしない(exit 0)。
set -uo pipefail

# リポジトリルート(このスクリプトは <repo>/.claude/hooks/ にある)
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

# stdin の JSON から編集対象ファイルパスを取得
input="$(cat)"
file="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)"
[ -z "$file" ] && exit 0

# 絶対パスへ正規化(存在チェックより先に行う。相対パスは REPO_ROOT 基準で解決する)
case "$file" in
/*) abs="$file" ;;
*) abs="$REPO_ROOT/$file" ;;
esac
Comment thread
Copilot marked this conversation as resolved.

[ -f "$abs" ] || exit 0

# 拡張子で処理を振り分け
run_eslint=0
case "$file" in
*.ts|*.tsx|*.js|*.jsx) run_eslint=1 ;;
*.json|*.css|*.scss|*.md|*.html|*.yml|*.yaml) run_eslint=0 ;;
*) exit 0 ;; # 対象外は何もしない
esac

# functions/ 配下かどうかで作業ディレクトリを切り替える
case "$abs" in
"$REPO_ROOT"/functions/*) workdir="$REPO_ROOT/functions" ;;
*) workdir="$REPO_ROOT" ;;
esac

cd "$workdir" || exit 0

# 自動整形(失敗してもブロックしない)
npx --no-install prettier --write "$abs" >/dev/null 2>&1 || true

# Lint は警告表示のみ。エラーがあれば stderr に出して Claude にフィードバックするが
# exit 2 ではなく exit 0 でブロックしない(整形済みコードはそのまま採用させる)。
if [ "$run_eslint" -eq 1 ]; then
if ! eslint_out="$(npx --no-install eslint "$abs" 2>&1)"; then
printf 'ESLint の警告/エラー (%s):\n%s\n' "$file" "$eslint_out" >&2
fi
fi

exit 0
33 changes: 33 additions & 0 deletions .claude/hooks/typecheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Stop hook: 作業終了時に両パッケージの型チェック(tsc --noEmit)を実行する。
# 型エラーがあれば exit 2 + stderr で Claude にフィードバックし、修正を促す。
# build は重いため hook では実行しない(必要時に手動で `npm run build`)。
set -uo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

status=0
report=""

# ルート(フロントエンド)の型チェック
if [ -f "$REPO_ROOT/tsconfig.json" ]; then
if ! out="$(cd "$REPO_ROOT" && npx --no-install tsc --noEmit 2>&1)"; then
status=2
report+=$'\n[root] tsc --noEmit に失敗:\n'"$out"$'\n'
fi
fi

# functions(バックエンド)の型チェック
if [ -f "$REPO_ROOT/functions/tsconfig.json" ]; then
if ! out="$(cd "$REPO_ROOT/functions" && npx --no-install tsc --noEmit 2>&1)"; then
status=2
report+=$'\n[functions] tsc --noEmit に失敗:\n'"$out"$'\n'
fi
fi

if [ "$status" -ne 0 ]; then
printf '型チェック (typecheck) でエラーがあります。修正してください。%s' "$report" >&2
exit 2
fi

exit 0
79 changes: 79 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint:*)",
"Bash(npm run format:*)",
"Bash(npm run typecheck:*)",
"Bash(npm run build:*)",
"Bash(npm run dev:*)",
"Bash(npm run preview:*)",
"Bash(npx eslint:*)",
"Bash(npx prettier:*)",
"Bash(npx tsc:*)",
"Bash(npx vite:*)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git show:*)",
"Bash(git branch:*)",
"Bash(ls:*)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(rg:*)",
"Bash(cat:*)",
"Bash(tree:*)"
],
"ask": [
"Bash(npm install:*)",
"Bash(npm ci:*)",
"Bash(npm i:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(git checkout:*)",
"Bash(git reset:*)",
"Bash(git rebase:*)",
"Bash(firebase deploy:*)",
"Bash(firebase emulators:*)",
"Bash(npm run deploy:*)",
"Bash(npm run serve:*)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(**/*.encoded)",
"Read(**/*.decoded)",
"Bash(rm -rf:*)",
"Bash(git push --force:*)",
"Bash(git push -f:*)",
"Bash(firebase functions:delete:*)",
"Bash(firebase hosting:disable:*)"
]
},
"enableAllProjectMcpServers": true,
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR/.claude/hooks/format-and-lint.sh\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR/.claude/hooks/typecheck.sh\""
}
]
}
]
}
}
7 changes: 6 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
"es2021": true,
"node": true
},
"extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"overrides": [],
"parser": "@typescript-eslint/parser",
"parserOptions": {
Expand Down
82 changes: 41 additions & 41 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,76 @@
version: 2
updates:
# Frontend (root) npm dependencies
- package-ecosystem: "npm"
directory: "/"
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: "weekly"
interval: 'weekly'
open-pull-requests-limit: 10
groups:
root-minor-patch:
update-types:
- "minor"
- "patch"
- 'minor'
- 'patch'
# Defer these major upgrades until their migrations are scoped (see
# plan); remove an entry when ready to adopt that major.
ignore:
# React 19 migration not yet scoped.
- dependency-name: "react"
update-types: ["version-update:semver-major"]
- dependency-name: "react-dom"
update-types: ["version-update:semver-major"]
- dependency-name: "@types/react"
update-types: ["version-update:semver-major"]
- dependency-name: "@types/react-dom"
update-types: ["version-update:semver-major"]
- dependency-name: 'react'
update-types: ['version-update:semver-major']
- dependency-name: 'react-dom'
update-types: ['version-update:semver-major']
- dependency-name: '@types/react'
update-types: ['version-update:semver-major']
- dependency-name: '@types/react-dom'
update-types: ['version-update:semver-major']
# TS 6 / ESLint 10 (flat config) not yet supported by the toolchain.
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
- dependency-name: "eslint"
update-types: ["version-update:semver-major"]
- dependency-name: 'typescript'
update-types: ['version-update:semver-major']
- dependency-name: 'eslint'
update-types: ['version-update:semver-major']
# daisyUI 5 requires Tailwind 4; couple with a Tailwind 4 migration.
- dependency-name: "daisyui"
update-types: ["version-update:semver-major"]
- dependency-name: "tailwindcss"
update-types: ["version-update:semver-major"]
- dependency-name: 'daisyui'
update-types: ['version-update:semver-major']
- dependency-name: 'tailwindcss'
update-types: ['version-update:semver-major']
# Keep @types/node from getting ahead of the CI/build Node runtime.
- dependency-name: "@types/node"
update-types: ["version-update:semver-major"]
- dependency-name: '@types/node'
update-types: ['version-update:semver-major']

# Cloud Functions npm dependencies
- package-ecosystem: "npm"
directory: "/functions"
- package-ecosystem: 'npm'
directory: '/functions'
schedule:
interval: "weekly"
interval: 'weekly'
open-pull-requests-limit: 10
groups:
functions-minor-patch:
update-types:
- "minor"
- "patch"
- 'minor'
- 'patch'
# Defer these major upgrades until their migrations are scoped (see
# plan); remove an entry when ready to adopt that major.
ignore:
# TS 6 / ESLint 10 (flat config) not yet supported by the toolchain.
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
- dependency-name: "eslint"
update-types: ["version-update:semver-major"]
- dependency-name: 'typescript'
update-types: ['version-update:semver-major']
- dependency-name: 'eslint'
update-types: ['version-update:semver-major']
# symbol-sdk 3 is a large crypto-breaking rewrite; handle separately.
- dependency-name: "symbol-sdk"
update-types: ["version-update:semver-major"]
- dependency-name: 'symbol-sdk'
update-types: ['version-update:semver-major']
# Keep @types/node aligned with the Node 22 deploy runtime.
- dependency-name: "@types/node"
update-types: ["version-update:semver-major"]
- dependency-name: '@types/node'
update-types: ['version-update:semver-major']

# GitHub Actions (keeps SHA-pinned actions up to date)
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: "weekly"
interval: 'weekly'
open-pull-requests-limit: 10
groups:
actions-all:
update-types:
- "minor"
- "patch"
- 'minor'
- 'patch'
4 changes: 2 additions & 2 deletions .github/workflows/pinact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ jobs:
with:
# Check-only: fail CI if any action is unpinned or a version comment
# does not match its SHA. Never modify files.
fix: "false"
verify: "true"
fix: 'false'
verify: 'true'
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ yarn-error.log*
*.log

.firebase/*

# Claude Code(settings.json / .mcp.json / hooks / CLAUDE.md はコミット対象)
.claude/settings.local.json

# Serena(MCP)ローカルキャッシュ
.serena/cache/
36 changes: 36 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"mcpServers": {
"serena": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"git+https://github.com/oraios/serena",
"serena",
"start-mcp-server",
"--context",
"ide-assistant",
"--project-from-cwd"
Comment thread
YasunoriMATSUOKA marked this conversation as resolved.
],
"env": {}
},
"context7": {
"type": "stdio",
"command": "npx",
"args": ["--yes", "@upstash/context7-mcp@latest"],
"env": {}
},
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["@playwright/mcp@latest"],
"env": {}
},
"chrome-devtools": {
"type": "stdio",
"command": "npx",
"args": ["chrome-devtools-mcp@latest"],
"env": {}
}
}
}
2 changes: 2 additions & 0 deletions .serena/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/cache
/project.local.yml
Loading