Skip to content
Closed
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
40 changes: 36 additions & 4 deletions CLI/CMUXCLI+SessionsList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,8 @@ extension CMUXCLI {
guard !normalized.isEmpty else {
throw CLIError(message: String(localized: "cli.sessions.error.agentRequiresValue", defaultValue: "sessions list: --agent requires a value"))
}
if normalized == "claude" || normalized == "claude-code" || normalized == "claude_code" {
selectedSpecs = agentSpecs.filter { $0.name == "claude" }
} else if let def = Self.agentDef(named: normalized) {
selectedSpecs = agentSpecs.filter { $0.name == def.name }
if let canonical = Self.sessionsCanonicalAgentName(normalized) {
selectedSpecs = agentSpecs.filter { $0.name == canonical }
} else {
throw CLIError(message: String(
format: String(localized: "cli.sessions.error.unknownAgent", defaultValue: "sessions list: unknown agent '%@'"),
Expand Down Expand Up @@ -309,13 +307,34 @@ extension CMUXCLI {
}
}

/// Canonical agent name for an `--agent` value, or nil when the value names
/// no agent this build knows.
///
/// Shared by `sessions list` and `sessions live` so the two subcommands
/// accept exactly the same spellings. `claude-code` is accepted because the
/// hook catalog calls the agent `claude` while its own docs and binary say
/// `claude-code`.
static func sessionsCanonicalAgentName(_ raw: String) -> String? {
let normalized = raw.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
guard !normalized.isEmpty else { return nil }
if normalized == "claude" || normalized == "claude-code" || normalized == "claude_code" {
return "claude"
}
return agentDef(named: normalized)?.name
}

func sessionsUsage() -> String {
String(localized: "cli.sessions.usage", defaultValue: """
Usage: cmux sessions list [options]
cmux sessions [options]
cmux sessions live [options]

Print saved agent session records from ~/.cmuxterm/*-hook-sessions.json.
This command does not require a running cmux socket.

For what is happening right now, use `cmux sessions live` instead: it asks
the running app, so it knows each session's current state, how long it has
held it, and the conversation title. Saved records know none of those.
By default, broad output shows active, restorable, or transcript-backed records.
Pass --all to inspect every saved hook record.

Expand All @@ -338,6 +357,19 @@ extension CMUXCLI {
Compatibility aliases:
cmux sessions debug [options]
cmux session-debug [options]

cmux sessions live [options]
Live agent sessions from the running app, ordered for triage: sessions
waiting on you first (longest wait first), then running (longest first),
then idle and ended (most recent first). Requires a running cmux.

--needs-me Only sessions waiting on a human
--state <name> Only needs-input, working, idle or ended
--agent <name> Only one agent, for example codex or claude
--limit <n> Limit rows shown (default: 100)
--all Print all matches
--json Print structured JSON, with total_matches and limit
alongside the rows
""")
}

Expand Down
Loading
Loading