@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
135 lines (134 loc) • 4.16 kB
JavaScript
import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { Command } from "commander";
import { existsSync, readFileSync } from "fs";
import { join } from "path";
import { homedir } from "os";
let countTokens;
try {
const tokenizer = await import("@anthropic-ai/tokenizer");
countTokens = tokenizer.countTokens;
} catch {
countTokens = (text) => Math.ceil(text.length / 3.5);
}
function readFileSafe(filePath) {
try {
if (existsSync(filePath)) {
return readFileSync(filePath, "utf-8");
}
} catch {
}
return null;
}
function createAuditCommand() {
const audit = new Command("audit").description(
"Measure context overhead (tokens injected before first message)"
).option("--json", "Output as JSON", false).action(async (options) => {
const projectRoot = process.cwd();
const home = homedir();
const entries = [];
const globalClaudeMd = readFileSafe(join(home, ".claude", "CLAUDE.md"));
if (globalClaudeMd) {
entries.push({
source: "~/.claude/CLAUDE.md",
tokens: countTokens(globalClaudeMd),
percent: 0
});
}
const projectClaudeMd = readFileSafe(join(projectRoot, "CLAUDE.md"));
if (projectClaudeMd) {
entries.push({
source: "./CLAUDE.md",
tokens: countTokens(projectClaudeMd),
percent: 0
});
}
const projectSlug = projectRoot.replace(/\//g, "-");
const memoryPath = join(
home,
".claude",
"projects",
projectSlug,
"memory",
"MEMORY.md"
);
const memoryMd = readFileSafe(memoryPath);
if (memoryMd) {
entries.push({
source: "auto-memory/MEMORY.md",
tokens: countTokens(memoryMd),
percent: 0
});
}
const handoffPath = join(projectRoot, ".stackmemory", "handoff.md");
const handoffMd = readFileSafe(handoffPath);
if (handoffMd) {
entries.push({
source: ".stackmemory/handoff.md",
tokens: countTokens(handoffMd),
percent: 0
});
}
try {
const { MCPToolDefinitions } = await import("../../integrations/mcp/tool-definitions.js");
const defs = new MCPToolDefinitions();
const allTools = defs.getAllToolDefinitions();
const schemasJson = JSON.stringify(allTools);
entries.push({
source: "MCP tool schemas",
tokens: countTokens(schemasJson),
percent: 0
});
} catch {
}
try {
const dbPath = join(projectRoot, ".stackmemory", "context.db");
if (existsSync(dbPath)) {
const { default: Database } = await import("better-sqlite3");
const { FrameManager } = await import("../../core/context/index.js");
const db = new Database(dbPath);
const fm = new FrameManager(db, "cli-project");
const hotStack = fm.getHotStackContext();
if (hotStack) {
entries.push({
source: "Active frames (hot stack)",
tokens: countTokens(hotStack),
percent: 0
});
}
db.close();
}
} catch {
}
const totalTokens = entries.reduce((sum, e) => sum + e.tokens, 0);
for (const entry of entries) {
entry.percent = totalTokens > 0 ? Math.round(entry.tokens / totalTokens * 1e3) / 10 : 0;
}
if (options.json) {
console.log(JSON.stringify({ entries, totalTokens }, null, 2));
return;
}
console.log("\nContext Overhead Audit");
console.log("\u2500".repeat(60));
console.log(
`${"Source".padEnd(32)} ${"Tokens".padStart(8)} ${"%".padStart(7)}`
);
console.log("\u2500".repeat(60));
for (const entry of entries) {
console.log(
`${entry.source.padEnd(32)} ${String(entry.tokens).padStart(8)} ${(entry.percent + "%").padStart(7)}`
);
}
console.log("\u2500".repeat(60));
console.log(
`${"TOTAL".padEnd(32)} ${String(totalTokens).padStart(8)} ${"100%".padStart(7)}`
);
console.log("");
});
return audit;
}
export {
createAuditCommand
};