@treeseed/sdk 0.8.19 → 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 (85) 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/d1-store.js +27 -3
  43. package/dist/db/node-sqlite.js +11 -2
  44. package/dist/dispatch.js +0 -1
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +40 -0
  47. package/dist/market-client.d.ts +1 -5
  48. package/dist/market-client.js +2 -8
  49. package/dist/model-registry.js +55 -24
  50. package/dist/operations/providers/default.js +0 -9
  51. package/dist/operations/services/config-runtime.d.ts +2 -2
  52. package/dist/operations/services/config-runtime.js +55 -3
  53. package/dist/operations/services/d1-migration.js +32 -0
  54. package/dist/operations/services/deploy.js +3 -0
  55. package/dist/operations/services/github-automation.d.ts +10 -15
  56. package/dist/operations/services/github-automation.js +3 -35
  57. package/dist/operations/services/hosting-audit.d.ts +1 -1
  58. package/dist/operations/services/hosting-audit.js +3 -27
  59. package/dist/operations/services/hub-launch.d.ts +0 -1
  60. package/dist/operations/services/hub-launch.js +1 -2
  61. package/dist/operations/services/hub-provider-launch.d.ts +0 -15
  62. package/dist/operations/services/hub-provider-launch.js +5 -41
  63. package/dist/operations/services/package-reference-policy.d.ts +1 -0
  64. package/dist/operations/services/package-reference-policy.js +10 -2
  65. package/dist/operations/services/project-platform.d.ts +69 -1
  66. package/dist/operations/services/project-platform.js +33 -13
  67. package/dist/operations/services/release-candidate.js +19 -3
  68. package/dist/operations/services/repository-save-orchestrator.js +10 -1
  69. package/dist/operations-registry.js +1 -3
  70. package/dist/platform/contracts.d.ts +2 -2
  71. package/dist/project-workflow.d.ts +0 -3
  72. package/dist/scripts/publish-package.js +5 -1
  73. package/dist/scripts/tenant-workflow-action.js +3 -3
  74. package/dist/scripts/workflow-commands.test.js +3 -6
  75. package/dist/sdk-types.d.ts +34 -2
  76. package/dist/sdk-types.js +2 -1
  77. package/dist/stores/operational-store.d.ts +13 -0
  78. package/dist/stores/operational-store.js +50 -0
  79. package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +1 -4
  80. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/api/server.js +1 -1
  81. package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +1 -17
  82. package/dist/workflow/operations.js +26 -8
  83. package/package.json +14 -1
  84. package/templates/github/hosted-project.workflow.yml +0 -1
  85. package/templates/github/deploy-processing.workflow.yml +0 -123
@@ -307,9 +307,6 @@ function renderWorkflowTemplate(templateName, { workingDirectory }) {
307
307
  function renderDeployWebWorkflow({ workingDirectory }) {
308
308
  return renderWorkflowTemplate("deploy-web.workflow.yml", { workingDirectory });
309
309
  }
310
- function renderDeployProcessingWorkflow({ workingDirectory }) {
311
- return renderWorkflowTemplate("deploy-processing.workflow.yml", { workingDirectory });
312
- }
313
310
  function renderHostedProjectWorkflow({ workingDirectory }) {
314
311
  return renderWorkflowTemplate("hosted-project.workflow.yml", { workingDirectory });
315
312
  }
@@ -323,44 +320,16 @@ function ensureWorkflowFile(tenantRoot, fileName, expected) {
323
320
  writeFileSync(workflowPath, expected, "utf8");
324
321
  return { workflowPath, changed: true };
325
322
  }
326
- function hasConcreteProcessingServices(deployConfig) {
327
- return Object.entries(deployConfig.services ?? {}).some(
328
- ([serviceKey, service]) => ["api", "manager", "worker", "workerRunner", "workdayStart", "workdayReport"].includes(serviceKey) && service && service.enabled !== false
329
- );
330
- }
331
- function shouldWriteProcessingWorkflow(deployConfig) {
332
- if ((deployConfig.hosting?.kind ?? "self_hosted_project") === "market_control_plane") {
333
- return true;
334
- }
335
- const mode = deployConfig.processing?.mode ?? "market-assigned";
336
- return mode === "project-owned" || mode === "local" || hasConcreteProcessingServices(deployConfig);
337
- }
338
323
  function ensureDeployWorkflow(tenantRoot) {
339
324
  const repositoryRoot = resolveGitRepositoryRoot(tenantRoot);
340
325
  const workingDirectory = relative(repositoryRoot, tenantRoot).replaceAll("\\", "/") || ".";
341
- const deployConfig = loadCliDeployConfig(tenantRoot);
342
326
  const web = ensureWorkflowFile(tenantRoot, "deploy-web.yml", renderDeployWebWorkflow({ workingDirectory }));
343
- const additionalWorkflows = [];
344
- let changed = web.changed;
345
- if (shouldWriteProcessingWorkflow(deployConfig)) {
346
- const processing = ensureWorkflowFile(
347
- tenantRoot,
348
- "deploy-processing.yml",
349
- renderDeployProcessingWorkflow({ workingDirectory })
350
- );
351
- changed = changed || processing.changed;
352
- additionalWorkflows.push({
353
- ...processing,
354
- workingDirectory,
355
- executionBoundary: "split-plane"
356
- });
357
- }
358
327
  return {
359
328
  workflowPath: web.workflowPath,
360
- changed,
329
+ changed: web.changed,
361
330
  workingDirectory,
362
- executionBoundary: "split-plane",
363
- additionalWorkflows
331
+ executionBoundary: "market-web-api",
332
+ additionalWorkflows: []
364
333
  };
365
334
  }
366
335
  function ensureHostedProjectWorkflow(tenantRoot) {
@@ -527,7 +496,6 @@ export {
527
496
  listGitHubVariableNames,
528
497
  maybeResolveGitHubRepositorySlug,
529
498
  parseGitHubRepositoryFromRemote,
530
- renderDeployProcessingWorkflow,
531
499
  renderDeployWebWorkflow,
532
500
  renderHostedProjectWorkflow,
533
501
  requiredGitHubEnvironment,
@@ -2,7 +2,7 @@ import { type TreeseedEnvironmentScope } from '../../platform/environment.ts';
2
2
  import type { TreeseedReconcileTarget } from '../../reconcile/contracts.ts';
3
3
  export type TreeseedHostingAuditEnvironment = 'current' | 'local' | 'staging' | 'prod';
4
4
  export type TreeseedHostingAuditResolvedEnvironment = 'local' | 'staging' | 'prod' | 'preview';
5
- export type TreeseedHostingAuditHostKind = 'repository' | 'web' | 'processing' | 'email';
5
+ export type TreeseedHostingAuditHostKind = 'repository' | 'web' | 'email';
6
6
  export type TreeseedHostingAuditCheckStatus = 'passed' | 'warning' | 'failed' | 'skipped' | 'repaired';
7
7
  export type TreeseedHostingAuditSeverity = 'info' | 'warning' | 'critical';
8
8
  export type TreeseedHostingAuditCheck = {
@@ -25,11 +25,10 @@ import {
25
25
  collectTreeseedReconcileStatus,
26
26
  reconcileTreeseedTarget
27
27
  } from "../../reconcile/index.js";
28
- const HOST_KINDS = ["repository", "web", "processing", "email"];
28
+ const HOST_KINDS = ["repository", "web", "email"];
29
29
  const HOST_GROUPS = {
30
30
  repository: /* @__PURE__ */ new Set(["auth", "github"]),
31
31
  web: /* @__PURE__ */ new Set(["cloudflare", "hosting"]),
32
- processing: /* @__PURE__ */ new Set(["railway", "hosting"]),
33
32
  email: /* @__PURE__ */ new Set(["smtp"])
34
33
  };
35
34
  function hasValue(value) {
@@ -236,24 +235,6 @@ function appendManualConfigChecks(checks, values, hostKinds) {
236
235
  remediation: "Set CLOUDFLARE_ACCOUNT_ID for TreeSeed-managed Web hosting."
237
236
  });
238
237
  }
239
- if (hostKinds.includes("processing")) {
240
- requiredKeyCheck(checks, values, {
241
- id: "processing.railway.token",
242
- hostType: "processing",
243
- provider: "railway",
244
- keys: ["RAILWAY_API_TOKEN"],
245
- label: "Processing provider token",
246
- remediation: "Set RAILWAY_API_TOKEN for TreeSeed-managed Processing hosting."
247
- });
248
- requiredKeyCheck(checks, values, {
249
- id: "processing.railway.workspace",
250
- hostType: "processing",
251
- provider: "railway",
252
- keys: ["TREESEED_RAILWAY_WORKSPACE"],
253
- label: "Processing provider workspace",
254
- remediation: "Set TREESEED_RAILWAY_WORKSPACE for TreeSeed-managed Processing hosting."
255
- });
256
- }
257
238
  if (hostKinds.includes("email")) {
258
239
  requiredKeyCheck(checks, values, {
259
240
  id: "email.smtp.host",
@@ -327,9 +308,8 @@ function providerConnectionChecks(report, hostKinds) {
327
308
  const allowedProviders = /* @__PURE__ */ new Set();
328
309
  if (hostKinds.includes("repository")) allowedProviders.add("github");
329
310
  if (hostKinds.includes("web")) allowedProviders.add("cloudflare");
330
- if (hostKinds.includes("processing")) allowedProviders.add("railway");
331
311
  return report.checks.filter((check) => allowedProviders.has(check.provider)).map((check) => {
332
- const hostType = check.provider === "github" ? "repository" : check.provider === "railway" ? "processing" : "web";
312
+ const hostType = check.provider === "github" ? "repository" : "web";
333
313
  return {
334
314
  id: `identity.${check.provider}`,
335
315
  hostType,
@@ -351,16 +331,12 @@ function reconcileSystemsForHostKinds(hostKinds) {
351
331
  systems.add("data");
352
332
  systems.add("web");
353
333
  }
354
- if (hostKinds.includes("processing")) {
355
- systems.add("api");
356
- systems.add("agents");
357
- }
358
334
  return [...systems];
359
335
  }
360
336
  function reconcileStatusChecks(status, repairedIds = /* @__PURE__ */ new Set()) {
361
337
  const checks = [];
362
338
  for (const unit of status.units) {
363
- const hostType = unit.provider === "github" ? "repository" : unit.provider === "railway" ? "processing" : "web";
339
+ const hostType = unit.provider === "github" ? "repository" : "web";
364
340
  const verified = unit.verification?.verified === true;
365
341
  const id = `resource.${unit.provider}.${unit.unitType}.${unit.unitId}`;
366
342
  const repaired = repairedIds.has(id);
@@ -61,7 +61,6 @@ export interface KnowledgeHubLaunchIntent {
61
61
  hosting?: {
62
62
  mode?: KnowledgeHubHostMode | 'managed';
63
63
  webHost?: Record<string, unknown> | null;
64
- processingHost?: Record<string, unknown> | null;
65
64
  };
66
65
  contentResolution?: HubContentResolutionPolicy;
67
66
  direction?: {
@@ -43,8 +43,7 @@ function normalizeKnowledgeHubLaunchIntent(input) {
43
43
  },
44
44
  hosting: {
45
45
  mode: input.hosting?.mode === "managed" ? "treeseed_managed" : input.hosting?.mode ?? "treeseed_managed",
46
- webHost: input.hosting?.webHost ?? null,
47
- processingHost: input.hosting?.processingHost ?? null
46
+ webHost: input.hosting?.webHost ?? null
48
47
  },
49
48
  contentResolution: input.contentResolution ?? defaultHubContentResolutionPolicy(),
50
49
  direction: input.direction ?? {},
@@ -38,7 +38,6 @@ export interface KnowledgeHubProviderLaunchInput {
38
38
  enableDefaultAgents?: boolean;
39
39
  preserveWorkingTree?: boolean;
40
40
  cloudflareHost?: KnowledgeHubCloudflareHostLaunchInput | null;
41
- processingHost?: KnowledgeHubProcessingHostLaunchInput | null;
42
41
  }
43
42
  export interface KnowledgeHubCloudflareHostConfig {
44
43
  CLOUDFLARE_API_TOKEN?: string;
@@ -58,20 +57,6 @@ export interface KnowledgeHubCloudflareHostLaunchInput {
58
57
  targetEnvironments?: Array<'local' | 'staging' | 'prod'>;
59
58
  config?: KnowledgeHubCloudflareHostConfig | null;
60
59
  }
61
- export interface KnowledgeHubProcessingHostConfig {
62
- RAILWAY_API_TOKEN?: string;
63
- TREESEED_RAILWAY_WORKSPACE?: string;
64
- TREESEED_RAILWAY_API_URL?: string;
65
- TREESEED_WORKER_POOL_SCALER?: string;
66
- environments?: Partial<Record<'staging' | 'prod', Record<string, unknown>>>;
67
- [key: string]: unknown;
68
- }
69
- export interface KnowledgeHubProcessingHostLaunchInput {
70
- mode: 'team_owned' | 'treeseed_managed';
71
- hostId?: string | null;
72
- targetEnvironments?: Array<'local' | 'staging' | 'prod'>;
73
- config?: KnowledgeHubProcessingHostConfig | null;
74
- }
75
60
  export interface KnowledgeHubProviderLaunchPhaseRecord {
76
61
  phase: string;
77
62
  status: 'running' | 'completed' | 'failed';
@@ -227,8 +227,8 @@ This hub is live and ready for the first team release cycle.
227
227
  };
228
228
  }
229
229
  function ensureHostedProjectFiles(projectRoot) {
230
- const agentApiPackage = ["@treeseed", "agent/api"].join("/");
231
- writeText(resolve(projectRoot, "src/api/server.js"), `import { createRailwayTreeseedApiServer } from '${agentApiPackage}';
230
+ const sdkApiPackage = ["@treeseed", "sdk/api"].join("/");
231
+ writeText(resolve(projectRoot, "src/api/server.js"), `import { createRailwayTreeseedApiServer } from '${sdkApiPackage}';
232
232
 
233
233
  const server = await createRailwayTreeseedApiServer();
234
234
  console.log(\`Treeseed project API listening on \${server.url}\`);
@@ -316,7 +316,7 @@ function applyManagedProjectDefaults(projectRoot, input) {
316
316
  railway: {
317
317
  serviceName: `${slug}-api`,
318
318
  buildCommand: "npm run build:api",
319
- startCommand: "npm run build:api && node ./src/api/server.js",
319
+ startCommand: "node ./src/api/server.js",
320
320
  healthcheckTimeoutSeconds: 120
321
321
  },
322
322
  environments: {
@@ -325,26 +325,6 @@ function applyManagedProjectDefaults(projectRoot, input) {
325
325
  }
326
326
  }
327
327
  },
328
- workdayManager: {
329
- enabled: managedRuntime,
330
- provider: managedRuntime ? "railway" : "none",
331
- railway: {
332
- serviceName: `${slug}-workday-manager`,
333
- rootDir: ".",
334
- buildCommand: "npm run build:api",
335
- startCommand: "npm run build:api && node ./packages/agent/dist/services/workday-manager.js",
336
- schedule: "0 9 * * 1-5"
337
- }
338
- },
339
- workerRunner: {
340
- enabled: managedRuntime,
341
- provider: managedRuntime ? "railway" : "none",
342
- railway: {
343
- rootDir: ".",
344
- buildCommand: "npm run build:api",
345
- startCommand: "npm run build:api && node ./packages/agent/dist/services/worker.js"
346
- }
347
- },
348
328
  ...config.services ?? {}
349
329
  },
350
330
  plugins: [{ package: "@treeseed/core/plugin-default" }],
@@ -553,20 +533,6 @@ function buildCloudflareHostEnvironmentOverlay(input, scope) {
553
533
  overlayValue(overlay, "TREESEED_CONTENT_BUCKET_BINDING", overlay.TREESEED_CONTENT_BUCKET_BINDING || "TREESEED_CONTENT_BUCKET");
554
534
  return overlay;
555
535
  }
556
- function buildProcessingHostEnvironmentOverlay(input, scope) {
557
- const config = input.processingHost?.config ?? {};
558
- const environmentConfig = config.environments?.[scope] ?? {};
559
- const overlay = {};
560
- for (const [key, value] of Object.entries(config)) {
561
- if (key === "environments") continue;
562
- overlayValue(overlay, key, value);
563
- }
564
- for (const [key, value] of Object.entries(environmentConfig)) {
565
- overlayValue(overlay, key, value);
566
- }
567
- overlayValue(overlay, "TREESEED_WORKER_POOL_SCALER", overlay.TREESEED_WORKER_POOL_SCALER || "railway");
568
- return overlay;
569
- }
570
536
  function scaffoldLaunchSource(projectRoot, input) {
571
537
  const repositoryName = slugify(input.repoName ?? input.projectSlug, "project");
572
538
  const templateId = input.sourceKind === "template" ? slugify(input.sourceRef ?? "starter-basic", "starter-basic") : "starter-basic";
@@ -682,12 +648,10 @@ async function executeKnowledgeHubProviderLaunch(input, options = {}) {
682
648
  const phases = [];
683
649
  const reportPhase = options.onPhase;
684
650
  const prodEnvOverlay = {
685
- ...buildCloudflareHostEnvironmentOverlay(input, "prod"),
686
- ...buildProcessingHostEnvironmentOverlay(input, "prod")
651
+ ...buildCloudflareHostEnvironmentOverlay(input, "prod")
687
652
  };
688
653
  const stagingEnvOverlay = {
689
- ...buildCloudflareHostEnvironmentOverlay(input, "staging"),
690
- ...buildProcessingHostEnvironmentOverlay(input, "staging")
654
+ ...buildCloudflareHostEnvironmentOverlay(input, "staging")
691
655
  };
692
656
  const preflight = await validateKnowledgeHubProviderLaunchPrerequisites(process.cwd(), { valuesOverlay: prodEnvOverlay });
693
657
  if (!preflight.ok) {
@@ -40,6 +40,7 @@ export declare function isPrereleaseVersion(version: string): boolean;
40
40
  export declare function isStableVersion(version: string): boolean;
41
41
  export declare function isGitDependencySpec(spec: string): boolean;
42
42
  export declare function devTagFromDependencySpec(spec: string): string | null;
43
+ export declare function releaseTagFromDependencySpec(spec: string): string | null;
43
44
  export declare function normalizeGitRemoteForDependency(remoteUrl: string, protocol?: GitDependencyProtocol): string | null;
44
45
  export declare function normalizeGitRemoteForManifest(remoteUrl: string, protocol?: GitDependencyProtocol): string | null;
45
46
  export declare function createPackageDependencyReference(input: {
@@ -43,6 +43,13 @@ function devTagFromDependencySpec(spec) {
43
43
  const ref = decodeURIComponent(value.slice(hashIndex + 1));
44
44
  return ref.includes("-dev.") ? ref : null;
45
45
  }
46
+ function releaseTagFromDependencySpec(spec) {
47
+ const value = String(spec).trim();
48
+ const hashIndex = value.lastIndexOf("#");
49
+ if (hashIndex === -1) return null;
50
+ const ref = decodeURIComponent(value.slice(hashIndex + 1));
51
+ return isStableVersion(ref) ? ref : null;
52
+ }
46
53
  function normalizeGitRemoteForDependency(remoteUrl, protocol = "preserve-origin") {
47
54
  const remote = String(remoteUrl).trim();
48
55
  if (!remote) return null;
@@ -224,7 +231,7 @@ function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames
224
231
  for (const [depName, specValue] of Object.entries(values)) {
225
232
  if (!packageNames.has(depName)) continue;
226
233
  const spec = String(specValue);
227
- if (isGitDependencySpec(spec) || devTagFromDependencySpec(spec)) {
234
+ if (isGitDependencySpec(spec) && !releaseTagFromDependencySpec(spec)) {
228
235
  issues.push({ repoName: pkg.name, filePath: packageJsonPath, field, dependencyName: depName, spec, reason: "git-dev-ref" });
229
236
  } else if (isPrereleaseVersion(spec)) {
230
237
  issues.push({ repoName: pkg.name, filePath: packageJsonPath, field, dependencyName: depName, spec, reason: "prerelease-dev-ref" });
@@ -252,7 +259,7 @@ function collectInternalDevReferenceIssues(root = workspaceRoot(), packageNames
252
259
  record.resolved,
253
260
  record.from
254
261
  ].map((value) => typeof value === "string" ? value : "").find(
255
- (value) => isGitDependencySpec(value) || devTagFromDependencySpec(value) || isPrereleaseVersion(value)
262
+ (value) => isGitDependencySpec(value) && !releaseTagFromDependencySpec(value) || devTagFromDependencySpec(value) || isPrereleaseVersion(value)
256
263
  );
257
264
  if (spec) {
258
265
  issues.push({ repoName: lockRoot.name, filePath: lockPath, spec, reason: "lockfile-dev-ref", dependencyName: packageName });
@@ -458,6 +465,7 @@ export {
458
465
  normalizeGitRemoteForDependency,
459
466
  normalizeGitRemoteForManifest,
460
467
  parseTreeseedDevTag,
468
+ releaseTagFromDependencySpec,
461
469
  rewriteInternalDependenciesToStableVersions,
462
470
  rewriteProjectInternalDependenciesToStableVersions,
463
471
  tagHasTreeseedDevMetadata,
@@ -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;
@@ -212,6 +212,23 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
212
212
  reason: string;
213
213
  };
214
214
  readiness: any;
215
+ apiMonitor: {
216
+ ok: boolean;
217
+ processingAgentApi: boolean;
218
+ endpoints: {
219
+ apiHealth: null;
220
+ apiReady: null;
221
+ d1Health: null;
222
+ agentHealth: null;
223
+ processingAgentApi: boolean;
224
+ } | {
225
+ apiHealth: string;
226
+ apiReady: string;
227
+ d1Health: string;
228
+ agentHealth: null;
229
+ processingAgentApi: boolean;
230
+ };
231
+ };
215
232
  };
216
233
  };
217
234
  hostingRepair: {
@@ -394,6 +411,23 @@ export declare function monitorProjectPlatform(options: ProjectPlatformActionOpt
394
411
  reason: string;
395
412
  };
396
413
  readiness: any;
414
+ apiMonitor: {
415
+ ok: boolean;
416
+ processingAgentApi: boolean;
417
+ endpoints: {
418
+ apiHealth: null;
419
+ apiReady: null;
420
+ d1Health: null;
421
+ agentHealth: null;
422
+ processingAgentApi: boolean;
423
+ } | {
424
+ apiHealth: string;
425
+ apiReady: string;
426
+ d1Health: string;
427
+ agentHealth: null;
428
+ processingAgentApi: boolean;
429
+ };
430
+ };
397
431
  };
398
432
  }>;
399
433
  export declare function syncControlPlaneState(options: ProjectPlatformActionOptions): Promise<void>;
@@ -528,6 +562,23 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
528
562
  reason: string;
529
563
  };
530
564
  readiness: any;
565
+ apiMonitor: {
566
+ ok: boolean;
567
+ processingAgentApi: boolean;
568
+ endpoints: {
569
+ apiHealth: null;
570
+ apiReady: null;
571
+ d1Health: null;
572
+ agentHealth: null;
573
+ processingAgentApi: boolean;
574
+ } | {
575
+ apiHealth: string;
576
+ apiReady: string;
577
+ d1Health: string;
578
+ agentHealth: null;
579
+ processingAgentApi: boolean;
580
+ };
581
+ };
531
582
  };
532
583
  } | {
533
584
  ok: boolean;
@@ -655,6 +706,23 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
655
706
  reason: string;
656
707
  };
657
708
  readiness: any;
709
+ apiMonitor: {
710
+ ok: boolean;
711
+ processingAgentApi: boolean;
712
+ endpoints: {
713
+ apiHealth: null;
714
+ apiReady: null;
715
+ d1Health: null;
716
+ agentHealth: null;
717
+ processingAgentApi: boolean;
718
+ } | {
719
+ apiHealth: string;
720
+ apiReady: string;
721
+ d1Health: string;
722
+ agentHealth: null;
723
+ processingAgentApi: boolean;
724
+ };
725
+ };
658
726
  };
659
727
  };
660
728
  hostingRepair: {
@@ -633,6 +633,25 @@ function resolveImmediateApiProbeUrl(siteConfig, state, target) {
633
633
  }
634
634
  return null;
635
635
  }
636
+ function resolveApiMonitorEndpoints(siteConfig, apiBaseUrl) {
637
+ if (!apiBaseUrl) {
638
+ return {
639
+ apiHealth: null,
640
+ apiReady: null,
641
+ d1Health: null,
642
+ agentHealth: null,
643
+ processingAgentApi: false
644
+ };
645
+ }
646
+ const baseUrl = String(apiBaseUrl).replace(/\/+$/u, "");
647
+ return {
648
+ apiHealth: `${baseUrl}/healthz`,
649
+ apiReady: `${baseUrl}/readyz`,
650
+ d1Health: `${baseUrl}/healthz/deep`,
651
+ agentHealth: null,
652
+ processingAgentApi: false
653
+ };
654
+ }
636
655
  async function probeQueue(siteConfig, state) {
637
656
  const config = queueClientConfig(siteConfig, state);
638
657
  if (!config) {
@@ -1326,6 +1345,7 @@ async function monitorProjectPlatform(options) {
1326
1345
  const state = loadDeployState(options.tenantRoot, siteConfig, { target });
1327
1346
  const webProbeUrl = resolveImmediatePagesProbeUrl(siteConfig, state, target);
1328
1347
  const apiBaseUrl = resolveImmediateApiProbeUrl(siteConfig, state, target);
1348
+ const apiMonitorEndpoints = resolveApiMonitorEndpoints(siteConfig, apiBaseUrl);
1329
1349
  const railwayResources = options.scope === "local" || !apiSelected && !agentsSelected ? { ok: true, skipped: true, reason: options.scope === "local" ? "local_scope" : "railway_not_selected" } : await verifyRailwayManagedResources(options.tenantRoot, options.scope, {
1330
1350
  env,
1331
1351
  settleDeployments: true,
@@ -1333,17 +1353,23 @@ async function monitorProjectPlatform(options) {
1333
1353
  });
1334
1354
  const skippedApiCheck = apiSelected ? { ok: false, skipped: true, reason: "api_url_unconfigured" } : { ok: true, skipped: true, reason: "api_not_selected" };
1335
1355
  const skippedAgentCheck = agentsSelected ? { ok: false, skipped: true, reason: "api_url_unconfigured" } : { ok: true, skipped: true, reason: "agents_not_selected" };
1356
+ const skippedD1Check = apiMonitorEndpoints.processingAgentApi ? { ok: true, skipped: true, reason: "processing_agent_api" } : skippedApiCheck;
1336
1357
  const checks = {
1337
1358
  pages: await probeHttp(webProbeUrl, { attempts: 3, delayMs: 5e3 }),
1338
- apiHealth: apiSelected && apiBaseUrl ? await probeHttp(`${String(apiBaseUrl).replace(/\/+$/u, "")}/healthz`, { attempts: 8, delayMs: 1e4 }) : skippedApiCheck,
1339
- apiReady: apiSelected && apiBaseUrl ? await probeHttp(`${String(apiBaseUrl).replace(/\/+$/u, "")}/readyz`, { attempts: 8, delayMs: 1e4 }) : skippedApiCheck,
1340
- d1Health: apiSelected && apiBaseUrl ? await probeHttp(`${String(apiBaseUrl).replace(/\/+$/u, "")}/healthz/deep`, { attempts: 8, delayMs: 1e4 }) : skippedApiCheck,
1341
- agentHealth: agentsSelected && apiBaseUrl ? await probeHttp(`${String(apiBaseUrl).replace(/\/+$/u, "")}/internal/core/agent/healthz`, { attempts: 8, delayMs: 1e4 }) : skippedAgentCheck,
1359
+ apiHealth: apiSelected && apiMonitorEndpoints.apiHealth ? await probeHttp(apiMonitorEndpoints.apiHealth, { attempts: 8, delayMs: 1e4 }) : skippedApiCheck,
1360
+ apiReady: apiSelected && apiMonitorEndpoints.apiReady ? await probeHttp(apiMonitorEndpoints.apiReady, { attempts: 8, delayMs: 1e4 }) : skippedApiCheck,
1361
+ d1Health: apiSelected && apiMonitorEndpoints.d1Health ? await probeHttp(apiMonitorEndpoints.d1Health, { attempts: 8, delayMs: 1e4 }) : skippedD1Check,
1362
+ agentHealth: agentsSelected && apiMonitorEndpoints.agentHealth ? await probeHttp(apiMonitorEndpoints.agentHealth, { attempts: 8, delayMs: 1e4 }) : skippedAgentCheck,
1342
1363
  r2: options.dryRun ? { ok: true, skipped: true, reason: "dry_run" } : probeR2(options.tenantRoot, siteConfig, state, target),
1343
1364
  queue: options.dryRun ? Promise.resolve({ ok: true, skipped: true, reason: "dry_run" }) : probeQueue(siteConfig, state),
1344
1365
  scaleProbe: probeScaleConfiguration(siteConfig, state),
1345
1366
  railwayResources,
1346
- readiness: state.readiness
1367
+ readiness: state.readiness,
1368
+ apiMonitor: {
1369
+ ok: true,
1370
+ processingAgentApi: apiMonitorEndpoints.processingAgentApi,
1371
+ endpoints: apiMonitorEndpoints
1372
+ }
1347
1373
  };
1348
1374
  const resolvedChecks = {
1349
1375
  ...checks,
@@ -1409,7 +1435,7 @@ async function runProjectPlatformAction(action, options) {
1409
1435
  const previousWorkflowAction = process.env.TREESEED_WORKFLOW_ACTION;
1410
1436
  const previousWorkflowPlane = process.env.TREESEED_WORKFLOW_PLANE;
1411
1437
  process.env.TREESEED_WORKFLOW_ACTION = action;
1412
- process.env.TREESEED_WORKFLOW_PLANE = previousWorkflowPlane ?? (action === "deploy_processing" ? "processing" : "web");
1438
+ process.env.TREESEED_WORKFLOW_PLANE = previousWorkflowPlane ?? "web";
1413
1439
  applyTreeseedEnvironmentToProcess({ tenantRoot: options.tenantRoot, scope: options.scope, override: true });
1414
1440
  const reporter = resolveReporter(options.tenantRoot, options.reporter);
1415
1441
  try {
@@ -1420,12 +1446,6 @@ async function runProjectPlatformAction(action, options) {
1420
1446
  reporter,
1421
1447
  bootstrapSystems: options.bootstrapSystems ?? WEB_PLATFORM_BOOTSTRAP_SYSTEMS
1422
1448
  });
1423
- case "deploy_processing":
1424
- return await deployProjectPlatform({
1425
- ...options,
1426
- reporter,
1427
- bootstrapSystems: options.bootstrapSystems ?? PROCESSING_PLATFORM_BOOTSTRAP_SYSTEMS
1428
- });
1429
1449
  case "publish_content":
1430
1450
  return await publishProjectContent({ ...options, reporter });
1431
1451
  case "monitor":
@@ -1436,7 +1456,7 @@ async function runProjectPlatformAction(action, options) {
1436
1456
  } catch (error) {
1437
1457
  await reportDeployment(reporter, {
1438
1458
  environment: options.scope,
1439
- deploymentKind: action === "publish_content" ? "content" : action === "deploy_web" || action === "deploy_processing" ? "code" : "mixed",
1459
+ deploymentKind: action === "publish_content" ? "content" : action === "deploy_web" ? "code" : "mixed",
1440
1460
  status: "failed",
1441
1461
  sourceRef: currentRef(options.tenantRoot),
1442
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"]) {
@@ -322,6 +322,14 @@ function packageVersionAtHead(node) {
322
322
  function packageVersionEligibleForBranch(node, version, options) {
323
323
  return node.branchMode === "package-release-main" ? isStableSemverVersion(version) : isDevVersionForBranch(version, node.branch || options.branch);
324
324
  }
325
+ function packageVersionTagConflictsWithHead(node, options) {
326
+ if (node.kind !== "package") return false;
327
+ const version = typeof node.packageJson?.version === "string" ? node.packageJson.version : null;
328
+ if (!version || !packageVersionEligibleForBranch(node, version, options)) return false;
329
+ const head = headCommit(node.path);
330
+ const state = tagState(node.path, version);
331
+ return state.localCommit != null && state.localCommit !== head || state.remoteCommit != null && state.remoteCommit !== head;
332
+ }
325
333
  function selectPackageVersion(node, options) {
326
334
  const current = String(node.packageJson?.version ?? "0.0.0");
327
335
  if (node.branchMode === "package-dev-save" && isDevVersionForBranch(current, node.branch || options.branch) && !tagExists(node.path, current)) {
@@ -1294,7 +1302,8 @@ async function saveOneRepository(node, options, state) {
1294
1302
  const gitDependencyRefreshSpecs = dependencyUpdates.map((update) => state.finalizedReferences.get(update.packageName)).filter((reference) => Boolean(reference) && reference.mode === "dev-git-tag").map((reference) => `${reference.packageName}@${reference.installSpec ?? reference.spec}`);
1295
1303
  const submodulePointers = collectSubmodulePointerChanges(node, state.finalizedCommits);
1296
1304
  const submodulesChanged = submodulePointers.length > 0;
1297
- const packageNeedsVersion = node.kind === "package" && (hasMeaningfulChanges(node.path) || dependencyChanged || submodulesChanged);
1305
+ const packageHasMeaningfulChanges = hasMeaningfulChanges(node.path);
1306
+ const packageNeedsVersion = node.kind === "package" && (packageHasMeaningfulChanges || dependencyChanged || submodulesChanged || packageVersionTagConflictsWithHead(node, options));
1298
1307
  let plannedVersion = null;
1299
1308
  if (packageNeedsVersion) {
1300
1309
  const selection = selectPackageVersion(node, options);
@@ -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';