dsh-qqbot-buddy 1.0.0-alpha.1 → 1.0.0-alpha.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
@@ -4,7 +4,7 @@
4
4
  支持配置档(Profile)/作用域绑定、可管理的工具与技能、SQLite + FTS5 长期记忆与知识库、
5
5
  群友库、人格卡与表情包,并提供多机器人隔离运行。
6
6
 
7
- - 适用版本:`1.0.0-alpha.1`(v2 分支)
7
+ - 适用版本:`1.0.0-alpha.2`(v2 分支)
8
8
  - 运行环境:**Node.js ≥ 24**(使用内置 `node:sqlite`)、dsh 0.2.x
9
9
  - 依赖:QQ 官方机器人平台的 `appId` / `appSecret`(WebSocket 接入,无需公网回调)
10
10
  - npm:[dsh-qqbot-buddy](https://www.npmjs.com/package/dsh-qqbot-buddy)(当前 alpha 走 `@next` 标签)
@@ -16,7 +16,7 @@
16
16
 
17
17
  | 模块 | 说明 |
18
18
  | --- | --- |
19
- | 独立控制台 | 随插件进程启动的 Web 管理台(默认 `127.0.0.1:6198`),token 登录、SSE 实时事件、开机即用,无需额外部署前端或数据库 |
19
+ | 独立控制台 | 随插件进程启动的 Web 管理台(默认 `127.0.0.1:6198`),token 登录、SSE 实时事件、开机即用,无需额外部署前端或数据库;与 dsh Web 双向快捷入口(控制台顶栏 → dsh Web;dsh Web 右下角 → QQ 控制台) |
20
20
  | 多机器人 | 每个 bot 独立工作目录 `<workspace>/bots/<botId>`,凭据、会话、日志互不影响;同一进程可管理多个 bot |
21
21
  | 配置档与绑定 | 三层策略:`global < bot < profile`;按 `群聊 / 私聊 / 指定 openid` 绑定不同配置档(精确 > 类型通配 > bot 通配 > 默认档),切换配置档不丢记忆 |
22
22
  | 提示词管理 | 人设卡、人格卡、口头禅、能力边界、工具指引;控制台提供**提示词拼合预览**,按真实顺序查看每段内容与字符数 |
@@ -179,6 +179,12 @@ Web 管理控制台。你不需要额外部署数据库、消息队列或前端
179
179
  > 顶栏右上角有 **「dsh Web ↗」** 按钮:一键打开当前 dsh 进程的 Web 界面(链接自带本进程的鉴权 token,无需再手抄)。
180
180
  > 注意:该 token 每次重启 dsh 都会变,因此按钮只在当前进程生命周期内有效;不要把带 token 的链接转发给别人。
181
181
 
182
+ **反向入口(dsh Web → 控制台)**:插件同时带一个 dsh Web 客户端入口——安装本插件的
183
+ web profile 会在页面右下角显示悬浮的 **「QQ 控制台」** 按钮,点击经同源路由 `/qqbot-dashboard`
184
+ 302 到控制台(端口/地址跟随配置,不需要改前端)。若 web profile 只用于放入口、控制台跑在
185
+ 机器人 profile 里,可在该 profile 的 patch 配置里设 `console.enabled: false`(不重复启动控制台)
186
+ 并把 `console.port` 指向已有控制台端口即可。
187
+
182
188
  ![控制台总览](images/console-overview.png)
183
189
 
184
190
  *图 1:控制台总览——机器人运行状态、SSE 事件流与配置规模一屏可见。*
package/lib/client.js ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * dsh Web 客户端插件:在侧边栏底部(sidebar.footer.action 槽位)加一个
3
+ * 「QQ」快捷入口,点击后跳到 QQBot 控制台。
4
+ *
5
+ * 入口地址不走硬编码端口:服务端注册了同源路由 /qqbot-dashboard,会读取本插件
6
+ * 当前配置的 console 地址并 302 过去,这样改端口/监听地址都不需要改前端。
7
+ *
8
+ * 说明:这是 dsh Web 的 client module(window.__ModuleLoader__ 协议),
9
+ * 只在安装了本插件的 web profile 里出现;纯前端、无构建依赖。
10
+ */
11
+ window.__ModuleLoader__.load({
12
+ id: 'dsh-qqbot-buddy',
13
+ factory: (require) => {
14
+ var module = { exports: {} };
15
+ var exports = module.exports;
16
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
17
+ const jsx = require('react/jsx-runtime');
18
+
19
+ const inject = ['slots'];
20
+ const PAGE = 'QQBot 控制台';
21
+
22
+ /** 侧边栏底部的 QQ 快捷入口(外链走同源 302)。 */
23
+ function QqbotDashboardAction() {
24
+ return jsx.jsxs('a', {
25
+ href: '/qqbot-dashboard',
26
+ target: '_blank',
27
+ rel: 'noreferrer',
28
+ title: PAGE + '(在新标签页打开)',
29
+ 'aria-label': PAGE,
30
+ className: 'qqbot-dashboard-entry',
31
+ style: {
32
+ position: 'fixed',
33
+ right: '16px',
34
+ bottom: '16px',
35
+ zIndex: 40,
36
+ pointerEvents: 'auto',
37
+ display: 'inline-flex',
38
+ alignItems: 'center',
39
+ justifyContent: 'center',
40
+ gap: '4px',
41
+ padding: '6px 10px',
42
+ borderRadius: '999px',
43
+ border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.35))',
44
+ background: 'var(--dsw-alias-bg-layer-2, rgba(20,20,20,.72))',
45
+ color: 'var(--dsw-alias-label-primary, inherit)',
46
+ textDecoration: 'none',
47
+ fontSize: '12px',
48
+ fontWeight: 600,
49
+ letterSpacing: '0.02em',
50
+ lineHeight: 1,
51
+ boxShadow: '0 2px 10px rgba(0,0,0,.18)',
52
+ },
53
+ children: [
54
+ jsx.jsx('span', { 'aria-hidden': 'true', children: 'QQ 控制台' }),
55
+ ],
56
+ });
57
+ }
58
+
59
+ function apply(ctx) {
60
+ // shell.overlay 是覆盖层列表槽位:不会被折叠侧栏的 hover mask 挡住,
61
+ // 用 fixed 定位放在左下角,任何页面都能点。
62
+ ctx.slots.inject('shell.overlay', () => ctx.slots.register({
63
+ name: 'shell.overlay',
64
+ id: 'qqbot-dashboard',
65
+ order: 20,
66
+ }, QqbotDashboardAction));
67
+ }
68
+
69
+ exports.apply = apply;
70
+ exports.inject = inject;
71
+ return module.exports;
72
+ },
73
+ });
package/lib/index.js CHANGED
@@ -371,6 +371,52 @@ export async function apply(ctx, config) {
371
371
  }
372
372
  }
373
373
 
374
+ // ── dsh Web → QQBot 控制台快捷入口 ──
375
+ // 客户端插件(lib/client.js)只挂一个 href="/qqbot-dashboard" 的按钮;
376
+ // 这里注册同源 302 路由,读取当前 console 配置并跳转,改端口/地址无需动前端。
377
+ try {
378
+ ctx.inject(['webServer'], (webCtx) => {
379
+ try {
380
+ const resolveConsoleUrl = () => {
381
+ try {
382
+ const address = runtime.console && typeof runtime.console.address === 'function' ? runtime.console.address() : null;
383
+ const url = address && address.url ? String(address.url) : '';
384
+ if (url !== '') return url.endsWith('/') ? url : url + '/';
385
+ } catch { /* 控制台未启动/已关闭 */ }
386
+ // console.enabled=false 只表示「本 profile 不启动控制台」(例如 web profile 只放入口,
387
+ // 控制台跑在机器人 profile 里);跳转仍按配置的 host/port 生成。
388
+ const consoleCfg = cfg.console || {};
389
+ let host = typeof consoleCfg.host === 'string' && consoleCfg.host !== '' ? consoleCfg.host : '127.0.0.1';
390
+ if (host === '0.0.0.0' || host === '::') host = '127.0.0.1';
391
+ const port = Number(consoleCfg.port) || 6198;
392
+ return 'http://' + host + ':' + port + '/';
393
+ };
394
+ webCtx.webServer.register({
395
+ kind: 'exact',
396
+ path: '/qqbot-dashboard',
397
+ handler: (req, res) => {
398
+ const target = resolveConsoleUrl();
399
+ if (target === '') {
400
+ res.statusCode = 503;
401
+ res.setHeader('content-type', 'text/plain; charset=utf-8');
402
+ res.end('QQBot 控制台未启用(dsh-qqbot-buddy 配置 console.enabled)');
403
+ return;
404
+ }
405
+ res.statusCode = 302;
406
+ res.setHeader('location', target);
407
+ res.setHeader('cache-control', 'no-store');
408
+ res.end();
409
+ },
410
+ });
411
+ logger.info('dsh Web 快捷入口已注册: /qqbot-dashboard');
412
+ } catch (err) {
413
+ logger.warn('dsh Web 快捷入口注册失败: ' + errText(err));
414
+ }
415
+ });
416
+ } catch (err) {
417
+ logger.warn('dsh Web 快捷入口注入失败: ' + errText(err));
418
+ }
419
+
374
420
  // ── 机器人宿主 ──
375
421
  try {
376
422
  const mod = await import('./host/agent.js');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-qqbot-buddy",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.2",
4
4
  "description": "DSH QQ 机器人插件 v2:自包含管理控制台、配置档/会话级配置、可管理的工具与技能、SQLite+FTS5 记忆与知识库",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,6 +25,7 @@
25
25
  "exports": {
26
26
  ".": "./lib/index.js",
27
27
  "./console": "./lib/console/server.js",
28
+ "./client": "./lib/client.js",
28
29
  "./package.json": "./package.json"
29
30
  },
30
31
  "engines": {
@@ -57,6 +58,13 @@
57
58
  "dsh": {
58
59
  "bundle": {
59
60
  "patch": "./cordis.patch.yml"
61
+ },
62
+ "client": {
63
+ "platform": "web",
64
+ "inject": [
65
+ "@deepseek-ai/dsh-client-ui-layout",
66
+ "@deepseek-ai/dsh-client-ui-renderer"
67
+ ]
60
68
  }
61
69
  },
62
70
  "bin": {