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 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
+ [![npm version](https://img.shields.io/npm/v/dotclaudemd)](https://www.npmjs.com/package/dotclaudemd)
8
+ [![license](https://img.shields.io/npm/l/dotclaudemd)](LICENSE)
9
+ [![node](https://img.shields.io/node/v/dotclaudemd)](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
- ## Why
115
+ ---
116
+
117
+ ## Installation
118
+
119
+ ### Use without installing (recommended)
16
120
 
17
- There is no standard starting point for writing CLAUDE.md files. Developers write them from scratch, often missing best practices or including anti-patterns. `dotclaudemd` provides a searchable, community-driven registry of templates with a CLI for scaffolding, linting, and health-checking.
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 with auto-detection.
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
- dotclaudemd init # Auto-detect stack, interactive prompts
27
- dotclaudemd init --stack mern-stack # Use a specific template
28
- dotclaudemd init --global # Write to ~/.claude/CLAUDE.md
29
- dotclaudemd init --no-interactive # Use defaults without prompting
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
- dotclaudemd lint # Lint CLAUDE.md in current project
38
- dotclaudemd lint path/to/CLAUDE.md # Lint a specific file
39
- dotclaudemd lint --json # Output as JSON
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 | Trigger |
45
- |------|----------|---------|
46
- | `line-count` | warn/error | >80 lines (warn), >150 lines (error) |
47
- | `has-commands` | warn | Missing build/test/dev commands |
48
- | `no-personality` | warn | "Be a senior engineer", persona instructions |
49
- | `no-at-file-refs` | warn | `@docs/...` patterns that embed entire files |
50
- | `no-negative-only` | warn | "Never use X" without "prefer Y instead" |
51
- | `stale-file-refs` | warn | Referenced paths that don't exist |
52
- | `no-unicode-bullets` | info | Unicode bullets instead of markdown lists |
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
- dotclaudemd doctor # Run health checks
61
- dotclaudemd doctor --json # Output as JSON
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 | Description |
67
- |-------|-------------|
68
- | `scripts-exist` | Commands in CLAUDE.md exist in package.json scripts |
69
- | `deps-mentioned` | Major dependencies are mentioned |
70
- | `file-refs-valid` | File paths mentioned actually exist |
71
- | `node-version-match` | Stated Node version matches .nvmrc |
72
- | `test-framework-match` | Mentioned test framework matches devDeps |
73
- | `package-manager-match` | Stated package manager matches lockfile |
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
- dotclaudemd browse # Interactive template browser
81
- dotclaudemd browse --list # Non-interactive list
82
- dotclaudemd browse --category python # Filter by category
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
- ## Available Templates
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
- | `nextjs-typescript` | Next.js App Router with TypeScript |
91
- | `nextjs-prisma-tailwind` | Full-stack Next.js with Prisma + Tailwind |
92
- | `express-mongodb` | Express.js REST API with MongoDB |
93
- | `mern-stack` | MERN full-stack application |
94
- | `react-vite` | React SPA with Vite |
95
- | `node-cli-tool` | Node.js CLI tool with TypeScript |
96
- | `fastapi-sqlalchemy` | FastAPI with SQLAlchemy ORM |
97
- | `django-rest` | Django REST Framework |
98
- | `flask-basic` | Flask web application |
99
- | `cargo-workspace` | Rust Cargo workspace |
100
- | `go-api` | Go REST API |
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-3ERFQLAD.js";
6
+ } from "./chunk-NYAP7NPA.js";
7
7
  import "./chunk-3WTPUEHL.js";
8
8
  import {
9
9
  defaultFsDeps
10
- } from "./chunk-3R6PUA3E.js";
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-GLWLFVHN.js");
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-7V4CRGTH.js.map
96
+ //# sourceMappingURL=browse-JZNKTNHN.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  defaultFsDeps,
7
7
  getTemplatesDir
8
- } from "./chunk-3R6PUA3E.js";
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-3ERFQLAD.js.map
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-3R6PUA3E.js.map
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-GLWLFVHN.js");
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-W7ZIDPL7.js");
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-4B7J2EH3.js");
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-7V4CRGTH.js");
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) => {