dsh-motor-ai-l0 0.3.2 → 0.3.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 +23 -0
- package/package.json +1 -1
- package/scripts/verify.mjs +27 -6
- package/skills/motor-l0-estimate/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@
|
|
|
5
5
|
|
|
6
6
|
版本三重一致性:`package.json.version` = `SKILL.md` 的 `metadata.version` = `CHANGELOG.md` 最新条目。
|
|
7
7
|
|
|
8
|
+
## [0.3.3] - 2026-10-12 — 🔧 发布自检脚本 EBUSY 免疫(无功能变化)
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **`scripts/verify.mjs` 全面摆脱子进程 spawn 依赖**(本机 node 进程内 spawn 持续
|
|
12
|
+
`EBUSY`,曾导致两项门禁无法执行):
|
|
13
|
+
1. 「进包 .mjs 相对 import 命中」门禁:由 `execFileSync('npm', ['pack','--dry-run','--json'], {shell:true})`
|
|
14
|
+
改为**纯 Node 的 `package.json files` 白名单展开**(含 `!` 排除与 `*` glob)。
|
|
15
|
+
语义等价——npm 在存在 `files` 时严格按白名单打包、`.npmignore` 不生效(见该文件首行注释),
|
|
16
|
+
已用真实 `npm pack` 交叉验证展开结果一致(53 个进包文件)。
|
|
17
|
+
顺带修复该门禁实现的两个 bug:`files` 项带尾斜杠(`tools/`)时路径拼出
|
|
18
|
+
`tools//l0//x.mjs` 双斜杠、与 import 解析结果不匹配 ⇒ 误报缺包。
|
|
19
|
+
2. 「配额闸门运行时行为」门禁:由 execFileSync 子进程改为 **ESM 顶层 await 预跑**
|
|
20
|
+
(`_selftest_quota.mjs` 导出 `runQuotaSelfTest()`,verify.mjs 顶层 await 后同步读结果)。
|
|
21
|
+
原因:verify 的 `check()` 是同步收集器(`const detail = fn()`),传 async fn 会静默假绿灯;
|
|
22
|
+
子进程通道又受 EBUSY 影响。顶层 await 是既不骗人也不依赖 spawn 的唯一通道。
|
|
23
|
+
- `scripts/_selftest_quota.mjs` 重构为「导出函数 + 仅主模块自跑」双通道
|
|
24
|
+
(`import.meta.url` 主模块判定),保留独立 CLI 能力(退出码 0/1)。
|
|
25
|
+
|
|
26
|
+
### 说明
|
|
27
|
+
- **无运行时功能变化**:0.3.2 的配额闸门功能完整;本版仅让发布自检脚本在
|
|
28
|
+
spawn 受限环境(CI/本机故障态)下仍可执行,且消除一次真实误报风险。
|
|
29
|
+
- 版本三重:`package.json` = `SKILL.md metadata.version` = `CHANGELOG` 最新条目 = 0.3.3。
|
|
30
|
+
|
|
8
31
|
## [0.3.2] - 2026-10-12 — 🚦 免费额度闸门(L2 商业闭环 · 免费层落地)
|
|
9
32
|
|
|
10
33
|
### Added
|
package/package.json
CHANGED
package/scripts/verify.mjs
CHANGED
|
@@ -1551,11 +1551,32 @@ check('P0 发布物无本机绝对路径泄漏(0.2.4/0.2.5 教训固化)', (
|
|
|
1551
1551
|
// 但 lib 不在 files 白名单 ⇒ 发布物缺该模块 ⇒ ERR_MODULE_NOT_FOUND ⇒ required 插件激活失败。
|
|
1552
1552
|
// 固化:解包后断言「所有进包 .mjs 的相对 import 必须命中包内文件」;漏网必报红。
|
|
1553
1553
|
check('发布门禁:进包 .mjs 的相对 import 必须命中包内文件(0.3.0 崩溃根因固化)', () => {
|
|
1554
|
-
//
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
const
|
|
1554
|
+
// 进包清单 = package.json files 白名单展开。不 spawn `npm pack --dry-run`:
|
|
1555
|
+
// ① 本机 node 进程内 spawn 可能持续 EBUSY(曾实测连 spawn 自身 node.exe 都失败);
|
|
1556
|
+
// ② npm 在存在 files 时严格按白名单打包、.npmignore 不生效(见 .npmignore 首行注释),
|
|
1557
|
+
// 语义与 `npm pack --dry-run --json` 等价(已用真实 npm pack 交叉验证文件数一致)。
|
|
1558
|
+
const globToRe = (g) => new RegExp('^' + g.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
1559
|
+
.replace(/\*/g, '[^/]*').replace(/\?/g, '[^/]') + '$')
|
|
1560
|
+
const entries = (pkg && pkg.files) || []
|
|
1561
|
+
const excludes = entries.filter(e => e.startsWith('!')).map(e => e.slice(1))
|
|
1562
|
+
const includes = entries.filter(e => e && !e.startsWith('!'))
|
|
1563
|
+
const isExcluded = (rel) => excludes.some(g => globToRe(g).test(rel))
|
|
1564
|
+
const packedSet = new Set()
|
|
1565
|
+
const walk = (rel) => {
|
|
1566
|
+
if (isExcluded(rel)) return
|
|
1567
|
+
let st
|
|
1568
|
+
try { st = statSync(join(ROOT, rel)) } catch { return }
|
|
1569
|
+
if (st.isDirectory()) {
|
|
1570
|
+
const parts = rel.split('/')
|
|
1571
|
+
if (parts.includes('node_modules') || parts.includes('.git')) return
|
|
1572
|
+
for (const name of readdirSync(join(ROOT, rel))) walk(rel + '/' + name)
|
|
1573
|
+
} else if (st.isFile()) {
|
|
1574
|
+
packedSet.add(rel)
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
for (const e of includes) walk(e.replace(/\/+$/, ''))
|
|
1578
|
+
packedSet.add('package.json')
|
|
1579
|
+
const packed = [...packedSet]
|
|
1559
1580
|
let count = 0
|
|
1560
1581
|
const missing = []
|
|
1561
1582
|
for (const pf of packed) {
|
|
@@ -1577,7 +1598,7 @@ check('发布门禁:进包 .mjs 的相对 import 必须命中包内文件(0.
|
|
|
1577
1598
|
}
|
|
1578
1599
|
must(missing.length === 0,
|
|
1579
1600
|
`进包文件引用但未进包的相对模块(必导致 DSH 加载崩溃):\n ${missing.join('\n ')}\n 修法:把该文件加入 package.json files,或把 import 改为依赖包路径`)
|
|
1580
|
-
return
|
|
1601
|
+
return `files 白名单展开 ${packed.length} 个进包文件;扫描 ${packed.filter(p => p.endsWith('.mjs')).length} 个 .mjs 共 ${count} 处相对 import,0 处缺包`
|
|
1581
1602
|
})
|
|
1582
1603
|
|
|
1583
1604
|
// ---------- 设计经验脱敏回传(design_exp)门禁 ----------
|