@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.
@@ -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<Omit<{
184
- schemaVersion: z.ZodLiteral<"treeseed.platform-project-create-plan/v1">;
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
- steps: ("project" | "library" | "repository" | "template" | "inventory")[];
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
- steps: ("project" | "library" | "repository" | "template" | "inventory")[];
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 = projectCreatePlanSchema.omit({ schemaVersion: true }).extend({
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"),
@@ -1,5 +1,6 @@
1
1
  export * from './schemas.js';
2
2
  export * from './contracts.js';
3
3
  export * from './inventory.js';
4
+ export * from './project-create.js';
4
5
  export * from './workset.js';
5
6
  export * from './verification.js';
@@ -1,5 +1,6 @@
1
1
  export * from "./schemas.js";
2
2
  export * from "./contracts.js";
3
3
  export * from "./inventory.js";
4
+ export * from "./project-create.js";
4
5
  export * from "./workset.js";
5
6
  export * from "./verification.js";
@@ -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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.67",
3
+ "version": "0.13.0-rc.69",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {