enigma-cli 1.35.5 → 1.35.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/assets/memory/AGENTS.md +5 -5
- package/assets/memory/CLAUDE.md +5 -5
- 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.md +14 -2
- package/assets/skills/frontend-policy/skill.json +3 -3
- 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/guardrails.js +52 -9
- package/package.json +1 -1
package/assets/memory/AGENTS.md
CHANGED
|
@@ -99,12 +99,12 @@ Prose to the user is compressed at level **{{output-level}}**. It shapes the ANS
|
|
|
99
99
|
### AI Quality Gate (Automatic)
|
|
100
100
|
|
|
101
101
|
- The AI quality gate is active. When you finish a code task and the changes are committed, drive the gate yourself before reporting the work done - on WHATEVER branch the work is on, the default branch included. The user should not have to ask for it.
|
|
102
|
-
- Skip automatic driving only when: the user told you to skip it, the repo's `.enigma.json` sets `gate: false`, there is nothing committed to validate, or `axi run` refuses the branch as protected (`gate-protected-branches`) - then say so and leave the work unvalidated rather than switching branches on your own. To stop it for good the user runs `/gate off` (this project) or `enigma config gate off -g` (everywhere); offer that instead of silently skipping it.
|
|
102
|
+
- Skip automatic driving only when: the user told you to skip or bypass it, the repo's `.enigma.json` sets `gate: false`, there is nothing committed to validate, or `axi run` refuses the branch as protected (`gate-protected-branches`) - then say so and leave the work unvalidated rather than switching branches on your own. The user's skip is final for that work: do not run it anyway, do not re-offer next turn. To stop it for good the user runs `/gate off` (this project) or `enigma config gate off -g` (everywhere); offer that instead of silently skipping it.
|
|
103
103
|
- Those are the only exits and each has to be NAMED. Asking is not one of them: the gate being on is already the decision, so "tell me if you want me to launch it" ends a turn on a question with one answer. Ending unvalidated and silent is worse. `enigma verify` denies the stop both ways - on a message that reports the gate as skipped, and on commits no run ever saw.
|
|
104
|
-
- On the default branch the pipeline opens no PR and
|
|
105
|
-
- If the repo is not initialized yet (`enigma gate axi` says so), run `enigma gate init`
|
|
106
|
-
- Drive it through the `/gate` workflow (`enigma gate axi run --intent "<what the user set out to accomplish>"`). A gate it hands back carries `fix_policy`, the user's standing answer to who decides: under `assisted` (the default) escalate only what contradicts the request, undoes a deliberate decision, changes agreed behavior, or needs a very large change, and fix the rest yourself
|
|
107
|
-
- While a run is active never edit code to fix a finding; the pipeline owns the fixes (respond with `--action fix`). Full
|
|
104
|
+
- On the default branch the pipeline opens no PR and pushes straight to it. That is intended; report it as the outcome instead of waiting for a PR link.
|
|
105
|
+
- If the repo is not initialized yet (`enigma gate axi` says so), run `enigma gate init` yourself, then proceed - a setup step you can perform, never a reason to stop or ask. If `enigma gate` misbehaves, `enigma gate doctor` reports why.
|
|
106
|
+
- Drive it through the `/gate` workflow (`enigma gate axi run --intent "<what the user set out to accomplish>"`). A gate it hands back carries `fix_policy`, the user's standing answer to who decides: under `assisted` (the default) escalate only what contradicts the request, undoes a deliberate decision, changes agreed behavior, or needs a very large change, and fix the rest yourself; under `ask` put every finding to the user first; under `auto` settle them all yourself. Do NOT pass `--yes` (the setting is how the user grants it) and do NOT merge the PR yourself - on `checks-passed`, leave it ready for the user to review and merge.
|
|
107
|
+
- While a run is active never edit code to fix a finding; the pipeline owns the fixes (respond with `--action fix`). Full reference: the gate skill / `/gate`.
|
|
108
108
|
<!-- enigma:gate:end -->
|
|
109
109
|
|
|
110
110
|
---
|
package/assets/memory/CLAUDE.md
CHANGED
|
@@ -99,12 +99,12 @@ Prose to the user is compressed at level **{{output-level}}**. It shapes the ANS
|
|
|
99
99
|
### AI Quality Gate (Automatic)
|
|
100
100
|
|
|
101
101
|
- The AI quality gate is active. When you finish a code task and the changes are committed, drive the gate yourself before reporting the work done - on WHATEVER branch the work is on, the default branch included. The user should not have to ask for it.
|
|
102
|
-
- Skip automatic driving only when: the user told you to skip it, the repo's `.enigma.json` sets `gate: false`, there is nothing committed to validate, or `axi run` refuses the branch as protected (`gate-protected-branches`) - then say so and leave the work unvalidated rather than switching branches on your own. To stop it for good the user runs `/gate off` (this project) or `enigma config gate off -g` (everywhere); offer that instead of silently skipping it.
|
|
102
|
+
- Skip automatic driving only when: the user told you to skip or bypass it, the repo's `.enigma.json` sets `gate: false`, there is nothing committed to validate, or `axi run` refuses the branch as protected (`gate-protected-branches`) - then say so and leave the work unvalidated rather than switching branches on your own. The user's skip is final for that work: do not run it anyway, do not re-offer next turn. To stop it for good the user runs `/gate off` (this project) or `enigma config gate off -g` (everywhere); offer that instead of silently skipping it.
|
|
103
103
|
- Those are the only exits and each has to be NAMED. Asking is not one of them: the gate being on is already the decision, so "tell me if you want me to launch it" ends a turn on a question with one answer. Ending unvalidated and silent is worse. `enigma verify` denies the stop both ways - on a message that reports the gate as skipped, and on commits no run ever saw.
|
|
104
|
-
- On the default branch the pipeline opens no PR and
|
|
105
|
-
- If the repo is not initialized yet (`enigma gate axi` says so), run `enigma gate init`
|
|
106
|
-
- Drive it through the `/gate` workflow (`enigma gate axi run --intent "<what the user set out to accomplish>"`). A gate it hands back carries `fix_policy`, the user's standing answer to who decides: under `assisted` (the default) escalate only what contradicts the request, undoes a deliberate decision, changes agreed behavior, or needs a very large change, and fix the rest yourself
|
|
107
|
-
- While a run is active never edit code to fix a finding; the pipeline owns the fixes (respond with `--action fix`). Full
|
|
104
|
+
- On the default branch the pipeline opens no PR and pushes straight to it. That is intended; report it as the outcome instead of waiting for a PR link.
|
|
105
|
+
- If the repo is not initialized yet (`enigma gate axi` says so), run `enigma gate init` yourself, then proceed - a setup step you can perform, never a reason to stop or ask. If `enigma gate` misbehaves, `enigma gate doctor` reports why.
|
|
106
|
+
- Drive it through the `/gate` workflow (`enigma gate axi run --intent "<what the user set out to accomplish>"`). A gate it hands back carries `fix_policy`, the user's standing answer to who decides: under `assisted` (the default) escalate only what contradicts the request, undoes a deliberate decision, changes agreed behavior, or needs a very large change, and fix the rest yourself; under `ask` put every finding to the user first; under `auto` settle them all yourself. Do NOT pass `--yes` (the setting is how the user grants it) and do NOT merge the PR yourself - on `checks-passed`, leave it ready for the user to review and merge.
|
|
107
|
+
- While a run is active never edit code to fix a finding; the pipeline owns the fixes (respond with `--action fix`). Full reference: the gate skill / `/gate`.
|
|
108
108
|
<!-- enigma:gate:end -->
|
|
109
109
|
|
|
110
110
|
---
|
|
@@ -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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
8
8
|
"sha": "9e30ee7d8a1a1e8c6e7f4e043857cd01841c68a427752e45bc0cad9ec5cfa279"
|
|
9
9
|
}
|
|
@@ -416,6 +416,16 @@ A skeleton is not compliance by itself. `if (!data) return <PageSkeleton />` at
|
|
|
416
416
|
- Check what survives the guard before writing it: if the body below it draws a title, a tab bar, a button or any literal copy, that markup could have painted on the first tick and the guard is blanking it.
|
|
417
417
|
- The same applies to a detail view: the record's name from the route, breadcrumbs, the action buttons and the section headings render immediately, and only the fields wait.
|
|
418
418
|
|
|
419
|
+
### A tracked value paints its last sample, not a skeleton
|
|
420
|
+
|
|
421
|
+
A cold client cache is not an empty screen when the application already stores the value's history. If a view charts, logs or samples a metric over time - container CPU and memory, queue depth, disk usage, request rate, a device's last reading - then the most recent stored sample is a real, dated value the app can paint on the first tick, and the live reading replaces it when it lands. Skeletoning that tile throws away data already sitting in the same store the chart reads.
|
|
422
|
+
|
|
423
|
+
- Reach for it whenever the live read is slower than the stored one, which is the normal case: polling a container runtime, an agent on a host, a device or a third-party status API takes seconds, while the last row of the history table is one indexed query on data the view was already loading for its chart.
|
|
424
|
+
- The stored sample and the live one are the same shape, so this is a swap and not a second code path: render from `latest ?? lastTracked`, and let the live value overwrite it.
|
|
425
|
+
- Date it, and never let the two look identical - "12% - 40s ago" going to "18% - now". An undated stale number is worse than a skeleton, because the user acts on it believing it is current (Client-Side Caching says the same about a cached snapshot).
|
|
426
|
+
- Mark the tile as reconnecting rather than blanking it when the live read FAILS. The last known value plus "no reading since 14:02" is the useful screen; a skeleton that never resolves says nothing at all.
|
|
427
|
+
- The exception is a value that is meaningless when stale: a lock or availability state a user is about to act on, a balance before a payment, anything under the "never serve stale for money, security or correctness" rule. Wait for the live read there and say what it is waiting for.
|
|
428
|
+
|
|
419
429
|
### The shell ships first, the data follows
|
|
420
430
|
|
|
421
431
|
Data that arrives inside the first HTML document is data the navigation waited for. In a server-rendered route (Next App Router, Remix, Nuxt), an awaited query in the route component blocks the whole transition: the router has nothing to commit until it resolves, so the previous page stays on screen and the app feels stuck on every link click.
|
|
@@ -510,8 +520,10 @@ Render dates and timestamps as localized, auto-updating values. Do not hand-roll
|
|
|
510
520
|
|
|
511
521
|
For a user-facing search box or finder over a list, use fuse.js (fuzzy search) rather than a hand-rolled `.toLowerCase().includes()` filter. Fuzzy matching tolerates typos and partial or transposed input and ranks results by relevance - which is what users expect from a search field; a raw substring filter misses "usnig" for "using" and cannot rank. Apply it by default without being asked whenever the input is a free-text search.
|
|
512
522
|
|
|
513
|
-
-
|
|
514
|
-
-
|
|
523
|
+
- Configure it where the data is: `keys` naming every field the user would expect to search (a row's name AND its id, owner, tag), `threshold` around 0.3 as the starting point, and `ignoreLocation` on so a match late in a long string still counts.
|
|
524
|
+
- Run it over the data already in memory, re-matching per keystroke. Debouncing belongs to the request that fetches the data, not to the match itself - an in-memory search of a loaded page is instant, and delaying it only makes the field feel broken.
|
|
525
|
+
- The exception is a filter over values the user PICKS rather than types - an id, a status, a tag, a date range, a facet from a dropdown. There the exact value is the requirement and fuzzy matching would be wrong; a plain comparison is correct, and it is not the case this rule is about.
|
|
526
|
+
- Server-backed search is the other half: once the list outgrows what the client holds, the query goes to the server (which does its own matching) and fuse.js narrows only what came back. Reuse the loaded list first (per Client-Side Caching) before falling back to a server query, and say which one is running, so an empty result reads as "no matches" and not as a broken field.
|
|
515
527
|
|
|
516
528
|
### A Data View Ships Its Own Search, Filters And Export
|
|
517
529
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "1.29.0",
|
|
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
|
-
"updated": "2026-08-
|
|
7
|
-
"cliVersion": "1.35.
|
|
8
|
-
"sha": "
|
|
6
|
+
"updated": "2026-08-07T17:32:14+02:00",
|
|
7
|
+
"cliVersion": "1.35.7",
|
|
8
|
+
"sha": "a83b0abf51b618d00d3bd4b66d245585fe27b01e36633533db825923ef9655b7"
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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.7",
|
|
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": "b74a256429fc887c07e3b3faa40fe6055ea0530e1d04d75f93054fe507adb950",
|
|
3
|
+
"enigma-linux-arm64": "295993f2b72b55d30566ec2827e6de28ad59b954fd2178695b5dc38aae7b1046",
|
|
4
|
+
"enigma-linux-x64": "c8af432bf2e5caf7a6bed8c6bb8dd02f6eb5e6c2f74222c0fb334a1828e916c0",
|
|
5
|
+
"enigma-win32-x64.exe": "b1d25eabd061876871a4e7643fe78478e6179d11893e0fb4262353047dc2a086"
|
|
6
6
|
}
|
package/dist/guardrails.js
CHANGED
|
@@ -422,16 +422,59 @@ var BUILTIN_RULES = [
|
|
|
422
422
|
id: "fe-search-fuzzy",
|
|
423
423
|
label: "Fuzzy search for finders (fuse.js)",
|
|
424
424
|
files: ["*.tsx", "*.jsx", "*.vue", "*.svelte", "*.astro"],
|
|
425
|
-
excludeFiles: [
|
|
425
|
+
excludeFiles: [
|
|
426
|
+
"*.test.*",
|
|
427
|
+
"*.spec.*",
|
|
428
|
+
"*.stories.*",
|
|
429
|
+
"**/tests/**",
|
|
430
|
+
"**/__tests__/**",
|
|
431
|
+
"**/dist/**",
|
|
432
|
+
"dist/**",
|
|
433
|
+
"**/build/**",
|
|
434
|
+
"build/**",
|
|
435
|
+
"**/_build/**",
|
|
436
|
+
"_build/**",
|
|
437
|
+
"**/.next/**",
|
|
438
|
+
".next/**",
|
|
439
|
+
"**/out/**",
|
|
440
|
+
"out/**",
|
|
441
|
+
"**/node_modules/**"
|
|
442
|
+
],
|
|
426
443
|
scope: "file",
|
|
427
|
-
// A hand-rolled case-insensitive substring finder
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
444
|
+
// A hand-rolled case-insensitive substring finder inside a `.filter(...)`, in the two
|
|
445
|
+
// spellings that are near-certainly a search box. (a) SYMMETRIC: both sides lowercased,
|
|
446
|
+
// which nothing but a case-insensitive text match is written for. (b) ONE-SIDED, where the
|
|
447
|
+
// haystack is lowercased and the needle is a binding NAMED for a search box
|
|
448
|
+
// (search/query/term/keyword/needle) - the name is what replaces the second
|
|
449
|
+
// toLowerCase as evidence, and it is what keeps a plain membership test
|
|
450
|
+
// (`.filter(x => ids.includes(x))`) out. `filter` is deliberately NOT one of those
|
|
451
|
+
// names: `statusFilter`/`activeTagFilter` is the PICKED-VALUE case this rule's own
|
|
452
|
+
// escape hatch exists for, so accepting it would make the rule fire on exactly what
|
|
453
|
+
// it sanctions. It costs no measured hit - every one-sided finding in the corpus is
|
|
454
|
+
// named search/query/needle. Widening to ANY `.filter(....includes(` was measured and
|
|
455
|
+
// rejected: 171 further lines in 124 files, overwhelmingly membership tests.
|
|
456
|
+
pattern: "\\.filter\\((?:[^;]*\\.toLowerCase\\(\\)\\.includes\\([^;]*\\.toLowerCase\\(\\)|[^;]*\\.toLowerCase\\(\\)\\.includes\\(\\s*[\\w.]*(?:search|query|term|keyword|needle)[\\w.]*\\s*\\))",
|
|
457
|
+
// Word-bounded: a bare `fuse` is a substring of "refuse" and "confuse", and this rule
|
|
458
|
+
// BLOCKS - a stray word in a comment silently switching a gate off is the failure mode
|
|
459
|
+
// an escape hatch is supposed to make deliberate.
|
|
460
|
+
absent: "\\bfuse\\b|enigma:allow-substring-search",
|
|
461
|
+
// DIFF stage, and the severity is what this rule is FOR: it shipped as a `warn`, a warn
|
|
462
|
+
// exits 0 and never reaches the model, so the convention it carries has never once been
|
|
463
|
+
// enforced - which is exactly how an agent ships a dashboard full of hand-rolled finders
|
|
464
|
+
// while frontend-policy says to use fuse.js. Blocking at the EDIT stage was not available:
|
|
465
|
+
// MEASURED with the engine's own rule over 4313 UI files of real product repositories,
|
|
466
|
+
// 17 candidate lines in 16 files, 17 findings - a command menu, a combobox, a tag input,
|
|
467
|
+
// a plugin search, a source picker, a project selector, an icon picker, three gateway
|
|
468
|
+
// tables - every one a genuine hand-rolled search box and 0 false positives, but also a
|
|
469
|
+
// backlog an edit-stage block would deny a turn over on every unrelated edit to those
|
|
470
|
+
// files. Against the ADDED lines there is no backlog by construction, so the rule can
|
|
471
|
+
// only fire on a finder the agent just wrote. The one borderline finding (filtering a
|
|
472
|
+
// session list by IP) is exactly what the escape hatch is for. Two of the seventeen are
|
|
473
|
+
// what the word boundary on `fuse` recovered: a tooltip in that file says a call is
|
|
474
|
+
// "refused", which silently cleared the rule for both of its search boxes.
|
|
475
|
+
stage: "diff",
|
|
476
|
+
message: "Hand-rolled substring search. A `.includes()` filter only finds a match the user typed exactly: it misses a typo, a transposition, a missing accent and any word typed out of order, and it cannot rank - so the best match sits wherever the source array happened to put it. Use fuse.js over the already-loaded data (keys per searchable field, `threshold` around 0.3, and re-run it per keystroke - debouncing belongs to the server-backed part, not to an in-memory search). Mark the line `enigma:allow-substring-search` when this is not a free-text search box: filtering by an id, a tag, a status or any value the user picks rather than types, or a project that takes no runtime dependency (dependency-policy) and matches by hand on purpose (frontend-policy).",
|
|
477
|
+
severity: "block",
|
|
435
478
|
skill: "frontend-policy"
|
|
436
479
|
},
|
|
437
480
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-cli",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.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": {
|