@starci/eslint-canon-fe 9.16.0 → 9.16.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/CHANGELOG.md +22 -14
- package/dist/control-height.js +1 -1
- package/dist/drawing.js +1 -1
- package/dist/function-budget.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/config.d.ts +1 -2
- package/dist/lib/config.js +2 -2
- package/dist/lib/own-hook-origin.d.ts +1 -1
- package/dist/lib/package-root.d.ts +1 -1
- package/dist/lib/package-root.js +1 -1
- package/dist/ui-rulings.d.ts +1 -1
- package/dist/ui-rulings.js +1 -1
- package/docs/control-height.md +1 -1
- package/docs/grammar-shim.md +1 -1
- package/docs/hooks-folder.md +1 -1
- package/docs/surface-rules.md +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.16.2 - 2026-11-07
|
|
4
|
+
|
|
5
|
+
- A patch: peers `@starci/hfs` ~6.0.0. Comments, rule docs and messages cite rules by their ids and carry no ruling history; the counting cohort entries carry no ruling field.
|
|
6
|
+
|
|
7
|
+
## 9.16.1 - 2026-11-07
|
|
8
|
+
|
|
9
|
+
- A patch: `starci-fe/control-height` no longer names `SegmentedControl` (removed from `@starci/grammar` 0.24.0); the controls it holds to the one 40px height are Button, IconButton, Switch, Input, SearchField, Select, Tabs, Textarea, NumberField and ComboBox. Its docs follow.
|
|
10
|
+
|
|
3
11
|
## 9.16.0 - 2026-11-06
|
|
4
12
|
|
|
5
13
|
- Added: `starci-fe/renderer-presentation-only` (R384, `FE_RENDERER_LOGIC`, RENDERER-PURITY-1) at error: in a client renderer of a root workspace package (`packages/<pkg>/src/client/**/*.tsx`) data computation (arithmetic between two data values, `+=` accumulation), aggregation (`reduce`, a chain of `filter`/`sort`/`flatMap`, `Math.max/min(...spread)`), date math (`Date.now()`/`getTime()` arithmetic, Date setters, date-fns add/sub/diff/compare/round), a relational comparison of two data values and a mutation outside a declared action (a write to a prop or an outer value, an in-place array mutator on data, `fetch`, storage, a beacon) are refused; they belong in a measured `.ts` module the renderer calls. Mapping, display filters, ternaries that pick a view, comparisons and arithmetic with a literal and `handle.run(...)` stay allowed. A front-end package (`fe/packages/*`) is not judged by it.
|
|
@@ -10,11 +18,11 @@
|
|
|
10
18
|
|
|
11
19
|
## 9.15.0 - 2026-11-05
|
|
12
20
|
|
|
13
|
-
- Changed
|
|
21
|
+
- Changed: the canon reads the @starci/hfs runtime from the installed hfs at run time, which it peers by `~5.13.0`, and bundles no copy; `runtime/` keeps only the project graph rule, the jsdoc, sonar and next helpers and the package-scripts template, and the stale forks (slots 3.13.0) are gone.
|
|
14
22
|
|
|
15
23
|
## 9.14.4 - 2026-11-05
|
|
16
24
|
|
|
17
|
-
- Changed: the runtime copy of the canon pins gives the Grammar family its same-minor range
|
|
25
|
+
- Changed: the runtime copy of the canon pins gives the Grammar family its same-minor range and names `@starci/hfs` 5.12.0 and the Grammar family 0.22.0.
|
|
18
26
|
|
|
19
27
|
## 9.14.3 - 2026-11-05
|
|
20
28
|
|
|
@@ -245,8 +253,8 @@
|
|
|
245
253
|
## 9.6.3 - 2026-10-31
|
|
246
254
|
|
|
247
255
|
- Changed: the bundled canon pins name the 0.16.3 cohort (@starci/grammar, eslint-grammar-core and eslint-grammar-offset-pop 0.16.3, eslint-canon-fe 9.6.3, eslint-canon-be 3.9.3, stylelint-canon 2.3.0, jest-preset 2.6.0, hfs 4.13.0); ChatWorkspace and PaneLayout are removed with no alias; PaneGrid and Pane are the one generic pane grid: grammar names are generic. The surface-rules spec uses PaneGrid.
|
|
248
|
-
- Added: lib/freestyle (`exemptFreestyle`, `freestyleContext`): no-arbitrary-value, no-app-surface-paint, no-raw-brand-value, no-list-panel-padding, no-inline-class-name and no-native-img do not report the raw elements inside a `<Freestyle>` subtree of the same file; a Grammar component inside it is judged as before
|
|
249
|
-
- Added: the lint result cache of `starci app check
|
|
256
|
+
- Added: lib/freestyle (`exemptFreestyle`, `freestyleContext`): no-arbitrary-value, no-app-surface-paint, no-raw-brand-value, no-list-panel-padding, no-inline-class-name and no-native-img do not report the raw elements inside a `<Freestyle>` subtree of the same file; a Grammar component inside it is judged as before. Specs: src/freestyle.spec.ts.
|
|
257
|
+
- Added: the lint result cache of `starci app check`: `crossFileInputs`, the files and folders each rule reads beyond the linted file (an fs-audit spec proves every rule declares what it reads), and the `projectGraph` export the cache keys a file's lint record on.
|
|
250
258
|
|
|
251
259
|
## 9.6.2 - 2026-10-31
|
|
252
260
|
|
|
@@ -339,7 +347,7 @@
|
|
|
339
347
|
|
|
340
348
|
## 9.5.4 - 2026-10-29
|
|
341
349
|
|
|
342
|
-
- Changed: the bundled slot manifest 3.13.0 admits `pgmq` in `ruleParams.db.extensions` (the lite event bus
|
|
350
|
+
- Changed: the bundled slot manifest 3.13.0 admits `pgmq` in `ruleParams.db.extensions` (the lite event bus), retires `ruleParams.db.queueOutbox` and `sides.be.queueOutbox` with the pg_cron half of R258, lists `public.event_bus_send`, `public.event_bus_read`, `public.event_bus_archive`, `public.event_bus_bury`, `public.event_bus_dead_letters` and `public.event_bus_requeue` in place of `public.event_bus_write` in `ruleParams.be.dbFunctions`, and moves slot `app.db.image` to `.starcistacks/images/db/Dockerfile` (admitted by the lite `app.starcistacks` allows); the bundled rule catalog keeps R258 `DB_PGMQ_DECLARED` as the event-bus law, retires `DB_CRON_OWNED` and adds R336 `BE_EVENT_BUS_LITE_SHAPE`; the bundled canon pins name hfs 4.11.3, eslint-canon-be 3.8.2, eslint-canon-fe 9.5.4 and the Grammar family 0.15.15. No front-end rule changed.
|
|
343
351
|
|
|
344
352
|
## 9.5.3 - 2026-10-29
|
|
345
353
|
|
|
@@ -411,12 +419,12 @@
|
|
|
411
419
|
|
|
412
420
|
## 9.3.0 - 2026-10-28
|
|
413
421
|
|
|
414
|
-
- Changed (breaking for apps):
|
|
422
|
+
- Changed (breaking for apps): a pure half takes `{ shape?, props, on? }`; `base-props-atom` refuses the retired `state` key with a message naming the rename, and `no-data-status-shape` reads `XShape` unions (and still the old `XState` names, so a status word is caught during the rename).
|
|
415
423
|
- Changed: the bundled runtime copies follow the retirement of `@starci/cli`: the bundled canon pins replace the retired `@starci/cli` with `starci-harness` 1.1.0-alpha.1 (`source: cli/package.json`), the one command line a product installs for `starci app`, and follow the harness packages (Grammar family 0.14.0, hfs 4.9.0, canon-fe 9.3.0, canon-be 3.5.0); the runtime finds an app's `starci` bin in its installed `starci-harness`.
|
|
416
424
|
|
|
417
425
|
## 9.2.0 - 2026-10-27
|
|
418
426
|
|
|
419
|
-
- Changed:
|
|
427
|
+
- Changed: the bundled Grammar catalog declares exactly two families, `core` (`@starci/eslint-grammar-core`, `coreGrammarConfig`) and `offset-pop`; `starci`, `starci-core` and `heritage` are refused. The Grammar entry checks (button intent, control height, surface rules, UI rulings) accept `@starci/grammar/<common|core|offset-pop>`. The bundled canon pins follow the harness packages (Grammar family 0.13.0, hfs 4.8.0, canon-fe 9.2.0, canon-be 3.4.57, stylelint-canon 2.1.0).
|
|
420
428
|
- Changed: the doc comment of `lint-escape-hatch.mjs` names the three patterns that own the refused spellings instead of spelling them again. No rule or behaviour changed.
|
|
421
429
|
|
|
422
430
|
## 9.1.11 - 2026-10-27
|
|
@@ -430,7 +438,7 @@
|
|
|
430
438
|
## 9.1.9 - 2026-10-26
|
|
431
439
|
|
|
432
440
|
- Added: starci-fe/control-height (R320 FE_CONTROL_HEIGHT), selection-fill-no-check and no-grammar-internal-selector.
|
|
433
|
-
- Changed: the bundled runtime copies carry the light push gate
|
|
441
|
+
- Changed: the bundled runtime copies carry the light push gate.
|
|
434
442
|
|
|
435
443
|
## 9.1.8 - 2026-10-26
|
|
436
444
|
|
|
@@ -523,7 +531,7 @@
|
|
|
523
531
|
## 8.4.30 - 2026-10-23
|
|
524
532
|
- Changed: the bundled canon pins select @starci/hfs 4.7.24 and @starci/cli 1.7.24.
|
|
525
533
|
- Added: the type-aware rules the back end already borrowed, at error: `@typescript-eslint/no-floating-promises`, `no-misused-promises`, `switch-exhaustiveness-check` and the `no-unsafe-assignment`, `-member-access`, `-call`, `-return`, `-argument` family.
|
|
526
|
-
- Changed: no Sonar way rule is left to the server (
|
|
534
|
+
- Changed: no Sonar way rule is left to the server (no loosening): S3403, S3800, S3782 and S6582 run at error, `unicorn/consistent-function-scoping` runs with its default options, and S7785 (`unicorn/prefer-top-level-await`) runs in the front end (ESM).
|
|
527
535
|
- Added: `starciPlainSourceConfig({ root })` for a TypeScript front-end tree that is no HFS app (a runtime package, the harness UI): typed linting, the inline-directive fence, the React Hooks, type-aware and Sonar way rules and every canon rule that needs no slot view (`SLOT_FREE_RULES`), all at error.
|
|
528
536
|
|
|
529
537
|
## 8.4.29 - 2026-10-22
|
|
@@ -612,9 +620,9 @@
|
|
|
612
620
|
|
|
613
621
|
## 8.4.1 - 2026-10-17
|
|
614
622
|
|
|
615
|
-
- Changed: the bundled runtime copies follow the runtime of 1.0.0-alpha.19
|
|
616
|
-
- Changed (R287 `FE_CALLBACK_SHAPE`, a18.1 NIVO request F2
|
|
617
|
-
- Changed (R287 `FE_CALLBACK_SHAPE`, a18.1 NIVO request F
|
|
623
|
+
- Changed: the bundled runtime copies follow the runtime of 1.0.0-alpha.19: the failure codes, the slot manifest (`exampleNa`) and the rule catalog (`specNa`, `exampleNa`) carry the removal of the runtime's own specs; package behavior is unchanged.
|
|
624
|
+
- Changed (R287 `FE_CALLBACK_SHAPE`, a18.1 NIVO request F2): the auth callback may call pure text helpers of the app's `modules/routes` or `modules/auth` (`requestOrigin`, `safeNextPath`; resolved by TypeScript symbol: synchronous, no await, no I/O global, only owner helpers and `modules/config` readers), use static route tables (`AUTH_ROUTES`), and read the exchange outcome's `success` or `ok` flag. An impure, async or non-text helper, a helper outside those owners and a credential passed to a helper are still refused.
|
|
625
|
+
- Changed (R287 `FE_CALLBACK_SHAPE`, a18.1 NIVO request F): the auth callback may await one `verifyOtp({ token_hash, type })` of the auth owner (`auth.verifyOtp` or `verifyOtp` from `modules/auth/server`), built from exactly the query values `token_hash` and `type`, beside the one `exchangeAuthCode(code)`; the token hash never reaches a redirect.
|
|
618
626
|
- Fixed (R55 `FE_CLIENT_BOUNDARY`, a18.1 NIVO request I): the finding on a page or layout owner now says the owner stays a server component that renders the client block or overlay carrying the directive. The rule is unchanged.
|
|
619
627
|
|
|
620
628
|
## 8.3.0 - 2026-10-15
|
|
@@ -635,11 +643,11 @@
|
|
|
635
643
|
|
|
636
644
|
## 8.2.16 - 2026-10-13
|
|
637
645
|
|
|
638
|
-
- Changed: the heroicons family is the one application icon set again
|
|
646
|
+
- Changed: the heroicons family is the one application icon set again: `heroicons-is-the-glyph-vendor` admits exactly `@heroicons/react/24/outline`, `@heroicons/react/16/solid` and the matching `@starci/heroicons` subpaths (read from the fe-stack `icons` concern), and refuses Phosphor and every other glyph catalogue, a package the catalog forbids included; `one-icon-set` (8.2.15) is gone. Only the Icon leaf and the toast module import a glyph. The bundled runtime mirror carries the fe-stack catalog and the canon pins with `@heroicons/react` 2.2.0 and `@starci/heroicons` 0.3.3.
|
|
639
647
|
|
|
640
648
|
## 8.2.15 - 2026-10-13
|
|
641
649
|
|
|
642
|
-
- Changed: carry the runtime mirror of HFS manifest 3.0.0 (one front-end standard for the lite and the full edition
|
|
650
|
+
- Changed: carry the runtime mirror of HFS manifest 3.0.0 (one front-end standard for the lite and the full edition) and the canon pins for Grammar 0.9.14, HFS 4.2.14, jest-preset 2.2.7 and CLI 1.2.14.
|
|
643
651
|
- Added: `fe-stack-import` (law `fe-stack`, finding code `FE_STACK_FORBIDDEN`): an import (static, re-export, dynamic, `require`, type-only included) of a package any concern of the fe-stack catalog (`runtime/knowledge/hfs/fe-stack.yaml`) forbids, and `@supabase/*` outside `modules/auth` (slot `fe.modules.auth`), are refused. The catalog is read from the runtime copy; a missing copy stops the lint run with the fix.
|
|
644
652
|
- Changed: the transport law follows the Apollo GraphQL + axios API layer. `fetch` (and `Request`, `EventSource`, `sendBeacon`) is legal in every file of the API layer (`modules/api`, the shared api package), `@apollo/client` only there, `axios` only in its REST calls (`modules/api/rest/`), `socket.io-client` only in `hooks/socketio/` (`fetch-only-in-api-client`, message `placed`); `client-fetch-has-signal` and `no-shared-transport-state` judge the whole layer (the generated `graphql/__generated__/` excepted); `no-hand-typed-wire` admits GraphQL documents in the API layer (one file per operation) and refuses them elsewhere; `one-outcome-union` names `GraphQLResponse` in `modules/api/graphql/types.ts` as the one vocabulary and also reads a `success` discriminant. The `modules/db` outcome home and the server reader role are gone.
|
|
645
653
|
- Changed: `hooks-folder-holds-hooks-only` judges the hooks families `hooks/{swr,rhf,zustand,socketio,effects,reuseables}` by the files their slots name (message `family`); `SwrSideEffects.tsx` and `SocketIoSideEffects.tsx` are legal `.tsx` files of `hooks/`.
|
package/dist/control-height.js
CHANGED
|
@@ -3,7 +3,7 @@ import { attributeValue, stringOf } from "./lib/ast.js";
|
|
|
3
3
|
import { importOf } from "./lib/bindings.js";
|
|
4
4
|
import { defineRule } from "./lib/rule.js";
|
|
5
5
|
const GRAMMAR_ENTRY = /^@starci\/grammar(?:\/(?:common|core|offset-pop))?$/;
|
|
6
|
-
const CONTROLS = new Set(["Button", "IconButton", "Switch", "Input", "SearchField", "Select", "Tabs", "
|
|
6
|
+
const CONTROLS = new Set(["Button", "IconButton", "Switch", "Input", "SearchField", "Select", "Tabs", "Textarea", "NumberField", "ComboBox"]);
|
|
7
7
|
/** A marketing hero call to action on a landing page is the one place the 48px step is allowed. */
|
|
8
8
|
const LANDING_PATH = /[\\/](?:landing|hero|marketing)[\\/]|(?:Landing|Hero)[^\\/]*[\\/]/;
|
|
9
9
|
/** The default size and its two spellings: the vendor `md` and Grammar's `control` are the same 40px height. */
|
package/dist/drawing.js
CHANGED
|
@@ -94,7 +94,7 @@ export const basePropsAtom = defineRule({
|
|
|
94
94
|
action: "`{{path}}` is a function inside `props`. Actions live in `on`; feature composition may receive named `render` callbacks that take atoms and return rendered blocks.",
|
|
95
95
|
onData: "`on.{{key}}` is not an action. `on` holds functions only; data belongs in `props`.",
|
|
96
96
|
member: "`{{key}}` is not part of the pure contract. A pure half takes `shape`, `props` and `on`{{children}}.",
|
|
97
|
-
renamed: "
|
|
97
|
+
renamed: "The drawn shape is named `shape`, never `state`: rename it `shape`.",
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
100
|
create(context) {
|
package/dist/function-budget.js
CHANGED
|
@@ -11,7 +11,7 @@ export const functionLineBudget = defineRule({
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
create(context) {
|
|
14
|
-
//
|
|
14
|
+
// A manifest without `ruleParams.functionLines` gets the cap of 80 lines.
|
|
15
15
|
const max = hfsOf(context).ruleParams.functionLines ?? 80;
|
|
16
16
|
if (!Number.isInteger(max) || max < 1)
|
|
17
17
|
throw new RangeError("ruleParams.functionLines must be a positive integer");
|
package/dist/index.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare const rules: Record<string, Rule>;
|
|
|
38
38
|
*
|
|
39
39
|
* Every FE canon rule is an error. Existing debt is fixed before adoption; lowering architecture
|
|
40
40
|
* to warn teaches every later author that the boundary is optional and is not a supported rollout. The one
|
|
41
|
-
* exception is the closed counting cohort of lib/config.ts (`COUNTING`),
|
|
41
|
+
* exception is the closed counting cohort of lib/config.ts (`COUNTING`), a warn for one release.
|
|
42
42
|
*/
|
|
43
43
|
export declare const recommended: Record<string, "error" | "warn">;
|
|
44
44
|
/** Flat-config options that make inline directives ineffective rather than merely forbidden. */
|
package/dist/index.js
CHANGED
|
@@ -132,7 +132,7 @@ export const rules = Object.fromEntries(CONTRIBUTIONS.flatMap((entry) => Object.
|
|
|
132
132
|
*
|
|
133
133
|
* Every FE canon rule is an error. Existing debt is fixed before adoption; lowering architecture
|
|
134
134
|
* to warn teaches every later author that the boundary is optional and is not a supported rollout. The one
|
|
135
|
-
* exception is the closed counting cohort of lib/config.ts (`COUNTING`),
|
|
135
|
+
* exception is the closed counting cohort of lib/config.ts (`COUNTING`), a warn for one release.
|
|
136
136
|
*/
|
|
137
137
|
export const recommended = Object.fromEntries(CONTRIBUTIONS.flatMap((entry) => Object.entries(entry.recommended)));
|
|
138
138
|
/** Flat-config options that make inline directives ineffective rather than merely forbidden. */
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -28,13 +28,12 @@ export declare const IGNORED: readonly string[];
|
|
|
28
28
|
*/
|
|
29
29
|
export declare const BORROWED: Readonly<Record<string, "error">>;
|
|
30
30
|
/**
|
|
31
|
-
* The counting cohort: a rule
|
|
31
|
+
* The counting cohort: a rule that ships at `warn` for one release while a codemod moves apps onto the API
|
|
32
32
|
* it asks for, each with the HFS rule id it enforces. `starci app check --gate lint` reports and counts its findings and never fails
|
|
33
33
|
* on them; the next cohort moves the rule to error and deletes its entry. No other rule may be below error.
|
|
34
34
|
*/
|
|
35
35
|
export declare const COUNTING: Readonly<Record<string, {
|
|
36
36
|
readonly rule: string;
|
|
37
|
-
readonly ruling: string;
|
|
38
37
|
}>>;
|
|
39
38
|
/**
|
|
40
39
|
* The flat config of one front-end repository.
|
package/dist/lib/config.js
CHANGED
|
@@ -41,12 +41,12 @@ export const BORROWED = Object.freeze({
|
|
|
41
41
|
});
|
|
42
42
|
const levelOf = (setting) => (Array.isArray(setting) ? setting[0] : setting);
|
|
43
43
|
/**
|
|
44
|
-
* The counting cohort: a rule
|
|
44
|
+
* The counting cohort: a rule that ships at `warn` for one release while a codemod moves apps onto the API
|
|
45
45
|
* it asks for, each with the HFS rule id it enforces. `starci app check --gate lint` reports and counts its findings and never fails
|
|
46
46
|
* on them; the next cohort moves the rule to error and deletes its entry. No other rule may be below error.
|
|
47
47
|
*/
|
|
48
48
|
export const COUNTING = Object.freeze({
|
|
49
|
-
"starci-fe/no-spacing-utility": { rule: "R350"
|
|
49
|
+
"starci-fe/no-spacing-utility": { rule: "R350" },
|
|
50
50
|
});
|
|
51
51
|
/**
|
|
52
52
|
* The flat config of one front-end repository.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve a `use*` import that comes from the app's own hooks folders (`hooks/swr`, `hooks/<domain>`, `hooks/zustand/<store>`...) by
|
|
3
|
-
* TypeScript symbol resolution, never by the spelling of the name (R56 `FE_HOOKS_ARE_HOOKS
|
|
3
|
+
* TypeScript symbol resolution, never by the spelling of the name (R56 `FE_HOOKS_ARE_HOOKS`).
|
|
4
4
|
*
|
|
5
5
|
* A composite product hook is built from the hooks beneath it: `hooks/<domain>/use<Name>.ts` composes the `use{Query,Mutate}<X>Swr`
|
|
6
6
|
* wrappers of `hooks/swr`. The import is followed through barrels and re-exports to the declaration, and counts only when that declaration
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const PACKAGE_ROOT: string;
|
|
3
3
|
/**
|
|
4
4
|
* The runtime of the installed @starci/hfs (its peer, a same-minor range): the slot manifest, the architecture machine and its catalogs are read from it
|
|
5
|
-
* at run time, never from a copy bundled here, so an hfs data change releases hfs alone
|
|
5
|
+
* at run time, never from a copy bundled here, so an hfs data change releases hfs alone.
|
|
6
6
|
*/
|
|
7
7
|
export declare const RUNTIME_ROOT: string;
|
|
8
8
|
/** The files this package keeps of its own in runtime/ (the project graph rule, the jsdoc, sonar and next helpers, the package-scripts template). */
|
package/dist/lib/package-root.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from "node:url";
|
|
|
9
9
|
export const PACKAGE_ROOT = fileURLToPath(new URL("../..", import.meta.url));
|
|
10
10
|
/**
|
|
11
11
|
* The runtime of the installed @starci/hfs (its peer, a same-minor range): the slot manifest, the architecture machine and its catalogs are read from it
|
|
12
|
-
* at run time, never from a copy bundled here, so an hfs data change releases hfs alone
|
|
12
|
+
* at run time, never from a copy bundled here, so an hfs data change releases hfs alone.
|
|
13
13
|
*/
|
|
14
14
|
export const RUNTIME_ROOT = join(dirname(createRequire(import.meta.url).resolve("@starci/hfs/package.json")), "runtime");
|
|
15
15
|
/** The files this package keeps of its own in runtime/ (the project graph rule, the jsdoc, sonar and next helpers, the package-scripts template). */
|
package/dist/ui-rulings.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ export declare const rules: {
|
|
|
7
7
|
"selection-fill-no-check": import("./lib/rule.js").Rule<"indicator", []>;
|
|
8
8
|
"no-grammar-internal-selector": import("./lib/rule.js").Rule<"internal", []>;
|
|
9
9
|
};
|
|
10
|
-
/** Both
|
|
10
|
+
/** Both rules are universal errors in the frontend canon. */
|
|
11
11
|
export declare const recommended: Recommended;
|
package/dist/ui-rulings.js
CHANGED
|
@@ -117,5 +117,5 @@ export const rules = {
|
|
|
117
117
|
"selection-fill-no-check": selectionFillNoCheck,
|
|
118
118
|
"no-grammar-internal-selector": noGrammarInternalSelector,
|
|
119
119
|
};
|
|
120
|
-
/** Both
|
|
120
|
+
/** Both rules are universal errors in the frontend canon. */
|
|
121
121
|
export const recommended = Object.fromEntries(Object.keys(rules).map((name) => [`starci-fe/${name}`, "error"]));
|
package/docs/control-height.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Control height (CONTROL-HEIGHT-1)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
One control height, 40px (HeroUI's own `h-10`), is the default of every standalone Grammar control: Button, IconButton, Input, SearchField, Select, Tabs, Switch, the chrome Avatar, Textarea and the composer send button. Grammar draws it; an app never states it.
|
|
4
4
|
|
|
5
5
|
| Rule | Finding code | Required behavior |
|
|
6
6
|
| --- | --- | --- |
|
package/docs/grammar-shim.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Grammar shims (R321)
|
|
2
2
|
|
|
3
|
-
Law module: `grammar-shim.mjs`. HFS rule: R321. Knowledge: `contexts/code/fe/ui.md` FE-UI-1 (the app makes no visual choice; the Grammar owns every visual element)
|
|
3
|
+
Law module: `grammar-shim.mjs`. HFS rule: R321. Knowledge: `contexts/code/fe/ui.md` FE-UI-1 (the app makes no visual choice; the Grammar owns every visual element).
|
|
4
4
|
|
|
5
5
|
An app imports a Grammar component where it renders it. It never hands one on from an app path under its own name: such a shim makes one app green while the defect it works around (a missing `"use client"`, a wrong prop, a broken export) stays in the Grammar for every other app. The defect is reported to the Grammar instead; an op files `blocked` naming the package, the component and the error.
|
|
6
6
|
|
package/docs/hooks-folder.md
CHANGED
|
@@ -8,7 +8,7 @@ Every rule below is an error in `starciFeConfig`; none can be switched off or su
|
|
|
8
8
|
|
|
9
9
|
## `starci-fe/hooks-folder-holds-hooks-only`
|
|
10
10
|
|
|
11
|
-
`hooks/` holds `use*.ts` hooks under the names their family slot gives and, per domain, one `<domain>.shared.ts`; nothing else. A hook file exports one hook; `server-only` and `next/headers` are never imported there. A hook is a function that calls a hook: a React, SWR or Redux hook, a `use*` imported from the app's own `hooks/` folders (a `hooks/swr` wrapper or a sibling domain hook, resolved by TypeScript symbol resolution through barrels; that hook's own file is judged when it is linted), or a library hook from an explicit list (`next-intl` `useTranslations`/`useLocale`/`useFormatter`/`useNow`/`useTimeZone`/`useMessages`, `next/navigation`, `next-themes` `useTheme`, `react-hook-form`, `zustand`). A `use*` from outside every `hooks/` folder or an unlisted library is not a hook by its spelling, and a file that exports a helper, a constant or a component still fails
|
|
11
|
+
`hooks/` holds `use*.ts` hooks under the names their family slot gives and, per domain, one `<domain>.shared.ts`; nothing else. A hook file exports one hook; `server-only` and `next/headers` are never imported there. A hook is a function that calls a hook: a React, SWR or Redux hook, a `use*` imported from the app's own `hooks/` folders (a `hooks/swr` wrapper or a sibling domain hook, resolved by TypeScript symbol resolution through barrels; that hook's own file is judged when it is linted), or a library hook from an explicit list (`next-intl` `useTranslations`/`useLocale`/`useFormatter`/`useNow`/`useTimeZone`/`useMessages`, `next/navigation`, `next-themes` `useTheme`, `react-hook-form`, `zustand`). A `use*` from outside every `hooks/` folder or an unlisted library is not a hook by its spelling, and a file that exports a helper, a constant or a component still fails.
|
|
12
12
|
|
|
13
13
|
**Invalid** (`src/hooks/course/readCourse.ts`)
|
|
14
14
|
|
package/docs/surface-rules.md
CHANGED
|
@@ -59,7 +59,7 @@ const Frame = () => (
|
|
|
59
59
|
|
|
60
60
|
## `starci-fe/no-table-in-card`
|
|
61
61
|
|
|
62
|
-
Finding code: `FE_TABLE_IN_CARD` (R351). A `DataTable` is not placed in a `SurfaceCard`. Plain rows with a few facts are a `SurfaceCard kind="list"` with the label outside and the note in its `footer`; a table that compares records across many columns sits in its section with no card around it. The rule reads the file: a Grammar `DataTable` enclosed by a Grammar `SurfaceCard` element is a finding, and so is a `DataTable` rendered by a component of the same file (a declaration, a variable's function, a `memo` or `forwardRef` wrapper, followed through other components of the file) that a `SurfaceCard` encloses. A card in another file that renders a table component is judged where the card is written. There is no inline exemption; a table
|
|
62
|
+
Finding code: `FE_TABLE_IN_CARD` (R351). A `DataTable` is not placed in a `SurfaceCard`. Plain rows with a few facts are a `SurfaceCard kind="list"` with the label outside and the note in its `footer`; a table that compares records across many columns sits in its section with no card around it. The rule reads the file: a Grammar `DataTable` enclosed by a Grammar `SurfaceCard` element is a finding, and so is a `DataTable` rendered by a component of the same file (a declaration, a variable's function, a `memo` or `forwardRef` wrapper, followed through other components of the file) that a `SurfaceCard` encloses. A card in another file that renders a table component is judged where the card is written. There is no inline exemption; a table complex enough to sit in a card is named in this rule.
|
|
63
63
|
|
|
64
64
|
Invalid:
|
|
65
65
|
|
|
@@ -127,7 +127,7 @@ const Filter = () => <FilterButtonGroup label="Team" options={options} value={te
|
|
|
127
127
|
|
|
128
128
|
## `starci-fe/no-heading-above-card`
|
|
129
129
|
|
|
130
|
-
Finding code: `FE_HEADING_ABOVE_CARD` (R354). A card
|
|
130
|
+
Finding code: `FE_HEADING_ABOVE_CARD` (R354). A card carries its own label, so a heading over it is wrong. A Grammar `Section` (not `kind="list"`) whose only child is one `SurfaceCard` is refused, and so is a card whose `ariaLabel` is the `Section`'s `title`. Several cards under one `Section` stay legal, and a `Section` holding anything else is not judged. The fix moves the title to the card's `label`, the count to `fact`, the action to `labelEnd` and the note to `footer`.
|
|
131
131
|
|
|
132
132
|
Invalid:
|
|
133
133
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starci/eslint-canon-fe",
|
|
3
|
-
"version": "9.16.
|
|
3
|
+
"version": "9.16.2",
|
|
4
4
|
"description": "Universal front-end lint laws for TypeScript and Next.js, independent of the selected Grammar family.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"node": ">=22.13.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@starci/hfs": "~
|
|
54
|
+
"@starci/hfs": "~6.0.0",
|
|
55
55
|
"eslint": ">=9",
|
|
56
56
|
"eslint-plugin-react-hooks": ">=7",
|
|
57
57
|
"typescript": ">=5.9"
|