@sealant/api-contracts-next 0.39.0-next.704 → 0.39.0-next.705

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.
@@ -427,6 +427,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
427
427
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
428
428
  }>>;
429
429
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
430
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
430
431
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
431
432
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
432
433
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -455,6 +456,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
455
456
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
456
457
  }>>;
457
458
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
459
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
458
460
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
459
461
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
460
462
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -572,6 +574,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
572
574
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
573
575
  }>>;
574
576
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
577
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
575
578
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
576
579
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
577
580
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -611,6 +614,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
611
614
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
612
615
  }>>;
613
616
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
617
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
614
618
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
615
619
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
616
620
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -678,6 +682,40 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
678
682
  readonly outputHighWater: import("effect/Schema").String;
679
683
  readonly createdAt: import("effect/Schema").String;
680
684
  readonly endedAt: import("effect/Schema").optional<import("effect/Schema").String>;
685
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("./sessions.js").SessionBadRequestError | typeof import("./sessions.js").SessionUnauthorizedError | typeof import("./sessions.js").SessionForbiddenError | typeof import("./sessions.js").SessionNotFoundError | typeof import("./sessions.js").SessionConflictError | typeof import("./sessions.js").SessionBadGatewayError | typeof import("./sessions.js").SessionInternalServerError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"createSessionAsUser", "POST", "/v1/sessions/as-user", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
686
+ readonly workspaceId: import("effect/Schema").String;
687
+ readonly ownerUserId: import("effect/Schema").String;
688
+ readonly argv: import("effect/Schema").$Array<import("effect/Schema").String>;
689
+ readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
690
+ readonly env: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").String>>;
691
+ readonly cols: import("effect/Schema").optional<import("effect/Schema").Int>;
692
+ readonly rows: import("effect/Schema").optional<import("effect/Schema").Int>;
693
+ readonly term: import("effect/Schema").optional<import("effect/Schema").String>;
694
+ readonly mode: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["pty", "pipe"]>>;
695
+ readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
696
+ readonly user: import("effect/Schema").String;
697
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
698
+ readonly authorization: import("effect/Schema").optional<import("effect/Schema").String>;
699
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
700
+ readonly sessionId: import("effect/Schema").String;
701
+ readonly workspaceId: import("effect/Schema").String;
702
+ readonly runId: import("effect/Schema").String;
703
+ readonly ownerUserId: import("effect/Schema").String;
704
+ readonly status: import("effect/Schema").Literals<readonly ["starting", "running", "exited", "failed"]>;
705
+ readonly argv: import("effect/Schema").$Array<import("effect/Schema").String>;
706
+ readonly argCount: import("effect/Schema").optional<import("effect/Schema").Number>;
707
+ readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
708
+ readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
709
+ readonly cols: import("effect/Schema").Number;
710
+ readonly rows: import("effect/Schema").Number;
711
+ readonly mode: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["pty", "pipe"]>>;
712
+ readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
713
+ readonly exitSignal: import("effect/Schema").optional<import("effect/Schema").Number>;
714
+ readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
715
+ readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
716
+ readonly outputHighWater: import("effect/Schema").String;
717
+ readonly createdAt: import("effect/Schema").String;
718
+ readonly endedAt: import("effect/Schema").optional<import("effect/Schema").String>;
681
719
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("./sessions.js").SessionBadRequestError | typeof import("./sessions.js").SessionUnauthorizedError | typeof import("./sessions.js").SessionForbiddenError | typeof import("./sessions.js").SessionNotFoundError | typeof import("./sessions.js").SessionConflictError | typeof import("./sessions.js").SessionBadGatewayError | typeof import("./sessions.js").SessionInternalServerError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"getSession", "GET", "/v1/sessions/:sessionId", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
682
720
  readonly sessionId: import("effect/Schema").String;
683
721
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
@@ -826,6 +864,11 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
826
864
  readonly openApiPath: import("effect/Schema").String;
827
865
  readonly features: import("effect/Schema").optional<import("effect/Schema").Struct<{
828
866
  readonly processUser: import("effect/Schema").Boolean;
867
+ readonly processUserRoutes: import("effect/Schema").optional<import("effect/Schema").Boolean>;
868
+ readonly dotfilesApply: import("effect/Schema").optional<import("effect/Schema").Boolean>;
869
+ readonly credentialsPartialPut: import("effect/Schema").optional<import("effect/Schema").Boolean>;
870
+ readonly credentialsPiOpencode: import("effect/Schema").optional<import("effect/Schema").Boolean>;
871
+ readonly captureOwnerMap: import("effect/Schema").optional<import("effect/Schema").Boolean>;
829
872
  }>>;
830
873
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<never>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"getSetupState", "GET", "/v1/system/setup-state", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
831
874
  readonly needsSetup: import("effect/Schema").Boolean;
@@ -893,6 +936,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
893
936
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
894
937
  }>>;
895
938
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
939
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
896
940
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
897
941
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
898
942
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -1000,6 +1044,42 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
1000
1044
  readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
1001
1045
  }>>;
1002
1046
  readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
1047
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
1048
+ readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
1049
+ readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
1050
+ readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
1051
+ readonly finishedAt: import("effect/Schema").optional<import("effect/Schema").String>;
1052
+ readonly recordDeletedAt: import("effect/Schema").optional<import("effect/Schema").String>;
1053
+ readonly createdAt: import("effect/Schema").String;
1054
+ readonly updatedAt: import("effect/Schema").String;
1055
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("./workspaces.js").WorkspaceBadRequestError | typeof import("./workspaces.js").WorkspaceNotFoundError | typeof import("./workspaces.js").WorkspaceConflictError | typeof import("./workspaces.js").WorkspaceBadGatewayError | typeof import("./workspaces.js").WorkspaceInternalServerError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"execWorkspaceAsUser", "POST", "/v1/workspaces/:workspaceId/exec-as-user", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
1056
+ readonly workspaceId: import("effect/Schema").String;
1057
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
1058
+ readonly ownerUserId: import("effect/Schema").String;
1059
+ readonly commands: import("effect/Schema").$Array<import("effect/Schema").Struct<{
1060
+ readonly executable: import("effect/Schema").String;
1061
+ readonly args: import("effect/Schema").$Array<import("effect/Schema").String>;
1062
+ readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
1063
+ }>>;
1064
+ readonly user: import("effect/Schema").String;
1065
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
1066
+ readonly runId: import("effect/Schema").String;
1067
+ readonly workspaceId: import("effect/Schema").String;
1068
+ readonly attemptId: import("effect/Schema").optional<import("effect/Schema").String>;
1069
+ readonly ownerUserId: import("effect/Schema").String;
1070
+ readonly harnessId: import("effect/Schema").String;
1071
+ readonly mode: import("effect/Schema").Literals<readonly ["one-shot", "interactive"]>;
1072
+ readonly status: import("effect/Schema").Literals<readonly ["queued", "running", "completed", "failed", "cancelled"]>;
1073
+ readonly prompt: import("effect/Schema").optional<import("effect/Schema").String>;
1074
+ readonly command: import("effect/Schema").optional<import("effect/Schema").Struct<{
1075
+ readonly executable: import("effect/Schema").String;
1076
+ readonly args: import("effect/Schema").$Array<import("effect/Schema").String>;
1077
+ readonly cwd: import("effect/Schema").optional<import("effect/Schema").String>;
1078
+ readonly argCount: import("effect/Schema").optional<import("effect/Schema").Number>;
1079
+ readonly argLengths: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Number>>;
1080
+ }>>;
1081
+ readonly metadata: import("effect/Schema").optional<import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>>;
1082
+ readonly user: import("effect/Schema").optional<import("effect/Schema").String>;
1003
1083
  readonly exitCode: import("effect/Schema").optional<import("effect/Schema").Number>;
1004
1084
  readonly errorMessage: import("effect/Schema").optional<import("effect/Schema").String>;
1005
1085
  readonly startedAt: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -1007,7 +1087,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
1007
1087
  readonly recordDeletedAt: import("effect/Schema").optional<import("effect/Schema").String>;
1008
1088
  readonly createdAt: import("effect/Schema").String;
1009
1089
  readonly updatedAt: import("effect/Schema").String;
1010
- }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("./workspaces.js").WorkspaceBadRequestError | typeof import("./workspaces.js").WorkspaceNotFoundError | typeof import("./workspaces.js").WorkspaceConflictError | typeof import("./workspaces.js").WorkspaceInternalServerError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"expireWorkspace", "POST", "/v1/workspaces/:workspaceId/expire", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
1090
+ }>>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<typeof import("./workspaces.js").WorkspaceBadRequestError | typeof import("./workspaces.js").WorkspaceNotFoundError | typeof import("./workspaces.js").WorkspaceConflictError | typeof import("./workspaces.js").WorkspaceBadGatewayError | typeof import("./workspaces.js").WorkspaceInternalServerError>, never, never> | import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"expireWorkspace", "POST", "/v1/workspaces/:workspaceId/expire", import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<import("effect/Schema").Struct<{
1011
1091
  readonly workspaceId: import("effect/Schema").String;
1012
1092
  }>>, import("effect/unstable/httpapi/HttpApiEndpoint").StringTree<never>, import("effect/unstable/httpapi/HttpApiEndpoint").Json<import("effect/Schema").Struct<{
1013
1093
  readonly ownerUserId: import("effect/Schema").String;
@@ -1106,6 +1186,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
1106
1186
  readonly acl: import("effect/Schema").Literals<readonly ["supported", "unsupported", "unknown"]>;
1107
1187
  }>>;
1108
1188
  }>>;
1189
+ readonly processUser: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["supported", "unsupported", "unknown"]>>;
1109
1190
  readonly error: import("effect/Schema").optional<import("effect/Schema").Struct<{
1110
1191
  readonly message: import("effect/Schema").String;
1111
1192
  readonly code: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -1403,6 +1484,7 @@ export declare const ControlPlaneAPI: HttpApi.HttpApi<"sealantControlPlaneApi",
1403
1484
  readonly acl: import("effect/Schema").Literals<readonly ["supported", "unsupported", "unknown"]>;
1404
1485
  }>>;
1405
1486
  }>>;
1487
+ readonly processUser: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["supported", "unsupported", "unknown"]>>;
1406
1488
  readonly error: import("effect/Schema").optional<import("effect/Schema").Struct<{
1407
1489
  readonly message: import("effect/Schema").String;
1408
1490
  readonly code: import("effect/Schema").optional<import("effect/Schema").String>;
@@ -57,6 +57,11 @@ export declare const runSchema: Schema.Struct<{
57
57
  }>>;
58
58
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
59
59
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
60
+ /**
61
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
62
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
63
+ */
64
+ readonly user: Schema.optional<Schema.String>;
60
65
  readonly exitCode: Schema.optional<Schema.Number>;
61
66
  readonly errorMessage: Schema.optional<Schema.String>;
62
67
  readonly startedAt: Schema.optional<Schema.String>;
@@ -135,6 +140,11 @@ export declare const listRunsResponseSchema: Schema.Struct<{
135
140
  }>>;
136
141
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
137
142
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
143
+ /**
144
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
145
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
146
+ */
147
+ readonly user: Schema.optional<Schema.String>;
138
148
  readonly exitCode: Schema.optional<Schema.Number>;
139
149
  readonly errorMessage: Schema.optional<Schema.String>;
140
150
  readonly startedAt: Schema.optional<Schema.String>;
@@ -335,6 +345,11 @@ export declare const RunsGroup: HttpApiGroup.HttpApiGroup<"runs", HttpApiEndpoin
335
345
  }>>;
336
346
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
337
347
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
348
+ /**
349
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
350
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
351
+ */
352
+ readonly user: Schema.optional<Schema.String>;
338
353
  readonly exitCode: Schema.optional<Schema.Number>;
339
354
  readonly errorMessage: Schema.optional<Schema.String>;
340
355
  readonly startedAt: Schema.optional<Schema.String>;
@@ -369,6 +384,11 @@ export declare const RunsGroup: HttpApiGroup.HttpApiGroup<"runs", HttpApiEndpoin
369
384
  }>>;
370
385
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
371
386
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
387
+ /**
388
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
389
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
390
+ */
391
+ readonly user: Schema.optional<Schema.String>;
372
392
  readonly exitCode: Schema.optional<Schema.Number>;
373
393
  readonly errorMessage: Schema.optional<Schema.String>;
374
394
  readonly startedAt: Schema.optional<Schema.String>;
@@ -509,6 +529,11 @@ export declare const RunsGroup: HttpApiGroup.HttpApiGroup<"runs", HttpApiEndpoin
509
529
  }>>;
510
530
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
511
531
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
532
+ /**
533
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
534
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
535
+ */
536
+ readonly user: Schema.optional<Schema.String>;
512
537
  readonly exitCode: Schema.optional<Schema.Number>;
513
538
  readonly errorMessage: Schema.optional<Schema.String>;
514
539
  readonly startedAt: Schema.optional<Schema.String>;
@@ -556,6 +581,11 @@ export declare const RunsGroup: HttpApiGroup.HttpApiGroup<"runs", HttpApiEndpoin
556
581
  }>>;
557
582
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
558
583
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
584
+ /**
585
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
586
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
587
+ */
588
+ readonly user: Schema.optional<Schema.String>;
559
589
  readonly exitCode: Schema.optional<Schema.Number>;
560
590
  readonly errorMessage: Schema.optional<Schema.String>;
561
591
  readonly startedAt: Schema.optional<Schema.String>;
@@ -55,6 +55,11 @@ export const runSchema = Schema.Struct({
55
55
  command: Schema.optional(recordedRunCommandSchema),
56
56
  /** Opaque caller correlation bag, echoed verbatim (no platform semantics). */
57
57
  metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
58
+ /**
59
+ * The Linux user the run's processes were started as (`user` on an exec or a session): the login
60
+ * name or uid the caller named, and nothing else of the process. Absent: the workspace's own user.
61
+ */
62
+ user: Schema.optional(NonEmptyString),
58
63
  exitCode: Schema.optional(Schema.Number),
59
64
  errorMessage: Schema.optional(Schema.String),
60
65
  startedAt: Schema.optional(Schema.String),
@@ -32,14 +32,20 @@ export declare const sessionModeSchema: Schema.Literals<readonly ["pty", "pipe"]
32
32
  export type SessionMode = typeof sessionModeSchema.Type;
33
33
  /**
34
34
  * The Linux user a process runs as (Mend ADR 0016): a user name of the image's passwd, or a numeric
35
- * uid. The process takes its uid, gid, supplementary groups and `HOME`, `USER`, `LOGNAME` and
36
- * `SHELL` from the passwd entry, umask 0002. Absent: the workspace's own user, as before.
35
+ * uid. The workspace's sealantd starts the process as that passwd entry: its uid, gid,
36
+ * supplementary groups and `HOME`, `USER`, `LOGNAME` and `SHELL`, umask 0002, a private `TMPDIR`
37
+ * and `XDG_RUNTIME_DIR`, the image's `/etc/sealant/person-env`, and none of the daemon's logins.
38
+ * Only a person Mend made: a uid in 40001–49999 whose primary group is `mend` (40000), never root,
39
+ * on a workspace whose sealantd reports `exec.user`. Anything else is refused before anything
40
+ * starts (`409`, `user-unsupported`). Absent: the workspace's own user, as before.
37
41
  */
38
42
  export declare const workspaceProcessUserSchema: Schema.String;
39
43
  export type WorkspaceProcessUser = typeof workspaceProcessUserSchema.Type;
40
44
  /**
41
- * The stable `code` a create or exec answers while no workspace runtime can start a process as
42
- * another user: Core asks sealantd to, and no released sealantd does yet. Nothing is started.
45
+ * The stable `code` a session or exec as a user is refused with (`409`), the message saying why:
46
+ * the workspace's sealantd does not run processes as another user (no `exec.user`), its runtime
47
+ * does not (Cloudflare), the user is not in range (root, a uid outside 40001–49999, or a primary
48
+ * group other than `mend`), or no such user exists yet. Nothing is started.
43
49
  */
44
50
  export declare const PROCESS_USER_UNSUPPORTED_CODE = "user-unsupported";
45
51
  export declare const createSessionRequestSchema: Schema.Struct<{
@@ -58,10 +64,38 @@ export declare const createSessionRequestSchema: Schema.Struct<{
58
64
  readonly mode: Schema.optional<Schema.Literals<readonly ["pty", "pipe"]>>;
59
65
  /** Opaque caller correlation bag: stored verbatim, echoed on reads, no platform semantics. */
60
66
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
61
- /** Run the session's process as this Linux user (see `workspaceProcessUserSchema`). */
67
+ /**
68
+ * Refused here (`409`, `user-unsupported`), never ignored: a session as a Linux user is opened
69
+ * with `POST /v1/sessions/as-user` (`createSessionAsUserRequestSchema`), a route a control plane
70
+ * that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
71
+ */
62
72
  readonly user: Schema.optional<Schema.String>;
63
73
  }>;
64
74
  export type CreateSessionRequest = typeof createSessionRequestSchema.Type;
75
+ /**
76
+ * `POST /v1/sessions/as-user`: a session whose leader runs as `user` (see
77
+ * `workspaceProcessUserSchema`), otherwise as `POST /v1/sessions`. Its own route, so a control
78
+ * plane from before it answers `404` instead of opening the session as the workspace's own user.
79
+ */
80
+ export declare const createSessionAsUserRequestSchema: Schema.Struct<{
81
+ readonly workspaceId: Schema.String;
82
+ readonly ownerUserId: Schema.String;
83
+ /** argv[0] is the program the session runs; the rest its arguments. */
84
+ readonly argv: Schema.$Array<Schema.String>;
85
+ /** Working directory inside the workspace (defaults to the workspace working directory). */
86
+ readonly cwd: Schema.optional<Schema.String>;
87
+ /** Extra environment for the PTY process (values are NOT secrets — use credentials for those). */
88
+ readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
89
+ readonly cols: Schema.optional<Schema.Int>;
90
+ readonly rows: Schema.optional<Schema.Int>;
91
+ readonly term: Schema.optional<Schema.String>;
92
+ /** Leader wiring; defaults to `pty`. `cols`/`rows`/`term` are ignored for `pipe`. */
93
+ readonly mode: Schema.optional<Schema.Literals<readonly ["pty", "pipe"]>>;
94
+ /** Opaque caller correlation bag: stored verbatim, echoed on reads, no platform semantics. */
95
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
96
+ readonly user: Schema.String;
97
+ }>;
98
+ export type CreateSessionAsUserRequest = typeof createSessionAsUserRequestSchema.Type;
65
99
  export declare const sessionSchema: Schema.Struct<{
66
100
  readonly sessionId: Schema.String;
67
101
  readonly workspaceId: Schema.String;
@@ -285,7 +319,11 @@ export declare const SessionsGroup: HttpApiGroup.HttpApiGroup<"sessions", HttpAp
285
319
  readonly mode: Schema.optional<Schema.Literals<readonly ["pty", "pipe"]>>;
286
320
  /** Opaque caller correlation bag: stored verbatim, echoed on reads, no platform semantics. */
287
321
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
288
- /** Run the session's process as this Linux user (see `workspaceProcessUserSchema`). */
322
+ /**
323
+ * Refused here (`409`, `user-unsupported`), never ignored: a session as a Linux user is opened
324
+ * with `POST /v1/sessions/as-user` (`createSessionAsUserRequestSchema`), a route a control plane
325
+ * that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
326
+ */
289
327
  readonly user: Schema.optional<Schema.String>;
290
328
  }>>, HttpApiEndpoint.StringTree<Schema.Struct<{
291
329
  readonly authorization: Schema.optional<Schema.String>;
@@ -322,6 +360,58 @@ export declare const SessionsGroup: HttpApiGroup.HttpApiGroup<"sessions", HttpAp
322
360
  readonly outputHighWater: Schema.String;
323
361
  readonly createdAt: Schema.String;
324
362
  readonly endedAt: Schema.optional<Schema.String>;
363
+ }>>, HttpApiEndpoint.Json<typeof SessionBadRequestError | typeof SessionUnauthorizedError | typeof SessionForbiddenError | typeof SessionNotFoundError | typeof SessionConflictError | typeof SessionBadGatewayError | typeof SessionInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"createSessionAsUser", "POST", "/as-user", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
364
+ readonly workspaceId: Schema.String;
365
+ readonly ownerUserId: Schema.String;
366
+ /** argv[0] is the program the session runs; the rest its arguments. */
367
+ readonly argv: Schema.$Array<Schema.String>;
368
+ /** Working directory inside the workspace (defaults to the workspace working directory). */
369
+ readonly cwd: Schema.optional<Schema.String>;
370
+ /** Extra environment for the PTY process (values are NOT secrets — use credentials for those). */
371
+ readonly env: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
372
+ readonly cols: Schema.optional<Schema.Int>;
373
+ readonly rows: Schema.optional<Schema.Int>;
374
+ readonly term: Schema.optional<Schema.String>;
375
+ /** Leader wiring; defaults to `pty`. `cols`/`rows`/`term` are ignored for `pipe`. */
376
+ readonly mode: Schema.optional<Schema.Literals<readonly ["pty", "pipe"]>>;
377
+ /** Opaque caller correlation bag: stored verbatim, echoed on reads, no platform semantics. */
378
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
379
+ readonly user: Schema.String;
380
+ }>>, HttpApiEndpoint.StringTree<Schema.Struct<{
381
+ readonly authorization: Schema.optional<Schema.String>;
382
+ }>>, HttpApiEndpoint.Json<Schema.Struct<{
383
+ readonly sessionId: Schema.String;
384
+ readonly workspaceId: Schema.String;
385
+ /** The interactive run recording this session; its record is the durable evidence. */
386
+ readonly runId: Schema.String;
387
+ readonly ownerUserId: Schema.String;
388
+ readonly status: Schema.Literals<readonly ["starting", "running", "exited", "failed"]>;
389
+ /**
390
+ * Only `argv[0]`, the program: Sealant never stores a session's arguments, because they can carry
391
+ * secrets. `argCount` and `argLengths` (UTF-8 bytes each) describe them.
392
+ */
393
+ readonly argv: Schema.$Array<Schema.String>;
394
+ /** How many arguments followed the program. Absent when there were none. */
395
+ readonly argCount: Schema.optional<Schema.Number>;
396
+ /** Each argument's length in UTF-8 bytes, in order. Absent when there were none. */
397
+ readonly argLengths: Schema.optional<Schema.$Array<Schema.Number>>;
398
+ readonly cwd: Schema.optional<Schema.String>;
399
+ readonly cols: Schema.Number;
400
+ readonly rows: Schema.Number;
401
+ /** Leader wiring. Absent on servers from before pipe mode shipped, which means `pty`. */
402
+ readonly mode: Schema.optional<Schema.Literals<readonly ["pty", "pipe"]>>;
403
+ readonly exitCode: Schema.optional<Schema.Number>;
404
+ readonly exitSignal: Schema.optional<Schema.Number>;
405
+ readonly errorMessage: Schema.optional<Schema.String>;
406
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
407
+ /**
408
+ * Highest ingested output sequence for this session's run (decimal string), or "0" when nothing
409
+ * has been ingested yet — the resume cursor: `output?from=<highWater + 1>` continues exactly
410
+ * where a previous reader stopped.
411
+ */
412
+ readonly outputHighWater: Schema.String;
413
+ readonly createdAt: Schema.String;
414
+ readonly endedAt: Schema.optional<Schema.String>;
325
415
  }>>, HttpApiEndpoint.Json<typeof SessionBadRequestError | typeof SessionUnauthorizedError | typeof SessionForbiddenError | typeof SessionNotFoundError | typeof SessionConflictError | typeof SessionBadGatewayError | typeof SessionInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getSession", "GET", "/:sessionId", HttpApiEndpoint.StringTree<Schema.Struct<{
326
416
  readonly sessionId: Schema.String;
327
417
  }>>, HttpApiEndpoint.StringTree<Schema.Struct<{
@@ -30,13 +30,19 @@ export const sessionAuthorizationHeadersSchema = Schema.Struct({
30
30
  export const sessionModeSchema = Schema.Literals(["pty", "pipe"]);
31
31
  /**
32
32
  * The Linux user a process runs as (Mend ADR 0016): a user name of the image's passwd, or a numeric
33
- * uid. The process takes its uid, gid, supplementary groups and `HOME`, `USER`, `LOGNAME` and
34
- * `SHELL` from the passwd entry, umask 0002. Absent: the workspace's own user, as before.
33
+ * uid. The workspace's sealantd starts the process as that passwd entry: its uid, gid,
34
+ * supplementary groups and `HOME`, `USER`, `LOGNAME` and `SHELL`, umask 0002, a private `TMPDIR`
35
+ * and `XDG_RUNTIME_DIR`, the image's `/etc/sealant/person-env`, and none of the daemon's logins.
36
+ * Only a person Mend made: a uid in 40001–49999 whose primary group is `mend` (40000), never root,
37
+ * on a workspace whose sealantd reports `exec.user`. Anything else is refused before anything
38
+ * starts (`409`, `user-unsupported`). Absent: the workspace's own user, as before.
35
39
  */
36
40
  export const workspaceProcessUserSchema = Schema.String.check(Schema.isPattern(/^(?:[a-z_][a-z0-9_-]{0,31}|[0-9]{1,10})$/));
37
41
  /**
38
- * The stable `code` a create or exec answers while no workspace runtime can start a process as
39
- * another user: Core asks sealantd to, and no released sealantd does yet. Nothing is started.
42
+ * The stable `code` a session or exec as a user is refused with (`409`), the message saying why:
43
+ * the workspace's sealantd does not run processes as another user (no `exec.user`), its runtime
44
+ * does not (Cloudflare), the user is not in range (root, a uid outside 40001–49999, or a primary
45
+ * group other than `mend`), or no such user exists yet. Nothing is started.
40
46
  */
41
47
  export const PROCESS_USER_UNSUPPORTED_CODE = "user-unsupported";
42
48
  export const createSessionRequestSchema = Schema.Struct({
@@ -55,9 +61,22 @@ export const createSessionRequestSchema = Schema.Struct({
55
61
  mode: Schema.optional(sessionModeSchema),
56
62
  /** Opaque caller correlation bag: stored verbatim, echoed on reads, no platform semantics. */
57
63
  metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
58
- /** Run the session's process as this Linux user (see `workspaceProcessUserSchema`). */
64
+ /**
65
+ * Refused here (`409`, `user-unsupported`), never ignored: a session as a Linux user is opened
66
+ * with `POST /v1/sessions/as-user` (`createSessionAsUserRequestSchema`), a route a control plane
67
+ * that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
68
+ */
59
69
  user: Schema.optional(workspaceProcessUserSchema),
60
70
  });
71
+ /**
72
+ * `POST /v1/sessions/as-user`: a session whose leader runs as `user` (see
73
+ * `workspaceProcessUserSchema`), otherwise as `POST /v1/sessions`. Its own route, so a control
74
+ * plane from before it answers `404` instead of opening the session as the workspace's own user.
75
+ */
76
+ export const createSessionAsUserRequestSchema = Schema.Struct({
77
+ ...createSessionRequestSchema.fields,
78
+ user: workspaceProcessUserSchema,
79
+ });
61
80
  export const sessionSchema = Schema.Struct({
62
81
  sessionId: NonEmptyString,
63
82
  workspaceId: NonEmptyString,
@@ -177,6 +196,23 @@ HttpApiEndpoint.post("createSession", "/", {
177
196
  SessionBadGatewayError,
178
197
  SessionInternalServerError,
179
198
  ],
199
+ }))
200
+ .add(
201
+ // Scope: workspace:exec. `createSession` with the leader run as a Linux user (`409`
202
+ // `user-unsupported` where the executor cannot; `502` when it does not answer the check).
203
+ HttpApiEndpoint.post("createSessionAsUser", "/as-user", {
204
+ headers: sessionAuthorizationHeadersSchema,
205
+ payload: createSessionAsUserRequestSchema,
206
+ success: sessionSchema.pipe(HttpApiSchema.status(201)),
207
+ error: [
208
+ SessionBadRequestError,
209
+ SessionUnauthorizedError,
210
+ SessionForbiddenError,
211
+ SessionNotFoundError,
212
+ SessionConflictError,
213
+ SessionBadGatewayError,
214
+ SessionInternalServerError,
215
+ ],
180
216
  }))
181
217
  .add(HttpApiEndpoint.get("listSessions", "/", {
182
218
  headers: sessionAuthorizationHeadersSchema,
@@ -7,11 +7,32 @@ export declare const systemIndexResponseSchema: Schema.Struct<{
7
7
  readonly openApiPath: Schema.String;
8
8
  /**
9
9
  * What this control plane can do that an older one cannot, so a client refuses a request it would
10
- * otherwise send to a server that ignores part of it. Absent from older control planes: nothing.
10
+ * otherwise send to a server that ignores part of it, and feature-detects instead of reading a
11
+ * version (a self-built control plane reports `0.0.0`). Absent from older control planes:
12
+ * nothing; an absent field: not this one.
11
13
  */
12
14
  readonly features: Schema.optional<Schema.Struct<{
13
- /** A process can run as a given Linux user (`user` on exec and sessions). */
15
+ /**
16
+ * Always `false` from this control plane: `user` on the plain exec and session routes is
17
+ * refused. Kept, and kept false, because SDKs from before the as-user routes read `true` as
18
+ * leave to send `user` on the plain routes, which a control plane from before `user` would
19
+ * accept and run as the workspace's own user.
20
+ */
14
21
  readonly processUser: Schema.Boolean;
22
+ /**
23
+ * `POST /v1/workspaces/:id/exec-as-user` and `POST /v1/sessions/as-user` exist: a process
24
+ * runs as a person's Linux user there. Whether a given workspace can is its read's
25
+ * `processUser`; one that cannot is refused there (`409`, `user-unsupported`).
26
+ */
27
+ readonly processUserRoutes: Schema.optional<Schema.Boolean>;
28
+ /** `POST /v1/workspaces/:id/dotfiles`: a person's dotfiles applied as their user. */
29
+ readonly dotfilesApply: Schema.optional<Schema.Boolean>;
30
+ /** `partial: true` on a credentials put: what is connected is written, the rest reported. */
31
+ readonly credentialsPartialPut: Schema.optional<Schema.Boolean>;
32
+ /** `pi` and `opencode` (ChatGPT logins from a Codex account) on a credentials put. */
33
+ readonly credentialsPiOpencode: Schema.optional<Schema.Boolean>;
34
+ /** `ownerMap` on a capture source: an executor whose restore gives each person their files. */
35
+ readonly captureOwnerMap: Schema.optional<Schema.Boolean>;
15
36
  }>>;
16
37
  }>;
17
38
  export type SystemIndexResponse = typeof systemIndexResponseSchema.Type;
@@ -46,11 +67,32 @@ export declare const SystemGroup: HttpApiGroup.HttpApiGroup<"system", HttpApiEnd
46
67
  readonly openApiPath: Schema.String;
47
68
  /**
48
69
  * What this control plane can do that an older one cannot, so a client refuses a request it would
49
- * otherwise send to a server that ignores part of it. Absent from older control planes: nothing.
70
+ * otherwise send to a server that ignores part of it, and feature-detects instead of reading a
71
+ * version (a self-built control plane reports `0.0.0`). Absent from older control planes:
72
+ * nothing; an absent field: not this one.
50
73
  */
51
74
  readonly features: Schema.optional<Schema.Struct<{
52
- /** A process can run as a given Linux user (`user` on exec and sessions). */
75
+ /**
76
+ * Always `false` from this control plane: `user` on the plain exec and session routes is
77
+ * refused. Kept, and kept false, because SDKs from before the as-user routes read `true` as
78
+ * leave to send `user` on the plain routes, which a control plane from before `user` would
79
+ * accept and run as the workspace's own user.
80
+ */
53
81
  readonly processUser: Schema.Boolean;
82
+ /**
83
+ * `POST /v1/workspaces/:id/exec-as-user` and `POST /v1/sessions/as-user` exist: a process
84
+ * runs as a person's Linux user there. Whether a given workspace can is its read's
85
+ * `processUser`; one that cannot is refused there (`409`, `user-unsupported`).
86
+ */
87
+ readonly processUserRoutes: Schema.optional<Schema.Boolean>;
88
+ /** `POST /v1/workspaces/:id/dotfiles`: a person's dotfiles applied as their user. */
89
+ readonly dotfilesApply: Schema.optional<Schema.Boolean>;
90
+ /** `partial: true` on a credentials put: what is connected is written, the rest reported. */
91
+ readonly credentialsPartialPut: Schema.optional<Schema.Boolean>;
92
+ /** `pi` and `opencode` (ChatGPT logins from a Codex account) on a credentials put. */
93
+ readonly credentialsPiOpencode: Schema.optional<Schema.Boolean>;
94
+ /** `ownerMap` on a capture source: an executor whose restore gives each person their files. */
95
+ readonly captureOwnerMap: Schema.optional<Schema.Boolean>;
54
96
  }>>;
55
97
  }>>, HttpApiEndpoint.Json<never>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"getSetupState", "GET", "/v1/system/setup-state", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
56
98
  readonly needsSetup: Schema.Boolean;
@@ -8,11 +8,32 @@ export const systemIndexResponseSchema = Schema.Struct({
8
8
  openApiPath: NonEmptyString,
9
9
  /**
10
10
  * What this control plane can do that an older one cannot, so a client refuses a request it would
11
- * otherwise send to a server that ignores part of it. Absent from older control planes: nothing.
11
+ * otherwise send to a server that ignores part of it, and feature-detects instead of reading a
12
+ * version (a self-built control plane reports `0.0.0`). Absent from older control planes:
13
+ * nothing; an absent field: not this one.
12
14
  */
13
15
  features: Schema.optional(Schema.Struct({
14
- /** A process can run as a given Linux user (`user` on exec and sessions). */
16
+ /**
17
+ * Always `false` from this control plane: `user` on the plain exec and session routes is
18
+ * refused. Kept, and kept false, because SDKs from before the as-user routes read `true` as
19
+ * leave to send `user` on the plain routes, which a control plane from before `user` would
20
+ * accept and run as the workspace's own user.
21
+ */
15
22
  processUser: Schema.Boolean,
23
+ /**
24
+ * `POST /v1/workspaces/:id/exec-as-user` and `POST /v1/sessions/as-user` exist: a process
25
+ * runs as a person's Linux user there. Whether a given workspace can is its read's
26
+ * `processUser`; one that cannot is refused there (`409`, `user-unsupported`).
27
+ */
28
+ processUserRoutes: Schema.optional(Schema.Boolean),
29
+ /** `POST /v1/workspaces/:id/dotfiles`: a person's dotfiles applied as their user. */
30
+ dotfilesApply: Schema.optional(Schema.Boolean),
31
+ /** `partial: true` on a credentials put: what is connected is written, the rest reported. */
32
+ credentialsPartialPut: Schema.optional(Schema.Boolean),
33
+ /** `pi` and `opencode` (ChatGPT logins from a Codex account) on a credentials put. */
34
+ credentialsPiOpencode: Schema.optional(Schema.Boolean),
35
+ /** `ownerMap` on a capture source: an executor whose restore gives each person their files. */
36
+ captureOwnerMap: Schema.optional(Schema.Boolean),
16
37
  })),
17
38
  });
18
39
  export const systemHealthResponseSchema = Schema.Struct({
@@ -70,6 +70,15 @@ export declare const workspaceImagePersonLayoutSchema: Schema.Struct<{
70
70
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
71
71
  }>;
72
72
  export type WorkspaceImagePersonLayout = typeof workspaceImagePersonLayoutSchema.Type;
73
+ /**
74
+ * Whether a workspace's processes can be started as a person's Linux user (`user` on exec and
75
+ * sessions): `supported` when the sealantd of the image its latest launch booted reports
76
+ * `exec.user` (the image build's probe), `unsupported` when it does not or the runtime never runs a
77
+ * process as a user (Cloudflare), `unknown` when nothing says (an image built before the probe).
78
+ * The exec or session itself asks the running daemon, whose answer decides.
79
+ */
80
+ export declare const workspaceProcessUserCapabilitySchema: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
81
+ export type WorkspaceProcessUserCapability = typeof workspaceProcessUserCapabilitySchema.Type;
73
82
  export declare const workspacePublishedImageSchema: Schema.Struct<{
74
83
  readonly reference: Schema.String;
75
84
  readonly digestReference: Schema.String;
@@ -182,10 +191,32 @@ export declare const execWorkspaceRequestSchema: Schema.Struct<{
182
191
  readonly args: Schema.$Array<Schema.String>;
183
192
  readonly cwd: Schema.optional<Schema.String>;
184
193
  }>>;
185
- /** Run every command as this Linux user (see `workspaceProcessUserSchema`). */
194
+ /**
195
+ * Refused here (`409`, `user-unsupported`), never ignored: an exec as a Linux user is asked for
196
+ * with `POST /v1/workspaces/:id/exec-as-user` (`execWorkspaceAsUserRequestSchema`), a route a
197
+ * control plane that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
198
+ */
186
199
  readonly user: Schema.optional<Schema.String>;
187
200
  }>;
188
201
  export type ExecWorkspaceRequest = typeof execWorkspaceRequestSchema.Type;
202
+ /**
203
+ * `POST /v1/workspaces/:id/exec-as-user`: an exec whose every command runs as `user` (see
204
+ * `workspaceProcessUserSchema`), checked against the running executor before the run is made and
205
+ * recorded on the run (`user`); otherwise as `POST /v1/workspaces/:id/exec`. Its own route, so a
206
+ * control plane from before it answers `404` instead of running the commands as the workspace's
207
+ * own user.
208
+ */
209
+ export declare const execWorkspaceAsUserRequestSchema: Schema.Struct<{
210
+ readonly ownerUserId: Schema.String;
211
+ /** Commands execute sequentially in the workspace, each recorded like any other process. */
212
+ readonly commands: Schema.$Array<Schema.Struct<{
213
+ readonly executable: Schema.String;
214
+ readonly args: Schema.$Array<Schema.String>;
215
+ readonly cwd: Schema.optional<Schema.String>;
216
+ }>>;
217
+ readonly user: Schema.String;
218
+ }>;
219
+ export type ExecWorkspaceAsUserRequest = typeof execWorkspaceAsUserRequestSchema.Type;
189
220
  /** The `harnessId` stamped on runs that apply a person's dotfiles (`applyWorkspaceDotfiles`). */
190
221
  export declare const dotfilesRunHarnessId = "dotfiles";
191
222
  /** How a dotfiles tree is applied: chezmoi and stow layouts are detected by `auto`. */
@@ -1126,6 +1157,8 @@ export declare const workspaceSummarySchema: Schema.Struct<{
1126
1157
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
1127
1158
  }>>;
1128
1159
  }>>;
1160
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
1161
+ readonly processUser: Schema.optional<Schema.Literals<readonly ["supported", "unsupported", "unknown"]>>;
1129
1162
  readonly error: Schema.optional<Schema.Struct<{
1130
1163
  readonly message: Schema.String;
1131
1164
  readonly code: Schema.optional<Schema.String>;
@@ -1285,6 +1318,8 @@ export declare const workspaceDetailsSchema: Schema.Struct<{
1285
1318
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
1286
1319
  }>>;
1287
1320
  }>>;
1321
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
1322
+ readonly processUser: Schema.optional<Schema.Literals<readonly ["supported", "unsupported", "unknown"]>>;
1288
1323
  readonly error: Schema.optional<Schema.Struct<{
1289
1324
  readonly message: Schema.String;
1290
1325
  readonly code: Schema.optional<Schema.String>;
@@ -1445,6 +1480,8 @@ export declare const listWorkspacesResponseSchema: Schema.Struct<{
1445
1480
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
1446
1481
  }>>;
1447
1482
  }>>;
1483
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
1484
+ readonly processUser: Schema.optional<Schema.Literals<readonly ["supported", "unsupported", "unknown"]>>;
1448
1485
  readonly error: Schema.optional<Schema.Struct<{
1449
1486
  readonly message: Schema.String;
1450
1487
  readonly code: Schema.optional<Schema.String>;
@@ -1764,6 +1801,7 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
1764
1801
  readonly argLengths: Schema.optional<Schema.$Array<Schema.Number>>;
1765
1802
  }>>;
1766
1803
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
1804
+ readonly user: Schema.optional<Schema.String>;
1767
1805
  readonly exitCode: Schema.optional<Schema.Number>;
1768
1806
  readonly errorMessage: Schema.optional<Schema.String>;
1769
1807
  readonly startedAt: Schema.optional<Schema.String>;
@@ -1887,8 +1925,48 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
1887
1925
  readonly args: Schema.$Array<Schema.String>;
1888
1926
  readonly cwd: Schema.optional<Schema.String>;
1889
1927
  }>>;
1890
- /** Run every command as this Linux user (see `workspaceProcessUserSchema`). */
1928
+ /**
1929
+ * Refused here (`409`, `user-unsupported`), never ignored: an exec as a Linux user is asked for
1930
+ * with `POST /v1/workspaces/:id/exec-as-user` (`execWorkspaceAsUserRequestSchema`), a route a
1931
+ * control plane that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
1932
+ */
1933
+ readonly user: Schema.optional<Schema.String>;
1934
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
1935
+ readonly runId: Schema.String;
1936
+ readonly workspaceId: Schema.String;
1937
+ readonly attemptId: Schema.optional<Schema.String>;
1938
+ readonly ownerUserId: Schema.String;
1939
+ readonly harnessId: Schema.String;
1940
+ readonly mode: Schema.Literals<readonly ["one-shot", "interactive"]>;
1941
+ readonly status: Schema.Literals<readonly ["queued", "running", "completed", "failed", "cancelled"]>;
1942
+ readonly prompt: Schema.optional<Schema.String>;
1943
+ readonly command: Schema.optional<Schema.Struct<{
1944
+ readonly executable: Schema.String;
1945
+ readonly args: Schema.$Array<Schema.String>;
1946
+ readonly cwd: Schema.optional<Schema.String>;
1947
+ readonly argCount: Schema.optional<Schema.Number>;
1948
+ readonly argLengths: Schema.optional<Schema.$Array<Schema.Number>>;
1949
+ }>>;
1950
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
1891
1951
  readonly user: Schema.optional<Schema.String>;
1952
+ readonly exitCode: Schema.optional<Schema.Number>;
1953
+ readonly errorMessage: Schema.optional<Schema.String>;
1954
+ readonly startedAt: Schema.optional<Schema.String>;
1955
+ readonly finishedAt: Schema.optional<Schema.String>;
1956
+ readonly recordDeletedAt: Schema.optional<Schema.String>;
1957
+ readonly createdAt: Schema.String;
1958
+ readonly updatedAt: Schema.String;
1959
+ }>>, HttpApiEndpoint.Json<typeof WorkspaceBadRequestError | typeof WorkspaceNotFoundError | typeof WorkspaceConflictError | typeof WorkspaceBadGatewayError | typeof WorkspaceInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"execWorkspaceAsUser", "POST", "/:workspaceId/exec-as-user", HttpApiEndpoint.StringTree<Schema.Struct<{
1960
+ readonly workspaceId: Schema.String;
1961
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
1962
+ readonly ownerUserId: Schema.String;
1963
+ /** Commands execute sequentially in the workspace, each recorded like any other process. */
1964
+ readonly commands: Schema.$Array<Schema.Struct<{
1965
+ readonly executable: Schema.String;
1966
+ readonly args: Schema.$Array<Schema.String>;
1967
+ readonly cwd: Schema.optional<Schema.String>;
1968
+ }>>;
1969
+ readonly user: Schema.String;
1892
1970
  }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
1893
1971
  readonly runId: Schema.String;
1894
1972
  readonly workspaceId: Schema.String;
@@ -1906,6 +1984,7 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
1906
1984
  readonly argLengths: Schema.optional<Schema.$Array<Schema.Number>>;
1907
1985
  }>>;
1908
1986
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
1987
+ readonly user: Schema.optional<Schema.String>;
1909
1988
  readonly exitCode: Schema.optional<Schema.Number>;
1910
1989
  readonly errorMessage: Schema.optional<Schema.String>;
1911
1990
  readonly startedAt: Schema.optional<Schema.String>;
@@ -1913,7 +1992,7 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
1913
1992
  readonly recordDeletedAt: Schema.optional<Schema.String>;
1914
1993
  readonly createdAt: Schema.String;
1915
1994
  readonly updatedAt: Schema.String;
1916
- }>>, HttpApiEndpoint.Json<typeof WorkspaceBadRequestError | typeof WorkspaceNotFoundError | typeof WorkspaceConflictError | typeof WorkspaceInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"expireWorkspace", "POST", "/:workspaceId/expire", HttpApiEndpoint.StringTree<Schema.Struct<{
1995
+ }>>, HttpApiEndpoint.Json<typeof WorkspaceBadRequestError | typeof WorkspaceNotFoundError | typeof WorkspaceConflictError | typeof WorkspaceBadGatewayError | typeof WorkspaceInternalServerError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"expireWorkspace", "POST", "/:workspaceId/expire", HttpApiEndpoint.StringTree<Schema.Struct<{
1917
1996
  readonly workspaceId: Schema.String;
1918
1997
  }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
1919
1998
  readonly ownerUserId: Schema.String;
@@ -2114,6 +2193,8 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
2114
2193
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
2115
2194
  }>>;
2116
2195
  }>>;
2196
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
2197
+ readonly processUser: Schema.optional<Schema.Literals<readonly ["supported", "unsupported", "unknown"]>>;
2117
2198
  readonly error: Schema.optional<Schema.Struct<{
2118
2199
  readonly message: Schema.String;
2119
2200
  readonly code: Schema.optional<Schema.String>;
@@ -2585,6 +2666,8 @@ export declare const WorkspacesGroup: HttpApiGroup.HttpApiGroup<"workspaces", Ht
2585
2666
  readonly acl: Schema.Literals<readonly ["supported", "unsupported", "unknown"]>;
2586
2667
  }>>;
2587
2668
  }>>;
2669
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
2670
+ readonly processUser: Schema.optional<Schema.Literals<readonly ["supported", "unsupported", "unknown"]>>;
2588
2671
  readonly error: Schema.optional<Schema.Struct<{
2589
2672
  readonly message: Schema.String;
2590
2673
  readonly code: Schema.optional<Schema.String>;
@@ -78,6 +78,18 @@ export const workspaceImagePersonLayoutSchema = Schema.Struct({
78
78
  /** ACLs on that runtime's `/workspace`, as the operator declared them. */
79
79
  acl: Schema.Literals(["supported", "unsupported", "unknown"]),
80
80
  });
81
+ /**
82
+ * Whether a workspace's processes can be started as a person's Linux user (`user` on exec and
83
+ * sessions): `supported` when the sealantd of the image its latest launch booted reports
84
+ * `exec.user` (the image build's probe), `unsupported` when it does not or the runtime never runs a
85
+ * process as a user (Cloudflare), `unknown` when nothing says (an image built before the probe).
86
+ * The exec or session itself asks the running daemon, whose answer decides.
87
+ */
88
+ export const workspaceProcessUserCapabilitySchema = Schema.Literals([
89
+ "supported",
90
+ "unsupported",
91
+ "unknown",
92
+ ]);
81
93
  export const workspacePublishedImageSchema = Schema.Struct({
82
94
  reference: NonEmptyString,
83
95
  digestReference: NonEmptyString,
@@ -167,9 +179,24 @@ export const execWorkspaceRequestSchema = Schema.Struct({
167
179
  ownerUserId: NonEmptyString,
168
180
  /** Commands execute sequentially in the workspace, each recorded like any other process. */
169
181
  commands: Schema.Array(runCommandSchema).check(Schema.isNonEmpty(), Schema.isMaxLength(32)),
170
- /** Run every command as this Linux user (see `workspaceProcessUserSchema`). */
182
+ /**
183
+ * Refused here (`409`, `user-unsupported`), never ignored: an exec as a Linux user is asked for
184
+ * with `POST /v1/workspaces/:id/exec-as-user` (`execWorkspaceAsUserRequestSchema`), a route a
185
+ * control plane that cannot run one answers `404`, so a mixed-version fleet never runs it as root.
186
+ */
171
187
  user: Schema.optional(workspaceProcessUserSchema),
172
188
  });
189
+ /**
190
+ * `POST /v1/workspaces/:id/exec-as-user`: an exec whose every command runs as `user` (see
191
+ * `workspaceProcessUserSchema`), checked against the running executor before the run is made and
192
+ * recorded on the run (`user`); otherwise as `POST /v1/workspaces/:id/exec`. Its own route, so a
193
+ * control plane from before it answers `404` instead of running the commands as the workspace's
194
+ * own user.
195
+ */
196
+ export const execWorkspaceAsUserRequestSchema = Schema.Struct({
197
+ ...execWorkspaceRequestSchema.fields,
198
+ user: workspaceProcessUserSchema,
199
+ });
173
200
  /** The `harnessId` stamped on runs that apply a person's dotfiles (`applyWorkspaceDotfiles`). */
174
201
  export const dotfilesRunHarnessId = "dotfiles";
175
202
  /** How a dotfiles tree is applied: chezmoi and stow layouts are detected by `auto`. */
@@ -852,6 +879,8 @@ export const workspaceSummarySchema = Schema.Struct({
852
879
  tag: Schema.optional(NonEmptyString),
853
880
  runtime: Schema.optional(workspaceRuntimeSchema),
854
881
  publishedImage: Schema.optional(workspacePublishedImageSchema),
882
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
883
+ processUser: Schema.optional(workspaceProcessUserCapabilitySchema),
855
884
  error: Schema.optional(workspaceErrorSchema),
856
885
  /** Where the launch is while the workspace is not ready (see `workspacePhaseSchema`). */
857
886
  phase: Schema.optional(workspacePhaseSchema),
@@ -948,6 +977,8 @@ export const workspaceDetailsSchema = Schema.Struct({
948
977
  tag: Schema.optional(NonEmptyString),
949
978
  runtime: Schema.optional(workspaceRuntimeSchema),
950
979
  publishedImage: Schema.optional(workspacePublishedImageSchema),
980
+ /** See `workspaceProcessUserCapabilitySchema`. Absent from older control planes. */
981
+ processUser: Schema.optional(workspaceProcessUserCapabilitySchema),
951
982
  error: Schema.optional(workspaceErrorSchema),
952
983
  /** Where the launch is while the workspace is not ready (see `workspacePhaseSchema`). */
953
984
  phase: Schema.optional(workspacePhaseSchema),
@@ -1214,8 +1245,28 @@ HttpApiEndpoint.post("execWorkspace", "/:workspaceId/exec", {
1214
1245
  error: [
1215
1246
  WorkspaceBadRequestError,
1216
1247
  WorkspaceNotFoundError,
1217
- // The workspace has never launched a runtime — nothing to exec in yet.
1248
+ // The workspace has never launched a runtime — nothing to exec in yet; or a `user`, which
1249
+ // this route refuses (`user-unsupported`): see `execWorkspaceAsUser`.
1218
1250
  WorkspaceConflictError,
1251
+ // Shared with `execWorkspaceAsUser`'s handler; this route never reaches the executor first.
1252
+ WorkspaceBadGatewayError,
1253
+ WorkspaceInternalServerError,
1254
+ ],
1255
+ }))
1256
+ .add(
1257
+ // `execWorkspace` with every command run as a Linux user: 202 + the queued run.
1258
+ HttpApiEndpoint.post("execWorkspaceAsUser", "/:workspaceId/exec-as-user", {
1259
+ params: workspaceIdParams,
1260
+ payload: execWorkspaceAsUserRequestSchema,
1261
+ success: runSchema.pipe(HttpApiSchema.status(202)),
1262
+ error: [
1263
+ WorkspaceBadRequestError,
1264
+ WorkspaceNotFoundError,
1265
+ // The executor cannot run a process as the user (`user-unsupported`, the message saying
1266
+ // why), or none is running (`workspace-not-running`).
1267
+ WorkspaceConflictError,
1268
+ // The executor did not answer whether the user may run a process.
1269
+ WorkspaceBadGatewayError,
1219
1270
  WorkspaceInternalServerError,
1220
1271
  ],
1221
1272
  }))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealant/api-contracts-next",
3
- "version": "0.39.0-next.704",
3
+ "version": "0.39.0-next.705",
4
4
  "description": "Contract-first HTTP API definitions for Sealant services",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -32,7 +32,7 @@
32
32
  "peerDependencies": {
33
33
  "effect": ">=4.0.0-beta.85 <5"
34
34
  },
35
- "gitHead": "4cfff680be5ef20c0413f37ba7835ffdd540104f",
35
+ "gitHead": "720a38bb179299ccfd50154afbe2818fa92df9f9",
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  }