claudenv 1.0.1

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.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: doc-generator
3
+ description: Generates and updates project documentation including CLAUDE.md, rules, and hooks. Use when the user asks about documentation, project setup, CLAUDE.md, or when detecting that documentation is missing or outdated.
4
+ allowed-tools: Read, Write, Glob, Grep, Bash(find:*), Bash(cat:*), Bash(node:*)
5
+ ---
6
+
7
+ # Documentation Generator Skill
8
+
9
+ ## When to use
10
+ - User mentions documentation, CLAUDE.md, or project setup
11
+ - User asks to configure Claude Code for their project
12
+ - New files detected that change the tech stack (new framework, test runner, etc.)
13
+ - After major refactoring that changes directory structure
14
+ - When CLAUDE.md references files or directories that no longer exist
15
+
16
+ ## Process
17
+
18
+ ### 1. Detect Tech Stack
19
+ Scan the project root for manifest files, framework configs, and tooling:
20
+
21
+ @.claude/skills/doc-generator/templates/detection-patterns.md
22
+
23
+ ### 2. Cross-Reference Existing Documentation
24
+ If CLAUDE.md already exists, read it and identify:
25
+ - Outdated commands or directory references
26
+ - Missing entries for new tools/dependencies
27
+ - Stale @imports pointing to removed files
28
+
29
+ ### 3. Generate or Update
30
+ - For new documentation: generate CLAUDE.md, _state.md, .claude/rules/code-style.md, .claude/rules/testing.md, .claude/rules/workflow.md
31
+ - For updates: propose specific changes and wait for user approval
32
+ - Always present generated content for review before writing
33
+ - NEVER create .md files beyond the ones listed above unless the user explicitly asks
34
+
35
+ ### 4. Validate
36
+ After writing, run the validation script:
37
+ ```
38
+ bash .claude/skills/doc-generator/scripts/validate.sh
39
+ ```
40
+
41
+ Fix any errors before completing.
42
+
43
+ ## Output Format
44
+ Generated CLAUDE.md should follow this structure:
45
+ - `# CLAUDE.md` heading
46
+ - `## Project overview` — one-sentence description with stack
47
+ - `## Commands` — all dev/build/test/lint commands
48
+ - `## Architecture` — key directories with descriptions
49
+ - `## Conventions` — @imports to code-style.md and testing.md
50
+ - `## Workflow` — @import to workflow.md (Claude Code best practices)
51
+ - `## Memory` — reference to _state.md for session persistence
52
+ - `## Rules` — project-specific rules as bullet points
53
+
54
+ Additionally generate:
55
+ - `_state.md` — project state tracking (decisions, focus, known issues)
56
+ - `.claude/rules/workflow.md` — Claude Code workflow best practices
@@ -0,0 +1,108 @@
1
+ #!/bin/bash
2
+ # Documentation validation script for Claude Code hooks.
3
+ # Exit 0 = success, Exit 2 = block action (sends stderr to Claude).
4
+ # POSIX-compatible for macOS and Linux.
5
+ set -euo pipefail
6
+
7
+ ERRORS=0
8
+ WARNINGS=0
9
+
10
+ error() {
11
+ echo "ERROR: $1" >&2
12
+ ERRORS=$((ERRORS + 1))
13
+ }
14
+
15
+ warn() {
16
+ echo "WARN: $1" >&2
17
+ WARNINGS=$((WARNINGS + 1))
18
+ }
19
+
20
+ ok() {
21
+ echo "OK: $1"
22
+ }
23
+
24
+ # --- Required files ---
25
+
26
+ if [ -f "CLAUDE.md" ] && [ -s "CLAUDE.md" ]; then
27
+ ok "CLAUDE.md exists and is non-empty"
28
+ else
29
+ error "CLAUDE.md is missing or empty"
30
+ fi
31
+
32
+ # --- Required sections in CLAUDE.md ---
33
+
34
+ if [ -f "CLAUDE.md" ]; then
35
+ for section in "## Commands" "## Architecture"; do
36
+ if grep -q "^${section}" CLAUDE.md 2>/dev/null; then
37
+ ok "CLAUDE.md has ${section}"
38
+ else
39
+ error "CLAUDE.md is missing required section: ${section}"
40
+ fi
41
+ done
42
+
43
+ # Check that ## Commands has at least one backtick-quoted command
44
+ # Use awk instead of head -n -1 for macOS compatibility
45
+ COMMANDS_SECTION=$(sed -n '/^## Commands/,/^## /p' CLAUDE.md | awk 'NR>1{print prev} {prev=$0}')
46
+ if echo "$COMMANDS_SECTION" | grep -q '`'; then
47
+ ok "## Commands section contains command examples"
48
+ else
49
+ warn "## Commands section has no inline code examples"
50
+ fi
51
+
52
+ # Check @import references
53
+ while IFS= read -r line; do
54
+ # Skip lines inside code blocks
55
+ case "$line" in
56
+ '```'*) continue ;;
57
+ esac
58
+ # Match bare @path lines (not emails, not inline)
59
+ if echo "$line" | grep -qE '^@[^@[:space:]]+$'; then
60
+ IMPORT_PATH=$(echo "$line" | sed 's/^@//')
61
+ # Resolve ~ to HOME
62
+ case "$IMPORT_PATH" in
63
+ '~/'*) IMPORT_PATH="${HOME}/${IMPORT_PATH#\~/}" ;;
64
+ esac
65
+ if [ -f "$IMPORT_PATH" ]; then
66
+ ok "@import ${IMPORT_PATH} resolves"
67
+ else
68
+ error "@import reference '${IMPORT_PATH}' does not resolve to a file"
69
+ fi
70
+ fi
71
+ done < CLAUDE.md
72
+ fi
73
+
74
+ # --- Optional structure checks ---
75
+
76
+ if [ -d ".claude" ]; then
77
+ ok ".claude/ directory exists"
78
+ else
79
+ warn ".claude/ directory not found"
80
+ fi
81
+
82
+ if [ -f ".claude/settings.json" ]; then
83
+ # Validate JSON syntax (requires python or node)
84
+ if command -v node >/dev/null 2>&1; then
85
+ if node -e "JSON.parse(require('fs').readFileSync('.claude/settings.json','utf-8'))" 2>/dev/null; then
86
+ ok ".claude/settings.json is valid JSON"
87
+ else
88
+ error ".claude/settings.json is not valid JSON"
89
+ fi
90
+ elif command -v python3 >/dev/null 2>&1; then
91
+ if python3 -c "import json; json.load(open('.claude/settings.json'))" 2>/dev/null; then
92
+ ok ".claude/settings.json is valid JSON"
93
+ else
94
+ error ".claude/settings.json is not valid JSON"
95
+ fi
96
+ fi
97
+ fi
98
+
99
+ # --- Summary ---
100
+
101
+ echo ""
102
+ echo "Validation complete: ${ERRORS} error(s), ${WARNINGS} warning(s)"
103
+
104
+ if [ "$ERRORS" -gt 0 ]; then
105
+ exit 2
106
+ fi
107
+
108
+ exit 0
@@ -0,0 +1,76 @@
1
+ # Tech Stack Detection Patterns
2
+
3
+ Use these patterns to identify the project's tech stack by scanning for files.
4
+
5
+ ## Language / Runtime Detection (check manifest files first)
6
+
7
+ | File | Language | Runtime |
8
+ |------|----------|---------|
9
+ | `package.json` | JavaScript/TypeScript | Node.js |
10
+ | `pyproject.toml`, `setup.py`, `requirements.txt` | Python | Python |
11
+ | `go.mod` | Go | Go |
12
+ | `Cargo.toml` | Rust | Rust |
13
+ | `Gemfile` | Ruby | Ruby |
14
+ | `composer.json` | PHP | PHP |
15
+ | `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/Kotlin | JVM |
16
+ | `*.csproj`, `*.sln` | C# | .NET |
17
+
18
+ **TypeScript override**: If `tsconfig.json` exists alongside `package.json`, the language is TypeScript.
19
+
20
+ ## Framework Detection (check config files)
21
+
22
+ | File | Framework |
23
+ |------|-----------|
24
+ | `next.config.js/mjs/ts` | Next.js |
25
+ | `nuxt.config.ts/js` | Nuxt |
26
+ | `vite.config.js/ts/mts` | Vite |
27
+ | `svelte.config.js` | SvelteKit |
28
+ | `astro.config.mjs/ts` | Astro |
29
+ | `angular.json` | Angular |
30
+ | `manage.py` | Django |
31
+ | `config/routes.rb` | Rails |
32
+ | `artisan` | Laravel |
33
+ | `application.properties/yml` | Spring Boot |
34
+
35
+ ## Package Manager Detection (check lockfiles)
36
+
37
+ | File | Package Manager |
38
+ |------|----------------|
39
+ | `package-lock.json` | npm |
40
+ | `yarn.lock` | Yarn |
41
+ | `pnpm-lock.yaml` | pnpm |
42
+ | `bun.lockb`, `bun.lock` | Bun |
43
+ | `poetry.lock` | Poetry |
44
+ | `Pipfile.lock` | Pipenv |
45
+ | `uv.lock` | uv |
46
+
47
+ ## Test Framework Detection
48
+
49
+ | File | Framework |
50
+ |------|-----------|
51
+ | `vitest.config.*` | Vitest |
52
+ | `jest.config.*` | Jest |
53
+ | `playwright.config.*` | Playwright |
54
+ | `cypress.config.*` | Cypress |
55
+ | `pytest.ini`, `conftest.py` | pytest |
56
+ | `.rspec` | RSpec |
57
+
58
+ Also check dependencies in `package.json` or `pyproject.toml`.
59
+
60
+ ## CI/CD Detection
61
+
62
+ | Path | System |
63
+ |------|--------|
64
+ | `.github/workflows/*.yml` | GitHub Actions |
65
+ | `.gitlab-ci.yml` | GitLab CI |
66
+ | `Jenkinsfile` | Jenkins |
67
+ | `.circleci/config.yml` | CircleCI |
68
+
69
+ ## Monorepo Detection
70
+
71
+ | File | Tool |
72
+ |------|------|
73
+ | `turbo.json` | Turborepo |
74
+ | `nx.json` | Nx |
75
+ | `lerna.json` | Lerna |
76
+ | `pnpm-workspace.yaml` | pnpm workspaces |
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Detection maps and constants for the documentation generator.
3
+ */
4
+
5
+ // Maps manifest filenames to language/platform
6
+ export const MANIFEST_MAP = {
7
+ 'package.json': { language: 'javascript', runtime: 'node' },
8
+ 'pyproject.toml': { language: 'python', runtime: 'python' },
9
+ 'setup.py': { language: 'python', runtime: 'python' },
10
+ 'requirements.txt': { language: 'python', runtime: 'python' },
11
+ 'go.mod': { language: 'go', runtime: 'go' },
12
+ 'Cargo.toml': { language: 'rust', runtime: 'rust' },
13
+ 'Gemfile': { language: 'ruby', runtime: 'ruby' },
14
+ 'composer.json': { language: 'php', runtime: 'php' },
15
+ 'pom.xml': { language: 'java', runtime: 'jvm' },
16
+ 'build.gradle': { language: 'java', runtime: 'jvm' },
17
+ 'build.gradle.kts': { language: 'kotlin', runtime: 'jvm' },
18
+ '*.csproj': { language: 'csharp', runtime: 'dotnet' },
19
+ '*.sln': { language: 'csharp', runtime: 'dotnet' },
20
+ };
21
+
22
+ // TypeScript override — detected via tsconfig.json presence alongside package.json
23
+ export const TYPESCRIPT_INDICATORS = ['tsconfig.json', 'tsconfig.base.json'];
24
+
25
+ // Maps config filenames to frameworks
26
+ export const FRAMEWORK_MAP = {
27
+ 'next.config.js': 'next.js',
28
+ 'next.config.mjs': 'next.js',
29
+ 'next.config.ts': 'next.js',
30
+ 'nuxt.config.ts': 'nuxt',
31
+ 'nuxt.config.js': 'nuxt',
32
+ 'vite.config.js': 'vite',
33
+ 'vite.config.ts': 'vite',
34
+ 'vite.config.mts': 'vite',
35
+ 'svelte.config.js': 'sveltekit',
36
+ 'astro.config.mjs': 'astro',
37
+ 'astro.config.ts': 'astro',
38
+ 'remix.config.js': 'remix',
39
+ 'angular.json': 'angular',
40
+ 'vue.config.js': 'vue-cli',
41
+ 'gatsby-config.js': 'gatsby',
42
+ 'gatsby-config.ts': 'gatsby',
43
+ 'manage.py': 'django',
44
+ 'config/routes.rb': 'rails',
45
+ 'artisan': 'laravel',
46
+ 'symfony.lock': 'symfony',
47
+ 'application.properties': 'spring-boot',
48
+ 'application.yml': 'spring-boot',
49
+ };
50
+
51
+ // Maps lockfiles to package managers
52
+ export const PACKAGE_MANAGER_MAP = {
53
+ 'package-lock.json': 'npm',
54
+ 'yarn.lock': 'yarn',
55
+ 'pnpm-lock.yaml': 'pnpm',
56
+ 'bun.lockb': 'bun',
57
+ 'bun.lock': 'bun',
58
+ 'poetry.lock': 'poetry',
59
+ 'Pipfile.lock': 'pipenv',
60
+ 'uv.lock': 'uv',
61
+ 'Gemfile.lock': 'bundler',
62
+ 'composer.lock': 'composer',
63
+ 'go.sum': 'go-modules',
64
+ 'Cargo.lock': 'cargo',
65
+ };
66
+
67
+ // Maps test config files or dependency names to test frameworks
68
+ export const TEST_FRAMEWORK_MAP = {
69
+ // Config file indicators
70
+ 'jest.config.js': 'jest',
71
+ 'jest.config.ts': 'jest',
72
+ 'jest.config.mjs': 'jest',
73
+ 'vitest.config.js': 'vitest',
74
+ 'vitest.config.ts': 'vitest',
75
+ 'vitest.config.mts': 'vitest',
76
+ '.mocharc.yml': 'mocha',
77
+ '.mocharc.json': 'mocha',
78
+ 'cypress.config.js': 'cypress',
79
+ 'cypress.config.ts': 'cypress',
80
+ 'playwright.config.js': 'playwright',
81
+ 'playwright.config.ts': 'playwright',
82
+ 'pytest.ini': 'pytest',
83
+ 'conftest.py': 'pytest',
84
+ 'setup.cfg': 'pytest', // often contains [tool:pytest]
85
+ '.rspec': 'rspec',
86
+ 'phpunit.xml': 'phpunit',
87
+ 'phpunit.xml.dist': 'phpunit',
88
+ };
89
+
90
+ // Dependency names that indicate test frameworks (for package.json/pyproject.toml parsing)
91
+ export const TEST_DEPENDENCY_MAP = {
92
+ jest: 'jest',
93
+ vitest: 'vitest',
94
+ mocha: 'mocha',
95
+ ava: 'ava',
96
+ tap: 'tap',
97
+ cypress: 'cypress',
98
+ playwright: 'playwright',
99
+ '@playwright/test': 'playwright',
100
+ pytest: 'pytest',
101
+ unittest: 'unittest',
102
+ nose2: 'nose2',
103
+ };
104
+
105
+ // CI/CD file patterns
106
+ export const CI_PATTERNS = [
107
+ { glob: '.github/workflows/*.yml', name: 'github-actions' },
108
+ { glob: '.github/workflows/*.yaml', name: 'github-actions' },
109
+ { glob: '.gitlab-ci.yml', name: 'gitlab-ci' },
110
+ { glob: 'Jenkinsfile', name: 'jenkins' },
111
+ { glob: '.circleci/config.yml', name: 'circleci' },
112
+ { glob: 'bitbucket-pipelines.yml', name: 'bitbucket-pipelines' },
113
+ { glob: '.travis.yml', name: 'travis-ci' },
114
+ { glob: 'azure-pipelines.yml', name: 'azure-devops' },
115
+ ];
116
+
117
+ // Linter config files
118
+ export const LINTER_MAP = {
119
+ '.eslintrc': 'eslint',
120
+ '.eslintrc.js': 'eslint',
121
+ '.eslintrc.json': 'eslint',
122
+ '.eslintrc.yml': 'eslint',
123
+ 'eslint.config.js': 'eslint',
124
+ 'eslint.config.mjs': 'eslint',
125
+ 'eslint.config.ts': 'eslint',
126
+ 'biome.json': 'biome',
127
+ 'biome.jsonc': 'biome',
128
+ '.pylintrc': 'pylint',
129
+ 'ruff.toml': 'ruff',
130
+ '.rubocop.yml': 'rubocop',
131
+ '.golangci.yml': 'golangci-lint',
132
+ '.golangci.yaml': 'golangci-lint',
133
+ 'clippy.toml': 'clippy',
134
+ };
135
+
136
+ // Formatter config files
137
+ export const FORMATTER_MAP = {
138
+ '.prettierrc': 'prettier',
139
+ '.prettierrc.js': 'prettier',
140
+ '.prettierrc.json': 'prettier',
141
+ '.prettierrc.yml': 'prettier',
142
+ 'prettier.config.js': 'prettier',
143
+ 'prettier.config.mjs': 'prettier',
144
+ '.editorconfig': 'editorconfig',
145
+ 'rustfmt.toml': 'rustfmt',
146
+ '.style.yapf': 'yapf',
147
+ 'pyproject.toml': null, // checked separately for [tool.black] or [tool.ruff.format]
148
+ };
149
+
150
+ // Monorepo indicators
151
+ export const MONOREPO_MAP = {
152
+ 'turbo.json': 'turborepo',
153
+ 'nx.json': 'nx',
154
+ 'lerna.json': 'lerna',
155
+ 'pnpm-workspace.yaml': 'pnpm-workspaces',
156
+ 'rush.json': 'rush',
157
+ };
158
+
159
+ // Infrastructure files
160
+ export const INFRA_MAP = {
161
+ 'Dockerfile': 'docker',
162
+ 'docker-compose.yml': 'docker-compose',
163
+ 'docker-compose.yaml': 'docker-compose',
164
+ 'terraform/': 'terraform',
165
+ '*.tf': 'terraform',
166
+ 'cdk.json': 'aws-cdk',
167
+ 'serverless.yml': 'serverless',
168
+ 'serverless.ts': 'serverless',
169
+ 'fly.toml': 'fly-io',
170
+ 'vercel.json': 'vercel',
171
+ 'netlify.toml': 'netlify',
172
+ 'render.yaml': 'render',
173
+ 'railway.json': 'railway',
174
+ 'Procfile': 'heroku',
175
+ };
176
+
177
+ // Required sections in CLAUDE.md for validation
178
+ export const REQUIRED_SECTIONS = ['## Commands', '## Architecture'];
179
+
180
+ // Suggested commands by framework
181
+ export const SUGGESTED_COMMANDS = {
182
+ 'next.js': {
183
+ dev: '{pm} next dev',
184
+ build: '{pm} next build',
185
+ test: '{pm} vitest run',
186
+ lint: '{pm} next lint',
187
+ },
188
+ vite: {
189
+ dev: '{pm} vite',
190
+ build: '{pm} vite build',
191
+ test: '{pm} vitest run',
192
+ },
193
+ django: {
194
+ dev: 'python manage.py runserver',
195
+ test: 'python manage.py test',
196
+ migrate: 'python manage.py migrate',
197
+ },
198
+ rails: {
199
+ dev: 'bin/rails server',
200
+ test: 'bin/rails test',
201
+ migrate: 'bin/rails db:migrate',
202
+ },
203
+ 'spring-boot': {
204
+ dev: './mvnw spring-boot:run',
205
+ build: './mvnw package',
206
+ test: './mvnw test',
207
+ },
208
+ laravel: {
209
+ dev: 'php artisan serve',
210
+ test: 'php artisan test',
211
+ migrate: 'php artisan migrate',
212
+ },
213
+ go: {
214
+ build: 'go build ./...',
215
+ test: 'go test ./...',
216
+ lint: 'golangci-lint run',
217
+ },
218
+ rust: {
219
+ build: 'cargo build',
220
+ test: 'cargo test',
221
+ lint: 'cargo clippy',
222
+ },
223
+ };
224
+
225
+ // Framework choices by language for cold-start prompts
226
+ export const FRAMEWORKS_BY_LANGUAGE = {
227
+ typescript: ['Next.js', 'Vite + React', 'Vite + Vue', 'SvelteKit', 'Astro', 'Express', 'Fastify', 'NestJS', 'None'],
228
+ javascript: ['Next.js', 'Vite + React', 'Vite + Vue', 'Express', 'Fastify', 'None'],
229
+ python: ['Django', 'FastAPI', 'Flask', 'None'],
230
+ go: ['Gin', 'Echo', 'Fiber', 'Chi', 'Standard library', 'None'],
231
+ rust: ['Actix Web', 'Axum', 'Rocket', 'None'],
232
+ ruby: ['Rails', 'Sinatra', 'None'],
233
+ php: ['Laravel', 'Symfony', 'None'],
234
+ java: ['Spring Boot', 'Quarkus', 'Micronaut', 'None'],
235
+ kotlin: ['Spring Boot', 'Ktor', 'None'],
236
+ csharp: ['ASP.NET Core', 'Blazor', 'None'],
237
+ };