@dsh-suite/plugin-deus 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +18 -0
  2. package/lib/client.js +94 -76
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,6 +30,24 @@
30
30
  7. **统计导出与分享(v0.3)** — 面板一键导出 CSV、**复制 Markdown 摘要**(Wilson CI 表格 + 诚实声明 + 包链接,可直接发帖),并内嵌近期神版率迷你趋势图(最近 40 条日志分桶折线)。
31
31
  8. **提示词 A/B 实验台(v0.4)** — 设计文档的「纯噪音退路」转正:对话页 dock 的 🧪 **实验台**里输入**任意**提示词变体 A/B,各跑 N 次**真实会话注入**(每次试验自动点「新建会话」隔离上下文),宿主按提示词文本队列配对判定,产出**指纹分布对比表**——每类的 Wilson 95% CI、Δ(A−B)、两比例 z 检验与显著性标记。Settings 面板可回看/切换历史实验。deus 由此从「神模工具」升级为「提示词实验台」,神模只是第一个被测假设。
32
32
 
33
+ ## Theme & Skin Compatibility / 主题与皮肤兼容
34
+
35
+ This plugin follows the DSH Web styling contract
36
+ ([`docs/web-styling.md`](https://github.com/deepseek-ai/deepseek-harness/blob/main/docs/web-styling.md)):
37
+ every color routes through `--dsw-alias-*` design tokens (dark literals are kept
38
+ only as fallbacks for hosts predating the alias table), with no per-theme CSS
39
+ selectors.
40
+
41
+ It also implements the [dsh-web Skin Center compatibility contract](https://github.com/zhu1090093659/dsh-web/tree/main/packages/skins/skin-center/contracts)
42
+ at **L1 (token coverage)** and **L2 (semantic attributes)**: the settings panel
43
+ root carries `data-dsh-plugin="plugin-deus"` + `data-dsh-surface="settings-modal"`,
44
+ the composer dock root carries `data-dsh-surface="chat-input"`, and skin-relevant
45
+ nodes are tagged with `data-dsh-part` (`banner` / `card` / `button-ghost` /
46
+ `input` / `textarea` / `select` / `chip` / `panel`), so third-party skins get
47
+ full restyle coverage without relying on unstable class names.
48
+
49
+ 本插件遵循 DSH Web 样式契约:全部颜色经 `--dsw-alias-*` 设计令牌引用(暗色字面量仅作旧宿主兜底),无按主题分支的 CSS 选择器;并实现 dsh-web 皮肤中心兼容契约 **L1(令牌覆盖)+ L2(语义属性)**——设置面板根节点输出 `data-dsh-plugin="plugin-deus"` + `data-dsh-surface="settings-modal"`,输入区 dock 根节点输出 `data-dsh-surface="chat-input"`,换肤相关节点标注 `data-dsh-part`,第三方皮肤无需依赖不稳定类名即可完整换肤。
50
+
33
51
  ## 安装 / Install
34
52
 
35
53
  ```bash
package/lib/client.js CHANGED
@@ -102,31 +102,45 @@ window.__ModuleLoader__.load({
102
102
  benchDefB: 'You are a world-class science writer; rehearse the answer three times in your head before speaking. Explain "entropy" to a bright middle-schooler in three sentences.',
103
103
  }
104
104
 
105
+ // DSH Web 样式契约(docs/web-styling.md):全部颜色经 --dsw-alias-* 令牌引用;
106
+ // 暗色字面量仅作宿主早于令牌表时的兜底。无按主题分支的选择器,皮肤可自由覆写。
105
107
  const S = {
106
- banner: { background: '#2d2406', border: '1px solid #9e6a03', borderRadius: '8px', padding: '10px 12px', fontSize: '12px', color: '#e3b341', lineHeight: '1.6', marginBottom: '14px' },
107
- status: { fontSize: '11px', color: '#8b949e', marginBottom: '10px' },
108
- card: { background: '#161b22', border: '1px solid #30363d', borderRadius: '10px', padding: '14px', marginBottom: '12px' },
108
+ banner: { background: 'var(--dsw-alias-state-warn-tertiary, #2d2406)', border: '1px solid var(--dsw-alias-state-warn-primary, #9e6a03)', borderRadius: '8px', padding: '10px 12px', fontSize: '12px', color: 'var(--dsw-alias-state-warn-label, #e3b341)', lineHeight: '1.6', marginBottom: '14px' },
109
+ status: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #8b949e)', marginBottom: '10px' },
110
+ card: { background: 'var(--dsw-alias-bg-layer-1, #161b22)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '10px', padding: '14px', marginBottom: '12px' },
109
111
  row: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap', marginTop: '10px' },
110
- btn: { background: 'transparent', border: '1px solid #30363d', borderRadius: '6px', color: '#8b949e', padding: '6px 12px', fontSize: '13px', cursor: 'pointer' },
111
- btnActive: { background: '#21262d', border: '1px solid #8b949e', borderRadius: '6px', color: '#e6edf3', padding: '6px 12px', fontSize: '13px', cursor: 'pointer' },
112
- chip: { background: '#0d1117', border: '1px solid #30363d', borderRadius: '20px', color: '#8b949e', padding: '2px 10px', fontSize: '11px' },
113
- name: { fontSize: '14px', fontWeight: '700', color: '#e6edf3' },
114
- desc: { fontSize: '12px', color: '#8b949e', marginTop: '4px', lineHeight: '1.5' },
115
- h2: { fontSize: '13px', fontWeight: '600', color: '#e6edf3', margin: '18px 0 8px' },
116
- table: { width: '100%', borderCollapse: 'collapse', fontSize: '12px', color: '#c9d1d9' },
117
- th: { textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #30363d', color: '#8b949e', fontWeight: '600' },
118
- td: { padding: '6px 8px', borderBottom: '1px solid #21262d' },
119
- input: { background: '#0d1117', border: '1px solid #30363d', borderRadius: '6px', color: '#e6edf3', padding: '6px 8px', fontSize: '12px', width: '100%', boxSizing: 'border-box' },
120
- mono: { fontFamily: 'monospace', fontSize: '12px', color: '#c9d1d9' },
121
- benchWrap: { width: '100%', background: '#0d1117', border: '1px solid #30363d', borderRadius: '10px', padding: '10px 12px', marginBottom: '6px' },
122
- benchTa: { width: '100%', minHeight: '52px', background: '#161b22', border: '1px solid #30363d', borderRadius: '8px', color: '#c9d1d9', fontSize: '12px', padding: '6px 8px', boxSizing: 'border-box', resize: 'vertical' },
123
- benchLabel: { fontSize: '11px', color: '#8b949e', margin: '6px 0 3px' },
112
+ btn: { background: 'transparent', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '6px', color: 'var(--dsw-alias-label-secondary, #8b949e)', padding: '6px 12px', fontSize: '13px', cursor: 'pointer' },
113
+ btnActive: { background: 'var(--dsw-alias-bg-layer-3, #21262d)', border: '1px solid var(--dsw-alias-label-secondary, #8b949e)', borderRadius: '6px', color: 'var(--dsw-alias-label-primary, #e6edf3)', padding: '6px 12px', fontSize: '13px', cursor: 'pointer' },
114
+ chip: { background: 'var(--dsw-alias-bg-layer-2, #0d1117)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '20px', color: 'var(--dsw-alias-label-secondary, #8b949e)', padding: '2px 10px', fontSize: '11px' },
115
+ name: { fontSize: '14px', fontWeight: '700', color: 'var(--dsw-alias-label-primary, #e6edf3)' },
116
+ desc: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #8b949e)', marginTop: '4px', lineHeight: '1.5' },
117
+ h2: { fontSize: '13px', fontWeight: '600', color: 'var(--dsw-alias-label-primary, #e6edf3)', margin: '18px 0 8px' },
118
+ table: { width: '100%', borderCollapse: 'collapse', fontSize: '12px', color: 'var(--dsw-alias-label-primary, #c9d1d9)' },
119
+ th: { textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid var(--dsw-alias-border-l1, #30363d)', color: 'var(--dsw-alias-label-secondary, #8b949e)', fontWeight: '600' },
120
+ td: { padding: '6px 8px', borderBottom: '1px solid var(--dsw-alias-border-l1, #21262d)' },
121
+ input: { background: 'var(--dsw-alias-bg-layer-2, #0d1117)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '6px', color: 'var(--dsw-alias-label-primary, #e6edf3)', padding: '6px 8px', fontSize: '12px', width: '100%', boxSizing: 'border-box' },
122
+ mono: { fontFamily: 'monospace', fontSize: '12px', color: 'var(--dsw-alias-label-primary, #c9d1d9)' },
123
+ benchWrap: { width: '100%', background: 'var(--dsw-alias-bg-layer-2, #0d1117)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '10px', padding: '10px 12px', marginBottom: '6px' },
124
+ benchTa: { width: '100%', minHeight: '52px', background: 'var(--dsw-alias-bg-layer-1, #161b22)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '8px', color: 'var(--dsw-alias-label-primary, #c9d1d9)', fontSize: '12px', padding: '6px 8px', boxSizing: 'border-box', resize: 'vertical' },
125
+ benchLabel: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #8b949e)', margin: '6px 0 3px' },
124
126
  benchTable: { width: '100%', borderCollapse: 'collapse', fontSize: '11px', marginTop: '6px' },
125
- benchCell: { border: '1px solid #21262d', padding: '3px 6px', textAlign: 'right', whiteSpace: 'nowrap' },
127
+ benchCell: { border: '1px solid var(--dsw-alias-border-l1, #21262d)', padding: '3px 6px', textAlign: 'right', whiteSpace: 'nowrap' },
126
128
  dock: { display: 'flex', gap: '6px', alignItems: 'center', flexWrap: 'wrap', padding: '4px 0' },
127
- dockChip: { background: '#161b22', border: '1px solid #30363d', borderRadius: '16px', color: '#8b949e', padding: '3px 12px', fontSize: '12px', cursor: 'pointer' },
129
+ dockChip: { background: 'var(--dsw-alias-bg-layer-1, #161b22)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '16px', color: 'var(--dsw-alias-label-secondary, #8b949e)', padding: '3px 12px', fontSize: '12px', cursor: 'pointer' },
128
130
  }
129
131
 
132
+ // 指纹分类强调色:god=紫 / med=绿 / pure=蓝 / unknown=灰。dsw 无图表系列令牌,
133
+ // 取语义最近的别名 + 字面量兜底。状态色统一走 state-* 令牌。
134
+ const CLS_ACCENT = {
135
+ god: 'var(--dsw-alias-state-business-primary, #d2a8ff)',
136
+ med: 'var(--dsw-alias-state-success-primary, #3fb950)',
137
+ pure: 'var(--dsw-alias-label-primary-bluish, #79c0ff)',
138
+ unknown: 'var(--dsw-alias-label-tertiary, #8b949e)',
139
+ }
140
+ const STATE_OK = 'var(--dsw-alias-state-success-primary, #3fb950)'
141
+ const STATE_ERR = 'var(--dsw-alias-state-error-primary, #f85149)'
142
+ const STATE_WARN = 'var(--dsw-alias-state-warn-primary, #d29922)'
143
+
130
144
  const pct = (ci) => `${(ci.rate * 100).toFixed(0)}% [${(ci.low * 100).toFixed(0)}–${(ci.high * 100).toFixed(0)}]`
131
145
 
132
146
  // ── tier A: settings section panel ──────────────────────────────────────
@@ -136,7 +150,7 @@ window.__ModuleLoader__.load({
136
150
  return fetch(url).then((r) => r.json())
137
151
  }
138
152
 
139
- const BENCH_CLS_COLORS = { god: '#d2a8ff', med: '#3fb950', pure: '#79c0ff', unknown: '#8b949e' }
153
+ const BENCH_CLS_COLORS = CLS_ACCENT
140
154
 
141
155
  function benchCellFmt(g, n) {
142
156
  if (!g || !n) return '—'
@@ -167,13 +181,13 @@ window.__ModuleLoader__.load({
167
181
  h('th', { style: S.benchCell }, t('colP')),
168
182
  h('th', { style: S.benchCell }, t('colSig')))),
169
183
  h('tbody', null, (report.comparison || []).map((row) => h('tr', { key: row.cls },
170
- h('td', { style: { ...S.benchCell, textAlign: 'left', color: BENCH_CLS_COLORS[row.cls] || '#8b949e' } }, t('detected_' + row.cls)),
184
+ h('td', { style: { ...S.benchCell, textAlign: 'left', color: BENCH_CLS_COLORS[row.cls] || CLS_ACCENT.unknown } }, t('detected_' + row.cls)),
171
185
  h('td', { style: S.benchCell }, benchCellFmt(row.a, vA && vA.n)),
172
186
  h('td', { style: S.benchCell }, benchCellFmt(row.b, vB && vB.n)),
173
187
  h('td', { style: S.benchCell }, row.delta == null ? '—' : (row.delta >= 0 ? '+' : '') + Math.round(row.delta * 100) + 'pp'),
174
188
  h('td', { style: S.benchCell }, row.z == null ? '—' : Number(row.z).toFixed(2)),
175
189
  h('td', { style: S.benchCell }, row.p == null ? '—' : row.p < 0.001 ? '<0.001' : Number(row.p).toFixed(3)),
176
- h('td', { style: { ...S.benchCell, color: '#d29922' } }, sig(row.p)),
190
+ h('td', { style: { ...S.benchCell, color: STATE_WARN } }, sig(row.p)),
177
191
  )))),
178
192
  vA && vA.prompt ? h('div', { style: { ...S.status, marginTop: '6px' } }, 'A: ' + JSON.stringify(vA.prompt)) : null,
179
193
  vB && vB.prompt ? h('div', { style: S.status }, 'B: ' + JSON.stringify(vB.prompt)) : null,
@@ -246,49 +260,49 @@ window.__ModuleLoader__.load({
246
260
  setEditing(null)
247
261
  }
248
262
 
249
- return h('div', { style: { maxWidth: '860px' } },
250
- h('div', { style: { fontSize: '14px', fontWeight: '600', color: '#e6edf3', marginBottom: '4px' } }, '⚗ ' + t('nav')),
263
+ return h('div', { style: { maxWidth: '860px' }, 'data-dsh-plugin': 'plugin-deus', 'data-dsh-surface': 'settings-modal' },
264
+ h('div', { style: { fontSize: '14px', fontWeight: '600', color: 'var(--dsw-alias-label-primary, #e6edf3)', marginBottom: '4px' } }, '⚗ ' + t('nav')),
251
265
  h('div', { style: S.status }, t('sub')),
252
- h('div', { style: S.banner }, '⚠️ ' + t('honesty')),
253
- err ? h('div', { style: { color: '#f85149', fontSize: '12px', marginBottom: '10px' } }, err) : null,
266
+ h('div', { style: S.banner, 'data-dsh-part': 'banner' }, '⚠️ ' + t('honesty')),
267
+ err ? h('div', { style: { color: STATE_ERR, fontSize: '12px', marginBottom: '10px' } }, err) : null,
254
268
  ver ? h('div', { style: { ...S.status, fontFamily: 'monospace' } },
255
269
  `${t('dshVer')}: ${ver.dsh} · ${t('pluginVer')}: ${ver.plugin} · ${t('logPath')}: ${ver.logPath}`) : null,
256
270
 
257
271
  h('div', { style: S.h2 }, t('presets')),
258
272
  h('div', { style: S.status }, t('presetsHint')),
259
- presets.map((p) => h('div', { key: p.id, style: S.card },
273
+ presets.map((p) => h('div', { key: p.id, style: S.card, 'data-dsh-part': 'card' },
260
274
  h('div', { style: { display: 'flex', alignItems: 'baseline', gap: '10px', flexWrap: 'wrap' } },
261
275
  h('span', { style: S.name }, p.label_zh),
262
- h('span', { style: { fontSize: '11px', color: '#8b949e' } }, p.id),
263
- p.builtin ? h('span', { style: S.chip }, 'built-in') : null,
276
+ h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #8b949e)' } }, p.id),
277
+ p.builtin ? h('span', { style: S.chip, 'data-dsh-part': 'chip' }, 'built-in') : null,
264
278
  ),
265
279
  h('div', { style: { ...S.mono, marginTop: '6px' } }, p.prompt === null ? t('empty') : JSON.stringify(p.prompt)),
266
280
  h('div', { style: S.row },
267
- h('button', { style: copied === p.id ? S.btnActive : S.btn, onClick: () => copyPrompt(p) },
281
+ h('button', { style: copied === p.id ? S.btnActive : S.btn, 'data-dsh-part': 'button-ghost', onClick: () => copyPrompt(p) },
268
282
  copied === p.id ? '📋 ' + t('copied') : '📋 ' + t('copy')),
269
- h('button', { style: S.btn, onClick: () => setEditing({ id: p.id, label_zh: p.label_zh, prompt: p.prompt === null ? '' : p.prompt }) }, '✏️ ' + t('edit')),
270
- h('button', { style: S.btn, onClick: () => saveAll(presets.filter((x) => x.id !== p.id)) }, '🗑 ' + t('del')),
283
+ h('button', { style: S.btn, 'data-dsh-part': 'button-ghost', onClick: () => setEditing({ id: p.id, label_zh: p.label_zh, prompt: p.prompt === null ? '' : p.prompt }) }, '✏️ ' + t('edit')),
284
+ h('button', { style: S.btn, 'data-dsh-part': 'button-ghost', onClick: () => saveAll(presets.filter((x) => x.id !== p.id)) }, '🗑 ' + t('del')),
271
285
  ),
272
286
  )),
273
- editing ? h('div', { style: S.card },
287
+ editing ? h('div', { style: S.card, 'data-dsh-part': 'card' },
274
288
  h('div', { style: S.status }, t('editId')),
275
- h('input', { style: S.input, value: editing.id, onChange: (e) => setEditing({ ...editing, id: e.target.value }) }),
289
+ h('input', { style: S.input, 'data-dsh-part': 'input', value: editing.id, onChange: (e) => setEditing({ ...editing, id: e.target.value }) }),
276
290
  h('div', { style: { ...S.status, marginTop: '8px' } }, t('editLabel')),
277
- h('input', { style: S.input, value: editing.label_zh, onChange: (e) => setEditing({ ...editing, label_zh: e.target.value }) }),
291
+ h('input', { style: S.input, 'data-dsh-part': 'input', value: editing.label_zh, onChange: (e) => setEditing({ ...editing, label_zh: e.target.value }) }),
278
292
  h('div', { style: { ...S.status, marginTop: '8px' } }, t('editPrompt')),
279
- h('textarea', { style: { ...S.input, minHeight: '60px' }, value: editing.prompt, onChange: (e) => setEditing({ ...editing, prompt: e.target.value }) }),
293
+ h('textarea', { style: { ...S.input, minHeight: '60px' }, 'data-dsh-part': 'textarea', value: editing.prompt, onChange: (e) => setEditing({ ...editing, prompt: e.target.value }) }),
280
294
  h('div', { style: S.row },
281
- h('button', { style: S.btnActive, onClick: commitEdit }, '💾 ' + t('save')),
282
- h('button', { style: S.btn, onClick: () => setEditing(null) }, t('cancel')),
295
+ h('button', { style: S.btnActive, 'data-dsh-part': 'button-ghost', onClick: commitEdit }, '💾 ' + t('save')),
296
+ h('button', { style: S.btn, 'data-dsh-part': 'button-ghost', onClick: () => setEditing(null) }, t('cancel')),
283
297
  ),
284
298
  ) : h('div', { style: S.row },
285
- h('button', { style: S.btn, onClick: () => setEditing({ id: '', label_zh: '', prompt: '' }) }, '➕ ' + t('add')),
286
- h('button', { style: S.btn, onClick: resetPresets }, '↩ ' + t('resetPresets')),
299
+ h('button', { style: S.btn, 'data-dsh-part': 'button-ghost', onClick: () => setEditing({ id: '', label_zh: '', prompt: '' }) }, '➕ ' + t('add')),
300
+ h('button', { style: S.btn, 'data-dsh-part': 'button-ghost', onClick: resetPresets }, '↩ ' + t('resetPresets')),
287
301
  ),
288
302
 
289
303
  h('div', { style: S.h2 }, t('stats')),
290
304
  h('div', { style: S.status }, t('statsHint')),
291
- h('div', { style: { ...S.status, color: '#7d8590' } }, t('measured')),
305
+ h('div', { style: { ...S.status, color: 'var(--dsw-alias-label-tertiary, #7d8590)' } }, t('measured')),
292
306
  h(Sparkline, { entries }),
293
307
  entries.length >= 4 ? h('div', { style: { ...S.status, fontSize: '10px' } }, t('trend')) : null,
294
308
  stats && stats.modes.length > 0
@@ -299,7 +313,7 @@ window.__ModuleLoader__.load({
299
313
  h('tbody', null, stats.modes.map((m) => h('tr', { key: m.mode },
300
314
  h('td', { style: S.td }, m.mode),
301
315
  h('td', { style: S.td }, m.n),
302
- h('td', { style: { ...S.td, color: '#d2a8ff' } }, pct(m.godCI)),
316
+ h('td', { style: { ...S.td, color: CLS_ACCENT.god } }, pct(m.godCI)),
303
317
  h('td', { style: S.td }, pct(m.medCI)),
304
318
  h('td', { style: S.td }, pct(m.pureCI)),
305
319
  ))),
@@ -309,6 +323,7 @@ window.__ModuleLoader__.load({
309
323
  h('a', { href: '/deus/log.csv', download: 'deus-log.csv', style: { ...S.btn, textDecoration: 'none', display: 'inline-block' } }, '⬇ ' + t('exportCsv')),
310
324
  stats ? h('button', {
311
325
  style: copied === '__md' ? S.btnActive : S.btn,
326
+ 'data-dsh-part': 'button-ghost',
312
327
  onClick: async () => {
313
328
  try {
314
329
  await navigator.clipboard.writeText(buildMarkdownSummary(stats))
@@ -316,7 +331,7 @@ window.__ModuleLoader__.load({
316
331
  } catch {}
317
332
  },
318
333
  }, '📋 ' + (copied === '__md' ? t('mdCopied') : t('copyMd'))) : null,
319
- h('button', { style: { ...S.btn, color: '#f85149', borderColor: '#f85149' }, onClick: resetLog }, '🗑 ' + t('resetLog')),
334
+ h('button', { style: { ...S.btn, color: STATE_ERR, borderColor: STATE_ERR }, 'data-dsh-part': 'button-ghost', onClick: resetLog }, '🗑 ' + t('resetLog')),
320
335
  ),
321
336
 
322
337
  h('div', { style: S.h2 }, t('anchor')),
@@ -324,7 +339,7 @@ window.__ModuleLoader__.load({
324
339
  anchor && anchor.agentPresets && h('div', { style: S.card },
325
340
  h('div', { style: S.status }, t('anchorPresetInstalled')),
326
341
  anchor.agentPresets.map((p) => h('div', { key: p.id, style: { display: 'flex', gap: '8px', alignItems: 'center', marginTop: '6px' } },
327
- h('span', { style: { ...S.chip, color: p.installed ? '#3fb950' : '#f85149', borderColor: p.installed ? '#3fb950' : '#f85149' } }, p.installed ? '✓' : '✗'),
342
+ h('span', { style: { ...S.chip, color: p.installed ? STATE_OK : STATE_ERR, borderColor: p.installed ? STATE_OK : STATE_ERR }, 'data-dsh-part': 'chip' }, p.installed ? '✓' : '✗'),
328
343
  h('span', { style: S.name }, p.name || p.id),
329
344
  p.reason ? h('span', { style: S.status }, '(' + p.reason + ')') : null,
330
345
  )),
@@ -339,9 +354,9 @@ window.__ModuleLoader__.load({
339
354
  h('td', { style: { ...S.td, ...S.mono } }, s.sessionId.slice(0, 8)),
340
355
  h('td', { style: S.td }, s.preset),
341
356
  h('td', { style: S.td }, s.total),
342
- h('td', { style: { ...S.td, color: '#d2a8ff' } }, s.total ? Math.round(100 * s.god / s.total) + '%' : '—'),
357
+ h('td', { style: { ...S.td, color: CLS_ACCENT.god } }, s.total ? Math.round(100 * s.god / s.total) + '%' : '—'),
343
358
  h('td', { style: S.td }, s.lastFp ? t('detected_' + s.lastFp) : '—'),
344
- h('td', { style: { ...S.td, color: s.drifted ? '#f85149' : '#3fb950' } }, s.drifted ? '⚠ ' + t('drifted') : '⚓ ' + t('anchoredOn')),
359
+ h('td', { style: { ...S.td, color: s.drifted ? STATE_ERR : STATE_OK } }, s.drifted ? '⚠ ' + t('drifted') : '⚓ ' + t('anchoredOn')),
345
360
  ))),
346
361
  )
347
362
  : h('div', { style: S.status }, t('anchorNone')),
@@ -349,9 +364,9 @@ window.__ModuleLoader__.load({
349
364
  h('div', { style: S.h2 }, '🧪 ' + t('bench')),
350
365
  h('div', { style: S.status }, t('benchHint')),
351
366
  h('div', { style: S.row },
352
- h('button', { style: S.btn, 'data-deus': 'bench-refresh', onClick: () => refreshBench(benchRunId) }, '🔄 ' + t('benchRefresh')),
367
+ h('button', { style: S.btn, 'data-deus': 'bench-refresh', 'data-dsh-part': 'button-ghost', onClick: () => refreshBench(benchRunId) }, '🔄 ' + t('benchRefresh')),
353
368
  benchData && benchData.runs && benchData.runs.length > 0 ? h('select', {
354
- style: { ...S.input, width: 'auto' }, 'data-deus': 'bench-runs',
369
+ style: { ...S.input, width: 'auto' }, 'data-deus': 'bench-runs', 'data-dsh-part': 'select',
355
370
  value: benchRunId,
356
371
  onChange: (e) => { setBenchRunId(e.target.value); refreshBench(e.target.value) },
357
372
  },
@@ -368,10 +383,10 @@ window.__ModuleLoader__.load({
368
383
  entries.length === 0 ? h('div', { style: S.status }, t('noData'))
369
384
  : entries.slice(0, 10).map((e, i) => h('div', { key: i, style: { ...S.card, padding: '10px 12px' } },
370
385
  h('div', { style: { display: 'flex', gap: '8px', alignItems: 'baseline', flexWrap: 'wrap' } },
371
- h('span', { style: S.chip }, e.prompt_mode),
372
- h('span', { style: { ...S.chip, color: e.detected === 'god' ? '#d2a8ff' : e.detected === 'pure' ? '#79c0ff' : e.detected === 'med' ? '#3fb950' : '#8b949e' } },
386
+ h('span', { style: S.chip, 'data-dsh-part': 'chip' }, e.prompt_mode),
387
+ h('span', { style: { ...S.chip, color: e.detected === 'god' ? CLS_ACCENT.god : e.detected === 'pure' ? CLS_ACCENT.pure : e.detected === 'med' ? CLS_ACCENT.med : CLS_ACCENT.unknown }, 'data-dsh-part': 'chip' },
373
388
  t('detected_' + (e.detected || 'unknown'))),
374
- h('span', { style: { fontSize: '11px', color: '#8b949e' } }, e.ts),
389
+ h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-tertiary, #8b949e)' } }, e.ts),
375
390
  ),
376
391
  h('div', { style: { ...S.mono, marginTop: '6px', whiteSpace: 'pre-wrap' } }, e.first_sentence),
377
392
  )),
@@ -604,70 +619,72 @@ window.__ModuleLoader__.load({
604
619
  const UNANCHORED_PRESET_RE = /^(deus-|minimal)/
605
620
  const unanchored = !st && sessPreset && !UNANCHORED_PRESET_RE.test(sessPreset)
606
621
 
607
- const benchPanel = benchOpen ? h('div', { style: S.benchWrap, 'data-deus': 'bench-panel' },
608
- h('div', { style: { fontSize: '12px', fontWeight: 600, color: '#e6edf3' } }, '🧪 ' + t('bench')),
622
+ const benchPanel = benchOpen ? h('div', { style: S.benchWrap, 'data-deus': 'bench-panel', 'data-dsh-part': 'panel' },
623
+ h('div', { style: { fontSize: '12px', fontWeight: 600, color: 'var(--dsw-alias-label-primary, #e6edf3)' } }, '🧪 ' + t('bench')),
609
624
  h('div', { style: S.status }, t('benchHint')),
610
625
  h('div', { style: S.benchLabel }, t('benchA')),
611
626
  h('textarea', {
612
- style: S.benchTa, 'data-deus': 'bench-a', value: benchA, disabled: benchRunning,
627
+ style: S.benchTa, 'data-deus': 'bench-a', 'data-dsh-part': 'textarea', value: benchA, disabled: benchRunning,
613
628
  onChange: (e) => { setBenchA(e.target.value); try { window.localStorage.setItem('deus.benchA', e.target.value) } catch { /* ignore */ } },
614
629
  }),
615
630
  h('div', { style: S.benchLabel }, t('benchB')),
616
631
  h('textarea', {
617
- style: S.benchTa, 'data-deus': 'bench-b', value: benchB, disabled: benchRunning,
632
+ style: S.benchTa, 'data-deus': 'bench-b', 'data-dsh-part': 'textarea', value: benchB, disabled: benchRunning,
618
633
  onChange: (e) => { setBenchB(e.target.value); try { window.localStorage.setItem('deus.benchB', e.target.value) } catch { /* ignore */ } },
619
634
  }),
620
635
  h('div', { style: { ...S.row, marginTop: '8px', alignItems: 'center' } },
621
636
  h('span', { style: { ...S.benchLabel, margin: 0 } }, t('benchTimes')),
622
637
  h('input', {
623
638
  type: 'number', min: 1, max: 20, 'data-deus': 'bench-n', value: benchN, disabled: benchRunning,
624
- style: { background: '#161b22', border: '1px solid #30363d', borderRadius: '8px', color: '#c9d1d9', fontSize: '12px', padding: '4px 6px', width: '60px' },
639
+ style: { background: 'var(--dsw-alias-bg-layer-1, #161b22)', border: '1px solid var(--dsw-alias-border-l1, #30363d)', borderRadius: '8px', color: 'var(--dsw-alias-label-primary, #c9d1d9)', fontSize: '12px', padding: '4px 6px', width: '60px' },
625
640
  onChange: (e) => setBenchN(e.target.value),
626
641
  }),
627
642
  benchRunning
628
- ? h('button', { style: { ...S.btn, color: '#f85149', borderColor: '#f85149' }, 'data-deus': 'bench-abort', onClick: abortBench }, t('benchAbort'))
629
- : h('button', { style: S.btnActive, 'data-deus': 'bench-run', onClick: runBench }, t('benchRun')),
643
+ ? h('button', { style: { ...S.btn, color: STATE_ERR, borderColor: STATE_ERR }, 'data-deus': 'bench-abort', 'data-dsh-part': 'button-ghost', onClick: abortBench }, t('benchAbort'))
644
+ : h('button', { style: S.btnActive, 'data-deus': 'bench-run', 'data-dsh-part': 'button-ghost', onClick: runBench }, t('benchRun')),
630
645
  ),
631
646
  benchProg ? h('div', { style: S.status, 'data-deus': 'bench-progress' },
632
647
  t('benchRunning') + ' · ' + t('benchProgress') + ': A ' + benchProg.a + '/' + benchProg.n + ' · B ' + benchProg.b + '/' + benchProg.n + ' · ' + benchProg.label + (benchProg.waiting ? ' ' + t('benchWaiting') : '')) : null,
633
- benchNote ? h('div', { style: { ...S.status, color: '#d29922' }, 'data-deus': 'bench-note' }, benchNote) : null,
648
+ benchNote ? h('div', { style: { ...S.status, color: STATE_WARN }, 'data-deus': 'bench-note' }, benchNote) : null,
634
649
  benchReport ? h(BenchTable, { report: benchReport, t }) : null,
635
650
  ) : null
636
651
 
637
652
  const dockRow = h('div', { style: S.dock, title: t('dockHint') },
638
- h('span', { style: { fontSize: '11px', color: '#8b949e' } }, '⚗'),
653
+ h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #8b949e)' } }, '⚗'),
639
654
  presets.map((p) => h('button', {
640
- key: p.id, style: S.dockChip, title: t('dockHint'),
655
+ key: p.id, style: S.dockChip, 'data-dsh-part': 'chip', title: t('dockHint'),
641
656
  onClick: () => fire(p),
642
657
  }, (autoSend ? '🚀 ' : '⚡ ') + p.label_zh)),
643
658
  st ? h('button', {
644
- style: { ...S.dockChip, color: st.drifted ? '#f85149' : '#3fb950', borderColor: st.drifted ? '#f85149' : '#3fb950' },
659
+ style: { ...S.dockChip, color: st.drifted ? STATE_ERR : STATE_OK, borderColor: st.drifted ? STATE_ERR : STATE_OK },
660
+ 'data-dsh-part': 'chip',
645
661
  title: st.drifted ? t('reanchor') : t('dockAnchored'),
646
662
  onClick: st.drifted ? fireReanchor : undefined,
647
663
  }, st.drifted ? '⚠ ' + t('reanchor') : `⚓ ${t('dockAnchored')} ${st.god}/${st.total}`) : null,
648
664
  unanchored ? h('button', {
649
- style: { ...S.dockChip, color: '#8b949e', borderColor: '#8b949e', borderStyle: 'dotted' },
665
+ style: { ...S.dockChip, color: 'var(--dsw-alias-label-secondary, #8b949e)', borderColor: 'var(--dsw-alias-border-l1, #8b949e)', borderStyle: 'dotted' },
666
+ 'data-dsh-part': 'chip',
650
667
  title: t('unanchoredTitle'),
651
668
  onClick: () => setShowGuide((v) => !v),
652
669
  }, t('unanchored')) : null,
653
670
  unanchored && showGuide ? h('div', {
654
671
  style: {
655
- fontSize: '11px', color: '#8b949e', lineHeight: 1.6, maxWidth: '520px',
656
- borderLeft: '2px solid #8b949e', paddingLeft: '8px', margin: '2px 0',
672
+ fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #8b949e)', lineHeight: 1.6, maxWidth: '520px',
673
+ borderLeft: '2px solid var(--dsw-alias-border-l1, #8b949e)', paddingLeft: '8px', margin: '2px 0',
657
674
  },
658
675
  }, t('guideText')) : null,
659
- reanchorMsg ? h('span', { style: { fontSize: '11px', color: '#3fb950' } }, reanchorMsg) : null,
660
- h('button', { style: { ...S.dockChip, borderStyle: 'dashed' }, title: t('autoSend'), onClick: toggleAuto },
676
+ reanchorMsg ? h('span', { style: { fontSize: '11px', color: STATE_OK } }, reanchorMsg) : null,
677
+ h('button', { style: { ...S.dockChip, borderStyle: 'dashed' }, 'data-dsh-part': 'chip', title: t('autoSend'), onClick: toggleAuto },
661
678
  (autoSend ? '☑ ' : '☐ ') + t('autoSend')),
662
- st ? h('button', { style: { ...S.dockChip, borderStyle: 'dashed' }, title: t('autoReanchor'), onClick: toggleAutoReanchor },
679
+ st ? h('button', { style: { ...S.dockChip, borderStyle: 'dashed' }, 'data-dsh-part': 'chip', title: t('autoReanchor'), onClick: toggleAutoReanchor },
663
680
  (autoReanchor ? '☑ ' : '☐ ') + t('autoReanchor')) : null,
664
681
  h('button', {
665
- style: { ...S.dockChip, borderStyle: 'dashed', color: benchOpen ? '#d2a8ff' : '#8b949e', borderColor: benchOpen ? '#d2a8ff' : '#30363d' },
666
- title: t('bench'), 'data-deus': 'bench-chip',
682
+ style: { ...S.dockChip, borderStyle: 'dashed', color: benchOpen ? CLS_ACCENT.god : 'var(--dsw-alias-label-secondary, #8b949e)', borderColor: benchOpen ? CLS_ACCENT.god : 'var(--dsw-alias-border-l1, #30363d)' },
683
+ title: t('bench'), 'data-deus': 'bench-chip', 'data-dsh-part': 'chip',
667
684
  onClick: () => setBenchOpen((v) => !v),
668
685
  }, '🧪 ' + t('bench')),
669
686
  )
670
- return h('div', { style: { width: '100%' } }, benchPanel, dockRow)
687
+ return h('div', { style: { width: '100%' }, 'data-dsh-plugin': 'plugin-deus', 'data-dsh-surface': 'chat-input' }, benchPanel, dockRow)
671
688
  }
672
689
 
673
690
  // v0.3: 触发率迷你趋势(最近 40 条日志分 10 桶的 god 率折线)
@@ -687,10 +704,11 @@ window.__ModuleLoader__.load({
687
704
  const xy = pts.map(([i, v]) => [P + (W - 2 * P) * i / (B - 1), H - P - (H - 2 * P) * v])
688
705
  const dAttr = xy.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ',' + p[1].toFixed(1)).join(' ')
689
706
  return h('svg', { width: W, height: H, viewBox: `0 0 ${W} ${H}`, style: { display: 'block', margin: '4px 0 2px' } },
690
- h('path', { d: `M${P},${H - P} L${W - P},${H - P}`, stroke: '#30363d', strokeWidth: 1, fill: 'none' }),
691
- h('path', { d: `M${P},${P} L${W - P},${P}`, stroke: '#30363d', strokeWidth: 1, strokeDasharray: '3 3', fill: 'none' }),
692
- h('path', { d: dAttr, stroke: '#d2a8ff', strokeWidth: 2, fill: 'none' }),
693
- xy.map((p, i) => h('circle', { key: i, cx: p[0], cy: p[1], r: 2.5, fill: '#d2a8ff' })),
707
+ // var() SVG 表现属性里不解析,必须走 style(CSS 层才能吃自定义属性)
708
+ h('path', { d: `M${P},${H - P} L${W - P},${H - P}`, style: { stroke: 'var(--dsw-alias-border-l1, #30363d)' }, strokeWidth: 1, fill: 'none' }),
709
+ h('path', { d: `M${P},${P} L${W - P},${P}`, style: { stroke: 'var(--dsw-alias-border-l1, #30363d)' }, strokeWidth: 1, strokeDasharray: '3 3', fill: 'none' }),
710
+ h('path', { d: dAttr, style: { stroke: CLS_ACCENT.god }, strokeWidth: 2, fill: 'none' }),
711
+ xy.map((p, i) => h('circle', { key: i, cx: p[0], cy: p[1], r: 2.5, style: { fill: CLS_ACCENT.god } })),
694
712
  )
695
713
  }
696
714
 
@@ -719,7 +737,7 @@ window.__ModuleLoader__.load({
719
737
  inject: ['slots', 'locale'],
720
738
  apply(ctx) {
721
739
  try {
722
- try { window.__deusClient = '0.4.0' } catch { /* non-browser */ }
740
+ try { window.__deusClient = '0.4.1' } catch { /* non-browser */ }
723
741
  ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'deus-mode: dicts')
724
742
  const t = ctx.locale.bind(NS)
725
743
  ctx.slots.inject('settings.section', () => ctx.slots.register({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-suite/plugin-deus",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "神模扳机 Deus Trigger — 提示词 A/B 实验台:任意提示词变体各跑 N 次真实会话注入,指纹分布对比(Wilson CI + 两比例 z 检验);预设库 + 一键注入 + 起手识别器 + 触发率统计。社区观察未获官方证实,本插件不承诺解锁任何隐藏能力。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",