@cxyhhhhh/dsh-qqbot 0.5.0-dev.202610101526 → 0.5.0-dev.202610101556
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/dist/setup/binding-service.d.ts.map +1 -1
- package/dist/setup/binding-service.js +7 -4
- package/dist/setup/binding-service.js.map +1 -1
- package/dist/setup/index.js +1 -1
- package/dist/setup/index.js.map +1 -1
- package/dist/setup/presenters.d.ts +4 -1
- package/dist/setup/presenters.d.ts.map +1 -1
- package/dist/setup/presenters.js +9 -6
- package/dist/setup/presenters.js.map +1 -1
- package/lib/client.js +3 -3
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
- package/tsdown.client.config.ts +8 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding-service.d.ts","sourceRoot":"","sources":["../../src/setup/binding-service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAwB,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACnH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,gCAAgC;AAChC,MAAM,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;AAElG,cAAc;AACd,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,kCAAkC;AAClC,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,CAAC;AAExC,WAAW;AACX,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,YAAY,CAAiD;IACrE,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,qBAAqB;IAO1C,mBAAmB;IACnB,IAAI,YAAY,IAAI,SAAS,CAE5B;IAED,0BAA0B;IAC1B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAK3C,6BAA6B;IAC7B,MAAM,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAIpC,eAAe;IACf,SAAS,IAAI,aAAa;IAa1B,iBAAiB;IACjB,KAAK,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IASzC,iCAAiC;IACjC,OAAO,IAAI,IAAI;IAMf,+BAA+B;IAC/B,OAAO,IAAI,IAAI;YASD,GAAG;
|
|
1
|
+
{"version":3,"file":"binding-service.d.ts","sourceRoot":"","sources":["../../src/setup/binding-service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAwB,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACnH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,gCAAgC;AAChC,MAAM,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;AAElG,cAAc;AACd,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,kCAAkC;AAClC,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,CAAC;AAExC,WAAW;AACX,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,YAAY,CAAiD;IACrE,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,qBAAqB;IAO1C,mBAAmB;IACnB,IAAI,YAAY,IAAI,SAAS,CAE5B;IAED,0BAA0B;IAC1B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAK3C,6BAA6B;IAC7B,MAAM,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;IAIpC,eAAe;IACf,SAAS,IAAI,aAAa;IAa1B,iBAAiB;IACjB,KAAK,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IASzC,iCAAiC;IACjC,OAAO,IAAI,IAAI;IAMf,+BAA+B;IAC/B,OAAO,IAAI,IAAI;YASD,GAAG;IAwBjB,OAAO,CAAC,WAAW;YAqCL,iBAAiB;IAgB/B,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,QAAQ;CAIjB"}
|
|
@@ -72,7 +72,7 @@ export class BindingService {
|
|
|
72
72
|
refresh() {
|
|
73
73
|
if (this.disposed || this.startPromise === null)
|
|
74
74
|
return;
|
|
75
|
-
|
|
75
|
+
console.log('正在刷新二维码…\n');
|
|
76
76
|
this.refreshCtl?.abort();
|
|
77
77
|
}
|
|
78
78
|
/** 终止绑定(插件卸载 / HMR 接管 / 替换) */
|
|
@@ -97,12 +97,13 @@ export class BindingService {
|
|
|
97
97
|
return null;
|
|
98
98
|
const reason = err instanceof Error ? err.message : String(err);
|
|
99
99
|
this.setPhase({ kind: 'failed', reason });
|
|
100
|
-
|
|
100
|
+
console.error(`[im-qqbot] 扫码绑定失败: ${reason}`);
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
103
|
if (this.disposed)
|
|
104
104
|
return null;
|
|
105
105
|
if (credentials !== null) {
|
|
106
|
+
console.log(`\n✔ 扫码绑定成功! AppID: ${credentials.appId}\n`);
|
|
106
107
|
this.setPhase({ kind: 'saving' });
|
|
107
108
|
return credentials;
|
|
108
109
|
}
|
|
@@ -143,6 +144,10 @@ export class BindingService {
|
|
|
143
144
|
});
|
|
144
145
|
}
|
|
145
146
|
async handleQrDisplayed(generation, url) {
|
|
147
|
+
// 终端链接指引先于 SVG 渲染:指引是二维码渲染错位时的自救通道,
|
|
148
|
+
// 必须与 connector 的二维码打印同步衔接,不隔任何异步间隙
|
|
149
|
+
for (const presenter of this.presenters)
|
|
150
|
+
presenter.onQrDisplayed(url);
|
|
146
151
|
let qrSvg;
|
|
147
152
|
try {
|
|
148
153
|
qrSvg = await this.renderQrFn(url);
|
|
@@ -154,8 +159,6 @@ export class BindingService {
|
|
|
154
159
|
if (generation !== this.runId || this.disposed)
|
|
155
160
|
return;
|
|
156
161
|
this.setPhase({ kind: 'waiting', url, qrSvg, issuedAt: Date.now() });
|
|
157
|
-
for (const presenter of this.presenters)
|
|
158
|
-
presenter.onQrDisplayed(url);
|
|
159
162
|
}
|
|
160
163
|
handleQrExpired(generation) {
|
|
161
164
|
if (generation !== this.runId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding-service.js","sourceRoot":"","sources":["../../src/setup/binding-service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAIlE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AA+BjD;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACjB,KAAK,GAAc,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IAClC,UAAU,GAAkB,EAAE,CAAC;IAC/B,SAAS,CAAY;IACrB,UAAU,CAA4B;IACtC,MAAM,CAAS;IACf,MAAM,CAAS;IAEf,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IAC1C,UAAU,GAA2B,IAAI,CAAC;IAC1C,KAAK,GAAG,CAAC,CAAC;IACV,YAAY,GAA4C,IAAI,CAAC;IAC7D,QAAQ,GAAG,KAAK,CAAC;IAEzB,YAAY,OAA8B;QACxC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,CAAC;IAC3D,CAAC;IAED,mBAAmB;IACnB,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,0BAA0B;IAC1B,SAAS,CAAC,QAAoB;QAC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,6BAA6B;IAC7B,MAAM,CAAC,SAAsB;QAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,eAAe;IACf,SAAS;QACP,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,MAAM;gBACT,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YAC/B,KAAK,SAAS;gBACZ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC3G,KAAK,QAAQ;gBACX,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YAC7B,KAAK,QAAQ;gBACX,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,KAAK;QACH,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,iCAAiC;IACjC,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI;YAAE,OAAO;QACxD,
|
|
1
|
+
{"version":3,"file":"binding-service.js","sourceRoot":"","sources":["../../src/setup/binding-service.ts"],"names":[],"mappings":"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"}
|
package/dist/setup/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export async function ensureCredentials(ctx, options) {
|
|
|
30
30
|
// - 终端通道(CLI / dsh web 运营者);Desktop 无可见终端,跳过
|
|
31
31
|
// - 浏览器降级通道(QQBOT_BIND_OPEN_BROWSER=1 显式启用)
|
|
32
32
|
if (!isDesktopHost()) {
|
|
33
|
-
service.attach(createTerminalPresenter(
|
|
33
|
+
service.attach(createTerminalPresenter());
|
|
34
34
|
}
|
|
35
35
|
if (process.env.QQBOT_BIND_OPEN_BROWSER === '1') {
|
|
36
36
|
service.attach(createBrowserPresenter(logger));
|
package/dist/setup/index.js.map
CHANGED
|
@@ -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,
|
|
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"}
|
|
@@ -24,8 +24,11 @@ export declare function clickableLink(url: string): string;
|
|
|
24
24
|
*
|
|
25
25
|
* ASCII 二维码由 connector 打印(printQrToConsole=true),
|
|
26
26
|
* 本呈现只补打可点击链接与过期提示。
|
|
27
|
+
*
|
|
28
|
+
* 绑定引导是用户直接交互内容,必须用普通 console.log 输出:
|
|
29
|
+
* 不带时间戳/级别前缀(避免打断二维码块),不受日志级别配置影响。
|
|
27
30
|
*/
|
|
28
|
-
export declare function createTerminalPresenter(
|
|
31
|
+
export declare function createTerminalPresenter(): QrPresenter;
|
|
29
32
|
/**
|
|
30
33
|
* 系统浏览器呈现(降级通道)
|
|
31
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenters.d.ts","sourceRoot":"","sources":["../../src/setup/presenters.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,yBAAyB;AACzB,MAAM,WAAW,WAAW;IAC1B,gBAAgB;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,8BAA8B;IAC9B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB;IACjB,WAAW,CAAC,IAAI,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED
|
|
1
|
+
{"version":3,"file":"presenters.d.ts","sourceRoot":"","sources":["../../src/setup/presenters.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,yBAAyB;AACzB,MAAM,WAAW,WAAW;IAC1B,gBAAgB;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,8BAA8B;IAC9B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB;IACjB,WAAW,CAAC,IAAI,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,WAAW,CAYrD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAelE"}
|
package/dist/setup/presenters.js
CHANGED
|
@@ -24,17 +24,20 @@ export function clickableLink(url) {
|
|
|
24
24
|
*
|
|
25
25
|
* ASCII 二维码由 connector 打印(printQrToConsole=true),
|
|
26
26
|
* 本呈现只补打可点击链接与过期提示。
|
|
27
|
+
*
|
|
28
|
+
* 绑定引导是用户直接交互内容,必须用普通 console.log 输出:
|
|
29
|
+
* 不带时间戳/级别前缀(避免打断二维码块),不受日志级别配置影响。
|
|
27
30
|
*/
|
|
28
|
-
export function createTerminalPresenter(
|
|
31
|
+
export function createTerminalPresenter() {
|
|
29
32
|
return {
|
|
30
33
|
id: 'terminal',
|
|
31
34
|
printQrToConsole: true,
|
|
32
35
|
onQrDisplayed(url) {
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
console.log('二维码显示异常?点击下方链接,用浏览器打开即可完成扫码:');
|
|
37
|
+
console.log(` ${clickableLink(url)}\n`);
|
|
35
38
|
},
|
|
36
39
|
onQrExpired() {
|
|
37
|
-
|
|
40
|
+
console.log('二维码已过期,正在刷新…\n');
|
|
38
41
|
},
|
|
39
42
|
};
|
|
40
43
|
}
|
|
@@ -51,14 +54,14 @@ export function createBrowserPresenter(logger) {
|
|
|
51
54
|
id: 'browser',
|
|
52
55
|
printQrToConsole: false,
|
|
53
56
|
onQrDisplayed(url) {
|
|
54
|
-
|
|
57
|
+
console.log(`扫码绑定链接: ${url}`);
|
|
55
58
|
if (opened)
|
|
56
59
|
return;
|
|
57
60
|
opened = true;
|
|
58
61
|
openInBrowser(url, logger);
|
|
59
62
|
},
|
|
60
63
|
onQrExpired() {
|
|
61
|
-
|
|
64
|
+
console.log('二维码已过期,正在刷新…(如浏览器中页面失效,请点击「刷新二维码」)');
|
|
62
65
|
},
|
|
63
66
|
};
|
|
64
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenters.js","sourceRoot":"","sources":["../../src/setup/presenters.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAe3C;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,IAAI,OAAO,OAAO,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC;AACpG,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,aAAa,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAC5D,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"presenters.js","sourceRoot":"","sources":["../../src/setup/presenters.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAe3C;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,IAAI,OAAO,OAAO,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC;AACpG,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,aAAa,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAC5D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,EAAE,EAAE,UAAU;QACd,gBAAgB,EAAE,IAAI;QACtB,aAAa,CAAC,GAAW;YACvB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,WAAW;YACT,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,OAAO;QACL,EAAE,EAAE,SAAS;QACb,gBAAgB,EAAE,KAAK;QACvB,aAAa,CAAC,GAAW;YACvB,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YAC9B,IAAI,MAAM;gBAAE,OAAO;YACnB,MAAM,GAAG,IAAI,CAAC;YACd,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,WAAW;YACT,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,SAAS,aAAa,CAAC,GAAW,EAAE,MAAc;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,OAAO,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;IAC3F,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3F,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC/B,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC"}
|
package/lib/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({
|
|
2
|
-
id: "@
|
|
2
|
+
id: "@cxyhhhhh/dsh-qqbot",
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
@@ -161,8 +161,8 @@ window.__ModuleLoader__.load({
|
|
|
161
161
|
];
|
|
162
162
|
/** 侧栏 Tab 类型(ui-sidebar-right 契约的局部投影) */
|
|
163
163
|
const TAB_KIND = "qqbot-bind";
|
|
164
|
-
/** 席位注册 key(Tab 类型 id
|
|
165
|
-
const TAB_ID = "
|
|
164
|
+
/** 席位注册 key(Tab 类型 id,席位按其分发;只需全局唯一,与包名解耦) */
|
|
165
|
+
const TAB_ID = "im-qqbot/bind";
|
|
166
166
|
/** 绑定入口图标(机器人轮廓,跟随主题 currentColor) */
|
|
167
167
|
function BindGuideIcon() {
|
|
168
168
|
return (0, react.createElement)("svg", {
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["useState","useCallback","createElement","createElement"],"sources":["../src/client/bind-page.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 端内绑定页 — 二维码展示与状态轮询\n *\n * 宿主插件在「待绑定」时注册 /qqbot/im-qqbot/bind 状态路由,本组件\n * 轮询该路由渲染二维码与实时状态;扫码成功后宿主写入 profile 并经\n * HMR 重载,路由随之消失(404),页面显示完成态。\n *\n * 运行时仅依赖 react(dsh 客户端平台种子表提供);宿主通信走同源 fetch,\n * Desktop 下由壳的 IPC 桥自动附加 Host 认证转发。\n */\nimport { createElement, useCallback, useEffect, useState, type CSSProperties, type ReactNode } from 'react';\n\n/** 状态查询路由(宿主 bind-routes 注册) */\nexport const BIND_STATE_URL = '/qqbot/im-qqbot/bind';\n\n/** 刷新路由 */\nconst BIND_REFRESH_URL = '/qqbot/im-qqbot/bind/refresh';\n\n/** 轮询间隔(毫秒):活跃轮询 / 失败退避 */\nconst ACTIVE_POLL_MS = 2000;\nconst RETRY_POLL_MS = 3000;\n\n/** 宿主路由的序列化状态(与 src/setup/bind-routes.ts 的协议保持一致) */\ntype BindStateWire =\n | { phase: 'starting' }\n | { phase: 'waiting'; url: string; qrSvg?: string; issuedAt: number }\n | { phase: 'saving' }\n | { phase: 'failed'; reason: string };\n\nconst CONTAINER: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '14px',\n padding: '24px',\n height: '100%',\n textAlign: 'center',\n fontSize: '14px',\n};\n\nconst QR_IMAGE: CSSProperties = {\n borderRadius: '8px',\n background: '#fff',\n padding: '10px',\n maxWidth: '100%',\n};\n\nconst TITLE: CSSProperties = { margin: 0, fontSize: '16px', fontWeight: 600 };\nconst HINT: CSSProperties = { margin: 0, opacity: 0.75, lineHeight: 1.6 };\nconst LINK: CSSProperties = { fontSize: '13px', opacity: 0.85 };\nconst BUTTON: CSSProperties = {\n padding: '6px 16px',\n borderRadius: '6px',\n border: '1px solid currentColor',\n background: 'transparent',\n color: 'inherit',\n cursor: 'pointer',\n fontSize: '13px',\n};\n\nconst STATUS_ICON: CSSProperties = { fontSize: '32px', lineHeight: 1 };\n\n/**\n * 绑定页主体(注册在 sidebar.right.pane.tab 席位)。\n *\n * 组件只消费框架注入的渲染位置,不依赖业务注入面;\n * 状态来自宿主路由轮询,卸载(Tab 关闭/隐藏)时停止轮询。\n */\nexport function BindBody(): ReactNode {\n const [state, setState] = useState<BindStateWire | null>(null);\n const [gone, setGone] = useState(false);\n const [refreshing, setRefreshing] = useState(false);\n\n useEffect(() => {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const tick = async (): Promise<void> => {\n if (stopped) return;\n try {\n const res = await fetch(BIND_STATE_URL, { cache: 'no-store' });\n if (res.status === 404) {\n // 已绑定(插件重载后路由消失)或插件未启用\n if (!stopped) setGone(true);\n return;\n }\n if (!res.ok) {\n schedule(RETRY_POLL_MS);\n return;\n }\n const body = (await res.json()) as BindStateWire;\n if (stopped) return;\n setState(body);\n schedule(body.phase === 'saving' ? 500 : ACTIVE_POLL_MS);\n return;\n } catch {\n // 宿主启动窗口期不可达:退避重试\n }\n schedule(RETRY_POLL_MS);\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n }, []);\n\n const refresh = useCallback(async (): Promise<void> => {\n setRefreshing(true);\n try {\n await fetch(BIND_REFRESH_URL, { method: 'POST' });\n setState({ phase: 'starting' });\n } catch (err) {\n console.error('[im-qqbot] 刷新二维码失败', err);\n } finally {\n setRefreshing(false);\n }\n }, []);\n\n if (gone) {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '✅'),\n createElement('p', { style: HINT }, '绑定已完成,或插件未启用。'),\n );\n }\n\n if (state === null || state.phase === 'starting') {\n return createElement('div', { style: CONTAINER },\n createElement('p', { style: HINT }, '正在生成二维码…'),\n );\n }\n\n if (state.phase === 'saving') {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '🎉'),\n createElement('p', { style: TITLE }, '扫码成功'),\n createElement('p', { style: HINT }, '凭据已保存,插件正在重载,稍后即可开始对话。'),\n );\n }\n\n if (state.phase === 'failed') {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '⚠️'),\n createElement('p', { style: TITLE }, '绑定失败'),\n createElement('p', { style: HINT }, state.reason),\n createElement('button', { style: BUTTON, disabled: refreshing, onClick: () => { void refresh(); } }, '重试'),\n );\n }\n\n return createElement('div', { style: CONTAINER },\n state.qrSvg === undefined\n ? null\n : createElement('img', { src: state.qrSvg, alt: 'QQ 扫码二维码', width: 220, height: 220, style: QR_IMAGE }),\n createElement('p', { style: TITLE }, 'QQ Bot 绑定'),\n createElement('p', { style: HINT }, '请使用手机 QQ 扫描上方二维码,完成机器人绑定'),\n createElement('a', { href: state.url, target: '_blank', rel: 'noreferrer noopener', style: LINK }, '在浏览器中打开扫码页'),\n createElement('button', { style: BUTTON, disabled: refreshing, onClick: () => { void refresh(); } },\n refreshing ? '正在刷新…' : '刷新二维码'),\n );\n}\n","/**\n * im-qqbot 浏览器半边 —— QQ Bot 端内扫码绑定入口\n *\n * 宿主插件在凭据缺失时注册 /qqbot/im-qqbot/bind 状态路由;本插件在\n * Web / Desktop 的右侧栏注册「QQ Bot 绑定」页,并在检测到待绑定状态时\n * 自动打开(每次页面加载至多一次)。\n *\n * 运行时依赖仅 react(客户端平台种子表提供);宿主侧栏服务经 ctx 注入,\n * 以防御式探测访问——组合缺失(如未来精简构建)时静默退出,不阻塞浏览器启动。\n */\nimport type { Context } from '@deepseek-ai/cordis';\nimport { createElement } from 'react';\nimport { BindBody, BIND_STATE_URL } from './bind-page.ts';\n\nexport const name = 'im-qqbot-client';\nexport const inject = ['slots', 'sidebarRight', 'sidebarRightTabs'];\n\n/** 侧栏 Tab 类型(ui-sidebar-right 契约的局部投影) */\nconst TAB_KIND = 'qqbot-bind';\n/** 席位注册 key(Tab 类型 id,body/title 席位按其分发) */\nconst TAB_ID = '@tencent-connect/dsh-qqbot/bind';\n\n/** ui-sidebar-right 的 Tab 注册表服务(局部投影) */\ninterface TabRegistryLike {\n register(definition: {\n id: string;\n kind: string;\n title: (address: string) => string;\n guide?: ReadonlyArray<{\n id: string;\n order: number;\n title: () => string;\n description: () => string;\n icon: unknown;\n }>;\n }): () => void;\n}\n\n/** ui-sidebar-right 的导航控制器服务(局部投影) */\ninterface SidebarRightLike {\n openTab(kind: string, options?: Record<string, unknown>): unknown;\n}\n\n/** ui-slots 的席位系统服务(局部投影) */\ninterface SlotsLike {\n inject(slotName: string, register: () => (() => void)): () => void;\n register(spec: { name: string; key: string }, component: unknown): () => void;\n}\n\n/** 绑定入口图标(机器人轮廓,跟随主题 currentColor) */\nfunction BindGuideIcon(): unknown {\n return createElement('svg', { width: 24, height: 24, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true },\n createElement('path', { d: 'M12 3a6 6 0 0 1 6 6v1.5a4.5 4.5 0 0 1 0 9H6a4.5 4.5 0 0 1 0-9V9a6 6 0 0 1 6-6Z', fill: 'currentColor', fillOpacity: 0.9 }),\n createElement('circle', { cx: 9.5, cy: 12, r: 1.4, fill: '#fff' }),\n createElement('circle', { cx: 14.5, cy: 12, r: 1.4, fill: '#fff' }),\n createElement('path', { d: 'M9.5 15.5a3 3 0 0 0 5 0', stroke: '#fff', strokeWidth: 1.2, strokeLinecap: 'round' }),\n );\n}\n\nexport function apply(ctx: Context): void {\n const tabs = (ctx as unknown as { sidebarRightTabs?: TabRegistryLike }).sidebarRightTabs;\n const right = (ctx as unknown as { sidebarRight?: SidebarRightLike }).sidebarRight;\n const slots = (ctx as unknown as { slots?: SlotsLike }).slots;\n // 侧栏组合缺失:静默退出(宿主绑定路由与终端呈现仍然可用)\n if (tabs === undefined || slots === undefined) return;\n\n const disposers: Array<() => void> = [\n // 1. Tab 类型注册(guide 入口 + 打开时的标题捕获)\n tabs.register({\n id: TAB_ID,\n kind: TAB_KIND,\n title: () => 'QQ Bot 绑定',\n guide: [{\n id: 'bind',\n order: 90,\n title: () => 'QQ Bot 绑定',\n description: () => '扫码将 QQ 机器人绑定到当前配置',\n icon: BindGuideIcon,\n }],\n }),\n // 2. Tab 主体(keyed 席位按 Tab 类型 id 分发)\n slots.inject('sidebar.right.pane.tab', () => slots.register(\n { name: 'sidebar.right.pane.tab', key: TAB_ID },\n BindBody,\n )),\n // 3. 待绑定检测与自动引导\n watchAndPrompt(right),\n ];\n\n (ctx as unknown as { effect(fn: () => () => void, name?: string): void }).effect(() => () => {\n for (const dispose of disposers.reverse()) dispose();\n }, 'im-qqbot-client.binding');\n}\n\n/**\n * 轮询绑定状态:待绑定时自动打开绑定页。\n *\n * - 页面隐藏时降频轮询(可见时立即恢复节拍)\n * - 404(已绑定/未安装)时退避到 30s,保持低成本常驻探测\n * - 每次页面加载至多自动打开一次(用户手动关闭后不打扰)\n */\nfunction watchAndPrompt(right: SidebarRightLike | undefined): () => void {\n let stopped = false;\n let opened = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const tick = async (): Promise<void> => {\n if (stopped) return;\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {\n schedule(5000);\n return;\n }\n try {\n const res = await fetch(BIND_STATE_URL, { cache: 'no-store' });\n if (res.ok) {\n const body = (await res.json()) as { phase?: string };\n if (body.phase === 'waiting' && !opened) {\n opened = true;\n try {\n right?.openTab(TAB_KIND);\n } catch (err) {\n console.error('[im-qqbot] 打开绑定页失败', err);\n }\n }\n schedule(3000);\n return;\n }\n // 404:已绑定或插件未启用\n schedule(30000);\n return;\n } catch {\n // 宿主暂不可达(启动窗口期):退避重试\n }\n schedule(10000);\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["useState","useCallback","createElement","createElement"],"sources":["../src/client/bind-page.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 端内绑定页 — 二维码展示与状态轮询\n *\n * 宿主插件在「待绑定」时注册 /qqbot/im-qqbot/bind 状态路由,本组件\n * 轮询该路由渲染二维码与实时状态;扫码成功后宿主写入 profile 并经\n * HMR 重载,路由随之消失(404),页面显示完成态。\n *\n * 运行时仅依赖 react(dsh 客户端平台种子表提供);宿主通信走同源 fetch,\n * Desktop 下由壳的 IPC 桥自动附加 Host 认证转发。\n */\nimport { createElement, useCallback, useEffect, useState, type CSSProperties, type ReactNode } from 'react';\n\n/** 状态查询路由(宿主 bind-routes 注册) */\nexport const BIND_STATE_URL = '/qqbot/im-qqbot/bind';\n\n/** 刷新路由 */\nconst BIND_REFRESH_URL = '/qqbot/im-qqbot/bind/refresh';\n\n/** 轮询间隔(毫秒):活跃轮询 / 失败退避 */\nconst ACTIVE_POLL_MS = 2000;\nconst RETRY_POLL_MS = 3000;\n\n/** 宿主路由的序列化状态(与 src/setup/bind-routes.ts 的协议保持一致) */\ntype BindStateWire =\n | { phase: 'starting' }\n | { phase: 'waiting'; url: string; qrSvg?: string; issuedAt: number }\n | { phase: 'saving' }\n | { phase: 'failed'; reason: string };\n\nconst CONTAINER: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '14px',\n padding: '24px',\n height: '100%',\n textAlign: 'center',\n fontSize: '14px',\n};\n\nconst QR_IMAGE: CSSProperties = {\n borderRadius: '8px',\n background: '#fff',\n padding: '10px',\n maxWidth: '100%',\n};\n\nconst TITLE: CSSProperties = { margin: 0, fontSize: '16px', fontWeight: 600 };\nconst HINT: CSSProperties = { margin: 0, opacity: 0.75, lineHeight: 1.6 };\nconst LINK: CSSProperties = { fontSize: '13px', opacity: 0.85 };\nconst BUTTON: CSSProperties = {\n padding: '6px 16px',\n borderRadius: '6px',\n border: '1px solid currentColor',\n background: 'transparent',\n color: 'inherit',\n cursor: 'pointer',\n fontSize: '13px',\n};\n\nconst STATUS_ICON: CSSProperties = { fontSize: '32px', lineHeight: 1 };\n\n/**\n * 绑定页主体(注册在 sidebar.right.pane.tab 席位)。\n *\n * 组件只消费框架注入的渲染位置,不依赖业务注入面;\n * 状态来自宿主路由轮询,卸载(Tab 关闭/隐藏)时停止轮询。\n */\nexport function BindBody(): ReactNode {\n const [state, setState] = useState<BindStateWire | null>(null);\n const [gone, setGone] = useState(false);\n const [refreshing, setRefreshing] = useState(false);\n\n useEffect(() => {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const tick = async (): Promise<void> => {\n if (stopped) return;\n try {\n const res = await fetch(BIND_STATE_URL, { cache: 'no-store' });\n if (res.status === 404) {\n // 已绑定(插件重载后路由消失)或插件未启用\n if (!stopped) setGone(true);\n return;\n }\n if (!res.ok) {\n schedule(RETRY_POLL_MS);\n return;\n }\n const body = (await res.json()) as BindStateWire;\n if (stopped) return;\n setState(body);\n schedule(body.phase === 'saving' ? 500 : ACTIVE_POLL_MS);\n return;\n } catch {\n // 宿主启动窗口期不可达:退避重试\n }\n schedule(RETRY_POLL_MS);\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n }, []);\n\n const refresh = useCallback(async (): Promise<void> => {\n setRefreshing(true);\n try {\n await fetch(BIND_REFRESH_URL, { method: 'POST' });\n setState({ phase: 'starting' });\n } catch (err) {\n console.error('[im-qqbot] 刷新二维码失败', err);\n } finally {\n setRefreshing(false);\n }\n }, []);\n\n if (gone) {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '✅'),\n createElement('p', { style: HINT }, '绑定已完成,或插件未启用。'),\n );\n }\n\n if (state === null || state.phase === 'starting') {\n return createElement('div', { style: CONTAINER },\n createElement('p', { style: HINT }, '正在生成二维码…'),\n );\n }\n\n if (state.phase === 'saving') {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '🎉'),\n createElement('p', { style: TITLE }, '扫码成功'),\n createElement('p', { style: HINT }, '凭据已保存,插件正在重载,稍后即可开始对话。'),\n );\n }\n\n if (state.phase === 'failed') {\n return createElement('div', { style: CONTAINER },\n createElement('div', { style: STATUS_ICON }, '⚠️'),\n createElement('p', { style: TITLE }, '绑定失败'),\n createElement('p', { style: HINT }, state.reason),\n createElement('button', { style: BUTTON, disabled: refreshing, onClick: () => { void refresh(); } }, '重试'),\n );\n }\n\n return createElement('div', { style: CONTAINER },\n state.qrSvg === undefined\n ? null\n : createElement('img', { src: state.qrSvg, alt: 'QQ 扫码二维码', width: 220, height: 220, style: QR_IMAGE }),\n createElement('p', { style: TITLE }, 'QQ Bot 绑定'),\n createElement('p', { style: HINT }, '请使用手机 QQ 扫描上方二维码,完成机器人绑定'),\n createElement('a', { href: state.url, target: '_blank', rel: 'noreferrer noopener', style: LINK }, '在浏览器中打开扫码页'),\n createElement('button', { style: BUTTON, disabled: refreshing, onClick: () => { void refresh(); } },\n refreshing ? '正在刷新…' : '刷新二维码'),\n );\n}\n","/**\n * im-qqbot 浏览器半边 —— QQ Bot 端内扫码绑定入口\n *\n * 宿主插件在凭据缺失时注册 /qqbot/im-qqbot/bind 状态路由;本插件在\n * Web / Desktop 的右侧栏注册「QQ Bot 绑定」页,并在检测到待绑定状态时\n * 自动打开(每次页面加载至多一次)。\n *\n * 运行时依赖仅 react(客户端平台种子表提供);宿主侧栏服务经 ctx 注入,\n * 以防御式探测访问——组合缺失(如未来精简构建)时静默退出,不阻塞浏览器启动。\n */\nimport type { Context } from '@deepseek-ai/cordis';\nimport { createElement } from 'react';\nimport { BindBody, BIND_STATE_URL } from './bind-page.ts';\n\nexport const name = 'im-qqbot-client';\nexport const inject = ['slots', 'sidebarRight', 'sidebarRightTabs'];\n\n/** 侧栏 Tab 类型(ui-sidebar-right 契约的局部投影) */\nconst TAB_KIND = 'qqbot-bind';\n/** 席位注册 key(Tab 类型 id,席位按其分发;只需全局唯一,与包名解耦) */\nconst TAB_ID = 'im-qqbot/bind';\n\n/** ui-sidebar-right 的 Tab 注册表服务(局部投影) */\ninterface TabRegistryLike {\n register(definition: {\n id: string;\n kind: string;\n title: (address: string) => string;\n guide?: ReadonlyArray<{\n id: string;\n order: number;\n title: () => string;\n description: () => string;\n icon: unknown;\n }>;\n }): () => void;\n}\n\n/** ui-sidebar-right 的导航控制器服务(局部投影) */\ninterface SidebarRightLike {\n openTab(kind: string, options?: Record<string, unknown>): unknown;\n}\n\n/** ui-slots 的席位系统服务(局部投影) */\ninterface SlotsLike {\n inject(slotName: string, register: () => (() => void)): () => void;\n register(spec: { name: string; key: string }, component: unknown): () => void;\n}\n\n/** 绑定入口图标(机器人轮廓,跟随主题 currentColor) */\nfunction BindGuideIcon(): unknown {\n return createElement('svg', { width: 24, height: 24, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true },\n createElement('path', { d: 'M12 3a6 6 0 0 1 6 6v1.5a4.5 4.5 0 0 1 0 9H6a4.5 4.5 0 0 1 0-9V9a6 6 0 0 1 6-6Z', fill: 'currentColor', fillOpacity: 0.9 }),\n createElement('circle', { cx: 9.5, cy: 12, r: 1.4, fill: '#fff' }),\n createElement('circle', { cx: 14.5, cy: 12, r: 1.4, fill: '#fff' }),\n createElement('path', { d: 'M9.5 15.5a3 3 0 0 0 5 0', stroke: '#fff', strokeWidth: 1.2, strokeLinecap: 'round' }),\n );\n}\n\nexport function apply(ctx: Context): void {\n const tabs = (ctx as unknown as { sidebarRightTabs?: TabRegistryLike }).sidebarRightTabs;\n const right = (ctx as unknown as { sidebarRight?: SidebarRightLike }).sidebarRight;\n const slots = (ctx as unknown as { slots?: SlotsLike }).slots;\n // 侧栏组合缺失:静默退出(宿主绑定路由与终端呈现仍然可用)\n if (tabs === undefined || slots === undefined) return;\n\n const disposers: Array<() => void> = [\n // 1. Tab 类型注册(guide 入口 + 打开时的标题捕获)\n tabs.register({\n id: TAB_ID,\n kind: TAB_KIND,\n title: () => 'QQ Bot 绑定',\n guide: [{\n id: 'bind',\n order: 90,\n title: () => 'QQ Bot 绑定',\n description: () => '扫码将 QQ 机器人绑定到当前配置',\n icon: BindGuideIcon,\n }],\n }),\n // 2. Tab 主体(keyed 席位按 Tab 类型 id 分发)\n slots.inject('sidebar.right.pane.tab', () => slots.register(\n { name: 'sidebar.right.pane.tab', key: TAB_ID },\n BindBody,\n )),\n // 3. 待绑定检测与自动引导\n watchAndPrompt(right),\n ];\n\n (ctx as unknown as { effect(fn: () => () => void, name?: string): void }).effect(() => () => {\n for (const dispose of disposers.reverse()) dispose();\n }, 'im-qqbot-client.binding');\n}\n\n/**\n * 轮询绑定状态:待绑定时自动打开绑定页。\n *\n * - 页面隐藏时降频轮询(可见时立即恢复节拍)\n * - 404(已绑定/未安装)时退避到 30s,保持低成本常驻探测\n * - 每次页面加载至多自动打开一次(用户手动关闭后不打扰)\n */\nfunction watchAndPrompt(right: SidebarRightLike | undefined): () => void {\n let stopped = false;\n let opened = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const tick = async (): Promise<void> => {\n if (stopped) return;\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {\n schedule(5000);\n return;\n }\n try {\n const res = await fetch(BIND_STATE_URL, { cache: 'no-store' });\n if (res.ok) {\n const body = (await res.json()) as { phase?: string };\n if (body.phase === 'waiting' && !opened) {\n opened = true;\n try {\n right?.openTab(TAB_KIND);\n } catch (err) {\n console.error('[im-qqbot] 打开绑定页失败', err);\n }\n }\n schedule(3000);\n return;\n }\n // 404:已绑定或插件未启用\n schedule(30000);\n return;\n } catch {\n // 宿主暂不可达(启动窗口期):退避重试\n }\n schedule(10000);\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/tsdown.client.config.ts
CHANGED
|
@@ -9,10 +9,16 @@
|
|
|
9
9
|
* 与 deepseek-harness 仓库 packages/client/tsdown.client.ts 的契约保持一致,
|
|
10
10
|
* 仅保留外部插件所需的最小集。
|
|
11
11
|
*/
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
12
13
|
import { defineConfig } from 'tsdown';
|
|
13
14
|
|
|
14
|
-
/** 浏览器模块 id
|
|
15
|
-
|
|
15
|
+
/** 浏览器模块 id:从 package.json 的 name 动态读取。
|
|
16
|
+
*
|
|
17
|
+
* 宿主 client-modules 按包名(最近归属的 package manifest)注册 boot 图行,
|
|
18
|
+
* bundle 的 __ModuleLoader__.load({ id }) 必须与其一致——改名发布
|
|
19
|
+
* (fork/scope 迁移)时硬编码会导致「loaded without registering」。
|
|
20
|
+
*/
|
|
21
|
+
const ID = (JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8')) as { name: string }).name;
|
|
16
22
|
|
|
17
23
|
/** 客户端平台种子表(baseline externals;react/cordis 之外的依赖须整体内联) */
|
|
18
24
|
const BASELINE_EXTERNALS = [
|