@treeseed/sdk 0.13.0-rc.67 → 0.13.0-rc.69
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/.treeseed-build-complete.json +1 -1
- package/dist/capacity-provider/contracts/environment-profiles.d.ts +255 -0
- package/dist/capacity-provider/contracts/environment-profiles.js +71 -0
- package/dist/capacity-provider/contracts/index.d.ts +1 -0
- package/dist/capacity-provider/contracts/index.js +1 -0
- package/dist/development/schemas.d.ts +192 -192
- package/dist/operator-contracts/canonical-command-tree.js +4 -1
- package/dist/operator-contracts/catalog/provider-environment-commands.d.ts +4 -0
- package/dist/operator-contracts/catalog/provider-environment-commands.js +69 -0
- package/dist/operator-contracts/catalog/provider-environment-operations.d.ts +41 -0
- package/dist/operator-contracts/catalog/provider-environment-operations.js +61 -0
- package/dist/operator-contracts/control-plane-operations.d.ts +39 -0
- package/dist/operator-contracts/control-plane-operations.js +4 -0
- package/dist/platform/contracts.d.ts +53 -7
- package/dist/platform/contracts.js +17 -3
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +1 -0
- package/dist/platform/project-create.d.ts +49 -0
- package/dist/platform/project-create.js +75 -0
- package/package.json +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const PROVIDER_ENVIRONMENT_OPERATIONS: {
|
|
2
|
+
readonly registrationCode: {
|
|
3
|
+
readonly status: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
4
|
+
teamId: string;
|
|
5
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
6
|
+
readonly reveal: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
7
|
+
teamId: string;
|
|
8
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
9
|
+
readonly rotate: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
10
|
+
teamId: string;
|
|
11
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
12
|
+
};
|
|
13
|
+
readonly environmentProfiles: {
|
|
14
|
+
readonly list: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
15
|
+
teamId: string;
|
|
16
|
+
providerId: string;
|
|
17
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
18
|
+
readonly show: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
19
|
+
teamId: string;
|
|
20
|
+
providerId: string;
|
|
21
|
+
profileId: string;
|
|
22
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
23
|
+
readonly publish: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
24
|
+
profileId: string;
|
|
25
|
+
}, {}, Record<string, unknown>, Record<string, unknown>>;
|
|
26
|
+
};
|
|
27
|
+
readonly environmentGrants: {
|
|
28
|
+
readonly show: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
29
|
+
teamId: string;
|
|
30
|
+
assignmentId: string;
|
|
31
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
32
|
+
readonly put: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
33
|
+
teamId: string;
|
|
34
|
+
assignmentId: string;
|
|
35
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
36
|
+
readonly revoke: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
37
|
+
teamId: string;
|
|
38
|
+
assignmentId: string;
|
|
39
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineOperation } from "../operation-builder.js";
|
|
3
|
+
const empty = z.object({}).strict();
|
|
4
|
+
const none = z.undefined();
|
|
5
|
+
const record = z.record(z.unknown());
|
|
6
|
+
function teamOperation(operationId, method, path, pathShape, options = {}) {
|
|
7
|
+
const kind = method === "GET" ? "read" : "mutation";
|
|
8
|
+
const riskClass = options.risk ?? "ordinary";
|
|
9
|
+
return defineOperation({
|
|
10
|
+
operationId,
|
|
11
|
+
description: `${kind === "read" ? "Read" : "Apply"} ${operationId}.`,
|
|
12
|
+
rest: { method, path },
|
|
13
|
+
parameters: `treeseed.${operationId}.parameters/v1`,
|
|
14
|
+
capability: options.capability ?? (kind === "read" ? "providers.read" : "providers.write"),
|
|
15
|
+
authentication: "oauth",
|
|
16
|
+
oauthScopes: kind === "read" ? ["treeseed:read"] : ["treeseed:admin"],
|
|
17
|
+
kind,
|
|
18
|
+
riskClass,
|
|
19
|
+
confirmation: riskClass === "ordinary" ? "never" : "input_required",
|
|
20
|
+
surfaces: ["rest", "cli"],
|
|
21
|
+
cacheScope: kind === "read" ? "principal" : "none",
|
|
22
|
+
pagination: options.pagination ?? "none",
|
|
23
|
+
concurrencyRequired: options.concurrency ?? ["DELETE", "PUT"].includes(method),
|
|
24
|
+
redactedPaths: options.redactedPaths
|
|
25
|
+
}, { path: z.object(pathShape).strict(), query: kind === "read" ? record : empty, body: kind === "read" ? none : record, output: record });
|
|
26
|
+
}
|
|
27
|
+
const providerPublish = defineOperation({
|
|
28
|
+
operationId: "providers.environment.profiles.publish",
|
|
29
|
+
description: "Publish a value-free provider environment profile descriptor.",
|
|
30
|
+
rest: { method: "PUT", path: "/v1/provider/environment-profiles/{profileId}" },
|
|
31
|
+
parameters: "treeseed.providers.environment.profiles.publish.parameters/v1",
|
|
32
|
+
capability: "providers.execute",
|
|
33
|
+
authentication: "provider",
|
|
34
|
+
oauthScopes: [],
|
|
35
|
+
kind: "mutation",
|
|
36
|
+
riskClass: "ordinary",
|
|
37
|
+
confirmation: "never",
|
|
38
|
+
surfaces: ["rest"],
|
|
39
|
+
cacheScope: "none",
|
|
40
|
+
pagination: "none"
|
|
41
|
+
}, { path: z.object({ profileId: z.string().min(1) }).strict(), query: empty, body: record, output: record });
|
|
42
|
+
const PROVIDER_ENVIRONMENT_OPERATIONS = {
|
|
43
|
+
registrationCode: {
|
|
44
|
+
status: teamOperation("providers.registration.code.status", "GET", "/v1/teams/{teamId}/capacity-provider-registration-code", { teamId: z.string().min(1) }),
|
|
45
|
+
reveal: teamOperation("providers.registration.code.reveal", "POST", "/v1/teams/{teamId}/capacity-provider-registration-code/reveal", { teamId: z.string().min(1) }, { risk: "credential", redactedPaths: ["output.registrationCode"] }),
|
|
46
|
+
rotate: teamOperation("providers.registration.code.rotate", "POST", "/v1/teams/{teamId}/capacity-provider-registration-code/rotate", { teamId: z.string().min(1) }, { risk: "credential", redactedPaths: ["output.registrationCode"], concurrency: true })
|
|
47
|
+
},
|
|
48
|
+
environmentProfiles: {
|
|
49
|
+
list: teamOperation("providers.environment.profiles.list", "GET", "/v1/teams/{teamId}/capacity-providers/{providerId}/environment-profiles", { teamId: z.string().min(1), providerId: z.string().min(1) }, { pagination: "cursor" }),
|
|
50
|
+
show: teamOperation("providers.environment.profiles.show", "GET", "/v1/teams/{teamId}/capacity-providers/{providerId}/environment-profiles/{profileId}", { teamId: z.string().min(1), providerId: z.string().min(1), profileId: z.string().min(1) }),
|
|
51
|
+
publish: providerPublish
|
|
52
|
+
},
|
|
53
|
+
environmentGrants: {
|
|
54
|
+
show: teamOperation("providers.environment.grants.show", "GET", "/v1/teams/{teamId}/assignments/{assignmentId}/environment-grant", { teamId: z.string().min(1), assignmentId: z.string().min(1) }),
|
|
55
|
+
put: teamOperation("providers.environment.grants.put", "PUT", "/v1/teams/{teamId}/assignments/{assignmentId}/environment-grant", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { risk: "authority" }),
|
|
56
|
+
revoke: teamOperation("providers.environment.grants.revoke", "DELETE", "/v1/teams/{teamId}/assignments/{assignmentId}/environment-grant", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { risk: "destructive" })
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export {
|
|
60
|
+
PROVIDER_ENVIRONMENT_OPERATIONS
|
|
61
|
+
};
|
|
@@ -1955,6 +1955,17 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
1955
1955
|
readonly connect: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1956
1956
|
teamId: string;
|
|
1957
1957
|
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1958
|
+
readonly registrationCode: {
|
|
1959
|
+
readonly status: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1960
|
+
teamId: string;
|
|
1961
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1962
|
+
readonly reveal: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1963
|
+
teamId: string;
|
|
1964
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1965
|
+
readonly rotate: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1966
|
+
teamId: string;
|
|
1967
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1968
|
+
};
|
|
1958
1969
|
readonly disconnect: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1959
1970
|
teamId: string;
|
|
1960
1971
|
connectionId: string;
|
|
@@ -1990,6 +2001,34 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
1990
2001
|
connectionId: string;
|
|
1991
2002
|
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1992
2003
|
};
|
|
2004
|
+
readonly environmentProfiles: {
|
|
2005
|
+
readonly list: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2006
|
+
teamId: string;
|
|
2007
|
+
providerId: string;
|
|
2008
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
2009
|
+
readonly show: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2010
|
+
teamId: string;
|
|
2011
|
+
providerId: string;
|
|
2012
|
+
profileId: string;
|
|
2013
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
2014
|
+
readonly publish: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2015
|
+
profileId: string;
|
|
2016
|
+
}, {}, Record<string, unknown>, Record<string, unknown>>;
|
|
2017
|
+
};
|
|
2018
|
+
readonly environmentGrants: {
|
|
2019
|
+
readonly show: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2020
|
+
teamId: string;
|
|
2021
|
+
assignmentId: string;
|
|
2022
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
2023
|
+
readonly put: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2024
|
+
teamId: string;
|
|
2025
|
+
assignmentId: string;
|
|
2026
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
2027
|
+
readonly revoke: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
2028
|
+
teamId: string;
|
|
2029
|
+
assignmentId: string;
|
|
2030
|
+
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
2031
|
+
};
|
|
1993
2032
|
readonly register: import("./control-plane-operation.js").ControlPlaneOperationBinding<{}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1994
2033
|
readonly registration: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
1995
2034
|
requestId: string;
|
|
@@ -6,6 +6,7 @@ import { adminAccountOperations, adminTeamOperations } from "./catalog/admin-acc
|
|
|
6
6
|
import { TREEAI_CONTROL_PLANE_OPERATIONS } from "./catalog/treeai-operations.js";
|
|
7
7
|
import { capabilityOntologyOperations } from "./catalog/capability-ontology-operations.js";
|
|
8
8
|
import { knowledgeShareOperations } from "./catalog/knowledge-share-operations.js";
|
|
9
|
+
import { PROVIDER_ENVIRONMENT_OPERATIONS } from "./catalog/provider-environment-operations.js";
|
|
9
10
|
import { buildControlPlaneCatalog, flattenControlPlaneOperations } from "./catalog/control-plane-catalog.js";
|
|
10
11
|
const empty = z.object({}).strict();
|
|
11
12
|
const none = z.undefined();
|
|
@@ -465,6 +466,7 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
465
466
|
status: resource("providers.status", "GET", "/v1/teams/{teamId}/capacity-providers/{providerId}/status", { teamId: z.string().min(1), providerId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
466
467
|
diagnose: resource("providers.diagnose", "GET", "/v1/teams/{teamId}/capacity-providers/{providerId}/diagnosis", { teamId: z.string().min(1), providerId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
467
468
|
connect: resource("providers.connect", "POST", "/v1/teams/{teamId}/capacity-provider-connections", { teamId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "credential", redactedPaths: ["body.enrollmentToken"] }),
|
|
469
|
+
registrationCode: PROVIDER_ENVIRONMENT_OPERATIONS.registrationCode,
|
|
468
470
|
disconnect: resource("providers.disconnect", "POST", "/v1/teams/{teamId}/capacity-provider-connections/{connectionId}/disconnect", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "destructive" }),
|
|
469
471
|
requests: {
|
|
470
472
|
list: resource("providers.requests.list", "GET", "/v1/teams/{teamId}/capacity-provider-requests", { teamId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli"], pagination: "cursor" }),
|
|
@@ -477,6 +479,8 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
477
479
|
rotate: resource("providers.credentials.rotate", "POST", "/v1/teams/{teamId}/capacity-provider-connections/{connectionId}/credentials/rotate", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "credential" }),
|
|
478
480
|
revoke: resource("providers.credentials.revoke", "POST", "/v1/teams/{teamId}/capacity-provider-connections/{connectionId}/credentials/revoke", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "irreversible" })
|
|
479
481
|
},
|
|
482
|
+
environmentProfiles: PROVIDER_ENVIRONMENT_OPERATIONS.environmentProfiles,
|
|
483
|
+
environmentGrants: PROVIDER_ENVIRONMENT_OPERATIONS.environmentGrants,
|
|
480
484
|
register: noPathProvider("providers.register", "POST", "/v1/provider-registrations", { authentication: "signed_request", redactedPaths: ["body.registrationKey"] }),
|
|
481
485
|
registration: providerPath("providers.registration.show", "GET", "/v1/provider-registrations/{requestId}", { requestId: z.string().min(1) }, { authentication: "signed_request", read: true }),
|
|
482
486
|
exchangeCredential: providerPath("providers.registration.credential", "POST", "/v1/provider-registrations/{requestId}/credential", { requestId: z.string().min(1) }, { authentication: "signed_request", redactedPaths: ["body.proof"] }),
|
|
@@ -149,6 +149,20 @@ export declare const projectCreatePlanSchema: z.ZodObject<{
|
|
|
149
149
|
visibility: "public" | "private";
|
|
150
150
|
}>;
|
|
151
151
|
steps: z.ZodArray<z.ZodEnum<["project", "repository", "template", "library", "inventory"]>, "many">;
|
|
152
|
+
actions: z.ZodArray<z.ZodObject<{
|
|
153
|
+
step: z.ZodEnum<["project", "repository", "template", "library", "inventory"]>;
|
|
154
|
+
action: z.ZodEnum<["create", "adopt", "apply", "bind", "publish", "noop", "blocked"]>;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
157
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
158
|
+
}, {
|
|
159
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
160
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
161
|
+
}>, "many">;
|
|
162
|
+
observationDigest: z.ZodString;
|
|
163
|
+
planDigest: z.ZodString;
|
|
164
|
+
ok: z.ZodBoolean;
|
|
165
|
+
blockers: z.ZodArray<z.ZodString, "many">;
|
|
152
166
|
}, "strict", z.ZodTypeAny, {
|
|
153
167
|
slug: string;
|
|
154
168
|
schemaVersion: "treeseed.platform-project-create-plan/v1";
|
|
@@ -157,6 +171,9 @@ export declare const projectCreatePlanSchema: z.ZodObject<{
|
|
|
157
171
|
owner: string;
|
|
158
172
|
visibility: "public" | "private";
|
|
159
173
|
};
|
|
174
|
+
blockers: string[];
|
|
175
|
+
ok: boolean;
|
|
176
|
+
planDigest: string;
|
|
160
177
|
template: {
|
|
161
178
|
id: string;
|
|
162
179
|
version: string;
|
|
@@ -164,6 +181,11 @@ export declare const projectCreatePlanSchema: z.ZodObject<{
|
|
|
164
181
|
};
|
|
165
182
|
team: string;
|
|
166
183
|
steps: ("project" | "library" | "repository" | "template" | "inventory")[];
|
|
184
|
+
actions: {
|
|
185
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
186
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
187
|
+
}[];
|
|
188
|
+
observationDigest: string;
|
|
167
189
|
}, {
|
|
168
190
|
slug: string;
|
|
169
191
|
schemaVersion: "treeseed.platform-project-create-plan/v1";
|
|
@@ -172,6 +194,9 @@ export declare const projectCreatePlanSchema: z.ZodObject<{
|
|
|
172
194
|
owner: string;
|
|
173
195
|
visibility: "public" | "private";
|
|
174
196
|
};
|
|
197
|
+
blockers: string[];
|
|
198
|
+
ok: boolean;
|
|
199
|
+
planDigest: string;
|
|
175
200
|
template: {
|
|
176
201
|
id: string;
|
|
177
202
|
version: string;
|
|
@@ -179,9 +204,15 @@ export declare const projectCreatePlanSchema: z.ZodObject<{
|
|
|
179
204
|
};
|
|
180
205
|
team: string;
|
|
181
206
|
steps: ("project" | "library" | "repository" | "template" | "inventory")[];
|
|
207
|
+
actions: {
|
|
208
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
209
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
210
|
+
}[];
|
|
211
|
+
observationDigest: string;
|
|
182
212
|
}>;
|
|
183
|
-
export declare const projectCreateReceiptSchema: z.ZodObject<
|
|
184
|
-
schemaVersion: z.ZodLiteral<"treeseed.platform-project-create-
|
|
213
|
+
export declare const projectCreateReceiptSchema: z.ZodObject<{
|
|
214
|
+
schemaVersion: z.ZodLiteral<"treeseed.platform-project-create-receipt/v1">;
|
|
215
|
+
planDigest: z.ZodString;
|
|
185
216
|
slug: z.ZodString;
|
|
186
217
|
template: z.ZodObject<{
|
|
187
218
|
id: z.ZodString;
|
|
@@ -210,13 +241,20 @@ export declare const projectCreateReceiptSchema: z.ZodObject<Omit<{
|
|
|
210
241
|
owner: string;
|
|
211
242
|
visibility: "public" | "private";
|
|
212
243
|
}>;
|
|
213
|
-
steps: z.ZodArray<z.ZodEnum<["project", "repository", "template", "library", "inventory"]>, "many">;
|
|
214
|
-
}, "schemaVersion"> & {
|
|
215
|
-
schemaVersion: z.ZodLiteral<"treeseed.platform-project-create-receipt/v1">;
|
|
216
244
|
projectId: z.ZodString;
|
|
217
245
|
repositoryUrl: z.ZodString;
|
|
218
246
|
libraryBindingId: z.ZodString;
|
|
219
247
|
inventoryVersion: z.ZodNumber;
|
|
248
|
+
actions: z.ZodArray<z.ZodObject<{
|
|
249
|
+
step: z.ZodEnum<["project", "repository", "template", "library", "inventory"]>;
|
|
250
|
+
action: z.ZodEnum<["create", "adopt", "apply", "bind", "publish", "noop", "blocked"]>;
|
|
251
|
+
}, "strip", z.ZodTypeAny, {
|
|
252
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
253
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
254
|
+
}, {
|
|
255
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
256
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
257
|
+
}>, "many">;
|
|
220
258
|
}, "strict", z.ZodTypeAny, {
|
|
221
259
|
slug: string;
|
|
222
260
|
schemaVersion: "treeseed.platform-project-create-receipt/v1";
|
|
@@ -225,13 +263,17 @@ export declare const projectCreateReceiptSchema: z.ZodObject<Omit<{
|
|
|
225
263
|
owner: string;
|
|
226
264
|
visibility: "public" | "private";
|
|
227
265
|
};
|
|
266
|
+
planDigest: string;
|
|
228
267
|
template: {
|
|
229
268
|
id: string;
|
|
230
269
|
version: string;
|
|
231
270
|
digest: string;
|
|
232
271
|
};
|
|
233
272
|
team: string;
|
|
234
|
-
|
|
273
|
+
actions: {
|
|
274
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
275
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
276
|
+
}[];
|
|
235
277
|
projectId: string;
|
|
236
278
|
repositoryUrl: string;
|
|
237
279
|
libraryBindingId: string;
|
|
@@ -244,13 +286,17 @@ export declare const projectCreateReceiptSchema: z.ZodObject<Omit<{
|
|
|
244
286
|
owner: string;
|
|
245
287
|
visibility: "public" | "private";
|
|
246
288
|
};
|
|
289
|
+
planDigest: string;
|
|
247
290
|
template: {
|
|
248
291
|
id: string;
|
|
249
292
|
version: string;
|
|
250
293
|
digest: string;
|
|
251
294
|
};
|
|
252
295
|
team: string;
|
|
253
|
-
|
|
296
|
+
actions: {
|
|
297
|
+
action: "noop" | "blocked" | "create" | "adopt" | "apply" | "bind" | "publish";
|
|
298
|
+
step: "project" | "library" | "repository" | "template" | "inventory";
|
|
299
|
+
}[];
|
|
254
300
|
projectId: string;
|
|
255
301
|
repositoryUrl: string;
|
|
256
302
|
libraryBindingId: string;
|
|
@@ -27,14 +27,28 @@ const projectCreatePlanSchema = z.object({
|
|
|
27
27
|
template: z.object({ id: z.string().min(1), version: z.string().min(1), digest }),
|
|
28
28
|
team: z.string().min(1),
|
|
29
29
|
repository: z.object({ owner: z.string().min(1), name: z.string().min(1), visibility: z.enum(["public", "private"]) }),
|
|
30
|
-
steps: z.array(z.enum(["project", "repository", "template", "library", "inventory"]))
|
|
30
|
+
steps: z.array(z.enum(["project", "repository", "template", "library", "inventory"])),
|
|
31
|
+
actions: z.array(z.object({
|
|
32
|
+
step: z.enum(["project", "repository", "template", "library", "inventory"]),
|
|
33
|
+
action: z.enum(["create", "adopt", "apply", "bind", "publish", "noop", "blocked"])
|
|
34
|
+
})),
|
|
35
|
+
observationDigest: digest,
|
|
36
|
+
planDigest: digest,
|
|
37
|
+
ok: z.boolean(),
|
|
38
|
+
blockers: z.array(z.string())
|
|
31
39
|
}).strict();
|
|
32
|
-
const projectCreateReceiptSchema =
|
|
40
|
+
const projectCreateReceiptSchema = z.object({
|
|
33
41
|
schemaVersion: z.literal("treeseed.platform-project-create-receipt/v1"),
|
|
42
|
+
planDigest: digest,
|
|
43
|
+
slug: projectCreatePlanSchema.shape.slug,
|
|
44
|
+
template: projectCreatePlanSchema.shape.template,
|
|
45
|
+
team: z.string().min(1),
|
|
46
|
+
repository: projectCreatePlanSchema.shape.repository,
|
|
34
47
|
projectId: z.string().min(1),
|
|
35
48
|
repositoryUrl: z.string().url(),
|
|
36
49
|
libraryBindingId: z.string().min(1),
|
|
37
|
-
inventoryVersion: z.number().int().positive()
|
|
50
|
+
inventoryVersion: z.number().int().positive(),
|
|
51
|
+
actions: projectCreatePlanSchema.shape.actions
|
|
38
52
|
}).strict();
|
|
39
53
|
const providerRegistrationRequestSchema = z.object({
|
|
40
54
|
schemaVersion: z.literal("treeseed.provider-registration-request/v1"),
|
package/dist/platform/index.d.ts
CHANGED
package/dist/platform/index.js
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ProjectCreatePlan, type ProjectCreateReceipt } from './contracts.js';
|
|
2
|
+
export type ProjectCreateStep = 'project' | 'repository' | 'template' | 'library' | 'inventory';
|
|
3
|
+
export type ProjectCreateState = 'missing' | 'ready' | 'conflict';
|
|
4
|
+
export interface ProjectCreateTarget {
|
|
5
|
+
slug: string;
|
|
6
|
+
template: {
|
|
7
|
+
id: string;
|
|
8
|
+
version: string;
|
|
9
|
+
digest: string;
|
|
10
|
+
};
|
|
11
|
+
team: string;
|
|
12
|
+
repository: {
|
|
13
|
+
owner: string;
|
|
14
|
+
name: string;
|
|
15
|
+
visibility: 'public' | 'private';
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface ProjectCreateObservation {
|
|
19
|
+
project: {
|
|
20
|
+
state: ProjectCreateState;
|
|
21
|
+
id?: string;
|
|
22
|
+
};
|
|
23
|
+
repository: {
|
|
24
|
+
state: ProjectCreateState;
|
|
25
|
+
url?: string;
|
|
26
|
+
};
|
|
27
|
+
template: {
|
|
28
|
+
state: ProjectCreateState;
|
|
29
|
+
digest?: string;
|
|
30
|
+
};
|
|
31
|
+
library: {
|
|
32
|
+
state: ProjectCreateState;
|
|
33
|
+
bindingId?: string;
|
|
34
|
+
};
|
|
35
|
+
inventory: {
|
|
36
|
+
state: ProjectCreateState;
|
|
37
|
+
version?: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface ProjectCreateAuthority {
|
|
41
|
+
observe(target: ProjectCreateTarget): Promise<ProjectCreateObservation>;
|
|
42
|
+
reconcileProject(target: ProjectCreateTarget): Promise<void>;
|
|
43
|
+
reconcileRepository(target: ProjectCreateTarget): Promise<void>;
|
|
44
|
+
applyTemplate(target: ProjectCreateTarget): Promise<void>;
|
|
45
|
+
reconcileLibrary(target: ProjectCreateTarget): Promise<void>;
|
|
46
|
+
publishInventory(target: ProjectCreateTarget): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export declare function planPlatformProjectCreate(target: ProjectCreateTarget, authority: Pick<ProjectCreateAuthority, 'observe'>): Promise<ProjectCreatePlan>;
|
|
49
|
+
export declare function applyPlatformProjectCreate(plan: ProjectCreatePlan, authority: ProjectCreateAuthority): Promise<ProjectCreateReceipt>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { projectCreatePlanSchema, projectCreateReceiptSchema } from "./contracts.js";
|
|
3
|
+
const steps = ["project", "repository", "template", "library", "inventory"];
|
|
4
|
+
const actionFor = {
|
|
5
|
+
project: "create",
|
|
6
|
+
repository: "adopt",
|
|
7
|
+
template: "apply",
|
|
8
|
+
library: "bind",
|
|
9
|
+
inventory: "publish"
|
|
10
|
+
};
|
|
11
|
+
function canonical(value) {
|
|
12
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
13
|
+
if (value && typeof value === "object") return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
|
|
14
|
+
return JSON.stringify(value);
|
|
15
|
+
}
|
|
16
|
+
function digest(value) {
|
|
17
|
+
return `sha256:${createHash("sha256").update(canonical(value)).digest("hex")}`;
|
|
18
|
+
}
|
|
19
|
+
function blockers(observation) {
|
|
20
|
+
return steps.filter((step) => observation[step].state === "conflict").map((step) => `${step}_conflicts_with_requested_target`);
|
|
21
|
+
}
|
|
22
|
+
async function planPlatformProjectCreate(target, authority) {
|
|
23
|
+
const observation = await authority.observe(target);
|
|
24
|
+
const conflicts = blockers(observation);
|
|
25
|
+
const base = {
|
|
26
|
+
schemaVersion: "treeseed.platform-project-create-plan/v1",
|
|
27
|
+
...target,
|
|
28
|
+
steps: [...steps],
|
|
29
|
+
actions: steps.map((step) => ({ step, action: observation[step].state === "ready" ? "noop" : observation[step].state === "conflict" ? "blocked" : actionFor[step] })),
|
|
30
|
+
observationDigest: digest(observation),
|
|
31
|
+
ok: conflicts.length === 0,
|
|
32
|
+
blockers: conflicts
|
|
33
|
+
};
|
|
34
|
+
return projectCreatePlanSchema.parse({ ...base, planDigest: digest(base) });
|
|
35
|
+
}
|
|
36
|
+
function requireReady(observation) {
|
|
37
|
+
const incomplete = steps.filter((step) => observation[step].state !== "ready");
|
|
38
|
+
if (incomplete.length) throw new Error(`Project creation postconditions are incomplete: ${incomplete.join(", ")}.`);
|
|
39
|
+
if (!observation.project.id || !observation.repository.url || !observation.library.bindingId || !observation.inventory.version) {
|
|
40
|
+
throw new Error("Project creation authority returned incomplete receipt identities.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function applyPlatformProjectCreate(plan, authority) {
|
|
44
|
+
const accepted = projectCreatePlanSchema.parse(plan);
|
|
45
|
+
const { planDigest: _planDigest, ...unsigned } = accepted;
|
|
46
|
+
if (digest(unsigned) !== accepted.planDigest) throw new Error("Project creation plan digest does not match its frozen inputs.");
|
|
47
|
+
if (!accepted.ok || accepted.blockers.length) throw new Error("Blocked project creation plans cannot be applied.");
|
|
48
|
+
const target = { slug: accepted.slug, template: accepted.template, team: accepted.team, repository: accepted.repository };
|
|
49
|
+
const current = await authority.observe(target);
|
|
50
|
+
if (digest(current) !== accepted.observationDigest) throw new Error("Project creation authority changed after planning; create a new plan.");
|
|
51
|
+
const operations = {
|
|
52
|
+
project: authority.reconcileProject,
|
|
53
|
+
repository: authority.reconcileRepository,
|
|
54
|
+
template: authority.applyTemplate,
|
|
55
|
+
library: authority.reconcileLibrary,
|
|
56
|
+
inventory: authority.publishInventory
|
|
57
|
+
};
|
|
58
|
+
for (const item of accepted.actions) if (item.action !== "noop") await operations[item.step].call(authority, target);
|
|
59
|
+
const final = await authority.observe(target);
|
|
60
|
+
requireReady(final);
|
|
61
|
+
return projectCreateReceiptSchema.parse({
|
|
62
|
+
schemaVersion: "treeseed.platform-project-create-receipt/v1",
|
|
63
|
+
planDigest: accepted.planDigest,
|
|
64
|
+
...target,
|
|
65
|
+
projectId: final.project.id,
|
|
66
|
+
repositoryUrl: final.repository.url,
|
|
67
|
+
libraryBindingId: final.library.bindingId,
|
|
68
|
+
inventoryVersion: final.inventory.version,
|
|
69
|
+
actions: accepted.actions
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
applyPlatformProjectCreate,
|
|
74
|
+
planPlatformProjectCreate
|
|
75
|
+
};
|