Skip to content

Commit e169b02

Browse files
Nick Sullivanclaude
andcommitted
✨ Add /repo-tooling command for automated project setup
Create language-agnostic tooling setup command that configures professional development environments with sensible defaults. Features: - Single recommendation with yes/no decision point - Smart version detection (checks latest LTS Node.js) - Language agnostic design (TypeScript now, Python ready) - Follows /ai-coding-config pattern for consistency - Fast default path with customization option TypeScript/Next.js templates include: - ESLint 9 flat config with Next.js rules - Prettier 3 with Tailwind plugin - Husky pre-commit/pre-push hooks - GitHub Actions CI/CD (build, test, quality) - Claude Code review workflows Command design principles: - Goals over process (trusts executing LLM) - Conversational, not robotic - Respects existing files - Only checks runtime versions (not npm packages) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 41ca1bc commit e169b02

File tree

9 files changed

+762
-0
lines changed

9 files changed

+762
-0
lines changed

.claude/commands/repo-tooling.md

Lines changed: 401 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
# Cancel in-progress runs for the same workflow + branch/PR
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
env:
18+
# NOTE: These versions should be detected from your project during installation
19+
# NODE_VERSION: Check package.json engines.node or use latest LTS
20+
# PNPM_VERSION: Check package.json packageManager field or use `pnpm --version`
21+
NODE_VERSION: "22" # REPLACE: Detected during /repo-tooling installation
22+
PNPM_VERSION: "10" # REPLACE: Detected during /repo-tooling installation
23+
24+
jobs:
25+
# Job 1: Code Quality Checks (Lint, Format, Type Check)
26+
quality:
27+
name: 🔍 Code Quality
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 5
30+
31+
steps:
32+
- name: 📥 Checkout repository
33+
uses: actions/checkout@v5
34+
with:
35+
fetch-depth: 0
36+
37+
- name: 📦 Setup pnpm
38+
uses: pnpm/action-setup@v4
39+
with:
40+
version: ${{ env.PNPM_VERSION }}
41+
42+
- name: ⚙️ Setup Node.js ${{ env.NODE_VERSION }}
43+
uses: actions/setup-node@v5
44+
with:
45+
node-version: ${{ env.NODE_VERSION }}
46+
cache: "pnpm"
47+
48+
- name: 📚 Install dependencies
49+
run: pnpm install --frozen-lockfile
50+
51+
- name: 🔎 Run ESLint
52+
run: pnpm lint
53+
54+
- name: ✨ Check code formatting with Prettier
55+
run: pnpm format:check
56+
57+
- name: 🔧 Run TypeScript type checking
58+
run: pnpm type-check
59+
60+
# Job 2: Unit & Integration Tests
61+
test:
62+
name: 🧪 Tests & Coverage
63+
runs-on: ubuntu-latest
64+
timeout-minutes: 5
65+
66+
steps:
67+
- name: 📥 Checkout repository
68+
uses: actions/checkout@v5
69+
70+
- name: 📦 Setup pnpm
71+
uses: pnpm/action-setup@v4
72+
with:
73+
version: ${{ env.PNPM_VERSION }}
74+
75+
- name: ⚙️ Setup Node.js ${{ env.NODE_VERSION }}
76+
uses: actions/setup-node@v5
77+
with:
78+
node-version: ${{ env.NODE_VERSION }}
79+
cache: "pnpm"
80+
81+
- name: 📚 Install dependencies
82+
run: pnpm install --frozen-lockfile
83+
84+
- name: 🧪 Run test suite with coverage
85+
run: pnpm test:coverage
86+
env:
87+
NODE_ENV: test
88+
89+
- name: 📦 Archive coverage reports
90+
uses: actions/upload-artifact@v4
91+
if: always()
92+
with:
93+
name: coverage-report
94+
path: coverage/
95+
retention-days: 7
96+
97+
# Job 3: Build Verification
98+
build:
99+
name: 🏗️ Production Build
100+
runs-on: ubuntu-latest
101+
timeout-minutes: 5
102+
103+
steps:
104+
- name: 📥 Checkout repository
105+
uses: actions/checkout@v5
106+
107+
- name: 📦 Setup pnpm
108+
uses: pnpm/action-setup@v4
109+
with:
110+
version: ${{ env.PNPM_VERSION }}
111+
112+
- name: ⚙️ Setup Node.js ${{ env.NODE_VERSION }}
113+
uses: actions/setup-node@v5
114+
with:
115+
node-version: ${{ env.NODE_VERSION }}
116+
cache: "pnpm"
117+
118+
- name: 📚 Install dependencies
119+
run: pnpm install --frozen-lockfile
120+
121+
- name: 📦 Restore Next.js build cache
122+
uses: actions/cache@v4
123+
with:
124+
path: .next/cache
125+
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}
126+
127+
- name: 🏗️ Build Next.js application
128+
run: pnpm build
129+
130+
- name: ✅ Verify build output
131+
run: |
132+
if [ ! -d ".next" ]; then
133+
echo "❌ Error: .next directory not found"
134+
exit 1
135+
fi
136+
echo "✅ Build successful! Output directory size:"
137+
du -sh .next
138+
139+
- name: 📦 Archive build artifacts
140+
uses: actions/upload-artifact@v4
141+
with:
142+
name: build-output
143+
path: .next/
144+
retention-days: 7
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
7+
jobs:
8+
claude-review:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
pull-requests: read
13+
issues: read
14+
id-token: write
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 1
21+
22+
- name: Run Claude Code Review
23+
id: claude-review
24+
uses: anthropics/claude-code-action@v1
25+
with:
26+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
27+
prompt: |
28+
REPO: ${{ github.repository }}
29+
PR NUMBER: ${{ github.event.pull_request.number }}
30+
31+
Please review this pull request and provide feedback on:
32+
- Code quality and best practices
33+
- Potential bugs or issues
34+
- Performance considerations
35+
- Security concerns
36+
- Test coverage
37+
38+
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
39+
40+
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
41+
42+
claude_args:
43+
'--permission-mode bypassPermissions --allowed-tools "Bash(gh issue
44+
view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr
45+
comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@v1
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
additional_permissions: |
40+
actions: read
41+
42+
claude_args: "--permission-mode bypassPermissions"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Run lint-staged to check and fix files before committing
2+
echo "🔍 Running pre-commit checks..."
3+
pnpm exec lint-staged || {
4+
echo "❌ Pre-commit checks failed. Fix errors above and try again."
5+
exit 1
6+
}
7+
echo "✅ Pre-commit checks passed"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Run full validation before pushing
2+
echo "🚀 Running full validation suite..."
3+
pnpm pre-push || {
4+
echo "❌ Pre-push validation failed. Run 'pnpm pre-push' to see full output."
5+
exit 1
6+
}
7+
echo "✅ All validations passed. Pushing..."
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Dependencies
2+
node_modules
3+
pnpm-lock.yaml
4+
pnpm-workspace.yaml
5+
package-lock.json
6+
7+
# Build output
8+
.next
9+
out
10+
build
11+
dist
12+
13+
# Cache
14+
.cache
15+
.turbo
16+
17+
# Coverage
18+
coverage
19+
20+
# Misc
21+
.DS_Store
22+
*.pem
23+
24+
# Prisma
25+
prisma/migrations
26+
27+
# IDE
28+
.vscode
29+
.idea

templates/typescript/.prettierrc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"printWidth": 100,
3+
"tabWidth": 2,
4+
"singleQuote": false,
5+
"trailingComma": "es5",
6+
"semi": true,
7+
"arrowParens": "always",
8+
"proseWrap": "preserve",
9+
"plugins": ["prettier-plugin-tailwindcss"],
10+
"overrides": [
11+
{
12+
"files": ["*.md", "*.mdc"],
13+
"options": {
14+
"parser": "markdown",
15+
"tabWidth": 2,
16+
"printWidth": 100,
17+
"proseWrap": "preserve"
18+
}
19+
},
20+
{
21+
"files": ["*.json", "*.jsonc"],
22+
"options": {
23+
"tabWidth": 2
24+
}
25+
},
26+
{
27+
"files": ["*.yml", "*.yaml"],
28+
"options": {
29+
"tabWidth": 2
30+
}
31+
}
32+
]
33+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { defineConfig, globalIgnores } from "eslint/config";
2+
import nextVitals from "eslint-config-next/core-web-vitals";
3+
import nextTs from "eslint-config-next/typescript";
4+
5+
const eslintConfig = defineConfig([
6+
// Global ignores must come FIRST to ensure files are ignored before other rules are evaluated
7+
globalIgnores([
8+
// Default ignores from Next.js:
9+
".next/**",
10+
"out/**",
11+
"build/**",
12+
"next-env.d.ts",
13+
// Additional project-specific ignores:
14+
"coverage/**",
15+
"node_modules/**",
16+
"dist/**",
17+
".prisma/**",
18+
"**/*.config.ts",
19+
"**/*.config.mjs",
20+
"**/*.config.js",
21+
]),
22+
...nextVitals,
23+
...nextTs,
24+
{
25+
rules: {
26+
// Custom rules
27+
"@typescript-eslint/no-unused-vars": [
28+
"warn",
29+
{
30+
argsIgnorePattern: "^_",
31+
varsIgnorePattern: "^_",
32+
},
33+
],
34+
"@typescript-eslint/no-explicit-any": "warn",
35+
"react/no-unescaped-entities": "off",
36+
},
37+
},
38+
// Relax rules for test files
39+
{
40+
files: [
41+
"**/__tests__/**",
42+
"**/*.test.ts",
43+
"**/*.test.tsx",
44+
"**/*.spec.ts",
45+
"**/*.spec.tsx",
46+
],
47+
rules: {
48+
"@typescript-eslint/no-explicit-any": "off",
49+
"@next/next/no-img-element": "off",
50+
},
51+
},
52+
]);
53+
54+
export default eslintConfig;

0 commit comments

Comments
 (0)