clauderc 1.0.4 → 1.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clauderc",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Setup Claude Code with best practices - agents, skills, commands, and templates",
5
5
  "type": "module",
6
6
  "bin": {
package/src/detector.js CHANGED
@@ -40,6 +40,9 @@ const ANALYSIS_FILES = [
40
40
  'vite.config.*',
41
41
  'next.config.*',
42
42
  'nuxt.config.*',
43
+ 'commitlint.config.js',
44
+ '.releaserc',
45
+ 'release.config.js',
43
46
  ];
44
47
 
45
48
  /**
@@ -299,6 +302,68 @@ function getRunCommand(pm) {
299
302
  return commands[pm] || '';
300
303
  }
301
304
 
305
+ /**
306
+ * Detect commit convention tools
307
+ */
308
+ function detectCommitConvention(projectPath) {
309
+ const commitlintConfigs = [
310
+ 'commitlint.config.js',
311
+ 'commitlint.config.cjs',
312
+ 'commitlint.config.mjs',
313
+ 'commitlint.config.ts',
314
+ '.commitlintrc.js',
315
+ '.commitlintrc.json',
316
+ '.commitlintrc.yml',
317
+ ];
318
+
319
+ const semanticReleaseConfigs = [
320
+ 'release.config.js',
321
+ 'release.config.cjs',
322
+ 'release.config.mjs',
323
+ '.releaserc',
324
+ '.releaserc.json',
325
+ '.releaserc.js',
326
+ '.releaserc.yml',
327
+ ];
328
+
329
+ const commitlint = commitlintConfigs.some(f => existsSync(join(projectPath, f)));
330
+ const husky = existsSync(join(projectPath, '.husky/commit-msg'));
331
+ const semanticRelease = semanticReleaseConfigs.some(f => existsSync(join(projectPath, f)));
332
+
333
+ let commitizen = false;
334
+ let commitlintDep = false;
335
+ let conventionalChangelog = false;
336
+ let standardVersion = false;
337
+ let semanticReleaseDep = false;
338
+
339
+ try {
340
+ const pkg = JSON.parse(readFileSync(join(projectPath, 'package.json'), 'utf-8'));
341
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
342
+ commitizen = !!deps['commitizen'];
343
+ commitlintDep = !!deps['@commitlint/cli'];
344
+ conventionalChangelog = !!deps['conventional-changelog'];
345
+ standardVersion = !!deps['standard-version'];
346
+ semanticReleaseDep = !!deps['semantic-release'];
347
+ } catch {
348
+ // no package.json or parse error
349
+ }
350
+
351
+ const hasCommitlint = commitlint || commitlintDep;
352
+ const hasSemanticRelease = semanticRelease || semanticReleaseDep;
353
+ const hasCommitizen = commitizen;
354
+
355
+ if (!hasCommitlint && !husky && !hasSemanticRelease && !hasCommitizen && !conventionalChangelog && !standardVersion) {
356
+ return null;
357
+ }
358
+
359
+ return {
360
+ commitlint: hasCommitlint,
361
+ husky,
362
+ semanticRelease: hasSemanticRelease,
363
+ commitizen: hasCommitizen,
364
+ };
365
+ }
366
+
302
367
  /**
303
368
  * Detect project stack from current directory
304
369
  */
@@ -376,6 +441,9 @@ export function detectStack(projectPath = process.cwd()) {
376
441
  // Detect CI
377
442
  result.ci = detectCI(projectPath);
378
443
 
444
+ // Detect commit convention
445
+ result.commitConvention = detectCommitConvention(projectPath);
446
+
379
447
  return result;
380
448
  }
381
449
 
package/src/project.js CHANGED
@@ -177,6 +177,38 @@ Use Plan Mode (Shift+Tab 2x) for:
177
177
  - NEVER skip tests without explicit approval
178
178
  `;
179
179
 
180
+ content += `
181
+ ## Conventions
182
+
183
+ ### Commits (Conventional Commits)
184
+ - Format: \`<type>(<scope>): <subject>\`
185
+ - Types: \`feat\` | \`fix\` | \`docs\` | \`style\` | \`refactor\` | \`perf\` | \`test\` | \`chore\` | \`ci\`
186
+ - Subject: imperative mood, max 72 chars, no period
187
+ - Breaking changes: add \`!\` after type or \`BREAKING CHANGE:\` in footer
188
+
189
+ ### Semantic Versioning
190
+ - \`feat\` → MINOR (1.x.0)
191
+ - \`fix\`, \`docs\`, \`refactor\`, \`perf\`, \`style\` → PATCH (1.0.x)
192
+ - \`BREAKING CHANGE\` or \`!\` → MAJOR (x.0.0)
193
+ - \`test\`, \`chore\`, \`ci\` → no version change
194
+
195
+ ### Pull Requests
196
+ - PR title: same Conventional Commits format
197
+ - PR body: Summary (why), Changes (what), Test Plan
198
+ - Run \`/verify\` before every PR
199
+ `;
200
+
201
+ if (config.stack.commitConvention) {
202
+ const tools = [];
203
+ if (config.stack.commitConvention.commitlint) tools.push('commitlint');
204
+ if (config.stack.commitConvention.husky) tools.push('husky');
205
+ if (config.stack.commitConvention.semanticRelease) tools.push('semantic-release');
206
+ if (config.stack.commitConvention.commitizen) tools.push('commitizen');
207
+ if (tools.length > 0) {
208
+ content += `> This project uses ${tools.join(', ')} — follow its configured rules.\n\n`;
209
+ }
210
+ }
211
+
180
212
  if (customRules && customRules.length > 0) {
181
213
  content += `
182
214
  ## Project Rules
@@ -351,19 +383,70 @@ ${commands.setup || '# No setup command detected - configure in CLAUDE.md'}
351
383
  \`\`\`
352
384
  `,
353
385
 
354
- pr: `# Create Pull Request
386
+ pr: `# Create a Semantic Pull Request
387
+
388
+ Create a PR following Conventional Commits with structured description.
389
+
390
+ ## PR Title
391
+ \`\`\`
392
+ <type>(<scope>): <description>
393
+ \`\`\`
355
394
 
356
- Commit, push, and create a PR.
395
+ ## PR Body Template
396
+ - **Summary**: 1-3 bullets explaining WHAT and WHY
397
+ - **Type of Change**: feat / fix / docs / refactor / perf / test / chore / breaking
398
+ - **Changes**: Detailed list
399
+ - **Breaking Changes**: If applicable, what breaks and migration steps
400
+ - **Test Plan**: How it was tested
357
401
 
358
402
  ## Steps
359
- 1. Stage all changes
360
- 2. Commit with descriptive message
361
- 3. Push to remote
362
- 4. Create PR with \`gh pr create\`
403
+ 1. Run \`/verify\` to ensure all checks pass
404
+ 2. Analyze all commits on branch since base
405
+ 3. Determine PR type (highest-impact: breaking > feat > fix > others)
406
+ 4. Generate title in Conventional Commits format (max 72 chars)
407
+ 5. Generate structured body
408
+ 6. Push branch and create PR with \`gh pr create\`
363
409
 
364
410
  ## Prerequisites
365
411
  - \`gh\` CLI installed and authenticated
366
412
  - All tests passing (\`/verify\`)
413
+ - Changes committed with \`/commit\`
414
+ `,
415
+
416
+ commit: `# Create a Semantic Commit
417
+
418
+ Create a well-structured commit following Conventional Commits.
419
+
420
+ ## Format
421
+ \`\`\`
422
+ <type>(<scope>): <subject>
423
+ \`\`\`
424
+
425
+ ## Types
426
+ | Type | Description | Version Impact |
427
+ |------|-------------|----------------|
428
+ | feat | New feature | MINOR |
429
+ | fix | Bug fix | PATCH |
430
+ | docs | Documentation | PATCH |
431
+ | refactor | Code restructuring | PATCH |
432
+ | perf | Performance improvement | PATCH |
433
+ | test | Tests | No release |
434
+ | chore | Build/CI/tooling | No release |
435
+
436
+ ## Rules
437
+ - Imperative mood ("add" not "added")
438
+ - Max 72 chars subject line
439
+ - No period at end
440
+ - Breaking changes: \`!\` after type or \`BREAKING CHANGE:\` footer
441
+ - Reference issues: \`Fixes #123\` in footer
442
+
443
+ ## Steps
444
+ 1. Analyze staged changes with \`git diff --staged\`
445
+ 2. Determine type from nature of changes
446
+ 3. Identify scope (module/component affected)
447
+ 4. Write subject in imperative mood
448
+ 5. Add body if change needs explanation
449
+ 6. Execute \`git commit -m "<message>"\`
367
450
  `,
368
451
  };
369
452
 
@@ -512,6 +595,7 @@ export async function runProjectWizard(options = {}) {
512
595
  log(' ├── commands/verify.md');
513
596
  log(' ├── commands/setup.md');
514
597
  log(' ├── commands/pr.md');
598
+ log(' ├── commands/commit.md');
515
599
  log(' ├── settings.json');
516
600
  log(' CLAUDE.md');
517
601
  if (useMerge) {
@@ -532,6 +616,7 @@ export async function runProjectWizard(options = {}) {
532
616
  { path: join(claudeDir, 'commands', 'verify.md'), content: generateCommandFile('verify', config), type: 'command file' },
533
617
  { path: join(claudeDir, 'commands', 'setup.md'), content: generateCommandFile('setup', config), type: 'command file' },
534
618
  { path: join(claudeDir, 'commands', 'pr.md'), content: generateCommandFile('pr', config), type: 'command file' },
619
+ { path: join(claudeDir, 'commands', 'commit.md'), content: generateCommandFile('commit', config), type: 'command file' },
535
620
  ];
536
621
 
537
622
  for (const file of files) {
@@ -549,7 +634,7 @@ export async function runProjectWizard(options = {}) {
549
634
  log(' Next steps:');
550
635
  log(' 1. Review CLAUDE.md and adjust as needed');
551
636
  log(' 2. Commit .claude/ to your repository');
552
- log(' 3. Run /test, /lint, /verify in Claude Code\n');
637
+ log(' 3. Run /test, /lint, /verify, /commit, /pr in Claude Code\n');
553
638
 
554
639
  return config;
555
640
  } catch (error) {
@@ -128,6 +128,16 @@ Create `CLAUDE.md` in project root. Requirements:
128
128
 
129
129
  ### settings.json Format
130
130
 
131
+ **CRITICAL: Only use properties that exist in the official schema. DO NOT invent properties.**
132
+
133
+ Valid top-level keys: `permissions`, `hooks`, `attribution`, `language`, `model`, `env`, `sandbox`, `respectGitignore`, `cleanupPeriodDays`
134
+
135
+ - `permissions`: `allow`, `deny`, `ask`, `defaultMode`, `additionalDirectories`
136
+ - `hooks`: `PreToolUse`, `PostToolUse`, `Stop`, `SessionStart`, `SessionEnd`
137
+ - `attribution`: `commit`, `pr`
138
+
139
+ **NEVER use:** `version`, `project`, `description`, `defaults`, `quality_gates`, `design_system`, `conventions`, `context_optimization`, `deny_read`, `require_approval`, `auto_approve`. These DO NOT exist. Textual instructions go in CLAUDE.md.
140
+
131
141
  ```json
132
142
  {
133
143
  "permissions": {
@@ -140,7 +150,7 @@ Create `CLAUDE.md` in project root. Requirements:
140
150
  "PostToolUse": [
141
151
  {
142
152
  "matcher": "Edit|Write",
143
- "hooks": ["{{LINT_FIX_COMMAND}}"]
153
+ "hooks": [{ "type": "command", "command": "{{LINT_FIX_COMMAND}}" }]
144
154
  }
145
155
  ]
146
156
  }
@@ -0,0 +1,80 @@
1
+ # Create a Semantic Commit
2
+
3
+ Create a well-structured commit following Conventional Commits specification.
4
+
5
+ ## Format
6
+
7
+ ```
8
+ <type>(<scope>): <subject>
9
+
10
+ [optional body]
11
+
12
+ [optional footer(s)]
13
+ ```
14
+
15
+ ## Types
16
+
17
+ | Type | Description | Version Impact |
18
+ |------|-------------|----------------|
19
+ | feat | New feature | MINOR (0.x.0) |
20
+ | fix | Bug fix | PATCH (0.0.x) |
21
+ | docs | Documentation only | PATCH |
22
+ | style | Formatting, no code change | PATCH |
23
+ | refactor | Code restructuring | PATCH |
24
+ | perf | Performance improvement | PATCH |
25
+ | test | Adding or fixing tests | No release |
26
+ | chore | Build, CI, tooling | No release |
27
+ | ci | CI/CD configuration | No release |
28
+
29
+ ## Breaking Changes
30
+
31
+ Add `!` after type or `BREAKING CHANGE:` in footer for MAJOR version bumps:
32
+
33
+ ```
34
+ feat!: remove deprecated API endpoints
35
+
36
+ BREAKING CHANGE: /v1/users removed. Use /v2/users instead.
37
+ ```
38
+
39
+ ## Steps
40
+
41
+ 1. Run `git diff --staged` to analyze staged changes
42
+ 2. Determine the appropriate type from the changes
43
+ 3. Identify the scope (module, component, or area affected)
44
+ 4. Write a concise subject (imperative mood, no period, max 72 chars)
45
+ 5. Add body if the change needs explanation (wrap at 72 chars)
46
+ 6. Add footer for breaking changes or issue references
47
+ 7. Execute `git commit -m "<message>"`
48
+
49
+ ## Rules
50
+
51
+ - Subject MUST be imperative mood ("add feature" not "added feature")
52
+ - Subject MUST NOT exceed 72 characters
53
+ - Subject MUST NOT end with a period
54
+ - Body separated from subject by blank line
55
+ - Reference issues: `Closes #123` or `Fixes #456` in footer
56
+ - Multiple logical changes = separate commits
57
+
58
+ ## Examples
59
+
60
+ ```bash
61
+ # Simple feature
62
+ git commit -m "feat(auth): add OAuth2 login support"
63
+
64
+ # Bug fix with issue reference
65
+ git commit -m "fix(api): handle null response from payment gateway
66
+
67
+ The payment gateway returns null when the session expires.
68
+ Added null check and automatic session refresh.
69
+
70
+ Fixes #234"
71
+
72
+ # Breaking change
73
+ git commit -m "feat(api)!: migrate to v2 authentication flow
74
+
75
+ BREAKING CHANGE: API key format changed from UUID to JWT.
76
+ All existing API keys must be regenerated."
77
+
78
+ # Chore (no release triggered)
79
+ git commit -m "chore(deps): upgrade lodash to 4.17.21"
80
+ ```
@@ -1,46 +1,77 @@
1
- # Create a Pull Request
1
+ # Create a Semantic Pull Request
2
2
 
3
- Commit changes, push to remote, and create a PR with generated description.
3
+ Create a PR following Conventional Commits with structured description.
4
4
 
5
- ## Workflow
6
- 1. Stage all changes
7
- 2. Generate commit message from diff
8
- 3. Push to current branch
9
- 4. Create PR with description
5
+ ## PR Title Format
10
6
 
11
- ## Prerequisites
12
- - `gh` CLI installed and authenticated
13
- - Changes ready to commit
7
+ Use Conventional Commits format:
8
+
9
+ ```
10
+ <type>(<scope>): <description>
11
+ ```
12
+
13
+ Examples:
14
+ - `feat(auth): add OAuth2 login flow`
15
+ - `fix(api): resolve race condition in payment processing`
16
+ - `docs(readme): add deployment instructions`
17
+
18
+ ## PR Body Template
19
+
20
+ ```markdown
21
+ ## Summary
22
+ <!-- 1-3 bullet points: WHAT changed and WHY -->
23
+
24
+ ## Type of Change
25
+ - [ ] feat: New feature (MINOR version bump)
26
+ - [ ] fix: Bug fix (PATCH version bump)
27
+ - [ ] docs: Documentation
28
+ - [ ] refactor: Code restructuring
29
+ - [ ] perf: Performance improvement
30
+ - [ ] test: Test changes
31
+ - [ ] chore: Build/CI/tooling
32
+ - [ ] breaking: Contains breaking changes (MAJOR version bump)
33
+
34
+ ## Changes
35
+ <!-- Detailed list of changes -->
36
+
37
+ ## Breaking Changes
38
+ <!-- If applicable: what breaks and migration steps -->
39
+
40
+ ## Test Plan
41
+ <!-- How was this tested? What should reviewers verify? -->
42
+ ```
43
+
44
+ ## Steps
45
+
46
+ 1. Verify all changes are committed and tests pass (`/verify`)
47
+ 2. Analyze all commits on the branch since diverging from base
48
+ 3. Determine PR type from commits (use highest-impact type: breaking > feat > fix > others)
49
+ 4. Generate title in Conventional Commits format (max 72 chars)
50
+ 5. Generate body using template above
51
+ 6. Push branch to remote
52
+ 7. Create PR with `gh pr create`
14
53
 
15
54
  ## Implementation
55
+
16
56
  ```bash
17
- # Get current branch
18
57
  BRANCH=$(git branch --show-current)
19
58
 
20
- # Check for changes
21
- if [ -z "$(git status --porcelain)" ]; then
22
- echo "No changes to commit"
23
- exit 0
59
+ # Ensure clean state
60
+ if [ -n "$(git status --porcelain)" ]; then
61
+ echo "Uncommitted changes. Run /commit first."
62
+ exit 1
24
63
  fi
25
64
 
26
- # Stage changes
27
- git add -A
28
-
29
- # Show what will be committed
30
- echo "📝 Changes to commit:"
31
- git status --short
32
-
33
- # Commit (message should be provided by Claude)
34
- # git commit -m "..."
35
-
36
- # Push
65
+ # Push and create PR
37
66
  git push -u origin $BRANCH
38
-
39
- # Create PR
40
- gh pr create --fill
67
+ gh pr create --title "<type>(<scope>): <description>" --body "<generated body>"
41
68
  ```
42
69
 
43
- ## Notes
44
- - Claude will generate an appropriate commit message
45
- - PR description is auto-generated from commits
46
- - Use `--draft` flag for draft PRs
70
+ ## Rules
71
+
72
+ - PR title MUST follow Conventional Commits format
73
+ - PR title MUST be under 72 characters
74
+ - Summary explains WHY, not just WHAT
75
+ - Breaking changes: title MUST include `!` after type
76
+ - Always run `/verify` before creating a PR
77
+ - Prefer small, focused PRs
@@ -42,6 +42,11 @@
42
42
  "added": "1.0.0",
43
43
  "description": "Project setup and dependency installation"
44
44
  },
45
+ "commands/commit.md": {
46
+ "version": "1.0.0",
47
+ "added": "1.1.0",
48
+ "description": "Semantic commit command"
49
+ },
45
50
  "templates/project-setup/CLAUDE_MD_TEMPLATE.md": {
46
51
  "version": "1.0.0",
47
52
  "added": "1.0.0",
@@ -82,6 +87,7 @@
82
87
  "commands/verify.md - Verify command",
83
88
  "commands/pr.md - PR command",
84
89
  "commands/setup.md - Setup command",
90
+ "commands/commit.md - Commit command",
85
91
  "templates/project-setup/* - All project setup templates"
86
92
  ],
87
93
  "changed": [],
@@ -31,6 +31,13 @@ Use this template as base for generating project-specific CLAUDE.md files.
31
31
  - Always run `{{VERIFY_COMMAND}}` before commit
32
32
  - Parallel work OK for: independent modules, test files, docs
33
33
 
34
+ ## Conventions
35
+ - Commits: [Conventional Commits](https://conventionalcommits.org) — `<type>(<scope>): <subject>`
36
+ - Types: feat, fix, docs, style, refactor, perf, test, chore, ci
37
+ - Breaking changes: `!` suffix or `BREAKING CHANGE:` footer
38
+ - PRs: same title format, structured body (Summary, Changes, Test Plan)
39
+ - Versioning: feat → MINOR, fix → PATCH, breaking → MAJOR
40
+
34
41
  ## Architecture
35
42
  {{ARCHITECTURE_NOTES}}
36
43
 
@@ -131,7 +131,12 @@ Location: `.claude/settings.json`
131
131
  "PostToolUse": [
132
132
  {
133
133
  "matcher": "Edit|Write",
134
- "hooks": ["npm run lint --fix || true"]
134
+ "hooks": [
135
+ {
136
+ "type": "command",
137
+ "command": "npm run lint --fix || true"
138
+ }
139
+ ]
135
140
  }
136
141
  ]
137
142
  }
@@ -168,7 +173,7 @@ npm run lint && npm test && npm run build
168
173
  "hooks": {
169
174
  "PostToolUse": [{
170
175
  "matcher": "Edit|Write",
171
- "hooks": ["npx eslint --fix ${file} || true"]
176
+ "hooks": [{ "type": "command", "command": "npx eslint --fix ${file} || true" }]
172
177
  }]
173
178
  }
174
179
  }
@@ -200,7 +205,7 @@ ruff check . && mypy . && pytest
200
205
  "hooks": {
201
206
  "PostToolUse": [{
202
207
  "matcher": "Edit|Write",
203
- "hooks": ["ruff format ${file} || true"]
208
+ "hooks": [{ "type": "command", "command": "ruff format ${file} || true" }]
204
209
  }]
205
210
  }
206
211
  }