@treeseed/cli 0.1.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +27 -26
  2. package/dist/cli/handlers/auth-login.d.ts +2 -0
  3. package/dist/cli/handlers/auth-login.js +67 -0
  4. package/dist/cli/handlers/auth-logout.d.ts +2 -0
  5. package/dist/cli/handlers/auth-logout.js +20 -0
  6. package/dist/cli/handlers/auth-whoami.d.ts +2 -0
  7. package/dist/cli/handlers/auth-whoami.js +24 -0
  8. package/dist/cli/handlers/close.js +19 -53
  9. package/dist/cli/handlers/config.js +33 -53
  10. package/dist/cli/handlers/destroy.js +34 -79
  11. package/dist/{src/cli/handlers/ship.d.ts → cli/handlers/dev.d.ts} +1 -1
  12. package/dist/cli/handlers/dev.js +19 -0
  13. package/dist/cli/handlers/doctor.js +13 -6
  14. package/dist/cli/handlers/init.js +32 -8
  15. package/dist/cli/handlers/release.js +21 -53
  16. package/dist/cli/handlers/rollback.js +8 -8
  17. package/dist/cli/handlers/save.js +21 -79
  18. package/dist/cli/handlers/stage.d.ts +2 -0
  19. package/dist/cli/handlers/stage.js +28 -0
  20. package/dist/cli/handlers/status.js +35 -26
  21. package/dist/{src/cli/handlers/deploy.d.ts → cli/handlers/switch.d.ts} +1 -1
  22. package/dist/cli/handlers/switch.js +29 -0
  23. package/dist/{src/cli/handlers/next.d.ts → cli/handlers/sync.d.ts} +1 -1
  24. package/dist/cli/handlers/sync.js +26 -0
  25. package/dist/cli/handlers/tasks.d.ts +2 -0
  26. package/dist/cli/handlers/tasks.js +31 -0
  27. package/dist/cli/handlers/template.d.ts +2 -0
  28. package/dist/cli/handlers/template.js +27 -0
  29. package/dist/cli/handlers/workflow.d.ts +6 -0
  30. package/dist/cli/handlers/workflow.js +71 -0
  31. package/dist/{src/cli → cli}/help.d.ts +2 -2
  32. package/dist/cli/help.js +36 -24
  33. package/dist/cli/main.d.ts +6 -0
  34. package/dist/cli/main.js +14 -19
  35. package/dist/cli/operations-help.d.ts +1 -0
  36. package/dist/cli/operations-help.js +1 -0
  37. package/dist/cli/operations-parser.d.ts +1 -0
  38. package/dist/cli/operations-parser.js +1 -0
  39. package/dist/cli/operations-registry.d.ts +5 -0
  40. package/dist/cli/operations-registry.js +260 -0
  41. package/dist/cli/operations-types.d.ts +72 -0
  42. package/dist/cli/parser.d.ts +3 -0
  43. package/dist/cli/parser.js +1 -6
  44. package/dist/cli/registry.d.ts +25 -0
  45. package/dist/cli/registry.js +28 -416
  46. package/dist/cli/repair.js +6 -4
  47. package/dist/cli/runtime.d.ts +31 -0
  48. package/dist/cli/runtime.js +240 -111
  49. package/dist/cli/types.d.ts +1 -0
  50. package/dist/{src/cli → cli}/workflow-state.d.ts +9 -0
  51. package/dist/cli/workflow-state.js +45 -21
  52. package/package.json +13 -13
  53. package/dist/cli/handlers/continue.js +0 -23
  54. package/dist/cli/handlers/deploy.js +0 -139
  55. package/dist/cli/handlers/next.js +0 -27
  56. package/dist/cli/handlers/prepare.js +0 -8
  57. package/dist/cli/handlers/promote.js +0 -8
  58. package/dist/cli/handlers/publish.js +0 -8
  59. package/dist/cli/handlers/setup.js +0 -48
  60. package/dist/cli/handlers/ship.js +0 -49
  61. package/dist/cli/handlers/start.js +0 -97
  62. package/dist/cli/handlers/teardown.js +0 -50
  63. package/dist/cli/handlers/work.js +0 -85
  64. package/dist/scripts/aggregate-book.d.ts +0 -1
  65. package/dist/scripts/aggregate-book.js +0 -121
  66. package/dist/scripts/assert-release-tag-version.d.ts +0 -1
  67. package/dist/scripts/assert-release-tag-version.js +0 -21
  68. package/dist/scripts/build-dist.d.ts +0 -1
  69. package/dist/scripts/build-dist.js +0 -108
  70. package/dist/scripts/build-tenant-worker.d.ts +0 -1
  71. package/dist/scripts/build-tenant-worker.js +0 -36
  72. package/dist/scripts/cleanup-markdown.d.ts +0 -2
  73. package/dist/scripts/cleanup-markdown.js +0 -373
  74. package/dist/scripts/config-runtime-lib.d.ts +0 -122
  75. package/dist/scripts/config-runtime-lib.js +0 -505
  76. package/dist/scripts/config-treeseed.d.ts +0 -2
  77. package/dist/scripts/config-treeseed.js +0 -81
  78. package/dist/scripts/d1-migration-lib.d.ts +0 -6
  79. package/dist/scripts/d1-migration-lib.js +0 -90
  80. package/dist/scripts/deploy-lib.d.ts +0 -127
  81. package/dist/scripts/deploy-lib.js +0 -841
  82. package/dist/scripts/ensure-mailpit.d.ts +0 -1
  83. package/dist/scripts/ensure-mailpit.js +0 -29
  84. package/dist/scripts/git-workflow-lib.d.ts +0 -25
  85. package/dist/scripts/git-workflow-lib.js +0 -136
  86. package/dist/scripts/github-automation-lib.d.ts +0 -156
  87. package/dist/scripts/github-automation-lib.js +0 -242
  88. package/dist/scripts/local-dev-lib.d.ts +0 -9
  89. package/dist/scripts/local-dev-lib.js +0 -84
  90. package/dist/scripts/local-dev.d.ts +0 -1
  91. package/dist/scripts/local-dev.js +0 -129
  92. package/dist/scripts/logs-mailpit.d.ts +0 -1
  93. package/dist/scripts/logs-mailpit.js +0 -2
  94. package/dist/scripts/mailpit-runtime.d.ts +0 -4
  95. package/dist/scripts/mailpit-runtime.js +0 -57
  96. package/dist/scripts/package-tools.d.ts +0 -22
  97. package/dist/scripts/package-tools.js +0 -255
  98. package/dist/scripts/patch-starlight-content-path.d.ts +0 -1
  99. package/dist/scripts/patch-starlight-content-path.js +0 -172
  100. package/dist/scripts/paths.d.ts +0 -17
  101. package/dist/scripts/paths.js +0 -26
  102. package/dist/scripts/publish-package.d.ts +0 -1
  103. package/dist/scripts/publish-package.js +0 -19
  104. package/dist/scripts/release-verify.d.ts +0 -1
  105. package/dist/scripts/release-verify.js +0 -136
  106. package/dist/scripts/run-fixture-astro-command.d.ts +0 -1
  107. package/dist/scripts/run-fixture-astro-command.js +0 -18
  108. package/dist/scripts/save-deploy-preflight-lib.d.ts +0 -34
  109. package/dist/scripts/save-deploy-preflight-lib.js +0 -69
  110. package/dist/scripts/scaffold-site.d.ts +0 -2
  111. package/dist/scripts/scaffold-site.js +0 -92
  112. package/dist/scripts/stop-mailpit.d.ts +0 -1
  113. package/dist/scripts/stop-mailpit.js +0 -5
  114. package/dist/scripts/sync-dev-vars.d.ts +0 -1
  115. package/dist/scripts/sync-dev-vars.js +0 -6
  116. package/dist/scripts/template-registry-lib.d.ts +0 -47
  117. package/dist/scripts/template-registry-lib.js +0 -137
  118. package/dist/scripts/tenant-astro-command.d.ts +0 -1
  119. package/dist/scripts/tenant-astro-command.js +0 -3
  120. package/dist/scripts/tenant-build.d.ts +0 -1
  121. package/dist/scripts/tenant-build.js +0 -16
  122. package/dist/scripts/tenant-check.d.ts +0 -1
  123. package/dist/scripts/tenant-check.js +0 -7
  124. package/dist/scripts/tenant-d1-migrate-local.d.ts +0 -1
  125. package/dist/scripts/tenant-d1-migrate-local.js +0 -11
  126. package/dist/scripts/tenant-deploy.d.ts +0 -2
  127. package/dist/scripts/tenant-deploy.js +0 -180
  128. package/dist/scripts/tenant-destroy.d.ts +0 -2
  129. package/dist/scripts/tenant-destroy.js +0 -104
  130. package/dist/scripts/tenant-dev.d.ts +0 -1
  131. package/dist/scripts/tenant-dev.js +0 -171
  132. package/dist/scripts/tenant-lint.d.ts +0 -1
  133. package/dist/scripts/tenant-lint.js +0 -4
  134. package/dist/scripts/tenant-test.d.ts +0 -1
  135. package/dist/scripts/tenant-test.js +0 -4
  136. package/dist/scripts/test-cloudflare-local.d.ts +0 -1
  137. package/dist/scripts/test-cloudflare-local.js +0 -212
  138. package/dist/scripts/test-scaffold.d.ts +0 -2
  139. package/dist/scripts/test-scaffold.js +0 -297
  140. package/dist/scripts/treeseed.d.ts +0 -2
  141. package/dist/scripts/treeseed.js +0 -4
  142. package/dist/scripts/validate-templates.d.ts +0 -2
  143. package/dist/scripts/validate-templates.js +0 -4
  144. package/dist/scripts/watch-dev-lib.d.ts +0 -21
  145. package/dist/scripts/watch-dev-lib.js +0 -277
  146. package/dist/scripts/workspace-close.d.ts +0 -2
  147. package/dist/scripts/workspace-close.js +0 -24
  148. package/dist/scripts/workspace-command-e2e.d.ts +0 -2
  149. package/dist/scripts/workspace-command-e2e.js +0 -718
  150. package/dist/scripts/workspace-lint.d.ts +0 -1
  151. package/dist/scripts/workspace-lint.js +0 -9
  152. package/dist/scripts/workspace-preflight-lib.d.ts +0 -36
  153. package/dist/scripts/workspace-preflight-lib.js +0 -179
  154. package/dist/scripts/workspace-preflight.d.ts +0 -2
  155. package/dist/scripts/workspace-preflight.js +0 -22
  156. package/dist/scripts/workspace-publish-changed-packages.d.ts +0 -1
  157. package/dist/scripts/workspace-publish-changed-packages.js +0 -16
  158. package/dist/scripts/workspace-release-verify.d.ts +0 -1
  159. package/dist/scripts/workspace-release-verify.js +0 -81
  160. package/dist/scripts/workspace-release.d.ts +0 -2
  161. package/dist/scripts/workspace-release.js +0 -42
  162. package/dist/scripts/workspace-save-lib.d.ts +0 -42
  163. package/dist/scripts/workspace-save-lib.js +0 -220
  164. package/dist/scripts/workspace-save.d.ts +0 -2
  165. package/dist/scripts/workspace-save.js +0 -124
  166. package/dist/scripts/workspace-start-warning.js +0 -3
  167. package/dist/scripts/workspace-start.d.ts +0 -2
  168. package/dist/scripts/workspace-start.js +0 -71
  169. package/dist/scripts/workspace-test-unit.d.ts +0 -1
  170. package/dist/scripts/workspace-test-unit.js +0 -4
  171. package/dist/scripts/workspace-test.d.ts +0 -1
  172. package/dist/scripts/workspace-test.js +0 -11
  173. package/dist/scripts/workspace-tools.d.ts +0 -13
  174. package/dist/scripts/workspace-tools.js +0 -226
  175. package/dist/src/cli/handlers/continue.d.ts +0 -2
  176. package/dist/src/cli/handlers/prepare.d.ts +0 -2
  177. package/dist/src/cli/handlers/promote.d.ts +0 -2
  178. package/dist/src/cli/handlers/publish.d.ts +0 -2
  179. package/dist/src/cli/handlers/setup.d.ts +0 -2
  180. package/dist/src/cli/handlers/start.d.ts +0 -3
  181. package/dist/src/cli/handlers/teardown.d.ts +0 -2
  182. package/dist/src/cli/handlers/work.d.ts +0 -2
  183. package/dist/src/cli/main.d.ts +0 -6
  184. package/dist/src/cli/parser.d.ts +0 -3
  185. package/dist/src/cli/registry.d.ts +0 -27
  186. package/dist/src/cli/runtime.d.ts +0 -4
  187. package/dist/src/cli/types.d.ts +0 -71
  188. /package/dist/{src/cli → cli}/handlers/close.d.ts +0 -0
  189. /package/dist/{src/cli → cli}/handlers/config.d.ts +0 -0
  190. /package/dist/{src/cli → cli}/handlers/destroy.d.ts +0 -0
  191. /package/dist/{src/cli → cli}/handlers/doctor.d.ts +0 -0
  192. /package/dist/{src/cli → cli}/handlers/init.d.ts +0 -0
  193. /package/dist/{src/cli → cli}/handlers/release.d.ts +0 -0
  194. /package/dist/{src/cli → cli}/handlers/rollback.d.ts +0 -0
  195. /package/dist/{src/cli → cli}/handlers/save.d.ts +0 -0
  196. /package/dist/{src/cli → cli}/handlers/status.d.ts +0 -0
  197. /package/dist/{src/cli → cli}/handlers/utils.d.ts +0 -0
  198. /package/dist/{scripts/workspace-start-warning.d.ts → cli/operations-types.js} +0 -0
  199. /package/dist/{src/cli → cli}/repair.d.ts +0 -0
  200. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- import { packageScriptPath } from './package-tools.js';
2
- import { packagesWithScript, run, workspaceRoot } from './workspace-tools.js';
3
- const root = workspaceRoot();
4
- run(process.execPath, [packageScriptPath('cleanup-markdown'), '--check'], {
5
- cwd: root,
6
- });
7
- for (const pkg of packagesWithScript('lint', root)) {
8
- run('npm', ['run', 'lint'], { cwd: pkg.dir });
9
- }
@@ -1,36 +0,0 @@
1
- export declare function createWranglerCommandEnv(overrides?: {}): {
2
- XDG_CONFIG_HOME: string;
3
- WRANGLER_SEND_METRICS: string;
4
- };
5
- export declare function parseGitHubAuthStatus(output: any, status: any): {
6
- authenticated: boolean;
7
- detail: any;
8
- };
9
- export declare function parseWranglerWhoAmI(output: any, status: any): {
10
- authenticated: boolean;
11
- detail: any;
12
- };
13
- export declare function parseCopilotSessionStatus(output: any, status: any): {
14
- configured: boolean;
15
- detail: any;
16
- };
17
- export declare function collectCliPreflight({ cwd, requireAuth }?: {
18
- cwd?: string | undefined;
19
- requireAuth?: boolean | undefined;
20
- }): {
21
- ok: boolean;
22
- requireAuth: boolean;
23
- missingCommands: string[];
24
- failingAuth: string[];
25
- checks: {
26
- commands: {
27
- [k: string]: {
28
- installed: boolean;
29
- path: string | null;
30
- };
31
- };
32
- auth: {};
33
- };
34
- };
35
- export declare function formatCliPreflightReport(report: any): string;
36
- export declare function writeJsonArtifact(filePath: any, value: any): void;
@@ -1,179 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { spawnSync } from 'node:child_process';
3
- import { tmpdir } from 'node:os';
4
- import { dirname, resolve } from 'node:path';
5
- import { createTempDir } from './workspace-tools.js';
6
- function runCapture(command, args, options = {}) {
7
- const result = spawnSync(command, args, {
8
- cwd: options.cwd ?? process.cwd(),
9
- env: { ...process.env, ...(options.env ?? {}) },
10
- stdio: 'pipe',
11
- encoding: 'utf8',
12
- timeout: options.timeoutMs,
13
- });
14
- return {
15
- status: result.status ?? 1,
16
- signal: result.signal ?? null,
17
- stdout: result.stdout ?? '',
18
- stderr: result.stderr ?? '',
19
- error: result.error?.message ?? null,
20
- };
21
- }
22
- function locateBinary(candidate) {
23
- const result = runCapture('bash', ['-lc', `command -v ${candidate}`]);
24
- return result.status === 0 ? result.stdout.trim() : null;
25
- }
26
- export function createWranglerCommandEnv(overrides = {}) {
27
- const configHome = createTempDir('treeseed-wrangler-config-');
28
- const logDir = resolve(configHome, '.wrangler', 'logs');
29
- mkdirSync(logDir, { recursive: true });
30
- return {
31
- XDG_CONFIG_HOME: configHome,
32
- WRANGLER_SEND_METRICS: 'false',
33
- ...overrides,
34
- };
35
- }
36
- export function parseGitHubAuthStatus(output, status) {
37
- return {
38
- authenticated: status === 0 && /Logged in|Active account:/i.test(output),
39
- detail: output.trim(),
40
- };
41
- }
42
- export function parseWranglerWhoAmI(output, status) {
43
- return {
44
- authenticated: status === 0 && !/error|failed/i.test(output),
45
- detail: output.trim(),
46
- };
47
- }
48
- export function parseCopilotSessionStatus(output, status) {
49
- const normalized = output.trim();
50
- return {
51
- configured: status === 0 || /copilot_github_token|github_token|gh_token/i.test(normalized),
52
- detail: normalized,
53
- };
54
- }
55
- function copilotSessionProbe() {
56
- const configDir = process.env.COPILOT_CONFIG_DIR
57
- ? resolve(process.env.COPILOT_CONFIG_DIR)
58
- : resolve(process.env.HOME ?? tmpdir(), '.copilot');
59
- const authPath = resolve(configDir, 'auth.json');
60
- const envConfigured = ['COPILOT_GITHUB_TOKEN', 'GH_TOKEN', 'GITHUB_TOKEN'].some((key) => {
61
- const value = process.env[key];
62
- return typeof value === 'string' && value.length > 0;
63
- });
64
- if (envConfigured) {
65
- return {
66
- status: 0,
67
- output: 'Copilot token environment variable detected.',
68
- };
69
- }
70
- if (!existsSync(authPath)) {
71
- return {
72
- status: 1,
73
- output: `No Copilot token environment variable detected and ${authPath} was not found.`,
74
- };
75
- }
76
- try {
77
- const contents = readFileSync(authPath, 'utf8');
78
- if (contents.trim().length === 0) {
79
- return {
80
- status: 1,
81
- output: `${authPath} is empty.`,
82
- };
83
- }
84
- return {
85
- status: 0,
86
- output: `Copilot auth configuration detected at ${authPath}.`,
87
- };
88
- }
89
- catch (error) {
90
- return {
91
- status: 1,
92
- output: error instanceof Error ? error.message : String(error),
93
- };
94
- }
95
- }
96
- export function collectCliPreflight({ cwd = process.cwd(), requireAuth = false } = {}) {
97
- const binaries = {
98
- git: locateBinary('git'),
99
- npm: locateBinary('npm'),
100
- gh: locateBinary('gh'),
101
- wrangler: locateBinary('wrangler'),
102
- copilot: locateBinary('copilot'),
103
- };
104
- const checks = {
105
- commands: Object.fromEntries(Object.entries(binaries).map(([name, path]) => [name, {
106
- installed: Boolean(path),
107
- path,
108
- }])),
109
- auth: {},
110
- };
111
- if (binaries.gh) {
112
- const result = runCapture('gh', ['auth', 'status'], { cwd });
113
- checks.auth.gh = parseGitHubAuthStatus(`${result.stdout}\n${result.stderr}`.trim(), result.status);
114
- }
115
- else {
116
- checks.auth.gh = { authenticated: false, detail: 'GitHub CLI is not installed.' };
117
- }
118
- if (binaries.wrangler) {
119
- const env = createWranglerCommandEnv();
120
- const result = runCapture('wrangler', ['whoami'], { cwd, env, timeoutMs: 60000 });
121
- checks.auth.wrangler = parseWranglerWhoAmI(`${result.stdout}\n${result.stderr}`.trim(), result.status);
122
- }
123
- else {
124
- checks.auth.wrangler = { authenticated: false, detail: 'Wrangler CLI is not installed.' };
125
- }
126
- if (binaries.copilot) {
127
- const probe = copilotSessionProbe();
128
- checks.auth.copilot = parseCopilotSessionStatus(probe.output, probe.status);
129
- }
130
- else {
131
- checks.auth.copilot = { configured: false, detail: 'Copilot CLI is not installed.' };
132
- }
133
- const missingCommands = Object.entries(checks.commands)
134
- .filter(([, value]) => !value.installed)
135
- .map(([name]) => name);
136
- const failingAuth = [];
137
- if (requireAuth) {
138
- if (!checks.auth.gh?.authenticated)
139
- failingAuth.push('gh');
140
- if (!checks.auth.wrangler?.authenticated)
141
- failingAuth.push('wrangler');
142
- }
143
- return {
144
- ok: missingCommands.length === 0 && failingAuth.length === 0,
145
- requireAuth,
146
- missingCommands,
147
- failingAuth,
148
- checks,
149
- };
150
- }
151
- export function formatCliPreflightReport(report) {
152
- const lines = [
153
- 'Treeseed preflight summary',
154
- `Status: ${report.ok ? 'ok' : 'failed'}`,
155
- `Require auth: ${report.requireAuth ? 'yes' : 'no'}`,
156
- 'Commands:',
157
- ];
158
- for (const [name, info] of Object.entries(report.checks.commands)) {
159
- lines.push(`- ${name}: ${info.installed ? `installed (${info.path})` : 'missing'}`);
160
- }
161
- lines.push('Auth/session:');
162
- lines.push(`- gh: ${report.checks.auth.gh?.authenticated ? 'authenticated' : 'not authenticated'}`);
163
- lines.push(` ${report.checks.auth.gh?.detail ?? ''}`.trimEnd());
164
- lines.push(`- wrangler: ${report.checks.auth.wrangler?.authenticated ? 'authenticated' : 'not authenticated'}`);
165
- lines.push(` ${report.checks.auth.wrangler?.detail ?? ''}`.trimEnd());
166
- lines.push(`- copilot: ${report.checks.auth.copilot?.configured ? 'configured' : 'not configured'}`);
167
- lines.push(` ${report.checks.auth.copilot?.detail ?? ''}`.trimEnd());
168
- if (report.missingCommands.length > 0) {
169
- lines.push(`Missing commands: ${report.missingCommands.join(', ')}`);
170
- }
171
- if (report.failingAuth.length > 0) {
172
- lines.push(`Auth failures: ${report.failingAuth.join(', ')}`);
173
- }
174
- return lines.filter(Boolean).join('\n');
175
- }
176
- export function writeJsonArtifact(filePath, value) {
177
- mkdirSync(dirname(filePath), { recursive: true });
178
- writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
179
- }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
- import { resolve } from 'node:path';
3
- import { collectCliPreflight, formatCliPreflightReport, writeJsonArtifact } from './workspace-preflight-lib.js';
4
- const args = new Set(process.argv.slice(2));
5
- const requireAuth = args.has('--require-auth');
6
- const json = args.has('--json');
7
- const reportPathArgIndex = process.argv.indexOf('--report-path');
8
- const reportPath = reportPathArgIndex >= 0 ? process.argv[reportPathArgIndex + 1] : process.env.TREESEED_PREFLIGHT_REPORT_PATH;
9
- const report = collectCliPreflight({
10
- cwd: process.cwd(),
11
- requireAuth,
12
- });
13
- if (reportPath) {
14
- writeJsonArtifact(resolve(reportPath), report);
15
- }
16
- if (json) {
17
- console.log(JSON.stringify(report, null, 2));
18
- }
19
- else {
20
- console.log(formatCliPreflightReport(report));
21
- }
22
- process.exit(report.ok ? 0 : 1);
@@ -1 +0,0 @@
1
- export {};
@@ -1,16 +0,0 @@
1
- import { packageScriptPath } from './package-tools.js';
2
- import { publishableWorkspacePackages, changedWorkspacePackages, run } from './workspace-tools.js';
3
- const publishablePackages = publishableWorkspacePackages();
4
- const changed = changedWorkspacePackages({ packages: publishablePackages, includeDependents: true });
5
- if (changed.length === 0) {
6
- console.log('No changed workspace packages to publish.');
7
- process.exit(0);
8
- }
9
- console.log(`Publishing changed workspace packages in order: ${changed.map((pkg) => pkg.name).join(', ')}`);
10
- run(process.execPath, [packageScriptPath('workspace-release-verify'), '--changed', '--full-smoke']);
11
- for (const pkg of changed) {
12
- console.log(`Publishing ${pkg.name}`);
13
- run('npm', ['run', 'release:publish'], {
14
- cwd: pkg.dir,
15
- });
16
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,81 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { publishableWorkspacePackages, changedWorkspacePackages, } from './workspace-tools.js';
3
- const cliArgs = new Set(process.argv.slice(2));
4
- const verifyChangedOnly = cliArgs.has('--changed');
5
- const fullSmoke = cliArgs.has('--full-smoke') || process.env.TREESEED_RELEASE_FULL_SMOKE === '1';
6
- const publishablePackages = publishableWorkspacePackages();
7
- const packagesToVerify = verifyChangedOnly
8
- ? changedWorkspacePackages({ packages: publishablePackages, includeDependents: true })
9
- : publishablePackages;
10
- const timings = [];
11
- function nowLabel() {
12
- return new Date().toISOString();
13
- }
14
- function logStep(message) {
15
- console.log(`[release-verify ${nowLabel()}] ${message}`);
16
- }
17
- async function withTiming(label, action) {
18
- const startedAt = Date.now();
19
- logStep(`${label} started`);
20
- try {
21
- await action();
22
- const durationMs = Date.now() - startedAt;
23
- timings.push({ label, durationMs, status: 'completed' });
24
- logStep(`${label} completed in ${(durationMs / 1000).toFixed(1)}s`);
25
- }
26
- catch (error) {
27
- const durationMs = Date.now() - startedAt;
28
- timings.push({ label, durationMs, status: 'failed' });
29
- logStep(`${label} failed in ${(durationMs / 1000).toFixed(1)}s`);
30
- throw error;
31
- }
32
- }
33
- function printSummary() {
34
- if (timings.length === 0) {
35
- return;
36
- }
37
- console.log('[release-verify] Stage summary');
38
- for (const entry of timings) {
39
- console.log(`[release-verify] ${entry.status === 'completed' ? 'ok ' : 'fail'} ${entry.label} (${(entry.durationMs / 1000).toFixed(1)}s)`);
40
- }
41
- }
42
- function verifyManifest(pkg) {
43
- for (const [dep, value] of Object.entries(pkg.packageJson.dependencies ?? {})) {
44
- if (!dep.startsWith('@treeseed/')) {
45
- continue;
46
- }
47
- if (String(value).startsWith('file:') || String(value).startsWith('workspace:')) {
48
- throw new Error(`${pkg.name} dependency ${dep} must not use local-only specifier "${value}".`);
49
- }
50
- }
51
- }
52
- function runReleaseVerify(pkg) {
53
- const extraArgs = fullSmoke ? ['--', '--full-smoke'] : [];
54
- const result = spawnSync('npm', ['run', 'release:verify', ...extraArgs], {
55
- cwd: pkg.dir,
56
- stdio: 'inherit',
57
- env: process.env,
58
- });
59
- if (result.status !== 0) {
60
- throw new Error(`${pkg.name} release:verify failed`);
61
- }
62
- }
63
- if (packagesToVerify.length === 0) {
64
- console.log('No changed workspace packages to verify.');
65
- process.exit(0);
66
- }
67
- try {
68
- logStep(`verifying ${packagesToVerify.map((pkg) => pkg.name).join(', ')} with package-owned ${fullSmoke ? 'full' : 'fast'} verification`);
69
- for (const pkg of packagesToVerify) {
70
- await withTiming(`${pkg.name} manifest verification`, async () => {
71
- verifyManifest(pkg);
72
- });
73
- await withTiming(`${pkg.name} release:verify`, async () => {
74
- runReleaseVerify(pkg);
75
- });
76
- }
77
- console.log(`Release verification passed for: ${packagesToVerify.map((pkg) => pkg.name).join(', ')}`);
78
- }
79
- finally {
80
- printSummary();
81
- }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env node
2
- import { readFileSync, writeFileSync } from 'node:fs';
3
- import { resolve } from 'node:path';
4
- import { applyTreeseedEnvironmentToProcess } from './config-runtime-lib.js';
5
- import { PRODUCTION_BRANCH, STAGING_BRANCH, mergeStagingIntoMain, prepareReleaseBranches, pushBranch } from './git-workflow-lib.js';
6
- import { incrementVersion, planWorkspaceReleaseBump, applyWorkspaceVersionChanges, repoRoot } from './workspace-save-lib.js';
7
- import { run, workspaceRoot } from './workspace-tools.js';
8
- import { runWorkspaceSavePreflight } from './save-deploy-preflight-lib.js';
9
- function parseArgs(argv) {
10
- const flags = new Set(argv);
11
- const selected = ['major', 'minor', 'patch'].filter((level) => flags.has(`--${level}`));
12
- if (selected.length !== 1) {
13
- throw new Error('Treeseed release requires exactly one version bump flag: --major, --minor, or --patch.');
14
- }
15
- return { level: selected[0] };
16
- }
17
- function bumpRootPackageJson(root, level) {
18
- const packageJsonPath = resolve(root, 'package.json');
19
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
20
- packageJson.version = incrementVersion(packageJson.version, level);
21
- writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8');
22
- return packageJson.version;
23
- }
24
- const { level } = parseArgs(process.argv.slice(2));
25
- const root = workspaceRoot();
26
- const gitRoot = repoRoot(root);
27
- prepareReleaseBranches(root);
28
- applyTreeseedEnvironmentToProcess({ tenantRoot: root, scope: 'staging' });
29
- runWorkspaceSavePreflight({ cwd: root });
30
- const plan = planWorkspaceReleaseBump(level, root);
31
- applyWorkspaceVersionChanges(plan);
32
- const rootVersion = bumpRootPackageJson(root, level);
33
- run('git', ['checkout', STAGING_BRANCH], { cwd: gitRoot });
34
- run('git', ['add', '-A'], { cwd: gitRoot });
35
- run('git', ['commit', '-m', `release: ${level} bump`], { cwd: gitRoot });
36
- pushBranch(gitRoot, STAGING_BRANCH);
37
- mergeStagingIntoMain(root);
38
- console.log('Treeseed release completed successfully.');
39
- console.log(`Staging branch: ${STAGING_BRANCH}`);
40
- console.log(`Production branch: ${PRODUCTION_BRANCH}`);
41
- console.log(`Release level: ${level}`);
42
- console.log(`Root version: ${rootVersion}`);
@@ -1,42 +0,0 @@
1
- export declare const MERGE_CONFLICT_EXIT_CODE = 12;
2
- export declare function incrementPatchVersion(version: any): string;
3
- export declare function incrementVersion(version: any, level?: string): string;
4
- export declare function planWorkspaceVersionChanges(root?: string): {
5
- packages: any[];
6
- publishable: Set<any>;
7
- bumped: Set<any>;
8
- touched: Set<unknown>;
9
- };
10
- export declare function applyWorkspaceVersionChanges(plan: any): any;
11
- export declare function planWorkspaceReleaseBump(level?: string, root?: string): {
12
- packages: any[];
13
- touched: Set<unknown>;
14
- versions: Map<any, any>;
15
- level: string;
16
- };
17
- export declare function repoRoot(cwd?: string): string;
18
- export declare function currentBranch(repoDir: any): string;
19
- export declare function originRemoteUrl(repoDir: any): string;
20
- export declare function gitStatusPorcelain(repoDir: any): string;
21
- export declare function hasMeaningfulChanges(repoDir: any): boolean;
22
- export declare function countConflictMarkers(source: any): {
23
- start: any;
24
- middle: any;
25
- end: any;
26
- };
27
- export declare function collectMergeConflictReport(repoDir: any): {
28
- branch: string;
29
- rebaseInProgress: boolean;
30
- conflictedFiles: string[];
31
- status: string;
32
- perFile: {
33
- filePath: string;
34
- markers: {
35
- start: any;
36
- middle: any;
37
- end: any;
38
- };
39
- diff: string;
40
- }[];
41
- };
42
- export declare function formatMergeConflictReport(report: any, repoDir: any, targetBranch?: string): string;
@@ -1,220 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import { changedWorkspacePackages, publishableWorkspacePackages, run, sortWorkspacePackages, workspacePackages, workspaceRoot } from './workspace-tools.js';
4
- export const MERGE_CONFLICT_EXIT_CODE = 12;
5
- function parseSemver(version) {
6
- const match = String(version).trim().match(/^(\d+)\.(\d+)\.(\d+)$/);
7
- if (!match) {
8
- throw new Error(`Unsupported version "${version}". Expected x.y.z.`);
9
- }
10
- return {
11
- major: Number(match[1]),
12
- minor: Number(match[2]),
13
- patch: Number(match[3]),
14
- };
15
- }
16
- export function incrementPatchVersion(version) {
17
- const parsed = parseSemver(version);
18
- return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
19
- }
20
- export function incrementVersion(version, level = 'patch') {
21
- const parsed = parseSemver(version);
22
- if (level === 'major') {
23
- return `${parsed.major + 1}.0.0`;
24
- }
25
- if (level === 'minor') {
26
- return `${parsed.major}.${parsed.minor + 1}.0`;
27
- }
28
- if (level === 'patch') {
29
- return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
30
- }
31
- throw new Error(`Unsupported release bump "${level}". Expected major, minor, or patch.`);
32
- }
33
- function readPackageJson(filePath) {
34
- return JSON.parse(readFileSync(filePath, 'utf8'));
35
- }
36
- function writePackageJson(filePath, value) {
37
- writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
38
- }
39
- function internalDependencyFields(packageJson) {
40
- return ['dependencies', 'optionalDependencies', 'peerDependencies', 'devDependencies']
41
- .filter((field) => packageJson[field] && typeof packageJson[field] === 'object');
42
- }
43
- export function planWorkspaceVersionChanges(root = workspaceRoot()) {
44
- const packages = workspacePackages(root).map((pkg) => ({
45
- ...pkg,
46
- packageJsonPath: resolve(pkg.dir, 'package.json'),
47
- packageJson: readPackageJson(resolve(pkg.dir, 'package.json')),
48
- }));
49
- const orderedPackages = sortWorkspacePackages(packages);
50
- const publishable = new Set(publishableWorkspacePackages(root).map((pkg) => pkg.name));
51
- const changedPublishable = new Set(changedWorkspacePackages({
52
- root,
53
- packages: orderedPackages.filter((pkg) => publishable.has(pkg.name)),
54
- includeDependents: false,
55
- }).map((pkg) => pkg.name));
56
- const versions = new Map(orderedPackages.map((pkg) => [pkg.name, pkg.packageJson.version]));
57
- const bumped = new Set(changedPublishable);
58
- const touched = new Set();
59
- for (const name of changedPublishable) {
60
- versions.set(name, incrementPatchVersion(versions.get(name)));
61
- }
62
- let changed = true;
63
- while (changed) {
64
- changed = false;
65
- for (const pkg of orderedPackages) {
66
- let packageDependencyChanged = false;
67
- for (const field of internalDependencyFields(pkg.packageJson)) {
68
- for (const depName of Object.keys(pkg.packageJson[field] ?? {})) {
69
- if (!versions.has(depName)) {
70
- continue;
71
- }
72
- const nextSpec = `^${versions.get(depName)}`;
73
- if (pkg.packageJson[field][depName] === nextSpec) {
74
- continue;
75
- }
76
- pkg.packageJson[field][depName] = nextSpec;
77
- packageDependencyChanged = true;
78
- touched.add(pkg.name);
79
- }
80
- }
81
- if (packageDependencyChanged && publishable.has(pkg.name) && !bumped.has(pkg.name)) {
82
- bumped.add(pkg.name);
83
- versions.set(pkg.name, incrementPatchVersion(versions.get(pkg.name)));
84
- changed = true;
85
- }
86
- }
87
- }
88
- for (const pkg of orderedPackages) {
89
- if (!bumped.has(pkg.name)) {
90
- continue;
91
- }
92
- const nextVersion = versions.get(pkg.name);
93
- if (pkg.packageJson.version !== nextVersion) {
94
- pkg.packageJson.version = nextVersion;
95
- touched.add(pkg.name);
96
- }
97
- }
98
- return {
99
- packages: orderedPackages,
100
- publishable,
101
- bumped,
102
- touched,
103
- };
104
- }
105
- export function applyWorkspaceVersionChanges(plan) {
106
- for (const pkg of plan.packages) {
107
- if (!plan.touched.has(pkg.name)) {
108
- continue;
109
- }
110
- writePackageJson(pkg.packageJsonPath, pkg.packageJson);
111
- }
112
- return plan;
113
- }
114
- export function planWorkspaceReleaseBump(level = 'patch', root = workspaceRoot()) {
115
- const packages = workspacePackages(root).map((pkg) => ({
116
- ...pkg,
117
- packageJsonPath: resolve(pkg.dir, 'package.json'),
118
- packageJson: readPackageJson(resolve(pkg.dir, 'package.json')),
119
- }));
120
- const publishable = new Set(publishableWorkspacePackages(root).map((pkg) => pkg.name));
121
- const touched = new Set();
122
- const versions = new Map();
123
- for (const pkg of packages) {
124
- if (!publishable.has(pkg.name)) {
125
- continue;
126
- }
127
- const nextVersion = incrementVersion(pkg.packageJson.version, level);
128
- pkg.packageJson.version = nextVersion;
129
- versions.set(pkg.name, nextVersion);
130
- touched.add(pkg.name);
131
- }
132
- for (const pkg of packages) {
133
- for (const field of internalDependencyFields(pkg.packageJson)) {
134
- for (const depName of Object.keys(pkg.packageJson[field] ?? {})) {
135
- if (!versions.has(depName)) {
136
- continue;
137
- }
138
- pkg.packageJson[field][depName] = `^${versions.get(depName)}`;
139
- touched.add(pkg.name);
140
- }
141
- }
142
- }
143
- return {
144
- packages,
145
- touched,
146
- versions,
147
- level,
148
- };
149
- }
150
- export function repoRoot(cwd = workspaceRoot()) {
151
- return run('git', ['rev-parse', '--show-toplevel'], { cwd, capture: true }).trim();
152
- }
153
- export function currentBranch(repoDir) {
154
- return run('git', ['branch', '--show-current'], { cwd: repoDir, capture: true }).trim();
155
- }
156
- export function originRemoteUrl(repoDir) {
157
- return run('git', ['remote', 'get-url', 'origin'], { cwd: repoDir, capture: true }).trim();
158
- }
159
- export function gitStatusPorcelain(repoDir) {
160
- return run('git', ['status', '--porcelain'], { cwd: repoDir, capture: true }).trim();
161
- }
162
- export function hasMeaningfulChanges(repoDir) {
163
- return gitStatusPorcelain(repoDir).length > 0;
164
- }
165
- export function countConflictMarkers(source) {
166
- return {
167
- start: (source.match(/^<{7} /gm) ?? []).length,
168
- middle: (source.match(/^={7}$/gm) ?? []).length,
169
- end: (source.match(/^>{7} /gm) ?? []).length,
170
- };
171
- }
172
- export function collectMergeConflictReport(repoDir) {
173
- const branch = currentBranch(repoDir);
174
- const conflictedFiles = run('git', ['diff', '--name-only', '--diff-filter=U'], {
175
- cwd: repoDir,
176
- capture: true,
177
- })
178
- .split('\n')
179
- .map((line) => line.trim())
180
- .filter(Boolean);
181
- const status = run('git', ['status', '--short'], { cwd: repoDir, capture: true });
182
- const perFile = conflictedFiles.map((filePath) => {
183
- const fullPath = resolve(repoDir, filePath);
184
- const source = existsSync(fullPath) ? readFileSync(fullPath, 'utf8') : '';
185
- return {
186
- filePath,
187
- markers: countConflictMarkers(source),
188
- diff: run('git', ['diff', '--', filePath], { cwd: repoDir, capture: true }),
189
- };
190
- });
191
- return {
192
- branch,
193
- rebaseInProgress: true,
194
- conflictedFiles,
195
- status,
196
- perFile,
197
- };
198
- }
199
- export function formatMergeConflictReport(report, repoDir, targetBranch = 'main') {
200
- const lines = [
201
- `Treeseed save failed due to merge conflicts during \`git pull --rebase origin ${targetBranch}\`.`,
202
- `Repository root: ${repoDir}`,
203
- `Branch: ${report.branch}`,
204
- `Rebase in progress: ${report.rebaseInProgress ? 'yes' : 'no'}`,
205
- 'Git status:',
206
- report.status || '(no git status output)',
207
- 'Conflicted files:',
208
- ];
209
- for (const file of report.perFile) {
210
- lines.push(`- ${file.filePath}`);
211
- lines.push(` markers: start=${file.markers.start} middle=${file.markers.middle} end=${file.markers.end}`);
212
- lines.push(' diff:');
213
- lines.push(file.diff || ' (no diff output)');
214
- }
215
- lines.push('Next steps:');
216
- lines.push('- Inspect conflicted files and reconcile local vs remote changes.');
217
- lines.push('- After resolving files, run `git add <files>` and `git rebase --continue`.');
218
- lines.push('- Or abort with `git rebase --abort` if you need to restart the save flow.');
219
- return lines.join('\n');
220
- }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};