Skip to content

Commit 86800ff

Browse files
committed
feat: remote environment support
1 parent 48f913b commit 86800ff

38 files changed

+971
-521
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { getBuiltInRatings } from 'web-codegen-scorer';
2+
3+
/** @type {import("web-codegen-scorer").EnvironmentConfig} */
4+
export default {
5+
displayName: 'Remote Env (example)',
6+
clientSideFramework: 'angular',
7+
sourceDirectory: './project',
8+
ratings: getBuiltInRatings(),
9+
generationSystemPrompt: './system-instructions.md',
10+
executablePrompts: ['../../prompts/**/*.md'],
11+
packageManager: 'npm',
12+
};

report-app/src/app/pages/report-viewer/report-viewer.html

Lines changed: 120 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
label="Score"
1313
size="large"
1414
[total]="overview.totalPoints"
15-
[max]="overview.maxOverallPoints" />
15+
[max]="overview.maxOverallPoints"
16+
/>
1617
</div>
1718
<div>
1819
<h2>{{ overview.displayName }}</h2>
@@ -31,31 +32,29 @@ <h2>{{ overview.displayName }}</h2>
3132
<div class="summary-grid">
3233
<div>
3334
<h3>Model</h3>
34-
<provider-label
35-
[id]="overview.model"
36-
[label]="overview.model"/>
35+
<provider-label [id]="overview.model" [label]="overview.model" />
3736
</div>
3837
@if (fw) {
3938
<div>
4039
<h3>Framework</h3>
4140
<div class="framework-info">
4241
<provider-label
4342
[id]="fw.fullStackFramework.id"
44-
[label]="fw.fullStackFramework.displayName"/>
43+
[label]="fw.fullStackFramework.displayName"
44+
/>
4545
@if (fw.clientSideFramework.id !== fw.fullStackFramework.id) {
4646
<provider-label
4747
[id]="fw.clientSideFramework.id"
48-
[label]="fw.clientSideFramework.displayName"/>
48+
[label]="fw.clientSideFramework.displayName"
49+
/>
4950
}
5051
</div>
5152
</div>
5253
}
5354
@if (runner) {
5455
<div>
5556
<h3>Runner</h3>
56-
<provider-label
57-
[id]="runner.id"
58-
[label]="runner.displayName"/>
57+
<provider-label [id]="runner.id" [label]="runner.displayName" />
5958
</div>
6059
}
6160
</div>
@@ -113,7 +112,9 @@ <h3 class="chart-title">
113112
</h3>
114113
<div class="summary-card-item">
115114
<stacked-bar-chart
116-
[data]="accessibilityStatsAsGraphData(overview.stats.accessibility)!"
115+
[data]="
116+
accessibilityStatsAsGraphData(overview.stats.accessibility)!
117+
"
117118
[compact]="true"
118119
/>
119120
</div>
@@ -124,21 +125,27 @@ <h3 class="chart-title">
124125
@if (details) {
125126
<h3>Usage Details</h3>
126127
<ul class="status-badge-group">
127-
<li class="status-badge neutral">Input tokens: {{ details.summary.usage.inputTokens | number }}</li>
128-
<li class="status-badge neutral">Output tokens: {{ details.summary.usage.outputTokens | number }}</li>
128+
<li class="status-badge neutral">
129+
Input tokens: {{ details.summary.usage.inputTokens | number }}
130+
</li>
131+
<li class="status-badge neutral">
132+
Output tokens: {{ details.summary.usage.outputTokens | number }}
133+
</li>
129134

130135
@if (details.summary.usage.totalTokens != null) {
131-
<li class="status-badge neutral">Total tokens: {{ details.summary.usage.totalTokens | number }}</li>
136+
<li class="status-badge neutral">
137+
Total tokens: {{ details.summary.usage.totalTokens | number }}
138+
</li>
132139
}
133140
</ul>
134141
}
135142
</div>
136143
</section>
137144

138145
@if (isLoading()) {
139-
<message-spinner message="Loading full report"/>
146+
<message-spinner message="Loading full report" />
140147
} @else if (error()) {
141-
<pre class="callout error code">{{error()?.stack}}</pre>
148+
<pre class="callout error code">{{ error()?.stack }}</pre>
142149
} @else if (report) {
143150
@let details = report.details;
144151

@@ -151,12 +158,18 @@ <h3>Usage Details</h3>
151158
@if (details.systemInstructionsPrompt || details.bestPracticesPrompt) {
152159
<!-- Legacy code path for older reports. -->
153160
<h4>System Prompt</h4>
154-
<pre class="callout neutral code">{{ details.systemInstructionsPrompt }}</pre>
161+
<pre class="callout neutral code">{{
162+
details.systemInstructionsPrompt
163+
}}</pre>
155164
<h4>Best Practices Prompt</h4>
156-
<pre class="callout neutral code">{{ details.bestPracticesPrompt }}</pre>
165+
<pre class="callout neutral code">{{
166+
details.bestPracticesPrompt
167+
}}</pre>
157168
} @else {
158169
<h4>Generation System Prompt</h4>
159-
<pre class="callout neutral code">{{ details.systemPromptGeneration }}</pre>
170+
<pre class="callout neutral code">{{
171+
details.systemPromptGeneration
172+
}}</pre>
160173
<h4>Repair System Prompt</h4>
161174
<pre class="callout neutral code">{{ details.systemPromptRepair }}</pre>
162175
}
@@ -219,7 +232,9 @@ <h4>Logs</h4>
219232
<h2>Generated applications</h2>
220233
@if (allFailedChecks().length > 0) {
221234
<details class="filter-dropdown" #dropdown>
222-
<summary>Filter by failed checks ({{ selectedChecks().size }} selected)</summary>
235+
<summary>
236+
Filter by failed checks ({{ selectedChecks().size }} selected)
237+
</summary>
223238
<div class="dropdown-content">
224239
<failed-checks-filter
225240
[allFailedChecks]="allFailedChecks()"
@@ -236,30 +251,32 @@ <h2>Generated applications</h2>
236251
<score
237252
size="small"
238253
[total]="result.score.totalPoints"
239-
[max]="result.score.maxOverallPoints" />
254+
[max]="result.score.maxOverallPoints"
255+
/>
240256
<div class="app-header">
241257
{{ result.promptDef.name }}
242258

243259
<div class="status-badge-group">
244-
@let initialBuild = result.attemptDetails[0].buildResult;
245-
@let repairBuild =
246-
result.attemptDetails.length > 1 ? result.attemptDetails[1].buildResult : null;
247-
@let finalBuild = repairBuild ?? initialBuild;
248-
249-
@if (finalBuild.runtimeErrors) {
260+
@let initialAttempt = result.attemptDetails[0];
261+
@let repairAttempt =
262+
result.attemptDetails.length > 1
263+
? result.attemptDetails[1]
264+
: null;
265+
@let finalAttempt = result.attemptDetails.at(-1)!;
266+
267+
@if (finalAttempt.serveTestingResult?.runtimeErrors) {
250268
<span class="status-badge error">Runtime error</span>
251269
}
252270

253-
@if (repairBuild?.status === 'error') {
271+
@if (repairAttempt?.buildResult?.status === 'error') {
254272
<span class="status-badge error">Build after repair</span>
255273
}
256274

257-
@if (initialBuild.status === 'error') {
275+
@if (initialAttempt?.buildResult?.status === 'error') {
258276
<span class="status-badge error">Initial build failed</span>
259277
}
260278
</div>
261279
</div>
262-
263280
</expansion-panel-header>
264281

265282
@if (appPanel.opened()) {
@@ -273,7 +290,9 @@ <h4>Prompt</h4>
273290
<h4>Results</h4>
274291
@for (category of result.score.categories; track category.id) {
275292
<h5>
276-
{{ category.name }} ({{ category.points }}/{{ category.maxPoints }}
293+
{{ category.name }} ({{ category.points }}/{{
294+
category.maxPoints
295+
}}
277296
points)
278297
</h5>
279298

@@ -283,16 +302,24 @@ <h5>
283302
@if (isSkippedAssessment(check)) {
284303
<span class="status"></span>
285304
<span class="name">{{ check.name }}</span>
286-
<span class="status-text points">Skipped: {{ check.message }}</span>
305+
<span class="status-text points"
306+
>Skipped: {{ check.message }}</span
307+
>
287308
} @else {
288309
@let isMax = check.successPercentage === 1;
289-
<span class="status status-text" [class.success]="isMax" [class.error]="!isMax">{{
290-
isMax ? '✔' : '✘'
291-
}}</span>
310+
<span
311+
class="status status-text"
312+
[class.success]="isMax"
313+
[class.error]="!isMax"
314+
>{{ isMax ? '✔' : '✘' }}</span
315+
>
292316
<span class="name">{{ check.name }}</span>
293-
<span class="status-text points" [class.success]="isMax" [class.error]="!isMax">{{
294-
check.message
295-
}}</span>
317+
<span
318+
class="status-text points"
319+
[class.success]="isMax"
320+
[class.error]="!isMax"
321+
>{{ check.message }}</span
322+
>
296323
}
297324
</div>
298325
} @empty {
@@ -302,15 +329,21 @@ <h5>
302329
}
303330
<!-- Total score section -->
304331
<div class="check-details total">
305-
@let totalPercent = formatScore(result.score.totalPoints, result.score.maxOverallPoints);
332+
@let totalPercent =
333+
formatScore(
334+
result.score.totalPoints,
335+
result.score.maxOverallPoints
336+
);
306337
<span class="status"></span>
307338
<span class="name">Total: &nbsp;</span>
308339
<span
309340
class="status-text points"
310341
[class.success]="totalPercent >= 90"
311342
[class.warn]="totalPercent < 90 && totalPercent >= 80"
312-
[class.error]="totalPercent < 80">
313-
{{ result.score.totalPoints }} / {{ result.score.maxOverallPoints }} points ({{
343+
[class.error]="totalPercent < 80"
344+
>
345+
{{ result.score.totalPoints }} /
346+
{{ result.score.maxOverallPoints }} points ({{
314347
totalPercent
315348
}})
316349
</span>
@@ -321,34 +354,48 @@ <h5>
321354
<h4>Additional info</h4>
322355
@for (attempt of result.attemptDetails; track attempt) {
323356
@let isBuilt = attempt.buildResult.status === 'success';
324-
@let axeViolations = attempt.buildResult.axeViolations;
325-
@let hasAxeViolations = axeViolations && axeViolations.length > 0;
357+
@let axeViolations =
358+
attempt.serveTestingResult?.axeViolations;
359+
@let hasAxeViolations =
360+
axeViolations && axeViolations.length > 0;
326361

327362
<expansion-panel #expansionPanel>
328363
<expansion-panel-header>
329-
{{ $index === 0 ? 'Initial response' : `Repair attempt #${$index}` }}
364+
{{
365+
$index === 0
366+
? 'Initial response'
367+
: `Repair attempt #${$index}`
368+
}}
330369
@if (!isBuilt) {
331-
<span
332-
class="status-badge"
333-
[class.error]="!isBuilt">Build</span>
370+
<span class="status-badge" [class.error]="!isBuilt"
371+
>Build</span
372+
>
334373
}
335374
@if (hasAxeViolations) {
336-
<span
337-
class="status-badge"
338-
[class.error]="hasAxeViolations">A11y</span>
375+
<span
376+
class="status-badge"
377+
[class.error]="hasAxeViolations"
378+
>A11y</span
379+
>
339380
}
340381
</expansion-panel-header>
341382

342383
@if (expansionPanel.opened()) {
343384
@if (attempt.reasoning) {
344385
<details class="thoughts-button">
345-
<summary class="neutral-button">See LLM Thoughts</summary>
346-
<pre class="callout neutral code">{{ attempt.reasoning }}</pre>
386+
<summary class="neutral-button">
387+
See LLM Thoughts
388+
</summary>
389+
<pre class="callout neutral code">{{
390+
attempt.reasoning
391+
}}</pre>
347392
</details>
348393
}
349394
@if (!isBuilt) {
350395
<h4>Build Message</h4>
351-
<pre class="callout warn code">{{ attempt.buildResult.message }}</pre>
396+
<pre class="callout warn code">{{
397+
attempt.buildResult.message
398+
}}</pre>
352399
}
353400

354401
@if (hasAxeViolations) {
@@ -381,17 +428,26 @@ <h4>Generated Code</h4>
381428
Format source code
382429
</button>
383430
</div>
384-
<app-code-viewer [code]="formatted().get(file) ?? file.code" />
431+
<app-code-viewer
432+
[code]="formatted().get(file) ?? file.code"
433+
/>
385434
}
386435
}
387436
</expansion-panel>
388437
}
389438

390-
@if (result.userJourneys && result.userJourneys.result.length > 0) {
439+
@if (
440+
result.userJourneys && result.userJourneys.result.length > 0
441+
) {
391442
<expansion-panel>
392-
<expansion-panel-header>User Journeys</expansion-panel-header>
393-
@for (journey of result.userJourneys.result; track journey.name) {
394-
<h4>{{journey.name}}</h4>
443+
<expansion-panel-header
444+
>User Journeys</expansion-panel-header
445+
>
446+
@for (
447+
journey of result.userJourneys.result;
448+
track journey.name
449+
) {
450+
<h4>{{ journey.name }}</h4>
395451

396452
<ol>
397453
@for (step of journey.steps; track $index) {
@@ -408,15 +464,18 @@ <h4>Debugging Tools</h4>
408464
<button
409465
class="neutral-button"
410466
title="Download a ZIP for debugging. You can upload the ZIP to AI Studio for further analysis of a specific app."
411-
(click)="downloadDebuggingZip(result)">
467+
(click)="downloadDebuggingZip(result)"
468+
>
412469
Download ZIP for debugging
413470
</button>
414471
</div>
415472

416-
@if (finalBuild.runtimeErrors) {
473+
@let finalRuntimeErrors =
474+
finalAttempt.serveTestingResult?.runtimeErrors;
475+
@if (finalRuntimeErrors) {
417476
<div class="app-details-section">
418477
<h4>Runtime errors</h4>
419-
<pre class="callout warn code">{{ finalBuild.runtimeErrors }}</pre>
478+
<pre class="callout warn code">{{ finalRuntimeErrors }}</pre>
420479
</div>
421480
}
422481

@@ -425,7 +484,7 @@ <h4>Runtime errors</h4>
425484
@if (screenshot) {
426485
<div class="app-details-section">
427486
<h4>Screenshot</h4>
428-
<img class="screenshot" [src]="screenshot"/>
487+
<img class="screenshot" [src]="screenshot" />
429488
</div>
430489
}
431490
</div>

report-app/src/app/pages/report-viewer/report-viewer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
signal,
1212
viewChild,
1313
} from '@angular/core';
14-
import { BuildErrorType } from '../../../../../runner/builder/builder-types';
14+
import { BuildErrorType } from '../../../../../runner/workers/builder/builder-types';
1515
import {
1616
AssessmentResult,
1717
IndividualAssessment,
@@ -235,7 +235,7 @@ export class ReportViewer {
235235
});
236236

237237
protected getScreenshotUrl(result: AssessmentResult): string | null {
238-
return result.build.screenshotPngUrl ?? null;
238+
return result.finalAttempt.serveTestingResult?.screenshotPngUrl ?? null;
239239
}
240240

241241
protected isLoading = this.reportsFetcher.isLoadingSingleReport;

0 commit comments

Comments
 (0)