opencode-copilot-account-switcher 0.14.3 → 0.14.4

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.
@@ -20,6 +20,9 @@ type WechatBindFlowInput = {
20
20
  readCommonSettings: () => Promise<CommonSettingsStore>;
21
21
  writeCommonSettings: (settings: CommonSettingsStore) => Promise<void>;
22
22
  writeLine?: (line: string) => Promise<void>;
23
+ renderQrTerminal?: (input: {
24
+ value: string;
25
+ }) => Promise<string | undefined>;
23
26
  now?: () => number;
24
27
  };
25
28
  export declare function runWechatBindFlow(input: WechatBindFlowInput): Promise<WechatBindFlowResult>;
@@ -1,6 +1,7 @@
1
1
  import { bindOperator, readOperatorBinding, rebindOperator, resetOperatorBinding } from "./operator-store.js";
2
2
  import { loadOpenClawWeixinPublicHelpers } from "./compat/openclaw-public-helpers.js";
3
3
  import { buildOpenClawMenuAccount } from "./openclaw-account-adapter.js";
4
+ import qrcodeTerminal from "qrcode-terminal";
4
5
  const DEFAULT_QR_WAIT_TIMEOUT_MS = 480000;
5
6
  function pickFirstNonEmptyString(...values) {
6
7
  for (const value of values) {
@@ -32,6 +33,13 @@ async function rollbackBinding(action, previousOperatorBinding, persistOperatorR
32
33
  }
33
34
  await clearOperatorBinding().catch(() => { });
34
35
  }
36
+ async function renderQrTerminalDefault(input) {
37
+ return await new Promise((resolve) => {
38
+ qrcodeTerminal.generate(input.value, { small: true }, (output) => {
39
+ resolve(typeof output === "string" && output.trim().length > 0 ? output : undefined);
40
+ });
41
+ });
42
+ }
35
43
  export async function runWechatBindFlow(input) {
36
44
  const now = input.now ?? Date.now;
37
45
  const loadPublicHelpers = input.loadPublicHelpers ?? loadOpenClawWeixinPublicHelpers;
@@ -39,6 +47,7 @@ export async function runWechatBindFlow(input) {
39
47
  const persistOperatorRebinding = input.rebindOperator ?? rebindOperator;
40
48
  const loadOperatorBinding = input.readOperatorBinding ?? readOperatorBinding;
41
49
  const clearOperatorBinding = input.resetOperatorBinding ?? resetOperatorBinding;
50
+ const renderQrTerminal = input.renderQrTerminal ?? renderQrTerminalDefault;
42
51
  const writeLine = input.writeLine ?? (async (line) => {
43
52
  process.stdout.write(`${line}\n`);
44
53
  });
@@ -53,6 +62,10 @@ export async function runWechatBindFlow(input) {
53
62
  await writeLine(qrTerminal);
54
63
  }
55
64
  else if (qrUrl) {
65
+ const renderedQr = await renderQrTerminal({ value: qrUrl }).catch(() => undefined);
66
+ if (renderedQr) {
67
+ await writeLine(renderedQr);
68
+ }
56
69
  await writeLine(`QR URL fallback: ${qrUrl}`);
57
70
  }
58
71
  else {
@@ -66,21 +79,19 @@ export async function runWechatBindFlow(input) {
66
79
  throw new Error("qr login did not complete");
67
80
  }
68
81
  const accountId = pickFirstNonEmptyString(waited?.accountId, helpers.latestAccountState?.accountId, (await helpers.accountHelpers.listAccountIds()).at(-1));
69
- const userId = pickFirstNonEmptyString(waited?.userId, waited?.openid, waited?.uid);
70
82
  if (!accountId) {
71
83
  throw new Error("missing accountId after qr login");
72
84
  }
73
- if (!userId) {
74
- throw new Error("missing userId after qr login");
75
- }
76
85
  const boundAt = now();
86
+ const userIdFromWait = pickFirstNonEmptyString(waited?.userId, waited?.openid, waited?.uid);
77
87
  const operatorBinding = {
78
88
  wechatAccountId: accountId,
79
- userId,
89
+ userId: "",
80
90
  boundAt,
81
91
  };
82
92
  const previousOperatorBinding = input.action === "wechat-rebind" ? await loadOperatorBinding() : undefined;
83
93
  let menuAccount;
94
+ let boundUserId = "";
84
95
  try {
85
96
  if (input.action === "wechat-rebind") {
86
97
  await persistOperatorRebinding(operatorBinding);
@@ -96,7 +107,7 @@ export async function runWechatBindFlow(input) {
96
107
  baseUrl: "https://ilinkai.weixin.qq.com",
97
108
  }),
98
109
  accountId,
99
- userId,
110
+ ...(userIdFromWait ? { userId: userIdFromWait } : {}),
100
111
  boundAt,
101
112
  }
102
113
  : helpers.latestAccountState;
@@ -104,6 +115,12 @@ export async function runWechatBindFlow(input) {
104
115
  latestAccountState: menuAccountState,
105
116
  accountHelpers: helpers.accountHelpers,
106
117
  });
118
+ const userId = pickFirstNonEmptyString(userIdFromWait, menuAccount?.userId);
119
+ if (!userId) {
120
+ throw new Error("missing userId after qr login");
121
+ }
122
+ boundUserId = userId;
123
+ operatorBinding.userId = userId;
107
124
  const settings = await input.readCommonSettings();
108
125
  const notifications = settings.wechat?.notifications ?? {
109
126
  enabled: true,
@@ -131,7 +148,7 @@ export async function runWechatBindFlow(input) {
131
148
  }
132
149
  return {
133
150
  accountId,
134
- userId,
151
+ userId: boundUserId,
135
152
  name: menuAccount?.name,
136
153
  enabled: menuAccount?.enabled,
137
154
  configured: menuAccount?.configured,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-copilot-account-switcher",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "description": "GitHub Copilot account switcher plugin for OpenCode",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",