@treeseed/sdk 0.13.0-rc.19 → 0.13.0-rc.20

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.
@@ -132,18 +132,18 @@ export declare function validatePortableContentData(model: string, value: unknow
132
132
  mergeTargetBeforeSave: import("zod").ZodOptional<import("zod").ZodBoolean>;
133
133
  }, "strict", import("zod").ZodTypeAny, {
134
134
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
135
- base: "main" | "staging";
135
+ base: "staging" | "main";
136
136
  prefix?: string | undefined;
137
- target?: "main" | "staging" | undefined;
137
+ target?: "staging" | "main" | undefined;
138
138
  branchNameTemplate?: string | undefined;
139
139
  worktree?: string | undefined;
140
140
  updateBaseBeforeRun?: boolean | undefined;
141
141
  mergeTargetBeforeSave?: boolean | undefined;
142
142
  }, {
143
143
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
144
- base: "main" | "staging";
144
+ base: "staging" | "main";
145
145
  prefix?: string | undefined;
146
- target?: "main" | "staging" | undefined;
146
+ target?: "staging" | "main" | undefined;
147
147
  branchNameTemplate?: string | undefined;
148
148
  worktree?: string | undefined;
149
149
  updateBaseBeforeRun?: boolean | undefined;
@@ -858,9 +858,9 @@ export declare function validatePortableContentData(model: string, value: unknow
858
858
  };
859
859
  branchPolicy: {
860
860
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
861
- base: "main" | "staging";
861
+ base: "staging" | "main";
862
862
  prefix?: string | undefined;
863
- target?: "main" | "staging" | undefined;
863
+ target?: "staging" | "main" | undefined;
864
864
  branchNameTemplate?: string | undefined;
865
865
  worktree?: string | undefined;
866
866
  updateBaseBeforeRun?: boolean | undefined;
@@ -1031,9 +1031,9 @@ export declare function validatePortableContentData(model: string, value: unknow
1031
1031
  };
1032
1032
  branchPolicy: {
1033
1033
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
1034
- base: "main" | "staging";
1034
+ base: "staging" | "main";
1035
1035
  prefix?: string | undefined;
1036
- target?: "main" | "staging" | undefined;
1036
+ target?: "staging" | "main" | undefined;
1037
1037
  branchNameTemplate?: string | undefined;
1038
1038
  worktree?: string | undefined;
1039
1039
  updateBaseBeforeRun?: boolean | undefined;
@@ -1204,9 +1204,9 @@ export declare function validatePortableContentData(model: string, value: unknow
1204
1204
  };
1205
1205
  branchPolicy: {
1206
1206
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
1207
- base: "main" | "staging";
1207
+ base: "staging" | "main";
1208
1208
  prefix?: string | undefined;
1209
- target?: "main" | "staging" | undefined;
1209
+ target?: "staging" | "main" | undefined;
1210
1210
  branchNameTemplate?: string | undefined;
1211
1211
  worktree?: string | undefined;
1212
1212
  updateBaseBeforeRun?: boolean | undefined;
@@ -1377,9 +1377,9 @@ export declare function validatePortableContentData(model: string, value: unknow
1377
1377
  };
1378
1378
  branchPolicy: {
1379
1379
  kind: "read-only" | "main-planning-content" | "staging-content" | "assignment-feature" | "staging-release";
1380
- base: "main" | "staging";
1380
+ base: "staging" | "main";
1381
1381
  prefix?: string | undefined;
1382
- target?: "main" | "staging" | undefined;
1382
+ target?: "staging" | "main" | undefined;
1383
1383
  branchNameTemplate?: string | undefined;
1384
1384
  worktree?: string | undefined;
1385
1385
  updateBaseBeforeRun?: boolean | undefined;
@@ -1652,9 +1652,9 @@ export declare function validatePortableContentData(model: string, value: unknow
1652
1652
  supportsReconcile: boolean;
1653
1653
  };
1654
1654
  offer: {
1655
- priceModel: "subscription" | "free" | "private" | "contact" | "one_time" | "one_time_current_version" | "subscription_updates" | "professional_hosting" | "scoped_contract" | "external";
1656
- license?: string | undefined;
1655
+ priceModel: "private" | "subscription" | "free" | "contact" | "one_time" | "one_time_current_version" | "subscription_updates" | "professional_hosting" | "scoped_contract" | "external";
1657
1656
  support?: string | undefined;
1657
+ license?: string | undefined;
1658
1658
  };
1659
1659
  relatedBooks: string[];
1660
1660
  relatedKnowledge: string[];
@@ -1682,11 +1682,11 @@ export declare function validatePortableContentData(model: string, value: unknow
1682
1682
  } & {
1683
1683
  [k: string]: unknown;
1684
1684
  };
1685
+ fixture?: string | undefined;
1685
1686
  budget?: {
1686
1687
  maxTokens: number;
1687
1688
  maxContextItems: number;
1688
1689
  } | undefined;
1689
- fixture?: string | undefined;
1690
1690
  queryRef?: {
1691
1691
  id: string;
1692
1692
  revision: number;
@@ -1796,7 +1796,7 @@ export declare function validatePortableContentData(model: string, value: unknow
1796
1796
  } | undefined;
1797
1797
  } | {
1798
1798
  id: string;
1799
- status: "completed" | "cancelled" | "failed" | "pending" | "running" | "waiting" | "suspended" | "admitted" | "leased";
1799
+ status: "completed" | "cancelled" | "failed" | "admitted" | "running" | "suspended" | "pending" | "waiting" | "leased";
1800
1800
  projectId: string;
1801
1801
  teamId: string;
1802
1802
  title: string;
@@ -1894,7 +1894,7 @@ export declare function validatePortableContentData(model: string, value: unknow
1894
1894
  date?: Date | undefined;
1895
1895
  draft?: boolean | undefined;
1896
1896
  author?: string | undefined;
1897
- feedback_kind?: "question" | "support" | "concern" | "response" | undefined;
1897
+ feedback_kind?: "support" | "question" | "concern" | "response" | undefined;
1898
1898
  entity_refs?: {
1899
1899
  id: string;
1900
1900
  model: string;
@@ -21,15 +21,29 @@ const operationBindings = {
21
21
  "agents show": operation("agents.show", [field("path", "projectId", "context", "project", true), field("path", "agentSlug", "argument", "agent", true)]),
22
22
  "agents classes list": operation("agents.classes.list", [field("path", "projectId", "context", "project", true)]),
23
23
  "agents classes show": operation("agents.classes.show", [field("path", "projectId", "context", "project", true), field("path", "classId", "argument", "class", true)]),
24
- "providers list": operation("services.providers.list", page()),
25
- "providers show": operation("services.connections.show", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "provider", true)]),
26
- "providers status": operation("services.connections.show", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "provider", true)]),
27
- "providers connect": operation("services.connections.create", [field("path", "teamId", "context", "team", true), field("body", "providerId", "option", "provider", true)]),
28
- "providers disconnect": operation("services.connections.disconnect", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true), field("body", "reason", "option")]),
29
- "providers credentials status": operation("services.credential.authorities.list", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true)]),
24
+ "providers list": operation("providers.list", [field("path", "teamId", "context", "team", true), ...page()]),
25
+ "providers show": operation("providers.show", [field("path", "teamId", "context", "team", true), field("path", "providerId", "argument", "provider", true)]),
26
+ "providers status": operation("providers.status", [field("path", "teamId", "context", "team", true), field("path", "providerId", "argument", "provider", true)]),
27
+ "providers diagnose": operation("providers.diagnose", [field("path", "teamId", "context", "team", true), field("path", "providerId", "argument", "provider", true)]),
28
+ "providers connect": operation("providers.connect", [field("path", "teamId", "context", "team", true)]),
29
+ "providers disconnect": operation("providers.disconnect", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true), field("body", "reason", "option")]),
30
+ "providers requests list": operation("providers.requests.list", [field("path", "teamId", "context", "team", true), ...page()]),
31
+ "providers requests show": operation("providers.requests.show", [field("path", "teamId", "context", "team", true), field("path", "requestId", "argument", "request", true)]),
32
+ "providers requests approve": operation("providers.requests.approve", [field("path", "teamId", "context", "team", true), field("path", "requestId", "argument", "request", true)]),
33
+ "providers requests reject": operation("providers.requests.reject", [field("path", "teamId", "context", "team", true), field("path", "requestId", "argument", "request", true)]),
34
+ "providers credentials status": operation("providers.credentials.status", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true)]),
35
+ "providers credentials rotate": operation("providers.credentials.rotate", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true)]),
36
+ "providers credentials revoke": operation("providers.credentials.revoke", [field("path", "teamId", "context", "team", true), field("path", "connectionId", "argument", "connection", true)]),
30
37
  "capacity status": operation("capacity.status", [field("path", "teamId", "context", "team", true), ...page()]),
38
+ "capacity explain": operation("capacity.explain", [field("path", "teamId", "context", "team", true)]),
31
39
  "capacity usage": operation("capacity.usage", [field("path", "teamId", "context", "team", true)]),
32
40
  "capacity ledger": operation("capacity.ledger", [field("path", "teamId", "context", "team", true), ...page()]),
41
+ "capacity audit": operation("capacity.audit", [field("path", "teamId", "context", "team", true), ...page()]),
42
+ "seeds validate": operation("seeds.validate", [field("body", "file", "argument", "file", true)]),
43
+ "seeds plan": operation("seeds.plan", [field("path", "name", "context", "seed", true), field("body", "file", "argument", "file", true)]),
44
+ "seeds apply": operation("seeds.apply", [field("path", "name", "context", "seed", true), field("body", "file", "argument", "file", true)]),
45
+ "seeds show": operation("seeds.show", [field("path", "name", "argument", "seed", true)]),
46
+ "seeds verify": operation("seeds.verify", [field("path", "name", "argument", "seed", true)]),
33
47
  "plans list": operation("plans.list", [field("path", "decisionId", "option", "decision", true), ...page()]),
34
48
  "plans show": operation("plans.show", [field("path", "capacityPlanId", "argument", "plan", true)]),
35
49
  "workdays plan": operation("workdays.plan", [field("path", "teamId", "context", "team", true), field("body", "profile", "option"), field("body", "projects", "option", "projects", false, "csv"), field("body", "start", "option"), field("body", "end", "option"), field("body", "duration", "option", "duration", false, "integer"), field("body", "objective", "option")]),
@@ -99,6 +113,7 @@ const commandTree = {
99
113
  branch("credentials", [leaf("status", "read", "connection"), leaf("rotate", "mutation", "connection", "credential"), leaf("revoke", "mutation", "connection", "irreversible")]),
100
114
  branch("offers", [leaf("show", "read", "connection"), leaf("validate", "read", "file"), leaf("plan", "read", "file"), leaf("apply", "mutation", "file", "authority")])
101
115
  ]),
116
+ branch("seeds", [leaf("validate", "read", "file"), leaf("plan", "read", "file"), leaf("apply", "mutation", "file", "authority"), leaf("show", "read", "seed"), leaf("verify", "read", "seed")]),
102
117
  branch("capacity", [leaf("status"), leaf("explain"), leaf("usage"), leaf("ledger"), leaf("audit")]),
103
118
  branch("plans", [leaf("list"), leaf("show", "read", "plan"), leaf("explain", "read", "plan"), { nodeType: "leaf", segment: "diff", description: "Compare two API-derived plans.", kind: "read", arguments: [{ name: "left", description: "Left plan identity.", required: true }, { name: "right", description: "Right plan identity.", required: true }], resultSchemaId: "treeseed.command.plans.diff/v1", execution: unavailable() }]),
104
119
  branch("workdays", [
@@ -466,12 +466,21 @@ export declare const CONTROL_PLANE_OPERATIONS: {
466
466
  readonly availability: ControlPlaneOperationBinding<{
467
467
  teamId: string;
468
468
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
469
+ readonly explain: ControlPlaneOperationBinding<{
470
+ teamId: string;
471
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
469
472
  readonly usage: ControlPlaneOperationBinding<{
470
473
  teamId: string;
471
474
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
472
475
  readonly ledger: ControlPlaneOperationBinding<{
473
476
  teamId: string;
474
477
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
478
+ readonly audit: ControlPlaneOperationBinding<{
479
+ teamId: string;
480
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
481
+ readonly lanes: ControlPlaneOperationBinding<{
482
+ teamId: string;
483
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
475
484
  readonly grants: ControlPlaneOperationBinding<{
476
485
  teamId: string;
477
486
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
@@ -559,12 +568,22 @@ export declare const CONTROL_PLANE_OPERATIONS: {
559
568
  readonly run: ControlPlaneOperationBinding<{
560
569
  runId: string;
561
570
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
571
+ readonly validate: ControlPlaneOperationBinding<{}, {}, Record<string, unknown>, Record<string, unknown>>;
562
572
  readonly plan: ControlPlaneOperationBinding<{
563
573
  name: string;
564
- }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
574
+ }, {}, Record<string, unknown>, Record<string, unknown>>;
565
575
  readonly apply: ControlPlaneOperationBinding<{
566
576
  name: string;
567
577
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
578
+ readonly show: ControlPlaneOperationBinding<{
579
+ name: string;
580
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
581
+ readonly verify: ControlPlaneOperationBinding<{
582
+ name: string;
583
+ }, {}, Record<string, unknown>, Record<string, unknown>>;
584
+ readonly reconcile: ControlPlaneOperationBinding<{
585
+ name: string;
586
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
568
587
  readonly resolveResources: ControlPlaneOperationBinding<{}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
569
588
  };
570
589
  readonly feedback: {
@@ -880,6 +899,59 @@ export declare const CONTROL_PLANE_OPERATIONS: {
880
899
  };
881
900
  };
882
901
  readonly providers: {
902
+ readonly list: ControlPlaneOperationBinding<{
903
+ teamId: string;
904
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
905
+ readonly show: ControlPlaneOperationBinding<{
906
+ teamId: string;
907
+ providerId: string;
908
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
909
+ readonly status: ControlPlaneOperationBinding<{
910
+ teamId: string;
911
+ providerId: string;
912
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
913
+ readonly diagnose: ControlPlaneOperationBinding<{
914
+ teamId: string;
915
+ providerId: string;
916
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
917
+ readonly connect: ControlPlaneOperationBinding<{
918
+ teamId: string;
919
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
920
+ readonly disconnect: ControlPlaneOperationBinding<{
921
+ teamId: string;
922
+ connectionId: string;
923
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
924
+ readonly requests: {
925
+ readonly list: ControlPlaneOperationBinding<{
926
+ teamId: string;
927
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
928
+ readonly show: ControlPlaneOperationBinding<{
929
+ teamId: string;
930
+ requestId: string;
931
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
932
+ readonly approve: ControlPlaneOperationBinding<{
933
+ teamId: string;
934
+ requestId: string;
935
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
936
+ readonly reject: ControlPlaneOperationBinding<{
937
+ teamId: string;
938
+ requestId: string;
939
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
940
+ };
941
+ readonly credentials: {
942
+ readonly status: ControlPlaneOperationBinding<{
943
+ teamId: string;
944
+ connectionId: string;
945
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
946
+ readonly rotate: ControlPlaneOperationBinding<{
947
+ teamId: string;
948
+ connectionId: string;
949
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
950
+ readonly revoke: ControlPlaneOperationBinding<{
951
+ teamId: string;
952
+ connectionId: string;
953
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
954
+ };
883
955
  readonly register: ControlPlaneOperationBinding<{}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
884
956
  readonly registration: ControlPlaneOperationBinding<{
885
957
  requestId: string;
@@ -54,6 +54,24 @@ const noPathProvider = (operationId, method, path, options = {}) => define({
54
54
  pagination: "none",
55
55
  redactedPaths: options.redactedPaths
56
56
  }, { path: empty, query: empty, body: method === "GET" ? none : record, output: payload });
57
+ function postRead(operationId, path, pathShape, capability, scopes, surfaces) {
58
+ return define({
59
+ operationId,
60
+ description: `Read ${operationId}.`,
61
+ rest: { method: "POST", path },
62
+ ...Object.keys(pathShape).length ? { parameters: `treeseed.${operationId}.parameters/v1` } : {},
63
+ capability,
64
+ authentication: "oauth",
65
+ oauthScopes: scopes,
66
+ kind: "read",
67
+ riskClass: "ordinary",
68
+ confirmation: "never",
69
+ surfaces,
70
+ cacheScope: "none",
71
+ pagination: "none",
72
+ idempotencyRequired: false
73
+ }, { path: z.object(pathShape).strict(), query: empty, body: record, output: payload });
74
+ }
57
75
  function resource(operationId, method, path, pathShape, options = { capability: "control-plane.use" }) {
58
76
  const kind = method === "GET" ? "read" : "mutation";
59
77
  const riskClass = options.risk ?? "ordinary";
@@ -273,8 +291,11 @@ const CONTROL_PLANE_OPERATIONS = {
273
291
  },
274
292
  capacity: {
275
293
  availability: resource("capacity.status", "GET", "/v1/teams/{teamId}/capacity/availability-sessions", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
294
+ explain: resource("capacity.explain", "GET", "/v1/teams/{teamId}/capacity/explanation", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "cli", "mcp_tool"] }),
276
295
  usage: resource("capacity.usage", "GET", "/v1/teams/{teamId}/capacity/usage", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "cli", "mcp_tool"] }),
277
296
  ledger: resource("capacity.ledger", "GET", "/v1/teams/{teamId}/capacity/ledger", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "cli"], pagination: "cursor" }),
297
+ audit: resource("capacity.audit", "GET", "/v1/teams/{teamId}/capacity/audit", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "cli"], pagination: "cursor" }),
298
+ lanes: resource("capacity.lanes.list", "GET", "/v1/teams/{teamId}/capacity/lanes", { teamId: z.string().min(1) }, { capability: "capacity.read", surfaces: ["rest", "mcp_tool"], pagination: "cursor" }),
278
299
  grants: resource("capacity.grants.list", "GET", "/v1/teams/{teamId}/capacity-grants", { teamId: z.string().min(1) }, { capability: "capacity.read", pagination: "cursor" }),
279
300
  grant: resource("capacity.grants.show", "GET", "/v1/teams/{teamId}/capacity-grants/{grantId}", { teamId: z.string().min(1), grantId: z.string().min(1) }, { capability: "capacity.read" })
280
301
  },
@@ -310,8 +331,12 @@ const CONTROL_PLANE_OPERATIONS = {
310
331
  seeds: {
311
332
  runs: resource("seeds.runs.list", "GET", "/v1/seeds/runs", {}, { capability: "seeds.read", pagination: "cursor" }),
312
333
  run: resource("seeds.runs.show", "GET", "/v1/seeds/runs/{runId}", { runId: z.string().min(1) }, { capability: "seeds.read" }),
313
- plan: resource("seeds.plan", "POST", "/v1/seeds/{name}/plan", { name: z.string().min(1) }, { capability: "seeds.write", scopes: ["treeseed:admin"] }),
314
- apply: resource("seeds.apply", "POST", "/v1/seeds/{name}/apply", { name: z.string().min(1) }, { capability: "seeds.write", scopes: ["treeseed:admin"], risk: "authority" }),
334
+ validate: postRead("seeds.validate", "/v1/seeds/validate", {}, "seeds.read", ["treeseed:admin"], ["rest", "cli"]),
335
+ plan: postRead("seeds.plan", "/v1/seeds/{name}/plan", { name: z.string().min(1) }, "seeds.write", ["treeseed:admin"], ["rest", "cli"]),
336
+ apply: resource("seeds.apply", "POST", "/v1/seeds/{name}/apply", { name: z.string().min(1) }, { capability: "seeds.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "authority" }),
337
+ show: resource("seeds.show", "GET", "/v1/seeds/{name}", { name: z.string().min(1) }, { capability: "seeds.read", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"] }),
338
+ verify: postRead("seeds.verify", "/v1/seeds/{name}/verify", { name: z.string().min(1) }, "seeds.read", ["treeseed:admin"], ["rest", "cli"]),
339
+ reconcile: resource("seeds.reconcile", "POST", "/v1/seeds/{name}/reconcile", { name: z.string().min(1) }, { capability: "seeds.write", scopes: ["treeseed:admin"], risk: "authority" }),
315
340
  resolveResources: resource("seeds.resources.resolve", "POST", "/v1/seeds/resources/resolve", {}, { capability: "seeds.read", scopes: ["treeseed:admin"] })
316
341
  },
317
342
  feedback: {
@@ -418,6 +443,23 @@ const CONTROL_PLANE_OPERATIONS = {
418
443
  }
419
444
  },
420
445
  providers: {
446
+ list: resource("providers.list", "GET", "/v1/teams/{teamId}/capacity-providers", { teamId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
447
+ show: resource("providers.show", "GET", "/v1/teams/{teamId}/capacity-providers/{providerId}", { teamId: z.string().min(1), providerId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli", "mcp_resource"] }),
448
+ 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"] }),
449
+ 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"] }),
450
+ 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"] }),
451
+ 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" }),
452
+ requests: {
453
+ 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" }),
454
+ show: resource("providers.requests.show", "GET", "/v1/teams/{teamId}/capacity-provider-requests/{requestId}", { teamId: z.string().min(1), requestId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli"] }),
455
+ approve: resource("providers.requests.approve", "POST", "/v1/teams/{teamId}/capacity-provider-requests/{requestId}/approve", { teamId: z.string().min(1), requestId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "authority" }),
456
+ reject: resource("providers.requests.reject", "POST", "/v1/teams/{teamId}/capacity-provider-requests/{requestId}/reject", { teamId: z.string().min(1), requestId: z.string().min(1) }, { capability: "providers.write", scopes: ["treeseed:admin"], surfaces: ["rest", "cli"], risk: "authority" })
457
+ },
458
+ credentials: {
459
+ status: resource("providers.credentials.status", "GET", "/v1/teams/{teamId}/capacity-provider-connections/{connectionId}/credentials", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "providers.read", surfaces: ["rest", "cli"] }),
460
+ 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" }),
461
+ 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" })
462
+ },
421
463
  register: noPathProvider("providers.register", "POST", "/v1/provider-registrations", { redactedPaths: ["body.registrationKey"] }),
422
464
  registration: providerPath("providers.registration.show", "GET", "/v1/provider-registrations/{requestId}", { requestId: z.string().min(1) }, { read: true }),
423
465
  exchangeCredential: providerPath("providers.registration.credential", "POST", "/v1/provider-registrations/{requestId}/credential", { requestId: z.string().min(1) }, { redactedPaths: ["body.proof"] }),
@@ -6,3 +6,4 @@ export * from './control-plane-operation.js';
6
6
  export * from './control-plane-operations.js';
7
7
  export * from './mcp.js';
8
8
  export * from './oauth.js';
9
+ export * from './seed/seed-bundle.js';
@@ -6,3 +6,4 @@ export * from "./control-plane-operation.js";
6
6
  export * from "./control-plane-operations.js";
7
7
  export * from "./mcp.js";
8
8
  export * from "./oauth.js";
9
+ export * from "./seed/seed-bundle.js";
@@ -0,0 +1,123 @@
1
+ import type { ProviderLanePurpose } from '../../agent-capacity/contracts/capacity/communication/communication-records.js';
2
+ export declare const SEED_BUNDLE_SCHEMA_VERSION: "treeseed.seed-bundle/v2";
3
+ export type SeedEnvironment = 'local' | 'staging' | 'prod' | string;
4
+ export interface SeedTeamResource {
5
+ key: string;
6
+ slug: string;
7
+ name: string;
8
+ displayName: string;
9
+ profileSummary?: string;
10
+ }
11
+ export interface SeedUserMembershipResource {
12
+ key: string;
13
+ team: string;
14
+ principal: {
15
+ kind: 'user';
16
+ email: string;
17
+ };
18
+ roles: string[];
19
+ missingUser: 'defer' | 'reject';
20
+ }
21
+ export interface SeedServicePrincipalMembershipResource {
22
+ key: string;
23
+ team: string;
24
+ principal: {
25
+ kind: 'service-principal';
26
+ key: string;
27
+ displayName: string;
28
+ interactiveLogin: false;
29
+ };
30
+ roles: string[];
31
+ }
32
+ export type SeedMembershipResource = SeedUserMembershipResource | SeedServicePrincipalMembershipResource;
33
+ export interface SeedRepositoryPolicy {
34
+ visibility: 'public' | 'private';
35
+ lifecycle: 'adopt' | 'create-or-adopt';
36
+ deletionPolicy: 'retain';
37
+ defaultBranch: string;
38
+ stagingBranch: string;
39
+ issues: boolean;
40
+ actions: boolean;
41
+ workflows: string[];
42
+ }
43
+ export interface SeedRepositoryResource {
44
+ key: string;
45
+ project: string;
46
+ role: 'primary' | 'content' | 'fixture' | 'support' | 'template';
47
+ provider: 'github';
48
+ owner: string;
49
+ name: string;
50
+ gitUrl: string;
51
+ defaultBranch: string;
52
+ checkoutPath?: string;
53
+ submodulePath?: string;
54
+ repositoryPolicy: SeedRepositoryPolicy;
55
+ metadata?: Record<string, unknown>;
56
+ }
57
+ export interface SeedProjectResource {
58
+ key: string;
59
+ team: string;
60
+ slug: string;
61
+ name: string;
62
+ description: string;
63
+ kind: string;
64
+ primaryRepository: string;
65
+ metadata?: Record<string, unknown>;
66
+ }
67
+ export interface SeedCapacityProviderPrerequisite {
68
+ key: string;
69
+ team: string;
70
+ environments: SeedEnvironment[];
71
+ manifestDigest: `sha256:${string}`;
72
+ manifestRef: string;
73
+ approval: 'trusted-local-owner';
74
+ projects: string[];
75
+ allowedModes: Array<'planning' | 'acting'>;
76
+ requiredLanePurposes: ProviderLanePurpose[];
77
+ }
78
+ export interface SeedBundleV2 {
79
+ schemaVersion: typeof SEED_BUNDLE_SCHEMA_VERSION;
80
+ name: string;
81
+ version: number;
82
+ description: string;
83
+ environments: SeedEnvironment[];
84
+ digest: `sha256:${string}`;
85
+ resources: {
86
+ teams: SeedTeamResource[];
87
+ memberships: SeedMembershipResource[];
88
+ projects: SeedProjectResource[];
89
+ repositories: SeedRepositoryResource[];
90
+ };
91
+ runtime: {
92
+ capacityProviders: SeedCapacityProviderPrerequisite[];
93
+ };
94
+ }
95
+ export interface SeedResourceReceipt {
96
+ resourceKey: string;
97
+ action: 'create' | 'adopt' | 'update' | 'noop' | 'blocked';
98
+ resourceId?: string;
99
+ digest: `sha256:${string}`;
100
+ readBackAt?: string;
101
+ blockers?: string[];
102
+ }
103
+ export interface SeedReconciliationReceipt {
104
+ schemaVersion: 'treeseed.seed-reconciliation-receipt/v1';
105
+ runId: string;
106
+ seedName: string;
107
+ seedVersion: number;
108
+ seedDigest: `sha256:${string}`;
109
+ mode: 'plan' | 'apply' | 'verify';
110
+ status: 'planned' | 'waiting_provider' | 'verified' | 'blocked' | 'failed';
111
+ resources: SeedResourceReceipt[];
112
+ providerRequestIds: string[];
113
+ createdAt: string;
114
+ completedAt?: string;
115
+ }
116
+ export interface SeedBundleDiagnostic {
117
+ code: string;
118
+ path: string;
119
+ message: string;
120
+ }
121
+ export declare function canonicalSeedBundlePayload(bundle: Omit<SeedBundleV2, 'digest'> | SeedBundleV2): string;
122
+ export declare function digestSeedBundle(bundle: Omit<SeedBundleV2, 'digest'> | SeedBundleV2): Promise<`sha256:${string}`>;
123
+ export declare function validateSeedBundle(bundle: SeedBundleV2): SeedBundleDiagnostic[];
@@ -0,0 +1,50 @@
1
+ const SEED_BUNDLE_SCHEMA_VERSION = "treeseed.seed-bundle/v2";
2
+ function text(value) {
3
+ return typeof value === "string" && value.trim().length > 0;
4
+ }
5
+ function canonical(value) {
6
+ if (Array.isArray(value)) return value.map(canonical);
7
+ if (!value || typeof value !== "object") return value;
8
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, canonical(entry)]));
9
+ }
10
+ function canonicalSeedBundlePayload(bundle) {
11
+ const { digest: _digest, ...payload } = bundle;
12
+ return JSON.stringify(canonical(payload));
13
+ }
14
+ async function digestSeedBundle(bundle) {
15
+ const bytes = new TextEncoder().encode(canonicalSeedBundlePayload(bundle));
16
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
17
+ return `sha256:${Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, "0")).join("")}`;
18
+ }
19
+ function validateSeedBundle(bundle) {
20
+ const diagnostics = [];
21
+ const add = (code, path, message) => diagnostics.push({ code, path, message });
22
+ if (bundle?.schemaVersion !== SEED_BUNDLE_SCHEMA_VERSION) add("seed_bundle_schema_invalid", "schemaVersion", `schemaVersion must be ${SEED_BUNDLE_SCHEMA_VERSION}.`);
23
+ if (!text(bundle?.name) || !Number.isInteger(bundle?.version) || bundle.version < 1) add("seed_bundle_identity_invalid", "name", "Seed name and positive version are required.");
24
+ if (!/^sha256:[a-f0-9]{64}$/u.test(bundle?.digest ?? "")) add("seed_bundle_digest_invalid", "digest", "Seed digest must be an exact SHA-256 digest.");
25
+ const teams = new Set((bundle?.resources?.teams ?? []).map((entry) => entry.key));
26
+ const projects = new Set((bundle?.resources?.projects ?? []).map((entry) => entry.key));
27
+ const repositories = new Set((bundle?.resources?.repositories ?? []).map((entry) => entry.key));
28
+ const allKeys = [...teams, ...projects, ...repositories, ...(bundle?.resources?.memberships ?? []).map((entry) => entry.key)];
29
+ if (new Set(allKeys).size !== allKeys.length) add("seed_bundle_resource_key_duplicate", "resources", "Every resource key must be globally unique.");
30
+ for (const [index, membership] of (bundle?.resources?.memberships ?? []).entries()) {
31
+ if (!teams.has(membership.team)) add("seed_bundle_membership_team_unknown", `resources.memberships[${index}].team`, "Membership references an unknown team.");
32
+ if (membership.principal.kind === "service-principal" && membership.principal.interactiveLogin !== false) add("seed_bundle_service_principal_interactive_forbidden", `resources.memberships[${index}].principal.interactiveLogin`, "Service principals cannot log in interactively.");
33
+ }
34
+ for (const [index, project] of (bundle?.resources?.projects ?? []).entries()) {
35
+ if (!teams.has(project.team)) add("seed_bundle_project_team_unknown", `resources.projects[${index}].team`, "Project references an unknown team.");
36
+ if (!repositories.has(project.primaryRepository)) add("seed_bundle_primary_repository_unknown", `resources.projects[${index}].primaryRepository`, "Project primary repository is missing.");
37
+ }
38
+ for (const [index, provider] of (bundle?.runtime?.capacityProviders ?? []).entries()) {
39
+ if (!teams.has(provider.team)) add("seed_bundle_provider_team_unknown", `runtime.capacityProviders[${index}].team`, "Provider references an unknown team.");
40
+ for (const project of provider.projects) if (!projects.has(project)) add("seed_bundle_provider_project_unknown", `runtime.capacityProviders[${index}].projects`, `Provider references unknown project ${project}.`);
41
+ for (const purpose of ["communication", "platform", "workday"]) if (!provider.requiredLanePurposes.includes(purpose)) add("seed_bundle_provider_lane_required", `runtime.capacityProviders[${index}].requiredLanePurposes`, `Provider prerequisite requires the ${purpose} lane.`);
42
+ }
43
+ return diagnostics;
44
+ }
45
+ export {
46
+ SEED_BUNDLE_SCHEMA_VERSION,
47
+ canonicalSeedBundlePayload,
48
+ digestSeedBundle,
49
+ validateSeedBundle
50
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.19",
3
+ "version": "0.13.0-rc.20",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {