enigma-cli 1.35.8 → 1.35.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Everything you need to work with a coding agent, in one command. `enigma`
4
4
  installs a shared set of engineering **policy skills** into the agents you
5
- actually use (Claude Code, OpenAI Codex, opencode) and sets up portable **git
5
+ actually use (Claude Code, OpenAI Codex, opencode, Kimi Code) and sets up portable **git
6
6
  security hooks** that block secrets, `.env` files, and dependency dirs from being
7
7
  committed.
8
8
 
@@ -47,7 +47,7 @@ the [GitHub CLI](https://cli.github.com), [Bun](https://bun.sh) and [Warp](https
47
47
  |--|--|
48
48
  | <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white" alt="Node.js"/></a> | `>= 18`, ships with `npm` - installs and runs the `enigma` CLI |
49
49
  | <a href="https://git-scm.com"><img src="https://img.shields.io/badge/Git-F05032?style=for-the-badge&logo=git&logoColor=white" alt="Git"/></a> | powers the security hooks and the commit guard |
50
- | <img src="https://img.shields.io/badge/Coding%20agent-555555?style=for-the-badge&logo=claude&logoColor=white" alt="Coding agent"/> | at least one of [Claude Code](https://claude.com/claude-code), [OpenAI Codex](https://github.com/openai/codex) or [opencode](https://opencode.ai) - the skills need a home |
50
+ | <img src="https://img.shields.io/badge/Coding%20agent-555555?style=for-the-badge&logo=claude&logoColor=white" alt="Coding agent"/> | at least one of [Claude Code](https://claude.com/claude-code), [OpenAI Codex](https://github.com/openai/codex), [opencode](https://opencode.ai) or [Kimi Code](https://www.kimi.com/code) - the skills need a home |
51
51
 
52
52
  ### Recommended
53
53
 
@@ -73,7 +73,7 @@ enigma guard [--all] Run the commit guard: staged files, --all for all tracked
73
73
  CI). --json emits one document; exits 1 on findings, 2 if it
74
74
  could not run at all
75
75
  enigma config [k v] Show or set runtime toggles (e.g. config commit-emoji off)
76
- enigma <tool> [acct] Launch claude | codex | opencode with an account
76
+ enigma <tool> [acct] Launch claude | codex | opencode | kimi with an account
77
77
  (resolution: explicit > active profile > tool active);
78
78
  auto-syncs deployed skills first
79
79
  enigma account ... Manage per-tool accounts (list/add/use/login/remove)
@@ -128,7 +128,7 @@ push,pr,ci` and `enigma gate init` work in an image without it.
128
128
 
129
129
  Skills are authored once and deployed to every selected agent (no per-agent
130
130
  duplication). `enigma install` auto-detects which agents are installed (CLI on
131
- `PATH` or a config dir like `~/.claude`, `~/.codex`, `~/.config/opencode`) and
131
+ `PATH` or a config dir like `~/.claude`, `~/.codex`, `~/.config/opencode`, `~/.kimi-code`) and
132
132
  preselects them; `--all` targets every supported agent.
133
133
 
134
134
  | Agent | Scope | Skills | Memory file |
@@ -309,9 +309,10 @@ your **company** Claude Code account and your **personal** one - keeping each
309
309
  fully isolated and switching between them without ever logging out. Each account
310
310
  has its own credentials, session, and history, so client work never mixes with
311
311
  personal projects. Supported tools: **Claude Code** (`CLAUDE_CONFIG_DIR`),
312
- **OpenAI Codex** (`CODEX_HOME`) and **OpenCode** (a private `XDG_DATA_HOME` /
312
+ **OpenAI Codex** (`CODEX_HOME`), **OpenCode** (a private `XDG_DATA_HOME` /
313
313
  `XDG_CONFIG_HOME` pair per managed account; its default account keeps your real
314
- environment untouched).
314
+ environment untouched) and **Kimi Code** (`KIMI_CODE_HOME`, which relocates its
315
+ whole data root - credentials, sessions, skills and `AGENTS.md`).
315
316
 
316
317
  > This is for legitimate, professional account separation (one account per
317
318
  > employer/context, as many organizations require). It is **not** a way to evade
@@ -338,9 +339,9 @@ enigma account rename work corp # rename an account (its config dir moves)
338
339
  enigma account remove work # delete an account and its config dir
339
340
  ```
340
341
 
341
- Your existing `~/.claude` / `~/.codex` / opencode setup is always available as
342
+ Your existing `~/.claude` / `~/.codex` / `~/.kimi-code` / opencode setup is always available as
342
343
  each tool's built-in `default` account (never deleted). New accounts live under
343
- `~/.enigma/<tool>/<name>/`. Bare `claude` / `codex` / `opencode` commands keep
344
+ `~/.enigma/<tool>/<name>/`. Bare `claude` / `codex` / `opencode` / `kimi` commands keep
344
345
  using your real environment as before.
345
346
 
346
347
  Managed accounts inherit your enigma setup automatically: because the tool reads
@@ -372,7 +373,7 @@ enigma profile use none # deactivate
372
373
 
373
374
  From the hub TUI (`enigma`), the **Accounts** panel lists every tool's accounts -
374
375
  with the signed-in identity (email for Claude/Codex, connected providers for
375
- OpenCode) - and lets you **add** (`a`), set active (`enter`), **connect**/log in
376
+ OpenCode and Kimi Code) - and lets you **add** (`a`), set active (`enter`), **connect**/log in
376
377
  (`c`), rename (`r`), or remove (`d`). Adding first asks **which tool** with a
377
378
  searchable selector (type to filter, like opencode's model picker), then the
378
379
  account name, then offers to connect right away. The **Profiles** panel manages
@@ -647,7 +648,7 @@ session transcripts (`~/.claude/projects/.../*.jsonl`) and reports:
647
648
  - **Breakdowns** by model, by project, **by account** (every Claude login - default and
648
649
  managed accounts, not just `~/.claude`), and a **recent sessions** table.
649
650
  - A **provider coverage** line: only Claude Code keeps a readable local usage store, so
650
- Codex and OpenCode are shown as unavailable (no local token store) rather than faked. The
651
+ Codex, OpenCode and Kimi Code are shown as unavailable (no local token store) rather than faked. The
651
652
  session/weekly windows are Claude-specific (they come from Anthropic's rate-limit headers).
652
653
  - A **current 5-hour block** computed locally from transcript timestamps: tokens + cost
653
654
  used in the open window, the **burn rate** (tokens/min) and a projected end-of-window
@@ -672,7 +673,7 @@ Honesty note: cost is an **estimate** (Anthropic does not record per-message cos
672
673
  transcript; real spend is billed by Anthropic). Token counts and prompt-cache reads are
673
674
  measured facts. enigma deliberately does **not** attribute savings to skills or to
674
675
  token-efficient output - a transcript has no counterfactual baseline, so any such figure
675
- would be invented. Only Claude Code is read today; Codex/OpenCode use absent or
676
+ would be invented. Only Claude Code is read today; Codex/OpenCode/Kimi Code use absent or
676
677
  undocumented local session stores and are not guessed.
677
678
 
678
679
  #### Manage accounts & profiles from the dashboard
@@ -0,0 +1,46 @@
1
+ {
2
+ "registry": "@enigmax/primitives",
3
+ "version": 1,
4
+ "kind": "primitive",
5
+ "items": [
6
+ {
7
+ "name": "marquee",
8
+ "title": "Draggable infinite marquee",
9
+ "description": "Looping row that takes a speed in px/s, measures its own lap, and can be grabbed and thrown without swallowing the clicks on its items.",
10
+ "targets": ["vanilla", "astro", "react"],
11
+ "entry": {
12
+ "vanilla": "@enigmax/primitives",
13
+ "astro": "@enigmax/primitives",
14
+ "react": "@enigmax/primitives/react"
15
+ },
16
+ "exports": {
17
+ "vanilla": ["createMarquee"],
18
+ "astro": ["createMarquee"],
19
+ "react": ["useMarquee"]
20
+ },
21
+ "files": [
22
+ {
23
+ "path": "src/core/marquee.ts",
24
+ "dest": "marquee.ts",
25
+ "targets": ["vanilla", "astro", "react"]
26
+ },
27
+ {
28
+ "path": "src/react/use-marquee.ts",
29
+ "dest": "use-marquee.ts",
30
+ "targets": ["react"],
31
+ "rewrite": { "@/core/marquee": "./marquee" }
32
+ }
33
+ ],
34
+ "styles": false,
35
+ "themeHooks": [
36
+ "[data-enigma-marquee]",
37
+ "[data-enigma-marquee][data-dragging]",
38
+ "[data-enigma-marquee][data-hovering]",
39
+ "[data-enigma-marquee][data-reduced-motion=true]",
40
+ "[data-enigma-marquee-track]",
41
+ "[data-enigma-marquee-copy]"
42
+ ],
43
+ "docs": "docs/notes/primitives.md#marquee"
44
+ }
45
+ ]
46
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "registry": "@enigmax/utils",
3
+ "version": 1,
4
+ "kind": "utility",
5
+ "items": [
6
+ {
7
+ "name": "cache",
8
+ "title": "Short-TTL read cache",
9
+ "description": "Read-through cache with in-flight deduplication, prefix invalidation and optional local/session persistence.",
10
+ "targets": ["vanilla", "astro", "react"],
11
+ "entry": {
12
+ "vanilla": "@enigmax/utils",
13
+ "astro": "@enigmax/utils",
14
+ "react": "@enigmax/utils/react"
15
+ },
16
+ "exports": {
17
+ "vanilla": ["createCache"],
18
+ "astro": ["createCache"],
19
+ "react": ["useCached"]
20
+ },
21
+ "files": [
22
+ {
23
+ "path": "src/core/cache.ts",
24
+ "dest": "cache.ts",
25
+ "targets": ["vanilla", "astro", "react"]
26
+ },
27
+ {
28
+ "path": "src/react/use-cached.ts",
29
+ "dest": "use-cached.ts",
30
+ "targets": ["react"],
31
+ "rewrite": { "@/core/cache": "./cache" }
32
+ }
33
+ ],
34
+ "styles": false,
35
+ "docs": "docs/notes/primitives.md#cache"
36
+ },
37
+ {
38
+ "name": "notifications",
39
+ "title": "Notification queue",
40
+ "description": "Ordering, dedupe by key, sticky errors and dismiss timers that hold instead of running while the tab is hidden. No rendering.",
41
+ "targets": ["vanilla", "astro", "react"],
42
+ "entry": {
43
+ "vanilla": "@enigmax/utils",
44
+ "astro": "@enigmax/utils",
45
+ "react": "@enigmax/utils/react"
46
+ },
47
+ "exports": {
48
+ "vanilla": ["createNotifications"],
49
+ "astro": ["createNotifications"],
50
+ "react": ["useNotifications"]
51
+ },
52
+ "files": [
53
+ {
54
+ "path": "src/core/notifications.ts",
55
+ "dest": "notifications.ts",
56
+ "targets": ["vanilla", "astro", "react"]
57
+ },
58
+ {
59
+ "path": "src/react/use-notifications.ts",
60
+ "dest": "use-notifications.ts",
61
+ "targets": ["react"],
62
+ "rewrite": { "@/core/notifications": "./notifications" }
63
+ }
64
+ ],
65
+ "styles": false,
66
+ "docs": "docs/notes/primitives.md#notifications"
67
+ }
68
+ ]
69
+ }
@@ -7,6 +7,6 @@
7
7
  "minimalCode"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.35.8",
10
+ "cliVersion": "1.35.10",
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.35.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
8
8
  "sha": "9e30ee7d8a1a1e8c6e7f4e043857cd01841c68a427752e45bc0cad9ec5cfa279"
9
9
  }
@@ -21,6 +21,13 @@ description: Frontend architecture - reusable components, abstraction thresholds
21
21
 
22
22
  ---
23
23
 
24
+ ## Headless Primitives Before Hand-Rolled Interaction
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.
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
+ - 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
+ - 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.
30
+
24
31
  ## Component Reuse (Mandatory)
25
32
 
26
33
  - ALWAYS reuse a single base component and drive its behavior with props; NEVER create separate components for variants of the same element.
@@ -3,7 +3,7 @@
3
3
  "version": "1.30.1",
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
- "updated": "2026-08-11T17:10:56+02:00",
7
- "cliVersion": "1.35.8",
8
- "sha": "54d8dcec18cf14a69617bbb919e61e329f72eaf0205f2034faef4ea31e9c7544"
6
+ "updated": "2026-08-13T18:04:26+02:00",
7
+ "cliVersion": "1.35.10",
8
+ "sha": "837f62ef43fa4ab46e7e74bb88dc6cb83e877f039565a80696e05345e28eb20d"
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.8",
7
+ "cliVersion": "1.35.10",
8
8
  "sha": "f55f4ed5474d5c6e7fd0804d88ac38fb3c9c3cd863519645d1415c02f4416db7"
9
9
  }
@@ -7,6 +7,6 @@
7
7
  "logoColorPolicy"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.35.8",
10
+ "cliVersion": "1.35.10",
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-02T19:59:01+02:00",
7
- "cliVersion": "1.35.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.8",
7
+ "cliVersion": "1.35.10",
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.35.8",
7
+ "cliVersion": "1.35.10",
8
8
  "sha": "24928a4c9eed28ebede9f23f746b09a9d3d8176f8fcca61a7780a853fa5bed4e"
9
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
- "enigma-darwin-arm64": "f80c9e61502413425c345c9c47dba54d6e4f3643b29dd5adab2df4faa1862080",
3
- "enigma-linux-arm64": "942ffce99f67dbc4c0891d8bcd11cc3d30651b377ed8a45091f2dcc3ee2e9376",
4
- "enigma-linux-x64": "27826793783f56800fb48b01a81c1685e56c3f7762ee549ab140ac6a46dae08d",
5
- "enigma-win32-x64.exe": "2e028371022a814c2812965b55f90e0165a4afa1ba9afa1f2e09d42ac06a26f2"
2
+ "enigma-darwin-arm64": "728e35d28b2e8726b1db2994b17157c39c5caa370dd83c2848f58ca3c4a6d99c",
3
+ "enigma-linux-arm64": "494ceda44c8cb913384dba6c38738aeba43662ce4a1a7128925539f26af81690",
4
+ "enigma-linux-x64": "40bfdc690fd443d48d1657799b67e17ec5e704159cd48a19f3a0aa9767d06091",
5
+ "enigma-win32-x64.exe": "e9538f2f23c8e777cc2d55e472c99a6c5f9a173028ebe2341e89ede68ff78803"
6
6
  }
@@ -141,6 +141,72 @@ var BUILTIN_RULES = [
141
141
  // idiomatic and has no detectable signature, and Rust's serde typed deserialization already
142
142
  // enforces shape - a rule for either would false-positive. The generic "validate every input"
143
143
  // principle for those languages lives in the always-on memory kernel instead.
144
+ {
145
+ id: "fe-marquee-duration",
146
+ label: "Looping row driven by a speed, not a duration",
147
+ files: ["*.ts", "*.tsx", "*.js", "*.jsx", "*.css", "*.scss", "*.astro", "*.vue", "*.svelte"],
148
+ excludeFiles: [
149
+ "*.test.*",
150
+ "*.spec.*",
151
+ "*.stories.*",
152
+ "*.min.js",
153
+ "*.min.css",
154
+ "**/tests/**",
155
+ "tests/**",
156
+ "**/__tests__/**",
157
+ "__tests__/**",
158
+ "**/dist/**",
159
+ "dist/**",
160
+ "**/build/**",
161
+ "build/**",
162
+ "**/node_modules/**",
163
+ "node_modules/**",
164
+ "**/vendor/**",
165
+ "vendor/**"
166
+ ],
167
+ ignoreFileCase: true,
168
+ scope: "file",
169
+ // Only newly written code: a duration-driven marquee is common in existing
170
+ // pages, and the rule has to name the one being added, not the backlog.
171
+ stage: "diff",
172
+ // A duration named on the same line as the looping row it drives. Requiring
173
+ // both words keeps every unrelated animation-duration out of the match.
174
+ pattern: "(marquee|ticker|logo-?wall|infinite-?scroll)[^\\n]*(animation-duration|animationDuration|--duration)|(animation-duration|animationDuration|--duration)[^\\n]*(marquee|ticker|logo-?wall|infinite-?scroll)",
175
+ absent: "px/s|pixels per second|pixelsPerSecond|\\bspeed\\b|@enigmax/primitives|useMarquee|createMarquee|enigma:allow-marquee-duration",
176
+ message: "Looping row driven by a duration. A lap is as long as its content, so the speed becomes content/duration and the row runs faster every time an item is added - measured at 45, 67 and 87 px/s for one rail at 10, 15 and 20 items. Take a speed in px/s and derive the duration, or use the primitive that already does: `enigma add marquee` (@enigmax/primitives), which also measures the lap from the DOM instead of computing it. Mark the line `enigma:allow-marquee-duration` when the duration is genuinely the contract.",
177
+ severity: "warn",
178
+ skill: "frontend-policy"
179
+ },
180
+ {
181
+ id: "fe-pointer-capture-drag",
182
+ label: "Drag bound to window, not setPointerCapture",
183
+ files: ["*.ts", "*.tsx", "*.js", "*.jsx", "*.astro", "*.vue", "*.svelte"],
184
+ excludeFiles: [
185
+ "*.test.*",
186
+ "*.spec.*",
187
+ "*.stories.*",
188
+ "*.min.js",
189
+ "**/tests/**",
190
+ "tests/**",
191
+ "**/__tests__/**",
192
+ "__tests__/**",
193
+ "**/dist/**",
194
+ "dist/**",
195
+ "**/build/**",
196
+ "build/**",
197
+ "**/node_modules/**",
198
+ "node_modules/**",
199
+ "**/vendor/**",
200
+ "vendor/**"
201
+ ],
202
+ scope: "file",
203
+ stage: "diff",
204
+ pattern: "\\.setPointerCapture\\s*\\(",
205
+ absent: "enigma:allow-pointer-capture",
206
+ message: "setPointerCapture retargets the compatibility mouse events too, so a plain click on a descendant arrives on the capturing element and the descendant's link never opens - a row of nine logo links quietly stops being nine links and nothing in the source looks wrong. Bind pointermove/pointerup/pointercancel to `window` instead, which is all the capture was for: a mousedown already captures the mouse at the OS level, so a release outside the window still arrives. Fine when the element has no interactive descendants (a slider thumb, a resize handle) - mark it `enigma:allow-pointer-capture` there (frontend-policy).",
207
+ severity: "warn",
208
+ skill: "frontend-policy"
209
+ },
144
210
  {
145
211
  id: "fe-password-input",
146
212
  label: "Reusable password input (show/hide)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigma-cli",
3
- "version": "1.35.8",
3
+ "version": "1.35.10",
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": {