claude-launchpad 0.16.0 → 0.16.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.
Files changed (30) hide show
  1. package/dist/{chunk-Z6FBT44W.js → chunk-IZFQTQ4C.js} +2 -2
  2. package/dist/{chunk-EDKY7JWY.js → chunk-NLZGJHE5.js} +3 -3
  3. package/dist/chunk-S4WIADYE.js +1139 -0
  4. package/dist/chunk-S4WIADYE.js.map +1 -0
  5. package/dist/{chunk-5MWCQLNL.js → chunk-SVWFSAYP.js} +2 -2
  6. package/dist/cli.js +118 -1060
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/memory/server.js +3 -3
  9. package/dist/{context-CWJUUTTU.js → context-53PKQOMI.js} +5 -5
  10. package/dist/{install-MVATZUXZ.js → install-PFTFTNIF.js} +11 -13
  11. package/dist/{install-MVATZUXZ.js.map → install-PFTFTNIF.js.map} +1 -1
  12. package/dist/{pull-YOESZ3UC.js → pull-4QTS57DQ.js} +6 -6
  13. package/dist/{push-74XC5CUK.js → push-JOCEW3VG.js} +6 -6
  14. package/dist/{require-deps-NKRCPVAO.js → require-deps-SUGLVBM2.js} +3 -3
  15. package/dist/{stats-QUBHHPV7.js → stats-7WFCVXBX.js} +6 -6
  16. package/dist/{tui-XIYOOUP6.js → tui-DKWRY5PT.js} +4 -4
  17. package/package.json +1 -1
  18. package/dist/chunk-RJGXPH7P.js +0 -107
  19. package/dist/chunk-RJGXPH7P.js.map +0 -1
  20. package/dist/chunk-SBA5KYQU.js +0 -76
  21. package/dist/chunk-SBA5KYQU.js.map +0 -1
  22. /package/dist/{chunk-Z6FBT44W.js.map → chunk-IZFQTQ4C.js.map} +0 -0
  23. /package/dist/{chunk-EDKY7JWY.js.map → chunk-NLZGJHE5.js.map} +0 -0
  24. /package/dist/{chunk-5MWCQLNL.js.map → chunk-SVWFSAYP.js.map} +0 -0
  25. /package/dist/{context-CWJUUTTU.js.map → context-53PKQOMI.js.map} +0 -0
  26. /package/dist/{pull-YOESZ3UC.js.map → pull-4QTS57DQ.js.map} +0 -0
  27. /package/dist/{push-74XC5CUK.js.map → push-JOCEW3VG.js.map} +0 -0
  28. /package/dist/{require-deps-NKRCPVAO.js.map → require-deps-SUGLVBM2.js.map} +0 -0
  29. /package/dist/{stats-QUBHHPV7.js.map → stats-7WFCVXBX.js.map} +0 -0
  30. /package/dist/{tui-XIYOOUP6.js.map → tui-DKWRY5PT.js.map} +0 -0
@@ -23,9 +23,9 @@ import {
23
23
  loadConfig,
24
24
  migrate,
25
25
  resolveDataDir
26
- } from "../../chunk-EDKY7JWY.js";
27
- import "../../chunk-Z6FBT44W.js";
28
- import "../../chunk-RJGXPH7P.js";
26
+ } from "../../chunk-NLZGJHE5.js";
27
+ import "../../chunk-IZFQTQ4C.js";
28
+ import "../../chunk-S4WIADYE.js";
29
29
 
30
30
  // src/commands/memory/server.ts
31
31
  import { createRequire } from "module";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-NAW47BYA.js";
9
9
  import {
10
10
  initStorage
11
- } from "./chunk-5MWCQLNL.js";
11
+ } from "./chunk-SVWFSAYP.js";
12
12
  import "./chunk-24VLPHJU.js";
13
13
  import {
14
14
  DEFAULT_DECAY_PARAMS,
@@ -22,9 +22,9 @@ import {
22
22
  RECENCY_HALF_LIFE,
23
23
  TYPE_INJECTION_BONUS,
24
24
  estimateTokens
25
- } from "./chunk-EDKY7JWY.js";
26
- import "./chunk-Z6FBT44W.js";
27
- import "./chunk-RJGXPH7P.js";
25
+ } from "./chunk-NLZGJHE5.js";
26
+ import "./chunk-IZFQTQ4C.js";
27
+ import "./chunk-S4WIADYE.js";
28
28
 
29
29
  // src/commands/memory/subcommands/context.ts
30
30
  import { readFileSync, writeFileSync } from "fs";
@@ -439,4 +439,4 @@ async function runContext(opts) {
439
439
  export {
440
440
  runContext
441
441
  };
442
- //# sourceMappingURL=context-CWJUUTTU.js.map
442
+ //# sourceMappingURL=context-53PKQOMI.js.map
@@ -1,11 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- getMemoryPlacement,
4
- readSettingsJson,
5
- readSettingsLocalJson,
6
- writeSettingsJson,
7
- writeSettingsLocalJson
8
- } from "./chunk-SBA5KYQU.js";
9
2
  import {
10
3
  readSyncConfig
11
4
  } from "./chunk-JQDMBE7W.js";
@@ -15,11 +8,16 @@ import {
15
8
  loadConfig,
16
9
  migrate,
17
10
  resolveDataDir
18
- } from "./chunk-EDKY7JWY.js";
19
- import "./chunk-Z6FBT44W.js";
11
+ } from "./chunk-NLZGJHE5.js";
12
+ import "./chunk-IZFQTQ4C.js";
20
13
  import {
21
- log
22
- } from "./chunk-RJGXPH7P.js";
14
+ getMemoryPlacement,
15
+ log,
16
+ readSettingsJson,
17
+ readSettingsLocalJson,
18
+ writeSettingsJson,
19
+ writeSettingsLocalJson
20
+ } from "./chunk-S4WIADYE.js";
23
21
 
24
22
  // src/commands/memory/subcommands/install.ts
25
23
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -179,7 +177,7 @@ function addToolPermissions(settings) {
179
177
  }
180
178
  }
181
179
  async function ensureNativeDeps() {
182
- const { cwdRequire } = await import("./require-deps-NKRCPVAO.js");
180
+ const { cwdRequire } = await import("./require-deps-SUGLVBM2.js");
183
181
  try {
184
182
  cwdRequire("better-sqlite3");
185
183
  return;
@@ -306,4 +304,4 @@ export {
306
304
  detectExistingSetup,
307
305
  runInstall
308
306
  };
309
- //# sourceMappingURL=install-MVATZUXZ.js.map
307
+ //# sourceMappingURL=install-PFTFTNIF.js.map
@@ -1 +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, readSettingsLocalJson, writeSettingsLocalJson } from '../../../lib/settings.js';\nimport { getMemoryPlacement } from '../../../lib/memory-placement.js';\nimport { log } from '../../../lib/output.js';\nimport { readSyncConfig } from '../utils/gist-transport.js';\nimport type { MemoryPlacement } from '../../../types/index.js';\n\ninterface InstallOpts {\n readonly dbPath?: string;\n}\n\nexport async function runInstall(opts: InstallOpts): Promise<void> {\n log.blank();\n log.step('Setting up your knowledge base');\n log.blank();\n\n // Step 0: Ensure native deps are installed globally\n await ensureNativeDeps();\n\n // Prompt for placement before any config writes\n const placement = await getMemoryPlacement(process.cwd());\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/5] Creating knowledge base...');\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const db = createDatabase({ dataDir });\n migrate(db);\n closeDatabase(db);\n log.success(`Knowledge base created at ${dataDir}/memory.db`);\n\n // Step 2: Configure Claude Code settings\n log.step('[2/5] Connecting to Claude Code...');\n await configureSettings(process.cwd(), placement);\n\n // Step 3: Register MCP server (project scope for shared, local scope for local)\n log.step('[3/5] Enabling memory tools...');\n const mcpScope = placement === \"local\" ? \"local\" : \"project\";\n const registered = registerMcpServer(mcpScope);\n if (registered) {\n log.success('Memory tools available in Claude Code');\n } else {\n log.warn('Could not enable memory tools automatically.');\n log.info(`Run: claude mcp add --scope ${mcpScope} agentic-memory -- npx claude-launchpad memory serve`);\n }\n\n // Step 4: CLAUDE.md + skills\n log.step('[4/5] Adding instructions...');\n const guidanceAdded = injectClaudeMdGuidance(process.cwd(), placement);\n if (guidanceAdded) {\n const label = placement === \"local\" ? \".claude/CLAUDE.md\" : \"CLAUDE.md\";\n log.success(`${label} updated with memory instructions`);\n }\n if (placement === \"shared\") {\n const skillsInstalled = installSkills(process.cwd());\n if (skillsInstalled > 0) {\n log.success(`Installed ${skillsInstalled} skill(s) to .claude/skills/`);\n }\n }\n\n log.blank();\n log.success('Knowledge base is ready. Claude will now remember across sessions.');\n log.info('Restart your Claude Code session to activate.');\n log.blank();\n}\n\nexport function detectExistingSetup(projectDir: string): MemoryPlacement | null {\n // Check local CLAUDE.md\n try {\n const localClaude = readFileSync(join(projectDir, '.claude', 'CLAUDE.md'), 'utf-8');\n if (localClaude.includes('## Memory') || localClaude.includes('agentic-memory')) return \"local\";\n } catch { /* not found */ }\n\n // Check root CLAUDE.md\n try {\n const rootClaude = readFileSync(join(projectDir, 'CLAUDE.md'), 'utf-8');\n if (rootClaude.includes('## Memory (agentic-memory)')) return \"shared\";\n } catch { /* not found */ }\n\n return null;\n}\n\nasync function configureSettings(projectDir: string, placement: MemoryPlacement): Promise<void> {\n const read = placement === \"local\" ? readSettingsLocalJson : readSettingsJson;\n const write = placement === \"local\" ? writeSettingsLocalJson : writeSettingsJson;\n const settings = await read(projectDir);\n\n // Disable built-in auto-memory\n settings['autoMemoryEnabled'] = false;\n log.info('Built-in auto-memory disabled (replaced by knowledge base)');\n\n // SessionStart hooks\n const hooks = (settings['hooks'] ?? {}) as Record<string, unknown[]>;\n if (readSyncConfig()) {\n addSessionStartPullHook(hooks);\n }\n addSessionStartHook(hooks);\n\n // SessionEnd push hook (only when sync is already configured)\n if (readSyncConfig()) {\n addSessionEndPushHook(hooks);\n }\n\n settings['hooks'] = hooks;\n\n // Auto-allow MCP tools\n addToolPermissions(settings);\n\n await write(projectDir, settings);\n const target = placement === \"local\" ? \"settings.local.json\" : \"settings.json\";\n log.success(`Claude Code configured in ${target}`);\n}\n\nfunction addSessionStartPullHook(hooks: Record<string, unknown[]>): void {\n const sessionStartHooks = (hooks['SessionStart'] ?? []) as Record<string, unknown>[];\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('memory pull'),\n );\n });\n\n if (!alreadyHooked) {\n // Insert at the beginning so pull runs before context injection\n sessionStartHooks.unshift({\n matcher: 'startup',\n hooks: [{ type: 'command', command: 'claude-launchpad memory pull -y 2>/dev/null; exit 0' }],\n });\n hooks['SessionStart'] = sessionStartHooks;\n log.info('Session start: memories will auto-pull from GitHub Gist');\n }\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('Session start: Claude will recall relevant context automatically');\n }\n}\n\nfunction addSessionEndPushHook(hooks: Record<string, unknown[]>): void {\n const sessionEndHooks = (hooks['SessionEnd'] ?? []) as Record<string, unknown>[];\n const alreadyHooked = sessionEndHooks.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('memory push'),\n );\n });\n\n if (!alreadyHooked) {\n sessionEndHooks.push({\n hooks: [{ type: 'command', command: 'claude-launchpad memory push -y >/dev/null 2>&1 & exit 0' }],\n });\n hooks['SessionEnd'] = sessionEndHooks;\n log.info('Session end: memories will auto-push to GitHub Gist');\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(`${added} memory tools auto-approved`);\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 required database libraries...');\n try {\n execSync('npm install -g better-sqlite3 sqlite-vec', { stdio: 'pipe', timeout: 120000 });\n log.success('Database libraries installed');\n } catch {\n log.error('Could not install database libraries 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('Requires a C++ compiler (Xcode on macOS, build-essential on Linux).');\n process.exit(1);\n }\n}\n\nfunction registerMcpServer(scope: \"project\" | \"local\"): 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('Memory tools already registered');\n return true;\n }\n execSync(\n `claude mcp add --scope ${scope} 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\n`;\n\nfunction injectClaudeMdGuidance(projectDir: string, placement: MemoryPlacement): boolean {\n const claudeMdPath = placement === \"local\"\n ? join(projectDir, '.claude', 'CLAUDE.md')\n : join(projectDir, 'CLAUDE.md');\n\n let content = '';\n try {\n content = readFileSync(claudeMdPath, 'utf-8');\n } catch {\n if (placement !== \"local\") return false;\n // Create local .claude/CLAUDE.md\n mkdirSync(join(projectDir, '.claude'), { recursive: true });\n content = '# Local Claude Config\\n';\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;AAczB,eAAsB,WAAW,MAAkC;AACjE,MAAI,MAAM;AACV,MAAI,KAAK,gCAAgC;AACzC,MAAI,MAAM;AAGV,QAAM,iBAAiB;AAGvB,QAAM,YAAY,MAAM,mBAAmB,QAAQ,IAAI,CAAC;AAExD,QAAM,SAAS,WAAW,KAAK,SAAS,EAAE,SAAS,KAAK,OAAO,IAAI,MAAS;AAC5E,QAAM,UAAU,eAAe,OAAO,OAAO;AAG7C,MAAI,KAAK,kCAAkC;AAC3C,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,6BAA6B,OAAO,YAAY;AAG5D,MAAI,KAAK,oCAAoC;AAC7C,QAAM,kBAAkB,QAAQ,IAAI,GAAG,SAAS;AAGhD,MAAI,KAAK,gCAAgC;AACzC,QAAM,WAAW,cAAc,UAAU,UAAU;AACnD,QAAM,aAAa,kBAAkB,QAAQ;AAC7C,MAAI,YAAY;AACd,QAAI,QAAQ,uCAAuC;AAAA,EACrD,OAAO;AACL,QAAI,KAAK,8CAA8C;AACvD,QAAI,KAAK,+BAA+B,QAAQ,sDAAsD;AAAA,EACxG;AAGA,MAAI,KAAK,8BAA8B;AACvC,QAAM,gBAAgB,uBAAuB,QAAQ,IAAI,GAAG,SAAS;AACrE,MAAI,eAAe;AACjB,UAAM,QAAQ,cAAc,UAAU,sBAAsB;AAC5D,QAAI,QAAQ,GAAG,KAAK,mCAAmC;AAAA,EACzD;AACA,MAAI,cAAc,UAAU;AAC1B,UAAM,kBAAkB,cAAc,QAAQ,IAAI,CAAC;AACnD,QAAI,kBAAkB,GAAG;AACvB,UAAI,QAAQ,aAAa,eAAe,8BAA8B;AAAA,IACxE;AAAA,EACF;AAEA,MAAI,MAAM;AACV,MAAI,QAAQ,oEAAoE;AAChF,MAAI,KAAK,+CAA+C;AACxD,MAAI,MAAM;AACZ;AAEO,SAAS,oBAAoB,YAA4C;AAE9E,MAAI;AACF,UAAM,cAAc,aAAa,KAAK,YAAY,WAAW,WAAW,GAAG,OAAO;AAClF,QAAI,YAAY,SAAS,WAAW,KAAK,YAAY,SAAS,gBAAgB,EAAG,QAAO;AAAA,EAC1F,QAAQ;AAAA,EAAkB;AAG1B,MAAI;AACF,UAAM,aAAa,aAAa,KAAK,YAAY,WAAW,GAAG,OAAO;AACtE,QAAI,WAAW,SAAS,4BAA4B,EAAG,QAAO;AAAA,EAChE,QAAQ;AAAA,EAAkB;AAE1B,SAAO;AACT;AAEA,eAAe,kBAAkB,YAAoB,WAA2C;AAC9F,QAAM,OAAO,cAAc,UAAU,wBAAwB;AAC7D,QAAM,QAAQ,cAAc,UAAU,yBAAyB;AAC/D,QAAM,WAAW,MAAM,KAAK,UAAU;AAGtC,WAAS,mBAAmB,IAAI;AAChC,MAAI,KAAK,4DAA4D;AAGrE,QAAM,QAAS,SAAS,OAAO,KAAK,CAAC;AACrC,MAAI,eAAe,GAAG;AACpB,4BAAwB,KAAK;AAAA,EAC/B;AACA,sBAAoB,KAAK;AAGzB,MAAI,eAAe,GAAG;AACpB,0BAAsB,KAAK;AAAA,EAC7B;AAEA,WAAS,OAAO,IAAI;AAGpB,qBAAmB,QAAQ;AAE3B,QAAM,MAAM,YAAY,QAAQ;AAChC,QAAM,SAAS,cAAc,UAAU,wBAAwB;AAC/D,MAAI,QAAQ,6BAA6B,MAAM,EAAE;AACnD;AAEA,SAAS,wBAAwB,OAAwC;AACvE,QAAM,oBAAqB,MAAM,cAAc,KAAK,CAAC;AACrD,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,aAAa;AAAA,IAC7F;AAAA,EACF,CAAC;AAED,MAAI,CAAC,eAAe;AAElB,sBAAkB,QAAQ;AAAA,MACxB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,sDAAsD,CAAC;AAAA,IAC7F,CAAC;AACD,UAAM,cAAc,IAAI;AACxB,QAAI,KAAK,yDAAyD;AAAA,EACpE;AACF;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,kEAAkE;AAAA,EAC7E;AACF;AAEA,SAAS,sBAAsB,OAAwC;AACrE,QAAM,kBAAmB,MAAM,YAAY,KAAK,CAAC;AACjD,QAAM,gBAAgB,gBAAgB,KAAK,CAAC,MAAM;AAChD,UAAM,aAAa,EAAE,OAAO;AAC5B,WAAO,YAAY;AAAA,MACjB,QAAM,OAAO,GAAG,SAAS,MAAM,YAAa,GAAG,SAAS,EAAa,SAAS,aAAa;AAAA,IAC7F;AAAA,EACF,CAAC;AAED,MAAI,CAAC,eAAe;AAClB,oBAAgB,KAAK;AAAA,MACnB,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,2DAA2D,CAAC;AAAA,IAClG,CAAC;AACD,UAAM,YAAY,IAAI;AACtB,QAAI,KAAK,qDAAqD;AAAA,EAChE;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,GAAG,KAAK,6BAA6B;AAAA,EAChD;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,2CAA2C;AACpD,MAAI;AACF,aAAS,4CAA4C,EAAE,OAAO,QAAQ,SAAS,KAAO,CAAC;AACvF,QAAI,QAAQ,8BAA8B;AAAA,EAC5C,QAAQ;AACN,QAAI,MAAM,qDAAqD;AAC/D,QAAI,MAAM;AACV,QAAI,KAAK,mBAAmB;AAC5B,QAAI,KAAK,4CAA4C;AACrD,QAAI,MAAM;AACV,QAAI,KAAK,qEAAqE;AAC9E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,kBAAkB,OAAqC;AAC9D,MAAI;AACF,UAAM,WAAW,SAAS,mBAAmB,EAAE,OAAO,QAAQ,SAAS,KAAO,UAAU,QAAQ,CAAC;AACjG,QAAI,SAAS,SAAS,gBAAgB,GAAG;AACvC,UAAI,KAAK,iCAAiC;AAC1C,aAAO;AAAA,IACT;AACA;AAAA,MACE,0BAA0B,KAAK;AAAA,MAC/B,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,YAAoB,WAAqC;AACvF,QAAM,eAAe,cAAc,UAC/B,KAAK,YAAY,WAAW,WAAW,IACvC,KAAK,YAAY,WAAW;AAEhC,MAAI,UAAU;AACd,MAAI;AACF,cAAU,aAAa,cAAc,OAAO;AAAA,EAC9C,QAAQ;AACN,QAAI,cAAc,QAAS,QAAO;AAElC,cAAU,KAAK,YAAY,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,cAAU;AAAA,EACZ;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":[]}
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, readSettingsLocalJson, writeSettingsLocalJson } from '../../../lib/settings.js';\nimport { getMemoryPlacement } from '../../../lib/memory-placement.js';\nimport { log } from '../../../lib/output.js';\nimport { readSyncConfig } from '../utils/gist-transport.js';\nimport type { MemoryPlacement } from '../../../types/index.js';\n\ninterface InstallOpts {\n readonly dbPath?: string;\n}\n\nexport async function runInstall(opts: InstallOpts): Promise<void> {\n log.blank();\n log.step('Setting up your knowledge base');\n log.blank();\n\n // Step 0: Ensure native deps are installed globally\n await ensureNativeDeps();\n\n // Prompt for placement before any config writes\n const placement = await getMemoryPlacement(process.cwd());\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/5] Creating knowledge base...');\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const db = createDatabase({ dataDir });\n migrate(db);\n closeDatabase(db);\n log.success(`Knowledge base created at ${dataDir}/memory.db`);\n\n // Step 2: Configure Claude Code settings\n log.step('[2/5] Connecting to Claude Code...');\n await configureSettings(process.cwd(), placement);\n\n // Step 3: Register MCP server (project scope for shared, local scope for local)\n log.step('[3/5] Enabling memory tools...');\n const mcpScope = placement === \"local\" ? \"local\" : \"project\";\n const registered = registerMcpServer(mcpScope);\n if (registered) {\n log.success('Memory tools available in Claude Code');\n } else {\n log.warn('Could not enable memory tools automatically.');\n log.info(`Run: claude mcp add --scope ${mcpScope} agentic-memory -- npx claude-launchpad memory serve`);\n }\n\n // Step 4: CLAUDE.md + skills\n log.step('[4/5] Adding instructions...');\n const guidanceAdded = injectClaudeMdGuidance(process.cwd(), placement);\n if (guidanceAdded) {\n const label = placement === \"local\" ? \".claude/CLAUDE.md\" : \"CLAUDE.md\";\n log.success(`${label} updated with memory instructions`);\n }\n if (placement === \"shared\") {\n const skillsInstalled = installSkills(process.cwd());\n if (skillsInstalled > 0) {\n log.success(`Installed ${skillsInstalled} skill(s) to .claude/skills/`);\n }\n }\n\n log.blank();\n log.success('Knowledge base is ready. Claude will now remember across sessions.');\n log.info('Restart your Claude Code session to activate.');\n log.blank();\n}\n\nexport function detectExistingSetup(projectDir: string): MemoryPlacement | null {\n // Check local CLAUDE.md\n try {\n const localClaude = readFileSync(join(projectDir, '.claude', 'CLAUDE.md'), 'utf-8');\n if (localClaude.includes('## Memory') || localClaude.includes('agentic-memory')) return \"local\";\n } catch { /* not found */ }\n\n // Check root CLAUDE.md\n try {\n const rootClaude = readFileSync(join(projectDir, 'CLAUDE.md'), 'utf-8');\n if (rootClaude.includes('## Memory (agentic-memory)')) return \"shared\";\n } catch { /* not found */ }\n\n return null;\n}\n\nasync function configureSettings(projectDir: string, placement: MemoryPlacement): Promise<void> {\n const read = placement === \"local\" ? readSettingsLocalJson : readSettingsJson;\n const write = placement === \"local\" ? writeSettingsLocalJson : writeSettingsJson;\n const settings = await read(projectDir);\n\n // Disable built-in auto-memory\n settings['autoMemoryEnabled'] = false;\n log.info('Built-in auto-memory disabled (replaced by knowledge base)');\n\n // SessionStart hooks\n const hooks = (settings['hooks'] ?? {}) as Record<string, unknown[]>;\n if (readSyncConfig()) {\n addSessionStartPullHook(hooks);\n }\n addSessionStartHook(hooks);\n\n // SessionEnd push hook (only when sync is already configured)\n if (readSyncConfig()) {\n addSessionEndPushHook(hooks);\n }\n\n settings['hooks'] = hooks;\n\n // Auto-allow MCP tools\n addToolPermissions(settings);\n\n await write(projectDir, settings);\n const target = placement === \"local\" ? \"settings.local.json\" : \"settings.json\";\n log.success(`Claude Code configured in ${target}`);\n}\n\nfunction addSessionStartPullHook(hooks: Record<string, unknown[]>): void {\n const sessionStartHooks = (hooks['SessionStart'] ?? []) as Record<string, unknown>[];\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('memory pull'),\n );\n });\n\n if (!alreadyHooked) {\n // Insert at the beginning so pull runs before context injection\n sessionStartHooks.unshift({\n matcher: 'startup',\n hooks: [{ type: 'command', command: 'claude-launchpad memory pull -y 2>/dev/null; exit 0' }],\n });\n hooks['SessionStart'] = sessionStartHooks;\n log.info('Session start: memories will auto-pull from GitHub Gist');\n }\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('Session start: Claude will recall relevant context automatically');\n }\n}\n\nfunction addSessionEndPushHook(hooks: Record<string, unknown[]>): void {\n const sessionEndHooks = (hooks['SessionEnd'] ?? []) as Record<string, unknown>[];\n const alreadyHooked = sessionEndHooks.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('memory push'),\n );\n });\n\n if (!alreadyHooked) {\n sessionEndHooks.push({\n hooks: [{ type: 'command', command: 'claude-launchpad memory push -y >/dev/null 2>&1 & exit 0' }],\n });\n hooks['SessionEnd'] = sessionEndHooks;\n log.info('Session end: memories will auto-push to GitHub Gist');\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(`${added} memory tools auto-approved`);\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 required database libraries...');\n try {\n execSync('npm install -g better-sqlite3 sqlite-vec', { stdio: 'pipe', timeout: 120000 });\n log.success('Database libraries installed');\n } catch {\n log.error('Could not install database libraries 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('Requires a C++ compiler (Xcode on macOS, build-essential on Linux).');\n process.exit(1);\n }\n}\n\nfunction registerMcpServer(scope: \"project\" | \"local\"): 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('Memory tools already registered');\n return true;\n }\n execSync(\n `claude mcp add --scope ${scope} 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\n`;\n\nfunction injectClaudeMdGuidance(projectDir: string, placement: MemoryPlacement): boolean {\n const claudeMdPath = placement === \"local\"\n ? join(projectDir, '.claude', 'CLAUDE.md')\n : join(projectDir, 'CLAUDE.md');\n\n let content = '';\n try {\n content = readFileSync(claudeMdPath, 'utf-8');\n } catch {\n if (placement !== \"local\") return false;\n // Create local .claude/CLAUDE.md\n mkdirSync(join(projectDir, '.claude'), { recursive: true });\n content = '# Local Claude Config\\n';\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":[]}
@@ -17,13 +17,13 @@ import {
17
17
  } from "./chunk-NAW47BYA.js";
18
18
  import {
19
19
  initStorage
20
- } from "./chunk-5MWCQLNL.js";
20
+ } from "./chunk-SVWFSAYP.js";
21
21
  import "./chunk-24VLPHJU.js";
22
- import "./chunk-EDKY7JWY.js";
23
- import "./chunk-Z6FBT44W.js";
22
+ import "./chunk-NLZGJHE5.js";
23
+ import "./chunk-IZFQTQ4C.js";
24
24
  import {
25
25
  log
26
- } from "./chunk-RJGXPH7P.js";
26
+ } from "./chunk-S4WIADYE.js";
27
27
 
28
28
  // src/commands/memory/subcommands/pull.ts
29
29
  async function runPull(opts) {
@@ -33,7 +33,7 @@ async function runPull(opts) {
33
33
  log.error("No sync gist found. Run `memory push` first.");
34
34
  return;
35
35
  }
36
- const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
36
+ const { requireMemoryDeps } = await import("./require-deps-SUGLVBM2.js");
37
37
  await requireMemoryDeps();
38
38
  const ctx = initStorage();
39
39
  try {
@@ -108,4 +108,4 @@ function printResult(result, project) {
108
108
  export {
109
109
  runPull
110
110
  };
111
- //# sourceMappingURL=pull-YOESZ3UC.js.map
111
+ //# sourceMappingURL=pull-4QTS57DQ.js.map
@@ -18,13 +18,13 @@ import {
18
18
  } from "./chunk-NAW47BYA.js";
19
19
  import {
20
20
  initStorage
21
- } from "./chunk-5MWCQLNL.js";
21
+ } from "./chunk-SVWFSAYP.js";
22
22
  import "./chunk-24VLPHJU.js";
23
- import "./chunk-EDKY7JWY.js";
24
- import "./chunk-Z6FBT44W.js";
23
+ import "./chunk-NLZGJHE5.js";
24
+ import "./chunk-IZFQTQ4C.js";
25
25
  import {
26
26
  log
27
- } from "./chunk-RJGXPH7P.js";
27
+ } from "./chunk-S4WIADYE.js";
28
28
 
29
29
  // src/commands/memory/subcommands/push.ts
30
30
  import { hostname } from "os";
@@ -48,7 +48,7 @@ function filterRelations(allRelations, memoryIds) {
48
48
  }
49
49
  async function runPush(opts) {
50
50
  assertGhAvailable();
51
- const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
51
+ const { requireMemoryDeps } = await import("./require-deps-SUGLVBM2.js");
52
52
  await requireMemoryDeps();
53
53
  const ctx = initStorage();
54
54
  try {
@@ -148,4 +148,4 @@ async function confirmCreate() {
148
148
  export {
149
149
  runPush
150
150
  };
151
- //# sourceMappingURL=push-74XC5CUK.js.map
151
+ //# sourceMappingURL=push-JOCEW3VG.js.map
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  cwdRequire,
4
4
  requireMemoryDeps
5
- } from "./chunk-Z6FBT44W.js";
6
- import "./chunk-RJGXPH7P.js";
5
+ } from "./chunk-IZFQTQ4C.js";
6
+ import "./chunk-S4WIADYE.js";
7
7
  export {
8
8
  cwdRequire,
9
9
  requireMemoryDeps
10
10
  };
11
- //# sourceMappingURL=require-deps-NKRCPVAO.js.map
11
+ //# sourceMappingURL=require-deps-SUGLVBM2.js.map
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  initStorage
4
- } from "./chunk-5MWCQLNL.js";
4
+ } from "./chunk-SVWFSAYP.js";
5
5
  import "./chunk-24VLPHJU.js";
6
- import "./chunk-EDKY7JWY.js";
7
- import "./chunk-Z6FBT44W.js";
6
+ import "./chunk-NLZGJHE5.js";
7
+ import "./chunk-IZFQTQ4C.js";
8
8
  import {
9
9
  log
10
- } from "./chunk-RJGXPH7P.js";
10
+ } from "./chunk-S4WIADYE.js";
11
11
 
12
12
  // src/commands/memory/subcommands/stats.ts
13
13
  import { existsSync, statSync } from "fs";
@@ -18,7 +18,7 @@ function formatBytes(bytes) {
18
18
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
19
19
  }
20
20
  async function runStats(opts) {
21
- const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
21
+ const { requireMemoryDeps } = await import("./require-deps-SUGLVBM2.js");
22
22
  await requireMemoryDeps();
23
23
  const ctx = initStorage(opts.dbPath);
24
24
  try {
@@ -72,4 +72,4 @@ async function runStats(opts) {
72
72
  export {
73
73
  runStats
74
74
  };
75
- //# sourceMappingURL=stats-QUBHHPV7.js.map
75
+ //# sourceMappingURL=stats-7WFCVXBX.js.map
@@ -11,9 +11,9 @@ import {
11
11
  loadConfig,
12
12
  migrate,
13
13
  resolveDataDir
14
- } from "./chunk-EDKY7JWY.js";
15
- import "./chunk-Z6FBT44W.js";
16
- import "./chunk-RJGXPH7P.js";
14
+ } from "./chunk-NLZGJHE5.js";
15
+ import "./chunk-IZFQTQ4C.js";
16
+ import "./chunk-S4WIADYE.js";
17
17
 
18
18
  // src/commands/memory/dashboard/tui.tsx
19
19
  import { render } from "ink";
@@ -1138,4 +1138,4 @@ async function startTui(options) {
1138
1138
  export {
1139
1139
  startTui
1140
1140
  };
1141
- //# sourceMappingURL=tui-XIYOOUP6.js.map
1141
+ //# sourceMappingURL=tui-DKWRY5PT.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-launchpad",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "CLI toolkit for Claude Code — scaffold CLAUDE.md, diagnose config, enforce hooks, test with eval, add persistent memory",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,107 +0,0 @@
1
- #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
7
-
8
- // src/lib/output.ts
9
- import chalk from "chalk";
10
- var colors = {
11
- success: chalk.green,
12
- error: chalk.red,
13
- warn: chalk.yellow,
14
- info: chalk.cyan,
15
- dim: chalk.dim,
16
- bold: chalk.bold,
17
- score: (score) => {
18
- if (score >= 80) return chalk.green.bold(`${score}%`);
19
- if (score >= 60) return chalk.yellow.bold(`${score}%`);
20
- return chalk.red.bold(`${score}%`);
21
- },
22
- severity: (sev) => {
23
- const map = {
24
- critical: chalk.bgRed.white.bold,
25
- high: chalk.red.bold,
26
- medium: chalk.yellow,
27
- low: chalk.cyan,
28
- info: chalk.dim
29
- };
30
- return map[sev](` ${sev.toUpperCase()} `);
31
- }
32
- };
33
- var log = {
34
- success: (msg) => console.log(` ${chalk.green("\u2713")} ${msg}`),
35
- error: (msg) => console.log(` ${chalk.red("\u2717")} ${msg}`),
36
- warn: (msg) => console.log(` ${chalk.yellow("!")} ${msg}`),
37
- step: (msg) => console.log(` ${chalk.cyan("\u2192")} ${msg}`),
38
- info: (msg) => console.log(` ${chalk.dim("\xB7")} ${msg}`),
39
- blank: () => console.log()
40
- };
41
- function printBanner() {
42
- log.blank();
43
- console.log(chalk.cyan.bold(" Claude Launchpad"));
44
- console.log(chalk.dim(" Scaffold \xB7 Diagnose \xB7 Evaluate \xB7 Remember"));
45
- log.blank();
46
- }
47
- function printScoreCard(label, score, max = 100) {
48
- const pct = Math.round(score / max * 100);
49
- const bar = renderBar(pct, 20);
50
- console.log(` ${chalk.bold(label.padEnd(22))} ${bar} ${colors.score(pct).padStart(12)}`);
51
- }
52
- function renderBar(pct, width) {
53
- const filled = Math.round(pct / 100 * width);
54
- const empty = width - filled;
55
- const color = pct >= 80 ? chalk.green : pct >= 60 ? chalk.yellow : chalk.red;
56
- return color("\u2501".repeat(filled)) + chalk.dim("\u2500".repeat(empty));
57
- }
58
- function printIssue(severity, _analyzer, message) {
59
- const sevLabel = {
60
- critical: chalk.bgRed.white.bold(" CRIT "),
61
- high: chalk.red.bold("HIGH"),
62
- medium: chalk.yellow("MED "),
63
- low: chalk.dim("LOW "),
64
- info: chalk.dim("INFO")
65
- };
66
- console.log(` ${sevLabel[severity]} ${message}`);
67
- }
68
- function renderDoctorReport(results, options) {
69
- const overallScore = Math.round(
70
- results.reduce((sum, r) => sum + r.score, 0) / results.length
71
- );
72
- for (const result of results) {
73
- printScoreCard(result.name, result.score);
74
- }
75
- log.blank();
76
- printScoreCard("Overall", overallScore);
77
- log.blank();
78
- const allIssues = results.flatMap((r) => r.issues);
79
- const actionable = allIssues.filter((i) => i.severity !== "info");
80
- if (actionable.length === 0) {
81
- log.success("No issues found. Your configuration looks solid.");
82
- return { overallScore, actionableCount: 0 };
83
- }
84
- const sorted = [...actionable].sort((a, b) => {
85
- const order = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
86
- return (order[a.severity] ?? 4) - (order[b.severity] ?? 4);
87
- });
88
- for (const issue of sorted) {
89
- printIssue(issue.severity, issue.analyzer, issue.message);
90
- }
91
- log.blank();
92
- if (options?.afterFix) {
93
- log.info(`${actionable.length} remaining issue(s) require manual intervention.`);
94
- } else {
95
- log.info(`${actionable.length} issue(s). Run ${chalk.bold("--fix")} to auto-repair or ${chalk.bold("--fix --dry-run")} to preview.`);
96
- }
97
- return { overallScore, actionableCount: actionable.length };
98
- }
99
-
100
- export {
101
- __export,
102
- log,
103
- printBanner,
104
- printScoreCard,
105
- renderDoctorReport
106
- };
107
- //# sourceMappingURL=chunk-RJGXPH7P.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/output.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport type { Severity, AnalyzerResult } from \"../types/index.js\";\n\n// ─── Colors ───\n\nexport const colors = {\n success: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n info: chalk.cyan,\n dim: chalk.dim,\n bold: chalk.bold,\n score: (score: number): string => {\n if (score >= 80) return chalk.green.bold(`${score}%`);\n if (score >= 60) return chalk.yellow.bold(`${score}%`);\n return chalk.red.bold(`${score}%`);\n },\n severity: (sev: Severity): string => {\n const map: Record<Severity, (s: string) => string> = {\n critical: chalk.bgRed.white.bold,\n high: chalk.red.bold,\n medium: chalk.yellow,\n low: chalk.cyan,\n info: chalk.dim,\n };\n return map[sev](` ${sev.toUpperCase()} `);\n },\n} as const;\n\n// ─── Prefixed Output ───\n\nexport const log = {\n success: (msg: string): void => console.log(` ${chalk.green(\"✓\")} ${msg}`),\n error: (msg: string): void => console.log(` ${chalk.red(\"✗\")} ${msg}`),\n warn: (msg: string): void => console.log(` ${chalk.yellow(\"!\")} ${msg}`),\n step: (msg: string): void => console.log(` ${chalk.cyan(\"→\")} ${msg}`),\n info: (msg: string): void => console.log(` ${chalk.dim(\"·\")} ${msg}`),\n blank: (): void => console.log(),\n} as const;\n\n// ─── Banner ───\n\nexport function printBanner(): void {\n log.blank();\n console.log(chalk.cyan.bold(\" Claude Launchpad\"));\n console.log(chalk.dim(\" Scaffold · Diagnose · Evaluate · Remember\"));\n log.blank();\n}\n\n// ─── Score Display ───\n\nexport function printScoreCard(label: string, score: number, max: number = 100): void {\n const pct = Math.round((score / max) * 100);\n const bar = renderBar(pct, 20);\n console.log(` ${chalk.bold(label.padEnd(22))} ${bar} ${colors.score(pct).padStart(12)}`);\n}\n\nfunction renderBar(pct: number, width: number): string {\n const filled = Math.round((pct / 100) * width);\n const empty = width - filled;\n const color = pct >= 80 ? chalk.green : pct >= 60 ? chalk.yellow : chalk.red;\n return color(\"━\".repeat(filled)) + chalk.dim(\"─\".repeat(empty));\n}\n\n// ─── Issues List (replaces table) ───\n\nexport function printIssue(severity: Severity, _analyzer: string, message: string): void {\n const sevLabel: Record<Severity, string> = {\n critical: chalk.bgRed.white.bold(\" CRIT \"),\n high: chalk.red.bold(\"HIGH\"),\n medium: chalk.yellow(\"MED \"),\n low: chalk.dim(\"LOW \"),\n info: chalk.dim(\"INFO\"),\n };\n console.log(` ${sevLabel[severity]} ${message}`);\n}\n\n// ─── Report Rendering (shared by doctor + watcher) ───\n\nexport function renderDoctorReport(results: ReadonlyArray<AnalyzerResult>, options?: { afterFix?: boolean }): {\n overallScore: number;\n actionableCount: number;\n} {\n const overallScore = Math.round(\n results.reduce((sum, r) => sum + r.score, 0) / results.length,\n );\n\n for (const result of results) {\n printScoreCard(result.name, result.score);\n }\n log.blank();\n printScoreCard(\"Overall\", overallScore);\n log.blank();\n\n const allIssues = results.flatMap((r) => r.issues);\n const actionable = allIssues.filter((i) => i.severity !== \"info\");\n\n if (actionable.length === 0) {\n log.success(\"No issues found. Your configuration looks solid.\");\n return { overallScore, actionableCount: 0 };\n }\n\n const sorted = [...actionable].sort((a, b) => {\n const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };\n return (order[a.severity] ?? 4) - (order[b.severity] ?? 4);\n });\n\n for (const issue of sorted) {\n printIssue(issue.severity, issue.analyzer, issue.message);\n }\n\n log.blank();\n if (options?.afterFix) {\n log.info(`${actionable.length} remaining issue(s) require manual intervention.`);\n } else {\n log.info(`${actionable.length} issue(s). Run ${chalk.bold(\"--fix\")} to auto-repair or ${chalk.bold(\"--fix --dry-run\")} to preview.`);\n }\n return { overallScore, actionableCount: actionable.length };\n}\n"],"mappings":"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","names":[]}
@@ -1,76 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/lib/settings.ts
4
- import { readFile, writeFile, mkdir } from "fs/promises";
5
- import { join } from "path";
6
- async function readSettingsJson(root) {
7
- const path = join(root, ".claude", "settings.json");
8
- try {
9
- const content = await readFile(path, "utf-8");
10
- return JSON.parse(content);
11
- } catch {
12
- return {};
13
- }
14
- }
15
- async function writeSettingsJson(root, settings) {
16
- const dir = join(root, ".claude");
17
- await mkdir(dir, { recursive: true });
18
- await writeFile(join(dir, "settings.json"), JSON.stringify(settings, null, 2) + "\n");
19
- }
20
- async function readSettingsLocalJson(root) {
21
- const path = join(root, ".claude", "settings.local.json");
22
- try {
23
- const content = await readFile(path, "utf-8");
24
- return JSON.parse(content);
25
- } catch {
26
- return {};
27
- }
28
- }
29
- async function writeSettingsLocalJson(root, settings) {
30
- const dir = join(root, ".claude");
31
- await mkdir(dir, { recursive: true });
32
- await writeFile(join(dir, "settings.local.json"), JSON.stringify(settings, null, 2) + "\n");
33
- }
34
-
35
- // src/lib/memory-placement.ts
36
- import { select } from "@inquirer/prompts";
37
- function hasMemoryPermissions(settings) {
38
- const permissions = settings.permissions;
39
- const allow = permissions?.allow ?? [];
40
- return allow.some((p) => p.includes("agentic-memory"));
41
- }
42
- async function getMemoryPlacement(root, skipPrompt = false) {
43
- const local = await readSettingsLocalJson(root);
44
- const persisted = local.memoryPlacement;
45
- if (persisted === "shared" || persisted === "local") {
46
- return persisted;
47
- }
48
- if (hasMemoryPermissions(local)) {
49
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: "local" });
50
- return "local";
51
- }
52
- const shared = await readSettingsJson(root);
53
- if (hasMemoryPermissions(shared)) {
54
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: "shared" });
55
- return "shared";
56
- }
57
- if (skipPrompt) return "shared";
58
- const choice = await select({
59
- message: "Where should memory config go?",
60
- choices: [
61
- { value: "shared", name: "Shared (team sees it) \u2014 CLAUDE.md + settings.json" },
62
- { value: "local", name: "Local (only you) \u2014 .claude/CLAUDE.md + settings.local.json" }
63
- ]
64
- });
65
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: choice });
66
- return choice;
67
- }
68
-
69
- export {
70
- readSettingsJson,
71
- writeSettingsJson,
72
- readSettingsLocalJson,
73
- writeSettingsLocalJson,
74
- getMemoryPlacement
75
- };
76
- //# sourceMappingURL=chunk-SBA5KYQU.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/settings.ts","../src/lib/memory-placement.ts"],"sourcesContent":["import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport async function readSettingsJson(root: string): Promise<Record<string, unknown>> {\n const path = join(root, \".claude\", \"settings.json\");\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nexport async function writeSettingsJson(root: string, settings: Record<string, unknown>): Promise<void> {\n const dir = join(root, \".claude\");\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"settings.json\"), JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nexport async function readSettingsLocalJson(root: string): Promise<Record<string, unknown>> {\n const path = join(root, \".claude\", \"settings.local.json\");\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nexport async function writeSettingsLocalJson(root: string, settings: Record<string, unknown>): Promise<void> {\n const dir = join(root, \".claude\");\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"settings.local.json\"), JSON.stringify(settings, null, 2) + \"\\n\");\n}\n","import { select } from \"@inquirer/prompts\";\nimport { readSettingsJson, readSettingsLocalJson, writeSettingsLocalJson } from \"./settings.js\";\nimport type { MemoryPlacement } from \"../types/index.js\";\n\nfunction hasMemoryPermissions(settings: Record<string, unknown>): boolean {\n const permissions = settings.permissions as Record<string, unknown> | undefined;\n const allow = (permissions?.allow as string[] | undefined) ?? [];\n return allow.some((p) => p.includes(\"agentic-memory\"));\n}\n\nexport async function getMemoryPlacement(root: string, skipPrompt = false): Promise<MemoryPlacement> {\n const local = await readSettingsLocalJson(root);\n const persisted = local.memoryPlacement;\n if (persisted === \"shared\" || persisted === \"local\") {\n return persisted;\n }\n\n // Backfill: infer from where agentic-memory permissions already live\n if (hasMemoryPermissions(local)) {\n await writeSettingsLocalJson(root, { ...local, memoryPlacement: \"local\" });\n return \"local\";\n }\n const shared = await readSettingsJson(root);\n if (hasMemoryPermissions(shared)) {\n await writeSettingsLocalJson(root, { ...local, memoryPlacement: \"shared\" });\n return \"shared\";\n }\n\n if (skipPrompt) return \"shared\";\n\n const choice = await select<MemoryPlacement>({\n message: \"Where should memory config go?\",\n choices: [\n { value: \"shared\", name: \"Shared (team sees it) — CLAUDE.md + settings.json\" },\n { value: \"local\", name: \"Local (only you) — .claude/CLAUDE.md + settings.local.json\" },\n ],\n });\n\n await writeSettingsLocalJson(root, { ...local, memoryPlacement: choice });\n return choice;\n}\n"],"mappings":";;;AAAA,SAAS,UAAU,WAAW,aAAa;AAC3C,SAAS,YAAY;AAErB,eAAsB,iBAAiB,MAAgD;AACrF,QAAM,OAAO,KAAK,MAAM,WAAW,eAAe;AAClD,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,MAAM,OAAO;AAC5C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,kBAAkB,MAAc,UAAkD;AACtG,QAAM,MAAM,KAAK,MAAM,SAAS;AAChC,QAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACpC,QAAM,UAAU,KAAK,KAAK,eAAe,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AACtF;AAEA,eAAsB,sBAAsB,MAAgD;AAC1F,QAAM,OAAO,KAAK,MAAM,WAAW,qBAAqB;AACxD,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,MAAM,OAAO;AAC5C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,uBAAuB,MAAc,UAAkD;AAC3G,QAAM,MAAM,KAAK,MAAM,SAAS;AAChC,QAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACpC,QAAM,UAAU,KAAK,KAAK,qBAAqB,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AAC5F;;;ACjCA,SAAS,cAAc;AAIvB,SAAS,qBAAqB,UAA4C;AACxE,QAAM,cAAc,SAAS;AAC7B,QAAM,QAAS,aAAa,SAAkC,CAAC;AAC/D,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,gBAAgB,CAAC;AACvD;AAEA,eAAsB,mBAAmB,MAAc,aAAa,OAAiC;AACnG,QAAM,QAAQ,MAAM,sBAAsB,IAAI;AAC9C,QAAM,YAAY,MAAM;AACxB,MAAI,cAAc,YAAY,cAAc,SAAS;AACnD,WAAO;AAAA,EACT;AAGA,MAAI,qBAAqB,KAAK,GAAG;AAC/B,UAAM,uBAAuB,MAAM,EAAE,GAAG,OAAO,iBAAiB,QAAQ,CAAC;AACzE,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,iBAAiB,IAAI;AAC1C,MAAI,qBAAqB,MAAM,GAAG;AAChC,UAAM,uBAAuB,MAAM,EAAE,GAAG,OAAO,iBAAiB,SAAS,CAAC;AAC1E,WAAO;AAAA,EACT;AAEA,MAAI,WAAY,QAAO;AAEvB,QAAM,SAAS,MAAM,OAAwB;AAAA,IAC3C,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,UAAU,MAAM,yDAAoD;AAAA,MAC7E,EAAE,OAAO,SAAS,MAAM,kEAA6D;AAAA,IACvF;AAAA,EACF,CAAC;AAED,QAAM,uBAAuB,MAAM,EAAE,GAAG,OAAO,iBAAiB,OAAO,CAAC;AACxE,SAAO;AACT;","names":[]}