@treeseed/sdk 0.13.0-rc.17 → 0.13.0-rc.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-capacity/validation/agent-definition-schema.d.ts +84 -84
- package/dist/agent-capacity/validation/agent-lab-forensics-schema.d.ts +1 -1
- package/dist/content/validation/agent-operational-content-schemas.d.ts +24 -24
- package/dist/content/validation/auxiliary-content-schemas.d.ts +8 -8
- package/dist/content/validation/content-model-schemas.d.ts +192 -192
- package/dist/content/validation/portable-content-data.d.ts +19 -19
- package/dist/entrypoints/clients/control-plane-client.d.ts +2 -0
- package/dist/entrypoints/clients/control-plane-client.js +8 -2
- package/dist/operator-contracts/canonical-command-tree.js +64 -4
- package/dist/operator-contracts/command-tree.d.ts +28 -0
- package/dist/operator-contracts/command-tree.js +49 -0
- package/dist/operator-contracts/control-plane-operations.d.ts +2 -2
- package/dist/operator-contracts/control-plane-operations.js +4 -4
- package/dist/operator-contracts/mcp.d.ts +1 -0
- package/dist/operator-contracts/mcp.js +7 -0
- package/package.json +1 -1
|
@@ -650,8 +650,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
650
650
|
}>, "many">>;
|
|
651
651
|
requiresArtifactKinds: import("zod").ZodOptional<import("zod").ZodEffects<import("zod").ZodArray<import("zod").ZodString, "many">, string[], string[]>>;
|
|
652
652
|
}, "strict", import("zod").ZodTypeAny, {
|
|
653
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
654
653
|
objective?: string | undefined;
|
|
654
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
655
655
|
proposalTypes?: string[] | undefined;
|
|
656
656
|
artifactKind?: string | undefined;
|
|
657
657
|
subjectModel?: string | undefined;
|
|
@@ -681,8 +681,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
681
681
|
}[] | undefined;
|
|
682
682
|
requiresArtifactKinds?: string[] | undefined;
|
|
683
683
|
}, {
|
|
684
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
685
684
|
objective?: string | undefined;
|
|
685
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
686
686
|
proposalTypes?: string[] | undefined;
|
|
687
687
|
artifactKind?: string | undefined;
|
|
688
688
|
subjectModel?: string | undefined;
|
|
@@ -728,8 +728,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
728
728
|
}, "strict", import("zod").ZodTypeAny, {
|
|
729
729
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
730
730
|
projectId?: string | undefined;
|
|
731
|
-
teamId?: string | undefined;
|
|
732
731
|
agentSlug?: string | undefined;
|
|
732
|
+
teamId?: string | undefined;
|
|
733
733
|
requiredRoles?: string[] | undefined;
|
|
734
734
|
allowedRoles?: string[] | undefined;
|
|
735
735
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -739,8 +739,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
739
739
|
}, {
|
|
740
740
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
741
741
|
projectId?: string | undefined;
|
|
742
|
-
teamId?: string | undefined;
|
|
743
742
|
agentSlug?: string | undefined;
|
|
743
|
+
teamId?: string | undefined;
|
|
744
744
|
requiredRoles?: string[] | undefined;
|
|
745
745
|
allowedRoles?: string[] | undefined;
|
|
746
746
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -752,8 +752,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
752
752
|
defaultAnswerPolicy?: {
|
|
753
753
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
754
754
|
projectId?: string | undefined;
|
|
755
|
-
teamId?: string | undefined;
|
|
756
755
|
agentSlug?: string | undefined;
|
|
756
|
+
teamId?: string | undefined;
|
|
757
757
|
requiredRoles?: string[] | undefined;
|
|
758
758
|
allowedRoles?: string[] | undefined;
|
|
759
759
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -766,8 +766,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
766
766
|
defaultAnswerPolicy?: {
|
|
767
767
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
768
768
|
projectId?: string | undefined;
|
|
769
|
-
teamId?: string | undefined;
|
|
770
769
|
agentSlug?: string | undefined;
|
|
770
|
+
teamId?: string | undefined;
|
|
771
771
|
requiredRoles?: string[] | undefined;
|
|
772
772
|
allowedRoles?: string[] | undefined;
|
|
773
773
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -976,8 +976,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
976
976
|
publishes?: string[] | undefined;
|
|
977
977
|
} | undefined;
|
|
978
978
|
planningIntent?: {
|
|
979
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
980
979
|
objective?: string | undefined;
|
|
980
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
981
981
|
proposalTypes?: string[] | undefined;
|
|
982
982
|
artifactKind?: string | undefined;
|
|
983
983
|
subjectModel?: string | undefined;
|
|
@@ -1011,8 +1011,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1011
1011
|
defaultAnswerPolicy?: {
|
|
1012
1012
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
1013
1013
|
projectId?: string | undefined;
|
|
1014
|
-
teamId?: string | undefined;
|
|
1015
1014
|
agentSlug?: string | undefined;
|
|
1015
|
+
teamId?: string | undefined;
|
|
1016
1016
|
requiredRoles?: string[] | undefined;
|
|
1017
1017
|
allowedRoles?: string[] | undefined;
|
|
1018
1018
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -1149,8 +1149,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1149
1149
|
publishes?: string[] | undefined;
|
|
1150
1150
|
} | undefined;
|
|
1151
1151
|
planningIntent?: {
|
|
1152
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1153
1152
|
objective?: string | undefined;
|
|
1153
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1154
1154
|
proposalTypes?: string[] | undefined;
|
|
1155
1155
|
artifactKind?: string | undefined;
|
|
1156
1156
|
subjectModel?: string | undefined;
|
|
@@ -1184,8 +1184,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1184
1184
|
defaultAnswerPolicy?: {
|
|
1185
1185
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
1186
1186
|
projectId?: string | undefined;
|
|
1187
|
-
teamId?: string | undefined;
|
|
1188
1187
|
agentSlug?: string | undefined;
|
|
1188
|
+
teamId?: string | undefined;
|
|
1189
1189
|
requiredRoles?: string[] | undefined;
|
|
1190
1190
|
allowedRoles?: string[] | undefined;
|
|
1191
1191
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -1322,8 +1322,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1322
1322
|
publishes?: string[] | undefined;
|
|
1323
1323
|
} | undefined;
|
|
1324
1324
|
planningIntent?: {
|
|
1325
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1326
1325
|
objective?: string | undefined;
|
|
1326
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1327
1327
|
proposalTypes?: string[] | undefined;
|
|
1328
1328
|
artifactKind?: string | undefined;
|
|
1329
1329
|
subjectModel?: string | undefined;
|
|
@@ -1357,8 +1357,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1357
1357
|
defaultAnswerPolicy?: {
|
|
1358
1358
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
1359
1359
|
projectId?: string | undefined;
|
|
1360
|
-
teamId?: string | undefined;
|
|
1361
1360
|
agentSlug?: string | undefined;
|
|
1361
|
+
teamId?: string | undefined;
|
|
1362
1362
|
requiredRoles?: string[] | undefined;
|
|
1363
1363
|
allowedRoles?: string[] | undefined;
|
|
1364
1364
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -1495,8 +1495,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1495
1495
|
publishes?: string[] | undefined;
|
|
1496
1496
|
} | undefined;
|
|
1497
1497
|
planningIntent?: {
|
|
1498
|
-
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1499
1498
|
objective?: string | undefined;
|
|
1499
|
+
stage?: "closeout" | "revision" | "discovery" | "synthesis" | "deliberation" | "evaluation" | undefined;
|
|
1500
1500
|
proposalTypes?: string[] | undefined;
|
|
1501
1501
|
artifactKind?: string | undefined;
|
|
1502
1502
|
subjectModel?: string | undefined;
|
|
@@ -1530,8 +1530,8 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1530
1530
|
defaultAnswerPolicy?: {
|
|
1531
1531
|
kind: "team-human" | "human-or-agent" | "specific-human" | "specific-agent";
|
|
1532
1532
|
projectId?: string | undefined;
|
|
1533
|
-
teamId?: string | undefined;
|
|
1534
1533
|
agentSlug?: string | undefined;
|
|
1534
|
+
teamId?: string | undefined;
|
|
1535
1535
|
requiredRoles?: string[] | undefined;
|
|
1536
1536
|
allowedRoles?: string[] | undefined;
|
|
1537
1537
|
allowedAgentIds?: string[] | undefined;
|
|
@@ -1568,10 +1568,10 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1568
1568
|
model: string;
|
|
1569
1569
|
priority: number;
|
|
1570
1570
|
status?: string | undefined;
|
|
1571
|
+
reason?: string | undefined;
|
|
1571
1572
|
title?: string | undefined;
|
|
1572
1573
|
slug?: string | undefined;
|
|
1573
1574
|
estimatedCredits?: number | undefined;
|
|
1574
|
-
reason?: string | undefined;
|
|
1575
1575
|
}[];
|
|
1576
1576
|
totalTasks: number;
|
|
1577
1577
|
completedTasks: number;
|
|
@@ -1709,9 +1709,9 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1709
1709
|
id: string;
|
|
1710
1710
|
required: boolean;
|
|
1711
1711
|
description: string;
|
|
1712
|
+
query: string;
|
|
1712
1713
|
title: string;
|
|
1713
1714
|
revision: number;
|
|
1714
|
-
query: string;
|
|
1715
1715
|
filters: Record<string, unknown>;
|
|
1716
1716
|
target: {
|
|
1717
1717
|
kind: "code" | "content" | "mixed" | "graph";
|
|
@@ -1763,15 +1763,15 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1763
1763
|
id: string;
|
|
1764
1764
|
status: "active" | "completed" | "ready" | "superseded" | "draft";
|
|
1765
1765
|
projectId: string;
|
|
1766
|
+
teamId: string;
|
|
1767
|
+
objective: string;
|
|
1766
1768
|
completed: {
|
|
1767
1769
|
id: string;
|
|
1768
1770
|
description: string;
|
|
1769
1771
|
title: string;
|
|
1770
1772
|
}[];
|
|
1771
|
-
teamId: string;
|
|
1772
1773
|
title: string;
|
|
1773
1774
|
revision: number;
|
|
1774
|
-
objective: string;
|
|
1775
1775
|
createdAt: Date;
|
|
1776
1776
|
remaining: {
|
|
1777
1777
|
id: string;
|
|
@@ -1804,10 +1804,10 @@ export declare function validatePortableContentData(model: string, value: unknow
|
|
|
1804
1804
|
sequence: number;
|
|
1805
1805
|
phase: string;
|
|
1806
1806
|
description?: string | undefined;
|
|
1807
|
+
reason?: string | undefined;
|
|
1807
1808
|
assignmentId?: string | undefined;
|
|
1808
1809
|
updatedAt?: Date | undefined;
|
|
1809
1810
|
workdayId?: string | undefined;
|
|
1810
|
-
reason?: string | undefined;
|
|
1811
1811
|
previousStatusRef?: {
|
|
1812
1812
|
id: string;
|
|
1813
1813
|
revision: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ControlPlaneOperationBinding, ControlPlaneOperationBody, ControlPlaneOperationOutput, ControlPlaneOperationPath, ControlPlaneOperationQuery, OAuthScope } from '../../operator-contracts/control-plane-operation.js';
|
|
2
2
|
import type { ApiPrincipal } from '../../operator-contracts/oauth.js';
|
|
3
|
+
import type { InputRequired } from '../../operator-contracts/mcp.js';
|
|
3
4
|
export declare const DEFAULT_CONTROL_PLANE_BASE_URL = "http://127.0.0.1:3002";
|
|
4
5
|
export declare const CONTROL_PLANE_BASE_URL_ENV = "TREESEED_API_BASE_URL";
|
|
5
6
|
export interface ControlPlaneServerProfile {
|
|
@@ -58,6 +59,7 @@ export interface ProblemDetails {
|
|
|
58
59
|
requestId?: string;
|
|
59
60
|
traceId?: string;
|
|
60
61
|
fields?: Record<string, string[]>;
|
|
62
|
+
inputRequired?: InputRequired;
|
|
61
63
|
}
|
|
62
64
|
export interface ControlPlaneCallOptions {
|
|
63
65
|
method?: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';
|
|
@@ -67,7 +67,8 @@ function problemFrom(payload, status) {
|
|
|
67
67
|
code: typeof source.code === "string" ? source.code : "control_plane_request_failed",
|
|
68
68
|
requestId: typeof source.requestId === "string" ? source.requestId : void 0,
|
|
69
69
|
traceId: typeof source.traceId === "string" ? source.traceId : void 0,
|
|
70
|
-
fields: source.fields && typeof source.fields === "object" ? source.fields : void 0
|
|
70
|
+
fields: source.fields && typeof source.fields === "object" ? source.fields : void 0,
|
|
71
|
+
inputRequired: source.inputRequired && typeof source.inputRequired === "object" ? source.inputRequired : void 0
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
class ControlPlaneClient {
|
|
@@ -132,7 +133,12 @@ class ControlPlaneClient {
|
|
|
132
133
|
async exchangeOAuthToken(values, signal) {
|
|
133
134
|
const response = await this.fetchImpl(`${this.baseUrl}/oauth/token`, { method: "POST", headers: { accept: "application/json", "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams(values), signal });
|
|
134
135
|
const payload = await responsePayload(response);
|
|
135
|
-
if (!response.ok)
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
const problem = problemFrom(payload, response.status);
|
|
138
|
+
problem.code = typeof payload.error === "string" ? payload.error : problem.code;
|
|
139
|
+
problem.detail = typeof payload.error_description === "string" ? payload.error_description : problem.detail;
|
|
140
|
+
throw new ControlPlaneClientError(problem.detail ?? problem.code, response.status, problem, response.headers);
|
|
141
|
+
}
|
|
136
142
|
return { tokenType: "Bearer", accessToken: String(payload.access_token), refreshToken: typeof payload.refresh_token === "string" ? payload.refresh_token : void 0, expiresIn: Number(payload.expires_in), scope: String(payload.scope ?? "").split(/\s+/u).filter(Boolean), audience: String(payload.audience ?? this.baseUrl), principal: payload.principal && typeof payload.principal === "object" ? payload.principal : void 0 };
|
|
137
143
|
}
|
|
138
144
|
async request(options) {
|
|
@@ -1,3 +1,53 @@
|
|
|
1
|
+
const unavailable = (reason = "This capability is not enabled until its control-plane operation is accepted.") => ({
|
|
2
|
+
kind: "unavailable",
|
|
3
|
+
code: "standards_migration_not_enabled",
|
|
4
|
+
reason
|
|
5
|
+
});
|
|
6
|
+
const protocol = (handlerId) => ({ kind: "protocol", handlerId });
|
|
7
|
+
const local = (handlerId) => ({ kind: "local", handlerId });
|
|
8
|
+
const field = (target, name, source, sourceName = name, required = false, transform = "identity") => ({ target, field: name, source, name: sourceName, required, transform });
|
|
9
|
+
const operation = (operationId, input = []) => ({ kind: "operation", operationId, input });
|
|
10
|
+
const page = () => [field("query", "status", "option"), field("query", "limit", "option", "limit", false, "integer"), field("query", "cursor", "option")];
|
|
11
|
+
const operationBindings = {
|
|
12
|
+
"auth login": protocol("protocol.oauth.device.login"),
|
|
13
|
+
"auth logout": protocol("protocol.oauth.revoke"),
|
|
14
|
+
"auth status": operation("accounts.current.show"),
|
|
15
|
+
"secrets list": local("local.secrets.list"),
|
|
16
|
+
"secrets status": local("local.secrets.status"),
|
|
17
|
+
"secrets unlock": local("local.secrets.unlock"),
|
|
18
|
+
"secrets lock": local("local.secrets.lock"),
|
|
19
|
+
"secrets rotate": local("local.secrets.rotate"),
|
|
20
|
+
"agents list": operation("agents.list", [field("path", "projectId", "context", "project", true), ...page()]),
|
|
21
|
+
"agents show": operation("agents.show", [field("path", "projectId", "context", "project", true), field("path", "agentSlug", "argument", "agent", true)]),
|
|
22
|
+
"agents classes list": operation("agents.classes.list", [field("path", "projectId", "context", "project", true)]),
|
|
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)]),
|
|
30
|
+
"capacity status": operation("capacity.status", [field("path", "teamId", "context", "team", true), ...page()]),
|
|
31
|
+
"capacity usage": operation("capacity.usage", [field("path", "teamId", "context", "team", true)]),
|
|
32
|
+
"capacity ledger": operation("capacity.ledger", [field("path", "teamId", "context", "team", true), ...page()]),
|
|
33
|
+
"plans list": operation("plans.list", [field("path", "decisionId", "option", "decision", true), ...page()]),
|
|
34
|
+
"plans show": operation("plans.show", [field("path", "capacityPlanId", "argument", "plan", true)]),
|
|
35
|
+
"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")]),
|
|
36
|
+
"workdays start": operation("workdays.start", [field("path", "teamId", "context", "team", true), field("body", "preflightId", "option", "preflight", true), field("body", "digest", "option", "digest", true)]),
|
|
37
|
+
"workdays list": operation("workdays.list", [field("path", "teamId", "context", "team", true), ...page()]),
|
|
38
|
+
"workdays show": operation("workdays.show", [field("path", "teamId", "context", "team", true), field("path", "runId", "argument", "workday", true)]),
|
|
39
|
+
"workdays schedules list": operation("workdays.schedules.list", [field("path", "teamId", "context", "team", true)]),
|
|
40
|
+
"workdays schedules start": operation("workdays.schedules.create", [field("path", "teamId", "context", "team", true), field("body", "profile", "option"), field("body", "projects", "option", "projects", false, "csv"), field("body", "duration", "option", "duration", false, "integer")]),
|
|
41
|
+
"assignments list": operation("assignments.list", [field("path", "teamId", "context", "team", true), ...page()]),
|
|
42
|
+
"assignments show": operation("assignments.show", [field("path", "teamId", "context", "team", true), field("path", "assignmentId", "argument", "assignment", true)]),
|
|
43
|
+
"assignments explain": operation("assignments.explain", [field("path", "teamId", "context", "team", true), field("path", "assignmentId", "argument", "assignment", true)]),
|
|
44
|
+
"assignments retry": operation("assignments.retry", [field("path", "teamId", "context", "team", true), field("path", "assignmentId", "argument", "assignment", true), field("body", "reason", "option")]),
|
|
45
|
+
"assignments cancel": operation("assignments.cancel", [field("path", "teamId", "context", "team", true), field("path", "assignmentId", "argument", "assignment", true), field("body", "reason", "option")]),
|
|
46
|
+
"status": operation("status.show"),
|
|
47
|
+
"save": unavailable("Unified GitHub-backed save is intentionally fail-closed during this cutover."),
|
|
48
|
+
"stage": unavailable("Unified GitHub-backed stage is intentionally fail-closed during this cutover."),
|
|
49
|
+
"release": unavailable("Production release is intentionally fail-closed during this cutover.")
|
|
50
|
+
};
|
|
1
51
|
const planOption = { name: "--plan", description: "Return the exact proposed outcome without mutation.", type: "boolean" };
|
|
2
52
|
function leaf(segment, kind = "read", argument, confirmation = "never") {
|
|
3
53
|
const value = {
|
|
@@ -7,14 +57,15 @@ function leaf(segment, kind = "read", argument, confirmation = "never") {
|
|
|
7
57
|
arguments: argument ? [{ name: argument, description: `${argument} identity or path.`, required: true }] : void 0,
|
|
8
58
|
options: kind === "mutation" ? [planOption] : void 0,
|
|
9
59
|
authorization: kind === "mutation" ? { capability: `command.${segment}`, confirmation } : void 0,
|
|
10
|
-
resultSchemaId: `treeseed.command.${segment}/v1
|
|
60
|
+
resultSchemaId: `treeseed.command.${segment}/v1`,
|
|
61
|
+
execution: unavailable()
|
|
11
62
|
};
|
|
12
63
|
return { nodeType: "leaf", ...value };
|
|
13
64
|
}
|
|
14
65
|
function branch(segment, children) {
|
|
15
66
|
return { nodeType: "branch", segment, description: `${segment[0].toUpperCase()}${segment.slice(1)} operations.`, children };
|
|
16
67
|
}
|
|
17
|
-
const
|
|
68
|
+
const commandTree = {
|
|
18
69
|
schemaVersion: "treeseed.command-tree/v1",
|
|
19
70
|
executable: "trsd",
|
|
20
71
|
commands: [
|
|
@@ -41,10 +92,10 @@ const TREESEED_COMMAND_TREE_V1 = {
|
|
|
41
92
|
branch("offers", [leaf("show", "read", "connection"), leaf("validate", "read", "file"), leaf("plan", "read", "file"), leaf("apply", "mutation", "file", "authority")])
|
|
42
93
|
]),
|
|
43
94
|
branch("capacity", [leaf("status"), leaf("explain"), leaf("usage"), leaf("ledger"), leaf("audit")]),
|
|
44
|
-
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" }]),
|
|
95
|
+
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() }]),
|
|
45
96
|
branch("workdays", [
|
|
46
97
|
branch("profiles", [leaf("list"), leaf("show", "read", "profile"), leaf("validate", "read", "file")]),
|
|
47
|
-
leaf("plan"),
|
|
98
|
+
leaf("plan", "mutation"),
|
|
48
99
|
leaf("start", "mutation", void 0, "authority"),
|
|
49
100
|
leaf("list"),
|
|
50
101
|
leaf("show", "read", "workday"),
|
|
@@ -63,6 +114,15 @@ const TREESEED_COMMAND_TREE_V1 = {
|
|
|
63
114
|
leaf("diagnose")
|
|
64
115
|
]
|
|
65
116
|
};
|
|
117
|
+
function attachExecution(nodes, parent = []) {
|
|
118
|
+
for (const node of nodes) {
|
|
119
|
+
const path = [...parent, node.segment];
|
|
120
|
+
if (node.nodeType === "branch") attachExecution(node.children, path);
|
|
121
|
+
else node.execution = operationBindings[path.join(" ")] ?? node.execution;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
attachExecution(commandTree.commands);
|
|
125
|
+
const TREESEED_COMMAND_TREE_V1 = commandTree;
|
|
66
126
|
function listCommandPaths(tree = TREESEED_COMMAND_TREE_V1) {
|
|
67
127
|
const paths = [];
|
|
68
128
|
const visit = (nodes, parent) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ControlPlaneOperationBinding } from './control-plane-operation.js';
|
|
1
2
|
export type CommandOperationKind = 'read' | 'mutation';
|
|
2
3
|
export type CommandExecutionMode = 'execute' | 'plan';
|
|
3
4
|
export type CommandErrorCategory = 'unknown_command' | 'invalid_input' | 'ambiguous_context' | 'authentication_required' | 'authorization_denied' | 'confirmation_required' | 'policy_blocked' | 'stale_preflight' | 'conflict' | 'not_found' | 'provider_unavailable' | 'rate_limited' | 'internal_error';
|
|
@@ -19,6 +20,31 @@ export interface CommandAuthorizationDescriptor {
|
|
|
19
20
|
capability: string;
|
|
20
21
|
confirmation: 'never' | 'destructive' | 'credential' | 'authority' | 'production' | 'irreversible';
|
|
21
22
|
}
|
|
23
|
+
export type CommandInputSource = 'argument' | 'context' | 'option';
|
|
24
|
+
export type CommandInputTarget = 'path' | 'query' | 'body';
|
|
25
|
+
export interface CommandInputBinding {
|
|
26
|
+
field: string;
|
|
27
|
+
source: CommandInputSource;
|
|
28
|
+
name: string;
|
|
29
|
+
target: CommandInputTarget;
|
|
30
|
+
required?: boolean;
|
|
31
|
+
transform?: 'identity' | 'integer' | 'csv';
|
|
32
|
+
}
|
|
33
|
+
export type CommandExecutionBinding = {
|
|
34
|
+
kind: 'operation';
|
|
35
|
+
operationId: `${string}.${string}`;
|
|
36
|
+
input: CommandInputBinding[];
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'protocol';
|
|
39
|
+
handlerId: `protocol.${string}`;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'local';
|
|
42
|
+
handlerId: `local.${string}`;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'unavailable';
|
|
45
|
+
code: string;
|
|
46
|
+
reason: string;
|
|
47
|
+
};
|
|
22
48
|
export interface CommandLeafDescriptor {
|
|
23
49
|
segment: string;
|
|
24
50
|
description: string;
|
|
@@ -27,6 +53,7 @@ export interface CommandLeafDescriptor {
|
|
|
27
53
|
options?: CommandOptionDescriptor[];
|
|
28
54
|
authorization?: CommandAuthorizationDescriptor;
|
|
29
55
|
resultSchemaId: string;
|
|
56
|
+
execution: CommandExecutionBinding;
|
|
30
57
|
}
|
|
31
58
|
export interface CommandBranchDescriptor {
|
|
32
59
|
segment: string;
|
|
@@ -76,4 +103,5 @@ export interface CommandTreeDiagnostic {
|
|
|
76
103
|
message: string;
|
|
77
104
|
}
|
|
78
105
|
export declare function validateCommandTree(tree: CommandTreeDescriptor): CommandTreeDiagnostic[];
|
|
106
|
+
export declare function validateCommandOperationBindings(tree: CommandTreeDescriptor, operations: readonly ControlPlaneOperationBinding<any, any, any, any>[]): CommandTreeDiagnostic[];
|
|
79
107
|
export declare function createCommandResult<TResult>(input: Omit<CommandResultEnvelope<TResult>, 'schemaVersion'>): CommandResultEnvelope<TResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZodUndefined } from "zod";
|
|
1
2
|
const SEGMENT = /^[a-z][a-z0-9]*$/;
|
|
2
3
|
const FORBIDDEN_AGENT_MANAGEMENT_OPTIONS = /* @__PURE__ */ new Set([
|
|
3
4
|
"--commit",
|
|
@@ -31,6 +32,17 @@ function validateCommandTree(tree) {
|
|
|
31
32
|
}
|
|
32
33
|
if ("children" in raw) diagnostics.push({ code: "command_node_ambiguous", path: diagnosticPath, message: "Leaf command nodes cannot contain child commands." });
|
|
33
34
|
if (!node.resultSchemaId.trim()) diagnostics.push({ code: "result_schema_required", path: `${diagnosticPath}.resultSchemaId`, message: "Leaf commands require a stable result schema." });
|
|
35
|
+
if (!node.execution) diagnostics.push({ code: "command_execution_required", path: `${diagnosticPath}.execution`, message: "Every leaf must declare one authoritative execution binding." });
|
|
36
|
+
if (node.execution?.kind === "operation") {
|
|
37
|
+
const targets = /* @__PURE__ */ new Set();
|
|
38
|
+
for (const binding of node.execution.input) {
|
|
39
|
+
const key = `${binding.target}.${binding.field}`;
|
|
40
|
+
if (targets.has(key)) diagnostics.push({ code: "command_input_target_duplicate", path: `${diagnosticPath}.execution.input`, message: `Duplicate command input target ${key}.` });
|
|
41
|
+
targets.add(key);
|
|
42
|
+
if (!binding.field.trim() || !binding.name.trim()) diagnostics.push({ code: "command_input_binding_invalid", path: `${diagnosticPath}.execution.input`, message: "Command input bindings require field and source names." });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (node.execution?.kind === "unavailable" && (!node.execution.code.trim() || !node.execution.reason.trim())) diagnostics.push({ code: "command_unavailable_reason_required", path: `${diagnosticPath}.execution`, message: "Unavailable commands require a stable code and explanation." });
|
|
34
46
|
const optionNames = /* @__PURE__ */ new Set();
|
|
35
47
|
for (const option of node.options ?? []) {
|
|
36
48
|
if (optionNames.has(option.name)) diagnostics.push({ code: "command_option_duplicate", path: `${diagnosticPath}.options.${index}`, message: `Duplicate option ${option.name}.` });
|
|
@@ -44,10 +56,47 @@ function validateCommandTree(tree) {
|
|
|
44
56
|
visit(tree.commands, []);
|
|
45
57
|
return diagnostics;
|
|
46
58
|
}
|
|
59
|
+
function validateCommandOperationBindings(tree, operations) {
|
|
60
|
+
const diagnostics = [];
|
|
61
|
+
const catalog = new Map(operations.map((operation) => [operation.descriptor.operationId, operation]));
|
|
62
|
+
const visit = (nodes, parent) => {
|
|
63
|
+
for (const node of nodes) {
|
|
64
|
+
const path = [...parent, node.segment];
|
|
65
|
+
if (node.nodeType === "branch") {
|
|
66
|
+
visit(node.children, path);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (node.execution.kind !== "operation") continue;
|
|
70
|
+
const binding = catalog.get(node.execution.operationId);
|
|
71
|
+
const diagnosticPath = `commands.${path.join(".")}.execution`;
|
|
72
|
+
if (!binding) {
|
|
73
|
+
diagnostics.push({ code: "command_operation_unknown", path: diagnosticPath, message: `Unknown control-plane operation ${node.execution.operationId}.` });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!binding.descriptor.surfaces.includes("cli")) diagnostics.push({ code: "command_operation_surface_missing", path: diagnosticPath, message: `Operation ${node.execution.operationId} does not declare the CLI surface.` });
|
|
77
|
+
if (binding.descriptor.kind !== node.kind) diagnostics.push({ code: "command_operation_kind_mismatch", path: diagnosticPath, message: `Command and operation ${node.execution.operationId} disagree about mutation behavior.` });
|
|
78
|
+
const expectedConfirmation = binding.descriptor.confirmation === "input_required" ? binding.descriptor.riskClass : "never";
|
|
79
|
+
if ((node.authorization?.confirmation ?? "never") !== expectedConfirmation) diagnostics.push({ code: "command_operation_confirmation_mismatch", path: diagnosticPath, message: `Command and operation ${node.execution.operationId} disagree about confirmation.` });
|
|
80
|
+
const shapes = {
|
|
81
|
+
path: "shape" in binding.schema.path ? Object.keys(binding.schema.path.shape) : null,
|
|
82
|
+
query: "shape" in binding.schema.query ? Object.keys(binding.schema.query.shape) : null,
|
|
83
|
+
body: "shape" in binding.schema.body ? Object.keys(binding.schema.body.shape) : null
|
|
84
|
+
};
|
|
85
|
+
for (const input of node.execution.input) {
|
|
86
|
+
const keys = shapes[input.target];
|
|
87
|
+
const undefinedSchema = binding.schema[input.target] instanceof ZodUndefined;
|
|
88
|
+
if (keys !== null && !keys.includes(input.field) || undefinedSchema) diagnostics.push({ code: "command_operation_input_unknown", path: `${diagnosticPath}.input.${input.target}.${input.field}`, message: `Operation ${node.execution.operationId} does not accept ${input.target} field ${input.field}.` });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
visit(tree.commands, []);
|
|
93
|
+
return diagnostics.sort((left, right) => `${left.path}:${left.code}`.localeCompare(`${right.path}:${right.code}`));
|
|
94
|
+
}
|
|
47
95
|
function createCommandResult(input) {
|
|
48
96
|
return { schemaVersion: "treeseed.command-result/v1", ...input };
|
|
49
97
|
}
|
|
50
98
|
export {
|
|
51
99
|
createCommandResult,
|
|
100
|
+
validateCommandOperationBindings,
|
|
52
101
|
validateCommandTree
|
|
53
102
|
};
|
|
@@ -10,8 +10,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
10
10
|
readonly projects: {
|
|
11
11
|
readonly list: ControlPlaneOperationBinding<{}, {
|
|
12
12
|
cursor?: string | undefined;
|
|
13
|
-
teamId?: string | undefined;
|
|
14
13
|
limit?: number | undefined;
|
|
14
|
+
teamId?: string | undefined;
|
|
15
15
|
}, undefined, Record<string, unknown>>;
|
|
16
16
|
readonly show: ControlPlaneOperationBinding<{
|
|
17
17
|
projectId: string;
|
|
@@ -413,8 +413,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
413
413
|
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
414
414
|
readonly putAuthority: ControlPlaneOperationBinding<{
|
|
415
415
|
teamId: string;
|
|
416
|
-
profileId: string;
|
|
417
416
|
connectionId: string;
|
|
417
|
+
profileId: string;
|
|
418
418
|
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
419
419
|
};
|
|
420
420
|
readonly agents: {
|
|
@@ -274,7 +274,7 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
274
274
|
providers: resource("services.providers.list", "GET", "/v1/service-providers", {}, { capability: "services.read", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
275
275
|
connections: resource("services.connections.list", "GET", "/v1/teams/{teamId}/services", { teamId: z.string().min(1) }, { capability: "services.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
|
|
276
276
|
connection: resource("services.connections.show", "GET", "/v1/teams/{teamId}/services/{connectionId}", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "services.read", surfaces: ["rest", "cli", "mcp_resource"] }),
|
|
277
|
-
createConnection: resource("services.connections.create", "POST", "/v1/teams/{teamId}/services", { teamId: z.string().min(1) }, { capability: "services.write", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
277
|
+
createConnection: resource("services.connections.create", "POST", "/v1/teams/{teamId}/services", { teamId: z.string().min(1) }, { capability: "services.write", surfaces: ["rest", "cli", "mcp_tool"], risk: "credential" }),
|
|
278
278
|
updateConnection: resource("services.connections.update", "PUT", "/v1/teams/{teamId}/services/{connectionId}", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "services.write", surfaces: ["rest", "cli", "mcp_tool"], concurrency: true }),
|
|
279
279
|
disconnect: resource("services.connections.disconnect", "DELETE", "/v1/teams/{teamId}/services/{connectionId}", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "services.write", surfaces: ["rest", "cli", "mcp_tool"], risk: "destructive", concurrency: true }),
|
|
280
280
|
authorities: resource("services.credential.authorities.list", "GET", "/v1/teams/{teamId}/services/{connectionId}/credential-authorities", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "secrets.read", surfaces: ["rest", "cli"], pagination: "cursor" }),
|
|
@@ -310,11 +310,11 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
310
310
|
workdays: {
|
|
311
311
|
list: resource("workdays.list", "GET", "/v1/teams/{teamId}/workday-runs", { teamId: z.string().min(1) }, { capability: "workdays.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
|
|
312
312
|
preflight: resource("workdays.plan", "POST", "/v1/teams/{teamId}/workday-runs/preflight", { teamId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
313
|
-
start: resource("workdays.start", "POST", "/v1/teams/{teamId}/workday-runs", { teamId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
313
|
+
start: resource("workdays.start", "POST", "/v1/teams/{teamId}/workday-runs", { teamId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"], risk: "authority" }),
|
|
314
314
|
show: resource("workdays.show", "GET", "/v1/teams/{teamId}/workday-runs/{runId}", { teamId: z.string().min(1), runId: z.string().min(1) }, { capability: "workdays.read", surfaces: ["rest", "cli", "mcp_resource"] }),
|
|
315
315
|
events: resource("workdays.events.list", "GET", "/v1/teams/{teamId}/workday-runs/{runId}/events", { teamId: z.string().min(1), runId: z.string().min(1) }, { capability: "workdays.read", pagination: "cursor" }),
|
|
316
316
|
schedules: resource("workdays.schedules.list", "GET", "/v1/teams/{teamId}/workday-schedules", { teamId: z.string().min(1) }, { capability: "workdays.read", surfaces: ["rest", "cli"], pagination: "cursor" }),
|
|
317
|
-
createSchedule: resource("workdays.schedules.create", "POST", "/v1/teams/{teamId}/workday-schedules", { teamId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli"] }),
|
|
317
|
+
createSchedule: resource("workdays.schedules.create", "POST", "/v1/teams/{teamId}/workday-schedules", { teamId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli"], risk: "authority" }),
|
|
318
318
|
updateSchedule: resource("workdays.schedules.update", "PATCH", "/v1/teams/{teamId}/workday-schedules/{scheduleId}", { teamId: z.string().min(1), scheduleId: z.string().min(1) }, { capability: "workdays.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli"], concurrency: true })
|
|
319
319
|
},
|
|
320
320
|
assignments: {
|
|
@@ -322,7 +322,7 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
322
322
|
show: resource("assignments.show", "GET", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.read", surfaces: ["rest", "cli", "mcp_resource"] }),
|
|
323
323
|
explain: resource("assignments.explain", "GET", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}/explanation", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.read", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
324
324
|
cancel: resource("assignments.cancel", "POST", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}/cancel", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"], risk: "destructive" }),
|
|
325
|
-
retry: resource("assignments.retry", "POST", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}/requeue", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"] })
|
|
325
|
+
retry: resource("assignments.retry", "POST", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}/requeue", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"], risk: "authority" })
|
|
326
326
|
},
|
|
327
327
|
operations: {
|
|
328
328
|
list: resource("operations.list", "GET", "/v1/platform/operations", {}, { capability: "operations.read", surfaces: ["rest", "mcp_tool"], pagination: "cursor" }),
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
const MCP_PROTOCOL_VERSION = "2026-07-28";
|
|
2
|
+
function encodeConfirmationState(state) {
|
|
3
|
+
const bytes = new TextEncoder().encode(JSON.stringify(state));
|
|
4
|
+
let binary = "";
|
|
5
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
6
|
+
return btoa(binary).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/gu, "");
|
|
7
|
+
}
|
|
2
8
|
const TREESEED_MCP_PROMPTS = [
|
|
3
9
|
{ name: "operate", description: "Operate TreeSeed through currently discoverable capabilities.", argumentSchemaId: "treeseed.prompt.objective/v1", requiredScopes: ["treeseed:read"] },
|
|
4
10
|
{ name: "research", description: "Research a governed TreeSeed question and accumulate knowledge.", argumentSchemaId: "treeseed.prompt.objective/v1", requiredScopes: ["treeseed:read"] },
|
|
@@ -72,6 +78,7 @@ export {
|
|
|
72
78
|
buildMcpCatalog,
|
|
73
79
|
buildMcpResources,
|
|
74
80
|
buildMcpTools,
|
|
81
|
+
encodeConfirmationState,
|
|
75
82
|
operationToMcpResource,
|
|
76
83
|
operationToMcpTool
|
|
77
84
|
};
|