live sessions default to agents only, and you ask by name for a commander
`?kind=` was opt-in, so a client that said nothing got everything — which is the wrong default for the one caller that cannot cope. The phone swipes between live chats one at a time, has no room for tabs and no way to skip a row, so a commander in that list is a commander you are stuck on. Defaulting to `agent` means forgetting the parameter can only ever under-report. The two callers that want both now say `kind=all` explicitly, and that is a fair price: they are few, they are on screens built to show both kinds, and they are the ones positioned to notice when the answer is wrong. `counts` still describes every live session whatever the filter, so a filtered caller renders both tab numbers from one request rather than two. Also corrects useLiveSessions' comment, which said `isCommander` was derived from the cwd. It stopped being true when a commander gained the right to choose its own working directory — it comes from the `command_hq_sessions` row, and the directory answers nothing. Unrelated but caught by docs:check on the way past: the registry gained a nineteenth entry (minesweeper, execution) and CLAUDE.md still said eighteen, which also left the generated platform skill two lines stale. Both corrected; the check is green again. The minesweeper feature itself is half-landed and not mine — `rfb.ts` fails typecheck and its registry test fails on a websocket that is not served. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,8 @@ export type LiveSession = {
|
||||
title: string | null;
|
||||
cwd: string | null;
|
||||
/**
|
||||
* A commander rather than an ordinary chat, derived server-side from the cwd.
|
||||
* A commander rather than an ordinary chat, derived server-side from its `command_hq_sessions` row.
|
||||
* NOT from the cwd — a commander chooses its own working directory, so the directory answers nothing.
|
||||
*
|
||||
* Every consumer of this list needs it, and one of them cannot work around its absence. The sessions
|
||||
* panel splits Live into two tabs; the iPhone app swipes between live chats, has no tabs, and so can only
|
||||
@@ -36,6 +37,12 @@ export type LiveSession = {
|
||||
isCommander: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Counts describe every live session, not just the ones returned — so a filtered request still renders
|
||||
* `Agents (n) / Commanders (n)` without a second round trip.
|
||||
*/
|
||||
type LivePayload = { sessions: LiveSession[]; counts: { agents: number; commanders: number } };
|
||||
|
||||
const LIVE_KEY = 'CHAT_LIVE_SESSIONS';
|
||||
|
||||
/**
|
||||
@@ -50,9 +57,17 @@ export function useLiveSessions() {
|
||||
const client = useClient();
|
||||
const { isAuthenticated } = useAuth();
|
||||
|
||||
const { data, isLoading, error, refetch } = useQuery<{ sessions: LiveSession[] }>({
|
||||
/*
|
||||
`kind=all` is required, not a default. `/chat/live` returns ONLY agents unless asked otherwise, so that
|
||||
a caller which forgets can never be handed a commander — a phone swiping between live chats one at a
|
||||
time has no way to skip one. This list is the other case: it renders both kinds as tabs, so it asks for
|
||||
both, explicitly, and the explicitness is what makes it reviewable.
|
||||
|
||||
`counts` describes the whole set either way, which is why both tab numbers are right from one request.
|
||||
*/
|
||||
const { data, isLoading, error, refetch } = useQuery<LivePayload>({
|
||||
queryKey: [LIVE_KEY],
|
||||
queryFn: () => client.get<{ sessions: LiveSession[] }>('/chat/live'),
|
||||
queryFn: () => client.get<LivePayload>('/chat/live?kind=all'),
|
||||
enabled: isAuthenticated,
|
||||
refetchInterval: 10_000,
|
||||
staleTime: 5_000,
|
||||
|
||||
Reference in New Issue
Block a user