@treeseed/sdk 0.9.0 → 0.10.5

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 (76) hide show
  1. package/dist/api/app.d.ts +8 -0
  2. package/dist/api/app.js +404 -0
  3. package/dist/api/auth/d1-database.d.ts +3 -0
  4. package/dist/api/auth/d1-database.js +20 -0
  5. package/dist/api/auth/d1-provider.d.ts +79 -0
  6. package/dist/api/auth/d1-provider.js +92 -0
  7. package/dist/api/auth/d1-store.d.ts +114 -0
  8. package/dist/api/auth/d1-store.js +902 -0
  9. package/dist/api/auth/memory-provider.d.ts +77 -0
  10. package/dist/api/auth/memory-provider.js +256 -0
  11. package/dist/api/auth/rbac.d.ts +22 -0
  12. package/dist/api/auth/rbac.js +162 -0
  13. package/dist/api/auth/tokens.d.ts +18 -0
  14. package/dist/api/auth/tokens.js +56 -0
  15. package/dist/api/config.d.ts +2 -0
  16. package/dist/api/config.js +118 -0
  17. package/dist/api/http.d.ts +28 -0
  18. package/dist/api/http.js +51 -0
  19. package/dist/api/index.d.ts +10 -0
  20. package/dist/api/index.js +27 -0
  21. package/dist/api/operations-routes.d.ts +11 -0
  22. package/dist/api/operations-routes.js +39 -0
  23. package/dist/api/operations.d.ts +3 -0
  24. package/dist/api/operations.js +26 -0
  25. package/dist/api/providers.d.ts +2 -0
  26. package/dist/api/providers.js +68 -0
  27. package/dist/api/railway.d.ts +52 -0
  28. package/dist/api/railway.js +71 -0
  29. package/dist/api/sdk-dispatch.d.ts +6 -0
  30. package/dist/api/sdk-dispatch.js +14 -0
  31. package/dist/api/sdk-routes.d.ts +11 -0
  32. package/dist/api/sdk-routes.js +29 -0
  33. package/dist/api/templates.d.ts +3 -0
  34. package/dist/api/templates.js +31 -0
  35. package/dist/api/types.d.ts +232 -0
  36. package/dist/api/types.js +0 -0
  37. package/dist/capacity-provider.d.ts +383 -0
  38. package/dist/capacity-provider.js +535 -0
  39. package/dist/capacity.d.ts +2 -35
  40. package/dist/control-plane-client.d.ts +8 -3
  41. package/dist/control-plane-client.js +12 -1
  42. package/dist/dispatch.js +0 -1
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +40 -0
  45. package/dist/market-client.d.ts +1 -5
  46. package/dist/market-client.js +2 -8
  47. package/dist/operations/providers/default.js +0 -9
  48. package/dist/operations/services/config-runtime.d.ts +2 -2
  49. package/dist/operations/services/config-runtime.js +55 -3
  50. package/dist/operations/services/github-automation.d.ts +10 -15
  51. package/dist/operations/services/github-automation.js +3 -35
  52. package/dist/operations/services/hosting-audit.d.ts +1 -1
  53. package/dist/operations/services/hosting-audit.js +3 -27
  54. package/dist/operations/services/hub-launch.d.ts +0 -1
  55. package/dist/operations/services/hub-launch.js +1 -2
  56. package/dist/operations/services/hub-provider-launch.d.ts +0 -15
  57. package/dist/operations/services/hub-provider-launch.js +5 -41
  58. package/dist/operations/services/package-reference-policy.d.ts +1 -0
  59. package/dist/operations/services/package-reference-policy.js +10 -2
  60. package/dist/operations/services/project-platform.d.ts +9 -9
  61. package/dist/operations/services/project-platform.js +6 -17
  62. package/dist/operations/services/release-candidate.js +19 -3
  63. package/dist/operations-registry.js +1 -3
  64. package/dist/platform/contracts.d.ts +2 -2
  65. package/dist/project-workflow.d.ts +0 -3
  66. package/dist/scripts/publish-package.js +5 -1
  67. package/dist/scripts/tenant-workflow-action.js +3 -3
  68. package/dist/scripts/workflow-commands.test.js +3 -6
  69. package/dist/sdk-types.d.ts +33 -1
  70. package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +1 -4
  71. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/api/server.js +1 -1
  72. package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +1 -17
  73. package/dist/workflow/operations.js +26 -8
  74. package/package.json +14 -1
  75. package/templates/github/hosted-project.workflow.yml +0 -1
  76. package/templates/github/deploy-processing.workflow.yml +0 -123
@@ -2,7 +2,7 @@ import { type ControlPlaneReporter } from '../../control-plane.ts';
2
2
  import type { TreeseedRunnableBootstrapSystem } from '../../reconcile/index.ts';
3
3
  import { type TreeseedBootstrapExecution, type TreeseedBootstrapWriter } from './bootstrap-runner.ts';
4
4
  export type ProjectPlatformScope = 'local' | 'staging' | 'prod';
5
- export type ProjectPlatformAction = 'deploy_web' | 'deploy_processing' | 'publish_content' | 'monitor';
5
+ export type ProjectPlatformAction = 'deploy_web' | 'publish_content' | 'monitor';
6
6
  export interface ProjectPlatformActionOptions {
7
7
  tenantRoot: string;
8
8
  scope: ProjectPlatformScope;
@@ -224,8 +224,8 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
224
224
  } | {
225
225
  apiHealth: string;
226
226
  apiReady: string;
227
- d1Health: string | null;
228
- agentHealth: string;
227
+ d1Health: string;
228
+ agentHealth: null;
229
229
  processingAgentApi: boolean;
230
230
  };
231
231
  };
@@ -423,8 +423,8 @@ export declare function monitorProjectPlatform(options: ProjectPlatformActionOpt
423
423
  } | {
424
424
  apiHealth: string;
425
425
  apiReady: string;
426
- d1Health: string | null;
427
- agentHealth: string;
426
+ d1Health: string;
427
+ agentHealth: null;
428
428
  processingAgentApi: boolean;
429
429
  };
430
430
  };
@@ -574,8 +574,8 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
574
574
  } | {
575
575
  apiHealth: string;
576
576
  apiReady: string;
577
- d1Health: string | null;
578
- agentHealth: string;
577
+ d1Health: string;
578
+ agentHealth: null;
579
579
  processingAgentApi: boolean;
580
580
  };
581
581
  };
@@ -718,8 +718,8 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
718
718
  } | {
719
719
  apiHealth: string;
720
720
  apiReady: string;
721
- d1Health: string | null;
722
- agentHealth: string;
721
+ d1Health: string;
722
+ agentHealth: null;
723
723
  processingAgentApi: boolean;
724
724
  };
725
725
  };
@@ -633,10 +633,6 @@ function resolveImmediateApiProbeUrl(siteConfig, state, target) {
633
633
  }
634
634
  return null;
635
635
  }
636
- function isProcessingAgentApiService(siteConfig) {
637
- const startCommand = String(siteConfig.services?.api?.railway?.startCommand ?? siteConfig.services?.api?.startCommand ?? "");
638
- return /\btreeseed-processing(?:\.js)?\s+api\b/u.test(startCommand) || /treeseed-processing\.js\s+api\b/u.test(startCommand);
639
- }
640
636
  function resolveApiMonitorEndpoints(siteConfig, apiBaseUrl) {
641
637
  if (!apiBaseUrl) {
642
638
  return {
@@ -644,17 +640,16 @@ function resolveApiMonitorEndpoints(siteConfig, apiBaseUrl) {
644
640
  apiReady: null,
645
641
  d1Health: null,
646
642
  agentHealth: null,
647
- processingAgentApi: isProcessingAgentApiService(siteConfig)
643
+ processingAgentApi: false
648
644
  };
649
645
  }
650
646
  const baseUrl = String(apiBaseUrl).replace(/\/+$/u, "");
651
- const processingAgentApi = isProcessingAgentApiService(siteConfig);
652
647
  return {
653
648
  apiHealth: `${baseUrl}/healthz`,
654
649
  apiReady: `${baseUrl}/readyz`,
655
- d1Health: processingAgentApi ? null : `${baseUrl}/healthz/deep`,
656
- agentHealth: processingAgentApi ? `${baseUrl}/agent/healthz` : `${baseUrl}/internal/core/agent/healthz`,
657
- processingAgentApi
650
+ d1Health: `${baseUrl}/healthz/deep`,
651
+ agentHealth: null,
652
+ processingAgentApi: false
658
653
  };
659
654
  }
660
655
  async function probeQueue(siteConfig, state) {
@@ -1440,7 +1435,7 @@ async function runProjectPlatformAction(action, options) {
1440
1435
  const previousWorkflowAction = process.env.TREESEED_WORKFLOW_ACTION;
1441
1436
  const previousWorkflowPlane = process.env.TREESEED_WORKFLOW_PLANE;
1442
1437
  process.env.TREESEED_WORKFLOW_ACTION = action;
1443
- process.env.TREESEED_WORKFLOW_PLANE = previousWorkflowPlane ?? (action === "deploy_processing" ? "processing" : "web");
1438
+ process.env.TREESEED_WORKFLOW_PLANE = previousWorkflowPlane ?? "web";
1444
1439
  applyTreeseedEnvironmentToProcess({ tenantRoot: options.tenantRoot, scope: options.scope, override: true });
1445
1440
  const reporter = resolveReporter(options.tenantRoot, options.reporter);
1446
1441
  try {
@@ -1451,12 +1446,6 @@ async function runProjectPlatformAction(action, options) {
1451
1446
  reporter,
1452
1447
  bootstrapSystems: options.bootstrapSystems ?? WEB_PLATFORM_BOOTSTRAP_SYSTEMS
1453
1448
  });
1454
- case "deploy_processing":
1455
- return await deployProjectPlatform({
1456
- ...options,
1457
- reporter,
1458
- bootstrapSystems: options.bootstrapSystems ?? PROCESSING_PLATFORM_BOOTSTRAP_SYSTEMS
1459
- });
1460
1449
  case "publish_content":
1461
1450
  return await publishProjectContent({ ...options, reporter });
1462
1451
  case "monitor":
@@ -1467,7 +1456,7 @@ async function runProjectPlatformAction(action, options) {
1467
1456
  } catch (error) {
1468
1457
  await reportDeployment(reporter, {
1469
1458
  environment: options.scope,
1470
- deploymentKind: action === "publish_content" ? "content" : action === "deploy_web" || action === "deploy_processing" ? "code" : "mixed",
1459
+ deploymentKind: action === "publish_content" ? "content" : action === "deploy_web" ? "code" : "mixed",
1471
1460
  status: "failed",
1472
1461
  sourceRef: currentRef(options.tenantRoot),
1473
1462
  commitSha: currentCommit(options.tenantRoot),
@@ -6,7 +6,7 @@ import { dirname, join, relative, resolve } from "node:path";
6
6
  import { isTreeseedEnvironmentEntryRelevant, isTreeseedEnvironmentEntryRequired } from "../../platform/environment.js";
7
7
  import { maybeResolveGitHubRepositorySlug } from "./github-automation.js";
8
8
  import { createGitHubApiClient, listGitHubEnvironmentSecretNames, listGitHubEnvironmentVariableNames } from "./github-api.js";
9
- import { collectInternalDevReferenceIssues } from "./package-reference-policy.js";
9
+ import { collectInternalDevReferenceIssues, normalizeGitRemoteForManifest } from "./package-reference-policy.js";
10
10
  import { collectTreeseedEnvironmentContext, resolveTreeseedMachineEnvironmentValues, validateTreeseedCommandEnvironment } from "./config-runtime.js";
11
11
  import { loadDeployState } from "./deploy.js";
12
12
  import { loadCliDeployConfig } from "./runtime-tools.js";
@@ -187,6 +187,7 @@ function applyPlannedStableMetadata(root, plannedVersions) {
187
187
  const stableVersions = new Map(
188
188
  Object.entries(plannedVersions).filter(([, version]) => STABLE_SEMVER.test(version))
189
189
  );
190
+ const stableGitReferences = stablePackageGitReferences(root, stableVersions);
190
191
  const targets = [
191
192
  { name: "@treeseed/market", dir: root },
192
193
  ...workspacePackages(root).map((pkg) => ({ name: pkg.name, dir: pkg.dir }))
@@ -206,8 +207,9 @@ function applyPlannedStableMetadata(root, plannedVersions) {
206
207
  if (!values || typeof values !== "object" || Array.isArray(values)) continue;
207
208
  for (const [dependencyName, version] of stableVersions.entries()) {
208
209
  if (!(dependencyName in values)) continue;
209
- if (String(values[dependencyName]) === version) continue;
210
- values[dependencyName] = version;
210
+ const dependencySpec = stableGitReferences.get(dependencyName) ?? version;
211
+ if (String(values[dependencyName]) === dependencySpec) continue;
212
+ values[dependencyName] = dependencySpec;
211
213
  changed = true;
212
214
  }
213
215
  }
@@ -216,6 +218,20 @@ function applyPlannedStableMetadata(root, plannedVersions) {
216
218
  }
217
219
  }
218
220
  }
221
+ function stablePackageGitReferences(root, versions) {
222
+ return new Map(workspacePackages(root).map((pkg) => {
223
+ const version = versions.get(pkg.name);
224
+ if (!version) return null;
225
+ let remote = null;
226
+ try {
227
+ remote = run("git", ["remote", "get-url", "origin"], { cwd: pkg.dir, capture: true }).trim();
228
+ } catch {
229
+ remote = null;
230
+ }
231
+ const manifestRemote = normalizeGitRemoteForManifest(remote ?? "", "preserve-origin");
232
+ return manifestRemote ? [pkg.name, `${manifestRemote}#${version}`] : null;
233
+ }).filter((entry) => Boolean(entry)));
234
+ }
219
235
  function rehearsalVerifyScript(root) {
220
236
  const scripts = packageScripts(resolve(root, "package.json"));
221
237
  for (const scriptName of ["verify:direct", "verify:local", "verify", "build"]) {
@@ -51,9 +51,7 @@ const TRESEED_OPERATION_SPECS = [
51
51
  operation({ id: "project.export", name: "export", aliases: [], group: "Utilities", summary: "Export a Markdown snapshot of the current codebase.", description: "Generate a Markdown codebase snapshot for the selected directory using the SDK-owned repomix integration and store it under .treeseed/exports.", provider: "default", related: ["status", "config"] }),
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
- 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"] }),
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" }),
54
+ operation({ id: "local.dev", name: "dev", aliases: [], group: "Local Development", summary: "Start the local Treeseed Market web/API development environment.", description: "Start the local Treeseed Market web/API development environment. Capacity provider lifecycle is handled by the capacity command.", provider: "default" }),
57
55
  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" }),
58
56
  operation({ id: "local.check", name: "check", aliases: [], group: "Local Development", summary: "Run the tenant check flow.", description: "Run the tenant check flow.", provider: "default" }),
59
57
  operation({ id: "local.preview", name: "preview", aliases: [], group: "Local Development", summary: "Preview the built tenant site locally.", description: "Preview the built tenant site locally.", provider: "default" }),
@@ -1,4 +1,4 @@
1
- import type { CapacityProviderRegistration } from '../capacity.ts';
1
+ import type { CapacityProviderRegistrationRequest } from '../capacity-provider.ts';
2
2
  export type TreeseedFeatureName = 'docs' | 'books' | 'notes' | 'questions' | 'objectives' | 'proposals' | 'decisions' | 'agents' | 'forms';
3
3
  export type TreeseedContentCollection = 'pages' | 'notes' | 'questions' | 'objectives' | 'proposals' | 'decisions' | 'people' | 'agents' | 'books' | 'docs' | 'templates' | 'knowledge_packs' | 'workdays';
4
4
  export interface TreeseedFeatureModules {
@@ -302,7 +302,7 @@ export interface TreeseedDeployConfig {
302
302
  surfaces?: TreeseedPlatformSurfacesConfig;
303
303
  services?: TreeseedManagedServicesConfig;
304
304
  processing?: TreeseedProcessingConfig;
305
- capacityProviders?: Record<string, CapacityProviderRegistration>;
305
+ capacityProviders?: Record<string, CapacityProviderRegistrationRequest>;
306
306
  smtp?: {
307
307
  enabled?: boolean;
308
308
  };
@@ -204,9 +204,6 @@ export interface LaunchProjectRequest {
204
204
  cloudflareHostId?: string | null;
205
205
  cloudflareHostMode?: 'team_owned' | 'treeseed_managed' | null;
206
206
  cloudflareHostConfig?: Record<string, unknown> | null;
207
- processingHostId?: string | null;
208
- processingHostMode?: 'team_owned' | 'treeseed_managed' | null;
209
- processingHostConfig?: Record<string, unknown> | null;
210
207
  targetEnvironments?: Array<'local' | 'staging' | 'prod'>;
211
208
  publicSite?: boolean;
212
209
  repoProvider?: 'github';
@@ -15,9 +15,13 @@ if (process.env.GITHUB_ACTIONS === 'true') {
15
15
  npmArgs.push(...extraArgs);
16
16
  const result = spawnSync('npm', npmArgs, {
17
17
  cwd: packageRoot,
18
- stdio: 'inherit',
18
+ encoding: 'utf8',
19
19
  env: process.env,
20
20
  });
21
+ if (result.stdout)
22
+ process.stdout.write(result.stdout);
23
+ if (result.stderr)
24
+ process.stderr.write(result.stderr);
21
25
  if (result.error) {
22
26
  console.error(result.error.message);
23
27
  process.exit(1);
@@ -56,15 +56,15 @@ function parseArgs(argv) {
56
56
  return parsed;
57
57
  }
58
58
  function parseAction(value) {
59
- if (value === 'deploy_web' || value === 'deploy_processing' || value === 'publish_content' || value === 'monitor') {
59
+ if (value === 'deploy_web' || value === 'publish_content' || value === 'monitor') {
60
60
  return value;
61
61
  }
62
- throw new Error(`Unsupported workflow action "${value}". Expected deploy_web, deploy_processing, publish_content, or monitor.`);
62
+ throw new Error(`Unsupported workflow action "${value}". Expected deploy_web, publish_content, or monitor.`);
63
63
  }
64
64
  async function main() {
65
65
  const options = parseArgs(process.argv.slice(2));
66
66
  process.env.TREESEED_WORKFLOW_ACTION = options.action;
67
- process.env.TREESEED_WORKFLOW_PLANE ||= options.action === 'deploy_processing' ? 'processing' : 'web';
67
+ process.env.TREESEED_WORKFLOW_PLANE ||= 'web';
68
68
  const scope = resolveScope(options.environment);
69
69
  const result = await runProjectPlatformAction(options.action, {
70
70
  tenantRoot,
@@ -6,7 +6,7 @@ import {
6
6
  deployTargetLabel,
7
7
  loadDeployState,
8
8
  } from '../dist/scripts/deploy-lib.js';
9
- import { renderDeployProcessingWorkflow, renderDeployWebWorkflow } from '../dist/operations/services/github-automation.js';
9
+ import { renderDeployWebWorkflow } from '../dist/operations/services/github-automation.js';
10
10
  import { incrementVersion } from '../dist/scripts/workspace-save-lib.js';
11
11
  import { makeTenantRoot } from './cli-test-fixtures.js';
12
12
 
@@ -25,15 +25,12 @@ test('branch preview state derives branch-specific worker names', () => {
25
25
  assert.equal(state.previewEnabled, true);
26
26
  });
27
27
 
28
- test('deploy workflows expose final web and processing actions', () => {
28
+ test('deploy workflow exposes final web actions only', () => {
29
29
  const webWorkflow = renderDeployWebWorkflow({ workingDirectory: '.' });
30
- const processingWorkflow = renderDeployProcessingWorkflow({ workingDirectory: '.' });
31
30
  assert.match(webWorkflow, /default: deploy_web/);
32
31
  assert.match(webWorkflow, /- publish_content/);
33
32
  assert.doesNotMatch(webWorkflow, /RAILWAY_API_TOKEN/);
34
- assert.match(processingWorkflow, /default: deploy_processing/);
35
- assert.match(processingWorkflow, /RAILWAY_API_TOKEN/);
36
- assert.match(processingWorkflow, /TREESEED_CAPACITY_PROVIDER_ID/);
33
+ assert.doesNotMatch(webWorkflow, /deploy_processing/);
37
34
  });
38
35
 
39
36
  test('version bump utility supports major, minor, and patch', () => {
@@ -400,7 +400,7 @@ export interface TaskCreditLedgerEntry {
400
400
  createdAt: string;
401
401
  }
402
402
  export type CapacityProviderKind = 'treeseed_managed' | 'team_owned' | 'external' | 'hybrid';
403
- export type CapacityProviderStatus = 'pending' | 'credential_required' | 'registering' | 'active' | 'degraded' | 'draining' | 'paused' | 'configuration_required' | 'disabled' | 'failed';
403
+ export type CapacityProviderStatus = 'pending' | 'online' | 'offline' | 'credential_required' | 'registering' | 'active' | 'degraded' | 'draining' | 'paused' | 'configuration_required' | 'rotation_required' | 'disabled' | 'failed';
404
404
  export type CapacityProviderBillingScope = 'treeseed' | 'team' | 'external';
405
405
  export type CapacityBusinessModel = 'subscription_quota' | 'token_metered' | 'hybrid_usage_based' | 'infrastructure_runtime' | 'custom';
406
406
  export type CapacityLaneUnit = 'treeseed_credit' | 'quota_minute' | 'token_usd' | 'github_ai_credit' | 'worker_second' | 'request' | 'custom';
@@ -644,6 +644,14 @@ export interface CapacityProvider {
644
644
  maxConcurrentWorkdays: number;
645
645
  maxConcurrentWorkers: number;
646
646
  capacityModel: Record<string, unknown>;
647
+ connectionState?: string | null;
648
+ lastSeenAt?: string | null;
649
+ activeKeyPrefix?: string | null;
650
+ lastRotatedAt?: string | null;
651
+ rotationRequired?: boolean;
652
+ capabilities?: unknown[];
653
+ budgets?: Record<string, unknown>;
654
+ deployment?: Record<string, unknown> | null;
647
655
  metadata?: Record<string, unknown>;
648
656
  createdAt: string;
649
657
  updatedAt: string;
@@ -1854,6 +1862,30 @@ export interface UpsertCapacityProviderRequest {
1854
1862
  capacityModel?: Record<string, unknown> | null;
1855
1863
  metadata?: Record<string, unknown> | null;
1856
1864
  }
1865
+ export interface CreateCapacityProviderRequest {
1866
+ name: string;
1867
+ launchMode: 'self_hosted' | 'managed_market_host' | 'connected_host';
1868
+ }
1869
+ export interface CreateCapacityProviderResponse {
1870
+ ok: true;
1871
+ provider: CapacityProvider;
1872
+ apiKey: {
1873
+ plaintext: string;
1874
+ prefix: string;
1875
+ };
1876
+ selfHosting: Record<string, unknown>;
1877
+ }
1878
+ export interface RenameCapacityProviderRequest {
1879
+ name: string;
1880
+ }
1881
+ export interface CapacityProviderRotateKeyResponse {
1882
+ ok: true;
1883
+ apiKey: {
1884
+ plaintext: string;
1885
+ prefix: string;
1886
+ };
1887
+ requiresRestart: boolean;
1888
+ }
1857
1889
  export interface UpsertCapacityProviderHostRequest {
1858
1890
  id?: string;
1859
1891
  hostId: string;
@@ -13,9 +13,7 @@
13
13
  "config": "treeseed config",
14
14
  "preflight": "treeseed preflight",
15
15
  "dev": "treeseed dev",
16
- "dev:web": "treeseed dev:web",
17
- "dev:api": "treeseed dev:api",
18
- "dev:watch": "treeseed dev --watch",
16
+ "capacity": "treeseed capacity",
19
17
  "check": "treeseed check",
20
18
  "build:web": "treeseed build",
21
19
  "build": "npm run build:web",
@@ -26,7 +24,6 @@
26
24
  },
27
25
  "dependencies": {
28
26
  "@treeseed/cli": "__CLI_VERSION__",
29
- "@treeseed/agent": "__AGENT_VERSION__",
30
27
  "@treeseed/core": "__CORE_VERSION__",
31
28
  "@treeseed/sdk": "__SDK_VERSION__",
32
29
  "yaml": "^2.8.1"
@@ -1,4 +1,4 @@
1
- import { createRailwayTreeseedApiServer } from '@treeseed/agent/api';
1
+ import { createRailwayTreeseedApiServer } from '@treeseed/sdk/api';
2
2
 
3
3
  const server = await createRailwayTreeseedApiServer();
4
4
  console.log(`Treeseed project API listening on ${server.url}`);
@@ -46,27 +46,11 @@ services:
46
46
  railway:
47
47
  serviceName: __SITE_SLUG__-api
48
48
  buildCommand: npm run build:api
49
- startCommand: node ./packages/agent/dist/scripts/treeseed-processing.js api
49
+ startCommand: node ./src/api/server.js
50
50
  healthcheckTimeoutSeconds: 120
51
51
  environments:
52
52
  local:
53
53
  baseUrl: http://127.0.0.1:3000
54
- workdayManager:
55
- enabled: true
56
- provider: railway
57
- railway:
58
- serviceName: __SITE_SLUG__-workday-manager
59
- rootDir: .
60
- buildCommand: npm run build:api
61
- startCommand: node ./packages/agent/dist/scripts/treeseed-processing.js manager
62
- schedule: '0 9 * * 1-5'
63
- workerRunner:
64
- enabled: true
65
- provider: railway
66
- railway:
67
- rootDir: .
68
- buildCommand: npm run build:api
69
- startCommand: node ./packages/agent/dist/scripts/treeseed-processing.js worker
70
54
  plugins:
71
55
  - package: '@treeseed/core/plugin-default'
72
56
  providers:
@@ -108,6 +108,7 @@ import {
108
108
  collectTreeseedDevTagCleanupPlan,
109
109
  collectInternalDevReferenceIssues,
110
110
  devTagFromDependencySpec,
111
+ normalizeGitRemoteForManifest,
111
112
  rewriteProjectInternalDependenciesToStableVersions
112
113
  } from "../operations/services/package-reference-policy.js";
113
114
  import {
@@ -446,7 +447,7 @@ function recordHostedDeploymentStatesFromRootGates(root, rootRelease, workflowGa
446
447
  { scope: "staging", branch: STAGING_BRANCH, commit: releaseRecord.stagingCommit },
447
448
  { scope: "prod", branch: releaseTag ?? PRODUCTION_BRANCH, commit: releaseRecord.releasedCommit }
448
449
  ]) {
449
- const gate = gates.find((candidate) => (candidate.workflow === "deploy-web.yml" || candidate.workflow === "deploy-processing.yml") && candidate.branch === target.branch && candidate.status === "completed" && candidate.conclusion === "success");
450
+ const gate = gates.find((candidate) => candidate.workflow === "deploy-web.yml" && candidate.branch === target.branch && candidate.status === "completed" && candidate.conclusion === "success");
450
451
  const timestamp = typeof gate?.updatedAt === "string" && gate.updatedAt.trim() ? gate.updatedAt : null;
451
452
  if (!gate || !timestamp) {
452
453
  continue;
@@ -705,11 +706,13 @@ function writeJsonFile(path, value) {
705
706
  `, "utf8");
706
707
  }
707
708
  function applyStableWorkspaceVersionChanges(root, versions) {
708
- for (const pkg of workspacePackages(root)) {
709
- const packageJsonPath = resolve(pkg.dir, "package.json");
709
+ const stableGitReferences = stablePackageGitReferences(root, versions);
710
+ for (const target of [{ name: "@treeseed/market", dir: root }, ...workspacePackages(root).map((pkg) => ({ name: pkg.name, dir: pkg.dir }))]) {
711
+ const packageJsonPath = resolve(target.dir, "package.json");
712
+ if (!existsSync(packageJsonPath)) continue;
710
713
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
711
714
  let changed = false;
712
- const plannedVersion = versions.get(pkg.name);
715
+ const plannedVersion = versions.get(target.name);
713
716
  if (plannedVersion && packageJson.version !== plannedVersion) {
714
717
  packageJson.version = plannedVersion;
715
718
  changed = true;
@@ -719,8 +722,9 @@ function applyStableWorkspaceVersionChanges(root, versions) {
719
722
  if (!values || typeof values !== "object" || Array.isArray(values)) continue;
720
723
  for (const [dependencyName, version] of versions.entries()) {
721
724
  if (!(dependencyName in values)) continue;
722
- if (String(values[dependencyName]) === version) continue;
723
- values[dependencyName] = version;
725
+ const dependencySpec = stableGitReferences.get(dependencyName) ?? version;
726
+ if (String(values[dependencyName]) === dependencySpec) continue;
727
+ values[dependencyName] = dependencySpec;
724
728
  changed = true;
725
729
  }
726
730
  }
@@ -729,6 +733,20 @@ function applyStableWorkspaceVersionChanges(root, versions) {
729
733
  }
730
734
  }
731
735
  }
736
+ function stablePackageGitReferences(root, versions) {
737
+ return new Map(workspacePackages(root).map((pkg) => {
738
+ const version = versions.get(pkg.name);
739
+ if (!version) return null;
740
+ let remote = null;
741
+ try {
742
+ remote = originRemoteUrl(pkg.dir);
743
+ } catch {
744
+ remote = null;
745
+ }
746
+ const manifestRemote = normalizeGitRemoteForManifest(remote ?? "", "preserve-origin");
747
+ return manifestRemote ? [pkg.name, `${manifestRemote}#${version}`] : null;
748
+ }).filter((entry) => Boolean(entry)));
749
+ }
732
750
  function gitObjectCommit(repoDir, ref) {
733
751
  try {
734
752
  return run("git", ["rev-list", "-n", "1", ref], { cwd: repoDir, capture: true }).trim() || null;
@@ -843,7 +861,7 @@ function defaultCiWorkflows(kind, branch) {
843
861
  return ["verify.yml"];
844
862
  }
845
863
  if (branch === STAGING_BRANCH || branch === PRODUCTION_BRANCH) {
846
- return ["deploy-web.yml", "deploy-processing.yml"];
864
+ return ["deploy-web.yml"];
847
865
  }
848
866
  return ["verify.yml"];
849
867
  }
@@ -1514,7 +1532,7 @@ function validateStagingWorkflowContracts(root) {
1514
1532
  return;
1515
1533
  }
1516
1534
  const missing = [];
1517
- for (const fileName of ["verify.yml", "deploy-web.yml", "deploy-processing.yml"]) {
1535
+ for (const fileName of ["verify.yml", "deploy-web.yml"]) {
1518
1536
  if (!existsSync(resolve(root, ".github", "workflows", fileName))) {
1519
1537
  missing.push(fileName);
1520
1538
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.10.5",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -63,6 +63,7 @@
63
63
  "extract-zip": "2.0.1",
64
64
  "github-slugger": "^2.0.0",
65
65
  "drizzle-orm": "^0.45.2",
66
+ "hono": "^4.8.2",
66
67
  "ink": "^7.0.0",
67
68
  "libsodium-wrappers": "^0.7.15",
68
69
  "mdast-util-to-string": "^4.0.0",
@@ -100,6 +101,14 @@
100
101
  "types": "./dist/operations/agent-tools.d.ts",
101
102
  "default": "./dist/operations/agent-tools.js"
102
103
  },
104
+ "./api": {
105
+ "types": "./dist/api/index.d.ts",
106
+ "default": "./dist/api/index.js"
107
+ },
108
+ "./api/auth/d1-provider": {
109
+ "types": "./dist/api/auth/d1-provider.d.ts",
110
+ "default": "./dist/api/auth/d1-provider.js"
111
+ },
103
112
  "./workflow": {
104
113
  "types": "./dist/workflow.d.ts",
105
114
  "default": "./dist/workflow.js"
@@ -229,6 +238,10 @@
229
238
  "types": "./dist/capacity.d.ts",
230
239
  "default": "./dist/capacity.js"
231
240
  },
241
+ "./capacity-provider": {
242
+ "types": "./dist/capacity-provider.d.ts",
243
+ "default": "./dist/capacity-provider.js"
244
+ },
232
245
  "./types": {
233
246
  "types": "./dist/sdk-types.d.ts",
234
247
  "default": "./dist/sdk-types.js"
@@ -35,7 +35,6 @@ on:
35
35
  type: choice
36
36
  options:
37
37
  - deploy_web
38
- - deploy_processing
39
38
  - publish_content
40
39
  - monitor
41
40
 
@@ -1,123 +0,0 @@
1
- name: Treeseed Processing Deploy
2
-
3
- on:
4
- workflow_call:
5
- inputs:
6
- environment:
7
- required: true
8
- type: string
9
- action_kind:
10
- required: true
11
- type: string
12
- project_id:
13
- required: false
14
- type: string
15
- preview_id:
16
- required: false
17
- type: string
18
- workflow_dispatch:
19
- inputs:
20
- environment:
21
- required: true
22
- default: staging
23
- type: choice
24
- options:
25
- - staging
26
- - prod
27
- action_kind:
28
- required: true
29
- default: deploy_processing
30
- type: choice
31
- options:
32
- - deploy_processing
33
- - monitor
34
- project_id:
35
- required: false
36
- type: string
37
- preview_id:
38
- required: false
39
- type: string
40
-
41
- jobs:
42
- __WORKING_DIRECTORY_BLOCK__ processing:
43
- runs-on: ubuntu-latest
44
- permissions:
45
- contents: read
46
- environment: ${{ inputs.environment == 'prod' && 'production' || 'staging' }}
47
- env:
48
- TREESEED_BOOTSTRAP_MODE: auto
49
- CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
50
- CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
51
- RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }}
52
- RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
53
- TREESEED_RAILWAY_WORKSPACE: ${{ vars.TREESEED_RAILWAY_WORKSPACE }}
54
- TREESEED_API_BASE_URL: ${{ vars.TREESEED_API_BASE_URL }}
55
- TREESEED_API_AUTH_SECRET: ${{ secrets.TREESEED_API_AUTH_SECRET }}
56
- TREESEED_API_D1_DATABASE_ID: ${{ vars.TREESEED_API_D1_DATABASE_ID }}
57
- TREESEED_API_WEB_SERVICE_ID: ${{ vars.TREESEED_API_WEB_SERVICE_ID }}
58
- TREESEED_API_WEB_SERVICE_SECRET: ${{ secrets.TREESEED_API_WEB_SERVICE_SECRET }}
59
- TREESEED_API_WEB_ASSERTION_SECRET: ${{ secrets.TREESEED_API_WEB_ASSERTION_SECRET }}
60
- TREESEED_API_BOOTSTRAP_ADMIN_ALLOWLIST: ${{ vars.TREESEED_API_BOOTSTRAP_ADMIN_ALLOWLIST }}
61
- TREESEED_API_AUTH_APPROVAL_BASE_URL: ${{ vars.TREESEED_API_AUTH_APPROVAL_BASE_URL || vars.TREESEED_SITE_URL }}
62
- TREESEED_SITE_URL: ${{ vars.TREESEED_SITE_URL }}
63
- BETTER_AUTH_URL: ${{ vars.BETTER_AUTH_URL || vars.TREESEED_SITE_URL }}
64
- TREESEED_PROJECT_ID: ${{ inputs.project_id || vars.TREESEED_PROJECT_ID }}
65
- TREESEED_PROJECT_RUNNER_TOKEN: ${{ secrets.TREESEED_PROJECT_RUNNER_TOKEN }}
66
- TREESEED_WORKER_POOL_SCALER: ${{ vars.TREESEED_WORKER_POOL_SCALER }}
67
- TREESEED_AGENT_POOL_MIN_WORKERS: ${{ vars.TREESEED_AGENT_POOL_MIN_WORKERS }}
68
- TREESEED_AGENT_POOL_MAX_WORKERS: ${{ vars.TREESEED_AGENT_POOL_MAX_WORKERS }}
69
- TREESEED_AGENT_POOL_TARGET_QUEUE_DEPTH: ${{ vars.TREESEED_AGENT_POOL_TARGET_QUEUE_DEPTH }}
70
- TREESEED_AGENT_POOL_COOLDOWN_SECONDS: ${{ vars.TREESEED_AGENT_POOL_COOLDOWN_SECONDS }}
71
- TREESEED_WORKDAY_TIMEZONE: ${{ vars.TREESEED_WORKDAY_TIMEZONE }}
72
- TREESEED_WORKDAY_WINDOWS_JSON: ${{ vars.TREESEED_WORKDAY_WINDOWS_JSON }}
73
- TREESEED_WORKDAY_TASK_CREDIT_BUDGET: ${{ vars.TREESEED_WORKDAY_TASK_CREDIT_BUDGET }}
74
- TREESEED_MANAGER_MAX_QUEUED_TASKS: ${{ vars.TREESEED_MANAGER_MAX_QUEUED_TASKS }}
75
- TREESEED_MANAGER_MAX_QUEUED_CREDITS: ${{ vars.TREESEED_MANAGER_MAX_QUEUED_CREDITS }}
76
- TREESEED_MANAGER_PRIORITY_MODELS: ${{ vars.TREESEED_MANAGER_PRIORITY_MODELS }}
77
- TREESEED_TASK_CREDIT_WEIGHTS_JSON: ${{ vars.TREESEED_TASK_CREDIT_WEIGHTS_JSON }}
78
- TREESEED_RAILWAY_PROJECT_ID: ${{ vars.TREESEED_RAILWAY_PROJECT_ID }}
79
- TREESEED_RAILWAY_ENVIRONMENT_ID: ${{ vars.TREESEED_RAILWAY_ENVIRONMENT_ID }}
80
- TREESEED_RAILWAY_WORKER_SERVICE_ID: ${{ vars.TREESEED_RAILWAY_WORKER_SERVICE_ID }}
81
- TREESEED_CAPACITY_PROVIDER_ID: ${{ vars.TREESEED_CAPACITY_PROVIDER_ID }}
82
- TREESEED_CAPACITY_PROVIDER_TEAM_ID: ${{ vars.TREESEED_CAPACITY_PROVIDER_TEAM_ID }}
83
- TREESEED_CAPACITY_PROVIDER_SERVICE_BASE_URL: ${{ vars.TREESEED_CAPACITY_PROVIDER_SERVICE_BASE_URL }}
84
- TREESEED_PROCESSING_DRAIN: ${{ vars.TREESEED_PROCESSING_DRAIN }}
85
- TREESEED_WORKFLOW_ACTION: ${{ inputs.action_kind }}
86
- TREESEED_WORKFLOW_ENVIRONMENT: ${{ inputs.environment }}
87
- TREESEED_WORKFLOW_PLANE: processing
88
- TREESEED_WORKFLOW_PROJECT: ${{ inputs.project_id || vars.TREESEED_PROJECT_ID }}
89
- TREESEED_WORKFLOW_PREVIEW_ID: ${{ inputs.preview_id }}
90
- steps:
91
- - uses: actions/checkout@v4
92
- with:
93
- submodules: recursive
94
-
95
- - uses: actions/setup-node@v4
96
- with:
97
- node-version: 22
98
- cache: npm
99
- cache-dependency-path: __CACHE_DEPENDENCY_PATH__
100
-
101
- - name: Install dependencies
102
- shell: bash
103
- run: |
104
- set -euo pipefail
105
- node -e "const fs = require('fs'); for (const file of ['packages/sdk/package.json', 'packages/agent/package.json', 'packages/core/package.json', 'packages/cli/package.json']) { if (!fs.existsSync(file)) continue; const p = JSON.parse(fs.readFileSync(file, 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync(file, JSON.stringify(p, null, '\t') + '\n'); }"
106
- npm ci --ignore-scripts
107
-
108
- - name: Build package artifacts
109
- shell: bash
110
- run: |
111
- set -euo pipefail
112
- for dir in packages/sdk packages/agent packages/core packages/cli; do
113
- if test -f "${dir}/package.json"; then npm --prefix "${dir}" run build:dist; fi
114
- done
115
-
116
- - name: Run processing workflow action
117
- shell: bash
118
- run: |
119
- set -euo pipefail
120
- EXTRA_ARGS=()
121
- if [[ -n "${TREESEED_WORKFLOW_PROJECT:-}" ]]; then EXTRA_ARGS+=(--project-id "${TREESEED_WORKFLOW_PROJECT}"); fi
122
- if [[ -n "${TREESEED_WORKFLOW_PREVIEW_ID:-}" ]]; then EXTRA_ARGS+=(--preview-id "${TREESEED_WORKFLOW_PREVIEW_ID}"); fi
123
- node ./packages/sdk/scripts/run-ts.mjs ./packages/sdk/scripts/tenant-workflow-action.ts --action "${TREESEED_WORKFLOW_ACTION}" --environment "${TREESEED_WORKFLOW_ENVIRONMENT}" "${EXTRA_ARGS[@]}"