@buildspacestudio/cli 0.6.0 → 0.8.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.
- package/README.md +1 -1
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +285 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +179 -70
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +90 -73
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +16 -3
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/api.d.ts +54 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +94 -9
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +7 -4
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/browser.d.ts +7 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/browser.js +44 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/env.d.ts +3 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +8 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/telemetry.d.ts +1 -1
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/telemetry.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ Behavior:
|
|
|
122
122
|
|
|
123
123
|
- `list` shows masked values
|
|
124
124
|
- `set` creates or updates a variable, and uppercases the key automatically
|
|
125
|
-
- `pull` writes
|
|
125
|
+
- `pull` writes non-secret vars plus the managed database credentials (`BUILDSPACE_DB_URL` and `BUILDSPACE_DB_TOKEN`) to a local env file
|
|
126
126
|
- keys with the `BUILDSPACE_` prefix are reserved
|
|
127
127
|
- `NEXT_PUBLIC_*` keys default to non-secret unless you override them
|
|
128
128
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAwTA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B/D"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { acceptHostedWorkspaceChanges, getHostedAgent, inspectHostedWorkspace, resetHostedWorkspace, setHostedAgentProviderKey, } from "../lib/api.js";
|
|
2
|
+
import { resolveAppContext } from "../lib/app.js";
|
|
3
|
+
import { hasFlag, readFlag } from "../lib/args.js";
|
|
4
|
+
import { resolveStoredAuth } from "../lib/auth.js";
|
|
5
|
+
import { openBrowser } from "../lib/browser.js";
|
|
6
|
+
import { trackEvent } from "../lib/telemetry.js";
|
|
7
|
+
const PROVIDERS = ["anthropic", "google", "openai", "openrouter"];
|
|
8
|
+
const PROVIDER_LABELS = {
|
|
9
|
+
anthropic: "Anthropic",
|
|
10
|
+
google: "Google Gemini",
|
|
11
|
+
openai: "OpenAI",
|
|
12
|
+
openrouter: "OpenRouter",
|
|
13
|
+
};
|
|
14
|
+
function printUsage() {
|
|
15
|
+
console.log("Usage: buildspace agent <subcommand> [options]");
|
|
16
|
+
console.log("");
|
|
17
|
+
console.log("Manage the hosted dev agent (OpenCode) attached to your app's dev workspace.");
|
|
18
|
+
console.log("");
|
|
19
|
+
console.log("Subcommands:");
|
|
20
|
+
console.log(" status Show the hosted agent URL, status, and provider");
|
|
21
|
+
console.log(" open Open the hosted agent workspace in your browser");
|
|
22
|
+
console.log(" inspect Show pending file changes in the workspace");
|
|
23
|
+
console.log(" accept Commit and push workspace changes to the tracked branch");
|
|
24
|
+
console.log(" reset Reset the workspace to match the tracked branch");
|
|
25
|
+
console.log(" key set Set the AI provider key the agent runs with");
|
|
26
|
+
console.log("");
|
|
27
|
+
console.log("Options:");
|
|
28
|
+
console.log(" --app <slug> App slug (default: git remote or active app)");
|
|
29
|
+
console.log(" --json Output as JSON (status, inspect only)");
|
|
30
|
+
console.log(" --no-open Print the URL instead of opening a browser (open only)");
|
|
31
|
+
console.log(" --message <text> Commit message for `accept` (default: auto-generated)");
|
|
32
|
+
console.log(" --provider <name> Provider for `key set`: anthropic, google, openai, openrouter");
|
|
33
|
+
console.log(" --key <value> Provider API key (omit to read from stdin)");
|
|
34
|
+
console.log("");
|
|
35
|
+
console.log("Examples:");
|
|
36
|
+
console.log(" buildspace agent status");
|
|
37
|
+
console.log(" buildspace agent open");
|
|
38
|
+
console.log(" buildspace agent inspect");
|
|
39
|
+
console.log(" buildspace agent accept --message 'Add auth flow'");
|
|
40
|
+
console.log(" buildspace agent reset");
|
|
41
|
+
console.log(" buildspace agent key set --provider anthropic --key sk-ant-...");
|
|
42
|
+
console.log(" cat key.txt | buildspace agent key set --provider openai");
|
|
43
|
+
}
|
|
44
|
+
const NOT_ENABLED_HINT = "Hosted dev agent is not enabled. Run `buildspace app hosting enable` to provision it.";
|
|
45
|
+
function resolveDevEnvId(context) {
|
|
46
|
+
return context.environments.find((env) => env.type === "dev")?.id ?? null;
|
|
47
|
+
}
|
|
48
|
+
function agentUrl(agent) {
|
|
49
|
+
return agent.url ?? (agent.domain ? `https://${agent.domain}` : null);
|
|
50
|
+
}
|
|
51
|
+
async function runStatus(args) {
|
|
52
|
+
const json = hasFlag(args, "--json");
|
|
53
|
+
const auth = await resolveStoredAuth();
|
|
54
|
+
try {
|
|
55
|
+
const context = await resolveAppContext(args, auth);
|
|
56
|
+
const agent = await getHostedAgent(context.app.id, auth);
|
|
57
|
+
if (json) {
|
|
58
|
+
console.log(JSON.stringify({ hostedAgent: agent }, null, 2));
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
console.log(`App: ${context.app.name} (${context.app.slug})`);
|
|
62
|
+
if (!agent) {
|
|
63
|
+
console.log(NOT_ENABLED_HINT);
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
console.log(` status: ${agent.status ?? "pending"}`);
|
|
67
|
+
console.log(` url: ${agentUrl(agent) ?? "pending"}`);
|
|
68
|
+
console.log(` branch: ${agent.trackedGitBranch ?? "buildspace/dev"}`);
|
|
69
|
+
console.log(` provider: ${agent.providerConfigured
|
|
70
|
+
? `configured${agent.configuredProvider ? ` (${agent.configuredProvider})` : ""}`
|
|
71
|
+
: "not configured — run `buildspace agent key set`"}`);
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
const message = error instanceof Error ? error.message : "Failed to get agent status";
|
|
76
|
+
console.error(`Error: ${message}`);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function runOpen(args) {
|
|
81
|
+
const noOpen = hasFlag(args, "--no-open");
|
|
82
|
+
const auth = await resolveStoredAuth();
|
|
83
|
+
try {
|
|
84
|
+
const context = await resolveAppContext(args, auth);
|
|
85
|
+
const agent = await getHostedAgent(context.app.id, auth);
|
|
86
|
+
if (!agent) {
|
|
87
|
+
console.error(NOT_ENABLED_HINT);
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
const url = agentUrl(agent);
|
|
91
|
+
if (!url) {
|
|
92
|
+
console.error("Agent URL is not ready yet. Check `buildspace agent status` and retry.");
|
|
93
|
+
return 1;
|
|
94
|
+
}
|
|
95
|
+
if (noOpen) {
|
|
96
|
+
console.log(url);
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const opened = await openBrowser(url);
|
|
100
|
+
trackEvent("cli.agent.opened");
|
|
101
|
+
if (opened) {
|
|
102
|
+
console.log(`Opening ${url}`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.log("Could not open a browser automatically. Open this URL manually:");
|
|
106
|
+
console.log(` ${url}`);
|
|
107
|
+
}
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const message = error instanceof Error ? error.message : "Failed to open agent";
|
|
112
|
+
console.error(`Error: ${message}`);
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function readStdin() {
|
|
117
|
+
return new Promise((resolve, reject) => {
|
|
118
|
+
let data = "";
|
|
119
|
+
process.stdin.setEncoding("utf8");
|
|
120
|
+
process.stdin.on("data", (chunk) => {
|
|
121
|
+
data += chunk;
|
|
122
|
+
});
|
|
123
|
+
process.stdin.on("end", () => resolve(data));
|
|
124
|
+
process.stdin.on("error", reject);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function isHostedAgentProvider(value) {
|
|
128
|
+
return PROVIDERS.includes(value);
|
|
129
|
+
}
|
|
130
|
+
async function runKeySet(args) {
|
|
131
|
+
const provider = readFlag(args, "--provider")?.trim().toLowerCase();
|
|
132
|
+
if (!provider) {
|
|
133
|
+
console.error("Missing required --provider.");
|
|
134
|
+
console.error(`Valid providers: ${PROVIDERS.join(", ")}`);
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
if (!isHostedAgentProvider(provider)) {
|
|
138
|
+
console.error(`Invalid --provider '${provider}'. Valid providers: ${PROVIDERS.join(", ")}`);
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
let apiKey = readFlag(args, "--key")?.trim();
|
|
142
|
+
if (!apiKey) {
|
|
143
|
+
if (process.stdin.isTTY) {
|
|
144
|
+
console.error("Missing API key. Pass --key <value> or pipe it via stdin.");
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
apiKey = (await readStdin()).trim();
|
|
148
|
+
}
|
|
149
|
+
if (!apiKey) {
|
|
150
|
+
console.error("Provider API key is empty.");
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
const auth = await resolveStoredAuth();
|
|
154
|
+
try {
|
|
155
|
+
const context = await resolveAppContext(args, auth);
|
|
156
|
+
const envId = resolveDevEnvId(context);
|
|
157
|
+
if (!envId) {
|
|
158
|
+
console.error(`No dev environment found for app '${context.app.slug}'.`);
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
await setHostedAgentProviderKey({ appId: context.app.id, envId, provider, apiKey }, auth);
|
|
162
|
+
trackEvent("cli.agent.key_set");
|
|
163
|
+
console.log(`Saved ${PROVIDER_LABELS[provider]} key for ${context.app.slug}.`);
|
|
164
|
+
console.log("Restart the workspace for the agent to pick up the new key.");
|
|
165
|
+
return 0;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
const message = error instanceof Error ? error.message : "Failed to save agent key";
|
|
169
|
+
console.error(`Error: ${message}`);
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function runInspect(args) {
|
|
174
|
+
const json = hasFlag(args, "--json");
|
|
175
|
+
const auth = await resolveStoredAuth();
|
|
176
|
+
try {
|
|
177
|
+
const context = await resolveAppContext(args, auth);
|
|
178
|
+
const status = await inspectHostedWorkspace(context.app.id, auth);
|
|
179
|
+
if (json) {
|
|
180
|
+
console.log(JSON.stringify({ status }, null, 2));
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
console.log(`App: ${context.app.name} (${context.app.slug})`);
|
|
184
|
+
console.log(` branch: ${status.branch}`);
|
|
185
|
+
console.log(` clean: ${status.clean}`);
|
|
186
|
+
if (status.files.length === 0) {
|
|
187
|
+
console.log(" No pending changes.");
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
console.log(` ${status.files.length} changed file(s):`);
|
|
191
|
+
for (const f of status.files) {
|
|
192
|
+
console.log(` ${f.status} ${f.path}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const message = error instanceof Error ? error.message : "Failed to inspect workspace";
|
|
199
|
+
console.error(`Error: ${message}`);
|
|
200
|
+
return 1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function runAccept(args) {
|
|
204
|
+
const commitMessage = readFlag(args, "--message")?.trim();
|
|
205
|
+
const auth = await resolveStoredAuth();
|
|
206
|
+
try {
|
|
207
|
+
const context = await resolveAppContext(args, auth);
|
|
208
|
+
const result = await acceptHostedWorkspaceChanges({ appId: context.app.id, commitMessage }, auth);
|
|
209
|
+
trackEvent("cli.agent.accept");
|
|
210
|
+
if (result.committed) {
|
|
211
|
+
console.log(`Accepted ${result.fileCount} file(s) on branch ${result.branch}.`);
|
|
212
|
+
console.log(` ${result.summary}`);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
console.log("No changes to accept — workspace is already clean.");
|
|
216
|
+
}
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
const message = error instanceof Error ? error.message : "Failed to accept workspace changes";
|
|
221
|
+
console.error(`Error: ${message}`);
|
|
222
|
+
return 1;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async function runReset(args) {
|
|
226
|
+
const auth = await resolveStoredAuth();
|
|
227
|
+
try {
|
|
228
|
+
const context = await resolveAppContext(args, auth);
|
|
229
|
+
const result = await resetHostedWorkspace(context.app.id, auth);
|
|
230
|
+
trackEvent("cli.agent.reset");
|
|
231
|
+
if (result.reset) {
|
|
232
|
+
console.log(`Workspace reset to branch ${result.branch}.`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.log("Workspace was already clean — nothing to reset.");
|
|
236
|
+
}
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
const message = error instanceof Error ? error.message : "Failed to reset workspace";
|
|
241
|
+
console.error(`Error: ${message}`);
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function runKey(args) {
|
|
246
|
+
const subcommand = args[0];
|
|
247
|
+
if (!subcommand || hasFlag(args, "--help", "-h", "help")) {
|
|
248
|
+
console.log("Usage: buildspace agent key set --provider <name> [--key <value>]");
|
|
249
|
+
return Promise.resolve(subcommand ? 0 : 1);
|
|
250
|
+
}
|
|
251
|
+
switch (subcommand) {
|
|
252
|
+
case "set":
|
|
253
|
+
return runKeySet(args.slice(1));
|
|
254
|
+
default:
|
|
255
|
+
console.error(`Unknown agent key subcommand: ${subcommand}`);
|
|
256
|
+
console.log("Usage: buildspace agent key set --provider <name> [--key <value>]");
|
|
257
|
+
return Promise.resolve(1);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
export function runAgentCommand(args) {
|
|
261
|
+
const subcommand = args[0];
|
|
262
|
+
if (!subcommand || hasFlag(args, "--help", "-h", "help")) {
|
|
263
|
+
printUsage();
|
|
264
|
+
return Promise.resolve(subcommand ? 0 : 1);
|
|
265
|
+
}
|
|
266
|
+
switch (subcommand) {
|
|
267
|
+
case "status":
|
|
268
|
+
return runStatus(args.slice(1));
|
|
269
|
+
case "open":
|
|
270
|
+
return runOpen(args.slice(1));
|
|
271
|
+
case "inspect":
|
|
272
|
+
return runInspect(args.slice(1));
|
|
273
|
+
case "accept":
|
|
274
|
+
return runAccept(args.slice(1));
|
|
275
|
+
case "reset":
|
|
276
|
+
return runReset(args.slice(1));
|
|
277
|
+
case "key":
|
|
278
|
+
return runKey(args.slice(1));
|
|
279
|
+
default:
|
|
280
|
+
console.error(`Unknown agent subcommand: ${subcommand}`);
|
|
281
|
+
printUsage();
|
|
282
|
+
return Promise.resolve(1);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AAmqBA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B7D"}
|
package/dist/commands/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createApp, deleteApp, disableHosting, enableHosting, getHostingState, getProvisioningStatus, } from "../lib/api.js";
|
|
1
|
+
import { ApiError, createApp, deleteApp, disableHosting, enableHosting, getHostingState, getProvisioningStatus, } from "../lib/api.js";
|
|
2
2
|
import { clearActiveApp, getActiveApp, listAppsWithActive, resolveAppContext, setActiveApp, validateAppForSelection, } from "../lib/app.js";
|
|
3
3
|
import { hasFlag, readFlag } from "../lib/args.js";
|
|
4
4
|
import { resolveStoredAuth } from "../lib/auth.js";
|
|
@@ -18,6 +18,7 @@ const ACTIVE_PROVISIONING_STATUSES = new Set(["pending", "running"]);
|
|
|
18
18
|
const TERMINAL_PROVISIONING_STATUSES = new Set(["completed", "completed_with_warnings", "failed"]);
|
|
19
19
|
const PROVISIONING_POLL_INTERVAL_MS = 1500;
|
|
20
20
|
const PROVISIONING_WAIT_WINDOW_MS = 30_000;
|
|
21
|
+
const REPO_STEP_KEY = "repository";
|
|
21
22
|
function printUsage() {
|
|
22
23
|
console.log("Usage: buildspace app <subcommand> [options]");
|
|
23
24
|
console.log("");
|
|
@@ -26,6 +27,7 @@ function printUsage() {
|
|
|
26
27
|
console.log(" current Show the current resolved app");
|
|
27
28
|
console.log(" use <slug> Set the active app");
|
|
28
29
|
console.log(" create Create a new app");
|
|
30
|
+
console.log(" status [<slug>] Show hosting status for an app");
|
|
29
31
|
console.log(" delete <slug> Soft-delete an app");
|
|
30
32
|
console.log(" hosting <status|enable|disable> Manage hosting per environment");
|
|
31
33
|
}
|
|
@@ -37,6 +39,8 @@ function printCreateUsage() {
|
|
|
37
39
|
console.log(" --slug <slug> Optional app slug override");
|
|
38
40
|
console.log(" --description <text> Optional description");
|
|
39
41
|
console.log(" --category <value> Optional category");
|
|
42
|
+
console.log(" --json Output result as JSON and skip provisioning wait");
|
|
43
|
+
console.log(" --no-wait Skip provisioning wait entirely");
|
|
40
44
|
}
|
|
41
45
|
function printDeleteUsage() {
|
|
42
46
|
console.log("Usage: buildspace app delete <slug> --confirm <slug> [--note <text>]");
|
|
@@ -95,31 +99,138 @@ function formatProvisioningLine(session) {
|
|
|
95
99
|
const label = activeStep?.label ?? "Finalizing provisioning";
|
|
96
100
|
return `${label} (${session.percent}%)`;
|
|
97
101
|
}
|
|
98
|
-
async function
|
|
99
|
-
const startedAt = Date.now();
|
|
102
|
+
async function pollUntilRepoReady(sessionId, auth, deadlineMs) {
|
|
100
103
|
let lastLine = null;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const result = await getProvisioningStatus(sessionId, auth);
|
|
104
|
-
const { session } = result;
|
|
105
|
-
lastSession = session;
|
|
104
|
+
while (Date.now() < deadlineMs) {
|
|
105
|
+
const { session } = await getProvisioningStatus(sessionId, auth);
|
|
106
106
|
const line = formatProvisioningLine(session);
|
|
107
107
|
if (line !== lastLine) {
|
|
108
108
|
console.log(` ${line}`);
|
|
109
109
|
lastLine = line;
|
|
110
110
|
}
|
|
111
111
|
if (TERMINAL_PROVISIONING_STATUSES.has(session.status)) {
|
|
112
|
-
return session;
|
|
112
|
+
return { reachedTerminal: true, session };
|
|
113
113
|
}
|
|
114
114
|
if (!ACTIVE_PROVISIONING_STATUSES.has(session.status)) {
|
|
115
|
-
return session;
|
|
115
|
+
return { reachedTerminal: false, session };
|
|
116
|
+
}
|
|
117
|
+
const repoStep = session.steps.find((s) => s.key === REPO_STEP_KEY);
|
|
118
|
+
if (repoStep?.status === "complete" || repoStep?.status === "warning") {
|
|
119
|
+
return { reachedTerminal: false, session };
|
|
120
|
+
}
|
|
121
|
+
await sleep(PROVISIONING_POLL_INTERVAL_MS);
|
|
122
|
+
}
|
|
123
|
+
// Deadline expired — do one final fetch to return current state
|
|
124
|
+
const { session } = await getProvisioningStatus(sessionId, auth);
|
|
125
|
+
return { reachedTerminal: TERMINAL_PROVISIONING_STATUSES.has(session.status), session };
|
|
126
|
+
}
|
|
127
|
+
async function pollUntilTerminal(sessionId, auth, deadlineMs) {
|
|
128
|
+
while (Date.now() < deadlineMs) {
|
|
129
|
+
const { session } = await getProvisioningStatus(sessionId, auth);
|
|
130
|
+
if (TERMINAL_PROVISIONING_STATUSES.has(session.status)) {
|
|
131
|
+
return { session, timedOut: false };
|
|
132
|
+
}
|
|
133
|
+
if (!ACTIVE_PROVISIONING_STATUSES.has(session.status)) {
|
|
134
|
+
return { session, timedOut: false };
|
|
116
135
|
}
|
|
117
136
|
await sleep(PROVISIONING_POLL_INTERVAL_MS);
|
|
118
137
|
}
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
const { session } = await getProvisioningStatus(sessionId, auth).catch(() => ({
|
|
139
|
+
session: null,
|
|
140
|
+
}));
|
|
141
|
+
return { session, timedOut: true };
|
|
142
|
+
}
|
|
143
|
+
function buildCreateAppInput(name, args) {
|
|
144
|
+
const slug = readFlag(args, "--slug")?.trim();
|
|
145
|
+
const description = readFlag(args, "--description")?.trim();
|
|
146
|
+
const category = readFlag(args, "--category")?.trim();
|
|
147
|
+
return {
|
|
148
|
+
name,
|
|
149
|
+
...(slug ? { slug } : {}),
|
|
150
|
+
...(description ? { description } : {}),
|
|
151
|
+
...(category ? { category } : {}),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function writeJsonCommandError(error, fallback) {
|
|
155
|
+
const code = error instanceof ApiError ? error.code : "NETWORK_ERROR";
|
|
156
|
+
const message = error instanceof Error ? error.message : fallback;
|
|
157
|
+
process.stderr.write(`${JSON.stringify({ error: message, code })}\n`);
|
|
158
|
+
}
|
|
159
|
+
async function printCreateResultHuman(result, noWait, auth) {
|
|
160
|
+
console.log(`Created app ${result.app.name} (${result.app.slug})`);
|
|
161
|
+
console.log("Active app updated.");
|
|
162
|
+
if (result.keys.length > 0) {
|
|
163
|
+
console.log("");
|
|
164
|
+
console.log("Initial API keys:");
|
|
165
|
+
for (const key of result.keys) {
|
|
166
|
+
console.log(` ${key.environment}/${key.type}: ${key.key}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (noWait) {
|
|
170
|
+
console.log("");
|
|
171
|
+
console.log("Provisioning is running in the background.");
|
|
172
|
+
console.log(`Run \`buildspace app status ${result.app.slug}\` to check progress.`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
console.log("");
|
|
176
|
+
await waitAndPrintCreateProgress(result.provisioningSession.id, result.app.slug, auth);
|
|
177
|
+
}
|
|
178
|
+
console.log("");
|
|
179
|
+
console.log(" Run your coding agent of choice to build your app.");
|
|
180
|
+
console.log(" buildspace deploy # when you're ready to ship a dev deploy");
|
|
181
|
+
await maybeShowSkillsHint();
|
|
182
|
+
}
|
|
183
|
+
function printCreateNextSteps(slug) {
|
|
184
|
+
console.log("Next steps:");
|
|
185
|
+
console.log(` buildspace init --app ${slug} # clone repo and pull dev env vars`);
|
|
186
|
+
console.log(` cd ${slug}`);
|
|
187
|
+
console.log(" bun dev");
|
|
188
|
+
}
|
|
189
|
+
async function waitAndPrintCreateProgress(sessionId, slug, auth) {
|
|
190
|
+
console.log("Provisioning infrastructure...");
|
|
191
|
+
const deadline = Date.now() + PROVISIONING_WAIT_WINDOW_MS;
|
|
192
|
+
const phase1 = await pollUntilRepoReady(sessionId, auth, deadline);
|
|
193
|
+
if (phase1.reachedTerminal) {
|
|
194
|
+
printProvisioningFinalStatus(phase1.session);
|
|
195
|
+
console.log("");
|
|
196
|
+
printCreateNextSteps(slug);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
console.log("");
|
|
200
|
+
console.log("Repository ready.");
|
|
201
|
+
console.log("");
|
|
202
|
+
printCreateNextSteps(slug);
|
|
203
|
+
console.log("");
|
|
204
|
+
console.log("Hosting, database, and storage are finishing setup in the background (~30s).");
|
|
205
|
+
const phase2 = await pollUntilTerminal(sessionId, auth, deadline);
|
|
206
|
+
if (phase2.timedOut || !phase2.session) {
|
|
207
|
+
console.log(`Run \`buildspace app status ${slug}\` to check when setup is complete.`);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
printProvisioningFinalStatus(phase2.session);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function printProvisioningFinalStatus(session) {
|
|
214
|
+
if (session.status === "completed") {
|
|
215
|
+
console.log("Infrastructure setup complete.");
|
|
216
|
+
}
|
|
217
|
+
else if (session.status === "completed_with_warnings") {
|
|
218
|
+
console.log("Infrastructure setup complete with warnings.");
|
|
219
|
+
}
|
|
220
|
+
else if (session.status === "failed") {
|
|
221
|
+
console.log("Infrastructure setup failed.");
|
|
222
|
+
}
|
|
223
|
+
if (session.warnings.length > 0) {
|
|
224
|
+
console.log("");
|
|
225
|
+
console.log("Setup warnings:");
|
|
226
|
+
for (const warning of session.warnings) {
|
|
227
|
+
console.log(` - ${warning}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (session.errorMessage) {
|
|
231
|
+
console.log("");
|
|
232
|
+
console.log(`Setup error: ${session.errorMessage}`);
|
|
121
233
|
}
|
|
122
|
-
return lastSession;
|
|
123
234
|
}
|
|
124
235
|
async function runList(args) {
|
|
125
236
|
const json = hasFlag(args, "--json");
|
|
@@ -187,23 +298,21 @@ async function runCreate(args) {
|
|
|
187
298
|
return 0;
|
|
188
299
|
}
|
|
189
300
|
const json = hasFlag(args, "--json");
|
|
301
|
+
const noWait = json || hasFlag(args, "--no-wait");
|
|
190
302
|
const name = readFlag(args, "--name")?.trim();
|
|
191
|
-
const slug = readFlag(args, "--slug")?.trim();
|
|
192
|
-
const description = readFlag(args, "--description")?.trim();
|
|
193
|
-
const category = readFlag(args, "--category")?.trim();
|
|
194
303
|
if (!name) {
|
|
195
|
-
|
|
196
|
-
|
|
304
|
+
if (json) {
|
|
305
|
+
process.stderr.write(`${JSON.stringify({ error: "Missing required --name.", code: "VALIDATION_ERROR" })}\n`);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
console.error("Missing required --name.");
|
|
309
|
+
printCreateUsage();
|
|
310
|
+
}
|
|
197
311
|
return 1;
|
|
198
312
|
}
|
|
199
313
|
const auth = await resolveStoredAuth();
|
|
200
314
|
try {
|
|
201
|
-
const result = await createApp(
|
|
202
|
-
name,
|
|
203
|
-
...(slug ? { slug } : {}),
|
|
204
|
-
...(description ? { description } : {}),
|
|
205
|
-
...(category ? { category } : {}),
|
|
206
|
-
}, auth);
|
|
315
|
+
const result = await createApp(buildCreateAppInput(name, args), auth);
|
|
207
316
|
await setActiveApp(result.app);
|
|
208
317
|
trackEvent("cli.app.created");
|
|
209
318
|
if (json) {
|
|
@@ -211,62 +320,60 @@ async function runCreate(args) {
|
|
|
211
320
|
app: { id: result.app.id, slug: result.app.slug, name: result.app.name },
|
|
212
321
|
environments: result.environments,
|
|
213
322
|
keys: result.keys,
|
|
323
|
+
provisioningSession: {
|
|
324
|
+
id: result.provisioningSession.id,
|
|
325
|
+
status: result.provisioningSession.status,
|
|
326
|
+
},
|
|
214
327
|
}, null, 2));
|
|
215
328
|
return 0;
|
|
216
329
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
console.log(` ${key.environment}/${key.type}: ${key.key}`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
console.log("");
|
|
227
|
-
console.log("Provisioning infrastructure. This usually takes around 30 seconds.");
|
|
228
|
-
const provisioningSession = await waitForProvisioning(result.provisioningSession.id, auth);
|
|
229
|
-
if (provisioningSession.status === "completed") {
|
|
230
|
-
console.log("Provisioning finished successfully.");
|
|
231
|
-
}
|
|
232
|
-
else if (provisioningSession.status === "completed_with_warnings") {
|
|
233
|
-
console.log("Provisioning finished with warnings.");
|
|
234
|
-
}
|
|
235
|
-
else if (provisioningSession.status === "failed") {
|
|
236
|
-
console.log("Provisioning failed.");
|
|
330
|
+
await printCreateResultHuman(result, noWait, auth);
|
|
331
|
+
return 0;
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
if (json) {
|
|
335
|
+
writeJsonCommandError(error, "Failed to create app");
|
|
237
336
|
}
|
|
238
337
|
else {
|
|
239
|
-
console.
|
|
240
|
-
console.log(`Check the dashboard or run \`buildspace app hosting status ${result.app.slug}\` in a moment for the latest state.`);
|
|
338
|
+
console.error(error instanceof Error ? error.message : "Failed to create app");
|
|
241
339
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
340
|
+
return 1;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function buildHostingEnvMap(hosting) {
|
|
344
|
+
const envMap = {};
|
|
345
|
+
for (const env of hosting.environments) {
|
|
346
|
+
const url = env.hosting?.managedDomain
|
|
347
|
+
? `https://${env.hosting.managedDomain}`
|
|
348
|
+
: (env.hosting?.publicUrl ?? null);
|
|
349
|
+
envMap[env.envType] = { status: env.hosting?.status ?? "disabled", url };
|
|
350
|
+
}
|
|
351
|
+
return envMap;
|
|
352
|
+
}
|
|
353
|
+
async function runStatus(args) {
|
|
354
|
+
const json = hasFlag(args, "--json");
|
|
355
|
+
const auth = await resolveStoredAuth();
|
|
356
|
+
try {
|
|
357
|
+
const context = await resolveAppContext(normalizeAppArgs(args), auth);
|
|
358
|
+
const hosting = await getHostingState(context.app.id, auth);
|
|
359
|
+
if (json) {
|
|
360
|
+
const { app } = context;
|
|
361
|
+
console.log(JSON.stringify({
|
|
362
|
+
app: { id: app.id, slug: app.slug, name: app.name },
|
|
363
|
+
hosting: buildHostingEnvMap(hosting),
|
|
364
|
+
}, null, 2));
|
|
365
|
+
return 0;
|
|
252
366
|
}
|
|
253
|
-
|
|
254
|
-
console.log("Next steps:");
|
|
255
|
-
console.log(" To connect this app locally and get it running in your terminal:");
|
|
256
|
-
console.log(` buildspace init --app ${result.app.slug} # clone, set up Bun, and pull dev env vars`);
|
|
257
|
-
console.log(` cd ${result.app.slug}`);
|
|
258
|
-
console.log(" bun dev # start local development");
|
|
259
|
-
console.log("");
|
|
260
|
-
console.log(" Run your coding agent of choice to build your app.");
|
|
261
|
-
console.log("");
|
|
262
|
-
console.log(" When you're ready to ship a dev deploy:");
|
|
263
|
-
console.log(" buildspace deploy");
|
|
264
|
-
await maybeShowSkillsHint();
|
|
367
|
+
printHostingStatus(hosting);
|
|
265
368
|
return 0;
|
|
266
369
|
}
|
|
267
370
|
catch (error) {
|
|
268
|
-
|
|
269
|
-
|
|
371
|
+
if (json) {
|
|
372
|
+
writeJsonCommandError(error, "Failed to get status");
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
console.error(error instanceof Error ? error.message : "Failed to get status");
|
|
376
|
+
}
|
|
270
377
|
return 1;
|
|
271
378
|
}
|
|
272
379
|
}
|
|
@@ -417,6 +524,8 @@ export function runAppCommand(args) {
|
|
|
417
524
|
return runUse(args.slice(1));
|
|
418
525
|
case "create":
|
|
419
526
|
return runCreate(args.slice(1));
|
|
527
|
+
case "status":
|
|
528
|
+
return runStatus(args.slice(1));
|
|
420
529
|
case "delete":
|
|
421
530
|
return runDelete(args.slice(1));
|
|
422
531
|
case "hosting":
|