@xemahq/kernel-contracts 0.29.0 → 0.31.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/dist/decision-gate/index.d.ts +3 -0
- package/dist/decision-gate/index.d.ts.map +1 -0
- package/dist/decision-gate/index.js +19 -0
- package/dist/decision-gate/index.js.map +1 -0
- package/dist/decision-gate/lib/decision-gate.d.ts +55 -0
- package/dist/decision-gate/lib/decision-gate.d.ts.map +1 -0
- package/dist/decision-gate/lib/decision-gate.js +56 -0
- package/dist/decision-gate/lib/decision-gate.js.map +1 -0
- package/dist/decision-gate/lib/pinned-subject-artifact.d.ts +9 -0
- package/dist/decision-gate/lib/pinned-subject-artifact.d.ts.map +1 -0
- package/dist/decision-gate/lib/pinned-subject-artifact.js +11 -0
- package/dist/decision-gate/lib/pinned-subject-artifact.js.map +1 -0
- package/dist/document-patch/index.d.ts +4 -0
- package/dist/document-patch/index.d.ts.map +1 -0
- package/dist/document-patch/index.js +20 -0
- package/dist/document-patch/index.js.map +1 -0
- package/dist/document-patch/lib/patch-anchor.d.ts +7 -0
- package/dist/document-patch/lib/patch-anchor.d.ts.map +1 -0
- package/dist/document-patch/lib/patch-anchor.js +14 -0
- package/dist/document-patch/lib/patch-anchor.js.map +1 -0
- package/dist/document-patch/lib/patch-enums.d.ts +11 -0
- package/dist/document-patch/lib/patch-enums.d.ts.map +1 -0
- package/dist/document-patch/lib/patch-enums.js +16 -0
- package/dist/document-patch/lib/patch-enums.js.map +1 -0
- package/dist/document-patch/lib/pending-patch.d.ts +22 -0
- package/dist/document-patch/lib/pending-patch.d.ts.map +1 -0
- package/dist/document-patch/lib/pending-patch.js +3 -0
- package/dist/document-patch/lib/pending-patch.js.map +1 -0
- package/dist/output/index.d.ts +7 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +23 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/lib/output-deliverable-expectation.d.ts +9 -0
- package/dist/output/lib/output-deliverable-expectation.d.ts.map +1 -0
- package/dist/output/lib/output-deliverable-expectation.js +3 -0
- package/dist/output/lib/output-deliverable-expectation.js.map +1 -0
- package/dist/output/lib/output-item-dto.d.ts +25 -0
- package/dist/output/lib/output-item-dto.d.ts.map +1 -0
- package/dist/output/lib/output-item-dto.js +3 -0
- package/dist/output/lib/output-item-dto.js.map +1 -0
- package/dist/output/lib/output-kind.d.ts +14 -0
- package/dist/output/lib/output-kind.d.ts.map +1 -0
- package/dist/output/lib/output-kind.js +18 -0
- package/dist/output/lib/output-kind.js.map +1 -0
- package/dist/output/lib/output-render-hint.d.ts +11 -0
- package/dist/output/lib/output-render-hint.d.ts.map +1 -0
- package/dist/output/lib/output-render-hint.js +10 -0
- package/dist/output/lib/output-render-hint.js.map +1 -0
- package/dist/output/lib/output-version-dto.d.ts +10 -0
- package/dist/output/lib/output-version-dto.d.ts.map +1 -0
- package/dist/output/lib/output-version-dto.js +3 -0
- package/dist/output/lib/output-version-dto.js.map +1 -0
- package/dist/output/lib/payload-schemas/code-diff.d.ts +7 -0
- package/dist/output/lib/payload-schemas/code-diff.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/code-diff.js +11 -0
- package/dist/output/lib/payload-schemas/code-diff.js.map +1 -0
- package/dist/output/lib/payload-schemas/decision-record.d.ts +19 -0
- package/dist/output/lib/payload-schemas/decision-record.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/decision-record.js +39 -0
- package/dist/output/lib/payload-schemas/decision-record.js.map +1 -0
- package/dist/output/lib/payload-schemas/diagram.d.ts +12 -0
- package/dist/output/lib/payload-schemas/diagram.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/diagram.js +34 -0
- package/dist/output/lib/payload-schemas/diagram.js.map +1 -0
- package/dist/output/lib/payload-schemas/external-blob.d.ts +9 -0
- package/dist/output/lib/payload-schemas/external-blob.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/external-blob.js +15 -0
- package/dist/output/lib/payload-schemas/external-blob.js.map +1 -0
- package/dist/output/lib/payload-schemas/index.d.ts +17 -0
- package/dist/output/lib/payload-schemas/index.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/index.js +94 -0
- package/dist/output/lib/payload-schemas/index.js.map +1 -0
- package/dist/output/lib/payload-schemas/json-payload.d.ts +4 -0
- package/dist/output/lib/payload-schemas/json-payload.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/json-payload.js +9 -0
- package/dist/output/lib/payload-schemas/json-payload.js.map +1 -0
- package/dist/output/lib/payload-schemas/manifest.d.ts +37 -0
- package/dist/output/lib/payload-schemas/manifest.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/manifest.js +43 -0
- package/dist/output/lib/payload-schemas/manifest.js.map +1 -0
- package/dist/output/lib/payload-schemas/markdown-doc.d.ts +8 -0
- package/dist/output/lib/payload-schemas/markdown-doc.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/markdown-doc.js +12 -0
- package/dist/output/lib/payload-schemas/markdown-doc.js.map +1 -0
- package/dist/output/lib/payload-schemas/review-findings.d.ts +30 -0
- package/dist/output/lib/payload-schemas/review-findings.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/review-findings.js +39 -0
- package/dist/output/lib/payload-schemas/review-findings.js.map +1 -0
- package/dist/output/lib/payload-schemas/schema.d.ts +4 -0
- package/dist/output/lib/payload-schemas/schema.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/schema.js +10 -0
- package/dist/output/lib/payload-schemas/schema.js.map +1 -0
- package/dist/output/lib/payload-schemas/test-report.d.ts +33 -0
- package/dist/output/lib/payload-schemas/test-report.d.ts.map +1 -0
- package/dist/output/lib/payload-schemas/test-report.js +46 -0
- package/dist/output/lib/payload-schemas/test-report.js.map +1 -0
- package/dist/question/index.d.ts +5 -0
- package/dist/question/index.d.ts.map +1 -0
- package/dist/question/index.js +21 -0
- package/dist/question/index.js.map +1 -0
- package/dist/question/lib/question-action-context.d.ts +7 -0
- package/dist/question/lib/question-action-context.d.ts.map +1 -0
- package/dist/question/lib/question-action-context.js +3 -0
- package/dist/question/lib/question-action-context.js.map +1 -0
- package/dist/question/lib/question-dto.d.ts +54 -0
- package/dist/question/lib/question-dto.d.ts.map +1 -0
- package/dist/question/lib/question-dto.js +3 -0
- package/dist/question/lib/question-dto.js.map +1 -0
- package/dist/question/lib/question-enums.d.ts +20 -0
- package/dist/question/lib/question-enums.d.ts.map +1 -0
- package/dist/question/lib/question-enums.js +32 -0
- package/dist/question/lib/question-enums.js.map +1 -0
- package/dist/question/lib/question-escalation.d.ts +8 -0
- package/dist/question/lib/question-escalation.d.ts.map +1 -0
- package/dist/question/lib/question-escalation.js +3 -0
- package/dist/question/lib/question-escalation.js.map +1 -0
- package/dist/review-inquiry/index.d.ts +3 -0
- package/dist/review-inquiry/index.d.ts.map +1 -0
- package/dist/review-inquiry/index.js +19 -0
- package/dist/review-inquiry/index.js.map +1 -0
- package/dist/review-inquiry/lib/review-inquiry.d.ts +138 -0
- package/dist/review-inquiry/lib/review-inquiry.d.ts.map +1 -0
- package/dist/review-inquiry/lib/review-inquiry.js +20 -0
- package/dist/review-inquiry/lib/review-inquiry.js.map +1 -0
- package/dist/review-inquiry/lib/web-annotation.d.ts +195 -0
- package/dist/review-inquiry/lib/web-annotation.d.ts.map +1 -0
- package/dist/review-inquiry/lib/web-annotation.js +59 -0
- package/dist/review-inquiry/lib/web-annotation.js.map +1 -0
- package/dist/run-detail/index.d.ts +7 -0
- package/dist/run-detail/index.d.ts.map +1 -0
- package/dist/run-detail/index.js +23 -0
- package/dist/run-detail/index.js.map +1 -0
- package/dist/run-detail/lib/run-detail-dto.d.ts +34 -0
- package/dist/run-detail/lib/run-detail-dto.d.ts.map +1 -0
- package/dist/run-detail/lib/run-detail-dto.js +3 -0
- package/dist/run-detail/lib/run-detail-dto.js.map +1 -0
- package/dist/run-detail/lib/run-mode.d.ts +14 -0
- package/dist/run-detail/lib/run-mode.d.ts.map +1 -0
- package/dist/run-detail/lib/run-mode.js +25 -0
- package/dist/run-detail/lib/run-mode.js.map +1 -0
- package/dist/run-detail/lib/run-outcome.d.ts +28 -0
- package/dist/run-detail/lib/run-outcome.d.ts.map +1 -0
- package/dist/run-detail/lib/run-outcome.js +27 -0
- package/dist/run-detail/lib/run-outcome.js.map +1 -0
- package/dist/run-detail/lib/run-phase-rail.d.ts +21 -0
- package/dist/run-detail/lib/run-phase-rail.d.ts.map +1 -0
- package/dist/run-detail/lib/run-phase-rail.js +14 -0
- package/dist/run-detail/lib/run-phase-rail.js.map +1 -0
- package/dist/run-detail/lib/run-revision-state.d.ts +47 -0
- package/dist/run-detail/lib/run-revision-state.d.ts.map +1 -0
- package/dist/run-detail/lib/run-revision-state.js +11 -0
- package/dist/run-detail/lib/run-revision-state.js.map +1 -0
- package/dist/run-detail/lib/wait-windows.d.ts +15 -0
- package/dist/run-detail/lib/wait-windows.d.ts.map +1 -0
- package/dist/run-detail/lib/wait-windows.js +39 -0
- package/dist/run-detail/lib/wait-windows.js.map +1 -0
- package/dist/workspace-image/index.d.ts +5 -0
- package/dist/workspace-image/index.d.ts.map +1 -0
- package/dist/workspace-image/index.js +21 -0
- package/dist/workspace-image/index.js.map +1 -0
- package/dist/workspace-image/lib/enums.d.ts +17 -0
- package/dist/workspace-image/lib/enums.d.ts.map +1 -0
- package/dist/workspace-image/lib/enums.js +22 -0
- package/dist/workspace-image/lib/enums.js.map +1 -0
- package/dist/workspace-image/lib/hash.d.ts +3 -0
- package/dist/workspace-image/lib/hash.d.ts.map +1 -0
- package/dist/workspace-image/lib/hash.js +50 -0
- package/dist/workspace-image/lib/hash.js.map +1 -0
- package/dist/workspace-image/lib/schemas.d.ts +103 -0
- package/dist/workspace-image/lib/schemas.d.ts.map +1 -0
- package/dist/workspace-image/lib/schemas.js +53 -0
- package/dist/workspace-image/lib/schemas.js.map +1 -0
- package/dist/workspace-image/lib/types.d.ts +50 -0
- package/dist/workspace-image/lib/types.d.ts.map +1 -0
- package/dist/workspace-image/lib/types.js +3 -0
- package/dist/workspace-image/lib/types.js.map +1 -0
- package/package.json +1 -1
- package/src/decision-gate/index.ts +13 -0
- package/src/decision-gate/lib/decision-gate.ts +113 -0
- package/src/decision-gate/lib/pinned-subject-artifact.ts +29 -0
- package/src/document-patch/index.ts +25 -0
- package/src/document-patch/lib/patch-anchor.ts +22 -0
- package/src/document-patch/lib/patch-enums.ts +36 -0
- package/src/document-patch/lib/pending-patch.ts +31 -0
- package/src/output/index.ts +20 -0
- package/src/output/lib/output-deliverable-expectation.ts +25 -0
- package/src/output/lib/output-item-dto.ts +54 -0
- package/src/output/lib/output-kind.ts +44 -0
- package/src/output/lib/output-render-hint.ts +28 -0
- package/src/output/lib/output-version-dto.ts +21 -0
- package/src/output/lib/payload-schemas/code-diff.ts +20 -0
- package/src/output/lib/payload-schemas/decision-record.ts +71 -0
- package/src/output/lib/payload-schemas/diagram.ts +54 -0
- package/src/output/lib/payload-schemas/external-blob.ts +36 -0
- package/src/output/lib/payload-schemas/index.ts +133 -0
- package/src/output/lib/payload-schemas/json-payload.ts +19 -0
- package/src/output/lib/payload-schemas/manifest.ts +81 -0
- package/src/output/lib/payload-schemas/markdown-doc.ts +33 -0
- package/src/output/lib/payload-schemas/review-findings.ts +75 -0
- package/src/output/lib/payload-schemas/schema.ts +22 -0
- package/src/output/lib/payload-schemas/test-report.ts +69 -0
- package/src/question/index.ts +24 -0
- package/src/question/lib/question-action-context.ts +26 -0
- package/src/question/lib/question-dto.ts +143 -0
- package/src/question/lib/question-enums.ts +67 -0
- package/src/question/lib/question-escalation.ts +22 -0
- package/src/review-inquiry/index.ts +19 -0
- package/src/review-inquiry/lib/review-inquiry.ts +76 -0
- package/src/review-inquiry/lib/web-annotation.ts +136 -0
- package/src/run-detail/index.ts +22 -0
- package/src/run-detail/lib/run-detail-dto.ts +84 -0
- package/src/run-detail/lib/run-mode.ts +65 -0
- package/src/run-detail/lib/run-outcome.ts +66 -0
- package/src/run-detail/lib/run-phase-rail.ts +43 -0
- package/src/run-detail/lib/run-revision-state.ts +83 -0
- package/src/run-detail/lib/wait-windows.ts +70 -0
- package/src/workspace-image/index.ts +13 -0
- package/src/workspace-image/lib/enums.ts +38 -0
- package/src/workspace-image/lib/hash.ts +95 -0
- package/src/workspace-image/lib/schemas.ts +63 -0
- package/src/workspace-image/lib/types.ts +79 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { WorkflowRunStatus } from '../../workflow';
|
|
2
|
+
|
|
3
|
+
import { RunOutcomeDto } from './run-outcome';
|
|
4
|
+
import { RunPhaseRailDto } from './run-phase-rail';
|
|
5
|
+
import { RunRevisionPayload } from './run-revision-state';
|
|
6
|
+
import { WaitWindow } from './wait-windows';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The single payload `GET /workflows/:slug/runs/:id/full` returns. Replaces
|
|
10
|
+
* the legacy `useRunSummary` + `useRunDescribe` + first-page `useRunHistory`
|
|
11
|
+
* + `useRunJobs` quad-query with one coalesced call.
|
|
12
|
+
*
|
|
13
|
+
* Conventions:
|
|
14
|
+
* - Every nested list is bounded — the FE never asks for "all events".
|
|
15
|
+
* Detail/history surfaces page through the timeline endpoint.
|
|
16
|
+
* - Every closed-domain field uses an enum from this package or
|
|
17
|
+
* `../../workflow`. No free-form strings except labels.
|
|
18
|
+
* - The payload is shaped for the user-visible view, not internal
|
|
19
|
+
* state. Internal Temporal IDs are exposed only in DEVELOPER mode.
|
|
20
|
+
*
|
|
21
|
+
* Wire envelope: this DTO is the `data` member of the standard envelope
|
|
22
|
+
*. The FE's envelope-assert util validates the
|
|
23
|
+
* shape end-to-end.
|
|
24
|
+
*/
|
|
25
|
+
export interface RunDetailDto {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly workflowSlug: string;
|
|
28
|
+
readonly workflowDisplayName: string;
|
|
29
|
+
readonly status: WorkflowRunStatus;
|
|
30
|
+
/** Initiator displayName — `null` for system-triggered runs (schedules, webhooks). */
|
|
31
|
+
readonly initiatorDisplayName: string | null;
|
|
32
|
+
readonly startedAt: string;
|
|
33
|
+
/** ISO-8601 when the run reached a terminal state, else `null`. */
|
|
34
|
+
readonly endedAt: string | null;
|
|
35
|
+
/** Engine ETA for in-flight runs. `null` when terminal or unknown. */
|
|
36
|
+
readonly etaAt: string | null;
|
|
37
|
+
|
|
38
|
+
readonly phaseRail: RunPhaseRailDto;
|
|
39
|
+
readonly waitWindows: readonly WaitWindow[];
|
|
40
|
+
|
|
41
|
+
/** What's actively running right now — feeds the Overview "Activity now" strip. */
|
|
42
|
+
readonly activityNow: readonly RunActivityNowDto[];
|
|
43
|
+
|
|
44
|
+
/** Last 6 events (coarse milestones). Click-through navigates to Developer mode. */
|
|
45
|
+
readonly recentTail: readonly RunRecentEventDto[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Revision-state discriminator + payload (see {@link RunRevisionPayload}).
|
|
49
|
+
* Drives whether/which of the 3 revision UIs renders.
|
|
50
|
+
*/
|
|
51
|
+
readonly revision: RunRevisionPayload;
|
|
52
|
+
|
|
53
|
+
/** Outcome strip for terminal runs. `null` for in-flight. */
|
|
54
|
+
readonly outcome: RunOutcomeDto | null;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* One-line "what's blocking" callout for in-flight runs. Server-computed
|
|
58
|
+
* from waitWindows + escalation state. `null` when nothing is blocking.
|
|
59
|
+
*/
|
|
60
|
+
readonly blockingSummary: string | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* One row in the Overview "Activity now" strip — coarse "who is doing
|
|
65
|
+
* what right now". Updated via SSE incremental patches; one sentence
|
|
66
|
+
* per active job, no timestamps (they're current).
|
|
67
|
+
*/
|
|
68
|
+
export interface RunActivityNowDto {
|
|
69
|
+
readonly jobKey: string;
|
|
70
|
+
readonly agentDisplayName: string | null;
|
|
71
|
+
readonly summary: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* One row in the Overview "Recent" tail — the last 6 coarse milestones
|
|
76
|
+
* (phase entered, deliverable emitted, agent paused, decision needed).
|
|
77
|
+
*/
|
|
78
|
+
export interface RunRecentEventDto {
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly at: string;
|
|
81
|
+
readonly summary: string;
|
|
82
|
+
/** Optional deep-link anchor for the Developer-mode timeline. */
|
|
83
|
+
readonly developerAnchor: string | null;
|
|
84
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { WorkflowRunStatus, TERMINAL_WORKFLOW_RUN_STATUSES } from '../../workflow';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The calm modes that replace the legacy 10-tab run detail.
|
|
5
|
+
*
|
|
6
|
+
* - `OVERVIEW` — coarse status + latest deliverables (links) + last 6
|
|
7
|
+
* events. Default for running and terminal runs.
|
|
8
|
+
* - `WORK` — the question canvas + reply form. Default when the run has
|
|
9
|
+
* a question waiting on the current user.
|
|
10
|
+
* - `OUTPUTS` — full deliverables surface. One sub-tab per artifact;
|
|
11
|
+
* each sub-tab renders the artifact's CONTENT (markdown rendered as
|
|
12
|
+
* an A4 page, code diff via the diff viewer, diagram via mermaid,
|
|
13
|
+
* etc.) with a `Show raw` toggle that reveals the underlying artifact
|
|
14
|
+
* JSON. Never the default — opened from the Overview deliverables
|
|
15
|
+
* strip or directly via the mode switcher.
|
|
16
|
+
* - `DEVELOPER` — full activity console + Temporal history + Mounts /
|
|
17
|
+
* Pending / Query diagnostic cards. Behind a user-pref + role gate.
|
|
18
|
+
*
|
|
19
|
+
* Mode-default selection is deterministic — see {@link selectDefaultRunMode}.
|
|
20
|
+
* Free-text strings are forbidden; consumers route on this enum.
|
|
21
|
+
*/
|
|
22
|
+
export enum RunMode {
|
|
23
|
+
OVERVIEW = 'overview',
|
|
24
|
+
WORK = 'work',
|
|
25
|
+
OUTPUTS = 'outputs',
|
|
26
|
+
DEVELOPER = 'developer',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Inputs the deterministic mode-default selector consumes. Keeping this
|
|
31
|
+
* narrow (no full RunDetailDto reference) lets callers pre-compute it
|
|
32
|
+
* without holding the whole run payload in scope.
|
|
33
|
+
*/
|
|
34
|
+
export interface RunModeSelectionInputs {
|
|
35
|
+
readonly status: WorkflowRunStatus;
|
|
36
|
+
readonly hasQuestionForCurrentUser: boolean;
|
|
37
|
+
/** User-pref override; wins if set. */
|
|
38
|
+
readonly userPreferredMode?: RunMode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Deterministic mode-default rules:
|
|
43
|
+
*
|
|
44
|
+
* status == waiting_on_human && hasQuestionForMe(runId) → WORK
|
|
45
|
+
* status terminal → OVERVIEW
|
|
46
|
+
* otherwise → OVERVIEW
|
|
47
|
+
* user pref override → wins
|
|
48
|
+
*
|
|
49
|
+
* No timing, no probabilities, no fuzzy matching. The FE calls this once
|
|
50
|
+
* per render and routes accordingly; reverse calls are not supported.
|
|
51
|
+
*/
|
|
52
|
+
export function selectDefaultRunMode(input: RunModeSelectionInputs): RunMode {
|
|
53
|
+
if (input.userPreferredMode !== undefined) {
|
|
54
|
+
return input.userPreferredMode;
|
|
55
|
+
}
|
|
56
|
+
const isTerminal = TERMINAL_WORKFLOW_RUN_STATUSES.includes(input.status);
|
|
57
|
+
if (
|
|
58
|
+
!isTerminal &&
|
|
59
|
+
input.status === WorkflowRunStatus.WAITING_ON_HUMAN &&
|
|
60
|
+
input.hasQuestionForCurrentUser
|
|
61
|
+
) {
|
|
62
|
+
return RunMode.WORK;
|
|
63
|
+
}
|
|
64
|
+
return RunMode.OVERVIEW;
|
|
65
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { WorkflowRunStatus } from '../../workflow';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Branch the FE outcome strip renders for a TERMINAL run. Mirrors the
|
|
5
|
+
* branch matrix for terminal runs.
|
|
6
|
+
*
|
|
7
|
+
* Every terminal run lands in exactly one branch — the engine sets it on
|
|
8
|
+
* the {@link RunDetailDto.outcome} field at run-end so the FE never has
|
|
9
|
+
* to re-derive from `status` + reason text.
|
|
10
|
+
*/
|
|
11
|
+
export enum RunOutcomeBranch {
|
|
12
|
+
SUCCEEDED = 'succeeded',
|
|
13
|
+
FAILED = 'failed',
|
|
14
|
+
CANCELLED = 'cancelled',
|
|
15
|
+
ESCALATION_EXHAUSTED = 'escalation_exhausted',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* What the user sees in the outcome card. Each branch's `actions` list
|
|
20
|
+
* is computed server-side (only valid CTAs leak into the wire) so the
|
|
21
|
+
* FE renders without policy logic.
|
|
22
|
+
*
|
|
23
|
+
* `summary` is one human sentence — never JSON. The FE displays it
|
|
24
|
+
* verbatim under the status header.
|
|
25
|
+
*/
|
|
26
|
+
export interface RunOutcomeDto {
|
|
27
|
+
readonly branch: RunOutcomeBranch;
|
|
28
|
+
readonly summary: string;
|
|
29
|
+
readonly actions: readonly RunOutcomeActionDto[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A button rendered under the outcome card. Closed CTA enum — the FE
|
|
34
|
+
* fails-fast on unknown values rather than rendering a placeholder.
|
|
35
|
+
*/
|
|
36
|
+
export interface RunOutcomeActionDto {
|
|
37
|
+
readonly kind: RunOutcomeActionKind;
|
|
38
|
+
readonly label: string;
|
|
39
|
+
/** Optional href; if absent the action is dispatched to the engine via SDK. */
|
|
40
|
+
readonly href?: string;
|
|
41
|
+
/** Optional opaque payload the engine echoes on dispatch. */
|
|
42
|
+
readonly payload?: Readonly<Record<string, unknown>>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export enum RunOutcomeActionKind {
|
|
46
|
+
RUN_AGAIN = 'run_again',
|
|
47
|
+
OPEN_IN_KB = 'open_in_kb',
|
|
48
|
+
REDO_FROM_PHASE = 'redo_from_phase',
|
|
49
|
+
OPEN_LAST_SUCCESSFUL_ARTIFACT = 'open_last_successful_artifact',
|
|
50
|
+
RESTART_WITH_SAME_INPUTS = 'restart_with_same_inputs',
|
|
51
|
+
ADJUST_ESCALATION_CHAIN = 'adjust_escalation_chain',
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* True iff a {@link WorkflowRunStatus} represents a terminal state that
|
|
56
|
+
* carries an outcome. Mirrors {@link TERMINAL_WORKFLOW_RUN_STATUSES} but
|
|
57
|
+
* rejects `ABORTED_FOR_MIGRATION` because that branch has no user-facing
|
|
58
|
+
* outcome card (it's an internal lifecycle event).
|
|
59
|
+
*/
|
|
60
|
+
export function isOutcomeBearingStatus(status: WorkflowRunStatus): boolean {
|
|
61
|
+
return (
|
|
62
|
+
status === WorkflowRunStatus.SUCCEEDED ||
|
|
63
|
+
status === WorkflowRunStatus.FAILED ||
|
|
64
|
+
status === WorkflowRunStatus.CANCELLED
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The phase rail shown at the top of every run-detail mode. Click any
|
|
3
|
+
* dot to filter the activity panel to that phase. The rail is a stable,
|
|
4
|
+
* compile-time-known sequence per workflow definition — the engine
|
|
5
|
+
* computes it once at run dispatch and freezes it on the run row so the
|
|
6
|
+
* FE doesn't have to re-derive from runtime activity.
|
|
7
|
+
*/
|
|
8
|
+
export interface RunPhaseRailDto {
|
|
9
|
+
readonly phases: readonly RunPhaseRailEntryDto[];
|
|
10
|
+
/**
|
|
11
|
+
* Index into `phases` of the currently-active phase. `null` when the
|
|
12
|
+
* run is terminal AND the last phase already completed (the rail
|
|
13
|
+
* renders fully filled).
|
|
14
|
+
*/
|
|
15
|
+
readonly currentIndex: number | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface RunPhaseRailEntryDto {
|
|
19
|
+
readonly stageKey: string;
|
|
20
|
+
/** Display label — e.g. "Implementation", "Architecture review". */
|
|
21
|
+
readonly label: string;
|
|
22
|
+
readonly status: RunPhaseRailStatus;
|
|
23
|
+
/** ISO-8601 when the phase entered RUNNING. `null` if not yet started. */
|
|
24
|
+
readonly startedAt: string | null;
|
|
25
|
+
/** ISO-8601 when the phase reached a terminal state. `null` if still in flight. */
|
|
26
|
+
readonly endedAt: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Closed phase-rail status set. Distinct from {@link JobRunStatus} — a
|
|
31
|
+
* single phase rolls up many jobs and adds the WAITING / SKIPPED rail
|
|
32
|
+
* affordances the user sees. Maps from job status server-side; FE
|
|
33
|
+
* renders the icon+color directly off this enum.
|
|
34
|
+
*/
|
|
35
|
+
export enum RunPhaseRailStatus {
|
|
36
|
+
PENDING = 'pending',
|
|
37
|
+
RUNNING = 'running',
|
|
38
|
+
WAITING = 'waiting',
|
|
39
|
+
SUCCEEDED = 'succeeded',
|
|
40
|
+
FAILED = 'failed',
|
|
41
|
+
CANCELLED = 'cancelled',
|
|
42
|
+
SKIPPED = 'skipped',
|
|
43
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three deliberately distinct revision UIs.
|
|
3
|
+
* The engine emits exactly one of these on the run detail payload; the
|
|
4
|
+
* FE renders the matching component (or nothing for `NONE`).
|
|
5
|
+
*
|
|
6
|
+
* - `REVISE` — purple checkpoint card embedded in the doc flow.
|
|
7
|
+
* CTAs: "Approve & continue" | "Revise with feedback".
|
|
8
|
+
* - `MANUAL_OVERRIDE` — warning banner shown after auto-retries are
|
|
9
|
+
* exhausted. CTAs: "Extend retries" | "Force approve" | "Reject run".
|
|
10
|
+
* - `REDO_FROM_PHASE` — terminal-only dropdown that re-dispatches from
|
|
11
|
+
* a chosen earlier phase.
|
|
12
|
+
* - `NONE` — no revision UI; the run is progressing normally.
|
|
13
|
+
*
|
|
14
|
+
* Auto-retry status surfaces as a status pill in the run header, NOT
|
|
15
|
+
* its own revision-state value. Don't extend this enum to cover
|
|
16
|
+
* non-revision states.
|
|
17
|
+
*/
|
|
18
|
+
export enum RunRevisionState {
|
|
19
|
+
NONE = 'none',
|
|
20
|
+
REVISE = 'revise',
|
|
21
|
+
MANUAL_OVERRIDE = 'manual_override',
|
|
22
|
+
REDO_FROM_PHASE = 'redo_from_phase',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Per-state payload the FE needs to render the matching component. The
|
|
27
|
+
* engine includes whichever variant matches `state` and omits the rest.
|
|
28
|
+
*
|
|
29
|
+
* `NONE` carries no payload — the discriminator alone suffices.
|
|
30
|
+
*/
|
|
31
|
+
export type RunRevisionPayload =
|
|
32
|
+
| { readonly state: RunRevisionState.NONE }
|
|
33
|
+
| { readonly state: RunRevisionState.REVISE; readonly checkpoint: RunReviseCheckpointDto }
|
|
34
|
+
| {
|
|
35
|
+
readonly state: RunRevisionState.MANUAL_OVERRIDE;
|
|
36
|
+
readonly override: RunManualOverrideDto;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
readonly state: RunRevisionState.REDO_FROM_PHASE;
|
|
40
|
+
readonly redo: RunRedoFromPhaseDto;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Payload for the purple checkpoint card. */
|
|
44
|
+
export interface RunReviseCheckpointDto {
|
|
45
|
+
readonly checkpointId: string;
|
|
46
|
+
readonly stageKey: string;
|
|
47
|
+
readonly title: string;
|
|
48
|
+
/** Human-readable summary of what's being reviewed. */
|
|
49
|
+
readonly summary: string;
|
|
50
|
+
/** Reviewer findings to render inline alongside the canvas. */
|
|
51
|
+
readonly findings: readonly RunReviseFindingDto[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface RunReviseFindingDto {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly severity: 'info' | 'minor' | 'major' | 'critical';
|
|
57
|
+
/** Optional file:line anchor — `null` if the finding is run-level. */
|
|
58
|
+
readonly anchor: string | null;
|
|
59
|
+
readonly message: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Payload for the manual-override banner (auto-retries exhausted). */
|
|
63
|
+
export interface RunManualOverrideDto {
|
|
64
|
+
readonly retryCount: number;
|
|
65
|
+
readonly retryLimit: number;
|
|
66
|
+
readonly lastFailureReason: string;
|
|
67
|
+
/** When the engine is willing to attempt one more retry on demand. */
|
|
68
|
+
readonly canExtendRetries: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Payload for the redo-from-phase dropdown (terminal runs only). */
|
|
72
|
+
export interface RunRedoFromPhaseDto {
|
|
73
|
+
readonly availablePhases: readonly RunRedoPhaseChoiceDto[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface RunRedoPhaseChoiceDto {
|
|
77
|
+
readonly stageKey: string;
|
|
78
|
+
readonly label: string;
|
|
79
|
+
/** Whether the engine has the inputs needed to re-dispatch from here. */
|
|
80
|
+
readonly available: boolean;
|
|
81
|
+
/** Human-readable reason when `available === false`. */
|
|
82
|
+
readonly unavailableReason?: string;
|
|
83
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for "the run is waiting on X" math used by the
|
|
3
|
+
* RunHeaderTimebar, the run-list "what's blocking" inline text, and the
|
|
4
|
+
* Overview blocking callout.
|
|
5
|
+
*
|
|
6
|
+
* Three different surfaces used to compute these windows independently
|
|
7
|
+
* and could disagree by the
|
|
8
|
+
* second. They now share this util.
|
|
9
|
+
*
|
|
10
|
+
* All times are ISO-8601 strings on the wire; the helpers parse + return
|
|
11
|
+
* primitive ms numbers so callers stay framework-agnostic.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface WaitWindow {
|
|
15
|
+
/** Inclusive start ISO-8601. */
|
|
16
|
+
readonly startedAt: string;
|
|
17
|
+
/** Exclusive end ISO-8601, or `null` if the wait is still open. */
|
|
18
|
+
readonly endedAt: string | null;
|
|
19
|
+
readonly reason: WaitReason;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Closed reason set. The user-visible label is rendered by the FE from
|
|
24
|
+
* this discriminator — never accept a free-form `reason` string from
|
|
25
|
+
* the wire.
|
|
26
|
+
*/
|
|
27
|
+
export enum WaitReason {
|
|
28
|
+
WAITING_ON_HUMAN = 'waiting_on_human',
|
|
29
|
+
WAITING_ON_AGENT = 'waiting_on_agent',
|
|
30
|
+
WAITING_ON_EXTERNAL = 'waiting_on_external',
|
|
31
|
+
WAITING_ON_DEPENDENCY = 'waiting_on_dependency',
|
|
32
|
+
WAITING_ON_QUOTA = 'waiting_on_quota',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Total wait duration (ms) summed across windows. Open windows count
|
|
37
|
+
* up to `nowMs`. Caller passes `nowMs` (test-injectable) — the lib
|
|
38
|
+
* never reads `Date.now()` on its own.
|
|
39
|
+
*/
|
|
40
|
+
export function totalWaitMs(windows: readonly WaitWindow[], nowMs: number): number {
|
|
41
|
+
let total = 0;
|
|
42
|
+
for (const w of windows) {
|
|
43
|
+
const start = Date.parse(w.startedAt);
|
|
44
|
+
const end = w.endedAt !== null ? Date.parse(w.endedAt) : nowMs;
|
|
45
|
+
if (Number.isFinite(start) && Number.isFinite(end) && end > start) {
|
|
46
|
+
total += end - start;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return total;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The currently-open wait window, if any. Returns the most recent open
|
|
54
|
+
* window (there should never be more than one open at a time, but if
|
|
55
|
+
* the engine emits overlapping waits we surface the most recent so the
|
|
56
|
+
* FE doesn't pick a stale reason).
|
|
57
|
+
*/
|
|
58
|
+
export function currentOpenWait(windows: readonly WaitWindow[]): WaitWindow | null {
|
|
59
|
+
let bestStart = -Infinity;
|
|
60
|
+
let bestWindow: WaitWindow | null = null;
|
|
61
|
+
for (const w of windows) {
|
|
62
|
+
if (w.endedAt !== null) continue;
|
|
63
|
+
const start = Date.parse(w.startedAt);
|
|
64
|
+
if (Number.isFinite(start) && start > bestStart) {
|
|
65
|
+
bestStart = start;
|
|
66
|
+
bestWindow = w;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return bestWindow;
|
|
70
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ── Workspace Image Contracts — Barrel Export ──
|
|
3
|
+
//
|
|
4
|
+
// Kernel (Layer 1) contracts for per-org workspace image variants. Pure
|
|
5
|
+
// types, closed enums, zod schemas, plus the deterministic content-hash
|
|
6
|
+
// helper used to identify a variant from its declarative manifest +
|
|
7
|
+
// base-image digest. Zero NestJS, zero Prisma.
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
|
+
|
|
10
|
+
export * from './lib/enums';
|
|
11
|
+
export * from './lib/types';
|
|
12
|
+
export * from './lib/hash';
|
|
13
|
+
export * from './lib/schemas';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ── Workspace image — closed-domain enums ──
|
|
3
|
+
//
|
|
4
|
+
// Closed sets backing the per-org workspace image variants described in
|
|
5
|
+
// the ImageLayerKind enumerates every layer recipe the kernel
|
|
6
|
+
// understands; VariantStatus enumerates the bake lifecycle.
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Closed set of layer-recipe kinds. Each kind has a strict TypeScript
|
|
11
|
+
* payload shape (see `ImageLayer` in `types.ts`).
|
|
12
|
+
*
|
|
13
|
+
* IMPORTANT: there is no `entrypoint` / `cmd` kind — the entrypoint is
|
|
14
|
+
* owned by the worker-runtime, never by an org-supplied recipe.
|
|
15
|
+
*/
|
|
16
|
+
export enum ImageLayerKind {
|
|
17
|
+
Apt = 'apt',
|
|
18
|
+
Dnf = 'dnf',
|
|
19
|
+
Apk = 'apk',
|
|
20
|
+
Pip = 'pip',
|
|
21
|
+
NpmGlobal = 'npm-global',
|
|
22
|
+
Env = 'env',
|
|
23
|
+
File = 'file',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Lifecycle of a single image variant. `draft` is editable in the UI;
|
|
28
|
+
* `building` is the active bake; `ready` is mountable by workers;
|
|
29
|
+
* `failed` retains the build log for debugging; `archived` keeps the row
|
|
30
|
+
* for history but disallows new use.
|
|
31
|
+
*/
|
|
32
|
+
export enum VariantStatus {
|
|
33
|
+
Draft = 'draft',
|
|
34
|
+
Building = 'building',
|
|
35
|
+
Ready = 'ready',
|
|
36
|
+
Failed = 'failed',
|
|
37
|
+
Archived = 'archived',
|
|
38
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ── Workspace image — deterministic content hash ──
|
|
3
|
+
//
|
|
4
|
+
// Given a `WorkspaceImageManifest` plus the resolved base-image digest,
|
|
5
|
+
// produce a stable sha256 used as the variant's content identity. Two
|
|
6
|
+
// inputs that differ only in JSON formatting MUST hash to the same value;
|
|
7
|
+
// two inputs that differ semantically MUST NOT collide.
|
|
8
|
+
//
|
|
9
|
+
// Strategy:
|
|
10
|
+
// 1. Canonicalize: recursively sort object keys; arrays keep their
|
|
11
|
+
// authored order (order is semantically meaningful — `apt install`
|
|
12
|
+
// ordering can change layer caching and image size).
|
|
13
|
+
// 2. JSON.stringify the canonical form (no whitespace, stable key order).
|
|
14
|
+
// 3. sha256 over the concatenation `canonicalManifest + '\n' + digest`.
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
|
|
19
|
+
import type { WorkspaceImageManifest } from './types';
|
|
20
|
+
|
|
21
|
+
type CanonicalJson =
|
|
22
|
+
| null
|
|
23
|
+
| boolean
|
|
24
|
+
| number
|
|
25
|
+
| string
|
|
26
|
+
| readonly CanonicalJson[]
|
|
27
|
+
| { readonly [key: string]: CanonicalJson };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Recursively produce a canonical, order-stable JSON-compatible value:
|
|
31
|
+
*
|
|
32
|
+
* - Objects: keys sorted lexicographically. `undefined` values dropped
|
|
33
|
+
* (mirrors `JSON.stringify`'s default and avoids two inputs differing
|
|
34
|
+
* only by an explicit `undefined` hashing differently).
|
|
35
|
+
* - Arrays: order is preserved (semantically meaningful in image layers).
|
|
36
|
+
* - Primitives & null: pass through.
|
|
37
|
+
*
|
|
38
|
+
* Throws on values JSON cannot represent (functions, symbols, bigint,
|
|
39
|
+
* circular refs) — fail-fast per the project's constitution.
|
|
40
|
+
*/
|
|
41
|
+
function canonicalize(value: unknown, seen: WeakSet<object> = new WeakSet()): CanonicalJson {
|
|
42
|
+
if (value === null) return null;
|
|
43
|
+
const t = typeof value;
|
|
44
|
+
if (t === 'string' || t === 'boolean') {
|
|
45
|
+
return value as CanonicalJson;
|
|
46
|
+
}
|
|
47
|
+
if (t === 'number') {
|
|
48
|
+
if (!Number.isFinite(value as number)) {
|
|
49
|
+
throw new Error('canonicalize: non-finite number is not JSON-representable');
|
|
50
|
+
}
|
|
51
|
+
return value as number;
|
|
52
|
+
}
|
|
53
|
+
if (t === 'undefined') {
|
|
54
|
+
// Will be dropped by the object pass; encountering it at the root or
|
|
55
|
+
// inside an array indicates a programmer error.
|
|
56
|
+
throw new Error('canonicalize: undefined is not JSON-representable');
|
|
57
|
+
}
|
|
58
|
+
if (t === 'bigint' || t === 'function' || t === 'symbol') {
|
|
59
|
+
throw new Error(`canonicalize: ${t} is not JSON-representable`);
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
if (seen.has(value)) throw new Error('canonicalize: circular reference');
|
|
63
|
+
seen.add(value);
|
|
64
|
+
return value.map((entry) => canonicalize(entry, seen));
|
|
65
|
+
}
|
|
66
|
+
// Plain object.
|
|
67
|
+
if (seen.has(value as object)) throw new Error('canonicalize: circular reference');
|
|
68
|
+
seen.add(value as object);
|
|
69
|
+
const entries = Object.entries(value as Record<string, unknown>)
|
|
70
|
+
.filter(([, v]) => v !== undefined)
|
|
71
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
72
|
+
const out: Record<string, CanonicalJson> = {};
|
|
73
|
+
for (const [k, v] of entries) {
|
|
74
|
+
out[k] = canonicalize(v, seen);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Compute the canonical content hash of a workspace image variant. The
|
|
81
|
+
* `baseImageDigest` MUST be the resolved digest of the base image at
|
|
82
|
+
* bake-time (not a mutable tag) — otherwise a tag drift would silently
|
|
83
|
+
* invalidate the hash.
|
|
84
|
+
*/
|
|
85
|
+
export function computeContentHash(
|
|
86
|
+
manifest: WorkspaceImageManifest,
|
|
87
|
+
baseImageDigest: string,
|
|
88
|
+
): string {
|
|
89
|
+
if (!baseImageDigest || typeof baseImageDigest !== 'string') {
|
|
90
|
+
throw new Error('computeContentHash: baseImageDigest is required');
|
|
91
|
+
}
|
|
92
|
+
const canonical = canonicalize(manifest);
|
|
93
|
+
const serialized = JSON.stringify(canonical);
|
|
94
|
+
return createHash('sha256').update(`${serialized}\n${baseImageDigest}`).digest('hex');
|
|
95
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ── Workspace image — zod schemas ──
|
|
3
|
+
//
|
|
4
|
+
// Runtime validators mirroring the enums and DTOs. Used by the bake
|
|
5
|
+
// service when persisting authored manifests and by the frontend when
|
|
6
|
+
// editing them in the Studio.
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { workerRuntimeKindSchema } from '../../worker-runtime';
|
|
11
|
+
|
|
12
|
+
import { ImageLayerKind, VariantStatus } from './enums';
|
|
13
|
+
|
|
14
|
+
export const imageLayerKindSchema = z.nativeEnum(ImageLayerKind);
|
|
15
|
+
export const variantStatusSchema = z.nativeEnum(VariantStatus);
|
|
16
|
+
|
|
17
|
+
const packagesArray = z.array(z.string().min(1));
|
|
18
|
+
|
|
19
|
+
export const imageLayerSchema = z.discriminatedUnion('kind', [
|
|
20
|
+
z.object({ kind: z.literal(ImageLayerKind.Apt), packages: packagesArray }),
|
|
21
|
+
z.object({ kind: z.literal(ImageLayerKind.Dnf), packages: packagesArray }),
|
|
22
|
+
z.object({ kind: z.literal(ImageLayerKind.Apk), packages: packagesArray }),
|
|
23
|
+
z.object({
|
|
24
|
+
kind: z.literal(ImageLayerKind.Pip),
|
|
25
|
+
packages: packagesArray,
|
|
26
|
+
pythonVersion: z.string().min(1).optional(),
|
|
27
|
+
}),
|
|
28
|
+
z.object({ kind: z.literal(ImageLayerKind.NpmGlobal), packages: packagesArray }),
|
|
29
|
+
z.object({
|
|
30
|
+
kind: z.literal(ImageLayerKind.Env),
|
|
31
|
+
vars: z.record(z.string().min(1), z.string()),
|
|
32
|
+
}),
|
|
33
|
+
z.object({
|
|
34
|
+
kind: z.literal(ImageLayerKind.File),
|
|
35
|
+
path: z.string().min(1),
|
|
36
|
+
contentBase64: z.string().min(1),
|
|
37
|
+
mode: z.number().int().nonnegative().optional(),
|
|
38
|
+
}),
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
export const workspaceImageManifestSchema = z.object({
|
|
42
|
+
layers: z.array(imageLayerSchema),
|
|
43
|
+
workdir: z.string().min(1).optional(),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const workspaceImageVariantSchema = z.object({
|
|
47
|
+
id: z.string().min(1),
|
|
48
|
+
orgId: z.string().min(1),
|
|
49
|
+
slug: z.string().min(1),
|
|
50
|
+
description: z.string(),
|
|
51
|
+
runtimeKind: workerRuntimeKindSchema,
|
|
52
|
+
baseImage: z.string().min(1),
|
|
53
|
+
manifest: workspaceImageManifestSchema,
|
|
54
|
+
contentHash: z.string().min(1),
|
|
55
|
+
registryRef: z.string().min(1).optional(),
|
|
56
|
+
status: variantStatusSchema,
|
|
57
|
+
isOrgDefault: z.boolean(),
|
|
58
|
+
autoRebake: z.boolean(),
|
|
59
|
+
regions: z.array(z.string().min(1)),
|
|
60
|
+
buildLog: z.string().optional(),
|
|
61
|
+
builtAt: z.string().min(1).optional(),
|
|
62
|
+
createdAt: z.string().min(1),
|
|
63
|
+
});
|