@wu529778790/open-im 1.11.8-beta.23 → 1.11.8-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/codex/cli-runner.js
CHANGED
|
@@ -217,22 +217,27 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
217
217
|
const event = parseCodexEvent(line);
|
|
218
218
|
if (!event)
|
|
219
219
|
return;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
220
|
+
// Codex CLI JSONL 格式是嵌套的:顶层 type 为 "event_msg" / "response_item",
|
|
221
|
+
// 真正的子类型在 payload.type 里。旧版扁平格式也兼容。
|
|
222
|
+
const topType = event.type;
|
|
223
|
+
const payload = event.payload ?? event;
|
|
224
|
+
const type = payload.type ?? topType;
|
|
225
|
+
log.debug(`[Codex event] topType=${topType} type=${type}`);
|
|
226
|
+
// thread.started / session_meta → 拿 session ID
|
|
227
|
+
if (type === 'thread.started' || type === 'session_meta') {
|
|
228
|
+
const threadId = payload.thread_id ?? payload.session_id ?? event.thread_id ?? '';
|
|
224
229
|
if (threadId)
|
|
225
230
|
callbacks.onSessionId?.(threadId);
|
|
226
231
|
return;
|
|
227
232
|
}
|
|
228
233
|
if (type === 'turn.failed') {
|
|
229
234
|
completed = true;
|
|
230
|
-
const err = event.error;
|
|
235
|
+
const err = payload.error ?? event.error;
|
|
231
236
|
callbacks.onError(err?.message ?? 'Codex turn failed');
|
|
232
237
|
return;
|
|
233
238
|
}
|
|
234
239
|
if (type === 'error') {
|
|
235
|
-
const msg = event.message;
|
|
240
|
+
const msg = payload.message ?? event.message;
|
|
236
241
|
if (msg?.includes('Reconnecting')) {
|
|
237
242
|
return;
|
|
238
243
|
}
|
|
@@ -240,12 +245,12 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
240
245
|
callbacks.onError(msg ?? 'Codex stream error');
|
|
241
246
|
return;
|
|
242
247
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
// item 事件:payload 里可能有 item 字段,或者 payload 本身就是 item
|
|
249
|
+
if (topType === 'response_item' || type === 'item.started' || type === 'item.updated' || type === 'item.completed') {
|
|
250
|
+
const item = payload.item ?? payload;
|
|
251
|
+
const itemType = item.type ?? type;
|
|
252
|
+
if (itemType === 'reasoning') {
|
|
253
|
+
// Codex 的 reasoning 可能是 encrypted_content(不可读),只在有 text 时累加
|
|
249
254
|
const text = item.text;
|
|
250
255
|
if (text) {
|
|
251
256
|
accumulatedThinking += (accumulatedThinking ? '\n\n' : '') + text;
|
|
@@ -253,23 +258,41 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
253
258
|
}
|
|
254
259
|
return;
|
|
255
260
|
}
|
|
261
|
+
// function_call(Codex 新格式:response_item.type=function_call)
|
|
262
|
+
if (itemType === 'function_call') {
|
|
263
|
+
const name = item.name ?? 'unknown';
|
|
264
|
+
const args = item.arguments;
|
|
265
|
+
const toolName = name === 'exec_command' ? 'Bash' : name === 'apply_patch' ? 'Edit' : name;
|
|
266
|
+
toolStats[toolName] = (toolStats[toolName] || 0) + 1;
|
|
267
|
+
callbacks.onToolUse?.(toolName, args ? { arguments: args } : {});
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// custom_tool_call(apply_patch 等)
|
|
271
|
+
if (itemType === 'custom_tool_call') {
|
|
272
|
+
const name = item.name ?? 'unknown';
|
|
273
|
+
const toolName = name === 'apply_patch' ? 'Edit' : name;
|
|
274
|
+
toolStats[toolName] = (toolStats[toolName] || 0) + 1;
|
|
275
|
+
callbacks.onToolUse?.(toolName, { input: item.input });
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
// command_execution(旧格式)
|
|
256
279
|
if (itemType === 'command_execution') {
|
|
257
280
|
const cmd = item.command;
|
|
258
|
-
if (cmd
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
callbacks.onToolUse?.(toolName, { command: cmd });
|
|
281
|
+
if (cmd) {
|
|
282
|
+
toolStats['Bash'] = (toolStats['Bash'] || 0) + 1;
|
|
283
|
+
callbacks.onToolUse?.('Bash', { command: cmd });
|
|
262
284
|
}
|
|
263
285
|
return;
|
|
264
286
|
}
|
|
265
|
-
|
|
287
|
+
// file_change(旧格式)
|
|
288
|
+
if (itemType === 'file_change') {
|
|
266
289
|
const changes = item.changes;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
callbacks.onToolUse?.(toolName, { changes });
|
|
290
|
+
toolStats['Edit'] = (toolStats['Edit'] || 0) + 1;
|
|
291
|
+
callbacks.onToolUse?.('Edit', { changes });
|
|
270
292
|
return;
|
|
271
293
|
}
|
|
272
|
-
|
|
294
|
+
// mcp_tool_call(旧格式)
|
|
295
|
+
if (itemType === 'mcp_tool_call') {
|
|
273
296
|
const tool = item.tool;
|
|
274
297
|
const server = item.server;
|
|
275
298
|
if (tool) {
|
|
@@ -279,16 +302,41 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
279
302
|
}
|
|
280
303
|
return;
|
|
281
304
|
}
|
|
282
|
-
|
|
283
|
-
|
|
305
|
+
// agent_message / message — 最终回复文本
|
|
306
|
+
// Codex 新格式:event_msg.payload.type=agent_message, payload.message=文本
|
|
307
|
+
// response_item.payload.type=message, payload.content=[{type:output_text,text:...}]
|
|
308
|
+
if (itemType === 'agent_message' || itemType === 'message') {
|
|
309
|
+
let text;
|
|
310
|
+
if (itemType === 'agent_message') {
|
|
311
|
+
text = item.message ?? item.text;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
// message 类型,content 是数组
|
|
315
|
+
const content = item.content;
|
|
316
|
+
if (Array.isArray(content)) {
|
|
317
|
+
text = content
|
|
318
|
+
.filter((c) => c.type === 'output_text' && c.text)
|
|
319
|
+
.map((c) => c.text)
|
|
320
|
+
.join('\n');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
284
323
|
if (text) {
|
|
324
|
+
// 只累加 final_answer 或 commentary,避免重复
|
|
325
|
+
const phase = item.phase ?? payload.phase;
|
|
285
326
|
accumulated += (accumulated ? '\n\n' : '') + text;
|
|
286
327
|
callbacks.onText(accumulated);
|
|
287
328
|
}
|
|
288
329
|
return;
|
|
289
330
|
}
|
|
290
331
|
}
|
|
291
|
-
|
|
332
|
+
// task_complete / turn.completed
|
|
333
|
+
if (type === 'task_complete' || type === 'turn.completed') {
|
|
334
|
+
// task_complete 里可能有 last_agent_message
|
|
335
|
+
const lastMsg = payload.last_agent_message;
|
|
336
|
+
if (lastMsg && !accumulated) {
|
|
337
|
+
accumulated = lastMsg;
|
|
338
|
+
callbacks.onText(accumulated);
|
|
339
|
+
}
|
|
292
340
|
completed = true;
|
|
293
341
|
callbacks.onComplete({
|
|
294
342
|
success: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wu529778790/open-im",
|
|
3
|
-
"version": "1.11.8-beta.
|
|
3
|
+
"version": "1.11.8-beta.25",
|
|
4
4
|
"description": "Your AI coding assistant, in every chat app. Multi-platform IM bridge for Claude Code, Codex, and CodeBuddy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap";:root{--c-bg: #fafafa;--c-surface: #ffffff;--c-surface-alt: #f5f5f5;--c-border: #e5e5e5;--c-border-foc: #a3a3a3;--c-text: #1a1a2e;--c-text-2: #525252;--c-text-3: #a3a3a3;--c-accent: #6366f1;--c-accent-h: #4f46e5;--c-accent-bg: #eef2ff;--c-accent-bdr: #c7d2fe;--c-ok: #10b981;--c-ok-bg: #ecfdf5;--c-ok-bdr: #a7f3d0;--c-warn: #f59e0b;--c-warn-bg: #fffbeb;--c-warn-bdr: #fde68a;--c-err: #ef4444;--c-err-bg: #fef2f2;--c-err-bdr: #fecaca;--shadow-xs: 0 1px 2px rgba(0,0,0,.05);--shadow-s: 0 1px 3px rgba(0,0,0,.1), 0 1px 2px rgba(0,0,0,.06);--shadow-m: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);--shadow-l: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--shadow-glow: 0 0 20px rgba(99,102,241,.15);--r-s: 6px;--r-m: 8px;--r-l: 12px;--r-xl: 16px;--font-display: "Space Grotesk", -apple-system, sans-serif;--font-body: "Inter", -apple-system, sans-serif;--font-mono: "JetBrains Mono", "SF Mono", monospace;--fast: .12s ease;--norm: .2s ease;--slow: .3s ease}:root.dark{--c-bg: #0a0a0f;--c-surface: #141418;--c-surface-alt: #1e1e24;--c-border: #2a2a32;--c-border-foc: #52525e;--c-text: #f0f0f5;--c-text-2: #a0a0ae;--c-text-3: #5a5a68;--c-accent: #818cf8;--c-accent-h: #6366f1;--c-accent-bg: rgba(99,102,241,.12);--c-accent-bdr: rgba(99,102,241,.3);--c-ok-bg: rgba(16,185,129,.12);--c-ok-bdr: rgba(16,185,129,.3);--c-warn-bg: rgba(245,158,11,.12);--c-warn-bdr: rgba(245,158,11,.3);--c-err-bg: rgba(239,68,68,.12);--c-err-bdr: rgba(239,68,68,.3);--shadow-xs: 0 1px 2px rgba(0,0,0,.3);--shadow-s: 0 1px 3px rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3);--shadow-m: 0 4px 6px -1px rgba(0,0,0,.4), 0 2px 4px -2px rgba(0,0,0,.3);--shadow-l: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.3);--shadow-glow: 0 0 20px rgba(129,140,248,.2)}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font-body);font-size:14px;line-height:1.5;color:var(--c-text);background:var(--c-bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:focus-visible{outline:2px solid var(--c-accent);outline-offset:2px}.content{padding:32px 40px 64px;max-width:800px;width:100%;margin:0 auto}.header{position:sticky;top:0;z-index:15;background:var(--c-surface);border-bottom:1px solid var(--c-border);padding:0 40px;height:48px;display:flex;align-items:center;justify-content:space-between}.header-left{display:flex;align-items:center;gap:12px}.header-right{display:flex;align-items:center;gap:8px}.header-status{font-size:13px;font-weight:500;display:inline-flex;align-items:center;gap:6px;color:var(--c-text-2)}.header-status .dot{width:8px;height:8px;border-radius:50%;display:inline-block}.header-status .dot.running{background:var(--c-ok);box-shadow:0 0 12px var(--c-ok);animation:pulse 2s infinite}.header-status .dot.idle{background:var(--c-text-3)}.header-divider{width:1px;height:20px;background:var(--c-border);margin:0 4px}@keyframes pulse{0%,to{opacity:1}50%{opacity:.6}}.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:32px}.stat-card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-l);padding:20px;transition:all var(--norm)}.stat-card:hover{box-shadow:var(--shadow-m);transform:translateY(-2px)}.stat-label{font-size:11px;font-weight:600;color:var(--c-text-3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px}.stat-value{font-family:var(--font-display);font-size:32px;font-weight:700;color:var(--c-text);line-height:1;letter-spacing:-.02em}.stat-meta{font-size:12px;color:var(--c-text-3);margin-top:6px}.section{margin-bottom:40px}.section-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:8px}.section-title{font-family:var(--font-display);font-size:18px;font-weight:600;color:var(--c-text);letter-spacing:-.01em}.section-desc{font-size:13px;color:var(--c-text-3)}.card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-l);overflow:hidden;transition:all var(--norm)}.card:hover{box-shadow:var(--shadow-s)}.card-head{padding:16px 20px;border-bottom:1px solid var(--c-border);display:flex;justify-content:space-between;align-items:center;gap:12px;cursor:pointer}.card-head:hover{background:var(--c-surface-alt)}.card-title{font-family:var(--font-display);font-size:14px;font-weight:600;color:var(--c-text)}.card-body{padding:20px}.platform-grid{display:grid;grid-template-columns:1fr;gap:16px}.platform-card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-l);overflow:visible;transition:all var(--norm)}.platform-card:hover{box-shadow:var(--shadow-m);border-color:var(--c-border-foc)}.platform-card.disabled{opacity:.85}.platform-card.enabled{border-color:var(--c-accent-bdr);box-shadow:0 0 0 1px var(--c-accent-bdr)}.platform-card-head{padding:16px 20px;display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer;border-radius:var(--r-l) var(--r-l) 0 0}.platform-card-head:hover{background:var(--c-surface-alt)}.platform-card-meta{display:flex;align-items:center;gap:12px;min-width:0}.platform-card-icon{width:40px;height:40px;border-radius:var(--r-m);background:var(--c-surface-alt);display:flex;align-items:center;justify-content:center;font-size:22px;line-height:1;flex-shrink:0}.platform-card-title-block{display:flex;flex-direction:column;gap:2px;min-width:0}.platform-card-name{font-family:var(--font-display);font-size:14px;font-weight:600;color:var(--c-text)}.platform-card-desc{font-size:12px;color:var(--c-text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.platform-card-right{display:grid;grid-template-columns:minmax(104px,116px) minmax(72px,84px) 40px minmax(72px,84px);align-items:center;gap:10px;flex-shrink:0}.platform-card-control{display:flex;align-items:center;justify-content:center;min-width:0}.platform-card-control-menu{width:40px}.platform-status-badge{display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:0;text-align:center;font-size:11px;font-weight:500;padding:3px 8px;border-radius:999px;border:1px solid transparent;white-space:nowrap}.platform-status-badge.on{background:var(--c-ok-bg);color:var(--c-ok);border-color:var(--c-ok-bdr)}.platform-status-badge.off{color:var(--c-text-3)}.platform-card-chevron{font-size:12px;color:var(--c-text-3);transition:transform var(--fast)}.platform-card-body{padding:16px 20px 20px;border-top:1px solid var(--c-border);border-radius:0 0 var(--r-l) var(--r-l)}.ai-command-picker{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-m);padding:12px 14px;display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.ai-command-picker-title{font-family:var(--font-display);font-size:13px;font-weight:600;color:var(--c-text)}.ai-command-picker-hint{font-size:12px;color:var(--c-text-2)}.ai-command-picker .form-select{margin-top:2px}.platform-card-divider{border:0;border-top:1px solid var(--c-border);margin:0 0 16px}.platform-card-hint{font-size:12px;color:var(--c-text-3);line-height:1.5;margin-bottom:16px}.platform-card-help{margin-top:16px;padding:10px 14px;background:var(--c-surface-alt);border-radius:var(--r-m);font-size:12px;color:var(--c-text-2);line-height:1.6}.platform-card-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}.platform-card-ai-tag{position:relative;display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:0;font-size:11px;font-weight:500;padding:3px 10px;border-radius:999px;background:var(--c-surface-alt);color:var(--c-text-2);border:1px solid var(--c-border);cursor:pointer;white-space:nowrap;transition:all var(--fast)}.platform-card-ai-tag:hover{border-color:var(--c-accent-bdr);color:var(--c-text)}.platform-card-ai-dropdown{position:absolute;top:calc(100% + 4px);right:0;min-width:140px;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-m);box-shadow:var(--shadow-m, 0 8px 24px rgba(0, 0, 0, .12));z-index:20;padding:4px}.platform-card-ai-option{display:block;width:100%;text-align:left;background:transparent;border:0;padding:6px 10px;font-size:12px;color:var(--c-text);cursor:pointer;border-radius:var(--r-s, 4px)}.platform-card-ai-option:hover{background:var(--c-surface-alt)}.platform-card-ai-option.active{color:var(--c-accent);font-weight:600}.platform-card-menu{position:relative;flex-shrink:0}.platform-card-menu-btn{width:32px;height:32px;background:transparent;border:0;padding:0;font-size:18px;line-height:1;color:var(--c-text-3);cursor:pointer;border-radius:var(--r-s, 4px);transition:all var(--fast)}.platform-card-menu-btn:hover{background:var(--c-surface-alt);color:var(--c-text)}.platform-card-menu-dropdown{position:absolute;top:calc(100% + 4px);right:0;min-width:160px;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-m);box-shadow:var(--shadow-m, 0 8px 24px rgba(0, 0, 0, .12));z-index:20;padding:4px}.platform-card-menu-item{display:block;width:100%;text-align:left;background:transparent;border:0;padding:8px 12px;font-size:13px;color:var(--c-text);cursor:pointer;border-radius:var(--r-s, 4px)}.platform-card-menu-item:hover{background:var(--c-surface-alt)}.platform-card-menu-item.danger{color:var(--c-err, #d33)}.platform-card-menu-item.danger:hover{background:#dc353514}.platform-card-menu-item:disabled{opacity:.4;cursor:not-allowed}.platform-card-config-btn{min-width:72px}.platform-card-right .toggle{justify-content:center;width:100%}.qr-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:1000;padding:16px}.qr-modal{position:relative;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-l);box-shadow:var(--shadow-l, 0 12px 40px rgba(0, 0, 0, .2));padding:28px 28px 24px;width:100%;max-width:360px;text-align:center}.qr-modal-close{position:absolute;top:8px;right:12px;background:transparent;border:0;font-size:22px;line-height:1;color:var(--c-text-3);cursor:pointer;padding:4px 8px;border-radius:var(--r-m)}.qr-modal-close:hover{background:var(--c-surface-alt);color:var(--c-text)}.qr-modal-title{font-family:var(--font-display);font-size:16px;font-weight:600;color:var(--c-text);margin-bottom:16px}.qr-modal-img-wrap{display:flex;align-items:center;justify-content:center;margin-bottom:14px}.qr-modal-img{width:220px;height:220px;border:1px solid var(--c-border);border-radius:var(--r-m)}.qr-modal-hint{font-size:13px;color:var(--c-text-2);line-height:1.5;margin-bottom:8px}.qr-modal-status{font-size:13px;color:var(--c-text-2);line-height:1.5}.qr-modal-status.muted{color:var(--c-text-3)}.qr-modal-status.ok{color:var(--c-ok);font-weight:600}.qr-modal-status.err{color:var(--c-err, var(--c-text));font-weight:500;word-break:break-word}.qr-modal-actions{display:flex;gap:8px;justify-content:center;margin-top:16px}.form-group{margin-bottom:14px}.form-group:last-child{margin-bottom:0}.form-label{display:block;font-size:12px;font-weight:500;color:var(--c-text-2);margin-bottom:5px}.form-input,.form-select,.form-textarea{width:100%;padding:8px 10px;font-family:inherit;font-size:13px;color:var(--c-text);background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-s);transition:border-color var(--fast),box-shadow var(--fast);outline:none}.form-input:focus,.form-select:focus,.form-textarea:focus{border-color:var(--c-accent);box-shadow:0 0 0 3px var(--c-accent-bg)}.form-input.mono,.form-textarea.mono{font-family:var(--font-mono);font-size:12px}.form-textarea{min-height:80px;resize:vertical}.form-hint{font-size:11px;color:var(--c-text-3);margin-top:4px;line-height:1.4}.form-hint a{color:var(--c-accent)}.form-hint code{font-family:var(--font-mono);font-size:10px;padding:1px 4px;background:var(--c-surface-alt);border-radius:3px}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:7px 14px;font-family:var(--font-body);font-size:13px;font-weight:500;border-radius:var(--r-s);border:1px solid transparent;cursor:pointer;text-decoration:none;transition:all var(--fast);white-space:nowrap}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-p{background:var(--c-accent);color:#fff}.btn-p:hover:not(:disabled){background:var(--c-accent-h);box-shadow:var(--shadow-glow)}.btn-s{background:var(--c-surface);color:var(--c-text);border-color:var(--c-border)}.btn-s:hover:not(:disabled){background:var(--c-surface-alt);border-color:var(--c-border-foc)}.btn-g{background:transparent;color:var(--c-text-2)}.btn-g:hover:not(:disabled){background:var(--c-surface-alt);color:var(--c-text)}.btn-d{background:var(--c-err-bg);color:var(--c-err);border-color:var(--c-err-bdr)}.btn-d:hover:not(:disabled){background:var(--c-err);color:#fff}.btn-w{background:var(--c-warn-bg);color:var(--c-warn);border-color:var(--c-warn-bdr)}.btn-w:hover:not(:disabled){background:var(--c-warn);color:#fff}.btn-sm{padding:5px 10px;font-size:12px}.btn-lg{padding:10px 20px;font-size:14px}.toggle{display:inline-flex;align-items:center;gap:8px;cursor:pointer;flex-shrink:0}.toggle-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.toggle-track{position:relative;width:36px;height:20px;background:var(--c-border-foc);border-radius:999px;transition:background var(--fast);flex-shrink:0}.toggle-track:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;background:#fff;border-radius:50%;transition:transform var(--fast);box-shadow:var(--shadow-xs)}.toggle-input:checked+.toggle-track{background:var(--c-accent);box-shadow:0 0 10px var(--c-accent)}.toggle-input:checked+.toggle-track:after{transform:translate(16px)}.tabs{display:inline-flex;gap:2px;padding:3px;background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-m)}.tab{padding:6px 12px;font-size:12px;font-weight:500;color:var(--c-text-2);background:transparent;border:none;border-radius:var(--r-s);cursor:pointer;transition:all var(--fast)}.tab:hover{color:var(--c-text)}.tab.active{background:var(--c-surface);color:var(--c-text);box-shadow:var(--shadow-xs)}.msg{padding:10px 14px;border-radius:var(--r-m);font-size:13px;line-height:1.5}.msg-ok{background:var(--c-ok-bg);color:var(--c-ok)}.msg-err{background:var(--c-err-bg);color:var(--c-err)}.msg-w{background:var(--c-warn-bg);color:var(--c-warn)}.badge{display:inline-flex;align-items:center;padding:2px 8px;font-size:11px;font-weight:500;border-radius:999px}.badge-ok{background:var(--c-ok-bg);color:var(--c-ok)}.badge-err{background:var(--c-err-bg);color:var(--c-err)}.badge-w{background:var(--c-warn-bg);color:var(--c-warn)}.badge-info{background:var(--c-accent-bg);color:var(--c-accent)}.field-tip{font-size:11px;color:var(--c-text-3);line-height:1.45;margin-top:5px}.field-tip a{color:var(--c-accent)}.field-tip code{font-family:var(--font-mono);font-size:10px;padding:1px 4px;background:var(--c-surface-alt);border-radius:3px}.mt-4{margin-top:16px}.mt-6{margin-top:24px}.gap-2{gap:8px}.gap-3{gap:12px}.text-center{text-align:center}.mono{font-family:var(--font-mono)}.hidden{display:none!important}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.flash{margin-bottom:20px}.dark-btn{padding:4px 8px;border-radius:var(--r-s);border:1px solid var(--c-border);background:var(--c-surface);color:var(--c-text-2);cursor:pointer;font-size:14px;line-height:1;transition:all var(--fast);display:inline-flex;align-items:center;justify-content:center}.dark-btn:hover{border-color:var(--c-border-foc);color:var(--c-text)}.config-stack{display:flex;flex-direction:column;gap:16px}.config-card .card-title{font-family:var(--font-mono);font-size:13px}.config-card textarea{width:100%}.wizard-wrap{display:flex;justify-content:center;padding-top:16px}.wizard{width:100%;max-width:580px;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-xl);box-shadow:var(--shadow-l);overflow:hidden}.wizard-bar{height:3px;background:var(--c-border)}.wizard-bar-fill{height:100%;background:var(--c-accent);transition:width .4s cubic-bezier(.4,0,.2,1)}.wizard-steps{display:flex;padding:20px 24px 0;gap:0}.wizard-step-ind{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;position:relative}.wizard-step-ind+.wizard-step-ind:before{content:"";position:absolute;top:12px;right:calc(50% + 16px);width:calc(100% - 32px);height:1px;background:var(--c-border)}.wizard-step-ind.done+.wizard-step-ind:before{background:var(--c-accent)}.wizard-step-dot{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;background:var(--c-surface-alt);color:var(--c-text-3);border:2px solid var(--c-border);position:relative;z-index:1;transition:all var(--norm)}.wizard-step-ind.active .wizard-step-dot{background:var(--c-accent);color:#fff;border-color:var(--c-accent);box-shadow:0 0 12px var(--c-accent)}.wizard-step-ind.done .wizard-step-dot{background:var(--c-ok);color:#fff;border-color:var(--c-ok)}.wizard-step-label{font-size:11px;font-weight:500;color:var(--c-text-3);white-space:nowrap}.wizard-step-ind.active .wizard-step-label{color:var(--c-accent);font-weight:600}.wizard-step-ind.done .wizard-step-label{color:var(--c-ok)}.wizard-body{padding:28px 32px;min-height:260px}.wizard-icon{font-size:36px;margin-bottom:12px}.wizard-title{font-family:var(--font-display);font-size:20px;font-weight:700;color:var(--c-text);margin-bottom:6px;letter-spacing:-.02em}.wizard-desc{font-size:13px;color:var(--c-text-2);line-height:1.6;margin-bottom:24px}.wizard-checklist{display:flex;flex-direction:column;gap:10px}.wizard-check{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--c-text)}.wizard-check-num{width:24px;height:24px;border-radius:50%;background:var(--c-accent-bg);color:var(--c-accent);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex-shrink:0}.wizard-chips{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}.wizard-platform-card{background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-l);overflow:hidden;transition:border-color var(--fast)}.wizard-platform-card.on{border-color:var(--c-accent)}.wizard-platform-head{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;cursor:pointer;gap:8px}.wizard-platform-head:hover{background:var(--c-surface-alt)}.wizard-platform-meta{display:flex;align-items:center;gap:10px;min-width:0}.wizard-platform-icon{width:36px;height:36px;border-radius:var(--r-m);background:var(--c-surface-alt);display:flex;align-items:center;justify-content:center;font-size:20px;line-height:1;flex-shrink:0}.wizard-platform-title-block{display:flex;flex-direction:column;gap:1px;min-width:0}.wizard-platform-name{font-family:var(--font-display);font-size:14px;font-weight:600}.wizard-platform-desc{font-size:12px;color:var(--c-text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wizard-platform-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.wizard-platform-chevron{font-size:12px;color:var(--c-text-3)}.wizard-platform-body{padding:0 16px 16px;border-top:1px solid var(--c-border)}.wizard-cred{background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-l);padding:20px;margin-bottom:14px}.wizard-cred:last-child{margin-bottom:0}.wizard-cred-name{font-family:var(--font-display);font-size:14px;font-weight:600;margin-bottom:14px;color:var(--c-text)}.wizard-radio-group{display:flex;flex-direction:column;gap:8px}.wizard-radio{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border:2px solid var(--c-border);border-radius:var(--r-m);cursor:pointer;transition:all var(--fast)}.wizard-radio:hover{border-color:var(--c-accent-bdr)}.wizard-radio.on{border-color:var(--c-accent);background:var(--c-accent-bg)}.wizard-radio input[type=radio]{margin-top:2px;accent-color:var(--c-accent)}.wizard-radio-body{display:flex;flex-direction:column;gap:2px}.wizard-radio-label{font-size:13px;font-weight:600;color:var(--c-text)}.wizard-radio-desc{font-size:12px;color:var(--c-text-3)}.wizard-review-block{margin-bottom:20px}.wizard-review-head{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--c-text-3);margin-bottom:10px}.wizard-kv{display:flex;justify-content:space-between;align-items:center;padding:7px 0;border-bottom:1px solid var(--c-border);font-size:12px}.wizard-kv span{color:var(--c-text-2)}.wizard-kv code{font-family:var(--font-mono);font-size:11px;color:var(--c-text);background:var(--c-surface-alt);padding:2px 6px;border-radius:4px}.wizard-platforms{display:flex;flex-wrap:wrap;gap:6px}.wizard-platform-pill{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:var(--c-surface-alt);border-radius:999px;font-size:12px;font-weight:500}.wizard-platform-pill .cmd{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--c-accent-bg);color:var(--c-accent);font-weight:500}.wizard-done{text-align:center;padding:20px 0}.wizard-nav{display:flex;align-items:center;padding:16px 32px 24px;gap:10px}.wizard-nav-spacer{flex:1}.wizard-pulse{animation:wiz-pulse 1.2s ease-in-out infinite}@keyframes wiz-pulse{0%,to{opacity:1}50%{opacity:.4}}.conn{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:32px}.conn-card{width:100%;max-width:420px;background:var(--c-surface);border:1px solid var(--c-border);border-radius:var(--r-xl);box-shadow:var(--shadow-l);padding:32px}.conn-logo{width:40px;height:40px;border-radius:var(--r-m);background:var(--c-accent);display:flex;align-items:center;justify-content:center;margin-bottom:20px}.conn-logo svg{width:22px;height:22px;color:#fff}.conn-title{font-family:var(--font-display);font-size:20px;font-weight:700;color:var(--c-text);margin-bottom:6px;letter-spacing:-.02em}.conn-desc{font-size:13px;color:var(--c-text-2);margin-bottom:24px;line-height:1.5}.conn-row{display:flex;gap:8px}.conn-input{flex:1;padding:8px 10px;font-family:var(--font-mono);font-size:13px;color:var(--c-text);background:var(--c-surface-alt);border:1px solid var(--c-border);border-radius:var(--r-s);outline:none;transition:border-color var(--fast)}.conn-input:focus{border-color:var(--c-accent);box-shadow:0 0 0 3px var(--c-accent-bg)}.conn-status{font-size:12px;margin-top:10px;color:var(--c-text-3)}.conn-status.ok{color:var(--c-ok)}.conn-status.err{color:var(--c-err)}@media(max-width:1024px){.stats-grid{grid-template-columns:1fr}}@media(max-width:768px){.content{padding:20px 16px 40px}.header{padding:0 16px}.header-toolbar{padding:10px 16px}.platform-grid{grid-template-columns:1fr}.platform-card-head{align-items:flex-start;flex-direction:column}.platform-card-right{width:100%;grid-template-columns:repeat(4,minmax(0,1fr))}.platform-card-control-menu,.platform-card-menu-btn{width:100%}.wizard-chips{grid-template-columns:1fr}}
|