dsh-immune-system 0.9.0 → 0.9.2
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
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# dsh-plugin-immune
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/dsh-immune-system)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://dsh-plugin.org/plugins)
|
|
7
|
+
|
|
3
8
|
**自进化避坑免疫系统** — 让 Agent 踩一次坑,就自己长记性。
|
|
4
9
|
|
|
5
10
|
Agent 踩了坑、修好了,却没人写文档——这次的经验被自动提炼成一条**抗体**。
|
|
@@ -10,7 +15,7 @@ Agent 踩了坑、修好了,却没人写文档——这次的经验被自动
|
|
|
10
15
|
> mistake can repeat.
|
|
11
16
|
|
|
12
17
|
支持两个宿主:**DSH**(DeepSeek Harness,已按真实宿主契约实测)与 **ZCode**(按实测 hook 契约)。
|
|
13
|
-
两者共用同一份 `core
|
|
18
|
+
两者共用同一份 `core/`,npm 包同名发布,一次踩坑、处处免疫。
|
|
14
19
|
|
|
15
20
|
[中文](#中文) · [English](#english)
|
|
16
21
|
|
|
@@ -39,29 +44,24 @@ Agent 踩了坑、修好了,却没人写文档——这次的经验被自动
|
|
|
39
44
|
|
|
40
45
|
#### DSH
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
与 `permissions` 声明,`dist/` 随包提交,安装时无需构建)。
|
|
44
|
-
|
|
45
|
-
**方式一:tarball(不需要 npm 账号,已验证)**
|
|
47
|
+
**npm(现在可用,最简)**:
|
|
46
48
|
|
|
47
49
|
```bash
|
|
48
|
-
|
|
49
|
-
dsh plugin add ./dsh-immune-system-0.3.8.tgz
|
|
50
|
+
dsh plugin --profile <profile> add dsh-immune-system
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
`cordis.patch.yml` 随包到位。
|
|
53
|
+
包发布在 https://www.npmjs.com/package/dsh-immune-system ,`dist/` 预构建随包。
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
**tarball / git**(等价,无需 npm 账号):
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
cd dsh-immune-system && npm
|
|
59
|
-
dsh plugin add dsh-immune-system
|
|
58
|
+
cd dsh-immune-system && npm pack # → dsh-immune-system-0.9.0.tgz
|
|
59
|
+
dsh plugin --profile <profile> add ./dsh-immune-system-0.9.0.tgz
|
|
60
|
+
dsh plugin --profile <profile> add github:meat-daemon-404/dsh-plugin-immune
|
|
60
61
|
```
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
`pnpm-workspace.yaml → allowBuilds` 才能装。除非你就要这个形态,否则用前两种。
|
|
63
|
+
`git:` 安装会在安装时跑 `prepare` 构建,被 pnpm 默认拦截——需要把 pnpm 打印的 key
|
|
64
|
+
加进 profile 的 `pnpm-workspace.yaml → allowBuilds`。除非你就要这个形态,否则用前两种。
|
|
65
65
|
|
|
66
66
|
装完**重启 DSH**(bundle 是启动时装配的,运行中的进程不会自己加载)。
|
|
67
67
|
`<profile>` 就是 `~/.dsh/profiles/` 下你实际在用的那个(桌面端通常是 `desktop`)。
|
|
@@ -99,9 +99,11 @@ node "<zcode.cjs 路径>" plugins install dsh-immune-system@dev-dsh-plugin-immun
|
|
|
99
99
|
| `/dsh-immune-system:immune` | ZCode | 同上(加 `--all`) |
|
|
100
100
|
| `/dsh-immune-system:immune-export` | ZCode | 同上 |
|
|
101
101
|
| `/dsh-immune-system:immune-forget` | ZCode | 同上(`<id>` / `--last` / `--prune` / `--purge`) |
|
|
102
|
+
| `/dsh-immune-system:immune-learn` | ZCode | 手动教一条规则 |
|
|
102
103
|
| `/dsh-immune-system:immune-ui` | ZCode | 启动本地仪表盘,给出地址 |
|
|
103
104
|
| `cli.js ui [--port N]` | 两者 | 同上(前台运行,默认 7788,端口占用自动顺延) |
|
|
104
105
|
| `cli.js learn <trigger> [symptom] <prescription>` | 两者 | 手动教一条规则(借鉴 pro-workflow 的 `/learn-rule`) |
|
|
106
|
+
| `cli.js search <query>` | 两者 | 只读检索——与仪表盘/MCP 同一条不计数通道 |
|
|
105
107
|
| `cli.js export-json <path>` / `import-json <path>` | 两者 | 库快照导出/导入——跨机器同步、git 提交、团队共享 |
|
|
106
108
|
| `cli.js doctor` | 两者 | 安装健康自检:node 版本、FTS5、数据库、marker、MCP 脚本 |
|
|
107
109
|
|
|
@@ -301,19 +303,25 @@ against the real host contract) and **ZCode** (verified against its hooks).
|
|
|
301
303
|
|
|
302
304
|
### Install
|
|
303
305
|
|
|
304
|
-
**
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
New-Item -ItemType Junction `
|
|
310
|
-
-Path "$env:USERPROFILE\.dsh\profiles\<profile>\node_modules\dsh-immune-system" `
|
|
311
|
-
-Target "<repo>\dsh-immune-system"
|
|
312
|
-
# then in that profile's package.json:
|
|
313
|
-
# dependencies["dsh-immune-system"] = "link:<repo>/dsh-immune-system"
|
|
314
|
-
# append "dsh-immune-system" to dsh.profile.bundles
|
|
306
|
+
**npm** — published as [`dsh-immune-system`](https://www.npmjs.com/package/dsh-immune-system),
|
|
307
|
+
prebuilt, no toolchain needed:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
dsh plugin --profile <profile> add dsh-immune-system
|
|
315
311
|
```
|
|
316
312
|
|
|
313
|
+
**tarball / git** (equivalent, no npm account required):
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
cd dsh-immune-system && npm pack
|
|
317
|
+
dsh plugin --profile <profile> add ./dsh-immune-system-0.9.0.tgz
|
|
318
|
+
dsh plugin --profile <profile> add github:meat-daemon-404/dsh-plugin-immune
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`git:` installs build at install time via `prepare`, which pnpm blocks until
|
|
322
|
+
allowlisted — see the Chinese section above for the exact fix. Prefer npm or the
|
|
323
|
+
tarball.
|
|
324
|
+
|
|
317
325
|
**Restart DSH** afterwards — bundles are composed at startup.
|
|
318
326
|
|
|
319
327
|
**ZCode** — this repository *is* a marketplace source:
|
|
@@ -87,7 +87,7 @@ export function importLibrary(store, snapshot) {
|
|
|
87
87
|
// status has no numeric setter; go through setStatus when it changed.
|
|
88
88
|
if (mergedStatus !== existing.status)
|
|
89
89
|
store.setStatus(existing.id, mergedStatus);
|
|
90
|
-
applyTallies(store, existing.id, mergedHits, mergedFails);
|
|
90
|
+
applyTallies(store, existing.id, mergedHits, mergedFails, incoming.created_at);
|
|
91
91
|
}
|
|
92
92
|
report.merged += 1;
|
|
93
93
|
continue;
|
|
@@ -104,7 +104,7 @@ export function importLibrary(store, snapshot) {
|
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
if (incoming.hit_count > 0 || incoming.fail_count > 0) {
|
|
107
|
-
applyTallies(store, id, incoming.hit_count, incoming.fail_count);
|
|
107
|
+
applyTallies(store, id, incoming.hit_count, incoming.fail_count, incoming.created_at);
|
|
108
108
|
}
|
|
109
109
|
if (incoming.status === 'retired')
|
|
110
110
|
store.setStatus(id, 'retired');
|
|
@@ -112,8 +112,14 @@ export function importLibrary(store, snapshot) {
|
|
|
112
112
|
}
|
|
113
113
|
return report;
|
|
114
114
|
}
|
|
115
|
-
/** Set tallies directly;
|
|
116
|
-
function applyTallies(store, id, hitCount, failCount) {
|
|
115
|
+
/** Set tallies (and optionally creation time) directly; import owns merge policy. */
|
|
116
|
+
function applyTallies(store, id, hitCount, failCount, createdAt) {
|
|
117
117
|
const db = store.db;
|
|
118
|
+
if (createdAt && createdAt > 0) {
|
|
119
|
+
// Snapshot time is preserved so zombie aging counts from the original
|
|
120
|
+
// lesson, not from when this machine imported it.
|
|
121
|
+
db.prepare('UPDATE antibodies SET hit_count = ?, fail_count = ?, created_at = ? WHERE id = ?').run(hitCount, failCount, createdAt, id);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
118
124
|
db.prepare('UPDATE antibodies SET hit_count = ?, fail_count = ? WHERE id = ?').run(hitCount, failCount, id);
|
|
119
125
|
}
|
|
@@ -367,19 +367,30 @@ function startPlugin(ctx) {
|
|
|
367
367
|
});
|
|
368
368
|
ctx.commands.register({
|
|
369
369
|
name: 'immune-learn',
|
|
370
|
-
description: 'Teach a rule directly: <trigger> [symptom] <prescription>',
|
|
371
|
-
input: { hint: '<trigger> [symptom] <prescription>' },
|
|
370
|
+
description: 'Teach a rule directly: <trigger> | [symptom] | <prescription> (| separated; without |, trigger = first token and prescription = the rest)',
|
|
371
|
+
input: { hint: '<trigger> | [symptom] | <prescription>' },
|
|
372
372
|
handler: ({ rawInput }) => {
|
|
373
|
-
const
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
const
|
|
379
|
-
|
|
373
|
+
const text = rawInput.trim();
|
|
374
|
+
// Free text cannot be split by whitespace: "用 pnpm 不是 npm" would put
|
|
375
|
+
// "npm" in the prescription slot. Pipe-separated when given; the
|
|
376
|
+
// separator-free form keeps trigger = first token, prescription = the rest.
|
|
377
|
+
const hasPipes = text.includes('|');
|
|
378
|
+
const segments = hasPipes
|
|
379
|
+
? text.split('|').map((part) => part.trim())
|
|
380
|
+
: (() => {
|
|
381
|
+
const tokens = text.split(/\s+/);
|
|
382
|
+
const first = tokens[0] ?? '';
|
|
383
|
+
const rest = tokens.slice(1).join(' ');
|
|
384
|
+
return rest ? [first, rest] : [first];
|
|
385
|
+
})();
|
|
386
|
+
const trigger = segments[0] ?? '';
|
|
387
|
+
const prescription = segments[segments.length - 1] ?? '';
|
|
388
|
+
const symptom = segments.length >= 3 ? segments.slice(1, -1).join(' | ') : '';
|
|
389
|
+
if (!trigger || !prescription || segments.length > 3) {
|
|
380
390
|
return {
|
|
381
391
|
kind: 'error',
|
|
382
|
-
text: `${t.notFound} —
|
|
392
|
+
text: `${t.notFound} — expected: <trigger> | [symptom] | <prescription>\n` +
|
|
393
|
+
`example: pnpm-lock.yaml 这个仓库 | npm 装依赖报错 | 用 pnpm 不要用 npm`,
|
|
383
394
|
};
|
|
384
395
|
}
|
|
385
396
|
const id = store.insert({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-immune-system",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Self-evolving pitfall immunity for coding agents: capture every failed-then-fixed tool episode, distil it into a reusable antibody, and inject the relevant ones before the agent repeats the mistake.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/dsh/src/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dsh": {
|
|
25
25
|
"id": "dsh-immune-system",
|
|
26
26
|
"name": "DSH Immune System",
|
|
27
|
-
"version": "0.9.
|
|
27
|
+
"version": "0.9.2",
|
|
28
28
|
"repo": "meat-daemon-404/dsh-plugin-immune",
|
|
29
29
|
"permissions": "读取工具调用结果与斜杠命令输入;在本机写 SQLite 抗体库(默认落在 $DSH_HOME/storages/dsh-immune-system/ 下按项目隔离);仅在显式配置 IMMUNE_LLM_BASE_URL 与 IMMUNE_LLM_MODEL 时才向该端点发起请求;不读取其它插件的配置,不执行任意命令",
|
|
30
30
|
"bundle": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-immune-system",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Self-evolving pitfall immunity for DeepSeek Harness: capture every failed-then-fixed tool episode, distil it into a reusable antibody stored in SQLite+FTS5, and inject the relevant ones before the agent repeats the mistake.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dsh": {
|
|
25
25
|
"id": "dsh-immune-system",
|
|
26
26
|
"name": "DSH Immune System",
|
|
27
|
-
"version": "0.9.
|
|
27
|
+
"version": "0.9.2",
|
|
28
28
|
"repo": "meat-daemon-404/dsh-plugin-immune",
|
|
29
29
|
"permissions": "读取工具调用结果与斜杠命令输入;在本机写 SQLite 抗体库(默认落在 $DSH_HOME/storages/dsh-immune-system/ 下按项目隔离);仅在显式配置 IMMUNE_LLM_BASE_URL 与 IMMUNE_LLM_MODEL 时才向该端点发起请求;不读取其它插件的配置,不执行任意命令",
|
|
30
30
|
"bundle": {
|