@sealant/api-contracts-next 0.0.0-next.0 → 0.39.0-next.682

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 (40) hide show
  1. package/LICENSE +202 -0
  2. package/dist/core-api/access-tokens.d.ts +126 -0
  3. package/dist/core-api/access-tokens.js +72 -0
  4. package/dist/core-api/budgets.d.ts +15 -0
  5. package/dist/core-api/budgets.js +13 -0
  6. package/dist/core-api/connected-accounts.d.ts +226 -0
  7. package/dist/core-api/connected-accounts.js +128 -0
  8. package/dist/core-api/control-plane.d.ts +1318 -0
  9. package/dist/core-api/control-plane.js +31 -0
  10. package/dist/core-api/github.d.ts +261 -0
  11. package/dist/core-api/github.js +153 -0
  12. package/dist/core-api/inference.d.ts +223 -0
  13. package/dist/core-api/inference.js +139 -0
  14. package/dist/core-api/oci-names.d.ts +21 -0
  15. package/dist/core-api/oci-names.js +44 -0
  16. package/dist/core-api/packages.d.ts +179 -0
  17. package/dist/core-api/packages.js +60 -0
  18. package/dist/core-api/profiles.d.ts +188 -0
  19. package/dist/core-api/profiles.js +88 -0
  20. package/dist/core-api/record-events.d.ts +209 -0
  21. package/dist/core-api/record-events.js +193 -0
  22. package/dist/core-api/registries.d.ts +106 -0
  23. package/dist/core-api/registries.js +85 -0
  24. package/dist/core-api/runs.d.ts +516 -0
  25. package/dist/core-api/runs.js +284 -0
  26. package/dist/core-api/sessions.d.ts +390 -0
  27. package/dist/core-api/sessions.js +264 -0
  28. package/dist/core-api/ssh-keys.d.ts +120 -0
  29. package/dist/core-api/ssh-keys.js +108 -0
  30. package/dist/core-api/system.d.ts +51 -0
  31. package/dist/core-api/system.js +41 -0
  32. package/dist/core-api/users.d.ts +71 -0
  33. package/dist/core-api/users.js +48 -0
  34. package/dist/core-api/workspaces.d.ts +1880 -0
  35. package/dist/core-api/workspaces.js +980 -0
  36. package/dist/index.d.ts +18 -0
  37. package/dist/index.js +18 -0
  38. package/dist/workspace-environment.d.ts +124 -0
  39. package/dist/workspace-environment.js +259 -0
  40. package/package.json +31 -9
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Run + execution-record wire contracts.
3
+ *
4
+ * A `run` is one harness execution; it owns the execution record (the telemetry log). These
5
+ * endpoints are the network face of the run-detail read path (RunRepo -> THIS contract -> apps/api ->
6
+ * SDK): register a run, read its metadata, list runs, update its terminal status, and read its
7
+ * record — timeline, byte-exact scrollback, and the provenance-honest loss report.
8
+ *
9
+ * Wire note: per-runtime monotonic uint64 sequences are carried as DECIMAL STRINGS (not JSON numbers)
10
+ * so values past 2^53 survive; the SDK and API layer convert to/from `bigint`.
11
+ */
12
+ import { Schema } from "effect";
13
+ import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi";
14
+ import { BudgetExceededError } from "./budgets.js";
15
+ const NonEmptyString = Schema.String.check(Schema.isNonEmpty(), Schema.isTrimmed());
16
+ export const runStatusSchema = Schema.Literals([
17
+ "queued",
18
+ "running",
19
+ "completed",
20
+ "failed",
21
+ "cancelled",
22
+ ]);
23
+ export const runModeSchema = Schema.Literals(["one-shot", "interactive"]);
24
+ // "pty" is the interactive stream: PTY output as recorded from sessions (StreamKind 5).
25
+ export const ioStreamSchema = Schema.Literals(["stdout", "stderr", "pty"]);
26
+ // ---------------------------------------------------------------------------------------------
27
+ // Run resource
28
+ // ---------------------------------------------------------------------------------------------
29
+ /** The one-shot harness invocation the control plane execs in the workspace. */
30
+ export const runCommandSchema = Schema.Struct({
31
+ executable: NonEmptyString,
32
+ args: Schema.Array(Schema.String),
33
+ cwd: Schema.optional(NonEmptyString),
34
+ });
35
+ export const runSchema = Schema.Struct({
36
+ runId: NonEmptyString,
37
+ workspaceId: NonEmptyString,
38
+ attemptId: Schema.optional(NonEmptyString),
39
+ ownerUserId: NonEmptyString,
40
+ harnessId: NonEmptyString,
41
+ mode: runModeSchema,
42
+ status: runStatusSchema,
43
+ prompt: Schema.optional(Schema.String),
44
+ /** The resolved invocation the control plane executed (server-side runs) — self-describing. */
45
+ command: Schema.optional(runCommandSchema),
46
+ /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
47
+ metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
48
+ exitCode: Schema.optional(Schema.Number),
49
+ errorMessage: Schema.optional(Schema.String),
50
+ startedAt: Schema.optional(Schema.String),
51
+ finishedAt: Schema.optional(Schema.String),
52
+ createdAt: Schema.String,
53
+ updatedAt: Schema.String,
54
+ });
55
+ export const runFileChangeSchema = Schema.Struct({
56
+ path: NonEmptyString,
57
+ change: Schema.Literals(["added", "modified", "deleted", "renamed"]),
58
+ oldPath: Schema.optional(NonEmptyString),
59
+ });
60
+ export const createRunRequestSchema = Schema.Struct({
61
+ workspaceId: NonEmptyString,
62
+ harnessId: NonEmptyString,
63
+ ownerUserId: NonEmptyString,
64
+ mode: Schema.optional(runModeSchema),
65
+ prompt: Schema.optional(Schema.String),
66
+ attemptId: Schema.optional(NonEmptyString),
67
+ // When present, the control plane EXECUTES the run SERVER-SIDE: the worker docker-execs this command
68
+ // in the workspace, ingests telemetry, and captures the diff. When absent AND `prompt` is present
69
+ // for a built-in harness, the control plane CONSTRUCTS the command itself (server-side invoke
70
+ // knowledge) — which is what lets a re-fetched workspace handle start a harness. An explicit
71
+ // command always wins (the escape hatch for custom harnesses). Absent both, the run row is
72
+ // created but not executed (the legacy host-local path where the caller runs it itself).
73
+ command: Schema.optional(runCommandSchema),
74
+ /** Opaque caller correlation bag ({ projectId, sessionId, ... }): stored + echoed, no semantics. */
75
+ metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
76
+ });
77
+ export const updateRunRequestSchema = Schema.Struct({
78
+ /** The run's owner. Required by the control plane: an update that names no owner finds no run. */
79
+ ownerUserId: Schema.optional(NonEmptyString),
80
+ status: Schema.optional(runStatusSchema),
81
+ exitCode: Schema.optional(Schema.Number),
82
+ errorMessage: Schema.optional(Schema.String),
83
+ // Terminal-transition capture: callers that observed the run's file changes (e.g. the SSH gateway
84
+ // closing an interactive session) persist them alongside the status flip.
85
+ diff: Schema.optional(Schema.String),
86
+ changedFiles: Schema.optional(Schema.Array(runFileChangeSchema)),
87
+ /** The caller read the run's changes and the reading failed: nothing is known of them. */
88
+ changesReadFailed: Schema.optional(Schema.Boolean),
89
+ });
90
+ export const listRunsQuerySchema = Schema.Struct({
91
+ workspaceId: Schema.optional(NonEmptyString),
92
+ ownerUserId: Schema.optional(NonEmptyString),
93
+ status: Schema.optional(runStatusSchema),
94
+ limit: Schema.optional(NonEmptyString),
95
+ });
96
+ export const listRunsResponseSchema = Schema.Struct({ items: Schema.Array(runSchema) });
97
+ // ---------------------------------------------------------------------------------------------
98
+ // Execution record — timeline
99
+ // ---------------------------------------------------------------------------------------------
100
+ export const timelineEntrySchema = Schema.Struct({
101
+ eventId: NonEmptyString,
102
+ sequence: NonEmptyString, // decimal-string uint64
103
+ kind: NonEmptyString,
104
+ occurredAt: NonEmptyString, // decimal-string monotonic timestamp
105
+ summary: Schema.String,
106
+ ref: Schema.optional(Schema.Unknown),
107
+ /** Correlation id of the producing process (attribution key for record views). */
108
+ processId: Schema.optional(NonEmptyString),
109
+ /** Numeric CaptureMethod / Confidence enums — how the fact was captured, per envelope. */
110
+ captureMethod: Schema.Number,
111
+ confidence: Schema.Number,
112
+ });
113
+ /**
114
+ * Owner scoping on reads: the run must belong to `ownerUserId` (uniform 404 otherwise). The field
115
+ * stays optional on the wire for older callers, but the control plane requires it: a read that
116
+ * names no owner finds no run.
117
+ */
118
+ export const runOwnerQuerySchema = Schema.Struct({
119
+ ownerUserId: Schema.optional(NonEmptyString),
120
+ });
121
+ export const getRunTimelineQuerySchema = Schema.Struct({
122
+ ownerUserId: Schema.optional(NonEmptyString),
123
+ fromSequence: Schema.optional(NonEmptyString),
124
+ toSequence: Schema.optional(NonEmptyString),
125
+ limit: Schema.optional(NonEmptyString),
126
+ /**
127
+ * Comma-separated payload cases (e.g. `processStarted,processExited,fileChange`). Filters the
128
+ * timeline to those event kinds server-side — the read path for record views that must not pay
129
+ * for the ioChunk-dominated full log.
130
+ */
131
+ kinds: Schema.optional(NonEmptyString),
132
+ });
133
+ export const runTimelineResponseSchema = Schema.Struct({
134
+ items: Schema.Array(timelineEntrySchema),
135
+ });
136
+ // ---------------------------------------------------------------------------------------------
137
+ // Execution record — single raw event (the full envelope, provenance included)
138
+ // ---------------------------------------------------------------------------------------------
139
+ /**
140
+ * One stored EventEnvelope, verbatim: correlation ids, both clocks, capture provenance, and the
141
+ * jsonb payload (bigints stringified at ingest). This is the drill-down read behind a timeline
142
+ * entry — the timeline carries the summary + ref, this carries the whole record.
143
+ */
144
+ export const runEventSchema = Schema.Struct({
145
+ eventId: NonEmptyString,
146
+ runId: NonEmptyString,
147
+ runtimeId: NonEmptyString,
148
+ executionId: Schema.optional(NonEmptyString),
149
+ sessionId: Schema.optional(NonEmptyString),
150
+ processId: Schema.optional(NonEmptyString),
151
+ requestId: Schema.optional(NonEmptyString),
152
+ schemaVersion: Schema.Number,
153
+ sequence: NonEmptyString, // decimal-string uint64
154
+ observedAt: NonEmptyString, // decimal-string int64 wall clock
155
+ monotonicTimestamp: NonEmptyString, // decimal-string uint64 ordering clock
156
+ captureMethod: Schema.Number,
157
+ confidence: Schema.Number,
158
+ payloadCase: NonEmptyString,
159
+ payload: Schema.Unknown,
160
+ ingestedAt: Schema.String,
161
+ });
162
+ // ---------------------------------------------------------------------------------------------
163
+ // Execution record — scrollback (byte-exact terminal output)
164
+ // ---------------------------------------------------------------------------------------------
165
+ export const getRunScrollbackQuerySchema = Schema.Struct({
166
+ ownerUserId: Schema.optional(NonEmptyString),
167
+ processId: NonEmptyString,
168
+ stream: ioStreamSchema,
169
+ atSequence: Schema.optional(NonEmptyString),
170
+ /** Inclusive lower sequence bound — with `atSequence` this selects a sequence RANGE. */
171
+ fromSequence: Schema.optional(NonEmptyString),
172
+ /** Maximum chunks to reconstruct (server default 5000). */
173
+ limit: Schema.optional(NonEmptyString),
174
+ });
175
+ export const runScrollbackResponseSchema = Schema.Struct({
176
+ processId: NonEmptyString,
177
+ stream: ioStreamSchema,
178
+ byteCount: Schema.Number,
179
+ /** Base64-encoded reconstructed bytes (byte-exact as recorded; redaction happens upstream). */
180
+ contentBase64: Schema.String,
181
+ });
182
+ // ---------------------------------------------------------------------------------------------
183
+ // Execution record — loss report (provenance honesty)
184
+ // ---------------------------------------------------------------------------------------------
185
+ export const lossSpanSchema = Schema.Struct({
186
+ kind: Schema.Literals(["dropped_event", "sequence_gap", "watch_overflow", "early_close"]),
187
+ fromSequence: Schema.optional(NonEmptyString),
188
+ toSequence: Schema.optional(NonEmptyString),
189
+ droppedCount: Schema.optional(NonEmptyString),
190
+ detectedVia: Schema.Literals(["marker", "gap"]),
191
+ reason: Schema.optional(Schema.String),
192
+ });
193
+ export const runLossReportSchema = Schema.Struct({
194
+ runId: NonEmptyString,
195
+ droppedEventCount: NonEmptyString, // decimal-string uint64
196
+ sequenceGapCount: Schema.Number,
197
+ watchOverflowCount: Schema.Number,
198
+ earlyClose: Schema.Boolean,
199
+ spans: Schema.Array(lossSpanSchema),
200
+ });
201
+ // ---------------------------------------------------------------------------------------------
202
+ // Run changes — the file diff the run produced (captured server-side)
203
+ // ---------------------------------------------------------------------------------------------
204
+ export const runChangesResponseSchema = Schema.Struct({
205
+ files: Schema.Array(runFileChangeSchema),
206
+ /** Unified diff of everything that changed (empty until the run has produced changes). */
207
+ diff: Schema.String,
208
+ /**
209
+ * Whether the run's changes were read. `false`: they were not (the run has not ended, no
210
+ * reading ran for it, or the reading failed), and the empty `files` and `diff` say nothing
211
+ * about what changed. Absent from a control plane older than the field: read as `true`.
212
+ */
213
+ available: Schema.optional(Schema.Boolean),
214
+ /** Why the changes are not available, when `available` is `false`. */
215
+ unavailableReason: Schema.optional(Schema.String),
216
+ });
217
+ // ---------------------------------------------------------------------------------------------
218
+ // Errors
219
+ // ---------------------------------------------------------------------------------------------
220
+ export class RunBadRequestError extends Schema.TaggedErrorClass()("RunBadRequestError", { message: Schema.String }, { httpApiStatus: 400 }) {
221
+ }
222
+ export class RunNotFoundError extends Schema.TaggedErrorClass()("RunNotFoundError", { message: Schema.String }, { httpApiStatus: 404 }) {
223
+ }
224
+ export class RunInternalServerError extends Schema.TaggedErrorClass()("RunInternalServerError", { message: Schema.String }, { httpApiStatus: 500 }) {
225
+ }
226
+ const runIdParams = Schema.Struct({ runId: NonEmptyString });
227
+ const runEventParams = Schema.Struct({ runId: NonEmptyString, sequence: NonEmptyString });
228
+ // ---------------------------------------------------------------------------------------------
229
+ // Group
230
+ // ---------------------------------------------------------------------------------------------
231
+ export const RunsGroup = HttpApiGroup.make("runs")
232
+ .add(HttpApiEndpoint.post("createRun", "/", {
233
+ payload: createRunRequestSchema,
234
+ success: runSchema.pipe(HttpApiSchema.status(201)),
235
+ error: [BudgetExceededError, RunBadRequestError, RunNotFoundError, RunInternalServerError],
236
+ }))
237
+ .add(HttpApiEndpoint.get("listRuns", "/", {
238
+ query: listRunsQuerySchema,
239
+ success: listRunsResponseSchema,
240
+ error: [RunBadRequestError, RunInternalServerError],
241
+ }))
242
+ .add(HttpApiEndpoint.get("getRun", "/:runId", {
243
+ params: runIdParams,
244
+ query: runOwnerQuerySchema,
245
+ success: runSchema,
246
+ error: [RunNotFoundError, RunInternalServerError],
247
+ }))
248
+ .add(HttpApiEndpoint.patch("updateRun", "/:runId", {
249
+ params: runIdParams,
250
+ payload: updateRunRequestSchema,
251
+ success: runSchema,
252
+ error: [RunBadRequestError, RunNotFoundError, RunInternalServerError],
253
+ }))
254
+ .add(HttpApiEndpoint.get("getRunTimeline", "/:runId/timeline", {
255
+ params: runIdParams,
256
+ query: getRunTimelineQuerySchema,
257
+ success: runTimelineResponseSchema,
258
+ error: [RunBadRequestError, RunNotFoundError, RunInternalServerError],
259
+ }))
260
+ .add(HttpApiEndpoint.get("getRunEvent", "/:runId/events/:sequence", {
261
+ params: runEventParams,
262
+ query: runOwnerQuerySchema,
263
+ success: runEventSchema,
264
+ error: [RunBadRequestError, RunNotFoundError, RunInternalServerError],
265
+ }))
266
+ .add(HttpApiEndpoint.get("getRunScrollback", "/:runId/scrollback", {
267
+ params: runIdParams,
268
+ query: getRunScrollbackQuerySchema,
269
+ success: runScrollbackResponseSchema,
270
+ error: [RunBadRequestError, RunNotFoundError, RunInternalServerError],
271
+ }))
272
+ .add(HttpApiEndpoint.get("getRunLoss", "/:runId/loss", {
273
+ params: runIdParams,
274
+ query: runOwnerQuerySchema,
275
+ success: runLossReportSchema,
276
+ error: [RunNotFoundError, RunInternalServerError],
277
+ }))
278
+ .add(HttpApiEndpoint.get("getRunChanges", "/:runId/changes", {
279
+ params: runIdParams,
280
+ query: runOwnerQuerySchema,
281
+ success: runChangesResponseSchema,
282
+ error: [RunNotFoundError, RunInternalServerError],
283
+ }))
284
+ .annotate(OpenApi.Description, "Runs (harness executions) and their execution record.");