dotclaudemd 0.1.1 → 0.2.0
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/README.md +470 -52
- package/dist/{browse-7V4CRGTH.js → browse-JZNKTNHN.js} +4 -4
- package/dist/{chunk-3ERFQLAD.js → chunk-NYAP7NPA.js} +2 -2
- package/dist/{chunk-3R6PUA3E.js → chunk-SU2BLIFX.js} +5 -1
- package/dist/chunk-SU2BLIFX.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/{doctor-4B7J2EH3.js → doctor-BHKDRHD4.js} +2 -2
- package/dist/{init-GLWLFVHN.js → init-5PXXIWA7.js} +81 -5
- package/dist/init-5PXXIWA7.js.map +1 -0
- package/dist/{lint-W7ZIDPL7.js → lint-BMJBNSBA.js} +3 -3
- package/dist/lint-BMJBNSBA.js.map +1 -0
- package/package.json +1 -1
- package/templates/java/springboot.md +64 -0
- package/templates/javascript/astro.md +51 -0
- package/templates/javascript/sveltekit.md +53 -0
- package/templates/javascript/typescript-monorepo.md +50 -0
- package/templates/javascript/vue-nuxt.md +57 -0
- package/templates/php/laravel.md +55 -0
- package/templates/ruby/rails.md +55 -0
- package/dist/chunk-3R6PUA3E.js.map +0 -1
- package/dist/init-GLWLFVHN.js.map +0 -1
- package/dist/lint-W7ZIDPL7.js.map +0 -1
- /package/dist/{browse-7V4CRGTH.js.map → browse-JZNKTNHN.js.map} +0 -0
- /package/dist/{chunk-3ERFQLAD.js.map → chunk-NYAP7NPA.js.map} +0 -0
- /package/dist/{doctor-4B7J2EH3.js.map → doctor-BHKDRHD4.js.map} +0 -0
package/README.md
CHANGED
|
@@ -2,107 +2,525 @@
|
|
|
2
2
|
|
|
3
3
|
CLAUDE.md Template Registry CLI — scaffold, lint, and health-check your CLAUDE.md files.
|
|
4
4
|
|
|
5
|
-
Think "github/gitignore but for CLAUDE.md."
|
|
5
|
+
Think **"github/gitignore but for CLAUDE.md."**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/dotclaudemd)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](package.json)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [What is CLAUDE.md?](#what-is-claudemd)
|
|
16
|
+
- [dotclaudemd vs Claude Code /init](#dotclaudemd-vs-claude-code-init)
|
|
17
|
+
- [Why](#why)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Commands](#commands)
|
|
21
|
+
- [init](#dotclaudemd-init)
|
|
22
|
+
- [lint](#dotclaudemd-lint-file)
|
|
23
|
+
- [doctor](#dotclaudemd-doctor)
|
|
24
|
+
- [browse](#dotclaudemd-browse)
|
|
25
|
+
- [Templates](#templates)
|
|
26
|
+
- [Use Cases](#use-cases)
|
|
27
|
+
- [Contributing](#contributing)
|
|
28
|
+
- [License](#license)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## What is CLAUDE.md?
|
|
33
|
+
|
|
34
|
+
CLAUDE.md is a special markdown file that [Claude Code](https://docs.anthropic.com/en/docs/claude-code) reads at the start of every conversation. It tells Claude how your project works — what commands to run, where code lives, and what conventions to follow.
|
|
35
|
+
|
|
36
|
+
Think of it as a **project brief for your AI pair programmer**. Without it, Claude has to guess your project structure, build system, and coding style every time. With a good CLAUDE.md, Claude already knows:
|
|
37
|
+
|
|
38
|
+
- How to build, test, and run your project
|
|
39
|
+
- Your directory structure and key files
|
|
40
|
+
- Framework-specific conventions (Server Components vs Client Components, Composition API vs Options API, etc.)
|
|
41
|
+
- Which database, ORM, and package manager you use
|
|
42
|
+
|
|
43
|
+
### Where does CLAUDE.md go?
|
|
44
|
+
|
|
45
|
+
| Location | Scope | When Claude reads it |
|
|
46
|
+
|----------|-------|----------------------|
|
|
47
|
+
| `./CLAUDE.md` | Project-level | When working in this project directory |
|
|
48
|
+
| `./.claude/CLAUDE.md` | Project-level (hidden) | Same as above, but keeps your root directory clean |
|
|
49
|
+
| `~/.claude/CLAUDE.md` | Global | Every conversation, in every project |
|
|
50
|
+
|
|
51
|
+
You can use `dotclaudemd init --global` to generate the global one.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## dotclaudemd vs Claude Code `/init`
|
|
56
|
+
|
|
57
|
+
Claude Code has a built-in `/init` command that generates a CLAUDE.md. Here's how it compares to `dotclaudemd init`:
|
|
58
|
+
|
|
59
|
+
| | Claude Code `/init` | `dotclaudemd init` |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| **How it works** | Claude reads your codebase and writes a CLAUDE.md using AI generation | Selects from 19 curated templates based on your detected stack |
|
|
62
|
+
| **Output quality** | Varies by conversation — different each time | Consistent, battle-tested templates with framework-specific best practices |
|
|
63
|
+
| **Customization** | Freeform — you can ask Claude to adjust | Structured variables (styling, database, framework, etc.) with predefined options |
|
|
64
|
+
| **Speed** | Takes 30-60s as Claude analyzes your code | Instant — template selection + variable substitution |
|
|
65
|
+
| **Token cost** | Uses Claude API tokens for generation | Zero tokens — runs locally, no AI calls |
|
|
66
|
+
| **Offline** | Requires internet connection | Works fully offline |
|
|
67
|
+
| **Linting** | None | 8 built-in lint rules catch anti-patterns |
|
|
68
|
+
| **Health checks** | None | `doctor` command verifies CLAUDE.md stays in sync with your project |
|
|
69
|
+
| **Reproducible** | No — regenerating gives different results | Yes — same template + same variables = same output |
|
|
70
|
+
|
|
71
|
+
### When to use which?
|
|
72
|
+
|
|
73
|
+
**Use `dotclaudemd init` when:**
|
|
74
|
+
- You want a proven, consistent starting point for your stack
|
|
75
|
+
- You're setting up CLAUDE.md for the first time on a well-known framework (Next.js, Rails, Spring Boot, etc.)
|
|
76
|
+
- You want to lint and health-check your CLAUDE.md over time
|
|
77
|
+
- You're working offline or want to avoid spending tokens on generation
|
|
78
|
+
- You need reproducible output across team members' projects
|
|
79
|
+
|
|
80
|
+
**Use Claude Code `/init` when:**
|
|
81
|
+
- Your project has a unique or unconventional structure that no template covers
|
|
82
|
+
- You want Claude to analyze your specific codebase and generate a tailored CLAUDE.md
|
|
83
|
+
- You're working on a project that doesn't fit standard categories
|
|
84
|
+
|
|
85
|
+
**Use both together:**
|
|
86
|
+
1. Run `npx dotclaudemd init` to get a solid template-based starting point
|
|
87
|
+
2. Then ask Claude to refine it based on your specific project's nuances
|
|
88
|
+
3. Run `npx dotclaudemd lint` and `npx dotclaudemd doctor` periodically to keep it healthy
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Why
|
|
93
|
+
|
|
94
|
+
There is no standard starting point for writing CLAUDE.md files. Developers write them from scratch, often missing best practices or including anti-patterns that waste context window tokens.
|
|
95
|
+
|
|
96
|
+
`dotclaudemd` solves this with:
|
|
97
|
+
|
|
98
|
+
- **19 curated templates** across 8 language/framework categories
|
|
99
|
+
- **Auto-detection** of your project stack (reads package.json, Cargo.toml, go.mod, pom.xml, Gemfile, composer.json)
|
|
100
|
+
- **Linting** that catches anti-patterns before they cost you tokens
|
|
101
|
+
- **Health checks** that verify your CLAUDE.md stays in sync with your actual project
|
|
102
|
+
|
|
103
|
+
---
|
|
6
104
|
|
|
7
105
|
## Quick Start
|
|
8
106
|
|
|
107
|
+
No installation needed — just run:
|
|
108
|
+
|
|
9
109
|
```bash
|
|
10
110
|
npx dotclaudemd init
|
|
11
111
|
```
|
|
12
112
|
|
|
13
113
|
This auto-detects your project stack and generates a CLAUDE.md from the best matching template.
|
|
14
114
|
|
|
15
|
-
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Installation
|
|
118
|
+
|
|
119
|
+
### Use without installing (recommended)
|
|
16
120
|
|
|
17
|
-
|
|
121
|
+
```bash
|
|
122
|
+
npx dotclaudemd <command>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Install globally
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm install -g dotclaudemd
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Install as a dev dependency
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm install -D dotclaudemd
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Then add to your `package.json` scripts:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"scripts": {
|
|
142
|
+
"claude:lint": "dotclaudemd lint",
|
|
143
|
+
"claude:doctor": "dotclaudemd doctor"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
> **Requires Node.js >= 20**
|
|
149
|
+
|
|
150
|
+
---
|
|
18
151
|
|
|
19
152
|
## Commands
|
|
20
153
|
|
|
21
154
|
### `dotclaudemd init`
|
|
22
155
|
|
|
23
|
-
Scaffold a CLAUDE.md from a template
|
|
156
|
+
Scaffold a CLAUDE.md from a template. Auto-detects your project stack and prompts you for template variables (styling, database, framework options, etc).
|
|
24
157
|
|
|
25
158
|
```bash
|
|
26
|
-
|
|
27
|
-
dotclaudemd init
|
|
28
|
-
|
|
29
|
-
|
|
159
|
+
# Auto-detect stack, interactive prompts
|
|
160
|
+
dotclaudemd init
|
|
161
|
+
|
|
162
|
+
# Use a specific template by name
|
|
163
|
+
dotclaudemd init --stack nextjs-typescript
|
|
164
|
+
|
|
165
|
+
# Write to ~/.claude/CLAUDE.md (global instructions for all projects)
|
|
166
|
+
dotclaudemd init --global
|
|
167
|
+
|
|
168
|
+
# Use all defaults without prompting (great for CI)
|
|
169
|
+
dotclaudemd init --no-interactive
|
|
170
|
+
|
|
171
|
+
# Overwrite an existing CLAUDE.md without confirmation
|
|
172
|
+
dotclaudemd init --force
|
|
173
|
+
|
|
174
|
+
# Combine flags
|
|
175
|
+
dotclaudemd init --stack rails --no-interactive --force
|
|
30
176
|
```
|
|
31
177
|
|
|
178
|
+
**How detection works:** The CLI looks at your project root for manifest files (`package.json`, `Cargo.toml`, `go.mod`, `pom.xml`, `Gemfile`, `composer.json`, `pyproject.toml`) and their contents (dependencies, lock files) to suggest the best matching template.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
32
182
|
### `dotclaudemd lint [file]`
|
|
33
183
|
|
|
34
|
-
Lint a CLAUDE.md for common anti-patterns.
|
|
184
|
+
Lint a CLAUDE.md for common anti-patterns that waste context window tokens or confuse Claude.
|
|
35
185
|
|
|
36
186
|
```bash
|
|
37
|
-
|
|
38
|
-
dotclaudemd lint
|
|
39
|
-
|
|
187
|
+
# Lint CLAUDE.md in current project
|
|
188
|
+
dotclaudemd lint
|
|
189
|
+
|
|
190
|
+
# Lint a specific file
|
|
191
|
+
dotclaudemd lint path/to/CLAUDE.md
|
|
192
|
+
|
|
193
|
+
# Machine-readable JSON output
|
|
194
|
+
dotclaudemd lint --json
|
|
40
195
|
```
|
|
41
196
|
|
|
197
|
+
Returns exit code `1` if errors are found (useful for CI).
|
|
198
|
+
|
|
42
199
|
**Lint Rules:**
|
|
43
200
|
|
|
44
|
-
| Rule | Severity |
|
|
45
|
-
|
|
46
|
-
| `line-count` | warn/error | >80 lines (warn), >150 lines (error) |
|
|
47
|
-
| `has-commands` | warn |
|
|
48
|
-
| `no-personality` | warn | "Be a senior engineer", persona instructions |
|
|
49
|
-
| `no-at-file-refs` | warn | `@docs
|
|
50
|
-
| `no-negative-only` | warn | "Never use X" without "prefer Y instead" |
|
|
51
|
-
| `stale-file-refs` | warn |
|
|
52
|
-
| `no-unicode-bullets` | info | Unicode
|
|
53
|
-
| `no-placeholder-vars` | error | Unreplaced `{{variable}}` placeholders |
|
|
201
|
+
| Rule | Severity | What it catches |
|
|
202
|
+
|------|----------|-----------------|
|
|
203
|
+
| `line-count` | warn / error | >80 lines (warn), >150 lines (error) — large files eat into Claude's context window |
|
|
204
|
+
| `has-commands` | warn | No build, test, or dev commands found — Claude needs these to help you build and test |
|
|
205
|
+
| `no-personality` | warn | "Be a senior engineer", "act as an expert" — persona instructions waste tokens and don't improve output |
|
|
206
|
+
| `no-at-file-refs` | warn | `@docs/api.md` patterns that embed entire files into context |
|
|
207
|
+
| `no-negative-only` | warn | "Never use X" without "prefer Y instead" — Claude works better with positive guidance |
|
|
208
|
+
| `stale-file-refs` | warn | File paths like `src/old-module.ts` that no longer exist in your project |
|
|
209
|
+
| `no-unicode-bullets` | info | Unicode bullet characters instead of markdown `- ` lists |
|
|
210
|
+
| `no-placeholder-vars` | error | Unreplaced `{{variable}}` placeholders from template rendering |
|
|
211
|
+
|
|
212
|
+
**Example output:**
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
Linting CLAUDE.md
|
|
216
|
+
|
|
217
|
+
⚠ line-count: File is 95 lines. Consider trimming to under 80 lines to save context window.
|
|
218
|
+
⚠ no-personality: Line 3: Avoid persona instructions like "act as". They waste tokens.
|
|
219
|
+
⚠ stale-file-refs: Line 12: Referenced path "src/old-module.ts" does not exist.
|
|
220
|
+
|
|
221
|
+
1 file linted: 0 errors, 3 warnings, 0 info
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
54
225
|
|
|
55
226
|
### `dotclaudemd doctor`
|
|
56
227
|
|
|
57
|
-
Check CLAUDE.md freshness against actual project state.
|
|
228
|
+
Check your CLAUDE.md freshness against your actual project state. Catches drift between what your CLAUDE.md says and what your project actually has.
|
|
58
229
|
|
|
59
230
|
```bash
|
|
60
|
-
|
|
61
|
-
dotclaudemd doctor
|
|
231
|
+
# Run all health checks
|
|
232
|
+
dotclaudemd doctor
|
|
233
|
+
|
|
234
|
+
# Machine-readable JSON output (includes freshness score)
|
|
235
|
+
dotclaudemd doctor --json
|
|
62
236
|
```
|
|
63
237
|
|
|
64
238
|
**Health Checks:**
|
|
65
239
|
|
|
66
|
-
| Check |
|
|
67
|
-
|
|
68
|
-
| `scripts-exist` | Commands
|
|
69
|
-
| `deps-mentioned` | Major dependencies are mentioned |
|
|
70
|
-
| `file-refs-valid` | File paths
|
|
71
|
-
| `node-version-match` |
|
|
72
|
-
| `test-framework-match` |
|
|
73
|
-
| `package-manager-match` |
|
|
240
|
+
| Check | What it verifies |
|
|
241
|
+
|-------|------------------|
|
|
242
|
+
| `scripts-exist` | Commands like `npm run build` actually exist in package.json scripts |
|
|
243
|
+
| `deps-mentioned` | Major production dependencies are mentioned somewhere in CLAUDE.md |
|
|
244
|
+
| `file-refs-valid` | File paths like `src/utils/helpers.ts` actually exist on disk |
|
|
245
|
+
| `node-version-match` | The Node version stated in CLAUDE.md matches `.nvmrc` / `.node-version` |
|
|
246
|
+
| `test-framework-match` | The test framework mentioned (jest, vitest, etc.) matches what's in devDependencies |
|
|
247
|
+
| `package-manager-match` | The package manager stated (npm, pnpm, yarn) matches your lockfile |
|
|
248
|
+
|
|
249
|
+
**Freshness Score:** Doctor computes a 0-100% freshness score based on check results:
|
|
250
|
+
- **80-100%** (green) — CLAUDE.md is up to date
|
|
251
|
+
- **50-79%** (yellow) — Some things are stale, consider updating
|
|
252
|
+
- **0-49%** (red) — CLAUDE.md is significantly out of sync
|
|
253
|
+
|
|
254
|
+
---
|
|
74
255
|
|
|
75
256
|
### `dotclaudemd browse`
|
|
76
257
|
|
|
77
|
-
Browse and preview available templates.
|
|
258
|
+
Browse and preview all available templates before choosing one.
|
|
78
259
|
|
|
79
260
|
```bash
|
|
80
|
-
|
|
81
|
-
dotclaudemd browse
|
|
82
|
-
|
|
261
|
+
# Interactive browser — select category, then template, then preview
|
|
262
|
+
dotclaudemd browse
|
|
263
|
+
|
|
264
|
+
# Non-interactive: list all templates
|
|
265
|
+
dotclaudemd browse --list
|
|
266
|
+
|
|
267
|
+
# Filter by language category
|
|
268
|
+
dotclaudemd browse --category python
|
|
269
|
+
dotclaudemd browse --category javascript
|
|
270
|
+
dotclaudemd browse --category java
|
|
83
271
|
```
|
|
84
272
|
|
|
85
|
-
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Templates
|
|
276
|
+
|
|
277
|
+
19 templates across 8 categories. Each template includes project-specific commands, architecture layout, and coding conventions.
|
|
278
|
+
|
|
279
|
+
### JavaScript / TypeScript
|
|
280
|
+
|
|
281
|
+
| Template | Description | Key Variables |
|
|
282
|
+
|----------|-------------|---------------|
|
|
283
|
+
| `nextjs-typescript` | Next.js App Router with TypeScript | `src_dir` (src/app), `styling` (Tailwind/CSS Modules/styled-components) |
|
|
284
|
+
| `nextjs-prisma-tailwind` | Full-stack Next.js with Prisma + Tailwind | `src_dir`, `db` (PostgreSQL/MySQL/SQLite) |
|
|
285
|
+
| `react-vite` | React SPA with Vite | `styling` (Tailwind/CSS Modules/vanilla), `state` (Zustand/Redux/Context) |
|
|
286
|
+
| `express-mongodb` | Express.js REST API with MongoDB | `auth` (JWT/Passport/None) |
|
|
287
|
+
| `mern-stack` | Full-stack MERN application | `styling`, `state` |
|
|
288
|
+
| `node-cli-tool` | Node.js CLI with TypeScript | `cli_framework` (Commander/yargs/Clipanion), `package_manager` |
|
|
289
|
+
| `sveltekit` | SvelteKit with TypeScript | `styling` (Tailwind/vanilla), `adapter` (auto/node/static/vercel) |
|
|
290
|
+
| `astro` | Astro content site | `styling`, `ui_framework` (React/Vue/Svelte/None) |
|
|
291
|
+
| `vue-nuxt` | Vue 3 SPA or Nuxt 3 | `variant` (Nuxt 3/Vue 3 SPA), `styling`, `state_management` (Pinia/None) |
|
|
292
|
+
| `typescript-monorepo` | Turborepo or Nx monorepo | `monorepo_tool` (Turborepo/Nx), `package_manager` (pnpm/npm/yarn) |
|
|
293
|
+
|
|
294
|
+
### Python
|
|
295
|
+
|
|
296
|
+
| Template | Description | Key Variables |
|
|
297
|
+
|----------|-------------|---------------|
|
|
298
|
+
| `fastapi-sqlalchemy` | FastAPI with SQLAlchemy ORM | `db_type` (PostgreSQL/MySQL/SQLite), `package_manager` (pip/poetry/uv) |
|
|
299
|
+
| `django-rest` | Django REST Framework | `db_type`, `package_manager` |
|
|
300
|
+
| `flask-basic` | Flask web application | `db_type`, `package_manager` |
|
|
301
|
+
|
|
302
|
+
### Java
|
|
303
|
+
|
|
304
|
+
| Template | Description | Key Variables |
|
|
305
|
+
|----------|-------------|---------------|
|
|
306
|
+
| `springboot` | Spring Boot REST API | `build_tool` (Maven/Gradle), `db` (PostgreSQL/MySQL/H2), `java_version` (21/17) |
|
|
307
|
+
|
|
308
|
+
### Go
|
|
309
|
+
|
|
310
|
+
| Template | Description | Key Variables |
|
|
311
|
+
|----------|-------------|---------------|
|
|
312
|
+
| `go-api` | Go REST API | `router` (net/http/Chi/Gin/Echo), `db_type` (PostgreSQL/SQLite/None) |
|
|
313
|
+
|
|
314
|
+
### Rust
|
|
315
|
+
|
|
316
|
+
| Template | Description | Key Variables |
|
|
317
|
+
|----------|-------------|---------------|
|
|
318
|
+
| `cargo-workspace` | Rust Cargo workspace | `project_type` (Binary/Library/Both) |
|
|
319
|
+
|
|
320
|
+
### Ruby
|
|
321
|
+
|
|
322
|
+
| Template | Description | Key Variables |
|
|
323
|
+
|----------|-------------|---------------|
|
|
324
|
+
| `rails` | Ruby on Rails | `api_only` (Yes/No), `db` (PostgreSQL/MySQL/SQLite) |
|
|
325
|
+
|
|
326
|
+
### PHP
|
|
327
|
+
|
|
328
|
+
| Template | Description | Key Variables |
|
|
329
|
+
|----------|-------------|---------------|
|
|
330
|
+
| `laravel` | Laravel PHP application | `db` (MySQL/PostgreSQL/SQLite) |
|
|
331
|
+
|
|
332
|
+
### Global
|
|
86
333
|
|
|
87
|
-
| Template | Description |
|
|
88
|
-
|
|
89
|
-
| `default` | Generic template for any project |
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
334
|
+
| Template | Description | Key Variables |
|
|
335
|
+
|----------|-------------|---------------|
|
|
336
|
+
| `default` | Generic template for any project | `project_name`, `language` |
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Use Cases
|
|
341
|
+
|
|
342
|
+
### 1. Starting a new project
|
|
343
|
+
|
|
344
|
+
You just ran `create-next-app` or `rails new` and want to add a CLAUDE.md immediately:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
cd my-new-project
|
|
348
|
+
npx dotclaudemd init
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
The CLI auto-detects your stack, suggests the best template, and prompts you for project-specific options (styling, database, etc).
|
|
352
|
+
|
|
353
|
+
### 2. Adding CLAUDE.md to an existing project
|
|
354
|
+
|
|
355
|
+
Your team has been working on a project for months but never created a CLAUDE.md:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
cd existing-project
|
|
359
|
+
npx dotclaudemd init
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Same flow — it reads your `package.json` (or `pom.xml`, `Gemfile`, etc.) and generates a CLAUDE.md that already knows your dependencies and project structure.
|
|
363
|
+
|
|
364
|
+
### 3. Setting up global Claude instructions
|
|
365
|
+
|
|
366
|
+
Want Claude to follow certain conventions across all your projects:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
npx dotclaudemd init --global
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
This writes to `~/.claude/CLAUDE.md`, which Claude reads for every project you open.
|
|
373
|
+
|
|
374
|
+
### 4. CI/CD: Linting CLAUDE.md in pull requests
|
|
375
|
+
|
|
376
|
+
Add a lint check to your CI pipeline to catch CLAUDE.md anti-patterns before they get merged:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
npx dotclaudemd lint --json
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Returns exit code `1` on errors. Add to your CI config:
|
|
383
|
+
|
|
384
|
+
```yaml
|
|
385
|
+
# GitHub Actions example
|
|
386
|
+
- name: Lint CLAUDE.md
|
|
387
|
+
run: npx dotclaudemd lint
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Or in `package.json`:
|
|
391
|
+
|
|
392
|
+
```json
|
|
393
|
+
{
|
|
394
|
+
"scripts": {
|
|
395
|
+
"lint:claude": "dotclaudemd lint"
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 5. Catching stale CLAUDE.md after refactoring
|
|
401
|
+
|
|
402
|
+
You refactored your project — renamed directories, swapped test frameworks, added new dependencies. Your CLAUDE.md is now out of date:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
npx dotclaudemd doctor
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Doctor checks whether the commands, file paths, and dependencies mentioned in your CLAUDE.md still match your actual project. It reports a freshness score and tells you exactly what's stale.
|
|
409
|
+
|
|
410
|
+
### 6. Browsing templates before choosing
|
|
411
|
+
|
|
412
|
+
Not sure which template fits your project? Browse them interactively:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
npx dotclaudemd browse
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Or list everything non-interactively:
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
npx dotclaudemd browse --list
|
|
422
|
+
npx dotclaudemd browse --category python
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### 7. Scaffolding for a specific stack (non-interactive)
|
|
426
|
+
|
|
427
|
+
You know exactly which template you want and don't need prompts:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
npx dotclaudemd init --stack fastapi-sqlalchemy --no-interactive --force
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
This uses all default variable values and overwrites any existing CLAUDE.md.
|
|
434
|
+
|
|
435
|
+
### 8. Onboarding new team members
|
|
436
|
+
|
|
437
|
+
New developer joins the team? The CLAUDE.md already documents:
|
|
438
|
+
- How to build, test, and run the project
|
|
439
|
+
- Project architecture and key directories
|
|
440
|
+
- Coding conventions and patterns to follow
|
|
441
|
+
|
|
442
|
+
Generate it once, commit it, and every developer (and Claude) benefits.
|
|
443
|
+
|
|
444
|
+
### 9. Monorepo setup
|
|
445
|
+
|
|
446
|
+
For Turborepo or Nx monorepos:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
npx dotclaudemd init --stack typescript-monorepo
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
The template covers workspace commands, package boundaries, and shared config conventions.
|
|
453
|
+
|
|
454
|
+
### 10. Multi-language project
|
|
455
|
+
|
|
456
|
+
Your project root has both `package.json` and `pom.xml`? The detector picks the primary stack (Node.js in this case). You can override:
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
npx dotclaudemd init --stack springboot
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Auto-Detection
|
|
465
|
+
|
|
466
|
+
The CLI detects your project stack by examining files in your project root:
|
|
467
|
+
|
|
468
|
+
| File | Detected Language | Frameworks Detected |
|
|
469
|
+
|------|-------------------|---------------------|
|
|
470
|
+
| `package.json` | JavaScript/TypeScript | Next.js, SvelteKit, Astro, Nuxt, Vue, Express, React, MERN |
|
|
471
|
+
| `turbo.json` / `nx.json` | JavaScript/TypeScript | Turborepo, Nx (monorepo) |
|
|
472
|
+
| `pyproject.toml` / `requirements.txt` | Python | FastAPI, Django, Flask |
|
|
473
|
+
| `Cargo.toml` | Rust | Actix, Axum, Rocket |
|
|
474
|
+
| `go.mod` | Go | Gin, Fiber, Chi, Echo |
|
|
475
|
+
| `pom.xml` / `build.gradle` | Java | Spring Boot |
|
|
476
|
+
| `Gemfile` | Ruby | Rails |
|
|
477
|
+
| `composer.json` | PHP | Laravel |
|
|
478
|
+
|
|
479
|
+
It also detects:
|
|
480
|
+
- **Package managers**: npm, pnpm, yarn, bun, poetry, pipenv, uv, pip, cargo, go, maven, gradle, bundler, composer
|
|
481
|
+
- **Test frameworks**: vitest, jest, mocha, pytest
|
|
482
|
+
- **Lock files**: package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lockb, poetry.lock, Pipfile.lock, uv.lock
|
|
483
|
+
|
|
484
|
+
---
|
|
101
485
|
|
|
102
486
|
## Contributing
|
|
103
487
|
|
|
104
488
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to add templates and contribute.
|
|
105
489
|
|
|
490
|
+
### Adding a Template
|
|
491
|
+
|
|
492
|
+
Templates live in `templates/{category}/{name}.md` with YAML frontmatter:
|
|
493
|
+
|
|
494
|
+
```yaml
|
|
495
|
+
---
|
|
496
|
+
name: my-template
|
|
497
|
+
displayName: My Template
|
|
498
|
+
description: Short description
|
|
499
|
+
category: javascript
|
|
500
|
+
tags: [javascript, typescript, myframework]
|
|
501
|
+
variables:
|
|
502
|
+
- name: styling
|
|
503
|
+
prompt: "Styling solution?"
|
|
504
|
+
options: [Tailwind CSS, vanilla CSS]
|
|
505
|
+
default: Tailwind CSS
|
|
506
|
+
detects:
|
|
507
|
+
files: [package.json]
|
|
508
|
+
dependencies: [my-framework]
|
|
509
|
+
priority: 10
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
# Project
|
|
513
|
+
|
|
514
|
+
My project using {{styling}}.
|
|
515
|
+
|
|
516
|
+
## Commands
|
|
517
|
+
...
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Variables use `{{double_braces}}` for substitution. The `detects` field enables auto-suggestion when the CLI finds matching files or dependencies.
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
106
524
|
## License
|
|
107
525
|
|
|
108
526
|
MIT
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
filterTemplates,
|
|
4
4
|
listTemplates,
|
|
5
5
|
renderTemplate
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-NYAP7NPA.js";
|
|
7
7
|
import "./chunk-3WTPUEHL.js";
|
|
8
8
|
import {
|
|
9
9
|
defaultFsDeps
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SU2BLIFX.js";
|
|
11
11
|
import {
|
|
12
12
|
warn
|
|
13
13
|
} from "./chunk-YHVOBZLV.js";
|
|
@@ -64,7 +64,7 @@ async function browseCommand(options = {}, deps = defaultFsDeps) {
|
|
|
64
64
|
default: true
|
|
65
65
|
});
|
|
66
66
|
if (useIt) {
|
|
67
|
-
const { initCommand } = await import("./init-
|
|
67
|
+
const { initCommand } = await import("./init-5PXXIWA7.js");
|
|
68
68
|
await initCommand({ stack: template.frontmatter.name }, deps);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -93,4 +93,4 @@ function printTemplateList(templates, categoryFilter) {
|
|
|
93
93
|
export {
|
|
94
94
|
browseCommand
|
|
95
95
|
};
|
|
96
|
-
//# sourceMappingURL=browse-
|
|
96
|
+
//# sourceMappingURL=browse-JZNKTNHN.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
defaultFsDeps,
|
|
7
7
|
getTemplatesDir
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SU2BLIFX.js";
|
|
9
9
|
|
|
10
10
|
// src/core/template-engine.ts
|
|
11
11
|
import matter from "gray-matter";
|
|
@@ -142,4 +142,4 @@ export {
|
|
|
142
142
|
filterTemplates,
|
|
143
143
|
suggestTemplates
|
|
144
144
|
};
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
145
|
+
//# sourceMappingURL=chunk-NYAP7NPA.js.map
|
|
@@ -44,6 +44,10 @@ function findProjectRoot(startDir) {
|
|
|
44
44
|
"pyproject.toml",
|
|
45
45
|
"Cargo.toml",
|
|
46
46
|
"go.mod",
|
|
47
|
+
"pom.xml",
|
|
48
|
+
"build.gradle",
|
|
49
|
+
"Gemfile",
|
|
50
|
+
"composer.json",
|
|
47
51
|
".git"
|
|
48
52
|
];
|
|
49
53
|
for (const indicator of indicators) {
|
|
@@ -76,4 +80,4 @@ export {
|
|
|
76
80
|
findProjectRoot,
|
|
77
81
|
findClaudeMd
|
|
78
82
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-SU2BLIFX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/fs.ts","../src/utils/paths.ts"],"sourcesContent":["import { readFile as nodeReadFile, writeFile as nodeWriteFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport type { FsDeps } from \"../types.js\";\n\nexport const defaultFsDeps: FsDeps = {\n async readFile(path: string): Promise<string> {\n return nodeReadFile(path, \"utf-8\");\n },\n\n async writeFile(path: string, content: string): Promise<void> {\n await nodeWriteFile(path, content, \"utf-8\");\n },\n\n async fileExists(path: string): Promise<boolean> {\n return existsSync(path);\n },\n\n async readDir(path: string): Promise<string[]> {\n return readdir(path);\n },\n};\n","import { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { existsSync } from \"node:fs\";\n\nexport function getTemplatesDir(): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n // From dist/cli.mjs or src/utils/paths.ts, go up to package root\n let dir = __dirname;\n for (let i = 0; i < 5; i++) {\n const candidate = join(dir, \"templates\");\n if (existsSync(candidate)) {\n return candidate;\n }\n dir = dirname(dir);\n }\n // Fallback: relative to package root\n return join(dirname(dirname(__dirname)), \"templates\");\n}\n\nexport function findProjectRoot(startDir?: string): string {\n let dir = startDir ? resolve(startDir) : process.cwd();\n while (true) {\n // Check for common project root indicators\n const indicators = [\n \"package.json\",\n \"pyproject.toml\",\n \"Cargo.toml\",\n \"go.mod\",\n \"pom.xml\",\n \"build.gradle\",\n \"Gemfile\",\n \"composer.json\",\n \".git\",\n ];\n for (const indicator of indicators) {\n if (existsSync(join(dir, indicator))) {\n return dir;\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir ? resolve(startDir) : process.cwd();\n}\n\nexport function findClaudeMd(projectRoot: string): string | null {\n // Check common CLAUDE.md locations\n const candidates = [\n join(projectRoot, \"CLAUDE.md\"),\n join(projectRoot, \".claude\", \"CLAUDE.md\"),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n"],"mappings":";;;AAAA,SAAS,YAAY,cAAc,aAAa,qBAAqB;AACrE,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAGjB,IAAM,gBAAwB;AAAA,EACnC,MAAM,SAAS,MAA+B;AAC5C,WAAO,aAAa,MAAM,OAAO;AAAA,EACnC;AAAA,EAEA,MAAM,UAAU,MAAc,SAAgC;AAC5D,UAAM,cAAc,MAAM,SAAS,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,WAAW,MAAgC;AAC/C,WAAO,WAAW,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,QAAQ,MAAiC;AAC7C,WAAO,QAAQ,IAAI;AAAA,EACrB;AACF;;;ACrBA,SAAS,SAAS,MAAM,eAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAS,cAAAA,mBAAkB;AAEpB,SAAS,kBAA0B;AACxC,QAAM,aAAa,cAAc,YAAY,GAAG;AAChD,QAAM,YAAY,QAAQ,UAAU;AAEpC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,YAAY,KAAK,KAAK,WAAW;AACvC,QAAIA,YAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,GAAG;AAAA,EACnB;AAEA,SAAO,KAAK,QAAQ,QAAQ,SAAS,CAAC,GAAG,WAAW;AACtD;AAEO,SAAS,gBAAgB,UAA2B;AACzD,MAAI,MAAM,WAAW,QAAQ,QAAQ,IAAI,QAAQ,IAAI;AACrD,SAAO,MAAM;AAEX,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,eAAW,aAAa,YAAY;AAClC,UAAIA,YAAW,KAAK,KAAK,SAAS,CAAC,GAAG;AACpC,eAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO,WAAW,QAAQ,QAAQ,IAAI,QAAQ,IAAI;AACpD;AAEO,SAAS,aAAa,aAAoC;AAE/D,QAAM,aAAa;AAAA,IACjB,KAAK,aAAa,WAAW;AAAA,IAC7B,KAAK,aAAa,WAAW,WAAW;AAAA,EAC1C;AACA,aAAW,aAAa,YAAY;AAClC,QAAIA,YAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;","names":["existsSync"]}
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ program.name("dotclaudemd").description(
|
|
|
13
13
|
"CLAUDE.md Template Registry CLI \u2014 scaffold, lint, and health-check your CLAUDE.md files"
|
|
14
14
|
).version("0.1.1");
|
|
15
15
|
program.command("init").description("Scaffold a CLAUDE.md from a template").option("--stack <name>", "Use a specific template by name (skip detection)").option("--global", "Write to ~/.claude/CLAUDE.md").option("--no-interactive", "Use defaults without prompting").option("--force", "Overwrite existing CLAUDE.md without prompting").action(async (options) => {
|
|
16
|
-
const { initCommand } = await import("./init-
|
|
16
|
+
const { initCommand } = await import("./init-5PXXIWA7.js");
|
|
17
17
|
await initCommand({
|
|
18
18
|
stack: options.stack,
|
|
19
19
|
global: options.global,
|
|
@@ -22,15 +22,15 @@ program.command("init").description("Scaffold a CLAUDE.md from a template").opti
|
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
program.command("lint [file]").description("Lint a CLAUDE.md for anti-patterns").option("--json", "Output results as JSON").action(async (file, options) => {
|
|
25
|
-
const { lintCommand } = await import("./lint-
|
|
25
|
+
const { lintCommand } = await import("./lint-BMJBNSBA.js");
|
|
26
26
|
await lintCommand(file, { json: options.json });
|
|
27
27
|
});
|
|
28
28
|
program.command("doctor").description("Check CLAUDE.md freshness against project state").option("--json", "Output results as JSON").action(async (options) => {
|
|
29
|
-
const { doctorCommand } = await import("./doctor-
|
|
29
|
+
const { doctorCommand } = await import("./doctor-BHKDRHD4.js");
|
|
30
30
|
await doctorCommand({ json: options.json });
|
|
31
31
|
});
|
|
32
32
|
program.command("browse").description("Browse and preview available templates").option("--category <cat>", "Filter by category").option("--list", "Non-interactive list mode").action(async (options) => {
|
|
33
|
-
const { browseCommand } = await import("./browse-
|
|
33
|
+
const { browseCommand } = await import("./browse-JZNKTNHN.js");
|
|
34
34
|
await browseCommand({ category: options.category, list: options.list });
|
|
35
35
|
});
|
|
36
36
|
program.parseAsync(process.argv).catch((err) => {
|