claude-launchpad 0.7.8 → 0.8.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.
File without changes
File without changes
File without changes
@@ -154,7 +154,7 @@ async function ensureNativeDeps() {
154
154
  function registerMcpServer() {
155
155
  try {
156
156
  execSync(
157
- "claude mcp add --scope user agentic-memory -- npx claude-launchpad memory serve",
157
+ "claude mcp add --scope user agentic-memory npx claude-launchpad memory serve",
158
158
  { stdio: "pipe", timeout: 1e4 }
159
159
  );
160
160
  return true;
@@ -250,4 +250,4 @@ function installSkills(projectDir) {
250
250
  export {
251
251
  runInstall
252
252
  };
253
- //# sourceMappingURL=install-56GBDZHM.js.map
253
+ //# sourceMappingURL=install-3IW2PDOS.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 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":"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","names":[]}
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,25 +1,11 @@
1
1
  {
2
2
  "name": "claude-launchpad",
3
- "version": "0.7.8",
3
+ "version": "0.8.0",
4
4
  "description": "CLI toolkit that makes Claude Code setups measurably good - scaffold, diagnose, evaluate, remember",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "claude-launchpad": "./dist/cli.js"
8
8
  },
9
- "scripts": {
10
- "dev": "tsx watch src/cli.ts",
11
- "build": "tsup",
12
- "start": "tsx src/cli.ts",
13
- "test": "vitest",
14
- "test:run": "vitest run",
15
- "lint": "eslint src/ --ext .ts",
16
- "typecheck": "tsc --noEmit",
17
- "prepublishOnly": "pnpm build",
18
- "publish:dev": "npm version prerelease --preid=dev && npm publish --tag dev",
19
- "publish:release": "npm publish",
20
- "docs:dev": "cd docs && pnpm dev",
21
- "docs:build": "cd docs && pnpm build"
22
- },
23
9
  "keywords": [
24
10
  "claude",
25
11
  "claude-code",
@@ -46,7 +32,6 @@
46
32
  "engines": {
47
33
  "node": ">=22"
48
34
  },
49
- "packageManager": "pnpm@10.26.1",
50
35
  "dependencies": {
51
36
  "@inquirer/prompts": "^8.3.2",
52
37
  "chalk": "^5.6.2",
@@ -71,9 +56,17 @@
71
56
  "typescript": "^6.0.2",
72
57
  "vitest": "^4.1.2"
73
58
  },
74
- "pnpm": {
75
- "onlyBuiltDependencies": [
76
- "better-sqlite3"
77
- ]
59
+ "scripts": {
60
+ "dev": "tsx watch src/cli.ts",
61
+ "build": "tsup",
62
+ "start": "tsx src/cli.ts",
63
+ "test": "vitest",
64
+ "test:run": "vitest run",
65
+ "lint": "eslint src/ --ext .ts",
66
+ "typecheck": "tsc --noEmit",
67
+ "publish:dev": "npm version prerelease --preid=dev --no-git-tag-version && node scripts/sync-version.mjs && npm publish --tag dev",
68
+ "publish:release": "npm publish",
69
+ "docs:dev": "cd docs && pnpm dev",
70
+ "docs:build": "cd docs && pnpm build"
78
71
  }
79
- }
72
+ }
@@ -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":"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","names":[]}