enigma-cli 1.33.1 → 1.33.2
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/skills/anti-overengineering-policy/skill.json +1 -1
- package/assets/skills/anti-overengineering-review/skill.json +1 -1
- package/assets/skills/backend-policy/SKILL.md +1 -1
- package/assets/skills/backend-policy/skill.json +4 -4
- 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.md +12 -2
- package/assets/skills/database-expert/skill.json +5 -5
- 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 +16 -1
- package/assets/skills/frontend-policy/skill.json +5 -5
- 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.md +23 -1
- package/assets/skills/security-policy/skill.json +5 -5
- 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 +152 -2
- package/package.json +1 -1
|
@@ -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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "f742a2be3f328b9ea1ff9a35a449177c2cbec35ad16e46f7054b7a873a2ab017"
|
|
9
9
|
}
|
|
@@ -17,7 +17,7 @@ description: Backend/API architecture - controller-service-repository layering,
|
|
|
17
17
|
- Separate controllers, services, repositories, and validators into distinct layers.
|
|
18
18
|
- Controller/route handler: parse and validate input, call a service, shape the response. No business logic.
|
|
19
19
|
- Service: business logic and orchestration. Reusable and domain-focused. No HTTP or framework details.
|
|
20
|
-
- Repository/data access: the only layer that talks to the database (per database-expert). No business logic.
|
|
20
|
+
- Repository/data access: the only layer that talks to the database (per database-expert). No business logic. On a TypeScript/JavaScript/Node/Bun stack that layer is the Prisma client over PostgreSQL by default - pick it without asking, and use another ORM only when the user, the requirements, or the existing codebase names one.
|
|
21
21
|
- Validator/schema: input contracts via Zod or equivalent (per validation-policy).
|
|
22
22
|
- Do not place business logic in route handlers, and do not place data access in services - go through the repository.
|
|
23
23
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-policy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Backend/API architecture: controller-service-repository layering, API and request optimization (batching, avoiding redundant calls, skipping no-op writes), server-side caching (Redis), and Zod boundary validation.",
|
|
6
|
-
"updated": "2026-
|
|
7
|
-
"cliVersion": "1.33.
|
|
8
|
-
"sha": "
|
|
6
|
+
"updated": "2026-08-01T15:51:38+02:00",
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
|
+
"sha": "572fcf9780e3892942c300214367d7205ed6dcde173a64c61c1e519506cf0cfa"
|
|
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, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
|
|
6
6
|
"updated": "2026-07-31T21:32:28+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "d6a86c28ad39ee502607a5ca8f6f361c8aa52b8fa946156165ec78c6139e495f"
|
|
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-06-01T00:45:28+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "3d3bbe0602d5bbb4afe37648fe3c2fa39376b1bcbac5d8c441f01fad1e866ed0"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Core engineering execution policy and harness orchestration (highest-authority rules).",
|
|
6
6
|
"updated": "2026-07-30T19:29:19+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "6a881d8589926fa7f48058314fd26d7042fd2ac82f1c87a6c11ffb54d1fda22b"
|
|
9
9
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: database-expert
|
|
3
|
-
description: Senior database architecture - engine selection (PostgreSQL is the default relational engine for anything deployed or multi-writer; SQLite only for local-first, embedded, single-writer stores), schema design, normalization and anti-duplication, query/index optimization, scalability (partitioning, sharding, replication), and RGPD/GDPR encryption of sensitive data. Use when designing, modifying, migrating, querying, or reviewing any database, schema, SQL, ORM model, or persistence layer, and when choosing the datastore for a new project's stack.
|
|
3
|
+
description: Senior database architecture - engine selection (PostgreSQL is the default relational engine for anything deployed or multi-writer; SQLite only for local-first, embedded, single-writer stores), ORM selection (TypeScript/JavaScript/Node/Bun projects use Prisma over PostgreSQL unless the user or the requirements name another ORM), schema design, normalization and anti-duplication, query/index optimization, scalability (partitioning, sharding, replication), and RGPD/GDPR encryption of sensitive data. Use when designing, modifying, migrating, querying, or reviewing any database, schema, SQL, ORM model, or persistence layer, and when choosing the datastore for a new project's stack.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Database Expert Policy (Senior Data Architecture Standards)
|
|
@@ -34,7 +34,17 @@ description: Senior database architecture - engine selection (PostgreSQL is the
|
|
|
34
34
|
- MySQL/MariaDB only when the platform, the host or the team requires it. SQL Server or Oracle only where it is already the environment.
|
|
35
35
|
- Do not add a second datastore before PostgreSQL runs out. It handles queues (`SELECT ... FOR UPDATE SKIP LOCKED`), full-text search, vectors, JSON documents and counters well past early scale. Add Redis, a search engine or a vector database when a measured limit demands it, not as part of the initial stack.
|
|
36
36
|
- Serverless and edge runtimes still get PostgreSQL: the problem there is connection count, not the engine, so put a pooler in front (PgBouncer, Prisma Accelerate, the provider's pooled endpoint) instead of switching to a file database.
|
|
37
|
-
- Wire it the same way every time:
|
|
37
|
+
- Wire it the same way every time: the ORM below, migrations committed to version control, the connection string from the environment and never in the repo, and pooling configured before the first load test rather than after the first outage.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ORM Selection (TypeScript/JavaScript: Prisma)
|
|
42
|
+
|
|
43
|
+
- Every TypeScript, JavaScript, Node, Bun or Deno project uses **Prisma over PostgreSQL**. Pick it without being asked - it is the default stack, not one option among several to weigh up.
|
|
44
|
+
- Use something else only when the user asks for another ORM, or the requirements or the existing codebase already commit to one. Then follow that choice and say in one line what it is.
|
|
45
|
+
- Treat Prisma as the schema's source of truth: `schema.prisma` defines the models, `prisma migrate` generates the migrations and they are committed, and the generated client is the query path. Do not hand-write parallel DDL for the same tables.
|
|
46
|
+
- Raw SQL stays available for what the query builder does poorly - `$queryRaw` with parameters, never interpolated input.
|
|
47
|
+
- The identifier policy below still applies: UUID primary keys - `@id @default(uuid(7))` where the installed Prisma version accepts the version argument, otherwise an application-generated UUIDv7/ULID - and never `autoincrement()`.
|
|
38
48
|
|
|
39
49
|
---
|
|
40
50
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "database-expert",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
|
-
"description": "Senior database architecture policy: engine selection (PostgreSQL by default, SQLite only for local-first/embedded stores), query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
|
|
6
|
-
"updated": "2026-
|
|
7
|
-
"cliVersion": "1.33.
|
|
8
|
-
"sha": "
|
|
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
|
+
"updated": "2026-08-01T15:51:38+02:00",
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
|
+
"sha": "4b7569446786c5bdbb71b2e9102aee0d8dd391b5e3e461d6fb1f05294d446ad9"
|
|
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-06-01T00:45:28+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "14b0064c8b33a0dc85e51464b05005cf5801c756b1101789a6924b9548420f6b"
|
|
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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "9e30ee7d8a1a1e8c6e7f4e043857cd01841c68a427752e45bc0cad9ec5cfa279"
|
|
9
9
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: frontend-policy
|
|
3
|
-
description: Frontend architecture - reusable components, abstraction thresholds, state management, no-op detection (skip any operation whose result equals the current state - form saves, toggles, filters, reorders - not just saves; dirty means the values DIFFER from the loaded snapshot, not that the user touched the field, so a value edited and put back leaves Save disabled), client-side caching (localStorage/sessionStorage to avoid redundant server calls and survive rate limits), instant first paint (render the shell immediately, load data async via the API, show skeletons - never block render on data), perceived performance and responsiveness (instant interaction feedback, prefetch on intent, debounce/throttle, cancel stale requests, avoid request waterfalls, lazy-load heavy widgets), large-list rendering (virtualized infinite scroll vs pagination, skeletons, progressive/parallel loading, short-TTL caching), optimistic UI with rollback, visual restraint (never a card inside a card, borders only where they carry information, spacing and background tone before chrome), icon actions (repeated row/card actions like copy, edit, rename, remove, download, refresh are icon-only buttons carrying aria-label plus title, never a text label), responsive/adaptive layout (fluid units, breakpoints, no overlap or horizontal overflow, viewport meta, touch targets), form fields that declare their keyboard and casing (autocapitalize/autocomplete/inputmode/spellcheck per field kind, set once in the shared Input, normalized on blur rather than on every keystroke, with an inline error on every field that has a rule), AI chat/assistant/agent interfaces (use Vercel's AI Elements registry for message threads, streaming, reasoning and tool-call panels, prompt inputs - never hand-roll chat UI in React), and periodic React code-health audits (react-doctor). Use when building or changing UI components, client state, forms/save flows, data fetching/caching, lists that show lots of data, loading states, dashboards/panels, layout/responsiveness, making the UI feel fast, building a chat/AI/agent/LLM interface, or any frontend structure.
|
|
3
|
+
description: Frontend architecture - reusable components, abstraction thresholds, state management, no-op detection (skip any operation whose result equals the current state - form saves, toggles, filters, reorders - not just saves; dirty means the values DIFFER from the loaded snapshot, not that the user touched the field, so a value edited and put back leaves Save disabled), client-side caching (localStorage/sessionStorage to avoid redundant server calls and survive rate limits), instant first paint (render the shell immediately, load data async via the API, show skeletons - never block render on data), perceived performance and responsiveness (instant interaction feedback, prefetch on intent, debounce/throttle, cancel stale requests, avoid request waterfalls, lazy-load heavy widgets), large-list rendering (virtualized infinite scroll vs pagination, skeletons, progressive/parallel loading, short-TTL caching), optimistic UI with rollback, visual restraint (never a card inside a card, borders only where they carry information, spacing and background tone before chrome), icon actions (repeated row/card actions like copy, edit, rename, remove, download, refresh are icon-only buttons carrying aria-label plus title, never a text label), responsive/adaptive layout (fluid units, breakpoints, no overlap or horizontal overflow, viewport meta, touch targets), form fields that declare their keyboard and casing (autocapitalize/autocomplete/inputmode/spellcheck per field kind, set once in the shared Input, normalized on blur rather than on every keystroke, with an inline error on every field that has a rule), auth screens (breached-password feedback, strength meter, cookie consent answered before login/register), AI chat/assistant/agent interfaces (use Vercel's AI Elements registry for message threads, streaming, reasoning and tool-call panels, prompt inputs - never hand-roll chat UI in React), and periodic React code-health audits (react-doctor). Use when building or changing UI components, client state, forms/save flows, data fetching/caching, lists that show lots of data, loading states, dashboards/panels, layout/responsiveness, making the UI feel fast, building a chat/AI/agent/LLM interface, or any frontend structure.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Frontend Architecture Policy
|
|
@@ -261,6 +261,9 @@ Auth is the first screen a user meets and the one most often shipped half-built.
|
|
|
261
261
|
- Every sign-in form with a password field carries a visible "Forgot your password?" link next to that field, leading to a real reset flow. Building the login screen without it is shipping a dead end.
|
|
262
262
|
- The reset request screen confirms in the same words whether or not the address is registered ("If that address has an account, we have sent a link"). Never render "no account with that email" - the screen would be an account-existence oracle.
|
|
263
263
|
- The new-password screen validates in real time against the same schema the server uses, uses the shared Input (which brings the show/hide toggle), and compares the confirmation field as the user types. Keep Submit disabled until both are valid, with the reason visible.
|
|
264
|
+
- Wherever a password is created (sign-up, reset, change), check it against Have I Been Pwned's Pwned Passwords range API as the user types - debounced, request aborted when the value changes - and refuse a breached one with "This password appeared in a data breach. Choose a different one." Free, no key, and the password never leaves the browser: only the first 5 characters of its SHA-1 do (mechanics and the server-side half in security-policy).
|
|
265
|
+
- Next to it, a strength meter: a row of segments that fills and shifts colour (red, amber, green) with a one-line verdict. Drive it from an entropy estimator (`@zxcvbn-ts/core`), fed the user's own email and name as context, not from a regex counting character classes - "Passw0rd!" satisfies every class rule and is guessed instantly. The meter is advisory; the length floor and the breach check are the gate.
|
|
266
|
+
- The consent banner is answered before either form submits (security-policy owns the cookie rules). Blocking the account on a "reject" is not the ask: record the choice, then continue.
|
|
264
267
|
- After sign-up the user lands inside the app, already signed in. If the account still needs email verification, say so in the app with a way to resend, and block only the actions that need it.
|
|
265
268
|
- Surface throttling honestly. On a `429`, show how long the wait is (from `Retry-After`), keep the button disabled with a countdown, and never swallow the response into a generic "something went wrong".
|
|
266
269
|
- A one-time-code field is one input with `autocomplete="one-time-code"`, `inputmode="numeric"`, paste of the whole code, and no clearing of what the user typed on a wrong attempt. Say how many attempts are left only if the server chose to reveal it.
|
|
@@ -268,6 +271,18 @@ Auth is the first screen a user meets and the one most often shipped half-built.
|
|
|
268
271
|
|
|
269
272
|
---
|
|
270
273
|
|
|
274
|
+
## Cookie Consent Banner
|
|
275
|
+
|
|
276
|
+
A site that loads analytics, ads, A/B testing or session replay ships a consent surface. What may be set and when is security-policy's; this is the UI half.
|
|
277
|
+
|
|
278
|
+
- Reject is as reachable as Accept: same level, same weight, one click. Hiding refusal behind an extra screen is a dark pattern, and in the EU it is not consent at all.
|
|
279
|
+
- Three actions: accept all, reject all, and per-category choices with the strictly necessary group shown as always-on and not togglable. Nothing in the other categories loads until one of them is chosen.
|
|
280
|
+
- It is a dialog over the page, not a layout shift: focus moves into it, Escape and the keyboard work, it does not sit on top of the primary action, and closing it does not reflow the page.
|
|
281
|
+
- Persist the decision so it is asked once, and leave a permanent way back in (a footer link or a settings row) to change or withdraw it.
|
|
282
|
+
- The login and sign-up screens do not submit while the banner is unanswered. Answer it, record the choice, then continue - including when the choice was to reject.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
271
286
|
## Client-Side Caching (Reduce Server Load)
|
|
272
287
|
|
|
273
288
|
Cache on the client to avoid redundant server round-trips and to keep the app usable under rate limits. The goal is to reach the backend (and therefore Redis/DB) as rarely as correctness allows.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontend-policy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.23.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
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/pagination, virtualization, skeletons, progressive loading), 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), and AI chat/agent interfaces via Vercel's AI Elements registry instead of hand-rolled message threads.",
|
|
6
|
-
"updated": "2026-
|
|
7
|
-
"cliVersion": "1.33.
|
|
8
|
-
"sha": "
|
|
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/pagination, virtualization, skeletons, progressive loading), 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-01T16:09:10+02:00",
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
|
+
"sha": "163f3e66d7a95d9a103a2478501b9ae9646de2a7324fad941fcccc70dd620b07"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Git & contribution policy (senior engineering standards).",
|
|
6
6
|
"updated": "2026-07-16T22:44:02+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "e6dfbc33884000d9d25841bd9c5a84d6558ffd374882cb7b34451eb2cebc2161"
|
|
9
9
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: security-policy
|
|
3
|
-
description: Application and AI-agent security - secrets management, authentication and authorization (least privilege), credential flows (sign-in, sign-up that establishes the session, password reset, 2FA, and rate limiting per IP and per account), OWASP Top 10 mitigations, transport and crypto baseline, secure logging, and agent/MCP/tool-use safety (prompt injection, untrusted tool output, permission boundaries). Use when handling secrets, auth, login or registration screens, permissions, untrusted data or tool output, or any security-sensitive code, config, or infrastructure.
|
|
3
|
+
description: Application and AI-agent security - secrets management, authentication and authorization (least privilege), credential flows (sign-in, sign-up that establishes the session, password reset, 2FA, breached-password checks against Have I Been Pwned, and rate limiting per IP and per account), cookie attributes and consent gating before non-essential storage, OWASP Top 10 mitigations, transport and crypto baseline, secure logging, and agent/MCP/tool-use safety (prompt injection, untrusted tool output, permission boundaries). Use when handling secrets, auth, login or registration screens, permissions, untrusted data or tool output, or any security-sensitive code, config, or infrastructure.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Security Policy
|
|
@@ -55,6 +55,16 @@ These four screens are one system: an attacker who cannot guess a password will
|
|
|
55
55
|
- On a successful reset: consume the token, rotate the session, and invalidate every other active session and refresh token for that account. Notify the account by email that the password changed.
|
|
56
56
|
- Never send the new password by email, and never embed credentials in the link. The link proves control of the address, nothing more.
|
|
57
57
|
|
|
58
|
+
### Every new password is checked against the breach corpus
|
|
59
|
+
|
|
60
|
+
- Any screen where a password is CREATED - sign-up, reset confirmation, change password - checks the candidate against Have I Been Pwned's Pwned Passwords range API before accepting it. A password sitting in a public breach is already in every credential-stuffing list, whatever its length or symbol count says.
|
|
61
|
+
- The API is free, needs no key and no account. Never send the password: SHA-1 the candidate, uppercase the hex, `GET https://api.pwnedpasswords.com/range/<first 5 hex chars>`, and look for the remaining 35 characters in the response, whose lines are `SUFFIX:COUNT`. Only the 5-character prefix ever leaves the client - that k-anonymity split is what the endpoint exists for.
|
|
62
|
+
- Send `Add-Padding: true` so the response length cannot be used to infer which prefix was asked for.
|
|
63
|
+
- Run it in real time while the user types (debounce ~400ms, abort the in-flight request when the value changes) so the answer is on screen before Submit, and run it again server-side on submit. The client check is UX; the server check is the rule.
|
|
64
|
+
- Fail OPEN. If the lookup errors or times out, accept the password and log it: blocking every registration on a third-party outage is the worse failure.
|
|
65
|
+
- Say what happened and what to do - "This password appeared in a data breach. Choose a different one." The breach count is optional; blaming the user is not.
|
|
66
|
+
- Do not stack composition rules on top (one symbol, one digit, forced rotation). NIST SP 800-63B dropped them: a length floor (12+), the breach check and rate limiting are the controls that work.
|
|
67
|
+
|
|
58
68
|
### Rate-limit by IP AND by account
|
|
59
69
|
|
|
60
70
|
- Limit both dimensions on every credential endpoint: sign-in, sign-up, password reset request, reset confirmation, email verification, 2FA/OTP verification, and any "does this identifier exist" helper the sign-in page calls.
|
|
@@ -73,6 +83,18 @@ These four screens are one system: an attacker who cannot guess a password will
|
|
|
73
83
|
|
|
74
84
|
---
|
|
75
85
|
|
|
86
|
+
## Cookies & Consent
|
|
87
|
+
|
|
88
|
+
- The session cookie is `HttpOnly`, `Secure`, `SameSite=Lax` (`Strict` where nothing legitimately enters the app cross-site), `Path=/`, with an explicit lifetime, and host-only unless a subdomain genuinely needs it. A token JavaScript can read is one XSS away from being someone else's session.
|
|
89
|
+
- `SameSite=None` demands `Secure` and a stated reason: it re-opens CSRF, so it comes with a CSRF token on every state-changing request.
|
|
90
|
+
- Use the `__Host-` prefix in production where the browser can enforce it (Secure, `Path=/`, no `Domain`).
|
|
91
|
+
- Classify every cookie before setting it: strictly necessary (session, CSRF, load balancing, the consent record itself) against everything else (analytics, A/B, ads, session replay). Only the first group may be set before the user has answered.
|
|
92
|
+
- Nothing in the second group runs until then. No analytics snippet, no tag manager, no third-party pixel, no `document.cookie` write, no `localStorage` copy of the same data: swapping the storage mechanism does not change the rule.
|
|
93
|
+
- Record the decision - what was accepted, when, against which policy version - and make withdrawing it as easy as giving it.
|
|
94
|
+
- An auth flow never starts with the banner unanswered: require the consent decision before sign-in or sign-up proceeds, so nothing is planted mid-flow behind the user's back. Accepting the non-essential ones must not be the price of an account - a "reject" that still signs the user in is what keeps this lawful under GDPR/ePrivacy, and the session cookie is strictly necessary anyway, so it needs no consent.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
76
98
|
## OWASP Top 10 Baseline
|
|
77
99
|
|
|
78
100
|
- Injection (SQL/NoSQL/command/LDAP): use parameterized queries and safe APIs; never build queries or shell commands by string concatenation (query specifics in database-expert).
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "security-policy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
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
|
-
"updated": "2026-
|
|
7
|
-
"cliVersion": "1.33.
|
|
8
|
-
"sha": "
|
|
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
|
+
"updated": "2026-08-01T16:09:10+02:00",
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
|
+
"sha": "4e222af4b41513380851d2dcfc441ceb6aacd66e300d8793ac3daf322b18c212"
|
|
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-07-29T01:18:36+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "13d24c217bdb6fe83fe16835d8f5c3d397a9f3338f16876c61ef96e97f34c90a"
|
|
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-07-30T20:10:24+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "2f82288d83dca3676d6bc49955c89477cc298f77fa56b4e414cd95ff858fa261"
|
|
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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
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.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
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-07-31T19:05:08+02:00",
|
|
7
|
-
"cliVersion": "1.33.
|
|
7
|
+
"cliVersion": "1.33.2",
|
|
8
8
|
"sha": "84bb43cc570aa927ab5c0311c17242b4158287961aa04af111cf83eb4eec6ce4"
|
|
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": "e107aa3f1cb5d7d7bfcd04c074af806e7566f5115e11c5e197ed5e5dc91050b7",
|
|
3
|
+
"enigma-linux-arm64": "7a66d16b4d71d3a8d8aed7d0d66767088488482d386939967f450ca33b7fdb0b",
|
|
4
|
+
"enigma-linux-x64": "858db068ff5fb24cef87c68519968d5b0378f63377c385b20facbbf99078cf88",
|
|
5
|
+
"enigma-win32-x64.exe": "f8b26dec60abfd4d108938b313401e737f9cd8a9de0b4bc41abf990d5691fb82"
|
|
6
6
|
}
|
package/dist/guardrails.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
import { execFileSync } from "child_process";
|
|
7
|
-
import { readFileSync, statSync, existsSync } from "fs";
|
|
8
7
|
import { dirname, join, resolve } from "path";
|
|
8
|
+
import { readFileSync, writeFileSync, statSync, existsSync } from "fs";
|
|
9
9
|
var COMMENT_LINE = /^\s*(\/\/|#|\*|--|<!--|\{?\/\*)/;
|
|
10
10
|
var BUILTIN_RULES = [
|
|
11
11
|
{
|
|
@@ -195,6 +195,112 @@ var BUILTIN_RULES = [
|
|
|
195
195
|
severity: "block",
|
|
196
196
|
skill: "frontend-policy"
|
|
197
197
|
},
|
|
198
|
+
{
|
|
199
|
+
id: "fe-name-value-normalize",
|
|
200
|
+
label: "A person-name value is normalized, not just autocapitalized",
|
|
201
|
+
files: ["*.tsx", "*.jsx", "*.vue", "*.svelte", "*.astro", "*.html", "*.htm"],
|
|
202
|
+
excludeFiles: [
|
|
203
|
+
"*.test.*",
|
|
204
|
+
"*.spec.*",
|
|
205
|
+
"**/tests/**",
|
|
206
|
+
"**/__tests__/**",
|
|
207
|
+
"**/stories/**",
|
|
208
|
+
"*.stories.*",
|
|
209
|
+
"*.min.js",
|
|
210
|
+
"**/dist/**",
|
|
211
|
+
"**/build/**",
|
|
212
|
+
"**/_build/**",
|
|
213
|
+
"**/node_modules/**",
|
|
214
|
+
"**/vendor/**",
|
|
215
|
+
"dist/**",
|
|
216
|
+
"build/**",
|
|
217
|
+
"_build/**",
|
|
218
|
+
"node_modules/**",
|
|
219
|
+
"vendor/**"
|
|
220
|
+
],
|
|
221
|
+
scope: "file",
|
|
222
|
+
// The twin of fe-name-input-capitalize, and the half that actually reaches the stored
|
|
223
|
+
// value: `autocapitalize` is a KEYBOARD hint. A phone honours it, a physical keyboard
|
|
224
|
+
// ignores it entirely, so "juan perez" typed on a laptop is stored exactly like that and
|
|
225
|
+
// the field looks broken to the user who typed it. The attribute alone clears the other
|
|
226
|
+
// rule, which is how a form ends up with the attribute and no normalization at all.
|
|
227
|
+
// Same person-name token set (see there for why `name`/`fullname` are excluded).
|
|
228
|
+
pattern: `autocomplete=\\{?["'](?:name|given-name|family-name|additional-name|honorific-prefix)["']|(?:\\bname|\\bid|\\bfor|formControlName)=\\{?["'](?:first[-_]?name|last[-_]?name|given[-_]?name|family[-_]?name|surname|apellidos?)["']`,
|
|
229
|
+
absent: "capitalizeWords|capitalizeName|capitalizeEach|toTitleCase|titleCase|startCase|properCase|normalizeName|normalizePerson|capitalize\\(|charAt\\(0\\)\\.toUpperCase|enigma:allow-no-capitalize",
|
|
230
|
+
message: 'Person-name field with no value normalization. `autocapitalize="words"` only shapes the phone keyboard - a physical keyboard ignores it, so "juan perez" is stored verbatim. Normalize the VALUE with the shared normalizer (validation-policy): trim, collapse inner spaces, and uppercase the first letter of every word, ONLY that letter, so `McDonald`, `O\'Brien` and `van der Berg` survive. Run it on blur (never on every keystroke - it moves the caret and breaks IME composition) and again on the server, which is the copy that decides what is stored. Put it in the shared Input/TextField so the next form gets it by construction. For a field that must keep exactly what was typed, add an `enigma:allow-no-capitalize` note (validation-policy, frontend-policy).',
|
|
231
|
+
severity: "block",
|
|
232
|
+
skill: "validation-policy"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: "sec-password-breach-check",
|
|
236
|
+
label: "A new password is checked against the breach corpus",
|
|
237
|
+
files: ["*.tsx", "*.jsx", "*.vue", "*.svelte", "*.astro", "*.html", "*.htm", "*.ts", "*.js"],
|
|
238
|
+
excludeFiles: [
|
|
239
|
+
"*.test.*",
|
|
240
|
+
"*.spec.*",
|
|
241
|
+
"**/tests/**",
|
|
242
|
+
"**/__tests__/**",
|
|
243
|
+
"**/stories/**",
|
|
244
|
+
"*.stories.*",
|
|
245
|
+
"*.min.js",
|
|
246
|
+
"**/dist/**",
|
|
247
|
+
"**/build/**",
|
|
248
|
+
"**/_build/**",
|
|
249
|
+
"**/node_modules/**",
|
|
250
|
+
"**/vendor/**",
|
|
251
|
+
"dist/**",
|
|
252
|
+
"build/**",
|
|
253
|
+
"_build/**",
|
|
254
|
+
"node_modules/**",
|
|
255
|
+
"vendor/**"
|
|
256
|
+
],
|
|
257
|
+
scope: "file",
|
|
258
|
+
// `autocomplete="new-password"` is the spec's own marker for a password being CREATED -
|
|
259
|
+
// sign-up, reset confirmation, change password - and never appears on a sign-in form
|
|
260
|
+
// (that one is `current-password`). So it selects exactly the screens where the check
|
|
261
|
+
// belongs, with no path guessing. Any mention of the check anywhere in the file clears
|
|
262
|
+
// it, including a call into a shared hook whose name carries `pwned`/`breach`.
|
|
263
|
+
pattern: `autocomplete=\\{?["']new-password["']`,
|
|
264
|
+
absent: "pwnedpasswords|haveibeenpwned|hibp|pwned|breach|enigma:allow-no-breach-check",
|
|
265
|
+
message: "A password is created here with no breach check. Length and symbol rules do not stop a password that is already in a credential-stuffing list. Check it against Have I Been Pwned's Pwned Passwords range API - free, no key, and the password never leaves the client: SHA-1 it, uppercase the hex, GET https://api.pwnedpasswords.com/range/<first 5 chars> with `Add-Padding: true`, and look for the remaining 35 characters in the `SUFFIX:COUNT` lines. Debounce it as the user types, abort the in-flight request when the value changes, repeat the check server-side on submit, and fail OPEN if the lookup errors so an outage never blocks a signup. For a flow that genuinely cannot reach it, add an `enigma:allow-no-breach-check` note (security-policy).",
|
|
266
|
+
severity: "block",
|
|
267
|
+
skill: "security-policy"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
id: "fe-tracking-before-consent",
|
|
271
|
+
label: "Non-essential tracking waits for consent",
|
|
272
|
+
files: ["*.tsx", "*.jsx", "*.vue", "*.svelte", "*.astro", "*.html", "*.htm", "*.ts", "*.js", "*.mts", "*.cts"],
|
|
273
|
+
excludeFiles: [
|
|
274
|
+
"*.test.*",
|
|
275
|
+
"*.spec.*",
|
|
276
|
+
"**/tests/**",
|
|
277
|
+
"**/__tests__/**",
|
|
278
|
+
"**/stories/**",
|
|
279
|
+
"*.stories.*",
|
|
280
|
+
"*.min.js",
|
|
281
|
+
"**/dist/**",
|
|
282
|
+
"**/build/**",
|
|
283
|
+
"**/_build/**",
|
|
284
|
+
"**/node_modules/**",
|
|
285
|
+
"**/vendor/**",
|
|
286
|
+
"dist/**",
|
|
287
|
+
"build/**",
|
|
288
|
+
"_build/**",
|
|
289
|
+
"node_modules/**",
|
|
290
|
+
"vendor/**"
|
|
291
|
+
],
|
|
292
|
+
scope: "file",
|
|
293
|
+
// The loaders and call sites of the common analytics/ads/replay vendors. Each one sets
|
|
294
|
+
// non-essential storage the moment it runs, so what matters is whether ANY consent
|
|
295
|
+
// handling exists in the same file - the gate, a Consent Mode default, or the stored
|
|
296
|
+
// decision being read. `consent` on its own clears it, deliberately generous: this rule
|
|
297
|
+
// catches the snippet pasted straight into the layout, not a considered implementation.
|
|
298
|
+
pattern: "googletagmanager\\.com|google-analytics\\.com|gtag\\(|dataLayer\\.push|connect\\.facebook\\.net|fbq\\(|mixpanel\\.|posthog\\.(?:init|capture)|amplitude\\.(?:init|getInstance)|static\\.hotjar\\.com|clarity\\.ms|cdn\\.segment\\.com",
|
|
299
|
+
absent: "consent|gdpr|cookieBanner|cookie-banner|CookieConsent|enigma:allow-no-consent",
|
|
300
|
+
message: "Analytics, ads or session replay loading with no consent gate in sight. Everything outside the strictly necessary group (session, CSRF, load balancing, the consent record) stays off until the user answers the banner - swapping the cookie for `localStorage` does not change that. Load the vendor only after the stored decision says so (or start in Consent Mode with everything denied and update on accept), make Reject as reachable as Accept, and keep the decision withdrawable. If this file genuinely runs after the gate, add an `enigma:allow-no-consent` note (security-policy, frontend-policy).",
|
|
301
|
+
severity: "block",
|
|
302
|
+
skill: "security-policy"
|
|
303
|
+
},
|
|
198
304
|
{
|
|
199
305
|
id: "fe-no-native-dialog",
|
|
200
306
|
label: "No native browser dialogs",
|
|
@@ -856,6 +962,43 @@ var PROJECT_CHECKS = {
|
|
|
856
962
|
var FILE_CHECKS = {
|
|
857
963
|
"proc-windows-hide": (content) => missingWindowsHide(content)
|
|
858
964
|
};
|
|
965
|
+
var FIXERS = {
|
|
966
|
+
"fe-name-input-capitalize": (line, file) => {
|
|
967
|
+
if (/autocapitalize/i.test(line)) return null;
|
|
968
|
+
const tags = line.match(/<input\b/gi);
|
|
969
|
+
if (!tags || tags.length !== 1) return null;
|
|
970
|
+
const attr = /\.[jt]sx$/i.test(file) ? 'autoCapitalize="words"' : 'autocapitalize="words"';
|
|
971
|
+
return line.replace(/<input\b/i, `<input ${attr}`);
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
function applyFixes(file, findings) {
|
|
975
|
+
const fixable = findings.filter((f) => f.line && FIXERS[f.ruleId]);
|
|
976
|
+
if (!fixable.length) return { fixed: [], remaining: findings };
|
|
977
|
+
let content;
|
|
978
|
+
try {
|
|
979
|
+
content = readFileSync(file, "utf8");
|
|
980
|
+
} catch {
|
|
981
|
+
return { fixed: [], remaining: findings };
|
|
982
|
+
}
|
|
983
|
+
const lines = content.split("\n");
|
|
984
|
+
const fixed = [];
|
|
985
|
+
for (const f of fixable) {
|
|
986
|
+
const idx = f.line - 1;
|
|
987
|
+
const before = lines[idx];
|
|
988
|
+
if (before === void 0) continue;
|
|
989
|
+
const after = FIXERS[f.ruleId](before, file);
|
|
990
|
+
if (after === null || after === before) continue;
|
|
991
|
+
lines[idx] = after;
|
|
992
|
+
fixed.push(f);
|
|
993
|
+
}
|
|
994
|
+
if (!fixed.length) return { fixed: [], remaining: findings };
|
|
995
|
+
try {
|
|
996
|
+
writeFileSync(file, lines.join("\n"));
|
|
997
|
+
} catch {
|
|
998
|
+
return { fixed: [], remaining: findings };
|
|
999
|
+
}
|
|
1000
|
+
return { fixed, remaining: checkPath(file) };
|
|
1001
|
+
}
|
|
859
1002
|
var SPAWNERS = /* @__PURE__ */ new Set(["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"]);
|
|
860
1003
|
function spawnerBindings(content) {
|
|
861
1004
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -1023,7 +1166,12 @@ function runGuardrailsHook(payload) {
|
|
|
1023
1166
|
} catch {
|
|
1024
1167
|
}
|
|
1025
1168
|
if (!file || typeof file !== "string") return 0;
|
|
1026
|
-
const
|
|
1169
|
+
const found = checkPath(file);
|
|
1170
|
+
if (!found.length) return 0;
|
|
1171
|
+
const { fixed, remaining: findings } = applyFixes(file, found);
|
|
1172
|
+
if (fixed.length) process.stdout.write(`enigma guardrails (fixed)
|
|
1173
|
+
${fixed.map((f) => `${f.file}:${f.line} (${f.ruleId})`).join("\n")}
|
|
1174
|
+
`);
|
|
1027
1175
|
if (!findings.length) return 0;
|
|
1028
1176
|
const warns = findings.filter((f) => f.severity === "warn");
|
|
1029
1177
|
const blocks = findings.filter((f) => f.severity === "block");
|
|
@@ -1093,7 +1241,9 @@ if (isGrEntry && fileURLToPath(import.meta.url) === grEntry) {
|
|
|
1093
1241
|
export {
|
|
1094
1242
|
BUILTIN_RULES,
|
|
1095
1243
|
FILE_CHECKS,
|
|
1244
|
+
FIXERS,
|
|
1096
1245
|
PROJECT_CHECKS,
|
|
1246
|
+
applyFixes,
|
|
1097
1247
|
checkFile,
|
|
1098
1248
|
checkPath,
|
|
1099
1249
|
findProjectRoot,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-cli",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.2",
|
|
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": {
|