opencode-claude-code-ua 0.0.0-stage → 0.3.6

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/ui/pro.html ADDED
@@ -0,0 +1,348 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>UA PRO · 出站兼容管理</title>
8
+ <script src="./theme.js"></script>
9
+ <link rel="stylesheet" href="./pro.css">
10
+ <link rel="icon" type="image/svg+xml" href="./icon.svg">
11
+ <script type="module" src="./ui/pro.js"></script>
12
+ </head>
13
+ <body>
14
+ <div id="pro-shell" class="pro-shell" data-ready="false">
15
+ <aside class="pro-side">
16
+ <a class="pro-brand" href="#overview" aria-label="UA PRO 概览"><span class="pro-mark" aria-hidden="true"><img src="./icon.svg" width="40" height="40" alt=""></span><span class="pro-brand-text"><span class="pro-eyebrow">MAGPIE</span><strong>UA PRO</strong><small>Claude Code · Codex 出站兼容</small></span></a>
17
+ <p class="pro-side-copy">配置连接,选择模板,<br>用真实模型验证请求。</p>
18
+ <nav id="pro-nav" class="pro-nav" data-nav aria-label="UA PRO 分区">
19
+ <a href="#overview" data-view-link="overview">概览</a>
20
+ <a href="#connections" data-view-link="connections">连接与模型</a>
21
+ <a href="#templates" data-view-link="templates">模板库</a>
22
+ <a href="#tests" data-view-link="tests">测试</a>
23
+ <a href="./accounts" data-leave="accounts">余额与签到<span class="nav-ext">独立页面</span></a>
24
+ <a href="#settings" data-view-link="settings">设置</a>
25
+ </nav>
26
+ <dl class="pro-side-meta">
27
+ <div class="pro-local-note"><dt>本地保存</dt><dd>密钥只存本机,不会显示在页面上。</dd></div>
28
+ <div><dt>配置 generation</dt><dd id="pro-generation" class="mono">—</dd></div>
29
+ <div><dt>运行</dt><dd id="pro-runtime">读取中</dd></div>
30
+ </dl>
31
+ </aside>
32
+
33
+ <main class="pro-main" id="pro-main">
34
+ <header class="pro-head">
35
+ <div class="pro-head-text"><h1 id="pro-title">概览</h1><p id="pro-status" role="status">正在读取 UA PRO 状态…</p></div>
36
+ <div class="pro-head-actions"><button id="pro-reload" type="button" class="ghost">重新读取</button><button id="pro-close" type="button" class="ghost">完成并关闭</button></div>
37
+ </header>
38
+ <div id="pro-error" class="pro-alert" role="alert" tabindex="-1" hidden></div>
39
+ <div id="pro-pending" class="pro-pending" role="status" hidden>
40
+ <p id="pro-pending-text">操作结果未确认。</p>
41
+ <div class="pending-actions"><button id="pro-recover" type="button" class="primary">查询操作结果</button><button id="pro-unlock" type="button" class="ghost" hidden>重新读取并解锁</button></div>
42
+ </div>
43
+
44
+ <section id="view-overview" data-view="overview" aria-labelledby="pro-title">
45
+ <div id="overview-metrics" class="metrics"></div>
46
+ <div id="overview-empty" class="empty" hidden>
47
+ <h2>还没有连接</h2>
48
+ <p>添加站点地址和 key 后即可使用。未指定模板时按协议自动绑定:Responses 用 Codex,Messages 用 Claude Code,Chat Completions 与 Gemini 普通转发。</p>
49
+ <button type="button" class="primary" data-action="connection-new">添加连接</button>
50
+ </div>
51
+ <div class="panel">
52
+ <div class="panel-head"><h2>连接与生效状态</h2><a href="#connections" class="link">管理连接</a></div>
53
+ <div id="overview-connections" class="overview-list"></div>
54
+ </div>
55
+ <p class="note">保存成功只表示配置已写入文件;正在运行的宿主是否已采用,以实际请求观察到的 generation 为准。</p>
56
+ </section>
57
+
58
+ <section id="view-connections" data-view="connections" aria-labelledby="pro-title" hidden>
59
+ <div class="toolbar"><p>同一站点可以有多个 key;每个连接独立锁定模板版本与模型能力。</p><div class="toolbar-actions"><button id="binding-open" type="button" class="ghost">应用模板</button><button id="connection-new" type="button" class="primary" data-action="connection-new">添加连接</button></div></div>
60
+ <div class="split">
61
+ <div id="connection-list" class="conn-list"></div>
62
+ <div id="connection-panel" class="side-panel" hidden>
63
+ <form id="connection-form" class="panel form-panel" novalidate hidden>
64
+ <div class="panel-head"><h2 id="connection-form-title">添加连接</h2><span id="connection-form-state" class="tag"></span></div>
65
+ <div class="grid2">
66
+ <label class="field">显示名<input id="conn-name" maxlength="200" autocomplete="off" required></label>
67
+ <label class="field">站点地址<input id="conn-base" type="url" inputmode="url" autocomplete="off" spellcheck="false" placeholder="https://api.example.com"></label>
68
+ </div>
69
+ <fieldset class="group">
70
+ <legend>认证</legend>
71
+ <p id="conn-host-note" class="hint" hidden>凭据由 Magpie 宿主账号提供,此处不保存 key。</p>
72
+ <div class="grid2">
73
+ <label class="field">方式<select id="conn-auth-mode"><option value="api-key">API key(按协议发送)</option><option value="bearer">Authorization: Bearer</option><option value="custom">完整 Authorization 值</option><option value="none">不发送凭据</option></select></label>
74
+ <label class="field" id="conn-key-field">Key<input id="conn-key" type="password" autocomplete="new-password" spellcheck="false"></label>
75
+ <label class="field" id="conn-value-field" hidden>Authorization 值<input id="conn-value" type="password" autocomplete="new-password" spellcheck="false"></label>
76
+ </div>
77
+ <p id="conn-secret-state" class="hint"></p>
78
+ <label class="check" id="conn-clear-field" hidden><input id="conn-clear-secret" type="checkbox">清除已保存凭据</label>
79
+ </fieldset>
80
+ <fieldset class="group">
81
+ <legend>协议与模型</legend>
82
+ <label class="field">默认上游协议<select id="conn-protocol"><option value="auto">自动(按请求协议)</option><option value="anthropic">Messages</option><option value="responses">Responses</option><option value="chat-completions">Chat Completions</option><option value="gemini">Gemini</option></select></label>
83
+ <div class="model-fetch-actions"><span class="field-label">模型列表</span><div class="row-actions"><button id="conn-model-fetch" type="button" class="ghost">获取模型</button><button id="conn-model-cancel" type="button" class="ghost" hidden>取消获取</button></div></div>
84
+ <p id="conn-model-status" class="hint" role="status" aria-live="polite">使用上方地址、认证方式和密钥读取模型,无需先保存;不会发送生成请求。</p>
85
+ <p id="conn-model-proxy-note" class="hint">宿主与独立配置工具的代理设置可能不同,两处获取结果可能不一致。</p>
86
+ <div id="conn-model-result" class="model-fetch-result" hidden>
87
+ <label id="conn-model-options-label" class="field" for="conn-model-options">获取到的模型(可多选)</label><select id="conn-model-options" multiple size="6" aria-describedby="conn-model-status"></select>
88
+ <div class="row-actions"><button id="conn-model-all" type="button" class="ghost">全选</button><button id="conn-model-add" type="button" class="primary">追加选中模型</button><button id="conn-model-replace" type="button" class="ghost">替换为选中模型</button></div>
89
+ <p class="hint">填入仅修改草稿。读取模型列表成功不代表模型生成已验证。</p>
90
+ </div>
91
+ <label class="field">模型(每行一个,可手填)<textarea id="conn-models" rows="4" spellcheck="false" placeholder="获取后选择填入,或手动输入模型 ID"></textarea></label>
92
+ <label class="field">模型协议覆盖(每行:模型 = 协议)<textarea id="conn-model-protocols" rows="3" spellcheck="false" placeholder="gpt-5-codex = responses"></textarea></label>
93
+ <details class="more">
94
+ <summary>自定义协议根路径</summary>
95
+ <p class="hint">只填协议根路径,例如 /v1;不要填具体的 /messages 等请求路径。留空使用默认。</p>
96
+ <div class="grid2">
97
+ <label class="field">Messages<input data-api-path="anthropic" spellcheck="false" placeholder="/v1"></label>
98
+ <label class="field">Responses<input data-api-path="responses" spellcheck="false" placeholder="/v1"></label>
99
+ <label class="field">Chat Completions<input data-api-path="chat-completions" spellcheck="false" placeholder="/v1"></label>
100
+ <label class="field">Gemini<input data-api-path="gemini" spellcheck="false" placeholder="/v1beta"></label>
101
+ </div>
102
+ </details>
103
+ </fieldset>
104
+ <fieldset class="group">
105
+ <legend>站点与绑定</legend>
106
+ <label class="check"><input id="conn-enabled" type="checkbox" checked>启用此连接</label>
107
+ <label class="check"><input id="conn-independent" type="checkbox">在 Magpie 中独立显示此站点(需重载宿主)</label>
108
+ <label class="field" id="conn-site-field">站点 ID<input id="conn-site" maxlength="64" spellcheck="false" placeholder="main"></label>
109
+ <label class="field" id="conn-binding-field">初始模板绑定<select id="conn-binding"></select></label>
110
+ <p id="conn-binding-note" class="hint" hidden>已有连接的模板绑定只能通过“应用模板”更改,保存连接不会改变它。</p>
111
+ </fieldset>
112
+ <p id="connection-form-error" class="form-error" role="alert"></p>
113
+ <div class="form-actions"><button id="connection-remove" type="button" class="danger" hidden>删除连接</button><span class="spacer"></span><button id="connection-cancel" type="button" class="ghost">取消</button><button id="connection-save" type="submit" class="primary">保存连接</button></div>
114
+ </form>
115
+
116
+ <form id="binding-form" class="panel form-panel" novalidate hidden>
117
+ <div class="panel-head"><h2>应用模板版本</h2><span class="tag mono" id="binding-generation"></span></div>
118
+ <fieldset class="group"><legend>连接</legend><div id="binding-connections" class="check-list"></div></fieldset>
119
+ <div class="grid2">
120
+ <label class="field">范围<select id="binding-scope"><option value="connection">连接默认</option><option value="model">单个模型覆盖</option></select></label>
121
+ <label class="field" id="binding-model-field" hidden>模型<input id="binding-model" list="binding-model-list" spellcheck="false" autocomplete="off"><datalist id="binding-model-list"></datalist></label>
122
+ </div>
123
+ <label class="field">绑定方式<select id="binding-mode"><option value="auto">自动(Responses→Codex,Messages→Claude Code)</option><option value="template">指定模板版本</option><option value="passthrough">普通转发(不改写身份与正文)</option></select></label>
124
+ <div class="grid2" id="binding-template-fields">
125
+ <label class="field">模板<select id="binding-template"></select></label>
126
+ <label class="field">版本<select id="binding-revision"></select></label>
127
+ </div>
128
+ <p id="binding-summary" class="hint"></p>
129
+ <p id="binding-error" class="form-error" role="alert"></p>
130
+ <div class="form-actions"><span class="spacer"></span><button id="binding-cancel" type="button" class="ghost">取消</button><button id="binding-apply" type="submit" class="primary">应用</button></div>
131
+ </form>
132
+ </div>
133
+ </div>
134
+ </section>
135
+
136
+ <section id="view-templates" data-view="templates" aria-labelledby="pro-title" hidden>
137
+ <div id="template-library">
138
+ <div class="toolbar"><label class="check"><input id="template-show-archived" type="checkbox">显示已归档</label><div class="toolbar-actions"><button id="template-import" type="button" class="ghost">导入模板</button><input id="template-import-file" type="file" accept="application/json,.json" hidden><button id="template-new" type="button" class="primary">新增模板</button></div></div>
139
+ <div id="template-list" class="tpl-list"></div>
140
+ </div>
141
+
142
+ <form id="template-editor" class="tpl-editor" novalidate hidden>
143
+ <header class="tpl-head">
144
+ <button id="tpl-back" type="button" class="link">返回模板库</button>
145
+ <div class="tpl-head-main">
146
+ <label class="field tpl-name-field">模板名称<input id="tpl-name" maxlength="160" autocomplete="off" required></label>
147
+ <dl class="tpl-meta">
148
+ <div><dt>版本</dt><dd id="tpl-revision" class="mono">—</dd></div>
149
+ <div><dt>基线</dt><dd id="tpl-base">—</dd></div>
150
+ <div><dt>草稿</dt><dd id="tpl-state">—</dd></div>
151
+ </dl>
152
+ </div>
153
+ <p id="tpl-readonly" class="readonly-note" hidden>内置模板只读。要修改,请以它为基线新增模板。<button id="tpl-fork" type="button" class="ghost">以此为基线新增</button></p>
154
+ </header>
155
+ <div class="tpl-body">
156
+ <div class="tpl-sections">
157
+ <fieldset class="group">
158
+ <legend>匹配与识别</legend>
159
+ <div class="field"><span class="field-label">适用协议</span><div id="tpl-protocols" class="chips"></div></div>
160
+ <div class="field"><span class="field-label">适用操作</span><div id="tpl-operations" class="chips"></div></div>
161
+ <label class="field">原始 UA 识别<select id="tpl-detector"><option value="none">不识别</option><option value="codex-ua">匹配 Codex UA</option><option value="claude-ua">匹配 Claude UA</option></select></label>
162
+ <p class="hint">识别是兼容启发式,用来区分原生与第三方调用,不是官方客户端认证。</p>
163
+ </fieldset>
164
+ <fieldset class="group">
165
+ <legend>客户端标识</legend>
166
+ <label class="field">身份模式<select id="tpl-mode"><option value="reference-compatible">参考兼容(按基线补全身份)</option><option value="preserve">保留入站身份</option></select></label>
167
+ <div class="grid2">
168
+ <label class="field">User-Agent<input id="tpl-ua" spellcheck="false" autocomplete="off"></label>
169
+ <label class="field">客户端版本<input id="tpl-version" spellcheck="false" autocomplete="off"></label>
170
+ </div>
171
+ </fieldset>
172
+ <fieldset class="group">
173
+ <legend>会话策略</legend>
174
+ <label class="field">会话标识<select id="tpl-session"><option value="reference-stable">稳定兼容标识</option><option value="host">宿主真实 session</option><option value="preserve">保留入站</option><option value="off">关闭</option></select></label>
175
+ <p id="tpl-session-hint" class="hint"></p>
176
+ </fieldset>
177
+ <fieldset class="group wide">
178
+ <legend>请求头</legend>
179
+ <p class="hint">动作:覆盖、仅缺失补充、缺失或空补充、删除、保留。认证头与传输控制头由宿主最后处理,模板不能设置。</p>
180
+ <div class="hdr-scroll"><table id="tpl-headers" class="hdr-table">
181
+ <colgroup><col class="c-on"><col class="c-name"><col class="c-action"><col class="c-value"><col class="c-when"><col class="c-ops"><col class="c-row"></colgroup>
182
+ <thead><tr><th scope="col">启用</th><th scope="col">名称</th><th scope="col">动作</th><th scope="col">值</th><th scope="col">条件</th><th scope="col">限定操作</th><th scope="col"><span class="sr-only">行操作</span></th></tr></thead>
183
+ <tbody></tbody>
184
+ </table></div>
185
+ <div class="row-actions"><button id="tpl-header-add" type="button" class="ghost">添加请求头</button><span id="tpl-header-count" class="hint"></span></div>
186
+ </fieldset>
187
+ <fieldset class="group wide">
188
+ <legend>请求正文</legend>
189
+ <div class="grid3">
190
+ <label class="check"><input id="tpl-codex-metadata" type="checkbox">Codex 元数据提升</label>
191
+ <label class="check"><input id="tpl-fast-beta" type="checkbox">fast beta 联动</label>
192
+ <label class="field">Claude 身份补全<select id="tpl-claude-compat"><option value="off">关闭</option><option value="third-party-messages">第三方 /messages 补全 system 与 user_id</option></select></label>
193
+ </div>
194
+ <details class="more" id="tpl-identity-details">
195
+ <summary>身份提示词(高级)</summary>
196
+ <label class="field">system 前缀文本<textarea id="tpl-identity-prompt" rows="3" spellcheck="false" placeholder="留空使用基线默认"></textarea></label>
197
+ </details>
198
+ <div class="grid3">
199
+ <label class="field">parameters.defaults(JSON)<textarea id="tpl-defaults" class="code" rows="6" spellcheck="false"></textarea></label>
200
+ <label class="field">parameters.overrides(JSON)<textarea id="tpl-overrides" class="code" rows="6" spellcheck="false"></textarea></label>
201
+ <label class="field">parameters.remove(每行一个)<textarea id="tpl-remove" class="code" rows="6" spellcheck="false"></textarea></label>
202
+ </div>
203
+ <p class="hint">默认保护 model、messages、tools、tool_choice 和 stream;count_tokens 不做正文变更。</p>
204
+ </fieldset>
205
+ <fieldset class="group wide">
206
+ <legend>限制</legend>
207
+ <div class="grid3">
208
+ <label class="field">正文读取上限(字节)<input id="tpl-max-body" type="number" min="1" max="67108864" step="1" inputmode="numeric"></label>
209
+ <label class="field">读取时限(毫秒)<input id="tpl-body-timeout" type="number" min="1" max="60000" step="1" inputmode="numeric"></label>
210
+ <label class="field">元数据上限(字节)<input id="tpl-max-metadata" type="number" min="1" max="4194304" step="1" inputmode="numeric"></label>
211
+ </div>
212
+ </fieldset>
213
+ </div>
214
+ <aside class="tpl-preview" aria-label="有效规则">
215
+ <h3>相对基线的变化</h3>
216
+ <div id="tpl-changes" class="diff-list"></div>
217
+ <h3>有效规则(请求头值已脱敏)</h3>
218
+ <pre id="tpl-json" class="code-block"></pre>
219
+ </aside>
220
+ </div>
221
+ <p id="tpl-error" class="form-error" role="alert"></p>
222
+ <footer class="tpl-actions">
223
+ <span id="tpl-dirty" class="tpl-dirty"></span>
224
+ <button id="tpl-discard" type="button" class="ghost">放弃草稿</button>
225
+ <button id="tpl-export" type="button" class="ghost">导出脱敏副本</button>
226
+ <button id="tpl-preview" type="button" class="ghost">本地预览</button>
227
+ <button id="tpl-apply" type="button" class="ghost">应用到连接</button>
228
+ <button id="tpl-save" type="submit" class="primary">保存新版本</button>
229
+ </footer>
230
+ </form>
231
+ </section>
232
+
233
+ <section id="view-tests" data-view="tests" aria-labelledby="pro-title" hidden>
234
+ <div class="split tests-split">
235
+ <form id="test-form" class="panel form-panel" novalidate>
236
+ <label class="field">测试层次<select id="test-kind"><option value="preview">本地转换预览(不联网)</option><option value="check">连接检查(只读取模型列表)</option><option value="infer">实际模型请求(一次简短合成请求)</option></select></label>
237
+ <p id="test-kind-hint" class="hint"></p>
238
+ <label class="field">连接<select id="test-connection"></select></label>
239
+ <div id="test-template-fields">
240
+ <label class="field">本次测试模板<select id="test-template-source"><option value="auto">自动适配本次协议(推荐)</option><option value="binding">严格使用连接绑定</option><option value="ref">指定已保存版本</option><option value="draft">当前草稿(临时快照)</option><option value="none">不使用模板(普通转发)</option></select></label>
241
+ <div class="grid2" id="test-ref-fields" hidden>
242
+ <label class="field">模板<select id="test-template"></select></label>
243
+ <label class="field">版本<select id="test-revision"></select></label>
244
+ </div>
245
+ </div>
246
+ <div class="grid2" id="test-protocol-fields">
247
+ <label class="field">上游协议<select id="test-protocol"><option value="anthropic">Messages</option><option value="responses">Responses</option><option value="chat-completions">Chat Completions</option><option value="gemini">Gemini</option></select></label>
248
+ <label class="field">操作<select id="test-operation"></select></label>
249
+ </div>
250
+ <div class="test-model-picker" id="test-model-fields">
251
+ <div class="test-model-actions">
252
+ <label class="field" for="test-model-select">测试模型</label>
253
+ <div class="row-actions"><button id="test-model-fetch" type="button" class="ghost">刷新模型</button><button id="test-model-cancel" type="button" class="ghost" hidden>取消获取</button></div>
254
+ </div>
255
+ <select id="test-model-select" class="test-model-select" aria-describedby="test-model-status"><option value="">请先选择连接</option></select>
256
+ <p id="test-model-status" class="hint test-model-status" role="status" aria-live="polite">选择连接后自动载入已保存或已发现的模型。</p>
257
+ <button id="test-model-manual" type="button" class="link" aria-expanded="false" aria-controls="test-model-manual-field">手动输入模型 ID</button>
258
+ <label class="field test-model-manual" id="test-model-manual-field" hidden>模型 ID(高级)<input id="test-model" list="test-model-list" spellcheck="false" autocomplete="off" placeholder="仅在列表未包含所需模型时填写"><datalist id="test-model-list"></datalist></label>
259
+ </div>
260
+ <label class="check check-inline" id="test-stream-field"><input id="test-stream" type="checkbox">流式响应</label>
261
+ <section id="test-plan" class="test-plan" aria-labelledby="test-plan-title">
262
+ <div class="panel-head"><h3 id="test-plan-title">本次请求</h3><span id="test-plan-state" class="tag"></span></div>
263
+ <code id="test-plan-url" class="test-plan-url"></code>
264
+ <p id="test-plan-template" class="hint"></p>
265
+ <p id="test-plan-note" class="hint"></p>
266
+ <p id="test-production-route" class="hint"></p>
267
+ <code id="test-model-reference" class="test-plan-url"></code>
268
+ <button id="test-route-save" type="button" class="ghost" hidden>将本次协议与模板保存为此模型路由</button>
269
+ <p id="test-plan-error" class="form-error" role="status" aria-live="polite"></p>
270
+ <details class="more" id="test-endpoint-options"><summary>本次协议路径(高级)</summary><label class="field">协议根路径<input id="test-api-path" autocomplete="off" spellcheck="false" placeholder="留空使用此连接的协议根路径"></label><p class="hint">例如 /v1 或 /anthropic/v1。只影响本次测试,不修改连接;不能填写外域地址或完整的 /messages 路径。</p></details>
271
+ <p class="hint">这是上游直测,不是客户端协议转换。站点地址相同不代表支持每一种 API;模型名称也不能证明接口能力。</p>
272
+ </section>
273
+ <details class="more" id="test-sample">
274
+ <summary>入站样例</summary>
275
+ <label class="field">请求头(JSON 对象)<textarea id="test-headers" class="code" rows="4" spellcheck="false">{}</textarea></label>
276
+ <label class="field">正文(JSON)<textarea id="test-body" class="code" rows="8" spellcheck="false"></textarea></label>
277
+ <button id="test-sample-reset" type="button" class="ghost">恢复默认样例</button>
278
+ </details>
279
+ <div id="test-sample-notice" class="test-sample-notice" role="status" hidden><p>已保留自定义样例。协议或模型改变后,请核对正文;不会替你静默覆盖。</p><button id="test-sample-adapt" type="button" class="ghost">使用当前协议的简短样例</button></div>
280
+ <p id="test-error" class="form-error" role="alert" tabindex="-1"></p>
281
+ <div class="form-actions"><span class="spacer"></span><button id="test-cancel" type="button" class="ghost" hidden>取消测试</button><button id="test-run" type="submit" class="primary">运行本地预览</button></div>
282
+ </form>
283
+ <div class="test-result-column"><div id="test-result-stale" class="test-result-stale" role="status" hidden>当前选择已改变。下方是上一次测试结果,不代表当前模型、协议或端点;重新测试后更新。</div><div id="test-result" class="panel result" aria-live="polite"><p class="empty-note">选择连接和模型,核对本次请求后运行。结果会标明模型、协议、地址和测试时间。</p></div></div>
284
+ </div>
285
+ </section>
286
+
287
+ <section id="view-settings" data-view="settings" aria-labelledby="pro-title" hidden>
288
+ <div class="settings-grid">
289
+ <div class="panel">
290
+ <h2>外观</h2>
291
+ <label class="field" for="theme-mode">主题</label>
292
+ <select id="theme-mode" data-theme-control><option value="system">跟随系统</option><option value="dark">夜间模式</option><option value="light">浅色模式</option></select>
293
+ </div>
294
+ <div class="panel">
295
+ <h2>其他页面</h2>
296
+ <p class="hint">在独立页面管理站点账号、余额与签到,打开前会确认未保存的草稿。</p>
297
+ <div class="link-row"><a href="./accounts" class="btn ghost" data-leave="accounts">余额与签到</a></div>
298
+ </div>
299
+ <div class="panel wide">
300
+ <h2>迁移旧 Claude 配置</h2>
301
+ <p class="hint">把本机旧 Claude 独立配置复制为 UA PRO 新连接,并绑定 14 头自定义模板。不修改、不停用原配置和原插件;写入前先预览映射。</p>
302
+ <div class="link-row"><button id="migration-preview" type="button" class="ghost">预览迁移</button><button id="migration-apply" type="button" class="primary" hidden>确认迁移</button></div>
303
+ <div id="migration-result" class="migration-result"></div>
304
+ </div>
305
+ <div class="panel wide">
306
+ <h2>本次配置会话</h2>
307
+ <dl id="session-info" class="kv"></dl>
308
+ </div>
309
+ </div>
310
+ </section>
311
+ </main>
312
+ </div>
313
+
314
+ <dialog id="template-base-dialog" class="dialog" aria-labelledby="template-base-title">
315
+ <form id="template-base-form" method="dialog" novalidate>
316
+ <h2 id="template-base-title">新增模板</h2>
317
+ <p class="hint">先选基线,完整复制其规则为独立草稿。之后基线更新不会自动改写这份模板。</p>
318
+ <label class="field">基线<select id="template-base-select"></select></label>
319
+ <label class="field">模板名称<input id="template-base-name" maxlength="160" autocomplete="off"></label>
320
+ <p id="template-base-error" class="form-error" role="alert"></p>
321
+ <div class="form-actions"><span class="spacer"></span><button id="template-base-cancel" type="button" class="ghost">取消</button><button id="template-base-confirm" type="submit" class="primary">复制为草稿</button></div>
322
+ </form>
323
+ </dialog>
324
+
325
+ <dialog id="template-history" class="dialog dialog-wide" aria-labelledby="history-title">
326
+ <div class="dialog-head"><h2 id="history-title">版本历史</h2><button id="history-close" type="button" class="ghost">关闭</button></div>
327
+ <div id="history-body" class="history-body"></div>
328
+ <div id="history-diff" class="history-diff"></div>
329
+ </dialog>
330
+
331
+ <dialog id="test-confirm" class="dialog" aria-labelledby="test-confirm-title">
332
+ <form method="dialog">
333
+ <h2 id="test-confirm-title">确认发起网络请求</h2>
334
+ <p id="test-confirm-text"></p>
335
+ <dl id="test-confirm-detail" class="kv"></dl>
336
+ <div class="form-actions"><span class="spacer"></span><button id="test-confirm-cancel" type="submit" value="cancel" class="ghost">取消</button><button id="test-confirm-send" type="submit" value="confirm" class="primary">确认发送</button></div>
337
+ </form>
338
+ </dialog>
339
+
340
+ <dialog id="confirm-dialog" class="dialog" aria-labelledby="confirm-title">
341
+ <form method="dialog">
342
+ <h2 id="confirm-title">确认</h2>
343
+ <p id="confirm-text"></p>
344
+ <div class="form-actions"><span class="spacer"></span><button id="confirm-cancel" type="submit" value="cancel" class="ghost">继续编辑</button><button id="confirm-ok" type="submit" value="confirm" class="danger">确认</button></div>
345
+ </form>
346
+ </dialog>
347
+ </body>
348
+ </html>