Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 22 additions & 79 deletions src/commands/agent/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
*/

import chalk from "chalk";
import { listAgents, type Agent } from "../../services/agentService.js";
import {
listAgents,
getAgentColumns,
type Agent,
} from "../../services/agentService.js";
import { output, outputError } from "../../utils/output.js";
import { formatTimeAgo } from "../../utils/time.js";

interface ListOptions {
full?: boolean;
Expand All @@ -16,81 +19,16 @@ interface ListOptions {
output?: string;
}

interface ColumnDef {
header: string;
raw: (agent: Agent) => string;
styled: (agent: Agent) => string;
}

const columns: ColumnDef[] = [
{
header: "NAME",
raw: (a) => a.name,
styled(a) {
return this.raw(a);
},
},
{
header: "SOURCE",
raw: (a) => (a as any).source?.type || "-",
styled(a) {
return this.raw(a);
},
},
{
header: "VERSION",
raw: (a) => {
const pkg =
(a as any).source?.npm?.package_name ||
(a as any).source?.pip?.package_name;
return pkg ? `${pkg}@${a.version}` : a.version;
},
styled(a) {
const pkg =
(a as any).source?.npm?.package_name ||
(a as any).source?.pip?.package_name;
return pkg ? chalk.dim(pkg + "@") + a.version : a.version;
},
/** Styling rules keyed by column key. Columns not listed render unstyled. */
const columnStyle: Record<string, (raw: string) => string> = {
id: (v) => chalk.dim(v),
created: (v) => chalk.dim(v),
version: (v) => {
// Dim the "pkg@" prefix when present. Use lastIndexOf to skip scoped package @ (e.g. @scope/pkg@1.0)
const at = v.lastIndexOf("@");
return at > 0 ? chalk.dim(v.slice(0, at + 1)) + v.slice(at + 1) : v;
},
{
header: "ID",
raw: (a) => a.id,
styled(a) {
return chalk.dim(a.id);
},
},
{
header: "CREATED",
raw: (a) => formatTimeAgo(a.create_time_ms),
styled(a) {
return chalk.dim(this.raw(a));
},
},
];

function computeColumnWidths(agents: Agent[]): number[] {
const minPad = 2;
const maxPad = 4;
const termWidth = process.stdout.columns || 120;

// Min width per column: max of header and all row values, plus minimum padding
const minWidths = columns.map((col) => {
const maxContent = agents.reduce(
(w, a) => Math.max(w, col.raw(a).length),
col.header.length,
);
return maxContent + minPad;
});

const totalMin = minWidths.reduce((s, w) => s + w, 0);
const slack = termWidth - totalMin;
const extraPerCol = Math.min(
maxPad - minPad,
Math.max(0, Math.floor(slack / columns.length)),
);

return minWidths.map((w) => w + extraPerCol);
}
};

function padStyled(raw: string, styled: string, width: number): string {
return styled + " ".repeat(Math.max(0, width - raw.length));
Expand All @@ -105,18 +43,23 @@ export function printAgentTable(agents: Agent[]): void {
return;
}

const widths = computeColumnWidths(agents);
const termWidth = process.stdout.columns || 120;
const columns = getAgentColumns(agents, termWidth, false);

// Header
const header = columns.map((col, i) => col.header.padEnd(widths[i])).join("");
const header = columns.map((col) => col.label.padEnd(col.width)).join("");
console.log(chalk.bold(header));
console.log(chalk.dim("─".repeat(Math.min(header.length, termWidth))));

// Rows
for (const agent of agents) {
const line = columns
.map((col, i) => padStyled(col.raw(agent), col.styled(agent), widths[i]))
.map((col) => {
const raw = col.getValue(agent);
const styleFn = columnStyle[col.key];
const styled = styleFn ? styleFn(raw) : raw;
return padStyled(raw, styled, col.width);
})
.join("");
console.log(line);
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/BenchmarkMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,21 @@ interface BenchmarkMenuItem {
const benchmarkMenuItems: BenchmarkMenuItem[] = [
{
key: "benchmarks",
label: "Benchmark Defs",
label: "Available Benchmarks",
description: "View benchmark definitions",
icon: "◉",
color: colors.primary,
},
{
key: "benchmark-jobs",
label: "Orchestrator Jobs",
label: "Benchmark Orchestrator Jobs",
description: "Run and manage benchmark jobs",
icon: "▲",
color: colors.warning,
},
{
key: "benchmark-runs",
label: "Legacy Runs",
label: "Manual Benchmark Runs",
description: "View and manage benchmark executions",
icon: "◇",
color: colors.success,
Expand Down
Loading
Loading