claude-launchpad 0.14.0 → 0.14.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.
package/README.md CHANGED
@@ -201,7 +201,7 @@ claude-launchpad memory
201
201
 
202
202
  If memory is not installed, it runs interactive setup. If installed, it shows stats. Requires native deps first: `npm install better-sqlite3 sqlite-vec`.
203
203
 
204
- Every session, Claude loads what it needs to know and extracts new knowledge when you finish. Stale facts fade on their own. Knowledge Claude actually uses gets reinforced. Each project has its own isolated memory, and you can sync it across machines via private GitHub Gist.
204
+ Every session, Claude loads what it needs to know and stores new knowledge as it works. Stale facts fade on their own. Knowledge Claude actually uses gets reinforced. Each project has its own isolated memory, and you can sync it across machines via private GitHub Gist.
205
205
 
206
206
  Browse everything with `--dashboard` -- a terminal UI with vim navigation, filtering, and search.
207
207
 
package/dist/cli.js CHANGED
@@ -602,7 +602,7 @@ function generateEnhanceSkill() {
602
602
  "1. Run `claude-launchpad doctor` to check the score improved",
603
603
  "2. Print suggested hooks (exact JSON) for .claude/settings.json but don't modify it",
604
604
  "3. Print suggested MCP servers if external services detected (Postgres, Redis, Stripe, etc.)",
605
- '4. If eval scenarios were generated, print: "Run this in your terminal (not inside Claude Code): `claude-launchpad eval --scenarios scenarios/`"',
605
+ '4. If eval scenarios were generated, print: "Run this in your terminal (not inside Claude Code): `claude-launchpad eval --scenarios scenarios/ --runs 1`"',
606
606
  "",
607
607
  "**Done when:** doctor score is equal or higher, suggestions printed, eval scenarios created if applicable.",
608
608
  "",
@@ -1541,7 +1541,7 @@ var MEMORY_MCP_TOOLS = [
1541
1541
  function hasMemoryIndicators(config) {
1542
1542
  const hasMcpServer = config.mcpServers.some((s) => s.name === "agentic-memory");
1543
1543
  const hasHookRef = config.hooks.some(
1544
- (h) => h.command?.includes("memory context") || h.command?.includes("memory extract")
1544
+ (h) => h.command?.includes("memory context")
1545
1545
  );
1546
1546
  return hasMcpServer || hasHookRef;
1547
1547
  }
@@ -1559,15 +1559,15 @@ async function analyzeMemory(config) {
1559
1559
  fix: "Add a SessionStart hook that runs `memory context` to inject relevant memories"
1560
1560
  });
1561
1561
  }
1562
- const hasStopHook = config.hooks.some(
1562
+ const hasStaleStopHook = config.hooks.some(
1563
1563
  (h) => h.event === "Stop" && h.command?.includes("memory extract")
1564
1564
  );
1565
- if (!hasStopHook) {
1565
+ if (hasStaleStopHook) {
1566
1566
  issues.push({
1567
1567
  analyzer: "Memory",
1568
- severity: "medium",
1569
- message: "No Stop hook with memory extract for session learnings",
1570
- fix: "Add a Stop hook that runs `memory extract` to capture session insights"
1568
+ severity: "low",
1569
+ message: "Deprecated Stop hook found (memory extract) \u2014 auto-extraction was removed, Claude stores memories directly via MCP tools",
1570
+ fix: "Run `doctor --fix` to remove the stale Stop hook"
1571
1571
  });
1572
1572
  }
1573
1573
  const autoMemoryDisabled = config.settings?.autoMemoryEnabled === false;
@@ -1744,9 +1744,10 @@ var FIX_TABLE = [
1744
1744
  { analyzer: "Rules", match: "lp-enhance skill is outdated", fix: (root) => updateEnhanceSkill(root) },
1745
1745
  { analyzer: "Settings", match: "Deprecated includeCoAuthoredBy", fix: (root) => migrateAttribution(root) },
1746
1746
  { analyzer: "Hooks", match: "SessionStart", fix: (root) => addSessionStartHook(root) },
1747
+ { analyzer: "Memory", match: "Deprecated Stop hook", fix: (root) => removeStaleStopHook(root) },
1747
1748
  { analyzer: "Memory", match: "autoMemoryEnabled not disabled", fix: (root) => disableAutoMemory(root) },
1748
1749
  { analyzer: "Memory", match: "MCP tool permission", fix: (root) => addMemoryToolPermissions(root) },
1749
- { analyzer: "Memory", match: "CLAUDE.md missing memory guidance", fix: (root) => addClaudeMdSection(root, "## Memory", "Use agentic-memory to persist knowledge across sessions:\n- Memories are automatically injected at session start and extracted at session end\n- Save non-obvious decisions, gotchas, and deferred issues\n- NEVER store credentials, API keys, tokens, or secrets in memories\n- Check memory for relevant context before starting work") }
1750
+ { analyzer: "Memory", match: "CLAUDE.md missing memory guidance", fix: (root) => addClaudeMdSection(root, "## Memory", "Use agentic-memory to persist knowledge across sessions:\n- Memories are automatically injected at session start\n- STORE IMMEDIATELY when: a dependency strategy changes, an architecture decision is made, a convention is established, a bug pattern is discovered, or a feature is killed/added\n- Use memory_search before memory_store to check for duplicates\n- NEVER store credentials, API keys, tokens, or secrets in memories") }
1750
1751
  ];
1751
1752
  async function tryFix(issue, root, detected) {
1752
1753
  const entry = FIX_TABLE.find(
@@ -1998,6 +1999,27 @@ async function updateEnhanceSkill(root) {
1998
1999
  log.success("Updated /lp-enhance skill to latest version");
1999
2000
  return true;
2000
2001
  }
2002
+ async function removeStaleStopHook(root) {
2003
+ const settings = await readSettingsJson(root);
2004
+ const hooks = settings.hooks;
2005
+ if (!hooks?.Stop) return false;
2006
+ const stopHooks = hooks.Stop;
2007
+ const filtered = stopHooks.filter((h) => {
2008
+ const innerHooks = h.hooks;
2009
+ return !innerHooks?.some(
2010
+ (ih) => typeof ih.command === "string" && ih.command.includes("memory extract")
2011
+ );
2012
+ });
2013
+ if (filtered.length === stopHooks.length) return false;
2014
+ if (filtered.length === 0) {
2015
+ delete hooks.Stop;
2016
+ } else {
2017
+ hooks.Stop = filtered;
2018
+ }
2019
+ await writeSettingsJson(root, settings);
2020
+ log.success("Removed deprecated Stop hook (memory extract)");
2021
+ return true;
2022
+ }
2001
2023
 
2002
2024
  // src/commands/doctor/watcher.ts
2003
2025
  import { readdir as readdir2, stat } from "fs/promises";
@@ -2805,7 +2827,7 @@ function createMemoryCommand() {
2805
2827
  log.info("Skipped.");
2806
2828
  return;
2807
2829
  }
2808
- const { runInstall } = await import("./install-H6GW4P6K.js");
2830
+ const { runInstall } = await import("./install-4GQ57KCQ.js");
2809
2831
  await runInstall({});
2810
2832
  } else {
2811
2833
  const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
@@ -2821,13 +2843,6 @@ function createMemoryCommand() {
2821
2843
  }).helpCommand(false),
2822
2844
  { hidden: true }
2823
2845
  );
2824
- memory.addCommand(
2825
- new Command4("extract").description("Extract facts from transcript (hook handler)").action(async () => {
2826
- const { runExtract } = await import("./extract-HMAN7RW4.js");
2827
- await runExtract();
2828
- }).helpCommand(false),
2829
- { hidden: true }
2830
- );
2831
2846
  memory.addCommand(
2832
2847
  new Command4("serve").description("Start MCP server (Claude Code)").action(async () => {
2833
2848
  const { startServer } = await import("./commands/memory/server.js");
@@ -2851,7 +2866,7 @@ function createMemoryCommand() {
2851
2866
  }
2852
2867
 
2853
2868
  // src/cli.ts
2854
- var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.14.0", "-v, --version").action(async () => {
2869
+ var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.14.1", "-v, --version").action(async () => {
2855
2870
  const hasConfig = await fileExists(join11(process.cwd(), "CLAUDE.md")) || await fileExists(join11(process.cwd(), ".claude", "settings.json"));
2856
2871
  if (hasConfig) {
2857
2872
  await program.commands.find((c) => c.name() === "doctor")?.parseAsync([], { from: "user" });