dsh-structured 0.9.4 → 0.9.9
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 +130 -108
- package/README.md +274 -273
- package/assets/screenshots/01-title-card.png +0 -0
- package/assets/screenshots/06-status-table.png +0 -0
- package/assets/screenshots/07-code-block.png +0 -0
- package/assets/screenshots/08-narrow.png +0 -0
- package/assets/screenshots/09-theme-light.png +0 -0
- package/assets/screenshots/10-theme-dark.png +0 -0
- package/docs/0.9-FINAL-RELEASE.md +22 -0
- package/docs/1.0-BASELINE.md +38 -0
- package/docs/1.0-GATE.md +39 -0
- package/docs/1.0-PERSONA-SPEC.md +59 -0
- package/lib/client.js +95 -68
- package/lib/index.js +518 -517
- package/package.json +102 -99
- package/scripts/theme-contrast.mjs +2 -2
- package/scripts/theme-hue-distance.mjs +55 -0
- package/src/client.js +93 -66
- package/src/index.js +516 -515
- package/test/client-cards.test.mjs +145 -140
- package/test/client-incremental.test.mjs +105 -0
- package/test/client-visual.test.mjs +299 -290
- package/test/fixtures/first-glance.html +80 -0
- package/test/fixtures/persona-gate/no-persona.md +8 -0
- package/test/fixtures/persona-gate/persona-append.md +9 -0
- package/test/fixtures/persona-gate/style-override.md +8 -0
- package/test/fixtures/style-probe.mjs +74 -0
- package/test/structured.test.mjs +590 -582
- package/test/style-browser.test.mjs +71 -0
- package/test/theme.test.mjs +8 -9
package/package.json
CHANGED
|
@@ -1,99 +1,102 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-structured",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "Structured output for DSH: no-label title card first, then tables/lists/steps; per-session switch and style.md override. 让 DSH 的每条实质回复默认结构化。",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"author": "MYCAIGC",
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/feigo313/dsh-structured.git"
|
|
12
|
-
},
|
|
13
|
-
"homepage": "https://github.com/feigo313/dsh-structured#readme",
|
|
14
|
-
"bugs": {
|
|
15
|
-
"url": "https://github.com/feigo313/dsh-structured/issues"
|
|
16
|
-
},
|
|
17
|
-
"publishConfig": {
|
|
18
|
-
"access": "public",
|
|
19
|
-
"registry": "https://registry.npmjs.org"
|
|
20
|
-
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"deepseek",
|
|
23
|
-
"harness",
|
|
24
|
-
"dsh",
|
|
25
|
-
"dsh-plugin",
|
|
26
|
-
"output-style",
|
|
27
|
-
"structured-output"
|
|
28
|
-
],
|
|
29
|
-
"exports": {
|
|
30
|
-
".": "./lib/index.js",
|
|
31
|
-
"./client": "./lib/client.js",
|
|
32
|
-
"./locale/*.json": "./locale/*.json",
|
|
33
|
-
"./icon": "./icon.svg",
|
|
34
|
-
"./package.json": "./package.json"
|
|
35
|
-
},
|
|
36
|
-
"dsh": {
|
|
37
|
-
"bundle": {
|
|
38
|
-
"patch": "./cordis.patch.yml"
|
|
39
|
-
},
|
|
40
|
-
"client": {
|
|
41
|
-
"platform": "web",
|
|
42
|
-
"inject": [
|
|
43
|
-
"@deepseek-ai/dsh-client-ui-settings"
|
|
44
|
-
],
|
|
45
|
-
"immediately": true
|
|
46
|
-
},
|
|
47
|
-
"compatibility": {
|
|
48
|
-
"dshReleases": {
|
|
49
|
-
"0.1.7-rc.2": "compatible",
|
|
50
|
-
"0.2.0-rc.2": "compatible",
|
|
51
|
-
"0.2.1-rc.1": "compatible",
|
|
52
|
-
"0.2.1-rc.2": "compatible",
|
|
53
|
-
"0.2.1-rc.3": "compatible",
|
|
54
|
-
"0.3.0-rc.1": "compatible"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
"files": [
|
|
59
|
-
"lib",
|
|
60
|
-
"src",
|
|
61
|
-
"scripts",
|
|
62
|
-
"docs",
|
|
63
|
-
"!docs/FULL-TEST-PROMPT.md",
|
|
64
|
-
"!docs/FULL-TEST-REPORT.md",
|
|
65
|
-
"!docs/RE-AUDIT-REPORT.md",
|
|
66
|
-
"!docs/PUBLISH-READY.md",
|
|
67
|
-
"!docs/RELEASE-NOTES-0.7.4.md",
|
|
68
|
-
"!docs/MAINTENANCE*.md",
|
|
69
|
-
"!docs/ACCEPTANCE-0.9.1.md",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
},
|
|
95
|
-
"
|
|
96
|
-
"@deepseek-ai/schemastery": "^3.18.0"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-structured",
|
|
3
|
+
"version": "0.9.9",
|
|
4
|
+
"description": "Structured output for DSH: no-label title card first, then tables/lists/steps; per-session switch and style.md override. 让 DSH 的每条实质回复默认结构化。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "MYCAIGC",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/feigo313/dsh-structured.git"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/feigo313/dsh-structured#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/feigo313/dsh-structured/issues"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"deepseek",
|
|
23
|
+
"harness",
|
|
24
|
+
"dsh",
|
|
25
|
+
"dsh-plugin",
|
|
26
|
+
"output-style",
|
|
27
|
+
"structured-output"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./lib/index.js",
|
|
31
|
+
"./client": "./lib/client.js",
|
|
32
|
+
"./locale/*.json": "./locale/*.json",
|
|
33
|
+
"./icon": "./icon.svg",
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"dsh": {
|
|
37
|
+
"bundle": {
|
|
38
|
+
"patch": "./cordis.patch.yml"
|
|
39
|
+
},
|
|
40
|
+
"client": {
|
|
41
|
+
"platform": "web",
|
|
42
|
+
"inject": [
|
|
43
|
+
"@deepseek-ai/dsh-client-ui-settings"
|
|
44
|
+
],
|
|
45
|
+
"immediately": true
|
|
46
|
+
},
|
|
47
|
+
"compatibility": {
|
|
48
|
+
"dshReleases": {
|
|
49
|
+
"0.1.7-rc.2": "compatible",
|
|
50
|
+
"0.2.0-rc.2": "compatible",
|
|
51
|
+
"0.2.1-rc.1": "compatible",
|
|
52
|
+
"0.2.1-rc.2": "compatible",
|
|
53
|
+
"0.2.1-rc.3": "compatible",
|
|
54
|
+
"0.3.0-rc.1": "compatible"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"files": [
|
|
59
|
+
"lib",
|
|
60
|
+
"src",
|
|
61
|
+
"scripts",
|
|
62
|
+
"docs",
|
|
63
|
+
"!docs/FULL-TEST-PROMPT.md",
|
|
64
|
+
"!docs/FULL-TEST-REPORT.md",
|
|
65
|
+
"!docs/RE-AUDIT-REPORT.md",
|
|
66
|
+
"!docs/PUBLISH-READY.md",
|
|
67
|
+
"!docs/RELEASE-NOTES-0.7.4.md",
|
|
68
|
+
"!docs/MAINTENANCE*.md",
|
|
69
|
+
"!docs/ACCEPTANCE-0.9.1.md",
|
|
70
|
+
"!docs/ACCEPTANCE-0.9.7.md",
|
|
71
|
+
"!docs/ACCEPTANCE-0.9.8.md",
|
|
72
|
+
"!docs/ACCEPTANCE-0.9.9.md",
|
|
73
|
+
"assets/screenshots",
|
|
74
|
+
"screenshots.json",
|
|
75
|
+
"test",
|
|
76
|
+
"cordis.patch.yml",
|
|
77
|
+
"locale/*.json",
|
|
78
|
+
"icon.svg",
|
|
79
|
+
"README.md",
|
|
80
|
+
"ACCEPTANCE.md",
|
|
81
|
+
"CHANGELOG.md",
|
|
82
|
+
"LICENSE"
|
|
83
|
+
],
|
|
84
|
+
"scripts": {
|
|
85
|
+
"build": "node scripts/build.mjs",
|
|
86
|
+
"pretest": "node scripts/build.mjs",
|
|
87
|
+
"test": "node --test test/*.test.mjs",
|
|
88
|
+
"theme-contrast": "node scripts/theme-contrast.mjs",
|
|
89
|
+
"prepack": "node scripts/build.mjs"
|
|
90
|
+
},
|
|
91
|
+
"engines": {
|
|
92
|
+
"node": ">=22",
|
|
93
|
+
"dsh": ">=0.1.7-rc.2 <0.4.0-0"
|
|
94
|
+
},
|
|
95
|
+
"peerDependencies": {
|
|
96
|
+
"@deepseek-ai/schemastery": "^3.18.0"
|
|
97
|
+
},
|
|
98
|
+
"devDependencies": {
|
|
99
|
+
"@deepseek-ai/schemastery": "^3.18.0",
|
|
100
|
+
"linkedom": "0.18.14"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -30,12 +30,12 @@ export const THEME_TOKENS = {
|
|
|
30
30
|
anthropic: {
|
|
31
31
|
light: {
|
|
32
32
|
surface: '#FAF9F5', surface2: '#F5F1E8', text: '#141413', muted: '#6B6359',
|
|
33
|
-
border: '#E5E0D5', accent: '#CC785C', accentText: '#A14A2E', success: '#266B4D', warn: '#
|
|
33
|
+
border: '#E5E0D5', accent: '#CC785C', accentText: '#A14A2E', success: '#266B4D', warn: '#806000', error: '#8C1D18',
|
|
34
34
|
codeBg: '#F5F1E8', codeText: '#141413',
|
|
35
35
|
},
|
|
36
36
|
dark: {
|
|
37
37
|
surface: '#1F1E1D', surface2: '#2A2825', text: '#F5F1E8', muted: '#A8A29A',
|
|
38
|
-
border: '#3A3733', accent: '#E8A087', accentText: '#E8A087', success: '#6FBF9A', warn: '#
|
|
38
|
+
border: '#3A3733', accent: '#E8A087', accentText: '#E8A087', success: '#6FBF9A', warn: '#EAB308', error: '#F28B82',
|
|
39
39
|
codeBg: '#171614', codeText: '#F5F1E8',
|
|
40
40
|
},
|
|
41
41
|
},
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** 0.9.8:品牌 accent 与语义 status 的 hue 分离检查(阈值 25°)。 */
|
|
3
|
+
import { pathToFileURL } from 'node:url'
|
|
4
|
+
import { THEME_TOKENS } from './theme-contrast.mjs'
|
|
5
|
+
|
|
6
|
+
export const HUE_THRESHOLD = 25
|
|
7
|
+
|
|
8
|
+
function rgb(hex) {
|
|
9
|
+
return [1, 3, 5].map((offset) => parseInt(hex.slice(offset, offset + 2), 16))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function hue(hex) {
|
|
13
|
+
const [r, g, b] = rgb(hex).map((channel) => channel / 255)
|
|
14
|
+
const max = Math.max(r, g, b)
|
|
15
|
+
const min = Math.min(r, g, b)
|
|
16
|
+
const delta = max - min
|
|
17
|
+
if (delta === 0) return 0
|
|
18
|
+
let value
|
|
19
|
+
if (max === r) value = ((g - b) / delta) % 6
|
|
20
|
+
else if (max === g) value = (b - r) / delta + 2
|
|
21
|
+
else value = (r - g) / delta + 4
|
|
22
|
+
value *= 60
|
|
23
|
+
return value < 0 ? value + 360 : value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function hueDistance(a, b) {
|
|
27
|
+
const diff = Math.abs(hue(a) - hue(b)) % 360
|
|
28
|
+
return diff > 180 ? 360 - diff : diff
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function checkHueSeparation() {
|
|
32
|
+
const results = []
|
|
33
|
+
const failures = []
|
|
34
|
+
for (const [theme, modes] of Object.entries(THEME_TOKENS)) {
|
|
35
|
+
for (const [mode, token] of Object.entries(modes)) {
|
|
36
|
+
for (const status of ['success', 'warn']) {
|
|
37
|
+
const distance = hueDistance(token.accent, token[status])
|
|
38
|
+
const row = { theme, mode, status, distance, threshold: HUE_THRESHOLD }
|
|
39
|
+
results.push(row)
|
|
40
|
+
if (distance < HUE_THRESHOLD) failures.push(row)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { results, failures }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
48
|
+
const { results, failures } = checkHueSeparation()
|
|
49
|
+
for (const row of results) console.log(`${row.theme}/${row.mode} accent-${row.status}: ${row.distance.toFixed(1)}°`)
|
|
50
|
+
if (failures.length > 0) {
|
|
51
|
+
console.error(JSON.stringify(failures, null, 2))
|
|
52
|
+
process.exit(1)
|
|
53
|
+
}
|
|
54
|
+
console.log(`PASS ${results.length} hue checks`)
|
|
55
|
+
}
|
package/src/client.js
CHANGED
|
@@ -129,12 +129,12 @@ body[data-ds-dark-theme][data-dsh-structured-theme="codex"] [class*="_markdown_"
|
|
|
129
129
|
}
|
|
130
130
|
body[data-dsh-structured-theme="anthropic"] [class*="_markdown_"]{
|
|
131
131
|
--ds-surface:#FAF9F5;--ds-surface-2:#F5F1E8;--ds-text:#141413;--ds-muted:#6B6359;
|
|
132
|
-
--ds-border:#E5E0D5;--ds-accent:#CC785C;--ds-accent-text:#A14A2E;--ds-success:#266B4D;--ds-warn:#
|
|
132
|
+
--ds-border:#E5E0D5;--ds-accent:#CC785C;--ds-accent-text:#A14A2E;--ds-success:#266B4D;--ds-warn:#806000;--ds-error:#8C1D18;
|
|
133
133
|
--ds-code-bg:#F5F1E8;--ds-code-text:#141413;
|
|
134
134
|
}
|
|
135
135
|
body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdown_"]{
|
|
136
136
|
--ds-surface:#1F1E1D;--ds-surface-2:#2A2825;--ds-text:#F5F1E8;--ds-muted:#A8A29A;
|
|
137
|
-
--ds-border:#3A3733;--ds-accent:#E8A087;--ds-accent-text:#E8A087;--ds-success:#6FBF9A;--ds-warn:#
|
|
137
|
+
--ds-border:#3A3733;--ds-accent:#E8A087;--ds-accent-text:#E8A087;--ds-success:#6FBF9A;--ds-warn:#EAB308;--ds-error:#F28B82;
|
|
138
138
|
--ds-code-bg:#171614;--ds-code-text:#F5F1E8;
|
|
139
139
|
}
|
|
140
140
|
[class*="_markdown_"] p{margin:.72em 0}
|
|
@@ -145,13 +145,15 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
145
145
|
[class*="_markdown_"] h1{font-size:26px;font-weight:700;margin:32px 0 12px;padding-bottom:8px;border-bottom:1px solid var(--ds-border)}
|
|
146
146
|
[class*="_markdown_"] h2{font-size:21px;font-weight:700;margin:28px 0 10px;padding-left:12px;border-left:3px solid var(--ds-accent)}
|
|
147
147
|
[class*="_markdown_"] h3{font-size:17px;font-weight:650;margin:22px 0 8px}
|
|
148
|
+
[class*="_markdown_"] h2[${ICON_ATTR}]{padding-left:42px;text-indent:-30px}
|
|
149
|
+
[class*="_markdown_"] h3[${ICON_ATTR}]{padding-left:30px;text-indent:-30px}
|
|
148
150
|
[class*="_markdown_"] h4{font-size:15px;font-weight:650;margin:16px 0 6px}
|
|
149
151
|
[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}
|
|
150
152
|
[class*="_markdown_"] h2[${ICON_ATTR}]::before,
|
|
151
153
|
[class*="_markdown_"] h3[${ICON_ATTR}]::before{
|
|
152
154
|
content:attr(${ICON_ATTR});
|
|
153
155
|
display:inline-flex;align-items:center;justify-content:center;
|
|
154
|
-
width:22px;height:22px;margin-right:8px;border-radius:6px;
|
|
156
|
+
width:22px;height:22px;margin-right:8px;text-indent:0;border-radius:6px;
|
|
155
157
|
background:color-mix(in srgb,var(--ds-accent) 12%,transparent);
|
|
156
158
|
color:var(--ds-accent-text);font-size:12px;font-weight:700;vertical-align:2px;
|
|
157
159
|
}
|
|
@@ -163,18 +165,19 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
163
165
|
[class*="_markdown_"] li::marker{color:var(--ds-accent-text)}
|
|
164
166
|
[class*="_markdown_"] hr{height:1px;border:0;margin:28px 0;background:linear-gradient(90deg,transparent,var(--ds-border),transparent)}
|
|
165
167
|
[class*="_markdown_"] table:not([${SKIP_ATTR}]){
|
|
166
|
-
width:100%;margin:
|
|
167
|
-
border:1px solid var(--ds-border);border-radius:12px;overflow:hidden;font-size:
|
|
168
|
+
width:100%;margin:16px 0;border-collapse:separate;border-spacing:0;
|
|
169
|
+
border:1px solid var(--ds-border);border-radius:12px;overflow:hidden;font-size:12.5px;
|
|
168
170
|
box-shadow:0 1px 2px rgba(0,0,0,.03);
|
|
169
171
|
}
|
|
170
172
|
[class*="_markdown_"] table:not([${SKIP_ATTR}]) thead th{
|
|
171
|
-
background:var(--ds-surface-2);
|
|
172
|
-
font-size:
|
|
173
|
-
|
|
173
|
+
height:38px;background:var(--ds-surface-2);
|
|
174
|
+
font-size:13px!important;letter-spacing:0!important;
|
|
175
|
+
color:color-mix(in srgb,var(--ds-text) 78%,var(--ds-muted));
|
|
176
|
+
font-weight:700!important;text-align:left;padding:0 18px!important;vertical-align:middle;
|
|
174
177
|
border-bottom:1px solid var(--ds-border);
|
|
175
178
|
}
|
|
176
179
|
[class*="_markdown_"] table:not([${SKIP_ATTR}]) tbody td{
|
|
177
|
-
padding:
|
|
180
|
+
padding:12px 18px!important;line-height:1.55;vertical-align:middle;border-left:0;border-right:0;
|
|
178
181
|
border-bottom:1px solid color-mix(in srgb,var(--ds-border) 55%,transparent);
|
|
179
182
|
word-break:break-word;
|
|
180
183
|
}
|
|
@@ -189,17 +192,17 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
189
192
|
[class*="_markdown_"] table:not([${SKIP_ATTR}]):not([${STATUS_TABLE_ATTR}]):has(thead th:nth-child(3):last-child) td:nth-child(2){width:22%}
|
|
190
193
|
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] th:first-child,
|
|
191
194
|
[class*="_markdown_"] table:not([${SKIP_ATTR}])[${STATUS_TABLE_ATTR}] td:first-child{
|
|
192
|
-
width:68px;text-align:center;padding:
|
|
193
|
-
white-space:nowrap;vertical-align:middle;border-radius:
|
|
195
|
+
width:68px;text-align:center;padding:4px 8px!important;font-size:10px;font-weight:700;
|
|
196
|
+
white-space:nowrap;vertical-align:middle;border-radius:6px;
|
|
194
197
|
}
|
|
195
198
|
[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)}
|
|
196
199
|
[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)}
|
|
197
200
|
[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)}
|
|
198
201
|
[class*="_markdown_"] p[${LEAD_ATTR}="table"]{
|
|
199
|
-
border
|
|
200
|
-
font-size:
|
|
202
|
+
border:0;padding:0;margin:12px 0 8px;
|
|
203
|
+
font-size:13px;color:var(--ds-text);
|
|
201
204
|
}
|
|
202
|
-
[class*="_markdown_"] p[${LEAD_ATTR}="table"] strong{color:var(--ds-
|
|
205
|
+
[class*="_markdown_"] p[${LEAD_ATTR}="table"] strong{font-size:14px;font-weight:700;color:var(--ds-text)}
|
|
203
206
|
[class*="_markdown_"] h2+table,[class*="_markdown_"] h2+p,[class*="_markdown_"] h3+table,[class*="_markdown_"] h3+p{margin-top:8px}
|
|
204
207
|
[class*="_markdown_"] :not(pre)>code{
|
|
205
208
|
background:var(--ds-surface-2);border:1px solid var(--ds-border);border-radius:6px;
|
|
@@ -250,65 +253,49 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
250
253
|
[class*="_markdown_"] blockquote[${TONE_ATTR}="warn"]{--ds-accent:var(--ds-warn);--ds-accent-text:var(--ds-warn)}
|
|
251
254
|
[class*="_markdown_"] blockquote[${TONE_ATTR}="success"]{--ds-accent:var(--ds-success);--ds-accent-text:var(--ds-success)}
|
|
252
255
|
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]{
|
|
253
|
-
border:1px solid color-mix(in srgb,var(--ds-accent)
|
|
256
|
+
border:1px solid color-mix(in srgb,var(--ds-accent) 18%,var(--ds-border));
|
|
254
257
|
border-left:3px solid var(--ds-accent);
|
|
255
|
-
border-radius:12px;padding:
|
|
256
|
-
background:linear-gradient(135deg,color-mix(in srgb,var(--ds-accent)
|
|
257
|
-
box-shadow:0 1px 2px rgba(0,0,0,.04)
|
|
258
|
+
border-radius:12px;padding:18px;
|
|
259
|
+
background:linear-gradient(135deg,color-mix(in srgb,var(--ds-accent) 5%,var(--ds-surface)),var(--ds-surface) 62%);
|
|
260
|
+
box-shadow:0 1px 2px rgba(0,0,0,.04);
|
|
258
261
|
}
|
|
259
262
|
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child>strong:first-child{
|
|
260
|
-
display:
|
|
261
|
-
font-size:
|
|
262
|
-
color:var(--ds-accent-text);margin-bottom:
|
|
263
|
+
display:block;position:static;
|
|
264
|
+
font-size:14px;line-height:1.3;letter-spacing:0;text-transform:none;
|
|
265
|
+
color:var(--ds-accent-text);margin-bottom:6px;
|
|
263
266
|
}
|
|
264
|
-
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:
|
|
265
|
-
content:"";display:inline-flex;flex:none;
|
|
266
|
-
width:26px;height:26px;border-radius:7px;
|
|
267
|
-
background:color-mix(in srgb,var(--ds-accent) 12%,transparent);
|
|
268
|
-
}
|
|
269
|
-
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child>strong:first-child::after{
|
|
270
|
-
content:"";position:absolute;left:5.5px;top:5.5px;width:15px;height:15px;
|
|
271
|
-
background-color:var(--ds-accent);
|
|
272
|
-
-webkit-mask:var(--ds-card-icon) center/contain no-repeat;
|
|
273
|
-
mask:var(--ds-card-icon) center/contain no-repeat;
|
|
274
|
-
}
|
|
275
|
-
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:nth-child(2)>strong:first-child{
|
|
276
|
-
display:block;font-size:16px;font-weight:700;line-height:1.45;
|
|
277
|
-
letter-spacing:-.01em;color:var(--ds-text);margin-bottom:4px;
|
|
278
|
-
}
|
|
279
|
-
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p{font-size:15.5px;line-height:1.7;font-weight:450;color:var(--ds-text)}
|
|
267
|
+
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p{font-size:13px;line-height:1.6;font-weight:400;color:var(--ds-text)}
|
|
280
268
|
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p strong{font-weight:700;color:var(--ds-text)}
|
|
281
269
|
[class*="_markdown_"] blockquote[${TONE_ATTR}]>p:first-child>strong:first-child{color:var(--ds-accent-text)}
|
|
282
|
-
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
--ds-
|
|
287
|
-
}
|
|
288
|
-
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="metric"]{
|
|
289
|
-
--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");
|
|
270
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="risk"]{--ds-accent:var(--ds-warn);--ds-accent-text:var(--ds-warn)}
|
|
271
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="accept"]{--ds-accent:var(--ds-success);--ds-accent-text:var(--ds-success)}
|
|
272
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]>p:first-child>strong:first-child{
|
|
273
|
+
font-size:24px;line-height:1.25;letter-spacing:-.02em;text-transform:none;
|
|
274
|
+
color:var(--ds-text);margin-bottom:0;
|
|
290
275
|
}
|
|
291
|
-
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="
|
|
292
|
-
|
|
293
|
-
--ds-
|
|
276
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]>p:first-child>strong:first-child::after{
|
|
277
|
+
content:"";display:block;height:1px;margin:12px 0;
|
|
278
|
+
background:var(--ds-border);
|
|
294
279
|
}
|
|
280
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]>p{font-size:13.5px;line-height:1.6;font-weight:400}
|
|
281
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="statement"]>p:first-child{margin-bottom:0}
|
|
295
282
|
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
283
|
+
background:none;border:0;border-top:1px solid var(--ds-border);border-radius:0;
|
|
284
|
+
box-shadow:none;padding:14px 0 0 14px;margin:18px 0;position:relative;
|
|
285
|
+
}
|
|
286
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]::before{
|
|
287
|
+
content:"";position:absolute;left:0;top:17px;width:0;height:0;
|
|
288
|
+
border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:9px solid #C2410C;
|
|
289
|
+
}
|
|
290
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]>p:first-child>strong:first-child{
|
|
291
|
+
font-size:16px;line-height:1.3;color:var(--ds-text);margin-bottom:8px;
|
|
292
|
+
}
|
|
293
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]>p,
|
|
294
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"] li{font-size:13px;line-height:1.6}
|
|
295
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"] ol,
|
|
296
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"] ul{padding-left:0;margin:.4em 0 0;list-style-position:inside}
|
|
297
|
+
[class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"] li{padding-left:0}
|
|
298
|
+
body[data-ds-dark-theme] [class*="_markdown_"] blockquote[${CARD_TYPE_ATTR}="next"]::before{border-left-color:#FB923C}
|
|
312
299
|
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:first-child{margin-top:0}
|
|
313
300
|
[class*="_markdown_"] blockquote[${CARD_ATTR}="1"]>p:last-child{margin-bottom:0}
|
|
314
301
|
[class*="_markdown_"] p[${STATUS_ATTR}],[class*="_markdown_"] li[${STATUS_ATTR}]{
|
|
@@ -662,11 +649,36 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
662
649
|
let disposed = false
|
|
663
650
|
let scheduled = false
|
|
664
651
|
let pending = null
|
|
652
|
+
let pendingRoots = null
|
|
653
|
+
|
|
654
|
+
// 增量扫描:mutation 只重扫它所在的 markdown 容器(或新增子树),
|
|
655
|
+
// 避免长会话里每帧对整页做一次全量 querySelectorAll(O(N²))。
|
|
656
|
+
const markRoot = (node) => {
|
|
657
|
+
if (!node) return
|
|
658
|
+
const element = node.nodeType === 1 ? node : node.parentElement
|
|
659
|
+
if (!element) return
|
|
660
|
+
const markdown = element.closest?.('[class*="_markdown_"]')
|
|
661
|
+
const root = markdown ?? element
|
|
662
|
+
if (pendingRoots === null) pendingRoots = new Set()
|
|
663
|
+
pendingRoots.add(root)
|
|
664
|
+
}
|
|
665
665
|
const run = () => {
|
|
666
666
|
if (disposed) return
|
|
667
667
|
scheduled = false
|
|
668
668
|
pending = null
|
|
669
|
-
|
|
669
|
+
const roots = pendingRoots
|
|
670
|
+
pendingRoots = null
|
|
671
|
+
if (roots === null) {
|
|
672
|
+
decorate(document)
|
|
673
|
+
return
|
|
674
|
+
}
|
|
675
|
+
const list = [...roots]
|
|
676
|
+
for (const root of list) {
|
|
677
|
+
if (root?.isConnected === false) continue
|
|
678
|
+
// 被另一个待扫根包含时跳过,避免重复工作。
|
|
679
|
+
if (list.some((other) => other !== root && other.contains?.(root))) continue
|
|
680
|
+
decorate(root)
|
|
681
|
+
}
|
|
670
682
|
}
|
|
671
683
|
const schedule = () => {
|
|
672
684
|
if (disposed || scheduled) return
|
|
@@ -674,7 +686,22 @@ body[data-ds-dark-theme][data-dsh-structured-theme="anthropic"] [class*="_markdo
|
|
|
674
686
|
if (typeof requestAnimationFrame === 'function') pending = requestAnimationFrame(run)
|
|
675
687
|
else pending = setTimeout(run, 16)
|
|
676
688
|
}
|
|
677
|
-
const observer = new MutationObserver(
|
|
689
|
+
const observer = new MutationObserver((records) => {
|
|
690
|
+
try {
|
|
691
|
+
for (const record of records) {
|
|
692
|
+
if (record.type === 'childList') {
|
|
693
|
+
for (const node of record.addedNodes) markRoot(node)
|
|
694
|
+
if (record.addedNodes.length === 0) markRoot(record.target)
|
|
695
|
+
} else {
|
|
696
|
+
markRoot(record.target)
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
} catch {
|
|
700
|
+
// 记录结构异常时退回整页扫描,保证装饰不丢。
|
|
701
|
+
pendingRoots = null
|
|
702
|
+
}
|
|
703
|
+
schedule()
|
|
704
|
+
})
|
|
678
705
|
observer.observe(document.body, { childList: true, subtree: true, characterData: true })
|
|
679
706
|
run()
|
|
680
707
|
|