dsh-vibe-math 2.0.1 → 2.0.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.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/installer.js +72 -3
  3. package/package.json +12 -2
package/README.md CHANGED
@@ -97,7 +97,8 @@ dsh plugin --profile <你的 profile> add github:ChongCyrus/Vibe-Mathematics
97
97
  - **形态依赖**:三个 preset 依赖 DSH 的标准 **agent-preset 机制**(`~/.dsh/.agent-presets/<id>/` + preset picker)与 **bundle patch 机制**(`cordis.patch.yml` 注入安装器)。
98
98
  - **宿主插件行**:`agent.cordis.yml` 引用宿主提供的 `@deepseek-ai/dsh-*` 插件行(persona、agent-instructions、tool-bash/pwsh、tool-fs/fs-search、tool-jobs、skill-filesystem、tool-skill、tool-goal、plan-mode、compaction、subagent/workflow、ask-user、todo、web 等,约 21 个唯一包名)。宿主缺行会导致 preset 挂载失败(会话启动时报错)。
99
99
  - **宿主服务 API**:预设插件消费 `subagents`(startContinuable / followup / interrupt)、`agents`(roots)、`tools`(register)、`commands`(register)、`fs`(resolve/stat/readText/writeText/listDir)、可选 `subprocess` / `sandboxPolicy`。这些 API 形状随 DSH 版本演进;本项目**已充分测试并确认适配 `dsh-v0.1.2-rc.1`**(`package.json` 的 `dsh.testedVersion`;`minVersion` 为 `0.1.2-rc.1`)。**注意:DSH 0.1.2 起 `subagents.startContinuable` 的 `agentOptions` / `toolFilter` 需要宿主 provider 声明对应 capability**(spawn / fork 进程内 provider 均支持,v4 指定常驻模型/路由与工具权限依赖于此)。
100
- - **运行时自检**:安装器(bundle 插件)每次启动时对上述服务与关键 API 做**能力自检**(DSH 不暴露版本号,故按能力而非版本检测;含 `fs.resolve` 返回形状检测与 subagent `agentOptions`/`toolFilter` capability 检测);不满足时打 warning 并提示升级 DSH。preset 挂载失败时先看 DSH 日志里的自检 warning。
100
+ - **DSH STORE 兼容声明**:`package.json` 的 `dsh.compatibility.dshReleases` 对每个完整 DSH 版本逐项声明 `compatible` / `incompatible` / `unknown`(当前 `0.1.2-alpha.4`、`0.1.2-alpha.5`、`0.1.2-rc.1` 均标 `compatible`);`engines.node` `^22.19.0 || >=24.0.0`(与 DSH 0.1.2 相同)。
101
+ - **运行时自检(能力 + 版本双检)**:安装器(bundle 插件)每次启动时:**① 尽力探测 DSH 版本**(读 `@deepseek-ai/dsh/package.json` 或 `DSH_VERSION` 环境变量;DSH 未通过公开 service/context 暴露版本,故为尽力而为,探测不到就跳过)。若探测到且该版本未被 `dshReleases` 声明为 `compatible`,会给出明确"DSH 版本不匹配,请使用 `dsh-v0.1.2-rc.1`(或 `0.1.2-alpha.4/alpha.5`)"提示;**② 再对上述服务与关键 API 做能力自检**(这是真正的挂载门槛,含 `fs.resolve` 返回形状检测与 subagent `agentOptions`/`toolFilter` capability 检测),不满足时打 warning。preset 挂载失败时先看 DSH 日志里的自检 warning。
101
102
  - **升级路径**:DSH 升级后无需重装本包;升级本包用 `dsh plugin update dsh-vibe-math`,重启 DSH 后安装器会自动把 preset 更新到新版本(见上文「安装」说明)。
102
103
 
103
104
  ---
package/installer.js CHANGED
@@ -24,7 +24,8 @@
24
24
  // are preserved and reported via the logger.
25
25
  // - same version: no-op (idempotent). Missing files are ALWAYS restored.
26
26
  // - force a full refresh at any time: delete the preset dirs and restart DSH.
27
- import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
27
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, unlinkSync, rmdirSync } from 'node:fs'
28
+ import { createRequire } from 'node:module'
28
29
  import { createHash } from 'node:crypto'
29
30
  import { homedir } from 'node:os'
30
31
  import { dirname, join } from 'node:path'
@@ -75,8 +76,42 @@ function writeState(path, state) {
75
76
 
76
77
  // DSH 适配性自检(能力检测,而非版本号——DSH 不向插件暴露版本)。
77
78
  // 检查 preset 运行时需要的宿主服务与关键 API 形状是否可用,缺失时打 warning。
79
+ // Best-effort DSH host-version detection. DSH does NOT expose its version through a documented
80
+ // service/context property or a guaranteed env var, so we probe in order: an explicit env var
81
+ // (future-proofing), then the installed @deepseek-ai/dsh package.json. This is layout-dependent
82
+ // (works for a typical global install where @deepseek-ai/dsh is a sibling of this plugin); when it
83
+ // cannot resolve, the capability self-check below is still the authoritative gate.
84
+ const __require = createRequire(import.meta.url)
85
+ function detectDshVersion() {
86
+ try { const v = process.env.DSH_VERSION; if (v && String(v).trim()) return String(v).trim() } catch (e) {}
87
+ try {
88
+ const p = __require.resolve('@deepseek-ai/dsh/package.json')
89
+ const v = (JSON.parse(readFileSync(p, 'utf8')).version || '').trim()
90
+ if (v) return v
91
+ } catch (e) { /* host package not resolvable from here — rely on capability check */ }
92
+ return undefined
93
+ }
94
+
78
95
  async function checkHostCapabilities(ctx, logger) {
79
96
  const problems = []
97
+ // 1) DSH version compatibility (best-effort, only when the version is detectable).
98
+ // Declared under package.json dsh.compatibility.dshReleases (per the DSH STORE contract):
99
+ // each full DSH release maps to 'compatible' | 'incompatible' | 'unknown'. A version that is
100
+ // absent or 'unknown' is a soft warning; 'incompatible' is a hard "please use X" message.
101
+ let dshRel = {}
102
+ try { const m = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'package.json'), 'utf8')); dshRel = (m.dsh && m.dsh.compatibility && m.dsh.compatibility.dshReleases) || {} } catch (e) {}
103
+ const supported = Object.keys(dshRel).sort()
104
+ const dshVersion = detectDshVersion()
105
+ if (dshVersion) {
106
+ const status = dshRel[dshVersion]
107
+ if (status === 'incompatible') {
108
+ problems.push('当前 DSH 版本 v' + dshVersion + ' 被本包声明为 incompatible;请使用 ' + supported.join(' / ') + '。')
109
+ } else if (status === undefined || status === 'unknown') {
110
+ problems.push('当前 DSH 版本 v' + dshVersion + ' 尚未被本包声明为兼容(dshReleases 仅声明 ' + supported.join(' / ') + ');建议使用 ' + supported.join(' / ') + ',或将该版本在 dshReleases 中标注后再自行验证。')
111
+ }
112
+ }
113
+ // 2) capability self-check (the authoritative mounting gate; also covers hosts whose version
114
+ // could not be read). subagents / agents / tools / commands / fs shapes + v4 capabilities.
80
115
  const checks = [
81
116
  ['subagents', ['startContinuable', 'followup', 'interrupt']],
82
117
  ['agents', ['roots']],
@@ -120,9 +155,9 @@ async function checkHostCapabilities(ctx, logger) {
120
155
  }
121
156
  } catch (e) { /* 探测失败不致命 */ }
122
157
  if (problems.length > 0) {
123
- logger?.warn?.('[dsh-vibe-math] 宿主能力自检:' + problems.length + ' 项不满足(' + problems.join(';') + ')。v2/v3/v4 预设依赖这些宿主服务/API,旧版 DSH 可能无法挂载,建议升级 DSH(本项目已充分测试并确认适配 dsh-v0.1.2-rc.1,见 package.json dsh.minVersion/testedVersion)。')
158
+ logger?.warn?.('[dsh-vibe-math] 宿主自检:' + problems.length + ' 项不满足(' + problems.join(';') + ')。v2/v3/v4 预设依赖这些宿主服务/API,旧版或未经声明兼容的 DSH 可能无法挂载' + (dshVersion ? '(当前检测到 DSH v' + dshVersion + ',本包适配 ' + (supported.length ? supported.join(' / ') : '(未声明)') + ')' : '') + '。')
124
159
  } else {
125
- logger?.info?.('[dsh-vibe-math] 宿主能力自检通过:subagents / agents / tools / commands / fs 服务及关键 API 均可用(已确认适配 DSH 0.1.2-rc.1)。')
160
+ logger?.info?.('[dsh-vibe-math] 宿主自检通过:subagents / agents / tools / commands / fs 服务及关键 API 均可用' + (dshVersion ? '(当前 DSH v' + dshVersion + ',本包已声明兼容 ' + supported.join(' / ') + ')' : '') + '。')
126
161
  }
127
162
  }
128
163
 
@@ -195,8 +230,42 @@ export async function apply(ctx) {
195
230
  }
196
231
  }
197
232
 
233
+ // Clean up preset dirs that this bundle NO LONGER manages (e.g. vibe-math-v1 after it was
234
+ // removed at v2.0.0). The copy loop only adds/updates PRESETS; it never deletes a preset that
235
+ // was dropped, so an old removed preset would linger in the picker forever. Here we remove the
236
+ // files this installer previously recorded as package-owned under a prefix that is no longer in
237
+ // PRESETS, then drop the dir if it became empty. User-owned files (provenance 'user') are kept.
238
+ const currentPrefixes = new Set(PRESETS.map(p => p.src + '/'))
239
+ let removedFiles = 0
240
+ let removedDirs = []
241
+ const stale = new Map() // prefix -> [keys]
242
+ for (const key of Object.keys(prevFiles)) {
243
+ const slash = key.indexOf('/')
244
+ if (slash === -1) continue
245
+ const prefix = key.slice(0, slash + 1)
246
+ if (currentPrefixes.has(prefix)) continue
247
+ if (!stale.has(prefix)) stale.set(prefix, [])
248
+ stale.get(prefix).push(key)
249
+ }
250
+ for (const [prefix, keys] of stale) {
251
+ let dirEmpty = true
252
+ for (const key of keys) {
253
+ const rec = (prevFiles[key] && typeof prevFiles[key] === 'object') ? prevFiles[key] : { provenance: 'package' }
254
+ if (rec.provenance === 'user') { dirEmpty = false; continue } // 用户文件 → 保留
255
+ const f = join(presetRoot, key)
256
+ if (existsSync(f)) { try { unlinkSync(f); removedFiles += 1 } catch (e) {} }
257
+ if (existsSync(f)) dirEmpty = false
258
+ }
259
+ const dir = join(presetRoot, prefix.slice(0, -1))
260
+ if (dirEmpty && existsSync(dir)) { try { rmdirSync(dir); removedDirs.push(dir) } catch (e) {} }
261
+ }
262
+
198
263
  writeState(stateFile, { version: pkgVersion, files: nextFiles, updatedAt: Date.now() })
199
264
 
265
+ if (removedFiles > 0 || removedDirs.length > 0) {
266
+ logger?.info?.('[dsh-vibe-math] preset cleanup: removed ' + removedFiles + ' file(s) from ' + removedDirs.length + ' stale preset dir(s) (' + removedDirs.map(d => d.split(/[\\/]/).pop()).join(', ') + ') that are no longer shipped.')
267
+ }
268
+
200
269
  if (isUpgrade) {
201
270
  logger?.info?.('[dsh-vibe-math] preset auto-update: version ' + (state.version || '(none)') + ' → ' + pkgVersion +
202
271
  ' — 新增 ' + installed + ' 个文件,更新 ' + updated + ' 个文件' +
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "dsh-vibe-math",
3
3
  "description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — THREE agent presets in one install: vibe-math-v2 (probability-driven: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), vibe-math-v3 (THIRD-generation, recommended: paper-style Markdown knowledge base with Problems/Progress/Propos/Methods/Verified + planner-agent scheduling that decides the next N actions + universal theory/method invention library + agents write their own Markdown directly via a per-file write lock), and vibe-math-v4 (FOURTH-generation: persistent self-organizing resident subagents that message & meet to decide all tasks, verify only by unanimous consensus, /compact at a context threshold, and stop only when all agree the problem is solved). Installing this bundle auto-installs all three presets (v1 was removed at v2.0.0).",
4
- "version": "2.0.1",
4
+ "version": "2.0.3",
5
5
  "type": "module",
6
+ "engines": {
7
+ "node": "^22.19.0 || >=24.0.0"
8
+ },
6
9
  "main": "installer.js",
7
10
  "exports": {
8
11
  ".": "./installer.js",
@@ -54,6 +57,13 @@
54
57
  },
55
58
  "minVersion": "0.1.2-rc.1",
56
59
  "testedVersion": "0.1.2-rc.1",
57
- "compatNote": "依赖宿主提供的 subagents/agents/tools/commands/fs 服务与 @deepseek-ai/dsh-* 插件行。本项目已充分测试并确认适配 dsh-v0.1.2-rc.1(v2/v3/v4;v1 已于 v2.0.0 移除)。注意:DSH 0.1.2 起 subagents.startContinuable 的 agentOptions/toolFilter 需要宿主 provider 声明对应 capability(spawn/fork 进程内 provider 均支持),安装器启动时会做能力自检并在旧版宿主上告警。"
60
+ "compatNote": "依赖宿主提供的 subagents/agents/tools/commands/fs 服务与 @deepseek-ai/dsh-* 插件行。本项目已充分测试并确认适配 dsh-v0.1.2-rc.1(v2/v3/v4;v1 已于 v2.0.0 移除)。注意:DSH 0.1.2 起 subagents.startContinuable 的 agentOptions/toolFilter 需要宿主 provider 声明对应 capability(spawn/fork 进程内 provider 均支持),安装器启动时会做能力自检并在旧版宿主上告警。",
61
+ "compatibility": {
62
+ "dshReleases": {
63
+ "0.1.2-alpha.4": "compatible",
64
+ "0.1.2-alpha.5": "compatible",
65
+ "0.1.2-rc.1": "compatible"
66
+ }
67
+ }
58
68
  }
59
69
  }