Status
PASS
1449 executed tests
Passed
1449
100.0% pass rate
Failed
0
 
Duration
16.9s
9.3s vitest + 7.6s android
TS Line Coverage
35.9%
6,240/17,398 TypeScript lines
Total Tests
1449
Pass Rate
100.0%
Line Coverage
35.9%

Vitest

PASS
Pass 1267 Fail 0 57 files Coverage + JSON report

Android

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

Apple (XCTest)

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

Robot Framework

PASS
Pass 7Fail 0Skip 0
Terminal Output Parsing PASS
Claude Code와 Codex CLI의 터미널 출력을 정확히 해석하는가?
248 passed 0 failed 3 files 259ms
output-parser.test.ts
205 / 205 196ms
OutputParser 205 / 205
basic option parsing › parses clean numbered options with newlines
17.40769800000004ms
basic option parsing › detects (recommended) marker
2.3893749999999727ms
basic option parsing › detects ✔ selected marker
1.425907000000052ms
basic option parsing › handles both recommended and selected on different options
1.21727199999998ms
basic option parsing › parses full Claude model selector with labels and middle dot
1.3564730000000509ms
ANSI-stripped options › parses concatenated text with · delimiter
1.2871680000000651ms
ANSI-stripped options › extracts version numbers from · delimited labels
0.7456779999999981ms
chunked input debounce › does NOT emit immediately on first chunk
0.7435050000000274ms
chunked input debounce › batches multiple chunks into single emission
1.4453970000000709ms
chunked input debounce › resets debounce timer when new chunk with options arrives
3.568512999999939ms
chunked input debounce › simulates real /model flow: split across chunks
1.1885690000000295ms
model ID date rejection › does NOT parse 20251001 from model ID as option number
0.8373269999999593ms
model ID date rejection › rejects large numbers that look like dates
0.5840540000000374ms
version number rejection › does NOT parse version "4.6" followed by digit as option
1.0951370000000225ms
version number rejection › does NOT parse "6)" from "4.6)" as option 6
0.9936030000000073ms
stale buffer overwrite › newer options overwrite older ones with same index
1.2128250000000662ms
permission prompts › detects Yes/No/Always pattern
2.0250240000000304ms
permission prompts › detects (Y)es/(N)o pattern
1.147006000000033ms
permission prompts › emits immediately with no debounce
0.7122679999999946ms
permission prompts › sets yes_no_always prompt type
0.617984999999976ms
permission prompts › sets yes_no prompt type
0.5839829999999893ms
permission prompts › suppresses false idle from user prompt echo after permission (interactive cooldown)
1.0748370000000023ms
permission prompts › allows real idle after interactive cooldown expires
0.8535319999999729ms
diff prompts › detects (V)iew/(A)pply/(D)eny pattern
1.3201980000000049ms
diff prompts › detects lowercase (a)pply/(d)eny/(v)iew pattern
0.7419929999999795ms
diff prompts › emits immediately with no debounce
0.6616910000000189ms
diff prompts › suppresses false idle from user prompt echo after diff (interactive cooldown)
0.9392410000000382ms
various option counts › handles 1 option
0.789935000000014ms
various option counts › handles 2 options
0.818719000000101ms
various option counts › handles 5+ options
0.8407819999999901ms
various option counts › handles bullet-style options
0.8752139999999144ms
option updates › emits new options when data changes after first emission
1.168798000000038ms
spinner cancels option timer › spinner cancels pending option debounce
0.8871920000000273ms
idle vs option debounce › idle prompt is ignored when option debounce is pending
3.776132999999959ms
idle vs option debounce › idle prompt fires normally when no option debounce is pending
0.6484310000000733ms
interactive prompt during spinner › stops spinner when permission prompt arrives
1.3047639999999774ms
interactive prompt during spinner › stops spinner when diff prompt arrives
0.9413540000000467ms
interactive prompt during spinner › stops spinner when option prompt arrives
0.9179490000000214ms
interactive prompt during spinner › stops spinner when idle prompt arrives in small chunk
1.0948260000000118ms
interactive prompt during spinner › ignores idle prompt in large chunk during spinner (screen redraw)
0.7587479999999687ms
cleanOptionLabel (via parseOptions) › deduplicates exact CamelCase matches
0.9276730000000271ms
cleanOptionLabel (via parseOptions) › preserves labels without · delimiter
0.5734479999999849ms
cleanOptionLabel (via parseOptions) › removes (recommended) from label text
0.78287499999999ms
cleanOptionLabel (via parseOptions) › removes ✔ from label text
0.716865000000098ms
cleanOptionLabel (via parseOptions) › extracts version from identity before middle dot
0.5648350000000164ms
metadata events › emits project_name from startup banner
0.526597000000038ms
metadata events › emits project_name only once (caches)
0.5530860000000075ms
metadata events › parses absolute path for project_name
0.5734180000000606ms
metadata events › emits model_info with model and plan
0.5999580000000151ms
metadata events › emits model_info without plan
0.46252000000004045ms
metadata events › emits model_info only once for same model (caches)
0.43254400000000714ms
metadata events › re-emits model_info when model changes
0.438562999999931ms
metadata events › parses ANSI-stripped model_info
0.48266000000000986ms
metadata events › detects API billing plan
0.5289699999999584ms
metadata events › emits status_line with duration and tokens
0.5062459999999191ms
metadata events › parses zero-minute status line
0.56565599999999ms
metadata events › emits tool_action from ⏺ pattern
0.5936879999999292ms
metadata events › extracts various tool names
0.5471880000000056ms
user prompt › emits user_prompt after first idle has been seen
0.7057079999999587ms
user prompt › does NOT emit user_prompt before first idle
0.5666479999999865ms
user prompt › filters out mode banner text
0.6274700000000166ms
user prompt › filters out numbered option lines
0.627418999999918ms
user prompt › filters out keyboard hint text
0.6239640000000009ms
user prompt › filters out "esc to interrupt" text
0.6160119999999552ms
user prompt › filters out autocomplete suggestions
1.7507590000000164ms
user prompt › filters out box-drawing decorative lines
0.6769339999999602ms
usage info › parses usage percentage
0.6703840000000127ms
usage info › parses usage cost
0.7128780000000461ms
usage info › parses session percentage with hour limit
0.5757809999998926ms
usage info › parses reset time with timezone
0.5462560000000849ms
usage info › parses time remaining
0.5601669999999785ms
spinner lifecycle › emits spinner_start on spinner char (after idle seen)
0.4483189999999695ms
spinner lifecycle › does NOT emit spinner_start before first idle
0.49171400000000176ms
spinner lifecycle › emits spinner_stop after debounce (2000ms)
0.6323270000000321ms
spinner lifecycle › does NOT emit duplicate spinner_start on repeated chars
0.903385999999955ms
spinner lifecycle › resets spinner debounce timer on repeated chars
0.9149740000000293ms
spinner lifecycle › ignores spinner chars in large text blocks (>80 non-ws)
0.7887129999999161ms
spinner lifecycle › recognizes all spinner characters
1.7978400000000647ms
idle detection › emits idle after IDLE_DEBOUNCE_MS (300ms)
0.8335610000000315ms
idle detection › sets seenFirstIdle on first idle prompt
0.7875609999999824ms
idle detection › cancels idle timer when spinner starts
0.8858209999999644ms
idle detection › recognizes > as idle prompt char
0.5950200000000905ms
mode detection › detects plan mode
0.5866869999999835ms
mode detection › detects accept edits mode
0.6428530000000592ms
mode detection › detects default mode after Shift+Tab
0.666027999999983ms
mode detection › detects default mode via idle prompt after Shift+Tab
0.7097740000000385ms
mode detection › emits default mode on Shift+Tab timeout (2s)
0.7639960000000201ms
mode detection › detects ANSI-stripped plan mode text
0.6177640000000792ms
mode detection › detects ANSI-stripped accept edits text
0.6129369999999881ms
mode detection › clears pending mode switch when mode banner is detected
0.6960730000000694ms
reset › clears cached project name and model name
0.8544430000000602ms
reset › disables spinner detection (clears seenFirstIdle)
0.6487509999999475ms
reset › allows re-detection after new idle prompt post-reset
0.6535890000000109ms
reset › allows re-detection of project name after reset
0.5385150000000749ms
reset › allows re-detection of model info after reset
0.5039419999999382ms
buffer management › truncates buffer when exceeding 8192 chars
1.2325649999999087ms
buffer management › keeps the last 4096 chars after truncation
1.295400000000086ms
option navigation › cursor movement during option selection does NOT trigger idle
1.132233000000042ms
option navigation › cursor movement does NOT trigger user_prompt
1.0390619999999444ms
option navigation › normal cursor movement between options emits no idle or user_prompt
0.9704179999999951ms
option navigation › real idle prompt still works after option navigation
1.064300000000003ms
option navigation › effort/hint text during navigation does not trigger events
1.00664299999994ms
option navigation › IDLE_PROMPT requires space/tab/NBSP after ❯ (not newline)
0.7669700000000148ms
option navigation › USER_PROMPT requires space/tab after ❯ (not newline)
0.9580789999999979ms
permission reclassification › reclassifies numbered Yes/No options as permission_prompt
1.2290990000000193ms
permission reclassification › does NOT reclassify regular options as permission
0.9573780000000625ms
permission reclassification › does NOT reclassify cursor-selection UI with "Enter to confirm" as permission
0.902875999999992ms
permission reclassification › detects cursor-selection UI even when ANSI stripping removes spaces
0.8195399999999609ms
permission reclassification › includes navigable and cursorIndex in reclassified permission_prompt
0.8683240000000296ms
permission reclassification › infers shortcuts for reclassified permission options
0.8473520000000008ms
permission reclassification › infers shortcut "a" for "don't ask again" labels
0.9705380000000332ms
permission reclassification › infers shortcut "a" for "allow all sessions" labels
0.9395119999999224ms
ghost text suggestion › detects SGR 90 (bright black) ghost text on prompt line
2.1596869999999626ms
ghost text suggestion › detects ghost text via Strategy 1 (Try "..." in clean text)
0.7622829999999112ms
ghost text suggestion › unwraps Try "..." wrapper with smart quotes
0.7809110000000601ms
ghost text suggestion › unwraps Try "..." wrapper with straight quotes
0.826279999999997ms
ghost text suggestion › detects ghost text on first idle (❯ and suggestion in same chunk)
0.8443780000000061ms
ghost text suggestion › clears suggestion on spinner start
0.7379170000000386ms
ghost text suggestion › debounces rapid updates
1.0001330000000053ms
ghost text suggestion › ignores dim (SGR 2) text without ❯ prompt context
0.904989999999998ms
ghost text suggestion › detects dim (SGR 2) ghost text on ❯ prompt line
2.5202039999999215ms
ghost text suggestion › detects ghost text with cursor-forward spacing (Strategy 1)
0.7009109999999055ms
ghost text suggestion › filters UI chrome fragments
1.207977000000028ms
ghost text suggestion › filters box-drawing lines as UI chrome
0.9230370000000221ms
ghost text suggestion › filters file paths (false positive from screen redraws)
0.9103679999999486ms
ghost text suggestion › detects 256-color gray ghost text
0.7740609999999606ms
ghost text suggestion › handles multi-segment ghost text on prompt line
0.8040760000000091ms
ghost text suggestion › ignores ghost text on non-prompt lines
0.5866579999999431ms
ghost text suggestion › detects 24-bit RGB gray ghost text
0.7047559999999748ms
ghost text suggestion › ignores 24-bit RGB non-gray colors (e.g. blue prompt char)
0.6480400000000373ms
ghost text suggestion › filters out short gray text like prompt char itself
0.6127469999998993ms
ghost text suggestion › suppresses ghost text detection during spinner (processing)
1.8909110000000737ms
ghost text suggestion › rejects digit+operator fragments like diff markers "96 +"
0.7292429999999968ms
ghost text UI chrome filtering › filters out "Tip:" segments on prompt line
0.735952999999995ms
ghost text UI chrome filtering › filters out "(ctrl+...)" shortcut hints on prompt line
0.6235130000000026ms
ghost text UI chrome filtering › filters concatenated UI chrome even in scheduleSuggestion
0.6394480000000158ms
ghost text UI chrome filtering › keeps ghost text when UI chrome is also present on the line
0.7860800000000836ms
filters out extended thinking indicators › rejects "(thought for 1s)" as ghost text via isUiChrome
0.621270000000095ms
filters out extended thinking indicators › rejects "(thought for 1s)>" via scheduleSuggestion
0.5699029999999539ms
filters out extended thinking indicators › rejects longer thinking durations like "(thought for 15s)"
0.47371700000007877ms
filters out extended thinking indicators › rejects "(thought for 1m 30s)" multipart duration
0.4523439999999255ms
filters out extended thinking indicators › rejects "✻ Cooked for 1m 26s" sparkle indicator
0.4084380000000465ms
filters out extended thinking indicators › rejects "✻ Cooked for 5s" short duration variant
0.4277869999999666ms
filters out extended thinking indicators › rejects "Cooked for 10s" without sparkle (cross-chunk)
0.5267470000000003ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 2 (dim)
0.45685100000002876ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 90 (bright black)
0.5025510000000395ms
parenthesized placeholder filtering › rejects "(loading...)"
0.5020700000000033ms
parenthesized placeholder filtering › rejects "(empty)"
0.4377719999999954ms
parenthesized placeholder filtering › rejects "(waiting for response)"
0.5610289999999623ms
parenthesized placeholder filtering › allows "fix the broken (auth) module" — parens in middle
0.7212009999999509ms
parenthesized placeholder filtering › allows "(optional) refactor the code" — paren prefix with text after
0.7508559999999989ms
stacked ANSI + cross-chunk ghost text › detects ghost text with stacked ANSI escapes (gray + italic)
0.8831959999999981ms
stacked ANSI + cross-chunk ghost text › detects ghost text with combined SGR params (2;90 = dim+bright-black)
0.7999300000000176ms
stacked ANSI + cross-chunk ghost text › detects cross-chunk ghost text (❯ and gray text in separate feeds)
1.2524650000000292ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when chunk contains ⎿ output fence
0.760089999999991ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when new chunk has \n (different line)
0.8580080000000407ms
ghost option from stale buffer › excludes stale numbered list items before actual option prompt
1.4517769999999928ms
ghost option from stale buffer › bypasses chunk size guard when ❯ cursor is present in large chunk
1.1164590000000771ms
ghost option from stale buffer › still works with scrambled TUI order after backward scan
0.9094959999999901ms
ghost option from stale buffer › excludes file path fragments from Read() tool in permission prompt
1.2175130000000536ms
option index ordering › returns options sorted by index even when TUI lines arrive out of order
0.9869930000000977ms
split ANSI sequence buffering › handles ANSI SGR codes split across chunks
0.9561469999999872ms
split ANSI sequence buffering › handles bare ESC at end of chunk
1.079232999999931ms
split ANSI sequence buffering › does not buffer complete ANSI sequences
0.8773469999999861ms
large chunk guard for option detection › does NOT detect numbered items in large response chunks as options
0.7944820000000163ms
large chunk guard for option detection › still detects real options in small TUI chunks
0.8744440000000395ms
CUP-positioned options › parses options using CUP (\x1b[row;colH) instead of newlines
1.1373510000000806ms
CUP-positioned options › parses options using CUD (\x1b[B) for vertical movement
1.0162180000000944ms
trailing TUI chrome stripping › strips "Esc to cancel" from last option label
1.0083460000000741ms
trailing TUI chrome stripping › strips "Enter to confirm" from last option label
0.6754519999999502ms
trailing TUI chrome stripping › does NOT strip "Esc" when it appears within legitimate label text
0.7182770000000573ms
CJK suggestion detection › accepts ghost text containing CJK characters
1.9590339999999742ms
CJK suggestion detection › accepts ghost text that is purely CJK (no ASCII words)
1.2175320000000056ms
AskUserQuestion with separators and descriptions › handles AskUserQuestion with separator and descriptions
0.9514799999999468ms
AskUserQuestion with separators and descriptions › handles options starting from non-zero index (buffer truncation)
0.6391569999999547ms
hierarchical CC prompt shapes › captures 5-option plan approval with long labels
0.7551829999999882ms
hierarchical CC prompt shapes › captures OpenClaw scope selection (numbered list)
0.7650479999999789ms
hierarchical CC prompt shapes › captures OpenClaw token-action step (short numbered list)
0.8344720000000052ms
permission scroll does not trigger idle (Bug 1) › scroll chunk with ❯ option text does NOT cause idle when navigable
1.1592339999999695ms
permission scroll does not trigger idle (Bug 1) › /model combined chunk: confirmation + idle prompt clears options
0.8455300000000534ms
permission scroll does not trigger idle (Bug 1) › /model separate chunks: ANSI reposition timer does not block idle
0.8178770000000668ms
permission scroll does not trigger idle (Bug 1) › cursor move chunk with option text does NOT falsely trigger idle
0.8585079999999152ms
permission scroll does not trigger idle (Bug 1) › genuine idle prompt exits navigable state and emits idle
0.6626430000000028ms
TUI cursor-overwrite label correction (Bug 2) › fixes contaminated permission option label using correction line
1.0193819999999505ms
TUI cursor-overwrite label correction (Bug 2) › leaves labels unchanged when no correction line is present
0.6715659999999843ms
genuine idle detection (semantic) › "❯ \n" is genuine idle — only prompt character, no label text
0.587368999999967ms
genuine idle detection (semantic) › "❯ Beta" is NOT idle — has label text after prompt char
0.6577949999999646ms
genuine idle detection (semantic) › "❯ A" is NOT idle — single-char label still counts
2.903773000000001ms
genuine idle detection (semantic) › ">" also treated as idle prompt character
0.5225709999999708ms
effort level parsing › detects "High effort" selection pattern
0.4500509999999167ms
effort level parsing › detects "Medium effort" selection pattern
0.41267499999992197ms
effort level parsing › detects "Low effort" selection pattern
0.4252040000000079ms
effort level parsing › detects "with high effort" confirmation line
0.3761500000000524ms
effort level parsing › detects effort in model info line
0.4661750000000211ms
effort level parsing › caches effort level — no re-emit on same value
0.35128099999997175ms
effort level parsing › emits on effort level change
0.44128699999998844ms
effort level parsing › resets effort level on reset()
0.35595899999998437ms
effort level parsing › does not match "effort" in unrelated context
0.3216370000000097ms
effort level parsing › does not match effort inside numbered option lines
0.4847829999999931ms
effort level parsing › getter returns current effort level
0.3394139999999197ms
effort level parsing › detects "Max effort" (Opus 4.7 variant)
0.3745159999999714ms
effort level parsing › detects "xhigh effort" (Opus 4.7 variant)
0.4701110000000881ms
effort level parsing › detects "default effort" (per-model default variant)
0.40957000000003063ms
effort level parsing › detects "fast effort" (Opus 4.6 variant)
0.4110519999999269ms
effort level parsing › detects effort in /model confirmation line with max
0.3694990000000189ms
codex-output-parser.test.ts
28 / 28 35ms
CodexOutputParser 28 / 28
idle detection › emits idle on ❯ prompt with source=prompt
10.333510000000018ms
idle detection › emits idle on > prompt
1.3649049999999932ms
idle detection › debounces rapid idle signals
0.7380660000000034ms
spinner detection › emits spinner_start on braille spinner chars after first idle
1.3730159999999785ms
spinner detection › does not emit spinner_start before first idle
0.8604109999999991ms
spinner detection › emits spinner_stop + idle on timeout with source=timeout
0.8611720000000105ms
spinner detection › emits spinner_stop when idle prompt appears
0.636952999999977ms
spinner detection › detects "Thinking" text as processing
0.6010789999999986ms
permission prompt detection › emits permission_prompt on Allow/Deny pattern
1.7899579999999844ms
permission prompt detection › emits permission_prompt on y/n pattern
0.8844380000000172ms
permission prompt detection › stops spinner when approval detected
0.6402279999999791ms
permission prompt detection › extracts Allow once / Always allow options
0.7779069999999706ms
tool action detection › detects Running: command pattern
2.8469159999999647ms
tool action detection › detects file operation patterns
0.8540019999999799ms
tool action detection › detects Editing file pattern
0.7292429999999968ms
tool action detection › dedups repeated emits of the same (tool, args) within window
0.5959910000000264ms
tool action detection › emits a different command immediately
0.5317739999999844ms
tool action detection › re-emits the same command after the dedup window elapses
0.5854649999999992ms
tool action detection › re-emits the same command after a turn boundary (idle resets dedup)
0.7334199999999669ms
model info detection › detects gpt model name
0.6507540000000063ms
model info detection › detects o-series model
0.5870080000000257ms
model info detection › does not re-emit same model
0.5186139999999568ms
project name detection › detects working directory
0.857056ms
project name detection › detects project from path
0.5805879999999775ms
project name detection › only detects project name once
0.5622910000000161ms
buffer management › truncates buffer at 8192 chars
0.5325349999999958ms
buffer management › handles incomplete ANSI sequences
0.6519260000000031ms
getProjectName › returns null when no project detected
0.5053639999999859ms
cursor-sync.test.ts
15 / 15 28ms
Cursor Synchronization 15 / 15
terminal keyboard cursor tracking › emits cursor_update when full option redraw arrives with ❯ at new position
13.07074ms
terminal keyboard cursor tracking › triggers buffer re-parse on small non-❯ chunk during navigable state
1.9221469999999954ms
terminal keyboard cursor tracking › does not emit cursor_update when cursor position unchanged
0.816114999999968ms
genuine idle distinction › treats "❯ \n" as genuine idle (clears navigable state)
0.841303000000039ms
genuine idle distinction › does NOT treat "❯ Beta" as idle (cursor on option label)
0.9801120000000196ms
genuine idle distinction › does NOT treat "❯ Allow once" as idle (permission cursor move)
1.2763699999999858ms
cursor authority in StateMachine › accepts optimistic update immediately
1.8308900000000108ms
cursor authority in StateMachine › suppresses stale PTY value within 200ms of optimistic update
0.6607789999999909ms
cursor authority in StateMachine › accepts PTY value after 200ms grace period
1.6134009999999535ms
cursor authority in StateMachine › always accepts PTY when no recent optimistic update
0.692436999999984ms
cursor authority in StateMachine › resets authority on state transition out of AWAITING
0.9247790000000009ms
cursor authority in StateMachine › default source parameter is pty
0.565324999999973ms
select_option proportional delay › delay scales with step count
0.5801780000000463ms
option re-emission with cursorIndex › AWAITING_OPTION update triggers state_changed with options
0.8773370000000114ms
option re-emission with cursorIndex › updateCursorIndex emits snapshot with new cursor value
0.7099739999999883ms
State Machine & Adapters PASS
에이전트의 상태 전이와 타입별 명령 라우팅이 정확한가?
175 passed 0 failed 3 files 163ms
state-machine.test.ts
57 / 57 51ms
StateMachine 57 / 57
basic transitions › starts in DISCONNECTED
5.195641000000023ms
basic transitions › SessionStart → IDLE
1.5456590000000006ms
basic transitions › UserPromptSubmit → PROCESSING
1.135266999999999ms
basic transitions › Stop → IDLE from PROCESSING
0.8825649999999996ms
basic transitions › SessionEnd → DISCONNECTED from any state
0.5726469999999608ms
permission flow › permission_prompt → AWAITING_PERMISSION
1.079813999999999ms
permission flow › user respond → PROCESSING from AWAITING_PERMISSION
0.8741729999999848ms
option flow › option_prompt → AWAITING_OPTION
0.6827329999999847ms
option flow › select_option → PROCESSING from AWAITING_OPTION
0.6704040000000191ms
diff flow › diff_prompt → AWAITING_DIFF
0.6712360000000217ms
diff flow › respond → PROCESSING from AWAITING_DIFF
0.6456670000000031ms
interrupt › interrupt → IDLE from PROCESSING
0.561930000000018ms
interrupt › interrupt → IDLE from AWAITING_PERMISSION
0.6522070000000326ms
strict transitions › allows IDLE → AWAITING_PERMISSION (prompt without spinner)
0.6329379999999674ms
strict transitions › blocks invalid transition: DISCONNECTED → PROCESSING
0.3950280000000248ms
strict transitions › allows wildcard session_end from any state
0.49538899999998876ms
stuck timeout › PROCESSING for >5min → auto-recovery to IDLE
1.3146790000000124ms
stuck timeout › AWAITING_PERMISSION does NOT timeout (waits for user)
0.7316969999999969ms
stuck timeout › AWAITING_OPTION does NOT timeout (waits for user)
0.6543100000000095ms
stuck timeout › AWAITING_DIFF does NOT timeout (waits for user)
1.593170999999984ms
stuck timeout › timer resets on state change before timeout
0.7701250000000073ms
stuck timeout › no timeout in IDLE state
0.6070880000000329ms
parser events › spinner_start → PROCESSING from IDLE
0.607009000000005ms
parser events › spinner_stop → IDLE from PROCESSING
0.5713339999999789ms
parser events › idle → IDLE from PROCESSING
0.6797980000000052ms
parser events › mode_change updates permission mode
0.7228440000000091ms
snapshot › emits state_changed on transitions
0.6128370000000132ms
snapshot › includes tool info in snapshot
0.7075600000000009ms
snapshot › clears tool info on PostToolUse
0.7321380000000204ms
snapshot › includes project name and model
0.8467510000000402ms
billingType detection › defaults to unknown
0.4703810000000317ms
billingType detection › detects subscription from "Claude Max" plan
0.6201989999999569ms
billingType detection › detects subscription from "Max" (case-insensitive)
0.6368439999999964ms
billingType detection › detects api from "api.anthropic.com"
0.5039730000000304ms
billingType detection › detects api (case-insensitive)
0.55146400000001ms
billingType detection › stays unknown for unrecognized plan
0.4553189999999745ms
billingType detection › stays unknown when plan is absent
0.5132570000000101ms
billingType detection › persists billingType across subsequent model_info without plan
0.593889000000047ms
billingType detection › emits state_changed when billingType is set
0.7369350000000168ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_OPTION to PROCESSING
0.6608699999999885ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_PERMISSION to PROCESSING
1.642906000000039ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_DIFF to PROCESSING
0.6179750000000013ms
spinner_start recovery from awaiting states › clears options and navigable state on spinner_start from AWAITING_OPTION
1.840865000000008ms
spinner_start recovery from awaiting states › stores navigable and cursorIndex from permission_prompt
0.6127670000000194ms
spinner_start recovery from awaiting states › cursor index tracking via updateCursorIndex
0.711275999999998ms
cursor authority (optimistic vs pty) › optimistic source updates cursor immediately
0.6000680000000216ms
cursor authority (optimistic vs pty) › suppresses stale PTY within 200ms of optimistic
0.5972229999999854ms
cursor authority (optimistic vs pty) › accepts PTY after 200ms grace period
0.5849850000000174ms
cursor authority (optimistic vs pty) › emits state_changed on optimistic update
0.7502649999999562ms
cursor authority (optimistic vs pty) › does NOT emit state_changed when stale PTY is suppressed
0.6496530000000007ms
codex_* hook events › codex_session_start → IDLE
0.5135169999999789ms
codex_* hook events › codex_user_prompt_submit → PROCESSING
0.606648000000007ms
codex_* hook events › codex_tool_start sets currentTool from tool_name
0.6243749999999864ms
codex_* hook events › codex_tool_end clears currentTool
0.6004580000000033ms
codex_* hook events › codex_stop → IDLE from PROCESSING
0.6636240000000271ms
codex_* hook events › codex_turn_complete is a snapshot-emit no-op for state
0.5498519999999871ms
codex_* hook events › full codex lifecycle preserves state transitions
0.652025999999978ms
adapter.test.ts
93 / 93 86ms
createAdapter factory 5 / 5
creates ClaudeCodeAdapter for "claude-code"
4.71919099999991ms
creates OpenClawAdapter for "openclaw"
1.1167689999999766ms
passes gatewayUrl to OpenClawAdapter
0.2210139999999683ms
creates CodexCliAdapter for "codex-cli"
0.7024320000000444ms
throws for unknown agent type
1.302361000000019ms
ClaudeCodeAdapter 17 / 17
capabilities › reports all Claude Code capabilities as true
1.0472939999999653ms
handleCommand routing › handles respond → returns true
0.6160520000000815ms
handleCommand routing › handles switch_mode → returns true
0.542220000000043ms
handleCommand routing › handles interrupt → returns true
0.5832920000000286ms
handleCommand routing › handles escape → returns true
0.338512000000037ms
handleCommand routing › defers select_option to bridge → returns false
0.30348899999989953ms
handleCommand routing › defers navigate_option to bridge → returns false
0.3470849999998791ms
handleCommand routing › defers send_prompt to bridge → returns false
0.344180999999935ms
handleCommand routing › defers voice to bridge → returns false
0.3173100000001341ms
handleCommand routing › defers query_usage to bridge → returns false
0.3594339999999647ms
switch_mode debounce › debounces rapid switch_mode calls (< 100ms apart)
0.9910590000001775ms
lifecycle › isAlive returns false before start
0.3155070000000251ms
lifecycle › getTtyPath returns undefined before start
0.31031899999993584ms
lifecycle › getProjectName returns null before start
0.35820200000011937ms
lifecycle › getHttpServer returns an object
0.322407000000112ms
onRawData callback › can register callback without error
0.5756609999998545ms
onDiag handler › can register handler without error
0.46867900000006557ms
OpenClawAdapter 17 / 17
capabilities › reports OpenClaw capabilities correctly
0.6258170000000973ms
handleCommand routing › handles respond → returns true (RPC)
0.5321850000000268ms
handleCommand routing › handles select_option → returns true (RPC)
0.30331900000010137ms
handleCommand routing › handles navigate_option → returns true (no-op)
0.21846099999993385ms
handleCommand routing › handles send_prompt → returns false without session key
0.3484770000000026ms
handleCommand routing › handles interrupt → returns true (RPC)
0.2832780000001094ms
handleCommand routing › handles escape → returns true (RPC)
0.20602199999984805ms
handleCommand routing › defers switch_mode → returns false (not supported)
0.21191099999987273ms
handleCommand routing › defers voice to bridge → returns false
0.1950249999999869ms
handleCommand routing › defers query_usage to bridge → returns false
0.23135999999999513ms
lifecycle › isAlive returns false before start
0.20610200000010082ms
lifecycle › getTtyPath returns undefined (no PTY)
0.19751900000005662ms
lifecycle › getProjectName returns null before start
0.19869999999991705ms
lifecycle › getHttpServer returns an object
0.2735139999999774ms
lifecycle › attachTerminal is a no-op
0.49919500000009975ms
onRawData callback › can register callback without error
0.419734999999946ms
onDiag handler › can register handler without error
0.3786729999999352ms
OpenClawAdapter gateway protocol 13 / 13
sends connect request with correct format on connect.challenge
4.215347999999949ms
becomes alive after hello-ok response
8.68712400000004ms
emits spinner_start on chat delta event
1.0418869999998606ms
emits idle on chat final event
1.060414000000037ms
emits idle on chat aborted event
0.9141030000000683ms
emits idle on chat error event
0.8017730000001393ms
emits permission_prompt on exec.approval.requested
1.105051999999887ms
sends exec.approval.resolve on respond after approval request
1.1301200000000335ms
sends exec.approval.resolve with deny on respond "n"
0.8166859999998906ms
sends chat.send on send_prompt with active session
1.1558880000000045ms
sends chat.abort on interrupt with active session and runId
1.331032999999934ms
emits SessionEnd on shutdown event
1.4246749999999793ms
clears pendingApprovalId on exec.approval.resolved
1.1740560000000642ms
CodexCliAdapter 16 / 16
capabilities › reports Codex CLI capabilities correctly
1.0669940000000224ms
handleCommand routing › handles respond → returns true
6.620116000000053ms
handleCommand routing › handles interrupt → returns true
0.3506599999998343ms
handleCommand routing › handles escape → returns true
0.3270349999997961ms
handleCommand routing › does not handle switch_mode → returns false
0.313754999999901ms
handleCommand routing › defers select_option to bridge → returns false
0.3219570000001113ms
handleCommand routing › defers navigate_option to bridge → returns false
1.404394999999795ms
handleCommand routing › defers send_prompt to bridge → returns false
0.3353669999999056ms
handleCommand routing › defers voice to bridge → returns false
1.5068100000000868ms
handleCommand routing › defers query_usage to bridge → returns false
0.34443099999998594ms
lifecycle › isAlive returns false before start
0.2878049999999348ms
lifecycle › getTtyPath returns undefined before start
0.3535949999998138ms
lifecycle › getProjectName returns null before start
0.3111410000001342ms
lifecycle › getHttpServer returns an object
0.3034989999998743ms
onRawData callback › can register callback without error
0.3474759999999151ms
onDiag handler › can register handler without error
0.287253999999848ms
CodexCliAdapter start lifecycle 2 / 2
emits SessionStart and connected on start
1.7959070000001702ms
feeds PTY data to output parser and emits activity
2.3849279999999453ms
MonitorAdapter 18 / 18
capabilities › reports monitor capabilities correctly
0.6831540000000587ms
handleCommand routing › rejects respond (no PTY)
0.2947060000001329ms
handleCommand routing › rejects interrupt (no PTY)
0.288396000000148ms
handleCommand routing › rejects escape (no PTY)
0.25001899999983834ms
handleCommand routing › rejects switch_mode (no PTY)
0.37442700000019613ms
handleCommand routing › rejects select_option (no PTY)
0.23375400000008995ms
handleCommand routing › rejects send_prompt (no PTY)
0.3479260000001432ms
handleCommand routing › defers voice to bridge
0.39165300000013303ms
handleCommand routing › defers query_usage to bridge
0.41770199999996294ms
lifecycle › isAlive always returns true
0.42208800000003066ms
lifecycle › getTtyPath returns undefined (no PTY)
0.43770199999994475ms
lifecycle › getProjectName returns null
0.4050520000000688ms
lifecycle › getHttpServer returns an object
0.39471800000001167ms
lifecycle › writeInput is a no-op (no PTY)
0.5582640000000083ms
lifecycle › attachTerminal is a no-op
0.5525260000001708ms
lifecycle › onRawData is a no-op
0.5378630000000157ms
start and event emission › emits connected event on start
0.7152320000000145ms
start and event emission › exposes hook server for external wiring
0.38830800000005183ms
ClaudeCodeAdapter start lifecycle 5 / 5
emits SessionStart and connected on start
1.7323810000000321ms
uses claude as default command
1.3521360000002005ms
feeds PTY data to output parser and emits activity
5.522465000000011ms
emits SessionEnd and disconnected on PTY exit
1.138091999999915ms
registers rawData callback without error
1.0642609999999877ms
protocol-contract.test.ts
25 / 25 26ms
Protocol Contract — StateUpdateEvent 5 / 5
minimal state_update has required fields
4.020873999999992ms
full state_update has all optional fields as correct types
1.1167090000000144ms
state_update serializes to valid JSON
0.27527700000001687ms
state enum values are lowercase strings
0.44552400000003445ms
promptType values match known set
0.24797499999999673ms
Protocol Contract — UsageEvent 3 / 3
has all required numeric fields
0.3733949999999595ms
rate limit fields are present when available
1.222880000000032ms
tokenStatus matches known values
0.19532600000002276ms
Protocol Contract — SessionsListEvent 2 / 2
sessions have required fields
0.6444160000000352ms
agentType is optional string
0.19559599999996635ms
Protocol Contract — ButtonStateEvent 1 / 1
buttons have required fields
0.7069999999999936ms
Protocol Contract — EncoderStateEvent 1 / 1
encoders have required fields
0.6727280000000064ms
Protocol Contract — TimelineEventMsg 1 / 1
entry has required fields
0.3514820000000327ms
Protocol Contract — ConnectionEvent 1 / 1
has required fields
0.32110600000004297ms
Protocol Contract — DisplayStateEvent 1 / 1
has boolean displayOn
0.25499600000000555ms
Protocol Contract — PluginCommand shapes 6 / 6
respond command has value
0.2401540000000182ms
select_option has numeric index
0.20571200000000545ms
navigate_option has direction
0.27846199999999044ms
send_prompt has text
0.19186999999999443ms
utility command has action
0.24772500000000264ms
clear_session_focus is fieldless
1.1016270000000077ms
Protocol Contract — BridgeEvent discriminated union 2 / 2
all event types in union have type field
2.6761790000000474ms
SERIAL_FORWARDED_EVENTS covers expected types
7.9859780000000455ms
Protocol Contract — Backward Compatibility 2 / 2
state_update can be parsed with only required fields (old client)
0.5032720000000381ms
usage_update required fields are sufficient for display
0.33281299999998737ms
Timeline Pipeline PASS
이벤트 타임라인의 저장, 중복 제거, 세션 간 릴레이가 올바른가?
93 passed 0 failed 3 files 1.3s
timeline.test.ts
53 / 53 19ms
cleanDetailText 12 / 12
returns empty/falsy input unchanged
2.367432000000008ms
strips markdown bold
0.45984599999997045ms
strips markdown headings
0.34432099999997945ms
strips code fences
0.2024069999999938ms
strips inline backticks
0.20121399999999312ms
strips markdown links
0.1574590000000171ms
strips blockquotes
0.16010199999999486ms
strips list markers
0.15988200000003872ms
collapses multiple blank lines
0.14706300000000283ms
filters system JSON blobs (connectionId)
0.18029300000000603ms
extracts error from JSON blob
0.2024860000000217ms
compacts other JSON
0.17784900000003745ms
cleanRawText 2 / 2
strips bold, headings, links, backticks
0.2603639999999814ms
returns empty/falsy unchanged
0.2192309999999793ms
cleanNopMarkers 3 / 3
removes NOP markers
0.4269259999999804ms
collapses resulting blank lines
0.20470000000000255ms
returns empty/falsy unchanged
0.19983300000001236ms
extractSemanticCore 4 / 4
strips duration suffix for chat_end
0.23975200000000996ms
keeps full text for chat_end without separator
0.17966100000001006ms
keeps full text for non-chat_end types
0.16166499999997086ms
trims whitespace
0.16035299999998642ms
isRepetitiveEntry 11 / 11
detects exact duplicate chat_end entries
0.6146699999999896ms
detects keyword-similar entries
0.6537389999999732ms
returns -1 for non-matching entries
0.2574700000000121ms
ignores entries outside window
0.19575600000001714ms
only applies to chat_end, chat_start, and error types
0.15269100000000435ms
dedupes repeated error entries within 1h window
0.24205599999999095ms
matches chat_start entries
0.16390799999999217ms
dedupes automated entries regardless of content
0.14121399999999085ms
does not dedup automated vs non-automated
0.1556250000000432ms
uses 8h window for automated entries
0.13310200000000805ms
expires automated dedup after 8h
0.12977599999999256ms
parseLogLine 21 / 21
returns null for null/undefined/non-object
0.5823310000000106ms
returns null for empty message
0.14892500000001974ms
returns null for model start/complete (suppressed)
0.1870630000000233ms
parses memory/recall (legacy structured)
0.39572899999996025ms
parses tool execution (legacy structured)
0.24218700000000126ms
filters gateway/ws subsystem
0.13898000000000366ms
filters infrastructure noise
0.6004489999999691ms
filters channel infra reconnect noise
0.668371000000036ms
filters connection status JSON blobs
0.6119560000000206ms
filters transient fetch timeouts
0.36848800000001347ms
filters edit mismatch errors (agent retries)
0.638116000000025ms
filters failover cascade noise
0.20539100000002009ms
parses genuine errors
0.8639370000000213ms
parses error from message pattern (not level)
0.6593579999999974ms
filters model/inference patterns (suppressed)
0.5402179999999817ms
does not synthesize memory_recall from message text alone
0.3916129999999498ms
does not synthesize tool_exec from message text alone
0.19208000000003267ms
parses ISO timestamp correctly via error pattern
0.2837799999999788ms
falls back to Date.now() for invalid timestamp on error message
0.4052330000000097ms
truncates long tool raw to 500 chars
0.32571300000000747ms
filters whatsapp noise from channel infra subsystem
0.34375ms
timeline-integration.test.ts
35 / 35 32ms
BridgeTimelineStore 11 / 11
adds and retrieves entries
6.10071099999999ms
filters history by timestamp
0.5834929999999758ms
calls listeners on new entries
0.4935970000000225ms
upsert updates existing entry with same ts+type
0.9105279999999993ms
upsert keeps timeline attribution fields
0.53667200000001ms
upsert adds new entry when no match exists
0.3584219999999618ms
updateEntryStatus updates approval status
0.36131699999998546ms
getLastEntry returns most recent of given type
0.427737000000036ms
getLastEntry returns null when type not found
0.21783899999996947ms
removeListener stops notifications
0.3984829999999988ms
enforces MAX_ENTRIES (200) with FIFO
7.320867000000021ms
deduplicateEntry pipeline 5 / 5
exact duplicate within 8s → skip
0.3595540000000028ms
same type, different content → add
0.23729900000000725ms
different type, same raw → add
0.23928200000000288ms
chat_response identical raw 6s apart → skip (PTY/Stop race)
0.7363739999999552ms
chat_response near-duplicate beyond 8s → repetitive merge
0.516570999999999ms
BridgeTimelineStore.setAttributor — history replay attribution 10 / 10
addEntry passes the entry through the attributor before storage
0.43126299999994444ms
caller-set fields take precedence over attributor (idempotent)
0.314865999999995ms
listener (broadcast) receives the same attributed entry
0.37948400000004767ms
upsertEntry propagates summaryKind to existing entry (LLM enrichment regression)
0.3742859999999837ms
upsertEntry routes through the attributor too
0.4446829999999977ms
late upsert preserves the original entry attribution after task rotation (regression)
0.4172020000000316ms
merge path (repetitive dedup) does not re-attribute after task rotation
0.36039500000003954ms
upsert with no existing match falls through to attributor (insert path)
0.27751999999998134ms
caller-set taskId on upsert overrides existing entry attribution
0.33041000000002896ms
history replay returns entries with taskId/runId set (regression)
1.2374520000000189ms
Stop hook + PTY fallback double-emit (regression) 1 / 1
identical chat_response from two emit paths is collapsed by store
0.672126999999989ms
Timeline → WS broadcast pipeline 4 / 4
store entries trigger broadcast via listener
0.48253999999997177ms
upsert entries broadcast with upsert flag
0.45947499999999764ms
exact duplicate within 5s is skipped by store
1.1279670000000124ms
different content within 5s is NOT deduped
0.3858439999999632ms
TimelineEntry types 4 / 4
common entry types have expected shape
2.7888399999999933ms
entries with status field
0.3592429999999922ms
entries with detail field
0.3274759999999901ms
entries with automated flag
0.2124520000000416ms
session-timeline-relay.test.ts
5 / 5 1.2s
SessionTimelineRelay 5 / 5
connects to sibling and relays timeline_event
313.22667999999993ms
relays timeline_history entries
303.04234699999995ms
removes subscription when session disappears
201.825557ms
ignores daemon sessions
0.39529799999991155ms
handles upsert timeline events
401.77063ms
Daemon & Infrastructure PASS
데몬 싱글톤, 세션 레지스트리, 사용량 릴레이가 안정적인가?
60 passed 0 failed 4 files 1.3s
daemon-lifecycle.test.ts
19 / 19 51ms
daemon.json lifecycle 6 / 6
writeDaemonInfo creates daemon.json with correct content
7.063273000000038ms
readDaemonInfo returns info when PID is alive
1.3819799999999987ms
readDaemonInfo returns null and removes file when PID is dead
0.8449979999999755ms
readDaemonInfo returns null when file does not exist
0.3806460000000129ms
removeDaemonInfo deletes daemon.json
0.6403080000000045ms
removeDaemonInfo is safe when file already gone
1.1890380000000391ms
session registry with real files 7 / 7
register creates sessions.json
1.6991909999999848ms
register replaces existing entry with same id
1.113424000000009ms
deregister removes session by id
1.3613690000000247ms
listActive prunes dead PIDs
1.1684680000000185ms
multiple sessions coexist
1.0551360000000045ms
findExistingDaemon returns daemon session
0.9688060000000291ms
findExistingDaemon returns null when no daemon
0.5934480000000235ms
findDaemonPort 4 / 4
returns port from daemon.json (priority 1)
0.6400279999999725ms
falls back to sessions.json daemon entry
0.6628929999999968ms
returns null when no daemon anywhere
0.39197300000000723ms
daemon.json takes precedence over sessions.json
0.8054989999999975ms
probeDaemonHealth 2 / 2
returns health JSON from running server
25.39384000000001ms
returns null for closed port
3.3766480000000456ms
session-registry.test.ts
10 / 10 12ms
Session Registry Logic 10 / 10
pruneDeadSessions › keeps alive sessions
4.851548000000008ms
pruneDeadSessions › removes sessions with dead PIDs
0.606648000000007ms
pruneDeadSessions › keeps old sessions if PID is alive
0.33516700000001265ms
pruneDeadSessions › handles mix of alive and dead sessions
1.325273999999979ms
port allocation logic › returns base port when no ports are used
0.383560000000017ms
port allocation logic › returns next port when base is taken
0.222487000000001ms
port allocation logic › skips used ports
0.17105799999998794ms
port allocation logic › finds gaps in used ports
0.16414799999998309ms
port allocation logic › throws when all ports are taken
1.1225279999999884ms
atomic write › write-then-rename produces valid JSON
3.2537710000000004ms
usage-relay.test.ts
12 / 12 626ms
Usage relay — HTTP (Tier 1) 3 / 3
fetches usage from sibling GET /usage
69.51277399999998ms
returns null usage when sibling has no data
9.187617000000046ms
rejects stale data (>5 min old)
3.553244999999947ms
Usage relay — WebSocket (Tier 2) 2 / 2
receives usage_update from sibling WS on connect
263.162414ms
does not send usage_update when sibling has no data
252.07730800000002ms
HookServer GET /usage (relay source) 2 / 2
returns cached usage via onApiUsage getter
12.227054999999837ms
returns fresh usage after update
6.273850000000039ms
429 prevention — relay-first strategy 2 / 2
sibling with data prevents direct API call
3.436868000000004ms
multiple siblings — first with data wins
5.2885989999999765ms
ApiUsageData shape 3 / 3
has all required fields
0.40165799999999763ms
serializes to valid JSON and back
0.323118999999906ms
handles null optional fields
0.2912700000001678ms
bridge-core.test.ts
19 / 19 579ms
BridgeCore Orchestration 19 / 19
buildStateEvent › builds state_update with IDLE state
20.165685999999994ms
buildStateEvent › includes cached ollamaStatus and gatewayAvailable
5.929070999999965ms
buildStateEvent › computes promptType for permission options
5.357866999999999ms
buildStateEvent › computes promptType yes_no_always for 3+ permission options
5.887693000000013ms
usage management › updateApiUsage caches and broadcasts
27.798009000000093ms
usage management › buildUsage includes API usage data
4.648183000000017ms
usage management › buildUsage works without API data
4.50023299999998ms
usage management › inferredBillingType propagates to StateMachine
4.401659999999993ms
sendInitialState › sends state_update, usage_update, connection, display_state on connect
18.079372000000035ms
sendInitialState › includes timeline_history when entries exist
15.329221999999959ms
state change broadcast › state_changed emits to WS clients when wired by caller
7.131276999999955ms
wireTimeline › timeline entries broadcast as timeline_event
58.85692100000006ms
hasClients guard › wsServer.getClientCount reflects connected clients
258.10970800000007ms
hasClients guard › external client count provider extends hasClients
5.237863000000061ms
voice assistant state › updateVoiceAssistantState caches and triggers state broadcast
57.78398800000002ms
voice assistant state › disabled voice assistant state is not included in event
4.868955000000028ms
session registry › registerSession writes to sessions.json
7.202309000000014ms
session registry › deregisterSession removes from sessions.json
5.934410999999955ms
broadcast coordination › broadcast sends to WS and SSE callback
60.74603300000001ms
Integration Tests PASS
전체 파이프라인이 실제 서버 환경에서 동작하는가?
29 passed 0 failed 2 files 933ms
server-integration.test.ts
15 / 15 633ms
Server Integration 15 / 15
SessionStart hook → IDLE state broadcast
104.65940599999999ms
full session lifecycle: SessionStart → UserPromptSubmit → Stop
16.312022999999954ms
PreToolUse → PostToolUse cycle broadcasts tool info
14.092265999999995ms
SessionEnd → DISCONNECTED
9.293706999999927ms
GET /health returns valid JSON
9.670536999999968ms
GET /usage returns data when getter is set
12.073342000000025ms
GET /usage returns null when no getter
4.945259999999962ms
GET /devices returns empty when no getter
5.029247000000055ms
POST to unknown route returns 404
6.561604999999986ms
hook endpoint responds immediately
7.319210999999996ms
SSE client receives state_update events
66.98596199999997ms
broadcasts to multiple WS clients
10.383235000000013ms
WS command from client triggers callback
106.86242800000002ms
rapid hook events do not corrupt state
243.88474499999995ms
token counts accumulate through hook events
14.258616999999958ms
tier3-integration.test.ts
14 / 14 299ms
mDNS crash recovery 3 / 3
invalidateMdnsInstance does not throw when no instance exists
4.529061000000013ms
EADDRNOTAVAIL pattern matches expected error messages
0.5851660000000152ms
non-mDNS errors are NOT matched by recovery pattern
0.3509610000000407ms
Display sleep/wake broadcast 5 / 5
DisplayMonitor initial state is ON
0.40794699999997874ms
display_state event has correct shape
0.30775600000004033ms
display_state broadcasts to WS clients
83.37530199999998ms
display_state broadcasts to multiple clients
57.21389099999999ms
SSE also receives display_state
111.49924600000008ms
Voice transcription endpoint 4 / 4
returns 503 when no voice manager is set
20.11115899999993ms
returns 400 for empty audio data
6.146337000000017ms
returns transcription from voice manager
5.592169000000013ms
returns 500 when voice manager throws
4.829205000000002ms
WsServer broadcast hooks (serial relay) 2 / 2
onBroadcast hook receives all broadcast events
1.760091999999986ms
broadcast hook errors do not crash server
1.3505030000000033ms
Stream Deck Plugin UI PASS
플러그인의 연결 관리, 옵션 레이아웃, 렌더링이 정확한가?
113 passed 0 failed 5 files 1.8s
connection-manager.test.ts
16 / 16 15ms
ConnectionManager 16 / 16
starts disconnected
3.6162990000000264ms
start() begins bridge connection to daemon
1.624067000000025ms
start() installs a port provider so daemon.json is re-read every attempt
0.3735149999999976ms
emits connected when bridge connects
1.3895319999999742ms
emits disconnected when bridge disconnects
0.46933000000001357ms
forwards state_update from bridge
1.0195619999999508ms
send() delegates to bridge
1.8311300000000301ms
send() drops command when not connected
0.38313999999996895ms
getBridgePort returns bridge port
0.3053019999999833ms
getConnectionSnapshot exposes connection and discovery state
0.36418099999997366ms
retryNow probes daemon discovery and reconnects immediately when disconnected
0.5101920000000177ms
switchToOpenClaw() › sends switch_agent command to bridge
0.6672990000000141ms
switchToClaude() › sends switch_agent command to bridge
1.4824220000000423ms
isGatewayAvailable() › returns false by default
0.33132100000000264ms
isGatewayAvailable() › returns true when bridge reports gateway available
0.22181499999999232ms
isGatewayAvailable() › returns false when bridge reports gateway unavailable
0.21838999999999942ms
connection-integration.test.ts
6 / 6 1.7s
ConnectionManager Integration — Real WebSocket 6 / 6
client connects and receives broadcast events
228.86923300000007ms
multiple clients receive same broadcast
208.54459499999996ms
client sends command to server
154.368516ms
handles rapid connect/disconnect without crashes
415.10934599999996ms
server detects client disconnect
253.65591500000005ms
bridge → gateway priority: second server takes over on disconnect
407.6168440000001ms
option-scenario.test.ts
9 / 9 6ms
option-renderer panels 3 / 3
E2 Focus panel renders with adaptive font
2.646974ms
E3 List panel renders 4 visible rows with 14px font
0.6774650000000122ms
E4 Detail panel shows word-wrapped label (12px, left-aligned)
0.538423999999992ms
colorForOption — "don't ask again" / "allow all sessions" 6 / 6
returns blue for "Yes, and don't ask again for: tail:*"
0.43861400000000117ms
returns blue for "Yes, and don’t ask again" (smart quote)
0.22278699999998253ms
returns blue for "Yes, allow all sessions in project"
0.22186600000000567ms
returns green for plain "Yes" (shortcut y)
0.20630199999999377ms
returns green for "Apply" (shortcut a, but no "don't ask" pattern)
0.19364300000000867ms
returns blue for "Always allow"
0.12945499999997878ms
renderer-snapshots.test.ts
63 / 63 63ms
voice-renderer snapshots 12 / 12
renderVoiceReady
8.557932999999991ms
renderVoiceRecording frame 0
0.8407720000000154ms
renderVoiceRecording frame 30 (>1min)
0.33955399999996416ms
renderVoiceTranscribing frame 0
0.45912500000002865ms
renderVoiceTranscribing frame 10 (different dot phase)
0.3554879999999798ms
renderVoiceError with message
0.47055199999999786ms
renderVoiceError default
0.2977199999999698ms
renderVoiceDisabled
0.3531550000000152ms
renderVoiceAssistantListening frame 0
0.42123800000001665ms
renderVoiceAssistantProcessing frame 5
0.4300010000000043ms
renderVoiceAssistantSpeaking frame 0
0.4904319999999984ms
renderWideVoiceText returns correct panel count
2.649458999999979ms
utility-renderer snapshots 4 / 4
renderSetupUtility
2.468999999999994ms
renderUtilityGeneric with icon
0.6043439999999691ms
renderUtilityGeneric text-only (no icon)
0.4173509999999965ms
renderUtilityMedia
0.6036229999999705ms
usage-dial-renderer snapshots 7 / 7
renderUsageOverview
0.7910860000000071ms
renderUsageDetail 5h
0.34197699999998576ms
renderUsageDetail 7d
0.23035799999996698ms
renderUsageSession
0.537633000000028ms
renderUsageExtra enabled
0.4583030000000008ms
renderUsageExtra disabled
0.3583730000000287ms
renderUsageDisconnected
0.3445410000000493ms
response-renderer snapshots 7 / 7
renderResponseIdle
0.37338499999998476ms
renderResponseProcessing
0.3201139999999896ms
renderResponseDisconnected
0.25680899999997564ms
renderResponseDisabled
0.2567579999999907ms
renderResponseSuggestion
0.6147700000000214ms
renderResponseInteractive
0.35348399999998037ms
renderSetupPrompt
0.26873699999998735ms
option-renderer snapshots 7 / 7
renderContextPanel permission
0.8389389999999821ms
renderContextPanel diff
0.44530400000002146ms
renderFocusPanel with recommended option
0.7452269999999999ms
renderListPanel 3 options
0.9993220000000065ms
renderListPanel 6 options (scroll indicator)
0.3860840000000394ms
renderDetailPanel
0.7596990000000119ms
renderWideOptionList returns correct panel count
0.7583769999999959ms
button-renderer snapshots 7 / 7
basic text button
0.739768999999967ms
button with subtitle
0.3469949999999926ms
disabled button
0.25951300000002675ms
loading button
0.260503999999969ms
long text that needs abbreviation
0.38213799999999765ms
svgToDataUrl returns data URI
0.5722959999999944ms
labelNeedsHaiku detects long labels
1.3835339999999974ms
session-slot-renderer snapshots 8 / 8
disconnected hero is icon-rich
1.0361169999999902ms
disconnected non-center slot is empty
0.3417670000000044ms
disconnected cluster quadrant tl
0.38653499999998076ms
disconnected cluster quadrant tr
0.3668349999999805ms
disconnected cluster quadrant bl
0.2667329999999879ms
disconnected cluster quadrant br
0.316709000000003ms
connected no-session card is icon-rich
0.45436699999999064ms
active idle session uses orbiting focus border
1.4310449999999832ms
timeline-renderer snapshots 5 / 5
empty timeline
0.529139999999984ms
single entry
1.009617999999989ms
multiple entries fisheye
0.43441799999999375ms
detail mode
0.5129060000000436ms
with session status
0.3108609999999885ms
qr-renderer snapshots 3 / 3
extractUrlLabel extracts host:port
0.44550399999997126ms
qrPathData deterministic
10.025989999999979ms
renderQrButtonSvg
8.882890000000032ms
agent-logos snapshots 3 / 3
claude-code watermark
0.4878479999999854ms
openclaw watermark
0.42225899999999683ms
CLAUDE_LOGO_PATH is defined
0.4815680000000384ms
text-utils-and-labels.test.ts
19 / 19 11ms
text-utils: CJK width measurement 4 / 4
Latin text is ~0.55em per char
2.54761400000001ms
Korean text is 1em per char (double-width)
0.5202569999999866ms
mixed text measures correctly
0.17330200000000673ms
isWide detects Hangul, CJK, fullwidth
0.2781009999999924ms
text-utils: wrapTextByWidth 3 / 3
short text returns single line
0.9524099999999862ms
long Latin text wraps to multiple lines
0.3997349999999926ms
Korean text wraps at correct pixel width
0.2832679999999925ms
button-renderer: abbreviation 10 / 10
short label renders without abbreviation indicator
1.1609960000000115ms
"Yes, I trust this folder" fits with wrapping (no abbreviation needed)
0.30392899999998235ms
"Yes, allow and don't ask again" wraps into 3 lines
0.22427899999999568ms
very long label triggers abbreviation with ~ indicator
0.8425640000000101ms
short permission labels like "No" render unchanged
0.22193599999999947ms
labelNeedsHaiku returns false for short labels
0.25087000000002035ms
labelNeedsHaiku returns false when heuristic abbreviation fits
0.16104400000000396ms
labelNeedsHaiku returns true for very long unknown labels
0.400164999999987ms
labelNeedsHaiku returns false when Haiku cache has result
0.8389490000000137ms
BUTTON_MAX_CHARS is reasonable
0.2605839999999944ms
button-renderer: CJK labels 2 / 2
Korean label does not overflow (produces valid SVG)
0.23438500000000317ms
mixed CJK/Latin label renders
0.14825400000000855ms
TUI Dashboard PASS
터미널 대시보드의 상태 렌더링과 테라리움 애니메이션이 올바른가?
49 passed 0 failed 3 files 64ms
tui-dashboard.test.ts
8 / 8 19ms
TUI dashboard models 8 / 8
stores modelCatalog from state_update
2.909860999999978ms
renders OAuth catalog and Ollama models in wide layout
2.6943449999999984ms
renders disconnected OAuth state
0.8539210000000139ms
shows current session summary and control hints
0.40488200000004326ms
renders agent list secondary line as model dash compact state
0.29093999999997777ms
renders sibling models in session bridge mode and omits uptime label
0.5130260000000249ms
renders help overlay when helpVisible is on
0.45775199999997085ms
shows numbered session badges
11.428616999999974ms
tui-renderer-snapshots.test.ts
29 / 29 23ms
blockGauge snapshots 7 / 7
0% — all empty, green
8.083597999999995ms
50% — half filled, green
0.5547090000000026ms
75% — yellow threshold
0.38626400000001127ms
95% — red threshold
0.34247799999999984ms
100% — all filled, red
0.35042000000001394ms
clamps negative to 0
0.33482699999999ms
clamps above 100
0.3041199999999833ms
resetTimeStr 5 / 5
returns empty for undefined
0.6752510000000029ms
returns ↻now for past time
0.5741590000000087ms
formats minutes
0.7043060000000025ms
formats hours and minutes
0.35314400000001456ms
formats days and hours
0.33449600000000146ms
formatUptime 3 / 3
seconds
0.3907910000000072ms
minutes
0.302977999999996ms
hours and minutes
0.32457100000002015ms
formatTokens 3 / 3
below 1000 unchanged
0.41610000000000014ms
1k-10k with decimal
0.3464039999999784ms
10k+ rounded
0.40169700000001285ms
activityDensityBar 3 / 3
empty timestamps — all dim
0.5710729999999842ms
recent burst — bright right side
0.4931959999999833ms
spread timestamps — distributed density
0.44953000000001ms
getLayout 3 / 3
wide for 120+ cols
0.45856399999999553ms
standard for 80-119 cols
0.42558400000001484ms
narrow for <80 cols
0.34816699999998946ms
shouldShowTerrarium 3 / 3
true for adequate size
0.42096599999999285ms
false for too narrow
0.28066499999999905ms
false for too short
0.26499099999998066ms
spinner 2 / 2
returns braille characters at different frames
2.76128700000001ms
spinner cycles through 10 frames
0.3483070000000055ms
tui-terrarium-snapshots.test.ts
12 / 12 21ms
TUI terrarium snapshots 12 / 12
initTerrarium creates context with expected structure
5.602174000000019ms
setOctopi configures octopus instances
0.9821959999999876ms
setCrayfish configures crayfish state
0.33810099999999466ms
setJellyfish configures jellyfish instances
0.5475379999999745ms
renderTerrariumFrame empty terrarium (small)
4.327955999999972ms
renderTerrariumFrame empty terrarium (large)
1.108947999999998ms
renderTerrariumFrame with idle octopus
1.586689999999976ms
renderTerrariumFrame with processing octopus
1.5453580000000215ms
renderTerrariumFrame with routing crayfish
3.552712999999983ms
renderTerrariumFrame with sick crayfish
1.133353999999997ms
renderTerrariumFrame too small returns empty
0.337509999999952ms
updateTerrarium advances bubble positions
0.4282880000000091ms
Serial Protocol PASS
ESP32와의 시리얼 바이트스트림이 정확히 프레이밍되는가?
22 passed 0 failed 1 files 12ms
esp32-serial-node.test.ts
22 / 22 12ms
SERIAL_FORWARDED_EVENTS 4 / 4
includes all display events
2.4278019999999856ms
includes timeline events (unique to serial)
0.22503000000000384ms
does NOT include plugin-only events
0.2651109999999903ms
required serial events are present
0.296418999999986ms
ESP32 port detection patterns 5 / 5
matches CH340 ports (86 Box)
0.3654229999999927ms
matches native USB JTAG ports (IPS 3.5", Round AMOLED)
0.3503690000000006ms
matches Linux serial ports
0.2791620000000137ms
excludes Bluetooth and WLAN
0.15293099999999527ms
excludes non-ESP32 ports
0.1652300000000082ms
handleSerialLine (source) 4 / 4
parses device_info message and updates deviceInfo
0.452463999999992ms
skips debug lines (non-JSON)
0.13617599999997765ms
recovers from malformed JSON
0.23251099999998814ms
ignores JSON without type field
0.2670839999999828ms
prepareForSerial (source) 5 / 5
strips agentCapabilities from state_update
0.45055200000001605ms
strips billingType and remoteUrl from state_update
0.23675799999998048ms
preserves essential state_update fields
1.6628460000000018ms
strips legacy usage fields from usage_update
0.8322490000000187ms
passes through other events unchanged
0.9215239999999767ms
WiFi provision protocol 1 / 1
provision message has all required fields
0.4532549999999844ms
serial buffer management 3 / 3
line splitting handles multiple lines in one chunk
0.533046000000013ms
handles partial message across chunks
0.5783140000000344ms
truncates buffer when exceeding 8KB limit
0.2510599999999954ms
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.893025999999992ms
darkens later sessions while preserving channel ordering
0.3709210000000098ms
clamps very large session indices to the darkest supported tone
0.20407900000000723ms
Hook Installation PASS
Claude Code hook의 설치, 제거, 마이그레이션이 안전한가?
21 passed 0 failed 1 files 17ms
install.test.ts
21 / 21 17ms
Hook Installer 21 / 21
buildHookEntry › creates matcher-group format with AGENTDECK_PORT env var
4.2804140000000075ms
buildHookEntry › includes daemon.json port resolution with fallback to 9120
0.3169589999999971ms
buildHookEntry › reads PORT from AGENTDECK_PORT env var first, then daemon.json, then 9120
0.32976899999999887ms
buildHookEntry › emits newline-separated shell so if/then/for/do keywords are not mis-terminated by `;`
0.4344070000000215ms
applyHooks › installs hooks to empty settings in matcher-group format
2.5882649999999785ms
applyHooks › preserves non-AgentDeck hooks
0.4570410000000038ms
applyHooks › replaces old flat-format hooks
0.3689889999999991ms
applyHooks › replaces old matcher-format hooks
0.376609999999971ms
applyHooks › is idempotent — running twice produces same result
0.9726009999999974ms
applyHooks › preserves existing non-hook settings
1.1271650000000477ms
removeHooks › removes all AgentDeck hooks (new format)
0.44844799999998486ms
removeHooks › removes old flat-format AgentDeck hooks
0.2059210000000462ms
removeHooks › preserves non-AgentDeck hooks
0.34949799999998277ms
removeHooks › handles empty settings gracefully
2.1386549999999716ms
migrateHooks › migrates old hardcoded port to env var
0.5351989999999773ms
migrateHooks › migrates flat format to matcher-group format
0.26749399999999923ms
migrateHooks › skips already-migrated hooks (new format)
0.22754400000002306ms
migrateHooks › skips non-AgentDeck hooks
0.20733400000000302ms
migrateHooks › migrates multiple events at once
0.5923159999999825ms
migrateHooks › migrates hardcoded port inside matcher-group
0.29896200000001727ms
migrateHooksIfNeeded (file-based) › upgrades old :-9120 fallback hooks to daemon.json-reading format
0.2801240000000007ms
Other Tests
Uncategorized test files
454 passed 0 failed 31 files
apme-category-e2e.test.ts
3 / 3 55ms
APME category-aware turn evaluation (E2E) 3 / 3
conversation turn: prompt → classify → judge → turn category + composite persisted
33.060452ms
research turn: rule-based classifier picks research, judge uses research rubric axes
10.158194999999978ms
daemon backfill pass: turns with response but no outcome get committed + null composite
11.851259999999968ms
apme-classifier.test.ts
18 / 18 65ms
classify() 12 / 12
planning — plan mode used
2.9615799999999695ms
planning — short session, no file changes
0.33244300000001203ms
research — web searches dominant
0.2019849999999792ms
research — grep/glob dominant, no file changes
0.24035400000002483ms
coding — edit+write dominant with file changes
0.2143249999999739ms
debugging — tests + edits + bash
0.17731800000001385ms
refactoring — many edits, no new files
0.15160900000000765ms
review — mostly reads, minimal edits
0.2541439999999966ms
ops — bash dominant, few edits
0.16284600000000182ms
conversation — very short, no tools
0.14309599999995726ms
multi_agent — multiple Agent delegations
0.15251099999994722ms
unknown — no clear pattern
0.19891999999998689ms
computeSignals() 3 / 3
counts tool calls and identifies dominant tool
23.774770999999987ms
detects plan mode from step payload
6.04664600000001ms
detects web searches
8.087232000000029ms
classifyRun() 2 / 2
returns signals and category for a coding run
7.004410000000007ms
returns unknown for empty runs
7.054440999999997ms
task_category schema migration 1 / 1
runs table has task_signals, task_category, task_category_source columns
7.068040999999994ms
apme-collector.test.ts
10 / 10 144ms
ApmeCollector 10 / 10
openRun → ingestHook → closeRun persists a run with steps
46.560997000000015ms
updateUsage and updateModel reflect in the run row
7.006046999999967ms
listRuns filters by agent and orders by started_at desc
17.47900800000002ms
default rubric v1 is seeded on init
6.567769999999996ms
insertEval + listEvalsForRun round-trip
6.860161000000005ms
scorecard view aggregates runs per model
8.202893000000017ms
multi-turn cycle captures prompts and responses (wireAgentApme path)
26.072427000000005ms
setLastClosedTurnResponse fills missing response on closed turn
6.707601000000011ms
setTurnResponse tags efficiency_json.response_kind (text / tool_only / empty)
9.371745999999973ms
no-op gracefully when store is disabled
8.828454000000022ms
apme-http.test.ts
13 / 13 277ms
APME HTTP routes 13 / 13
returns 503 when APME is not initialized
76.514734ms
GET /apme/runs lists recent runs with evals and overall score
29.426008999999965ms
GET /apme/runs filters by agent
9.702625000000012ms
GET /apme/run/:id returns run detail with steps and evals
15.30152499999997ms
GET /apme/run/:id returns 404 for unknown runs
8.766300000000001ms
GET /apme/run/:id includes per-task rollup with attached evals
32.133564999999976ms
GET /apme/tasks/:id returns task detail with evals + turns
35.76753100000002ms
closeTaskExternal with manual signal records outcome + boundary_signal=manual
13.50759099999999ms
GET /apme/scorecard returns model aggregates
11.771986000000027ms
GET /apme/rubric/current returns seeded rubric v1
8.615436999999986ms
POST /apme/vibe records feedback and rejects unknown runs
18.452721000000054ms
POST /apme/recommend returns candidate list
10.115971000000002ms
unknown /apme/* path returns 404
7.37212100000005ms
apme-judge-probe.test.ts
20 / 20 91ms
probeJudgeBackend — MLX 4 / 4
returns unavailable when /v1/models is unreachable
6.195874000000003ms
returns unavailable when /v1/models advertises no chat-capable model
33.782812999999976ms
returns unavailable when chat ping fails (model not loaded)
1.1239310000000273ms
returns ready when catalog AND chat ping both succeed
0.939452000000017ms
probeJudgeBackend — OpenClaw 4 / 4
returns unavailable when /health is unreachable
0.7314969999999903ms
returns unavailable when /health is up but /models is not (gateway not initialised)
0.7080209999999738ms
returns unavailable when configured model is not in /models catalog
1.1723440000000096ms
returns ready when /health + /models both up and model matches
1.0596330000000194ms
probeJudgeBackend — Anthropic API (stub backend) 2 / 2
returns unavailable when ANTHROPIC_API_KEY is not set
1.4145900000000324ms
returns unavailable even when ANTHROPIC_API_KEY is set (callApi is a stub)
0.8732909999999947ms
callJudgeWithMeta — effective backend labelling across fallback 3 / 3
FM happy path labels eval as foundationModels
1.3409490000000233ms
FM→MLX fallback (fallbackToMlx=true) labels eval as mlx, not foundationModels
5.570938999999953ms
FM failure without fallbackToMlx propagates the error (no silent label drift)
2.897474000000045ms
sanitizeForMlx — runtime fallback hygiene 4 / 4
strips FM endpoint and model when forcing to MLX
1.0915410000000065ms
strips OpenClaw endpoint and model when forcing to MLX
0.8458099999999718ms
returns the same cfg shape when already-clean MLX is passed
0.6483610000000226ms
clears a custom MLX endpoint when source backend is MLX but model is overridden
0.5158300000000509ms
probeJudgeBackend — Foundation Models 3 / 3
returns unavailable when Swift daemon FM endpoint cannot be resolved
27.61703ms
returns unavailable when FM endpoint responds with error body
1.0890380000000164ms
returns ready when FM endpoint responds with text
0.753990999999985ms
apme-runner.test.ts
31 / 31 405ms
detectLanguage 4 / 4
recognizes TypeScript from package.json
5.674245000000042ms
recognizes Swift from .xcodeproj
0.9542840000000297ms
recognizes Kotlin from build.gradle.kts
0.4961799999999812ms
returns null for unknown paths
0.25859200000002147ms
parseJudgeJson 5 / 5
extracts scores and reasoning from a clean JSON blob
1.1054530000000113ms
rescales 0-10 axis to 0-1
0.316188000000011ms
tolerates prose wrapping and code fences
0.2730829999999287ms
returns null when there is no JSON at all
0.19817999999997937ms
returns null when overall is missing
0.2147340000000213ms
effectiveJudgeModelTag 4 / 4
uses cfg.model for MLX when no pin is set
1.357605000000035ms
uses llm.mlx pin over cfg.model for MLX backend
0.8214029999999184ms
ignores llm.mlx pin for non-MLX backends
0.7075199999999313ms
foundationModels uses the Swift-parity judgeModelLabel
0.44854899999995723ms
callJudge foundationModels routing 3 / 3
returns FM text on ok response
33.65790400000003ms
throws when FM reports unavailable (default = no fallback)
3.4880769999999757ms
falls back to MLX only when fallbackToMlx is explicitly true
44.78706299999999ms
shouldJudge gating 4 / 4
never runs when sampleRate is 0
0.2820570000000089ms
skips clear passes when onlyWhenDisagreement is true
0.13674700000001394ms
runs on failures when onlyWhenDisagreement is true
0.1144929999999249ms
runs for clear passes when onlyWhenDisagreement is false
0.18223600000010265ms
ApmeRunner.runOne 4 / 4
records deterministic failures and invokes judge with rubric prompt
70.22137499999997ms
skips layer 2 on a clean pass when onlyWhenDisagreement is true
15.98909100000003ms
enqueueTurn skips judge for tool_only and empty turns
23.69768499999998ms
swallows judge errors without inserting partial rows
14.119892999999934ms
runDeterministic (end-to-end spawn) 3 / 3
runs sh-based commands against the project path and reports pass
53.04461700000002ms
captures exit code 1 as tests_pass=0
49.511470999999915ms
skips entirely when the worktree has no changes
41.801692ms
onTaskEvaluated 3 / 3
fires after enqueueTask resolves and carries the composite score + outcome
16.785416999999825ms
derives outcome=fail for low composite scores
11.500525000000152ms
preserves a manually-set outcome — judge does not overwrite `abandoned`
11.681053999999904ms
buildJudgePrompt 1 / 1
includes rubric prompt + task + context fields
0.3542660000000524ms
apme-settings.test.ts
16 / 16 18ms
loadApmeConfig — defaults + merge behaviour 12 / 12
returns full defaults when settings.json does not exist
5.478246000000013ms
returns full defaults when settings.json has no apme section
1.595532999999989ms
returns defaults on malformed JSON (must not throw)
0.7681619999999612ms
merges user-set fields on top of defaults
1.0962680000000091ms
clamps sampleRate to [0, 1]
0.8990000000000009ms
falls back to mlx when judge.backend is unknown string
1.7445389999999747ms
downgrades judge.backend="api" to "mlx" on the Node bridge (callApi is a stub)
0.6851770000000101ms
also wipes endpoint/model when downgrading backend="api" → "mlx"
0.853020000000015ms
also wipes endpoint/model when falling back from unknown backend → "mlx"
0.7397290000000112ms
preserves user-set endpoint/model when keeping their chosen backend
0.7516470000000481ms
respects explicit enabled=false (opt-out)
0.650763999999981ms
clamps deterministic.timeoutSec to [5, 1800]
0.9074519999999779ms
loadApmeConfig — DEFAULT_APME_CONFIG sanity 4 / 4
default backend is local MLX (cost-sensitive policy)
0.20167500000002292ms
default sampleRate is 1.0 (judge every closed run; cost is local)
0.22957700000000614ms
default enabled is true (zero-config activation)
0.1785499999999729ms
default autoTune is true (rubric self-improves over time)
0.15466399999996838ms
apme-task-boundary.test.ts
12 / 12 195ms
ApmeCollector task boundaries 10 / 10
first UserPromptSubmit opens a task and attaches the turn
24.45437800000002ms
TodoWrite with every todo completed closes the active task
13.127177000000017ms
TodoWrite with partial completion does NOT close the task
13.33151399999997ms
next UserPromptSubmit after boundary opens a new task
13.01612799999998ms
splitRun closes the active task with boundary=clear
18.028008999999997ms
closeRun closes the active task with boundary=session_end
15.496359999999981ms
onTaskClosed fires with the task metadata
9.400228000000027ms
onTaskOpened fires with sessionId + agentType + projectName + taskIndex
9.075496999999984ms
onTaskClosed payload includes session, agent, project, and timing
8.863486000000023ms
empty task (no turns between two boundaries) is dropped
14.132375999999965ms
ApmeRunner task eval 2 / 2
enqueueTask invokes judge with turns and persists summary + scores
29.338778000000048ms
skips task eval when all turns are tool_only / empty
26.37967699999996ms
apme-telemetry-envelope.test.ts
39 / 39 355ms
claudeHookToSpans 6 / 6
emits turn_start with prompt for UserPromptSubmit
5.4818539999999985ms
detects /clear and emits a task_boundary span (not turn_start)
0.7097839999999564ms
emits tool_call for PreToolUse with gen_ai.tool.name
2.46583099999998ms
emits tool_result for PostToolUse
0.34436099999999215ms
falls through to raw_step for unknown events (Stop, SessionEnd, …)
0.4442219999999679ms
handles legacy { prompt: ... } shape on UserPromptSubmit
0.3513020000000324ms
claudePtyParserEventToSpans 4 / 4
maps tool_start to a tool_call span
0.704625999999962ms
maps tool_end to a tool_result span
0.30161700000002156ms
emits a raw_step for spinner_start/idle/spinner_stop
0.3592240000000402ms
drops unknown parser events
0.33126100000004044ms
claudePtyResponseToSpan 3 / 3
returns a turn_response span for non-trivial text
0.5491099999999847ms
marks fallback_to_last_closed when requested
0.2580209999999852ms
returns null for empty / single-character text (filters silence)
0.28420099999999593ms
timelineEntryToSpans 12 / 12
translates chat_start to turn_start with detail as prompt
0.4943080000000464ms
translates chat_response to turn_response
0.4263250000000198ms
translates chat_end with response detail to turn_response with fallback flag
0.30133599999999205ms
drops chat_response / chat_end with empty body
0.4589149999999904ms
translates tool_request with first-token tool name
0.5719459999999685ms
codex_user_prompt_submit → turn_start span
6.366623000000004ms
codex_user_prompt_submit with /clear → task_boundary span
0.5339779999999905ms
codex_tool_start → tool_call span with tool name
0.5522750000000087ms
codex_tool_end → tool_result span
0.4944189999999935ms
codex_stop / codex_session_start / codex_turn_complete → raw_step
0.9970889999999599ms
translates tool_exec the same as tool_request (legacy + Codex paths)
0.40192799999999806ms
translates tool_resolved to a tool_result span
0.2401739999999677ms
ApmeCollector.ingestSpan dispatch 13 / 13
turn_start span opens a turn and records the prompt
43.148213999999996ms
turn_response span persists the response on the active turn
22.99530199999998ms
tool_call span increments tool_calls on the active turn
28.75840199999999ms
chat_end fallback does not clobber a prior closed turn response
28.54899499999999ms
Codex timeline path opens turn and counts tools (timelineEntryToSpans)
19.340802999999994ms
task_boundary span with signal=clear splits the run
26.33990799999998ms
task_boundary span with signal=manual closes the active task
22.93381899999997ms
task_boundary span with signal=idle_gap closes the active task
24.375504999999976ms
task_boundary span with signal=todo_complete closes the active task
22.818184000000088ms
task_boundary span with an unknown signal is dropped (no task close, no throw)
24.96879899999999ms
raw_step span inserts a steps row without lifecycle effects
23.982485999999994ms
session_meta span updates the model id on the run
19.261032ms
timeline adapter feeds the same dispatch path correctly
20.667731000000003ms
eval-schema constants 1 / 1
exports a stable schema version string
0.26614199999994526ms
apme-tuner.test.ts
18 / 18 189ms
correlation 4 / 4
returns 1 for perfectly aligned arrays
3.2097949999999855ms
returns -1 for anti-aligned arrays
0.312453000000005ms
returns null when variance is zero
0.26590199999998276ms
returns null when arrays are too short
0.22749399999997877ms
parseProposal 3 / 3
extracts prompt + weights from a clean JSON blob
0.941504000000009ms
rejects proposals with too-short prompts
0.30226700000002893ms
rejects proposals with no weights
0.22815499999995836ms
extractOverall 3 / 3
parses overall score from a JSON blob
0.3011650000000259ms
rescales 0-10 values
0.20374799999996185ms
returns null when overall is missing
0.2077340000000163ms
collectDisagreements 1 / 1
picks up tests-pass-judge-fail and user-reject-judge-approve cases
56.97825399999999ms
vibeCorrelation 2 / 2
returns high positive correlation when judge and user agree
0.38297899999997753ms
returns null when there are too few labeled samples
0.13900000000001ms
ApmeTuner.tune 5 / 5
accepts a proposal that improves vibe correlation
37.61512099999999ms
rejects a proposal that makes correlation worse
38.10920799999997ms
rejects when the judge returns unparseable text
33.69872700000002ms
refuses to run when there are fewer than 3 disagreement samples
10.415774999999996ms
refuses when autoTune is disabled
4.876046000000031ms
bridge-core-sessions.test.ts
2 / 2 84ms
BridgeCore sessions_list 2 / 2
broadcastSessionsList enriches sessions before broadcast
22.184145ms
sendInitialState sends enriched sessions_list to the connecting client
61.492413ms
claude-transcript-reader.test.ts
7 / 7 9ms
readLastTurn 7 / 7
extracts assistant text and user prompt from a text-only turn
4.864418000000001ms
flags tool-only turns (tool_use blocks, no text blocks)
0.818979000000013ms
concatenates text across multiple assistant records for one turn
0.6428319999999985ms
picks the LAST user prompt when multiple turns are in the file
0.583802999999989ms
returns null for missing file
0.4374620000000107ms
skips malformed lines and continues parsing
0.6917159999999853ms
accepts legacy string content on both roles
0.7075600000000009ms
codex-turn-manager.test.ts
9 / 9 115ms
CodexTurnManager (hook-primary path) 6 / 6
happy path: UPS → tool_start → tool_end → stop emits one chat
29.35842699999995ms
codex_stop does not reset subsequent turn_index numbering
22.254502000000002ms
codex_stop finalizes APME turn (endedAt set, tool_calls flushed)
8.85314100000005ms
next prompt opens a fresh chat_start
6.9994669999999815ms
hook freshness window suppresses PTY parser idle close
6.909089999999992ms
long-bash: hook tool_start + tool_end keep the same turn open
6.865194000000031ms
CodexTurnManager (PTY-only fallback when hooks absent) 3 / 3
spinner_start opens turn, prompt-source idle closes after deferral
13.54000000000002ms
timeout-source idle without prior tool_action does not latch
7.068921999999986ms
tool_action then timeout-idle latches; spinner_start closes prev + opens new
12.852055000000007ms
gateway-parity-fixtures.test.ts
33 / 33 8ms
Gateway parity fixtures 33 / 33
fixture set is non-empty
3.0839049999999872ms
'auth-pairing-required-error.json' carries a valid frame discriminator
0.9210429999999974ms
'chat-delta.json' carries a valid frame discriminator
0.2630580000000009ms
'chat-final-with-tools.json' carries a valid frame discriminator
0.2230170000000271ms
'connect-challenge.json' carries a valid frame discriminator
0.17943100000002232ms
'connect-hello-ok-device-token.json' carries a valid frame discriminator
0.12117399999999634ms
'connect-ok.json' carries a valid frame discriminator
0.1013629999999921ms
'exec-approval-requested.json' carries a valid frame discriminator
0.10232400000001007ms
'health-event.json' carries a valid frame discriminator
0.09400200000001746ms
'logs-tail-response.json' carries a valid frame discriminator
0.12255500000000552ms
'models-list-response.json' carries a valid frame discriminator
0.10662100000001828ms
'rpc-error.json' carries a valid frame discriminator
0.10052199999998379ms
'session-message.json' carries a valid frame discriminator
0.0998909999999853ms
'session-tool.json' carries a valid frame discriminator
0.09250900000000684ms
'sessions-changed.json' carries a valid frame discriminator
0.08841400000000021ms
'tick.json' carries a valid frame discriminator
0.10249500000000467ms
'auth-pairing-required-error.json' conforms to its frame shape
0.3718020000000024ms
'chat-delta.json' conforms to its frame shape
0.1042280000000062ms
'chat-final-with-tools.json' conforms to its frame shape
0.07814799999999877ms
'connect-challenge.json' conforms to its frame shape
0.07775799999998867ms
'connect-hello-ok-device-token.json' conforms to its frame shape
0.09434300000000917ms
'connect-ok.json' conforms to its frame shape
0.19174000000001ms
'exec-approval-requested.json' conforms to its frame shape
0.08008100000000695ms
'health-event.json' conforms to its frame shape
0.06906499999999482ms
'logs-tail-response.json' conforms to its frame shape
0.08174300000001722ms
'models-list-response.json' conforms to its frame shape
0.08078199999999924ms
'rpc-error.json' conforms to its frame shape
0.17690800000002582ms
'session-message.json' conforms to its frame shape
0.10191500000001952ms
'session-tool.json' conforms to its frame shape
0.08839299999999639ms
'sessions-changed.json' conforms to its frame shape
0.08585999999999672ms
'tick.json' conforms to its frame shape
0.08354599999998413ms
chat-final fixture carries the final-state fields the adapter depends on
0.29207199999999034ms
exec.approval.requested fixture exposes options for the user prompt
0.4448030000000074ms
openclaw-hook.test.ts
8 / 8 7ms
openclaw-hook → telemetry spans 8 / 8
OPENCLAW_IDLE_GAP_MS is conservative (60–180 s) so multi-turn collab stays together
2.347410999999994ms
chat.send produces exactly one turn_start span carrying the prompt text
0.7383060000000228ms
chat.final with a response + tools yields turn_response + per-tool tool_result spans
1.5592790000000036ms
chat.delta emits no spans — deltas are streaming chunks, not eval signals
0.7589279999999974ms
chat.aborted emits a manual task_boundary so the user gesture closes the task immediately
0.2568390000000136ms
chat.error emits nothing — the agent may retry, idle timer keeps running
0.20771400000000995ms
idle-gap task_boundary span carries boundary_signal=idle_gap
0.38287900000000263ms
all emitted spans propagate traceId for run correlation
0.3484070000000088ms
opencode-client.test.ts
13 / 13 21ms
OpenCodeClient 12 / 12
health › should call /global/health
10.231075000000004ms
listSessions › should call /session with directory and limit
1.0333430000000021ms
createSession › should POST to /session
1.0388210000000129ms
sendMessage › should POST to /session/{id}/message with parts
1.0734640000000013ms
sendMessage › should include model option when provided
0.6780259999999885ms
abortSession › should POST to /session/{id}/abort
0.6875900000000001ms
respondPermission › should POST allow response
0.5457150000000013ms
respondPermission › should POST deny response
0.5149289999999951ms
HTTP error handling › should throw on non-ok response
2.8654249999999877ms
disconnect › should prevent reconnection after disconnect
0.6125569999999811ms
url accessor › should return server URL
0.39442600000000994ms
url accessor › should strip trailing slash
0.4077570000000037ms
OpenCodeAdapter event mapping 1 / 1
should export OpenCodeSSEEvent type
0.24440000000001305ms
opencode-hook.test.ts
8 / 8 7ms
opencode-hook → telemetry spans 8 / 8
tool part with status=running produces a tool_call span
3.956233999999995ms
tool part with status=completed produces a tool_result span
0.31932299999999714ms
todowrite completion with all todos completed emits a task_boundary span (todo_complete)
0.5018689999999992ms
todowrite completion with a pending todo does NOT emit a task_boundary
0.29723999999998796ms
todowrite reads todos out of state.output JSON string when input is absent
0.31253199999997605ms
non-tool part returns an empty span list
1.0580009999999902ms
message.updated for user role with prompt emits a turn_start
0.5125749999999698ms
message.updated for assistant role with response emits a turn_response
0.2731830000000173ms
passive-observer.test.ts
4 / 4 7ms
passive-observer parsers 4 / 4
parses ps output without depending on fixed command columns
4.155956000000003ms
summarizes Claude transcripts and redacts tool secrets
1.6030350000000055ms
summarizes Codex rollout metadata, context, and pending tool calls
1.245823999999999ms
maps lsof field output to Codex rollout files by pid
0.4384330000000034ms
project-name.test.ts
14 / 14 74ms
resolveProjectName 10 / 10
returns git toplevel basename from a nested subdir
17.247573000000017ms
falls back to nearest package.json name when no git
5.209719999999976ms
skips package.json with empty name and keeps walking
4.305161999999996ms
falls back to cwd basename when no git and no package.json
4.1148139999999955ms
returns 'unknown' for a basename-less root
3.7892319999999984ms
AGENTDECK_PROJECT_NAME env var wins over everything
7.100149000000016ms
envOverride option takes precedence over env var
0.5332170000000076ms
preserves scoped package name verbatim
4.466064999999986ms
git subprocess error (non-repo) does not throw
5.242879999999985ms
malformed package.json is ignored (walks to parent)
4.523893000000015ms
gitToplevelBasename 2 / 2
returns null outside a git worktree
3.9819730000000106ms
returns repo basename from nested subdir
10.618822000000023ms
nearestPackageJsonName 2 / 2
returns null when no ancestor has package.json
0.88870399999999ms
returns nearest ancestor name
1.0882670000000019ms
session-aggregator.test.ts
7 / 7 24ms
session-aggregator 7 / 7
uses ownState for the current session without fetching /health
5.6746029999999905ms
fetches sibling /health and merges state and modelName
3.44853599999999ms
falls back to base session info when sibling /health fails (no cache)
0.862305000000049ms
returns cached state when sibling /health fails after a previous success
0.6736890000000244ms
clearSiblingStateCache removes cached entry
0.4991850000000113ms
buildEnrichedSessionsList includes own session and excludes daemon
12.153202999999962ms
buildEnrichedSessionsList returns own session in single-session mode without /health calls
0.6408599999999751ms
tui-hud-entries.test.ts
16 / 16 24ms
buildHudEntries — primary anchoring 7 / 7
promotes the matching-port sibling to primary instead of appending a duplicate
15.401246000000015ms
patches the anchored sibling with the primary's live fields (matches macOS / Android)
0.647609999999986ms
uses the primary's projectName for the #N suffix grouping after anchoring
0.5304520000000252ms
preserves the deterministic #N order when primary anchors a sibling slot
1.1488780000000247ms
appends a synthetic primary when no sibling shares its agentType
0.3498690000000124ms
skips the synthetic primary when a sibling shares agentType but no port match (duplicate guard)
0.3056720000000155ms
never appends primary when agentType is daemon or openclaw
0.33285300000000007ms
buildHudEntries — virtual OpenClaw 2 / 2
inserts a virtual OpenClaw row when gateway is available and sessions has none
0.4131349999999543ms
does not insert a virtual row when sessions already contains an openclaw entry
0.31588799999997264ms
buildHudEntries — hotkey eligibility (sibling-only) 1 / 1
primary and virtual rows do not consume hotkey slots
0.4137759999999844ms
formatTaskEvalSuffix — task_end badge for each outcome class 6 / 6
renders ✓ for success
0.2748259999999618ms
renders ✗ for fail
0.20548100000002023ms
renders △ for partial
0.15575599999999667ms
renders ⊘ for abandoned (manual cancel)
0.13746800000001258ms
renders ? as score placeholder when judge has not produced a number yet
0.2213949999999727ms
returns empty string while the eval is still pending (outcome undefined)
0.179711999999995ms
codex-install.test.ts
29 / 29 34ms
codex-mini-toml: applyManagedBlock 3 / 3
appends fence when absent
3.786106000000018ms
replaces existing fence block
0.5538279999999816ms
apply twice is idempotent
0.3882770000000164ms
codex-mini-toml: removeManagedBlock 2 / 2
leaves user content
0.5585649999999873ms
is idempotent without fence
0.19616700000000264ms
codex-mini-toml: hasTopLevelKeyOutsideFence 3 / 3
detects user notify key
0.4060940000000244ms
ignores notify key inside table
0.271710000000013ms
ignores notify key inside fence
0.20574199999998655ms
codex-mini-toml: hasTableOutsideFence 5 / 5
detects user [otel] table
0.3956880000000069ms
detects user [otel.exporter] dotted table
0.24866600000001426ms
detects array-of-table header [[hooks.Stop]]
0.2653219999999976ms
ignores [otel] inside fence
0.20613099999999918ms
ignores [otelfoo] (word boundary)
0.19088899999999853ms
codex-mini-toml: quoted 3 / 3
escapes backslash and double quote
0.31089000000000055ms
escapes newline and tab
0.18433900000002268ms
passes simple ASCII
0.18074300000000676ms
codex-install: managedBlockBody 3 / 3
roundtrip preserves user TOML byte-for-byte (load-bearing)
1.6161050000000046ms
matches Codex schema (lifecycle hooks + endpoints + notify dummy)
1.402811999999983ms
omits conflicting optional channels when asked
1.3264460000000327ms
codex-install: install / uninstall (file I/O) 10 / 10
creates config with fence when file is absent
4.683624000000009ms
preserves user content when installing into existing config
1.8060919999999783ms
skips when user already has [features] table outside fence
1.7142029999999977ms
skips when user already has [hooks] table outside fence
0.8231949999999983ms
omits notify when user has top-level notify
1.691899000000035ms
omits OTel when user has [otel] table
2.6122010000000273ms
uninstall strips fence and preserves user content
2.6955370000000016ms
uninstall is idempotent when no config exists
1.6229250000000093ms
honours AGENTDECK_NO_CODEX_HOOKS=1 opt-out
0.731977000000029ms
install is idempotent (same port → no rewrite)
1.6399400000000242ms
bridge-client.test.ts
3 / 3 3.4s
BridgeClient — port provider 3 / 3
skips connect when provider returns null
55.15118099999995ms
connects once provider returns a live port
1259.318172ms
rebinds to a new port when provider value changes
2103.5040950000002ms
session-slot-button.test.ts
12 / 12 8ms
computeCenterSlot 6 / 6
SD+ 4x2 → bottom-center
3.334633999999994ms
SD MK2 5x3 → true geometric center
0.25044900000000325ms
SD XL 8x4 → middle row, mid column
0.18193499999998153ms
SD Mini 3x2 → bottom-center
0.17646700000000237ms
single key device → slot 0
0.17059800000001246ms
clamps degenerate zero rows/cols to slot 0
0.17012800000000539ms
computeCenterCluster 6 / 6
SD+ 4x2 → 2x2 cluster on geometric center (slots 1,2,5,6)
1.6142209999999864ms
SD XL 8x4 → 2x2 cluster on geometric center (slots 11,12,19,20)
0.40529300000000035ms
SD MK2 5x3 → single full hero on slot 7
0.3482659999999953ms
SD Mini 3x2 (odd cols) → single full hero on slot 4
0.2884559999999965ms
single-key device → single full hero on slot 0
0.26112500000002115ms
degenerate zero dimensions → single hero on slot 0
0.2517609999999877ms
session-slot-manager.test.ts
8 / 8 13ms
SessionSlotManager detail layout 8 / 8
re-points detail focus onto the codex fold representative when the focused thread is absorbed
5.302430999999956ms
exits detail view when the focused session is gone with no fold successor
0.47518800000000283ms
folds codex companion threads by project before slot assignment
2.23983800000002ms
renders connected no-session list as status cards instead of text-only empty buttons
0.7077899999999886ms
puts processing tool info before OpenClaw presets
1.6027750000000083ms
keeps a processing status tile even before tool metadata arrives
0.3963200000000029ms
aliases the model name on detail MODEL surfaces (status card + OpenClaw preset)
0.9510579999999891ms
uses actual parser options and reserves MORE only when awaiting overflow exists
0.5354900000000384ms
format-utils.test.ts
18 / 18 8ms
adjustUsagePercent 11 / 11
returns undefined when percent is null
3.2735819999999762ms
returns undefined when percent is undefined
0.2761069999999961ms
returns percent unchanged when resetsAt is null
0.2639289999999903ms
returns percent unchanged when resetsAt is undefined
0.15495399999997517ms
returns percent unchanged when resetsAt is in the future
0.456750999999997ms
returns 0 when resetsAt is in the past (window expired)
0.22495100000000434ms
returns 0 when resetsAt equals now (edge case)
0.1412740000000099ms
handles invalid date string gracefully (returns percent)
0.15250100000000089ms
handles empty string resetsAt (returns percent)
0.11913999999998737ms
returns percent unchanged when resetsAt is far in the past (>1h)
0.1676130000000171ms
still returns 0 just after the 1h threshold boundary
0.17011700000000474ms
formatResetTime 7 / 7
returns "now" when resetsAt is in the past
0.24816599999999767ms
returns undefined for null input
0.19707900000000222ms
returns minutes-only for < 1h remaining
0.24459999999999127ms
returns hours and minutes for < 24h remaining
0.2191919999999925ms
returns days and hours for >= 24h remaining
0.1720499999999845ms
omits minutes when exactly on the hour
0.17207999999999402ms
passes through pre-formatted strings (no T)
0.19898099999997498ms
llm-settings.test.ts
10 / 10 9ms
llm-settings 10 / 10
returns defaults when settings.json is missing
3.52823699999999ms
reads llm.mlx pin from settings.json
0.6697729999999922ms
treats "qwen3-30b" and "default" as placeholders (unpinned)
0.8819180000000131ms
falls back to apme.judge.model when llm.mlx is absent
0.36531300000001465ms
strips /chat/completions suffix from legacy endpoints
0.4369709999999998ms
prefers llm.mlx over apme.judge when both set
0.33801100000002293ms
resolveMlxModel: pin > probe > fallback
0.8430450000000178ms
pickMlxModel: 4-layer priority (pin > fallback > first > null)
0.492795000000001ms
mlxChatUrl reflects endpoint setting
0.4989839999999788ms
caches result for TTL window
0.8099850000000117ms
session-utils.test.ts
13 / 13 20ms
agentTypeRank 1 / 1
ranks openclaw first, then claude-code, codex-cli, opencode, others
3.5119419999999764ms
naturalLabelCompare 2 / 2
orders numeric chunks naturally (Agent 2 before Agent 10)
11.410067999999995ms
treats undefined as empty string
0.30886699999999223ms
sortSessions 6 / 6
places openclaw before claude-code regardless of project
1.1881170000000054ms
sorts by project name within the same agent type
0.32918699999999035ms
sorts numbered project names naturally (#2 before #10)
0.296559000000002ms
breaks ties on startedAt ascending (oldest first)
0.2811550000000125ms
falls back to id natural-compare when startedAt ties to the same ms
0.2889069999999947ms
does not mutate the input array
0.29643899999999235ms
assignDisplayNames 4 / 4
passes single sessions through without #N suffix
0.4269859999999994ms
adds #1/#2 suffixes for duplicate (project, agentType) tuples in input order
0.3624680000000069ms
numbers same project across different agentTypes independently
0.36939899999998715ms
produces the same #N assignment as a deterministic sort + display pipeline
0.4310820000000035ms
svg-renderers/model-alias.test.ts
7 / 7 4ms
aliasModelName 3 / 3
shortens claude family-major-minor
2.6422369999999944ms
drops trailing date suffix on claude releases
0.17175000000000296ms
passes gpt and unknown strings through unchanged
0.16102300000000014ms
formatModelEffort 4 / 4
returns aliased model when no effort to show
0.2730730000000108ms
appends non-default effort when it fits
0.1264720000000068ms
truncates aliased model name to fit budget with effort suffix
0.20468999999999937ms
returns empty string for missing model
0.10545000000001892ms
timeline-summarizer.test.ts
13 / 13 5ms
extractTopicHintWithKind — Korean polite-closer robustness 7 / 7
returns the cleaned topic when the response opens with "네, …"
2.813976999999994ms
returns the original (kind=fallback) when the entire response is just a polite closer
0.3613870000000077ms
returns null for empty / very short text (still)
0.23022800000001098ms
skips lone heading markers and code fences
0.3602149999999824ms
a heading WITH text becomes the topic (heading is the title)
0.1855510000000038ms
strips list bullet markers
0.13927000000001044ms
extractTopicHint convenience returns just the hint string
0.1503370000000075ms
promptSnippetFallback 6 / 6
returns first sentence trimmed
0.25790000000000646ms
returns whole string when no sentence terminator
0.14869500000000357ms
truncates to maxLen with ellipsis
0.21561600000001135ms
cuts at first newline if no sentence terminator
0.10213499999997566ms
returns null for empty / very short input
0.13387199999999666ms
handles Korean prompts
0.14303599999999506ms
timeline-task-hierarchy.test.ts
40 / 40 15ms
deduplicateEntry — task hierarchy 3 / 3
always adds task_start even with identical raw within 8s
3.114241000000021ms
always adds task_end with same boundarySignal back-to-back
0.2999540000000138ms
still dedupes ordinary chat_start within 8s
0.17962199999999484ms
timelineIconKey 5 / 5
maps task entries to "task"
0.3005550000000028ms
maps tool_request status to success/error/awaiting
0.2812449999999842ms
chat_start in flight is "running"; chat_end is "success"
0.28332799999998315ms
error → error; user_action → user; memory_recall → memory
0.23490599999999517ms
every key has an e-ink glyph of constant 4-char width
0.4445819999999969ms
isInFlightTask 5 / 5
task_start without matching task_end is in flight
0.29679899999999293ms
task_start whose task_end (same taskId) appeared is finished
0.21054800000001705ms
mismatched taskId on task_end does not close it
0.16899599999999282ms
task_start without taskId is never considered in flight
0.1436779999999942ms
non-task_start entries are never in flight
0.14968600000000265ms
isRotatingEntry 5 / 5
chat_start always rotates (icon-key running)
0.12726299999999924ms
orphan task_start rotates via in-flight predicate
0.1670520000000124ms
closed task_start does not rotate
0.1047190000000171ms
static rows do not rotate
0.1583699999999908ms
eval_result and task_end never rotate
0.10848400000000424ms
parseTimelineMarkdown 9 / 9
returns single text line for plain text
1.1753280000000075ms
parses headings 1-6 with required space
0.5771629999999845ms
parses bullets and numbered lists
0.3539949999999976ms
handles code fence — verbatim lines, not interpreted
0.25548599999999055ms
blank line → blank kind
0.2504289999999969ms
parses tables with header separator
0.5266169999999875ms
parses tables without separator (no header)
0.3344049999999754ms
table block ends at first non-table line
0.36773600000000783ms
quote lines parse
0.2093770000000177ms
parseInlineSpans 9 / 9
returns empty for empty string
0.28751499999998487ms
returns single plain span for plain text
0.20939699999999561ms
parses **bold**
0.2466229999999996ms
parses *italic* (single star)
0.16965700000000083ms
parses `code` inline
0.1291450000000225ms
parses [text](url) link
0.16854499999999462ms
unclosed ** falls back to plain
0.24363800000000424ms
multiple spans in one line
0.19655699999998433ms
first-match-wins: ** consumed before * (no double-italic split)
0.13506399999999985ms
prepareMarkdownDetail 4 / 4
preserves markdown markers (chat-response detail goes to client)
0.5629209999999887ms
still filters system JSON blobs
0.2288560000000075ms
collapses 3+ blank lines but keeps double-blank paragraph break
0.22438900000000217ms
contrasts with cleanDetailText which strips markdown (non-chat path)
0.927031999999997ms
Android PASS
JUnit + Robolectric · 13 files · 175 tests
data.DashboardOrientationTest
3 / 3 3ms
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
33 / 33 7.2s
parse state_update with all permission modes
6249ms
parse connection connected with sessionId
40ms
parse sessions_list
47ms
PluginCommands selectOption generates valid JSON
44ms
parse timeline_event with fractional timestamps
74ms
parse button_state
41ms
PluginCommands utility with and without value
31ms
parse invalid json returns null
39ms
parse timeline_history
27ms
parse timeline_event upsert
29ms
parse state_update with processing state and tool info
32ms
PluginCommands respond escapes special characters
32ms
PluginCommands respond generates valid JSON
38ms
parse state_update with permission options
28ms
parse connection disconnected
24ms
parse missing type returns null
38ms
parse deck_slot_map
29ms
parse usage_update with extra usage
24ms
parse state_update with ollama status
22ms
PluginCommands navigateOption
23ms
parse state_update with agent capabilities
24ms
parse unknown type returns null
28ms
parse user_prompt
27ms
BridgeTimelineEntry converts to TimelineEntry
42ms
parse state_update with model catalog
23ms
parse state_update ignores unknown fields
18ms
parse state_update with idle state
19ms
parse display_state sleep and wake
23ms
parse voice_state
20ms
parse encoder_state
22ms
PluginCommands interrupt and escape
20ms
parse usage_update with rate limits
17ms
parse timeline_event
17ms
state.SessionMetricsTest
8 / 8 8ms
reset clears all metrics
7ms
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
1ms
onMessageReceived increments count
state.TimelineDisplayScenarioTest
5 / 5 7ms
multi-agent dashboard timeline projects meaningful session rows
5ms
synthetic chat_start is suppressed once completion arrives
1ms
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 33ms
addEntry drops openclaw placeholder with status-only detail
7ms
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
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
1ms
timelineDisplayGroups hides chat_end when chat_response already represents the same turn
upsertEntry adds new entry if no match
addEntry stores entry
groupConsecutive does not merge tool_request across sessions
groupConsecutive groups same summary within 60s
timelineDisplayGroups keeps independent sessions visible
updateLastOfType modifies the last matching entry
upsertEntry refuses to insert otel noise via add fallback
addEntries merges and deduplicates
addEntry drops openclaw placeholder with arbitrary future status
1ms
upsertEntry preserves existing detail if new detail is null
addEntry keeps real openclaw tool rows
groupConsecutive splits tool_request after 10s gap
addEntries sorts by timestamp
upsertEntry preserves existing summaryKind when new entry omits it
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
1ms
addEntry deduplicates within 5s window
upsertEntry propagates summaryKind progression heuristic to llm
timelineDisplayGroups collapses synthetic chat_start once response arrives
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
12ms
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
3ms
groupConsecutive groups tool_request within 10s
upsertEntry merges task_end by taskId beyond the 1s tolerance window
1ms
state.TimelineTaskHierarchyTest
24 / 24 17ms
mismatched taskId on task_end does not close it
1ms
stripMarkdownInline drops markers including table syntax
3ms
detail redundancy fires when prefix matches summary
1ms
detail redundancy does not fire when content is genuinely new
1ms
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
2ms
task entries never group with each other
iconKey resolves tool_request status to success error awaiting
taskId is the strongest grouping key
1ms
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
5ms
task_start without taskId is never considered in flight
orphan task_start rotates via in-flight predicate
markdown parser code fence is verbatim
1ms
eink glyphs are constant 4-char width
terrarium.TerrariumStateTest
7 / 7 267ms
claude processing does not bleed into OpenClaw crayfish on aggregate view
124ms
stale gateway error is ignored when gateway is unavailable
24ms
authenticated gateway shows OpenClaw at rest
22ms
gateway error surfaces sick OpenClaw
22ms
reachable gateway without auth hides OpenClaw and workers
22ms
OpenClaw processing routes its own crayfish
21ms
daemon aggregate keeps OpenClaw crayfish calm while claude works
28ms
terrarium.renderer.EinkAnimationTimingTest
3 / 3 5ms
animation frame advance is elapsed-time based and bounded
3ms
fish simulation scales movement for partial color frames
1ms
color e-ink animation uses video-like cadence
ui.eink.EinkAttentionPanelTest
3 / 3 14ms
non-focused awaiting session hides unavailable live prompt fields
13ms
primary awaiting session is surfaced when not represented by siblings
featured attention prefers focused awaiting session
1ms
ui.eink.SessionDisplayOrderingTest
6 / 6 4ms
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
compareSessionsForDisplay tie-breaks on natural id when startedAt is identical
1ms
agentTypeRank places openclaw first
compareSessionsForDisplay is stable across re-sorts of any input order
1ms
ui.monitor.OpenClawDisplayLinesTest
4 / 4 3ms
empty when no default tagged
3ms
empty catalog yields empty list
keeps only default model when present
empty when default is unavailable
ui.monitor.SubscriptionLineTest
12 / 12 10ms
subscriptionTrailing flags expired for past dates
6ms
malformed until renders renewal needed
1ms
future ISO8601 with offset renders date suffix
parseUntilInstant accepts ISO8601
bare date in past renders renewal needed
1ms
future ISO8601 with fractional seconds renders date suffix
subscriptionTrailing returns date for future
1ms
parseUntilInstant accepts blank as null
past until renders renewal needed
bare date string parses as UTC midnight
1ms
subscriptionTrailing returns null for blank or null
null until renders name only
util.TimeFormatUtilsTest
20 / 20 9ms
gaugeBar clamps below 0
1ms
formatCount thousands show K
1ms
formatBytes kilobytes
formatDurationCompact seconds
formatDurationCompact exact minutes no seconds
1ms
formatDurationCompact sub-second
formatCount int overload works
gaugeBar clamps above 100
formatBytes small values
1ms
formatCount small numbers unchanged
gaugeBar 50 percent is half filled
gaugeBar 0 percent is all empty
formatBytes megabytes
formatResetTime returns original on parse failure
1ms
gaugeBar custom width
formatBytes gigabytes
formatUptime zero returns 0 colon 00
1ms
formatCount millions show M
formatDurationCompact minutes
2ms
gaugeBar 100 percent is all filled
Robot Framework PASS
ESP32 Hardware Tests · 1 suites · 4 scenarios · 7 tests · 4 boards
BoardBuildFlash+BootBoot TimeFW SizeBoot HeapLatency
86Box20.9s
IPS 3.5"17.2s
Round17.1s
TC00115.5s
01_build.robot no-hwquicksmoke
7 / 7
Build And Verify 4 boards 4 / 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
20.9s
IPS 3.5 Build And Verify
17.2s
Round AMOLED Build And Verify
17.1s
Ulanzi TC001 Build And Verify
15.5s
Boot Test Environment Builds Successfully
1.4s
Source Files Are Present
PlatformIO Configuration Parses Cleanly
904ms
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 · 17,398 lines tracked
Lines ≥17%: 35.9%
Functions ≥15%: 32.2%
Branches ≥14%: 31.6%
Statements ≥16%: 34.4%
bridge
36% Lines
35% Stmts
34% Funcs
32% Branch
4553/12604 lines covered
plugin
28% Lines
26% Stmts
23% Funcs
21% Branch
1010/3612 lines covered
shared
51% Lines
51% Stmts
39% Funcs
47% Branch
483/944 lines covered
hooks
82% Lines
80% Stmts
86% Funcs
73% Branch
194/238 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/d200h/hid-protocol.ts 0% 0% 0% 0%
bridge/src/d200h/image-renderer.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/mdns.ts 5% 3% 9% 5%
bridge/src/tui/dashboard.ts 5% 11% 3% 6%
bridge/src/antigravity-local.ts 7% 4% 20% 6%
bridge/src/mlx-probe.ts 6% 0% 0% 6%
bridge/src/pixoo/pixoo-camera.ts 6% 0% 0% 7%
bridge/src/apme/outcome.ts 8% 2% 8% 8%
bridge/src/pixoo/pixoo-renderer.ts 6% 0% 0% 8%
bridge/src/pixoo/pixoo-client.ts 11% 0% 0% 11%
bridge/src/pixoo/pixoo-sprites.ts 10% 0% 8% 11%
bridge/src/pixoo/pixoo-bridge.ts 11% 0% 0% 13%
bridge/src/esp32-serial.ts 12% 12% 4% 13%
bridge/src/logger.ts 18% 10% 17% 15%
bridge/src/timeline-summarizer.ts 13% 0% 0% 15%
bridge/src/gateway-probe.ts 12% 0% 0% 16%
bridge/src/display-monitor.ts 20% 9% 18% 22%
bridge/src/usage-api.ts 26% 12% 50% 28%
bridge/src/codex-auth.ts 36% 8% 25% 37%
bridge/src/bridge-core.ts 37% 39% 26% 39%
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% 40% 42% 50%
bridge/src/pty-manager.ts 54% 31% 53% 55%
bridge/src/hook-server.ts 53% 29% 53% 55%
bridge/src/ws-server.ts 60% 31% 58% 59%
bridge/src/adapters/openclaw.ts 60% 43% 55% 62%
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 68% 72% 100% 67%
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/session-registry.ts 70% 46% 71% 73%
bridge/src/tui/ansi.ts 75% 49% 83% 75%
bridge/src/apme/store.ts 64% 68% 77% 77%
bridge/src/state-machine.ts 80% 62% 81% 80%
bridge/src/adapters/monitor.ts 81% 60% 87% 81%
bridge/src/apme/runner.ts 76% 63% 69% 82%
bridge/src/adapters/pty-adapter.ts 82% 81% 65% 82%
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/session-aggregator.ts 85% 58% 86% 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/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 60% 68% 75% 63%
hooks/src/codex-install.ts 84% 62% 87% 87%
hooks/src/codex-mini-toml.ts 97% 91% 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% 36% 67% 60%
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 86% 79% 85% 90%
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 10% 5% 11% 9%
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/session-utils.ts 41% 41% 47% 43%
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/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%