agent-scenario-loop 0.1.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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/app/profile-session.ts +812 -0
  4. package/core/config-template.json +41 -0
  5. package/dist/core/agent-summary.d.ts +15 -0
  6. package/dist/core/agent-summary.js +177 -0
  7. package/dist/core/artifact-contract.d.ts +151 -0
  8. package/dist/core/artifact-contract.js +897 -0
  9. package/dist/core/artifact-layout.d.ts +56 -0
  10. package/dist/core/artifact-layout.js +61 -0
  11. package/dist/core/artifact-writer.d.ts +44 -0
  12. package/dist/core/artifact-writer.js +55 -0
  13. package/dist/core/comparison.d.ts +133 -0
  14. package/dist/core/comparison.js +294 -0
  15. package/dist/core/evidence-interpreter.d.ts +28 -0
  16. package/dist/core/evidence-interpreter.js +69 -0
  17. package/dist/core/execution-plan.d.ts +44 -0
  18. package/dist/core/execution-plan.js +95 -0
  19. package/dist/core/planner.d.ts +132 -0
  20. package/dist/core/planner.js +812 -0
  21. package/dist/core/ports.d.ts +198 -0
  22. package/dist/core/ports.js +146 -0
  23. package/dist/core/run-index.d.ts +62 -0
  24. package/dist/core/run-index.js +143 -0
  25. package/dist/core/schema-validator.d.ts +86 -0
  26. package/dist/core/schema-validator.js +407 -0
  27. package/dist/index.d.ts +11 -0
  28. package/dist/index.js +27 -0
  29. package/dist/runner/agent-device-driver.d.ts +126 -0
  30. package/dist/runner/agent-device-driver.js +168 -0
  31. package/dist/runner/agent-device.d.ts +295 -0
  32. package/dist/runner/agent-device.js +1271 -0
  33. package/dist/runner/android-adb-driver.d.ts +175 -0
  34. package/dist/runner/android-adb-driver.js +399 -0
  35. package/dist/runner/android-adb.d.ts +254 -0
  36. package/dist/runner/android-adb.js +1618 -0
  37. package/dist/runner/argent-driver.d.ts +183 -0
  38. package/dist/runner/argent-driver.js +297 -0
  39. package/dist/runner/argent.d.ts +349 -0
  40. package/dist/runner/argent.js +1211 -0
  41. package/dist/runner/check-plan.d.ts +45 -0
  42. package/dist/runner/check-plan.js +210 -0
  43. package/dist/runner/cli.d.ts +20 -0
  44. package/dist/runner/cli.js +23 -0
  45. package/dist/runner/compare-latest.d.ts +99 -0
  46. package/dist/runner/compare-latest.js +233 -0
  47. package/dist/runner/compare.d.ts +58 -0
  48. package/dist/runner/compare.js +157 -0
  49. package/dist/runner/demo-loop.d.ts +45 -0
  50. package/dist/runner/demo-loop.js +170 -0
  51. package/dist/runner/example-android-live.d.ts +137 -0
  52. package/dist/runner/example-android-live.js +454 -0
  53. package/dist/runner/example-ios-live.d.ts +137 -0
  54. package/dist/runner/example-ios-live.js +471 -0
  55. package/dist/runner/host-doctor.d.ts +131 -0
  56. package/dist/runner/host-doctor.js +628 -0
  57. package/dist/runner/init-project.d.ts +88 -0
  58. package/dist/runner/init-project.js +263 -0
  59. package/dist/runner/ios-simctl-driver.d.ts +69 -0
  60. package/dist/runner/ios-simctl-driver.js +97 -0
  61. package/dist/runner/ios-simctl.d.ts +254 -0
  62. package/dist/runner/ios-simctl.js +1415 -0
  63. package/dist/runner/live-android.d.ts +137 -0
  64. package/dist/runner/live-android.js +539 -0
  65. package/dist/runner/live-comparison.d.ts +67 -0
  66. package/dist/runner/live-comparison.js +147 -0
  67. package/dist/runner/live-ios.d.ts +137 -0
  68. package/dist/runner/live-ios.js +460 -0
  69. package/dist/runner/live-proof-summary.d.ts +263 -0
  70. package/dist/runner/live-proof-summary.js +465 -0
  71. package/dist/runner/live-proof.d.ts +467 -0
  72. package/dist/runner/live-proof.js +920 -0
  73. package/dist/runner/local-env.d.ts +64 -0
  74. package/dist/runner/local-env.js +155 -0
  75. package/dist/runner/profile-android.d.ts +82 -0
  76. package/dist/runner/profile-android.js +671 -0
  77. package/dist/runner/profile-ios.d.ts +108 -0
  78. package/dist/runner/profile-ios.js +532 -0
  79. package/dist/runner/profile-mobile.d.ts +254 -0
  80. package/dist/runner/profile-mobile.js +1307 -0
  81. package/dist/runner/validate-project.d.ts +273 -0
  82. package/dist/runner/validate-project.js +1501 -0
  83. package/docs/adapters.md +145 -0
  84. package/docs/api.md +94 -0
  85. package/docs/authoring.md +196 -0
  86. package/docs/concepts.md +136 -0
  87. package/docs/consumer-rehearsal.md +115 -0
  88. package/docs/contracts.md +267 -0
  89. package/docs/live-proofs.md +270 -0
  90. package/docs/principles.md +46 -0
  91. package/examples/event-logs/app-startup-baseline.log +4 -0
  92. package/examples/event-logs/app-startup-current.log +4 -0
  93. package/examples/minimal-app/README.md +70 -0
  94. package/examples/mobile-app/README.md +302 -0
  95. package/examples/mobile-app/app.json +22 -0
  96. package/examples/mobile-app/asl/package-scripts.json +32 -0
  97. package/examples/mobile-app/asl.config.json +37 -0
  98. package/examples/mobile-app/event-logs/android-app-startup.log +4 -0
  99. package/examples/mobile-app/event-logs/android-open-close-cycle.log +12 -0
  100. package/examples/mobile-app/event-logs/android-scroll-settle.log +12 -0
  101. package/examples/mobile-app/event-logs/app-startup.log +4 -0
  102. package/examples/mobile-app/event-logs/open-close-cycle.log +12 -0
  103. package/examples/mobile-app/event-logs/scroll-settle.log +12 -0
  104. package/examples/mobile-app/index.ts +20 -0
  105. package/examples/mobile-app/metro.config.js +20 -0
  106. package/examples/mobile-app/package.json +62 -0
  107. package/examples/mobile-app/patches/expo-modules-jsi@56.0.10.patch +19 -0
  108. package/examples/mobile-app/plugins/with-ios-build-compat.js +271 -0
  109. package/examples/mobile-app/pnpm-lock.yaml +4440 -0
  110. package/examples/mobile-app/runner-manifests/evidence-provider.json +79 -0
  111. package/examples/mobile-app/runner-manifests/primary-runner.json +19 -0
  112. package/examples/mobile-app/scenarios/android/app-startup-video.json +73 -0
  113. package/examples/mobile-app/scenarios/android/app-startup.json +44 -0
  114. package/examples/mobile-app/scenarios/android/open-close-cycle.json +54 -0
  115. package/examples/mobile-app/scenarios/android/scroll-settle.json +49 -0
  116. package/examples/mobile-app/scenarios/ios/app-startup.json +44 -0
  117. package/examples/mobile-app/scenarios/ios/open-close-cycle.json +54 -0
  118. package/examples/mobile-app/scenarios/ios/scroll-settle.json +49 -0
  119. package/examples/mobile-app/scenarios/mobile/app-startup.json +91 -0
  120. package/examples/mobile-app/scenarios/mobile/open-close-cycle.json +160 -0
  121. package/examples/mobile-app/scenarios/mobile/scroll-settle.json +148 -0
  122. package/examples/mobile-app/scripts/asl-capture-accessibility-provider.mjs +112 -0
  123. package/examples/mobile-app/scripts/asl-capture-profiler-provider.mjs +127 -0
  124. package/examples/mobile-app/src/devtools/profile-session.ts +7 -0
  125. package/examples/mobile-app/src/example-screen.tsx +322 -0
  126. package/examples/mobile-app/tsconfig.json +16 -0
  127. package/examples/mobile-app/tsconfig.typecheck.json +13 -0
  128. package/examples/runners/README.md +44 -0
  129. package/examples/runners/adb-android.json +25 -0
  130. package/examples/runners/agent-device-android.json +27 -0
  131. package/examples/runners/agent-device-ios.json +27 -0
  132. package/examples/runners/argent-android.json +32 -0
  133. package/examples/runners/argent-ios.json +32 -0
  134. package/examples/runners/argent-react-profiler-provider.json +15 -0
  135. package/examples/runners/axe-accessibility-provider.json +24 -0
  136. package/examples/runners/manual-log-ingest.json +9 -0
  137. package/examples/runners/rozenite-profiler-provider.json +9 -0
  138. package/examples/runners/script-accessibility-provider.json +24 -0
  139. package/examples/runners/script-memory-provider.json +24 -0
  140. package/examples/runners/script-network-provider.json +24 -0
  141. package/examples/runners/script-profiler-provider.json +30 -0
  142. package/examples/runners/xcodebuildmcp-ios.json +29 -0
  143. package/examples/scenarios/ios/app-startup.json +28 -0
  144. package/examples/scenarios/ios/open-close-cycle.json +35 -0
  145. package/examples/scenarios/mobile/app-startup.json +72 -0
  146. package/examples/scenarios/mobile/media-open-close.json +141 -0
  147. package/examples/scenarios/mobile/open-close-cycle.json +135 -0
  148. package/examples/scenarios/mobile/scroll-settle.json +106 -0
  149. package/package.json +240 -0
  150. package/schemas/budget-verdict.schema.json +115 -0
  151. package/schemas/causal-run.schema.json +279 -0
  152. package/schemas/comparison.schema.json +196 -0
  153. package/schemas/health.schema.json +108 -0
  154. package/schemas/live-proof-set.schema.json +195 -0
  155. package/schemas/live-proof.schema.json +413 -0
  156. package/schemas/manifest.schema.json +204 -0
  157. package/schemas/metrics.schema.json +137 -0
  158. package/schemas/project-validation.schema.json +343 -0
  159. package/schemas/runner-capabilities.schema.json +217 -0
  160. package/schemas/scenario.schema.json +400 -0
  161. package/schemas/verdict.schema.json +88 -0
  162. package/templates/evidence-provider.json +83 -0
  163. package/templates/gitignore-snippet +9 -0
  164. package/templates/integration-readme.md +125 -0
  165. package/templates/mobile-scenario.json +133 -0
  166. package/templates/package-scripts.json +32 -0
  167. package/templates/primary-runner.json +19 -0
  168. package/templates/project.config.json +37 -0
  169. package/templates/scripts/asl-capture-accessibility-provider.mjs +112 -0
  170. package/templates/scripts/asl-capture-profiler-provider.mjs +127 -0
@@ -0,0 +1,41 @@
1
+ {
2
+ "projectName": "replace-me",
3
+ "app": {
4
+ "displayName": "Example App",
5
+ "scheme": "example-app",
6
+ "profileSessionScheme": "example-app",
7
+ "iosBundleId": "com.example.app",
8
+ "iosConflictingBundleIds": [],
9
+ "androidPackage": "com.example.app",
10
+ "ios": {
11
+ "xcodeScheme": "Example App",
12
+ "launchConfiguration": "Debug",
13
+ "profileConfiguration": "Release"
14
+ }
15
+ },
16
+ "paths": {
17
+ "artifactRoot": "artifacts/asl",
18
+ "iosArtifactsRoot": "artifacts/asl/ios",
19
+ "androidArtifactsRoot": "artifacts/asl/android",
20
+ "scenarioRoot": "examples/scenarios/mobile",
21
+ "iosScenarioRoot": "examples/scenarios/ios",
22
+ "androidScenarioRoot": "examples/scenarios/mobile"
23
+ },
24
+ "drivers": {
25
+ "default": "fixture-log-ingest",
26
+ "supported": ["fixture-log-ingest", "adb", "ios-simctl", "agent-device", "argent", "xcodebuildmcp"]
27
+ },
28
+ "versionControl": {
29
+ "commit": [
30
+ "core/**",
31
+ "runner/**",
32
+ "app/**",
33
+ "examples/scenarios/**",
34
+ "docs/**"
35
+ ],
36
+ "ignore": [
37
+ "artifacts/asl/**",
38
+ "raw simulator recordings, screenshots, and ephemeral profiler exports"
39
+ ]
40
+ }
41
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Builds the minimum agent-facing markdown summary for a run.
3
+ *
4
+ * @param {{health: Record<string, unknown>, verdict: Record<string, unknown>, comparison?: Record<string, unknown> | null}} options
5
+ * @returns {string}
6
+ */
7
+ declare function buildAgentSummaryMarkdown({ health, verdict, comparison }: AgentSummaryInput): string;
8
+ export { buildAgentSummaryMarkdown, };
9
+ export type { AgentSummaryInput, SummaryRecord, };
10
+ type SummaryRecord = Record<string, unknown>;
11
+ type AgentSummaryInput = {
12
+ health: SummaryRecord;
13
+ verdict: SummaryRecord;
14
+ comparison?: SummaryRecord | null;
15
+ };
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAgentSummaryMarkdown = buildAgentSummaryMarkdown;
4
+ /**
5
+ * Returns an array when the value is already an array; otherwise returns an empty array.
6
+ *
7
+ * @param {unknown} value
8
+ * @returns {unknown[]}
9
+ */
10
+ function asArray(value) {
11
+ return Array.isArray(value) ? value : [];
12
+ }
13
+ /**
14
+ * Wraps a scalar value in markdown code ticks.
15
+ *
16
+ * @param {unknown} value
17
+ * @returns {string}
18
+ */
19
+ function code(value) {
20
+ return `\`${String(value ?? 'unknown')}\``;
21
+ }
22
+ /**
23
+ * Reads the first non-empty string from candidate values.
24
+ *
25
+ * @param {unknown[]} values
26
+ * @param {string} fallback
27
+ * @returns {string}
28
+ */
29
+ function firstString(values, fallback) {
30
+ const found = values.find((value) => typeof value === 'string' && value.length > 0);
31
+ return typeof found === 'string' ? found : fallback;
32
+ }
33
+ /**
34
+ * Formats an optional next-action hint stored on a health check.
35
+ *
36
+ * @param {SummaryRecord} record
37
+ * @returns {string}
38
+ */
39
+ function formatNextAction(record) {
40
+ const metadata = record.metadata;
41
+ if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) {
42
+ return '';
43
+ }
44
+ const metadataRecord = metadata;
45
+ const nextAction = firstString([metadataRecord.nextAction], '');
46
+ if (!nextAction) {
47
+ return '';
48
+ }
49
+ const nextActionCode = firstString([metadataRecord.nextActionCode], '');
50
+ return nextActionCode
51
+ ? ` Next action ${code(nextActionCode)}: ${nextAction}`
52
+ : ` Next action: ${nextAction}`;
53
+ }
54
+ /**
55
+ * Formats health or warning checks as markdown list items.
56
+ *
57
+ * @param {unknown[]} checks
58
+ * @returns {string[]}
59
+ */
60
+ function formatChecks(checks) {
61
+ return asArray(checks).map((check) => {
62
+ if (!check || typeof check !== 'object') {
63
+ return '- unknown check';
64
+ }
65
+ const record = check;
66
+ const name = firstString([record.name, record.code], 'unknown_check');
67
+ const status = firstString([record.status], 'unknown');
68
+ const message = firstString([record.message], 'no message');
69
+ return `- ${code(name)}: ${status} - ${message}${formatNextAction(record)}`;
70
+ });
71
+ }
72
+ /**
73
+ * Formats failed budget checks as markdown list items.
74
+ *
75
+ * @param {unknown[]} budgetChecks
76
+ * @returns {string[]}
77
+ */
78
+ function formatFailedBudgets(budgetChecks) {
79
+ return asArray(budgetChecks)
80
+ .filter((check) => {
81
+ const record = check;
82
+ return !!record && typeof record === 'object' && record.pass === false;
83
+ })
84
+ .map((check) => {
85
+ const record = check;
86
+ const name = firstString([record.name], 'unknown budget');
87
+ const metric = firstString([record.metric], 'unknown metric');
88
+ return `- ${name}: ${metric} expected ${record.expected ?? 'n/a'}, actual ${record.actual ?? 'n/a'}`;
89
+ });
90
+ }
91
+ /**
92
+ * Formats comparison provenance for agent-readable summaries.
93
+ *
94
+ * @param {SummaryRecord} comparison
95
+ * @returns {string[]}
96
+ */
97
+ function formatComparisonBasis(comparison) {
98
+ const basis = comparison.comparisonBasis;
99
+ if (!basis || typeof basis !== 'object' || Array.isArray(basis)) {
100
+ return [];
101
+ }
102
+ const basisRecord = basis;
103
+ const baseline = basisRecord.baseline;
104
+ const current = basisRecord.current;
105
+ if (!baseline || typeof baseline !== 'object' || !current || typeof current !== 'object') {
106
+ return [];
107
+ }
108
+ const baselineRecord = baseline;
109
+ const currentRecord = current;
110
+ const lines = [
111
+ '',
112
+ '## comparison basis',
113
+ '',
114
+ `- Strategy: ${code(firstString([basisRecord.strategy], 'unknown'))}`,
115
+ `- Baseline: ${code(firstString([baselineRecord.runId], 'unknown-baseline'))} at ${code(firstString([baselineRecord.runDir], 'unknown-dir'))}`,
116
+ `- Current: ${code(firstString([currentRecord.runId], 'unknown-current'))} at ${code(firstString([currentRecord.runDir], 'unknown-dir'))}`,
117
+ ];
118
+ const selection = basisRecord.selection;
119
+ if (selection && typeof selection === 'object' && !Array.isArray(selection)) {
120
+ const selectionRecord = selection;
121
+ lines.push(`- Selection: inspected ${selectionRecord.candidatesInspected ?? 'unknown'}, trusted ${selectionRecord.trustedCandidates ?? 'unknown'}, trusted prior ${selectionRecord.trustedPriorCandidates ?? 'unknown'}, skipped current ${selectionRecord.skippedCurrentRun ?? 'unknown'}`);
122
+ }
123
+ return lines;
124
+ }
125
+ /**
126
+ * Builds the minimum agent-facing markdown summary for a run.
127
+ *
128
+ * @param {{health: Record<string, unknown>, verdict: Record<string, unknown>, comparison?: Record<string, unknown> | null}} options
129
+ * @returns {string}
130
+ */
131
+ function buildAgentSummaryMarkdown({ health, verdict, comparison = null }) {
132
+ const scenarioId = firstString([health?.scenarioId, verdict?.scenarioId], 'unknown-scenario');
133
+ const runId = firstString([health?.runId, verdict?.runId], 'unknown-run');
134
+ const healthStatus = firstString([health?.healthStatus], 'failed');
135
+ const verdictStatus = firstString([verdict?.verdictStatus], 'inconclusive');
136
+ const comparisonStatus = comparison
137
+ ? firstString([comparison.comparisonStatus], 'inconclusive')
138
+ : 'not_available';
139
+ const lines = [
140
+ '# agent summary',
141
+ '',
142
+ `- Scenario: ${code(scenarioId)}`,
143
+ `- Run ID: ${code(runId)}`,
144
+ `- Health: ${healthStatus}`,
145
+ `- Verdict: ${verdictStatus}`,
146
+ `- Comparison: ${comparisonStatus}`,
147
+ '',
148
+ '## gate',
149
+ '',
150
+ ];
151
+ if (healthStatus === 'passed') {
152
+ lines.push('Scenario health passed. Optimization claims still require verdict or comparison evidence.');
153
+ }
154
+ else {
155
+ lines.push('Do not optimize from this run. Scenario health did not pass.');
156
+ }
157
+ const failedChecks = asArray(health?.checks).filter((check) => {
158
+ const record = check;
159
+ return !!record && typeof record === 'object' && record.status !== 'passed';
160
+ });
161
+ if (failedChecks.length > 0) {
162
+ lines.push('', '## failed checks', '', ...formatChecks(failedChecks));
163
+ }
164
+ const warnings = asArray(health?.warnings);
165
+ if (warnings.length > 0) {
166
+ lines.push('', '## warnings', '', ...formatChecks(warnings));
167
+ }
168
+ const failedBudgets = formatFailedBudgets(asArray(verdict?.budgetChecks));
169
+ if (failedBudgets.length > 0) {
170
+ lines.push('', '## failed budgets', '', ...failedBudgets);
171
+ }
172
+ if (comparison) {
173
+ lines.push('', '## comparison', '', firstString([comparison.summary], 'No comparison summary provided.'));
174
+ lines.push(...formatComparisonBasis(comparison));
175
+ }
176
+ return `${lines.join('\n')}\n`;
177
+ }
@@ -0,0 +1,151 @@
1
+ declare const PROFILE_EVENT_PREFIX = "[profile-event]";
2
+ type ArtifactRecord = Record<string, any>;
3
+ type ProfileEvent = ArtifactRecord & {
4
+ event?: string;
5
+ scenario?: string;
6
+ runId?: string;
7
+ iteration?: number;
8
+ atMs?: number;
9
+ timestamp?: number | string;
10
+ };
11
+ type BudgetCheck = {
12
+ name: string;
13
+ actual: unknown;
14
+ limit: number;
15
+ pass: boolean;
16
+ unit: string;
17
+ };
18
+ /**
19
+ * Returns a nearest-rank percentile for numeric measurements.
20
+ *
21
+ * @param {number[]} values
22
+ * @param {number} percentileValue
23
+ * @returns {number | null}
24
+ */
25
+ declare function percentile(values: number[], percentileValue: number): number | null;
26
+ /**
27
+ * Extracts structured profile events from device logs.
28
+ *
29
+ * Supports both JSON payloads and the older key/value payload format.
30
+ *
31
+ * @param {string} logText
32
+ * @param {{runId?: string, scenario?: string}} [filters]
33
+ * @returns {Record<string, unknown>[]}
34
+ */
35
+ declare function extractProfileEvents(logText: string, filters?: {
36
+ runId?: string;
37
+ scenario?: string;
38
+ }): ProfileEvent[];
39
+ /**
40
+ * Builds timing metrics from app-emitted profile events.
41
+ *
42
+ * @param {{scenario: string, runId: string, events: Record<string, unknown>[], expectedIterations: number, timeoutCount?: number, artifacts?: Record<string, unknown>, cycleEventNames?: Record<string, string> | null, budgets?: Record<string, unknown> | null}} options
43
+ * @returns {Record<string, unknown>}
44
+ */
45
+ declare function buildMetricsFromProfileEvents({ scenario, runId, events, expectedIterations, timeoutCount, artifacts, cycleEventNames, budgets, }: {
46
+ scenario: string;
47
+ runId: string;
48
+ events: ProfileEvent[];
49
+ expectedIterations: number;
50
+ timeoutCount?: number;
51
+ artifacts?: ArtifactRecord;
52
+ cycleEventNames?: ArtifactRecord | null;
53
+ budgets?: ArtifactRecord | null;
54
+ }): ArtifactRecord;
55
+ /**
56
+ * Evaluates configured profile budgets against generated metrics.
57
+ *
58
+ * @param {{metrics: Record<string, unknown>, budgets?: Record<string, unknown> | null}} options
59
+ * @returns {Record<string, unknown> | null}
60
+ */
61
+ declare function evaluateProfileBudgets({ metrics, budgets }: {
62
+ metrics: ArtifactRecord;
63
+ budgets?: ArtifactRecord | null;
64
+ }): ArtifactRecord | null;
65
+ /**
66
+ * Recursively sorts object keys and array values for stable JSON artifacts.
67
+ *
68
+ * @param {unknown} value
69
+ * @returns {unknown}
70
+ */
71
+ declare function sortValue(value: any): any;
72
+ /**
73
+ * Builds a causal timeline from app-owned profile events.
74
+ *
75
+ * @param {{events: Record<string, unknown>[], startedAt?: string, phaseMap?: Record<string, string> | null, owner?: string | null}} options
76
+ * @returns {Record<string, unknown>[]}
77
+ */
78
+ declare function buildCausalTimeline({ events, startedAt, phaseMap, owner, }: {
79
+ events: ProfileEvent[];
80
+ startedAt?: string;
81
+ phaseMap?: ArtifactRecord | null;
82
+ owner?: string | null;
83
+ }): ArtifactRecord[];
84
+ /**
85
+ * Builds the `budget-verdict.json` profile artifact from budget evaluation.
86
+ *
87
+ * @param {{flowId: string, runId: string, budgetEvaluation?: Record<string, unknown> | null, visualOutcome?: Record<string, unknown> | null, baselineRunId?: string | null}} options
88
+ * @returns {Record<string, unknown> | null}
89
+ */
90
+ declare function buildBudgetVerdict({ flowId, runId, budgetEvaluation, visualOutcome, baselineRunId, }: {
91
+ flowId: string;
92
+ runId: string;
93
+ budgetEvaluation?: ArtifactRecord | null;
94
+ visualOutcome?: ArtifactRecord | null;
95
+ baselineRunId?: string | null;
96
+ }): ArtifactRecord | null;
97
+ /**
98
+ * Builds the `causal-run.json` profile artifact.
99
+ *
100
+ * @param {Record<string, unknown>} options
101
+ * @returns {Record<string, unknown>}
102
+ */
103
+ declare function buildCausalRun({ scenario, flowId, runId, platform, buildFlavor, interactionDriver, trigger, budgets, timeline, artifacts, manifest, metrics, }: ArtifactRecord): ArtifactRecord;
104
+ /**
105
+ * Builds the run manifest artifact.
106
+ *
107
+ * @param {Record<string, unknown>} options
108
+ * @returns {Record<string, unknown>}
109
+ */
110
+ declare function buildManifest({ scenario, scenarioHash, runId, platform, status, startedAt, endedAt, interactionDriver, comparisonLane, simulator, bundleId, gitSha, toolVersions, artifacts, failureReason, }: ArtifactRecord): ArtifactRecord;
111
+ /**
112
+ * Builds the human-readable profile summary.
113
+ *
114
+ * @param {{manifest: Record<string, unknown>, metrics: Record<string, unknown>}} options
115
+ * @returns {string}
116
+ */
117
+ declare function buildSummaryMarkdown({ manifest, metrics }: {
118
+ manifest: ArtifactRecord;
119
+ metrics: ArtifactRecord;
120
+ }): string;
121
+ /**
122
+ * Extracts possible accessibility or test identifiers from a UI tree dump.
123
+ *
124
+ * @param {string} rawDescription
125
+ * @returns {string[]}
126
+ */
127
+ declare function extractCandidateIdentifiers(rawDescription: string): string[];
128
+ /**
129
+ * Finds the first UI identifier matching a required pattern.
130
+ *
131
+ * @param {string} rawDescription
132
+ * @param {string} pattern
133
+ * @returns {string | null}
134
+ */
135
+ declare function findMatchingIdentifier(rawDescription: string, pattern: string): string | null;
136
+ /**
137
+ * Evaluates a UI contract from required identifier patterns.
138
+ *
139
+ * @param {{rawDescription: string, requiredIdentifierPatterns?: string[]}} options
140
+ * @returns {{pass: boolean, checks: Record<string, unknown>[], missingPatterns: string[]}}
141
+ */
142
+ declare function evaluateUiContract({ rawDescription, requiredIdentifierPatterns, }: {
143
+ rawDescription: string;
144
+ requiredIdentifierPatterns?: string[];
145
+ }): {
146
+ pass: boolean;
147
+ checks: ArtifactRecord[];
148
+ missingPatterns: string[];
149
+ };
150
+ export { PROFILE_EVENT_PREFIX, buildBudgetVerdict, buildCausalRun, buildCausalTimeline, buildManifest, buildMetricsFromProfileEvents, buildSummaryMarkdown, evaluateUiContract, evaluateProfileBudgets, extractCandidateIdentifiers, extractProfileEvents, findMatchingIdentifier, percentile, sortValue, };
151
+ export type { ArtifactRecord, BudgetCheck, ProfileEvent, };