@cxyhhhhh/dsh-qqbot 0.5.4-dev.202610302146 → 0.5.4-dev.202610302325

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/lib/client.js CHANGED
@@ -795,7 +795,7 @@ window.__ModuleLoader__.load({
795
795
  }, "正在加载配置…");
796
796
  const dirty = Object.keys(form).some((key) => !shallowEqual(form[key], initial[key]));
797
797
  const access = form.access ?? {
798
- c2cMode: "allowlist",
798
+ c2cMode: "open",
799
799
  c2cAllow: [],
800
800
  groupMode: "open",
801
801
  groupAllow: []
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["STYLE_ID","useState","useRef","useCallback","createElement","createElement","useState","useCallback","createElement"],"sources":["../src/shared/bind-protocol.ts","../src/client/bind-page.ts","../src/client/config-panel.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 端内绑定协议 —— 宿主路由与客户端面板的共享契约\n *\n * 类型与路径常量的唯一事实源:宿主(setup/bind-routes.ts)与浏览器\n * (client/bind-page.ts)各自 import,杜绝两端协议漂移。\n * 本模块必须保持纯类型 + 纯常量(零 node 依赖、零副作用):\n * 客户端 tsdown 构建会将其内联进 bundle。\n */\n\n/** 状态查询(绑定页轮询) */\nexport const BIND_STATE_PATH = '/qqbot/im-qqbot/bind';\n\n/** 刷新二维码(绑定页按钮) */\nexport const BIND_REFRESH_PATH = '/qqbot/im-qqbot/bind/refresh';\n\n/** 手动填写/编辑凭据(绑定页表单) */\nexport const BIND_MANUAL_PATH = '/qqbot/im-qqbot/bind/manual';\n\n/** 解绑:移除已保存凭据,回到绑定流程 */\nexport const BIND_UNBIND_PATH = '/qqbot/im-qqbot/bind/unbind';\n\n/** 配置读写(设置面板表单) */\nexport const BIND_CONFIG_PATH = '/qqbot/im-qqbot/config';\n\n/** 线上协议(HTTP 路由序列化形态) */\nexport type BindStateWire =\n | { phase: 'starting' }\n | { phase: 'waiting'; url: string; qrSvg?: string; issuedAt: number }\n | { phase: 'saving' }\n | { phase: 'failed'; reason: string }\n | { phase: 'bound'; appId: string };\n\n/** manual / unbind 操作的统一响应 */\nexport interface BindActionResponse {\n ok: boolean;\n message?: string;\n error?: string;\n}\n","/**\n * 端内绑定面板 — 扫码 / 手动填写 / 已绑定编辑\n *\n * 宿主插件注册 /qqbot/im-qqbot/bind 路由(待绑定与已绑定 fiber 均常驻):\n * - 未绑定:waiting(二维码)/ starting / saving / failed 相位 + manual 提交\n * - 已绑定:bound 相位(回显脱敏 appId,secret 不回传)+ manual 更换 + 解绑\n * 扫码成功或手动保存均写入 profile patch 并经 HMR 重载生效。\n *\n * 样式为注入式 CSS 类(imqb-* 命名空间,随面板挂载注入一次):\n * hover/过渡/focus 样式无法用 inline style 表达,统一走类;\n * 颜色尽量取 DSW 主题变量(--dsw-alias-*),缺省值兜底。\n *\n * 同一组件复用于两种展示位(侧栏绑定页 / 设置页 QQ Bot 栏目)。\n * 运行时仅依赖 react(dsh 客户端平台种子表提供);宿主通信走同源 fetch,\n * Desktop 下由壳的 IPC 桥自动附加 Host 认证转发。\n */\nimport { createElement, useCallback, useEffect, useRef, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n BIND_MANUAL_PATH,\n BIND_REFRESH_PATH,\n BIND_STATE_PATH,\n BIND_UNBIND_PATH,\n type BindStateWire,\n} from '../shared/bind-protocol.ts';\n\n/** 轮询间隔(毫秒):活跃轮询 / 失败退避 */\nconst ACTIVE_POLL_MS = 2000;\nconst RETRY_POLL_MS = 3000;\n\n/** 样式注入标记(幂等) */\nconst STYLE_ID = 'im-qqbot-bind-panel-styles';\n\n/**\n * 注入面板样式(全局一次,幂等)。交互态(hover/active/focus)无法用 inline\n * style 表达,统一收敛到类;DSW 主题变量缺失时用中性值兜底。\n * 插件激活时即安装:插件详情按钮渲染在面板之外,需提前可见;\n * 安装后不再随挂载移除,避免多个展示位互相清掉样式。\n */\nexport function installPanelStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = `\n.imqb-panel {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n gap: 14px; padding: 24px; min-height: 320px; text-align: center; font-size: 14px;\n}\n.imqb-title { margin: 0; font-size: 16px; font-weight: 600; }\n.imqb-hint { margin: 0; opacity: 0.75; line-height: 1.6; }\n.imqb-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }\n.imqb-link { font-size: 13px; opacity: 0.85; color: var(--dsw-alias-brand, #4d6bfe); text-decoration: none; }\n.imqb-link:hover { text-decoration: underline; }\n.imqb-icon { font-size: 32px; line-height: 1; }\n.imqb-qr { border-radius: 10px; background: #fff; padding: 10px; max-width: 100%; }\n.imqb-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }\n.imqb-btn, .imqb-pill {\n font: inherit; cursor: pointer; color: inherit;\n transition: background-color .15s ease, border-color .15s ease, color .15s ease, opacity .15s ease;\n}\n.imqb-btn:disabled, .imqb-pill:disabled { opacity: 0.5; cursor: default; }\n.imqb-btn {\n padding: 7px 18px; border-radius: 8px; font-size: 13px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n background: transparent;\n}\n.imqb-btn:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-btn--primary {\n border-color: transparent;\n background: var(--dsw-alias-brand, #4d6bfe); color: #fff; font-weight: 500;\n}\n.imqb-btn--primary:hover:not(:disabled) { background: var(--dsw-alias-brand-strong, #3b5cf0); }\n.imqb-btn--danger { color: var(--dsw-alias-danger, #f26d6d); border-color: var(--dsw-alias-danger, rgba(242, 109, 109, 0.5)); }\n.imqb-btn--danger:hover:not(:disabled) { background: var(--dsw-alias-danger, rgba(242, 109, 109, 0.12)); }\n.imqb-ghost {\n border: none; background: transparent; opacity: 0.65; padding: 4px 8px;\n font: inherit; font-size: 13px; cursor: pointer; color: inherit;\n}\n.imqb-ghost:hover { opacity: 1; text-decoration: underline; }\n/* 插件详情「设置」按钮:30px,略高于旁边的 sm 次要按钮 */\n.imqb-pluginOpen {\n display: inline-flex; align-items: center; justify-content: center;\n box-sizing: border-box; height: 30px; padding: 0 14px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n border-radius: 8px; background: var(--dsw-alias-bg-layer-1, transparent);\n color: var(--dsw-alias-label-primary, inherit); font: inherit;\n font-size: 13px; line-height: 20px; cursor: pointer;\n}\n.imqb-pluginOpen:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-pluginOpen:focus-visible { outline: 2px solid var(--dsw-alias-brand, #4d6bfe); outline-offset: 3px; }\n@media (pointer: coarse) { .imqb-pluginOpen { height: 44px; } }\n/* 主面板页面容器(layout.selectPanel 目标):滚动 + 留白 */\n.imqb-pluginPage {\n height: 100%; min-height: 0; overflow: auto; box-sizing: border-box;\n padding: 24px clamp(16px, 4vw, 48px) 32px;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n.imqb-pluginPageContent { max-width: 1080px; margin: 0 auto; }\n.imqb-pill {\n padding: 5px 16px; border-radius: 999px; font-size: 13px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4)); background: transparent;\n}\n.imqb-pill:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-btn:focus-visible, .imqb-pill:focus-visible, .imqb-input:focus-visible, .imqb-ghost:focus-visible {\n outline: 2px solid var(--dsw-alias-brand, #4d6bfe); outline-offset: 1px;\n}\n.imqb-form { display: flex; flex-direction: column; gap: 12px; width: min(320px, 100%); box-sizing: border-box; }\n.imqb-field { display: flex; flex-direction: column; gap: 5px; text-align: left; font-size: 13px; }\n.imqb-input {\n padding: 8px 10px; border-radius: 8px; box-sizing: border-box; width: 100%;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n background: var(--dsw-alias-bg-input, rgba(128, 128, 128, 0.08));\n color: inherit; font: inherit; font-size: 13px; outline: none;\n}\n.imqb-input:focus { border-color: var(--dsw-alias-brand, #4d6bfe); }\n.imqb-error { margin: 0; font-size: 12px; color: var(--dsw-alias-danger, #f26d6d); }\n/* 紧凑状态视图(已绑定 / 过渡态):设置行风格,无居中大卡留白 */\n.imqb-status { display: flex; flex-direction: column; text-align: left; font-size: 14px; }\n.imqb-status-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; }\n.imqb-status-icon { font-size: 24px; line-height: 1; flex: none; }\n.imqb-qqicon {\n flex: none; display: block; border-radius: 8px; /* 透明底,QQ 蓝徽标在明暗主题下均清晰 */\n}\n.imqb-status-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }\n.imqb-status-title { margin: 0; font-size: 14px; font-weight: 600; line-height: 1.5; }\n.imqb-status-sub { margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary, inherit); opacity: .85; }\n.imqb-status-actions { display: flex; align-items: center; gap: 8px; padding: 4px 0 12px; }\n/* 扫码成功后的连接过渡:二维码模糊变暗 + 覆盖层 */\n.imqb-scanned { position: relative; display: inline-block; }\n.imqb-scanned-qr {\n display: block; border-radius: 10px; background: #fff; padding: 10px;\n filter: blur(6px) saturate(0.6); opacity: 0.55;\n}\n.imqb-scanned-veil {\n position: absolute; inset: 0; display: flex; flex-direction: column;\n align-items: center; justify-content: center; gap: 6px; text-align: center;\n}\n.imqb-scanned-title { margin: 0; font-size: 15px; font-weight: 600; }\n.imqb-scanned-sub { margin: 0; font-size: 12px; opacity: 0.75; line-height: 1.6; }\n `;\n document.head.appendChild(style);\n}\n\nfunction usePanelStyles(): void {\n useEffect(() => { installPanelStyles(); }, []);\n}\n\n/**\n * 绑定状态轮询 hook。\n *\n * 404 语义分两种:从未拿到过路由 = 插件未启用(终态);\n * 曾经拿到过 = HMR 重载窗口期(manual/unbind 保存后路由短暂消失),\n * 低频等待恢复而不是判定终态——否则保存成功提示会被\n * 「插件未启用」覆盖且无法自愈。\n *\n * bound 为稳定态:轮询大幅降频(30s)。因此解绑等本地动作后必须\n * 调用 recheck() 立即重置节拍——否则视图最长停留 30s+ 才收敛到\n * 新相位(如解绑后的 waiting 二维码)。\n *\n * @returns 轮询快照与 recheck:state 为宿主相位(null = 加载中),\n * gone 表示插件未启用(从未注册过路由),recheck 废弃当前\n * 定时器并立即重新轮询(新轮询链取代旧链,不产生双计时器)。\n */\nexport function useBindState(enabled = true): { state: BindStateWire | null; gone: boolean; recheck: () => void } {\n const [state, setState] = useState<BindStateWire | null>(null);\n const [gone, setGone] = useState(false);\n const recheckRef = useRef<() => void>(() => {});\n\n useEffect(() => {\n if (!enabled) return;\n let stopped = false;\n let sawRoute = false;\n let generation = 0;\n let running = false;\n let restartAfterFlight = false;\n // recheck 后的快速收敛窗口:解绑等动作改变的是服务端状态(经\n // HMR 异步生效),动作后立即轮询拿到的可能仍是旧 fiber 的相位\n // (如 bound→30s 降频),窗口期内强制快轮询直到相位真正变化\n let urgentUntil = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const intervalFor = (phase: BindStateWire['phase']): number => {\n const base = phase === 'saving' ? 500 : phase === 'bound' ? 30000 : ACTIVE_POLL_MS;\n return Date.now() < urgentUntil ? Math.min(base, ACTIVE_POLL_MS) : base;\n };\n\n const tick = async (): Promise<void> => {\n if (stopped || running) return;\n running = true;\n const myGeneration = generation;\n const alive = (): boolean => myGeneration === generation && !stopped;\n try {\n const res = await fetch(BIND_STATE_PATH, { cache: 'no-store' });\n if (res.status === 404) {\n if (!stopped && !sawRoute) setGone(true);\n // sawRoute:HMR 窗口期,保留当前视图等待路由恢复\n else if (alive()) schedule(Date.now() < urgentUntil ? 1000 : 3000);\n return;\n }\n if (!res.ok) {\n if (alive()) schedule(RETRY_POLL_MS);\n return;\n }\n sawRoute = true;\n const body = (await res.json()) as BindStateWire;\n if (!alive()) return;\n setState(body);\n schedule(intervalFor(body.phase));\n return;\n } catch {\n // 宿主启动窗口期不可达:退避重试\n } finally {\n running = false;\n // 在飞期间被 recheck 取代:接力启动新轮询链(否则链会断)\n if (restartAfterFlight && !stopped) {\n restartAfterFlight = false;\n void tick();\n }\n }\n if (alive()) schedule(RETRY_POLL_MS);\n };\n\n // 立即重置节拍:废弃当前计时器,旧轮询链(在飞请求)作废,\n // 新链立即发起,并进入快速收敛窗口\n recheckRef.current = (): void => {\n generation += 1;\n urgentUntil = Date.now() + 15000;\n if (timer !== undefined) clearTimeout(timer);\n if (running) {\n restartAfterFlight = true;\n return;\n }\n void tick();\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n }, []);\n\n const recheck = useCallback((): void => { recheckRef.current(); }, []);\n\n return { state, gone, recheck };\n}\n\ninterface ManualResult { ok: boolean; message?: string; error?: string }\n\n/** 手动提交凭据(填写 / 更换共用) */\nasync function submitManualCredentials(appId: string, appSecret: string): Promise<ManualResult> {\n try {\n const res = await fetch(BIND_MANUAL_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ appId, appSecret }),\n });\n const body = (await res.json().catch(() => ({}))) as ManualResult;\n if (res.ok && body.ok) return { ok: true, message: body.message };\n return { ok: false, error: body.error ?? `保存失败(HTTP ${res.status})` };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\n/**\n * 手动凭据表单(填写 / 更换共用)。\n *\n * appSecret 永不回显(占位符提示),提交成功后展示保存结果;\n * 宿主写入 profile patch 并经 HMR 重载,状态轮询随后收敛为 bound。\n */\nfunction ManualForm({ initialAppId }: { initialAppId?: string }): ReactNode {\n const [appId, setAppId] = useState(initialAppId ?? '');\n const [appSecret, setAppSecret] = useState('');\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<ManualResult | null>(null);\n\n const submit = useCallback((event: FormEvent): void => {\n event.preventDefault();\n if (busy) return;\n const trimmedId = appId.trim();\n const trimmedSecret = appSecret.trim();\n if (trimmedId.length === 0 || trimmedSecret.length === 0) {\n setResult({ ok: false, error: 'appId 与 appSecret 均为必填' });\n return;\n }\n setBusy(true);\n void submitManualCredentials(trimmedId, trimmedSecret).then((outcome) => {\n setResult(outcome);\n setBusy(false);\n });\n }, [appId, appSecret, busy]);\n\n if (result !== null && result.ok) {\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, '✅'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, result.message ?? '凭据已保存'),\n createElement('p', { className: 'imqb-status-sub' }, '插件将自动重载;稍后即可开始对话'),\n ),\n ),\n );\n }\n\n return createElement('form', { className: 'imqb-form', onSubmit: submit },\n createElement('label', { className: 'imqb-field' },\n 'AppID',\n createElement('input', {\n className: 'imqb-input', value: appId, placeholder: 'QQ 机器人 AppID',\n onChange: (event) => { setAppId(event.currentTarget.value); },\n autoComplete: 'off', spellCheck: false,\n }),\n ),\n createElement('label', { className: 'imqb-field' },\n 'AppSecret',\n createElement('input', {\n className: 'imqb-input', type: 'password', value: appSecret,\n placeholder: initialAppId === undefined ? 'QQ 机器人 AppSecret' : '输入新的 AppSecret(不回显)',\n onChange: (event) => { setAppSecret(event.currentTarget.value); },\n autoComplete: 'new-password',\n }),\n ),\n result !== null && !result.ok\n ? createElement('p', { className: 'imqb-error' }, result.error)\n : null,\n createElement('button', { className: 'imqb-btn imqb-btn--primary', type: 'submit', disabled: busy },\n busy ? '正在保存…' : '保存'),\n );\n}\n\n/** QQ 机器人 logo 路径(assets/icons/qqbot_logo.svg,内嵌以保持 bundle 自包含) */\nexport const QQ_BOT_LOGO_PATH =\n 'M19.3862 15.5001C19.3861 11.4203 16.0789 8.11296 11.999 8.11292C7.91915 8.11292 4.61203 11.4203 4.61182 15.5001V17.0001C4.61182 18.5949 5.90429 19.8873 7.49902 19.8873H16.499C18.0937 19.8873 19.3862 18.5949 19.3862 17.0001V15.5001ZM10.6118 14.0001C10.6118 14.6145 10.1129 15.1134 9.49853 15.1134C8.8843 15.1132 8.38672 14.6144 8.38672 14.0001V12.0006C8.38672 11.3863 8.8843 10.8875 9.49853 10.8873C10.1129 10.8873 10.6118 11.3862 10.6118 12.0006V14.0001ZM15.6113 14.0001C15.6113 14.6143 15.1136 15.1131 14.4995 15.1134C13.8851 15.1134 13.3862 14.6145 13.3862 14.0001V12.0006C13.3862 11.3862 13.8851 10.8873 14.4995 10.8873C15.1136 10.8876 15.6113 11.3864 15.6113 12.0006V14.0001ZM14.2607 3.04895C14.2607 3.89351 13.7957 4.62474 13.1108 5.0133V5.95374C17.8958 6.50514 21.6112 10.5676 21.6113 15.5001V17.0001C21.6113 19.8237 19.3225 22.1124 16.499 22.1124H7.49902C4.67546 22.1124 2.38672 19.8237 2.38672 17.0001V15.5001C2.38691 10.568 6.10139 6.50571 10.8857 5.95374V5.01185C10.2017 4.62305 9.73583 3.89286 9.73583 3.04895C9.73609 1.79961 10.7496 0.787231 11.999 0.787231C13.2484 0.787297 14.2605 1.79966 14.2607 3.04895Z';\n\n/** QQ 机器人图标(logo 矢量渲染,透明底,随 size 缩放) */\nfunction QqBotIcon({ size = 28 }: { size?: number }): ReactNode {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 24 24', fill: 'none',\n 'aria-hidden': true, className: 'imqb-qqicon',\n },\n createElement('path', { d: QQ_BOT_LOGO_PATH, fill: '#0085FF' }),\n );\n}\n/** 已绑定视图:回显 appId + 更换凭据 / 解绑入口 */\nfunction BoundView({ appId, recheck }: { appId: string; recheck: () => void }): ReactNode {\n const [editing, setEditing] = useState(false);\n const [unbindResult, setUnbindResult] = useState<{ ok: boolean; message: string } | null>(null);\n\n const unbind = useCallback((): void => {\n if (!window.confirm('确定解绑吗?\\n解绑后机器人立即下线,插件将重新进入扫码绑定流程。')) return;\n void fetch(BIND_UNBIND_PATH, { method: 'POST' })\n .then(async (res) => {\n const body = (await res.json().catch(() => ({}))) as { ok?: boolean; message?: string; error?: string };\n if (res.ok && body.ok === true) {\n setUnbindResult({ ok: true, message: body.message ?? '已解绑,插件将重载并重新进入绑定流程' });\n // bound 态轮询已降频到 30s:立即重置节拍,让 waiting(二维码)\n // 尽快出现而不是等下一个 30s 周期\n recheck();\n return;\n }\n setUnbindResult({ ok: false, message: body.error ?? `解绑失败(HTTP ${res.status})` });\n })\n .catch((err: unknown) => {\n setUnbindResult({ ok: false, message: err instanceof Error ? err.message : String(err) });\n });\n }, [recheck]);\n\n if (unbindResult !== null) {\n // 非终态视图:解绑成功后正常由轮询收敛到 waiting;若 HMR 未\n // 触发(状态停留 bound),用户仍有「刷新状态」出口而不是死胡同\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, unbindResult.ok ? '👋' : '⚠️'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, unbindResult.message),\n ),\n unbindResult.ok\n ? createElement('button', { className: 'imqb-ghost', onClick: recheck }, '刷新状态')\n : createElement('button', { className: 'imqb-ghost', onClick: () => { setUnbindResult(null); } }, '返回'),\n ),\n );\n }\n\n if (editing) {\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '更换凭据'),\n ),\n createElement('button', { className: 'imqb-ghost', onClick: () => { setEditing(false); } }, '返回'),\n ),\n createElement(ManualForm, { initialAppId: appId }),\n );\n }\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement(QqBotIcon, { size: 28 }),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '已绑定'),\n createElement('p', { className: 'imqb-status-sub imqb-mono' }, `AppID ${appId} · 私聊与群聊已接入`),\n ),\n ),\n createElement('div', { className: 'imqb-status-actions' },\n createElement('button', { className: 'imqb-btn imqb-btn--primary', onClick: () => { setEditing(true); } }, '更换凭据'),\n createElement('button', { className: 'imqb-btn imqb-btn--danger', onClick: unbind }, '解绑'),\n ),\n );\n}\n\n/** 未绑定视图:扫码 / 手动填写切换 */\nfunction UnboundView({ state }: { state: Extract<BindStateWire, { phase: 'waiting' }> }): ReactNode {\n const [mode, setMode] = useState<'qr' | 'manual'>('qr');\n const refresh = useCallback(() => { void fetch(BIND_REFRESH_PATH, { method: 'POST' }).catch(() => {}); }, []);\n\n if (mode === 'manual') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('p', { className: 'imqb-title' }, '手动填写凭据'),\n createElement(ManualForm, {}),\n createElement('button', { className: 'imqb-ghost', onClick: () => { setMode('qr'); } }, '改用扫码绑定'),\n );\n }\n\n return createElement('div', { className: 'imqb-panel' },\n state.qrSvg === undefined\n ? null\n : createElement('img', { src: state.qrSvg, alt: 'QQ 扫码二维码', width: 220, height: 220, className: 'imqb-qr' }),\n createElement('p', { className: 'imqb-title' }, '扫码绑定 QQ 机器人'),\n createElement('p', { className: 'imqb-hint' }, '使用手机 QQ 扫描二维码完成绑定'),\n createElement('a', { href: state.url, target: '_blank', rel: 'noreferrer noopener', className: 'imqb-link' }, '二维码显示异常?在浏览器中打开'),\n createElement('div', { className: 'imqb-row' },\n createElement('button', { className: 'imqb-pill', onClick: refresh }, '刷新二维码'),\n createElement('button', { className: 'imqb-pill', onClick: () => { setMode('manual'); } }, '手动填写'),\n ),\n );\n}\n\n/** 依据宿主相位渲染面板主体(可注入共享轮询结果避免双计时器) */\nexport function BindPanelBody(props?: {\n state?: BindStateWire | null;\n gone?: boolean;\n recheck?: () => void;\n}): ReactNode {\n usePanelStyles();\n const injected = props?.state !== undefined;\n const internal = useBindState(!injected);\n const state = injected ? props.state : internal.state;\n const gone = injected ? (props.gone ?? false) : internal.gone;\n const recheck = injected ? (props.recheck ?? (() => {})) : internal.recheck;\n // 扫码成功的连接过渡场景需要保留最后一帧二维码:waiting 相位持续记录,\n // bound 后清空(避免下次解绑重绑时旧码闪现)\n const [lastQr, setLastQr] = useState<string | null>(null);\n useEffect(() => {\n if (state === null) return;\n if (state.phase === 'waiting') {\n if (state.qrSvg !== undefined) setLastQr(state.qrSvg);\n } else if (state.phase === 'bound') {\n setLastQr(null);\n }\n }, [state]);\n\n if (gone) {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-icon' }, '❔'),\n createElement('p', { className: 'imqb-hint' }, '插件未启用,或当前版本不支持端内配置'),\n );\n }\n\n if (state === null || state.phase === 'starting') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('p', { className: 'imqb-hint' }, '正在获取绑定状态…'),\n );\n }\n\n if (state.phase === 'saving') {\n // 扫码路径:保留二维码做模糊过渡(手动填写路径无二维码,用紧凑态)\n if (lastQr !== null) {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-scanned' },\n createElement('img', { src: lastQr, alt: 'QQ 扫码二维码', width: 220, height: 220, className: 'imqb-scanned-qr' }),\n createElement('div', { className: 'imqb-scanned-veil' },\n createElement('p', { className: 'imqb-scanned-title' }, '✅ 扫码成功'),\n createElement('p', { className: 'imqb-scanned-sub' }, '正在连接机器人,稍候…'),\n ),\n ),\n );\n }\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, '🎉'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '扫码成功'),\n createElement('p', { className: 'imqb-status-sub' }, '凭据已保存,插件正在重载,稍后即可开始对话'),\n ),\n ),\n );\n }\n\n if (state.phase === 'failed') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-icon' }, '⚠️'),\n createElement('p', { className: 'imqb-title' }, '绑定失败'),\n createElement('p', { className: 'imqb-hint' }, state.reason),\n createElement('div', { className: 'imqb-row' },\n createElement('button', { className: 'imqb-btn imqb-btn--primary', onClick: () => { window.location.reload(); } }, '重试'),\n ),\n );\n }\n\n if (state.phase === 'bound') {\n return createElement(BoundView, { appId: state.appId, recheck });\n }\n\n return createElement(UnboundView, { state });\n}\n","/**\n * QQ 机器人配置面板 — 必要配置的 UI 编辑\n *\n * UI 复刻 DSW 通用设置(settings-form 原语)的视觉风格:\n * 左对齐设置列、0.5px 行分隔、label 13px/500、控件右置;\n * Switch 为 36×20 aria-checked 结构(thumb translateX 动画);\n * 三值选择用分段控件(滑动指示器按段数/索引的 CSS 变量定位);\n * 保存按钮为 DSW 反色主按钮(label-primary 底 + bg-layer-3 字)。\n *\n * 数据流:GET /qqbot/im-qqbot/config 回显当前生效配置(appSecret\n * 已由宿主剔除)→ 表单编辑 → dirty diff → POST 仅提交变更键 →\n * 宿主白名单 + Schema 校验 → 最小写入 profile patch → HMR 重载生效。\n *\n * 字段策略:只开放用户必要的配置;cwd 只读展示;超时与性能调优\n * 类字段走 profile patch / 环境变量。\n */\nimport { createElement, useCallback, useEffect, useState, type CSSProperties, type ChangeEvent, type FormEvent, type ReactNode } from 'react';\nimport { BIND_CONFIG_PATH } from '../shared/bind-protocol.ts';\n\n/** 访问控制配置(与 src/config.ts 的 AccessControlConfig 对应的局部投影) */\ninterface AccessControlWire {\n c2cMode: 'open' | 'allowlist' | 'disabled';\n c2cAllow: string[];\n groupMode: 'open' | 'allowlist' | 'disabled';\n groupAllow: string[];\n}\n\n/** GET 回显的生效配置(appSecret 已剔除) */\ntype ConfigWire = {\n requireMention?: boolean;\n streaming?: boolean;\n showToolResults?: boolean;\n debug?: boolean;\n provider?: string;\n model?: string;\n preset?: string;\n groupPrompt?: string;\n directPrompt?: string;\n access?: AccessControlWire;\n cwd?: string;\n};\n\n/** 样式注入标记(幂等) */\nconst STYLE_ID = 'im-qqbot-config-panel-styles';\n\n/** DSW 通用设置风格(settings-form / Switch / SegmentedControl 原语复刻) */\nfunction useConfigPanelStyles(): void {\n useEffect(() => {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = `\n.imqb2-form { display: flex; flex-direction: column; width: 100%; }\n.imqb2-group-title {\n padding: 14px 0 2px; font-size: 12px; font-weight: 600; line-height: 18px;\n color: var(--dsw-alias-label-tertiary); text-transform: uppercase; letter-spacing: .04em;\n}\n.imqb2-field { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; }\n.imqb2-field + .imqb2-field { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n.imqb2-head { display: flex; align-items: center; gap: 8px; min-height: 28px; }\n.imqb2-label {\n flex: 1; min-width: 0; font-size: 13px; font-weight: 500; line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.imqb2-help { margin: 0; font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n.imqb2-hint { margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary); }\n/* Switch(aria-checked 驱动,视觉态与无障碍态同源) */\n.imqb2-switch {\n box-sizing: border-box; position: relative; flex: 0 0 auto;\n width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 999px;\n background: var(--dsw-alias-border-l3); cursor: pointer; font: inherit;\n}\n.imqb2-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary); }\n.imqb2-switch:disabled { cursor: default; opacity: 0.5; }\n.imqb2-switch:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n.imqb2-switch-thumb {\n display: block; width: 16px; height: 16px; border-radius: 50%;\n background: var(--dsw-alias-switch-thumb, #ffffff);\n transition: transform 120ms ease;\n}\n.imqb2-switch[aria-checked='true'] .imqb2-switch-thumb {\n background: var(--dsw-alias-label-primary-foreground, #ffffff);\n transform: translateX(16px);\n}\n/* 输入(官方 fields.input 复刻) */\n.imqb2-input {\n box-sizing: border-box; width: 100%; height: 34px; padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4); border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-bg-layer-3); font: inherit; font-size: 13px; line-height: 1.5;\n color: var(--dsw-alias-label-primary); outline: none;\n}\n.imqb2-input:focus { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n.imqb2-input:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.imqb2-textarea { height: auto; min-height: 68px; padding: 8px 12px; resize: vertical; line-height: 1.5; }\n/* 分段控件(官方 SegmentedControl 复刻:指示器按段数/索引定位) */\n.imqb2-seg {\n position: relative; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr;\n gap: 2px; padding: 4px; border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.imqb2-seg-indicator {\n position: absolute; top: 4px; left: 4px;\n width: calc((100% - 8px - 2px * (var(--imqb2-seg-count) - 1)) / var(--imqb2-seg-count));\n height: calc(100% - 8px);\n border: 0; border-radius: var(--dsw-radius-sm, 6px);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--dsw-elevation-soft, 0 1px 3px rgba(0,0,0,.08));\n transform: translateX(calc(var(--imqb2-seg-index) * (100% + 2px)));\n transition: transform 160ms ease;\n pointer-events: none;\n}\n.imqb2-seg-tab {\n box-sizing: border-box; position: relative; z-index: 1; height: 28px; padding: 0 16px;\n border: 0; border-radius: var(--dsw-radius-sm, 6px); background: transparent;\n color: var(--dsw-alias-label-secondary); font: inherit; font-size: 13px; line-height: 20px;\n font-weight: 500; white-space: nowrap; cursor: pointer; transition: color 120ms ease;\n}\n.imqb2-seg-tab:hover, .imqb2-seg-tab[aria-selected='true'] { color: var(--dsw-alias-label-primary); }\n.imqb2-seg-tab:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n/* 底栏(官方 SettingsForm.footer 复刻) */\n.imqb2-footer { display: flex; align-items: center; gap: 8px; padding-top: 16px; }\n.imqb2-note { flex: 1; min-width: 0; margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary); }\n.imqb2-note--error { color: var(--dsw-alias-state-error-primary, var(--dsw-alias-label-error)); }\n.imqb2-note--ok { color: var(--dsw-alias-label-secondary); }\n.imqb2-save {\n appearance: none; flex: none; border: 1px solid transparent;\n border-radius: var(--dsw-radius-md, 8px); padding: 5px 14px;\n font: inherit; font-size: 13px; line-height: 1.5; cursor: pointer;\n background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3);\n}\n.imqb2-save:disabled { opacity: 0.4; cursor: default; }\n.imqb2-save:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 1px;\n}\n/* cwd 只读行 */\n.imqb2-readonly { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--dsw-alias-label-secondary); word-break: break-all; margin: 0; }\n `;\n document.head.appendChild(style);\n return () => { style.remove(); };\n }, []);\n}\n\n/** 开关(官方 Switch 原语结构:aria-checked 驱动视觉态) */\nfunction Switch({ checked, label, onChange }: {\n checked: boolean; label: string; onChange: (next: boolean) => void;\n}): ReactNode {\n return createElement('button', {\n type: 'button', role: 'switch', 'aria-checked': checked, 'aria-label': label,\n className: 'imqb2-switch',\n onClick: () => { onChange(!checked); },\n }, createElement('span', { className: 'imqb2-switch-thumb' }));\n}\n\n/** 访问模式分段选择(官方 SegmentedControl 结构:CSS 变量定位滑动指示器) */\nfunction Segmented({ value, options, onChange, label }: {\n value: AccessMode; options: ReadonlyArray<{ value: AccessMode; label: string }>;\n onChange: (next: AccessMode) => void; label: string;\n}): ReactNode {\n const index = Math.max(0, options.findIndex((o) => o.value === value));\n const trackStyle = {\n '--imqb2-seg-count': options.length,\n '--imqb2-seg-index': index,\n } as CSSProperties;\n return createElement('div', { className: 'imqb2-seg', role: 'tablist', 'aria-label': label, style: trackStyle },\n createElement('span', { className: 'imqb2-seg-indicator' }),\n options.map((o) => createElement('button', {\n key: o.value, type: 'button', role: 'tab', 'aria-selected': o.value === value,\n className: 'imqb2-seg-tab', onClick: () => { onChange(o.value); },\n }, o.label)),\n );\n}\n\n/** 开关行(label 左 + Switch 右 + 可选 help) */\nfunction SwitchRow({ label, help, checked, onChange }: {\n label: string; help?: string; checked: boolean; onChange: (next: boolean) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement(Switch, { checked, label, onChange }),\n ),\n help === undefined ? null : createElement('p', { className: 'imqb2-help' }, help),\n );\n}\n\n/** 文本行(label 上 + 输入下,与官方 fields 布局一致) */\nfunction FieldRow({ label, help, value, placeholder, onChange }: {\n label: string; help?: string; value: string; placeholder?: string; onChange: (next: string) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement('input', {\n className: 'imqb2-input', value, placeholder, spellCheck: false,\n onChange: (event: ChangeEvent<HTMLInputElement>) => { onChange(event.currentTarget.value); },\n }),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\n/** 多行文本行 */\nfunction AreaRow({ label, help, value, rows, onChange }: {\n label: string; help?: string; value: string; rows?: number; onChange: (next: string) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement('textarea', {\n className: 'imqb2-input imqb2-textarea', value, rows: rows ?? 3,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => { onChange(event.currentTarget.value); },\n }),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\n/** 访问模式分段选择行 */\nfunction SegmentedRow({ label, help, value, options, onChange }: {\n label: string; help?: string; value: AccessMode;\n options: ReadonlyArray<{ value: AccessMode; label: string }>; onChange: (next: AccessMode) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement(Segmented, { value, options, onChange, label }),\n ),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\ntype AccessMode = AccessControlWire['c2cMode'];\n\nconst MODE_OPTIONS: ReadonlyArray<{ value: AccessMode; label: string }> = [\n { value: 'open', label: '所有人' },\n { value: 'allowlist', label: '白名单' },\n { value: 'disabled', label: '禁用' },\n];\n\n/** 深比较(表单值与初始回显值的 dirty 判断) */\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * 配置面板主体。\n *\n * 保存仅提交变更键(服务端按白名单合并),保存成功后提示\n * HMR 重载语义(进行中的机器人会话将重置)。\n */\nexport function ConfigPanel(props?: { bindPhase?: string }): ReactNode {\n useConfigPanelStyles();\n const [initial, setInitial] = useState<ConfigWire | null>(null);\n const [form, setForm] = useState<ConfigWire | null>(null);\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<{ ok: boolean; message: string } | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n // 绑定相位变化时重拉配置(扫码落库的白名单等新值)\n const bindPhase = props?.bindPhase;\n\n useEffect(() => {\n let stopped = false;\n void fetch(BIND_CONFIG_PATH, { cache: 'no-store' })\n .then(async (res) => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as { config: ConfigWire };\n if (stopped) return;\n setInitial(body.config);\n setForm(body.config);\n })\n .catch((err: unknown) => {\n if (!stopped) setLoadError(err instanceof Error ? err.message : String(err));\n });\n return () => { stopped = true; };\n }, [bindPhase]);\n\n const patch = useCallback(<K extends keyof ConfigWire>(key: K, value: ConfigWire[K]): void => {\n setForm((current) => current === null ? current : { ...current, [key]: value });\n setResult(null);\n }, []);\n\n const submit = useCallback((event: FormEvent): void => {\n event.preventDefault();\n if (busy || initial === null || form === null) return;\n const changed: Record<string, unknown> = {};\n for (const key of Object.keys(form) as Array<keyof ConfigWire>) {\n if (!shallowEqual(form[key], initial[key])) {\n changed[key] = form[key];\n }\n }\n if (Object.keys(changed).length === 0) return;\n\n // 白名单编辑期间保留原始换行/空行(textarea 可正常回车),提交时才规范化\n if (changed.access !== undefined) {\n const a = changed.access as AccessControlWire;\n changed.access = {\n ...a,\n c2cAllow: a.c2cAllow.map((s) => s.trim()).filter(Boolean),\n groupAllow: a.groupAllow.map((s) => s.trim()).filter(Boolean),\n };\n }\n\n setBusy(true);\n void fetch(BIND_CONFIG_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(changed),\n })\n .then(async (res) => {\n const body = (await res.json().catch(() => ({}))) as { ok?: boolean; message?: string; error?: string };\n if (res.ok && body.ok === true) {\n setResult({ ok: true, message: body.message ?? '配置已保存,插件将自动重载' });\n setInitial(form);\n return;\n }\n setResult({ ok: false, message: body.error ?? `保存失败(HTTP ${res.status})` });\n })\n .catch((err: unknown) => {\n setResult({ ok: false, message: err instanceof Error ? err.message : String(err) });\n })\n .finally(() => { setBusy(false); });\n }, [busy, form, initial]);\n\n if (loadError !== null) {\n return createElement('p', { className: 'imqb2-hint', style: { padding: '12px 0' } },\n `配置加载失败:${loadError}`);\n }\n if (initial === null || form === null) {\n return createElement('p', { className: 'imqb2-hint', style: { padding: '12px 0' } }, '正在加载配置…');\n }\n\n const dirty = (Object.keys(form) as Array<keyof ConfigWire>).some((key) => !shallowEqual(form[key], initial[key]));\n const access: AccessControlWire = form.access ?? { c2cMode: 'allowlist', c2cAllow: [], groupMode: 'open', groupAllow: [] };\n\n return createElement('form', { className: 'imqb2-form', onSubmit: submit },\n createElement('div', { className: 'imqb2-group-title' }, '服务范围'),\n createElement(SegmentedRow, {\n label: '私聊', value: access.c2cMode, options: MODE_OPTIONS,\n onChange: (v) => { patch('access', { ...access, c2cMode: v }); },\n }),\n access.c2cMode === 'allowlist'\n ? createElement(AreaRow, {\n label: '私聊白名单', help: '请输入用户 openid,多个请换行输入', rows: 3,\n value: access.c2cAllow.join('\\n'),\n onChange: (v) => { patch('access', { ...access, c2cAllow: v.split('\\n').map((s) => s.trim()) }); },\n })\n : null,\n createElement(SegmentedRow, {\n label: '群聊', value: access.groupMode, options: MODE_OPTIONS,\n onChange: (v) => { patch('access', { ...access, groupMode: v }); },\n }),\n access.groupMode === 'allowlist'\n ? createElement(AreaRow, {\n label: '群聊白名单', help: '请输入群 openid,多个请换行输入', rows: 3,\n value: access.groupAllow.join('\\n'),\n onChange: (v) => { patch('access', { ...access, groupAllow: v.split('\\n').map((s) => s.trim()) }); },\n })\n : null,\n\n createElement('div', { className: 'imqb2-group-title' }, '基础设置'),\n createElement(SwitchRow, {\n label: '群聊仅回复 @机器人的消息', checked: form.requireMention ?? true,\n help: '开启后,机器人仅可回复 @机器人的群聊消息',\n onChange: (v) => { patch('requireMention', v); },\n }),\n createElement(SwitchRow, {\n label: '流式输出', checked: form.streaming ?? true,\n help: '回复内容分段实时推送到聊天',\n onChange: (v) => { patch('streaming', v); },\n }),\n createElement(SwitchRow, {\n label: '显示工具调用结果', checked: form.showToolResults ?? false,\n help: '在聊天中展示 agent 工具调用的结构化结果',\n onChange: (v) => { patch('showToolResults', v); },\n }),\n\n createElement('div', { className: 'imqb2-group-title' }, '模型'),\n createElement(FieldRow, {\n label: 'Provider', value: form.provider ?? '', placeholder: '留空继承宿主默认',\n onChange: (v) => { patch('provider', v); },\n }),\n createElement(FieldRow, {\n label: 'Model', value: form.model ?? '', placeholder: '留空继承宿主默认',\n onChange: (v) => { patch('model', v); },\n }),\n createElement(FieldRow, {\n label: 'Preset', value: form.preset ?? '', placeholder: 'Agent preset id',\n onChange: (v) => { patch('preset', v); },\n }),\n\n createElement('div', { className: 'imqb2-group-title' }, '个性化提示词'),\n createElement(AreaRow, {\n label: '群聊额外 system prompt', value: form.groupPrompt ?? '',\n onChange: (v) => { patch('groupPrompt', v); },\n }),\n createElement(AreaRow, {\n label: '私聊额外 system prompt', value: form.directPrompt ?? '',\n onChange: (v) => { patch('directPrompt', v); },\n }),\n\n form.cwd !== undefined\n ? createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, 'Agent 工作目录'),\n createElement('span', { className: 'imqb2-hint' }, '只读'),\n ),\n createElement('p', { className: 'imqb2-readonly' }, form.cwd),\n )\n : null,\n\n createElement('div', { className: 'imqb2-footer' },\n result !== null\n ? createElement('p', { className: `imqb2-note${result.ok ? ' imqb2-note--ok' : ' imqb2-note--error'}` },\n (result.ok ? '' : '⚠️ ') + result.message)\n : dirty\n ? createElement('p', { className: 'imqb2-note' }, '保存后插件将重载,进行中的机器人会话将重置')\n : createElement('p', { className: 'imqb2-note' }),\n createElement('button', { className: 'imqb2-save', type: 'submit', disabled: busy || !dirty },\n busy ? '正在保存…' : '保存'),\n ),\n );\n}\n","/**\n * im-qqbot 浏览器半边 —— QQ Bot 端内扫码绑定入口\n *\n * 宿主插件在凭据缺失时注册 /qqbot/im-qqbot/bind 状态路由;本插件在\n * Web / Desktop 提供两个展示位:\n *\n * 1. 设置页「QQ Bot」栏目(settings.section 席位)——注册即展示,\n * 无 Session surface 时序依赖,待绑定/已绑定状态常驻可见;\n * 2. 右侧栏「QQ Bot 绑定」页(sidebarRightTabs)——Start 页入口 +\n * 待绑定时自动打开(失败随轮询重试)。\n *\n * 运行时依赖仅 react(客户端平台种子表提供);宿主服务经 cordis inject\n * 声明访问(声明缺失时插件保持 inactive,不阻塞浏览器启动)。\n */\nimport type { Context } from '@deepseek-ai/cordis';\nimport { createElement, type ReactNode } from 'react';\nimport { BIND_STATE_PATH } from '../shared/bind-protocol.ts';\nimport { BindPanelBody, useBindState, QQ_BOT_LOGO_PATH, installPanelStyles } from './bind-page.ts';\nimport { ConfigPanel } from './config-panel.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/** 本插件包名(插件详情页按其匹配来源包,只在对应详情页渲染操作按钮) */\nconst PACKAGE_NAME = '@tencent-connect/dsh-qqbot';\n/** 主面板 id(layout.selectPanel 导航目标;keyed main 席位按其分发) */\nconst IM_MAIN_PANEL_ID = 'im-qqbot';\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: Record<string, unknown>, component: unknown): () => void;\n}\n\n/** 绑定入口图标(QQ 机器人,跟随主题图标色变量) */\nfunction BindGuideIcon(): ReactNode {\n return createElement('svg', {\n width: 24, height: 24, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,\n },\n createElement('path', {\n d: 'M9.50039 11.1504C9.96983 11.1504 10.3504 11.5309 10.3504 12.0004V14.0004C10.3504 14.4698 9.96983 14.8504 9.50039 14.8504C9.03095 14.8504 8.65039 14.4698 8.65039 14.0004V12.0004C8.65039 11.5309 9.03095 11.1504 9.50039 11.1504Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n createElement('path', {\n d: 'M14.5004 11.1504C14.9698 11.1504 15.3504 11.5309 15.3504 12.0004V14.0004C15.3504 14.4698 14.9698 14.8504 14.5004 14.8504C14.0309 14.8504 13.6504 14.4698 13.6504 14.0004V12.0004C13.6504 11.5309 14.0309 11.1504 14.5004 11.1504Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n createElement('path', {\n fillRule: 'evenodd',\n clipRule: 'evenodd',\n d: 'M12.8504 5.3109C13.5299 4.99138 14.0004 4.30063 14.0004 3.5C14.0004 2.39543 13.1049 1.5 12.0004 1.5C10.8958 1.5 10.0004 2.39543 10.0004 3.5C10.0004 4.30065 10.4708 4.99141 11.1504 5.31092V6.18851C6.38487 6.61795 2.65039 10.6231 2.65039 15.5004V17.0004C2.65039 19.679 4.82181 21.8504 7.50039 21.8504H16.5004C19.179 21.8504 21.3504 19.679 21.3504 17.0004V15.5004C21.3504 10.6231 17.6159 6.61795 12.8504 6.18851V5.3109ZM12.0004 7.85039C7.77541 7.85039 4.35039 11.2754 4.35039 15.5004V17.0004C4.35039 18.7401 5.76069 20.1504 7.50039 20.1504H16.5004C18.2401 20.1504 19.6504 18.7401 19.6504 17.0004V15.5004C19.6504 11.2754 16.2254 7.85039 12.0004 7.85039Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n );\n}\n\n/** 设置页栏目:共享一份绑定状态轮询,驱动绑定面板与配置刷新 */\nfunction QQBotSettingsSection(): ReactNode {\n const { state, gone, recheck } = useBindState();\n return createElement('div', null,\n createElement(BindPanelBody, { state, gone, recheck }),\n createElement(ConfigPanel, { bindPhase: state?.phase }),\n );\n}\n\n/** 主面板页面:与设置栏目同一内容,包一层滚动留白容器(plugins.detail.actions 的跳转目标) */\nfunction QQBotPage(): ReactNode {\n return createElement('div', { className: 'imqb-pluginPage' },\n createElement('div', { className: 'imqb-pluginPageContent' },\n createElement(QQBotSettingsSection)),\n );\n}\n\n/** 左侧栏入口图标(宿主传入 size:展开 18 / 收起 16;currentColor 跟随侧栏配色与选中态) */\nfunction QqBotSidebarIcon({ size = 16 }: { size?: number; active?: boolean }): ReactNode {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,\n },\n createElement('path', { d: QQ_BOT_LOGO_PATH, fill: 'currentColor' }));\n}\n\n/** 插件详情「设置」按钮:仅在本包的 bundle / 组件行详情页渲染,其他插件不显示 */\nfunction OpenQqBotAction({ subject, packageName, onOpen }: {\n subject?: { kind?: string; pkg?: { name?: string }; row?: { moduleName?: string } };\n packageName: string;\n onOpen: () => void;\n}): ReactNode {\n if (subject?.kind !== 'bundle' && subject?.kind !== 'row') return null;\n if (subject.pkg?.name !== packageName) return null;\n if (subject.kind === 'row' && subject.row?.moduleName !== packageName) return null;\n return createElement('button', {\n type: 'button', className: 'imqb-pluginOpen', onClick: onOpen,\n }, '设置');\n}\n\nexport function apply(ctx: Context): void {\n // 面板样式全局安装:插件详情按钮等面板外渲染的元素也需要可见\n installPanelStyles();\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 const disposers: Array<() => void> = [];\n\n // 1. 设置页「QQ Bot」栏目(主展示位:注册即展示,无时序依赖)\n if (slots !== undefined) {\n disposers.push( slots.inject('settings.section', () => slots.register(\n { name: 'settings.section', id: 'qqbot', order: 7, label: 'QQ 机器人' },\n QQBotSettingsSection,\n )));\n }\n\n // 2. 侧栏绑定页(快捷展示位:Start 页入口 + 待绑定自动打开)\n if (tabs !== undefined && slots !== undefined) {\n disposers.push(tabs.register({\n id: TAB_ID,\n kind: TAB_KIND,\n title: () => 'QQ 机器人绑定',\n guide: [{\n id: 'bind',\n order: 90,\n title: () => 'QQ 机器人绑定',\n description: () => '扫码或手动填写,绑定 QQ 机器人',\n icon: BindGuideIcon,\n }],\n }));\n disposers.push(slots.inject('sidebar.right.pane.tab', () => slots.register(\n { name: 'sidebar.right.pane.tab', key: TAB_ID },\n BindPanelBody,\n )));\n // 待绑定检测与自动引导\n disposers.push(watchAndPrompt(right));\n }\n\n // 3. 主面板 + 插件详情「设置」操作(layout.selectPanel 导航,\n const ctxInject = (ctx as unknown as {\n inject?: (deps: readonly string[], callback: (pageCtx: Context) => (() => void) | undefined) => unknown;\n }).inject;\n if (typeof ctxInject === 'function') {\n // ctx.inject 返回 Fiber(非 disposer):子插件随父插件卸载自动清理,\n // 回调返回的清理函数由 cordis 在依赖变更/卸载时调用。\n void ctxInject.call(ctx, ['layout'], (pageCtx: Context) => {\n const pageSlots = (pageCtx as unknown as { slots?: SlotsLike }).slots;\n const layout = (pageCtx as unknown as { layout?: { selectPanel(panelId: string | null): void } }).layout;\n if (pageSlots === undefined || layout === undefined) return undefined;\n const stopMain = pageSlots.inject('main', () => pageSlots.register(\n { name: 'main', key: IM_MAIN_PANEL_ID },\n QQBotPage,\n ));\n const stopActions = pageSlots.inject('plugins.detail.actions', () => pageSlots.register(\n {\n name: 'plugins.detail.actions', id: 'im-qqbot-open', order: 20,\n inject: () => ({\n packageName: PACKAGE_NAME,\n onOpen: () => layout.selectPanel(IM_MAIN_PANEL_ID),\n }),\n },\n OpenQqBotAction,\n ));\n // 左侧栏入口:id 与 main 席位 key 一致,宿主点击即 selectPanel\n const stopSidebar = pageSlots.inject('sidebar.panellist', () => pageSlots.register(\n {\n name: 'sidebar.panellist', id: IM_MAIN_PANEL_ID,\n order: 10, label: 'QQ 机器人',\n },\n QqBotSidebarIcon,\n ));\n return () => {\n stopActions();\n stopSidebar();\n stopMain();\n };\n });\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 * 打开失败(如启动早期 Session surface 尚未挂载)不消费机会,\n * 由下一轮轮询(3s)自动重试\n */\nfunction watchAndPrompt(right: SidebarRightLike | undefined): () => void {\n let stopped = false;\n let opened = right === undefined;\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_PATH, { cache: 'no-store' });\n if (res.ok) {\n const body = (await res.json()) as { phase?: string };\n if (body.phase === 'waiting' && !opened && right !== undefined) {\n try {\n right.openTab(TAB_KIND);\n opened = true;\n } catch (err) {\n // 启动早期 Session surface 可能尚未挂载:保留机会,3s 后随轮询重试\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":["STYLE_ID","useState","useRef","useCallback","createElement","createElement","useState","useCallback","createElement"],"sources":["../src/shared/bind-protocol.ts","../src/client/bind-page.ts","../src/client/config-panel.ts","../src/client/index.ts"],"sourcesContent":["/**\n * 端内绑定协议 —— 宿主路由与客户端面板的共享契约\n *\n * 类型与路径常量的唯一事实源:宿主(setup/bind-routes.ts)与浏览器\n * (client/bind-page.ts)各自 import,杜绝两端协议漂移。\n * 本模块必须保持纯类型 + 纯常量(零 node 依赖、零副作用):\n * 客户端 tsdown 构建会将其内联进 bundle。\n */\n\n/** 状态查询(绑定页轮询) */\nexport const BIND_STATE_PATH = '/qqbot/im-qqbot/bind';\n\n/** 刷新二维码(绑定页按钮) */\nexport const BIND_REFRESH_PATH = '/qqbot/im-qqbot/bind/refresh';\n\n/** 手动填写/编辑凭据(绑定页表单) */\nexport const BIND_MANUAL_PATH = '/qqbot/im-qqbot/bind/manual';\n\n/** 解绑:移除已保存凭据,回到绑定流程 */\nexport const BIND_UNBIND_PATH = '/qqbot/im-qqbot/bind/unbind';\n\n/** 配置读写(设置面板表单) */\nexport const BIND_CONFIG_PATH = '/qqbot/im-qqbot/config';\n\n/** 线上协议(HTTP 路由序列化形态) */\nexport type BindStateWire =\n | { phase: 'starting' }\n | { phase: 'waiting'; url: string; qrSvg?: string; issuedAt: number }\n | { phase: 'saving' }\n | { phase: 'failed'; reason: string }\n | { phase: 'bound'; appId: string };\n\n/** manual / unbind 操作的统一响应 */\nexport interface BindActionResponse {\n ok: boolean;\n message?: string;\n error?: string;\n}\n","/**\n * 端内绑定面板 — 扫码 / 手动填写 / 已绑定编辑\n *\n * 宿主插件注册 /qqbot/im-qqbot/bind 路由(待绑定与已绑定 fiber 均常驻):\n * - 未绑定:waiting(二维码)/ starting / saving / failed 相位 + manual 提交\n * - 已绑定:bound 相位(回显脱敏 appId,secret 不回传)+ manual 更换 + 解绑\n * 扫码成功或手动保存均写入 profile patch 并经 HMR 重载生效。\n *\n * 样式为注入式 CSS 类(imqb-* 命名空间,随面板挂载注入一次):\n * hover/过渡/focus 样式无法用 inline style 表达,统一走类;\n * 颜色尽量取 DSW 主题变量(--dsw-alias-*),缺省值兜底。\n *\n * 同一组件复用于两种展示位(侧栏绑定页 / 设置页 QQ Bot 栏目)。\n * 运行时仅依赖 react(dsh 客户端平台种子表提供);宿主通信走同源 fetch,\n * Desktop 下由壳的 IPC 桥自动附加 Host 认证转发。\n */\nimport { createElement, useCallback, useEffect, useRef, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n BIND_MANUAL_PATH,\n BIND_REFRESH_PATH,\n BIND_STATE_PATH,\n BIND_UNBIND_PATH,\n type BindStateWire,\n} from '../shared/bind-protocol.ts';\n\n/** 轮询间隔(毫秒):活跃轮询 / 失败退避 */\nconst ACTIVE_POLL_MS = 2000;\nconst RETRY_POLL_MS = 3000;\n\n/** 样式注入标记(幂等) */\nconst STYLE_ID = 'im-qqbot-bind-panel-styles';\n\n/**\n * 注入面板样式(全局一次,幂等)。交互态(hover/active/focus)无法用 inline\n * style 表达,统一收敛到类;DSW 主题变量缺失时用中性值兜底。\n * 插件激活时即安装:插件详情按钮渲染在面板之外,需提前可见;\n * 安装后不再随挂载移除,避免多个展示位互相清掉样式。\n */\nexport function installPanelStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = `\n.imqb-panel {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n gap: 14px; padding: 24px; min-height: 320px; text-align: center; font-size: 14px;\n}\n.imqb-title { margin: 0; font-size: 16px; font-weight: 600; }\n.imqb-hint { margin: 0; opacity: 0.75; line-height: 1.6; }\n.imqb-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }\n.imqb-link { font-size: 13px; opacity: 0.85; color: var(--dsw-alias-brand, #4d6bfe); text-decoration: none; }\n.imqb-link:hover { text-decoration: underline; }\n.imqb-icon { font-size: 32px; line-height: 1; }\n.imqb-qr { border-radius: 10px; background: #fff; padding: 10px; max-width: 100%; }\n.imqb-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }\n.imqb-btn, .imqb-pill {\n font: inherit; cursor: pointer; color: inherit;\n transition: background-color .15s ease, border-color .15s ease, color .15s ease, opacity .15s ease;\n}\n.imqb-btn:disabled, .imqb-pill:disabled { opacity: 0.5; cursor: default; }\n.imqb-btn {\n padding: 7px 18px; border-radius: 8px; font-size: 13px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n background: transparent;\n}\n.imqb-btn:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-btn--primary {\n border-color: transparent;\n background: var(--dsw-alias-brand, #4d6bfe); color: #fff; font-weight: 500;\n}\n.imqb-btn--primary:hover:not(:disabled) { background: var(--dsw-alias-brand-strong, #3b5cf0); }\n.imqb-btn--danger { color: var(--dsw-alias-danger, #f26d6d); border-color: var(--dsw-alias-danger, rgba(242, 109, 109, 0.5)); }\n.imqb-btn--danger:hover:not(:disabled) { background: var(--dsw-alias-danger, rgba(242, 109, 109, 0.12)); }\n.imqb-ghost {\n border: none; background: transparent; opacity: 0.65; padding: 4px 8px;\n font: inherit; font-size: 13px; cursor: pointer; color: inherit;\n}\n.imqb-ghost:hover { opacity: 1; text-decoration: underline; }\n/* 插件详情「设置」按钮:30px,略高于旁边的 sm 次要按钮 */\n.imqb-pluginOpen {\n display: inline-flex; align-items: center; justify-content: center;\n box-sizing: border-box; height: 30px; padding: 0 14px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n border-radius: 8px; background: var(--dsw-alias-bg-layer-1, transparent);\n color: var(--dsw-alias-label-primary, inherit); font: inherit;\n font-size: 13px; line-height: 20px; cursor: pointer;\n}\n.imqb-pluginOpen:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-pluginOpen:focus-visible { outline: 2px solid var(--dsw-alias-brand, #4d6bfe); outline-offset: 3px; }\n@media (pointer: coarse) { .imqb-pluginOpen { height: 44px; } }\n/* 主面板页面容器(layout.selectPanel 目标):滚动 + 留白 */\n.imqb-pluginPage {\n height: 100%; min-height: 0; overflow: auto; box-sizing: border-box;\n padding: 24px clamp(16px, 4vw, 48px) 32px;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n.imqb-pluginPageContent { max-width: 1080px; margin: 0 auto; }\n.imqb-pill {\n padding: 5px 16px; border-radius: 999px; font-size: 13px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4)); background: transparent;\n}\n.imqb-pill:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.12)); }\n.imqb-btn:focus-visible, .imqb-pill:focus-visible, .imqb-input:focus-visible, .imqb-ghost:focus-visible {\n outline: 2px solid var(--dsw-alias-brand, #4d6bfe); outline-offset: 1px;\n}\n.imqb-form { display: flex; flex-direction: column; gap: 12px; width: min(320px, 100%); box-sizing: border-box; }\n.imqb-field { display: flex; flex-direction: column; gap: 5px; text-align: left; font-size: 13px; }\n.imqb-input {\n padding: 8px 10px; border-radius: 8px; box-sizing: border-box; width: 100%;\n border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.4));\n background: var(--dsw-alias-bg-input, rgba(128, 128, 128, 0.08));\n color: inherit; font: inherit; font-size: 13px; outline: none;\n}\n.imqb-input:focus { border-color: var(--dsw-alias-brand, #4d6bfe); }\n.imqb-error { margin: 0; font-size: 12px; color: var(--dsw-alias-danger, #f26d6d); }\n/* 紧凑状态视图(已绑定 / 过渡态):设置行风格,无居中大卡留白 */\n.imqb-status { display: flex; flex-direction: column; text-align: left; font-size: 14px; }\n.imqb-status-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; }\n.imqb-status-icon { font-size: 24px; line-height: 1; flex: none; }\n.imqb-qqicon {\n flex: none; display: block; border-radius: 8px; /* 透明底,QQ 蓝徽标在明暗主题下均清晰 */\n}\n.imqb-status-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }\n.imqb-status-title { margin: 0; font-size: 14px; font-weight: 600; line-height: 1.5; }\n.imqb-status-sub { margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary, inherit); opacity: .85; }\n.imqb-status-actions { display: flex; align-items: center; gap: 8px; padding: 4px 0 12px; }\n/* 扫码成功后的连接过渡:二维码模糊变暗 + 覆盖层 */\n.imqb-scanned { position: relative; display: inline-block; }\n.imqb-scanned-qr {\n display: block; border-radius: 10px; background: #fff; padding: 10px;\n filter: blur(6px) saturate(0.6); opacity: 0.55;\n}\n.imqb-scanned-veil {\n position: absolute; inset: 0; display: flex; flex-direction: column;\n align-items: center; justify-content: center; gap: 6px; text-align: center;\n}\n.imqb-scanned-title { margin: 0; font-size: 15px; font-weight: 600; }\n.imqb-scanned-sub { margin: 0; font-size: 12px; opacity: 0.75; line-height: 1.6; }\n `;\n document.head.appendChild(style);\n}\n\nfunction usePanelStyles(): void {\n useEffect(() => { installPanelStyles(); }, []);\n}\n\n/**\n * 绑定状态轮询 hook。\n *\n * 404 语义分两种:从未拿到过路由 = 插件未启用(终态);\n * 曾经拿到过 = HMR 重载窗口期(manual/unbind 保存后路由短暂消失),\n * 低频等待恢复而不是判定终态——否则保存成功提示会被\n * 「插件未启用」覆盖且无法自愈。\n *\n * bound 为稳定态:轮询大幅降频(30s)。因此解绑等本地动作后必须\n * 调用 recheck() 立即重置节拍——否则视图最长停留 30s+ 才收敛到\n * 新相位(如解绑后的 waiting 二维码)。\n *\n * @returns 轮询快照与 recheck:state 为宿主相位(null = 加载中),\n * gone 表示插件未启用(从未注册过路由),recheck 废弃当前\n * 定时器并立即重新轮询(新轮询链取代旧链,不产生双计时器)。\n */\nexport function useBindState(enabled = true): { state: BindStateWire | null; gone: boolean; recheck: () => void } {\n const [state, setState] = useState<BindStateWire | null>(null);\n const [gone, setGone] = useState(false);\n const recheckRef = useRef<() => void>(() => {});\n\n useEffect(() => {\n if (!enabled) return;\n let stopped = false;\n let sawRoute = false;\n let generation = 0;\n let running = false;\n let restartAfterFlight = false;\n // recheck 后的快速收敛窗口:解绑等动作改变的是服务端状态(经\n // HMR 异步生效),动作后立即轮询拿到的可能仍是旧 fiber 的相位\n // (如 bound→30s 降频),窗口期内强制快轮询直到相位真正变化\n let urgentUntil = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const schedule = (ms: number): void => {\n timer = setTimeout(() => { void tick(); }, ms);\n };\n\n const intervalFor = (phase: BindStateWire['phase']): number => {\n const base = phase === 'saving' ? 500 : phase === 'bound' ? 30000 : ACTIVE_POLL_MS;\n return Date.now() < urgentUntil ? Math.min(base, ACTIVE_POLL_MS) : base;\n };\n\n const tick = async (): Promise<void> => {\n if (stopped || running) return;\n running = true;\n const myGeneration = generation;\n const alive = (): boolean => myGeneration === generation && !stopped;\n try {\n const res = await fetch(BIND_STATE_PATH, { cache: 'no-store' });\n if (res.status === 404) {\n if (!stopped && !sawRoute) setGone(true);\n // sawRoute:HMR 窗口期,保留当前视图等待路由恢复\n else if (alive()) schedule(Date.now() < urgentUntil ? 1000 : 3000);\n return;\n }\n if (!res.ok) {\n if (alive()) schedule(RETRY_POLL_MS);\n return;\n }\n sawRoute = true;\n const body = (await res.json()) as BindStateWire;\n if (!alive()) return;\n setState(body);\n schedule(intervalFor(body.phase));\n return;\n } catch {\n // 宿主启动窗口期不可达:退避重试\n } finally {\n running = false;\n // 在飞期间被 recheck 取代:接力启动新轮询链(否则链会断)\n if (restartAfterFlight && !stopped) {\n restartAfterFlight = false;\n void tick();\n }\n }\n if (alive()) schedule(RETRY_POLL_MS);\n };\n\n // 立即重置节拍:废弃当前计时器,旧轮询链(在飞请求)作废,\n // 新链立即发起,并进入快速收敛窗口\n recheckRef.current = (): void => {\n generation += 1;\n urgentUntil = Date.now() + 15000;\n if (timer !== undefined) clearTimeout(timer);\n if (running) {\n restartAfterFlight = true;\n return;\n }\n void tick();\n };\n\n void tick();\n return () => { stopped = true; if (timer !== undefined) clearTimeout(timer); };\n }, []);\n\n const recheck = useCallback((): void => { recheckRef.current(); }, []);\n\n return { state, gone, recheck };\n}\n\ninterface ManualResult { ok: boolean; message?: string; error?: string }\n\n/** 手动提交凭据(填写 / 更换共用) */\nasync function submitManualCredentials(appId: string, appSecret: string): Promise<ManualResult> {\n try {\n const res = await fetch(BIND_MANUAL_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ appId, appSecret }),\n });\n const body = (await res.json().catch(() => ({}))) as ManualResult;\n if (res.ok && body.ok) return { ok: true, message: body.message };\n return { ok: false, error: body.error ?? `保存失败(HTTP ${res.status})` };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\n/**\n * 手动凭据表单(填写 / 更换共用)。\n *\n * appSecret 永不回显(占位符提示),提交成功后展示保存结果;\n * 宿主写入 profile patch 并经 HMR 重载,状态轮询随后收敛为 bound。\n */\nfunction ManualForm({ initialAppId }: { initialAppId?: string }): ReactNode {\n const [appId, setAppId] = useState(initialAppId ?? '');\n const [appSecret, setAppSecret] = useState('');\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<ManualResult | null>(null);\n\n const submit = useCallback((event: FormEvent): void => {\n event.preventDefault();\n if (busy) return;\n const trimmedId = appId.trim();\n const trimmedSecret = appSecret.trim();\n if (trimmedId.length === 0 || trimmedSecret.length === 0) {\n setResult({ ok: false, error: 'appId 与 appSecret 均为必填' });\n return;\n }\n setBusy(true);\n void submitManualCredentials(trimmedId, trimmedSecret).then((outcome) => {\n setResult(outcome);\n setBusy(false);\n });\n }, [appId, appSecret, busy]);\n\n if (result !== null && result.ok) {\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, '✅'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, result.message ?? '凭据已保存'),\n createElement('p', { className: 'imqb-status-sub' }, '插件将自动重载;稍后即可开始对话'),\n ),\n ),\n );\n }\n\n return createElement('form', { className: 'imqb-form', onSubmit: submit },\n createElement('label', { className: 'imqb-field' },\n 'AppID',\n createElement('input', {\n className: 'imqb-input', value: appId, placeholder: 'QQ 机器人 AppID',\n onChange: (event) => { setAppId(event.currentTarget.value); },\n autoComplete: 'off', spellCheck: false,\n }),\n ),\n createElement('label', { className: 'imqb-field' },\n 'AppSecret',\n createElement('input', {\n className: 'imqb-input', type: 'password', value: appSecret,\n placeholder: initialAppId === undefined ? 'QQ 机器人 AppSecret' : '输入新的 AppSecret(不回显)',\n onChange: (event) => { setAppSecret(event.currentTarget.value); },\n autoComplete: 'new-password',\n }),\n ),\n result !== null && !result.ok\n ? createElement('p', { className: 'imqb-error' }, result.error)\n : null,\n createElement('button', { className: 'imqb-btn imqb-btn--primary', type: 'submit', disabled: busy },\n busy ? '正在保存…' : '保存'),\n );\n}\n\n/** QQ 机器人 logo 路径(assets/icons/qqbot_logo.svg,内嵌以保持 bundle 自包含) */\nexport const QQ_BOT_LOGO_PATH =\n 'M19.3862 15.5001C19.3861 11.4203 16.0789 8.11296 11.999 8.11292C7.91915 8.11292 4.61203 11.4203 4.61182 15.5001V17.0001C4.61182 18.5949 5.90429 19.8873 7.49902 19.8873H16.499C18.0937 19.8873 19.3862 18.5949 19.3862 17.0001V15.5001ZM10.6118 14.0001C10.6118 14.6145 10.1129 15.1134 9.49853 15.1134C8.8843 15.1132 8.38672 14.6144 8.38672 14.0001V12.0006C8.38672 11.3863 8.8843 10.8875 9.49853 10.8873C10.1129 10.8873 10.6118 11.3862 10.6118 12.0006V14.0001ZM15.6113 14.0001C15.6113 14.6143 15.1136 15.1131 14.4995 15.1134C13.8851 15.1134 13.3862 14.6145 13.3862 14.0001V12.0006C13.3862 11.3862 13.8851 10.8873 14.4995 10.8873C15.1136 10.8876 15.6113 11.3864 15.6113 12.0006V14.0001ZM14.2607 3.04895C14.2607 3.89351 13.7957 4.62474 13.1108 5.0133V5.95374C17.8958 6.50514 21.6112 10.5676 21.6113 15.5001V17.0001C21.6113 19.8237 19.3225 22.1124 16.499 22.1124H7.49902C4.67546 22.1124 2.38672 19.8237 2.38672 17.0001V15.5001C2.38691 10.568 6.10139 6.50571 10.8857 5.95374V5.01185C10.2017 4.62305 9.73583 3.89286 9.73583 3.04895C9.73609 1.79961 10.7496 0.787231 11.999 0.787231C13.2484 0.787297 14.2605 1.79966 14.2607 3.04895Z';\n\n/** QQ 机器人图标(logo 矢量渲染,透明底,随 size 缩放) */\nfunction QqBotIcon({ size = 28 }: { size?: number }): ReactNode {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 24 24', fill: 'none',\n 'aria-hidden': true, className: 'imqb-qqicon',\n },\n createElement('path', { d: QQ_BOT_LOGO_PATH, fill: '#0085FF' }),\n );\n}\n/** 已绑定视图:回显 appId + 更换凭据 / 解绑入口 */\nfunction BoundView({ appId, recheck }: { appId: string; recheck: () => void }): ReactNode {\n const [editing, setEditing] = useState(false);\n const [unbindResult, setUnbindResult] = useState<{ ok: boolean; message: string } | null>(null);\n\n const unbind = useCallback((): void => {\n if (!window.confirm('确定解绑吗?\\n解绑后机器人立即下线,插件将重新进入扫码绑定流程。')) return;\n void fetch(BIND_UNBIND_PATH, { method: 'POST' })\n .then(async (res) => {\n const body = (await res.json().catch(() => ({}))) as { ok?: boolean; message?: string; error?: string };\n if (res.ok && body.ok === true) {\n setUnbindResult({ ok: true, message: body.message ?? '已解绑,插件将重载并重新进入绑定流程' });\n // bound 态轮询已降频到 30s:立即重置节拍,让 waiting(二维码)\n // 尽快出现而不是等下一个 30s 周期\n recheck();\n return;\n }\n setUnbindResult({ ok: false, message: body.error ?? `解绑失败(HTTP ${res.status})` });\n })\n .catch((err: unknown) => {\n setUnbindResult({ ok: false, message: err instanceof Error ? err.message : String(err) });\n });\n }, [recheck]);\n\n if (unbindResult !== null) {\n // 非终态视图:解绑成功后正常由轮询收敛到 waiting;若 HMR 未\n // 触发(状态停留 bound),用户仍有「刷新状态」出口而不是死胡同\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, unbindResult.ok ? '👋' : '⚠️'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, unbindResult.message),\n ),\n unbindResult.ok\n ? createElement('button', { className: 'imqb-ghost', onClick: recheck }, '刷新状态')\n : createElement('button', { className: 'imqb-ghost', onClick: () => { setUnbindResult(null); } }, '返回'),\n ),\n );\n }\n\n if (editing) {\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '更换凭据'),\n ),\n createElement('button', { className: 'imqb-ghost', onClick: () => { setEditing(false); } }, '返回'),\n ),\n createElement(ManualForm, { initialAppId: appId }),\n );\n }\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement(QqBotIcon, { size: 28 }),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '已绑定'),\n createElement('p', { className: 'imqb-status-sub imqb-mono' }, `AppID ${appId} · 私聊与群聊已接入`),\n ),\n ),\n createElement('div', { className: 'imqb-status-actions' },\n createElement('button', { className: 'imqb-btn imqb-btn--primary', onClick: () => { setEditing(true); } }, '更换凭据'),\n createElement('button', { className: 'imqb-btn imqb-btn--danger', onClick: unbind }, '解绑'),\n ),\n );\n}\n\n/** 未绑定视图:扫码 / 手动填写切换 */\nfunction UnboundView({ state }: { state: Extract<BindStateWire, { phase: 'waiting' }> }): ReactNode {\n const [mode, setMode] = useState<'qr' | 'manual'>('qr');\n const refresh = useCallback(() => { void fetch(BIND_REFRESH_PATH, { method: 'POST' }).catch(() => {}); }, []);\n\n if (mode === 'manual') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('p', { className: 'imqb-title' }, '手动填写凭据'),\n createElement(ManualForm, {}),\n createElement('button', { className: 'imqb-ghost', onClick: () => { setMode('qr'); } }, '改用扫码绑定'),\n );\n }\n\n return createElement('div', { className: 'imqb-panel' },\n state.qrSvg === undefined\n ? null\n : createElement('img', { src: state.qrSvg, alt: 'QQ 扫码二维码', width: 220, height: 220, className: 'imqb-qr' }),\n createElement('p', { className: 'imqb-title' }, '扫码绑定 QQ 机器人'),\n createElement('p', { className: 'imqb-hint' }, '使用手机 QQ 扫描二维码完成绑定'),\n createElement('a', { href: state.url, target: '_blank', rel: 'noreferrer noopener', className: 'imqb-link' }, '二维码显示异常?在浏览器中打开'),\n createElement('div', { className: 'imqb-row' },\n createElement('button', { className: 'imqb-pill', onClick: refresh }, '刷新二维码'),\n createElement('button', { className: 'imqb-pill', onClick: () => { setMode('manual'); } }, '手动填写'),\n ),\n );\n}\n\n/** 依据宿主相位渲染面板主体(可注入共享轮询结果避免双计时器) */\nexport function BindPanelBody(props?: {\n state?: BindStateWire | null;\n gone?: boolean;\n recheck?: () => void;\n}): ReactNode {\n usePanelStyles();\n const injected = props?.state !== undefined;\n const internal = useBindState(!injected);\n const state = injected ? props.state : internal.state;\n const gone = injected ? (props.gone ?? false) : internal.gone;\n const recheck = injected ? (props.recheck ?? (() => {})) : internal.recheck;\n // 扫码成功的连接过渡场景需要保留最后一帧二维码:waiting 相位持续记录,\n // bound 后清空(避免下次解绑重绑时旧码闪现)\n const [lastQr, setLastQr] = useState<string | null>(null);\n useEffect(() => {\n if (state === null) return;\n if (state.phase === 'waiting') {\n if (state.qrSvg !== undefined) setLastQr(state.qrSvg);\n } else if (state.phase === 'bound') {\n setLastQr(null);\n }\n }, [state]);\n\n if (gone) {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-icon' }, '❔'),\n createElement('p', { className: 'imqb-hint' }, '插件未启用,或当前版本不支持端内配置'),\n );\n }\n\n if (state === null || state.phase === 'starting') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('p', { className: 'imqb-hint' }, '正在获取绑定状态…'),\n );\n }\n\n if (state.phase === 'saving') {\n // 扫码路径:保留二维码做模糊过渡(手动填写路径无二维码,用紧凑态)\n if (lastQr !== null) {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-scanned' },\n createElement('img', { src: lastQr, alt: 'QQ 扫码二维码', width: 220, height: 220, className: 'imqb-scanned-qr' }),\n createElement('div', { className: 'imqb-scanned-veil' },\n createElement('p', { className: 'imqb-scanned-title' }, '✅ 扫码成功'),\n createElement('p', { className: 'imqb-scanned-sub' }, '正在连接机器人,稍候…'),\n ),\n ),\n );\n }\n return createElement('div', { className: 'imqb-status' },\n createElement('div', { className: 'imqb-status-row' },\n createElement('div', { className: 'imqb-status-icon' }, '🎉'),\n createElement('div', { className: 'imqb-status-meta' },\n createElement('p', { className: 'imqb-status-title' }, '扫码成功'),\n createElement('p', { className: 'imqb-status-sub' }, '凭据已保存,插件正在重载,稍后即可开始对话'),\n ),\n ),\n );\n }\n\n if (state.phase === 'failed') {\n return createElement('div', { className: 'imqb-panel' },\n createElement('div', { className: 'imqb-icon' }, '⚠️'),\n createElement('p', { className: 'imqb-title' }, '绑定失败'),\n createElement('p', { className: 'imqb-hint' }, state.reason),\n createElement('div', { className: 'imqb-row' },\n createElement('button', { className: 'imqb-btn imqb-btn--primary', onClick: () => { window.location.reload(); } }, '重试'),\n ),\n );\n }\n\n if (state.phase === 'bound') {\n return createElement(BoundView, { appId: state.appId, recheck });\n }\n\n return createElement(UnboundView, { state });\n}\n","/**\n * QQ 机器人配置面板 — 必要配置的 UI 编辑\n *\n * UI 复刻 DSW 通用设置(settings-form 原语)的视觉风格:\n * 左对齐设置列、0.5px 行分隔、label 13px/500、控件右置;\n * Switch 为 36×20 aria-checked 结构(thumb translateX 动画);\n * 三值选择用分段控件(滑动指示器按段数/索引的 CSS 变量定位);\n * 保存按钮为 DSW 反色主按钮(label-primary 底 + bg-layer-3 字)。\n *\n * 数据流:GET /qqbot/im-qqbot/config 回显当前生效配置(appSecret\n * 已由宿主剔除)→ 表单编辑 → dirty diff → POST 仅提交变更键 →\n * 宿主白名单 + Schema 校验 → 最小写入 profile patch → HMR 重载生效。\n *\n * 字段策略:只开放用户必要的配置;cwd 只读展示;超时与性能调优\n * 类字段走 profile patch / 环境变量。\n */\nimport { createElement, useCallback, useEffect, useState, type CSSProperties, type ChangeEvent, type FormEvent, type ReactNode } from 'react';\nimport { BIND_CONFIG_PATH } from '../shared/bind-protocol.ts';\n\n/** 访问控制配置(与 src/config.ts 的 AccessControlConfig 对应的局部投影) */\ninterface AccessControlWire {\n c2cMode: 'open' | 'allowlist' | 'disabled';\n c2cAllow: string[];\n groupMode: 'open' | 'allowlist' | 'disabled';\n groupAllow: string[];\n}\n\n/** GET 回显的生效配置(appSecret 已剔除) */\ntype ConfigWire = {\n requireMention?: boolean;\n streaming?: boolean;\n showToolResults?: boolean;\n debug?: boolean;\n provider?: string;\n model?: string;\n preset?: string;\n groupPrompt?: string;\n directPrompt?: string;\n access?: AccessControlWire;\n cwd?: string;\n};\n\n/** 样式注入标记(幂等) */\nconst STYLE_ID = 'im-qqbot-config-panel-styles';\n\n/** DSW 通用设置风格(settings-form / Switch / SegmentedControl 原语复刻) */\nfunction useConfigPanelStyles(): void {\n useEffect(() => {\n if (typeof document === 'undefined') return;\n if (document.getElementById(STYLE_ID) !== null) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = `\n.imqb2-form { display: flex; flex-direction: column; width: 100%; }\n.imqb2-group-title {\n padding: 14px 0 2px; font-size: 12px; font-weight: 600; line-height: 18px;\n color: var(--dsw-alias-label-tertiary); text-transform: uppercase; letter-spacing: .04em;\n}\n.imqb2-field { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; }\n.imqb2-field + .imqb2-field { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n.imqb2-head { display: flex; align-items: center; gap: 8px; min-height: 28px; }\n.imqb2-label {\n flex: 1; min-width: 0; font-size: 13px; font-weight: 500; line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.imqb2-help { margin: 0; font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n.imqb2-hint { margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary); }\n/* Switch(aria-checked 驱动,视觉态与无障碍态同源) */\n.imqb2-switch {\n box-sizing: border-box; position: relative; flex: 0 0 auto;\n width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 999px;\n background: var(--dsw-alias-border-l3); cursor: pointer; font: inherit;\n}\n.imqb2-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary); }\n.imqb2-switch:disabled { cursor: default; opacity: 0.5; }\n.imqb2-switch:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n.imqb2-switch-thumb {\n display: block; width: 16px; height: 16px; border-radius: 50%;\n background: var(--dsw-alias-switch-thumb, #ffffff);\n transition: transform 120ms ease;\n}\n.imqb2-switch[aria-checked='true'] .imqb2-switch-thumb {\n background: var(--dsw-alias-label-primary-foreground, #ffffff);\n transform: translateX(16px);\n}\n/* 输入(官方 fields.input 复刻) */\n.imqb2-input {\n box-sizing: border-box; width: 100%; height: 34px; padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4); border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-bg-layer-3); font: inherit; font-size: 13px; line-height: 1.5;\n color: var(--dsw-alias-label-primary); outline: none;\n}\n.imqb2-input:focus { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n.imqb2-input:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.imqb2-textarea { height: auto; min-height: 68px; padding: 8px 12px; resize: vertical; line-height: 1.5; }\n/* 分段控件(官方 SegmentedControl 复刻:指示器按段数/索引定位) */\n.imqb2-seg {\n position: relative; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr;\n gap: 2px; padding: 4px; border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.imqb2-seg-indicator {\n position: absolute; top: 4px; left: 4px;\n width: calc((100% - 8px - 2px * (var(--imqb2-seg-count) - 1)) / var(--imqb2-seg-count));\n height: calc(100% - 8px);\n border: 0; border-radius: var(--dsw-radius-sm, 6px);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--dsw-elevation-soft, 0 1px 3px rgba(0,0,0,.08));\n transform: translateX(calc(var(--imqb2-seg-index) * (100% + 2px)));\n transition: transform 160ms ease;\n pointer-events: none;\n}\n.imqb2-seg-tab {\n box-sizing: border-box; position: relative; z-index: 1; height: 28px; padding: 0 16px;\n border: 0; border-radius: var(--dsw-radius-sm, 6px); background: transparent;\n color: var(--dsw-alias-label-secondary); font: inherit; font-size: 13px; line-height: 20px;\n font-weight: 500; white-space: nowrap; cursor: pointer; transition: color 120ms ease;\n}\n.imqb2-seg-tab:hover, .imqb2-seg-tab[aria-selected='true'] { color: var(--dsw-alias-label-primary); }\n.imqb2-seg-tab:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n/* 底栏(官方 SettingsForm.footer 复刻) */\n.imqb2-footer { display: flex; align-items: center; gap: 8px; padding-top: 16px; }\n.imqb2-note { flex: 1; min-width: 0; margin: 0; font-size: 12px; line-height: 1.5; color: var(--dsw-alias-label-tertiary); }\n.imqb2-note--error { color: var(--dsw-alias-state-error-primary, var(--dsw-alias-label-error)); }\n.imqb2-note--ok { color: var(--dsw-alias-label-secondary); }\n.imqb2-save {\n appearance: none; flex: none; border: 1px solid transparent;\n border-radius: var(--dsw-radius-md, 8px); padding: 5px 14px;\n font: inherit; font-size: 13px; line-height: 1.5; cursor: pointer;\n background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3);\n}\n.imqb2-save:disabled { opacity: 0.4; cursor: default; }\n.imqb2-save:focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 1px;\n}\n/* cwd 只读行 */\n.imqb2-readonly { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--dsw-alias-label-secondary); word-break: break-all; margin: 0; }\n `;\n document.head.appendChild(style);\n return () => { style.remove(); };\n }, []);\n}\n\n/** 开关(官方 Switch 原语结构:aria-checked 驱动视觉态) */\nfunction Switch({ checked, label, onChange }: {\n checked: boolean; label: string; onChange: (next: boolean) => void;\n}): ReactNode {\n return createElement('button', {\n type: 'button', role: 'switch', 'aria-checked': checked, 'aria-label': label,\n className: 'imqb2-switch',\n onClick: () => { onChange(!checked); },\n }, createElement('span', { className: 'imqb2-switch-thumb' }));\n}\n\n/** 访问模式分段选择(官方 SegmentedControl 结构:CSS 变量定位滑动指示器) */\nfunction Segmented({ value, options, onChange, label }: {\n value: AccessMode; options: ReadonlyArray<{ value: AccessMode; label: string }>;\n onChange: (next: AccessMode) => void; label: string;\n}): ReactNode {\n const index = Math.max(0, options.findIndex((o) => o.value === value));\n const trackStyle = {\n '--imqb2-seg-count': options.length,\n '--imqb2-seg-index': index,\n } as CSSProperties;\n return createElement('div', { className: 'imqb2-seg', role: 'tablist', 'aria-label': label, style: trackStyle },\n createElement('span', { className: 'imqb2-seg-indicator' }),\n options.map((o) => createElement('button', {\n key: o.value, type: 'button', role: 'tab', 'aria-selected': o.value === value,\n className: 'imqb2-seg-tab', onClick: () => { onChange(o.value); },\n }, o.label)),\n );\n}\n\n/** 开关行(label 左 + Switch 右 + 可选 help) */\nfunction SwitchRow({ label, help, checked, onChange }: {\n label: string; help?: string; checked: boolean; onChange: (next: boolean) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement(Switch, { checked, label, onChange }),\n ),\n help === undefined ? null : createElement('p', { className: 'imqb2-help' }, help),\n );\n}\n\n/** 文本行(label 上 + 输入下,与官方 fields 布局一致) */\nfunction FieldRow({ label, help, value, placeholder, onChange }: {\n label: string; help?: string; value: string; placeholder?: string; onChange: (next: string) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement('input', {\n className: 'imqb2-input', value, placeholder, spellCheck: false,\n onChange: (event: ChangeEvent<HTMLInputElement>) => { onChange(event.currentTarget.value); },\n }),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\n/** 多行文本行 */\nfunction AreaRow({ label, help, value, rows, onChange }: {\n label: string; help?: string; value: string; rows?: number; onChange: (next: string) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement('textarea', {\n className: 'imqb2-input imqb2-textarea', value, rows: rows ?? 3,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => { onChange(event.currentTarget.value); },\n }),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\n/** 访问模式分段选择行 */\nfunction SegmentedRow({ label, help, value, options, onChange }: {\n label: string; help?: string; value: AccessMode;\n options: ReadonlyArray<{ value: AccessMode; label: string }>; onChange: (next: AccessMode) => void;\n}): ReactNode {\n return createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, label),\n createElement(Segmented, { value, options, onChange, label }),\n ),\n help === undefined ? null : createElement('p', { className: 'imqb2-hint' }, help),\n );\n}\n\ntype AccessMode = AccessControlWire['c2cMode'];\n\nconst MODE_OPTIONS: ReadonlyArray<{ value: AccessMode; label: string }> = [\n { value: 'open', label: '所有人' },\n { value: 'allowlist', label: '白名单' },\n { value: 'disabled', label: '禁用' },\n];\n\n/** 深比较(表单值与初始回显值的 dirty 判断) */\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * 配置面板主体。\n *\n * 保存仅提交变更键(服务端按白名单合并),保存成功后提示\n * HMR 重载语义(进行中的机器人会话将重置)。\n */\nexport function ConfigPanel(props?: { bindPhase?: string }): ReactNode {\n useConfigPanelStyles();\n const [initial, setInitial] = useState<ConfigWire | null>(null);\n const [form, setForm] = useState<ConfigWire | null>(null);\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<{ ok: boolean; message: string } | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n // 绑定相位变化时重拉配置(扫码落库的白名单等新值)\n const bindPhase = props?.bindPhase;\n\n useEffect(() => {\n let stopped = false;\n void fetch(BIND_CONFIG_PATH, { cache: 'no-store' })\n .then(async (res) => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as { config: ConfigWire };\n if (stopped) return;\n setInitial(body.config);\n setForm(body.config);\n })\n .catch((err: unknown) => {\n if (!stopped) setLoadError(err instanceof Error ? err.message : String(err));\n });\n return () => { stopped = true; };\n }, [bindPhase]);\n\n const patch = useCallback(<K extends keyof ConfigWire>(key: K, value: ConfigWire[K]): void => {\n setForm((current) => current === null ? current : { ...current, [key]: value });\n setResult(null);\n }, []);\n\n const submit = useCallback((event: FormEvent): void => {\n event.preventDefault();\n if (busy || initial === null || form === null) return;\n const changed: Record<string, unknown> = {};\n for (const key of Object.keys(form) as Array<keyof ConfigWire>) {\n if (!shallowEqual(form[key], initial[key])) {\n changed[key] = form[key];\n }\n }\n if (Object.keys(changed).length === 0) return;\n\n // 白名单编辑期间保留原始换行/空行(textarea 可正常回车),提交时才规范化\n if (changed.access !== undefined) {\n const a = changed.access as AccessControlWire;\n changed.access = {\n ...a,\n c2cAllow: a.c2cAllow.map((s) => s.trim()).filter(Boolean),\n groupAllow: a.groupAllow.map((s) => s.trim()).filter(Boolean),\n };\n }\n\n setBusy(true);\n void fetch(BIND_CONFIG_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(changed),\n })\n .then(async (res) => {\n const body = (await res.json().catch(() => ({}))) as { ok?: boolean; message?: string; error?: string };\n if (res.ok && body.ok === true) {\n setResult({ ok: true, message: body.message ?? '配置已保存,插件将自动重载' });\n setInitial(form);\n return;\n }\n setResult({ ok: false, message: body.error ?? `保存失败(HTTP ${res.status})` });\n })\n .catch((err: unknown) => {\n setResult({ ok: false, message: err instanceof Error ? err.message : String(err) });\n })\n .finally(() => { setBusy(false); });\n }, [busy, form, initial]);\n\n if (loadError !== null) {\n return createElement('p', { className: 'imqb2-hint', style: { padding: '12px 0' } },\n `配置加载失败:${loadError}`);\n }\n if (initial === null || form === null) {\n return createElement('p', { className: 'imqb2-hint', style: { padding: '12px 0' } }, '正在加载配置…');\n }\n\n const dirty = (Object.keys(form) as Array<keyof ConfigWire>).some((key) => !shallowEqual(form[key], initial[key]));\n const access: AccessControlWire = form.access ?? { c2cMode: 'open', c2cAllow: [], groupMode: 'open', groupAllow: [] };\n\n return createElement('form', { className: 'imqb2-form', onSubmit: submit },\n createElement('div', { className: 'imqb2-group-title' }, '服务范围'),\n createElement(SegmentedRow, {\n label: '私聊', value: access.c2cMode, options: MODE_OPTIONS,\n onChange: (v) => { patch('access', { ...access, c2cMode: v }); },\n }),\n access.c2cMode === 'allowlist'\n ? createElement(AreaRow, {\n label: '私聊白名单', help: '请输入用户 openid,多个请换行输入', rows: 3,\n value: access.c2cAllow.join('\\n'),\n onChange: (v) => { patch('access', { ...access, c2cAllow: v.split('\\n').map((s) => s.trim()) }); },\n })\n : null,\n createElement(SegmentedRow, {\n label: '群聊', value: access.groupMode, options: MODE_OPTIONS,\n onChange: (v) => { patch('access', { ...access, groupMode: v }); },\n }),\n access.groupMode === 'allowlist'\n ? createElement(AreaRow, {\n label: '群聊白名单', help: '请输入群 openid,多个请换行输入', rows: 3,\n value: access.groupAllow.join('\\n'),\n onChange: (v) => { patch('access', { ...access, groupAllow: v.split('\\n').map((s) => s.trim()) }); },\n })\n : null,\n\n createElement('div', { className: 'imqb2-group-title' }, '基础设置'),\n createElement(SwitchRow, {\n label: '群聊仅回复 @机器人的消息', checked: form.requireMention ?? true,\n help: '开启后,机器人仅可回复 @机器人的群聊消息',\n onChange: (v) => { patch('requireMention', v); },\n }),\n createElement(SwitchRow, {\n label: '流式输出', checked: form.streaming ?? true,\n help: '回复内容分段实时推送到聊天',\n onChange: (v) => { patch('streaming', v); },\n }),\n createElement(SwitchRow, {\n label: '显示工具调用结果', checked: form.showToolResults ?? false,\n help: '在聊天中展示 agent 工具调用的结构化结果',\n onChange: (v) => { patch('showToolResults', v); },\n }),\n\n createElement('div', { className: 'imqb2-group-title' }, '模型'),\n createElement(FieldRow, {\n label: 'Provider', value: form.provider ?? '', placeholder: '留空继承宿主默认',\n onChange: (v) => { patch('provider', v); },\n }),\n createElement(FieldRow, {\n label: 'Model', value: form.model ?? '', placeholder: '留空继承宿主默认',\n onChange: (v) => { patch('model', v); },\n }),\n createElement(FieldRow, {\n label: 'Preset', value: form.preset ?? '', placeholder: 'Agent preset id',\n onChange: (v) => { patch('preset', v); },\n }),\n\n createElement('div', { className: 'imqb2-group-title' }, '个性化提示词'),\n createElement(AreaRow, {\n label: '群聊额外 system prompt', value: form.groupPrompt ?? '',\n onChange: (v) => { patch('groupPrompt', v); },\n }),\n createElement(AreaRow, {\n label: '私聊额外 system prompt', value: form.directPrompt ?? '',\n onChange: (v) => { patch('directPrompt', v); },\n }),\n\n form.cwd !== undefined\n ? createElement('div', { className: 'imqb2-field' },\n createElement('div', { className: 'imqb2-head' },\n createElement('span', { className: 'imqb2-label' }, 'Agent 工作目录'),\n createElement('span', { className: 'imqb2-hint' }, '只读'),\n ),\n createElement('p', { className: 'imqb2-readonly' }, form.cwd),\n )\n : null,\n\n createElement('div', { className: 'imqb2-footer' },\n result !== null\n ? createElement('p', { className: `imqb2-note${result.ok ? ' imqb2-note--ok' : ' imqb2-note--error'}` },\n (result.ok ? '' : '⚠️ ') + result.message)\n : dirty\n ? createElement('p', { className: 'imqb2-note' }, '保存后插件将重载,进行中的机器人会话将重置')\n : createElement('p', { className: 'imqb2-note' }),\n createElement('button', { className: 'imqb2-save', type: 'submit', disabled: busy || !dirty },\n busy ? '正在保存…' : '保存'),\n ),\n );\n}\n","/**\n * im-qqbot 浏览器半边 —— QQ Bot 端内扫码绑定入口\n *\n * 宿主插件在凭据缺失时注册 /qqbot/im-qqbot/bind 状态路由;本插件在\n * Web / Desktop 提供两个展示位:\n *\n * 1. 设置页「QQ Bot」栏目(settings.section 席位)——注册即展示,\n * 无 Session surface 时序依赖,待绑定/已绑定状态常驻可见;\n * 2. 右侧栏「QQ Bot 绑定」页(sidebarRightTabs)——Start 页入口 +\n * 待绑定时自动打开(失败随轮询重试)。\n *\n * 运行时依赖仅 react(客户端平台种子表提供);宿主服务经 cordis inject\n * 声明访问(声明缺失时插件保持 inactive,不阻塞浏览器启动)。\n */\nimport type { Context } from '@deepseek-ai/cordis';\nimport { createElement, type ReactNode } from 'react';\nimport { BIND_STATE_PATH } from '../shared/bind-protocol.ts';\nimport { BindPanelBody, useBindState, QQ_BOT_LOGO_PATH, installPanelStyles } from './bind-page.ts';\nimport { ConfigPanel } from './config-panel.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/** 本插件包名(插件详情页按其匹配来源包,只在对应详情页渲染操作按钮) */\nconst PACKAGE_NAME = '@tencent-connect/dsh-qqbot';\n/** 主面板 id(layout.selectPanel 导航目标;keyed main 席位按其分发) */\nconst IM_MAIN_PANEL_ID = 'im-qqbot';\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: Record<string, unknown>, component: unknown): () => void;\n}\n\n/** 绑定入口图标(QQ 机器人,跟随主题图标色变量) */\nfunction BindGuideIcon(): ReactNode {\n return createElement('svg', {\n width: 24, height: 24, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,\n },\n createElement('path', {\n d: 'M9.50039 11.1504C9.96983 11.1504 10.3504 11.5309 10.3504 12.0004V14.0004C10.3504 14.4698 9.96983 14.8504 9.50039 14.8504C9.03095 14.8504 8.65039 14.4698 8.65039 14.0004V12.0004C8.65039 11.5309 9.03095 11.1504 9.50039 11.1504Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n createElement('path', {\n d: 'M14.5004 11.1504C14.9698 11.1504 15.3504 11.5309 15.3504 12.0004V14.0004C15.3504 14.4698 14.9698 14.8504 14.5004 14.8504C14.0309 14.8504 13.6504 14.4698 13.6504 14.0004V12.0004C13.6504 11.5309 14.0309 11.1504 14.5004 11.1504Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n createElement('path', {\n fillRule: 'evenodd',\n clipRule: 'evenodd',\n d: 'M12.8504 5.3109C13.5299 4.99138 14.0004 4.30063 14.0004 3.5C14.0004 2.39543 13.1049 1.5 12.0004 1.5C10.8958 1.5 10.0004 2.39543 10.0004 3.5C10.0004 4.30065 10.4708 4.99141 11.1504 5.31092V6.18851C6.38487 6.61795 2.65039 10.6231 2.65039 15.5004V17.0004C2.65039 19.679 4.82181 21.8504 7.50039 21.8504H16.5004C19.179 21.8504 21.3504 19.679 21.3504 17.0004V15.5004C21.3504 10.6231 17.6159 6.61795 12.8504 6.18851V5.3109ZM12.0004 7.85039C7.77541 7.85039 4.35039 11.2754 4.35039 15.5004V17.0004C4.35039 18.7401 5.76069 20.1504 7.50039 20.1504H16.5004C18.2401 20.1504 19.6504 18.7401 19.6504 17.0004V15.5004C19.6504 11.2754 16.2254 7.85039 12.0004 7.85039Z',\n fill: 'var(------icon_primary, #1A1A1A)',\n }),\n );\n}\n\n/** 设置页栏目:共享一份绑定状态轮询,驱动绑定面板与配置刷新 */\nfunction QQBotSettingsSection(): ReactNode {\n const { state, gone, recheck } = useBindState();\n return createElement('div', null,\n createElement(BindPanelBody, { state, gone, recheck }),\n createElement(ConfigPanel, { bindPhase: state?.phase }),\n );\n}\n\n/** 主面板页面:与设置栏目同一内容,包一层滚动留白容器(plugins.detail.actions 的跳转目标) */\nfunction QQBotPage(): ReactNode {\n return createElement('div', { className: 'imqb-pluginPage' },\n createElement('div', { className: 'imqb-pluginPageContent' },\n createElement(QQBotSettingsSection)),\n );\n}\n\n/** 左侧栏入口图标(宿主传入 size:展开 18 / 收起 16;currentColor 跟随侧栏配色与选中态) */\nfunction QqBotSidebarIcon({ size = 16 }: { size?: number; active?: boolean }): ReactNode {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,\n },\n createElement('path', { d: QQ_BOT_LOGO_PATH, fill: 'currentColor' }));\n}\n\n/** 插件详情「设置」按钮:仅在本包的 bundle / 组件行详情页渲染,其他插件不显示 */\nfunction OpenQqBotAction({ subject, packageName, onOpen }: {\n subject?: { kind?: string; pkg?: { name?: string }; row?: { moduleName?: string } };\n packageName: string;\n onOpen: () => void;\n}): ReactNode {\n if (subject?.kind !== 'bundle' && subject?.kind !== 'row') return null;\n if (subject.pkg?.name !== packageName) return null;\n if (subject.kind === 'row' && subject.row?.moduleName !== packageName) return null;\n return createElement('button', {\n type: 'button', className: 'imqb-pluginOpen', onClick: onOpen,\n }, '设置');\n}\n\nexport function apply(ctx: Context): void {\n // 面板样式全局安装:插件详情按钮等面板外渲染的元素也需要可见\n installPanelStyles();\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 const disposers: Array<() => void> = [];\n\n // 1. 设置页「QQ Bot」栏目(主展示位:注册即展示,无时序依赖)\n if (slots !== undefined) {\n disposers.push( slots.inject('settings.section', () => slots.register(\n { name: 'settings.section', id: 'qqbot', order: 7, label: 'QQ 机器人' },\n QQBotSettingsSection,\n )));\n }\n\n // 2. 侧栏绑定页(快捷展示位:Start 页入口 + 待绑定自动打开)\n if (tabs !== undefined && slots !== undefined) {\n disposers.push(tabs.register({\n id: TAB_ID,\n kind: TAB_KIND,\n title: () => 'QQ 机器人绑定',\n guide: [{\n id: 'bind',\n order: 90,\n title: () => 'QQ 机器人绑定',\n description: () => '扫码或手动填写,绑定 QQ 机器人',\n icon: BindGuideIcon,\n }],\n }));\n disposers.push(slots.inject('sidebar.right.pane.tab', () => slots.register(\n { name: 'sidebar.right.pane.tab', key: TAB_ID },\n BindPanelBody,\n )));\n // 待绑定检测与自动引导\n disposers.push(watchAndPrompt(right));\n }\n\n // 3. 主面板 + 插件详情「设置」操作(layout.selectPanel 导航,\n const ctxInject = (ctx as unknown as {\n inject?: (deps: readonly string[], callback: (pageCtx: Context) => (() => void) | undefined) => unknown;\n }).inject;\n if (typeof ctxInject === 'function') {\n // ctx.inject 返回 Fiber(非 disposer):子插件随父插件卸载自动清理,\n // 回调返回的清理函数由 cordis 在依赖变更/卸载时调用。\n void ctxInject.call(ctx, ['layout'], (pageCtx: Context) => {\n const pageSlots = (pageCtx as unknown as { slots?: SlotsLike }).slots;\n const layout = (pageCtx as unknown as { layout?: { selectPanel(panelId: string | null): void } }).layout;\n if (pageSlots === undefined || layout === undefined) return undefined;\n const stopMain = pageSlots.inject('main', () => pageSlots.register(\n { name: 'main', key: IM_MAIN_PANEL_ID },\n QQBotPage,\n ));\n const stopActions = pageSlots.inject('plugins.detail.actions', () => pageSlots.register(\n {\n name: 'plugins.detail.actions', id: 'im-qqbot-open', order: 20,\n inject: () => ({\n packageName: PACKAGE_NAME,\n onOpen: () => layout.selectPanel(IM_MAIN_PANEL_ID),\n }),\n },\n OpenQqBotAction,\n ));\n // 左侧栏入口:id 与 main 席位 key 一致,宿主点击即 selectPanel\n const stopSidebar = pageSlots.inject('sidebar.panellist', () => pageSlots.register(\n {\n name: 'sidebar.panellist', id: IM_MAIN_PANEL_ID,\n order: 10, label: 'QQ 机器人',\n },\n QqBotSidebarIcon,\n ));\n return () => {\n stopActions();\n stopSidebar();\n stopMain();\n };\n });\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 * 打开失败(如启动早期 Session surface 尚未挂载)不消费机会,\n * 由下一轮轮询(3s)自动重试\n */\nfunction watchAndPrompt(right: SidebarRightLike | undefined): () => void {\n let stopped = false;\n let opened = right === undefined;\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_PATH, { cache: 'no-store' });\n if (res.ok) {\n const body = (await res.json()) as { phase?: string };\n if (body.phase === 'waiting' && !opened && right !== undefined) {\n try {\n right.openTab(TAB_KIND);\n opened = true;\n } catch (err) {\n // 启动早期 Session surface 可能尚未挂载:保留机会,3s 后随轮询重试\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":";;;;;;;;;;;;;;;;;EAUA,MAAa,kBAAkB;;EAG/B,MAAa,oBAAoB;;EAGjC,MAAa,mBAAmB;;EAGhC,MAAa,mBAAmB;;EAGhC,MAAa,mBAAmB;;;;;;;;;;;;;;;;;;;;ECIhC,MAAM,iBAAiB;EACvB,MAAM,gBAAgB;;EAGtB,MAAMA,aAAW;;;;;;;EAQjB,SAAgB,qBAA2B;GACzC,IAAI,OAAO,aAAa,aAAa;GACrC,IAAI,SAAS,eAAeA,UAAQ,MAAM,MAAM;GAChD,MAAM,QAAQ,SAAS,cAAc,OAAO;GAC5C,MAAM,KAAKA;GACX,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGpB,SAAS,KAAK,YAAY,KAAK;EACjC;EAEA,SAAS,iBAAuB;GAC9B,CAAA,GAAA,MAAA,UAAA,OAAgB;IAAE,mBAAmB;GAAG,GAAG,CAAC,CAAC;EAC/C;;;;;;;;;;;;;;;;;EAkBA,SAAgB,aAAa,UAAU,MAA2E;GAChH,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,CAA+B,IAAI;GAC7D,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,cAAA,GAAaC,MAAAA,OAAAA,OAAyB,CAAC,CAAC;GAE9C,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,SAAS;IACd,IAAI,UAAU;IACd,IAAI,WAAW;IACf,IAAI,aAAa;IACjB,IAAI,UAAU;IACd,IAAI,qBAAqB;IAIzB,IAAI,cAAc;IAClB,IAAI;IAEJ,MAAM,YAAY,OAAqB;KACrC,QAAQ,iBAAiB;MAAE,KAAU;KAAG,GAAG,EAAE;IAC/C;IAEA,MAAM,eAAe,UAA0C;KAC7D,MAAM,OAAO,UAAU,WAAW,MAAM,UAAU,UAAU,MAAQ;KACpE,OAAO,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI,MAAM,cAAc,IAAI;IACrE;IAEA,MAAM,OAAO,YAA2B;KACtC,IAAI,WAAW,SAAS;KACxB,UAAU;KACV,MAAM,eAAe;KACrB,MAAM,cAAuB,iBAAiB,cAAc,CAAC;KAC7D,IAAI;MACF,MAAM,MAAM,MAAM,MAAM,iBAAiB,EAAE,OAAO,WAAW,CAAC;MAC9D,IAAI,IAAI,WAAW,KAAK;OACtB,IAAI,CAAC,WAAW,CAAC,UAAU,QAAQ,IAAI;YAElC,IAAI,MAAM,GAAG,SAAS,KAAK,IAAI,IAAI,cAAc,MAAO,GAAI;OACjE;MACF;MACA,IAAI,CAAC,IAAI,IAAI;OACX,IAAI,MAAM,GAAG,SAAS,aAAa;OACnC;MACF;MACA,WAAW;MACX,MAAM,OAAQ,MAAM,IAAI,KAAK;MAC7B,IAAI,CAAC,MAAM,GAAG;MACd,SAAS,IAAI;MACb,SAAS,YAAY,KAAK,KAAK,CAAC;MAChC;KACF,QAAQ,CAER,UAAU;MACR,UAAU;MAEV,IAAI,sBAAsB,CAAC,SAAS;OAClC,qBAAqB;OACrB,KAAU;MACZ;KACF;KACA,IAAI,MAAM,GAAG,SAAS,aAAa;IACrC;IAIA,WAAW,gBAAsB;KAC/B,cAAc;KACd,cAAc,KAAK,IAAI,IAAI;KAC3B,IAAI,UAAU,KAAA,GAAW,aAAa,KAAK;KAC3C,IAAI,SAAS;MACX,qBAAqB;MACrB;KACF;KACA,KAAU;IACZ;IAEA,KAAU;IACV,aAAa;KAAE,UAAU;KAAM,IAAI,UAAU,KAAA,GAAW,aAAa,KAAK;IAAG;GAC/E,GAAG,CAAC,CAAC;GAIL,OAAO;IAAE;IAAO;IAAM,UAAA,GAFNC,MAAAA,YAAAA,OAAwB;KAAE,WAAW,QAAQ;IAAG,GAAG,CAAC,CAExC;GAAE;EAChC;;EAKA,eAAe,wBAAwB,OAAe,WAA0C;GAC9F,IAAI;IACF,MAAM,MAAM,MAAM,MAAM,kBAAkB;KACxC,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAO;KAAU,CAAC;IAC3C,CAAC;IACD,MAAM,OAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;IAC/C,IAAI,IAAI,MAAM,KAAK,IAAI,OAAO;KAAE,IAAI;KAAM,SAAS,KAAK;IAAQ;IAChE,OAAO;KAAE,IAAI;KAAO,OAAO,KAAK,SAAS,aAAa,IAAI,OAAO;IAAG;GACtE,SAAS,KAAK;IACZ,OAAO;KAAE,IAAI;KAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;IAAE;GAC9E;EACF;;;;;;;EAQA,SAAS,WAAW,EAAE,gBAAsD;GAC1E,MAAM,CAAC,OAAO,aAAA,GAAYF,MAAAA,SAAAA,CAAS,gBAAgB,EAAE;GACrD,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,EAAE;GAC7C,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAA8B,IAAI;GAE9D,MAAM,UAAA,GAASE,MAAAA,YAAAA,EAAa,UAA2B;IACrD,MAAM,eAAe;IACrB,IAAI,MAAM;IACV,MAAM,YAAY,MAAM,KAAK;IAC7B,MAAM,gBAAgB,UAAU,KAAK;IACrC,IAAI,UAAU,WAAW,KAAK,cAAc,WAAW,GAAG;KACxD,UAAU;MAAE,IAAI;MAAO,OAAO;KAAyB,CAAC;KACxD;IACF;IACA,QAAQ,IAAI;IACZ,wBAA6B,WAAW,aAAa,CAAC,CAAC,MAAM,YAAY;KACvE,UAAU,OAAO;KACjB,QAAQ,KAAK;IACf,CAAC;GACH,GAAG;IAAC;IAAO;IAAW;GAAI,CAAC;GAE3B,IAAI,WAAW,QAAQ,OAAO,IAC5B,QAAA,GAAOC,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GAClDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,GAAG,GAAG,IAAA,GAC3DA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,IAAA,GACnDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,oBAAoB,GAAG,OAAO,WAAW,OAAO,IAAA,GAChFA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,kBAAkB,GAAG,kBAAkB,CACzE,CACF,CACF;GAGF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,QAAQ;IAAE,WAAW;IAAa,UAAU;GAAO,IAAA,GACtEA,MAAAA,cAAAA,CAAc,SAAS,EAAE,WAAW,aAAa,GAC/C,UAAA,GACAA,MAAAA,cAAAA,CAAc,SAAS;IACrB,WAAW;IAAc,OAAO;IAAO,aAAa;IACpD,WAAW,UAAU;KAAE,SAAS,MAAM,cAAc,KAAK;IAAG;IAC5D,cAAc;IAAO,YAAY;GACnC,CAAC,CACH,IAAA,GACAA,MAAAA,cAAAA,CAAc,SAAS,EAAE,WAAW,aAAa,GAC/C,cAAA,GACAA,MAAAA,cAAAA,CAAc,SAAS;IACrB,WAAW;IAAc,MAAM;IAAY,OAAO;IAClD,aAAa,iBAAiB,KAAA,IAAY,qBAAqB;IAC/D,WAAW,UAAU;KAAE,aAAa,MAAM,cAAc,KAAK;IAAG;IAChE,cAAc;GAChB,CAAC,CACH,GACA,WAAW,QAAQ,CAAC,OAAO,MAAA,GACvBA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,OAAO,KAAK,IAC5D,OAAA,GACJA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAA8B,MAAM;IAAU,UAAU;GAAK,GAChG,OAAO,UAAU,IAAI,CACzB;EACF;;EAGA,MAAa,mBACX;;EAGF,SAAS,UAAU,EAAE,OAAO,MAAoC;GAC9D,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO;IAC1B,OAAO;IAAM,QAAQ;IAAM,SAAS;IAAa,MAAM;IACvD,eAAe;IAAM,WAAW;GAClC,IAAA,GACEA,MAAAA,cAAAA,CAAc,QAAQ;IAAE,GAAG;IAAkB,MAAM;GAAU,CAAC,CAChE;EACF;;EAEA,SAAS,UAAU,EAAE,OAAO,WAA8D;GACxF,MAAM,CAAC,SAAS,eAAA,GAAcH,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAkD,IAAI;GAE9F,MAAM,UAAA,GAASE,MAAAA,YAAAA,OAAwB;IACrC,IAAI,CAAC,OAAO,QAAQ,mCAAmC,GAAG;IAC1D,MAAW,kBAAkB,EAAE,QAAQ,OAAO,CAAC,CAAC,CAC7C,KAAK,OAAO,QAAQ;KACnB,MAAM,OAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;KAC/C,IAAI,IAAI,MAAM,KAAK,OAAO,MAAM;MAC9B,gBAAgB;OAAE,IAAI;OAAM,SAAS,KAAK,WAAW;MAAqB,CAAC;MAG3E,QAAQ;MACR;KACF;KACA,gBAAgB;MAAE,IAAI;MAAO,SAAS,KAAK,SAAS,aAAa,IAAI,OAAO;KAAG,CAAC;IAClF,CAAC,CAAC,CACD,OAAO,QAAiB;KACvB,gBAAgB;MAAE,IAAI;MAAO,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAAE,CAAC;IAC1F,CAAC;GACL,GAAG,CAAC,OAAO,CAAC;GAEZ,IAAI,iBAAiB,MAGnB,QAAA,GAAOC,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GAClDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,GAAG,aAAa,KAAK,OAAO,IAAI,IAAA,GACrFA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,IAAA,GACnDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,oBAAoB,GAAG,aAAa,OAAO,CAC7E,GACA,aAAa,MAAA,GACTA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAc,SAAS;GAAQ,GAAG,MAAM,KAAA,GAC7EA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAc,eAAe;KAAE,gBAAgB,IAAI;IAAG;GAAE,GAAG,IAAI,CAC1G,CACF;GAGF,IAAI,SACF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GAClDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,IAAA,GACnDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,oBAAoB,GAAG,MAAM,CAC/D,IAAA,GACAA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAc,eAAe;KAAE,WAAW,KAAK;IAAG;GAAE,GAAG,IAAI,CAClG,IAAA,GACAA,MAAAA,cAAAA,CAAc,YAAY,EAAE,cAAc,MAAM,CAAC,CACnD;GAEF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GAClDA,MAAAA,cAAAA,CAAc,WAAW,EAAE,MAAM,GAAG,CAAC,IAAA,GACrCA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,IAAA,GACnDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,oBAAoB,GAAG,KAAK,IAAA,GAC5DA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,4BAA4B,GAAG,SAAS,MAAM,YAAY,CAC5F,CACF,IAAA,GACAA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,sBAAsB,IAAA,GACtDA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAA8B,eAAe;KAAE,WAAW,IAAI;IAAG;GAAE,GAAG,MAAM,IAAA,GACjHA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAA6B,SAAS;GAAO,GAAG,IAAI,CAC3F,CACF;EACF;;EAGA,SAAS,YAAY,EAAE,SAA6E;GAClG,MAAM,CAAC,MAAM,YAAA,GAAWH,MAAAA,SAAAA,CAA0B,IAAI;GACtD,MAAM,WAAA,GAAUE,MAAAA,YAAAA,OAAkB;IAAE,MAAW,mBAAmB,EAAE,QAAQ,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;GAAG,GAAG,CAAC,CAAC;GAE5G,IAAI,SAAS,UACX,QAAA,GAAOC,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GACpDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,QAAQ,IAAA,GACxDA,MAAAA,cAAAA,CAAc,YAAY,CAAC,CAAC,IAAA,GAC5BA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAc,eAAe;KAAE,QAAQ,IAAI;IAAG;GAAE,GAAG,QAAQ,CAClG;GAGF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,GACpD,MAAM,UAAU,KAAA,IACZ,QAAA,GACAA,MAAAA,cAAAA,CAAc,OAAO;IAAE,KAAK,MAAM;IAAO,KAAK;IAAY,OAAO;IAAK,QAAQ;IAAK,WAAW;GAAU,CAAC,IAAA,GAC7GA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,aAAa,IAAA,GAC7DA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,YAAY,GAAG,mBAAmB,IAAA,GAClEA,MAAAA,cAAAA,CAAc,KAAK;IAAE,MAAM,MAAM;IAAK,QAAQ;IAAU,KAAK;IAAuB,WAAW;GAAY,GAAG,iBAAiB,IAAA,GAC/HA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,WAAW,IAAA,GAC3CA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAa,SAAS;GAAQ,GAAG,OAAO,IAAA,GAC7EA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAa,eAAe;KAAE,QAAQ,QAAQ;IAAG;GAAE,GAAG,MAAM,CACnG,CACF;EACF;;EAGA,SAAgB,cAAc,OAIhB;GACZ,eAAe;GACf,MAAM,WAAW,OAAO,UAAU,KAAA;GAClC,MAAM,WAAW,aAAa,CAAC,QAAQ;GACvC,MAAM,QAAQ,WAAW,MAAM,QAAQ,SAAS;GAChD,MAAM,OAAO,WAAY,MAAM,QAAQ,QAAS,SAAS;GACzD,MAAM,UAAU,WAAY,MAAM,kBAAkB,CAAC,KAAM,SAAS;GAGpE,MAAM,CAAC,QAAQ,cAAA,GAAaH,MAAAA,SAAAA,CAAwB,IAAI;GACxD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,UAAU,MAAM;IACpB,IAAI,MAAM,UAAU,WACd;SAAA,MAAM,UAAU,KAAA,GAAW,UAAU,MAAM,KAAK;IAAA,OAC/C,IAAI,MAAM,UAAU,SACzB,UAAU,IAAI;GAElB,GAAG,CAAC,KAAK,CAAC;GAEV,IAAI,MACF,QAAA,GAAOG,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GACpDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,YAAY,GAAG,GAAG,IAAA,GACpDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,YAAY,GAAG,oBAAoB,CACrE;GAGF,IAAI,UAAU,QAAQ,MAAM,UAAU,YACpC,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GACpDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,YAAY,GAAG,WAAW,CAC5D;GAGF,IAAI,MAAM,UAAU,UAAU;IAE5B,IAAI,WAAW,MACb,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GACpDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,eAAe,IAAA,GAC/CA,MAAAA,cAAAA,CAAc,OAAO;KAAE,KAAK;KAAQ,KAAK;KAAY,OAAO;KAAK,QAAQ;KAAK,WAAW;IAAkB,CAAC,IAAA,GAC5GA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,oBAAoB,IAAA,GACpDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,qBAAqB,GAAG,QAAQ,IAAA,GAChEA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,mBAAmB,GAAG,aAAa,CACrE,CACF,CACF;IAEF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GAClDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,GAAG,IAAI,IAAA,GAC5DA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,mBAAmB,IAAA,GACnDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,oBAAoB,GAAG,MAAM,IAAA,GAC7DA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,kBAAkB,GAAG,uBAAuB,CAC9E,CACF,CACF;GACF;GAEA,IAAI,MAAM,UAAU,UAClB,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GACpDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,YAAY,GAAG,IAAI,IAAA,GACrDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,MAAM,IAAA,GACtDA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,YAAY,GAAG,MAAM,MAAM,IAAA,GAC3DA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,WAAW,IAAA,GAC3CA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAA8B,eAAe;KAAE,OAAO,SAAS,OAAO;IAAG;GAAE,GAAG,IAAI,CACzH,CACF;GAGF,IAAI,MAAM,UAAU,SAClB,QAAA,GAAOA,MAAAA,cAAAA,CAAc,WAAW;IAAE,OAAO,MAAM;IAAO;GAAQ,CAAC;GAGjE,QAAA,GAAOA,MAAAA,cAAAA,CAAc,aAAa,EAAE,MAAM,CAAC;EAC7C;;;;;;;;;;;;;;;;;;;;ECxdA,MAAM,WAAW;;EAGjB,SAAS,uBAA6B;GACpC,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,OAAO,aAAa,aAAa;IACrC,IAAI,SAAS,eAAe,QAAQ,MAAM,MAAM;IAChD,MAAM,QAAQ,SAAS,cAAc,OAAO;IAC5C,MAAM,KAAK;IACX,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6FpB,SAAS,KAAK,YAAY,KAAK;IAC/B,aAAa;KAAE,MAAM,OAAO;IAAG;GACjC,GAAG,CAAC,CAAC;EACP;;EAGA,SAAS,OAAO,EAAE,SAAS,OAAO,YAEpB;GACZ,QAAA,GAAOC,MAAAA,cAAAA,CAAc,UAAU;IAC7B,MAAM;IAAU,MAAM;IAAU,gBAAgB;IAAS,cAAc;IACvE,WAAW;IACX,eAAe;KAAE,SAAS,CAAC,OAAO;IAAG;GACvC,IAAA,GAAGA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,qBAAqB,CAAC,CAAC;EAC/D;;EAGA,SAAS,UAAU,EAAE,OAAO,SAAS,UAAU,SAGjC;GACZ,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,WAAW,MAAM,EAAE,UAAU,KAAK,CAAC;GACrE,MAAM,aAAa;IACjB,qBAAqB,QAAQ;IAC7B,qBAAqB;GACvB;GACA,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO;IAAE,WAAW;IAAa,MAAM;IAAW,cAAc;IAAO,OAAO;GAAW,IAAA,GAC5GA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,sBAAsB,CAAC,GAC1D,QAAQ,KAAK,OAAA,GAAMA,MAAAA,cAAAA,CAAc,UAAU;IACzC,KAAK,EAAE;IAAO,MAAM;IAAU,MAAM;IAAO,iBAAiB,EAAE,UAAU;IACxE,WAAW;IAAiB,eAAe;KAAE,SAAS,EAAE,KAAK;IAAG;GAClE,GAAG,EAAE,KAAK,CAAC,CACb;EACF;;EAGA,SAAS,UAAU,EAAE,OAAO,MAAM,SAAS,YAE7B;GACZ,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GAC7CA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,cAAc,GAAG,KAAK,IAAA,GACzDA,MAAAA,cAAAA,CAAc,QAAQ;IAAE;IAAS;IAAO;GAAS,CAAC,CACpD,GACA,SAAS,KAAA,IAAY,QAAA,GAAOA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,IAAI,CAClF;EACF;;EAGA,SAAS,SAAS,EAAE,OAAO,MAAM,OAAO,aAAa,YAEvC;GACZ,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,cAAc,GAAG,KAAK,IAAA,GACzDA,MAAAA,cAAAA,CAAc,SAAS;IACrB,WAAW;IAAe;IAAO;IAAa,YAAY;IAC1D,WAAW,UAAyC;KAAE,SAAS,MAAM,cAAc,KAAK;IAAG;GAC7F,CAAC,GACD,SAAS,KAAA,IAAY,QAAA,GAAOA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,IAAI,CAClF;EACF;;EAGA,SAAS,QAAQ,EAAE,OAAO,MAAM,OAAO,MAAM,YAE/B;GACZ,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,cAAc,GAAG,KAAK,IAAA,GACzDA,MAAAA,cAAAA,CAAc,YAAY;IACxB,WAAW;IAA8B;IAAO,MAAM,QAAQ;IAC9D,WAAW,UAA4C;KAAE,SAAS,MAAM,cAAc,KAAK;IAAG;GAChG,CAAC,GACD,SAAS,KAAA,IAAY,QAAA,GAAOA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,IAAI,CAClF;EACF;;EAGA,SAAS,aAAa,EAAE,OAAO,MAAM,OAAO,SAAS,YAGvC;GACZ,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GACrDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GAC7CA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,cAAc,GAAG,KAAK,IAAA,GACzDA,MAAAA,cAAAA,CAAc,WAAW;IAAE;IAAO;IAAS;IAAU;GAAM,CAAC,CAC9D,GACA,SAAS,KAAA,IAAY,QAAA,GAAOA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,IAAI,CAClF;EACF;EAIA,MAAM,eAAoE;GACxE;IAAE,OAAO;IAAQ,OAAO;GAAM;GAC9B;IAAE,OAAO;IAAa,OAAO;GAAM;GACnC;IAAE,OAAO;IAAY,OAAO;GAAK;EACnC;;EAGA,SAAS,aAAa,GAAY,GAAqB;GACrD,OAAO,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;EAC/C;;;;;;;EAQA,SAAgB,YAAY,OAA2C;GACrE,qBAAqB;GACrB,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,CAA4B,IAAI;GAC9D,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAA4B,IAAI;GACxD,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAkD,IAAI;GAClF,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAwB,IAAI;GAE9D,MAAM,YAAY,OAAO;GAEzB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,UAAU;IACd,MAAW,kBAAkB,EAAE,OAAO,WAAW,CAAC,CAAC,CAChD,KAAK,OAAO,QAAQ;KACnB,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,QAAQ,IAAI,QAAQ;KACjD,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,IAAI,SAAS;KACb,WAAW,KAAK,MAAM;KACtB,QAAQ,KAAK,MAAM;IACrB,CAAC,CAAC,CACD,OAAO,QAAiB;KACvB,IAAI,CAAC,SAAS,aAAa,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;IAC7E,CAAC;IACH,aAAa;KAAE,UAAU;IAAM;GACjC,GAAG,CAAC,SAAS,CAAC;GAEd,MAAM,SAAA,GAAQC,MAAAA,YAAAA,EAAyC,KAAQ,UAA+B;IAC5F,SAAS,YAAY,YAAY,OAAO,UAAU;KAAE,GAAG;MAAU,MAAM;IAAM,CAAC;IAC9E,UAAU,IAAI;GAChB,GAAG,CAAC,CAAC;GAEL,MAAM,UAAA,GAASA,MAAAA,YAAAA,EAAa,UAA2B;IACrD,MAAM,eAAe;IACrB,IAAI,QAAQ,YAAY,QAAQ,SAAS,MAAM;IAC/C,MAAM,UAAmC,CAAC;IAC1C,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAChC,IAAI,CAAC,aAAa,KAAK,MAAM,QAAQ,IAAI,GACvC,QAAQ,OAAO,KAAK;IAGxB,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,GAAG;IAGvC,IAAI,QAAQ,WAAW,KAAA,GAAW;KAChC,MAAM,IAAI,QAAQ;KAClB,QAAQ,SAAS;MACf,GAAG;MACH,UAAU,EAAE,SAAS,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO;MACxD,YAAY,EAAE,WAAW,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO;KAC9D;IACF;IAEA,QAAQ,IAAI;IACZ,MAAW,kBAAkB;KAC3B,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAAC,CACC,KAAK,OAAO,QAAQ;KACnB,MAAM,OAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;KAC/C,IAAI,IAAI,MAAM,KAAK,OAAO,MAAM;MAC9B,UAAU;OAAE,IAAI;OAAM,SAAS,KAAK,WAAW;MAAgB,CAAC;MAChE,WAAW,IAAI;MACf;KACF;KACA,UAAU;MAAE,IAAI;MAAO,SAAS,KAAK,SAAS,aAAa,IAAI,OAAO;KAAG,CAAC;IAC5E,CAAC,CAAC,CACD,OAAO,QAAiB;KACvB,UAAU;MAAE,IAAI;MAAO,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAAE,CAAC;IACpF,CAAC,CAAC,CACD,cAAc;KAAE,QAAQ,KAAK;IAAG,CAAC;GACtC,GAAG;IAAC;IAAM;IAAM;GAAO,CAAC;GAExB,IAAI,cAAc,MAChB,QAAA,GAAOF,MAAAA,cAAAA,CAAc,KAAK;IAAE,WAAW;IAAc,OAAO,EAAE,SAAS,SAAS;GAAE,GAChF,UAAU,WAAW;GAEzB,IAAI,YAAY,QAAQ,SAAS,MAC/B,QAAA,GAAOA,MAAAA,cAAAA,CAAc,KAAK;IAAE,WAAW;IAAc,OAAO,EAAE,SAAS,SAAS;GAAE,GAAG,SAAS;GAGhG,MAAM,QAAS,OAAO,KAAK,IAAI,CAAC,CAA6B,MAAM,QAAQ,CAAC,aAAa,KAAK,MAAM,QAAQ,IAAI,CAAC;GACjH,MAAM,SAA4B,KAAK,UAAU;IAAE,SAAS;IAAQ,UAAU,CAAC;IAAG,WAAW;IAAQ,YAAY,CAAC;GAAE;GAEpH,QAAA,GAAOA,MAAAA,cAAAA,CAAc,QAAQ;IAAE,WAAW;IAAc,UAAU;GAAO,IAAA,GACvEA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,oBAAoB,GAAG,MAAM,IAAA,GAC/DA,MAAAA,cAAAA,CAAc,cAAc;IAC1B,OAAO;IAAM,OAAO,OAAO;IAAS,SAAS;IAC7C,WAAW,MAAM;KAAE,MAAM,UAAU;MAAE,GAAG;MAAQ,SAAS;KAAE,CAAC;IAAG;GACjE,CAAC,GACD,OAAO,YAAY,eAAA,GACfA,MAAAA,cAAAA,CAAc,SAAS;IACrB,OAAO;IAAS,MAAM;IAAwB,MAAM;IACpD,OAAO,OAAO,SAAS,KAAK,IAAI;IAChC,WAAW,MAAM;KAAE,MAAM,UAAU;MAAE,GAAG;MAAQ,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;KAAE,CAAC;IAAG;GACnG,CAAC,IACD,OAAA,GACJA,MAAAA,cAAAA,CAAc,cAAc;IAC1B,OAAO;IAAM,OAAO,OAAO;IAAW,SAAS;IAC/C,WAAW,MAAM;KAAE,MAAM,UAAU;MAAE,GAAG;MAAQ,WAAW;KAAE,CAAC;IAAG;GACnE,CAAC,GACD,OAAO,cAAc,eAAA,GACjBA,MAAAA,cAAAA,CAAc,SAAS;IACrB,OAAO;IAAS,MAAM;IAAuB,MAAM;IACnD,OAAO,OAAO,WAAW,KAAK,IAAI;IAClC,WAAW,MAAM;KAAE,MAAM,UAAU;MAAE,GAAG;MAAQ,YAAY,EAAE,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;KAAE,CAAC;IAAG;GACrG,CAAC,IACD,OAAA,GAEJA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,oBAAoB,GAAG,MAAM,IAAA,GAC/DA,MAAAA,cAAAA,CAAc,WAAW;IACvB,OAAO;IAAiB,SAAS,KAAK,kBAAkB;IACxD,MAAM;IACN,WAAW,MAAM;KAAE,MAAM,kBAAkB,CAAC;IAAG;GACjD,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,WAAW;IACvB,OAAO;IAAQ,SAAS,KAAK,aAAa;IAC1C,MAAM;IACN,WAAW,MAAM;KAAE,MAAM,aAAa,CAAC;IAAG;GAC5C,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,WAAW;IACvB,OAAO;IAAY,SAAS,KAAK,mBAAmB;IACpD,MAAM;IACN,WAAW,MAAM;KAAE,MAAM,mBAAmB,CAAC;IAAG;GAClD,CAAC,IAAA,GAEDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,oBAAoB,GAAG,IAAI,IAAA,GAC7DA,MAAAA,cAAAA,CAAc,UAAU;IACtB,OAAO;IAAY,OAAO,KAAK,YAAY;IAAI,aAAa;IAC5D,WAAW,MAAM;KAAE,MAAM,YAAY,CAAC;IAAG;GAC3C,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,UAAU;IACtB,OAAO;IAAS,OAAO,KAAK,SAAS;IAAI,aAAa;IACtD,WAAW,MAAM;KAAE,MAAM,SAAS,CAAC;IAAG;GACxC,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,UAAU;IACtB,OAAO;IAAU,OAAO,KAAK,UAAU;IAAI,aAAa;IACxD,WAAW,MAAM;KAAE,MAAM,UAAU,CAAC;IAAG;GACzC,CAAC,IAAA,GAEDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,oBAAoB,GAAG,QAAQ,IAAA,GACjEA,MAAAA,cAAAA,CAAc,SAAS;IACrB,OAAO;IAAsB,OAAO,KAAK,eAAe;IACxD,WAAW,MAAM;KAAE,MAAM,eAAe,CAAC;IAAG;GAC9C,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,SAAS;IACrB,OAAO;IAAsB,OAAO,KAAK,gBAAgB;IACzD,WAAW,MAAM;KAAE,MAAM,gBAAgB,CAAC;IAAG;GAC/C,CAAC,GAED,KAAK,QAAQ,KAAA,KAAA,GACTA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,cAAc,IAAA,GAC9CA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,aAAa,IAAA,GAC7CA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,cAAc,GAAG,YAAY,IAAA,GAChEA,MAAAA,cAAAA,CAAc,QAAQ,EAAE,WAAW,aAAa,GAAG,IAAI,CACzD,IAAA,GACAA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,iBAAiB,GAAG,KAAK,GAAG,CAC9D,IACA,OAAA,GAEJA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,eAAe,GAC/C,WAAW,QAAA,GACPA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,OAAO,KAAK,oBAAoB,uBAAuB,IACjG,OAAO,KAAK,KAAK,SAAS,OAAO,OAAO,IAC3C,SAAA,GACEA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,GAAG,uBAAuB,KAAA,GACvEA,MAAAA,cAAAA,CAAc,KAAK,EAAE,WAAW,aAAa,CAAC,IAAA,GACpDA,MAAAA,cAAAA,CAAc,UAAU;IAAE,WAAW;IAAc,MAAM;IAAU,UAAU,QAAQ,CAAC;GAAM,GAC1F,OAAO,UAAU,IAAI,CACzB,CACF;EACF;;;ECrZA,MAAa,OAAO;EACpB,MAAa,SAAS;GAAC;GAAS;GAAgB;EAAkB;;EAGlE,MAAM,WAAW;;EAEjB,MAAM,SAAS;;EAEf,MAAM,eAAe;;EAErB,MAAM,mBAAmB;;EA8BzB,SAAS,gBAA2B;GAClC,QAAA,GAAOG,MAAAA,cAAAA,CAAc,OAAO;IAC1B,OAAO;IAAI,QAAQ;IAAI,SAAS;IAAa,MAAM;IAAQ,eAAe;GAC5E,IAAA,GACEA,MAAAA,cAAAA,CAAc,QAAQ;IACpB,GAAG;IACH,MAAM;GACR,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,QAAQ;IACpB,GAAG;IACH,MAAM;GACR,CAAC,IAAA,GACDA,MAAAA,cAAAA,CAAc,QAAQ;IACpB,UAAU;IACV,UAAU;IACV,GAAG;IACH,MAAM;GACR,CAAC,CACH;EACF;;EAGA,SAAS,uBAAkC;GACzC,MAAM,EAAE,OAAO,MAAM,YAAY,aAAa;GAC9C,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,OAAA,GAC1BA,MAAAA,cAAAA,CAAc,eAAe;IAAE;IAAO;IAAM;GAAQ,CAAC,IAAA,GACrDA,MAAAA,cAAAA,CAAc,aAAa,EAAE,WAAW,OAAO,MAAM,CAAC,CACxD;EACF;;EAGA,SAAS,YAAuB;GAC9B,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,kBAAkB,IAAA,GACzDA,MAAAA,cAAAA,CAAc,OAAO,EAAE,WAAW,yBAAyB,IAAA,GACzDA,MAAAA,cAAAA,CAAc,oBAAoB,CAAC,CACvC;EACF;;EAGA,SAAS,iBAAiB,EAAE,OAAO,MAAsD;GACvF,QAAA,GAAOA,MAAAA,cAAAA,CAAc,OAAO;IAC1B,OAAO;IAAM,QAAQ;IAAM,SAAS;IAAa,MAAM;IAAQ,eAAe;GAChF,IAAA,GACEA,MAAAA,cAAAA,CAAc,QAAQ;IAAE,GAAG;IAAkB,MAAM;GAAe,CAAC,CAAC;EACxE;;EAGA,SAAS,gBAAgB,EAAE,SAAS,aAAa,UAInC;GACZ,IAAI,SAAS,SAAS,YAAY,SAAS,SAAS,OAAO,OAAO;GAClE,IAAI,QAAQ,KAAK,SAAS,aAAa,OAAO;GAC9C,IAAI,QAAQ,SAAS,SAAS,QAAQ,KAAK,eAAe,aAAa,OAAO;GAC9E,QAAA,GAAOA,MAAAA,cAAAA,CAAc,UAAU;IAC7B,MAAM;IAAU,WAAW;IAAmB,SAAS;GACzD,GAAG,IAAI;EACT;EAEA,SAAgB,MAAM,KAAoB;GAExC,mBAAmB;GACnB,MAAM,OAAQ,IAA0D;GACxE,MAAM,QAAS,IAAuD;GACtE,MAAM,QAAS,IAAyC;GAExD,MAAM,YAA+B,CAAC;GAGtC,IAAI,UAAU,KAAA,GACZ,UAAU,KAAS,MAAM,OAAO,0BAA0B,MAAM,SAC9D;IAAE,MAAM;IAAoB,IAAI;IAAS,OAAO;IAAG,OAAO;GAAS,GACnE,oBACF,CAAC,CAAC;GAIJ,IAAI,SAAS,KAAA,KAAa,UAAU,KAAA,GAAW;IAC7C,UAAU,KAAK,KAAK,SAAS;KAC3B,IAAI;KACJ,MAAM;KACN,aAAa;KACb,OAAO,CAAC;MACN,IAAI;MACJ,OAAO;MACP,aAAa;MACb,mBAAmB;MACnB,MAAM;KACR,CAAC;IACH,CAAC,CAAC;IACF,UAAU,KAAK,MAAM,OAAO,gCAAgC,MAAM,SAChE;KAAE,MAAM;KAA0B,KAAK;IAAO,GAC9C,aACF,CAAC,CAAC;IAEF,UAAU,KAAK,eAAe,KAAK,CAAC;GACtC;GAGA,MAAM,YAAa,IAEhB;GACH,IAAI,OAAO,cAAc,YAGvB,UAAe,KAAK,KAAK,CAAC,QAAQ,IAAI,YAAqB;IACzD,MAAM,YAAa,QAA6C;IAChE,MAAM,SAAU,QAAkF;IAClG,IAAI,cAAc,KAAA,KAAa,WAAW,KAAA,GAAW,OAAO,KAAA;IAC5D,MAAM,WAAW,UAAU,OAAO,cAAc,UAAU,SACxD;KAAE,MAAM;KAAQ,KAAK;IAAiB,GACtC,SACF,CAAC;IACD,MAAM,cAAc,UAAU,OAAO,gCAAgC,UAAU,SAC7E;KACE,MAAM;KAA0B,IAAI;KAAiB,OAAO;KAC5D,eAAe;MACb,aAAa;MACb,cAAc,OAAO,YAAY,gBAAgB;KACnD;IACF,GACA,eACF,CAAC;IAED,MAAM,cAAc,UAAU,OAAO,2BAA2B,UAAU,SACxE;KACE,MAAM;KAAqB,IAAI;KAC/B,OAAO;KAAI,OAAO;IACpB,GACA,gBACF,CAAC;IACD,aAAa;KACX,YAAY;KACZ,YAAY;KACZ,SAAS;IACX;GACF,CAAC;GAGH,IAA0E,mBAAmB;IAC3F,KAAK,MAAM,WAAW,UAAU,QAAQ,GAAG,QAAQ;GACrD,GAAG,yBAAyB;EAC9B;;;;;;;;;;EAWA,SAAS,eAAe,OAAiD;GACvE,IAAI,UAAU;GACd,IAAI,SAAS,UAAU,KAAA;GACvB,IAAI;GAEJ,MAAM,YAAY,OAAqB;IACrC,QAAQ,iBAAiB;KAAE,KAAU;IAAG,GAAG,EAAE;GAC/C;GAEA,MAAM,OAAO,YAA2B;IACtC,IAAI,SAAS;IACb,IAAI,OAAO,aAAa,eAAe,SAAS,oBAAoB,UAAU;KAC5E,SAAS,GAAI;KACb;IACF;IACA,IAAI;KACF,MAAM,MAAM,MAAM,MAAM,iBAAiB,EAAE,OAAO,WAAW,CAAC;KAC9D,IAAI,IAAI,IAAI;MAEV,KAAI,MADgB,IAAI,KAAK,EAAA,CACpB,UAAU,aAAa,CAAC,UAAU,UAAU,KAAA,GACnD,IAAI;OACF,MAAM,QAAQ,QAAQ;OACtB,SAAS;MACX,SAAS,KAAK;OAEZ,QAAQ,MAAM,2BAA2B,GAAG;MAC9C;MAEF,SAAS,GAAI;MACb;KACF;KAEA,SAAS,GAAK;KACd;IACF,QAAQ,CAER;IACA,SAAS,GAAK;GAChB;GAEA,KAAU;GACV,aAAa;IAAE,UAAU;IAAM,IAAI,UAAU,KAAA,GAAW,aAAa,KAAK;GAAG;EAC/E"}
package/lib/config.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import Schema from '@deepseek-ai/schemastery';
5
5
  /** 访问控制子 Schema(独立导出:config 路由的服务端校验复用) */
6
6
  export const AccessControlSchema = Schema.object({
7
- c2cMode: Schema.union(['open', 'allowlist', 'disabled']).default('allowlist').description('C2C访问模式(默认白名单,空名单拒绝所有人)'),
7
+ c2cMode: Schema.union(['open', 'allowlist', 'disabled']).default('open').description('C2C访问模式(默认开放)'),
8
8
  c2cAllow: Schema.array(Schema.string()).default([]).description('C2C白名单(QQ OpenID)'),
9
9
  groupMode: Schema.union(['open', 'allowlist', 'disabled']).default('open').description('群聊访问模式(默认开放:群自带进群门槛 + @bot 触发)'),
10
10
  groupAllow: Schema.array(Schema.string()).default([]).description('群聊白名单(群 OpenID)'),
@@ -27,7 +27,7 @@ export const ConfigSchema = Schema.object({
27
27
  askTimeoutMs: Schema.number().default(5 * 60 * 1000).description('待答问题超时(ms),超时自动拒绝并提示'),
28
28
  historyLimit: Schema.number().default(10).description('群历史缓冲条数'),
29
29
  access: AccessControlSchema.default({
30
- c2cMode: 'allowlist',
30
+ c2cMode: 'open',
31
31
  c2cAllow: [],
32
32
  groupMode: 'open',
33
33
  groupAllow: [],
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -25,26 +25,22 @@ export interface HostAdapter {
25
25
  globalService(name: string): unknown | undefined;
26
26
  /** 官方 fork seed 构造;旧宿主无导出时返回 undefined */
27
27
  buildForkSeed(events: readonly unknown[], boundary: number): Promise<readonly unknown[] | undefined>;
28
- /** 会话 header 读取(取 meta.agentPreset 等);服务缺失或读取失败返回 undefined */
28
+ /** 会话 header 读取(取 agentPreset 等);会话不存在、服务缺失或读取失败返回 undefined */
29
29
  sessionHeader(sessionId: string): Promise<SessionHeaderLike | undefined>;
30
30
  /**
31
31
  * 会话是否存在于持久化层。
32
32
  *
33
- * 三种结果语义不同,调用方必须区分——把「判不出」当成「不存在」正是重建已存在
34
- * 会话、撞出重复 id 的根因:
35
- * - `true` / `false`:确定答案;
36
- * - `undefined`:旧宿主无该服务,没有求证手段;
37
- * - 抛出:求证过程本身失败(后端故障),不能据此断言会话不存在。
33
+ * `undefined` = 没有求证手段(宿主未注册 sessionPersistence,或其形态不含
34
+ * `stat`)。调用方不得把它当成「不存在」——那正是重建已存在会话、撞出重复
35
+ * id 的根因。后端真故障时照常抛出。
38
36
  */
39
37
  sessionExists(sessionId: string): Promise<boolean | undefined>;
40
38
  /** 探测结果摘要(启动契约检查用) */
41
39
  readonly capabilities: string[];
42
40
  }
43
- /** 会话持久化 header 的最小结构(只读插件关心的字段) */
41
+ /** 会话 header 的最小结构(只读插件关心的字段;`agentPreset` 在 header 顶层) */
44
42
  export interface SessionHeaderLike {
45
- meta?: {
46
- agentPreset?: string;
47
- };
43
+ agentPreset?: string;
48
44
  }
49
45
  export declare function createHostAdapter(ctx: Context, logger?: AdapterLogger): HostAdapter;
50
46
  /** 测试辅助:清空模块缓存 */
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/host/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,aAAa,CAAC,OAAO,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,SAAS,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;KAAE,GAAG,SAAS,OAAO,EAAE,CAAC;IACvH,uCAAuC;IACvC,UAAU,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAChF,iCAAiC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,0CAA0C;IAC1C,aAAa,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;IACrG,+DAA+D;IAC/D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACzE;;;;;;;;OAQG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/D,sBAAsB;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjC;AAiCD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAuFnF;AAWD,kBAAkB;AAClB,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/host/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,aAAa,CAAC,OAAO,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,SAAS,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;KAAE,GAAG,SAAS,OAAO,EAAE,CAAC;IACvH,uCAAuC;IACvC,UAAU,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAChF,iCAAiC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,0CAA0C;IAC1C,aAAa,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;IACrG,gEAAgE;IAChE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACzE;;;;;;OAMG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/D,sBAAsB;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwCD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAmFnF;AAWD,kBAAkB;AAClB,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -7,14 +7,15 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  /**
10
- * 宿主「会话不存在」错误的稳定 name。
10
+ * 取出可用的持久化服务;形态不匹配返回 undefined。
11
11
  *
12
- * 不 import `SessionPersistenceNotFoundError`:该类属 session-persistence 包
13
- * (插件未直接依赖),且跨 realm 的 instanceof 不可靠。只认 name,不做文案
14
- * 猜测——resume/load 的报错可能来自别的环节(preset 挂载、同 id 未释放),
15
- * 把它们误判成「会话不存在」会导致重建一个实际存在的会话。
12
+ * 宿主服务是版本漂移点,必须探测方法是否存在再调用:直接调用缺失的方法会抛
13
+ * `TypeError`,与「后端故障」混在一起,让调用方误以为求证过了。
16
14
  */
17
- const NOT_FOUND_NAME = 'SessionPersistenceNotFoundError';
15
+ function statCapablePersistence(ctx) {
16
+ const persistence = safeGet(ctx, 'sessionPersistence');
17
+ return typeof persistence?.stat === 'function' ? persistence : undefined;
18
+ }
18
19
  /** 模块级函数的动态 import 结果缓存(spec 变量路径绕开本地依赖类型检查) */
19
20
  const moduleCache = new Map();
20
21
  async function importModule(spec, logger) {
@@ -35,8 +36,10 @@ export function createHostAdapter(ctx, logger) {
35
36
  const capabilities = [];
36
37
  // events 读取路径只有运行时才能确定,sessionEvents 内自适应
37
38
  capabilities.push('sessionEvents(s自适应)');
38
- // persistence 可能在插件启动后才注册,sessionExists/sessionHeader 内每次取
39
- capabilities.push(safeGet(ctx, 'sessionPersistence') ? 'sessionPersistence(已注册)' : 'sessionPersistence(缺失,会话存在性判定降级)');
39
+ // 可能在插件启动后才注册,sessionExists/sessionHeader 内每次重新探测;此处仅记录启动时形态
40
+ capabilities.push(statCapablePersistence(ctx)
41
+ ? 'sessionPersistence.stat(可用)'
42
+ : 'sessionPersistence.stat(不可用,会话存在性判定降级)');
40
43
  let resolveFn;
41
44
  const presets = safeGet(ctx, 'agentPresets');
42
45
  if (presets && typeof presets.serviceFor === 'function') {
@@ -78,29 +81,21 @@ export function createHostAdapter(ctx, logger) {
78
81
  return safeGet(ctx, name);
79
82
  },
80
83
  async sessionHeader(sessionId) {
81
- const persistence = safeGet(ctx, 'sessionPersistence');
84
+ const persistence = statCapablePersistence(ctx);
82
85
  if (!persistence)
83
86
  return undefined;
84
87
  try {
85
- return await persistence.load(sessionId);
88
+ return (await persistence.stat(sessionId))?.header;
86
89
  }
87
90
  catch {
88
- return undefined;
91
+ return undefined; // 读不到 preset 不该阻断会话打开,回落到当前 effective preset
89
92
  }
90
93
  },
91
94
  async sessionExists(sessionId) {
92
- const persistence = safeGet(ctx, 'sessionPersistence');
95
+ const persistence = statCapablePersistence(ctx);
93
96
  if (!persistence)
94
97
  return undefined;
95
- try {
96
- await persistence.load(sessionId);
97
- return true;
98
- }
99
- catch (err) {
100
- if (err?.name === NOT_FOUND_NAME)
101
- return false;
102
- throw err; // 求证失败 ≠ 会话不存在
103
- }
98
+ return (await persistence.stat(sessionId)) !== undefined;
104
99
  },
105
100
  async buildForkSeed(events, boundary) {
106
101
  const mod = await importModule('@deepseek-ai/dsh-session/fork', logger);
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/host/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/host/adapter.ts"],"names":[],"mappings":"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"}
@@ -100,9 +100,9 @@ export declare class SessionManager {
100
100
  /**
101
101
  * resume 失败后是否允许首次创建。
102
102
  *
103
- * 只有确认会话不存在才可创建:损坏/占用/后端故障沿用同一 id 重建,会把同一
104
- * sessionId 写进多个 project 目录,宿主 `list()` 随后报 duplicate,会话列表
105
- * 整体打不开(对齐宿主 `restoreOrCreateConfigured` 的 fail-loud 语义)。
103
+ * 只有「会话确实不在盘上」才可创建:损坏/占用/后端故障沿用同一 id 重建,会把
104
+ * 同一 sessionId 写进多个 project 目录,宿主 `list()` 随后报 duplicate,会话
105
+ * 列表整体打不开(对齐宿主 `restoreOrCreateConfigured` 的 fail-loud 语义)。
106
106
  *
107
107
  * @returns 允许创建返回 true;拒绝时已记录 warn,调用方应抛出原 resume 错误。
108
108
  */
@@ -133,7 +133,7 @@ export class SessionManager {
133
133
  * 读不到(服务缺失 / session 不存在 / 未记录 agentPreset)返回 undefined。
134
134
  */
135
135
  async resolvePersistedPreset(sessionId) {
136
- return (await this.host.sessionHeader(sessionId))?.meta?.agentPreset;
136
+ return (await this.host.sessionHeader(sessionId))?.agentPreset;
137
137
  }
138
138
  // ── 模型相关(委托给 ModelResolver) ──
139
139
  getEffectiveModel(scope, peerId) {
@@ -483,9 +483,9 @@ export class SessionManager {
483
483
  /**
484
484
  * resume 失败后是否允许首次创建。
485
485
  *
486
- * 只有确认会话不存在才可创建:损坏/占用/后端故障沿用同一 id 重建,会把同一
487
- * sessionId 写进多个 project 目录,宿主 `list()` 随后报 duplicate,会话列表
488
- * 整体打不开(对齐宿主 `restoreOrCreateConfigured` 的 fail-loud 语义)。
486
+ * 只有「会话确实不在盘上」才可创建:损坏/占用/后端故障沿用同一 id 重建,会把
487
+ * 同一 sessionId 写进多个 project 目录,宿主 `list()` 随后报 duplicate,会话
488
+ * 列表整体打不开(对齐宿主 `restoreOrCreateConfigured` 的 fail-loud 语义)。
489
489
  *
490
490
  * @returns 允许创建返回 true;拒绝时已记录 warn,调用方应抛出原 resume 错误。
491
491
  */
@@ -496,7 +496,7 @@ export class SessionManager {
496
496
  exists = await this.host.sessionExists(sessionId);
497
497
  }
498
498
  catch (probeError) {
499
- // 求证本身失败(后端故障):无法断言不存在,按存在处理
499
+ // 求证本身失败(持久化后端故障):无法断言不在盘上,按存在处理
500
500
  this.logger.warn(`refusing to recreate session, existence unknown: ${context} probeErr=${errorText(probeError)}`);
501
501
  return false;
502
502
  }
@@ -505,8 +505,8 @@ export class SessionManager {
505
505
  return false;
506
506
  }
507
507
  if (exists === undefined) {
508
- // 旧宿主无 persistence 服务,没有求证手段:仅按 resume 结果创建
509
- this.logger.warn(`creating session without existence check (host lacks sessionPersistence): ${context}`);
508
+ // 宿主无 sessionPersistence.stat:没有求证手段,只能按 resume 结果创建(= 修复前行为)
509
+ this.logger.warn(`creating session without existence check (host lacks sessionPersistence.stat): ${context}`);
510
510
  }
511
511
  return true;
512
512
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"qr-svg.d.ts","sourceRoot":"","sources":["../../src/setup/qr-svg.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrE"}
1
+ {"version":3,"file":"qr-svg.d.ts","sourceRoot":"","sources":["../../src/setup/qr-svg.ts"],"names":[],"mappings":"AA2CA;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQrE"}
@@ -3,8 +3,33 @@
3
3
  *
4
4
  * 二维码图像在宿主生成而非浏览器:客户端 bundle 保持零第三方依赖
5
5
  * (externals 仅平台种子表),且二维码由可信源编码,页面无伪造面。
6
+ *
7
+ * qrcode 是 CJS 包:不同加载链下 `import` 的 interop 形态不同——
8
+ * Node 原生 ESM 得到 exports 本身;宿主插件加载链可能得到
9
+ * `{ default: exports }` 包裹,此时 QRCode.toString 落到
10
+ * Object.prototype.toString,静默产出 `[object Object]` 的烂二维码
11
+ * (页面裂图、无任何报错)。两层防御:
12
+ * 1. pickQrApi 按能力探测解包(只认自有 toString 属性);
13
+ * 2. 渲染结果 sanity 校验(非 <svg 开头即抛错 → 页面降级为链接)。
6
14
  */
7
- import QRCode from 'qrcode';
15
+ import * as qrcodeModule from 'qrcode';
16
+ /** 按「toString 是自有属性」逐层探测(覆盖 exports / {default} / namespace 三种 interop 形态) */
17
+ function pickQrApi() {
18
+ const seen = new Set();
19
+ let candidate = qrcodeModule;
20
+ for (let depth = 0; depth < 3 && candidate !== undefined && !seen.has(candidate); depth += 1) {
21
+ seen.add(candidate);
22
+ if (typeof candidate === 'object' || typeof candidate === 'function') {
23
+ const hasOwnToString = Object.prototype.hasOwnProperty.call(candidate, 'toString');
24
+ if (hasOwnToString && typeof candidate.toString === 'function') {
25
+ return candidate;
26
+ }
27
+ }
28
+ candidate = candidate.default;
29
+ }
30
+ throw new Error('qrcode API not found under any interop shape');
31
+ }
32
+ const QRCode = pickQrApi();
8
33
  /** 二维码渲染参数(输出 SVG,含 1 单位留白,240px 宽度适合侧栏展示) */
9
34
  const QR_OPTIONS = { type: 'svg', margin: 1, width: 240 };
10
35
  /**
@@ -15,6 +40,11 @@ const QR_OPTIONS = { type: 'svg', margin: 1, width: 240 };
15
40
  */
16
41
  export async function renderQrSvgDataUrl(url) {
17
42
  const svg = await QRCode.toString(url, QR_OPTIONS);
43
+ // sanity:interop 异常或库行为变化时 fail-loud(调用方 warn 并降级为链接),
44
+ // 而不是静默产出无效 data URL(用户看到裂图且无从排查)
45
+ if (typeof svg !== 'string' || !svg.startsWith('<svg')) {
46
+ throw new Error(`unexpected QRCode.toString result (${typeof svg})`);
47
+ }
18
48
  return `data:image/svg+xml;base64,${Buffer.from(svg, 'utf8').toString('base64')}`;
19
49
  }
20
50
  //# sourceMappingURL=qr-svg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qr-svg.js","sourceRoot":"","sources":["../../src/setup/qr-svg.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,8CAA8C;AAC9C,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,KAAc,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAClD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnD,OAAO,6BAA6B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACpF,CAAC"}
1
+ {"version":3,"file":"qr-svg.js","sourceRoot":"","sources":["../../src/setup/qr-svg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAOvC,8EAA8E;AAC9E,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;IAChC,IAAI,SAAS,GAAY,YAAY,CAAC;IACtC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC7F,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YACrE,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACnF,IAAI,cAAc,IAAI,OAAQ,SAAmC,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;gBAC1F,OAAO,SAAkB,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,SAAS,GAAI,SAAmC,CAAC,OAAO,CAAC;IAC3D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAE3B,8CAA8C;AAC9C,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,KAAc,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAClD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnD,uDAAuD;IACvD,kCAAkC;IAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,GAAG,GAAG,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,6BAA6B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACpF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cxyhhhhh/dsh-qqbot",
3
- "version": "0.5.4-dev.202610302146",
3
+ "version": "0.5.4-dev.202610302325",
4
4
  "icon": "./assets/icons/qq_logo.svg",
5
5
  "description": "在 QQ 私聊和群聊里直接对话 DeepSeek Harness。 Chat with DeepSeek Harness in QQ private and group chats.",
6
6
  "type": "module",
@@ -1,209 +0,0 @@
1
- # dsh 配置写入与会话 id 缺陷审查
2
-
3
- > 审查基线:`main@078c338`(0.5.4)
4
- > 复现用例:分支 `test/defect-repro-config-session`(提交 `0202760`)
5
- > 修复:D1 `e5902f6`、E3 `e49dadf`、E1/E2 与 D1 数值保真(本分支)
6
- > 日期:2026-10-30
7
-
8
- ## 1. 背景
9
-
10
- 用户反馈两类问题,需确认 0.5.4 是否已修复:
11
-
12
- 1. 以不恰当的方式操作 dsh 配置,安装后用户可能丢失自己的配置;
13
- 2. 以不恰当的方式固定会话 id(未沿用 dsh 的 UUID 方式),边界情况(如多进程并发)下会话列表可能出现重复 id,导致用户无法打开 dsh。
14
-
15
- ## 2. 结论速览
16
-
17
- | 问题 | 结论 |
18
- |---|---|
19
- | 1. 操作 dsh 配置 | **已修复**:`cordis.patch.yml` 与 `~/.dsh/settings.yaml` 写入均满足文档保真 + 原子写 |
20
- | 2. 固定会话 id | **已修复**:新 id 为 `session-${randomUUID()}`;确定性 id 仅用于迁移存量会话 |
21
-
22
- 缺陷清单与当前状态:
23
-
24
- | 编号 | 缺陷 | 严重度 | 状态 |
25
- |---|---|---|---|
26
- | D1 | `settings.yaml` 整文件 load+dump:丢注释、改值、非原子、无锁 | 高 | ✅ 已修复(`e5902f6` + 本分支补数值保真) |
27
- | E1 | `resume` 任何失败都当「会话不存在」,用同一 id 盲目 `create`,错误被吞 | 高 | ✅ 已修复(本分支) |
28
- | E2 | 并发窗口内用 0.5.x 确定性 legacy id 新建会话 | 高 | ✅ 已修复(本分支) |
29
- | E3 | `model-prefs.json` 无并发/崩溃保护,损坏后静默回落 legacy id | 中 | ✅ 已修复(`e49dadf`) |
30
- | — | 行首 tab 规范化会改写多行文本内容 | — | ❌ 误报,已澄清 |
31
-
32
- 修复后用例语义由「复现当前错误行为」改为「钉死修复后行为」,文件与分组保持不变。
33
-
34
- ## 3. 问题 1:dsh 配置写入
35
-
36
- ### 3.1 已修复:`cordis.patch.yml`(提交 17a5c80、9d2cc6c)
37
-
38
- `src/setup/persist.ts` 改用 eemeli/yaml Document API 原地编辑,满足四条约束:
39
-
40
- | 约束 | 位置 |
41
- |---|---|
42
- | 文档保真(注释/锚点/`!!js`/insert 行原样保留) | `applyEdit`、`PARSE_OPTIONS` |
43
- | fail-closed(非法 YAML / 顶层非数组 / config 非映射 / 锚点共享拒写) | `parseProfilePatch`、`findEntryConfig`(128-178 行) |
44
- | 原子写(同目录临时文件 + rename) | `editProfilePatch`(97-105 行) |
45
- | 乐观校验 + 读回验证 + 回滚 | `editProfilePatch`(89-122 行) |
46
-
47
- 三个入口 `persistCredentialsToProfile` / `removeCredentialsFromProfile` / `updateProfileConfig`(234-375 行)只改 `im-qqbot` 条目;`updateProfileConfig` 不碰 `appId/appSecret`。调用方:`src/index.ts:51`、`src/setup/index.ts:133`、`src/setup/bind-routes.ts:151/328`。测试:`persist.test.ts`、`bind-integration.test.ts`。
48
-
49
- > 设计行为(非缺陷,需知悉):扫码重新绑定会把私聊白名单 `c2cAllow` 整体替换为扫码者一人(`overwriteC2cAllowlist`,205-214 行)。原本配置了多人白名单的用户会感知为「配置被覆盖」。
50
-
51
- ### 3.2 已修复:D1 `~/.dsh/settings.yaml`(提交 e5902f6,数值保真见本分支)
52
-
53
- **位置**:`src/media/vision-tool.ts` `ensureVisionInputModal`,由 `src/gateway/bootstrap.ts` 在每次启动时调用。
54
-
55
- **触发条件**:`vision.enabled` 且该视觉模型未声明 `input: [..., image]`。补齐后幂等,因此每个模型通常只在首次启动时触发一次。
56
-
57
- 采纳了修复建议 2(叶子级编辑而非停写)。改动后满足:
58
-
59
- | 约束 | 实现 |
60
- |---|---|
61
- | 文档保真 | `parseDocument` + 逐层 `get` 定位到目标模型后 `model.set('input', ...)`,注释/锚点/其他命名空间原文保留 |
62
- | 数值保真 | `parseDocument(..., { intAsBigInt: true })`,整数不经 double 中转(否则大整数回写丢精度) |
63
- | 原子写 | 同目录临时文件 + `renameSync`,失败时清理临时文件 |
64
- | 乐观校验 | 写前重读比对,窗口内被外部改动则放弃本次补写(幂等,下次启动重试) |
65
- | fail-closed | 解析失败 / 定位不到目标只 `warn`,不阻断启动、不写文件 |
66
-
67
- **回归用例**:`src/media/vision-tool.test.ts` 覆盖注释与锚点保真(D1-1)、其他命名空间值保真(D1-2)、原子写与无临时文件残留(D1-3)、乐观校验让宿主写入胜出(D1-4);`src/media/vision-modal.test.ts` 覆盖补写生效、幂等、fail-closed、tab 归一化。
68
-
69
- **遗留(低风险,已评估)**:未使用宿主 `dsh-settings-file` 的跨进程写锁(`withFileLock`),乐观校验只把竞态窗口收窄到「读回比对 → rename」之间;临时文件名固定 `.imqqbot.tmp`,多进程同时首启会互相踩。该路径每模型仅首启触发一次且失败不损坏原文件,暂不引入锁依赖。
70
-
71
- ## 4. 问题 2:会话 id
72
-
73
- ### 4.1 已修复(提交 0a1abbb)
74
-
75
- `src/session/session-id.ts`:
76
-
77
- - `mintSessionId()` = `session-${randomUUID()}`,与宿主一致(`packages/host/apiproxy/src/api-proxy.ts:2168/2415`);
78
- - `legacyDerivedSessionId()` 保留 0.5.x 的 SHA-256 派生算法,**仅用于定位存量会话**。
79
-
80
- `src/session/session-manager.ts` 用到新 id 的位置:
81
-
82
- | 场景 | 位置 |
83
- |---|---|
84
- | `/model` 切换 fork 子会话 | 328 行 |
85
- | `/new` | 591 行 |
86
- | 首次创建 | 536-541 行 |
87
- | legacy 迁移:resume 命中则沿用并落盘 | 455-465、515、533 行 |
88
-
89
- ### 4.2 已修复:E1 resume 失败按原因分流
90
-
91
- **原缺陷**:`getOrCreate` 的 `catch {}` 吞掉错误,prefs 已记录 id X 时,`resume(X)` 无论因何失败(日志损坏、IO 错误、HMR 期间同 id 未释放、preset 挂载失败等)都会接着 `create(X)`。宿主自身只在确认磁盘不存在时才 create(`packages/core/agent-loop/src/index.ts` 406-428 行,注释 “corruption and backend failures stay loud”)。
92
-
93
- **后果**(修复前):跨进程且两个进程 cwd 不同时,jsonl 后端 `link()` 的 EEXIST 保护只覆盖同一 project 目录,同一 id 落在两个目录,之后 `list()` 抛 `duplicate JSONL session id`,**会话列表整体无法打开**——即用户反馈的现象;0.5.x 老会话遇一次瞬时错误即被永久弃用。
94
-
95
- **修复**:宿主调用收口到 `src/host/adapter.ts`(该文件的定位就是「收口所有版本漂移点」),`session-manager` 不再直接 `ctx.get('sessionPersistence')`。
96
-
97
- - adapter 新增 `sessionExists(sessionId): Promise<boolean | undefined>`,三种结果语义互不混同:
98
- | 结果 | 含义 | 调用方动作 |
99
- |---|---|---|
100
- | `true` | 会话在盘上 | 拒绝重建,warn 后抛原 resume 错误 |
101
- | `false` | 宿主报 `SessionPersistenceNotFoundError` | 允许首次创建 |
102
- | `undefined` | 旧宿主无该服务,无求证手段 | 按 resume 结果创建,warn 留痕 |
103
- | 抛出 | 求证过程本身失败(后端故障) | 拒绝重建,不能据此断言不存在 |
104
- - **判定只认错误 `name`**,不做 `cause` 链回溯、不做 `ENOENT`、不做文案猜测。参照 `dsh-im` 的 `isSessionNotFound`(只比对 code)与其注释「never recognize arbitrary internal failures」:resume/load 的报错可能来自别的环节(preset 挂载、工具缺失、同 id 未释放),宽泛的文案匹配会把「工具 not found」误判成「会话不存在」,恰好触发本要防的重建。不 import 宿主错误类——插件未直接依赖 session-persistence 包,跨 realm 的 `instanceof` 也不可靠。
105
- - 顺带把原先散落的 `resolvePersistedPreset` 的 `ctx.get` 也收到 adapter 的 `sessionHeader`。
106
- - `mayCreateAfterResumeFailure(key, sessionId, resumeError)` 只负责按上表分流并记日志,返回 false 时由调用方抛原 resume 错误(原错误信息量大于求证错误)。
107
-
108
- > 比建议的 `list()` 更省:`load` 是单条查询,且只在 create 路径触发一次。
109
-
110
- **回归用例**:adapter 侧 4 个(load 成功 / NotFound name / 文案含 not found 但 name 不符 → 抛 / 无服务 → undefined);session-manager 侧 E1-1(会话在盘上不重建、prefs 不改写、日志可见)、E1-2(瞬时错误不弃用 legacy,故障恢复后仍能恢复)、E1-3(求证失败按存在处理,抛原 resume 错误)、E1-4(确认缺失 → 即使 resume 报 IO 错误也允许创建)、E1-5(旧宿主降级路径留痕)。
111
-
112
- ### 4.3 已修复:E2 确定性 id 不进入新建路径
113
-
114
- **原缺陷**:prefs 为空时候选为 legacy id L,`resume(L)` 等待期间 prefs 被并发写入会使 `if (!getSessionId(key))` 不成立,局部 `sessionId` 仍为 L,于是用 0.5.x 确定性 id 新建会话;同时同 key 并发 `getOrCreate` 会各自 create,先建的 agent 被覆盖且未 dispose。
115
-
116
- 并发写入来源未变:`/new` 同步写 prefs,`/compact` 从磁盘拉起会话,斜杠指令位于 `concurrencyGuard` 之前(`src/gateway/middleware-setup.ts`)。
117
-
118
- **修复**:
119
-
120
- - `openSession` 进入时记录 `candidateIsLegacy`(prefs 是否 miss),不再以「此刻 prefs 是否为空」作判据;
121
- - 新增 `resolveCreateId(key, candidate, candidateIsLegacy)`:prefs 在窗口内被改写则采用其最新 id(内存与 prefs 指向同一会话);候选来自 legacy 派生则一律铸造新 id;候选来自 prefs 且确认缺失则沿用该 id;
122
- - create 成功后统一 `persistSessionId`,内存与 prefs 不再分叉;
123
- - `getOrCreate` 外层加 per-key singleflight(`inflight` Map):同 key 并发复用同一次 resume/create,后到者只更新回复目标与活跃时间;完成或失败后清理在途记录。
124
-
125
- **回归用例**:E2-1(`/new` 并发写入 → 采用 prefs 最新 id,不用 legacy)、E2-2(`/compact` 与普通消息并发 → 一次 resume/create、无多余 agent)、E2-3(singleflight 失败时双方收到同一错误且在途记录已清理)。
126
-
127
- ### 4.4 已修复:E3 `model-prefs.json` 并发/崩溃保护(提交 e49dadf)
128
-
129
- 原缺陷:映射只存于全局 `~/.dsh-qqbot/model-prefs.json`,启动读一次、之后全量快照覆盖写(非原子、无锁、写前不重读),读取失败仅在 debug 下打日志。
130
-
131
- 修复后(`src/model/prefs-store.ts`):同目录临时文件(名带 pid + 随机后缀,跨进程互不覆盖)+ rename;`mergeDisk` 写前重读按 key 合并,内存覆盖同 key;引入**删除墓碑**防止「本进程的删除被并发写复活」(建议之外的补充);加载失败经 `onError` 无条件告警;发现损坏先备份到 `.corrupted.<ts>` 再覆盖,保留人工恢复的余地。
132
-
133
- **回归用例**:`prefs-store.test.ts` 覆盖多实例写前合并、内存覆盖同 key、外部写入新 key 不丢、删除墓碑、原子写与临时文件清理;`session-manager.test.ts` E3-4 钉死「映射丢失留下可见日志」。
134
-
135
- ### 4.5 其他
136
-
137
- - `session-manager.ts` 头部过时注释(「SessionId 由 sessionKey 确定性派生」)已更新为当前语义:映射存于 prefs,新 id 由 `mintSessionId()` 铸造,确定性 id 仅用于迁移;
138
- - 宿主调用统一经 `host/adapter.ts`,`session-manager` 内不再出现 `ctx.get`(`agentPresets` 的读取仍在 manager 内,因其返回的是插件自有服务契约而非宿主漂移点)。
139
-
140
- ### 4.6 与 dsh-im 的做法对照
141
-
142
- `dsh-im` 走 RPC 架构,但同一问题的处理方式可直接借鉴,本次修复据此收紧:
143
-
144
- | 关注点 | dsh-im | 本插件 |
145
- |---|---|---|
146
- | 判定收口 | `shared/session-error.mjs` 导出 `isSessionNotFound(code)`,13 处调用方只问布尔 | `host/adapter.ts` 导出 `sessionExists(id)`,调用方只看三态 |
147
- | 判定严格度 | 只比对 code(`session-not-found` / `session/not-found`),注释明示不认任意 internal 错误 | 只比对错误 `name`,不做 cause 回溯/文案猜测 |
148
- | 旧宿主兼容 | 单独的 `isSessionLogCorrupt`,**限定** method 白名单 + 特定文案签名才认 | `sessionExists` 返回 `undefined` 表示无求证手段,不猜 |
149
- | 存在性求证 | `sessionExists()` 先查归档再读 history,归档算存在(否则会静默绑新会话) | `load` 单条查询,求证失败则抛而非当作不存在 |
150
-
151
- 本次按此修正了初版实现的两处过度设计:删掉 `resume-failure.ts` 的 8 层 `cause` 回溯与 `/not found|no such|does not exist/i` 宽泛正则(该正则会把「工具 not found」误判成「会话不存在」),把宿主访问从 `session-manager` 挪进 adapter。
152
-
153
- ## 5. 误报澄清
154
-
155
- 此前判断「行首 tab 规范化 `/^\t+/gm` 会改写多行文本块(如提示词)内容」**不成立**:
156
-
157
- - 合法 YAML 中第 0 列 tab 不可能出现在块标量内部(js-yaml 直接报 `tab characters must not be used in indentation`);
158
- - 块内缩进之后的 tab 不匹配 `/^\t+/m`;
159
- - 多行引号字符串续行前导空白在折叠时本就被剥离。
160
-
161
- 该规范化只影响宿主本身也无法解析的非法文件。用例「误报澄清」固定该结论。
162
-
163
- ## 6. 验证方法
164
-
165
- ### 6.1 用例约定
166
-
167
- - 用例现已全部为回归用例,断言**修复后的期望行为**;原「缺陷复现」断言(钉死当时的错误行为)已随修复逐条翻转,编号与分组保留,便于对照本文档追溯;
168
- - 每组配有「对照组」用例,证明测试装置本身正确(正常路径行为符合预期)。
169
-
170
- ### 6.2 隔离手段
171
-
172
- | 依赖 | 隔离方式 |
173
- |---|---|
174
- | `~/.dsh-qqbot` | `vi.mock('../shared/dirs.ts')` 指向临时目录,不触碰真实插件目录 |
175
- | `~/.dsh/settings.yaml` | `DSH_HOME` 指向临时目录 |
176
- | 写入中途失败 / 宿主并发写 | `vi.mock('node:fs')` 包装 `writeFileSync` / `readFileSync` 注入钩子 |
177
- | 宿主 agent 注册表 | fake `get/resume/create`,用 deferred Promise 精确控制并发时序 |
178
- | 宿主 persistence | `persistenceCtx(load)` 注入替身,覆盖 `sessionExists` 的四种结果;默认 `absentCtx`(磁盘无会话)对应全新用户,`emptyCtx`(无服务)对应旧宿主降级 |
179
-
180
- ### 6.3 变异检查
181
-
182
- 修复前曾临时为 `getOrCreate` 加最小修复(非「不存在」错误向上抛 + legacy 候选一律铸造)以排除「用例空转」:E1/E2 共 4 个用例全部变红,对照组保持通过。修复落地后这 4 个用例按期望行为重写,仍由同一组装置驱动。
183
-
184
- ### 6.4 运行
185
-
186
- ```bash
187
- pnpm install --frozen-lockfile
188
- pnpm vitest run
189
- pnpm tsc
190
- ```
191
-
192
- 结果:26 个文件 291 个用例全部通过,`tsc` 无错。项目以 pnpm 管理依赖(`pnpm-lock.yaml`),仓库内的 `package-lock.json` 并非事实源,勿用 `npm ci`。
193
-
194
- ## 7. 覆盖边界
195
-
196
- - 「会话列表出现重复 id 导致 dsh 无法打开」的最终后果发生在宿主侧,插件单测无法覆盖;单测钉死的是插件侧前提——不再对已存在 id / legacy 固定 id 发起 create,宿主侧行为依据阅读 deepseek-harness 源码;
197
- - `sessionExists` 在旧宿主(无 `sessionPersistence`)上返回 `undefined`,此时退回「按 resume 结果创建」——等同修复前行为,E1-5 钉死该降级路径会留日志,但真实旧宿主未实测;
198
- - 项目当前无 ESLint 配置,`pnpm lint` 不可用。
199
-
200
- ## 8. 变更影响评估
201
-
202
- | 问题 | 回答 |
203
- |---|---|
204
- | 影响接口 | 会话创建/恢复(所有入站消息、`/new`、`/compact`、`/model`);启动时视觉配置自检 |
205
- | 向后兼容 | legacy 迁移语义保持:prefs 未命中时仍探测 legacy 一次,resume 命中则沿用并落盘 |
206
- | 行为变更 | resume 因非缺失原因失败时不再静默重建,改为向上抛——用户会看到报错而非被切到空会话;故障恢复后原会话历史仍在 |
207
- | 灰度 | 会话路由变更影响全部用户,建议先在测试 bot 验证老用户(0.5.x 会话)恢复路径 |
208
- | 数据迁移 | 无 DDL;`model-prefs.json` 格式不变 |
209
- | 回滚 | 代码回滚即可;E3 修复引入的备份文件不影响旧版本读取 |