Skip to content
Merged
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
2 changes: 2 additions & 0 deletions frontend/e2e/pages/sessions-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class SessionsPage {
readonly sortButton: Locator;
readonly projectTypeahead: Locator;
readonly sessionListHeader: Locator;
readonly sessionCount: Locator;

readonly analyticsPage: Locator;
readonly analyticsToolbar: Locator;
Expand All @@ -27,6 +28,7 @@ export class SessionsPage {
this.sortButton = page.getByLabel("Toggle sort order");
this.projectTypeahead = page.locator(".typeahead");
this.sessionListHeader = page.locator(".session-list-header");
this.sessionCount = this.sessionListHeader.locator(".session-count");
this.analyticsPage = page.locator(".analytics-page");
this.analyticsToolbar = page.locator(".analytics-toolbar");
this.exportBtn = page.locator(".export-btn");
Expand Down
4 changes: 1 addition & 3 deletions frontend/e2e/termination.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ test.describe("session termination status", () => {

// The fixture has exactly one unclean session.
await expect(sp.sessionItems).toHaveCount(1);
await expect(sp.sessionListHeader).toContainText(
"1 sessions",
);
await expect(sp.sessionCount).toHaveText("1 session");

// Surviving session renders the unclean StatusDot.
await expect(
Expand Down
7 changes: 3 additions & 4 deletions frontend/e2e/virtual-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,9 @@ test.describe("Virtual list behavior", () => {

// Wait for filtered results to render before checking
// scroll position — on CI the re-render can be slow.
await expect(sp.sessionListHeader).toContainText(
"1 sessions",
{ timeout: 5_000 },
);
await expect(sp.sessionCount).toHaveText("1 session", {
timeout: 5_000,
});

await expect
.poll(() => getScrollTop(sp.sessionListScroll), {
Expand Down
236 changes: 229 additions & 7 deletions frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,54 @@
"header_actions_settings": "Settings",
"header_actions_keyboard_shortcuts": "Keyboard shortcuts",
"header_actions_keyboard_shortcuts_shortcut": "Keyboard shortcuts (?)",
"status_bar_sessions": "{count} sessions",
"status_bar_messages": "{count} messages",
"status_bar_projects": "{count} projects",
"status_bar_sessions": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} session",
"countPlural=other": "{countLabel} sessions"
}
}
],
"status_bar_messages": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} message",
"countPlural=other": "{countLabel} messages"
}
}
],
"status_bar_projects": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} project",
"countPlural=other": "{countLabel} projects"
}
}
],
"status_bar_open_performance_debug": "Open performance debug",
"status_bar_perf": "Perf",
"status_bar_remote_unreachable_title": "Can't reach the remote server. Open settings to check the URL, token, or disconnect.",
Expand Down Expand Up @@ -248,8 +293,34 @@
"compact_boundary_title": "Context window compacted at this point",
"compact_boundary_label": "Context compacted",
"compact_boundary_show_full_summary": "Show full summary",
"sidebar_session_count": "{count} sessions",
"sidebar_session_count": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} session",
"countPlural=other": "{countLabel} sessions"
}
}
],
"sidebar_loading": "loading",
"sidebar_multi_select": "Multi-select",
"sidebar_exit_multi_select": "Exit multi-select",
"sidebar_select_all_visible": "Select all visible",
"sidebar_clear_selection": "Clear selection",
"sidebar_batch_clear": "Clear",
"sidebar_batch_all": "All",
"sidebar_selected_count": "{countLabel} selected",
"sidebar_move_selected_to_trash": "Move selected sessions to trash",
"sidebar_deleting": "Deleting...",
"sidebar_delete": "Delete",
"sidebar_cancel": "Cancel",
"sidebar_status": "Status",
"sidebar_active": "Active",
"sidebar_active_title": "Last activity within 10 minutes",
Expand Down Expand Up @@ -287,6 +358,8 @@
"sidebar_filters_clear_filters": "Clear filters",
"sidebar_row_expand": "Expand",
"sidebar_row_collapse": "Collapse",
"sidebar_row_select_session": "Select session",
"sidebar_row_deselect_session": "Deselect session",
"sidebar_row_star_session": "Star session",
"sidebar_row_unstar_session": "Unstar session",
"sidebar_row_rename": "Rename",
Expand Down Expand Up @@ -599,6 +672,9 @@
"usage_top_sessions_by_cost": "Top Sessions by Cost",
"settings_title": "Settings",
"settings_loading": "Loading settings...",
"settings_resync_title_unavailable": "Full resync unavailable in read-only mode",
"settings_resync_unavailable_hint": "Unavailable while connected to a read-only backend",
"settings_resync_hint": "Re-scan all session files from scratch",
"settings_language_title": "Language",
"settings_language_description": "Choose the interface language.",
"settings_language_label": "Interface language",
Expand Down Expand Up @@ -649,7 +725,23 @@
"activity_int_auto_short": "{int} int / {auto} auto",
"activity_peak_label": "peak {count}",
"activity_agent_min_value": "{value} agent-min",
"activity_output_tokens_value": "{count} output tokens",
"activity_no_sessions_selected_slot": "No sessions active in the selected slot.",
"activity_output_tokens_value": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} output token",
"countPlural=other": "{countLabel} output tokens"
}
}
],
"activity_concurrency": "Concurrency",
"activity_overlay": "Overlay",
"activity_overlay_metric": "Concurrency overlay metric",
Expand Down Expand Up @@ -791,6 +883,104 @@
"status_dot_stale": "Flagged session, idle for 10–60 minutes",
"status_dot_unclean": "Terminated mid tool call (or file truncated)",
"call_row_toggle_subagent_calls": "Toggle sub-agent calls",
"call_row_running_duration": "running {duration}+",
"call_group_parallel_label": "parallel",
"call_group_parallel_call_count": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} call",
"countPlural=other": "{countLabel} calls"
}
}
],
"subagent_calls_label": "↳ sub-agent",
"subagent_calls_summary": [
{
"declarations": [
"input count",
"input countLabel",
"input duration",
"input running",
"local countPlural = count: plural"
],
"selectors": [
"countPlural",
"running"
],
"match": {
"countPlural=one,running=true": "{countLabel} call · running {duration}+",
"countPlural=other,running=true": "{countLabel} calls · running {duration}+",
"countPlural=one,running=false": "{countLabel} call · {duration}",
"countPlural=other,running=false": "{countLabel} calls · {duration}"
}
}
],
"activity_lane_activity": "activity",
"activity_lane_message_count": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} message",
"countPlural=other": "{countLabel} messages"
}
}
],
"session_vitals_title": "Analysis",
"session_vitals_subtitle": "Session vital signs",
"session_vitals_close": "Close session analysis",
"session_vitals_session": "Session",
"session_vitals_running": "running",
"session_vitals_running_duration": "running {duration}+",
"session_vitals_tool_calls": "tool calls",
"session_vitals_tool_time": "tool time",
"session_vitals_slowest_call": "slowest call",
"session_vitals_jump_to_call": "Jump to call",
"session_vitals_turns": "turns",
"session_vitals_subagents": "sub-agents",
"session_vitals_time_spent": "Time spent",
"session_vitals_clear_category_filter": "clear category filter",
"session_vitals_completed_turns_hint": "completed turns · click to highlight",
"session_vitals_timeline": "Timeline",
"session_vitals_click_marks_to_scroll": "click marks to scroll",
"session_vitals_jump_to_turn": "Jump to {category} turn at {time}",
"session_vitals_calls": "Calls",
"session_vitals_calls_summary": [
{
"declarations": [
"input count",
"input countLabel",
"input runningCount",
"local countPlural = count: plural",
"local runningPlural = runningCount: plural"
],
"selectors": [
"countPlural",
"runningPlural"
],
"match": {
"countPlural=one,runningPlural=one": "{countLabel} call · {runningCount} running",
"countPlural=other,runningPlural=one": "{countLabel} calls · {runningCount} running",
"countPlural=one,runningPlural=other": "{countLabel} call",
"countPlural=other,runningPlural=other": "{countLabel} calls"
}
}
],
"session_vitals_now": "now",
"code_block_copy": "Copy code block",
"code_block_copy_title": "Copy code",
"common_copied": "Copied!",
Expand Down Expand Up @@ -915,7 +1105,22 @@
"insights_page_sessions_computed": "sessions computed",
"insights_page_score_distribution": "Score distribution",
"insights_page_pct_affected": "{pct}% affected",
"insights_page_driver_sessions": "{count} sessions",
"insights_page_driver_sessions": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} session",
"countPlural=other": "{countLabel} sessions"
}
}
],
"insights_page_session_evidence": "Session evidence",
"insights_page_close": "Close",
"insights_page_loading_examples": "Loading examples...",
Expand Down Expand Up @@ -1028,6 +1233,8 @@
"resync_failed": "Failed: {count}",
"resync_close_btn": "Close",
"resync_retry": "Retry",
"resync_error_read_only": "Full resync is unavailable for read-only backends.",
"resync_error_in_progress": "A sync is already in progress.",
"shortcuts_open_command_palette": "Open command palette",
"shortcuts_find_in_session": "Find in session",
"shortcuts_close_palette": "Close palette / modal / find",
Expand Down Expand Up @@ -1169,7 +1376,22 @@
"trash_title": "Trash",
"trash_emptying": "Emptying...",
"trash_empty_trash": "Empty Trash",
"trash_msgs": "{count} msgs",
"trash_msgs": [
{
"declarations": [
"input count",
"input countLabel",
"local countPlural = count: plural"
],
"selectors": [
"countPlural"
],
"match": {
"countPlural=one": "{countLabel} msg",
"countPlural=other": "{countLabel} msgs"
}
}
],
"trash_deleted_ago": "deleted {time}",
"trash_restore_session": "Restore session",
"trash_restore": "Restore",
Expand Down
Loading