dsh-mini-utility-dock 0.2.0 → 0.3.0

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.en.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Release notes are generated from the matching version section; newest first.
4
4
  For Chinese, see [CHANGELOG.md](CHANGELOG.md).
5
5
 
6
+ ## 0.3.0 - 2026-09-22
7
+
8
+ - New `dsh-plugin-docs`: a bilingual docs structure check, adopted from the `check-docs.mjs` copy each plugin repository carried. Same interface: no arguments checks the README and CHANGELOG pairs for structural alignment, `--base <revision>` requires bilingual pairs to change together. This package's own bilingual docs are now checked by it too.
9
+ - README gains badges and a positioning statement; the two diagnostic bins (`dsh-plugin-parity`, `dsh-plugin-docs`) are documented with their purpose and opt-in mechanism; the package description states the "family shared assets" scope.
10
+
6
11
  ## 0.2.0 - 2026-09-21
7
12
 
8
13
  - New `dsh-plugin-parity`: a cross-repository drift check, adopted from the copy each plugin repository carried. The member list is caller-supplied via `--member <repo>:<export>`; this package names no repository of its own. Without `--member` it runs the static checks only and discovers every repository that embeds the host-guard block.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Release Notes 由对应版本段生成;最新版本在前。
4
4
  英文版见 [CHANGELOG.en.md](CHANGELOG.en.md)。
5
5
 
6
+ ## 0.3.0 - 2026-09-22
7
+
8
+ - 新增 `dsh-plugin-docs`:双语文档结构校验,收编自插件仓里各自维护的 `check-docs.mjs`。接口不变:无参数查 README 与 CHANGELOG 的中英结构对齐,`--base <revision>` 检查双语对同改。本包自身的双语文档也由此接入校验。
9
+ - README 补上 badges 与包定位说明;两个诊断 bin(`dsh-plugin-parity`、`dsh-plugin-docs`)的用途与接入方式补进文档;包描述同步「族级共享资产」的定位。
10
+
6
11
  ## 0.2.0 - 2026-09-21
7
12
 
8
13
  - 新增 `dsh-plugin-parity`:跨仓漂移诊断,收编自插件仓里各自维护的那份脚本。成员表由调用方通过 `--member <repo>:<export>` 提供,本包不点名任何仓;不带 `--member` 时只跑静态检查,自动发现所有嵌入了宿主守卫块的仓。
package/README.en.md CHANGED
@@ -2,7 +2,14 @@
2
2
 
3
3
  [中文](./README.md) | [English](./README.en.md)
4
4
 
5
- Source fragments and an embedding CLI shared by the DSH plugins.
5
+ [![ci](https://github.com/xswt442-cmd/dsh-mini-utility-dock/actions/workflows/ci.yml/badge.svg)](https://github.com/xswt442-cmd/dsh-mini-utility-dock/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/dsh-mini-utility-dock?label=npm&color=4d6bfe)](https://www.npmjs.com/package/dsh-mini-utility-dock)
7
+ [![release](https://img.shields.io/github/v/release/xswt442-cmd/dsh-mini-utility-dock?label=release&color=16a3a3)](https://github.com/xswt442-cmd/dsh-mini-utility-dock/releases)
8
+ [![node](https://img.shields.io/static/v1?label=node&message=%3E%3D20&color=339933&logo=node.js&logoColor=white)](https://nodejs.org)
9
+ [![downloads](https://img.shields.io/npm/d18m/dsh-mini-utility-dock?label=downloads&logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-mini-utility-dock)
10
+ [![license](https://img.shields.io/badge/license-MIT-22c55e.svg)](./LICENSE)
11
+
12
+ The DSH plugin family's shared assets: source fragments, an embedding CLI, and the cross-repo diagnostics and bilingual docs checks built around them.
6
13
 
7
14
  ## Fragments
8
15
 
@@ -44,4 +51,6 @@ Consumers invoke the same CLI as `loopback:sync` / `guard:sync`, with the target
44
51
 
45
52
  A consumer's `npm test` runs `loopback:check` / `guard:check`, comparing its two fragments byte for byte against the dock version it pins. A published version is immutable and consumers pin an exact version, so pin agreement implies fragment agreement.
46
53
 
47
- `scripts/guard-parity.mjs` (in each consumer) checks that cross-repo property directly, including pin agreement. It is a manual diagnostic and **does not run in CI**: the property cannot hold while peers sit on a different branch. Run it when all three checkouts share a branch.
54
+ `dsh-plugin-parity` (a bin provided by this package) checks that cross-repo property directly, including pin agreement and a behavioral comparison. It is a manual diagnostic and **does not run in CI**: the property cannot hold while peers sit on a different branch. The member list is caller-supplied via `--member <repo>:<export>` — the guard factory's export name is per-repository by fragment design, so the tool presupposes no members; without `--member` it runs the static checks only and discovers every checkout that embeds the guard block.
55
+
56
+ `dsh-plugin-docs` (another bin of this package) checks the documentation pairs for structural alignment: the two READMEs share heading levels and code-fence languages, the two CHANGELOGs expose the same releases, sections and item counts (section titles normalized through a bilingual category map); `--base <revision>` additionally requires both files of a pair to change together — a one-sided edit is a missing translation. Repositories opt in by pointing their own `docs:check` script at it; this package runs the same check on its own bilingual docs.
package/README.md CHANGED
@@ -2,7 +2,14 @@
2
2
 
3
3
  [中文](./README.md) | [English](./README.en.md)
4
4
 
5
- DSH 插件共享的源码片段与嵌入 CLI。
5
+ [![ci](https://github.com/xswt442-cmd/dsh-mini-utility-dock/actions/workflows/ci.yml/badge.svg)](https://github.com/xswt442-cmd/dsh-mini-utility-dock/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/dsh-mini-utility-dock?label=npm&color=4d6bfe)](https://www.npmjs.com/package/dsh-mini-utility-dock)
7
+ [![release](https://img.shields.io/github/v/release/xswt442-cmd/dsh-mini-utility-dock?label=release&color=16a3a3)](https://github.com/xswt442-cmd/dsh-mini-utility-dock/releases)
8
+ [![node](https://img.shields.io/static/v1?label=node&message=%3E%3D20&color=339933&logo=node.js&logoColor=white)](https://nodejs.org)
9
+ [![downloads](https://img.shields.io/npm/d18m/dsh-mini-utility-dock?label=downloads&logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-mini-utility-dock)
10
+ [![license](https://img.shields.io/badge/license-MIT-22c55e.svg)](./LICENSE)
11
+
12
+ DSH 插件族的共享资产:源码片段、嵌入 CLI,以及围绕它们的跨仓诊断与双语文档校验工具。
6
13
 
7
14
  ## 片段
8
15
 
@@ -44,4 +51,6 @@ npm run dock:embed -- sync path/to/client.js
44
51
 
45
52
  消费仓的 `npm test` 用 `loopback:check` / `guard:check` 把本仓两个片段与所 pin 的 dock 版本逐字节比对。dock 版本不可变且消费仓 pin 精确版本,故「pin 一致」即「片段一致」。
46
53
 
47
- `scripts/guard-parity.mjs`(位于各消费仓)直接检这条跨仓性质,含 pin 一致性断言。它是人工诊断工具,**不在 CI 中运行**:peer 处于不同分支时该性质本就不成立。请在三个检出同分支时运行。
54
+ `dsh-plugin-parity`(本包提供的 bin)直接检这条跨仓性质,含 pin 一致性断言与行为级对比。它是人工诊断工具,**不在 CI 中运行**:peer 处于不同分支时该性质本就不成立。成员表由调用方经 `--member <repo>:<export>` 提供——守卫工厂的导出名按片段设计是各仓自定的,故本工具不预设任何成员;不带 `--member` 时只跑静态检查,自动发现所有嵌入了宿主守卫块的仓。
55
+
56
+ `dsh-plugin-docs`(同样是本包的 bin)校验双语文档的结构对齐:README 中英标题层级与代码围栏一致,CHANGELOG 中英版本段、分类段与条目数一致(分类标题经双语映射归一);`--base <revision>` 额外要求双语对同改,单边改动即缺翻译。接入方式是各仓自己的 `docs:check` script 指向它——本包自身的双语文档也由此校验。
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+ // Bilingual structure check for the documentation pairs the DSH plugins ship:
3
+ // README.md against README.en.md, CHANGELOG.md against CHANGELOG.en.md.
4
+ //
5
+ // Verifies, naming no repository and taking no file arguments (the four names
6
+ // are the family convention):
7
+ // * both READMEs share the same heading-level sequence and code-fence
8
+ // languages — content inside fences is exempt, since that is where
9
+ // language-specific examples live;
10
+ // * both CHANGELOGs expose the same releases: version, date, per-section
11
+ // item counts, with section titles normalized through a bilingual
12
+ // category map (新增/Added, 修复/Fixed, ...);
13
+ // * with `--base <revision>`, both files of each pair changed together
14
+ // since that revision — a one-sided edit is a missing translation.
15
+ //
16
+ // Repositories opt in through their own `docs:check` script; this package
17
+ // runs the same check on its own bilingual docs.
18
+
19
+ import { execFileSync } from 'node:child_process'
20
+ import fs from 'node:fs'
21
+
22
+ const read = (file) => fs.readFileSync(file, 'utf8').replace(/\r\n/g, '\n')
23
+
24
+ function markdownShape(file) {
25
+ let fenced = false
26
+ const headings = []
27
+ const fences = []
28
+
29
+ for (const line of read(file).split('\n')) {
30
+ const fence = line.match(/^\s*```\s*(\S*)/)
31
+ if (fence) {
32
+ if (!fenced) fences.push(fence[1])
33
+ fenced = !fenced
34
+ continue
35
+ }
36
+ if (fenced) continue
37
+ const heading = line.match(/^(#{1,3})\s+/)
38
+ if (heading) headings.push(heading[1].length)
39
+ }
40
+
41
+ if (fenced) throw new Error(`${file}: unclosed code fence`)
42
+ return { headings, fences }
43
+ }
44
+
45
+ function changelogShape(file) {
46
+ const releases = []
47
+ let release
48
+ let section
49
+
50
+ for (const line of read(file).split('\n')) {
51
+ const version = line.match(/^##\s+(\d+\.\d+\.\d+)(?:\s+-\s+(\d{4}-\d{2}-\d{2}))?\s*$/)
52
+ if (version) {
53
+ release = { version: version[1], date: version[2] ?? '', sections: [] }
54
+ releases.push(release)
55
+ section = undefined
56
+ continue
57
+ }
58
+ if (!release) continue
59
+
60
+ const heading = line.match(/^###\s+(.+?)\s*$/)
61
+ if (heading) {
62
+ section = { title: heading[1], items: 0 }
63
+ release.sections.push(section)
64
+ continue
65
+ }
66
+ if (section && /^\s*-\s+/.test(line)) section.items += 1
67
+ }
68
+
69
+ return releases
70
+ }
71
+
72
+ const category = new Map([
73
+ ['新增', 'added'], ['Added', 'added'],
74
+ ['修复', 'fixed'], ['Fixed', 'fixed'],
75
+ ['变更', 'changed'], ['Changed', 'changed'],
76
+ ['移除', 'removed'], ['Removed', 'removed'],
77
+ ['安全', 'security'], ['Security', 'security'],
78
+ ['性能', 'performance'], ['Performance', 'performance'],
79
+ ['兼容性', 'compatibility'], ['Compatibility', 'compatibility'],
80
+ ['维护', 'maintenance'], ['Maintenance', 'maintenance'],
81
+ ])
82
+
83
+ function assertEqual(left, right, message) {
84
+ if (JSON.stringify(left) !== JSON.stringify(right)) {
85
+ throw new Error(`${message}\nleft: ${JSON.stringify(left)}\nright: ${JSON.stringify(right)}`)
86
+ }
87
+ }
88
+
89
+ const zhReadme = markdownShape('README.md')
90
+ const enReadme = markdownShape('README.en.md')
91
+ assertEqual(zhReadme, enReadme, 'README structure differs between languages')
92
+
93
+ const normalizeLog = (file) => changelogShape(file).map((release) => ({
94
+ version: release.version,
95
+ date: release.date,
96
+ sections: release.sections.map(({ title, items }) => ({
97
+ title: category.get(title) ?? title.toLowerCase(),
98
+ items,
99
+ })),
100
+ }))
101
+ assertEqual(normalizeLog('CHANGELOG.md'), normalizeLog('CHANGELOG.en.md'), 'CHANGELOG structure differs between languages')
102
+
103
+ const baseIndex = process.argv.indexOf('--base')
104
+ if (baseIndex !== -1) {
105
+ const base = process.argv[baseIndex + 1]
106
+ if (!base) throw new Error('--base requires a Git revision')
107
+
108
+ const changed = new Set(execFileSync('git', ['diff', '--name-only', base, 'HEAD'], { encoding: 'utf8' })
109
+ .split(/\r?\n/)
110
+ .filter(Boolean))
111
+
112
+ for (const [primary, translation] of [
113
+ ['README.md', 'README.en.md'],
114
+ ['CHANGELOG.md', 'CHANGELOG.en.md'],
115
+ ]) {
116
+ if (changed.has(primary) !== changed.has(translation)) {
117
+ throw new Error(`${primary} and ${translation} must change together`)
118
+ }
119
+ }
120
+ }
121
+
122
+ console.log('bilingual docs are structurally aligned')
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "dsh-mini-utility-dock",
3
- "version": "0.2.0",
4
- "description": "Canonical fragments and a build-time embedding CLI shared by DSH plugins: the Mini Utility Dock bootstrap for client halves, and the loopback predicates plus the host request guard for host halves.",
3
+ "version": "0.3.0",
4
+ "description": "The DSH plugin family's shared assets: source fragments (the Mini Utility Dock bootstrap for client halves, the loopback predicates and host request guard for host halves), the embedding CLI, and the family diagnostics — cross-repo drift check and bilingual docs structure check.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "dsh-mini-utility-dock": "bin/dsh-mini-utility-dock.js",
8
- "dsh-plugin-parity": "bin/dsh-plugin-parity.js"
8
+ "dsh-plugin-parity": "bin/dsh-plugin-parity.js",
9
+ "dsh-plugin-docs": "bin/dsh-plugin-docs.js"
9
10
  },
10
11
  "files": [
11
12
  "bin",
@@ -18,6 +19,7 @@
18
19
  ],
19
20
  "scripts": {
20
21
  "dock:embed": "node bin/dsh-mini-utility-dock.js",
22
+ "docs:check": "node bin/dsh-plugin-docs.js",
21
23
  "test": "node --test test/*.test.js"
22
24
  },
23
25
  "engines": {