@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.
Files changed (237) hide show
  1. package/README.md +97 -506
  2. package/dist/{src/cli-tools.d.ts → cli-tools.d.ts} +1 -1
  3. package/dist/cli-tools.js +5 -3
  4. package/dist/{src/content-store.d.ts → content-store.d.ts} +3 -2
  5. package/dist/content-store.js +52 -20
  6. package/dist/{src/d1-store.d.ts → d1-store.d.ts} +62 -1
  7. package/dist/d1-store.js +625 -65
  8. package/dist/field-aliases.d.ts +11 -0
  9. package/dist/field-aliases.js +41 -0
  10. package/dist/graph/build.d.ts +19 -0
  11. package/dist/graph/build.js +949 -0
  12. package/dist/graph/dsl.d.ts +2 -0
  13. package/dist/graph/dsl.js +243 -0
  14. package/dist/graph/query.d.ts +47 -0
  15. package/dist/graph/query.js +447 -0
  16. package/dist/graph/ranking.d.ts +3 -0
  17. package/dist/graph/ranking.js +483 -0
  18. package/dist/graph/schema.d.ts +142 -0
  19. package/dist/graph/schema.js +133 -0
  20. package/dist/graph.d.ts +52 -0
  21. package/dist/graph.js +133 -0
  22. package/dist/index.d.ts +28 -0
  23. package/dist/index.js +91 -2
  24. package/dist/model-registry.d.ts +8 -0
  25. package/dist/model-registry.js +351 -25
  26. package/dist/operations/providers/default.d.ts +10 -0
  27. package/dist/operations/providers/default.js +514 -0
  28. package/dist/operations/runtime.d.ts +7 -0
  29. package/dist/operations/runtime.js +60 -0
  30. package/dist/operations/services/config-runtime.d.ts +269 -0
  31. package/dist/operations/services/config-runtime.js +1397 -0
  32. package/dist/operations/services/d1-migration.d.ts +6 -0
  33. package/dist/operations/services/d1-migration.js +89 -0
  34. package/dist/operations/services/deploy.d.ts +371 -0
  35. package/dist/operations/services/deploy.js +981 -0
  36. package/dist/operations/services/git-workflow.d.ts +49 -0
  37. package/dist/operations/services/git-workflow.js +218 -0
  38. package/dist/operations/services/github-automation.d.ts +156 -0
  39. package/dist/operations/services/github-automation.js +256 -0
  40. package/dist/operations/services/local-dev.d.ts +9 -0
  41. package/dist/operations/services/local-dev.js +106 -0
  42. package/dist/operations/services/mailpit-runtime.d.ts +4 -0
  43. package/dist/operations/services/mailpit-runtime.js +59 -0
  44. package/dist/operations/services/railway-deploy.d.ts +53 -0
  45. package/dist/operations/services/railway-deploy.js +123 -0
  46. package/dist/operations/services/runtime-paths.d.ts +19 -0
  47. package/dist/operations/services/runtime-paths.js +54 -0
  48. package/dist/operations/services/runtime-tools.d.ts +117 -0
  49. package/dist/operations/services/runtime-tools.js +358 -0
  50. package/dist/operations/services/save-deploy-preflight.d.ts +34 -0
  51. package/dist/operations/services/save-deploy-preflight.js +76 -0
  52. package/dist/operations/services/template-registry.d.ts +88 -0
  53. package/dist/operations/services/template-registry.js +407 -0
  54. package/dist/operations/services/watch-dev.d.ts +21 -0
  55. package/dist/operations/services/watch-dev.js +284 -0
  56. package/dist/operations/services/workspace-preflight.d.ts +40 -0
  57. package/dist/operations/services/workspace-preflight.js +165 -0
  58. package/dist/operations/services/workspace-save.d.ts +42 -0
  59. package/dist/operations/services/workspace-save.js +235 -0
  60. package/dist/operations/services/workspace-tools.d.ts +16 -0
  61. package/dist/operations/services/workspace-tools.js +270 -0
  62. package/dist/operations-registry.d.ts +5 -0
  63. package/dist/operations-registry.js +68 -0
  64. package/dist/operations-types.d.ts +71 -0
  65. package/dist/operations-types.js +17 -0
  66. package/dist/operations.d.ts +6 -0
  67. package/dist/operations.js +16 -0
  68. package/dist/platform/books-data.d.ts +1 -0
  69. package/dist/platform/books-data.js +1 -0
  70. package/dist/platform/contracts.d.ts +158 -0
  71. package/dist/platform/contracts.js +0 -0
  72. package/dist/platform/deploy/config.d.ts +4 -0
  73. package/dist/platform/deploy/config.js +222 -0
  74. package/dist/platform/deploy-config.d.ts +1 -0
  75. package/dist/platform/deploy-config.js +1 -0
  76. package/dist/platform/deploy-runtime.d.ts +18 -0
  77. package/dist/platform/deploy-runtime.js +78 -0
  78. package/dist/platform/env.yaml +394 -0
  79. package/dist/platform/environment.d.ts +130 -0
  80. package/dist/platform/environment.js +331 -0
  81. package/dist/platform/plugin.d.ts +2 -0
  82. package/dist/platform/plugin.js +4 -0
  83. package/dist/platform/plugins/constants.d.ts +22 -0
  84. package/dist/platform/plugins/constants.js +29 -0
  85. package/dist/platform/plugins/plugin.d.ts +51 -0
  86. package/dist/platform/plugins/plugin.js +6 -0
  87. package/dist/platform/plugins/runtime.d.ts +35 -0
  88. package/dist/platform/plugins/runtime.js +161 -0
  89. package/dist/platform/plugins.d.ts +6 -0
  90. package/dist/platform/plugins.js +38 -0
  91. package/dist/platform/site-config-schema.js +1 -0
  92. package/dist/platform/tenant/config.d.ts +9 -0
  93. package/dist/platform/tenant/config.js +154 -0
  94. package/dist/platform/tenant/runtime-config.d.ts +4 -0
  95. package/dist/platform/tenant/runtime-config.js +20 -0
  96. package/dist/platform/tenant-config.d.ts +1 -0
  97. package/dist/platform/tenant-config.js +1 -0
  98. package/dist/platform/utils/books-data.d.ts +29 -0
  99. package/dist/platform/utils/books-data.js +82 -0
  100. package/dist/platform/utils/site-config-schema.js +321 -0
  101. package/dist/remote.d.ts +175 -0
  102. package/dist/remote.js +202 -0
  103. package/dist/runtime.js +35 -22
  104. package/dist/scripts/aggregate-book.js +121 -0
  105. package/dist/scripts/build-dist.js +54 -13
  106. package/dist/scripts/build-tenant-worker.js +36 -0
  107. package/dist/scripts/cleanup-markdown.js +373 -0
  108. package/dist/scripts/cli-test-fixtures.js +48 -0
  109. package/dist/scripts/config-treeseed.js +95 -0
  110. package/dist/scripts/ensure-mailpit.js +29 -0
  111. package/dist/scripts/local-dev.js +129 -0
  112. package/dist/scripts/logs-mailpit.js +2 -0
  113. package/dist/scripts/patch-starlight-content-path.js +172 -0
  114. package/dist/scripts/release-verify.js +34 -6
  115. package/dist/scripts/run-fixture-astro-command.js +18 -0
  116. package/dist/scripts/scaffold-site.js +65 -0
  117. package/dist/scripts/stop-mailpit.js +5 -0
  118. package/dist/scripts/sync-dev-vars.js +6 -0
  119. package/dist/scripts/sync-template.js +20 -0
  120. package/dist/scripts/template-catalog.test.js +100 -0
  121. package/dist/scripts/template-command.js +31 -0
  122. package/dist/scripts/tenant-astro-command.js +3 -0
  123. package/dist/scripts/tenant-build.js +16 -0
  124. package/dist/scripts/tenant-check.js +7 -0
  125. package/dist/scripts/tenant-d1-migrate-local.js +11 -0
  126. package/dist/scripts/tenant-deploy.js +180 -0
  127. package/dist/scripts/tenant-destroy.js +104 -0
  128. package/dist/scripts/tenant-dev.js +171 -0
  129. package/dist/scripts/tenant-lint.js +4 -0
  130. package/dist/scripts/tenant-test.js +4 -0
  131. package/dist/scripts/test-cloudflare-local.js +212 -0
  132. package/dist/scripts/test-scaffold.js +314 -0
  133. package/dist/scripts/test-smoke.js +71 -13
  134. package/dist/scripts/treeseed-assert-release-tag-version.js +21 -0
  135. package/dist/scripts/treeseed-build-dist.js +134 -0
  136. package/dist/scripts/treeseed-publish-package.js +19 -0
  137. package/dist/scripts/treeseed-release-verify.js +131 -0
  138. package/dist/scripts/treeseed-run-ts.js +45 -0
  139. package/dist/scripts/validate-templates.js +6 -0
  140. package/dist/scripts/verify-driver.js +29 -0
  141. package/dist/scripts/workflow-commands.test.js +39 -0
  142. package/dist/scripts/workspace-close.js +24 -0
  143. package/dist/scripts/workspace-command-e2e.js +718 -0
  144. package/dist/scripts/workspace-lint.js +9 -0
  145. package/dist/scripts/workspace-preflight.js +22 -0
  146. package/dist/scripts/workspace-publish-changed-packages.js +16 -0
  147. package/dist/scripts/workspace-release-verify.js +81 -0
  148. package/dist/scripts/workspace-release.js +42 -0
  149. package/dist/scripts/workspace-save.js +124 -0
  150. package/dist/scripts/workspace-start-warning.js +3 -0
  151. package/dist/scripts/workspace-start.js +71 -0
  152. package/dist/scripts/workspace-test-unit.js +4 -0
  153. package/dist/scripts/workspace-test.js +11 -0
  154. package/dist/sdk-fields.d.ts +11 -0
  155. package/dist/sdk-fields.js +169 -0
  156. package/dist/sdk-filters.d.ts +4 -0
  157. package/dist/sdk-filters.js +12 -15
  158. package/dist/sdk-types.d.ts +796 -0
  159. package/dist/sdk-types.js +7 -1
  160. package/dist/sdk-version.d.ts +2 -0
  161. package/dist/sdk-version.js +42 -0
  162. package/dist/sdk.d.ts +215 -0
  163. package/dist/sdk.js +235 -11
  164. package/dist/stores/cursor-store.js +9 -3
  165. package/dist/stores/lease-store.js +8 -2
  166. package/dist/{src/stores → stores}/message-store.d.ts +1 -1
  167. package/dist/stores/message-store.js +27 -3
  168. package/dist/stores/operational-store.d.ts +24 -0
  169. package/dist/stores/operational-store.js +279 -0
  170. package/dist/stores/run-store.js +8 -1
  171. package/dist/stores/subscription-store.js +7 -5
  172. package/dist/template-catalog.d.ts +13 -0
  173. package/dist/template-catalog.js +141 -0
  174. package/dist/treeseed/services/compose.yml +7 -0
  175. package/dist/treeseed/template-catalog/catalog.fixture.json +55 -0
  176. package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.d.ts +2 -0
  177. package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.ts +3 -0
  178. package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +32 -0
  179. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +40 -0
  180. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/empty/.gitkeep +1 -0
  181. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/knowledge/handbook/index.mdx +11 -0
  182. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/pages/welcome.mdx +11 -0
  183. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.d.ts +1 -0
  184. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.ts +3 -0
  185. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/env.yaml +1 -0
  186. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +19 -0
  187. package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +26 -0
  188. package/dist/treeseed/template-catalog/templates/starter-basic/template/tsconfig.json +9 -0
  189. package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +90 -0
  190. package/dist/utils/agents/contracts/messages.d.ts +88 -0
  191. package/dist/utils/agents/contracts/messages.js +138 -0
  192. package/dist/utils/agents/contracts/run.d.ts +20 -0
  193. package/dist/utils/agents/contracts/run.js +0 -0
  194. package/dist/utils/agents/runtime-types.d.ts +117 -0
  195. package/dist/utils/agents/runtime-types.js +4 -0
  196. package/dist/verification.d.ts +20 -0
  197. package/dist/verification.js +98 -0
  198. package/dist/workflow/operations.d.ts +396 -0
  199. package/dist/workflow/operations.js +841 -0
  200. package/dist/workflow-state.d.ts +56 -0
  201. package/dist/workflow-state.js +195 -0
  202. package/dist/workflow-support.d.ts +9 -0
  203. package/dist/workflow-support.js +176 -0
  204. package/dist/workflow.d.ts +111 -0
  205. package/dist/workflow.js +97 -0
  206. package/package.json +111 -5
  207. package/scripts/verify-driver.mjs +29 -0
  208. package/dist/scripts/.ts-run-1775630384291-crtqr3izsa.js +0 -22
  209. package/dist/scripts/.ts-run-1775630388025-vnjle0z75a.js +0 -129
  210. package/dist/scripts/assert-release-tag-version.d.ts +0 -1
  211. package/dist/scripts/build-dist.d.ts +0 -1
  212. package/dist/scripts/fixture-tools.d.ts +0 -5
  213. package/dist/scripts/package-tools.d.ts +0 -15
  214. package/dist/scripts/publish-package.d.ts +0 -1
  215. package/dist/scripts/release-verify.d.ts +0 -1
  216. package/dist/scripts/test-smoke.d.ts +0 -1
  217. package/dist/src/index.d.ts +0 -6
  218. package/dist/src/model-registry.d.ts +0 -4
  219. package/dist/src/sdk-filters.d.ts +0 -4
  220. package/dist/src/sdk-types.d.ts +0 -285
  221. package/dist/src/sdk.d.ts +0 -109
  222. package/dist/test/test-fixture.d.ts +0 -1
  223. package/dist/test/utils/envelopes.test.d.ts +0 -1
  224. package/dist/test/utils/sdk.test.d.ts +0 -1
  225. package/dist/vitest.config.d.ts +0 -2
  226. /package/dist/{src/frontmatter.d.ts → frontmatter.d.ts} +0 -0
  227. /package/dist/{src/git-runtime.d.ts → git-runtime.d.ts} +0 -0
  228. /package/dist/{src/runtime.d.ts → runtime.d.ts} +0 -0
  229. /package/dist/{src/stores → stores}/cursor-store.d.ts +0 -0
  230. /package/dist/{src/stores → stores}/envelopes.d.ts +0 -0
  231. /package/dist/{src/stores → stores}/helpers.d.ts +0 -0
  232. /package/dist/{src/stores → stores}/lease-store.d.ts +0 -0
  233. /package/dist/{src/stores → stores}/run-store.d.ts +0 -0
  234. /package/dist/{src/stores → stores}/subscription-store.d.ts +0 -0
  235. /package/dist/{src/types → types}/agents.d.ts +0 -0
  236. /package/dist/{src/types → types}/cloudflare.d.ts +0 -0
  237. /package/dist/{src/wrangler-d1.d.ts → wrangler-d1.d.ts} +0 -0
@@ -0,0 +1,21 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
5
+ const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
6
+ const packageVersion = packageJson.version;
7
+ const tagName = process.argv[2] || process.env.GITHUB_REF_NAME;
8
+ if (!tagName) {
9
+ console.error('Release tag validation requires a tag name argument or GITHUB_REF_NAME.');
10
+ process.exit(1);
11
+ }
12
+ if (!/^\d+\.\d+\.\d+$/.test(tagName)) {
13
+ console.error(`Release tag "${tagName}" must use plain semver format "x.y.z".`);
14
+ process.exit(1);
15
+ }
16
+ const taggedVersion = tagName;
17
+ if (taggedVersion !== packageVersion) {
18
+ console.error(`Release tag version "${taggedVersion}" does not match @treeseed/cli version "${packageVersion}".`);
19
+ process.exit(1);
20
+ }
21
+ console.log(`Release tag "${tagName}" matches @treeseed/cli version "${packageVersion}".`);
@@ -0,0 +1,134 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, chmodSync } from 'node:fs';
2
+ import { basename, dirname, extname, join, relative, resolve } from 'node:path';
3
+ import { build } from 'esbuild';
4
+ import ts from 'typescript';
5
+ import { packageRoot } from './package-tools.js';
6
+ const srcRoot = resolve(packageRoot, 'src');
7
+ const scriptsRoot = resolve(packageRoot, 'scripts');
8
+ const distRoot = resolve(packageRoot, 'dist');
9
+ const templateCatalogSourceRoot = resolve(srcRoot, 'template-catalog');
10
+ const COPY_EXTENSIONS = new Set(['.json', '.md']);
11
+ function walkFiles(root) {
12
+ const files = [];
13
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
14
+ const fullPath = join(root, entry.name);
15
+ if (entry.isDirectory())
16
+ files.push(...walkFiles(fullPath));
17
+ else
18
+ files.push(fullPath);
19
+ }
20
+ return files;
21
+ }
22
+ function ensureDir(filePath) {
23
+ mkdirSync(dirname(filePath), { recursive: true });
24
+ }
25
+ function rewriteRuntimeSpecifiers(contents, outputFile = null) {
26
+ let rewritten = contents
27
+ .replace(/(['"`])(\.[^'"`\n]+)\.(mjs|ts)\1/g, '$1$2.js$1')
28
+ .replace(/(['"`])\.\.\/src\//g, '$1../');
29
+ if (!outputFile || outputFile.includes(`${resolve(distRoot, 'scripts')}`)) {
30
+ return rewritten;
31
+ }
32
+ rewritten = rewritten.replace(/(['"`])((?:\.\.\/)+scripts\/([^'"`\n]+))\1/g, (_match, quote, _specifier, scriptPath) => {
33
+ const targetPath = resolve(distRoot, 'scripts', scriptPath);
34
+ let relativeSpecifier = relative(dirname(outputFile), targetPath).replaceAll('\\', '/');
35
+ if (!relativeSpecifier.startsWith('.')) {
36
+ relativeSpecifier = `./${relativeSpecifier}`;
37
+ }
38
+ return `${quote}${relativeSpecifier}${quote}`;
39
+ });
40
+ return rewritten;
41
+ }
42
+ function isTypeScriptSource(filePath) {
43
+ return filePath.endsWith('.ts') && !filePath.endsWith('.d.js');
44
+ }
45
+ async function compileModule(filePath, sourceRoot, outputRoot) {
46
+ const relativePath = relative(sourceRoot, filePath);
47
+ const outputFile = resolve(outputRoot, relativePath.replace(/\.(mjs|ts)$/u, '.js'));
48
+ ensureDir(outputFile);
49
+ await build({
50
+ entryPoints: [filePath],
51
+ outfile: outputFile,
52
+ platform: 'node',
53
+ format: 'esm',
54
+ bundle: false,
55
+ logLevel: 'silent',
56
+ });
57
+ const builtSource = readFileSync(outputFile, 'utf8');
58
+ writeFileSync(outputFile, rewriteRuntimeSpecifiers(builtSource, outputFile), 'utf8');
59
+ }
60
+ function copyAsset(filePath, sourceRoot, outputRoot) {
61
+ const outputFile = resolve(outputRoot, relative(sourceRoot, filePath));
62
+ ensureDir(outputFile);
63
+ copyFileSync(filePath, outputFile);
64
+ if (outputFile.endsWith('.d.js')) {
65
+ writeFileSync(outputFile, rewriteRuntimeSpecifiers(readFileSync(outputFile, 'utf8')), 'utf8');
66
+ }
67
+ }
68
+ function copyAssetTree(sourceRoot, outputRoot) {
69
+ for (const filePath of walkFiles(sourceRoot)) {
70
+ copyAsset(filePath, sourceRoot, outputRoot);
71
+ }
72
+ }
73
+ function transpileScript(filePath) {
74
+ if (basename(filePath).startsWith('.ts-run-')) {
75
+ return;
76
+ }
77
+ const source = readFileSync(filePath, 'utf8');
78
+ const relativePath = relative(scriptsRoot, filePath);
79
+ const outputFile = resolve(distRoot, 'scripts', relativePath.replace(/\.(mjs|ts)$/u, '.js'));
80
+ const transformed = extname(filePath) === '.ts'
81
+ ? ts.transpileModule(source, {
82
+ compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 },
83
+ }).outputText
84
+ : source;
85
+ ensureDir(outputFile);
86
+ writeFileSync(outputFile, rewriteRuntimeSpecifiers(transformed, outputFile), 'utf8');
87
+ chmodSync(outputFile, 0o755);
88
+ }
89
+ function emitDeclarations() {
90
+ const rootNames = walkFiles(srcRoot).filter(isTypeScriptSource);
91
+ const program = ts.createProgram({
92
+ rootNames,
93
+ options: {
94
+ allowImportingTsExtensions: true,
95
+ target: ts.ScriptTarget.ES2022,
96
+ module: ts.ModuleKind.ESNext,
97
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
98
+ strict: true,
99
+ types: ['node'],
100
+ declaration: true,
101
+ emitDeclarationOnly: true,
102
+ declarationDir: distRoot,
103
+ rootDir: srcRoot,
104
+ noEmit: false,
105
+ },
106
+ });
107
+ const result = program.emit();
108
+ if (result.emitSkipped) {
109
+ throw new Error('Declaration build failed.');
110
+ }
111
+ }
112
+ rmSync(distRoot, { recursive: true, force: true });
113
+ for (const filePath of walkFiles(srcRoot)) {
114
+ if (filePath.startsWith(`${templateCatalogSourceRoot}/`)) {
115
+ continue;
116
+ }
117
+ const extension = extname(filePath);
118
+ if (isTypeScriptSource(filePath))
119
+ await compileModule(filePath, srcRoot, distRoot);
120
+ else if (COPY_EXTENSIONS.has(extension))
121
+ copyAsset(filePath, srcRoot, distRoot);
122
+ }
123
+ if (existsSync(templateCatalogSourceRoot)) {
124
+ copyAssetTree(templateCatalogSourceRoot, resolve(distRoot, 'template-catalog'));
125
+ }
126
+ for (const filePath of walkFiles(scriptsRoot)) {
127
+ const extension = extname(filePath);
128
+ if (extension === '.ts' || extension === '.mjs')
129
+ transpileScript(filePath);
130
+ }
131
+ emitDeclarations();
132
+ if (existsSync(resolve(packageRoot, 'README.md'))) {
133
+ copyFileSync(resolve(packageRoot, 'README.md'), resolve(distRoot, '..', 'README.md'));
134
+ }
@@ -0,0 +1,19 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
5
+ const extraArgs = process.argv.slice(2);
6
+ const npmArgs = ['publish', '.', '--access', 'public'];
7
+ if (process.env.GITHUB_ACTIONS === 'true')
8
+ npmArgs.push('--provenance');
9
+ npmArgs.push(...extraArgs);
10
+ const result = spawnSync('npm', npmArgs, {
11
+ cwd: packageRoot,
12
+ stdio: 'inherit',
13
+ env: process.env,
14
+ });
15
+ if (result.error) {
16
+ console.error(result.error.message);
17
+ process.exit(1);
18
+ }
19
+ process.exit(result.status ?? 1);
@@ -0,0 +1,131 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
2
+ import { mkdtempSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, extname, join, resolve } from 'node:path';
5
+ import { spawnSync } from 'node:child_process';
6
+ import { agentPackageRoot, corePackageRoot, packageRoot, sdkPackageRoot } from '../operations/services/runtime-tools.js';
7
+ const textExtensions = new Set(['.js', '.ts', '.mjs', '.cjs', '.d.js', '.json', '.md']);
8
+ const forbiddenPatterns = [
9
+ /['"`]workspace:[^'"`\n]+['"`]/,
10
+ /['"`](?:\.\.\/|\.\/)[^'"`\n]*src\/[^'"`\n]*\.(?:[cm]?js|ts|tsx|json|astro|css)['"`]/,
11
+ /['"`][^'"`\n]*\/packages\/[^'"`\n]*\/src\/[^'"`\n]*['"`]/,
12
+ ];
13
+ function run(command, args, cwd = packageRoot, capture = false) {
14
+ const result = spawnSync(command, args, {
15
+ cwd,
16
+ stdio: capture ? 'pipe' : 'inherit',
17
+ encoding: 'utf8',
18
+ env: process.env,
19
+ });
20
+ if (result.status !== 0) {
21
+ throw new Error(result.stderr?.trim() || result.stdout?.trim() || `${command} ${args.join(' ')} failed`);
22
+ }
23
+ return (result.stdout ?? '').trim();
24
+ }
25
+ function walkFiles(root) {
26
+ const files = [];
27
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
28
+ const fullPath = join(root, entry.name);
29
+ if (entry.isDirectory()) {
30
+ files.push(...walkFiles(fullPath));
31
+ continue;
32
+ }
33
+ files.push(fullPath);
34
+ }
35
+ return files;
36
+ }
37
+ function scanDirectory(root) {
38
+ for (const filePath of walkFiles(root)) {
39
+ if (!textExtensions.has(extname(filePath)))
40
+ continue;
41
+ const source = readFileSync(filePath, 'utf8');
42
+ for (const pattern of forbiddenPatterns) {
43
+ if (pattern.test(source)) {
44
+ throw new Error(`${filePath} contains forbidden publish reference matching ${pattern}.`);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ function resolveNodeModulesRoot() {
50
+ let current = packageRoot;
51
+ while (true) {
52
+ const candidate = resolve(current, 'node_modules');
53
+ try {
54
+ readdirSync(candidate);
55
+ return candidate;
56
+ }
57
+ catch {
58
+ }
59
+ const parent = resolve(current, '..');
60
+ if (parent === current)
61
+ break;
62
+ current = parent;
63
+ }
64
+ throw new Error(`Unable to locate node_modules for ${packageRoot}.`);
65
+ }
66
+ function mirrorDependencies(tempRoot) {
67
+ const sharedNodeModules = resolveNodeModulesRoot();
68
+ for (const entry of readdirSync(sharedNodeModules, { withFileTypes: true })) {
69
+ if (entry.name === '.bin') {
70
+ continue;
71
+ }
72
+ if (entry.name === '@treeseed') {
73
+ const sourceScopeRoot = resolve(sharedNodeModules, entry.name);
74
+ const targetScopeRoot = resolve(tempRoot, 'node_modules', entry.name);
75
+ mkdirSync(targetScopeRoot, { recursive: true });
76
+ for (const scopedEntry of readdirSync(sourceScopeRoot, { withFileTypes: true })) {
77
+ if (scopedEntry.name === 'cli') {
78
+ continue;
79
+ }
80
+ const targetPath = resolve(targetScopeRoot, scopedEntry.name);
81
+ symlinkSync(resolve(sourceScopeRoot, scopedEntry.name), targetPath, scopedEntry.isDirectory() ? 'dir' : 'file');
82
+ }
83
+ continue;
84
+ }
85
+ const targetPath = resolve(tempRoot, 'node_modules', entry.name);
86
+ mkdirSync(dirname(targetPath), { recursive: true });
87
+ symlinkSync(resolve(sharedNodeModules, entry.name), targetPath, entry.isDirectory() ? 'dir' : 'file');
88
+ }
89
+ }
90
+ function pack(root, fallbackName) {
91
+ const output = run('npm', ['pack', '--silent', '--ignore-scripts'], root, true);
92
+ const filename = output
93
+ .split('\n')
94
+ .map((line) => line.trim())
95
+ .filter(Boolean)
96
+ .at(-1) ?? fallbackName;
97
+ return resolve(root, filename);
98
+ }
99
+ function installPackagedPackage(extractRoot, tempRoot, tarballPath, folderName) {
100
+ mkdirSync(resolve(tempRoot, 'node_modules', '@treeseed'), { recursive: true });
101
+ run('tar', ['-xzf', tarballPath, '-C', extractRoot]);
102
+ run('cp', ['-R', resolve(extractRoot, 'package'), resolve(tempRoot, 'node_modules', '@treeseed', folderName)]);
103
+ rmSync(resolve(extractRoot, 'package'), { recursive: true, force: true });
104
+ }
105
+ function hasWorkspacePackageSource(root) {
106
+ return root !== packageRoot && existsSync(resolve(root, 'scripts'));
107
+ }
108
+ run('npm', ['run', 'build']);
109
+ scanDirectory(resolve(packageRoot, 'dist'));
110
+ run('npm', ['test']);
111
+ if (hasWorkspacePackageSource(sdkPackageRoot) && hasWorkspacePackageSource(corePackageRoot) && hasWorkspacePackageSource(agentPackageRoot)) {
112
+ run('npm', ['run', 'test:scaffold']);
113
+ }
114
+ else {
115
+ console.log('Skipping scaffold verification because local sdk/core/agent package sources are not available.');
116
+ }
117
+ const stageRoot = mkdtempSync(join(tmpdir(), 'treeseed-cli-release-'));
118
+ const extractRoot = resolve(stageRoot, 'extract');
119
+ const installRoot = resolve(stageRoot, 'install');
120
+ try {
121
+ mkdirSync(extractRoot, { recursive: true });
122
+ const cliTarball = pack(packageRoot, 'treeseed-cli.tgz');
123
+ mirrorDependencies(installRoot);
124
+ installPackagedPackage(extractRoot, installRoot, cliTarball, 'cli');
125
+ writeFileSync(resolve(installRoot, 'package.json'), `${JSON.stringify({ name: 'treeseed-cli-smoke', private: true, type: 'module' }, null, 2)}\n`, 'utf8');
126
+ run(process.execPath, ['node_modules/@treeseed/cli/dist/cli/main.js', '--help'], installRoot);
127
+ console.log('CLI packed-install bin smoke passed.');
128
+ }
129
+ finally {
130
+ rmSync(stageRoot, { recursive: true, force: true });
131
+ }
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { build } from 'esbuild';
4
+ import { readFileSync, rmSync, writeFileSync } from 'node:fs';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { pathToFileURL } from 'node:url';
7
+
8
+ const [, , entryArg, ...scriptArgs] = process.argv;
9
+
10
+ if (!entryArg) {
11
+ console.error('Usage: node ./scripts/run-ts.mjs <entry.ts> [...args]');
12
+ process.exit(1);
13
+ }
14
+
15
+ const cwd = process.cwd();
16
+ const entryPath = resolve(cwd, entryArg);
17
+ const outfile = resolve(
18
+ dirname(entryPath),
19
+ `.ts-run-${Date.now()}-${Math.random().toString(36).slice(2)}.js`,
20
+ );
21
+
22
+ try {
23
+ await build({
24
+ entryPoints: [entryPath],
25
+ outfile,
26
+ bundle: true,
27
+ format: 'esm',
28
+ platform: 'node',
29
+ packages: 'external',
30
+ sourcemap: 'inline',
31
+ logLevel: 'silent',
32
+ });
33
+
34
+ const builtSource = readFileSync(outfile, 'utf8');
35
+ writeFileSync(
36
+ outfile,
37
+ builtSource.replace(/(['"`])(\.[^'"`\n]+)\.ts\1/g, '$1$2.js$1'),
38
+ 'utf8',
39
+ );
40
+
41
+ process.argv = [process.argv[0] ?? 'node', entryPath, ...scriptArgs];
42
+ await import(pathToFileURL(outfile).href);
43
+ } finally {
44
+ rmSync(outfile, { force: true });
45
+ }
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { validateAllTemplateDefinitions } from '../operations/services/template-registry.js';
3
+ const definitions = await validateAllTemplateDefinitions({
4
+ writeWarning: (message) => console.warn(message),
5
+ });
6
+ console.log(`Validated ${definitions.length} template definition${definitions.length === 1 ? '' : 's'}.`);
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync } from 'node:fs';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const scriptRoot = dirname(fileURLToPath(import.meta.url));
9
+ const packageRoot = resolve(scriptRoot, '..');
10
+ const sourceRunner = resolve(packageRoot, 'scripts', 'run-ts.mjs');
11
+ const sourceEntry = resolve(packageRoot, 'src', 'verification.ts');
12
+ const publishedEntry = resolve(packageRoot, 'dist', 'verification.js');
13
+
14
+ if (existsSync(sourceRunner) && existsSync(sourceEntry)) {
15
+ const result = spawnSync(process.execPath, [sourceRunner, sourceEntry], {
16
+ cwd: process.cwd(),
17
+ env: process.env,
18
+ stdio: 'inherit',
19
+ });
20
+ process.exit(result.status ?? 1);
21
+ }
22
+
23
+ if (existsSync(publishedEntry)) {
24
+ const { runTreeseedVerifyDriver } = await import('../dist/verification.js');
25
+ process.exit(runTreeseedVerifyDriver({ packageRoot: process.cwd() }));
26
+ }
27
+
28
+ process.stderr.write(`Unable to locate Treeseed SDK verification runtime from ${packageRoot}.\n`);
29
+ process.exit(1);
@@ -0,0 +1,39 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {
4
+ createBranchPreviewDeployTarget,
5
+ createPersistentDeployTarget,
6
+ deployTargetLabel,
7
+ loadDeployState,
8
+ } from '../dist/scripts/deploy-lib.js';
9
+ import { renderDeployWorkflow } from '../dist/scripts/github-automation-lib.js';
10
+ import { incrementVersion } from '../dist/scripts/workspace-save-lib.js';
11
+ import { makeTenantRoot } from './cli-test-fixtures.js';
12
+
13
+ test('persistent and branch targets produce distinct labels', () => {
14
+ assert.equal(deployTargetLabel(createPersistentDeployTarget('staging')), 'staging');
15
+ assert.equal(deployTargetLabel(createBranchPreviewDeployTarget('feature/one')), 'branch:feature/one');
16
+ });
17
+
18
+ test('branch preview state derives branch-specific worker names', () => {
19
+ const tenantRoot = makeTenantRoot();
20
+ const deployConfig = {
21
+ cloudflare: { accountId: 'fixture-cloudflare-account-id', workerName: 'treeseed-working-site' },
22
+ };
23
+ const state = loadDeployState(tenantRoot, deployConfig, { target: createBranchPreviewDeployTarget('feature/preview') });
24
+ assert.match(state.workerName, /^treeseed-working-site-feature-preview/);
25
+ assert.equal(state.previewEnabled, true);
26
+ });
27
+
28
+ test('deploy workflow targets staging and main branches', () => {
29
+ const workflow = renderDeployWorkflow({ workingDirectory: '.' });
30
+ assert.match(workflow, /- staging/);
31
+ assert.match(workflow, /- main/);
32
+ assert.match(workflow, /--environment \$\{\{ github\.ref_name == 'main' && 'prod' \|\| 'staging' \}\}/);
33
+ });
34
+
35
+ test('version bump utility supports major, minor, and patch', () => {
36
+ assert.equal(incrementVersion('1.2.3', 'patch'), '1.2.4');
37
+ assert.equal(incrementVersion('1.2.3', 'minor'), '1.3.0');
38
+ assert.equal(incrementVersion('1.2.3', 'major'), '2.0.0');
39
+ });
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { applyTreeseedEnvironmentToProcess } from '../operations/services/config-runtime.js';
3
+ import { cleanupDestroyedState, createBranchPreviewDeployTarget, destroyCloudflareResources, loadDeployState, printDestroySummary, validateDestroyPrerequisites, } from '../operations/services/deploy.js';
4
+ import { assertFeatureBranch, deleteLocalBranch, deleteRemoteBranch, mergeCurrentBranchIntoStaging, } from '../operations/services/git-workflow.js';
5
+ import { loadCliDeployConfig } from '../operations/services/runtime-tools.js';
6
+ import { runWorkspaceSavePreflight } from '../operations/services/save-deploy-preflight.js';
7
+ const tenantRoot = process.cwd();
8
+ const featureBranch = assertFeatureBranch(tenantRoot);
9
+ const previewTarget = createBranchPreviewDeployTarget(featureBranch);
10
+ const deployConfig = loadCliDeployConfig(tenantRoot);
11
+ const previewState = loadDeployState(tenantRoot, deployConfig, { target: previewTarget });
12
+ runWorkspaceSavePreflight({ cwd: tenantRoot });
13
+ const repoDir = mergeCurrentBranchIntoStaging(tenantRoot, featureBranch);
14
+ if (previewState.readiness?.initialized) {
15
+ applyTreeseedEnvironmentToProcess({ tenantRoot, scope: 'staging', override: true });
16
+ validateDestroyPrerequisites(tenantRoot, { requireRemote: true });
17
+ const result = destroyCloudflareResources(tenantRoot, { target: previewTarget });
18
+ printDestroySummary(result);
19
+ }
20
+ cleanupDestroyedState(tenantRoot, { target: previewTarget });
21
+ deleteRemoteBranch(repoDir, featureBranch);
22
+ deleteLocalBranch(repoDir, featureBranch);
23
+ console.log('Treeseed close completed successfully.');
24
+ console.log(`Merged ${featureBranch} into staging and removed branch artifacts.`);