gennady 0.8.4-draft.2 → 0.8.4-draft.3

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.
Files changed (146) hide show
  1. package/ai/directives/sdd-v2/root.directive.xml +36 -3
  2. package/ai/directives/sdd-v2/router.directive.xml +22 -1
  3. package/ai/kit/templates/sdd-v2/root.directive.hbs +11 -3
  4. package/ai/kit/templates/sdd-v2/router.directive.hbs +22 -1
  5. package/ai/skills/agent-inbox/SKILL.md +1 -1
  6. package/ai/skills/sdd/SKILL.md +5 -3
  7. package/ai/skills/sdd-audit/SKILL.md +5 -2
  8. package/ai/skills/sdd-check/SKILL.md +2 -2
  9. package/ai/skills/sdd-code-review/SKILL.md +4 -1
  10. package/ai/skills/sdd-critic/SKILL.md +5 -2
  11. package/ai/skills/sdd-execute/SKILL.md +5 -2
  12. package/ai/skills/sdd-reconcile/SKILL.md +5 -2
  13. package/ai/skills/sdd-scaffold/SKILL.md +5 -2
  14. package/dist/ai/directives/sdd-v2/root.directive.xml +36 -3
  15. package/dist/ai/directives/sdd-v2/router.directive.xml +22 -1
  16. package/dist/ai/kit/templates/sdd-v2/root.directive.hbs +11 -3
  17. package/dist/ai/kit/templates/sdd-v2/router.directive.hbs +22 -1
  18. package/dist/ai/skills/agent-inbox/SKILL.md +1 -1
  19. package/dist/ai/skills/sdd/SKILL.md +5 -3
  20. package/dist/ai/skills/sdd-audit/SKILL.md +5 -2
  21. package/dist/ai/skills/sdd-check/SKILL.md +2 -2
  22. package/dist/ai/skills/sdd-code-review/SKILL.md +4 -1
  23. package/dist/ai/skills/sdd-critic/SKILL.md +5 -2
  24. package/dist/ai/skills/sdd-execute/SKILL.md +5 -2
  25. package/dist/ai/skills/sdd-reconcile/SKILL.md +5 -2
  26. package/dist/ai/skills/sdd-scaffold/SKILL.md +5 -2
  27. package/dist/chunks/{classify-mr-stage.logic-BiCHTmPp.js → classify-mr-stage.logic-CazmQDwZ.js} +2 -2
  28. package/dist/chunks/{config-index-9VHWSDQD.js → config-index-DU8-FEjq.js} +1 -1
  29. package/dist/chunks/{devtools-b0DwO1x_.js → devtools-1JmXJjUG.js} +1 -1
  30. package/dist/chunks/{eval.cmd-CwNPaNJd.js → eval.cmd-CBANnOFG.js} +1 -1
  31. package/dist/chunks/{help-D5cXtdMI.js → help-DVloaFF5.js} +1 -1
  32. package/dist/chunks/{index-BVnJEutp.js → index-2xhpqJtd.js} +2 -2
  33. package/dist/chunks/{index-RR5OUxje.js → index-AxsLBUAx.js} +14 -14
  34. package/dist/chunks/{index-CUkeTGqM.js → index-B7sydB0W.js} +2 -2
  35. package/dist/chunks/{index-CMCn9ErF.js → index-BKxk4zOz.js} +2 -2
  36. package/dist/chunks/{index-Db13NlHh.js → index-BNMmX_Mv.js} +21 -21
  37. package/dist/chunks/{index-CmQO-RmM.js → index-BPzldG3a.js} +2 -2
  38. package/dist/chunks/{index-BOQl7F_Z.js → index-BQlFDvKW.js} +2 -2
  39. package/dist/chunks/{index-RzkvIfJQ.js → index-Baq7RL1L.js} +3 -3
  40. package/dist/chunks/index-BbPiwvY9.js +2 -0
  41. package/dist/chunks/{index-ClJLPEUB.js → index-BreGNLJ_.js} +1 -1
  42. package/dist/chunks/{index-DjSafAkN.js → index-BslPwGtM.js} +2 -2
  43. package/dist/chunks/{index-DiMFxS0z.js → index-BtCUN2fZ.js} +16 -16
  44. package/dist/chunks/{index-CS0VbiLD.js → index-C10-EOdB.js} +1 -1
  45. package/dist/chunks/{index-2BOEcJIa.js → index-C4JmZLaj.js} +2 -2
  46. package/dist/chunks/index-CA-JKLr4.js +2 -0
  47. package/dist/chunks/{index-43GiH--T.js → index-CG_jJZVu.js} +2 -2
  48. package/dist/chunks/{index-BdkFKsMm.js → index-CGyP2uDE.js} +3 -3
  49. package/dist/chunks/{index-BOKv0b01.js → index-CPl1s9XJ.js} +2 -2
  50. package/dist/chunks/{index-DIPrBH-4.js → index-CSxE4cEm.js} +9 -9
  51. package/dist/chunks/{index-Cm7U1-fU.js → index-CWR5EzXx.js} +2 -2
  52. package/dist/chunks/{index-BwN5llCR.js → index-Camql5kL.js} +2 -2
  53. package/dist/chunks/{index-Drh-J9O7.js → index-CdUiTipO.js} +7 -7
  54. package/dist/chunks/{index-Cn029KTN.js → index-Crg61pK5.js} +2 -2
  55. package/dist/chunks/{index-Dja2O-hV.js → index-Cv9ZYXso.js} +1 -1
  56. package/dist/chunks/{index-Ck8v_Gv7.js → index-D7ADMlG3.js} +1 -1
  57. package/dist/chunks/index-DNl2gC8l.js +158 -0
  58. package/dist/chunks/{index-BYIzl-Ut.js → index-DVJA0qVm.js} +36 -36
  59. package/dist/chunks/{index-BAEIZVx0.js → index-DcFJhkY1.js} +2 -2
  60. package/dist/chunks/{index-Dx5_CB2E.js → index-DdEd-L3x.js} +2 -2
  61. package/dist/chunks/{index-DVmqMmgb.js → index-DkGA1eW_.js} +32 -32
  62. package/dist/chunks/{index-3k7mPX1e.js → index-Dnwxlti3.js} +1 -1
  63. package/dist/chunks/{index-CrizvxOJ.js → index-DqdEJDi2.js} +2 -2
  64. package/dist/chunks/{index-BIPebtDl.js → index-DqiwmBt4.js} +1 -1
  65. package/dist/chunks/{index-DS4MhAw-.js → index-PfuqBWjY.js} +2 -2
  66. package/dist/chunks/{index-BmFT1Kx2.js → index-SVP6RfVl.js} +2 -2
  67. package/dist/chunks/{index-CDxV4b81.js → index-Y8wu48Q0.js} +1 -1
  68. package/dist/chunks/index-_ewSKppm.js +2 -0
  69. package/dist/chunks/{index-Ctcr_Qeu.js → index-aBVtCLIJ.js} +2 -2
  70. package/dist/chunks/index-dNdz9j6d.js +2 -0
  71. package/dist/chunks/{index-BFUkVkSo.js → index-gskOpu3H.js} +16 -16
  72. package/dist/chunks/{index-CXpkT25O.js → index-pBSLMn5Q.js} +3 -3
  73. package/dist/chunks/index-sqPhX5Io.js +2 -0
  74. package/dist/chunks/{index-BzmR4Es2.js → index-vfrjhUD1.js} +39 -39
  75. package/dist/chunks/{index-J2NvjjDV.js → index-xGF5XC_i.js} +2 -2
  76. package/dist/chunks/{run-review-command.logic-CA2Rjymb.js → run-review-command.logic-B9GoCxh-.js} +24 -24
  77. package/dist/chunks/{serve.cmd-RxYS6WoN.js → serve.cmd-UXkaeaPI.js} +2 -2
  78. package/dist/chunks/{services-Csd556Tv.js → services-BYCeGBlO.js} +4 -4
  79. package/dist/chunks/{shared-B5CTGvpG.js → shared-B3cXL2Np.js} +1178 -1117
  80. package/dist/chunks/{stats-index-BLztvK69.js → stats-index-AIAnnp9S.js} +2 -2
  81. package/dist/gennady.js +46 -46
  82. package/dist/index.js +4 -4
  83. package/dist/shared/sdd/ladder.d.ts +42 -0
  84. package/dist/shared/sdd/module-specs.d.ts +7 -0
  85. package/dist/shared/sdd/tracker.d.ts +9 -0
  86. package/package.json +1 -1
  87. package/dist/chunks/classify-mr-stage.logic-ClmhzQPQ.js +0 -53
  88. package/dist/chunks/config-index-RFeqlDWs.js +0 -104
  89. package/dist/chunks/devtools-p8tmPuLn.js +0 -79
  90. package/dist/chunks/eval.cmd-ewU5lcUY.js +0 -34
  91. package/dist/chunks/help-DzGnMNi2.js +0 -7
  92. package/dist/chunks/index--AXFi0ty.js +0 -89
  93. package/dist/chunks/index-64TSesTc.js +0 -186
  94. package/dist/chunks/index-9Gv5trS_.js +0 -125
  95. package/dist/chunks/index-B1DQIryA.js +0 -2
  96. package/dist/chunks/index-B1PiBeQ3.js +0 -2
  97. package/dist/chunks/index-B4rzuhkt.js +0 -183
  98. package/dist/chunks/index-B97HJjkg.js +0 -159
  99. package/dist/chunks/index-BF6qypm0.js +0 -131
  100. package/dist/chunks/index-BK84ZQsh.js +0 -128
  101. package/dist/chunks/index-BRVIirjj.js +0 -141
  102. package/dist/chunks/index-BXnryCGW.js +0 -96
  103. package/dist/chunks/index-BaZm7Otb.js +0 -2
  104. package/dist/chunks/index-Bhk746A2.js +0 -129
  105. package/dist/chunks/index-Bi-eY_dY.js +0 -164
  106. package/dist/chunks/index-BjumU69g.js +0 -2
  107. package/dist/chunks/index-BkWXcpXU.js +0 -16979
  108. package/dist/chunks/index-BlY4jQIA.js +0 -168
  109. package/dist/chunks/index-C0iy7GxD.js +0 -140
  110. package/dist/chunks/index-CCBTXczb.js +0 -56
  111. package/dist/chunks/index-CDAfkSrr.js +0 -2
  112. package/dist/chunks/index-CDHymWzC.js +0 -102
  113. package/dist/chunks/index-CNfXJAao.js +0 -2
  114. package/dist/chunks/index-CQsae1nq.js +0 -207
  115. package/dist/chunks/index-CVmd0prf.js +0 -2
  116. package/dist/chunks/index-CZuTNeNm.js +0 -2
  117. package/dist/chunks/index-CasNhhrL.js +0 -96
  118. package/dist/chunks/index-Ce7GWENF.js +0 -377
  119. package/dist/chunks/index-Cf-02TAg.js +0 -265
  120. package/dist/chunks/index-CfjQWSrh.js +0 -52
  121. package/dist/chunks/index-Chr7gBBz.js +0 -443
  122. package/dist/chunks/index-Ci875Zlg.js +0 -346
  123. package/dist/chunks/index-CwA6RzIB.js +0 -3793
  124. package/dist/chunks/index-D1dI63ej.js +0 -46
  125. package/dist/chunks/index-DCS32A2i.js +0 -663
  126. package/dist/chunks/index-DOFoNxvb.js +0 -131
  127. package/dist/chunks/index-DVkCEuws.js +0 -136
  128. package/dist/chunks/index-DkadaaXq.js +0 -658
  129. package/dist/chunks/index-Dn11CLtk.js +0 -7
  130. package/dist/chunks/index-Do3spFJT.js +0 -340
  131. package/dist/chunks/index-DrFRZ0Yg.js +0 -2
  132. package/dist/chunks/index-DvEQhXi2.js +0 -1054
  133. package/dist/chunks/index-GiS0x6jg.js +0 -90
  134. package/dist/chunks/index-NacvqeQ5.js +0 -69
  135. package/dist/chunks/index-RNJhFzdr.js +0 -227
  136. package/dist/chunks/index-R_vUB6CL.js +0 -2
  137. package/dist/chunks/index-TQft1s5H.js +0 -20
  138. package/dist/chunks/index-ZmQRP38W.js +0 -26969
  139. package/dist/chunks/index-jdOZ4AkD.js +0 -143
  140. package/dist/chunks/index-kNa21kUI.js +0 -279
  141. package/dist/chunks/index-v4AV9kAc.js +0 -108
  142. package/dist/chunks/run-review-command.logic-CU1Slmc_.js +0 -331
  143. package/dist/chunks/serve.cmd-dWu_k_G_.js +0 -162
  144. package/dist/chunks/services-CwvXl2MB.js +0 -46832
  145. package/dist/chunks/shared-DSZTUx5b.js +0 -4509
  146. package/dist/chunks/stats-index-H6ALcjxy.js +0 -66
@@ -1,1054 +0,0 @@
1
- import { execSync as pe } from "node:child_process";
2
- import { existsSync as ie, readFileSync as H, readdirSync as B, statSync as re, lstatSync as Re } from "node:fs";
3
- import { resolve as A, relative as Y, extname as G, join as Ne } from "node:path";
4
- import { l as E, ap as Ee, aq as Ie, ar as j, as as Te } from "./services-CwvXl2MB.js";
5
- import { p as Ce, aF as Le } from "./shared-DSZTUx5b.js";
6
- class O {
7
- /** @purpose Collected lint errors — empty array when clean. */
8
- errors;
9
- /** @purpose Count of errors auto-fixed by DbcContractCheck. */
10
- autoFixed;
11
- /** @purpose Deduplicated task file paths resolved from @tasks annotations in linted files. */
12
- taskPaths;
13
- /** @purpose Deduplicated spec file paths resolved from task files. */
14
- specPaths;
15
- /** @purpose Agent guidance hint shown at the end of the report when relevant error families are present. */
16
- guidance;
17
- /**
18
- * @purpose Creates a LintReport with collected errors, autoFixed count, resolved references, and optional guidance.
19
- * @param errors Collected lint errors.
20
- * @param [autoFixed] Count of auto-fixed errors, defaults to 0.
21
- * @param [taskPaths] Resolved task file paths (deduplicated).
22
- * @param [specPaths] Resolved spec file paths (deduplicated).
23
- * @param [guidance] Agent guidance hint, defaults to undefined.
24
- */
25
- constructor(t, e = 0, s = [], o = [], i) {
26
- this.errors = t, this.autoFixed = e, this.taskPaths = s, this.specPaths = o, this.guidance = i;
27
- }
28
- /** @purpose Returns 0 when no errors, 1 otherwise — ESLint convention. | @returns 0 for clean, 1 for errors. */
29
- get exitCode() {
30
- return this.errors.length > 0 ? 1 : 0;
31
- }
32
- /**
33
- * @purpose Formats errors in ESLint-compatible output with resolved task/spec references.
34
- * @returns ESLint-compatible formatted string with References block.
35
- */
36
- format() {
37
- const t = [];
38
- if (this.autoFixed > 0 && t.push(`Auto-fixed: ${this.autoFixed} error(s)`), this.errors.length > 0 && t.push(
39
- ...this.errors.map(
40
- (e) => `${e.file}:${e.line}:${e.col}: ${e.severity}: ${e.code}: ${e.message}`
41
- )
42
- ), this.errors.length > 0 && (this.specPaths.length > 0 || this.taskPaths.length > 0)) {
43
- t.push(""), t.push("---"), t.push("Relevant specs & tasks for errors above:");
44
- for (const e of this.specPaths)
45
- t.push(` ${e}`);
46
- for (const e of this.taskPaths)
47
- t.push(` ${e}`);
48
- }
49
- return this.guidance && (t.push(""), t.push("---"), t.push(this.guidance)), t.join(`
50
- `);
51
- }
52
- }
53
- const Z = "ERR_CLI_LINT_MISSING_FILE", q = "ERR_CLI_LINT_MISSING_CONSUMERS", ye = "ERR_CLI_LINT_ANCHOR_UNPAIRED_START", Se = "ERR_CLI_LINT_ANCHOR_UNPAIRED_END", ve = "ERR_CLI_LINT_ANCHOR_NESTING", P = "ERR_CLI_LINT_ANCHOR_MALFORMED", z = "ERR_CLI_LINT_NON_ENGLISH", Ae = "ERR_CLI_LINT_RESOLVE_FAILED", xe = "ERR_CLI_LINT_STAGED_CONFLICT", Oe = "ERR_CLI_LINT_UNAUTHORIZED_DISABLE", ke = "ERR_CLI_LINT_DISABLE_MISSING_PURPOSE", w = "ERR_CLI_LINT_TOO_MANY_INVARIANTS", De = "ERR_CLI_LINT_ANCHOR_AT_CLASS_BODY", $e = "ERR_CLI_LINT_ANCHOR_CONSECUTIVE_START", we = "ERR_CLI_LINT_ANCHOR_TOO_THIN", J = "ERR_CLI_LINT_TAG_TOO_MANY_WORDS", ce = "ERR_CLI_LINT_REGION_TOO_MANY_COMMENTS", ae = "ERR_CLI_LINT_REGION_START_ANNOTATION_TOO_LONG", be = "ERR_CLI_LINT_INVENTORY_UNDECLARED", Me = "ERR_CLI_LINT_INVENTORY_UNIMPLEMENTED", Fe = "ERR_CLI_LINT_UNKNOWN_FLAG", We = "ERR_CLI_LINT_SPEC_NOT_FOUND", Ue = "ERR_CLI_LINT_INVENTORY_REVERSE_NEEDS_SPEC";
54
- function Pe(n, t) {
55
- const e = [];
56
- if (n.length === 0)
57
- return e.push({
58
- file: t,
59
- line: 1,
60
- col: 1,
61
- severity: "error",
62
- code: Z,
63
- message: "[FileHeaderCheck#check] Missing // @file: directive"
64
- }), e.push({
65
- file: t,
66
- line: 1,
67
- col: 1,
68
- severity: "error",
69
- code: q,
70
- message: "[FileHeaderCheck#check] Missing // @consumers: directive"
71
- }), e;
72
- const s = n.split(`
73
- `);
74
- let o = !1, i = !1;
75
- for (const r of s) {
76
- const c = r.trim();
77
- if (c.startsWith("import ") || (c.startsWith("// @file:") && (o = !0), c.startsWith("// @consumers:") && (i = !0), o && i))
78
- break;
79
- }
80
- return o || e.push({
81
- file: t,
82
- line: 1,
83
- col: 1,
84
- severity: "error",
85
- code: Z,
86
- message: "[FileHeaderCheck#check] Missing // @file: directive"
87
- }), i || e.push({
88
- file: t,
89
- line: 1,
90
- col: 1,
91
- severity: "error",
92
- code: q,
93
- message: "[FileHeaderCheck#check] Missing // @consumers: directive"
94
- }), e;
95
- }
96
- function F(n) {
97
- let t = "", e = 0, s = !1, o = !1, i = !1;
98
- for (; e < n.length; ) {
99
- const r = n[e], c = n[e + 1] ?? "";
100
- if (!s && !o && !i) {
101
- if (r === "/" && c === "/") break;
102
- if (r === "/" && c === "*") {
103
- for (e += 2; e < n.length - 1 && !(n[e] === "*" && n[e + 1] === "/"); ) e++;
104
- e += 2;
105
- continue;
106
- }
107
- }
108
- if (r === "\\") {
109
- e += 2;
110
- continue;
111
- }
112
- if (!o && !i && r === "'") {
113
- s = !s, e++;
114
- continue;
115
- }
116
- if (!s && !i && r === '"') {
117
- o = !o, e++;
118
- continue;
119
- }
120
- if (!s && !o && r === "`") {
121
- i = !i, e++;
122
- continue;
123
- }
124
- !s && !o && !i && (t += r), e++;
125
- }
126
- return t;
127
- }
128
- const He = /\/\/ #(region|endregion)\s+(START|END)_([A-Z0-9_]+)/, Ge = /\/\/ #(region|endregion)\s*$/;
129
- function Ve(n, t) {
130
- const e = n.split(`
131
- `), s = [], o = [];
132
- let i = 0;
133
- const r = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
134
- for (let a = 0; a < e.length; a++) {
135
- const l = e[a], u = l.match(He);
136
- if (i = Ye(l, i), u) {
137
- const g = u[2], m = u[3], d = a + 1, p = u.index ?? 0, C = l.indexOf(g, p), N = (C >= 0 ? C : p) + 1;
138
- if (g === "START") {
139
- const _ = r.get(i), S = c.get(i) ?? !1;
140
- _ && je(o, _) && !S && s.push({
141
- file: t,
142
- line: d,
143
- col: N,
144
- severity: "error",
145
- code: $e,
146
- message: `START_${m} immediately follows START_${_.name} at the same level — merge regions or close START_${_.name} first`
147
- }), o.push({ name: m, line: d, col: N }), r.set(i, { name: m, line: d, col: N }), c.set(i, !1);
148
- continue;
149
- }
150
- const L = Be(o, (_) => _.name === m);
151
- if (L === -1)
152
- s.push({
153
- file: t,
154
- line: d,
155
- col: N,
156
- severity: "error",
157
- code: Se,
158
- message: `END_${m} without matching START_${m} — add the missing opening anchor or remove this closing one`
159
- });
160
- else {
161
- for (let _ = o.length - 1; _ > L; _--) {
162
- const S = o[_];
163
- s.push({
164
- file: t,
165
- line: d,
166
- col: N,
167
- severity: "error",
168
- code: ve,
169
- message: `END_${m} closes parent while START_${S.name} at line ${S.line} is still open — close inner block first`
170
- });
171
- }
172
- o.length = L, r.delete(i), c.set(i, !1);
173
- }
174
- continue;
175
- }
176
- Je(l) && c.set(i, !0);
177
- const f = l.match(Ge);
178
- if (f) {
179
- const g = a + 1, m = (f.index ?? 0) + 1;
180
- if (f[1] === "endregion")
181
- if (o.length > 0) {
182
- const d = o[o.length - 1];
183
- s.push({
184
- file: t,
185
- line: g,
186
- col: m,
187
- severity: "error",
188
- code: P,
189
- message: `#endregion without END_<NAME> — expected END_${d.name} (auto-closed by stack top START_${d.name} at line ${d.line})`
190
- }), o.pop(), r.delete(i), c.set(i, !1);
191
- } else
192
- s.push({
193
- file: t,
194
- line: g,
195
- col: m,
196
- severity: "error",
197
- code: P,
198
- message: "#endregion without END_<NAME> — no open block to close"
199
- });
200
- else
201
- s.push({
202
- file: t,
203
- line: g,
204
- col: m,
205
- severity: "error",
206
- code: P,
207
- message: "#region without START_<NAME> — add START_ prefix with a block name"
208
- });
209
- }
210
- }
211
- for (const a of o)
212
- s.push({
213
- file: t,
214
- line: a.line,
215
- col: a.col,
216
- severity: "error",
217
- code: ye,
218
- message: `START_${a.name} without matching END_${a.name} — add the missing closing anchor`
219
- });
220
- return s.sort((a, l) => a.line - l.line || a.col - l.col), s;
221
- }
222
- function Be(n, t) {
223
- for (let e = n.length - 1; e >= 0; e--)
224
- if (t(n[e])) return e;
225
- return -1;
226
- }
227
- function Ye(n, t) {
228
- let e = t;
229
- const s = F(n);
230
- for (const o of s)
231
- o === "{" ? e++ : o === "}" && e--;
232
- return e;
233
- }
234
- function je(n, t) {
235
- return n.some(
236
- (e) => e.name === t.name && e.line === t.line && e.col === t.col
237
- );
238
- }
239
- function Je(n) {
240
- const t = n.trim();
241
- return !(t === "" || t.startsWith("//") || t.startsWith("/*") && t.endsWith("*/"));
242
- }
243
- async function Xe(n, t, e) {
244
- E.debug(`[DbcContractCheck#check] [idle → creating] ${t}`);
245
- const s = new Ie(), o = new j(), i = new Ee(s, o);
246
- try {
247
- if (!e) {
248
- const c = await i.lint(t, { content: n });
249
- return E.info(
250
- `[DbcContractCheck#check] [creating → linted] ${t} (${c.errors.length} errors)`
251
- ), { errors: c.errors.map(Q), autoFixed: 0 };
252
- }
253
- const r = await i.lintAndFix(t, { content: n });
254
- return E.info(
255
- `[DbcContractCheck#check] [creating → fixed] ${t} (autoFixed=${r.autoFixed}, remaining=${r.errors.length})`
256
- ), {
257
- errors: r.errors.map(Q),
258
- autoFixed: r.autoFixed
259
- };
260
- } catch (r) {
261
- const c = new Error(`[DbcContractCheck#check] Lint failed for ${t}`, { cause: r });
262
- throw E.error(`[DbcContractCheck#check] [creating → failed] ${t}`, { error: c }), c;
263
- }
264
- }
265
- function Q(n) {
266
- return {
267
- file: n.file,
268
- line: n.line,
269
- col: n.col,
270
- severity: "error",
271
- code: n.code,
272
- message: n.message
273
- };
274
- }
275
- const ee = 8, Ke = /@ts-ignore|@ts-nocheck|@ts-expect-error|eslint-disable(?:-next-line|-line)?(?:-[a-z-]+)?\b/, Ze = /\bd-\d+\b/i;
276
- function qe(n) {
277
- let t = !1, e = !1, s = !1;
278
- for (let o = 0; o < n.length - 1; o++) {
279
- const i = n[o], r = o > 0 ? n[o - 1] : "";
280
- if (!t && !e && !s) {
281
- if (i === "/" && (n[o + 1] === "/" || n[o + 1] === "*")) return o;
282
- i === "'" ? t = !0 : i === '"' ? e = !0 : i === "`" && (s = !0);
283
- } else r !== "\\" && (t && i === "'" ? t = !1 : e && i === '"' ? e = !1 : s && i === "`" && (s = !1));
284
- }
285
- return -1;
286
- }
287
- function ze(n, t) {
288
- const e = n.split(`
289
- `), s = [];
290
- for (let o = 0; o < e.length; o++) {
291
- const i = e[o], r = qe(i);
292
- if (r < 0) continue;
293
- const c = i.slice(r), a = Ke.exec(c);
294
- if (!a) continue;
295
- const l = a[0], u = r + a.index + 1, f = Ze.exec(i);
296
- if (!f) {
297
- s.push({
298
- file: t,
299
- line: o + 1,
300
- col: u,
301
- severity: "error",
302
- code: Oe,
303
- message: `Unauthorized disable: \`${l}\` has no Decision Log reference. Add \`D-NNN\` (e.g., \`D-042\`) in the same comment line pointing to a Decision Log entry that authorizes this disable. Policy: see specs/cli/cli.spec.md#d-007.`
304
- });
305
- continue;
306
- }
307
- const g = Qe(c, l, f[0]);
308
- g < ee && s.push({
309
- file: t,
310
- line: o + 1,
311
- col: u,
312
- severity: "error",
313
- code: ke,
314
- message: `Disable lacks purpose: \`${l}\` cites \`${f[0]}\` but the explanation is too short (${g} non-whitespace chars; need ≥ ${ee}). Add a purpose after the D-NNN reference, e.g., \`${l}: ${f[0]} — <why this disable is necessary>\`. Policy: see specs/cli/cli.spec.md#d-007.`
315
- });
316
- }
317
- return s;
318
- }
319
- function Qe(n, t, e) {
320
- let s = n.replace(t, "");
321
- return s = s.replace(e, ""), s = s.replace(/\*\//g, ""), s = s.replace(/^\/\/|^\/\*/g, ""), s.replace(/\s/g, "").length;
322
- }
323
- const te = new RegExp("\\p{Script=Cyrillic}", "u");
324
- function et(n, t) {
325
- const e = [], s = n.split(`
326
- `), o = tt(s);
327
- for (let i = 0; i < s.length; i++) {
328
- const r = s[i], c = i + 1, a = r.trim();
329
- if (a.startsWith("// @file:") || a.startsWith("// @consumers:")) {
330
- const l = [...r];
331
- for (let u = 0; u < l.length; u++)
332
- te.test(l[u]) && e.push({
333
- file: t,
334
- line: c,
335
- col: u + 1,
336
- severity: "error",
337
- code: z,
338
- message: `[LanguageCheck#check] Cyrillic character '${l[u]}' in file header — use English only`
339
- });
340
- }
341
- if (o.has(i)) {
342
- const l = [...r];
343
- for (let u = 0; u < l.length; u++)
344
- if (te.test(l[u])) {
345
- e.push({
346
- file: t,
347
- line: c,
348
- col: u + 1,
349
- severity: "error",
350
- code: z,
351
- message: `[LanguageCheck#check] Cyrillic character '${l[u]}' in JSDoc contract — use English only`
352
- });
353
- break;
354
- }
355
- }
356
- }
357
- return e;
358
- }
359
- function tt(n) {
360
- const t = /* @__PURE__ */ new Set();
361
- let e = !1;
362
- for (let s = 0; s < n.length; s++) {
363
- const o = n[s].trim();
364
- if (o.startsWith("/**")) {
365
- e = !0, t.add(s), o.endsWith("*/") && (e = !1);
366
- continue;
367
- }
368
- e && (t.add(s), o.includes("*/") && (e = !1));
369
- }
370
- return t;
371
- }
372
- const nt = /^\s*export\s+(?:(?:default\s+)?(?:function|class|abstract\s+class|interface))\s+(\w+)/, st = /^\s*(?:function|class|abstract\s+class|interface)\s+(\w+)/, ot = /\/\/\s*#region\s+START_\w+.*\binvariant\s*:/;
373
- function it(n, t, e) {
374
- const s = n.split(`
375
- `), o = [];
376
- let i = 0;
377
- const r = [];
378
- let c = null, a = !1, l = "", u = 0, f = 0, g = !1, m = [];
379
- for (let d = 0; d < s.length; d++) {
380
- const p = s[d], C = d + 1, N = p.trim();
381
- if (N.startsWith("/**"))
382
- if (N.includes("*/") && N.length > 3) {
383
- const v = ne(N);
384
- m = [];
385
- for (let y = 0; y < v; y++) m.push(C);
386
- } else {
387
- g = !0, m = [];
388
- continue;
389
- }
390
- if (g) {
391
- if (N.includes("*/")) {
392
- g = !1;
393
- continue;
394
- }
395
- const v = ne(N);
396
- for (let y = 0; y < v; y++) m.push(C);
397
- continue;
398
- }
399
- const L = p.match(nt), _ = N.includes("*/") ? N.slice(N.lastIndexOf("*/") + 2) : null, S = _ ? _.match(
400
- /^\s*export\s+(?:(?:default\s+)?(?:function|class|abstract\s+class|interface))\s+(\w+)/
401
- ) : null, R = L || S, k = S ? N.lastIndexOf("*/") + 2 : 0;
402
- if (R) {
403
- a = !0, l = R[1], u = C;
404
- const v = (R.index ?? 0) + k, y = p.indexOf(l, v);
405
- f = (y >= 0 ? y : v) + 1;
406
- } else m.length > 0 && st.test(p) && (m = []);
407
- const D = F(p);
408
- for (const v of D)
409
- if (v === "{") {
410
- if (i++, a) {
411
- const y = {
412
- name: l,
413
- nameLine: u,
414
- nameCol: f,
415
- bodyDepth: i,
416
- jsdocCount: m.length,
417
- regionCount: 0
418
- };
419
- r.push(y), c = y, a = !1, m = [];
420
- }
421
- } else v === "}" && (c && i === c.bodyDepth && (c.jsdocCount > e && o.push({
422
- file: t,
423
- line: c.nameLine,
424
- col: c.nameCol,
425
- severity: "error",
426
- code: w,
427
- message: `Entity "${c.name}" has ${c.jsdocCount} JSDoc @invariant tags (max ${e}) — consider reviewing the contract; too many invariants suggest the entity is overloaded`
428
- }), c.regionCount > e && o.push({
429
- file: t,
430
- line: c.nameLine,
431
- col: c.nameCol,
432
- severity: "error",
433
- code: w,
434
- message: `Entity "${c.name}" has ${c.regionCount} region invariants (max ${e}) — consider reviewing the contract; too many region invariants suggest the entity is overloaded`
435
- }), r.pop(), c = r.length > 0 ? r[r.length - 1] : null), i--);
436
- c && ot.test(p) && c.regionCount++;
437
- }
438
- for (const d of r)
439
- d.jsdocCount > e && o.push({
440
- file: t,
441
- line: d.nameLine,
442
- col: d.nameCol,
443
- severity: "error",
444
- code: w,
445
- message: `Entity "${d.name}" has ${d.jsdocCount} JSDoc @invariant tags (max ${e}) — consider reviewing the contract; too many invariants suggest the entity is overloaded`
446
- }), d.regionCount > e && o.push({
447
- file: t,
448
- line: d.nameLine,
449
- col: d.nameCol,
450
- severity: "error",
451
- code: w,
452
- message: `Entity "${d.name}" has ${d.regionCount} region invariants (max ${e}) — consider reviewing the contract; too many region invariants suggest the entity is overloaded`
453
- });
454
- return o.sort((d, p) => d.line - p.line || d.col - p.col), o;
455
- }
456
- function ne(n) {
457
- const t = n.match(/@invariant\b/g);
458
- return t ? t.length : 0;
459
- }
460
- const rt = /\/\/ #(region|endregion)\s+(START|END)_([A-Z0-9_]+)/;
461
- function ct(n, t) {
462
- const e = n.split(`
463
- `), s = [];
464
- let o = 0;
465
- const i = [];
466
- let r = !1;
467
- for (let c = 0; c < e.length; c++) {
468
- const a = e[c], l = c + 1;
469
- /\b(?:class|namespace)\s+\w/.test(F(a)) && (r = !0);
470
- const u = F(a);
471
- for (const g of u)
472
- g === "{" ? (o++, r && (i.push(o), r = !1)) : g === "}" && (i.length > 0 && o === i[i.length - 1] && i.pop(), o--);
473
- const f = a.match(rt);
474
- if (f && i.length > 0 && o === i[i.length - 1]) {
475
- const g = f[3], d = f[2] === "START" ? "START" : "END", C = (f.index ?? 0) + 1;
476
- s.push({
477
- file: t,
478
- line: l,
479
- col: C,
480
- severity: "error",
481
- code: De,
482
- message: `#region ${d}_${g} at class body level — regions must not separate class members; move inside a method body or remove`
483
- });
484
- }
485
- }
486
- return s.sort((c, a) => c.line - a.line || c.col - a.col), s;
487
- }
488
- const le = /\/\/ #(region|endregion)\s+(START|END)_([A-Z0-9_]+)/, ue = 2;
489
- function at(n, t) {
490
- const e = n.split(`
491
- `), s = [], o = [];
492
- for (let i = 0; i < e.length; i++) {
493
- const r = e[i], c = r.match(le);
494
- if (c && c[2] === "START") {
495
- const a = c[3], l = c.index ?? 0, u = r.indexOf("START", l), f = (u >= 0 ? u : l) + 1, m = r.slice(l + c[0].length).trim().length > 0;
496
- o.push({
497
- name: a,
498
- startLine: i + 1,
499
- col: f,
500
- meaningfulCount: 0,
501
- hasStartAnnotation: m,
502
- hasBodyComment: !1
503
- });
504
- continue;
505
- }
506
- if (c && c[2] === "END") {
507
- const a = c[3], l = ut(o, (u) => u.name === a);
508
- if (l !== -1) {
509
- const u = o[l];
510
- u.meaningfulCount < ue && s.push(lt(t, u)), o.length = l;
511
- }
512
- continue;
513
- }
514
- if (o.length !== 0)
515
- if (ft(r))
516
- for (const a of o)
517
- a.meaningfulCount++;
518
- else dt(r) && (o[o.length - 1].hasBodyComment = !0);
519
- }
520
- return s.sort((i, r) => i.line - r.line || i.col - r.col), s;
521
- }
522
- function lt(n, t) {
523
- const { name: e, startLine: s, col: o, meaningfulCount: i, hasStartAnnotation: r, hasBodyComment: c } = t;
524
- let a;
525
- return i === 0 && (r || c) ? a = `START_${e} wraps only comments — keep the comment(s) and remove the region wrapper` : i === 0 ? a = `START_${e} is empty (0 meaningful lines) — remove the empty region` : r ? a = `START_${e} has only ${i} meaningful line(s) + annotation — keep the annotation as a plain comment and remove the region wrapper` : a = `START_${e} has only ${i} meaningful line(s) — regions need at least ${ue} lines of code; consider removing the region`, {
526
- file: n,
527
- line: s,
528
- col: o,
529
- severity: "error",
530
- code: we,
531
- message: a
532
- };
533
- }
534
- function ut(n, t) {
535
- for (let e = n.length - 1; e >= 0; e--)
536
- if (t(n[e])) return e;
537
- return -1;
538
- }
539
- function ft(n) {
540
- const t = n.trim();
541
- return !(t === "" || t.startsWith("//") || t.startsWith("/*") && t.endsWith("*/"));
542
- }
543
- function dt(n) {
544
- const t = n.trim();
545
- return t.startsWith("//") ? !le.test(t) : !1;
546
- }
547
- const b = /@(?:param|returns|purpose|implements|invariant|sideEffect|consumer|see|post|throws|pre|tasks)\b/, ht = /^\/\/\s*@(?:file|consumers):/;
548
- function fe(n) {
549
- return n.trim().split(/\s+/).filter(Boolean).length;
550
- }
551
- function mt(n, t, e) {
552
- const s = n.split(`
553
- `), o = [];
554
- let i = !1, r = [];
555
- for (let c = 0; c < s.length; c++) {
556
- const a = s[c], l = a.trim();
557
- if (l.startsWith("/**")) {
558
- i = !0, r = [a], l.endsWith("*/") && (i = !1, o.push(...se(r, t, c + 1, c + 1, e)));
559
- continue;
560
- }
561
- if (i && (r.push(a), l.includes("*/"))) {
562
- i = !1;
563
- const u = c + 1 - r.length + 1, f = c + 1;
564
- o.push(...se(r, t, u, f, e));
565
- }
566
- }
567
- for (let c = 0; c < s.length; c++) {
568
- const a = s[c], l = c + 1, u = a.trim();
569
- if (u.startsWith("import "))
570
- break;
571
- if (u.match(ht)) {
572
- const g = u.slice(u.indexOf(":") + 1).trim(), m = fe(g);
573
- if (m > e) {
574
- const d = u.startsWith("// @file:") ? "@file" : "@consumers", p = u.indexOf(":") + 2;
575
- o.push({
576
- file: t,
577
- line: l,
578
- col: p,
579
- severity: "error",
580
- code: J,
581
- message: `[WordCountCheck#check] ${d} has ${m} words (max ${e}) — shorten the description`
582
- });
583
- }
584
- }
585
- }
586
- return o.sort((c, a) => c.line - a.line || c.col - a.col), o;
587
- }
588
- function gt(n, t) {
589
- const s = n.map((i) => {
590
- let r = i.trim();
591
- return r.startsWith("/**") && (r = r.slice(3)), r.endsWith("*/") && (r = r.slice(0, r.length - 2).trim()), r.startsWith("*") && (r = r.slice(1)), r;
592
- }).join(`
593
- `).slice(t), o = s.slice(1).search(b);
594
- return o === -1 ? s.slice(1) : s.slice(1, o + 1);
595
- }
596
- function se(n, t, e, s, o) {
597
- const i = [], c = n.map((l) => {
598
- let u = l.trim();
599
- return u.startsWith("/**") && (u = u.slice(3)), u.endsWith("*/") && (u = u.slice(0, u.length - 2).trim()), u.startsWith("*") && (u = u.slice(1)), u;
600
- }).join(`
601
- `);
602
- let a = 0;
603
- for (; a < c.length; ) {
604
- b.lastIndex = 0;
605
- const l = b.exec(c.slice(a));
606
- if (!l) break;
607
- const u = l[0], f = a + (l.index ?? 0), g = gt(n, f), m = fe(g);
608
- if (m > o) {
609
- let p = 0, C = e, N = 1;
610
- for (let L = 0; L < n.length; L++) {
611
- const _ = n[L].length + 1;
612
- if (p + _ > f) {
613
- C = e + L, N = f - p + 1;
614
- break;
615
- }
616
- p += _;
617
- }
618
- i.push({
619
- file: t,
620
- line: C,
621
- col: N,
622
- severity: "error",
623
- code: J,
624
- message: `[WordCountCheck#check] ${u} has ${m} words (max ${o}) — shorten the description`
625
- });
626
- }
627
- if (a = f + u.length, a >= c.length) break;
628
- const d = c.slice(a).search(b);
629
- if (d === -1) break;
630
- a += d;
631
- }
632
- return i;
633
- }
634
- const de = /\/\/ #(region|endregion)\s+(START|END)_([A-Z0-9_]+)/, oe = 30;
635
- function _t(n) {
636
- return n.trim().split(/\s+/).filter(Boolean).length;
637
- }
638
- function pt(n) {
639
- const t = n.trim();
640
- return t.startsWith("//") ? !de.test(t) : !1;
641
- }
642
- function Rt(n, t, e) {
643
- const s = n.split(`
644
- `), o = [], i = [];
645
- for (let r = 0; r < s.length; r++) {
646
- const c = s[r], a = c.match(de);
647
- if (a && a[2] === "START") {
648
- const l = a[3], u = a.index ?? 0, f = c.indexOf("START", u), g = (f >= 0 ? f : u) + 1, m = c.slice(u + a[0].length).trim(), d = m.length > 0 ? _t(m) : 0;
649
- d > oe && o.push({
650
- file: t,
651
- line: r + 1,
652
- col: g,
653
- severity: "error",
654
- code: ae,
655
- message: `START_${l} annotation has ${d} words (max ${oe}) — shorten the annotation`
656
- }), i.push({
657
- name: l,
658
- startLine: r + 1,
659
- col: g,
660
- commentCount: 0,
661
- startAnnotationWords: d
662
- });
663
- continue;
664
- }
665
- if (a && a[2] === "END") {
666
- const l = a[3], u = Nt(i, (f) => f.name === l);
667
- if (u !== -1) {
668
- const f = i[u];
669
- f.commentCount > e && o.push({
670
- file: t,
671
- line: f.startLine,
672
- col: f.col,
673
- severity: "error",
674
- code: ce,
675
- message: `START_${l} has ${f.commentCount} comment lines (max ${e}) — reduce comments or extract them outside the region`
676
- }), i.length = u;
677
- }
678
- continue;
679
- }
680
- if (i.length !== 0 && pt(c))
681
- for (const l of i)
682
- l.commentCount++;
683
- }
684
- return o.sort((r, c) => r.line - c.line || r.col - c.col), o;
685
- }
686
- function Nt(n, t) {
687
- for (let e = n.length - 1; e >= 0; e--)
688
- if (t(n[e])) return e;
689
- return -1;
690
- }
691
- async function Et(n, t, e) {
692
- const s = await new j().parseFile(t, n);
693
- if (!s.ok) return [];
694
- const o = new Set(e);
695
- return s.exported.filter((i) => !o.has(i.name)).map((i) => ({
696
- file: t,
697
- line: 1,
698
- col: 1,
699
- severity: "error",
700
- code: be,
701
- message: `Exported \`${i.name}\` is not in the module's closed-world Entity Inventory (AX_CLOSED_WORLD_INVENTORY). Fix: remove it, or — if genuinely needed — log an \`intro <name> ← <reason>\` line (AX_INTRODUCED_DISCIPLINE) and backflow it into the spec inventory; never silently keep an undeclared export. If you added it under drift / context loss, re-read the module spec ## 3 Entity Inventory and AX_INTRODUCED_DISCIPLINE.`
702
- }));
703
- }
704
- async function It(n, t) {
705
- const e = await new j().parseFile(t, n);
706
- return e.ok ? e.exported.map((s) => s.name) : [];
707
- }
708
- function Tt(n, t, e) {
709
- return n.filter((s) => !t.has(s)).map((s) => ({
710
- file: e,
711
- line: 1,
712
- col: 1,
713
- severity: "error",
714
- code: Me,
715
- message: `Inventory entity \`${s}\` is declared in the spec but exported by no scanned file — planned-but-unbuilt or renamed-away. Fix: implement it, or remove the stale inventory row (and supersede the decision that introduced it). If the sweep did not cover the whole module, re-run \`lint --spec=<spec> --inventory-reverse <module-dir>\` over the full code root before trusting this.`
716
- }));
717
- }
718
- function Ct(n, t = "tasks") {
719
- const e = /* @__PURE__ */ new Map(), s = A(n, t);
720
- if (!ie(s))
721
- return e;
722
- const o = St(s);
723
- for (const i of o) {
724
- let r;
725
- try {
726
- r = H(i, "utf-8");
727
- } catch {
728
- continue;
729
- }
730
- const c = r.match(/-\s+\*\*Task-ID:\*\*\s+(TSK-\d+)/);
731
- if (!c) continue;
732
- const a = c[1], l = Y(n, i), u = Lt(r, n);
733
- e.set(a, { taskPath: l, specPaths: u });
734
- }
735
- return e;
736
- }
737
- function Lt(n, t) {
738
- const e = /* @__PURE__ */ new Set(), s = n.match(/\*\*Spec References:\*\*[\s\S]*?(?=\n- \*\*|$)/);
739
- if (!s) return [];
740
- const o = s[0], i = /\[([^\]]*)\]\(([^)]+\.md)[^)]*\)/g;
741
- let r;
742
- for (; (r = i.exec(o)) !== null; ) {
743
- const c = r[2].split("/").pop();
744
- if (!c) continue;
745
- const a = yt(A(t, "specs"), c);
746
- if (a) {
747
- const l = Y(t, a);
748
- l.startsWith("..") || e.add(l);
749
- }
750
- }
751
- return [...e].sort();
752
- }
753
- function yt(n, t) {
754
- if (!ie(n)) return null;
755
- const e = [n];
756
- for (; e.length > 0; ) {
757
- const s = e.pop();
758
- let o;
759
- try {
760
- o = B(s);
761
- } catch {
762
- continue;
763
- }
764
- for (const i of o) {
765
- const r = A(s, i);
766
- try {
767
- const c = re(r);
768
- if (c.isDirectory())
769
- e.push(r);
770
- else if (c.isFile() && i === t)
771
- return r;
772
- } catch {
773
- }
774
- }
775
- }
776
- return null;
777
- }
778
- function St(n) {
779
- const t = [], e = [n];
780
- for (; e.length > 0; ) {
781
- const s = e.pop();
782
- let o;
783
- try {
784
- o = B(s);
785
- } catch {
786
- continue;
787
- }
788
- for (const i of o) {
789
- const r = A(s, i);
790
- try {
791
- const c = re(r);
792
- c.isDirectory() ? e.push(r) : c.isFile() && i.endsWith(".md") && t.push(r);
793
- } catch {
794
- }
795
- }
796
- }
797
- return t;
798
- }
799
- function vt(n) {
800
- const t = n.match(/@tasks:\s*(.+)/m);
801
- return t ? t[1].split(/[,;\s]+/).map((e) => e.trim()).filter((e) => /^TSK-\d+$/.test(e)) : [];
802
- }
803
- function At(n, t) {
804
- const e = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
805
- for (const o of n) {
806
- const i = t.get(o);
807
- if (i) {
808
- e.add(i.taskPath);
809
- for (const r of i.specPaths)
810
- s.add(r);
811
- }
812
- }
813
- return {
814
- taskPaths: [...e].sort(),
815
- specPaths: [...s].sort()
816
- };
817
- }
818
- function xt(n) {
819
- let t = "", e = 0;
820
- for (; e < n.length; ) {
821
- const s = n[e], o = n[e + 1];
822
- if (s === "*" && o === "*")
823
- n[e + 2] === "/" ? (t += "(?:.*\\/)?", e += 3) : (e + 2 >= n.length, t += ".*", e += 2);
824
- else if (s === "*")
825
- t += "[^/]*", e++;
826
- else if (s === "?")
827
- t += "[^/]", e++;
828
- else if (s === ".")
829
- t += "\\.", e++;
830
- else if (s === "[") {
831
- const i = n.indexOf("]", e);
832
- i !== -1 ? (t += n.slice(e, i + 1), e = i + 1) : (t += "\\[", e++);
833
- } else
834
- t += Ot(s), e++;
835
- }
836
- return new RegExp("^" + t + "$");
837
- }
838
- function Ot(n) {
839
- return "^$\\+*.?{}[]()|/".includes(n) ? "\\" + n : n;
840
- }
841
- async function kt(n) {
842
- let t;
843
- try {
844
- t = Ce(
845
- n,
846
- {
847
- autofix: ["autofix"],
848
- staged: ["staged"],
849
- verbose: ["verbose", "v"],
850
- maxInvariants: { aliases: ["max-invariants"], takesValue: !0 },
851
- exclude: { aliases: ["exclude"], takesValue: !0 },
852
- maxWords: { aliases: ["max-words"], takesValue: !0 },
853
- maxRegionComments: { aliases: ["max-region-comments"], takesValue: !0 },
854
- spec: { aliases: ["spec"], takesValue: !0 },
855
- inventoryReverse: { aliases: ["inventory-reverse"], takesValue: !0 }
856
- },
857
- { strict: !0 }
858
- );
859
- } catch (h) {
860
- const T = h instanceof Error ? h.message : String(h);
861
- return E.warn(`[LintCommand#run] [idle → failed] ${T}`), new O([
862
- {
863
- file: "",
864
- line: 0,
865
- col: 0,
866
- severity: "error",
867
- code: Fe,
868
- message: T
869
- }
870
- ]);
871
- }
872
- const e = t._.filter(
873
- (h) => typeof h == "string" && h !== "lint"
874
- ), s = t.autofix === !0 || t.autofix === "true", o = t.staged === !0 || t.staged === "true", i = t.verbose === !0 || t.verbose === "true", r = typeof t.maxInvariants == "string" ? parseInt(t.maxInvariants, 10) : 3, c = typeof t.maxWords == "string" ? parseInt(t.maxWords, 10) : 25, a = typeof t.maxRegionComments == "string" ? parseInt(t.maxRegionComments, 10) : 3, l = typeof t.spec == "string" ? t.spec : null, u = typeof t.inventoryReverse == "string" ? t.inventoryReverse : null;
875
- if (u && !l) {
876
- const h = {
877
- file: "",
878
- line: 0,
879
- col: 0,
880
- severity: "error",
881
- code: Ue,
882
- message: "--inventory-reverse requires --spec=<module-spec> — the reverse sweep checks that spec’s Entity Inventory against the code."
883
- };
884
- return E.warn("[LintCommand#run] --inventory-reverse given without --spec"), new O([h]);
885
- }
886
- let f = null;
887
- const g = [];
888
- if (l)
889
- try {
890
- f = Le(H(A(l), "utf-8"));
891
- } catch (h) {
892
- const T = h instanceof Error ? h.message : String(h);
893
- g.push({
894
- file: l,
895
- line: 0,
896
- col: 0,
897
- severity: "error",
898
- code: We,
899
- message: `Cannot read --spec target: ${T}`
900
- }), E.warn(`[LintCommand#run] --spec unreadable: ${l}`);
901
- }
902
- const m = f !== null && f.length === 0;
903
- m && console.log(
904
- `ℹ️ [LintCommand#run] ${l} has no Entity Inventory section — nothing to verify`
905
- ), u && e.length === 0 && !o && e.push(u);
906
- const d = [
907
- "**/node_modules/**",
908
- "**/__tests__/**",
909
- "**/fixtures/**",
910
- "**/__tests__/fixtures/**",
911
- "**/dist/**",
912
- "**/coverage/**",
913
- "**/build/**",
914
- "**/out/**"
915
- ], p = t.exclude, C = Array.isArray(p) ? p : typeof p == "string" ? [p] : [], L = [...d, ...C].map(xt);
916
- i && Te("debug");
917
- let _;
918
- const S = [];
919
- if (o) {
920
- if (e.length > 0) {
921
- const h = {
922
- file: "",
923
- line: 0,
924
- col: 0,
925
- severity: "error",
926
- code: xe,
927
- message: "--staged and positional targets are mutually exclusive. Use either --staged or provide file/directory paths, not both."
928
- };
929
- return E.warn("[LintCommand#run] --staged and positional targets are mutually exclusive"), new O([h]);
930
- }
931
- E.debug("[LintCommand#run] [idle → collecting] staged mode");
932
- try {
933
- _ = pe("git diff --staged --name-only", { encoding: "utf-8" }).trim().split(`
934
- `).filter(Boolean).filter((T) => T.endsWith(".ts")), _ = [...new Set(_)];
935
- } catch (h) {
936
- const T = new Error("[LintCommand#run] Git scan failed — not a git repository?", {
937
- cause: h
938
- });
939
- throw E.error("[LintCommand#run] [collecting → failed]", { error: T }), T;
940
- }
941
- } else if (e.length > 0) {
942
- E.debug(`[LintCommand#run] [idle → resolving] ${e.length} target(s)`);
943
- const h = $t(e);
944
- _ = h.files, S.push(...h.errors);
945
- for (const T of h.errors)
946
- E.warn(`[LintCommand#run] [resolving → failed] ${T.file}: ${T.message}`);
947
- } else
948
- _ = [];
949
- if (_.length > 0 && L.length > 0) {
950
- const h = _.length, T = A(".");
951
- _ = _.filter((I) => {
952
- const W = I.startsWith("/") ? Y(T, I) : I;
953
- return !L.some(($) => $.test(W));
954
- }), E.debug(`[LintCommand#run] [filtering → filtered] ${h} → ${_.length} file(s)`);
955
- }
956
- if (_.length === 0)
957
- return E.debug("[LintCommand#run] [collecting → done] no files to lint"), new O([...S, ...g]);
958
- E.debug(`[LintCommand#run] [collecting → linting] ${_.length} file(s)`);
959
- const R = [...S, ...g];
960
- let k = 0;
961
- const D = /* @__PURE__ */ new Set(), v = A("."), y = Ct(v), X = /* @__PURE__ */ new Set();
962
- for (const h of _) {
963
- const T = A(h);
964
- let I;
965
- try {
966
- E.debug(`[LintCommand#run] [linting → reading] ${h}`), I = H(T, "utf-8");
967
- } catch (x) {
968
- const U = new Error(`[LintCommand#run] Cannot read file: ${h}`, { cause: x });
969
- E.error(`[LintCommand#run] [reading → failed] ${h}`, { error: U });
970
- continue;
971
- }
972
- const W = R.length;
973
- R.push(...Pe(I, h)), R.push(...Ve(I, h)), R.push(...et(I, h)), R.push(...ze(I, h)), R.push(...ct(I, h)), R.push(...at(I, h)), R.push(...it(I, h, r)), R.push(...mt(I, h, c)), R.push(...Rt(I, h, a));
974
- const $ = await Xe(I, h, s);
975
- if (R.push(...$.errors), k += $.autoFixed, f !== null && !m && (R.push(...await Et(I, h, f)), u))
976
- for (const x of await It(I, h)) D.add(x);
977
- if (R.length > W) {
978
- const x = vt(I);
979
- for (const U of x)
980
- X.add(U);
981
- }
982
- }
983
- u && f !== null && l && !m && R.push(...Tt(f, D, l));
984
- const { taskPaths: me, specPaths: ge } = At([...X], y), _e = Mt(R), K = new O(R, k, me, ge, _e);
985
- return K.exitCode === 1 ? console.log(`❌ [LintCommand#run] [linting → failed] ${R.length} error(s)`) : console.log("✅ [LintCommand#run] [linting → clean] no errors"), K;
986
- }
987
- const V = [".ts", ".tsx"], Dt = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage", "build", "out", "__tests__"]);
988
- function $t(n) {
989
- E.debug(`[resolveTargets] [idle → resolving] ${n.length} target(s)`);
990
- const t = /* @__PURE__ */ new Set(), e = [];
991
- for (const o of n) {
992
- const i = G(o).toLowerCase();
993
- if (i && !V.includes(i) && !o.endsWith("/"))
994
- continue;
995
- let r;
996
- try {
997
- r = Re(o);
998
- } catch (a) {
999
- const l = a;
1000
- e.push({
1001
- file: o,
1002
- line: 0,
1003
- col: 0,
1004
- severity: "error",
1005
- code: Ae,
1006
- message: `${o}: ${l.code ?? "UNKNOWN"}: ${l.message}`
1007
- });
1008
- continue;
1009
- }
1010
- if (r.isSymbolicLink())
1011
- continue;
1012
- const c = A(o);
1013
- if (r.isDirectory())
1014
- he(c, t);
1015
- else if (r.isFile()) {
1016
- const a = G(o).toLowerCase();
1017
- V.includes(a) && t.add(c);
1018
- }
1019
- }
1020
- const s = [...t].sort();
1021
- return E.debug(
1022
- `[resolveTargets] [resolving → resolved] ${s.length} file(s), ${e.length} error(s)`
1023
- ), { files: s, errors: e };
1024
- }
1025
- function he(n, t) {
1026
- let e;
1027
- try {
1028
- e = B(n, { withFileTypes: !0 });
1029
- } catch {
1030
- return;
1031
- }
1032
- for (const s of e) {
1033
- const o = Ne(n, s.name);
1034
- if (!s.name.startsWith(".") && !Dt.has(s.name) && !s.isSymbolicLink()) {
1035
- if (s.isDirectory())
1036
- he(o, t);
1037
- else if (s.isFile()) {
1038
- const i = G(s.name).toLowerCase();
1039
- V.includes(i) && t.add(o);
1040
- }
1041
- }
1042
- }
1043
- }
1044
- const wt = "WORD_COUNT errors found — consider reviewing each affected contract as a whole. Tag-by-tag truncation risks breaking cross-tag consistency. Technique: (1) remove filler words, (2) compress overlapping @purpose/@param/@returns, (3) keep entity names and spec refs.", bt = "REGION_COMMENT errors found — reduce comment density inside #region blocks. Merge adjacent comment lines, move descriptive text outside the region, or split the region. Verify the region still has ≥2 meaningful code lines after cleanup (see AnchorThinCheck).";
1045
- function Mt(n) {
1046
- const t = new Set(n.map((s) => s.code)), e = [];
1047
- if ((t.has(J) || t.has(ae)) && e.push(wt), t.has(ce) && e.push(bt), e.length !== 0)
1048
- return e.join(`
1049
-
1050
- `);
1051
- }
1052
- const M = await kt(process.argv);
1053
- (M.exitCode === 1 || M.autoFixed > 0) && console.log(M.format());
1054
- process.exit(M.exitCode);