feat: Claude Code Monitor — lanes, pipelines and a merged workspace

Internal SmartGift build of a Claude Code monitoring dashboard.

Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.

Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.

Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.
This commit is contained in:
2026-07-29 17:07:45 +07:00
commit 57dc91585d
783 changed files with 221743 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"title": "Activity Feed",
"subtitle": "Real-time stream of all agent events",
"paused": "(paused - {{count}} buffered)",
"resume": "Resume",
"pause": "Pause",
"noActivity": "No activity yet",
"noActivityDesc": "Events will stream here in real-time as Claude Code agents work.",
"viewSession": "Session"
}
+80
View File
@@ -0,0 +1,80 @@
{
"title": "Alerts",
"subtitle": "Rules-based alerting for sessions, agents, events, and token usage",
"refresh": "Refresh",
"ackAll": "Acknowledge all ({{count}})",
"ruleTypes": {
"event_pattern": "Event pattern",
"inactivity": "Inactivity",
"status_duration": "Stuck agent",
"token_threshold": "Token threshold"
},
"ruleTypeHints": {
"event_pattern": "Fires when an ingested event matches the pattern. Set a count above 1 to require N matching events within a time window (e.g. more than 5 errors in 2 minutes).",
"inactivity": "Fires when an active session has received no events for the configured number of minutes.",
"status_duration": "Fires when an agent has remained in the selected status with no activity for the configured number of minutes.",
"token_threshold": "Fires when a session's total token usage (input + output + cache) exceeds the threshold."
},
"ruleDesc": {
"eventPattern": "Matches {{pattern}}",
"eventPatternCount": "≥{{count}} × {{pattern}} within {{window}} min",
"inactivity": "No session activity for {{minutes}} min",
"statusDuration": "Agent stuck in {{status}} for {{minutes}} min",
"tokenThreshold": "Session tokens exceed {{tokens}}"
},
"rules": {
"title": "Alert rules",
"add": "Add rule",
"cancel": "Cancel",
"create": "Create rule",
"saving": "Saving…",
"empty": "No alert rules yet. Add one to start monitoring for stuck agents, error bursts, idle sessions, or token spikes.",
"enabled": "Enabled",
"disabled": "Disabled",
"enable": "Enable rule",
"disable": "Disable rule",
"delete": "Delete rule",
"confirmDelete": "Delete rule \"{{name}}\" and its alert history?",
"cooldown": "{{seconds}}s cooldown",
"form": {
"name": "Rule name",
"namePlaceholder": "e.g. Error burst",
"type": "Rule type",
"eventType": "Event type (exact)",
"toolName": "Tool name (exact)",
"summaryContains": "Summary contains",
"count": "Trigger count",
"windowMinutes": "Window (minutes)",
"agentStatus": "Agent status",
"minutes": "Minutes",
"totalTokens": "Total tokens",
"cooldown": "Cooldown (seconds)"
},
"deleteTitle": "Delete alert rule?",
"help": {
"name": "A label for this rule. Shows in the alert feed and is included in webhook payloads (rule_name). e.g. 'Repeated Bash errors'.",
"type": "What this rule watches. event_pattern matches the live event stream; inactivity = an active session goes quiet; status_duration = an agent is stuck in a state; token_threshold = a session's token usage crosses a limit.",
"eventType": "The Claude Code hook event to match. Leave blank to match any event type. Matched exactly (case-sensitive).",
"toolName": "The tool the agent invoked (on PreToolUse / PostToolUse events). Leave blank to match any tool. Matched exactly.",
"summaryContains": "Case-insensitive substring match against the event's summary text. Useful for catching errors or specific phrases. Leave blank to skip.",
"count": "How many matching events must occur before the alert fires. 1 = fire on the first match. Set above 1 to detect bursts (e.g. repeated errors).",
"window": "The rolling look-back window for the count. e.g. count 5 + window 2 means '5 matching events within any 2-minute span'.",
"status": "Which agent state to watch. 'working' catches agents stuck mid-task; 'waiting' catches agents blocked on input/permission.",
"minutesInactivity": "Fire when an active session has had no events for this many minutes (a stalled or forgotten session).",
"minutesStatus": "Fire when an agent stays in the selected status with no activity for this many minutes (a stuck agent).",
"totalTokens": "Fire when a session's cumulative tokens (input + output + cache read + cache write) cross this number. e.g. 1000000 = 1M tokens.",
"cooldown": "Minimum seconds between repeat alerts for the same rule + session + agent. Prevents noisy duplicates. Default 300 (5 min); 0 = no cooldown."
}
},
"feed": {
"title": "Alert feed",
"unackedCount": "{{count}} unacknowledged",
"unackedOnly": "Unacknowledged only",
"ack": "Acknowledge",
"viewSession": "View session",
"loadMore": "Load more ({{shown}} of {{total}})",
"emptyTitle": "No alerts",
"emptyDescription": "Alerts fired by your rules will appear here in real time.",
"emptyUnacked": "Everything is acknowledged. New alerts will appear here as they fire."
}
}
+54
View File
@@ -0,0 +1,54 @@
{
"title": "Analytics",
"subtitle": "Real-time monitoring and analytics for Claude Code sessions",
"export": "Export",
"totalSessions": "Total Sessions",
"totalAgents": "Total Agents",
"totalTokens": "Total Tokens",
"totalCost": "Total Cost",
"totalEvents": "Total Events",
"cacheHitRate": "% cache hit rate",
"perSession": " per session",
"noDataCost": "No data",
"eventCountLabel_one": "{{count}} event",
"eventCountLabel_other": "{{count}} events",
"tabs": {
"tokenAnalytics": "Token Analytics",
"costAnalytics": "Cost Analytics",
"workflowIntelligence": "Workflow Intelligence",
"productivityAnalytics": "Productivity Analytics"
},
"eventActivity": "Event Activity - Last 52 Weeks",
"last30Days": "Last 30 Days",
"dailyEventCount": "Daily event count",
"peakDay": "Peak day",
"total30d": "Total (30d)",
"tokenDistribution": "Token Distribution",
"tokenMix": "Token Mix",
"cacheEfficiency": "Cache efficiency",
"tokenBreakdown": "Token Breakdown",
"tokenInfo": "Token data captured from Claude Code Stop events.",
"costByModel": "Cost by Model",
"dailyCostTrends": "Daily Cost Trends",
"costByWeekday": "Cost by Weekday",
"costPerDay": "Cost per day",
"peakCostDay": "Peak cost day",
"totalCost30d": "Total cost (30d)",
"noDailyCostData": "No daily cost data yet.",
"noCostData": "No cost data yet.",
"subagentTypes": "Subagent Types",
"noSubagentData": "No subagent data yet.",
"agentStatus": "Agent Status",
"totalAgentsLabel": "Total agents",
"eventTypes": "Event Types",
"noEventData": "No event data yet.",
"toolUsage": "Tool Usage",
"noToolData": "No tool usage data yet.",
"sessionOutcomes": "Session Outcomes",
"totalSessionsLabel": "Total sessions",
"dailySessionTrends": "Daily Session Trends",
"noSessionTrendData": "No session trend data yet.",
"last7Days": "Last 7 days",
"less": "Less",
"more": "More"
}
+264
View File
@@ -0,0 +1,264 @@
{
"title": "Claude Config Explorer",
"subtitle": "Your Claude Code setup at a glance - plugins, skills, subagents, MCP servers, hooks, and settings.",
"refresh": "Refresh",
"refreshing": "Refreshing…",
"lastUpdated": "Last updated {{time}}",
"loadError": "Failed to load: {{message}}",
"scope": {
"all": "All scopes",
"user": "User",
"project": "Project",
"projectLocal": "Project (local)",
"home": "Home"
},
"tabs": {
"overview": "Overview",
"skills": "Skills",
"agents": "Subagents",
"commands": "Slash commands",
"outputStyles": "Output styles",
"plugins": "Plugins",
"marketplaces": "Marketplaces",
"mcp": "MCP servers",
"hooks": "Hooks",
"keybindings": "Keybindings",
"settings": "Settings",
"memory": "Memory"
},
"overview": {
"rootsTitle": "Roots",
"claudeHome": "Claude home",
"projectClaudeDir": "Project .claude",
"projectRoot": "Project root",
"claudeJson": "claude.json",
"summary": "Quick summary",
"user": "user",
"project": "project",
"items": "items"
},
"common": {
"search": "Search by name…",
"clearSearch": "Clear search",
"empty": "Nothing here yet.",
"viewSource": "View source",
"close": "Close",
"copyPath": "Copy path",
"copied": "Copied",
"truncated": "(truncated for preview)",
"size": "Size",
"modified": "Modified",
"scopeLabel": "Scope",
"noFrontmatter": "No frontmatter",
"redactedNotice": "Values matching /token|secret|password|key|auth/i are redacted server-side."
},
"skills": {
"name": "Name",
"description": "Description"
},
"agents": {
"name": "Name",
"model": "Model",
"tools": "Tools"
},
"plugins": {
"manifest": "Manifest",
"marketplace": "Marketplace",
"version": "Version",
"installedAt": "Installed",
"lastUpdated": "Updated",
"installPath": "Install path",
"missing": "Install path missing",
"manifestMissing": "No installed_plugins.json found at {{path}}",
"enabled": "Enabled",
"disabled": "Disabled",
"contributes": "Contributes",
"skills_one": "{{count}} skill",
"skills_other": "{{count}} skills",
"agents_one": "{{count}} agent",
"agents_other": "{{count}} agents",
"commands_one": "{{count}} command",
"commands_other": "{{count}} commands",
"outputStyles_one": "{{count}} output style",
"outputStyles_other": "{{count}} output styles",
"hooks_one": "{{count}} hook script",
"hooks_other": "{{count}} hook scripts",
"author": "Author",
"homepage": "Homepage",
"license": "License",
"description": "Description"
},
"marketplaces": {
"manifest": "Known marketplaces manifest",
"noMarketplaces": "No marketplaces registered.",
"source": "Source",
"lastUpdated": "Last synced",
"pluginCount": "Plugins",
"owner": "Owner",
"installLocation": "Install path",
"addCmd": "claude plugin marketplace add <repo>"
},
"keybindings": {
"file": "Source file",
"missing": "No keybindings.json found at {{path}}",
"context": "Context",
"key": "Key",
"action": "Action",
"docsLink": "View keybindings docs",
"contextPlaceholder": "Context (e.g. Global, Chat)",
"addContext": "Add context",
"removeContext": "Remove context",
"addBinding": "Add binding",
"removeBinding": "Remove binding",
"errContext": "Every context needs a name.",
"errDupContext": "Duplicate context: {{context}}",
"errEmpty": "Every binding in \"{{context}}\" needs both a key and an action.",
"errDupKey": "Duplicate key \"{{key}}\" in context \"{{context}}\"."
},
"statusline": {
"title": "Statusline",
"configured": "Configured statusline command",
"scripts": "Statusline scripts found in CLAUDE_HOME",
"noStatusline": "No statusline configured."
},
"hookScripts": {
"title": "~/.claude/hooks/ scripts",
"subtitle": "Helper scripts referenced by your hook commands. These run when settings.json `hooks.<event>.hooks[].command` invokes them.",
"empty": "No scripts in ~/.claude/hooks/."
},
"mcp": {
"userScope": "User-scoped servers",
"projectScope": "Project-scoped servers",
"command": "Command",
"args": "Args",
"env": "Env names",
"url": "URL",
"headers": "Header names",
"kind": "Kind",
"source": "Source",
"noServers": "No MCP servers found."
},
"hooks": {
"noHooks": "No hooks configured.",
"matcher": "Matcher",
"command": "Command",
"type": "Type",
"timeout": "Timeout",
"fileMissing": "(no settings file at this scope)"
},
"settings": {
"fileMissing": "(no settings file at this scope)"
},
"memory": {
"userScope": "User memory",
"projectScope": "Project memory",
"missing": "No CLAUDE.md found.",
"autoTitle": "Project memory store",
"autoSubtitle": "Per-project file-based memory under ~/.claude/projects/<project>/memory/ — a MEMORY.md index plus one file per remembered fact. Read-only here.",
"noMatches": "No memory files match your search.",
"indexFiles": "Index",
"jumpTo": "Jump to file",
"fileCount_one": "{{count}} file",
"fileCount_other": "{{count}} files",
"factFiles_one": "{{count}} fact",
"factFiles_other": "{{count}} facts",
"newFile": "New file",
"newFileTitle": "New memory file in {{project}}",
"namePlaceholder": "e.g. my_fact.md",
"nameHelp": "Filename ending in .md (.md is added if you omit it).",
"projectLabel": "Project",
"projectHelp": "Created in this project's memory dir."
},
"edit": {
"newButton": "New",
"editButton": "Edit",
"deleteButton": "Delete",
"save": "Save",
"cancel": "Cancel",
"saving": "Saving…",
"deleting": "Deleting…",
"newTitle": "Create new {{type}}",
"editTitle": "Edit {{name}}",
"namePlaceholder": "name (kebab-case, no spaces)",
"nameLabel": "Name",
"nameHelp": "Letters, digits, dot, dash, underscore. Max 64 chars.",
"contentLabel": "Content",
"scopePicker": "Scope",
"writeError": "Save failed: {{message}}",
"deleteError": "Delete failed: {{message}}",
"saveSuccess": "Saved · backup at {{path}}",
"saveSuccessNew": "Created.",
"deleteSuccess": "Deleted · backup at {{path}}",
"confirmDelete": "Delete this item?",
"confirmDeleteBody": "This will move the file (or skill folder, including bundled assets) to a timestamped backup before removing it. The backup lives outside the directories Claude Code scans, so the entry will disappear from your CLI.",
"confirmDeletePath": "Path: {{path}}",
"confirmDeleteAction": "Yes, back up and delete",
"templates": {
"skills": "---\nname: my-skill\ndescription: One-line description (shown when Claude picks the skill)\n---\n\nBody - what the skill does, when to use it, examples.\n",
"agents": "---\nname: my-agent\ndescription: When to invoke this subagent\ntools: Read, Grep\nmodel: sonnet\n---\n\nSystem prompt for the subagent.\n",
"commands": "---\ndescription: One-line description shown in the slash menu\n---\n\nWhat /my-command does.\n",
"output-styles": "---\nname: my-style\ndescription: Output style description\n---\n\nStyle instructions.\n",
"memory": "# Project memory\n\nClaude reads this on session start.\n",
"auto-memory": "---\nname: my-fact\ndescription: One-line summary of the remembered fact\nmetadata:\n type: feedback\n---\n\nThe fact to remember.\n"
}
},
"backups": {
"title": "Backups",
"empty": "No backups yet - every edit or delete creates a timestamped backup that lands here.",
"viewLink": "Show backup history",
"openButton": "Backups",
"subtitle": "Every save / delete in the editor writes a copy here first. Backup folders live outside the directories Claude Code scans, so they don't reappear as ghosts in your CLI.",
"restoreHint": "Restore by renaming the backup back into place:",
"size": "Size",
"created": "Created",
"type": "Type",
"scopeLabel": "Scope",
"filterAll": "All types"
},
"explain": {
"hooks": {
"title": "Hooks are read-only here on purpose",
"body": "Hooks live in the `hooks` block of `settings.json` files that Claude Code writes to constantly. Editing them from the dashboard would race with the live CLI and could silently break the dashboard's own ingestion (the `hook-handler.js` entry below).",
"howTo": "Edit them yourself with one of:",
"cmd1": "claude config /hooks",
"cmd1Note": "Interactive hook editor inside Claude Code",
"cmd2": "$EDITOR ~/.claude/settings.json",
"cmd2Note": "Hand-edit the user-level hooks block",
"cmd3": "$EDITOR .claude/settings.json",
"cmd3Note": "Hand-edit the project-level hooks block"
},
"settings": {
"title": "Settings are read-only here on purpose",
"body": "These JSON files are rewritten by the live `claude` CLI on every model change, theme toggle, plugin enable, etc. A dashboard write would race with the CLI and lose state.",
"howTo": "Edit settings via Claude Code itself:",
"cmd1": "claude config set <key> <value>",
"cmd1Note": "Set an individual key safely",
"cmd2": "/config",
"cmd2Note": "Open the interactive config UI inside the CLI",
"cmd3": "$EDITOR ~/.claude/settings.json",
"cmd3Note": "Hand-edit (only when no `claude` process is running)"
},
"plugins": {
"title": "Plugins are managed by the CLI",
"body": "Plugins are bundles with their own registry - `installed_plugins.json` plus install paths under `plugins/cache/`. The dashboard reads them but defers install/uninstall to `claude plugin …` so the registry stays consistent.",
"install": "Install a plugin:",
"installCmd": "claude plugin install <marketplace>/<plugin>",
"uninstall": "Uninstall this plugin:",
"uninstallButton": "Copy uninstall command"
},
"mcp": {
"title": "MCP servers are managed by the CLI",
"body": "MCP server config lives inside `~/.claude.json`, the same file the live CLI writes to constantly. Concurrent writes from the dashboard would corrupt project state, so add/remove flow goes through Claude Code itself.",
"list": "List configured servers:",
"listCmd": "claude mcp list",
"add": "Add a server:",
"addCmd": "claude mcp add <name> <command> [args…]",
"remove": "Remove this server:",
"removeButton": "Copy remove command"
}
},
"snippet": {
"copy": "Copy",
"copied": "Copied"
}
}
+192
View File
@@ -0,0 +1,192 @@
{
"refresh": "Refresh",
"retry": "Retry",
"cancel": "Cancel",
"export": "Export",
"loading": "Loading...",
"noData": "No data",
"total": "Total",
"active": "active",
"total_lower": "total",
"subagent": "subagent",
"subagents": "subagents",
"subagent_label_one": "{{count}} subagent",
"subagent_label_other": "{{count}} subagents",
"events": "events",
"event": "event",
"sessions": "sessions",
"session": "session",
"agents": "agents",
"agent": "agent",
"live": "Live",
"offline": "Offline",
"running": "running",
"dashboardRun": "Run",
"days": "days",
"hours": "hours",
"updated": "Updated ",
"lastUpdated": "Last updated: ",
"showMore": "Show more ({{count}} remaining)",
"plusMore": "+{{count}} more",
"ofSessions": "% of sessions",
"save": "Save",
"edit": "Edit",
"delete": "Delete",
"actions": "Actions",
"close": "Close",
"unexpectedError": "Unexpected error",
"depth": "Depth",
"type": "Type",
"statusLabel": "Status",
"status": {
"working": "Working",
"waiting": "Waiting",
"completed": "Completed",
"error": "Error",
"active": "Active",
"abandoned": "Abandoned"
},
"awaitingReason": {
"notification": {
"label": "Needs input",
"desc": "Blocked on a permission prompt or an input request — Claude can't continue until you respond."
},
"stop": {
"label": "Turn done",
"desc": "Claude finished its reply; the session is idle until you send the next prompt."
},
"session_start": {
"label": "At prompt",
"desc": "The session just started or resumed and is sitting at an empty prompt — nothing has been asked yet."
},
"interrupted": {
"label": "Interrupted",
"desc": "The last turn was interrupted (Esc or a recovered hook) — Claude is waiting for direction."
}
},
"time": {
"justNow": "just now",
"mAgo": "{{count}}m ago",
"hAgo": "{{count}}h ago",
"dAgo": "{{count}}d ago"
},
"pagination": {
"previous": "Previous",
"next": "Next",
"showing": "Showing {{from}}-{{to}} of {{total}}"
},
"token": {
"input": "Input",
"output": "Output",
"cacheRead": "Cache Read",
"cacheWrite": "Cache Write",
"totalTokens": "Total tokens"
},
"cost": {
"model": "Model",
"cost": "Cost",
"totalCost": "Total Cost",
"totalEstimatedCost": "Total Estimated Cost"
},
"duration": {
"h_m": "{{h}}h {{m}}m",
"m_s": "{{m}}m {{s}}s",
"s": "{{s}}s"
},
"eventDetail": {
"summary": "Summary",
"seeDetailsBelow": "Check below for full details in {{fields}}",
"eventId": "Event ID",
"recordedAt": "Recorded at",
"session": "Session",
"sessionId": "Session ID",
"agentId": "Agent ID",
"agent": "Agent",
"cwd": "Working directory",
"permissionMode": "Permission mode",
"toolUseId": "Tool Use ID",
"toolName": "Tool",
"toolInput": "Tool Input",
"toolResponse": "Tool Response",
"isError": "Error",
"transcriptPath": "Transcript Path",
"agentTranscriptPath": "Subagent Transcript Path",
"hookEventName": "Hook Event Name",
"stopReason": "Stop Reason",
"stopHookActive": "Stop Hook Active",
"subagentType": "Subagent Type",
"agentType": "Agent Type",
"notificationType": "Notification Type",
"message": "Message",
"prompt": "Prompt",
"model": "Model",
"reason": "Reason",
"source": "Source",
"imported": "Imported",
"type": "Type",
"timestamp": "Timestamp",
"uuid": "UUID",
"durationMs": "Duration (ms)",
"compactionNumber": "Compaction Number",
"totalCompactions": "Total Compactions",
"lastAssistantMessage": "Last Assistant Message",
"rawPayload": "Raw Payload",
"copy": "Copy",
"copied": "Copied",
"noPayload": "No payload captured for this event.",
"viewDetails": "View details",
"expand": "Expand event",
"collapse": "Collapse event"
},
"eventFilters": {
"searchPlaceholder": "Search summary, tool, payload...",
"status": "Status",
"eventType": "Event type",
"toolName": "Tool",
"agentId": "Agent",
"sessionId": "Session",
"from": "From",
"to": "To",
"clearAll": "Clear filters",
"noOptions": "No options",
"showing": "Showing {{shown}} of {{total}}",
"loadMore": "Load more",
"loading": "Loading...",
"noResults": "No events match the current filters",
"grouped": "Group by tool call",
"flat": "Flat list",
"groupEventCount_one": "{{count}} event",
"groupEventCount_other": "{{count}} events",
"help": {
"toggle": "Help",
"title": "About events, filters, and grouping",
"subtitle": "Unlock deeper insights: badges, lifecycles, and filter mechanics explained.",
"valuesTitle": "What each filter accepts",
"valueStatusDesc": "Preset shortcut that expands to event_type values (Working → PreToolUse, Completed → Stop/SubagentStop/Compaction, ...).",
"valueEventTypeDesc": "Raw event_type strings from the DB. Pulled from /api/events/facets.",
"valueToolNameDesc": "tool_name values currently in the DB (Bash, Edit, Read, Grep, mcp__... tools). Pulled from /api/events/facets.",
"valueAgentIdDesc": "Full agent UUIDs (main + subagents). Select one or more to scope to specific agents.",
"valueSessionIdDesc": "Session UUIDs. Typically you'd navigate to /sessions/:id instead, but this lets you intersect multiple sessions.",
"valueSearchDesc": "Substring match on summary, tool_name, and the raw JSON payload. Debounced 300ms.",
"valueDateRangeDesc": "ISO datetime lower/upper bounds on the event's created_at.",
"statusesTitle": "Status badges",
"statusesIntro": "Status is derived from event_type. It's what you see on each row.",
"statusWorkingDesc": "Agent started a tool call (PreToolUse). The tool is about to run.",
"statusConnectedDesc": "Tool call completed and returned a result (PostToolUse).",
"statusCompletedDesc": "Turn or lifecycle boundary (Stop, SubagentStop, Compaction).",
"statusErrorDesc": "An error was recorded (error, APIError).",
"statusIdleDesc": "Lifecycle or metadata (Notification, TurnDuration, SessionStart, SessionEnd).",
"lifecycleTitle": "Event lifecycle",
"lifecycleDesc": "A typical tool call emits two events sharing the same tool_use_id:",
"lifecycleFlow": "PreToolUse (Working) → PostToolUse (Connected) → ... → Stop (Completed)",
"filtersTitle": "How filters work",
"filterTip1": "Filters compose with AND across categories. Within one category, multi-select is OR.",
"filterTip2": "Status is a shortcut that expands to event_type values (Working → PreToolUse, Completed → Stop/SubagentStop/Compaction, ...). Status + Event type compose as OR on event_type.",
"filterTipGrouping": "Grouping tip: a grouped row needs both Pre and Post events. If you filter by Status, pick Working + Connected together to keep pairs intact - otherwise a group will only show half of the call.",
"filterTip3": "Text search matches summary, tool_name, and the raw payload (data column).",
"filterTip4": "Date range applies to each event's created_at."
}
},
"examples": "Examples",
"help": "Help"
}
+22
View File
@@ -0,0 +1,22 @@
{
"title": "Dashboard",
"subtitle": "Real-time overview of Claude Code agent activity",
"totalSessions": "Total Sessions",
"activeAgents": "Active Agents",
"activeSubagents": "Active Subagents",
"eventsToday": "Events Today",
"totalEvents": "Total Events",
"totalCost": "Total Cost",
"viewBoard": "View Board",
"viewAll": "View All",
"activeAgentsSection": "Active Agents",
"recentActivity": "Recent Activity",
"noAgents": "No active agents",
"noAgentsDesc": "Agents will appear here when a Claude Code session is running.",
"noActivity": "No activity yet",
"noActivityDesc": "Events from Claude Code sessions will stream here in real-time.",
"failedConnect": "Failed to connect to server",
"failedLoad": "Failed to load data",
"activeTrend": " active",
"totalTrend": " in active sessions"
}
+31
View File
@@ -0,0 +1,31 @@
{
"notFound": {
"code": "404",
"title": "Page not found",
"description": "The route you requested does not exist. Use navigation to return to a valid page.",
"goDashboard": "Go to Dashboard",
"goBack": "Go Back"
},
"notifications": {
"newSession": "New Session",
"sessionDefault": "Session ",
"sessionError": "Session Error",
"subagentSpawned": "Subagent Spawned",
"finishedResponding": "Claude Finished Responding",
"readyForInput": "Ready for input",
"sessionCompleted": "Session Completed",
"sessionClosed": "Session closed",
"defaultTitle": "Claude Code",
"defaultBody": "Notification"
},
"toolLegend": {
"read": "Read",
"write": "Write",
"edit": "Edit",
"bash": "Bash",
"grep": "Grep",
"glob": "Glob",
"agent": "Agent",
"other": "Other"
}
}
+45
View File
@@ -0,0 +1,45 @@
{
"title": "Kanban Board",
"subtitle": "Kanban view of all agents by status",
"subtitleSessions": "Kanban view of all sessions by status",
"viewToggle": {
"agents": "Agents",
"sessions": "Sessions"
},
"noAgents": "No agents tracked yet",
"noAgentsDesc": "Start a Claude Code session with hooks installed to see agents appear here.",
"agentCount": "{{count}} agent tracked",
"agentCount_plural": "{{count}} agents tracked",
"noAgentsInColumn": "No agents",
"noSessions": "No sessions tracked yet",
"noSessionsDesc": "Start a Claude Code session with hooks installed to see sessions appear here.",
"sessionCount": "{{count}} session tracked",
"sessionCount_plural": "{{count}} sessions tracked",
"noSessionsInColumn": "No sessions",
"ran": "ran ",
"running": "running ",
"session": {
"anonymous": "Untitled session",
"agentSummary_one": "{{count}} agent",
"agentSummary_other": "{{count}} agents",
"subagentSummary_one": "{{count}} subagent",
"subagentSummary_other": "{{count}} subagents",
"turnSummary_one": "{{count}} turn",
"turnSummary_other": "{{count}} turns"
},
"tooltip": {
"agent": {
"working": "Agent is actively running a tool call right now.\n\nEntered on PreToolUse or UserPromptSubmit, exits on Stop (turn finished).",
"waiting": "Agent finished its turn and is blocked on the human - either Claude is waiting for the next user message or has prompted for permission to use a tool.\n\nCleared on the next PreToolUse / PostToolUse, or when the session ends.",
"completed": "Agent has fully ended for this session - typically because SessionEnd fired or, for subagents, SubagentStop was processed.\n\nNo further activity will be recorded against this agent.",
"error": "Agent recorded an error and will not continue. For main agents this comes from a Stop with stop_reason=error; for subagents, from a failed run."
},
"session": {
"active": "Session is mid-turn - Claude is currently running and the user isn't blocking anything. Brief by nature: a session moves through Active during tool calls and back to Waiting at end of turn.",
"waiting": "Session is sitting on the user. Either Claude finished its turn (most common) or it has surfaced a permission prompt and is blocked until the human responds.\n\nLook here for sessions you owe a reply to.",
"completed": "Session has fully closed - SessionEnd fired (CLI exited cleanly) or the user explicitly closed it.\n\nAll agents on this session are also completed.",
"error": "Session ended with an error - Claude returned stop_reason=error, an unrecoverable failure occurred, or an upstream API error terminated the run.",
"abandoned": "Session went stale without a clean SessionEnd. Marked abandoned after 5+ minutes of no activity (orphaned by /resume, network drop, or the CLI being killed). Distinct from Completed: we never saw a real exit signal."
}
}
}
+74
View File
@@ -0,0 +1,74 @@
{
"action.clear": "clear",
"action.forget": "forget lane",
"action.purge": "purge history",
"action.remove": "remove",
"action.reset": "reset worktree",
"action.start": "start",
"action.stop": "stop",
"actionError": "Lane action failed: {{message}}",
"actionErrorUnknown": "Unknown error",
"add": "Add lane",
"addLane": "Create a lane from a working directory",
"addLaneBaseLabel": "Branch to fork from",
"addLaneNoBranches": "This repo has no commits yet — the worktree will start empty.",
"addLaneNotARepo": "Not a git repository (or no read access) yet.",
"addLaneRepoHint": "An existing git repo. The dashboard creates a new worktree for the lane, not a folder you pick.",
"addLaneRepoLabel": "Source repository",
"addLaneTitleLabel": "Title",
"addLaneTitlePlaceholder": "Optional",
"autoStage": "auto: {{stage}}",
"cardId": "Lane {{id}}",
"confirmRemoveCancel": "Cancel",
"confirmRemoveConfirm": "Remove",
"confirmRemoveMessage": "This action cannot be undone.",
"confirmRemoveTitle": "Remove lane?",
"countDead": "dead",
"countNeedsYou": "need you",
"countRunning": "running",
"countTotal": "lanes",
"destructive.blocked.adopted": "This is an adopted directory and cannot be changed by a worktree action.",
"destructive.blocked.missing": "The lane directory is missing, so this action cannot continue.",
"destructive.blocked.unreadable": "The lane directory cannot be read as a Git worktree, so this action cannot continue.",
"destructive.cancel": "Cancel",
"destructive.count.bytesEstimate": "Estimated space freed",
"destructive.count.dirty": "Modified files",
"destructive.count.events": "Events",
"destructive.count.head": "HEAD",
"destructive.count.sessions": "Sessions",
"destructive.count.tokenRows": "Token rows",
"destructive.count.unpushed": "Unpushed commits",
"destructive.count.untracked": "Untracked files",
"destructive.force": "I understand these unpushed commits will be discarded.",
"destructive.loading": "Loading current facts…",
"destructive.notice.activeSessionSkipped": "One or more sessions in this lane are still active and will be kept, not purged.",
"destructive.notice.adopted": "This lane points at a directory you own. Only the dashboard's record of it is dropped — the directory and its files are left untouched.",
"destructive.notice.missing": "The lane directory is already gone. Removing it drops the dashboard's record and clears Git's stale worktree entry; nothing is deleted from disk.",
"destructive.notice.unreadable": "The lane directory cannot be read as a Git worktree. Removal is attempted; if Git itself refuses, its worktree record is cleared directly instead. Either way, the directory itself is never touched.",
"destructive.purge.confirm": "Purge history",
"destructive.purge.message": "Approve the current counts before deleting stored session history.",
"destructive.purge.title": "Purge lane history?",
"destructive.remove.confirm": "Remove lane",
"destructive.remove.message": "Approve the current counts before this action.",
"destructive.remove.title": "Remove lane?",
"destructive.reset.confirm": "Reset worktree",
"destructive.reset.message": "Approve the current counts before resetting this worktree.",
"destructive.reset.survives": "Gitignored files such as node_modules and .env are kept; untracked files are deleted.",
"destructive.reset.title": "Reset managed worktree?",
"destructive.warning.no-remote": "No Git remote is configured, so nothing here is backed up remotely. You can still proceed.",
"emptyState": "No lanes yet. Create one from a working directory:",
"git.uncommitted": "{{dirty}} modified · {{untracked}} untracked",
"kind.adopted": "adopted",
"kind.managed": "managed",
"laneHeader": "Lane {{id}} · {{title}} · {{pipeline}}",
"moreActions": "More actions",
"preflightError": "Could not load the current lane facts.",
"preflightErrorWithMessage": "Could not load the current lane facts: {{message}}",
"status.failed": "failed",
"status.idle": "idle",
"status.provisioning": "provisioning",
"status.running": "running",
"statusDead": "DEAD",
"title": "Lanes",
"tooltipStart": "Spawn a conversation-mode run with no initial prompt; driven from CLI or via message"
}
+63
View File
@@ -0,0 +1,63 @@
{
"activityFeed": "Activity Feed",
"agentBoard": "Kanban Board",
"analytics": "Analytics",
"avg": "avg",
"brand": "Agent Dashboard",
"brandSub": "Claude Code Monitor",
"ccConfig": "Claude Config",
"checkFailed": "Update check failed",
"checkForUpdates": "Check for updates",
"checkingForUpdates": "Checking for updates...",
"close": "Close",
"collapse": "Collapse sidebar",
"collapseShort": "Collapse",
"connection": "Connection",
"connectionDetails": "Connection details",
"connectionUptime": "Connected",
"dashboard": "Dashboard",
"daysAgo": "{{count}}d ago",
"disconnected": "Disconnected",
"eventsLastMin": "Last 60s",
"eventsReceived": "Events received",
"eventsTotal": "Total",
"expand": "Expand sidebar",
"hoursAgo": "{{count}}h ago",
"justNow": "just now",
"language": "Language",
"languageNames": {
"en": "English",
"vi": "Vietnamese"
},
"languageShort": {
"en": "EN",
"vi": "VI"
},
"lastEvent": "Last event",
"live": "Live",
"minutesAgo": "{{count}}m ago",
"noEventsYet": "No events yet",
"notConnected": "Not connected",
"notFound": "Not found",
"peakRate": "Peak",
"recentActivity": "Recent activity",
"resetStats": "Reset",
"scrollDown": "Scroll navigation down",
"scrollUp": "Scroll navigation up",
"secondsAgo": "{{count}}s ago",
"sessions": "Sessions",
"settings": "Settings",
"skipToContent": "Skip to content",
"statsPersisted": "Stats persist across reloads",
"switchLanguage": "Switch to {{language}}",
"throughput60s": "Throughput · last 60s",
"topEventTypes": "Top event types",
"unitEvents": "events",
"unitPerSec": "events/s",
"upToDate": "Up to date",
"updateAvailable": "Update available",
"website": "Website",
"workflows": "Workflows",
"workspace": "Workspace",
"wsEndpoint": "WebSocket"
}
+153
View File
@@ -0,0 +1,153 @@
{
"actions": {
"newRun": "New run",
"send": "Send",
"sending": "Sending…",
"start": "Run",
"starting": "Starting…",
"stop": "Stop",
"stopping": "Stopping…",
"viewSession": "View session"
},
"autocomplete": {
"fileHint": "Type @ to reference a file",
"groupBuiltin": "Built-in (CLI only - won't run from here)",
"groupFiles": "Files in cwd",
"groupProject": "Project commands",
"groupUser": "User commands",
"noMatches": "No matches",
"slashHint": "Type / for slash commands"
},
"binary": {
"found": "Using {{path}}",
"missing": "The `claude` CLI isn't on your PATH. Install Claude Code or set PATH so the dashboard can spawn it."
},
"concurrency": {
"active_one": "{{count}} run already in flight",
"active_other": "{{count}} runs already in flight",
"atCap": "Concurrency cap reached ({{max}}). Stop one of the running runs to start a new one.",
"viewActive": "View active runs"
},
"empty": {
"body": "Type a prompt and click Run. Output streams here as the model thinks, calls tools, and answers.",
"title": "Nothing yet"
},
"errors": {
"attachFailed": "Couldn't attach to run: {{message}}",
"cwdRequired": "Working directory required to start a run",
"killFailed": "Couldn't stop: {{message}}",
"laneCreateFailed": "Failed to create lane: {{message}}",
"noLaneSelected": "No lane selected or could not create one",
"noRunIdReturned": "No run_id returned from lane start",
"runStartedButNotAttached": "Run is live but couldn't attach to console: {{message}}",
"sendFailed": "Couldn't send: {{message}}",
"startFailed": "Couldn't start run: {{message}}"
},
"events": {
"claude": "Claude",
"collapse": "Collapse",
"expand": "Expand",
"system": "System",
"thinking": "Thinking",
"tool": "Tool",
"toolResult": "Tool result",
"you": "You"
},
"fields": {
"cwd": "Working directory",
"cwdGroups": {
"dashboard": "Dashboard server",
"home": "Home",
"recent": "Recent - used by Claude Code"
},
"cwdHint": "Absolute path. Defaults to the dashboard's own cwd.",
"cwdNoMatches": "No matches. Type an absolute path to use it directly.",
"cwdPlaceholder": "Type to search or paste an absolute path…",
"effort": "Thinking effort",
"model": "Model",
"modelCustom": "Custom…",
"modelCustomPlaceholder": "model id (e.g. claude-opus-4-7-20260101)",
"modelInheritLabel": "Inherit from settings",
"permissionAcceptEdits": "acceptEdits (recommended)",
"permissionBypass": "bypassPermissions (DANGER - allows everything without asking)",
"permissionDefault": "default (interactive prompts - sessions may hang headlessly)",
"permissionMode": "Permission mode",
"permissionPlan": "plan (read-only planning)",
"prompt": "Prompt",
"promptPlaceholder": "Ask Claude anything…"
},
"footer": {
"cost": "Cost",
"duration": "Duration",
"exitCode": "Exit code",
"sessionId": "Session ID",
"turns": "Turns"
},
"hint": {
"headlessExplain": "Headless mode is best for scripted tasks where you know exactly what you want. The session can't ask follow-up questions and will hang on permission prompts unless you stay in acceptEdits.",
"permissionWarning": "bypassPermissions allows ALL tool invocations without confirming. Only use for trusted prompts.",
"shortcut": "Cmd+Enter / Ctrl+Enter to send"
},
"limitations": {
"dismiss": "Got it"
},
"mode": {
"conversation": "Conversation",
"conversationHint": "Multi-turn - keep typing follow-ups while the agent works.",
"headless": "One-shot",
"headlessHint": "Single prompt, single response. Stdin closes after spawn.",
"label": "Mode"
},
"resume": {
"clear": "Clear selection",
"freshHint": "Start a fresh Claude Code session.",
"freshOption": "New session",
"label": "Source session",
"noSessions": "No sessions found.",
"originalCwd": "Original cwd",
"pickSession": "Pick a session…",
"preview": "Last activity",
"resumeHint": "Pick a session from your history and continue the conversation. Cwd is locked to the original.",
"resumeOption": "Resume existing session",
"search": "Search by ID, cwd, or status…",
"selectedBadge": "Resuming"
},
"runs": {
"allSessionsLink": "See all Claude Code sessions →",
"attached": "Attached to existing run",
"scopeNote": "Only shows runs you started from this dashboard.",
"started": "Started {{when}}",
"switcher": "Active runs",
"switcherEmpty": "No active runs",
"viewActive": "View active run",
"viewActive_other": "{{count}} active runs",
"viewLabel": "View"
},
"status": {
"abandoned": "Abandoned",
"completed": "Completed",
"error": "Error",
"idle": "Idle",
"killed": "Killed",
"running": "Running",
"spawning": "Spawning…"
},
"statusHeader": {
"cwd": "Cwd",
"duration": "Elapsed",
"effort": "Effort",
"envelopes": "Events",
"model": "Model",
"permissionMode": "Mode",
"session": "Session"
},
"subtitle": "Spin up a Claude Code session right inside the dashboard. Live streaming output, multi-turn conversation, and the same hooks-driven analytics as your terminal sessions.",
"title": "Run Claude",
"tokens": {
"cacheRead": "Cache hit",
"cost": "Cost",
"input": "Input",
"label": "Context",
"output": "Output"
}
}
+43
View File
@@ -0,0 +1,43 @@
{
"title": "Sessions",
"searchPlaceholder": "Search sessions...",
"filterAll": "All",
"filterActive": "Active",
"filterWaiting": "Waiting",
"filterCompleted": "Completed",
"filterError": "Error",
"filterAbandoned": "Abandoned",
"sessionCount": "{{count}} session recorded",
"sessionCount_plural": "{{count}} sessions recorded",
"noSessions": "No sessions found",
"noSessionsDesc": "Try adjusting your search or filters.",
"noSessionsHint": "Start a Claude Code session with hooks installed to begin tracking.",
"tableSession": "Session",
"tableStatus": "Status",
"tableLastActive": "Last Active",
"tableDuration": "Duration",
"tableAgents": "Agents",
"tableCost": "Cost",
"tableDirectory": "Directory",
"defaultName": "Session ",
"detail": {
"waitingBanner": {
"title": "Waiting for your input",
"generic": "Claude Code is paused in this session until you respond in the terminal."
},
"failedLoad": "Failed to load session",
"loading": "Loading session...",
"notFound": "Session not found",
"backToSessions": "Back to Sessions",
"agents": "Agents",
"noAgents": "No agents recorded.",
"unparented": "Unparented Subagents",
"costBreakdown": "Cost Breakdown",
"eventTimeline": "Event Timeline",
"noEvents": "No events recorded.",
"conversation": "Conversation",
"timeline": "Timeline ({{shown}}/{{total}})",
"transcriptNotFound": "Conversation transcript not found for this agent. The transcript file may be missing or not yet linked."
},
"remoteSourceBadgeTitle": "Collected from a remote machine"
}
+435
View File
@@ -0,0 +1,435 @@
{
"title": "Settings",
"subtitle": "Manage pricing, notifications, data, and hooks",
"exportData": "Export Data",
"acrossSessions": "Across all tracked sessions",
"basedOnUsage": "Based on per-model token usage",
"tabby": {
"title": "Tabby companion",
"description": "A floating cat that reacts to your live sessions.",
"enable": "Show Tabby",
"enableDesc": "Display the corner companion across the dashboard (⌘B to open)"
},
"pricing": {
"title": "Model Pricing",
"description": "Rates per million tokens (USD). Use % as wildcard in patterns. Some models have a time-limited introductory rate (shown in violet); usage on or before its cutoff date is billed at that rate, and usage after it at the standard rate.",
"introNote": "Intro ${{input}}/${{output}} through {{until}}",
"introRatesTitle": "Introductory rates",
"introRatesHint": "Leave the date empty for no promo",
"introUntil": "Through (date)",
"introUntilInvalid": "Introductory cutoff must be a YYYY-MM-DD date",
"resetConfirm": "Confirm Reset",
"resetDefaults": "Reset Defaults",
"resetResult": "Reset to {{count}} default rules",
"addModel": "Add Model",
"pattern": "Pattern",
"patternPlaceholder": "claude-opus-4%",
"namePlaceholder": "Claude Opus 4",
"validationRequired": "Pattern and display name are required",
"lastUpdated": "Last updated: ",
"tooltip": {
"title": "How model pricing works",
"howItWorks": "How it works",
"howItWorksBody": "When a session reports usage, the dashboard finds the first pricing rule whose pattern matches the model id and multiplies (input tokens / 1M) and (output tokens / 1M) by the rates below to compute cost. Rules are evaluated top-to-bottom - the first match wins.",
"patternsTitle": "Pattern syntax",
"patternsBody": "Patterns are SQL-style globs. % is a wildcard that matches any characters. For example: claude-opus-4-7% matches every model id that starts with claude-opus-4-7 (e.g. claude-opus-4-7, claude-opus-4-7-20260101). claude-%-haiku matches any haiku variant. An exact id like claude-sonnet-4-6 only matches itself.",
"manualUpdates": "You must update prices manually",
"manualUpdatesBody": "Anthropic publishes pricing changes on their website - there is no live feed. When a new model launches or rates change, edit the matching rule (or add a new one above the catch-all) so newly recorded sessions are costed correctly. Already-stored sessions keep the price that was applied at ingest time.",
"apiPricing": "Reference only - API rates",
"apiPricingBody": "These are pay-as-you-go API rates. If you use Claude Code on a subscription plan (Pro, Max, Team, or Enterprise), your actual cost is a flat monthly fee, not per-token - so these figures will usually be higher than what you really pay. Treat the costs here as a usage estimate for reference, not a bill."
},
"cacheWrite5m": "Cache Write (5m)",
"cacheWrite1h": "Cache Write (1h)",
"fastInput": "Fast Input",
"fastOutput": "Fast Output"
},
"claudeHome": {
"title": "CLAUDE_HOME",
"description": "Root directory for Claude Code session data. Changing this updates the scan path for transcripts and imports immediately.",
"save": "Save",
"saving": "Saving...",
"current": "Current:",
"placeholder": "/path/to/claude-home",
"saveFailed": "Failed to update CLAUDE_HOME"
},
"hooks": {
"title": "Hook Configuration",
"description": "Claude Code hooks forward events to the dashboard in real time.",
"allInstalled": "All hooks installed",
"incomplete": "Hooks incomplete",
"reinstall": "Reinstall Hooks",
"success": "Hooks installed successfully",
"failed": "Hook installation failed"
},
"notifications": {
"title": "Notifications",
"description": "Browser notifications for important events. Requires permission.",
"enable": "Enable Browser Notifications",
"granted": "Permission granted",
"blocked": "Permission blocked",
"required": "Permission required",
"notifyWhen": "Notify me when...",
"newSession": "New session starts",
"sessionComplete": "Session completes",
"sessionError": "Session errors",
"subagentSpawned": "Subagent spawned",
"testTitle": "Agent Monitor",
"testBody": "Notifications are working!",
"sendTest": "Send Test Notification",
"disabledInfo": "Notifications are disabled - enable to get alerts for session events"
},
"import": {
"title": "Import History",
"description": "Bring existing Claude Code sessions into the dashboard. Token counts, per-model cost, compactions, subagents, tool uses, and turn durations are reconstructed from the original JSONL transcripts - identical to how live sessions are captured.",
"accuracyNote": "Re-running is safe. Sessions are deduplicated by session ID, and compaction baselines ensure token totals never double-count.",
"supportedFiles": "Supported inputs: .jsonl, .meta.json, .zip, .tar, .tar.gz, .tgz, .gz",
"instructions": "How to gather your history",
"stepLocate": "1. Locate your Claude Code history",
"stepLocateBody": "Every Claude Code session is stored as a JSONL transcript under the projects folder. Each subfolder is named after the working directory where the session started (slashes replaced with dashes).",
"stepArchive": "2. Bundle it for transfer (optional)",
"stepArchiveBody": "To move history from another machine, archive the whole folder first, then copy it over (AirDrop, scp, USB, cloud storage):",
"stepChoose": "3. Pick an import mode below",
"stepChooseBody": "Rescan the default location, point at any folder you've extracted history into, or upload files/archives directly.",
"stepVerify": "4. Verify tokens and cost",
"stepVerifyBody": "After import, open Analytics → Cost to confirm the breakdown. Re-importing the same session is always safe.",
"defaultLocation": "Default location on this machine",
"locationFound": "Folder found",
"locationMissing": "Folder not found",
"projectsLabel": "projects",
"jsonlLabel": "JSONL files",
"modeRescan": "Rescan default folder",
"modeRescanDesc": "Re-read ~/.claude/projects and import anything new.",
"modeFolder": "Scan a folder",
"modeFolderDesc": "Scan any directory on this machine for JSONL transcripts (walks subfolders).",
"modeUpload": "Upload files",
"modeUploadDesc": "Drop JSONL files or an archive (.zip / .tar.gz) directly into the browser.",
"modeBackup": "Restore backup",
"modeBackupDesc": "Import a dashboard export (.json) from Export data — merge another machine's history in.",
"backupHint": "Drop an export .json here or click to select",
"backupSub": "The file produced by the Export data button (top of Settings)",
"runRestore": "Restore",
"backupResult": {
"title": "Restore complete",
"sessionsImported": "Sessions added: {{count}}",
"sessionsSkipped": "Already present: {{count}}",
"events": "Events: {{count}}",
"pricing": "Pricing rules: {{count}}",
"detail": "{{agents}} agents · {{workflows}} workflows · {{runs}} runs · {{rules}} alert rules"
},
"folderPlaceholder": "/absolute/path/to/claude-history",
"folderHelper": "Absolute path. Tilde (~) is expanded. Subfolders are scanned recursively.",
"runRescan": "Rescan Now",
"runScan": "Scan Folder",
"runUpload": "Upload & Import",
"dropzoneHint": "Drag files here or click to select",
"dropzoneSub": "Accepts .jsonl, .meta.json, .zip, .tar, .tar.gz, .tgz, .gz",
"filesSelected": "{{count}} file(s) selected",
"clearSelection": "Clear",
"copy": "Copy",
"copied": "Copied",
"progress": {
"scan": "Scanning directory...",
"extract": "Extracting archives ({{processed}}/{{total}})...",
"parse": "Parsing transcripts ({{processed}}/{{total}})...",
"complete": "Import complete",
"error": "Import failed"
},
"result": {
"imported": "Imported: {{count}}",
"backfilled": "Enriched existing: {{count}}",
"skipped": "Already up to date: {{count}}",
"errors": "Errors: {{count}}",
"filesScanned": "Files scanned: {{count}}",
"title": "Last import result"
},
"errors": {
"noFiles": "No files selected",
"noJsonl": "No .jsonl files were found in the uploaded content",
"pathRequired": "Path is required",
"pathInvalid": "Path must be absolute",
"pathNotFound": "Path does not exist",
"pathNotDir": "Path is not a directory",
"generic": "Import failed: {{message}}"
}
},
"data": {
"title": "Data Management",
"description": "Database info, import/export, and cleanup.",
"dbOverview": "Database Overview",
"dbSize": "DB Size",
"loadingDb": "Loading database info...",
"sessionCleanup": "Session Cleanup",
"cleanupDesc": "Abandon stale sessions and purge old data",
"abandonAfter": "Abandon stale active sessions older than",
"purgeAfter": "Purge completed/errored sessions older than",
"confirmCleanup": "Confirm Cleanup",
"runCleanup": "Run Cleanup",
"nothingToClean": "Nothing to clean up",
"abandonedResult": " sessions abandoned",
"purgedResult": " sessions purged ({{events}} events, {{agents}} agents)"
},
"danger": {
"title": "Danger Zone",
"description": "Irreversible actions that delete data permanently",
"warning": "This will delete all sessions, agents, events, and token data. Are you sure?",
"yesClearAll": "Yes, Clear All",
"clearAllData": "Clear All Data",
"clearedResult": "Cleared {{count}} rows"
},
"about": {
"title": "About",
"description": "Server runtime information.",
"release": "Release",
"uiBuild": "UI build v{{version}} (rebuild client to match)",
"uptime": "Uptime",
"nodejs": "Node.js",
"platform": "Platform",
"wsClients": "WS Clients",
"loadingInfo": "Loading server info..."
},
"tables": {
"sessions": "sessions",
"agents": "agents",
"events": "events",
"sessionsWithCost": "sessions with cost",
"pricingRules": "pricing rules"
},
"messages": {
"failedLoad": "Failed to load",
"failedSave": "Failed to save",
"failedDelete": "Failed to delete",
"unknownError": "Unknown",
"actionFailed": "Error: {{message}}"
},
"webhooks": {
"title": "Webhook Notifications",
"description": "Forward fired alerts to Slack, Discord, Microsoft Teams, or any HTTP endpoint. Delivery is automatic, retried on failure, and never blocks monitoring.",
"count_one": "{{count}} target",
"count_other": "{{count}} targets",
"add": "Add Webhook",
"loading": "Loading webhooks…",
"empty": "No webhooks configured. Add one to forward alerts to Slack, Discord, Teams, or a custom endpoint.",
"scopedTo_one": "{{count}} rule",
"scopedTo_other": "{{count}} rules",
"enabled": "Enabled",
"test": "Test",
"edit": "Edit",
"delete": "Delete",
"confirmDelete": "Confirm",
"testOk": "Delivered (HTTP {{status}})",
"testFail": "Failed: {{error}}",
"addTitle": "New Webhook",
"editTitle": "Edit Webhook",
"fieldName": "Name",
"fieldNamePlaceholder": "e.g. Team Slack #alerts",
"fieldType": "Type",
"type": {
"slack": "Slack",
"discord": "Discord",
"teams": "Microsoft Teams",
"generic": "Generic (custom JSON)"
},
"fieldUrl": "Webhook URL",
"urlKeepHint": "leave blank to keep current",
"urlKeepPlaceholder": "•••••••• (unchanged)",
"urlPlaceholder": {
"slack": "https://hooks.slack.com/services/…",
"discord": "https://discord.com/api/webhooks/…",
"teams": "https://outlook.office.com/webhook/…",
"generic": "https://example.com/webhook"
},
"fieldSecret": "Signing secret (optional)",
"secretPlaceholder": "HMAC-SHA256 secret",
"secretKeepPlaceholder": "•••••••• (leave blank to keep)",
"secretHint": "When set, requests are signed with an X-Webhook-Signature header.",
"fieldHeaders": "Custom headers (optional)",
"replaceHeaders": "Replace headers",
"headerKey": "Header",
"headerValue": "Value",
"addHeader": "Add header",
"scopeAll": "Receive alerts from all rules",
"enabledOnSave": "Enabled",
"save": "Save",
"create": "Create",
"cancel": "Cancel",
"urlOptional": "optional override",
"urlAuto": "URL is set automatically from the credentials below.",
"deleteTitle": "Delete webhook?",
"deleteMessage": "Delete \"{{name}}\"? Fired alerts will stop being delivered to this target. This cannot be undone.",
"guideToggle": "How to set up {{provider}}",
"guideDocs": "Official {{provider}} docs",
"guideStaleNote": "Provider setup screens change often, so these steps may be out of date - always confirm against the official docs."
},
"alertsHub": {
"title": "Alerts",
"description": "Define alert rules, route them to webhook channels, and review what has fired - all in one place.",
"tabRules": "Rules",
"tabChannels": "Channels",
"tabActivity": "Activity",
"rulesHint": "Conditions that trigger an alert. Evaluated server-side against the live event stream.",
"rulesEmptyHint": "Add a rule to start alerting on errors, inactivity, stuck agents, or token thresholds."
},
"jumpTo": "Jump to",
"webhookGuides": {
"slack": {
"steps": [
"Create or open a Slack app at api.slack.com/apps.",
"Turn on 'Incoming Webhooks', then click 'Add New Webhook to Workspace'.",
"Choose the channel to post to and authorize.",
"Copy the generated URL (https://hooks.slack.com/services/…) and paste it above."
]
},
"discord": {
"steps": [
"Open your server → Server Settings → Integrations → Webhooks.",
"Click 'New Webhook', pick a channel, optionally rename it.",
"Click 'Copy Webhook URL' and paste it above."
]
},
"teams": {
"steps": [
"In the target Teams channel, click ⋯ → 'Workflows'.",
"Pick the template 'Post to a channel when a webhook request is received'.",
"Finish the flow and copy the generated HTTP POST URL.",
"Paste it above. (Classic Office 365 connectors were retired in 2025 - use Workflows.)"
]
},
"google_chat": {
"steps": [
"Open the Google Chat space → space title → 'Apps & integrations'.",
"Click 'Webhooks' → 'Add webhook' and give it a name.",
"Copy the webhook URL and paste it above."
]
},
"mattermost": {
"steps": [
"Main Menu → Integrations → Incoming Webhooks (an admin must enable webhooks first).",
"Click 'Add Incoming Webhook' and choose a channel.",
"Save, then copy the webhook URL and paste it above."
]
},
"rocketchat": {
"steps": [
"Administration → Integrations → New → Incoming.",
"Enable it, pick a channel, and save.",
"Copy the 'Webhook URL' and paste it above."
]
},
"telegram": {
"steps": [
"Message @BotFather, run /newbot, and copy the bot token.",
"Add the bot to your group/channel (or just DM it).",
"Find the chat ID: send a message, open https://api.telegram.org/bot<token>/getUpdates, read result[].message.chat.id.",
"Enter the Bot token and Chat ID above - no URL needed."
]
},
"pagerduty": {
"steps": [
"Open the target Service → Integrations → 'Add integration'.",
"Choose 'Events API v2'.",
"Copy the Integration Key (the routing key).",
"Enter it as the Routing key above - the Events API URL is prefilled."
]
},
"opsgenie": {
"steps": [
"Settings → Integrations → add an 'API' integration.",
"Copy the generated API key.",
"Note your account region (US or EU).",
"Enter the API key and region above - the alerts URL is derived from the region."
]
},
"splunk_oncall": {
"steps": [
"Integrations → REST Endpoint, and enable it.",
"Copy the REST URL - it already contains your API key.",
"Replace the trailing '$routing_key' with one of your routing keys.",
"Paste the full URL above."
]
},
"zapier": {
"steps": [
"Create a Zap with the trigger 'Webhooks by Zapier' → 'Catch Hook'.",
"Copy the custom webhook URL it gives you.",
"Paste it above. The alert arrives as JSON: { event, alert }."
]
},
"make": {
"steps": [
"Add a 'Webhooks' → 'Custom webhook' module as the first step of a scenario.",
"Click 'Add', create the hook, and copy its URL.",
"Paste it above, then run once so Make learns the payload shape."
]
},
"n8n": {
"steps": [
"Add a 'Webhook' node to your workflow; set the method to POST.",
"Copy the Production URL.",
"Activate the workflow and paste the URL above (http is allowed for self-hosted)."
]
},
"pipedream": {
"steps": [
"Create a workflow with an 'HTTP / Webhook' trigger.",
"Copy the unique endpoint URL.",
"Paste it above; inspect deliveries in the Pipedream event inspector."
]
},
"generic": {
"steps": [
"Point this at any endpoint that accepts a JSON POST (https, or http for local testing).",
"Body shape: { event: 'alert.triggered', source, sent_at, alert: { … } }.",
"Optional: set a signing secret (HMAC-SHA256 over the body → X-Webhook-Signature header) and custom headers.",
"Tip: use a free inspector like webhook.site to see the exact payload."
]
}
},
"remoteSources": {
"title": "Remote Data Sources",
"description": "Collect Claude Code usage from other machines over SSH - e.g. a dev box or cloud VM you drive over SSH while running this dashboard locally. Authentication uses your own SSH setup (~/.ssh/config, keys, agent); no passwords are stored here.",
"scopeTitle": "Data scope",
"scopeDesc": "Choose which machines' data the whole dashboard shows. Changes apply immediately across every page — sessions, analytics, and cost.",
"scopeAll": "All sources",
"scopeAllDesc": "This machine plus every configured remote source, combined.",
"scopeLocal": "This machine only",
"scopeLocalDesc": "Only sessions collected locally — hides all remote-source data.",
"scopeSelected": "Selected sources",
"scopeSelectedDesc": "Pick exactly which machines to include, below.",
"scopeSelectedCount": "{{n}} of {{total}} selected",
"scopePickMachines": "Machines to include",
"thisMachine": "This machine",
"listTitle": "Configured sources",
"add": "Add source",
"addTitle": "Add a remote source",
"editTitle": "Edit source",
"fieldLabel": "Label",
"fieldHost": "SSH host",
"fieldPort": "Port (optional)",
"fieldIdentity": "Identity file (optional)",
"fieldRemoteHome": "Remote Claude home (optional)",
"fieldRemoteHomeHint": "Linux/macOS: default ~/.claude (or an absolute path like /home/you/.claude). Windows SSH + Claude in WSL: leave blank (auto-detect) or use wsl:~/.claude. Native Windows: C:/Users/you/.claude.",
"fieldEnabled": "Sync automatically in the background",
"empty": "No remote sources yet.",
"emptyHint": "Add a machine you reach over SSH to pull its Claude Code usage in.",
"paused": "Auto-sync off",
"sessionCount": "{{n}} sessions",
"sessionCountLinked": "{{n}} linked",
"sessionCountHint": "Sessions linked to this source (not every session visible when data scope is All)",
"lastSync": "Last sync: {{when}}",
"neverSynced": "Never synced",
"imported": "{{n}} imported",
"syncNew": "{{n}} new",
"syncOnRemote": "{{n}} on remote",
"test": "Test",
"syncNow": "Sync",
"syncAll": "Sync all",
"enable": "Enable",
"disable": "Disable",
"confirmDelete": "Remove this source?",
"purgeData": "Also delete the sessions imported from this source (cannot be undone)",
"deleteAndPurge": "Remove + delete data",
"removeKeep": "Remove (keep data)",
"remoteSourceBadgeTitle": "Collected from a remote machine"
},
"cursorPathsNote": "Informational: Cursor sessions count here too — Cursor happens to use the same ~/.claude paths as Claude Code (locally and on synced remotes)."
}
+79
View File
@@ -0,0 +1,79 @@
{
"greeting": {
"morning": "Good morning",
"afternoon": "Good afternoon",
"evening": "Good evening",
"night": "Working late"
},
"tagline": "Nothing your agents do stays in the dark.",
"sub1": "Real-time observability for every Claude Code session.",
"sub2": "Tokens, tools, costs, and workflows, all live.",
"brand": "Claude Code Monitor",
"taglines": [
"Nothing your agents do stays in the dark.",
"See every move your agents make.",
"Your agents, fully observable.",
"Every token, tool, and turn — in plain sight.",
"Watch your fleet think.",
"Where Claude Code sessions come into focus.",
"Real-time eyes on every agent.",
"From prompt to result, all on the record.",
"The control room for your AI agents.",
"Every subagent accounted for.",
"Know exactly what your agents cost.",
"Your agentic workflows, made legible.",
"Observe. Measure. Optimize.",
"Mission control for Claude Code.",
"Turn agent chaos into a clear picture.",
"The receipts for every run."
],
"subs": [
[
"Real-time observability for every Claude Code session.",
"Tokens, tools, costs, and workflows, all live."
],
[
"Live sessions, agents, and events as they happen.",
"Per-model token and cost breakdowns, no guesswork."
],
[
"Trace every tool call across your agent tree.",
"Spot the slow turn, the costly model, the silent failure."
],
["Hooks stream straight to a local dashboard.", "Your data never leaves your machine."],
[
"Watch orchestrators delegate to subagents.",
"DAGs, concurrency, and error propagation, visualized."
],
[
"Cost tracking down to the cache token.",
"Per-model pricing with compaction-aware baselines."
],
[
"Every session, agent, and event in one place.",
"Search, replay, and inspect without leaving the room."
],
[
"From SessionStart to SessionEnd, captured.",
"Compactions, API errors, and turn durations included."
],
[
"Know which model did what, and what it cost.",
"Subagents priced at their own rate, not the orchestrator's."
],
["Workflow fleets and inner agents, surfaced.", "Even the runs that never fire a hook."],
["A local-first window into your agents.", "No cloud, no account, no telemetry."],
[
"Measure productivity, not vibes.",
"Velocity, cache efficiency, and tool effectiveness, scored."
],
[
"Catch the anomaly before the invoice does.",
"Cost outliers and token spikes, flagged early."
],
[
"Your Claude Code config, fully mapped.",
"Skills, agents, hooks, MCP, and memory at a glance."
]
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"title": "Dashboard update available",
"lead": "A new version of the dashboard is available. To update, run the following command in your terminal:",
"commitsBehind": "{{count}} commit(s) behind {{ref}}",
"copy": "Copy command",
"commandLabel": "Terminal command to update the dashboard",
"copied": "Copied",
"dismiss": "Dismiss",
"fetchError": "Could not reach git remote. Try again when you are online.",
"notGit": "This install is not a git clone; use a manual upgrade path.",
"restartNote": "After the command finishes, close and restart the dashboard the same way you started it: if you used npm start, run npm start again.",
"checkNow": "Check now",
"checking": "Checking...",
"checkError": "Could not check for updates"
}
+468
View File
@@ -0,0 +1,468 @@
{
"title": "Workflows",
"subtitle": "Agent orchestration intelligence",
"failedLoad": "Failed to load workflow data",
"filteredBy": "Filtered by:",
"clearFilter": "Clear filter",
"refreshData": "Refresh data",
"exportJson": "Export as JSON",
"allSessions": "All Sessions",
"activeOnly": "Active Only",
"completed": "Completed",
"runs": {
"title": "Dynamic Workflows",
"subtitle": "Fleets spawned by the Workflow tool, reconstructed from on-disk run journals",
"sessionTitle": "Dynamic Workflows",
"loading": "Loading dynamic workflows…",
"empty": "No dynamic workflows yet. Runs from the Workflow tool appear here once their journal is written (at completion).",
"noAgents": "No inner agents recorded for this run.",
"openSession": "Open parent session",
"filterPhase": "Filter by phase",
"clearFilter": "Clear",
"resultsLabel": "Results",
"promptLabel": "Prompt",
"resultLabel": "Result",
"loadingFull": "Loading full text…",
"tokens": "tokens",
"agents_one": "{{count}} agent",
"agents_other": "{{count}} agents",
"tools_one": "{{count}} tool call",
"tools_other": "{{count}} tool calls",
"status": {
"running": "Running",
"working": "Running",
"queued": "Queued",
"completed": "Completed",
"done": "Done",
"success": "Done",
"error": "Error",
"failed": "Failed"
},
"col": {
"agent": "Agent",
"phase": "Phase",
"state": "State",
"tokens": "Tokens",
"tools": "Tools",
"duration": "Duration"
}
},
"chartInfo": {
"labels": {
"what": "What this shows",
"howToRead": "How to read it",
"why": "Why it matters"
},
"orchestration": {
"what": "A layered DAG of how Claude Code sessions fan out: from the originating sessions, into the main agent, into each subagent type, through any context compactions, and finally into terminal outcomes (completed / error / abandoned).",
"howToRead": "Each column is one layer. Box width is constant; the small badge is the count. Edges flow left-to-right; thicker edges = more frequent transitions. Hover any node for stats; click to filter the rest of the page by it.",
"why": "Use it to answer 'where does work go in my workflows?' - which subagent types dominate, where compaction kicks in, and which paths end in errors vs clean completions."
},
"toolFlow": {
"what": "A Sankey-style chart of consecutive tool-call transitions across every session in scope. Each band is one (source → target) pair counted across all sessions.",
"howToRead": "Tools appear as colored bars on the left and right. Bands connect them: thickness = number of times the source ran immediately before the target. Hover a band for share-of-source and share-of-target percentages; hover a node for its total usage and share of all tool calls.",
"why": "Surfaces habitual tool chains (e.g. Read → Edit → Bash). Useful for spotting loops, wasted hops, and missing tool variety in agent behavior."
},
"pipeline": {
"what": "A directed graph of agent-type co-occurrence: which agent types tend to run sequentially after which, and how often.",
"howToRead": "Circles are agent types; size encodes total spawns. Arrows go A → B when B was observed running shortly after A in the same session, with the label = count. Hover an arrow for share of source/target; hover a circle for spawns, sessions, and success rate. Drag nodes to rearrange.",
"why": "Surfaces real delegation pipelines you may not have intentionally designed - e.g. a code-review agent that nearly always follows a build agent - so you can codify or simplify them."
},
"effectiveness": {
"what": "One card per subagent type with a success-rate ring, total sessions, average duration, and a 7-day activity sparkline.",
"howToRead": "Ring fill is success rate; the percentage in the center is the same. The two boxes give counts and average wall-clock duration. The sparkline is sessions per day for the last week - hover a bar for the daily count.",
"why": "Quick health check per agent: which agents are reliable, which are slow, and which are trending up or down in usage."
},
"patterns": {
"what": "A ranked list of recurring agent-orchestration sequences detected from session traces, plus a callout for solo sessions that ran without subagents.",
"howToRead": "Each row is a step sequence (main → sub → sub …). The right side shows how many sessions matched it and what percentage of all sessions that represents. Click a pattern to highlight it.",
"why": "Reveals the standard 'shapes' of work in your project. Frequent patterns are good candidates to formalize as named workflows or skills."
},
"modelDelegation": {
"what": "A two-column flow showing which main models delegate to which subagent models, plus per-node agent counts and total tokens.",
"howToRead": "Left column = main models for sessions; right column = models used inside subagents. Lines indicate observed main → subagent pairings. Hover a node for share-of-all-agents, sessions, total tokens, and a description of the model family (Opus / Sonnet / Haiku).",
"why": "Helps you confirm cost/latency tiering - e.g. main on Sonnet, subagents on Haiku - and catch unintended escalations to Opus."
},
"errorPropagation": {
"what": "Where errors cluster across the agent hierarchy: by depth (session/main vs direct subagent vs nested), by agent type, and by API/session-level error category.",
"howToRead": "The top banner gives the session-level error rate. The depth bars show how many errors occurred at each nesting level. The error-prone types list ranks subagent types by error count. The bottom block surfaces API/session error summaries.",
"why": "Pinpoints whether failures live in the orchestration spine (main agent), in specific subagents, or in deep nested chains - guiding where to invest in retries, validation, or rewrites."
},
"concurrency": {
"what": "Aggregate timing of when each agent type is active relative to the session timeline, plus how many sessions feature it.",
"howToRead": "Each row is one agent type. Bar length is proportional to session count. The right-hand percentages show the average start and end position within a session (0% = session start, 100% = session end). Hover for a description of the timing pattern (front-loaded, mid-session, back-loaded, etc.).",
"why": "Reveals the rhythm of your sessions - e.g. linting up front, code-review near the end - and surfaces agents that monopolize the entire session."
},
"complexity": {
"what": "A scatter plot of every session: x = wall-clock duration, y = total agents involved, bubble size = total tokens, color = final status.",
"howToRead": "Top-right bubbles are long, agent-heavy sessions. Big bubbles burned the most tokens. Reds/yellows = error/abandoned outcomes. Hover any bubble for full session stats; click to drill into it below.",
"why": "Gives a single view of the cost/complexity distribution. Outliers are the sessions worth investigating for runaway behavior or cost spikes."
},
"compaction": {
"what": "How often Claude triggered context compaction across sessions: total events, tokens recovered, and a per-session distribution.",
"howToRead": "The two stat boxes show total compaction events and the cumulative tokens reclaimed. The bar chart lists sessions with at least one compaction, sorted descending by count.",
"why": "Compactions indicate context pressure. A long tail of high-compaction sessions usually means workflows that should be split, summarized, or migrated to a longer-context model."
},
"drillIn": {
"what": "Per-session detail view: full agent tree, tool-call timeline, and raw event sequence for whichever session you select.",
"howToRead": "Pick a session from the dropdown above or click a bubble in the scatter plot. The tabs let you switch between hierarchical (Agent Tree), temporal (Tool Timeline), and chronological (Event Sequence) views of the same session.",
"why": "When an aggregate chart flags a suspicious session, this is where you go to read exactly what happened, in order."
}
},
"stats": {
"avgAgentDepth": "Avg Agent Depth",
"avgSubagentsPerSession": "Avg Subagents / Session",
"agentSuccessRate": "Agent Success Rate",
"mostCommonFlow": "Most Common Flow",
"avgCompactions": "Avg Compactions",
"avgDuration": "Avg Duration",
"tooltip": {
"howCalc": "How it's calculated",
"whatItMeans": "What this number means",
"moreInfo": "Explain this metric",
"valueMeansFmt": "{{value}} {{phrase}} means {{interpretation}}",
"phrase": {
"depth": "average agent depth",
"subagents": "subagents per session",
"success": "agent success rate",
"topFlow": "most common flow",
"compactions": "compactions per session",
"duration": "average duration"
},
"calc": {
"depth": "For each session we record the deepest agent nesting level (main = 0, direct subagent = 1, sub-subagent = 2, …) and average those maximums across all sessions in the current filter.",
"subagents": "Total number of subagent invocations (every Task / SubagentStop pair) divided by the number of sessions in scope. Counts every subagent run, including parallel and re-spawned ones.",
"success": "Across all main + subagent runs in scope: completed runs ÷ (completed + errored + abandoned) × 100. A run counts as completed when a Stop / SubagentStop is observed without an error event in between.",
"topFlow": "Every consecutive pair of tool calls within a session is counted as one transition. The pair that appears most frequently across all sessions is shown here as 'source → target'.",
"compactions": "Total number of context-compaction events recorded by the PreCompact / SessionStart(compact) hooks, divided by the number of sessions in scope.",
"duration": "Mean wall-clock time from each session's first event (SessionStart) to its last event (Stop / SessionEnd / latest hook), averaged across all sessions in scope."
},
"depth": {
"zero": "no nested agents have been observed. Every session ran with just the main agent - no subagent delegation occurred.",
"rare": "nesting is rare. Most sessions stay at depth 0 (main agent only); only a small fraction reach into subagents.",
"single": "sessions typically delegate to a single layer of subagents (main → subagent), without further nesting.",
"multi": "multi-layer orchestration is common - subagents themselves frequently spawn further subagents (main → sub → sub).",
"deep": "deep, recursive orchestration is the norm. Sessions consistently chain three or more agent layers."
},
"subagents": {
"zero": "no subagents have fired. Sessions completed entirely on the main agent.",
"lowFreq": "practically: roughly one subagent every ~{{count}} sessions. Most sessions don't spawn any subagent at all.",
"moderate": "sessions typically delegate to 13 subagents - moderate use of specialized helpers.",
"heavy": "heavy delegation - sessions routinely fan out to several subagents.",
"veryHeavy": "very orchestration-heavy: sessions average 6+ subagent runs each."
},
"success": {
"perfect": "near-perfect. Almost every agent run finishes with a clean Stop event - no errors or abandonment.",
"healthy": "healthy. The vast majority of agent runs complete successfully; only sporadic failures.",
"acceptable": "acceptable, but watch the error trend - roughly 1 in every 520 runs fails or is abandoned.",
"concerning": "concerning - a meaningful share of agent runs are failing. Inspect the Errors page for top culprits.",
"critical": "critical: most agent runs are failing or being abandoned. Check ErrorPropagation and recent deploys."
},
"topFlow": {
"none": "not enough consecutive tool calls have been recorded yet to surface a dominant pair.",
"selfLoop": "{{tool}} most often follows itself - typical for repeated reads/edits or chained shell commands.",
"pair": "{{source}} most often runs immediately before {{target}}. Read it as a habit: agents tend to {{sourceLower}} and then {{targetLower}} as their next step."
},
"compactions": {
"zero": "no context compaction has been observed. Sessions stayed comfortably within the model's context window.",
"lowFreq": "practically: ~1 compaction every {{count}} sessions. Long-running sessions are the exception.",
"moderate": "sessions typically hit compaction once or twice - context pressure exists but is manageable.",
"high": "high compaction rate. Sessions routinely run long enough to require multiple context compressions; consider splitting work."
},
"duration": {
"zero": "no completed sessions yet - duration is 0.",
"veryShort": "very short sessions (under a minute) - likely quick tool calls or single-shot prompts.",
"short": "short sessions, on the order of a few minutes. Typical for focused, single-feature work.",
"medium": "medium-length sessions (530 min). Standard development cadence.",
"long": "long sessions (3060 min). Likely multi-step workflows or longer review cycles.",
"veryLong": "very long sessions (13 hr). Watch for compaction and context pressure.",
"marathon": "marathon sessions (3+ hours). Consider whether work could be split into multiple shorter sessions."
}
}
},
"orchestration": {
"title": "Agent Orchestration Graph",
"subtitle": "Aggregate spawning patterns across all sessions - Click a node to filter",
"sessions": "Sessions",
"mainAgent": "Main Agent",
"compactions": "Compactions",
"noData": "No orchestration data",
"noDataDesc": "Agent spawning data will appear here once sessions with subagents have been recorded.",
"legend": "Legend",
"edgeWeight": "Edge weight = frequency",
"count": "Count",
"otherTypes": "{{count}} other types",
"ariaLabel": "Agent orchestration directed acyclic graph",
"layers": {
"origin": "Origin",
"mainAgent": "Main Agent",
"subagentTypes": "Subagent Types",
"compactions": "Compactions",
"outcomes": "Outcomes"
},
"tooltip": {
"tipClickToFilter": "Tip: click to filter the rest of the page by this node.",
"layer": {
"session": "Layer 0 - Origin",
"main": "Layer 1 - Main agent",
"subagent": "Layer 2 - Subagent type",
"subagentOverflow": "Layer 2 - Subagent types",
"nested": "Layer 3 - Compactions",
"outcome": "Layer 4 - Outcome"
},
"desc": {
"session": "Each unit here is a Claude Code session matching the current status filter. Outgoing edges fan out to the main agents these sessions launched.",
"main": "The top-level Claude run for each session. Every session has exactly one main agent; from here the graph branches into the subagent types it delegated to.",
"subagent": "A specialized subagent the main agent delegated to (e.g. via the Task tool).",
"subagentClean": " Every run of this subagent has completed cleanly.",
"subagentAllError": " Every run of this subagent has errored - investigate the agent definition.",
"subagentSomeErrors": " {{count}} run(s) errored - see Error Propagation below for details.",
"subagentOverflow": "All remaining subagent types collapsed into one node so the graph stays readable. Hover any other subagent node to see individual stats.",
"nested": "Context-window compaction events. Claude triggers a compaction when the running context approaches the model's limit; the count reflects how often that happened across the sessions in scope.",
"outcomeCompleted": "Sessions whose final hook was a clean Stop event. No error events were emitted before termination.",
"outcomeError": "Sessions that emitted at least one error event (tool error, subagent error, or session error) before terminating.",
"outcomeAbandoned": "Sessions that stopped without a clean Stop event and without explicit errors - usually closed mid-flight.",
"outcomeFallback": "The terminal status of sessions in scope, computed from the last hook event observed for each session."
}
}
},
"toolFlow": {
"title": "Tool Execution Flow",
"subtitle": "How tools chain together - Sankey-style directed flow",
"noData": "No tool flow data",
"transitionCount_one": "{{count}} transition",
"transitionCount_other": "{{count}} transitions",
"tooltip": {
"node": "Tool node",
"link": "Tool transition",
"totalCalls": "Total calls",
"shareOfAll": "Share of all tool use",
"transitionsObserved": "Transitions observed",
"shareOfSourceFmt": "Share of {{source}} → next",
"shareOfTargetFmt": "Share of prev → {{target}}",
"nodeDescFmt": "Bar height shows how often {{name}} appears across all sessions in scope. Bands flowing in on the left show what ran before {{name}}; bands flowing out on the right show what ran after.",
"linkDescFmt": "Across every session, this counts how often {{source}} ran immediately before {{target}}. Thicker bands = more common transitions; the percentages show how dominant this hop is among each tool's outgoing / incoming flow."
}
},
"pipeline": {
"title": "Agent Pipeline Graph",
"subtitle": "Directed workflow - which agent types run after which, with frequency labels",
"noData": "No pipeline data yet",
"noDataDesc": "Directed workflow edges appear once agent types run sequentially across multiple sessions.",
"legend": "Legend",
"legendDesc": "A runs before B (labeled count)",
"frequency": "Frequency",
"meaning": "Meaning",
"times": " times",
"ranAfter": " ran after ",
"spawns": " spawns",
"spawned": "Spawned",
"inSessions": "In sessions",
"ariaLabel": "Agent pipeline graph",
"tooltip": {
"agentType": "Agent type",
"edge": "Sequential edge",
"shareOfAllSpawns": "Share of all spawns",
"sequentialPairs": "Sequential pairs",
"totalSpawnsFmt": "{{id}} total spawns",
"shareOfSrcFmt": "Share of {{source}} → next",
"shareOfTgtFmt": "Share of prev → {{target}}",
"edgeDescFmt": "{{target}} ran immediately after {{source}} {{count}} time(s) across all sessions. The thicker the arrow, the more often this hand-off occurred. Use this to spot habitual delegation chains in your workflows.",
"nodeDescFmt": "{{id}} ran {{total}} time(s) across {{sessions}} session(s); its success rate is {{rate}}% ({{health}}). Circle size encodes total spawns; arrows show which agent types tend to run before or after it.",
"health": {
"perfect": "near-perfect",
"healthy": "healthy",
"shaky": "shaky",
"failing": "failing often"
}
}
},
"effectiveness": {
"title": "Subagent Effectiveness",
"subtitle": "Performance metrics per agent type",
"success": "Success",
"sessions": "Sessions",
"avgDuration": "Avg Duration",
"weeklyActivity": "Weekly activity",
"noData": "No subagent data available",
"successRateAria": "Success rate: {{rate}}%",
"weeklyActivityAria": "Weekly activity sparkline",
"sessionCount_one": "{{count}} session",
"sessionCount_other": "{{count}} sessions"
},
"patterns": {
"title": "Detected Workflow Patterns",
"subtitle": "Common agent orchestration sequences",
"noData": "No patterns detected yet",
"noDataDesc": "Patterns appear once multiple sessions share the same agent sequence.",
"solo": "solo (no subagents)",
"label": "Workflow Patterns",
"detail": {
"clickHint": "Click for details",
"stepsHeading": "Full step sequence",
"statsHeading": "Stats",
"stepsCount_one": "{{count}} step",
"stepsCount_other": "{{count}} steps",
"uniqueAgents": "Unique agent types",
"occurrences": "Sessions matching this pattern",
"shareOfSessions": "Share of all sessions",
"narrativeHeading": "What this means",
"suggestionHeading": "Suggestion",
"narrative": {
"soloFmt": "Sessions that ran with only {{first}} - no delegation to other agent types.",
"twoStepFmt": "A two-step hand-off: {{first}} delegates straight to {{last}}, with no further branching.",
"shortFmt": "A {{count}}-step chain that starts at {{first}} and ends at {{last}}.",
"longFmt": "A long {{count}}-step chain - begins at {{first}}, threads through several agents, and lands at {{last}}.",
"loopHintFmt": " {{agent}} appears more than once in this sequence - typical of a verification or revision loop.",
"dominant": " This is the dominant workflow in your project - more than half of sessions follow it.",
"common": " This is a common workflow, accounting for roughly a quarter of sessions.",
"regular": " A recognised workflow, but not the majority pattern.",
"niche": " A niche pattern that only surfaces occasionally."
},
"suggestion": {
"solo": "Solo run - would a code-reviewer or test-runner subagent raise the quality of these sessions?",
"shortChain": "Short chain. If it keeps recurring, name it as a slash command, skill, or named workflow so it's easy to reproduce.",
"mediumChain": "Frequent enough to formalise. A named workflow or template would make this pattern reusable.",
"longChain": "Long chain - review whether every hop is necessary, or whether some agents could be merged or skipped.",
"loop": "Loop detected. Confirm the repeated step is intentional verification rather than a silent retry of a failing call."
}
}
},
"modelDelegation": {
"title": "Model Delegation Flow",
"subtitle": "How models route through agent hierarchies",
"mainModels": "MAIN MODELS",
"subagentModels": "SUBAGENT MODELS",
"noData": "No model delegation data available",
"agentsCount_one": "{{count}} agent",
"agentsCount_other": "{{count}} agents",
"tokensCount": "{{tokens}} tokens",
"sessionsCount_one": "{{count}} session",
"sessionsCount_other": "{{count}} sessions",
"ariaLabel": "Model delegation flow diagram",
"tooltip": {
"mainModel": "Main model",
"subagentModel": "Subagent model",
"agentRuns": "Agent runs",
"shareOfAll": "Share of all agents",
"sessionsOnModel": "Sessions on this model",
"totalTokens": "Total tokens",
"family": {
"opus": "Opus - highest-capability tier; best for complex reasoning, longest context, costliest per token.",
"sonnet": "Sonnet - balanced tier; good default for most coding and tool-use workflows.",
"haiku": "Haiku - fastest, cheapest tier; ideal for short, latency-sensitive subagents.",
"other": "Non-Anthropic or unrecognized model - falls outside the standard Opus/Sonnet/Haiku families."
},
"lines": {
"main": "Lines on the right show subagent models this main model delegated work to.",
"sub": "Lines on the left show main models that delegated work to this subagent model."
}
}
},
"errorPropagation": {
"title": "Error Propagation Map",
"subtitle": "Where errors cluster in agent hierarchy depth",
"noErrors": "No errors recorded",
"allSuccess": "All sessions completed successfully",
"sessionsHadErrors": " sessions had errors",
"sessionsErrorSummary": "{{errorSessions}} of {{totalSessions}} sessions had errors",
"agentErrors": " agent-level error(s) across hierarchy",
"sessionErrorsOnly": "Session-level errors only",
"errorsByDepth": "Errors by hierarchy depth",
"errorProneTypes": "Error-prone agent types",
"apiSessionErrors": "API & session errors",
"depthLabels": {
"sessionMain": "Session / Main",
"directSubagent": "Direct Subagent",
"nested": "Nested (depth 2)",
"deep": "Deep (depth 3+)"
}
},
"concurrency": {
"title": "Agent Concurrency Timeline",
"subtitle": "Parallel agent execution patterns - Shows how agents overlap in time",
"noData": "No concurrency data",
"noDataDesc": "Concurrency data appears once sessions with subagents have been recorded.",
"sessions": "Sessions",
"timing": "Timing",
"max": " max",
"sessionInfo_one": "{{count}} session - active {{from}}%-{{to}}% of session",
"sessionInfo_other": "{{count}} sessions - active {{from}}%-{{to}}% of session",
"tooltip": {
"lane": "Concurrency lane",
"sessionsWith": "Sessions with this agent",
"avgStart": "Avg start in session",
"avgEnd": "Avg end in session",
"barHint": "Bar length is proportional to how many sessions feature this agent type. Timing percentages are averages across those sessions.",
"timing": {
"wholeSession": "Active across nearly the entire session - runs from the start through to the end.",
"frontLoadedFmt": "Front-loaded: typically active from session start until ~{{end}}% of the way through.",
"backLoadedFmt": "Back-loaded: typically kicks in around {{start}}% of the session and stays until the end.",
"tightFmt": "Tightly scoped: runs in a narrow band between {{start}}% and {{end}}% of the session timeline.",
"midSessionFmt": "Mid-session work: runs roughly from {{start}}% to {{end}}% of the session timeline."
}
}
},
"complexity": {
"title": "Session Complexity Scatter",
"subtitle": "Duration vs agent count vs tokens - Bubble size = token usage",
"noData": "No session complexity data",
"noDataDesc": "Sessions will appear here once they complete with agent activity.",
"duration": "Duration",
"agentCount": "Agent Count",
"ariaLabel": "Session complexity scatter plot",
"tooltip": {
"duration": "Duration:",
"agents": "Agents:",
"subagents": "Subagents:",
"tokens": "Tokens:",
"model": "Model:"
}
},
"compaction": {
"title": "Compaction Impact Analysis",
"subtitle": "How context compression is spread across your sessions",
"help": "When a session's context window fills up, Claude Code compresses older history into a summary. Each compaction is one such event.",
"noData": "No compactions recorded",
"totalCompactions": "Total compactions",
"sessionsAffected": "Sessions affected",
"ofTotal": "of {{total}}",
"avgPerSession": "Avg / affected session",
"peakSession": "Most in one session",
"tokensRecovered": "Tokens Recovered",
"distribution": "Sessions by compaction count",
"xAxis": "Compactions per session",
"yAxis": "Sessions",
"summary": "{{affected}} of {{total}} sessions ({{pct}}%) used context compaction.",
"tokensFreed": "Compaction freed ~{{tokens}} tokens of context.",
"ariaLabel": "Number of sessions by compaction count",
"tipTitle": "Compacted {{count}}x",
"tipDetail": "{{sessions}} sessions · {{pct}}% of affected"
},
"drillIn": {
"title": "Session Drill-In",
"subtitle": "Select a session from the scatter plot or use the dropdown to explore",
"searchPlaceholder": "Search sessions...",
"noSessionSelected": "No session selected",
"noSessionDesc": "Search and select a session above, or click a bubble in the scatter plot, to drill into its agent tree, tool timeline, and event sequence.",
"failedLoad": "Failed to load session",
"loading": "Loading...",
"loadMore": "Load more",
"noMatch": "No sessions match your search.",
"notFound": "No sessions found.",
"unknownModel": "unknown model",
"closePanel": "Close drill-in panel",
"close": "Close",
"tabs": {
"agentTree": "Agent Tree",
"toolTimeline": "Tool Timeline",
"eventSequence": "Event Sequence"
},
"noAgentTree": "No agent tree data available.",
"noToolEvents": "No tool events recorded.",
"noEvents": "No events recorded for this session.",
"showingOf": "Showing 100 of {{total}} events",
"sessionInfo": " session(s) - active {{from}}%-{{to}}% of session",
"sortedByCompaction": " session(s) (sorted by compaction count)"
}
}