oh-my-knowledge 0.45.0 → 0.46.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/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/assets/agent-skills/omk/SKILL.md +3 -3
- package/dist/assets/agent-skills/omk/references/commands.md +13 -6
- package/dist/cli/commands/doctor.d.ts +3 -2
- package/dist/cli/commands/doctor.js +66 -63
- package/dist/cli/lib/cmd-flags.d.ts +3 -2
- package/dist/cli/lib/i18n-dict/common.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/common.js +0 -4
- package/dist/doctor/endpoint-rule.js +1 -1
- package/dist/doctor/health/composer.js +162 -50
- package/dist/doctor/health/consensus.d.ts +43 -0
- package/dist/doctor/health/consensus.js +224 -0
- package/dist/doctor/health/dimension-spec.d.ts +6 -0
- package/dist/doctor/health/register.d.ts +0 -1
- package/dist/doctor/health/register.js +0 -1
- package/dist/doctor/index.js +3 -0
- package/dist/doctor/messages.d.ts +1 -1
- package/dist/doctor/messages.js +8 -0
- package/dist/doctor/rules.d.ts +4 -2
- package/dist/doctor/rules.js +4 -2
- package/dist/executors/claude-cli.js +1 -1
- package/dist/observability/skill-chain-advisories.js +2 -2
- package/dist/renderer/doctor-detail-renderer.js +30 -2
- package/dist/renderer/report-shell.d.ts +1 -1
- package/dist/renderer/report-shell.js +5 -0
- package/dist/renderer/skill-detail-renderer.js +844 -100
- package/dist/server/skill-index.js +37 -1
- package/dist/shared/llm-prompts/registry.js +2 -1
- package/dist/shared/llm-prompts/skill-health-merge.d.ts +22 -0
- package/dist/shared/llm-prompts/skill-health-merge.js +79 -0
- package/dist/shared/llm-prompts/skill-health.js +1 -1
- package/dist/types/doctor.d.ts +32 -8
- package/dist/types/skill-index.d.ts +10 -0
- package/package.json +4 -3
|
@@ -40,7 +40,7 @@ export async function claudeCliExecutor({ model, system, prompt, cwd, skillDir,
|
|
|
40
40
|
if (system)
|
|
41
41
|
args.push('--system-prompt', system);
|
|
42
42
|
// effort 决策:
|
|
43
|
-
// - lean=true(纯文本生成):默认 'low',但允许调用方显式覆盖(如 doctor
|
|
43
|
+
// - lean=true(纯文本生成):默认 'low',但允许调用方显式覆盖(如 doctor 用 --effort 调高)。
|
|
44
44
|
// - 否则用调用方传入的 effort,或 sonnet 默认(不传 flag = claude CLI 自己定)。
|
|
45
45
|
const effectiveEffort = lean ? (effort ?? 'low') : effort;
|
|
46
46
|
if (lean) {
|
|
@@ -49,8 +49,8 @@ const ADVISORIES = {
|
|
|
49
49
|
skill_md_not_found: {
|
|
50
50
|
code: 'skill_md_not_found',
|
|
51
51
|
shortLabel: '本地未找到 SKILL.md',
|
|
52
|
-
message: '本地常见 skill 目录里没有这个 skill 的 SKILL.md,inbox
|
|
53
|
-
commandTemplate: 'omk doctor ~/.claude/skills/${skillName}/SKILL.md
|
|
52
|
+
message: '本地常见 skill 目录里没有这个 skill 的 SKILL.md,inbox 跑不了静态/运行时审计。如果你想看 LLM 健康度审计(触发边界 / 文档 / 依赖 / 安全等 7 维),可以试试 omk doctor;inbox 本身不依赖它。',
|
|
53
|
+
commandTemplate: 'omk doctor ~/.claude/skills/${skillName}/SKILL.md',
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
56
|
export function getSkillChainAdvisory(code) {
|
|
@@ -46,8 +46,18 @@ function renderRuleCard(r, lang, forceOpen = false) {
|
|
|
46
46
|
const mIcon = isErr
|
|
47
47
|
? svgIcon('x', { size: 14, style: 'color:#dc2626;vertical-align:-2px;margin-right:5px' })
|
|
48
48
|
: svgIcon('warn', { size: 14, style: `color:${f.level === '警告' ? '#d97706' : '#637083'};vertical-align:-2px;margin-right:5px` });
|
|
49
|
+
// 多采样支持度 k/n:仅 n>1 时展示(单次采样无意义)。k<n 用偏灰提示"非每次都报"。
|
|
50
|
+
const sup = f.support;
|
|
51
|
+
const supportTitle = sup && typeof sup.n === 'number' && typeof sup.k === 'number'
|
|
52
|
+
? (lang === 'zh'
|
|
53
|
+
? `${sup.n} 次采样里有 ${sup.k} 次报了这条`
|
|
54
|
+
: `Reported by ${sup.k} of ${sup.n} samples`)
|
|
55
|
+
: '';
|
|
56
|
+
const supBadge = sup && typeof sup.n === 'number' && sup.n > 1 && typeof sup.k === 'number'
|
|
57
|
+
? `<span class="rs-badge rs-badge--${sup.k >= sup.n ? 'pass' : 'warn'}" title="${e(supportTitle)}" style="margin-left:6px">${sup.k}/${sup.n}</span>`
|
|
58
|
+
: '';
|
|
49
59
|
return `<div class="rs-finding rs-finding--${isErr ? 'err' : 'warn'}">
|
|
50
|
-
<div class="rs-finding-desc">${mIcon}${e(f.description ?? '')}</div>
|
|
60
|
+
<div class="rs-finding-desc">${mIcon}${e(f.description ?? '')}${supBadge}</div>
|
|
51
61
|
${f.suggestion ? `<div class="rs-finding-sug">${svgIcon('bulb', { size: 13, style: 'vertical-align:-2px;margin-right:5px' })}${e(f.suggestion)}</div>` : ''}
|
|
52
62
|
</div>`;
|
|
53
63
|
}).join('');
|
|
@@ -56,7 +66,25 @@ function renderRuleCard(r, lang, forceOpen = false) {
|
|
|
56
66
|
<div class="rs-card-body">${findingHtml}</div>
|
|
57
67
|
</details>`;
|
|
58
68
|
}
|
|
69
|
+
function renderSampleDegradedAlert(summary, lang) {
|
|
70
|
+
const samples = summary?.detail?.samples;
|
|
71
|
+
if (!samples || samples.degraded !== true)
|
|
72
|
+
return '';
|
|
73
|
+
const requested = typeof samples.requested === 'number' ? samples.requested : 0;
|
|
74
|
+
const succeeded = typeof samples.succeeded === 'number' ? samples.succeeded : 0;
|
|
75
|
+
if (requested <= 1 || succeeded >= requested)
|
|
76
|
+
return '';
|
|
77
|
+
const title = lang === 'zh' ? '共识置信降级' : 'Consensus confidence degraded';
|
|
78
|
+
const body = lang === 'zh'
|
|
79
|
+
? `本次只成功解析 ${succeeded}/${requested} 次采样,finding 支持度仅基于成功样本。建议重跑,或在限流场景下降低并发。`
|
|
80
|
+
: `Only ${succeeded}/${requested} samples parsed successfully. Finding support is based on successful samples only. Re-run or lower concurrency if rate-limited.`;
|
|
81
|
+
return `<div class="rs-alert rs-alert--warn">
|
|
82
|
+
<div class="rs-alert-title">${e(title)}</div>
|
|
83
|
+
<div class="rs-alert-body">${e(body)}</div>
|
|
84
|
+
</div>`;
|
|
85
|
+
}
|
|
59
86
|
function renderSkillBlock(sk, lang) {
|
|
87
|
+
const summary = sk.results.find((r) => r.ruleId.endsWith(':_summary'));
|
|
60
88
|
const rules = sk.results.filter((r) => !r.ruleId.endsWith(':_summary'));
|
|
61
89
|
const pass = rules.filter((r) => r.status === 'pass').length;
|
|
62
90
|
const warn = rules.filter((r) => r.status === 'warn').length;
|
|
@@ -78,7 +106,7 @@ function renderSkillBlock(sk, lang) {
|
|
|
78
106
|
const oksHtml = oks.length
|
|
79
107
|
? `<div class="rs-panel"><details class="rs-fold"><summary>${zh ? `展开 ${oks.length} 条通过的规则` : `Show ${oks.length} passed rules`}</summary>${oks.map((r) => renderRuleCard(r, lang)).join('')}</details></div>`
|
|
80
108
|
: '';
|
|
81
|
-
return stats + issuesHtml + oksHtml;
|
|
109
|
+
return renderSampleDegradedAlert(summary, lang) + stats + issuesHtml + oksHtml;
|
|
82
110
|
}
|
|
83
111
|
export function renderDoctorDetail(report, skillName, langQ, lang = DEFAULT_LANG, skillContext) {
|
|
84
112
|
const zh = lang === 'zh';
|
|
@@ -74,4 +74,4 @@ export interface ReportShellOpts {
|
|
|
74
74
|
extraCss?: string;
|
|
75
75
|
}
|
|
76
76
|
export declare function reportShell(opts: ReportShellOpts, lang?: Lang): string;
|
|
77
|
-
export declare const REPORT_SHELL_CSS = "\n/* \u2500\u2500 \u9762\u5305\u5C51(\u66FF\u6389\u88F8\u8FD4\u56DE\u94FE\u63A5) \u2500\u2500 */\n.rs-crumb{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:13px;color:#637083}\n.rs-crumb-link{display:inline-flex;align-items:center;gap:6px;color:#637083;text-decoration:none}\n.rs-crumb-link:hover{color:#4f46e5;text-decoration:none}\n.rs-crumb-link svg{color:#9ca3af}\n.rs-crumb-link:hover svg{color:#4f46e5}\n.rs-crumb-sep{color:#c0c6d2}\n.rs-crumb-dim{color:#637083}\n.rs-crumb-cur{color:#182033;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-crumb-spacer{flex:1}\n.rs-crumb-back{display:inline-flex;align-items:center;gap:5px;color:#9ca3af;text-decoration:none;flex-shrink:0}\n.rs-crumb-back:hover{color:#4f46e5;text-decoration:none}\n\n/* \u2500\u2500 skill \u7EF4\u5EA6\u5207\u6362\u5668(doctor/eval/observe \u4E92\u94FE)\u2014 \u5206\u6BB5\u63A7\u4EF6\u98CE \u2500\u2500 */\n.rs-dims{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 16px}\n.rs-dims-seg{display:inline-flex;align-items:stretch;background:#fff;border:1px solid #e4e8f1;border-radius:10px;padding:3px;gap:2px;box-shadow:0 1px 2px rgba(31,41,55,3%)}\n.rs-dim{display:inline-flex;align-items:center;gap:7px;font-size:13px;padding:7px 14px;border-radius:7px;color:#637083;text-decoration:none;white-space:nowrap;transition:background .12s,color .12s}\na.rs-dim:hover{background:#f1f4f9;color:#182033}\n.rs-dim-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}\n.rs-dim-lbl{font-weight:500}\n/* \u5F53\u524D\u7EF4\u5EA6:\u6D45\u586B\u5145 + \u72B6\u6001\u70B9\u5DF2\u8868\u660E\u8EAB\u4EFD,\u6587\u5B57\u52A0\u91CD */\n.rs-dim--active{background:#f1f4f9;color:#182033;cursor:default}\n.rs-dim--active .rs-dim-lbl{font-weight:700}\n.rs-dim--empty{color:#b6bcc8;cursor:default}\n/* \u5168\u90E8\u5386\u53F2\u6309\u94AE */\n.rs-hist-btn{display:inline-flex;align-items:center;gap:6px;font-size:13px;padding:7px 13px;border-radius:9px;border:1px solid #e4e8f1;background:#fff;color:#637083;cursor:pointer;white-space:nowrap;font-family:inherit;transition:border-color .15s,color .15s}\n.rs-hist-btn:hover{border-color:#c7cedb;color:#182033}\n.rs-hist-ct{font-variant-numeric:tabular-nums;font-weight:700;color:#9ca3af;font-size:12px}\n/* \u5168\u90E8\u5386\u53F2\u5F39\u6846 */\n.rs-hist-overlay{display:none;position:fixed;inset:0;background:rgba(24,32,51,.32);z-index:50;align-items:flex-start;justify-content:center;padding:8vh 16px}\n.rs-hist-modal{background:#fff;border-radius:14px;box-shadow:0 24px 60px rgba(31,41,55,.22);width:100%;max-width:520px;max-height:76vh;display:flex;flex-direction:column;overflow:hidden}\n.rs-hist-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #eef1f6;font-size:14px;color:#182033}\n.rs-hist-x{background:transparent;border:none;color:#9ca3af;font-size:16px;cursor:pointer;line-height:1;padding:4px}\n.rs-hist-x:hover{color:#182033}\n.rs-hist-list{overflow-y:auto;padding:6px 10px 12px}\n.rs-hist-group{margin-top:8px}\n.rs-hist-group-h{display:flex;align-items:center;gap:7px;font-size:12px;color:#637083;font-weight:600;padding:8px 8px 6px}\n.rs-hist-group-dot{width:7px;height:7px;border-radius:50%}\n.rs-hist-group-h small{font-weight:500;color:#b6bcc8}\n.rs-hist-row{display:flex;align-items:baseline;gap:14px;padding:8px;border-radius:8px;text-decoration:none;color:#182033;font-size:13px}\n.rs-hist-row:hover{background:#f1f4f9}\n.rs-hist-row--cur{background:#f1f4f9;cursor:default}\n.rs-hist-date{font-variant-numeric:tabular-nums;color:#637083;min-width:88px;flex-shrink:0}\n.rs-hist-score{font-weight:700;font-variant-numeric:tabular-nums;font-family:\"SF Mono\",Menlo,monospace;min-width:72px;flex-shrink:0}\n.rs-hist-score--green{color:#1f9d63}.rs-hist-score--yellow{color:#d97706}.rs-hist-score--red{color:#dc2626}.rs-hist-score--gray{color:#9ca3af}\n.rs-hist-meta{flex:1;min-width:0;color:#9ca3af;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-hist-go{color:#c0c6d2;font-size:13px;flex-shrink:0}\n.rs-hist-row:hover .rs-hist-go{color:#637083}\n.rs-hist-row--cur .rs-hist-go{color:#4f46e5;font-weight:600;font-size:12px}\n\n/* \u2500\u2500 Hero \u2500\u2500 */\n.rs-hero{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:20px 24px;background:#fff;border:1px solid #e4e8f1;border-radius:12px;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}\n@media(max-width:640px){.rs-hero{flex-direction:column;align-items:flex-start}}\n.rs-hero-left{display:flex;flex-direction:column;gap:4px;min-width:0}\n.rs-hero-kind{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#637083}\n.rs-hero-icon{display:inline-flex;align-items:center}\n.rs-hero-name{margin:0;font-size:20px;font-weight:700;color:#182033;letter-spacing:-.2px}\n.rs-hero-meta{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:4px;color:#9ca3af;font-size:12px;font-variant-numeric:tabular-nums}\n.rs-hero-meta span{display:inline-flex;align-items:center;gap:4px}\n.rs-hero-score{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex-shrink:0;line-height:1}\n.rs-hero-num{font-size:40px;font-weight:800;letter-spacing:-1.5px;font-variant-numeric:tabular-nums;line-height:1}\n.rs-hero-grade{font-size:12px;font-weight:600;color:#637083}\n\n/* \u2500\u2500 \u7EDF\u8BA1\u6761 \u2500\u2500 */\n.rs-stats{display:flex;flex-wrap:wrap;gap:20px;padding:14px 20px;background:#fff;border:1px solid #e4e8f1;border-radius:10px;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}\n.rs-stat{display:flex;align-items:baseline;gap:6px}\n.rs-stat-num{font-size:20px;font-weight:800;font-variant-numeric:tabular-nums;line-height:1}\n.rs-stat-label{font-size:12px;color:#637083}\n.rs-stat--pass .rs-stat-num{color:#1f9d63}\n.rs-stat--warn .rs-stat-num{color:#d97706}\n.rs-stat--fail .rs-stat-num{color:#dc2626}\n.rs-stat--total .rs-stat-num{color:#182033}\n\n/* \u2500\u2500 Panel\uFF08\u5185\u5BB9\u533A\u5757\uFF09 \u2500\u2500 */\n.rs-panel{background:#fff;border:1px solid #e4e8f1;border-radius:12px;box-shadow:0 8px 24px rgba(31,41,55,4%);padding:18px 20px;margin-bottom:16px}\n.rs-panel-title{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:700;color:#182033;margin-bottom:14px}\n.rs-panel-title small{font-size:12px;font-weight:400;color:#9ca3af;margin-left:4px}\n\n/* \u2500\u2500 \u89C4\u5219 / \u7528\u4F8B:\u9762\u677F\u5185\u7684 hairline \u5217\u8868\u9879(\u65E0 tint \u76D2\u5B50,\u72B6\u6001\u9760\u5DE6\u4FA7\u8272\u70B9) \u2500\u2500 */\n.rs-card{border-bottom:1px solid #eef1f6;background:transparent;border-radius:8px;transition:background .12s}\n.rs-card:last-child{border-bottom:none}\ndetails.rs-card:not([open]):hover{background:#f9fafc}\ndetails.rs-card[open]{background:#fafbfd}\n.rs-card-head{display:flex;align-items:center;gap:10px;padding:12px 6px;cursor:pointer;list-style:none}\n.rs-card-head::-webkit-details-marker{display:none}\ndetails.rs-card>.rs-card-head::after{content:'\u203A';margin-left:4px;color:#c0c6d2;font-size:16px;transition:transform .15s;flex-shrink:0}\ndetails.rs-card[open]>.rs-card-head::after{transform:rotate(90deg)}\n.rs-card-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}\n.rs-card-dot--fail{background:#dc2626}\n.rs-card-dot--warn{background:#d97706}\n.rs-card-dot--pass{background:#1f9d63}\n.rs-card-dot--skip{background:#cbd2dd}\n.rs-card-name{flex:1;min-width:0;font-size:14px;font-weight:600;color:#182033;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-card-badges{display:flex;gap:6px;flex-shrink:0}\n.rs-badge{font-size:11px;font-weight:600;padding:1px 8px;border-radius:10px}\n.rs-badge--fail{color:#dc2626;background:rgba(220,38,38,10%)}\n.rs-badge--warn{color:#d97706;background:rgba(217,119,6,10%)}\n.rs-badge--pass{color:#1f9d63;background:rgba(31,157,99,10%)}\n.rs-card-body{padding:0 6px 14px 24px}\n.rs-finding{margin-top:10px;font-size:13.5px;line-height:1.65}\n.rs-finding-desc{color:#374151;word-break:break-word}\n.rs-finding-sug{margin-top:6px;padding:8px 12px;background:rgba(79,70,229,.05);border-radius:6px;color:#4f46e5;font-size:12.5px;line-height:1.6;word-break:break-word}\n\n/* \u2500\u2500 \u6298\u53E0\u901A\u8FC7\u9879 \u2500\u2500 */\n.rs-fold{margin-top:10px}\n.rs-fold>summary{cursor:pointer;list-style:none;font-size:12.5px;color:#637083;padding:6px 0}\n.rs-fold>summary::-webkit-details-marker{display:none}\n.rs-fold>summary:hover{color:#182033}\n.rs-fold[open]>summary{margin-bottom:8px}\n\n/* \u2500\u2500 \u7A7A\u6001 \u2500\u2500 */\n.rs-empty{padding:32px 20px;text-align:center;color:#9ca3af;font-size:13px}\n";
|
|
77
|
+
export declare const REPORT_SHELL_CSS = "\n/* \u2500\u2500 \u9762\u5305\u5C51(\u66FF\u6389\u88F8\u8FD4\u56DE\u94FE\u63A5) \u2500\u2500 */\n.rs-crumb{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:13px;color:#637083}\n.rs-crumb-link{display:inline-flex;align-items:center;gap:6px;color:#637083;text-decoration:none}\n.rs-crumb-link:hover{color:#4f46e5;text-decoration:none}\n.rs-crumb-link svg{color:#9ca3af}\n.rs-crumb-link:hover svg{color:#4f46e5}\n.rs-crumb-sep{color:#c0c6d2}\n.rs-crumb-dim{color:#637083}\n.rs-crumb-cur{color:#182033;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-crumb-spacer{flex:1}\n.rs-crumb-back{display:inline-flex;align-items:center;gap:5px;color:#9ca3af;text-decoration:none;flex-shrink:0}\n.rs-crumb-back:hover{color:#4f46e5;text-decoration:none}\n\n/* \u2500\u2500 skill \u7EF4\u5EA6\u5207\u6362\u5668(doctor/eval/observe \u4E92\u94FE)\u2014 \u5206\u6BB5\u63A7\u4EF6\u98CE \u2500\u2500 */\n.rs-dims{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 16px}\n.rs-dims-seg{display:inline-flex;align-items:stretch;background:#fff;border:1px solid #e4e8f1;border-radius:10px;padding:3px;gap:2px;box-shadow:0 1px 2px rgba(31,41,55,3%)}\n.rs-dim{display:inline-flex;align-items:center;gap:7px;font-size:13px;padding:7px 14px;border-radius:7px;color:#637083;text-decoration:none;white-space:nowrap;transition:background .12s,color .12s}\na.rs-dim:hover{background:#f1f4f9;color:#182033}\n.rs-dim-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}\n.rs-dim-lbl{font-weight:500}\n/* \u5F53\u524D\u7EF4\u5EA6:\u6D45\u586B\u5145 + \u72B6\u6001\u70B9\u5DF2\u8868\u660E\u8EAB\u4EFD,\u6587\u5B57\u52A0\u91CD */\n.rs-dim--active{background:#f1f4f9;color:#182033;cursor:default}\n.rs-dim--active .rs-dim-lbl{font-weight:700}\n.rs-dim--empty{color:#b6bcc8;cursor:default}\n/* \u5168\u90E8\u5386\u53F2\u6309\u94AE */\n.rs-hist-btn{display:inline-flex;align-items:center;gap:6px;font-size:13px;padding:7px 13px;border-radius:9px;border:1px solid #e4e8f1;background:#fff;color:#637083;cursor:pointer;white-space:nowrap;font-family:inherit;transition:border-color .15s,color .15s}\n.rs-hist-btn:hover{border-color:#c7cedb;color:#182033}\n.rs-hist-ct{font-variant-numeric:tabular-nums;font-weight:700;color:#9ca3af;font-size:12px}\n/* \u5168\u90E8\u5386\u53F2\u5F39\u6846 */\n.rs-hist-overlay{display:none;position:fixed;inset:0;background:rgba(24,32,51,.32);z-index:50;align-items:flex-start;justify-content:center;padding:8vh 16px}\n.rs-hist-modal{background:#fff;border-radius:14px;box-shadow:0 24px 60px rgba(31,41,55,.22);width:100%;max-width:520px;max-height:76vh;display:flex;flex-direction:column;overflow:hidden}\n.rs-hist-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #eef1f6;font-size:14px;color:#182033}\n.rs-hist-x{background:transparent;border:none;color:#9ca3af;font-size:16px;cursor:pointer;line-height:1;padding:4px}\n.rs-hist-x:hover{color:#182033}\n.rs-hist-list{overflow-y:auto;padding:6px 10px 12px}\n.rs-hist-group{margin-top:8px}\n.rs-hist-group-h{display:flex;align-items:center;gap:7px;font-size:12px;color:#637083;font-weight:600;padding:8px 8px 6px}\n.rs-hist-group-dot{width:7px;height:7px;border-radius:50%}\n.rs-hist-group-h small{font-weight:500;color:#b6bcc8}\n.rs-hist-row{display:flex;align-items:baseline;gap:14px;padding:8px;border-radius:8px;text-decoration:none;color:#182033;font-size:13px}\n.rs-hist-row:hover{background:#f1f4f9}\n.rs-hist-row--cur{background:#f1f4f9;cursor:default}\n.rs-hist-date{font-variant-numeric:tabular-nums;color:#637083;min-width:88px;flex-shrink:0}\n.rs-hist-score{font-weight:700;font-variant-numeric:tabular-nums;font-family:\"SF Mono\",Menlo,monospace;min-width:72px;flex-shrink:0}\n.rs-hist-score--green{color:#1f9d63}.rs-hist-score--yellow{color:#d97706}.rs-hist-score--red{color:#dc2626}.rs-hist-score--gray{color:#9ca3af}\n.rs-hist-meta{flex:1;min-width:0;color:#9ca3af;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-hist-go{color:#c0c6d2;font-size:13px;flex-shrink:0}\n.rs-hist-row:hover .rs-hist-go{color:#637083}\n.rs-hist-row--cur .rs-hist-go{color:#4f46e5;font-weight:600;font-size:12px}\n\n/* \u2500\u2500 Hero \u2500\u2500 */\n.rs-hero{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:20px 24px;background:#fff;border:1px solid #e4e8f1;border-radius:12px;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}\n@media(max-width:640px){.rs-hero{flex-direction:column;align-items:flex-start}}\n.rs-hero-left{display:flex;flex-direction:column;gap:4px;min-width:0}\n.rs-hero-kind{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#637083}\n.rs-hero-icon{display:inline-flex;align-items:center}\n.rs-hero-name{margin:0;font-size:20px;font-weight:700;color:#182033;letter-spacing:-.2px}\n.rs-hero-meta{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:4px;color:#9ca3af;font-size:12px;font-variant-numeric:tabular-nums}\n.rs-hero-meta span{display:inline-flex;align-items:center;gap:4px}\n.rs-hero-score{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex-shrink:0;line-height:1}\n.rs-hero-num{font-size:40px;font-weight:800;letter-spacing:-1.5px;font-variant-numeric:tabular-nums;line-height:1}\n.rs-hero-grade{font-size:12px;font-weight:600;color:#637083}\n\n/* \u2500\u2500 \u7EDF\u8BA1\u6761 \u2500\u2500 */\n.rs-stats{display:flex;flex-wrap:wrap;gap:20px;padding:14px 20px;background:#fff;border:1px solid #e4e8f1;border-radius:10px;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}\n.rs-stat{display:flex;align-items:baseline;gap:6px}\n.rs-stat-num{font-size:20px;font-weight:800;font-variant-numeric:tabular-nums;line-height:1}\n.rs-stat-label{font-size:12px;color:#637083}\n.rs-stat--pass .rs-stat-num{color:#1f9d63}\n.rs-stat--warn .rs-stat-num{color:#d97706}\n.rs-stat--fail .rs-stat-num{color:#dc2626}\n.rs-stat--total .rs-stat-num{color:#182033}\n\n/* \u2500\u2500 \u63D0\u793A\u6761 \u2500\u2500 */\n.rs-alert{display:flex;flex-direction:column;gap:3px;padding:12px 16px;border:1px solid #f5c26b;border-radius:10px;background:#fff8ed;color:#92400e;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}\n.rs-alert-title{font-size:13px;font-weight:800}\n.rs-alert-body{font-size:12.5px;line-height:1.65}\n\n/* \u2500\u2500 Panel\uFF08\u5185\u5BB9\u533A\u5757\uFF09 \u2500\u2500 */\n.rs-panel{background:#fff;border:1px solid #e4e8f1;border-radius:12px;box-shadow:0 8px 24px rgba(31,41,55,4%);padding:18px 20px;margin-bottom:16px}\n.rs-panel-title{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:700;color:#182033;margin-bottom:14px}\n.rs-panel-title small{font-size:12px;font-weight:400;color:#9ca3af;margin-left:4px}\n\n/* \u2500\u2500 \u89C4\u5219 / \u7528\u4F8B:\u9762\u677F\u5185\u7684 hairline \u5217\u8868\u9879(\u65E0 tint \u76D2\u5B50,\u72B6\u6001\u9760\u5DE6\u4FA7\u8272\u70B9) \u2500\u2500 */\n.rs-card{border-bottom:1px solid #eef1f6;background:transparent;border-radius:8px;transition:background .12s}\n.rs-card:last-child{border-bottom:none}\ndetails.rs-card:not([open]):hover{background:#f9fafc}\ndetails.rs-card[open]{background:#fafbfd}\n.rs-card-head{display:flex;align-items:center;gap:10px;padding:12px 6px;cursor:pointer;list-style:none}\n.rs-card-head::-webkit-details-marker{display:none}\ndetails.rs-card>.rs-card-head::after{content:'\u203A';margin-left:4px;color:#c0c6d2;font-size:16px;transition:transform .15s;flex-shrink:0}\ndetails.rs-card[open]>.rs-card-head::after{transform:rotate(90deg)}\n.rs-card-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}\n.rs-card-dot--fail{background:#dc2626}\n.rs-card-dot--warn{background:#d97706}\n.rs-card-dot--pass{background:#1f9d63}\n.rs-card-dot--skip{background:#cbd2dd}\n.rs-card-name{flex:1;min-width:0;font-size:14px;font-weight:600;color:#182033;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.rs-card-badges{display:flex;gap:6px;flex-shrink:0}\n.rs-badge{font-size:11px;font-weight:600;padding:1px 8px;border-radius:10px}\n.rs-badge--fail{color:#dc2626;background:rgba(220,38,38,10%)}\n.rs-badge--warn{color:#d97706;background:rgba(217,119,6,10%)}\n.rs-badge--pass{color:#1f9d63;background:rgba(31,157,99,10%)}\n.rs-card-body{padding:0 6px 14px 24px}\n.rs-finding{margin-top:10px;font-size:13.5px;line-height:1.65}\n.rs-finding-desc{color:#374151;word-break:break-word}\n.rs-finding-sug{margin-top:6px;padding:8px 12px;background:rgba(79,70,229,.05);border-radius:6px;color:#4f46e5;font-size:12.5px;line-height:1.6;word-break:break-word}\n\n/* \u2500\u2500 \u6298\u53E0\u901A\u8FC7\u9879 \u2500\u2500 */\n.rs-fold{margin-top:10px}\n.rs-fold>summary{cursor:pointer;list-style:none;font-size:12.5px;color:#637083;padding:6px 0}\n.rs-fold>summary::-webkit-details-marker{display:none}\n.rs-fold>summary:hover{color:#182033}\n.rs-fold[open]>summary{margin-bottom:8px}\n\n/* \u2500\u2500 \u7A7A\u6001 \u2500\u2500 */\n.rs-empty{padding:32px 20px;text-align:center;color:#9ca3af;font-size:13px}\n";
|
|
@@ -181,6 +181,11 @@ a.rs-dim:hover{background:#f1f4f9;color:#182033}
|
|
|
181
181
|
.rs-stat--fail .rs-stat-num{color:#dc2626}
|
|
182
182
|
.rs-stat--total .rs-stat-num{color:#182033}
|
|
183
183
|
|
|
184
|
+
/* ── 提示条 ── */
|
|
185
|
+
.rs-alert{display:flex;flex-direction:column;gap:3px;padding:12px 16px;border:1px solid #f5c26b;border-radius:10px;background:#fff8ed;color:#92400e;box-shadow:0 8px 24px rgba(31,41,55,4%);margin-bottom:16px}
|
|
186
|
+
.rs-alert-title{font-size:13px;font-weight:800}
|
|
187
|
+
.rs-alert-body{font-size:12.5px;line-height:1.65}
|
|
188
|
+
|
|
184
189
|
/* ── Panel(内容区块) ── */
|
|
185
190
|
.rs-panel{background:#fff;border:1px solid #e4e8f1;border-radius:12px;box-shadow:0 8px 24px rgba(31,41,55,4%);padding:18px 20px;margin-bottom:16px}
|
|
186
191
|
.rs-panel-title{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:700;color:#182033;margin-bottom:14px}
|