@shipfox/client-workflows 16.0.0 → 18.0.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +32 -0
- package/dist/components/identifier/identifier.js +2 -2
- package/dist/components/identifier/identifier.js.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js.map +1 -1
- package/dist/components/job-detail/job-context-panel.d.ts +6 -0
- package/dist/components/job-detail/job-context-panel.d.ts.map +1 -0
- package/dist/components/job-detail/job-context-panel.js +228 -0
- package/dist/components/job-detail/job-context-panel.js.map +1 -0
- package/dist/components/job-detail/job-detail-header.d.ts +3 -1
- package/dist/components/job-detail/job-detail-header.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-header.js +54 -48
- package/dist/components/job-detail/job-detail-header.js.map +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-view.js +100 -57
- package/dist/components/job-detail/job-detail-view.js.map +1 -1
- package/dist/components/job-detail/job-empty-states.d.ts +4 -0
- package/dist/components/job-detail/job-empty-states.d.ts.map +1 -1
- package/dist/components/job-detail/job-empty-states.js +60 -11
- package/dist/components/job-detail/job-empty-states.js.map +1 -1
- package/dist/components/job-detail/job-execution-switcher.js +4 -4
- package/dist/components/job-detail/job-execution-switcher.js.map +1 -1
- package/dist/components/job-detail/json-code.d.ts +14 -0
- package/dist/components/job-detail/json-code.d.ts.map +1 -0
- package/dist/components/job-detail/json-code.js +93 -0
- package/dist/components/job-detail/json-code.js.map +1 -0
- package/dist/components/job-detail/step-attempt-log-panel.d.ts.map +1 -1
- package/dist/components/job-detail/step-attempt-log-panel.js +9 -6
- package/dist/components/job-detail/step-attempt-log-panel.js.map +1 -1
- package/dist/components/job-detail/step-troubleshooting.d.ts +18 -0
- package/dist/components/job-detail/step-troubleshooting.d.ts.map +1 -0
- package/dist/components/job-detail/step-troubleshooting.js +497 -0
- package/dist/components/job-detail/step-troubleshooting.js.map +1 -0
- package/dist/components/job-graph/job-graph-content.d.ts.map +1 -1
- package/dist/components/job-graph/job-graph-content.js +5 -4
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/job-graph/job-node.js +3 -3
- package/dist/components/job-graph/job-node.js.map +1 -1
- package/dist/components/step-list/index.d.ts +1 -0
- package/dist/components/step-list/index.d.ts.map +1 -1
- package/dist/components/step-list/index.js.map +1 -1
- package/dist/components/step-list/step-list-model.d.ts.map +1 -1
- package/dist/components/step-list/step-list-model.js +6 -0
- package/dist/components/step-list/step-list-model.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +5 -1
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js +117 -82
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-duration-label.js +1 -1
- package/dist/components/workflow-run-duration-label.js.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.js +6 -6
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filters.js +4 -4
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +6 -6
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +7 -7
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +0 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +8 -13
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/index.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js +2 -2
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts +9 -2
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-list.js +28 -19
- package/dist/components/workflow-run-tabs/run-annotation-list.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +5 -5
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.js +11 -10
- package/dist/components/workflow-run-view/run-workspace-nav.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js +6 -6
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +72 -12
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +9 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts +10 -1
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js.map +1 -1
- package/dist/core/entities/step-attempt.d.ts +29 -0
- package/dist/core/entities/step-attempt.d.ts.map +1 -1
- package/dist/core/entities/step-attempt.js.map +1 -1
- package/dist/core/entities/step.d.ts +3 -1
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/run-annotation.d.ts +6 -0
- package/dist/core/run-annotation.d.ts.map +1 -1
- package/dist/core/run-annotation.js.map +1 -1
- package/dist/core/workflow-run.d.ts +1 -1
- package/dist/core/workflow-run.d.ts.map +1 -1
- package/dist/core/workflow-run.js.map +1 -1
- package/dist/hooks/api/annotations.d.ts +63 -0
- package/dist/hooks/api/annotations.d.ts.map +1 -0
- package/dist/hooks/api/annotations.js +145 -0
- package/dist/hooks/api/annotations.js.map +1 -0
- package/dist/hooks/api/step-attempt-detail.d.ts +14 -0
- package/dist/hooks/api/step-attempt-detail.d.ts.map +1 -0
- package/dist/hooks/api/step-attempt-detail.js +43 -0
- package/dist/hooks/api/step-attempt-detail.js.map +1 -0
- package/dist/hooks/api/workflow-run-mapper.d.ts +9 -2
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +48 -0
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/pages/project-workflows-page.js +19 -19
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-run-list-page.js +1 -1
- package/dist/pages/workflow-run-list-page.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/components/identifier/identifier.tsx +2 -2
- package/src/components/job-detail/agent-config-failure-callout.tsx +5 -1
- package/src/components/job-detail/job-context-panel.test.tsx +72 -0
- package/src/components/job-detail/job-context-panel.tsx +241 -0
- package/src/components/job-detail/job-detail-header.tsx +52 -46
- package/src/components/job-detail/job-detail-view.stories.tsx +555 -53
- package/src/components/job-detail/job-detail-view.tsx +105 -59
- package/src/components/job-detail/job-empty-states.test.ts +105 -1
- package/src/components/job-detail/job-empty-states.tsx +77 -10
- package/src/components/job-detail/job-execution-switcher.tsx +5 -5
- package/src/components/job-detail/json-code.tsx +120 -0
- package/src/components/job-detail/step-attempt-log-panel.test.tsx +1 -0
- package/src/components/job-detail/step-attempt-log-panel.tsx +17 -6
- package/src/components/job-detail/step-troubleshooting.stories.tsx +120 -0
- package/src/components/job-detail/step-troubleshooting.test.tsx +337 -0
- package/src/components/job-detail/step-troubleshooting.tsx +541 -0
- package/src/components/job-graph/job-graph-content.tsx +4 -3
- package/src/components/job-graph/job-node.tsx +3 -3
- package/src/components/step-list/index.ts +1 -0
- package/src/components/step-list/step-list-model.ts +6 -0
- package/src/components/step-list/step-list.test.tsx +75 -2
- package/src/components/step-list/step-list.tsx +73 -20
- package/src/components/workflow-run-duration-label.tsx +1 -1
- package/src/components/workflow-run-list/job-status-strip.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-filters.tsx +4 -4
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-row.tsx +7 -7
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +11 -11
- package/src/components/workflow-run-tabs/index.ts +5 -1
- package/src/components/workflow-run-tabs/run-annotation-count-chip.tsx +2 -2
- package/src/components/workflow-run-tabs/run-annotation-list.tsx +25 -10
- package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +5 -5
- package/src/components/workflow-run-view/run-workspace-nav.tsx +18 -11
- package/src/components/workflow-run-view/workflow-run-states.tsx +6 -6
- package/src/components/workflow-run-view/workflow-run-view.tsx +114 -14
- package/src/core/entities/job-execution.ts +9 -0
- package/src/core/entities/job.ts +12 -1
- package/src/core/entities/step-attempt.ts +33 -0
- package/src/core/entities/step.ts +3 -1
- package/src/core/run-annotation.ts +6 -0
- package/src/core/workflow-run.ts +4 -0
- package/src/hooks/api/annotations.test.ts +84 -0
- package/src/hooks/api/annotations.ts +240 -0
- package/src/hooks/api/step-attempt-detail.ts +67 -0
- package/src/hooks/api/workflow-run-mapper.ts +47 -0
- package/src/hooks/api/workflow-runs.test.tsx +61 -1
- package/src/pages/project-workflows-page.tsx +19 -19
- package/src/pages/workflow-job-detail-page.test.tsx +52 -1
- package/src/pages/workflow-run-list-page.tsx +1 -1
- package/test/fixtures/workflow-run.ts +7 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -2,13 +2,25 @@
|
|
|
2
2
|
// biome-ignore-all lint/a11y/noNoninteractiveTabindex: the story mirrors the focusable log surface.
|
|
3
3
|
|
|
4
4
|
import {type StepLogSnapshot, stepLogsQueryKeys} from '@shipfox/client-logs';
|
|
5
|
-
import {Text} from '@shipfox/react-ui/typography';
|
|
6
5
|
import type {Meta, StoryObj} from '@storybook/react';
|
|
7
6
|
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
|
|
7
|
+
import {
|
|
8
|
+
createMemoryHistory,
|
|
9
|
+
createRootRoute,
|
|
10
|
+
createRoute,
|
|
11
|
+
createRouter,
|
|
12
|
+
Outlet,
|
|
13
|
+
RouterProvider,
|
|
14
|
+
} from '@tanstack/react-router';
|
|
8
15
|
import {type ReactNode, useState} from 'react';
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
16
|
+
import {userEvent, within} from 'storybook/test';
|
|
17
|
+
import type {RunAnnotationSummary} from '#core/run-annotation.js';
|
|
18
|
+
import type {Job, JobExecution, StepAttemptDetail, WorkflowRunDetail} from '#core/workflow-run.js';
|
|
19
|
+
import {workflowRunAnnotationsQueryKeys} from '#hooks/api/annotations.js';
|
|
20
|
+
import {stepAttemptDetailQueryKeys} from '#hooks/api/step-attempt-detail.js';
|
|
11
21
|
import type {useWorkflowRunAttemptQuery} from '#hooks/api/workflow-runs.js';
|
|
22
|
+
import {workflowRunsQueryKeys} from '#hooks/api/workflow-runs.js';
|
|
23
|
+
import {WorkflowJobDetailPage} from '#pages/workflow-job-detail-page.js';
|
|
12
24
|
import {
|
|
13
25
|
workflowJob,
|
|
14
26
|
workflowJobExecutionDto,
|
|
@@ -22,6 +34,7 @@ import {JobDetailView} from './job-detail-view.js';
|
|
|
22
34
|
const WORKSPACE_SLUG = 'acme';
|
|
23
35
|
const PROJECT_SLUG = 'platform';
|
|
24
36
|
const RUN_ID = '11111111-1111-4111-8111-111111111111';
|
|
37
|
+
const INSPECTOR_TRIGGER_NAME = /Inspect Run tests/;
|
|
25
38
|
const LOG_RECORDS: StepLogSnapshot['records'] = [
|
|
26
39
|
{
|
|
27
40
|
v: 1,
|
|
@@ -43,6 +56,8 @@ interface JobDetailStoryArgs {
|
|
|
43
56
|
run: WorkflowRunDetail;
|
|
44
57
|
jobId: string;
|
|
45
58
|
selectedExecutionId?: string | undefined;
|
|
59
|
+
search?: Parameters<typeof JobDetailView>[0]['search'];
|
|
60
|
+
stepDetails?: readonly StepAttemptDetail[];
|
|
46
61
|
}
|
|
47
62
|
|
|
48
63
|
type JobDetailQuery = ReturnType<typeof useWorkflowRunAttemptQuery>;
|
|
@@ -73,52 +88,132 @@ export const Executions: Story = {
|
|
|
73
88
|
},
|
|
74
89
|
};
|
|
75
90
|
|
|
76
|
-
export const
|
|
91
|
+
export const Loading: Story = {
|
|
77
92
|
render: () => {
|
|
78
|
-
const
|
|
79
|
-
const emptyRun = emptyJobRun();
|
|
80
|
-
const loadedRun = playgroundRun();
|
|
93
|
+
const run = playgroundRun();
|
|
81
94
|
return (
|
|
82
|
-
<
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</StateExample>
|
|
89
|
-
<StateExample label="Empty">
|
|
90
|
-
<JobDetailStoryState query={makeQuery(emptyRun)} jobId={emptyRun.jobs[0]?.id ?? ''} />
|
|
91
|
-
</StateExample>
|
|
92
|
-
<StateExample label="Error">
|
|
93
|
-
<JobDetailStoryState
|
|
94
|
-
query={makeQuery(undefined, {isError: true, error: new Error('Storybook error')})}
|
|
95
|
-
jobId="missing-job"
|
|
96
|
-
/>
|
|
97
|
-
</StateExample>
|
|
98
|
-
<StateExample label="Partial">
|
|
99
|
-
<JobDetailStoryState query={makeQuery(partialRun)} jobId={partialRun.jobs[0]?.id ?? ''} />
|
|
100
|
-
</StateExample>
|
|
101
|
-
<StateExample label="Job not found">
|
|
102
|
-
<JobDetailStoryState query={makeQuery(loadedRun)} jobId="missing-job" />
|
|
103
|
-
</StateExample>
|
|
104
|
-
</div>
|
|
95
|
+
<JobDetailStoryViewport>
|
|
96
|
+
<JobDetailStoryState
|
|
97
|
+
query={makeQuery(undefined, {isPending: true})}
|
|
98
|
+
jobId={run.jobs[0]?.id ?? ''}
|
|
99
|
+
/>
|
|
100
|
+
</JobDetailStoryViewport>
|
|
105
101
|
);
|
|
106
102
|
},
|
|
107
103
|
};
|
|
108
104
|
|
|
109
|
-
|
|
105
|
+
export const Empty: Story = {
|
|
106
|
+
render: () => {
|
|
107
|
+
const run = emptyJobRun();
|
|
108
|
+
return <JobDetailStoryFrame run={run} jobId={run.jobs[0]?.id ?? ''} />;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const ErrorState: Story = {
|
|
113
|
+
render: () => (
|
|
114
|
+
<JobDetailStoryViewport>
|
|
115
|
+
<JobDetailStoryState
|
|
116
|
+
query={makeQuery(undefined, {isError: true, error: new Error('Storybook error')})}
|
|
117
|
+
jobId="missing-job"
|
|
118
|
+
/>
|
|
119
|
+
</JobDetailStoryViewport>
|
|
120
|
+
),
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const Partial: Story = {
|
|
124
|
+
render: () => {
|
|
125
|
+
const run = partialJobRun();
|
|
126
|
+
return <JobDetailStoryFrame run={run} jobId={run.jobs[0]?.id ?? ''} />;
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const JobNotFound: Story = {
|
|
131
|
+
render: () => {
|
|
132
|
+
const run = playgroundRun();
|
|
133
|
+
return <JobDetailStoryFrame run={run} jobId="missing-job" />;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const StepFailure: Story = {
|
|
138
|
+
render: () => {
|
|
139
|
+
const {run, commandJobId, stepDetails} = failureRun();
|
|
140
|
+
return <JobDetailStoryFrame run={run} jobId={commandJobId} stepDetails={stepDetails} />;
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const TimedOutBeforeStep: Story = {
|
|
145
|
+
render: () => {
|
|
146
|
+
const {run, timeoutJobId} = failureRun();
|
|
147
|
+
return <JobDetailStoryFrame run={run} jobId={timeoutJobId} />;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const ConditionRejected: Story = {
|
|
152
|
+
render: () => {
|
|
153
|
+
const {run, conditionJobId} = failureRun();
|
|
154
|
+
return <JobDetailStoryFrame run={run} jobId={conditionJobId} />;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const FailureStates: Story = {
|
|
159
|
+
render: () => <FailureCompositionStory />,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const InspectionData: Story = {
|
|
163
|
+
render: () => {
|
|
164
|
+
const {run, jobId, executionId, stepId, attemptId, stepDetails} = inspectionRun();
|
|
165
|
+
return (
|
|
166
|
+
<JobDetailStoryFrame
|
|
167
|
+
run={run}
|
|
168
|
+
jobId={jobId}
|
|
169
|
+
selectedExecutionId={executionId}
|
|
170
|
+
search={{jobExecutionId: executionId, stepId, stepAttemptId: attemptId}}
|
|
171
|
+
stepDetails={stepDetails}
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
},
|
|
175
|
+
play: async ({canvasElement}) => {
|
|
176
|
+
const canvas = within(canvasElement);
|
|
177
|
+
const inspectorTrigger = await canvas.findByRole('button', {
|
|
178
|
+
name: INSPECTOR_TRIGGER_NAME,
|
|
179
|
+
});
|
|
180
|
+
await userEvent.click(inspectorTrigger);
|
|
181
|
+
const documentBody = within(canvasElement.ownerDocument.body);
|
|
182
|
+
await documentBody.findByRole('region', {name: 'Inputs'});
|
|
183
|
+
await documentBody.findByRole('region', {name: 'Evaluation'});
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export const RunComposition: Story = {
|
|
188
|
+
render: () => <RunCompositionStory />,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
function JobDetailStoryFrame({
|
|
192
|
+
run,
|
|
193
|
+
jobId,
|
|
194
|
+
selectedExecutionId,
|
|
195
|
+
search,
|
|
196
|
+
stepDetails,
|
|
197
|
+
}: JobDetailStoryArgs) {
|
|
110
198
|
const job = run.jobs.find((candidate) => candidate.id === jobId) ?? run.jobs[0];
|
|
111
199
|
const selectedExecution = job?.jobExecutions.find(
|
|
112
200
|
(execution) => execution.id === selectedExecutionId,
|
|
113
201
|
);
|
|
114
202
|
return (
|
|
115
|
-
<
|
|
203
|
+
<JobDetailStoryViewport>
|
|
116
204
|
<JobDetailStoryState
|
|
117
205
|
query={makeQuery(run)}
|
|
118
206
|
jobId={jobId}
|
|
119
|
-
search={selectedExecution ? {jobExecutionId: selectedExecution.id} : {}}
|
|
207
|
+
search={search ?? (selectedExecution ? {jobExecutionId: selectedExecution.id} : {})}
|
|
208
|
+
stepDetails={stepDetails}
|
|
120
209
|
/>
|
|
121
|
-
</
|
|
210
|
+
</JobDetailStoryViewport>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function JobDetailStoryViewport({children}: {children: ReactNode}) {
|
|
215
|
+
return (
|
|
216
|
+
<div className="flex min-h-screen min-w-0 w-full bg-background-neutral-base">{children}</div>
|
|
122
217
|
);
|
|
123
218
|
}
|
|
124
219
|
|
|
@@ -126,14 +221,16 @@ function JobDetailStoryState({
|
|
|
126
221
|
query,
|
|
127
222
|
jobId,
|
|
128
223
|
search = {},
|
|
224
|
+
stepDetails = [],
|
|
129
225
|
}: {
|
|
130
226
|
query: JobDetailQuery;
|
|
131
227
|
jobId: string;
|
|
132
228
|
search?: Parameters<typeof JobDetailView>[0]['search'];
|
|
229
|
+
stepDetails?: readonly StepAttemptDetail[];
|
|
133
230
|
}) {
|
|
134
231
|
const run = query.data;
|
|
135
232
|
return (
|
|
136
|
-
<StoryQueryProvider run={run}>
|
|
233
|
+
<StoryQueryProvider run={run} stepDetails={stepDetails}>
|
|
137
234
|
<JobDetailView
|
|
138
235
|
workspaceSlug={WORKSPACE_SLUG}
|
|
139
236
|
projectSlug={PROJECT_SLUG}
|
|
@@ -161,9 +258,11 @@ function makeQuery(data: WorkflowRunDetail | undefined, overrides: Partial<JobDe
|
|
|
161
258
|
|
|
162
259
|
function StoryQueryProvider({
|
|
163
260
|
run,
|
|
261
|
+
stepDetails = [],
|
|
164
262
|
children,
|
|
165
263
|
}: {
|
|
166
264
|
run: WorkflowRunDetail | undefined;
|
|
265
|
+
stepDetails?: readonly StepAttemptDetail[];
|
|
167
266
|
children: ReactNode;
|
|
168
267
|
}) {
|
|
169
268
|
const [queryClient] = useState(() => {
|
|
@@ -171,10 +270,6 @@ function StoryQueryProvider({
|
|
|
171
270
|
defaultOptions: {queries: {staleTime: Number.POSITIVE_INFINITY}},
|
|
172
271
|
});
|
|
173
272
|
if (run) {
|
|
174
|
-
client.setQueryData(runAnnotationsQueryKeys.list(run.id, run.runAttempt.attempt), {
|
|
175
|
-
pages: [{annotations: [], hasMore: false, nextCursor: null}],
|
|
176
|
-
pageParams: [undefined],
|
|
177
|
-
});
|
|
178
273
|
for (const job of run.jobs) {
|
|
179
274
|
for (const execution of job.jobExecutions) {
|
|
180
275
|
for (const step of execution.steps) {
|
|
@@ -187,6 +282,34 @@ function StoryQueryProvider({
|
|
|
187
282
|
}
|
|
188
283
|
}
|
|
189
284
|
}
|
|
285
|
+
client.setQueryData(workflowRunsQueryKeys.detail(run.id), run);
|
|
286
|
+
for (const detail of stepDetails) {
|
|
287
|
+
client.setQueryData(
|
|
288
|
+
stepAttemptDetailQueryKeys.detail(detail.stepId, detail.attempt),
|
|
289
|
+
detail,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
const summary: RunAnnotationSummary = {
|
|
293
|
+
total: 0,
|
|
294
|
+
error: 0,
|
|
295
|
+
warning: 0,
|
|
296
|
+
info: 0,
|
|
297
|
+
success: 0,
|
|
298
|
+
truncated: false,
|
|
299
|
+
stepCounts: [],
|
|
300
|
+
};
|
|
301
|
+
for (const job of run.jobs) {
|
|
302
|
+
for (const execution of job.jobExecutions) {
|
|
303
|
+
client.setQueryData(
|
|
304
|
+
workflowRunAnnotationsQueryKeys.summary(run.id, run.runAttempt.attempt, execution.id),
|
|
305
|
+
summary,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
client.setQueryData(
|
|
310
|
+
workflowRunAnnotationsQueryKeys.summary(run.id, run.runAttempt.attempt),
|
|
311
|
+
summary,
|
|
312
|
+
);
|
|
190
313
|
}
|
|
191
314
|
return client;
|
|
192
315
|
});
|
|
@@ -249,6 +372,135 @@ function playgroundRun(): WorkflowRunDetail {
|
|
|
249
372
|
});
|
|
250
373
|
}
|
|
251
374
|
|
|
375
|
+
function compositionRun() {
|
|
376
|
+
const setupId = '12121212-1212-4212-8212-121212121212';
|
|
377
|
+
const buildId = '13131313-1313-4313-8313-131313131313';
|
|
378
|
+
const buildExecutionId = '14141414-1414-4414-8414-141414141414';
|
|
379
|
+
const installStepId = '15151515-1515-4515-8515-151515151515';
|
|
380
|
+
const installAttemptId = '16161616-1616-4616-8616-161616161616';
|
|
381
|
+
const testStepId = '17171717-1717-4717-8717-171717171717';
|
|
382
|
+
const testAttemptId = '18181818-1818-4818-8818-181818181818';
|
|
383
|
+
const packageStepId = '19191919-1919-4919-8919-191919191919';
|
|
384
|
+
const deployId = '20202020-2020-4020-8020-202020202020';
|
|
385
|
+
|
|
386
|
+
const installStep = workflowStepDto({
|
|
387
|
+
id: installStepId,
|
|
388
|
+
job_execution_id: buildExecutionId,
|
|
389
|
+
key: 'install',
|
|
390
|
+
name: 'Install dependencies',
|
|
391
|
+
status: 'succeeded',
|
|
392
|
+
position: 0,
|
|
393
|
+
attempts: [
|
|
394
|
+
workflowStepAttemptDto({
|
|
395
|
+
id: installAttemptId,
|
|
396
|
+
step_id: installStepId,
|
|
397
|
+
status: 'succeeded',
|
|
398
|
+
finished_at: '2026-08-06T09:02:00.000Z',
|
|
399
|
+
}),
|
|
400
|
+
],
|
|
401
|
+
});
|
|
402
|
+
const testStep = workflowStepDto({
|
|
403
|
+
id: testStepId,
|
|
404
|
+
job_execution_id: buildExecutionId,
|
|
405
|
+
key: 'test',
|
|
406
|
+
name: 'Run tests',
|
|
407
|
+
status: 'failed',
|
|
408
|
+
status_reason: 'agent_invocation_failed',
|
|
409
|
+
position: 1,
|
|
410
|
+
config: {run: 'pnpm test --filter=@shipfox/client-workflows'},
|
|
411
|
+
error: {
|
|
412
|
+
message: 'The test command exited with code 1.',
|
|
413
|
+
reason: 'agent_invocation_failed',
|
|
414
|
+
category: 'user',
|
|
415
|
+
exit_code: 1,
|
|
416
|
+
},
|
|
417
|
+
attempts: [
|
|
418
|
+
workflowStepAttemptDto({
|
|
419
|
+
id: testAttemptId,
|
|
420
|
+
step_id: testStepId,
|
|
421
|
+
status: 'failed',
|
|
422
|
+
exit_code: 1,
|
|
423
|
+
output: {summary: '4 tests failed in the workflow package.'},
|
|
424
|
+
outputs: {failed_tests: 4},
|
|
425
|
+
error: {
|
|
426
|
+
message: 'The test command exited with code 1.',
|
|
427
|
+
reason: 'agent_invocation_failed',
|
|
428
|
+
category: 'user',
|
|
429
|
+
exit_code: 1,
|
|
430
|
+
},
|
|
431
|
+
finished_at: '2026-08-06T09:05:00.000Z',
|
|
432
|
+
}),
|
|
433
|
+
],
|
|
434
|
+
});
|
|
435
|
+
const packageStep = workflowStepDto({
|
|
436
|
+
id: packageStepId,
|
|
437
|
+
job_execution_id: buildExecutionId,
|
|
438
|
+
key: 'package',
|
|
439
|
+
name: 'Package artifacts',
|
|
440
|
+
status: 'skipped',
|
|
441
|
+
status_reason: 'upstream_failed',
|
|
442
|
+
position: 2,
|
|
443
|
+
attempts: [],
|
|
444
|
+
});
|
|
445
|
+
const buildExecution = workflowJobExecutionDto({
|
|
446
|
+
id: buildExecutionId,
|
|
447
|
+
job_id: buildId,
|
|
448
|
+
status: 'failed',
|
|
449
|
+
status_reason: 'step_failed',
|
|
450
|
+
runner: ['runner-linux-x64'],
|
|
451
|
+
outputs: {failed_tests: 4},
|
|
452
|
+
steps: [installStep, testStep, packageStep],
|
|
453
|
+
});
|
|
454
|
+
const buildJob = workflowJob({
|
|
455
|
+
id: buildId,
|
|
456
|
+
key: 'build',
|
|
457
|
+
name: 'build',
|
|
458
|
+
status: 'failed',
|
|
459
|
+
status_reason: 'step_failed',
|
|
460
|
+
runner: ['runner-linux-x64'],
|
|
461
|
+
outputs: {failed_tests: 4},
|
|
462
|
+
position: 1,
|
|
463
|
+
job_executions: [buildExecution],
|
|
464
|
+
});
|
|
465
|
+
const run = storyRun({
|
|
466
|
+
status: 'failed',
|
|
467
|
+
jobs: [
|
|
468
|
+
makeJob({
|
|
469
|
+
id: setupId,
|
|
470
|
+
key: 'setup',
|
|
471
|
+
name: 'setup',
|
|
472
|
+
status: 'succeeded',
|
|
473
|
+
position: 0,
|
|
474
|
+
executions: [
|
|
475
|
+
makeExecution('21212121-2121-4212-8212-212121212121', setupId, 1, 'succeeded'),
|
|
476
|
+
],
|
|
477
|
+
}),
|
|
478
|
+
buildJob,
|
|
479
|
+
makeJob({
|
|
480
|
+
id: deployId,
|
|
481
|
+
key: 'deploy',
|
|
482
|
+
name: 'deploy',
|
|
483
|
+
status: 'pending',
|
|
484
|
+
position: 2,
|
|
485
|
+
dependencies: [buildId],
|
|
486
|
+
executions: [],
|
|
487
|
+
}),
|
|
488
|
+
],
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
run,
|
|
493
|
+
stepDetails: [
|
|
494
|
+
stepAttemptDetail({
|
|
495
|
+
stepId: testStepId,
|
|
496
|
+
attempt: 1,
|
|
497
|
+
authoredConfig: {run: String.raw`pnpm test --filter=\${{ inputs.package }}`},
|
|
498
|
+
config: {run: 'pnpm test --filter=@shipfox/client-workflows'},
|
|
499
|
+
}),
|
|
500
|
+
],
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
252
504
|
function emptyJobRun(): WorkflowRunDetail {
|
|
253
505
|
return storyRun({
|
|
254
506
|
status: 'succeeded',
|
|
@@ -284,6 +536,250 @@ function partialJobRun(): WorkflowRunDetail {
|
|
|
284
536
|
});
|
|
285
537
|
}
|
|
286
538
|
|
|
539
|
+
function failureRun() {
|
|
540
|
+
const commandJobId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee1';
|
|
541
|
+
const commandExecutionId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee2';
|
|
542
|
+
const commandStepId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee3';
|
|
543
|
+
const commandAttemptId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee4';
|
|
544
|
+
const timeoutJobId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee5';
|
|
545
|
+
const timeoutExecutionId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee6';
|
|
546
|
+
const conditionJobId = 'eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee7';
|
|
547
|
+
const commandStep = workflowStepDto({
|
|
548
|
+
id: commandStepId,
|
|
549
|
+
job_execution_id: commandExecutionId,
|
|
550
|
+
key: 'run-tests',
|
|
551
|
+
name: 'Run tests',
|
|
552
|
+
status: 'failed',
|
|
553
|
+
status_reason: 'agent_invocation_failed',
|
|
554
|
+
config: {run: 'pnpm test --filter=@shipfox/client-workflows'},
|
|
555
|
+
evaluation_trace: [
|
|
556
|
+
{
|
|
557
|
+
expression: 'inputs["package"]',
|
|
558
|
+
roots: ['inputs.package'],
|
|
559
|
+
fill_target: 'step-dispatch',
|
|
560
|
+
evaluated_at: '2026-08-05T12:00:00.000Z',
|
|
561
|
+
field: 'run',
|
|
562
|
+
value: '@shipfox/client-workflows',
|
|
563
|
+
},
|
|
564
|
+
],
|
|
565
|
+
error: {
|
|
566
|
+
message: 'The test command exited with code 1.',
|
|
567
|
+
reason: 'agent_invocation_failed',
|
|
568
|
+
category: 'user',
|
|
569
|
+
exit_code: 1,
|
|
570
|
+
},
|
|
571
|
+
attempts: [
|
|
572
|
+
workflowStepAttemptDto({
|
|
573
|
+
id: commandAttemptId,
|
|
574
|
+
step_id: commandStepId,
|
|
575
|
+
status: 'failed',
|
|
576
|
+
exit_code: 1,
|
|
577
|
+
output: {summary: '4 tests failed in the workflow package.'},
|
|
578
|
+
outputs: {failed_tests: 4},
|
|
579
|
+
error: {
|
|
580
|
+
message: 'The test command exited with code 1.',
|
|
581
|
+
reason: 'agent_invocation_failed',
|
|
582
|
+
category: 'user',
|
|
583
|
+
exit_code: 1,
|
|
584
|
+
},
|
|
585
|
+
finished_at: '2026-08-05T12:04:00.000Z',
|
|
586
|
+
}),
|
|
587
|
+
],
|
|
588
|
+
});
|
|
589
|
+
const commandExecution = workflowJobExecutionDto({
|
|
590
|
+
id: commandExecutionId,
|
|
591
|
+
job_id: commandJobId,
|
|
592
|
+
status: 'failed',
|
|
593
|
+
status_reason: 'step_failed',
|
|
594
|
+
runner: ['runner-linux-x64'],
|
|
595
|
+
outputs: {test_count: 370, failed_tests: 4},
|
|
596
|
+
evaluation_trace: [
|
|
597
|
+
{
|
|
598
|
+
expression: 'inputs["package"]',
|
|
599
|
+
roots: ['inputs.package'],
|
|
600
|
+
fill_target: 'job-dispatch',
|
|
601
|
+
evaluated_at: '2026-08-05T12:00:00.000Z',
|
|
602
|
+
field: 'condition',
|
|
603
|
+
value: '@shipfox/client-workflows',
|
|
604
|
+
},
|
|
605
|
+
],
|
|
606
|
+
steps: [commandStep],
|
|
607
|
+
});
|
|
608
|
+
const commandJob = workflowJob({
|
|
609
|
+
id: commandJobId,
|
|
610
|
+
key: 'test',
|
|
611
|
+
name: 'test',
|
|
612
|
+
status: 'failed',
|
|
613
|
+
status_reason: 'step_failed',
|
|
614
|
+
runner: ['runner-linux-x64'],
|
|
615
|
+
outputs: {test_count: 370, failed_tests: 4},
|
|
616
|
+
position: 0,
|
|
617
|
+
job_executions: [commandExecution],
|
|
618
|
+
});
|
|
619
|
+
const timeoutJob = workflowJob({
|
|
620
|
+
id: timeoutJobId,
|
|
621
|
+
key: 'deploy',
|
|
622
|
+
name: 'deploy',
|
|
623
|
+
status: 'failed',
|
|
624
|
+
status_reason: 'timed_out',
|
|
625
|
+
position: 1,
|
|
626
|
+
job_executions: [
|
|
627
|
+
workflowJobExecutionDto({
|
|
628
|
+
id: timeoutExecutionId,
|
|
629
|
+
job_id: timeoutJobId,
|
|
630
|
+
status: 'failed',
|
|
631
|
+
status_reason: 'timed_out',
|
|
632
|
+
steps: [],
|
|
633
|
+
}),
|
|
634
|
+
],
|
|
635
|
+
});
|
|
636
|
+
const conditionJob = workflowJob({
|
|
637
|
+
id: conditionJobId,
|
|
638
|
+
key: 'publish',
|
|
639
|
+
name: 'publish',
|
|
640
|
+
status: 'skipped',
|
|
641
|
+
status_reason: 'condition_rejected',
|
|
642
|
+
position: 2,
|
|
643
|
+
job_executions: [],
|
|
644
|
+
});
|
|
645
|
+
const run = storyRun({status: 'failed', jobs: [commandJob, timeoutJob, conditionJob]});
|
|
646
|
+
const stepDetails = [
|
|
647
|
+
stepAttemptDetail({
|
|
648
|
+
stepId: commandStepId,
|
|
649
|
+
attempt: 1,
|
|
650
|
+
authoredConfig: {run: String.raw`pnpm test --filter=\${{ inputs.package }}`},
|
|
651
|
+
config: {run: 'pnpm test --filter=@shipfox/client-workflows'},
|
|
652
|
+
}),
|
|
653
|
+
];
|
|
654
|
+
|
|
655
|
+
return {
|
|
656
|
+
run,
|
|
657
|
+
commandJobId,
|
|
658
|
+
timeoutJobId,
|
|
659
|
+
conditionJobId,
|
|
660
|
+
commandExecutionId,
|
|
661
|
+
commandStepId,
|
|
662
|
+
commandAttemptId,
|
|
663
|
+
stepDetails,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function inspectionRun() {
|
|
668
|
+
const story = failureRun();
|
|
669
|
+
return {
|
|
670
|
+
run: story.run,
|
|
671
|
+
jobId: story.commandJobId,
|
|
672
|
+
executionId: story.commandExecutionId,
|
|
673
|
+
stepId: story.commandStepId,
|
|
674
|
+
attemptId: story.commandAttemptId,
|
|
675
|
+
stepDetails: story.stepDetails,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
function stepAttemptDetail({
|
|
680
|
+
stepId,
|
|
681
|
+
attempt,
|
|
682
|
+
authoredConfig,
|
|
683
|
+
config,
|
|
684
|
+
}: {
|
|
685
|
+
stepId: string;
|
|
686
|
+
attempt: number;
|
|
687
|
+
authoredConfig: Record<string, unknown>;
|
|
688
|
+
config: Record<string, unknown>;
|
|
689
|
+
}): StepAttemptDetail {
|
|
690
|
+
return {
|
|
691
|
+
stepId,
|
|
692
|
+
attempt,
|
|
693
|
+
authoredConfig,
|
|
694
|
+
config,
|
|
695
|
+
evaluationTrace: [
|
|
696
|
+
{
|
|
697
|
+
expression: 'inputs.package',
|
|
698
|
+
roots: ['inputs.package'],
|
|
699
|
+
fillTarget: 'run',
|
|
700
|
+
evaluatedAt: '2026-08-05T12:00:00.000Z',
|
|
701
|
+
field: 'run',
|
|
702
|
+
value: '@shipfox/client-workflows',
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
expression: 'inputs.branch',
|
|
706
|
+
roots: ['inputs.branch'],
|
|
707
|
+
fillTarget: 'run',
|
|
708
|
+
evaluatedAt: '2026-08-05T12:00:00.000Z',
|
|
709
|
+
field: 'run',
|
|
710
|
+
value: 'main',
|
|
711
|
+
},
|
|
712
|
+
],
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
function RunCompositionStory() {
|
|
717
|
+
const {run, stepDetails} = compositionRun();
|
|
718
|
+
const job = run.jobs[1] ?? run.jobs[0];
|
|
719
|
+
if (!job) return null;
|
|
720
|
+
|
|
721
|
+
return (
|
|
722
|
+
<StoryQueryProvider run={run} stepDetails={stepDetails}>
|
|
723
|
+
<StoryRouter>
|
|
724
|
+
<WorkflowJobDetailPage
|
|
725
|
+
projectId="project-id"
|
|
726
|
+
workspaceSlug={WORKSPACE_SLUG}
|
|
727
|
+
projectSlug={PROJECT_SLUG}
|
|
728
|
+
workflowRunId={run.id}
|
|
729
|
+
jobId={job.id}
|
|
730
|
+
search={{}}
|
|
731
|
+
/>
|
|
732
|
+
</StoryRouter>
|
|
733
|
+
</StoryQueryProvider>
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function FailureCompositionStory() {
|
|
738
|
+
const {run, commandJobId, stepDetails} = failureRun();
|
|
739
|
+
|
|
740
|
+
return (
|
|
741
|
+
<StoryQueryProvider run={run} stepDetails={stepDetails}>
|
|
742
|
+
<StoryRouter>
|
|
743
|
+
<WorkflowJobDetailPage
|
|
744
|
+
projectId="project-id"
|
|
745
|
+
workspaceSlug={WORKSPACE_SLUG}
|
|
746
|
+
projectSlug={PROJECT_SLUG}
|
|
747
|
+
workflowRunId={run.id}
|
|
748
|
+
jobId={commandJobId}
|
|
749
|
+
search={{}}
|
|
750
|
+
/>
|
|
751
|
+
</StoryRouter>
|
|
752
|
+
</StoryQueryProvider>
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function StoryRouter({children}: {children: ReactNode}) {
|
|
757
|
+
const [router] = useState(() => {
|
|
758
|
+
const rootRoute = createRootRoute({component: Outlet});
|
|
759
|
+
const storyRoute = createRoute({
|
|
760
|
+
getParentRoute: () => rootRoute,
|
|
761
|
+
path: '/',
|
|
762
|
+
component: () => children,
|
|
763
|
+
});
|
|
764
|
+
const runRoute = createRoute({
|
|
765
|
+
getParentRoute: () => rootRoute,
|
|
766
|
+
path: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',
|
|
767
|
+
component: () => null,
|
|
768
|
+
});
|
|
769
|
+
const jobRoute = createRoute({
|
|
770
|
+
getParentRoute: () => rootRoute,
|
|
771
|
+
path: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId/jobs/$jobId',
|
|
772
|
+
component: () => null,
|
|
773
|
+
});
|
|
774
|
+
return createRouter({
|
|
775
|
+
history: createMemoryHistory({initialEntries: ['/']}),
|
|
776
|
+
routeTree: rootRoute.addChildren([storyRoute, runRoute, jobRoute]),
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
return <RouterProvider router={router} />;
|
|
781
|
+
}
|
|
782
|
+
|
|
287
783
|
function executionStory() {
|
|
288
784
|
const jobId = '77777777-7777-4777-8777-777777777777';
|
|
289
785
|
const firstExecutionId = '88888888-8888-4888-8888-888888888888';
|
|
@@ -335,6 +831,9 @@ function storyRun({
|
|
|
335
831
|
status: job.status,
|
|
336
832
|
status_reason: job.statusReason,
|
|
337
833
|
carried_over: job.carriedOver,
|
|
834
|
+
success: job.success,
|
|
835
|
+
runner: job.runner,
|
|
836
|
+
evaluation_trace: job.evaluationTrace,
|
|
338
837
|
listening: job.listening,
|
|
339
838
|
listener_status: job.listenerStatus,
|
|
340
839
|
dependencies: job.dependencies,
|
|
@@ -349,8 +848,10 @@ function storyRun({
|
|
|
349
848
|
name: execution.name,
|
|
350
849
|
status: execution.status,
|
|
351
850
|
status_reason: execution.statusReason,
|
|
851
|
+
runner: execution.runner,
|
|
352
852
|
trigger_events: [],
|
|
353
|
-
outputs:
|
|
853
|
+
outputs: execution.outputs,
|
|
854
|
+
evaluation_trace: execution.evaluationTrace,
|
|
354
855
|
queued_at: execution.queuedAt,
|
|
355
856
|
started_at: execution.startedAt,
|
|
356
857
|
finished_at: execution.finishedAt,
|
|
@@ -366,7 +867,19 @@ function storyRun({
|
|
|
366
867
|
status: step.status,
|
|
367
868
|
type: step.type,
|
|
368
869
|
config: step.config,
|
|
369
|
-
|
|
870
|
+
evaluation_trace: step.evaluationTrace,
|
|
871
|
+
error: step.error
|
|
872
|
+
? {
|
|
873
|
+
message: step.error.message,
|
|
874
|
+
...(step.error.exitCode !== null ? {exit_code: step.error.exitCode} : {}),
|
|
875
|
+
...(step.error.signal ? {signal: step.error.signal} : {}),
|
|
876
|
+
...(step.error.reason ? {reason: step.error.reason} : {}),
|
|
877
|
+
...(step.error.agentConfigIssue
|
|
878
|
+
? {agent_config_issue: step.error.agentConfigIssue}
|
|
879
|
+
: {}),
|
|
880
|
+
...(step.error.category ? {category: step.error.category} : {}),
|
|
881
|
+
}
|
|
882
|
+
: null,
|
|
370
883
|
position: step.position,
|
|
371
884
|
current_attempt: step.currentAttempt,
|
|
372
885
|
exit_code: null,
|
|
@@ -393,7 +906,7 @@ function storyRun({
|
|
|
393
906
|
})),
|
|
394
907
|
})),
|
|
395
908
|
})),
|
|
396
|
-
outputs: job.jobExecutions[0]?.outputs ?? null,
|
|
909
|
+
outputs: job.outputs ?? job.jobExecutions[0]?.outputs ?? null,
|
|
397
910
|
resolution_reason: job.resolutionReason,
|
|
398
911
|
})),
|
|
399
912
|
});
|
|
@@ -518,14 +1031,3 @@ function executionDto(execution: JobExecution) {
|
|
|
518
1031
|
),
|
|
519
1032
|
});
|
|
520
1033
|
}
|
|
521
|
-
|
|
522
|
-
function StateExample({label, children}: {label: string; children: ReactNode}) {
|
|
523
|
-
return (
|
|
524
|
-
<section className="min-w-0 rounded-8 border border-border-neutral-base bg-background-neutral-base p-12">
|
|
525
|
-
<Text as="h3" size="xs" bold className="mb-8 text-foreground-neutral-muted">
|
|
526
|
-
{label}
|
|
527
|
-
</Text>
|
|
528
|
-
{children}
|
|
529
|
-
</section>
|
|
530
|
-
);
|
|
531
|
-
}
|