UNPKG

@stackmemoryai/stackmemory

Version:

Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.

184 lines (183 loc) 6.66 kB
#!/usr/bin/env tsx import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync } from "fs"; import { join } from "path"; import { execSync } from "child_process"; import chalk from "chalk"; const enableDiffMem = process.argv.includes("--with-diffmem"); function getEnv(key, defaultValue) { const value = process.env[key]; if (value === void 0) { if (defaultValue !== void 0) return defaultValue; throw new Error(`Environment variable ${key} is required`); } return value; } function getOptionalEnv(key) { return process.env[key]; } const projectRoot = process.cwd(); console.log(chalk.blue.bold("\n\u{1F680} Initializing StackMemory...\n")); const stackDir = join(projectRoot, ".stackmemory"); if (!existsSync(stackDir)) { mkdirSync(stackDir, { recursive: true }); console.log(chalk.green("\u2713") + " Created .stackmemory directory"); } else { console.log(chalk.yellow("\u26A0") + " .stackmemory directory already exists"); } const gitignorePath = join(projectRoot, ".gitignore"); const gitignoreEntry = "\n# StackMemory\n.stackmemory/*.db\n.stackmemory/*.db-*\n"; if (existsSync(gitignorePath)) { const gitignore = readFileSync(gitignorePath, "utf-8"); if (!gitignore.includes(".stackmemory")) { appendFileSync(gitignorePath, gitignoreEntry); console.log(chalk.green("\u2713") + " Added .stackmemory to .gitignore"); } } else { writeFileSync(gitignorePath, gitignoreEntry); console.log(chalk.green("\u2713") + " Created .gitignore with .stackmemory"); } const configPath = join(stackDir, "config.json"); if (!existsSync(configPath)) { const config = { projectId: projectRoot.split("/").pop(), userId: process.env["USER"] || "default", teamId: "local", initialized: (/* @__PURE__ */ new Date()).toISOString() }; writeFileSync(configPath, JSON.stringify(config, null, 2)); console.log(chalk.green("\u2713") + " Created config file"); } const jsonlPath = join(stackDir, "frames.jsonl"); if (!existsSync(jsonlPath)) { const initialFrame = { id: "init_" + Date.now(), type: "system", content: "StackMemory initialized", timestamp: Date.now() }; writeFileSync(jsonlPath, JSON.stringify(initialFrame) + "\n"); console.log(chalk.green("\u2713") + " Created frames.jsonl"); } const isMacOS = process.platform === "darwin"; const mcpConfigPath = isMacOS ? join( process.env["HOME"] || "~", "Library", "Application Support", "Claude", "claude_desktop_config.json" ) : join( process.env["HOME"] || "~", ".config", "claude", "claude_desktop_config.json" ); console.log(chalk.blue("\n\u{1F4DD} MCP Configuration for Claude Code:\n")); const mcpConfig = { mcpServers: { stackmemory: { command: "node", args: [join(projectRoot, "dist", "integrations", "mcp", "server.js")], env: { PROJECT_ROOT: projectRoot } } } }; console.log(chalk.gray("Add this to your Claude Code MCP configuration:")); console.log(chalk.gray("(" + mcpConfigPath + ")\n")); console.log(chalk.cyan(JSON.stringify(mcpConfig, null, 2))); console.log(chalk.blue("\n\u{1F4E6} Building TypeScript files...\n")); try { execSync("npm run build", { stdio: "inherit", cwd: projectRoot }); console.log(chalk.green("\u2713") + " Build completed"); } catch { console.log(chalk.yellow("\u26A0") + " Build failed - run npm run build manually"); } if (enableDiffMem) { console.log(chalk.blue("\n\u{1F9E0} Setting up DiffMem integration...\n")); const diffmemDir = join(stackDir, "diffmem"); const diffmemStorageDir = join(diffmemDir, "storage"); const diffmemWorktreesDir = join(diffmemDir, "worktrees"); mkdirSync(diffmemStorageDir, { recursive: true }); mkdirSync(diffmemWorktreesDir, { recursive: true }); if (!existsSync(join(diffmemStorageDir, ".git"))) { try { execSync("git init", { cwd: diffmemStorageDir, stdio: "pipe" }); execSync('git commit --allow-empty -m "Initialize DiffMem storage"', { cwd: diffmemStorageDir, stdio: "pipe" }); console.log(chalk.green("\u2713") + " Initialized DiffMem storage repository"); } catch { console.log( chalk.yellow("\u26A0") + " Failed to initialize git repo for DiffMem" ); } } const diffmemConfigPath = join(diffmemDir, "config.json"); const diffmemConfig = { enabled: true, endpoint: "http://localhost:8000", userId: process.env["USER"] || "default", storagePath: diffmemStorageDir, worktreePath: diffmemWorktreesDir }; writeFileSync(diffmemConfigPath, JSON.stringify(diffmemConfig, null, 2)); console.log(chalk.green("\u2713") + " Created DiffMem configuration"); const envPath = join(projectRoot, ".env"); const diffmemEnvVars = ` # DiffMem Configuration (Long-term User Memory) DIFFMEM_ENABLED=true DIFFMEM_ENDPOINT=http://localhost:8000 DIFFMEM_USER_ID=${process.env["USER"] || "default"} DIFFMEM_STORAGE_PATH=${diffmemStorageDir} DIFFMEM_WORKTREE_PATH=${diffmemWorktreesDir} `; if (existsSync(envPath)) { const envContent = readFileSync(envPath, "utf-8"); if (!envContent.includes("DIFFMEM_")) { appendFileSync(envPath, diffmemEnvVars); console.log(chalk.green("\u2713") + " Added DiffMem configuration to .env"); } } else { writeFileSync(envPath, diffmemEnvVars.trim() + "\n"); console.log(chalk.green("\u2713") + " Created .env with DiffMem configuration"); } console.log(chalk.green("\u2713") + " DiffMem integration configured"); console.log( chalk.gray( " Note: DiffMem server must be running for user memory features" ) ); } console.log(chalk.green.bold("\n\u2705 StackMemory initialized successfully!\n")); console.log(chalk.gray("Next steps:")); console.log(chalk.gray("1. Add the MCP configuration above to Claude Code")); console.log(chalk.gray("2. Restart Claude Code")); console.log(chalk.gray("3. Start using context tracking!")); if (enableDiffMem) { console.log(chalk.gray("4. Start DiffMem server: npm run diffmem:start")); } console.log(chalk.gray("\nUseful commands:")); console.log( chalk.cyan(" npm run mcp:dev") + " - Start MCP server in dev mode" ); console.log(chalk.cyan(" npm run status") + " - Check StackMemory status"); console.log(chalk.cyan(" npm run analyze") + " - Analyze context usage"); if (enableDiffMem) { console.log( chalk.cyan(" npm run diffmem:start") + " - Start DiffMem server" ); } console.log(); //# sourceMappingURL=initialize.js.map