@treeseed/sdk 0.8.12 → 0.8.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.
@@ -421,6 +421,44 @@ function buildBuiltinModelRegistry(repoRoot) {
421
421
  sortableFields: ["sent_at", "created_at"],
422
422
  pickField: "created_at"
423
423
  },
424
+ approval_request: {
425
+ name: "approval_request",
426
+ aliases: ["approval_requests", "approvals"],
427
+ storage: "d1",
428
+ operations: ["get", "read", "search", "create", "update"],
429
+ fields: {
430
+ team_id: field("team_id", { aliases: ["teamId"], filterable: true, dbColumns: ["team_id"], writeDbColumn: "team_id" }),
431
+ project_id: field("project_id", { aliases: ["projectId"], filterable: true, dbColumns: ["project_id"], writeDbColumn: "project_id" }),
432
+ work_day_id: field("work_day_id", { aliases: ["workDayId"], filterable: true, dbColumns: ["work_day_id"], writeDbColumn: "work_day_id" }),
433
+ task_id: field("task_id", { aliases: ["taskId"], filterable: true, dbColumns: ["task_id"], writeDbColumn: "task_id" }),
434
+ kind: field("kind", { filterable: true, dbColumns: ["kind"], writeDbColumn: "kind" }),
435
+ state: field("state", { filterable: true, dbColumns: ["state"], writeDbColumn: "state" }),
436
+ severity: field("severity", { filterable: true, dbColumns: ["severity"], writeDbColumn: "severity" }),
437
+ created_at: field("created_at", { aliases: ["createdAt"], filterable: true, sortable: true, comparableAs: "date", dbColumns: ["created_at"], writeDbColumn: "created_at" }),
438
+ updated_at: field("updated_at", { aliases: ["updatedAt"], filterable: true, sortable: true, comparableAs: "date", dbColumns: ["updated_at"], writeDbColumn: "updated_at" })
439
+ },
440
+ filterableFields: ["team_id", "project_id", "work_day_id", "task_id", "kind", "state", "severity", "created_at", "updated_at"],
441
+ sortableFields: ["created_at", "updated_at"],
442
+ pickField: "created_at"
443
+ },
444
+ team_inbox_item: {
445
+ name: "team_inbox_item",
446
+ aliases: ["team_inbox_items", "inbox_item", "inbox_items"],
447
+ storage: "d1",
448
+ operations: ["get", "read", "search", "create", "update"],
449
+ fields: {
450
+ team_id: field("team_id", { aliases: ["teamId"], filterable: true, dbColumns: ["team_id"], writeDbColumn: "team_id" }),
451
+ project_id: field("project_id", { aliases: ["projectId"], filterable: true, dbColumns: ["project_id"], writeDbColumn: "project_id" }),
452
+ kind: field("kind", { filterable: true, dbColumns: ["kind"], writeDbColumn: "kind" }),
453
+ state: field("state", { filterable: true, dbColumns: ["state"], writeDbColumn: "state" }),
454
+ item_key: field("item_key", { aliases: ["itemKey"], filterable: true, dbColumns: ["item_key"], writeDbColumn: "item_key" }),
455
+ created_at: field("created_at", { aliases: ["createdAt"], filterable: true, sortable: true, comparableAs: "date", dbColumns: ["created_at"], writeDbColumn: "created_at" }),
456
+ updated_at: field("updated_at", { aliases: ["updatedAt"], filterable: true, sortable: true, comparableAs: "date", dbColumns: ["updated_at"], writeDbColumn: "updated_at" })
457
+ },
458
+ filterableFields: ["team_id", "project_id", "kind", "state", "item_key", "created_at", "updated_at"],
459
+ sortableFields: ["created_at", "updated_at"],
460
+ pickField: "created_at"
461
+ },
424
462
  agent: {
425
463
  name: "agent",
426
464
  aliases: ["agents"],
@@ -497,6 +535,42 @@ function buildBuiltinModelRegistry(repoRoot) {
497
535
  filterableFields: ["model", "item_key", "claimed_by", "lease_expires_at"],
498
536
  sortableFields: ["lease_expires_at", "claimed_at"],
499
537
  pickField: "lease_expires_at"
538
+ },
539
+ workday_manager_lease: {
540
+ name: "workday_manager_lease",
541
+ aliases: ["workday_manager_leases", "manager_lease", "manager_leases"],
542
+ storage: "d1",
543
+ operations: ["get", "read", "search", "create", "update"],
544
+ fields: {
545
+ project_id: field("project_id", { aliases: ["projectId"], filterable: true, dbColumns: ["project_id"], writeDbColumn: "project_id" }),
546
+ environment: field("environment", { filterable: true, dbColumns: ["environment"], writeDbColumn: "environment" }),
547
+ work_day_id: field("work_day_id", { aliases: ["workDayId"], filterable: true, dbColumns: ["work_day_id"], writeDbColumn: "work_day_id" }),
548
+ manager_id: field("manager_id", { aliases: ["managerId"], filterable: true, dbColumns: ["manager_id"], writeDbColumn: "manager_id" }),
549
+ state: field("state", { filterable: true, dbColumns: ["state"], writeDbColumn: "state" }),
550
+ heartbeat_at: field("heartbeat_at", { aliases: ["heartbeatAt"], sortable: true, comparableAs: "date", dbColumns: ["heartbeat_at"], writeDbColumn: "heartbeat_at" }),
551
+ expires_at: field("expires_at", { aliases: ["expiresAt"], sortable: true, comparableAs: "date", dbColumns: ["expires_at"], writeDbColumn: "expires_at" })
552
+ },
553
+ filterableFields: ["project_id", "environment", "work_day_id", "manager_id", "state"],
554
+ sortableFields: ["heartbeat_at", "expires_at"],
555
+ pickField: "heartbeat_at"
556
+ },
557
+ worker_runner: {
558
+ name: "worker_runner",
559
+ aliases: ["worker_runners", "runner", "runners"],
560
+ storage: "d1",
561
+ operations: ["get", "read", "search", "create", "update"],
562
+ fields: {
563
+ project_id: field("project_id", { aliases: ["projectId"], filterable: true, dbColumns: ["project_id"], writeDbColumn: "project_id" }),
564
+ environment: field("environment", { filterable: true, dbColumns: ["environment"], writeDbColumn: "environment" }),
565
+ runner_id: field("runner_id", { aliases: ["runnerId"], filterable: true, sortable: true, dbColumns: ["runner_id"], writeDbColumn: "runner_id" }),
566
+ runner_service_name: field("runner_service_name", { aliases: ["runnerServiceName"], filterable: true, dbColumns: ["runner_service_name"], writeDbColumn: "runner_service_name" }),
567
+ state: field("state", { filterable: true, dbColumns: ["state"], writeDbColumn: "state" }),
568
+ available_capacity: field("available_capacity", { aliases: ["availableCapacity"], sortable: true, comparableAs: "number", dbColumns: ["available_capacity"], writeDbColumn: "available_capacity" }),
569
+ last_heartbeat_at: field("last_heartbeat_at", { aliases: ["lastHeartbeatAt"], sortable: true, comparableAs: "date", dbColumns: ["last_heartbeat_at"], writeDbColumn: "last_heartbeat_at" })
570
+ },
571
+ filterableFields: ["project_id", "environment", "runner_id", "runner_service_name", "state"],
572
+ sortableFields: ["runner_id", "available_capacity", "last_heartbeat_at"],
573
+ pickField: "last_heartbeat_at"
500
574
  }
501
575
  };
502
576
  }
@@ -184,6 +184,11 @@ function workflowInputForOperation(name, input) {
184
184
  return {};
185
185
  case "dev:watch":
186
186
  return { ...input, watch: true };
187
+ case "dev:manager":
188
+ return {
189
+ ...input,
190
+ surfaces: input.withWorker === true ? "manager,worker" : typeof input.surfaces === "string" ? input.surfaces : "manager"
191
+ };
187
192
  default:
188
193
  return input;
189
194
  }
@@ -1071,6 +1076,7 @@ class DefaultTreeseedOperationsProvider {
1071
1076
  new WorkflowOperation("release"),
1072
1077
  new WorkflowOperation("destroy"),
1073
1078
  new WorkflowOperation("dev"),
1079
+ new WorkflowOperation("dev:manager", "dev"),
1074
1080
  new WorkflowOperation("dev:watch", "dev"),
1075
1081
  new InitOperation("init"),
1076
1082
  new HubPlanLaunchOperation("hub.plan_launch"),
@@ -340,14 +340,14 @@ const LOCAL_RUNTIME_AUTH_ENV_KEYS = [
340
340
  "TREESEED_API_DEVICE_ACCESS_TOKEN_TTL",
341
341
  "TREESEED_API_DEVICE_POLL_INTERVAL",
342
342
  "TREESEED_API_WEB_EXCHANGE_TTL",
343
- "TREESEED_GITHUB_CLIENT_ID",
344
- "TREESEED_GITHUB_CLIENT_SECRET",
345
- "TREESEED_GOOGLE_CLIENT_ID",
346
- "TREESEED_GOOGLE_CLIENT_SECRET",
347
- "TREESEED_MICROSOFT_CLIENT_ID",
348
- "TREESEED_MICROSOFT_CLIENT_SECRET",
349
- "TREESEED_APPLE_CLIENT_ID",
350
- "TREESEED_APPLE_CLIENT_SECRET"
343
+ "TREESEED_AUTH_GITHUB_CLIENT_ID",
344
+ "TREESEED_AUTH_GITHUB_CLIENT_SECRET",
345
+ "TREESEED_AUTH_GOOGLE_CLIENT_ID",
346
+ "TREESEED_AUTH_GOOGLE_CLIENT_SECRET",
347
+ "TREESEED_AUTH_MICROSOFT_CLIENT_ID",
348
+ "TREESEED_AUTH_MICROSOFT_CLIENT_SECRET",
349
+ "TREESEED_AUTH_APPLE_CLIENT_ID",
350
+ "TREESEED_AUTH_APPLE_CLIENT_SECRET"
351
351
  ];
352
352
  function localAuthRuntimeVars(env) {
353
353
  return Object.fromEntries(
@@ -52,6 +52,7 @@ const TRESEED_OPERATION_SPECS = [
52
52
  operation({ id: "deploy.release", name: "release", aliases: [], group: "Workflow", summary: "Release changed packages and market from staging to production.", description: "Select changed packages plus dependents, validate publish workflows, release packages first, then promote market from staging to main with aligned package pointers.", provider: "default", related: ["stage", "status", "rollback"] }),
53
53
  operation({ id: "deploy.destroy", name: "destroy", aliases: [], group: "Workflow", summary: "Destroy a persistent environment and its local state.", description: "Delete the selected persistent environment resources and remove the local deploy state after confirmation.", provider: "default", related: ["config", "status"] }),
54
54
  operation({ id: "local.dev", name: "dev", aliases: [], group: "Local Development", summary: "Start the unified local Treeseed development environment.", description: "Start the unified local Treeseed development environment.", provider: "default" }),
55
+ operation({ id: "local.devManager", name: "dev:manager", aliases: [], group: "Local Development", summary: "Start the governed local workday manager.", description: "Start the governed local documentation automation manager through the integrated dev supervisor.", provider: "default", related: ["dev"] }),
55
56
  operation({ id: "local.devWatch", name: "dev:watch", aliases: [], group: "Local Development", summary: "Start local development with rebuild and watch mode.", description: "Start local development with rebuild and watch mode.", provider: "default" }),
56
57
  operation({ id: "local.build", name: "build", aliases: [], group: "Local Development", summary: "Build the tenant site and generated worker artifacts.", description: "Build the tenant site and generated worker artifacts.", provider: "default" }),
57
58
  operation({ id: "local.check", name: "check", aliases: [], group: "Local Development", summary: "Run the tenant check flow.", description: "Run the tenant check flow.", provider: "default" }),
@@ -11,5 +11,6 @@ runLocalD1Migrations({
11
11
  cwd: tenantRoot,
12
12
  wranglerConfig,
13
13
  migrationsRoot,
14
+ persistTo: process.env.TREESEED_API_D1_LOCAL_PERSIST_TO?.trim() || undefined,
14
15
  });
15
16
  process.exit(0);
@@ -1,5 +1,5 @@
1
1
  import type { TreeseedFieldAliasBinding } from './field-aliases.ts';
2
- export declare const SDK_MODEL_NAMES: readonly ["page", "note", "question", "proposal", "decision", "book", "knowledge", "objective", "person", "subscription", "message", "agent", "agent_run", "agent_cursor", "content_lease", "work_day", "task", "task_event", "task_output", "graph_run", "report"];
2
+ export declare const SDK_MODEL_NAMES: readonly ["page", "note", "question", "proposal", "decision", "book", "knowledge", "objective", "person", "subscription", "message", "agent", "agent_run", "agent_cursor", "content_lease", "work_day", "task", "task_event", "task_output", "graph_run", "report", "approval_request", "team_inbox_item", "workday_manager_lease", "worker_runner"];
3
3
  export declare const SDK_OPERATIONS: readonly ["get", "read", "search", "follow", "pick", "create", "update"];
4
4
  export declare const SDK_STORAGE_BACKENDS: readonly ["content", "d1"];
5
5
  export declare const SDK_PICK_STRATEGIES: readonly ["latest", "highest_priority", "oldest"];
@@ -328,7 +328,7 @@ export interface WorkdayManagerLease {
328
328
  createdAt: string;
329
329
  updatedAt: string;
330
330
  }
331
- export type WorkerRunnerState = 'active' | 'sleeping' | 'waking' | 'draining' | 'failed';
331
+ export type WorkerRunnerState = 'active' | 'idle' | 'offline' | 'sleeping' | 'waking' | 'draining' | 'failed';
332
332
  export interface WorkerRunner {
333
333
  id: string;
334
334
  projectId: string;
@@ -411,7 +411,7 @@ export type CapacityOverflowPolicy = 'deny' | 'hard_grant' | 'soft_grant' | 'wei
411
411
  export type CapacityReservationState = 'reserved' | 'consuming' | 'consumed' | 'released' | 'expired' | 'cancelled' | 'failed' | 'overran_pending_approval';
412
412
  export type CapacityEstimatePhase = 'intent' | 'discovery' | 'plan' | 'execution' | 'actual';
413
413
  export type CapacityEstimateConfidence = 'low' | 'medium' | 'high';
414
- export type CapacityApprovalState = 'pending' | 'approved' | 'rejected' | 'expired' | 'superseded';
414
+ export type CapacityApprovalState = 'pending' | 'approved' | 'changes_requested' | 'deferred' | 'rejected' | 'expired' | 'superseded';
415
415
  export type TaskRiskClass = 'low' | 'medium' | 'high';
416
416
  export type TaskMutationScope = 'none' | 'repository_read' | 'repository_write' | 'production';
417
417
  export type TaskConcurrencyClass = 'read_only' | 'repository_claim' | 'exclusive_project' | 'human_attention';
@@ -840,9 +840,36 @@ export interface ApprovalRequest {
840
840
  decidedById: string | null;
841
841
  decidedAt: string | null;
842
842
  decision: Record<string, unknown> | null;
843
+ metadata: Record<string, unknown>;
843
844
  createdAt: string;
844
845
  updatedAt: string;
845
846
  }
847
+ export interface ListApprovalRequestsRequest {
848
+ projectId?: string | null;
849
+ teamId?: string | null;
850
+ state?: CapacityApprovalState | string | Array<CapacityApprovalState | string> | null;
851
+ limit?: number;
852
+ }
853
+ export interface DecideApprovalRequestRequest {
854
+ state: CapacityApprovalState | string;
855
+ optionId?: string | null;
856
+ note?: string | null;
857
+ decision?: Record<string, unknown> | null;
858
+ decidedByType?: string | null;
859
+ decidedById?: string | null;
860
+ }
861
+ export interface UpsertTeamInboxItemRequest {
862
+ id?: string;
863
+ teamId: string;
864
+ projectId?: string | null;
865
+ kind: string;
866
+ state: string;
867
+ title: string;
868
+ summary?: string | null;
869
+ href?: string | null;
870
+ itemKey?: string | null;
871
+ metadata?: Record<string, unknown> | null;
872
+ }
846
873
  export interface CapacityTaskExecutionEnvelope {
847
874
  providerId?: string | null;
848
875
  laneId?: string | null;
package/dist/sdk-types.js CHANGED
@@ -19,7 +19,11 @@ const SDK_MODEL_NAMES = [
19
19
  "task_event",
20
20
  "task_output",
21
21
  "graph_run",
22
- "report"
22
+ "report",
23
+ "approval_request",
24
+ "team_inbox_item",
25
+ "workday_manager_lease",
26
+ "worker_runner"
23
27
  ];
24
28
  const SDK_OPERATIONS = ["get", "read", "search", "follow", "pick", "create", "update"];
25
29
  const SDK_STORAGE_BACKENDS = ["content", "d1"];
package/dist/sdk.d.ts CHANGED
@@ -3,7 +3,7 @@ import { ContentStore } from './content-store.ts';
3
3
  import { type AgentDatabase } from './d1-store.ts';
4
4
  import { type LoadedTreeseedPluginEntry } from './platform/plugins.ts';
5
5
  import type { ReleaseDetail, ReleaseSummary, SharePackageStatus, WorkstreamDetail, WorkstreamEvent, WorkstreamSummary } from './project-workflow.ts';
6
- import type { SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreatePrioritySnapshotRequest, SdkCreateTaskRequest, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkJsonEnvelope, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMutationRequest, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkContextPackRequest, SdkGraphDslParseResult, SdkPickRequest, SdkPriorityOverrideRequest, SdkClaimWorkdayManagerLeaseRequest, SdkCreateWorkdayRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkRecordWorkerRunnerRequest, SdkRecordRunRequest, SdkRecordScaleDecisionRequest, SdkRecordTaskCreditsRequest, SdkReleaseWorkdayManagerLeaseRequest, SdkSearchRequest, SdkStartWorkDayRequest, SdkTaskProgressRequest, SdkTaskSearchRequest, SdkUpsertWorkPolicyRequest, SdkUpdateWorkDayGraphRequest, SdkUpdateRequest, SdkModelDefinition, SdkModelRegistry, SdkGraphRankingProvider, SdkDispatchConfig, SdkDispatchRequest, SdkDispatchResult, PrioritySnapshot, RepositoryClaim, RunnerScaleDecision, ScaleDecision, TaskCreditLedgerEntry, WorkdayManagerLease, WorkdayPolicy, WorkdayRequest, WorkerRunner } from './sdk-types.ts';
6
+ import type { SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, CreateApprovalRequestRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreatePrioritySnapshotRequest, SdkCreateTaskRequest, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkJsonEnvelope, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMutationRequest, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkContextPackRequest, SdkGraphDslParseResult, SdkPickRequest, SdkPriorityOverrideRequest, SdkClaimWorkdayManagerLeaseRequest, SdkCreateWorkdayRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkRecordWorkerRunnerRequest, SdkRecordRunRequest, SdkRecordScaleDecisionRequest, SdkRecordTaskCreditsRequest, SdkReleaseWorkdayManagerLeaseRequest, SdkSearchRequest, SdkStartWorkDayRequest, SdkTaskProgressRequest, SdkTaskSearchRequest, SdkUpsertWorkPolicyRequest, SdkUpdateWorkDayGraphRequest, SdkUpdateRequest, SdkModelDefinition, SdkModelRegistry, SdkGraphRankingProvider, SdkDispatchConfig, SdkDispatchRequest, SdkDispatchResult, DecideApprovalRequestRequest, ListApprovalRequestsRequest, PrioritySnapshot, RepositoryClaim, RunnerScaleDecision, ScaleDecision, TaskCreditLedgerEntry, WorkdayManagerLease, WorkdayPolicy, WorkdayRequest, WorkerRunner, UpsertTeamInboxItemRequest } from './sdk-types.ts';
7
7
  export interface AgentSdkOptions {
8
8
  repoRoot?: string;
9
9
  database?: AgentDatabase;
@@ -92,6 +92,7 @@ export declare class AgentSdk {
92
92
  listWorkdayRequests(projectId: string, environment: string, state?: string | null): Promise<SdkJsonEnvelope<WorkdayRequest[]>>;
93
93
  claimWorkdayManagerLease(request: SdkClaimWorkdayManagerLeaseRequest): Promise<SdkJsonEnvelope<WorkdayManagerLease>>;
94
94
  releaseWorkdayManagerLease(request: SdkReleaseWorkdayManagerLeaseRequest): Promise<SdkJsonEnvelope<WorkdayManagerLease>>;
95
+ listWorkdayManagerLeases(projectId: string, environment: string): Promise<SdkJsonEnvelope<WorkdayManagerLease[]>>;
95
96
  recordWorkerRunner(request: SdkRecordWorkerRunnerRequest): Promise<SdkJsonEnvelope<WorkerRunner>>;
96
97
  listWorkerRunners(projectId: string, environment: string): Promise<SdkJsonEnvelope<WorkerRunner[]>>;
97
98
  recordRepositoryClaim(request: SdkRecordRepositoryClaimRequest): Promise<SdkJsonEnvelope<RepositoryClaim>>;
@@ -107,6 +108,10 @@ export declare class AgentSdk {
107
108
  listTaskCredits(workDayId: string): Promise<SdkJsonEnvelope<TaskCreditLedgerEntry[]>>;
108
109
  recordScaleDecision(request: SdkRecordScaleDecisionRequest): Promise<SdkJsonEnvelope<ScaleDecision>>;
109
110
  getLatestScaleDecision(projectId: string, environment: string, poolName: string): Promise<SdkJsonEnvelope<ScaleDecision>>;
111
+ createApprovalRequest(request: CreateApprovalRequestRequest): Promise<SdkJsonEnvelope<import("./sdk-types.ts").ApprovalRequest | null>>;
112
+ listApprovalRequests(request?: ListApprovalRequestsRequest): Promise<SdkJsonEnvelope<import("./sdk-types.ts").ApprovalRequest[]>>;
113
+ decideApprovalRequest(id: string, request: DecideApprovalRequestRequest): Promise<SdkJsonEnvelope<import("./sdk-types.ts").ApprovalRequest | null>>;
114
+ upsertTeamInboxItem(request: UpsertTeamInboxItemRequest): Promise<SdkJsonEnvelope<import("./project-workflow.ts").InboxItem | null>>;
110
115
  listWorkstreams(projectId: string): Promise<SdkJsonEnvelope<WorkstreamSummary[]>>;
111
116
  getWorkstream(workstreamId: string): Promise<SdkJsonEnvelope<WorkstreamDetail>>;
112
117
  upsertWorkstream(input: Partial<WorkstreamSummary> & Pick<WorkstreamSummary, 'projectId' | 'title'>): Promise<SdkJsonEnvelope<WorkstreamSummary>>;
package/dist/sdk.js CHANGED
@@ -281,6 +281,10 @@ class AgentSdk {
281
281
  const payload = await this.database.releaseWorkdayManagerLease(request);
282
282
  return this.envelope("workday_manager_lease", "release", payload);
283
283
  }
284
+ async listWorkdayManagerLeases(projectId, environment) {
285
+ const payload = await this.database.listWorkdayManagerLeases(projectId, environment);
286
+ return this.envelope("workday_manager_lease", "search", payload, { count: payload.length });
287
+ }
284
288
  async recordWorkerRunner(request) {
285
289
  const payload = await this.database.recordWorkerRunner(request);
286
290
  return this.envelope("worker_runner", "update", payload);
@@ -341,6 +345,22 @@ class AgentSdk {
341
345
  const payload = await this.database.getLatestScaleDecision(projectId, environment, poolName);
342
346
  return this.envelope("report", "get", payload);
343
347
  }
348
+ async createApprovalRequest(request) {
349
+ const payload = await this.database.createApprovalRequest(request);
350
+ return this.envelope("approval_request", "create", payload);
351
+ }
352
+ async listApprovalRequests(request = {}) {
353
+ const payload = await this.database.listApprovalRequests(request);
354
+ return this.envelope("approval_request", "search", payload, { count: payload.length });
355
+ }
356
+ async decideApprovalRequest(id, request) {
357
+ const payload = await this.database.decideApprovalRequest(id, request);
358
+ return this.envelope("approval_request", "update", payload);
359
+ }
360
+ async upsertTeamInboxItem(request) {
361
+ const payload = await this.database.upsertTeamInboxItem(request);
362
+ return this.envelope("team_inbox_item", "update", payload);
363
+ }
344
364
  async listWorkstreams(projectId) {
345
365
  const payload = await this.database.listWorkstreams(projectId);
346
366
  return this.envelope("task", "search", payload, { count: payload.length });
@@ -0,0 +1,5 @@
1
+ import type { SeedDiagnostic } from './types.js';
2
+ export declare function errorDiagnostic(code: string, message: string, path?: string): SeedDiagnostic;
3
+ export declare function warningDiagnostic(code: string, message: string, path?: string): SeedDiagnostic;
4
+ export declare function hasSeedErrors(diagnostics: SeedDiagnostic[]): boolean;
5
+ export declare function formatSeedDiagnostics(diagnostics: SeedDiagnostic[]): string[];
@@ -0,0 +1,22 @@
1
+ function errorDiagnostic(code, message, path) {
2
+ return { severity: "error", code, message, path };
3
+ }
4
+ function warningDiagnostic(code, message, path) {
5
+ return { severity: "warning", code, message, path };
6
+ }
7
+ function hasSeedErrors(diagnostics) {
8
+ return diagnostics.some((diagnostic) => diagnostic.severity === "error");
9
+ }
10
+ function formatSeedDiagnostics(diagnostics) {
11
+ return diagnostics.map((diagnostic) => {
12
+ const prefix = diagnostic.severity === "error" ? "ERROR" : "WARN";
13
+ const location = diagnostic.path ? ` ${diagnostic.path}` : "";
14
+ return `${prefix} ${diagnostic.code}${location}: ${diagnostic.message}`;
15
+ });
16
+ }
17
+ export {
18
+ errorDiagnostic,
19
+ formatSeedDiagnostics,
20
+ hasSeedErrors,
21
+ warningDiagnostic
22
+ };
@@ -0,0 +1,20 @@
1
+ import type { SeedPlan } from './types.js';
2
+ export { formatSeedDiagnostics, hasSeedErrors } from './errors.js';
3
+ export { formatSeedPlan } from './planner.js';
4
+ export type * from './types.js';
5
+ export declare function loadAndPlanSeed(input: {
6
+ projectRoot: string;
7
+ seedName: string;
8
+ environments?: string;
9
+ mode: SeedPlan['mode'];
10
+ }): {
11
+ ok: boolean;
12
+ plan: null;
13
+ diagnostics: import("./types.js").SeedDiagnostic[];
14
+ manifestPath: string;
15
+ } | {
16
+ ok: boolean;
17
+ plan: SeedPlan;
18
+ diagnostics: import("./types.js").SeedDiagnostic[];
19
+ manifestPath: string;
20
+ };
@@ -0,0 +1,53 @@
1
+ import { errorDiagnostic, hasSeedErrors } from "./errors.js";
2
+ import { loadSeedManifest } from "./loader.js";
3
+ import { resolveSelectedSeedEnvironments } from "./normalize.js";
4
+ import { createSeedPlan } from "./planner.js";
5
+ import { parseSeedManifest } from "./schema.js";
6
+ import { formatSeedDiagnostics, hasSeedErrors as hasSeedErrors2 } from "./errors.js";
7
+ import { formatSeedPlan } from "./planner.js";
8
+ function loadAndPlanSeed(input) {
9
+ const loaded = loadSeedManifest(input.projectRoot, input.seedName);
10
+ const diagnostics = [...loaded.diagnostics];
11
+ const manifest = parseSeedManifest(loaded.value, diagnostics);
12
+ if (!manifest) {
13
+ return {
14
+ ok: false,
15
+ plan: null,
16
+ diagnostics,
17
+ manifestPath: loaded.path
18
+ };
19
+ }
20
+ if (manifest.name !== input.seedName) {
21
+ diagnostics.push(errorDiagnostic("seed.name_mismatch", `Manifest name ${manifest.name} does not match requested seed ${input.seedName}.`, "name"));
22
+ }
23
+ const selected = resolveSelectedSeedEnvironments(manifest, input.environments);
24
+ for (const message of selected.errors) {
25
+ diagnostics.push(errorDiagnostic("seed.environment_selection", message, "environments"));
26
+ }
27
+ if (hasSeedErrors(diagnostics)) {
28
+ return {
29
+ ok: false,
30
+ plan: null,
31
+ diagnostics,
32
+ manifestPath: loaded.path
33
+ };
34
+ }
35
+ return {
36
+ ok: true,
37
+ plan: createSeedPlan({
38
+ manifest,
39
+ manifestPath: loaded.path,
40
+ environments: selected.environments,
41
+ mode: input.mode,
42
+ diagnostics
43
+ }),
44
+ diagnostics,
45
+ manifestPath: loaded.path
46
+ };
47
+ }
48
+ export {
49
+ formatSeedDiagnostics,
50
+ formatSeedPlan,
51
+ hasSeedErrors2 as hasSeedErrors,
52
+ loadAndPlanSeed
53
+ };
@@ -0,0 +1,8 @@
1
+ import type { SeedDiagnostic } from './types.js';
2
+ export type LoadedSeedDocument = {
3
+ path: string;
4
+ value: unknown;
5
+ diagnostics: SeedDiagnostic[];
6
+ };
7
+ export declare function resolveSeedManifestPath(projectRoot: string, seedName: string): string;
8
+ export declare function loadSeedManifest(projectRoot: string, seedName: string): LoadedSeedDocument;
@@ -0,0 +1,32 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { parseDocument } from "yaml";
4
+ import { errorDiagnostic } from "./errors.js";
5
+ function resolveSeedManifestPath(projectRoot, seedName) {
6
+ return resolve(projectRoot, "seeds", `${seedName}.yaml`);
7
+ }
8
+ function loadSeedManifest(projectRoot, seedName) {
9
+ const path = resolveSeedManifestPath(projectRoot, seedName);
10
+ const diagnostics = [];
11
+ if (!/^[a-z0-9][a-z0-9._-]*$/u.test(seedName)) {
12
+ diagnostics.push(errorDiagnostic("seed.invalid_name", `Seed name must be a simple file-safe identifier: ${seedName}.`, "name"));
13
+ return { path, value: null, diagnostics };
14
+ }
15
+ if (!existsSync(path)) {
16
+ diagnostics.push(errorDiagnostic("seed.not_found", `Seed manifest not found at ${path}.`, "manifest"));
17
+ return { path, value: null, diagnostics };
18
+ }
19
+ const source = readFileSync(path, "utf8");
20
+ const document = parseDocument(source, { prettyErrors: false });
21
+ for (const parseError of document.errors) {
22
+ diagnostics.push(errorDiagnostic("seed.yaml_parse_error", parseError.message, "manifest"));
23
+ }
24
+ if (diagnostics.length > 0) {
25
+ return { path, value: null, diagnostics };
26
+ }
27
+ return { path, value: document.toJSON(), diagnostics };
28
+ }
29
+ export {
30
+ loadSeedManifest,
31
+ resolveSeedManifestPath
32
+ };
@@ -0,0 +1,13 @@
1
+ import type { NormalizedSeedResource, SeedEnvironment, SeedManifest } from './types.js';
2
+ export declare function seedOwnershipMetadata(seed: SeedManifest, resourceKey: string): {
3
+ seed: {
4
+ name: string;
5
+ resourceKey: string;
6
+ version: 1;
7
+ };
8
+ };
9
+ export declare function normalizeSeedResources(manifest: SeedManifest, selected: SeedEnvironment[]): NormalizedSeedResource[];
10
+ export declare function resolveSelectedSeedEnvironments(manifest: SeedManifest, requested: string | undefined): {
11
+ environments: SeedEnvironment[];
12
+ errors: string[];
13
+ };