@kaged/ui
React 19 SPA — mobile-first web dashboard with TanStack Router/Query, Zustand state, guest routes, project config editing, and terminal viewer
113
source files
26
test files
~13.3k
lines
✓ 566 pass
tests
fail
typecheck
clean
lint
Test results 566
resolveAuthGate > pending status → loading
[0.680ms]
resolveAuthGate > success status → authenticated
[0.040ms]
resolveAuthGate > error with status 401 → auth_required
[0.050ms]
resolveAuthGate > error with status 403 → auth_required
[0.030ms]
resolveAuthGate > error with non-auth status → connection_error
[0.030ms]
resolveAuthGate > error with no status (network failure) → connection_error
[0.020ms]
resolveAuthGate > error with null error object → connection_error
[0.020ms]
resolveAuthFlow > sidecar → authenticated regardless of cookie
[0.060ms]
resolveAuthFlow > loopback with cookie → authenticated
[0.020ms]
resolveAuthFlow > loopback without cookie → launch_url_required
[0.020ms]
resolveAuthFlow > insecure → no_auth regardless of cookie
[0.020ms]
requiresLaunchUrl > loopback → true
[0.020ms]
requiresLaunchUrl > sidecar → false
[0.020ms]
requiresLaunchUrl > insecure → false
[0.010ms]
isInsecure > insecure → true
[0.020ms]
isInsecure > sidecar → false
[0.020ms]
isInsecure > loopback → false
[0.020ms]
authorDisplayLabel — guest > display_name + handle → 'Name (handle)'
[0.090ms]
authorDisplayLabel — guest > handle only → handle
[0.030ms]
authorDisplayLabel — guest > display_name only → display_name
[0.020ms]
authorDisplayLabel — guest > neither display_name nor handle → user_id fallback (orphaned guest)
[0.020ms]
authorDisplayLabel — operator > display_name set → display_name
[0.050ms]
authorDisplayLabel — operator > no display_name → literal 'Operator'
[0.020ms]
authorDisplayLabel — operator > ignores handle for operators (handle isn't an operator concept)
[0.020ms]
authorDisplayLabel — agent > renders raw user_id as label
[0.040ms]
authorDisplayLabel — agent > ignores display_name and handle for agents (no agent registry yet)
[0.030ms]
projectBadge > ready → [LIVE] amber, no pulse
[0.730ms]
projectBadge > pending → [DRAFT] text-secondary with pulse
[0.060ms]
projectBadge > invalid → [CRASHED] magenta
[0.030ms]
projectBadge > all project states return a badge
[0.090ms]
projectBadge > all project badges have uppercase bracket-lock labels
[0.060ms]
sessionBadge > idle → [IDLE] dim
[0.050ms]
sessionBadge > running → [LIVE] amber
[0.020ms]
sessionBadge > paused → [PAUSED] amber-dim
[0.020ms]
sessionBadge > ended → [ENDED] magenta-dim
[0.020ms]
sessionBadge > all session states return a badge
[0.040ms]
sessionBadge > all session badges have uppercase bracket-lock labels
[0.050ms]
subagentBadge > caged → [CAGED] magenta with magenta-faint bg
[0.050ms]
subagentBadge > uncaged → [UNCAGED] magenta with magenta-dim bg
[0.020ms]
subagentBadge > idle → [IDLE] dim, no bg
[0.030ms]
subagentBadge > running → [LIVE] amber
[0.020ms]
subagentBadge > paused → [PAUSED] amber-dim
[0.020ms]
subagentBadge > blocked → [BLOCKED] magenta
[0.030ms]
subagentBadge > failed → [CRASHED] magenta
[0.020ms]
subagentBadge > all subagent badges have uppercase bracket-lock labels
[0.070ms]
resolveBanners > no flags → empty array
[0.080ms]
resolveBanners > insecure only → one banner
[0.060ms]
resolveBanners > noSandbox only → one banner
[0.030ms]
resolveBanners > both flags → two banners, insecure first
[0.030ms]
resolveBanners > insecure banner has correct text
[0.050ms]
resolveBanners > insecure banner has abbreviated mobile text
[0.030ms]
resolveBanners > no_sandbox banner has correct text
[0.030ms]
resolveBanners > no_sandbox banner has abbreviated mobile text
[0.030ms]
hasBanners > no flags → false
[0.030ms]
hasBanners > insecure → true
[0.020ms]
hasBanners > noSandbox → true
[0.020ms]
hasBanners > both → true
[0.020ms]
resolveBreakpoint > 0px → xs
[0.060ms]
resolveBreakpoint > 375px (iPhone SE / Mini) → xs
[0.020ms]
resolveBreakpoint > 390px (iPhone 12–15 standard) → xs
[0.010ms]
resolveBreakpoint > 411px (Pixel 6/7/8, Galaxy S20+, OnePlus 9) → xs
[0.010ms]
resolveBreakpoint > 412px (Pixel 6 Pro variant) → xs
[0.030ms]
resolveBreakpoint > 414px (iPhone Plus legacy) → xs
[0.010ms]
resolveBreakpoint > 428px (iPhone Pro Max / Plus) → xs
[0.020ms]
resolveBreakpoint > 479px (xs upper bound) → xs
[0.020ms]
resolveBreakpoint > 480px → sm
[0.020ms]
resolveBreakpoint > 767px (sm upper bound) → sm
[0.020ms]
resolveBreakpoint > 768px → md
[0.010ms]
resolveBreakpoint > 1023px (md upper bound) → md
[0.010ms]
resolveBreakpoint > 1024px → lg
[0.020ms]
resolveBreakpoint > 1439px (lg upper bound) → lg
[0.010ms]
resolveBreakpoint > 1440px → xl
[0.010ms]
resolveBreakpoint > 2560px (ultrawide) → xl
[0.010ms]
isMobile > 375px → true
[0.030ms]
isMobile > 480px → true (sm is still mobile)
[0.020ms]
isMobile > 767px → true
[0.020ms]
isMobile > 768px → false (tablet)
[0.020ms]
isMobile > 1024px → false (desktop)
[0.020ms]
isTablet > 767px → false (mobile)
[0.030ms]
isTablet > 768px → true
[0.010ms]
isTablet > 1023px → true
[0.010ms]
isTablet > 1024px → false (desktop)
[0.010ms]
isDesktop > 1023px → false (tablet)
[0.040ms]
isDesktop > 1024px → true
[0.030ms]
isDesktop > 1440px → true (xl)
[0.020ms]
isDesktop > 375px → false (mobile)
[0.020ms]
getBreakpoint > xs starts at 0, ends at 479
[0.120ms]
getBreakpoint > sm starts at 480, ends at 767
[0.030ms]
getBreakpoint > md starts at 768, ends at 1023
[0.020ms]
getBreakpoint > lg starts at 1024, ends at 1439
[0.020ms]
getBreakpoint > xl starts at 1440, no upper bound
[0.030ms]
getAllBreakpoints > returns 5 breakpoints
[0.020ms]
getAllBreakpoints > breakpoints are in ascending order by minWidth
[0.050ms]
getAllBreakpoints > breakpoints form contiguous ranges (no gaps)
[0.040ms]
compactor routes > session_compactor → /projects/:id/sessions/:sid/compactor
[0.080ms]
compactor routes > session_compaction_detail → /projects/:id/sessions/:sid/compactor/:compactionId
[0.010ms]
compactor routes > project_compactor → /projects/:id/compactor
[0.010ms]
compactor routes > buildPath resolves session compactor
[0.350ms]
compactor routes > buildPath resolves session compaction detail
[0.060ms]
compactor routes > buildPath resolves project compactor
[0.040ms]
compaction query keys > session compactions key is stable
[0.040ms]
compaction query keys > single compaction key is stable
[0.030ms]
compaction api types > request and response shapes compile
[0.180ms]
compactionStatusBadge > success badge contract
[0.030ms]
compactionStatusBadge > fallback badge contract
[0.010ms]
compactionStatusBadge > failed badge contract
[0ms]
compactionStatusBadge > in_progress badge contract
[0ms]
compaction indicator color thresholds > below 60% is green
[0.040ms]
compaction indicator color thresholds > 60-84% is amber
[0.020ms]
compaction indicator color thresholds > 85%+ is magenta
[0.020ms]
context indicator route > session compactor route remains stable
[0.030ms]
context estimate query keys > context estimate key is stable
[0.040ms]
context estimate api types > response shape compiles
[0.050ms]
context indicator color thresholds > below 60% is green
[0.060ms]
context indicator color thresholds > 60-84% is amber
[0.030ms]
context indicator color thresholds > 85%+ is magenta
[0.030ms]
CornerBrackets types > three tones are valid
[0.030ms]
CornerBrackets types > two weights are valid
[0.020ms]
CornerBrackets tone mapping > amber tone uses --color-amber CSS var
[0.020ms]
CornerBrackets tone mapping > dim tone uses --color-text-dim CSS var
[0.010ms]
CornerBrackets tone mapping > magenta tone uses magenta accent
[0.020ms]
CornerBrackets weight mapping > hairline is 50% opacity
[0.010ms]
CornerBrackets weight mapping > visible is 100% opacity
[0.010ms]
EmptyState types > message-only props are valid
[0.040ms]
EmptyState types > message + action props are valid
[0.070ms]
getRoutePattern (guest routes) > guest_login → /g/login
[0.030ms]
getRoutePattern (guest routes) > guest_setup → /g/setup
[0.020ms]
getRoutePattern (guest routes) > guest_logout → /g/logout
[0.010ms]
getRoutePattern (guest routes) > guest_projects → /g
[0.010ms]
getRoutePattern (guest routes) > guest_project → /g/:project_id
[0.010ms]
getRoutePattern (guest routes) > guest_project_workflows → /g/:project_id/workflows
[0.010ms]
getRoutePattern (guest routes) > guest_project_workflow → /g/:project_id/workflows/:name
[0.020ms]
getRoutePattern (guest routes) > guest_project_runs → /g/:project_id/runs
[0.010ms]
getRoutePattern (guest routes) > guest_project_run → /g/:project_id/runs/:run_id
[0.010ms]
getRoutePattern (guest routes) > guest_project_issues → /g/:project_id/issues
[0.010ms]
getRoutePattern (guest routes) > guest_project_issue_new → /g/:project_id/issues/new
[0.010ms]
getRoutePattern (guest routes) > guest_project_issue → /g/:project_id/issues/:number
[0.020ms]
getRoutePattern (guest routes) > guest_account → /g/account
[0.010ms]
getRoutePattern (guest routes) > guest_account_sessions → /g/account/sessions
[0.010ms]
buildPath (guest routes) > guest_login (no params)
[0.030ms]
buildPath (guest routes) > guest_setup (no params)
[0.030ms]
buildPath (guest routes) > guest_logout (no params)
[0.020ms]
buildPath (guest routes) > guest_projects (no params)
[0.030ms]
buildPath (guest routes) > guest_project with project_id
[0.040ms]
buildPath (guest routes) > guest_project_workflows with project_id
[0.040ms]
buildPath (guest routes) > guest_project_workflow with project_id and name
[0.040ms]
buildPath (guest routes) > guest_project_runs with project_id
[0.020ms]
buildPath (guest routes) > guest_project_run with project_id and run_id
[0.030ms]
buildPath (guest routes) > guest_project_issues with project_id
[0.040ms]
buildPath (guest routes) > guest_project_issue_new with project_id
[0.030ms]
buildPath (guest routes) > guest_project_issue with project_id and number
[0.030ms]
buildPath (guest routes) > guest_account (no params)
[0.030ms]
buildPath (guest routes) > guest_account_sessions (no params)
[0.020ms]
buildPath (guest routes) > encodes special characters in guest params
[0.020ms]
buildPath (guest routes) > throws on missing project_id for guest_project
[0.090ms]
buildPath (guest routes) > throws on missing name for guest_project_workflow
[0.060ms]
getAllRoutes (guest inclusion) > includes 14 guest routes
[0.020ms]
getAllRoutes (guest inclusion) > all guest route patterns start with /g
[0.040ms]
getAllRoutes (guest inclusion) > no duplicate guest route ids
[0.110ms]
getAllRoutes (guest inclusion) > no duplicate guest route patterns
[0.050ms]
KanjiGlyph types > three sizes are valid
[0.040ms]
KanjiGlyph types > three glow modes are valid
[0.030ms]
KanjiGlyph size mapping > sm maps to text-base
[0.020ms]
KanjiGlyph size mapping > md maps to text-2xl
[0.020ms]
KanjiGlyph size mapping > lg maps to text-6xl
[0.010ms]
KanjiGlyph size mapping > all sizes include leading-none
[0.050ms]
KanjiGlyph glow spec > glow amber radial opacity is 12%
[0.020ms]
KanjiGlyph glow spec > glow transition duration is 200ms
[0.010ms]
KanjiGlyph pulse spec > pulse animation class follows naming convention
[0.010ms]
launch route > launch route pattern is /launch
[0.030ms]
launch route > buildPath for launch needs no params
[0.030ms]
getApiBase > returns /api/v1 by default (no KAGED_UI_API_BASE set)
[0.030ms]
getApiBase > returns a string
[0.020ms]
getApiBase > does not have trailing slash
[0.030ms]
avatarLetter > extracts first letter uppercased from normal name
[0.060ms]
avatarLetter > extracts first letter from single-char name
[0.020ms]
avatarLetter > handles already-uppercase name
[0.020ms]
avatarLetter > returns ? for empty string
[0.020ms]
avatarLetter > returns ? for whitespace-only string
[0.010ms]
avatarLetter > trims leading whitespace before extracting
[0.020ms]
avatarLetter > handles numeric first character
[0.020ms]
avatarLetter > handles unicode first character
[0.020ms]
avatarColor > returns a value from AVATAR_PALETTE
[0.930ms]
avatarColor > is deterministic — same id returns same color
[0.060ms]
avatarColor > different ids can produce different colors
[0.360ms]
avatarColor > handles empty string without throwing
[0.030ms]
avatarColor > handles very long id
[0.140ms]
avatarColor > single-char ids produce valid palette entries
[0.070ms]
AVATAR_PALETTE > has exactly 8 entries
[0.020ms]
AVATAR_PALETTE > includes brand colors
[0.030ms]
AVATAR_PALETTE > all entries are non-empty strings
[0.040ms]
StateDot types > all four colours are valid StateDotColor values
[0.040ms]
StateDot types > both sizes are valid
[0.020ms]
StateDot colour mapping > each colour maps to a bg- class
[0.080ms]
StateDot colour mapping > amber maps to bg-amber
[0.020ms]
StateDot colour mapping > cyan maps to bg-cyan
[0.020ms]
StateDot colour mapping > magenta maps to bg-magenta
[0.020ms]
StateDot colour mapping > dim maps to bg-text-dim
[0.010ms]
StateDot pulse spec > pulse animation class name follows naming convention
[0.020ms]
StatusBadge types > all variants have bracket-lock labels
[0.080ms]
StatusBadge types > all variants have required class fields
[0.070ms]
StatusBadge types > only PENDING and DRAFT pulse
[0.050ms]
StatusBadge types > danger variants use magenta text
[0.040ms]
StatusBadge types > CAGED uses magenta-faint bg, UNCAGED uses magenta-dim bg
[0.030ms]
StatusBadge types > amber signal variants use amber text
[0.040ms]
StatusBadge types > dim variants use text-dim
[0.040ms]
StatusBadge types > EXIT label format for display with value
[0.020ms]
TabBarTab props > minimal tab props
[0.050ms]
TabBarTab props > active tab
[0.030ms]
TabBarTab props > compact mode hides label for inactive tabs
[0.030ms]
TabBarTab props > compact mode shows label for active tab
[0.020ms]
TabBarTab props > onActivate and onClose callbacks fire
[0.080ms]
TabBarTab props > activity data accepts all StateDotColor values
[0.060ms]
TabBarAction props > onClick is required
[0.050ms]
TabBarAction props > label is optional
[0.020ms]
TabBarSubInfo props > breadcrumb is required, actions are optional
[0.030ms]
TabBarSubInfo props > actions slot is accepted
[0.020ms]
TabBar container props > children is required, prependSlot is optional
[0.020ms]
TabBar container props > prependSlot accepted for back-chevron
[0.020ms]
Tab strip spec compliance > global mode tabs are route-bound and not closeable
[0.050ms]
Tab strip spec compliance > project mode tabs are object-bound and closeable
[0.040ms]
Tab strip spec compliance > session opening registers a single session tab
[0.030ms]
KAGED_TERMINAL_THEME > background matches spec --bg-inset
[0.030ms]
KAGED_TERMINAL_THEME > foreground matches spec --text-primary
[0.020ms]
KAGED_TERMINAL_THEME > cursor matches spec --amber
[0.020ms]
KAGED_TERMINAL_THEME > red matches spec --magenta
[0.020ms]
KAGED_TERMINAL_THEME > cyan matches spec --cyan
[0.010ms]
KAGED_TERMINAL_THEME > has all 21 color properties
[0.040ms]
KAGED_TERMINAL_THEME > all values are hex color strings
[0.080ms]
DEFAULT_TERMINAL_CONFIG > fontFamily uses literal font stack for xterm.js renderer
[0.020ms]
DEFAULT_TERMINAL_CONFIG > fontSize is 14
[0.010ms]
DEFAULT_TERMINAL_CONFIG > lineHeight is 1.0 so TUI box-drawing stays aligned
[0.010ms]
DEFAULT_TERMINAL_CONFIG > scrollback is 10000
[0.020ms]
DEFAULT_TERMINAL_CONFIG > theme is the KAGED_TERMINAL_THEME
[0.010ms]
BottomBar types > BottomBarProps accepts children
[0.030ms]
BottomBarSidebarZone props > expanded defaults to undefined (component defaults to true)
[0.020ms]
BottomBarSidebarZone props > expanded=true shows sidebar zone
[0.020ms]
BottomBarSidebarZone props > expanded=false hides sidebar zone
[0.020ms]
BottomBarMainZone props > accepts children
[0.020ms]
BottomBarStatus props > dotColor accepts all StateDotColor values
[0.060ms]
BottomBarStatus props > dotPulse is optional
[0.020ms]
BottomBarStatus props > dotPulse=true for degraded daemon
[0.020ms]
BottomBarStatus props > items are middot-separated status text segments
[0.040ms]
BottomBarStatus props > empty items array is valid
[0.030ms]
BottomBarIconButton props > icon and ariaLabel are required
[0.040ms]
BottomBarIconButton props > active=true highlights button amber
[0.020ms]
BottomBarIconButton props > label adds text beside icon
[0.020ms]
BottomBarIconButton props > onClick callback fires
[0.050ms]
BottomBar composition contract > global mode: sidebar zone + main zone with System + status block
[0.060ms]
BottomBar composition contract > project mode: sidebar zone + main zone with Settings/Status/Audit + log toggle + status block
[0.050ms]
BottomBar composition contract > sidebar zone disappears when sidebar is collapsed
[0.020ms]
BottomBar composition contract > global mode has no log toggle
[0.020ms]
BottomBar composition contract > project mode has log toggle
[0.010ms]
BottomBarIconButton active states per spec > collapse icon is amber when sidebar expanded
[0.020ms]
BottomBarIconButton active states per spec > expand icon is amber when sidebar collapsed
[0.020ms]
BottomBarIconButton active states per spec > filter icon has no active state by default
[0.020ms]
resolveGuestAuthGate > pending → loading
[0.080ms]
resolveGuestAuthGate > success → authenticated
[0.030ms]
resolveGuestAuthGate > error with 401 → auth_required
[0.040ms]
resolveGuestAuthGate > error with 403 → auth_required
[0.030ms]
resolveGuestAuthGate > error with 500 → connection_error
[0.030ms]
resolveGuestAuthGate > error with null error object → connection_error
[0.020ms]
isGuestRoute > /g → true
[0.030ms]
isGuestRoute > /g/ → true
[0.020ms]
isGuestRoute > /g/login → true
[0.030ms]
isGuestRoute > /g/setup → true
[0.020ms]
isGuestRoute > /g/proj-1/issues → true
[0.010ms]
isGuestRoute > /g/proj-1/workflows/deploy → true
[0.020ms]
isGuestRoute > / → false
[0.020ms]
isGuestRoute > /launch → false
[0.020ms]
isGuestRoute > /projects/foo → false
[0.020ms]
isGuestRoute > /system → false
[0.010ms]
isGuestRoute > /global → false (prefix match only)
[0.010ms]
isGuestUnauthRoute > /g/login → true
[0.030ms]
isGuestUnauthRoute > /g/setup → true
[0.020ms]
isGuestUnauthRoute > /g/setup/validate → true (startsWith)
[0.020ms]
isGuestUnauthRoute > /g → false
[0.010ms]
isGuestUnauthRoute > /g/account → false
[0.020ms]
isGuestUnauthRoute > /g/proj-1/issues → false
[0.010ms]
isGuestUnauthRoute > /launch → false
[0.010ms]
resolveIdentityType > operator session → operator
[0.030ms]
resolveIdentityType > guest session → guest
[0.020ms]
resolveIdentityType > no session → none
[0.020ms]
resolveIdentityType > both sessions → operator wins
[0.020ms]
shouldRedirectOperatorFromGuest > /g → true (operator should not be on guest routes)
[0.030ms]
shouldRedirectOperatorFromGuest > /g/login → true
[0.010ms]
shouldRedirectOperatorFromGuest > /g/proj-1/issues → true
[0.020ms]
shouldRedirectOperatorFromGuest > / → false
[0.010ms]
shouldRedirectOperatorFromGuest > /projects/foo → false
[0.020ms]
shouldRedirectGuestFromOperator > / → true (guest should not be on operator routes)
[0.030ms]
shouldRedirectGuestFromOperator > /projects/foo → true
[0.010ms]
shouldRedirectGuestFromOperator > /system → true
[0.020ms]
shouldRedirectGuestFromOperator > /launch → false (launch is shared)
[0.030ms]
shouldRedirectGuestFromOperator > /g → false (already on guest route)
[0.030ms]
shouldRedirectGuestFromOperator > /g/login → false
[0.010ms]
shouldRedirectGuestFromOperator > /g/proj-1/workflows → false
[0.010ms]
Button types > variant list is exhaustive
[0.030ms]
Button types > size list is exhaustive
[0.030ms]
Button types > type list is exhaustive
[0.020ms]
IconButton types > tone list is exhaustive
[0.030ms]
IconButton types > default size is 26
[7.26ms]
ActionBarItem types > tone list is exhaustive
[0.030ms]
ActionBarItem types > exports as a function
[0.020ms]
ScopeTab types and rendering > kind list is exhaustive
[0.020ms]
ScopeTab types and rendering > system kind renders the kanji tab
[0.610ms]
ScopeTab types and rendering > project kind renders the label text
[0.320ms]
RailItem types and rendering > count is optional at the type level
[0.030ms]
RailItem types and rendering > count > 0 renders the badge span
[0.260ms]
RailItem types and rendering > count 0 or undefined renders no badge
[0.150ms]
PanelToggle types > side list is exhaustive
[0.040ms]
PanelToggle types > open is required and boolean
[0.030ms]
PanelToggle types > exports as a function
[0.020ms]
TextInput types > size list is exhaustive
[0.020ms]
TextInput types > borderless and mono flags are supported
[0.030ms]
TextInput types > default type contracts stay callable
[0.250ms]
Dropdown types > option shape uses string value and label
[0.050ms]
Dropdown types > size list is exhaustive
[0.030ms]
ObjectTab types and rendering > kind list is exhaustive
[0.030ms]
ObjectTab types and rendering > ObjectTab is exported as a function
[0.020ms]
ObjectTab types and rendering > accepts all tab kinds
[0.630ms]
ObjectTab types and rendering > session kind renders BotMessageSquare icon and state dot
[0.140ms]
ObjectTab types and rendering > sourceId is accepted for issue and file tabs
[0.240ms]
RightPaneIcon types > pane list is exhaustive
[0.030ms]
RightPaneIcon types > files pane is not allowed
[0.020ms]
DockRow types > label list is exhaustive
[0.030ms]
DockRow types > DockRow stays callable for both edit modes
[0.390ms]
getRoutePattern > dashboard → /
[0.020ms]
getRoutePattern > launch → /launch
[0.010ms]
getRoutePattern > project → /projects/:id
[0.020ms]
getRoutePattern > session → /projects/:id/sessions/:sid
[0ms]
getRoutePattern > session_history → /projects/:id/sessions/:sid/history
[0ms]
getRoutePattern > project_settings → /projects/:id/settings
[0ms]
getRoutePattern > system → /system
[0ms]
getRoutePattern > system_aliases → /system/aliases
[0ms]
getRoutePattern > system_providers → /system/providers
[0ms]
getRoutePattern > system_plugins → /system/plugins
[0ms]
getRoutePattern > system_guests → /system/guests
[0ms]
getRoutePattern > system_status → /system/status
[0ms]
getRoutePattern > system_audit → /system/audit
[0ms]
buildPath > dashboard (no params)
[0.040ms]
buildPath > project with id param
[1.67ms]
buildPath > session with id and sid params
[0.070ms]
buildPath > session_history with both params
[0.030ms]
buildPath > project_settings with id
[0.020ms]
buildPath > system routes need no params
[0.060ms]
buildPath > system status and audit need no params
[0.030ms]
buildPath > encodes special characters in params
[0.030ms]
buildPath > throws on missing required param
[0.070ms]
buildPath > throws on missing all params for parameterized route
[0.060ms]
getAllRoutes > returns 36 routes (22 operator + 14 guest)
[0.020ms]
getAllRoutes > every route has id and pattern
[0.080ms]
getAllRoutes > no duplicate route ids
[0.070ms]
getAllRoutes > no duplicate patterns
[0.050ms]
shouldShowTodoTab > returns false when todos is undefined
[0.030ms]
shouldShowTodoTab > returns false when todos is empty array
[0.020ms]
shouldShowTodoTab > returns true when todos has at least one item
[0.120ms]
shouldShowTodoTab > returns true even when all todos are completed
[0.030ms]
resolveDefaultSidePanelTab > returns fallback when todos is undefined
[0.030ms]
resolveDefaultSidePanelTab > returns fallback when todos is empty
[0.020ms]
resolveDefaultSidePanelTab > returns fallback when all todos are terminal (completed/abandoned)
[0.090ms]
resolveDefaultSidePanelTab > returns 'todo' when there is a pending todo
[0.030ms]
resolveDefaultSidePanelTab > returns 'todo' when there is an in_progress todo
[0.020ms]
resolveDefaultSidePanelTab > returns 'todo' when mixed active and terminal todos
[0.030ms]
buildSidePanelTabs > without todo tab, returns 3 base tabs
[0.070ms]
buildSidePanelTabs > with todo tab, returns 4 tabs
[0.040ms]
buildSidePanelTabs > todo tab is first when present
[0.020ms]
buildSidePanelTabs > todo tab has label 'Todos'
[0.030ms]
buildSidePanelTabs > base tab order is preserved after todo tab
[0.030ms]
root path special-case > isNavActive > root item (to='/') active on exact '/'
[0.050ms]
root path special-case > isNavActive > root item inactive on any descendant
[0.030ms]
exact flag > isNavActive > exact=true matches only the exact path
[0.030ms]
exact flag > isNavActive > exact=true rejects descendants
[0.030ms]
exact flag > isNavActive > exact=true on non-root item
[0.040ms]
descendant matching (default) > isNavActive > matches exact path
[0.020ms]
descendant matching (default) > isNavActive > matches child paths
[0.030ms]
descendant matching (default) > isNavActive > matches deeply nested descendants
[0.020ms]
descendant matching (default) > isNavActive > rejects unrelated paths
[0.030ms]
descendant matching (default) > isNavActive > rejects path-prefix collision (no trailing slash guard bypass)
[0.020ms]
project session paths > isNavActive > active on exact session path
[0.020ms]
project session paths > isNavActive > active on session sub-route
[0.020ms]
project session paths > isNavActive > inactive on different session
[0.020ms]
project session paths > isNavActive > inactive on parent sessions list
[0.020ms]
works with real nav items > isNavActive > global dashboard item active on '/'
[0.030ms]
works with real nav items > isNavActive > bottom nav System active on /system and /system/*
[0.030ms]
works with real nav items > isNavActive > project Overview (exact) active only on sessions list
[0.060ms]
works with real nav items > isNavActive > project bottom items use descendant matching
[0.110ms]
ShellMode > global and project are the two valid modes
[0.030ms]
ShellMode > modes are string literals (not enums)
[0.020ms]
useShellStore > exposes sidebarExpanded as boolean
[0.170ms]
useShellStore > exposes setSidebarExpanded function
[0.030ms]
useShellStore > exposes toggleSidebar function
[0.030ms]
useShellStore > setSidebarExpanded(false) collapses
[0.090ms]
useShellStore > setSidebarExpanded(true) expands
[0.040ms]
useShellStore > toggleSidebar flips expanded → collapsed
[0.080ms]
useShellStore > toggleSidebar flips collapsed → expanded
[0.040ms]
useShellStore > toggle round-trips: true → false → true
[0.040ms]
useShellStore > toggle round-trips: false → true → false
[0.030ms]
useShellStore > setSidebarExpanded is idempotent
[0.040ms]
MobileBottomNav items > project context returns 5 items (sessions, issues, files, status, settings)
[0.110ms]
MobileBottomNav items > global context returns only Dashboard (no System on mobile)
[0.030ms]
Desktop sidebar item composition > global mode: Dashboard + System = 2 total
[0.030ms]
Desktop sidebar item composition > project mode: Overview + 6 project bottom items = 7 total
[0.050ms]
Desktop sidebar item composition > project items include encoded project id in paths
[0.060ms]
Desktop sidebar item composition > project mode retains more items than global mode
[0.040ms]
Shell structural contracts > sidebar width constants: 140px desktop, 280px mobile drawer
[0.040ms]
Shell structural contracts > shell localStorage key is 'kaged.ui.sidebar.expanded'
[0.010ms]
Shell structural contracts > all nav items have required icon property
[0.050ms]
Shell structural contracts > shell mode is determined by isProjectContext, not stored state
[0.050ms]
makeTabId > produces kind:sourceId format
[0.040ms]
makeTabId > different kinds produce different IDs for the same sourceId
[0.030ms]
makeTabId > same kind+sourceId always returns the same string
[0.030ms]
openSession > useTabStore > creates a single session tab
[0.410ms]
openSession > useTabStore > sets activeTabId to the session tab
[0.110ms]
openSession > useTabStore > session tab uses the provided label
[0.080ms]
openSession > useTabStore > session tab is closeable
[0.050ms]
openSession > useTabStore > opening a different session adds a new tab alongside the old one
[0.150ms]
openSession > useTabStore > opening same session again is a no-op when the tab already exists
[0.060ms]
openSession > useTabStore > re-opening same session after closing it restores the tab
[0.190ms]
openSession > useTabStore > non-session tabs are preserved when a new session opens
[0.070ms]
openSession > useTabStore > different projects are independent
[0.070ms]
openIssue > useTabStore > creates a single issue tab with kind 'issue'
[0.170ms]
openIssue > useTabStore > sets activeTabId to the issue tab
[0.060ms]
openIssue > useTabStore > issue tab uses the provided label
[0.040ms]
openIssue > useTabStore > issue tab is closeable
[0.040ms]
openIssue > useTabStore > sourceId is the string representation of the issue number
[0.040ms]
openIssue > useTabStore > opening same issue again is a no-op
[0.050ms]
openIssue > useTabStore > different projects are independent
[0.070ms]
openIssue > useTabStore > non-issue tabs are preserved when opening an issue
[0.070ms]
openFile > useTabStore > creates a single file tab with kind 'file'
[0.160ms]
openFile > useTabStore > sets activeTabId to the file tab
[0.060ms]
openFile > useTabStore > sourceId is the file path
[0.040ms]
openFile > useTabStore > file tab is closeable
[0.040ms]
openFile > useTabStore > opening same file path again is a no-op
[0.050ms]
openFile > useTabStore > different file paths create different tabs
[0.060ms]
useTabStore > mixed heterogeneous tabs preserve order and fallback activation on close
[0.170ms]
closeTab > useTabStore > removes the targeted tab
[0.100ms]
closeTab > useTabStore > closing the active tab falls back to adjacent tab
[0.080ms]
closeTab > useTabStore > closing a non-active tab does not change activeTabId
[0.070ms]
closeTab > useTabStore > closing the last tab results in null activeTabId
[0.050ms]
activateTab > useTabStore > sets activeTabId to the given tab
[0.150ms]
activateTab > useTabStore > no-op when tabId does not exist in the project
[0.060ms]
clearProject > useTabStore > removes all tabs and sets activeTabId to null
[0.110ms]
clearProject > useTabStore > does not affect other projects
[0.070ms]
getProjectTabs selector > returns empty default for unknown project
[0.050ms]
getProjectTabs selector > returns stored tabs for known project
[0.070ms]
getActiveTab selector > returns null when project has no tabs
[0.040ms]
getActiveTab selector > returns the active StoreTab
[0.060ms]
getActiveTab selector > returns null when activeTabId references a removed tab
[0.040ms]
hydrateProject > no-op when project is already loaded in state
[0.120ms]
hydrateProject > no-op when localStorage has no persisted tabs
[0.040ms]
hydrateProject > loads persisted tabs from localStorage into state
[0.070ms]
hydrateProject > hydrated tabs are visible via getProjectTabs selector
[0.090ms]
hydrateProject > idempotent — second call is a no-op
[0.060ms]
resolveSubagentDot > returns null for empty array
[0.080ms]
resolveSubagentDot > returns null when all subagents are idle
[0.060ms]
resolveSubagentDot > returns null when all subagents are paused
[0.030ms]
resolveSubagentDot > returns null when mix of idle and paused (all quiet)
[0.020ms]
resolveSubagentDot > returns cyan pulse for running subagent
[0.030ms]
resolveSubagentDot > returns magenta no-pulse for failed subagent
[0.030ms]
resolveSubagentDot > returns magenta no-pulse for blocked subagent
[0.030ms]
resolveSubagentDot > running takes priority over failed
[0.020ms]
resolveSubagentDot > running takes priority over blocked
[0.020ms]
resolveSubagentDot > failed takes priority over blocked
[0.030ms]
resolveSubagentDot > running takes priority over all others combined
[0.030ms]
useShellStore — log state > logOpen defaults to false
[0.040ms]
useShellStore — log state > logHeight defaults to LOG_HEIGHT_DEFAULT (240)
[0.020ms]
useShellStore — log state > setLogOpen(true) opens log
[0.040ms]
useShellStore — log state > setLogOpen(false) closes log
[0.030ms]
useShellStore — log state > toggleLog flips false → true
[0.060ms]
useShellStore — log state > toggleLog flips true → false
[0.030ms]
useShellStore — log state > toggleLog round-trips: false → true → false
[0.030ms]
useShellStore — log state > setLogHeight sets height within bounds
[0.040ms]
useShellStore — log state > setLogHeight clamps below LOG_HEIGHT_MIN
[0.040ms]
useShellStore — log state > setLogHeight clamps above LOG_HEIGHT_MAX
[0.030ms]
useShellStore — log state > setLogHeight rounds fractional values
[0.030ms]
useShellStore — log state > LOG_HEIGHT_MIN < LOG_HEIGHT_DEFAULT < LOG_HEIGHT_MAX
[0.030ms]
useShellStore — log state > LOG_HEIGHT_MIN is 120, LOG_HEIGHT_MAX is 600
[0.020ms]
STORAGE_KEYS > sidebarExpanded key
[0.010ms]
STORAGE_KEYS > logOpen key
[0.010ms]
STORAGE_KEYS > logHeight key
[0.010ms]
STORAGE_KEYS > all keys share the kaged.ui prefix
[0.040ms]
Shell store — ADR-35 §5.4 keys > storage keys match ADR-35
[0.090ms]
Shell store — ADR-35 §5.4 keys > lastProjectId defaults to null and round-trips
[0.080ms]
Shell store — ADR-35 §5.4 keys > rightPanelUserToggled defaults to false and can be set
[0.050ms]
Shell store — ADR-35 §5.4 keys > getActivity defaults to sessions and setActivity updates reactive state
[0.130ms]
Shell store — ADR-35 §5.4 keys > loadActivity hydrates from localStorage once and is idempotent
[0.120ms]
Shell store — ADR-35 §5.4 keys > systemActivity defaults to config and round-trips
[0.060ms]
Shell store — ADR-35 §5.4 keys > setSystemActivity persists and updates state
[0.040ms]
Shell store — ADR-35 §5.4 keys > activity state is isolated per project
[0.050ms]
Shell store — ADR-35 §5.4 keys > all ActivityItem values are covered
[0.050ms]
LogFilterState helpers > DEFAULT_LOG_FILTERS has all kinds enabled
[0.030ms]
LogFilterState helpers > LOG_FILTER_KINDS lists all filter kinds
[0.040ms]
LogFilterState helpers > isLogFilterActive reads from filter state
[0.050ms]
LogFilterState helpers > toggleLogFilter flips a single kind
[0.030ms]
LogFilterState helpers > toggleLogFilter is immutable (returns new object)
[0.030ms]
LogFilterState helpers > double-toggle round-trips
[0.030ms]
filterEntries > returns all entries when all filters are enabled and query is empty
[0.060ms]
filterEntries > filters out daemon entries when daemon filter is off
[0.090ms]
filterEntries > filters out multiple kinds
[0.050ms]
filterEntries > all filters off returns empty
[0.030ms]
filterEntries > search query filters by message (case-insensitive)
[0.050ms]
filterEntries > search query combined with kind filter
[0.030ms]
filterEntries > empty entries returns empty
[0.030ms]
filterEntries > no-match search query returns empty
[0.020ms]
PROJECT_LOG_NAV_ITEM > returns a NavItem with label 'Log'
[0.040ms]
PROJECT_LOG_NAV_ITEM > routes to /projects/:id/log
[0.020ms]
PROJECT_LOG_NAV_ITEM > encodes projectId in path
[0.020ms]
PROJECT_LOG_NAV_ITEM > has icon property (ScrollText)
[0.020ms]
PROJECT_LOG_NAV_ITEM > isNavActive works for log route
[0.050ms]
Desktop sidebar item composition (Phase 6a) > project mode: Overview + 6 bottom + Log = 8 total
[0.060ms]
Desktop sidebar item composition (Phase 6a) > global mode still has 2 items (no Log)
[0.020ms]
Desktop sidebar item composition (Phase 6a) > all project mode items include encoded project id
[0.050ms]
Desktop sidebar item composition (Phase 6a) > all 5 project items have icon property
[0.040ms]
isProjectContext > returns false for dashboard
[1.31ms]
isProjectContext > returns false for system
[0.090ms]
isProjectContext > returns false for system status
[0.020ms]
isProjectContext > returns false for system audit
[0.020ms]
isProjectContext > returns false for launch
[0.020ms]
isProjectContext > returns true for project overview
[0.010ms]
isProjectContext > returns true for project settings
[0.020ms]
isProjectContext > returns true for session view
[0.020ms]
isProjectContext > returns true for session history
[0.020ms]
isProjectContext > returns false for bare /projects without id
[0.030ms]
extractProjectId > extracts id from project overview path
[0.050ms]
extractProjectId > extracts id from project settings path
[0.070ms]
extractProjectId > extracts id from session view path
[0.020ms]
extractProjectId > returns null for non-project paths
[0.030ms]
extractProjectId > returns null for bare /projects
[0.020ms]
extractProjectId > handles url-encoded project ids
[0.020ms]
isSystemContext > returns true for /system routes
[0.040ms]
isSystemContext > returns false for non-system routes
[0.030ms]
GLOBAL_NAV_ITEMS > contains exactly one item (Dashboard)
[0.040ms]
BOTTOM_NAV_ITEMS > contains a single System entry
[0.020ms]
PROJECT_NAV_ITEMS > Overview points at /sessions (not the project root) so /projects/:id stays a redirect surface and active-match doesn't bleed into siblings
[0.050ms]
PROJECT_NAV_ITEMS > encodes project id in paths
[0.020ms]
PROJECT_NAV_ITEMS > Overview uses exact-match active state so it does not stay highlighted on /sessions/:sid descendants
[0.020ms]
PROJECT_BOTTOM_NAV_ITEMS > generates Tasks, Guests, Issues, Settings, Status, Audit (project-scoped) replacing global bottom nav
[0.070ms]
PROJECT_BOTTOM_NAV_ITEMS > encodes project id in paths
[0.040ms]
PROJECT_BOTTOM_NAV_ITEMS > targets include Tasks, Guests, Issues, Settings, Status, Audit in order
[0.040ms]
PROJECT_BOTTOM_NAV_ITEMS > bottom items default to descendant-match (no exact flag) so any future child routes inherit the parent highlight
[0.040ms]
truncateSessionId > truncates long ids to 10 chars + ellipsis
[0.040ms]
truncateSessionId > does not truncate ids <= 10 chars
[0.020ms]
truncateSessionId > handles empty string
[0.020ms]
sessionDisplayName > returns label when present
[0.030ms]
sessionDisplayName > returns truncated id when label is null
[0.020ms]
sessionDisplayName > returns truncated id when label is undefined
[0.020ms]
sessionDisplayName > returns truncated id when label is empty string
[0.020ms]
sessionDisplayName > returns truncated id when label is whitespace-only
[0.020ms]
Sidebar types > two modes exist
[0.030ms]
SidebarHeader props > global mode requires no projectName
[0.030ms]
SidebarHeader props > project mode accepts projectName (no back-chevron per ADR-0035 §10.6)
[0.020ms]
SidebarSection props > label is required
[0.020ms]
SidebarItem props > minimal item requires label and to
[0.030ms]
SidebarItem props > active item has active=true
[0.020ms]
SidebarItem props > session item has dotColor and dotPulse
[0.020ms]
SidebarItem props > editable item accepts onEdit callback
[0.040ms]
SidebarItem props > all StateDotColor values are valid for dotColor
[0.040ms]
SidebarItem props > onClick prevents default navigation
[0.040ms]
Tasks section > tasks section uses Terminal icon and is a SidebarSection
[0.040ms]
Tasks section > tasks section auto-hides when empty
[0.020ms]
Tasks section > task items can have confirm badge
[0.020ms]
SidebarFooter props > version defaults accepted when undefined
[0.020ms]
SidebarFooter props > explicit version is passed through
[0.020ms]
Sidebar composition contract > Sidebar accepts children (slot-based composition)
[0.020ms]
Sidebar composition contract > global mode sidebar structure: header + section + footer
[0.040ms]
Sidebar composition contract > project mode sidebar structure: header + sessions + issues + tasks + archive + footer
[0.050ms]