@treeseed/sdk 0.5.2 → 0.6.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 +2 -0
- package/dist/index.js +46 -0
- package/dist/operations/providers/default.js +1 -1
- package/dist/operations/services/config-runtime.d.ts +49 -42
- package/dist/operations/services/config-runtime.js +465 -142
- package/dist/operations/services/deploy.d.ts +298 -0
- package/dist/operations/services/deploy.js +381 -137
- package/dist/operations/services/git-workflow.d.ts +9 -0
- package/dist/operations/services/git-workflow.js +32 -0
- package/dist/operations/services/github-api.d.ts +115 -0
- package/dist/operations/services/github-api.js +455 -0
- package/dist/operations/services/github-automation.d.ts +19 -33
- package/dist/operations/services/github-automation.js +44 -131
- package/dist/operations/services/key-agent.d.ts +20 -1
- package/dist/operations/services/key-agent.js +267 -102
- package/dist/operations/services/knowledge-coop-launch.d.ts +2 -3
- package/dist/operations/services/knowledge-coop-launch.js +26 -12
- package/dist/operations/services/project-platform.d.ts +157 -150
- package/dist/operations/services/project-platform.js +129 -26
- package/dist/operations/services/railway-api.d.ts +244 -0
- package/dist/operations/services/railway-api.js +882 -0
- package/dist/operations/services/railway-deploy.d.ts +171 -27
- package/dist/operations/services/railway-deploy.js +672 -172
- package/dist/operations/services/runtime-tools.d.ts +18 -0
- package/dist/operations/services/runtime-tools.js +19 -6
- package/dist/operations/services/workspace-preflight.js +2 -2
- package/dist/platform/contracts.d.ts +7 -0
- package/dist/platform/deploy-config.js +23 -0
- package/dist/platform/deploy-runtime.d.ts +1 -0
- package/dist/platform/deploy-runtime.js +7 -9
- package/dist/platform/env.yaml +10 -9
- package/dist/platform/environment.js +4 -0
- package/dist/platform/plugin.d.ts +6 -0
- package/dist/platform/plugins/constants.d.ts +1 -0
- package/dist/platform/plugins/constants.js +1 -0
- package/dist/platform/plugins/runtime.d.ts +4 -0
- package/dist/platform/plugins/runtime.js +8 -1
- package/dist/platform/published-content.js +27 -4
- package/dist/platform/tenant/runtime-config.js +33 -24
- package/dist/plugin-default.d.ts +1 -0
- package/dist/plugin-default.js +1 -0
- package/dist/reconcile/builtin-adapters.d.ts +3 -0
- package/dist/reconcile/builtin-adapters.js +2093 -0
- package/dist/reconcile/contracts.d.ts +155 -0
- package/dist/reconcile/contracts.js +0 -0
- package/dist/reconcile/desired-state.d.ts +179 -0
- package/dist/reconcile/desired-state.js +319 -0
- package/dist/reconcile/engine.d.ts +405 -0
- package/dist/reconcile/engine.js +356 -0
- package/dist/reconcile/errors.d.ts +5 -0
- package/dist/reconcile/errors.js +13 -0
- package/dist/reconcile/index.d.ts +7 -0
- package/dist/reconcile/index.js +7 -0
- package/dist/reconcile/registry.d.ts +7 -0
- package/dist/reconcile/registry.js +64 -0
- package/dist/reconcile/state.d.ts +7 -0
- package/dist/reconcile/state.js +303 -0
- package/dist/reconcile/units.d.ts +6 -0
- package/dist/reconcile/units.js +68 -0
- package/dist/scripts/config-treeseed.js +27 -19
- package/dist/scripts/tenant-deploy.js +35 -14
- package/dist/workflow/operations.js +127 -22
- package/dist/workflow-support.d.ts +3 -1
- package/dist/workflow-support.js +50 -0
- package/dist/workflow.d.ts +2 -0
- package/package.json +7 -1
|
@@ -95,6 +95,7 @@ export declare function loadCliDeployConfig(tenantRoot: any): {
|
|
|
95
95
|
research: string;
|
|
96
96
|
};
|
|
97
97
|
deploy: string;
|
|
98
|
+
dns: string;
|
|
98
99
|
content: {
|
|
99
100
|
runtime: string;
|
|
100
101
|
publish: string;
|
|
@@ -110,6 +111,23 @@ export declare function loadCliDeployConfig(tenantRoot: any): {
|
|
|
110
111
|
rootDir: string | undefined;
|
|
111
112
|
publicBaseUrl: string | undefined;
|
|
112
113
|
localBaseUrl: string | undefined;
|
|
114
|
+
environments: {
|
|
115
|
+
local: {
|
|
116
|
+
baseUrl: string | undefined;
|
|
117
|
+
domain: string | undefined;
|
|
118
|
+
railwayEnvironment: string | undefined;
|
|
119
|
+
};
|
|
120
|
+
staging: {
|
|
121
|
+
baseUrl: string | undefined;
|
|
122
|
+
domain: string | undefined;
|
|
123
|
+
railwayEnvironment: string | undefined;
|
|
124
|
+
};
|
|
125
|
+
prod: {
|
|
126
|
+
baseUrl: string | undefined;
|
|
127
|
+
domain: string | undefined;
|
|
128
|
+
railwayEnvironment: string | undefined;
|
|
129
|
+
};
|
|
130
|
+
} | undefined;
|
|
113
131
|
cache: {
|
|
114
132
|
sourcePages: {
|
|
115
133
|
browserTtlSeconds: number | undefined;
|
|
@@ -45,6 +45,7 @@ const TREESEED_DEFAULT_PROVIDER_SELECTIONS = {
|
|
|
45
45
|
research: "project_graph"
|
|
46
46
|
},
|
|
47
47
|
deploy: "cloudflare",
|
|
48
|
+
dns: "cloudflare-dns",
|
|
48
49
|
content: {
|
|
49
50
|
runtime: "team_scoped_r2_overlay",
|
|
50
51
|
publish: "team_scoped_r2_overlay",
|
|
@@ -211,6 +212,17 @@ function parseSurfaceConfig(value, label) {
|
|
|
211
212
|
rootDir: optionalString(record.rootDir),
|
|
212
213
|
publicBaseUrl: optionalString(record.publicBaseUrl),
|
|
213
214
|
localBaseUrl: optionalString(record.localBaseUrl),
|
|
215
|
+
environments: (() => {
|
|
216
|
+
const environments = optionalRecord(record.environments, `${label}.environments`);
|
|
217
|
+
if (!environments) {
|
|
218
|
+
return void 0;
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
local: parseServiceEnvironmentConfig(environments.local),
|
|
222
|
+
staging: parseServiceEnvironmentConfig(environments.staging),
|
|
223
|
+
prod: parseServiceEnvironmentConfig(environments.prod)
|
|
224
|
+
};
|
|
225
|
+
})(),
|
|
214
226
|
cache: parseWebSurfaceCacheConfig(record.cache, `${label}.cache`)
|
|
215
227
|
};
|
|
216
228
|
}
|
|
@@ -453,9 +465,9 @@ function parseFallbackDeployConfig(configPath) {
|
|
|
453
465
|
"self_hosted_project"
|
|
454
466
|
]) ?? "self_hosted_project",
|
|
455
467
|
registration: optionalEnum(hosting.registration, "hosting.registration", ["optional", "none"]) ?? "none",
|
|
456
|
-
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL),
|
|
457
|
-
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID),
|
|
458
|
-
projectId: optionalString(process.env.TREESEED_PROJECT_ID)
|
|
468
|
+
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL) ?? optionalString(hosting.marketBaseUrl),
|
|
469
|
+
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID) ?? optionalString(hosting.teamId),
|
|
470
|
+
projectId: optionalString(process.env.TREESEED_PROJECT_ID) ?? optionalString(hosting.projectId)
|
|
459
471
|
};
|
|
460
472
|
const services = parseManagedServicesConfig(record.services);
|
|
461
473
|
const normalizedPlanes = normalizePlanesFromLegacyHosting(parsedHosting);
|
|
@@ -471,9 +483,9 @@ function parseFallbackDeployConfig(configPath) {
|
|
|
471
483
|
const runtime = {
|
|
472
484
|
mode: optionalEnum(runtimeRecord.mode, "runtime.mode", ["none", "byo_attached", "treeseed_managed"]) ?? inferredPlanes.runtime.mode,
|
|
473
485
|
registration: optionalEnum(runtimeRecord.registration, "runtime.registration", ["optional", "required", "none"]) ?? inferredPlanes.runtime.registration ?? "none",
|
|
474
|
-
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL) ?? inferredPlanes.runtime.marketBaseUrl,
|
|
475
|
-
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID) ?? inferredPlanes.runtime.teamId,
|
|
476
|
-
projectId: optionalString(process.env.TREESEED_PROJECT_ID) ?? inferredPlanes.runtime.projectId
|
|
486
|
+
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL) ?? optionalString(runtimeRecord.marketBaseUrl) ?? inferredPlanes.runtime.marketBaseUrl,
|
|
487
|
+
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID) ?? optionalString(runtimeRecord.teamId) ?? inferredPlanes.runtime.teamId,
|
|
488
|
+
projectId: optionalString(process.env.TREESEED_PROJECT_ID) ?? optionalString(runtimeRecord.projectId) ?? inferredPlanes.runtime.projectId
|
|
477
489
|
};
|
|
478
490
|
const smtp = optionalRecord(record.smtp, "smtp") ?? {};
|
|
479
491
|
const turnstile = optionalRecord(record.turnstile, "turnstile") ?? {};
|
|
@@ -523,6 +535,7 @@ function parseFallbackDeployConfig(configPath) {
|
|
|
523
535
|
research: expectString(agentProviders.research ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.agents.research, "providers.agents.research")
|
|
524
536
|
},
|
|
525
537
|
deploy: expectString(record.providers?.deploy ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.deploy, "providers.deploy"),
|
|
538
|
+
dns: expectString(record.providers?.dns ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.dns, "providers.dns"),
|
|
526
539
|
content: {
|
|
527
540
|
runtime: expectString(
|
|
528
541
|
contentProviders.runtime ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.runtime,
|
|
@@ -58,8 +58,8 @@ function parseWranglerWhoAmI(values = process.env) {
|
|
|
58
58
|
}
|
|
59
59
|
function parseRailwayWhoAmI(values = process.env) {
|
|
60
60
|
return {
|
|
61
|
-
authenticated: envTokenStatus(["RAILWAY_API_TOKEN"
|
|
62
|
-
detail: envTokenStatus(["RAILWAY_API_TOKEN"
|
|
61
|
+
authenticated: envTokenStatus(["RAILWAY_API_TOKEN"], "Railway", values).ready,
|
|
62
|
+
detail: envTokenStatus(["RAILWAY_API_TOKEN"], "Railway", values).detail
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
function parseCopilotSessionStatus(values = process.env) {
|
|
@@ -122,6 +122,7 @@ export interface TreeseedPlatformSurfaceConfig {
|
|
|
122
122
|
rootDir?: string;
|
|
123
123
|
publicBaseUrl?: string;
|
|
124
124
|
localBaseUrl?: string;
|
|
125
|
+
environments?: Partial<Record<'local' | 'staging' | 'prod', TreeseedManagedServiceEnvironmentConfig>>;
|
|
125
126
|
cache?: TreeseedWebSurfaceCacheConfig;
|
|
126
127
|
}
|
|
127
128
|
export interface TreeseedWebCachePolicyConfig {
|
|
@@ -192,6 +193,11 @@ export interface TreeseedManagedServiceRailwayConfig {
|
|
|
192
193
|
rootDir?: string;
|
|
193
194
|
buildCommand?: string;
|
|
194
195
|
startCommand?: string;
|
|
196
|
+
healthcheckPath?: string;
|
|
197
|
+
healthcheckTimeoutSeconds?: number;
|
|
198
|
+
healthcheckIntervalSeconds?: number;
|
|
199
|
+
restartPolicy?: string;
|
|
200
|
+
runtimeMode?: string;
|
|
195
201
|
schedule?: string | string[];
|
|
196
202
|
}
|
|
197
203
|
export interface TreeseedManagedServiceConfig {
|
|
@@ -224,6 +230,7 @@ export interface TreeseedProviderSelections {
|
|
|
224
230
|
research: string;
|
|
225
231
|
};
|
|
226
232
|
deploy: string;
|
|
233
|
+
dns?: string;
|
|
227
234
|
content?: {
|
|
228
235
|
runtime: string;
|
|
229
236
|
publish: string;
|
|
@@ -295,6 +295,7 @@ function parseProviderSelections(value) {
|
|
|
295
295
|
)
|
|
296
296
|
},
|
|
297
297
|
deploy: expectString(record.deploy ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.deploy, "providers.deploy"),
|
|
298
|
+
dns: expectString(record.dns ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.dns, "providers.dns"),
|
|
298
299
|
content: {
|
|
299
300
|
runtime: expectString(
|
|
300
301
|
contentProviders.runtime ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.runtime,
|
|
@@ -345,6 +346,17 @@ function parseManagedServiceConfig(value, label) {
|
|
|
345
346
|
rootDir: optionalString(railway.rootDir),
|
|
346
347
|
buildCommand: optionalString(railway.buildCommand),
|
|
347
348
|
startCommand: optionalString(railway.startCommand),
|
|
349
|
+
healthcheckPath: optionalString(railway.healthcheckPath),
|
|
350
|
+
healthcheckTimeoutSeconds: optionalPositiveNumber(
|
|
351
|
+
railway.healthcheckTimeoutSeconds,
|
|
352
|
+
`${label}.railway.healthcheckTimeoutSeconds`
|
|
353
|
+
),
|
|
354
|
+
healthcheckIntervalSeconds: optionalPositiveNumber(
|
|
355
|
+
railway.healthcheckIntervalSeconds,
|
|
356
|
+
`${label}.railway.healthcheckIntervalSeconds`
|
|
357
|
+
),
|
|
358
|
+
restartPolicy: optionalString(railway.restartPolicy),
|
|
359
|
+
runtimeMode: optionalString(railway.runtimeMode),
|
|
348
360
|
schedule: Array.isArray(railway.schedule) ? railway.schedule.map((entry) => optionalString(entry)).filter(Boolean) : optionalString(railway.schedule)
|
|
349
361
|
},
|
|
350
362
|
environments: {
|
|
@@ -382,6 +394,17 @@ function parsePlatformSurfaceConfig(value, label) {
|
|
|
382
394
|
rootDir: optionalString(record.rootDir),
|
|
383
395
|
publicBaseUrl: optionalString(record.publicBaseUrl),
|
|
384
396
|
localBaseUrl: optionalString(record.localBaseUrl),
|
|
397
|
+
environments: (() => {
|
|
398
|
+
const environments = optionalRecord(record.environments, `${label}.environments`);
|
|
399
|
+
if (!environments) {
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
local: parseServiceEnvironmentConfig(environments.local, `${label}.environments.local`),
|
|
404
|
+
staging: parseServiceEnvironmentConfig(environments.staging, `${label}.environments.staging`),
|
|
405
|
+
prod: parseServiceEnvironmentConfig(environments.prod, `${label}.environments.prod`)
|
|
406
|
+
};
|
|
407
|
+
})(),
|
|
385
408
|
cache: parseWebSurfaceCacheConfig(record.cache, `${label}.cache`)
|
|
386
409
|
};
|
|
387
410
|
}
|
|
@@ -12,6 +12,7 @@ export declare function getTreeseedAgentProviderSelections(): {
|
|
|
12
12
|
research: string;
|
|
13
13
|
};
|
|
14
14
|
export declare function getTreeseedDeployProvider(): string;
|
|
15
|
+
export declare function getTreeseedDnsProvider(): string;
|
|
15
16
|
export declare function getTreeseedContentRuntimeProvider(): string;
|
|
16
17
|
export declare function getTreeseedContentPublishProvider(): string;
|
|
17
18
|
export declare function getTreeseedContentServingMode(): string;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { loadTreeseedDeployConfig } from "./deploy-config.js";
|
|
2
1
|
import { TREESEED_DEFAULT_PLUGIN_REFERENCES, TREESEED_DEFAULT_PROVIDER_SELECTIONS } from "./plugins/constants.js";
|
|
3
2
|
let cachedDeployConfig = null;
|
|
4
3
|
function defaultDeployConfig() {
|
|
@@ -29,13 +28,8 @@ function getTreeseedDeployConfig() {
|
|
|
29
28
|
cachedDeployConfig = __TREESEED_DEPLOY_CONFIG__;
|
|
30
29
|
return cachedDeployConfig;
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return cachedDeployConfig;
|
|
35
|
-
} catch {
|
|
36
|
-
cachedDeployConfig = defaultDeployConfig();
|
|
37
|
-
return cachedDeployConfig;
|
|
38
|
-
}
|
|
31
|
+
cachedDeployConfig = defaultDeployConfig();
|
|
32
|
+
return cachedDeployConfig;
|
|
39
33
|
}
|
|
40
34
|
function resetTreeseedDeployConfigForTests() {
|
|
41
35
|
cachedDeployConfig = null;
|
|
@@ -52,6 +46,9 @@ function getTreeseedAgentProviderSelections() {
|
|
|
52
46
|
function getTreeseedDeployProvider() {
|
|
53
47
|
return getTreeseedDeployConfig().providers?.deploy ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.deploy;
|
|
54
48
|
}
|
|
49
|
+
function getTreeseedDnsProvider() {
|
|
50
|
+
return getTreeseedDeployConfig().providers?.dns ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.dns;
|
|
51
|
+
}
|
|
55
52
|
function getTreeseedContentRuntimeProvider() {
|
|
56
53
|
return getTreeseedDeployConfig().providers?.content?.runtime ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.runtime;
|
|
57
54
|
}
|
|
@@ -59,7 +56,7 @@ function getTreeseedContentPublishProvider() {
|
|
|
59
56
|
return getTreeseedDeployConfig().providers?.content?.publish ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.publish;
|
|
60
57
|
}
|
|
61
58
|
function getTreeseedContentServingMode() {
|
|
62
|
-
const override = process
|
|
59
|
+
const override = globalThis.process?.env?.TREESEED_CONTENT_SERVING_MODE?.trim();
|
|
63
60
|
if (override === "local_collections" || override === "published_runtime") {
|
|
64
61
|
return override;
|
|
65
62
|
}
|
|
@@ -84,6 +81,7 @@ export {
|
|
|
84
81
|
getTreeseedContentServingMode,
|
|
85
82
|
getTreeseedDeployConfig,
|
|
86
83
|
getTreeseedDeployProvider,
|
|
84
|
+
getTreeseedDnsProvider,
|
|
87
85
|
getTreeseedDocsProvider,
|
|
88
86
|
getTreeseedFormsProvider,
|
|
89
87
|
getTreeseedOperationsProvider,
|
package/dist/platform/env.yaml
CHANGED
|
@@ -76,32 +76,33 @@ entries:
|
|
|
76
76
|
- process-env
|
|
77
77
|
relevanceRef: railwayManagedEnabled
|
|
78
78
|
requiredWhenRef: railwayManagedEnabled
|
|
79
|
-
|
|
80
|
-
label: Railway
|
|
81
|
-
group:
|
|
82
|
-
description:
|
|
83
|
-
howToGet: In Railway,
|
|
84
|
-
sensitivity:
|
|
79
|
+
TREESEED_RAILWAY_WORKSPACE:
|
|
80
|
+
label: Railway workspace
|
|
81
|
+
group: railway
|
|
82
|
+
description: Railway workspace Treeseed should use when listing or creating projects during bootstrap and config reconciliation.
|
|
83
|
+
howToGet: In Railway, use the workspace slug or name shown in the workspace switcher. Treeseed defaults this repository to knowledge-coop unless you override it here.
|
|
84
|
+
sensitivity: plain
|
|
85
85
|
targets:
|
|
86
86
|
- local-runtime
|
|
87
|
-
- railway-
|
|
87
|
+
- railway-var
|
|
88
88
|
scopes:
|
|
89
89
|
- local
|
|
90
90
|
- staging
|
|
91
91
|
- prod
|
|
92
92
|
storage: shared
|
|
93
|
-
requirement:
|
|
93
|
+
requirement: conditional
|
|
94
94
|
purposes:
|
|
95
95
|
- deploy
|
|
96
96
|
- destroy
|
|
97
97
|
- config
|
|
98
98
|
validation:
|
|
99
99
|
kind: nonempty
|
|
100
|
-
minLength: 8
|
|
101
100
|
sourcePriority:
|
|
102
101
|
- machine-config
|
|
103
102
|
- process-env
|
|
103
|
+
defaultValueRef: railwayWorkspaceDefault
|
|
104
104
|
relevanceRef: railwayManagedEnabled
|
|
105
|
+
requiredWhenRef: railwayManagedEnabled
|
|
105
106
|
CLOUDFLARE_ACCOUNT_ID:
|
|
106
107
|
label: Cloudflare account ID
|
|
107
108
|
group: cloudflare
|
|
@@ -180,6 +180,9 @@ function resolveHostedTeamId(context) {
|
|
|
180
180
|
function resolveHostedProjectId(context) {
|
|
181
181
|
return context.deployConfig.slug;
|
|
182
182
|
}
|
|
183
|
+
function resolveRailwayWorkspaceDefault() {
|
|
184
|
+
return "knowledge-coop";
|
|
185
|
+
}
|
|
183
186
|
const VALUE_RESOLVERS = {
|
|
184
187
|
generatedSecret: () => generatedSecret(),
|
|
185
188
|
localFormsBypassDefault: () => "true",
|
|
@@ -202,6 +205,7 @@ const VALUE_RESOLVERS = {
|
|
|
202
205
|
marketBaseUrlDefault: (context) => resolveMarketBaseUrl(context),
|
|
203
206
|
hostingTeamIdDefault: (context) => resolveHostedTeamId(context),
|
|
204
207
|
hostingProjectIdDefault: (context) => resolveHostedProjectId(context),
|
|
208
|
+
railwayWorkspaceDefault: () => resolveRailwayWorkspaceDefault(),
|
|
205
209
|
agentPoolMinWorkersDefault: () => "0",
|
|
206
210
|
agentPoolMaxWorkersDefault: () => "2",
|
|
207
211
|
agentPoolTargetQueueDepthDefault: () => "1",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TreeseedDeployConfig, TreeseedPlatformLayerDefinition, TreeseedPlatformResourceKind, TreeseedPlatformSurfaceName, TreeseedTenantConfig } from './contracts.ts';
|
|
2
2
|
import type { TreeseedEnvironmentRegistryOverlay } from './environment.ts';
|
|
3
3
|
import type { SdkGraphRankingProvider } from '../sdk-types.ts';
|
|
4
|
+
import type { TreeseedReconcileAdapter } from '../reconcile/contracts.ts';
|
|
4
5
|
export type TreeseedSiteLayerDefinition = TreeseedPlatformLayerDefinition & {
|
|
5
6
|
kinds?: Array<'pages' | 'styles' | 'components'>;
|
|
6
7
|
};
|
|
@@ -68,6 +69,10 @@ export interface TreeseedPlugin {
|
|
|
68
69
|
id?: string;
|
|
69
70
|
provides?: Record<string, any> & {
|
|
70
71
|
operations?: string[];
|
|
72
|
+
dns?: string[];
|
|
73
|
+
reconcile?: {
|
|
74
|
+
providers?: string[];
|
|
75
|
+
};
|
|
71
76
|
};
|
|
72
77
|
operationProviders?: Record<string, unknown>;
|
|
73
78
|
siteProviders?: Record<string, TreeseedSiteExtensionContribution | ((context: TreeseedPluginSiteContext) => TreeseedSiteExtensionContribution)>;
|
|
@@ -82,6 +87,7 @@ export interface TreeseedPlugin {
|
|
|
82
87
|
platformHooks?: Partial<Record<TreeseedPlatformSurfaceName, TreeseedPlatformExtensionContribution>> | ((context: TreeseedPluginPlatformContext) => TreeseedPlatformExtensionContribution | undefined);
|
|
83
88
|
platformLayers?: TreeseedPlatformLayerContribution[] | ((context: TreeseedPluginPlatformContext) => TreeseedPlatformLayerContribution[] | undefined);
|
|
84
89
|
environmentRegistry?: TreeseedEnvironmentRegistryOverlay | ((context: TreeseedPluginEnvironmentContext) => TreeseedEnvironmentRegistryOverlay | undefined);
|
|
90
|
+
reconcileAdapters?: Record<string, TreeseedReconcileAdapter | ((context: TreeseedPluginEnvironmentContext) => TreeseedReconcileAdapter | undefined)> | ((context: TreeseedPluginEnvironmentContext) => Record<string, TreeseedReconcileAdapter | ((context: TreeseedPluginEnvironmentContext) => TreeseedReconcileAdapter | undefined)> | undefined);
|
|
85
91
|
graphRankingProviders?: Record<string, TreeseedGraphRankingProviderContribution>;
|
|
86
92
|
[key: string]: unknown;
|
|
87
93
|
}
|
|
@@ -25,12 +25,16 @@ export declare function loadTreeseedPluginRuntime(config?: TreeseedDeployConfig)
|
|
|
25
25
|
handlers: Set<string>;
|
|
26
26
|
};
|
|
27
27
|
deploy: Set<string>;
|
|
28
|
+
dns: Set<string>;
|
|
28
29
|
content: {
|
|
29
30
|
runtime: Set<string>;
|
|
30
31
|
publish: Set<string>;
|
|
31
32
|
docs: Set<string>;
|
|
32
33
|
};
|
|
33
34
|
site: Set<string>;
|
|
35
|
+
reconcile: {
|
|
36
|
+
providers: Set<string>;
|
|
37
|
+
};
|
|
34
38
|
};
|
|
35
39
|
};
|
|
36
40
|
export declare function resolveTreeseedGraphRankingProvider(plugins: LoadedPluginEntry[], context: Omit<TreeseedPluginEnvironmentContext, 'pluginConfig'>): SdkGraphRankingProvider | null;
|
|
@@ -106,12 +106,16 @@ function collectProvidedIds(plugins) {
|
|
|
106
106
|
handlers: /* @__PURE__ */ new Set()
|
|
107
107
|
},
|
|
108
108
|
deploy: /* @__PURE__ */ new Set(),
|
|
109
|
+
dns: /* @__PURE__ */ new Set(),
|
|
109
110
|
content: {
|
|
110
111
|
runtime: /* @__PURE__ */ new Set(),
|
|
111
112
|
publish: /* @__PURE__ */ new Set(),
|
|
112
113
|
docs: /* @__PURE__ */ new Set()
|
|
113
114
|
},
|
|
114
|
-
site: /* @__PURE__ */ new Set()
|
|
115
|
+
site: /* @__PURE__ */ new Set(),
|
|
116
|
+
reconcile: {
|
|
117
|
+
providers: /* @__PURE__ */ new Set()
|
|
118
|
+
}
|
|
115
119
|
};
|
|
116
120
|
for (const { plugin } of plugins) {
|
|
117
121
|
for (const id of plugin.provides?.forms ?? []) provided.forms.add(id);
|
|
@@ -124,10 +128,12 @@ function collectProvidedIds(plugins) {
|
|
|
124
128
|
for (const id of plugin.provides?.agents?.research ?? []) provided.agents.research.add(id);
|
|
125
129
|
for (const id of plugin.provides?.agents?.handlers ?? []) provided.agents.handlers.add(id);
|
|
126
130
|
for (const id of plugin.provides?.deploy ?? []) provided.deploy.add(id);
|
|
131
|
+
for (const id of plugin.provides?.dns ?? []) provided.dns.add(id);
|
|
127
132
|
for (const id of plugin.provides?.content?.runtime ?? []) provided.content.runtime.add(id);
|
|
128
133
|
for (const id of plugin.provides?.content?.publish ?? []) provided.content.publish.add(id);
|
|
129
134
|
for (const id of plugin.provides?.content?.docs ?? []) provided.content.docs.add(id);
|
|
130
135
|
for (const id of plugin.provides?.site ?? []) provided.site.add(id);
|
|
136
|
+
for (const id of plugin.provides?.reconcile?.providers ?? []) provided.reconcile.providers.add(id);
|
|
131
137
|
}
|
|
132
138
|
return provided;
|
|
133
139
|
}
|
|
@@ -152,6 +158,7 @@ function loadTreeseedPluginRuntime(config = loadTreeseedDeployConfig()) {
|
|
|
152
158
|
assertSelectedProvider(provided.agents.notification, "agents.notification", providers.agents.notification);
|
|
153
159
|
assertSelectedProvider(provided.agents.research, "agents.research", providers.agents.research);
|
|
154
160
|
assertSelectedProvider(provided.deploy, "deploy", providers.deploy);
|
|
161
|
+
assertSelectedProvider(provided.dns, "dns", providers.dns ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.dns);
|
|
155
162
|
assertSelectedProvider(provided.content.runtime, "content.runtime", providers.content?.runtime);
|
|
156
163
|
assertSelectedProvider(provided.content.publish, "content.publish", providers.content?.publish);
|
|
157
164
|
if (providers.content?.docs) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createHash, createHmac } from "node:crypto";
|
|
2
1
|
const PUBLISHED_CONTENT_MANIFEST_SCHEMA_VERSION = 2;
|
|
3
2
|
const EDITORIAL_PREVIEW_COOKIE = "treeseed-content-preview";
|
|
4
3
|
function isRecord(value) {
|
|
@@ -25,8 +24,27 @@ function optionalNumber(value) {
|
|
|
25
24
|
function optionalBoolean(value) {
|
|
26
25
|
return typeof value === "boolean" ? value : void 0;
|
|
27
26
|
}
|
|
27
|
+
function getNodeCrypto() {
|
|
28
|
+
return globalThis.process?.getBuiltinModule?.("crypto") ?? null;
|
|
29
|
+
}
|
|
28
30
|
function stableHash(value) {
|
|
29
|
-
|
|
31
|
+
const crypto = getNodeCrypto();
|
|
32
|
+
if (crypto?.createHash) {
|
|
33
|
+
return crypto.createHash("sha256").update(value).digest("hex");
|
|
34
|
+
}
|
|
35
|
+
let hash = 2166136261;
|
|
36
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
37
|
+
hash ^= value.charCodeAt(index);
|
|
38
|
+
hash = Math.imul(hash, 16777619);
|
|
39
|
+
}
|
|
40
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
41
|
+
}
|
|
42
|
+
function hmacSha256Base64Url(value, secret) {
|
|
43
|
+
const crypto = getNodeCrypto();
|
|
44
|
+
if (!crypto?.createHmac) {
|
|
45
|
+
throw new Error("Editorial preview token signing requires a crypto runtime.");
|
|
46
|
+
}
|
|
47
|
+
return crypto.createHmac("sha256", secret).update(value).digest("base64url");
|
|
30
48
|
}
|
|
31
49
|
function base64UrlEncode(value) {
|
|
32
50
|
return Buffer.from(value, "utf8").toString("base64url");
|
|
@@ -223,7 +241,7 @@ function signEditorialPreviewToken(payload, secret) {
|
|
|
223
241
|
expiresAt: expectString(payload.expiresAt, "previewToken.expiresAt")
|
|
224
242
|
};
|
|
225
243
|
const encodedPayload = base64UrlEncode(JSON.stringify(normalized));
|
|
226
|
-
const signature =
|
|
244
|
+
const signature = hmacSha256Base64Url(encodedPayload, secret);
|
|
227
245
|
return `${encodedPayload}.${signature}`;
|
|
228
246
|
}
|
|
229
247
|
function verifyEditorialPreviewToken(token, secret) {
|
|
@@ -231,7 +249,12 @@ function verifyEditorialPreviewToken(token, secret) {
|
|
|
231
249
|
if (!encodedPayload || !signature) {
|
|
232
250
|
return null;
|
|
233
251
|
}
|
|
234
|
-
|
|
252
|
+
let expected;
|
|
253
|
+
try {
|
|
254
|
+
expected = hmacSha256Base64Url(encodedPayload, secret);
|
|
255
|
+
} catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
235
258
|
if (expected !== signature) {
|
|
236
259
|
return null;
|
|
237
260
|
}
|
|
@@ -1,28 +1,37 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
import { loadTreeseedManifest } from "../tenant-config.js";
|
|
4
1
|
import { parseSiteConfig } from "../utils/site-config-schema.js";
|
|
5
2
|
const injectedTenantConfig = typeof __TREESEED_TENANT_CONFIG__ !== "undefined" ? __TREESEED_TENANT_CONFIG__ : null;
|
|
6
3
|
const injectedProjectRoot = typeof __TREESEED_PROJECT_ROOT__ !== "undefined" ? __TREESEED_PROJECT_ROOT__ : null;
|
|
7
4
|
const injectedSiteConfig = typeof __TREESEED_SITE_CONFIG__ !== "undefined" ? __TREESEED_SITE_CONFIG__ : null;
|
|
5
|
+
function getNodeBuiltin(name) {
|
|
6
|
+
const getBuiltinModule = globalThis.process?.getBuiltinModule;
|
|
7
|
+
return getBuiltinModule?.(name) ?? null;
|
|
8
|
+
}
|
|
9
|
+
function getCwd() {
|
|
10
|
+
const cwd = globalThis.process?.cwd;
|
|
11
|
+
return cwd?.() ?? ".";
|
|
12
|
+
}
|
|
13
|
+
function resolveRuntimePath(projectRoot, path) {
|
|
14
|
+
const pathModule = getNodeBuiltin("path");
|
|
15
|
+
return pathModule?.resolve(projectRoot, path) ?? `${projectRoot.replace(/\/$/, "")}/${path}`;
|
|
16
|
+
}
|
|
8
17
|
function fallbackTenantConfig(projectRoot) {
|
|
9
18
|
return {
|
|
10
19
|
id: "treeseed-runtime",
|
|
11
|
-
siteConfigPath:
|
|
20
|
+
siteConfigPath: resolveRuntimePath(projectRoot, "treeseed.site.yaml"),
|
|
12
21
|
content: {
|
|
13
|
-
pages:
|
|
14
|
-
notes:
|
|
15
|
-
questions:
|
|
16
|
-
objectives:
|
|
17
|
-
proposals:
|
|
18
|
-
decisions:
|
|
19
|
-
people:
|
|
20
|
-
agents:
|
|
21
|
-
books:
|
|
22
|
-
docs:
|
|
23
|
-
templates:
|
|
24
|
-
knowledge_packs:
|
|
25
|
-
workdays:
|
|
22
|
+
pages: resolveRuntimePath(projectRoot, "src/content/pages"),
|
|
23
|
+
notes: resolveRuntimePath(projectRoot, "src/content/notes"),
|
|
24
|
+
questions: resolveRuntimePath(projectRoot, "src/content/questions"),
|
|
25
|
+
objectives: resolveRuntimePath(projectRoot, "src/content/objectives"),
|
|
26
|
+
proposals: resolveRuntimePath(projectRoot, "src/content/proposals"),
|
|
27
|
+
decisions: resolveRuntimePath(projectRoot, "src/content/decisions"),
|
|
28
|
+
people: resolveRuntimePath(projectRoot, "src/content/people"),
|
|
29
|
+
agents: resolveRuntimePath(projectRoot, "src/content/agents"),
|
|
30
|
+
books: resolveRuntimePath(projectRoot, "src/content/books"),
|
|
31
|
+
docs: resolveRuntimePath(projectRoot, "src/content/knowledge"),
|
|
32
|
+
templates: resolveRuntimePath(projectRoot, "src/content/templates"),
|
|
33
|
+
knowledge_packs: resolveRuntimePath(projectRoot, "src/content/knowledge-packs"),
|
|
34
|
+
workdays: resolveRuntimePath(projectRoot, "src/content/workdays")
|
|
26
35
|
},
|
|
27
36
|
features: {
|
|
28
37
|
docs: true,
|
|
@@ -35,20 +44,20 @@ function fallbackTenantConfig(projectRoot) {
|
|
|
35
44
|
}
|
|
36
45
|
};
|
|
37
46
|
}
|
|
38
|
-
const RUNTIME_PROJECT_ROOT = injectedProjectRoot ??
|
|
47
|
+
const RUNTIME_PROJECT_ROOT = injectedProjectRoot ?? getCwd();
|
|
39
48
|
const RUNTIME_TENANT = (() => {
|
|
40
49
|
if (injectedTenantConfig) {
|
|
41
50
|
return injectedTenantConfig;
|
|
42
51
|
}
|
|
43
|
-
|
|
44
|
-
return loadTreeseedManifest();
|
|
45
|
-
} catch {
|
|
46
|
-
return fallbackTenantConfig(RUNTIME_PROJECT_ROOT);
|
|
47
|
-
}
|
|
52
|
+
return fallbackTenantConfig(RUNTIME_PROJECT_ROOT);
|
|
48
53
|
})();
|
|
49
54
|
const RUNTIME_SITE_CONFIG = injectedSiteConfig ?? (() => {
|
|
55
|
+
const fs = getNodeBuiltin("fs");
|
|
56
|
+
if (!fs) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
50
59
|
try {
|
|
51
|
-
return parseSiteConfig(readFileSync(RUNTIME_TENANT.siteConfigPath, "utf8"));
|
|
60
|
+
return parseSiteConfig(fs.readFileSync(RUNTIME_TENANT.siteConfigPath, "utf8"));
|
|
52
61
|
} catch {
|
|
53
62
|
return null;
|
|
54
63
|
}
|
package/dist/plugin-default.d.ts
CHANGED
package/dist/plugin-default.js
CHANGED