@dsh-plugins/dsh-llm-hub 1.5.2 → 1.5.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 +38 -0
- package/package.json +2 -1
- package/scripts/prepublish-gate.mjs +105 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [1.5.3] - 2026-09-26
|
|
6
|
+
|
|
7
|
+
### 🛂 工程纪律对齐
|
|
8
|
+
|
|
9
|
+
#### 发版脚本 + tarball 收齐
|
|
10
|
+
|
|
11
|
+
- `scripts/prepublish-gate.mjs` 列入 `package.json#files`,随 tarball 出厂(1.5.2 时漏配)。
|
|
12
|
+
- 这条本身没功能改动,单纯是「门禁脚本要在 tarball 里」的一致性修补。
|
|
13
|
+
|
|
14
|
+
#### 作者身份纠正(修 1.5.0/1.5.1/1.5.2 的提交)
|
|
15
|
+
|
|
16
|
+
**根因**:1.5.0/1.5.1/1.5.2 三次发布的提交者不是 DSH 数字成员身份,而是套用了主人 paylinker 邮箱、漏了 `Agent:` trailer、commit type 用了 `release:`(不在 conventional 列表)。违反:
|
|
17
|
+
|
|
18
|
+
- `commit_convention §1`:数字成员用自己的 D1 email,禁止套主人邮箱。
|
|
19
|
+
- `commit_convention §1.5`:本机 CLI 提交必须带 `Agent: cli:<id>` trailer。
|
|
20
|
+
- `commit_convention §2`:commit type 必须是 `feat / fix / refactor / chore / docs / style / test / ci / perf`。
|
|
21
|
+
- `external-cli-layering`:GitHub 操作应该走 L1 `gh` CLI 而不是 L3 `curl`。
|
|
22
|
+
|
|
23
|
+
**为什么 1.5.0/1.5.1/1.5.2 不改**:tag 已发布、npm tarball 不可变、GH Release body 已建,回滚会
|
|
24
|
+
让那一批点升级的用户装不到。本版只**纠正未来**:
|
|
25
|
+
|
|
26
|
+
- 1.5.3 起 commit author 署 `DSH <dsh@webkubor.online>`(D1 上的 agent 身份)。
|
|
27
|
+
- trailer:`Agent: cli:claude-code`。
|
|
28
|
+
- commit type 用 conventional 写法 `chore(release):`。
|
|
29
|
+
- GH 操作走 `gh` CLI。
|
|
30
|
+
|
|
31
|
+
**为什么这次保留 `dsh-llm-hub` 的工作流**:1.5.0/1.5.1/1.5.2 的 commit 内容、CHANGELOG、assets/ 都是
|
|
32
|
+
对的,错的只是元数据(author / trailer / type)。元数据修一遍不影响业务,下次升级自然拉到
|
|
33
|
+
1.5.3 的内容。
|
|
34
|
+
|
|
35
|
+
**没有破坏性变更**,没有功能改动。
|
|
36
|
+
|
|
37
|
+
升级:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
dsh plugin --profile web update @dsh-plugins/dsh-llm-hub@^1.5.3
|
|
41
|
+
```
|
|
42
|
+
|
|
5
43
|
## [1.5.2] - 2026-09-26
|
|
6
44
|
|
|
7
45
|
### 🔧 发版门禁 + README 推广区
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plugins/dsh-llm-hub",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "DSH 模型管理层:网关可达性探测、模型目录拉取、DeepSeek + MiniMax/智谱/Moonshot/StepFun 余额与配额、本月用量统计、余额预警、Provider 健康看板,再把本机装好的 codex / claude / agy 注册成子代理(装了才出现)。零运行时依赖,不改动 DSH 安装。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"assets",
|
|
78
78
|
"cordis.patch.yml",
|
|
79
79
|
"lib",
|
|
80
|
+
"scripts",
|
|
80
81
|
"types"
|
|
81
82
|
]
|
|
82
83
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* prepublish-gate —— 在 `npm publish` 之前把三条硬契约拦在本地。
|
|
4
|
+
*
|
|
5
|
+
* 为什么是门禁而不是文档:
|
|
6
|
+
* 2026-09-26 推 1.5.0 时, CHANGELOG 写了、assets/ 落了、版本号 bump 了,
|
|
7
|
+
* 但 package.json 的 files 数组忘了加 'assets' —— 推上 npm 后 122kB
|
|
8
|
+
* tarball 不含 3 张 SVG, 从 npm 读 CHANGELOG.md 的人看不到截图。
|
|
9
|
+
* 同样那次, 1.5.1 推上去时 publish.yml 在「GH Release」那一步挂了:
|
|
10
|
+
* CHANGELOG 里没 [1.5.1] 段, 脚本 process.exit(1), 整个 job 标红。
|
|
11
|
+
* npm publish 已经过 —— 1.5.1 在 npm 上, 但 GH Release 没建, 走到 README
|
|
12
|
+
* 想挂 release link 时发现 404。
|
|
13
|
+
*
|
|
14
|
+
* 两条都是「约定没做成门禁」。本脚本把三条契约变成前置门:
|
|
15
|
+
* 1. tarball 必含 paths in MUST_INCLUDE
|
|
16
|
+
* 2. CHANGELOG 顶部必含 '## [<当前 package.json version>]' 段
|
|
17
|
+
* 3. assets/ 目录里至少有一张 .svg 推广图 (不允许空目录占位)
|
|
18
|
+
*
|
|
19
|
+
* 任一条挂了: process.exit(1) + stderr 一行指明错在哪。
|
|
20
|
+
*
|
|
21
|
+
* `npm publish` 调用 prepublishOnly 时, 本脚本非零退出 → publish 整体
|
|
22
|
+
* 失败, tarball 不会被推上 registry, 也就不会出现「npm 上了但本地行为
|
|
23
|
+
* 与预期不一致」的漂移。
|
|
24
|
+
*/
|
|
25
|
+
import { readFileSync } from 'node:fs'
|
|
26
|
+
import { execFileSync } from 'node:child_process'
|
|
27
|
+
import { dirname, join } from 'node:path'
|
|
28
|
+
import { fileURLToPath } from 'node:url'
|
|
29
|
+
|
|
30
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
31
|
+
const pkgRoot = dirname(here)
|
|
32
|
+
|
|
33
|
+
const pkg = JSON.parse(readFileSync(join(pkgRoot, 'package.json'), 'utf8'))
|
|
34
|
+
const version = pkg.version
|
|
35
|
+
|
|
36
|
+
const MUST_INCLUDE = [
|
|
37
|
+
'package.json',
|
|
38
|
+
'cordis.patch.yml',
|
|
39
|
+
'lib/client.js',
|
|
40
|
+
'lib/index.js',
|
|
41
|
+
'lib/harness.js',
|
|
42
|
+
'README.md',
|
|
43
|
+
'LICENSE'
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
const ASSETS_MIN = 1 // 至少一张 .svg, 防止目录被空提交
|
|
47
|
+
|
|
48
|
+
const errors = []
|
|
49
|
+
|
|
50
|
+
// ── 1. tarball 路径断言 ────────────────────────────────────────────────────
|
|
51
|
+
let packFiles
|
|
52
|
+
try {
|
|
53
|
+
const out = execFileSync('npm', ['pack', '--dry-run', '--json'], {
|
|
54
|
+
cwd: pkgRoot,
|
|
55
|
+
encoding: 'utf8',
|
|
56
|
+
stdio: ['ignore', 'pipe', 'inherit']
|
|
57
|
+
})
|
|
58
|
+
packFiles = JSON.parse(out)[0].files.map(f => f.path)
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error('[prepublish-gate] npm pack --dry-run 失败:', err.message)
|
|
61
|
+
process.exit(2)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const missing = MUST_INCLUDE.filter(p => !packFiles.includes(p))
|
|
65
|
+
if (missing.length > 0) {
|
|
66
|
+
errors.push(`tarball 缺少必含文件: ${missing.join(', ')}\n → 在 package.json 'files' 数组里列出, 或确认文件实际存在`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── 2. assets/ 目录必含至少一张 SVG ─────────────────────────────────────────
|
|
70
|
+
const assetSvgs = packFiles.filter(p => p.startsWith('assets/') && p.endsWith('.svg'))
|
|
71
|
+
if (assetSvgs.length < ASSETS_MIN) {
|
|
72
|
+
errors.push(`tarball assets/ 里 .svg < ${ASSETS_MIN}: 找到 ${assetSvgs.length} 张\n → 在 assets/ 下放图, 并确认 package.json 'files' 含 'assets'`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ── 3. CHANGELOG 顶部必含 '## [<当前 version>]' 段 ─────────────────────────
|
|
76
|
+
const changelogPath = join(pkgRoot, 'CHANGELOG.md')
|
|
77
|
+
let changelogText
|
|
78
|
+
try {
|
|
79
|
+
changelogText = readFileSync(changelogPath, 'utf8')
|
|
80
|
+
} catch (err) {
|
|
81
|
+
errors.push(`CHANGELOG.md 读取失败: ${err.message}`)
|
|
82
|
+
changelogText = ''
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (changelogText) {
|
|
86
|
+
const expectedHeader = `## [${version}]`
|
|
87
|
+
if (!changelogText.includes(expectedHeader)) {
|
|
88
|
+
errors.push(`CHANGELOG.md 缺少 '${expectedHeader}' 段\n → publish.yml 的 release body 直接 grep 这一行; 缺了 GH Release 创建会失败, npm 上却有版本号, 出现「npm 上了 / Release 没建」的漂移`)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ── 报告 ──────────────────────────────────────────────────────────────────
|
|
93
|
+
if (errors.length > 0) {
|
|
94
|
+
console.error(`\n[prepublish-gate] ${errors.length} 条契约不满足, 拒绝发版:\n`)
|
|
95
|
+
for (const e of errors) {
|
|
96
|
+
console.error(' ✖', e)
|
|
97
|
+
console.error('')
|
|
98
|
+
}
|
|
99
|
+
console.error('[prepublish-gate] exit 1 → npm publish 已中止。修完再推。')
|
|
100
|
+
process.exit(1)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log(`[prepublish-gate] ✓ @${pkg.name}@${version} 三条契约通过`)
|
|
104
|
+
console.log(`[prepublish-gate] · tarball: ${packFiles.length} 个文件, 含 ${assetSvgs.length} 张 assets/*.svg`)
|
|
105
|
+
console.log(`[prepublish-gate] · CHANGELOG 含 '## [${version}]' 段`)
|