@sealant/sdk-next 0.39.0-next.753 → 0.40.0-next.755
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/client.js +27 -2
- package/dist/effect/api-client.d.ts +86 -0
- package/dist/effect/operations.d.ts +62 -0
- package/dist/effect/operations.js +5 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.js +5 -0
- package/dist/internal/credentials.d.ts +1 -3
- package/dist/internal/credentials.js +0 -1
- package/dist/internal/features.d.ts +2 -0
- package/dist/internal/features.js +8 -0
- package/dist/internal/inference.js +1 -7
- package/dist/internal/map-error.js +5 -0
- package/dist/types.d.ts +70 -7
- package/package.json +3 -3
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { archiveConnectedAccountOp, archiveSshKeyOp, cancelWorkspaceCreateOp, createAccessTokenOp, createConnectedAccountOp, createSshKeyOp, createWorkspaceOp, ensureUserOp, getRunOp, getSetupStateOp, getUserOp, bindUserPersonOp, getWorkspaceCreateOp, getWorkspaceOp, inferenceRespondOp, inspectWorkspaceImageOp, listConnectedAccountsOp, listSshKeysOp, listWorkspacesOp, } from "./effect/operations.js";
|
|
1
|
+
import { archiveConnectedAccountOp, archiveSshKeyOp, cancelWorkspaceCreateOp, createAccessTokenOp, createConnectedAccountOp, createSshKeyOp, createWorkspaceOp, ensureUserOp, getRunOp, getSetupStateOp, getUserOp, bindUserPersonOp, getWorkspaceCreateOp, getWorkspaceOp, inferenceRespondOp, inspectWorkspaceImageOp, listConnectedAccountsOp, listSshKeysOp, listWorkspacesOp, markConnectedAccountInvalidOp, setConnectedAccountDefaultOp, } from "./effect/operations.js";
|
|
2
2
|
import { runHarness, startHarness } from "./effect/run-harness.js";
|
|
3
3
|
import { makeSdkRuntime } from "./effect/runtime.js";
|
|
4
4
|
import { SealantError } from "./errors.js";
|
|
@@ -7,7 +7,7 @@ import { makeWorkspace, registerHarnessExecutors, toRuntimeInfo, toWorkspaceImag
|
|
|
7
7
|
import { buildCreateWorkspaceRequest } from "./internal/blueprint.js";
|
|
8
8
|
import { resolveInternalConfig } from "./internal/config.js";
|
|
9
9
|
import { parseTtlSeconds } from "./internal/duration.js";
|
|
10
|
-
import { readFeatures } from "./internal/features.js";
|
|
10
|
+
import { readFeatures, requireConnectedAccountDefaults } from "./internal/features.js";
|
|
11
11
|
import { imageSpecKey } from "./internal/image-key.js";
|
|
12
12
|
import { buildInferenceRespondRequest, mapInferenceResponse } from "./internal/inference.js";
|
|
13
13
|
import { requireSshUser } from "./internal/process-user.js";
|
|
@@ -33,6 +33,8 @@ const mapConnectedAccount = (wire) => ({
|
|
|
33
33
|
lastUsedAt: wire.lastUsedAt,
|
|
34
34
|
lastSyncedAt: wire.lastSyncedAt,
|
|
35
35
|
credential: wire.credential,
|
|
36
|
+
isDefault: wire.isDefault ?? wire.name === "default",
|
|
37
|
+
...(wire.credentialRevision === undefined ? {} : { credentialRevision: wire.credentialRevision }),
|
|
36
38
|
});
|
|
37
39
|
// Wire the run-execution implementations into the Workspace facade (the injection point exists to
|
|
38
40
|
// break the workspace <-> run-harness import cycle; the client is the composition root).
|
|
@@ -243,11 +245,16 @@ export class Sealant {
|
|
|
243
245
|
return wire.items.map(mapConnectedAccount);
|
|
244
246
|
},
|
|
245
247
|
connect: async (options) => {
|
|
248
|
+
if (options.accountId !== undefined || options.makeDefault !== undefined) {
|
|
249
|
+
await requireConnectedAccountDefaults(this.#ctx);
|
|
250
|
+
}
|
|
246
251
|
const wire = await this.#runtime.run(createConnectedAccountOp({
|
|
247
252
|
ownerUserId: this.#ctx.config.hostLocal.ownerUserId,
|
|
248
253
|
provider: options.provider,
|
|
249
254
|
secret: options.secret,
|
|
250
255
|
...(options.name === undefined ? {} : { name: options.name }),
|
|
256
|
+
...(options.accountId === undefined ? {} : { accountId: options.accountId }),
|
|
257
|
+
...(options.makeDefault === undefined ? {} : { makeDefault: options.makeDefault }),
|
|
251
258
|
}));
|
|
252
259
|
return mapConnectedAccount(wire);
|
|
253
260
|
},
|
|
@@ -255,6 +262,24 @@ export class Sealant {
|
|
|
255
262
|
const wire = await this.#runtime.run(archiveConnectedAccountOp(connectedAccountId, this.#ctx.config.hostLocal.ownerUserId));
|
|
256
263
|
return mapConnectedAccount(wire);
|
|
257
264
|
},
|
|
265
|
+
setDefault: async (options) => {
|
|
266
|
+
await requireConnectedAccountDefaults(this.#ctx);
|
|
267
|
+
const wire = await this.#runtime.run(setConnectedAccountDefaultOp(options.provider, {
|
|
268
|
+
ownerUserId: this.#ctx.config.hostLocal.ownerUserId,
|
|
269
|
+
connectedAccountId: options.accountId,
|
|
270
|
+
}));
|
|
271
|
+
return mapConnectedAccount(wire);
|
|
272
|
+
},
|
|
273
|
+
markInvalid: async (connectedAccountId, options) => {
|
|
274
|
+
if (options?.revision !== undefined) {
|
|
275
|
+
await requireConnectedAccountDefaults(this.#ctx);
|
|
276
|
+
}
|
|
277
|
+
const wire = await this.#runtime.run(markConnectedAccountInvalidOp(connectedAccountId, {
|
|
278
|
+
ownerUserId: this.#ctx.config.hostLocal.ownerUserId,
|
|
279
|
+
...(options?.revision === undefined ? {} : { revision: options.revision }),
|
|
280
|
+
}));
|
|
281
|
+
return { outcome: wire.outcome ?? "marked", account: mapConnectedAccount(wire) };
|
|
282
|
+
},
|
|
258
283
|
};
|
|
259
284
|
/**
|
|
260
285
|
* Where workspace SSH connects for this deployment — how an editor (VS Code Remote-SSH) or
|
|
@@ -74,11 +74,15 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
74
74
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
75
75
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
76
76
|
}>;
|
|
77
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
78
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
77
79
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
78
80
|
readonly createConnectedAccount: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"createConnectedAccount", "POST", "/v1/connected-accounts/", never, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
79
81
|
readonly ownerUserId: import("effect/Schema").String;
|
|
80
82
|
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
81
83
|
readonly name: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
84
|
+
readonly accountId: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
85
|
+
readonly makeDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
82
86
|
readonly secret: import("effect/Schema").String;
|
|
83
87
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
84
88
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
@@ -98,6 +102,8 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
98
102
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
99
103
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
100
104
|
}>;
|
|
105
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
106
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
101
107
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountBadRequestError | typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountConflictError | typeof import("@sealant/api-contracts").ConnectedAccountServiceUnavailableError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
102
108
|
readonly listConnectedAccounts: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"listConnectedAccounts", "GET", "/v1/connected-accounts/", never, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
103
109
|
readonly ownerUserId: import("effect/Schema").String;
|
|
@@ -120,12 +126,15 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
120
126
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
121
127
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
122
128
|
}>;
|
|
129
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
130
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
123
131
|
}>>;
|
|
124
132
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
125
133
|
readonly markConnectedAccountInvalid: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"markConnectedAccountInvalid", "POST", "/v1/connected-accounts/:connectedAccountId/mark-invalid", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
126
134
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
127
135
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
128
136
|
readonly ownerUserId: import("effect/Schema").String;
|
|
137
|
+
readonly revision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
129
138
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
130
139
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
131
140
|
readonly ownerUserId: import("effect/Schema").String;
|
|
@@ -144,7 +153,36 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
144
153
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
145
154
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
146
155
|
}>;
|
|
156
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
157
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
158
|
+
readonly outcome: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["marked", "superseded"]>>;
|
|
147
159
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
160
|
+
readonly setConnectedAccountDefault: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"setConnectedAccountDefault", "PUT", "/v1/connected-accounts/defaults/:provider", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
161
|
+
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
162
|
+
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
163
|
+
readonly ownerUserId: import("effect/Schema").String;
|
|
164
|
+
readonly connectedAccountId: import("effect/Schema").String;
|
|
165
|
+
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
166
|
+
readonly connectedAccountId: import("effect/Schema").String;
|
|
167
|
+
readonly ownerUserId: import("effect/Schema").String;
|
|
168
|
+
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
169
|
+
readonly name: import("effect/Schema").String;
|
|
170
|
+
readonly kind: import("effect/Schema").String;
|
|
171
|
+
readonly status: import("effect/Schema").Literals<readonly ["active", "invalid", "archived"]>;
|
|
172
|
+
readonly metadata: import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>;
|
|
173
|
+
readonly connectedAt: import("effect/Schema").String;
|
|
174
|
+
readonly updatedAt: import("effect/Schema").String;
|
|
175
|
+
readonly lastUsedAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
176
|
+
readonly lastSyncedAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
177
|
+
readonly credential: import("effect/Schema").Struct<{
|
|
178
|
+
readonly accessExpiresAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
179
|
+
readonly refreshExpiresAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
180
|
+
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
181
|
+
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
182
|
+
}>;
|
|
183
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
184
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
185
|
+
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountConflictError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
148
186
|
};
|
|
149
187
|
readonly github: {
|
|
150
188
|
readonly handleWebhook: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"handleWebhook", "POST", "/v1/github/webhooks", never, never, import("effect/Schema").toCodecJson<import("effect/Schema").String>, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
@@ -341,6 +379,8 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
341
379
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
342
380
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
343
381
|
}>;
|
|
382
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
383
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
344
384
|
}>;
|
|
345
385
|
}>>;
|
|
346
386
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ProfileNotFoundError | typeof import("@sealant/api-contracts").ProfileInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
@@ -388,6 +428,8 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
388
428
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
389
429
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
390
430
|
}>;
|
|
431
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
432
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
391
433
|
}>;
|
|
392
434
|
}>>;
|
|
393
435
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ProfileBadRequestError | typeof import("@sealant/api-contracts").ProfileNotFoundError | typeof import("@sealant/api-contracts").ProfileConflictError | typeof import("@sealant/api-contracts").ProfileInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
@@ -942,6 +984,7 @@ declare const buildControlPlaneClient: (config: SealantInternalConfig) => Effect
|
|
|
942
984
|
readonly workspaceSshUser: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
943
985
|
readonly personBinding: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
944
986
|
readonly sshKeyRemovalEndsConnections: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
987
|
+
readonly connectedAccountDefaults: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
945
988
|
}>>;
|
|
946
989
|
}>>, never, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
947
990
|
readonly getSetupState: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"getSetupState", "GET", "/v1/system/setup-state", never, never, never, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
@@ -1849,11 +1892,15 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
1849
1892
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1850
1893
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
1851
1894
|
}>;
|
|
1895
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
1896
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
1852
1897
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
1853
1898
|
readonly createConnectedAccount: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"createConnectedAccount", "POST", "/v1/connected-accounts/", never, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1854
1899
|
readonly ownerUserId: import("effect/Schema").String;
|
|
1855
1900
|
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
1856
1901
|
readonly name: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
1902
|
+
readonly accountId: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
1903
|
+
readonly makeDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
1857
1904
|
readonly secret: import("effect/Schema").String;
|
|
1858
1905
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1859
1906
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
@@ -1873,6 +1920,8 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
1873
1920
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1874
1921
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
1875
1922
|
}>;
|
|
1923
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
1924
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
1876
1925
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountBadRequestError | typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountConflictError | typeof import("@sealant/api-contracts").ConnectedAccountServiceUnavailableError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
1877
1926
|
readonly listConnectedAccounts: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"listConnectedAccounts", "GET", "/v1/connected-accounts/", never, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
1878
1927
|
readonly ownerUserId: import("effect/Schema").String;
|
|
@@ -1895,12 +1944,15 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
1895
1944
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1896
1945
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
1897
1946
|
}>;
|
|
1947
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
1948
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
1898
1949
|
}>>;
|
|
1899
1950
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
1900
1951
|
readonly markConnectedAccountInvalid: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"markConnectedAccountInvalid", "POST", "/v1/connected-accounts/:connectedAccountId/mark-invalid", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
1901
1952
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
1902
1953
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1903
1954
|
readonly ownerUserId: import("effect/Schema").String;
|
|
1955
|
+
readonly revision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
1904
1956
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1905
1957
|
readonly connectedAccountId: import("effect/Schema").String;
|
|
1906
1958
|
readonly ownerUserId: import("effect/Schema").String;
|
|
@@ -1919,7 +1971,36 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
1919
1971
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1920
1972
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
1921
1973
|
}>;
|
|
1974
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
1975
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
1976
|
+
readonly outcome: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["marked", "superseded"]>>;
|
|
1922
1977
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
1978
|
+
readonly setConnectedAccountDefault: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"setConnectedAccountDefault", "PUT", "/v1/connected-accounts/defaults/:provider", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
1979
|
+
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
1980
|
+
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1981
|
+
readonly ownerUserId: import("effect/Schema").String;
|
|
1982
|
+
readonly connectedAccountId: import("effect/Schema").String;
|
|
1983
|
+
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
1984
|
+
readonly connectedAccountId: import("effect/Schema").String;
|
|
1985
|
+
readonly ownerUserId: import("effect/Schema").String;
|
|
1986
|
+
readonly provider: import("effect/Schema").Literals<readonly ["claude", "codex", "github"]>;
|
|
1987
|
+
readonly name: import("effect/Schema").String;
|
|
1988
|
+
readonly kind: import("effect/Schema").String;
|
|
1989
|
+
readonly status: import("effect/Schema").Literals<readonly ["active", "invalid", "archived"]>;
|
|
1990
|
+
readonly metadata: import("effect/Schema").$Record<import("effect/Schema").String, import("effect/Schema").Unknown>;
|
|
1991
|
+
readonly connectedAt: import("effect/Schema").String;
|
|
1992
|
+
readonly updatedAt: import("effect/Schema").String;
|
|
1993
|
+
readonly lastUsedAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1994
|
+
readonly lastSyncedAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1995
|
+
readonly credential: import("effect/Schema").Struct<{
|
|
1996
|
+
readonly accessExpiresAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1997
|
+
readonly refreshExpiresAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1998
|
+
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
1999
|
+
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
2000
|
+
}>;
|
|
2001
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2002
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
2003
|
+
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ConnectedAccountNotFoundError | typeof import("@sealant/api-contracts").ConnectedAccountConflictError | typeof import("@sealant/api-contracts").ConnectedAccountInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
1923
2004
|
};
|
|
1924
2005
|
readonly github: {
|
|
1925
2006
|
readonly handleWebhook: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"handleWebhook", "POST", "/v1/github/webhooks", never, never, import("effect/Schema").toCodecJson<import("effect/Schema").String>, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
@@ -2116,6 +2197,8 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
2116
2197
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
2117
2198
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
2118
2199
|
}>;
|
|
2200
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2201
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
2119
2202
|
}>;
|
|
2120
2203
|
}>>;
|
|
2121
2204
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ProfileNotFoundError | typeof import("@sealant/api-contracts").ProfileInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
@@ -2163,6 +2246,8 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
2163
2246
|
readonly lastRefreshAt: import("effect/Schema").NullOr<import("effect/Schema").String>;
|
|
2164
2247
|
readonly lastRefreshOutcome: import("effect/Schema").NullOr<import("effect/Schema").Literals<readonly ["refreshed", "fresh", "failed"]>>;
|
|
2165
2248
|
}>;
|
|
2249
|
+
readonly isDefault: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2250
|
+
readonly credentialRevision: import("effect/Schema").optional<import("effect/Schema").Int>;
|
|
2166
2251
|
}>;
|
|
2167
2252
|
}>>;
|
|
2168
2253
|
}>>, import("effect/Schema").toCodecJson<typeof import("@sealant/api-contracts").ProfileBadRequestError | typeof import("@sealant/api-contracts").ProfileNotFoundError | typeof import("@sealant/api-contracts").ProfileConflictError | typeof import("@sealant/api-contracts").ProfileInternalServerError>, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
@@ -2717,6 +2802,7 @@ declare const SealantApiClient_base: Context.ServiceClass<SealantApiClient, "@se
|
|
|
2717
2802
|
readonly workspaceSshUser: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2718
2803
|
readonly personBinding: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2719
2804
|
readonly sshKeyRemovalEndsConnections: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2805
|
+
readonly connectedAccountDefaults: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
2720
2806
|
}>>;
|
|
2721
2807
|
}>>, never, import("@sealant/api-contracts").RequestRefusal, never>, never, never>;
|
|
2722
2808
|
readonly getSetupState: HttpApiClient.Client.Method<import("effect/http-api/HttpApiEndpoint").HttpApiEndpoint<"getSetupState", "GET", "/v1/system/setup-state", never, never, never, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
@@ -1109,12 +1109,16 @@ export declare const listConnectedAccountsOp: (ownerUserId: string) => Effect.Ef
|
|
|
1109
1109
|
readonly lastRefreshAt: string | null;
|
|
1110
1110
|
readonly lastRefreshOutcome: "failed" | "fresh" | "refreshed" | null;
|
|
1111
1111
|
};
|
|
1112
|
+
readonly isDefault?: boolean | undefined;
|
|
1113
|
+
readonly credentialRevision?: number | undefined;
|
|
1112
1114
|
}[];
|
|
1113
1115
|
}, import("@sealant/api-contracts").ConnectedAccountInternalServerError | import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1114
1116
|
export declare const createConnectedAccountOp: (payload: {
|
|
1115
1117
|
readonly ownerUserId: string;
|
|
1116
1118
|
readonly provider: "claude" | "codex" | "github";
|
|
1117
1119
|
readonly name?: string | undefined;
|
|
1120
|
+
readonly accountId?: string | undefined;
|
|
1121
|
+
readonly makeDefault?: boolean | undefined;
|
|
1118
1122
|
readonly secret: string;
|
|
1119
1123
|
}) => Effect.Effect<{
|
|
1120
1124
|
readonly connectedAccountId: string;
|
|
@@ -1136,6 +1140,8 @@ export declare const createConnectedAccountOp: (payload: {
|
|
|
1136
1140
|
readonly lastRefreshAt: string | null;
|
|
1137
1141
|
readonly lastRefreshOutcome: "failed" | "fresh" | "refreshed" | null;
|
|
1138
1142
|
};
|
|
1143
|
+
readonly isDefault?: boolean | undefined;
|
|
1144
|
+
readonly credentialRevision?: number | undefined;
|
|
1139
1145
|
}, import("@sealant/api-contracts").ConnectedAccountBadRequestError | import("@sealant/api-contracts").ConnectedAccountConflictError | import("@sealant/api-contracts").ConnectedAccountInternalServerError | import("@sealant/api-contracts").ConnectedAccountNotFoundError | import("@sealant/api-contracts").ConnectedAccountServiceUnavailableError | import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1140
1146
|
export declare const archiveConnectedAccountOp: (connectedAccountId: string, ownerUserId: string) => Effect.Effect<{
|
|
1141
1147
|
readonly connectedAccountId: string;
|
|
@@ -1157,6 +1163,61 @@ export declare const archiveConnectedAccountOp: (connectedAccountId: string, own
|
|
|
1157
1163
|
readonly lastRefreshAt: string | null;
|
|
1158
1164
|
readonly lastRefreshOutcome: "failed" | "fresh" | "refreshed" | null;
|
|
1159
1165
|
};
|
|
1166
|
+
readonly isDefault?: boolean | undefined;
|
|
1167
|
+
readonly credentialRevision?: number | undefined;
|
|
1168
|
+
}, import("@sealant/api-contracts").ConnectedAccountInternalServerError | import("@sealant/api-contracts").ConnectedAccountNotFoundError | import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1169
|
+
export declare const setConnectedAccountDefaultOp: (provider: "claude" | "codex" | "github", payload: {
|
|
1170
|
+
readonly ownerUserId: string;
|
|
1171
|
+
readonly connectedAccountId: string;
|
|
1172
|
+
}) => Effect.Effect<{
|
|
1173
|
+
readonly connectedAccountId: string;
|
|
1174
|
+
readonly ownerUserId: string;
|
|
1175
|
+
readonly provider: "claude" | "codex" | "github";
|
|
1176
|
+
readonly name: string;
|
|
1177
|
+
readonly kind: string;
|
|
1178
|
+
readonly status: "active" | "archived" | "invalid";
|
|
1179
|
+
readonly metadata: {
|
|
1180
|
+
readonly [x: string]: unknown;
|
|
1181
|
+
};
|
|
1182
|
+
readonly connectedAt: string;
|
|
1183
|
+
readonly updatedAt: string;
|
|
1184
|
+
readonly lastUsedAt: string | null;
|
|
1185
|
+
readonly lastSyncedAt: string | null;
|
|
1186
|
+
readonly credential: {
|
|
1187
|
+
readonly accessExpiresAt: string | null;
|
|
1188
|
+
readonly refreshExpiresAt: string | null;
|
|
1189
|
+
readonly lastRefreshAt: string | null;
|
|
1190
|
+
readonly lastRefreshOutcome: "failed" | "fresh" | "refreshed" | null;
|
|
1191
|
+
};
|
|
1192
|
+
readonly isDefault?: boolean | undefined;
|
|
1193
|
+
readonly credentialRevision?: number | undefined;
|
|
1194
|
+
}, import("@sealant/api-contracts").ConnectedAccountConflictError | import("@sealant/api-contracts").ConnectedAccountInternalServerError | import("@sealant/api-contracts").ConnectedAccountNotFoundError | import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1195
|
+
export declare const markConnectedAccountInvalidOp: (connectedAccountId: string, payload: {
|
|
1196
|
+
readonly ownerUserId: string;
|
|
1197
|
+
readonly revision?: number | undefined;
|
|
1198
|
+
}) => Effect.Effect<{
|
|
1199
|
+
readonly connectedAccountId: string;
|
|
1200
|
+
readonly ownerUserId: string;
|
|
1201
|
+
readonly provider: "claude" | "codex" | "github";
|
|
1202
|
+
readonly name: string;
|
|
1203
|
+
readonly kind: string;
|
|
1204
|
+
readonly status: "active" | "archived" | "invalid";
|
|
1205
|
+
readonly metadata: {
|
|
1206
|
+
readonly [x: string]: unknown;
|
|
1207
|
+
};
|
|
1208
|
+
readonly connectedAt: string;
|
|
1209
|
+
readonly updatedAt: string;
|
|
1210
|
+
readonly lastUsedAt: string | null;
|
|
1211
|
+
readonly lastSyncedAt: string | null;
|
|
1212
|
+
readonly credential: {
|
|
1213
|
+
readonly accessExpiresAt: string | null;
|
|
1214
|
+
readonly refreshExpiresAt: string | null;
|
|
1215
|
+
readonly lastRefreshAt: string | null;
|
|
1216
|
+
readonly lastRefreshOutcome: "failed" | "fresh" | "refreshed" | null;
|
|
1217
|
+
};
|
|
1218
|
+
readonly isDefault?: boolean | undefined;
|
|
1219
|
+
readonly credentialRevision?: number | undefined;
|
|
1220
|
+
readonly outcome?: "marked" | "superseded" | undefined;
|
|
1160
1221
|
}, import("@sealant/api-contracts").ConnectedAccountInternalServerError | import("@sealant/api-contracts").ConnectedAccountNotFoundError | import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1161
1222
|
export declare const inferenceRespondOp: (payload: {
|
|
1162
1223
|
readonly ownerUserId: string;
|
|
@@ -1218,6 +1279,7 @@ export declare const getIndexOp: () => Effect.Effect<{
|
|
|
1218
1279
|
readonly workspaceSshUser?: boolean | undefined;
|
|
1219
1280
|
readonly personBinding?: boolean | undefined;
|
|
1220
1281
|
readonly sshKeyRemovalEndsConnections?: boolean | undefined;
|
|
1282
|
+
readonly connectedAccountDefaults?: boolean | undefined;
|
|
1221
1283
|
} | undefined;
|
|
1222
1284
|
}, import("effect/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").RequestRefusedError | import("effect/Schema").SchemaError, SealantApiClient>;
|
|
1223
1285
|
export declare const getSetupStateOp: () => Effect.Effect<{
|
|
@@ -70,6 +70,11 @@ export const archiveConnectedAccountOp = (connectedAccountId, ownerUserId) => Ef
|
|
|
70
70
|
params: { connectedAccountId },
|
|
71
71
|
query: { ownerUserId },
|
|
72
72
|
}));
|
|
73
|
+
export const setConnectedAccountDefaultOp = (provider, payload) => Effect.flatMap(SealantApiClient, (client) => client.connectedAccounts.setConnectedAccountDefault({ params: { provider }, payload }));
|
|
74
|
+
export const markConnectedAccountInvalidOp = (connectedAccountId, payload) => Effect.flatMap(SealantApiClient, (client) => client.connectedAccounts.markConnectedAccountInvalid({
|
|
75
|
+
params: { connectedAccountId },
|
|
76
|
+
payload,
|
|
77
|
+
}));
|
|
73
78
|
// ---- inference ----
|
|
74
79
|
export const inferenceRespondOp = (payload) => Effect.flatMap(SealantApiClient, (client) => client.inference.respond({ payload }));
|
|
75
80
|
// ---- system ----
|
package/dist/errors.d.ts
CHANGED
|
@@ -37,11 +37,14 @@ export declare class SealantApiError extends SealantError {
|
|
|
37
37
|
* reason is about (`claude`, `codex`, `github`).
|
|
38
38
|
*/
|
|
39
39
|
readonly provider?: string;
|
|
40
|
+
/** The accounts a `connected-account-ambiguous` connect could have meant. */
|
|
41
|
+
readonly candidateAccountIds?: readonly string[];
|
|
40
42
|
constructor(message: string, options?: {
|
|
41
43
|
readonly code?: string;
|
|
42
44
|
readonly status?: number;
|
|
43
45
|
readonly reason?: string;
|
|
44
46
|
readonly provider?: string;
|
|
47
|
+
readonly candidateAccountIds?: readonly string[];
|
|
45
48
|
readonly cause?: unknown;
|
|
46
49
|
});
|
|
47
50
|
}
|
package/dist/errors.js
CHANGED
|
@@ -39,6 +39,8 @@ export class SealantApiError extends SealantError {
|
|
|
39
39
|
* reason is about (`claude`, `codex`, `github`).
|
|
40
40
|
*/
|
|
41
41
|
provider;
|
|
42
|
+
/** The accounts a `connected-account-ambiguous` connect could have meant. */
|
|
43
|
+
candidateAccountIds;
|
|
42
44
|
constructor(message, options) {
|
|
43
45
|
super(message, {
|
|
44
46
|
code: options?.code ?? "api_error",
|
|
@@ -53,6 +55,9 @@ export class SealantApiError extends SealantError {
|
|
|
53
55
|
if (options?.provider !== undefined) {
|
|
54
56
|
this.provider = options.provider;
|
|
55
57
|
}
|
|
58
|
+
if (options?.candidateAccountIds !== undefined) {
|
|
59
|
+
this.candidateAccountIds = options.candidateAccountIds;
|
|
60
|
+
}
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
/** The requested operation is part of the public surface but not yet implemented in this slice. */
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* calls it and folds the result into the request it builds.
|
|
5
5
|
*
|
|
6
6
|
* SECURITY: this only ever moves account **references** (booleans/names/ids) — never token values or
|
|
7
|
-
* other secret material.
|
|
8
|
-
* through as the named account; `profile` becomes `profileId`.
|
|
7
|
+
* other secret material.
|
|
9
8
|
*/
|
|
10
9
|
import type { WorkspaceCredentialsOptions } from "../types.js";
|
|
11
10
|
/** The control-plane's workspace-create payload shape for connected-account credentials. */
|
|
@@ -15,7 +14,6 @@ export interface WorkspaceCredentialsPayload {
|
|
|
15
14
|
readonly codex?: string;
|
|
16
15
|
readonly github?: string;
|
|
17
16
|
}
|
|
18
|
-
/** `true` → the account named `default`; a string passes through; `false`/absent → none. */
|
|
19
17
|
export declare const mapAccountRef: (value: string | boolean | undefined) => string | undefined;
|
|
20
18
|
/**
|
|
21
19
|
* Maps `WorkspaceCredentialsOptions` to the API payload shape, or `undefined` when no credentials were
|
|
@@ -16,6 +16,7 @@ export declare const toFeatures: (index: {
|
|
|
16
16
|
readonly workspaceSshUser?: boolean | undefined;
|
|
17
17
|
readonly personBinding?: boolean | undefined;
|
|
18
18
|
readonly sshKeyRemovalEndsConnections?: boolean | undefined;
|
|
19
|
+
readonly connectedAccountDefaults?: boolean | undefined;
|
|
19
20
|
} | undefined;
|
|
20
21
|
}) => SealantFeatures;
|
|
21
22
|
/**
|
|
@@ -23,3 +24,4 @@ export declare const toFeatures: (index: {
|
|
|
23
24
|
* index could not be read; the failure is kept briefly, then the index is asked again.
|
|
24
25
|
*/
|
|
25
26
|
export declare const readFeatures: (ctx: SdkContext) => Promise<SealantFeatures>;
|
|
27
|
+
export declare const requireConnectedAccountDefaults: (ctx: SdkContext) => Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getIndexOp } from "../effect/operations.js";
|
|
2
|
+
import { SealantError } from "../errors.js";
|
|
2
3
|
import { elapsed } from "./clock.js";
|
|
3
4
|
/** How long an answer is kept: an upgraded control plane is noticed within this. */
|
|
4
5
|
const ANSWER_TTL_MS = 5 * 60_000;
|
|
@@ -19,6 +20,7 @@ export const toFeatures = (index) => {
|
|
|
19
20
|
workspaceSshUser: features?.workspaceSshUser === true,
|
|
20
21
|
personBinding: features?.personBinding === true,
|
|
21
22
|
sshKeyRemovalEndsConnections: features?.sshKeyRemovalEndsConnections === true,
|
|
23
|
+
connectedAccountDefaults: features?.connectedAccountDefaults === true,
|
|
22
24
|
};
|
|
23
25
|
};
|
|
24
26
|
/**
|
|
@@ -41,3 +43,9 @@ export const readFeatures = (ctx) => {
|
|
|
41
43
|
answers.set(ctx.runtime, fresh);
|
|
42
44
|
return fresh.features;
|
|
43
45
|
};
|
|
46
|
+
export const requireConnectedAccountDefaults = async (ctx) => {
|
|
47
|
+
const supported = await readFeatures(ctx).then((features) => features.connectedAccountDefaults, () => false);
|
|
48
|
+
if (!supported) {
|
|
49
|
+
throw new SealantError("This control plane cannot choose a default connected account or target one by id (it does not report the feature, or could not be asked); nothing was sent.", { code: "connected-account-defaults-unsupported" });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const mapAccountRef = (value) => {
|
|
3
|
-
if (value === undefined || value === false) {
|
|
4
|
-
return undefined;
|
|
5
|
-
}
|
|
6
|
-
return value === true ? DEFAULT_ACCOUNT_NAME : value;
|
|
7
|
-
};
|
|
1
|
+
import { mapAccountRef } from "./credentials.js";
|
|
8
2
|
export const buildInferenceRespondRequest = (options, ownerUserId) => {
|
|
9
3
|
if ("sessionId" in options) {
|
|
10
4
|
return {
|
|
@@ -37,11 +37,16 @@ export const toSealantError = (cause) => {
|
|
|
37
37
|
const status = extractStatus(record);
|
|
38
38
|
const reason = nonEmptyString(record?.["code"]);
|
|
39
39
|
const provider = nonEmptyString(record?.["provider"]);
|
|
40
|
+
const candidates = record?.["candidateAccountIds"];
|
|
41
|
+
const candidateAccountIds = Array.isArray(candidates)
|
|
42
|
+
? candidates.filter((id) => typeof id === "string")
|
|
43
|
+
: undefined;
|
|
40
44
|
return new SealantApiError(message, {
|
|
41
45
|
code: tag,
|
|
42
46
|
...(status === undefined ? {} : { status }),
|
|
43
47
|
...(reason === undefined ? {} : { reason }),
|
|
44
48
|
...(provider === undefined ? {} : { provider }),
|
|
49
|
+
...(candidateAccountIds === undefined ? {} : { candidateAccountIds }),
|
|
45
50
|
cause,
|
|
46
51
|
});
|
|
47
52
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -151,8 +151,8 @@ export type WorkspaceOs = "fedora" | "arch" | "nix" | "ubuntu";
|
|
|
151
151
|
* harness inside the workspace authenticates as the caller's own Claude / Codex / GitHub identity
|
|
152
152
|
* instead of running unauthenticated.
|
|
153
153
|
*
|
|
154
|
-
* For each provider: `true` means "my default account" (the one
|
|
155
|
-
* names a specific connected account. `profile` names a profile slug/id whose bundled per-provider
|
|
154
|
+
* For each provider: `true` means "my default account" (the one I chose; see
|
|
155
|
+
* {@link ConnectedAccountsNamespace.setDefault}), and a `string` names a specific connected account. `profile` names a profile slug/id whose bundled per-provider
|
|
156
156
|
* bindings apply first; any explicit `claude`/`codex`/`github` field wins over the profile's binding
|
|
157
157
|
* for that provider.
|
|
158
158
|
*
|
|
@@ -1395,6 +1395,12 @@ export interface SealantFeatures {
|
|
|
1395
1395
|
* a minute; from an older control plane they stay open until the workspace stops.
|
|
1396
1396
|
*/
|
|
1397
1397
|
readonly sshKeyRemovalEndsConnections: boolean;
|
|
1398
|
+
/**
|
|
1399
|
+
* A default account per provider is a choice: `connectedAccounts.setDefault()`, `accountId` and
|
|
1400
|
+
* `makeDefault` on `connect()`. On an older control plane the default is the account named
|
|
1401
|
+
* `default`.
|
|
1402
|
+
*/
|
|
1403
|
+
readonly connectedAccountDefaults: boolean;
|
|
1398
1404
|
}
|
|
1399
1405
|
/** A published workspace image. */
|
|
1400
1406
|
export interface WorkspaceImage {
|
|
@@ -2106,26 +2112,82 @@ export interface ConnectedAccount {
|
|
|
2106
2112
|
readonly lastUsedAt: string | null;
|
|
2107
2113
|
readonly lastSyncedAt: string | null;
|
|
2108
2114
|
readonly credential: ConnectedAccountCredential;
|
|
2115
|
+
/**
|
|
2116
|
+
* Whether this is the owner's default for its provider, the one `true` selects. From a control
|
|
2117
|
+
* plane without `connectedAccountDefaults`: whether it is named `default`.
|
|
2118
|
+
*/
|
|
2119
|
+
readonly isDefault: boolean;
|
|
2120
|
+
/**
|
|
2121
|
+
* Which credential the account holds; it moves on whenever different bytes are stored. Absent
|
|
2122
|
+
* from a control plane without `connectedAccountDefaults`.
|
|
2123
|
+
*/
|
|
2124
|
+
readonly credentialRevision?: number;
|
|
2109
2125
|
}
|
|
2110
|
-
|
|
2126
|
+
interface ConnectConnectedAccountBase {
|
|
2111
2127
|
readonly provider: ConnectedAccountProvider;
|
|
2112
2128
|
/**
|
|
2113
2129
|
* Provider-shaped plaintext, passed through and sealed server-side: a Claude setup token or
|
|
2114
2130
|
* verbatim `.credentials.json`, verbatim Codex `auth.json`, or a GitHub token. Never logged.
|
|
2115
2131
|
*/
|
|
2116
2132
|
readonly secret: string;
|
|
2117
|
-
/**
|
|
2133
|
+
/**
|
|
2134
|
+
* Make the connected account the owner's default for the provider. A first account is the default
|
|
2135
|
+
* without it. Needs `features().connectedAccountDefaults`.
|
|
2136
|
+
*/
|
|
2137
|
+
readonly makeDefault?: boolean;
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* Which account a connect writes. A person's first account for a provider is named `default`
|
|
2141
|
+
* whatever `name` says. After that, `name` replaces the account of that name or makes a new one,
|
|
2142
|
+
* and `name: "default"` replaces the chosen default. With neither `name` nor `accountId` (or
|
|
2143
|
+
* `default` while none is chosen), an only account is replaced, and with several the call fails
|
|
2144
|
+
* with `reason` `connected-account-ambiguous` and the candidates in `candidateAccountIds`.
|
|
2145
|
+
*/
|
|
2146
|
+
export type ConnectConnectedAccountOptions = ConnectConnectedAccountBase & ({
|
|
2118
2147
|
readonly name?: string;
|
|
2148
|
+
readonly accountId?: never;
|
|
2149
|
+
} | {
|
|
2150
|
+
/** Replace this account. Needs `features().connectedAccountDefaults`. */
|
|
2151
|
+
readonly accountId: string;
|
|
2152
|
+
readonly name?: never;
|
|
2153
|
+
});
|
|
2154
|
+
export interface SetDefaultConnectedAccountOptions {
|
|
2155
|
+
readonly provider: ConnectedAccountProvider;
|
|
2156
|
+
/** One of the owner's active accounts of `provider`. */
|
|
2157
|
+
readonly accountId: string;
|
|
2158
|
+
}
|
|
2159
|
+
export interface MarkConnectedAccountInvalidOptions {
|
|
2160
|
+
/**
|
|
2161
|
+
* The `credentialRevision` the refusal was seen on. Once the account holds a newer credential,
|
|
2162
|
+
* nothing is marked and the outcome is `superseded`. Needs `features().connectedAccountDefaults`.
|
|
2163
|
+
*/
|
|
2164
|
+
readonly revision?: number;
|
|
2165
|
+
}
|
|
2166
|
+
export interface MarkConnectedAccountInvalidResult {
|
|
2167
|
+
/** `marked`: the account is now invalid. `superseded`: a newer credential, left as it was. */
|
|
2168
|
+
readonly outcome: "marked" | "superseded";
|
|
2169
|
+
readonly account: ConnectedAccount;
|
|
2119
2170
|
}
|
|
2120
2171
|
/**
|
|
2121
|
-
* The owner's connected provider accounts.
|
|
2122
|
-
*
|
|
2172
|
+
* The owner's connected provider accounts. Reconnecting swaps the sealed credential in place.
|
|
2173
|
+
* Secrets flow one way — in; no call returns them.
|
|
2123
2174
|
*/
|
|
2124
2175
|
export interface ConnectedAccountsNamespace {
|
|
2125
2176
|
list(): Promise<readonly ConnectedAccount[]>;
|
|
2126
2177
|
connect(options: ConnectConnectedAccountOptions): Promise<ConnectedAccount>;
|
|
2127
|
-
/**
|
|
2178
|
+
/**
|
|
2179
|
+
* Soft-archives the account; uniform not-found for "does not exist" and "not yours". Archiving
|
|
2180
|
+
* the default leaves the owner without one for that provider: no other account is chosen.
|
|
2181
|
+
*/
|
|
2128
2182
|
disconnect(connectedAccountId: string): Promise<ConnectedAccount>;
|
|
2183
|
+
/**
|
|
2184
|
+
* Make the account the owner's default for its provider, the one `true` selects. An invalid
|
|
2185
|
+
* account is refused (`reason` `connected-account-invalid`). Choosing the default again changes
|
|
2186
|
+
* nothing. Needs `features().connectedAccountDefaults`.
|
|
2187
|
+
*/
|
|
2188
|
+
setDefault(options: SetDefaultConnectedAccountOptions): Promise<ConnectedAccount>;
|
|
2189
|
+
/** Report that the provider refused the account's credential, so surfaces ask to reconnect it. */
|
|
2190
|
+
markInvalid(connectedAccountId: string, options?: MarkConnectedAccountInvalidOptions): Promise<MarkConnectedAccountInvalidResult>;
|
|
2129
2191
|
}
|
|
2130
2192
|
/** Connect coordinates for the deployment's workspace SSH gateway. */
|
|
2131
2193
|
export interface WorkspaceSshInfo {
|
|
@@ -2169,3 +2231,4 @@ export interface SshKeysNamespace {
|
|
|
2169
2231
|
/** Archives the key; the gateway stops resolving it. */
|
|
2170
2232
|
remove(sshKeyId: string): Promise<SshKey>;
|
|
2171
2233
|
}
|
|
2234
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealant/sdk-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0-next.755",
|
|
4
4
|
"description": "The fluent public SDK for Sealant — create a workspace, run a harness, replay the record.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@sealant/api-contracts": "npm:@sealant/api-contracts-next@0.
|
|
29
|
+
"@sealant/api-contracts": "npm:@sealant/api-contracts-next@0.40.0-next.755"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"effect": "^4.0.5"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "f51aa3c26804adc254ee7d8706397737bf59a2b9",
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
}
|