Skip to content

Commit 6720aa9

Browse files
YB0ysteipete
authored andcommitted
fix(cli): add sessions list alias (#81163) (thanks @YB0y)
1 parent aca258a commit 6720aa9

3 files changed

Lines changed: 131 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Docs: https://docs.openclaw.ai
1212

1313
### Fixes
1414

15+
- CLI/sessions: accept `openclaw sessions list` as an alias for `openclaw sessions`, matching other list-style commands. Fixes #81139. (#81163) Thanks @YB0y.
1516
- CLI/plugins: have `openclaw plugins doctor` warn when a configured runtime needs a missing owner plugin, sharing the same install mapping as `openclaw doctor --fix`. Fixes #81326. (#81674) Thanks @Zavianx.
1617
- Agents/Codex: route OpenAI runs that resolve to `openai-codex` through the Codex provider and bootstrap OpenClaw's stored OAuth profile into the Codex harness when the harness owns transport, so `openai/*` model refs no longer fail with `No API key found for openai-codex` despite an existing Codex OAuth profile. (#82864) Thanks @ragesaq.
1718
- Agents/ACP: distinguish prompt-submitted and runtime-active child stalls from true interactive waits, including redacted proxy-env diagnostics for Codex ACP no-output runs. Fixes #44810.

src/cli/program/register.status-health-sessions.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,74 @@ describe("registerStatusHealthSessionsCommands", () => {
241241
});
242242
});
243243

244+
it("dispatches sessions list as an alias for bare sessions (regression for #81139)", async () => {
245+
await runCli(["sessions", "list"]);
246+
247+
expect(sessionsCommand).toHaveBeenCalledTimes(1);
248+
expectCommandOptions(sessionsCommand, {
249+
json: false,
250+
allAgents: false,
251+
agent: undefined,
252+
store: undefined,
253+
});
254+
});
255+
256+
it("forwards sessions parent options through the list alias", async () => {
257+
await runCli([
258+
"sessions",
259+
"--json",
260+
"--verbose",
261+
"--store",
262+
"/tmp/sessions.json",
263+
"--agent",
264+
"work",
265+
"--all-agents",
266+
"--active",
267+
"120",
268+
"--limit",
269+
"25",
270+
"list",
271+
]);
272+
273+
expect(setVerbose).toHaveBeenCalledWith(true);
274+
expectCommandOptions(sessionsCommand, {
275+
json: true,
276+
store: "/tmp/sessions.json",
277+
agent: "work",
278+
allAgents: true,
279+
active: "120",
280+
limit: "25",
281+
});
282+
});
283+
284+
it("forwards sessions list-side options", async () => {
285+
await runCli([
286+
"sessions",
287+
"list",
288+
"--json",
289+
"--verbose",
290+
"--store",
291+
"/tmp/sessions.json",
292+
"--agent",
293+
"work",
294+
"--all-agents",
295+
"--active",
296+
"120",
297+
"--limit",
298+
"25",
299+
]);
300+
301+
expect(setVerbose).toHaveBeenCalledWith(true);
302+
expectCommandOptions(sessionsCommand, {
303+
json: true,
304+
store: "/tmp/sessions.json",
305+
agent: "work",
306+
allAgents: true,
307+
active: "120",
308+
limit: "25",
309+
});
310+
});
311+
244312
it("runs sessions cleanup subcommand with forwarded options", async () => {
245313
await runCli([
246314
"sessions",

src/cli/program/register.status-health-sessions.ts

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,57 @@ function resolveVerbose(opts: { verbose?: boolean; debug?: boolean }): boolean {
2626
return Boolean(opts.verbose || opts.debug);
2727
}
2828

29+
type SessionsListCliOptions = {
30+
json?: boolean;
31+
verbose?: boolean;
32+
store?: string;
33+
agent?: string;
34+
allAgents?: boolean;
35+
active?: string;
36+
limit?: string;
37+
};
38+
39+
function addSessionsListOptions(command: Command): Command {
40+
return command
41+
.option("--json", "Output as JSON", false)
42+
.option("--verbose", "Verbose logging", false)
43+
.option("--store <path>", "Path to session store (default: resolved from config)")
44+
.option("--agent <id>", "Agent id to inspect (default: configured default agent)")
45+
.option("--all-agents", "Aggregate sessions across all configured agents", false)
46+
.option("--active <minutes>", "Only show sessions updated within the past N minutes")
47+
.option("--limit <count>", 'Max sessions to show (default: 100; use "all" for full output)');
48+
}
49+
50+
function mergeSessionsListOptions(
51+
opts: SessionsListCliOptions,
52+
parentOpts?: SessionsListCliOptions,
53+
): SessionsListCliOptions {
54+
return {
55+
json: Boolean(opts.json || parentOpts?.json),
56+
verbose: Boolean(opts.verbose || parentOpts?.verbose),
57+
store: opts.store ?? parentOpts?.store,
58+
agent: opts.agent ?? parentOpts?.agent,
59+
allAgents: Boolean(opts.allAgents || parentOpts?.allAgents),
60+
active: opts.active ?? parentOpts?.active,
61+
limit: opts.limit ?? parentOpts?.limit,
62+
};
63+
}
64+
65+
async function runSessionsListCli(opts: SessionsListCliOptions): Promise<void> {
66+
setVerbose(Boolean(opts.verbose));
67+
await sessionsCommand(
68+
{
69+
json: Boolean(opts.json),
70+
store: opts.store,
71+
agent: opts.agent,
72+
allAgents: Boolean(opts.allAgents),
73+
active: opts.active,
74+
limit: opts.limit,
75+
},
76+
defaultRuntime,
77+
);
78+
}
79+
2980
function parseTimeoutMs(timeout: unknown): number | null | undefined {
3081
const parsed = parsePositiveIntOrUndefined(timeout);
3182
if (timeout !== undefined && parsed === undefined) {
@@ -123,16 +174,9 @@ export function registerStatusHealthSessionsCommands(program: Command) {
123174
});
124175
});
125176

126-
const sessionsCmd = program
127-
.command("sessions")
128-
.description("List stored conversation sessions")
129-
.option("--json", "Output as JSON", false)
130-
.option("--verbose", "Verbose logging", false)
131-
.option("--store <path>", "Path to session store (default: resolved from config)")
132-
.option("--agent <id>", "Agent id to inspect (default: configured default agent)")
133-
.option("--all-agents", "Aggregate sessions across all configured agents", false)
134-
.option("--active <minutes>", "Only show sessions updated within the past N minutes")
135-
.option("--limit <count>", 'Max sessions to show (default: 100; use "all" for full output)')
177+
const sessionsCmd = addSessionsListOptions(
178+
program.command("sessions").description("List stored conversation sessions"),
179+
)
136180
.addHelpText(
137181
"after",
138182
() =>
@@ -154,21 +198,17 @@ export function registerStatusHealthSessionsCommands(program: Command) {
154198
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.openclaw.ai/cli/sessions")}\n`,
155199
)
156200
.action(async (opts) => {
157-
setVerbose(Boolean(opts.verbose));
158-
await sessionsCommand(
159-
{
160-
json: Boolean(opts.json),
161-
store: opts.store as string | undefined,
162-
agent: opts.agent as string | undefined,
163-
allAgents: Boolean(opts.allAgents),
164-
active: opts.active as string | undefined,
165-
limit: opts.limit as string | undefined,
166-
},
167-
defaultRuntime,
168-
);
201+
await runSessionsListCli(opts as SessionsListCliOptions);
169202
});
170203
sessionsCmd.enablePositionalOptions();
171204

205+
addSessionsListOptions(
206+
sessionsCmd.command("list").description("List stored conversation sessions"),
207+
).action(async (opts, command) => {
208+
const parentOpts = command.parent?.opts() as SessionsListCliOptions | undefined;
209+
await runSessionsListCli(mergeSessionsListOptions(opts as SessionsListCliOptions, parentOpts));
210+
});
211+
172212
sessionsCmd
173213
.command("cleanup")
174214
.description("Run session-store maintenance now")

0 commit comments

Comments
 (0)