Skip to content

Add a CLI command to list on-radar (focus-queue) sessions #322

Description

@germanescobar

Summary

controller sessions currently only knows how to start a session. There is no way to enumerate the on-radar / focus-queue sessions from the CLI, so a scheduled agent that wants to "go through all on-radar sessions" has to fall back to parsing the Controller home directory's focus/ sidecar files directly — and even then, it only gets the focus state, not the projectId / worktreeId / sessionId tuple a session-start needs.

Context

The on-radar list shown in the sidebar is computed client-side from the session summaries returned by GET /api/projects/:projectId/sessions: any session whose summary has focusPinnedAt set is in the queue (client/src/components/sidebar.tsx, around line 320). The server side already exposes all the pieces we need — the summaries endpoint, the focus-pin / focus-unpin / focus-done action routes (server/routes/sessions.ts lines 2519-2521), and the SessionFocus sidecar (server/lib/focus-state.ts) — the CLI just doesn't wrap any of them.

Repro

  1. Schedule a recurring session that should iterate the on-radar queue, e.g.:

    controller schedules add super-agents --worktree main \
      --every weekday --at-hour 9 \
      --prompt "For every session currently on radar, open it, run 'continue', and report what it did."
  2. From inside that scheduled session, try to discover the queue from the CLI:

    controller sessions list
    # controller sessions: Unknown sessions command: list
  3. The only escape hatches today are:

    • ls "<controllerHome>/focus/" and cross-reference ids back to projects/worktrees by hand,
    • or shell out to curl against the local server (GET /api/projects/<id>/sessions and grep for focusPinnedAt).

    Both work, but neither is what an agent should have to do, and the first one leaks the Controller home layout into the agent's prompt.

Proposed change

Add a sessions on-radar [<project>] subcommand (or focus-queue, if you'd rather mirror the underlying terminology — happy to defer to whatever naming you prefer; "on-radar" is what the sidebar says). It should:

  1. Resolve <project> the same way worktrees list / sessions start / schedules list do (optional first positional, fall back to cwd via resolveProjectId).
  2. GET /api/projects/<projectId>/sessions to load the summaries.
  3. Filter to entries where focusPinnedAt is set, in the same order the sidebar uses (ascending by focusPinnedAt ?? createdAt, matching client/src/components/sidebar.tsx).
  4. Print one row per session with at least sessionId, projectId, worktreeId, title, provider, focusPinnedAt, and the latest activity timestamp so an agent can decide whether each item is worth visiting. JSON mode (--json) for programmatic consumption would be a nice follow-up but isn't required.
  5. Print No sessions on radar. (matching the sidebar copy) when the filter result is empty, so the agent can detect an empty queue without grepping.

Optional but worth considering while we're in here:

  • A --all-projects flag that walks every project and prints a unified list — this is the common case for a "go through everything on radar" sweep, and resolving projectId per row is the part that hurts most today.
  • Symmetric sessions pin / sessions unpin / sessions done subcommands that wrap the existing POST /:projectId/sessions/:sessionId/focus-pin|unpin|done routes. If included, they should accept <project> and <sessionId> as positional args (or a --worktree flag for the project lookup) and print a one-line confirmation, mirroring the integration delete we just landed in integrations delete is missing from the CLI #308.

Why this matters

The scheduled-agent workflow in controller schedules already exists (#243), and the on-radar / Controller Mode workflow that "go through on-radar sessions" implies has been shipping since #277. Closing this gap is what makes the two actually compose: without a CLI to list the queue, a schedule that says "go through on-radar sessions" can't find the on-radar sessions.

Validation

  • Unit test in cli/__tests__/controller-cli.test.mjs that stubs GET /api/projects/<id>/sessions with a mixed list (some pinned, some not, some with focusPinnedAt, some without) and asserts the CLI prints only the pinned ones in the right order, with a clear No sessions on radar. line for the empty case.
  • Manual: from the same project that has sessions on radar in the desktop sidebar, run controller sessions on-radar and confirm the output matches what the sidebar shows.
  • Manual: schedule a sweep with controller schedules add, then once it fires, watch the agent use the new command to discover the queue instead of poking around <controllerHome>/focus/.

Out of scope

  • Renaming "on-radar" to "focus-queue" (or vice versa) in the CLI surface. Pick one for the subcommand and document it in the help text; a follow-up can align the rest.
  • A bulk "mark all as done" / "clear on-radar" command. Easy to add later if there's demand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions