oh-my-knowledge 0.30.0 → 0.32.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 +33 -672
- package/README.zh.md +45 -684
- package/dist/analysis/coverage-analyzer.d.ts.map +1 -0
- package/dist/analysis/coverage-analyzer.js.map +1 -0
- package/dist/analysis/failure-clusterer.d.ts.map +1 -0
- package/dist/analysis/failure-clusterer.js.map +1 -0
- package/dist/analysis/gap-analyzer.d.ts +121 -0
- package/dist/analysis/gap-analyzer.d.ts.map +1 -0
- package/dist/analysis/gap-analyzer.js +471 -0
- package/dist/analysis/gap-analyzer.js.map +1 -0
- package/dist/analysis/hedging-classifier.d.ts.map +1 -0
- package/dist/analysis/hedging-classifier.js.map +1 -0
- package/dist/analysis/report-diagnostics.d.ts +34 -0
- package/dist/analysis/report-diagnostics.d.ts.map +1 -0
- package/dist/analysis/report-diagnostics.js +753 -0
- package/dist/analysis/report-diagnostics.js.map +1 -0
- package/dist/analysis/sample-diagnostics.d.ts.map +1 -0
- package/dist/analysis/sample-diagnostics.js.map +1 -0
- package/dist/analysis/saturation.d.ts.map +1 -0
- package/dist/analysis/saturation.js.map +1 -0
- package/dist/authoring/evolver.d.ts +102 -0
- package/dist/authoring/evolver.d.ts.map +1 -0
- package/dist/authoring/evolver.js +681 -0
- package/dist/authoring/evolver.js.map +1 -0
- package/dist/authoring/generator.d.ts +38 -0
- package/dist/authoring/generator.d.ts.map +1 -0
- package/dist/authoring/generator.js +720 -0
- package/dist/authoring/generator.js.map +1 -0
- package/dist/authoring/sample-fixer.d.ts +51 -0
- package/dist/authoring/sample-fixer.d.ts.map +1 -0
- package/dist/authoring/sample-fixer.js +213 -0
- package/dist/authoring/sample-fixer.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +26 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +302 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/eval/gold/compare.d.ts +17 -0
- package/dist/cli/commands/eval/gold/compare.d.ts.map +1 -0
- package/dist/cli/commands/eval/gold/compare.js +91 -0
- package/dist/cli/commands/eval/gold/compare.js.map +1 -0
- package/dist/cli/commands/eval/gold/index.d.ts +9 -0
- package/dist/cli/commands/eval/gold/index.d.ts.map +1 -0
- package/dist/cli/commands/eval/gold/index.js +34 -0
- package/dist/cli/commands/eval/gold/index.js.map +1 -0
- package/dist/cli/commands/eval/gold/init.d.ts +11 -0
- package/dist/cli/commands/eval/gold/init.d.ts.map +1 -0
- package/dist/cli/commands/eval/gold/init.js +51 -0
- package/dist/cli/commands/eval/gold/init.js.map +1 -0
- package/dist/cli/commands/eval/gold/validate.d.ts +12 -0
- package/dist/cli/commands/eval/gold/validate.d.ts.map +1 -0
- package/dist/cli/commands/eval/gold/validate.js +46 -0
- package/dist/cli/commands/eval/gold/validate.js.map +1 -0
- package/dist/cli/commands/eval/index.d.ts +54 -0
- package/dist/cli/commands/eval/index.d.ts.map +1 -0
- package/dist/cli/commands/eval/index.js +465 -0
- package/dist/cli/commands/eval/index.js.map +1 -0
- package/dist/cli/commands/evolve.d.ts +37 -0
- package/dist/cli/commands/evolve.d.ts.map +1 -0
- package/dist/cli/commands/evolve.js +283 -0
- package/dist/cli/commands/evolve.js.map +1 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +152 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/observe/inbox.d.ts +23 -0
- package/dist/cli/commands/observe/inbox.d.ts.map +1 -0
- package/dist/cli/commands/observe/inbox.js +260 -0
- package/dist/cli/commands/observe/inbox.js.map +1 -0
- package/dist/cli/commands/observe/index.d.ts +22 -0
- package/dist/cli/commands/observe/index.d.ts.map +1 -0
- package/dist/cli/commands/observe/index.js +118 -0
- package/dist/cli/commands/observe/index.js.map +1 -0
- package/dist/cli/commands/observe/ingest.d.ts +13 -0
- package/dist/cli/commands/observe/ingest.d.ts.map +1 -0
- package/dist/cli/commands/observe/ingest.js +71 -0
- package/dist/cli/commands/observe/ingest.js.map +1 -0
- package/dist/cli/commands/observe/show.d.ts +13 -0
- package/dist/cli/commands/observe/show.d.ts.map +1 -0
- package/dist/cli/commands/observe/show.js +49 -0
- package/dist/cli/commands/observe/show.js.map +1 -0
- package/dist/cli/commands/sample.d.ts +38 -0
- package/dist/cli/commands/sample.d.ts.map +1 -0
- package/dist/cli/commands/sample.js +487 -0
- package/dist/cli/commands/sample.js.map +1 -0
- package/dist/cli/commands/studio.d.ts +23 -0
- package/dist/cli/commands/studio.d.ts.map +1 -0
- package/dist/cli/commands/studio.js +158 -0
- package/dist/cli/commands/studio.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lib/cli-exit.d.ts +16 -0
- package/dist/cli/lib/cli-exit.d.ts.map +1 -0
- package/dist/cli/lib/cli-exit.js +20 -0
- package/dist/cli/lib/cli-exit.js.map +1 -0
- package/dist/cli/lib/cmd-flags.d.ts +224 -0
- package/dist/cli/lib/cmd-flags.d.ts.map +1 -0
- package/dist/cli/lib/cmd-flags.js +46 -0
- package/dist/cli/lib/cmd-flags.js.map +1 -0
- package/dist/cli/lib/i18n-dict/common.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/common.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/common.js +67 -0
- package/dist/cli/lib/i18n-dict/common.js.map +1 -0
- package/dist/cli/lib/i18n-dict/evolve.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/evolve.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/evolve.js +43 -0
- package/dist/cli/lib/i18n-dict/evolve.js.map +1 -0
- package/dist/cli/lib/i18n-dict/gen.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/gen.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/gen.js +63 -0
- package/dist/cli/lib/i18n-dict/gen.js.map +1 -0
- package/dist/cli/lib/i18n-dict/help.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/help.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/help.js +281 -0
- package/dist/cli/lib/i18n-dict/help.js.map +1 -0
- package/dist/cli/lib/i18n-dict/init.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/init.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/init.js +27 -0
- package/dist/cli/lib/i18n-dict/init.js.map +1 -0
- package/dist/cli/lib/i18n-dict/run.d.ts +4 -0
- package/dist/cli/lib/i18n-dict/run.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/run.js +143 -0
- package/dist/cli/lib/i18n-dict/run.js.map +1 -0
- package/dist/cli/lib/i18n-dict/types.d.ts +5 -0
- package/dist/cli/lib/i18n-dict/types.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict/types.js +2 -0
- package/dist/cli/lib/i18n-dict/types.js.map +1 -0
- package/dist/cli/lib/i18n-dict.d.ts +63 -0
- package/dist/cli/lib/i18n-dict.d.ts.map +1 -0
- package/dist/cli/lib/i18n-dict.js +67 -0
- package/dist/cli/lib/i18n-dict.js.map +1 -0
- package/dist/cli/lib/i18n.d.ts +29 -0
- package/dist/cli/lib/i18n.d.ts.map +1 -0
- package/dist/cli/lib/i18n.js +58 -0
- package/dist/cli/lib/i18n.js.map +1 -0
- package/dist/cli/lib/parse-run-config/judge-models.d.ts +24 -0
- package/dist/cli/lib/parse-run-config/judge-models.d.ts.map +1 -0
- package/dist/cli/lib/parse-run-config/judge-models.js +55 -0
- package/dist/cli/lib/parse-run-config/judge-models.js.map +1 -0
- package/dist/cli/lib/parse-run-config/samples-discovery.d.ts +19 -0
- package/dist/cli/lib/parse-run-config/samples-discovery.d.ts.map +1 -0
- package/dist/cli/lib/parse-run-config/samples-discovery.js +53 -0
- package/dist/cli/lib/parse-run-config/samples-discovery.js.map +1 -0
- package/dist/cli/lib/parse-run-config/variant-resolution.d.ts +18 -0
- package/dist/cli/lib/parse-run-config/variant-resolution.d.ts.map +1 -0
- package/dist/cli/lib/parse-run-config/variant-resolution.js +59 -0
- package/dist/cli/lib/parse-run-config/variant-resolution.js.map +1 -0
- package/dist/cli/lib/parse-run-config.d.ts +93 -0
- package/dist/cli/lib/parse-run-config.d.ts.map +1 -0
- package/dist/cli/lib/parse-run-config.js +157 -0
- package/dist/cli/lib/parse-run-config.js.map +1 -0
- package/dist/cli/lib/progress.d.ts.map +1 -0
- package/dist/cli/lib/progress.js.map +1 -0
- package/dist/cli/lib/resolve-skill-input.d.ts +8 -0
- package/dist/cli/lib/resolve-skill-input.d.ts.map +1 -0
- package/dist/cli/lib/resolve-skill-input.js +38 -0
- package/dist/cli/lib/resolve-skill-input.js.map +1 -0
- package/dist/cli/lib/run-tally.d.ts +18 -0
- package/dist/cli/lib/run-tally.d.ts.map +1 -0
- package/dist/cli/lib/run-tally.js.map +1 -0
- package/dist/cli/lib/shared.d.ts +12 -0
- package/dist/cli/lib/shared.d.ts.map +1 -0
- package/dist/cli/lib/shared.js +26 -0
- package/dist/cli/lib/shared.js.map +1 -0
- package/dist/cli/lib/update-check.d.ts +9 -0
- package/dist/cli/lib/update-check.d.ts.map +1 -0
- package/dist/cli/lib/update-check.js +113 -0
- package/dist/cli/lib/update-check.js.map +1 -0
- package/dist/cli/oclif/base-command.d.ts +8 -0
- package/dist/cli/oclif/base-command.d.ts.map +1 -0
- package/dist/cli/oclif/base-command.js +27 -0
- package/dist/cli/oclif/base-command.js.map +1 -0
- package/dist/cli/oclif/help.d.ts +16 -0
- package/dist/cli/oclif/help.d.ts.map +1 -0
- package/dist/cli/oclif/help.js +33 -0
- package/dist/cli/oclif/help.js.map +1 -0
- package/dist/cli/oclif/i18n.d.ts +16 -0
- package/dist/cli/oclif/i18n.d.ts.map +1 -0
- package/dist/cli/oclif/i18n.js +62 -0
- package/dist/cli/oclif/i18n.js.map +1 -0
- package/dist/cli/oclif/parsers.d.ts +10 -0
- package/dist/cli/oclif/parsers.d.ts.map +1 -0
- package/dist/cli/oclif/parsers.js +102 -0
- package/dist/cli/oclif/parsers.js.map +1 -0
- package/dist/cli/oclif/projection.d.ts +23 -0
- package/dist/cli/oclif/projection.d.ts.map +1 -0
- package/dist/cli/oclif/projection.js +52 -0
- package/dist/cli/oclif/projection.js.map +1 -0
- package/dist/cli/oclif/run.d.ts +2 -0
- package/dist/cli/oclif/run.d.ts.map +1 -0
- package/dist/cli/oclif/run.js +11 -0
- package/dist/cli/oclif/run.js.map +1 -0
- package/dist/diagnosis/observe-mapper.d.ts +68 -0
- package/dist/diagnosis/observe-mapper.d.ts.map +1 -0
- package/dist/diagnosis/observe-mapper.js +276 -0
- package/dist/diagnosis/observe-mapper.js.map +1 -0
- package/dist/diagnosis/observe-producer.d.ts +9 -0
- package/dist/diagnosis/observe-producer.d.ts.map +1 -0
- package/dist/diagnosis/observe-producer.js +199 -0
- package/dist/diagnosis/observe-producer.js.map +1 -0
- package/dist/diagnosis/studio-projection.d.ts +7 -0
- package/dist/diagnosis/studio-projection.d.ts.map +1 -0
- package/dist/diagnosis/studio-projection.js +84 -0
- package/dist/diagnosis/studio-projection.js.map +1 -0
- package/dist/diagnosis/types.d.ts +4 -0
- package/dist/diagnosis/types.d.ts.map +1 -0
- package/dist/diagnosis/types.js +20 -0
- package/dist/diagnosis/types.js.map +1 -0
- package/dist/doctor/fixer.d.ts +12 -0
- package/dist/doctor/fixer.d.ts.map +1 -0
- package/dist/doctor/fixer.js +326 -0
- package/dist/doctor/fixer.js.map +1 -0
- package/dist/doctor/health/builtin-dimensions.d.ts.map +1 -0
- package/dist/doctor/health/builtin-dimensions.js.map +1 -0
- package/dist/doctor/health/composer.d.ts.map +1 -0
- package/dist/doctor/health/composer.js +296 -0
- package/dist/doctor/health/composer.js.map +1 -0
- package/dist/doctor/health/dimension-registry.d.ts.map +1 -0
- package/dist/doctor/health/dimension-registry.js.map +1 -0
- package/dist/doctor/health/dimension-spec.d.ts +47 -0
- package/dist/doctor/health/dimension-spec.d.ts.map +1 -0
- package/dist/doctor/health/dimension-spec.js.map +1 -0
- package/dist/doctor/health/parser.d.ts +26 -0
- package/dist/doctor/health/parser.d.ts.map +1 -0
- package/dist/doctor/health/parser.js +228 -0
- package/dist/doctor/health/parser.js.map +1 -0
- package/dist/doctor/health/prompt-builder.d.ts +3 -0
- package/dist/doctor/health/prompt-builder.d.ts.map +1 -0
- package/dist/doctor/health/prompt-builder.js +2 -0
- package/dist/doctor/health/prompt-builder.js.map +1 -0
- package/dist/doctor/health/register.d.ts.map +1 -0
- package/dist/doctor/health/register.js.map +1 -0
- package/dist/doctor/index.d.ts.map +1 -0
- package/dist/doctor/index.js +246 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/doctor/messages.d.ts +21 -0
- package/dist/doctor/messages.d.ts.map +1 -0
- package/dist/doctor/messages.js +217 -0
- package/dist/doctor/messages.js.map +1 -0
- package/dist/doctor/preflight.d.ts.map +1 -0
- package/dist/doctor/preflight.js.map +1 -0
- package/dist/doctor/renderer.d.ts +17 -0
- package/dist/doctor/renderer.d.ts.map +1 -0
- package/dist/doctor/renderer.js +122 -0
- package/dist/doctor/renderer.js.map +1 -0
- package/dist/doctor/rules.d.ts.map +1 -0
- package/dist/doctor/rules.js +289 -0
- package/dist/doctor/rules.js.map +1 -0
- package/dist/eval-core/bootstrap.d.ts.map +1 -0
- package/dist/eval-core/bootstrap.js.map +1 -0
- package/dist/eval-core/cache.d.ts.map +1 -0
- package/dist/eval-core/cache.js.map +1 -0
- package/dist/eval-core/comparability.d.ts.map +1 -0
- package/dist/eval-core/comparability.js.map +1 -0
- package/dist/eval-core/dependency-checker.d.ts +37 -0
- package/dist/eval-core/dependency-checker.d.ts.map +1 -0
- package/dist/eval-core/dependency-checker.js.map +1 -0
- package/dist/eval-core/evaluation-execution.d.ts.map +1 -0
- package/dist/eval-core/evaluation-execution.js.map +1 -0
- package/dist/eval-core/evaluation-job.d.ts.map +1 -0
- package/dist/eval-core/evaluation-job.js.map +1 -0
- package/dist/eval-core/evaluation-reporting.d.ts.map +1 -0
- package/dist/eval-core/evaluation-reporting.js.map +1 -0
- package/dist/eval-core/execution-strategy.d.ts.map +1 -0
- package/dist/eval-core/execution-strategy.js +165 -0
- package/dist/eval-core/execution-strategy.js.map +1 -0
- package/dist/eval-core/fact-checker.d.ts.map +1 -0
- package/dist/eval-core/fact-checker.js.map +1 -0
- package/dist/eval-core/layer-gates.d.ts.map +1 -0
- package/dist/eval-core/layer-gates.js.map +1 -0
- package/dist/eval-core/mock-hook.cjs +215 -0
- package/dist/eval-core/mocks-runtime.d.ts +100 -0
- package/dist/eval-core/mocks-runtime.d.ts.map +1 -0
- package/dist/eval-core/mocks-runtime.js +559 -0
- package/dist/eval-core/mocks-runtime.js.map +1 -0
- package/dist/eval-core/schema.d.ts.map +1 -0
- package/dist/eval-core/schema.js.map +1 -0
- package/dist/eval-core/statistics.d.ts.map +1 -0
- package/dist/eval-core/statistics.js.map +1 -0
- package/dist/eval-core/task-planner.d.ts.map +1 -0
- package/dist/eval-core/task-planner.js.map +1 -0
- package/dist/eval-core/verdict.d.ts.map +1 -0
- package/dist/eval-core/verdict.js.map +1 -0
- package/dist/eval-workflows/batch-evaluation-workflow.d.ts.map +1 -0
- package/dist/eval-workflows/batch-evaluation-workflow.js.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.d.ts +22 -0
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.js +67 -0
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.js.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/report-finalize.d.ts +32 -0
- package/dist/eval-workflows/evaluation-pipeline/report-finalize.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/report-finalize.js +57 -0
- package/dist/eval-workflows/evaluation-pipeline/report-finalize.js.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/run-state.d.ts +60 -0
- package/dist/eval-workflows/evaluation-pipeline/run-state.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/run-state.js +88 -0
- package/dist/eval-workflows/evaluation-pipeline/run-state.js.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.d.ts +21 -0
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.js +46 -0
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.js.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline.d.ts +97 -0
- package/dist/eval-workflows/evaluation-pipeline.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-pipeline.js +179 -0
- package/dist/eval-workflows/evaluation-pipeline.js.map +1 -0
- package/dist/eval-workflows/evaluation-preparation.d.ts.map +1 -0
- package/dist/eval-workflows/evaluation-preparation.js.map +1 -0
- package/dist/eval-workflows/messages.d.ts +4 -0
- package/dist/eval-workflows/messages.d.ts.map +1 -0
- package/dist/eval-workflows/messages.js +30 -0
- package/dist/eval-workflows/messages.js.map +1 -0
- package/dist/eval-workflows/run-evaluation.d.ts.map +1 -0
- package/dist/eval-workflows/run-evaluation.js +528 -0
- package/dist/eval-workflows/run-evaluation.js.map +1 -0
- package/dist/executors/anthropic-api.d.ts.map +1 -0
- package/dist/executors/anthropic-api.js.map +1 -0
- package/dist/executors/claude-cli.d.ts.map +1 -0
- package/dist/executors/claude-cli.js +181 -0
- package/dist/executors/claude-cli.js.map +1 -0
- package/dist/executors/claude-sdk-trace.d.ts.map +1 -0
- package/dist/executors/claude-sdk-trace.js.map +1 -0
- package/dist/executors/claude-sdk.d.ts.map +1 -0
- package/dist/executors/claude-sdk.js.map +1 -0
- package/dist/executors/codex-cli-trace.d.ts.map +1 -0
- package/dist/executors/codex-cli-trace.js.map +1 -0
- package/dist/executors/codex-cli.d.ts.map +1 -0
- package/dist/executors/codex-cli.js.map +1 -0
- package/dist/executors/codex-sdk.d.ts.map +1 -0
- package/dist/executors/codex-sdk.js.map +1 -0
- package/dist/executors/gemini.d.ts.map +1 -0
- package/dist/executors/gemini.js.map +1 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/openai-api.d.ts.map +1 -0
- package/dist/executors/openai-api.js.map +1 -0
- package/dist/executors/runtime-fingerprint.d.ts.map +1 -0
- package/dist/executors/runtime-fingerprint.js.map +1 -0
- package/dist/executors/script.d.ts.map +1 -0
- package/dist/executors/script.js.map +1 -0
- package/dist/executors/shared.d.ts +194 -0
- package/dist/executors/shared.d.ts.map +1 -0
- package/dist/executors/shared.js +253 -0
- package/dist/executors/shared.js.map +1 -0
- package/dist/grading/assertions.d.ts.map +1 -0
- package/dist/grading/assertions.js.map +1 -0
- package/dist/grading/debias-validate.d.ts.map +1 -0
- package/dist/grading/debias-validate.js.map +1 -0
- package/dist/grading/diagnostic.d.ts.map +1 -0
- package/dist/grading/diagnostic.js.map +1 -0
- package/dist/grading/gold-cli.d.ts.map +1 -0
- package/dist/grading/gold-cli.js.map +1 -0
- package/dist/grading/gold-dataset.d.ts.map +1 -0
- package/dist/grading/gold-dataset.js.map +1 -0
- package/dist/grading/human-gold.d.ts.map +1 -0
- package/dist/grading/human-gold.js.map +1 -0
- package/dist/grading/index.d.ts.map +1 -0
- package/dist/grading/index.js.map +1 -0
- package/dist/grading/judge.d.ts.map +1 -0
- package/dist/grading/judge.js.map +1 -0
- package/dist/grading/layered-scores.d.ts.map +1 -0
- package/dist/grading/layered-scores.js.map +1 -0
- package/dist/inputs/eval-config.d.ts.map +1 -0
- package/dist/inputs/eval-config.js.map +1 -0
- package/dist/inputs/load-samples.d.ts.map +1 -0
- package/dist/inputs/load-samples.js.map +1 -0
- package/dist/inputs/mcp-resolver.d.ts.map +1 -0
- package/dist/inputs/mcp-resolver.js.map +1 -0
- package/dist/inputs/skill-loader.d.ts.map +1 -0
- package/dist/inputs/skill-loader.js +261 -0
- package/dist/inputs/skill-loader.js.map +1 -0
- package/dist/inputs/url-fetcher.d.ts.map +1 -0
- package/dist/inputs/url-fetcher.js.map +1 -0
- package/dist/observability/experience-frontmatter.d.ts +37 -0
- package/dist/observability/experience-frontmatter.d.ts.map +1 -0
- package/dist/observability/experience-frontmatter.js +100 -0
- package/dist/observability/experience-frontmatter.js.map +1 -0
- package/dist/observability/experience.d.ts +23 -0
- package/dist/observability/experience.d.ts.map +1 -0
- package/dist/observability/experience.js +3438 -0
- package/dist/observability/experience.js.map +1 -0
- package/dist/observability/feedback-matchers.d.ts +37 -0
- package/dist/observability/feedback-matchers.d.ts.map +1 -0
- package/dist/observability/feedback-matchers.js +232 -0
- package/dist/observability/feedback-matchers.js.map +1 -0
- package/dist/observability/feedback-projection.d.ts +21 -0
- package/dist/observability/feedback-projection.d.ts.map +1 -0
- package/dist/observability/feedback-projection.js +20 -0
- package/dist/observability/feedback-projection.js.map +1 -0
- package/dist/observability/inbox-view-model.d.ts +43 -0
- package/dist/observability/inbox-view-model.d.ts.map +1 -0
- package/dist/observability/inbox-view-model.js +180 -0
- package/dist/observability/inbox-view-model.js.map +1 -0
- package/dist/observability/inbox.d.ts +28 -0
- package/dist/observability/inbox.d.ts.map +1 -0
- package/dist/observability/inbox.js +765 -0
- package/dist/observability/inbox.js.map +1 -0
- package/dist/observability/problem-patterns.d.ts +12 -0
- package/dist/observability/problem-patterns.d.ts.map +1 -0
- package/dist/observability/problem-patterns.js +244 -0
- package/dist/observability/problem-patterns.js.map +1 -0
- package/dist/observability/prompts/llm-enhanced-review.prompt.md +224 -0
- package/dist/observability/resolved-review.d.ts +37 -0
- package/dist/observability/resolved-review.d.ts.map +1 -0
- package/dist/observability/resolved-review.js +552 -0
- package/dist/observability/resolved-review.js.map +1 -0
- package/dist/observability/review-state.d.ts +20 -0
- package/dist/observability/review-state.d.ts.map +1 -0
- package/dist/observability/review-state.js +169 -0
- package/dist/observability/review-state.js.map +1 -0
- package/dist/observability/skill-chain-advisories.d.ts +16 -0
- package/dist/observability/skill-chain-advisories.d.ts.map +1 -0
- package/dist/observability/skill-chain-advisories.js +69 -0
- package/dist/observability/skill-chain-advisories.js.map +1 -0
- package/dist/observability/skill-chain.d.ts +7 -0
- package/dist/observability/skill-chain.d.ts.map +1 -0
- package/dist/observability/skill-chain.js +474 -0
- package/dist/observability/skill-chain.js.map +1 -0
- package/dist/observability/skill-health-analyzer.d.ts.map +1 -0
- package/dist/observability/skill-health-analyzer.js.map +1 -0
- package/dist/observability/soft-standards/constants.d.ts +5 -0
- package/dist/observability/soft-standards/constants.d.ts.map +1 -0
- package/dist/observability/soft-standards/constants.js +10 -0
- package/dist/observability/soft-standards/constants.js.map +1 -0
- package/dist/observability/soft-standards/index.d.ts +16 -0
- package/dist/observability/soft-standards/index.d.ts.map +1 -0
- package/dist/observability/soft-standards/index.js +15 -0
- package/dist/observability/soft-standards/index.js.map +1 -0
- package/dist/observability/soft-standards/llm-extractor.d.ts +6 -0
- package/dist/observability/soft-standards/llm-extractor.d.ts.map +1 -0
- package/dist/observability/soft-standards/llm-extractor.js +692 -0
- package/dist/observability/soft-standards/llm-extractor.js.map +1 -0
- package/dist/observability/soft-standards/runtime-evaluator.d.ts +12 -0
- package/dist/observability/soft-standards/runtime-evaluator.d.ts.map +1 -0
- package/dist/observability/soft-standards/runtime-evaluator.js +385 -0
- package/dist/observability/soft-standards/runtime-evaluator.js.map +1 -0
- package/dist/observability/soft-standards/skill-standards-store.d.ts +11 -0
- package/dist/observability/soft-standards/skill-standards-store.d.ts.map +1 -0
- package/dist/observability/soft-standards/skill-standards-store.js +158 -0
- package/dist/observability/soft-standards/skill-standards-store.js.map +1 -0
- package/dist/observability/soft-standards/types.d.ts +212 -0
- package/dist/observability/soft-standards/types.d.ts.map +1 -0
- package/dist/observability/soft-standards/types.js +2 -0
- package/dist/observability/soft-standards/types.js.map +1 -0
- package/dist/observability/text-signals.d.ts +14 -0
- package/dist/observability/text-signals.d.ts.map +1 -0
- package/dist/observability/text-signals.js +116 -0
- package/dist/observability/text-signals.js.map +1 -0
- package/dist/observability/trace-adapter.d.ts.map +1 -0
- package/dist/observability/trace-adapter.js.map +1 -0
- package/dist/observability/trace-attribution.d.ts +56 -0
- package/dist/observability/trace-attribution.d.ts.map +1 -0
- package/dist/observability/trace-attribution.js +200 -0
- package/dist/observability/trace-attribution.js.map +1 -0
- package/dist/observability/trace-segmenter.d.ts +52 -0
- package/dist/observability/trace-segmenter.d.ts.map +1 -0
- package/dist/observability/trace-segmenter.js +322 -0
- package/dist/observability/trace-segmenter.js.map +1 -0
- package/dist/observability/trace-source.d.ts +92 -0
- package/dist/observability/trace-source.d.ts.map +1 -0
- package/dist/observability/trace-source.js +502 -0
- package/dist/observability/trace-source.js.map +1 -0
- package/dist/renderer/html-renderer.d.ts.map +1 -0
- package/dist/renderer/html-renderer.js.map +1 -0
- package/dist/renderer/layout.d.ts.map +1 -0
- package/dist/renderer/layout.js.map +1 -0
- package/dist/renderer/observation-inbox/helpers.d.ts +14 -0
- package/dist/renderer/observation-inbox/helpers.d.ts.map +1 -0
- package/dist/renderer/observation-inbox/helpers.js +75 -0
- package/dist/renderer/observation-inbox/helpers.js.map +1 -0
- package/dist/renderer/observation-inbox/styles.d.ts +2 -0
- package/dist/renderer/observation-inbox/styles.d.ts.map +1 -0
- package/dist/renderer/observation-inbox/styles.js +5184 -0
- package/dist/renderer/observation-inbox/styles.js.map +1 -0
- package/dist/renderer/observation-inbox-renderer.d.ts +5 -0
- package/dist/renderer/observation-inbox-renderer.d.ts.map +1 -0
- package/dist/renderer/observation-inbox-renderer.js +7182 -0
- package/dist/renderer/observation-inbox-renderer.js.map +1 -0
- package/dist/renderer/skill-detail-renderer.d.ts +13 -0
- package/dist/renderer/skill-detail-renderer.d.ts.map +1 -0
- package/dist/renderer/skill-detail-renderer.js +1244 -0
- package/dist/renderer/skill-detail-renderer.js.map +1 -0
- package/dist/renderer/skill-health-renderer.d.ts.map +1 -0
- package/dist/renderer/skill-health-renderer.js.map +1 -0
- package/dist/renderer/skill-list-renderer.d.ts +3 -0
- package/dist/renderer/skill-list-renderer.d.ts.map +1 -0
- package/dist/renderer/skill-list-renderer.js +334 -0
- package/dist/renderer/skill-list-renderer.js.map +1 -0
- package/dist/renderer/summary.d.ts +68 -0
- package/dist/renderer/summary.d.ts.map +1 -0
- package/dist/renderer/summary.js +1896 -0
- package/dist/renderer/summary.js.map +1 -0
- package/dist/renderer/table.d.ts.map +1 -0
- package/dist/renderer/table.js.map +1 -0
- package/dist/renderer/test-view.d.ts.map +1 -0
- package/dist/renderer/test-view.js +905 -0
- package/dist/renderer/test-view.js.map +1 -0
- package/dist/renderer/trends.d.ts.map +1 -0
- package/dist/renderer/trends.js.map +1 -0
- package/dist/server/job-store.d.ts.map +1 -0
- package/dist/server/job-store.js.map +1 -0
- package/dist/server/report-server.d.ts.map +1 -0
- package/dist/server/report-server.js +892 -0
- package/dist/server/report-server.js.map +1 -0
- package/dist/server/report-store.d.ts.map +1 -0
- package/dist/server/report-store.js.map +1 -0
- package/dist/server/skill-index.d.ts +14 -0
- package/dist/server/skill-index.d.ts.map +1 -0
- package/dist/server/skill-index.js +381 -0
- package/dist/server/skill-index.js.map +1 -0
- package/dist/server/skill-insights.d.ts +32 -0
- package/dist/server/skill-insights.d.ts.map +1 -0
- package/dist/server/skill-insights.js +788 -0
- package/dist/server/skill-insights.js.map +1 -0
- package/dist/shared/hard-rules.d.ts +42 -0
- package/dist/shared/hard-rules.d.ts.map +1 -0
- package/dist/shared/hard-rules.js +242 -0
- package/dist/shared/hard-rules.js.map +1 -0
- package/dist/shared/llm-prompts/index.d.ts +14 -0
- package/dist/shared/llm-prompts/index.d.ts.map +1 -0
- package/dist/shared/llm-prompts/index.js +22 -0
- package/dist/shared/llm-prompts/index.js.map +1 -0
- package/dist/shared/llm-prompts/skill-health.d.ts +22 -0
- package/dist/shared/llm-prompts/skill-health.d.ts.map +1 -0
- package/dist/shared/llm-prompts/skill-health.js +170 -0
- package/dist/shared/llm-prompts/skill-health.js.map +1 -0
- package/dist/shared/time.d.ts.map +1 -0
- package/dist/shared/time.js.map +1 -0
- package/dist/shared/tool-search.d.ts.map +1 -0
- package/dist/shared/tool-search.js.map +1 -0
- package/dist/types/dependencies.d.ts +23 -0
- package/dist/types/dependencies.d.ts.map +1 -0
- package/dist/types/dependencies.js +2 -0
- package/dist/types/dependencies.js.map +1 -0
- package/dist/types/diagnosis.d.ts +88 -0
- package/dist/types/diagnosis.d.ts.map +1 -0
- package/dist/types/diagnosis.js +2 -0
- package/dist/types/diagnosis.js.map +1 -0
- package/dist/types/doctor.d.ts +157 -0
- package/dist/types/doctor.d.ts.map +1 -0
- package/dist/types/doctor.js.map +1 -0
- package/dist/types/eval.d.ts +377 -0
- package/dist/types/eval.d.ts.map +1 -0
- package/dist/types/eval.js.map +1 -0
- package/dist/types/executor.d.ts.map +1 -0
- package/dist/types/executor.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/judge.d.ts.map +1 -0
- package/dist/types/judge.js.map +1 -0
- package/dist/types/observability.d.ts +865 -0
- package/dist/types/observability.d.ts.map +1 -0
- package/dist/types/observability.js +14 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/report.d.ts +560 -0
- package/dist/types/report.d.ts.map +1 -0
- package/dist/types/report.js.map +1 -0
- package/dist/types/shared.d.ts.map +1 -0
- package/dist/types/shared.js.map +1 -0
- package/dist/types/skill-index.d.ts +142 -0
- package/dist/types/skill-index.d.ts.map +1 -0
- package/dist/types/skill-index.js +2 -0
- package/dist/types/skill-index.js.map +1 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/util/safe-slice.d.ts +23 -0
- package/dist/util/safe-slice.d.ts.map +1 -0
- package/dist/util/safe-slice.js +33 -0
- package/dist/util/safe-slice.js.map +1 -0
- package/package.json +40 -8
- package/dist/src/analysis/coverage-analyzer.d.ts.map +0 -1
- package/dist/src/analysis/coverage-analyzer.js.map +0 -1
- package/dist/src/analysis/failure-clusterer.d.ts.map +0 -1
- package/dist/src/analysis/failure-clusterer.js.map +0 -1
- package/dist/src/analysis/gap-analyzer.d.ts +0 -121
- package/dist/src/analysis/gap-analyzer.d.ts.map +0 -1
- package/dist/src/analysis/gap-analyzer.js +0 -471
- package/dist/src/analysis/gap-analyzer.js.map +0 -1
- package/dist/src/analysis/hedging-classifier.d.ts.map +0 -1
- package/dist/src/analysis/hedging-classifier.js.map +0 -1
- package/dist/src/analysis/report-diagnostics.d.ts +0 -34
- package/dist/src/analysis/report-diagnostics.d.ts.map +0 -1
- package/dist/src/analysis/report-diagnostics.js +0 -753
- package/dist/src/analysis/report-diagnostics.js.map +0 -1
- package/dist/src/analysis/sample-diagnostics.d.ts.map +0 -1
- package/dist/src/analysis/sample-diagnostics.js.map +0 -1
- package/dist/src/analysis/saturation.d.ts.map +0 -1
- package/dist/src/analysis/saturation.js.map +0 -1
- package/dist/src/authoring/evolver.d.ts +0 -78
- package/dist/src/authoring/evolver.d.ts.map +0 -1
- package/dist/src/authoring/evolver.js +0 -320
- package/dist/src/authoring/evolver.js.map +0 -1
- package/dist/src/authoring/generator.d.ts +0 -35
- package/dist/src/authoring/generator.d.ts.map +0 -1
- package/dist/src/authoring/generator.js +0 -704
- package/dist/src/authoring/generator.js.map +0 -1
- package/dist/src/authoring/sample-fixer.d.ts +0 -45
- package/dist/src/authoring/sample-fixer.d.ts.map +0 -1
- package/dist/src/authoring/sample-fixer.js +0 -186
- package/dist/src/authoring/sample-fixer.js.map +0 -1
- package/dist/src/cli/cli-exit.d.ts +0 -15
- package/dist/src/cli/cli-exit.d.ts.map +0 -1
- package/dist/src/cli/cli-exit.js +0 -19
- package/dist/src/cli/cli-exit.js.map +0 -1
- package/dist/src/cli/commands/_shared.d.ts +0 -12
- package/dist/src/cli/commands/_shared.d.ts.map +0 -1
- package/dist/src/cli/commands/_shared.js +0 -26
- package/dist/src/cli/commands/_shared.js.map +0 -1
- package/dist/src/cli/commands/doctor.d.ts +0 -2
- package/dist/src/cli/commands/doctor.d.ts.map +0 -1
- package/dist/src/cli/commands/doctor.js +0 -174
- package/dist/src/cli/commands/doctor.js.map +0 -1
- package/dist/src/cli/commands/eval-gold.d.ts +0 -2
- package/dist/src/cli/commands/eval-gold.d.ts.map +0 -1
- package/dist/src/cli/commands/eval-gold.js +0 -137
- package/dist/src/cli/commands/eval-gold.js.map +0 -1
- package/dist/src/cli/commands/eval-runner.d.ts +0 -2
- package/dist/src/cli/commands/eval-runner.d.ts.map +0 -1
- package/dist/src/cli/commands/eval-runner.js +0 -299
- package/dist/src/cli/commands/eval-runner.js.map +0 -1
- package/dist/src/cli/commands/eval.d.ts +0 -2
- package/dist/src/cli/commands/eval.d.ts.map +0 -1
- package/dist/src/cli/commands/eval.js +0 -11
- package/dist/src/cli/commands/eval.js.map +0 -1
- package/dist/src/cli/commands/evolve.d.ts +0 -2
- package/dist/src/cli/commands/evolve.d.ts.map +0 -1
- package/dist/src/cli/commands/evolve.js +0 -132
- package/dist/src/cli/commands/evolve.js.map +0 -1
- package/dist/src/cli/commands/init.d.ts +0 -2
- package/dist/src/cli/commands/init.d.ts.map +0 -1
- package/dist/src/cli/commands/init.js +0 -110
- package/dist/src/cli/commands/init.js.map +0 -1
- package/dist/src/cli/commands/observe.d.ts +0 -2
- package/dist/src/cli/commands/observe.d.ts.map +0 -1
- package/dist/src/cli/commands/observe.js +0 -247
- package/dist/src/cli/commands/observe.js.map +0 -1
- package/dist/src/cli/commands/registry.d.ts +0 -11
- package/dist/src/cli/commands/registry.d.ts.map +0 -1
- package/dist/src/cli/commands/registry.js +0 -32
- package/dist/src/cli/commands/registry.js.map +0 -1
- package/dist/src/cli/commands/sample.d.ts +0 -15
- package/dist/src/cli/commands/sample.d.ts.map +0 -1
- package/dist/src/cli/commands/sample.js +0 -415
- package/dist/src/cli/commands/sample.js.map +0 -1
- package/dist/src/cli/commands/studio.d.ts +0 -2
- package/dist/src/cli/commands/studio.d.ts.map +0 -1
- package/dist/src/cli/commands/studio.js +0 -84
- package/dist/src/cli/commands/studio.js.map +0 -1
- package/dist/src/cli/i18n-dict.d.ts +0 -54
- package/dist/src/cli/i18n-dict.d.ts.map +0 -1
- package/dist/src/cli/i18n-dict.js +0 -1125
- package/dist/src/cli/i18n-dict.js.map +0 -1
- package/dist/src/cli/i18n.d.ts +0 -24
- package/dist/src/cli/i18n.d.ts.map +0 -1
- package/dist/src/cli/i18n.js +0 -53
- package/dist/src/cli/i18n.js.map +0 -1
- package/dist/src/cli/index.d.ts.map +0 -1
- package/dist/src/cli/index.js +0 -61
- package/dist/src/cli/index.js.map +0 -1
- package/dist/src/cli/parse-run-config.d.ts +0 -90
- package/dist/src/cli/parse-run-config.d.ts.map +0 -1
- package/dist/src/cli/parse-run-config.js +0 -302
- package/dist/src/cli/parse-run-config.js.map +0 -1
- package/dist/src/cli/parse-strict.d.ts +0 -7
- package/dist/src/cli/parse-strict.d.ts.map +0 -1
- package/dist/src/cli/parse-strict.js +0 -26
- package/dist/src/cli/parse-strict.js.map +0 -1
- package/dist/src/cli/progress.d.ts.map +0 -1
- package/dist/src/cli/progress.js.map +0 -1
- package/dist/src/cli/run-tally.d.ts +0 -18
- package/dist/src/cli/run-tally.d.ts.map +0 -1
- package/dist/src/cli/run-tally.js.map +0 -1
- package/dist/src/cli/update-check.d.ts +0 -3
- package/dist/src/cli/update-check.d.ts.map +0 -1
- package/dist/src/cli/update-check.js +0 -37
- package/dist/src/cli/update-check.js.map +0 -1
- package/dist/src/doctor/health/builtin-dimensions.d.ts.map +0 -1
- package/dist/src/doctor/health/builtin-dimensions.js.map +0 -1
- package/dist/src/doctor/health/composer.d.ts.map +0 -1
- package/dist/src/doctor/health/composer.js +0 -293
- package/dist/src/doctor/health/composer.js.map +0 -1
- package/dist/src/doctor/health/dimension-registry.d.ts.map +0 -1
- package/dist/src/doctor/health/dimension-registry.js.map +0 -1
- package/dist/src/doctor/health/dimension-spec.d.ts +0 -47
- package/dist/src/doctor/health/dimension-spec.d.ts.map +0 -1
- package/dist/src/doctor/health/dimension-spec.js.map +0 -1
- package/dist/src/doctor/health/parser.d.ts +0 -27
- package/dist/src/doctor/health/parser.d.ts.map +0 -1
- package/dist/src/doctor/health/parser.js +0 -191
- package/dist/src/doctor/health/parser.js.map +0 -1
- package/dist/src/doctor/health/prompt-builder.d.ts +0 -22
- package/dist/src/doctor/health/prompt-builder.d.ts.map +0 -1
- package/dist/src/doctor/health/prompt-builder.js +0 -170
- package/dist/src/doctor/health/prompt-builder.js.map +0 -1
- package/dist/src/doctor/health/register.d.ts.map +0 -1
- package/dist/src/doctor/health/register.js.map +0 -1
- package/dist/src/doctor/html-renderer.d.ts +0 -20
- package/dist/src/doctor/html-renderer.d.ts.map +0 -1
- package/dist/src/doctor/html-renderer.js +0 -376
- package/dist/src/doctor/html-renderer.js.map +0 -1
- package/dist/src/doctor/index.d.ts.map +0 -1
- package/dist/src/doctor/index.js +0 -245
- package/dist/src/doctor/index.js.map +0 -1
- package/dist/src/doctor/preflight.d.ts.map +0 -1
- package/dist/src/doctor/preflight.js.map +0 -1
- package/dist/src/doctor/renderer.d.ts +0 -17
- package/dist/src/doctor/renderer.d.ts.map +0 -1
- package/dist/src/doctor/renderer.js +0 -123
- package/dist/src/doctor/renderer.js.map +0 -1
- package/dist/src/doctor/rules.d.ts.map +0 -1
- package/dist/src/doctor/rules.js +0 -289
- package/dist/src/doctor/rules.js.map +0 -1
- package/dist/src/eval-core/bootstrap.d.ts.map +0 -1
- package/dist/src/eval-core/bootstrap.js.map +0 -1
- package/dist/src/eval-core/cache.d.ts.map +0 -1
- package/dist/src/eval-core/cache.js.map +0 -1
- package/dist/src/eval-core/comparability.d.ts.map +0 -1
- package/dist/src/eval-core/comparability.js.map +0 -1
- package/dist/src/eval-core/dependency-checker.d.ts +0 -58
- package/dist/src/eval-core/dependency-checker.d.ts.map +0 -1
- package/dist/src/eval-core/dependency-checker.js.map +0 -1
- package/dist/src/eval-core/evaluation-execution.d.ts.map +0 -1
- package/dist/src/eval-core/evaluation-execution.js.map +0 -1
- package/dist/src/eval-core/evaluation-job.d.ts.map +0 -1
- package/dist/src/eval-core/evaluation-job.js.map +0 -1
- package/dist/src/eval-core/evaluation-reporting.d.ts.map +0 -1
- package/dist/src/eval-core/evaluation-reporting.js.map +0 -1
- package/dist/src/eval-core/execution-strategy.d.ts.map +0 -1
- package/dist/src/eval-core/execution-strategy.js +0 -165
- package/dist/src/eval-core/execution-strategy.js.map +0 -1
- package/dist/src/eval-core/fact-checker.d.ts.map +0 -1
- package/dist/src/eval-core/fact-checker.js.map +0 -1
- package/dist/src/eval-core/layer-gates.d.ts.map +0 -1
- package/dist/src/eval-core/layer-gates.js.map +0 -1
- package/dist/src/eval-core/mock-hook.cjs +0 -203
- package/dist/src/eval-core/mocks-runtime.d.ts +0 -96
- package/dist/src/eval-core/mocks-runtime.d.ts.map +0 -1
- package/dist/src/eval-core/mocks-runtime.js +0 -323
- package/dist/src/eval-core/mocks-runtime.js.map +0 -1
- package/dist/src/eval-core/schema.d.ts.map +0 -1
- package/dist/src/eval-core/schema.js.map +0 -1
- package/dist/src/eval-core/statistics.d.ts.map +0 -1
- package/dist/src/eval-core/statistics.js.map +0 -1
- package/dist/src/eval-core/task-planner.d.ts.map +0 -1
- package/dist/src/eval-core/task-planner.js.map +0 -1
- package/dist/src/eval-core/verdict.d.ts.map +0 -1
- package/dist/src/eval-core/verdict.js.map +0 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts.map +0 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.js.map +0 -1
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts +0 -109
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +0 -1
- package/dist/src/eval-workflows/evaluation-pipeline.js +0 -373
- package/dist/src/eval-workflows/evaluation-pipeline.js.map +0 -1
- package/dist/src/eval-workflows/evaluation-preparation.d.ts.map +0 -1
- package/dist/src/eval-workflows/evaluation-preparation.js.map +0 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts.map +0 -1
- package/dist/src/eval-workflows/run-evaluation.js +0 -528
- package/dist/src/eval-workflows/run-evaluation.js.map +0 -1
- package/dist/src/executors/anthropic-api.d.ts.map +0 -1
- package/dist/src/executors/anthropic-api.js.map +0 -1
- package/dist/src/executors/claude-cli.d.ts.map +0 -1
- package/dist/src/executors/claude-cli.js +0 -179
- package/dist/src/executors/claude-cli.js.map +0 -1
- package/dist/src/executors/claude-sdk-trace.d.ts.map +0 -1
- package/dist/src/executors/claude-sdk-trace.js.map +0 -1
- package/dist/src/executors/claude-sdk.d.ts.map +0 -1
- package/dist/src/executors/claude-sdk.js.map +0 -1
- package/dist/src/executors/codex-cli-trace.d.ts.map +0 -1
- package/dist/src/executors/codex-cli-trace.js.map +0 -1
- package/dist/src/executors/codex-cli.d.ts.map +0 -1
- package/dist/src/executors/codex-cli.js.map +0 -1
- package/dist/src/executors/codex-sdk.d.ts.map +0 -1
- package/dist/src/executors/codex-sdk.js.map +0 -1
- package/dist/src/executors/gemini.d.ts.map +0 -1
- package/dist/src/executors/gemini.js.map +0 -1
- package/dist/src/executors/index.d.ts.map +0 -1
- package/dist/src/executors/index.js.map +0 -1
- package/dist/src/executors/openai-api.d.ts.map +0 -1
- package/dist/src/executors/openai-api.js.map +0 -1
- package/dist/src/executors/runtime-fingerprint.d.ts.map +0 -1
- package/dist/src/executors/runtime-fingerprint.js.map +0 -1
- package/dist/src/executors/script.d.ts.map +0 -1
- package/dist/src/executors/script.js.map +0 -1
- package/dist/src/executors/shared.d.ts +0 -194
- package/dist/src/executors/shared.d.ts.map +0 -1
- package/dist/src/executors/shared.js +0 -256
- package/dist/src/executors/shared.js.map +0 -1
- package/dist/src/grading/assertions.d.ts.map +0 -1
- package/dist/src/grading/assertions.js.map +0 -1
- package/dist/src/grading/debias-validate.d.ts.map +0 -1
- package/dist/src/grading/debias-validate.js.map +0 -1
- package/dist/src/grading/diagnostic.d.ts.map +0 -1
- package/dist/src/grading/diagnostic.js.map +0 -1
- package/dist/src/grading/gold-cli.d.ts.map +0 -1
- package/dist/src/grading/gold-cli.js.map +0 -1
- package/dist/src/grading/gold-dataset.d.ts.map +0 -1
- package/dist/src/grading/gold-dataset.js.map +0 -1
- package/dist/src/grading/human-gold.d.ts.map +0 -1
- package/dist/src/grading/human-gold.js.map +0 -1
- package/dist/src/grading/index.d.ts.map +0 -1
- package/dist/src/grading/index.js.map +0 -1
- package/dist/src/grading/judge.d.ts.map +0 -1
- package/dist/src/grading/judge.js.map +0 -1
- package/dist/src/grading/layered-scores.d.ts.map +0 -1
- package/dist/src/grading/layered-scores.js.map +0 -1
- package/dist/src/inputs/eval-config.d.ts.map +0 -1
- package/dist/src/inputs/eval-config.js.map +0 -1
- package/dist/src/inputs/load-samples.d.ts.map +0 -1
- package/dist/src/inputs/load-samples.js.map +0 -1
- package/dist/src/inputs/mcp-resolver.d.ts.map +0 -1
- package/dist/src/inputs/mcp-resolver.js.map +0 -1
- package/dist/src/inputs/skill-loader.d.ts.map +0 -1
- package/dist/src/inputs/skill-loader.js +0 -253
- package/dist/src/inputs/skill-loader.js.map +0 -1
- package/dist/src/inputs/url-fetcher.d.ts.map +0 -1
- package/dist/src/inputs/url-fetcher.js.map +0 -1
- package/dist/src/observability/experience.d.ts +0 -260
- package/dist/src/observability/experience.d.ts.map +0 -1
- package/dist/src/observability/experience.js +0 -1233
- package/dist/src/observability/experience.js.map +0 -1
- package/dist/src/observability/inbox-view-model.d.ts +0 -27
- package/dist/src/observability/inbox-view-model.d.ts.map +0 -1
- package/dist/src/observability/inbox-view-model.js +0 -135
- package/dist/src/observability/inbox-view-model.js.map +0 -1
- package/dist/src/observability/inbox.d.ts +0 -125
- package/dist/src/observability/inbox.d.ts.map +0 -1
- package/dist/src/observability/inbox.js +0 -741
- package/dist/src/observability/inbox.js.map +0 -1
- package/dist/src/observability/problem-patterns.d.ts +0 -51
- package/dist/src/observability/problem-patterns.d.ts.map +0 -1
- package/dist/src/observability/problem-patterns.js +0 -205
- package/dist/src/observability/problem-patterns.js.map +0 -1
- package/dist/src/observability/review-state.d.ts +0 -54
- package/dist/src/observability/review-state.d.ts.map +0 -1
- package/dist/src/observability/review-state.js +0 -131
- package/dist/src/observability/review-state.js.map +0 -1
- package/dist/src/observability/skill-chain-advisories.d.ts +0 -25
- package/dist/src/observability/skill-chain-advisories.d.ts.map +0 -1
- package/dist/src/observability/skill-chain-advisories.js +0 -69
- package/dist/src/observability/skill-chain-advisories.js.map +0 -1
- package/dist/src/observability/skill-chain.d.ts +0 -61
- package/dist/src/observability/skill-chain.d.ts.map +0 -1
- package/dist/src/observability/skill-chain.js +0 -233
- package/dist/src/observability/skill-chain.js.map +0 -1
- package/dist/src/observability/skill-health-analyzer.d.ts.map +0 -1
- package/dist/src/observability/skill-health-analyzer.js.map +0 -1
- package/dist/src/observability/text-signals.d.ts +0 -7
- package/dist/src/observability/text-signals.d.ts.map +0 -1
- package/dist/src/observability/text-signals.js +0 -22
- package/dist/src/observability/text-signals.js.map +0 -1
- package/dist/src/observability/trace-adapter.d.ts.map +0 -1
- package/dist/src/observability/trace-adapter.js.map +0 -1
- package/dist/src/observability/trace-attribution.d.ts +0 -56
- package/dist/src/observability/trace-attribution.d.ts.map +0 -1
- package/dist/src/observability/trace-attribution.js +0 -200
- package/dist/src/observability/trace-attribution.js.map +0 -1
- package/dist/src/observability/trace-segmenter.d.ts +0 -52
- package/dist/src/observability/trace-segmenter.d.ts.map +0 -1
- package/dist/src/observability/trace-segmenter.js +0 -320
- package/dist/src/observability/trace-segmenter.js.map +0 -1
- package/dist/src/observability/trace-source.d.ts +0 -99
- package/dist/src/observability/trace-source.d.ts.map +0 -1
- package/dist/src/observability/trace-source.js +0 -492
- package/dist/src/observability/trace-source.js.map +0 -1
- package/dist/src/renderer/html-renderer.d.ts.map +0 -1
- package/dist/src/renderer/html-renderer.js.map +0 -1
- package/dist/src/renderer/layout.d.ts.map +0 -1
- package/dist/src/renderer/layout.js.map +0 -1
- package/dist/src/renderer/observation-inbox-renderer.d.ts +0 -4
- package/dist/src/renderer/observation-inbox-renderer.d.ts.map +0 -1
- package/dist/src/renderer/observation-inbox-renderer.js +0 -5376
- package/dist/src/renderer/observation-inbox-renderer.js.map +0 -1
- package/dist/src/renderer/skill-detail-renderer.d.ts +0 -15
- package/dist/src/renderer/skill-detail-renderer.d.ts.map +0 -1
- package/dist/src/renderer/skill-detail-renderer.js +0 -1234
- package/dist/src/renderer/skill-detail-renderer.js.map +0 -1
- package/dist/src/renderer/skill-health-renderer.d.ts.map +0 -1
- package/dist/src/renderer/skill-health-renderer.js.map +0 -1
- package/dist/src/renderer/skill-list-renderer.d.ts +0 -4
- package/dist/src/renderer/skill-list-renderer.d.ts.map +0 -1
- package/dist/src/renderer/skill-list-renderer.js +0 -327
- package/dist/src/renderer/skill-list-renderer.js.map +0 -1
- package/dist/src/renderer/summary.d.ts +0 -68
- package/dist/src/renderer/summary.d.ts.map +0 -1
- package/dist/src/renderer/summary.js +0 -1896
- package/dist/src/renderer/summary.js.map +0 -1
- package/dist/src/renderer/table.d.ts.map +0 -1
- package/dist/src/renderer/table.js.map +0 -1
- package/dist/src/renderer/test-view.d.ts.map +0 -1
- package/dist/src/renderer/test-view.js +0 -905
- package/dist/src/renderer/test-view.js.map +0 -1
- package/dist/src/renderer/trends.d.ts.map +0 -1
- package/dist/src/renderer/trends.js.map +0 -1
- package/dist/src/server/job-store.d.ts.map +0 -1
- package/dist/src/server/job-store.js.map +0 -1
- package/dist/src/server/report-server.d.ts.map +0 -1
- package/dist/src/server/report-server.js +0 -801
- package/dist/src/server/report-server.js.map +0 -1
- package/dist/src/server/report-store.d.ts.map +0 -1
- package/dist/src/server/report-store.js.map +0 -1
- package/dist/src/server/skill-index.d.ts +0 -77
- package/dist/src/server/skill-index.d.ts.map +0 -1
- package/dist/src/server/skill-index.js +0 -331
- package/dist/src/server/skill-index.js.map +0 -1
- package/dist/src/server/skill-insights.d.ts +0 -92
- package/dist/src/server/skill-insights.d.ts.map +0 -1
- package/dist/src/server/skill-insights.js +0 -676
- package/dist/src/server/skill-insights.js.map +0 -1
- package/dist/src/shared/hard-rules.d.ts +0 -40
- package/dist/src/shared/hard-rules.d.ts.map +0 -1
- package/dist/src/shared/hard-rules.js +0 -200
- package/dist/src/shared/hard-rules.js.map +0 -1
- package/dist/src/shared/time.d.ts.map +0 -1
- package/dist/src/shared/time.js.map +0 -1
- package/dist/src/shared/tool-search.d.ts.map +0 -1
- package/dist/src/shared/tool-search.js.map +0 -1
- package/dist/src/types/doctor.d.ts +0 -155
- package/dist/src/types/doctor.d.ts.map +0 -1
- package/dist/src/types/doctor.js.map +0 -1
- package/dist/src/types/eval.d.ts +0 -372
- package/dist/src/types/eval.d.ts.map +0 -1
- package/dist/src/types/eval.js.map +0 -1
- package/dist/src/types/executor.d.ts.map +0 -1
- package/dist/src/types/executor.js.map +0 -1
- package/dist/src/types/index.d.ts +0 -8
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/index.js +0 -8
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/types/judge.d.ts.map +0 -1
- package/dist/src/types/judge.js.map +0 -1
- package/dist/src/types/report.d.ts +0 -551
- package/dist/src/types/report.d.ts.map +0 -1
- package/dist/src/types/report.js.map +0 -1
- package/dist/src/types/shared.d.ts.map +0 -1
- package/dist/src/types/shared.js.map +0 -1
- package/dist/src/types/storage.d.ts.map +0 -1
- package/dist/src/types/storage.js.map +0 -1
- package/dist/src/util/safe-slice.d.ts +0 -23
- package/dist/src/util/safe-slice.d.ts.map +0 -1
- package/dist/src/util/safe-slice.js +0 -33
- package/dist/src/util/safe-slice.js.map +0 -1
- /package/dist/{src/analysis → analysis}/coverage-analyzer.d.ts +0 -0
- /package/dist/{src/analysis → analysis}/coverage-analyzer.js +0 -0
- /package/dist/{src/analysis → analysis}/failure-clusterer.d.ts +0 -0
- /package/dist/{src/analysis → analysis}/failure-clusterer.js +0 -0
- /package/dist/{src/analysis → analysis}/hedging-classifier.d.ts +0 -0
- /package/dist/{src/analysis → analysis}/hedging-classifier.js +0 -0
- /package/dist/{src/analysis → analysis}/sample-diagnostics.d.ts +0 -0
- /package/dist/{src/analysis → analysis}/sample-diagnostics.js +0 -0
- /package/dist/{src/analysis → analysis}/saturation.d.ts +0 -0
- /package/dist/{src/analysis → analysis}/saturation.js +0 -0
- /package/dist/{src/cli → cli}/index.d.ts +0 -0
- /package/dist/{src/cli → cli/lib}/progress.d.ts +0 -0
- /package/dist/{src/cli → cli/lib}/progress.js +0 -0
- /package/dist/{src/cli → cli/lib}/run-tally.js +0 -0
- /package/dist/{src/doctor → doctor}/health/builtin-dimensions.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/health/builtin-dimensions.js +0 -0
- /package/dist/{src/doctor → doctor}/health/composer.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/health/dimension-registry.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/health/dimension-registry.js +0 -0
- /package/dist/{src/doctor → doctor}/health/dimension-spec.js +0 -0
- /package/dist/{src/doctor → doctor}/health/register.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/health/register.js +0 -0
- /package/dist/{src/doctor → doctor}/index.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/preflight.d.ts +0 -0
- /package/dist/{src/doctor → doctor}/preflight.js +0 -0
- /package/dist/{src/doctor → doctor}/rules.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/bootstrap.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/bootstrap.js +0 -0
- /package/dist/{src/eval-core → eval-core}/cache.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/cache.js +0 -0
- /package/dist/{src/eval-core → eval-core}/comparability.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/comparability.js +0 -0
- /package/dist/{src/eval-core → eval-core}/dependency-checker.js +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-execution.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-execution.js +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-job.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-job.js +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-reporting.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/evaluation-reporting.js +0 -0
- /package/dist/{src/eval-core → eval-core}/execution-strategy.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/fact-checker.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/fact-checker.js +0 -0
- /package/dist/{src/eval-core → eval-core}/layer-gates.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/layer-gates.js +0 -0
- /package/dist/{src/eval-core → eval-core}/schema.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/schema.js +0 -0
- /package/dist/{src/eval-core → eval-core}/statistics.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/statistics.js +0 -0
- /package/dist/{src/eval-core → eval-core}/task-planner.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/task-planner.js +0 -0
- /package/dist/{src/eval-core → eval-core}/verdict.d.ts +0 -0
- /package/dist/{src/eval-core → eval-core}/verdict.js +0 -0
- /package/dist/{src/eval-workflows → eval-workflows}/batch-evaluation-workflow.d.ts +0 -0
- /package/dist/{src/eval-workflows → eval-workflows}/batch-evaluation-workflow.js +0 -0
- /package/dist/{src/eval-workflows → eval-workflows}/evaluation-preparation.d.ts +0 -0
- /package/dist/{src/eval-workflows → eval-workflows}/evaluation-preparation.js +0 -0
- /package/dist/{src/eval-workflows → eval-workflows}/run-evaluation.d.ts +0 -0
- /package/dist/{src/executors → executors}/anthropic-api.d.ts +0 -0
- /package/dist/{src/executors → executors}/anthropic-api.js +0 -0
- /package/dist/{src/executors → executors}/claude-cli.d.ts +0 -0
- /package/dist/{src/executors → executors}/claude-sdk-trace.d.ts +0 -0
- /package/dist/{src/executors → executors}/claude-sdk-trace.js +0 -0
- /package/dist/{src/executors → executors}/claude-sdk.d.ts +0 -0
- /package/dist/{src/executors → executors}/claude-sdk.js +0 -0
- /package/dist/{src/executors → executors}/codex-cli-trace.d.ts +0 -0
- /package/dist/{src/executors → executors}/codex-cli-trace.js +0 -0
- /package/dist/{src/executors → executors}/codex-cli.d.ts +0 -0
- /package/dist/{src/executors → executors}/codex-cli.js +0 -0
- /package/dist/{src/executors → executors}/codex-sdk.d.ts +0 -0
- /package/dist/{src/executors → executors}/codex-sdk.js +0 -0
- /package/dist/{src/executors → executors}/gemini.d.ts +0 -0
- /package/dist/{src/executors → executors}/gemini.js +0 -0
- /package/dist/{src/executors → executors}/index.d.ts +0 -0
- /package/dist/{src/executors → executors}/index.js +0 -0
- /package/dist/{src/executors → executors}/openai-api.d.ts +0 -0
- /package/dist/{src/executors → executors}/openai-api.js +0 -0
- /package/dist/{src/executors → executors}/runtime-fingerprint.d.ts +0 -0
- /package/dist/{src/executors → executors}/runtime-fingerprint.js +0 -0
- /package/dist/{src/executors → executors}/script.d.ts +0 -0
- /package/dist/{src/executors → executors}/script.js +0 -0
- /package/dist/{src/grading → grading}/assertions.d.ts +0 -0
- /package/dist/{src/grading → grading}/assertions.js +0 -0
- /package/dist/{src/grading → grading}/debias-validate.d.ts +0 -0
- /package/dist/{src/grading → grading}/debias-validate.js +0 -0
- /package/dist/{src/grading → grading}/diagnostic.d.ts +0 -0
- /package/dist/{src/grading → grading}/diagnostic.js +0 -0
- /package/dist/{src/grading → grading}/gold-cli.d.ts +0 -0
- /package/dist/{src/grading → grading}/gold-cli.js +0 -0
- /package/dist/{src/grading → grading}/gold-dataset.d.ts +0 -0
- /package/dist/{src/grading → grading}/gold-dataset.js +0 -0
- /package/dist/{src/grading → grading}/human-gold.d.ts +0 -0
- /package/dist/{src/grading → grading}/human-gold.js +0 -0
- /package/dist/{src/grading → grading}/index.d.ts +0 -0
- /package/dist/{src/grading → grading}/index.js +0 -0
- /package/dist/{src/grading → grading}/judge.d.ts +0 -0
- /package/dist/{src/grading → grading}/judge.js +0 -0
- /package/dist/{src/grading → grading}/layered-scores.d.ts +0 -0
- /package/dist/{src/grading → grading}/layered-scores.js +0 -0
- /package/dist/{src/inputs → inputs}/eval-config.d.ts +0 -0
- /package/dist/{src/inputs → inputs}/eval-config.js +0 -0
- /package/dist/{src/inputs → inputs}/load-samples.d.ts +0 -0
- /package/dist/{src/inputs → inputs}/load-samples.js +0 -0
- /package/dist/{src/inputs → inputs}/mcp-resolver.d.ts +0 -0
- /package/dist/{src/inputs → inputs}/mcp-resolver.js +0 -0
- /package/dist/{src/inputs → inputs}/skill-loader.d.ts +0 -0
- /package/dist/{src/inputs → inputs}/url-fetcher.d.ts +0 -0
- /package/dist/{src/inputs → inputs}/url-fetcher.js +0 -0
- /package/dist/{src/observability → observability}/skill-health-analyzer.d.ts +0 -0
- /package/dist/{src/observability → observability}/skill-health-analyzer.js +0 -0
- /package/dist/{src/observability → observability}/trace-adapter.d.ts +0 -0
- /package/dist/{src/observability → observability}/trace-adapter.js +0 -0
- /package/dist/{src/renderer → renderer}/html-renderer.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/html-renderer.js +0 -0
- /package/dist/{src/renderer → renderer}/layout.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/layout.js +0 -0
- /package/dist/{src/renderer → renderer}/skill-health-renderer.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/skill-health-renderer.js +0 -0
- /package/dist/{src/renderer → renderer}/table.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/table.js +0 -0
- /package/dist/{src/renderer → renderer}/test-view.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/trends.d.ts +0 -0
- /package/dist/{src/renderer → renderer}/trends.js +0 -0
- /package/dist/{src/server → server}/job-store.d.ts +0 -0
- /package/dist/{src/server → server}/job-store.js +0 -0
- /package/dist/{src/server → server}/report-server.d.ts +0 -0
- /package/dist/{src/server → server}/report-store.d.ts +0 -0
- /package/dist/{src/server → server}/report-store.js +0 -0
- /package/dist/{src/shared → shared}/time.d.ts +0 -0
- /package/dist/{src/shared → shared}/time.js +0 -0
- /package/dist/{src/shared → shared}/tool-search.d.ts +0 -0
- /package/dist/{src/shared → shared}/tool-search.js +0 -0
- /package/dist/{src/types → types}/doctor.js +0 -0
- /package/dist/{src/types → types}/eval.js +0 -0
- /package/dist/{src/types → types}/executor.d.ts +0 -0
- /package/dist/{src/types → types}/executor.js +0 -0
- /package/dist/{src/types → types}/judge.d.ts +0 -0
- /package/dist/{src/types → types}/judge.js +0 -0
- /package/dist/{src/types → types}/report.js +0 -0
- /package/dist/{src/types → types}/shared.d.ts +0 -0
- /package/dist/{src/types → types}/shared.js +0 -0
- /package/dist/{src/types → types}/storage.d.ts +0 -0
- /package/dist/{src/types → types}/storage.js +0 -0
|
@@ -0,0 +1,1244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill 详情页 — 问题优先,扁平 1-2 屏。
|
|
3
|
+
*
|
|
4
|
+
* ┌─ skill 名 + band + 健康摘要一句话 ──────────────┐
|
|
5
|
+
* │ 关键问题(按受众分组,默认全展开)│ 健康趋势(chart.js 折线)│
|
|
6
|
+
* │ #1 [高 / Skill] 标题 … │ ─── 三条线 ────────── │
|
|
7
|
+
* │ #2 [高 / Skill] 标题 … │ 🩺 Doctor 7✓ 1⚠ │
|
|
8
|
+
* │ #3 [中 / 用例] 标题 … │ 🧪 Eval 80% │
|
|
9
|
+
* │ 单条点击 → modal │ 👁 Observe 稳定 │
|
|
10
|
+
* │ │ 阶段卡点击 → modal │
|
|
11
|
+
* └────────────────────────────────────────────────────────┘
|
|
12
|
+
* 隐藏 modal:每条 insight 一个 + 3 个阶段全量明细各一个
|
|
13
|
+
*/
|
|
14
|
+
import { layout, e, DEFAULT_LANG } from './layout.js';
|
|
15
|
+
const BAND_DOT = {
|
|
16
|
+
green: '🟢', yellow: '🟡', red: '🔴', gray: '⚪',
|
|
17
|
+
};
|
|
18
|
+
// v6 之前的 insight × audience × 三视角 抽象在 v7 详情页砍掉了,只保留 sample 维度
|
|
19
|
+
// (renderEvalSection 直接读 evalReport.results,不再走 detectInsights / audience 分组)。
|
|
20
|
+
// 相关常量(SEVERITY_ICON / AUDIENCE_INFO_* / PATCH_TARGET_*)等以后做调试 UI
|
|
21
|
+
// 需要时再恢复。
|
|
22
|
+
function relTime(ts, lang) {
|
|
23
|
+
if (!ts)
|
|
24
|
+
return lang === 'zh' ? '未跑' : 'never';
|
|
25
|
+
try {
|
|
26
|
+
const past = new Date(ts).getTime();
|
|
27
|
+
const diff = Math.max(0, Date.now() - past);
|
|
28
|
+
const mins = Math.floor(diff / 60000);
|
|
29
|
+
if (mins < 60)
|
|
30
|
+
return lang === 'zh' ? `${mins} 分钟前` : `${mins}m ago`;
|
|
31
|
+
const hours = Math.floor(mins / 60);
|
|
32
|
+
if (hours < 24)
|
|
33
|
+
return lang === 'zh' ? `${hours} 小时前` : `${hours}h ago`;
|
|
34
|
+
return lang === 'zh' ? `${Math.floor(hours / 24)} 天前` : `${Math.floor(hours / 24)}d ago`;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function fmtDateShort(ts) {
|
|
41
|
+
if (!ts)
|
|
42
|
+
return '';
|
|
43
|
+
try {
|
|
44
|
+
const d = new Date(ts);
|
|
45
|
+
return `${String(d.getMonth() + 1).padStart(2, '0')}/${String(d.getDate()).padStart(2, '0')}`;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function assessHealth(entry, insights, lang) {
|
|
52
|
+
const ran = [entry.doctor, entry.eval, entry.observe].filter(Boolean).length;
|
|
53
|
+
// 三大维度都没跑过时,如果 Diagnosis 已经给出 high/medium 信号(例如只跑了 `omk observe ingest`
|
|
54
|
+
// 拿到 `skill_md_not_found`),仍然要把卡片标红/黄,而不是落到灰色「未评估」。
|
|
55
|
+
// 否则 Diagnosis 作为 Studio 数据源的价值会被 UI 口径吞掉:红色筛选筛不到,
|
|
56
|
+
// 用户看不到「这个 skill 有待优化项,但卡片仍灰」的矛盾态。
|
|
57
|
+
const highCount = insights.filter((i) => i.severity === 'high').length;
|
|
58
|
+
const medCount = insights.filter((i) => i.severity === 'medium').length;
|
|
59
|
+
if (ran === 0) {
|
|
60
|
+
if (highCount > 0) {
|
|
61
|
+
return { grade: 'unhealthy', score: null, label: lang === 'zh' ? '不健康' : 'Unhealthy', emoji: '🔴', color: 'red' };
|
|
62
|
+
}
|
|
63
|
+
if (medCount > 0) {
|
|
64
|
+
return { grade: 'fair', score: null, label: lang === 'zh' ? '待改进' : 'Fair', emoji: '🟡', color: 'yellow' };
|
|
65
|
+
}
|
|
66
|
+
return { grade: 'unscored', score: null, label: lang === 'zh' ? '未评估' : 'Unscored', emoji: '⚪', color: 'gray' };
|
|
67
|
+
}
|
|
68
|
+
let doctorPct = null;
|
|
69
|
+
if (entry.doctor) {
|
|
70
|
+
const total = entry.doctor.passCount + entry.doctor.warnCount + entry.doctor.failCount;
|
|
71
|
+
doctorPct = total > 0
|
|
72
|
+
? ((entry.doctor.passCount + entry.doctor.warnCount * 0.5) / total) * 100
|
|
73
|
+
: 100;
|
|
74
|
+
}
|
|
75
|
+
let evalPct = null;
|
|
76
|
+
if (entry.eval) {
|
|
77
|
+
if (entry.eval.compositeScore != null) {
|
|
78
|
+
evalPct = (entry.eval.compositeScore / 5) * 100;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const total = entry.eval.passCount + entry.eval.failCount;
|
|
82
|
+
if (total > 0)
|
|
83
|
+
evalPct = (entry.eval.passCount / total) * 100;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
let observePct = null;
|
|
87
|
+
if (entry.observe) {
|
|
88
|
+
const coverage = (1 - entry.observe.gapRate) * 100;
|
|
89
|
+
const bandMul = entry.observe.healthBand === 'red' ? 0.6 : entry.observe.healthBand === 'yellow' ? 0.85 : 1;
|
|
90
|
+
observePct = coverage * bandMul;
|
|
91
|
+
}
|
|
92
|
+
const dims = [doctorPct, evalPct, observePct].filter((x) => x != null);
|
|
93
|
+
const score = dims.length > 0 ? Math.round(dims.reduce((s, x) => s + x, 0) / dims.length) : null;
|
|
94
|
+
const hasFail = (entry.doctor != null && entry.doctor.failCount > 0)
|
|
95
|
+
|| (entry.eval != null && entry.eval.failCount > 0)
|
|
96
|
+
|| (entry.observe != null && entry.observe.healthBand === 'red');
|
|
97
|
+
const hasWarn = (entry.doctor != null && entry.doctor.warnCount > 0)
|
|
98
|
+
|| (entry.eval != null && entry.eval.compositeScore != null && entry.eval.compositeScore < 3.5)
|
|
99
|
+
|| (entry.observe != null && entry.observe.healthBand === 'yellow');
|
|
100
|
+
if (highCount > 0 || hasFail) {
|
|
101
|
+
return { grade: 'unhealthy', score, label: lang === 'zh' ? '不健康' : 'Unhealthy', emoji: '🔴', color: 'red' };
|
|
102
|
+
}
|
|
103
|
+
if (medCount > 0 || hasWarn) {
|
|
104
|
+
return { grade: 'fair', score, label: lang === 'zh' ? '待改进' : 'Fair', emoji: '🟡', color: 'yellow' };
|
|
105
|
+
}
|
|
106
|
+
if (insights.length === 0 && !hasWarn) {
|
|
107
|
+
return { grade: 'excellent', score, label: lang === 'zh' ? '健康' : 'Excellent', emoji: '🟢', color: 'green' };
|
|
108
|
+
}
|
|
109
|
+
return { grade: 'good', score, label: lang === 'zh' ? '良好' : 'Good', emoji: '🟢', color: 'green' };
|
|
110
|
+
}
|
|
111
|
+
// ────────── Hero:健康等级 + 名称 + 摘要 ──────────
|
|
112
|
+
function renderHero(entry, insights, lastTs, reportCount, lang) {
|
|
113
|
+
const h = assessHealth(entry, insights, lang);
|
|
114
|
+
const scoreTip = lang === 'zh'
|
|
115
|
+
? '参考分:doctor 通过率、eval 综合分、observe 稳定度归一到 0-100 后取平均(warn/告警按 0.5 折算)。同一 skill 跨时间可比;不同 skill 之间因 sample 难度不同不严格可比'
|
|
116
|
+
: 'Reference score: average of doctor pass-rate, eval composite, and observe stability normalized to 0-100. Comparable within a skill over time; not strictly comparable across skills (sample difficulty differs)';
|
|
117
|
+
const scoreBlock = h.score != null
|
|
118
|
+
? `<span class="si-hero-score" title="${e(scoreTip)}"><span class="si-hero-score-num">${h.score}</span><span class="si-hero-score-unit">/100</span></span>`
|
|
119
|
+
: `<span class="si-hero-score si-hero-score--empty" title="${e(scoreTip)}">—</span>`;
|
|
120
|
+
return `<div class="si-hero">
|
|
121
|
+
<div class="si-hero-grade si-hero-grade--${h.color}">
|
|
122
|
+
<span class="si-hero-grade-emoji">${h.emoji}</span>
|
|
123
|
+
<span class="si-hero-grade-label">${e(h.label)}</span>
|
|
124
|
+
${scoreBlock}
|
|
125
|
+
</div>
|
|
126
|
+
<div class="si-hero-info">
|
|
127
|
+
<div class="si-hero-name">${e(entry.skillName)}</div>
|
|
128
|
+
<div class="si-hero-summary">${renderHealthSummary(entry, insights, lang)}</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="si-hero-meta">${reportCount}/3 · ${relTime(lastTs, lang)}</div>
|
|
131
|
+
</div>`;
|
|
132
|
+
}
|
|
133
|
+
function renderHealthSummary(entry, insights, lang) {
|
|
134
|
+
const issues = [];
|
|
135
|
+
if (entry.doctor) {
|
|
136
|
+
if (entry.doctor.failCount > 0)
|
|
137
|
+
issues.push(lang === 'zh' ? `doctor ${entry.doctor.failCount} 项不通过` : `doctor ${entry.doctor.failCount} fail`);
|
|
138
|
+
else if (entry.doctor.warnCount > 0)
|
|
139
|
+
issues.push(lang === 'zh' ? `doctor ${entry.doctor.warnCount} 项告警` : `doctor ${entry.doctor.warnCount} warn`);
|
|
140
|
+
}
|
|
141
|
+
if (entry.eval) {
|
|
142
|
+
const total = entry.eval.passCount + entry.eval.failCount;
|
|
143
|
+
if (total > 0) {
|
|
144
|
+
const pct = Math.round((entry.eval.passCount / total) * 100);
|
|
145
|
+
if (entry.eval.failCount > 0)
|
|
146
|
+
issues.push(lang === 'zh' ? `eval 通过率 ${pct}%(${entry.eval.failCount} 条挂)` : `eval ${pct}% pass (${entry.eval.failCount} fail)`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (entry.observe && entry.observe.healthBand !== 'green') {
|
|
150
|
+
issues.push(lang === 'zh' ? `observe ${BAND_DOT[entry.observe.healthBand]}` : `observe ${BAND_DOT[entry.observe.healthBand]}`);
|
|
151
|
+
}
|
|
152
|
+
const high = insights.filter((i) => i.severity === 'high').length;
|
|
153
|
+
const med = insights.filter((i) => i.severity === 'medium').length;
|
|
154
|
+
if (high > 0 || med > 0) {
|
|
155
|
+
const parts = [];
|
|
156
|
+
if (high > 0)
|
|
157
|
+
parts.push(lang === 'zh' ? `${high} 个高优` : `${high} high`);
|
|
158
|
+
if (med > 0)
|
|
159
|
+
parts.push(lang === 'zh' ? `${med} 个中优` : `${med} medium`);
|
|
160
|
+
issues.push(lang === 'zh' ? `检出 ${insights.length} 个待优化(${parts.join(',')})` : `${insights.length} issue(s) (${parts.join(', ')})`);
|
|
161
|
+
}
|
|
162
|
+
if (issues.length === 0) {
|
|
163
|
+
const ran = [entry.doctor, entry.eval, entry.observe].filter(Boolean).length;
|
|
164
|
+
if (ran === 0)
|
|
165
|
+
return lang === 'zh' ? '尚未运行任何检查' : 'No checks run yet';
|
|
166
|
+
return lang === 'zh' ? '✅ 三视角全绿,无告警' : '✅ All three views green';
|
|
167
|
+
}
|
|
168
|
+
return issues.join(lang === 'zh' ? ',' : ', ');
|
|
169
|
+
}
|
|
170
|
+
function buildTrendData(entry) {
|
|
171
|
+
const dateMap = new Map();
|
|
172
|
+
const dateOf = (ts) => ts.slice(0, 10);
|
|
173
|
+
const get = (date) => {
|
|
174
|
+
if (!dateMap.has(date)) {
|
|
175
|
+
dateMap.set(date, { x: date, doctorPct: null, evalPct: null, observePct: null, doctorReportId: null, evalReportId: null, observeAnalysisId: null });
|
|
176
|
+
}
|
|
177
|
+
return dateMap.get(date);
|
|
178
|
+
};
|
|
179
|
+
for (const h of entry.doctorHistory) {
|
|
180
|
+
const total = h.passCount + h.warnCount + h.failCount;
|
|
181
|
+
const d = get(dateOf(h.timestamp));
|
|
182
|
+
d.doctorPct = total > 0 ? (h.passCount / total) * 100 : null;
|
|
183
|
+
d.doctorReportId = h.reportId;
|
|
184
|
+
}
|
|
185
|
+
for (const h of entry.evalHistory) {
|
|
186
|
+
const c = h.compositeScore;
|
|
187
|
+
const d = get(dateOf(h.timestamp));
|
|
188
|
+
d.evalPct = c != null ? (c / 5) * 100 : null;
|
|
189
|
+
d.evalReportId = h.reportId;
|
|
190
|
+
}
|
|
191
|
+
for (const h of entry.observeHistory) {
|
|
192
|
+
const d = get(dateOf(h.generatedAt));
|
|
193
|
+
d.observePct = (1 - h.gapRate) * 100;
|
|
194
|
+
d.observeAnalysisId = h.analysisId;
|
|
195
|
+
}
|
|
196
|
+
return Array.from(dateMap.values()).sort((a, b) => a.x.localeCompare(b.x));
|
|
197
|
+
}
|
|
198
|
+
function renderTrendChart(entry, langQ, lang) {
|
|
199
|
+
const data = buildTrendData(entry);
|
|
200
|
+
const labelDoctor = lang === 'zh' ? '🩺 健康度' : '🩺 Structure';
|
|
201
|
+
const labelEval = lang === 'zh' ? '🧪 评测结果' : '🧪 Test score';
|
|
202
|
+
const labelObserve = lang === 'zh' ? '👁 线上观测' : '👁 Live stability';
|
|
203
|
+
if (data.length < 2) {
|
|
204
|
+
return `<div class="si-trend-empty">${lang === 'zh' ? '📈 还没有足够的历史数据画趋势(至少 2 个时间点)' : '📈 Need at least 2 data points for trend'}</div>`;
|
|
205
|
+
}
|
|
206
|
+
const linksDoctor = data.map(() => null);
|
|
207
|
+
const linksEval = data.map((d) => d.evalReportId ? `/reports/${d.evalReportId}${langQ}` : null);
|
|
208
|
+
const linksObserve = data.map((d) => d.observeAnalysisId ? `/analyses/${d.observeAnalysisId}${langQ}` : null);
|
|
209
|
+
const explainDoctor = lang === 'zh' ? 'omk doctor 通过率' : 'omk doctor pass-rate';
|
|
210
|
+
const explainEval = lang === 'zh' ? 'omk eval 综合分(归一)' : 'omk eval composite (normalized)';
|
|
211
|
+
const explainObserve = lang === 'zh' ? 'omk observe 真实使用稳定度' : 'omk observe production stability';
|
|
212
|
+
const json = JSON.stringify({
|
|
213
|
+
labels: data.map((d) => fmtDateShort(d.x)),
|
|
214
|
+
datasets: [
|
|
215
|
+
{ label: labelDoctor, data: data.map((d) => d.doctorPct), borderColor: '#5e8252', backgroundColor: 'rgba(94,130,82,.1)', tension: 0.3, spanGaps: true, _hint: explainDoctor },
|
|
216
|
+
{ label: labelEval, data: data.map((d) => d.evalPct), borderColor: '#5a7a93', backgroundColor: 'rgba(90,122,147,.1)', tension: 0.3, spanGaps: true, _hint: explainEval },
|
|
217
|
+
{ label: labelObserve, data: data.map((d) => d.observePct), borderColor: '#b08030', backgroundColor: 'rgba(176,128,48,.1)', tension: 0.3, spanGaps: true, _hint: explainObserve },
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
const links = JSON.stringify([linksDoctor, linksEval, linksObserve]);
|
|
221
|
+
return `<div class="si-trend-canvas-wrap">
|
|
222
|
+
<canvas id="trend-chart" data-chart='${json.replace(/'/g, ''')}' data-links='${links.replace(/'/g, ''')}'></canvas>
|
|
223
|
+
</div>`;
|
|
224
|
+
}
|
|
225
|
+
/** 给一个 insight,从 stageRefs.evalSampleIds + evalReport 拿完整的失败样本详情。
|
|
226
|
+
* illustration 是 detector 挑出的(最多 2 条)代表性样本,带 prompt/output/工具调用;
|
|
227
|
+
* diagnostic.expected / actual 是诊断 LLM 写的"期望 vs 实际"对照,用户最想看的。 */
|
|
228
|
+
function renderSampleBody(s, lang) {
|
|
229
|
+
const block = (icon, label, text, cls = '') => {
|
|
230
|
+
if (!text || !text.trim())
|
|
231
|
+
return '';
|
|
232
|
+
return `<div class="si-sb-block si-sb-block--${cls}">
|
|
233
|
+
<div class="si-sb-label">${icon} ${e(label)}</div>
|
|
234
|
+
<div class="si-sb-text">${e(text)}</div>
|
|
235
|
+
</div>`;
|
|
236
|
+
};
|
|
237
|
+
// 拼 suggestion:skill / sample 两段都可能空,只显示有的。
|
|
238
|
+
// diagnostic LLM 偶尔会输出截断的垃圾(如单字"在"),用最小长度 8 字符过滤。
|
|
239
|
+
const isMeaningful = (text) => text.trim().length >= 8;
|
|
240
|
+
const sugParts = [];
|
|
241
|
+
if (isMeaningful(s.suggestionSkill)) {
|
|
242
|
+
sugParts.push(`<div class="si-sb-sugrow"><span class="si-sb-sugtag">改 SKILL.md</span><span>${e(s.suggestionSkill)}</span></div>`);
|
|
243
|
+
}
|
|
244
|
+
if (isMeaningful(s.suggestionSample)) {
|
|
245
|
+
sugParts.push(`<div class="si-sb-sugrow"><span class="si-sb-sugtag">改 sample</span><span>${e(s.suggestionSample)}</span></div>`);
|
|
246
|
+
}
|
|
247
|
+
const suggestionBlock = sugParts.length > 0
|
|
248
|
+
? `<div class="si-sb-block si-sb-block--suggest">
|
|
249
|
+
<div class="si-sb-label">💡 ${lang === 'zh' ? '建议(针对这条样本)' : 'Suggestion (per-sample)'}</div>
|
|
250
|
+
<div class="si-sb-text">${sugParts.join('')}</div>
|
|
251
|
+
</div>`
|
|
252
|
+
: `<div class="si-sb-block si-sb-block--suggest si-sb-block--empty">
|
|
253
|
+
<div class="si-sb-label">💡 ${lang === 'zh' ? '建议(针对这条样本)' : 'Suggestion (per-sample)'}</div>
|
|
254
|
+
<div class="si-sb-text si-sb-empty">${lang === 'zh' ? '诊断 LLM 没给出针对这条样本的建议(可能输出截断或样本本身是诱错样本,无需改动)' : 'Diagnostic LLM did not return a per-sample suggestion'}</div>
|
|
255
|
+
</div>`;
|
|
256
|
+
return `<div class="si-sb">
|
|
257
|
+
${block('📝', lang === 'zh' ? '用例 prompt' : 'Prompt', s.prompt, 'prompt')}
|
|
258
|
+
${block('🎯', lang === 'zh' ? '期望' : 'Expected', s.expected, 'expected')}
|
|
259
|
+
${block('⚠️', lang === 'zh' ? '实际' : 'Actual', s.actual, 'actual')}
|
|
260
|
+
${suggestionBlock}
|
|
261
|
+
</div>`;
|
|
262
|
+
}
|
|
263
|
+
/** 失败用例 section v6:默认全折叠,每条 summary 完整展示一行;
|
|
264
|
+
* 点开看 prompt / 期望 / 实际 / per-sample 建议 */
|
|
265
|
+
// ────────── CSS ──────────
|
|
266
|
+
const SKILL_DETAIL_CSS = `
|
|
267
|
+
.si-back { display:inline-block;margin-bottom:8px;color:var(--text-muted);font-size:13px;text-decoration:none }
|
|
268
|
+
.si-back:hover { color:var(--text-primary) }
|
|
269
|
+
|
|
270
|
+
/* Hero — grade 卡 + 信息块,grid 布局让 grade 卡固定宽度 */
|
|
271
|
+
.si-hero { display:grid;grid-template-columns:auto 1fr auto;gap:18px;align-items:center;padding:14px 18px;background:var(--bg-surface);border-radius:8px;box-shadow:var(--shadow-sm);margin:8px 0 14px }
|
|
272
|
+
@media(max-width:640px){ .si-hero { grid-template-columns:auto 1fr;gap:12px } .si-hero-meta { grid-column:1/-1;text-align:right } }
|
|
273
|
+
|
|
274
|
+
/* 健康等级卡 — 左侧色卡,emoji + 等级 + 参考分纵向堆叠 */
|
|
275
|
+
.si-hero-grade { display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-width:96px;padding:10px 14px;border-radius:8px;background:var(--bg-soft);border-left:4px solid var(--border) }
|
|
276
|
+
.si-hero-grade--green { border-left-color:#5e8252;background:rgba(94,130,82,.08) }
|
|
277
|
+
.si-hero-grade--yellow { border-left-color:#b08030;background:rgba(176,128,48,.08) }
|
|
278
|
+
.si-hero-grade--red { border-left-color:#9c4a3f;background:rgba(156,74,63,.08) }
|
|
279
|
+
.si-hero-grade--gray { border-left-color:var(--border);background:var(--bg-soft) }
|
|
280
|
+
.si-hero-grade-emoji { font-size:20px;line-height:1 }
|
|
281
|
+
.si-hero-grade-label { font-size:13px;font-weight:600;color:var(--text-primary);letter-spacing:0.02em }
|
|
282
|
+
.si-hero-score { font-variant-numeric:tabular-nums;cursor:help;display:flex;align-items:baseline;gap:1px;margin-top:1px }
|
|
283
|
+
.si-hero-score-num { font-size:22px;font-weight:700;line-height:1 }
|
|
284
|
+
.si-hero-grade--green .si-hero-score-num { color:#5e8252 }
|
|
285
|
+
.si-hero-grade--yellow .si-hero-score-num { color:#b08030 }
|
|
286
|
+
.si-hero-grade--red .si-hero-score-num { color:#9c4a3f }
|
|
287
|
+
.si-hero-grade--gray .si-hero-score-num { color:var(--text-muted) }
|
|
288
|
+
.si-hero-score-unit { font-size:11px;color:var(--text-muted);font-weight:500 }
|
|
289
|
+
.si-hero-score--empty { font-size:18px;color:var(--text-muted) }
|
|
290
|
+
|
|
291
|
+
.si-hero-info { display:flex;flex-direction:column;gap:4px;min-width:0 }
|
|
292
|
+
.si-hero-name { font-size:20px;font-weight:600;color:var(--text-primary);line-height:1.3 }
|
|
293
|
+
.si-hero-summary { color:var(--text-secondary);font-size:13px;line-height:1.5 }
|
|
294
|
+
.si-hero-meta { color:var(--text-muted);font-size:12px;font-variant-numeric:tabular-nums;align-self:center }
|
|
295
|
+
|
|
296
|
+
/* 主网格:左 6/12 右 6/12,移动端单列 */
|
|
297
|
+
.si-grid { display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start }
|
|
298
|
+
@media(max-width:880px){ .si-grid { grid-template-columns:1fr } }
|
|
299
|
+
|
|
300
|
+
/* 左栏:问题列表 */
|
|
301
|
+
.si-list { background:var(--bg-surface);border-radius:8px;padding:12px 14px;box-shadow:var(--shadow-sm) }
|
|
302
|
+
|
|
303
|
+
/* 空态 — 不喊"恭喜",用已有数据证明它健康 + 给可补充的下一步,有视觉重量 */
|
|
304
|
+
.si-empty { display:flex;flex-direction:column;gap:14px;padding:6px 4px }
|
|
305
|
+
.si-empty-h { display:flex;align-items:center;gap:10px;padding:10px 14px;background:rgba(94,130,82,.08);border-left:3px solid #5e8252;border-radius:6px }
|
|
306
|
+
.si-empty-emoji { font-size:22px;line-height:1 }
|
|
307
|
+
.si-empty-title { font-size:14px;font-weight:600;color:var(--text-primary) }
|
|
308
|
+
.si-empty-section-h { font-size:11.5px;font-weight:600;color:var(--text-muted);letter-spacing:0.04em;margin-bottom:6px;text-transform:uppercase }
|
|
309
|
+
.si-empty-list { margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:6px }
|
|
310
|
+
.si-empty-list li { display:grid;grid-template-columns:18px 1fr;gap:8px;align-items:start;font-size:13px;line-height:1.55;color:var(--text-primary) }
|
|
311
|
+
.si-empty-list code { background:var(--bg-soft);padding:1px 6px;border-radius:3px;font-family:"SF Mono",Menlo,monospace;font-size:11.5px;color:var(--text-primary) }
|
|
312
|
+
.si-empty-icon { font-weight:700;text-align:center }
|
|
313
|
+
.si-empty-list--pass .si-empty-icon { color:#5e8252 }
|
|
314
|
+
.si-empty-list--next .si-empty-icon { color:var(--accent) }
|
|
315
|
+
.si-aud { margin-bottom:12px }
|
|
316
|
+
.si-aud:last-child { margin-bottom:0 }
|
|
317
|
+
.si-aud-h { display:flex;align-items:center;gap:8px;padding:6px 8px;background:var(--bg-soft);border-radius:5px;margin-bottom:6px }
|
|
318
|
+
.si-aud-icon { font-size:14px }
|
|
319
|
+
.si-aud-title { font-size:13px;font-weight:600;color:var(--text-primary) }
|
|
320
|
+
.si-aud-count { padding:1px 7px;border-radius:9px;background:var(--bg-surface);font-size:11px;color:var(--text-secondary);font-weight:600 }
|
|
321
|
+
.si-aud-sub { color:var(--text-muted);font-size:11px;margin-left:auto }
|
|
322
|
+
.si-aud-rows { display:flex;flex-direction:column;gap:3px }
|
|
323
|
+
|
|
324
|
+
.si-row { all:unset;cursor:pointer;display:grid;grid-template-columns:auto auto 1fr auto auto;gap:8px;align-items:center;padding:8px 10px;border-radius:5px;border:1px solid transparent;transition:border-color .12s,background .12s;text-align:left }
|
|
325
|
+
.si-row:hover { border-color:var(--border-hover);background:var(--bg-soft) }
|
|
326
|
+
.si-row:focus-visible { outline:2px solid var(--accent);outline-offset:1px }
|
|
327
|
+
.si-row-num { font-size:11px;font-weight:700;color:var(--text-muted);font-variant-numeric:tabular-nums;background:var(--bg-soft);padding:1px 6px;border-radius:3px;min-width:28px;text-align:center }
|
|
328
|
+
.si-row-sev { font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:8px;letter-spacing:0.02em }
|
|
329
|
+
.si-row-sev--high { background:rgba(156,74,63,.16);color:#9c4a3f }
|
|
330
|
+
.si-row-sev--medium { background:rgba(176,128,48,.14);color:#b08030 }
|
|
331
|
+
.si-row-sev--low { background:rgba(94,130,82,.16);color:#5e8252 }
|
|
332
|
+
.si-row-title { font-size:13.5px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
|
|
333
|
+
.si-row-meta { font-size:11px;color:var(--text-muted);font-variant-numeric:tabular-nums }
|
|
334
|
+
.si-row-arrow { color:var(--text-muted);font-size:14px;font-weight:300 }
|
|
335
|
+
.si-row--high { border-left:3px solid #9c4a3f;padding-left:7px }
|
|
336
|
+
|
|
337
|
+
/* 右栏 */
|
|
338
|
+
.si-right { display:flex;flex-direction:column;gap:12px }
|
|
339
|
+
.si-trend { background:var(--bg-surface);border-radius:8px;padding:14px 16px;box-shadow:var(--shadow-sm) }
|
|
340
|
+
.si-trend-h { display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:8px }
|
|
341
|
+
.si-trend-empty { padding:24px;text-align:center;color:var(--text-muted);font-size:13px;display:flex;align-items:center;justify-content:center;min-height:200px }
|
|
342
|
+
/* chart.js responsive 要求父容器有确定的高度,否则 canvas 会无限拉高(每次 resize 让父元素变大,触发新 resize)。
|
|
343
|
+
用 position:relative + 固定 height,让 canvas 在内部以 absolute 填充。 */
|
|
344
|
+
.si-trend-canvas-wrap { position:relative;width:100%;height:200px }
|
|
345
|
+
.si-trend-canvas-wrap > canvas { position:absolute;left:0;top:0;width:100% !important;height:100% !important }
|
|
346
|
+
.si-trend-hint { font-size:10.5px;color:var(--text-muted);text-align:center;margin-top:6px;font-style:italic }
|
|
347
|
+
.si-trend-fallback { position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;background:var(--bg-soft);border-radius:6px;padding:14px;text-align:center }
|
|
348
|
+
.si-trend-fallback-icon { font-size:24px;line-height:1 }
|
|
349
|
+
.si-trend-fallback-msg { font-size:13px;font-weight:600;color:#9c4a3f }
|
|
350
|
+
.si-trend-fallback-hint { font-size:11px;color:var(--text-muted);max-width:80% }
|
|
351
|
+
|
|
352
|
+
/* 三视角当前状态区:跟趋势图区域并列,加标题让用户一眼知道这是"当前快照速览" */
|
|
353
|
+
.si-stages-block { background:var(--bg-surface);border-radius:8px;padding:12px 14px;box-shadow:var(--shadow-sm) }
|
|
354
|
+
.si-stages-h { display:flex;flex-direction:column;gap:1px;margin-bottom:10px }
|
|
355
|
+
.si-stages-title { font-size:13px;font-weight:600;color:var(--text-primary) }
|
|
356
|
+
.si-stages-sub { font-size:11px;color:var(--text-muted);font-style:italic }
|
|
357
|
+
.si-stagecards { display:flex;flex-direction:column;gap:8px }
|
|
358
|
+
.si-stages-block .si-stagecard { box-shadow:none;background:var(--bg-soft) }
|
|
359
|
+
.si-stages-block .si-stagecard:hover { box-shadow:var(--shadow-sm) }
|
|
360
|
+
.si-stagecard { all:unset;cursor:pointer;display:grid;grid-template-columns:32px 1fr auto auto;gap:10px;align-items:center;padding:10px 14px;background:var(--bg-surface);border-radius:7px;box-shadow:var(--shadow-sm);transition:transform .12s,box-shadow .12s;border-left:4px solid var(--border) }
|
|
361
|
+
.si-stagecard:hover { transform:translateX(2px);box-shadow:var(--shadow-md) }
|
|
362
|
+
.si-stagecard:focus-visible { outline:2px solid var(--accent);outline-offset:1px }
|
|
363
|
+
.si-stagecard--green { border-left-color:#5e8252 }
|
|
364
|
+
.si-stagecard--yellow { border-left-color:#b08030 }
|
|
365
|
+
.si-stagecard--red { border-left-color:#9c4a3f }
|
|
366
|
+
.si-stagecard--gray { border-left-color:var(--border) }
|
|
367
|
+
.si-stagecard-icon { font-size:22px;line-height:1 }
|
|
368
|
+
.si-stagecard-body { display:flex;flex-direction:column;gap:2px }
|
|
369
|
+
.si-stagecard-name { font-size:14px;font-weight:600;color:var(--text-primary) }
|
|
370
|
+
.si-stagecard-status { font-size:12px;color:var(--text-secondary);font-variant-numeric:tabular-nums }
|
|
371
|
+
.si-stagecard-meta { font-size:11px;color:var(--text-muted);font-variant-numeric:tabular-nums }
|
|
372
|
+
.si-stagecard-arrow { color:var(--text-muted);font-size:16px;font-weight:300 }
|
|
373
|
+
|
|
374
|
+
/* ── Insight modal v4:极简 — 只展示问题 + 解决 ──────────
|
|
375
|
+
* 顺序:title + desc(问题) → 失败用例(具体哪些用例 + 错因) → 怎么改(建议 + patch)
|
|
376
|
+
* 删:严重度 tag / audience tag / 影响数 / 主推动作卡 / 三视角折叠
|
|
377
|
+
* 第一条 recommendation 加 ⭐ 推荐标记
|
|
378
|
+
*/
|
|
379
|
+
|
|
380
|
+
/* 失败用例 section(sample 视角主信息)*/
|
|
381
|
+
.si-failures { margin:14px 0;padding:12px 14px;background:var(--bg-soft);border-radius:6px }
|
|
382
|
+
.si-failures-h { font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:10px }
|
|
383
|
+
.si-failure-item { background:rgba(156,74,63,.04);border-radius:5px;margin-bottom:8px;border-left:3px solid #9c4a3f }
|
|
384
|
+
.si-failure-item:last-child { margin-bottom:0 }
|
|
385
|
+
/* 两行布局:第一行 id + tags + 右对齐 trace;第二行 summary 独占 */
|
|
386
|
+
.si-failure-head { display:flex;flex-direction:column;gap:6px;padding:10px 12px;cursor:default }
|
|
387
|
+
details.si-failure-item > summary.si-failure-head { cursor:pointer;list-style:none;user-select:none }
|
|
388
|
+
details.si-failure-item > summary.si-failure-head::-webkit-details-marker { display:none }
|
|
389
|
+
.si-failure-row1 { display:flex;align-items:center;gap:8px;flex-wrap:wrap }
|
|
390
|
+
.si-failure-row1::before { content:'▸ ';color:var(--text-muted);font-size:11px;margin-right:-4px }
|
|
391
|
+
details.si-failure-item[open] > summary > .si-failure-row1::before { content:'▾ ' }
|
|
392
|
+
.si-failure-row2 { font-size:14px;color:var(--text-secondary);line-height:1.55;padding-left:16px;white-space:pre-wrap;word-break:break-word }
|
|
393
|
+
.si-failure-spacer { flex:1 }
|
|
394
|
+
.si-failure-id { font-size:12.5px;font-weight:600;color:#9c4a3f;background:var(--bg-soft);padding:2px 8px;border-radius:3px;font-family:"SF Mono",Menlo,monospace }
|
|
395
|
+
.si-failure-modes { display:flex;gap:4px;flex-wrap:wrap }
|
|
396
|
+
.si-failure-mode { font-size:12px;color:#b08030;background:rgba(176,128,48,.14);padding:2px 8px;border-radius:8px;font-weight:500;white-space:nowrap }
|
|
397
|
+
.si-failure-trace { font-size:12px;color:var(--accent);text-decoration:none;font-weight:500;white-space:nowrap }
|
|
398
|
+
.si-failure-trace:hover { text-decoration:underline }
|
|
399
|
+
|
|
400
|
+
/* 通过 / 诱错 sample 紧凑行 */
|
|
401
|
+
.si-pass-item { display:flex;gap:10px;align-items:center;padding:5px 8px;border-radius:4px;font-size:14px;line-height:1.5 }
|
|
402
|
+
.si-pass-item:hover { background:var(--bg-soft) }
|
|
403
|
+
.si-pass-card { background:var(--bg-surface);border-radius:5px;margin-bottom:6px;border-left:3px solid #5e8252 }
|
|
404
|
+
.si-pass-card > summary { list-style:none;cursor:pointer;user-select:none }
|
|
405
|
+
.si-pass-card > summary::-webkit-details-marker { display:none }
|
|
406
|
+
.si-pass-head { display:flex;flex-direction:column;gap:4px;padding:8px 12px }
|
|
407
|
+
.si-pass-row1 { display:flex;align-items:center;gap:8px;flex-wrap:wrap }
|
|
408
|
+
.si-pass-row1::before { content:'▸ ';color:var(--text-muted);font-size:11px;margin-right:-4px }
|
|
409
|
+
details.si-pass-card[open] > summary > .si-pass-row1::before { content:'▾ ' }
|
|
410
|
+
.si-pass-id { font-size:12px;font-weight:600;color:#5e8252;background:var(--bg-soft);padding:2px 8px;border-radius:3px;font-family:"SF Mono",Menlo,monospace;flex-shrink:0 }
|
|
411
|
+
.si-pass-score { font-size:12px;font-weight:600;color:#5e8252;background:rgba(94,130,82,.1);padding:1px 7px;border-radius:10px }
|
|
412
|
+
.si-pass-prompt-preview { font-size:13px;color:var(--text-secondary);padding-left:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
|
|
413
|
+
.si-pass-body { padding:0 12px 10px 28px;display:flex;flex-direction:column;gap:8px }
|
|
414
|
+
.si-pass-section { }
|
|
415
|
+
.si-pass-label { font-size:12px;font-weight:600;color:var(--text-muted);margin-bottom:4px }
|
|
416
|
+
.si-pass-content { font-size:14px;color:var(--text-primary);line-height:1.6;white-space:pre-wrap;word-break:break-word;background:var(--bg-soft);padding:8px 12px;border-radius:4px }
|
|
417
|
+
.si-sample-dot { font-size:10px;line-height:1;flex-shrink:0 }
|
|
418
|
+
.se-scores { margin-bottom:12px;padding:12px 14px;background:var(--bg-soft);border-radius:8px }
|
|
419
|
+
.se-scores-hero { display:flex;align-items:baseline;gap:8px;margin-bottom:10px }
|
|
420
|
+
.se-hero-label { font-size:14px;font-weight:600;color:var(--text-primary) }
|
|
421
|
+
.se-hero-val { font-size:28px;font-weight:700;color:var(--text-primary);line-height:1 }
|
|
422
|
+
.se-hero-max { font-size:14px;font-weight:400;color:var(--text-muted) }
|
|
423
|
+
.se-hero-link { font-size:12px;color:var(--accent);text-decoration:none;font-weight:500;margin-left:auto }
|
|
424
|
+
.se-hero-link:hover { text-decoration:underline }
|
|
425
|
+
.se-scores-grid { display:grid;grid-template-columns:repeat(3,1fr);gap:8px }
|
|
426
|
+
@media(max-width:600px) { .se-scores-grid { grid-template-columns:repeat(2,1fr) } }
|
|
427
|
+
.se-score-card { padding:8px 10px;background:var(--bg-surface);border-radius:6px }
|
|
428
|
+
.se-score-label { font-size:12px;color:var(--text-muted);margin-bottom:4px }
|
|
429
|
+
.se-score-bar { height:4px;background:var(--border);border-radius:2px;overflow:hidden;margin-bottom:4px }
|
|
430
|
+
.se-score-fill { height:100%;border-radius:2px }
|
|
431
|
+
.se-score-fill--good { background:#5e8252 }
|
|
432
|
+
.se-score-fill--mid { background:#b08030 }
|
|
433
|
+
.se-score-fill--low { background:#9c4a3f }
|
|
434
|
+
.se-score-val { font-size:16px;font-weight:600;color:var(--text-primary) }
|
|
435
|
+
.se-score-max { font-size:12px;font-weight:400;color:var(--text-muted) }
|
|
436
|
+
.si-pass-preview { flex:1;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0 }
|
|
437
|
+
.si-failure-trace:hover { text-decoration:underline }
|
|
438
|
+
.si-failure-detail { padding:0 12px 10px;border-top:1px solid var(--border) }
|
|
439
|
+
.si-failure-detail .si-illustration { border-left:none;background:transparent;padding:8px 0 0 0 }
|
|
440
|
+
.si-failure-no-detail { padding:6px 0;font-size:13px;color:var(--text-muted);font-style:italic }
|
|
441
|
+
|
|
442
|
+
/* v7:顶部全景区 — 左 3 个 donut ring + 右趋势图,两栏同高 */
|
|
443
|
+
.si-overview { display:grid;grid-template-columns:3fr 2fr;gap:18px;margin:10px 0 22px;align-items:stretch }
|
|
444
|
+
@media(max-width:880px){ .si-overview { grid-template-columns:1fr } }
|
|
445
|
+
.si-overview-cards { background:var(--bg-surface);border-radius:10px;padding:18px 14px;box-shadow:var(--shadow-sm);display:flex;align-items:center;justify-content:space-around;gap:8px }
|
|
446
|
+
.si-overview-trend { background:var(--bg-surface);border-radius:10px;padding:14px 16px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column }
|
|
447
|
+
|
|
448
|
+
/* 三视角 ring + label(锚定到下面对应 section);内容自身居中,被 cards 容器垂直拉伸时上下留白对称 */
|
|
449
|
+
.si-vs { flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:8px;padding:8px 4px;text-decoration:none;color:var(--text-primary);border-radius:8px;transition:background .15s }
|
|
450
|
+
.si-vs:hover { background:var(--bg-soft);text-decoration:none }
|
|
451
|
+
.si-ring { display:block }
|
|
452
|
+
.si-vs-h { display:flex;align-items:baseline;gap:4px;flex-wrap:wrap;justify-content:center;margin-top:4px }
|
|
453
|
+
.si-vs-icon { font-size:15px;line-height:1 }
|
|
454
|
+
.si-vs-label { font-size:13.5px;font-weight:600;color:var(--text-primary) }
|
|
455
|
+
.si-vs-sublabel { font-size:11px;color:var(--text-muted) }
|
|
456
|
+
.si-vs-stat { font-size:12.5px;color:var(--text-secondary);font-variant-numeric:tabular-nums;line-height:1.45 }
|
|
457
|
+
.si-vs-spark { display:block;margin-top:2px }
|
|
458
|
+
@media(max-width:560px){
|
|
459
|
+
.si-overview-cards { flex-direction:column;align-items:stretch }
|
|
460
|
+
.si-vs { flex-direction:row;justify-content:flex-start;text-align:left;gap:14px;align-items:center }
|
|
461
|
+
.si-vs-h, .si-vs-stat, .si-vs-spark { margin:0 }
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* 三视角 section(下方主体) */
|
|
465
|
+
.si-sect { background:var(--bg-surface);border-radius:8px;padding:14px 18px;box-shadow:var(--shadow-sm);margin-bottom:14px;border-left:4px solid var(--border);scroll-margin-top:16px }
|
|
466
|
+
.si-sect--green { border-left-color:#5e8252 }
|
|
467
|
+
.si-sect--yellow { border-left-color:#b08030 }
|
|
468
|
+
.si-sect--red { border-left-color:#9c4a3f }
|
|
469
|
+
.si-sect--gray { border-left-color:var(--border) }
|
|
470
|
+
.si-sect-h { display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:10px;flex-wrap:wrap }
|
|
471
|
+
.si-sect-title { font-size:15px;font-weight:600;color:var(--text-primary) }
|
|
472
|
+
.si-sect-meta { font-size:11.5px;color:var(--text-muted);font-variant-numeric:tabular-nums }
|
|
473
|
+
.si-sect-body { display:flex;flex-direction:column;gap:6px }
|
|
474
|
+
.si-sect-empty { font-size:13px;color:var(--text-muted);font-style:italic;padding:8px 0 }
|
|
475
|
+
.si-sect-line { font-size:14px;color:var(--text-secondary);margin-bottom:4px }
|
|
476
|
+
.si-sect-allpass { font-size:14px;color:#5e8252;padding:6px 10px;background:rgba(94,130,82,.07);border-radius:4px }
|
|
477
|
+
.si-sect-link { display:inline-block;margin-top:8px;font-size:12px;color:var(--accent);text-decoration:none;font-weight:500 }
|
|
478
|
+
.si-sect-link:hover { text-decoration:underline }
|
|
479
|
+
.si-sect-fold { margin-top:8px;border-top:1px dashed var(--border);padding-top:6px }
|
|
480
|
+
.si-sect-fold > summary { cursor:pointer;font-size:11.5px;color:var(--text-muted);user-select:none;list-style:none;padding:4px 0 }
|
|
481
|
+
.si-sect-fold > summary::-webkit-details-marker { display:none }
|
|
482
|
+
.si-sect-fold > summary:hover { color:var(--text-secondary) }
|
|
483
|
+
.si-sect-fold-body { padding-top:6px;display:flex;flex-direction:column;gap:5px }
|
|
484
|
+
.si-sect-skipped { font-size:11px;color:var(--text-muted);font-style:italic;margin-top:6px }
|
|
485
|
+
|
|
486
|
+
/* doctor 规则展示(用在 doctor section 和 observe section) */
|
|
487
|
+
.sd-grid { display:flex;flex-direction:column;gap:4px }
|
|
488
|
+
.sd-dim { border-radius:6px;border:1px solid var(--border);overflow:hidden }
|
|
489
|
+
.sd-dim--err { border-color:rgba(156,74,63,.3) }
|
|
490
|
+
.sd-dim--warn { border-color:rgba(176,128,48,.3) }
|
|
491
|
+
.sd-dim--pass { border-color:rgba(94,130,82,.25);background:rgba(94,130,82,.04) }
|
|
492
|
+
.sd-dim--skip { border-color:var(--border);opacity:.6 }
|
|
493
|
+
.sd-dim > summary { list-style:none;cursor:pointer }
|
|
494
|
+
.sd-dim > summary::-webkit-details-marker { display:none }
|
|
495
|
+
.sd-dim-header { display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px }
|
|
496
|
+
.sd-dim-dot { flex-shrink:0;font-size:10px;line-height:1 }
|
|
497
|
+
.sd-dim-name { font-weight:600;color:var(--text-primary);flex:1;min-width:0 }
|
|
498
|
+
.sd-dim-badges { display:flex;gap:6px;flex-shrink:0 }
|
|
499
|
+
.sd-badge { font-size:12px;padding:1px 7px;border-radius:10px;font-weight:500 }
|
|
500
|
+
.sd-badge--err { background:rgba(156,74,63,.1);color:#9c4a3f }
|
|
501
|
+
.sd-badge--warn { background:rgba(176,128,48,.1);color:#b08030 }
|
|
502
|
+
.sd-dim-body { padding:0 12px 10px;display:flex;flex-direction:column;gap:6px }
|
|
503
|
+
.sd-item { padding:8px 10px;border-radius:4px;font-size:14px;line-height:1.6 }
|
|
504
|
+
.sd-item--err { background:rgba(156,74,63,.05);border-left:2px solid #9c4a3f }
|
|
505
|
+
.sd-item--warn { background:rgba(176,128,48,.05);border-left:2px solid #b08030 }
|
|
506
|
+
.sd-item-desc { color:var(--text-primary);word-break:break-word }
|
|
507
|
+
.sd-item-sug { margin-top:4px;font-size:13px;color:var(--text-secondary);padding:4px 8px;background:rgba(94,130,82,.05);border-radius:4px;word-break:break-word }
|
|
508
|
+
.sd-warn-fold { margin-top:6px }
|
|
509
|
+
.sd-warn-list { display:flex;flex-direction:column;gap:6px;margin-top:6px }
|
|
510
|
+
.sd-warn-toggle { cursor:pointer;font-size:13px;color:var(--text-muted);user-select:none;list-style:none;padding:2px 0 }
|
|
511
|
+
.sd-warn-toggle::-webkit-details-marker { display:none }
|
|
512
|
+
.sd-warn-toggle::before { content:'▸ ';font-size:10px }
|
|
513
|
+
details[open] > .sd-warn-toggle::before { content:'▾ ' }
|
|
514
|
+
.sd-warn-toggle:hover { color:var(--text-secondary) }
|
|
515
|
+
.sd-pass-fold { margin-top:6px }
|
|
516
|
+
.sd-pass-fold > .sd-dim + .sd-dim { margin-top:4px }
|
|
517
|
+
.sd-pass-toggle { cursor:pointer;font-size:13px;color:var(--text-muted);user-select:none;list-style:none;padding:6px 0 }
|
|
518
|
+
.sd-pass-toggle::-webkit-details-marker { display:none }
|
|
519
|
+
.sd-pass-toggle:hover { color:var(--text-secondary) }
|
|
520
|
+
.si-rule-hint { margin-top:4px;font-size:12px;color:var(--text-secondary);line-height:1.55 }
|
|
521
|
+
|
|
522
|
+
/* 单条 sample 展开后的 4 段(modal v6:用例 prompt / 期望 / 实际 / 建议)*/
|
|
523
|
+
.si-sb { display:flex;flex-direction:column;gap:10px;padding:10px 0 }
|
|
524
|
+
.si-sb-block { padding:10px 12px;border-radius:5px;background:var(--bg-soft) }
|
|
525
|
+
.si-sb-block--prompt { background:var(--bg-soft) }
|
|
526
|
+
.si-sb-block--expected { background:rgba(94,130,82,.06) }
|
|
527
|
+
.si-sb-block--actual { background:rgba(176,128,48,.07) }
|
|
528
|
+
.si-sb-block--suggest { background:rgba(122,107,137,.07) }
|
|
529
|
+
.si-sb-label { font-size:12px;font-weight:700;color:var(--text-secondary);letter-spacing:0.02em;margin-bottom:5px }
|
|
530
|
+
.si-sb-block--expected .si-sb-label { color:#5e8252 }
|
|
531
|
+
.si-sb-block--actual .si-sb-label { color:#b08030 }
|
|
532
|
+
.si-sb-block--suggest .si-sb-label { color:#7a6b89 }
|
|
533
|
+
.si-sb-text { font-size:13px;color:var(--text-primary);line-height:1.6;white-space:pre-wrap;word-break:break-word }
|
|
534
|
+
.si-sb-block--prompt .si-sb-text { font-family:"SF Mono",Menlo,monospace;font-size:12.5px;max-height:200px;overflow-y:auto }
|
|
535
|
+
.si-sb-sugrow { display:grid;grid-template-columns:90px 1fr;gap:8px;padding:4px 0;align-items:start }
|
|
536
|
+
.si-sb-sugrow:not(:first-child) { border-top:1px dashed var(--border) }
|
|
537
|
+
.si-sb-sugtag { font-size:11px;color:#7a6b89;background:var(--bg-surface);padding:2px 8px;border-radius:8px;font-weight:600;width:fit-content;height:fit-content }
|
|
538
|
+
.si-sb-block--empty { opacity:.75 }
|
|
539
|
+
.si-sb-empty { color:var(--text-muted);font-style:italic;font-size:12.5px }
|
|
540
|
+
|
|
541
|
+
/* 单条 sample 的"期望 vs 实际 vs 卡在哪"diff 对照视图(已被 v6 sb 视图替代,保留 placeholder)*/
|
|
542
|
+
.si-diff { display:flex;flex-direction:column;gap:8px;padding:10px 0 }
|
|
543
|
+
.si-diff-row { display:grid;grid-template-columns:24px 50px 1fr;gap:10px;align-items:start;padding:8px 12px;border-radius:5px;line-height:1.55 }
|
|
544
|
+
.si-diff-row--expected { background:rgba(94,130,82,.07);border-left:3px solid #5e8252 }
|
|
545
|
+
.si-diff-row--actual { background:rgba(176,128,48,.08);border-left:3px solid #b08030 }
|
|
546
|
+
.si-diff-row--failed { background:rgba(156,74,63,.07);border-left:3px solid #9c4a3f }
|
|
547
|
+
.si-diff-icon { font-size:14px;line-height:1.5 }
|
|
548
|
+
.si-diff-label { font-size:11.5px;font-weight:700;letter-spacing:0.04em;color:var(--text-secondary);padding-top:2px }
|
|
549
|
+
.si-diff-row--expected .si-diff-label { color:#5e8252 }
|
|
550
|
+
.si-diff-row--actual .si-diff-label { color:#b08030 }
|
|
551
|
+
.si-diff-row--failed .si-diff-label { color:#9c4a3f }
|
|
552
|
+
.si-diff-text { color:var(--text-primary);font-size:13px;word-break:break-word }
|
|
553
|
+
.si-diff-text--mono { font-family:"SF Mono",Menlo,monospace;font-size:12px;background:var(--bg-surface);padding:2px 7px;border-radius:3px;width:fit-content }
|
|
554
|
+
/* 原始 prompt/output 降级到二级折叠 */
|
|
555
|
+
.si-diff-raw { margin-top:6px;border-top:1px dashed var(--border);padding-top:8px }
|
|
556
|
+
.si-diff-raw > summary { cursor:pointer;font-size:11.5px;color:var(--text-muted);user-select:none;list-style:none }
|
|
557
|
+
.si-diff-raw > summary::-webkit-details-marker { display:none }
|
|
558
|
+
.si-diff-raw > summary:hover { color:var(--text-secondary) }
|
|
559
|
+
.si-diff-raw-body { padding:6px 0 }
|
|
560
|
+
|
|
561
|
+
/* 占位符标识 */
|
|
562
|
+
.si-placeholder { background:rgba(176,128,48,.20);color:#7a5810;padding:1px 4px;border-radius:3px;font-weight:600;font-style:italic }
|
|
563
|
+
.si-rec-patch-hint { font-size:11.5px;color:#7a5810;background:rgba(176,128,48,.10);padding:6px 10px;border-radius:4px;margin-bottom:6px;line-height:1.5 }
|
|
564
|
+
.si-rec-patch-hint .si-placeholder { background:rgba(176,128,48,.30) }
|
|
565
|
+
|
|
566
|
+
/* 第一条建议的"⭐ 推荐先做"标记 */
|
|
567
|
+
.si-rec-item--primary { border-left-color:#5e8252;background:rgba(94,130,82,.06) }
|
|
568
|
+
.si-rec-star { font-size:10.5px;font-weight:700;color:#5e8252;background:rgba(94,130,82,.16);padding:2px 8px;border-radius:9px;letter-spacing:0.02em;flex-shrink:0 }
|
|
569
|
+
|
|
570
|
+
/* 建议 + patch 直接铺(去掉 details 折叠)*/
|
|
571
|
+
.si-recs { margin:14px 0 }
|
|
572
|
+
.si-recs-h { font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:10px }
|
|
573
|
+
.si-rec-item { background:var(--bg-soft);border-radius:6px;padding:10px 12px;margin-bottom:8px;border-left:3px solid var(--accent) }
|
|
574
|
+
.si-rec-item:last-child { margin-bottom:0 }
|
|
575
|
+
.si-rec-head { display:flex;align-items:flex-start;gap:8px;margin-bottom:8px }
|
|
576
|
+
.si-rec-num { font-size:11px;font-weight:700;color:var(--text-muted);background:var(--bg-surface);padding:1px 7px;border-radius:9px;flex-shrink:0;margin-top:1px;font-variant-numeric:tabular-nums }
|
|
577
|
+
.si-rec-pri { padding:1px 7px;border-radius:8px;font-size:10.5px;font-weight:600;flex-shrink:0;margin-top:1px }
|
|
578
|
+
.si-rec-pri--high { background:rgba(156,74,63,.14);color:#9c4a3f }
|
|
579
|
+
.si-rec-pri--medium { background:rgba(176,128,48,.12);color:#b08030 }
|
|
580
|
+
.si-rec-pri--low { background:rgba(94,130,82,.14);color:#5e8252 }
|
|
581
|
+
.si-rec-action { flex:1;color:var(--text-primary);font-size:13px;line-height:1.55 }
|
|
582
|
+
.si-rec-patch { margin-left:0 }
|
|
583
|
+
.si-rec-patch-meta { display:flex;gap:8px;align-items:center;font-size:11px;color:var(--text-muted);margin-bottom:5px;flex-wrap:wrap }
|
|
584
|
+
.si-rec-patch-target { font-weight:600;color:var(--text-secondary) }
|
|
585
|
+
.si-rec-patch-loc { font-family:"SF Mono",Menlo,monospace;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
|
|
586
|
+
.si-rec-patch-copy { background:var(--accent);color:#fff;border:none;border-radius:4px;padding:3px 10px;font-size:11px;cursor:pointer;font-weight:500;transition:background .1s;flex-shrink:0 }
|
|
587
|
+
.si-rec-patch-copy:hover { background:var(--accent-hover) }
|
|
588
|
+
.si-rec-patch-copy.copied { background:#5e8252 }
|
|
589
|
+
.si-rec-patch-snippet { background:var(--bg-surface);padding:10px 12px;border-radius:4px;border-left:2px solid var(--accent);font-size:11.5px;line-height:1.55;overflow-x:auto;margin:0 }
|
|
590
|
+
.si-rec-patch-snippet code { font-family:"SF Mono",Menlo,monospace;color:var(--text-primary);white-space:pre;display:block }
|
|
591
|
+
|
|
592
|
+
/* 三视角细节折叠(底部)*/
|
|
593
|
+
.si-modal-detail { margin-top:14px;border-top:1px solid var(--border);padding-top:10px }
|
|
594
|
+
.si-modal-detail > summary { cursor:pointer;font-size:12px;font-weight:600;color:var(--text-secondary);user-select:none;list-style:none;padding:4px 0 }
|
|
595
|
+
.si-modal-detail > summary::-webkit-details-marker { display:none }
|
|
596
|
+
.si-modal-detail > summary:hover { color:var(--text-primary) }
|
|
597
|
+
.si-modal-detail-body { margin-top:8px;padding:8px 10px;background:var(--bg-soft);border-radius:5px }
|
|
598
|
+
|
|
599
|
+
/* Modal 内的样式(沿用 modal-overlay/modal-content,只补本页特有的)*/
|
|
600
|
+
.si-modal { max-width:760px;width:90% }
|
|
601
|
+
.si-modal-h { display:flex;align-items:center;gap:10px;flex-wrap:wrap }
|
|
602
|
+
.si-modal-num { font-size:12px;font-weight:700;color:var(--text-muted);background:var(--bg-soft);padding:2px 8px;border-radius:4px }
|
|
603
|
+
.si-modal-sev { font-size:18px }
|
|
604
|
+
.si-modal-title { margin:0;font-size:17px;font-weight:600;color:var(--text-primary) }
|
|
605
|
+
/* si-modal-tags / si-modal-affect / si-aud-tag — modal v4 极简后不再使用,保留 placeholder 防回退 */
|
|
606
|
+
.si-modal-desc { color:var(--text-secondary);font-size:13px;line-height:1.6;margin:0 0 14px }
|
|
607
|
+
.si-modal-purpose { color:var(--text-secondary);font-size:13px;line-height:1.6;margin:6px 0 12px;font-style:italic }
|
|
608
|
+
.si-modal-stats { color:var(--text-secondary);font-size:13px;margin-bottom:14px;padding:8px 12px;background:var(--bg-soft);border-radius:5px;font-variant-numeric:tabular-nums }
|
|
609
|
+
.si-modal-empty { color:var(--text-muted);font-size:13px;padding:18px;text-align:center;font-style:italic }
|
|
610
|
+
|
|
611
|
+
.si-sev-tag { padding:2px 9px;border-radius:11px;font-size:11px;font-weight:600 }
|
|
612
|
+
.si-sev-tag--high { background:rgba(156,74,63,.14);color:#9c4a3f }
|
|
613
|
+
.si-sev-tag--medium { background:rgba(176,128,48,.12);color:#b08030 }
|
|
614
|
+
.si-sev-tag--low { background:rgba(94,130,82,.14);color:#5e8252 }
|
|
615
|
+
|
|
616
|
+
/* 证据 */
|
|
617
|
+
.si-evidence { background:var(--bg-soft);padding:10px 12px;border-radius:6px;margin-bottom:12px }
|
|
618
|
+
.si-evidence-h { font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:8px }
|
|
619
|
+
.si-ev { padding:4px 0;font-size:13px;line-height:1.55 }
|
|
620
|
+
.si-ev-line { display:grid;grid-template-columns:24px 100px 1fr;gap:10px;align-items:start }
|
|
621
|
+
.si-ev-icon { text-align:center;font-weight:600 }
|
|
622
|
+
.si-ev--flagged .si-ev-icon { color:#9c4a3f }
|
|
623
|
+
.si-ev--blind .si-ev-icon { color:#7a6b89 }
|
|
624
|
+
.si-ev--silent .si-ev-icon { color:#7a9270 }
|
|
625
|
+
.si-ev--na .si-ev-icon { color:var(--text-muted) }
|
|
626
|
+
.si-ev-perspective { color:var(--text-secondary);font-weight:500 }
|
|
627
|
+
.si-ev-msg { color:var(--text-primary) }
|
|
628
|
+
.si-ev-ill { margin-top:4px;margin-left:34px }
|
|
629
|
+
.si-ev-ill > summary { cursor:pointer;font-size:11.5px;color:var(--accent);list-style:none;padding:2px 0 }
|
|
630
|
+
.si-ev-ill > summary::-webkit-details-marker { display:none }
|
|
631
|
+
.si-ev-ill > summary::before { content:'▸ ';color:var(--text-muted) }
|
|
632
|
+
.si-ev-ill[open] > summary::before { content:'▾ ' }
|
|
633
|
+
.si-ev-ill-body { padding:6px 0;display:flex;flex-direction:column;gap:8px }
|
|
634
|
+
.si-illustration { background:var(--bg-surface);border-left:2px solid var(--border);padding:6px 10px;border-radius:4px;font-size:11.5px }
|
|
635
|
+
.si-ill-h { margin-bottom:4px }
|
|
636
|
+
.si-ill-h code { background:var(--bg-soft);padding:1px 5px;border-radius:3px;font-size:11px }
|
|
637
|
+
.si-ill-row { display:grid;grid-template-columns:80px 1fr;gap:8px;align-items:start;margin-bottom:3px }
|
|
638
|
+
.si-ill-label { color:var(--text-muted);font-size:10.5px;font-weight:500 }
|
|
639
|
+
.si-ill-text { color:var(--text-primary);font-size:11.5px;background:var(--bg-soft);padding:3px 6px;border-radius:3px;white-space:pre-wrap;word-break:break-word }
|
|
640
|
+
.si-ill-text--mono { font-family:"SF Mono",Menlo,monospace;background:rgba(156,74,63,.10);color:#9c4a3f }
|
|
641
|
+
.si-ill-tools { margin:0;padding-left:0;list-style:none;display:flex;flex-direction:column;gap:2px }
|
|
642
|
+
.si-ill-tools li { font-family:"SF Mono",Menlo,monospace;font-size:10.5px;background:var(--bg-soft);padding:2px 5px;border-radius:3px }
|
|
643
|
+
|
|
644
|
+
/* 推荐 */
|
|
645
|
+
.si-recs ul { margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:10px }
|
|
646
|
+
.si-recs li { font-size:13px;line-height:1.55 }
|
|
647
|
+
.si-rec-line { display:flex;gap:8px;align-items:flex-start }
|
|
648
|
+
.si-rec-pri { padding:1px 7px;border-radius:8px;font-size:10.5px;font-weight:600;flex-shrink:0;margin-top:1px }
|
|
649
|
+
.si-rec-pri--high { background:rgba(156,74,63,.14);color:#9c4a3f }
|
|
650
|
+
.si-rec-pri--medium { background:rgba(176,128,48,.12);color:#b08030 }
|
|
651
|
+
.si-rec-pri--low { background:rgba(94,130,82,.14);color:#5e8252 }
|
|
652
|
+
.si-rec-action { color:var(--text-primary);flex:1 }
|
|
653
|
+
.si-recs-h { font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:8px;margin-top:0 }
|
|
654
|
+
.si-patch { margin-top:6px;margin-left:24px }
|
|
655
|
+
.si-patch > summary { cursor:pointer;font-size:11.5px;color:var(--accent);list-style:none;padding:2px 0 }
|
|
656
|
+
.si-patch > summary::-webkit-details-marker { display:none }
|
|
657
|
+
.si-patch > summary::before { content:'▸ ';color:var(--text-muted) }
|
|
658
|
+
.si-patch[open] > summary::before { content:'▾ ' }
|
|
659
|
+
.si-patch-body { padding:6px 0 }
|
|
660
|
+
.si-patch-meta { display:flex;gap:8px;margin-bottom:6px;font-size:11px;color:var(--text-muted);align-items:center }
|
|
661
|
+
.si-patch-target { font-weight:600;color:var(--text-secondary) }
|
|
662
|
+
.si-patch-loc { font-family:"SF Mono",Menlo,monospace }
|
|
663
|
+
.si-patch-snippet { background:var(--bg-soft);padding:10px 12px;border-radius:4px;border-left:2px solid var(--accent);font-size:11.5px;line-height:1.55;overflow-x:auto;margin:0 }
|
|
664
|
+
.si-patch-snippet code { font-family:"SF Mono",Menlo,monospace;color:var(--text-primary);white-space:pre;display:block }
|
|
665
|
+
|
|
666
|
+
/* Modal 内的 doctor rule list */
|
|
667
|
+
.si-rules { list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px }
|
|
668
|
+
.si-rule { display:flex;gap:10px;font-size:13px;line-height:1.55;align-items:flex-start;padding:8px 10px;border-radius:4px }
|
|
669
|
+
.si-rule--warn { background:rgba(176,128,48,.07) }
|
|
670
|
+
.si-rule--fail { background:rgba(156,74,63,.08) }
|
|
671
|
+
.si-rule-icon { flex-shrink:0;font-weight:700;width:16px;text-align:center;font-size:14px }
|
|
672
|
+
.si-rule--pass .si-rule-icon { color:#5e8252 }
|
|
673
|
+
.si-rule--warn .si-rule-icon { color:#b08030 }
|
|
674
|
+
.si-rule--fail .si-rule-icon { color:#9c4a3f }
|
|
675
|
+
.si-rule-body { flex:1;min-width:0 }
|
|
676
|
+
.si-rule-id { font-size:11px;color:var(--text-muted);background:var(--bg-soft);padding:1px 5px;border-radius:3px;margin-right:6px }
|
|
677
|
+
.si-rule-msg { color:var(--text-primary) }
|
|
678
|
+
.si-rule-hint { font-size:12px;color:var(--text-secondary);margin-top:3px;line-height:1.55 }
|
|
679
|
+
|
|
680
|
+
/* Sample list (eval modal — 全部用例清单)。复用 si-history-row 大部分样式,只重写 grid */
|
|
681
|
+
.si-sample-list { max-height:340px;overflow-y:auto }
|
|
682
|
+
.si-sample-row { grid-template-columns:18px 100px 56px 1fr auto !important;gap:8px !important }
|
|
683
|
+
.si-sample-row--pass { background:rgba(94,130,82,.06) }
|
|
684
|
+
.si-sample-row--fail { background:rgba(156,74,63,.06);border-left:2px solid #9c4a3f }
|
|
685
|
+
.si-sample-row--tripwire { background:rgba(122,107,137,.06);border-left:2px solid #7a6b89 }
|
|
686
|
+
.si-sample-icon { font-weight:700;text-align:center;font-size:13px }
|
|
687
|
+
.si-sample-icon--pass { color:#5e8252 }
|
|
688
|
+
.si-sample-icon--fail { color:#9c4a3f }
|
|
689
|
+
.si-sample-icon--tripwire { color:#7a6b89 }
|
|
690
|
+
.si-sample-id { font-size:11px;color:var(--text-secondary);background:transparent;padding:0;font-family:"SF Mono",Menlo,monospace;font-weight:600 }
|
|
691
|
+
.si-sample-score { font-variant-numeric:tabular-nums;font-size:12px;color:var(--text-secondary);font-weight:600;text-align:right }
|
|
692
|
+
.si-sample-desc { color:var(--text-secondary);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0 }
|
|
693
|
+
@media(max-width:640px){
|
|
694
|
+
.si-sample-row { grid-template-columns:18px 1fr auto !important }
|
|
695
|
+
.si-sample-id { grid-column:2/3 }
|
|
696
|
+
.si-sample-score, .si-sample-desc { display:none }
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/* History section in stage modals */
|
|
700
|
+
.si-history { margin-top:14px;border-top:1px solid var(--border);padding-top:10px }
|
|
701
|
+
.si-history > summary { cursor:pointer;list-style:none;padding:6px 4px;font-size:12.5px;font-weight:600;color:var(--text-secondary);user-select:none;display:flex;align-items:center;gap:6px }
|
|
702
|
+
.si-history > summary::-webkit-details-marker { display:none }
|
|
703
|
+
.si-history > summary::before { content:'▸ ';color:var(--text-muted);font-size:11px }
|
|
704
|
+
.si-history[open] > summary::before { content:'▾ ' }
|
|
705
|
+
.si-history > summary:hover { color:var(--text-primary) }
|
|
706
|
+
.si-history-list { margin:6px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px }
|
|
707
|
+
.si-history-list li { padding:0;background:transparent }
|
|
708
|
+
/* 整行可点击:eval/observe 用 <a>,doctor 历史用 <button>(走 inline modal),样式完全一致 */
|
|
709
|
+
.si-history-row { all:unset;cursor:pointer;display:grid;grid-template-columns:64px 1fr auto auto;gap:10px;align-items:center;padding:7px 10px;background:var(--bg-soft);border-radius:5px;font-size:12.5px;line-height:1.45;transition:background .12s,transform .12s;text-align:left;width:100%;box-sizing:border-box;color:var(--text-primary) }
|
|
710
|
+
.si-history-row:hover { background:var(--bg-elevated);transform:translateX(2px) }
|
|
711
|
+
.si-history-row:focus-visible { outline:2px solid var(--accent);outline-offset:1px }
|
|
712
|
+
.si-history-date { font-variant-numeric:tabular-nums;font-weight:600;color:var(--text-secondary) }
|
|
713
|
+
.si-history-meta { color:var(--text-secondary);font-variant-numeric:tabular-nums }
|
|
714
|
+
.si-history-status { font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:8px;letter-spacing:0.02em;justify-self:end }
|
|
715
|
+
.si-history-status--green { background:rgba(94,130,82,.18);color:#5e8252 }
|
|
716
|
+
.si-history-status--yellow { background:rgba(176,128,48,.16);color:#b08030 }
|
|
717
|
+
.si-history-status--red { background:rgba(156,74,63,.18);color:#9c4a3f }
|
|
718
|
+
.si-history-arrow { color:var(--text-muted);font-size:14px;font-weight:300 }
|
|
719
|
+
@media(max-width:640px){
|
|
720
|
+
.si-history-row { grid-template-columns:56px 1fr auto;gap:6px }
|
|
721
|
+
.si-history-arrow { display:none }
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/* Eval modal blocks */
|
|
725
|
+
.si-eval-block { background:var(--bg-soft);padding:12px 14px;border-radius:6px;margin-bottom:12px }
|
|
726
|
+
.si-eval-block:last-child { margin-bottom:0 }
|
|
727
|
+
.si-eval-h { margin:0 0 10px;font-size:13px;font-weight:600;color:var(--text-primary) }
|
|
728
|
+
.si-eval-score-row { display:flex;gap:14px;align-items:flex-end;margin-bottom:10px }
|
|
729
|
+
.si-eval-composite { font-size:30px;font-weight:700;color:var(--text-primary);font-variant-numeric:tabular-nums;line-height:1 }
|
|
730
|
+
.si-eval-composite-sub { font-size:11.5px;color:var(--text-muted);margin-left:4px;font-weight:normal }
|
|
731
|
+
.si-eval-headline { color:var(--text-secondary);font-size:12.5px;line-height:1.5;margin:0;font-style:italic }
|
|
732
|
+
.si-layers { display:flex;flex-direction:column;gap:5px;margin-bottom:8px }
|
|
733
|
+
.si-layer { display:grid;grid-template-columns:80px 1fr 50px;gap:10px;align-items:center;font-size:12.5px }
|
|
734
|
+
.si-layer-lbl { color:var(--text-secondary) }
|
|
735
|
+
.si-layer-bar { background:var(--bg-surface);border-radius:4px;height:8px;overflow:hidden }
|
|
736
|
+
.si-layer-fill { height:100%;border-radius:4px }
|
|
737
|
+
.si-layer-fill--pass { background:#5e8252 }
|
|
738
|
+
.si-layer-fill--warn { background:#b08030 }
|
|
739
|
+
.si-layer-fill--fail { background:#9c4a3f }
|
|
740
|
+
.si-layer-num { font-variant-numeric:tabular-nums;font-weight:600;text-align:right;font-size:12px }
|
|
741
|
+
.si-layer-num--pass { color:#5e8252 }
|
|
742
|
+
.si-layer-num--warn { color:#b08030 }
|
|
743
|
+
.si-layer-num--fail { color:#9c4a3f }
|
|
744
|
+
.si-eval-link { display:inline-block;color:var(--accent);font-size:12.5px;text-decoration:none;font-weight:500 }
|
|
745
|
+
.si-eval-link:hover { text-decoration:underline }
|
|
746
|
+
.si-failed-list { margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:6px }
|
|
747
|
+
.si-failed-list li { font-size:12.5px;line-height:1.55;display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;padding:8px 10px;border-radius:4px;background:rgba(156,74,63,.06);border-left:2px solid #9c4a3f }
|
|
748
|
+
.si-fs-id { font-size:11px;background:var(--bg-surface);padding:1px 5px;border-radius:3px;color:#9c4a3f;font-weight:600 }
|
|
749
|
+
.si-fs-mode { font-size:10.5px;color:#b08030;background:rgba(176,128,48,.14);padding:1px 6px;border-radius:8px;font-weight:500 }
|
|
750
|
+
.si-fs-summary { color:var(--text-secondary);font-size:12px;flex-basis:100% }
|
|
751
|
+
`;
|
|
752
|
+
// ────────── chart.js init script ──────────
|
|
753
|
+
const TREND_INIT_SCRIPT = `
|
|
754
|
+
<script src="/static/chart.js" onerror="window.__omkChartLoadError=true"></script>
|
|
755
|
+
<script>
|
|
756
|
+
(function(){
|
|
757
|
+
var L = (document.documentElement.dataset.lang || 'zh');
|
|
758
|
+
function showFallback(canvas, msg){
|
|
759
|
+
if (!canvas) return;
|
|
760
|
+
var wrap = canvas.parentElement;
|
|
761
|
+
if (!wrap || wrap.dataset.omkFallback === '1') return;
|
|
762
|
+
wrap.dataset.omkFallback = '1'; // 防止异步路径多次写入
|
|
763
|
+
wrap.innerHTML = '<div class="si-trend-fallback">' +
|
|
764
|
+
'<div class="si-trend-fallback-icon">📉</div>' +
|
|
765
|
+
'<div class="si-trend-fallback-msg">' + msg + '</div>' +
|
|
766
|
+
'<div class="si-trend-fallback-hint">' + (L === 'en' ? 'Check browser console for details.' : '数据仍可从下方指标速览看,或在浏览器控制台看具体错误。') + '</div>' +
|
|
767
|
+
'</div>';
|
|
768
|
+
}
|
|
769
|
+
// 异步兜底:Chart 内部 RAF / setTimeout 抛错会冒泡到 window.error,这里捕获后
|
|
770
|
+
// 把 trend canvas 区域降级,不让"图表 init 看似成功但渲染失败"留出空白。
|
|
771
|
+
window.addEventListener('error', function(ev){
|
|
772
|
+
var canvas = document.getElementById('trend-chart');
|
|
773
|
+
if (!canvas) return;
|
|
774
|
+
var msg = (ev && ev.message) || '';
|
|
775
|
+
if (/chart/i.test(msg) || (ev.filename && /chart\\.js$/i.test(ev.filename))) {
|
|
776
|
+
showFallback(canvas, L === 'en' ? 'Trend chart error' : '趋势图渲染异常');
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
function init(){
|
|
780
|
+
var canvas = document.getElementById('trend-chart');
|
|
781
|
+
if (!canvas) return;
|
|
782
|
+
if (window.__omkChartLoadError || !window.Chart) {
|
|
783
|
+
showFallback(canvas, L === 'en' ? 'Chart failed to load' : '趋势图加载失败');
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
var raw = canvas.getAttribute('data-chart');
|
|
787
|
+
var rawLinks = canvas.getAttribute('data-links');
|
|
788
|
+
if (!raw) return;
|
|
789
|
+
try {
|
|
790
|
+
var data = JSON.parse(raw);
|
|
791
|
+
var links = rawLinks ? JSON.parse(rawLinks) : null;
|
|
792
|
+
// 防御:dataset data 长度跟 labels 严重不一致直接降级,别让 chart 静默画空 canvas
|
|
793
|
+
if (data && Array.isArray(data.labels) && Array.isArray(data.datasets)) {
|
|
794
|
+
var bad = data.datasets.some(function(ds){
|
|
795
|
+
return !Array.isArray(ds.data) || ds.data.length !== data.labels.length;
|
|
796
|
+
});
|
|
797
|
+
if (bad) {
|
|
798
|
+
showFallback(canvas, L === 'en' ? 'Chart data format error' : '趋势图数据格式异常');
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
new Chart(canvas, {
|
|
803
|
+
type: 'line',
|
|
804
|
+
data: data,
|
|
805
|
+
options: {
|
|
806
|
+
responsive: true, maintainAspectRatio: false,
|
|
807
|
+
plugins: {
|
|
808
|
+
legend: { position: 'bottom', labels: { boxWidth: 10, font: { size: 11 }, color: '#7a7a7a' } },
|
|
809
|
+
tooltip: { callbacks: {
|
|
810
|
+
label: function(ctx){ return ctx.dataset.label + ': ' + (ctx.parsed.y == null ? '—' : ctx.parsed.y.toFixed(1) + '%'); },
|
|
811
|
+
afterLabel: function(ctx){
|
|
812
|
+
var hint = ctx.dataset._hint || '';
|
|
813
|
+
var lines = hint ? [hint] : [];
|
|
814
|
+
if (links) {
|
|
815
|
+
var url = links[ctx.datasetIndex] && links[ctx.datasetIndex][ctx.dataIndex];
|
|
816
|
+
if (url) lines.push(L === 'en' ? '→ Click to view report' : '→ 点击看那期报告');
|
|
817
|
+
}
|
|
818
|
+
return lines;
|
|
819
|
+
}
|
|
820
|
+
} }
|
|
821
|
+
},
|
|
822
|
+
scales: {
|
|
823
|
+
y: { min: 0, max: 100, ticks: { callback: function(v){ return v === 0 || v === 100 ? v + '%' : ''; }, color: '#a8a8a8', font: { size: 10 }, stepSize: 25 }, grid: { color: 'rgba(58,58,58,.06)' } },
|
|
824
|
+
x: { ticks: { color: '#a8a8a8', font: { size: 10 } }, grid: { display: false } }
|
|
825
|
+
},
|
|
826
|
+
elements: { point: { radius: 3, hoverRadius: 5 } },
|
|
827
|
+
onClick: function(_evt, elements){
|
|
828
|
+
if (!links || !elements || elements.length === 0) return;
|
|
829
|
+
var el = elements[0];
|
|
830
|
+
var url = links[el.datasetIndex] && links[el.datasetIndex][el.index];
|
|
831
|
+
if (url) window.location.href = url;
|
|
832
|
+
},
|
|
833
|
+
onHover: function(evt, elements){
|
|
834
|
+
if (!links) return;
|
|
835
|
+
var any = elements && elements.some(function(el){ return links[el.datasetIndex] && links[el.datasetIndex][el.index]; });
|
|
836
|
+
evt.native.target.style.cursor = any ? 'pointer' : 'default';
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
} catch(e) {
|
|
841
|
+
console.warn('trend chart init failed:', e);
|
|
842
|
+
showFallback(canvas, L === 'en' ? 'Trend chart error' : '趋势图渲染异常');
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
846
|
+
else init();
|
|
847
|
+
})();
|
|
848
|
+
</script>`;
|
|
849
|
+
// ────────── v7:三视角顶层全景 + 各 section 直铺 ──────────
|
|
850
|
+
/** 紧凑 inline sparkline(供顶部速览卡每张里用,显示该视角历史走向)。
|
|
851
|
+
* values 是 0-100 归一化数组(空数组返回占位)。 */
|
|
852
|
+
function renderInlineSpark(values, color) {
|
|
853
|
+
if (!values || values.length === 0) {
|
|
854
|
+
return `<svg class="si-vs-spark" width="80" height="22" viewBox="0 0 80 22" xmlns="http://www.w3.org/2000/svg"><text x="50%" y="55%" text-anchor="middle" fill="#a8a8a8" font-size="9">no data</text></svg>`;
|
|
855
|
+
}
|
|
856
|
+
const w = 80, h = 22, pad = 2;
|
|
857
|
+
const min = Math.min(...values, 0);
|
|
858
|
+
const max = Math.max(...values, 100);
|
|
859
|
+
const range = (max - min) || 1;
|
|
860
|
+
const dx = values.length > 1 ? (w - 2 * pad) / (values.length - 1) : 0;
|
|
861
|
+
const pts = values.map((v, i) => {
|
|
862
|
+
const x = pad + i * dx;
|
|
863
|
+
const y = pad + (h - 2 * pad) * (1 - (v - min) / range);
|
|
864
|
+
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
865
|
+
}).join(' ');
|
|
866
|
+
return `<svg class="si-vs-spark" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}" xmlns="http://www.w3.org/2000/svg">
|
|
867
|
+
<polyline points="${pts}" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
868
|
+
</svg>`;
|
|
869
|
+
}
|
|
870
|
+
/** Donut ring SVG:中央显示百分比,弧色按 band。半径 38,周长 ~239。 */
|
|
871
|
+
function renderDonutRing(pct, color, label) {
|
|
872
|
+
const r = 38, c = 2 * Math.PI * r;
|
|
873
|
+
const safePct = pct == null ? 0 : Math.max(0, Math.min(100, pct));
|
|
874
|
+
const dashOffset = c * (1 - safePct / 100);
|
|
875
|
+
const centerText = pct == null ? '—' : `${Math.round(safePct)}%`;
|
|
876
|
+
return `<svg class="si-ring" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="${e(label)}">
|
|
877
|
+
<circle cx="50" cy="50" r="${r}" fill="none" stroke="var(--bg-soft)" stroke-width="8"/>
|
|
878
|
+
${pct != null ? `<circle cx="50" cy="50" r="${r}" fill="none" stroke="${color}" stroke-width="8"
|
|
879
|
+
stroke-dasharray="${c.toFixed(2)}" stroke-dashoffset="${dashOffset.toFixed(2)}"
|
|
880
|
+
stroke-linecap="round" transform="rotate(-90 50 50)"/>` : ''}
|
|
881
|
+
<text x="50" y="56" text-anchor="middle" font-size="19" font-weight="700" fill="${pct == null ? 'var(--text-muted)' : color}" font-family="-apple-system,BlinkMacSystemFont,sans-serif">${centerText}</text>
|
|
882
|
+
</svg>`;
|
|
883
|
+
}
|
|
884
|
+
/** 三视角顶部全景:3 个 Apple-watch 风 donut ring,每个 ring 下面带 emoji + label + 状态 + sparkline */
|
|
885
|
+
function renderViewSummaryCards(entry, lang) {
|
|
886
|
+
// doctor
|
|
887
|
+
const docBand = entry.doctor
|
|
888
|
+
? (entry.doctor.status === 'fail' ? 'red' : entry.doctor.status === 'warn' ? 'yellow' : 'green') : 'gray';
|
|
889
|
+
const docColor = docBand === 'green' ? '#5e8252' : docBand === 'yellow' ? '#b08030' : docBand === 'red' ? '#9c4a3f' : '#a8a8a8';
|
|
890
|
+
const docPct = entry.doctor && (entry.doctor.passCount + entry.doctor.warnCount + entry.doctor.failCount) > 0
|
|
891
|
+
? (entry.doctor.passCount / (entry.doctor.passCount + entry.doctor.warnCount + entry.doctor.failCount)) * 100
|
|
892
|
+
: null;
|
|
893
|
+
const docPassRates = entry.doctorHistory.map((h) => {
|
|
894
|
+
const tot = h.passCount + h.warnCount + h.failCount;
|
|
895
|
+
return tot > 0 ? (h.passCount / tot) * 100 : 0;
|
|
896
|
+
});
|
|
897
|
+
const docStat = entry.doctor
|
|
898
|
+
? `${entry.doctor.passCount}✓ ${entry.doctor.warnCount}⚠ ${entry.doctor.failCount}✗`
|
|
899
|
+
: (lang === 'zh' ? '未运行' : 'not run');
|
|
900
|
+
// eval
|
|
901
|
+
const evalBand = entry.eval
|
|
902
|
+
? (entry.eval.failCount === 0 ? 'green' : entry.eval.passCount === 0 ? 'red' : 'yellow') : 'gray';
|
|
903
|
+
const evalColor = evalBand === 'green' ? '#5e8252' : evalBand === 'yellow' ? '#b08030' : evalBand === 'red' ? '#9c4a3f' : '#a8a8a8';
|
|
904
|
+
const evalPct = entry.eval && entry.eval.compositeScore != null
|
|
905
|
+
? (entry.eval.compositeScore / 5) * 100
|
|
906
|
+
: null;
|
|
907
|
+
const evalCompositeRates = entry.evalHistory.map((h) => (h.compositeScore ?? 0) / 5 * 100);
|
|
908
|
+
const evalStat = entry.eval && (entry.eval.passCount + entry.eval.failCount) > 0
|
|
909
|
+
? `${entry.eval.totalSamples} ${lang === 'zh' ? '用例' : 'samples'} · ${Math.round((entry.eval.passCount / (entry.eval.passCount + entry.eval.failCount)) * 100)}%${entry.eval.compositeScore != null ? ` · ${entry.eval.compositeScore.toFixed(2)}/5` : ''}`
|
|
910
|
+
: (lang === 'zh' ? '未运行' : 'not run');
|
|
911
|
+
// observe
|
|
912
|
+
const obsBand = entry.observe?.healthBand ?? 'gray';
|
|
913
|
+
const obsColor = obsBand === 'green' ? '#5e8252' : obsBand === 'yellow' ? '#b08030' : obsBand === 'red' ? '#9c4a3f' : '#a8a8a8';
|
|
914
|
+
const obsPct = entry.observe ? (1 - entry.observe.gapRate) * 100 : null;
|
|
915
|
+
const obsStabilityRates = entry.observeHistory.map((h) => (1 - h.gapRate) * 100);
|
|
916
|
+
const obsStat = entry.observe
|
|
917
|
+
? `${entry.observe.segmentCount} ${lang === 'zh' ? '段' : 'segs'} · ${((1 - entry.observe.gapRate) * 100).toFixed(0)}% ${lang === 'zh' ? '稳定' : 'stable'}`
|
|
918
|
+
: (lang === 'zh' ? '未运行' : 'not run');
|
|
919
|
+
const node = (icon, label, sublabel, band, pct, color, stat, sparkRates, anchor) => `<a class="si-vs si-vs--${band}" href="#${anchor}">
|
|
920
|
+
${renderDonutRing(pct, color, `${label} ${sublabel}`)}
|
|
921
|
+
<div class="si-vs-h">
|
|
922
|
+
<span class="si-vs-icon">${icon}</span>
|
|
923
|
+
<span class="si-vs-label">${e(label)}</span>
|
|
924
|
+
<span class="si-vs-sublabel">${e(sublabel)}</span>
|
|
925
|
+
</div>
|
|
926
|
+
<div class="si-vs-stat">${e(stat)}</div>
|
|
927
|
+
${renderInlineSpark(sparkRates, color)}
|
|
928
|
+
</a>`;
|
|
929
|
+
return `${node('🩺', lang === 'zh' ? '健康度' : 'Structure', '(doctor)', docBand, docPct, docColor, docStat, docPassRates, 'section-doctor')}
|
|
930
|
+
${node('🧪', lang === 'zh' ? '评测结果' : 'Test score', '(eval)', evalBand, evalPct, evalColor, evalStat, evalCompositeRates, 'section-eval')}
|
|
931
|
+
${node('👁', lang === 'zh' ? '线上观测' : 'Live stability', '(observe)', obsBand, obsPct, obsColor, obsStat, obsStabilityRates, 'section-observe')}`;
|
|
932
|
+
}
|
|
933
|
+
/** doctor section:展示告警 / 失败规则;通过的规则折叠到底部 */
|
|
934
|
+
function renderDoctorSection(snap, lang) {
|
|
935
|
+
if (!snap) {
|
|
936
|
+
return `<section id="section-doctor" class="si-sect si-sect--gray">
|
|
937
|
+
<div class="si-sect-h">🩺 ${lang === 'zh' ? '健康度 (doctor)' : 'Structure (doctor)'}</div>
|
|
938
|
+
<div class="si-sect-empty">${lang === 'zh' ? '未运行 omk doctor' : 'doctor not run yet'}</div>
|
|
939
|
+
</section>`;
|
|
940
|
+
}
|
|
941
|
+
const getDet = (r) => r.detail;
|
|
942
|
+
const SORT_ORDER = { fail: 0, warn: 1, skipped: 2, pass: 3 };
|
|
943
|
+
const dims = snap.results
|
|
944
|
+
.filter((r) => !r.ruleId.endsWith(':_summary'))
|
|
945
|
+
.sort((a, b) => (SORT_ORDER[a.status] ?? 9) - (SORT_ORDER[b.status] ?? 9));
|
|
946
|
+
const STATUS_CFG = {
|
|
947
|
+
fail: { dot: '🔴', label: lang === 'zh' ? '不通过' : 'fail', cls: 'err' },
|
|
948
|
+
warn: { dot: '🟡', label: lang === 'zh' ? '告警' : 'warn', cls: 'warn' },
|
|
949
|
+
pass: { dot: '🟢', label: lang === 'zh' ? '通过' : 'pass', cls: 'pass' },
|
|
950
|
+
skipped: { dot: '⚪', label: lang === 'zh' ? '跳过' : 'skip', cls: 'skip' },
|
|
951
|
+
};
|
|
952
|
+
const renderDimRow = (r) => {
|
|
953
|
+
const det = getDet(r);
|
|
954
|
+
const name = det?.displayName ?? r.ruleId;
|
|
955
|
+
const cfg = STATUS_CFG[r.status] ?? STATUS_CFG.pass;
|
|
956
|
+
const findings = det?.findings ?? [];
|
|
957
|
+
const errors = findings.filter((f) => f.level === '错误');
|
|
958
|
+
const warnings = findings.filter((f) => f.level === '警告');
|
|
959
|
+
const hasDetails = errors.length > 0 || warnings.length > 0;
|
|
960
|
+
const badge = (count, type) => {
|
|
961
|
+
if (!count)
|
|
962
|
+
return '';
|
|
963
|
+
const label = type === 'err' ? (lang === 'zh' ? '错误' : 'err') : (lang === 'zh' ? '警告' : 'warn');
|
|
964
|
+
return `<span class="sd-badge sd-badge--${type}">${count} ${label}</span>`;
|
|
965
|
+
};
|
|
966
|
+
const header = `<div class="sd-dim-header">
|
|
967
|
+
<span class="sd-dim-dot">${cfg.dot}</span>
|
|
968
|
+
<span class="sd-dim-name">${e(name)}</span>
|
|
969
|
+
<span class="sd-dim-badges">${badge(errors.length, 'err')}${badge(warnings.length, 'warn')}</span>
|
|
970
|
+
</div>`;
|
|
971
|
+
if (!hasDetails)
|
|
972
|
+
return `<div class="sd-dim sd-dim--${cfg.cls}">${header}</div>`;
|
|
973
|
+
let body = '';
|
|
974
|
+
if (errors.length > 0) {
|
|
975
|
+
body += errors.map((f) => `<div class="sd-item sd-item--err">
|
|
976
|
+
<div class="sd-item-desc">❌ ${e(f.description ?? '')}</div>
|
|
977
|
+
${f.suggestion ? `<div class="sd-item-sug">💡 ${e(f.suggestion)}</div>` : ''}
|
|
978
|
+
</div>`).join('');
|
|
979
|
+
}
|
|
980
|
+
if (warnings.length > 0) {
|
|
981
|
+
body += `<details class="sd-warn-fold"><summary class="sd-warn-toggle">${lang === 'zh' ? `${warnings.length} 条警告` : `${warnings.length} warning(s)`}</summary>`;
|
|
982
|
+
body += `<div class="sd-warn-list">${warnings.map((f) => `<div class="sd-item sd-item--warn">
|
|
983
|
+
<div class="sd-item-desc">⚠️ ${e(f.description ?? '')}</div>
|
|
984
|
+
${f.suggestion ? `<div class="sd-item-sug">💡 ${e(f.suggestion)}</div>` : ''}
|
|
985
|
+
</div>`).join('')}</div>`;
|
|
986
|
+
body += `</details>`;
|
|
987
|
+
}
|
|
988
|
+
return `<details class="sd-dim sd-dim--${cfg.cls}" ${errors.length > 0 ? 'open' : ''}>
|
|
989
|
+
<summary>${header}</summary>
|
|
990
|
+
<div class="sd-dim-body">${body}</div>
|
|
991
|
+
</details>`;
|
|
992
|
+
};
|
|
993
|
+
return `<section id="section-doctor" class="si-sect si-sect--${snap.status === 'fail' ? 'red' : snap.status === 'warn' ? 'yellow' : 'green'}">
|
|
994
|
+
<div class="si-sect-h">
|
|
995
|
+
<span class="si-sect-title">🩺 ${lang === 'zh' ? '健康度 (doctor)' : 'Structure (doctor)'}</span>
|
|
996
|
+
<span class="si-sect-meta">${snap.passCount}✓ ${snap.warnCount}⚠ ${snap.failCount}✗ · ${relTime(snap.timestamp, lang)}</span>
|
|
997
|
+
</div>
|
|
998
|
+
<div class="sd-grid">
|
|
999
|
+
${dims.filter((r) => r.status === 'fail' || r.status === 'warn').map(renderDimRow).join('')}
|
|
1000
|
+
${dims.filter((r) => r.status === 'pass' || r.status === 'skipped').length > 0
|
|
1001
|
+
? `<details class="sd-pass-fold"><summary class="sd-pass-toggle">${lang === 'zh'
|
|
1002
|
+
? `▸ ${dims.filter((r) => r.status === 'pass' || r.status === 'skipped').length} 项通过`
|
|
1003
|
+
: `▸ ${dims.filter((r) => r.status === 'pass' || r.status === 'skipped').length} passed`}</summary>
|
|
1004
|
+
${dims.filter((r) => r.status === 'pass' || r.status === 'skipped').map(renderDimRow).join('')}
|
|
1005
|
+
</details>`
|
|
1006
|
+
: ''}
|
|
1007
|
+
</div>
|
|
1008
|
+
</section>`;
|
|
1009
|
+
}
|
|
1010
|
+
/** eval section:失败 sample 列表(默认折叠,展开看 prompt/期望/实际/建议) */
|
|
1011
|
+
function renderEvalSection(snap, evalReport, langQ, lang) {
|
|
1012
|
+
if (!snap) {
|
|
1013
|
+
return `<section id="section-eval" class="si-sect si-sect--gray">
|
|
1014
|
+
<div class="si-sect-h">🧪 ${lang === 'zh' ? '评测结果 (eval)' : 'Test score (eval)'}</div>
|
|
1015
|
+
<div class="si-sect-empty">${lang === 'zh' ? '未运行 omk eval' : 'eval not run yet'}</div>
|
|
1016
|
+
</section>`;
|
|
1017
|
+
}
|
|
1018
|
+
const failedSamples = [];
|
|
1019
|
+
const passedSamples = [];
|
|
1020
|
+
const tripwireSamples = [];
|
|
1021
|
+
if (evalReport && snap.variantName) {
|
|
1022
|
+
const variant = snap.variantName;
|
|
1023
|
+
for (const r of evalReport.results) {
|
|
1024
|
+
const v = r.variants?.[variant];
|
|
1025
|
+
if (!v)
|
|
1026
|
+
continue;
|
|
1027
|
+
const sid = r.sample_id;
|
|
1028
|
+
const prompt = evalReport.sampleSnapshots?.[sid]?.prompt ?? '';
|
|
1029
|
+
const promptPreview = prompt.slice(0, 80).replace(/\n+/g, ' ');
|
|
1030
|
+
const passed = (v.assertions?.details ?? []).every((d) => d.passed);
|
|
1031
|
+
const isTripwire = (v.diagnostic?.rootCause ?? []).includes('tripwire_intentional')
|
|
1032
|
+
|| evalReport.sampleSnapshots?.[sid]?.tripwire === true;
|
|
1033
|
+
if (isTripwire) {
|
|
1034
|
+
tripwireSamples.push({ sampleId: sid, prompt, promptPreview });
|
|
1035
|
+
}
|
|
1036
|
+
else if (passed) {
|
|
1037
|
+
passedSamples.push({
|
|
1038
|
+
sampleId: sid, prompt, promptPreview, score: v.compositeScore ?? null,
|
|
1039
|
+
rubric: evalReport.sampleSnapshots?.[sid]?.rubric ?? '',
|
|
1040
|
+
output: v.outputPreview ?? '',
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
else {
|
|
1044
|
+
failedSamples.push({
|
|
1045
|
+
sampleId: sid,
|
|
1046
|
+
diagnosticSummary: v.diagnostic?.summary ?? '',
|
|
1047
|
+
prompt,
|
|
1048
|
+
expected: v.diagnostic?.expected ?? '',
|
|
1049
|
+
actual: v.diagnostic?.actual ?? '',
|
|
1050
|
+
suggestionSkill: v.diagnostic?.suggestion?.skill ?? '',
|
|
1051
|
+
suggestionSample: v.diagnostic?.suggestion?.sample ?? '',
|
|
1052
|
+
failureModes: (v.diagnostic?.failureModes ?? []),
|
|
1053
|
+
illustration: null,
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
const total = snap.passCount + snap.failCount;
|
|
1059
|
+
const pct = total > 0 ? Math.round((snap.passCount / total) * 100) : 0;
|
|
1060
|
+
const sectBand = snap.failCount === 0 ? 'green' : snap.passCount === 0 ? 'red' : 'yellow';
|
|
1061
|
+
const failedBlock = failedSamples.length > 0
|
|
1062
|
+
? failedSamples.map((s) => {
|
|
1063
|
+
const summary = s.diagnosticSummary || (lang === 'zh' ? '(无诊断摘要)' : '(no summary)');
|
|
1064
|
+
const modes = s.failureModes.length > 0
|
|
1065
|
+
? `<span class="si-failure-modes">${s.failureModes.map((m) => `<span class="si-failure-mode">${e(m)}</span>`).join('')}</span>`
|
|
1066
|
+
: '';
|
|
1067
|
+
const traceLink = `<a class="si-failure-trace" href="/reports/${e(snap.reportId)}${langQ}#sample-${e(s.sampleId)}" onclick="event.stopPropagation()">${lang === 'zh' ? '完整 trace →' : 'full trace →'}</a>`;
|
|
1068
|
+
return `<details class="si-failure-item">
|
|
1069
|
+
<summary class="si-failure-head">
|
|
1070
|
+
<div class="si-failure-row1">
|
|
1071
|
+
<span class="si-sample-dot si-sample-dot--fail">🔴</span>
|
|
1072
|
+
<code class="si-failure-id">${e(s.sampleId)}</code>
|
|
1073
|
+
${modes}
|
|
1074
|
+
<span class="si-failure-spacer"></span>
|
|
1075
|
+
${traceLink}
|
|
1076
|
+
</div>
|
|
1077
|
+
<div class="si-failure-row2">${e(summary)}</div>
|
|
1078
|
+
</summary>
|
|
1079
|
+
<div class="si-failure-detail">${renderSampleBody(s, lang)}</div>
|
|
1080
|
+
</details>`;
|
|
1081
|
+
}).join('')
|
|
1082
|
+
: '';
|
|
1083
|
+
// 通过 sample: 可展开看 prompt 全文 + 得分 + trace 链接
|
|
1084
|
+
const renderPassedSample = (s) => {
|
|
1085
|
+
const traceLink = `<a class="si-failure-trace" href="/reports/${e(snap.reportId)}${langQ}#sample-${e(s.sampleId)}" onclick="event.stopPropagation()">${lang === 'zh' ? '完整 trace →' : 'full trace →'}</a>`;
|
|
1086
|
+
const scoreText = s.score != null ? `${s.score.toFixed(1)}/5` : '';
|
|
1087
|
+
return `<details class="si-pass-card">
|
|
1088
|
+
<summary class="si-pass-head">
|
|
1089
|
+
<div class="si-pass-row1">
|
|
1090
|
+
<span class="si-sample-dot">🟢</span>
|
|
1091
|
+
<code class="si-pass-id">${e(s.sampleId)}</code>
|
|
1092
|
+
${scoreText ? `<span class="si-pass-score">${scoreText}</span>` : ''}
|
|
1093
|
+
<span class="si-failure-spacer"></span>
|
|
1094
|
+
${traceLink}
|
|
1095
|
+
</div>
|
|
1096
|
+
<div class="si-pass-prompt-preview">${e(s.promptPreview)}${s.prompt.length > 80 ? '…' : ''}</div>
|
|
1097
|
+
</summary>
|
|
1098
|
+
<div class="si-pass-body">
|
|
1099
|
+
<div class="si-pass-section">
|
|
1100
|
+
<div class="si-pass-label">${lang === 'zh' ? '📝 用例 Prompt' : '📝 Prompt'}</div>
|
|
1101
|
+
<div class="si-pass-content">${e(s.prompt)}</div>
|
|
1102
|
+
</div>
|
|
1103
|
+
${s.rubric ? `<div class="si-pass-section">
|
|
1104
|
+
<div class="si-pass-label">${lang === 'zh' ? '🎯 期望' : '🎯 Expected'}</div>
|
|
1105
|
+
<div class="si-pass-content">${e(s.rubric)}</div>
|
|
1106
|
+
</div>` : ''}
|
|
1107
|
+
${s.output ? `<div class="si-pass-section">
|
|
1108
|
+
<div class="si-pass-label">${lang === 'zh' ? '✅ 实际输出' : '✅ Actual'}</div>
|
|
1109
|
+
<div class="si-pass-content">${e(s.output)}</div>
|
|
1110
|
+
</div>` : ''}
|
|
1111
|
+
</div>
|
|
1112
|
+
</details>`;
|
|
1113
|
+
};
|
|
1114
|
+
const passedFold = passedSamples.length > 0
|
|
1115
|
+
? `<details class="si-sect-fold">
|
|
1116
|
+
<summary>${lang === 'zh' ? `▸ 已通过 ${passedSamples.length} 条用例` : `▸ ${passedSamples.length} samples passed`}</summary>
|
|
1117
|
+
<div class="si-sect-fold-body">${passedSamples.map(renderPassedSample).join('')}</div>
|
|
1118
|
+
</details>`
|
|
1119
|
+
: '';
|
|
1120
|
+
const tripwireFold = tripwireSamples.length > 0
|
|
1121
|
+
? `<details class="si-sect-fold">
|
|
1122
|
+
<summary>${lang === 'zh' ? `▸ 诱错样本 ${tripwireSamples.length} 条(按设计应该失败)` : `▸ ${tripwireSamples.length} tripwire samples (designed to fail)`}</summary>
|
|
1123
|
+
<div class="si-sect-fold-body">${tripwireSamples.map(renderPassedSample).join('')}</div>
|
|
1124
|
+
</details>`
|
|
1125
|
+
: '';
|
|
1126
|
+
const failedHeading = failedSamples.length > 0
|
|
1127
|
+
? `<div class="si-sect-line">${lang === 'zh' ? `${failedSamples.length} 条用例失败:` : `${failedSamples.length} samples failed:`}</div>`
|
|
1128
|
+
: `<div class="si-sect-allpass">✓ ${lang === 'zh' ? '所有用例通过' : 'all samples pass'}</div>`;
|
|
1129
|
+
// 综合得分 + 六维雷达
|
|
1130
|
+
const variantSummary = evalReport?.summary?.[snap.variantName];
|
|
1131
|
+
const scoreCard = (label, value, max) => {
|
|
1132
|
+
if (value == null)
|
|
1133
|
+
return '';
|
|
1134
|
+
const pctW = Math.round((value / max) * 100);
|
|
1135
|
+
const cls = pctW >= 80 ? 'good' : pctW >= 60 ? 'mid' : 'low';
|
|
1136
|
+
return `<div class="se-score-card">
|
|
1137
|
+
<div class="se-score-label">${e(label)}</div>
|
|
1138
|
+
<div class="se-score-bar"><div class="se-score-fill se-score-fill--${cls}" style="width:${pctW}%"></div></div>
|
|
1139
|
+
<div class="se-score-val">${value.toFixed(2)}<span class="se-score-max">/${max}</span></div>
|
|
1140
|
+
</div>`;
|
|
1141
|
+
};
|
|
1142
|
+
const scoreSummary = variantSummary ? `<div class="se-scores">
|
|
1143
|
+
<div class="se-scores-hero">
|
|
1144
|
+
<div class="se-hero-label">${lang === 'zh' ? '综合得分' : 'Composite'}</div>
|
|
1145
|
+
<div class="se-hero-val">${(variantSummary.avgCompositeScore ?? 0).toFixed(2)}<span class="se-hero-max">/5</span></div>
|
|
1146
|
+
<a class="se-hero-link" href="/reports/${e(snap.reportId)}${langQ}">${lang === 'zh' ? '查看详情 →' : 'Details →'}</a>
|
|
1147
|
+
</div>
|
|
1148
|
+
<div class="se-scores-grid">
|
|
1149
|
+
${scoreCard(lang === 'zh' ? '事实 / Fact' : 'Fact', variantSummary.avgFactScore, 5)}
|
|
1150
|
+
${scoreCard(lang === 'zh' ? '行为 / Behavior' : 'Behavior', variantSummary.avgAssertionScore, 5)}
|
|
1151
|
+
${scoreCard(lang === 'zh' ? 'LLM 评价 / Judge' : 'Judge', variantSummary.avgJudgeScore, 5)}
|
|
1152
|
+
${scoreCard(lang === 'zh' ? '工具成功率' : 'Tool success', variantSummary.toolSuccessRate != null ? variantSummary.toolSuccessRate * 100 : null, 100)}
|
|
1153
|
+
${scoreCard(lang === 'zh' ? 'Trace 覆盖率' : 'Trace coverage', variantSummary.traceCoverageRate != null ? variantSummary.traceCoverageRate * 100 : null, 100)}
|
|
1154
|
+
${scoreCard(lang === 'zh' ? '平均轮次' : 'Avg turns', variantSummary.avgNumTurns, 20)}
|
|
1155
|
+
</div>
|
|
1156
|
+
</div>` : '';
|
|
1157
|
+
return `<section id="section-eval" class="si-sect si-sect--${sectBand}">
|
|
1158
|
+
<div class="si-sect-h">
|
|
1159
|
+
<span class="si-sect-title">🧪 ${lang === 'zh' ? '评测结果 (eval)' : 'Test score (eval)'}</span>
|
|
1160
|
+
<span class="si-sect-meta">${snap.totalSamples} ${lang === 'zh' ? '用例' : 'samples'} · ${pct}% ${lang === 'zh' ? '通过' : 'pass'}${snap.compositeScore != null ? ` · ${snap.compositeScore.toFixed(2)}/5` : ''} · ${relTime(snap.timestamp, lang)}</span>
|
|
1161
|
+
</div>
|
|
1162
|
+
<div class="si-sect-body">
|
|
1163
|
+
${scoreSummary}
|
|
1164
|
+
${failedHeading}
|
|
1165
|
+
${failedBlock}
|
|
1166
|
+
${passedFold}
|
|
1167
|
+
${tripwireFold}
|
|
1168
|
+
<a class="si-sect-link" href="/reports/${e(snap.reportId)}${langQ}">${lang === 'zh' ? '完整 A/B 报告 →' : 'Full A/B report →'}</a>
|
|
1169
|
+
</div>
|
|
1170
|
+
</section>`;
|
|
1171
|
+
}
|
|
1172
|
+
/** observe section:展示异常指标(gap / 工具失败率) */
|
|
1173
|
+
function renderObserveSection(snap, langQ, lang) {
|
|
1174
|
+
if (!snap) {
|
|
1175
|
+
return `<section id="section-observe" class="si-sect si-sect--gray">
|
|
1176
|
+
<div class="si-sect-h">👁 ${lang === 'zh' ? '线上观测 (observe)' : 'Live stability (observe)'}</div>
|
|
1177
|
+
<div class="si-sect-empty">${lang === 'zh' ? '未跑 omk observe' : 'observe not run yet'}</div>
|
|
1178
|
+
</section>`;
|
|
1179
|
+
}
|
|
1180
|
+
const gapPct = (snap.gapRate * 100).toFixed(0);
|
|
1181
|
+
const failPct = (snap.failureRate * 100).toFixed(1);
|
|
1182
|
+
const alerts = [];
|
|
1183
|
+
if (snap.gapRate >= 0.2) {
|
|
1184
|
+
alerts.push(`<div class="si-rule si-rule--warn">
|
|
1185
|
+
<div class="si-rule-head">
|
|
1186
|
+
<span class="si-rule-icon">⚠</span>
|
|
1187
|
+
<code class="si-rule-id">${lang === 'zh' ? '知识库 gap' : 'KB gap'}</code>
|
|
1188
|
+
<span class="si-rule-msg">${gapPct}% ${lang === 'zh' ? '段命中知识库 gap — LLM 找不到该读哪段' : 'segments hit knowledge gap'}</span>
|
|
1189
|
+
</div>
|
|
1190
|
+
</div>`);
|
|
1191
|
+
}
|
|
1192
|
+
if (snap.failureRate >= 0.2) {
|
|
1193
|
+
alerts.push(`<div class="si-rule si-rule--warn">
|
|
1194
|
+
<div class="si-rule-head">
|
|
1195
|
+
<span class="si-rule-icon">⚠</span>
|
|
1196
|
+
<code class="si-rule-id">${lang === 'zh' ? '工具失败率' : 'tool fail rate'}</code>
|
|
1197
|
+
<span class="si-rule-msg">${failPct}% ${lang === 'zh' ? '工具调用失败 — 可能环境问题或 skill 让 LLM 走错路径' : 'tool calls failing'}</span>
|
|
1198
|
+
</div>
|
|
1199
|
+
</div>`);
|
|
1200
|
+
}
|
|
1201
|
+
const body = alerts.length > 0
|
|
1202
|
+
? alerts.join('')
|
|
1203
|
+
: `<div class="si-sect-allpass">✓ ${lang === 'zh' ? '生产观测健康' : 'production observation healthy'}</div>`;
|
|
1204
|
+
return `<section id="section-observe" class="si-sect si-sect--${snap.healthBand}">
|
|
1205
|
+
<div class="si-sect-h">
|
|
1206
|
+
<span class="si-sect-title">👁 ${lang === 'zh' ? '线上观测 (observe)' : 'Live stability (observe)'}</span>
|
|
1207
|
+
<span class="si-sect-meta">${snap.segmentCount} ${lang === 'zh' ? '段' : 'segs'} · gap ${gapPct}% · ${lang === 'zh' ? '工具失败率' : 'tool fail'} ${failPct}% · ${relTime(snap.generatedAt, lang)}</span>
|
|
1208
|
+
</div>
|
|
1209
|
+
<div class="si-sect-body">
|
|
1210
|
+
${body}
|
|
1211
|
+
<a class="si-sect-link" href="/analyses/${e(snap.analysisId)}${langQ}">${lang === 'zh' ? '完整观测报告 →' : 'Full observation report →'}</a>
|
|
1212
|
+
</div>
|
|
1213
|
+
</section>`;
|
|
1214
|
+
}
|
|
1215
|
+
// ────────── 主入口 ──────────
|
|
1216
|
+
export function renderSkillDetail(entry, evalReport, lang = DEFAULT_LANG, insights = []) {
|
|
1217
|
+
const langQ = lang === DEFAULT_LANG ? '' : `?lang=${lang}`;
|
|
1218
|
+
const reportCount = [entry.doctor, entry.eval, entry.observe].filter(Boolean).length;
|
|
1219
|
+
const lastTs = [entry.doctor?.timestamp, entry.eval?.timestamp, entry.observe?.generatedAt]
|
|
1220
|
+
.filter((s) => Boolean(s)).sort().pop();
|
|
1221
|
+
return layout(entry.skillName, `
|
|
1222
|
+
<main>
|
|
1223
|
+
<a class="si-back" href="/${langQ}">${lang === 'zh' ? '← 返回 Skills' : '← Back to Skills'}</a>
|
|
1224
|
+
${renderHero(entry, insights, lastTs, reportCount, lang)}
|
|
1225
|
+
|
|
1226
|
+
<div class="si-overview">
|
|
1227
|
+
<section class="si-overview-cards" aria-label="${lang === 'zh' ? '三视角速览' : 'View summary'}">
|
|
1228
|
+
${renderViewSummaryCards(entry, lang)}
|
|
1229
|
+
</section>
|
|
1230
|
+
<section class="si-overview-trend">
|
|
1231
|
+
<div class="si-trend-h">📈 ${lang === 'zh' ? '健康趋势(0-100%)' : 'Trend (0-100%)'}</div>
|
|
1232
|
+
${renderTrendChart(entry, langQ, lang)}
|
|
1233
|
+
</section>
|
|
1234
|
+
</div>
|
|
1235
|
+
|
|
1236
|
+
${renderDoctorSection(entry.doctor, lang)}
|
|
1237
|
+
${renderEvalSection(entry.eval, evalReport, langQ, lang)}
|
|
1238
|
+
${renderObserveSection(entry.observe, langQ, lang)}
|
|
1239
|
+
</main>
|
|
1240
|
+
<style>${SKILL_DETAIL_CSS}</style>
|
|
1241
|
+
${TREND_INIT_SCRIPT}
|
|
1242
|
+
`, lang);
|
|
1243
|
+
}
|
|
1244
|
+
//# sourceMappingURL=skill-detail-renderer.js.map
|