@zaofan/dsh-qqbot 1.8.6 → 1.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.
Files changed (76) hide show
  1. package/README.md +114 -27
  2. package/README_EN.md +122 -8
  3. package/dist/features/ext-capabilities.d.ts +85 -0
  4. package/dist/features/ext-capabilities.d.ts.map +1 -1
  5. package/dist/features/ext-capabilities.js +4 -0
  6. package/dist/features/ext-capabilities.js.map +1 -1
  7. package/dist/features/ext-hooks.d.ts +84 -0
  8. package/dist/features/ext-hooks.d.ts.map +1 -0
  9. package/dist/features/ext-hooks.js +299 -0
  10. package/dist/features/ext-hooks.js.map +1 -0
  11. package/dist/features/ext-inbound-context.d.ts +202 -0
  12. package/dist/features/ext-inbound-context.d.ts.map +1 -0
  13. package/dist/features/ext-inbound-context.js +724 -0
  14. package/dist/features/ext-inbound-context.js.map +1 -0
  15. package/dist/features/ext-inbound-state.d.ts +153 -0
  16. package/dist/features/ext-inbound-state.d.ts.map +1 -0
  17. package/dist/features/ext-inbound-state.js +419 -0
  18. package/dist/features/ext-inbound-state.js.map +1 -0
  19. package/dist/features/ext-inbound.d.ts +117 -0
  20. package/dist/features/ext-inbound.d.ts.map +1 -0
  21. package/dist/features/ext-inbound.js +518 -0
  22. package/dist/features/ext-inbound.js.map +1 -0
  23. package/dist/features/ext-reload.d.ts +22 -0
  24. package/dist/features/ext-reload.d.ts.map +1 -1
  25. package/dist/features/ext-reload.js +32 -0
  26. package/dist/features/ext-reload.js.map +1 -1
  27. package/dist/features/extension-store.d.ts +13 -0
  28. package/dist/features/extension-store.d.ts.map +1 -1
  29. package/dist/features/extension-store.js +76 -18
  30. package/dist/features/extension-store.js.map +1 -1
  31. package/dist/gateway/bootstrap.d.ts +14 -1
  32. package/dist/gateway/bootstrap.d.ts.map +1 -1
  33. package/dist/gateway/bootstrap.js +61 -2
  34. package/dist/gateway/bootstrap.js.map +1 -1
  35. package/dist/gateway/debounce.d.ts +43 -1
  36. package/dist/gateway/debounce.d.ts.map +1 -1
  37. package/dist/gateway/debounce.js +71 -35
  38. package/dist/gateway/debounce.js.map +1 -1
  39. package/dist/gateway/middleware-setup.d.ts.map +1 -1
  40. package/dist/gateway/middleware-setup.js +88 -1
  41. package/dist/gateway/middleware-setup.js.map +1 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +49 -9
  44. package/dist/index.js.map +1 -1
  45. package/dist/session/session-manager.d.ts.map +1 -1
  46. package/dist/session/session-manager.js +7 -3
  47. package/dist/session/session-manager.js.map +1 -1
  48. package/dist/session/surface-guard.d.ts +1 -1
  49. package/dist/shared/index.d.ts +1 -1
  50. package/dist/shared/index.d.ts.map +1 -1
  51. package/dist/shared/index.js +1 -1
  52. package/dist/shared/index.js.map +1 -1
  53. package/dist/shared/utils.d.ts +40 -0
  54. package/dist/shared/utils.d.ts.map +1 -1
  55. package/dist/shared/utils.js +59 -2
  56. package/dist/shared/utils.js.map +1 -1
  57. package/dist/transport/inbound.d.ts.map +1 -1
  58. package/dist/transport/inbound.js +23 -3
  59. package/dist/transport/inbound.js.map +1 -1
  60. package/docs/USER-GUIDE.md +93 -36
  61. package/docs/botplay-contract.md +2 -0
  62. package/examples/ext-hooks/README.md +95 -0
  63. package/examples/ext-hooks/hello-hook.mjs +54 -0
  64. package/examples/ext-hooks/session-watch-hook.mjs +119 -0
  65. package/examples/ext-inbound/README.md +230 -0
  66. package/examples/ext-inbound/class-advisor.mjs +306 -0
  67. package/examples/ext-inbound/no-wake-on-child-quote.mjs +192 -0
  68. package/examples/ext-tools/README.md +22 -0
  69. package/examples/ext-tools/lib/preset_resolve.mjs +85 -0
  70. package/examples/ext-tools/lib/session_watch_lib.mjs +350 -0
  71. package/examples/ext-tools/session_create.mjs +201 -0
  72. package/examples/ext-tools/session_send.mjs +141 -0
  73. package/examples/ext-tools/session_watch.mjs +93 -0
  74. package/examples/ext-tools/sessions_list.mjs +180 -0
  75. package/package.json +141 -141
  76. package/settings-host.js +22 -5
package/package.json CHANGED
@@ -1,141 +1,141 @@
1
- {
2
- "name": "@zaofan/dsh-qqbot",
3
- "version": "1.8.6",
4
- "description": "QQ Bot IM channel plugin for deepseek-harness (dsh)",
5
- "type": "module",
6
- "main": "./entry.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./entry.js"
12
- },
13
- "./channel-tools": {
14
- "types": "./dist/channel-tools.d.ts",
15
- "import": "./dist/channel-tools.js"
16
- },
17
- "./sticker-store": {
18
- "types": "./dist/features/sticker-store.d.ts",
19
- "import": "./dist/features/sticker-store.js"
20
- },
21
- "./schedule-store": {
22
- "types": "./dist/features/schedule-store.d.ts",
23
- "import": "./dist/features/schedule-store.js"
24
- },
25
- "./client": "./client/qqbot-settings.js"
26
- },
27
- "scripts": {
28
- "build": "tsc",
29
- "dev": "tsc --watch",
30
- "prepublishOnly": "npm run build && node scripts/check-package.mjs",
31
- "check:package": "node scripts/check-package.mjs",
32
- "lint": "eslint src/",
33
- "test": "vitest run",
34
- "clean": "rm -rf dist",
35
- "ci:prepare-test-pkg": "node scripts/prepare-test-pkg.js"
36
- },
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/zaofan-make/dsh-qqbot.git"
40
- },
41
- "homepage": "https://github.com/zaofan-make/dsh-qqbot#readme",
42
- "bugs": {
43
- "url": "https://github.com/zaofan-make/dsh-qqbot/issues"
44
- },
45
- "keywords": [
46
- "deepseek-harness",
47
- "dsh",
48
- "dsh-plugin",
49
- "qqbot",
50
- "qq-bot",
51
- "chatbot",
52
- "ai-agent",
53
- "cordis",
54
- "plugin",
55
- "llm"
56
- ],
57
- "license": "MIT",
58
- "files": [
59
- "dist",
60
- "docs/USER-GUIDE.md",
61
- "docs/botplay-contract.md",
62
- "docs/host-services.md",
63
- "examples",
64
- "client",
65
- "cordis.patch.yml",
66
- "settings-host.js",
67
- "README.md",
68
- "README_EN.md",
69
- "LICENSE",
70
- "voice-convert.mjs",
71
- "scripts/download-model.mjs",
72
- "scripts/fix-dsh-016-presets.ps1",
73
- "entry.js"
74
- ],
75
- "dsh": {
76
- "bundle": {
77
- "patch": "./cordis.patch.yml"
78
- },
79
- "client": {
80
- "platform": "web",
81
- "inject": [
82
- "@deepseek-ai/dsh-client-ui-settings",
83
- "@deepseek-ai/dsh-client-ui-slots"
84
- ],
85
- "immediately": true
86
- },
87
- "engines": {
88
- "dsh": ">=0.1.5-rc.2"
89
- },
90
- "manifestVersion": 1
91
- },
92
- "dependencies": {
93
- "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
94
- "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
95
- "@deepseek-ai/schemastery": "3.18.4",
96
- "@huggingface/transformers": "^4.3.0",
97
- "@tencent-connect/qqbot-connector": "1.2.0",
98
- "@tencent-connect/qqbot-nodejs": "^1.0.4",
99
- "js-yaml": "^4.1.0",
100
- "lamejs-fixed": "^1.2.2",
101
- "silk-wasm": "^3.7.1"
102
- },
103
- "peerDependencies": {
104
- "@deepseek-ai/cordis": ">=4.0.1",
105
- "@deepseek-ai/dsh-agent": ">=0.1.0-rc.6",
106
- "@deepseek-ai/dsh-llm": ">=0.1.0-rc.6",
107
- "@deepseek-ai/dsh-session": ">=0.1.0-rc.6",
108
- "@deepseek-ai/dsh-settings": "*",
109
- "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2",
110
- "@tencent-connect/qqbot-connector": "1.2.0"
111
- },
112
- "peerDependenciesMeta": {
113
- "@deepseek-ai/cordis": {
114
- "optional": false
115
- },
116
- "@deepseek-ai/schemastery": {
117
- "optional": false
118
- },
119
- "@deepseek-ai/dsh-agent": {
120
- "optional": false
121
- },
122
- "@deepseek-ai/dsh-session": {
123
- "optional": false
124
- },
125
- "@deepseek-ai/dsh-llm": {
126
- "optional": false
127
- }
128
- },
129
- "devDependencies": {
130
- "@deepseek-ai/cordis": "4.0.1",
131
- "@deepseek-ai/dsh-agent": "0.1.0-rc.6",
132
- "@deepseek-ai/dsh-llm": "0.1.0-rc.6",
133
- "@deepseek-ai/dsh-session": "0.1.0-rc.6",
134
- "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2",
135
- "@deepseek-ai/schemastery": "3.18.1",
136
- "@types/js-yaml": "^4.0.9",
137
- "@types/node": "^26.2.0",
138
- "typescript": "^5.5.0",
139
- "vitest": "^4.1.8"
140
- }
141
- }
1
+ {
2
+ "name": "@zaofan/dsh-qqbot",
3
+ "version": "1.9.2",
4
+ "description": "QQ Bot IM channel plugin for deepseek-harness (dsh)",
5
+ "type": "module",
6
+ "main": "./entry.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./entry.js"
12
+ },
13
+ "./channel-tools": {
14
+ "types": "./dist/channel-tools.d.ts",
15
+ "import": "./dist/channel-tools.js"
16
+ },
17
+ "./sticker-store": {
18
+ "types": "./dist/features/sticker-store.d.ts",
19
+ "import": "./dist/features/sticker-store.js"
20
+ },
21
+ "./schedule-store": {
22
+ "types": "./dist/features/schedule-store.d.ts",
23
+ "import": "./dist/features/schedule-store.js"
24
+ },
25
+ "./client": "./client/qqbot-settings.js"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "dev": "tsc --watch",
30
+ "prepublishOnly": "npm run build && node scripts/check-package.mjs",
31
+ "check:package": "node scripts/check-package.mjs",
32
+ "lint": "eslint src/",
33
+ "test": "vitest run",
34
+ "clean": "rm -rf dist",
35
+ "ci:prepare-test-pkg": "node scripts/prepare-test-pkg.js"
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/zaofan-make/dsh-qqbot.git"
40
+ },
41
+ "homepage": "https://github.com/zaofan-make/dsh-qqbot#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/zaofan-make/dsh-qqbot/issues"
44
+ },
45
+ "keywords": [
46
+ "deepseek-harness",
47
+ "dsh",
48
+ "dsh-plugin",
49
+ "qqbot",
50
+ "qq-bot",
51
+ "chatbot",
52
+ "ai-agent",
53
+ "cordis",
54
+ "plugin",
55
+ "llm"
56
+ ],
57
+ "license": "MIT",
58
+ "files": [
59
+ "dist",
60
+ "docs/USER-GUIDE.md",
61
+ "docs/botplay-contract.md",
62
+ "docs/host-services.md",
63
+ "examples",
64
+ "client",
65
+ "cordis.patch.yml",
66
+ "settings-host.js",
67
+ "README.md",
68
+ "README_EN.md",
69
+ "LICENSE",
70
+ "voice-convert.mjs",
71
+ "scripts/download-model.mjs",
72
+ "scripts/fix-dsh-016-presets.ps1",
73
+ "entry.js"
74
+ ],
75
+ "dsh": {
76
+ "bundle": {
77
+ "patch": "./cordis.patch.yml"
78
+ },
79
+ "client": {
80
+ "platform": "web",
81
+ "inject": [
82
+ "@deepseek-ai/dsh-client-ui-settings",
83
+ "@deepseek-ai/dsh-client-ui-slots"
84
+ ],
85
+ "immediately": true
86
+ },
87
+ "engines": {
88
+ "dsh": ">=0.1.5-rc.2"
89
+ },
90
+ "manifestVersion": 1
91
+ },
92
+ "dependencies": {
93
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
94
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
95
+ "@deepseek-ai/schemastery": "3.18.4",
96
+ "@huggingface/transformers": "^4.3.0",
97
+ "@tencent-connect/qqbot-connector": "1.2.0",
98
+ "@tencent-connect/qqbot-nodejs": "^1.0.4",
99
+ "js-yaml": "^4.1.0",
100
+ "lamejs-fixed": "^1.2.2",
101
+ "silk-wasm": "^3.7.1"
102
+ },
103
+ "peerDependencies": {
104
+ "@deepseek-ai/cordis": ">=4.0.1",
105
+ "@deepseek-ai/dsh-agent": ">=0.1.0-rc.6",
106
+ "@deepseek-ai/dsh-llm": ">=0.1.0-rc.6",
107
+ "@deepseek-ai/dsh-session": ">=0.1.0-rc.6",
108
+ "@deepseek-ai/dsh-settings": "*",
109
+ "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2",
110
+ "@tencent-connect/qqbot-connector": "1.2.0"
111
+ },
112
+ "peerDependenciesMeta": {
113
+ "@deepseek-ai/cordis": {
114
+ "optional": false
115
+ },
116
+ "@deepseek-ai/schemastery": {
117
+ "optional": false
118
+ },
119
+ "@deepseek-ai/dsh-agent": {
120
+ "optional": false
121
+ },
122
+ "@deepseek-ai/dsh-session": {
123
+ "optional": false
124
+ },
125
+ "@deepseek-ai/dsh-llm": {
126
+ "optional": false
127
+ }
128
+ },
129
+ "devDependencies": {
130
+ "@deepseek-ai/cordis": "4.0.1",
131
+ "@deepseek-ai/dsh-agent": "0.1.0-rc.6",
132
+ "@deepseek-ai/dsh-llm": "0.1.0-rc.6",
133
+ "@deepseek-ai/dsh-session": "0.1.0-rc.6",
134
+ "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2",
135
+ "@deepseek-ai/schemastery": "3.18.1",
136
+ "@types/js-yaml": "^4.0.9",
137
+ "@types/node": "^26.2.0",
138
+ "typescript": "^5.5.0",
139
+ "vitest": "^4.1.8"
140
+ }
141
+ }
package/settings-host.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * 仅 web profile 装配; 同源 fence 抄 modsearch。
5
5
  */
6
6
  import { readFileSync, writeFileSync, appendFileSync, rmSync, mkdirSync, existsSync, readdirSync, statSync, cpSync, renameSync, openSync, readSync, closeSync, createWriteStream } from 'node:fs';
7
- import { extname, join, resolve, dirname, normalize, sep } from 'node:path';
7
+ import { basename, extname, join, resolve, dirname, normalize, sep } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { spawn } from 'node:child_process';
10
10
  import { homedir } from 'node:os';
@@ -225,10 +225,25 @@ const OWN_SETTINGS_DIR = join(DSH_HOME_DIR, 'qqbot-settings');
225
225
  * 新布局 `{DSH_HOME}/qqbot-settings/<profile>/<ns>.json` —— 各 profile 各一份,**同一个 ns 也不再互相覆盖**;
226
226
  * 老布局 `{DSH_HOME}/qqbot-settings/<ns>.json` —— 所有 profile 共用(就是本次踩坑的根源),仅作读取兜底。
227
227
  * 读:新路径优先 → 老路径兜底(老数据不丢);写:一律写新路径 —— 读取已兜底到老文件,首次保存天然是
228
- * "老内容 + 本次改动",等于**自动搬家**。profile 取自 `DSH_PROFILE`;取不到时落 `_default`
229
- * (退化回老行为,此时由写入者指纹兜底拦住互相覆盖)。
228
+ * "老内容 + 本次改动",等于**自动搬家**。
229
+ *
230
+ * ⚠️ profile 名(2026-10-12 修):**不能只读 `process.env.DSH_PROFILE`**。宿主不会把 profile 名放进
231
+ * 自己的环境变量 —— DSH 是通过 `ctx.get('profileContext').name` 提供的,`DSH_PROFILE` 只在
232
+ * **每次 shell / 工具调用**时由 harness 临时注入(见 `@deepseek-ai/dsh-shell-env`)。于是这里永远拿到空
233
+ * → 永远落 `_default/`,"各 profile 各一份"形同虚设(实测 `writer.json` 记的是 `"profile": "unknown"`)。
234
+ * 现在与 `src/shared/utils.ts` 的 `resolveProfileName()` **同规则**:环境变量 → `PROFILE_ROOT` 目录名
235
+ * (要求其父目录名为 `profiles`,挡住源码 checkout 目录)→ 落 `_default`。改一处务必同步另一处。
230
236
  */
231
- const NS_PROFILE_DIR = String(process.env.DSH_PROFILE || '').trim().replace(/[^A-Za-z0-9_-]/g, '_') || '_default';
237
+ function resolveProfileName() {
238
+ const env = String(process.env.DSH_PROFILE || '').trim();
239
+ if (env) return env;
240
+ try {
241
+ return basename(dirname(PROFILE_ROOT)) === 'profiles' ? basename(PROFILE_ROOT) : '';
242
+ } catch {
243
+ return '';
244
+ }
245
+ }
246
+ const NS_PROFILE_DIR = String(resolveProfileName()).trim().replace(/[^A-Za-z0-9_-]/g, '_') || '_default';
232
247
  function safeNsOf(ns) {
233
248
  return String(ns || NS).replace(/[^A-Za-z0-9_-]/g, '_') || 'im-qqbot';
234
249
  }
@@ -274,7 +289,9 @@ function readNsWriter(ns) {
274
289
  } catch { return null; }
275
290
  }
276
291
  function myProfileName() {
277
- return String(process.env.DSH_PROFILE || '').trim() || 'unknown';
292
+ // 2026-10-12:改用 resolveProfileName()(同规则见其定义处注释)——
293
+ // 原来只读 process.env.DSH_PROFILE,宿主里永远是空 → 指纹恒为 "unknown" → NS_CONFLICT 拦截永久失效。
294
+ return resolveProfileName() || 'unknown';
278
295
  }
279
296
  /** 该设置槽是否正被**别的** profile 占用(供 /read 与 /update 共用) */
280
297
  function nsConflictOf(ns) {