docs: UI-audit fixes in CLAUDE.md, API, OpenAPI, LANES and READMEs

New params and errors (agents session_ids, sessions awaiting/from/to,
stats tool counts, event labels, cleanup dry_run/INVALID_PURGE_DAYS, lane
start slot auto/ESESSIONLIVE/EUNSUPPORTED), terminal and pane shortcuts,
the shared UI primitives, accent vs accent-solid, lazy routes and the
Settings groups. openapi.yaml regenerated.
This commit is contained in:
2026-10-05 13:22:13 +07:00
parent d4961d94ef
commit 442f133930
12 changed files with 230 additions and 31 deletions
+69 -6
View File
@@ -636,6 +636,14 @@ components:
count:
type: integer
minimum: 0
tool_call_count:
type: integer
minimum: 0
description: 'Exact tool calls: PreToolUse events with a tool_name, or PostToolUse ones when the session has no PreToolUse (an imported session). tools_used is a top-15 list, so its sum is not this.'
distinct_tool_count:
type: integer
minimum: 0
description: Number of different tool names this session called.
error_count:
type: integer
minimum: 0
@@ -1778,9 +1786,12 @@ components:
minimum: 0
description: Mark active sessions abandoned if stale for this many hours
purge_days:
type: number
minimum: 0
description: Delete old completed/error/abandoned sessions older than this many days
type: integer
minimum: 1
description: Delete old completed/error/abandoned sessions older than this many days. A whole number ≥ 1, else 400 INVALID_PURGE_DAYS (a fraction would purge almost everything).
dry_run:
type: boolean
description: true = answer the same counts and change nothing.
CleanupResponse:
type: object
required:
@@ -1802,6 +1813,11 @@ components:
type: integer
purged_agents:
type: integer
dry_run:
type: boolean
enum:
- true
description: 'Present (true) only on a dry run: the counts were not applied.'
CcConfigScope:
type: string
enum:
@@ -4773,6 +4789,28 @@ paths:
- antigravity
description: Only the sessions of one CLI. Applied before `limit`, so a busy Codex lane cannot push Claude sessions off a page.
example: claude
- name: awaiting
in: query
schema:
type: string
enum:
- '1'
description: '`1` = only sessions blocked on the user (`awaiting_input_since IS NOT NULL AND status = ''active''`), the UI''s Waiting filter. Applied before `limit`/`offset`, so `total` stays exact.'
example: '1'
- name: from
in: query
schema:
type: string
format: date-time
description: Inclusive lower bound on `started_at` (ISO 8601). An unparseable value is ignored. Applied before `limit`/`offset`.
example: '2026-10-01T00:00:00.000Z'
- name: to
in: query
schema:
type: string
format: date-time
description: Inclusive upper bound on `started_at` (ISO 8601). An unparseable value is ignored. Applied before `limit`/`offset`.
example: '2026-10-05T23:59:59.999Z'
- $ref: '#/components/parameters/SourcesQuery'
example: local,4d1f0e2a-7b9c-4c33-8a21-9e0f7b6d4c11
- $ref: '#/components/parameters/LimitQuery'
@@ -5039,7 +5077,7 @@ paths:
tags:
- Sessions
summary: Get aggregated session stats
description: 'Returns aggregated counts for the SessionOverview panel: total events, events-by-type, the top 15 tools by usage, an error count (events whose `event_type`/`summary` match /error/i or /failed/i), the event time range, agent type/status counts, the subagent-type breakdown (excluding the special `compaction` type, which is surfaced under `agents.compaction`), and token totals. All aggregation runs in SQL, so it stays cheap even for sessions with tens of thousands of events; the endpoint is read-only with no side effects. The frontend debounces calls on `new_event` / `agent_*` / `session_updated` websocket frames so the counters track a running session. Returns 404 with code `NOT_FOUND` when the session does not exist.'
description: 'Returns aggregated counts for the SessionOverview panel: total events, events-by-type, the top 15 tools by usage, the exact `tool_call_count` (PreToolUse events with a `tool_name`, or PostToolUse when the session has none, e.g. an imported one) and `distinct_tool_count` (different tool names) — `tools_used` is a top-15 list, so its sum is not the count —, an error count (events whose `event_type`/`summary` match /error/i or /failed/i), the event time range, agent type/status counts, the subagent-type breakdown (excluding the special `compaction` type, which is surfaced under `agents.compaction`), and token totals. All aggregation runs in SQL, so it stays cheap even for sessions with tens of thousands of events; the endpoint is read-only with no side effects. The frontend debounces calls on `new_event` / `agent_*` / `session_updated` websocket frames so the counters track a running session. Returns 404 with code `NOT_FOUND` when the session does not exist.'
operationId: getSessionStats
parameters:
- $ref: '#/components/parameters/SessionIdPath'
@@ -5072,6 +5110,8 @@ paths:
count: 121
- tool_name: Grep
count: 77
tool_call_count: 612
distinct_tool_count: 9
error_count: 6
first_event_at: '2026-06-25T14:02:11.052Z'
last_event_at: '2026-06-25T14:31:50.119Z'
@@ -5252,13 +5292,19 @@ paths:
tags:
- Agents
summary: List agents
description: 'Returns agents, most recent first. Filters are applied with precedence rather than composition: when `session_id` is supplied it wins and returns every agent for that session (ignoring `status` and pagination); otherwise a `status` filter returns paginated agents in that lifecycle state; otherwise all agents are returned paginated. `limit` defaults to 10000 when not a positive integer. Read-only, no side effects. Each agent''s `metadata` is returned as a raw JSON-encoded string, not a parsed object.'
description: 'Returns agents, most recent first. Filters are applied with precedence rather than composition: `session_ids` (comma-separated, duplicates and blanks dropped, at most 200 ids, `limit` applied but not `offset`, newest `started_at` first; an empty list answers no agents) wins over everything else and returns every agent of those sessions in one call; next, when `session_id` is supplied it wins and returns every agent for that session (ignoring `status` and pagination); otherwise a `status` filter returns paginated agents in that lifecycle state; otherwise all agents are returned paginated. `limit` defaults to 10000 when not a positive integer. Read-only, no side effects. Each agent''s `metadata` is returned as a raw JSON-encoded string, not a parsed object.'
operationId: listAgents
parameters:
- $ref: '#/components/parameters/AgentStatusQuery'
example: working
- $ref: '#/components/parameters/SessionFilterQuery'
example: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
- name: session_ids
in: query
schema:
type: string
description: 'Comma-separated session ids: every agent of those sessions in one call (the Dashboard''s active trees). Duplicates and blanks are dropped, at most 200 ids are read, `limit` still applies and `offset` does not; ordered by `started_at` DESC. Takes precedence over `session_id`, `status` and `sources`. An empty list answers `{agents: []}`.'
example: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d,0c4e9a1b-2d3f-4a5b-8c6d-7e8f9a0b1c2d
- $ref: '#/components/parameters/SourcesQuery'
example: local,4d1f0e2a-7b9c-4c33-8a21-9e0f7b6d4c11
- $ref: '#/components/parameters/LimitQuery'
@@ -5499,6 +5545,8 @@ paths:
`q` performs a case-insensitive substring (`LIKE %q%`) search across the `summary`, `tool_name`, and the JSON-encoded `data` columns. `from`/`to` are inclusive ISO-8601 datetime bounds on `created_at`; unparseable values are ignored rather than rejected. `limit` is clamped to 1–500 (default 50) and `offset` is clamped to >= 0 (default 0).
Note: each returned event's `data` field is a **JSON-encoded string**, not a nested object — callers must `JSON.parse` it to inspect the payload.
Each row also carries its labels, so a list page need not fetch every session and agent to name them: `session_name`, `session_cwd`, `session_lane_id`, `agent_name` and `agent_subagent_type` (nullable; `null` when the session or agent row is missing). They are REST-only — the WebSocket `new_event` frame is unchanged.
parameters:
- in: query
name: event_type
@@ -6648,7 +6696,7 @@ paths:
tags:
- Settings
summary: Abandon stale sessions and optionally purge old history
description: 'Two-phase maintenance. Phase 1 (`abandon_hours`, non-destructive): marks any still-`active` session with no events newer than that many hours as `abandoned`, and completes its lingering agents — a tidy-up of crashed/orphaned sessions. Phase 2 (`purge_days`) is ⚠ DESTRUCTIVE and IRREVERSIBLE: it permanently DELETES completed/error/abandoned sessions (and their events, agents, and token_usage) whose `started_at` is older than that many days. Active sessions are NEVER purged. Both fields are optional and independent — send only `abandon_hours` for a safe tidy-up, or include `purge_days` to also reclaim disk. Export first if the purged history matters. The response reports counts for each phase.'
description: 'Two-phase maintenance. Phase 1 (`abandon_hours`, non-destructive): marks any still-`active` session with no events newer than that many hours as `abandoned`, and completes its lingering agents — a tidy-up of crashed/orphaned sessions. Phase 2 (`purge_days`) is ⚠ DESTRUCTIVE and IRREVERSIBLE: it permanently DELETES completed/error/abandoned sessions (and their events, agents, and token_usage) whose `started_at` is older than that many days. Active sessions are NEVER purged. Both fields are optional and independent — send only `abandon_hours` for a safe tidy-up, or include `purge_days` to also reclaim disk. Export first if the purged history matters. `purge_days` must be a whole number ≥ 1, else 400 `INVALID_PURGE_DAYS` (a fraction like 0.1 would purge almost everything). `dry_run: true` answers the same counts (plus `dry_run: true`) and changes nothing — preview a purge before running it. The response reports counts for each phase.'
operationId: cleanupData
requestBody:
required: true
@@ -6666,6 +6714,11 @@ paths:
value:
abandon_hours: 12
purge_days: 90
preview:
summary: 'Dry run: count what a 90-day purge would delete, change nothing'
value:
purge_days: 90
dry_run: true
responses:
'200':
description: Cleanup result
@@ -6679,6 +6732,16 @@ paths:
purged_sessions: 57
purged_events: 14820
purged_agents: 241
'400':
description: purge_days is not a whole number of days, 1 or more
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error:
code: INVALID_PURGE_DAYS
message: purge_days must be a whole number of days, 1 or more
/api/import/guide:
get:
tags: