enigma-cli 1.30.7 → 1.30.9

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.
@@ -7,6 +7,6 @@
7
7
  "minimalCode"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.30.7",
10
+ "cliVersion": "1.30.9",
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.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "f742a2be3f328b9ea1ff9a35a449177c2cbec35ad16e46f7054b7a873a2ab017"
9
9
  }
@@ -36,6 +36,7 @@ description: Backend/API architecture - controller-service-repository layering,
36
36
 
37
37
  - Minimize external requests; prefer batching or aggregation over many small calls.
38
38
  - Avoid redundant network calls and duplicate work within a request.
39
+ - Skip no-op writes: if a mutation would set fields to the values they already hold, short-circuit before touching the database - no write, no domain event, no cache invalidation - and return the unchanged resource. Compare the incoming values against the current row (or a version/ETag). The client applies the same rule (frontend-policy); the server is the authority.
39
40
  - Merge requests when possible; coalesce concurrent identical work.
40
41
  - Avoid N+1 queries; batch data access (delegate query specifics to database-expert).
41
42
  - Return only the fields the client needs; avoid overfetching.
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "backend-policy",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "provider": "FJRG2007/enigma",
5
- "description": "Backend/API architecture: controller-service-repository layering, API and request optimization, server-side caching (Redis), and Zod boundary validation.",
6
- "updated": "2026-06-16T12:06:06+02:00",
7
- "cliVersion": "1.30.7",
8
- "sha": "a46c3cd00aa5f47adb1e7907f1d2bc6f5562f7a272890dee9b1121976ac04ae1"
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-07-23T04:41:39+02:00",
7
+ "cliVersion": "1.30.9",
8
+ "sha": "d091e8708888d23ee14cdd6c0e71f386861f2252d95360895a31c73db090a689"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Ciphera code style conventions (formatting, naming, imports, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
6
6
  "updated": "2026-06-26T13:40:52+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "dc9ceb784004b05a0117c464e4bed05946835a04acea282586c0b735ee7c2284"
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.30.7",
7
+ "cliVersion": "1.30.9",
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-16T22:43:53+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "d132f20db08806054d95e58d3d56c2aa7ebc8e6dd24d902b0a0ed9ddfae216c5"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Senior database architecture policy: query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
6
6
  "updated": "2026-06-03T14:19:50+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "2883bcecb3202683ae6f81b073c3d6a9cec9c55029e011bdd06ba7ac3537297e"
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.30.7",
7
+ "cliVersion": "1.30.9",
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.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "6375d835c2aef2c9bd31ce116444dc3d796f510f9970a213aa3ac4696d7e21b9"
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-06-25T15:51:43-04:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "fb78be3233bf9caa67d1f522c19831542b23f47e440b02211b5a950c898318b9"
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 save detection (skip mutations when the edited state equals the saved state), client-side caching (localStorage/sessionStorage to avoid redundant server calls and survive rate limits), large-list rendering (virtualized infinite scroll vs pagination, skeletons, progressive/parallel loading, short-TTL caching), optimistic UI with rollback, 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, 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), 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, responsive/adaptive layout (fluid units, breakpoints, no overlap or horizontal overflow, viewport meta, touch targets), 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, or any frontend structure.
4
4
  ---
5
5
 
6
6
  # Frontend Architecture Policy
@@ -74,6 +74,19 @@ Keep surfaces flat and let spacing, not chrome, do the grouping.
74
74
 
75
75
  ---
76
76
 
77
+ ## Responsive & Adaptive Layout
78
+
79
+ Build every UI to adapt to the viewport; never assume a desktop width. A layout that looks right on your screen but overlaps, overflows, or clips at another size is NOT done - responsiveness is part of the task, not a follow-up.
80
+
81
+ - Design fluid / mobile-first: use responsive units and constraints (%, rem, `fr`, `min`/`max`/`clamp`, flexbox/grid) over fixed pixel widths and absolute positioning, and let content reflow. Reserve fixed sizes for things that are genuinely fixed (icons, avatars).
82
+ - Verify at real breakpoints - narrow phone, tablet, desktop, and very wide - not only the current window. At every size: nothing overlaps, collides, or sits on top of other content, and nothing is cut off, clipped, or hidden behind another element ("no se pisan las cosas").
83
+ - No horizontal page scroll: constrain widths (`max-width: 100%`), wrap or truncate long text, and give wide content (tables, code blocks, charts, diagrams) its OWN horizontal scroll container so the page body never scrolls sideways.
84
+ - Every HTML document needs the responsive viewport meta (`<meta name="viewport" content="width=device-width, initial-scale=1">`), or it renders at desktop width on mobile.
85
+ - Media scales: images/video use `max-width: 100%` with appropriate `object-fit`; never a hardcoded width that breaks small screens.
86
+ - Touch-friendly: tap targets are large enough (~44px) with spacing that prevents mis-taps, and any hover-only affordance has a tap/focus equivalent.
87
+
88
+ ---
89
+
77
90
  ## State Management
78
91
 
79
92
  - Keep state as local as possible; lift it only when genuinely shared.
@@ -82,25 +95,36 @@ Keep surfaces flat and let spacing, not chrome, do the grouping.
82
95
 
83
96
  ---
84
97
 
85
- ## No-Op Save Detection (Dirty-State Check)
98
+ ## No-Op Detection (Skip Operations That Change Nothing)
86
99
 
87
- Before sending a save/update mutation, compare the edited state against the last-known saved state. If they are equal, the save is a no-op: skip the request entirely.
100
+ The general rule: before running any operation, check whether its result would equal the current state. If the outcome is identical to what already exists, the operation is a no-op - skip it entirely: no request, no mutation, no event, no side effect. A form save is just the most common instance of this.
88
101
 
89
- ### The rule
102
+ ### The general rule
90
103
 
91
- - Track the saved (pristine) snapshot of the form/settings when it loads or after a successful save.
92
- - Compute dirtiness by comparing the current edited values against that snapshot (deep/structural equality on the fields being saved), not by counting user interactions.
93
- - Example: a value goes from state x to state z, then back to x before saving. The net change is zero - the form is NOT dirty, and pressing Save must send nothing to the backend.
94
- - When the form is not dirty, the Save action does nothing (and the button should reflect it, e.g. disabled or neutral); no request, no spinner, no toast.
95
- - When partial updates are supported, send only the changed fields (a diff against the snapshot), not the full object.
96
- - After a successful save, replace the snapshot with the newly saved state so subsequent edits diff against it.
104
+ - Hold the current (pristine) state as a snapshot, and before acting decide whether the operation would actually change it - by comparing the resulting values against the current ones (deep/structural equality on the affected fields), not by whether the user interacted.
105
+ - If nothing would change, do not perform the operation: send no request, run no mutation, emit no event, write nothing.
106
+ - Common no-ops to skip: saving a form whose values equal the loaded ones; toggling a flag to the value it already holds; selecting the filter/sort/tab that is already active; dropping an item back into its original position; re-applying a value that is already set; a PATCH whose fields already hold those values.
107
+ - When only part changed, act on the diff, not the whole object (send only the changed fields). After a successful operation, replace the snapshot with the new state so the next comparison is correct.
108
+
109
+ ### Forms & Save (the common case)
110
+
111
+ - Track the saved snapshot when the form/settings loads or after a successful save; compute dirtiness by comparing the edited values against it.
112
+ - Example: a value goes x -> z -> back to x before saving. The net change is zero - the form is NOT dirty, and Save must send nothing to the backend.
113
+ - When the form is not dirty, Save must never hit the network. Two acceptable UX options:
114
+ - Preferred: disable / neutralize the Save button while the edited values equal the snapshot, so there is nothing to submit until a real change exists.
115
+ - Or keep Save enabled but short-circuit on click: show the normal "saved" confirmation instantly and send NO request. Never open a spinner or fire a call for a no-op.
116
+ - Example: the user opens their account settings and presses Save without changing the name. The name still equals the loaded value, so the form is not dirty - the button is disabled, or the click just confirms success without a request.
117
+
118
+ ### Enforce it server-side too
119
+
120
+ - The client no-op check is a UX/latency win, not the authority. The server should also short-circuit an idempotent no-op: if a mutation would set fields to the values they already hold, skip the write, the domain event, and the cache invalidation, and return the unchanged resource (the server-side rule is owned by backend-policy).
97
121
 
98
122
  ### When NOT to apply it (judgment call)
99
123
 
100
- This is the default, not an absolute. Skip the no-op check and allow the save to go through when overwriting has value on its own:
124
+ This is the default, not an absolute. Skip the no-op check and let the operation through when performing it has value on its own:
101
125
 
102
126
  - The resource is edited concurrently by many users or updated constantly server-side, and an explicit save is meant to assert/overwrite the user's view ("last write wins" by intent).
103
- - Saving has intentional side effects beyond persisting values: bumping `updatedAt`, re-triggering a pipeline/deploy, re-validating, or acknowledging a state.
127
+ - The operation has intentional side effects beyond persisting values: bumping `updatedAt`, re-triggering a pipeline/deploy, re-validating, or acknowledging a state.
104
128
  - The client snapshot cannot be trusted to match the server (long-lived stale forms) and the save doubles as a sync.
105
129
 
106
130
  Decide per case which mode fits; when in doubt for simple single-user forms and settings panels, apply the no-op check.
@@ -151,6 +175,18 @@ Cache on the client to avoid redundant server round-trips and to keep the app us
151
175
 
152
176
  ---
153
177
 
178
+ ## Instant First Paint (Shell First, Data Async)
179
+
180
+ Render the page shell immediately; never block the first paint on data. A view that fetches everything before it renders anything looks frozen until the slowest request returns - the user stares at a blank screen. Paint the static structure (nav, headings, card frames, table chrome, stat-tile outlines) on the first tick, then fill each region as its data arrives.
181
+
182
+ - Load data asynchronously via the API AFTER the shell renders (client fetch on mount, or streaming/Suspense on server components) - do not gate the component's first render on the awaited data. The layout is static and free to render now; only the contents wait.
183
+ - Show skeleton placeholders shaped like the real content in every region still loading (cards, rows, charts, stat tiles), not one full-page spinner. Reserve the final dimensions so nothing shifts when data lands (no layout shift / CLS).
184
+ - This applies to ANY data-driven view - dashboards, panels, detail pages, settings screens - not only long lists. A dashboard of independent widgets renders its grid instantly and lets each widget resolve on its own (see Progressive / parallel rendering below).
185
+ - For an instant first paint with REAL content, read the client cache first (per Client-Side Caching) and render it immediately, then revalidate in the background (stale-while-revalidate); fall back to skeletons only on a cold cache.
186
+ - Keep empty and error states per region, so a single failed or slow widget shows its own inline state without blanking the whole page.
187
+
188
+ ---
189
+
154
190
  ## Large Lists & Progressive Loading
155
191
 
156
192
  Never render an unbounded or large dataset in one shot (no fetch-everything then map over thousands of rows). Lists of products, feeds, search results, logs, etc. must load incrementally and keep the rendered DOM bounded.
@@ -188,6 +224,19 @@ Never render an unbounded or large dataset in one shot (no fetch-everything then
188
224
 
189
225
  ---
190
226
 
227
+ ## Perceived Performance & Responsiveness
228
+
229
+ Make the dashboard FEEL instant: acknowledge every interaction immediately and push the slow work off the critical path. Combine these with Instant First Paint, Client-Side Caching, and Optimistic UI above.
230
+
231
+ - Instant interaction feedback: respond to every click/keystroke in under ~100ms (button press state, inline value change, row highlight) even while the real work is still running. A control must never feel dead while a request is in flight; keep expensive updates off the main thread (e.g. React's `startTransition`/`useTransition`) so typing and clicking stay smooth.
232
+ - Prefetch on intent: warm the data for the next likely view before the user commits - on hover/focus of a nav item or row, when a tab becomes visible, or as a row scrolls into view. Prefetch into the client cache (per Client-Side Caching) so the actual navigation reads a warm cache and paints instantly. Do not prefetch everything eagerly - only the high-probability next step.
233
+ - Debounce and throttle user-driven work: debounce inputs that trigger a query (search, filter, autosave) so a request fires only after the user pauses (~200-300ms), not per keystroke; throttle high-frequency events (scroll, resize, pointer-move, drag) to at most one run per frame. This cuts redundant requests and the re-renders that make the UI stutter.
234
+ - Cancel stale in-flight requests: when inputs change or the component unmounts, abort the previous request (AbortController, or the data library's cancellation) so a slow earlier response cannot land after - and overwrite - a newer one (an out-of-order race that shows stale data). Guard async results by the request they belong to before applying them.
235
+ - Avoid request waterfalls: start independent requests in parallel, never one-after-another. Do not fetch in a child that only renders after a parent's fetch resolves when both could start at once - hoist and fire them together (`Promise.all`, parallel queries, route loaders). Reserve sequential awaits for genuinely dependent data. (Splitting the server work is backend-policy; per-section streaming is Instant First Paint.)
236
+ - Defer heavy, offscreen widgets: code-split and lazy-load large or below-the-fold dashboard pieces (charts, editors, rarely-opened panels) so the initial bundle and first paint stay small; load them on demand or as they near the viewport.
237
+
238
+ ---
239
+
191
240
  ## Dates & Timestamps
192
241
 
193
242
  Render dates and timestamps as localized, auto-updating values. Do not hand-roll formatting (`new Date().toLocaleString`, ad-hoc "X ago" math) scattered across components, and do not pull in a heavy date library just to display a time.
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "frontend-policy",
3
- "version": "1.9.0",
3
+ "version": "1.13.0",
4
4
  "provider": "FJRG2007/enigma",
5
- "description": "Frontend architecture: reusable components, abstraction thresholds, state management, no-op save detection, large-list rendering (infinite scroll/pagination, virtualization, skeletons, progressive loading), and optimistic UI with rollback.",
6
- "updated": "2026-07-22T01:41:06+02:00",
7
- "cliVersion": "1.30.7",
8
- "sha": "c5e0b4ac972e6448331bc56f7fc0069f3f57c3515ea719d0be46addfc8dbb064"
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), 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, and responsive/adaptive layout (fluid units, breakpoints, no overlap/overflow, viewport meta, touch targets).",
6
+ "updated": "2026-07-23T04:41:39+02:00",
7
+ "cliVersion": "1.30.9",
8
+ "sha": "e4aa651134cfa25d8c65828ac213ff80d191eddb151a0f76a847031773cec8a3"
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.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "e6dfbc33884000d9d25841bd9c5a84d6558ffd374882cb7b34451eb2cebc2161"
9
9
  }
@@ -7,6 +7,6 @@
7
7
  "logoColorPolicy"
8
8
  ],
9
9
  "updated": "2026-07-17T00:17:02+02:00",
10
- "cliVersion": "1.30.7",
10
+ "cliVersion": "1.30.9",
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), OWASP Top 10, transport/crypto baseline, secure logging, and agent/MCP/tool-use safety.",
6
6
  "updated": "2026-06-01T00:45:28+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "9971e9d9127397d0152e89d24aad3191e2935e55a8483db7fd15f5d4d7a60e7a"
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-06-16T16:39:13+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "699586cce82ec0a5458288b598ee7e5ebdddb3dfcf19db354d8bc5e85e47c1c7"
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-21T20:25:56+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "feaf44a9b3ab9676c8ebd3c2a799f156d28419998f5a5355250fe95a28cd5a01"
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.",
6
6
  "updated": "2026-07-22T01:41:06+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "a8c008fac91782de0d4ef1a4ae6ee77d69e3c0a506ea06b649aa86a6c988bc4f"
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.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "3bdf591057b760f674fb2b1425f63acb426cda2c4f042e1a74c5a5d3807df664"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "provider": "FJRG2007/enigma",
5
5
  "description": "Strict frontend + backend schema validation, schema consistency, and safe client-facing error handling.",
6
6
  "updated": "2026-07-22T01:41:06+02:00",
7
- "cliVersion": "1.30.7",
7
+ "cliVersion": "1.30.9",
8
8
  "sha": "d937df0052d1ec151728a28f6567744d9e7ca0a65d84b4d5c9a697f1e40d704f"
9
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
- "enigma-darwin-arm64": "ec0e3648824798d272df7bfcd36a3de7cdbc02e5684f6fecbaa8108f32fdea9a",
3
- "enigma-linux-arm64": "1e2fd06ad4ce9c23d134d647c177d8ee86463ab544441e61db477b632f78400f",
4
- "enigma-linux-x64": "6a31ba93f9b379d81cd32a081ce5a4e3761870b0aefbd7a404e26b5365b0607a",
5
- "enigma-win32-x64.exe": "d906126cd9a28c20bd80e973e00f6715596e2b887806b5681c8207065fe0f02b"
2
+ "enigma-darwin-arm64": "9bdfdba0e0ad0687d2226d51a294ceea7591c169729a688141d0811de204377e",
3
+ "enigma-linux-arm64": "cdf8b3d629e20079979540945634a377528e1ceac990a0d40bc0f43ac0088737",
4
+ "enigma-linux-x64": "564004849a26e7af75a0fa05c8657459c120b82c09fb2dc3d4c1e4473504ae2a",
5
+ "enigma-win32-x64.exe": "e93d49c75a52b5fc074bdcf1af6b332b4d6856c50206f8f29d60c1f2bc1cbfcb"
6
6
  }
@@ -135,6 +135,51 @@ var BUILTIN_RULES = [
135
135
  severity: "warn",
136
136
  skill: "frontend-policy"
137
137
  },
138
+ {
139
+ id: "fe-skeleton-loading",
140
+ label: "Skeletons over blank/spinner loading",
141
+ files: ["*.tsx", "*.jsx"],
142
+ excludeFiles: ["*.test.*", "*.spec.*", "**/tests/**", "**/__tests__/**"],
143
+ scope: "file",
144
+ // JSX only (*.tsx/*.jsx = React/Preact/Solid/RN); other frameworks use their own idioms and
145
+ // file types, so they are never touched by this rule. A whole-component loading guard that
146
+ // returns null or a bare spinner (blank screen until the fetch resolves) - the "page doesn't
147
+ // render until it has data" tell. The return group matches ONLY null / a
148
+ // *Spinner|*Loader|*Loading|CircularProgress element, so `return <Skeleton/>` is NOT matched
149
+ // (that is the correct pattern). `absent` skips the file when ANY placeholder/skeleton signal
150
+ // is present (skeleton, animate-pulse, shimmer, Suspense, a content-loader lib, <Placeholder>)
151
+ // - the component already renders a placeholder somewhere. Kept to the terse one-line guard for
152
+ // precision (a multi-line block is not matched: precision > recall).
153
+ pattern: "\\bif\\s*\\(\\s*(isLoading|isPending|isFetching|loading|pending)\\s*\\)\\s*return\\s+(null\\b|<\\s*\\w*(Spinner|Loader|Loading|CircularProgress)\\b)",
154
+ absent: "skeleton|animate-pulse|shimmer|Suspense|ContentLoader|content-loader|<\\s*Placeholder",
155
+ message: "Component returns nothing (or only a spinner) while data loads, so the page stays blank until the fetch resolves. Render the shell/layout on first paint and show skeleton placeholders shaped like the final content (reserve their space to avoid layout shift) while data loads async via the API (frontend-policy).",
156
+ severity: "warn",
157
+ skill: "frontend-policy"
158
+ },
159
+ {
160
+ id: "fe-viewport-meta",
161
+ label: "Responsive viewport meta tag",
162
+ // Full HTML documents (a page/layout, not a fragment). Astro layouts own the <head>;
163
+ // .vue/.svelte SFCs manage head via the framework, so they are not included. A head-fragment
164
+ // file (Storybook preview-head.html, an injected partial) holds bare <meta>/<link> with NO
165
+ // literal <head> tag, so it never matches the pattern either.
166
+ files: ["*.html", "*.htm", "*.astro"],
167
+ // EMAIL and PRINT/PDF docs are full <head> documents that OMIT viewport ON PURPOSE (mail
168
+ // clients ignore it; print is fixed-width) - exclude those trees so they never flag.
169
+ excludeFiles: ["**/dist/**", "**/build/**", "**/email/**", "**/emails/**", "**/mail/**", "**/mailer/**", "**/mailers/**", "**/pdf/**", "**/print/**"],
170
+ scope: "file",
171
+ // Fires on a web document that opens a <head> but never declares a viewport meta - the one
172
+ // precise slice of "make it responsive": without it the page renders at desktop width on
173
+ // mobile. `absent` skips the file when viewport is present OR when it is clearly an EMAIL
174
+ // (mso- Outlook styles, an <!--[if mso]> conditional, -webkit-text-size-adjust reset, or MJML
175
+ // <mj-*>) - emails legitimately have no viewport, so those must never be flagged. Together with
176
+ // the path excludes this drives cross-stack false positives to ~zero.
177
+ pattern: "<head[\\s>]",
178
+ absent: "viewport|mso-|<!--\\[if\\s|-webkit-text-size-adjust|<mj-",
179
+ message: 'HTML document with a <head> but no responsive viewport meta. Add <meta name="viewport" content="width=device-width, initial-scale=1"> so the page is responsive on mobile instead of rendering at desktop width (frontend-policy).',
180
+ severity: "warn",
181
+ skill: "frontend-policy"
182
+ },
138
183
  {
139
184
  id: "doc-no-file-tree",
140
185
  label: "No ASCII file-tree in the README",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigma-cli",
3
- "version": "1.30.7",
3
+ "version": "1.30.9",
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": {