Status
FAIL
1510 executed tests
Passed
1506
99.7% pass rate
Failed
4
 
Duration
15.7s
9.9s vitest + 5.8s android
TS Line Coverage
36.2%
6,655/18,354 TypeScript lines
Total Tests
1510
Pass Rate
99.7%
Line Coverage
36.2%

Vitest

PASS
Pass 1327 Fail 0 62 files Coverage + JSON report

Android

PASS
Pass 176 Fail 0 13 files JUnit + Robolectric on ubuntu

Apple (XCTest)

NOT RUN
Not executed in Pages workflow (requires macOS runner)

Robot Framework

FAIL
Pass 3Fail 4Skip 0
Terminal Output Parsing PASS
Claude Code와 Codex CLI의 터미널 출력을 정확히 해석하는가?
252 passed 0 failed 3 files 266ms
output-parser.test.ts
209 / 209 191ms
OutputParser 209 / 209
basic option parsing › parses clean numbered options with newlines
17.646605000000022ms
basic option parsing › detects (recommended) marker
1.7503319999999576ms
basic option parsing › detects ✔ selected marker
1.0645899999999529ms
basic option parsing › handles both recommended and selected on different options
0.831389999999999ms
basic option parsing › parses full Claude model selector with labels and middle dot
1.2883879999999976ms
ANSI-stripped options › parses concatenated text with · delimiter
0.9286470000000691ms
ANSI-stripped options › extracts version numbers from · delimited labels
0.7112589999999273ms
chunked input debounce › does NOT emit immediately on first chunk
0.5647589999999809ms
chunked input debounce › batches multiple chunks into single emission
2.8988390000000663ms
chunked input debounce › resets debounce timer when new chunk with options arrives
0.7401330000000144ms
chunked input debounce › simulates real /model flow: split across chunks
1.641277999999943ms
model ID date rejection › does NOT parse 20251001 from model ID as option number
1.1730630000000701ms
model ID date rejection › rejects large numbers that look like dates
0.6782799999999725ms
version number rejection › does NOT parse version "4.6" followed by digit as option
0.9610549999999876ms
version number rejection › does NOT parse "6)" from "4.6)" as option 6
0.9214360000000852ms
stale buffer overwrite › newer options overwrite older ones with same index
1.2123530000000073ms
permission prompts › detects Yes/No/Always pattern
1.5154090000000906ms
permission prompts › detects (Y)es/(N)o pattern
1.0094279999999571ms
permission prompts › emits immediately with no debounce
0.7713099999999713ms
permission prompts › sets yes_no_always prompt type
0.6898179999999456ms
permission prompts › sets yes_no prompt type
0.5055309999999054ms
permission prompts › extracts the multi-line question header above yes/no/always options
0.5530919999999924ms
permission prompts › extracts the question from a box-framed permission prompt
0.5539430000000038ms
permission prompts › extracts the inline question from the (Y)es/(N)o line
0.41492399999992813ms
permission prompts › does not mistake box-drawing or footer chrome for a question
0.5289759999999433ms
permission prompts › suppresses false idle from user prompt echo after permission (interactive cooldown)
0.7957470000000058ms
permission prompts › allows real idle after interactive cooldown expires
0.6266630000000077ms
diff prompts › detects (V)iew/(A)pply/(D)eny pattern
0.9488969999999881ms
diff prompts › detects lowercase (a)pply/(d)eny/(v)iew pattern
0.5352149999999938ms
diff prompts › emits immediately with no debounce
0.4504379999999628ms
diff prompts › suppresses false idle from user prompt echo after diff (interactive cooldown)
4.735631000000012ms
various option counts › handles 1 option
0.7488459999999577ms
various option counts › handles 2 options
0.6391810000000078ms
various option counts › handles 5+ options
0.6090960000000223ms
various option counts › handles bullet-style options
0.6570480000000316ms
option updates › emits new options when data changes after first emission
0.7964970000000449ms
spinner cancels option timer › spinner cancels pending option debounce
0.6877339999999776ms
idle vs option debounce › idle prompt is ignored when option debounce is pending
0.8196120000000064ms
idle vs option debounce › idle prompt fires normally when no option debounce is pending
0.7147350000000188ms
interactive prompt during spinner › stops spinner when permission prompt arrives
1.2618270000000393ms
interactive prompt during spinner › stops spinner when diff prompt arrives
0.8100080000000389ms
interactive prompt during spinner › stops spinner when option prompt arrives
0.7608850000000302ms
interactive prompt during spinner › stops spinner when idle prompt arrives in small chunk
0.6179389999999785ms
interactive prompt during spinner › ignores idle prompt in large chunk during spinner (screen redraw)
0.6478749999999991ms
cleanOptionLabel (via parseOptions) › deduplicates exact CamelCase matches
0.5695259999999962ms
cleanOptionLabel (via parseOptions) › preserves labels without · delimiter
0.4704470000000356ms
cleanOptionLabel (via parseOptions) › removes (recommended) from label text
0.4914090000000897ms
cleanOptionLabel (via parseOptions) › removes ✔ from label text
0.6578799999999774ms
cleanOptionLabel (via parseOptions) › extracts version from identity before middle dot
0.47056799999995746ms
metadata events › emits project_name from startup banner
0.5176890000000185ms
metadata events › emits project_name only once (caches)
0.45633699999996225ms
metadata events › parses absolute path for project_name
0.4141429999999673ms
metadata events › emits model_info with model and plan
0.48202500000002146ms
metadata events › emits model_info without plan
0.4390399999999772ms
metadata events › emits model_info only once for same model (caches)
0.34975500000007287ms
metadata events › re-emits model_info when model changes
0.4222750000000133ms
metadata events › parses ANSI-stripped model_info
0.4583499999999958ms
metadata events › detects API billing plan
0.39048700000000736ms
metadata events › emits status_line with duration and tokens
0.4691450000000259ms
metadata events › parses zero-minute status line
0.4848190000000159ms
metadata events › emits tool_action from ⏺ pattern
0.4684939999999642ms
metadata events › extracts various tool names
0.3533909999999878ms
user prompt › emits user_prompt after first idle has been seen
0.5965370000000121ms
user prompt › does NOT emit user_prompt before first idle
0.4378590000000031ms
user prompt › filters out mode banner text
0.4695759999999609ms
user prompt › filters out numbered option lines
0.4112480000000005ms
user prompt › filters out keyboard hint text
0.5140129999999772ms
user prompt › filters out "esc to interrupt" text
0.6218149999999696ms
user prompt › filters out autocomplete suggestions
1.2881869999999935ms
user prompt › filters out box-drawing decorative lines
0.46186499999998887ms
usage info › parses usage percentage
0.5759160000000065ms
usage info › parses usage cost
0.5824660000000677ms
usage info › parses session percentage with hour limit
0.5104179999999587ms
usage info › parses reset time with timezone
0.44334700000001703ms
usage info › parses time remaining
0.7004630000000134ms
spinner lifecycle › emits spinner_start on spinner char (after idle seen)
0.7263020000000324ms
spinner lifecycle › does NOT emit spinner_start before first idle
0.594793999999979ms
spinner lifecycle › emits spinner_stop after debounce (2000ms)
0.5906880000000001ms
spinner lifecycle › does NOT emit duplicate spinner_start on repeated chars
0.5407830000000331ms
spinner lifecycle › resets spinner debounce timer on repeated chars
0.5925509999999576ms
spinner lifecycle › ignores spinner chars in large text blocks (>80 non-ws)
0.5365870000000541ms
spinner lifecycle › recognizes all spinner characters
1.1366590000000087ms
idle detection › emits idle after IDLE_DEBOUNCE_MS (300ms)
0.6535629999999628ms
idle detection › sets seenFirstIdle on first idle prompt
0.7365280000000212ms
idle detection › cancels idle timer when spinner starts
0.7688060000000405ms
idle detection › recognizes > as idle prompt char
0.5732419999999365ms
mode detection › detects plan mode
0.5538930000000164ms
mode detection › detects accept edits mode
0.45251999999993586ms
mode detection › detects default mode after Shift+Tab
0.4773569999999836ms
mode detection › detects default mode via idle prompt after Shift+Tab
0.47005699999999706ms
mode detection › emits default mode on Shift+Tab timeout (2s)
0.43572500000004766ms
mode detection › detects ANSI-stripped plan mode text
0.5032870000000003ms
mode detection › detects ANSI-stripped accept edits text
0.4064009999999598ms
mode detection › clears pending mode switch when mode banner is detected
0.4938130000000456ms
reset › clears cached project name and model name
0.5814040000000205ms
reset › disables spinner detection (clears seenFirstIdle)
0.4585890000000745ms
reset › allows re-detection after new idle prompt post-reset
0.45903099999998176ms
reset › allows re-detection of project name after reset
0.3896759999998949ms
reset › allows re-detection of model info after reset
0.36078299999996943ms
buffer management › truncates buffer when exceeding 8192 chars
0.8612650000000031ms
buffer management › keeps the last 4096 chars after truncation
1.1883269999999584ms
option navigation › cursor movement during option selection does NOT trigger idle
0.8768280000000459ms
option navigation › cursor movement does NOT trigger user_prompt
0.7194020000000592ms
option navigation › normal cursor movement between options emits no idle or user_prompt
0.656977999999981ms
option navigation › real idle prompt still works after option navigation
0.7554660000000695ms
option navigation › effort/hint text during navigation does not trigger events
0.7465230000000247ms
option navigation › IDLE_PROMPT requires space/tab/NBSP after ❯ (not newline)
0.5026459999999133ms
option navigation › USER_PROMPT requires space/tab after ❯ (not newline)
3.5338440000000446ms
permission reclassification › reclassifies numbered Yes/No options as permission_prompt
1.201547000000005ms
permission reclassification › does NOT reclassify regular options as permission
0.8484250000000202ms
permission reclassification › does NOT reclassify cursor-selection UI with "Enter to confirm" as permission
0.691569999999956ms
permission reclassification › detects cursor-selection UI even when ANSI stripping removes spaces
0.5927110000000084ms
permission reclassification › includes navigable and cursorIndex in reclassified permission_prompt
0.8106989999999996ms
permission reclassification › infers shortcuts for reclassified permission options
1.0385420000000067ms
permission reclassification › infers shortcut "a" for "don't ask again" labels
0.8144250000000284ms
permission reclassification › infers shortcut "a" for "allow all sessions" labels
0.9721609999999146ms
ghost text suggestion › detects SGR 90 (bright black) ghost text on prompt line
5.708352999999988ms
ghost text suggestion › detects ghost text via Strategy 1 (Try "..." in clean text)
0.6041889999999057ms
ghost text suggestion › unwraps Try "..." wrapper with smart quotes
0.7147749999999178ms
ghost text suggestion › unwraps Try "..." wrapper with straight quotes
0.5867419999999584ms
ghost text suggestion › detects ghost text on first idle (❯ and suggestion in same chunk)
0.664519999999925ms
ghost text suggestion › clears suggestion on spinner start
0.8610950000000912ms
ghost text suggestion › debounces rapid updates
0.8432980000000043ms
ghost text suggestion › ignores dim (SGR 2) text without ❯ prompt context
0.773192999999992ms
ghost text suggestion › detects dim (SGR 2) ghost text on ❯ prompt line
0.6470129999999017ms
ghost text suggestion › detects ghost text with cursor-forward spacing (Strategy 1)
2.0082949999999755ms
ghost text suggestion › filters UI chrome fragments
0.9797929999999724ms
ghost text suggestion › filters box-drawing lines as UI chrome
0.7289059999999381ms
ghost text suggestion › filters file paths (false positive from screen redraws)
3.3125109999999722ms
ghost text suggestion › detects 256-color gray ghost text
0.7047800000000279ms
ghost text suggestion › handles multi-segment ghost text on prompt line
0.8862129999999979ms
ghost text suggestion › ignores ghost text on non-prompt lines
2.15128500000003ms
ghost text suggestion › detects 24-bit RGB gray ghost text
0.7562970000000178ms
ghost text suggestion › ignores 24-bit RGB non-gray colors (e.g. blue prompt char)
0.647544000000039ms
ghost text suggestion › filters out short gray text like prompt char itself
0.8046199999999999ms
ghost text suggestion › suppresses ghost text detection during spinner (processing)
0.7403329999999642ms
ghost text suggestion › rejects digit+operator fragments like diff markers "96 +"
0.7886460000000852ms
ghost text UI chrome filtering › filters out "Tip:" segments on prompt line
0.7530719999999747ms
ghost text UI chrome filtering › filters out "(ctrl+...)" shortcut hints on prompt line
0.6352550000000292ms
ghost text UI chrome filtering › filters concatenated UI chrome even in scheduleSuggestion
0.6031169999999975ms
ghost text UI chrome filtering › keeps ghost text when UI chrome is also present on the line
0.7693870000000516ms
filters out extended thinking indicators › rejects "(thought for 1s)" as ghost text via isUiChrome
0.654694999999947ms
filters out extended thinking indicators › rejects "(thought for 1s)>" via scheduleSuggestion
0.6161759999999958ms
filters out extended thinking indicators › rejects longer thinking durations like "(thought for 15s)"
0.5626160000000482ms
filters out extended thinking indicators › rejects "(thought for 1m 30s)" multipart duration
0.6321900000000369ms
filters out extended thinking indicators › rejects "✻ Cooked for 1m 26s" sparkle indicator
0.5407330000000456ms
filters out extended thinking indicators › rejects "✻ Cooked for 5s" short duration variant
0.7060020000000122ms
filters out extended thinking indicators › rejects "Cooked for 10s" without sparkle (cross-chunk)
0.7940140000000611ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 2 (dim)
0.6757959999999912ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 90 (bright black)
0.7438690000000179ms
parenthesized placeholder filtering › rejects "(loading...)"
0.6721400000000131ms
parenthesized placeholder filtering › rejects "(empty)"
0.6890859999999748ms
parenthesized placeholder filtering › rejects "(waiting for response)"
1.005582000000004ms
parenthesized placeholder filtering › allows "fix the broken (auth) module" — parens in middle
0.6764570000000276ms
parenthesized placeholder filtering › allows "(optional) refactor the code" — paren prefix with text after
0.6592009999999391ms
stacked ANSI + cross-chunk ghost text › detects ghost text with stacked ANSI escapes (gray + italic)
0.6206730000000107ms
stacked ANSI + cross-chunk ghost text › detects ghost text with combined SGR params (2;90 = dim+bright-black)
0.5296170000000302ms
stacked ANSI + cross-chunk ghost text › detects cross-chunk ghost text (❯ and gray text in separate feeds)
1.102608000000032ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when chunk contains ⎿ output fence
0.7316100000000461ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when new chunk has \n (different line)
0.6519710000000032ms
ghost option from stale buffer › excludes stale numbered list items before actual option prompt
1.1473150000000487ms
ghost option from stale buffer › bypasses chunk size guard when ❯ cursor is present in large chunk
0.9055209999999079ms
ghost option from stale buffer › still works with scrambled TUI order after backward scan
0.7089760000000069ms
ghost option from stale buffer › excludes file path fragments from Read() tool in permission prompt
0.995777999999973ms
option index ordering › returns options sorted by index even when TUI lines arrive out of order
1.0436489999999594ms
split ANSI sequence buffering › handles ANSI SGR codes split across chunks
0.9850110000000996ms
split ANSI sequence buffering › handles bare ESC at end of chunk
0.8354759999999715ms
split ANSI sequence buffering › does not buffer complete ANSI sequences
0.6124109999999519ms
large chunk guard for option detection › does NOT detect numbered items in large response chunks as options
0.6186999999999898ms
large chunk guard for option detection › still detects real options in small TUI chunks
0.711810000000014ms
CUP-positioned options › parses options using CUP (\x1b[row;colH) instead of newlines
1.1495089999999664ms
CUP-positioned options › parses options using CUD (\x1b[B) for vertical movement
1.0261130000000094ms
trailing TUI chrome stripping › strips "Esc to cancel" from last option label
0.9666140000000496ms
trailing TUI chrome stripping › strips "Enter to confirm" from last option label
0.6340440000000171ms
trailing TUI chrome stripping › does NOT strip "Esc" when it appears within legitimate label text
0.6979400000000169ms
CJK suggestion detection › accepts ghost text containing CJK characters
1.957033000000024ms
CJK suggestion detection › accepts ghost text that is purely CJK (no ASCII words)
0.9527830000000677ms
AskUserQuestion with separators and descriptions › handles AskUserQuestion with separator and descriptions
0.861295000000041ms
AskUserQuestion with separators and descriptions › handles options starting from non-zero index (buffer truncation)
1.0382710000000088ms
hierarchical CC prompt shapes › captures 5-option plan approval with long labels
1.0327429999999822ms
hierarchical CC prompt shapes › captures OpenClaw scope selection (numbered list)
0.9713299999999663ms
hierarchical CC prompt shapes › captures OpenClaw token-action step (short numbered list)
0.9005640000000312ms
permission scroll does not trigger idle (Bug 1) › scroll chunk with ❯ option text does NOT cause idle when navigable
1.004359999999906ms
permission scroll does not trigger idle (Bug 1) › /model combined chunk: confirmation + idle prompt clears options
0.8459729999999581ms
permission scroll does not trigger idle (Bug 1) › /model separate chunks: ANSI reposition timer does not block idle
0.6753760000000284ms
permission scroll does not trigger idle (Bug 1) › cursor move chunk with option text does NOT falsely trigger idle
3.6277039999999943ms
permission scroll does not trigger idle (Bug 1) › genuine idle prompt exits navigable state and emits idle
0.878641000000016ms
TUI cursor-overwrite label correction (Bug 2) › fixes contaminated permission option label using correction line
0.9794630000000097ms
TUI cursor-overwrite label correction (Bug 2) › leaves labels unchanged when no correction line is present
0.6139630000000125ms
genuine idle detection (semantic) › "❯ \n" is genuine idle — only prompt character, no label text
0.5317490000001044ms
genuine idle detection (semantic) › "❯ Beta" is NOT idle — has label text after prompt char
0.571739999999977ms
genuine idle detection (semantic) › "❯ A" is NOT idle — single-char label still counts
0.8095680000000129ms
genuine idle detection (semantic) › ">" also treated as idle prompt character
0.6070029999999633ms
effort level parsing › detects "High effort" selection pattern
0.5859910000000355ms
effort level parsing › detects "Medium effort" selection pattern
0.39903000000003885ms
effort level parsing › detects "Low effort" selection pattern
0.40985699999998815ms
effort level parsing › detects "with high effort" confirmation line
0.37825899999995727ms
effort level parsing › detects effort in model info line
0.3602920000000722ms
effort level parsing › caches effort level — no re-emit on same value
0.49931499999991047ms
effort level parsing › emits on effort level change
0.5530109999999695ms
effort level parsing › resets effort level on reset()
0.42667199999993954ms
effort level parsing › does not match "effort" in unrelated context
0.3275730000000294ms
effort level parsing › does not match effort inside numbered option lines
0.5768870000000561ms
effort level parsing › getter returns current effort level
0.3760860000001003ms
effort level parsing › detects "Max effort" (Opus 4.7 variant)
0.4945740000000569ms
effort level parsing › detects "xhigh effort" (Opus 4.7 variant)
0.5061309999999821ms
effort level parsing › detects "default effort" (per-model default variant)
0.5475430000000188ms
effort level parsing › detects "fast effort" (Opus 4.6 variant)
0.5167269999999462ms
effort level parsing › detects effort in /model confirmation line with max
0.5308489999999892ms
codex-output-parser.test.ts
28 / 28 38ms
CodexOutputParser 28 / 28
idle detection › emits idle on ❯ prompt with source=prompt
12.192633ms
idle detection › emits idle on > prompt
1.7397080000000074ms
idle detection › debounces rapid idle signals
0.7767790000000048ms
spinner detection › emits spinner_start on braille spinner chars after first idle
1.3786049999999932ms
spinner detection › does not emit spinner_start before first idle
0.9055830000000071ms
spinner detection › emits spinner_stop + idle on timeout with source=timeout
0.9589829999999893ms
spinner detection › emits spinner_stop when idle prompt appears
0.658411000000001ms
spinner detection › detects "Thinking" text as processing
0.6393020000000149ms
permission prompt detection › emits permission_prompt on Allow/Deny pattern
1.7807300000000055ms
permission prompt detection › emits permission_prompt on y/n pattern
0.9115819999999815ms
permission prompt detection › stops spinner when approval detected
0.6640289999999993ms
permission prompt detection › extracts Allow once / Always allow options
0.7808950000000152ms
tool action detection › detects Running: command pattern
3.120808000000011ms
tool action detection › detects file operation patterns
0.8777809999999988ms
tool action detection › detects Editing file pattern
0.8563989999999819ms
tool action detection › dedups repeated emits of the same (tool, args) within window
0.6370189999999809ms
tool action detection › emits a different command immediately
0.5931230000000198ms
tool action detection › re-emits the same command after the dedup window elapses
0.5761179999999797ms
tool action detection › re-emits the same command after a turn boundary (idle resets dedup)
0.7410450000000139ms
model info detection › detects gpt model name
0.6726519999999994ms
model info detection › detects o-series model
0.6556770000000256ms
model info detection › does not re-emit same model
0.5356360000000109ms
project name detection › detects working directory
0.9887080000000026ms
project name detection › detects project from path
0.7098790000000008ms
project name detection › only detects project name once
0.645702ms
buffer management › truncates buffer at 8192 chars
0.6138640000000066ms
buffer management › handles incomplete ANSI sequences
0.7121119999999905ms
getProjectName › returns null when no project detected
0.5663729999999987ms
cursor-sync.test.ts
15 / 15 38ms
Cursor Synchronization 15 / 15
terminal keyboard cursor tracking › emits cursor_update when full option redraw arrives with ❯ at new position
17.810108999999954ms
terminal keyboard cursor tracking › triggers buffer re-parse on small non-❯ chunk during navigable state
4.703710000000001ms
terminal keyboard cursor tracking › does not emit cursor_update when cursor position unchanged
1.2314530000000445ms
genuine idle distinction › treats "❯ \n" as genuine idle (clears navigable state)
1.17646000000002ms
genuine idle distinction › does NOT treat "❯ Beta" as idle (cursor on option label)
1.4692719999999895ms
genuine idle distinction › does NOT treat "❯ Allow once" as idle (permission cursor move)
1.8176859999999806ms
cursor authority in StateMachine › accepts optimistic update immediately
2.1004819999999995ms
cursor authority in StateMachine › suppresses stale PTY value within 200ms of optimistic update
0.7360180000000014ms
cursor authority in StateMachine › accepts PTY value after 200ms grace period
1.4201780000000213ms
cursor authority in StateMachine › always accepts PTY when no recent optimistic update
0.6381409999999619ms
cursor authority in StateMachine › resets authority on state transition out of AWAITING
0.9213059999999587ms
cursor authority in StateMachine › default source parameter is pty
0.6177989999999909ms
select_option proportional delay › delay scales with step count
0.6451509999999985ms
option re-emission with cursorIndex › AWAITING_OPTION update triggers state_changed with options
0.9605960000000096ms
option re-emission with cursorIndex › updateCursorIndex emits snapshot with new cursor value
0.7912809999999695ms
State Machine & Adapters PASS
에이전트의 상태 전이와 타입별 명령 라우팅이 정확한가?
178 passed 0 failed 3 files 196ms
state-machine.test.ts
60 / 60 56ms
StateMachine 60 / 60
basic transitions › starts in DISCONNECTED
6.937761999999964ms
basic transitions › SessionStart → IDLE
1.4119230000000016ms
basic transitions › UserPromptSubmit → PROCESSING
1.1448220000000333ms
basic transitions › Stop → IDLE from PROCESSING
0.8645400000000336ms
basic transitions › SessionEnd → DISCONNECTED from any state
0.6590810000000147ms
permission flow › permission_prompt → AWAITING_PERMISSION
1.1376410000000305ms
permission flow › user respond → PROCESSING from AWAITING_PERMISSION
0.6046589999999696ms
option flow › option_prompt → AWAITING_OPTION
0.6373689999999783ms
option flow › select_option → PROCESSING from AWAITING_OPTION
0.5424460000000408ms
option flow › option_prompt carries the question into the snapshot
0.5897060000000351ms
diff flow › diff_prompt → AWAITING_DIFF
0.6421459999999684ms
diff flow › respond → PROCESSING from AWAITING_DIFF
0.8514199999999619ms
interrupt › interrupt → IDLE from PROCESSING
0.6005230000000097ms
interrupt › interrupt → IDLE from AWAITING_PERMISSION
0.7084750000000213ms
strict transitions › allows IDLE → AWAITING_PERMISSION (prompt without spinner)
0.6391910000000394ms
strict transitions › blocks invalid transition: DISCONNECTED → PROCESSING
0.5608839999999873ms
strict transitions › allows wildcard session_end from any state
0.6933329999999955ms
stuck timeout › PROCESSING for >5min → auto-recovery to IDLE
1.3146970000000238ms
stuck timeout › AWAITING_PERMISSION survives the 5min PROCESSING window but recovers after the 10min backstop
6.041193999999962ms
stuck timeout › AWAITING_OPTION recovers after the 10min backstop
0.7527719999999931ms
stuck timeout › AWAITING_DIFF recovers after the 10min backstop
0.6904480000000035ms
stuck timeout › AWAITING backstop resets when the user responds (no false recovery)
0.739011000000005ms
stuck timeout › AWAITING backstop re-arms on PTY activity (silence-based, not a hard cap from entry)
0.9909299999999917ms
stuck timeout › timer resets on state change before timeout
0.7978599999999574ms
stuck timeout › no timeout in IDLE state
0.5220459999999889ms
parser events › spinner_start → PROCESSING from IDLE
0.5547039999999583ms
parser events › spinner_stop → IDLE from PROCESSING
0.5069929999999658ms
parser events › idle → IDLE from PROCESSING
1.6471569999999929ms
parser events › mode_change updates permission mode
0.6625259999999571ms
snapshot › emits state_changed on transitions
0.48651100000000724ms
snapshot › includes tool info in snapshot
0.6269019999999728ms
snapshot › clears tool info on PostToolUse
0.8007939999999962ms
snapshot › includes project name and model
0.6934029999999893ms
billingType detection › defaults to unknown
0.5165069999999901ms
billingType detection › detects subscription from "Claude Max" plan
0.6624659999999949ms
billingType detection › detects subscription from "Max" (case-insensitive)
2.102572000000009ms
billingType detection › detects api from "api.anthropic.com"
0.5689160000000015ms
billingType detection › detects api (case-insensitive)
0.5550549999999816ms
billingType detection › stays unknown for unrecognized plan
0.6608240000000478ms
billingType detection › stays unknown when plan is absent
1.2093029999999771ms
billingType detection › persists billingType across subsequent model_info without plan
0.5804830000000152ms
billingType detection › emits state_changed when billingType is set
0.5584799999999746ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_OPTION to PROCESSING
0.4286250000000109ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_PERMISSION to PROCESSING
0.5166770000000156ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_DIFF to PROCESSING
0.40207500000002483ms
spinner_start recovery from awaiting states › clears options and navigable state on spinner_start from AWAITING_OPTION
1.52864900000003ms
spinner_start recovery from awaiting states › stores navigable and cursorIndex from permission_prompt
0.4222050000000195ms
spinner_start recovery from awaiting states › cursor index tracking via updateCursorIndex
0.5389559999999847ms
cursor authority (optimistic vs pty) › optimistic source updates cursor immediately
0.4052599999999984ms
cursor authority (optimistic vs pty) › suppresses stale PTY within 200ms of optimistic
0.48573099999998703ms
cursor authority (optimistic vs pty) › accepts PTY after 200ms grace period
0.39042700000004515ms
cursor authority (optimistic vs pty) › emits state_changed on optimistic update
0.5631070000000022ms
cursor authority (optimistic vs pty) › does NOT emit state_changed when stale PTY is suppressed
0.5309589999999957ms
codex_* hook events › codex_session_start → IDLE
0.37938099999996666ms
codex_* hook events › codex_user_prompt_submit → PROCESSING
0.5603519999999662ms
codex_* hook events › codex_tool_start sets currentTool from tool_name
0.7058020000000056ms
codex_* hook events › codex_tool_end clears currentTool
0.532621000000006ms
codex_* hook events › codex_stop → IDLE from PROCESSING
0.5947550000000206ms
codex_* hook events › codex_turn_complete is a snapshot-emit no-op for state
0.5188699999999926ms
codex_* hook events › full codex lifecycle preserves state transitions
0.5783390000000281ms
adapter.test.ts
93 / 93 104ms
createAdapter factory 5 / 5
creates ClaudeCodeAdapter for "claude-code"
6.45708999999988ms
creates OpenClawAdapter for "openclaw"
1.6348579999998947ms
passes gatewayUrl to OpenClawAdapter
0.4001619999999093ms
creates CodexCliAdapter for "codex-cli"
1.0136139999999614ms
throws for unknown agent type
1.7973930000000564ms
ClaudeCodeAdapter 17 / 17
capabilities › reports all Claude Code capabilities as true
1.2473959999999806ms
handleCommand routing › handles respond → returns true
0.8394120000000385ms
handleCommand routing › handles switch_mode → returns true
0.5349040000000969ms
handleCommand routing › handles interrupt → returns true
0.6123110000000906ms
handleCommand routing › handles escape → returns true
0.3970569999999043ms
handleCommand routing › defers select_option to bridge → returns false
0.40321700000004057ms
handleCommand routing › defers navigate_option to bridge → returns false
0.36800399999992806ms
handleCommand routing › defers send_prompt to bridge → returns false
0.3774479999999585ms
handleCommand routing › defers voice to bridge → returns false
0.39744800000016767ms
handleCommand routing › defers query_usage to bridge → returns false
0.34355600000003506ms
switch_mode debounce › debounces rapid switch_mode calls (< 100ms apart)
1.1417169999999714ms
lifecycle › isAlive returns false before start
0.43939000000000306ms
lifecycle › getTtyPath returns undefined before start
0.4236069999999472ms
lifecycle › getProjectName returns null before start
0.46708300000000236ms
lifecycle › getHttpServer returns an object
0.401794000000109ms
onRawData callback › can register callback without error
0.6196019999999862ms
onDiag handler › can register handler without error
0.5444780000000264ms
OpenClawAdapter 17 / 17
capabilities › reports OpenClaw capabilities correctly
0.641505000000052ms
handleCommand routing › handles respond → returns true (RPC)
0.5856909999999971ms
handleCommand routing › handles select_option → returns true (RPC)
0.35938099999998485ms
handleCommand routing › handles navigate_option → returns true (no-op)
0.28863400000000183ms
handleCommand routing › handles send_prompt → returns false without session key
0.4649890000000596ms
handleCommand routing › handles interrupt → returns true (RPC)
0.3129910000000109ms
handleCommand routing › handles escape → returns true (RPC)
0.29760799999985466ms
handleCommand routing › defers switch_mode → returns false (not supported)
0.2798210000000836ms
handleCommand routing › defers voice to bridge → returns false
0.2643080000000282ms
handleCommand routing › defers query_usage to bridge → returns false
0.2655299999998988ms
lifecycle › isAlive returns false before start
0.2882130000000416ms
lifecycle › getTtyPath returns undefined (no PTY)
0.2400910000001204ms
lifecycle › getProjectName returns null before start
0.2534410000000662ms
lifecycle › getHttpServer returns an object
0.2946829999998499ms
lifecycle › attachTerminal is a no-op
0.6090859999999338ms
onRawData callback › can register callback without error
0.4789700000001176ms
onDiag handler › can register handler without error
0.4423750000000837ms
OpenClawAdapter gateway protocol 13 / 13
sends connect request with correct format on connect.challenge
4.80068899999992ms
becomes alive after hello-ok response
9.268978000000061ms
emits spinner_start on chat delta event
1.1149070000001302ms
emits idle on chat final event
1.118161999999984ms
emits idle on chat aborted event
0.8076340000000073ms
emits idle on chat error event
0.7770479999999225ms
emits permission_prompt on exec.approval.requested
1.0442310000000816ms
sends exec.approval.resolve on respond after approval request
2.9407119999998486ms
sends exec.approval.resolve with deny on respond "n"
0.8300480000000334ms
sends chat.send on send_prompt with active session
1.823011999999835ms
sends chat.abort on interrupt with active session and runId
7.211644999999862ms
emits SessionEnd on shutdown event
1.0277450000000954ms
clears pendingApprovalId on exec.approval.resolved
0.7631980000001022ms
CodexCliAdapter 16 / 16
capabilities › reports Codex CLI capabilities correctly
2.1175940000000537ms
handleCommand routing › handles respond → returns true
0.3679230000000189ms
handleCommand routing › handles interrupt → returns true
0.3224350000000413ms
handleCommand routing › handles escape → returns true
0.3723299999999199ms
handleCommand routing › does not handle switch_mode → returns false
0.3800810000000183ms
handleCommand routing › defers select_option to bridge → returns false
0.32152399999995396ms
handleCommand routing › defers navigate_option to bridge → returns false
0.38495899999998073ms
handleCommand routing › defers send_prompt to bridge → returns false
2.4191779999998744ms
handleCommand routing › defers voice to bridge → returns false
0.38341700000000856ms
handleCommand routing › defers query_usage to bridge → returns false
0.3742929999998523ms
lifecycle › isAlive returns false before start
0.3345930000000408ms
lifecycle › getTtyPath returns undefined before start
0.31136799999990217ms
lifecycle › getProjectName returns null before start
0.3562560000000303ms
lifecycle › getHttpServer returns an object
0.34940599999981714ms
onRawData callback › can register callback without error
0.5123399999999947ms
onDiag handler › can register handler without error
0.5463609999999335ms
CodexCliAdapter start lifecycle 2 / 2
emits SessionStart and connected on start
2.7149329999999736ms
feeds PTY data to output parser and emits activity
3.224708999999848ms
MonitorAdapter 18 / 18
capabilities › reports monitor capabilities correctly
0.9960679999999229ms
handleCommand routing › rejects respond (no PTY)
0.5008430000000317ms
handleCommand routing › rejects interrupt (no PTY)
0.4322700000000168ms
handleCommand routing › rejects escape (no PTY)
0.42004099999985556ms
handleCommand routing › rejects switch_mode (no PTY)
0.5471430000000055ms
handleCommand routing › rejects select_option (no PTY)
0.41318100000012237ms
handleCommand routing › rejects send_prompt (no PTY)
0.3419249999999465ms
handleCommand routing › defers voice to bridge
0.23648499999990236ms
handleCommand routing › defers query_usage to bridge
0.2246380000001409ms
lifecycle › isAlive always returns true
0.39734800000019277ms
lifecycle › getTtyPath returns undefined (no PTY)
0.7622770000000401ms
lifecycle › getProjectName returns null
0.3954439999999977ms
lifecycle › getHttpServer returns an object
0.4040669999999409ms
lifecycle › writeInput is a no-op (no PTY)
0.6122210000000905ms
lifecycle › attachTerminal is a no-op
0.5908890000000611ms
lifecycle › onRawData is a no-op
0.5341730000000098ms
start and event emission › emits connected event on start
0.798860999999988ms
start and event emission › exposes hook server for external wiring
0.44125400000007176ms
ClaudeCodeAdapter start lifecycle 5 / 5
emits SessionStart and connected on start
1.767138000000159ms
uses claude as default command
1.3945269999999255ms
feeds PTY data to output parser and emits activity
4.660788000000139ms
emits SessionEnd and disconnected on PTY exit
3.5211040000001503ms
registers rawData callback without error
3.727836000000025ms
protocol-contract.test.ts
25 / 25 36ms
Protocol Contract — StateUpdateEvent 5 / 5
minimal state_update has required fields
4.624544000000014ms
full state_update has all optional fields as correct types
1.2784029999999689ms
state_update serializes to valid JSON
0.27108799999996336ms
state enum values are lowercase strings
0.5766270000000304ms
promptType values match known set
0.2431760000000054ms
Protocol Contract — UsageEvent 3 / 3
has all required numeric fields
0.3888549999999782ms
rate limit fields are present when available
1.589098999999976ms
tokenStatus matches known values
0.2448880000000031ms
Protocol Contract — SessionsListEvent 2 / 2
sessions have required fields
0.5548939999999902ms
agentType is optional string
0.5060410000000388ms
Protocol Contract — ButtonStateEvent 1 / 1
buttons have required fields
0.66769400000004ms
Protocol Contract — EncoderStateEvent 1 / 1
encoders have required fields
0.583486999999991ms
Protocol Contract — TimelineEventMsg 1 / 1
entry has required fields
0.41070799999999963ms
Protocol Contract — ConnectionEvent 1 / 1
has required fields
0.2870110000000068ms
Protocol Contract — DisplayStateEvent 1 / 1
has boolean displayOn
0.22896500000001652ms
Protocol Contract — PluginCommand shapes 6 / 6
respond command has value
0.24101300000000947ms
select_option has numeric index
0.17158800000004248ms
navigate_option has direction
0.21912000000003218ms
send_prompt has text
0.18740200000002005ms
utility command has action
0.2495450000000119ms
clear_session_focus is fieldless
1.1841009999999983ms
Protocol Contract — BridgeEvent discriminated union 2 / 2
all event types in union have type field
2.9659699999999702ms
SERIAL_FORWARDED_EVENTS covers expected types
17.135291999999993ms
Protocol Contract — Backward Compatibility 2 / 2
state_update can be parsed with only required fields (old client)
0.45634599999999637ms
usage_update required fields are sufficient for display
0.33622600000001057ms
Timeline Pipeline PASS
이벤트 타임라인의 저장, 중복 제거, 세션 간 릴레이가 올바른가?
93 passed 0 failed 3 files 1.3s
timeline.test.ts
53 / 53 16ms
cleanDetailText 12 / 12
returns empty/falsy input unchanged
2.435561999999976ms
strips markdown bold
0.4224760000000174ms
strips markdown headings
0.25690700000001243ms
strips code fences
0.16000999999999976ms
strips inline backticks
0.11201800000000617ms
strips markdown links
0.09546299999999519ms
strips blockquotes
0.09043600000001106ms
strips list markers
0.09125799999998208ms
collapses multiple blank lines
0.0865699999999947ms
filters system JSON blobs (connectionId)
0.09891799999999762ms
extracts error from JSON blob
0.09432200000000535ms
compacts other JSON
0.10556800000000521ms
cleanRawText 2 / 2
strips bold, headings, links, backticks
0.1866200000000049ms
returns empty/falsy unchanged
0.10481699999999705ms
cleanNopMarkers 3 / 3
removes NOP markers
0.2720989999999972ms
collapses resulting blank lines
0.12853300000000445ms
returns empty/falsy unchanged
0.13941900000000373ms
extractSemanticCore 4 / 4
strips duration suffix for chat_end
0.16389699999999152ms
keeps full text for chat_end without separator
0.11635499999999865ms
keeps full text for non-chat_end types
0.1003910000000019ms
trims whitespace
0.10033100000001127ms
isRepetitiveEntry 11 / 11
detects exact duplicate chat_end entries
0.45856000000000563ms
detects keyword-similar entries
0.46183500000000777ms
returns -1 for non-matching entries
0.1799909999999727ms
ignores entries outside window
0.13443200000000388ms
only applies to chat_end, chat_start, and error types
0.16589899999999602ms
dedupes repeated error entries within 1h window
0.1944029999999941ms
matches chat_start entries
0.14885300000000257ms
dedupes automated entries regardless of content
0.1415230000000065ms
does not dedup automated vs non-automated
0.15469200000001138ms
uses 8h window for automated entries
0.14249399999999923ms
expires automated dedup after 8h
0.15960000000001173ms
parseLogLine 21 / 21
returns null for null/undefined/non-object
0.5541929999999979ms
returns null for empty message
0.17457199999998352ms
returns null for model start/complete (suppressed)
0.24057199999998602ms
parses memory/recall (legacy structured)
0.5239080000000058ms
parses tool execution (legacy structured)
0.4220139999999901ms
filters gateway/ws subsystem
0.246249999999975ms
filters infrastructure noise
0.5858410000000163ms
filters channel infra reconnect noise
0.713532999999984ms
filters connection status JSON blobs
0.471888999999976ms
filters transient fetch timeouts
0.26722200000000385ms
filters edit mismatch errors (agent retries)
0.13612499999999272ms
filters failover cascade noise
0.12378599999999551ms
parses genuine errors
0.6530220000000213ms
parses error from message pattern (not level)
0.7627170000000092ms
filters model/inference patterns (suppressed)
0.4939730000000395ms
does not synthesize memory_recall from message text alone
0.2723999999999478ms
does not synthesize tool_exec from message text alone
0.18252499999999827ms
parses ISO timestamp correctly via error pattern
0.2149830000000179ms
falls back to Date.now() for invalid timestamp on error message
0.2679830000000152ms
truncates long tool raw to 500 chars
0.2495850000000246ms
filters whatsapp noise from channel infra subsystem
0.3109969999999862ms
timeline-integration.test.ts
35 / 35 35ms
BridgeTimelineStore 11 / 11
adds and retrieves entries
6.346732999999972ms
filters history by timestamp
0.528615000000002ms
calls listeners on new entries
0.5607540000000313ms
upsert updates existing entry with same ts+type
0.9458619999999769ms
upsert keeps timeline attribution fields
0.5067520000000059ms
upsert adds new entry when no match exists
0.4077839999999924ms
updateEntryStatus updates approval status
0.32116300000001274ms
getLastEntry returns most recent of given type
0.43871999999998934ms
getLastEntry returns null when type not found
0.21985100000000557ms
removeListener stops notifications
0.3396410000000287ms
enforces MAX_ENTRIES (200) with FIFO
7.1662959999999885ms
deduplicateEntry pipeline 5 / 5
exact duplicate within 8s → skip
0.3799410000000307ms
same type, different content → add
0.27438300000000027ms
different type, same raw → add
0.25995100000000093ms
chat_response identical raw 6s apart → skip (PTY/Stop race)
0.4670419999999922ms
chat_response near-duplicate beyond 8s → repetitive merge
0.4042180000000144ms
BridgeTimelineStore.setAttributor — history replay attribution 10 / 10
addEntry passes the entry through the attributor before storage
0.31996099999997796ms
caller-set fields take precedence over attributor (idempotent)
0.558114000000046ms
listener (broadcast) receives the same attributed entry
0.3862410000000409ms
upsertEntry propagates summaryKind to existing entry (LLM enrichment regression)
0.4103670000000079ms
upsertEntry routes through the attributor too
0.42465900000001966ms
late upsert preserves the original entry attribution after task rotation (regression)
0.46725299999997105ms
merge path (repetitive dedup) does not re-attribute after task rotation
0.37152800000001207ms
upsert with no existing match falls through to attributor (insert path)
0.2723500000000172ms
caller-set taskId on upsert overrides existing entry attribution
0.37617499999998927ms
history replay returns entries with taskId/runId set (regression)
0.6066020000000094ms
Stop hook + PTY fallback double-emit (regression) 1 / 1
identical chat_response from two emit paths is collapsed by store
0.6483450000000062ms
Timeline → WS broadcast pipeline 4 / 4
store entries trigger broadcast via listener
0.4258699999999749ms
upsert entries broadcast with upsert flag
0.42063300000000936ms
exact duplicate within 5s is skipped by store
0.3823150000000055ms
different content within 5s is NOT deduped
0.3915590000000293ms
TimelineEntry types 4 / 4
common entry types have expected shape
1.4259040000000027ms
entries with status field
0.23641600000001972ms
entries with detail field
2.2524569999999926ms
entries with automated flag
0.21379199999995535ms
session-timeline-relay.test.ts
5 / 5 1.2s
SessionTimelineRelay 5 / 5
connects to sibling and relays timeline_event
313.648308ms
relays timeline_history entries
301.65896ms
removes subscription when session disappears
201.9353319999999ms
ignores daemon sessions
3.108951000000161ms
handles upsert timeline events
402.11497699999995ms
Daemon & Infrastructure PASS
데몬 싱글톤, 세션 레지스트리, 사용량 릴레이가 안정적인가?
60 passed 0 failed 4 files 1.3s
daemon-lifecycle.test.ts
19 / 19 52ms
daemon.json lifecycle 6 / 6
writeDaemonInfo creates daemon.json with correct content
5.2467980000000125ms
readDaemonInfo returns info when PID is alive
1.0916230000000269ms
readDaemonInfo returns null and removes file when PID is dead
0.830159999999978ms
readDaemonInfo returns null when file does not exist
0.4017240000000015ms
removeDaemonInfo deletes daemon.json
0.6651019999999903ms
removeDaemonInfo is safe when file already gone
1.1590549999999666ms
session registry with real files 7 / 7
register creates sessions.json
2.104467999999997ms
register replaces existing entry with same id
1.2134209999999825ms
deregister removes session by id
1.7686820000000125ms
listActive prunes dead PIDs
1.898287000000039ms
multiple sessions coexist
1.4641129999999976ms
findExistingDaemon returns daemon session
1.0473669999999515ms
findExistingDaemon returns null when no daemon
0.6456719999999905ms
findDaemonPort 4 / 4
returns port from daemon.json (priority 1)
0.6463229999999953ms
falls back to sessions.json daemon entry
0.6407040000000279ms
returns null when no daemon anywhere
0.4065519999999765ms
daemon.json takes precedence over sessions.json
0.6832780000000298ms
probeDaemonHealth 2 / 2
returns health JSON from running server
27.065860999999984ms
returns null for closed port
3.4365829999999846ms
session-registry.test.ts
10 / 10 11ms
Session Registry Logic 10 / 10
pruneDeadSessions › keeps alive sessions
4.701573999999994ms
pruneDeadSessions › removes sessions with dead PIDs
0.6173069999999825ms
pruneDeadSessions › keeps old sessions if PID is alive
0.4030260000000112ms
pruneDeadSessions › handles mix of alive and dead sessions
1.0346440000000143ms
port allocation logic › returns base port when no ports are used
0.27551399999998694ms
port allocation logic › returns next port when base is taken
0.16694100000000844ms
port allocation logic › skips used ports
0.12371600000000171ms
port allocation logic › finds gaps in used ports
0.09870800000001623ms
port allocation logic › throws when all ports are taken
0.7684449999999856ms
atomic write › write-then-rename produces valid JSON
2.5162300000000073ms
usage-relay.test.ts
12 / 12 618ms
Usage relay — HTTP (Tier 1) 3 / 3
fetches usage from sibling GET /usage
55.713121ms
returns null usage when sibling has no data
14.601939000000016ms
rejects stale data (>5 min old)
4.202335999999946ms
Usage relay — WebSocket (Tier 2) 2 / 2
receives usage_update from sibling WS on connect
261.579257ms
does not send usage_update when sibling has no data
254.29780200000005ms
HookServer GET /usage (relay source) 2 / 2
returns cached usage via onApiUsage getter
10.913397000000032ms
returns fresh usage after update
6.45990299999994ms
429 prevention — relay-first strategy 2 / 2
sibling with data prevents direct API call
3.802453000000014ms
multiple siblings — first with data wins
4.821292000000085ms
ApiUsageData shape 3 / 3
has all required fields
0.45747800000003735ms
serializes to valid JSON and back
0.36067300000013347ms
handles null optional fields
0.32144399999992856ms
bridge-core.test.ts
19 / 19 585ms
BridgeCore Orchestration 19 / 19
buildStateEvent › builds state_update with IDLE state
22.759293000000014ms
buildStateEvent › includes cached ollamaStatus and gatewayAvailable
7.347307999999941ms
buildStateEvent › computes promptType for permission options
6.196578000000045ms
buildStateEvent › computes promptType yes_no_always for 3+ permission options
4.703213000000005ms
usage management › updateApiUsage caches and broadcasts
28.48093700000004ms
usage management › buildUsage includes API usage data
5.687046000000009ms
usage management › buildUsage works without API data
5.056287999999995ms
usage management › inferredBillingType propagates to StateMachine
6.630199999999945ms
sendInitialState › sends state_update, usage_update, connection, display_state on connect
16.445869000000016ms
sendInitialState › includes timeline_history when entries exist
16.123384999999985ms
state change broadcast › state_changed emits to WS clients when wired by caller
7.1470370000000685ms
wireTimeline › timeline entries broadcast as timeline_event
58.10437200000001ms
hasClients guard › wsServer.getClientCount reflects connected clients
257.53825299999994ms
hasClients guard › external client count provider extends hasClients
6.797702000000072ms
voice assistant state › updateVoiceAssistantState caches and triggers state broadcast
60.93894499999999ms
voice assistant state › disabled voice assistant state is not included in event
4.806897999999933ms
session registry › registerSession writes to sessions.json
5.047879999999964ms
session registry › deregisterSession removes from sessions.json
4.941801000000055ms
broadcast coordination › broadcast sends to WS and SSE callback
58.57319200000006ms
Integration Tests PASS
전체 파이프라인이 실제 서버 환경에서 동작하는가?
31 passed 0 failed 2 files 937ms
server-integration.test.ts
17 / 17 656ms
Server Integration 17 / 17
SessionStart hook → IDLE state broadcast
85.15282400000001ms
PreToolUse responds 200 with an EMPTY body (managed sessions must not gate)
21.683577000000014ms
non-PreToolUse hooks still ack with { received: true }
8.265859999999975ms
full session lifecycle: SessionStart → UserPromptSubmit → Stop
11.683786999999938ms
PreToolUse → PostToolUse cycle broadcasts tool info
18.61514999999997ms
SessionEnd → DISCONNECTED
8.97839399999998ms
GET /health returns valid JSON
13.965080000000057ms
GET /usage returns data when getter is set
5.989274999999907ms
GET /usage returns null when no getter
6.585081999999943ms
GET /devices returns empty when no getter
5.744506999999999ms
POST to unknown route returns 404
4.775929000000019ms
hook endpoint responds immediately
6.356137999999987ms
SSE client receives state_update events
74.75559499999997ms
broadcasts to multiple WS clients
9.160258000000113ms
WS command from client triggers callback
105.18789199999992ms
rapid hook events do not corrupt state
251.63421799999992ms
token counts accumulate through hook events
17.101372000000083ms
tier3-integration.test.ts
14 / 14 281ms
mDNS crash recovery 3 / 3
invalidateMdnsInstance does not throw when no instance exists
4.53666800000002ms
EADDRNOTAVAIL pattern matches expected error messages
0.5362380000000257ms
non-mDNS errors are NOT matched by recovery pattern
0.3600720000000024ms
Display sleep/wake broadcast 5 / 5
DisplayMonitor initial state is ON
0.33894099999997707ms
display_state event has correct shape
0.3453899999999521ms
display_state broadcasts to WS clients
82.38415700000002ms
display_state broadcasts to multiple clients
56.15960800000005ms
SSE also receives display_state
105.05193699999995ms
Voice transcription endpoint 4 / 4
returns 503 when no voice manager is set
14.266304000000105ms
returns 400 for empty audio data
5.1702229999999645ms
returns transcription from voice manager
4.872613999999999ms
returns 500 when voice manager throws
3.9901969999999665ms
WsServer broadcast hooks (serial relay) 2 / 2
onBroadcast hook receives all broadcast events
1.4586160000000064ms
broadcast hook errors do not crash server
1.0498700000000554ms
Stream Deck Plugin UI PASS
플러그인의 연결 관리, 옵션 레이아웃, 렌더링이 정확한가?
114 passed 0 failed 5 files 1.8s
connection-manager.test.ts
16 / 16 15ms
ConnectionManager 16 / 16
starts disconnected
4.101613000000015ms
start() begins bridge connection to daemon
1.7495790000000113ms
start() installs a port provider so daemon.json is re-read every attempt
0.4033059999999864ms
emits connected when bridge connects
1.4847299999999848ms
emits disconnected when bridge disconnects
0.4500069999999994ms
forwards state_update from bridge
0.9356459999999913ms
send() delegates to bridge
1.4206650000000138ms
send() drops command when not connected
0.3245080000000087ms
getBridgePort returns bridge port
0.22075100000000702ms
getConnectionSnapshot exposes connection and discovery state
0.27739700000000767ms
retryNow probes daemon discovery and reconnects immediately when disconnected
0.3957540000000108ms
switchToOpenClaw() › sends switch_agent command to bridge
0.5332109999999943ms
switchToClaude() › sends switch_agent command to bridge
1.236647999999974ms
isGatewayAvailable() › returns false by default
0.21473199999999792ms
isGatewayAvailable() › returns true when bridge reports gateway available
0.1904660000000149ms
isGatewayAvailable() › returns false when bridge reports gateway unavailable
0.1714070000000163ms
connection-integration.test.ts
6 / 6 1.7s
ConnectionManager Integration — Real WebSocket 6 / 6
client connects and receives broadcast events
227.94641300000006ms
multiple clients receive same broadcast
208.77606600000001ms
client sends command to server
156.0977190000001ms
handles rapid connect/disconnect without crashes
412.2811609999999ms
server detects client disconnect
253.887019ms
bridge → gateway priority: second server takes over on disconnect
406.0709509999999ms
option-scenario.test.ts
9 / 9 6ms
option-renderer panels 3 / 3
E2 Focus panel renders with adaptive font
2.6926249999999925ms
E3 List panel renders 4 visible rows with 14px font
0.779420999999985ms
E4 Detail panel shows word-wrapped label (12px, left-aligned)
0.5421839999999918ms
colorForOption — "don't ask again" / "allow all sessions" 6 / 6
returns blue for "Yes, and don't ask again for: tail:*"
0.39732699999999ms
returns blue for "Yes, and don’t ask again" (smart quote)
0.23878899999999703ms
returns blue for "Yes, allow all sessions in project"
0.28925499999999715ms
returns green for plain "Yes" (shortcut y)
0.21898900000002186ms
returns green for "Apply" (shortcut a, but no "don't ask" pattern)
0.16837300000000255ms
returns blue for "Always allow"
0.1312470000000019ms
renderer-snapshots.test.ts
64 / 64 69ms
voice-renderer snapshots 12 / 12
renderVoiceReady
5.477966999999978ms
renderVoiceRecording frame 0
0.7937029999999936ms
renderVoiceRecording frame 30 (>1min)
0.34075200000000905ms
renderVoiceTranscribing frame 0
0.46580000000000155ms
renderVoiceTranscribing frame 10 (different dot phase)
0.3268709999999828ms
renderVoiceError with message
0.432329999999979ms
renderVoiceError default
0.3314889999999764ms
renderVoiceDisabled
0.321282999999994ms
renderVoiceAssistantListening frame 0
0.3952249999999822ms
renderVoiceAssistantProcessing frame 5
0.49637599999999793ms
renderVoiceAssistantSpeaking frame 0
0.4665509999999813ms
renderWideVoiceText returns correct panel count
2.2023619999999937ms
utility-renderer snapshots 4 / 4
renderSetupUtility
0.43248999999997295ms
renderUtilityGeneric with icon
0.5713289999999915ms
renderUtilityGeneric text-only (no icon)
0.3657089999999812ms
renderUtilityMedia
0.6201320000000123ms
usage-dial-renderer snapshots 7 / 7
renderUsageOverview
1.0202039999999784ms
renderUsageDetail 5h
0.4514490000000251ms
renderUsageDetail 7d
0.3536110000000008ms
renderUsageSession
0.652481000000023ms
renderUsageExtra enabled
0.46124299999996765ms
renderUsageExtra disabled
0.42119400000001406ms
renderUsageDisconnected
0.4171779999999785ms
response-renderer snapshots 7 / 7
renderResponseIdle
0.5288560000000189ms
renderResponseProcessing
0.3820840000000203ms
renderResponseDisconnected
0.3656199999999785ms
renderResponseDisabled
0.3801510000000121ms
renderResponseSuggestion
0.7260519999999815ms
renderResponseInteractive
0.4402219999999488ms
renderSetupPrompt
0.3222449999999526ms
option-renderer snapshots 7 / 7
renderContextPanel permission
0.815796999999975ms
renderContextPanel diff
0.4319600000000037ms
renderFocusPanel with recommended option
0.8962880000000268ms
renderListPanel 3 options
0.6340830000000324ms
renderListPanel 6 options (scroll indicator)
0.3427449999999794ms
renderDetailPanel
0.6821459999999888ms
renderWideOptionList returns correct panel count
0.9660630000000765ms
button-renderer snapshots 7 / 7
basic text button
0.9922620000000961ms
button with subtitle
0.4098860000000286ms
disabled button
0.32084199999997054ms
loading button
0.33685700000000907ms
long text that needs abbreviation
0.6176090000000158ms
svgToDataUrl returns data URI
0.6158659999999827ms
labelNeedsHaiku detects long labels
1.3980320000000575ms
session-slot-renderer snapshots 9 / 9
disconnected hero is icon-rich
1.4363799999999856ms
disconnected non-center slot is empty
0.30262500000003456ms
disconnected cluster quadrant tl
0.3651590000000624ms
disconnected cluster quadrant tr
0.3125599999999622ms
disconnected cluster quadrant bl
0.39519400000006044ms
disconnected cluster quadrant br
0.29075699999998506ms
connected no-session card is icon-rich
0.2993699999999535ms
active idle session uses orbiting focus border
1.519523999999933ms
stale session dims the render and shows a STALE badge
0.6487049999999499ms
timeline-renderer snapshots 5 / 5
empty timeline
0.5003920000000335ms
single entry
2.6745959999999513ms
multiple entries fisheye
0.9343549999999823ms
detail mode
0.649387000000047ms
with session status
1.8322540000000345ms
qr-renderer snapshots 3 / 3
extractUrlLabel extracts host:port
0.6017249999999876ms
qrPathData deterministic
17.869641ms
renderQrButtonSvg
5.06540700000005ms
agent-logos snapshots 3 / 3
claude-code watermark
0.6871629999999413ms
openclaw watermark
0.5594919999999775ms
CLAUDE_LOGO_PATH is defined
0.4576879999999619ms
text-utils-and-labels.test.ts
19 / 19 10ms
text-utils: CJK width measurement 4 / 4
Latin text is ~0.55em per char
2.4913530000000037ms
Korean text is 1em per char (double-width)
0.4756039999999757ms
mixed text measures correctly
0.16011100000000056ms
isWide detects Hangul, CJK, fullwidth
0.24574000000001206ms
text-utils: wrapTextByWidth 3 / 3
short text returns single line
0.923057ms
long Latin text wraps to multiple lines
0.40108299999999986ms
Korean text wraps at correct pixel width
0.25812799999999925ms
button-renderer: abbreviation 10 / 10
short label renders without abbreviation indicator
1.1901279999999872ms
"Yes, I trust this folder" fits with wrapping (no abbreviation needed)
0.33283999999997604ms
"Yes, allow and don't ask again" wraps into 3 lines
0.22711100000000783ms
very long label triggers abbreviation with ~ indicator
0.8771469999999795ms
short permission labels like "No" render unchanged
0.2251890000000003ms
labelNeedsHaiku returns false for short labels
0.1945220000000063ms
labelNeedsHaiku returns false when heuristic abbreviation fits
0.14482799999998974ms
labelNeedsHaiku returns true for very long unknown labels
0.40569999999999595ms
labelNeedsHaiku returns false when Haiku cache has result
0.20355599999999185ms
BUTTON_MAX_CHARS is reasonable
0.891680000000008ms
button-renderer: CJK labels 2 / 2
Korean label does not overflow (produces valid SVG)
0.25228900000001886ms
mixed CJK/Latin label renders
0.1567850000000135ms
TUI Dashboard PASS
터미널 대시보드의 상태 렌더링과 테라리움 애니메이션이 올바른가?
49 passed 0 failed 3 files 60ms
tui-dashboard.test.ts
8 / 8 18ms
TUI dashboard models 8 / 8
stores modelCatalog from state_update
3.703665000000001ms
renders OAuth catalog and Ollama models in wide layout
2.908871000000005ms
renders disconnected OAuth state
1.122095999999999ms
shows current session summary and control hints
0.5583489999999927ms
renders agent list secondary line as model dash compact state
0.41402199999998857ms
renders sibling models in session bridge mode and omits uptime label
0.6597909999999843ms
renders help overlay when helpVisible is on
0.612780999999984ms
shows numbered session badges
8.13274899999999ms
tui-renderer-snapshots.test.ts
29 / 29 22ms
blockGauge snapshots 7 / 7
0% — all empty, green
6.885764999999992ms
50% — half filled, green
0.5812530000000038ms
75% — yellow threshold
0.3467909999999961ms
95% — red threshold
0.38243499999998676ms
100% — all filled, red
0.3354140000000143ms
clamps negative to 0
0.30985499999997046ms
clamps above 100
0.3449279999999817ms
resetTimeStr 5 / 5
returns empty for undefined
0.6651790000000233ms
returns ↻now for past time
0.5573669999999993ms
formats minutes
0.6834670000000074ms
formats hours and minutes
0.3174060000000054ms
formats days and hours
0.34844299999997475ms
formatUptime 3 / 3
seconds
0.3147629999999708ms
minutes
0.27502400000003036ms
hours and minutes
0.28966499999995676ms
formatTokens 3 / 3
below 1000 unchanged
0.3300060000000258ms
1k-10k with decimal
0.29917999999997846ms
10k+ rounded
0.30304499999999734ms
activityDensityBar 3 / 3
empty timestamps — all dim
0.5199910000000045ms
recent burst — bright right side
0.4468209999999999ms
spread timestamps — distributed density
0.39251899999999296ms
getLayout 3 / 3
wide for 120+ cols
0.37815800000004174ms
standard for 80-119 cols
1.264579000000026ms
narrow for <80 cols
0.3697660000000269ms
shouldShowTerrarium 3 / 3
true for adequate size
0.4366459999999961ms
false for too narrow
0.30626100000000633ms
false for too short
0.29397199999999657ms
spinner 2 / 2
returns braille characters at different frames
2.811144000000013ms
spinner cycles through 10 frames
0.34686099999998987ms
tui-terrarium-snapshots.test.ts
12 / 12 19ms
TUI terrarium snapshots 12 / 12
initTerrarium creates context with expected structure
4.516345000000001ms
setOctopi configures octopus instances
0.9951250000000016ms
setCrayfish configures crayfish state
0.39755800000000363ms
setJellyfish configures jellyfish instances
0.5399610000000052ms
renderTerrariumFrame empty terrarium (small)
4.344947999999988ms
renderTerrariumFrame empty terrarium (large)
1.1093970000000013ms
renderTerrariumFrame with idle octopus
1.592772999999994ms
renderTerrariumFrame with processing octopus
1.283298000000002ms
renderTerrariumFrame with routing crayfish
1.6875459999999975ms
renderTerrariumFrame with sick crayfish
1.8386020000000087ms
renderTerrariumFrame too small returns empty
0.3916889999999853ms
updateTerrarium advances bubble positions
0.42246399999999085ms
Serial Protocol PASS
ESP32와의 시리얼 바이트스트림이 정확히 프레이밍되는가?
29 passed 0 failed 1 files 21ms
esp32-serial-node.test.ts
29 / 29 21ms
SERIAL_FORWARDED_EVENTS 4 / 4
includes all display events
2.816264999999987ms
includes timeline events (unique to serial)
0.27854899999999816ms
does NOT include plugin-only events
0.26643000000001393ms
required serial events are present
0.31943999999998596ms
ESP32 port detection patterns 5 / 5
matches CH340 ports (86 Box)
0.5669430000000375ms
matches native USB JTAG ports (IPS 3.5", Round AMOLED)
0.38482900000002473ms
matches Linux serial ports
0.25119799999998804ms
excludes Bluetooth and WLAN
0.157587000000035ms
excludes non-ESP32 ports
0.2618039999999837ms
handleSerialLine (source) 5 / 5
parses device_info message and updates deviceInfo
1.1298379999999497ms
skips debug lines (non-JSON)
0.2365350000000035ms
recovers from malformed JSON
0.6820650000000228ms
ignores JSON without type field
0.22195399999998244ms
does not mark deviceInfo present for non-identifying messages
0.41680699999994886ms
serial I/O error classification 2 / 2
treats nonblocking backpressure as retryable
0.5413839999999936ms
does not retry terminal serial errors
0.2894049999999879ms
prepareForSerial (source) 9 / 9
strips agentCapabilities from state_update
0.7032479999999737ms
strips billingType and remoteUrl from state_update
0.292570000000012ms
preserves essential state_update fields
1.7095110000000204ms
strips bulky state_update fields before device_info arrives
0.6085649999999987ms
trims sessions_list to firmware fields and string sizes
1.0844710000000077ms
round-robins sessions_list by agent type so non-Claude agents survive the cap
1.320114999999987ms
roundRobinByAgentType keeps every present agent type and is a no-op under the cap
1.4219080000000304ms
strips legacy usage fields from usage_update
1.6829200000000242ms
passes through other events unchanged
0.2616930000000366ms
WiFi provision protocol 1 / 1
provision message has all required fields
0.407463000000007ms
serial buffer management 3 / 3
line splitting handles multiple lines in one chunk
0.4433569999999918ms
handles partial message across chunks
0.5043080000000373ms
truncates buffer when exceeding 8KB limit
0.18704200000001947ms
Display Rendering PASS
외부 디스플레이에 전송할 이미지 데이터가 올바른가?
3 passed 0 failed 1 files 3ms
pixoo-sprites.test.ts
3 / 3 3ms
getOctopusPaletteForSession 3 / 3
keeps the first additional session near the original terracotta tone
2.9403079999999875ms
darkens later sessions while preserving channel ordering
0.37454300000001695ms
clamps very large session indices to the darkest supported tone
0.20605999999997948ms
Hook Installation PASS
Claude Code hook의 설치, 제거, 마이그레이션이 안전한가?
21 passed 0 failed 1 files 16ms
install.test.ts
21 / 21 16ms
Hook Installer 21 / 21
buildHookEntry › creates matcher-group format with AGENTDECK_PORT env var
3.443583000000018ms
buildHookEntry › includes daemon.json port resolution with fallback to 9120
0.37246999999999275ms
buildHookEntry › reads PORT from AGENTDECK_PORT env var first, then daemon.json, then 9120
0.424839999999989ms
buildHookEntry › emits newline-separated shell so if/then/for/do keywords are not mis-terminated by `;`
0.5082450000000165ms
applyHooks › installs hooks to empty settings in matcher-group format
2.9124239999999872ms
applyHooks › preserves non-AgentDeck hooks
0.5026660000000049ms
applyHooks › replaces old flat-format hooks
0.3885449999999935ms
applyHooks › replaces old matcher-format hooks
0.44728299999999876ms
applyHooks › is idempotent — running twice produces same result
1.084462000000002ms
applyHooks › preserves existing non-hook settings
1.1948280000000011ms
removeHooks › removes all AgentDeck hooks (new format)
0.5279650000000231ms
removeHooks › removes old flat-format AgentDeck hooks
0.25193900000002145ms
removeHooks › preserves non-AgentDeck hooks
0.38800399999999513ms
removeHooks › handles empty settings gracefully
0.19550499999999715ms
migrateHooks › migrates old hardcoded port to env var
0.37874000000002184ms
migrateHooks › migrates flat format to matcher-group format
0.2147030000000143ms
migrateHooks › skips already-migrated hooks (new format)
0.1866600000000176ms
migrateHooks › skips non-AgentDeck hooks
0.14720199999999295ms
migrateHooks › migrates multiple events at once
0.6267730000000142ms
migrateHooks › migrates hardcoded port inside matcher-group
0.429996999999986ms
migrateHooksIfNeeded (file-based) › upgrades old :-9120 fallback hooks to daemon.json-reading format
0.3385989999999879ms
Other Tests
Uncategorized test files
497 passed 0 failed 36 files
apme-category-e2e.test.ts
3 / 3 42ms
APME category-aware turn evaluation (E2E) 3 / 3
conversation turn: prompt → classify → judge → turn category + composite persisted
26.868563999999964ms
research turn: rule-based classifier picks research, judge uses research rubric axes
8.224665000000016ms
daemon backfill pass: turns with response but no outcome get committed + null composite
7.248359999999991ms
apme-classifier.test.ts
18 / 18 75ms
classify() 12 / 12
planning — plan mode used
3.284033000000022ms
planning — short session, no file changes
0.3529009999999744ms
research — web searches dominant
0.2460100000000125ms
research — grep/glob dominant, no file changes
0.28139299999998ms
coding — edit+write dominant with file changes
0.2831869999999981ms
debugging — tests + edits + bash
0.23286999999999125ms
refactoring — many edits, no new files
0.19403199999999288ms
review — mostly reads, minimal edits
0.23818799999997964ms
ops — bash dominant, few edits
0.2220439999999826ms
conversation — very short, no tools
0.21394199999997454ms
multi_agent — multiple Agent delegations
0.1921389999999974ms
unknown — no clear pattern
0.19850900000000138ms
computeSignals() 3 / 3
counts tool calls and identifies dominant tool
26.14072299999998ms
detects plan mode from step payload
7.055110000000013ms
detects web searches
6.153962999999976ms
classifyRun() 2 / 2
returns signals and category for a coding run
7.133928000000026ms
returns unknown for empty runs
11.050893999999971ms
task_category schema migration 1 / 1
runs table has task_signals, task_category, task_category_source columns
11.249833999999964ms
apme-collector.test.ts
11 / 11 210ms
ApmeCollector 11 / 11
openRun → ingestHook → closeRun persists a run with steps
44.720665999999994ms
updateUsage and updateModel reflect in the run row
9.574778000000038ms
listRuns filters by agent and orders by started_at desc
26.361339999999984ms
default rubric v1 is seeded on init
11.094327000000021ms
insertEval + listEvalsForRun round-trip
12.822266000000013ms
excludes _empty runs from the unevaluated run queue
13.536335000000008ms
scorecard view aggregates runs per model
10.57807699999995ms
multi-turn cycle captures prompts and responses (wireAgentApme path)
56.328666999999996ms
setLastClosedTurnResponse fills missing response on closed turn
7.9515969999999925ms
setTurnResponse tags efficiency_json.response_kind (text / tool_only / empty)
8.652886000000024ms
no-op gracefully when store is disabled
7.715462000000002ms
apme-http.test.ts
13 / 13 369ms
APME HTTP routes 13 / 13
returns 503 when APME is not initialized
113.89549499999998ms
GET /apme/runs lists recent runs with evals and overall score
49.211884999999995ms
GET /apme/runs filters by agent
14.343808000000024ms
GET /apme/run/:id returns run detail with steps and evals
19.727238999999997ms
GET /apme/run/:id returns 404 for unknown runs
8.434252999999956ms
GET /apme/run/:id includes per-task rollup with attached evals
33.746735ms
GET /apme/tasks/:id returns task detail with evals + turns
30.771972000000005ms
closeTaskExternal with manual signal records outcome + boundary_signal=manual
10.561506000000008ms
GET /apme/scorecard returns model aggregates
11.07025699999997ms
GET /apme/rubric/current returns seeded rubric v1
9.16220700000008ms
POST /apme/vibe records feedback and rejects unknown runs
23.26323699999989ms
POST /apme/recommend returns candidate list
35.35800799999993ms
unknown /apme/* path returns 404
10.075495000000046ms
apme-judge-probe.test.ts
20 / 20 97ms
probeJudgeBackend — MLX 4 / 4
returns unavailable when /v1/models is unreachable
8.144146999999975ms
returns unavailable when /v1/models advertises no chat-capable model
37.136743000000024ms
returns unavailable when chat ping fails (model not loaded)
1.0486769999999979ms
returns ready when catalog AND chat ping both succeed
0.8702289999999948ms
probeJudgeBackend — OpenClaw 4 / 4
returns unavailable when /health is unreachable
1.0873050000000148ms
returns unavailable when /health is up but /models is not (gateway not initialised)
0.7202730000000201ms
returns unavailable when configured model is not in /models catalog
0.8326920000000086ms
returns ready when /health + /models both up and model matches
0.7609239999999886ms
probeJudgeBackend — Anthropic API (stub backend) 2 / 2
returns unavailable when ANTHROPIC_API_KEY is not set
1.107481000000007ms
returns unavailable even when ANTHROPIC_API_KEY is set (callApi is a stub)
0.7703690000000165ms
callJudgeWithMeta — effective backend labelling across fallback 3 / 3
FM happy path labels eval as foundationModels
1.1518920000000321ms
FM→MLX fallback (fallbackToMlx=true) labels eval as mlx, not foundationModels
7.504854999999964ms
FM failure without fallbackToMlx propagates the error (no silent label drift)
5.71903999999995ms
sanitizeForMlx — runtime fallback hygiene 4 / 4
strips FM endpoint and model when forcing to MLX
0.6766269999999963ms
strips OpenClaw endpoint and model when forcing to MLX
0.5595110000000432ms
returns the same cfg shape when already-clean MLX is passed
0.570568000000037ms
clears a custom MLX endpoint when source backend is MLX but model is overridden
0.5147839999999633ms
probeJudgeBackend — Foundation Models 3 / 3
returns unavailable when Swift daemon FM endpoint cannot be resolved
24.123055000000022ms
returns unavailable when FM endpoint responds with error body
0.9436089999999808ms
returns ready when FM endpoint responds with text
0.781735000000026ms
apme-runner.test.ts
32 / 32 426ms
detectLanguage 4 / 4
recognizes TypeScript from package.json
5.328591999999958ms
recognizes Swift from .xcodeproj
1.1271950000000288ms
recognizes Kotlin from build.gradle.kts
0.62203599999998ms
returns null for unknown paths
0.3118289999999888ms
parseJudgeJson 5 / 5
extracts scores and reasoning from a clean JSON blob
0.9231680000000324ms
rescales 0-10 axis to 0-1
0.2233960000000934ms
tolerates prose wrapping and code fences
0.20461699999998473ms
returns null when there is no JSON at all
0.1410919999999578ms
returns null when overall is missing
0.212729999999965ms
effectiveJudgeModelTag 4 / 4
uses cfg.model for MLX when no pin is set
1.1993039999999837ms
uses llm.mlx pin over cfg.model for MLX backend
0.7361170000000357ms
ignores llm.mlx pin for non-MLX backends
0.5350849999999809ms
foundationModels uses the Swift-parity judgeModelLabel
0.38808300000005147ms
callJudge foundationModels routing 3 / 3
returns FM text on ok response
26.36512499999992ms
throws when FM reports unavailable (default = no fallback)
2.6696640000000116ms
falls back to MLX only when fallbackToMlx is explicitly true
43.924240000000054ms
shouldJudge gating 4 / 4
never runs when sampleRate is 0
0.31097700000009354ms
skips clear passes when onlyWhenDisagreement is true
0.15957000000003063ms
runs on failures when onlyWhenDisagreement is true
0.17291000000000167ms
runs for clear passes when onlyWhenDisagreement is false
0.20809300000007624ms
ApmeRunner.runOne 5 / 5
records deterministic failures and invokes judge with rubric prompt
86.80355199999997ms
skips layer 2 on a clean pass when onlyWhenDisagreement is true
13.288347000000044ms
does not notify onResult for no-op run evals
6.742299000000003ms
enqueueTurn skips judge for tool_only and empty turns
29.18404499999997ms
swallows judge errors without inserting partial rows
13.747642000000042ms
runDeterministic (end-to-end spawn) 3 / 3
runs sh-based commands against the project path and reports pass
51.51717699999995ms
captures exit code 1 as tests_pass=0
51.10106100000007ms
skips entirely when the worktree has no changes
42.505810999999994ms
onTaskEvaluated 3 / 3
fires after enqueueTask resolves and carries the composite score + outcome
20.10950899999989ms
derives outcome=fail for low composite scores
13.247659999999996ms
preserves a manually-set outcome — judge does not overwrite `abandoned`
10.638286999999991ms
buildJudgePrompt 1 / 1
includes rubric prompt + task + context fields
0.4901270000000295ms
apme-settings.test.ts
16 / 16 19ms
loadApmeConfig — defaults + merge behaviour 12 / 12
returns full defaults when settings.json does not exist
8.938514999999995ms
returns full defaults when settings.json has no apme section
1.5800890000000152ms
returns defaults on malformed JSON (must not throw)
0.7127130000000079ms
merges user-set fields on top of defaults
0.9792939999999817ms
clamps sampleRate to [0, 1]
0.7952769999999987ms
falls back to mlx when judge.backend is unknown string
0.7548960000000022ms
downgrades judge.backend="api" to "mlx" on the Node bridge (callApi is a stub)
0.739752999999979ms
also wipes endpoint/model when downgrading backend="api" → "mlx"
0.7899090000000228ms
also wipes endpoint/model when falling back from unknown backend → "mlx"
0.6878049999999973ms
preserves user-set endpoint/model when keeping their chosen backend
0.7221170000000257ms
respects explicit enabled=false (opt-out)
0.5562070000000006ms
clamps deterministic.timeoutSec to [5, 1800]
0.7358370000000036ms
loadApmeConfig — DEFAULT_APME_CONFIG sanity 4 / 4
default backend is local MLX (cost-sensitive policy)
0.16795200000001387ms
default sampleRate is 1.0 (judge every closed run; cost is local)
0.1673720000000003ms
default enabled is true (zero-config activation)
0.12113200000001711ms
default autoTune is true (rubric self-improves over time)
0.1695449999999994ms
apme-task-boundary.test.ts
12 / 12 221ms
ApmeCollector task boundaries 10 / 10
first UserPromptSubmit opens a task and attaches the turn
31.82069899999999ms
TodoWrite with every todo completed closes the active task
9.825265000000002ms
TodoWrite with partial completion does NOT close the task
8.86418900000001ms
next UserPromptSubmit after boundary opens a new task
22.12525100000005ms
splitRun closes the active task with boundary=clear
24.768173999999988ms
closeRun closes the active task with boundary=session_end
15.608640999999977ms
onTaskClosed fires with the task metadata
8.786923000000002ms
onTaskOpened fires with sessionId + agentType + projectName + taskIndex
9.740436999999986ms
onTaskClosed payload includes session, agent, project, and timing
8.79993300000001ms
empty task (no turns between two boundaries) is dropped
17.345602999999983ms
ApmeRunner task eval 2 / 2
enqueueTask invokes judge with turns and persists summary + scores
32.62089699999996ms
skips task eval when all turns are tool_only / empty
30.318566000000033ms
apme-telemetry-envelope.test.ts
39 / 39 417ms
claudeHookToSpans 6 / 6
emits turn_start with prompt for UserPromptSubmit
5.6001210000000015ms
detects /clear and emits a task_boundary span (not turn_start)
0.6174589999999966ms
emits tool_call for PreToolUse with gen_ai.tool.name
1.4799950000000308ms
emits tool_result for PostToolUse
0.24094299999995883ms
falls through to raw_step for unknown events (Stop, SessionEnd, …)
0.30794300000002295ms
handles legacy { prompt: ... } shape on UserPromptSubmit
0.17603500000001304ms
claudePtyParserEventToSpans 4 / 4
maps tool_start to a tool_call span
0.47435299999995095ms
maps tool_end to a tool_result span
0.20869399999997995ms
emits a raw_step for spinner_start/idle/spinner_stop
0.21574499999996988ms
drops unknown parser events
2.7194089999999846ms
claudePtyResponseToSpan 3 / 3
returns a turn_response span for non-trivial text
0.6302570000000287ms
marks fallback_to_last_closed when requested
0.25004599999999755ms
returns null for empty / single-character text (filters silence)
0.28852399999999534ms
timelineEntryToSpans 12 / 12
translates chat_start to turn_start with detail as prompt
0.5338629999999966ms
translates chat_response to turn_response
0.42244599999997945ms
translates chat_end with response detail to turn_response with fallback flag
0.29479300000002695ms
drops chat_response / chat_end with empty body
0.4007919999999672ms
translates tool_request with first-token tool name
0.2172170000000051ms
codex_user_prompt_submit → turn_start span
35.426761ms
codex_user_prompt_submit with /clear → task_boundary span
0.5556249999999636ms
codex_tool_start → tool_call span with tool name
0.5484150000000341ms
codex_tool_end → tool_result span
0.43066799999996874ms
codex_stop / codex_session_start / codex_turn_complete → raw_step
0.9840500000000247ms
translates tool_exec the same as tool_request (legacy + Codex paths)
0.4793109999999956ms
translates tool_resolved to a tool_result span
0.25038699999998926ms
ApmeCollector.ingestSpan dispatch 13 / 13
turn_start span opens a turn and records the prompt
57.50431000000003ms
turn_response span persists the response on the active turn
34.10284100000001ms
tool_call span increments tool_calls on the active turn
33.31615800000003ms
chat_end fallback does not clobber a prior closed turn response
31.997705000000053ms
Codex timeline path opens turn and counts tools (timelineEntryToSpans)
14.617350999999985ms
task_boundary span with signal=clear splits the run
21.523389000000066ms
task_boundary span with signal=manual closes the active task
24.047631000000024ms
task_boundary span with signal=idle_gap closes the active task
20.79663699999992ms
task_boundary span with signal=todo_complete closes the active task
19.858632000000057ms
task_boundary span with an unknown signal is dropped (no task close, no throw)
23.457943999999998ms
raw_step span inserts a steps row without lifecycle effects
26.001348000000007ms
session_meta span updates the model id on the run
31.26482299999998ms
timeline adapter feeds the same dispatch path correctly
23.83393000000001ms
eval-schema constants 1 / 1
exports a stable schema version string
0.2974669999999833ms
apme-tuner.test.ts
18 / 18 184ms
correlation 4 / 4
returns 1 for perfectly aligned arrays
3.165725000000009ms
returns -1 for anti-aligned arrays
0.3145139999999742ms
returns null when variance is zero
0.25995100000000093ms
returns null when arrays are too short
0.21530500000000075ms
parseProposal 3 / 3
extracts prompt + weights from a clean JSON blob
0.9814879999999562ms
rejects proposals with too-short prompts
0.2921890000000076ms
rejects proposals with no weights
0.3310379999999782ms
extractOverall 3 / 3
parses overall score from a JSON blob
0.3225659999999948ms
rescales 0-10 values
0.21866900000003398ms
returns null when overall is missing
0.21175800000003164ms
collectDisagreements 1 / 1
picks up tests-pass-judge-fail and user-reject-judge-approve cases
54.64642100000003ms
vibeCorrelation 2 / 2
returns high positive correlation when judge and user agree
0.3958860000000186ms
returns null when there are too few labeled samples
0.14820299999996678ms
ApmeTuner.tune 5 / 5
accepts a proposal that improves vibe correlation
32.27438999999998ms
rejects a proposal that makes correlation worse
37.789963ms
rejects when the judge returns unparseable text
35.66625600000003ms
refuses to run when there are fewer than 3 disagreement samples
10.821919000000037ms
refuses when autoTune is disabled
4.926956000000018ms
awaiting-overlay.test.ts
13 / 13 19ms
awaiting-overlay 13 / 13
set then get returns the trimmed question
9.239692999999988ms
carries an optional requestId (actionable PreToolUse gate)
0.5903770000000179ms
returns undefined for an unknown session
0.44663099999999645ms
expires after the TTL (5 min)
0.9483850000000018ms
re-setting refreshes the TTL (a follow-up prompt keeps the overlay alive)
0.5069519999999841ms
clear removes the entry and reports whether one existed
0.6114089999999806ms
caps question length at 120 chars
0.565400000000011ms
looksLikePermissionMessage › matches real permission prompts
1.1280450000000144ms
looksLikePermissionMessage › rejects idle pings and empty messages
0.6032960000000003ms
applyAwaitingOverlayToObserved › flips a matching observed session to awaiting_permission with the question
1.877240999999998ms
applyAwaitingOverlayToObserved › matches the uuid after stripping the observed:claude: / observed:codex: prefix
0.746561000000014ms
applyAwaitingOverlayToObserved › leaves sessions untouched when no overlay exists
0.6037670000000048ms
applyAwaitingOverlayToObserved › propagates the requestId for actionable gates
0.7413540000000012ms
bridge-core-sessions.test.ts
2 / 2 87ms
BridgeCore sessions_list 2 / 2
broadcastSessionsList enriches sessions before broadcast
25.322917000000018ms
sendInitialState sends enriched sessions_list to the connecting client
62.181646ms
claude-transcript-reader.test.ts
7 / 7 13ms
readLastTurn 7 / 7
extracts assistant text and user prompt from a text-only turn
6.8356609999999876ms
flags tool-only turns (tool_use blocks, no text blocks)
1.1394819999999868ms
concatenates text across multiple assistant records for one turn
1.0116999999999905ms
picks the LAST user prompt when multiple turns are in the file
0.9071030000000064ms
returns null for missing file
0.6409629999999993ms
skips malformed lines and continues parsing
1.7913110000000074ms
accepts legacy string content on both roles
0.8453800000000058ms
codex-turn-manager.test.ts
9 / 9 102ms
CodexTurnManager (hook-primary path) 6 / 6
happy path: UPS → tool_start → tool_end → stop emits one chat
29.740425999999957ms
codex_stop does not reset subsequent turn_index numbering
18.06659400000001ms
codex_stop finalizes APME turn (endedAt set, tool_calls flushed)
8.384530999999981ms
next prompt opens a fresh chat_start
10.912915999999996ms
hook freshness window suppresses PTY parser idle close
6.28518600000001ms
long-bash: hook tool_start + tool_end keep the same turn open
5.304935ms
CodexTurnManager (PTY-only fallback when hooks absent) 3 / 3
spinner_start opens turn, prompt-source idle closes after deferral
9.490991000000008ms
timeout-source idle without prior tool_action does not latch
5.702959000000021ms
tool_action then timeout-idle latches; spinner_start closes prev + opens new
7.267358999999999ms
d200h-button-map.test.ts
5 / 5 13ms
D200H buildButtonCommandMap 5 / 5
single-session AWAITING: mode/focus/options/usage/interrupt at expected keys
9.034073000000035ms
multi-session AWAITING: sessions focus by real id, options on row 1
1.2214649999999665ms
options are inert unless AWAITING
0.627241999999967ms
no real session: hero focus is inert (no synthetic id dispatched)
0.5150240000000395ms
DISCONNECTED frame has no actionable keys
0.6117990000000191ms
gateway-parity-fixtures.test.ts
33 / 33 14ms
Gateway parity fixtures 33 / 33
fixture set is non-empty
3.243602999999979ms
'auth-pairing-required-error.json' carries a valid frame discriminator
1.2620159999999885ms
'chat-delta.json' carries a valid frame discriminator
0.41696600000000217ms
'chat-final-with-tools.json' carries a valid frame discriminator
0.30363600000001156ms
'connect-challenge.json' carries a valid frame discriminator
0.3419640000000186ms
'connect-hello-ok-device-token.json' carries a valid frame discriminator
0.3310680000000161ms
'connect-ok.json' carries a valid frame discriminator
0.2663000000000011ms
'exec-approval-requested.json' carries a valid frame discriminator
0.32189400000001456ms
'health-event.json' carries a valid frame discriminator
0.2872910000000104ms
'logs-tail-response.json' carries a valid frame discriminator
0.29149799999999004ms
'models-list-response.json' carries a valid frame discriminator
0.23619499999998084ms
'rpc-error.json' carries a valid frame discriminator
0.30011100000001534ms
'session-message.json' carries a valid frame discriminator
0.2569660000000056ms
'session-tool.json' carries a valid frame discriminator
0.21101700000002666ms
'sessions-changed.json' carries a valid frame discriminator
0.21902900000000614ms
'tick.json' carries a valid frame discriminator
0.2384089999999901ms
'auth-pairing-required-error.json' conforms to its frame shape
0.5246989999999983ms
'chat-delta.json' conforms to its frame shape
0.15294000000000096ms
'chat-final-with-tools.json' conforms to its frame shape
0.1395599999999888ms
'connect-challenge.json' conforms to its frame shape
0.18628000000001066ms
'connect-hello-ok-device-token.json' conforms to its frame shape
0.14303499999999758ms
'connect-ok.json' conforms to its frame shape
0.29257999999998674ms
'exec-approval-requested.json' conforms to its frame shape
0.18119200000001ms
'health-event.json' conforms to its frame shape
0.25243900000000963ms
'logs-tail-response.json' conforms to its frame shape
0.22416699999999423ms
'models-list-response.json' conforms to its frame shape
0.27614399999998795ms
'rpc-error.json' conforms to its frame shape
0.34519800000001055ms
'session-message.json' conforms to its frame shape
0.22607999999999606ms
'session-tool.json' conforms to its frame shape
0.23473300000000563ms
'sessions-changed.json' conforms to its frame shape
0.1880130000000122ms
'tick.json' conforms to its frame shape
0.2619329999999991ms
chat-final fixture carries the final-state fields the adapter depends on
0.5631960000000049ms
exec.approval.requested fixture exposes options for the user prompt
0.7770579999999825ms
openclaw-hook.test.ts
8 / 8 8ms
openclaw-hook → telemetry spans 8 / 8
OPENCLAW_IDLE_GAP_MS is conservative (60–180 s) so multi-turn collab stays together
2.7488799999999856ms
chat.send produces exactly one turn_start span carrying the prompt text
1.0114289999999926ms
chat.final with a response + tools yields turn_response + per-tool tool_result spans
1.4093269999999904ms
chat.delta emits no spans — deltas are streaming chunks, not eval signals
1.047473999999994ms
chat.aborted emits a manual task_boundary so the user gesture closes the task immediately
0.27036599999999567ms
chat.error emits nothing — the agent may retry, idle timer keeps running
0.1974869999999953ms
idle-gap task_boundary span carries boundary_signal=idle_gap
0.2674920000000043ms
all emitted spans propagate traceId for run correlation
0.30126200000000836ms
opencode-client.test.ts
13 / 13 22ms
OpenCodeClient 12 / 12
health › should call /global/health
10.485383000000013ms
listSessions › should call /session with directory and limit
1.1070060000000126ms
createSession › should POST to /session
1.0754390000000171ms
sendMessage › should POST to /session/{id}/message with parts
1.079024000000004ms
sendMessage › should include model option when provided
0.8022770000000037ms
abortSession › should POST to /session/{id}/abort
0.8242099999999937ms
respondPermission › should POST allow response
0.629558000000003ms
respondPermission › should POST deny response
0.482184999999987ms
HTTP error handling › should throw on non-ok response
2.8848319999999887ms
disconnect › should prevent reconnection after disconnect
0.5495270000000119ms
url accessor › should return server URL
0.3271520000000123ms
url accessor › should strip trailing slash
0.4247890000000041ms
OpenCodeAdapter event mapping 1 / 1
should export OpenCodeSSEEvent type
0.2676319999999919ms
opencode-hook.test.ts
8 / 8 6ms
opencode-hook → telemetry spans 8 / 8
tool part with status=running produces a tool_call span
2.8956210000000056ms
tool part with status=completed produces a tool_result span
0.25843900000000986ms
todowrite completion with all todos completed emits a task_boundary span (todo_complete)
0.4251790000000142ms
todowrite completion with a pending todo does NOT emit a task_boundary
0.2078730000000064ms
todowrite reads todos out of state.output JSON string when input is absent
0.30814300000000117ms
non-tool part returns an empty span list
0.9740640000000269ms
message.updated for user role with prompt emits a turn_start
0.42190300000001457ms
message.updated for assistant role with response emits a turn_response
0.20926399999999035ms
passive-observer.test.ts
4 / 4 8ms
passive-observer parsers 4 / 4
parses ps output without depending on fixed command columns
4.628614999999968ms
summarizes Claude transcripts and redacts tool secrets
1.727796000000012ms
summarizes Codex rollout metadata, context, and pending tool calls
1.2669530000000009ms
maps lsof field output to Codex rollout files by pid
0.4359759999999824ms
permission-resolver.test.ts
12 / 12 15ms
permission-resolver 12 / 12
register → resolve(allow) ends the held response with allow
6.503921999999989ms
resolve(deny) ends with deny
0.5186089999999979ms
times out to "ask" after timeoutMs
0.8555649999999844ms
resolving an unknown id returns null and is a no-op
0.3421639999999968ms
double resolve: second returns null (already resolved)
0.3634759999999915ms
abandonPending drops the entry without writing a decision
0.4563760000000059ms
sweepStalePending resolves entries older than maxAge to ask
0.46513900000002195ms
re-registering a duplicate requestId resolves the stale entry to ask first
0.6359649999999988ms
resolving over a dead socket does not throw and still clears the entry
1.713985000000008ms
fires onResolved exactly once on a device decision
1.4674349999999947ms
fires onResolved with "ask" on timeout
0.5375169999999798ms
drainAllPending resolves every held response to ask
0.4921199999999999ms
project-name.test.ts
14 / 14 71ms
resolveProjectName 10 / 10
returns git toplevel basename from a nested subdir
17.262687ms
falls back to nearest package.json name when no git
4.94199500000002ms
skips package.json with empty name and keeps walking
4.223034999999982ms
falls back to cwd basename when no git and no package.json
3.877796999999987ms
returns 'unknown' for a basename-less root
3.720470000000006ms
AGENTDECK_PROJECT_NAME env var wins over everything
6.795901000000015ms
envOverride option takes precedence over env var
0.4745629999999892ms
preserves scoped package name verbatim
4.320350999999988ms
git subprocess error (non-repo) does not throw
4.876857000000001ms
malformed package.json is ignored (walks to parent)
4.088111999999995ms
gitToplevelBasename 2 / 2
returns null outside a git worktree
3.619447999999977ms
returns repo basename from nested subdir
9.988047000000023ms
nearestPackageJsonName 2 / 2
returns null when no ancestor has package.json
0.8539629999999931ms
returns nearest ancestor name
0.9694760000000144ms
session-aggregator.test.ts
8 / 8 23ms
session-aggregator 8 / 8
uses ownState for the current session without fetching /health
6.686694999999986ms
fetches sibling /health and merges state and modelName
2.9783429999999953ms
falls back to base session info when sibling /health fails (no cache)
0.6955869999999891ms
returns cached state when sibling /health fails after a previous success
0.592852999999991ms
clearSiblingStateCache removes cached entry
0.4099970000000326ms
sweeps cached state for sessions that drop out of the active set
0.6619569999999726ms
buildEnrichedSessionsList includes own session and excludes daemon
10.411631999999997ms
buildEnrichedSessionsList returns own session in single-session mode without /health calls
0.5804840000000127ms
tui-hud-entries.test.ts
16 / 16 15ms
buildHudEntries — primary anchoring 7 / 7
promotes the matching-port sibling to primary instead of appending a duplicate
10.618763999999999ms
patches the anchored sibling with the primary's live fields (matches macOS / Android)
0.46883600000001024ms
uses the primary's projectName for the #N suffix grouping after anchoring
0.3996609999999805ms
preserves the deterministic #N order when primary anchors a sibling slot
0.87751099999997ms
appends a synthetic primary when no sibling shares its agentType
0.29819899999995414ms
skips the synthetic primary when a sibling shares agentType but no port match (duplicate guard)
0.24568999999996777ms
never appends primary when agentType is daemon or openclaw
0.23536400000000413ms
buildHudEntries — virtual OpenClaw 2 / 2
inserts a virtual OpenClaw row when gateway is available and sessions has none
0.30675200000001723ms
does not insert a virtual row when sessions already contains an openclaw entry
0.21180799999996225ms
buildHudEntries — hotkey eligibility (sibling-only) 1 / 1
primary and virtual rows do not consume hotkey slots
0.32850500000000693ms
formatTaskEvalSuffix — task_end badge for each outcome class 6 / 6
renders ✓ for success
0.18992600000001403ms
renders ✗ for fail
0.12180399999999736ms
renders △ for partial
0.10811300000000301ms
renders ⊘ for abandoned (manual cancel)
0.10236400000002277ms
renders ? as score placeholder when judge has not produced a number yet
0.09732700000000705ms
returns empty string while the eval is still pending (outcome undefined)
0.13439199999999119ms
usage-event.test.ts
3 / 3 5ms
buildUsageEvent subscription quota scoping 3 / 3
omits Anthropic quota when the model is not yet known
3.925879000000009ms
omits Anthropic 5h/7d quota for GLM/API-backed models
0.5120699999999943ms
keeps Anthropic 5h/7d quota for Claude model aliases
0.23570499999999583ms
codex-install.test.ts
32 / 32 28ms
codex-mini-toml: applyManagedBlock 4 / 4
appends fence when absent
2.5233949999999936ms
replaces existing fence block
0.46660200000002305ms
apply twice is idempotent
0.24669099999999844ms
moves Codex hook trust state out of the managed fence
0.3690650000000062ms
codex-mini-toml: removeManagedBlock 2 / 2
leaves user content
0.33728700000000345ms
is idempotent without fence
0.11420200000000591ms
codex-mini-toml: hasTopLevelKeyOutsideFence 3 / 3
detects user notify key
0.331908999999996ms
ignores notify key inside table
0.180341999999996ms
ignores notify key inside fence
0.13665500000001884ms
codex-mini-toml: hasTableOutsideFence 6 / 6
detects user [otel] table
0.28017099999999573ms
detects user [otel.exporter] dotted table
0.17477199999999016ms
detects array-of-table header [[hooks.Stop]]
0.18536900000000855ms
ignores Codex hook trust state outside fence
0.19588500000000408ms
ignores [otel] inside fence
0.14156299999999078ms
ignores [otelfoo] (word boundary)
0.11910900000000879ms
codex-mini-toml: quoted 3 / 3
escapes backslash and double quote
0.1853190000000211ms
escapes newline and tab
0.14725100000001135ms
passes simple ASCII
0.16200399999999604ms
codex-install: managedBlockBody 3 / 3
roundtrip preserves user TOML byte-for-byte (load-bearing)
1.5485989999999958ms
matches Codex schema (lifecycle hooks + endpoints + notify dummy)
1.9953599999999767ms
omits conflicting optional channels when asked
1.0537040000000104ms
codex-install: install / uninstall (file I/O) 11 / 11
creates config with fence when file is absent
3.2516789999999958ms
preserves user content when installing into existing config
1.4349980000000073ms
skips when user already has [features] table outside fence
0.618029000000007ms
skips when user already has [hooks] table outside fence
1.1624079999999992ms
omits notify when user has top-level notify
0.9469640000000084ms
omits OTel when user has [otel] table
1.0540650000000085ms
uninstall strips fence and preserves user content
1.670332000000002ms
uninstall is idempotent when no config exists
1.4915029999999945ms
honours AGENTDECK_NO_CODEX_HOOKS=1 opt-out
0.557027000000005ms
install is idempotent (same port → no rewrite)
1.7012080000000083ms
preserves Codex hook trust state across reinstall
3.430689000000001ms
bridge-client.test.ts
3 / 3 3.4s
BridgeClient — port provider 3 / 3
skips connect when provider returns null
56.69834700000001ms
connects once provider returns a live port
1264.031673ms
rebinds to a new port when provider value changes
2104.69232ms
encoder-offline-policy.test.ts
3 / 3 4ms
renderOfflineTouchStrip — all-or-nothing 800px slice contract 3 / 3
every slice is a 200x100 canvas carrying the shared banner content
3.320949000000013ms
slices 0..3 offset the same banner by -index*200 (E0..E3 align into one strip)
0.39301000000000386ms
uses a per-slice gradient id so the four panels are independent SVGs
0.2675920000000076ms
session-slot-button.test.ts
12 / 12 6ms
computeCenterSlot 6 / 6
SD+ 4x2 → bottom-center
2.439223999999996ms
SD MK2 5x3 → true geometric center
0.21309999999999718ms
SD XL 8x4 → middle row, mid column
0.156675000000007ms
SD Mini 3x2 → bottom-center
0.13681600000001026ms
single key device → slot 0
0.1703860000000077ms
clamps degenerate zero rows/cols to slot 0
0.13483199999998874ms
computeCenterCluster 6 / 6
SD+ 4x2 → 2x2 cluster on geometric center (slots 1,2,5,6)
1.0446600000000217ms
SD XL 8x4 → 2x2 cluster on geometric center (slots 11,12,19,20)
0.2558750000000032ms
SD MK2 5x3 → single full hero on slot 7
0.24427700000001096ms
SD Mini 3x2 (odd cols) → single full hero on slot 4
0.14815299999997933ms
single-key device → single full hero on slot 0
0.1331000000000131ms
degenerate zero dimensions → single hero on slot 0
0.13906900000000633ms
session-slot-manager.test.ts
8 / 8 9ms
SessionSlotManager detail layout 8 / 8
re-points detail focus onto the codex fold representative when the focused thread is absorbed
4.166601000000014ms
exits detail view when the focused session is gone with no fold successor
0.4064610000000357ms
folds codex companion threads by project before slot assignment
1.6296429999999873ms
renders connected no-session list as status cards instead of text-only empty buttons
0.5423959999999965ms
puts processing tool info before OpenClaw presets
1.2694609999999784ms
keeps a processing status tile even before tool metadata arrives
0.3036069999999995ms
aliases the model name on detail MODEL surfaces (status card + OpenClaw preset)
0.7661630000000059ms
uses actual parser options and reserves MORE only when awaiting overflow exists
0.4519409999999766ms
format-utils.test.ts
18 / 18 9ms
adjustUsagePercent 11 / 11
returns undefined when percent is null
3.474851000000001ms
returns undefined when percent is undefined
0.2773369999999886ms
returns percent unchanged when resetsAt is null
0.36729199999999196ms
returns percent unchanged when resetsAt is undefined
0.22215399999998908ms
returns percent unchanged when resetsAt is in the future
0.5329110000000128ms
returns 0 when resetsAt is in the past (window expired)
0.3482829999999808ms
returns 0 when resetsAt equals now (edge case)
0.24431699999999523ms
handles invalid date string gracefully (returns percent)
0.2634260000000097ms
handles empty string resetsAt (returns percent)
0.23576399999998898ms
returns percent unchanged when resetsAt is far in the past (>1h)
0.21089699999998857ms
still returns 0 just after the 1h threshold boundary
0.25578400000000556ms
formatResetTime 7 / 7
returns "now" when resetsAt is in the past
0.37809799999999427ms
returns undefined for null input
0.27246900000000096ms
returns minutes-only for < 1h remaining
0.33504299999998466ms
returns hours and minutes for < 24h remaining
0.39037700000000086ms
returns days and hours for >= 24h remaining
0.26040199999999913ms
omits minutes when exactly on the hour
0.2657689999999775ms
passes through pre-formatted strings (no T)
0.29194900000001667ms
llm-settings.test.ts
10 / 10 14ms
llm-settings 10 / 10
returns defaults when settings.json is missing
5.437669999999997ms
reads llm.mlx pin from settings.json
0.9373379999999827ms
treats "qwen3-30b" and "default" as placeholders (unpinned)
1.1620960000000196ms
falls back to apme.judge.model when llm.mlx is absent
0.5189400000000148ms
strips /chat/completions suffix from legacy endpoints
0.555864999999983ms
prefers llm.mlx over apme.judge when both set
0.4938820000000135ms
resolveMlxModel: pin > probe > fallback
1.1250900000000001ms
pickMlxModel: 4-layer priority (pin > fallback > first > null)
0.7170569999999827ms
mlxChatUrl reflects endpoint setting
0.5156749999999874ms
caches result for TTL window
1.6235690000000034ms
session-utils.test.ts
14 / 14 16ms
agentTypeRank 1 / 1
ranks openclaw first, then claude-code, codex-cli, codex-app, opencode, others
2.653254000000004ms
naturalLabelCompare 2 / 2
orders numeric chunks naturally (Agent 2 before Agent 10)
7.908263000000005ms
treats undefined as empty string
0.19765800000001832ms
sortSessions 6 / 6
places openclaw before claude-code regardless of project
0.9695889999999849ms
sorts by project name within the same agent type
0.2884040000000141ms
sorts numbered project names naturally (#2 before #10)
0.2985390000000052ms
breaks ties on startedAt ascending (oldest first)
0.2794409999999914ms
falls back to id natural-compare when startedAt ties to the same ms
0.2945530000000076ms
does not mutate the input array
0.27790899999999397ms
foldCodexSessionsForDisplay 1 / 1
folds Codex CLI and Codex App separately even with the same project
1.858587ms
assignDisplayNames 4 / 4
passes single sessions through without #N suffix
0.46879599999999755ms
adds #1/#2 suffixes for duplicate (project, agentType) tuples in input order
0.31666699999999537ms
numbers same project across different agentTypes independently
0.4689459999999883ms
produces the same #N assignment as a deterministic sort + display pipeline
0.47163000000000466ms
svg-renderers/model-alias.test.ts
7 / 7 4ms
aliasModelName 3 / 3
shortens claude family-major-minor
3.1980150000000265ms
drops trailing date suffix on claude releases
0.1889139999999827ms
passes gpt and unknown strings through unchanged
0.20324500000000967ms
formatModelEffort 4 / 4
returns aliased model when no effort to show
0.2481920000000173ms
appends non-default effort when it fits
0.12347599999998238ms
truncates aliased model name to fit budget with effort suffix
0.21474299999999857ms
returns empty string for missing model
0.18631999999999493ms
timeline-summarizer.test.ts
13 / 13 6ms
extractTopicHintWithKind — Korean polite-closer robustness 7 / 7
returns the cleaned topic when the response opens with "네, …"
2.9605689999999925ms
returns the original (kind=fallback) when the entire response is just a polite closer
0.38587900000001696ms
returns null for empty / very short text (still)
0.20622000000000185ms
skips lone heading markers and code fences
0.2994099999999946ms
a heading WITH text becomes the topic (heading is the title)
0.1826340000000073ms
strips list bullet markers
0.17211800000001176ms
extractTopicHint convenience returns just the hint string
0.16937500000000227ms
promptSnippetFallback 6 / 6
returns first sentence trimmed
0.23358099999998672ms
returns whole string when no sentence terminator
0.16718099999999936ms
truncates to maxLen with ellipsis
0.2639560000000074ms
cuts at first newline if no sentence terminator
0.10757200000000466ms
returns null for empty / very short input
0.1337909999999738ms
handles Korean prompts
0.1375060000000019ms
timeline-task-hierarchy.test.ts
40 / 40 15ms
deduplicateEntry — task hierarchy 3 / 3
always adds task_start even with identical raw within 8s
2.8712580000000116ms
always adds task_end with same boundarySignal back-to-back
0.3528699999999958ms
still dedupes ordinary chat_start within 8s
0.18873400000001084ms
timelineIconKey 5 / 5
maps task entries to "task"
0.25511399999999185ms
maps tool_request status to success/error/awaiting
0.20987500000001091ms
chat_start in flight is "running"; chat_end is "success"
0.1403410000000065ms
error → error; user_action → user; memory_recall → memory
0.16259400000001278ms
every key has an e-ink glyph of constant 4-char width
0.34620999999998503ms
isInFlightTask 5 / 5
task_start without matching task_end is in flight
0.30146400000000995ms
task_start whose task_end (same taskId) appeared is finished
0.14919500000002017ms
mismatched taskId on task_end does not close it
0.1174570000000017ms
task_start without taskId is never considered in flight
0.10710100000000011ms
non-task_start entries are never in flight
0.13326000000000704ms
isRotatingEntry 5 / 5
chat_start always rotates (icon-key running)
0.13570400000000404ms
orphan task_start rotates via in-flight predicate
0.17106799999999112ms
closed task_start does not rotate
0.11348099999997885ms
static rows do not rotate
0.1790600000000211ms
eval_result and task_end never rotate
0.13022499999999582ms
parseTimelineMarkdown 9 / 9
returns single text line for plain text
1.3512209999999811ms
parses headings 1-6 with required space
0.5827260000000081ms
parses bullets and numbered lists
0.3342429999999865ms
handles code fence — verbatim lines, not interpreted
0.44218499999999494ms
blank line → blank kind
0.28044199999999364ms
parses tables with header separator
0.5431670000000111ms
parses tables without separator (no header)
0.35261100000002443ms
table block ends at first non-table line
0.2463109999999915ms
quote lines parse
0.17417200000002708ms
parseInlineSpans 9 / 9
returns empty for empty string
0.29166799999998716ms
returns single plain span for plain text
0.19373099999998544ms
parses **bold**
0.16995600000001332ms
parses *italic* (single star)
0.15766700000000355ms
parses `code` inline
0.21053699999998798ms
parses [text](url) link
0.17888899999999808ms
unclosed ** falls back to plain
0.1391490000000033ms
multiple spans in one line
0.17136699999997518ms
first-match-wins: ** consumed before * (no double-italic split)
0.13139799999999013ms
prepareMarkdownDetail 4 / 4
preserves markdown markers (chat-response detail goes to client)
0.5065910000000144ms
still filters system JSON blobs
0.2239059999999995ms
collapses 3+ blank lines but keeps double-blank paragraph break
0.2683839999999975ms
contrasts with cleanDetailText which strips markdown (non-chat path)
0.9161579999999958ms
Android PASS
JUnit + Robolectric · 13 files · 176 tests
data.DashboardOrientationTest
3 / 3 2ms
defaults keep e-ink fixed and tablets auto-rotating
2ms
legacy unspecified preference still counts as auto
manual rotate toggles fixed modes from auto using current posture
net.ProtocolTest
34 / 34 5.5s
parse state_update with all permission modes
4424ms
parse connection connected with sessionId
37ms
parse sessions_list
63ms
PluginCommands selectOption generates valid JSON
73ms
parse timeline_event with fractional timestamps
57ms
parse button_state
39ms
PluginCommands utility with and without value
32ms
parse invalid json returns null
33ms
parse timeline_history
24ms
parse timeline_event upsert
29ms
parse state_update with processing state and tool info
33ms
PluginCommands respond escapes special characters
47ms
parse display_state with dim instruction
38ms
PluginCommands respond generates valid JSON
26ms
parse state_update with permission options
28ms
parse connection disconnected
48ms
parse missing type returns null
24ms
parse deck_slot_map
26ms
parse usage_update with extra usage
26ms
parse state_update with ollama status
27ms
PluginCommands navigateOption
21ms
parse state_update with agent capabilities
24ms
parse unknown type returns null
27ms
parse user_prompt
30ms
BridgeTimelineEntry converts to TimelineEntry
27ms
parse state_update with model catalog
32ms
parse state_update ignores unknown fields
20ms
parse state_update with idle state
22ms
parse display_state sleep and wake
18ms
parse voice_state
24ms
parse encoder_state
25ms
PluginCommands interrupt and escape
18ms
parse usage_update with rate limits
21ms
parse timeline_event
20ms
state.SessionMetricsTest
8 / 8 6ms
reset clears all metrics
5ms
onMessageReceived updates lastMessageAt
onConnected sets connectedSince
onDisconnected clears connectedSince
clean reconnect after disconnect does not increment
initial state has no connection
reconnect increments reconnectCount when still connected
onMessageReceived increments count
state.TimelineDisplayScenarioTest
5 / 5 5ms
multi-agent dashboard timeline projects meaningful session rows
4ms
synthetic chat_start is suppressed once completion arrives
chat_end with summaryKind survives even when chat_response paired
1ms
codex otel low-signal tool entries are suppressed
same timestamp summaries stay separate by agent and project
state.TimelineStoreTest
47 / 47 35ms
addEntry drops openclaw placeholder with status-only detail
6ms
timelineDisplayGroups keeps meaningful chat_start alongside response
addEntry allows same type+summary after 5s
1ms
addEntries filters otel noise from bulk replay
2ms
clear empties the store
upsertEntry updates existing entry within 1s tolerance
upsertEntry without taskId falls back to ts-window match
1ms
timelineDisplayGroups keeps in-flight chat_start until completion
groupConsecutive empty list returns empty
addEntry drops openclaw placeholder tool rows
addEntry keeps meaningful raw on otel-active session
timelineLifecycleBounds pairs response with prior start
timelineDisplayGroups hides chat_end when chat_response already represents the same turn
1ms
upsertEntry adds new entry if no match
addEntry stores entry
groupConsecutive does not merge tool_request across sessions
1ms
groupConsecutive groups same summary within 60s
timelineDisplayGroups keeps independent sessions visible
updateLastOfType modifies the last matching entry
1ms
upsertEntry refuses to insert otel noise via add fallback
addEntries merges and deduplicates
addEntry drops openclaw placeholder with arbitrary future status
upsertEntry preserves existing detail if new detail is null
1ms
addEntry keeps real openclaw tool rows
groupConsecutive splits tool_request after 10s gap
addEntries sorts by timestamp
1ms
upsertEntry preserves existing summaryKind when new entry omits it
1ms
groupConsecutive does not merge chat_end across projects
upsertEntry preserves timeline attribution
groupConsecutive splits different types
addEntry allows different type within 5s
addEntry drops openclaw placeholder with failed status
groupConsecutive single entry
addEntry deduplicates within 5s window
upsertEntry propagates summaryKind progression heuristic to llm
timelineDisplayGroups collapses synthetic chat_start once response arrives
1ms
addEntry allows different summary within 5s
groupConsecutive groups chat_end by type only within 60s
addEntry drops codex otel low-signal tool noise
addEntry caps at MAX_ENTRIES
11ms
groupConsecutive does not merge distinct run ids on same session
timelineDisplayGroups keeps in-flight start when later completion has distinct run id
addEntry keeps openclaw placeholder summary when detail has content
1ms
groupConsecutive requires same summary for other types
updateLastOfType no-op if type not found
groupConsecutive groups tool_request within 10s
upsertEntry merges task_end by taskId beyond the 1s tolerance window
state.TimelineTaskHierarchyTest
24 / 24 17ms
mismatched taskId on task_end does not close it
1ms
stripMarkdownInline drops markers including table syntax
4ms
detail redundancy fires when prefix matches summary
1ms
detail redundancy does not fire when content is genuinely new
same project two sessions are not the same context anymore
closed task_start does not rotate
1ms
non task_start entries are never in flight
task_start whose task_end (same taskId) appeared is finished
static rows do not rotate
stripMarkdownInline preserves non-table pipes
task hierarchy is never elided by display projection
task_start without matching task_end is in flight
chat_start always rotates via icon-key running
task entries never group with each other
iconKey resolves tool_request status to success error awaiting
taskId is the strongest grouping key
iconKey resolves to Task for task entries
eval_result and task_end never rotate
stripMarkdownInline handles single-cell table row
markdown parser parity with shared - basics
7ms
task_start without taskId is never considered in flight
orphan task_start rotates via in-flight predicate
markdown parser code fence is verbatim
eink glyphs are constant 4-char width
1ms
terrarium.TerrariumStateTest
7 / 7 217ms
claude processing does not bleed into OpenClaw crayfish on aggregate view
70ms
stale gateway error is ignored when gateway is unavailable
24ms
authenticated gateway shows OpenClaw at rest
25ms
gateway error surfaces sick OpenClaw
25ms
reachable gateway without auth hides OpenClaw and workers
24ms
OpenClaw processing routes its own crayfish
23ms
daemon aggregate keeps OpenClaw crayfish calm while claude works
24ms
terrarium.renderer.EinkAnimationTimingTest
3 / 3 6ms
animation frame advance is elapsed-time based and bounded
3ms
fish simulation scales movement for partial color frames
2ms
color e-ink animation uses video-like cadence
ui.eink.EinkAttentionPanelTest
3 / 3 17ms
non-focused awaiting session hides unavailable live prompt fields
14ms
primary awaiting session is surfaced when not represented by siblings
featured attention prefers focused awaiting session
2ms
ui.eink.SessionDisplayOrderingTest
6 / 6 5ms
naturalLabelCompare orders Agent 2 before Agent 10
1ms
compareSessionsForDisplay breaks ties on startedAt ascending (oldest first)
1ms
compareSessionsForDisplay sorts openclaw before claude-code regardless of project
1ms
compareSessionsForDisplay tie-breaks on natural id when startedAt is identical
agentTypeRank places openclaw first
compareSessionsForDisplay is stable across re-sorts of any input order
2ms
ui.monitor.OpenClawDisplayLinesTest
4 / 4 5ms
empty when no default tagged
5ms
empty catalog yields empty list
keeps only default model when present
empty when default is unavailable
ui.monitor.SubscriptionLineTest
12 / 12 12ms
subscriptionTrailing flags expired for past dates
7ms
malformed until renders renewal needed
1ms
future ISO8601 with offset renders date suffix
1ms
parseUntilInstant accepts ISO8601
1ms
bare date in past renders renewal needed
future ISO8601 with fractional seconds renders date suffix
1ms
subscriptionTrailing returns date for future
parseUntilInstant accepts blank as null
past until renders renewal needed
1ms
bare date string parses as UTC midnight
subscriptionTrailing returns null for blank or null
null until renders name only
util.TimeFormatUtilsTest
20 / 20 12ms
gaugeBar clamps below 0
2ms
formatCount thousands show K
2ms
formatBytes kilobytes
formatDurationCompact seconds
1ms
formatDurationCompact exact minutes no seconds
formatDurationCompact sub-second
formatCount int overload works
gaugeBar clamps above 100
formatBytes small values
2ms
formatCount small numbers unchanged
gaugeBar 50 percent is half filled
gaugeBar 0 percent is all empty
formatBytes megabytes
formatResetTime returns original on parse failure
gaugeBar custom width
formatBytes gigabytes
1ms
formatUptime zero returns 0 colon 00
1ms
formatCount millions show M
formatDurationCompact minutes
1ms
gaugeBar 100 percent is all filled
Robot Framework FAIL
ESP32 Hardware Tests · 1 suites · 4 scenarios · 7 tests · 4 boards
BoardBuildFlash+BootBoot TimeFW SizeBoot HeapLatency
Round0.8s
IPS 3.5"0.6s
TC0010.6s
86Box17.2s
01_build.robot no-hwquicksmoke
3 / 7
Build And Verify 4 boards 1 / 4
Given the "${board}" firmware is built
Then the firmware binary should exist for "${board}"
And the firmware size should be sane for "${board}"
And the partitions binary should exist for "${board}"
✓ 86Box✗ IPS 3.5"✗ Round✗ TC001
Box 86 Build And Verify
17.2s
IPS 3.5 Build And Verify
PlatformIO build failed for ips_35: UnknownEnvNamesError: Unknown environment names 'ips_35'. Valid names are 'ips35, axs_test, box_86, rgb48, ips10, boot_test_qspi, display_test, amoled, qspi_test, esp32_c6_147, led8x32, ttgo': 1 != 0
606ms
Round AMOLED Build And Verify
PlatformIO build failed for round_amoled: UnknownEnvNamesError: Unknown environment names 'round_amoled'. Valid names are 'led8x32, box_86, rgb48, amoled, ips35, qspi_test, display_test, ttgo, ips10, boot_test_qspi, axs_test, esp32_c6_147': 1 != 0
806ms
Ulanzi TC001 Build And Verify
PlatformIO build failed for ulanzi_tc001: UnknownEnvNamesError: Unknown environment names 'ulanzi_tc001'. Valid names are 'rgb48, display_test, ips10, boot_test_qspi, amoled, ttgo, box_86, ips35, axs_test, qspi_test, led8x32, esp32_c6_147': 1 != 0
606ms
Boot Test Environment Builds Successfully
PlatformIO build failed for boot_test: UnknownEnvNamesError: Unknown environment names 'boot_test'. Valid names are 'box_86, amoled, rgb48, qspi_test, ips10, ttgo, esp32_c6_147, led8x32, boot_test_qspi, ips35, axs_test, display_test': 1 != 0
605ms
Source Files Are Present
PlatformIO Configuration Parses Cleanly
704ms
Scenario Coverage
User scenario mapping against actual test results
5 covered 5 partial/missing 10 with identified gaps
Score Scenario Priority Unit Integ. Platform E2E
6/8
Session Lifecycle
Start session -> processing -> idle -> stop. Core state machine transitions that drive all UI.
  • No end-to-end test with real Claude PTY process
  • No Android UI test for state transitions
critical 4/41/21/2
3/5
Permission Flow
Agent requests permission -> user sees options -> approves/denies -> state transitions back.
  • No multi-option navigation end-to-end test
  • No encoder dial interaction test for option scrolling
critical 2/20/21/1
7/7
Multi-agent Monitoring
Daemon hub orchestrates multiple session bridges, unified dashboard for all agents.
  • No daemon + session bridge coordinated test
  • No multi-agent state aggregation test
high 3/34/4
7/7
Device Connection
mDNS discovery -> auth token validation -> WebSocket/serial state sync with dashboard clients.
  • No real mDNS discovery test
  • No ADB reverse tunnel test
  • No auth token rejection test
high 3/33/31/1
4/5
Timeline Aggregation
Events from multiple sessions -> daemon relay -> dedup -> unified timeline for all clients.
  • No daemon-to-client relay end-to-end test
  • No LLM summary enrichment test
high 2/21/11/2
1/1
Voice Recording & Transcription
Audio capture -> whisper transcription -> text delivery to Claude PTY or clipboard.
  • No audio recording unit test
  • No recording -> transcription -> paste end-to-end
  • No Android voice recording test
  • No silence detection unit test
medium 1/1
2/3
Encoder & Button Interaction
Dial rotate -> option scroll -> push select. Button press -> action trigger. Label rendering.
  • No encoder rotate/push integration test
  • No wide canvas takeover test
  • No Android Deck gesture test
medium 2/3
4/5
Usage Tracking & Rate Limits
API usage fetch -> rate limit gauge -> sibling relay (429 prevention) -> dashboard display.
  • No real API rate limit response test
  • No usage_update WS relay end-to-end
medium 0/12/22/2
2/2
Daemon Singleton Guard
PID check -> port probe -> prevent double daemon. Auto-fallback on port conflict.
  • No port conflict auto-fallback test
  • No LaunchAgent KeepAlive loop prevention test
medium 1/11/1
1/1
Hook Installation & Migration
Install Claude Code hooks -> migrate v2.0 flat format to v2.1 matcher groups -> port injection.
  • No real settings.local.json file test
  • No hook execution verification test
medium 1/1
Coverage
v8 provider · 18,354 lines tracked
Lines ≥17%: 36.2%
Functions ≥15%: 33.0%
Branches ≥14%: 31.9%
Statements ≥16%: 34.9%
bridge
37% Lines
35% Stmts
35% Funcs
32% Branch
4900/13403 lines covered
plugin
28% Lines
26% Stmts
22% Funcs
21% Branch
1016/3688 lines covered
shared
52% Lines
52% Stmts
44% Funcs
46% Branch
517/997 lines covered
hooks
84% Lines
82% Stmts
87% Funcs
76% Branch
222/266 lines covered
File Stmts Branch Funcs Lines
bridge/src/adb-reverse.ts 0% 0% 0% 0%
bridge/src/check-deps.ts 0% 0% 0% 0%
bridge/src/cli.ts 0% 0% 0% 0%
bridge/src/daemon-server.ts 0% 0% 0% 0%
bridge/src/daemon-ws-client.ts 0% 0% 0% 0%
bridge/src/daemon.ts 0% 0% 0% 0%
bridge/src/diag-analyzer.ts 0% 0% 0% 0%
bridge/src/event-journal.ts 0% 0% 0% 0%
bridge/src/hook-migration.ts 0% 0% 0% 0%
bridge/src/index.ts 0% 0% 0% 0%
bridge/src/log-stream.ts 0% 100% 0% 0%
bridge/src/pty-ringbuffer.ts 0% 0% 0% 0%
bridge/src/session-focus-relay.ts 0% 0% 0% 0%
bridge/src/terminal-status.ts 0% 0% 0% 0%
bridge/src/tts.ts 0% 0% 0% 0%
bridge/src/types.ts 0% 0% 0% 0%
bridge/src/utility-proxy.ts 0% 0% 0% 0%
bridge/src/version-check.ts 0% 0% 0% 0%
bridge/src/voice-assistant.ts 0% 0% 0% 0%
bridge/src/voice.ts 0% 0% 0% 0%
bridge/src/wake-word.ts 0% 0% 0% 0%
bridge/src/whisper-server-manager.ts 0% 0% 0% 0%
bridge/src/wifi-config.ts 0% 0% 0% 0%
bridge/src/apme/dashboard-html.ts 0% 100% 0% 0%
bridge/src/apme/types.ts 0% 0% 0% 0%
bridge/src/idotmatrix/idotmatrix-settings.ts 0% 0% 0% 0%
bridge/src/modules/adb-module.ts 0% 0% 0% 0%
bridge/src/modules/d200h-module.ts 0% 0% 0% 0%
bridge/src/modules/d200h-renderer.ts 0% 0% 0% 0%
bridge/src/modules/index.ts 0% 0% 0% 0%
bridge/src/modules/mdns-module.ts 0% 100% 0% 0%
bridge/src/modules/pixoo-module.ts 0% 0% 0% 0%
bridge/src/modules/serial-module.ts 0% 0% 0% 0%
bridge/src/modules/types.ts 0% 0% 0% 0%
bridge/src/pixoo/pixoo-settings.ts 0% 0% 0% 0%
bridge/src/tui/screen.ts 0% 0% 0% 0%
bridge/src/types/picovoice.d.ts 0% 0% 0% 0%
bridge/src/adapters/opencode-adapter.ts 0% 0% 0% 1%
bridge/src/apme/index.ts 3% 0% 0% 3%
bridge/src/pixoo/pixoo-font.ts 3% 0% 0% 4%
bridge/src/apme/hw-sampler.ts 6% 4% 20% 4%
bridge/src/ollama-probe.ts 5% 0% 0% 5%
bridge/src/tui/dashboard.ts 5% 11% 3% 6%
bridge/src/mdns.ts 5% 5% 10% 6%
bridge/src/antigravity-local.ts 7% 4% 20% 6%
bridge/src/mlx-probe.ts 6% 0% 0% 6%
bridge/src/apme/outcome.ts 8% 2% 8% 8%
bridge/src/pixoo/pixoo-renderer.ts 6% 0% 0% 8%
bridge/src/pixoo/pixoo-camera.ts 8% 0% 0% 8%
bridge/src/pixoo/pixoo-client.ts 10% 0% 0% 10%
bridge/src/d200h/hid-protocol.ts 11% 0% 0% 12%
bridge/src/pixoo/pixoo-bridge.ts 12% 0% 0% 14%
bridge/src/logger.ts 18% 10% 17% 15%
bridge/src/timeline-summarizer.ts 13% 0% 0% 15%
bridge/src/pixoo/pixoo-sprites.ts 14% 0% 7% 16%
bridge/src/gateway-probe.ts 12% 0% 0% 16%
bridge/src/display-monitor.ts 20% 9% 18% 22%
bridge/src/esp32-serial.ts 25% 20% 19% 27%
bridge/src/usage-api.ts 26% 12% 50% 28%
bridge/src/d200h/image-renderer.ts 35% 64% 45% 36%
bridge/src/codex-auth.ts 36% 8% 25% 37%
bridge/src/bridge-core.ts 36% 39% 26% 37%
bridge/src/usage-tracker.ts 44% 55% 23% 44%
bridge/src/opencode-client.ts 40% 38% 57% 44%
bridge/src/model-catalog.ts 39% 17% 36% 46%
bridge/src/passive-observer.ts 45% 39% 40% 50%
bridge/src/pty-manager.ts 54% 31% 53% 55%
bridge/src/hook-server.ts 53% 30% 53% 55%
bridge/src/ws-server.ts 60% 31% 58% 59%
bridge/src/adapters/openclaw.ts 59% 41% 54% 61%
bridge/src/auth.ts 59% 37% 75% 63%
bridge/src/apme/recommend.ts 58% 32% 67% 64%
bridge/src/tui/terrarium.ts 62% 48% 64% 64%
bridge/src/usage-event.ts 72% 72% 100% 71%
bridge/src/session-registry.ts 69% 43% 67% 71%
bridge/src/tui/renderer.ts 70% 57% 92% 71%
bridge/src/apme/classifier.ts 65% 66% 74% 71%
bridge/src/adapters/index.ts 71% 67% 100% 71%
bridge/src/adapters/claude-code.ts 73% 40% 50% 73%
bridge/src/tui/ansi.ts 75% 49% 83% 75%
bridge/src/apme/store.ts 66% 69% 81% 79%
bridge/src/session-aggregator.ts 81% 56% 89% 79%
bridge/src/adapters/monitor.ts 81% 60% 87% 81%
bridge/src/adapters/pty-adapter.ts 82% 81% 65% 82%
bridge/src/apme/runner.ts 76% 64% 69% 82%
bridge/src/state-machine.ts 83% 64% 90% 83%
bridge/src/adapters/codex-cli.ts 83% 100% 75% 83%
bridge/src/session-timeline-relay.ts 80% 62% 71% 84%
bridge/src/apme/adapters/codex-hook.ts 79% 60% 100% 85%
bridge/src/apme/collector.ts 80% 68% 88% 85%
bridge/src/apme/adapters/codex-turn-manager.ts 78% 58% 95% 86%
bridge/src/apme/http.ts 84% 79% 88% 86%
bridge/src/apme/tuner.ts 87% 73% 96% 89%
bridge/src/output-parser.ts 89% 83% 100% 93%
bridge/src/apme/adapters/timeline.ts 95% 80% 100% 94%
bridge/src/codex-output-parser.ts 90% 84% 93% 94%
bridge/src/apme/classify-turn.ts 91% 80% 100% 95%
bridge/src/apme/adapters/opencode-hook.ts 96% 83% 100% 95%
bridge/src/apme/adapters/openclaw-hook.ts 92% 70% 100% 96%
bridge/src/utils/project-name.ts 94% 88% 100% 96%
bridge/src/timeline-store.ts 97% 89% 100% 98%
bridge/src/awaiting-overlay.ts 100% 90% 100% 100%
bridge/src/permission-resolver.ts 98% 68% 100% 100%
bridge/src/apme/claude-transcript-reader.ts 91% 76% 100% 100%
bridge/src/apme/settings.ts 97% 86% 100% 100%
bridge/src/apme/adapters/claude-hook.ts 100% 75% 100% 100%
bridge/src/apme/adapters/claude-pty.ts 100% 88% 100% 100%
bridge/src/tui/gauge.ts 98% 96% 100% 100%
hooks/src/install.ts 62% 69% 75% 64%
hooks/src/codex-install.ts 84% 62% 87% 87%
hooks/src/codex-mini-toml.ts 97% 94% 100% 100%
plugin/src/agent-link.ts 0% 0% 0% 0%
plugin/src/encoder-registry.ts 0% 0% 0% 0%
plugin/src/encoder-takeover.ts 0% 0% 0% 0%
plugin/src/label-summarizer.ts 0% 0% 0% 0%
plugin/src/plugin.ts 0% 0% 0% 0%
plugin/src/project-picker.ts 0% 0% 0% 0%
plugin/src/project-scanner.ts 0% 0% 0% 0%
plugin/src/timeline-store.ts 0% 0% 0% 0%
plugin/src/voice-local.ts 0% 0% 0% 0%
plugin/src/actions/iterm-dial.ts 0% 0% 0% 0%
plugin/src/actions/option-dial.ts 0% 0% 0% 0%
plugin/src/actions/session-slot-button.ts 0% 0% 0% 0%
plugin/src/actions/utility-dial.ts 0% 0% 0% 0%
plugin/src/actions/voice-dial.ts 0% 0% 0% 0%
plugin/src/renderers/agent-logos.ts 0% 0% 0% 0%
plugin/src/renderers/session-slot-renderer.ts 0% 0% 0% 0%
plugin/src/renderers/text-utils.ts 0% 0% 0% 0%
plugin/src/utility-modes/apme.ts 0% 0% 0% 0%
plugin/src/utility-modes/brightness.ts 0% 0% 0% 0%
plugin/src/utility-modes/darkmode.ts 0% 0% 0% 0%
plugin/src/utility-modes/diag.ts 0% 0% 0% 0%
plugin/src/utility-modes/index.ts 0% 0% 0% 0%
plugin/src/utility-modes/macos.ts 0% 0% 0% 0%
plugin/src/utility-modes/media.ts 0% 0% 0% 0%
plugin/src/utility-modes/mic.ts 0% 0% 0% 0%
plugin/src/utility-modes/permission-mode.ts 0% 0% 0% 0%
plugin/src/utility-modes/timer.ts 0% 0% 0% 0%
plugin/src/utility-modes/tower.ts 0% 0% 0% 0%
plugin/src/utility-modes/types.ts 0% 0% 0% 0%
plugin/src/utility-modes/volume.ts 0% 0% 0% 0%
plugin/src/bridge-client.ts 55% 35% 67% 59%
plugin/src/renderers/timeline-renderer.ts 58% 34% 75% 63%
plugin/src/session-slot-manager.ts 66% 54% 68% 66%
plugin/src/log.ts 59% 50% 33% 67%
plugin/src/utility-modes/usage.ts 65% 47% 43% 73%
plugin/src/renderers/usage-dial-renderer.ts 75% 55% 91% 80%
plugin/src/renderers/button-renderer.ts 82% 72% 100% 82%
plugin/src/renderers/response-renderer.ts 85% 40% 92% 87%
plugin/src/connection-manager.ts 85% 79% 81% 88%
plugin/src/renderers/voice-renderer.ts 88% 57% 87% 90%
plugin/src/renderers/option-renderer.ts 92% 69% 100% 93%
plugin/src/layout-manager.ts 95% 92% 100% 95%
plugin/src/renderers/utility-renderer.ts 98% 57% 100% 98%
plugin/src/renderers/qr-renderer.ts 98% 90% 80% 98%
plugin/src/center-slot.ts 100% 100% 100% 100%
shared/src/adapter.ts 0% 100% 100% 0%
shared/src/command-builders.ts 0% 100% 0% 0%
shared/src/design-tokens.ts 0% 100% 100% 0%
shared/src/eval-schema.ts 0% 100% 0% 0%
shared/src/gateway-protocol.ts 0% 100% 100% 0%
shared/src/index.ts 0% 0% 0% 0%
shared/src/net-utils.ts 0% 0% 0% 0%
shared/src/telemetry-envelope.ts 0% 0% 0% 0%
shared/src/voice-paths.ts 0% 0% 0% 0%
shared/src/svg-renderers/index.ts 0% 0% 0% 0%
shared/src/svg-renderers/text-utils.ts 2% 0% 0% 2%
shared/src/svg-renderers/session-slot-renderer.ts 9% 5% 10% 8%
shared/src/svg-renderers/agent-logos.ts 14% 0% 0% 14%
shared/src/state-colors.ts 15% 0% 0% 17%
shared/src/format-utils.ts 42% 41% 29% 42%
shared/src/timeline-summarizer.ts 73% 63% 57% 76%
shared/src/timeline.ts 74% 70% 100% 80%
shared/src/timeline-icons.ts 88% 82% 75% 85%
shared/src/session-utils.ts 87% 70% 100% 86%
shared/src/llm-settings.ts 100% 98% 100% 100%
shared/src/protocol.ts 100% 100% 100% 100%
shared/src/states.ts 100% 100% 100% 100%
shared/src/timeline-markdown.ts 99% 92% 100% 100%