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.
Files changed (2) hide show
  1. package/dist/cli.js +36 -0
  2. 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.2",
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": {