@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]

Mentioned in

Type Document
adr ADR-0016: Streaming-first UI — live data and operator abort are non-negotiable
adr ADR-0019: Workflows are operator-authored, parameterised DSL artifacts agents invoke
adr ADR-0021: Guest UI lives at /g/* — segregated route tree, distinct app shell
adr ADR-0024: Context compaction is kaged-owned, layered, observable, and operator-tunable
adr ADR-0025: Typecheck orchestrates per-package; root tsc is a marker
adr ADR-0028: 3rd-party OAuth provider auth — token lifecycle and credential management
adr ADR-0030: Log streaming via Server-Sent Events
adr ADR-0031: An assistant turn is an ordered transcript of parts, not a flattened bubble
adr ADR-0035: Unified operator shell — scope tabs, activity rail, route-driven chrome, and enforced UI primitives
spec Spec: Agent Harness
spec Spec: Daemon
spec Spec: Operational Logging
spec Spec: Project Terminals