@lizard-build/cli 0.3.74 → 0.3.75

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/dist/lib/api.d.ts CHANGED
@@ -31,12 +31,15 @@ export declare function isAuthError(err: unknown): boolean;
31
31
  * optimistic-concurrency conflicts, which must stay a retryable conflict.
32
32
  */
33
33
  export declare function isProjectDeletedError(err: unknown): err is APIError;
34
+ /** Like api.get, but returns the raw response body instead of JSON.parse-ing
35
+ * it — for endpoints that reply with `text/plain` (e.g. sandbox file reads). */
36
+ export declare function getRawText(path: string): Promise<string>;
34
37
  export declare const api: {
35
38
  get: <T = any>(path: string) => Promise<T>;
36
39
  post: <T = any>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<T>;
37
40
  put: <T = any>(path: string, body?: unknown) => Promise<T>;
38
41
  patch: <T = any>(path: string, body?: unknown) => Promise<T>;
39
- delete: <T = any>(path: string) => Promise<T>;
42
+ delete: <T = any>(path: string, body?: unknown) => Promise<T>;
40
43
  };
41
44
  /** Stream SSE and call handler for each event. Return false to stop.
42
45
  *
package/dist/lib/api.js CHANGED
@@ -94,12 +94,36 @@ async function request(method, path, body, extraHeaders = {}) {
94
94
  return undefined;
95
95
  return JSON.parse(text);
96
96
  }
97
+ /** Like api.get, but returns the raw response body instead of JSON.parse-ing
98
+ * it — for endpoints that reply with `text/plain` (e.g. sandbox file reads). */
99
+ export async function getRawText(path) {
100
+ const url = baseURL + path;
101
+ const token = _accessToken || getToken();
102
+ const headers = { "User-Agent": USER_AGENT };
103
+ if (token)
104
+ headers["Authorization"] = `Bearer ${token}`;
105
+ const res = await fetch(url, { method: "GET", headers });
106
+ if (!res.ok) {
107
+ let msg = res.statusText;
108
+ let code = "";
109
+ let body = null;
110
+ try {
111
+ const j = (await res.json());
112
+ body = j;
113
+ msg = j.error || j.message || msg;
114
+ code = j.code || "";
115
+ }
116
+ catch { }
117
+ throw new APIError(res.status, msg, code, body);
118
+ }
119
+ return res.text();
120
+ }
97
121
  export const api = {
98
122
  get: (path) => request("GET", path),
99
123
  post: (path, body, headers) => request("POST", path, body, headers),
100
124
  put: (path, body) => request("PUT", path, body),
101
125
  patch: (path, body) => request("PATCH", path, body),
102
- delete: (path) => request("DELETE", path),
126
+ delete: (path, body) => request("DELETE", path, body),
103
127
  };
104
128
  /** Compare two Redis-stream-style event ids (`<ms>-<seq>`). Returns true when
105
129
  * `id` is at or before `last` — i.e. a replayed event we've already shown.
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const CURRENT_VERSION = "0.3.74";
1
+ export declare const CURRENT_VERSION = "0.3.75";
2
2
  /**
3
3
  * True only when running as the Bun-compiled standalone binary. Under
4
4
  * npm/node, `process.execPath` is the *node* executable — self-update would
@@ -4,7 +4,7 @@ import { Readable } from "node:stream";
4
4
  import { join, dirname } from "node:path";
5
5
  import os from "node:os";
6
6
  import { spawn } from "node:child_process";
7
- export const CURRENT_VERSION = "0.3.74";
7
+ export const CURRENT_VERSION = "0.3.75";
8
8
  const RELEASES_API = "https://api.github.com/repos/lizard-build/lizard-cli/releases/latest";
9
9
  const RELEASE_BASE = "https://github.com/lizard-build/lizard-cli/releases/latest/download";
10
10
  /** Minimum gap between background update checks. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lizard-build/cli",
3
- "version": "0.3.74",
3
+ "version": "0.3.75",
4
4
  "description": "Lizard CLI — deploy and manage apps on Lizard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,456 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import fs from "node:fs";
4
+ import * as https from "node:https";
5
+ import * as http from "node:http";
6
+ import * as p from "@clack/prompts";
7
+ import { Command } from "commander";
8
+ import { api, getBaseURL, getRawText, streamSSE, withQuery, withScope, type ResourceScope } from "../lib/api.js";
9
+ import { getToken } from "../lib/auth.js";
10
+ import { resolveProjectScope } from "../lib/resolve.js";
11
+ import { resolveWorkspace } from "../lib/picker.js";
12
+ import { success, info, error, isJSONMode, printJSON, table, statusColor, timeAgo, isTTY } from "../lib/format.js";
13
+
14
+ const VALID_TEMPLATES = ["base", "code-interpreter-v1"] as const;
15
+
16
+ interface SandboxRecord {
17
+ sandboxId: string;
18
+ id: string;
19
+ template: string;
20
+ status: string;
21
+ region: string;
22
+ cpus: number;
23
+ memoryMb: number;
24
+ guestIp?: string;
25
+ startedAt: number | string;
26
+ endAt?: number | string;
27
+ expiresAt?: number | string;
28
+ projectId?: string | null;
29
+ }
30
+
31
+ interface VolumeRecord {
32
+ id: string;
33
+ name: string;
34
+ }
35
+
36
+ function parseIntOption(v: string): number {
37
+ const n = parseInt(v, 10);
38
+ if (Number.isNaN(n)) throw new Error(`Invalid number: ${v}`);
39
+ return n;
40
+ }
41
+
42
+ /** Resolve a volume by name or ID. Requires a project — volumes are project-scoped. */
43
+ async function resolveVolumeId(
44
+ projectId: string,
45
+ scope: ResourceScope,
46
+ nameOrId: string,
47
+ ): Promise<string> {
48
+ const volumes = await api.get<VolumeRecord[]>(
49
+ withScope(`/api/projects/${projectId}/volumes`, scope),
50
+ );
51
+ const lower = nameOrId.toLowerCase();
52
+ const match = volumes.find(
53
+ (v) => v.id.toLowerCase() === lower || v.name.toLowerCase() === lower,
54
+ );
55
+ if (!match) {
56
+ throw new Error(
57
+ `Volume "${nameOrId}" not found. Available: ${volumes.map((v) => v.name).join(", ") || "(none)"}`,
58
+ );
59
+ }
60
+ return match.id;
61
+ }
62
+
63
+ function printSandboxList(sandboxes: SandboxRecord[]) {
64
+ if (isJSONMode()) {
65
+ printJSON(sandboxes);
66
+ return;
67
+ }
68
+ if (sandboxes.length === 0) {
69
+ console.log("No sandboxes. Use `lizard sandbox create`.");
70
+ return;
71
+ }
72
+ table(
73
+ ["ID", "Template", "Status", "Region", "CPU/Mem", "Created"],
74
+ sandboxes.map((s) => [
75
+ s.id,
76
+ s.template,
77
+ statusColor(s.status),
78
+ s.region,
79
+ `${s.cpus} vCPU / ${s.memoryMb} MB`,
80
+ timeAgo(s.startedAt as any),
81
+ ]),
82
+ );
83
+ }
84
+
85
+ export function registerSandbox(program: Command) {
86
+ const sb = program
87
+ .command("sandbox")
88
+ .alias("sb")
89
+ .description("Manage ephemeral compute sandboxes");
90
+
91
+ sb.command("create")
92
+ .description("Create a sandbox")
93
+ .option("-t, --template <name>", `Template (${VALID_TEMPLATES.join(", ")})`, "base")
94
+ .option("--cpus <n>", "vCPUs (1-8, default 1)", parseIntOption)
95
+ .option("--memory <mb>", "Memory in MB (128-8192, default 2048)", parseIntOption)
96
+ .option("--timeout <ms>", "Idle timeout in ms before auto-stop (default 300000)", parseIntOption)
97
+ .option("--region <code>", "Region to create the sandbox in")
98
+ .option("--volume <name-or-id>", "Attach a persistent volume (requires --project or a linked project)")
99
+ .option("-p, --project <id>", "Associate with a project (name, slug, or ID)")
100
+ .option("-w, --workspace <ws>", "Workspace to create the sandbox in")
101
+ .action(async (opts) => {
102
+ if (opts.template && !(VALID_TEMPLATES as readonly string[]).includes(opts.template)) {
103
+ throw new Error(`Unknown template "${opts.template}". Available: ${VALID_TEMPLATES.join(", ")}`);
104
+ }
105
+
106
+ let projectId: string | undefined;
107
+ let workspaceId: string | undefined;
108
+ let scope: ResourceScope | undefined;
109
+
110
+ if (opts.project || opts.volume) {
111
+ const resolved = await resolveProjectScope(opts.project);
112
+ projectId = resolved.projectId;
113
+ scope = resolved.scope;
114
+ workspaceId = resolved.scope.workspaceId ?? undefined;
115
+ } else if (opts.workspace) {
116
+ workspaceId = (await resolveWorkspace(opts.workspace)).id;
117
+ }
118
+
119
+ let volumeId: string | undefined;
120
+ if (opts.volume) {
121
+ volumeId = await resolveVolumeId(projectId!, scope!, opts.volume);
122
+ }
123
+
124
+ const spinner = isJSONMode() ? null : ora("Creating sandbox...").start();
125
+ let sandbox: SandboxRecord;
126
+ try {
127
+ sandbox = await api.post<SandboxRecord>("/api/sandboxes", {
128
+ template: opts.template,
129
+ cpus: opts.cpus,
130
+ memoryMb: opts.memory,
131
+ timeoutMs: opts.timeout,
132
+ region: opts.region,
133
+ volumeId,
134
+ workspaceId,
135
+ projectId,
136
+ });
137
+ } catch (e) {
138
+ spinner?.stop();
139
+ throw e;
140
+ }
141
+ spinner?.stop();
142
+
143
+ if (isJSONMode()) {
144
+ printJSON(sandbox);
145
+ return;
146
+ }
147
+ success(`Sandbox ${chalk.bold(sandbox.id)} created`);
148
+ info(chalk.dim(` Template: ${sandbox.template} Region: ${sandbox.region}`));
149
+ info(chalk.dim(` Exec: lizard sandbox exec ${sandbox.id} -- <cmd>`));
150
+ });
151
+
152
+ sb.command("list")
153
+ .alias("ls")
154
+ .description("List sandboxes")
155
+ .option("-p, --project <id>", "Only list sandboxes for this project")
156
+ .action(async (opts) => {
157
+ if (opts.project) {
158
+ const { projectId, scope } = await resolveProjectScope(opts.project);
159
+ const sandboxes = await api.get<SandboxRecord[]>(
160
+ withScope(`/api/projects/${projectId}/sandboxes`, scope),
161
+ );
162
+ printSandboxList(sandboxes);
163
+ return;
164
+ }
165
+ const sandboxes = await api.get<SandboxRecord[]>("/api/sandboxes");
166
+ printSandboxList(sandboxes);
167
+ });
168
+
169
+ sb.command("rm")
170
+ .alias("delete")
171
+ .argument("<id>", "Sandbox ID")
172
+ .description("Delete a sandbox")
173
+ .option("-y, --yes", "Skip confirmation")
174
+ .action(async (id: string, opts) => {
175
+ if (!opts.yes && isTTY() && !isJSONMode()) {
176
+ const ok = await p.confirm({ message: `Delete sandbox ${chalk.bold(id)}?` });
177
+ if (p.isCancel(ok) || !ok) process.exit(5);
178
+ }
179
+ await api.delete(`/api/sandboxes/${id}`);
180
+ if (isJSONMode()) printJSON({ id, status: "deleted" });
181
+ else success(`Sandbox ${chalk.bold(id)} deleted`);
182
+ });
183
+
184
+ sb.command("pause")
185
+ .argument("<id>", "Sandbox ID")
186
+ .description("Pause a sandbox")
187
+ .action(async (id: string) => {
188
+ const updated = await api.post<SandboxRecord>(`/api/sandboxes/${id}/pause`);
189
+ if (isJSONMode()) printJSON(updated);
190
+ else success(`Sandbox ${chalk.bold(id)} paused`);
191
+ });
192
+
193
+ sb.command("resume")
194
+ .argument("<id>", "Sandbox ID")
195
+ .description("Resume a paused sandbox")
196
+ .action(async (id: string) => {
197
+ const updated = await api.post<SandboxRecord>(`/api/sandboxes/${id}/resume`);
198
+ if (isJSONMode()) printJSON(updated);
199
+ else success(`Sandbox ${chalk.bold(id)} resumed`);
200
+ });
201
+
202
+ sb.command("timeout")
203
+ .argument("<id>", "Sandbox ID")
204
+ .argument("<ms>", "New idle timeout in milliseconds", parseIntOption)
205
+ .description("Update a sandbox's idle timeout")
206
+ .action(async (id: string, ms: number) => {
207
+ const updated = await api.post<SandboxRecord>(`/api/sandboxes/${id}/timeout`, { timeoutMs: ms });
208
+ if (isJSONMode()) printJSON(updated);
209
+ else success(`Sandbox ${chalk.bold(id)} timeout set to ${ms}ms`);
210
+ });
211
+
212
+ sb.command("exec")
213
+ .argument("<id>", "Sandbox ID")
214
+ .argument("[cmd...]", "Command and args to run (pass after `--`, e.g. `-- ls -la /tmp`)")
215
+ .description("Execute a command inside a sandbox, streaming output")
216
+ .addHelpText(
217
+ "after",
218
+ `
219
+ Examples:
220
+ lizard sandbox exec sb_abc123 -- ls -la /tmp
221
+ lizard sandbox exec sb_abc123 -- python3 script.py`,
222
+ )
223
+ .action(async (id: string, cmdArgs: string[]) => {
224
+ if (cmdArgs.length === 0) {
225
+ throw new Error("No command given. Usage: lizard sandbox exec <id> -- <cmd> [args...]");
226
+ }
227
+ // The server runs `cmd` via `/bin/sh -c` only when it's a string — an
228
+ // array execs the binary directly with no PATH lookup or shell
229
+ // features (pipes, globs). Shell-quote and join so `sh -c` sees it.
230
+ const cmd = cmdArgs.map(shellQuote).join(" ");
231
+ if (!isJSONMode()) {
232
+ process.stdout.write(chalk.dim(`$ ${cmd}\n`));
233
+ }
234
+ const exitCode = await execStream(id, cmd, (stream, line) => {
235
+ if (stream === "stderr") process.stderr.write(line + "\n");
236
+ else process.stdout.write(line + "\n");
237
+ });
238
+ process.exit(exitCode);
239
+ });
240
+
241
+ sb.command("logs")
242
+ .argument("<id>", "Sandbox ID")
243
+ .description("Stream sandbox vm-agent logs")
244
+ .option("--tail <n>", "Number of historical lines to include before following", "200")
245
+ .action(async (id: string, opts) => {
246
+ info(chalk.dim("Streaming logs... (Ctrl+C to stop)\n"));
247
+ await streamSSE(withQuery(`/api/sandboxes/${id}/logs`, { tail: opts.tail }), (_event, data) => {
248
+ let parsed: any;
249
+ try {
250
+ parsed = JSON.parse(data);
251
+ } catch {
252
+ parsed = { message: data };
253
+ }
254
+ if (isJSONMode()) {
255
+ process.stdout.write(JSON.stringify(parsed) + "\n");
256
+ } else {
257
+ process.stdout.write((parsed.message ?? data) + "\n");
258
+ }
259
+ return true;
260
+ });
261
+ });
262
+
263
+ sb.command("expose")
264
+ .argument("<id>", "Sandbox ID")
265
+ .argument("<port>", "Port to expose", parseIntOption)
266
+ .description("Expose a sandbox port over HTTPS")
267
+ .action(async (id: string, port: number) => {
268
+ const result = await api.post<{ hostname: string; url: string; port: number }>(
269
+ `/api/sandboxes/${id}/expose/${port}`,
270
+ );
271
+ if (isJSONMode()) {
272
+ printJSON(result);
273
+ return;
274
+ }
275
+ success(`Port ${port} exposed`);
276
+ info(` ${chalk.cyan(result.url)}`);
277
+ });
278
+
279
+ sb.command("unexpose")
280
+ .argument("<id>", "Sandbox ID")
281
+ .argument("<port>", "Port to unexpose", parseIntOption)
282
+ .description("Remove an exposed sandbox port")
283
+ .action(async (id: string, port: number) => {
284
+ await api.delete(`/api/sandboxes/${id}/expose/${port}`);
285
+ if (isJSONMode()) printJSON({ id, port, status: "unexposed" });
286
+ else success(`Port ${port} unexposed`);
287
+ });
288
+
289
+ registerSandboxFiles(sb);
290
+ }
291
+
292
+ function registerSandboxFiles(sb: Command) {
293
+ const files = sb.command("files").description("Manage files inside a sandbox");
294
+
295
+ files
296
+ .command("ls")
297
+ .argument("<id>", "Sandbox ID")
298
+ .argument("[path]", "Directory to list", "/")
299
+ .description("List a directory inside a sandbox")
300
+ .action(async (id: string, path: string) => {
301
+ const entries = await api.get<Array<{ type: string; name: string; path: string; size: number }>>(
302
+ withQuery(`/api/sandboxes/${id}/files/list`, { path }),
303
+ );
304
+ if (isJSONMode()) {
305
+ printJSON(entries);
306
+ return;
307
+ }
308
+ if (entries.length === 0) {
309
+ console.log("(empty)");
310
+ return;
311
+ }
312
+ table(
313
+ ["Type", "Name", "Size"],
314
+ entries.map((e) => [e.type, e.name, e.type === "dir" ? "" : `${e.size}B`]),
315
+ );
316
+ });
317
+
318
+ files
319
+ .command("cat")
320
+ .argument("<id>", "Sandbox ID")
321
+ .argument("<path>", "File path inside the sandbox")
322
+ .description("Print a file from inside a sandbox")
323
+ .action(async (id: string, path: string) => {
324
+ const content = await getRawText(withQuery(`/api/sandboxes/${id}/files`, { path }));
325
+ process.stdout.write(content);
326
+ });
327
+
328
+ files
329
+ .command("put")
330
+ .argument("<id>", "Sandbox ID")
331
+ .argument("<local>", "Local file path")
332
+ .argument("<remote>", "Destination path inside the sandbox")
333
+ .description("Upload a local file into a sandbox")
334
+ .action(async (id: string, local: string, remote: string) => {
335
+ const content = fs.readFileSync(local, "utf-8");
336
+ await api.post(`/api/sandboxes/${id}/files`, { path: remote, content });
337
+ if (isJSONMode()) printJSON({ id, path: remote, status: "written" });
338
+ else success(`Wrote ${chalk.bold(remote)} in sandbox ${id}`);
339
+ });
340
+
341
+ files
342
+ .command("get")
343
+ .argument("<id>", "Sandbox ID")
344
+ .argument("<remote>", "File path inside the sandbox")
345
+ .argument("<local>", "Local destination path")
346
+ .description("Download a file from a sandbox")
347
+ .action(async (id: string, remote: string, local: string) => {
348
+ const content = await getRawText(withQuery(`/api/sandboxes/${id}/files`, { path: remote }));
349
+ fs.writeFileSync(local, content);
350
+ if (isJSONMode()) printJSON({ id, path: remote, local, status: "downloaded" });
351
+ else success(`Downloaded ${chalk.bold(remote)} to ${local}`);
352
+ });
353
+
354
+ files
355
+ .command("rm")
356
+ .argument("<id>", "Sandbox ID")
357
+ .argument("<path>", "Path inside the sandbox")
358
+ .description("Delete a file or directory inside a sandbox")
359
+ .action(async (id: string, path: string) => {
360
+ await api.delete(`/api/sandboxes/${id}/files`, { path });
361
+ if (isJSONMode()) printJSON({ id, path, status: "deleted" });
362
+ else success(`Deleted ${chalk.bold(path)} in sandbox ${id}`);
363
+ });
364
+ }
365
+
366
+ /** Run a command inside a sandbox, streaming output. Resolves with the exit
367
+ * code: the remote command's code from the `exit` event, or 1 when the
368
+ * server reported an `error` event without one. Mirrors ssh.ts's parser. */
369
+ function execStream(
370
+ sandboxId: string,
371
+ cmd: string,
372
+ onLine: (stream: string, line: string) => void,
373
+ ): Promise<number> {
374
+ return new Promise((resolve, reject) => {
375
+ let exitCode: number | null = null;
376
+ let sawError = false;
377
+ const baseURL = getBaseURL();
378
+ const url = new URL(`${baseURL}/api/sandboxes/${sandboxId}/exec`);
379
+ const token = getToken();
380
+ const body = JSON.stringify({ cmd });
381
+
382
+ const reqHeaders: Record<string, string> = {
383
+ "Content-Type": "application/json",
384
+ "Content-Length": String(Buffer.byteLength(body)),
385
+ Accept: "text/event-stream",
386
+ };
387
+ if (token) reqHeaders["Authorization"] = `Bearer ${token}`;
388
+
389
+ const transport = url.protocol === "https:" ? https : http;
390
+ const req = transport.request(
391
+ {
392
+ hostname: url.hostname,
393
+ port: url.port || (url.protocol === "https:" ? 443 : 80),
394
+ path: url.pathname,
395
+ method: "POST",
396
+ headers: reqHeaders,
397
+ },
398
+ (res) => {
399
+ if (res.statusCode && res.statusCode >= 400) {
400
+ let errBody = "";
401
+ res.on("data", (c: Buffer) => (errBody += c.toString()));
402
+ res.on("end", () => reject(new Error(`exec failed ${res.statusCode}: ${errBody}`)));
403
+ return;
404
+ }
405
+
406
+ let buf = "";
407
+ let currentEvent = "";
408
+ res.setEncoding("utf8");
409
+ res.on("data", (chunk: string) => {
410
+ buf += chunk;
411
+ const lines = buf.split("\n");
412
+ buf = lines.pop() ?? "";
413
+
414
+ for (const line of lines) {
415
+ const trimmed = line.replace(/\r$/, "");
416
+ if (trimmed === "") {
417
+ currentEvent = "";
418
+ } else if (trimmed.startsWith("event:")) {
419
+ currentEvent = trimmed.slice(6).trim();
420
+ } else if (trimmed.startsWith("data:")) {
421
+ const data = trimmed.slice(5).trimStart();
422
+ if (currentEvent === "exit") {
423
+ try { exitCode = JSON.parse(data).exitCode ?? 0; } catch {}
424
+ } else if (currentEvent === "error") {
425
+ sawError = true;
426
+ error(data);
427
+ } else {
428
+ try {
429
+ const parsed = JSON.parse(data);
430
+ onLine(parsed.stream ?? "stdout", parsed.line ?? data);
431
+ } catch {
432
+ onLine("stdout", data);
433
+ }
434
+ }
435
+ }
436
+ }
437
+ });
438
+
439
+ res.on("end", () => resolve(exitCode ?? (sawError ? 1 : 0)));
440
+ res.on("error", reject);
441
+ },
442
+ );
443
+
444
+ req.on("error", reject);
445
+ req.write(body);
446
+ req.end();
447
+ });
448
+ }
449
+
450
+ /** POSIX single-quote escaping. Safe-token chars pass through verbatim;
451
+ * anything else gets wrapped in '…' with embedded `'` rewritten as `'\''`. */
452
+ function shellQuote(arg: string): string {
453
+ if (arg === "") return "''";
454
+ if (/^[A-Za-z0-9_./:=@%+,-]+$/.test(arg)) return arg;
455
+ return "'" + arg.replace(/'/g, "'\\''") + "'";
456
+ }