ygc-dsh-sync 1.2.2 → 1.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/README.md +107 -283
- package/client.js +425 -545
- package/index.js +311 -223
- package/lib/api.js +161 -747
- package/lib/core.js +73 -43
- package/lib/skill-learn.js +1115 -0
- package/lib/skill-optimize.js +888 -0
- package/lib/skill-scope.js +288 -0
- package/lib/skill-share-run.js +388 -0
- package/lib/skillshare.js +781 -0
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -123,287 +123,105 @@ curl -X POST http://127.0.0.1:<PORT>/api/local/dsh-sync-backup/attach/repair \
|
|
|
123
123
|
|
|
124
124
|
样式只用 `--dsw-alias-*` 主题令牌,跟随明暗模式。
|
|
125
125
|
|
|
126
|
-
##
|
|
126
|
+
## 技能共享与优化(1.3.0)
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
**母版功能已取消。** 技能不再有「外部母版目录」这一层:来源只有两处——本机特征文件夹里的备份、别人特征文件夹里的备份。老的 `masterRoot` 配置会在读取 state 时被删掉,残留的老路由(`/skills/pull`、`/skills/push`、`/skills/mode`、`/skills/changelog`、`/skills/list`)一并下线。
|
|
129
129
|
|
|
130
|
-
###
|
|
130
|
+
### 目录约定
|
|
131
131
|
|
|
132
|
-
| 情况 | 处理 |
|
|
133
|
-
|---|---|
|
|
134
|
-
| 母版有、本地无 | 拉取到本地 |
|
|
135
|
-
| 两侧都有,**母版版本更高** | 拉取覆盖本地(旧版备份到 `.pre-pull-<时间戳>/`) |
|
|
136
|
-
| 两侧都有,**本地版本更高**或内容不同 | **只报告**,你在面板上勾选并点「推送到母版」才执行 |
|
|
137
|
-
| 本地有、母版没有 | **跳过**,不放进母版,本地也原样保留 |
|
|
138
|
-
|
|
139
|
-
母版里删掉的技能,本地**什么都不做**——不删、不搬,就是留着不用。
|
|
140
|
-
|
|
141
|
-
### 记忆插件的技能优化:同步时自动处理
|
|
142
|
-
|
|
143
|
-
记忆插件(`dsh-mnemon`)会自己审查会话、写技能草稿,但草稿写完停在
|
|
144
|
-
`ledger.json` 的 `drafts[]` 里等人在面板上点「采纳」。放着不管就越积越多
|
|
145
|
-
(本机曾积 12 份),而技能同步只看磁盘上的 `SKILL.md`——草稿还没落地,
|
|
146
|
-
一条都同步不出去。
|
|
147
|
-
|
|
148
|
-
所以**每轮技能同步开头先做一次预处理**,把两端接起来:
|
|
149
|
-
|
|
150
|
-
1. 读 `~/.mnemon/skills/ledger.json`,取 `status="ready"` 的草稿(同技能多份取最新)
|
|
151
|
-
2. 校验:技能名能当目录名、frontmatter 的 `name` 对得上、`update` 草稿的
|
|
152
|
-
`baseHash` 仍等于当前 `SKILL.md` 的 sha256
|
|
153
|
-
3. 落地到本机 `~/.agents/skills/<技能名>/SKILL.md`,旧版备份到
|
|
154
|
-
`.pre-mnemon-<时间戳>/`
|
|
155
|
-
4. 立刻推回母版,旧版备份到 `_backup/<技能名>.<时间戳>/`,并在母版
|
|
156
|
-
`_技能修改记录.md` 写一条,触发方式记为「记忆插件优化」
|
|
157
|
-
5. 然后照常比对/拉取/推送——这一轮看到的已经是落地后的内容
|
|
158
|
-
|
|
159
|
-
为什么单独推一次:草稿是本插件刚落的,谱系里还没记过这份内容,按判据会
|
|
160
|
-
落进「待你决定」。这一步是**明知新**,不猜。
|
|
161
|
-
|
|
162
|
-
四条边界:
|
|
163
|
-
|
|
164
|
-
| 情况 | 行为 |
|
|
165
|
-
|---|---|
|
|
166
|
-
| 本机 `SKILL.md` 已经是这份草稿的内容 | 跳过(`already-applied`),重复跑幂等 |
|
|
167
|
-
| `update` 草稿的 `baseHash` 与当前文件不符 | 跳过(`stale-base`),期间有人改过,交给待裁决 |
|
|
168
|
-
| `create` 草稿撞上已有同名技能 / 技能属性为「母版有·本机不拉取」 | 跳过 |
|
|
169
|
-
| `targetRoot` 是 `project-*` | 跳过(`project-scope`),项目技能不进母版 |
|
|
170
|
-
|
|
171
|
-
#### 落地之后要结案,否则面板永远显示「待审」
|
|
172
|
-
|
|
173
|
-
只把文件写进去、账本不动,面板上那条建议就永远停在 `review`、草稿永远停在
|
|
174
|
-
`ready`——看起来一直有活没干。所以落地成功后会顺手把账本里对应的
|
|
175
|
-
`draft` 与 `suggestion` 标成 `adopted`。
|
|
176
|
-
|
|
177
|
-
写账本是安全的,因为记忆插件每次操作都从磁盘重读 `ledger.json`
|
|
178
|
-
(`SkillsStore.ledger()` 里就是 `readJson`),没有内存缓存。只要格式对得上:
|
|
179
|
-
|
|
180
|
-
| 项 | 规则 |
|
|
181
|
-
|---|---|
|
|
182
|
-
| `generation` | 每次写入 +1(插件用它算 revision,不 +1 会被当成没变) |
|
|
183
|
-
| `reviews` | 截到最新的 200 条 |
|
|
184
|
-
| `drafts` | 非 `ready` 的只留 60 份(`ready` 全留,等处理) |
|
|
185
|
-
| 落盘 | 先写 `<file>.<pid>-<uuid>.tmp` 再 rename,`mode 600` |
|
|
186
|
-
| 并发 | 写之前比对 size + mtime,期间被改过就整体放弃,下一轮再来 |
|
|
187
|
-
|
|
188
|
-
结案判据仍然只用内容哈希:**磁盘上的 `SKILL.md` 必须还等于草稿内容**才结案。
|
|
189
|
-
刚落完就被人改回去、或者本机根与草稿目标根对不上,一律不结案,留在 `ready`
|
|
190
|
-
等下一轮。
|
|
191
|
-
|
|
192
|
-
面板上「记忆插件优化自动处理」可关(`skills.mnemonAuto`,默认开);
|
|
193
|
-
关键设置:`POST /skills/config` 传 `{"mnemonAuto": false}`。
|
|
194
|
-
|
|
195
|
-
#### 已经积压的历史账本
|
|
196
|
-
|
|
197
|
-
外部流程(本插件早期版本、手工采纳)落地过的草稿,账本里仍停在 `review`。
|
|
198
|
-
用 `C:\DSH-Work\mnemon-reconcile\reconcile.mjs` 一次性对账:
|
|
199
|
-
|
|
200
|
-
```powershell
|
|
201
|
-
node reconcile.mjs # 预演,只报告
|
|
202
|
-
node reconcile.mjs --apply # 真写(先自动备份 ledger.json)
|
|
203
132
|
```
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|---|---|---|---|
|
|
220
|
-
| 1 | **内容修改时间** | 谱系文件记录的「两侧各自的内容何时变成现在这样」 | `content-time` |
|
|
221
|
-
| 2 | **只一侧变过** | 上次比对时记的内容,现在只有一侧还对得上 → 另一侧是改的 | `content-time` |
|
|
222
|
-
| 3 | **记忆插件演化记录** | `~/.mnemon/skills/ledger.json` 里 `reason=evolution` 的哈希 + 时间 | `mnemon` |
|
|
223
|
-
| 4 | **历史快照时间** | 母版 `_backup/`、本机 `.pre-pull-*`、记忆插件 `versions/`、母版修改记录 | `content-time` |
|
|
224
|
-
| 5 | **谱系基线** | 上次两侧一致时的内容树;只有一侧偏离 | `lineage` |
|
|
225
|
-
| 6 | **包含关系** | 一侧完全包含另一侧(纯新增,没改写原意) | `superset` |
|
|
226
|
-
|
|
227
|
-
六段都拿不到证据 → 归「待你决定」,不自动覆盖任何一方。
|
|
228
|
-
|
|
229
|
-
#### 「内容修改时间」到底是什么
|
|
230
|
-
|
|
231
|
-
不是 `stat` 出来的 mtime,是同步插件**亲眼看到内容变成现在这样**的那一刻:
|
|
232
|
-
|
|
233
|
-
- 每次比对都会把两侧当前的内容哈希记进 `<母版>/.skill-lineage.json`
|
|
234
|
-
- **同一个哈希再次观测,时间保持不动**——内容没变就不算改动,哪怕文件被 NAS
|
|
235
|
-
搬过、mtime 全变了
|
|
236
|
-
- 内容真变了才刷新时间
|
|
237
|
-
|
|
238
|
-
所以「谁的内容时间更晚,谁就是新版」这句话,在同步场景下才成立;
|
|
239
|
-
换成 mtime 就完全不成立。
|
|
240
|
-
|
|
241
|
-
#### 记忆插件的修改留下了什么
|
|
242
|
-
|
|
243
|
-
三样东西,全部只读,记忆插件一行代码都不用改:
|
|
244
|
-
|
|
245
|
-
| 痕迹 | 位置 | 能证明什么 |
|
|
246
|
-
|---|---|---|
|
|
247
|
-
| **演化版本记录** | `~/.mnemon/skills/ledger.json` → `versions[]` | 采纳草稿时写一条 `reason="evolution"`,`hash` 正是新 SKILL.md 的 sha256 —— **「这次是记忆插件改的」最硬的证据** |
|
|
248
|
-
| **历史全文快照** | `~/.mnemon/skills/versions/<sha256(skillKey) 前16位>/<versionId>.md` | 当时那份全文,可做三方对比 |
|
|
249
|
-
| **演化建议/草稿** | `ledger.json` → `suggestions[]` / `drafts[]` | 还没采纳的改动在 `drafts[].content`,已采纳的进 `versions[]` |
|
|
250
|
-
|
|
251
|
-
它的目录名就是 `sha256(skillKey).hex.slice(0,16)`,`skillKey` 形如
|
|
252
|
-
`user-dsh:kb-zhishiku` —— 不用猜,照算就能对上号。
|
|
253
|
-
|
|
254
|
-
**注意**:记忆插件平常的技能注册表不在账本里(那是宿主扫磁盘得出的),账本只记
|
|
255
|
-
「安装」和「演化」。所以账本里查不到某个技能,**不能**推断是谁改的——
|
|
256
|
-
这种情况下判据继续往后走,不硬判。
|
|
257
|
-
|
|
258
|
-
```
|
|
259
|
-
$ node tools/skill-lineage.mjs --status
|
|
260
|
-
母版:D:\Ai工作空间\技能库
|
|
261
|
-
本机:C:\Users\DSH\.agents\skills
|
|
262
|
-
谱系:43 条观测
|
|
263
|
-
账本:2 个技能有记忆插件记录
|
|
264
|
-
|
|
265
|
-
一致 43 · 待你决定 4
|
|
266
|
-
|
|
267
|
-
本机新 demo [content-time] 上次比对后本机内容变了(11-01 21:51 之后)
|
|
268
|
-
母版新 demo2 [content-time] 母版这份内容更晚(11-01 22:03 vs 10-30 10:18)
|
|
269
|
-
本机新 demo3 [superset] 本机内容完全包含母版内容(只增不减)
|
|
270
|
-
待你决定 x [-] 两侧内容都改写过、没有快照或演化记录可比,需要你决定(保留哪边)
|
|
133
|
+
插件库\
|
|
134
|
+
└─ <本机标识>\
|
|
135
|
+
├─ PLUGINS.json 插件清单(1.0.0 起)
|
|
136
|
+
├─ OTHERS-PLUGINS.json/.md 他人插件汇总
|
|
137
|
+
└─ skills\ ← 技能共享层
|
|
138
|
+
├─ SKILLS.json 本机技能索引(机器读)
|
|
139
|
+
├─ SKILLS.md 同一份的人读版本
|
|
140
|
+
├─ SKILL-ORIGIN.json 来源台账:这个技能最初从哪台机器学来的
|
|
141
|
+
├─ SKILL-LEARNINGS.json 学习 / 优化台账(机器读)
|
|
142
|
+
├─ SKILL-LEARNINGS.md 同一份的人读版本(**别的机器也读这份参考**)
|
|
143
|
+
├─ learn-drafts\<技能名>\ 待批草稿(SKILL.md + DRAFT-META.json)
|
|
144
|
+
└─ <技能名>\
|
|
145
|
+
├─ SKILL.md 技能正文
|
|
146
|
+
├─ scripts\ references\ … 整棵技能目录一起备份
|
|
147
|
+
└─ SKILL-CARD.json 名片:说明 / 来源 / 更新时间 / 内容指纹
|
|
271
148
|
```
|
|
272
149
|
|
|
273
|
-
|
|
150
|
+
一人一格,**只写自己那一格**。别人的特征文件夹全程只读:不写、不改、不删、不移动。
|
|
274
151
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
| 判定 | 动作 |
|
|
278
|
-
|---|---|
|
|
279
|
-
| 母版更新 | **自动拉取**覆盖本机(旧版备份到 `.pre-pull-<时间戳>/`) |
|
|
280
|
-
| 本机更新(同步属性) | **自动推送**覆盖母版(旧版备份到 `_backup/<技能>.<时间戳>/`,并写修改记录) |
|
|
281
|
-
| 判不出来 | **什么都不动**,列在面板上等你裁决,附差异摘要 |
|
|
152
|
+
### 归属:哪些技能归本插件管
|
|
282
153
|
|
|
283
|
-
|
|
284
|
-
面板上的「比对」按钮走自动模式,定时器也是。
|
|
154
|
+
来自技能市场的第三方技能**不管理、不同步、不优化**(例如记忆插件 `dsh-mnemon` 自带的技能市场)。判据按强度排序(`lib/skill-scope.js`):
|
|
285
155
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
```
|
|
289
|
-
母版独有 3 行、本机独有 12 行(14770 vs 14735 字节)
|
|
290
|
-
- 旧的那一行
|
|
291
|
-
+ 新的那一行
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### 为什么不能靠 version 硬撑
|
|
295
|
-
|
|
296
|
-
版本号只能表达「谁手工标得更正式」,表达不了「谁的内容是后来的」。
|
|
297
|
-
存量 48 个技能里:
|
|
298
|
-
|
|
299
|
-
- `kb-zhishiku` 本机 2.0.0 / 母版 1.0.0 —— 版本号确实能分
|
|
300
|
-
- `skill-creator` 两侧都没有 version —— 版本号完全失效
|
|
301
|
-
- `expert-copywriting` 两侧都是 1.0.0 但内容不同 —— 版本号给出错误结论
|
|
302
|
-
|
|
303
|
-
现在这三种都由内容时间处理;真分不出来的才落到「待你决定」。
|
|
304
|
-
|
|
305
|
-
### 给技能补 version
|
|
306
|
-
|
|
307
|
-
`tools/add-version.mjs` 批量补 `version: 1.0.0`:
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
node tools/add-version.mjs --dry # 只看会改哪些
|
|
311
|
-
node tools/add-version.mjs # 实际写入
|
|
312
|
-
node tools/add-version.mjs --dir <路径> # 指定技能根
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
行为:
|
|
316
|
-
|
|
317
|
-
- 已有 `version` 的**跳过**,不覆盖
|
|
318
|
-
- 无 front matter 的**跳过**,不强加
|
|
319
|
-
- 保留原编码(UTF-8 无 BOM / 有 BOM)
|
|
320
|
-
- 保留换行风格(CRLF / LF)
|
|
321
|
-
- 改写前备份为 `SKILL.md.bak-<时间戳>`
|
|
322
|
-
- 幂等:重复运行不产生第二份备份
|
|
323
|
-
|
|
324
|
-
**2026-10-29 已对 42 个技能执行**,全部补为 `1.0.0`,42 份备份在各自目录下。`wx-send-image` 是空目录(无 SKILL.md),未处理。
|
|
325
|
-
|
|
326
|
-
**2026-11-01 起 `version` 不再参与新旧判定**——它只是个给人看的标记。
|
|
327
|
-
判定改按内容修改时间,见上文「新旧怎么判」。补 version 这一步留着,
|
|
328
|
-
只是因为部分技能商店/清单用得上。
|
|
329
|
-
|
|
330
|
-
### 单机属性(技能列表)
|
|
331
|
-
|
|
332
|
-
每个技能有一个**只存本机**的属性,三种值:
|
|
333
|
-
|
|
334
|
-
| 属性 | 含义 | 改为该属性时做的事 |
|
|
156
|
+
| 顺序 | 判据 | 结论 |
|
|
335
157
|
|---|---|---|
|
|
336
|
-
|
|
|
337
|
-
|
|
|
338
|
-
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
属性只写本机 state(`~/.dsh/storages/sync-backup.json` 的 `skills.modes`),不随母版走,所以每台机器可以各设各的。
|
|
158
|
+
| 1 | `state.skills.share.scope[技能名]` 人工指定 | 说了算 |
|
|
159
|
+
| 2 | `~/.mnemon/skills/ledger.json` 的 `installs[]` 里有它 | 第三方(最硬:市场自己写的记录) |
|
|
160
|
+
| 3 | 官方精选目录同名 **且** 目录带 `LICENSE*` | 第三方(台账被清掉时兜底) |
|
|
161
|
+
| 4 | 技能库 / 母版同名 | 自己的 |
|
|
162
|
+
| 5 | 其余 | 自己的(母版取消后这就是正常路径,不再标 weak) |
|
|
343
163
|
|
|
344
|
-
|
|
164
|
+
本机实测:140 个技能里 18 到 20 个判为第三方(`baoyu-*`、`canvas-design`、`mcp-builder` 等),其余 120 个归自己。面板上能把某个技能手工改成「自己编写」或「第三方」,改完立刻生效。
|
|
345
165
|
|
|
346
|
-
|
|
166
|
+
### 一轮共享做什么(开机 + 定时 + 面板「立即共享」)
|
|
347
167
|
|
|
168
|
+
1. **备份本机**:把归自己的技能整棵目录拷进 `插件库/<本机>/skills/<技能名>/`,同时写 `SKILL-CARD.json`(说明、来源、更新时间、`contentHash`、`treeHash`)与 `SKILLS.json`。
|
|
169
|
+
- 幂等:整棵目录指纹没变的技能不重拷。
|
|
170
|
+
- 本机已经没有的技能:移进 `skills/.trash-<时间戳>/`,不直删。
|
|
171
|
+
2. **扫别人**:读各台机器的 `skills/`(只读)。别人的格子里有、本机没有的 → 拉到本机(拉到后删掉名片,名片是共享层的东西,不污染本机技能目录)。
|
|
172
|
+
3. **同名不同内容**:**不覆盖**。进学习评估(`lib/skill-learn.js`),判据先穷尽机械手段,判不出来才叫模型:
|
|
173
|
+
- 一侧是另一侧章节的严格超集 → 直接给结论(`keep` / `adopt`),不花模型调用。
|
|
174
|
+
- 双方各有对方没有的章节 → 调模型评估,产出合并稿或修订稿,**落成待批草稿**。
|
|
175
|
+
- 模型不可用 → 只记录差异与理由,标 `manual`。
|
|
176
|
+
4. **写台账**:结论写进 `SKILL-LEARNINGS.{json,md}`。`SKILL-LEARNINGS.md` 里逐条写清「谁、因为什么、怎么改的、草稿在哪」,**别的机器读这份文件就能直接参考结论**,不必重跑一次评估。
|
|
348
177
|
|
|
178
|
+
### 优化类型(差异与体检共用同一套动作)
|
|
349
179
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
|
361
|
-
|
|
362
|
-
| 时间 | 本机时间,精确到秒 |
|
|
363
|
-
| 操作者 | `<本机名称> (<本机标识>)` |
|
|
364
|
-
| 操作 | `覆盖` / `新增` |
|
|
365
|
-
| 技能 | 技能名 |
|
|
366
|
-
| 触发方式 | `用户授权` / `自动` |
|
|
367
|
-
| 说明 | 覆盖时记旧版备份路径,新增时记「母版此前无此技能」 |
|
|
368
|
-
|
|
369
|
-
例:
|
|
370
|
-
|
|
371
|
-
```
|
|
372
|
-
| 2026-10-29 16:20:31 | 李超台式 (DSH-7e6b1bb7e052) | 覆盖 | expert-code-review | 用户授权 | 旧版备份于 _backup/expert-code-review.20261029-162031 |
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
只有**实际写入母版**才记录。拉取(母版 → 本地)不碰母版,不产生记录。
|
|
376
|
-
|
|
377
|
-
竖线和换行会转义,不会破坏表格。母版只读时记录失败不阻断推送,只在响应里报错。
|
|
180
|
+
| 动作 | 含义 | 判据 |
|
|
181
|
+
|---|---|---|
|
|
182
|
+
| `merge` | 合并精炼 | 两侧各有一半,章节都能保住 |
|
|
183
|
+
| `condense` | 精简冗余 | 命令行与数值没增加、正文显著重复 |
|
|
184
|
+
| `enrich` | 补全工况 | 一侧有「什么情况下用 / 不用」,一侧没有 |
|
|
185
|
+
| `pitfalls` | 增加踩坑经验 | 两侧 Pitfalls 条目不同且都能保住 |
|
|
186
|
+
| `revise` | 修订错误技能 | 含错误命令 / 过时 API / 引用不存在的资源,**能定位就改** |
|
|
187
|
+
| `deprecate` | 停用(作废) | 改也没意义;正文换成停用声明,人批了才替换本机副本 |
|
|
188
|
+
| `fixpath` | 修死引用 | 正文引用了 `scripts/xxx` 却不存在 |
|
|
189
|
+
| `adopt` | 采用对方版本 | 对方章节是本机超集 |
|
|
190
|
+
| `keep` | 保留本机 | 本机更完整,或对方是错误做法 |
|
|
191
|
+
| `manual` | 等人工 | 模型不可用 / 回复不可解析 / 稿子没过机械审核 |
|
|
378
192
|
|
|
379
|
-
|
|
193
|
+
### 本机技能优化
|
|
380
194
|
|
|
381
|
-
|
|
195
|
+
面板「优化本机技能」按钮 → 后台跑一轮(`lib/skill-optimize.js`),顺序固定:
|
|
382
196
|
|
|
383
|
-
|
|
197
|
+
1. **体检**(不花钱):缺 description / 缺 Pitfalls / 缺 Verification / 围栏不成对 / 引用了不存在的文件 / 过短过长 / 有资源目录却零加载指针 / 长破折号。每条都带「为什么错 + 该怎么做」。
|
|
198
|
+
2. **冗余配对**(不花钱):描述词 Jaccard 相似度 ≥ 0.42 的两条技能记为合并候选。
|
|
199
|
+
3. **排优先级**:按问题严重度加权,合并候选额外加分。
|
|
200
|
+
4. **出草稿**:取前 N 条(默认 3,上限 12)调模型,产出改完的 SKILL.md,过机械审核后落 `learn-drafts/`。
|
|
384
201
|
|
|
385
|
-
|
|
202
|
+
机械审核的硬线(`auditOptimized`):
|
|
386
203
|
|
|
387
|
-
-
|
|
388
|
-
-
|
|
389
|
-
-
|
|
390
|
-
-
|
|
391
|
-
-
|
|
204
|
+
- frontmatter 的 `name` 必须与技能名逐字一致;description 60 到 400 字。
|
|
205
|
+
- `## Pitfalls` 与 `## Verification` 两节必须在。
|
|
206
|
+
- **允许变短**(精炼是合法动作),但命令行数量不许掉到原文 70% 以下,具体数值同理。
|
|
207
|
+
- 原有章节标题不许丢超过 40%,原有踩坑条目不许丢超过 30%。
|
|
208
|
+
- 不许比原文长出 40% 以上,不许新增长破折号,围栏必须成对。
|
|
392
209
|
|
|
393
|
-
|
|
210
|
+
草稿只是草稿:**本机技能在「批准」之前一个字都不动**。批准时旧版先备份到 `~/.agents/skills/.pre-learn-<时间戳>/<技能名>/`,然后再写;如果出草稿之后本机那份被人改过(`mineHash` 对不上),默认拒绝覆盖并说明原因。
|
|
394
211
|
|
|
395
|
-
|
|
212
|
+
### 只读与写边界
|
|
396
213
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
推送时母版旧版会备份到 `<母版>/_backup/<技能名>.<时间戳>/`。
|
|
214
|
+
| 路径 | 谁写 | 怎么保证 |
|
|
215
|
+
|---|---|---|
|
|
216
|
+
| `插件库/<本机>/skills/**` | 本机 | 每次写前过 `assertOwnFeaturePath` |
|
|
217
|
+
| `插件库/<别人>/skills/**` | **没人写** | 全程 `readdirSync` / `readFileSync`,测试里断言对方目录文件集合与内容哈希不变 |
|
|
218
|
+
| `~/.agents/skills/**` | 本机 | 只在「批准草稿」时写,写前留备份 |
|
|
405
219
|
|
|
220
|
+
### 已知取舍
|
|
406
221
|
|
|
222
|
+
- 拉取只拉「本机没有」的;同名不同内容一律不覆盖,因为这里没有可信的新旧判据(mtime 会被 NAS 改写,见上一节)。
|
|
223
|
+
- 优化默认出草稿而不是直接改:合并不可逆,模型也会犯错。需要全自动就把 `share.autoApply` 打开,语义是「过了机械审核的草稿自动批准」。
|
|
224
|
+
- 市场第三方的判定依赖 `ledger.json`。台账被清掉后靠「官方目录同名 + 有 LICENSE 文件」兜底;两者都不成立时会按「自己编写」处理,面板上可以人工改回来。
|
|
407
225
|
|
|
408
226
|
## 接口
|
|
409
227
|
|
|
@@ -420,42 +238,48 @@ Get-Process | Where-Object { $_.CommandLine -like '*Sync-Skills*' }
|
|
|
420
238
|
| POST | `/patrol/register` | 注册选中的目录 + 补齐特征文件夹 |
|
|
421
239
|
| POST | `/patrol/repair` | 补全缺特征文件夹的工作区 |
|
|
422
240
|
| POST | `/patrol/config` | 定时巡检开关与间隔分钟数 |
|
|
423
|
-
| POST | `/skills/scan` |
|
|
424
|
-
| POST | `/skills/
|
|
425
|
-
| POST | `/skills/
|
|
426
|
-
| POST | `/skills/
|
|
427
|
-
| POST | `/skills/
|
|
428
|
-
| POST | `/skills/list` |
|
|
429
|
-
| POST | `/skills/
|
|
241
|
+
| POST | `/skills/scan` | 技能现状,只读(走 runShare 的 dryRun) |
|
|
242
|
+
| POST | `/skills/share` | 立即共享一轮:备份 → 拉缺失 → 差异进学习 |
|
|
243
|
+
| POST | `/skills/inspect` | 整库机械体检,不调模型、不写盘 |
|
|
244
|
+
| POST | `/skills/optimize/run` | 跑一轮本机优化(后台,`maxPerRound`、`includeMerge`) |
|
|
245
|
+
| POST | `/skills/optimize/state` | 优化进度与上一轮报告 |
|
|
246
|
+
| POST | `/skills/learning/list` | 待批草稿列表 |
|
|
247
|
+
| POST | `/skills/learning/draft` | 读某份草稿正文(`name`) |
|
|
248
|
+
| POST | `/skills/learning/approve` | 批准落地(`name`、`force`) |
|
|
249
|
+
| POST | `/skills/learning/reject` | 驳回(`name`、`reason`) |
|
|
250
|
+
| POST | `/skills/scope` | 归属判定摘要(自研 / 第三方 / weak) |
|
|
251
|
+
| POST | `/skills/scope/set` | 人工改归属(`name`、`scope`) |
|
|
252
|
+
| POST | `/skills/config` | 开关、间隔、learn / autoApply / 每轮条数 |
|
|
253
|
+
|
|
254
|
+
1.3.0 下线:`/skills/pull`、`/skills/push`、`/skills/mode`、`/skills/changelog`、`/skills/list`(母版功能的入口)。
|
|
430
255
|
|
|
431
256
|
## 测试
|
|
432
257
|
|
|
258
|
+
旧套件里与母版相关的部分(`skills.test.mjs`、`skills-api.test.mjs`、`mode*.test.mjs`、`changelog*.test.mjs`)随 1.3.0 一并作废:那些端点已经下线,留着只会一直红。
|
|
259
|
+
|
|
260
|
+
1.3.0 的验收走三个脚本,全部落在临时目录,不碰真实技能库与真实 state:
|
|
261
|
+
|
|
433
262
|
```bash
|
|
434
|
-
|
|
435
|
-
node test/
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
node test/
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
node test/
|
|
442
|
-
node test/persist.test.mjs # 跨进程持久性:生成后永不改变
|
|
443
|
-
node test/schedule.test.mjs # 排程:开机首跑 + 间隔计时 + 改配置立即生效
|
|
444
|
-
node test/host-load.test.mjs # Host 半加载与清理
|
|
445
|
-
node test/skills.test.mjs # 技能:版本比较、树哈希、比对规则、拉取推送
|
|
446
|
-
node test/skills-api.test.mjs # 技能四个端点
|
|
447
|
-
node test/changelog.test.mjs # 修改记录:自动建、追加、转义、只读容错
|
|
448
|
-
node test/changelog-api.test.mjs # 推送时写入记录、新增/覆盖区分
|
|
449
|
-
node test/addversion.test.mjs # 补 version:编码/换行保留、幂等、跳过规则
|
|
450
|
-
node test/client.test.mjs # 客户端契约:注入、注册配对、locale、组件可调用
|
|
451
|
-
node test/mode.test.mjs # 单机属性:三种切换的实质动作与审计
|
|
452
|
-
node test/mode-api.test.mjs # 列表与属性切换端点
|
|
263
|
+
# 端到端:归属判定 → 备份 → 拉缺失 → 同名不覆盖 → 体检 → 优化出草稿 → 批准落地 → 幂等
|
|
264
|
+
node test/01-skill-share.e2e.mjs # 36 项断言
|
|
265
|
+
|
|
266
|
+
# 冒烟:伪造 ctx 加载 index.js,走真实 HTTP 路由(证明老路由下线、新路由可控)
|
|
267
|
+
node test/02-routes.smoke.mjs # 23 项断言
|
|
268
|
+
|
|
269
|
+
# 解析:模型回复切分(内层代码块不被当成结束围栏)
|
|
270
|
+
node test/03-parse.mjs # 见下
|
|
453
271
|
```
|
|
454
272
|
|
|
455
|
-
|
|
273
|
+
三条必须成立的硬断言(回归红线):
|
|
274
|
+
|
|
275
|
+
1. **别人的特征文件夹一个字节都不变**:跑完共享后比对对方 `skills/` 的文件集合与 `SKILL.md` 内容哈希。
|
|
276
|
+
2. **市场第三方不进备份、不进体检、不进优化**:`market-skill` 不出现在 `插件库/<本机>/skills/` 里,也不出现在体检结果里。
|
|
277
|
+
3. **批准前本机技能不动**:出草稿之后、批准之前,本机 `SKILL.md` 的 `version` 仍是原值。
|
|
456
278
|
|
|
457
279
|
## 已知限制
|
|
458
280
|
|
|
459
281
|
- 拉取进来的会话要重启 DSH 才可见(无热重扫接口)。
|
|
460
282
|
- 不接管任何既有同步脚本,只管 `.dsh-sync/sessions/<标识>/` 这一块。
|
|
461
283
|
- 冲突留档放在本机标识目录内的 `.conflicts/`,不写工作区其他位置。
|
|
284
|
+
- 技能共享的「更新时间」取 `SKILL.md` 的落盘时间(展示用);**判同一律看内容指纹**,不看时间——NAS 搬运会刷 mtime。
|
|
285
|
+
- 别人那台如果还跑 1.2.x(没有 `skills/` 层),本机只会在 `errors` 里报一句「还没有技能共享目录」,不影响别的机器。
|