@runwisp/ui 0.13.0 → 0.15.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 (69) hide show
  1. package/package.json +39 -47
  2. package/src/astro/CTABand.astro +19 -12
  3. package/src/astro/Hero.astro +3 -3
  4. package/src/astro/SiteFooter.astro +4 -4
  5. package/src/astro/SiteHeader.astro +4 -4
  6. package/src/lib/actions/portal.ts +0 -3
  7. package/src/lib/assets/runwisp-logo.svg +1 -8
  8. package/src/lib/components/AccordionItem.svelte +4 -10
  9. package/src/lib/components/Alert.svelte +11 -11
  10. package/src/lib/components/Avatar.svelte +1 -1
  11. package/src/lib/components/Badge.svelte +13 -13
  12. package/src/lib/components/Breadcrumb.svelte +3 -3
  13. package/src/lib/components/Button.svelte +2 -2
  14. package/src/lib/components/Card.svelte +4 -4
  15. package/src/lib/components/Checkbox.svelte +12 -10
  16. package/src/lib/components/CodeBlock.svelte +7 -13
  17. package/src/lib/components/CronInput.svelte +12 -15
  18. package/src/lib/components/DataGrid.svelte +14 -13
  19. package/src/lib/components/Drawer.svelte +9 -9
  20. package/src/lib/components/Dropdown.svelte +12 -20
  21. package/src/lib/components/DurationInput.svelte +10 -14
  22. package/src/lib/components/EmptyState.svelte +1 -1
  23. package/src/lib/components/ErrorState.svelte +4 -4
  24. package/src/lib/components/FeatureCard.svelte +4 -4
  25. package/src/lib/components/FormField.svelte +4 -6
  26. package/src/lib/components/Heading.svelte +4 -1
  27. package/src/lib/components/Input.svelte +10 -12
  28. package/src/lib/components/Kbd.svelte +1 -1
  29. package/src/lib/components/Link.svelte +2 -3
  30. package/src/lib/components/LinkButton.svelte +2 -2
  31. package/src/lib/components/LogConsole.svelte +22 -21
  32. package/src/lib/components/Logo.svelte +3 -1
  33. package/src/lib/components/Modal.svelte +9 -11
  34. package/src/lib/components/PageContainer.svelte +1 -1
  35. package/src/lib/components/PageHeader.svelte +1 -1
  36. package/src/lib/components/Pagination.svelte +4 -4
  37. package/src/lib/components/Popover.svelte +5 -7
  38. package/src/lib/components/Progress.svelte +6 -4
  39. package/src/lib/components/Prose.svelte +4 -4
  40. package/src/lib/components/Radio.svelte +11 -10
  41. package/src/lib/components/RadioGroup.svelte +3 -5
  42. package/src/lib/components/Select.svelte +23 -36
  43. package/src/lib/components/Separator.svelte +4 -1
  44. package/src/lib/components/Skeleton.svelte +6 -6
  45. package/src/lib/components/StatusIndicator.svelte +7 -18
  46. package/src/lib/components/Table.svelte +1 -1
  47. package/src/lib/components/TableCell.svelte +1 -1
  48. package/src/lib/components/TableRow.svelte +1 -5
  49. package/src/lib/components/Tabs.svelte +10 -13
  50. package/src/lib/components/TaskCard.svelte +7 -4
  51. package/src/lib/components/Textarea.svelte +10 -11
  52. package/src/lib/components/ThemeToggle.svelte +1 -1
  53. package/src/lib/components/ToastContainer.svelte +3 -8
  54. package/src/lib/components/Toggle.svelte +2 -3
  55. package/src/lib/components/Tooltip.svelte +12 -10
  56. package/src/lib/components/button-styles.ts +17 -18
  57. package/src/lib/components/dashboard/RunDetailPanel.svelte +160 -249
  58. package/src/lib/components/dashboard/RunFilterPopover.svelte +31 -25
  59. package/src/lib/components/dashboard/RunsList.svelte +55 -50
  60. package/src/lib/components/dashboard/run-filters.test.ts +31 -33
  61. package/src/lib/components/dashboard/run-filters.ts +33 -33
  62. package/src/lib/components/dashboard/run-helpers.test.ts +42 -17
  63. package/src/lib/components/dashboard/run-helpers.ts +53 -17
  64. package/src/lib/components/dashboard/status-config.ts +9 -8
  65. package/src/lib/theme-tokens.css +179 -114
  66. package/src/lib/theme.css +49 -35
  67. package/src/lib/utils/error.ts +0 -3
  68. package/src/lib/utils/format.test.ts +2 -6
  69. package/src/lib/utils/format.ts +28 -3
@@ -8,7 +8,7 @@ export type RunsListSortDirection = "asc" | "desc" | "";
8
8
  /**
9
9
  * The single filter shape shared by the runs list, the filter popover, the
10
10
  * SSE-merge source, and the bulk selector. Every field beyond `search` and
11
- * `sort_direction` is an optional dimension applied server-side; the zero
11
+ * `sortDirection` is an optional dimension applied server-side; the zero
12
12
  * value (`emptyRunFilters`) matches every run.
13
13
  *
14
14
  * `statuses` is a multi-select set joined to a comma-separated string only at
@@ -19,26 +19,26 @@ export type RunsListSortDirection = "asc" | "desc" | "";
19
19
  export interface RunsListFilters {
20
20
  search: string;
21
21
  statuses: string[];
22
- sort_direction: RunsListSortDirection;
22
+ sortDirection: RunsListSortDirection;
23
23
  // Optional dimensions explicitly admit `undefined` so a dimension can be
24
24
  // cleared by reassignment (`{ ...f, x: undefined }`) under the project's
25
25
  // exactOptionalPropertyTypes — a fresh object reference is what re-triggers
26
26
  // the parent's fetch effect through several levels of `bind:`.
27
- task_name?: string | undefined;
28
- created_after?: string | undefined;
29
- created_before?: string | undefined;
30
- triggered_by?: string | undefined;
27
+ taskName?: string | undefined;
28
+ createdAfter?: string | undefined;
29
+ createdBefore?: string | undefined;
30
+ triggeredBy?: string | undefined;
31
31
  // A human exit-code expression — a bare code (`137`), a comparison (`>100`,
32
32
  // `<=150`), or a space-separated combination (`>100 <150`). Normalized to an
33
33
  // inclusive [min, max] range (`exitCodeRange`) at the wire boundary; the
34
- // server only ever sees `exit_code_min` / `exit_code_max`.
35
- exit_code?: string | undefined;
36
- retries_only?: boolean | undefined;
34
+ // server only ever sees `exitCodeMin` / `exitCodeMax`.
35
+ exitCode?: string | undefined;
36
+ retriesOnly?: boolean | undefined;
37
37
  }
38
38
 
39
39
  /** A fresh default filter — no dimensions active, newest-first. */
40
40
  export function emptyRunFilters(): RunsListFilters {
41
- return { search: "", statuses: [], sort_direction: "desc" };
41
+ return { search: "", statuses: [], sortDirection: "desc" };
42
42
  }
43
43
 
44
44
  /**
@@ -131,14 +131,14 @@ function exactBucket(statuses: string[]): StatusBucket | undefined {
131
131
  * page the task name is the page scope (injected at fetch time), never a
132
132
  * popover-set filter, so it stays absent from those filters and is not counted.
133
133
  */
134
- export type FilterDimension = "status" | "time" | "task" | "triggered_by" | "exit_code" | "retries";
134
+ export type FilterDimension = "status" | "time" | "task" | "triggeredBy" | "exitCode" | "retries";
135
135
 
136
136
  const DIMENSION_ORDER: FilterDimension[] = [
137
137
  "status",
138
138
  "time",
139
139
  "task",
140
- "triggered_by",
141
- "exit_code",
140
+ "triggeredBy",
141
+ "exitCode",
142
142
  "retries",
143
143
  ];
144
144
 
@@ -148,15 +148,15 @@ export function dimensionActive(f: RunsListFilters, dim: FilterDimension): boole
148
148
  case "status":
149
149
  return f.statuses.length > 0;
150
150
  case "time":
151
- return Boolean(f.created_after) || Boolean(f.created_before);
151
+ return Boolean(f.createdAfter) || Boolean(f.createdBefore);
152
152
  case "task":
153
- return Boolean(f.task_name);
154
- case "triggered_by":
155
- return Boolean(f.triggered_by);
156
- case "exit_code":
157
- return exitCodeRangeActive(f.exit_code);
153
+ return Boolean(f.taskName);
154
+ case "triggeredBy":
155
+ return Boolean(f.triggeredBy);
156
+ case "exitCode":
157
+ return exitCodeRangeActive(f.exitCode);
158
158
  case "retries":
159
- return Boolean(f.retries_only);
159
+ return Boolean(f.retriesOnly);
160
160
  }
161
161
  }
162
162
 
@@ -176,15 +176,15 @@ export function clearDimension(f: RunsListFilters, dim: FilterDimension): RunsLi
176
176
  case "status":
177
177
  return { ...f, statuses: [] };
178
178
  case "time":
179
- return { ...f, created_after: undefined, created_before: undefined };
179
+ return { ...f, createdAfter: undefined, createdBefore: undefined };
180
180
  case "task":
181
- return { ...f, task_name: undefined };
182
- case "triggered_by":
183
- return { ...f, triggered_by: undefined };
184
- case "exit_code":
185
- return { ...f, exit_code: undefined };
181
+ return { ...f, taskName: undefined };
182
+ case "triggeredBy":
183
+ return { ...f, triggeredBy: undefined };
184
+ case "exitCode":
185
+ return { ...f, exitCode: undefined };
186
186
  case "retries":
187
- return { ...f, retries_only: undefined };
187
+ return { ...f, retriesOnly: undefined };
188
188
  }
189
189
  }
190
190
 
@@ -196,12 +196,12 @@ export function clearPopoverFilters(f: RunsListFilters): RunsListFilters {
196
196
  return {
197
197
  ...f,
198
198
  statuses: [],
199
- created_after: undefined,
200
- created_before: undefined,
201
- task_name: undefined,
202
- triggered_by: undefined,
203
- exit_code: undefined,
204
- retries_only: undefined,
199
+ createdAfter: undefined,
200
+ createdBefore: undefined,
201
+ taskName: undefined,
202
+ triggeredBy: undefined,
203
+ exitCode: undefined,
204
+ retriesOnly: undefined,
205
205
  };
206
206
  }
207
207
 
@@ -2,29 +2,54 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { RUN_STATUSES } from "@runwisp/common";
5
6
  import {
6
7
  runDuration,
7
8
  runStartDelay,
9
+ runVerdict,
8
10
  formatTriggeredByLabel,
9
11
  runRetryLabel,
10
12
  instanceSuffix,
11
13
  } from "./run-helpers.js";
12
14
 
15
+ describe("runVerdict", () => {
16
+ it("covers every run status", () => {
17
+ for (const status of RUN_STATUSES) {
18
+ expect(runVerdict(status).verb, status).toBeTruthy();
19
+ }
20
+ });
21
+
22
+ it("phrases a timed outcome so a duration reads after it", () => {
23
+ expect(runVerdict("success")).toEqual({ verb: "succeeded in", timed: true });
24
+ expect(runVerdict("failed")).toEqual({ verb: "failed after", timed: true });
25
+ });
26
+
27
+ it("marks statuses that never produced a duration as untimed", () => {
28
+ // These end without ever running, so the caller renders the verb alone
29
+ // rather than "skipped after —".
30
+ expect(runVerdict("missed").timed).toBe(false);
31
+ expect(runVerdict("skipped").timed).toBe(false);
32
+ expect(runVerdict("dst_skipped").timed).toBe(false);
33
+ expect(runVerdict("queue_full").timed).toBe(false);
34
+ expect(runVerdict("pending").timed).toBe(false);
35
+ });
36
+ });
37
+
13
38
  describe("runDuration", () => {
14
- it("returns undefined when start_at is not set", () => {
39
+ it("returns undefined when startAt is not set", () => {
15
40
  expect(runDuration({})).toBeUndefined();
16
41
  });
17
42
 
18
- it("returns formatted duration when both start_at and end_at are set", () => {
43
+ it("returns formatted duration when both startAt and endAt are set", () => {
19
44
  const start = "2024-06-15T12:00:00.000Z";
20
45
  const end = "2024-06-15T12:00:05.000Z";
21
- expect(runDuration({ start_at: start, end_at: end })).toBe("5s");
46
+ expect(runDuration({ startAt: start, endAt: end })).toBe("5s");
22
47
  });
23
48
 
24
49
  it("returns ms duration for sub-second runs", () => {
25
50
  const start = "2024-06-15T12:00:00.000Z";
26
51
  const end = "2024-06-15T12:00:00.500Z";
27
- expect(runDuration({ start_at: start, end_at: end })).toBe("500ms");
52
+ expect(runDuration({ startAt: start, endAt: end })).toBe("500ms");
28
53
  });
29
54
 
30
55
  describe("with fake clock", () => {
@@ -36,35 +61,35 @@ describe("runDuration", () => {
36
61
  vi.useRealTimers();
37
62
  });
38
63
 
39
- it("uses current time when end_at is not set (run still in progress)", () => {
40
- expect(runDuration({ start_at: "2024-06-15T12:00:00.000Z" })).toBe("2s");
64
+ it("uses current time when endAt is not set (run still in progress)", () => {
65
+ expect(runDuration({ startAt: "2024-06-15T12:00:00.000Z" })).toBe("2s");
41
66
  });
42
67
  });
43
68
 
44
69
  it("counts against an injected now for an in-progress run", () => {
45
70
  const start = "2024-06-15T12:00:00.000Z";
46
71
  const now = new Date("2024-06-15T12:00:07.000Z").getTime();
47
- expect(runDuration({ start_at: start }, now)).toBe("7s");
72
+ expect(runDuration({ startAt: start }, now)).toBe("7s");
48
73
  });
49
74
 
50
75
  it("ignores the injected now once the run has ended", () => {
51
76
  const start = "2024-06-15T12:00:00.000Z";
52
77
  const end = "2024-06-15T12:00:05.000Z";
53
78
  const now = new Date("2024-06-15T12:01:00.000Z").getTime();
54
- expect(runDuration({ start_at: start, end_at: end }, now)).toBe("5s");
79
+ expect(runDuration({ startAt: start, endAt: end }, now)).toBe("5s");
55
80
  });
56
81
  });
57
82
 
58
83
  describe("runStartDelay", () => {
59
- it("returns undefined when start_at is not set", () => {
60
- expect(runStartDelay({ created_at: "2024-06-15T12:00:00.000Z" })).toBeUndefined();
84
+ it("returns undefined when startAt is not set", () => {
85
+ expect(runStartDelay({ createdAt: "2024-06-15T12:00:00.000Z" })).toBeUndefined();
61
86
  });
62
87
 
63
88
  it("returns undefined when the run started within a second of its tick", () => {
64
89
  expect(
65
90
  runStartDelay({
66
- created_at: "2024-06-15T12:00:00.000Z",
67
- start_at: "2024-06-15T12:00:00.300Z",
91
+ createdAt: "2024-06-15T12:00:00.000Z",
92
+ startAt: "2024-06-15T12:00:00.300Z",
68
93
  }),
69
94
  ).toBeUndefined();
70
95
  });
@@ -72,8 +97,8 @@ describe("runStartDelay", () => {
72
97
  it("formats the jitter/queue gap when the run started meaningfully later", () => {
73
98
  expect(
74
99
  runStartDelay({
75
- created_at: "2024-06-15T03:00:00.000Z",
76
- start_at: "2024-06-15T03:07:12.000Z",
100
+ createdAt: "2024-06-15T03:00:00.000Z",
101
+ startAt: "2024-06-15T03:07:12.000Z",
77
102
  }),
78
103
  ).toBe("7m 12s");
79
104
  });
@@ -91,15 +116,15 @@ describe("formatTriggeredByLabel", () => {
91
116
 
92
117
  describe("runRetryLabel", () => {
93
118
  it("returns undefined for a first attempt that is not a retry", () => {
94
- expect(runRetryLabel({ retry_attempt: 0 })).toBeUndefined();
119
+ expect(runRetryLabel({ retryAttempt: 0 })).toBeUndefined();
95
120
  });
96
121
 
97
122
  it("labels a run with a positive attempt number", () => {
98
- expect(runRetryLabel({ retry_attempt: 2 })).toBe("retry #2");
123
+ expect(runRetryLabel({ retryAttempt: 2 })).toBe("retry #2");
99
124
  });
100
125
 
101
126
  it("labels a run that points back at the run it re-attempts", () => {
102
- expect(runRetryLabel({ retry_attempt: 1, retry_of_run_id: "01JABC" })).toBe("retry #1");
127
+ expect(runRetryLabel({ retryAttempt: 1, retryOfRunId: "01JABC" })).toBe("retry #1");
103
128
  });
104
129
  });
105
130
 
@@ -1,30 +1,68 @@
1
1
  // SPDX-FileCopyrightText: PoppyCake, s.r.o.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import type { Run } from "@runwisp/common";
4
+ import type { Run, RunStatus } from "@runwisp/common";
5
5
  import { formatDuration } from "../../utils/format.js";
6
6
 
7
+ export interface RunVerdict {
8
+ /** Verb phrase for the outcome, ending in its preposition when `timed`. */
9
+ verb: string;
10
+ /**
11
+ * Whether the phrase expects a duration after it. False for statuses that
12
+ * never produced one (nothing ran, or nothing has yet), so the caller
13
+ * renders the verb alone rather than "skipped after —".
14
+ */
15
+ timed: boolean;
16
+ }
17
+
18
+ /**
19
+ * The run's outcome as a verb phrase, so a detail view can state it as one
20
+ * sentence ("succeeded in 933ms") instead of a status badge competing with a
21
+ * separate duration readout for the same glance.
22
+ */
23
+ const RUN_VERDICTS: Record<RunStatus, RunVerdict> = {
24
+ success: { verb: "succeeded in", timed: true },
25
+ failed: { verb: "failed after", timed: true },
26
+ crashed: { verb: "crashed after", timed: true },
27
+ timeout: { verb: "timed out after", timed: true },
28
+ stopped: { verb: "stopped after", timed: true },
29
+ daemon_stopped: { verb: "cut short after", timed: true },
30
+ log_overflow: { verb: "killed after", timed: true },
31
+ start_failed: { verb: "gave up after", timed: true },
32
+ ended: { verb: "ended after", timed: true },
33
+ running: { verb: "running for", timed: true },
34
+ pending: { verb: "queued", timed: false },
35
+ missed: { verb: "never ran", timed: false },
36
+ skipped: { verb: "skipped", timed: false },
37
+ dst_skipped: { verb: "skipped", timed: false },
38
+ queue_full: { verb: "skipped", timed: false },
39
+ };
40
+
41
+ export function runVerdict(status: RunStatus): RunVerdict {
42
+ return RUN_VERDICTS[status];
43
+ }
44
+
7
45
  export function runDuration(
8
- run: Pick<Run, "start_at" | "end_at">,
46
+ run: Pick<Run, "startAt" | "endAt">,
9
47
  now: number = Date.now(),
10
48
  ): string | undefined {
11
- if (!run.start_at) return undefined;
12
- const start = new Date(run.start_at).getTime();
13
- const end = run.end_at ? new Date(run.end_at).getTime() : now;
49
+ if (!run.startAt) return undefined;
50
+ const start = new Date(run.startAt).getTime();
51
+ const end = run.endAt ? new Date(run.endAt).getTime() : now;
14
52
  return formatDuration(end - start);
15
53
  }
16
54
 
17
55
  /**
18
- * Gap between when a run was scheduled (`created_at`, the cron tick) and when
19
- * it actually started (`start_at`), formatted — or undefined when the two are
56
+ * Gap between when a run was scheduled (`createdAt`, the cron tick) and when
57
+ * it actually started (`startAt`), formatted — or undefined when the two are
20
58
  * within a second of each other. This is the visible face of `jitter`: a
21
59
  * jittered run is created at its tick but starts later inside the window, and
22
60
  * this is by how much. It also surfaces queue-wait, since a queued run is
23
61
  * created when it joins the line and started when the line clears.
24
62
  */
25
- export function runStartDelay(run: Pick<Run, "created_at" | "start_at">): string | undefined {
26
- if (!run.start_at) return undefined;
27
- const delay = new Date(run.start_at).getTime() - new Date(run.created_at).getTime();
63
+ export function runStartDelay(run: Pick<Run, "createdAt" | "startAt">): string | undefined {
64
+ if (!run.startAt) return undefined;
65
+ const delay = new Date(run.startAt).getTime() - new Date(run.createdAt).getTime();
28
66
  if (delay < 1000) return undefined;
29
67
  return formatDuration(delay);
30
68
  }
@@ -44,8 +82,8 @@ export function instanceSuffix(instanceIndex: number, instanceCount: number): st
44
82
  return "";
45
83
  }
46
84
 
47
- /** Human label for why a run fired (the `triggered_by` source). */
48
- export function formatTriggeredByLabel(triggeredBy: Run["triggered_by"]): string {
85
+ /** Human label for why a run fired (the `triggeredBy` source). */
86
+ export function formatTriggeredByLabel(triggeredBy: Run["triggeredBy"]): string {
49
87
  if (triggeredBy === "api") return "API";
50
88
  if (triggeredBy === "cron") return "Cron";
51
89
  if (triggeredBy === "service") return "Service";
@@ -58,11 +96,9 @@ export function formatTriggeredByLabel(triggeredBy: Run["triggered_by"]): string
58
96
  * A run is a retry if it carries a positive attempt number or points back at
59
97
  * the run it re-attempts.
60
98
  */
61
- export function runRetryLabel(
62
- run: Pick<Run, "retry_attempt" | "retry_of_run_id">,
63
- ): string | undefined {
64
- if (run.retry_attempt > 0 || run.retry_of_run_id) {
65
- return `retry #${String(run.retry_attempt)}`;
99
+ export function runRetryLabel(run: Pick<Run, "retryAttempt" | "retryOfRunId">): string | undefined {
100
+ if (run.retryAttempt > 0 || run.retryOfRunId) {
101
+ return `retry #${String(run.retryAttempt)}`;
66
102
  }
67
103
  return undefined;
68
104
  }
@@ -45,7 +45,7 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
45
45
  border: "border-success-soft",
46
46
  dot: "bg-success-surface",
47
47
  badge: "bg-success-soft text-success-soft-text",
48
- description: "The run finished with exit code 0.",
48
+ description: "The run finished with exit code 0 - everything OK.",
49
49
  },
50
50
  failed: {
51
51
  icon: CircleX,
@@ -64,7 +64,7 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
64
64
  dot: "bg-danger-surface",
65
65
  badge: "bg-danger-soft text-danger-soft-text",
66
66
  description:
67
- "The process was killed, or the daemon found it still 'running' after a hard crash and marked it crashed (exit -2). It was not resumed.",
67
+ "The process was killed, or the daemon found it still 'running' after a hard crash and marked it crashed. It was not resumed.",
68
68
  },
69
69
  stopped: {
70
70
  icon: CircleStop,
@@ -73,7 +73,7 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
73
73
  border: "border-warning-soft",
74
74
  dot: "bg-warning-surface",
75
75
  badge: "bg-warning-soft text-warning-soft-text",
76
- description: "An operator stopped this run before it finished.",
76
+ description: "A human or an external script manually stopped this run before it finished.",
77
77
  },
78
78
  timeout: {
79
79
  icon: TimerOff,
@@ -82,7 +82,8 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
82
82
  border: "border-warning-soft",
83
83
  dot: "bg-warning-surface",
84
84
  badge: "bg-warning-soft text-warning-soft-text",
85
- description: "The run exceeded its configured timeout and was terminated.",
85
+ description:
86
+ "The run exceeded its configured timeout and was terminated. Timeout duration can be changed.",
86
87
  },
87
88
  skipped: {
88
89
  icon: SkipForward,
@@ -101,7 +102,7 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
101
102
  border: "border-danger-soft",
102
103
  dot: "bg-danger-surface",
103
104
  badge: "bg-danger-soft text-danger-soft-text",
104
- description: "The run hit log_max_size and was handled per log_on_full.",
105
+ description: "The run hit log_max_size and was handled because of log_on_full.",
105
106
  },
106
107
  queue_full: {
107
108
  icon: SkipForward,
@@ -150,7 +151,7 @@ export const RUN_STATUS_CONFIG: Record<RunStatus, RunStatusConfig> = {
150
151
  dot: "bg-danger-surface",
151
152
  badge: "bg-danger-soft text-danger-soft-text",
152
153
  description:
153
- "The service kept failing to stay up for healthy_after; after start_retries the supervisor gave up (FATAL) and stopped restarting it.",
154
+ "The service kept failing to stay up for healthy_after; after restart_attempts the supervisor gave up (FATAL) and stopped restarting it.",
154
155
  },
155
156
  pending: {
156
157
  icon: Clock,
@@ -176,6 +177,6 @@ export function getRunStatusConfig(status: RunStatus): RunStatusConfig {
176
177
  return RUN_STATUS_CONFIG[status];
177
178
  }
178
179
 
179
- export function runDisplayStatus(run: Pick<Run, "status" | "end_reason">): RunStatus {
180
- return displayStatus(run.status, run.end_reason);
180
+ export function runDisplayStatus(run: Pick<Run, "status" | "endReason">): RunStatus {
181
+ return displayStatus(run.status, run.endReason);
181
182
  }