@treeseed/sdk 0.13.0-rc.12 → 0.13.0-rc.14

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.
@@ -7,6 +7,7 @@ export type ControlPlaneConfirmationPolicy = 'never' | 'input_required';
7
7
  export type ControlPlaneOperationSurface = 'rest' | 'cli' | 'mcp_tool' | 'mcp_resource' | 'internal';
8
8
  export type ControlPlaneCacheScope = 'none' | 'principal' | 'team' | 'project' | 'public';
9
9
  export type ControlPlanePaginationKind = 'none' | 'cursor';
10
+ export type ControlPlaneAuthenticationKind = 'anonymous' | 'oauth' | 'oauth_or_provider' | 'provider' | 'signed_request';
10
11
  export interface ControlPlaneRestBinding {
11
12
  method: ControlPlaneHttpMethod;
12
13
  path: `/v1/${string}`;
@@ -33,6 +34,7 @@ export interface ControlPlaneOperationDescriptor {
33
34
  rest?: ControlPlaneRestBinding;
34
35
  schemas: ControlPlaneSchemaBinding;
35
36
  capability: string;
37
+ authentication: ControlPlaneAuthenticationKind;
36
38
  oauthScopes: OAuthScope[];
37
39
  kind: ControlPlaneOperationKind;
38
40
  riskClass: ControlPlaneRiskClass;
@@ -44,6 +44,15 @@ function validateControlPlaneCatalog(catalog) {
44
44
  for (const scope of operation.oauthScopes) {
45
45
  if (!TREESEED_OAUTH_SCOPES.includes(scope)) diagnostics.push({ code: "oauth_scope_invalid", path: `${path}.oauthScopes`, message: `Unknown OAuth scope ${scope}.` });
46
46
  }
47
+ if (["oauth", "oauth_or_provider"].includes(operation.authentication) && operation.oauthScopes.length === 0) {
48
+ diagnostics.push({ code: "oauth_scope_required", path: `${path}.oauthScopes`, message: "OAuth-authenticated operations require at least one OAuth scope." });
49
+ }
50
+ if (!["oauth", "oauth_or_provider"].includes(operation.authentication) && operation.oauthScopes.length > 0) {
51
+ diagnostics.push({ code: "oauth_scope_forbidden", path: `${path}.oauthScopes`, message: "Only OAuth-authenticated operations may declare OAuth scopes." });
52
+ }
53
+ if (operation.authentication === "provider" && operation.capability !== "providers.execute") {
54
+ diagnostics.push({ code: "provider_auth_capability_invalid", path: `${path}.capability`, message: "Provider-authenticated operations require providers.execute." });
55
+ }
47
56
  for (const duplicate of duplicates(operation.surfaces)) diagnostics.push({ code: "surface_duplicate", path: `${path}.surfaces`, message: `Duplicate operation surface ${duplicate}.` });
48
57
  for (const duplicate of duplicates(operation.oauthScopes)) diagnostics.push({ code: "oauth_scope_duplicate", path: `${path}.oauthScopes`, message: `Duplicate OAuth scope ${duplicate}.` });
49
58
  const elevatedRisk = operation.riskClass !== "ordinary";
@@ -496,6 +496,53 @@ export declare const CONTROL_PLANE_OPERATIONS: {
496
496
  actionId: string;
497
497
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
498
498
  };
499
+ readonly treedx: {
500
+ readonly library: ControlPlaneOperationBinding<{
501
+ projectId: string;
502
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
503
+ readonly bindLibrary: ControlPlaneOperationBinding<{
504
+ projectId: string;
505
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
506
+ readonly createRepository: ControlPlaneOperationBinding<{
507
+ projectId: string;
508
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
509
+ readonly createWorkspace: ControlPlaneOperationBinding<{
510
+ projectId: string;
511
+ repoId: string;
512
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
513
+ readonly readWorkspaceFile: ControlPlaneOperationBinding<{
514
+ projectId: string;
515
+ workspaceId: string;
516
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
517
+ readonly applyChangeset: ControlPlaneOperationBinding<{
518
+ projectId: string;
519
+ workspaceId: string;
520
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
521
+ readonly searchWorkspace: ControlPlaneOperationBinding<{
522
+ projectId: string;
523
+ workspaceId: string;
524
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
525
+ readonly commitWorkspace: ControlPlaneOperationBinding<{
526
+ projectId: string;
527
+ workspaceId: string;
528
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
529
+ readonly closeWorkspace: ControlPlaneOperationBinding<{
530
+ projectId: string;
531
+ workspaceId: string;
532
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
533
+ readonly readRepositoryFiles: ControlPlaneOperationBinding<{
534
+ projectId: string;
535
+ repoId: string;
536
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
537
+ readonly listRepositoryPaths: ControlPlaneOperationBinding<{
538
+ projectId: string;
539
+ repoId: string;
540
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
541
+ readonly buildRepositoryContext: ControlPlaneOperationBinding<{
542
+ projectId: string;
543
+ repoId: string;
544
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
545
+ };
499
546
  readonly providers: {
500
547
  readonly register: ControlPlaneOperationBinding<{}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
501
548
  readonly registration: ControlPlaneOperationBinding<{
@@ -12,6 +12,7 @@ function define(definition, schema) {
12
12
  return {
13
13
  descriptor: {
14
14
  ...descriptor,
15
+ authentication: definition.authentication ?? (definition.oauthScopes.length ? "oauth" : "anonymous"),
15
16
  schemaVersion: CONTROL_PLANE_OPERATION_SCHEMA_VERSION,
16
17
  schemas: {
17
18
  input: `treeseed.${definition.operationId}.input/v1`,
@@ -34,6 +35,7 @@ function read(operationId, path, capability, surfaces = ["rest"]) {
34
35
  description: `Read ${operationId}.`,
35
36
  rest: { method: "GET", path },
36
37
  capability,
38
+ authentication: "oauth",
37
39
  oauthScopes: ["treeseed:read"],
38
40
  kind: "read",
39
41
  riskClass: "ordinary",
@@ -51,7 +53,8 @@ function providerPath(operationId, method, path, pathShape, options = {}) {
51
53
  rest: { method, path },
52
54
  parameters: `treeseed.${operationId}.parameters/v1`,
53
55
  capability: "providers.execute",
54
- oauthScopes: ["treeseed:execution"],
56
+ authentication: "provider",
57
+ oauthScopes: [],
55
58
  kind,
56
59
  riskClass: "ordinary",
57
60
  confirmation: "never",
@@ -66,7 +69,8 @@ const noPathProvider = (operationId, method, path, options = {}) => define({
66
69
  description: `${options.read ? "Read" : "Apply"} ${operationId}.`,
67
70
  rest: { method, path },
68
71
  capability: "providers.execute",
69
- oauthScopes: ["treeseed:execution"],
72
+ authentication: "provider",
73
+ oauthScopes: [],
70
74
  kind: options.read ? "read" : "mutation",
71
75
  riskClass: "ordinary",
72
76
  confirmation: "never",
@@ -84,6 +88,7 @@ function resource(operationId, method, path, pathShape, options = { capability:
84
88
  rest: { method, path },
85
89
  ...Object.keys(pathShape).length ? { parameters: `treeseed.${operationId}.parameters/v1` } : {},
86
90
  capability: options.capability,
91
+ authentication: options.authentication ?? ((options.scopes ?? (kind === "read" ? ["treeseed:read"] : ["treeseed:projects:write"])).length ? "oauth" : "anonymous"),
87
92
  oauthScopes: options.scopes ?? (kind === "read" ? ["treeseed:read"] : ["treeseed:projects:write"]),
88
93
  kind,
89
94
  riskClass,
@@ -162,7 +167,7 @@ const CONTROL_PLANE_OPERATIONS = {
162
167
  members: resource("teams.members.list", "GET", "/v1/teams/{teamId}/members", { teamId: z.string().min(1) }, { capability: "teams.read", pagination: "cursor" }),
163
168
  invite: resource("teams.invites.create", "POST", "/v1/teams/{teamId}/invites", { teamId: z.string().min(1) }, { capability: "teams.write" }),
164
169
  invites: resource("teams.invites.list", "GET", "/v1/teams/{teamId}/invites", { teamId: z.string().min(1) }, { capability: "teams.read", pagination: "cursor" }),
165
- inviteShow: resource("teams.invites.show", "GET", "/v1/team-invites/{token}", { token: z.string().min(1) }, { capability: "teams.join", scopes: [], redactedPaths: ["path.token"] }),
170
+ inviteShow: resource("teams.invites.show", "GET", "/v1/team-invites/{token}", { token: z.string().min(1) }, { capability: "teams.join", scopes: [], authentication: "signed_request", redactedPaths: ["path.token"] }),
166
171
  inviteAccept: resource("teams.invites.accept", "POST", "/v1/team-invites/{token}/accept", { token: z.string().min(1) }, { capability: "teams.join", redactedPaths: ["path.token"] }),
167
172
  updateMember: resource("teams.members.update", "PATCH", "/v1/teams/{teamId}/members/{membershipId}", { teamId: z.string().min(1), membershipId: z.string().min(1) }, { capability: "teams.write", concurrency: true }),
168
173
  removeMember: resource("teams.members.delete", "DELETE", "/v1/teams/{teamId}/members/{membershipId}", { teamId: z.string().min(1), membershipId: z.string().min(1) }, { capability: "teams.write", risk: "destructive", concurrency: true }),
@@ -218,8 +223,8 @@ const CONTROL_PLANE_OPERATIONS = {
218
223
  },
219
224
  repositories: {
220
225
  githubSetup: resource("repositories.github.setup", "POST", "/v1/provider-connectors/github/{kind}/setup", { kind: z.string().min(1) }, { capability: "repositories.connect", scopes: ["treeseed:projects:write"], risk: "authority" }),
221
- githubCallback: resource("repositories.github.callback", "GET", "/v1/provider-connectors/github/{kind}/callback", { kind: z.string().min(1) }, { capability: "repositories.connect", scopes: [] }),
222
- githubWebhook: resource("repositories.github.webhook", "POST", "/v1/provider-webhooks/github/{kind}", { kind: z.string().min(1) }, { capability: "repositories.webhook", scopes: [], redactedPaths: ["body"] }),
226
+ githubCallback: resource("repositories.github.callback", "GET", "/v1/provider-connectors/github/{kind}/callback", { kind: z.string().min(1) }, { capability: "repositories.connect", scopes: [], authentication: "signed_request" }),
227
+ githubWebhook: resource("repositories.github.webhook", "POST", "/v1/provider-webhooks/github/{kind}", { kind: z.string().min(1) }, { capability: "repositories.webhook", scopes: [], authentication: "signed_request", redactedPaths: ["body"] }),
223
228
  workflowOperations: resource("repositories.workflows.list", "GET", "/v1/projects/{projectId}/workflow-operations", { projectId: z.string().min(1) }, { capability: "workflows.read", pagination: "cursor" }),
224
229
  workflowRuns: resource("repositories.workflow.runs.list", "GET", "/v1/projects/{projectId}/workflow-operation-runs", { projectId: z.string().min(1) }, { capability: "workflows.read", pagination: "cursor" }),
225
230
  updateWorkflow: resource("repositories.workflows.update", "PUT", "/v1/projects/{projectId}/workflow-operations/{operationId}", { projectId: z.string().min(1), operationId: z.string().min(1) }, { capability: "workflows.write", concurrency: true }),
@@ -309,6 +314,20 @@ const CONTROL_PLANE_OPERATIONS = {
309
314
  actions: resource("realtime.actions.list", "GET", "/v1/client-sessions/{sessionId}/actions", { sessionId: z.string().min(1) }, { capability: "realtime.read", pagination: "cursor" }),
310
315
  actionResult: resource("realtime.actions.result", "POST", "/v1/client-sessions/{sessionId}/actions/{actionId}/result", { sessionId: z.string().min(1), actionId: z.string().min(1) }, { capability: "realtime.write" })
311
316
  },
317
+ treedx: {
318
+ library: resource("treedx.library.show", "GET", "/v1/projects/{projectId}/treedx-library", { projectId: z.string().min(1) }, { capability: "treedx.read" }),
319
+ bindLibrary: resource("treedx.library.bind", "POST", "/v1/projects/{projectId}/treedx-library", { projectId: z.string().min(1) }, { capability: "treedx.write" }),
320
+ createRepository: resource("treedx.repositories.create", "POST", "/v1/dx/projects/{projectId}/repos", { projectId: z.string().min(1) }, { capability: "treedx.write", authentication: "oauth_or_provider" }),
321
+ createWorkspace: resource("treedx.workspaces.create", "POST", "/v1/dx/projects/{projectId}/repos/{repoId}/workspaces", { projectId: z.string().min(1), repoId: z.string().min(1) }, { capability: "treedx.write", authentication: "oauth_or_provider" }),
322
+ readWorkspaceFile: resource("treedx.workspaces.files.read", "GET", "/v1/dx/projects/{projectId}/workspaces/{workspaceId}/files", { projectId: z.string().min(1), workspaceId: z.string().min(1) }, { capability: "treedx.read", authentication: "oauth_or_provider" }),
323
+ applyChangeset: resource("treedx.workspaces.changesets.apply", "POST", "/v1/dx/projects/{projectId}/workspaces/{workspaceId}/changesets", { projectId: z.string().min(1), workspaceId: z.string().min(1) }, { capability: "treedx.write", authentication: "oauth_or_provider" }),
324
+ searchWorkspace: resource("treedx.workspaces.search", "POST", "/v1/dx/projects/{projectId}/workspaces/{workspaceId}/search", { projectId: z.string().min(1), workspaceId: z.string().min(1) }, { capability: "treedx.read", authentication: "oauth_or_provider", scopes: ["treeseed:read"] }),
325
+ commitWorkspace: resource("treedx.workspaces.commit", "POST", "/v1/dx/projects/{projectId}/workspaces/{workspaceId}/commit", { projectId: z.string().min(1), workspaceId: z.string().min(1) }, { capability: "treedx.write", authentication: "oauth_or_provider" }),
326
+ closeWorkspace: resource("treedx.workspaces.close", "POST", "/v1/dx/projects/{projectId}/workspaces/{workspaceId}/close", { projectId: z.string().min(1), workspaceId: z.string().min(1) }, { capability: "treedx.write", authentication: "oauth_or_provider" }),
327
+ readRepositoryFiles: resource("treedx.repositories.files.read", "POST", "/v1/dx/projects/{projectId}/repos/{repoId}/files/read", { projectId: z.string().min(1), repoId: z.string().min(1) }, { capability: "treedx.read", authentication: "oauth_or_provider", scopes: ["treeseed:read"] }),
328
+ listRepositoryPaths: resource("treedx.repositories.paths.list", "POST", "/v1/dx/projects/{projectId}/repos/{repoId}/paths/list", { projectId: z.string().min(1), repoId: z.string().min(1) }, { capability: "treedx.read", authentication: "oauth_or_provider", scopes: ["treeseed:read"] }),
329
+ buildRepositoryContext: resource("treedx.repositories.context.build", "POST", "/v1/dx/projects/{projectId}/repos/{repoId}/context/build", { projectId: z.string().min(1), repoId: z.string().min(1) }, { capability: "treedx.read", authentication: "oauth_or_provider", scopes: ["treeseed:read"] })
330
+ },
312
331
  providers: {
313
332
  register: noPathProvider("providers.register", "POST", "/v1/provider-registrations", { redactedPaths: ["body.registrationKey"] }),
314
333
  registration: providerPath("providers.registration.show", "GET", "/v1/provider-registrations/{requestId}", { requestId: z.string().min(1) }, { read: true }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.12",
3
+ "version": "0.13.0-rc.14",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {