@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.
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ export { projectConnectionModeFromHosting } from './sdk-types.ts';
4
4
  export { createControlPlaneReporter } from './control-plane.ts';
5
5
  export { ControlPlaneClient } from './control-plane-client.ts';
6
6
  export { reservationHasCapacity, reserveCreditsForEstimate, scoreCapacityLane, selectBestCapacityLane, summarizeCapacityPlan, } from './capacity.ts';
7
- export { executeKnowledgeCoopManagedLaunch, validateKnowledgeCoopManagedLaunchPrerequisites, } from './operations/services/knowledge-coop-launch.ts';
7
+ export { executeKnowledgeHubProviderLaunch, validateKnowledgeHubProviderLaunchPrerequisites, } from './operations/services/hub-provider-launch.ts';
8
+ export { createKnowledgeHubRepositories, defaultHubContentResolutionPolicy, executeKnowledgeHubLaunch, normalizeKnowledgeHubLaunchIntent, planKnowledgeHubLaunch, planKnowledgeHubRepositories, validateRepositoryHost, type HubContentResolutionPolicy, type KnowledgeHubLaunchIntent, type KnowledgeHubLaunchPhase, type KnowledgeHubLaunchPlan, type KnowledgeHubLaunchResult, type KnowledgeHubRepositoryPlan, type RepositoryHost, } from './operations/services/hub-launch.ts';
8
9
  export { ensureRailwayEnvironment, ensureRailwayProject, ensureRailwayService, getRailwayAuthProfile, listRailwayEnvironments, listRailwayProjects, listRailwayServices, listRailwayVariables, railwayGraphqlRequest, resolveRailwayApiToken, resolveRailwayApiUrl, resolveRailwayWorkspace, resolveRailwayWorkspaceContext, upsertRailwayVariables, } from './operations/services/railway-api.ts';
9
10
  export { buildKnowledgeCoopKnowledgePackPackage, buildKnowledgeCoopTemplatePackage, importKnowledgeCoopKnowledgePack, } from './operations/services/knowledge-coop-packaging.ts';
10
11
  export { KNOWLEDGE_COOP_AGENT_MESSAGE_KINDS, KNOWLEDGE_COOP_JOB_STATUSES, KNOWLEDGE_COOP_RELEASE_STATES, KNOWLEDGE_COOP_SHARE_PACKAGE_STATES, KNOWLEDGE_COOP_TEAM_CAPABILITIES, KNOWLEDGE_COOP_WORKSTREAM_STATES, normalizeKnowledgeCoopJobStatus, normalizeRemoteJobStatus, } from './knowledge-coop.ts';
@@ -31,7 +32,7 @@ export { TreeseedWorkflowSdk } from './workflow.ts';
31
32
  export * from './db/index.ts';
32
33
  export { collectTreeseedReconcileStatus, createTreeseedReconcileRegistry, deriveTreeseedDesiredUnits, destroyTreeseedTargetUnits, observeTreeseedUnits, planTreeseedReconciliation, reconcileTreeseedTarget, } from './reconcile/index.ts';
33
34
  export { getTreeseedVerifyDriverStatus, runTreeseedVerifyDriver } from './verification.ts';
34
- export type { KnowledgeCoopLaunchPreflightReport, KnowledgeCoopLaunchFailurePhase, KnowledgeCoopManagedLaunchInput, KnowledgeCoopManagedLaunchResult, AgentMessageKind, AgentMessageRecord, AgentStatusRecord, DirectBoardItemSummary, InboxItem, KnowledgeCoopJobStatus, LaunchProjectRequest, LaunchProjectResult, LinkedProjectRecordRef, ProjectConnectionStatus, ProjectOverviewSummary, ReleaseDetail, ReleaseState, ReleaseSummary, SharePackageState, SharePackageStatus, TeamCapability, TeamHomeSummary, TeamMemberSummary, WorkstreamDetail, WorkstreamEvent, WorkstreamState, WorkstreamSummary, SdkContentEntry, SdkDispatchCapability, SdkDispatchConfig, SdkDispatchCredentialSource, SdkDispatchExecutionClass, SdkDispatchNamespace, SdkDispatchPolicy, SdkDispatchRequest, SdkDispatchResult, SdkDispatchTarget, SdkCursorEntity, SdkFilterCondition, SdkFollowRequest, SdkGraphEdge, SdkGraphEdgeType, SdkGraphDslRelation, SdkGraphDslParseResult, SdkGraphModelConfig, SdkGraphNode, SdkGraphNodeType, SdkGraphPathExplanation, SdkGraphQueryStage, SdkGraphQueryView, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphQueryResult, SdkGraphRankingBuildInput, SdkGraphRankingDiagnostics, SdkGraphRankingIndex, SdkGraphRankingNodeResult, SdkGraphRankingProvider, SdkGraphRankingQueryRequest, SdkGraphRankingQueryResult, SdkGraphRankingSearchRequest, SdkGraphRefreshPayload, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkGraphSearchResult, SdkGraphSeed, SdkGraphSeedResolution, SdkGraphTraversalResult, SdkGraphWhereFilter, SdkContextPack, SdkContextPackRequest, SdkGetRequest, SdkJsonEnvelope, SdkLeaseEntity, SdkManagerContextPayload, SdkMessageEntity, SdkModelFieldBinding, SdkModelDefinition, SdkModelRegistry, SdkModelName, SdkMutationRequest, SdkOperation, SdkPickRequest, SdkPickResult, SdkQueueMessageEnvelope, SdkRunEntity, SdkSearchRequest, SdkTaskEntity, SdkTaskEventEntity, SdkTaskOutputEntity, SdkWorkDayEntity, SdkGraphRunEntity, SdkReportEntity, SdkSubscriptionEntity, SdkTemplateCatalogEntry, SdkTemplateCatalogPublisher, SdkTemplateCatalogResponse, SdkTemplateCatalogSource, SdkUpdateRequest, ProjectCapabilityGrant, ProjectConnection, ProjectConnectionMode, ProjectDeployment, ProjectDeploymentKind, ProjectDeploymentStatus, ProjectEnvironment, ProjectExecutionOwner, ProjectHosting, ProjectInfrastructureResource, ProjectInfrastructureResourceKind, ProjectInfrastructureResourceProvider, ProjectRunnerRegistrationState, RemoteJob, RemoteJobEvent, RemoteJobStatus, AgentPool, AgentPoolAutoscalePolicy, AgentPoolRegistration, AgentPoolScaleDecision, AgentPoolStatus, CatalogArtifactVersion, CatalogItem, CatalogItemFilters, CatalogItemOfferMode, ProjectEnvironmentName, ProjectWorkdaySummary, TreeseedHostingKind, TreeseedHostingRegistration, PriorityOverride, WorkdayWindow, WorkdaySchedule, WorkdayRequest, WorkdayManagerLease, WorkerRunner, WorkerRunnerState, RepositoryClaim, TaskCreditWeight, TaskCreditBudget, WorkdayPolicy, PrioritySnapshotItem, PrioritySnapshot, TaskCreditLedgerEntry, ApprovalRequest, CapacityBusinessModel, CapacityGrant, CapacityGrantScope, CapacityLedgerEntry, CapacityLaneUnit, CapacityPlan, CapacityProvider, CapacityProviderHost, CapacityProviderKind, CapacityProviderLane, CapacityReservation, CapacityRoutingDecision, CapacityTaskExecutionEnvelope, CreateApprovalRequestRequest, CreateCapacityReservationRequest, CreateCapacityRoutingDecisionRequest, CreateTaskEstimateRequest, CreateTaskUsageActualRequest, RecordCapacityUsageRequest, TaskEstimate, TaskEstimateProfile, TaskUsageActual, UpsertCapacityGrantRequest, UpsertCapacityProviderHostRequest, UpsertCapacityProviderLaneRequest, UpsertCapacityProviderRequest, ScaleDecision, RunnerScaleDecision, TeamStorageLocator, TeamWebHost, TeamWebHostOwnership, TeamWebHostProvider, EncryptedWebHostPayload, UpsertAgentPoolRequest, UpsertCatalogArtifactVersionRequest, UpsertCatalogItemRequest, UpsertProjectEnvironmentRequest, UpsertProjectHostingRequest, UpsertProjectInfrastructureResourceRequest, UpsertTeamStorageLocatorRequest, UpsertTeamWebHostRequest, CreateProjectDeploymentRequest, RecordAgentPoolRegistrationRequest, SdkCreateWorkdayRequest, SdkClaimWorkdayManagerLeaseRequest, SdkReleaseWorkdayManagerLeaseRequest, SdkRecordWorkerRunnerRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkUpdateWorkDayGraphRequest, WorkerPoolScaleResult, WorkerPoolScaler, } from './sdk-types.ts';
35
+ export type { KnowledgeHubProviderLaunchPreflightReport, KnowledgeHubProviderLaunchFailurePhase, KnowledgeHubProviderLaunchInput, KnowledgeHubProviderLaunchResult, AgentMessageKind, AgentMessageRecord, AgentStatusRecord, DirectBoardItemSummary, InboxItem, KnowledgeCoopJobStatus, LaunchProjectRequest, LaunchProjectResult, LinkedProjectRecordRef, ProjectConnectionStatus, ProjectOverviewSummary, ReleaseDetail, ReleaseState, ReleaseSummary, SharePackageState, SharePackageStatus, TeamCapability, TeamHomeSummary, TeamMemberSummary, WorkstreamDetail, WorkstreamEvent, WorkstreamState, WorkstreamSummary, SdkContentEntry, SdkDispatchCapability, SdkDispatchConfig, SdkDispatchCredentialSource, SdkDispatchExecutionClass, SdkDispatchNamespace, SdkDispatchPolicy, SdkDispatchRequest, SdkDispatchResult, SdkDispatchTarget, SdkCursorEntity, SdkFilterCondition, SdkFollowRequest, SdkGraphEdge, SdkGraphEdgeType, SdkGraphDslRelation, SdkGraphDslParseResult, SdkGraphModelConfig, SdkGraphNode, SdkGraphNodeType, SdkGraphPathExplanation, SdkGraphQueryStage, SdkGraphQueryView, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphQueryResult, SdkGraphRankingBuildInput, SdkGraphRankingDiagnostics, SdkGraphRankingIndex, SdkGraphRankingNodeResult, SdkGraphRankingProvider, SdkGraphRankingQueryRequest, SdkGraphRankingQueryResult, SdkGraphRankingSearchRequest, SdkGraphRefreshPayload, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkGraphSearchResult, SdkGraphSeed, SdkGraphSeedResolution, SdkGraphTraversalResult, SdkGraphWhereFilter, SdkContextPack, SdkContextPackRequest, SdkGetRequest, SdkJsonEnvelope, SdkLeaseEntity, SdkManagerContextPayload, SdkMessageEntity, SdkModelFieldBinding, SdkModelDefinition, SdkModelRegistry, SdkModelName, SdkMutationRequest, SdkOperation, SdkPickRequest, SdkPickResult, SdkQueueMessageEnvelope, SdkRunEntity, SdkSearchRequest, SdkTaskEntity, SdkTaskEventEntity, SdkTaskOutputEntity, SdkWorkDayEntity, SdkGraphRunEntity, SdkReportEntity, SdkSubscriptionEntity, SdkTemplateCatalogEntry, SdkTemplateCatalogPublisher, SdkTemplateCatalogResponse, SdkTemplateCatalogSource, SdkUpdateRequest, ProjectCapabilityGrant, ProjectConnection, ProjectConnectionMode, ProjectDeployment, ProjectDeploymentKind, ProjectDeploymentStatus, ProjectEnvironment, ProjectExecutionOwner, ProjectHosting, ProjectInfrastructureResource, ProjectInfrastructureResourceKind, ProjectInfrastructureResourceProvider, ProjectRunnerRegistrationState, RemoteJob, RemoteJobEvent, RemoteJobStatus, AgentPool, AgentPoolAutoscalePolicy, AgentPoolRegistration, AgentPoolScaleDecision, AgentPoolStatus, CatalogArtifactVersion, CatalogItem, CatalogItemFilters, CatalogItemOfferMode, ProjectEnvironmentName, ProjectWorkdaySummary, TreeseedHostingKind, TreeseedHostingRegistration, PriorityOverride, WorkdayWindow, WorkdaySchedule, WorkdayRequest, WorkdayManagerLease, WorkerRunner, WorkerRunnerState, RepositoryClaim, TaskCreditWeight, TaskCreditBudget, WorkdayPolicy, PrioritySnapshotItem, PrioritySnapshot, TaskCreditLedgerEntry, ApprovalRequest, CapacityBusinessModel, CapacityGrant, CapacityGrantScope, CapacityLedgerEntry, CapacityLaneUnit, CapacityPlan, CapacityProvider, CapacityProviderHost, CapacityProviderKind, CapacityProviderLane, CapacityReservation, CapacityRoutingDecision, CapacityTaskExecutionEnvelope, CreateApprovalRequestRequest, CreateCapacityReservationRequest, CreateCapacityRoutingDecisionRequest, CreateTaskEstimateRequest, CreateTaskUsageActualRequest, RecordCapacityUsageRequest, TaskEstimate, TaskEstimateProfile, TaskUsageActual, UpsertCapacityGrantRequest, UpsertCapacityProviderHostRequest, UpsertCapacityProviderLaneRequest, UpsertCapacityProviderRequest, ScaleDecision, RunnerScaleDecision, TeamStorageLocator, TeamWebHost, TeamWebHostOwnership, TeamWebHostProvider, EncryptedWebHostPayload, UpsertAgentPoolRequest, UpsertCatalogArtifactVersionRequest, UpsertCatalogItemRequest, UpsertProjectEnvironmentRequest, UpsertProjectHostingRequest, UpsertProjectInfrastructureResourceRequest, UpsertTeamStorageLocatorRequest, UpsertTeamWebHostRequest, CreateProjectDeploymentRequest, RecordAgentPoolRegistrationRequest, SdkCreateWorkdayRequest, SdkClaimWorkdayManagerLeaseRequest, SdkReleaseWorkdayManagerLeaseRequest, SdkRecordWorkerRunnerRequest, SdkRecordRepositoryClaimRequest, SdkRecordRunnerScaleDecisionRequest, SdkUpdateWorkDayGraphRequest, WorkerPoolScaleResult, WorkerPoolScaler, } from './sdk-types.ts';
35
36
  export type * from './knowledge-coop.ts';
36
37
  export type { ControlPlaneAgentPoolHeartbeat, ControlPlaneDeploymentReport, ControlPlaneEnvironmentReport, ControlPlaneReporter, ControlPlaneReporterKind, ControlPlaneResourceReport, ControlPlaneScaleDecisionReport, ControlPlaneWorkdaySummaryReport, } from './control-plane.ts';
37
38
  export type { ControlPlaneClientOptions } from './control-plane-client.ts';
package/dist/index.js CHANGED
@@ -11,9 +11,18 @@ import {
11
11
  summarizeCapacityPlan
12
12
  } from "./capacity.js";
13
13
  import {
14
- executeKnowledgeCoopManagedLaunch,
15
- validateKnowledgeCoopManagedLaunchPrerequisites
16
- } from "./operations/services/knowledge-coop-launch.js";
14
+ executeKnowledgeHubProviderLaunch,
15
+ validateKnowledgeHubProviderLaunchPrerequisites
16
+ } from "./operations/services/hub-provider-launch.js";
17
+ import {
18
+ createKnowledgeHubRepositories,
19
+ defaultHubContentResolutionPolicy,
20
+ executeKnowledgeHubLaunch,
21
+ normalizeKnowledgeHubLaunchIntent,
22
+ planKnowledgeHubLaunch,
23
+ planKnowledgeHubRepositories,
24
+ validateRepositoryHost
25
+ } from "./operations/services/hub-launch.js";
17
26
  import {
18
27
  ensureRailwayEnvironment,
19
28
  ensureRailwayProject,
@@ -239,17 +248,20 @@ export {
239
248
  createControlPlaneReporter,
240
249
  createDefaultGraphRankingProvider,
241
250
  createFilesystemContentSource,
251
+ createKnowledgeHubRepositories,
242
252
  createPublishedContentPipeline,
243
253
  createTeamScopedR2OverlayContentPublishProvider,
244
254
  createTeamScopedR2OverlayContentRuntimeProvider,
245
255
  createTreeseedManagedToolEnv,
246
256
  createTreeseedReconcileRegistry,
257
+ defaultHubContentResolutionPolicy,
247
258
  deriveTreeseedDesiredUnits,
248
259
  destroyTreeseedTargetUnits,
249
260
  ensureRailwayEnvironment,
250
261
  ensureRailwayProject,
251
262
  ensureRailwayService,
252
- executeKnowledgeCoopManagedLaunch,
263
+ executeKnowledgeHubLaunch,
264
+ executeKnowledgeHubProviderLaunch,
253
265
  executeSdkOperation,
254
266
  findDispatchCapability,
255
267
  findSdkOperation,
@@ -278,6 +290,7 @@ export {
278
290
  normalizeAliasedRecord,
279
291
  normalizeFilterFields,
280
292
  normalizeKnowledgeCoopJobStatus,
293
+ normalizeKnowledgeHubLaunchIntent,
281
294
  normalizeMutationData,
282
295
  normalizeRecordToCanonicalShape,
283
296
  normalizeRemoteJobStatus,
@@ -288,6 +301,8 @@ export {
288
301
  parsePublishedContentManifest,
289
302
  parsePublishedOverlayManifest,
290
303
  parseTemplateCatalogResponse,
304
+ planKnowledgeHubLaunch,
305
+ planKnowledgeHubRepositories,
291
306
  planTreeseedReconciliation,
292
307
  preprocessAliasedRecord,
293
308
  projectConnectionModeFromHosting,
@@ -332,8 +347,9 @@ export {
332
347
  tenantFeatureEnabled,
333
348
  tenantModelRendered,
334
349
  upsertRailwayVariables,
335
- validateKnowledgeCoopManagedLaunchPrerequisites,
350
+ validateKnowledgeHubProviderLaunchPrerequisites,
336
351
  validateModelFieldAliases,
352
+ validateRepositoryHost,
337
353
  verifyArtifactBytes,
338
354
  verifyEditorialPreviewToken,
339
355
  writeMarketRegistryState
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { join, relative, resolve } from "node:path";
4
4
  import { tmpdir } from "node:os";
@@ -46,7 +46,14 @@ import {
46
46
  syncTemplateProject,
47
47
  validateTemplateProduct
48
48
  } from "../../operations/services/template-registry.js";
49
- import { validateKnowledgeCoopManagedLaunchPrerequisites } from "../../operations/services/knowledge-coop-launch.js";
49
+ import { validateKnowledgeHubProviderLaunchPrerequisites } from "../../operations/services/hub-provider-launch.js";
50
+ import { publishProjectContent } from "../../operations/services/project-platform.js";
51
+ import {
52
+ createKnowledgeHubRepositories,
53
+ executeKnowledgeHubLaunch,
54
+ planKnowledgeHubLaunch,
55
+ validateRepositoryHost
56
+ } from "../../operations/services/hub-launch.js";
50
57
  import {
51
58
  collectCliPreflight,
52
59
  formatCliPreflightReport
@@ -142,6 +149,34 @@ function copyDirectory(sourceDir, targetDir) {
142
149
  writeFileSync(targetPath, readFileSync(sourcePath));
143
150
  }
144
151
  }
152
+ function copyFileIfExists(sourceFile, targetFile) {
153
+ if (!existsSync(sourceFile)) return;
154
+ mkdirSync(resolve(targetFile, ".."), { recursive: true });
155
+ writeFileSync(targetFile, readFileSync(sourceFile));
156
+ }
157
+ function prepareContentPublishRoot(tenantRoot, contentRepositoryRoot) {
158
+ if (!contentRepositoryRoot || resolve(contentRepositoryRoot) === resolve(tenantRoot)) {
159
+ return { root: tenantRoot, cleanup: () => {
160
+ } };
161
+ }
162
+ const tempRoot = mkdtempSync(join(tmpdir(), "treeseed-content-repo-publish-"));
163
+ copyFileIfExists(resolve(tenantRoot, "treeseed.site.yaml"), resolve(tempRoot, "treeseed.site.yaml"));
164
+ copyFileIfExists(resolve(tenantRoot, "package.json"), resolve(tempRoot, "package.json"));
165
+ copyFileIfExists(resolve(tenantRoot, "src", "manifest.yaml"), resolve(tempRoot, "src", "manifest.yaml"));
166
+ copyTreeseedOperationalState(tenantRoot, tempRoot);
167
+ const contentSource = resolve(contentRepositoryRoot, "src", "content");
168
+ if (existsSync(contentSource)) {
169
+ copyDirectory(contentSource, resolve(tempRoot, "src", "content"));
170
+ }
171
+ const publicSource = resolve(contentRepositoryRoot, "public");
172
+ if (existsSync(publicSource)) {
173
+ copyDirectory(publicSource, resolve(tempRoot, "public"));
174
+ }
175
+ return {
176
+ root: tempRoot,
177
+ cleanup: () => rmSync(tempRoot, { recursive: true, force: true })
178
+ };
179
+ }
145
180
  function workflowInputForOperation(name, input) {
146
181
  switch (name) {
147
182
  case "status":
@@ -218,12 +253,12 @@ class PreflightOperation extends BaseOperation {
218
253
  cwd: context.cwd,
219
254
  requireAuth: input.requireAuth ?? this.requireAuth
220
255
  });
221
- const launch = input.launch === true || input.managedLaunch === true ? await validateKnowledgeCoopManagedLaunchPrerequisites(context.cwd) : null;
256
+ const launch = input.launch === true || input.managedLaunch === true ? await validateKnowledgeHubProviderLaunchPrerequisites(context.cwd) : null;
222
257
  const stdout = [formatCliPreflightReport(report)];
223
258
  if (launch) {
224
259
  stdout.push(
225
260
  "",
226
- "Knowledge Coop managed launch preflight",
261
+ "Knowledge Hub launch preflight",
227
262
  `- ok: ${launch.ok ? "yes" : "no"}`,
228
263
  `- commands: git=${launch.commands.git ? "ok" : "missing"}, gh=${launch.commands.gh ? "ok" : "missing"}, wrangler=${launch.commands.wrangler ? "ok" : "missing"}, railway=${launch.commands.railway ? "ok" : "missing"}`
229
264
  );
@@ -253,6 +288,23 @@ class InitOperation extends BaseOperation {
253
288
  if (!directory) {
254
289
  return failureResult(this.metadata, "Init requires a target directory.");
255
290
  }
291
+ const launchPlan = planKnowledgeHubLaunch({
292
+ team: { id: typeof input.teamId === "string" ? input.teamId : "local" },
293
+ hub: {
294
+ name: typeof input.name === "string" ? input.name : directory,
295
+ slug: typeof input.slug === "string" ? input.slug : directory,
296
+ visibility: "team"
297
+ },
298
+ source: {
299
+ kind: "template",
300
+ ref: String(input.template ?? "starter-basic")
301
+ },
302
+ repository: {
303
+ topology: input.repositoryTopology === "split_software_content" ? "split_software_content" : "combined_compatibility",
304
+ provider: "github"
305
+ },
306
+ hosting: { mode: "self_hosted" }
307
+ });
256
308
  const definition = await scaffoldTemplateProject(
257
309
  String(input.template ?? "starter-basic"),
258
310
  resolve(context.cwd, directory),
@@ -269,7 +321,8 @@ class InitOperation extends BaseOperation {
269
321
  );
270
322
  return operationResult(this.metadata, {
271
323
  directory,
272
- template: definition.id
324
+ template: definition.id,
325
+ launchPlan
273
326
  });
274
327
  }
275
328
  }
@@ -318,6 +371,386 @@ class SyncTemplateOperation extends BaseOperation {
318
371
  });
319
372
  }
320
373
  }
374
+ class HubPlanLaunchOperation extends BaseOperation {
375
+ async execute(input, _context) {
376
+ const intent = input.intent && typeof input.intent === "object" ? input.intent : input;
377
+ return operationResult(this.metadata, planKnowledgeHubLaunch(intent));
378
+ }
379
+ }
380
+ class HubValidateLaunchOperation extends BaseOperation {
381
+ async execute(input, _context) {
382
+ try {
383
+ const intent = input.intent && typeof input.intent === "object" ? input.intent : input;
384
+ const plan = planKnowledgeHubLaunch(intent);
385
+ return operationResult(this.metadata, {
386
+ ok: true,
387
+ issues: [],
388
+ plan
389
+ });
390
+ } catch (error) {
391
+ return operationResult(this.metadata, {
392
+ ok: false,
393
+ issues: [error instanceof Error ? error.message : String(error)]
394
+ }, {
395
+ ok: false,
396
+ exitCode: 1
397
+ });
398
+ }
399
+ }
400
+ }
401
+ class HubExecuteLaunchOperation extends BaseOperation {
402
+ async execute(input, context) {
403
+ const intent = input.intent && typeof input.intent === "object" ? input.intent : input;
404
+ const result = await executeKnowledgeHubLaunch(intent, {
405
+ onPhase: async (phase) => {
406
+ await context.onProgress?.({
407
+ kind: "hub_launch_phase",
408
+ ...phase
409
+ });
410
+ }
411
+ });
412
+ return operationResult(this.metadata, result);
413
+ }
414
+ }
415
+ class HubResumeLaunchOperation extends BaseOperation {
416
+ async execute(input, context) {
417
+ const intent = input.intent && typeof input.intent === "object" ? input.intent : input;
418
+ const result = await executeKnowledgeHubLaunch(intent, {
419
+ onPhase: async (phase) => {
420
+ await context.onProgress?.({
421
+ kind: "hub_launch_phase",
422
+ resumed: true,
423
+ ...phase
424
+ });
425
+ }
426
+ });
427
+ return operationResult(this.metadata, {
428
+ resumed: true,
429
+ ...result
430
+ });
431
+ }
432
+ }
433
+ function plainObject(value) {
434
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
435
+ }
436
+ function stringValue(value, fallback = "") {
437
+ return typeof value === "string" && value.trim() ? value.trim() : fallback;
438
+ }
439
+ function arrayOfStrings(value) {
440
+ return Array.isArray(value) ? value.map((entry) => String(entry)).filter(Boolean) : [];
441
+ }
442
+ function normalizeUpdatePlan(input, cwd) {
443
+ const source = plainObject(input.source);
444
+ const sourceKind = stringValue(input.sourceKind ?? source.kind, "template");
445
+ const sourceRef = stringValue(input.sourceRef ?? source.ref, "");
446
+ const sourceVersion = stringValue(input.sourceVersion ?? source.version, "");
447
+ const requestedChanges = Array.isArray(input.changes) ? input.changes : [];
448
+ const changedPaths = requestedChanges.length > 0 ? requestedChanges.flatMap((change) => {
449
+ const entry = plainObject(change);
450
+ return stringValue(entry.path) ? [String(entry.path)] : arrayOfStrings(entry.paths);
451
+ }) : arrayOfStrings(input.changedPaths);
452
+ const safeConfigOnly = input.safeConfigOnly === true || input.updateKind === "runtime_config";
453
+ const behaviorChanges = arrayOfStrings(input.behaviorChanges);
454
+ const contentChanges = changedPaths.filter((path) => path.startsWith("src/content/") || path.startsWith("content/"));
455
+ const requiresDecision = input.requiresDecision === true || !safeConfigOnly && (contentChanges.length > 0 || behaviorChanges.length > 0 || ["template", "knowledge_pack", "market_listing"].includes(sourceKind));
456
+ const conflicts = arrayOfStrings(input.conflicts).map((path) => ({
457
+ path,
458
+ reason: "caller_reported_conflict"
459
+ }));
460
+ return {
461
+ state: "planned",
462
+ hubId: stringValue(input.hubId ?? input.projectId, ""),
463
+ sourceKind,
464
+ sourceRef: sourceRef || null,
465
+ sourceVersion: sourceVersion || null,
466
+ changedPaths,
467
+ conflicts,
468
+ requiredDecisions: requiresDecision ? [{
469
+ kind: "binding_update",
470
+ reason: safeConfigOnly ? "approval_policy" : "template_or_content_change",
471
+ decisionId: stringValue(input.decisionId, "") || null
472
+ }] : [],
473
+ requiresDecision,
474
+ repositoryTargets: plainObject(input.repositoryTargets),
475
+ provenance: {
476
+ sourceKind,
477
+ sourceRef: sourceRef || null,
478
+ sourceVersion: sourceVersion || null,
479
+ plannedAt: (/* @__PURE__ */ new Date()).toISOString()
480
+ },
481
+ workspace: plainObject(input.workspace),
482
+ tenantRoot: stringValue(input.tenantRoot, cwd)
483
+ };
484
+ }
485
+ function writeJsonFile(path, value) {
486
+ mkdirSync(resolve(path, ".."), { recursive: true });
487
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
488
+ `, "utf8");
489
+ }
490
+ function workspaceAttachPlan(input, cwd) {
491
+ const parent = plainObject(input.parent ?? input.parentRepository);
492
+ const software = plainObject(input.softwareRepository);
493
+ const content = plainObject(input.contentRepository);
494
+ const hubMountPath = stringValue(input.hubMountPath, "docs");
495
+ const softwareSubmodulePath = stringValue(input.softwareSubmodulePath, `${hubMountPath}/hub-site`);
496
+ const contentSubmodulePath = stringValue(input.contentSubmodulePath, `${hubMountPath}/hub-content`);
497
+ const issues = [];
498
+ if (!stringValue(parent.owner) && !stringValue(parent.url)) issues.push("Parent repository owner/url is required.");
499
+ if (!stringValue(parent.name) && !stringValue(parent.url)) issues.push("Parent repository name/url is required.");
500
+ if (!stringValue(software.url) && !stringValue(software.name)) issues.push("Software repository url/name is required.");
501
+ if (!stringValue(content.url) && !stringValue(content.name)) issues.push("Content repository url/name is required.");
502
+ return {
503
+ state: issues.length > 0 ? "invalid" : "planned",
504
+ issues,
505
+ hubId: stringValue(input.hubId ?? input.projectId, ""),
506
+ tenantRoot: stringValue(input.tenantRoot, cwd),
507
+ parentRepository: parent,
508
+ softwareRepository: software,
509
+ contentRepository: content,
510
+ hubMountPath,
511
+ softwareSubmodulePath,
512
+ contentSubmodulePath,
513
+ updateSubmodulePointersEnabled: input.updateSubmodulePointersEnabled === true,
514
+ allowedWriteTargets: arrayOfStrings(input.allowedWriteTargets).length > 0 ? arrayOfStrings(input.allowedWriteTargets) : ["content"],
515
+ contentOverlay: stringValue(input.contentOverlay, "src_content_when_present")
516
+ };
517
+ }
518
+ class HubPlanUpdateOperation extends BaseOperation {
519
+ async execute(input, context) {
520
+ return operationResult(this.metadata, normalizeUpdatePlan(input, context.cwd));
521
+ }
522
+ }
523
+ class HubValidateUpdateOperation extends BaseOperation {
524
+ async execute(input, _context) {
525
+ const issues = [];
526
+ if (!input.hubId && !input.projectId) issues.push("hubId or projectId is required.");
527
+ if (!input.sourceKind) issues.push("sourceKind is required.");
528
+ return operationResult(this.metadata, {
529
+ ok: issues.length === 0,
530
+ issues
531
+ }, {
532
+ ok: issues.length === 0,
533
+ exitCode: issues.length === 0 ? 0 : 1
534
+ });
535
+ }
536
+ }
537
+ class HubExecuteUpdateOperation extends BaseOperation {
538
+ async execute(input, context) {
539
+ const plan = normalizeUpdatePlan(plainObject(input.plan).state ? plainObject(input.plan) : input, context.cwd);
540
+ const decisionApproved = input.decisionApproved === true || typeof input.decisionId === "string" || typeof input.approvedDecisionId === "string";
541
+ if (plan.requiresDecision && !decisionApproved) {
542
+ const proposal = {
543
+ kind: "treeseed_update_proposal",
544
+ plan,
545
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
546
+ reason: "Decision required before binding template, pack, content, or behavior changes."
547
+ };
548
+ const proposalPath = resolve(plan.tenantRoot, ".treeseed", "proposals", `update-${Date.now()}.json`);
549
+ writeJsonFile(proposalPath, proposal);
550
+ return operationResult(this.metadata, {
551
+ state: "waiting_for_decision",
552
+ applied: false,
553
+ requiresDecision: true,
554
+ proposalPath: relative(plan.tenantRoot, proposalPath),
555
+ plan
556
+ });
557
+ }
558
+ const appliedPath = resolve(plan.tenantRoot, ".treeseed", "updates", `applied-${Date.now()}.json`);
559
+ writeJsonFile(appliedPath, {
560
+ kind: "treeseed_safe_update_application",
561
+ plan,
562
+ decisionApproved,
563
+ appliedAt: (/* @__PURE__ */ new Date()).toISOString()
564
+ });
565
+ return operationResult(this.metadata, {
566
+ state: "applied",
567
+ applied: true,
568
+ requiresDecision: plan.requiresDecision,
569
+ appliedPath: relative(plan.tenantRoot, appliedPath),
570
+ plan
571
+ });
572
+ }
573
+ }
574
+ class HubResumeUpdateOperation extends BaseOperation {
575
+ async execute(input, context) {
576
+ const executor = new HubExecuteUpdateOperation(this.metadata.name);
577
+ return executor.execute({ ...input, resumed: true }, context);
578
+ }
579
+ }
580
+ class RepositoryHostValidateOperation extends BaseOperation {
581
+ async execute(input, _context) {
582
+ const host = input.host && typeof input.host === "object" ? input.host : input;
583
+ const result = validateRepositoryHost(host);
584
+ return operationResult(this.metadata, {
585
+ ...result,
586
+ validatedAt: (/* @__PURE__ */ new Date()).toISOString()
587
+ }, {
588
+ ok: result.ok,
589
+ exitCode: result.ok ? 0 : 1
590
+ });
591
+ }
592
+ }
593
+ class RepositoryHostCreateRepositoriesOperation extends BaseOperation {
594
+ async execute(input, _context) {
595
+ const plan = input.plan;
596
+ if (!plan) {
597
+ return failureResult(this.metadata, "repository_host.create_repositories requires a repository plan.");
598
+ }
599
+ return operationResult(this.metadata, await createKnowledgeHubRepositories({
600
+ plan,
601
+ dryRun: input.dryRun === true,
602
+ description: typeof input.description === "string" ? input.description : null,
603
+ homepageUrl: typeof input.homepageUrl === "string" ? input.homepageUrl : null
604
+ }));
605
+ }
606
+ }
607
+ class ContentVerifyPackageOperation extends BaseOperation {
608
+ async execute(input, context) {
609
+ const tenantRoot = typeof input.tenantRoot === "string" ? input.tenantRoot : context.cwd;
610
+ const contentRoot = resolve(tenantRoot, "src", "content");
611
+ return operationResult(this.metadata, {
612
+ ok: existsSync(contentRoot),
613
+ packageRef: typeof input.packageRef === "string" ? input.packageRef : null,
614
+ contentRoot,
615
+ issues: existsSync(contentRoot) ? [] : [`Missing content root: ${contentRoot}`]
616
+ });
617
+ }
618
+ }
619
+ class ContentPublishOperation extends BaseOperation {
620
+ async execute(input, context) {
621
+ const tenantRoot = typeof input.tenantRoot === "string" ? input.tenantRoot : context.cwd;
622
+ const contentRepositoryRoot = typeof input.contentRepositoryRoot === "string" ? input.contentRepositoryRoot : typeof input.contentRoot === "string" ? input.contentRoot : null;
623
+ const scope = input.scope === "staging" || input.scope === "prod" || input.scope === "local" ? input.scope : "prod";
624
+ if (input.dryRun === true) {
625
+ return operationResult(this.metadata, {
626
+ status: "planned",
627
+ tenantRoot,
628
+ contentRepositoryRoot,
629
+ scope,
630
+ publishTarget: typeof input.publishTarget === "string" ? input.publishTarget : "r2_published_artifacts"
631
+ });
632
+ }
633
+ const preparedRoot = prepareContentPublishRoot(tenantRoot, contentRepositoryRoot);
634
+ try {
635
+ const result = await publishProjectContent({
636
+ tenantRoot: preparedRoot.root,
637
+ scope,
638
+ projectId: typeof input.projectId === "string" ? input.projectId : null,
639
+ previewId: typeof input.previewId === "string" ? input.previewId : null,
640
+ env: context.env
641
+ });
642
+ return operationResult(this.metadata, {
643
+ status: "published",
644
+ scope,
645
+ tenantRoot,
646
+ contentRepositoryRoot,
647
+ result,
648
+ publishTarget: "r2_published_artifacts",
649
+ contentSource: contentRepositoryRoot ? "content_repository" : "tenant_root",
650
+ r2: {
651
+ bucketName: context.env?.TREESEED_CONTENT_BUCKET_NAME ?? process.env.TREESEED_CONTENT_BUCKET_NAME ?? null,
652
+ publicBaseUrl: context.env?.TREESEED_CONTENT_PUBLIC_BASE_URL ?? process.env.TREESEED_CONTENT_PUBLIC_BASE_URL ?? null
653
+ }
654
+ });
655
+ } finally {
656
+ preparedRoot.cleanup();
657
+ }
658
+ }
659
+ }
660
+ class WorkspacePlanAttachParentOperation extends BaseOperation {
661
+ async execute(input, context) {
662
+ const plan = workspaceAttachPlan(input, context.cwd);
663
+ return operationResult(this.metadata, {
664
+ ...plan,
665
+ requiresTechnicalStewardApproval: true
666
+ }, {
667
+ ok: plan.issues.length === 0,
668
+ exitCode: plan.issues.length === 0 ? 0 : 1
669
+ });
670
+ }
671
+ }
672
+ class WorkspaceAttachParentOperation extends BaseOperation {
673
+ async execute(input, context) {
674
+ const plan = workspaceAttachPlan(plainObject(input.plan).state ? plainObject(input.plan) : input, context.cwd);
675
+ if (plan.issues.length > 0) {
676
+ return operationResult(this.metadata, {
677
+ state: "invalid",
678
+ attached: false,
679
+ issues: plan.issues,
680
+ plan
681
+ }, {
682
+ ok: false,
683
+ exitCode: 1
684
+ });
685
+ }
686
+ const manifest = {
687
+ schemaVersion: 1,
688
+ kind: "treeseed_composed_workspace",
689
+ hubId: plan.hubId,
690
+ parentRepository: plan.parentRepository,
691
+ softwareRepository: plan.softwareRepository,
692
+ contentRepository: plan.contentRepository,
693
+ mounts: {
694
+ hub: plan.hubMountPath,
695
+ software: plan.softwareSubmodulePath,
696
+ content: plan.contentSubmodulePath
697
+ },
698
+ updateSubmodulePointersEnabled: plan.updateSubmodulePointersEnabled,
699
+ allowedWriteTargets: plan.allowedWriteTargets,
700
+ credentialScopes: {
701
+ software: ["repository:software"],
702
+ content: ["repository:content"],
703
+ parentWorkspace: plan.updateSubmodulePointersEnabled ? ["repository:parent_workspace"] : []
704
+ },
705
+ contentOverlay: plan.contentOverlay,
706
+ attachedAt: (/* @__PURE__ */ new Date()).toISOString()
707
+ };
708
+ const manifestPath = resolve(plan.tenantRoot, ".treeseed", "workspace.json");
709
+ writeJsonFile(manifestPath, manifest);
710
+ return operationResult(this.metadata, {
711
+ state: "attached",
712
+ attached: true,
713
+ manifestPath: relative(plan.tenantRoot, manifestPath),
714
+ manifest,
715
+ plan
716
+ });
717
+ }
718
+ }
719
+ class WorkspaceUpdateSubmodulePointersOperation extends BaseOperation {
720
+ async execute(input, context) {
721
+ const plan = workspaceAttachPlan(plainObject(input.workspace).state ? plainObject(input.workspace) : input, context.cwd);
722
+ const hasCapability = input.hasParentWorkspaceCapability === true || arrayOfStrings(input.capabilities).includes("parent_workspace:update_submodule_pointers");
723
+ if (!plan.updateSubmodulePointersEnabled || !hasCapability) {
724
+ return operationResult(this.metadata, {
725
+ state: "blocked",
726
+ updated: false,
727
+ reason: !plan.updateSubmodulePointersEnabled ? "Workspace link does not allow TreeSeed to update submodule pointers." : "Caller does not have parent workspace capability.",
728
+ softwareRef: stringValue(input.softwareRef) || null,
729
+ contentRef: stringValue(input.contentRef) || null
730
+ }, {
731
+ ok: false,
732
+ exitCode: 1
733
+ });
734
+ }
735
+ const pointerPlan = {
736
+ kind: "treeseed_workspace_submodule_pointer_update",
737
+ hubId: plan.hubId,
738
+ softwareSubmodulePath: plan.softwareSubmodulePath,
739
+ contentSubmodulePath: plan.contentSubmodulePath,
740
+ softwareRef: stringValue(input.softwareRef) || null,
741
+ contentRef: stringValue(input.contentRef) || null,
742
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
743
+ };
744
+ const pointerPath = resolve(plan.tenantRoot, ".treeseed", "workspace-submodule-pointers.json");
745
+ writeJsonFile(pointerPath, pointerPlan);
746
+ return operationResult(this.metadata, {
747
+ state: "updated",
748
+ updated: true,
749
+ pointerPath: relative(plan.tenantRoot, pointerPath),
750
+ ...pointerPlan
751
+ });
752
+ }
753
+ }
321
754
  class DoctorOperation extends BaseOperation {
322
755
  async execute(_input, context) {
323
756
  const state = resolveTreeseedWorkflowState(context.cwd);
@@ -640,6 +1073,21 @@ class DefaultTreeseedOperationsProvider {
640
1073
  new WorkflowOperation("dev"),
641
1074
  new WorkflowOperation("dev:watch", "dev"),
642
1075
  new InitOperation("init"),
1076
+ new HubPlanLaunchOperation("hub.plan_launch"),
1077
+ new HubValidateLaunchOperation("hub.validate_launch"),
1078
+ new HubExecuteLaunchOperation("hub.execute_launch"),
1079
+ new HubResumeLaunchOperation("hub.resume_launch"),
1080
+ new HubPlanUpdateOperation("hub.plan_update"),
1081
+ new HubValidateUpdateOperation("hub.validate_update"),
1082
+ new HubExecuteUpdateOperation("hub.execute_update"),
1083
+ new HubResumeUpdateOperation("hub.resume_update"),
1084
+ new RepositoryHostValidateOperation("repository_host.validate"),
1085
+ new RepositoryHostCreateRepositoriesOperation("repository_host.create_repositories"),
1086
+ new ContentVerifyPackageOperation("content.verify_package"),
1087
+ new ContentPublishOperation("content.publish"),
1088
+ new WorkspacePlanAttachParentOperation("workspace.plan_attach_parent"),
1089
+ new WorkspaceAttachParentOperation("workspace.attach_parent"),
1090
+ new WorkspaceUpdateSubmodulePointersOperation("workspace.update_submodule_pointers"),
643
1091
  new TemplateOperation("template"),
644
1092
  new SyncTemplateOperation("sync"),
645
1093
  new DoctorOperation("doctor"),
@@ -13,6 +13,7 @@ function defaultContext(overrides = {}) {
13
13
  cwd: overrides.cwd ?? process.cwd(),
14
14
  env: overrides.env ?? process.env,
15
15
  write: overrides.write,
16
+ onProgress: overrides.onProgress,
16
17
  spawn: overrides.spawn,
17
18
  outputFormat: overrides.outputFormat ?? "human",
18
19
  prompt: overrides.prompt,
@@ -51,7 +51,9 @@ export declare function ensureGitHubBootstrapRepository(tenantRoot: string, { va
51
51
  pushed: boolean;
52
52
  mode: string;
53
53
  }>;
54
- export declare function createGitHubRepository(input: any): Promise<import("./github-api.ts").GitHubRepositorySummary>;
54
+ export declare function createGitHubRepository(input: any, { env }?: {
55
+ env?: NodeJS.ProcessEnv | undefined;
56
+ }): Promise<import("./github-api.ts").GitHubRepositorySummary>;
55
57
  export declare function initializeGitHubRepositoryWorkingTree(cwd: any, repository: any, { defaultBranch, createStaging, commitMessage, remoteName, push, }?: {
56
58
  defaultBranch?: string | undefined;
57
59
  createStaging?: boolean | undefined;
@@ -200,7 +200,7 @@ async function ensureGitHubBootstrapRepository(tenantRoot, {
200
200
  mode: "real"
201
201
  };
202
202
  }
203
- async function createGitHubRepository(input) {
203
+ async function createGitHubRepository(input, { env = process.env } = {}) {
204
204
  const visibility = input.visibility ?? "private";
205
205
  const remotes = resolveGitHubRemoteUrls(input.owner, input.name);
206
206
  return await ensureGitHubRepository({
@@ -211,7 +211,7 @@ async function createGitHubRepository(input) {
211
211
  visibility,
212
212
  topics: Array.isArray(input.topics) ? input.topics.map((topic) => slugifySegment(topic, "treeseed")) : []
213
213
  }, {
214
- client: createGitHubApiClient()
214
+ client: createGitHubApiClient({ env })
215
215
  });
216
216
  }
217
217
  function initializeGitHubRepositoryWorkingTree(cwd, repository, {