@treeseed/cli 0.6.46 → 0.6.47
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.
|
@@ -44,9 +44,9 @@ function formatSavePlanSections(repositoryPlan) {
|
|
|
44
44
|
}
|
|
45
45
|
const handleSave = async (invocation, context) => {
|
|
46
46
|
try {
|
|
47
|
+
const progressWrite = context.outputFormat === "json" ? ((output) => context.write(output, "stderr")) : context.write;
|
|
47
48
|
const result = await createWorkflowSdk(context, {
|
|
48
|
-
write:
|
|
49
|
-
}) : context.write
|
|
49
|
+
write: progressWrite
|
|
50
50
|
}).save({
|
|
51
51
|
message: invocation.positionals.join(" ").trim(),
|
|
52
52
|
hotfix: invocation.args.hotfix === true,
|
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
resolveTreeseedLaunchEnvironment,
|
|
4
4
|
resolveTreeseedToolCommand
|
|
5
5
|
} from "@treeseed/sdk/workflow-support";
|
|
6
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
7
8
|
import { join } from "node:path";
|
|
8
9
|
import { workflowErrorResult } from "./workflow.js";
|
|
9
10
|
const WRAPPED_TOOLS = /* @__PURE__ */ new Set(["gh", "railway", "wrangler"]);
|
|
@@ -54,6 +55,34 @@ function findRailwayProjectId(value) {
|
|
|
54
55
|
}
|
|
55
56
|
return null;
|
|
56
57
|
}
|
|
58
|
+
function findRailwayProjectIdFromCommand(value) {
|
|
59
|
+
if (!value || typeof value !== "object") {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
for (const entry of value) {
|
|
64
|
+
const found = findRailwayProjectIdFromCommand(entry);
|
|
65
|
+
if (found) {
|
|
66
|
+
return found;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const record = value;
|
|
72
|
+
if (typeof record.lastDeploymentCommand === "string") {
|
|
73
|
+
const match = record.lastDeploymentCommand.match(/--project\s+([0-9a-f]{8}-[0-9a-f-]{27,})/iu);
|
|
74
|
+
if (match?.[1]) {
|
|
75
|
+
return match[1];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const entry of Object.values(record)) {
|
|
79
|
+
const found = findRailwayProjectIdFromCommand(entry);
|
|
80
|
+
if (found) {
|
|
81
|
+
return found;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
57
86
|
function railwayProjectIdFromDeployState(cwd, scope) {
|
|
58
87
|
const stateScope = scope === "prod" ? "prod" : scope;
|
|
59
88
|
const statePath = join(cwd, ".treeseed", "state", "environments", stateScope, "deploy.json");
|
|
@@ -61,12 +90,18 @@ function railwayProjectIdFromDeployState(cwd, scope) {
|
|
|
61
90
|
return null;
|
|
62
91
|
}
|
|
63
92
|
try {
|
|
64
|
-
|
|
93
|
+
const state = JSON.parse(readFileSync(statePath, "utf8"));
|
|
94
|
+
return findRailwayProjectIdFromCommand(state) ?? findRailwayProjectId(state);
|
|
65
95
|
} catch {
|
|
66
96
|
return null;
|
|
67
97
|
}
|
|
68
98
|
}
|
|
99
|
+
function railwayCommandUsesProjectFiles(args) {
|
|
100
|
+
const command = args[0] ?? "";
|
|
101
|
+
return ["up", "dev", "develop", "run", "local", "shell"].includes(command);
|
|
102
|
+
}
|
|
69
103
|
const handleToolWrapper = (invocation, context) => {
|
|
104
|
+
let isolatedRailwayCwd = null;
|
|
70
105
|
try {
|
|
71
106
|
const toolName = wrappedToolName(invocation.commandName);
|
|
72
107
|
const scope = wrapperScope(invocation.args.environment);
|
|
@@ -101,8 +136,14 @@ const handleToolWrapper = (invocation, context) => {
|
|
|
101
136
|
if (toolName === "railway" && scope !== "local" && targetArgs[0] !== "link") {
|
|
102
137
|
const environmentName = railwayEnvironmentName(scope);
|
|
103
138
|
const projectId = managedEnv.TREESEED_RAILWAY_PROJECT_ID || railwayProjectIdFromDeployState(context.cwd, scope);
|
|
139
|
+
const railwayCwd = railwayCommandUsesProjectFiles(targetArgs) ? context.cwd : isolatedRailwayCwd = mkdtempSync(join(tmpdir(), `treeseed-railway-${scope}-`));
|
|
140
|
+
const railwayEnv = isolatedRailwayCwd ? {
|
|
141
|
+
...managedEnv,
|
|
142
|
+
HOME: isolatedRailwayCwd,
|
|
143
|
+
XDG_CONFIG_HOME: join(isolatedRailwayCwd, ".config")
|
|
144
|
+
} : managedEnv;
|
|
104
145
|
if (projectId) {
|
|
105
|
-
context.spawn(resolved.command, [
|
|
146
|
+
const linkResult = context.spawn(resolved.command, [
|
|
106
147
|
...resolved.argsPrefix,
|
|
107
148
|
"link",
|
|
108
149
|
"--project",
|
|
@@ -111,44 +152,72 @@ const handleToolWrapper = (invocation, context) => {
|
|
|
111
152
|
environmentName,
|
|
112
153
|
"--json"
|
|
113
154
|
], {
|
|
114
|
-
cwd:
|
|
115
|
-
env:
|
|
155
|
+
cwd: railwayCwd,
|
|
156
|
+
env: railwayEnv,
|
|
116
157
|
stdio: "pipe"
|
|
117
158
|
});
|
|
159
|
+
if ((linkResult.status ?? 1) !== 0) {
|
|
160
|
+
return {
|
|
161
|
+
exitCode: linkResult.status ?? 1,
|
|
162
|
+
stderr: [`Failed to link Railway project ${projectId} for ${environmentName} before running ${targetArgs.join(" ") || "railway"}.`],
|
|
163
|
+
report: {
|
|
164
|
+
command: toolName,
|
|
165
|
+
ok: false,
|
|
166
|
+
scope,
|
|
167
|
+
executable: resolved.command,
|
|
168
|
+
binaryPath: resolved.binaryPath,
|
|
169
|
+
argsPrefix: resolved.argsPrefix,
|
|
170
|
+
args: targetArgs,
|
|
171
|
+
projectLink: {
|
|
172
|
+
projectId,
|
|
173
|
+
environment: environmentName,
|
|
174
|
+
status: linkResult.status ?? 1
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
118
179
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
180
|
+
if (!(isolatedRailwayCwd && projectId)) {
|
|
181
|
+
const environmentResult = context.spawn(resolved.command, [
|
|
182
|
+
...resolved.argsPrefix,
|
|
183
|
+
"environment",
|
|
184
|
+
environmentName,
|
|
185
|
+
"--json"
|
|
186
|
+
], {
|
|
187
|
+
cwd: railwayCwd,
|
|
188
|
+
env: railwayEnv,
|
|
189
|
+
stdio: "pipe"
|
|
190
|
+
});
|
|
191
|
+
if ((environmentResult.status ?? 1) !== 0) {
|
|
192
|
+
return {
|
|
193
|
+
exitCode: environmentResult.status ?? 1,
|
|
194
|
+
stderr: [`Failed to select Railway environment ${railwayEnvironmentName(scope)} before running ${targetArgs.join(" ") || "railway"}.`],
|
|
195
|
+
report: {
|
|
196
|
+
command: toolName,
|
|
197
|
+
ok: false,
|
|
198
|
+
scope,
|
|
199
|
+
executable: resolved.command,
|
|
200
|
+
binaryPath: resolved.binaryPath,
|
|
201
|
+
argsPrefix: resolved.argsPrefix,
|
|
202
|
+
args: targetArgs,
|
|
203
|
+
environmentSelection: {
|
|
204
|
+
environment: environmentName,
|
|
205
|
+
status: environmentResult.status ?? 1
|
|
206
|
+
}
|
|
144
207
|
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
147
210
|
}
|
|
148
211
|
}
|
|
212
|
+
const railwayTargetCwd = toolName === "railway" && isolatedRailwayCwd ? isolatedRailwayCwd : context.cwd;
|
|
213
|
+
const targetEnv = toolName === "railway" && isolatedRailwayCwd ? {
|
|
214
|
+
...managedEnv,
|
|
215
|
+
HOME: isolatedRailwayCwd,
|
|
216
|
+
XDG_CONFIG_HOME: join(isolatedRailwayCwd, ".config")
|
|
217
|
+
} : managedEnv;
|
|
149
218
|
const result = context.spawn(resolved.command, [...resolved.argsPrefix, ...targetArgs], {
|
|
150
|
-
cwd:
|
|
151
|
-
env:
|
|
219
|
+
cwd: railwayTargetCwd,
|
|
220
|
+
env: targetEnv,
|
|
152
221
|
stdio: "inherit"
|
|
153
222
|
});
|
|
154
223
|
return {
|
|
@@ -166,6 +235,13 @@ const handleToolWrapper = (invocation, context) => {
|
|
|
166
235
|
};
|
|
167
236
|
} catch (error) {
|
|
168
237
|
return workflowErrorResult(error);
|
|
238
|
+
} finally {
|
|
239
|
+
if (isolatedRailwayCwd) {
|
|
240
|
+
try {
|
|
241
|
+
rmSync(isolatedRailwayCwd, { recursive: true, force: true });
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
169
245
|
}
|
|
170
246
|
};
|
|
171
247
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.47",
|
|
4
4
|
"description": "Operator-facing Treeseed CLI package.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"release:publish": "node ./scripts/run-ts.mjs ./scripts/publish-package.ts"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@treeseed/sdk": "0.6.
|
|
48
|
+
"@treeseed/sdk": "0.6.51",
|
|
49
49
|
"ink": "^7.0.0",
|
|
50
50
|
"react": "^19.2.5"
|
|
51
51
|
},
|