akm-cli 0.9.0-beta.9 → 0.9.0-rc.1
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/CHANGELOG.md +715 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/help/help-improve.md +9 -6
- package/dist/assets/hints/cli-hints-full.md +6 -5
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/proactive-maintenance.json +25 -0
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/recombine-only.json +21 -0
- package/dist/assets/profiles/reflect-distill.json +30 -0
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +11 -3
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +45 -16
- package/dist/assets/wiki/schema-template.md +4 -4
- package/dist/cli/clack.js +56 -0
- package/dist/cli/config-migrate.js +7 -1
- package/dist/cli/confirm.js +1 -1
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +25 -21
- package/dist/commands/agent/agent-dispatch.js +3 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +26 -7
- package/dist/commands/config-cli.js +26 -13
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-binding.js +95 -0
- package/dist/commands/env/env-cli.js +228 -292
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +156 -155
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +3 -3
- package/dist/commands/health/advisories.js +151 -0
- package/dist/commands/health/checks.js +103 -16
- package/dist/commands/health/html-report.js +447 -81
- package/dist/commands/health/improve-metrics.js +771 -0
- package/dist/commands/health/llm-usage.js +65 -0
- package/dist/commands/health/md-report.js +103 -0
- package/dist/commands/health/metrics.js +278 -0
- package/dist/commands/health/stash-exposure.js +46 -0
- package/dist/commands/health/surfaces.js +216 -0
- package/dist/commands/health/task-runs.js +135 -0
- package/dist/commands/health/types.js +26 -0
- package/dist/commands/health/windows.js +195 -0
- package/dist/commands/health.js +91 -1091
- package/dist/commands/improve/anti-collapse.js +170 -0
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/collapse-detector.js +421 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +64 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +1295 -1277
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill/content-repair.js +202 -0
- package/dist/commands/improve/distill/promote-memory.js +229 -0
- package/dist/commands/improve/distill/quality-gate.js +236 -0
- package/dist/commands/improve/distill-guards.js +127 -0
- package/dist/commands/improve/distill-promotion-policy.js +826 -167
- package/dist/commands/improve/distill.js +228 -605
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +179 -59
- package/dist/commands/improve/extract-prompt.js +54 -3
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +409 -43
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/hot-probation.js +45 -0
- package/dist/commands/improve/improve-auto-accept.js +157 -10
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +28 -8
- package/dist/commands/improve/improve-result-file.js +15 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +485 -2764
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1100 -0
- package/dist/commands/improve/memory/memory-belief.js +14 -15
- package/dist/commands/improve/memory/memory-contradiction-detect.js +83 -60
- package/dist/commands/improve/memory/memory-improve.js +27 -27
- package/dist/commands/improve/outcome-loop.js +270 -0
- package/dist/commands/improve/preparation.js +2002 -0
- package/dist/commands/improve/proactive-maintenance.js +37 -35
- package/dist/commands/improve/procedural.js +398 -0
- package/dist/commands/improve/recombine.js +818 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +206 -45
- package/dist/commands/improve/salience.js +455 -0
- package/dist/commands/improve/schema-similarity-gate.js +168 -0
- package/dist/commands/improve/shared.js +51 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/observability-cli.js +4 -4
- package/dist/commands/proposal/drain-policies.js +13 -4
- package/dist/commands/proposal/drain.js +45 -51
- package/dist/commands/proposal/legacy-import.js +115 -0
- package/dist/commands/proposal/proposal-cli.js +24 -34
- package/dist/commands/proposal/proposal.js +2 -1
- package/dist/commands/proposal/propose.js +8 -3
- package/dist/commands/proposal/repository.js +829 -0
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +93 -895
- package/dist/commands/read/curate.js +410 -111
- package/dist/commands/read/knowledge.js +10 -3
- package/dist/commands/read/remember-cli.js +133 -138
- package/dist/commands/read/search-cli.js +15 -8
- package/dist/commands/read/search.js +22 -11
- package/dist/commands/read/show.js +106 -14
- package/dist/commands/registry-cli.js +76 -87
- package/dist/commands/remember.js +11 -12
- package/dist/commands/sources/add-cli.js +91 -95
- package/dist/commands/sources/history.js +1 -1
- package/dist/commands/sources/init.js +66 -18
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +44 -46
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/sources-cli.js +3 -3
- package/dist/commands/sources/stash-cli.js +19 -39
- package/dist/commands/sources/stash-skeleton.js +57 -8
- package/dist/commands/tasks/default-tasks.js +15 -2
- package/dist/commands/tasks/tasks-cli.js +20 -29
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +23 -38
- package/dist/commands/workflow-cli.js +291 -13
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +79 -5
- package/dist/core/asset/frontmatter.js +188 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +4 -23
- package/dist/core/concurrent.js +10 -1
- package/dist/core/config/config-io.js +10 -1
- package/dist/core/config/config-migration.js +18 -40
- package/dist/core/config/config-schema.js +403 -62
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +67 -22
- package/dist/core/deep-merge.js +38 -0
- package/dist/core/errors.js +1 -0
- package/dist/core/eval/rank-metrics.js +113 -0
- package/dist/core/events.js +4 -7
- package/dist/core/improve-types.js +47 -8
- package/dist/core/json-schema.js +142 -0
- package/dist/core/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +18 -18
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +770 -0
- package/dist/core/state-db.js +132 -1126
- package/dist/core/structured.js +69 -0
- package/dist/core/time.js +53 -0
- package/dist/core/warn.js +21 -0
- package/dist/core/write-source.js +37 -0
- package/dist/indexer/db/db.js +261 -770
- package/dist/indexer/db/entry-mapper.js +41 -0
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/db/schema.js +516 -0
- package/dist/indexer/ensure-index.js +36 -92
- package/dist/indexer/feedback/utility-policy.js +75 -0
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +207 -4
- package/dist/indexer/index-writer-lock.js +18 -11
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +182 -204
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/metadata.js +20 -0
- package/dist/indexer/read-preflight.js +23 -0
- package/dist/indexer/search/db-search.js +89 -13
- package/dist/indexer/search/fts-query.js +51 -0
- package/dist/indexer/search/ranking-contributors.js +95 -9
- package/dist/indexer/search/ranking.js +79 -3
- package/dist/indexer/search/search-fields.js +6 -0
- package/dist/indexer/search/search-source.js +32 -21
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +48 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +41 -13
- package/dist/integrations/agent/config.js +20 -59
- package/dist/integrations/agent/detect.js +9 -0
- package/dist/integrations/agent/index.js +3 -19
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +79 -6
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +83 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +206 -81
- package/dist/integrations/harnesses/aider/agent-builder.js +113 -0
- package/dist/integrations/harnesses/aider/index.js +58 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +153 -0
- package/dist/integrations/harnesses/amazonq/index.js +59 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -7
- package/dist/integrations/harnesses/claude/index.js +27 -23
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +10 -0
- package/dist/integrations/harnesses/codex/agent-builder.js +137 -0
- package/dist/integrations/harnesses/codex/index.js +63 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +60 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +121 -0
- package/dist/integrations/harnesses/gemini/index.js +60 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/index.js +28 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +17 -16
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/harness.js +65 -0
- package/dist/integrations/harnesses/opencode-sdk/index.js +10 -34
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +642 -71
- package/dist/integrations/harnesses/openhands/agent-builder.js +126 -0
- package/dist/integrations/harnesses/openhands/index.js +58 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +104 -0
- package/dist/integrations/harnesses/pi/index.js +58 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/types.js +8 -0
- package/dist/integrations/session-logs/index.js +40 -11
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +34 -11
- package/dist/llm/embedder.js +67 -4
- package/dist/llm/embedders/cache.js +3 -1
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +73 -3
- package/dist/llm/feature-gate.js +16 -15
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +87 -15
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +6 -1
- package/dist/output/text/helpers.js +241 -2
- package/dist/output/text/workflow.js +4 -1
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +27 -9
- package/dist/runtime.js +25 -1
- package/dist/schemas/akm-config.json +14225 -0
- package/dist/schemas/akm-workflow.json +328 -0
- package/dist/scripts/migrate-storage.js +2743 -8390
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +1652 -607
- package/dist/setup/detect.js +9 -0
- package/dist/setup/legacy-config.js +106 -0
- package/dist/setup/prompt.js +57 -0
- package/dist/setup/providers.js +14 -0
- package/dist/setup/registry-stash-loader.js +12 -0
- package/dist/setup/semantic-assets.js +124 -0
- package/dist/setup/setup.js +52 -1614
- package/dist/setup/steps/connection.js +734 -0
- package/dist/setup/steps/output.js +31 -0
- package/dist/setup/steps/platforms.js +124 -0
- package/dist/setup/steps/semantic.js +27 -0
- package/dist/setup/steps/sources.js +222 -0
- package/dist/setup/steps/stashdir.js +42 -0
- package/dist/setup/steps/tasks.js +152 -0
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/canaries-repository.js +107 -0
- package/dist/storage/repositories/consolidation-repository.js +38 -0
- package/dist/storage/repositories/embeddings-repository.js +72 -0
- package/dist/storage/repositories/events-repository.js +187 -0
- package/dist/storage/repositories/extract-sessions-repository.js +96 -0
- package/dist/storage/repositories/improve-runs-repository.js +146 -0
- package/dist/storage/repositories/index-db.js +14 -8
- package/dist/storage/repositories/proposals-repository.js +220 -0
- package/dist/storage/repositories/recombine-repository.js +213 -0
- package/dist/storage/repositories/registry-cache.js +93 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +46 -0
- package/dist/storage/repositories/task-history-repository.js +93 -0
- package/dist/storage/repositories/workflow-runs-repository.js +189 -1
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/index.js +9 -0
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +15 -13
- package/dist/text-import-hook.mjs +1 -1
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/authoring/authoring.js +123 -10
- package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
- package/dist/workflows/cli.js +5 -0
- package/dist/workflows/db.js +138 -4
- package/dist/workflows/exec/brief.js +484 -0
- package/dist/workflows/exec/native-executor.js +975 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1295 -0
- package/dist/workflows/exec/run-workflow.js +596 -0
- package/dist/workflows/exec/scheduler.js +100 -0
- package/dist/workflows/exec/step-work.js +1156 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/watch.js +116 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +388 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +33 -0
- package/dist/workflows/ir/schema.js +4 -0
- package/dist/workflows/parser.js +3 -1
- package/dist/workflows/program/expressions.js +369 -0
- package/dist/workflows/program/parser.js +760 -0
- package/dist/workflows/program/project.js +105 -0
- package/dist/workflows/program/schema.js +54 -0
- package/dist/workflows/renderer.js +82 -5
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/runs.js +248 -153
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +188 -0
- package/dist/workflows/validate-summary.js +26 -10
- package/dist/workflows/validator.js +1 -1
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +7 -5
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0-beta.60.md +19 -0
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +10 -10
- package/dist/assets/tasks/core/update-stashes.yml +0 -4
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
- package/dist/indexer/passes/staleness-detect.js +0 -488
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
--surface2:#21262d;
|
|
18
18
|
--border: #30363d;
|
|
19
19
|
--text: #e6edf3;
|
|
20
|
-
--muted: #
|
|
20
|
+
--muted: #9ea8b5;
|
|
21
21
|
--accent: #58a6ff;
|
|
22
22
|
--green: #3fb950;
|
|
23
23
|
--yellow: #d29922;
|
|
24
24
|
--red: #f85149;
|
|
25
25
|
--purple: #bc8cff;
|
|
26
|
+
--neutral: #8b949e;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
body {
|
|
@@ -43,7 +44,8 @@
|
|
|
43
44
|
gap: 12px;
|
|
44
45
|
flex-wrap: wrap;
|
|
45
46
|
}
|
|
46
|
-
header .logo { font-size: 20px; font-weight: 700; color: var(--accent); letter-spacing: -0.5px; flex-shrink: 0; }
|
|
47
|
+
header .logo { font-size: 20px; font-weight: 700; color: var(--accent); letter-spacing: -0.5px; flex-shrink: 0; display: flex; flex-direction: column; line-height: 1.1; }
|
|
48
|
+
header .logo-version { font-size: 10px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
|
|
47
49
|
header .meta { color: var(--muted); font-size: 13px; min-width: 0; }
|
|
48
50
|
header .meta .title { font-weight: 600; color: var(--text); }
|
|
49
51
|
header .badges { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
@@ -73,6 +75,8 @@
|
|
|
73
75
|
h2 { font-size: 16px; font-weight: 600; margin-bottom: 16px; }
|
|
74
76
|
h3 { font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
|
|
75
77
|
|
|
78
|
+
abbr[title] { text-decoration: underline dotted; cursor: help; text-underline-offset: 2px; }
|
|
79
|
+
|
|
76
80
|
/* ── Executive summary (Discord card) ───────────────────────────────── */
|
|
77
81
|
.exec {
|
|
78
82
|
background: linear-gradient(180deg, var(--surface) 0%, #12161c 100%);
|
|
@@ -80,6 +84,17 @@
|
|
|
80
84
|
border-radius: 10px; padding: 18px 22px; margin-bottom: 28px;
|
|
81
85
|
}
|
|
82
86
|
.exec h2 { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
|
|
87
|
+
.exec .verdict {
|
|
88
|
+
font-size: 14px; color: var(--text); margin-bottom: 16px;
|
|
89
|
+
padding: 10px 14px; background: var(--surface2); border-radius: 8px;
|
|
90
|
+
border-left: 3px solid var(--accent);
|
|
91
|
+
}
|
|
92
|
+
.exec .verdict b { font-weight: 700; }
|
|
93
|
+
.exec .verdict.pass { border-left-color: var(--green); }
|
|
94
|
+
.exec .verdict.warn { border-left-color: var(--yellow); }
|
|
95
|
+
.exec .verdict.fail { border-left-color: var(--red); }
|
|
96
|
+
.exec .freshness { font-size: 12px; color: var(--muted); margin-bottom: 14px; }
|
|
97
|
+
.exec .freshness.stale { color: var(--yellow); font-weight: 600; }
|
|
83
98
|
.exec .exec-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
|
|
84
99
|
@media (max-width: 900px) { .exec .exec-grid { grid-template-columns: 1fr; gap: 16px; } }
|
|
85
100
|
.exec . blk-title, .exec h4 {
|
|
@@ -110,10 +125,21 @@
|
|
|
110
125
|
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
111
126
|
gap: 10px; margin-bottom: 28px;
|
|
112
127
|
}
|
|
128
|
+
.filter-bar {
|
|
129
|
+
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
|
|
130
|
+
background: var(--surface); border: 1px solid var(--border);
|
|
131
|
+
border-radius: 8px; padding: 12px 14px; margin-bottom: 20px;
|
|
132
|
+
}
|
|
133
|
+
.filter-bar label { color: var(--muted); font-size: 12px; font-weight: 600; }
|
|
134
|
+
.filter-bar select {
|
|
135
|
+
background: var(--surface2); color: var(--text); border: 1px solid var(--border);
|
|
136
|
+
border-radius: 6px; padding: 6px 10px; font-size: 12px;
|
|
137
|
+
}
|
|
138
|
+
.filter-note { color: var(--muted); font-size: 12px; margin-left: auto; }
|
|
113
139
|
@media (max-width: 600px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 20px; } }
|
|
114
140
|
.kpi-card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; }
|
|
115
|
-
.kpi-card .label { font-size:
|
|
116
|
-
.kpi-card .value { font-size: 26px; font-weight: 700; line-height: 1; }
|
|
141
|
+
.kpi-card .label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
|
|
142
|
+
.kpi-card .value { font-size: 26px; font-weight: 700; line-height: 1; color: var(--text); }
|
|
117
143
|
.kpi-card .sub { font-size: 11px; color: var(--muted); margin-top: 4px; }
|
|
118
144
|
@media (max-width: 600px) { .kpi-card .value { font-size: 22px; } }
|
|
119
145
|
.kpi-card.green .value { color: var(--green); }
|
|
@@ -121,6 +147,10 @@
|
|
|
121
147
|
.kpi-card.red .value { color: var(--red); }
|
|
122
148
|
.kpi-card.blue .value { color: var(--accent); }
|
|
123
149
|
.kpi-card.purple .value { color: var(--purple); }
|
|
150
|
+
.kpi-card.neutral .value { color: var(--text); }
|
|
151
|
+
.kpi-card.green { border-left: 3px solid var(--green); }
|
|
152
|
+
.kpi-card.yellow { border-left: 3px solid var(--yellow); }
|
|
153
|
+
.kpi-card.red { border-left: 3px solid var(--red); }
|
|
124
154
|
|
|
125
155
|
/* ── Chart panels ───────────────────────────────────────────────────── */
|
|
126
156
|
.charts-grid {
|
|
@@ -132,11 +162,20 @@
|
|
|
132
162
|
.charts-grid { grid-template-columns: 1fr; gap: 10px; }
|
|
133
163
|
.chart-panel.full-width { grid-column: auto; }
|
|
134
164
|
}
|
|
135
|
-
.chart-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; }
|
|
165
|
+
.chart-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; position: relative; }
|
|
136
166
|
.chart-panel.full-width { grid-column: 1 / -1; }
|
|
137
167
|
.chart-panel .ec { width: 100%; height: 240px; }
|
|
138
168
|
.chart-panel.full-width .ec { height: 280px; }
|
|
169
|
+
.chart-panel .ec.tall { height: 300px; }
|
|
170
|
+
.chart-panel.full-width .ec.tall { height: 320px; }
|
|
139
171
|
@media (max-width: 600px) { .chart-panel .ec { height: 200px; } }
|
|
172
|
+
.empty-overlay {
|
|
173
|
+
position: absolute; inset: 44px 16px 16px 16px;
|
|
174
|
+
display: none; align-items: center; justify-content: center;
|
|
175
|
+
color: var(--muted); font-size: 13px; text-align: center;
|
|
176
|
+
pointer-events: none;
|
|
177
|
+
}
|
|
178
|
+
.empty-overlay.show { display: flex; }
|
|
140
179
|
|
|
141
180
|
/* ── Tables ─────────────────────────────────────────────────────────── */
|
|
142
181
|
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
|
@@ -160,8 +199,12 @@
|
|
|
160
199
|
.tag { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 500; }
|
|
161
200
|
.tag-extract { background: rgba(88,166,255,0.15); color: var(--accent); }
|
|
162
201
|
.tag-consolidate { background: rgba(188,140,255,0.15); color: var(--purple); }
|
|
202
|
+
.prio { display: inline-flex; align-items: center; padding: 1px 7px; border-radius: 4px; font-size: 11px; font-weight: 700; margin-right: 6px; }
|
|
203
|
+
.prio.p1 { background: rgba(248,81,73,0.18); color: var(--red); }
|
|
204
|
+
.prio.p2 { background: rgba(210,153,34,0.18); color: var(--yellow); }
|
|
205
|
+
.prio.p3 { background: rgba(139,148,158,0.15);color: var(--muted); }
|
|
163
206
|
|
|
164
|
-
/* ── Advisories
|
|
207
|
+
/* ── Advisories / Action items ──────────────────────────────────────── */
|
|
165
208
|
.advisory-list { display: flex; flex-direction: column; gap: 10px; }
|
|
166
209
|
.advisory {
|
|
167
210
|
display: flex; gap: 12px;
|
|
@@ -173,6 +216,7 @@
|
|
|
173
216
|
.advisory-icon { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
|
|
174
217
|
.advisory-body .title { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
|
|
175
218
|
.advisory-body .desc { font-size: 12px; color: var(--muted); word-break: break-word; }
|
|
219
|
+
.advisory-body .remedy { font-size: 12px; margin-top: 6px; }
|
|
176
220
|
|
|
177
221
|
/* ── Trend indicators ───────────────────────────────────────────────── */
|
|
178
222
|
.trend { font-size: 12px; }
|
|
@@ -193,13 +237,6 @@
|
|
|
193
237
|
font-size: 11px; background: var(--surface2);
|
|
194
238
|
padding: 2px 6px; border-radius: 4px; color: var(--accent); word-break: break-all;
|
|
195
239
|
}
|
|
196
|
-
.command-block {
|
|
197
|
-
background: var(--surface2); border: 1px solid var(--border); border-radius: 6px;
|
|
198
|
-
padding: 12px 16px; font-family: 'SFMono-Regular', Consolas, monospace;
|
|
199
|
-
font-size: 12px; color: var(--muted); line-height: 1.8; overflow-x: auto;
|
|
200
|
-
}
|
|
201
|
-
.command-block span { color: var(--accent); }
|
|
202
|
-
|
|
203
240
|
/* ── Footer ─────────────────────────────────────────────────────────── */
|
|
204
241
|
footer {
|
|
205
242
|
border-top: 1px solid var(--border); padding: 14px 32px;
|
|
@@ -212,7 +249,7 @@
|
|
|
212
249
|
<body>
|
|
213
250
|
|
|
214
251
|
<header>
|
|
215
|
-
<div class="logo">AKM
|
|
252
|
+
<div class="logo">AKM<span class="logo-version">v%%AKM_VERSION%%</span></div>
|
|
216
253
|
<div class="meta">
|
|
217
254
|
<div class="title">Improve Health Report</div>
|
|
218
255
|
<div>Window: %%WINDOW%% · %%SINCE_HUMAN%% · %%RUN_COUNT%% runs</div>
|
|
@@ -229,75 +266,104 @@
|
|
|
229
266
|
%%EXEC_SUMMARY_HTML%%
|
|
230
267
|
</section>
|
|
231
268
|
|
|
269
|
+
<!-- Action Items (merged + de-duplicated advisories and what-to-watch) -->
|
|
270
|
+
<div class="section">
|
|
271
|
+
<h2>Action Items</h2>
|
|
272
|
+
<div class="advisory-list">
|
|
273
|
+
%%ACTION_ITEMS_HTML%%
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
232
277
|
<!-- KPI Row -->
|
|
233
278
|
<div class="kpi-grid">
|
|
234
279
|
%%KPI_CARDS_HTML%%
|
|
235
280
|
</div>
|
|
236
281
|
|
|
282
|
+
<!-- Summary -->
|
|
283
|
+
<div class="section">
|
|
284
|
+
<h2>%%WINDOW%% Aggregate Summary</h2>
|
|
285
|
+
<div class="summary-table">
|
|
286
|
+
<div class="table-wrap">
|
|
287
|
+
<table>
|
|
288
|
+
<thead><tr><th>Metric</th><th>Value</th><th>Trend</th></tr></thead>
|
|
289
|
+
<tbody>
|
|
290
|
+
%%SUMMARY_ROWS_HTML%%
|
|
291
|
+
</tbody>
|
|
292
|
+
</table>
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<div class="filter-bar">
|
|
298
|
+
<label for="rangeSelect">Slice</label>
|
|
299
|
+
<select id="rangeSelect">
|
|
300
|
+
%%SLICE_OPTIONS_HTML%%
|
|
301
|
+
</select>
|
|
302
|
+
|
|
303
|
+
<label for="taskFilter">Task</label>
|
|
304
|
+
<select id="taskFilter"></select>
|
|
305
|
+
|
|
306
|
+
<label for="statusFilter">Status</label>
|
|
307
|
+
<select id="statusFilter">
|
|
308
|
+
<option value="all" selected>all</option>
|
|
309
|
+
<option value="ok">ok</option>
|
|
310
|
+
<option value="failed">failed</option>
|
|
311
|
+
</select>
|
|
312
|
+
|
|
313
|
+
<div class="filter-note">Filters affect charts and the Recent Runs table.</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
237
316
|
<!-- Charts -->
|
|
238
317
|
<div class="section">
|
|
239
318
|
<h2>Run Trend Lines (%%WINDOW%%)</h2>
|
|
240
319
|
<div class="charts-grid">
|
|
241
320
|
|
|
242
321
|
<div class="chart-panel full-width">
|
|
243
|
-
<h3>Wall Time
|
|
244
|
-
<div id="chartWallTime" class="ec"></div>
|
|
322
|
+
<h3>Wall Time — successful vs failed runs (min)</h3>
|
|
323
|
+
<div id="chartWallTime" class="ec tall" role="img" aria-label="Line chart of wall time per run in minutes with a rolling average overlay"></div>
|
|
324
|
+
<div class="empty-overlay" id="emptyWallTime">No runs in the selected slice.</div>
|
|
245
325
|
</div>
|
|
246
326
|
|
|
247
327
|
<div class="chart-panel full-width">
|
|
248
328
|
<h3>Per-Phase Wall Time Decomposition (stacked, min)</h3>
|
|
249
|
-
<div id="chartPhases" class="ec"></div>
|
|
329
|
+
<div id="chartPhases" class="ec tall" role="img" aria-label="Stacked area chart decomposing wall time per run into consolidation, memory inference, graph extraction, and unattributed phases"></div>
|
|
330
|
+
<div class="empty-overlay" id="emptyPhases">No runs in the selected slice.</div>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<div class="chart-panel full-width">
|
|
334
|
+
<h3>LLM Tokens per Stage (stacked: prompt / completion / reasoning)</h3>
|
|
335
|
+
<div id="chartLlmStages" class="ec" role="img" aria-label="Horizontal stacked bar chart of LLM token usage per pipeline stage, broken into prompt, completion, and reasoning tokens"></div>
|
|
336
|
+
<div class="empty-overlay" id="emptyLlmStages">No per-stage LLM usage recorded in this window.</div>
|
|
250
337
|
</div>
|
|
251
338
|
|
|
252
339
|
<div class="chart-panel">
|
|
253
340
|
<h3>Stash Growth (derived vs eligible)</h3>
|
|
254
|
-
<div id="chartStash" class="ec"></div>
|
|
341
|
+
<div id="chartStash" class="ec tall" role="img" aria-label="Line chart of stash derived versus eligible asset counts per run"></div>
|
|
342
|
+
<div class="empty-overlay" id="emptyStash">No runs in the selected slice.</div>
|
|
255
343
|
</div>
|
|
256
344
|
|
|
257
345
|
<div class="chart-panel">
|
|
258
|
-
<h3>Consolidation Output (promoted
|
|
259
|
-
<div id="chartConsOutput" class="ec"></div>
|
|
346
|
+
<h3>Consolidation Output (promoted line · merged / deleted bars)</h3>
|
|
347
|
+
<div id="chartConsOutput" class="ec tall" role="img" aria-label="Consolidation output per run: promoted as a line on the right axis, merged and deleted as bars on the left axis"></div>
|
|
348
|
+
<div class="empty-overlay" id="emptyConsOutput">No runs in the selected slice.</div>
|
|
260
349
|
</div>
|
|
261
350
|
|
|
262
351
|
<div class="chart-panel">
|
|
263
352
|
<h3>Success / Failures per Run</h3>
|
|
264
|
-
<div id="chartSuccess" class="ec"></div>
|
|
353
|
+
<div id="chartSuccess" class="ec" role="img" aria-label="Line chart of wall time for successful runs with failed runs marked as red triangles"></div>
|
|
354
|
+
<div class="empty-overlay" id="emptySuccess">No runs in the selected slice.</div>
|
|
265
355
|
</div>
|
|
266
356
|
|
|
267
357
|
<div class="chart-panel">
|
|
268
358
|
<h3>Lint Flagged vs Fixed</h3>
|
|
269
|
-
<div id="chartLint" class="ec"></div>
|
|
359
|
+
<div id="chartLint" class="ec" role="img" aria-label="Line chart of lint issues flagged versus fixed per run"></div>
|
|
360
|
+
<div class="empty-overlay" id="emptyLint">No runs in the selected slice.</div>
|
|
270
361
|
</div>
|
|
271
362
|
|
|
272
363
|
<div class="chart-panel full-width">
|
|
273
364
|
<h3>Distill Skip-Reason Breakdown (stacked)</h3>
|
|
274
|
-
<div id="chartDistill" class="ec"></div>
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
</div>
|
|
278
|
-
</div>
|
|
279
|
-
|
|
280
|
-
<!-- Summary + Advisories -->
|
|
281
|
-
<div class="section">
|
|
282
|
-
<h2>%%WINDOW%% Aggregate Summary</h2>
|
|
283
|
-
<div class="two-col">
|
|
284
|
-
|
|
285
|
-
<div class="summary-table">
|
|
286
|
-
<div class="table-wrap">
|
|
287
|
-
<table>
|
|
288
|
-
<thead><tr><th>Metric</th><th>Value</th><th>Trend</th></tr></thead>
|
|
289
|
-
<tbody>
|
|
290
|
-
%%SUMMARY_ROWS_HTML%%
|
|
291
|
-
</tbody>
|
|
292
|
-
</table>
|
|
293
|
-
</div>
|
|
294
|
-
</div>
|
|
295
|
-
|
|
296
|
-
<div>
|
|
297
|
-
<h3 style="margin-bottom:12px;">Decision Quality & Advisories</h3>
|
|
298
|
-
<div class="advisory-list">
|
|
299
|
-
%%ADVISORY_CARDS_HTML%%
|
|
300
|
-
</div>
|
|
365
|
+
<div id="chartDistill" class="ec tall" role="img" aria-label="Stacked bar chart of distill skip reasons per run"></div>
|
|
366
|
+
<div class="empty-overlay" id="emptyDistill">No distill skips recorded in this window.</div>
|
|
301
367
|
</div>
|
|
302
368
|
|
|
303
369
|
</div>
|
|
@@ -318,22 +384,14 @@
|
|
|
318
384
|
</div>
|
|
319
385
|
</div>
|
|
320
386
|
|
|
321
|
-
<!--
|
|
387
|
+
<!-- Recent runs -->
|
|
322
388
|
<div class="section">
|
|
323
|
-
<h2>
|
|
324
|
-
<div class="advisory-list">
|
|
325
|
-
%%WATCH_ITEMS_HTML%%
|
|
326
|
-
</div>
|
|
327
|
-
</div>
|
|
328
|
-
|
|
329
|
-
<!-- Last 10 runs -->
|
|
330
|
-
<div class="section">
|
|
331
|
-
<h2>Last 10 Runs</h2>
|
|
389
|
+
<h2>Recent Runs</h2>
|
|
332
390
|
<div class="summary-table">
|
|
333
391
|
<div class="table-wrap">
|
|
334
392
|
<table>
|
|
335
393
|
<thead>
|
|
336
|
-
<tr><th>Started
|
|
394
|
+
<tr><th>Started</th><th>Task</th><th>Wall</th><th>Promoted</th><th>Merged</th><th>Contradicted</th><th>MI Written</th><th>Entities</th><th>Lint Fixed</th><th>Status</th></tr>
|
|
337
395
|
</thead>
|
|
338
396
|
<tbody id="lastRunsTable"></tbody>
|
|
339
397
|
</table>
|
|
@@ -341,47 +399,73 @@
|
|
|
341
399
|
</div>
|
|
342
400
|
</div>
|
|
343
401
|
|
|
344
|
-
<!-- Command set -->
|
|
345
|
-
<div class="section">
|
|
346
|
-
<h2>Command Set Used</h2>
|
|
347
|
-
<div class="command-block">
|
|
348
|
-
%%COMMANDS_HTML%%
|
|
349
|
-
</div>
|
|
350
|
-
</div>
|
|
351
|
-
|
|
352
402
|
</main>
|
|
353
403
|
|
|
354
404
|
<footer>
|
|
355
|
-
<span>AKM
|
|
356
|
-
<span>Generated %%GENERATED_AT%%</span>
|
|
405
|
+
<span>AKM v%%AKM_VERSION%% · Window: %%WINDOW%% · %%REPORT_TITLE%%</span>
|
|
406
|
+
<span>Generated <time data-iso="%%GENERATED_AT%%">%%GENERATED_AT%%</time></span>
|
|
357
407
|
</footer>
|
|
358
408
|
|
|
359
409
|
<script>
|
|
360
410
|
// ── Injected run data ─────────────────────────────────────────────────────────
|
|
361
411
|
%%RUNS_JS_CONST%%
|
|
362
412
|
const DISTILL_REASONS = %%DISTILL_REASONS_JSON%%;
|
|
413
|
+
const LLM_BY_STAGE = %%LLM_BY_STAGE_JSON%%;
|
|
363
414
|
|
|
364
415
|
// ── Theme constants ───────────────────────────────────────────────────────────
|
|
365
416
|
const C = {
|
|
366
417
|
bg: '#161b22', surface2: '#21262d', border: '#30363d',
|
|
367
|
-
text: '#e6edf3', muted: '#
|
|
418
|
+
text: '#e6edf3', muted: '#9ea8b5',
|
|
368
419
|
accent: '#58a6ff', green: '#3fb950', yellow: '#d29922',
|
|
369
420
|
red: '#f85149', purple: '#bc8cff',
|
|
370
421
|
};
|
|
371
422
|
const SERIES_PALETTE = [C.accent, C.green, C.yellow, C.purple, C.red, '#39c5cf', '#db61a2', '#e3b341'];
|
|
372
423
|
|
|
373
|
-
// x-axis category labels = run startedAt (UTC, sorted ascending by collect.py)
|
|
374
|
-
const xLabels = RUNS.map(r => {
|
|
375
|
-
const d = new Date(r.startedAt);
|
|
376
|
-
const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
377
|
-
const dd = String(d.getUTCDate()).padStart(2, '0');
|
|
378
|
-
const hh = String(d.getUTCHours()).padStart(2, '0');
|
|
379
|
-
const mi = String(d.getUTCMinutes()).padStart(2, '0');
|
|
380
|
-
return `${mm}-${dd} ${hh}:${mi}`;
|
|
381
|
-
});
|
|
382
|
-
|
|
383
424
|
const toMin = ms => ms ? +(ms / 60000).toFixed(2) : 0;
|
|
384
425
|
|
|
426
|
+
function makeXLabels(rs) {
|
|
427
|
+
return rs.map(r => {
|
|
428
|
+
const d = new Date(r.startedAt);
|
|
429
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
430
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
431
|
+
const hh = String(d.getHours()).padStart(2, '0');
|
|
432
|
+
const mi = String(d.getMinutes()).padStart(2, '0');
|
|
433
|
+
return `${mm}-${dd} ${hh}:${mi}`;
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function latestRunTime(rs) {
|
|
438
|
+
if (!rs.length) return 0;
|
|
439
|
+
return Math.max(...rs.map(r => Date.parse(r.completedAt || r.startedAt || 0)).filter(Number.isFinite));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function filteredRuns() {
|
|
443
|
+
const slice = document.getElementById('rangeSelect')?.value || 'all';
|
|
444
|
+
const task = document.getElementById('taskFilter')?.value || 'all';
|
|
445
|
+
const status = document.getElementById('statusFilter')?.value || 'all';
|
|
446
|
+
// slice value is 'all' (full window) or a cutoff in ms relative to the newest run.
|
|
447
|
+
const startMs = slice === 'all' ? -Infinity : latestRunTime(RUNS) - Number(slice);
|
|
448
|
+
return RUNS.filter(r => {
|
|
449
|
+
const ts = Date.parse(r.completedAt || r.startedAt || 0);
|
|
450
|
+
if (Number.isFinite(ts) && ts < startMs) return false;
|
|
451
|
+
if (task !== 'all' && (r.taskId || 'manual') !== task) return false;
|
|
452
|
+
if (status === 'ok' && !r.ok) return false;
|
|
453
|
+
if (status === 'failed' && r.ok) return false;
|
|
454
|
+
return true;
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function populateFilters() {
|
|
459
|
+
const taskSelect = document.getElementById('taskFilter');
|
|
460
|
+
const tasks = ['all', ...Array.from(new Set(RUNS.map(r => r.taskId || 'manual'))).sort()];
|
|
461
|
+
taskSelect.innerHTML = tasks.map(t => `<option value="${t}">${t}</option>`).join('');
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function toggleEmpty(id, isEmpty) {
|
|
465
|
+
const el = document.getElementById(id);
|
|
466
|
+
if (el) el.classList.toggle('show', !!isEmpty);
|
|
467
|
+
}
|
|
468
|
+
|
|
385
469
|
// Centered rolling average (window = ~10% of runs, min 3) — deterministic.
|
|
386
470
|
function rollingAvg(arr) {
|
|
387
471
|
const n = arr.length;
|
|
@@ -402,16 +486,20 @@ const baseAxis = {
|
|
|
402
486
|
splitLine: { lineStyle: { color: 'rgba(48,54,61,0.5)' } },
|
|
403
487
|
};
|
|
404
488
|
const baseGrid = { left: 48, right: 16, top: 28, bottom: 28, containLabel: true };
|
|
489
|
+
const denseGrid = { left: 48, right: 16, top: 28, bottom: 40, containLabel: true };
|
|
405
490
|
const baseTooltip = {
|
|
406
491
|
trigger: 'axis',
|
|
407
492
|
backgroundColor: C.surface2, borderColor: C.border, borderWidth: 1,
|
|
408
493
|
textStyle: { color: C.text, fontSize: 12 },
|
|
409
494
|
};
|
|
410
495
|
const baseLegend = { textStyle: { color: C.muted, fontSize: 11 }, top: 2, type: 'scroll' };
|
|
496
|
+
const denseZoom = [{ type: 'slider', bottom: 4, height: 18, borderColor: C.border, backgroundColor: 'rgba(33,38,45,0.6)', fillerColor: 'rgba(88,166,255,0.18)', handleStyle: { color: C.accent }, textStyle: { color: C.muted, fontSize: 9 } }];
|
|
411
497
|
|
|
412
498
|
function mkChart(id, option) {
|
|
413
499
|
const el = document.getElementById(id);
|
|
414
500
|
if (!el) return;
|
|
501
|
+
const prior = echarts.getInstanceByDom(el);
|
|
502
|
+
if (prior) prior.dispose();
|
|
415
503
|
const chart = echarts.init(el, null, { renderer: 'canvas' });
|
|
416
504
|
// animation off → deterministic first paint & no per-frame randomness
|
|
417
505
|
option.animation = false;
|
|
@@ -422,11 +510,21 @@ function mkChart(id, option) {
|
|
|
422
510
|
}
|
|
423
511
|
|
|
424
512
|
// ── 1. Wall time per run + rolling avg ────────────────────────────────────────
|
|
425
|
-
|
|
513
|
+
function renderCharts(rs) {
|
|
514
|
+
const xLabels = makeXLabels(rs);
|
|
515
|
+
toggleEmpty('emptyWallTime', !rs.length);
|
|
516
|
+
toggleEmpty('emptyPhases', !rs.length);
|
|
517
|
+
toggleEmpty('emptyStash', !rs.length);
|
|
518
|
+
toggleEmpty('emptyConsOutput', !rs.length);
|
|
519
|
+
toggleEmpty('emptySuccess', !rs.length);
|
|
520
|
+
toggleEmpty('emptyLint', !rs.length);
|
|
521
|
+
const wall = rs.map(r => toMin(r.wallTimeMs));
|
|
522
|
+
const failPoints = rs.map((r, i) => r.ok ? null : [i, toMin(r.wallTimeMs)]).filter(Boolean);
|
|
426
523
|
mkChart('chartWallTime', {
|
|
427
524
|
tooltip: baseTooltip,
|
|
428
|
-
legend: { ...baseLegend, data: ['Wall time', 'Rolling avg'] },
|
|
429
|
-
grid:
|
|
525
|
+
legend: { ...baseLegend, data: ['Wall time', 'Rolling avg', 'Failed run'] },
|
|
526
|
+
grid: denseGrid,
|
|
527
|
+
dataZoom: denseZoom,
|
|
430
528
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
431
529
|
yAxis: { type: 'value', name: 'min', nameTextStyle: { color: C.muted }, ...baseAxis },
|
|
432
530
|
series: [
|
|
@@ -434,21 +532,24 @@ mkChart('chartWallTime', {
|
|
|
434
532
|
lineStyle: { color: C.accent, width: 1.5 }, areaStyle: { color: 'rgba(88,166,255,0.08)' } },
|
|
435
533
|
{ name: 'Rolling avg', type: 'line', data: rollingAvg(wall), showSymbol: false, smooth: true,
|
|
436
534
|
lineStyle: { color: C.yellow, width: 2, type: 'dashed' } },
|
|
535
|
+
{ name: 'Failed run', type: 'scatter', symbol: 'triangle', symbolSize: 12,
|
|
536
|
+
itemStyle: { color: C.red }, data: failPoints },
|
|
437
537
|
],
|
|
438
538
|
});
|
|
439
539
|
|
|
440
540
|
// ── 2. Per-phase wall time decomposition (stacked area) ──────────────────────
|
|
441
541
|
mkChart('chartPhases', {
|
|
442
542
|
tooltip: baseTooltip,
|
|
443
|
-
legend: { ...baseLegend, data: ['Consolidation', 'Memory inference', 'Graph extraction', '
|
|
444
|
-
grid:
|
|
543
|
+
legend: { ...baseLegend, data: ['Consolidation', 'Memory inference', 'Graph extraction', 'Unattributed'] },
|
|
544
|
+
grid: denseGrid,
|
|
545
|
+
dataZoom: denseZoom,
|
|
445
546
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
446
547
|
yAxis: { type: 'value', name: 'min', nameTextStyle: { color: C.muted }, ...baseAxis },
|
|
447
548
|
series: [
|
|
448
|
-
{ name: 'Consolidation', type: 'line', stack: 'p', areaStyle: { color: 'rgba(88,166,255,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data:
|
|
449
|
-
{ name: 'Memory inference', type: 'line', stack: 'p', areaStyle: { color: 'rgba(63,185,80,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data:
|
|
450
|
-
{ name: 'Graph extraction', type: 'line', stack: 'p', areaStyle: { color: 'rgba(188,140,255,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data:
|
|
451
|
-
{ name: '
|
|
549
|
+
{ name: 'Consolidation', type: 'line', stack: 'p', areaStyle: { color: 'rgba(88,166,255,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data: rs.map(r => toMin(r.consDurationMs)) },
|
|
550
|
+
{ name: 'Memory inference', type: 'line', stack: 'p', areaStyle: { color: 'rgba(63,185,80,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data: rs.map(r => toMin(r.miDurationMs)) },
|
|
551
|
+
{ name: 'Graph extraction', type: 'line', stack: 'p', areaStyle: { color: 'rgba(188,140,255,0.55)' }, lineStyle: { width: 0 }, showSymbol: false, data: rs.map(r => toMin(r.geDurationMs)) },
|
|
552
|
+
{ name: 'Unattributed', type: 'line', stack: 'p', areaStyle: { color: 'rgba(210,153,34,0.45)' }, lineStyle: { width: 0 }, showSymbol: false, data: rs.map(r => toMin(r.otherMs)) },
|
|
452
553
|
],
|
|
453
554
|
});
|
|
454
555
|
|
|
@@ -456,12 +557,13 @@ mkChart('chartPhases', {
|
|
|
456
557
|
mkChart('chartStash', {
|
|
457
558
|
tooltip: baseTooltip,
|
|
458
559
|
legend: { ...baseLegend, data: ['Derived', 'Eligible'] },
|
|
459
|
-
grid:
|
|
560
|
+
grid: denseGrid,
|
|
561
|
+
dataZoom: denseZoom,
|
|
460
562
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
461
563
|
yAxis: { type: 'value', ...baseAxis },
|
|
462
564
|
series: [
|
|
463
|
-
{ name: 'Derived', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.green, width: 1.8 }, data:
|
|
464
|
-
{ name: 'Eligible', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.accent, width: 1.8 }, data:
|
|
565
|
+
{ name: 'Derived', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.green, width: 1.8 }, data: rs.map(r => r.derived) },
|
|
566
|
+
{ name: 'Eligible', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.accent, width: 1.8 }, data: rs.map(r => r.eligible) },
|
|
465
567
|
],
|
|
466
568
|
});
|
|
467
569
|
|
|
@@ -469,24 +571,32 @@ mkChart('chartStash', {
|
|
|
469
571
|
mkChart('chartConsOutput', {
|
|
470
572
|
tooltip: baseTooltip,
|
|
471
573
|
legend: { ...baseLegend, data: ['Promoted', 'Merged', 'Deleted'] },
|
|
472
|
-
grid:
|
|
574
|
+
grid: denseGrid,
|
|
575
|
+
dataZoom: denseZoom,
|
|
473
576
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
474
|
-
|
|
577
|
+
// Promoted dwarfs merged/deleted, so it gets its own right-hand axis and is
|
|
578
|
+
// drawn as a line; merged/deleted stay as bars on the left axis where their
|
|
579
|
+
// smaller magnitudes remain readable.
|
|
580
|
+
yAxis: [
|
|
581
|
+
{ type: 'value', name: 'merged / deleted', nameTextStyle: { color: C.muted, fontSize: 10 }, ...baseAxis },
|
|
582
|
+
{ type: 'value', name: 'promoted', nameTextStyle: { color: C.muted, fontSize: 10 }, position: 'right', ...baseAxis, splitLine: { show: false } },
|
|
583
|
+
],
|
|
475
584
|
series: [
|
|
476
|
-
{ name: 'Promoted', type: '
|
|
477
|
-
{ name: 'Merged', type: 'bar', itemStyle: { color: 'rgba(63,185,80,0.75)' },
|
|
478
|
-
{ name: 'Deleted', type: 'bar', itemStyle: { color: 'rgba(248,81,73,0.75)' },
|
|
585
|
+
{ name: 'Promoted', type: 'line', yAxisIndex: 1, showSymbol: false, smooth: true, lineStyle: { color: C.accent, width: 1.8 }, itemStyle: { color: C.accent }, data: rs.map(r => r.promoted) },
|
|
586
|
+
{ name: 'Merged', type: 'bar', yAxisIndex: 0, itemStyle: { color: 'rgba(63,185,80,0.75)' }, data: rs.map(r => r.merged) },
|
|
587
|
+
{ name: 'Deleted', type: 'bar', yAxisIndex: 0, itemStyle: { color: 'rgba(248,81,73,0.75)' }, data: rs.map(r => r.deleted) },
|
|
479
588
|
],
|
|
480
589
|
});
|
|
481
590
|
|
|
482
|
-
// ── 5. Success / failures (failed runs as distinct red
|
|
591
|
+
// ── 5. Success / failures (failed runs as distinct red triangles) ────────────
|
|
592
|
+
const failScatter = rs.map((r, i) => r.ok ? null : [i, toMin(r.wallTimeMs)]).filter(Boolean);
|
|
483
593
|
mkChart('chartSuccess', {
|
|
484
594
|
tooltip: {
|
|
485
595
|
...baseTooltip,
|
|
486
596
|
formatter: p => {
|
|
487
597
|
const arr = Array.isArray(p) ? p : [p];
|
|
488
598
|
const i = arr[0].dataIndex;
|
|
489
|
-
return `${xLabels[i]}<br/>${
|
|
599
|
+
return `${xLabels[i]}<br/>${rs[i].ok ? '✅ ok' : '❌ failed'} · ${toMin(rs[i].wallTimeMs)}m`;
|
|
490
600
|
},
|
|
491
601
|
},
|
|
492
602
|
legend: { ...baseLegend, data: ['Wall time (ok)', 'Failed run'] },
|
|
@@ -495,10 +605,10 @@ mkChart('chartSuccess', {
|
|
|
495
605
|
yAxis: { type: 'value', name: 'min', nameTextStyle: { color: C.muted }, ...baseAxis },
|
|
496
606
|
series: [
|
|
497
607
|
{ name: 'Wall time (ok)', type: 'line', showSymbol: false, smooth: true,
|
|
498
|
-
lineStyle: { color: C.green, width: 1.2 }, data:
|
|
499
|
-
{ name: 'Failed run', type: 'scatter', symbolSize:
|
|
608
|
+
lineStyle: { color: C.green, width: 1.2 }, data: rs.map(r => r.ok ? toMin(r.wallTimeMs) : null) },
|
|
609
|
+
{ name: 'Failed run', type: 'scatter', symbol: 'triangle', symbolSize: 12,
|
|
500
610
|
itemStyle: { color: C.red },
|
|
501
|
-
data:
|
|
611
|
+
data: failScatter },
|
|
502
612
|
],
|
|
503
613
|
});
|
|
504
614
|
|
|
@@ -510,8 +620,8 @@ mkChart('chartLint', {
|
|
|
510
620
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
511
621
|
yAxis: { type: 'value', ...baseAxis },
|
|
512
622
|
series: [
|
|
513
|
-
{ name: 'Flagged', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.yellow, width: 1.6 }, areaStyle: { color: 'rgba(210,153,34,0.10)' }, data:
|
|
514
|
-
{ name: 'Fixed', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.green, width: 1.6 }, data:
|
|
623
|
+
{ name: 'Flagged', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.yellow, width: 1.6 }, areaStyle: { color: 'rgba(210,153,34,0.10)' }, data: rs.map(r => r.lintFlagged) },
|
|
624
|
+
{ name: 'Fixed', type: 'line', showSymbol: false, smooth: true, lineStyle: { color: C.green, width: 1.6 }, data: rs.map(r => r.lintFixed) },
|
|
515
625
|
],
|
|
516
626
|
});
|
|
517
627
|
|
|
@@ -521,29 +631,64 @@ const distillSeries = DISTILL_REASONS.map((reason, idx) => ({
|
|
|
521
631
|
type: 'bar',
|
|
522
632
|
stack: 'd',
|
|
523
633
|
itemStyle: { color: SERIES_PALETTE[idx % SERIES_PALETTE.length] },
|
|
524
|
-
data:
|
|
634
|
+
data: rs.map(r => (r.distillByReason && r.distillByReason[reason]) || 0),
|
|
525
635
|
}));
|
|
636
|
+
const distillEmpty = !rs.length || !DISTILL_REASONS.length;
|
|
637
|
+
toggleEmpty('emptyDistill', distillEmpty);
|
|
526
638
|
mkChart('chartDistill', {
|
|
527
639
|
tooltip: baseTooltip,
|
|
528
640
|
legend: { ...baseLegend, data: DISTILL_REASONS },
|
|
529
|
-
grid: { ...
|
|
641
|
+
grid: { ...denseGrid, top: 40 },
|
|
642
|
+
dataZoom: denseZoom,
|
|
530
643
|
xAxis: { type: 'category', data: xLabels, ...baseAxis },
|
|
531
644
|
yAxis: { type: 'value', ...baseAxis },
|
|
532
645
|
series: distillSeries.length ? distillSeries
|
|
533
|
-
: [{ name: 'none', type: 'bar', data:
|
|
646
|
+
: [{ name: 'none', type: 'bar', data: rs.map(() => 0) }],
|
|
534
647
|
});
|
|
648
|
+
}
|
|
535
649
|
|
|
536
|
-
// ──
|
|
650
|
+
// ── 8. LLM tokens per stage (horizontal stacked bar) — window aggregate ──────
|
|
651
|
+
function humanizeStage(s) {
|
|
652
|
+
return String(s).replace(/[-_]/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
|
653
|
+
}
|
|
654
|
+
function renderLlmStages() {
|
|
655
|
+
const stages = Object.keys(LLM_BY_STAGE).sort();
|
|
656
|
+
toggleEmpty('emptyLlmStages', !stages.length);
|
|
657
|
+
const labels = stages.map(humanizeStage);
|
|
658
|
+
const prompt = stages.map(s => LLM_BY_STAGE[s].promptTokens || 0);
|
|
659
|
+
const completion = stages.map(s => LLM_BY_STAGE[s].completionTokens || 0);
|
|
660
|
+
const reasoning = stages.map(s => LLM_BY_STAGE[s].reasoningTokens || 0);
|
|
661
|
+
mkChart('chartLlmStages', {
|
|
662
|
+
tooltip: { ...baseTooltip, trigger: 'axis', axisPointer: { type: 'shadow' } },
|
|
663
|
+
legend: { ...baseLegend, data: ['Prompt', 'Completion', 'Reasoning'] },
|
|
664
|
+
grid: { left: 8, right: 24, top: 28, bottom: 8, containLabel: true },
|
|
665
|
+
xAxis: { type: 'value', ...baseAxis },
|
|
666
|
+
yAxis: { type: 'category', data: labels, ...baseAxis },
|
|
667
|
+
series: [
|
|
668
|
+
{ name: 'Prompt', type: 'bar', stack: 'tok', itemStyle: { color: 'rgba(88,166,255,0.8)' }, data: prompt },
|
|
669
|
+
{ name: 'Completion', type: 'bar', stack: 'tok', itemStyle: { color: 'rgba(63,185,80,0.8)' }, data: completion },
|
|
670
|
+
{ name: 'Reasoning', type: 'bar', stack: 'tok', itemStyle: { color: 'rgba(188,140,255,0.8)' }, data: reasoning },
|
|
671
|
+
],
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// ── Recent runs table ─────────────────────────────────────────────────────────
|
|
676
|
+
function renderLastRuns(rs) {
|
|
537
677
|
const tbody = document.getElementById('lastRunsTable');
|
|
538
|
-
|
|
678
|
+
tbody.innerHTML = '';
|
|
679
|
+
[...rs].reverse().forEach(r => {
|
|
539
680
|
const tr = document.createElement('tr');
|
|
540
|
-
const
|
|
681
|
+
const d = new Date(r.startedAt);
|
|
682
|
+
const pad = n => String(n).padStart(2, '0');
|
|
683
|
+
const ts = `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
541
684
|
const dur = r.wallTimeMs ? (r.wallTimeMs / 60000).toFixed(1) + 'm' : '—';
|
|
685
|
+
const task = r.taskId || 'manual';
|
|
542
686
|
const badge = r.ok
|
|
543
687
|
? '<span class="badge-pill badge-pass" style="padding:2px 8px;font-size:11px;"><span class="dot dot-pass" style="width:6px;height:6px;"></span> ok</span>'
|
|
544
688
|
: '<span class="badge-pill badge-fail" style="padding:2px 8px;font-size:11px;"><span class="dot dot-fail" style="width:6px;height:6px;"></span> failed</span>';
|
|
545
689
|
tr.innerHTML = `
|
|
546
690
|
<td style="font-family:monospace;font-size:12px;">${ts}</td>
|
|
691
|
+
<td><code>${task}</code></td>
|
|
547
692
|
<td>${dur}</td>
|
|
548
693
|
<td style="color:var(--accent);font-weight:600;">${r.promoted || 0}</td>
|
|
549
694
|
<td>${r.merged || 0}</td>
|
|
@@ -555,6 +700,31 @@ RUNS.slice(-10).forEach(r => {
|
|
|
555
700
|
`;
|
|
556
701
|
tbody.appendChild(tr);
|
|
557
702
|
});
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function updateFilteredViews() {
|
|
706
|
+
const rs = filteredRuns();
|
|
707
|
+
renderCharts(rs);
|
|
708
|
+
renderLastRuns(rs);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
populateFilters();
|
|
712
|
+
document.getElementById('rangeSelect').addEventListener('change', updateFilteredViews);
|
|
713
|
+
document.getElementById('taskFilter').addEventListener('change', updateFilteredViews);
|
|
714
|
+
document.getElementById('statusFilter').addEventListener('change', updateFilteredViews);
|
|
715
|
+
renderLlmStages();
|
|
716
|
+
updateFilteredViews();
|
|
717
|
+
|
|
718
|
+
// Reformat server-rendered ISO timestamps to the viewer's local timezone.
|
|
719
|
+
(function() {
|
|
720
|
+
const pad = n => String(n).padStart(2, '0');
|
|
721
|
+
document.querySelectorAll('time[data-iso]').forEach(el => {
|
|
722
|
+
const d = new Date(el.dataset.iso);
|
|
723
|
+
if (!isNaN(d)) {
|
|
724
|
+
el.textContent = `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
})();
|
|
558
728
|
</script>
|
|
559
729
|
</body>
|
|
560
730
|
</html>
|