@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
JavaScript
#!/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