@netlify/axis 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +977 -0
- package/dist/adapters/base/acp-adapter.d.ts +44 -0
- package/dist/adapters/base/acp-adapter.d.ts.map +1 -0
- package/dist/adapters/base/acp-adapter.js +559 -0
- package/dist/adapters/base/acp-adapter.js.map +1 -0
- package/dist/adapters/base/agent-adapter.d.ts +132 -0
- package/dist/adapters/base/agent-adapter.d.ts.map +1 -0
- package/dist/adapters/base/agent-adapter.js +212 -0
- package/dist/adapters/base/agent-adapter.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +3 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +138 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/claude-sdk.d.ts +11 -0
- package/dist/adapters/claude-sdk.d.ts.map +1 -0
- package/dist/adapters/claude-sdk.js +46 -0
- package/dist/adapters/claude-sdk.js.map +1 -0
- package/dist/adapters/codex.d.ts +3 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +183 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/gemini-acp.d.ts +11 -0
- package/dist/adapters/gemini-acp.d.ts.map +1 -0
- package/dist/adapters/gemini-acp.js +60 -0
- package/dist/adapters/gemini-acp.js.map +1 -0
- package/dist/adapters/gemini.d.ts +3 -0
- package/dist/adapters/gemini.d.ts.map +1 -0
- package/dist/adapters/gemini.js +222 -0
- package/dist/adapters/gemini.js.map +1 -0
- package/dist/adapters/goose.d.ts +3 -0
- package/dist/adapters/goose.d.ts.map +1 -0
- package/dist/adapters/goose.js +9 -0
- package/dist/adapters/goose.js.map +1 -0
- package/dist/adapters/registry.d.ts +7 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +37 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/utils/mcp.d.ts +23 -0
- package/dist/adapters/utils/mcp.d.ts.map +1 -0
- package/dist/adapters/utils/mcp.js +114 -0
- package/dist/adapters/utils/mcp.js.map +1 -0
- package/dist/adapters/utils/resolve.d.ts +20 -0
- package/dist/adapters/utils/resolve.d.ts.map +1 -0
- package/dist/adapters/utils/resolve.js +48 -0
- package/dist/adapters/utils/resolve.js.map +1 -0
- package/dist/adapters/utils/skills.d.ts +17 -0
- package/dist/adapters/utils/skills.d.ts.map +1 -0
- package/dist/adapters/utils/skills.js +52 -0
- package/dist/adapters/utils/skills.js.map +1 -0
- package/dist/adapters/utils/token-estimator.d.ts +21 -0
- package/dist/adapters/utils/token-estimator.d.ts.map +1 -0
- package/dist/adapters/utils/token-estimator.js +37 -0
- package/dist/adapters/utils/token-estimator.js.map +1 -0
- package/dist/baselines/diff.d.ts +9 -0
- package/dist/baselines/diff.d.ts.map +1 -0
- package/dist/baselines/diff.js +83 -0
- package/dist/baselines/diff.js.map +1 -0
- package/dist/baselines/index.d.ts +3 -0
- package/dist/baselines/index.d.ts.map +1 -0
- package/dist/baselines/index.js +3 -0
- package/dist/baselines/index.js.map +1 -0
- package/dist/baselines/store.d.ts +19 -0
- package/dist/baselines/store.d.ts.map +1 -0
- package/dist/baselines/store.js +104 -0
- package/dist/baselines/store.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +487 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +99 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/validator.d.ts +11 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +203 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/docs-site/_astro/cli.DDWZtG0-.css +1 -0
- package/dist/docs-site/cli/index.html +18 -0
- package/dist/docs-site/configuration/index.html +121 -0
- package/dist/docs-site/content-assets.mjs +1 -0
- package/dist/docs-site/content-modules.mjs +1 -0
- package/dist/docs-site/data-store.json +9 -0
- package/dist/docs-site/index.html +69 -0
- package/dist/docs-site/quickstart/index.html +59 -0
- package/dist/docs-site/running/index.html +87 -0
- package/dist/docs-site/scoring/index.html +135 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/report-ui/index.html +291 -0
- package/dist/report-ui/mock-data.json +298 -0
- package/dist/reports/html.d.ts +7 -0
- package/dist/reports/html.d.ts.map +1 -0
- package/dist/reports/html.js +27 -0
- package/dist/reports/html.js.map +1 -0
- package/dist/reports/reader.d.ts +21 -0
- package/dist/reports/reader.d.ts.map +1 -0
- package/dist/reports/reader.js +110 -0
- package/dist/reports/reader.js.map +1 -0
- package/dist/reports/writer.d.ts +14 -0
- package/dist/reports/writer.d.ts.map +1 -0
- package/dist/reports/writer.js +106 -0
- package/dist/reports/writer.js.map +1 -0
- package/dist/runner/lifecycle.d.ts +10 -0
- package/dist/runner/lifecycle.d.ts.map +1 -0
- package/dist/runner/lifecycle.js +58 -0
- package/dist/runner/lifecycle.js.map +1 -0
- package/dist/runner/runner.d.ts +34 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +330 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/scoring/category-score.d.ts +52 -0
- package/dist/scoring/category-score.d.ts.map +1 -0
- package/dist/scoring/category-score.js +157 -0
- package/dist/scoring/category-score.js.map +1 -0
- package/dist/scoring/composite.d.ts +5 -0
- package/dist/scoring/composite.d.ts.map +1 -0
- package/dist/scoring/composite.js +24 -0
- package/dist/scoring/composite.js.map +1 -0
- package/dist/scoring/deep-eval.d.ts +25 -0
- package/dist/scoring/deep-eval.d.ts.map +1 -0
- package/dist/scoring/deep-eval.js +382 -0
- package/dist/scoring/deep-eval.js.map +1 -0
- package/dist/scoring/goal-achievement.d.ts +5 -0
- package/dist/scoring/goal-achievement.d.ts.map +1 -0
- package/dist/scoring/goal-achievement.js +241 -0
- package/dist/scoring/goal-achievement.js.map +1 -0
- package/dist/scoring/index.d.ts +22 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +115 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/parse-json.d.ts +6 -0
- package/dist/scoring/parse-json.d.ts.map +1 -0
- package/dist/scoring/parse-json.js +18 -0
- package/dist/scoring/parse-json.js.map +1 -0
- package/dist/scoring/sparse-index.d.ts +15 -0
- package/dist/scoring/sparse-index.d.ts.map +1 -0
- package/dist/scoring/sparse-index.js +338 -0
- package/dist/scoring/sparse-index.js.map +1 -0
- package/dist/scoring/triage.d.ts +15 -0
- package/dist/scoring/triage.d.ts.map +1 -0
- package/dist/scoring/triage.js +204 -0
- package/dist/scoring/triage.js.map +1 -0
- package/dist/skills/resolver.d.ts +19 -0
- package/dist/skills/resolver.d.ts.map +1 -0
- package/dist/skills/resolver.js +95 -0
- package/dist/skills/resolver.js.map +1 -0
- package/dist/transcript/categorize.d.ts +24 -0
- package/dist/transcript/categorize.d.ts.map +1 -0
- package/dist/transcript/categorize.js +233 -0
- package/dist/transcript/categorize.js.map +1 -0
- package/dist/transcript/classify.d.ts +7 -0
- package/dist/transcript/classify.d.ts.map +1 -0
- package/dist/transcript/classify.js +32 -0
- package/dist/transcript/classify.js.map +1 -0
- package/dist/transcript/extract.d.ts +24 -0
- package/dist/transcript/extract.d.ts.map +1 -0
- package/dist/transcript/extract.js +266 -0
- package/dist/transcript/extract.js.map +1 -0
- package/dist/transcript/index.d.ts +3 -0
- package/dist/transcript/index.d.ts.map +1 -0
- package/dist/transcript/index.js +2 -0
- package/dist/transcript/index.js.map +1 -0
- package/dist/transcript/normalize.d.ts +15 -0
- package/dist/transcript/normalize.d.ts.map +1 -0
- package/dist/transcript/normalize.js +160 -0
- package/dist/transcript/normalize.js.map +1 -0
- package/dist/transcript/types.d.ts +92 -0
- package/dist/transcript/types.d.ts.map +1 -0
- package/dist/transcript/types.js +2 -0
- package/dist/transcript/types.js.map +1 -0
- package/dist/transcript/urls.d.ts +10 -0
- package/dist/transcript/urls.d.ts.map +1 -0
- package/dist/transcript/urls.js +31 -0
- package/dist/transcript/urls.js.map +1 -0
- package/dist/types/agent.d.ts +80 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +2 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/baseline.d.ts +65 -0
- package/dist/types/baseline.d.ts.map +1 -0
- package/dist/types/baseline.js +2 -0
- package/dist/types/baseline.js.map +1 -0
- package/dist/types/config.d.ts +76 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/output.d.ts +70 -0
- package/dist/types/output.d.ts.map +1 -0
- package/dist/types/output.js +15 -0
- package/dist/types/output.js.map +1 -0
- package/dist/types/report.d.ts +37 -0
- package/dist/types/report.d.ts.map +1 -0
- package/dist/types/report.js +2 -0
- package/dist/types/report.js.map +1 -0
- package/dist/types/scenario.d.ts +23 -0
- package/dist/types/scenario.d.ts.map +1 -0
- package/dist/types/scenario.js +2 -0
- package/dist/types/scenario.js.map +1 -0
- package/dist/types/scoring.d.ts +176 -0
- package/dist/types/scoring.d.ts.map +1 -0
- package/dist/types/scoring.js +2 -0
- package/dist/types/scoring.js.map +1 -0
- package/dist/ui/AnimatedTokens.d.ts +29 -0
- package/dist/ui/AnimatedTokens.d.ts.map +1 -0
- package/dist/ui/AnimatedTokens.js +53 -0
- package/dist/ui/AnimatedTokens.js.map +1 -0
- package/dist/ui/App.d.ts +6 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +16 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/LiveDuration.d.ts +20 -0
- package/dist/ui/LiveDuration.d.ts.map +1 -0
- package/dist/ui/LiveDuration.js +31 -0
- package/dist/ui/LiveDuration.js.map +1 -0
- package/dist/ui/LiveStatus.d.ts +7 -0
- package/dist/ui/LiveStatus.d.ts.map +1 -0
- package/dist/ui/LiveStatus.js +52 -0
- package/dist/ui/LiveStatus.js.map +1 -0
- package/dist/ui/format.d.ts +29 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +514 -0
- package/dist/ui/format.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { ScoringWeights } from "./config.js";
|
|
2
|
+
import type { BaseRunResult, Logger, RunSummary } from "./output.js";
|
|
3
|
+
export interface CriterionGrade {
|
|
4
|
+
check: string;
|
|
5
|
+
weight: number;
|
|
6
|
+
score: number;
|
|
7
|
+
rationale: string;
|
|
8
|
+
}
|
|
9
|
+
export interface GoalAchievementScore {
|
|
10
|
+
score: number;
|
|
11
|
+
criteria: CriterionGrade[];
|
|
12
|
+
}
|
|
13
|
+
/** The three process-quality categories for interaction classification. */
|
|
14
|
+
export type InteractionCategory = "environment" | "service" | "agent";
|
|
15
|
+
/**
|
|
16
|
+
* A single classified interaction in the transcript.
|
|
17
|
+
* An "interaction" is typically a tool_use + its paired tool_result,
|
|
18
|
+
* or a group of consecutive assistant entries, or a standalone error.
|
|
19
|
+
*/
|
|
20
|
+
export interface Interaction {
|
|
21
|
+
/** Sequential ID within the run (1-based). */
|
|
22
|
+
id: number;
|
|
23
|
+
/** Indices into the NormalizedEntry[] array that compose this interaction. */
|
|
24
|
+
entryIndices: number[];
|
|
25
|
+
/** Classified categories (an interaction can belong to multiple, e.g. env + service). */
|
|
26
|
+
categories: InteractionCategory[];
|
|
27
|
+
/** The sparse index line for this interaction. */
|
|
28
|
+
sparseLine: string;
|
|
29
|
+
/** Tool name if this is a tool-based interaction. */
|
|
30
|
+
toolName: string | null;
|
|
31
|
+
/** Whether this interaction had an error. */
|
|
32
|
+
hasError: boolean;
|
|
33
|
+
/** Duration in ms (from paired timestamps), null if unavailable. */
|
|
34
|
+
durationMs: number | null;
|
|
35
|
+
/** Offset from the first transcript entry in ms. null if timestamp unavailable. */
|
|
36
|
+
startMs: number | null;
|
|
37
|
+
/** Approximate token weight of the context (input + output text size in bytes). */
|
|
38
|
+
contextBytes: number;
|
|
39
|
+
/** Formatted content for display in reports (tool I/O, assistant text, etc). */
|
|
40
|
+
content?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Deterministic compressed representation of a transcript. */
|
|
43
|
+
export interface SparseIndex {
|
|
44
|
+
/** One line per interaction, ordered by sequence. */
|
|
45
|
+
lines: string[];
|
|
46
|
+
/** The full interaction objects (lines[i] corresponds to interactions[i]). */
|
|
47
|
+
interactions: Interaction[];
|
|
48
|
+
/** Summary stats. */
|
|
49
|
+
stats: {
|
|
50
|
+
totalInteractions: number;
|
|
51
|
+
byCategory: Record<InteractionCategory, number>;
|
|
52
|
+
totalErrors: number;
|
|
53
|
+
totalDurationMs: number;
|
|
54
|
+
/** Wall-clock elapsed time from first to last interaction end. */
|
|
55
|
+
wallClockMs: number;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export interface TriageFlaggedInteraction {
|
|
59
|
+
/** Interaction ID (matches Interaction.id). */
|
|
60
|
+
id: number;
|
|
61
|
+
/** Why this interaction was flagged for deep evaluation. */
|
|
62
|
+
reason: string;
|
|
63
|
+
/** The concern areas to evaluate in depth. */
|
|
64
|
+
concerns: ("success" | "speed" | "weight" | "relevance" | "necessity")[];
|
|
65
|
+
}
|
|
66
|
+
export interface TriagePattern {
|
|
67
|
+
/** Pattern description (e.g., "Repeated failed attempts at deployment"). */
|
|
68
|
+
description: string;
|
|
69
|
+
/** Interaction IDs involved. */
|
|
70
|
+
interactionIds: number[];
|
|
71
|
+
/** Severity: how much this pattern should affect the score. */
|
|
72
|
+
severity: "low" | "medium" | "high";
|
|
73
|
+
}
|
|
74
|
+
/** Output of the triage LLM pass. */
|
|
75
|
+
export interface TriageResult {
|
|
76
|
+
/** Per-interaction triage notes. Only populated for flagged interactions. */
|
|
77
|
+
flaggedInteractions: TriageFlaggedInteraction[];
|
|
78
|
+
/** High-level patterns the triage pass identified. */
|
|
79
|
+
patterns: TriagePattern[];
|
|
80
|
+
/** Per-category preliminary notes. */
|
|
81
|
+
categoryNotes: Record<InteractionCategory, string>;
|
|
82
|
+
}
|
|
83
|
+
/** Per-interaction audit result from the deep evaluation pass. */
|
|
84
|
+
export interface InteractionAudit {
|
|
85
|
+
/** Interaction ID. */
|
|
86
|
+
id: number;
|
|
87
|
+
/** Categories (copied from interaction — may be multi-category). */
|
|
88
|
+
categories: InteractionCategory[];
|
|
89
|
+
/** Did the interaction succeed or encounter failures? 0-1 */
|
|
90
|
+
success: number;
|
|
91
|
+
/** Speed relative to expected for this type of operation. 0-1 */
|
|
92
|
+
speed: number;
|
|
93
|
+
/** How much context was consumed/produced, relative to what was needed. 0-1 */
|
|
94
|
+
weight: number;
|
|
95
|
+
/** How much of the context was actionable vs wasteful. 0-1 */
|
|
96
|
+
contextRelevance: number;
|
|
97
|
+
/** Brief rationale for the scores. */
|
|
98
|
+
rationale: string;
|
|
99
|
+
}
|
|
100
|
+
/** Collective necessity judgment across interactions in a category. */
|
|
101
|
+
export interface NecessityJudgment {
|
|
102
|
+
category: InteractionCategory;
|
|
103
|
+
/** 0-1: were the interactions in this category necessary? */
|
|
104
|
+
score: number;
|
|
105
|
+
/** Interactions flagged as unnecessary. */
|
|
106
|
+
unnecessaryIds: number[];
|
|
107
|
+
rationale: string;
|
|
108
|
+
}
|
|
109
|
+
/** Full deep evaluation output. */
|
|
110
|
+
export interface DeepEvalResult {
|
|
111
|
+
/** Per-interaction audits (only for flagged interactions + sampled unflagged). */
|
|
112
|
+
audits: InteractionAudit[];
|
|
113
|
+
/** Per-category necessity scores. */
|
|
114
|
+
necessity: NecessityJudgment[];
|
|
115
|
+
}
|
|
116
|
+
/** Score for a single process-quality category (environment, service, agent). */
|
|
117
|
+
export interface CategoryScore {
|
|
118
|
+
/** 0-100, after log-normal mapping. */
|
|
119
|
+
score: number;
|
|
120
|
+
/** Number of interactions in this category. */
|
|
121
|
+
interactionCount: number;
|
|
122
|
+
/** Number of audited (LLM-evaluated) interactions. */
|
|
123
|
+
auditedCount: number;
|
|
124
|
+
/** Breakdown of audit dimensions (each 0-100). */
|
|
125
|
+
dimensions: {
|
|
126
|
+
success: number;
|
|
127
|
+
speed: number;
|
|
128
|
+
weight: number;
|
|
129
|
+
relevance: number;
|
|
130
|
+
necessity: number;
|
|
131
|
+
};
|
|
132
|
+
/** Audit details for this category. */
|
|
133
|
+
audits: InteractionAudit[];
|
|
134
|
+
/** Necessity judgment. */
|
|
135
|
+
necessity: NecessityJudgment;
|
|
136
|
+
}
|
|
137
|
+
export interface ScoreResult {
|
|
138
|
+
/** 0-100 composite AXIS score. */
|
|
139
|
+
axisScore: number;
|
|
140
|
+
/** Goal achievement (LLM judge). */
|
|
141
|
+
goalAchievement: GoalAchievementScore;
|
|
142
|
+
/** Process quality for environment interactions. */
|
|
143
|
+
environment: CategoryScore;
|
|
144
|
+
/** Process quality for service interactions. */
|
|
145
|
+
service: CategoryScore;
|
|
146
|
+
/** Process quality for agent-internal interactions. */
|
|
147
|
+
agent: CategoryScore;
|
|
148
|
+
/** Weights used for this scoring. */
|
|
149
|
+
weights: ScoringWeights;
|
|
150
|
+
/** The sparse index generated for this run (included in debug mode). */
|
|
151
|
+
sparseIndex?: SparseIndex;
|
|
152
|
+
}
|
|
153
|
+
export interface ScoredRunResult extends BaseRunResult {
|
|
154
|
+
score: ScoreResult;
|
|
155
|
+
}
|
|
156
|
+
export interface ScoredOutput {
|
|
157
|
+
version: string;
|
|
158
|
+
timestamp: string;
|
|
159
|
+
durationMs: number;
|
|
160
|
+
results: ScoredRunResult[];
|
|
161
|
+
summary: ScoredSummary;
|
|
162
|
+
}
|
|
163
|
+
export interface ScoredSummary extends RunSummary {
|
|
164
|
+
averageAxisScore: number;
|
|
165
|
+
}
|
|
166
|
+
/** Map of MCP server name → forced AXIS category (from config axisCategory). */
|
|
167
|
+
export type McpCategoryOverrides = Map<string, "environment" | "service">;
|
|
168
|
+
export interface ScoringOptions {
|
|
169
|
+
weights?: ScoringWeights;
|
|
170
|
+
logger?: Logger;
|
|
171
|
+
/** Called when scoring starts/finishes for a result. */
|
|
172
|
+
onProgress?: (scenarioKey: string, agentName: string, phase: "start" | "done") => void;
|
|
173
|
+
/** MCP server category overrides from config. */
|
|
174
|
+
mcpCategoryOverrides?: McpCategoryOverrides;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/types/scoring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/types/scoring.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure interpolation step: given the currently displayed value and the target,
|
|
3
|
+
* returns the next displayed value. Always increases by at least 1 when behind,
|
|
4
|
+
* never overshoots, and never decreases.
|
|
5
|
+
*/
|
|
6
|
+
export declare function nextDisplayed(current: number, target: number): number;
|
|
7
|
+
export interface AnimatedTokensProps {
|
|
8
|
+
/** Monotonically-increasing target value to count up toward. */
|
|
9
|
+
target: number;
|
|
10
|
+
/**
|
|
11
|
+
* When true, the component keeps its interval running even after catching up
|
|
12
|
+
* to `target` so it can animate further increases. When false, the interval
|
|
13
|
+
* self-stops once displayed === target.
|
|
14
|
+
*/
|
|
15
|
+
active: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* When true, `target` reflects the authoritative total from the adapter's
|
|
18
|
+
* `metadata.tokenUsage` (not the chars/5 estimate). The `~` prefix is
|
|
19
|
+
* dropped once the displayed value catches up to this true target.
|
|
20
|
+
*/
|
|
21
|
+
isFinal?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Smoothly counts up a number toward `target`. Never overshoots. Never
|
|
25
|
+
* counts down — if `target` regresses (it shouldn't, by design), the displayed
|
|
26
|
+
* value simply holds until target catches up.
|
|
27
|
+
*/
|
|
28
|
+
export declare function AnimatedTokens({ target, active, isFinal }: AnimatedTokensProps): import("react/jsx-runtime").JSX.Element | null;
|
|
29
|
+
//# sourceMappingURL=AnimatedTokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnimatedTokens.d.ts","sourceRoot":"","sources":["../../src/ui/AnimatedTokens.tsx"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,mBAAmB,kDAoC9E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
/** Interval between animation ticks (ms). ~20 Hz. */
|
|
5
|
+
const TICK_MS = 50;
|
|
6
|
+
/** Ease-out factor: fraction of remaining distance closed per tick. */
|
|
7
|
+
const EASE_FACTOR = 0.12;
|
|
8
|
+
/**
|
|
9
|
+
* Pure interpolation step: given the currently displayed value and the target,
|
|
10
|
+
* returns the next displayed value. Always increases by at least 1 when behind,
|
|
11
|
+
* never overshoots, and never decreases.
|
|
12
|
+
*/
|
|
13
|
+
export function nextDisplayed(current, target) {
|
|
14
|
+
if (current >= target)
|
|
15
|
+
return current;
|
|
16
|
+
const remaining = target - current;
|
|
17
|
+
const step = Math.max(1, Math.ceil(remaining * EASE_FACTOR));
|
|
18
|
+
return Math.min(target, current + step);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Smoothly counts up a number toward `target`. Never overshoots. Never
|
|
22
|
+
* counts down — if `target` regresses (it shouldn't, by design), the displayed
|
|
23
|
+
* value simply holds until target catches up.
|
|
24
|
+
*/
|
|
25
|
+
export function AnimatedTokens({ target, active, isFinal }) {
|
|
26
|
+
const [displayed, setDisplayed] = useState(0);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
// Nothing to animate: no target yet.
|
|
29
|
+
if (target <= 0)
|
|
30
|
+
return;
|
|
31
|
+
const interval = setInterval(() => {
|
|
32
|
+
setDisplayed((current) => {
|
|
33
|
+
if (current >= target) {
|
|
34
|
+
// Caught up. Only stop auto-ticking when the job is no longer active.
|
|
35
|
+
if (!active) {
|
|
36
|
+
clearInterval(interval);
|
|
37
|
+
}
|
|
38
|
+
return current;
|
|
39
|
+
}
|
|
40
|
+
return nextDisplayed(current, target);
|
|
41
|
+
});
|
|
42
|
+
}, TICK_MS);
|
|
43
|
+
return () => clearInterval(interval);
|
|
44
|
+
}, [target, active]);
|
|
45
|
+
if (target <= 0)
|
|
46
|
+
return null;
|
|
47
|
+
// Drop the `~` prefix once the real total has arrived and the animation
|
|
48
|
+
// has caught up — from that point on the number is authoritative, not an
|
|
49
|
+
// estimate.
|
|
50
|
+
const prefix = isFinal && displayed >= target ? "" : "~";
|
|
51
|
+
return (_jsxs(Text, { dimColor: true, children: [prefix, displayed.toLocaleString(), " tok"] }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=AnimatedTokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnimatedTokens.js","sourceRoot":"","sources":["../../src/ui/AnimatedTokens.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,qDAAqD;AACrD,MAAM,OAAO,GAAG,EAAE,CAAC;AAEnB,uEAAuE;AACvE,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,MAAc;IAC3D,IAAI,OAAO,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;AAC1C,CAAC;AAmBD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAuB;IAC7E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,qCAAqC;QACrC,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO;QAExB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,YAAY,CAAC,CAAC,OAAO,EAAE,EAAE;gBACvB,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;oBACtB,sEAAsE;oBACtE,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,aAAa,CAAC,QAAQ,CAAC,CAAC;oBAC1B,CAAC;oBACD,OAAO,OAAO,CAAC;gBACjB,CAAC;gBACD,OAAO,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAErB,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7B,wEAAwE;IACxE,yEAAyE;IACzE,YAAY;IACZ,MAAM,MAAM,GAAG,OAAO,IAAI,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAEzD,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,mBACX,MAAM,EACN,SAAS,CAAC,cAAc,EAAE,YACtB,CACR,CAAC;AACJ,CAAC"}
|
package/dist/ui/App.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { JobState } from "../types/output.js";
|
|
2
|
+
export interface AppProps {
|
|
3
|
+
subscribe: (cb: (jobs: JobState[]) => void) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare function App({ subscribe }: AppProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
//# sourceMappingURL=App.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;CACrD;AAED,wBAAgB,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,QAAQ,kDAc1C"}
|
package/dist/ui/App.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { LiveStatus } from "./LiveStatus.js";
|
|
4
|
+
export function App({ subscribe }) {
|
|
5
|
+
const [jobs, setJobs] = useState([]);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
subscribe((updatedJobs) => {
|
|
8
|
+
setJobs([...updatedJobs]);
|
|
9
|
+
});
|
|
10
|
+
}, [subscribe]);
|
|
11
|
+
if (jobs.length === 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return _jsx(LiveStatus, { jobs: jobs });
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C,MAAM,UAAU,GAAG,CAAC,EAAE,SAAS,EAAY;IACzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAa,EAAE,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YACxB,OAAO,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAC,UAAU,IAAC,IAAI,EAAE,IAAI,GAAI,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface LiveDurationProps {
|
|
2
|
+
/** Epoch-ms when the job entered `running`. Drives the live elapsed counter. */
|
|
3
|
+
startedAt?: number;
|
|
4
|
+
/** Final duration in ms. Once set, takes precedence over the live elapsed counter. */
|
|
5
|
+
finalMs?: number;
|
|
6
|
+
/**
|
|
7
|
+
* When true, the component keeps ticking. When false, rendering stops
|
|
8
|
+
* updating (static snapshot of whatever `finalMs` / last elapsed value is).
|
|
9
|
+
*/
|
|
10
|
+
active: boolean;
|
|
11
|
+
/** Optional ink text color (inherited from the row). */
|
|
12
|
+
color?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Renders `(12.3s)` — either the final `durationMs` from metadata (if set) or
|
|
16
|
+
* a live-ticking elapsed counter computed from `startedAt`. The timer stays
|
|
17
|
+
* visible in every state so users see how long each agent took / is taking.
|
|
18
|
+
*/
|
|
19
|
+
export declare function LiveDuration({ startedAt, finalMs, active, color }: LiveDurationProps): import("react/jsx-runtime").JSX.Element | null;
|
|
20
|
+
//# sourceMappingURL=LiveDuration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveDuration.d.ts","sourceRoot":"","sources":["../../src/ui/LiveDuration.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,iBAAiB,kDAkBpF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { formatDuration } from "./format.js";
|
|
5
|
+
/** Update interval for the ticking elapsed timer (ms). */
|
|
6
|
+
const TICK_MS = 100;
|
|
7
|
+
/**
|
|
8
|
+
* Renders `(12.3s)` — either the final `durationMs` from metadata (if set) or
|
|
9
|
+
* a live-ticking elapsed counter computed from `startedAt`. The timer stays
|
|
10
|
+
* visible in every state so users see how long each agent took / is taking.
|
|
11
|
+
*/
|
|
12
|
+
export function LiveDuration({ startedAt, finalMs, active, color }) {
|
|
13
|
+
const [now, setNow] = useState(() => Date.now());
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
// No ticking needed if we already have a final value, or no start time,
|
|
16
|
+
// or the job is no longer active.
|
|
17
|
+
if (finalMs !== undefined)
|
|
18
|
+
return;
|
|
19
|
+
if (!startedAt)
|
|
20
|
+
return;
|
|
21
|
+
if (!active)
|
|
22
|
+
return;
|
|
23
|
+
const interval = setInterval(() => setNow(Date.now()), TICK_MS);
|
|
24
|
+
return () => clearInterval(interval);
|
|
25
|
+
}, [startedAt, finalMs, active]);
|
|
26
|
+
const ms = finalMs !== undefined ? finalMs : startedAt ? now - startedAt : undefined;
|
|
27
|
+
if (ms === undefined)
|
|
28
|
+
return null;
|
|
29
|
+
return _jsxs(Text, { color: color, children: ["(", formatDuration(ms), ")"] });
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=LiveDuration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveDuration.js","sourceRoot":"","sources":["../../src/ui/LiveDuration.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,0DAA0D;AAC1D,MAAM,OAAO,GAAG,GAAG,CAAC;AAgBpB;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAqB;IACnF,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,wEAAwE;QACxE,kCAAkC;QAClC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAClC,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAChE,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAEjC,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAElC,OAAO,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,kBAAI,cAAc,CAAC,EAAE,CAAC,SAAS,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveStatus.d.ts","sourceRoot":"","sources":["../../src/ui/LiveStatus.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAKnD,UAAU,eAAe;IACvB,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,2CAyCnD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { STATUS_ICONS, STATUS_LABELS } from "./format.js";
|
|
4
|
+
import { AnimatedTokens } from "./AnimatedTokens.js";
|
|
5
|
+
import { LiveDuration } from "./LiveDuration.js";
|
|
6
|
+
export function LiveStatus({ jobs }) {
|
|
7
|
+
const done = jobs.filter((j) => j.status === "done").length;
|
|
8
|
+
const failed = jobs.filter((j) => j.status === "failed").length;
|
|
9
|
+
const scoring = jobs.filter((j) => j.status === "scoring").length;
|
|
10
|
+
const total = jobs.length;
|
|
11
|
+
const scenarios = groupByScenario(jobs);
|
|
12
|
+
const scenarioCount = scenarios.length;
|
|
13
|
+
const agentCount = new Set(jobs.map((j) => j.agentName)).size;
|
|
14
|
+
const allFinished = done + failed === total && total > 0;
|
|
15
|
+
const scoredJobs = jobs.filter((j) => j.axisScore !== undefined);
|
|
16
|
+
const avgScore = scoredJobs.length > 0 ? Math.round(scoredJobs.reduce((sum, j) => sum + j.axisScore, 0) / scoredJobs.length) : null;
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsx(Text, { children: " " }), _jsxs(Text, { bold: true, children: ["AXIS \u2014 ", scenarioCount, " scenario", scenarioCount !== 1 ? "s" : "", " \u00B7 ", agentCount, " agent", agentCount !== 1 ? "s" : ""] }), _jsx(Text, { children: "─".repeat(50) }), scenarios.map(({ scenarioKey, agents }) => (_jsx(ScenarioGroup, { scenarioKey: scenarioKey, agents: agents }, scenarioKey))), _jsx(Text, { children: "─".repeat(50) }), allFinished && avgScore !== null ? (_jsxs(Text, { bold: true, children: ["Average AXIS Result: ", avgScore, " / 100"] })) : scoring > 0 ? (_jsxs(Text, { children: [done + failed, "/", total, " complete \u00B7 scoring ", scoring, " result", scoring !== 1 ? "s" : "", "\u2026"] })) : (_jsxs(Text, { children: [done + failed, "/", total, " complete"] })), _jsx(Text, { children: " " })] }));
|
|
18
|
+
}
|
|
19
|
+
function ScenarioGroup({ scenarioKey, agents }) {
|
|
20
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: scenarioKey }), agents.map((job) => (_jsx(AgentRow, { job: job }, job.agentName))), _jsx(Text, { children: " " })] }));
|
|
21
|
+
}
|
|
22
|
+
function AgentRow({ job }) {
|
|
23
|
+
const icon = STATUS_ICONS[job.status] ?? "?";
|
|
24
|
+
const label = (job.status === "done" || job.status === "failed") && job.axisScore !== undefined
|
|
25
|
+
? `${job.axisScore} / 100`
|
|
26
|
+
: (STATUS_LABELS[job.status] ?? job.status);
|
|
27
|
+
const color = job.status === "done"
|
|
28
|
+
? "green"
|
|
29
|
+
: job.status === "failed"
|
|
30
|
+
? "red"
|
|
31
|
+
: job.status === "running" || job.status === "scoring"
|
|
32
|
+
? "yellow"
|
|
33
|
+
: undefined;
|
|
34
|
+
// The timer and token counter are both visible in every state where they
|
|
35
|
+
// have a value. The timer shows live-elapsed during running/scoring and
|
|
36
|
+
// the final `durationMs` afterwards. The token counter keeps animating
|
|
37
|
+
// until it catches up to the final real total even after the job is done.
|
|
38
|
+
const active = job.status === "running" || job.status === "scoring";
|
|
39
|
+
const hasTime = job.runStartedAt !== undefined || job.durationMs !== undefined;
|
|
40
|
+
const hasTokens = (job.liveTokens ?? 0) > 0;
|
|
41
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { color: color, children: [" ", icon, " ", job.agentName.padEnd(20), " ", label.padEnd(15)] }), hasTime ? (_jsx(Box, { marginRight: 1, children: _jsx(LiveDuration, { startedAt: job.runStartedAt, finalMs: job.durationMs, active: active, color: color }) })) : null, hasTokens ? _jsx(AnimatedTokens, { target: job.liveTokens ?? 0, active: active, isFinal: job.tokensFinal }) : null] }));
|
|
42
|
+
}
|
|
43
|
+
function groupByScenario(jobs) {
|
|
44
|
+
const map = new Map();
|
|
45
|
+
for (const job of jobs) {
|
|
46
|
+
const list = map.get(job.scenarioKey) ?? [];
|
|
47
|
+
list.push(job);
|
|
48
|
+
map.set(job.scenarioKey, list);
|
|
49
|
+
}
|
|
50
|
+
return Array.from(map, ([scenarioKey, agents]) => ({ scenarioKey, agents }));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=LiveStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveStatus.js","sourceRoot":"","sources":["../../src/ui/LiveStatus.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { RunOutput, RunResult } from "../types/output.js";
|
|
2
|
+
import type { ScoreResult, ScoredOutput, ScoredRunResult } from "../types/scoring.js";
|
|
3
|
+
import type { ReportManifest } from "../types/report.js";
|
|
4
|
+
import type { Baseline, BaselineDiff } from "../types/baseline.js";
|
|
5
|
+
export declare const STATUS_ICONS: Record<string, string>;
|
|
6
|
+
export declare const STATUS_LABELS: Record<string, string>;
|
|
7
|
+
export declare function formatDuration(ms: number): string;
|
|
8
|
+
/**
|
|
9
|
+
* Simplify a raw error string into a short, actionable message.
|
|
10
|
+
* Returns the original string (truncated) if no known pattern matches.
|
|
11
|
+
*/
|
|
12
|
+
export declare function friendlyError(raw: string, maxLen?: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Build a short insight string identifying the weakest dimension for each
|
|
15
|
+
* category that scored below the threshold. Returns null if all categories are fine.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildScoreInsight(score: ScoreResult): string | null;
|
|
18
|
+
export declare function renderFinalOutput(output: RunOutput, verbose: boolean, agentCount?: number): string;
|
|
19
|
+
export declare function renderSummaryTable(output: RunOutput): string;
|
|
20
|
+
export declare function renderResultDetail(result: RunResult): string;
|
|
21
|
+
export declare function renderScoredOutput(output: ScoredOutput, verbose: boolean, agentCount?: number): string;
|
|
22
|
+
export declare function renderScoredSummaryTable(output: ScoredOutput): string;
|
|
23
|
+
export declare function renderReportList(reports: ReportManifest[]): string;
|
|
24
|
+
export declare function renderReportDetail(report: ReportManifest): string;
|
|
25
|
+
export declare function renderScenarioDetail(result: RunResult | ScoredRunResult): string;
|
|
26
|
+
export declare function renderBaselineList(baselines: Baseline[]): string;
|
|
27
|
+
export declare function renderBaselineShow(baseline: Baseline): string;
|
|
28
|
+
export declare function renderBaselineDiff(diff: BaselineDiff): string;
|
|
29
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/ui/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAmC,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAoBnE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ/C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQhD,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGjD;AAmBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,CAO9D;AASD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CA0BnE;AAyBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAmBlG;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAoC5D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAmC5D;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBtG;AAkFD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAgDrE;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAkClE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA4EjE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,eAAe,GAAG,MAAM,CAuChF;AASD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CA4BhE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAoC7D;AAQD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAmC7D"}
|