@treeseed/sdk 0.6.39 → 0.6.41

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.
Files changed (44) hide show
  1. package/dist/capacity.d.ts +53 -0
  2. package/dist/capacity.js +100 -0
  3. package/dist/control-plane-client.d.ts +41 -1
  4. package/dist/control-plane-client.js +154 -0
  5. package/dist/control-plane.d.ts +6 -1
  6. package/dist/control-plane.js +39 -2
  7. package/dist/d1-store.d.ts +63 -1
  8. package/dist/d1-store.js +190 -1
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.js +12 -0
  11. package/dist/operations/services/config-runtime.js +2 -2
  12. package/dist/operations/services/deploy.js +3 -2
  13. package/dist/operations/services/knowledge-coop-launch.js +5 -28
  14. package/dist/operations/services/package-reference-policy.d.ts +68 -0
  15. package/dist/operations/services/package-reference-policy.js +135 -0
  16. package/dist/operations/services/project-platform.d.ts +14 -0
  17. package/dist/operations/services/project-platform.js +3 -2
  18. package/dist/operations/services/railway-api.d.ts +33 -0
  19. package/dist/operations/services/railway-api.js +273 -0
  20. package/dist/operations/services/railway-deploy.d.ts +22 -0
  21. package/dist/operations/services/railway-deploy.js +216 -18
  22. package/dist/operations/services/release-candidate.d.ts +2 -0
  23. package/dist/operations/services/release-candidate.js +28 -0
  24. package/dist/operations/services/runtime-tools.js +1 -1
  25. package/dist/operations-registry.js +1 -0
  26. package/dist/reconcile/bootstrap-systems.js +1 -1
  27. package/dist/reconcile/builtin-adapters.js +5 -9
  28. package/dist/reconcile/contracts.d.ts +1 -1
  29. package/dist/reconcile/desired-state.js +9 -17
  30. package/dist/reconcile/state.js +4 -4
  31. package/dist/reconcile/units.js +4 -8
  32. package/dist/sdk-types.d.ts +566 -3
  33. package/dist/sdk.d.ts +12 -1
  34. package/dist/sdk.js +44 -0
  35. package/dist/stores/operational-store.d.ts +12 -1
  36. package/dist/stores/operational-store.js +283 -5
  37. package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +5 -24
  38. package/dist/types/agents.d.ts +27 -0
  39. package/dist/workflow/operations.d.ts +94 -2
  40. package/dist/workflow/operations.js +90 -32
  41. package/dist/workflow-state.js +3 -5
  42. package/dist/workflow.d.ts +8 -1
  43. package/dist/workflow.js +6 -0
  44. package/package.json +5 -1
@@ -0,0 +1,53 @@
1
+ import type { CapacityEstimateConfidence, CapacityGrant, CapacityPlan, CapacityProviderLane, CapacityReservation, TaskEstimateProfile } from './sdk-types.ts';
2
+ import type { AgentProviderProfile } from './types/agents.ts';
3
+ export interface CapacityEstimateInput {
4
+ taskSignature?: string | null;
5
+ taskKind?: string | null;
6
+ confidence?: CapacityEstimateConfidence | null;
7
+ estimatedCreditsP50?: number | null;
8
+ estimatedCreditsP90?: number | null;
9
+ profile?: TaskEstimateProfile | null;
10
+ defaultCredits?: number | null;
11
+ }
12
+ export interface CapacityLaneCandidate {
13
+ lane: CapacityProviderLane;
14
+ grant?: CapacityGrant | null;
15
+ remainingCredits?: number | null;
16
+ agentProfile?: AgentProviderProfile | null;
17
+ taskKind?: string | null;
18
+ requiredCapabilities?: string[];
19
+ modelClass?: string | null;
20
+ region?: string | null;
21
+ }
22
+ export interface CapacityLaneScore {
23
+ laneId: string;
24
+ capacityProviderId: string;
25
+ score: number;
26
+ agentFit: number;
27
+ scarcityPenalty: number;
28
+ fairnessScore: number;
29
+ costPenalty: number;
30
+ reasons: string[];
31
+ }
32
+ export declare function reserveCreditsForEstimate(input: CapacityEstimateInput): {
33
+ taskSignature: string;
34
+ confidence: CapacityEstimateConfidence;
35
+ estimatedCreditsP50: number;
36
+ estimatedCreditsP90: number;
37
+ reservedCredits: number;
38
+ };
39
+ export declare function summarizeCapacityPlan(plan: CapacityPlan): {
40
+ grantedDailyCredits: number;
41
+ reservedCredits: number;
42
+ consumedCredits: number;
43
+ remainingDailyCredits: number | null;
44
+ providerCount: number;
45
+ laneCount: number;
46
+ grantCount: number;
47
+ };
48
+ export declare function scoreCapacityLane(input: CapacityLaneCandidate): CapacityLaneScore;
49
+ export declare function selectBestCapacityLane(candidates: CapacityLaneCandidate[]): {
50
+ selected: CapacityLaneScore;
51
+ scores: CapacityLaneScore[];
52
+ };
53
+ export declare function reservationHasCapacity(reservation: CapacityReservation): boolean;
@@ -0,0 +1,100 @@
1
+ function finiteNumber(value) {
2
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
3
+ }
4
+ function scarcityPenalty(level) {
5
+ if (level === "high") return 35;
6
+ if (level === "medium") return 15;
7
+ return 0;
8
+ }
9
+ function reserveCreditsForEstimate(input) {
10
+ const profileP50 = finiteNumber(input.profile?.creditsP50);
11
+ const profileP90 = finiteNumber(input.profile?.creditsP90);
12
+ const p50 = Math.max(1, Math.ceil(
13
+ finiteNumber(input.estimatedCreditsP50) ?? profileP50 ?? finiteNumber(input.defaultCredits) ?? 1
14
+ ));
15
+ const p90 = Math.max(p50, Math.ceil(
16
+ finiteNumber(input.estimatedCreditsP90) ?? profileP90 ?? p50 * 2
17
+ ));
18
+ const confidence = input.confidence ?? "medium";
19
+ const reserved = confidence === "high" ? Math.max(p50, Math.ceil((p50 + p90) * 0.75)) : p90;
20
+ return {
21
+ taskSignature: input.taskSignature ?? input.taskKind ?? "unknown",
22
+ confidence,
23
+ estimatedCreditsP50: p50,
24
+ estimatedCreditsP90: p90,
25
+ reservedCredits: reserved
26
+ };
27
+ }
28
+ function summarizeCapacityPlan(plan) {
29
+ const reservedCredits = plan.activeReservations.filter((reservation) => reservation.state === "reserved").reduce((total, reservation) => total + reservation.reservedCredits, 0);
30
+ const consumedCredits = plan.activeReservations.reduce((total, reservation) => total + reservation.consumedCredits, 0);
31
+ const grantedDailyCredits = plan.grants.filter((grant) => grant.state === "active").reduce((total, grant) => total + (grant.dailyCreditLimit ?? 0), 0);
32
+ return {
33
+ grantedDailyCredits,
34
+ reservedCredits,
35
+ consumedCredits,
36
+ remainingDailyCredits: grantedDailyCredits > 0 ? Math.max(0, grantedDailyCredits - reservedCredits - consumedCredits) : null,
37
+ providerCount: plan.providers.length,
38
+ laneCount: plan.lanes.length,
39
+ grantCount: plan.grants.length
40
+ };
41
+ }
42
+ function scoreCapacityLane(input) {
43
+ const reasons = [];
44
+ let agentFit = 0;
45
+ const profile = input.agentProfile;
46
+ if (profile) {
47
+ const preferred = profile.preferredLanes.find(
48
+ (preference) => preference.laneId === input.lane.id || preference.providerId === input.lane.capacityProviderId || preference.modelClass && preference.modelClass === input.lane.modelClass || preference.provider && preference.provider === input.lane.capacityProviderId
49
+ );
50
+ if (preferred) {
51
+ agentFit += Math.max(0, preferred.weight);
52
+ reasons.push("agent_preference");
53
+ }
54
+ if (profile.disallowedProviders?.includes(input.lane.capacityProviderId)) {
55
+ agentFit -= 1e3;
56
+ reasons.push("agent_disallowed_provider");
57
+ }
58
+ if (input.region && profile.disallowedRegions?.includes(input.region)) {
59
+ agentFit -= 1e3;
60
+ reasons.push("agent_disallowed_region");
61
+ }
62
+ }
63
+ if (input.modelClass && input.lane.modelClass === input.modelClass) {
64
+ agentFit += 20;
65
+ reasons.push("model_class_match");
66
+ }
67
+ const fairnessScore = Math.max(0, (input.grant?.priorityWeight ?? 1) * 10);
68
+ const scarcity = scarcityPenalty(input.lane.scarcityLevel);
69
+ const remaining = input.remainingCredits;
70
+ const costPenalty = remaining !== null && remaining !== void 0 && remaining <= 0 ? 500 : 0;
71
+ if (scarcity > 0) reasons.push(`scarcity:${input.lane.scarcityLevel}`);
72
+ if (costPenalty > 0) reasons.push("capacity_exhausted");
73
+ return {
74
+ laneId: input.lane.id,
75
+ capacityProviderId: input.lane.capacityProviderId,
76
+ score: agentFit + fairnessScore - scarcity - costPenalty,
77
+ agentFit,
78
+ scarcityPenalty: scarcity,
79
+ fairnessScore,
80
+ costPenalty,
81
+ reasons
82
+ };
83
+ }
84
+ function selectBestCapacityLane(candidates) {
85
+ const scored = candidates.map(scoreCapacityLane).sort((left, right) => right.score - left.score || left.laneId.localeCompare(right.laneId));
86
+ return {
87
+ selected: scored[0] ?? null,
88
+ scores: scored
89
+ };
90
+ }
91
+ function reservationHasCapacity(reservation) {
92
+ return reservation.state === "reserved" && reservation.reservedCredits > reservation.consumedCredits;
93
+ }
94
+ export {
95
+ reservationHasCapacity,
96
+ reserveCreditsForEstimate,
97
+ scoreCapacityLane,
98
+ selectBestCapacityLane,
99
+ summarizeCapacityPlan
100
+ };
@@ -1,4 +1,4 @@
1
- import type { AgentPool, AgentPoolRegistration, AgentPoolScaleDecision, CatalogArtifactVersion, CatalogItem, CatalogItemFilters, CreateProjectDeploymentRequest, PriorityOverride, PrioritySnapshot, ProjectConnection, ProjectDeployment, ProjectEnvironment, ProjectEnvironmentName, ProjectHosting, ProjectInfrastructureResource, ProjectWorkdaySummary, RecordAgentPoolRegistrationRequest, ScaleDecision, TeamStorageLocator, TeamWebHost, UpsertAgentPoolRequest, UpsertCatalogArtifactVersionRequest, UpsertCatalogItemRequest, UpsertProjectEnvironmentRequest, UpsertProjectHostingRequest, UpsertProjectInfrastructureResourceRequest, UpsertTeamStorageLocatorRequest, UpsertTeamWebHostRequest, WorkdayPolicy, SdkPriorityOverrideRequest, SdkUpsertWorkPolicyRequest } from './sdk-types.ts';
1
+ import type { AgentPool, AgentPoolRegistration, AgentPoolScaleDecision, ApprovalRequest, CapacityGrant, CapacityPlan, CapacityProvider, CapacityProviderLane, CapacityReservation, CapacityRoutingDecision, CatalogArtifactVersion, CatalogItem, CatalogItemFilters, CreateApprovalRequestRequest, CreateCapacityReservationRequest, CreateCapacityRoutingDecisionRequest, CreateProjectDeploymentRequest, CreateTaskEstimateRequest, CreateTaskUsageActualRequest, PriorityOverride, PrioritySnapshot, ProjectConnection, ProjectDeployment, ProjectEnvironment, ProjectEnvironmentName, ProjectHosting, ProjectInfrastructureResource, ProjectWorkdaySummary, RecordAgentPoolRegistrationRequest, RecordCapacityUsageRequest, RepositoryClaim, RunnerScaleDecision, ScaleDecision, SdkCreateWorkdayRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkRecordWorkerRunnerRequest, TeamStorageLocator, TeamWebHost, TaskEstimate, UpsertAgentPoolRequest, UpsertCapacityGrantRequest, UpsertCapacityProviderLaneRequest, UpsertCapacityProviderRequest, UpsertCatalogArtifactVersionRequest, UpsertCatalogItemRequest, UpsertProjectEnvironmentRequest, UpsertProjectHostingRequest, UpsertProjectInfrastructureResourceRequest, UpsertTeamStorageLocatorRequest, UpsertTeamWebHostRequest, WorkdayPolicy, WorkdayRequest, WorkerRunner, SdkPriorityOverrideRequest, SdkUpsertWorkPolicyRequest } from './sdk-types.ts';
2
2
  import type { AgentMessageRecord, AgentStatusRecord, DirectBoardItemSummary, InboxItem, LaunchProjectRequest, LaunchProjectResult, ProjectOverviewSummary, ReleaseDetail, ReleaseSummary, SharePackageStatus, TeamHomeSummary, TeamMemberSummary, WorkstreamDetail, WorkstreamSummary } from './knowledge-coop.ts';
3
3
  export interface ControlPlaneClientOptions {
4
4
  baseUrl: string;
@@ -43,6 +43,10 @@ export declare class ControlPlaneClient {
43
43
  listAgentPoolScaleDecisions(projectId: string, poolId: string): Promise<AgentPoolScaleDecision[]>;
44
44
  getProjectWorkPolicy(projectId: string, environment?: ProjectEnvironmentName): Promise<WorkdayPolicy | null>;
45
45
  upsertProjectWorkPolicy(projectId: string, input: SdkUpsertWorkPolicyRequest): Promise<WorkdayPolicy>;
46
+ getProjectWorkdayPolicy(projectId: string, environment?: ProjectEnvironmentName): Promise<WorkdayPolicy | null>;
47
+ upsertProjectWorkdayPolicy(projectId: string, input: SdkUpsertWorkPolicyRequest): Promise<WorkdayPolicy>;
48
+ getProjectWorkdayStatus(projectId: string, environment?: ProjectEnvironmentName): Promise<Record<string, unknown>>;
49
+ createProjectWorkdayRequest(projectId: string, input: SdkCreateWorkdayRequest): Promise<WorkdayRequest>;
46
50
  listProjectPriorityOverrides(projectId: string): Promise<PriorityOverride[]>;
47
51
  upsertProjectPriorityOverride(projectId: string, input: SdkPriorityOverrideRequest): Promise<PriorityOverride>;
48
52
  listProjectPrioritySnapshots(projectId: string, workDayId?: string | null): Promise<PrioritySnapshot[]>;
@@ -53,6 +57,11 @@ export declare class ControlPlaneClient {
53
57
  recordRunnerAgentPoolRegistration(projectId: string, poolId: string, input: RecordAgentPoolRegistrationRequest): Promise<AgentPoolRegistration>;
54
58
  recordRunnerScaleDecision(projectId: string, poolName: string, input: Pick<ScaleDecision, 'environment' | 'workDayId' | 'desiredWorkers' | 'observedQueueDepth' | 'observedActiveLeases' | 'reason' | 'metadata'>): Promise<AgentPoolScaleDecision>;
55
59
  recordRunnerWorkdaySummary(projectId: string, input: ProjectWorkdaySummary): Promise<ProjectWorkdaySummary>;
60
+ recordWorkerRunner(projectId: string, input: SdkRecordWorkerRunnerRequest): Promise<WorkerRunner>;
61
+ listWorkerRunners(projectId: string, environment?: ProjectEnvironmentName): Promise<WorkerRunner[]>;
62
+ recordRepositoryClaim(projectId: string, input: SdkRecordRepositoryClaimRequest): Promise<RepositoryClaim>;
63
+ listRepositoryClaims(projectId: string, repositoryId?: string | null): Promise<RepositoryClaim[]>;
64
+ recordRunnerScaleDecisionV2(projectId: string, input: SdkRecordRunnerScaleDecisionRequest): Promise<RunnerScaleDecision>;
56
65
  getTeamHomeSummary(teamId: string): Promise<TeamHomeSummary>;
57
66
  listTeamInboxItems(teamId: string): Promise<InboxItem[]>;
58
67
  listTeamMembers(teamId: string): Promise<TeamMemberSummary[]>;
@@ -70,6 +79,37 @@ export declare class ControlPlaneClient {
70
79
  host: TeamWebHost;
71
80
  validation: Record<string, unknown> | null;
72
81
  }>;
82
+ listCapacityProviders(teamId: string): Promise<(CapacityProvider & {
83
+ lanes?: CapacityProviderLane[];
84
+ })[]>;
85
+ createCapacityProvider(teamId: string, input: UpsertCapacityProviderRequest): Promise<CapacityProvider>;
86
+ updateCapacityProvider(teamId: string, providerId: string, input: Partial<UpsertCapacityProviderRequest>): Promise<CapacityProvider>;
87
+ listCapacityProviderLanes(teamId: string, providerId: string): Promise<CapacityProviderLane[]>;
88
+ createCapacityProviderLane(teamId: string, providerId: string, input: UpsertCapacityProviderLaneRequest): Promise<CapacityProviderLane>;
89
+ listCapacityGrants(teamId: string, input?: {
90
+ projectId?: string | null;
91
+ providerId?: string | null;
92
+ }): Promise<CapacityGrant[]>;
93
+ createCapacityGrant(teamId: string, input: UpsertCapacityGrantRequest): Promise<CapacityGrant>;
94
+ getProjectCapacityPlan(projectId: string, environment?: ProjectEnvironmentName | 'local' | null): Promise<CapacityPlan>;
95
+ recordRunnerCapacityEstimate(projectId: string, input: CreateTaskEstimateRequest | {
96
+ estimates: CreateTaskEstimateRequest[];
97
+ }): Promise<TaskEstimate | TaskEstimate[]>;
98
+ createRunnerCapacityReservation(projectId: string, input: CreateCapacityReservationRequest): Promise<CapacityReservation>;
99
+ recordRunnerCapacityUsage(projectId: string, input: RecordCapacityUsageRequest & {
100
+ usageActual?: CreateTaskUsageActualRequest;
101
+ }): Promise<{
102
+ entry: unknown;
103
+ usageActual: unknown | null;
104
+ }>;
105
+ recordRunnerCapacityRoutingDecision(projectId: string, input: CreateCapacityRoutingDecisionRequest): Promise<CapacityRoutingDecision>;
106
+ createRunnerApprovalRequest(projectId: string, input: CreateApprovalRequestRequest): Promise<ApprovalRequest>;
107
+ decideApprovalRequest(approvalRequestId: string, input: {
108
+ state?: 'approved' | 'rejected';
109
+ optionId?: string | null;
110
+ note?: string | null;
111
+ decision?: Record<string, unknown>;
112
+ }): Promise<ApprovalRequest>;
73
113
  listTeamProducts(teamId: string): Promise<CatalogItem[]>;
74
114
  launchProject(teamId: string, input: LaunchProjectRequest): Promise<LaunchProjectResult>;
75
115
  getProjectSummary(projectId: string): Promise<ProjectOverviewSummary>;
@@ -159,6 +159,34 @@ class ControlPlaneClient {
159
159
  { body: input }
160
160
  );
161
161
  }
162
+ getProjectWorkdayPolicy(projectId, environment = "staging") {
163
+ return this.requestJson(
164
+ "GET",
165
+ `/v1/projects/${encodeURIComponent(projectId)}/workday-policy`,
166
+ { query: { environment } }
167
+ );
168
+ }
169
+ upsertProjectWorkdayPolicy(projectId, input) {
170
+ return this.requestJson(
171
+ "PUT",
172
+ `/v1/projects/${encodeURIComponent(projectId)}/workday-policy`,
173
+ { body: input }
174
+ );
175
+ }
176
+ getProjectWorkdayStatus(projectId, environment = "staging") {
177
+ return this.requestJson(
178
+ "GET",
179
+ `/v1/projects/${encodeURIComponent(projectId)}/workday-status`,
180
+ { query: { environment } }
181
+ );
182
+ }
183
+ createProjectWorkdayRequest(projectId, input) {
184
+ return this.requestJson(
185
+ "POST",
186
+ `/v1/projects/${encodeURIComponent(projectId)}/workday-requests`,
187
+ { body: input }
188
+ );
189
+ }
162
190
  listProjectPriorityOverrides(projectId) {
163
191
  return this.requestJson(
164
192
  "GET",
@@ -228,6 +256,41 @@ class ControlPlaneClient {
228
256
  { body: input }
229
257
  );
230
258
  }
259
+ recordWorkerRunner(projectId, input) {
260
+ return this.requestJson(
261
+ "POST",
262
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/worker-runners`,
263
+ { body: input }
264
+ );
265
+ }
266
+ listWorkerRunners(projectId, environment = "staging") {
267
+ return this.requestJson(
268
+ "GET",
269
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/worker-runners`,
270
+ { query: { environment } }
271
+ );
272
+ }
273
+ recordRepositoryClaim(projectId, input) {
274
+ return this.requestJson(
275
+ "POST",
276
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/repository-claims`,
277
+ { body: input }
278
+ );
279
+ }
280
+ listRepositoryClaims(projectId, repositoryId) {
281
+ return this.requestJson(
282
+ "GET",
283
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/repository-claims`,
284
+ { query: { repositoryId: repositoryId ?? null } }
285
+ );
286
+ }
287
+ recordRunnerScaleDecisionV2(projectId, input) {
288
+ return this.requestJson(
289
+ "POST",
290
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/runner-scale-decisions`,
291
+ { body: input }
292
+ );
293
+ }
231
294
  getTeamHomeSummary(teamId) {
232
295
  return this.requestJson("GET", `/v1/teams/${encodeURIComponent(teamId)}/home`);
233
296
  }
@@ -260,6 +323,97 @@ class ControlPlaneClient {
260
323
  { body: input }
261
324
  );
262
325
  }
326
+ listCapacityProviders(teamId) {
327
+ return this.requestJson(
328
+ "GET",
329
+ `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers`
330
+ );
331
+ }
332
+ createCapacityProvider(teamId, input) {
333
+ return this.requestJson("POST", `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers`, {
334
+ body: input
335
+ });
336
+ }
337
+ updateCapacityProvider(teamId, providerId, input) {
338
+ return this.requestJson(
339
+ "PATCH",
340
+ `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers/${encodeURIComponent(providerId)}`,
341
+ { body: input }
342
+ );
343
+ }
344
+ listCapacityProviderLanes(teamId, providerId) {
345
+ return this.requestJson(
346
+ "GET",
347
+ `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers/${encodeURIComponent(providerId)}/lanes`
348
+ );
349
+ }
350
+ createCapacityProviderLane(teamId, providerId, input) {
351
+ return this.requestJson(
352
+ "POST",
353
+ `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers/${encodeURIComponent(providerId)}/lanes`,
354
+ { body: input }
355
+ );
356
+ }
357
+ listCapacityGrants(teamId, input = {}) {
358
+ return this.requestJson("GET", `/v1/teams/${encodeURIComponent(teamId)}/capacity-grants`, {
359
+ query: {
360
+ projectId: input.projectId ?? null,
361
+ providerId: input.providerId ?? null
362
+ }
363
+ });
364
+ }
365
+ createCapacityGrant(teamId, input) {
366
+ return this.requestJson("POST", `/v1/teams/${encodeURIComponent(teamId)}/capacity-grants`, {
367
+ body: input
368
+ });
369
+ }
370
+ getProjectCapacityPlan(projectId, environment) {
371
+ return this.requestJson("GET", `/v1/projects/${encodeURIComponent(projectId)}/capacity-plan`, {
372
+ query: { environment: environment ?? null }
373
+ });
374
+ }
375
+ recordRunnerCapacityEstimate(projectId, input) {
376
+ return this.requestJson(
377
+ "POST",
378
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/capacity/estimates`,
379
+ { body: input }
380
+ );
381
+ }
382
+ createRunnerCapacityReservation(projectId, input) {
383
+ return this.requestJson(
384
+ "POST",
385
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/capacity/reservations`,
386
+ { body: input }
387
+ );
388
+ }
389
+ recordRunnerCapacityUsage(projectId, input) {
390
+ return this.requestJson(
391
+ "POST",
392
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/capacity/usage`,
393
+ { body: input }
394
+ );
395
+ }
396
+ recordRunnerCapacityRoutingDecision(projectId, input) {
397
+ return this.requestJson(
398
+ "POST",
399
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/capacity/routing-decisions`,
400
+ { body: input }
401
+ );
402
+ }
403
+ createRunnerApprovalRequest(projectId, input) {
404
+ return this.requestJson(
405
+ "POST",
406
+ `/v1/projects/${encodeURIComponent(projectId)}/runner/approval-requests`,
407
+ { body: input }
408
+ );
409
+ }
410
+ decideApprovalRequest(approvalRequestId, input) {
411
+ return this.requestJson(
412
+ "POST",
413
+ `/v1/approval-requests/${encodeURIComponent(approvalRequestId)}/decide`,
414
+ { body: input }
415
+ );
416
+ }
263
417
  listTeamProducts(teamId) {
264
418
  return this.requestJson("GET", `/v1/teams/${encodeURIComponent(teamId)}/products`);
265
419
  }
@@ -1,4 +1,4 @@
1
- import type { AgentPoolAutoscalePolicy, ProjectDeploymentKind, ProjectDeploymentStatus, ProjectEnvironmentName, ProjectInfrastructureResourceKind, ProjectInfrastructureResourceProvider, TreeseedHostingKind, TreeseedHostingRegistration } from './sdk-types.ts';
1
+ import type { AgentPoolAutoscalePolicy, ApprovalRequest, CapacityPlan, CapacityReservation, CapacityRoutingDecision, CreateApprovalRequestRequest, CreateCapacityReservationRequest, CreateCapacityRoutingDecisionRequest, ProjectDeploymentKind, ProjectDeploymentStatus, ProjectEnvironmentName, ProjectInfrastructureResourceKind, ProjectInfrastructureResourceProvider, RecordCapacityUsageRequest, TreeseedHostingKind, TreeseedHostingRegistration } from './sdk-types.ts';
2
2
  import type { TreeseedDeployConfig } from './platform/contracts.ts';
3
3
  export type ControlPlaneReporterKind = 'noop' | 'market_http' | 'self_http';
4
4
  export interface ControlPlaneEnvironmentReport {
@@ -78,6 +78,11 @@ export interface ControlPlaneReporter {
78
78
  registerAgentPoolHeartbeat(input: ControlPlaneAgentPoolHeartbeat): Promise<void>;
79
79
  reportScaleDecision(input: ControlPlaneScaleDecisionReport): Promise<void>;
80
80
  reportWorkdaySummary(input: ControlPlaneWorkdaySummaryReport): Promise<void>;
81
+ getProjectCapacityPlan(environment?: ProjectEnvironmentName | 'local' | null): Promise<CapacityPlan | null>;
82
+ createCapacityReservation(input: CreateCapacityReservationRequest): Promise<CapacityReservation | null>;
83
+ reportCapacityUsage(input: RecordCapacityUsageRequest): Promise<void>;
84
+ reportCapacityRoutingDecision(input: CreateCapacityRoutingDecisionRequest): Promise<CapacityRoutingDecision | null>;
85
+ createApprovalRequest(input: CreateApprovalRequestRequest): Promise<ApprovalRequest | null>;
81
86
  }
82
87
  export interface ControlPlaneReporterOptions {
83
88
  kind?: ControlPlaneReporterKind | null;
@@ -41,6 +41,20 @@ class NoopControlPlaneReporter {
41
41
  }
42
42
  async reportWorkdaySummary() {
43
43
  }
44
+ async getProjectCapacityPlan() {
45
+ return null;
46
+ }
47
+ async createCapacityReservation() {
48
+ return null;
49
+ }
50
+ async reportCapacityUsage() {
51
+ }
52
+ async reportCapacityRoutingDecision() {
53
+ return null;
54
+ }
55
+ async createApprovalRequest() {
56
+ return null;
57
+ }
44
58
  }
45
59
  class HttpControlPlaneReporter {
46
60
  constructor(kind, projectId, baseUrl, runnerToken, fetchImpl = fetch) {
@@ -59,7 +73,7 @@ class HttpControlPlaneReporter {
59
73
  enabled;
60
74
  async request(method, pathname, body) {
61
75
  if (!this.enabled || !this.baseUrl || !this.runnerToken) {
62
- return;
76
+ return null;
63
77
  }
64
78
  const response = await this.fetchImpl(new URL(pathname, this.baseUrl), {
65
79
  method,
@@ -67,11 +81,13 @@ class HttpControlPlaneReporter {
67
81
  authorization: `Bearer ${this.runnerToken}`,
68
82
  "content-type": "application/json"
69
83
  },
70
- body: JSON.stringify(body)
84
+ body: body === void 0 ? void 0 : JSON.stringify(body)
71
85
  });
72
86
  if (!response.ok) {
73
87
  throw new Error(`Control-plane request failed for ${pathname}: ${response.status} ${response.statusText}`);
74
88
  }
89
+ const envelope = await response.json().catch(() => null);
90
+ return envelope?.payload ?? null;
75
91
  }
76
92
  async reportEnvironment(input) {
77
93
  if (!this.projectId) return;
@@ -109,6 +125,27 @@ class HttpControlPlaneReporter {
109
125
  if (!this.projectId) return;
110
126
  await this.request("POST", `/v1/projects/${this.projectId}/runner/workdays`, input);
111
127
  }
128
+ async getProjectCapacityPlan(environment) {
129
+ if (!this.projectId) return null;
130
+ const suffix = environment ? `?environment=${encodeURIComponent(environment)}` : "";
131
+ return this.request("GET", `/v1/projects/${this.projectId}/capacity-plan${suffix}`);
132
+ }
133
+ async createCapacityReservation(input) {
134
+ if (!this.projectId) return null;
135
+ return this.request("POST", `/v1/projects/${this.projectId}/runner/capacity/reservations`, input);
136
+ }
137
+ async reportCapacityUsage(input) {
138
+ if (!this.projectId) return;
139
+ await this.request("POST", `/v1/projects/${this.projectId}/runner/capacity/usage`, input);
140
+ }
141
+ async reportCapacityRoutingDecision(input) {
142
+ if (!this.projectId) return null;
143
+ return this.request("POST", `/v1/projects/${this.projectId}/runner/capacity/routing-decisions`, input);
144
+ }
145
+ async createApprovalRequest(input) {
146
+ if (!this.projectId) return null;
147
+ return this.request("POST", `/v1/projects/${this.projectId}/runner/approval-requests`, input);
148
+ }
112
149
  }
113
150
  function createControlPlaneReporter(options = {}) {
114
151
  const kind = resolveReporterKind(options);
@@ -1,7 +1,7 @@
1
1
  import type { ContentLeaseRecord } from './types/agents.ts';
2
2
  import type { D1DatabaseLike } from './types/cloudflare.ts';
3
3
  import type { ReleaseDetail, ReleaseSummary, SharePackageStatus, WorkstreamDetail, WorkstreamEvent, WorkstreamSummary } from './knowledge-coop.ts';
4
- import type { SdkAppendTaskEventRequest, SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreatePrioritySnapshotRequest, SdkCreateTaskRequest, SdkCursorEntity, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkLeaseEntity, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMessageEntity, SdkMutationRequest, SdkPickRequest, SdkPickResult, SdkPriorityOverrideRequest, SdkRecordRunRequest, SdkRecordScaleDecisionRequest, SdkRecordTaskCreditsRequest, SdkReportEntity, SdkRunEntity, SdkSearchRequest, SdkStartWorkDayRequest, SdkSubscriptionEntity, SdkTaskEntity, SdkTaskSearchRequest, SdkUpsertWorkPolicyRequest, SdkTaskProgressRequest, SdkUpdateRequest, SdkWorkDayEntity, ScaleDecision, TaskCreditLedgerEntry, WorkdayPolicy, PrioritySnapshot } from './sdk-types.ts';
4
+ import type { SdkAppendTaskEventRequest, SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreatePrioritySnapshotRequest, SdkCreateTaskRequest, SdkCursorEntity, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkLeaseEntity, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMessageEntity, SdkMutationRequest, SdkPickRequest, SdkPickResult, SdkPriorityOverrideRequest, SdkClaimWorkdayManagerLeaseRequest, SdkCreateWorkdayRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkRecordWorkerRunnerRequest, SdkRecordRunRequest, SdkRecordScaleDecisionRequest, SdkRecordTaskCreditsRequest, SdkReleaseWorkdayManagerLeaseRequest, SdkReportEntity, SdkRunEntity, SdkSearchRequest, SdkStartWorkDayRequest, SdkSubscriptionEntity, SdkTaskEntity, SdkTaskSearchRequest, SdkUpsertWorkPolicyRequest, SdkTaskProgressRequest, SdkUpdateWorkDayGraphRequest, SdkUpdateRequest, SdkWorkDayEntity, RepositoryClaim, RunnerScaleDecision, ScaleDecision, TaskCreditLedgerEntry, WorkdayManagerLease, WorkdayPolicy, WorkdayRequest, WorkerRunner, PrioritySnapshot } from './sdk-types.ts';
5
5
  import { type LeaseClaimInput } from './stores/lease-store.ts';
6
6
  export interface TryClaimContentLeaseInput extends LeaseClaimInput {
7
7
  }
@@ -37,6 +37,17 @@ export interface AgentDatabase {
37
37
  getManagerContext(taskId: string): Promise<SdkManagerContextPayload>;
38
38
  getWorkPolicy(projectId: string, environment?: string): Promise<WorkdayPolicy | null>;
39
39
  upsertWorkPolicy(request: SdkUpsertWorkPolicyRequest): Promise<WorkdayPolicy | null>;
40
+ createWorkdayRequest(request: SdkCreateWorkdayRequest): Promise<WorkdayRequest | null>;
41
+ listWorkdayRequests(projectId: string, environment: string, state?: string | null): Promise<WorkdayRequest[]>;
42
+ claimWorkdayManagerLease(request: SdkClaimWorkdayManagerLeaseRequest): Promise<WorkdayManagerLease | null>;
43
+ releaseWorkdayManagerLease(request: SdkReleaseWorkdayManagerLeaseRequest): Promise<WorkdayManagerLease | null>;
44
+ recordWorkerRunner(request: SdkRecordWorkerRunnerRequest): Promise<WorkerRunner | null>;
45
+ listWorkerRunners(projectId: string, environment: string): Promise<WorkerRunner[]>;
46
+ recordRepositoryClaim(request: SdkRecordRepositoryClaimRequest): Promise<RepositoryClaim | null>;
47
+ listRepositoryClaims(projectId: string, repositoryId?: string | null): Promise<RepositoryClaim[]>;
48
+ recordRunnerScaleDecision(request: SdkRecordRunnerScaleDecisionRequest): Promise<RunnerScaleDecision | null>;
49
+ listRunnerScaleDecisions(projectId: string, environment: string, workDayId?: string | null): Promise<RunnerScaleDecision[]>;
50
+ updateWorkDayGraph(request: SdkUpdateWorkDayGraphRequest): Promise<SdkWorkDayEntity | null>;
40
51
  listPriorityOverrides(projectId: string): Promise<Record<string, unknown>[]>;
41
52
  upsertPriorityOverride(request: SdkPriorityOverrideRequest): Promise<Record<string, unknown> | null>;
42
53
  createPrioritySnapshot(request: SdkCreatePrioritySnapshotRequest): Promise<PrioritySnapshot | null>;
@@ -71,6 +82,11 @@ export declare class MemoryAgentDatabase implements AgentDatabase {
71
82
  private readonly graphRuns;
72
83
  private readonly reports;
73
84
  private readonly workPolicies;
85
+ private readonly workdayRequests;
86
+ private readonly workdayManagerLeases;
87
+ private readonly workerRunners;
88
+ private readonly repositoryClaims;
89
+ private readonly runnerScaleDecisions;
74
90
  private readonly priorityOverrides;
75
91
  private readonly prioritySnapshots;
76
92
  private readonly taskCreditLedger;
@@ -145,6 +161,41 @@ export declare class MemoryAgentDatabase implements AgentDatabase {
145
161
  }>;
146
162
  getWorkPolicy(projectId: string, environment?: string): Promise<WorkdayPolicy | null>;
147
163
  upsertWorkPolicy(request: SdkUpsertWorkPolicyRequest): Promise<WorkdayPolicy>;
164
+ createWorkdayRequest(request: SdkCreateWorkdayRequest): Promise<WorkdayRequest>;
165
+ listWorkdayRequests(projectId: string, environment: string, state?: string | null): Promise<WorkdayRequest[]>;
166
+ claimWorkdayManagerLease(request: SdkClaimWorkdayManagerLeaseRequest): Promise<WorkdayManagerLease | null>;
167
+ releaseWorkdayManagerLease(request: SdkReleaseWorkdayManagerLeaseRequest): Promise<{
168
+ state: "released";
169
+ updatedAt: string;
170
+ id: string;
171
+ projectId: string;
172
+ environment: import("./sdk-types.ts").ProjectEnvironmentName | "local";
173
+ workDayId: string | null;
174
+ managerId: string;
175
+ heartbeatAt: string;
176
+ expiresAt: string;
177
+ metadata?: Record<string, unknown>;
178
+ createdAt: string;
179
+ } | null>;
180
+ recordWorkerRunner(request: SdkRecordWorkerRunnerRequest): Promise<WorkerRunner>;
181
+ listWorkerRunners(projectId: string, environment: string): Promise<WorkerRunner[]>;
182
+ recordRepositoryClaim(request: SdkRecordRepositoryClaimRequest): Promise<RepositoryClaim>;
183
+ listRepositoryClaims(projectId: string, repositoryId?: string | null): Promise<RepositoryClaim[]>;
184
+ recordRunnerScaleDecision(request: SdkRecordRunnerScaleDecisionRequest): Promise<RunnerScaleDecision>;
185
+ listRunnerScaleDecisions(projectId: string, environment: string, workDayId?: string | null): Promise<RunnerScaleDecision[]>;
186
+ updateWorkDayGraph(request: SdkUpdateWorkDayGraphRequest): Promise<{
187
+ graphVersion: string;
188
+ summaryJson: string;
189
+ updatedAt: string;
190
+ id: string;
191
+ projectId: string;
192
+ state: string;
193
+ capacityBudget: number;
194
+ capacityUsed: number;
195
+ startedAt: string;
196
+ endedAt: string | null;
197
+ createdAt: string;
198
+ } | null>;
148
199
  listPriorityOverrides(projectId: string): Promise<Record<string, unknown>[]>;
149
200
  upsertPriorityOverride(request: SdkPriorityOverrideRequest): Promise<{
150
201
  id: string;
@@ -230,6 +281,17 @@ export declare class CloudflareD1AgentDatabase implements AgentDatabase {
230
281
  }>;
231
282
  getWorkPolicy(projectId: string, environment?: string): Promise<WorkdayPolicy | null>;
232
283
  upsertWorkPolicy(request: SdkUpsertWorkPolicyRequest): Promise<WorkdayPolicy | null>;
284
+ createWorkdayRequest(request: SdkCreateWorkdayRequest): Promise<WorkdayRequest | null>;
285
+ listWorkdayRequests(projectId: string, environment: string, state?: string | null): Promise<WorkdayRequest[]>;
286
+ claimWorkdayManagerLease(request: SdkClaimWorkdayManagerLeaseRequest): Promise<WorkdayManagerLease | null>;
287
+ releaseWorkdayManagerLease(request: SdkReleaseWorkdayManagerLeaseRequest): Promise<WorkdayManagerLease | null>;
288
+ recordWorkerRunner(request: SdkRecordWorkerRunnerRequest): Promise<WorkerRunner | null>;
289
+ listWorkerRunners(projectId: string, environment: string): Promise<WorkerRunner[]>;
290
+ recordRepositoryClaim(request: SdkRecordRepositoryClaimRequest): Promise<RepositoryClaim | null>;
291
+ listRepositoryClaims(projectId: string, repositoryId?: string | null): Promise<RepositoryClaim[]>;
292
+ recordRunnerScaleDecision(request: SdkRecordRunnerScaleDecisionRequest): Promise<RunnerScaleDecision | null>;
293
+ listRunnerScaleDecisions(projectId: string, environment: string, workDayId?: string | null): Promise<RunnerScaleDecision[]>;
294
+ updateWorkDayGraph(request: SdkUpdateWorkDayGraphRequest): Promise<SdkWorkDayEntity | null>;
233
295
  listPriorityOverrides(projectId: string): Promise<import("./stores/helpers.ts").DatabaseRow[]>;
234
296
  upsertPriorityOverride(request: SdkPriorityOverrideRequest): Promise<{
235
297
  id: string;