@cxyhhhhh/dsh-qqbot 0.5.0-dev.202610101632 → 0.5.0-dev.202610101921

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.
@@ -8,10 +8,13 @@
8
8
  * 照常加载(CLI profile),就绪/替换时自动(重)注册路由
9
9
  * 3. 按宿主形态挂呈现策略(终端 / 浏览器降级)
10
10
  * 4. 生命周期与 ctx fiber 绑定(dispose 时 abort 轮询、注销路由)
11
+ *
12
+ * 凭据已配置的 fiber 调用 registerBoundCredentialRoutes 注册常驻路由
13
+ * (bound 状态回显 + 手动编辑),与扫码流程共用持久化路径。
11
14
  */
12
15
  import type { Context } from '@deepseek-ai/cordis';
13
16
  import type { Logger } from '../types.ts';
14
- import type { SetupCredentials } from './persist.ts';
17
+ import { type SetupCredentials } from './persist.ts';
15
18
  export type { SetupCredentials } from './persist.ts';
16
19
  export { persistCredentialsToProfile } from './persist.ts';
17
20
  export { isDesktopHost } from './presenters.ts';
@@ -20,12 +23,28 @@ export interface EnsureCredentialsOptions {
20
23
  logger: Logger;
21
24
  /** 二维码 URL 的 source 标识 */
22
25
  source?: string;
26
+ /** 当前生效配置(apply 时 loader 合并值;config 路由 GET 回显用) */
27
+ config: Record<string, unknown>;
23
28
  }
24
29
  /**
25
- * 执行扫码绑定编排,返回凭据;失败/取消返回 null。
30
+ * 执行扫码绑定编排,返回凭据就绪的 Promise;失败/取消 resolve null。
31
+ *
32
+ * 【同步契约】函数体必须保持无 await——绑定编排(服务接管、路由注册、
33
+ * 呈现策略、ctx 生命周期挂载)在调用后的同步阶段全部完成,随后返回
34
+ * `service.start()` 的挂起 Promise。调用方(插件 apply)因此可以不等待
35
+ * 扫码结果直接完成加载:boot 的 `loader.await()` 会等所有插件 fiber
36
+ * settle,若 apply 无限期等待用户扫码,Host ready 会被阻塞
37
+ * (Desktop 界面无法进入、Web URL 延迟输出)。
26
38
  *
27
- * 凭据持久化由调用方(插件入口)执行——成功写入 cordis.patch.yml 会
28
- * 触发 HMR 热重载,新 fiber 以凭据启动网关。
39
+ * 凭据持久化由调用方在 Promise 的 then 链中执行——成功写入
40
+ * cordis.patch.yml 会触发 HMR 热重载,新 fiber 以凭据启动网关。
29
41
  */
30
42
  export declare function ensureCredentials(ctx: Context, options: EnsureCredentialsOptions): Promise<SetupCredentials | null>;
43
+ /**
44
+ * 凭据已配置的 fiber 注册常驻路由(状态回显 + 手动编辑/更换)。
45
+ *
46
+ * 在 apply 的 bootstrapGateway 之前调用;写入经同一 persist 路径,
47
+ * 保存后触发 HMR 重载、新 fiber 以新凭据重启网关。
48
+ */
49
+ export declare function registerBoundCredentialRoutes(ctx: Context, logger: Logger, appId: string, config: Record<string, unknown>): void;
31
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,2BAA2B;AAC3B,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA4ClC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,OAAO,EAA+B,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGlF,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,2BAA2B;AAC3B,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAmDlC;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAehI"}
@@ -1,15 +1,24 @@
1
1
  import { BindingService } from "./binding-service.js";
2
2
  import { registerBindRoutes } from "./bind-routes.js";
3
3
  import { createBrowserPresenter, createTerminalPresenter, isDesktopHost } from "./presenters.js";
4
+ import { persistCredentialsToProfile } from "./persist.js";
5
+ import { getProfileDir } from "../shared/index.js";
4
6
  export { persistCredentialsToProfile } from "./persist.js";
5
7
  export { isDesktopHost } from "./presenters.js";
6
8
  /** 进程内活动绑定服务(HMR 接管用) */
7
9
  let activeService = null;
8
10
  /**
9
- * 执行扫码绑定编排,返回凭据;失败/取消返回 null。
11
+ * 执行扫码绑定编排,返回凭据就绪的 Promise;失败/取消 resolve null。
10
12
  *
11
- * 凭据持久化由调用方(插件入口)执行——成功写入 cordis.patch.yml 会
12
- * 触发 HMR 热重载,新 fiber 以凭据启动网关。
13
+ * 【同步契约】函数体必须保持无 await——绑定编排(服务接管、路由注册、
14
+ * 呈现策略、ctx 生命周期挂载)在调用后的同步阶段全部完成,随后返回
15
+ * `service.start()` 的挂起 Promise。调用方(插件 apply)因此可以不等待
16
+ * 扫码结果直接完成加载:boot 的 `loader.await()` 会等所有插件 fiber
17
+ * settle,若 apply 无限期等待用户扫码,Host ready 会被阻塞
18
+ * (Desktop 界面无法进入、Web URL 延迟输出)。
19
+ *
20
+ * 凭据持久化由调用方在 Promise 的 then 链中执行——成功写入
21
+ * cordis.patch.yml 会触发 HMR 热重载,新 fiber 以凭据启动网关。
13
22
  */
14
23
  export async function ensureCredentials(ctx, options) {
15
24
  const logger = options.logger;
@@ -43,7 +52,14 @@ export async function ensureCredentials(ctx, options) {
43
52
  const webServer = scoped.webServer;
44
53
  if (webServer === undefined || typeof webServer.register !== 'function')
45
54
  return;
46
- const disposeRoutes = registerBindRoutes(webServer, service, logger);
55
+ const disposeRoutes = registerBindRoutes(webServer, service, logger, {
56
+ // 未绑定流程中的手动提交:终止扫码轮询,走同一持久化路径
57
+ onManualCredentials: (credentials) => {
58
+ service.dispose();
59
+ return persistCredentials(credentials, logger);
60
+ },
61
+ currentConfig: () => options.config,
62
+ });
47
63
  // 回调作用域(服务卸载/替换、插件卸载)连带注销路由
48
64
  scoped.effect(() => {
49
65
  return disposeRoutes;
@@ -51,4 +67,32 @@ export async function ensureCredentials(ctx, options) {
51
67
  });
52
68
  return service.start();
53
69
  }
70
+ /**
71
+ * 凭据已配置的 fiber 注册常驻路由(状态回显 + 手动编辑/更换)。
72
+ *
73
+ * 在 apply 的 bootstrapGateway 之前调用;写入经同一 persist 路径,
74
+ * 保存后触发 HMR 重载、新 fiber 以新凭据重启网关。
75
+ */
76
+ export function registerBoundCredentialRoutes(ctx, logger, appId, config) {
77
+ ctx.inject(['webServer'], (scoped) => {
78
+ const webServer = scoped.webServer;
79
+ if (webServer === undefined || typeof webServer.register !== 'function')
80
+ return;
81
+ const disposeRoutes = registerBindRoutes(webServer, null, logger, {
82
+ boundAppId: () => appId,
83
+ onManualCredentials: (credentials) => persistCredentials(credentials, logger),
84
+ currentConfig: () => config,
85
+ });
86
+ scoped.effect(() => {
87
+ return disposeRoutes;
88
+ }, 'im-qqbot.bind-routes');
89
+ });
90
+ }
91
+ /** 手动凭据持久化(失败时返回可展示的错误) */
92
+ function persistCredentials(credentials, logger) {
93
+ const persisted = persistCredentialsToProfile(credentials, getProfileDir() ?? undefined, logger);
94
+ return persisted
95
+ ? { persisted: true }
96
+ : { persisted: false, error: '无法定位 profile 目录或写入失败,请改用环境变量配置' };
97
+ }
54
98
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAsB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIjG,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,yBAAyB;AACzB,IAAI,aAAa,GAA0B,IAAI,CAAC;AAShD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAY,EACZ,OAAiC;IAEjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;IAE7C,mCAAmC;IACnC,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;QACxD,aAAa,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IACD,aAAa,GAAG,OAAO,CAAC;IAExB,gCAAgC;IAC/B,GAAwE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QAC1F,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,IAAI,aAAa,KAAK,OAAO;YAAE,aAAa,GAAG,IAAI,CAAC;IACtD,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAEvB,QAAQ;IACR,6CAA6C;IAC7C,4CAA4C;IAC5C,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,EAAE,CAAC;QAChD,OAAO,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,0BAA0B;IAC1B,4CAA4C;IAC5C,uCAAuC;IACvC,2CAA2C;IAC1C,GAEC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;QAClC,MAAM,SAAS,GAAI,MAA6C,CAAC,SAAsC,CAAC;QACxG,IAAI,SAAS,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,QAAQ,KAAK,UAAU;YAAE,OAAO;QAChF,MAAM,aAAa,GAAG,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACrE,4BAA4B;QAC3B,MAA2E,CAAC,MAAM,CAAC,GAAG,EAAE;YACvF,OAAO,aAAa,CAAC;QACvB,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"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"}
@@ -14,4 +14,28 @@ export declare function persistCredentialsToProfile(credentials: SetupCredential
14
14
  info(msg: string, ...args: unknown[]): void;
15
15
  warn(msg: string, ...args: unknown[]): void;
16
16
  }): boolean;
17
+ /**
18
+ * 从 dsh profile 的 cordis.patch.yml 中移除已保存的凭据(解绑)。
19
+ *
20
+ * 保留 im-qqbot 条目的其余 config(requireMention 等用户配置),
21
+ * 仅删除 appId/appSecret 字段;条目或字段不存在时幂等成功。
22
+ * 移除后写入触发 HMR 重载,插件回到未绑定态(绑定流程重新可用)。
23
+ */
24
+ export declare function removeCredentialsFromProfile(profileDir?: string, logger?: {
25
+ info(msg: string, ...args: unknown[]): void;
26
+ warn(msg: string, ...args: unknown[]): void;
27
+ }): boolean;
28
+ /**
29
+ * 将配置更新合并进 dsh profile 的 cordis.patch.yml(im-qqbot 条目)。
30
+ *
31
+ * 最小写入原则:只把「本次提交的顶层键」合并进条目 config——
32
+ * 不固化 bundle patch 的默认值(保持其版本演进的覆盖能力),
33
+ * 不触碰已保存的凭据字段(appId/appSecret 由绑定/更换/解绑流程管理)。
34
+ * 嵌套对象(如 access)按顶层键整体替换,避免部分合并出混合态。
35
+ * 写入触发 HMR 重载,新 fiber 以新配置启动。
36
+ */
37
+ export declare function updateProfileConfig(configPatch: Record<string, unknown>, profileDir?: string, logger?: {
38
+ info(msg: string, ...args: unknown[]): void;
39
+ warn(msg: string, ...args: unknown[]): void;
40
+ }): boolean;
17
41
  //# sourceMappingURL=persist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/setup/persist.ts"],"names":[],"mappings":"AAWA,WAAW;AACX,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AASD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,gBAAgB,EAC7B,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAAE,GACpG,OAAO,CAoDT"}
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/setup/persist.ts"],"names":[],"mappings":"AAWA,WAAW;AACX,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AASD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,gBAAgB,EAC7B,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAAE,GACpG,OAAO,CAoDT;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAAE,GACpG,OAAO,CA6BT;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAAE,GACpG,OAAO,CAuCT"}
@@ -52,7 +52,7 @@ export function persistCredentialsToProfile(credentials, profileDir, logger) {
52
52
  }
53
53
  // 3. dump 写回(保证合法 YAML)
54
54
  // 先确保 profile 目录存在(文件不存在时也能正常创建,而非误入 ENOENT)
55
- const output = `# QQ Bot 凭据(扫码绑定自动生成)\n${yaml.dump(entries)}`;
55
+ const output = `# QQ 机器人凭据(扫码绑定自动生成)\n${yaml.dump(entries)}`;
56
56
  mkdirSync(dir, { recursive: true });
57
57
  writeFileSync(patchPath, output, 'utf8');
58
58
  log.info(`✔ 凭据已写入: ${patchPath}`);
@@ -65,6 +65,89 @@ export function persistCredentialsToProfile(credentials, profileDir, logger) {
65
65
  return false;
66
66
  }
67
67
  }
68
+ /**
69
+ * 从 dsh profile 的 cordis.patch.yml 中移除已保存的凭据(解绑)。
70
+ *
71
+ * 保留 im-qqbot 条目的其余 config(requireMention 等用户配置),
72
+ * 仅删除 appId/appSecret 字段;条目或字段不存在时幂等成功。
73
+ * 移除后写入触发 HMR 重载,插件回到未绑定态(绑定流程重新可用)。
74
+ */
75
+ export function removeCredentialsFromProfile(profileDir, logger) {
76
+ const log = logger ?? console;
77
+ if (!profileDir) {
78
+ return false;
79
+ }
80
+ const patchPath = resolve(profileDir, 'cordis.patch.yml');
81
+ try {
82
+ if (!existsSync(patchPath))
83
+ return true; // 无 patch 文件 = 无凭据,幂等成功
84
+ const entries = parsePatchEntries(readFileSync(patchPath, 'utf8'));
85
+ const entry = entries.find((e) => e.id === 'im-qqbot');
86
+ if (entry === undefined || entry.config === undefined)
87
+ return true;
88
+ if (entry.config.appId === undefined && entry.config.appSecret === undefined)
89
+ return true;
90
+ delete entry.config.appId;
91
+ delete entry.config.appSecret;
92
+ mkdirSync(profileDir, { recursive: true });
93
+ writeFileSync(patchPath, yaml.dump(entries), 'utf8');
94
+ log.info(`✔ 凭据已移除: ${patchPath}`);
95
+ log.info(` 插件将重新进入绑定流程`);
96
+ return true;
97
+ }
98
+ catch (err) {
99
+ log.warn(`移除凭据失败: ${err instanceof Error ? err.message : String(err)}`);
100
+ return false;
101
+ }
102
+ }
103
+ /**
104
+ * 将配置更新合并进 dsh profile 的 cordis.patch.yml(im-qqbot 条目)。
105
+ *
106
+ * 最小写入原则:只把「本次提交的顶层键」合并进条目 config——
107
+ * 不固化 bundle patch 的默认值(保持其版本演进的覆盖能力),
108
+ * 不触碰已保存的凭据字段(appId/appSecret 由绑定/更换/解绑流程管理)。
109
+ * 嵌套对象(如 access)按顶层键整体替换,避免部分合并出混合态。
110
+ * 写入触发 HMR 重载,新 fiber 以新配置启动。
111
+ */
112
+ export function updateProfileConfig(configPatch, profileDir, logger) {
113
+ const log = logger ?? console;
114
+ if (!profileDir) {
115
+ log.warn('未定位到 profile 目录,配置无法持久化');
116
+ return false;
117
+ }
118
+ const patchPath = resolve(profileDir, 'cordis.patch.yml');
119
+ try {
120
+ let entries = [];
121
+ if (existsSync(patchPath)) {
122
+ entries = parsePatchEntries(readFileSync(patchPath, 'utf8'));
123
+ }
124
+ const entry = entries.find((e) => e.id === 'im-qqbot');
125
+ if (entry !== undefined) {
126
+ const existing = (entry.config ?? {});
127
+ // 只覆盖提交键;appId/appSecret 由绑定流程管理,防御性保留
128
+ const next = { ...existing };
129
+ for (const [key, value] of Object.entries(configPatch)) {
130
+ if (key === 'appId' || key === 'appSecret')
131
+ continue;
132
+ next[key] = value;
133
+ }
134
+ entry.config = next;
135
+ }
136
+ else {
137
+ const { appId: _a, appSecret: _s, ...rest } = configPatch;
138
+ entries.push({ id: 'im-qqbot', config: rest });
139
+ }
140
+ mkdirSync(profileDir, { recursive: true });
141
+ writeFileSync(patchPath, yaml.dump(entries), 'utf8');
142
+ log.info(`✔ 配置已保存: ${patchPath}`);
143
+ log.info(` 插件将自动重载`);
144
+ return true;
145
+ }
146
+ catch (err) {
147
+ log.warn(`保存配置失败: ${err instanceof Error ? err.message : String(err)}`);
148
+ return false;
149
+ }
150
+ }
68
151
  /**
69
152
  * 解析 cordis.patch.yml 为条目数组
70
153
  *
@@ -1 +1 @@
1
- {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../src/setup/persist.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../src/setup/persist.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ export interface QrPresenter {
14
14
  * 是否运行在 DSH Desktop 宿主中。
15
15
  *
16
16
  * Desktop 的 Host 以 ELECTRON_RUN_AS_NODE=1 的 Electron 子进程运行
17
- * (官方启动约定),stdout 对用户不可见,终端呈现无意义。
17
+ * (Desktop 宿主的启动约定),stdout 对用户不可见,终端呈现无意义。
18
18
  */
19
19
  export declare function isDesktopHost(): boolean;
20
20
  /** 终端可点击的 OSC 8 超链接(不支持 OSC 8 的终端会忽略控制序列,退化为纯 URL 文本) */
@@ -10,7 +10,7 @@ import { spawn } from 'node:child_process';
10
10
  * 是否运行在 DSH Desktop 宿主中。
11
11
  *
12
12
  * Desktop 的 Host 以 ELECTRON_RUN_AS_NODE=1 的 Electron 子进程运行
13
- * (官方启动约定),stdout 对用户不可见,终端呈现无意义。
13
+ * (Desktop 宿主的启动约定),stdout 对用户不可见,终端呈现无意义。
14
14
  */
15
15
  export function isDesktopHost() {
16
16
  return process.env.ELECTRON_RUN_AS_NODE === '1' && typeof process.versions?.electron === 'string';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 端内绑定协议 —— 宿主路由与客户端面板的共享契约
3
+ *
4
+ * 类型与路径常量的唯一事实源:宿主(setup/bind-routes.ts)与浏览器
5
+ * (client/bind-page.ts)各自 import,杜绝两端协议漂移。
6
+ * 本模块必须保持纯类型 + 纯常量(零 node 依赖、零副作用):
7
+ * 客户端 tsdown 构建会将其内联进 bundle。
8
+ */
9
+ /** 状态查询(绑定页轮询) */
10
+ export declare const BIND_STATE_PATH = "/qqbot/im-qqbot/bind";
11
+ /** 刷新二维码(绑定页按钮) */
12
+ export declare const BIND_REFRESH_PATH = "/qqbot/im-qqbot/bind/refresh";
13
+ /** 手动填写/编辑凭据(绑定页表单) */
14
+ export declare const BIND_MANUAL_PATH = "/qqbot/im-qqbot/bind/manual";
15
+ /** 解绑:移除已保存凭据,回到绑定流程 */
16
+ export declare const BIND_UNBIND_PATH = "/qqbot/im-qqbot/bind/unbind";
17
+ /** 配置读写(设置面板表单) */
18
+ export declare const BIND_CONFIG_PATH = "/qqbot/im-qqbot/config";
19
+ /** 线上协议(HTTP 路由序列化形态) */
20
+ export type BindStateWire = {
21
+ phase: 'starting';
22
+ } | {
23
+ phase: 'waiting';
24
+ url: string;
25
+ qrSvg?: string;
26
+ issuedAt: number;
27
+ } | {
28
+ phase: 'saving';
29
+ } | {
30
+ phase: 'failed';
31
+ reason: string;
32
+ } | {
33
+ phase: 'bound';
34
+ appId: string;
35
+ };
36
+ /** manual / unbind 操作的统一响应 */
37
+ export interface BindActionResponse {
38
+ ok: boolean;
39
+ message?: string;
40
+ error?: string;
41
+ }
42
+ //# sourceMappingURL=bind-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind-protocol.d.ts","sourceRoot":"","sources":["../../src/shared/bind-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kBAAkB;AAClB,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAEtD,mBAAmB;AACnB,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE,uBAAuB;AACvB,eAAO,MAAM,gBAAgB,gCAAgC,CAAC;AAE9D,wBAAwB;AACxB,eAAO,MAAM,gBAAgB,gCAAgC,CAAC;AAE9D,mBAAmB;AACnB,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD,yBAAyB;AACzB,MAAM,MAAM,aAAa,GACrB;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,GACrB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,8BAA8B;AAC9B,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 端内绑定协议 —— 宿主路由与客户端面板的共享契约
3
+ *
4
+ * 类型与路径常量的唯一事实源:宿主(setup/bind-routes.ts)与浏览器
5
+ * (client/bind-page.ts)各自 import,杜绝两端协议漂移。
6
+ * 本模块必须保持纯类型 + 纯常量(零 node 依赖、零副作用):
7
+ * 客户端 tsdown 构建会将其内联进 bundle。
8
+ */
9
+ /** 状态查询(绑定页轮询) */
10
+ export const BIND_STATE_PATH = '/qqbot/im-qqbot/bind';
11
+ /** 刷新二维码(绑定页按钮) */
12
+ export const BIND_REFRESH_PATH = '/qqbot/im-qqbot/bind/refresh';
13
+ /** 手动填写/编辑凭据(绑定页表单) */
14
+ export const BIND_MANUAL_PATH = '/qqbot/im-qqbot/bind/manual';
15
+ /** 解绑:移除已保存凭据,回到绑定流程 */
16
+ export const BIND_UNBIND_PATH = '/qqbot/im-qqbot/bind/unbind';
17
+ /** 配置读写(设置面板表单) */
18
+ export const BIND_CONFIG_PATH = '/qqbot/im-qqbot/config';
19
+ //# sourceMappingURL=bind-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind-protocol.js","sourceRoot":"","sources":["../../src/shared/bind-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kBAAkB;AAClB,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAEtD,mBAAmB;AACnB,MAAM,CAAC,MAAM,iBAAiB,GAAG,8BAA8B,CAAC;AAEhE,uBAAuB;AACvB,MAAM,CAAC,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAE9D,wBAAwB;AACxB,MAAM,CAAC,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAE9D,mBAAmB;AACnB,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 被动回复限额管理(参考 openclaw-qqbot 的 reply-limiter)。
2
+ * 被动回复限额管理。
3
3
  *
4
4
  * QQ Bot 被动回复有限额:同一条消息只能被动回复 N 次,超时后不能再被动回复。
5
5
  * 当限额耗尽或消息过期时,应降级为主动消息(proactive,不传 msgId)。
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 被动回复限额管理(参考 openclaw-qqbot 的 reply-limiter)。
2
+ * 被动回复限额管理。
3
3
  *
4
4
  * QQ Bot 被动回复有限额:同一条消息只能被动回复 N 次,超时后不能再被动回复。
5
5
  * 当限额耗尽或消息过期时,应降级为主动消息(proactive,不传 msgId)。