enigma-cli 1.37.0 → 1.37.1

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.
@@ -155,8 +155,8 @@
155
155
  },
156
156
  {
157
157
  "name": "input",
158
- "title": "Input, with what a password field needs",
159
- "description": "A field you pass props to, with no styles of its own. A password gets its reveal toggle automatically; a generator, a strength meter and a breach check are one prop each and off until you ask. React renders every part of it, so nothing fights your tree.",
158
+ "title": "Input, one field for every type",
159
+ "description": "A field you pass props to, typed by its `type`: password gets the reveal toggle, a generator, a strength meter and a breach check; search gets debouncing, ranking and a clear button; everything else is a plain field with native props. What each type needs is loaded when that type is used, so a form of text fields ships none of it.",
160
160
  "targets": [
161
161
  "vanilla",
162
162
  "astro",
@@ -165,7 +165,7 @@
165
165
  "entry": {
166
166
  "vanilla": "@enigmax/primitives",
167
167
  "astro": "@enigmax/primitives",
168
- "react": "@enigmax/primitives/react"
168
+ "react": "@enigmax/primitives/react/input"
169
169
  },
170
170
  "exports": {
171
171
  "vanilla": [
@@ -181,17 +181,28 @@
181
181
  },
182
182
  "files": [
183
183
  {
184
- "path": "src/core/input.ts",
185
- "dest": "input/input.ts",
184
+ "path": "src/core/input-icons.ts",
185
+ "dest": "input/input-icons.ts",
186
186
  "targets": [
187
187
  "vanilla",
188
188
  "astro",
189
189
  "react"
190
190
  ]
191
191
  },
192
+ {
193
+ "path": "src/core/input.ts",
194
+ "dest": "input/input.ts",
195
+ "targets": [
196
+ "vanilla",
197
+ "astro"
198
+ ],
199
+ "rewrite": {
200
+ "@/core/input-icons": "./input-icons"
201
+ }
202
+ },
192
203
  {
193
204
  "path": "src/core/password.ts",
194
- "dest": "input/password.ts",
205
+ "dest": "input/password-core.ts",
195
206
  "targets": [
196
207
  "vanilla",
197
208
  "astro",
@@ -199,13 +210,56 @@
199
210
  ]
200
211
  },
201
212
  {
202
- "path": "src/react/use-input.ts",
203
- "dest": "input/use-input.ts",
213
+ "path": "src/core/search.ts",
214
+ "dest": "input/search-core.ts",
215
+ "targets": [
216
+ "react"
217
+ ]
218
+ },
219
+ {
220
+ "path": "src/react/input/types.ts",
221
+ "dest": "input/types.ts",
222
+ "targets": [
223
+ "react"
224
+ ],
225
+ "rewrite": {
226
+ "@/core/search": "./search-core",
227
+ "@/core/password": "./password-core"
228
+ }
229
+ },
230
+ {
231
+ "path": "src/react/input/icon.tsx",
232
+ "dest": "input/icon.tsx",
233
+ "targets": [
234
+ "react"
235
+ ]
236
+ },
237
+ {
238
+ "path": "src/react/input/write-value.ts",
239
+ "dest": "input/write-value.ts",
240
+ "targets": [
241
+ "react"
242
+ ]
243
+ },
244
+ {
245
+ "path": "src/react/input/password.tsx",
246
+ "dest": "input/password.tsx",
204
247
  "targets": [
205
248
  "react"
206
249
  ],
207
250
  "rewrite": {
208
- "@/core/input": "./input"
251
+ "@/core/password": "./password-core",
252
+ "@/react/input/types": "./types"
253
+ }
254
+ },
255
+ {
256
+ "path": "src/react/input/search.tsx",
257
+ "dest": "input/search.tsx",
258
+ "targets": [
259
+ "react"
260
+ ],
261
+ "rewrite": {
262
+ "@/core/search": "./search-core"
209
263
  }
210
264
  },
211
265
  {
@@ -219,15 +273,20 @@
219
273
  "style": "css"
220
274
  },
221
275
  {
222
- "path": "src/react/input.tsx",
276
+ "path": "src/react/input/index.tsx",
223
277
  "dest": "input/index.tsx",
224
278
  "main": true,
225
279
  "targets": [
226
280
  "react"
227
281
  ],
228
282
  "rewrite": {
229
- "@/core/input": "./input",
230
- "@/core/password": "./password"
283
+ "@/react/input/icon": "./icon",
284
+ "@/react/input/write-value": "./write-value",
285
+ "@/core/input-icons": "./input-icons",
286
+ "@/react/input/types": "./types",
287
+ "@/react/input/password": "./password",
288
+ "@/react/input/search": "./search",
289
+ "@/core/password": "./password-core"
231
290
  }
232
291
  },
233
292
  {
@@ -262,7 +321,8 @@
262
321
  "[data-enigma-password-strength-segment]",
263
322
  "[data-enigma-password-strength-segment][data-filled]",
264
323
  "[data-enigma-password-strength-label]",
265
- "[data-enigma-password-strength-warning]"
324
+ "[data-enigma-password-strength-warning]",
325
+ "[data-enigma-input-action=clear]"
266
326
  ],
267
327
  "docs": "docs/notes/primitives.md#input",
268
328
  "recipes": [
@@ -273,7 +333,7 @@
273
333
  {
274
334
  "name": "search",
275
335
  "title": "Search as you type",
276
- "description": "Search as you type, fuzzy by default with Fuse.js. Debouncing, ranking and cancellation are the primitive's; the matching is replaceable, and dropping Fuse falls back to a built-in accent-insensitive substring matcher.",
336
+ "description": "The engine behind `<Input type=\"search\">` and the palette: debouncing, ranking and cancellation, fuzzy with Fuse.js or a built-in accent-insensitive substring matcher with no dependency at all.",
277
337
  "targets": [
278
338
  "vanilla",
279
339
  "astro",
@@ -282,7 +342,7 @@
282
342
  "entry": {
283
343
  "vanilla": "@enigmax/primitives/search",
284
344
  "astro": "@enigmax/primitives/search",
285
- "react": "@enigmax/primitives/react"
345
+ "react": "@enigmax/primitives/react/search"
286
346
  },
287
347
  "exports": {
288
348
  "vanilla": [
@@ -413,14 +473,111 @@
413
473
  "[data-loading]",
414
474
  "[data-cooldown]",
415
475
  "[aria-disabled=true]",
416
- "[aria-busy=true]"
476
+ "[aria-busy=true]",
477
+ "[data-enigma-button-key]"
417
478
  ],
418
479
  "docs": "docs/notes/primitives.md#button"
419
480
  },
481
+ {
482
+ "name": "palette",
483
+ "title": "Command palette",
484
+ "description": "Ctrl/Cmd+K, search as you type, what was searched before, groups, and every key a palette is expected to answer to. A dialog made of parts you can compose or take whole, with the focus trap, the scroll lock and the listbox wiring already right.",
485
+ "targets": [
486
+ "react"
487
+ ],
488
+ "entry": {
489
+ "react": "@enigmax/primitives/react/palette"
490
+ },
491
+ "exports": {
492
+ "react": [
493
+ "SearchPalette"
494
+ ]
495
+ },
496
+ "files": [
497
+ {
498
+ "path": "src/core/palette.ts",
499
+ "dest": "palette/palette.ts",
500
+ "targets": [
501
+ "react"
502
+ ]
503
+ },
504
+ {
505
+ "path": "src/core/search.ts",
506
+ "dest": "palette/search-core.ts",
507
+ "targets": [
508
+ "react"
509
+ ]
510
+ },
511
+ {
512
+ "path": "src/react/slot.tsx",
513
+ "dest": "palette/slot.tsx",
514
+ "targets": [
515
+ "react"
516
+ ]
517
+ },
518
+ {
519
+ "path": "src/react/palette/context.ts",
520
+ "dest": "palette/context.ts",
521
+ "targets": [
522
+ "react"
523
+ ],
524
+ "rewrite": {
525
+ "@/core/palette": "./palette",
526
+ "@/core/search": "./search-core"
527
+ }
528
+ },
529
+ {
530
+ "path": "src/react/palette/root.tsx",
531
+ "dest": "palette/root.tsx",
532
+ "targets": [
533
+ "react"
534
+ ],
535
+ "rewrite": {
536
+ "@/core/palette": "./palette",
537
+ "@/core/search": "./search-core",
538
+ "@/react/slot": "./slot",
539
+ "@/react/palette/context": "./context"
540
+ }
541
+ },
542
+ {
543
+ "path": "src/react/palette/index.tsx",
544
+ "dest": "palette/index.tsx",
545
+ "main": true,
546
+ "targets": [
547
+ "react"
548
+ ],
549
+ "rewrite": {
550
+ "@/react/palette/root": "./root",
551
+ "@/react/palette/context": "./context"
552
+ }
553
+ }
554
+ ],
555
+ "styles": false,
556
+ "themeHooks": [
557
+ "[data-enigma-palette-trigger]",
558
+ "[data-enigma-palette-trigger-key]",
559
+ "[data-enigma-palette-overlay]",
560
+ "[data-enigma-palette-content]",
561
+ "[data-enigma-palette-title]",
562
+ "[data-enigma-palette-field]",
563
+ "[data-enigma-palette-list]",
564
+ "[data-enigma-palette-group]",
565
+ "[data-enigma-palette-group-label]",
566
+ "[data-enigma-palette-item]",
567
+ "[data-enigma-palette-item][data-active=true]",
568
+ "[data-enigma-palette-item][data-kind=recent]",
569
+ "[data-enigma-palette-item-label]",
570
+ "[data-enigma-palette-item-description]",
571
+ "[data-enigma-palette-empty]",
572
+ "[data-enigma-palette-footer]",
573
+ "[data-enigma-palette-hint]"
574
+ ],
575
+ "docs": "docs/notes/primitives.md#palette"
576
+ },
420
577
  {
421
578
  "name": "flags",
422
579
  "title": "Country flags",
423
- "description": "A flag as an image, from the CDN or from files you downloaded, in the rectangular set or the round one. Emoji flags are the thing this replaces: Windows ships no glyph for them, so a picker built out of emoji renders as bare letters for most desktop readers.",
580
+ "description": "A flag as an image, served by enigma or from files in your project, rectangular, square or round. It names itself in the reader's language, and accepts the emoji flag it replaces as its code - Windows ships no glyph for those, so a picker built out of emoji renders as bare letters for most desktop readers.",
424
581
  "targets": [
425
582
  "vanilla",
426
583
  "astro",
@@ -429,7 +586,7 @@
429
586
  "entry": {
430
587
  "vanilla": "@enigmax/primitives",
431
588
  "astro": "@enigmax/primitives",
432
- "react": "@enigmax/primitives/react"
589
+ "react": "@enigmax/primitives/react/flag"
433
590
  },
434
591
  "exports": {
435
592
  "vanilla": [
@@ -7,6 +7,6 @@
7
7
  "minimalCode"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.37.0",
10
+ "cliVersion": "1.37.1",
11
11
  "sha": "3f0dcc28341bb0407860534f7ce9314cfc91b5e673f8f3d13b89d61851ed75f6"
12
12
  }
@@ -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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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-19T12:37:59+02:00",
7
- "cliVersion": "1.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "6b8a924cc11b61d4b45b73384aeb095ce622229359b7cc2c6ce4bb0cf3015ed7"
9
9
  }
@@ -7,6 +7,6 @@
7
7
  "codeGraph"
8
8
  ],
9
9
  "updated": "2026-08-15T20:49:24+02:00",
10
- "cliVersion": "1.37.0",
10
+ "cliVersion": "1.37.1",
11
11
  "sha": "95b7202e5659f8d9d6f11ce29e7dc5b01575ba86c78ef948bec4753ccf430155"
12
12
  }
@@ -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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "9e30ee7d8a1a1e8c6e7f4e043857cd01841c68a427752e45bc0cad9ec5cfa279"
9
9
  }
@@ -23,7 +23,7 @@ description: Frontend architecture - reusable components, abstraction thresholds
23
23
 
24
24
  ## Headless Primitives Before Hand-Rolled Interaction
25
25
 
26
- - Interaction logic - looping/draggable rows, momentum, focus traps, virtualized lists, dismiss timers, read caches - is BEHAVIOR, and behavior that has already been measured and tested is a dependency, not a snippet to rewrite. Check the catalogue before writing it: `enigma add` lists it, `enigma add <name>` adds it as a dependency, `enigma add <name> --copy` vendors the source in when it must be edited.
26
+ - Interaction logic - looping/draggable rows, momentum, focus traps, virtualized lists, dismiss timers, read caches - is BEHAVIOR, and behavior that has already been measured and tested is a dependency, not a snippet to rewrite. Check the catalogue before writing it: `enigma add` lists it and `enigma add <name>` adds it as a DEPENDENCY, which is how you use these - the package keeps getting fixes and a dependency is how they reach the project. `--copy` vendors the source and freezes it at that version; reach for it to EDIT a component, never as the normal way to add one.
27
27
  - These primitives ship NO visual styles. They apply only what the behavior requires (overflow, touch-action, user-select, will-change, transform) and publish their state as `data-*` attributes, so the look stays entirely yours.
28
28
  - Do not hand-roll one of them "just for this page". The hand-rolled version is where the measured bugs come back: a duration-driven marquee that accelerates as items are added, a `setPointerCapture` drag that silently stops every link in the row from opening, a hover slowdown that sticks forever after the first tap because touch never fires `pointerleave`.
29
29
  - If the catalogue has no primitive for what you need, write it as one (core + adapter + registry entry + test) rather than inline in a page, so the next screen reuses it instead of rewriting it.
@@ -4,6 +4,6 @@
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Frontend architecture: reusable components, abstraction thresholds, state management, real-time form validation where an emptied or not-yet-filled field is incomplete rather than invalid (a `*` on the label and an aria-disabled submit, never \"email is not valid\" over an empty input), 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-31T02:47:20+02:00",
7
- "cliVersion": "1.37.0",
8
- "sha": "682be5335e0c761c6aa56e8d4825dec0821ca7875e0684b3cdfcc856bc750a2f"
7
+ "cliVersion": "1.37.1",
8
+ "sha": "13689bf1abc873fa4dd4241658b0552ab96870cca4e091aa2f89831051bcc616"
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-22T09:25:34+02:00",
7
- "cliVersion": "1.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "cb320a6a5fd3279604ad7920b877c1a36e48f4f39aeead1a4c4daa89901d9ce0"
9
9
  }
@@ -7,6 +7,6 @@
7
7
  "logoColorPolicy"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.37.0",
10
+ "cliVersion": "1.37.1",
11
11
  "sha": "09cdbefd98625b02a7d03685e5deed128238ff8454a83fe22279610fe3ef8ddf"
12
12
  }
@@ -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-19T12:37:59+02:00",
7
- "cliVersion": "1.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "0270c33d2b4559e831aec794c188d293d26fc17e2a8064a967d716ceb3a7bab6"
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.37.0",
7
+ "cliVersion": "1.37.1",
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.37.0",
7
+ "cliVersion": "1.37.1",
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-08-19T12:37:59+02:00",
7
- "cliVersion": "1.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "a5a228a302f50d975a947b9d84676b4c2a4780f2b222f819388cc98d6a12f207"
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.37.0",
7
+ "cliVersion": "1.37.1",
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), real-time error timing (an emptied or not-yet-filled field is incomplete, not invalid: a `*` and an aria-disabled submit instead of \"not valid\" over an empty input), schema consistency, and safe client-facing error handling.",
6
6
  "updated": "2026-08-11T17:10:56+02:00",
7
- "cliVersion": "1.37.0",
7
+ "cliVersion": "1.37.1",
8
8
  "sha": "24928a4c9eed28ebede9f23f746b09a9d3d8176f8fcca61a7780a853fa5bed4e"
9
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
- "enigma-darwin-arm64": "91724cb93f5ac7a8c5f2ca04f21433abbd8a18c4924cbab325bfb125c8dad63b",
3
- "enigma-linux-arm64": "62a1f86c6ed33b606a4064dd3565925e09cd6707781308aa568b5381edee0cb2",
4
- "enigma-linux-x64": "7c4f3f47140040d48fcbe44ffe7d7f31eeb0b6e50b3f17a3c5cbec4b8dc25eb7",
5
- "enigma-win32-x64.exe": "37532ee23b065e1a40d2410a7e548c7c3186f560bc989b04db5c429aa319356a"
2
+ "enigma-darwin-arm64": "3c011a7265b40a1a8e80dd198ffa2d422752df227732f4de28a4c88a25839596",
3
+ "enigma-linux-arm64": "714224e6bd93a8505a79e029b28cc9edb5d8925171ff7050e4a03b61830da9eb",
4
+ "enigma-linux-x64": "933e61c9bd8ecd1b86b61bbe149d00f33bb39fe6b00f73b1d4791b95d225f67c",
5
+ "enigma-win32-x64.exe": "769b6604325109f844e1ce8f61d0725dc654fca9e4e338f2fc39174d11605680"
6
6
  }
@@ -329,6 +329,31 @@ var BUILTIN_RULES = [
329
329
  severity: "block",
330
330
  skill: "validation-policy"
331
331
  },
332
+ {
333
+ id: "fe-new-password-affordance-on-signin",
334
+ label: "The strength meter belongs on a new password, not on sign-in",
335
+ files: ["*.tsx", "*.jsx", "*.vue", "*.svelte", "*.astro", "*.html", "*.htm"],
336
+ excludeFiles: [
337
+ "*.test.*",
338
+ "*.spec.*",
339
+ "**/tests/**",
340
+ "**/__tests__/**",
341
+ "**/fixtures/**",
342
+ "**/dist/**",
343
+ "**/build/**",
344
+ "**/node_modules/**",
345
+ "**/vendor/**",
346
+ "dist/**",
347
+ "build/**",
348
+ "node_modules/**",
349
+ "vendor/**"
350
+ ],
351
+ scope: "file",
352
+ fileCheck: "fe-new-password-affordance-on-signin",
353
+ message: 'A new-password affordance on a sign-in form. The five-bar strength meter, the generator and the breach check exist for a form that CREATES a password - registration, a reset, a change-password screen - and each is wrong here in its own way: the meter scores a password the visitor already has and cannot change from this screen, so it is noise at best and an accusation at worst; the generator offers to replace the one they are trying to type; and the breach check sends a hash of a real credential on every sign-in attempt. What DOES belong on sign-in is the same format VALIDATION the creation form applied - minimum length, the character rules, the normalizer - because a password that cannot satisfy the rules it was created under cannot be the right one, so the client refuses to send it and the server never sees the attempt. Keep the validation and the reveal toggle; drop the meter, the generator and the breach check. The file says which side it is on through `autocomplete="current-password"`; a change-password screen carries a `new-password` field too and is not flagged. Mark the line with an `enigma:` note if this one really is a creation form (frontend-policy, security-policy, validation-policy).',
354
+ severity: "block",
355
+ skill: "frontend-policy"
356
+ },
332
357
  {
333
358
  id: "fe-password-reveal-hand-rolled",
334
359
  label: "Password reveal toggled by hand",
@@ -1099,7 +1124,7 @@ var BUILTIN_RULES = [
1099
1124
  // `u` (not the default `i`): the escapes above are code-point escapes, which only
1100
1125
  // mean that with the unicode flag on.
1101
1126
  flags: "u",
1102
- message: 'Flag emoji. There is no font fix for this and it is not a style preference: Windows has never shipped country flags in its emoji font, so this renders as two bare letters ("ES") for most desktop readers, and iOS, Android, macOS and Linux each draw a different one. Render a flag as an IMAGE: `enigma add flags` (@enigmax/primitives) is `<Flag code="es" />`, which serves the rectangular set (lipis/flag-icons) or the round one (HatScripts/circle-flags) from a CDN, or from files it downloads into the project with `--flags local`. It also accepts the emoji you are replacing as its `code`, so a migration is the component and nothing else. In terminal output, a commit or a log line, drop the flag entirely rather than replacing it - a country name is the information, the glyph never was.',
1127
+ message: 'Flag emoji. There is no font fix for this and it is not a style preference: Windows has never shipped country flags in its emoji font, so this renders as two bare letters ("ES") for most desktop readers, and iOS, Android, macOS and Linux each draw a different one. Render a flag as an IMAGE: `enigma add flags` (@enigmax/primitives) is `<Flag code="es" />`, and serves the rectangular, square or round artwork from enigma over a CDN - or from files it downloads into the project with `--flags local`. It also accepts the emoji you are replacing as its `code`, so a migration is the component and nothing else. In terminal output, a commit or a log line, drop the flag entirely rather than replacing it - a country name is the information, the glyph never was.',
1103
1128
  severity: "block"
1104
1129
  },
1105
1130
  // NOTE: there is deliberately no "Save button with no dirty check" rule, even though
@@ -1723,6 +1748,22 @@ var PROJECT_CHECKS = {
1723
1748
  return !("prisma" in pkg || "@prisma/client" in pkg);
1724
1749
  }
1725
1750
  };
1751
+ var CURRENT_PASSWORD = /autocomplete\s*=\s*["'{\s]*current-password/i;
1752
+ var NEW_PASSWORD = /autocomplete\s*=\s*["'{\s]*new-password/i;
1753
+ var NEW_PASSWORD_PROP = /(?:^|\s)(strength|generate|breach)(?:\s*=|\s*\}|\s*\/?>|\s|$)/;
1754
+ var NOT_A_JSX_PROP = /\b(?:const|let|var|function|import|export|interface)\b/;
1755
+ function newPasswordAffordanceOnSignIn(content) {
1756
+ if (!CURRENT_PASSWORD.test(content) || NEW_PASSWORD.test(content)) return [];
1757
+ const out = [];
1758
+ const lines = content.split("\n");
1759
+ for (let i = 0; i < lines.length; i++) {
1760
+ const line = lines[i];
1761
+ if (COMMENT_LINE.test(line) || /enigma:/.test(line) || NOT_A_JSX_PROP.test(line)) continue;
1762
+ const match = NEW_PASSWORD_PROP.exec(line);
1763
+ if (match) out.push({ line: i + 1, detail: `${match[1]} on a sign-in form` });
1764
+ }
1765
+ return out;
1766
+ }
1726
1767
  var FILE_CHECKS = {
1727
1768
  "proc-windows-hide": (content) => missingWindowsHide(content),
1728
1769
  "fe-server-first-mutation": (content) => serverFirstMutation(content),
@@ -1734,7 +1775,8 @@ var FILE_CHECKS = {
1734
1775
  "ts-import-extension": (content, file) => extensionImports(content, file),
1735
1776
  "ts-alias-deep-relative": (content, file) => deepRelativeImports(content, file),
1736
1777
  "ts-alias-paths": (content, file) => missingPathAlias(content, file),
1737
- "sec-operator-env-leak": (content) => operatorHomePathLeak(content)
1778
+ "sec-operator-env-leak": (content) => operatorHomePathLeak(content),
1779
+ "fe-new-password-affordance-on-signin": (content) => newPasswordAffordanceOnSignIn(content)
1738
1780
  };
1739
1781
  var FIXERS = {
1740
1782
  "fe-name-input-capitalize": (line, file) => {
@@ -2571,6 +2613,7 @@ export {
2571
2613
  loadRules,
2572
2614
  missingPathAlias,
2573
2615
  missingWindowsHide,
2616
+ newPasswordAffordanceOnSignIn,
2574
2617
  operatorHomePathLeak,
2575
2618
  pageAwaitWithoutBoundary,
2576
2619
  readLedger,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigma-cli",
3
- "version": "1.37.0",
3
+ "version": "1.37.1",
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": {