@lizard-build/cli 0.3.43 → 0.3.45

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.
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerEvents(program: Command): void;
@@ -0,0 +1,70 @@
1
+ import chalk from "chalk";
2
+ import { api } from "../lib/api.js";
3
+ import { resolveProjectScope, getActiveServiceWithKind } from "../lib/resolve.js";
4
+ import { info, error, isJSONMode, printJSON, table, statusColor, timeAgo } from "../lib/format.js";
5
+ export function registerEvents(program) {
6
+ program
7
+ .command("events")
8
+ .description("Show deploy history and replica status for an app")
9
+ .option("-s, --service <id>", "Service name or ID (defaults to linked service)")
10
+ .option("-p, --project <id>", "Project name, slug, or ID")
11
+ .option("-n, --limit <n>", "Max deploys to show", "10")
12
+ .action(async (opts) => {
13
+ const n = parseInt(opts.limit, 10);
14
+ if (isNaN(n) || n < 1) {
15
+ error("--limit must be a positive integer");
16
+ process.exit(1);
17
+ }
18
+ const { projectId } = await resolveProjectScope(opts.project);
19
+ const svc = await getActiveServiceWithKind(opts.service, projectId);
20
+ if (svc.kind === "addon") {
21
+ error(`Deploy events are only available for apps — "${svc.name}" is an addon`);
22
+ process.exit(1);
23
+ }
24
+ const [builds, podStatus] = await Promise.all([
25
+ api.get(`/api/apps/${svc.id}/deploy-events`),
26
+ api
27
+ .get(`/api/apps/${svc.id}/pod-status`)
28
+ .catch(() => ({ pods: [] })),
29
+ ]);
30
+ const slice = builds.slice(0, n);
31
+ if (isJSONMode()) {
32
+ printJSON({
33
+ service: { id: svc.id, name: svc.name },
34
+ pods: podStatus.pods,
35
+ deploys: slice,
36
+ });
37
+ return;
38
+ }
39
+ if (podStatus.pods.length > 0) {
40
+ console.log(chalk.bold("Replicas"));
41
+ table(["Name", "Phase", "Ready", "Restarts", "Started", "Reason"], podStatus.pods.map((pod) => [
42
+ pod.name,
43
+ statusColor(pod.phase.toLowerCase()),
44
+ pod.ready ? chalk.green("✓") : chalk.red("✗"),
45
+ String(pod.restarts),
46
+ pod.startedAt ? timeAgo(pod.startedAt) : chalk.dim("—"),
47
+ pod.reason || chalk.dim("—"),
48
+ ]));
49
+ console.log();
50
+ }
51
+ if (slice.length === 0) {
52
+ info(chalk.dim(`No deploys for ${svc.name} yet.`));
53
+ return;
54
+ }
55
+ console.log(chalk.bold("Deploys"));
56
+ table(["When", "Status", "Trigger", "Commit", "Restarts", "Build"], slice.map((b) => [
57
+ timeAgo(b.createdAt),
58
+ statusColor(b.status),
59
+ b.trigger ?? chalk.dim("—"),
60
+ b.commitSha ? b.commitSha.slice(0, 7) : chalk.dim("—"),
61
+ b.events.length > 0 ? chalk.yellow(String(b.events.length)) : chalk.dim("0"),
62
+ chalk.dim(b.buildId),
63
+ ]));
64
+ if (builds.length > slice.length) {
65
+ info(chalk.dim(`\n(${builds.length - slice.length} more — re-run with -n ${builds.length})`));
66
+ }
67
+ info(chalk.dim("\nCrash details: lizard logs --restarts Build logs: lizard logs --build"));
68
+ });
69
+ }
70
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerMetrics(program: Command): void;
@@ -0,0 +1,280 @@
1
+ import chalk from "chalk";
2
+ import { api, withScope, withQuery, APIError } from "../lib/api.js";
3
+ import { getProjectLink } from "../lib/config.js";
4
+ import { resolveProjectScope, getActiveServiceWithKind } from "../lib/resolve.js";
5
+ import { info, error, isJSONMode, printJSON, table, timeAgo } from "../lib/format.js";
6
+ const RANGES = ["1h", "6h", "24h", "7d", "14d", "30d"];
7
+ export function registerMetrics(program) {
8
+ program
9
+ .command("metrics")
10
+ .description("Show resource metrics (CPU, memory, network, disk) and cost")
11
+ .option("-s, --service <id>", "Service name or ID (defaults to linked service)")
12
+ .option("-p, --project <id>", "Project name, slug, or ID")
13
+ .option("-r, --range <range>", `Time range: ${RANGES.join("|")}`, "1h")
14
+ .option("-w, --watch", "Live view, refreshed every 3s (Ctrl+C to stop)")
15
+ .option("--cost", "Show running resources and cost per hour instead of metrics")
16
+ .action(async (opts) => {
17
+ if (!RANGES.includes(opts.range)) {
18
+ error(`Invalid --range "${opts.range}". Choose one of: ${RANGES.join(", ")}`);
19
+ process.exit(1);
20
+ }
21
+ if (opts.watch && isJSONMode()) {
22
+ error("--watch is interactive and cannot be combined with --json (poll without --watch instead)");
23
+ process.exit(1);
24
+ }
25
+ const { projectId, scope } = await resolveProjectScope(opts.project);
26
+ if (opts.cost) {
27
+ await showCost(projectId, scope);
28
+ return;
29
+ }
30
+ // Service detail when -s is given or a service is linked; otherwise
31
+ // an overview of every service in the project.
32
+ const hasService = Boolean(opts.service || getProjectLink()?.serviceId);
33
+ if (opts.watch) {
34
+ let serviceId;
35
+ if (hasService) {
36
+ serviceId = (await getActiveServiceWithKind(opts.service, projectId)).id;
37
+ }
38
+ await watchLive(projectId, scope, serviceId);
39
+ return;
40
+ }
41
+ if (hasService) {
42
+ await showServiceMetrics(opts.service, projectId, scope, opts.range);
43
+ }
44
+ else {
45
+ await showProjectOverview(projectId, scope);
46
+ }
47
+ });
48
+ }
49
+ // ── Formatting helpers ────────────────────────────────────────────────────
50
+ function fmtBytes(b) {
51
+ if (!isFinite(b) || b < 0)
52
+ return "—";
53
+ if (b < 1024)
54
+ return `${Math.round(b)} B`;
55
+ if (b < 1024 * 1024)
56
+ return `${(b / 1024).toFixed(1)} KB`;
57
+ if (b < 1024 * 1024 * 1024)
58
+ return `${(b / 1024 / 1024).toFixed(1)} MB`;
59
+ return `${(b / 1024 / 1024 / 1024).toFixed(2)} GB`;
60
+ }
61
+ function fmtRate(b) {
62
+ return `${fmtBytes(b)}/s`;
63
+ }
64
+ function fmtMb(mb) {
65
+ return fmtBytes(mb * 1024 * 1024);
66
+ }
67
+ function fmtVcpu(v) {
68
+ return v.toFixed(2);
69
+ }
70
+ /** Render values as a unicode sparkline, downsampled to `width` buckets. */
71
+ function sparkline(values, width = 30) {
72
+ if (values.length === 0)
73
+ return "";
74
+ const blocks = "▁▂▃▄▅▆▇█";
75
+ const buckets = [];
76
+ const per = Math.max(1, Math.ceil(values.length / width));
77
+ for (let i = 0; i < values.length; i += per) {
78
+ const slice = values.slice(i, i + per);
79
+ buckets.push(slice.reduce((a, b) => a + b, 0) / slice.length);
80
+ }
81
+ const max = Math.max(...buckets);
82
+ if (max <= 0)
83
+ return chalk.dim(blocks[0].repeat(buckets.length));
84
+ return buckets
85
+ .map((v) => blocks[Math.min(blocks.length - 1, Math.floor((v / max) * (blocks.length - 1) + 0.5))])
86
+ .join("");
87
+ }
88
+ function seriesByName(series, name) {
89
+ return series.find((s) => s.metric === name)?.values ?? [];
90
+ }
91
+ /** min/avg/max over a series. Rate metrics carry an artificial 0 as their
92
+ * first sample (no previous counter to diff against) — skip it. */
93
+ function stats(values, isRate = false) {
94
+ const vals = isRate && values.length > 1 ? values.slice(1) : values;
95
+ if (vals.length === 0)
96
+ return null;
97
+ return {
98
+ now: vals[vals.length - 1],
99
+ min: Math.min(...vals),
100
+ avg: vals.reduce((a, b) => a + b, 0) / vals.length,
101
+ max: Math.max(...vals),
102
+ values: vals,
103
+ };
104
+ }
105
+ // ── Service detail ────────────────────────────────────────────────────────
106
+ async function fetchServiceMetrics(svc, projectId, scope, range) {
107
+ const path = svc.kind === "app"
108
+ ? withQuery(`/api/apps/${svc.id}/metrics`, { range })
109
+ : withScope(withQuery(`/api/projects/${projectId}/addons/${svc.id}/metrics`, { range }), scope);
110
+ return api.get(path);
111
+ }
112
+ async function showServiceMetrics(serviceFlag, projectId, scope, range) {
113
+ const svc = await getActiveServiceWithKind(serviceFlag, projectId);
114
+ const data = await fetchServiceMetrics(svc, projectId, scope, range);
115
+ if (isJSONMode()) {
116
+ printJSON({ service: { id: svc.id, name: svc.name, kind: svc.kind }, range, ...data });
117
+ return;
118
+ }
119
+ const { series, latest, limits } = data;
120
+ if (series.length === 0 && !latest) {
121
+ info(chalk.dim(`No metrics for ${svc.name} yet — the service may be new or stopped.`));
122
+ return;
123
+ }
124
+ const sampled = latest ? timeAgo(latest.sampledAt) : chalk.dim("no live data");
125
+ console.log(chalk.bold(svc.name) + chalk.dim(` (${svc.kind}) — last ${range}, sampled ${sampled}`));
126
+ console.log();
127
+ const cpu = stats(seriesByName(series, "cpu"));
128
+ const mem = stats(seriesByName(series, "memory"));
129
+ const rx = stats(seriesByName(series, "network_rx"), true);
130
+ const tx = stats(seriesByName(series, "network_tx"), true);
131
+ const dr = stats(seriesByName(series, "disk_read"), true);
132
+ const dw = stats(seriesByName(series, "disk_write"), true);
133
+ const rows = [];
134
+ const push = (label, s, fmt, now) => {
135
+ if (!s)
136
+ return;
137
+ const current = now ?? s.now;
138
+ rows.push([
139
+ label,
140
+ current === null || current === undefined ? chalk.dim("—") : fmt(current),
141
+ fmt(s.min),
142
+ fmt(s.avg),
143
+ fmt(s.max),
144
+ chalk.cyan(sparkline(s.values)),
145
+ ]);
146
+ };
147
+ // "Now" for CPU/memory prefers the live Redis snapshot over the last
148
+ // (up to 90s stale) historical sample.
149
+ push("CPU (vCPU)", cpu, fmtVcpu, latest ? latest.cpu : undefined);
150
+ push("Memory", mem, fmtBytes, latest ? latest.memUsedMb * 1024 * 1024 : undefined);
151
+ push("Net ↓", rx, fmtRate);
152
+ push("Net ↑", tx, fmtRate);
153
+ push("Disk read", dr, fmtRate);
154
+ push("Disk write", dw, fmtRate);
155
+ if (rows.length > 0) {
156
+ table(["Metric", "Now", "Min", "Avg", "Max", "Trend"], rows);
157
+ }
158
+ else if (latest) {
159
+ // Live snapshot only (brand-new VM, no history rows yet)
160
+ table(["Metric", "Now"], [
161
+ ["CPU (vCPU)", fmtVcpu(latest.cpu)],
162
+ ["Memory", `${fmtMb(latest.memUsedMb)} / ${fmtMb(latest.memTotalMb)}`],
163
+ ]);
164
+ }
165
+ console.log();
166
+ const diskUsed = seriesByName(series, "disk_used");
167
+ const diskTotal = seriesByName(series, "disk_total");
168
+ if (diskUsed.length > 0) {
169
+ const used = diskUsed[diskUsed.length - 1];
170
+ const total = diskTotal[diskTotal.length - 1] ?? 0;
171
+ console.log(chalk.dim("Disk used ") + fmtBytes(used) + (total > 0 ? chalk.dim(` / ${fmtBytes(total)}`) : ""));
172
+ }
173
+ console.log(chalk.dim("Limits ") +
174
+ `${(limits.cpuMillis / 1000).toFixed(limits.cpuMillis % 1000 === 0 ? 0 : 1)} vCPU · ${fmtMb(limits.memoryMi)} memory`);
175
+ }
176
+ // ── Project overview ──────────────────────────────────────────────────────
177
+ async function fetchLive(projectId, scope) {
178
+ const data = await api.get(withScope(withQuery(`/api/projects/${projectId}/metrics`, { live: true }), scope));
179
+ return (data.services || []).filter((s) => !s.deleted);
180
+ }
181
+ function overviewRows(services) {
182
+ return services.map((s) => {
183
+ const cpuLimit = s.limits.cpuMillis / 1000;
184
+ return [
185
+ s.label,
186
+ s.type,
187
+ s.latest ? `${fmtVcpu(s.latest.cpu)} / ${cpuLimit}` : chalk.dim("—"),
188
+ s.latest ? `${fmtMb(s.latest.memUsedMb)} / ${fmtMb(s.latest.memTotalMb)}` : chalk.dim("—"),
189
+ s.latest ? timeAgo(s.latest.sampledAt) : chalk.dim("no data"),
190
+ ];
191
+ });
192
+ }
193
+ async function showProjectOverview(projectId, scope) {
194
+ const services = await fetchLive(projectId, scope);
195
+ if (isJSONMode()) {
196
+ printJSON({ services });
197
+ return;
198
+ }
199
+ if (services.length === 0) {
200
+ console.log("No services. Use `lizard add` or `lizard up`.");
201
+ return;
202
+ }
203
+ table(["Service", "Type", "CPU (vCPU)", "Memory", "Sampled"], overviewRows(services));
204
+ info(chalk.dim("\nDetails: lizard metrics -s <service> Live: lizard metrics --watch"));
205
+ }
206
+ // ── Watch mode ────────────────────────────────────────────────────────────
207
+ async function watchLive(projectId, scope, serviceId) {
208
+ info(chalk.dim("Watching metrics... (Ctrl+C to stop)"));
209
+ // Capture console output so each refresh replaces the previous frame
210
+ // instead of scrolling.
211
+ for (;;) {
212
+ let services;
213
+ try {
214
+ services = await fetchLive(projectId, scope);
215
+ }
216
+ catch (e) {
217
+ error(e.message || String(e));
218
+ process.exit(1);
219
+ }
220
+ if (serviceId)
221
+ services = services.filter((s) => s.id === serviceId);
222
+ process.stdout.write("\x1b[2J\x1b[H"); // clear screen, cursor home
223
+ console.log(chalk.dim(new Date().toLocaleTimeString()) + chalk.dim(" (refreshes every 3s, Ctrl+C to stop)"));
224
+ console.log();
225
+ if (services.length === 0) {
226
+ console.log(chalk.dim("No services."));
227
+ }
228
+ else {
229
+ table(["Service", "Type", "CPU (vCPU)", "Memory", "Sampled"], overviewRows(services));
230
+ }
231
+ await new Promise((r) => setTimeout(r, 3000));
232
+ }
233
+ }
234
+ async function showCost(projectId, scope) {
235
+ if (!scope.workspaceId) {
236
+ error("Could not resolve the workspace for this project. Run `lizard link` first.");
237
+ process.exit(1);
238
+ }
239
+ let data;
240
+ try {
241
+ data = await api.get(withQuery("/api/billing/live", { workspaceId: scope.workspaceId }));
242
+ }
243
+ catch (e) {
244
+ if (e instanceof APIError && e.status === 403) {
245
+ error("Billing is only visible to the workspace owner.");
246
+ process.exit(2);
247
+ }
248
+ throw e;
249
+ }
250
+ const mine = data.resources.filter((r) => r.projectId === projectId);
251
+ const projectCost = mine.reduce((a, r) => a + r.costPerHour, 0);
252
+ if (isJSONMode()) {
253
+ printJSON({
254
+ projectId,
255
+ resources: mine,
256
+ projectCostPerHour: projectCost,
257
+ workspaceCostPerHour: data.costPerHour,
258
+ });
259
+ return;
260
+ }
261
+ if (mine.length === 0) {
262
+ console.log("No running resources in this project.");
263
+ }
264
+ else {
265
+ table(["Resource", "Type", "vCPU", "Memory", "Storage", "$/hr"], mine.map((r) => [
266
+ r.name,
267
+ r.addonType ? `addon (${r.addonType})` : r.type,
268
+ fmtVcpu(r.vcpu),
269
+ `${r.memoryGb.toFixed(2)} GB`,
270
+ r.storageGb > 0 ? `${r.storageGb} GB` : chalk.dim("—"),
271
+ `$${r.costPerHour.toFixed(4)}`,
272
+ ]));
273
+ console.log();
274
+ console.log(chalk.dim("Project ") +
275
+ `$${projectCost.toFixed(4)}/hr` +
276
+ chalk.dim(` (~$${(projectCost * 730).toFixed(2)}/mo at current usage)`));
277
+ }
278
+ console.log(chalk.dim("Workspace ") + `$${data.costPerHour.toFixed(4)}/hr`);
279
+ }
280
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/commands/metrics.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -22,12 +22,14 @@ import { registerAdd } from "./commands/add.js";
22
22
  import { registerConfig } from "./commands/config.js";
23
23
  import { registerDocs } from "./commands/docs.js";
24
24
  import { registerDomain } from "./commands/domain.js";
25
+ import { registerEvents } from "./commands/events.js";
25
26
  import { registerGit } from "./commands/git.js";
26
27
  import { registerInit } from "./commands/init.js";
27
28
  import { registerLink } from "./commands/link.js";
28
29
  import { registerLogin } from "./commands/login.js";
29
30
  import { registerLogout } from "./commands/logout.js";
30
31
  import { registerLogs } from "./commands/logs.js";
32
+ import { registerMetrics } from "./commands/metrics.js";
31
33
  import { registerOpen } from "./commands/open.js";
32
34
  import { registerPort } from "./commands/port.js";
33
35
  import { registerProjects } from "./commands/projects.js";
@@ -96,12 +98,14 @@ registerAdd(program);
96
98
  registerConfig(program);
97
99
  registerDocs(program);
98
100
  registerDomain(program);
101
+ registerEvents(program);
99
102
  registerGit(program);
100
103
  registerInit(program);
101
104
  registerLink(program);
102
105
  registerLogin(program);
103
106
  registerLogout(program);
104
107
  registerLogs(program);
108
+ registerMetrics(program);
105
109
  registerOpen(program);
106
110
  registerPort(program);
107
111
  registerProjects(program);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const CURRENT_VERSION = "0.3.43";
1
+ export declare const CURRENT_VERSION = "0.3.45";
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.43";
7
+ export const CURRENT_VERSION = "0.3.45";
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.43",
3
+ "version": "0.3.45",
4
4
  "description": "Lizard CLI — deploy and manage apps on Lizard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,106 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { api, withQuery } from "../lib/api.js";
4
+ import { resolveProjectScope, getActiveServiceWithKind } from "../lib/resolve.js";
5
+ import { info, error, isJSONMode, printJSON, table, statusColor, timeAgo } from "../lib/format.js";
6
+
7
+ // Shape returned by /api/apps/:id/deploy-events (build-level; crash events
8
+ // per build are surfaced by `lizard logs --restarts`).
9
+ interface DeployEvent {
10
+ buildId: string;
11
+ trigger: string | null;
12
+ status: string;
13
+ commitSha: string | null;
14
+ createdAt: number;
15
+ events: Array<{ id: string; source: string; status: string }>;
16
+ }
17
+
18
+ interface PodStatus {
19
+ name: string;
20
+ phase: string;
21
+ ready: boolean;
22
+ restarts: number;
23
+ reason?: string | null;
24
+ message?: string | null;
25
+ exitCode?: number | null;
26
+ startedAt?: number | null;
27
+ }
28
+
29
+ export function registerEvents(program: Command) {
30
+ program
31
+ .command("events")
32
+ .description("Show deploy history and replica status for an app")
33
+ .option("-s, --service <id>", "Service name or ID (defaults to linked service)")
34
+ .option("-p, --project <id>", "Project name, slug, or ID")
35
+ .option("-n, --limit <n>", "Max deploys to show", "10")
36
+ .action(async (opts) => {
37
+ const n = parseInt(opts.limit, 10);
38
+ if (isNaN(n) || n < 1) {
39
+ error("--limit must be a positive integer");
40
+ process.exit(1);
41
+ }
42
+
43
+ const { projectId } = await resolveProjectScope(opts.project);
44
+ const svc = await getActiveServiceWithKind(opts.service, projectId);
45
+ if (svc.kind === "addon") {
46
+ error(`Deploy events are only available for apps — "${svc.name}" is an addon`);
47
+ process.exit(1);
48
+ }
49
+
50
+ const [builds, podStatus] = await Promise.all([
51
+ api.get<DeployEvent[]>(`/api/apps/${svc.id}/deploy-events`),
52
+ api
53
+ .get<{ pods: PodStatus[] }>(`/api/apps/${svc.id}/pod-status`)
54
+ .catch(() => ({ pods: [] as PodStatus[] })),
55
+ ]);
56
+ const slice = builds.slice(0, n);
57
+
58
+ if (isJSONMode()) {
59
+ printJSON({
60
+ service: { id: svc.id, name: svc.name },
61
+ pods: podStatus.pods,
62
+ deploys: slice,
63
+ });
64
+ return;
65
+ }
66
+
67
+ if (podStatus.pods.length > 0) {
68
+ console.log(chalk.bold("Replicas"));
69
+ table(
70
+ ["Name", "Phase", "Ready", "Restarts", "Started", "Reason"],
71
+ podStatus.pods.map((pod) => [
72
+ pod.name,
73
+ statusColor(pod.phase.toLowerCase()),
74
+ pod.ready ? chalk.green("✓") : chalk.red("✗"),
75
+ String(pod.restarts),
76
+ pod.startedAt ? timeAgo(pod.startedAt) : chalk.dim("—"),
77
+ pod.reason || chalk.dim("—"),
78
+ ]),
79
+ );
80
+ console.log();
81
+ }
82
+
83
+ if (slice.length === 0) {
84
+ info(chalk.dim(`No deploys for ${svc.name} yet.`));
85
+ return;
86
+ }
87
+
88
+ console.log(chalk.bold("Deploys"));
89
+ table(
90
+ ["When", "Status", "Trigger", "Commit", "Restarts", "Build"],
91
+ slice.map((b) => [
92
+ timeAgo(b.createdAt),
93
+ statusColor(b.status),
94
+ b.trigger ?? chalk.dim("—"),
95
+ b.commitSha ? b.commitSha.slice(0, 7) : chalk.dim("—"),
96
+ b.events.length > 0 ? chalk.yellow(String(b.events.length)) : chalk.dim("0"),
97
+ chalk.dim(b.buildId),
98
+ ]),
99
+ );
100
+
101
+ if (builds.length > slice.length) {
102
+ info(chalk.dim(`\n(${builds.length - slice.length} more — re-run with -n ${builds.length})`));
103
+ }
104
+ info(chalk.dim("\nCrash details: lizard logs --restarts Build logs: lizard logs --build"));
105
+ });
106
+ }
@@ -0,0 +1,390 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { api, withScope, withQuery, APIError, type ResourceScope } from "../lib/api.js";
4
+ import { getProjectLink } from "../lib/config.js";
5
+ import { resolveProjectScope, getActiveServiceWithKind } from "../lib/resolve.js";
6
+ import { info, error, isJSONMode, printJSON, table, timeAgo } from "../lib/format.js";
7
+
8
+ // Shapes returned by /api/apps/:id/metrics and /api/projects/:id/metrics.
9
+ // Units: series cpu = vCPUs, memory/disk_used/disk_total = bytes,
10
+ // network_rx/tx + disk_read/write = bytes/s; latest mem is in MB.
11
+ interface SeriesItem {
12
+ metric: string;
13
+ timestamps: number[]; // seconds
14
+ values: number[];
15
+ }
16
+
17
+ interface LatestMetrics {
18
+ cpu: number; // vCPUs in use
19
+ memUsedMb: number;
20
+ memTotalMb: number;
21
+ sampledAt: number; // ms
22
+ }
23
+
24
+ interface EntityMetricsResult {
25
+ series: SeriesItem[];
26
+ latest: LatestMetrics | null;
27
+ limits: { cpuMillis: number; memoryMi: number };
28
+ }
29
+
30
+ interface ProjectEntityMetrics extends EntityMetricsResult {
31
+ id: string;
32
+ label: string;
33
+ type: "app" | "addon";
34
+ deleted: boolean;
35
+ }
36
+
37
+ const RANGES = ["1h", "6h", "24h", "7d", "14d", "30d"];
38
+
39
+ export function registerMetrics(program: Command) {
40
+ program
41
+ .command("metrics")
42
+ .description("Show resource metrics (CPU, memory, network, disk) and cost")
43
+ .option("-s, --service <id>", "Service name or ID (defaults to linked service)")
44
+ .option("-p, --project <id>", "Project name, slug, or ID")
45
+ .option("-r, --range <range>", `Time range: ${RANGES.join("|")}`, "1h")
46
+ .option("-w, --watch", "Live view, refreshed every 3s (Ctrl+C to stop)")
47
+ .option("--cost", "Show running resources and cost per hour instead of metrics")
48
+ .action(async (opts) => {
49
+ if (!RANGES.includes(opts.range)) {
50
+ error(`Invalid --range "${opts.range}". Choose one of: ${RANGES.join(", ")}`);
51
+ process.exit(1);
52
+ }
53
+ if (opts.watch && isJSONMode()) {
54
+ error("--watch is interactive and cannot be combined with --json (poll without --watch instead)");
55
+ process.exit(1);
56
+ }
57
+
58
+ const { projectId, scope } = await resolveProjectScope(opts.project);
59
+
60
+ if (opts.cost) {
61
+ await showCost(projectId, scope);
62
+ return;
63
+ }
64
+
65
+ // Service detail when -s is given or a service is linked; otherwise
66
+ // an overview of every service in the project.
67
+ const hasService = Boolean(opts.service || getProjectLink()?.serviceId);
68
+
69
+ if (opts.watch) {
70
+ let serviceId: string | undefined;
71
+ if (hasService) {
72
+ serviceId = (await getActiveServiceWithKind(opts.service, projectId)).id;
73
+ }
74
+ await watchLive(projectId, scope, serviceId);
75
+ return;
76
+ }
77
+
78
+ if (hasService) {
79
+ await showServiceMetrics(opts.service, projectId, scope, opts.range);
80
+ } else {
81
+ await showProjectOverview(projectId, scope);
82
+ }
83
+ });
84
+ }
85
+
86
+ // ── Formatting helpers ────────────────────────────────────────────────────
87
+
88
+ function fmtBytes(b: number): string {
89
+ if (!isFinite(b) || b < 0) return "—";
90
+ if (b < 1024) return `${Math.round(b)} B`;
91
+ if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`;
92
+ if (b < 1024 * 1024 * 1024) return `${(b / 1024 / 1024).toFixed(1)} MB`;
93
+ return `${(b / 1024 / 1024 / 1024).toFixed(2)} GB`;
94
+ }
95
+
96
+ function fmtRate(b: number): string {
97
+ return `${fmtBytes(b)}/s`;
98
+ }
99
+
100
+ function fmtMb(mb: number): string {
101
+ return fmtBytes(mb * 1024 * 1024);
102
+ }
103
+
104
+ function fmtVcpu(v: number): string {
105
+ return v.toFixed(2);
106
+ }
107
+
108
+ /** Render values as a unicode sparkline, downsampled to `width` buckets. */
109
+ function sparkline(values: number[], width = 30): string {
110
+ if (values.length === 0) return "";
111
+ const blocks = "▁▂▃▄▅▆▇█";
112
+ const buckets: number[] = [];
113
+ const per = Math.max(1, Math.ceil(values.length / width));
114
+ for (let i = 0; i < values.length; i += per) {
115
+ const slice = values.slice(i, i + per);
116
+ buckets.push(slice.reduce((a, b) => a + b, 0) / slice.length);
117
+ }
118
+ const max = Math.max(...buckets);
119
+ if (max <= 0) return chalk.dim(blocks[0].repeat(buckets.length));
120
+ return buckets
121
+ .map((v) => blocks[Math.min(blocks.length - 1, Math.floor((v / max) * (blocks.length - 1) + 0.5))])
122
+ .join("");
123
+ }
124
+
125
+ function seriesByName(series: SeriesItem[], name: string): number[] {
126
+ return series.find((s) => s.metric === name)?.values ?? [];
127
+ }
128
+
129
+ interface MetricStats {
130
+ now: number | null;
131
+ min: number;
132
+ avg: number;
133
+ max: number;
134
+ values: number[];
135
+ }
136
+
137
+ /** min/avg/max over a series. Rate metrics carry an artificial 0 as their
138
+ * first sample (no previous counter to diff against) — skip it. */
139
+ function stats(values: number[], isRate = false): MetricStats | null {
140
+ const vals = isRate && values.length > 1 ? values.slice(1) : values;
141
+ if (vals.length === 0) return null;
142
+ return {
143
+ now: vals[vals.length - 1],
144
+ min: Math.min(...vals),
145
+ avg: vals.reduce((a, b) => a + b, 0) / vals.length,
146
+ max: Math.max(...vals),
147
+ values: vals,
148
+ };
149
+ }
150
+
151
+ // ── Service detail ────────────────────────────────────────────────────────
152
+
153
+ async function fetchServiceMetrics(
154
+ svc: { id: string; kind: "app" | "addon" },
155
+ projectId: string,
156
+ scope: ResourceScope,
157
+ range: string,
158
+ ): Promise<EntityMetricsResult> {
159
+ const path =
160
+ svc.kind === "app"
161
+ ? withQuery(`/api/apps/${svc.id}/metrics`, { range })
162
+ : withScope(
163
+ withQuery(`/api/projects/${projectId}/addons/${svc.id}/metrics`, { range }),
164
+ scope,
165
+ );
166
+ return api.get<EntityMetricsResult>(path);
167
+ }
168
+
169
+ async function showServiceMetrics(
170
+ serviceFlag: string | undefined,
171
+ projectId: string,
172
+ scope: ResourceScope,
173
+ range: string,
174
+ ) {
175
+ const svc = await getActiveServiceWithKind(serviceFlag, projectId);
176
+ const data = await fetchServiceMetrics(svc, projectId, scope, range);
177
+
178
+ if (isJSONMode()) {
179
+ printJSON({ service: { id: svc.id, name: svc.name, kind: svc.kind }, range, ...data });
180
+ return;
181
+ }
182
+
183
+ const { series, latest, limits } = data;
184
+ if (series.length === 0 && !latest) {
185
+ info(chalk.dim(`No metrics for ${svc.name} yet — the service may be new or stopped.`));
186
+ return;
187
+ }
188
+
189
+ const sampled = latest ? timeAgo(latest.sampledAt) : chalk.dim("no live data");
190
+ console.log(chalk.bold(svc.name) + chalk.dim(` (${svc.kind}) — last ${range}, sampled ${sampled}`));
191
+ console.log();
192
+
193
+ const cpu = stats(seriesByName(series, "cpu"));
194
+ const mem = stats(seriesByName(series, "memory"));
195
+ const rx = stats(seriesByName(series, "network_rx"), true);
196
+ const tx = stats(seriesByName(series, "network_tx"), true);
197
+ const dr = stats(seriesByName(series, "disk_read"), true);
198
+ const dw = stats(seriesByName(series, "disk_write"), true);
199
+
200
+ const rows: string[][] = [];
201
+ const push = (
202
+ label: string,
203
+ s: MetricStats | null,
204
+ fmt: (v: number) => string,
205
+ now?: number | null,
206
+ ) => {
207
+ if (!s) return;
208
+ const current = now ?? s.now;
209
+ rows.push([
210
+ label,
211
+ current === null || current === undefined ? chalk.dim("—") : fmt(current),
212
+ fmt(s.min),
213
+ fmt(s.avg),
214
+ fmt(s.max),
215
+ chalk.cyan(sparkline(s.values)),
216
+ ]);
217
+ };
218
+
219
+ // "Now" for CPU/memory prefers the live Redis snapshot over the last
220
+ // (up to 90s stale) historical sample.
221
+ push("CPU (vCPU)", cpu, fmtVcpu, latest ? latest.cpu : undefined);
222
+ push("Memory", mem, fmtBytes, latest ? latest.memUsedMb * 1024 * 1024 : undefined);
223
+ push("Net ↓", rx, fmtRate);
224
+ push("Net ↑", tx, fmtRate);
225
+ push("Disk read", dr, fmtRate);
226
+ push("Disk write", dw, fmtRate);
227
+
228
+ if (rows.length > 0) {
229
+ table(["Metric", "Now", "Min", "Avg", "Max", "Trend"], rows);
230
+ } else if (latest) {
231
+ // Live snapshot only (brand-new VM, no history rows yet)
232
+ table(
233
+ ["Metric", "Now"],
234
+ [
235
+ ["CPU (vCPU)", fmtVcpu(latest.cpu)],
236
+ ["Memory", `${fmtMb(latest.memUsedMb)} / ${fmtMb(latest.memTotalMb)}`],
237
+ ],
238
+ );
239
+ }
240
+
241
+ console.log();
242
+ const diskUsed = seriesByName(series, "disk_used");
243
+ const diskTotal = seriesByName(series, "disk_total");
244
+ if (diskUsed.length > 0) {
245
+ const used = diskUsed[diskUsed.length - 1];
246
+ const total = diskTotal[diskTotal.length - 1] ?? 0;
247
+ console.log(
248
+ chalk.dim("Disk used ") + fmtBytes(used) + (total > 0 ? chalk.dim(` / ${fmtBytes(total)}`) : ""),
249
+ );
250
+ }
251
+ console.log(
252
+ chalk.dim("Limits ") +
253
+ `${(limits.cpuMillis / 1000).toFixed(limits.cpuMillis % 1000 === 0 ? 0 : 1)} vCPU · ${fmtMb(limits.memoryMi)} memory`,
254
+ );
255
+ }
256
+
257
+ // ── Project overview ──────────────────────────────────────────────────────
258
+
259
+ async function fetchLive(projectId: string, scope: ResourceScope): Promise<ProjectEntityMetrics[]> {
260
+ const data = await api.get<{ services: ProjectEntityMetrics[] }>(
261
+ withScope(withQuery(`/api/projects/${projectId}/metrics`, { live: true }), scope),
262
+ );
263
+ return (data.services || []).filter((s) => !s.deleted);
264
+ }
265
+
266
+ function overviewRows(services: ProjectEntityMetrics[]): string[][] {
267
+ return services.map((s) => {
268
+ const cpuLimit = s.limits.cpuMillis / 1000;
269
+ return [
270
+ s.label,
271
+ s.type,
272
+ s.latest ? `${fmtVcpu(s.latest.cpu)} / ${cpuLimit}` : chalk.dim("—"),
273
+ s.latest ? `${fmtMb(s.latest.memUsedMb)} / ${fmtMb(s.latest.memTotalMb)}` : chalk.dim("—"),
274
+ s.latest ? timeAgo(s.latest.sampledAt) : chalk.dim("no data"),
275
+ ];
276
+ });
277
+ }
278
+
279
+ async function showProjectOverview(projectId: string, scope: ResourceScope) {
280
+ const services = await fetchLive(projectId, scope);
281
+
282
+ if (isJSONMode()) {
283
+ printJSON({ services });
284
+ return;
285
+ }
286
+
287
+ if (services.length === 0) {
288
+ console.log("No services. Use `lizard add` or `lizard up`.");
289
+ return;
290
+ }
291
+
292
+ table(["Service", "Type", "CPU (vCPU)", "Memory", "Sampled"], overviewRows(services));
293
+ info(chalk.dim("\nDetails: lizard metrics -s <service> Live: lizard metrics --watch"));
294
+ }
295
+
296
+ // ── Watch mode ────────────────────────────────────────────────────────────
297
+
298
+ async function watchLive(projectId: string, scope: ResourceScope, serviceId?: string) {
299
+ info(chalk.dim("Watching metrics... (Ctrl+C to stop)"));
300
+ // Capture console output so each refresh replaces the previous frame
301
+ // instead of scrolling.
302
+ for (;;) {
303
+ let services: ProjectEntityMetrics[];
304
+ try {
305
+ services = await fetchLive(projectId, scope);
306
+ } catch (e: any) {
307
+ error(e.message || String(e));
308
+ process.exit(1);
309
+ }
310
+ if (serviceId) services = services.filter((s) => s.id === serviceId);
311
+
312
+ process.stdout.write("\x1b[2J\x1b[H"); // clear screen, cursor home
313
+ console.log(chalk.dim(new Date().toLocaleTimeString()) + chalk.dim(" (refreshes every 3s, Ctrl+C to stop)"));
314
+ console.log();
315
+ if (services.length === 0) {
316
+ console.log(chalk.dim("No services."));
317
+ } else {
318
+ table(["Service", "Type", "CPU (vCPU)", "Memory", "Sampled"], overviewRows(services));
319
+ }
320
+
321
+ await new Promise((r) => setTimeout(r, 3000));
322
+ }
323
+ }
324
+
325
+ // ── Cost ──────────────────────────────────────────────────────────────────
326
+
327
+ interface BillingResource {
328
+ projectId: string;
329
+ type: "app" | "addon";
330
+ name: string;
331
+ addonType?: string;
332
+ vcpu: number;
333
+ memoryGb: number;
334
+ storageGb: number;
335
+ costPerHour: number;
336
+ }
337
+
338
+ async function showCost(projectId: string, scope: ResourceScope) {
339
+ if (!scope.workspaceId) {
340
+ error("Could not resolve the workspace for this project. Run `lizard link` first.");
341
+ process.exit(1);
342
+ }
343
+
344
+ let data: { resources: BillingResource[]; costPerHour: number };
345
+ try {
346
+ data = await api.get(withQuery("/api/billing/live", { workspaceId: scope.workspaceId }));
347
+ } catch (e) {
348
+ if (e instanceof APIError && e.status === 403) {
349
+ error("Billing is only visible to the workspace owner.");
350
+ process.exit(2);
351
+ }
352
+ throw e;
353
+ }
354
+
355
+ const mine = data.resources.filter((r) => r.projectId === projectId);
356
+ const projectCost = mine.reduce((a, r) => a + r.costPerHour, 0);
357
+
358
+ if (isJSONMode()) {
359
+ printJSON({
360
+ projectId,
361
+ resources: mine,
362
+ projectCostPerHour: projectCost,
363
+ workspaceCostPerHour: data.costPerHour,
364
+ });
365
+ return;
366
+ }
367
+
368
+ if (mine.length === 0) {
369
+ console.log("No running resources in this project.");
370
+ } else {
371
+ table(
372
+ ["Resource", "Type", "vCPU", "Memory", "Storage", "$/hr"],
373
+ mine.map((r) => [
374
+ r.name,
375
+ r.addonType ? `addon (${r.addonType})` : r.type,
376
+ fmtVcpu(r.vcpu),
377
+ `${r.memoryGb.toFixed(2)} GB`,
378
+ r.storageGb > 0 ? `${r.storageGb} GB` : chalk.dim("—"),
379
+ `$${r.costPerHour.toFixed(4)}`,
380
+ ]),
381
+ );
382
+ console.log();
383
+ console.log(
384
+ chalk.dim("Project ") +
385
+ `$${projectCost.toFixed(4)}/hr` +
386
+ chalk.dim(` (~$${(projectCost * 730).toFixed(2)}/mo at current usage)`),
387
+ );
388
+ }
389
+ console.log(chalk.dim("Workspace ") + `$${data.costPerHour.toFixed(4)}/hr`);
390
+ }
package/src/index.ts CHANGED
@@ -27,12 +27,14 @@ import { registerAdd } from "./commands/add.js";
27
27
  import { registerConfig } from "./commands/config.js";
28
28
  import { registerDocs } from "./commands/docs.js";
29
29
  import { registerDomain } from "./commands/domain.js";
30
+ import { registerEvents } from "./commands/events.js";
30
31
  import { registerGit } from "./commands/git.js";
31
32
  import { registerInit } from "./commands/init.js";
32
33
  import { registerLink } from "./commands/link.js";
33
34
  import { registerLogin } from "./commands/login.js";
34
35
  import { registerLogout } from "./commands/logout.js";
35
36
  import { registerLogs } from "./commands/logs.js";
37
+ import { registerMetrics } from "./commands/metrics.js";
36
38
  import { registerOpen } from "./commands/open.js";
37
39
  import { registerPort } from "./commands/port.js";
38
40
  import { registerProjects } from "./commands/projects.js";
@@ -108,12 +110,14 @@ registerAdd(program);
108
110
  registerConfig(program);
109
111
  registerDocs(program);
110
112
  registerDomain(program);
113
+ registerEvents(program);
111
114
  registerGit(program);
112
115
  registerInit(program);
113
116
  registerLink(program);
114
117
  registerLogin(program);
115
118
  registerLogout(program);
116
119
  registerLogs(program);
120
+ registerMetrics(program);
117
121
  registerOpen(program);
118
122
  registerPort(program);
119
123
  registerProjects(program);
@@ -5,7 +5,7 @@ import { join, dirname } from "node:path";
5
5
  import os from "node:os";
6
6
  import { spawn } from "node:child_process";
7
7
 
8
- export const CURRENT_VERSION = "0.3.43";
8
+ export const CURRENT_VERSION = "0.3.45";
9
9
  const RELEASES_API = "https://api.github.com/repos/lizard-build/lizard-cli/releases/latest";
10
10
  const RELEASE_BASE = "https://github.com/lizard-build/lizard-cli/releases/latest/download";
11
11
 
package/test/cli.test.ts CHANGED
@@ -6,6 +6,9 @@
6
6
  * - Authed: `lizard login --token <token>` (or any prior session)
7
7
  * - Optionally point at a specific built binary: LIZARD_BIN=./dist/index.js
8
8
  * - Optionally pin a project: LIZARD_TEST_PROJECT_ID=<id>
9
+ * Without the pin only read-only/self-contained tests run; suites that
10
+ * mutate services (deploy, scale) are skipped so they can never touch
11
+ * an arbitrary real project picked from the account.
9
12
  *
10
13
  * Run: npm test
11
14
  *
@@ -258,8 +261,11 @@ describe("ps (service inventory)", () => {
258
261
  });
259
262
 
260
263
  // ── Scale (no-op against existing app) ────────────────────────────────────────
264
+ //
265
+ // Mutates a real app (forces replicas=1) — only safe against a dedicated,
266
+ // explicitly pinned test project.
261
267
 
262
- describe("scale", () => {
268
+ describe.skipIf(!process.env.LIZARD_TEST_PROJECT_ID)("scale", () => {
263
269
  test("scale --replicas succeeds when an app exists", async () => {
264
270
  const services = await cliJSON("ps", "--project", projectId);
265
271
  const apps: Array<{ id: string; name: string }> = services?.apps ?? [];
@@ -284,10 +290,10 @@ describe("domain", () => {
284
290
  console.log(" ⚠ no apps, skipping domain test");
285
291
  return;
286
292
  }
287
- const data = await cliJSON("domain", "--service", apps[0].name, "--project", projectId).catch(
288
- () => [],
289
- );
290
- expect(Array.isArray(data)).toBe(true);
293
+ // `domain` (no subcommand) prints the current domain: { hostname, generated }
294
+ const data = await cliJSON("domain", "--service", apps[0].name, "--project", projectId);
295
+ expect(data).toHaveProperty("hostname");
296
+ expect(typeof data.hostname).toBe("string");
291
297
  });
292
298
  });
293
299
 
@@ -296,23 +302,22 @@ describe("domain", () => {
296
302
  // Heavy test: uploads the fixture as a fresh app, waits for it to come up,
297
303
  // then exercises service-scope secrets against it. Set LIZARD_SKIP_DEPLOY=1
298
304
  // to skip while iterating locally.
305
+ //
306
+ // SAFETY: runs only when LIZARD_TEST_PROJECT_ID explicitly pins a dedicated
307
+ // test project. Without the pin, projectId falls back to an arbitrary real
308
+ // project from the account — deploying into (let alone cleaning up) such a
309
+ // project is never acceptable. The suite must also never mass-delete apps
310
+ // it didn't create: a teardown used to wipe every app in the project and
311
+ // destroyed real services. Cleanup is limited to `createdApps` in afterAll.
299
312
 
300
313
  let DEPLOY_DIR: string | undefined;
301
314
 
302
- describe.skipIf(process.env.LIZARD_SKIP_DEPLOY === "1")("deploy", () => {
315
+ describe.skipIf(
316
+ process.env.LIZARD_SKIP_DEPLOY === "1" || !process.env.LIZARD_TEST_PROJECT_ID,
317
+ )("deploy", () => {
303
318
  const appName = `cli-test-${Date.now()}`;
304
319
  let appId: string;
305
320
 
306
- beforeAll(async () => {
307
- // Tear down any leftover apps in the test project so we deploy clean.
308
- // `service rm` requires --project (after the command, per commander).
309
- const services = await cliJSON("ps", "--project", projectId).catch(() => ({ apps: [] }));
310
- const existing: Array<{ id: string }> = services?.apps ?? [];
311
- for (const app of existing) {
312
- await cli("service", "rm", app.id, "-y", "--project", projectId).catch(() => {});
313
- }
314
- }, 60_000);
315
-
316
321
  test(
317
322
  "deploy local fixture app (detached)",
318
323
  async () => {