@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,514 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { join, relative, resolve } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { RemoteTreeseedAuthClient, RemoteTreeseedClient } from "../../remote.js";
|
|
6
|
+
import {
|
|
7
|
+
findTreeseedOperation,
|
|
8
|
+
TRESEED_OPERATION_SPECS
|
|
9
|
+
} from "../../operations-registry.js";
|
|
10
|
+
import {
|
|
11
|
+
clearTreeseedRemoteSession,
|
|
12
|
+
resolveTreeseedRemoteConfig,
|
|
13
|
+
setTreeseedRemoteSession
|
|
14
|
+
} from "../../operations/services/config-runtime.js";
|
|
15
|
+
import {
|
|
16
|
+
createPersistentDeployTarget,
|
|
17
|
+
deployTargetLabel,
|
|
18
|
+
ensureGeneratedWranglerConfig,
|
|
19
|
+
finalizeDeploymentState,
|
|
20
|
+
loadDeployState
|
|
21
|
+
} from "../../operations/services/deploy.js";
|
|
22
|
+
import {
|
|
23
|
+
dockerIsAvailable,
|
|
24
|
+
findRunningMailpitContainer,
|
|
25
|
+
stopKnownMailpitContainers
|
|
26
|
+
} from "../../operations/services/mailpit-runtime.js";
|
|
27
|
+
import {
|
|
28
|
+
loadCliDeployConfig,
|
|
29
|
+
packageScriptPath,
|
|
30
|
+
resolveWranglerBin
|
|
31
|
+
} from "../../operations/services/runtime-tools.js";
|
|
32
|
+
import {
|
|
33
|
+
scaffoldTemplateProject,
|
|
34
|
+
listTemplateProducts,
|
|
35
|
+
resolveTemplateProduct,
|
|
36
|
+
serializeTemplateRegistryEntry,
|
|
37
|
+
syncTemplateProject,
|
|
38
|
+
validateTemplateProduct
|
|
39
|
+
} from "../../operations/services/template-registry.js";
|
|
40
|
+
import {
|
|
41
|
+
collectCliPreflight,
|
|
42
|
+
formatCliPreflightReport
|
|
43
|
+
} from "../../operations/services/workspace-preflight.js";
|
|
44
|
+
import { repoRoot } from "../../operations/services/workspace-save.js";
|
|
45
|
+
import { run } from "../../operations/services/workspace-tools.js";
|
|
46
|
+
import { resolveTreeseedWorkflowState } from "../../workflow-state.js";
|
|
47
|
+
import { TreeseedWorkflowError, TreeseedWorkflowSdk } from "../../workflow.js";
|
|
48
|
+
function operationResult(metadata, payload, options = {}) {
|
|
49
|
+
return {
|
|
50
|
+
operation: metadata.id,
|
|
51
|
+
ok: options.ok ?? true,
|
|
52
|
+
payload,
|
|
53
|
+
meta: options.meta,
|
|
54
|
+
nextSteps: options.nextSteps,
|
|
55
|
+
exitCode: options.exitCode ?? (options.ok === false ? 1 : 0),
|
|
56
|
+
stdout: options.stdout,
|
|
57
|
+
stderr: options.stderr
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function failureResult(metadata, message, options = {}) {
|
|
61
|
+
return operationResult(metadata, null, {
|
|
62
|
+
ok: false,
|
|
63
|
+
exitCode: options.exitCode ?? 1,
|
|
64
|
+
stderr: [message],
|
|
65
|
+
meta: options.meta
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function contextEnv(context) {
|
|
69
|
+
return { ...process.env, ...context.env ?? {} };
|
|
70
|
+
}
|
|
71
|
+
function runNodeScript(metadata, scriptName, args, context) {
|
|
72
|
+
if (context.spawn) {
|
|
73
|
+
const result2 = context.spawn(process.execPath, [packageScriptPath(scriptName), ...args], {
|
|
74
|
+
cwd: context.cwd,
|
|
75
|
+
env: contextEnv(context),
|
|
76
|
+
stdio: "inherit"
|
|
77
|
+
});
|
|
78
|
+
return operationResult(metadata, {
|
|
79
|
+
script: scriptName,
|
|
80
|
+
args
|
|
81
|
+
}, {
|
|
82
|
+
ok: (result2.status ?? 1) === 0,
|
|
83
|
+
exitCode: result2.status ?? 1
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const result = spawnSync(process.execPath, [packageScriptPath(scriptName), ...args], {
|
|
87
|
+
cwd: context.cwd,
|
|
88
|
+
env: contextEnv(context),
|
|
89
|
+
encoding: "utf8",
|
|
90
|
+
stdio: "pipe"
|
|
91
|
+
});
|
|
92
|
+
const stdout = (result.stdout ?? "").split(/\r?\n/).filter(Boolean);
|
|
93
|
+
const stderr = (result.stderr ?? "").split(/\r?\n/).filter(Boolean);
|
|
94
|
+
for (const line of stdout) context.write?.(line, "stdout");
|
|
95
|
+
for (const line of stderr) context.write?.(line, "stderr");
|
|
96
|
+
return operationResult(metadata, {
|
|
97
|
+
script: scriptName,
|
|
98
|
+
args
|
|
99
|
+
}, {
|
|
100
|
+
ok: (result.status ?? 1) === 0,
|
|
101
|
+
exitCode: result.status ?? 1,
|
|
102
|
+
stdout,
|
|
103
|
+
stderr
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function copyTreeseedOperationalState(sourceRoot, targetRoot) {
|
|
107
|
+
const sourceTreeseedRoot = resolve(sourceRoot, ".treeseed");
|
|
108
|
+
if (!existsSync(sourceTreeseedRoot)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
copyDirectory(sourceTreeseedRoot, resolve(targetRoot, ".treeseed"));
|
|
112
|
+
}
|
|
113
|
+
function copyDirectory(sourceDir, targetDir) {
|
|
114
|
+
mkdirSync(targetDir, { recursive: true });
|
|
115
|
+
for (const entry of readdirSync(sourceDir, { withFileTypes: true })) {
|
|
116
|
+
const sourcePath = resolve(sourceDir, entry.name);
|
|
117
|
+
const targetPath = resolve(targetDir, entry.name);
|
|
118
|
+
if (entry.isDirectory()) {
|
|
119
|
+
copyDirectory(sourcePath, targetPath);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
writeFileSync(targetPath, readFileSync(sourcePath));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function workflowInputForOperation(name, input) {
|
|
126
|
+
switch (name) {
|
|
127
|
+
case "status":
|
|
128
|
+
case "tasks":
|
|
129
|
+
return {};
|
|
130
|
+
case "dev:watch":
|
|
131
|
+
return { ...input, watch: true };
|
|
132
|
+
default:
|
|
133
|
+
return input;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
class BaseOperation {
|
|
137
|
+
metadata;
|
|
138
|
+
constructor(name) {
|
|
139
|
+
const metadata = findTreeseedOperation(name);
|
|
140
|
+
if (!metadata) {
|
|
141
|
+
throw new Error(`Unknown operation metadata for "${name}".`);
|
|
142
|
+
}
|
|
143
|
+
this.metadata = metadata;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
class WorkflowOperation extends BaseOperation {
|
|
147
|
+
workflowName;
|
|
148
|
+
constructor(name, workflowName) {
|
|
149
|
+
super(name);
|
|
150
|
+
this.workflowName = workflowName ?? (name === "switch" ? "switch" : name);
|
|
151
|
+
}
|
|
152
|
+
async execute(input, context) {
|
|
153
|
+
try {
|
|
154
|
+
const workflow = new TreeseedWorkflowSdk({
|
|
155
|
+
cwd: context.cwd,
|
|
156
|
+
env: context.env,
|
|
157
|
+
write: context.write,
|
|
158
|
+
prompt: context.prompt,
|
|
159
|
+
confirm: context.confirm,
|
|
160
|
+
transport: context.transport ?? "sdk"
|
|
161
|
+
});
|
|
162
|
+
return await workflow.execute(this.workflowName, workflowInputForOperation(this.metadata.name, input));
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error instanceof TreeseedWorkflowError) {
|
|
165
|
+
return failureResult(this.metadata, error.message, {
|
|
166
|
+
exitCode: error.exitCode ?? 1,
|
|
167
|
+
meta: {
|
|
168
|
+
code: error.code,
|
|
169
|
+
details: error.details ?? null
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
class ScriptOperation extends BaseOperation {
|
|
178
|
+
constructor(name, scriptName, extraArgs = []) {
|
|
179
|
+
super(name);
|
|
180
|
+
this.scriptName = scriptName;
|
|
181
|
+
this.extraArgs = extraArgs;
|
|
182
|
+
}
|
|
183
|
+
scriptName;
|
|
184
|
+
extraArgs;
|
|
185
|
+
async execute(input, context) {
|
|
186
|
+
const args = Array.isArray(input.args) ? input.args.map(String) : [];
|
|
187
|
+
return runNodeScript(this.metadata, this.scriptName, [...this.extraArgs, ...args], context);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
class PreflightOperation extends BaseOperation {
|
|
191
|
+
constructor(name, requireAuth = false) {
|
|
192
|
+
super(name);
|
|
193
|
+
this.requireAuth = requireAuth;
|
|
194
|
+
}
|
|
195
|
+
requireAuth;
|
|
196
|
+
async execute(input, context) {
|
|
197
|
+
const report = collectCliPreflight({
|
|
198
|
+
cwd: context.cwd,
|
|
199
|
+
requireAuth: input.requireAuth ?? this.requireAuth
|
|
200
|
+
});
|
|
201
|
+
const stdout = [formatCliPreflightReport(report)];
|
|
202
|
+
for (const line of stdout) context.write?.(line, "stdout");
|
|
203
|
+
return operationResult(this.metadata, report, {
|
|
204
|
+
ok: report.ok,
|
|
205
|
+
exitCode: report.ok ? 0 : 1,
|
|
206
|
+
stdout,
|
|
207
|
+
stderr: []
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
class InitOperation extends BaseOperation {
|
|
212
|
+
async execute(input, context) {
|
|
213
|
+
const directory = String(input.directory ?? input.target ?? "").trim();
|
|
214
|
+
if (!directory) {
|
|
215
|
+
return failureResult(this.metadata, "Init requires a target directory.");
|
|
216
|
+
}
|
|
217
|
+
const definition = await scaffoldTemplateProject(
|
|
218
|
+
String(input.template ?? "starter-basic"),
|
|
219
|
+
resolve(context.cwd, directory),
|
|
220
|
+
{
|
|
221
|
+
target: directory,
|
|
222
|
+
name: typeof input.name === "string" ? input.name : null,
|
|
223
|
+
slug: typeof input.slug === "string" ? input.slug : null,
|
|
224
|
+
siteUrl: typeof input.siteUrl === "string" ? input.siteUrl : null,
|
|
225
|
+
contactEmail: typeof input.contactEmail === "string" ? input.contactEmail : null,
|
|
226
|
+
repositoryUrl: typeof input.repositoryUrl === "string" ? input.repositoryUrl : typeof input.repo === "string" ? input.repo : null,
|
|
227
|
+
discordUrl: typeof input.discordUrl === "string" ? input.discordUrl : typeof input.discord === "string" ? input.discord : void 0
|
|
228
|
+
},
|
|
229
|
+
{ writeWarning: (message) => context.write?.(message, "stderr") }
|
|
230
|
+
);
|
|
231
|
+
return operationResult(this.metadata, {
|
|
232
|
+
directory,
|
|
233
|
+
template: definition.id
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
class TemplateOperation extends BaseOperation {
|
|
238
|
+
async execute(input, context) {
|
|
239
|
+
const action = String(input.action ?? "list");
|
|
240
|
+
const target = typeof input.id === "string" ? input.id : typeof input.target === "string" ? input.target : void 0;
|
|
241
|
+
const writeWarning = (message) => context.write?.(message, "stderr");
|
|
242
|
+
if (action === "show") {
|
|
243
|
+
if (!target) {
|
|
244
|
+
return failureResult(this.metadata, "Template show requires an id.");
|
|
245
|
+
}
|
|
246
|
+
return operationResult(this.metadata, {
|
|
247
|
+
action,
|
|
248
|
+
template: serializeTemplateRegistryEntry(await resolveTemplateProduct(target, { writeWarning }))
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if (action === "validate") {
|
|
252
|
+
const products = target ? [await resolveTemplateProduct(target, { writeWarning })] : await listTemplateProducts({ writeWarning });
|
|
253
|
+
for (const product of products) {
|
|
254
|
+
await validateTemplateProduct(product, { writeWarning });
|
|
255
|
+
}
|
|
256
|
+
return operationResult(this.metadata, {
|
|
257
|
+
action,
|
|
258
|
+
validated: products.map((product) => product.id)
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return operationResult(this.metadata, {
|
|
262
|
+
action: "list",
|
|
263
|
+
templates: (await listTemplateProducts({ writeWarning })).map((product) => serializeTemplateRegistryEntry(product))
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
class SyncTemplateOperation extends BaseOperation {
|
|
268
|
+
async execute(input, context) {
|
|
269
|
+
const changed = await syncTemplateProject(context.cwd, {
|
|
270
|
+
check: input.check === true,
|
|
271
|
+
writeWarning: (message) => context.write?.(message, "stderr")
|
|
272
|
+
});
|
|
273
|
+
return operationResult(this.metadata, {
|
|
274
|
+
check: input.check === true,
|
|
275
|
+
changed
|
|
276
|
+
}, {
|
|
277
|
+
ok: input.check === true ? changed.length === 0 : true,
|
|
278
|
+
exitCode: input.check === true && changed.length > 0 ? 1 : 0
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
class DoctorOperation extends BaseOperation {
|
|
283
|
+
async execute(_input, context) {
|
|
284
|
+
const state = resolveTreeseedWorkflowState(context.cwd);
|
|
285
|
+
const preflight = collectCliPreflight({ cwd: context.cwd, requireAuth: false });
|
|
286
|
+
return operationResult(this.metadata, {
|
|
287
|
+
state,
|
|
288
|
+
preflight
|
|
289
|
+
}, {
|
|
290
|
+
ok: preflight.ok,
|
|
291
|
+
exitCode: preflight.ok ? 0 : 1
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
class AuthLoginOperation extends BaseOperation {
|
|
296
|
+
async execute(input, context) {
|
|
297
|
+
const tenantRoot = context.cwd;
|
|
298
|
+
const remoteConfig = resolveTreeseedRemoteConfig(tenantRoot, context.env);
|
|
299
|
+
const hostId = typeof input.host === "string" ? input.host : remoteConfig.activeHostId;
|
|
300
|
+
const client = new RemoteTreeseedAuthClient(new RemoteTreeseedClient({
|
|
301
|
+
...remoteConfig,
|
|
302
|
+
activeHostId: hostId
|
|
303
|
+
}));
|
|
304
|
+
const started = await client.startDeviceFlow({
|
|
305
|
+
clientName: "treeseed-sdk",
|
|
306
|
+
scopes: ["auth:me", "sdk", "operations"]
|
|
307
|
+
});
|
|
308
|
+
const deadline = Date.parse(started.expiresAt);
|
|
309
|
+
while (Date.now() < deadline) {
|
|
310
|
+
const response = await client.pollDeviceFlow({ deviceCode: started.deviceCode });
|
|
311
|
+
if (response.ok && response.status === "approved") {
|
|
312
|
+
setTreeseedRemoteSession(tenantRoot, {
|
|
313
|
+
hostId,
|
|
314
|
+
accessToken: response.accessToken,
|
|
315
|
+
refreshToken: response.refreshToken,
|
|
316
|
+
expiresAt: response.expiresAt,
|
|
317
|
+
principal: response.principal
|
|
318
|
+
});
|
|
319
|
+
return operationResult(this.metadata, {
|
|
320
|
+
hostId,
|
|
321
|
+
verificationUriComplete: started.verificationUriComplete,
|
|
322
|
+
userCode: started.userCode,
|
|
323
|
+
principal: response.principal
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (!response.ok && response.status !== "already_used") {
|
|
327
|
+
return failureResult(this.metadata, response.error);
|
|
328
|
+
}
|
|
329
|
+
await new Promise((resolveTimer) => setTimeout(resolveTimer, started.intervalSeconds * 1e3));
|
|
330
|
+
}
|
|
331
|
+
return failureResult(this.metadata, "Treeseed API login expired before approval completed.");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
class AuthLogoutOperation extends BaseOperation {
|
|
335
|
+
async execute(input, context) {
|
|
336
|
+
const remoteConfig = resolveTreeseedRemoteConfig(context.cwd, context.env);
|
|
337
|
+
const hostId = typeof input.host === "string" ? input.host : remoteConfig.activeHostId;
|
|
338
|
+
clearTreeseedRemoteSession(context.cwd, hostId);
|
|
339
|
+
return operationResult(this.metadata, { hostId });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
class AuthWhoAmIOperation extends BaseOperation {
|
|
343
|
+
async execute(_input, context) {
|
|
344
|
+
const remoteConfig = resolveTreeseedRemoteConfig(context.cwd, context.env);
|
|
345
|
+
const client = new RemoteTreeseedAuthClient(new RemoteTreeseedClient(remoteConfig));
|
|
346
|
+
const response = await client.whoAmI();
|
|
347
|
+
return operationResult(this.metadata, {
|
|
348
|
+
hostId: remoteConfig.activeHostId,
|
|
349
|
+
principal: response.payload
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
class RollbackOperation extends BaseOperation {
|
|
354
|
+
async execute(input, context) {
|
|
355
|
+
const scope = typeof input.environment === "string" ? input.environment : null;
|
|
356
|
+
if (scope !== "staging" && scope !== "prod") {
|
|
357
|
+
return failureResult(this.metadata, 'Rollback requires environment "staging" or "prod".');
|
|
358
|
+
}
|
|
359
|
+
const requestedCommit = typeof input.to === "string" ? input.to : null;
|
|
360
|
+
const tenantRoot = context.cwd;
|
|
361
|
+
const deployConfig = loadCliDeployConfig(tenantRoot);
|
|
362
|
+
const target = createPersistentDeployTarget(scope);
|
|
363
|
+
const state = loadDeployState(tenantRoot, deployConfig, { target });
|
|
364
|
+
const history = Array.isArray(state.deploymentHistory) ? state.deploymentHistory : [];
|
|
365
|
+
const latestCommit = typeof state.lastDeployedCommit === "string" ? state.lastDeployedCommit : null;
|
|
366
|
+
const rollbackEntry = requestedCommit ? history.find((entry) => entry.commit === requestedCommit) ?? null : [...history].reverse().find((entry) => typeof entry.commit === "string" && entry.commit !== latestCommit) ?? null;
|
|
367
|
+
const rollbackCommit = requestedCommit ?? (typeof rollbackEntry?.commit === "string" ? rollbackEntry.commit : latestCommit);
|
|
368
|
+
if (!rollbackCommit) {
|
|
369
|
+
return failureResult(this.metadata, `No rollback candidate is recorded for ${scope}.`);
|
|
370
|
+
}
|
|
371
|
+
const gitRoot = repoRoot(tenantRoot);
|
|
372
|
+
const tenantRelativePath = relative(gitRoot, tenantRoot);
|
|
373
|
+
const tempRoot = mkdtempSync(join(tmpdir(), "treeseed-rollback-"));
|
|
374
|
+
const tempTenantRoot = resolve(tempRoot, tenantRelativePath);
|
|
375
|
+
const currentNodeModules = resolve(tenantRoot, "node_modules");
|
|
376
|
+
let finalizedState = null;
|
|
377
|
+
try {
|
|
378
|
+
run("git", ["worktree", "add", "--detach", tempRoot, rollbackCommit], { cwd: gitRoot, capture: true });
|
|
379
|
+
copyTreeseedOperationalState(tenantRoot, tempTenantRoot);
|
|
380
|
+
if (existsSync(currentNodeModules) && !existsSync(resolve(tempTenantRoot, "node_modules"))) {
|
|
381
|
+
symlinkSync(currentNodeModules, resolve(tempTenantRoot, "node_modules"), "dir");
|
|
382
|
+
}
|
|
383
|
+
const { wranglerPath } = ensureGeneratedWranglerConfig(tempTenantRoot, { target });
|
|
384
|
+
const buildResult = spawnSync(process.execPath, [packageScriptPath("tenant-build")], {
|
|
385
|
+
cwd: tempTenantRoot,
|
|
386
|
+
env: contextEnv(context),
|
|
387
|
+
stdio: "inherit"
|
|
388
|
+
});
|
|
389
|
+
if ((buildResult.status ?? 1) !== 0) {
|
|
390
|
+
return failureResult(this.metadata, "Rollback build failed.", { exitCode: buildResult.status ?? 1 });
|
|
391
|
+
}
|
|
392
|
+
const publishResult = spawnSync(process.execPath, [resolveWranglerBin(), "deploy", "--config", wranglerPath], {
|
|
393
|
+
cwd: tempTenantRoot,
|
|
394
|
+
env: contextEnv(context),
|
|
395
|
+
stdio: "inherit"
|
|
396
|
+
});
|
|
397
|
+
if ((publishResult.status ?? 1) !== 0) {
|
|
398
|
+
return failureResult(this.metadata, "Rollback deploy failed.", { exitCode: publishResult.status ?? 1 });
|
|
399
|
+
}
|
|
400
|
+
const previousCommit = process.env.TREESEED_DEPLOY_COMMIT;
|
|
401
|
+
process.env.TREESEED_DEPLOY_COMMIT = rollbackCommit;
|
|
402
|
+
try {
|
|
403
|
+
finalizedState = finalizeDeploymentState(tenantRoot, { target });
|
|
404
|
+
} finally {
|
|
405
|
+
if (previousCommit) process.env.TREESEED_DEPLOY_COMMIT = previousCommit;
|
|
406
|
+
else delete process.env.TREESEED_DEPLOY_COMMIT;
|
|
407
|
+
}
|
|
408
|
+
} finally {
|
|
409
|
+
try {
|
|
410
|
+
run("git", ["worktree", "remove", "--force", tempRoot], { cwd: gitRoot, capture: true });
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return operationResult(this.metadata, {
|
|
415
|
+
scope,
|
|
416
|
+
target: deployTargetLabel(target),
|
|
417
|
+
rollbackCommit,
|
|
418
|
+
rollbackEntry,
|
|
419
|
+
finalizedState
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
class MailpitUpOperation extends BaseOperation {
|
|
424
|
+
async execute(_input, context) {
|
|
425
|
+
if (!dockerIsAvailable()) {
|
|
426
|
+
return failureResult(this.metadata, "Docker is required for Treeseed form email testing.");
|
|
427
|
+
}
|
|
428
|
+
const existing = findRunningMailpitContainer();
|
|
429
|
+
if (existing) {
|
|
430
|
+
return operationResult(this.metadata, { reused: true, container: existing });
|
|
431
|
+
}
|
|
432
|
+
return runNodeScript(this.metadata, "ensure-mailpit", [], context);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
class MailpitDownOperation extends BaseOperation {
|
|
436
|
+
async execute(_input, _context) {
|
|
437
|
+
const stopped = stopKnownMailpitContainers();
|
|
438
|
+
return operationResult(this.metadata, { stopped }, { ok: stopped, exitCode: stopped ? 0 : 1 });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
class MailpitLogsOperation extends BaseOperation {
|
|
442
|
+
async execute(_input, context) {
|
|
443
|
+
return runNodeScript(this.metadata, "logs-mailpit", [], context);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
class DefaultTreeseedOperationsProvider {
|
|
447
|
+
id = "default";
|
|
448
|
+
operations;
|
|
449
|
+
constructor() {
|
|
450
|
+
this.operations = [
|
|
451
|
+
new WorkflowOperation("status"),
|
|
452
|
+
new WorkflowOperation("tasks"),
|
|
453
|
+
new WorkflowOperation("switch", "switch"),
|
|
454
|
+
new WorkflowOperation("save"),
|
|
455
|
+
new WorkflowOperation("close"),
|
|
456
|
+
new WorkflowOperation("stage"),
|
|
457
|
+
new WorkflowOperation("config"),
|
|
458
|
+
new WorkflowOperation("release"),
|
|
459
|
+
new WorkflowOperation("destroy"),
|
|
460
|
+
new WorkflowOperation("dev"),
|
|
461
|
+
new WorkflowOperation("dev:watch", "dev"),
|
|
462
|
+
new InitOperation("init"),
|
|
463
|
+
new TemplateOperation("template"),
|
|
464
|
+
new SyncTemplateOperation("sync"),
|
|
465
|
+
new DoctorOperation("doctor"),
|
|
466
|
+
new AuthLoginOperation("auth:login"),
|
|
467
|
+
new AuthLogoutOperation("auth:logout"),
|
|
468
|
+
new AuthWhoAmIOperation("auth:whoami"),
|
|
469
|
+
new RollbackOperation("rollback"),
|
|
470
|
+
new ScriptOperation("build", "tenant-build"),
|
|
471
|
+
new ScriptOperation("check", "tenant-check"),
|
|
472
|
+
new ScriptOperation("preview", "tenant-astro-command"),
|
|
473
|
+
new ScriptOperation("lint", "workspace-lint"),
|
|
474
|
+
new ScriptOperation("test", "workspace-test"),
|
|
475
|
+
new ScriptOperation("test:unit", "workspace-test-unit"),
|
|
476
|
+
new PreflightOperation("preflight", false),
|
|
477
|
+
new PreflightOperation("auth:check", true),
|
|
478
|
+
new ScriptOperation("test:e2e", "workspace-command-e2e"),
|
|
479
|
+
new ScriptOperation("test:e2e:local", "workspace-command-e2e", ["--mode=local"]),
|
|
480
|
+
new ScriptOperation("test:e2e:staging", "workspace-command-e2e", ["--mode=staging"]),
|
|
481
|
+
new ScriptOperation("test:e2e:full", "workspace-command-e2e", ["--mode=full"]),
|
|
482
|
+
new ScriptOperation("test:release", "workspace-release-verify"),
|
|
483
|
+
new ScriptOperation("test:release:full", "workspace-release-verify", ["--full-smoke"]),
|
|
484
|
+
new ScriptOperation("release:publish:changed", "workspace-publish-changed-packages"),
|
|
485
|
+
new ScriptOperation("astro", "tenant-astro-command"),
|
|
486
|
+
new ScriptOperation("sync:devvars", "sync-dev-vars"),
|
|
487
|
+
new MailpitUpOperation("mailpit:up"),
|
|
488
|
+
new MailpitDownOperation("mailpit:down"),
|
|
489
|
+
new MailpitLogsOperation("mailpit:logs"),
|
|
490
|
+
new ScriptOperation("d1:migrate:local", "tenant-d1-migrate-local"),
|
|
491
|
+
new ScriptOperation("cleanup:markdown", "cleanup-markdown", ["--write"]),
|
|
492
|
+
new ScriptOperation("cleanup:markdown:check", "cleanup-markdown", ["--check"]),
|
|
493
|
+
new ScriptOperation("starlight:patch", "patch-starlight-content-path")
|
|
494
|
+
];
|
|
495
|
+
}
|
|
496
|
+
listOperations() {
|
|
497
|
+
return [...this.operations];
|
|
498
|
+
}
|
|
499
|
+
findOperation(name) {
|
|
500
|
+
if (!name) return null;
|
|
501
|
+
return this.operations.find((operation) => operation.metadata.name === name || operation.metadata.aliases.includes(name)) ?? null;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function createDefaultTreeseedOperationsProvider() {
|
|
505
|
+
return new DefaultTreeseedOperationsProvider();
|
|
506
|
+
}
|
|
507
|
+
function listDefaultOperationMetadata() {
|
|
508
|
+
return TRESEED_OPERATION_SPECS;
|
|
509
|
+
}
|
|
510
|
+
export {
|
|
511
|
+
DefaultTreeseedOperationsProvider,
|
|
512
|
+
createDefaultTreeseedOperationsProvider,
|
|
513
|
+
listDefaultOperationMetadata
|
|
514
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type TreeseedOperationContext, type TreeseedOperationRequest } from '../operations-types.ts';
|
|
2
|
+
export declare class TreeseedOperationsSdk {
|
|
3
|
+
listOperations(): import("../operations-types.ts").TreeseedOperationMetadata[];
|
|
4
|
+
findOperation(name: string | null | undefined): import("../operations-types.ts").TreeseedOperationMetadata | null;
|
|
5
|
+
resolveProvider(cwd?: string): any;
|
|
6
|
+
execute(request: TreeseedOperationRequest, contextOverrides?: Partial<TreeseedOperationContext>): Promise<any>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { loadTreeseedDeployConfig } from "../platform/deploy/config.js";
|
|
2
|
+
import { createDefaultTreeseedOperationsProvider } from "./providers/default.js";
|
|
3
|
+
import { withProcessCwd } from "../operations/services/runtime-tools.js";
|
|
4
|
+
import {
|
|
5
|
+
findTreeseedOperation,
|
|
6
|
+
TRESEED_OPERATION_SPECS
|
|
7
|
+
} from "../operations-registry.js";
|
|
8
|
+
import {
|
|
9
|
+
TreeseedOperationError
|
|
10
|
+
} from "../operations-types.js";
|
|
11
|
+
function defaultContext(overrides = {}) {
|
|
12
|
+
return {
|
|
13
|
+
cwd: overrides.cwd ?? process.cwd(),
|
|
14
|
+
env: overrides.env ?? process.env,
|
|
15
|
+
write: overrides.write,
|
|
16
|
+
spawn: overrides.spawn,
|
|
17
|
+
outputFormat: overrides.outputFormat ?? "human",
|
|
18
|
+
prompt: overrides.prompt,
|
|
19
|
+
confirm: overrides.confirm,
|
|
20
|
+
transport: overrides.transport ?? "sdk"
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function resolveBuiltinProvider(providerId) {
|
|
24
|
+
if (providerId === "default") {
|
|
25
|
+
return createDefaultTreeseedOperationsProvider();
|
|
26
|
+
}
|
|
27
|
+
throw new TreeseedOperationError("operations", "provider_resolution_failed", `Unknown Treeseed operations provider "${providerId}".`);
|
|
28
|
+
}
|
|
29
|
+
class TreeseedOperationsSdk {
|
|
30
|
+
listOperations() {
|
|
31
|
+
return [...TRESEED_OPERATION_SPECS];
|
|
32
|
+
}
|
|
33
|
+
findOperation(name) {
|
|
34
|
+
return findTreeseedOperation(name);
|
|
35
|
+
}
|
|
36
|
+
resolveProvider(cwd = process.cwd()) {
|
|
37
|
+
return withProcessCwd(cwd, () => {
|
|
38
|
+
const deployConfig = loadTreeseedDeployConfig();
|
|
39
|
+
const selectedProviderId = deployConfig.providers.operations ?? "default";
|
|
40
|
+
return resolveBuiltinProvider(selectedProviderId);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async execute(request, contextOverrides = {}) {
|
|
44
|
+
const context = defaultContext(contextOverrides);
|
|
45
|
+
const provider = this.resolveProvider(context.cwd);
|
|
46
|
+
const operation = provider.findOperation(request.operationName);
|
|
47
|
+
if (!operation) {
|
|
48
|
+
throw new TreeseedOperationError(
|
|
49
|
+
request.operationName,
|
|
50
|
+
"validation_failed",
|
|
51
|
+
`Unknown Treeseed operation "${request.operationName}".`,
|
|
52
|
+
{ exitCode: 1 }
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return operation.execute(request.input ?? {}, context);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
TreeseedOperationsSdk
|
|
60
|
+
};
|