enigma-cli 1.35.2 → 1.35.4
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 +44 -2
- package/assets/skills/anti-overengineering-policy/skill.json +1 -1
- package/assets/skills/anti-overengineering-review/skill.json +1 -1
- package/assets/skills/backend-policy/skill.json +1 -1
- package/assets/skills/ciphera-style-policy/skill.json +1 -1
- package/assets/skills/code-review-policy/skill.json +1 -1
- package/assets/skills/core-engineering-policy/skill.json +1 -1
- package/assets/skills/database-expert/skill.json +1 -1
- package/assets/skills/debugging-policy/skill.json +1 -1
- package/assets/skills/dependency-policy/skill.json +1 -1
- package/assets/skills/email-policy/skill.json +1 -1
- package/assets/skills/frontend-design/skill.json +1 -1
- package/assets/skills/frontend-policy/skill.json +1 -1
- package/assets/skills/git-policy/skill.json +1 -1
- package/assets/skills/logo-sourcing-policy/skill.json +1 -1
- package/assets/skills/security-policy/skill.json +1 -1
- package/assets/skills/skill-creator/skill.json +1 -1
- package/assets/skills/task-completion-policy/skill.json +1 -1
- package/assets/skills/technical-writing-policy/skill.json +1 -1
- package/assets/skills/testing-policy/skill.json +1 -1
- package/assets/skills/validation-policy/skill.json +1 -1
- package/bin/checksums.json +4 -4
- package/dist/guard.js +0 -0
- package/dist/guardrails.js +57 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,7 +68,10 @@ Everything in **Minimum**, plus:
|
|
|
68
68
|
enigma Interactive menu: choose features to set up
|
|
69
69
|
enigma install Install/update agent skills
|
|
70
70
|
enigma security Set up git security hooks in the current repo
|
|
71
|
-
enigma guard [--all] Run the commit guard
|
|
71
|
+
enigma guard [--all] Run the commit guard: staged files, --all for all tracked, or
|
|
72
|
+
--range <base>..<head> for what a commit range touched (pre-push,
|
|
73
|
+
CI). --json emits one document; exits 1 on findings, 2 if it
|
|
74
|
+
could not run at all
|
|
72
75
|
enigma config [k v] Show or set runtime toggles (e.g. config commit-emoji off)
|
|
73
76
|
enigma <tool> [acct] Launch claude | codex | opencode with an account
|
|
74
77
|
(resolution: explicit > active profile > tool active);
|
|
@@ -81,7 +84,10 @@ enigma compress [file] Compress JSON/logs/text to fewer tokens (reversible via C
|
|
|
81
84
|
--clear wipes all dashboard data (stats/history/cache)
|
|
82
85
|
enigma verify Check that work reported as finished actually is: scans the change for
|
|
83
86
|
unfinished work and runs your verification command. parity <src> <dst>
|
|
84
|
-
compares a codebase against a port of it.
|
|
87
|
+
compares a codebase against a port of it. --json emits one document;
|
|
88
|
+
exits 1 on findings, 2 when the check could not run. Also runs at turn
|
|
89
|
+
end, where it additionally checks the reply itself against your
|
|
90
|
+
output-style level
|
|
85
91
|
enigma mcp Run the context-compression MCP server over stdio
|
|
86
92
|
enigma dashboard|dash Open the local dashboard (manage enigma; see savings) in your browser (http://enigma,
|
|
87
93
|
or http://localhost:24282 if :80/hosts is unavailable)
|
|
@@ -94,6 +100,30 @@ enigma check Integrity gate: verify skills are well-formed and sealed
|
|
|
94
100
|
enigma help | version
|
|
95
101
|
```
|
|
96
102
|
|
|
103
|
+
Every command answers `enigma <command> --help` with its own usage, flags and exit codes.
|
|
104
|
+
|
|
105
|
+
### Running enigma inside a container or CI runner
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
enigma install --hooks <cls> Which hooks to wire: post-edit, stop | all | none
|
|
109
|
+
enigma install --no-hooks Wire none of them --no-statusline Leave statusLine alone
|
|
110
|
+
enigma install --ref <tag|sha> Pin the skills ref (the resolved commit is printed)
|
|
111
|
+
enigma install --assets-from <dir> Install from a staged assets tree (implies --offline)
|
|
112
|
+
enigma install --offline Make no network call at all
|
|
113
|
+
|
|
114
|
+
ENIGMA_AGENT_CLAUDE=<abs path> Point the gate at an agent installed off PATH
|
|
115
|
+
(also _CODEX, _OPENCODE, _ROVODEV, _PI). The daemon runs
|
|
116
|
+
the pipeline, so set it before the daemon starts
|
|
117
|
+
ENIGMA_BIN_PATH=<abs path> Use this enigma binary instead of downloading the release
|
|
118
|
+
ENIGMA_SKILLS_REF=<tag|sha> Default skills ref (install --ref overrides it)
|
|
119
|
+
ENIGMA_OFFLINE=1 No enigma command reaches the network - the skill check,
|
|
120
|
+
the update notice and the background linter/dashboard
|
|
121
|
+
installs all stand down (install --offline sets it)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`gh` is needed only by the gate's push, pr and ci steps: `enigma gate axi run --skip
|
|
125
|
+
push,pr,ci` and `enigma gate init` work in an image without it.
|
|
126
|
+
|
|
97
127
|
## Agent skills
|
|
98
128
|
|
|
99
129
|
Skills are authored once and deployed to every selected agent (no per-agent
|
|
@@ -265,6 +295,13 @@ On every commit the guard, OS-agnostically:
|
|
|
265
295
|
Each protection is individually toggleable (saved to `.githooks/enigma-guard.json`).
|
|
266
296
|
Bypass once with `git commit --no-verify`.
|
|
267
297
|
|
|
298
|
+
`enigma guard` also runs standalone, outside the pre-commit hook, for a pre-push hook or CI
|
|
299
|
+
job where nothing is staged: `enigma guard --range <base>..<head>` scans exactly what a
|
|
300
|
+
commit range touched (a lone ref means `<ref>..HEAD`), reading each file at that range's
|
|
301
|
+
head rather than the working tree, so a secret committed and then edited out is still
|
|
302
|
+
caught. `--json` emits one machine-readable document; exit codes split 0 clean, 1 blocking
|
|
303
|
+
findings, 2 the guard could not run at all (no repository, an unresolvable range).
|
|
304
|
+
|
|
268
305
|
## Multiple accounts and profiles
|
|
269
306
|
|
|
270
307
|
Work across separate workflows with different accounts per tool - for example
|
|
@@ -446,6 +483,11 @@ other safety-critical replies. Only the selected level's rules are deployed, so
|
|
|
446
483
|
asking for "normal mode" lifts the compression for the rest of the session while
|
|
447
484
|
changing level takes `enigma config output-style <level>` and an agent restart.
|
|
448
485
|
|
|
486
|
+
Set to anything but `off`, it is also enforced: the `enigma verify` turn-end
|
|
487
|
+
hook scans the reply itself for filler, an announcing-the-work preamble, and
|
|
488
|
+
padded table rows, and denies the stop on the ones it can catch without false
|
|
489
|
+
positives (`enigma guardrails stats` reports how often a reply broke the level).
|
|
490
|
+
|
|
449
491
|
Claude Code's status bar shows an `[ENIGMA]` badge at all times; while the mode is
|
|
450
492
|
active it appends the level (`[ENIGMA:FULL]`, `[ENIGMA:LITE]`, `[ENIGMA:ULTRA]`).
|
|
451
493
|
enigma wires this into `settings.json` during `enigma install`, only when you have
|
|
@@ -4,6 +4,6 @@
|
|
|
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
6
|
"updated": "2026-06-16T11:24:30+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "f742a2be3f328b9ea1ff9a35a449177c2cbec35ad16e46f7054b7a873a2ab017"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Backend/API architecture: controller-service-repository layering, modern TypeScript project configuration (module resolution, strict flags, @/* path alias), API and request optimization (batching, avoiding redundant calls, skipping no-op writes), server-side caching (Redis), and Zod boundary validation.",
|
|
6
6
|
"updated": "2026-08-02T19:59:01+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "652637f818b4ce4f4d5d83fa68fa57fe7842e32fb179523958c5496af54bb938"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Ciphera code style conventions (formatting, naming, imports incl. namespace imports for wide module surfaces, path-alias specifiers and no file extensions, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
|
|
6
6
|
"updated": "2026-08-02T19:59:01+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "3beb0383a9cb0331ef8a579308a2517d24d57a8ba33751ad17d16d0a4f66e344"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Pre-delivery self-review gate, prioritized review dimensions, and change-quality criteria.",
|
|
6
6
|
"updated": "2026-08-02T04:15:47+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "b35f0bb4a29f2346d9a1b00a4bfee9557a9b6a44116d9e6e59abcd945466dbcb"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Core engineering execution policy and harness orchestration (highest-authority rules), including the generalization rule that treats a named example as a class to sweep and fix.",
|
|
6
6
|
"updated": "2026-08-02T04:28:51+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "95091678d4e72e3a9b1ef3ad0514e503a2a631f0d134bf772b4a1b3c66881995"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Senior database architecture policy: engine selection (PostgreSQL by default, SQLite only for local-first/embedded stores), ORM selection (Prisma in TypeScript/JavaScript), query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
|
|
6
6
|
"updated": "2026-08-04T18:33:27+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "26fddc14caf697e830448a2cc453ddc470fe83d098d50bd67b278effba63274e"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Reproduce-isolate-fix debugging methodology with root-cause discipline and regression verification.",
|
|
6
6
|
"updated": "2026-08-02T04:15:47+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "968876bcac9ce6e5a20be05c89ac97191b112c9e08679a8dc506d150c375fec4"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
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
6
|
"updated": "2026-06-01T00:45:28+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "6375d835c2aef2c9bd31ce116444dc3d796f510f9970a213aa3ac4696d7e21b9"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Transactional email: React Email templates instead of hand-written HTML tables, server-side rendering, one send module behind the provider SDK, plain-text alternatives, idempotent background sending, link safety, and deliverability (SPF/DKIM/DMARC, bounce suppression, unsubscribe).",
|
|
6
6
|
"updated": "2026-07-30T19:29:19+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "c9724fdbcdbeab99573be3fd44d4cdd97c2a394d99f3c4395f118f17356b00ed"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one.",
|
|
6
6
|
"updated": "2026-07-29T01:18:36+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "9e30ee7d8a1a1e8c6e7f4e043857cd01841c68a427752e45bc0cad9ec5cfa279"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Frontend architecture: reusable components, abstraction thresholds, state management, no-op detection (skip any operation whose result equals current state, not just form saves; dirty means different from the loaded snapshot, not touched), instant first paint (render the shell, load data async, skeletons), perceived performance (prefetch on intent, debounce/throttle, cancel stale requests, avoid waterfalls, lazy widgets), large-list rendering (infinite scroll is the preferred default, pagination the deliberate exception when the design or the user calls for it, virtualization, skeletons, progressive loading), data views that ship their own affordances by default (a log, expense, transaction or history table is not done when the rows render: fuse.js search, the filters its column kinds imply, a date range, sort, filter state in the URL, and an export of the filtered set), every reference to an entity being a way into it (a name, id, project or path in a row links to that record, reveals it in a hover card, or at minimum copies and filters by it, never inert text; machine codes get human labels and raw payloads are never dumped into a cell), optimistic UI with rollback, visual restraint (one card level, spacing before borders, one elevation scale), icon actions (repeated row/card actions are icon-only buttons with aria-label plus title, not text labels), responsive/adaptive layout (fluid units, breakpoints, no overlap/overflow, viewport meta, touch targets), form fields that declare their keyboard and casing (autocapitalize/autocomplete/inputmode per field kind, set once in the shared Input, normalized on blur), variable-length text (min-width:0 in flex/grid, wrap vs truncate, long unbroken strings, worst-case content checks), auth screens (breached-password feedback, strength meter, cookie consent before login/register), and AI chat/agent interfaces via Vercel's AI Elements registry instead of hand-rolled message threads.",
|
|
6
6
|
"updated": "2026-08-04T14:11:26+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "e5fbf094be2e7a00e40d02fd7611b7333b1249d7ac951029b8944e359135aa21"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Git & contribution policy (senior engineering standards).",
|
|
6
6
|
"updated": "2026-08-04T20:04:42+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "f55f4ed5474d5c6e7fd0804d88ac38fb3c9c3cd863519645d1415c02f4416db7"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Application and AI-agent security: secrets, authn/authz (least privilege), credential flows with breach-checked passwords (Have I Been Pwned), OWASP Top 10, transport/crypto baseline, cookies and consent, secure logging, and agent/MCP/tool-use safety.",
|
|
6
6
|
"updated": "2026-08-02T19:59:01+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "3201b6d41437626eb7bf45648c0d7f8c419dc4de87fbd9d4ca83c5ae3b6b6edf"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
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
6
|
"updated": "2026-08-03T00:16:54+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "a49f6166f57d734e0f13487332da37903e925f32257447856af0fbd6a5f1dc84"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Exhaustive completion discipline for long/multi-item tasks - inventory, coverage ledger, verified done.",
|
|
6
6
|
"updated": "2026-08-02T04:15:47+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "4c2197954135dd3375f32d839238b82a95c0e93e976ddf5a9cbc4a0cf0146e97"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Concise, realistic technical copy - UI microcopy, descriptions, hints, empty/error states, and README/doc prose that informs without over-explaining or restating the obvious, and never uses a typographic dash.",
|
|
6
6
|
"updated": "2026-07-28T20:30:23+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "a4b792103eb1f9dad93b9d70ea79dc18fe9cbbc318facf5adb47ae5907d842f9"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
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
6
|
"updated": "2026-06-16T17:11:49+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "3bdf591057b760f674fb2b1425f63acb426cda2c4f042e1a74c5a5d3807df664"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Strict frontend + backend schema validation, normalization before validation (shared normalizers: trim, lowercase email, capitalize names, canonicalize links and handles), schema consistency, and safe client-facing error handling.",
|
|
6
6
|
"updated": "2026-08-01T17:44:16+02:00",
|
|
7
|
-
"cliVersion": "1.35.
|
|
7
|
+
"cliVersion": "1.35.4",
|
|
8
8
|
"sha": "225e1e26f4a49fac70714b1bebc104ea42143203cc8fcc9e3330b29f05b6e025"
|
|
9
9
|
}
|
package/bin/checksums.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"enigma-darwin-arm64": "
|
|
3
|
-
"enigma-linux-arm64": "
|
|
4
|
-
"enigma-linux-x64": "
|
|
5
|
-
"enigma-win32-x64.exe": "
|
|
2
|
+
"enigma-darwin-arm64": "bd603ee8e1ea1e0d2fe1c0a7aaf87ba467073f314d067c33a46c78078759c49e",
|
|
3
|
+
"enigma-linux-arm64": "e621d92ce01a4e3e69b0a6ef2ca7ad337b79fcbbe72ada59ab578bcf13bf1cdd",
|
|
4
|
+
"enigma-linux-x64": "431171223a57a7a99f1e5ed4be7227394ffdca46103b1f4c80afdd5a22f30312",
|
|
5
|
+
"enigma-win32-x64.exe": "7296654a8cf971a7fbf6b3f330d6e99a85cb1a9e06932b7c4ae93fb794ce50cd"
|
|
6
6
|
}
|
package/dist/guard.js
CHANGED
|
Binary file
|
package/dist/guardrails.js
CHANGED
|
@@ -1963,6 +1963,7 @@ Fix the above before continuing.
|
|
|
1963
1963
|
}
|
|
1964
1964
|
var LEDGER_MAX_BYTES = 512 * 1024;
|
|
1965
1965
|
var LEDGER_KEEP = 2e3;
|
|
1966
|
+
var LEDGER_KEEP_REPLY = 200;
|
|
1966
1967
|
function ledgerPath() {
|
|
1967
1968
|
return process.env.ENIGMA_GUARDRAILS_LOG || join(homedir(), ".enigma", "guardrail-log.jsonl");
|
|
1968
1969
|
}
|
|
@@ -1978,20 +1979,21 @@ function recordedToday(day) {
|
|
|
1978
1979
|
}
|
|
1979
1980
|
function recordFindings(findings, outcome, stage = "edit") {
|
|
1980
1981
|
if (!findings.length) return;
|
|
1981
|
-
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1982
|
-
const seen = stage === "diff" || outcome !== "blocked" ? recordedToday(at.slice(0, 10)) : null;
|
|
1983
|
-
const rows = [];
|
|
1984
|
-
for (const f of findings) {
|
|
1985
|
-
if (seen) {
|
|
1986
|
-
const key = ledgerKey(f.ruleId, outcome, f.file, f.line);
|
|
1987
|
-
if (seen.has(key)) continue;
|
|
1988
|
-
seen.add(key);
|
|
1989
|
-
}
|
|
1990
|
-
rows.push(JSON.stringify({ at, rule: f.ruleId, severity: f.severity, outcome, stage, file: f.file, line: f.line }));
|
|
1991
|
-
}
|
|
1992
|
-
if (!rows.length) return;
|
|
1993
|
-
const path = ledgerPath();
|
|
1994
1982
|
try {
|
|
1983
|
+
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1984
|
+
const dedupe = stage !== "reply" && !(stage === "edit" && outcome === "blocked");
|
|
1985
|
+
const seen = dedupe ? recordedToday(at.slice(0, 10)) : null;
|
|
1986
|
+
const rows = [];
|
|
1987
|
+
for (const f of findings) {
|
|
1988
|
+
if (seen) {
|
|
1989
|
+
const key = ledgerKey(f.ruleId, outcome, f.file, f.line);
|
|
1990
|
+
if (seen.has(key)) continue;
|
|
1991
|
+
seen.add(key);
|
|
1992
|
+
}
|
|
1993
|
+
rows.push(JSON.stringify({ at, rule: f.ruleId, severity: f.severity, outcome, stage, file: f.file, line: f.line }));
|
|
1994
|
+
}
|
|
1995
|
+
if (!rows.length) return;
|
|
1996
|
+
const path = ledgerPath();
|
|
1995
1997
|
mkdirSync(dirname(path), { recursive: true });
|
|
1996
1998
|
let size = 0;
|
|
1997
1999
|
try {
|
|
@@ -1999,15 +2001,38 @@ function recordFindings(findings, outcome, stage = "edit") {
|
|
|
1999
2001
|
} catch {
|
|
2000
2002
|
}
|
|
2001
2003
|
if (size > LEDGER_MAX_BYTES) {
|
|
2002
|
-
const kept = readFileSync(path, "utf8")
|
|
2003
|
-
writeFileSync(path, `${kept.join("\n")}
|
|
2004
|
-
`);
|
|
2004
|
+
const kept = rotateLedger(readFileSync(path, "utf8"));
|
|
2005
|
+
writeFileSync(path, kept.length ? `${kept.join("\n")}
|
|
2006
|
+
` : "");
|
|
2005
2007
|
}
|
|
2006
2008
|
appendFileSync(path, `${rows.join("\n")}
|
|
2007
2009
|
`);
|
|
2008
2010
|
} catch {
|
|
2009
2011
|
}
|
|
2010
2012
|
}
|
|
2013
|
+
function rotateLedger(text) {
|
|
2014
|
+
const lines = text.split("\n").filter(Boolean);
|
|
2015
|
+
const kept = [];
|
|
2016
|
+
let conventions = 0;
|
|
2017
|
+
let replies = 0;
|
|
2018
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
2019
|
+
const line = lines[i];
|
|
2020
|
+
let reply = false;
|
|
2021
|
+
try {
|
|
2022
|
+
reply = JSON.parse(line)?.stage === "reply";
|
|
2023
|
+
} catch {
|
|
2024
|
+
}
|
|
2025
|
+
if (reply) {
|
|
2026
|
+
if (replies >= LEDGER_KEEP_REPLY) continue;
|
|
2027
|
+
replies++;
|
|
2028
|
+
} else {
|
|
2029
|
+
if (conventions >= LEDGER_KEEP) continue;
|
|
2030
|
+
conventions++;
|
|
2031
|
+
}
|
|
2032
|
+
kept.push(line);
|
|
2033
|
+
}
|
|
2034
|
+
return kept.reverse();
|
|
2035
|
+
}
|
|
2011
2036
|
function eachLedgerEntry(sinceDays, visit) {
|
|
2012
2037
|
let text;
|
|
2013
2038
|
try {
|
|
@@ -2027,15 +2052,27 @@ function eachLedgerEntry(sinceDays, visit) {
|
|
|
2027
2052
|
}
|
|
2028
2053
|
}
|
|
2029
2054
|
}
|
|
2055
|
+
function isConvention(entry) {
|
|
2056
|
+
return entry.stage !== "reply";
|
|
2057
|
+
}
|
|
2030
2058
|
function readLedger(sinceDays = 0) {
|
|
2031
2059
|
const out = [];
|
|
2032
|
-
eachLedgerEntry(sinceDays, (entry) =>
|
|
2060
|
+
eachLedgerEntry(sinceDays, (entry) => {
|
|
2061
|
+
if (isConvention(entry)) out.push(entry);
|
|
2062
|
+
});
|
|
2063
|
+
return out;
|
|
2064
|
+
}
|
|
2065
|
+
function readReplyLedger(sinceDays = 0) {
|
|
2066
|
+
const out = [];
|
|
2067
|
+
eachLedgerEntry(sinceDays, (entry) => {
|
|
2068
|
+
if (!isConvention(entry)) out.push(entry);
|
|
2069
|
+
});
|
|
2033
2070
|
return out;
|
|
2034
2071
|
}
|
|
2035
2072
|
function countLedger(sinceDays = 0) {
|
|
2036
2073
|
let count = 0;
|
|
2037
|
-
eachLedgerEntry(sinceDays, () => {
|
|
2038
|
-
count++;
|
|
2074
|
+
eachLedgerEntry(sinceDays, (entry) => {
|
|
2075
|
+
if (isConvention(entry)) count++;
|
|
2039
2076
|
});
|
|
2040
2077
|
return count;
|
|
2041
2078
|
}
|
|
@@ -2121,6 +2158,7 @@ export {
|
|
|
2121
2158
|
missingWindowsHide,
|
|
2122
2159
|
pageAwaitWithoutBoundary,
|
|
2123
2160
|
readLedger,
|
|
2161
|
+
readReplyLedger,
|
|
2124
2162
|
recordFindings,
|
|
2125
2163
|
runGuardrailsHook,
|
|
2126
2164
|
runGuardrailsScan,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-cli",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.4",
|
|
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": {
|