@goodandready/dsh-dsml-artifact-guard 0.2.0 โ†’ 0.2.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 ADDED
@@ -0,0 +1,74 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `@goodandready/dsh-dsml-artifact-guard` plugin are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [0.2.2] - 2026-09-18
11
+
12
+ ### Fixed
13
+ - **Settings reachable again (`lib/client.js`)**: the settings card registered into `settings.plugin.item`, a slot the current DSH core no longer renders, so the plugin's settings were unreachable. The surface now registers into the Plugins page row seat `plugins.row.config`, keyed `@goodandready/dsh-dsml-artifact-guard#dsh-dsml-artifact-guard`: the plugin's row gains a configure control whose page is the settings form (`view: 'page'`, rendered bare โ€” `PluginCard` accepts `bare` and drops the card wrapper because the host page draws the title, icon, crumb and padding) plus a one-line state under the title (`view: 'summary'`). The legacy seat stays registered as a fallback for older cores ([#31](http://192.168.1.111:3005/goodandready/dsh-dsml-artifact-guard/issues/31)).
14
+ - **Row-seat guard (`test/row-config-seat.test.js`)**: asserts the row key, the seat order (row seat first, legacy seat kept) and the bare page render.
15
+
16
+ ---
17
+
18
+ ## [0.2.1] - 2026-09-18
19
+
20
+ ### Fixed
21
+ - **Theme Semantic Standardization (`lib/client.js`)**: Eliminated all 42 hardcoded hex/rgba color literals in favor of canonical DeepSeek Harness theme CSS custom properties (`--dsw-alias-...`) and `color-mix()` tints, guaranteeing high contrast and legibility across Dark and Light modes ([#26](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/26)).
22
+ - **Theme Regression Test Guard (`test/theme.test.js`)**: Added automated regression test asserting zero hardcoded hex and rgba color literals in client surfaces.
23
+ - **Repository Hygiene**: Fixed `.gitignore` whitespace rule for `AGENTS.md` and untracked `package-lock.json` in alignment with zero-dependency architecture.
24
+
25
+ ---
26
+
27
+ ## [0.2.0] - 2026-09-17
28
+
29
+ ### Added
30
+ - **Native Settings Card (`lib/client.js`)**: Registered UI card in slot `settings.plugin.item` with snapshot status check, configuration inputs, and disabled warning indicator ([#17](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/17)).
31
+ - **One-Click In-Place Updater (`lib/updater.js`)**: Standard HTTP endpoint `/api/dsh-dsml-artifact-guard/update` with SemVer comparison, loopback/same-origin protection, and update execution ([#18](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/18)).
32
+ - **Core Primitive Chevron**: Requested `IconChevronDownOutline14` with SVG fallback.
33
+
34
+ ### Fixed
35
+ - **Package Hygiene**: Deduplicated multilingual READMEs in `docs/` and restricted `package.json#files` allowlist, reducing package size by ~40% ([#20](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/20)).
36
+ - **Repository Cleanliness**: Removed `AGENTS.md` from git tracking ([#19](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/19)) and eliminated legacy `.tgz` archives from source tree ([#21](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/21)).
37
+
38
+ ---
39
+
40
+ ## [0.1.5] - 2026-09-17
41
+
42
+ ### Documentation
43
+ - Fixed Mermaid diagram edge label syntax on GitHub and added standard community support block ([#15](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/15)).
44
+
45
+ ---
46
+
47
+ ## [0.1.4] - 2026-09-12
48
+
49
+ ### Changed
50
+ - Schema `mode` default set to `sanitize` for out-of-the-box protection ([#11](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/11)).
51
+ - Added robust open/close tag balancing in `sanitizeDsmlArtifacts` to handle prior closed blocks in prose ([#11](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/11)).
52
+ - Updated design contract documentation and verified package hygiene ([#11](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/11)).
53
+
54
+ ---
55
+
56
+ ## [0.1.3] - 2026-09-06
57
+
58
+ ### Changed
59
+ - Wrapped `llm/stream` handler in `ctx.effect` for clean lifecycle unmount ([#8](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/8)).
60
+ - Updated `cordis.patch.yml` to use `config: {}`, allowing schema defaults to apply automatically unless overridden ([#9](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/9)).
61
+
62
+ ---
63
+
64
+ ## [0.1.2] - 2026-09-02
65
+
66
+ ### Fixed
67
+ - Packaging and runtime compatibility adjustments for DSH profile loader.
68
+
69
+ ---
70
+
71
+ ## [0.1.1] - 2026-08-30
72
+
73
+ ### Added
74
+ - Initial release: synchronous, fail-open DSML protocol closing tag sanitizer for DeepSeek Harness model streams.
package/README.md CHANGED
@@ -110,6 +110,21 @@ The guard retains a minimal 96-byte window until the next chunk or `finish` even
110
110
  * **`audit`**: Emits diagnostic logs with `ctx.logger.info(...)` without modifying the user-visible stream.
111
111
  * **`disabled`**: Bypasses processing entirely.
112
112
 
113
+ ### 5. Native Web UI Settings Card
114
+ Registered directly in the DeepSeek Harness `settings.plugin.item` slot (`lib/client.js`):
115
+ * **Reactive Configuration**: Adjust `mode`, `providerId`, and `modelId` on the fly without restarting the harness, powered by reactive `scope.watch`.
116
+ * **Snapshot State Awareness**: Gracefully handles snapshot loading, ready, and unavailable states.
117
+ * **Protection Bypass Warning**: Displays a prominent `OFF` badge and warning banner when the guard is set to `disabled`.
118
+
119
+ ### 6. One-Click In-Place Auto-Updater
120
+ A canonical HTTP management route (`/api/dsh-dsml-artifact-guard/update`) mounted via `lib/updater.js`:
121
+ * **SemVer Inspection**: Queries the registry and compares versions with full pre-release support.
122
+ * **Loopback & Same-Origin Protection**: Write mutations (`POST`) are strictly restricted to local loopback connections with valid origin headers.
123
+ * **Clean Invocation**: Executes package updates safely without risky CLI bypass flags.
124
+
125
+ ### 7. Full Dark & Light Theme Compliance
126
+ All client UI styles are strictly tokenized via DeepSeek Harness `--dsw-alias-...` CSS custom properties and `color-mix()` functions with zero hardcoded hex or rgba color literals. High contrast and accessibility are guaranteed in both Dark and Light themes, guarded by automated regression tests (`test/theme.test.js`).
127
+
113
128
  ---
114
129
 
115
130
  ## ๐Ÿ“ฆ Installation
@@ -144,6 +159,13 @@ dsh-dsml-artifact-guard:
144
159
  | `providerId` | `string` | `"opencode-go"` | Target provider identifier exhibiting leaked tags |
145
160
  | `modelId` | `string` | `"deepseek-v4-flash"` | Target model identifier exhibiting leaked tags |
146
161
 
162
+ ### HTTP Management Endpoints
163
+
164
+ | Method | Endpoint | Access | Description |
165
+ |:---|:---|:---|:---|
166
+ | `GET` | `/api/dsh-dsml-artifact-guard/update` | Web UI / Localhost | Retrieves current version, latest registry version, and update status |
167
+ | `POST` | `/api/dsh-dsml-artifact-guard/update` | Loopback & Same-Origin | Triggers in-place package update via DSH CLI |
168
+
147
169
  ---
148
170
 
149
171
  ## ๐Ÿงช Testing
@@ -161,25 +183,6 @@ npm run check
161
183
 
162
184
  MIT ยฉ [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
163
185
 
164
- ## Changed in v0.1.3
165
-
166
- #8: wrap `llm/stream` in `ctx.effect` so unload unsubscribes.
167
- #9: `cordis.patch.yml` uses `config: {}` โ€” schema defaults (`mode: audit`, provider/model ids) apply unless overridden in host config.
168
-
169
- ## Changed in v0.1.4
170
-
171
- #11: schema `mode` default set to `sanitize` for out-of-the-box protection.
172
- #11: robust open/close tag balancing in `sanitizeDsmlArtifacts` to handle prior closed blocks in prose.
173
- #11: repo hygiene with tracked `package-lock.json` and design contract.
174
-
175
- ## Changed in v0.1.5
176
-
177
- #15: fix Mermaid diagram edge label syntax on GitHub and add mandatory repository support block.
178
-
179
- ## Changed in v0.2.0
186
+ ---
180
187
 
181
- - #17: Native DSH Settings Card in slot settings.plugin.item with snapshot status checking, form inputs, and disabled warning indicator.
182
- - #18: One-click plugin updater with endpoint /api/dsh-dsml-artifact-guard/update, semver comparison, and loopback/same-origin protection.
183
- - #19: Sanitized repository from internal AGENTS.md and updated .gitignore.
184
- - #20: Optimized npm package allowlist, eliminating duplicate READMEs and reducing package size by ~40%.
185
- - #21: Removed legacy build archives from source tree.
188
+ For a complete release history and version migration notes, see [CHANGELOG.md](CHANGELOG.md).
package/README.ru.md CHANGED
@@ -161,25 +161,6 @@ npm run check
161
161
 
162
162
  MIT ยฉ [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
163
163
 
164
- ## Changed in v0.1.3
165
-
166
- #8: wrap `llm/stream` in `ctx.effect` so unload unsubscribes.
167
- #9: `cordis.patch.yml` uses `config: {}` โ€” schema defaults (`mode: audit`, provider/model ids) apply unless overridden in host config.
168
-
169
- ## ะ˜ะทะผะตะฝะตะฝะธั ะฒ v0.1.4
170
-
171
- #11: ะทะฝะฐั‡ะตะฝะธะต `mode` ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ ะฒ ัั…ะตะผะต ะฟะตั€ะตะฒะตะดะตะฝะพ ะฝะฐ `sanitize` ะดะปั ะทะฐั‰ะธั‚ั‹ ยซะธะท ะบะพั€ะพะฑะบะธยป.
172
- #11: ะฑะฐะปะฐะฝัะธั€ะพะฒะบะฐ ะพั‚ะบั€ั‹ะฒะฐัŽั‰ะธั… ะธ ะทะฐะบั€ั‹ะฒะฐัŽั‰ะธั… ั‚ะตะณะพะฒ ะฒ `sanitizeDsmlArtifacts` ะฟั€ะธ ะฝะฐะปะธั‡ะธะธ ะทะฐะบั€ั‹ั‚ั‹ั… ะฑะปะพะบะพะฒ ะฒ ะฟั€ะพะทะต.
173
- #11: ะณะธะณะธะตะฝะฐ ั€ะตะฟะพะทะธั‚ะพั€ะธั ั ะพั‚ัะปะตะถะธะฒะฐะตะผั‹ะผ `package-lock.json` ะธ ะดะธะทะฐะนะฝ-ะบะพะฝั‚ั€ะฐะบั‚ะพะผ.
174
-
175
- ## ะ˜ะทะผะตะฝะตะฝะธั ะฒ v0.1.5
176
-
177
- #15: ะธัะฟั€ะฐะฒะปะตะฝ ัะธะฝั‚ะฐะบัะธั ัั‚ั€ะตะปะพะบ ะดะธะฐะณั€ะฐะผะผั‹ Mermaid ะฝะฐ GitHub ะธ ะดะพะฑะฐะฒะปะตะฝ ะพะฑัะทะฐั‚ะตะปัŒะฝั‹ะน ะฑะปะพะบ ะฟะพะดะดะตั€ะถะบะธ ั€ะตะฟะพะทะธั‚ะพั€ะธั.
178
-
179
- ## ะ˜ะทะผะตะฝะตะฝะธั ะฒ v0.2.0
164
+ ---
180
165
 
181
- - #17: ะะฐั‚ะธะฒะฝะฐั ะบะฐั€ั‚ะพั‡ะบะฐ ะฝะฐัั‚ั€ะพะตะบ ะฒ ัะปะพั‚ะต settings.plugin.item ัะพ ัั‚ะฐั‚ัƒัะพะผ ัะฝะธะผะบะฐ, ั„ะพั€ะผะพะน ะธ ะฟั€ะตะดัƒะฟั€ะตะถะดะตะฝะธะตะผ ะพะฑ ะพั‚ะบะปัŽั‡ะตะฝะธะธ.
182
- - #18: ะœะพะดัƒะปัŒ ะฐะฒั‚ะพะพะฑะฝะพะฒะปะตะฝะธั ะฒ 1 ะบะปะธะบ ั ัะฝะดะฟะพะธะฝั‚ะพะผ /api/dsh-dsml-artifact-guard/update, ัั€ะฐะฒะฝะตะฝะธะตะผ ะฒะตั€ัะธะน ะธ ะทะฐั‰ะธั‚ะพะน same-origin/loopback.
183
- - #19: ะกะฐะฝะธั‚ะฐะนะทะธะฝะณ ั€ะตะฟะพะทะธั‚ะพั€ะธั ะพั‚ ะฒะฝัƒั‚ั€ะตะฝะฝะตะณะพ AGENTS.md ะธ ะพะฑะฝะพะฒะปะตะฝะธะต .gitignore.
184
- - #20: ะžะฟั‚ะธะผะธะทะฐั†ะธั ัะพัั‚ะฐะฒะฐ npm-ะฟะฐะบะตั‚ะฐ, ัƒะดะฐะปะตะฝะธะต ะดัƒะฑะปะธะบะฐั‚ะพะฒ README ะธ ัะพะบั€ะฐั‰ะตะฝะธะต ั€ะฐะทะผะตั€ะฐ ะฟะฐะบะตั‚ะฐ ะฝะฐ ~40%.
185
- - #21: ะžั‡ะธัั‚ะบะฐ ะดะตั€ะตะฒะฐ ะธัั…ะพะดะฝะธะบะพะฒ ะพั‚ ะฐั€ั…ะธะฒะฝั‹ั… ะฟะฐะบะตั‚ะพะฒ .tgz.
166
+ ะŸะพะปะฝะฐั ะธัั‚ะพั€ะธั ะฒะตั€ัะธะน ะธ ะธะทะผะตะฝะตะฝะธะน ะดะพัั‚ัƒะฟะฝะฐ ะฒ ั„ะฐะนะปะต [CHANGELOG.md](CHANGELOG.md).
package/README.zh.md CHANGED
@@ -161,25 +161,6 @@ npm run check
161
161
 
162
162
  MIT ยฉ [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
163
163
 
164
- ## Changed in v0.1.3
165
-
166
- #8: wrap `llm/stream` in `ctx.effect` so unload unsubscribes.
167
- #9: `cordis.patch.yml` uses `config: {}` โ€” schema defaults (`mode: audit`, provider/model ids) apply unless overridden in host config.
168
-
169
- ## v0.1.4 ๅ˜ๆ›ด่ฏดๆ˜Ž
170
-
171
- #11: ๅฐ† schema ไธญ `mode` ้ป˜่ฎคๅ€ผ่ฎพ็ฝฎไธบ `sanitize`๏ผŒๅฎž็Žฐๅผ€็ฎฑๅณ็”จ็š„ๆธ…็†ไฟๆŠคใ€‚
172
- #11: ๅœจ `sanitizeDsmlArtifacts` ไธญๅฎž็Žฐไธฅๆ ผ็š„ๅผ€้—ญๆ ‡็ญพๆทฑๅบฆๅนณ่กก๏ผŒ็ฒพๅ‡†ๅค„็†ๆญฃๆ–‡ไธญๅทฒ้—ญๅˆๆ ‡็ญพไธŽๆœซๅฐพๆณ„ๆผๆ ‡็ญพใ€‚
173
- #11: ็บณๅ…ฅ `package-lock.json` ่ทŸ่ธชๅนถๅฎŒๅ–„่ฎพ่ฎกๅฅ‘็บฆใ€‚
174
-
175
- ## v0.1.5 ๅ˜ๆ›ด่ฏดๆ˜Ž
176
-
177
- #15: ไฟฎๅค GitHub ไธŠ Mermaid ๆต็จ‹ๅ›พ่พนๆ ‡็ญพ่ฏญๆณ•่งฃๆž้”™่ฏฏ๏ผŒๅนถ่กฅๅ…จๆ ‡ๅ‡†้กน็›ฎๆ”ฏๆŒๅผ•ๅฏผๅŒบใ€‚
178
-
179
- ## v0.2.0 ๆ›ดๆ–ฐๆ—ฅๅฟ—
164
+ ---
180
165
 
181
- - #17: ๅœจ settings.plugin.item ๆ’ๆงฝไธญๆณจๅ†ŒๅŽŸ็”Ÿ่ฎพ็ฝฎๅก็‰‡๏ผŒๆ”ฏๆŒๅฟซ็…ง็Šถๆ€ๆฃ€ๆŸฅไธŽ็ฆ็”จ่ญฆ็คบๆจชๅน…ใ€‚
182
- - #18: ไธ€้”ฎๅœจ็บฟๆ›ดๆ–ฐๆจกๅ—๏ผŒๆไพ› /api/dsh-dsml-artifact-guard/update ็ซฏ็‚นไธŽๅŒๆบ/ๅ›ž็Žฏๅฎ‰ๅ…จๆ ก้ชŒใ€‚
183
- - #19: ๆธ…็†ๅ…ฌๅผ€ไปฃ็ ไป“ๅบ“ไธญ็š„ๅ†…้ƒจ AGENTS.md ่ง„ๅˆ™ๆ–‡ไปถๅนถๆ›ดๆ–ฐ .gitignoreใ€‚
184
- - #20: ไผ˜ๅŒ– npm ๅ‘ๅธƒๅŒ…็™ฝๅๅ•๏ผŒ็งป้™คๅ†—ไฝ™ README ๅ‰ฏๆœฌ๏ผŒๅฎ‰่ฃ…ๅŒ…ไฝ“็งฏ็ผฉๅ‡็บฆ 40%FDใ€‚
185
- - #21: ๆธ…็†ๆบไปฃ็ ็›ฎๅฝ•ไธญ็š„ๆ—ง็‰ˆๆœฌ .tgz ๆ‰“ๅŒ…ๅฝ’ๆกฃใ€‚
166
+ ๅฎŒๆ•ด็‰ˆๆœฌๆผ”่ฟ›ไธŽๆ›ดๆ–ฐ่ฎฐๅฝ•่ฏฆ่ง [CHANGELOG.md](CHANGELOG.md)ใ€‚
package/lib/client.js CHANGED
@@ -6,6 +6,12 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
7
  const React = require('react');
8
8
  const NS = '@goodandready/dsh-dsml-artifact-guard';
9
+ // Row seat (#31): the Plugins page keys a row's configuration page by
10
+ // '<package name>#<row id>', with the row id exactly as cordis.patch.yml
11
+ // declares it. Keep all three in step with package.json and the patch.
12
+ const PKG = '@goodandready/dsh-dsml-artifact-guard';
13
+ const ROW_ID = 'dsh-dsml-artifact-guard';
14
+ const ROW_CONFIG_KEY = PKG + '#' + ROW_ID;
9
15
 
10
16
  // Query core chevron primitive when available; fallback SVG otherwise
11
17
  let CoreChevron = null;
@@ -77,7 +83,7 @@ window.__ModuleLoader__.load({
77
83
  modelId: 'deepseek-v4-flash',
78
84
  };
79
85
 
80
- function PluginCard({ ctx: _ctx, t }) {
86
+ function PluginCard({ ctx: _ctx, t, bare }) {
81
87
  const [expanded, setExpanded] = React.useState(false);
82
88
  const [draft, setDraft] = React.useState(DEFAULTS);
83
89
  const [status, setStatus] = React.useState('loading');
@@ -241,19 +247,7 @@ window.__ModuleLoader__.load({
241
247
 
242
248
  const isDisabled = draft.mode === 'disabled';
243
249
 
244
- return React.createElement('div', {
245
- 'data-dsh-plugin': NS,
246
- className: 'dsh-dsml-artifact-guard-card',
247
- style: {
248
- borderRadius: 12,
249
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
250
- background: 'var(--dsw-alias-bg-card, rgba(255,255,255,0.02))',
251
- overflow: 'hidden',
252
- marginBottom: 12,
253
- },
254
- },
255
- // Header
256
- React.createElement('div', {
250
+ const header = React.createElement('div', {
257
251
  onClick: () => setExpanded(v => !v),
258
252
  style: {
259
253
  display: 'flex',
@@ -271,7 +265,7 @@ window.__ModuleLoader__.load({
271
265
  style: {
272
266
  fontSize: 15,
273
267
  fontWeight: 600,
274
- color: 'var(--dsw-alias-label-primary, #f1f5f9)',
268
+ color: 'var(--dsw-alias-label-primary)',
275
269
  },
276
270
  }, tt('title')),
277
271
  React.createElement('span', {
@@ -280,8 +274,8 @@ window.__ModuleLoader__.load({
280
274
  fontWeight: 500,
281
275
  padding: '2px 6px',
282
276
  borderRadius: 6,
283
- background: 'rgba(59,130,246,0.15)',
284
- color: 'var(--dsw-alias-accent-primary, #3b82f6)',
277
+ background: 'color-mix(in srgb, var(--dsw-alias-brand-primary, var(--dsw-alias-state-brand-primary)) 15%, transparent)',
278
+ color: 'var(--dsw-alias-brand-primary, var(--dsw-alias-state-brand-primary))',
285
279
  },
286
280
  }, 'v' + updateState.currentVersion),
287
281
  isDisabled && React.createElement('span', {
@@ -290,15 +284,15 @@ window.__ModuleLoader__.load({
290
284
  fontWeight: 600,
291
285
  padding: '2px 6px',
292
286
  borderRadius: 6,
293
- background: 'rgba(239,68,68,0.15)',
294
- color: '#ef4444',
287
+ background: 'color-mix(in srgb, var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary)) 15%, transparent)',
288
+ color: 'var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary))',
295
289
  },
296
290
  }, 'OFF')
297
291
  ),
298
292
  React.createElement('span', {
299
293
  style: {
300
294
  fontSize: 13,
301
- color: 'var(--dsw-alias-label-secondary, #94a3b8)',
295
+ color: 'var(--dsw-alias-label-secondary)',
302
296
  },
303
297
  }, tt('sub'))
304
298
  ),
@@ -306,20 +300,22 @@ window.__ModuleLoader__.load({
306
300
  style: {
307
301
  display: 'flex',
308
302
  alignItems: 'center',
309
- color: 'var(--dsw-alias-label-tertiary, #64748b)',
303
+ color: 'var(--dsw-alias-label-tertiary)',
310
304
  },
311
305
  },
312
306
  CoreChevron
313
307
  ? React.createElement(CoreChevron, { style: { transform: expanded ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' } })
314
308
  : React.createElement('span', { dangerouslySetInnerHTML: { __html: expanded ? CHEVRON_UP_SVG : CHEVRON_DOWN_SVG } })
315
309
  )
316
- ),
310
+ );
317
311
 
318
- // Body
319
- expanded && React.createElement('div', {
312
+ // Body. The row/page seat asks for the form alone: the host page draws
313
+ // the title, icon and crumb and supplies its own padding, so rendering
314
+ // our card chrome there would double the border and shift the block.
315
+ const body = React.createElement('div', {
320
316
  style: {
321
- padding: '0 16px 16px',
322
- borderTop: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
317
+ padding: bare ? '0' : '0 16px 16px',
318
+ borderTop: bare ? 'none' : '1px solid var(--dsw-alias-border-l2)',
323
319
  },
324
320
  },
325
321
  // One-Click Updater block
@@ -327,9 +323,9 @@ window.__ModuleLoader__.load({
327
323
  style: {
328
324
  padding: '12px 14px',
329
325
  margin: '14px 0',
330
- background: 'rgba(255,255,255,0.03)',
326
+ background: 'color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent)',
331
327
  borderRadius: 8,
332
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
328
+ border: '1px solid var(--dsw-alias-border-l2)',
333
329
  display: 'flex',
334
330
  alignItems: 'center',
335
331
  justifyContent: 'space-between',
@@ -338,19 +334,19 @@ window.__ModuleLoader__.load({
338
334
  },
339
335
  },
340
336
  React.createElement('div', { style: { fontSize: 13, display: 'flex', alignItems: 'center', gap: 8 } },
341
- React.createElement('span', { style: { color: 'var(--dsw-alias-label-secondary, #94a3b8)' } },
337
+ React.createElement('span', { style: { color: 'var(--dsw-alias-label-secondary)' } },
342
338
  tt('version') + ': ' + updateState.currentVersion
343
339
  ),
344
- updateState.checking && React.createElement('span', { style: { color: 'var(--dsw-alias-label-tertiary, #64748b)', fontSize: 12 } },
340
+ updateState.checking && React.createElement('span', { style: { color: 'var(--dsw-alias-label-tertiary)', fontSize: 12 } },
345
341
  tt('updateChecking')
346
342
  ),
347
- !updateState.checking && updateState.updateAvailable && React.createElement('span', { style: { color: '#f59e0b', fontWeight: 600, fontSize: 12 } },
343
+ !updateState.checking && updateState.updateAvailable && React.createElement('span', { style: { color: 'var(--dsw-alias-state-warning-primary)', fontWeight: 600, fontSize: 12 } },
348
344
  tt('updateAvailable', { v: updateState.latestVersion })
349
345
  ),
350
- !updateState.checking && !updateState.updateAvailable && !updateState.error && React.createElement('span', { style: { color: '#10b981', fontSize: 12 } },
346
+ !updateState.checking && !updateState.updateAvailable && !updateState.error && React.createElement('span', { style: { color: 'var(--dsw-alias-state-success-primary)', fontSize: 12 } },
351
347
  'โœ“ ' + tt('upToDate')
352
348
  ),
353
- updateState.error && React.createElement('span', { style: { color: '#ef4444', fontSize: 12 } },
349
+ updateState.error && React.createElement('span', { style: { color: 'var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary))', fontSize: 12 } },
354
350
  updateState.error
355
351
  )
356
352
  ),
@@ -360,8 +356,8 @@ window.__ModuleLoader__.load({
360
356
  style: {
361
357
  padding: '6px 14px',
362
358
  borderRadius: 6,
363
- background: 'var(--dsw-alias-accent-primary, #3b82f6)',
364
- color: '#fff',
359
+ background: 'var(--dsw-alias-label-primary)',
360
+ color: 'var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-card))',
365
361
  border: 0,
366
362
  fontSize: 12,
367
363
  fontWeight: 600,
@@ -373,11 +369,11 @@ window.__ModuleLoader__.load({
373
369
  style: {
374
370
  padding: '8px 12px',
375
371
  marginBottom: 12,
376
- background: 'rgba(16,185,129,0.1)',
377
- color: '#10b981',
372
+ background: 'color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)',
373
+ color: 'var(--dsw-alias-state-success-primary)',
378
374
  borderRadius: 6,
379
375
  fontSize: 12,
380
- border: '1px solid rgba(16,185,129,0.2)',
376
+ border: '1px solid color-mix(in srgb, var(--dsw-alias-state-success-primary) 20%, transparent)',
381
377
  },
382
378
  }, updateState.notice),
383
379
 
@@ -386,20 +382,20 @@ window.__ModuleLoader__.load({
386
382
  style: {
387
383
  padding: '8px 12px',
388
384
  marginBottom: 14,
389
- background: 'rgba(239,68,68,0.1)',
390
- color: '#f87171',
385
+ background: 'color-mix(in srgb, var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary)) 10%, transparent)',
386
+ color: 'var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary))',
391
387
  borderRadius: 6,
392
388
  fontSize: 12,
393
- border: '1px solid rgba(239,68,68,0.2)',
389
+ border: '1px solid color-mix(in srgb, var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary)) 20%, transparent)',
394
390
  },
395
391
  }, tt('disabledNotice')),
396
392
 
397
393
  // Status Loading / Unavailable
398
394
  status === 'loading' && React.createElement('div', {
399
- style: { padding: '16px 0', fontSize: 13, color: 'var(--dsw-alias-label-tertiary, #64748b)' },
395
+ style: { padding: '16px 0', fontSize: 13, color: 'var(--dsw-alias-label-tertiary)' },
400
396
  }, tt('saving')),
401
397
  status === 'unavailable' && React.createElement('div', {
402
- style: { padding: '16px 0', fontSize: 13, color: '#ef4444' },
398
+ style: { padding: '16px 0', fontSize: 13, color: 'var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary))' },
403
399
  }, tt('statusUnavailable')),
404
400
 
405
401
  // Settings Fields
@@ -407,7 +403,7 @@ window.__ModuleLoader__.load({
407
403
  // Mode Select
408
404
  React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
409
405
  React.createElement('label', {
410
- style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary, #f1f5f9)' },
406
+ style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary)' },
411
407
  }, tt('mode')),
412
408
  React.createElement('select', {
413
409
  value: draft.mode,
@@ -415,9 +411,9 @@ window.__ModuleLoader__.load({
415
411
  style: {
416
412
  height: 34,
417
413
  borderRadius: 6,
418
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
419
- background: 'var(--dsw-alias-bg-field, rgba(0,0,0,0.2))',
420
- color: 'var(--dsw-alias-label-primary, #f1f5f9)',
414
+ border: '1px solid var(--dsw-alias-border-l2)',
415
+ background: 'var(--dsw-alias-bg-field, var(--dsw-alias-bg-layer-2))',
416
+ color: 'var(--dsw-alias-label-primary)',
421
417
  padding: '0 10px',
422
418
  fontSize: 13,
423
419
  },
@@ -431,7 +427,7 @@ window.__ModuleLoader__.load({
431
427
  // Provider ID Field
432
428
  React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
433
429
  React.createElement('label', {
434
- style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary, #f1f5f9)' },
430
+ style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary)' },
435
431
  }, tt('providerId')),
436
432
  React.createElement('input', {
437
433
  type: 'text',
@@ -440,9 +436,9 @@ window.__ModuleLoader__.load({
440
436
  style: {
441
437
  height: 34,
442
438
  borderRadius: 6,
443
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
444
- background: 'var(--dsw-alias-bg-field, rgba(0,0,0,0.2))',
445
- color: 'var(--dsw-alias-label-primary, #f1f5f9)',
439
+ border: '1px solid var(--dsw-alias-border-l2)',
440
+ background: 'var(--dsw-alias-bg-field, var(--dsw-alias-bg-layer-2))',
441
+ color: 'var(--dsw-alias-label-primary)',
446
442
  padding: '0 10px',
447
443
  fontSize: 13,
448
444
  },
@@ -452,7 +448,7 @@ window.__ModuleLoader__.load({
452
448
  // Model ID Field
453
449
  React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
454
450
  React.createElement('label', {
455
- style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary, #f1f5f9)' },
451
+ style: { fontSize: 13, fontWeight: 500, color: 'var(--dsw-alias-label-primary)' },
456
452
  }, tt('modelId')),
457
453
  React.createElement('input', {
458
454
  type: 'text',
@@ -461,9 +457,9 @@ window.__ModuleLoader__.load({
461
457
  style: {
462
458
  height: 34,
463
459
  borderRadius: 6,
464
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
465
- background: 'var(--dsw-alias-bg-field, rgba(0,0,0,0.2))',
466
- color: 'var(--dsw-alias-label-primary, #f1f5f9)',
460
+ border: '1px solid var(--dsw-alias-border-l2)',
461
+ background: 'var(--dsw-alias-bg-field, var(--dsw-alias-bg-layer-2))',
462
+ color: 'var(--dsw-alias-label-primary)',
467
463
  padding: '0 10px',
468
464
  fontSize: 13,
469
465
  },
@@ -477,7 +473,7 @@ window.__ModuleLoader__.load({
477
473
  alignItems: 'center',
478
474
  gap: 12,
479
475
  paddingTop: 12,
480
- borderTop: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
476
+ borderTop: '1px solid var(--dsw-alias-border-l2)',
481
477
  marginTop: 4,
482
478
  },
483
479
  },
@@ -489,8 +485,8 @@ window.__ModuleLoader__.load({
489
485
  padding: '0 18px',
490
486
  border: 0,
491
487
  borderRadius: 8,
492
- background: 'var(--dsw-alias-accent-primary, #3b82f6)',
493
- color: '#fff',
488
+ background: 'var(--dsw-alias-label-primary)',
489
+ color: 'var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-card))',
494
490
  fontSize: 13,
495
491
  fontWeight: 600,
496
492
  cursor: saving ? 'default' : 'pointer',
@@ -499,15 +495,52 @@ window.__ModuleLoader__.load({
499
495
  msg && React.createElement('span', {
500
496
  style: {
501
497
  fontSize: 13,
502
- color: msg === tt('saved') ? '#10b981' : '#f87171',
498
+ color: msg === tt('saved') ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-danger-primary, var(--dsw-alias-state-error-primary))',
503
499
  },
504
500
  }, msg)
505
501
  )
506
502
  )
507
- )
503
+ );
504
+ if (bare) {
505
+ return React.createElement('div', {
506
+ 'data-dsh-plugin': NS,
507
+ className: 'dsh-dsml-artifact-guard-form',
508
+ }, body);
509
+ }
510
+ return React.createElement('div', {
511
+ 'data-dsh-plugin': NS,
512
+ className: 'dsh-dsml-artifact-guard-card',
513
+ style: {
514
+ borderRadius: 12,
515
+ border: '1px solid var(--dsw-alias-border-l2)',
516
+ background: 'var(--dsw-alias-bg-card, var(--dsw-alias-bg-layer-3))',
517
+ overflow: 'hidden',
518
+ marginBottom: 12,
519
+ },
520
+ },
521
+ header,
522
+ expanded && body
508
523
  );
509
524
  }
510
525
 
526
+ // View-aware entry for the host slots that carry a configuration page.
527
+ // 'plugins.row.config' asks for view:'summary' (the one-liner under the row
528
+ // title) and view:'page' (the form, bare). The older seat keeps the card.
529
+ function PluginItem(props) {
530
+ if (props && props.view === 'summary') {
531
+ const ctx = props && props.ctx;
532
+ const lang = (ctx && ctx.locale && typeof ctx.locale.get === 'function' ? ctx.locale.get() : null) || 'en';
533
+ const dict = String(lang).startsWith('zh') ? zh : en;
534
+ const tt = typeof props.t === 'function' ? props.t : (k) => dict[k] || en[k] || k;
535
+ return React.createElement('div', {
536
+ 'data-dsh-plugin': NS,
537
+ className: 'dsh-dsml-artifact-guard-sub',
538
+ style: { fontSize: 13, color: 'var(--dsw-alias-label-secondary)' },
539
+ }, tt('sub'));
540
+ }
541
+ return React.createElement(PluginCard, Object.assign({}, props, { bare: true }));
542
+ }
543
+
511
544
  exports.inject = ['slots', 'settingsScope', 'locale'];
512
545
  exports.apply = function apply(ctx) {
513
546
  if (typeof ctx.locale?.register === 'function') {
@@ -543,6 +576,21 @@ window.__ModuleLoader__.load({
543
576
  }
544
577
  }
545
578
 
579
+ // Newest seat first: the Plugins page renders a row's own configuration
580
+ // page from 'plugins.row.config'. Keep 'settings.plugin.item' below as the
581
+ // fallback for cores that still render the old card slot.
582
+ registerSlotWhenReady('plugins.row.config', () =>
583
+ ctx.slots.register(
584
+ {
585
+ name: 'plugins.row.config',
586
+ key: ROW_CONFIG_KEY,
587
+ locale: NS,
588
+ inject: () => ({ ctx }),
589
+ },
590
+ PluginItem
591
+ )
592
+ );
593
+
546
594
  registerSlotWhenReady('settings.plugin.item', () =>
547
595
  ctx.slots.register(
548
596
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-dsml-artifact-guard",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Sanitizes leaked DeepSeek DSML closing tags from model text streams",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -11,7 +11,8 @@
11
11
  "README.md",
12
12
  "README.ru.md",
13
13
  "README.zh.md",
14
- "LICENSE"
14
+ "LICENSE",
15
+ "CHANGELOG.md"
15
16
  ],
16
17
  "scripts": {
17
18
  "check": "node --check lib/index.js",