claude-launchpad 0.9.2-dev.2 → 0.10.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.
|
@@ -42,7 +42,7 @@ async function runInstall(opts) {
|
|
|
42
42
|
log.success("MCP server registered via `claude mcp add`");
|
|
43
43
|
} else {
|
|
44
44
|
log.warn("Could not register MCP server automatically.");
|
|
45
|
-
log.info("Run: claude mcp add agentic-memory
|
|
45
|
+
log.info("Run: claude mcp add --scope user agentic-memory npx claude-launchpad memory serve");
|
|
46
46
|
}
|
|
47
47
|
log.step("[4/4] Injecting guidance...");
|
|
48
48
|
const guidanceAdded = injectClaudeMdGuidance(process.cwd());
|
|
@@ -153,6 +153,11 @@ async function ensureNativeDeps() {
|
|
|
153
153
|
}
|
|
154
154
|
function registerMcpServer() {
|
|
155
155
|
try {
|
|
156
|
+
const existing = execSync("claude mcp list", { stdio: "pipe", timeout: 1e4, encoding: "utf-8" });
|
|
157
|
+
if (existing.includes("agentic-memory")) {
|
|
158
|
+
log.info("MCP server already registered globally");
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
156
161
|
execSync(
|
|
157
162
|
"claude mcp add --scope user agentic-memory npx claude-launchpad memory serve",
|
|
158
163
|
{ stdio: "pipe", timeout: 1e4 }
|
|
@@ -250,4 +255,4 @@ function installSkills(projectDir) {
|
|
|
250
255
|
export {
|
|
251
256
|
runInstall
|
|
252
257
|
};
|
|
253
|
-
//# sourceMappingURL=install-
|
|
258
|
+
//# sourceMappingURL=install-PSSMUGLO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/subcommands/install.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { createDatabase, closeDatabase } from '../storage/database.js';\nimport { migrate } from '../storage/migrator.js';\nimport { loadConfig, resolveDataDir } from '../config.js';\nimport { readSettingsJson, writeSettingsJson } from '../../../lib/settings.js';\nimport { log } from '../../../lib/output.js';\n\ninterface InstallOpts {\n readonly dbPath?: string;\n}\n\nexport async function runInstall(opts: InstallOpts): Promise<void> {\n log.blank();\n log.step('Memory system - install');\n log.blank();\n\n // Step 0: Ensure native deps are installed globally\n await ensureNativeDeps();\n\n const config = loadConfig(opts.dbPath ? { dataDir: opts.dbPath } : undefined);\n const dataDir = resolveDataDir(config.dataDir);\n\n // Step 1: Database\n log.step('[1/4] Setting up database...');\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const db = createDatabase({ dataDir });\n migrate(db);\n closeDatabase(db);\n log.success(`${dataDir}/memory.db ready`);\n\n // Step 2: Configure Claude Code settings\n log.step('[2/4] Configuring Claude Code...');\n await configureSettings(process.cwd());\n\n // Step 3: Register MCP server\n log.step('[3/4] Registering MCP server...');\n const registered = registerMcpServer();\n if (registered) {\n log.success('MCP server registered via `claude mcp add`');\n } else {\n log.warn('Could not register MCP server automatically.');\n log.info('Run: claude mcp add --scope user agentic-memory npx claude-launchpad memory serve');\n }\n\n // Step 4: CLAUDE.md + skills\n log.step('[4/4] Injecting guidance...');\n const guidanceAdded = injectClaudeMdGuidance(process.cwd());\n if (guidanceAdded) {\n log.success('Memory guidance added to CLAUDE.md');\n }\n const skillsInstalled = installSkills(process.cwd());\n if (skillsInstalled > 0) {\n log.success(`Installed ${skillsInstalled} skill(s) to .claude/skills/`);\n }\n\n log.blank();\n log.success('Memory system installed.');\n log.info('Restart your Claude Code session for the MCP server to connect.');\n log.blank();\n}\n\nasync function configureSettings(projectDir: string): Promise<void> {\n const settings = await readSettingsJson(projectDir);\n\n // Disable built-in auto-memory\n settings['autoMemoryEnabled'] = false;\n log.info('Built-in auto-memory disabled');\n\n // SessionStart hook\n const hooks = (settings['hooks'] ?? {}) as Record<string, unknown[]>;\n addSessionStartHook(hooks);\n addStopHook(hooks);\n settings['hooks'] = hooks;\n\n // Auto-allow MCP tools\n addToolPermissions(settings);\n\n await writeSettingsJson(projectDir, settings);\n log.success('settings.json updated');\n}\n\nfunction addSessionStartHook(hooks: Record<string, unknown[]>): void {\n const sessionStartHooks = (hooks['SessionStart'] ?? []) as Record<string, unknown>[];\n const hookCommand = 'npx claude-launchpad memory context --json 2>/dev/null; exit 0';\n\n const alreadyHooked = sessionStartHooks.some((h) => {\n const innerHooks = h['hooks'] as Record<string, unknown>[] | undefined;\n return innerHooks?.some(\n ih => typeof ih['command'] === 'string' && (ih['command'] as string).includes('claude-launchpad memory context'),\n );\n });\n\n if (!alreadyHooked) {\n sessionStartHooks.push({\n matcher: 'startup|resume',\n hooks: [{ type: 'command', command: hookCommand }],\n });\n hooks['SessionStart'] = sessionStartHooks;\n log.info('SessionStart hook added (injects memory context)');\n }\n}\n\nfunction addStopHook(hooks: Record<string, unknown[]>): void {\n const stopHooks = (hooks['Stop'] ?? []) as Record<string, unknown>[];\n const extractCommand = 'npx claude-launchpad memory extract 2>/dev/null; exit 0';\n\n const alreadyHasExtract = stopHooks.some((h) => {\n const innerHooks = h['hooks'] as Record<string, unknown>[] | undefined;\n return innerHooks?.some(\n ih => typeof ih['command'] === 'string' && (ih['command'] as string).includes('claude-launchpad memory extract'),\n );\n });\n\n if (!alreadyHasExtract) {\n stopHooks.push({\n hooks: [{ type: 'command', command: extractCommand, async: true }],\n });\n hooks['Stop'] = stopHooks;\n log.info('Stop hook added (extracts facts from transcript)');\n }\n}\n\nfunction addToolPermissions(settings: Record<string, unknown>): void {\n const permissions = (settings['permissions'] ?? {}) as Record<string, unknown>;\n const allowList = (permissions['allow'] ?? []) as string[];\n\n const memoryTools = [\n 'mcp__agentic-memory__memory_store',\n 'mcp__agentic-memory__memory_search',\n 'mcp__agentic-memory__memory_recent',\n 'mcp__agentic-memory__memory_forget',\n 'mcp__agentic-memory__memory_relate',\n 'mcp__agentic-memory__memory_stats',\n 'mcp__agentic-memory__memory_update',\n ];\n\n let added = 0;\n for (const tool of memoryTools) {\n if (!allowList.includes(tool)) {\n allowList.push(tool);\n added++;\n }\n }\n\n if (added > 0) {\n permissions['allow'] = allowList;\n settings['permissions'] = permissions;\n log.info(`Auto-allowed ${added} MCP tools`);\n }\n}\n\nasync function ensureNativeDeps(): Promise<void> {\n const { cwdRequire } = await import('../utils/require-deps.js');\n try {\n cwdRequire('better-sqlite3');\n return;\n } catch {\n // Not installed — install globally\n }\n\n log.step('Installing native dependencies (better-sqlite3, sqlite-vec)...');\n try {\n execSync('npm install -g better-sqlite3 sqlite-vec', { stdio: 'pipe', timeout: 120000 });\n log.success('Native dependencies installed globally');\n } catch {\n log.error('Failed to install native dependencies automatically.');\n log.blank();\n log.info('Install manually:');\n log.step(' npm install -g better-sqlite3 sqlite-vec');\n log.blank();\n log.info('This requires a C++ compiler (Xcode on macOS, build-essential on Linux).');\n process.exit(1);\n }\n}\n\nfunction registerMcpServer(): boolean {\n try {\n const existing = execSync('claude mcp list', { stdio: 'pipe', timeout: 10000, encoding: 'utf-8' });\n if (existing.includes('agentic-memory')) {\n log.info('MCP server already registered globally');\n return true;\n }\n execSync(\n 'claude mcp add --scope user agentic-memory npx claude-launchpad memory serve',\n { stdio: 'pipe', timeout: 10000 },\n );\n return true;\n } catch {\n return false;\n }\n}\n\nconst MEMORY_GUIDANCE = `\n## Memory (agentic-memory)\nThis project uses **agentic-memory** for persistent memory across sessions.\n- **DO NOT** use the built-in auto-memory system (~/.claude/projects/*/memory/)\n- Memory context is **automatically injected** at session start via SessionStart hook - no need to call memory_recent manually\n- Use \\`memory_search\\` to find specific memories by keyword\n- Use \\`memory_store\\` to save decisions, gotchas, and learnings worth remembering\n- Use \\`memory_stats\\` to check memory health\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. Don't wait for session end - the Stop hook only catches obvious patterns.\n`;\n\nfunction injectClaudeMdGuidance(projectDir: string): boolean {\n const claudeMdPath = join(projectDir, 'CLAUDE.md');\n\n let content = '';\n try {\n content = readFileSync(claudeMdPath, 'utf-8');\n } catch {\n return false;\n }\n\n if (content.includes('## Memory (agentic-memory)')) {\n return false;\n }\n\n const updated = content.trimEnd() + '\\n' + MEMORY_GUIDANCE;\n writeFileSync(claudeMdPath, updated, 'utf-8');\n return true;\n}\n\nconst MIGRATE_MEMORY_SKILL = `---\nname: lp-migrate-memory\ndescription: Migrate legacy Claude Code auto-memory files (~/.claude/projects/*/memory/*.md) into agentic-memory. Use when setting up agentic-memory on a project that already has built-in memories.\nallowed-tools: Read, Glob, Grep, mcp__agentic-memory__memory_store, mcp__agentic-memory__memory_search\n---\n\n# Migrate Legacy Claude Code Memories\n\nMigrate memory files from Claude Code's built-in auto-memory system into agentic-memory.\n\n## Steps\n\n1. **Find legacy memory files** for this project:\n - Scan \\`~/.claude/projects/*/memory/*.md\\` for directories whose slug matches the current project path\n - The slug format is the absolute path with \\`/\\` replaced by \\`-\\` and leading \\`-\\` (e.g. \\`-Users-john-projects-myapp\\`)\n - Also check \\`~/.claude/projects/*/memory/team/*.md\\` for team memories\n\n2. **For each memory file found**, read it and parse:\n - YAML frontmatter: \\`name\\`, \\`description\\`, \\`type\\` (user/feedback/project/reference)\n - Body content (everything after the frontmatter closing \\`---\\`)\n - Skip \\`MEMORY.md\\` (it's just an index file, not a memory)\n\n3. **Before storing**, check for duplicates:\n - Call \\`memory_search\\` with the memory description or first 100 chars of content\n - If a close match exists (same topic), skip it and report\n\n4. **Map types and store** each memory via \\`memory_store\\`:\n - \\`user\\` -> type: \\`semantic\\`, tags: [\\`user\\`, \\`migrated\\`], importance: 0.7\n - \\`feedback\\` -> type: \\`semantic\\`, tags: [\\`feedback\\`, \\`migrated\\`], importance: 0.8\n - \\`project\\` -> type: \\`semantic\\`, tags: [\\`project\\`, \\`migrated\\`], importance: 0.6\n - \\`reference\\` -> type: \\`semantic\\`, tags: [\\`reference\\`, \\`migrated\\`], importance: 0.5\n - Use the frontmatter \\`name\\` as the title\n - Use the body content as the memory content\n - Set source: \\`import\\`\n - Adjust importance up/down based on the content (decisions and gotchas deserve higher importance)\n\n5. **Report results**: list what was migrated, what was skipped (duplicates), and what failed\n\n## Important\n\n- Do NOT delete the original files - the user can do that manually after verifying\n- Do NOT migrate content that is purely derived from code (architecture, file structure) - it belongs in CLAUDE.md, not memory\n- If unsure about a memory's value, migrate it anyway - the decay system will naturally prune low-value memories over time\n`;\n\nconst SKILLS: Readonly<Record<string, string>> = {\n 'lp-migrate-memory': MIGRATE_MEMORY_SKILL,\n};\n\nfunction installSkills(projectDir: string): number {\n const skillsDir = join(projectDir, '.claude', 'skills');\n let installed = 0;\n\n for (const [name, content] of Object.entries(SKILLS)) {\n const skillDir = join(skillsDir, name);\n const skillPath = join(skillDir, 'SKILL.md');\n\n if (existsSync(skillPath)) continue;\n\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillPath, content.trimStart(), 'utf-8');\n installed++;\n }\n\n return installed;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAWzB,eAAsB,WAAW,MAAkC;AACjE,MAAI,MAAM;AACV,MAAI,KAAK,yBAAyB;AAClC,MAAI,MAAM;AAGV,QAAM,iBAAiB;AAEvB,QAAM,SAAS,WAAW,KAAK,SAAS,EAAE,SAAS,KAAK,OAAO,IAAI,MAAS;AAC5E,QAAM,UAAU,eAAe,OAAO,OAAO;AAG7C,MAAI,KAAK,8BAA8B;AACvC,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EACxC;AACA,QAAM,KAAK,eAAe,EAAE,QAAQ,CAAC;AACrC,UAAQ,EAAE;AACV,gBAAc,EAAE;AAChB,MAAI,QAAQ,GAAG,OAAO,kBAAkB;AAGxC,MAAI,KAAK,kCAAkC;AAC3C,QAAM,kBAAkB,QAAQ,IAAI,CAAC;AAGrC,MAAI,KAAK,iCAAiC;AAC1C,QAAM,aAAa,kBAAkB;AACrC,MAAI,YAAY;AACd,QAAI,QAAQ,4CAA4C;AAAA,EAC1D,OAAO;AACL,QAAI,KAAK,8CAA8C;AACvD,QAAI,KAAK,mFAAmF;AAAA,EAC9F;AAGA,MAAI,KAAK,6BAA6B;AACtC,QAAM,gBAAgB,uBAAuB,QAAQ,IAAI,CAAC;AAC1D,MAAI,eAAe;AACjB,QAAI,QAAQ,oCAAoC;AAAA,EAClD;AACA,QAAM,kBAAkB,cAAc,QAAQ,IAAI,CAAC;AACnD,MAAI,kBAAkB,GAAG;AACvB,QAAI,QAAQ,aAAa,eAAe,8BAA8B;AAAA,EACxE;AAEA,MAAI,MAAM;AACV,MAAI,QAAQ,0BAA0B;AACtC,MAAI,KAAK,iEAAiE;AAC1E,MAAI,MAAM;AACZ;AAEA,eAAe,kBAAkB,YAAmC;AAClE,QAAM,WAAW,MAAM,iBAAiB,UAAU;AAGlD,WAAS,mBAAmB,IAAI;AAChC,MAAI,KAAK,+BAA+B;AAGxC,QAAM,QAAS,SAAS,OAAO,KAAK,CAAC;AACrC,sBAAoB,KAAK;AACzB,cAAY,KAAK;AACjB,WAAS,OAAO,IAAI;AAGpB,qBAAmB,QAAQ;AAE3B,QAAM,kBAAkB,YAAY,QAAQ;AAC5C,MAAI,QAAQ,uBAAuB;AACrC;AAEA,SAAS,oBAAoB,OAAwC;AACnE,QAAM,oBAAqB,MAAM,cAAc,KAAK,CAAC;AACrD,QAAM,cAAc;AAEpB,QAAM,gBAAgB,kBAAkB,KAAK,CAAC,MAAM;AAClD,UAAM,aAAa,EAAE,OAAO;AAC5B,WAAO,YAAY;AAAA,MACjB,QAAM,OAAO,GAAG,SAAS,MAAM,YAAa,GAAG,SAAS,EAAa,SAAS,iCAAiC;AAAA,IACjH;AAAA,EACF,CAAC;AAED,MAAI,CAAC,eAAe;AAClB,sBAAkB,KAAK;AAAA,MACrB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,YAAY,CAAC;AAAA,IACnD,CAAC;AACD,UAAM,cAAc,IAAI;AACxB,QAAI,KAAK,kDAAkD;AAAA,EAC7D;AACF;AAEA,SAAS,YAAY,OAAwC;AAC3D,QAAM,YAAa,MAAM,MAAM,KAAK,CAAC;AACrC,QAAM,iBAAiB;AAEvB,QAAM,oBAAoB,UAAU,KAAK,CAAC,MAAM;AAC9C,UAAM,aAAa,EAAE,OAAO;AAC5B,WAAO,YAAY;AAAA,MACjB,QAAM,OAAO,GAAG,SAAS,MAAM,YAAa,GAAG,SAAS,EAAa,SAAS,iCAAiC;AAAA,IACjH;AAAA,EACF,CAAC;AAED,MAAI,CAAC,mBAAmB;AACtB,cAAU,KAAK;AAAA,MACb,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,gBAAgB,OAAO,KAAK,CAAC;AAAA,IACnE,CAAC;AACD,UAAM,MAAM,IAAI;AAChB,QAAI,KAAK,kDAAkD;AAAA,EAC7D;AACF;AAEA,SAAS,mBAAmB,UAAyC;AACnE,QAAM,cAAe,SAAS,aAAa,KAAK,CAAC;AACjD,QAAM,YAAa,YAAY,OAAO,KAAK,CAAC;AAE5C,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ;AACZ,aAAW,QAAQ,aAAa;AAC9B,QAAI,CAAC,UAAU,SAAS,IAAI,GAAG;AAC7B,gBAAU,KAAK,IAAI;AACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,GAAG;AACb,gBAAY,OAAO,IAAI;AACvB,aAAS,aAAa,IAAI;AAC1B,QAAI,KAAK,gBAAgB,KAAK,YAAY;AAAA,EAC5C;AACF;AAEA,eAAe,mBAAkC;AAC/C,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,4BAA0B;AAC9D,MAAI;AACF,eAAW,gBAAgB;AAC3B;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI,KAAK,gEAAgE;AACzE,MAAI;AACF,aAAS,4CAA4C,EAAE,OAAO,QAAQ,SAAS,KAAO,CAAC;AACvF,QAAI,QAAQ,wCAAwC;AAAA,EACtD,QAAQ;AACN,QAAI,MAAM,sDAAsD;AAChE,QAAI,MAAM;AACV,QAAI,KAAK,mBAAmB;AAC5B,QAAI,KAAK,4CAA4C;AACrD,QAAI,MAAM;AACV,QAAI,KAAK,0EAA0E;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,oBAA6B;AACpC,MAAI;AACF,UAAM,WAAW,SAAS,mBAAmB,EAAE,OAAO,QAAQ,SAAS,KAAO,UAAU,QAAQ,CAAC;AACjG,QAAI,SAAS,SAAS,gBAAgB,GAAG;AACvC,UAAI,KAAK,wCAAwC;AACjD,aAAO;AAAA,IACT;AACA;AAAA,MACE;AAAA,MACA,EAAE,OAAO,QAAQ,SAAS,IAAM;AAAA,IAClC;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWxB,SAAS,uBAAuB,YAA6B;AAC3D,QAAM,eAAe,KAAK,YAAY,WAAW;AAEjD,MAAI,UAAU;AACd,MAAI;AACF,cAAU,aAAa,cAAc,OAAO;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,4BAA4B,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,QAAQ,IAAI,OAAO;AAC3C,gBAAc,cAAc,SAAS,OAAO;AAC5C,SAAO;AACT;AAEA,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6C7B,IAAM,SAA2C;AAAA,EAC/C,qBAAqB;AACvB;AAEA,SAAS,cAAc,YAA4B;AACjD,QAAM,YAAY,KAAK,YAAY,WAAW,QAAQ;AACtD,MAAI,YAAY;AAEhB,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,MAAM,GAAG;AACpD,UAAM,WAAW,KAAK,WAAW,IAAI;AACrC,UAAM,YAAY,KAAK,UAAU,UAAU;AAE3C,QAAI,WAAW,SAAS,EAAG;AAE3B,cAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AACvC,kBAAc,WAAW,QAAQ,UAAU,GAAG,OAAO;AACrD;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/subcommands/install.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { createDatabase, closeDatabase } from '../storage/database.js';\nimport { migrate } from '../storage/migrator.js';\nimport { loadConfig, resolveDataDir } from '../config.js';\nimport { readSettingsJson, writeSettingsJson } from '../../../lib/settings.js';\nimport { log } from '../../../lib/output.js';\n\ninterface InstallOpts {\n readonly dbPath?: string;\n}\n\nexport async function runInstall(opts: InstallOpts): Promise<void> {\n log.blank();\n log.step('Memory system - install');\n log.blank();\n\n // Step 0: Ensure native deps are installed globally\n await ensureNativeDeps();\n\n const config = loadConfig(opts.dbPath ? { dataDir: opts.dbPath } : undefined);\n const dataDir = resolveDataDir(config.dataDir);\n\n // Step 1: Database\n log.step('[1/4] Setting up database...');\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const db = createDatabase({ dataDir });\n migrate(db);\n closeDatabase(db);\n log.success(`${dataDir}/memory.db ready`);\n\n // Step 2: Configure Claude Code settings\n log.step('[2/4] Configuring Claude Code...');\n await configureSettings(process.cwd());\n\n // Step 3: Register MCP server\n log.step('[3/4] Registering MCP server...');\n const registered = registerMcpServer();\n if (registered) {\n log.success('MCP server registered via `claude mcp add`');\n } else {\n log.warn('Could not register MCP server automatically.');\n log.info('Run: claude mcp add agentic-memory -- npx claude-launchpad memory serve');\n }\n\n // Step 4: CLAUDE.md + skills\n log.step('[4/4] Injecting guidance...');\n const guidanceAdded = injectClaudeMdGuidance(process.cwd());\n if (guidanceAdded) {\n log.success('Memory guidance added to CLAUDE.md');\n }\n const skillsInstalled = installSkills(process.cwd());\n if (skillsInstalled > 0) {\n log.success(`Installed ${skillsInstalled} skill(s) to .claude/skills/`);\n }\n\n log.blank();\n log.success('Memory system installed.');\n log.info('Restart your Claude Code session for the MCP server to connect.');\n log.blank();\n}\n\nasync function configureSettings(projectDir: string): Promise<void> {\n const settings = await readSettingsJson(projectDir);\n\n // Disable built-in auto-memory\n settings['autoMemoryEnabled'] = false;\n log.info('Built-in auto-memory disabled');\n\n // SessionStart hook\n const hooks = (settings['hooks'] ?? {}) as Record<string, unknown[]>;\n addSessionStartHook(hooks);\n addStopHook(hooks);\n settings['hooks'] = hooks;\n\n // Auto-allow MCP tools\n addToolPermissions(settings);\n\n await writeSettingsJson(projectDir, settings);\n log.success('settings.json updated');\n}\n\nfunction addSessionStartHook(hooks: Record<string, unknown[]>): void {\n const sessionStartHooks = (hooks['SessionStart'] ?? []) as Record<string, unknown>[];\n const hookCommand = 'npx claude-launchpad memory context --json 2>/dev/null; exit 0';\n\n const alreadyHooked = sessionStartHooks.some((h) => {\n const innerHooks = h['hooks'] as Record<string, unknown>[] | undefined;\n return innerHooks?.some(\n ih => typeof ih['command'] === 'string' && (ih['command'] as string).includes('claude-launchpad memory context'),\n );\n });\n\n if (!alreadyHooked) {\n sessionStartHooks.push({\n matcher: 'startup|resume',\n hooks: [{ type: 'command', command: hookCommand }],\n });\n hooks['SessionStart'] = sessionStartHooks;\n log.info('SessionStart hook added (injects memory context)');\n }\n}\n\nfunction addStopHook(hooks: Record<string, unknown[]>): void {\n const stopHooks = (hooks['Stop'] ?? []) as Record<string, unknown>[];\n const extractCommand = 'npx claude-launchpad memory extract 2>/dev/null; exit 0';\n\n const alreadyHasExtract = stopHooks.some((h) => {\n const innerHooks = h['hooks'] as Record<string, unknown>[] | undefined;\n return innerHooks?.some(\n ih => typeof ih['command'] === 'string' && (ih['command'] as string).includes('claude-launchpad memory extract'),\n );\n });\n\n if (!alreadyHasExtract) {\n stopHooks.push({\n hooks: [{ type: 'command', command: extractCommand, async: true }],\n });\n hooks['Stop'] = stopHooks;\n log.info('Stop hook added (extracts facts from transcript)');\n }\n}\n\nfunction addToolPermissions(settings: Record<string, unknown>): void {\n const permissions = (settings['permissions'] ?? {}) as Record<string, unknown>;\n const allowList = (permissions['allow'] ?? []) as string[];\n\n const memoryTools = [\n 'mcp__agentic-memory__memory_store',\n 'mcp__agentic-memory__memory_search',\n 'mcp__agentic-memory__memory_recent',\n 'mcp__agentic-memory__memory_forget',\n 'mcp__agentic-memory__memory_relate',\n 'mcp__agentic-memory__memory_stats',\n 'mcp__agentic-memory__memory_update',\n ];\n\n let added = 0;\n for (const tool of memoryTools) {\n if (!allowList.includes(tool)) {\n allowList.push(tool);\n added++;\n }\n }\n\n if (added > 0) {\n permissions['allow'] = allowList;\n settings['permissions'] = permissions;\n log.info(`Auto-allowed ${added} MCP tools`);\n }\n}\n\nasync function ensureNativeDeps(): Promise<void> {\n const { cwdRequire } = await import('../utils/require-deps.js');\n try {\n cwdRequire('better-sqlite3');\n return;\n } catch {\n // Not installed — install globally\n }\n\n log.step('Installing native dependencies (better-sqlite3, sqlite-vec)...');\n try {\n execSync('npm install -g better-sqlite3 sqlite-vec', { stdio: 'pipe', timeout: 120000 });\n log.success('Native dependencies installed globally');\n } catch {\n log.error('Failed to install native dependencies automatically.');\n log.blank();\n log.info('Install manually:');\n log.step(' npm install -g better-sqlite3 sqlite-vec');\n log.blank();\n log.info('This requires a C++ compiler (Xcode on macOS, build-essential on Linux).');\n process.exit(1);\n }\n}\n\nfunction registerMcpServer(): boolean {\n try {\n execSync(\n 'claude mcp add --scope user agentic-memory npx claude-launchpad memory serve',\n { stdio: 'pipe', timeout: 10000 },\n );\n return true;\n } catch {\n return false;\n }\n}\n\nconst MEMORY_GUIDANCE = `\n## Memory (agentic-memory)\nThis project uses **agentic-memory** for persistent memory across sessions.\n- **DO NOT** use the built-in auto-memory system (~/.claude/projects/*/memory/)\n- Memory context is **automatically injected** at session start via SessionStart hook - no need to call memory_recent manually\n- Use \\`memory_search\\` to find specific memories by keyword\n- Use \\`memory_store\\` to save decisions, gotchas, and learnings worth remembering\n- Use \\`memory_stats\\` to check memory health\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. Don't wait for session end - the Stop hook only catches obvious patterns.\n`;\n\nfunction injectClaudeMdGuidance(projectDir: string): boolean {\n const claudeMdPath = join(projectDir, 'CLAUDE.md');\n\n let content = '';\n try {\n content = readFileSync(claudeMdPath, 'utf-8');\n } catch {\n return false;\n }\n\n if (content.includes('## Memory (agentic-memory)')) {\n return false;\n }\n\n const updated = content.trimEnd() + '\\n' + MEMORY_GUIDANCE;\n writeFileSync(claudeMdPath, updated, 'utf-8');\n return true;\n}\n\nconst MIGRATE_MEMORY_SKILL = `---\nname: lp-migrate-memory\ndescription: Migrate legacy Claude Code auto-memory files (~/.claude/projects/*/memory/*.md) into agentic-memory. Use when setting up agentic-memory on a project that already has built-in memories.\nallowed-tools: Read, Glob, Grep, mcp__agentic-memory__memory_store, mcp__agentic-memory__memory_search\n---\n\n# Migrate Legacy Claude Code Memories\n\nMigrate memory files from Claude Code's built-in auto-memory system into agentic-memory.\n\n## Steps\n\n1. **Find legacy memory files** for this project:\n - Scan \\`~/.claude/projects/*/memory/*.md\\` for directories whose slug matches the current project path\n - The slug format is the absolute path with \\`/\\` replaced by \\`-\\` and leading \\`-\\` (e.g. \\`-Users-john-projects-myapp\\`)\n - Also check \\`~/.claude/projects/*/memory/team/*.md\\` for team memories\n\n2. **For each memory file found**, read it and parse:\n - YAML frontmatter: \\`name\\`, \\`description\\`, \\`type\\` (user/feedback/project/reference)\n - Body content (everything after the frontmatter closing \\`---\\`)\n - Skip \\`MEMORY.md\\` (it's just an index file, not a memory)\n\n3. **Before storing**, check for duplicates:\n - Call \\`memory_search\\` with the memory description or first 100 chars of content\n - If a close match exists (same topic), skip it and report\n\n4. **Map types and store** each memory via \\`memory_store\\`:\n - \\`user\\` -> type: \\`semantic\\`, tags: [\\`user\\`, \\`migrated\\`], importance: 0.7\n - \\`feedback\\` -> type: \\`semantic\\`, tags: [\\`feedback\\`, \\`migrated\\`], importance: 0.8\n - \\`project\\` -> type: \\`semantic\\`, tags: [\\`project\\`, \\`migrated\\`], importance: 0.6\n - \\`reference\\` -> type: \\`semantic\\`, tags: [\\`reference\\`, \\`migrated\\`], importance: 0.5\n - Use the frontmatter \\`name\\` as the title\n - Use the body content as the memory content\n - Set source: \\`import\\`\n - Adjust importance up/down based on the content (decisions and gotchas deserve higher importance)\n\n5. **Report results**: list what was migrated, what was skipped (duplicates), and what failed\n\n## Important\n\n- Do NOT delete the original files - the user can do that manually after verifying\n- Do NOT migrate content that is purely derived from code (architecture, file structure) - it belongs in CLAUDE.md, not memory\n- If unsure about a memory's value, migrate it anyway - the decay system will naturally prune low-value memories over time\n`;\n\nconst SKILLS: Readonly<Record<string, string>> = {\n 'lp-migrate-memory': MIGRATE_MEMORY_SKILL,\n};\n\nfunction installSkills(projectDir: string): number {\n const skillsDir = join(projectDir, '.claude', 'skills');\n let installed = 0;\n\n for (const [name, content] of Object.entries(SKILLS)) {\n const skillDir = join(skillsDir, name);\n const skillPath = join(skillDir, 'SKILL.md');\n\n if (existsSync(skillPath)) continue;\n\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillPath, content.trimStart(), 'utf-8');\n installed++;\n }\n\n return installed;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAWzB,eAAsB,WAAW,MAAkC;AACjE,MAAI,MAAM;AACV,MAAI,KAAK,yBAAyB;AAClC,MAAI,MAAM;AAGV,QAAM,iBAAiB;AAEvB,QAAM,SAAS,WAAW,KAAK,SAAS,EAAE,SAAS,KAAK,OAAO,IAAI,MAAS;AAC5E,QAAM,UAAU,eAAe,OAAO,OAAO;AAG7C,MAAI,KAAK,8BAA8B;AACvC,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EACxC;AACA,QAAM,KAAK,eAAe,EAAE,QAAQ,CAAC;AACrC,UAAQ,EAAE;AACV,gBAAc,EAAE;AAChB,MAAI,QAAQ,GAAG,OAAO,kBAAkB;AAGxC,MAAI,KAAK,kCAAkC;AAC3C,QAAM,kBAAkB,QAAQ,IAAI,CAAC;AAGrC,MAAI,KAAK,iCAAiC;AAC1C,QAAM,aAAa,kBAAkB;AACrC,MAAI,YAAY;AACd,QAAI,QAAQ,4CAA4C;AAAA,EAC1D,OAAO;AACL,QAAI,KAAK,8CAA8C;AACvD,QAAI,KAAK,yEAAyE;AAAA,EACpF;AAGA,MAAI,KAAK,6BAA6B;AACtC,QAAM,gBAAgB,uBAAuB,QAAQ,IAAI,CAAC;AAC1D,MAAI,eAAe;AACjB,QAAI,QAAQ,oCAAoC;AAAA,EAClD;AACA,QAAM,kBAAkB,cAAc,QAAQ,IAAI,CAAC;AACnD,MAAI,kBAAkB,GAAG;AACvB,QAAI,QAAQ,aAAa,eAAe,8BAA8B;AAAA,EACxE;AAEA,MAAI,MAAM;AACV,MAAI,QAAQ,0BAA0B;AACtC,MAAI,KAAK,iEAAiE;AAC1E,MAAI,MAAM;AACZ;AAEA,eAAe,kBAAkB,YAAmC;AAClE,QAAM,WAAW,MAAM,iBAAiB,UAAU;AAGlD,WAAS,mBAAmB,IAAI;AAChC,MAAI,KAAK,+BAA+B;AAGxC,QAAM,QAAS,SAAS,OAAO,KAAK,CAAC;AACrC,sBAAoB,KAAK;AACzB,cAAY,KAAK;AACjB,WAAS,OAAO,IAAI;AAGpB,qBAAmB,QAAQ;AAE3B,QAAM,kBAAkB,YAAY,QAAQ;AAC5C,MAAI,QAAQ,uBAAuB;AACrC;AAEA,SAAS,oBAAoB,OAAwC;AACnE,QAAM,oBAAqB,MAAM,cAAc,KAAK,CAAC;AACrD,QAAM,cAAc;AAEpB,QAAM,gBAAgB,kBAAkB,KAAK,CAAC,MAAM;AAClD,UAAM,aAAa,EAAE,OAAO;AAC5B,WAAO,YAAY;AAAA,MACjB,QAAM,OAAO,GAAG,SAAS,MAAM,YAAa,GAAG,SAAS,EAAa,SAAS,iCAAiC;AAAA,IACjH;AAAA,EACF,CAAC;AAED,MAAI,CAAC,eAAe;AAClB,sBAAkB,KAAK;AAAA,MACrB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,YAAY,CAAC;AAAA,IACnD,CAAC;AACD,UAAM,cAAc,IAAI;AACxB,QAAI,KAAK,kDAAkD;AAAA,EAC7D;AACF;AAEA,SAAS,YAAY,OAAwC;AAC3D,QAAM,YAAa,MAAM,MAAM,KAAK,CAAC;AACrC,QAAM,iBAAiB;AAEvB,QAAM,oBAAoB,UAAU,KAAK,CAAC,MAAM;AAC9C,UAAM,aAAa,EAAE,OAAO;AAC5B,WAAO,YAAY;AAAA,MACjB,QAAM,OAAO,GAAG,SAAS,MAAM,YAAa,GAAG,SAAS,EAAa,SAAS,iCAAiC;AAAA,IACjH;AAAA,EACF,CAAC;AAED,MAAI,CAAC,mBAAmB;AACtB,cAAU,KAAK;AAAA,MACb,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,gBAAgB,OAAO,KAAK,CAAC;AAAA,IACnE,CAAC;AACD,UAAM,MAAM,IAAI;AAChB,QAAI,KAAK,kDAAkD;AAAA,EAC7D;AACF;AAEA,SAAS,mBAAmB,UAAyC;AACnE,QAAM,cAAe,SAAS,aAAa,KAAK,CAAC;AACjD,QAAM,YAAa,YAAY,OAAO,KAAK,CAAC;AAE5C,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ;AACZ,aAAW,QAAQ,aAAa;AAC9B,QAAI,CAAC,UAAU,SAAS,IAAI,GAAG;AAC7B,gBAAU,KAAK,IAAI;AACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,GAAG;AACb,gBAAY,OAAO,IAAI;AACvB,aAAS,aAAa,IAAI;AAC1B,QAAI,KAAK,gBAAgB,KAAK,YAAY;AAAA,EAC5C;AACF;AAEA,eAAe,mBAAkC;AAC/C,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,4BAA0B;AAC9D,MAAI;AACF,eAAW,gBAAgB;AAC3B;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI,KAAK,gEAAgE;AACzE,MAAI;AACF,aAAS,4CAA4C,EAAE,OAAO,QAAQ,SAAS,KAAO,CAAC;AACvF,QAAI,QAAQ,wCAAwC;AAAA,EACtD,QAAQ;AACN,QAAI,MAAM,sDAAsD;AAChE,QAAI,MAAM;AACV,QAAI,KAAK,mBAAmB;AAC5B,QAAI,KAAK,4CAA4C;AACrD,QAAI,MAAM;AACV,QAAI,KAAK,0EAA0E;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,oBAA6B;AACpC,MAAI;AACF;AAAA,MACE;AAAA,MACA,EAAE,OAAO,QAAQ,SAAS,IAAM;AAAA,IAClC;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWxB,SAAS,uBAAuB,YAA6B;AAC3D,QAAM,eAAe,KAAK,YAAY,WAAW;AAEjD,MAAI,UAAU;AACd,MAAI;AACF,cAAU,aAAa,cAAc,OAAO;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS,4BAA4B,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,QAAQ,IAAI,OAAO;AAC3C,gBAAc,cAAc,SAAS,OAAO;AAC5C,SAAO;AACT;AAEA,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6C7B,IAAM,SAA2C;AAAA,EAC/C,qBAAqB;AACvB;AAEA,SAAS,cAAc,YAA4B;AACjD,QAAM,YAAY,KAAK,YAAY,WAAW,QAAQ;AACtD,MAAI,YAAY;AAEhB,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,MAAM,GAAG;AACpD,UAAM,WAAW,KAAK,WAAW,IAAI;AACrC,UAAM,YAAY,KAAK,UAAU,UAAU;AAE3C,QAAI,WAAW,SAAS,EAAG;AAE3B,cAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AACvC,kBAAc,WAAW,QAAQ,UAAU,GAAG,OAAO;AACrD;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|