@goodandready/dsh-dsml-artifact-guard 0.2.1 → 0.2.3

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,87 @@
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.3] - 2026-09-19
11
+
12
+ ### Fixed
13
+ - **Settings reachable again on the plugin's own page**: the card registered into
14
+ `settings.plugin.item` / `plugins.row.config`, and the current DSH core
15
+ (0.1.6-alpha.2) only renders a plugin's configuration page for entries registered
16
+ in the plugin list seat `plugins.item` — that is how `dsh-agentrouter` and
17
+ `dsh-agent-orchestrator` show their settings. The view-aware `PluginItem` is now
18
+ registered there as well (`id: 'dsh-dsml-artifact-guard'`, order 95, static label),
19
+ with the row seat and the legacy card kept as fallbacks.
20
+ - The render path was hardened on the way: `PluginCard` is wrapped in its own error
21
+ boundary so a throw inside this card cannot take the whole client batch down.
22
+
23
+ ## [0.2.2] - 2026-09-18
24
+
25
+ ### Fixed
26
+ - **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)).
27
+ - **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.
28
+
29
+ ---
30
+
31
+ ## [0.2.1] - 2026-09-18
32
+
33
+ ### Fixed
34
+ - **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)).
35
+ - **Theme Regression Test Guard (`test/theme.test.js`)**: Added automated regression test asserting zero hardcoded hex and rgba color literals in client surfaces.
36
+ - **Repository Hygiene**: Fixed `.gitignore` whitespace rule for `AGENTS.md` and untracked `package-lock.json` in alignment with zero-dependency architecture.
37
+
38
+ ---
39
+
40
+ ## [0.2.0] - 2026-09-17
41
+
42
+ ### Added
43
+ - **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)).
44
+ - **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)).
45
+ - **Core Primitive Chevron**: Requested `IconChevronDownOutline14` with SVG fallback.
46
+
47
+ ### Fixed
48
+ - **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)).
49
+ - **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)).
50
+
51
+ ---
52
+
53
+ ## [0.1.5] - 2026-09-17
54
+
55
+ ### Documentation
56
+ - 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)).
57
+
58
+ ---
59
+
60
+ ## [0.1.4] - 2026-09-12
61
+
62
+ ### Changed
63
+ - Schema `mode` default set to `sanitize` for out-of-the-box protection ([#11](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/11)).
64
+ - 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)).
65
+ - Updated design contract documentation and verified package hygiene ([#11](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/11)).
66
+
67
+ ---
68
+
69
+ ## [0.1.3] - 2026-09-06
70
+
71
+ ### Changed
72
+ - Wrapped `llm/stream` handler in `ctx.effect` for clean lifecycle unmount ([#8](https://github.com/GooDAnDReaDY/dsh-dsml-artifact-guard/issues/8)).
73
+ - 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)).
74
+
75
+ ---
76
+
77
+ ## [0.1.2] - 2026-09-02
78
+
79
+ ### Fixed
80
+ - Packaging and runtime compatibility adjustments for DSH profile loader.
81
+
82
+ ---
83
+
84
+ ## [0.1.1] - 2026-08-30
85
+
86
+ ### Added
87
+ - 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,31 +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
180
-
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.
186
-
187
- ## Changed in v0.2.1
186
+ ---
188
187
 
189
- - #26: Theme tokenization for settings card in `lib/client.js`: eliminated all 42 hardcoded hex/rgba color literals, migrating to canonical `--dsw-alias-...` CSS custom properties and `color-mix()` for flawless Dark and Light mode rendering.
190
- - #26: Added automated theme regression test guard (`test/theme.test.js`).
191
- - #26: Fixed `.gitignore` rule for `AGENTS.md` and untracked `package-lock.json` for pure zero-dependency repository hygiene.
188
+ For a complete release history and version migration notes, see [CHANGELOG.md](CHANGELOG.md).
package/README.ru.md CHANGED
@@ -161,31 +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
180
-
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.
186
-
187
- ## Изменения в v0.2.1
164
+ ---
188
165
 
189
- - #26: Полная токенизация темы для карточки настроек в `lib/client.js`: устранены все 42 вхождения захардкоженных hex/rgba цветов с переходом на канонические переменные ядра `--dsw-alias-...` и `color-mix()` для идеальной читаемости в тёмной и светлой темах.
190
- - #26: Добавлен автоматический тест-страж соответствия теме (`test/theme.test.js`).
191
- - #26: Исправлено правило игнорирования `AGENTS.md` в `.gitignore` и снято отслеживание с `package-lock.json` в рамках стандарта нулевых зависимостей.
166
+ Полная история версий и изменений доступна в файле [CHANGELOG.md](CHANGELOG.md).
package/README.zh.md CHANGED
@@ -161,31 +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 更新日志
180
-
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 打包归档。
186
-
187
- ## v0.2.1 更新日志
164
+ ---
188
165
 
189
- - #26:配置面板全量主题语义化规范(`lib/client.js`):彻底清除全部 42 处硬编码 hex/rgba 颜色,全面接入 `--dsw-alias-...` 核心变量与 `color-mix()`,保障深色与浅色主题下的极致对比度与可读性。
190
- - #26:新增前端主题规范自动化回归防护测试(`test/theme.test.js`)。
191
- - #26:修复 `.gitignore` 对 `AGENTS.md` 的忽略匹配,移除 `package-lock.json` 跟踪以践行极致零依赖标准。
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)',
250
- background: 'var(--dsw-alias-bg-card, var(--dsw-alias-bg-layer-3))',
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',
@@ -313,13 +307,15 @@ window.__ModuleLoader__.load({
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)',
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
@@ -504,10 +500,47 @@ window.__ModuleLoader__.load({
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,41 @@ 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
+
594
+ // List seat (plugins.item): the seat the Plugins page really renders as the
595
+ // plugin's own page with its configuration — the page draws the title, icon
596
+ // and crumb and asks for view 'summary' (the card's one-liner) or view 'page'
597
+ // (the form), both served by PluginItem. The label is a static string on
598
+ // purpose: it is resolved while the page renders, and a locale lookup there
599
+ // would take the whole client batch down with it.
600
+ registerSlotWhenReady('plugins.item', () =>
601
+ ctx.slots.register(
602
+ {
603
+ name: 'plugins.item',
604
+ id: 'dsh-dsml-artifact-guard',
605
+ order: 95,
606
+ label: () => 'DSML Artifact Guard',
607
+ locale: NS,
608
+ inject: () => ({ ctx }),
609
+ },
610
+ PluginItem
611
+ )
612
+ );
613
+
546
614
  registerSlotWhenReady('settings.plugin.item', () =>
547
615
  ctx.slots.register(
548
616
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-dsml-artifact-guard",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
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",