@treeseed/sdk 0.1.2 → 0.3.1
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/README.md +97 -506
- package/dist/{src/cli-tools.d.ts → cli-tools.d.ts} +1 -1
- package/dist/cli-tools.js +5 -3
- package/dist/{src/content-store.d.ts → content-store.d.ts} +3 -2
- package/dist/content-store.js +52 -20
- package/dist/{src/d1-store.d.ts → d1-store.d.ts} +62 -1
- package/dist/d1-store.js +625 -65
- package/dist/field-aliases.d.ts +11 -0
- package/dist/field-aliases.js +41 -0
- package/dist/graph/build.d.ts +19 -0
- package/dist/graph/build.js +949 -0
- package/dist/graph/dsl.d.ts +2 -0
- package/dist/graph/dsl.js +243 -0
- package/dist/graph/query.d.ts +47 -0
- package/dist/graph/query.js +447 -0
- package/dist/graph/ranking.d.ts +3 -0
- package/dist/graph/ranking.js +483 -0
- package/dist/graph/schema.d.ts +142 -0
- package/dist/graph/schema.js +133 -0
- package/dist/graph.d.ts +52 -0
- package/dist/graph.js +133 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +91 -2
- package/dist/model-registry.d.ts +8 -0
- package/dist/model-registry.js +351 -25
- package/dist/operations/providers/default.d.ts +10 -0
- package/dist/operations/providers/default.js +514 -0
- package/dist/operations/runtime.d.ts +7 -0
- package/dist/operations/runtime.js +60 -0
- package/dist/operations/services/config-runtime.d.ts +269 -0
- package/dist/operations/services/config-runtime.js +1397 -0
- package/dist/operations/services/d1-migration.d.ts +6 -0
- package/dist/operations/services/d1-migration.js +89 -0
- package/dist/operations/services/deploy.d.ts +371 -0
- package/dist/operations/services/deploy.js +981 -0
- package/dist/operations/services/git-workflow.d.ts +49 -0
- package/dist/operations/services/git-workflow.js +218 -0
- package/dist/operations/services/github-automation.d.ts +156 -0
- package/dist/operations/services/github-automation.js +256 -0
- package/dist/operations/services/local-dev.d.ts +9 -0
- package/dist/operations/services/local-dev.js +106 -0
- package/dist/operations/services/mailpit-runtime.d.ts +4 -0
- package/dist/operations/services/mailpit-runtime.js +59 -0
- package/dist/operations/services/railway-deploy.d.ts +53 -0
- package/dist/operations/services/railway-deploy.js +123 -0
- package/dist/operations/services/runtime-paths.d.ts +19 -0
- package/dist/operations/services/runtime-paths.js +54 -0
- package/dist/operations/services/runtime-tools.d.ts +117 -0
- package/dist/operations/services/runtime-tools.js +358 -0
- package/dist/operations/services/save-deploy-preflight.d.ts +34 -0
- package/dist/operations/services/save-deploy-preflight.js +76 -0
- package/dist/operations/services/template-registry.d.ts +88 -0
- package/dist/operations/services/template-registry.js +407 -0
- package/dist/operations/services/watch-dev.d.ts +21 -0
- package/dist/operations/services/watch-dev.js +284 -0
- package/dist/operations/services/workspace-preflight.d.ts +40 -0
- package/dist/operations/services/workspace-preflight.js +165 -0
- package/dist/operations/services/workspace-save.d.ts +42 -0
- package/dist/operations/services/workspace-save.js +235 -0
- package/dist/operations/services/workspace-tools.d.ts +16 -0
- package/dist/operations/services/workspace-tools.js +270 -0
- package/dist/operations-registry.d.ts +5 -0
- package/dist/operations-registry.js +68 -0
- package/dist/operations-types.d.ts +71 -0
- package/dist/operations-types.js +17 -0
- package/dist/operations.d.ts +6 -0
- package/dist/operations.js +16 -0
- package/dist/platform/books-data.d.ts +1 -0
- package/dist/platform/books-data.js +1 -0
- package/dist/platform/contracts.d.ts +158 -0
- package/dist/platform/contracts.js +0 -0
- package/dist/platform/deploy/config.d.ts +4 -0
- package/dist/platform/deploy/config.js +222 -0
- package/dist/platform/deploy-config.d.ts +1 -0
- package/dist/platform/deploy-config.js +1 -0
- package/dist/platform/deploy-runtime.d.ts +18 -0
- package/dist/platform/deploy-runtime.js +78 -0
- package/dist/platform/env.yaml +394 -0
- package/dist/platform/environment.d.ts +130 -0
- package/dist/platform/environment.js +331 -0
- package/dist/platform/plugin.d.ts +2 -0
- package/dist/platform/plugin.js +4 -0
- package/dist/platform/plugins/constants.d.ts +22 -0
- package/dist/platform/plugins/constants.js +29 -0
- package/dist/platform/plugins/plugin.d.ts +51 -0
- package/dist/platform/plugins/plugin.js +6 -0
- package/dist/platform/plugins/runtime.d.ts +35 -0
- package/dist/platform/plugins/runtime.js +161 -0
- package/dist/platform/plugins.d.ts +6 -0
- package/dist/platform/plugins.js +38 -0
- package/dist/platform/site-config-schema.js +1 -0
- package/dist/platform/tenant/config.d.ts +9 -0
- package/dist/platform/tenant/config.js +154 -0
- package/dist/platform/tenant/runtime-config.d.ts +4 -0
- package/dist/platform/tenant/runtime-config.js +20 -0
- package/dist/platform/tenant-config.d.ts +1 -0
- package/dist/platform/tenant-config.js +1 -0
- package/dist/platform/utils/books-data.d.ts +29 -0
- package/dist/platform/utils/books-data.js +82 -0
- package/dist/platform/utils/site-config-schema.js +321 -0
- package/dist/remote.d.ts +175 -0
- package/dist/remote.js +202 -0
- package/dist/runtime.js +35 -22
- package/dist/scripts/aggregate-book.js +121 -0
- package/dist/scripts/build-dist.js +54 -13
- package/dist/scripts/build-tenant-worker.js +36 -0
- package/dist/scripts/cleanup-markdown.js +373 -0
- package/dist/scripts/cli-test-fixtures.js +48 -0
- package/dist/scripts/config-treeseed.js +95 -0
- package/dist/scripts/ensure-mailpit.js +29 -0
- package/dist/scripts/local-dev.js +129 -0
- package/dist/scripts/logs-mailpit.js +2 -0
- package/dist/scripts/patch-starlight-content-path.js +172 -0
- package/dist/scripts/release-verify.js +34 -6
- package/dist/scripts/run-fixture-astro-command.js +18 -0
- package/dist/scripts/scaffold-site.js +65 -0
- package/dist/scripts/stop-mailpit.js +5 -0
- package/dist/scripts/sync-dev-vars.js +6 -0
- package/dist/scripts/sync-template.js +20 -0
- package/dist/scripts/template-catalog.test.js +100 -0
- package/dist/scripts/template-command.js +31 -0
- package/dist/scripts/tenant-astro-command.js +3 -0
- package/dist/scripts/tenant-build.js +16 -0
- package/dist/scripts/tenant-check.js +7 -0
- package/dist/scripts/tenant-d1-migrate-local.js +11 -0
- package/dist/scripts/tenant-deploy.js +180 -0
- package/dist/scripts/tenant-destroy.js +104 -0
- package/dist/scripts/tenant-dev.js +171 -0
- package/dist/scripts/tenant-lint.js +4 -0
- package/dist/scripts/tenant-test.js +4 -0
- package/dist/scripts/test-cloudflare-local.js +212 -0
- package/dist/scripts/test-scaffold.js +314 -0
- package/dist/scripts/test-smoke.js +71 -13
- package/dist/scripts/treeseed-assert-release-tag-version.js +21 -0
- package/dist/scripts/treeseed-build-dist.js +134 -0
- package/dist/scripts/treeseed-publish-package.js +19 -0
- package/dist/scripts/treeseed-release-verify.js +131 -0
- package/dist/scripts/treeseed-run-ts.js +45 -0
- package/dist/scripts/validate-templates.js +6 -0
- package/dist/scripts/verify-driver.js +29 -0
- package/dist/scripts/workflow-commands.test.js +39 -0
- package/dist/scripts/workspace-close.js +24 -0
- package/dist/scripts/workspace-command-e2e.js +718 -0
- package/dist/scripts/workspace-lint.js +9 -0
- package/dist/scripts/workspace-preflight.js +22 -0
- package/dist/scripts/workspace-publish-changed-packages.js +16 -0
- package/dist/scripts/workspace-release-verify.js +81 -0
- package/dist/scripts/workspace-release.js +42 -0
- package/dist/scripts/workspace-save.js +124 -0
- package/dist/scripts/workspace-start-warning.js +3 -0
- package/dist/scripts/workspace-start.js +71 -0
- package/dist/scripts/workspace-test-unit.js +4 -0
- package/dist/scripts/workspace-test.js +11 -0
- package/dist/sdk-fields.d.ts +11 -0
- package/dist/sdk-fields.js +169 -0
- package/dist/sdk-filters.d.ts +4 -0
- package/dist/sdk-filters.js +12 -15
- package/dist/sdk-types.d.ts +796 -0
- package/dist/sdk-types.js +7 -1
- package/dist/sdk-version.d.ts +2 -0
- package/dist/sdk-version.js +42 -0
- package/dist/sdk.d.ts +215 -0
- package/dist/sdk.js +235 -11
- package/dist/stores/cursor-store.js +9 -3
- package/dist/stores/lease-store.js +8 -2
- package/dist/{src/stores → stores}/message-store.d.ts +1 -1
- package/dist/stores/message-store.js +27 -3
- package/dist/stores/operational-store.d.ts +24 -0
- package/dist/stores/operational-store.js +279 -0
- package/dist/stores/run-store.js +8 -1
- package/dist/stores/subscription-store.js +7 -5
- package/dist/template-catalog.d.ts +13 -0
- package/dist/template-catalog.js +141 -0
- package/dist/treeseed/services/compose.yml +7 -0
- package/dist/treeseed/template-catalog/catalog.fixture.json +55 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.d.ts +2 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.ts +3 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +32 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +40 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/empty/.gitkeep +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/knowledge/handbook/index.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/pages/welcome.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.d.ts +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.ts +3 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/env.yaml +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +19 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +26 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/tsconfig.json +9 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +90 -0
- package/dist/utils/agents/contracts/messages.d.ts +88 -0
- package/dist/utils/agents/contracts/messages.js +138 -0
- package/dist/utils/agents/contracts/run.d.ts +20 -0
- package/dist/utils/agents/contracts/run.js +0 -0
- package/dist/utils/agents/runtime-types.d.ts +117 -0
- package/dist/utils/agents/runtime-types.js +4 -0
- package/dist/verification.d.ts +20 -0
- package/dist/verification.js +98 -0
- package/dist/workflow/operations.d.ts +396 -0
- package/dist/workflow/operations.js +841 -0
- package/dist/workflow-state.d.ts +56 -0
- package/dist/workflow-state.js +195 -0
- package/dist/workflow-support.d.ts +9 -0
- package/dist/workflow-support.js +176 -0
- package/dist/workflow.d.ts +111 -0
- package/dist/workflow.js +97 -0
- package/package.json +111 -5
- package/scripts/verify-driver.mjs +29 -0
- package/dist/scripts/.ts-run-1775630384291-crtqr3izsa.js +0 -22
- package/dist/scripts/.ts-run-1775630388025-vnjle0z75a.js +0 -129
- package/dist/scripts/assert-release-tag-version.d.ts +0 -1
- package/dist/scripts/build-dist.d.ts +0 -1
- package/dist/scripts/fixture-tools.d.ts +0 -5
- package/dist/scripts/package-tools.d.ts +0 -15
- package/dist/scripts/publish-package.d.ts +0 -1
- package/dist/scripts/release-verify.d.ts +0 -1
- package/dist/scripts/test-smoke.d.ts +0 -1
- package/dist/src/index.d.ts +0 -6
- package/dist/src/model-registry.d.ts +0 -4
- package/dist/src/sdk-filters.d.ts +0 -4
- package/dist/src/sdk-types.d.ts +0 -285
- package/dist/src/sdk.d.ts +0 -109
- package/dist/test/test-fixture.d.ts +0 -1
- package/dist/test/utils/envelopes.test.d.ts +0 -1
- package/dist/test/utils/sdk.test.d.ts +0 -1
- package/dist/vitest.config.d.ts +0 -2
- /package/dist/{src/frontmatter.d.ts → frontmatter.d.ts} +0 -0
- /package/dist/{src/git-runtime.d.ts → git-runtime.d.ts} +0 -0
- /package/dist/{src/runtime.d.ts → runtime.d.ts} +0 -0
- /package/dist/{src/stores → stores}/cursor-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/envelopes.d.ts +0 -0
- /package/dist/{src/stores → stores}/helpers.d.ts +0 -0
- /package/dist/{src/stores → stores}/lease-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/run-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/subscription-store.d.ts +0 -0
- /package/dist/{src/types → types}/agents.d.ts +0 -0
- /package/dist/{src/types → types}/cloudflare.d.ts +0 -0
- /package/dist/{src/wrangler-d1.d.ts → wrangler-d1.d.ts} +0 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { parse as parseYaml } from "yaml";
|
|
6
|
+
import { loadTreeseedDeployConfig } from "./deploy/config.js";
|
|
7
|
+
import { loadTreeseedPlugins } from "./plugins/runtime.js";
|
|
8
|
+
import { loadTreeseedManifest } from "./tenant/config.js";
|
|
9
|
+
const TREESEED_ENVIRONMENT_SCOPES = ["local", "staging", "prod"];
|
|
10
|
+
const TREESEED_ENVIRONMENT_REQUIREMENTS = ["required", "conditional", "optional"];
|
|
11
|
+
const TREESEED_ENVIRONMENT_TARGETS = [
|
|
12
|
+
"local-file",
|
|
13
|
+
"wrangler-dev-vars",
|
|
14
|
+
"github-secret",
|
|
15
|
+
"github-variable",
|
|
16
|
+
"cloudflare-secret",
|
|
17
|
+
"cloudflare-var",
|
|
18
|
+
"railway-secret",
|
|
19
|
+
"config-file"
|
|
20
|
+
];
|
|
21
|
+
const TREESEED_ENVIRONMENT_PURPOSES = ["dev", "save", "deploy", "destroy", "config"];
|
|
22
|
+
const TREESEED_ENVIRONMENT_SENSITIVITY = ["secret", "plain", "derived"];
|
|
23
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const CORE_ENVIRONMENT_PATH = resolve(moduleDir, "env.yaml");
|
|
25
|
+
const TENANT_ENVIRONMENT_OVERLAY_PATH = "src/env.yaml";
|
|
26
|
+
function loadOptionalTenantConfig() {
|
|
27
|
+
try {
|
|
28
|
+
return loadTreeseedManifest();
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function turnstileEnabled(context) {
|
|
34
|
+
return context.deployConfig.turnstile?.enabled !== false;
|
|
35
|
+
}
|
|
36
|
+
function smtpEnabled(context) {
|
|
37
|
+
return context.deployConfig.smtp?.enabled === true;
|
|
38
|
+
}
|
|
39
|
+
function railwayManagedEnabled(context) {
|
|
40
|
+
return Object.values(context.deployConfig.services ?? {}).some(
|
|
41
|
+
(service) => service && service.enabled !== false && (service.provider ?? "railway") === "railway"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
function generatedSecret(bytes = 24) {
|
|
45
|
+
return randomBytes(bytes).toString("hex");
|
|
46
|
+
}
|
|
47
|
+
const VALUE_RESOLVERS = {
|
|
48
|
+
generatedSecret: () => generatedSecret(),
|
|
49
|
+
localFormsBypassDefault: () => "true"
|
|
50
|
+
};
|
|
51
|
+
const PREDICATES = {
|
|
52
|
+
turnstileEnabled: (context) => turnstileEnabled(context),
|
|
53
|
+
turnstileNonLocal: (context, scope) => turnstileEnabled(context) && scope !== "local",
|
|
54
|
+
smtpEnabled: (context) => smtpEnabled(context),
|
|
55
|
+
smtpNonLocal: (context, scope) => smtpEnabled(context) && scope !== "local",
|
|
56
|
+
railwayManagedEnabled: (context) => railwayManagedEnabled(context)
|
|
57
|
+
};
|
|
58
|
+
function deepMerge(left, right) {
|
|
59
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
60
|
+
return [...right];
|
|
61
|
+
}
|
|
62
|
+
if (left && typeof left === "object" && !Array.isArray(left) && right && typeof right === "object" && !Array.isArray(right)) {
|
|
63
|
+
const result = { ...left };
|
|
64
|
+
for (const [key, value] of Object.entries(right)) {
|
|
65
|
+
result[key] = key in result ? deepMerge(result[key], value) : value;
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
return right;
|
|
70
|
+
}
|
|
71
|
+
function normalizeOverlay(raw, label) {
|
|
72
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
73
|
+
throw new Error(`Invalid Treeseed environment registry overlay from ${label}.`);
|
|
74
|
+
}
|
|
75
|
+
const overlay = raw;
|
|
76
|
+
if (overlay.entries === void 0) {
|
|
77
|
+
return { entries: {} };
|
|
78
|
+
}
|
|
79
|
+
if (!overlay.entries || typeof overlay.entries !== "object" || Array.isArray(overlay.entries)) {
|
|
80
|
+
throw new Error(`Invalid Treeseed environment registry overlay entries in ${label}.`);
|
|
81
|
+
}
|
|
82
|
+
return overlay;
|
|
83
|
+
}
|
|
84
|
+
function readYamlOverlayIfPresent(filePath) {
|
|
85
|
+
if (!existsSync(filePath)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return normalizeOverlay(parseYaml(readFileSync(filePath, "utf8")), filePath);
|
|
89
|
+
}
|
|
90
|
+
function pluginEnvironmentCandidates(baseDir) {
|
|
91
|
+
const dir = resolve(baseDir);
|
|
92
|
+
return [
|
|
93
|
+
resolve(dir, "env.yaml"),
|
|
94
|
+
resolve(dir, "src/env.yaml"),
|
|
95
|
+
resolve(dir, "../env.yaml"),
|
|
96
|
+
resolve(dir, "../src/env.yaml"),
|
|
97
|
+
resolve(dir, "../../env.yaml"),
|
|
98
|
+
resolve(dir, "../../src/env.yaml")
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
function readPluginEnvironmentOverlay(baseDir) {
|
|
102
|
+
for (const candidate of pluginEnvironmentCandidates(baseDir)) {
|
|
103
|
+
const overlay = readYamlOverlayIfPresent(candidate);
|
|
104
|
+
if (overlay) {
|
|
105
|
+
return { path: candidate, overlay };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
function loadTreeseedEnvironmentOverlay(tenantRoot) {
|
|
111
|
+
const overlayPath = resolve(tenantRoot, TENANT_ENVIRONMENT_OVERLAY_PATH);
|
|
112
|
+
return {
|
|
113
|
+
path: overlayPath,
|
|
114
|
+
overlay: readYamlOverlayIfPresent(overlayPath) ?? { entries: {} }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function resolveNamedValueResolver(ref) {
|
|
118
|
+
if (!ref) return void 0;
|
|
119
|
+
const resolver = VALUE_RESOLVERS[ref];
|
|
120
|
+
if (!resolver) {
|
|
121
|
+
throw new Error(`Unknown Treeseed environment value resolver "${ref}".`);
|
|
122
|
+
}
|
|
123
|
+
return resolver;
|
|
124
|
+
}
|
|
125
|
+
function resolveNamedPredicate(ref) {
|
|
126
|
+
if (!ref) return void 0;
|
|
127
|
+
const predicate = PREDICATES[ref];
|
|
128
|
+
if (!predicate) {
|
|
129
|
+
throw new Error(`Unknown Treeseed environment predicate "${ref}".`);
|
|
130
|
+
}
|
|
131
|
+
return predicate;
|
|
132
|
+
}
|
|
133
|
+
function materializeEntry(id, entry) {
|
|
134
|
+
return {
|
|
135
|
+
...entry,
|
|
136
|
+
id,
|
|
137
|
+
defaultValue: resolveNamedValueResolver(entry.defaultValueRef),
|
|
138
|
+
localDefaultValue: resolveNamedValueResolver(entry.localDefaultValueRef),
|
|
139
|
+
isRelevant: resolveNamedPredicate(entry.relevanceRef),
|
|
140
|
+
requiredWhen: resolveNamedPredicate(entry.requiredWhenRef)
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function mergeEntryYaml(baseEntry, id, override) {
|
|
144
|
+
const merged = baseEntry ? deepMerge(baseEntry, override) : override;
|
|
145
|
+
if (typeof merged.label !== "string" || typeof merged.group !== "string" || typeof merged.description !== "string" || typeof merged.howToGet !== "string" || !Array.isArray(merged.targets) || !Array.isArray(merged.scopes) || typeof merged.requirement !== "string" || !Array.isArray(merged.purposes) || typeof merged.sensitivity !== "string") {
|
|
146
|
+
throw new Error(`Treeseed environment registry entry "${id}" is missing required metadata after merge.`);
|
|
147
|
+
}
|
|
148
|
+
return merged;
|
|
149
|
+
}
|
|
150
|
+
function collectOverlaySources(context) {
|
|
151
|
+
const sources = [];
|
|
152
|
+
const coreOverlay = readYamlOverlayIfPresent(CORE_ENVIRONMENT_PATH);
|
|
153
|
+
if (!coreOverlay) {
|
|
154
|
+
throw new Error(`Treeseed core environment registry file was not found at ${CORE_ENVIRONMENT_PATH}.`);
|
|
155
|
+
}
|
|
156
|
+
sources.push({ label: CORE_ENVIRONMENT_PATH, overlay: coreOverlay });
|
|
157
|
+
for (const pluginEntry of context.plugins) {
|
|
158
|
+
const fileOverlay = readPluginEnvironmentOverlay(pluginEntry.baseDir);
|
|
159
|
+
if (fileOverlay) {
|
|
160
|
+
sources.push({ label: fileOverlay.path, overlay: fileOverlay.overlay });
|
|
161
|
+
}
|
|
162
|
+
const overlaySource = pluginEntry.plugin.environmentRegistry;
|
|
163
|
+
if (!overlaySource) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const pluginContext = {
|
|
167
|
+
projectRoot: context.tenantRoot,
|
|
168
|
+
tenantConfig: context.tenantConfig,
|
|
169
|
+
deployConfig: context.deployConfig,
|
|
170
|
+
pluginConfig: pluginEntry.config
|
|
171
|
+
};
|
|
172
|
+
const overlay = typeof overlaySource === "function" ? overlaySource(pluginContext) : overlaySource;
|
|
173
|
+
if (overlay) {
|
|
174
|
+
sources.push({
|
|
175
|
+
label: `plugin ${pluginEntry.package}`,
|
|
176
|
+
overlay: normalizeOverlay(overlay, `plugin ${pluginEntry.package}`)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const tenantOverlay = loadTreeseedEnvironmentOverlay(context.tenantRoot);
|
|
181
|
+
sources.push({ label: tenantOverlay.path, overlay: tenantOverlay.overlay });
|
|
182
|
+
return sources;
|
|
183
|
+
}
|
|
184
|
+
function resolveTreeseedEnvironmentContext(options = {}) {
|
|
185
|
+
const deployConfig = options.deployConfig ?? loadTreeseedDeployConfig();
|
|
186
|
+
const tenantConfig = options.tenantConfig ?? loadOptionalTenantConfig();
|
|
187
|
+
const plugins = options.plugins ?? loadTreeseedPlugins(deployConfig);
|
|
188
|
+
const tenantRoot = deployConfig.__tenantRoot ?? tenantConfig?.__tenantRoot ?? process.cwd();
|
|
189
|
+
return {
|
|
190
|
+
deployConfig,
|
|
191
|
+
tenantConfig,
|
|
192
|
+
plugins,
|
|
193
|
+
tenantRoot
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function resolveTreeseedEnvironmentRegistry(options = {}) {
|
|
197
|
+
const context = resolveTreeseedEnvironmentContext(options);
|
|
198
|
+
const entriesById = /* @__PURE__ */ new Map();
|
|
199
|
+
const order = [];
|
|
200
|
+
for (const source of collectOverlaySources(context)) {
|
|
201
|
+
for (const [id, override] of Object.entries(source.overlay.entries ?? {})) {
|
|
202
|
+
const current = entriesById.get(id);
|
|
203
|
+
entriesById.set(id, mergeEntryYaml(current, id, override ?? {}));
|
|
204
|
+
if (!current) {
|
|
205
|
+
order.push(id);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
context,
|
|
211
|
+
entries: order.map((id) => materializeEntry(id, entriesById.get(id)))
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function isTreeseedEnvironmentEntryRelevant(entry, context, scope, purpose) {
|
|
215
|
+
if (!entry.scopes.includes(scope)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
if (purpose && !entry.purposes.includes(purpose)) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
if (entry.isRelevant) {
|
|
222
|
+
return entry.isRelevant(context, scope, purpose);
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
function isEntryRequired(entry, context, scope, purpose) {
|
|
227
|
+
if (entry.requirement === "required") {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
if (entry.requirement === "conditional") {
|
|
231
|
+
return entry.requiredWhen ? entry.requiredWhen(context, scope, purpose) : true;
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
function materializeDefaultValue(entry, context, scope) {
|
|
236
|
+
const source = scope === "local" && entry.localDefaultValue !== void 0 ? entry.localDefaultValue : entry.defaultValue;
|
|
237
|
+
if (source === void 0) {
|
|
238
|
+
return void 0;
|
|
239
|
+
}
|
|
240
|
+
return typeof source === "function" ? source(context, scope) : source;
|
|
241
|
+
}
|
|
242
|
+
function getTreeseedEnvironmentSuggestedValues(options) {
|
|
243
|
+
const registry = resolveTreeseedEnvironmentRegistry(options);
|
|
244
|
+
return Object.fromEntries(
|
|
245
|
+
registry.entries.filter((entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, options.scope, options.purpose)).map((entry) => [entry.id, materializeDefaultValue(entry, registry.context, options.scope)]).filter(([, value]) => value !== void 0)
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
function valuePresent(value) {
|
|
249
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
250
|
+
}
|
|
251
|
+
function validateValue(entry, value) {
|
|
252
|
+
if (!entry.validation) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
switch (entry.validation.kind) {
|
|
256
|
+
case "string":
|
|
257
|
+
case "nonempty":
|
|
258
|
+
return valuePresent(value) ? null : `${entry.id} must be a non-empty string.`;
|
|
259
|
+
case "boolean":
|
|
260
|
+
return /^(true|false|1|0)$/i.test(value) ? null : `${entry.id} must be true or false.`;
|
|
261
|
+
case "number":
|
|
262
|
+
return Number.isFinite(Number(value)) ? null : `${entry.id} must be a number.`;
|
|
263
|
+
case "url":
|
|
264
|
+
try {
|
|
265
|
+
new URL(value);
|
|
266
|
+
return null;
|
|
267
|
+
} catch {
|
|
268
|
+
return `${entry.id} must be a valid URL.`;
|
|
269
|
+
}
|
|
270
|
+
case "email":
|
|
271
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ? null : `${entry.id} must be a valid email address.`;
|
|
272
|
+
case "enum":
|
|
273
|
+
return entry.validation.values.includes(value) ? null : `${entry.id} must be one of: ${entry.validation.values.join(", ")}.`;
|
|
274
|
+
default:
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function validateTreeseedEnvironmentValues(options) {
|
|
279
|
+
const registry = resolveTreeseedEnvironmentRegistry(options);
|
|
280
|
+
const relevantEntries = registry.entries.filter(
|
|
281
|
+
(entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, options.scope, options.purpose)
|
|
282
|
+
);
|
|
283
|
+
const requiredEntries = relevantEntries.filter(
|
|
284
|
+
(entry) => isEntryRequired(entry, registry.context, options.scope, options.purpose)
|
|
285
|
+
);
|
|
286
|
+
const missing = [];
|
|
287
|
+
const invalid = [];
|
|
288
|
+
for (const entry of requiredEntries) {
|
|
289
|
+
const value = options.values[entry.id];
|
|
290
|
+
if (!valuePresent(value)) {
|
|
291
|
+
missing.push({
|
|
292
|
+
id: entry.id,
|
|
293
|
+
label: entry.label,
|
|
294
|
+
reason: "missing",
|
|
295
|
+
message: `${entry.id} is required for ${options.purpose} (${options.scope}). ${entry.howToGet}`,
|
|
296
|
+
entry
|
|
297
|
+
});
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const validationMessage = validateValue(entry, value);
|
|
301
|
+
if (validationMessage) {
|
|
302
|
+
invalid.push({
|
|
303
|
+
id: entry.id,
|
|
304
|
+
label: entry.label,
|
|
305
|
+
reason: "invalid",
|
|
306
|
+
message: validationMessage,
|
|
307
|
+
entry
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
ok: missing.length === 0 && invalid.length === 0,
|
|
313
|
+
entries: relevantEntries,
|
|
314
|
+
required: requiredEntries,
|
|
315
|
+
missing,
|
|
316
|
+
invalid
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
export {
|
|
320
|
+
TREESEED_ENVIRONMENT_PURPOSES,
|
|
321
|
+
TREESEED_ENVIRONMENT_REQUIREMENTS,
|
|
322
|
+
TREESEED_ENVIRONMENT_SCOPES,
|
|
323
|
+
TREESEED_ENVIRONMENT_SENSITIVITY,
|
|
324
|
+
TREESEED_ENVIRONMENT_TARGETS,
|
|
325
|
+
getTreeseedEnvironmentSuggestedValues,
|
|
326
|
+
isTreeseedEnvironmentEntryRelevant,
|
|
327
|
+
loadTreeseedEnvironmentOverlay,
|
|
328
|
+
resolveTreeseedEnvironmentContext,
|
|
329
|
+
resolveTreeseedEnvironmentRegistry,
|
|
330
|
+
validateTreeseedEnvironmentValues
|
|
331
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const TREESEED_DEFAULT_PLUGIN_PACKAGE = "@treeseed/core/plugin-default";
|
|
2
|
+
export declare const TREESEED_DEFAULT_PROVIDER_SELECTIONS: {
|
|
3
|
+
forms: string;
|
|
4
|
+
operations: string;
|
|
5
|
+
agents: {
|
|
6
|
+
execution: string;
|
|
7
|
+
mutation: string;
|
|
8
|
+
repository: string;
|
|
9
|
+
verification: string;
|
|
10
|
+
notification: string;
|
|
11
|
+
research: string;
|
|
12
|
+
};
|
|
13
|
+
deploy: string;
|
|
14
|
+
content: {
|
|
15
|
+
docs: string;
|
|
16
|
+
};
|
|
17
|
+
site: string;
|
|
18
|
+
};
|
|
19
|
+
export declare const TREESEED_DEFAULT_PLUGIN_REFERENCES: {
|
|
20
|
+
package: string;
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
}[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const TREESEED_DEFAULT_PLUGIN_PACKAGE = "@treeseed/core/plugin-default";
|
|
2
|
+
const TREESEED_DEFAULT_PROVIDER_SELECTIONS = {
|
|
3
|
+
forms: "store_only",
|
|
4
|
+
operations: "default",
|
|
5
|
+
agents: {
|
|
6
|
+
execution: "stub",
|
|
7
|
+
mutation: "local_branch",
|
|
8
|
+
repository: "stub",
|
|
9
|
+
verification: "stub",
|
|
10
|
+
notification: "stub",
|
|
11
|
+
research: "stub"
|
|
12
|
+
},
|
|
13
|
+
deploy: "cloudflare",
|
|
14
|
+
content: {
|
|
15
|
+
docs: "default"
|
|
16
|
+
},
|
|
17
|
+
site: "default"
|
|
18
|
+
};
|
|
19
|
+
const TREESEED_DEFAULT_PLUGIN_REFERENCES = [
|
|
20
|
+
{
|
|
21
|
+
package: TREESEED_DEFAULT_PLUGIN_PACKAGE,
|
|
22
|
+
enabled: true
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
export {
|
|
26
|
+
TREESEED_DEFAULT_PLUGIN_PACKAGE,
|
|
27
|
+
TREESEED_DEFAULT_PLUGIN_REFERENCES,
|
|
28
|
+
TREESEED_DEFAULT_PROVIDER_SELECTIONS
|
|
29
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { TreeseedDeployConfig, TreeseedTenantConfig } from '../contracts.ts';
|
|
2
|
+
import type { TreeseedEnvironmentRegistryOverlay } from '../environment.ts';
|
|
3
|
+
import type { SdkGraphRankingProvider } from '../../sdk-types.ts';
|
|
4
|
+
export type TreeseedSiteLayerDefinition = {
|
|
5
|
+
root: string;
|
|
6
|
+
kinds?: Array<'pages' | 'styles' | 'components'>;
|
|
7
|
+
};
|
|
8
|
+
export type TreeseedSiteRouteContribution = {
|
|
9
|
+
pattern: string;
|
|
10
|
+
entrypoint?: string;
|
|
11
|
+
resourcePath?: string;
|
|
12
|
+
};
|
|
13
|
+
export type TreeseedSiteExtensionContribution = {
|
|
14
|
+
routes?: TreeseedSiteRouteContribution[];
|
|
15
|
+
starlightComponents?: Record<string, string>;
|
|
16
|
+
customCss?: string[];
|
|
17
|
+
remarkPlugins?: unknown[];
|
|
18
|
+
rehypePlugins?: unknown[];
|
|
19
|
+
envSchema?: Record<string, unknown>;
|
|
20
|
+
vitePlugins?: unknown[];
|
|
21
|
+
integrations?: unknown[];
|
|
22
|
+
routeMiddleware?: unknown[];
|
|
23
|
+
};
|
|
24
|
+
export type TreeseedPluginSiteContext = {
|
|
25
|
+
projectRoot: string;
|
|
26
|
+
tenantConfig: TreeseedTenantConfig;
|
|
27
|
+
siteConfig?: unknown;
|
|
28
|
+
deployConfig?: TreeseedDeployConfig;
|
|
29
|
+
pluginConfig: Record<string, unknown>;
|
|
30
|
+
};
|
|
31
|
+
export type TreeseedPluginEnvironmentContext = {
|
|
32
|
+
projectRoot: string;
|
|
33
|
+
tenantConfig?: TreeseedTenantConfig;
|
|
34
|
+
deployConfig?: TreeseedDeployConfig;
|
|
35
|
+
pluginConfig: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
export type TreeseedGraphRankingProviderContribution = SdkGraphRankingProvider | ((context: TreeseedPluginEnvironmentContext) => SdkGraphRankingProvider | undefined);
|
|
38
|
+
export interface TreeseedPlugin {
|
|
39
|
+
id?: string;
|
|
40
|
+
provides?: Record<string, any> & {
|
|
41
|
+
operations?: string[];
|
|
42
|
+
};
|
|
43
|
+
operationProviders?: Record<string, unknown>;
|
|
44
|
+
siteProviders?: Record<string, TreeseedSiteExtensionContribution | ((context: TreeseedPluginSiteContext) => TreeseedSiteExtensionContribution)>;
|
|
45
|
+
siteHooks?: TreeseedSiteExtensionContribution | ((context: TreeseedPluginSiteContext) => TreeseedSiteExtensionContribution);
|
|
46
|
+
siteLayers?: TreeseedSiteLayerDefinition[] | ((context: TreeseedPluginSiteContext) => TreeseedSiteLayerDefinition[] | undefined);
|
|
47
|
+
environmentRegistry?: TreeseedEnvironmentRegistryOverlay | ((context: TreeseedPluginEnvironmentContext) => TreeseedEnvironmentRegistryOverlay | undefined);
|
|
48
|
+
graphRankingProviders?: Record<string, TreeseedGraphRankingProviderContribution>;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
export declare function defineTreeseedPlugin<T extends TreeseedPlugin>(plugin: T): T;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TreeseedDeployConfig } from '../contracts.ts';
|
|
2
|
+
import type { TreeseedPluginEnvironmentContext } from './plugin.ts';
|
|
3
|
+
import type { SdkGraphRankingProvider } from '../../sdk-types.ts';
|
|
4
|
+
type LoadedPluginEntry = {
|
|
5
|
+
package: string;
|
|
6
|
+
config: Record<string, unknown>;
|
|
7
|
+
baseDir: string;
|
|
8
|
+
plugin: Record<string, any>;
|
|
9
|
+
};
|
|
10
|
+
export type LoadedTreeseedPluginEntry = LoadedPluginEntry;
|
|
11
|
+
export declare function loadTreeseedPlugins(config?: TreeseedDeployConfig): LoadedPluginEntry[];
|
|
12
|
+
export declare function loadTreeseedPluginRuntime(config?: TreeseedDeployConfig): {
|
|
13
|
+
config: TreeseedDeployConfig;
|
|
14
|
+
plugins: LoadedPluginEntry[];
|
|
15
|
+
provided: {
|
|
16
|
+
forms: Set<string>;
|
|
17
|
+
operations: Set<string>;
|
|
18
|
+
agents: {
|
|
19
|
+
execution: Set<string>;
|
|
20
|
+
mutation: Set<string>;
|
|
21
|
+
repository: Set<string>;
|
|
22
|
+
verification: Set<string>;
|
|
23
|
+
notification: Set<string>;
|
|
24
|
+
research: Set<string>;
|
|
25
|
+
handlers: Set<string>;
|
|
26
|
+
};
|
|
27
|
+
deploy: Set<string>;
|
|
28
|
+
content: {
|
|
29
|
+
docs: Set<string>;
|
|
30
|
+
};
|
|
31
|
+
site: Set<string>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export declare function resolveTreeseedGraphRankingProvider(plugins: LoadedPluginEntry[], context: Omit<TreeseedPluginEnvironmentContext, 'pluginConfig'>): SdkGraphRankingProvider | null;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { loadTreeseedDeployConfig } from "../deploy/config.js";
|
|
6
|
+
import { TREESEED_DEFAULT_PLUGIN_PACKAGE } from "./constants.js";
|
|
7
|
+
const require2 = createRequire(import.meta.url);
|
|
8
|
+
const runtimeDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
function normalizeLoadedPlugin(moduleExports, packageName) {
|
|
10
|
+
const plugin = moduleExports?.default ?? moduleExports;
|
|
11
|
+
if (!plugin || typeof plugin !== "object") {
|
|
12
|
+
throw new Error(`Treeseed plugin "${packageName}" did not export a plugin object.`);
|
|
13
|
+
}
|
|
14
|
+
return plugin;
|
|
15
|
+
}
|
|
16
|
+
function isPathLikePluginReference(packageName) {
|
|
17
|
+
return packageName.startsWith(".") || packageName.startsWith("/") || packageName.startsWith("file:");
|
|
18
|
+
}
|
|
19
|
+
function resolveLocalDefaultPluginPath() {
|
|
20
|
+
const candidates = [
|
|
21
|
+
path.resolve(runtimeDir, "../../../../core/dist/plugin-default.js")
|
|
22
|
+
];
|
|
23
|
+
for (const candidate of candidates) {
|
|
24
|
+
if (existsSync(candidate)) {
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function resolveInstalledPluginPath(packageName, tenantRoot) {
|
|
31
|
+
return require2.resolve(packageName, {
|
|
32
|
+
paths: [tenantRoot, process.cwd()]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function loadPluginModule(packageName, tenantRoot) {
|
|
36
|
+
if (packageName === TREESEED_DEFAULT_PLUGIN_PACKAGE) {
|
|
37
|
+
const localDefaultPluginPath = resolveLocalDefaultPluginPath();
|
|
38
|
+
const resolvedPath2 = localDefaultPluginPath ?? resolveInstalledPluginPath(packageName, tenantRoot);
|
|
39
|
+
return {
|
|
40
|
+
moduleExports: require2(resolvedPath2),
|
|
41
|
+
baseDir: path.dirname(resolvedPath2)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (isPathLikePluginReference(packageName)) {
|
|
45
|
+
const resolvedPath2 = packageName.startsWith("file:") ? fileURLToPath(packageName) : path.resolve(tenantRoot, packageName);
|
|
46
|
+
return {
|
|
47
|
+
moduleExports: require2(resolvedPath2),
|
|
48
|
+
baseDir: path.dirname(resolvedPath2)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const resolvedPath = resolveInstalledPluginPath(packageName, tenantRoot);
|
|
52
|
+
return {
|
|
53
|
+
moduleExports: require2(resolvedPath),
|
|
54
|
+
baseDir: path.dirname(resolvedPath)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function loadTreeseedPlugins(config = loadTreeseedDeployConfig()) {
|
|
58
|
+
const tenantRoot = config.__tenantRoot ?? process.cwd();
|
|
59
|
+
const plugins = [];
|
|
60
|
+
for (const pluginRef of config.plugins ?? []) {
|
|
61
|
+
if (pluginRef?.enabled === false) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const loaded = loadPluginModule(pluginRef.package, tenantRoot);
|
|
65
|
+
const plugin = normalizeLoadedPlugin(loaded.moduleExports, pluginRef.package);
|
|
66
|
+
plugins.push({
|
|
67
|
+
package: pluginRef.package,
|
|
68
|
+
config: pluginRef.config ?? {},
|
|
69
|
+
baseDir: loaded.baseDir,
|
|
70
|
+
plugin
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return plugins;
|
|
74
|
+
}
|
|
75
|
+
function collectProvidedIds(plugins) {
|
|
76
|
+
const provided = {
|
|
77
|
+
forms: /* @__PURE__ */ new Set(),
|
|
78
|
+
operations: /* @__PURE__ */ new Set(),
|
|
79
|
+
agents: {
|
|
80
|
+
execution: /* @__PURE__ */ new Set(),
|
|
81
|
+
mutation: /* @__PURE__ */ new Set(),
|
|
82
|
+
repository: /* @__PURE__ */ new Set(),
|
|
83
|
+
verification: /* @__PURE__ */ new Set(),
|
|
84
|
+
notification: /* @__PURE__ */ new Set(),
|
|
85
|
+
research: /* @__PURE__ */ new Set(),
|
|
86
|
+
handlers: /* @__PURE__ */ new Set()
|
|
87
|
+
},
|
|
88
|
+
deploy: /* @__PURE__ */ new Set(),
|
|
89
|
+
content: {
|
|
90
|
+
docs: /* @__PURE__ */ new Set()
|
|
91
|
+
},
|
|
92
|
+
site: /* @__PURE__ */ new Set()
|
|
93
|
+
};
|
|
94
|
+
for (const { plugin } of plugins) {
|
|
95
|
+
for (const id of plugin.provides?.forms ?? []) provided.forms.add(id);
|
|
96
|
+
for (const id of plugin.provides?.operations ?? []) provided.operations.add(id);
|
|
97
|
+
for (const id of plugin.provides?.agents?.execution ?? []) provided.agents.execution.add(id);
|
|
98
|
+
for (const id of plugin.provides?.agents?.mutation ?? []) provided.agents.mutation.add(id);
|
|
99
|
+
for (const id of plugin.provides?.agents?.repository ?? []) provided.agents.repository.add(id);
|
|
100
|
+
for (const id of plugin.provides?.agents?.verification ?? []) provided.agents.verification.add(id);
|
|
101
|
+
for (const id of plugin.provides?.agents?.notification ?? []) provided.agents.notification.add(id);
|
|
102
|
+
for (const id of plugin.provides?.agents?.research ?? []) provided.agents.research.add(id);
|
|
103
|
+
for (const id of plugin.provides?.agents?.handlers ?? []) provided.agents.handlers.add(id);
|
|
104
|
+
for (const id of plugin.provides?.deploy ?? []) provided.deploy.add(id);
|
|
105
|
+
for (const id of plugin.provides?.content?.docs ?? []) provided.content.docs.add(id);
|
|
106
|
+
for (const id of plugin.provides?.site ?? []) provided.site.add(id);
|
|
107
|
+
}
|
|
108
|
+
return provided;
|
|
109
|
+
}
|
|
110
|
+
function assertSelectedProvider(provided, label, id) {
|
|
111
|
+
if (!id) {
|
|
112
|
+
throw new Error(`Treeseed plugin runtime is missing selected provider id for ${label}.`);
|
|
113
|
+
}
|
|
114
|
+
if (!provided.has(id)) {
|
|
115
|
+
throw new Error(`Treeseed plugin runtime could not resolve ${label} provider "${id}".`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function loadTreeseedPluginRuntime(config = loadTreeseedDeployConfig()) {
|
|
119
|
+
const plugins = loadTreeseedPlugins(config);
|
|
120
|
+
const provided = collectProvidedIds(plugins);
|
|
121
|
+
const providers = config.providers;
|
|
122
|
+
assertSelectedProvider(provided.forms, "forms", providers.forms);
|
|
123
|
+
assertSelectedProvider(provided.operations, "operations", providers.operations);
|
|
124
|
+
assertSelectedProvider(provided.agents.execution, "agents.execution", providers.agents.execution);
|
|
125
|
+
assertSelectedProvider(provided.agents.mutation, "agents.mutation", providers.agents.mutation);
|
|
126
|
+
assertSelectedProvider(provided.agents.repository, "agents.repository", providers.agents.repository);
|
|
127
|
+
assertSelectedProvider(provided.agents.verification, "agents.verification", providers.agents.verification);
|
|
128
|
+
assertSelectedProvider(provided.agents.notification, "agents.notification", providers.agents.notification);
|
|
129
|
+
assertSelectedProvider(provided.agents.research, "agents.research", providers.agents.research);
|
|
130
|
+
assertSelectedProvider(provided.deploy, "deploy", providers.deploy);
|
|
131
|
+
assertSelectedProvider(provided.content.docs, "content.docs", providers.content?.docs);
|
|
132
|
+
assertSelectedProvider(provided.site, "site", providers.site);
|
|
133
|
+
return {
|
|
134
|
+
config,
|
|
135
|
+
plugins,
|
|
136
|
+
provided
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function resolveTreeseedGraphRankingProvider(plugins, context) {
|
|
140
|
+
for (const entry of plugins) {
|
|
141
|
+
const contributions = entry.plugin.graphRankingProviders;
|
|
142
|
+
if (!contributions || typeof contributions !== "object") {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
for (const contribution of Object.values(contributions)) {
|
|
146
|
+
if (!contribution) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const provider = typeof contribution === "function" ? contribution({ ...context, pluginConfig: entry.config ?? {} }) : contribution;
|
|
150
|
+
if (provider) {
|
|
151
|
+
return provider;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
export {
|
|
158
|
+
loadTreeseedPluginRuntime,
|
|
159
|
+
loadTreeseedPlugins,
|
|
160
|
+
resolveTreeseedGraphRankingProvider
|
|
161
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { TREESEED_DEFAULT_PLUGIN_PACKAGE, TREESEED_DEFAULT_PLUGIN_REFERENCES, TREESEED_DEFAULT_PROVIDER_SELECTIONS, } from './plugins/constants.ts';
|
|
2
|
+
export { getTreeseedAgentProviderSelections, getTreeseedDeployConfig, getTreeseedDeployProvider, getTreeseedDocsProvider, getTreeseedFormsProvider, getTreeseedOperationsProvider, getTreeseedSiteProvider, isTreeseedSmtpEnabled, isTreeseedTurnstileEnabled, resetTreeseedDeployConfigForTests, } from './deploy-runtime.ts';
|
|
3
|
+
export { defineTreeseedPlugin } from './plugins/plugin.ts';
|
|
4
|
+
export type * from './plugins/plugin.ts';
|
|
5
|
+
export { loadTreeseedPluginRuntime, loadTreeseedPlugins, resolveTreeseedGraphRankingProvider } from './plugins/runtime.ts';
|
|
6
|
+
export type { LoadedTreeseedPluginEntry } from './plugins/runtime.ts';
|