dsh-structured 0.8.3 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +43 -18
- package/assets/screenshots/09-theme-light.png +0 -0
- package/assets/screenshots/10-theme-dark.png +0 -0
- package/cordis.patch.yml +2 -0
- package/docs/DESIGN-REFERENCES.md +1 -1
- package/docs/RISK-ROLLBACK.md +3 -1
- package/docs/ROADMAP.md +3 -3
- package/docs/VISUAL-CRITIQUE.md +1 -1
- package/docs/VISUAL-PLAN.md +10 -10
- package/lib/client.js +724 -508
- package/lib/index.js +22 -10
- package/package.json +3 -1
- package/screenshots.json +3 -1
- package/scripts/measure-prose.mjs +3 -1
- package/scripts/theme-contrast.mjs +104 -0
- package/src/client.js +724 -508
- package/src/index.js +22 -10
- package/test/client-config-page.test.mjs +273 -0
- package/test/client-visual.test.mjs +130 -3
- package/test/measure-prose.test.mjs +9 -0
- package/test/structured.test.mjs +4 -1
- package/test/theme.test.mjs +121 -0
package/lib/client.js
CHANGED
|
@@ -1,510 +1,726 @@
|
|
|
1
1
|
// Generated from src/client.js by scripts/build.mjs — edit src/, then run `npm run build`.
|
|
2
2
|
// dsh-structured client module: renders "结论:" blockquotes as cards.
|
|
3
|
-
/**
|
|
4
|
-
* dsh-structured client
|
|
5
|
-
*
|
|
6
|
-
* 两层,都是纯 DOM 增强,不改消息内容、不替换 app root:
|
|
7
|
-
* 1) 对话 markdown 视觉层:标题字号/层级、表格、代码块、引用块、列表、链接的排版与配色。
|
|
8
|
-
* 2) 语义装饰:结论卡片、风险/验收等 callout 色调、标题关键词图标、代码块语言色。
|
|
9
|
-
*
|
|
10
|
-
* 只给宿主已有节点加 class/attribute,不搬 React 节点;markdown 重渲染后由 MutationObserver
|
|
11
|
-
* 重新扫描。主题色全部走 --dsw-alias-*,自动跟随明暗主题。
|
|
12
|
-
*/
|
|
13
|
-
window.__ModuleLoader__.load({
|
|
14
|
-
id: 'dsh-structured',
|
|
15
|
-
factory() {
|
|
16
|
-
const CARD_ATTR = 'data-dsh-structured-card'
|
|
17
|
-
const CARD_TYPE_ATTR = 'data-dsh-structured-card-type'
|
|
18
|
-
const ICON_ATTR = 'data-dsh-structured-icon'
|
|
19
|
-
const TONE_ATTR = 'data-dsh-structured-tone'
|
|
20
|
-
const LANG_ATTR = 'data-dsh-structured-lang'
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
[
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
[
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
[
|
|
60
|
-
[
|
|
61
|
-
[
|
|
62
|
-
[
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
[class*="_markdown_"]
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
[class*="_markdown_"]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
[class*="_markdown_"]
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
[class*="_markdown_"]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
[class*="_markdown_"]
|
|
105
|
-
[class*="_markdown_"]
|
|
106
|
-
[class*="_markdown_"]
|
|
107
|
-
[class*="_markdown_"]
|
|
108
|
-
[class*="_markdown_"]
|
|
109
|
-
[class*="_markdown_"]
|
|
110
|
-
[class*="_markdown_"]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
[class*="_markdown_"]
|
|
118
|
-
[class*="_markdown_"]
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
[class*="_markdown_"]
|
|
123
|
-
[class*="_markdown_"]
|
|
124
|
-
[class*="_markdown_"] :not(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
background:var(--ds-surface-2);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
[class*="_markdown_"]
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
[class*="_markdown_"]
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
[class*="_markdown_"]
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
[class*="_markdown_"]
|
|
148
|
-
[class*="_markdown_"]
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
[class*="_markdown_"]
|
|
155
|
-
[class*="_markdown_"]
|
|
156
|
-
[class*="_markdown_"]
|
|
157
|
-
[class*="_markdown_"]
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
[class*="_markdown_"]
|
|
162
|
-
[class*="_markdown_"]
|
|
163
|
-
[class*="_markdown_"]
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
[class*="_markdown_"]
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
border-radius:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
[class*="_markdown_"]
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
[class*="_markdown_"]
|
|
200
|
-
[class*="_markdown_"]
|
|
201
|
-
[class*="_markdown_"]
|
|
202
|
-
[class*="_markdown_"]
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
[class*="_markdown_"] blockquote
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
[class*="_markdown_"] blockquote[${
|
|
212
|
-
--ds-accent
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
[class*="_markdown_"] blockquote[${
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
[class*="_markdown_"] blockquote[${
|
|
229
|
-
|
|
230
|
-
color:var(--ds-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
[class*="_markdown_"]
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
[class*="_markdown_"]
|
|
239
|
-
[class*="_markdown_"]
|
|
240
|
-
[class*="_markdown_"]
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
for (
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
if (
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
3
|
+
/**
|
|
4
|
+
* dsh-structured client
|
|
5
|
+
*
|
|
6
|
+
* 两层,都是纯 DOM 增强,不改消息内容、不替换 app root:
|
|
7
|
+
* 1) 对话 markdown 视觉层:标题字号/层级、表格、代码块、引用块、列表、链接的排版与配色。
|
|
8
|
+
* 2) 语义装饰:结论卡片、风险/验收等 callout 色调、标题关键词图标、代码块语言色。
|
|
9
|
+
*
|
|
10
|
+
* 只给宿主已有节点加 class/attribute,不搬 React 节点;markdown 重渲染后由 MutationObserver
|
|
11
|
+
* 重新扫描。主题色全部走 --dsw-alias-*,自动跟随明暗主题。
|
|
12
|
+
*/
|
|
13
|
+
window.__ModuleLoader__.load({
|
|
14
|
+
id: 'dsh-structured',
|
|
15
|
+
factory(require) {
|
|
16
|
+
const CARD_ATTR = 'data-dsh-structured-card'
|
|
17
|
+
const CARD_TYPE_ATTR = 'data-dsh-structured-card-type'
|
|
18
|
+
const ICON_ATTR = 'data-dsh-structured-icon'
|
|
19
|
+
const TONE_ATTR = 'data-dsh-structured-tone'
|
|
20
|
+
const LANG_ATTR = 'data-dsh-structured-lang'
|
|
21
|
+
const CODE_ATTR = 'data-dsh-structured-code'
|
|
22
|
+
const SKIP_ATTR = 'data-dsh-structured-skip'
|
|
23
|
+
const STATUS_ATTR = 'data-dsh-structured-status'
|
|
24
|
+
const STATUS_TABLE_ATTR = 'data-dsh-structured-status-table'
|
|
25
|
+
const LEAD_ATTR = 'data-dsh-structured-lead'
|
|
26
|
+
const ROW_ATTR = 'data-dsh-structured-row'
|
|
27
|
+
const ROOT_ATTR = 'data-dsh-structured'
|
|
28
|
+
const THEME_ATTR = 'data-dsh-structured-theme'
|
|
29
|
+
const THEMES = ['deepseek', 'codex', 'anthropic']
|
|
30
|
+
const STYLE_ID = 'dsh-structured-skin-style'
|
|
31
|
+
const LEGACY_STYLE_ID = 'dsh-structured-card-style'
|
|
32
|
+
|
|
33
|
+
/** 配置页常量:宿主插件详情页的 bundle 配置 slot(键 = 包名)。 */
|
|
34
|
+
const CONFIG_NS = 'dsh-structured'
|
|
35
|
+
const BUNDLE_CONFIG_SLOT = 'plugins.bundle.config'
|
|
36
|
+
|
|
37
|
+
/** 六个配置字段的界面文案;field 与 host Config schema 对齐,fallback 为 schema 默认值。 */
|
|
38
|
+
const CONFIG_FIELDS = [
|
|
39
|
+
{ field: 'theme', kind: 'segmented', fallback: 'deepseek', label: '主题 / Theme', hint: '回复区配色,改完立即生效', options: [['deepseek', 'DeepSeek'], ['codex', 'Codex'], ['anthropic', 'Anthropic']] },
|
|
40
|
+
{ field: 'visual', kind: 'switch', fallback: true, label: '视觉层 / Visual layer', hint: '关闭后不加载回复区样式(标题卡、表格、代码块皮肤)' },
|
|
41
|
+
{ field: 'defaultEnabled', kind: 'switch', fallback: true, label: '新会话默认开启 / Default on', hint: '新会话默认注入结构化提示词' },
|
|
42
|
+
{ field: 'tailReminder', kind: 'switch', fallback: true, label: '尾部提醒 / Tail reminder', hint: '在 system prompt 末尾追加一句结构化提醒' },
|
|
43
|
+
{ field: 'includeSubagents', kind: 'switch', fallback: false, label: '子代理注入 / Subagents', hint: '子代理会话也注入(其产出不直接面向用户)' },
|
|
44
|
+
{ field: 'genui', kind: 'segmented', fallback: 'auto', label: 'GenUI 联动 / GenUI routing', hint: 'auto:检测到 dsh-genui 才追加 dsh-ui 路由规则', options: [['auto', 'auto'], ['on', 'on'], ['off', 'off']] },
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
const CARD_TYPES = new Map([
|
|
48
|
+
['结论', 'conclusion'], ['总结', 'conclusion'], ['答案', 'conclusion'],
|
|
49
|
+
['判断', 'decision'], ['决策', 'decision'],
|
|
50
|
+
['指标', 'metric'], ['数据', 'metric'],
|
|
51
|
+
['风险', 'risk'], ['注意', 'risk'], ['警告', 'risk'],
|
|
52
|
+
['下一步', 'next'], ['行动', 'next'], ['待办', 'next'],
|
|
53
|
+
['验收', 'accept'], ['通过', 'accept'], ['完成', 'accept'],
|
|
54
|
+
['重点', 'key'], ['关键', 'key'],
|
|
55
|
+
])
|
|
56
|
+
const ICONS = [
|
|
57
|
+
[/结论|总结|答案|判断/, '◆'],
|
|
58
|
+
[/方案|计划|步骤|流程/, '▸'],
|
|
59
|
+
[/风险|注意|警告|坑/, '⚠'],
|
|
60
|
+
[/验收|检查|核对/, '✓'],
|
|
61
|
+
[/对比|选型|取舍/, '⇄'],
|
|
62
|
+
[/下一步|行动|待办/, '→'],
|
|
63
|
+
[/背景|原因|根因/, '◎'],
|
|
64
|
+
[/指标|数据|结果/, '▦'],
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
const CSS = `
|
|
68
|
+
[class*="_markdown_"]{
|
|
69
|
+
--ds-surface:#FFFFFF;--ds-surface-2:#F4F7FB;--ds-text:#0F172A;--ds-muted:#5B6B82;
|
|
70
|
+
--ds-border:#E2E8F0;--ds-accent:#2563EB;--ds-accent-text:#2563EB;--ds-success:#166534;--ds-warn:#92400E;--ds-error:#991B1B;
|
|
71
|
+
--ds-code-bg:#F6F8FA;--ds-code-text:#0F172A;
|
|
72
|
+
font-size:15px;line-height:1.72;letter-spacing:.01em;
|
|
73
|
+
}
|
|
74
|
+
body[data-ds-dark-theme] [class*="_markdown_"]{
|
|
75
|
+
--ds-surface:#111827;--ds-surface-2:#1F2937;--ds-text:#E5E7EB;--ds-muted:#9CA3AF;
|
|
76
|
+
--ds-border:#374151;--ds-accent:#60A5FA;--ds-accent-text:#60A5FA;--ds-success:#4ADE80;--ds-warn:#FBBF24;--ds-error:#F87171;
|
|
77
|
+
--ds-code-bg:#0B1220;--ds-code-text:#E5E7EB;
|
|
78
|
+
}
|
|
79
|
+
body[data-dsh-structured-theme="codex"] [class*="_markdown_"]{
|
|
80
|
+
--ds-surface:#FFFFFF;--ds-surface-2:#F0F7F4;--ds-text:#0D1117;--ds-muted:#4F625A;
|
|
81
|
+
--ds-border:#CFE3DB;--ds-accent:#10A37F;--ds-accent-text:#0B6B4F;--ds-success:#116329;--ds-warn:#7D4E00;--ds-error:#A40E26;
|
|
82
|
+
--ds-code-bg:#F0F7F4;--ds-code-text:#0D1117;
|
|
83
|
+
}
|
|
84
|
+
body[data-ds-dark-theme][data-dsh-structured-theme="codex"] [class*="_markdown_"]{
|
|
85
|
+
--ds-surface:#0B1512;--ds-surface-2:#12211B;--ds-text:#E6F2EC;--ds-muted:#9DB2A8;
|
|
86
|
+
--ds-border:#233A31;--ds-accent:#34D399;--ds-accent-text:#6EE7B7;--ds-success:#3FB950;--ds-warn:#D29922;--ds-error:#F85149;
|
|
87
|
+
--ds-code-bg:#07100D;--ds-code-text:#E6F2EC;
|
|
88
|
+
}
|
|
89
|
+
body[data-dsh-structured-theme="anthropic"] [class*="_markdown_"]{
|
|
90
|
+
--ds-surface:#FAF9F5;--ds-surface-2:#F5F1E8;--ds-text:#141413;--ds-muted:#6B6359;
|
|
91
|
+
--ds-border:#E5E0D5;--ds-accent:#CC785C;--ds-accent-text:#A14A2E;--ds-success:#266B4D;--ds-warn:#92400E;--ds-error:#8C1D18;
|
|
92
|
+
--ds-code-bg:#F5F1E8;--ds-code-text:#141413;
|
|
93
|
+
}
|
|
94
|
+
body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdown_"]{
|
|
95
|
+
--ds-surface:#1F1E1D;--ds-surface-2:#2A2825;--ds-text:#F5F1E8;--ds-muted:#A8A29A;
|
|
96
|
+
--ds-border:#3A3733;--ds-accent:#E8A087;--ds-accent-text:#E8A087;--ds-success:#6FBF9A;--ds-warn:#E0A458;--ds-error:#F28B82;
|
|
97
|
+
--ds-code-bg:#171614;--ds-code-text:#F5F1E8;
|
|
98
|
+
}
|
|
99
|
+
[class*="_markdown_"] p{margin:.72em 0}
|
|
100
|
+
[class*="_markdown_"] h1,[class*="_markdown_"] h2,[class*="_markdown_"] h3,
|
|
101
|
+
[class*="_markdown_"] h4,[class*="_markdown_"] h5,[class*="_markdown_"] h6{
|
|
102
|
+
color:var(--ds-text);line-height:1.32;letter-spacing:-.01em;
|
|
103
|
+
}
|
|
104
|
+
[class*="_markdown_"] h1{font-size:26px;font-weight:700;margin:32px 0 12px;padding-bottom:8px;border-bottom:1px solid var(--ds-border)}
|
|
105
|
+
[class*="_markdown_"] h2{font-size:21px;font-weight:700;margin:28px 0 10px;padding-left:12px;border-left:3px solid var(--ds-accent)}
|
|
106
|
+
[class*="_markdown_"] h3{font-size:17px;font-weight:650;margin:22px 0 8px}
|
|
107
|
+
[class*="_markdown_"] h4{font-size:15px;font-weight:650;margin:16px 0 6px}
|
|
108
|
+
[class*="_markdown_"] h5,[class*="_markdown_"] h6{font-size:13px;font-weight:700;margin:14px 0 6px;color:var(--ds-muted);text-transform:uppercase;letter-spacing:.06em}
|
|
109
|
+
[class*="_markdown_"] h2[${ICON_ATTR}]::before,
|
|
110
|
+
[class*="_markdown_"] h3[${ICON_ATTR}]::before{
|
|
111
|
+
content:attr(${ICON_ATTR});
|
|
112
|
+
display:inline-flex;align-items:center;justify-content:center;
|
|
113
|
+
width:22px;height:22px;margin-right:8px;border-radius:6px;
|
|
114
|
+
background:color-mix(in srgb,var(--ds-accent) 12%,transparent);
|
|
115
|
+
color:var(--ds-accent-text);font-size:12px;font-weight:700;vertical-align:2px;
|
|
116
|
+
}
|
|
117
|
+
[class*="_markdown_"] strong{font-weight:700;color:var(--ds-text)}
|
|
118
|
+
[class*="_markdown_"] a{color:var(--ds-accent-text);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--ds-accent) 38%,transparent)}
|
|
119
|
+
[class*="_markdown_"] a:hover{border-bottom-color:var(--ds-accent)}
|
|
120
|
+
[class*="_markdown_"] ul,[class*="_markdown_"] ol{padding-left:1.5em;margin:.6em 0}
|
|
121
|
+
[class*="_markdown_"] li{margin:.28em 0}
|
|
122
|
+
[class*="_markdown_"] li::marker{color:var(--ds-accent-text)}
|
|
123
|
+
[class*="_markdown_"] hr{height:1px;border:0;margin:28px 0;background:linear-gradient(90deg,transparent,var(--ds-border),transparent)}
|
|
124
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]){
|
|
125
|
+
width:100%;margin:18px 0;border-collapse:separate;border-spacing:0;
|
|
126
|
+
border:1px solid var(--ds-border);border-radius:12px;overflow:hidden;font-size:13.5px;
|
|
127
|
+
box-shadow:0 1px 2px rgba(0,0,0,.03);
|
|
128
|
+
}
|
|
129
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) thead th{
|
|
130
|
+
background:var(--ds-surface-2);
|
|
131
|
+
font-size:11px!important;letter-spacing:.07em!important;color:var(--ds-muted);
|
|
132
|
+
font-weight:700!important;text-align:left;padding:12px 18px!important;
|
|
133
|
+
border-bottom:1px solid var(--ds-border);
|
|
134
|
+
}
|
|
135
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody td{
|
|
136
|
+
padding:13px 18px!important;line-height:1.55;vertical-align:middle;border-left:0;border-right:0;
|
|
137
|
+
border-bottom:1px solid color-mix(in srgb,var(--ds-border) 55%,transparent);
|
|
138
|
+
word-break:break-word;
|
|
139
|
+
}
|
|
140
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody tr:nth-child(even){background:color-mix(in srgb,var(--ds-surface-2) 45%,transparent)}
|
|
141
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody tr:hover{background:color-mix(in srgb,var(--ds-accent) 5%,transparent)}
|
|
142
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody tr:last-child td{border-bottom:0}
|
|
143
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):has(thead th:nth-child(2):last-child) th:first-child,
|
|
144
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):has(thead th:nth-child(2):last-child) td:first-child{width:30%}
|
|
145
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):not([${STATUS_TABLE_ATTR}]):has(thead th:nth-child(3):last-child) th:first-child,
|
|
146
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):not([${STATUS_TABLE_ATTR}]):has(thead th:nth-child(3):last-child) td:first-child{width:24%}
|
|
147
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):not([${STATUS_TABLE_ATTR}]):has(thead th:nth-child(3):last-child) th:nth-child(2),
|
|
148
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]):not([${STATUS_TABLE_ATTR}]):has(thead th:nth-child(3):last-child) td:nth-child(2){width:22%}
|
|
149
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] th:first-child,
|
|
150
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] td:first-child{
|
|
151
|
+
width:68px;text-align:center;padding:7px 8px!important;font-size:11px;font-weight:700;
|
|
152
|
+
white-space:nowrap;vertical-align:middle;border-radius:7px;
|
|
153
|
+
}
|
|
154
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] tbody tr[${ROW_ATTR}="success"] td:first-child{background:color-mix(in srgb,var(--ds-success) 12%,transparent);color:var(--ds-success)}
|
|
155
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] tbody tr[${ROW_ATTR}="warn"] td:first-child{background:color-mix(in srgb,var(--ds-warn) 12%,transparent);color:var(--ds-warn)}
|
|
156
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] tbody tr[${ROW_ATTR}="error"] td:first-child{background:color-mix(in srgb,var(--ds-error) 12%,transparent);color:var(--ds-error)}
|
|
157
|
+
[class*="_markdown_"] p[${LEAD_ATTR}="table"]{
|
|
158
|
+
border-left:2px solid var(--ds-accent);padding-left:10px;margin:10px 0 8px;
|
|
159
|
+
font-size:14px;color:var(--ds-text);
|
|
160
|
+
}
|
|
161
|
+
[class*="_markdown_"] p[${LEAD_ATTR}="table"] strong{color:var(--ds-accent-text)}
|
|
162
|
+
[class*="_markdown_"] h2+table,[class*="_markdown_"] h2+p,[class*="_markdown_"] h3+table,[class*="_markdown_"] h3+p{margin-top:8px}
|
|
163
|
+
[class*="_markdown_"] :not(pre)>code{
|
|
164
|
+
background:var(--ds-surface-2);border:1px solid var(--ds-border);border-radius:6px;
|
|
165
|
+
padding:.12em .38em;font-size:.9em;color:var(--ds-accent-text);overflow-wrap:anywhere;
|
|
166
|
+
}
|
|
167
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"]{
|
|
168
|
+
margin:16px 0;border:1px solid var(--ds-border);border-radius:12px;overflow:hidden;
|
|
169
|
+
background:var(--ds-code-bg);box-shadow:0 1px 2px rgba(0,0,0,.04);
|
|
170
|
+
}
|
|
171
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] > [class*="_bannerWrap"]{
|
|
172
|
+
margin:0;padding:0;border:0;background:none;
|
|
173
|
+
}
|
|
174
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] [data-code-block-banner]{
|
|
175
|
+
display:flex;align-items:center;justify-content:space-between;gap:8px;margin:0;border-radius:0;
|
|
176
|
+
padding:6px 12px;font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
|
|
177
|
+
color:var(--ds-muted);border-bottom:1px solid var(--ds-border);
|
|
178
|
+
background:linear-gradient(90deg,color-mix(in srgb,var(--ds-code-accent,var(--ds-accent)) 14%,transparent),transparent 72%);
|
|
179
|
+
}
|
|
180
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] [data-code-block-banner] > [class*="_heading"]{
|
|
181
|
+
flex:1;min-width:0;justify-content:flex-start;text-align:left;
|
|
182
|
+
}
|
|
183
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] [data-code-block-banner] > [class*="_actions"]{
|
|
184
|
+
margin-left:auto;flex:none;
|
|
185
|
+
}
|
|
186
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] > [data-code-block-content]{padding:0}
|
|
187
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] [data-code-block-banner]::before{
|
|
188
|
+
content:"";width:8px;height:8px;border-radius:50%;flex:none;
|
|
189
|
+
background:var(--ds-code-accent,var(--ds-accent));
|
|
190
|
+
box-shadow:0 0 0 3px color-mix(in srgb,var(--ds-code-accent,var(--ds-accent)) 18%,transparent);
|
|
191
|
+
}
|
|
192
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"] pre{margin:0;padding:14px 16px;font-size:13px;line-height:1.65;overflow:auto;color:var(--ds-code-text)}
|
|
193
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="js"]{--ds-code-accent:#eab308}
|
|
194
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="ts"],
|
|
195
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="tsx"]{--ds-code-accent:#3b82f6}
|
|
196
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="py"],
|
|
197
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="python"]{--ds-code-accent:#22c55e}
|
|
198
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="bash"],
|
|
199
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="sh"],
|
|
200
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="powershell"]{--ds-code-accent:#14b8a6}
|
|
201
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="json"]{--ds-code-accent:#a855f7}
|
|
202
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="html"],
|
|
203
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="css"]{--ds-code-accent:#f97316}
|
|
204
|
+
[class*="_markdown_"] .md-code-block[${CODE_ATTR}="1"][data-dsh-structured-lang="sql"]{--ds-code-accent:#06b6d4}
|
|
205
|
+
[class*="_markdown_"] blockquote{
|
|
206
|
+
margin:14px 0;padding:10px 14px;border-left:3px solid var(--ds-accent);
|
|
207
|
+
background:color-mix(in srgb,var(--ds-accent) 6%,transparent);border-radius:0 10px 10px 0;
|
|
208
|
+
}
|
|
209
|
+
[class*="_markdown_"] blockquote[${TONE_ATTR}="warn"]{--ds-accent:var(--ds-warn);--ds-accent-text:var(--ds-warn)}
|
|
210
|
+
[class*="_markdown_"] blockquote[${TONE_ATTR}="success"]{--ds-accent:var(--ds-success);--ds-accent-text:var(--ds-success)}
|
|
211
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]{
|
|
212
|
+
border:1px solid color-mix(in srgb,var(--ds-accent) 16%,var(--ds-border));
|
|
213
|
+
border-left:3px solid var(--ds-accent);
|
|
214
|
+
border-radius:12px;padding:14px 16px 15px;
|
|
215
|
+
background:linear-gradient(135deg,color-mix(in srgb,var(--ds-accent) 6%,var(--ds-surface)),var(--ds-surface) 60%);
|
|
216
|
+
box-shadow:0 1px 2px rgba(0,0,0,.04),0 12px 32px -24px color-mix(in srgb,var(--ds-accent) 32%,transparent);
|
|
217
|
+
}
|
|
218
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child>strong:first-child{
|
|
219
|
+
display:flex;align-items:center;gap:9px;position:relative;
|
|
220
|
+
font-size:13px;line-height:1.1;letter-spacing:.06em;text-transform:uppercase;
|
|
221
|
+
color:var(--ds-accent-text);margin-bottom:8px;
|
|
222
|
+
}
|
|
223
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child>strong:first-child::before{
|
|
224
|
+
content:"";display:inline-flex;flex:none;
|
|
225
|
+
width:26px;height:26px;border-radius:7px;
|
|
226
|
+
background:color-mix(in srgb,var(--ds-accent) 12%,transparent);
|
|
227
|
+
}
|
|
228
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child>strong:first-child::after{
|
|
229
|
+
content:"";position:absolute;left:5.5px;top:5.5px;width:15px;height:15px;
|
|
230
|
+
background-color:var(--ds-accent);
|
|
231
|
+
-webkit-mask:var(--ds-card-icon) center/contain no-repeat;
|
|
232
|
+
mask:var(--ds-card-icon) center/contain no-repeat;
|
|
233
|
+
}
|
|
234
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:nth-child(2)>strong:first-child{
|
|
235
|
+
display:block;font-size:16px;font-weight:700;line-height:1.45;
|
|
236
|
+
letter-spacing:-.01em;color:var(--ds-text);margin-bottom:4px;
|
|
237
|
+
}
|
|
238
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p{font-size:15.5px;line-height:1.7;font-weight:450;color:var(--ds-text)}
|
|
239
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p strong{font-weight:700;color:var(--ds-text)}
|
|
240
|
+
[class*="_markdown_"] blockquote[${TONE_ATTR}]>p:first-child>strong:first-child{color:var(--ds-accent-text)}
|
|
241
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="conclusion"]{
|
|
242
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3l9 9-9 9-9-9 9-9z' fill='none' stroke='black' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
243
|
+
}
|
|
244
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="decision"]{
|
|
245
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 7h6l4 10h6M4 17h6l4-10h6' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
246
|
+
}
|
|
247
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="metric"]{
|
|
248
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 20V10M12 20V4M19 20v-7' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
|
|
249
|
+
}
|
|
250
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="risk"]{
|
|
251
|
+
--ds-accent:var(--ds-warn);--ds-accent-text:var(--ds-warn);
|
|
252
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 4l9 16H3L12 4z' fill='none' stroke='black' stroke-width='1.8' stroke-linejoin='round'/%3E%3Cpath d='M12 10v4M12 17v.5' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
|
|
253
|
+
}
|
|
254
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]{
|
|
255
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
256
|
+
}
|
|
257
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="accept"]{
|
|
258
|
+
--ds-accent:var(--ds-success);--ds-accent-text:var(--ds-success);
|
|
259
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 12.5l5 5L20 6.5' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
260
|
+
}
|
|
261
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="key"]{
|
|
262
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3l2.6 6.2 6.7.5-5.1 4.4 1.6 6.5L12 17.3 6.2 20.6l1.6-6.5L2.7 9.7l6.7-.5L12 3z' fill='none' stroke='black' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
263
|
+
}
|
|
264
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]{
|
|
265
|
+
--ds-card-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3l9 9-9 9-9-9 9-9z' fill='none' stroke='black' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
266
|
+
}
|
|
267
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]>p:first-child>strong:first-child{
|
|
268
|
+
font-size:16px;line-height:1.45;letter-spacing:-.01em;text-transform:none;
|
|
269
|
+
color:var(--ds-text);margin-bottom:4px;
|
|
270
|
+
}
|
|
271
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child{margin-top:0}
|
|
272
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:last-child{margin-bottom:0}
|
|
273
|
+
[class*="_markdown_"] p[${STATUS_ATTR}],[class*="_markdown_"] li[${STATUS_ATTR}]{
|
|
274
|
+
border-left:3px solid var(--ds-accent);background:color-mix(in srgb,var(--ds-accent) 7%,transparent);
|
|
275
|
+
border-radius:0 6px 6px 0;padding:4px 10px;margin:.4em 0;
|
|
276
|
+
}
|
|
277
|
+
[class*="_markdown_"] p[${STATUS_ATTR}="success"],[class*="_markdown_"] li[${STATUS_ATTR}="success"]{--ds-accent:var(--ds-success)}
|
|
278
|
+
[class*="_markdown_"] p[${STATUS_ATTR}="warn"],[class*="_markdown_"] li[${STATUS_ATTR}="warn"]{--ds-accent:var(--ds-warn)}
|
|
279
|
+
[class*="_markdown_"] p[${STATUS_ATTR}="error"],[class*="_markdown_"] li[${STATUS_ATTR}="error"]{--ds-accent:var(--ds-error)}
|
|
280
|
+
@media (max-width:720px){
|
|
281
|
+
[class*="_markdown_"]{font-size:14.5px}
|
|
282
|
+
[class*="_markdown_"] h1{font-size:22px}
|
|
283
|
+
[class*="_markdown_"] h2{font-size:18px}
|
|
284
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]){font-size:13px}
|
|
285
|
+
[class*="_markdown_"] table:not([${SKIP_ATTR}]) thead th,[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody td{padding:7px 9px}
|
|
286
|
+
}
|
|
287
|
+
@media (prefers-reduced-motion:reduce){
|
|
288
|
+
[class*="_markdown_"] *{transition:none!important;animation:none!important}
|
|
289
|
+
}
|
|
290
|
+
`
|
|
291
|
+
|
|
292
|
+
function iconFor(text) {
|
|
293
|
+
for (const [pattern, icon] of ICONS) if (pattern.test(text)) return icon
|
|
294
|
+
return null
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function firstParagraph(block) {
|
|
298
|
+
return [...(block.children ?? [])].find((element) => element.tagName === 'P') ?? null
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function labelOf(block) {
|
|
302
|
+
const first = firstParagraph(block)
|
|
303
|
+
const strong = first?.firstElementChild
|
|
304
|
+
if (!strong || strong.tagName !== 'STRONG') return null
|
|
305
|
+
return (strong.textContent ?? '').replace(/[::]\s*$/u, '').trim()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function cardTypeFor(block) {
|
|
309
|
+
const label = labelOf(block)
|
|
310
|
+
return label === null ? null : (CARD_TYPES.get(label) ?? null)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function isLabelLike(text) {
|
|
314
|
+
return [...CARD_TYPES.keys()].some((label) => text.startsWith(label) && text !== label)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function inGenui(element) {
|
|
318
|
+
try {
|
|
319
|
+
return Boolean(element.closest?.('[data-genui], [class*="genui-root"]'))
|
|
320
|
+
} catch {
|
|
321
|
+
return false
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function inDiff(element) {
|
|
326
|
+
try {
|
|
327
|
+
return Boolean(element.closest?.('[data-diff], .md-diff, [class*="_diff_"], [class*="diff-view"], [class*="diff-block"], [data-testid*="diff"]'))
|
|
328
|
+
} catch {
|
|
329
|
+
return false
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function bannerLanguage(code) {
|
|
334
|
+
const banner = code.querySelector?.('[data-code-block-banner]')
|
|
335
|
+
const heading = banner?.querySelector?.('[class*="_heading"]')
|
|
336
|
+
const raw = ((heading?.textContent ?? banner?.textContent) ?? '').trim().split(/\s+/)[0] ?? ''
|
|
337
|
+
return raw.toLowerCase().replace(/[^a-z0-9+#]/g, '')
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function isDiffCode(code) {
|
|
341
|
+
const lang = bannerLanguage(code)
|
|
342
|
+
return lang === 'diff' || lang === 'patch'
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function statusFor(text) {
|
|
346
|
+
if (/^✅/.test(text)) return 'success'
|
|
347
|
+
if (/^⚠/.test(text)) return 'warn'
|
|
348
|
+
if (/^❌/.test(text)) return 'error'
|
|
349
|
+
return null
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function isStatementCard(block) {
|
|
353
|
+
if (inDiff(block)) return false
|
|
354
|
+
const markdown = block.closest?.('[class*="_markdown_"]')
|
|
355
|
+
if (!markdown) return false
|
|
356
|
+
const first = [...markdown.querySelectorAll('blockquote')].find((element) => !inGenui(element) && !inDiff(element))
|
|
357
|
+
if (first !== block) return false
|
|
358
|
+
const paragraphs = [...block.children].filter((element) => element.tagName === 'P')
|
|
359
|
+
const firstParagraph = paragraphs[0]
|
|
360
|
+
const strong = firstParagraph?.firstElementChild
|
|
361
|
+
if (!strong || strong.tagName !== 'STRONG') return false
|
|
362
|
+
let previous = strong.previousSibling
|
|
363
|
+
while (previous) {
|
|
364
|
+
if (previous.nodeType === 1) return false
|
|
365
|
+
if (previous.nodeType === 3 && (previous.textContent ?? '').trim() !== '') return false
|
|
366
|
+
previous = previous.previousSibling
|
|
367
|
+
}
|
|
368
|
+
const title = (strong.textContent ?? '').trim()
|
|
369
|
+
if (title.length === 0 || isLabelLike(title)) return false
|
|
370
|
+
let rest = ''
|
|
371
|
+
for (let node = strong.nextSibling; node; node = node.nextSibling) rest += node.textContent ?? ''
|
|
372
|
+
const secondBody = paragraphs.slice(1).some((element) => (element.textContent ?? '').trim().length > 0)
|
|
373
|
+
return rest.trim().length > 0 || secondBody
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function decorate(root) {
|
|
377
|
+
for (const heading of root.querySelectorAll('[class*="_markdown_"] h2, [class*="_markdown_"] h3')) {
|
|
378
|
+
if (inGenui(heading) || inDiff(heading)) continue
|
|
379
|
+
const icon = iconFor((heading.textContent ?? '').trim())
|
|
380
|
+
if (icon === null) heading.removeAttribute(ICON_ATTR)
|
|
381
|
+
else heading.setAttribute(ICON_ATTR, icon)
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
for (const block of root.querySelectorAll('blockquote')) {
|
|
385
|
+
if (inGenui(block) || inDiff(block)) continue
|
|
386
|
+
let type = cardTypeFor(block)
|
|
387
|
+
if (type === null && isStatementCard(block)) type = 'statement'
|
|
388
|
+
if (type === null) {
|
|
389
|
+
block.removeAttribute(CARD_ATTR)
|
|
390
|
+
block.removeAttribute(CARD_TYPE_ATTR)
|
|
391
|
+
block.removeAttribute(LEAD_ATTR)
|
|
392
|
+
block.removeAttribute(TONE_ATTR)
|
|
393
|
+
continue
|
|
394
|
+
}
|
|
395
|
+
block.setAttribute(CARD_ATTR, '1')
|
|
396
|
+
block.setAttribute(CARD_TYPE_ATTR, type)
|
|
397
|
+
block.removeAttribute(LEAD_ATTR)
|
|
398
|
+
block.setAttribute(TONE_ATTR, type === 'risk' ? 'warn' : type === 'accept' ? 'success' : 'info')
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
for (const element of root.querySelectorAll('[class*="_markdown_"] p, [class*="_markdown_"] li')) {
|
|
402
|
+
if (inGenui(element) || inDiff(element) || element.closest('blockquote, table')) {
|
|
403
|
+
element.removeAttribute(STATUS_ATTR)
|
|
404
|
+
continue
|
|
405
|
+
}
|
|
406
|
+
const status = statusFor((element.textContent ?? '').trimStart())
|
|
407
|
+
if (status === null) element.removeAttribute(STATUS_ATTR)
|
|
408
|
+
else element.setAttribute(STATUS_ATTR, status)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
for (const row of root.querySelectorAll('[class*="_markdown_"] table tr')) {
|
|
412
|
+
if (inGenui(row) || inDiff(row) || row.closest('thead') || row.closest(`[${SKIP_ATTR}="table"]`)) {
|
|
413
|
+
row.removeAttribute(ROW_ATTR)
|
|
414
|
+
continue
|
|
415
|
+
}
|
|
416
|
+
const status = statusFor((row.textContent ?? '').trimStart())
|
|
417
|
+
if (status === null) row.removeAttribute(ROW_ATTR)
|
|
418
|
+
else row.setAttribute(ROW_ATTR, status)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
for (const table of root.querySelectorAll('[class*="_markdown_"] table')) {
|
|
422
|
+
if (inGenui(table)) {
|
|
423
|
+
table.removeAttribute(SKIP_ATTR)
|
|
424
|
+
table.removeAttribute(STATUS_TABLE_ATTR)
|
|
425
|
+
continue
|
|
426
|
+
}
|
|
427
|
+
if (inDiff(table)) {
|
|
428
|
+
table.setAttribute(SKIP_ATTR, 'table')
|
|
429
|
+
table.removeAttribute(STATUS_TABLE_ATTR)
|
|
430
|
+
continue
|
|
431
|
+
}
|
|
432
|
+
table.removeAttribute(SKIP_ATTR)
|
|
433
|
+
const rows = [...table.querySelectorAll('tbody tr')]
|
|
434
|
+
const statusTable =
|
|
435
|
+
rows.length > 0 &&
|
|
436
|
+
rows.every((row) => statusFor((row.cells?.[0]?.textContent ?? '').trimStart()) !== null)
|
|
437
|
+
if (statusTable) table.setAttribute(STATUS_TABLE_ATTR, '1')
|
|
438
|
+
else table.removeAttribute(STATUS_TABLE_ATTR)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
for (const paragraph of root.querySelectorAll('[class*="_markdown_"] p')) {
|
|
442
|
+
if (inGenui(paragraph) || inDiff(paragraph) || paragraph.closest('blockquote, table')) {
|
|
443
|
+
paragraph.removeAttribute(LEAD_ATTR)
|
|
444
|
+
continue
|
|
445
|
+
}
|
|
446
|
+
if (/^表格结论/.test((paragraph.textContent ?? '').trimStart())) paragraph.setAttribute(LEAD_ATTR, 'table')
|
|
447
|
+
else paragraph.removeAttribute(LEAD_ATTR)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
for (const code of root.querySelectorAll('[class*="_markdown_"] .md-code-block')) {
|
|
451
|
+
if (inGenui(code)) {
|
|
452
|
+
code.removeAttribute(LANG_ATTR)
|
|
453
|
+
code.removeAttribute(CODE_ATTR)
|
|
454
|
+
code.removeAttribute(SKIP_ATTR)
|
|
455
|
+
continue
|
|
456
|
+
}
|
|
457
|
+
if (inDiff(code) || isDiffCode(code)) {
|
|
458
|
+
code.removeAttribute(LANG_ATTR)
|
|
459
|
+
code.removeAttribute(CODE_ATTR)
|
|
460
|
+
code.setAttribute(SKIP_ATTR, 'code')
|
|
461
|
+
continue
|
|
462
|
+
}
|
|
463
|
+
code.removeAttribute(SKIP_ATTR)
|
|
464
|
+
code.setAttribute(CODE_ATTR, '1')
|
|
465
|
+
const lang = bannerLanguage(code)
|
|
466
|
+
if (lang.length === 0) code.removeAttribute(LANG_ATTR)
|
|
467
|
+
else code.setAttribute(LANG_ATTR, lang)
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* 在插件板块的插件详情页注册配置区(plugins.bundle.config,键 = 包名)。
|
|
473
|
+
* 宿主不会从 Config schema 自动生成表单——配置页必须由插件自己的浏览器半侧注册;
|
|
474
|
+
* 宿主 describe 未服务本命名空间(whileServed 不触发)或 primitives 缺失时不出配置页,
|
|
475
|
+
* 且任何失败都不影响视觉层与消息渲染。
|
|
476
|
+
*/
|
|
477
|
+
function setupConfigPage(child, form) {
|
|
478
|
+
if (typeof require !== 'function') return
|
|
479
|
+
if (typeof child?.configForms?.whileServed !== 'function') return
|
|
480
|
+
if (typeof child?.slots?.inject !== 'function' || typeof child?.slots?.register !== 'function') return
|
|
481
|
+
if (typeof form?.set !== 'function') return
|
|
482
|
+
let jsx
|
|
483
|
+
let jsxs
|
|
484
|
+
let ui
|
|
485
|
+
try {
|
|
486
|
+
const runtime = require('react/jsx-runtime')
|
|
487
|
+
jsx = runtime.jsx
|
|
488
|
+
jsxs = runtime.jsxs
|
|
489
|
+
ui = require('@deepseek-ai/dsh-client-ui-primitives')
|
|
490
|
+
if (typeof ui?.Switch !== 'function' || typeof ui?.SegmentedControl !== 'function') return
|
|
491
|
+
} catch {
|
|
492
|
+
// primitives 不可用(非 desktop 表层):不出配置页。
|
|
493
|
+
return
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const labelStyle = { fontSize: '14px', lineHeight: '20px', color: 'var(--dsw-alias-label-primary, inherit)' }
|
|
497
|
+
const hintStyle = { fontSize: '12.5px', lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary, inherit)', marginTop: '2px' }
|
|
498
|
+
const rowStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '16px', padding: '10px 0', borderBottom: '1px solid var(--dsw-alias-border-l2, rgba(127,127,127,.18))' }
|
|
499
|
+
const noteStyle = { fontSize: '12.5px', lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary, inherit)', margin: '6px 0 2px' }
|
|
500
|
+
|
|
501
|
+
const fieldValue = (value, spec) => {
|
|
502
|
+
const raw = value?.[spec.field]
|
|
503
|
+
if (raw && typeof raw.get === 'function') return raw.get()
|
|
504
|
+
return raw === undefined || raw === null ? spec.fallback : raw
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const renderRow = (state, setField, spec) => {
|
|
508
|
+
const writable = state.writable !== false
|
|
509
|
+
const control = spec.kind === 'switch'
|
|
510
|
+
? jsx(ui.Switch, {
|
|
511
|
+
checked: fieldValue(state.value, spec) === true,
|
|
512
|
+
disabled: !writable,
|
|
513
|
+
label: spec.label,
|
|
514
|
+
onChange: (next) => setField(spec.field, next === true),
|
|
515
|
+
})
|
|
516
|
+
: jsx(ui.SegmentedControl, {
|
|
517
|
+
id: 'dsh-structured-' + spec.field,
|
|
518
|
+
value: String(fieldValue(state.value, spec)),
|
|
519
|
+
options: spec.options.map(([value, text]) => ({ value, label: text })),
|
|
520
|
+
disabled: !writable,
|
|
521
|
+
label: spec.label,
|
|
522
|
+
onChange: (next) => setField(spec.field, next),
|
|
523
|
+
})
|
|
524
|
+
return jsxs('div', {
|
|
525
|
+
style: rowStyle,
|
|
526
|
+
children: [
|
|
527
|
+
jsxs('div', { style: { minWidth: 0 }, children: [
|
|
528
|
+
jsx('div', { style: labelStyle, children: spec.label }),
|
|
529
|
+
jsx('div', { style: hintStyle, children: spec.hint }),
|
|
530
|
+
] }),
|
|
531
|
+
control,
|
|
532
|
+
],
|
|
533
|
+
})
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const StructuredConfigCard = (props) => {
|
|
537
|
+
if (props.view !== undefined && props.view !== 'page') return null
|
|
538
|
+
const read = props.useStructuredConfig ?? props.structuredConfig
|
|
539
|
+
const state = typeof read === 'function' ? read((snapshot) => snapshot) : null
|
|
540
|
+
if (!state || state.status !== 'ready' || typeof state.value !== 'object' || state.value === null) {
|
|
541
|
+
return jsx('p', { style: noteStyle, children: '插件未加载或配置暂不可用。' })
|
|
542
|
+
}
|
|
543
|
+
const setField = typeof props.setField === 'function' ? props.setField : () => {}
|
|
544
|
+
return jsxs('div', {
|
|
545
|
+
'data-dsh-structured-config': '1',
|
|
546
|
+
children: [
|
|
547
|
+
state.writable === false
|
|
548
|
+
? jsx('p', { style: noteStyle, children: '当前配置被更高层覆盖(home patch / CLI overlay),此处只读。' })
|
|
549
|
+
: null,
|
|
550
|
+
jsx('div', { children: CONFIG_FIELDS.map((spec) => renderRow(state, setField, spec)) }),
|
|
551
|
+
jsx('p', { style: noteStyle, children: '会话级开关请用 /structured on | off(按会话生效,不写入这里)。' }),
|
|
552
|
+
],
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
child.effect?.(
|
|
557
|
+
() =>
|
|
558
|
+
child.configForms.whileServed([CONFIG_NS], () =>
|
|
559
|
+
child.slots.inject(BUNDLE_CONFIG_SLOT, () =>
|
|
560
|
+
child.slots.register({
|
|
561
|
+
name: BUNDLE_CONFIG_SLOT,
|
|
562
|
+
key: 'dsh-structured',
|
|
563
|
+
inject: () => ({
|
|
564
|
+
hooks: { structuredConfig: form },
|
|
565
|
+
setField: (field, value) => {
|
|
566
|
+
try {
|
|
567
|
+
form.set(field, value)
|
|
568
|
+
} catch {
|
|
569
|
+
// 写入失败不打断页面;快照未变化即用户可见的反馈。
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
}),
|
|
573
|
+
}, StructuredConfigCard),
|
|
574
|
+
),
|
|
575
|
+
),
|
|
576
|
+
'dsh-structured: bundle config page',
|
|
577
|
+
)
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
let active = false
|
|
581
|
+
let disposeLayer = null
|
|
582
|
+
let currentTheme = 'deepseek'
|
|
583
|
+
|
|
584
|
+
const applyTheme = (theme) => {
|
|
585
|
+
const safe = THEMES.includes(theme) ? theme : 'deepseek'
|
|
586
|
+
currentTheme = safe
|
|
587
|
+
if (typeof document === 'undefined') return
|
|
588
|
+
document.body?.setAttribute(THEME_ATTR, safe)
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const enable = () => {
|
|
592
|
+
if (active) return
|
|
593
|
+
if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return
|
|
594
|
+
if (document.body === null) return
|
|
595
|
+
active = true
|
|
596
|
+
|
|
597
|
+
document.getElementById(LEGACY_STYLE_ID)?.remove()
|
|
598
|
+
document.getElementById(STYLE_ID)?.remove()
|
|
599
|
+
const style = document.createElement('style')
|
|
600
|
+
style.id = STYLE_ID
|
|
601
|
+
style.textContent = CSS
|
|
602
|
+
document.head.appendChild(style)
|
|
603
|
+
document.documentElement.setAttribute(ROOT_ATTR, 'active')
|
|
604
|
+
document.body.setAttribute(THEME_ATTR, currentTheme)
|
|
605
|
+
try {
|
|
606
|
+
console.info('[dsh-structured] visual layer active')
|
|
607
|
+
} catch {
|
|
608
|
+
// console 不可用时忽略。
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
let disposed = false
|
|
612
|
+
let scheduled = false
|
|
613
|
+
let pending = null
|
|
614
|
+
const run = () => {
|
|
615
|
+
if (disposed) return
|
|
616
|
+
scheduled = false
|
|
617
|
+
pending = null
|
|
618
|
+
decorate(document)
|
|
619
|
+
}
|
|
620
|
+
const schedule = () => {
|
|
621
|
+
if (disposed || scheduled) return
|
|
622
|
+
scheduled = true
|
|
623
|
+
if (typeof requestAnimationFrame === 'function') pending = requestAnimationFrame(run)
|
|
624
|
+
else pending = setTimeout(run, 16)
|
|
625
|
+
}
|
|
626
|
+
const observer = new MutationObserver(schedule)
|
|
627
|
+
observer.observe(document.body, { childList: true, subtree: true, characterData: true })
|
|
628
|
+
run()
|
|
629
|
+
|
|
630
|
+
disposeLayer = () => {
|
|
631
|
+
if (disposed) return
|
|
632
|
+
disposed = true
|
|
633
|
+
active = false
|
|
634
|
+
disposeLayer = null
|
|
635
|
+
observer.disconnect()
|
|
636
|
+
if (pending !== null) {
|
|
637
|
+
if (typeof cancelAnimationFrame === 'function') cancelAnimationFrame(pending)
|
|
638
|
+
else clearTimeout(pending)
|
|
639
|
+
}
|
|
640
|
+
style.remove()
|
|
641
|
+
document.documentElement.removeAttribute(ROOT_ATTR)
|
|
642
|
+
document.body?.removeAttribute(THEME_ATTR)
|
|
643
|
+
for (const attr of [CARD_ATTR, CARD_TYPE_ATTR, ICON_ATTR, TONE_ATTR, LANG_ATTR, CODE_ATTR, SKIP_ATTR, STATUS_ATTR, STATUS_TABLE_ATTR, LEAD_ATTR, ROW_ATTR]) {
|
|
644
|
+
for (const element of document.querySelectorAll('[' + attr + ']')) element.removeAttribute(attr)
|
|
645
|
+
}
|
|
646
|
+
try {
|
|
647
|
+
console.info('[dsh-structured] visual layer disposed')
|
|
648
|
+
} catch {
|
|
649
|
+
// console 不可用时忽略。
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const disable = () => {
|
|
655
|
+
const layer = disposeLayer
|
|
656
|
+
disposeLayer = null
|
|
657
|
+
if (typeof layer === 'function') layer()
|
|
658
|
+
if (typeof document === 'undefined') return
|
|
659
|
+
document.getElementById(STYLE_ID)?.remove()
|
|
660
|
+
document.documentElement.removeAttribute(ROOT_ATTR)
|
|
661
|
+
document.body?.removeAttribute(THEME_ATTR)
|
|
662
|
+
for (const attr of [CARD_ATTR, CARD_TYPE_ATTR, ICON_ATTR, TONE_ATTR, LANG_ATTR, CODE_ATTR, SKIP_ATTR, STATUS_ATTR, STATUS_TABLE_ATTR, LEAD_ATTR, ROW_ATTR]) {
|
|
663
|
+
for (const element of document.querySelectorAll('[' + attr + ']')) element.removeAttribute(attr)
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const applyVisual = (on) => {
|
|
668
|
+
if (on) enable()
|
|
669
|
+
else disable()
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
return {
|
|
673
|
+
inject: [],
|
|
674
|
+
__test: { inDiff, isDiffCode, decorate, setupConfigPage },
|
|
675
|
+
apply(ctx) {
|
|
676
|
+
// 默认主题/视觉先启用;随后由 profile Config 的 theme/visual 覆盖。
|
|
677
|
+
enable()
|
|
678
|
+
try {
|
|
679
|
+
ctx?.inject?.(['configForms'], (child) => {
|
|
680
|
+
try {
|
|
681
|
+
const form = child.configForms?.get('dsh-structured')
|
|
682
|
+
if (!form || typeof form.getSnapshot !== 'function') return
|
|
683
|
+
const readValue = (value) => (value && typeof value.get === 'function' ? value.get() : value)
|
|
684
|
+
const read = () => {
|
|
685
|
+
try {
|
|
686
|
+
const value = form.getSnapshot()?.value ?? {}
|
|
687
|
+
applyTheme(readValue(value.theme))
|
|
688
|
+
applyVisual(readValue(value.visual) !== false)
|
|
689
|
+
} catch {
|
|
690
|
+
// 读取失败时保持当前状态,不打断回复。
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
read()
|
|
694
|
+
if (typeof form.subscribe === 'function') {
|
|
695
|
+
child.effect?.(() => form.subscribe(read), 'dsh-structured: theme/visual preferences')
|
|
696
|
+
}
|
|
697
|
+
} catch {
|
|
698
|
+
// configForms 不可用时保持默认开启。
|
|
699
|
+
}
|
|
700
|
+
})
|
|
701
|
+
} catch {
|
|
702
|
+
// 无 ctx.inject 的宿主保持默认开启。
|
|
703
|
+
}
|
|
704
|
+
try {
|
|
705
|
+
// 插件详情页配置区与视觉层分开注入:配置页失败不影响主题/视觉联动。
|
|
706
|
+
ctx?.inject?.(['configForms', 'slots'], (child) => {
|
|
707
|
+
try {
|
|
708
|
+
const form = child.configForms?.get('dsh-structured')
|
|
709
|
+
if (form) setupConfigPage(child, form)
|
|
710
|
+
} catch {
|
|
711
|
+
// 配置页不可用不影响视觉层与注入。
|
|
712
|
+
}
|
|
713
|
+
})
|
|
714
|
+
} catch {
|
|
715
|
+
// 无 ctx.inject 的宿主没有配置页,视觉层照常。
|
|
716
|
+
}
|
|
717
|
+
try {
|
|
718
|
+
ctx?.effect?.(() => disable, 'dsh-structured: visual layer')
|
|
719
|
+
} catch {
|
|
720
|
+
// 没有 effect 释放器时,视觉层保持到页面卸载。
|
|
721
|
+
}
|
|
722
|
+
return disable
|
|
723
|
+
},
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
})
|