@linxiraos/pi-tui 1.1.27 → 1.2.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 +50 -461
- package/README.md +7 -5
- package/dist/types/app-keybindings.d.ts +1 -1
- package/dist/types/apps/cleanse-board.d.ts +1 -1
- package/dist/types/apps/debug/log-viewer.d.ts +4 -0
- package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
- package/dist/types/apps/git/git-tui.d.ts +2 -2
- package/dist/types/apps/git/help.d.ts +3 -1
- package/dist/types/apps/if-bench-board.d.ts +2 -2
- package/dist/types/apps/setup-model-picker.d.ts +1 -1
- package/dist/types/autocomplete.d.ts +5 -2
- package/dist/types/charts/chart-plan.d.ts +674 -0
- package/dist/types/charts/chart-svg.d.ts +59 -0
- package/dist/types/charts/table-data.d.ts +175 -0
- package/dist/types/chat/assistant-message.d.ts +5 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +2 -0
- package/dist/types/chat/compaction-summary-message.d.ts +1 -0
- package/dist/types/chat/execution-shared.d.ts +6 -5
- package/dist/types/chat/fence-figure.d.ts +42 -0
- package/dist/types/chat/figure-markdown.d.ts +42 -0
- package/dist/types/chat/messages.d.ts +1 -1
- package/dist/types/chat/svg-figure.d.ts +33 -0
- package/dist/types/chat/svg-source.d.ts +49 -0
- package/dist/types/chat/table-chart.d.ts +89 -0
- package/dist/types/chat/tool-execution.d.ts +2 -0
- package/dist/types/chat/user-message.d.ts +15 -2
- package/dist/types/chrome/shared.d.ts +9 -0
- package/dist/types/chrome/transcript-container.d.ts +6 -0
- package/dist/types/components/box.d.ts +1 -0
- package/dist/types/components/disclosure.d.ts +1 -0
- package/dist/types/components/editor.d.ts +15 -4
- package/dist/types/components/form.d.ts +1 -0
- package/dist/types/components/image.d.ts +12 -44
- package/dist/types/components/key-value-list.d.ts +1 -0
- package/dist/types/components/layout/row.d.ts +1 -0
- package/dist/types/components/layout/stack.d.ts +1 -0
- package/dist/types/components/markdown.d.ts +36 -3
- package/dist/types/components/scroll-view.d.ts +1 -0
- package/dist/types/components/section.d.ts +1 -0
- package/dist/types/components/table.d.ts +1 -0
- package/dist/types/components/text.d.ts +1 -0
- package/dist/types/components/tree-view.d.ts +7 -0
- package/dist/types/components/truncated-text.d.ts +1 -0
- package/dist/types/fuzzy.d.ts +29 -1
- package/dist/types/key-hint-format.d.ts +1 -1
- package/dist/types/keybinding-matchers.d.ts +3 -0
- package/dist/types/keybindings.d.ts +1 -1
- package/dist/types/kitty-graphics.d.ts +2 -2
- package/dist/types/loop-watchdog.d.ts +8 -7
- package/dist/types/multiplexers/cmux.d.ts +16 -0
- package/dist/types/multiplexers/herdr.d.ts +26 -0
- package/dist/types/multiplexers/notify.d.ts +13 -0
- package/dist/types/multiplexers/orca.d.ts +12 -0
- package/dist/types/multiplexers/screen.d.ts +9 -0
- package/dist/types/multiplexers/tmux.d.ts +29 -0
- package/dist/types/multiplexers/types.d.ts +100 -0
- package/dist/types/multiplexers/wmux.d.ts +12 -0
- package/dist/types/multiplexers/zellij.d.ts +12 -0
- package/dist/types/native/backend.d.ts +3 -2
- package/dist/types/native/blobs.d.ts +7 -3
- package/dist/types/native/encode.d.ts +3 -4
- package/dist/types/native/overlay.d.ts +5 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
- package/dist/types/overlays/agent-hub-types.d.ts +9 -0
- package/dist/types/overlays/agent-hub.d.ts +2 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +11 -2
- package/dist/types/overlays/agents-hub.d.ts +9 -0
- package/dist/types/overlays/annotation-overlay.d.ts +19 -2
- package/dist/types/overlays/annotation-types.d.ts +2 -0
- package/dist/types/overlays/ask-dialog.d.ts +5 -2
- package/dist/types/overlays/history-search.d.ts +10 -0
- package/dist/types/overlays/hook-selector.d.ts +9 -4
- package/dist/types/overlays/jobs-panel.d.ts +1 -7
- package/dist/types/overlays/model-browser.d.ts +54 -7
- package/dist/types/overlays/model-hub.d.ts +23 -0
- package/dist/types/overlays/oauth-selector.d.ts +0 -1
- package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
- package/dist/types/overlays/session-observer-registry.d.ts +2 -0
- package/dist/types/overlays/session-selector.d.ts +6 -2
- package/dist/types/overlays/settings-defs.d.ts +1 -0
- package/dist/types/overlays/usage-dashboard.d.ts +8 -4
- package/dist/types/overlays/usage-display.d.ts +3 -1
- package/dist/types/prompt/composer.d.ts +2 -7
- package/dist/types/prompt/custom-editor.d.ts +11 -8
- package/dist/types/prompt/image-source.d.ts +2 -1
- package/dist/types/prompt/interactive-context-helpers.d.ts +4 -1
- package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
- package/dist/types/prompt/welcome.d.ts +19 -42
- package/dist/types/render/composite.d.ts +2 -0
- package/dist/types/render/output-pane.d.ts +1 -0
- package/dist/types/render/render-utils.d.ts +1 -0
- package/dist/types/render/tool-card.d.ts +6 -0
- package/dist/types/render/width-aware-text.d.ts +2 -0
- package/dist/types/setup/scenes/splash.d.ts +1 -1
- package/dist/types/setup/scenes/types.d.ts +1 -0
- package/dist/types/status-line/component.d.ts +3 -0
- package/dist/types/status-line/host.d.ts +4 -1
- package/dist/types/status-line/segments.d.ts +2 -0
- package/dist/types/status-line/types.d.ts +14 -3
- package/dist/types/terminal-capabilities.d.ts +27 -35
- package/dist/types/terminal-multiplexer.d.ts +127 -14
- package/dist/types/terminal.d.ts +22 -6
- package/dist/types/theme/active-symbols.d.ts +1 -1
- package/dist/types/theme/schema.d.ts +11 -2
- package/dist/types/theme/symbols.d.ts +1 -1
- package/dist/types/theme/theme-class.d.ts +7 -0
- package/dist/types/theme/theme.d.ts +1 -1
- package/dist/types/theme/tui-adapters.d.ts +3 -0
- package/dist/types/tmux.d.ts +11 -4
- package/dist/types/tools/daemon.d.ts +1 -1
- package/dist/types/tools/eval.d.ts +22 -3
- package/dist/types/tools/glob.d.ts +4 -0
- package/dist/types/tools/native-view.d.ts +47 -0
- package/dist/types/tools/output-meta.d.ts +11 -1
- package/dist/types/tools/renderer.d.ts +37 -2
- package/dist/types/tools/streaming-output.d.ts +20 -1
- package/dist/types/tools/task.d.ts +0 -4
- package/dist/types/tools/write.d.ts +9 -2
- package/dist/types/tools/yield.d.ts +22 -0
- package/dist/types/tui.d.ts +31 -0
- package/dist/types/utils.d.ts +6 -0
- package/dist/types/vim.d.ts +19 -5
- package/package.json +13 -9
- package/src/app-keybindings.d.ts +1 -1
- package/src/app-keybindings.ts +1 -1
- package/src/apps/autoresearch-dashboard.ts +7 -3
- package/src/apps/cleanse-board.ts +2 -2
- package/src/apps/cleanse-picker.ts +1 -1
- package/src/apps/debug/log-viewer.ts +188 -72
- package/src/apps/debug/raw-sse-buffer.ts +8 -0
- package/src/apps/debug/raw-sse.ts +39 -5
- package/src/apps/git/diff-pane.ts +26 -5
- package/src/apps/git/git-tui.ts +2 -2
- package/src/apps/git/help.ts +29 -20
- package/src/apps/if-bench-board.ts +2 -2
- package/src/apps/ps-top.ts +2 -2
- package/src/apps/setup-model-picker.ts +1 -1
- package/src/autocomplete.d.ts +5 -2
- package/src/autocomplete.ts +67 -43
- package/src/charts/chart-plan.d.ts +674 -0
- package/src/charts/chart-plan.ts +5081 -0
- package/src/charts/chart-svg.d.ts +59 -0
- package/src/charts/chart-svg.ts +4657 -0
- package/src/charts/table-data.d.ts +175 -0
- package/src/charts/table-data.ts +1478 -0
- package/src/chat/advisor-message.ts +11 -0
- package/src/chat/assistant-message.d.ts +5 -0
- package/src/chat/assistant-message.ts +219 -50
- package/src/chat/chat-transcript-builder.d.ts +2 -0
- package/src/chat/chat-transcript-builder.ts +5 -3
- package/src/chat/compaction-summary-message.d.ts +1 -0
- package/src/chat/compaction-summary-message.ts +8 -0
- package/src/chat/execution-shared.d.ts +6 -5
- package/src/chat/execution-shared.ts +42 -25
- package/src/chat/fence-figure.d.ts +42 -0
- package/src/chat/fence-figure.ts +80 -0
- package/src/chat/figure-markdown.d.ts +42 -0
- package/src/chat/figure-markdown.ts +174 -0
- package/src/chat/messages.d.ts +1 -1
- package/src/chat/messages.ts +1 -1
- package/src/chat/read-tool-group.ts +6 -4
- package/src/chat/skill-message.ts +6 -0
- package/src/chat/svg-figure.d.ts +33 -0
- package/src/chat/svg-figure.ts +399 -0
- package/src/chat/svg-source.d.ts +49 -0
- package/src/chat/svg-source.ts +188 -0
- package/src/chat/table-chart.d.ts +89 -0
- package/src/chat/table-chart.ts +294 -0
- package/src/chat/tool-execution.d.ts +2 -0
- package/src/chat/tool-execution.ts +80 -6
- package/src/chat/user-message.d.ts +15 -2
- package/src/chat/user-message.ts +55 -3
- package/src/chrome/shared.ts +53 -0
- package/src/chrome/transcript-container.d.ts +6 -0
- package/src/chrome/transcript-container.ts +93 -13
- package/src/components/box.d.ts +1 -0
- package/src/components/box.ts +5 -0
- package/src/components/disclosure.d.ts +1 -0
- package/src/components/disclosure.ts +8 -0
- package/src/components/editor.d.ts +15 -4
- package/src/components/editor.ts +294 -46
- package/src/components/form.d.ts +1 -0
- package/src/components/form.ts +8 -0
- package/src/components/image.d.ts +12 -44
- package/src/components/image.ts +47 -151
- package/src/components/key-value-list.d.ts +1 -0
- package/src/components/key-value-list.ts +4 -0
- package/src/components/layout/row.d.ts +1 -0
- package/src/components/layout/row.ts +7 -0
- package/src/components/layout/stack.d.ts +1 -0
- package/src/components/layout/stack.ts +7 -0
- package/src/components/markdown.d.ts +36 -3
- package/src/components/markdown.ts +433 -318
- package/src/components/scroll-view.d.ts +1 -0
- package/src/components/scroll-view.ts +5 -0
- package/src/components/section.d.ts +1 -0
- package/src/components/section.ts +5 -0
- package/src/components/settings-list.ts +2 -0
- package/src/components/table.d.ts +1 -0
- package/src/components/table.ts +4 -0
- package/src/components/text.d.ts +1 -0
- package/src/components/text.ts +7 -0
- package/src/components/tree-view.d.ts +7 -0
- package/src/components/tree-view.ts +38 -8
- package/src/components/truncated-text.d.ts +1 -0
- package/src/components/truncated-text.ts +5 -0
- package/src/desktop-notify.ts +1 -1
- package/src/fuzzy.d.ts +29 -1
- package/src/fuzzy.ts +115 -30
- package/src/key-hint-format.d.ts +1 -1
- package/src/key-hint-format.ts +1 -1
- package/src/keybinding-matchers.d.ts +3 -0
- package/src/keybinding-matchers.ts +6 -2
- package/src/keybindings.d.ts +1 -1
- package/src/keybindings.ts +1 -1
- package/src/kitty-graphics.d.ts +2 -2
- package/src/kitty-graphics.ts +4 -4
- package/src/loop-watchdog.d.ts +8 -7
- package/src/loop-watchdog.ts +18 -13
- package/src/multiplexers/cmux.d.ts +16 -0
- package/src/multiplexers/cmux.ts +29 -0
- package/src/multiplexers/herdr.d.ts +26 -0
- package/src/multiplexers/herdr.ts +64 -0
- package/src/multiplexers/notify.d.ts +13 -0
- package/src/multiplexers/notify.ts +24 -0
- package/src/multiplexers/orca.d.ts +12 -0
- package/src/multiplexers/orca.ts +16 -0
- package/src/multiplexers/screen.d.ts +9 -0
- package/src/multiplexers/screen.ts +15 -0
- package/src/multiplexers/tmux.d.ts +29 -0
- package/src/multiplexers/tmux.ts +40 -0
- package/src/multiplexers/types.d.ts +100 -0
- package/src/multiplexers/types.ts +110 -0
- package/src/multiplexers/wmux.d.ts +12 -0
- package/src/multiplexers/wmux.ts +16 -0
- package/src/multiplexers/zellij.d.ts +12 -0
- package/src/multiplexers/zellij.ts +24 -0
- package/src/native/backend.d.ts +3 -2
- package/src/native/backend.ts +174 -18
- package/src/native/blobs.d.ts +7 -3
- package/src/native/blobs.ts +47 -12
- package/src/native/encode.d.ts +3 -4
- package/src/native/encode.ts +58 -31
- package/src/native/overlay.d.ts +5 -0
- package/src/native/overlay.ts +13 -0
- package/src/native/reconcile.ts +4 -0
- package/src/overlays/agent-hub-projection.d.ts +6 -5
- package/src/overlays/agent-hub-projection.ts +124 -13
- package/src/overlays/agent-hub-types.d.ts +9 -0
- package/src/overlays/agent-hub-types.ts +6 -0
- package/src/overlays/agent-hub.ts +46 -31
- package/src/overlays/agent-transcript-viewer.ts +91 -23
- package/src/overlays/agents-hub.ts +28 -8
- package/src/overlays/annotation-overlay.ts +293 -90
- package/src/overlays/annotation-types.ts +2 -0
- package/src/overlays/ask-dialog.ts +7 -10
- package/src/overlays/btw-history-panel.ts +12 -1
- package/src/overlays/copy-selector.ts +30 -8
- package/src/overlays/extensions/state-manager.ts +52 -12
- package/src/overlays/history-search.ts +100 -7
- package/src/overlays/hook-selector.ts +12 -5
- package/src/overlays/jobs-panel.ts +28 -46
- package/src/overlays/model-browser.ts +341 -110
- package/src/overlays/model-hub.ts +300 -49
- package/src/overlays/move-overlay.ts +28 -14
- package/src/overlays/oauth-selector.ts +54 -70
- package/src/overlays/plan-review-overlay.ts +194 -70
- package/src/overlays/plugin-settings.ts +11 -5
- package/src/overlays/report-panel.ts +2 -2
- package/src/overlays/rewind-selector.ts +86 -17
- package/src/overlays/session-observer-registry.d.ts +2 -0
- package/src/overlays/session-observer-registry.ts +10 -2
- package/src/overlays/session-selector.ts +64 -26
- package/src/overlays/settings-defs.ts +4 -3
- package/src/overlays/settings-selector.ts +33 -8
- package/src/overlays/snapcompact-shape-preview.ts +2 -3
- package/src/overlays/stats-notice.ts +1 -1
- package/src/overlays/tree-selector.ts +41 -20
- package/src/overlays/usage-dashboard.ts +100 -50
- package/src/overlays/usage-display.ts +10 -4
- package/src/prompt/attachment-chips.ts +15 -11
- package/src/prompt/composer-attachments.ts +6 -4
- package/src/prompt/composer-cache.ts +4 -6
- package/src/prompt/composer.ts +6 -37
- package/src/prompt/custom-editor.ts +54 -26
- package/src/prompt/image-source.ts +2 -1
- package/src/prompt/interactive-context-helpers.ts +30 -18
- package/src/prompt/macos-spelling.ts +7 -0
- package/src/prompt/magic-keywords.ts +11 -2
- package/src/prompt/model-mention-autocomplete.ts +14 -14
- package/src/prompt/tips.txt +6 -5
- package/src/prompt/welcome.ts +235 -411
- package/src/prompt/word-completion.ts +38 -5
- package/src/render/composite.d.ts +2 -0
- package/src/render/composite.ts +64 -0
- package/src/render/output-pane.d.ts +1 -0
- package/src/render/output-pane.ts +6 -0
- package/src/render/render-utils.d.ts +1 -0
- package/src/render/render-utils.ts +11 -0
- package/src/render/tool-card.d.ts +6 -0
- package/src/render/tool-card.ts +15 -0
- package/src/render/width-aware-text.d.ts +2 -0
- package/src/render/width-aware-text.ts +5 -0
- package/src/setup/scenes/model.ts +2 -1
- package/src/setup/scenes/splash.ts +116 -53
- package/src/setup/scenes/types.ts +1 -0
- package/src/status-line/component.ts +292 -78
- package/src/status-line/host.ts +4 -1
- package/src/status-line/segments.ts +40 -22
- package/src/status-line/types.ts +15 -3
- package/src/terminal-capabilities.d.ts +27 -35
- package/src/terminal-capabilities.ts +75 -189
- package/src/terminal-multiplexer.d.ts +127 -14
- package/src/terminal-multiplexer.ts +112 -33
- package/src/terminal.d.ts +22 -6
- package/src/terminal.ts +139 -37
- package/src/theme/active-symbols.d.ts +1 -1
- package/src/theme/active-symbols.ts +1 -1
- package/src/theme/schema-validation.ts +1 -0
- package/src/theme/schema.d.ts +11 -2
- package/src/theme/schema.ts +14 -1
- package/src/theme/session-color.ts +1 -7
- package/src/theme/symbols.d.ts +1 -1
- package/src/theme/symbols.ts +6 -1
- package/src/theme/theme-class.d.ts +7 -0
- package/src/theme/theme-class.ts +26 -1
- package/src/theme/theme-schema.json +5 -1
- package/src/theme/theme.d.ts +1 -1
- package/src/theme/theme.ts +8 -4
- package/src/theme/tui-adapters.d.ts +3 -0
- package/src/theme/tui-adapters.ts +68 -0
- package/src/tmux.d.ts +11 -4
- package/src/tmux.ts +47 -11
- package/src/tools/ast-edit.ts +59 -35
- package/src/tools/ast-grep.ts +35 -16
- package/src/tools/bash.ts +92 -42
- package/src/tools/daemon.d.ts +1 -1
- package/src/tools/daemon.ts +1 -1
- package/src/tools/default-renderer.ts +35 -19
- package/src/tools/edit.ts +142 -120
- package/src/tools/eval-format/index.ts +28 -2
- package/src/tools/eval-format/javascript.ts +7 -5
- package/src/tools/eval.d.ts +22 -3
- package/src/tools/eval.ts +364 -208
- package/src/tools/fetch.ts +5 -6
- package/src/tools/glob.d.ts +4 -0
- package/src/tools/glob.ts +33 -65
- package/src/tools/grep.ts +81 -48
- package/src/tools/index.ts +2 -0
- package/src/tools/lsp.ts +81 -59
- package/src/tools/mcp.ts +111 -68
- package/src/tools/native-view.d.ts +47 -0
- package/src/tools/native-view.ts +102 -1
- package/src/tools/output-meta.d.ts +11 -1
- package/src/tools/output-meta.ts +23 -3
- package/src/tools/read.ts +7 -5
- package/src/tools/renderer.d.ts +37 -2
- package/src/tools/renderer.ts +42 -2
- package/src/tools/streaming-output.d.ts +20 -1
- package/src/tools/streaming-output.ts +149 -50
- package/src/tools/task.d.ts +0 -4
- package/src/tools/task.ts +112 -59
- package/src/tools/todo.ts +119 -30
- package/src/tools/wait.ts +34 -24
- package/src/tools/web-search.ts +1 -1
- package/src/tools/write.d.ts +9 -2
- package/src/tools/write.ts +147 -95
- package/src/tools/yield.d.ts +22 -0
- package/src/tools/yield.ts +225 -0
- package/src/tui.d.ts +31 -0
- package/src/tui.ts +309 -160
- package/src/utils.d.ts +6 -0
- package/src/utils.ts +19 -0
- package/src/vim.d.ts +19 -5
- package/src/vim.ts +333 -18
- package/src/windows-input-mode.ts +8 -0
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which chart a table becomes and the data it plots. {@link planChart} is the
|
|
3
|
+
* local best guess over a {@link TableAnalysis}: the chart kind, the label
|
|
4
|
+
* column and the measure columns to draw. A host may substitute its own
|
|
5
|
+
* {@link ChartPlan} (a model's pick for a multi-series table); either way
|
|
6
|
+
* {@link buildChart} turns it into the {@link ChartSpec} that
|
|
7
|
+
* {@link renderChartSvg} draws, and {@link worthCharting} decides whether
|
|
8
|
+
* the picture says more than the table already does.
|
|
9
|
+
*
|
|
10
|
+
* The heuristics were fitted on ~7k tables from real assistant answers: the
|
|
11
|
+
* label is the first text column (index columns like `#`/`Rank` never are),
|
|
12
|
+
* table order is kept (most tables are deliberately unsorted), total rows stay
|
|
13
|
+
* out of the scale, and units never share an axis. Rows whose labels repeat
|
|
14
|
+
* (`Model | Harness | …`) are named by the text columns that tell them apart
|
|
15
|
+
* ({@link ChartPlan.qualifiers}), nested under one of them
|
|
16
|
+
* ({@link ChartPlan.group}) when it already runs in blocks; otherwise names
|
|
17
|
+
* sharing a leading part nest under it (`glm new`, `glm prior`), and names are
|
|
18
|
+
* shortened for display wherever they stay distinct. A row named as the
|
|
19
|
+
* baseline becomes the {@link ChartPlan.reference} the others read against;
|
|
20
|
+
* before/after values spanning decades, or rows of very different sizes
|
|
21
|
+
* beside a baseline column, draw as factors of change.
|
|
22
|
+
*
|
|
23
|
+
* A plan also carries what the table means ({@link guessMeaning} locally, a
|
|
24
|
+
* judge's answers in `smart` mode): which way each measure improves, what
|
|
25
|
+
* competes, the rows it is about, a status column, and the one
|
|
26
|
+
* {@link tableTakeaways | takeaway} stated as its title.
|
|
27
|
+
*/
|
|
28
|
+
import { type Dimension, type Status, type TableAnalysis, type TableColumn } from "./table-data.js";
|
|
29
|
+
/**
|
|
30
|
+
* Which way a measure improves: `higher` (pass rate, throughput, speedup) or
|
|
31
|
+
* `lower` (cost, latency, errors). Measures that improve neither way (counts,
|
|
32
|
+
* sizes, shares, ids) have none.
|
|
33
|
+
*/
|
|
34
|
+
export type Polarity = "higher" | "lower";
|
|
35
|
+
/** Which way a table's alternatives run: down its rows or across its plotted columns. */
|
|
36
|
+
export type Rivals = "rows" | "columns";
|
|
37
|
+
/**
|
|
38
|
+
* Chart kinds, by the table shapes they fit:
|
|
39
|
+
* - `bar`: one measure across categories.
|
|
40
|
+
* - `paired`: one quantity under two conditions per category (before/after, old vs new), or `a → b` cells.
|
|
41
|
+
* - `grouped`: two to four same-unit measures per category that are not one before/after pair.
|
|
42
|
+
* - `stacked`: same-unit parts of one whole per category (`Cached + Uncached input + Output = Total`), one segmented bar each;
|
|
43
|
+
* outcome counts (`ok | fail`) as each category's mix ({@link ChartPlan.normalize}).
|
|
44
|
+
* - `line`: measures over an ordered axis (dates, runs, sizes).
|
|
45
|
+
* - `heatmap`: a matrix of same-unit values.
|
|
46
|
+
* - `multiples`: measures in different units, each scaled on its own; transposed when each row is its own metric.
|
|
47
|
+
* - `share`: parts of a whole in one bar: percentages summing to 100, or counts splitting one total (items by status).
|
|
48
|
+
* - `diverging`: signed changes around zero.
|
|
49
|
+
* - `scatter`: two continuous measures per item.
|
|
50
|
+
* - `change`: metrics in different units against a baseline column (before/after), as factors.
|
|
51
|
+
* - `progress`: scores out of a total (`12/12`), as filled tracks.
|
|
52
|
+
* - `timeline`: one measure's rows laid end to end on one axis, in table order or at an offset column
|
|
53
|
+
* (pipeline steps to time scale, parts of a buffer at their offsets).
|
|
54
|
+
* - `waterfall`: one measure's rows building up, step by step in table order, to their total (a total row
|
|
55
|
+
* or their sum), with any cap row as a rule.
|
|
56
|
+
* - `dots`: two to six same-unit series per category as dots on one shared axis (a Cleveland dot plot),
|
|
57
|
+
* logarithmic when the values span decades; generalizes the dumbbell beyond two series.
|
|
58
|
+
* - `range`: values written as `a–b` intervals, as floating bars from low to high, with an optional
|
|
59
|
+
* central estimate and a stated reference (a budget, a price, 1×); series in other units get their own band.
|
|
60
|
+
* - `slope`: each category's value at two to four ordered stages (`Baseline | Best (Iter 3) | Iter 4`),
|
|
61
|
+
* a line per category from stage to stage, labelled at both ends; moves toned by polarity.
|
|
62
|
+
* - `butterfly`: two opposing amounts per category (`Added | Removed`, `Wins | Losses`) as back-to-back
|
|
63
|
+
* bars from a shared spine, each row's net beside it.
|
|
64
|
+
* - `bullet`: one measured value per row against that row's own target, budget or limit (a `Target ≤ 200 µs`
|
|
65
|
+
* column), each as a share of its target on one axis: a bar (a `p50 / p99` span) to a target mark, toned by
|
|
66
|
+
* whether it stays on the target's side ({@link ChartPlan.target}).
|
|
67
|
+
* - `ladder`: quantiles of one measurement per category (`p50 | p90 | p99 | max` columns, `p50 / p99`
|
|
68
|
+
* cells), each row a line from its lowest quantile to its highest with a mark at each, on one shared
|
|
69
|
+
* axis (logarithmic when the tails span decades); one ladder per condition measured (`Startup`, `Wall`).
|
|
70
|
+
* - `histogram`: counts or shares over rows that are ordered bins (`1`, `2–5`, `6–20`, `100+`), as
|
|
71
|
+
* columns in bin order; two to four distributions side by side, as shares of each one's total when
|
|
72
|
+
* their totals differ ({@link ChartPlan.normalize}).
|
|
73
|
+
* - `stat`: a small table comparing two conditions (old vs new, on vs off) on one to four metrics, as a tile
|
|
74
|
+
* per metric: the factor between them in big figures over a short bar per condition ({@link statShape}).
|
|
75
|
+
*/
|
|
76
|
+
export type ChartKind = "bar" | "paired" | "grouped" | "line" | "heatmap" | "multiples" | "share" | "diverging" | "scatter" | "change" | "progress" | "stacked" | "timeline" | "waterfall" | "dots" | "range" | "slope" | "butterfly" | "bullet" | "ladder" | "histogram" | "stat";
|
|
77
|
+
/** What to draw from a table: the kind, the columns naming each category, and the columns plotted. */
|
|
78
|
+
export interface ChartPlan {
|
|
79
|
+
readonly kind: ChartKind;
|
|
80
|
+
/** Column naming each category (or holding the x values of a line); rows are numbered without one. */
|
|
81
|
+
readonly label: number | undefined;
|
|
82
|
+
/** Columns joined to the label to tell rows apart (`Sonnet 5.5 · bash`); none by default. */
|
|
83
|
+
readonly qualifiers?: readonly number[];
|
|
84
|
+
/**
|
|
85
|
+
* Naming column whose values nest the rows: rows regroup by its values in
|
|
86
|
+
* order of first appearance (table order within each), and a label column
|
|
87
|
+
* writes each value once beside its block. Lines keep their x order and ignore it.
|
|
88
|
+
*/
|
|
89
|
+
readonly group?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Plotted columns, in order; a `change` measures the rest against the first (or its `a → b` cells),
|
|
92
|
+
* a `slope` runs through them as stages, and a `butterfly` draws the first leftward (the losing side).
|
|
93
|
+
*/
|
|
94
|
+
readonly series: readonly number[];
|
|
95
|
+
/**
|
|
96
|
+
* `change` over metric pairs (`Baseline Turns | Iter1 Turns | Baseline Tokens
|
|
97
|
+
* In | Iter1 Tokens In`): the baseline column of each series, in order, so
|
|
98
|
+
* each series is measured against its own before column instead of the first.
|
|
99
|
+
*/
|
|
100
|
+
readonly baselines?: readonly number[];
|
|
101
|
+
/** Each data row is its own series (a metric with its own unit) and the plotted columns are the categories. */
|
|
102
|
+
readonly transpose: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Heatmap cells shaded on one scale across every cell (default), each
|
|
105
|
+
* series on its own, or each row on its own. A `series`-shaded heatmap of
|
|
106
|
+
* at most {@link MAX_PANELS} series draws as a grid of bars instead, each
|
|
107
|
+
* column on its own axis: its columns are different quantities.
|
|
108
|
+
*/
|
|
109
|
+
readonly shading?: Shading;
|
|
110
|
+
/**
|
|
111
|
+
* Rows whose `column` cell reads `value` are the reference the others are
|
|
112
|
+
* read against (`Harness` = `baseline`), one per group; none by default.
|
|
113
|
+
*/
|
|
114
|
+
readonly reference?: RowReference;
|
|
115
|
+
/**
|
|
116
|
+
* Rows ranked by a plotted column instead of table order (rankings,
|
|
117
|
+
* leaderboards); within each group when grouped. Lines and scatters keep
|
|
118
|
+
* their x order, `change` charts table order. Table order by default: most
|
|
119
|
+
* tables are deliberately ordered.
|
|
120
|
+
*/
|
|
121
|
+
readonly order?: RowOrder;
|
|
122
|
+
/**
|
|
123
|
+
* `stacked`: the column the plotted parts make up (`Total`), labelling each
|
|
124
|
+
* bar with its written figure and drawing any rest it holds beyond the parts
|
|
125
|
+
* as an unlabelled track. Without it a bar ends at the parts' sum.
|
|
126
|
+
*/
|
|
127
|
+
readonly whole?: number;
|
|
128
|
+
/**
|
|
129
|
+
* `stacked`: each bar spans 100% of its category's total (its whole, else
|
|
130
|
+
* its parts' sum), so rows of very different sizes compare by their mix.
|
|
131
|
+
* Absent: normalized when the parts are outcomes ({@link outcomeTones}:
|
|
132
|
+
* `ok | fail`, `Pass | Fail | Skip`), whose rates are the point, over
|
|
133
|
+
* totals {@link MIX_SPREAD}× apart or more.
|
|
134
|
+
* `histogram`: each distribution as shares of its own total, so populations
|
|
135
|
+
* of different sizes compare by shape. Absent: normalized when two or more
|
|
136
|
+
* count columns' totals lie {@link MIX_SPREAD}× apart or more.
|
|
137
|
+
*/
|
|
138
|
+
readonly normalize?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* `timeline`: the column holding each segment's start (`Offset`, `Start`),
|
|
141
|
+
* in the plotted column's dimension; without it segments follow one another
|
|
142
|
+
* in table order from zero.
|
|
143
|
+
*/
|
|
144
|
+
readonly offsets?: number;
|
|
145
|
+
/**
|
|
146
|
+
* `waterfall`: the row (by index) of a cap the steps build toward (`Hard
|
|
147
|
+
* cap`, `Budget`), drawn as a rule across the steps instead of a step.
|
|
148
|
+
*/
|
|
149
|
+
readonly limit?: number;
|
|
150
|
+
/**
|
|
151
|
+
* `bullet`: the column holding each row's target (`Target` `≤ 200 µs`, `§6
|
|
152
|
+
* budget`, `Limit`), which the one plotted series is measured against
|
|
153
|
+
* ({@link findTarget}).
|
|
154
|
+
*/
|
|
155
|
+
readonly target?: number;
|
|
156
|
+
/** Which way each column improves, by column index; neutral columns absent. */
|
|
157
|
+
readonly polarity?: Readonly<Record<number, Polarity>>;
|
|
158
|
+
/** Which way each row's metric improves, by row index, where rows are metrics ({@link rowsAreMetrics}). */
|
|
159
|
+
readonly rowPolarity?: Readonly<Record<number, Polarity>>;
|
|
160
|
+
/**
|
|
161
|
+
* What competes, so each contest's best value (by {@link polarity}) is
|
|
162
|
+
* marked: `rows` are alternatives scored by every measure (models,
|
|
163
|
+
* configs, arms: the best per column); `columns` are alternatives measured
|
|
164
|
+
* on every row (`Record | Map | string[]` per scenario: the best per row).
|
|
165
|
+
* Absent for parts of a whole, steps, or items described side by side.
|
|
166
|
+
*/
|
|
167
|
+
readonly rivals?: Rivals;
|
|
168
|
+
/** Rows the table is about (the recommended option, `current`, `ours`, the bolded row), by row index. */
|
|
169
|
+
readonly focus?: readonly number[];
|
|
170
|
+
/** Column whose status cells (`ok`, `FAIL`, `pending`, ✅) badge each row's name. */
|
|
171
|
+
readonly status?: number;
|
|
172
|
+
/** The chart's title: one fact stated over it, the text of one of {@link tableTakeaways}; none by default. */
|
|
173
|
+
readonly title?: string;
|
|
174
|
+
}
|
|
175
|
+
/** A naming cell marking reference rows: column index and cell text. */
|
|
176
|
+
export interface RowReference {
|
|
177
|
+
readonly column: number;
|
|
178
|
+
readonly value: string;
|
|
179
|
+
}
|
|
180
|
+
/** Rows sorted by `column`'s values, largest first (`descending`) or smallest first. */
|
|
181
|
+
export interface RowOrder {
|
|
182
|
+
readonly column: number;
|
|
183
|
+
readonly direction: "descending" | "ascending";
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* How a heatmap shades its cells: `shared` compares every cell with every
|
|
187
|
+
* other; `series` compares within each column (different quantities, like
|
|
188
|
+
* input vs. reasoning tokens), so one large column does not wash out the
|
|
189
|
+
* rest; `row` compares within each row (one measure across conditions, rows
|
|
190
|
+
* of very different sizes), so one large row does not wash out the rest.
|
|
191
|
+
*/
|
|
192
|
+
export type Shading = "shared" | "series" | "row";
|
|
193
|
+
/** One plotted value. */
|
|
194
|
+
export interface ChartPoint {
|
|
195
|
+
/** Value in base units (seconds, bytes, …). */
|
|
196
|
+
readonly value: number;
|
|
197
|
+
/** The number as the table wrote it (`~$250`, `12.5 ms`), shown as the value label. */
|
|
198
|
+
readonly text: string;
|
|
199
|
+
/** The table bolded the cell. */
|
|
200
|
+
readonly emphasis: boolean;
|
|
201
|
+
/** Upper end of a range cell (`24–72 h`). */
|
|
202
|
+
readonly upper?: number;
|
|
203
|
+
/** The spread a `± e` cell states around the value (`3.67s ± 0.69`), drawn as a whisker either side of it. */
|
|
204
|
+
readonly error?: number;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Which side of its target a value must stay: at or under it (`max`: `≤ 200
|
|
208
|
+
* µs`, a budget, a limit) or at or over it (`min`: `≥ 0.85`, `≥ 700 MB/s`).
|
|
209
|
+
*/
|
|
210
|
+
export type Bound = "max" | "min";
|
|
211
|
+
/**
|
|
212
|
+
* A row's target in a `bullet` chart, as the table wrote it: a value, or a
|
|
213
|
+
* window it must fall in (`60–100 ms`, its {@link ChartPoint.upper}), and the
|
|
214
|
+
* {@link Bound} the measure must keep; absent when neither the cell, the
|
|
215
|
+
* header nor the measure's polarity says which side.
|
|
216
|
+
*/
|
|
217
|
+
export interface ChartTarget extends ChartPoint {
|
|
218
|
+
readonly bound?: Bound;
|
|
219
|
+
}
|
|
220
|
+
export interface ChartSeries {
|
|
221
|
+
readonly name: string;
|
|
222
|
+
readonly dim: Dimension;
|
|
223
|
+
/** Currency symbol or rate unit the axis prints; empty for other dimensions. */
|
|
224
|
+
readonly unit: string;
|
|
225
|
+
/** One per category; `null` where the cell holds no number of this series' dimension. */
|
|
226
|
+
readonly points: readonly (ChartPoint | null)[];
|
|
227
|
+
/** Status words standing in for a value (`TIMEOUT`, `OOM`), one per category. */
|
|
228
|
+
readonly notes: readonly (string | undefined)[];
|
|
229
|
+
/** Which way the series improves; absent when neutral. */
|
|
230
|
+
readonly polarity?: Polarity;
|
|
231
|
+
/** Category of the series' best value, marked when its rows are rivals; absent when tied or neutral. */
|
|
232
|
+
readonly best?: number;
|
|
233
|
+
}
|
|
234
|
+
/** Consecutive categories sharing a leading name, which a label column writes once beside its members. */
|
|
235
|
+
export interface ChartGroup {
|
|
236
|
+
/** The shared name; empty for a run of rows outside every group, written as members only. */
|
|
237
|
+
readonly name: string;
|
|
238
|
+
/** The rest of each member category's name, in order; empty where the group's name alone names the row. */
|
|
239
|
+
readonly members: readonly string[];
|
|
240
|
+
}
|
|
241
|
+
/** The data a chart draws, independent of how it is drawn. */
|
|
242
|
+
export interface ChartSpec {
|
|
243
|
+
readonly kind: ChartKind;
|
|
244
|
+
/**
|
|
245
|
+
* One name per category: the label cell, joined with the cells that tell
|
|
246
|
+
* repeated labels apart (`Sonnet 5.5 · bash`); without groups, shortened
|
|
247
|
+
* for display where names stay distinct (`openai/gpt-5.5:xhi` → `gpt-5.5`).
|
|
248
|
+
*/
|
|
249
|
+
readonly categories: readonly string[];
|
|
250
|
+
/**
|
|
251
|
+
* `categories` nested under their {@link ChartPlan.group} values
|
|
252
|
+
* (`Sonnet 5.5` → `baseline`, `bash`, `http`), covering them in order; without
|
|
253
|
+
* a group, under a leading part their names share (`glm new`, `glm prior` →
|
|
254
|
+
* `glm` → `new`, `prior`). Absent when neither applies, or when each series is a row.
|
|
255
|
+
*/
|
|
256
|
+
readonly groups?: readonly ChartGroup[];
|
|
257
|
+
readonly series: readonly ChartSeries[];
|
|
258
|
+
/**
|
|
259
|
+
* Numeric x positions of a line, the x measure of a scatter, or each
|
|
260
|
+
* `timeline` segment's start ({@link ChartPlan.offsets}), one per category.
|
|
261
|
+
*/
|
|
262
|
+
readonly x?: {
|
|
263
|
+
readonly name: string;
|
|
264
|
+
readonly dim: Dimension;
|
|
265
|
+
readonly unit: string;
|
|
266
|
+
readonly values: readonly number[];
|
|
267
|
+
};
|
|
268
|
+
/** Total/summary rows, printed under the chart instead of skewing its scale. */
|
|
269
|
+
readonly caption?: string;
|
|
270
|
+
/** Name of the category axis: the headers of the columns naming the rows. */
|
|
271
|
+
readonly axis: string;
|
|
272
|
+
/** What a `change` measures against (its baseline column); its points are factors of it. */
|
|
273
|
+
readonly baseline?: string;
|
|
274
|
+
/**
|
|
275
|
+
* The `change` is measured against a rival column — the one leading most rows — rather than a before
|
|
276
|
+
* state: its bars are gaps to that rival (`+22%` slower than `tsc-rs, 8`), never improvements or regressions.
|
|
277
|
+
*/
|
|
278
|
+
readonly rival?: boolean;
|
|
279
|
+
/** How a heatmap shades its cells; `shared` when absent. */
|
|
280
|
+
readonly shading?: Shading;
|
|
281
|
+
/**
|
|
282
|
+
* Indices of the categories the others read against ({@link ChartPlan.reference}),
|
|
283
|
+
* at most one per group: bars and bar grids mark each with a dashed rule at
|
|
284
|
+
* its value through its group, and single bars print the others' change from it.
|
|
285
|
+
*/
|
|
286
|
+
readonly reference?: readonly number[];
|
|
287
|
+
/** `stacked`: the whole each category's parts make up ({@link ChartPlan.whole}), one point per category. */
|
|
288
|
+
readonly whole?: ChartSeries;
|
|
289
|
+
/**
|
|
290
|
+
* `stacked`: each bar is its category's mix, parts as percentages of its total; `histogram`: each
|
|
291
|
+
* distribution as shares of its own total ({@link ChartPlan.normalize}).
|
|
292
|
+
*/
|
|
293
|
+
readonly normalized?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Outcome of each part of a whole, coloring it `success`/`warning`/`error`/
|
|
296
|
+
* `muted` instead of a series color: per series of a `stacked` chart
|
|
297
|
+
* (`ok | fail` headers), per category of a `share` (`✅ Resolved`, `❌ Remaining`);
|
|
298
|
+
* `undefined` for a part naming none. Absent unless most parts read as
|
|
299
|
+
* statuses ({@link outcomeTones}) and they are not all alike.
|
|
300
|
+
*/
|
|
301
|
+
readonly tones?: readonly (Status | undefined)[];
|
|
302
|
+
/**
|
|
303
|
+
* `waterfall`: the bar the steps build to — the table's total row as
|
|
304
|
+
* written, else the steps' sum written like their figures (`~$8.0M`).
|
|
305
|
+
*/
|
|
306
|
+
readonly total?: {
|
|
307
|
+
readonly name: string;
|
|
308
|
+
readonly point: ChartPoint;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* `range`: the central estimate of the first series' intervals, one point per category, from a
|
|
312
|
+
* plotted column whose values all fall inside them (`≈ $6,700` beside `$6.0k–7.3k`); drawn as a tick.
|
|
313
|
+
*/
|
|
314
|
+
readonly estimate?: ChartSeries;
|
|
315
|
+
/**
|
|
316
|
+
* `bullet`: each category's target ({@link ChartPlan.target}), against the
|
|
317
|
+
* first series' point; `null` where the row states none in its unit.
|
|
318
|
+
*/
|
|
319
|
+
readonly targets?: readonly (ChartTarget | null)[];
|
|
320
|
+
/** `bullet`: what the targets are called, lowercased from their header (`target`, `budget`, `limit`). */
|
|
321
|
+
readonly targetName?: string;
|
|
322
|
+
/**
|
|
323
|
+
* The one fact the chart states over it ({@link ChartPlan.title}: `Every
|
|
324
|
+
* scenario improved (median 14× less)`); no title line without one.
|
|
325
|
+
*/
|
|
326
|
+
readonly title?: string;
|
|
327
|
+
/**
|
|
328
|
+
* Muted note beside the title. Absent: the renderer writes how the chart
|
|
329
|
+
* encodes the data where that is not obvious (`log scale`, `scaled per column`).
|
|
330
|
+
*/
|
|
331
|
+
readonly subtitle?: string;
|
|
332
|
+
/**
|
|
333
|
+
* The two series of a `paired` chart are one quantity before and after
|
|
334
|
+
* (`a → b` cells, before/after headers per {@link isTransition}): drawn as a
|
|
335
|
+
* transition — a hollow muted start, a connector fading into the lead color,
|
|
336
|
+
* a solid end, and the figures as `a → b`. Otherwise the pair are peers
|
|
337
|
+
* (`xutf` vs `std`, two conditions without an order) drawn in two series
|
|
338
|
+
* colors without direction. Only condition pairs ({@link isConditionPair} or
|
|
339
|
+
* the judge's `pair`) draw as `paired` at all. A `ladder`'s two ladders
|
|
340
|
+
* (`before fix` | `after fix`) by the same reading: the first muted.
|
|
341
|
+
*/
|
|
342
|
+
readonly transition?: boolean;
|
|
343
|
+
/** Marks laid over the chart by a planner: reference lines, highlighted categories, callouts. */
|
|
344
|
+
readonly annotations?: readonly ChartAnnotation[];
|
|
345
|
+
/**
|
|
346
|
+
* Each series is a table row (a metric in its own unit) and the categories
|
|
347
|
+
* are the plotted columns ({@link ChartPlan.transpose}); {@link axis} then
|
|
348
|
+
* names the series rather than the categories.
|
|
349
|
+
*/
|
|
350
|
+
readonly transposed?: boolean;
|
|
351
|
+
/** Which way each category's metric improves where categories are metrics or items moving by a factor (`change`); neutral absent. */
|
|
352
|
+
readonly categoryPolarity?: readonly (Polarity | undefined)[];
|
|
353
|
+
/**
|
|
354
|
+
* Per category, the series holding its best value where the plotted
|
|
355
|
+
* columns are rivals sharing a unit and a polarity; absent where tied.
|
|
356
|
+
*/
|
|
357
|
+
readonly leaders?: readonly (number | undefined)[];
|
|
358
|
+
/** Status of each category (`ok`, `FAIL`, `pending`), badged beside its name. */
|
|
359
|
+
readonly status?: readonly (Status | undefined)[];
|
|
360
|
+
/** Header of the column the {@link status} badges come from, named in their key. */
|
|
361
|
+
readonly statusName?: string;
|
|
362
|
+
/**
|
|
363
|
+
* Status columns the chart does not plot (`Preserves layout? | Machine-parseable? | Renderable?`),
|
|
364
|
+
* drawn as a matrix of status dots between the row names and the marks, each column headed by its
|
|
365
|
+
* name; two to {@link MAX_MATRIX}, in place of the single {@link status} badge.
|
|
366
|
+
*/
|
|
367
|
+
readonly matrix?: readonly StatusColumn[];
|
|
368
|
+
/**
|
|
369
|
+
* `ladder`: the series of each ladder drawn on every category, lowest quantile first; one ladder per
|
|
370
|
+
* condition measured (`Startup p50 | Startup p95 | Wall p50 | Wall p95`), named by it (empty when
|
|
371
|
+
* there is one). Each series is named by its quantile (`p50`, `max`).
|
|
372
|
+
*/
|
|
373
|
+
readonly ladders?: readonly ChartLadder[];
|
|
374
|
+
}
|
|
375
|
+
/** One measurement's quantiles in a `ladder` chart: its name and its series, lowest quantile first. */
|
|
376
|
+
export interface ChartLadder {
|
|
377
|
+
readonly name: string;
|
|
378
|
+
readonly series: readonly number[];
|
|
379
|
+
}
|
|
380
|
+
/** A status column of a {@link ChartSpec.matrix}: its header and each category's status. */
|
|
381
|
+
export interface StatusColumn {
|
|
382
|
+
readonly name: string;
|
|
383
|
+
readonly statuses: readonly (Status | undefined)[];
|
|
384
|
+
}
|
|
385
|
+
/** A fact a chart could state as its title, from {@link tableTakeaways}. */
|
|
386
|
+
export interface Takeaway {
|
|
387
|
+
/** What the fact is about (`top:pass%`, `move:Build units`), unique among one chart's takeaways. */
|
|
388
|
+
readonly key: string;
|
|
389
|
+
readonly text: string;
|
|
390
|
+
/** Striking on its figures alone (a large move, a far outlier, a sweep): worth stating without a judge. */
|
|
391
|
+
readonly striking: boolean;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* A mark a planner lays over a chart; the renderer draws each kind where the
|
|
395
|
+
* chart supports it (bar-like kinds and lines) and skips it elsewhere.
|
|
396
|
+
* - `reference`: a dashed rule across the plot at `value` (base units of the
|
|
397
|
+
* first series), labelled at its end (`budget 200 ms`, `baseline`).
|
|
398
|
+
* - `highlight`: a soft band behind category `category` (an index into
|
|
399
|
+
* {@link ChartSpec.categories}) and its label set in full strength.
|
|
400
|
+
* - `callout`: short `text` beside the mark of `category` in `series` (default
|
|
401
|
+
* 0) with a leader line (`60× the rest`, `fastest`).
|
|
402
|
+
*/
|
|
403
|
+
export type ChartAnnotation = {
|
|
404
|
+
readonly kind: "reference";
|
|
405
|
+
readonly value: number;
|
|
406
|
+
readonly label: string;
|
|
407
|
+
/** Series whose axis the value is on, for charts with an axis per unit (`range` bands); 0 by default. */
|
|
408
|
+
readonly series?: number;
|
|
409
|
+
} | {
|
|
410
|
+
readonly kind: "highlight";
|
|
411
|
+
readonly category: number;
|
|
412
|
+
} | {
|
|
413
|
+
readonly kind: "callout";
|
|
414
|
+
readonly category: number;
|
|
415
|
+
readonly series?: number;
|
|
416
|
+
readonly text: string;
|
|
417
|
+
};
|
|
418
|
+
/** The local best guess at a chart for `table`, or `undefined` when no chart fits. */
|
|
419
|
+
export declare function planChart(table: TableAnalysis): ChartPlan | undefined;
|
|
420
|
+
/**
|
|
421
|
+
* Whether a model should pick `table`'s chart (`tui.autoGraph: smart`):
|
|
422
|
+
* multi-series tables, and tables whose rows may be named by a number the
|
|
423
|
+
* `guess` plots (`Thread | State`, `Finding | Current`), where only meaning
|
|
424
|
+
* tells a name from a measure.
|
|
425
|
+
*/
|
|
426
|
+
export declare function shouldJudge(table: TableAnalysis, guess: ChartPlan | undefined): boolean;
|
|
427
|
+
/** Measure columns before `guess`'s text label column: numbers that may only name their rows. */
|
|
428
|
+
export declare function leadingMeasures(table: TableAnalysis, guess: ChartPlan): TableColumn[];
|
|
429
|
+
/**
|
|
430
|
+
* Facts about `table` a chart could state as its headline under `plan`'s
|
|
431
|
+
* meaning, strongest first: those of the chart `plan` draws (its moves, its
|
|
432
|
+
* trend), and of measures side by side, under each of `contests` (`plan`'s
|
|
433
|
+
* own {@link ChartPlan.rivals} by default; a judge is offered either reading's).
|
|
434
|
+
* `scope` says which measures stand side by side: `drawn` (the default, what
|
|
435
|
+
* a title may state) only those the chart draws ({@link drawnNames}) — a
|
|
436
|
+
* headline citing a column the chart leaves out (`Total` beside a chart of
|
|
437
|
+
* `vs current`) names a figure the reader cannot find on it; `table` every
|
|
438
|
+
* measure (a row best on measures the chart leaves out), the options a judge
|
|
439
|
+
* weighs while it may still pick a chart drawing them.
|
|
440
|
+
*/
|
|
441
|
+
export declare function tableTakeaways(table: TableAnalysis, plan: ChartPlan, contests?: readonly (Rivals | undefined)[], scope?: "drawn" | "table"): Takeaway[];
|
|
442
|
+
/**
|
|
443
|
+
* What a chart draws, by name: its series, its x measure (not the row names a line runs along), the
|
|
444
|
+
* whole its parts stack to and the baseline its factors are of — the columns (or, transposed, rows) a
|
|
445
|
+
* headline may cite.
|
|
446
|
+
*/
|
|
447
|
+
export declare function drawnNames(spec: ChartSpec): Set<string>;
|
|
448
|
+
/**
|
|
449
|
+
* The local guess at what `plan`'s rows and measures mean: header keywords
|
|
450
|
+
* for each measure's {@link Polarity} (resources like tokens or memory only
|
|
451
|
+
* beside a baseline), rivals from the label's header, focus from bolded or
|
|
452
|
+
* `(current)` row names, and a status column whose cells vary.
|
|
453
|
+
*/
|
|
454
|
+
export declare function guessMeaning(table: TableAnalysis, plan: ChartPlan): Pick<ChartPlan, "polarity" | "rowPolarity" | "rivals" | "focus" | "status">;
|
|
455
|
+
/** Whether `plan`'s rows may each be a metric of their own: a `change`, a transposed table, or mixed-unit columns. */
|
|
456
|
+
export declare function rowsAreMetrics(table: TableAnalysis, plan: ChartPlan): boolean;
|
|
457
|
+
/** Most segments one share bar keeps legible; more parts read as bars (a planner's `share` pick included). */
|
|
458
|
+
export declare const MAX_SHARE_SEGMENTS = 10;
|
|
459
|
+
/**
|
|
460
|
+
* Same-unit count or percent measures whose headers each lead with an outcome
|
|
461
|
+
* (`ok | fail`, `Pass | Partial | Fail`) of more than one kind: the parts of
|
|
462
|
+
* each row's attempts, read as its mix.
|
|
463
|
+
*/
|
|
464
|
+
export declare function outcomeColumns(measures: readonly TableColumn[]): TableColumn[] | undefined;
|
|
465
|
+
/**
|
|
466
|
+
* The outcome each of `names` leads with (`ok`, `FAIL`, ✅, or none) when at
|
|
467
|
+
* least {@link TONED_SHARE} of them lead with one, `good` and something else
|
|
468
|
+
* among them: parts colored by what they say rather than by series
|
|
469
|
+
* (`✅ FIXED | 🟡 PARTIAL | 🎨 VISUAL? | ❌ OPEN`). `undefined` otherwise.
|
|
470
|
+
*/
|
|
471
|
+
export declare function outcomeTones(names: readonly string[]): (Status | undefined)[] | undefined;
|
|
472
|
+
/** A measured column and the column of targets it is held to ({@link findTarget}). */
|
|
473
|
+
export interface TargetColumns {
|
|
474
|
+
readonly measured: TableColumn;
|
|
475
|
+
readonly target: TableColumn;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* The column of targets `table` holds its measure to, read from headers and cells: a header naming targets
|
|
479
|
+
* ({@link TARGET_HEADER}) over cells mostly holding one ({@link targetCell}) and mostly written as bounds (`≤
|
|
480
|
+
* 200 µs`), which a word naming nothing else ({@link TARGET_WORD}: `Target`, `Budget`) does without; never the
|
|
481
|
+
* first column, which keys the rows (a `limit` setting each row tries). The measure held to it is the nearest
|
|
482
|
+
* column to it (left first), not itself mostly bounds, whose cells share a unit and a sign convention with the
|
|
483
|
+
* targets ({@link measuredCell}) in two rows or more, in half the rows or more, and in at least half of the
|
|
484
|
+
* rows writing both. `undefined` when none.
|
|
485
|
+
*/
|
|
486
|
+
export declare function findTarget(table: TableAnalysis): TargetColumns | undefined;
|
|
487
|
+
/**
|
|
488
|
+
* How `point` stands against `target`: `met` when it keeps the target's side (its worst end — the high end
|
|
489
|
+
* under a ceiling, the low end over a floor — at or past the target; inside a window), `close` when met
|
|
490
|
+
* within {@link CLOSE_SHARE}; `share` its worst end over the target (the window's top), `undefined` for a
|
|
491
|
+
* zero target. `undefined` for a target without a bound or window. Exported for the renderer.
|
|
492
|
+
*/
|
|
493
|
+
export declare function targetStanding(point: ChartPoint, target: ChartTarget): {
|
|
494
|
+
readonly met: boolean;
|
|
495
|
+
readonly close: boolean;
|
|
496
|
+
readonly share: number | undefined;
|
|
497
|
+
} | undefined;
|
|
498
|
+
/**
|
|
499
|
+
* Whether the table's prose carries it, so a chart of `columns` would only
|
|
500
|
+
* restate small whole numbers set beside sentences: text columns (other than
|
|
501
|
+
* the label) whose typical cells add up to {@link PROSE_CELL} characters a
|
|
502
|
+
* row, next to plotted values that are all whole numbers up to
|
|
503
|
+
* {@link MAX_PROSE_COUNT} (tiers, ratings, fixes per PR).
|
|
504
|
+
*/
|
|
505
|
+
export declare function proseLed(table: TableAnalysis, columns: readonly TableColumn[]): boolean;
|
|
506
|
+
/**
|
|
507
|
+
* The data `plan` draws from `table`, or `undefined` when it leaves fewer than
|
|
508
|
+
* two categories or no series with two values. The kind is fitted to the
|
|
509
|
+
* series it ends up with ({@link fitKind}), so any plan — a model's pick
|
|
510
|
+
* included — draws as something the renderer supports.
|
|
511
|
+
*/
|
|
512
|
+
export declare function buildChart(table: TableAnalysis, plan: ChartPlan): ChartSpec | undefined;
|
|
513
|
+
/** One quantile of a {@link Ladder}: a column holding it alone, or one item of a column's slash lists. */
|
|
514
|
+
export interface Rung {
|
|
515
|
+
readonly column: TableColumn;
|
|
516
|
+
/** Which listed value of each cell (`p99` of `79 / 124 µs`); absent when the column holds the quantile alone. */
|
|
517
|
+
readonly slot?: number;
|
|
518
|
+
/** How many values each cell of a listing column holds (the quantiles its header lists). */
|
|
519
|
+
readonly slots?: number;
|
|
520
|
+
/** The quantile as the header writes it (`p50`, `max`). */
|
|
521
|
+
readonly name: string;
|
|
522
|
+
/** Where it ranks: 0 the minimum, 50 the median (or a mean beside quantiles), 100 the maximum. */
|
|
523
|
+
readonly rank: number;
|
|
524
|
+
/** The unit the header gives bare numbers (`cpu p50 / p95 (ms)`): their dimension and base factor. */
|
|
525
|
+
readonly scale?: readonly [Dimension, number];
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Quantiles of one measurement per row (`p50 | p90 | p99 | max`, `Startup p50 | Startup p95`,
|
|
529
|
+
* `p50 / p99` cells), lowest rank first, all of one dimension.
|
|
530
|
+
*/
|
|
531
|
+
export interface Ladder {
|
|
532
|
+
/** The measurement (`Startup`, `zoom 1`); empty when its headers name nothing but quantiles. */
|
|
533
|
+
readonly name: string;
|
|
534
|
+
readonly rungs: readonly Rung[];
|
|
535
|
+
readonly dim: Dimension;
|
|
536
|
+
/** Currency symbol or rate unit the axis prints; empty for other dimensions. */
|
|
537
|
+
readonly unit: string;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* `table`'s quantile ladders ({@link quantileLadders}) beside the `label` column, when their columns
|
|
541
|
+
* are at least half of what the table measures and no column holds per-row targets ({@link findTarget}:
|
|
542
|
+
* quantiles held to targets are a `bullet`): the table is about the distributions. Every column
|
|
543
|
+
* but the label may hold quantiles, measures and text alike — a quantile alike in every row (`p50` 2,
|
|
544
|
+
* 2) is no measure, and a list of three (`1.69 / 2.59 / 3.17`) reads as prose.
|
|
545
|
+
*/
|
|
546
|
+
export declare function tableLadders(table: TableAnalysis, label: number | undefined): Ladder[] | undefined;
|
|
547
|
+
/** The columns `ladders` read their quantiles from, each once, in ladder order. */
|
|
548
|
+
export declare function ladderColumns(ladders: readonly Ladder[]): number[];
|
|
549
|
+
/**
|
|
550
|
+
* The quantile ladders among `measures`: columns whose headers each name one quantile of one
|
|
551
|
+
* measurement (`p50 | p90 | p99`, `Startup p50 | Startup p95`; a bare `p95` after `TTFT p50` joins
|
|
552
|
+
* it), and columns whose headers name a slash list of quantiles over cells listing that many values
|
|
553
|
+
* (`p50 / p99` over `79 / 124 µs`). A ladder needs two quantiles, one of them neither the minimum nor
|
|
554
|
+
* the maximum, one dimension, and its values rising with rank in {@link ORDERED_SHARE} of the rows
|
|
555
|
+
* holding two (two such rows at least); ladders in
|
|
556
|
+
* another dimension than the first leave, at most {@link MAX_LADDERS} stay. `undefined` when none.
|
|
557
|
+
*/
|
|
558
|
+
export declare function quantileLadders(measures: readonly TableColumn[], rows: readonly number[]): Ladder[] | undefined;
|
|
559
|
+
/**
|
|
560
|
+
* `rows` as ordered bins of `column`: {@link MIN_BINS} to {@link MAX_BINS} cells each a value, a range
|
|
561
|
+
* or an open end (`1 | 2–5 | 6–20 | 21–100 | 100+`, `<1 ms | 1–10 ms | >10 ms`), not all single values,
|
|
562
|
+
* running one way and meeting end to start — no overlap, a gap of at most one between whole-number bins
|
|
563
|
+
* (or one written digit between decimal ones). The rows in ascending bin order, else `undefined`.
|
|
564
|
+
*/
|
|
565
|
+
export declare function binRows(column: TableColumn, rows: readonly number[]): number[] | undefined;
|
|
566
|
+
/**
|
|
567
|
+
* The column whose rows are `table`'s ordered bins ({@link binRows}) — its label, else its first column —
|
|
568
|
+
* with the measures counting each bin ({@link frequencyColumns}); `undefined` unless both hold.
|
|
569
|
+
*/
|
|
570
|
+
export declare function histogramColumns(table: TableAnalysis, measures?: readonly TableColumn[]): {
|
|
571
|
+
bins: TableColumn;
|
|
572
|
+
counts: TableColumn[];
|
|
573
|
+
} | undefined;
|
|
574
|
+
/**
|
|
575
|
+
* The same-unit measures plotted as intervals when values written `a–b` make
|
|
576
|
+
* up most of the numbers of at least one of them ({@link RANGE_SHARE}), with the
|
|
577
|
+
* measures sharing its unit (an estimate column, a pair's other side); other
|
|
578
|
+
* units' interval columns join as bands of their own. At most {@link MAX_RANGES}.
|
|
579
|
+
*/
|
|
580
|
+
export declare function rangeColumns(measures: readonly TableColumn[], rows: readonly number[]): TableColumn[] | undefined;
|
|
581
|
+
/**
|
|
582
|
+
* Whether `columns` over `rows` read best as dots: three to six columns of one measurement
|
|
583
|
+
* ({@link DOT_DIMS}) spanning {@link DOT_SPREAD}× or more, where grouped bars from zero would flatten
|
|
584
|
+
* the small values — one quantity whose rows sit apart on a log axis, or rows too tight for one axis
|
|
585
|
+
* beside a baseline column their factors can be read against ({@link dotLayout}).
|
|
586
|
+
*/
|
|
587
|
+
export declare function dotsFit(columns: readonly TableColumn[], rows: readonly number[]): boolean;
|
|
588
|
+
/**
|
|
589
|
+
* The middle of a value written `a–b`, which a factor between two intervals compares: the geometric
|
|
590
|
+
* mean (`5.7–9.6 ms` → 7.4 ms), the arithmetic one from zero; a single value is its own.
|
|
591
|
+
*/
|
|
592
|
+
export declare function intervalMiddle(point: ChartPoint): number;
|
|
593
|
+
/**
|
|
594
|
+
* Whether two headers name one quantity under two conditions — the one
|
|
595
|
+
* before/after helper every pair decision goes through (the judge's `pair`
|
|
596
|
+
* answer stands in for it where the headers say nothing): a before/after word
|
|
597
|
+
* ({@link isTransition}) or the same words around one that differs (`gpt-5.5
|
|
598
|
+
* window | gpt-5.4 (target) window`, `Q5_K_M | Q4_K_M`). Identical headers (a
|
|
599
|
+
* list wrapped into two halves) and unrelated quantities (`Verts | Faces`,
|
|
600
|
+
* `Tier | New Findings`) are no pair.
|
|
601
|
+
*/
|
|
602
|
+
export declare function isConditionPair(first: string, second: string): boolean;
|
|
603
|
+
/**
|
|
604
|
+
* The direction of a condition pair: `first` names the before state and
|
|
605
|
+
* `second` the after one (`Baseline | Iter20`, `old (diff) | new`, `Stock |
|
|
606
|
+
* Patched`), so the pair reads as a move from `first` to `second`. A pair
|
|
607
|
+
* without such words (`xutf | std`, `Q5_K_M | Q4_K_M`) has no direction: peers.
|
|
608
|
+
*/
|
|
609
|
+
export declare function isTransition(first: string, second: string): boolean;
|
|
610
|
+
/**
|
|
611
|
+
* Three to {@link MAX_STAGES} adjacent same-unit measures holding one quantity
|
|
612
|
+
* at successive stages of a run: a before column (`Baseline`, `Original`)
|
|
613
|
+
* followed by later stages ({@link STAGE_HEADER}: `Iter 1 | Iter 2`, `Best (Iter
|
|
614
|
+
* 3) | Iter 4`, `Round 1 | Now`), each typically within {@link QUANTITY_SPREAD}×
|
|
615
|
+
* of the first row by row (a `Tokens In (Iter2)` beside turns is another
|
|
616
|
+
* quantity). Deltas and totals end the run. `undefined` when no such run exists.
|
|
617
|
+
*/
|
|
618
|
+
export declare function stageColumns(measures: readonly TableColumn[], rows: readonly number[]): TableColumn[] | undefined;
|
|
619
|
+
/**
|
|
620
|
+
* Two same-unit measures of opposing amounts ({@link OPPOSED}: `Removed |
|
|
621
|
+
* Added`, `Losses | Wins`), the losing side first, neither a delta or a total
|
|
622
|
+
* and neither naming both sides; `undefined` when no such pair exists.
|
|
623
|
+
*/
|
|
624
|
+
export declare function opposedColumns(measures: readonly TableColumn[]): [TableColumn, TableColumn] | undefined;
|
|
625
|
+
/**
|
|
626
|
+
* Each category's value of `entry` as a factor of its group's reference
|
|
627
|
+
* category ({@link ChartSpec.reference}; the whole chart is one group without
|
|
628
|
+
* groups): `undefined` for the reference itself, outside any referenced
|
|
629
|
+
* group, or where either value is missing or not positive.
|
|
630
|
+
*/
|
|
631
|
+
export declare function referenceFactors(spec: ChartSpec, entry: ChartSeries): (number | undefined)[];
|
|
632
|
+
/**
|
|
633
|
+
* A share in percent as a chart writes it: whole percents, one decimal within
|
|
634
|
+
* 1 of either end (`0.4%`, `99.6%`) so a sliver never rounds to nothing or
|
|
635
|
+
* everything, and `<0.1%` / `>99.9%` past that. Exported for the renderer.
|
|
636
|
+
*/
|
|
637
|
+
export declare function percentText(percent: number): string;
|
|
638
|
+
/**
|
|
639
|
+
* Whether a chart of `spec` reads faster than its table: at least four
|
|
640
|
+
* categories (or small-multiple panels), and either nine plotted values or a
|
|
641
|
+
* 3× spread within a series. On a model-judged sample of assistant tables this
|
|
642
|
+
* gate kept 85% of the tables a chart clearly helped while rejecting most two-
|
|
643
|
+
* and three-row ones. A `change` needs three metrics and one moving by
|
|
644
|
+
* {@link NOTABLE_FACTOR} either way: its factors are what the table lacks.
|
|
645
|
+
* Series holding one value in all their categories but one (`5/5` in eight
|
|
646
|
+
* of nine rows) say nothing bars add to.
|
|
647
|
+
*/
|
|
648
|
+
export declare function worthCharting(spec: ChartSpec): boolean;
|
|
649
|
+
/**
|
|
650
|
+
* Columns that may join `label` in naming rows: short text or date columns
|
|
651
|
+
* whose cells vary (a column of one value tells no rows apart).
|
|
652
|
+
*/
|
|
653
|
+
export declare function namingColumns(table: TableAnalysis, label: TableColumn | undefined): TableColumn[];
|
|
654
|
+
/**
|
|
655
|
+
* The local guess at the columns naming rows beside `label`: the fewest of
|
|
656
|
+
* `spare` (by default {@link namingColumns}) that tell repeated labels apart
|
|
657
|
+
* (`Model | Harness`), the one with the fewest distinct values first (a factor
|
|
658
|
+
* like `Harness`, not a notes column); and as the group, the first naming
|
|
659
|
+
* column already running in blocks, so table order stays as written.
|
|
660
|
+
*/
|
|
661
|
+
export declare function guessNaming(table: TableAnalysis, label: TableColumn | undefined, spare?: readonly TableColumn[]): {
|
|
662
|
+
qualifiers: readonly number[];
|
|
663
|
+
group: number | undefined;
|
|
664
|
+
};
|
|
665
|
+
/**
|
|
666
|
+
* How a heatmap of `columns` over `rows` should shade: each column on its own
|
|
667
|
+
* when two columns typically differ {@link QUANTITY_SPREAD}× within a row
|
|
668
|
+
* (different quantities, like input vs. reasoning tokens), each row on its
|
|
669
|
+
* own when two rows typically do within a column (one measure on a small and
|
|
670
|
+
* a huge item) and a row's cells typically differ {@link ROW_CONTRAST}×,
|
|
671
|
+
* else one scale for every cell. The local default of the
|
|
672
|
+
* judge's shading answer.
|
|
673
|
+
*/
|
|
674
|
+
export declare function guessShading(columns: readonly TableColumn[], rows: readonly number[]): Shading;
|