huhaa-myskills 0.2.13 → 0.3.0
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/bin/huhaa-myskills.mjs +71 -5
- package/package.json +1 -1
- package/packages/web/dist/assets/index-CaQOPbDU.css +1 -0
- package/packages/web/dist/assets/index-Dlvh4-4K.js +36 -0
- package/packages/web/dist/index.html +2 -2
- package/packages/web/src/App.vue +239 -265
- package/packages/web/src/components/DetailPanel.vue +551 -0
- package/packages/web/src/stores/i18n.js +6 -0
- package/packages/web/src/stores/skills.js +127 -0
- package/packages/web/src/styles.css +922 -275
- package/packages/web/dist/assets/index-BPepSb3q.js +0 -36
- package/packages/web/dist/assets/index-CIGkgT5w.css +0 -1
package/bin/huhaa-myskills.mjs
CHANGED
|
@@ -72,7 +72,7 @@ Usage:
|
|
|
72
72
|
huhaa-myskills <command> [options]
|
|
73
73
|
|
|
74
74
|
Commands:
|
|
75
|
-
start Scan + start server + open browser (default)
|
|
75
|
+
start Scan + start server + open browser (runs in background by default)
|
|
76
76
|
scan Scan only, dump IR JSON to stdout
|
|
77
77
|
stats Scan + print human-readable summary (counts / brands / errors / samples)
|
|
78
78
|
duplicates Scan + print duplicate diagnostics by name/content/path
|
|
@@ -82,8 +82,9 @@ Commands:
|
|
|
82
82
|
dev Dev mode (Vite + nodemon)
|
|
83
83
|
|
|
84
84
|
Options:
|
|
85
|
-
-v, --version
|
|
86
|
-
-h, --help
|
|
85
|
+
-v, --version Show version
|
|
86
|
+
-h, --help Show this message
|
|
87
|
+
-f, --foreground Keep running in foreground (for debugging)
|
|
87
88
|
|
|
88
89
|
Env:
|
|
89
90
|
HUHAA_HOME override user data dir (default: ~/.config/huhaa-myskills)
|
|
@@ -94,6 +95,7 @@ Paths:
|
|
|
94
95
|
config ${configFile()}
|
|
95
96
|
cache ${cacheFile()}
|
|
96
97
|
state ${stateFile()}
|
|
98
|
+
logs ${path.join(homeDir(), 'huhaa.log')}
|
|
97
99
|
`);
|
|
98
100
|
}
|
|
99
101
|
|
|
@@ -268,6 +270,7 @@ function printDupGroup(title, groups, limit) {
|
|
|
268
270
|
|
|
269
271
|
async function cmdStart() {
|
|
270
272
|
await ensureConfigOrInit();
|
|
273
|
+
const isForeground = process.argv.includes('--foreground') || process.argv.includes('-f');
|
|
271
274
|
const preferred = parseInt(process.env.PORT || '11520', 10);
|
|
272
275
|
const port = await pickPort(preferred, 10);
|
|
273
276
|
if (!port) {
|
|
@@ -275,16 +278,79 @@ async function cmdStart() {
|
|
|
275
278
|
process.exit(1);
|
|
276
279
|
}
|
|
277
280
|
if (port !== preferred) {
|
|
278
|
-
console.
|
|
281
|
+
console.warn(`[start] port ${preferred} busy, using ${port} instead.`);
|
|
279
282
|
}
|
|
280
283
|
|
|
284
|
+
const homeDirectory = homeDir();
|
|
285
|
+
const logFile = path.join(homeDirectory, 'huhaa.log');
|
|
286
|
+
|
|
287
|
+
// 后台模式:fork 子进程
|
|
288
|
+
if (!isForeground) {
|
|
289
|
+
return startBackgroundServer(port, logFile, homeDirectory);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// 前台模式:直接启动
|
|
293
|
+
await runServer(port, logFile, homeDirectory);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async function startBackgroundServer(port, logFile, homeDirectory) {
|
|
297
|
+
// 检查是否已有运行的实例
|
|
298
|
+
try {
|
|
299
|
+
const stateData = JSON.parse(fs.readFileSync(stateFile(), 'utf8'));
|
|
300
|
+
if (stateData.pid && isProcessRunning(stateData.pid)) {
|
|
301
|
+
console.log(`✓ HuHaa-MySkills already running on http://localhost:${stateData.port}`);
|
|
302
|
+
console.log(`📝 Logs: ${logFile}`);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
} catch {
|
|
306
|
+
// 状态文件不存在或无效,继续启动
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 打开日志文件用于输出重定向
|
|
310
|
+
const logFd = fs.openSync(logFile, 'a');
|
|
311
|
+
|
|
312
|
+
// Spawn 子进程
|
|
313
|
+
const child = spawn(process.execPath, [process.argv[1], 'start', '--foreground'], {
|
|
314
|
+
detached: true,
|
|
315
|
+
stdio: ['ignore', logFd, logFd],
|
|
316
|
+
env: {
|
|
317
|
+
...process.env,
|
|
318
|
+
PORT: port.toString()
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
child.unref();
|
|
323
|
+
|
|
324
|
+
// 等待子进程启动,检查端口是否开放
|
|
325
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
326
|
+
|
|
327
|
+
// 关闭日志文件描述符(子进程已继承)
|
|
328
|
+
fs.closeSync(logFd);
|
|
329
|
+
|
|
330
|
+
console.log(`✓ HuHaa-MySkills running in background at http://localhost:${port}`);
|
|
331
|
+
console.log(`📝 Logs: ${logFile}`);
|
|
332
|
+
console.log(`💡 To view logs: tail -f ${logFile}`);
|
|
333
|
+
console.log(`💡 To stop: pkill -f "huhaa-myskills start"`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function isProcessRunning(pid) {
|
|
337
|
+
try {
|
|
338
|
+
process.kill(pid, 0);
|
|
339
|
+
return true;
|
|
340
|
+
} catch {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function runServer(port, logFile, homeDirectory) {
|
|
281
346
|
writeJson(stateFile(), { port, pid: process.pid, startedAt: new Date().toISOString() });
|
|
282
347
|
|
|
283
348
|
const { startServer } = await import(path.join(PKGS_ROOT, 'server/src/index.mjs'));
|
|
284
349
|
await startServer({ port });
|
|
285
350
|
|
|
286
351
|
console.log(`\n HuHaa-MySkills running: http://localhost:${port}\n`);
|
|
287
|
-
console.log(` data dir: ${
|
|
352
|
+
console.log(` data dir: ${homeDirectory}`);
|
|
353
|
+
console.log(` logs: ${logFile}`);
|
|
288
354
|
console.log(` Ctrl+C to stop.\n`);
|
|
289
355
|
|
|
290
356
|
openBrowser(`http://localhost:${port}`);
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.skill-tree[data-v-1b7c4344]{display:flex;flex-direction:column;overflow-y:auto;font-size:13px;border-right:1px solid #ddd;-webkit-user-select:none;user-select:none}.tree-group[data-v-1b7c4344]{border-bottom:1px solid #f0f0f0}.tree-group-header[data-v-1b7c4344]{width:100%;padding:8px 10px;background:#f8f8f8;border:none;border-bottom:1px solid #e8e8e8;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:6px;font-size:12px;text-align:left;justify-content:flex-start;transition:all .15s ease}.tree-group-header[data-v-1b7c4344]:hover{background:#f0f0f0}.tree-group-header.expanded[data-v-1b7c4344]{background:#e8e8e8}.tree-arrow[data-v-1b7c4344]{width:16px;text-align:center;flex-shrink:0;font-size:11px;color:#666}.source-icon[data-v-1b7c4344]{width:16px;text-align:center;flex-shrink:0;font-size:14px}.source-name[data-v-1b7c4344]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-count[data-v-1b7c4344]{margin-left:auto;color:#999;font-size:11px;font-weight:400;flex-shrink:0}.tree-group-items[data-v-1b7c4344]{background:#fafafa;display:flex;flex-direction:column}.skill-tree-item[data-v-1b7c4344]{display:flex;align-items:center;gap:6px;width:100%;padding:6px 16px;border:none;background:transparent;cursor:pointer;font-size:12px;transition:background-color .1s ease;text-align:left;color:inherit;justify-content:flex-start}.skill-tree-item[data-v-1b7c4344]:hover{background:#f0f0f0}.skill-tree-item.active[data-v-1b7c4344]{background:#e3f2fd;color:#1976d2;font-weight:500}.icon[data-v-1b7c4344]{width:16px;text-align:center;flex-shrink:0;font-size:12px}.name[data-v-1b7c4344]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.category-tag[data-v-1b7c4344]{margin-left:4px;padding:1px 4px;background:#f0f0f0;border-radius:2px;font-size:10px;color:#666;flex-shrink:0}.empty-tree[data-v-1b7c4344]{display:flex;align-items:center;justify-content:center;height:100px;color:#999;font-size:12px}.directory-tree[data-v-265e211f]{display:flex;flex-direction:column;overflow-y:auto;font-size:13px;-webkit-user-select:none;user-select:none}.tree-item[data-v-265e211f]{display:flex;flex-direction:column}.tree-dir[data-v-265e211f]{padding:6px 10px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;gap:6px;font-size:12px;text-align:left;color:inherit;transition:background-color .1s ease;width:100%;justify-content:flex-start}.tree-dir[data-v-265e211f]:hover{background:#f0f0f0}.tree-dir.selected[data-v-265e211f]{background:#e8f4f8;color:#0d5a7c;font-weight:500}.tree-arrow[data-v-265e211f]{width:16px;text-align:center;flex-shrink:0;font-size:10px;color:#666}.tree-icon[data-v-265e211f]{width:16px;text-align:center;flex-shrink:0;font-size:12px}.tree-name[data-v-265e211f]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}.tree-count[data-v-265e211f]{margin-left:auto;padding:0 4px;background:#e8e8e8;border-radius:2px;font-size:10px;color:#666;flex-shrink:0}.tree-skills[data-v-265e211f]{display:flex;flex-direction:column}.tree-skill-item[data-v-265e211f]{padding:6px 10px;background:transparent;border:none;cursor:pointer;display:flex;align-items:center;gap:6px;font-size:12px;text-align:left;color:inherit;transition:background-color .1s ease;width:100%;justify-content:flex-start}.tree-skill-item[data-v-265e211f]:hover{background:#f5f5f5}.tree-skill-item.active[data-v-265e211f]{background:#e3f2fd;color:#1976d2;font-weight:500}.empty-tree[data-v-265e211f]{display:flex;align-items:center;justify-content:center;height:100px;color:#999;font-size:12px}.app-tree[data-v-450fa8e2]{display:flex;flex-direction:column;overflow-y:auto;font-size:13px;-webkit-user-select:none;user-select:none}.tree-group[data-v-450fa8e2]{border-bottom:1px solid #f0f0f0}.tree-group-header[data-v-450fa8e2]{width:100%;padding:8px 10px;background:#f8f8f8;border:none;border-bottom:1px solid #e8e8e8;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:6px;font-size:12px;text-align:left;justify-content:flex-start;transition:all .15s ease}.tree-group-header[data-v-450fa8e2]:hover{background:#f0f0f0}.tree-group-header.expanded[data-v-450fa8e2]{background:#e8e8e8}.tree-arrow[data-v-450fa8e2]{width:16px;text-align:center;flex-shrink:0;font-size:11px;color:#666}.app-icon[data-v-450fa8e2]{width:16px;text-align:center;flex-shrink:0;font-size:14px}.app-name[data-v-450fa8e2]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-count[data-v-450fa8e2]{margin-left:auto;color:#999;font-size:11px;font-weight:400;flex-shrink:0}.tree-group-items[data-v-450fa8e2]{background:#fafafa;display:flex;flex-direction:column}.skill-tree-item[data-v-450fa8e2]{display:flex;align-items:center;gap:6px;width:100%;padding:6px 16px;border:none;background:transparent;cursor:pointer;font-size:12px;text-align:left;transition:background-color .1s ease;color:inherit;justify-content:flex-start}.skill-tree-item[data-v-450fa8e2]:hover{background:#f0f0f0}.skill-tree-item.active[data-v-450fa8e2]{background:#e3f2fd;color:#1976d2;font-weight:500}.icon[data-v-450fa8e2]{width:16px;text-align:center;flex-shrink:0;font-size:12px}.name[data-v-450fa8e2]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.source-tag[data-v-450fa8e2]{margin-left:4px;padding:1px 4px;background:#f0f0f0;border-radius:2px;font-size:10px;color:#666;flex-shrink:0}.empty-tree[data-v-450fa8e2]{display:flex;align-items:center;justify-content:center;height:100px;color:#999;font-size:12px}:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,PingFang SC,sans-serif;color:#182033;background:#eef1f6;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}*{box-sizing:border-box}html,body,#app{height:100%;margin:0}button,input{font:inherit}button{cursor:pointer}.shell{height:100vh;display:grid;grid-template-columns:100px 1fr 400px;grid-template-rows:60px 1fr;overflow:hidden;gap:0}.sidebar{grid-column:1 / 2;grid-row:2 / 3;background:#f8fafc;border-right:1px solid #e5e7eb;overflow:hidden;padding:0;position:relative;-webkit-user-select:none;user-select:none;display:flex;flex-direction:column}.sidebar-toggle{flex:0 0 auto;height:40px;display:flex;align-items:center;justify-content:center;border-bottom:1px solid #e5e7eb;cursor:pointer;background:#fff;font-size:14px;color:#6b7280;transition:all .2s ease;padding:0 4px}.sidebar-toggle:hover{background:#f3f4f6;color:#374151}.sidebar.collapsed .sidebar-toggle{justify-content:center;padding:0}.sidebar-content{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px}.filter-compact{display:flex;flex-direction:column;gap:8px}.filter-item{display:flex;flex-direction:column;gap:4px;font-size:11px}.filter-item span{color:#6b7280;font-weight:600;padding:0 4px}.filter-select-compact{padding:6px 4px;border:1px solid #d1d5db;border-radius:4px;background:#fff;color:#374151;font-size:11px;cursor:pointer}.filter-select-compact:hover{border-color:#9ca3af}.filter-select-compact:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 2px #8b5cf61a}.sidebar-resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;background:transparent;cursor:col-resize;transition:background .2s}.sidebar-resize-handle:hover{background:#8b5cf6}.topbar{grid-column:1 / 4;grid-row:1 / 2;padding:10px 16px;background:linear-gradient(180deg,#ffffffeb,#f8fafceb);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid #d9dee8;display:flex;align-items:center;gap:12px;height:60px}.topbar-left{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.search-box{display:flex;align-items:center;gap:9px;padding:0 13px;border:1px solid #d4dbe8;border-radius:14px;background:#f8fafc;box-shadow:inset 0 1px #fffc;min-width:0;flex:1}.search-icon{color:#7c3aed;font-size:18px;line-height:1;flex-shrink:0}.search-box input{width:100%;height:40px;padding:0;border:0;outline:none;background:transparent;color:#111827;font-size:14px}.search-box input::placeholder{color:#9ca3af}.search-box:focus-within{border-color:#8b5cf6;background:#fff;box-shadow:0 0 0 4px #7c3aed1c}.topbar-right{display:flex;gap:8px;flex-shrink:0}.btn{height:40px;border:0;border-radius:12px;padding:0 14px;font-weight:600;font-size:13px;color:#374151;background:#eef2ff;transition:transform .12s ease,box-shadow .12s ease,background .12s ease;cursor:pointer;white-space:nowrap}.btn:hover{transform:translateY(-1px);box-shadow:0 8px 18px #0f172a1a}.btn:disabled{opacity:.58;cursor:wait;transform:none;box-shadow:none}.btn.soft{background:#f1f5f9;color:#475569}.btn.primary{color:#fff;background:linear-gradient(135deg,#7c3aed,#2563eb);box-shadow:0 10px 20px #4f46e52e}.main{grid-column:2 / 3;grid-row:1 / 3;overflow:hidden;display:flex;flex-direction:column;background:#f3f5fa}.content-wrapper{flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0}.error,.loading{padding:16px;text-align:center;font-size:14px}.error{color:#dc2626;background:#fee2e2}.loading{color:#7c3aed;background:#f3f4f6}.list-panel{flex:1;overflow-y:auto;display:flex;flex-direction:column;border-right:1px solid #e5e7eb}.list-head{flex:0 0 auto;padding:12px 16px;display:flex;align-items:center;justify-content:space-between;gap:16px;background:#fff;border-bottom:1px solid #e5e7eb}.list-view-label{font-weight:600;color:#111827;min-width:80px}.list-head>div:last-child{display:flex;align-items:center;gap:6px;color:#6b7280;font-size:13px}.list-head strong{color:#111827;font-size:14px}.skill-card{width:100%;padding:12px 16px;border:0;border-bottom:1px solid #e5e7eb;background:#fff;text-align:left;cursor:pointer;transition:background .2s ease;font-size:13px}.skill-card:hover{background:#f9fafb}.skill-card.selected{background:#f0f9ff;border-left:3px solid #0284c7;padding-left:13px}.skill-title{display:flex;align-items:center;gap:8px;margin-bottom:6px}.src{display:inline-block;padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;background:#e0e7ff;color:#3730a3;flex-shrink:0}.skill-title strong{color:#111827;font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-chipline{display:flex;gap:6px;margin-bottom:4px;font-size:12px}.skill-chipline span{padding:2px 6px;border-radius:3px;background:#f3f4f6;color:#6b7280}.skill-meta{font-size:12px;color:#9ca3af;margin-bottom:6px}.skill-card p{margin:0;color:#6b7280;font-size:12px;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}mark{background:#fef3c7;padding:2px 0;border-radius:2px}.detail-panel-fixed{grid-column:3 / 4;grid-row:1 / 3;background:#fff;border-left:1px solid #e5e7eb;overflow:hidden;display:flex;flex-direction:column;position:relative}.detail-close-btn{flex:0 0 auto;padding:12px 16px;border-bottom:1px solid #e5e7eb;display:flex;justify-content:space-between;align-items:center}.detail-close-btn h3{margin:0;font-size:14px;font-weight:600}.detail-close-btn button{padding:6px 12px;border:1px solid #d1d5db;border-radius:6px;background:#fff;color:#6b7280;font-size:12px;cursor:pointer;transition:all .2s ease}.detail-close-btn button:hover{background:#f3f4f6;color:#374151}.detail-head{flex:0 0 auto;padding:16px;border-bottom:1px solid #e5e7eb}.detail-head>div>div:first-child{margin-bottom:8px}.detail-kicker{display:flex;gap:6px;align-items:center;font-size:11px;margin-bottom:4px}.detail-kicker span{padding:2px 6px;border-radius:4px;background:#f3f4f6;color:#6b7280}.detail-kicker .src{background:none;font-weight:600}.detail-head h2{margin:0 0 8px;font-size:18px}.badge-row{display:flex;gap:4px;margin-bottom:8px;flex-wrap:wrap}.badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;font-weight:600;background:#e0e7ff;color:#3730a3}.badge.danger{background:#fee2e2;color:#b91c1c}.badge.warn{background:#fef3c7;color:#b45309}.detail-head p{margin:0;font-size:13px;color:#4b5563;line-height:1.5}.actions{flex:0 0 auto;padding:12px 16px;border-bottom:1px solid #e5e7eb;display:grid;grid-template-columns:repeat(2,1fr);gap:6px}.action-btn{padding:8px 12px;font-size:12px;border:1px solid #d1d5db;border-radius:8px;background:#fff;color:#374151;cursor:pointer;transition:all .2s ease;white-space:nowrap}.action-btn:hover{background:#f9fafb;border-color:#9ca3af}.notice{flex:0 0 auto;padding:8px 16px;background:#fef3c7;border-bottom:1px solid #fcd34d;font-size:12px;color:#92400e}.kv>div{display:grid;grid-template-columns:140px 1fr;gap:12px;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #f3f4f6;font-size:12px}@media(max-width:1199px){.shell{grid-template-columns:80px 1fr 320px}}@media(max-width:767px){.shell{grid-template-columns:1fr 300px}.detail-panel{grid-column:2 / 3}.actions,.usage-grid{grid-template-columns:1fr}.kv>div{grid-template-columns:1fr}}.detail-close{position:absolute;top:12px;right:12px;width:32px;height:32px;border:0;border-radius:8px;background:#f3f4f6;color:#6b7280;font-size:18px;cursor:pointer;z-index:10;transition:all .2s ease}.detail-close:hover{background:#e5e7eb;color:#1f2937}.detail-scroll{flex:1 1 auto;overflow-y:auto;padding:16px}.usage-card{margin-bottom:24px}.usage-head{margin-bottom:12px}.usage-head span{display:block;font-size:11px;color:#9ca3af;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}.usage-head h3{margin:0;font-size:14px;font-weight:600}.usage-prompt{margin-bottom:12px;padding:10px 12px;background:#f3f4f6;border-radius:8px;border-left:3px solid #8b5cf6}.usage-prompt code{font-size:11px;color:#374151;word-break:break-word}.usage-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px}.usage-grid>div{padding:8px 10px;background:#f9fafb;border-radius:6px}.usage-grid strong{display:block;font-size:11px;color:#6b7280;margin-bottom:4px}.usage-grid p{margin:0;font-size:12px;color:#374151;line-height:1.4}.usage-block{margin-bottom:12px}.usage-block strong{display:block;font-size:12px;margin-bottom:6px}.tag{display:inline-block;padding:3px 8px;margin:2px 4px 2px 0;border-radius:4px;background:#e0e7ff;color:#3730a3;font-size:11px}.param-table{display:grid;gap:8px;font-size:12px}.param-table>div{padding:8px;background:#f9fafb;border-radius:6px}.param-table code{display:block;font-size:11px;color:#dc2626;margin-bottom:2px}.param-table b{display:inline-block;padding:1px 4px;background:#fef3c7;color:#b45309;border-radius:2px;font-size:10px;margin-left:4px}.usage-link{display:block;padding:6px 0;font-size:12px;color:#0ea5e9;text-decoration:none;border-bottom:1px solid #e0e7ff;word-break:break-word}.usage-link:hover{color:#0284c7}.kv{margin-bottom:24px}.kv>div{margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #f3f4f6;font-size:12px}.kv dt{font-weight:600;color:#6b7280;word-break:break-word}.kv dd{margin:0;color:#374151;word-break:break-word}.kv code{display:block;padding:6px;background:#f3f4f6;border-radius:4px;font-size:11px;color:#374151;overflow-x:auto}.kv-error dd{color:#b91c1c}.markdown{margin-bottom:20px;font-size:13px;line-height:1.6;color:#374151}.markdown h1,.markdown h2,.markdown h3{margin-top:16px;margin-bottom:8px;font-weight:600}.markdown p{margin:8px 0}.markdown code{background:#f3f4f6;padding:2px 4px;border-radius:3px;font-size:11px;color:#dc2626}.markdown pre{background:#1f2937;padding:10px;border-radius:6px;overflow-x:auto;margin:8px 0}.markdown pre code{background:none;color:#e5e7eb;padding:0}
|