Skip to content
Draft
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
7 changes: 4 additions & 3 deletions src/cli/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const USAGE = `Usage:
*/
function formatKeyRows(payload: Record<string, unknown>, keys: Array<Record<string, unknown>>): string[] {
const cells: string[][] = [["ID", "NAME", "PREFIX", "REQ 7D", "TOTAL", "LAST USED"]];
const usageAvailable = typeof payload.attributionSince === "string";
for (const entry of keys) {
const usage = (entry.usage ?? {}) as Record<string, unknown>;
const ambiguous = usage.ambiguous === true;
Expand All @@ -42,9 +43,9 @@ function formatKeyRows(payload: Record<string, unknown>, keys: Array<Record<stri
String(entry.name ?? ""),
String(entry.prefix ?? ""),
// One marker spanning both numeric columns: the union guarantees neither exists.
ambiguous ? "ambiguous" : num(usage.requests7d),
ambiguous ? "" : num(usage.totalRequests),
ambiguous ? "" : (typeof usage.lastUsedAt === "string" ? usage.lastUsedAt : "never"),
!usageAvailable ? "unavailable" : ambiguous ? "ambiguous" : num(usage.requests7d),
!usageAvailable || ambiguous ? "" : num(usage.totalRequests),
!usageAvailable || ambiguous ? "" : (typeof usage.lastUsedAt === "string" ? usage.lastUsedAt : "never"),
]);
}
const widths = cells[0]!.map((_, column) => Math.max(...cells.map(row => (row[column] ?? "").length)));
Expand Down
12 changes: 12 additions & 0 deletions tests/cli-dto-fidelity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ describe("#2705 access key usage columns", () => {
id: "k_9f2a", name: "ci-runner", prefix: "ocx_data_abc...",
usage: { requests7d: 1204, totalRequests: 18330, lastUsedAt: "2026-08-27T04:11:00Z" },
}],
attributionSince: "2026-07-29T00:00:00Z",
});
expect(out).toContain("REQ 7D");
expect(out).toContain("1,204");
Expand All @@ -228,6 +229,7 @@ describe("#2705 access key usage columns", () => {
// use is the dangerous answer for someone deciding what to delete.
const out = await listOutput({
keys: [{ id: "k_11bd", name: "laptop", prefix: "ocx_data_def...", usage: { ambiguous: true } }],
attributionSince: "2026-07-29T00:00:00Z",
});
expect(out).toContain("ambiguous");
expect(out).not.toMatch(/\b0\b/);
Expand All @@ -236,10 +238,20 @@ describe("#2705 access key usage columns", () => {
test("a never-used key says never rather than showing an empty cell", async () => {
const out = await listOutput({
keys: [{ id: "k_new", name: "fresh", prefix: "ocx_data_ghi...", usage: { requests7d: 0, totalRequests: 0 } }],
attributionSince: "2026-08-29T00:00:00Z",
});
expect(out).toContain("never");
});

test("unavailable attribution does not report zero usage or never used", async () => {
const out = await listOutput({
keys: [{ id: "k_unknown", name: "unknown", prefix: "ocx_data_jkl...", usage: { requests7d: 0, totalRequests: 0 } }],
});
expect(out).toContain("unavailable");
expect(out).not.toMatch(/\b0\b/);
expect(out).not.toContain("never");
});

test("dataset-level attribution and truncation print ONCE as a footer", async () => {
// They describe the usage log, not a key. Without attributionSince an absent lastUsedAt is
// unreadable: "never used" and "nothing attributable yet" look identical.
Expand Down
Loading