@treeseed/sdk 0.13.0-rc.71 → 0.13.0-rc.72

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.
@@ -1 +1 @@
1
- {"completedAt":"2026-09-02T02:46:28.673Z"}
1
+ {"completedAt":"2026-09-02T02:59:22.984Z"}
@@ -705,6 +705,7 @@ export declare const hostedTopologyRollbackSchema: z.ZodObject<{
705
705
  schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-rollback/v1">;
706
706
  rollbackId: z.ZodString;
707
707
  sourceReceiptId: z.ZodString;
708
+ environment: z.ZodEnum<["staging", "production"]>;
708
709
  operations: z.ZodArray<z.ZodObject<{
709
710
  resourceId: z.ZodString;
710
711
  action: z.ZodEnum<["restore", "delete-created", "noop"]>;
@@ -724,6 +725,7 @@ export declare const hostedTopologyRollbackSchema: z.ZodObject<{
724
725
  rollbackDigest: z.ZodString;
725
726
  }, "strict", z.ZodTypeAny, {
726
727
  schemaVersion: "treeseed.hosted-topology-rollback/v1";
728
+ environment: "production" | "staging";
727
729
  operations: {
728
730
  action: "noop" | "restore" | "delete-created";
729
731
  resourceId: string;
@@ -735,6 +737,7 @@ export declare const hostedTopologyRollbackSchema: z.ZodObject<{
735
737
  rollbackDigest: string;
736
738
  }, {
737
739
  schemaVersion: "treeseed.hosted-topology-rollback/v1";
740
+ environment: "production" | "staging";
738
741
  operations: {
739
742
  action: "noop" | "restore" | "delete-created";
740
743
  resourceId: string;
@@ -745,6 +748,28 @@ export declare const hostedTopologyRollbackSchema: z.ZodObject<{
745
748
  sourceReceiptId: string;
746
749
  rollbackDigest: string;
747
750
  }>;
751
+ export declare const hostedTopologyRollbackApprovalSchema: z.ZodObject<{
752
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-rollback-approval/v1">;
753
+ rollbackDigest: z.ZodString;
754
+ environment: z.ZodEnum<["staging", "production"]>;
755
+ decision: z.ZodLiteral<"approved">;
756
+ approvedBy: z.ZodString;
757
+ approvedAt: z.ZodString;
758
+ }, "strict", z.ZodTypeAny, {
759
+ schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
760
+ environment: "production" | "staging";
761
+ decision: "approved";
762
+ approvedBy: string;
763
+ approvedAt: string;
764
+ rollbackDigest: string;
765
+ }, {
766
+ schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
767
+ environment: "production" | "staging";
768
+ decision: "approved";
769
+ approvedBy: string;
770
+ approvedAt: string;
771
+ rollbackDigest: string;
772
+ }>;
748
773
  export type HostedTopologyDeclaration = z.infer<typeof hostedTopologyDeclarationSchema>;
749
774
  export type HostedResourceObservation = z.infer<typeof hostedResourceObservationSchema>;
750
775
  export type HostedTopologyPlan = z.infer<typeof hostedTopologyPlanSchema>;
@@ -765,6 +790,7 @@ export declare function verifyHostedTopologyReadback(input: {
765
790
  }): HostedTopologyReceipt;
766
791
  export declare function planHostedTopologyRollback(receiptInput: HostedTopologyReceipt): {
767
792
  schemaVersion: "treeseed.hosted-topology-rollback/v1";
793
+ environment: "production" | "staging";
768
794
  operations: {
769
795
  action: "noop" | "restore" | "delete-created";
770
796
  resourceId: string;
@@ -775,3 +801,26 @@ export declare function planHostedTopologyRollback(receiptInput: HostedTopologyR
775
801
  sourceReceiptId: string;
776
802
  rollbackDigest: string;
777
803
  };
804
+ export declare function authorizeHostedTopologyRollback(rollbackInput: z.input<typeof hostedTopologyRollbackSchema>, approvalInput: z.input<typeof hostedTopologyRollbackApprovalSchema>): {
805
+ rollback: {
806
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
807
+ environment: "production" | "staging";
808
+ operations: {
809
+ action: "noop" | "restore" | "delete-created";
810
+ resourceId: string;
811
+ providerResourceId: string;
812
+ targetDigest: string | null;
813
+ }[];
814
+ rollbackId: string;
815
+ sourceReceiptId: string;
816
+ rollbackDigest: string;
817
+ };
818
+ approval: {
819
+ schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
820
+ environment: "production" | "staging";
821
+ decision: "approved";
822
+ approvedBy: string;
823
+ approvedAt: string;
824
+ rollbackDigest: string;
825
+ };
826
+ };
@@ -113,6 +113,7 @@ const hostedTopologyRollbackSchema = z.object({
113
113
  schemaVersion: z.literal("treeseed.hosted-topology-rollback/v1"),
114
114
  rollbackId: z.string().regex(/^topology-rollback-[a-f0-9]{16}$/u),
115
115
  sourceReceiptId: z.string().regex(/^topology-receipt-[a-f0-9]{16}$/u),
116
+ environment: z.enum(["staging", "production"]),
116
117
  operations: z.array(z.object({
117
118
  resourceId: identifier,
118
119
  action: z.enum(["restore", "delete-created", "noop"]),
@@ -121,6 +122,14 @@ const hostedTopologyRollbackSchema = z.object({
121
122
  }).strict()),
122
123
  rollbackDigest: digest
123
124
  }).strict();
125
+ const hostedTopologyRollbackApprovalSchema = z.object({
126
+ schemaVersion: z.literal("treeseed.hosted-topology-rollback-approval/v1"),
127
+ rollbackDigest: digest,
128
+ environment: z.enum(["staging", "production"]),
129
+ decision: z.literal("approved"),
130
+ approvedBy: z.string().min(1).max(256),
131
+ approvedAt: timestamp
132
+ }).strict();
124
133
  function observationMap(items, declaration) {
125
134
  const resources = new Map(declaration.resources.map((resource) => [resource.id, resource]));
126
135
  const observations = /* @__PURE__ */ new Map();
@@ -211,10 +220,16 @@ function planHostedTopologyRollback(receiptInput) {
211
220
  return { resourceId: resource.resourceId, action: !prior || prior.state === "missing" ? "delete-created" : prior.observedDigest === resource.observedDigest ? "noop" : "restore", providerResourceId: resource.providerResourceId, targetDigest: prior?.observedDigest ?? null };
212
221
  }).sort((left, right) => left.resourceId.localeCompare(right.resourceId));
213
222
  const rollbackDigest = deploymentDigest({ sourceReceiptId: receipt.receiptId, operations });
214
- return hostedTopologyRollbackSchema.parse({ schemaVersion: "treeseed.hosted-topology-rollback/v1", rollbackId: `topology-rollback-${rollbackDigest.slice(7, 23)}`, sourceReceiptId: receipt.receiptId, operations, rollbackDigest });
223
+ return hostedTopologyRollbackSchema.parse({ schemaVersion: "treeseed.hosted-topology-rollback/v1", rollbackId: `topology-rollback-${rollbackDigest.slice(7, 23)}`, sourceReceiptId: receipt.receiptId, environment: receipt.environment, operations, rollbackDigest });
224
+ }
225
+ function authorizeHostedTopologyRollback(rollbackInput, approvalInput) {
226
+ const rollback = hostedTopologyRollbackSchema.parse(rollbackInput), approval = hostedTopologyRollbackApprovalSchema.parse(approvalInput);
227
+ if (approval.rollbackDigest !== rollback.rollbackDigest || approval.environment !== rollback.environment) throw new Error("Hosted topology rollback approval does not bind the exact rollback and environment.");
228
+ return { rollback, approval };
215
229
  }
216
230
  export {
217
231
  authorizeHostedTopologyPlan,
232
+ authorizeHostedTopologyRollback,
218
233
  authorizedHostedTopologyPlanSchema,
219
234
  hostedProviderSchema,
220
235
  hostedResourceKindSchema,
@@ -223,6 +238,7 @@ export {
223
238
  hostedTopologyDeclarationSchema,
224
239
  hostedTopologyPlanSchema,
225
240
  hostedTopologyReceiptSchema,
241
+ hostedTopologyRollbackApprovalSchema,
226
242
  hostedTopologyRollbackSchema,
227
243
  planHostedTopology,
228
244
  planHostedTopologyRollback,
@@ -34,6 +34,10 @@ const operationBindings = {
34
34
  "platform verify": local("local.platform.verify"),
35
35
  "platform workset": local("local.platform.workset"),
36
36
  "platform project create": local("local.platform.project.create"),
37
+ "platform topology plan": local("local.platform.topology.plan"),
38
+ "platform topology apply": local("local.platform.topology.apply"),
39
+ "platform topology status": local("local.platform.topology.status"),
40
+ "platform topology rollback": local("local.platform.topology.rollback"),
37
41
  "host status": local("local.host.status"),
38
42
  "host doctor": local("local.host.doctor"),
39
43
  "host plan": local("local.host.plan"),
@@ -358,6 +362,12 @@ const commandTree = {
358
362
  { nodeType: "leaf", segment: "workset", description: "Plan or safely materialize exact primary source checkouts beneath packages/.", kind: "mutation", options: [planOption, { name: "--apply", description: "Apply the frozen workset plan.", type: "boolean" }, { name: "--yes", description: "Confirm the planned checkout mutations.", type: "boolean" }, { name: "--profile", description: "Composable source profile; repeat to union profiles.", type: "string[]" }, { name: "--project", description: "Explicit project slug; repeat to select projects.", type: "string[]" }, { name: "--exclude", description: "Project slug to exclude; repeat as needed.", type: "string[]" }, { name: "--json", description: "Emit the stable command-result envelope.", type: "boolean" }], authorization: { capability: "development.workset", confirmation: "never" }, resultSchemaId: "treeseed.platform-workset-result/v1", execution: local("local.platform.workset") },
359
363
  branch("project", [
360
364
  { nodeType: "leaf", segment: "create", description: "Plan or reconcile a project, repository, template, library binding, and live inventory without writing application source into Platform Git.", kind: "mutation", arguments: [{ name: "slug", description: "Portable project slug.", required: true }], options: [planOption, { name: "--apply", description: "Apply the accepted creation plan.", type: "boolean" }, { name: "--yes", description: "Confirm authority-bearing project creation.", type: "boolean" }, { name: "--template", description: "Published template identity.", type: "string", required: true }, { name: "--json", description: "Emit the stable command-result envelope.", type: "boolean" }], authorization: { capability: "projects.create", confirmation: "authority" }, resultSchemaId: "treeseed.platform-project-create-result/v1", execution: local("local.platform.project.create") }
365
+ ]),
366
+ branch("topology", [
367
+ { nodeType: "leaf", segment: "plan", description: "Plan Cloudflare and Railway reconciliation from a portable hosted-topology declaration.", kind: "read", arguments: [{ name: "file", description: "Hosted topology YAML or JSON declaration.", required: true }], resultSchemaId: "treeseed.hosted-topology-plan/v1", execution: local("local.platform.topology.plan") },
368
+ { nodeType: "leaf", segment: "apply", description: "Apply an exact reviewed hosted-topology plan through the operations runner.", kind: "mutation", arguments: [{ name: "plan", description: "Exact plan JSON file.", required: true }], options: [planOption, { name: "--approval", description: "Exact environment approval JSON file.", type: "string", required: true }, { name: "--yes", description: "Confirm the authority-bearing mutation.", type: "boolean" }], authorization: { capability: "infrastructure.write", confirmation: "authority" }, resultSchemaId: "treeseed.platform-operation/v1", execution: local("local.platform.topology.apply") },
369
+ { nodeType: "leaf", segment: "status", description: "Read the latest hosted-topology operation and known-good receipt.", kind: "read", resultSchemaId: "treeseed.infrastructure.topology.status.output/v1", execution: local("local.platform.topology.status") },
370
+ { nodeType: "leaf", segment: "rollback", description: "Restore exact prior hosted-topology state from a known-good receipt.", kind: "mutation", arguments: [{ name: "rollback", description: "Exact rollback JSON file.", required: true }], options: [planOption, { name: "--approval", description: "Exact rollback approval JSON file.", type: "string", required: true }, { name: "--yes", description: "Confirm the destructive rollback.", type: "boolean" }], authorization: { capability: "infrastructure.write", confirmation: "destructive" }, resultSchemaId: "treeseed.platform-operation/v1", execution: local("local.platform.topology.rollback") }
361
371
  ])
362
372
  ]),
363
373
  branch("dev", [
@@ -0,0 +1,168 @@
1
+ export declare const HOSTED_TOPOLOGY_OPERATIONS: {
2
+ readonly plan: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
3
+ teamId: string;
4
+ }, {}, {
5
+ declaration: {
6
+ schemaVersion: "treeseed.hosted-topology/v1";
7
+ resources: {
8
+ id: string;
9
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
10
+ provider: "cloudflare" | "railway";
11
+ adoption: {
12
+ mode: "adopt-or-create";
13
+ replacement: "forbidden";
14
+ externalIdInput?: string | undefined;
15
+ };
16
+ dependsOn?: string[] | undefined;
17
+ parameters?: Record<string, {
18
+ input: string;
19
+ } | {
20
+ artifact: string;
21
+ } | {
22
+ resourceOutput: {
23
+ resourceId: string;
24
+ output: string;
25
+ };
26
+ } | {
27
+ literal: string | number | boolean;
28
+ }> | undefined;
29
+ }[];
30
+ id: string;
31
+ platform: {
32
+ repository: "treeseed-ai/platform";
33
+ commit: string;
34
+ };
35
+ mutation: "approval-required";
36
+ environment: "production" | "staging";
37
+ artifacts: Record<string, {
38
+ digest: string;
39
+ source: string;
40
+ }>;
41
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
42
+ connectionRef: string;
43
+ }>>;
44
+ };
45
+ }, {
46
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
47
+ blockers: {
48
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
49
+ message: string;
50
+ resourceId?: string | undefined;
51
+ }[];
52
+ planDigest: string;
53
+ actions: {
54
+ action: "noop" | "create" | "adopt" | "update";
55
+ resourceId: string;
56
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
57
+ provider: "cloudflare" | "railway";
58
+ providerResourceId: string | null;
59
+ desiredDigest: string;
60
+ previousDigest: string | null;
61
+ }[];
62
+ environment: "production" | "staging";
63
+ executable: false;
64
+ planId: string;
65
+ declarationDigest: string;
66
+ topologyId: string;
67
+ platformCommit: string;
68
+ approvalRequired: boolean;
69
+ }>;
70
+ readonly apply: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
71
+ teamId: string;
72
+ }, {}, {
73
+ approval: {
74
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
75
+ planDigest: string;
76
+ environment: "production" | "staging";
77
+ decision: "approved";
78
+ approvedBy: string;
79
+ approvedAt: string;
80
+ };
81
+ plan: {
82
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
83
+ blockers: {
84
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
85
+ message: string;
86
+ resourceId?: string | undefined;
87
+ }[];
88
+ planDigest: string;
89
+ actions: {
90
+ action: "noop" | "create" | "adopt" | "update";
91
+ resourceId: string;
92
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
93
+ provider: "cloudflare" | "railway";
94
+ providerResourceId: string | null;
95
+ desiredDigest: string;
96
+ previousDigest: string | null;
97
+ }[];
98
+ environment: "production" | "staging";
99
+ executable: false;
100
+ planId: string;
101
+ declarationDigest: string;
102
+ topologyId: string;
103
+ platformCommit: string;
104
+ approvalRequired: boolean;
105
+ };
106
+ }, Record<string, unknown>>;
107
+ readonly status: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
108
+ teamId: string;
109
+ }, {}, undefined, {
110
+ operation: Record<string, unknown> | null;
111
+ receipt: {
112
+ schemaVersion: "treeseed.hosted-topology-receipt/v1";
113
+ resources: {
114
+ state: "missing" | "degraded" | "healthy";
115
+ resourceId: string;
116
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
117
+ provider: "cloudflare" | "railway";
118
+ providerResourceId: string | null;
119
+ managedBy: "external" | "treeseed" | null;
120
+ observedDigest: string | null;
121
+ observedAt: string;
122
+ }[];
123
+ planDigest: string;
124
+ state: "known-good";
125
+ environment: "production" | "staging";
126
+ completedAt: string;
127
+ receiptId: string;
128
+ declarationDigest: string;
129
+ topologyId: string;
130
+ platformCommit: string;
131
+ previousResources: {
132
+ state: "missing" | "degraded" | "healthy";
133
+ resourceId: string;
134
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
135
+ provider: "cloudflare" | "railway";
136
+ providerResourceId: string | null;
137
+ managedBy: "external" | "treeseed" | null;
138
+ observedDigest: string | null;
139
+ observedAt: string;
140
+ }[];
141
+ } | null;
142
+ }>;
143
+ readonly rollback: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
144
+ teamId: string;
145
+ }, {}, {
146
+ rollback: {
147
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
148
+ environment: "production" | "staging";
149
+ operations: {
150
+ action: "noop" | "restore" | "delete-created";
151
+ resourceId: string;
152
+ providerResourceId: string;
153
+ targetDigest: string | null;
154
+ }[];
155
+ rollbackId: string;
156
+ sourceReceiptId: string;
157
+ rollbackDigest: string;
158
+ };
159
+ approval: {
160
+ schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
161
+ environment: "production" | "staging";
162
+ decision: "approved";
163
+ approvedBy: string;
164
+ approvedAt: string;
165
+ rollbackDigest: string;
166
+ };
167
+ }, Record<string, unknown>>;
168
+ };
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ import { hostedTopologyApprovalSchema, hostedTopologyDeclarationSchema, hostedTopologyPlanSchema, hostedTopologyReceiptSchema, hostedTopologyRollbackApprovalSchema, hostedTopologyRollbackSchema } from "../../deployment/hosted-topology.js";
3
+ import { defineOperation } from "../operation-builder.js";
4
+ const teamPath = z.object({ teamId: z.string().min(1) }).strict();
5
+ const empty = z.object({}).strict();
6
+ const none = z.undefined();
7
+ const operationReceipt = z.record(z.unknown());
8
+ const HOSTED_TOPOLOGY_OPERATIONS = {
9
+ plan: defineOperation({
10
+ operationId: "infrastructure.topology.plan",
11
+ description: "Plan exact hosted topology reconciliation from authoritative provider observations.",
12
+ rest: { method: "POST", path: "/v1/teams/{teamId}/infrastructure/topology/plan" },
13
+ parameters: "treeseed.infrastructure.topology.plan.parameters/v1",
14
+ capability: "infrastructure.read",
15
+ authentication: "oauth",
16
+ oauthScopes: ["treeseed:read"],
17
+ kind: "read",
18
+ riskClass: "ordinary",
19
+ confirmation: "never",
20
+ surfaces: ["rest", "cli"],
21
+ cacheScope: "none",
22
+ pagination: "none",
23
+ idempotencyRequired: false
24
+ }, { path: teamPath, query: empty, body: z.object({ declaration: hostedTopologyDeclarationSchema }).strict(), output: hostedTopologyPlanSchema }),
25
+ apply: defineOperation({
26
+ operationId: "infrastructure.topology.apply",
27
+ description: "Apply an exact approved hosted topology plan through the operations runner.",
28
+ rest: { method: "POST", path: "/v1/teams/{teamId}/infrastructure/topology/apply" },
29
+ parameters: "treeseed.infrastructure.topology.apply.parameters/v1",
30
+ capability: "infrastructure.write",
31
+ authentication: "oauth",
32
+ oauthScopes: ["treeseed:admin"],
33
+ kind: "mutation",
34
+ riskClass: "authority",
35
+ confirmation: "input_required",
36
+ surfaces: ["rest", "cli"],
37
+ cacheScope: "none",
38
+ pagination: "none",
39
+ concurrencyRequired: true,
40
+ redactedPaths: ["body.approval.approvedBy"]
41
+ }, { path: teamPath, query: empty, body: z.object({ plan: hostedTopologyPlanSchema, approval: hostedTopologyApprovalSchema }).strict(), output: operationReceipt }),
42
+ status: defineOperation({
43
+ operationId: "infrastructure.topology.status",
44
+ description: "Read the latest authoritative hosted topology receipt and operation state.",
45
+ rest: { method: "GET", path: "/v1/teams/{teamId}/infrastructure/topology" },
46
+ parameters: "treeseed.infrastructure.topology.status.parameters/v1",
47
+ capability: "infrastructure.read",
48
+ authentication: "oauth",
49
+ oauthScopes: ["treeseed:read"],
50
+ kind: "read",
51
+ riskClass: "ordinary",
52
+ confirmation: "never",
53
+ surfaces: ["rest", "cli"],
54
+ cacheScope: "principal",
55
+ pagination: "none"
56
+ }, { path: teamPath, query: empty, body: none, output: z.object({ receipt: hostedTopologyReceiptSchema.nullable(), operation: operationReceipt.nullable() }).strict() }),
57
+ rollback: defineOperation({
58
+ operationId: "infrastructure.topology.rollback",
59
+ description: "Restore exact prior hosted topology lineage from a known-good receipt.",
60
+ rest: { method: "POST", path: "/v1/teams/{teamId}/infrastructure/topology/rollback" },
61
+ parameters: "treeseed.infrastructure.topology.rollback.parameters/v1",
62
+ capability: "infrastructure.write",
63
+ authentication: "oauth",
64
+ oauthScopes: ["treeseed:admin"],
65
+ kind: "mutation",
66
+ riskClass: "destructive",
67
+ confirmation: "input_required",
68
+ surfaces: ["rest", "cli"],
69
+ cacheScope: "none",
70
+ pagination: "none",
71
+ concurrencyRequired: true,
72
+ redactedPaths: ["body.approval.approvedBy"]
73
+ }, { path: teamPath, query: empty, body: z.object({ rollback: hostedTopologyRollbackSchema, approval: hostedTopologyRollbackApprovalSchema }).strict(), output: operationReceipt })
74
+ };
75
+ export {
76
+ HOSTED_TOPOLOGY_OPERATIONS
77
+ };
@@ -1,5 +1,175 @@
1
1
  import type { ControlPlaneOperationDescriptor } from './control-plane-operation.js';
2
2
  export declare const CONTROL_PLANE_OPERATIONS: {
3
+ readonly infrastructure: {
4
+ readonly topology: {
5
+ readonly plan: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
6
+ teamId: string;
7
+ }, {}, {
8
+ declaration: {
9
+ schemaVersion: "treeseed.hosted-topology/v1";
10
+ resources: {
11
+ id: string;
12
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
13
+ provider: "cloudflare" | "railway";
14
+ adoption: {
15
+ mode: "adopt-or-create";
16
+ replacement: "forbidden";
17
+ externalIdInput?: string | undefined;
18
+ };
19
+ dependsOn?: string[] | undefined;
20
+ parameters?: Record<string, {
21
+ input: string;
22
+ } | {
23
+ artifact: string;
24
+ } | {
25
+ resourceOutput: {
26
+ resourceId: string;
27
+ output: string;
28
+ };
29
+ } | {
30
+ literal: string | number | boolean;
31
+ }> | undefined;
32
+ }[];
33
+ id: string;
34
+ platform: {
35
+ repository: "treeseed-ai/platform";
36
+ commit: string;
37
+ };
38
+ mutation: "approval-required";
39
+ environment: "production" | "staging";
40
+ artifacts: Record<string, {
41
+ digest: string;
42
+ source: string;
43
+ }>;
44
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
45
+ connectionRef: string;
46
+ }>>;
47
+ };
48
+ }, {
49
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
50
+ blockers: {
51
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
52
+ message: string;
53
+ resourceId?: string | undefined;
54
+ }[];
55
+ planDigest: string;
56
+ actions: {
57
+ action: "noop" | "create" | "adopt" | "update";
58
+ resourceId: string;
59
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
60
+ provider: "cloudflare" | "railway";
61
+ providerResourceId: string | null;
62
+ desiredDigest: string;
63
+ previousDigest: string | null;
64
+ }[];
65
+ environment: "production" | "staging";
66
+ executable: false;
67
+ planId: string;
68
+ declarationDigest: string;
69
+ topologyId: string;
70
+ platformCommit: string;
71
+ approvalRequired: boolean;
72
+ }>;
73
+ readonly apply: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
74
+ teamId: string;
75
+ }, {}, {
76
+ approval: {
77
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
78
+ planDigest: string;
79
+ environment: "production" | "staging";
80
+ decision: "approved";
81
+ approvedBy: string;
82
+ approvedAt: string;
83
+ };
84
+ plan: {
85
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
86
+ blockers: {
87
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
88
+ message: string;
89
+ resourceId?: string | undefined;
90
+ }[];
91
+ planDigest: string;
92
+ actions: {
93
+ action: "noop" | "create" | "adopt" | "update";
94
+ resourceId: string;
95
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
96
+ provider: "cloudflare" | "railway";
97
+ providerResourceId: string | null;
98
+ desiredDigest: string;
99
+ previousDigest: string | null;
100
+ }[];
101
+ environment: "production" | "staging";
102
+ executable: false;
103
+ planId: string;
104
+ declarationDigest: string;
105
+ topologyId: string;
106
+ platformCommit: string;
107
+ approvalRequired: boolean;
108
+ };
109
+ }, Record<string, unknown>>;
110
+ readonly status: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
111
+ teamId: string;
112
+ }, {}, undefined, {
113
+ operation: Record<string, unknown> | null;
114
+ receipt: {
115
+ schemaVersion: "treeseed.hosted-topology-receipt/v1";
116
+ resources: {
117
+ state: "missing" | "degraded" | "healthy";
118
+ resourceId: string;
119
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
120
+ provider: "cloudflare" | "railway";
121
+ providerResourceId: string | null;
122
+ managedBy: "external" | "treeseed" | null;
123
+ observedDigest: string | null;
124
+ observedAt: string;
125
+ }[];
126
+ planDigest: string;
127
+ state: "known-good";
128
+ environment: "production" | "staging";
129
+ completedAt: string;
130
+ receiptId: string;
131
+ declarationDigest: string;
132
+ topologyId: string;
133
+ platformCommit: string;
134
+ previousResources: {
135
+ state: "missing" | "degraded" | "healthy";
136
+ resourceId: string;
137
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
138
+ provider: "cloudflare" | "railway";
139
+ providerResourceId: string | null;
140
+ managedBy: "external" | "treeseed" | null;
141
+ observedDigest: string | null;
142
+ observedAt: string;
143
+ }[];
144
+ } | null;
145
+ }>;
146
+ readonly rollback: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
147
+ teamId: string;
148
+ }, {}, {
149
+ rollback: {
150
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
151
+ environment: "production" | "staging";
152
+ operations: {
153
+ action: "noop" | "restore" | "delete-created";
154
+ resourceId: string;
155
+ providerResourceId: string;
156
+ targetDigest: string | null;
157
+ }[];
158
+ rollbackId: string;
159
+ sourceReceiptId: string;
160
+ rollbackDigest: string;
161
+ };
162
+ approval: {
163
+ schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
164
+ environment: "production" | "staging";
165
+ decision: "approved";
166
+ approvedBy: string;
167
+ approvedAt: string;
168
+ rollbackDigest: string;
169
+ };
170
+ }, Record<string, unknown>>;
171
+ };
172
+ };
3
173
  readonly capabilities: {
4
174
  list: import("./control-plane-operation.js").ControlPlaneOperationBinding<{}, {
5
175
  status?: "revoked" | "active" | "deprecated" | undefined;
@@ -7,11 +7,9 @@ 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
9
  import { PROVIDER_ENVIRONMENT_OPERATIONS } from "./catalog/provider-environment-operations.js";
10
+ import { HOSTED_TOPOLOGY_OPERATIONS } from "./catalog/hosted-topology-operations.js";
10
11
  import { buildControlPlaneCatalog, flattenControlPlaneOperations } from "./catalog/control-plane-catalog.js";
11
- const empty = z.object({}).strict();
12
- const none = z.undefined();
13
- const record = z.record(z.unknown());
14
- const payload = record;
12
+ const empty = z.object({}).strict(), none = z.undefined(), record = z.record(z.unknown()), payload = record;
15
13
  function read(operationId, path, capability, surfaces = ["rest"]) {
16
14
  return define({
17
15
  operationId,
@@ -102,6 +100,7 @@ function resource(operationId, method, path, pathShape, options = { capability:
102
100
  }, { path: z.object(pathShape).strict(), query: kind === "read" ? record : empty, body: kind === "read" ? none : record, output: payload });
103
101
  }
104
102
  const CONTROL_PLANE_OPERATIONS = {
103
+ infrastructure: { topology: HOSTED_TOPOLOGY_OPERATIONS },
105
104
  capabilities: capabilityOntologyOperations(),
106
105
  inbox: inboxOperations(),
107
106
  treeai: TREEAI_CONTROL_PLANE_OPERATIONS,
@@ -117,14 +117,14 @@ const SERVICE_PROVIDER_CATALOG = [
117
117
  knowledgePageIds: ["provider.cloudflare"],
118
118
  connectionFields: [field("accountId", "Account ID", "The non-secret Cloudflare account identifier.")],
119
119
  capabilities: [
120
- { type: "frontend-hosting", label: "Frontend hosting", description: "Future Pages and Workers application hosting.", credentialProfileIds: ["cloudflare-runtime"], status: "available" },
121
- { type: "dns-management", label: "DNS management", description: "Future scoped DNS record management.", credentialProfileIds: ["cloudflare-dns"], status: "planned" },
120
+ { type: "frontend-hosting", label: "Frontend hosting", description: "Pages and Workers application hosting.", credentialProfileIds: ["cloudflare-runtime"], status: "available" },
121
+ { type: "dns-management", label: "DNS management", description: "Scoped DNS record management.", credentialProfileIds: ["cloudflare-dns"], status: "available" },
122
122
  { type: "object-storage", label: "Object storage", description: "R2-backed immutable publication and private artifact storage.", credentialProfileIds: ["cloudflare-storage"], status: "available" }
123
123
  ],
124
124
  credentialProfiles: [
125
- { id: "cloudflare-runtime", label: "Pages and Workers token", description: "A token limited to application deployment resources.", capabilities: ["frontend-hosting"], fields: [field("apiToken", "API token", "Encrypted in this browser and used only for authorized frontend operations.", true, true)], permissions: ["Account: Workers Scripts Edit", "Account: Pages Edit"], sharing: "capability-scoped", unattendedCompatible: false, knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
126
- { id: "cloudflare-dns", label: "DNS token", description: "A token restricted to selected zones.", capabilities: ["dns-management"], fields: [field("apiToken", "DNS API token", "Encrypted separately from deployment authority.", true, true)], permissions: ["Zone: DNS Edit for only the managed zones"], sharing: "capability-scoped", unattendedCompatible: false, knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
127
- { id: "cloudflare-storage", label: "Storage token", description: "A token limited to R2 resources.", capabilities: ["object-storage"], fields: [field("apiToken", "Storage API token", "Encrypted separately from runtime and DNS authority.", true, true)], permissions: ["Account: Workers R2 Storage Edit"], sharing: "capability-scoped", unattendedCompatible: false, knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] }
125
+ { id: "cloudflare-runtime", label: "Pages and Workers token", description: "A token limited to application deployment resources.", capabilities: ["frontend-hosting"], fields: [field("apiToken", "API token", "Encrypted in this browser and used only for authorized frontend operations.", true, true)], permissions: ["Account: Workers Scripts Edit", "Account: Pages Edit"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
126
+ { id: "cloudflare-dns", label: "DNS token", description: "A token restricted to selected zones.", capabilities: ["dns-management"], fields: [field("apiToken", "DNS API token", "Encrypted separately from deployment authority.", true, true)], permissions: ["Zone: DNS Edit for only the managed zones"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
127
+ { id: "cloudflare-storage", label: "Storage token", description: "A token limited to R2 resources.", capabilities: ["object-storage"], fields: [field("apiToken", "Storage API token", "Encrypted separately from runtime and DNS authority.", true, true)], permissions: ["Account: Workers R2 Storage Edit"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] }
128
128
  ]
129
129
  },
130
130
  {
@@ -136,10 +136,10 @@ const SERVICE_PROVIDER_CATALOG = [
136
136
  knowledgePageIds: ["provider.railway"],
137
137
  connectionFields: [field("workspaceId", "Workspace ID", "The non-secret Railway workspace identifier.")],
138
138
  capabilities: [
139
- { type: "backend-hosting", label: "Backend hosting", description: "Future API and backend service hosting.", credentialProfileIds: ["railway-workspace"], status: "available" },
140
- { type: "database-hosting", label: "Database hosting", description: "Future managed database placement.", credentialProfileIds: ["railway-workspace"], status: "planned" },
139
+ { type: "backend-hosting", label: "Backend hosting", description: "API and backend service hosting.", credentialProfileIds: ["railway-workspace"], status: "available" },
140
+ { type: "database-hosting", label: "Database hosting", description: "Managed database placement.", credentialProfileIds: ["railway-workspace"], status: "available" },
141
141
  { type: "capacity-runtime-hosting", label: "Capacity runtime hosting", description: "Future capacity provider placement.", credentialProfileIds: ["railway-workspace"], status: "planned" },
142
- { type: "private-knowledge-index-hosting", label: "Private knowledge hosting", description: "Future private TreeDX knowledge-plane placement.", credentialProfileIds: ["railway-workspace"], status: "planned" }
142
+ { type: "private-knowledge-index-hosting", label: "Private knowledge hosting", description: "Private TreeDX knowledge-plane placement.", credentialProfileIds: ["railway-workspace"], status: "available" }
143
143
  ],
144
144
  credentialProfiles: [{
145
145
  id: "railway-workspace",
@@ -149,7 +149,8 @@ const SERVICE_PROVIDER_CATALOG = [
149
149
  fields: [field("apiToken", "Workspace token", "Encrypted in this browser. TreeSeed will request explicit authorization before interactive use.", true, true)],
150
150
  permissions: ["Workspace access required by the selected operations"],
151
151
  sharing: "provider-shared",
152
- unattendedCompatible: false,
152
+ unattendedCompatible: true,
153
+ authoritySchemes: ["environment-reference", "external-vault", "workload-identity"],
153
154
  knowledgePageIds: ["provider.railway", "services.credentials", "vault.rotation"]
154
155
  }]
155
156
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.71",
3
+ "version": "0.13.0-rc.72",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {