engramx 0.4.2 → 0.4.3
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.
- package/dist/cli.js +36 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1773,6 +1773,42 @@ program.command("dashboard").alias("hud").description("Live terminal dashboard s
|
|
|
1773
1773
|
await new Promise(() => {
|
|
1774
1774
|
});
|
|
1775
1775
|
});
|
|
1776
|
+
program.command("hud-label").description("Output JSON label for Claude HUD --extra-cmd (fast, <20ms)").argument("[path]", "Project directory", ".").action(async (projectPath) => {
|
|
1777
|
+
const resolvedPath = pathResolve(projectPath);
|
|
1778
|
+
const logPath = join8(resolvedPath, ".engram", "hook-log.jsonl");
|
|
1779
|
+
if (!existsSync8(join8(resolvedPath, ".engram", "graph.db"))) {
|
|
1780
|
+
console.log('{"label":""}');
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
if (!existsSync8(logPath)) {
|
|
1784
|
+
console.log('{"label":"\u26A1engram \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 ready"}');
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
try {
|
|
1788
|
+
const entries = readHookLog(resolvedPath);
|
|
1789
|
+
const summary = summarizeHookLog(entries);
|
|
1790
|
+
if (summary.totalInvocations === 0) {
|
|
1791
|
+
console.log('{"label":"\u26A1engram \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 listening..."}');
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
const totalPreTool = (summary.byDecision["deny"] ?? 0) + (summary.byDecision["allow"] ?? 0) + (summary.byDecision["passthrough"] ?? 0);
|
|
1795
|
+
const denied = summary.readDenyCount;
|
|
1796
|
+
const hitRate = totalPreTool > 0 ? Math.round(denied / totalPreTool * 100) : 0;
|
|
1797
|
+
const tokens = summary.estimatedTokensSaved;
|
|
1798
|
+
let formatted;
|
|
1799
|
+
if (tokens >= 1e6) formatted = (tokens / 1e6).toFixed(1) + "M";
|
|
1800
|
+
else if (tokens >= 1e3) formatted = (tokens / 1e3).toFixed(1) + "K";
|
|
1801
|
+
else formatted = String(tokens);
|
|
1802
|
+
const barWidth = 10;
|
|
1803
|
+
let filled = Math.round(hitRate / 100 * barWidth);
|
|
1804
|
+
if (filled > barWidth) filled = barWidth;
|
|
1805
|
+
if (denied > 0 && filled === 0) filled = 1;
|
|
1806
|
+
const bar2 = "\u25B0".repeat(filled) + "\u25B1".repeat(barWidth - filled);
|
|
1807
|
+
console.log(JSON.stringify({ label: `\u26A1engram ${formatted} saved ${bar2} ${hitRate}%` }));
|
|
1808
|
+
} catch {
|
|
1809
|
+
console.log('{"label":"\u26A1engram"}');
|
|
1810
|
+
}
|
|
1811
|
+
});
|
|
1776
1812
|
program.command("query").description("Query the knowledge graph").argument("<question>", "Natural language question or keywords").option("--dfs", "Use DFS traversal", false).option("-d, --depth <n>", "Traversal depth", "3").option("-b, --budget <n>", "Token budget", "2000").option("-p, --project <path>", "Project directory", ".").action(async (question, opts) => {
|
|
1777
1813
|
const result = await query(opts.project, question, {
|
|
1778
1814
|
mode: opts.dfs ? "dfs" : "bfs",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "engramx",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "The structural code graph your AI agent can't forget to use. A Claude Code hook layer that intercepts Read/Edit/Write/Bash and replaces file contents with ~300-token structural graph summaries. 82% measured token reduction. Context rot is empirically solved — cite Chroma. Local SQLite, zero LLM cost, zero cloud, zero native deps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|