claude-launchpad 0.5.0 → 0.5.2

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
@@ -5,19 +5,16 @@
5
5
  [![GitHub stars](https://img.shields.io/github/stars/mboss37/claude-launchpad?style=flat-square)](https://github.com/mboss37/claude-launchpad)
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/mboss37/claude-launchpad/blob/master/LICENSE)
7
7
 
8
- **Everything you need to launch a project with Claude Code — and keep it healthy.**
8
+ **Score your Claude Code setup. Fix what's broken. Prove it works.**
9
9
 
10
- A launchpad isn't just where you start. It's where you prepare, run checks, and make sure everything is ready before you go. Claude Launchpad does exactly that for your Claude Code setup:
11
-
12
- - **Launch new projects** with production-ready Claude Code config from day one
13
- - **Check existing projects** — score your config, find issues, auto-fix them
14
- - **Prove it works** — run Claude against test scenarios and see if your rules are actually followed
10
+ CLAUDE.md is advisory Claude follows your rules ~80% of the time. Hooks are deterministic 100% compliance. But most developers have zero hooks and too many instructions. This tool gives you a number, fixes the gaps, and lets you prove Claude actually follows your config.
15
11
 
16
12
  ```bash
17
- npm i -g claude-launchpad
18
- cd your-project
13
+ npx claude-launchpad
19
14
  ```
20
15
 
16
+ That's it. Run it in any project with Claude Code. You'll see a score out of 100 and a list of exactly what's wrong. Run `--fix` to auto-repair.
17
+
21
18
  ## Two Paths, One Tool
22
19
 
23
20
  ### Starting a new project?
@@ -26,9 +23,9 @@ cd your-project
26
23
  claude-launchpad init
27
24
  ```
28
25
 
29
- Detects your stack, generates `CLAUDE.md` with your commands, conventions, and memory management instructions, creates `TASKS.md` for sprint tracking and session continuity, sets up hooks for auto-formatting, `.env` protection, and context re-injection after compaction, and adds a `.claudeignore` so Claude doesn't waste time reading `node_modules`.
26
+ Detects your stack, generates `CLAUDE.md` with your commands and conventions, creates `TASKS.md` for tracking work across sessions, sets up hooks that auto-format code and block dangerous operations, and adds a `.claudeignore` so Claude skips `node_modules` and build artifacts.
30
27
 
31
- Then run `enhance` to have Claude read your codebase and fill in the architecture, conventions, and guardrails with real, project-specific content not boilerplate.
28
+ Then run `enhance` to have Claude read your actual codebase and fill in the architecture and guardrails not boilerplate, real project-specific content. Requires Claude Code CLI.
32
29
 
33
30
  ### Already have a project?
34
31
 
@@ -40,35 +37,24 @@ Scans your Claude Code config, gives you a score out of 100, and tells you exact
40
37
 
41
38
  ## All Commands
42
39
 
43
- | Command | What it does |
44
- |---|---|
45
- | `claude-launchpad init` | Launch a new project: detects stack, generates config, security rules, hooks, permissions |
46
- | `claude-launchpad` | Check your config: score it 0-100, list issues |
47
- | `claude-launchpad doctor --fix` | Auto-fix issues: adds hooks, rules, missing sections, .claudeignore |
48
- | `claude-launchpad doctor --watch` | Live score that updates when you save config files |
49
- | `claude-launchpad enhance` | Claude reads your code and completes CLAUDE.md with real content |
50
- | `claude-launchpad eval --suite security` | Run Claude against test scenarios, prove your config works |
40
+ | Command | What it does | Runs |
41
+ |---|---|---|
42
+ | `claude-launchpad init` | Detect stack, generate config, hooks, permissions | Locally |
43
+ | `claude-launchpad` | Score your config 0-100, list issues | Locally |
44
+ | `claude-launchpad doctor --fix` | Auto-fix issues: hooks, rules, sections, .claudeignore | Locally |
45
+ | `claude-launchpad doctor --watch` | Live score that updates when you save config files | Locally |
46
+ | `claude-launchpad enhance` | Claude reads your code and completes CLAUDE.md | Via Claude CLI |
47
+ | `claude-launchpad eval` | Run Claude against test scenarios, prove config works | Via Claude CLI |
51
48
 
52
49
  ## Quick Start
53
50
 
54
51
  ```bash
55
- # Install
56
- npm i -g claude-launchpad
57
-
58
- # Go to any project with Claude Code
59
52
  cd your-project
60
-
61
- # See your score
62
- claude-launchpad
63
-
64
- # Fix everything it found
65
- claude-launchpad doctor --fix
66
-
67
- # See your new score
68
- claude-launchpad
53
+ npx claude-launchpad # see your score
54
+ npx claude-launchpad doctor --fix # fix everything
69
55
  ```
70
56
 
71
- That takes you from ~42% to ~93% with zero manual work.
57
+ A typical unconfigured project scores ~42%. After `--fix`, it jumps to ~86%. Run `init` on a fresh project and you start at ~93%.
72
58
 
73
59
  ## The Doctor
74
60
 
@@ -105,6 +91,7 @@ Output looks like this:
105
91
  | Flag | What it does |
106
92
  |---|---|
107
93
  | `--fix` | Auto-fixes issues: adds hooks, CLAUDE.md sections, rules, .claudeignore |
94
+ | `--fix --dry-run` | Preview what --fix would change without applying |
108
95
  | `--watch` | Re-runs every second, updates when you save a config file |
109
96
  | `--json` | Pure JSON output, no colors, no banner — for scripts and CI |
110
97
  | `--min-score <n>` | Exit code 1 if score is below threshold — use in CI to block bad configs |
@@ -182,7 +169,7 @@ Results are saved to `.claude/eval/` as structured markdown — you can feed the
182
169
  |---|---|---|
183
170
  | `security` | 6 | SQL injection, .env protection, secret exposure, input validation, credential read, sandbox escape |
184
171
  | `conventions` | 5 | Error handling, immutability, file size, naming, no hardcoded values |
185
- | `workflow` | 2 | Git conventions, session continuity |
172
+ | `workflow` | 4 | Git conventions, session continuity, memory persistence, deferred tracking |
186
173
 
187
174
  **All eval flags:**
188
175
 
@@ -217,14 +204,6 @@ jobs:
217
204
 
218
205
  Score below threshold = exit code 1 = PR blocked.
219
206
 
220
- ## Plugin (pending marketplace review)
221
-
222
- ```bash
223
- claude plugin install claude-launchpad
224
- ```
225
-
226
- Then use `/launchpad:doctor`, `/launchpad:init`, `/launchpad:enhance`, `/launchpad:eval` inside Claude Code. The plugin nudges you to re-check your score when you edit config files.
227
-
228
207
  ## How It Works
229
208
 
230
209
  **Doctor** reads your files and runs static analysis. No API calls. No network. No cost.
@@ -237,12 +216,7 @@ Then use `/launchpad:doctor`, `/launchpad:init`, `/launchpad:enhance`, `/launchp
237
216
 
238
217
  ## Why This Exists
239
218
 
240
- - **CLAUDE.md is advisory.** ~80% compliance. Claude might ignore your rules.
241
- - **Hooks are deterministic.** 100% compliance. But most people have zero hooks.
242
- - **Instruction budget is real.** Past ~150, compliance drops. Most people don't know they're over.
243
- - **Nobody measures.** You can't improve what you can't measure.
244
-
245
- This tool gives you a number. Fix the issues, re-run, watch the number go up.
219
+ Nobody measures their Claude Code config quality. You write CLAUDE.md, hope Claude follows it, and never verify. This tool gives you a number. Fix the issues, re-run, watch it go up.
246
220
 
247
221
  ## Glossary
248
222
 
@@ -254,6 +228,7 @@ New to Claude Code? Here's what the terms mean:
254
228
  | **Hooks** | Shell commands that run automatically when Claude does something. For example: auto-format a file after Claude edits it, or block Claude from reading your `.env` file. They live in `.claude/settings.json`. |
255
229
  | **Instruction budget** | CLAUDE.md has a soft limit of ~150 actionable lines. Past that, Claude starts ignoring rules at the bottom. Doctor counts your lines and warns you. |
256
230
  | **Rules** | Extra markdown files in `.claude/rules/` that Claude reads alongside CLAUDE.md. Use them to offload detailed conventions so CLAUDE.md stays under budget. |
231
+ | **Compaction** | When a Claude Code conversation gets too long, it compresses older messages to free up space. This can lose context — a PostCompact hook re-injects critical files (like TASKS.md) after compaction. |
257
232
  | **MCP Servers** | External tools Claude can connect to (databases, APIs, docs). Configured in `.claude/settings.json`. Most projects don't need them. |
258
233
  | **.claudeignore** | Like `.gitignore` but for Claude. Tells Claude which files to skip (node_modules, dist, lockfiles) so it doesn't waste time reading noise. |
259
234
 
package/dist/cli.js CHANGED
@@ -404,6 +404,13 @@ function generateSettings(detected) {
404
404
  if (formatHook) {
405
405
  postToolUse.push(formatHook);
406
406
  }
407
+ const sessionStart = [{
408
+ matcher: "startup|resume",
409
+ hooks: [{
410
+ type: "command",
411
+ command: "cat TASKS.md 2>/dev/null; exit 0"
412
+ }]
413
+ }];
407
414
  const postCompact = [{
408
415
  matcher: "",
409
416
  hooks: [{
@@ -412,6 +419,7 @@ function generateSettings(detected) {
412
419
  }]
413
420
  }];
414
421
  const hooks = {};
422
+ hooks.SessionStart = sessionStart;
415
423
  if (preToolUse.length > 0) hooks.PreToolUse = preToolUse;
416
424
  if (postToolUse.length > 0) hooks.PostToolUse = postToolUse;
417
425
  hooks.PostCompact = postCompact;
@@ -810,7 +818,8 @@ async function readHooks(claudeDir) {
810
818
  event,
811
819
  type: h.type ?? "command",
812
820
  matcher,
813
- command: h.command
821
+ command: h.command,
822
+ timeout: h.timeout
814
823
  });
815
824
  }
816
825
  } else {
@@ -818,7 +827,8 @@ async function readHooks(claudeDir) {
818
827
  event,
819
828
  type: g.type ?? "command",
820
829
  matcher,
821
- command: g.command
830
+ command: g.command,
831
+ timeout: g.timeout
822
832
  });
823
833
  }
824
834
  }
@@ -981,6 +991,44 @@ async function analyzeSettings(config) {
981
991
  fix: "Add PreToolUse hooks for security or remove allowedTools to use interactive prompting"
982
992
  });
983
993
  }
994
+ if (config.settings.includeCoAuthoredBy !== void 0) {
995
+ issues.push({
996
+ analyzer: "Settings",
997
+ severity: "low",
998
+ message: 'Deprecated includeCoAuthoredBy \u2014 use attribution: { commit: "", pr: "" } instead',
999
+ fix: "Replace includeCoAuthoredBy with the attribution object in settings.json"
1000
+ });
1001
+ }
1002
+ if (!config.settings.claudeMdExcludes) {
1003
+ issues.push({
1004
+ analyzer: "Settings",
1005
+ severity: "info",
1006
+ message: "No claudeMdExcludes configured \u2014 consider adding this if you have a monorepo"
1007
+ });
1008
+ }
1009
+ const broadMatchers = ["Bash", "Write", "Edit", "Read"];
1010
+ const hooksWithoutTimeout = config.hooks.filter(
1011
+ (h) => !h.timeout && broadMatchers.some((m) => h.matcher?.includes(m))
1012
+ );
1013
+ if (hooksWithoutTimeout.length > 0) {
1014
+ issues.push({
1015
+ analyzer: "Settings",
1016
+ severity: "low",
1017
+ message: `${hooksWithoutTimeout.length} hook(s) on broad matchers without timeout \u2014 defaults to 60s per invocation`,
1018
+ fix: "Add timeout (in seconds) to hooks on Bash, Write, Edit, or Read matchers"
1019
+ });
1020
+ }
1021
+ if (config.settings.autoMemoryEnabled === false) {
1022
+ const hasMemorySection = config.claudeMdContent?.includes("## Memory") ?? false;
1023
+ if (!hasMemorySection) {
1024
+ issues.push({
1025
+ analyzer: "Settings",
1026
+ severity: "medium",
1027
+ message: "Auto-memory is disabled with no manual memory strategy in CLAUDE.md",
1028
+ fix: "Re-enable autoMemoryEnabled or add a ## Memory section to CLAUDE.md"
1029
+ });
1030
+ }
1031
+ }
984
1032
  const actionableCount = issues.filter((i) => i.severity !== "info").length;
985
1033
  const score = Math.max(0, 100 - actionableCount * 20);
986
1034
  return { name: "Settings", issues, score };
@@ -1040,7 +1088,16 @@ async function analyzeHooks(config) {
1040
1088
  fix: "Add a PostCompact hook that re-injects TASKS.md after compaction"
1041
1089
  });
1042
1090
  }
1043
- const score = Math.max(0, 100 - issues.length * 20);
1091
+ const hasSessionStart = hooks.some((h) => h.event === "SessionStart");
1092
+ if (!hasSessionStart) {
1093
+ issues.push({
1094
+ analyzer: "Hooks",
1095
+ severity: "low",
1096
+ message: "No SessionStart hook \u2014 session starts without project context loaded",
1097
+ fix: "Add a SessionStart hook that injects TASKS.md at startup"
1098
+ });
1099
+ }
1100
+ const score = Math.max(0, 100 - issues.length * 15);
1044
1101
  return { name: "Hooks", issues, score };
1045
1102
  }
1046
1103
 
@@ -1373,7 +1430,8 @@ var FIX_TABLE = [
1373
1430
  { analyzer: "Permissions", match: "Credential files not blocked", fix: (root) => addCredentialDenyRules(root) },
1374
1431
  { analyzer: "Permissions", match: "Bypass permissions mode", fix: (root) => addBypassDisable(root) },
1375
1432
  { analyzer: "Permissions", match: "Sandbox not enabled", fix: (root) => addSandboxSettings(root) },
1376
- { analyzer: "Permissions", match: ".env is protected by hooks but not in .claudeignore", fix: (root) => addEnvToClaudeignore(root) }
1433
+ { analyzer: "Permissions", match: ".env is protected by hooks but not in .claudeignore", fix: (root) => addEnvToClaudeignore(root) },
1434
+ { analyzer: "Settings", match: "Deprecated includeCoAuthoredBy", fix: (root) => migrateAttribution(root) }
1377
1435
  ];
1378
1436
  async function tryFix(issue, root, detected) {
1379
1437
  const entry = FIX_TABLE.find(
@@ -1475,6 +1533,15 @@ async function addPostCompactHook(root) {
1475
1533
  log.success("Added PostCompact hook (re-injects TASKS.md after compaction)");
1476
1534
  return true;
1477
1535
  }
1536
+ async function migrateAttribution(root) {
1537
+ const settings = await readSettingsJson(root);
1538
+ if (settings.includeCoAuthoredBy === void 0) return false;
1539
+ const { includeCoAuthoredBy: _, ...rest } = settings;
1540
+ const updated = { ...rest, attribution: { commit: "", pr: "" } };
1541
+ await writeSettingsJson(root, updated);
1542
+ log.success("Migrated includeCoAuthoredBy \u2192 attribution object");
1543
+ return true;
1544
+ }
1478
1545
  async function addCredentialDenyRules(root) {
1479
1546
  const settings = await readSettingsJson(root);
1480
1547
  const permissions = settings.permissions ?? {};
@@ -1660,7 +1727,7 @@ async function runAndDisplay(projectRoot) {
1660
1727
 
1661
1728
  // src/commands/doctor/index.ts
1662
1729
  function createDoctorCommand() {
1663
- return new Command2("doctor").description("Diagnose your Claude Code configuration and report issues").option("-p, --path <path>", "Project root path", process.cwd()).option("--json", "Output as JSON").option("--min-score <n>", "Exit non-zero if overall score is below this threshold (for CI)").option("--fix", "Auto-apply deterministic fixes for detected issues").option("--watch", "Watch for config changes and re-run automatically").action(async (opts) => {
1730
+ return new Command2("doctor").description("Diagnose your Claude Code configuration and report issues").option("-p, --path <path>", "Project root path", process.cwd()).option("--json", "Output as JSON").option("--min-score <n>", "Exit non-zero if overall score is below this threshold (for CI)").option("--fix", "Auto-apply deterministic fixes for detected issues").option("--dry-run", "Preview what --fix would change without applying").option("--watch", "Watch for config changes and re-run automatically").action(async (opts) => {
1664
1731
  if (opts.watch) {
1665
1732
  await watchConfig(opts.path);
1666
1733
  return;
@@ -1697,13 +1764,36 @@ function createDoctorCommand() {
1697
1764
  const allIssues = results.flatMap((r) => r.issues);
1698
1765
  const fixable = allIssues.filter((i) => i.severity !== "info");
1699
1766
  if (fixable.length > 0) {
1767
+ if (opts.dryRun) {
1768
+ log.blank();
1769
+ log.step("Dry run \u2014 would apply these fixes:");
1770
+ log.blank();
1771
+ for (const issue of fixable) {
1772
+ log.info(` Would fix: ${issue.message}`);
1773
+ }
1774
+ log.blank();
1775
+ log.success(`${fixable.length} fix(es) available. Run --fix without --dry-run to apply.`);
1776
+ return;
1777
+ }
1700
1778
  log.blank();
1701
1779
  log.step("Applying fixes...");
1702
1780
  log.blank();
1703
1781
  const { fixed, skipped } = await applyFixes(fixable, opts.path);
1704
1782
  log.blank();
1705
1783
  if (fixed > 0) {
1706
- log.success(`Applied ${fixed} fix(es). Run \`claude-launchpad doctor\` again to see your new score.`);
1784
+ log.success(`Applied ${fixed} fix(es). Re-scanning...`);
1785
+ log.blank();
1786
+ const updatedConfig = await parseClaudeConfig(opts.path);
1787
+ const updatedResults = await Promise.all([
1788
+ analyzeBudget(updatedConfig),
1789
+ analyzeQuality(updatedConfig),
1790
+ analyzeSettings(updatedConfig),
1791
+ analyzeHooks(updatedConfig),
1792
+ analyzeRules(updatedConfig),
1793
+ analyzePermissions(updatedConfig),
1794
+ analyzeMcp(updatedConfig)
1795
+ ]);
1796
+ renderDoctorReport(updatedResults);
1707
1797
  }
1708
1798
  if (skipped > 0) {
1709
1799
  log.info(`${skipped} issue(s) require manual intervention.`);
@@ -2346,9 +2436,15 @@ Also review .claude/settings.json hooks:
2346
2436
  - Read the existing hooks in .claude/settings.json
2347
2437
  - If you see project-specific patterns that deserve hooks (e.g., protected directories, test file patterns, migration files), suggest adding them
2348
2438
  - If no PostCompact hook exists, suggest adding one that re-injects TASKS.md after context compaction (critical for session continuity)
2439
+ - If no SessionStart hook exists, suggest adding one that injects TASKS.md at session startup
2349
2440
  - DO NOT overwrite existing hooks \u2014 only add new ones that are specific to this project
2350
2441
  - Print hook suggestions at the end with the exact JSON to add, don't modify settings.json directly
2351
2442
 
2443
+ Also check for advanced configuration opportunities:
2444
+ - If the project has both app code and tests, suggest creating path-scoped .claude/rules/ files with paths: frontmatter (e.g., test conventions only load when editing test files)
2445
+ - If the project uses external APIs (Stripe, GitHub, AWS SDKs, etc.), suggest sandbox.network.allowedDomains to restrict outbound traffic
2446
+ - If you detect a monorepo (Turborepo, Lerna, pnpm workspaces, multiple package.json), suggest claudeMdExcludes in settings.json
2447
+
2352
2448
  Rules:
2353
2449
  - Don't remove existing content \u2014 only add or improve
2354
2450
  - Be specific to THIS project, not generic advice