Skip to content

Commit 23ed4ed

Browse files
Chris-Mollerclaude
andcommitted
refactor(cli): simplify releases and build list output to stacked format
Remove table formatting from `ecloud compute app releases` and `ecloud compute build list` commands. Always use the stacked vertical format which shows each field on its own line for better legibility regardless of terminal width. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ed4294f commit 23ed4ed

File tree

2 files changed

+31
-174
lines changed

2 files changed

+31
-174
lines changed

packages/cli/src/commands/compute/app/releases.ts

Lines changed: 14 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ import { getClientId } from "../../../utils/version";
77
import { createViemClients } from "../../../utils/viemClients";
88
import chalk from "chalk";
99
import { formatAppRelease } from "../../../utils/releases";
10-
import { Address, isAddress } from "viem";
11-
import Table from "cli-table3";
10+
import { Address } from "viem";
1211
import {
13-
terminalWidth,
1412
formatRepoDisplay,
1513
extractRepoName,
1614
formatImageDisplay,
@@ -132,20 +130,8 @@ export default class AppReleases extends Command {
132130
return;
133131
}
134132

135-
type Row = {
136-
rel: string;
137-
block: string;
138-
created: string;
139-
repo: string;
140-
commit: string;
141-
digest: string;
142-
image: string;
143-
build: string;
144-
prov: string;
145-
deps: string;
146-
};
147-
148-
const rows: Row[] = releases.map((r, i) => {
133+
for (let i = 0; i < releases.length; i++) {
134+
const r = releases[i]!;
149135
const rel = r.rmsReleaseId ?? String(i);
150136
const block = r.createdAtBlock ? String(r.createdAtBlock) : "-";
151137
const created = r.createdAt ? formatHumanTime(r.createdAt) : "-";
@@ -155,100 +141,21 @@ export default class AppReleases extends Command {
155141
const image = formatImageDisplay(r.build?.imageUrl ?? r.registryUrl ?? "-");
156142
const build = r.build?.buildId ?? "-";
157143
const prov = provenanceSummaryFromBuild(r.build);
158-
const depCount = r.build?.dependencies ? Object.keys(r.build.dependencies).length : 0;
159-
const deps = depCount > 0 ? `deps:${depCount}` : "-";
160-
return { rel, block, created, repo, commit, digest, image, build, prov, deps };
161-
});
162-
163-
const headers = {
164-
rel: chalk.bold("Rel"),
165-
block: chalk.bold("Block"),
166-
created: chalk.bold("Created"),
167-
repo: chalk.bold("Repo"),
168-
commit: chalk.bold("Commit"),
169-
digest: chalk.bold("Digest"),
170-
image: chalk.bold("Image"),
171-
build: chalk.bold("Build"),
172-
prov: chalk.bold("Prov"),
173-
deps: chalk.bold("Deps"),
174-
};
175144

176-
const tw = terminalWidth();
177-
// With 10 columns this gets unreadable on narrow terminals; fall back to stacked.
178-
const shouldStack = tw < 140;
179-
180-
if (shouldStack) {
181-
for (const r of rows) {
182-
this.log(`${chalk.cyan(r.rel)} ${r.created} (block ${r.block})`);
183-
this.log(` Repo: ${r.repo}`);
184-
this.log(` Commit: ${r.commit}`);
185-
this.log(` Digest: ${r.digest}`);
186-
this.log(` Image: ${r.image}`);
187-
this.log(` Build: ${r.build}`);
188-
this.log(` Provenance: ${r.prov}`);
189-
const relObj = releases.find((x, idx) => (x.rmsReleaseId ?? String(idx)) === r.rel);
190-
const depLines = formatDepLines(relObj?.build?.dependencies);
191-
if (depLines.length) {
192-
for (const l of depLines) this.log(l);
193-
}
194-
this.log(chalk.gray(" ───────────────────────────────────────────────────────────────"));
145+
this.log(`${chalk.cyan(rel)} ${created} (block ${block})`);
146+
this.log(` Repo: ${repo}`);
147+
this.log(` Commit: ${commit}`);
148+
this.log(` Digest: ${digest}`);
149+
this.log(` Image: ${image}`);
150+
this.log(` Build: ${build}`);
151+
this.log(` Provenance: ${prov}`);
152+
const depLines = formatDepLines(r.build?.dependencies);
153+
if (depLines.length) {
154+
for (const l of depLines) this.log(l);
195155
}
196-
this.log("");
197-
this.log(
198-
chalk.gray(
199-
`Tip: use ${chalk.yellow("--full")} for detailed release output, ${chalk.yellow(
200-
"--json",
201-
)} to copy/paste, and ${chalk.yellow(
202-
"ecloud compute build info <buildId>",
203-
)} for full build/provenance details.`,
204-
),
205-
);
206-
return;
156+
this.log(chalk.gray(" ───────────────────────────────────────────────────────────────"));
207157
}
208158

209-
// Allocate flexible width to the "wide" columns based on terminal width.
210-
// Note: cli-table3 includes borders/padding; this is intentionally approximate.
211-
const fixed = 6 + 10 + 20 + 36 + 12 + 8 + 10; // rel + block + created + build + prov + deps + commit(min-ish)
212-
const remaining = Math.max(60, tw - fixed);
213-
const repoW = Math.max(18, Math.floor(remaining * 0.25));
214-
const digestW = Math.max(18, Math.floor(remaining * 0.35));
215-
const imageW = Math.max(18, remaining - repoW - digestW);
216-
217-
const table = new Table({
218-
head: [
219-
headers.rel,
220-
headers.block,
221-
headers.created,
222-
headers.repo,
223-
headers.commit,
224-
headers.digest,
225-
headers.image,
226-
headers.build,
227-
headers.prov,
228-
headers.deps,
229-
],
230-
colWidths: [6, 10, 20, repoW, 10, digestW, imageW, 36, 12, 8],
231-
wordWrap: true,
232-
style: { "padding-left": 0, "padding-right": 1, head: [], border: [] },
233-
});
234-
235-
for (const r of rows) {
236-
table.push([
237-
r.rel,
238-
r.block,
239-
r.created,
240-
r.repo,
241-
r.commit,
242-
r.digest,
243-
r.image,
244-
r.build,
245-
r.prov,
246-
r.deps,
247-
]);
248-
}
249-
250-
this.log(table.toString());
251-
252159
this.log("");
253160
this.log(
254161
chalk.gray(

packages/cli/src/commands/compute/build/list.ts

Lines changed: 17 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { Command, Flags } from "@oclif/core";
22
import chalk from "chalk";
33
import { privateKeyToAccount } from "viem/accounts";
4-
import type { Build } from "@layr-labs/ecloud-sdk";
54
import { addHexPrefix } from "@layr-labs/ecloud-sdk";
65
import { commonFlags, validateCommonFlags } from "../../../flags";
76
import { createBuildClient } from "../../../client";
87
import { withTelemetry } from "../../../telemetry";
98
import { formatBuildStatus } from "../../../utils/buildInfo";
10-
import Table from "cli-table3";
119
import {
12-
terminalWidth,
1310
formatRepoDisplay,
1411
formatImageDisplay,
1512
provenanceSummary,
@@ -70,76 +67,29 @@ export default class BuildList extends Command {
7067
return;
7168
}
7269

73-
type Row = {
74-
buildId: string;
75-
status: string;
76-
repo: string;
77-
commit: string;
78-
image: string;
79-
created: string;
80-
prov: string;
81-
};
82-
83-
// Keep raw-ish values; we will truncate based on terminal width.
84-
const rows: Row[] = builds.map((b: Build) => ({
85-
buildId: b.buildId || "-",
86-
status: formatBuildStatus(b.status),
87-
repo: formatRepoDisplay(b.repoUrl || "-"),
88-
commit: b.gitRef || "-",
89-
image: formatImageDisplay(b.imageUrl || "-"),
90-
created: formatHumanTime(b.createdAt),
91-
prov: provenanceSummary({
92-
provenanceJson: b.provenanceJson,
93-
provenanceSignature: b.provenanceSignature,
94-
dependencies: b.dependencies,
95-
}),
96-
}));
97-
98-
const tw = terminalWidth();
99-
// With 7 columns, narrow terminals get hard to read. Fall back to stacked output.
100-
const shouldStack = tw < 110;
101-
10270
this.log("");
10371
this.log(chalk.bold(`Builds for ${billingAddress} (${validatedFlags.environment}):`));
10472
this.log("");
10573

106-
if (shouldStack) {
107-
for (const r of rows) {
108-
this.log(`${r.status} ${chalk.cyan(r.buildId)} ${r.created}`);
109-
this.log(` Repo: ${r.repo}`);
110-
this.log(` Commit: ${r.commit}`);
111-
this.log(` Image: ${r.image}`);
112-
this.log(` Prov: ${r.prov}`);
113-
this.log(chalk.gray(" ───────────────────────────────────────────────────────────────"));
114-
}
115-
} else {
116-
// Allocate flexible width to the "wide" columns (repo/commit/image) based on terminal width.
117-
// cli-table3 adds 8 border chars (left + right + 6 between columns).
118-
const fixed = 37 + 10 + 20 + 14 + 8; // id + status + created + prov + borders
119-
const remaining = Math.max(30, tw - fixed);
120-
const repoW = Math.max(18, Math.floor(remaining * 0.28));
121-
const commitW = Math.max(18, Math.floor(remaining * 0.36));
122-
const imageW = Math.max(18, remaining - repoW - commitW);
123-
124-
const table = new Table({
125-
head: [
126-
chalk.bold("ID"),
127-
chalk.bold("Status"),
128-
chalk.bold("Repo"),
129-
chalk.bold("Commit"),
130-
chalk.bold("Image"),
131-
chalk.bold("Created"),
132-
chalk.bold("Prov"),
133-
],
134-
colWidths: [37, 10, repoW, commitW, imageW, 20, 14],
135-
wordWrap: true,
136-
style: { "padding-left": 0, "padding-right": 1, head: [], border: [] },
74+
for (const b of builds) {
75+
const buildId = b.buildId || "-";
76+
const status = formatBuildStatus(b.status);
77+
const repo = formatRepoDisplay(b.repoUrl || "-");
78+
const commit = b.gitRef || "-";
79+
const image = formatImageDisplay(b.imageUrl || "-");
80+
const created = formatHumanTime(b.createdAt);
81+
const prov = provenanceSummary({
82+
provenanceJson: b.provenanceJson,
83+
provenanceSignature: b.provenanceSignature,
84+
dependencies: b.dependencies,
13785
});
13886

139-
for (const r of rows) {
140-
table.push([r.buildId, r.status, r.repo, r.commit, r.image, r.created, r.prov]);
141-
}
142-
this.log(table.toString());
87+
this.log(`${status} ${chalk.cyan(buildId)} ${created}`);
88+
this.log(` Repo: ${repo}`);
89+
this.log(` Commit: ${commit}`);
90+
this.log(` Image: ${image}`);
91+
this.log(` Prov: ${prov}`);
92+
this.log(chalk.gray(" ───────────────────────────────────────────────────────────────"));
14393
}
14494

14595
this.log("");

0 commit comments

Comments
 (0)