UNPKG

@stackmemoryai/stackmemory

Version:

Lossless, project-scoped memory for AI coding tools. Durable context across sessions with 56 MCP tools, FTS5 search, conductor orchestrator, loop/watch monitoring, snapshot capture, pre-flight overlap checks, Claude/Codex/OpenCode wrappers, Linear sync, a

92 lines (91 loc) 2.38 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { execFileSync } from "child_process"; function getCurrentBranch(cwd) { try { return execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: cwd || process.cwd(), encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim(); } catch { return "unknown"; } } function detectBaseBranch(cwd) { const dir = cwd || process.cwd(); for (const base of ["main", "master", "develop"]) { try { execFileSync("git", ["rev-parse", "--verify", base], { cwd: dir, encoding: "utf-8", stdio: "pipe" }); return base; } catch { continue; } } return "main"; } function getDiffStats(baseBranch, cwd) { try { const output = execFileSync( "git", ["diff", "--name-status", `${baseBranch}...HEAD`], { cwd: cwd || process.cwd(), encoding: "utf-8", timeout: 1e4 } ); const changed = []; const created = []; const deleted = []; for (const line of output.split("\n").filter((l) => l.trim())) { const [status, ...pathParts] = line.split(" "); const filePath = pathParts.join(" "); if (!filePath) continue; switch (status.charAt(0)) { case "A": created.push(filePath); break; case "D": deleted.push(filePath); break; case "M": case "R": case "C": changed.push(filePath); break; } } return { changed, created, deleted }; } catch { return { changed: [], created: [], deleted: [] }; } } function getCommitsSince(baseBranch, cwd) { try { const output = execFileSync( "git", [ "log", `${baseBranch}..HEAD`, "--pretty=format:%H%x00%s%x00%an%x00%aI", "--no-merges" ], { cwd: cwd || process.cwd(), encoding: "utf-8", timeout: 1e4 } ); return output.split("\n").filter((l) => l.trim()).map((line) => { const [hash, message, author, date] = line.split("\0"); return { hash, message, author, date }; }); } catch { return []; } } export { detectBaseBranch, getCommitsSince, getCurrentBranch, getDiffStats };