@starci/eslint-canon-fe 7.1.0 → 7.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.1.1 - 2026-10-01
4
+
5
+ - Fixed: every rule failed to load in product repositories ("the managed package-scripts template ... cannot be found next to the runtime"): the bundled runtime now carries the data files the architecture machine reads beside its code (the managed package-scripts templates, canon-pins and the Sonar gate). A new runtime spec, `tests/canon-packed-load.spec.mjs`, installs each canon from its packed tarball into a real HFS repository and requires every rule to load.
6
+
3
7
  ## 7.1.0 - 2026-10-01
4
8
 
5
9
  - New: the `project-graph` law: the TS-attached front-end architecture checks (routes, owners, paths) as eslint rules at error, from one cached project graph per lint run.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starci/eslint-canon-fe",
3
- "version": "7.1.0",
3
+ "version": "7.1.1",
4
4
  "description": "The StarCi front-end lint canon: every rule its laws publish, gathered as one flat-config plugin and attached by one factory.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -0,0 +1,170 @@
1
+ schema: starci/canon-pins@1
2
+ purpose: >-
3
+ The exact version of every dependency a StarCi product repository pins. One version per dependency for the whole
4
+ family. Raising a version is a change to this file first (with the package bump when it is a @starci package),
5
+ then the repositories' own upgrade lane (each sets the exact version and reinstalls; nothing else installs a @starci package). Read on 2026-09-29 from the packages under
6
+ .claude/packages and from the installed node_modules of nivo-backend, nivo-fe, starci-next, starci-next-fe,
7
+ mia-mia-backend and miamia-fe; where they disagreed the newest version installed in more than one repository
8
+ won, and the runtime's own version won for @starci packages.
9
+ pins:
10
+ # --- @starci packages. Every @starci package is a PUBLISHED npm package (install: registry): a product repository
11
+ # installs the exact pinned version from the npm registry in the root and every workspace package.json, never `file:`.
12
+ '@starci/grammar':
13
+ version: 0.8.0
14
+ group: starci
15
+ install: registry
16
+ side: fe
17
+ source: packages/grammar/package.json
18
+ why: nivo-fe pins 0.4.11 and 0.5.0 in one workspace, starci-next-fe 0.5.1, miamia-fe 0.5.0; the runtime source is 0.8.0 (the brand layer sets `--font-sans` and `--font-mono`; the grammar reads them; 0.7.2 added the Input tel kind and IconButton disclosure props).
19
+ '@starci/eslint-canon-be':
20
+ version: 2.1.1
21
+ group: starci
22
+ install: registry
23
+ side: be
24
+ source: packages/eslint/be/package.json
25
+ why: '2.0.0 (C0 release): starciBeConfig({ hfs: loadHfs(import.meta.url) }) typed factory and the BE-CONVENTION laws (R36 sql-text-only, R83 no-repository-class, R85/R87/R89 service-deps, R43 config-parsed-in-main, R47/R48 test world, R95 operations, R98-R101 builders).'
26
+ '@starci/eslint-canon-fe':
27
+ version: 7.1.1
28
+ group: starci
29
+ install: registry
30
+ side: fe
31
+ source: packages/eslint/fe/package.json
32
+ why: '7.0.0: the front end has no tests (test rules removed, FE_NO_TESTS R97 in hfs); no-vietnamese-in-source (R91).'
33
+ '@starci/stylelint-canon':
34
+ version: 2.0.1
35
+ group: starci
36
+ install: registry
37
+ side: fe
38
+ source: packages/stylelint/package.json
39
+ why: '2.0.1 accepts `--font-sans` and `--font-mono` in the brand layer (the vocabulary follows the grammar 0.8.0). 2.0.0 adds status-contrast (HeroUI soft pairs measured per theme), fixes brand-layer-shape on the shared :root,.light,.dark block and the info soft pair, and derives appTokens with loadAppTokens(import.meta.url) for the managed one-line stylelint.config.mjs.'
40
+ '@starci/tsconfig':
41
+ version: 2.0.0
42
+ group: starci
43
+ install: registry
44
+ side: both
45
+ source: packages/tsconfig/package.json
46
+ '@starci/prettier-config':
47
+ version: 1.0.0
48
+ group: starci
49
+ install: registry
50
+ side: both
51
+ source: packages/prettier-config/package.json
52
+ '@starci/jest-preset':
53
+ version: 2.1.0
54
+ group: starci
55
+ install: registry
56
+ side: be
57
+ source: packages/jest-preset/package.json
58
+ why: '2.1.0: four projects on the test world, the unit kit (mockEntityManager, fakeTransaction, fakeIds, FakeClock, Outcome matchers) and the recordingOutbox claim side.'
59
+ '@starci/hfs':
60
+ version: 3.0.0
61
+ group: starci
62
+ install: registry
63
+ side: both
64
+ source: packages/hfs/package.json
65
+ why: '2.0.0 (C0 release): the BE-CONVENTION machine, emit-contracts (GraphQL SDL and OpenAPI from the typed operation table), the four-project test layout, FE has no tests, repo.scripts slot, secrets guard in work-hygiene, rule ids R<2-3 digits>.'
66
+ # --- tooling
67
+ typescript:
68
+ version: 5.9.3
69
+ group: tooling
70
+ side: both
71
+ why: all six repositories resolve 5.9.3 already; the declared ranges (^5, ^5.7.3) become exact.
72
+ prettier:
73
+ version: 3.9.6
74
+ group: tooling
75
+ side: both
76
+ why: only nivo-backend has it installed (3.9.6); the other five adopt it with the formatter change.
77
+ stylelint:
78
+ version: 17.15.0
79
+ group: tooling
80
+ side: fe
81
+ why: no repository has it installed; 17.15.0 is the current release, and the canon plugin needs the ESM-only 17 line.
82
+ postcss-value-parser:
83
+ version: 4.2.0
84
+ group: tooling
85
+ side: fe
86
+ why: peer of @starci/stylelint-canon (it parses declaration values); 4.2.0 is what stylelint 17.15.0 itself resolves.
87
+ eslint:
88
+ version: 9.39.5
89
+ group: tooling
90
+ side: both
91
+ why: five repositories resolve 9.39.5, nivo-backend 9.39.4.
92
+ eslint-plugin-react-hooks:
93
+ version: 7.1.1
94
+ group: tooling
95
+ side: fe
96
+ why: '2.0.0 (C0 release): the BE-CONVENTION machine, emit-contracts (GraphQL SDL and OpenAPI from the typed operation table), the four-project test layout, FE has no tests, repo.scripts slot, secrets guard in work-hygiene, rule ids R<2-3 digits>.'
97
+ '@types/node':
98
+ version: 22.20.4
99
+ group: tooling
100
+ side: both
101
+ why: nivo-fe resolves 20.19.43 and nivo-backend 22.20.0; the package engines are node >=22.
102
+ # --- test
103
+ jest:
104
+ version: 29.7.0
105
+ group: test
106
+ side: be
107
+ ts-jest:
108
+ version: 29.4.12
109
+ group: test
110
+ side: be
111
+ '@types/jest':
112
+ version: 29.5.14
113
+ group: test
114
+ side: be
115
+ # --- framework
116
+ next:
117
+ version: 16.1.6
118
+ group: framework
119
+ side: fe
120
+ react:
121
+ version: 19.2.3
122
+ group: framework
123
+ side: fe
124
+ react-dom:
125
+ version: 19.2.3
126
+ group: framework
127
+ side: fe
128
+ '@nestjs/core':
129
+ version: 11.2.5
130
+ group: framework
131
+ side: be
132
+ why: nivo-backend resolves 11.1.27, starci-next and mia-mia-backend 11.2.5.
133
+ '@nestjs/common':
134
+ version: 11.2.5
135
+ group: framework
136
+ side: be
137
+ '@nestjs/platform-express':
138
+ version: 11.2.5
139
+ group: framework
140
+ side: be
141
+ '@nestjs/testing':
142
+ version: 11.2.5
143
+ group: framework
144
+ side: be
145
+ '@nestjs/terminus':
146
+ version: 11.1.1
147
+ group: framework
148
+ side: be
149
+ why: readiness probes with dependency indicators use Terminus (the liveness route of the hfs sync --init skeleton does not, being a thin door over the liveness service); nivo-backend, starci-next and mia-mia-backend all resolve 11.1.1.
150
+ next-intl:
151
+ version: 4.13.6
152
+ group: framework
153
+ side: fe
154
+ why: every HFS front end uses next-intl with the [locale] segment (hfs sync --init writes it); nivo-fe resolves 4.13.6.
155
+ supertest:
156
+ version: 7.3.0
157
+ group: tooling
158
+ side: be
159
+ why: the e2e world of a back end calls the app over HTTP (/health/live in the skeleton); starci-next and mia-mia-backend resolve 7.3.0, nivo-backend 7.2.2.
160
+ # --- ui
161
+ '@heroui/react':
162
+ version: 3.2.6
163
+ group: ui
164
+ side: fe
165
+ why: nivo-fe resolves 3.2.4, starci-next-fe and miamia-fe 3.2.6.
166
+ '@heroui/styles':
167
+ version: 3.2.6
168
+ group: ui
169
+ side: fe
170
+ why: nivo-fe resolves 3.2.4, starci-next-fe and miamia-fe 3.2.6.
@@ -0,0 +1,86 @@
1
+ schema: starci/sonar-gate@1
2
+ id: sonar-gate
3
+ title: The Sonar quality gate every product is held to
4
+ purpose: |
5
+ The one place the Sonar thresholds live. A product repository never restates them: its
6
+ .starcistacks/application-stacks.yaml `services.sonar.qualityGate` names the gate below, and
7
+ scripts/checks/sonar-local.mjs (1) makes the local SonarQube's gate of that name carry exactly these
8
+ conditions and selects it for the project, and (2) judges an op's slice - the lines it changed - against
9
+ the same numbers. Code-writing ops cannot settle done while the slice is red
10
+ (scripts/kernel/sonar-settle.mjs). Changing a number here changes every repository on the next scan.
11
+ The gate has two parts: `newCode` (the recent work: duplication, blocker/critical issues, hotspots) and
12
+ `overall` (the whole code: no imported HFS, ESLint or stylelint finding, no duplicated-lines excess, no cognitive-
13
+ complexity issue). The one Sonar mechanism of the HFS canon is packages/hfs/README.md section "Sonar".
14
+ gate:
15
+ name: starci-new-code
16
+ # A project with no new-code baseline judges the whole project as new code (nivo inc-f92febebbb64); a fixed
17
+ # window keeps "new code" the recent work on main, so the server gate is passable on a healthy main.
18
+ newCodePeriod: {type: NUMBER_OF_DAYS, value: 30}
19
+ newCode:
20
+ # Sonar holds NO coverage condition: unit coverage is the runner's job (jest per-file 100 on `*.service.ts`), never an lcov import.
21
+ # SonarQube's ignoreSmallChanges: fewer changed lines than this are not held to duplication.
22
+ ignoreBelowChangedLines: 20
23
+ duplication:
24
+ metric: new_duplicated_lines_density
25
+ maxPercent: 3
26
+ issues:
27
+ # An open issue of these severities on a changed line fails the slice; lesser ones are listed, never blocking.
28
+ blockingSeverities: [BLOCKER, CRITICAL]
29
+ metrics: {BLOCKER: new_blocker_violations, CRITICAL: new_critical_violations}
30
+ max: 0
31
+ hotspots:
32
+ metric: new_security_hotspots_reviewed
33
+ minReviewedPercent: 100
34
+ unreviewedMax: 0
35
+ # The whole code, not only the new code. Every finding of the HFS canon reaches Sonar through ONE entry, `hfs lint`
36
+ # (packages/hfs, contract changes hfs-sonar-import and hfs-lint-entry), which writes ONE file, reports/lint.sonar.json
37
+ # (`npm run lint -- --sonar reports/lint.sonar.json`), named by sonar.externalIssuesReportPaths; the gate holds the open-issue count of
38
+ # the whole project at zero. The file carries three engines:
39
+ # starci-hfs the repository findings of `hfs check` (managed files, tree, pins, CI, contracts; the rule id is the finding code)
40
+ # eslint ESLint's json over the repository (the BE and FE canon plugins alike, per-file and project-graph rules)
41
+ # stylelint stylelint's json over the style glob (front ends)
42
+ # The engines share ONE placement rule (a finding on a file Sonar does not index is filed on the first source file); Sonar's own
43
+ # ESLint import (sonar.eslint.reportPaths) is not used because it drops such issues.
44
+ # A SonarQube gate condition cannot filter issues by engine, so the condition is the project's open issues (`violations`,
45
+ # overall code): the three engines above are the imports it counts, and every native Sonar issue counts with them. That is
46
+ # stricter than the engines alone and it is intended: a project that meets this gate has no open issue of any origin.
47
+ overall:
48
+ issues:
49
+ metric: violations
50
+ max: 0
51
+ engines: [starci-hfs, eslint, stylelint]
52
+ # HFS_DUPLICATE_CODE (R21): duplicated lines density of the whole project, the Sonar enforcer of the machine's clone check.
53
+ # SonarJS runs its own token-based detection (sonar.cpd.* minimums are not read for TypeScript), so ruleParams.<profile>.duplicateBlock
54
+ # is enforced by the machine and imported as starci-hfs issues, and this density is the Sonar-side backstop.
55
+ duplication:
56
+ metric: duplicated_lines_density
57
+ maxPercent: 3
58
+ # HFS_SIZE_GROWTH (R20): the cognitive complexity of a function is the Sonar rule S3776 (typescript:S3776, Sonar way, default
59
+ # threshold); an open S3776 issue is an open issue of `overall.issues`, so the zero-issue condition is its gate.
60
+ cognitiveComplexity:
61
+ rule: typescript:S3776
62
+ via: overall.issues
63
+ # The Sonar enforcers of the rule catalog (knowledge/hfs/rules.yaml): the failure code each condition above is the gate of.
64
+ enforces:
65
+ - {rule: R20, code: HFS_SIZE_GROWTH, enforcer: cognitive-complexity, condition: cognitiveComplexity}
66
+ - {rule: R21, code: HFS_DUPLICATE_CODE, enforcer: duplicated-lines-density, condition: duplication}
67
+ - {rule: R21, code: HFS_DUPLICATE_SYMBOL, enforcer: duplicated-lines-density, condition: duplication}
68
+ # Ops that write product code: each runs sonar-local on its own change and cannot settle done while the gate is red.
69
+ enforcedOps: [backend.implement, interface.implement, code.refactor]
70
+ reasoning: |
71
+ Chosen against the four projects the local server holds on 2026-09-29 (whole-project duplicated lines
72
+ 1.6 / 2.1 / 1.7 / 0.0 percent), so new code that meets them is at or below what main already carries.
73
+ no coverage condition: the unit project fails below its per-file 100 threshold on `*.service.ts`, so Sonar never
74
+ imports an lcov report and never judges coverage.
75
+ duplication 3: the Sonar way value; the worst project today is 2.1, so 3 rejects a real copy-paste block and
76
+ passes ordinary work.
77
+ blocker/critical 0: the two severities that are defects, not style. main carries old debt of both kinds
78
+ (nivo-backend 3 blocker, 137 critical), so the SLICE verdict reads only changed lines and never main's backlog;
79
+ major and lower are reported on the summary and never fail a slice.
80
+ overall issues 0 and overall duplication 3: the server gate is also the owner's definition of done for the HFS canon:
81
+ a repository that carries any open ESLint, stylelint or HFS finding is not green, whatever the age of the line. The
82
+ op slice keeps judging changed lines (an op cannot fix a repository's whole backlog); the dashboard and CI show the
83
+ whole-project condition. Adopting a repository therefore means clearing its imported findings, which `hfs check`,
84
+ eslint and stylelint already demand at land.
85
+ hotspots 0 unreviewed: a hotspot is a question the author must answer; on changed lines it is answered in the
86
+ same slice.
@@ -0,0 +1,19 @@
1
+ {
2
+ "scripts": {
3
+ "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
4
+ {{appScripts}}
5
+ "typecheck": "tsc -p tsconfig.json",
6
+ "typecheck:tests": "tsc -p src/tests/tsconfig.json",
7
+ "lint": "hfs lint",
8
+ "lint:fix": "hfs lint --fix",
9
+ "format": "prettier --write .",
10
+ "format:check": "prettier --check .",
11
+ "test": "jest --selectProjects unit --coverage",
12
+ "test:affected": "jest --selectProjects unit --passWithNoTests",
13
+ "test:integration": "npm run typecheck:tests && jest --selectProjects integration",
14
+ "test:e2e": "npm run typecheck:tests && jest --selectProjects e2e",
15
+ "test:contract": "npm run typecheck:tests && jest --selectProjects contract",
16
+ "test:stack": "starci-test-stack",
17
+ "contract:emit": "hfs emit-contracts"
18
+ }
19
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "scripts": {
3
+ "prepare": "husky",
4
+ {{appScripts}}
5
+ "codegen": "npm run codegen --workspaces --if-present",
6
+ "build": "npm run build --workspaces --if-present",
7
+ "typecheck": "npm run typecheck --workspaces --if-present",
8
+ "lint": "npm run codegen --silent && hfs lint --stylelint \"{{styleGlob}}\"",
9
+ "lint:fix": "npm run codegen --silent && hfs lint --fix --stylelint \"{{styleGlob}}\"",
10
+ "format": "prettier --write .",
11
+ "format:check": "prettier --check ."
12
+ }
13
+ }