codex-weixin 0.2.1 → 0.2.3

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/web/app.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const state = {
2
+ version: "",
2
3
  requestToken: "",
3
4
  accounts: [],
4
5
  sessions: [],
@@ -12,6 +13,7 @@ const state = {
12
13
  loadedSessionKey: "",
13
14
  loadingMessages: false,
14
15
  sendingMessage: false,
16
+ savingSessionRuntime: false,
15
17
  selectedAccountId: "",
16
18
  chatFiles: []
17
19
  };
@@ -24,6 +26,7 @@ const els = {};
24
26
  document.addEventListener("DOMContentLoaded", () => {
25
27
  Object.assign(els, {
26
28
  accountsList: document.querySelector("#accountsList"),
29
+ productVersion: document.querySelector("#productVersion"),
27
30
  sessionsList: document.querySelector("#sessionsList"),
28
31
  sessionAccountTabs: document.querySelector("#sessionAccountTabs"),
29
32
  sessionListCount: document.querySelector("#sessionListCount"),
@@ -37,6 +40,9 @@ document.addEventListener("DOMContentLoaded", () => {
37
40
  chatFileInput: document.querySelector("#chatFileInput"),
38
41
  composerFiles: document.querySelector("#composerFiles"),
39
42
  refreshMessagesButton: document.querySelector("#refreshMessagesButton"),
43
+ sessionRuntimeToolbar: document.querySelector("#sessionRuntimeToolbar"),
44
+ sessionModelInput: document.querySelector("#sessionModelInput"),
45
+ sessionEffortInput: document.querySelector("#sessionEffortInput"),
40
46
  runningAccountMetric: document.querySelector("#runningAccountMetric"),
41
47
  sessionMetric: document.querySelector("#sessionMetric"),
42
48
  workspaceMetric: document.querySelector("#workspaceMetric"),
@@ -59,6 +65,8 @@ function bindEvents() {
59
65
  document.querySelector("#newSessionButton").addEventListener("click", openNewSessionDialog);
60
66
  document.querySelector("#settingsForm").addEventListener("submit", (event) => void saveSettings(event));
61
67
  document.querySelector("#modelInput").addEventListener("change", () => renderEffortOptions(""));
68
+ els.sessionModelInput.addEventListener("change", () => void handleSessionModelChange());
69
+ els.sessionEffortInput.addEventListener("change", () => void saveSessionRuntimeSettings());
62
70
  document.querySelector("#accountForm").addEventListener("submit", (event) => void saveAccountRemark(event));
63
71
  document.querySelector("#sessionForm").addEventListener("submit", (event) => void saveSession(event));
64
72
  document.querySelector("#sessionSenderInput").addEventListener("change", updateNewSessionDefaultTitle);
@@ -80,6 +88,7 @@ async function bootstrap() {
80
88
  try {
81
89
  const data = await api("/api/bootstrap", { token: false });
82
90
  state.requestToken = data.requestToken;
91
+ state.version = data.version || "";
83
92
  state.accounts = data.accounts;
84
93
  state.sessions = data.sessions;
85
94
  state.config = data.config;
@@ -125,6 +134,7 @@ async function refreshData(notify) {
125
134
  }
126
135
 
127
136
  function renderAll() {
137
+ renderProductVersion();
128
138
  renderMetrics();
129
139
  renderAccounts();
130
140
  renderSessions();
@@ -132,6 +142,12 @@ function renderAll() {
132
142
  drawIcons();
133
143
  }
134
144
 
145
+ function renderProductVersion() {
146
+ const version = state.version.trim();
147
+ els.productVersion.hidden = !version;
148
+ els.productVersion.textContent = version ? `v${version.replace(/^v/i, "")}` : "";
149
+ }
150
+
135
151
  function renderMetrics() {
136
152
  els.runningAccountMetric.textContent = String(state.accounts.filter((account) => account.status === "running").length);
137
153
  els.sessionMetric.textContent = String(state.sessions.length);
@@ -149,6 +165,11 @@ function renderMetrics() {
149
165
  }
150
166
 
151
167
  function renderAccounts() {
168
+ const expandedAccountIds = new Set(
169
+ [...els.accountsList.querySelectorAll(".account-identifiers[open]")]
170
+ .map((details) => details.dataset.accountId)
171
+ .filter(Boolean)
172
+ );
152
173
  if (!state.accounts.length) {
153
174
  els.accountsList.innerHTML = emptyState("scan-line", "还没有微信账号", "", `<button class="button button-primary" type="button" data-account-action="add"><i data-lucide="scan-line"></i><span>添加微信</span></button>`);
154
175
  drawIcons();
@@ -175,6 +196,16 @@ function renderAccounts() {
175
196
  <button class="icon-button is-danger" type="button" data-account-action="remove" data-account-id="${escapeAttr(account.accountId)}" title="移除账号" aria-label="移除账号"><i data-lucide="trash-2"></i></button>
176
197
  </div>
177
198
  </div>
199
+ <details class="account-identifiers" data-account-id="${escapeAttr(account.accountId)}"${expandedAccountIds.has(account.accountId) ? " open" : ""}>
200
+ <summary>
201
+ <span class="account-identifiers-title"><i data-lucide="fingerprint"></i><strong>账号 ID</strong><small>Bot ID 与 User ID</small></span>
202
+ <i class="account-identifiers-chevron" data-lucide="chevron-down"></i>
203
+ </summary>
204
+ <dl class="account-identifiers-grid">
205
+ <div><dt>Bot ID</dt><dd><code title="${escapeAttr(account.botId || account.accountId)}">${escapeHtml(account.botId || account.accountId)}</code></dd></div>
206
+ <div><dt>User ID</dt><dd><code title="${escapeAttr(account.userId || "未返回")}">${escapeHtml(account.userId || "未返回")}</code></dd></div>
207
+ </dl>
208
+ </details>
178
209
  <div class="account-detail">${renderAuthorizationState(account, pendingSender)}</div>
179
210
  ${authorized && pendingSender ? `<div class="pending-access"><div><strong>新的微信访问请求</strong><span>当前授权不受影响,可选择允许新的访问</span></div><button class="button button-secondary" type="button" data-account-action="allow" data-account-id="${escapeAttr(account.accountId)}" data-sender-id="${escapeAttr(pendingSender)}"><i data-lucide="user-check"></i><span>允许访问</span></button></div>` : ""}
180
211
  ${account.error ? `<div class="pending-access"><div><strong>账号运行错误</strong><span>${escapeHtml(account.error)}</span></div></div>` : ""}
@@ -481,13 +512,14 @@ async function loadSelectedSessionMessages() {
481
512
 
482
513
  function renderChatPanel() {
483
514
  const session = selectedSession();
484
- const enabled = Boolean(session) && !state.sendingMessage;
515
+ const enabled = Boolean(session) && !state.sendingMessage && !state.savingSessionRuntime;
485
516
  els.chatInput.disabled = !enabled;
486
517
  els.chatAttachButton.disabled = !enabled;
487
518
  els.chatFileInput.disabled = !enabled;
488
519
  els.refreshMessagesButton.disabled = !session || state.loadingMessages || state.sendingMessage;
489
520
  renderComposerFiles();
490
521
  updateComposerState();
522
+ renderSessionRuntimeControls(session);
491
523
  if (!session) {
492
524
  els.chatTitle.textContent = "选择一个会话";
493
525
  els.chatContext.textContent = "查看历史消息并继续聊天";
@@ -522,6 +554,112 @@ function renderChatPanel() {
522
554
  setChatMessagesHtml(html, renderKey);
523
555
  }
524
556
 
557
+ function renderSessionRuntimeControls(session) {
558
+ const disabled = !session || state.sendingMessage || state.savingSessionRuntime;
559
+ els.sessionModelInput.disabled = disabled;
560
+ els.sessionEffortInput.disabled = disabled;
561
+ const renderKey = session ? [
562
+ sessionKey(session),
563
+ session.model || "",
564
+ session.effort || "",
565
+ state.config?.model || "",
566
+ state.config?.effort || "",
567
+ state.codexRuntime?.model || "",
568
+ state.codexRuntime?.effort || "",
569
+ state.codexModels.length
570
+ ].join("|") : "none";
571
+ if (els.sessionRuntimeToolbar.dataset.renderKey === renderKey) return;
572
+ els.sessionRuntimeToolbar.dataset.renderKey = renderKey;
573
+
574
+ if (!session) {
575
+ els.sessionModelInput.innerHTML = '<option value="">选择会话后设置</option>';
576
+ els.sessionEffortInput.innerHTML = '<option value="">选择会话后设置</option>';
577
+ return;
578
+ }
579
+
580
+ const inheritedModel = state.config?.model || state.codexRuntime?.model || "";
581
+ const models = Array.isArray(state.codexModels) ? state.codexModels : [];
582
+ const options = [{
583
+ value: "",
584
+ label: inheritedModel ? `继承全局(${inheritedModel})` : "继承全局设置"
585
+ }, ...models.map((model) => ({
586
+ value: model.model,
587
+ label: model.displayName && model.displayName !== model.model
588
+ ? `${model.displayName} · ${model.model}`
589
+ : model.model,
590
+ title: model.description || ""
591
+ }))];
592
+ if (session.model && !options.some((option) => option.value === session.model)) {
593
+ options.push({ value: session.model, label: `${session.model}(当前会话)`, title: "" });
594
+ }
595
+ els.sessionModelInput.innerHTML = options.map((option) => `<option value="${escapeAttr(option.value)}"${option.title ? ` title="${escapeAttr(option.title)}"` : ""}>${escapeHtml(option.label)}</option>`).join("");
596
+ els.sessionModelInput.value = session.model || "";
597
+ setSessionEffortOptions(session.model || "", session.effort || "");
598
+ }
599
+
600
+ function setSessionEffortOptions(modelOverride, preferredEffort) {
601
+ const effectiveModel = modelOverride || state.config?.model || state.codexRuntime?.model || "";
602
+ const model = state.codexModels.find((candidate) => candidate.model === effectiveModel);
603
+ const advertised = model?.supportedEfforts?.length
604
+ ? model.supportedEfforts
605
+ : state.codexModels.flatMap((candidate) => candidate.supportedEfforts || []);
606
+ const efforts = [...new Map(advertised.map((option) => [option.effort, option])).values()]
607
+ .sort((a, b) => effortRank(a.effort) - effortRank(b.effort));
608
+ if (preferredEffort && !efforts.some((option) => option.effort === preferredEffort)) {
609
+ efforts.push({ effort: preferredEffort, description: "当前会话" });
610
+ }
611
+ const inheritedEffort = state.config?.effort || state.codexRuntime?.effort || model?.defaultEffort;
612
+ const inheritedLabel = inheritedEffort
613
+ ? `继承全局(${effortInlineName(inheritedEffort)})`
614
+ : "继承全局设置";
615
+ els.sessionEffortInput.innerHTML = [
616
+ `<option value="">${escapeHtml(inheritedLabel)}</option>`,
617
+ ...efforts.map((option) => `<option value="${escapeAttr(option.effort)}"${option.description ? ` title="${escapeAttr(option.description)}"` : ""}>${escapeHtml(effortDisplayName(option.effort))}</option>`)
618
+ ].join("");
619
+ els.sessionEffortInput.value = preferredEffort;
620
+ }
621
+
622
+ async function handleSessionModelChange() {
623
+ const modelValue = els.sessionModelInput.value;
624
+ const model = state.codexModels.find((candidate) => candidate.model === (modelValue || state.config?.model || state.codexRuntime?.model));
625
+ const efforts = model?.supportedEfforts?.map((option) => option.effort) || [];
626
+ let effortValue = els.sessionEffortInput.value;
627
+ const inheritedEffort = state.config?.effort || state.codexRuntime?.effort || "";
628
+ const effectiveEffort = effortValue || inheritedEffort;
629
+ if (effectiveEffort && efforts.length && !efforts.includes(effectiveEffort)) {
630
+ effortValue = efforts.includes(model?.defaultEffort) ? model.defaultEffort : efforts[0] || "";
631
+ }
632
+ setSessionEffortOptions(modelValue, effortValue);
633
+ await saveSessionRuntimeSettings();
634
+ }
635
+
636
+ async function saveSessionRuntimeSettings() {
637
+ const session = selectedSession();
638
+ if (!session || state.savingSessionRuntime) return;
639
+ const key = sessionKey(session);
640
+ const model = els.sessionModelInput.value;
641
+ const effort = els.sessionEffortInput.value;
642
+ state.savingSessionRuntime = true;
643
+ renderChatPanel();
644
+ try {
645
+ const result = await api(`/api/sessions/${encodeURIComponent(session.accountId)}/${encodeURIComponent(session.id)}`, {
646
+ method: "PATCH",
647
+ body: { model: model || null, effort: effort || null }
648
+ });
649
+ const index = state.sessions.findIndex((candidate) => sessionKey(candidate) === key);
650
+ if (index >= 0) state.sessions[index] = result.session;
651
+ els.sessionRuntimeToolbar.dataset.renderKey = "";
652
+ renderSessions();
653
+ toast("会话模型设置已更新");
654
+ } catch (error) {
655
+ toast(error.message, true);
656
+ await refreshData(false);
657
+ } finally {
658
+ state.savingSessionRuntime = false;
659
+ renderChatPanel();
660
+ }
661
+ }
662
+
525
663
  function renderTypingIndicator() {
526
664
  return `<div class="chat-typing" role="status" aria-label="对方正在输入">
527
665
  <span class="typing-dots" aria-hidden="true"><i></i><i></i><i></i></span>
@@ -659,7 +797,7 @@ function renderComposerFiles() {
659
797
  }
660
798
 
661
799
  function updateComposerState() {
662
- const canCompose = Boolean(selectedSession()) && !state.sendingMessage;
800
+ const canCompose = Boolean(selectedSession()) && !state.sendingMessage && !state.savingSessionRuntime;
663
801
  els.chatInput.disabled = !canCompose;
664
802
  els.chatAttachButton.disabled = !canCompose;
665
803
  els.chatFileInput.disabled = !canCompose;
@@ -20,6 +20,7 @@
20
20
  <i data-lucide="message-circle"></i>
21
21
  </span>
22
22
  <span class="brand-name">codex-weixin</span>
23
+ <span class="brand-version" id="productVersion" aria-label="codex-weixin 版本" hidden></span>
23
24
  </a>
24
25
  <nav class="view-tabs" aria-label="管理视图">
25
26
  <button class="tab is-active" type="button" data-view="accounts">微信账号</button>
@@ -92,6 +93,17 @@
92
93
  <i data-lucide="refresh-cw"></i>
93
94
  </button>
94
95
  </header>
96
+ <div class="chat-runtime-toolbar" id="sessionRuntimeToolbar" aria-label="当前会话模型设置">
97
+ <span class="chat-runtime-title"><i data-lucide="sliders-horizontal"></i><span>会话设置</span></span>
98
+ <label>
99
+ <span>模型</span>
100
+ <select id="sessionModelInput" disabled><option value="">继承全局设置</option></select>
101
+ </label>
102
+ <label>
103
+ <span>推理强度</span>
104
+ <select id="sessionEffortInput" disabled><option value="">继承全局设置</option></select>
105
+ </label>
106
+ </div>
95
107
  <div class="chat-messages" id="chatMessages" aria-live="polite"></div>
96
108
  <form class="chat-composer" id="chatComposer">
97
109
  <div class="composer-files" id="composerFiles" aria-live="polite" hidden></div>
@@ -38,6 +38,8 @@ button:disabled { cursor: not-allowed; opacity: .48; }
38
38
  .brand-mark svg:first-child { left: 6px; top: 6px; }
39
39
  .brand-mark svg:last-child { right: 3px; bottom: 3px; padding: 2px; color: white; border-radius: 50%; background: var(--green); }
40
40
  .brand-name { overflow: hidden; font-size: 15px; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
41
+ .brand-version { min-width: max-content; padding: 3px 6px; border: 1px solid #b9c5bd; border-radius: 4px; color: var(--ink-soft); background: #f5f7f5; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 9px; font-weight: 700; line-height: 1; }
42
+ .brand-version[hidden] { display: none; }
41
43
  .view-tabs { height: 38px; display: inline-flex; align-items: center; padding: 3px; gap: 2px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--canvas); }
42
44
  .tab { min-width: 82px; height: 30px; border: 0; border-radius: 4px; color: var(--ink-soft); background: transparent; font-size: 13px; font-weight: 650; }
43
45
  .tab:hover { color: var(--ink); }
@@ -94,6 +96,21 @@ h2 { margin: 0; font-size: 19px; line-height: 1.3; }
94
96
  .account-stat span { display: block; color: var(--ink-soft); font-size: 11px; }
95
97
  .account-stat strong { display: block; margin-top: 4px; font-size: 15px; }
96
98
  .account-actions { display: flex; gap: 8px; }
99
+ .account-identifiers { border-top: 1px solid var(--line); background: #fcfdfc; }
100
+ .account-identifiers summary { min-height: 46px; padding: 9px 20px; color: var(--ink-soft); cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
101
+ .account-identifiers summary::-webkit-details-marker { display: none; }
102
+ .account-identifiers summary:hover { color: var(--ink); background: #f7f9f7; }
103
+ .account-identifiers-title { min-width: 0; display: flex; align-items: center; gap: 8px; }
104
+ .account-identifiers-title > svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--green-dark); }
105
+ .account-identifiers-title strong { color: var(--ink); font-size: 11px; }
106
+ .account-identifiers-title small { overflow: hidden; font-size: 9px; font-weight: 550; text-overflow: ellipsis; white-space: nowrap; }
107
+ .account-identifiers-chevron { width: 15px; height: 15px; flex: 0 0 auto; transition: transform .16s ease; }
108
+ .account-identifiers[open] .account-identifiers-chevron { transform: rotate(180deg); }
109
+ .account-identifiers-grid { margin: 0; padding: 2px 20px 15px 43px; display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; }
110
+ .account-identifiers-grid div { min-width: 0; }
111
+ .account-identifiers-grid dt { margin-bottom: 4px; color: var(--ink-soft); font-size: 9px; font-weight: 750; text-transform: uppercase; }
112
+ .account-identifiers-grid dd { margin: 0; }
113
+ .account-identifiers-grid code { color: #26302c; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 10px; line-height: 1.5; overflow-wrap: anywhere; user-select: all; }
97
114
  .account-detail { padding: 14px 20px; border-top: 1px solid var(--line); background: #fafbfa; display: flex; align-items: center; justify-content: space-between; gap: 18px; }
98
115
  .authorization-state { width: 100%; min-width: 0; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
99
116
  .authorization-icon { width: 34px; height: 34px; border-radius: 50%; color: var(--ink-soft); background: var(--surface-muted); display: grid; place-items: center; }
@@ -143,10 +160,16 @@ h2 { margin: 0; font-size: 19px; line-height: 1.3; }
143
160
  .session-actions .icon-button { width: 29px; height: 29px; background: transparent; }
144
161
  .session-actions .icon-button svg { width: 15px; height: 15px; }
145
162
 
146
- .chat-panel { min-width: 0; min-height: 650px; background: linear-gradient(180deg, #fff 0, #fbfcfb 100%); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
163
+ .chat-panel { min-width: 0; min-height: 650px; background: linear-gradient(180deg, #fff 0, #fbfcfb 100%); display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto; }
147
164
  .chat-header { min-height: 82px; padding: 17px 20px; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 18px; }
148
165
  .chat-header h2 { max-width: 620px; overflow: hidden; font-size: 17px; text-overflow: ellipsis; white-space: nowrap; }
149
166
  .chat-context { max-width: 720px; margin: 5px 0 0; overflow: hidden; color: var(--ink-soft); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 9px; text-overflow: ellipsis; white-space: nowrap; }
167
+ .chat-runtime-toolbar { min-height: 54px; padding: 9px 20px; border-bottom: 1px solid var(--line); background: #f7f9f7; display: grid; grid-template-columns: auto minmax(190px, 1fr) minmax(170px, .72fr); align-items: center; gap: 14px; }
168
+ .chat-runtime-title { color: var(--ink-soft); display: inline-flex; align-items: center; gap: 6px; font-size: 9px; font-weight: 800; letter-spacing: .04em; white-space: nowrap; }
169
+ .chat-runtime-title svg { width: 14px; height: 14px; color: var(--green-dark); }
170
+ .chat-runtime-toolbar label { min-width: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 7px; }
171
+ .chat-runtime-toolbar label > span { font-size: 9px; white-space: nowrap; }
172
+ .chat-runtime-toolbar select { min-width: 0; min-height: 32px; height: 32px; padding-inline: 9px 28px; font-size: 10px; }
150
173
  .chat-messages { min-height: 0; max-height: 560px; padding: 26px 24px 30px; overflow-y: auto; scroll-behavior: smooth; background-image: radial-gradient(circle at 1px 1px, rgb(31 57 44 / 5%) 1px, transparent 0); background-size: 24px 24px; }
151
174
  .chat-message { width: fit-content; min-width: 0; max-width: min(78%, 720px); margin-bottom: 22px; display: grid; gap: 6px; }
152
175
  .chat-message.is-user { margin-left: auto; justify-items: end; }
@@ -284,6 +307,7 @@ input:focus, select:focus, textarea:focus { border-color: var(--focus); outline:
284
307
  .header-inner, .status-inner, .view { width: min(calc(100% - 24px), var(--content)); }
285
308
  .header-inner { min-height: 62px; gap: 12px; }
286
309
  .brand-name { max-width: 178px; font-size: 13px; }
310
+ .brand-version { padding-inline: 5px; font-size: 8px; }
287
311
  .brand-mark { width: 34px; height: 34px; flex-basis: 34px; }
288
312
  .header-action { width: 38px; padding: 0; }
289
313
  .header-action span { display: none; }
@@ -297,6 +321,8 @@ input:focus, select:focus, textarea:focus { border-color: var(--focus); outline:
297
321
  .account-main .account-stat { display: none; }
298
322
  .account-actions { grid-column: 2; grid-row: 1; }
299
323
  .account-detail, .pending-access { padding: 12px 16px; align-items: start; flex-direction: column; }
324
+ .account-identifiers summary { padding-inline: 16px; }
325
+ .account-identifiers-grid { padding: 2px 16px 14px 39px; grid-template-columns: 1fr; gap: 10px; }
300
326
  .authorization-state { grid-template-columns: auto minmax(0, 1fr); }
301
327
  .authorization-action { width: 100%; grid-column: 1 / -1; }
302
328
  .pending-access .button { width: 100%; }
@@ -304,6 +330,9 @@ input:focus, select:focus, textarea:focus { border-color: var(--focus); outline:
304
330
  .session-account-bar-label { padding-inline: 2px; }
305
331
  .session-account-tabs { width: 100%; }
306
332
  .chat-header { padding: 15px 16px; }
333
+ .chat-runtime-toolbar { padding: 10px 12px; grid-template-columns: 1fr 1fr; gap: 8px; }
334
+ .chat-runtime-title { grid-column: 1 / -1; }
335
+ .chat-runtime-toolbar label { grid-template-columns: 1fr; gap: 4px; }
307
336
  .chat-messages { padding: 22px 14px 26px; }
308
337
  .chat-message { max-width: 92%; }
309
338
  .chat-composer { padding-inline: 12px; }
@@ -1,6 +1,7 @@
1
1
  import type { StatePaths } from "../state/paths.js";
2
2
  export type WeixinAccount = {
3
3
  accountId: string;
4
+ botId?: string;
4
5
  token: string;
5
6
  baseUrl: string;
6
7
  cdnBaseUrl: string;
@@ -13,6 +14,11 @@ export declare const DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com";
13
14
  export declare const DEFAULT_CDN_BASE_URL = "https://novac2c.cdn.weixin.qq.com/c2c";
14
15
  export declare function normalizeAccountId(raw: string): string;
15
16
  export declare function saveAccount(paths: StatePaths, account: WeixinAccount): void;
17
+ export type SaveScannedAccountResult = {
18
+ account: WeixinAccount;
19
+ reusedExisting: boolean;
20
+ };
21
+ export declare function saveScannedAccount(paths: StatePaths, scanned: WeixinAccount, targetAccountId?: string): SaveScannedAccountResult;
16
22
  export declare function listAccounts(paths: StatePaths): WeixinAccount[];
17
23
  export declare function setAccountEnabled(paths: StatePaths, accountId: string, enabled: boolean): WeixinAccount;
18
24
  export declare function setAccountDisplayName(paths: StatePaths, accountId: string, displayName: string): WeixinAccount;
@@ -10,6 +10,29 @@ export function saveAccount(paths, account) {
10
10
  ensureDir(paths.accountsDir);
11
11
  writeJsonFile(path.join(paths.accountsDir, `${normalizeAccountId(account.accountId)}.json`), account);
12
12
  }
13
+ export function saveScannedAccount(paths, scanned, targetAccountId) {
14
+ const accounts = listAccounts(paths);
15
+ const target = targetAccountId ? loadAccount(paths, targetAccountId) : undefined;
16
+ if (target?.userId && scanned.userId && target.userId !== scanned.userId) {
17
+ throw new Error("The scanned WeChat account does not match the existing account");
18
+ }
19
+ const exact = accounts.find((account) => account.accountId === scanned.accountId);
20
+ const sameUsers = scanned.userId
21
+ ? accounts.filter((account) => account.userId === scanned.userId)
22
+ : [];
23
+ const existing = target ?? exact ?? (sameUsers.length === 1 ? sameUsers[0] : undefined);
24
+ const botId = scanned.botId ?? scanned.accountId;
25
+ const account = existing ? {
26
+ ...scanned,
27
+ accountId: existing.accountId,
28
+ botId,
29
+ userId: scanned.userId ?? existing.userId,
30
+ ...(existing.displayName ? { displayName: existing.displayName } : {}),
31
+ enabled: true
32
+ } : { ...scanned, botId };
33
+ saveAccount(paths, account);
34
+ return { account, reusedExisting: Boolean(existing) };
35
+ }
13
36
  export function listAccounts(paths) {
14
37
  ensureDir(paths.accountsDir);
15
38
  return fs.readdirSync(paths.accountsDir)
@@ -1 +1 @@
1
- {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/weixin/accounts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/weixin/accounts.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { DEFAULT_BASE_URL, DEFAULT_CDN_BASE_URL, saveAccount } from "./accounts.js";
1
+ import { DEFAULT_BASE_URL, DEFAULT_CDN_BASE_URL, saveScannedAccount } from "./accounts.js";
2
2
  export class WeixinQrLoginSession {
3
3
  qrContent;
4
4
  qrToken;
@@ -60,8 +60,7 @@ export async function loginWithQr(options) {
60
60
  throw new Error("WeChat QR code expired. Start login again.");
61
61
  }
62
62
  if (update.status === "confirmed") {
63
- saveAccount(options.paths, update.account);
64
- return update.account;
63
+ return saveScannedAccount(options.paths, update.account).account;
65
64
  }
66
65
  }
67
66
  }
@@ -71,6 +70,7 @@ function accountFromStatus(status, pollBaseUrl) {
71
70
  }
72
71
  return {
73
72
  accountId: status.ilink_bot_id,
73
+ botId: status.ilink_bot_id,
74
74
  token: status.bot_token,
75
75
  userId: status.ilink_user_id,
76
76
  baseUrl: status.baseurl ?? status.base_url ?? pollBaseUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/weixin/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/weixin/login.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-weixin",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Local multi-account WeChat server for OpenAI Codex.",
5
5
  "license": "MIT",
6
6
  "author": "Xuechao Zou",