@treeseed/sdk 0.6.51 → 0.7.0

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.
@@ -1,4 +1,4 @@
1
- import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1
+ import { cpSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { tmpdir } from "node:os";
4
4
  import { dirname, join, resolve } from "node:path";
@@ -18,12 +18,12 @@ import { templateCatalogRoot } from "./runtime-paths.js";
18
18
  import { scaffoldTemplateProject } from "./template-registry.js";
19
19
  import { buildKnowledgeCoopKnowledgePackPackage, buildKnowledgeCoopTemplatePackage, importKnowledgeCoopKnowledgePack } from "./knowledge-coop-packaging.js";
20
20
  import { resolveTreeseedToolBinary } from "../../managed-dependencies.js";
21
- class KnowledgeCoopLaunchError extends Error {
21
+ class KnowledgeHubProviderLaunchError extends Error {
22
22
  phase;
23
23
  phases;
24
24
  constructor(phase, message, phases = []) {
25
25
  super(message);
26
- this.name = "KnowledgeCoopLaunchError";
26
+ this.name = "KnowledgeHubProviderLaunchError";
27
27
  this.phase = phase;
28
28
  this.phases = [...phases];
29
29
  }
@@ -132,13 +132,13 @@ The first release should verify that the hub is live, the core direction is visi
132
132
  `);
133
133
  writeText(resolve(projectRoot, "src/content/notes", `${noteSlug}.mdx`), `---
134
134
  title: ${input.projectName} Operating Model
135
- description: The initial working agreements for this Knowledge Coop hub.
135
+ description: The initial working agreements for this Knowledge Hub.
136
136
  date: ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}
137
137
  summary: Managed launch created the default branches, runtime wiring, and first operational checkpoints.
138
138
  status: live
139
139
  ---
140
140
 
141
- This hub starts with a managed launch, a seeded objective, and a visible first workstream so the team can continue from a known baseline.
141
+ This hub starts with a Knowledge Hub launch, a seeded objective, and a visible first workstream so the team can continue from a known baseline.
142
142
  `);
143
143
  writeText(resolve(projectRoot, "src/content/proposals", "establish-initial-operating-routine.mdx"), `---
144
144
  id: ${proposalId}
@@ -166,11 +166,11 @@ id: ${decisionId}
166
166
  title: Adopt The Initial Launch Posture
167
167
  description: Record the launch decision for the first operating cycle of the hub.
168
168
  date: ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}
169
- summary: The managed launch will begin with a narrow first release and explicit direction artifacts.
169
+ summary: The Knowledge Hub launch will begin with a narrow first release and explicit direction artifacts.
170
170
  status: live
171
171
  decisionType: approved
172
172
  rationale: The initial launch should bias toward clarity, setup completion, and a visible first release loop.
173
- authority: Knowledge Coop managed launch
173
+ authority: Knowledge Hub launch
174
174
  primaryContributor: ${stewardSlug}
175
175
  relatedObjectives:
176
176
  - launch-knowledge-hub
@@ -514,13 +514,15 @@ function commandAvailable(command) {
514
514
  }
515
515
  return spawnSync("bash", ["-lc", `command -v ${command}`], { stdio: "ignore" }).status === 0;
516
516
  }
517
- function appendPhase(phases, phase, status, detail) {
518
- phases.push({
517
+ async function appendPhase(phases, phase, status, detail, reporter) {
518
+ const record = {
519
519
  phase,
520
520
  status,
521
521
  detail,
522
522
  timestamp: nowIso()
523
- });
523
+ };
524
+ phases.push(record);
525
+ await reporter?.(record);
524
526
  }
525
527
  function stringValue(value) {
526
528
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : "";
@@ -565,6 +567,7 @@ function buildProcessingHostEnvironmentOverlay(input, scope) {
565
567
  return overlay;
566
568
  }
567
569
  function scaffoldKnowledgeCoopSource(projectRoot, input) {
570
+ const repositoryName = slugify(input.repoName ?? input.projectSlug, "project");
568
571
  const templateId = input.sourceKind === "template" ? slugify(input.sourceRef ?? "starter-basic", "starter-basic") : "starter-basic";
569
572
  const templateCatalogEnv = { TREESEED_TEMPLATE_CATALOG_URL: currentTemplateCatalogUrl() };
570
573
  if (input.sourceKind === "knowledge_pack") {
@@ -590,13 +593,59 @@ function scaffoldKnowledgeCoopSource(projectRoot, input) {
590
593
  slug: input.projectSlug,
591
594
  siteUrl: resolveManagedWebUrl(slugify(input.projectSlug, "project")),
592
595
  contactEmail: input.contactEmail ?? `hello+${slugify(input.projectSlug, "project")}@knowledge.coop`,
593
- repositoryUrl: `https://github.com/${slugify(input.repoOwner ?? resolveDefaultGitHubOwner(), "treeseed-ai")}/${slugify(input.projectSlug, "project")}`
596
+ repositoryUrl: `https://github.com/${slugify(input.repoOwner ?? resolveDefaultGitHubOwner(), "treeseed-ai")}/${repositoryName}`
594
597
  }, {
595
598
  cwd: projectRoot,
596
599
  env: templateCatalogEnv
597
600
  });
598
601
  }
599
- async function validateKnowledgeCoopManagedLaunchPrerequisites(tenantRoot = process.cwd(), { valuesOverlay = {} } = {}) {
602
+ function repositoryHostGitHubEnvOverlay() {
603
+ const token = process.env.TREESEED_HOSTED_HUBS_GITHUB_TOKEN || process.env.TREESEED_REPOSITORY_HOST_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN || "";
604
+ return token ? { ...process.env, GH_TOKEN: token, GITHUB_TOKEN: token } : process.env;
605
+ }
606
+ function prepareKnowledgeHubContentRepositoryRoot(sourceRoot, contentRoot, input) {
607
+ mkdirSync(contentRoot, { recursive: true });
608
+ const contentSource = resolve(sourceRoot, "src", "content");
609
+ if (existsSync(contentSource)) {
610
+ cpSync(contentSource, resolve(contentRoot, "src", "content"), { recursive: true });
611
+ }
612
+ const publicSource = resolve(sourceRoot, "public");
613
+ if (existsSync(publicSource)) {
614
+ cpSync(publicSource, resolve(contentRoot, "public"), { recursive: true });
615
+ }
616
+ writeFileSync(resolve(contentRoot, "README.md"), `# ${input.projectName} Content
617
+
618
+ Content source for the ${input.projectName} TreeSeed Knowledge Hub.
619
+ `, "utf8");
620
+ writeFileSync(resolve(contentRoot, "treeseed.content.json"), `${JSON.stringify({
621
+ schemaVersion: 1,
622
+ kind: "treeseed_hub_content",
623
+ projectId: input.projectId,
624
+ projectSlug: input.projectSlug,
625
+ contentRoot: "src/content",
626
+ productionSource: "r2_published_artifacts",
627
+ overlayPolicy: "src_content_when_present"
628
+ }, null, 2)}
629
+ `, "utf8");
630
+ }
631
+ function stripSoftwareContentOverlay(sourceRoot, input) {
632
+ const contentRoot = resolve(sourceRoot, "src", "content");
633
+ rmSync(contentRoot, { recursive: true, force: true });
634
+ mkdirSync(contentRoot, { recursive: true });
635
+ writeFileSync(resolve(contentRoot, ".gitkeep"), "", "utf8");
636
+ writeFileSync(
637
+ resolve(contentRoot, "README.md"),
638
+ `# Preview content overlay
639
+
640
+ This software repository does not own ordinary Knowledge Hub content. Production content is published from the content repository to R2 artifacts. Checked-out files under \`src/content\` are for local, staging, or preview overlays only.
641
+
642
+ Hub: ${input.projectName}
643
+ Content source: ${input.contentRepository?.name ?? `${slugify(input.projectSlug, "project")}-content`}
644
+ `,
645
+ "utf8"
646
+ );
647
+ }
648
+ async function validateKnowledgeHubProviderLaunchPrerequisites(tenantRoot = process.cwd(), { valuesOverlay = {} } = {}) {
600
649
  const values = collectTreeseedConfigSeedValues(tenantRoot, "prod", process.env, valuesOverlay);
601
650
  const requiredConfig = [
602
651
  ["TREESEED_BETTER_AUTH_SECRET"],
@@ -628,8 +677,9 @@ async function validateKnowledgeCoopManagedLaunchPrerequisites(tenantRoot = proc
628
677
  commands
629
678
  };
630
679
  }
631
- async function executeKnowledgeCoopManagedLaunch(input) {
680
+ async function executeKnowledgeHubProviderLaunch(input, options = {}) {
632
681
  const phases = [];
682
+ const reportPhase = options.onPhase;
633
683
  const prodEnvOverlay = {
634
684
  ...buildCloudflareHostEnvironmentOverlay(input, "prod"),
635
685
  ...buildProcessingHostEnvironmentOverlay(input, "prod")
@@ -638,35 +688,82 @@ async function executeKnowledgeCoopManagedLaunch(input) {
638
688
  ...buildCloudflareHostEnvironmentOverlay(input, "staging"),
639
689
  ...buildProcessingHostEnvironmentOverlay(input, "staging")
640
690
  };
641
- const preflight = await validateKnowledgeCoopManagedLaunchPrerequisites(process.cwd(), { valuesOverlay: prodEnvOverlay });
691
+ const preflight = await validateKnowledgeHubProviderLaunchPrerequisites(process.cwd(), { valuesOverlay: prodEnvOverlay });
642
692
  if (!preflight.ok) {
643
- throw new KnowledgeCoopLaunchError(
693
+ throw new KnowledgeHubProviderLaunchError(
644
694
  "runtime_connection_failed",
645
- `Knowledge Coop launch preflight failed: ${[...preflight.missingConfig, ...preflight.providerChecks.issues].join("; ") || "provider checks failed."}`,
695
+ `Knowledge Hub launch preflight failed: ${[...preflight.missingConfig, ...preflight.providerChecks.issues].join("; ") || "provider checks failed."}`,
646
696
  []
647
697
  );
648
698
  }
649
- const workingRoot = mkdtempSync(join(tmpdir(), `knowledge-coop-launch-${slugify(input.projectSlug, "project")}-`));
699
+ const workingRoot = mkdtempSync(join(tmpdir(), `hub-provider-launch-${slugify(input.projectSlug, "project")}-`));
650
700
  const repoOwner = slugify(input.repoOwner ?? resolveDefaultGitHubOwner(), "treeseed-ai");
651
- const repoName = slugify(input.projectSlug, "project");
701
+ const repoName = slugify(input.repoName ?? input.projectSlug, "project");
702
+ const githubEnv = repositoryHostGitHubEnvOverlay();
703
+ let packageSourceRoot = null;
652
704
  try {
653
- appendPhase(phases, "repo_provision", "running", "Creating GitHub repository.");
654
- const repository = await createGitHubRepository({
705
+ await appendPhase(phases, "repo_provision", "running", "Creating or connecting GitHub software repository.", reportPhase);
706
+ const repository = input.existingRepository?.url ? {
707
+ slug: `${input.existingRepository.owner}/${input.existingRepository.name}`,
708
+ owner: input.existingRepository.owner,
709
+ name: input.existingRepository.name,
710
+ url: input.existingRepository.url,
711
+ visibility: input.existingRepository.visibility ?? input.repoVisibility ?? "private"
712
+ } : await createGitHubRepository({
655
713
  owner: repoOwner,
656
714
  name: repoName,
657
- description: input.summary ?? `Knowledge Coop hub for ${input.projectName}`,
715
+ description: input.summary ?? `Knowledge Hub for ${input.projectName}`,
658
716
  visibility: input.repoVisibility ?? "private",
659
717
  homepageUrl: resolveManagedWebUrl(repoName),
660
718
  topics: ["knowledge-coop", "treeseed", "knowledge-hub"]
661
- });
662
- appendPhase(phases, "repo_provision", "completed", `Created ${repository.slug}.`);
663
- appendPhase(phases, "content_bootstrap", "running", "Scaffolding the project and seeding initial content.");
719
+ }, { env: githubEnv });
720
+ await appendPhase(phases, "repo_provision", "completed", `${input.existingRepository?.url ? "Connected" : "Created"} ${repository.slug}.`, reportPhase);
721
+ await appendPhase(phases, "content_bootstrap", "running", "Scaffolding the project and seeding initial content.", reportPhase);
664
722
  await scaffoldKnowledgeCoopSource(workingRoot, input);
665
723
  ensureHostedProjectFiles(workingRoot);
666
724
  const managedDefaults = applyManagedProjectDefaults(workingRoot, input);
667
725
  const seed = seedKnowledgeCoopContent(workingRoot, input);
668
- appendPhase(phases, "content_bootstrap", "completed", "Scaffolded the repo and seeded Direct content.");
669
- appendPhase(phases, "workflow_bootstrap", "running", "Initializing git branches and GitHub workflows.");
726
+ packageSourceRoot = mkdtempSync(join(tmpdir(), `knowledge-coop-package-${slugify(input.projectSlug, "project")}-`));
727
+ cpSync(workingRoot, packageSourceRoot, { recursive: true });
728
+ await appendPhase(phases, "content_bootstrap", "completed", "Scaffolded the repo and seeded Direct content.", reportPhase);
729
+ let contentRepository = null;
730
+ let contentRepositoryWorkingRoot = null;
731
+ if (input.contentRepository?.name) {
732
+ await appendPhase(phases, "content_repository", "running", "Creating content repository.", reportPhase);
733
+ contentRepositoryWorkingRoot = mkdtempSync(join(tmpdir(), `knowledge-coop-content-${slugify(input.projectSlug, "project")}-`));
734
+ prepareKnowledgeHubContentRepositoryRoot(workingRoot, contentRepositoryWorkingRoot, input);
735
+ const createdContentRepository = input.contentRepository.url ? {
736
+ slug: `${slugify(input.contentRepository.owner ?? repoOwner, "treeseed-ai")}/${slugify(input.contentRepository.name, `${repoName}-content`)}`,
737
+ owner: slugify(input.contentRepository.owner ?? repoOwner, "treeseed-ai"),
738
+ name: slugify(input.contentRepository.name, `${repoName}-content`),
739
+ url: input.contentRepository.url,
740
+ visibility: input.contentRepository.visibility ?? input.repoVisibility ?? "private"
741
+ } : await createGitHubRepository({
742
+ owner: slugify(input.contentRepository.owner ?? repoOwner, "treeseed-ai"),
743
+ name: slugify(input.contentRepository.name, `${repoName}-content`),
744
+ description: input.summary ?? `Content source for ${input.projectName}`,
745
+ visibility: input.contentRepository.visibility ?? input.repoVisibility ?? "private",
746
+ homepageUrl: resolveManagedWebUrl(repoName),
747
+ topics: ["knowledge-coop", "treeseed", "knowledge-hub", "content"]
748
+ }, { env: githubEnv });
749
+ const contentInitResult = initializeGitHubRepositoryWorkingTree(contentRepositoryWorkingRoot, createdContentRepository, {
750
+ defaultBranch: input.contentRepository.defaultBranch ?? "main",
751
+ createStaging: true,
752
+ commitMessage: `Initialize ${input.projectName} content`
753
+ });
754
+ contentRepository = {
755
+ slug: createdContentRepository.slug,
756
+ owner: createdContentRepository.owner,
757
+ name: createdContentRepository.name,
758
+ url: createdContentRepository.url,
759
+ defaultBranch: contentInitResult.defaultBranch,
760
+ stagingBranch: contentInitResult.stagingBranch,
761
+ visibility: createdContentRepository.visibility
762
+ };
763
+ await appendPhase(phases, "content_repository", "completed", `${input.contentRepository.url ? "Connected" : "Created"} ${contentRepository.slug}.`, reportPhase);
764
+ stripSoftwareContentOverlay(workingRoot, input);
765
+ }
766
+ await appendPhase(phases, "workflow_bootstrap", "running", "Initializing git branches and GitHub workflows.", reportPhase);
670
767
  const initResult = initializeGitHubRepositoryWorkingTree(workingRoot, repository, {
671
768
  defaultBranch: "main",
672
769
  createStaging: true,
@@ -685,8 +782,8 @@ async function executeKnowledgeCoopManagedLaunch(input) {
685
782
  }));
686
783
  }
687
784
  const workflowSummary = { ...workflows, environmentSync: githubEnvironmentSync };
688
- appendPhase(phases, "workflow_bootstrap", "completed", "Configured GitHub workflows, secrets, and variables.");
689
- appendPhase(phases, "hosting_registration", "running", "Provisioning Cloudflare resources and deploy state.");
785
+ await appendPhase(phases, "workflow_bootstrap", "completed", "Configured GitHub workflows, secrets, and variables.", reportPhase);
786
+ await appendPhase(phases, "hosting_registration", "running", "Provisioning Cloudflare resources and deploy state.", reportPhase);
690
787
  const staging = await reconcileTreeseedTarget({
691
788
  tenantRoot: workingRoot,
692
789
  target: createPersistentDeployTarget("staging"),
@@ -703,7 +800,7 @@ async function executeKnowledgeCoopManagedLaunch(input) {
703
800
  target: createPersistentDeployTarget("prod"),
704
801
  env: { ...process.env, ...prodEnvOverlay }
705
802
  });
706
- appendPhase(phases, "hosting_registration", "completed", "Provisioned Cloudflare resources.");
803
+ await appendPhase(phases, "hosting_registration", "completed", "Provisioned Cloudflare resources.", reportPhase);
707
804
  const launchConfig = loadCliDeployConfig(workingRoot);
708
805
  const managedRuntime = launchConfig.runtime?.mode === "treeseed_managed";
709
806
  let services = [];
@@ -711,7 +808,7 @@ async function executeKnowledgeCoopManagedLaunch(input) {
711
808
  let schedules = [];
712
809
  let railwayVerification = [];
713
810
  if (managedRuntime) {
714
- appendPhase(phases, "runtime_connection", "running", "Deploying Railway services and registering runtime connectivity.");
811
+ await appendPhase(phases, "runtime_connection", "running", "Deploying Railway services and registering runtime connectivity.", reportPhase);
715
812
  const railwayEnv = { ...process.env, ...prodEnvOverlay };
716
813
  validateRailwayDeployPrerequisites(workingRoot, "prod", { env: railwayEnv });
717
814
  services = configuredRailwayServices(workingRoot, "prod");
@@ -722,9 +819,9 @@ async function executeKnowledgeCoopManagedLaunch(input) {
722
819
  schedules = await ensureRailwayScheduledJobs(workingRoot, "prod", { env: railwayEnv });
723
820
  railwayVerification = await verifyRailwayScheduledJobs(workingRoot, "prod", { env: railwayEnv });
724
821
  finalizeDeploymentState(workingRoot, { scope: "prod", serviceResults: deployments });
725
- appendPhase(phases, "runtime_connection", "completed", "Deployed Railway services and recorded runtime readiness.");
822
+ await appendPhase(phases, "runtime_connection", "completed", "Deployed Railway services and recorded runtime readiness.", reportPhase);
726
823
  } else {
727
- appendPhase(phases, "runtime_connection", "completed", "Skipped managed runtime deployment for hub-only or BYO runtime launch.");
824
+ await appendPhase(phases, "runtime_connection", "completed", "Skipped managed runtime deployment for hub-only or BYO runtime launch.", reportPhase);
728
825
  }
729
826
  const defaultWorkstream = createDefaultWorkstream(input.projectId, input, seed);
730
827
  const projectMetadata = loadProjectMetadata(
@@ -736,7 +833,8 @@ async function executeKnowledgeCoopManagedLaunch(input) {
736
833
  managedDefaults.projectApiBaseUrl,
737
834
  { slug: repository.slug, url: repository.url }
738
835
  );
739
- const templatePackage = buildKnowledgeCoopTemplatePackage(workingRoot, {
836
+ const packageRoot = packageSourceRoot ?? workingRoot;
837
+ const templatePackage = buildKnowledgeCoopTemplatePackage(packageRoot, {
740
838
  projectSlug: input.projectSlug,
741
839
  title: `${input.projectName} template`,
742
840
  summary: input.summary ?? null,
@@ -749,7 +847,7 @@ async function executeKnowledgeCoopManagedLaunch(input) {
749
847
  }
750
848
  }
751
849
  });
752
- const knowledgePackPackage = buildKnowledgeCoopKnowledgePackPackage(workingRoot, {
850
+ const knowledgePackPackage = buildKnowledgeCoopKnowledgePackPackage(packageRoot, {
753
851
  projectSlug: input.projectSlug,
754
852
  title: `${input.projectName} knowledge pack`,
755
853
  summary: input.summary ?? null,
@@ -769,10 +867,12 @@ async function executeKnowledgeCoopManagedLaunch(input) {
769
867
  owner: repository.owner,
770
868
  name: repository.name,
771
869
  url: repository.url,
772
- defaultBranch: initResult.defaultBranch,
773
- stagingBranch: initResult.stagingBranch,
870
+ defaultBranch: input.existingRepository?.defaultBranch ?? initResult.defaultBranch,
871
+ stagingBranch: input.existingRepository?.stagingBranch ?? initResult.stagingBranch,
774
872
  visibility: repository.visibility
775
873
  },
874
+ contentRepository,
875
+ contentRepositoryWorkingRoot,
776
876
  workflows: workflowSummary,
777
877
  cloudflare: {
778
878
  staging,
@@ -795,16 +895,19 @@ async function executeKnowledgeCoopManagedLaunch(input) {
795
895
  };
796
896
  } catch (error) {
797
897
  const message = error instanceof Error ? error.message : String(error);
798
- const phase = error instanceof KnowledgeCoopLaunchError ? error.phase : phases.some((entry) => entry.phase === "runtime_connection" && entry.status === "running") ? "runtime_connection_failed" : phases.some((entry) => entry.phase === "hosting_registration" && entry.status === "running") ? "hosting_registration_failed" : phases.some((entry) => entry.phase === "workflow_bootstrap" && entry.status === "running") ? "workflow_bootstrap_failed" : phases.some((entry) => entry.phase === "content_bootstrap" && entry.status === "running") ? "content_bootstrap_failed" : "repo_provision_failed";
799
- appendPhase(phases, phase.replace(/_failed$/u, ""), "failed", message);
800
- throw new KnowledgeCoopLaunchError(phase, message, phases);
898
+ const phase = error instanceof KnowledgeHubProviderLaunchError ? error.phase : phases.some((entry) => entry.phase === "runtime_connection" && entry.status === "running") ? "runtime_connection_failed" : phases.some((entry) => entry.phase === "hosting_registration" && entry.status === "running") ? "hosting_registration_failed" : phases.some((entry) => entry.phase === "workflow_bootstrap" && entry.status === "running") ? "workflow_bootstrap_failed" : phases.some((entry) => entry.phase === "content_bootstrap" && entry.status === "running") ? "content_bootstrap_failed" : "repo_provision_failed";
899
+ await appendPhase(phases, phase.replace(/_failed$/u, ""), "failed", message, reportPhase);
900
+ throw new KnowledgeHubProviderLaunchError(phase, message, phases);
801
901
  } finally {
802
902
  if (input.preserveWorkingTree === false) {
803
903
  rmSync(workingRoot, { recursive: true, force: true });
804
904
  }
905
+ if (packageSourceRoot && packageSourceRoot !== workingRoot && input.preserveWorkingTree === false) {
906
+ rmSync(packageSourceRoot, { recursive: true, force: true });
907
+ }
805
908
  }
806
909
  }
807
910
  export {
808
- executeKnowledgeCoopManagedLaunch,
809
- validateKnowledgeCoopManagedLaunchPrerequisites
911
+ executeKnowledgeHubProviderLaunch,
912
+ validateKnowledgeHubProviderLaunchPrerequisites
810
913
  };
@@ -33,6 +33,21 @@ const TRESEED_OPERATION_SPECS = [
33
33
  operation({ id: "template.sync", name: "sync", aliases: [], group: "Validation", summary: "Validate or reconcile the managed template surface for the current site.", description: "Use remote template metadata plus the local scaffold artifact to check or apply updates to the managed scaffold surface.", provider: "default", related: ["template", "init", "status"] }),
34
34
  operation({ id: "project.init", name: "init", aliases: [], group: "Workflow", summary: "Scaffold a new Treeseed tenant project.", description: "Create a new Treeseed tenant directory from a remote-catalog template backed by the packaged scaffold artifact.", provider: "default", related: ["config", "switch", "dev"] }),
35
35
  operation({ id: "project.config", name: "config", aliases: [], group: "Workflow", summary: "Configure and test the runtime foundation.", description: "Apply safe repairs, collect environment values, write local machine config, initialize environments, sync providers, and run doctor-style checks.", provider: "default", related: ["status", "switch", "dev"] }),
36
+ operation({ id: "hub.planLaunch", name: "hub.plan_launch", aliases: [], group: "Workflow", summary: "Plan an online Knowledge Hub launch.", description: "Normalize a Knowledge Hub launch intent, resolve repository topology, and return the durable launch plan shared by CLI and Market.", provider: "default", related: ["hub.validate_launch", "hub.execute_launch"] }),
37
+ operation({ id: "hub.validateLaunch", name: "hub.validate_launch", aliases: [], group: "Validation", summary: "Validate an online Knowledge Hub launch intent.", description: "Validate the shared Knowledge Hub launch intent and repository plan before execution.", provider: "default", related: ["hub.plan_launch", "hub.execute_launch"] }),
38
+ operation({ id: "hub.executeLaunch", name: "hub.execute_launch", aliases: [], group: "Workflow", summary: "Execute an online Knowledge Hub launch.", description: "Execute a Knowledge Hub launch through the shared SDK launch contract.", provider: "default", related: ["hub.plan_launch", "hub.resume_launch"] }),
39
+ operation({ id: "hub.resumeLaunch", name: "hub.resume_launch", aliases: [], group: "Workflow", summary: "Resume an online Knowledge Hub launch.", description: "Resume a previously planned Knowledge Hub launch from durable launch state.", provider: "default", related: ["hub.execute_launch"] }),
40
+ operation({ id: "hub.planUpdate", name: "hub.plan_update", aliases: [], group: "Workflow", summary: "Plan a Knowledge Hub update.", description: "Create a preview plan for template, knowledge pack, runtime, capability, or repository-topology updates.", provider: "default", related: ["hub.validate_update", "hub.execute_update"] }),
41
+ operation({ id: "hub.validateUpdate", name: "hub.validate_update", aliases: [], group: "Validation", summary: "Validate a Knowledge Hub update plan.", description: "Validate a planned update before it becomes binding work.", provider: "default", related: ["hub.plan_update"] }),
42
+ operation({ id: "hub.executeUpdate", name: "hub.execute_update", aliases: [], group: "Workflow", summary: "Execute a Knowledge Hub update.", description: "Apply a capability-gated Knowledge Hub update after required review or Decision approval.", provider: "default", related: ["hub.plan_update", "hub.resume_update"] }),
43
+ operation({ id: "hub.resumeUpdate", name: "hub.resume_update", aliases: [], group: "Workflow", summary: "Resume a Knowledge Hub update.", description: "Resume a previously planned Knowledge Hub update from durable state.", provider: "default", related: ["hub.execute_update"] }),
44
+ operation({ id: "repositoryHost.validate", name: "repository_host.validate", aliases: [], group: "Validation", summary: "Validate Repository Host configuration.", description: "Validate a GitHub Repository Host for Knowledge Hub repository provisioning.", provider: "default", related: ["repository_host.create_repositories"] }),
45
+ operation({ id: "repositoryHost.createRepositories", name: "repository_host.create_repositories", aliases: [], group: "Workflow", summary: "Create or connect Knowledge Hub repositories.", description: "Create or connect the software and content repositories for a Knowledge Hub repository plan.", provider: "default", related: ["hub.plan_launch"] }),
46
+ operation({ id: "content.verifyPackage", name: "content.verify_package", aliases: [], group: "Validation", summary: "Verify a content package before publishing.", description: "Verify Knowledge Hub content package metadata before publishing content artifacts.", provider: "default", related: ["content.publish"] }),
47
+ operation({ id: "content.publish", name: "content.publish", aliases: [], group: "Workflow", summary: "Publish Knowledge Hub content artifacts.", description: "Publish verified Knowledge Hub content artifacts to the configured content target.", provider: "default", related: ["content.verify_package"] }),
48
+ operation({ id: "workspace.planAttachParent", name: "workspace.plan_attach_parent", aliases: [], group: "Workflow", summary: "Plan parent workspace attachment.", description: "Plan how a Knowledge Hub software/content repository pair attaches to a parent repository workspace.", provider: "default", related: ["workspace.attach_parent"] }),
49
+ operation({ id: "workspace.attachParent", name: "workspace.attach_parent", aliases: [], group: "Workflow", summary: "Attach a parent workspace.", description: "Attach a parent repository workspace after technical steward approval.", provider: "default", related: ["workspace.plan_attach_parent", "workspace.update_submodule_pointers"] }),
50
+ operation({ id: "workspace.updateSubmodulePointers", name: "workspace.update_submodule_pointers", aliases: [], group: "Workflow", summary: "Update workspace submodule pointers.", description: "Update parent workspace submodule pointers for software and content repositories.", provider: "default", related: ["workspace.attach_parent"] }),
36
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"] }),
37
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"] }),
38
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"] }),
@@ -44,6 +44,7 @@ export type TreeseedOperationContext = {
44
44
  cwd: string;
45
45
  env: NodeJS.ProcessEnv;
46
46
  write?: TreeseedOperationWriter;
47
+ onProgress?: (event: Record<string, unknown>) => void | Promise<void>;
47
48
  spawn?: TreeseedOperationSpawn;
48
49
  outputFormat?: 'human' | 'json';
49
50
  prompt?: TreeseedOperationPrompt;
@@ -1,6 +1,8 @@
1
1
  export { TRESEED_OPERATION_SPECS, findTreeseedOperation, listTreeseedOperationNames, } from './operations-registry.ts';
2
2
  export { collectTreeseedConfigSeedValues } from './operations/services/config-runtime.ts';
3
+ export { createKnowledgeHubRepositories, defaultHubContentResolutionPolicy, executeKnowledgeHubLaunch, normalizeKnowledgeHubLaunchIntent, planKnowledgeHubLaunch, planKnowledgeHubRepositories, validateRepositoryHost, } from './operations/services/hub-launch.ts';
3
4
  export { TreeseedOperationsSdk } from './operations/runtime.ts';
5
+ export type { HubContentResolutionPolicy, KnowledgeHubLaunchIntent, KnowledgeHubLaunchPhase, KnowledgeHubLaunchPlan, KnowledgeHubLaunchResult, KnowledgeHubRepositoryPlan, RepositoryHost, } from './operations/services/hub-launch.ts';
4
6
  export type { TreeseedOperationContext, TreeseedOperationImplementation, TreeseedOperationId, TreeseedOperationMetadata, TreeseedOperationProvider, TreeseedOperationProviderId, TreeseedOperationRequest, TreeseedOperationResult, TreeseedOperationGroup, } from './operations-types.ts';
5
7
  export { TreeseedOperationError } from './operations-types.ts';
6
8
  export { TreeseedWorkflowSdk } from './workflow.ts';
@@ -4,6 +4,15 @@ import {
4
4
  listTreeseedOperationNames
5
5
  } from "./operations-registry.js";
6
6
  import { collectTreeseedConfigSeedValues } from "./operations/services/config-runtime.js";
7
+ import {
8
+ createKnowledgeHubRepositories,
9
+ defaultHubContentResolutionPolicy,
10
+ executeKnowledgeHubLaunch,
11
+ normalizeKnowledgeHubLaunchIntent,
12
+ planKnowledgeHubLaunch,
13
+ planKnowledgeHubRepositories,
14
+ validateRepositoryHost
15
+ } from "./operations/services/hub-launch.js";
7
16
  import { TreeseedOperationsSdk } from "./operations/runtime.js";
8
17
  import { TreeseedOperationError } from "./operations-types.js";
9
18
  import { TreeseedWorkflowSdk } from "./workflow.js";
@@ -13,6 +22,13 @@ export {
13
22
  TreeseedOperationsSdk,
14
23
  TreeseedWorkflowSdk,
15
24
  collectTreeseedConfigSeedValues,
25
+ createKnowledgeHubRepositories,
26
+ defaultHubContentResolutionPolicy,
27
+ executeKnowledgeHubLaunch,
16
28
  findTreeseedOperation,
17
- listTreeseedOperationNames
29
+ listTreeseedOperationNames,
30
+ normalizeKnowledgeHubLaunchIntent,
31
+ planKnowledgeHubLaunch,
32
+ planKnowledgeHubRepositories,
33
+ validateRepositoryHost
18
34
  };
package/dist/remote.d.ts CHANGED
@@ -230,4 +230,15 @@ export declare class RemoteTreeseedRunnerClient {
230
230
  ok: true;
231
231
  payload: RemoteJob;
232
232
  }>;
233
+ consumeCredentialSession(jobId: string, sessionId: string): Promise<{
234
+ ok: true;
235
+ payload: {
236
+ id: string;
237
+ hostKind: string;
238
+ hostId: string;
239
+ purpose: string;
240
+ provider?: string | null;
241
+ config: Record<string, string>;
242
+ };
243
+ }>;
233
244
  }
package/dist/remote.js CHANGED
@@ -262,6 +262,12 @@ class RemoteTreeseedRunnerClient {
262
262
  requireAuth: true
263
263
  });
264
264
  }
265
+ consumeCredentialSession(jobId, sessionId) {
266
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/provider-credential-sessions/${encodeURIComponent(sessionId)}/consume`, {
267
+ method: "POST",
268
+ requireAuth: true
269
+ });
270
+ }
265
271
  }
266
272
  export {
267
273
  CloudflareQueuePullClient,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.6.51",
3
+ "version": "0.7.0",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {