@linkdesk/plugin-sdk 0.1.42 → 0.1.44

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.
@@ -0,0 +1,420 @@
1
+ /**
2
+ * check-css-namespace 腿·**插件域自有类名引用悬空**(E6#136 · 2026-09-20)。
3
+ *
4
+ * ── 这条缝是怎么被实测踩出来的 ──
5
+ * 生态首个第三方 AI 作者(geme-tihu-bicycle)在 CSS 头注释里列 token 族时用了 `--text-` 族名+`/` 分隔——闭合符
6
+ * 把块注释**提前闭合**,注释后的残渣文本黏住紧随其后的 `.geme-tihu-bicycle-root` 规则,把整条规则
7
+ * 吞掉;TSX 里引用该类名的样式**静默不生效**(PostCSS/Vite 全程零警告,靠逐条截图比对才发现)。
8
+ * 三条既有腿都没接住(缝隙正中央):
9
+ * · `dangling-names.ts`(E6#119)头注明写「**非 `ldk-` 的未定义名不计悬空**——假红比漏报更坏」
10
+ * ⇒ 自有前缀类名**有意宽松掉**(`notJudged`);
11
+ * · `keyframe-refs.ts`(E6#112)只管关键帧;
12
+ * · 壳侧 `audit:plugin-dead-css`(E6#113)是反方向(定义了没人用)。
13
+ * 本腿把「自有前缀类名引用了、本仓 CSS 里却找不到定义」这一格补上——是既有口径的**补缝**,
14
+ * 不是第二把全能尺子。
15
+ *
16
+ * ── 🔴 窄口子(判据写死,不许走样)──
17
+ * · 射程 = 插件仓 `.ts`/`.tsx` 里 `className` 的**字符串字面量**(`classList` / `querySelector`
18
+ * 等其他通道不进本腿——任务书判据写死 className;`ldk-*` 借用归 dangling-names、宿主保留名归
19
+ * reserved-classes、前缀形态归 plugin-prefix,各归各腿);
20
+ * · 只判**本插件前缀**(`<pluginId>-`)的类名——非本前缀的自有名(DOM 钩子 / 第三方内联)不判;
21
+ * · **动态拼接一律跳过并计数**(模板插值 / `clsx(...)` / 变量 / 三元——静态读不出运行时拼出来的
22
+ * 名字,拦就是假红;口径与 `dangling-names.ts` 逐字同源);
23
+ * · 定义集 = 本仓自有 CSS(`.css` 全量)**规则选择器提及**的类名(`classTokensIn` 口径——scoped
24
+ * 调优 `.root .item` 里的 `.item` 是合法定义,⇒ 按**提及集**收,⛔ 不用裸定义集,否则 scoped 假红)。
25
+ *
26
+ * ── 🔴 根因案为什么要「孤儿闭合符段剔除」──
27
+ * 注释被提前闭合后,`stripComments` 的非贪婪匹配在**第一个闭合符**处收口 ⇒ cleaned 里残留
28
+ * 「孤儿闭合符 + 残渣文本」;残渣与紧随的规则选择器**黏成同一段**(直到 `{`)——运行时解析器把
29
+ * 这一整段当无效选择器 ⇒ **规则整条被吞**(这正是样式丢失的机制)。若直接照抄提及集口径,黏住的
30
+ * 类名照样被抓出来 ⇒ 假绿(根因案不红)。本腿在收提及集前先找**孤儿闭合符**(cleaned 中已无配对
31
+ * 注释 ⇒ 任何存活的星号+斜杠相邻对都是提前闭合的产物;字符串里的跳过):含孤儿的选择器段**整段剔除**
32
+ * ——与运行时「规则被吞」如实对齐。剔除的段数记进报告(`orphanSegments`,诊断读数),判红仍走
33
+ * 「引用找不到」这一条路(⛔ 不给孤儿本身单开判红灯——判据写死引用↔定义集比对)。
34
+ *
35
+ * ── fail-closed ──
36
+ * `pluginId` 读不到 ⇒ 前缀无从谈起 ⇒ 报「无法判定」(与前缀腿同一件事同一落点 `plugin.json:1`,
37
+ * 由 lint.ts 的同点去重保证不重复报)——⛔ 不许静默当 0 处通过。
38
+ *
39
+ * 知情绕行 = 标准 disable 注释(`CHECK_IDS.cssNamespace`,与命名空间家族同一 id)。
40
+ */
41
+ import { collectCssUnits, collectFiles, isTestOrMockRel, readSource, relPath, } from "./scan.js";
42
+ import { splitSelector } from "./css-selectors.js";
43
+ import { resolve } from "node:path";
44
+ import { buildDisableIndex, isDisabled, CHECK_IDS } from "./disable.js";
45
+ import { resolvePluginIdForCss } from "./plugin-prefix.js";
46
+ /** 名字形态(与 dangling-names.ts `IDENT` 同款) */
47
+ const IDENT = /^-?[_a-zA-Z][\w-]*$/;
48
+ /** 偏移 → 1-based 行号 */
49
+ const lineAt = (text, index) => text.slice(0, index).split("\n").length;
50
+ /* jscpd:ignore-start */
51
+ /* ↑ className 站点抽取与 `dangling-names.ts` `shoutSites()` 的 className 分支逐行同构——跨判据
52
+ 无法共享私有函数(那边的 literals 混入 classList/querySelector 通道,本腿射程写死只收
53
+ className)⇒ 复制窄化为 className 单通道,口径由单测钉住。 */
54
+ /**
55
+ * className 站点抽取(**只收 className 赋值位的字符串字面量**):`className: "x"` / `className="x"` /
56
+ * `className={"x"}`。模板插值(含 `${`)与非字面量(变量 / 函数调用 / 三元)一律**跳过并计数**。
57
+ */
58
+ function ownClassNameSites(text) {
59
+ const literals = [];
60
+ const skipped = { interp: 0, dynamic: 0 };
61
+ const push = (raw, at) => {
62
+ const line = lineAt(text, at);
63
+ for (const tok of raw.split(/\s+/)) {
64
+ if (IDENT.test(tok))
65
+ literals.push({ name: tok, line });
66
+ }
67
+ };
68
+ // 与 dangling-names 的 scanCode 同款极简词法:跳过注释/字符串/正则,只走代码
69
+ let i = 0;
70
+ const regexAllowed = (prev) => prev === "" || /[([{,;:=!&|?+\-*%~^<>]/.test(prev) || prev === "return" || prev === "typeof";
71
+ let prev = "";
72
+ while (i < text.length) {
73
+ const c = text[i];
74
+ const c2 = text[i + 1];
75
+ if (c === "/" && c2 === "/") {
76
+ const e = text.indexOf("\n", i);
77
+ i = e < 0 ? text.length : e + 1;
78
+ continue;
79
+ }
80
+ if (c === "/" && c2 === "*") {
81
+ const e = text.indexOf("*/", i + 2);
82
+ i = e < 0 ? text.length : e + 2;
83
+ continue;
84
+ }
85
+ if (c === '"' || c === "'") {
86
+ // 字符串里出现的 "className" 不是站点——但要跳过整段防误入
87
+ let j = i + 1;
88
+ while (j < text.length) {
89
+ if (text[j] === "\\") {
90
+ j += 2;
91
+ continue;
92
+ }
93
+ if (text[j] === c)
94
+ break;
95
+ j++;
96
+ }
97
+ i = j + 1;
98
+ prev = '"';
99
+ continue;
100
+ }
101
+ if (c === "`") {
102
+ // 模板:正文跳过,${} 内是代码——但 ${} 里的 className 站点极少且多伴插值,仍走一遍防漏
103
+ let j = i + 1;
104
+ while (j < text.length) {
105
+ if (text[j] === "\\") {
106
+ j += 2;
107
+ continue;
108
+ }
109
+ if (text[j] === "`")
110
+ break;
111
+ if (text[j] === "$" && text[j + 1] === "{") {
112
+ let depth = 1;
113
+ let k = j + 2;
114
+ while (k < text.length && depth > 0) {
115
+ const k2 = text[k];
116
+ if (k2 === '"' || k2 === "'" || k2 === "`") { // 嵌套字符串/模板粗跳
117
+ const q = k2;
118
+ k++;
119
+ while (k < text.length && text[k] !== q) {
120
+ if (text[k] === "\\")
121
+ k++;
122
+ k++;
123
+ }
124
+ k++;
125
+ continue;
126
+ }
127
+ if (k2 === "{")
128
+ depth++;
129
+ else if (k2 === "}")
130
+ depth--;
131
+ k++;
132
+ }
133
+ j = k;
134
+ continue;
135
+ }
136
+ j++;
137
+ }
138
+ i = j + 1;
139
+ prev = "`";
140
+ continue;
141
+ }
142
+ if (c === "/" && regexAllowed(prev)) {
143
+ let j = i + 1;
144
+ let inClass = false;
145
+ while (j < text.length) {
146
+ const r = text[j];
147
+ if (r === "\\") {
148
+ j += 2;
149
+ continue;
150
+ }
151
+ if (r === "[")
152
+ inClass = true;
153
+ else if (r === "]")
154
+ inClass = false;
155
+ else if (r === "/" && !inClass)
156
+ break;
157
+ else if (r === "\n")
158
+ break;
159
+ j++;
160
+ }
161
+ i = j;
162
+ prev = "/";
163
+ continue;
164
+ }
165
+ if (/[A-Za-z_$]/.test(c)) {
166
+ let j = i;
167
+ while (j < text.length && /[\w$]/.test(text[j]))
168
+ j++;
169
+ const word = text.slice(i, j);
170
+ if (word === "className") {
171
+ let k = j;
172
+ while (k < text.length && /\s/.test(text[k]))
173
+ k++;
174
+ // 必须是赋值位(`className: "x"` / `className = "x"` / `className={"x"}`)——读法/比较/箭头不是站点
175
+ if (text[k] === ":" || (text[k] === "=" && text[k + 1] !== "=" && text[k + 1] !== ">")) {
176
+ k++;
177
+ while (k < text.length && /\s/.test(text[k]))
178
+ k++;
179
+ let braced = false;
180
+ if (text[k] === "{") {
181
+ braced = true;
182
+ k++;
183
+ while (k < text.length && /\s/.test(text[k]))
184
+ k++;
185
+ }
186
+ const ch = text[k];
187
+ if (ch === '"' || ch === "'") {
188
+ let e = k + 1;
189
+ let raw = "";
190
+ let closed = false;
191
+ while (e < text.length) {
192
+ if (text[e] === "\\") {
193
+ raw += text[e + 1] ?? "";
194
+ e += 2;
195
+ continue;
196
+ }
197
+ if (text[e] === ch) {
198
+ closed = true;
199
+ break;
200
+ }
201
+ raw += text[e];
202
+ e++;
203
+ }
204
+ if (closed) {
205
+ if (braced) {
206
+ let z = e + 1;
207
+ while (z < text.length && /\s/.test(text[z]))
208
+ z++;
209
+ if (text[z] !== "}") {
210
+ skipped.dynamic++;
211
+ i = j;
212
+ prev = word;
213
+ continue;
214
+ }
215
+ }
216
+ push(raw, k);
217
+ i = j;
218
+ prev = word;
219
+ continue;
220
+ }
221
+ skipped.dynamic++;
222
+ i = j;
223
+ prev = word;
224
+ continue;
225
+ }
226
+ if (ch === "`") {
227
+ let e = k + 1;
228
+ let raw = "";
229
+ let closed = false;
230
+ while (e < text.length) {
231
+ if (text[e] === "\\") {
232
+ raw += text[e + 1] ?? "";
233
+ e += 2;
234
+ continue;
235
+ }
236
+ if (text[e] === "`") {
237
+ closed = true;
238
+ break;
239
+ }
240
+ raw += text[e];
241
+ e++;
242
+ }
243
+ if (closed && raw.includes("${")) {
244
+ skipped.interp++;
245
+ i = j;
246
+ prev = word;
247
+ continue;
248
+ }
249
+ if (closed) {
250
+ if (braced) {
251
+ let z = e + 1;
252
+ while (z < text.length && /\s/.test(text[z]))
253
+ z++;
254
+ if (text[z] !== "}") {
255
+ skipped.dynamic++;
256
+ i = j;
257
+ prev = word;
258
+ continue;
259
+ }
260
+ }
261
+ push(raw, k);
262
+ i = j;
263
+ prev = word;
264
+ continue;
265
+ }
266
+ skipped.dynamic++;
267
+ i = j;
268
+ prev = word;
269
+ continue;
270
+ }
271
+ skipped.dynamic++; // 变量 / clsx(...) / 三元 …… 静态读不出
272
+ i = j;
273
+ prev = word;
274
+ continue;
275
+ }
276
+ }
277
+ prev = word;
278
+ i = j;
279
+ continue;
280
+ }
281
+ if (!/\s/.test(c))
282
+ prev = c;
283
+ i++;
284
+ }
285
+ return { literals, skipped };
286
+ }
287
+ /* jscpd:ignore-end */
288
+ /** 本腿扫描的扩展名(判据写死 `.ts`/`.tsx`——TSX 是 className 的主通道) */
289
+ const JS_EXTS = [".ts", ".tsx"];
290
+ /** 一个选择器里的类名(剥属性选择器后再抓 `.x`——与 dangling-names.ts 同款口径) */
291
+ const classTokensIn = (sel) => [...String(sel).replace(/\[[^\]]*\]/g, " ").matchAll(/\.(-?[_a-zA-Z][\w-]*)/g)].map((m) => m[1]);
292
+ /** cleaned(已剥配对注释)里的**孤儿闭合符**:任何存活的「星号+斜杠」相邻对都是注释内容提前闭合的产物(字符串里的跳过) */
293
+ export function orphanCloseIndices(cleaned) {
294
+ const out = [];
295
+ let i = 0;
296
+ while (i < cleaned.length) {
297
+ const c = cleaned[i];
298
+ if (c === '"' || c === "'") {
299
+ const q = c;
300
+ i++;
301
+ while (i < cleaned.length && cleaned[i] !== q) {
302
+ if (cleaned[i] === "\\")
303
+ i++;
304
+ i++;
305
+ }
306
+ i++;
307
+ continue;
308
+ }
309
+ if (c === "*" && cleaned[i + 1] === "/") {
310
+ out.push(i);
311
+ i += 2;
312
+ continue;
313
+ }
314
+ i++;
315
+ }
316
+ return out;
317
+ }
318
+ /** 报点文案(作者面:名字 + 出处 + 三种常见根因 + 修法) */
319
+ function messageOf(site) {
320
+ return (`\`${site.name}\`(className 引用,本仓 ${site.file}:${site.line})在本仓 CSS 定义集里找不到 ⇒ ` +
321
+ `样式**静默不生效**(零报错,只有界面不对)。三种常见根因:① 类名两边拼错(TSX 与 CSS 对不上);` +
322
+ `② 定义它的样式文件没被 import 进入口;③ CSS 块注释里写了 \`--token-*/\` 这类文本——\`*/\` 会把` +
323
+ `注释**提前闭合**,注释后的残渣黏住下一条规则把它整条吞掉(生态首例:一个游戏插件的根类名就是这样` +
324
+ `丢的,靠逐条截图比对才找到)。修法:对齐两边类名 / 补 import / 把注释里的 \`*/\` 改掉(token 族名` +
325
+ `之间用空格或顿号分开,别用 \`/\`)。知情绕行 = // eslint-disable-next-line ${CHECK_IDS.cssNamespace} -- 理由。`);
326
+ }
327
+ /**
328
+ * 跑本仓自有类名引用悬空判据。⚠️ `resolution` 可注入(单测用);缺省从工程根 plugin.json 解析。
329
+ */
330
+ export function runDanglingOwnClassCheck(root, opts = {}) {
331
+ const absRoot = resolve(root);
332
+ const resolution = opts.resolution ?? resolvePluginIdForCss(absRoot);
333
+ const report = {
334
+ root: absRoot,
335
+ pluginId: resolution.pluginId,
336
+ error: resolution.error,
337
+ ownRefs: 0,
338
+ ownDefs: 0,
339
+ orphanSegments: 0,
340
+ skipped: { interp: 0, dynamic: 0 },
341
+ dangling: [],
342
+ violations: [],
343
+ };
344
+ // 🔴 fail-closed(不可豁免):pluginId 读不到 ⇒ 前缀无从谈起 ⇒ 「无法判定」报红——⛔ 不许当 0 处通过
345
+ if (resolution.error || !resolution.pluginId) {
346
+ report.violations.push({
347
+ file: "plugin.json",
348
+ line: 1,
349
+ message: "工程 pluginId **读不到** ⇒ 自有类名悬空判据**无法判定**(判定轴心 = `<pluginId>-` 前缀)。「0 处通过」" +
350
+ "在这里是假绿(假绿比假红更坏:你会以为已经查过了)。修复:补好工程根 plugin.json 的 pluginId 字段。",
351
+ });
352
+ return report;
353
+ }
354
+ const prefix = `${resolution.pluginId}-`;
355
+ // ① 本仓 CSS 定义集先**全量收齐**(提及集口径 + 孤儿 `*/` 段剔除——与 collectCssUnits 同一批站点/豁免索引)
356
+ const cssUnits = collectCssUnits(absRoot, [CHECK_IDS.cssNamespace]);
357
+ const ownDefs = new Set();
358
+ for (const unit of cssUnits) {
359
+ const orphans = orphanCloseIndices(unit.cleaned);
360
+ for (const m of unit.cleaned.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
361
+ const sel = m[1].trim();
362
+ const segStart = m.index ?? 0;
363
+ const segEnd = segStart + m[1].length;
364
+ // 🔴 该选择器段含孤儿 `*/` ⇒ 残渣黏连、运行时已把这条规则整段吞掉 ⇒ 剔除(与运行时如实)
365
+ let hasOrphan = false;
366
+ for (const o of orphans) {
367
+ if (o >= segStart && o < segEnd) {
368
+ hasOrphan = true;
369
+ break;
370
+ }
371
+ }
372
+ if (hasOrphan) {
373
+ report.orphanSegments++;
374
+ continue;
375
+ }
376
+ if (sel.startsWith("@") || !m[2].trim())
377
+ continue;
378
+ for (const one of splitSelector(sel.replace(/\[[^\]]*\]/g, " "))) {
379
+ for (const n of classTokensIn(one))
380
+ ownDefs.add(n);
381
+ }
382
+ }
383
+ }
384
+ report.ownDefs = ownDefs.size;
385
+ const sites = [];
386
+ for (const file of collectFiles(absRoot, JS_EXTS)) {
387
+ const rel = relPath(absRoot, file);
388
+ if (isTestOrMockRel(rel))
389
+ continue;
390
+ const src = readSource(file);
391
+ const { literals, skipped } = ownClassNameSites(src);
392
+ report.skipped.interp += skipped.interp;
393
+ report.skipped.dynamic += skipped.dynamic;
394
+ if (literals.length === 0)
395
+ continue;
396
+ const disabled = buildDisableIndex(src, [CHECK_IDS.cssNamespace]);
397
+ for (const l of literals)
398
+ sites.push({ site: l, rel, disabled });
399
+ }
400
+ // ③ 判定:自有前缀 + 定义集里没有 ⇒ 悬空
401
+ const dangling = new Map();
402
+ for (const { site, rel, disabled } of sites) {
403
+ if (!site.name.startsWith(prefix))
404
+ continue; // 只判本插件前缀(窄口子)
405
+ report.ownRefs++;
406
+ if (ownDefs.has(site.name))
407
+ continue;
408
+ if (isDisabled(disabled, site.line, CHECK_IDS.cssNamespace))
409
+ continue;
410
+ const entry = { name: site.name, file: rel, line: site.line };
411
+ if (!dangling.has(site.name))
412
+ dangling.set(site.name, entry);
413
+ }
414
+ report.dangling = [...dangling.values()].sort((x, y) => x.name.localeCompare(y.name) || x.file.localeCompare(y.file) || x.line - y.line);
415
+ for (const site of report.dangling) {
416
+ report.violations.push({ file: site.file, line: site.line, message: messageOf(site) });
417
+ }
418
+ return report;
419
+ }
420
+ //# sourceMappingURL=dangling-own-classes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dangling-own-classes.js","sourceRoot":"","sources":["../../../src/eslint/checks/dangling-own-classes.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,9 @@ export declare const CHECK_IDS: {
36
36
  * ⚠️ 本 id 在 CHECK_IDS 里**仅作文档**:`checks/ui-css-import.ts` 刻意不接 disable 机制
37
37
  * (「知情地把样式烤死」是语义错误不是合法偏离),eslint-disable 注释对它无效。 */
38
38
  readonly uiCssImport: "linkdesk/no-ui-css-import";
39
+ /** E6#137(2026-09-20):window/document 全局 keydown/keyup 监听判红——正解 = 容器 onKeyDown +
40
+ * tabIndex(focus 分区);确需全局抓键的正当形态(快捷键录制器)走 disable + 理由(判据无白名单)。 */
41
+ readonly noGlobalKeyListener: "linkdesk/no-global-key-listener";
39
42
  };
40
43
  export interface DisableIndex {
41
44
  /** 1-based 行 → 该行豁免的 id 集合(行级 next-line/line + 文件级 disable 区间) */
@@ -1 +1 @@
1
- {"version":3,"file":"disable.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/disable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS;;;;;IAKpB,oEAAoE;;IAEpE,qEAAqE;;IAErE;;;gFAG4E;;IAE5E;;;oEAGgE;;IAEhE;;yDAEqD;;CAE7C,CAAC;AAoFX,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAClC;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,CAmDnF;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAGjF"}
1
+ {"version":3,"file":"disable.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/disable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS;;;;;IAKpB,oEAAoE;;IAEpE,qEAAqE;;IAErE;;;gFAG4E;;IAE5E;;;oEAGgE;;IAEhE;;yDAEqD;;IAErD;wEACoE;;CAE5D,CAAC;AAoFX,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAClC;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,CAmDnF;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAGjF"}
@@ -36,6 +36,9 @@ export const CHECK_IDS = {
36
36
  * ⚠️ 本 id 在 CHECK_IDS 里**仅作文档**:`checks/ui-css-import.ts` 刻意不接 disable 机制
37
37
  * (「知情地把样式烤死」是语义错误不是合法偏离),eslint-disable 注释对它无效。 */
38
38
  uiCssImport: "linkdesk/no-ui-css-import",
39
+ /** E6#137(2026-09-20):window/document 全局 keydown/keyup 监听判红——正解 = 容器 onKeyDown +
40
+ * tabIndex(focus 分区);确需全局抓键的正当形态(快捷键录制器)走 disable + 理由(判据无白名单)。 */
41
+ noGlobalKeyListener: "linkdesk/no-global-key-listener",
39
42
  };
40
43
  /** 单遍注释 tokenizer:产出全部 // 行注释与 /* 块注释(块注释可跨行)。 */
41
44
  function tokenizeComments(source) {
@@ -1 +1 @@
1
- {"version":3,"file":"disable.js","sourceRoot":"","sources":["../../../src/eslint/checks/disable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,WAAW,EAAE,2BAA2B;IACxC,SAAS,EAAE,iCAAiC;IAC5C,WAAW,EAAE,iCAAiC;IAC9C,YAAY,EAAE,iCAAiC;IAC/C,oEAAoE;IACpE,gBAAgB,EAAE,gCAAgC;IAClD,qEAAqE;IACrE,eAAe,EAAE,gCAAgC;IACjD;;;gFAG4E;IAC5E,mBAAmB,EAAE,mCAAmC;IACxD;;;oEAGgE;IAChE,gBAAgB,EAAE,iCAAiC;IACnD;;yDAEqD;IACrD,WAAW,EAAE,2BAA2B;CAChC,CAAC;AAQX,kDAAkD;AAClD,SAAS,gBAAgB,CAAC,MAAc;IACtC,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACb,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,IAAI,EAAE,CAAC;YACP,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,SAAS;YACT,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC,GAAG,CAAC,CAAC;YACN,SAAS;QACX,CAAC;QACD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,WAAW;YACX,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,IAAI,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC9D,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;oBAAE,CAAC,EAAE,CAAC;gBAC5B,CAAC,EAAE,CAAC;YACN,CAAC;YACD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;YAC1C,oBAAoB;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;gBAAE,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;oBAAE,IAAI,EAAE,CAAC;YAC7D,CAAC,GAAG,GAAG,CAAC;YACR,SAAS;QACX,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AASD,MAAM,UAAU,GAAG,UAAU,CAAC;AAE9B,SAAS,YAAY,CAAC,OAAmB;IACvC,kDAAkD;IAClD,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC3F,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,IAAI,GACR,IAAI,KAAK,0BAA0B;QACjC,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,IAAI,KAAK,qBAAqB;YAC9B,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,IAAI,KAAK,gBAAgB;gBACzB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,QAAQ,CAAC;IACnB,+CAA+C;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChF,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;AACxE,CAAC;AAOD,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,SAAmB;IACnE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAU,EAAQ,EAAE;QAC3C,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC;QACD,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAExF,qCAAqC;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,mBAAmB;IAC5D,oCAAoC;IACpC,MAAM,OAAO,GAAG,CAAC,GAAa,EAAY,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjH,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,IAAY,EAAE,WAAmB,EAAQ,EAAE;QACzE,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB;oBACnD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,KAAK;QAAE,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;IAErE,yBAAyB;IACzB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,UAAU,CAAC,KAAmB,EAAE,IAAY,EAAE,EAAU;IACtE,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"disable.js","sourceRoot":"","sources":["../../../src/eslint/checks/disable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * check 腿——**window/document 全局键盘监听判红**(E6#137 · 2026-09-20)。
3
+ *
4
+ * ── 这条禁令为什么现在才有腿 ──
5
+ * 作者面 [05-ui-conventions §4.2](../../../../../docs/03-plugin-authoring/05-ui-conventions.md) 早已
6
+ * 定案键盘两轨制:声明式 keybindings(非文本键)+ **focus 分区**(容器 `onKeyDown` + `tabIndex`,
7
+ * DOM focus 天然分区)⇒ `window`/`document` 级 keydown/keyup 是点名的反模式(历史案:serial F2
8
+ * 劫持 file tree F2)。但规约只是文档——SDK 没有任何腿拦它 = **空转判据**。生态首个第三方 AI 作者
9
+ * 实测即写了 `window.addEventListener("keydown")`;核对会话随即摸底 18 仓,**官方仓自己命中 3 处**
10
+ * (serial-monitor SearchBar 两处、settings 快捷键录制器一处)——这条腿不是对第三方作者的苛求,
11
+ * 是工程自己的欠账。
12
+ *
13
+ * ── 判定式(窄口子,不猜写法)──
14
+ * 扫插件工程源文件(.ts/.tsx/.js/.jsx)里 `(window|document).addEventListener(<"keydown"|"keyup"
15
+ * 字面量">, …)` **本身**即违规——第三个参数(capture)带不带都一样红(全局抓键的形态问题与
16
+ * capture 无关);单双引号都认。键名走**变量**的形态(`addEventListener(EVENT, …)`)静态读不出
17
+ * ⇒ 不判(判据写死字面量;假红比漏报更坏的姊妹口径:窄射程宁可漏,不猜)。注释里的提及不算
18
+ * (stripComments / stripLineComments 同其余 check)。
19
+ *
20
+ * ── 报文教正解(插件自由制造——不是只堵)──
21
+ * focus 分区正解 = 容器 `onKeyDown` + `tabIndex={0}`(DOM focus 天然分区,见作者面
22
+ * 05-ui-conventions §4.2);确需全局抓键的**正当形态**(如快捷键录制器要在输入被吞前抓原始键)走
23
+ * 标准 disable 注释 + 行尾理由——**判据本身无白名单**(settings 录制器的裁决走豁免注释,不进本腿)。
24
+ */
25
+ import { type CheckViolation } from "./scan.js";
26
+ export declare const GLOBAL_KEY_LISTENER_ID: "linkdesk/no-global-key-listener";
27
+ /** 判级文案——正解 + 豁免出口(报错即文档) */
28
+ export declare const GLOBAL_KEY_LISTENER_WHY: string;
29
+ export interface GlobalKeyListenerReport {
30
+ /** 源码里全局键盘监听站点(豁免的也算在「看见了」里) */
31
+ sites: {
32
+ file: string;
33
+ line: number;
34
+ target: string;
35
+ event: string;
36
+ }[];
37
+ violations: CheckViolation[];
38
+ }
39
+ export declare function runGlobalKeyListenerCheck(root: string): GlobalKeyListenerReport;
40
+ //# sourceMappingURL=no-global-key-listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-global-key-listener.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/no-global-key-listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAQL,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAGnB,eAAO,MAAM,sBAAsB,mCAAgC,CAAC;AAEpE,6BAA6B;AAC7B,eAAO,MAAM,uBAAuB,QAI4B,CAAC;AAOjE,MAAM,WAAW,uBAAuB;IACtC,gCAAgC;IAChC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvE,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,uBAAuB,CAwB/E"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * check 腿——**window/document 全局键盘监听判红**(E6#137 · 2026-09-20)。
3
+ *
4
+ * ── 这条禁令为什么现在才有腿 ──
5
+ * 作者面 [05-ui-conventions §4.2](../../../../../docs/03-plugin-authoring/05-ui-conventions.md) 早已
6
+ * 定案键盘两轨制:声明式 keybindings(非文本键)+ **focus 分区**(容器 `onKeyDown` + `tabIndex`,
7
+ * DOM focus 天然分区)⇒ `window`/`document` 级 keydown/keyup 是点名的反模式(历史案:serial F2
8
+ * 劫持 file tree F2)。但规约只是文档——SDK 没有任何腿拦它 = **空转判据**。生态首个第三方 AI 作者
9
+ * 实测即写了 `window.addEventListener("keydown")`;核对会话随即摸底 18 仓,**官方仓自己命中 3 处**
10
+ * (serial-monitor SearchBar 两处、settings 快捷键录制器一处)——这条腿不是对第三方作者的苛求,
11
+ * 是工程自己的欠账。
12
+ *
13
+ * ── 判定式(窄口子,不猜写法)──
14
+ * 扫插件工程源文件(.ts/.tsx/.js/.jsx)里 `(window|document).addEventListener(<"keydown"|"keyup"
15
+ * 字面量">, …)` **本身**即违规——第三个参数(capture)带不带都一样红(全局抓键的形态问题与
16
+ * capture 无关);单双引号都认。键名走**变量**的形态(`addEventListener(EVENT, …)`)静态读不出
17
+ * ⇒ 不判(判据写死字面量;假红比漏报更坏的姊妹口径:窄射程宁可漏,不猜)。注释里的提及不算
18
+ * (stripComments / stripLineComments 同其余 check)。
19
+ *
20
+ * ── 报文教正解(插件自由制造——不是只堵)──
21
+ * focus 分区正解 = 容器 `onKeyDown` + `tabIndex={0}`(DOM focus 天然分区,见作者面
22
+ * 05-ui-conventions §4.2);确需全局抓键的**正当形态**(如快捷键录制器要在输入被吞前抓原始键)走
23
+ * 标准 disable 注释 + 行尾理由——**判据本身无白名单**(settings 录制器的裁决走豁免注释,不进本腿)。
24
+ */
25
+ import { collectFiles, isTestOrMockRel, readSource, stripComments, stripLineComments, countNewlines, relPath, } from "./scan.js";
26
+ import { buildDisableIndex, isDisabled, CHECK_IDS } from "./disable.js";
27
+ export const GLOBAL_KEY_LISTENER_ID = CHECK_IDS.noGlobalKeyListener;
28
+ /** 判级文案——正解 + 豁免出口(报错即文档) */
29
+ export const GLOBAL_KEY_LISTENER_WHY = "全局 keydown/keyup 会劫持整个窗口的按键(历史案:serial 插件抢 F2 连文件树一起失效)。" +
30
+ "focus 分区正解 = 在你的容器上写 `onKeyDown` + `tabIndex={0}`(DOM focus 天然分区,聚焦谁谁收到;" +
31
+ "见作者面 05-ui-conventions §4.2)。确需全局抓键的正当形态(如快捷键录制器)= " +
32
+ `// eslint-disable-next-line ${GLOBAL_KEY_LISTENER_ID} -- 理由。`;
33
+ const EXT = [".ts", ".tsx", ".js", ".jsx"];
34
+ /** 违规物 = window/document + addEventListener + 键名**字面量**(keydown/keyup;capture 参数无关) */
35
+ const GLOBAL_KEY_RE = /\b(window|document)\s*\.\s*addEventListener\s*\(\s*(['"])(keydown|keyup)\2/g;
36
+ export function runGlobalKeyListenerCheck(root) {
37
+ const report = { sites: [], violations: [] };
38
+ for (const abs of collectFiles(root, EXT)) {
39
+ const rel = relPath(root, abs);
40
+ if (isTestOrMockRel(rel))
41
+ continue; // 与其余 check 同口径:测试夹具里的字符串不是真监听
42
+ const src = readSource(abs);
43
+ const cleaned = stripLineComments(stripComments(src));
44
+ const disabled = buildDisableIndex(src, [GLOBAL_KEY_LISTENER_ID]);
45
+ const re = new RegExp(GLOBAL_KEY_RE.source, "g");
46
+ let m;
47
+ while ((m = re.exec(cleaned)) !== null) {
48
+ const line = countNewlines(cleaned.slice(0, m.index)) + 1;
49
+ report.sites.push({ file: rel, line, target: m[1], event: m[3] });
50
+ if (isDisabled(disabled, line, GLOBAL_KEY_LISTENER_ID))
51
+ continue;
52
+ report.violations.push({
53
+ file: rel,
54
+ line,
55
+ message: `在 ${m[1]} 上全局监听 \`${m[3]}\`(${rel}:${line})——这是壳点名的反模式。${GLOBAL_KEY_LISTENER_WHY}`,
56
+ });
57
+ }
58
+ }
59
+ report.violations.sort((x, y) => x.file.localeCompare(y.file) || x.line - y.line);
60
+ return report;
61
+ }
62
+ //# sourceMappingURL=no-global-key-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-global-key-listener.js","sourceRoot":"","sources":["../../../src/eslint/checks/no-global-key-listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,OAAO,GAER,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC,mBAAmB,CAAC;AAEpE,6BAA6B;AAC7B,MAAM,CAAC,MAAM,uBAAuB,GAClC,0DAA0D;IAC1D,0EAA0E;IAC1E,qDAAqD;IACrD,+BAA+B,sBAAsB,SAAS,CAAC;AAEjE,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAE3C,uFAAuF;AACvF,MAAM,aAAa,GAAG,6EAA6E,CAAC;AAQpG,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,MAAM,MAAM,GAA4B,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACtE,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,eAAe,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,+BAA+B;QACnE,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAClE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClE,IAAI,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,sBAAsB,CAAC;gBAAE,SAAS;YACjE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gBACrB,IAAI,EAAE,GAAG;gBACT,IAAI;gBACJ,OAAO,EACL,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,IAAI,gBAAgB,uBAAuB,EAAE;aACtF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -55,6 +55,21 @@ export interface PluginLintReport {
55
55
  hostClassCount: number;
56
56
  hostKeyframeCount: number;
57
57
  };
58
+ /** 🔴 E6#136(2026-09-20):自有类名引用悬空腿读数(refs = 自有前缀引用站点;defs = 本仓 CSS 提及集;
59
+ * orphanSegments = 含孤儿闭合符被剔除的选择器段——根因案信号) */
60
+ danglingOwnClassCounts: {
61
+ refs: number;
62
+ defs: number;
63
+ dangling: number;
64
+ orphanSegments: number;
65
+ skippedInterp: number;
66
+ skippedDynamic: number;
67
+ };
68
+ /** 🔴 E6#137(2026-09-20):全局键盘监听腿读数(sites = 看见的站点含豁免;red = 判红) */
69
+ globalKeyCounts: {
70
+ sites: number;
71
+ red: number;
72
+ };
58
73
  /** 🟡 E6#119:退役名提示(只提示、⛔ 永不拒绝——不进任何腿报点) */
59
74
  retiredHints: RetiredNameHint[];
60
75
  /** 退役登记账的加载实况(found=false ⇒ 提示空转——报告里必须能看出来,不许静默) */