Skip to content

Commit f51bd0c

Browse files
fix: filter soft-archived cards by default in workboard list CLI
1 parent dba291e commit f51bd0c

2 files changed

Lines changed: 65 additions & 13 deletions

File tree

extensions/workboard/src/cli.test.ts

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,22 @@ describe("registerWorkboardCli", () => {
8989

9090
it("redacts claim tokens from card JSON output", async () => {
9191
const store = new WorkboardStore(createMemoryStore());
92-
const card = await store.create({ title: "Claimed worker", status: "running" });
92+
const card = await store.create({
93+
title: "Claimed worker",
94+
status: "running",
95+
});
9396
await store.claim(card.id, { ownerId: "worker", token: "secret-token" });
9497
const program = createProgram(store);
9598

9699
const listOutput = await captureStdout(async () => {
97-
await program.parseAsync(["workboard", "list", "--json"], { from: "user" });
100+
await program.parseAsync(["workboard", "list", "--json"], {
101+
from: "user",
102+
});
98103
});
99104
const showOutput = await captureStdout(async () => {
100-
await program.parseAsync(["workboard", "show", card.id, "--json"], { from: "user" });
105+
await program.parseAsync(["workboard", "show", card.id, "--json"], {
106+
from: "user",
107+
});
101108
});
102109

103110
expect(listOutput).not.toContain("secret-token");
@@ -108,14 +115,19 @@ describe("registerWorkboardCli", () => {
108115

109116
it("does not fall back to local dispatch for explicit gateway targets", async () => {
110117
const store = new WorkboardStore(createMemoryStore());
111-
const card = await store.create({ title: "Remote target", status: "ready" });
118+
const card = await store.create({
119+
title: "Remote target",
120+
status: "ready",
121+
});
112122
const program = createProgram(store);
113123
gatewayRuntime.callGatewayFromCli.mockRejectedValueOnce(
114124
new Error("connect ECONNREFUSED 127.0.0.1:18789"),
115125
);
116126

117127
await expect(
118-
program.parseAsync(["workboard", "dispatch", "--url", "ws://remote"], { from: "user" }),
128+
program.parseAsync(["workboard", "dispatch", "--url", "ws://remote"], {
129+
from: "user",
130+
}),
119131
).rejects.toThrow("ECONNREFUSED");
120132

121133
const after = await store.get(card.id);
@@ -125,7 +137,10 @@ describe("registerWorkboardCli", () => {
125137

126138
it("does not fall back to local dispatch for configured remote gateways", async () => {
127139
const store = new WorkboardStore(createMemoryStore());
128-
const card = await store.create({ title: "Configured remote target", status: "ready" });
140+
const card = await store.create({
141+
title: "Configured remote target",
142+
status: "ready",
143+
});
129144
const program = createProgram(store);
130145
gatewayRuntime.getRuntimeConfig.mockReturnValue({
131146
gateway: { mode: "remote", remote: { url: "wss://gateway.example" } },
@@ -152,4 +167,29 @@ describe("registerWorkboardCli", () => {
152167
program.parseAsync(["workboard", "show", prefix], { from: "user" }),
153168
).rejects.toThrow("Ambiguous card id prefix");
154169
});
170+
171+
it("filters out archived cards by default in list command", async () => {
172+
const store = new WorkboardStore(createMemoryStore());
173+
const activeCard = await store.create({ title: "Active Card" });
174+
const archivedCard = await store.create({ title: "Archived Card" });
175+
await store.archive(archivedCard.id, true);
176+
const program = createProgram(store);
177+
178+
const defaultOutput = await captureStdout(async () => {
179+
await program.parseAsync(["workboard", "list", "--json"], {
180+
from: "user",
181+
});
182+
});
183+
const parsedDefault = JSON.parse(defaultOutput);
184+
expect(parsedDefault.cards).toHaveLength(1);
185+
expect(parsedDefault.cards[0].id).toBe(activeCard.id);
186+
187+
const archivedOutput = await captureStdout(async () => {
188+
await program.parseAsync(["workboard", "list", "--include-archived", "--json"], {
189+
from: "user",
190+
});
191+
});
192+
const parsedArchived = JSON.parse(archivedOutput);
193+
expect(parsedArchived.cards).toHaveLength(2);
194+
});
155195
});

extensions/workboard/src/cli.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,26 @@ export function registerWorkboardCli(params: { program: Command; store: Workboar
130130
.description("List Workboard cards")
131131
.option("--board <id>", "Board id")
132132
.option("--status <status>", "Filter by status")
133+
.option("--include-archived", "Include archived cards", false)
133134
.option("--json", "Print JSON", false)
134-
.action(async (options: JsonOptions & { board?: string; status?: string }) => {
135-
let cards = await params.store.list({ boardId: options.board });
136-
if (options.status) {
137-
cards = cards.filter((card) => card.status === options.status);
138-
}
139-
writeCards(cards, options);
140-
});
135+
.action(
136+
async (
137+
options: JsonOptions & {
138+
board?: string;
139+
status?: string;
140+
includeArchived?: boolean;
141+
},
142+
) => {
143+
let cards = await params.store.list({ boardId: options.board });
144+
if (!options.includeArchived) {
145+
cards = cards.filter((card) => !card.metadata?.archivedAt);
146+
}
147+
if (options.status) {
148+
cards = cards.filter((card) => card.status === options.status);
149+
}
150+
writeCards(cards, options);
151+
},
152+
);
141153

142154
workboard
143155
.command("create")

0 commit comments

Comments
 (0)