Skip to content

Commit 4c80b55

Browse files
silouoneadw factory
andauthored
adw: clens-013-list-reverse-flag build (run clens-013-list-reverse-flag-1785085459819) (#21)
Co-authored-by: adw factory <adw-factory@e2b.local>
1 parent 55844b9 commit 4c80b55

4 files changed

Lines changed: 137 additions & 2 deletions

File tree

packages/cli/src/cli.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const commands: Readonly<Record<string, CommandDef>> = {
7878
projectDir: ctx.projectDir,
7979
json: ctx.flags.json,
8080
global: ctx.flags.global,
81+
reverse: ctx.flags.reverse,
8182
});
8283
},
8384
},
@@ -329,7 +330,7 @@ const GLOBAL_FLAGS = new Set(["--help", "-h", "--version", "-v"]);
329330

330331
const VALID_FLAGS_BY_COMMAND: Readonly<Record<string, ReadonlySet<string>>> = {
331332
init: new Set(["--remove", "--status", "--dev", "--global", "--legacy"]),
332-
list: new Set(["--json", "--global"]),
333+
list: new Set(["--json", "--global", "--reverse"]),
333334
distill: new Set(["--last", "--all", "--global", "--force", "--deep", "--json", "--pricing"]),
334335
report: new Set(["--last", "--json", "--detail", "--full", "--intent"]),
335336
agents: new Set(["--last", "--json", "--comms"]),
@@ -397,6 +398,7 @@ ${bold("Setup:")}
397398
${bold("Sessions:")}
398399
${cyan("list")} List captured sessions
399400
${cyan("list --global")} List sessions across all registered projects
401+
${cyan("list --reverse")} List sessions oldest-first
400402
${cyan("name")} Set/clear a session's label & color flag
401403
${cyan("distill")} Extract insights from session data
402404
${cyan("distill --global")} Distill every session across all registered projects
@@ -488,6 +490,7 @@ const flags: Flags = {
488490
comms: args.includes("--comms"),
489491
global: args.includes("--global"),
490492
legacy: args.includes("--legacy"),
493+
reverse: args.includes("--reverse"),
491494
...(pricingValue ? { pricing: pricingValue } : {}),
492495
};
493496

packages/cli/src/commands/list.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ export const listCommand = async (args: {
1212
projectDir: string;
1313
json: boolean;
1414
global: boolean;
15+
reverse: boolean;
1516
}): Promise<void> => {
16-
const sessions: readonly SessionSummary[] = args.global
17+
const fetchedSessions: readonly SessionSummary[] = args.global
1718
? await (async () => {
1819
const { listGlobalSessions } = await import("../session/global-read");
1920
return listGlobalSessions();
@@ -24,6 +25,10 @@ export const listCommand = async (args: {
2425
return enrichSessionSummaries(raw, args.projectDir);
2526
})();
2627

28+
const sessions: readonly SessionSummary[] = args.reverse
29+
? [...fetchedSessions].reverse()
30+
: fetchedSessions;
31+
2732
if (args.json) {
2833
console.log(JSON.stringify(sessions, null, 2));
2934
return;

packages/cli/src/commands/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export type Flags = {
1717
readonly comms: boolean;
1818
readonly global: boolean;
1919
readonly legacy: boolean;
20+
readonly reverse: boolean;
2021
readonly pricing?: string;
2122
};
2223

packages/cli/test/cli.test.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ describe("cli --help", () => {
7070
expect(stdout).toContain("Usage:");
7171
expect(stdout).toContain("Analysis:");
7272
});
73+
74+
test("documents list --reverse", async () => {
75+
const { stdout } = await runCli("--help");
76+
expect(stdout).toContain("list --reverse");
77+
});
7378
});
7479

7580
describe("cli init", () => {
@@ -156,6 +161,127 @@ describe("cli list", () => {
156161
expect(stdout).toContain("Total:");
157162
expect(stdout).toContain("session(s)");
158163
});
164+
165+
test("--reverse reorders the table oldest-first, footer count unchanged", async () => {
166+
const idA = "aaaa1111-0000-0000-0000-000000000000";
167+
const idB = "bbbb2222-0000-0000-0000-000000000000";
168+
writeSession(idA, [
169+
makeStoredEvent({ t: 1000, event: "SessionStart", sid: idA }),
170+
makeStoredEvent({ t: 2000, event: "SessionEnd", sid: idA }),
171+
]);
172+
writeSession(idB, [
173+
makeStoredEvent({ t: 50000, event: "SessionStart", sid: idB }),
174+
makeStoredEvent({ t: 60000, event: "SessionEnd", sid: idB }),
175+
]);
176+
177+
const reversed = await runCli("list", "--reverse");
178+
expect(reversed.exitCode).toBe(0);
179+
expect(reversed.stdout.indexOf("aaaa1111")).toBeGreaterThanOrEqual(0);
180+
expect(reversed.stdout.indexOf("bbbb2222")).toBeGreaterThanOrEqual(0);
181+
expect(reversed.stdout.indexOf("aaaa1111")).toBeLessThan(reversed.stdout.indexOf("bbbb2222"));
182+
expect(reversed.stdout).toContain("Total:");
183+
expect(reversed.stdout).toContain("across 2 session(s)");
184+
185+
// Mirror image: without --reverse, newest (B) comes first.
186+
const forward = await runCli("list");
187+
expect(forward.stdout.indexOf("bbbb2222")).toBeLessThan(forward.stdout.indexOf("aaaa1111"));
188+
});
189+
190+
test("--json --reverse reverses the JSON array (oldest first)", async () => {
191+
const idA = "aaaa1111-0000-0000-0000-000000000000";
192+
const idB = "bbbb2222-0000-0000-0000-000000000000";
193+
writeSession(idA, [
194+
makeStoredEvent({ t: 1000, event: "SessionStart", sid: idA }),
195+
makeStoredEvent({ t: 2000, event: "SessionEnd", sid: idA }),
196+
]);
197+
writeSession(idB, [
198+
makeStoredEvent({ t: 50000, event: "SessionStart", sid: idB }),
199+
makeStoredEvent({ t: 60000, event: "SessionEnd", sid: idB }),
200+
]);
201+
202+
const { exitCode, stdout } = await runCli("list", "--json", "--reverse");
203+
expect(exitCode).toBe(0);
204+
const parsed = JSON.parse(stdout);
205+
expect(parsed).toHaveLength(2);
206+
expect(parsed[0].session_id).toBe(idA);
207+
expect(parsed[parsed.length - 1].session_id).toBe(idB);
208+
209+
// Cross-check: exact reverse of the plain --json order.
210+
const forward = await runCli("list", "--json");
211+
const forwardParsed = JSON.parse(forward.stdout);
212+
expect(parsed).toEqual([...forwardParsed].reverse());
213+
});
214+
215+
test("no --reverse flag is byte-identical to today (newest-first)", async () => {
216+
const idA = "aaaa1111-0000-0000-0000-000000000000";
217+
const idB = "bbbb2222-0000-0000-0000-000000000000";
218+
writeSession(idA, [
219+
makeStoredEvent({ t: 1000, event: "SessionStart", sid: idA }),
220+
makeStoredEvent({ t: 2000, event: "SessionEnd", sid: idA }),
221+
]);
222+
writeSession(idB, [
223+
makeStoredEvent({ t: 50000, event: "SessionStart", sid: idB }),
224+
makeStoredEvent({ t: 60000, event: "SessionEnd", sid: idB }),
225+
]);
226+
227+
const { exitCode, stdout } = await runCli("list");
228+
expect(exitCode).toBe(0);
229+
expect(stdout.indexOf("bbbb2222")).toBeLessThan(stdout.indexOf("aaaa1111"));
230+
});
231+
232+
test("empty session list with --reverse still prints 'No sessions found.'", async () => {
233+
const { exitCode, stdout } = await runCli("list", "--reverse");
234+
expect(exitCode).toBe(0);
235+
expect(stdout.trim()).toBe("No sessions found.");
236+
});
237+
238+
test("empty session list with --json --reverse prints an empty JSON array", async () => {
239+
const { exitCode, stdout } = await runCli("list", "--json", "--reverse");
240+
expect(exitCode).toBe(0);
241+
expect(JSON.parse(stdout)).toEqual([]);
242+
});
243+
244+
test("--reverse with a single session is a no-op (same output as forward)", async () => {
245+
const id = "cccc3333-0000-0000-0000-000000000000";
246+
writeSession(id, [
247+
makeStoredEvent({ t: 1000, event: "SessionStart", sid: id }),
248+
makeStoredEvent({ t: 2000, event: "SessionEnd", sid: id }),
249+
]);
250+
251+
const forward = await runCli("list");
252+
const reversed = await runCli("list", "--reverse");
253+
expect(reversed.exitCode).toBe(0);
254+
expect(reversed.stdout).toBe(forward.stdout);
255+
});
256+
257+
test("--reverse fully reverses three sessions, not just the endpoints", async () => {
258+
const idOldest = "aaaa1111-0000-0000-0000-000000000000";
259+
const idMiddle = "bbbb2222-0000-0000-0000-000000000000";
260+
const idNewest = "cccc3333-0000-0000-0000-000000000000";
261+
writeSession(idOldest, [
262+
makeStoredEvent({ t: 1000, event: "SessionStart", sid: idOldest }),
263+
makeStoredEvent({ t: 2000, event: "SessionEnd", sid: idOldest }),
264+
]);
265+
writeSession(idMiddle, [
266+
makeStoredEvent({ t: 30000, event: "SessionStart", sid: idMiddle }),
267+
makeStoredEvent({ t: 40000, event: "SessionEnd", sid: idMiddle }),
268+
]);
269+
writeSession(idNewest, [
270+
makeStoredEvent({ t: 50000, event: "SessionStart", sid: idNewest }),
271+
makeStoredEvent({ t: 60000, event: "SessionEnd", sid: idNewest }),
272+
]);
273+
274+
const { exitCode, stdout } = await runCli("list", "--json", "--reverse");
275+
expect(exitCode).toBe(0);
276+
const parsed = JSON.parse(stdout) as Array<{ session_id: string }>;
277+
expect(parsed.map((s) => s.session_id)).toEqual([idOldest, idMiddle, idNewest]);
278+
});
279+
280+
test("--reverse with an unknown flag still rejects the unknown flag", async () => {
281+
const { exitCode, stderr } = await runCli("list", "--reverse", "--bogus");
282+
expect(exitCode).toBe(1);
283+
expect(stderr).toContain("Unknown flag --bogus");
284+
});
159285
});
160286

161287
describe("cli session resolution", () => {

0 commit comments

Comments
 (0)