enigma-cli 1.15.5 → 1.15.7

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/README.md CHANGED
@@ -71,6 +71,9 @@ enigma <tool> [acct] Launch claude | codex | opencode with an account
71
71
  enigma account ... Manage per-tool accounts (list/add/use/login/remove)
72
72
  enigma profile ... Group one account per tool (list/add/use/set/unset/remove)
73
73
  enigma skills ... List skills and manage discards (list/discard/restore)
74
+ enigma compress [file] Compress JSON/logs/text to fewer tokens (reversible via CCR);
75
+ --retrieve <hash> restores, --stats shows total savings
76
+ enigma mcp Run the context-compression MCP server over stdio
74
77
  enigma seal Maintenance: (re)compute skill content hashes
75
78
  enigma check Integrity gate: verify skills are well-formed and sealed
76
79
  enigma help | version
@@ -435,6 +438,48 @@ and applies nothing; correctness and security stay with the normal review.
435
438
  Side-by-side "with vs without enigma" comparisons live in
436
439
  [`docs/examples/`](../../docs/examples/README.md).
437
440
 
441
+ ## Context compression (opt-in)
442
+
443
+ A native, dependency-free engine that shrinks large content before it reaches the
444
+ model - same information, far fewer tokens. It detects the content type and routes
445
+ it:
446
+
447
+ - **JSON** arrays of records are compressed statistically: a representative,
448
+ schema-preserving sample is kept (head + stride samples + tail), and **error
449
+ rows, numeric anomalies and structural outliers are always preserved** - unique
450
+ entities with no signal are left intact so real data is never silently dropped.
451
+ - **Logs** collapse by template (volatile timestamps/numbers/hashes are masked;
452
+ runs of similar lines fold into one + a count), keeping error/warning lines.
453
+ - **Plain text** is truncated head+tail. Code, diffs and markdown pass through
454
+ untouched (no safe lossy transform without a parser).
455
+
456
+ Compression is **reversible** (CCR - Compress-Cache-Retrieve): when rows or spans
457
+ are dropped, the full original is cached under `~/.enigma/ccr` and the output
458
+ carries a `<<enigma:ccr:HASH ...>>` marker. Pass the hash back to get the original.
459
+
460
+ ```bash
461
+ cat tool-output.json | enigma compress # compressed to stdout, savings to stderr
462
+ enigma compress big.log # compress a file
463
+ enigma compress --retrieve <hash> # restore a cached original
464
+ enigma compress --stats # cumulative token savings
465
+ ```
466
+
467
+ ### As an MCP server
468
+
469
+ `enigma mcp` runs a stdio MCP server exposing three tools - `enigma_compress`,
470
+ `enigma_retrieve`, `enigma_stats` - so an agent can compress large tool outputs
471
+ itself and retrieve originals on demand. Enable deployment and it is registered in
472
+ each managed agent's own config (Claude Code `mcpServers`, Codex
473
+ `[mcp_servers.enigma]`, opencode `mcp`), preserving your other servers:
474
+
475
+ ```bash
476
+ enigma config compress on # register the MCP server on install/sync
477
+ enigma config compress off # remove it again
478
+ ```
479
+
480
+ **Off by default** - adding an MCP server to your agents is an explicit choice.
481
+ Everything runs locally; no data leaves your machine.
482
+
438
483
  ## License
439
484
 
440
485
  [Apache-2.0](LICENSE).
@@ -0,0 +1,165 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>enigma - context savings</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0b0e14; --surface: #151a23; --surface2: #1b2230; --border: #232a36;
10
+ --text: #e6e6e6; --muted: #8a93a3; --accent: #e0a458; --accent2: #d7875f; --good: #6fcf97;
11
+ }
12
+ * { box-sizing: border-box; }
13
+ body {
14
+ margin: 0; background: var(--bg); color: var(--text);
15
+ font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
16
+ -webkit-font-smoothing: antialiased; padding: 24px; max-width: 1000px; margin: 0 auto;
17
+ }
18
+ a { color: var(--accent2); }
19
+ header { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; }
20
+ .wordmark { font-size: 20px; font-weight: 700; letter-spacing: 0.5px; }
21
+ .wordmark span { color: var(--accent); }
22
+ .sub { color: var(--muted); font-size: 13px; }
23
+ .live { margin-left: auto; display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; }
24
+ .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); }
25
+ .dot.stale { background: var(--muted); box-shadow: none; }
26
+ .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
27
+ .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 16px; }
28
+ .card .label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.6px; }
29
+ .card .value { font-size: 28px; font-weight: 700; margin-top: 6px; }
30
+ .card .value.accent { color: var(--accent); }
31
+ .card .value.good { color: var(--good); }
32
+ .card .foot { color: var(--muted); font-size: 12px; margin-top: 4px; }
33
+ .panel { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 18px; margin-bottom: 20px; }
34
+ .panel h2 { font-size: 14px; font-weight: 600; margin: 0 0 14px; color: var(--text); }
35
+ .panel h2 small { color: var(--muted); font-weight: 400; margin-left: 8px; }
36
+ .chart { width: 100%; height: 200px; display: block; }
37
+ .bar-row { display: flex; align-items: center; gap: 12px; margin: 10px 0; font-size: 13px; }
38
+ .bar-row .name { width: 70px; color: var(--muted); }
39
+ .bar-track { flex: 1; height: 14px; background: var(--surface2); border-radius: 7px; overflow: hidden; }
40
+ .bar-fill { height: 100%; border-radius: 7px; }
41
+ .bar-row .num { width: 90px; text-align: right; font-variant-numeric: tabular-nums; }
42
+ .empty { color: var(--muted); font-size: 14px; text-align: center; padding: 40px 0; }
43
+ footer { color: var(--muted); font-size: 12px; line-height: 1.6; margin-top: 8px; }
44
+ code { background: var(--surface2); padding: 1px 6px; border-radius: 5px; color: var(--accent2); }
45
+ @media (max-width: 720px) { .grid { grid-template-columns: repeat(2, 1fr); } }
46
+ </style>
47
+ </head>
48
+ <body>
49
+ <header>
50
+ <div>
51
+ <div class="wordmark">enigma<span>.</span></div>
52
+ <div class="sub">context compression savings</div>
53
+ </div>
54
+ <div class="live"><span id="dot" class="dot stale"></span><span id="updated">connecting...</span></div>
55
+ </header>
56
+
57
+ <div class="grid">
58
+ <div class="card"><div class="label">Tokens saved</div><div id="saved" class="value good">-</div><div id="savedFoot" class="foot">across all compressions</div></div>
59
+ <div class="card"><div class="label">Savings rate</div><div id="rate" class="value accent">-</div><div class="foot">of input tokens removed</div></div>
60
+ <div class="card"><div class="label">Compressions</div><div id="calls" class="value">-</div><div class="foot">reversible via CCR</div></div>
61
+ <div class="card"><div class="label">In &rarr; Out</div><div id="inout" class="value" style="font-size:20px">-</div><div class="foot">total tokens</div></div>
62
+ </div>
63
+
64
+ <div class="panel">
65
+ <h2>Tokens saved per day <small id="rangeLabel"></small></h2>
66
+ <svg id="chart" class="chart" viewBox="0 0 600 200" preserveAspectRatio="none" role="img" aria-label="Daily tokens saved"></svg>
67
+ <div id="chartEmpty" class="empty" style="display:none">No compression activity recorded yet. Run <code>enigma compress &lt;file&gt;</code> or enable the compression MCP (<code>enigma config compress on</code>).</div>
68
+ </div>
69
+
70
+ <div class="panel">
71
+ <h2>Before vs after <small>cumulative tokens</small></h2>
72
+ <div class="bar-row"><span class="name">Before</span><div class="bar-track"><div id="barBefore" class="bar-fill" style="background:var(--accent2)"></div></div><span id="numBefore" class="num">-</span></div>
73
+ <div class="bar-row"><span class="name">After</span><div class="bar-track"><div id="barAfter" class="bar-fill" style="background:var(--good)"></div></div><span id="numAfter" class="num">-</span></div>
74
+ </div>
75
+
76
+ <footer>
77
+ Polling pauses automatically when this tab is hidden, and the server caches each snapshot - so an open dashboard costs almost nothing.
78
+ Data source: <code>~/.enigma/ccr/stats.json</code> + <code>history.jsonl</code>. enigma <span id="ver"></span>
79
+ </footer>
80
+
81
+ <script>
82
+ const POLL_MS = 5000;
83
+ const $ = (id) => document.getElementById(id);
84
+
85
+ function fmt(n) {
86
+ n = Number(n) || 0;
87
+ if (n >= 1e9) return (n / 1e9).toFixed(2) + "B";
88
+ if (n >= 1e6) return (n / 1e6).toFixed(2) + "M";
89
+ if (n >= 1e3) return (n / 1e3).toFixed(1) + "k";
90
+ return String(Math.round(n));
91
+ }
92
+
93
+ // Bucket history points into the last 30 calendar days of saved tokens.
94
+ function dailySaved(history) {
95
+ const DAY = 86400000;
96
+ const today = Math.floor(Date.now() / DAY);
97
+ const start = today - 29;
98
+ const buckets = new Array(30).fill(0);
99
+ for (const p of history || []) {
100
+ const day = Math.floor(p.t / DAY);
101
+ if (day < start || day > today) continue;
102
+ buckets[day - start] += Math.max(0, (p.b || 0) - (p.a || 0));
103
+ }
104
+ return buckets;
105
+ }
106
+
107
+ function renderChart(buckets) {
108
+ const svg = $("chart"), W = 600, H = 200, pad = 6;
109
+ const max = Math.max(1, ...buckets);
110
+ const n = buckets.length;
111
+ const x = (i) => pad + (i * (W - pad * 2)) / (n - 1);
112
+ const y = (v) => H - pad - (v / max) * (H - pad * 2);
113
+ const pts = buckets.map((v, i) => x(i) + "," + y(v));
114
+ const line = "M" + pts.join(" L");
115
+ const area = line + " L" + x(n - 1) + "," + (H - pad) + " L" + x(0) + "," + (H - pad) + " Z";
116
+ const hasData = buckets.some((v) => v > 0);
117
+ $("chartEmpty").style.display = hasData ? "none" : "block";
118
+ svg.style.display = hasData ? "block" : "none";
119
+ svg.innerHTML =
120
+ '<defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1">' +
121
+ '<stop offset="0%" stop-color="#e0a458" stop-opacity="0.35"/>' +
122
+ '<stop offset="100%" stop-color="#e0a458" stop-opacity="0"/></linearGradient></defs>' +
123
+ '<path d="' + area + '" fill="url(#g)"/>' +
124
+ '<path d="' + line + '" fill="none" stroke="#e0a458" stroke-width="2" vector-effect="non-scaling-stroke"/>';
125
+ }
126
+
127
+ function render(data) {
128
+ const s = data.stats || {};
129
+ const before = s.tokensBefore || 0, after = s.tokensAfter || 0, saved = s.tokensSaved || 0;
130
+ const rate = before ? Math.round((saved / before) * 100) : 0;
131
+ $("saved").textContent = fmt(saved);
132
+ $("savedFoot").textContent = saved ? "~" + saved.toLocaleString() + " tokens" : "across all compressions";
133
+ $("rate").textContent = rate + "%";
134
+ $("calls").textContent = fmt(s.calls || 0);
135
+ $("inout").textContent = fmt(before) + " → " + fmt(after);
136
+ $("numBefore").textContent = fmt(before);
137
+ $("numAfter").textContent = fmt(after);
138
+ const max = Math.max(1, before);
139
+ $("barBefore").style.width = (before / max * 100) + "%";
140
+ $("barAfter").style.width = (after / max * 100) + "%";
141
+ renderChart(dailySaved(data.history));
142
+ $("rangeLabel").textContent = "last 30 days";
143
+ $("ver").textContent = data.version ? "v" + data.version : "";
144
+ $("dot").classList.remove("stale");
145
+ $("updated").textContent = "updated " + new Date(data.generatedAt || Date.now()).toLocaleTimeString();
146
+ }
147
+
148
+ async function poll() {
149
+ // Headroom pattern: never hit the server while the tab is hidden.
150
+ if (document.hidden) return;
151
+ try {
152
+ const res = await fetch("/api/stats", { cache: "no-store" });
153
+ render(await res.json());
154
+ } catch {
155
+ $("dot").classList.add("stale");
156
+ $("updated").textContent = "disconnected";
157
+ }
158
+ }
159
+
160
+ poll();
161
+ setInterval(poll, POLL_MS);
162
+ document.addEventListener("visibilitychange", () => { if (!document.hidden) poll(); });
163
+ </script>
164
+ </body>
165
+ </html>
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Minimal-code discipline - YAGNI ladder, deletion over addition, no unrequested abstractions, and the enigma: shortcut-marking convention; intensity via the minimal-code setting.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "297c5d9a0573a319a6f8476f5b1da8cb93e6f3297f13b76ac25d91ce10c7b523"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "On-demand over-engineering review - diff review, whole-repo audit, and enigma: debt-marker ledger (tags delete/stdlib/native/yagni/shrink, line/dep scoring); lists cuts, applies nothing.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "f742a2be3f328b9ea1ff9a35a449177c2cbec35ad16e46f7054b7a873a2ab017"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.1.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Backend/API architecture: controller-service-repository layering, API and request optimization, server-side caching (Redis), and Zod boundary validation.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "a46c3cd00aa5f47adb1e7907f1d2bc6f5562f7a272890dee9b1121976ac04ae1"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.1.1",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Ciphera code style conventions (formatting, naming, imports, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "74f638aec13e8c93257fe1ad604c28b07e9a7c456796a4ceefcc99217d9e7039"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Pre-delivery self-review gate, prioritized review dimensions, and change-quality criteria.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "3d3bbe0602d5bbb4afe37648fe3c2fa39376b1bcbac5d8c441f01fad1e866ed0"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.9.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Core engineering execution policy and harness orchestration (highest-authority rules).",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "82d246faa4770248a36f143926fbf06bd3ffc082959014184548b57193770fab"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.1.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Senior database architecture policy: query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "2883bcecb3202683ae6f81b073c3d6a9cec9c55029e011bdd06ba7ac3537297e"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Reproduce-isolate-fix debugging methodology with root-cause discipline and regression verification.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "14b0064c8b33a0dc85e51464b05005cf5801c756b1101789a6924b9548420f6b"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Dependency and supply-chain security: lockfiles and reproducible installs, version pinning, vulnerability auditing, vetting/minimizing packages, vendoring, and SBOM/provenance.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "6375d835c2aef2c9bd31ce116444dc3d796f510f9970a213aa3ac4696d7e21b9"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "431645565aec8a4ab4cd17247139f78c377a9bcfcfc4ee1d6f252199c332d86f"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.3.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Frontend architecture: reusable components, abstraction thresholds, state management, no-op save detection, large-list rendering (infinite scroll/pagination, virtualization, skeletons, progressive loading), and optimistic UI with rollback.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "26962db5a8b607e95098a6d88977aee59a10bd14e03afe97245f2b013fd21a9a"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.3.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Git & contribution policy (senior engineering standards).",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "73a978ef11f4def067f9252fc3e2e6aa737a08b6d58ad8a2a45cbcd4b02813f6"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Application and AI-agent security: secrets, authn/authz (least privilege), OWASP Top 10, transport/crypto baseline, secure logging, and agent/MCP/tool-use safety.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "9971e9d9127397d0152e89d24aad3191e2935e55a8483db7fd15f5d4d7a60e7a"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Create new skills, modify and improve existing skills, and measure skill performance with evals and benchmarks.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "699586cce82ec0a5458288b598ee7e5ebdddb3dfcf19db354d8bc5e85e47c1c7"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.1.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Exhaustive completion discipline for long/multi-item tasks - inventory, coverage ledger, verified done.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "6e3facba307eb2b55cefbab2e4b2a346a2b82f93c3ef47e11ebeb78c3c9453a8"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.2.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Test strategy, coverage gates, deterministic tests, mocking discipline, regression-first bug fixing, and test-suite organization (layout by type/domain, mirrored paths, file naming, fixture/helper placement).",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "3bdf591057b760f674fb2b1425f63acb426cda2c4f042e1a74c5a5d3807df664"
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "version": "1.0.0",
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Strict frontend + backend schema validation, schema consistency, and safe client-facing error handling.",
6
- "cliVersion": "1.15.5",
6
+ "cliVersion": "1.15.7",
7
7
  "sha": "a33622a2f810ee4cea39824cb1a7ca34b355a917d4224025df50d77dd74f0b3a"
8
8
  }
@@ -1,6 +1,6 @@
1
1
  {
2
- "enigma-darwin-arm64": "323f7a1f3e3321f37e834e5c844765844e7fc60c33c4959e5edf46896bc63a43",
3
- "enigma-linux-arm64": "124d4612ef8a5fb348dd66445e31dbf4cb6dda37046457a8f675f47cc50a0c02",
4
- "enigma-linux-x64": "c18bb1e324fb2aa8c4fa93fcac7c0c831838f186a59fee8012013b3b87ea6b91",
5
- "enigma-win32-x64.exe": "bbad15e4b9a5ad37c397b88e646f9f035ffc1063d566347dc975cafc915d8029"
2
+ "enigma-darwin-arm64": "b0c79cf7d490f7d5ce651c738b44d4e7f9a5bf0f515fbc75f120d734bba0cd73",
3
+ "enigma-linux-arm64": "b5e245fde0803cc32ab644f41a656bdd224ca1d24c82f61fcf35da470407d578",
4
+ "enigma-linux-x64": "a8dd7cd2f1cecc0751b346031685f82c88b6fa4dcf487091191cbf07996a380e",
5
+ "enigma-win32-x64.exe": "5bff478ef5e232d5b1491bb798b24e796307b8d5f9ef3b3e70811aac954609dc"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigma-cli",
3
- "version": "1.15.5",
3
+ "version": "1.15.7",
4
4
  "description": "Everything you need to work with a coding agent: install shared policy skills for Claude Code, OpenAI Codex and opencode, and set up portable git security hooks.",
5
5
  "type": "module",
6
6
  "bin": {