Status
FAIL
1803 executed tests
Passed
1799
99.8% pass rate
Failed
4
 
Duration
19.4s
13.9s vitest + 5.6s android
TS Line Coverage
40.6%
8,334/20,540 TypeScript lines
Total Tests
1803
Pass Rate
99.8%
Line Coverage
40.6%

Vitest

PASS
Pass 1601 Fail 0 88 files Coverage + JSON report

Android

PASS
Pass 195 Fail 0 14 files JUnit + Robolectric on ubuntu

Apple (XCTest)

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

Robot Framework

FAIL
Pass 3Fail 4Skip 0
Terminal Output Parsing PASS
Claude Code와 Codex CLI의 터미널 출력을 정확히 해석하는가?
257 passed 0 failed 3 files 273ms
output-parser.test.ts
214 / 214 189ms
OutputParser 214 / 214
basic option parsing › parses clean numbered options with newlines
17.352332000000047ms
basic option parsing › detects (recommended) marker
1.6499689999999418ms
basic option parsing › detects ✔ selected marker
1.4987259999999196ms
basic option parsing › handles both recommended and selected on different options
0.862805000000094ms
basic option parsing › parses full Claude model selector with labels and middle dot
1.3148109999999633ms
ANSI-stripped options › parses concatenated text with · delimiter
1.2588759999999866ms
ANSI-stripped options › extracts version numbers from · delimited labels
0.5674330000000509ms
chunked input debounce › does NOT emit immediately on first chunk
0.603870000000029ms
chunked input debounce › batches multiple chunks into single emission
2.7768080000000737ms
chunked input debounce › resets debounce timer when new chunk with options arrives
0.8516140000000405ms
chunked input debounce › simulates real /model flow: split across chunks
1.797745999999961ms
model ID date rejection › does NOT parse 20251001 from model ID as option number
1.2395999999999958ms
model ID date rejection › rejects large numbers that look like dates
0.6996500000000196ms
version number rejection › does NOT parse version "4.6" followed by digit as option
0.9996810000000096ms
version number rejection › does NOT parse "6)" from "4.6)" as option 6
0.9438460000000077ms
stale buffer overwrite › newer options overwrite older ones with same index
0.939469000000031ms
permission prompts › detects Yes/No/Always pattern
1.5118999999999687ms
permission prompts › keeps ALL real options when a numbered prompt contains "Yes, allow once" (no collapse to 3)
1.3892009999999573ms
permission prompts › detects (Y)es/(N)o pattern
1.312787999999955ms
permission prompts › emits immediately with no debounce
0.7630390000000489ms
permission prompts › sets yes_no_always prompt type
0.5361440000000357ms
permission prompts › sets yes_no prompt type
0.47791399999994155ms
permission prompts › extracts the multi-line question header above yes/no/always options
0.6519909999999527ms
permission prompts › extracts the question from a box-framed permission prompt
0.8025120000000925ms
permission prompts › extracts the inline question from the (Y)es/(N)o line
0.49847299999998995ms
permission prompts › does not mistake box-drawing or footer chrome for a question
0.6230959999999186ms
permission prompts › suppresses false idle from user prompt echo after permission (interactive cooldown)
0.8637970000000905ms
permission prompts › allows real idle after interactive cooldown expires
0.8532270000000608ms
diff prompts › detects (V)iew/(A)pply/(D)eny pattern
0.9514110000000073ms
diff prompts › detects lowercase (a)pply/(d)eny/(v)iew pattern
0.5256439999999429ms
diff prompts › emits immediately with no debounce
0.49822200000005523ms
diff prompts › suppresses false idle from user prompt echo after diff (interactive cooldown)
2.896852000000081ms
various option counts › handles 1 option
0.622335000000021ms
various option counts › handles 2 options
0.5894130000000359ms
various option counts › handles 5+ options
0.5596479999999247ms
various option counts › marks direct-input options as freeform instead of a normal choice
0.7060319999999365ms
various option counts › handles bullet-style options
0.6466699999999719ms
option updates › emits new options when data changes after first emission
0.7330419999999549ms
spinner cancels option timer › spinner cancels pending option debounce
0.7137460000000146ms
idle vs option debounce › idle prompt is ignored when option debounce is pending
0.9406999999999925ms
idle vs option debounce › idle prompt fires normally when no option debounce is pending
0.7696509999999535ms
interactive prompt during spinner › stops spinner when permission prompt arrives
1.111770999999976ms
interactive prompt during spinner › stops spinner when diff prompt arrives
0.8219380000000456ms
interactive prompt during spinner › stops spinner when option prompt arrives
0.9515809999999192ms
interactive prompt during spinner › stops spinner when idle prompt arrives in small chunk
0.9812170000000151ms
interactive prompt during spinner › ignores idle prompt in large chunk during spinner (screen redraw)
0.7445729999999458ms
cleanOptionLabel (via parseOptions) › deduplicates exact CamelCase matches
0.7822439999999915ms
cleanOptionLabel (via parseOptions) › preserves labels without · delimiter
0.5585260000000289ms
cleanOptionLabel (via parseOptions) › removes (recommended) from label text
0.578563000000031ms
cleanOptionLabel (via parseOptions) › removes ✔ from label text
0.5023499999999785ms
cleanOptionLabel (via parseOptions) › extracts version from identity before middle dot
0.551431999999977ms
metadata events › emits project_name from startup banner
0.6726899999999887ms
metadata events › emits project_name only once (caches)
0.45797800000002553ms
metadata events › parses absolute path for project_name
0.40606000000002496ms
metadata events › seedProjectName disables the scrape (resolver wins over basename)
0.485178000000019ms
metadata events › seeded name survives reset(); scrape stays disabled
0.4448130000000674ms
metadata events › seeding 'unknown' keeps the scrape live as fallback
0.4423180000000002ms
metadata events › emits model_info with model and plan
0.43102699999997185ms
metadata events › emits model_info without plan
0.4744079999999258ms
metadata events › emits model_info only once for same model (caches)
0.3809230000000525ms
metadata events › re-emits model_info when model changes
0.44055500000001757ms
metadata events › parses ANSI-stripped model_info
0.38948900000002595ms
metadata events › detects API billing plan
0.46737500000006094ms
metadata events › emits status_line with duration and tokens
0.7589309999999614ms
metadata events › parses zero-minute status line
0.6199500000000171ms
metadata events › emits tool_action from ⏺ pattern
0.4225209999999606ms
metadata events › extracts various tool names
0.4384410000000116ms
user prompt › emits user_prompt after first idle has been seen
0.6899710000000141ms
user prompt › does NOT emit user_prompt before first idle
0.5968869999999242ms
user prompt › filters out mode banner text
0.5353530000001001ms
user prompt › filters out numbered option lines
0.5447500000000218ms
user prompt › filters out keyboard hint text
0.7913919999999735ms
user prompt › filters out "esc to interrupt" text
0.6279260000000022ms
user prompt › filters out autocomplete suggestions
1.5777530000000297ms
user prompt › filters out box-drawing decorative lines
0.692937000000029ms
usage info › parses usage percentage
0.5898140000000467ms
usage info › parses usage cost
0.7649820000000318ms
usage info › parses session percentage with hour limit
0.6758549999999559ms
usage info › parses reset time with timezone
0.4810300000000325ms
usage info › parses time remaining
0.49426600000003873ms
spinner lifecycle › emits spinner_start on spinner char (after idle seen)
0.4594699999998966ms
spinner lifecycle › does NOT emit spinner_start before first idle
0.4216190000000779ms
spinner lifecycle › emits spinner_stop after debounce (2000ms)
0.49294300000008207ms
spinner lifecycle › does NOT emit duplicate spinner_start on repeated chars
0.6014550000001009ms
spinner lifecycle › resets spinner debounce timer on repeated chars
0.6274449999999661ms
spinner lifecycle › ignores spinner chars in large text blocks (>80 non-ws)
0.5214559999999437ms
spinner lifecycle › recognizes all spinner characters
1.7638210000000072ms
idle detection › emits idle after IDLE_DEBOUNCE_MS (300ms)
0.5663600000000315ms
idle detection › sets seenFirstIdle on first idle prompt
0.566449999999918ms
idle detection › cancels idle timer when spinner starts
0.81766099999993ms
idle detection › recognizes > as idle prompt char
0.7647210000000086ms
mode detection › detects plan mode
0.6201109999999517ms
mode detection › detects accept edits mode
0.6541649999999208ms
mode detection › detects default mode after Shift+Tab
0.7675269999999728ms
mode detection › detects default mode via idle prompt after Shift+Tab
0.6887590000000046ms
mode detection › emits default mode on Shift+Tab timeout (2s)
0.6829280000000608ms
mode detection › detects ANSI-stripped plan mode text
0.6404789999999139ms
mode detection › detects ANSI-stripped accept edits text
0.6279460000000654ms
mode detection › clears pending mode switch when mode banner is detected
0.7679379999999583ms
reset › clears cached project name and model name
0.7940469999999777ms
reset › disables spinner detection (clears seenFirstIdle)
0.6712570000000824ms
reset › allows re-detection after new idle prompt post-reset
0.7377910000000156ms
reset › allows re-detection of project name after reset
1.2800959999999577ms
reset › allows re-detection of model info after reset
0.5622630000000299ms
buffer management › truncates buffer when exceeding 8192 chars
1.372398999999973ms
buffer management › keeps the last 4096 chars after truncation
1.6986990000000333ms
option navigation › cursor movement during option selection does NOT trigger idle
0.8438390000000027ms
option navigation › cursor movement does NOT trigger user_prompt
0.9880190000000084ms
option navigation › normal cursor movement between options emits no idle or user_prompt
1.0618880000000672ms
option navigation › real idle prompt still works after option navigation
0.9961050000000569ms
option navigation › effort/hint text during navigation does not trigger events
0.8130110000000741ms
option navigation › IDLE_PROMPT requires space/tab/NBSP after ❯ (not newline)
0.6334960000000365ms
option navigation › USER_PROMPT requires space/tab after ❯ (not newline)
0.6463699999999335ms
permission reclassification › reclassifies numbered Yes/No options as permission_prompt
0.9180280000000494ms
permission reclassification › does NOT reclassify regular options as permission
0.6186480000000074ms
permission reclassification › does NOT reclassify cursor-selection UI with "Enter to confirm" as permission
0.6674189999999953ms
permission reclassification › detects cursor-selection UI even when ANSI stripping removes spaces
0.7076250000000073ms
permission reclassification › includes navigable and cursorIndex in reclassified permission_prompt
2.421502999999916ms
permission reclassification › infers shortcuts for reclassified permission options
0.809976000000006ms
permission reclassification › infers shortcut "a" for "don't ask again" labels
0.6758650000000443ms
permission reclassification › infers shortcut "a" for "allow all sessions" labels
0.5967769999999746ms
ghost text suggestion › detects SGR 90 (bright black) ghost text on prompt line
1.202861999999982ms
ghost text suggestion › detects ghost text via Strategy 1 (Try "..." in clean text)
0.5667409999999791ms
ghost text suggestion › unwraps Try "..." wrapper with smart quotes
0.6093200000000252ms
ghost text suggestion › unwraps Try "..." wrapper with straight quotes
0.5045350000000326ms
ghost text suggestion › detects ghost text on first idle (❯ and suggestion in same chunk)
0.5597470000000158ms
ghost text suggestion › clears suggestion on spinner start
0.975016000000096ms
ghost text suggestion › debounces rapid updates
1.0297369999999546ms
ghost text suggestion › ignores dim (SGR 2) text without ❯ prompt context
0.7545120000000907ms
ghost text suggestion › detects dim (SGR 2) ghost text on ❯ prompt line
0.7264999999999873ms
ghost text suggestion › detects ghost text with cursor-forward spacing (Strategy 1)
0.6965340000000424ms
ghost text suggestion › filters UI chrome fragments
1.1692789999999604ms
ghost text suggestion › filters box-drawing lines as UI chrome
0.8475269999999ms
ghost text suggestion › filters file paths (false positive from screen redraws)
0.9207430000000159ms
ghost text suggestion › detects 256-color gray ghost text
0.7684689999999819ms
ghost text suggestion › handles multi-segment ghost text on prompt line
0.7308380000000625ms
ghost text suggestion › ignores ghost text on non-prompt lines
0.648394000000053ms
ghost text suggestion › detects 24-bit RGB gray ghost text
0.71058000000005ms
ghost text suggestion › ignores 24-bit RGB non-gray colors (e.g. blue prompt char)
0.6012359999999717ms
ghost text suggestion › filters out short gray text like prompt char itself
0.6470910000000458ms
ghost text suggestion › suppresses ghost text detection during spinner (processing)
0.6860040000000254ms
ghost text suggestion › rejects digit+operator fragments like diff markers "96 +"
0.6136689999999589ms
ghost text UI chrome filtering › filters out "Tip:" segments on prompt line
0.7094280000000026ms
ghost text UI chrome filtering › filters out "(ctrl+...)" shortcut hints on prompt line
0.6392060000000583ms
ghost text UI chrome filtering › filters concatenated UI chrome even in scheduleSuggestion
0.716331000000082ms
ghost text UI chrome filtering › keeps ghost text when UI chrome is also present on the line
0.7771039999998948ms
filters out extended thinking indicators › rejects "(thought for 1s)" as ghost text via isUiChrome
0.7448040000000447ms
filters out extended thinking indicators › rejects "(thought for 1s)>" via scheduleSuggestion
0.7152280000000246ms
filters out extended thinking indicators › rejects longer thinking durations like "(thought for 15s)"
0.6951309999999467ms
filters out extended thinking indicators › rejects "(thought for 1m 30s)" multipart duration
0.7057709999999133ms
filters out extended thinking indicators › rejects "✻ Cooked for 1m 26s" sparkle indicator
0.6832190000000082ms
filters out extended thinking indicators › rejects "✻ Cooked for 5s" short duration variant
0.6707159999999703ms
filters out extended thinking indicators › rejects "Cooked for 10s" without sparkle (cross-chunk)
0.8093450000000075ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 2 (dim)
0.7389630000000125ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 90 (bright black)
0.7113910000000487ms
parenthesized placeholder filtering › rejects "(loading...)"
0.7161710000000312ms
parenthesized placeholder filtering › rejects "(empty)"
0.6632419999999684ms
parenthesized placeholder filtering › rejects "(waiting for response)"
0.7074750000000449ms
parenthesized placeholder filtering › allows "fix the broken (auth) module" — parens in middle
0.7838880000000472ms
parenthesized placeholder filtering › allows "(optional) refactor the code" — paren prefix with text after
0.7948269999999411ms
stacked ANSI + cross-chunk ghost text › detects ghost text with stacked ANSI escapes (gray + italic)
0.7717949999999973ms
stacked ANSI + cross-chunk ghost text › detects ghost text with combined SGR params (2;90 = dim+bright-black)
0.8461539999999559ms
stacked ANSI + cross-chunk ghost text › detects cross-chunk ghost text (❯ and gray text in separate feeds)
1.1866410000000087ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when chunk contains ⎿ output fence
0.7837870000000748ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when new chunk has \n (different line)
0.7114520000000084ms
ghost option from stale buffer › excludes stale numbered list items before actual option prompt
1.2821900000000142ms
ghost option from stale buffer › bypasses chunk size guard when ❯ cursor is present in large chunk
1.1159890000000132ms
ghost option from stale buffer › still works with scrambled TUI order after backward scan
0.6891399999999521ms
ghost option from stale buffer › excludes file path fragments from Read() tool in permission prompt
0.8130419999999958ms
option index ordering › returns options sorted by index even when TUI lines arrive out of order
0.7552839999999605ms
split ANSI sequence buffering › handles ANSI SGR codes split across chunks
0.8058489999999665ms
split ANSI sequence buffering › handles bare ESC at end of chunk
0.6938890000000129ms
split ANSI sequence buffering › does not buffer complete ANSI sequences
0.6211230000000114ms
large chunk guard for option detection › does NOT detect numbered items in large response chunks as options
0.6219939999999724ms
large chunk guard for option detection › still detects real options in small TUI chunks
0.5801360000000386ms
CUP-positioned options › parses options using CUP (\x1b[row;colH) instead of newlines
0.8153559999999516ms
CUP-positioned options › parses options using CUD (\x1b[B) for vertical movement
0.8289320000000089ms
trailing TUI chrome stripping › strips "Esc to cancel" from last option label
0.7491120000000819ms
trailing TUI chrome stripping › strips "Enter to confirm" from last option label
0.7069940000000088ms
trailing TUI chrome stripping › does NOT strip "Esc" when it appears within legitimate label text
0.666407999999933ms
CJK suggestion detection › accepts ghost text containing CJK characters
1.4917119999998931ms
CJK suggestion detection › accepts ghost text that is purely CJK (no ASCII words)
0.8124310000000605ms
AskUserQuestion with separators and descriptions › handles AskUserQuestion with separator and descriptions
1.0281850000000077ms
AskUserQuestion with separators and descriptions › handles options starting from non-zero index (buffer truncation)
0.9098930000000109ms
hierarchical CC prompt shapes › captures 5-option plan approval with long labels
1.1222709999999552ms
hierarchical CC prompt shapes › captures OpenClaw scope selection (numbered list)
2.9595199999999977ms
hierarchical CC prompt shapes › captures OpenClaw token-action step (short numbered list)
0.6513089999999693ms
permission scroll does not trigger idle (Bug 1) › scroll chunk with ❯ option text does NOT cause idle when navigable
0.7127550000000156ms
permission scroll does not trigger idle (Bug 1) › /model combined chunk: confirmation + idle prompt clears options
0.6893700000000536ms
permission scroll does not trigger idle (Bug 1) › /model separate chunks: ANSI reposition timer does not block idle
0.624960000000101ms
permission scroll does not trigger idle (Bug 1) › cursor move chunk with option text does NOT falsely trigger idle
0.6684209999999666ms
permission scroll does not trigger idle (Bug 1) › genuine idle prompt exits navigable state and emits idle
0.7169930000000022ms
TUI cursor-overwrite label correction (Bug 2) › fixes contaminated permission option label using correction line
0.8289909999999736ms
TUI cursor-overwrite label correction (Bug 2) › leaves labels unchanged when no correction line is present
0.6140589999999975ms
genuine idle detection (semantic) › "❯ \n" is genuine idle — only prompt character, no label text
0.6112040000000434ms
genuine idle detection (semantic) › "❯ Beta" is NOT idle — has label text after prompt char
0.5557400000000143ms
genuine idle detection (semantic) › "❯ A" is NOT idle — single-char label still counts
0.8309550000000172ms
genuine idle detection (semantic) › ">" also treated as idle prompt character
0.4974610000000439ms
effort level parsing › detects "High effort" selection pattern
0.49485599999991337ms
effort level parsing › detects "Medium effort" selection pattern
0.41541700000004766ms
effort level parsing › detects "Low effort" selection pattern
0.3870040000000472ms
effort level parsing › detects "with high effort" confirmation line
0.38600300000007337ms
effort level parsing › detects effort in model info line
0.6431340000000318ms
effort level parsing › caches effort level — no re-emit on same value
0.5506110000000035ms
effort level parsing › emits on effort level change
0.5543780000000424ms
effort level parsing › resets effort level on reset()
0.5368850000000975ms
effort level parsing › does not match "effort" in unrelated context
0.4896360000000186ms
effort level parsing › does not match effort inside numbered option lines
0.6370919999999387ms
effort level parsing › getter returns current effort level
0.4956579999999349ms
effort level parsing › detects "Max effort" (Opus 4.7 variant)
0.5594979999999623ms
effort level parsing › detects "xhigh effort" (Opus 4.7 variant)
0.7022550000000365ms
effort level parsing › detects "default effort" (per-model default variant)
0.529672000000005ms
effort level parsing › detects "fast effort" (Opus 4.6 variant)
0.5725719999999228ms
effort level parsing › detects effort in /model confirmation line with max
0.5467129999999543ms
codex-output-parser.test.ts
28 / 28 44ms
CodexOutputParser 28 / 28
idle detection › emits idle on ❯ prompt with source=prompt
13.063490000000002ms
idle detection › emits idle on > prompt
1.9518350000000169ms
idle detection › debounces rapid idle signals
0.961749999999995ms
spinner detection › emits spinner_start on braille spinner chars after first idle
1.6225880000000075ms
spinner detection › does not emit spinner_start before first idle
1.0596239999999852ms
spinner detection › emits spinner_stop + idle on timeout with source=timeout
1.2180210000000216ms
spinner detection › emits spinner_stop when idle prompt appears
0.7954790000000003ms
spinner detection › detects "Thinking" text as processing
0.7591010000000438ms
permission prompt detection › emits permission_prompt on Allow/Deny pattern
1.9885639999999967ms
permission prompt detection › emits permission_prompt on y/n pattern
1.0636420000000157ms
permission prompt detection › stops spinner when approval detected
0.7769339999999829ms
permission prompt detection › extracts Allow once / Always allow options
0.9684939999999642ms
tool action detection › detects Running: command pattern
4.7346749999999815ms
tool action detection › detects file operation patterns
0.8420169999999985ms
tool action detection › detects Editing file pattern
0.816929000000016ms
tool action detection › dedups repeated emits of the same (tool, args) within window
0.7277930000000197ms
tool action detection › emits a different command immediately
0.7138170000000059ms
tool action detection › re-emits the same command after the dedup window elapses
0.7127550000000156ms
tool action detection › re-emits the same command after a turn boundary (idle resets dedup)
0.9730820000000335ms
model info detection › detects gpt model name
0.7253489999999942ms
model info detection › detects o-series model
0.6427339999999617ms
model info detection › does not re-emit same model
0.5954749999999649ms
project name detection › detects working directory
0.9734829999999874ms
project name detection › detects project from path
0.7529099999999858ms
project name detection › only detects project name once
0.6592239999999947ms
buffer management › truncates buffer at 8192 chars
0.6361009999999965ms
buffer management › handles incomplete ANSI sequences
0.8702389999999696ms
getProjectName › returns null when no project detected
0.5790339999999787ms
cursor-sync.test.ts
15 / 15 41ms
Cursor Synchronization 15 / 15
terminal keyboard cursor tracking › emits cursor_update when full option redraw arrives with ❯ at new position
19.20155299999999ms
terminal keyboard cursor tracking › triggers buffer re-parse on small non-❯ chunk during navigable state
2.922542999999962ms
terminal keyboard cursor tracking › does not emit cursor_update when cursor position unchanged
3.244374999999991ms
genuine idle distinction › treats "❯ \n" as genuine idle (clears navigable state)
1.2685950000000048ms
genuine idle distinction › does NOT treat "❯ Beta" as idle (cursor on option label)
1.665918999999974ms
genuine idle distinction › does NOT treat "❯ Allow once" as idle (permission cursor move)
1.9187929999999938ms
cursor authority in StateMachine › accepts optimistic update immediately
2.3524949999999762ms
cursor authority in StateMachine › suppresses stale PTY value within 200ms of optimistic update
0.8462440000000129ms
cursor authority in StateMachine › accepts PTY value after 200ms grace period
0.795599999999979ms
cursor authority in StateMachine › always accepts PTY when no recent optimistic update
0.7766950000000179ms
cursor authority in StateMachine › resets authority on state transition out of AWAITING
1.1389520000000175ms
cursor authority in StateMachine › default source parameter is pty
0.6582329999999956ms
select_option proportional delay › delay scales with step count
0.7787490000000048ms
option re-emission with cursorIndex › AWAITING_OPTION update triggers state_changed with options
1.0932059999999524ms
option re-emission with cursorIndex › updateCursorIndex emits snapshot with new cursor value
0.8689269999999851ms
State Machine & Adapters PASS
에이전트의 상태 전이와 타입별 명령 라우팅이 정확한가?
178 passed 0 failed 3 files 186ms
state-machine.test.ts
60 / 60 61ms
StateMachine 60 / 60
basic transitions › starts in DISCONNECTED
5.829092000000003ms
basic transitions › SessionStart → IDLE
1.3975960000000214ms
basic transitions › UserPromptSubmit → PROCESSING
1.5966090000000008ms
basic transitions › Stop → IDLE from PROCESSING
0.7779459999999858ms
basic transitions › SessionEnd → DISCONNECTED from any state
0.576139000000012ms
permission flow › permission_prompt → AWAITING_PERMISSION
2.9206869999999867ms
permission flow › user respond → PROCESSING from AWAITING_PERMISSION
0.8053370000000086ms
option flow › option_prompt → AWAITING_OPTION
0.7655730000000176ms
option flow › select_option → PROCESSING from AWAITING_OPTION
0.7271910000000048ms
option flow › option_prompt carries the question into the snapshot
0.4807400000000257ms
diff flow › diff_prompt → AWAITING_DIFF
0.6636520000000132ms
diff flow › respond → PROCESSING from AWAITING_DIFF
0.8832530000000247ms
interrupt › interrupt → IDLE from PROCESSING
0.46885700000001407ms
interrupt › interrupt → IDLE from AWAITING_PERMISSION
0.5337989999999877ms
strict transitions › allows IDLE → AWAITING_PERMISSION (prompt without spinner)
0.6440860000000157ms
strict transitions › blocks invalid transition: DISCONNECTED → PROCESSING
0.5487779999999702ms
strict transitions › allows wildcard session_end from any state
0.6580219999999599ms
stuck timeout › PROCESSING for >5min → auto-recovery to IDLE
1.178184999999985ms
stuck timeout › AWAITING_PERMISSION survives the 5min PROCESSING window but recovers after the 10min backstop
0.6288069999999948ms
stuck timeout › AWAITING_OPTION recovers after the 10min backstop
1.0429919999999697ms
stuck timeout › AWAITING_DIFF recovers after the 10min backstop
1.0077059999999847ms
stuck timeout › AWAITING backstop resets when the user responds (no false recovery)
1.0128260000000182ms
stuck timeout › AWAITING backstop re-arms on PTY activity (silence-based, not a hard cap from entry)
1.2033220000000142ms
stuck timeout › timer resets on state change before timeout
5.3649919999999724ms
stuck timeout › no timeout in IDLE state
0.5820500000000379ms
parser events › spinner_start → PROCESSING from IDLE
0.6103420000000028ms
parser events › spinner_stop → IDLE from PROCESSING
0.6757749999999874ms
parser events › idle → IDLE from PROCESSING
0.6659270000000106ms
parser events › mode_change updates permission mode
0.9136400000000435ms
snapshot › emits state_changed on transitions
0.6746530000000348ms
snapshot › includes tool info in snapshot
0.7859609999999861ms
snapshot › clears tool info on PostToolUse
0.8118000000000052ms
snapshot › includes project name and model
0.7497539999999958ms
billingType detection › defaults to unknown
0.5780020000000263ms
billingType detection › detects subscription from "Claude Max" plan
0.6873070000000325ms
billingType detection › detects subscription from "Max" (case-insensitive)
0.6461390000000051ms
billingType detection › detects api from "api.anthropic.com"
0.6313719999999989ms
billingType detection › detects api (case-insensitive)
0.6776389999999992ms
billingType detection › stays unknown for unrecognized plan
0.752397999999971ms
billingType detection › stays unknown when plan is absent
1.4331530000000043ms
billingType detection › persists billingType across subsequent model_info without plan
0.8303840000000378ms
billingType detection › emits state_changed when billingType is set
0.7210299999999847ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_OPTION to PROCESSING
0.7366489999999999ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_PERMISSION to PROCESSING
0.6814160000000129ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_DIFF to PROCESSING
0.7507659999999987ms
spinner_start recovery from awaiting states › clears options and navigable state on spinner_start from AWAITING_OPTION
2.2727740000000267ms
spinner_start recovery from awaiting states › stores navigable and cursorIndex from permission_prompt
0.7840380000000096ms
spinner_start recovery from awaiting states › cursor index tracking via updateCursorIndex
0.7953290000000379ms
cursor authority (optimistic vs pty) › optimistic source updates cursor immediately
0.6787310000000275ms
cursor authority (optimistic vs pty) › suppresses stale PTY within 200ms of optimistic
0.7329929999999649ms
cursor authority (optimistic vs pty) › accepts PTY after 200ms grace period
0.5382879999999659ms
cursor authority (optimistic vs pty) › emits state_changed on optimistic update
0.6221320000000219ms
cursor authority (optimistic vs pty) › does NOT emit state_changed when stale PTY is suppressed
0.5729119999999739ms
codex_* hook events › codex_session_start → IDLE
0.5648780000000215ms
codex_* hook events › codex_user_prompt_submit → PROCESSING
0.640197999999998ms
codex_* hook events › codex_tool_start sets currentTool from tool_name
0.701564000000019ms
codex_* hook events › codex_tool_end clears currentTool
0.6736200000000281ms
codex_* hook events › codex_stop → IDLE from PROCESSING
0.7268300000000067ms
codex_* hook events › codex_turn_complete is a snapshot-emit no-op for state
0.6495859999999993ms
codex_* hook events › full codex lifecycle preserves state transitions
0.8167290000000094ms
adapter.test.ts
93 / 93 95ms
createAdapter factory 5 / 5
creates ClaudeCodeAdapter for "claude-code"
3.9489920000000893ms
creates OpenClawAdapter for "openclaw"
1.3152529999999842ms
passes gatewayUrl to OpenClawAdapter
0.3082569999999123ms
creates CodexCliAdapter for "codex-cli"
0.7185249999999996ms
throws for unknown agent type
1.2612010000000282ms
ClaudeCodeAdapter 17 / 17
capabilities › reports all Claude Code capabilities as true
0.8743369999999686ms
handleCommand routing › handles respond → returns true
0.5667209999999159ms
handleCommand routing › handles switch_mode → returns true
0.48241299999995135ms
handleCommand routing › handles interrupt → returns true
0.6032689999999548ms
handleCommand routing › handles escape → returns true
0.3686499999998887ms
handleCommand routing › defers select_option to bridge → returns false
0.2737720000000081ms
handleCommand routing › defers navigate_option to bridge → returns false
0.30847799999992276ms
handleCommand routing › defers send_prompt to bridge → returns false
0.2749450000001161ms
handleCommand routing › defers voice to bridge → returns false
0.29513199999996687ms
handleCommand routing › defers query_usage to bridge → returns false
0.2757360000000517ms
switch_mode debounce › debounces rapid switch_mode calls (< 100ms apart)
0.8212069999999585ms
lifecycle › isAlive returns false before start
0.34979500000008557ms
lifecycle › getTtyPath returns undefined before start
0.2927879999999732ms
lifecycle › getProjectName returns null before start
0.29043400000000474ms
lifecycle › getHttpServer returns an object
0.34504599999991115ms
onRawData callback › can register callback without error
0.40366500000004635ms
onDiag handler › can register handler without error
0.5706079999999929ms
OpenClawAdapter 17 / 17
capabilities › reports OpenClaw capabilities correctly
0.7361280000000079ms
handleCommand routing › handles respond → returns true (RPC)
0.4421279999999115ms
handleCommand routing › handles select_option → returns true (RPC)
0.2294400000000678ms
handleCommand routing › handles navigate_option → returns true (no-op)
0.24164300000006733ms
handleCommand routing › handles send_prompt → returns false without session key
0.29438100000015766ms
handleCommand routing › handles interrupt → returns true (RPC)
0.20959300000004077ms
handleCommand routing › handles escape → returns true (RPC)
0.18435500000009597ms
handleCommand routing › defers switch_mode → returns false (not supported)
0.23270499999989624ms
handleCommand routing › defers voice to bridge → returns false
0.29393099999992955ms
handleCommand routing › defers query_usage to bridge → returns false
0.23606199999994715ms
lifecycle › isAlive returns false before start
0.23627200000009907ms
lifecycle › getTtyPath returns undefined (no PTY)
0.32324500000004264ms
lifecycle › getProjectName returns null before start
0.27315199999998185ms
lifecycle › getHttpServer returns an object
0.22483099999999467ms
lifecycle › attachTerminal is a no-op
0.4406249999999545ms
onRawData callback › can register callback without error
0.30905800000005ms
onDiag handler › can register handler without error
0.30026199999997516ms
OpenClawAdapter gateway protocol 13 / 13
sends connect request with correct format on connect.challenge
4.21902799999998ms
becomes alive after hello-ok response
6.887422000000015ms
emits spinner_start on chat delta event
1.1744679999999335ms
emits idle on chat final event
5.199202999999898ms
emits idle on chat aborted event
0.8715809999998783ms
emits idle on chat error event
0.7224630000000616ms
emits permission_prompt on exec.approval.requested
0.8222190000001319ms
sends exec.approval.resolve on respond after approval request
0.951441000000159ms
sends exec.approval.resolve with deny on respond "n"
0.6776179999999385ms
sends chat.send on send_prompt with active session
1.2571230000000924ms
sends chat.abort on interrupt with active session and runId
1.0257699999999659ms
emits SessionEnd on shutdown event
0.6666249999998399ms
clears pendingApprovalId on exec.approval.resolved
0.6744730000000345ms
CodexCliAdapter 16 / 16
capabilities › reports Codex CLI capabilities correctly
0.9199320000000171ms
handleCommand routing › handles respond → returns true
0.4374480000001313ms
handleCommand routing › handles interrupt → returns true
0.3973329999998896ms
handleCommand routing › handles escape → returns true
0.39314600000011524ms
handleCommand routing › does not handle switch_mode → returns false
0.3793399999999565ms
handleCommand routing › defers select_option to bridge → returns false
0.43558500000017375ms
handleCommand routing › defers navigate_option to bridge → returns false
0.46741500000007363ms
handleCommand routing › defers send_prompt to bridge → returns false
0.4391920000000482ms
handleCommand routing › defers voice to bridge → returns false
0.38110299999993913ms
handleCommand routing › defers query_usage to bridge → returns false
0.438961000000063ms
lifecycle › isAlive returns false before start
0.3641020000000026ms
lifecycle › getTtyPath returns undefined before start
0.3469300000001567ms
lifecycle › getProjectName returns null before start
0.4297839999999269ms
lifecycle › getHttpServer returns an object
0.3444250000000011ms
onRawData callback › can register callback without error
1.076323999999886ms
onDiag handler › can register handler without error
0.5742850000001454ms
CodexCliAdapter start lifecycle 2 / 2
emits SessionStart and connected on start
5.601034000000027ms
feeds PTY data to output parser and emits activity
3.5358819999999014ms
MonitorAdapter 18 / 18
capabilities › reports monitor capabilities correctly
1.0524809999999434ms
handleCommand routing › rejects respond (no PTY)
1.6306990000000496ms
handleCommand routing › rejects interrupt (no PTY)
0.4011310000000776ms
handleCommand routing › rejects escape (no PTY)
0.3740299999999479ms
handleCommand routing › rejects switch_mode (no PTY)
0.3889279999998507ms
handleCommand routing › rejects select_option (no PTY)
0.3812829999999394ms
handleCommand routing › rejects send_prompt (no PTY)
0.3744610000001103ms
handleCommand routing › defers voice to bridge
0.4380100000000766ms
handleCommand routing › defers query_usage to bridge
0.40079100000002654ms
lifecycle › isAlive always returns true
0.29942099999993843ms
lifecycle › getTtyPath returns undefined (no PTY)
0.27915200000006735ms
lifecycle › getProjectName returns null
0.32819400000016685ms
lifecycle › getHttpServer returns an object
0.2783809999998539ms
lifecycle › writeInput is a no-op (no PTY)
0.45864800000003925ms
lifecycle › attachTerminal is a no-op
0.46212500000001455ms
lifecycle › onRawData is a no-op
0.5936910000000353ms
start and event emission › emits connected event on start
0.7073139999999967ms
start and event emission › exposes hook server for external wiring
0.5225280000001931ms
ClaudeCodeAdapter start lifecycle 5 / 5
emits SessionStart and connected on start
1.92254899999989ms
uses claude as default command
1.5520550000001094ms
feeds PTY data to output parser and emits activity
6.09364000000005ms
emits SessionEnd and disconnected on PTY exit
10.499343999999837ms
registers rawData callback without error
1.3038810000000467ms
protocol-contract.test.ts
25 / 25 30ms
Protocol Contract — StateUpdateEvent 5 / 5
minimal state_update has required fields
5.48219499999999ms
full state_update has all optional fields as correct types
1.5626359999999977ms
state_update serializes to valid JSON
0.35657699999998727ms
state enum values are lowercase strings
0.6303210000000092ms
promptType values match known set
0.3745710000000031ms
Protocol Contract — UsageEvent 3 / 3
has all required numeric fields
0.6307610000000068ms
rate limit fields are present when available
1.5380400000000236ms
tokenStatus matches known values
0.22547200000002476ms
Protocol Contract — SessionsListEvent 2 / 2
sessions have required fields
0.5113569999999754ms
agentType is optional string
0.3025959999999941ms
Protocol Contract — ButtonStateEvent 1 / 1
buttons have required fields
0.9049850000000106ms
Protocol Contract — EncoderStateEvent 1 / 1
encoders have required fields
0.9675020000000245ms
Protocol Contract — TimelineEventMsg 1 / 1
entry has required fields
0.42699900000002344ms
Protocol Contract — ConnectionEvent 1 / 1
has required fields
0.3467489999999884ms
Protocol Contract — DisplayStateEvent 1 / 1
has boolean displayOn
0.3829870000000142ms
Protocol Contract — PluginCommand shapes 6 / 6
respond command has value
0.29253800000003594ms
select_option has numeric index
0.2667690000000107ms
navigate_option has direction
0.312184000000002ms
send_prompt has text
0.27730900000000247ms
utility command has action
0.2794630000000211ms
clear_session_focus is fieldless
1.2025519999999688ms
Protocol Contract — BridgeEvent discriminated union 2 / 2
all event types in union have type field
2.9493420000000015ms
SERIAL_FORWARDED_EVENTS covers expected types
8.067498ms
Protocol Contract — Backward Compatibility 2 / 2
state_update can be parsed with only required fields (old client)
0.30240600000001905ms
usage_update required fields are sufficient for display
0.20544499999999744ms
Timeline Pipeline PASS
이벤트 타임라인의 저장, 중복 제거, 세션 간 릴레이가 올바른가?
111 passed 0 failed 3 files 1.3s
timeline.test.ts
64 / 64 34ms
cleanDetailText 12 / 12
returns empty/falsy input unchanged
4.384229000000005ms
strips markdown bold
0.648744000000022ms
strips markdown headings
0.5043140000000221ms
strips code fences
0.2670699999999897ms
strips inline backticks
0.3314809999999966ms
strips markdown links
0.2908040000000369ms
strips blockquotes
0.24209399999995185ms
strips list markers
0.2626819999999839ms
collapses multiple blank lines
0.2832700000000159ms
filters system JSON blobs (connectionId)
0.31190399999997ms
extracts error from JSON blob
0.2506089999999972ms
compacts other JSON
0.35880199999996876ms
cleanRawText 2 / 2
strips bold, headings, links, backticks
0.3194979999999532ms
returns empty/falsy unchanged
0.23351800000000367ms
cleanNopMarkers 3 / 3
removes NOP markers
0.4903680000000463ms
collapses resulting blank lines
0.302216000000044ms
returns empty/falsy unchanged
0.2174269999999865ms
normalizeTimelineEntryForStorage 9 / 9
summarizes OpenClaw cron model_call prompts instead of storing shell-like instructions
2.5020849999999655ms
drops low-signal OpenClaw placeholder tool rows
0.48179199999998445ms
keeps OpenClaw placeholder tool rows when detail carries input or output
1.2048350000000028ms
drops OpenClaw NO_REPLY polling responses from the user-facing timeline
0.6168059999999969ms
drops OpenClaw automated polling chat starts from the user-facing timeline
0.48898500000001377ms
drops Claude task notification chat starts from the user-facing timeline
0.2927380000000426ms
keeps OpenClaw LINE userId notification failures visible
0.5044639999999845ms
drops Codex command tool rows even when detail carries input
0.33146099999999024ms
extracts readable labels from cron headers
0.39611200000001645ms
isAssistantProgressUpdate 2 / 2
detects non-terminal build/status updates
0.7330319999999801ms
does not classify final completion reports as progress
0.7966119999999819ms
extractSemanticCore 4 / 4
strips duration suffix for chat_end
0.33128099999998994ms
keeps full text for chat_end without separator
0.2590450000000146ms
keeps full text for non-chat_end types
0.30576299999995626ms
trims whitespace
0.2687230000000227ms
isRepetitiveEntry 11 / 11
detects exact duplicate chat_end entries
0.7035470000000146ms
detects keyword-similar entries
0.7608749999999986ms
returns -1 for non-matching entries
0.4317689999999743ms
ignores entries outside window
0.24182299999995394ms
only applies to chat_end, chat_start, and error types
0.29691600000001017ms
dedupes repeated error entries within 1h window
0.32437699999996994ms
matches chat_start entries
0.31136299999997163ms
dedupes automated entries regardless of content
0.26190000000002556ms
does not dedup automated vs non-automated
0.27951300000000856ms
uses 8h window for automated entries
0.20223799999996572ms
expires automated dedup after 8h
0.15094299999998384ms
parseLogLine 21 / 21
returns null for null/undefined/non-object
0.6423130000000015ms
returns null for empty message
0.20644699999996874ms
returns null for model start/complete (suppressed)
0.3213519999999903ms
parses memory/recall (legacy structured)
0.47872699999999213ms
parses tool execution (legacy structured)
0.541134999999997ms
filters gateway/ws subsystem
0.23947799999996278ms
filters infrastructure noise
0.46308700000003ms
filters channel infra reconnect noise
1.0175160000000005ms
filters connection status JSON blobs
0.6095820000000458ms
filters transient fetch timeouts
0.2897619999999961ms
filters edit mismatch errors (agent retries)
0.14888899999999694ms
filters failover cascade noise
0.17206199999998262ms
parses genuine errors
0.6549559999999701ms
parses error from message pattern (not level)
0.5971180000000231ms
filters model/inference patterns (suppressed)
0.3830669999999827ms
does not synthesize memory_recall from message text alone
0.28638599999999315ms
does not synthesize tool_exec from message text alone
0.2031109999999785ms
parses ISO timestamp correctly via error pattern
0.3093289999999911ms
falls back to Date.now() for invalid timestamp on error message
0.33232199999997647ms
truncates long tool raw to 500 chars
0.2812059999999974ms
filters whatsapp noise from channel infra subsystem
0.33693099999999276ms
timeline-integration.test.ts
42 / 42 39ms
BridgeTimelineStore 18 / 18
adds and retrieves entries
5.2214440000000195ms
filters history by timestamp
1.4058610000000158ms
returns timeline history sorted by timestamp after late upserts
1.3363320000000272ms
returns per-session history sorted by timestamp after late upserts
0.5589429999999993ms
normalizes OpenClaw cron prompt dumps before storing history
1.626814999999965ms
drops low-signal OpenClaw placeholder tool rows before broadcast/history
0.5253240000000119ms
drops Codex tool_exec rows before broadcast/history
0.36928100000000086ms
loads persisted timeline history without replaying Codex tool_exec firehose
1.0725510000000327ms
calls listeners on new entries
0.41994600000003857ms
upsert updates existing entry with same ts+type
0.5306729999999789ms
upsert keeps timeline attribution fields
0.4671950000000038ms
upsert adds new entry when no match exists
0.3145289999999932ms
task_end updates in place by taskId and carries judge fields
0.8940629999999601ms
updateEntryStatus updates approval status
0.3345059999999762ms
getLastEntry returns most recent of given type
0.5950739999999541ms
getLastEntry returns null when type not found
0.288880000000006ms
removeListener stops notifications
0.47652199999998857ms
enforces MAX_ENTRIES (200) with FIFO
10.787893999999994ms
deduplicateEntry pipeline 5 / 5
exact duplicate within 8s → skip
0.2961440000000266ms
same type, different content → add
0.29947100000003957ms
different type, same raw → add
0.3132969999999773ms
chat_response identical raw 6s apart → skip (PTY/Stop race)
0.26122900000001437ms
chat_response near-duplicate beyond 8s → repetitive merge
0.4788459999999759ms
BridgeTimelineStore.setAttributor — history replay attribution 10 / 10
addEntry passes the entry through the attributor before storage
0.4749090000000251ms
caller-set fields take precedence over attributor (idempotent)
0.34300199999995584ms
listener (broadcast) receives the same attributed entry
0.7086070000000291ms
upsertEntry propagates summaryKind to existing entry (LLM enrichment regression)
0.4404540000000452ms
upsertEntry routes through the attributor too
0.43425300000001243ms
late upsert preserves the original entry attribution after task rotation (regression)
1.2001269999999522ms
merge path (repetitive dedup) does not re-attribute after task rotation
0.393807000000038ms
upsert with no existing match falls through to attributor (insert path)
0.19811099999998305ms
caller-set taskId on upsert overrides existing entry attribution
0.25930499999998347ms
history replay returns entries with taskId/runId set (regression)
0.7239759999999933ms
Stop hook + PTY fallback double-emit (regression) 1 / 1
identical chat_response from two emit paths is collapsed by store
0.4401940000000195ms
Timeline → WS broadcast pipeline 4 / 4
store entries trigger broadcast via listener
0.34503599999999324ms
upsert entries broadcast with upsert flag
0.3013140000000476ms
exact duplicate within 5s is skipped by store
1.6250220000000013ms
different content within 5s is NOT deduped
0.24932699999999386ms
TimelineEntry types 4 / 4
common entry types have expected shape
0.7542520000000081ms
entries with status field
0.29713600000002316ms
entries with detail field
0.266337999999962ms
entries with automated flag
0.2353909999999928ms
session-timeline-relay.test.ts
5 / 5 1.2s
SessionTimelineRelay 5 / 5
connects to sibling and relays timeline_event
317.379307ms
relays timeline_history entries
302.2975419999999ms
removes subscription when session disappears
201.69084499999997ms
ignores daemon sessions
0.42827199999987897ms
handles upsert timeline events
402.7020520000001ms
Daemon & Infrastructure PASS
데몬 싱글톤, 세션 레지스트리, 사용량 릴레이가 안정적인가?
72 passed 0 failed 4 files 2.5s
daemon-lifecycle.test.ts
19 / 19 55ms
daemon.json lifecycle 6 / 6
writeDaemonInfo creates daemon.json with correct content
7.1640030000000365ms
readDaemonInfo returns info when PID is alive
1.5419180000000097ms
readDaemonInfo returns null and removes file when PID is dead
1.1784860000000208ms
readDaemonInfo returns null when file does not exist
0.6206020000000194ms
removeDaemonInfo deletes daemon.json
0.9579129999999623ms
removeDaemonInfo is safe when file already gone
1.760505999999964ms
session registry with real files 7 / 7
register creates sessions.json
2.5018139999999676ms
register replaces existing entry with same id
1.70195700000005ms
deregister removes session by id
1.8557950000000005ms
listActive prunes dead PIDs
1.6497789999999668ms
multiple sessions coexist
1.511320000000012ms
findExistingDaemon returns daemon session
1.007316000000003ms
findExistingDaemon returns null when no daemon
0.6175359999999728ms
findDaemonPort 4 / 4
returns port from daemon.json (priority 1)
0.6639330000000427ms
falls back to sessions.json daemon entry
0.6839710000000423ms
returns null when no daemon anywhere
0.4056889999999953ms
daemon.json takes precedence over sessions.json
0.7739700000000198ms
probeDaemonHealth 2 / 2
returns health JSON from running server
24.35967099999999ms
returns null for closed port
2.7813979999999674ms
session-registry.test.ts
21 / 21 1.3s
Session Registry Logic 21 / 21
pruneDeadSessions › keeps alive sessions
5.652506999999986ms
pruneDeadSessions › removes sessions with dead PIDs
0.8049780000000055ms
pruneDeadSessions › keeps old sessions if PID is alive
0.4555329999999742ms
pruneDeadSessions › handles mix of alive and dead sessions
1.7971340000000282ms
port allocation logic › returns base port when no ports are used
0.6456890000000044ms
port allocation logic › returns next port when base is taken
0.3154209999999864ms
port allocation logic › skips used ports
0.2687830000000133ms
port allocation logic › finds gaps in used ports
0.31230500000000916ms
port allocation logic › throws when all ports are taken
1.3504890000000103ms
atomic write › write-then-rename produces valid JSON
3.4200229999999863ms
shouldConcedePortToOccupant (startup-race hardening) › does not concede to a non-daemon occupant (session bridge)
0.2963550000000055ms
shouldConcedePortToOccupant (startup-race hardening) › does not concede when the probe failed (null occupant)
0.19713899999999285ms
shouldConcedePortToOccupant (startup-race hardening) › concedes to a daemon backed by a live, distinct PID
0.20743799999999624ms
shouldConcedePortToOccupant (startup-race hardening) › does NOT concede to a forged/stale daemon whose PID is dead
0.3001120000000128ms
shouldConcedePortToOccupant (startup-race hardening) › does NOT concede when the reported PID is our own
0.20443299999999454ms
shouldConcedePortToOccupant (startup-race hardening) › trusts the mode when no PID is reported (e.g. Swift App Store daemon)
0.19608699999997725ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › finds a Swift daemon sitting on a fallback port inside the window
27.574039ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › ignores non-daemon occupants (session bridges) and skipped ports
5.273994999999957ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › returns empty when the window is quiet
2.0684830000000147ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForDaemonExit resolves true once /health stops answering
503.85679200000004ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForDaemonExit resolves false when the daemon never leaves
756.342965ms
usage-relay.test.ts
12 / 12 635ms
Usage relay — HTTP (Tier 1) 3 / 3
fetches usage from sibling GET /usage
71.547485ms
returns null usage when sibling has no data
8.736437999999964ms
rejects stale data (>5 min old)
7.796868000000018ms
Usage relay — WebSocket (Tier 2) 2 / 2
receives usage_update from sibling WS on connect
261.468849ms
does not send usage_update when sibling has no data
256.49497599999995ms
HookServer GET /usage (relay source) 2 / 2
returns cached usage via onApiUsage getter
8.54432799999995ms
returns fresh usage after update
8.670524999999998ms
429 prevention — relay-first strategy 2 / 2
sibling with data prevents direct API call
3.969571999999971ms
multiple siblings — first with data wins
6.0385170000001835ms
ApiUsageData shape 3 / 3
has all required fields
0.5616210000000592ms
serializes to valid JSON and back
0.4257669999999507ms
handles null optional fields
0.30365899999992507ms
bridge-core.test.ts
20 / 20 514ms
BridgeCore Orchestration 20 / 20
buildStateEvent › builds state_update with IDLE state
22.909065000000055ms
buildStateEvent › includes cached ollamaStatus and gatewayAvailable
2.7430460000000494ms
buildStateEvent › computes promptType for permission options
1.53607599999998ms
buildStateEvent › computes promptType yes_no_always for 3+ permission options
0.6995699999999943ms
usage management › updateApiUsage caches and broadcasts
25.96246199999996ms
usage management › buildUsage includes API usage data
1.3591250000000628ms
usage management › buildUsage works without API data
1.0608660000000327ms
usage management › inferredBillingType propagates to StateMachine
0.9190410000001066ms
sendInitialState › sends state_update, usage_update, connection, display_state on connect
8.850100999999995ms
sendInitialState › includes timeline_history when entries exist
5.531656999999996ms
sendInitialState › caps initial timeline_history below the ESP32 WebSocket frame limit
11.180663999999979ms
state change broadcast › state_changed emits to WS clients when wired by caller
6.492417000000046ms
wireTimeline › timeline entries broadcast as timeline_event
54.59940199999994ms
hasClients guard › wsServer.getClientCount reflects connected clients
254.161785ms
hasClients guard › external client count provider extends hasClients
1.0312509999999975ms
voice assistant state › updateVoiceAssistantState caches and triggers state broadcast
54.16994399999999ms
voice assistant state › disabled voice assistant state is not included in event
1.1810409999999365ms
session registry › registerSession writes to sessions.json
3.221341999999936ms
session registry › deregisterSession removes from sessions.json
1.786654999999996ms
broadcast coordination › broadcast sends to WS and SSE callback
53.40590699999996ms
Integration Tests PASS
전체 파이프라인이 실제 서버 환경에서 동작하는가?
33 passed 0 failed 2 files 1.1s
server-integration.test.ts
17 / 17 771ms
Server Integration 17 / 17
SessionStart hook → IDLE state broadcast
130.176854ms
PreToolUse responds 200 with an EMPTY body (managed sessions must not gate)
30.15495199999998ms
non-PreToolUse hooks still ack with { received: true }
17.780493000000092ms
full session lifecycle: SessionStart → UserPromptSubmit → Stop
21.621113000000037ms
PreToolUse → PostToolUse cycle broadcasts tool info
41.19046500000002ms
SessionEnd → DISCONNECTED
21.751285999999936ms
GET /health returns valid JSON
20.59588599999995ms
GET /usage returns data when getter is set
6.416544000000044ms
GET /usage returns null when no getter
7.489032999999949ms
GET /devices returns empty when no getter
7.3259369999999535ms
POST to unknown route returns 404
5.904525000000035ms
hook endpoint responds immediately
6.774805000000015ms
SSE client receives state_update events
72.42593900000008ms
broadcasts to multiple WS clients
8.938346000000024ms
WS command from client triggers callback
105.44953499999997ms
rapid hook events do not corrupt state
247.8061110000001ms
token counts accumulate through hook events
18.83591300000012ms
tier3-integration.test.ts
16 / 16 333ms
mDNS crash recovery 3 / 3
invalidateMdnsInstance does not throw when no instance exists
9.593951000000004ms
isNonFatalMdnsError matches recoverable mDNS multicast failures
0.9048050000000103ms
isNonFatalMdnsError does NOT match unrelated fatal errors
0.47325499999999465ms
Display sleep/wake broadcast 7 / 7
DisplayMonitor initial state is ON
0.44911100000001625ms
parses macOS lock/session presence from ioreg output
2.1111930000000143ms
treats an absent ScreenIsLocked key as UNLOCKED when IOConsoleUsers is visible
0.5270269999999755ms
display_state event has correct shape
0.35763900000000604ms
display_state broadcasts to WS clients
85.94162ms
display_state broadcasts to multiple clients
61.0363440000001ms
SSE also receives display_state
122.70486900000003ms
Voice transcription endpoint 4 / 4
returns 503 when no voice manager is set
20.110996ms
returns 400 for empty audio data
7.822126000000026ms
returns transcription from voice manager
7.896325000000047ms
returns 500 when voice manager throws
7.084855999999945ms
WsServer broadcast hooks (serial relay) 2 / 2
onBroadcast hook receives all broadcast events
2.209206999999992ms
broadcast hook errors do not crash server
1.5854879999999412ms
Stream Deck Plugin UI PASS
플러그인의 연결 관리, 옵션 레이아웃, 렌더링이 정확한가?
135 passed 0 failed 5 files 1.8s
connection-manager.test.ts
16 / 16 18ms
ConnectionManager 16 / 16
starts disconnected
4.862324000000001ms
start() begins bridge connection to daemon
2.048144999999977ms
start() installs a port provider so daemon.json is re-read every attempt
0.48953699999998435ms
emits connected when bridge connects
2.0612600000000043ms
emits disconnected when bridge disconnects
0.5629940000000033ms
forwards state_update from bridge
1.262755000000027ms
send() delegates to bridge
2.037534999999991ms
send() drops command when not connected
0.4251759999999649ms
getBridgePort returns bridge port
0.33288299999998117ms
getConnectionSnapshot exposes connection and discovery state
0.5372259999999756ms
retryNow probes daemon discovery and reconnects immediately when disconnected
0.6649749999999699ms
switchToOpenClaw() › sends switch_agent command to bridge
0.8266080000000215ms
switchToClaude() › sends switch_agent command to bridge
0.5752270000000408ms
isGatewayAvailable() › returns false by default
0.3521790000000351ms
isGatewayAvailable() › returns true when bridge reports gateway available
0.35123799999996663ms
isGatewayAvailable() › returns false when bridge reports gateway unavailable
0.355054999999993ms
connection-integration.test.ts
6 / 6 1.7s
ConnectionManager Integration — Real WebSocket 6 / 6
client connects and receives broadcast events
226.22882ms
multiple clients receive same broadcast
203.970033ms
client sends command to server
153.64695799999993ms
handles rapid connect/disconnect without crashes
416.50844299999994ms
server detects client disconnect
253.05727300000012ms
bridge → gateway priority: second server takes over on disconnect
407.8999610000001ms
option-scenario.test.ts
9 / 9 7ms
option-renderer panels 3 / 3
E2 Focus panel renders with adaptive font
3.0511230000000182ms
E3 List panel renders 4 visible rows with 14px font
0.7818040000000224ms
E4 Detail panel shows word-wrapped label (12px, left-aligned)
0.647262000000012ms
colorForOption — "don't ask again" / "allow all sessions" 6 / 6
returns blue for "Yes, and don't ask again for: tail:*"
0.5047649999999919ms
returns blue for "Yes, and don’t ask again" (smart quote)
0.2312819999999931ms
returns blue for "Yes, allow all sessions in project"
0.2329469999999958ms
returns green for plain "Yes" (shortcut y)
0.26492600000000266ms
returns green for "Apply" (shortcut a, but no "don't ask" pattern)
0.1857079999999769ms
returns blue for "Always allow"
0.15337699999997767ms
renderer-snapshots.test.ts
85 / 85 78ms
voice-renderer snapshots 12 / 12
renderVoiceReady
5.02006700000004ms
renderVoiceRecording frame 0
0.5551189999999906ms
renderVoiceRecording frame 30 (>1min)
0.3299880000000712ms
renderVoiceTranscribing frame 0
0.3273019999999178ms
renderVoiceTranscribing frame 10 (different dot phase)
0.304349000000002ms
renderVoiceError with message
0.5510610000000042ms
renderVoiceError default
0.37401999999997315ms
renderVoiceDisabled
0.45021299999996245ms
renderVoiceAssistantListening frame 0
0.4877329999999347ms
renderVoiceAssistantProcessing frame 5
0.5312940000000026ms
renderVoiceAssistantSpeaking frame 0
0.5248619999999846ms
renderWideVoiceText returns correct panel count
2.7267340000000786ms
utility-renderer snapshots 4 / 4
renderSetupUtility
0.48032899999998335ms
renderUtilityGeneric with icon
0.7039479999999685ms
renderUtilityGeneric text-only (no icon)
0.39479900000003454ms
renderUtilityMedia
0.48392599999999675ms
usage-dial-renderer snapshots 7 / 7
renderUsageOverview
0.7322709999999688ms
renderUsageDetail 5h
0.3969430000000784ms
renderUsageDetail 7d
0.31323700000007193ms
renderUsageSession
0.6066060000000562ms
renderUsageExtra enabled
0.4760709999999335ms
renderUsageExtra disabled
0.40856399999995574ms
renderUsageDisconnected
0.45575300000007246ms
usage-gauge snapshots 7 / 7
renderUsageGauge Claude 5h (green ramp, low usage)
1.3933079999999336ms
renderUsageGauge Claude 7d
0.31296599999996033ms
renderUsageGauge Codex 5h uses the blue brand logo + amber ramp
0.5183099999999286ms
renderUsageGauge Codex 7d
0.32676200000003064ms
renderUsageGauge critical (>80 used → red ramp)
0.4843660000000227ms
renderUsageGauge full-bleed fill (no narrow 60px tank rect)
0.5053570000000036ms
renderUsageGauge unknown draws a dim tile + dash, no fill
0.6521810000000414ms
usage-encoder level-fill (SD+ 200x100) snapshots 7 / 7
both-view Claude shows both windows + terracotta brand logo
1.279164000000037ms
both-view Codex uses the blue brand logo + severity ramp
0.8150560000000269ms
single 5h view enlarges the 5H window across the LCD
0.6163040000000137ms
single 7d view enlarges the 7D window across the LCD
0.45288699999991877ms
note suppresses the gauges (No Codex usage)
0.3948290000000725ms
Waiting note before the first usage payload
1.2349310000000742ms
a single unknown window draws a dash panel, the other a real fill
0.5735839999999826ms
response-renderer snapshots 7 / 7
renderResponseIdle
0.5198030000000244ms
renderResponseProcessing
0.38305800000000545ms
renderResponseDisconnected
0.27775000000008276ms
renderResponseDisabled
0.2979569999999967ms
renderResponseSuggestion
0.6860340000000633ms
renderResponseInteractive
0.4928619999999455ms
renderSetupPrompt
0.40548899999998866ms
option-renderer snapshots 7 / 7
renderContextPanel permission
0.8697879999999714ms
renderContextPanel diff
0.4026240000000598ms
renderFocusPanel with recommended option
0.859279000000015ms
renderListPanel 3 options
0.9108750000000327ms
renderListPanel 6 options (scroll indicator)
0.5345200000000432ms
renderDetailPanel
0.7444130000000087ms
renderWideOptionList returns correct panel count
0.9136899999999741ms
button-renderer snapshots 7 / 7
basic text button
1.17656199999999ms
button with subtitle
0.48555899999996655ms
disabled button
0.45511199999998553ms
loading button
0.4481190000000197ms
long text that needs abbreviation
0.5728219999999737ms
svgToDataUrl returns data URI
0.5265349999999671ms
labelNeedsHaiku detects long labels
1.4280929999999898ms
session-slot-renderer snapshots 9 / 9
disconnected hero is icon-rich
1.5149470000000065ms
disconnected non-center slot is empty
0.3365599999999631ms
disconnected cluster quadrant tl
0.4454129999999168ms
disconnected cluster quadrant tr
0.4275709999999435ms
disconnected cluster quadrant bl
0.3928650000000289ms
disconnected cluster quadrant br
0.36967200000003686ms
connected no-session card is icon-rich
0.5100049999999783ms
active idle session uses orbiting focus border
1.25172299999997ms
stale session dims the render and shows a STALE badge
0.491971000000035ms
display-tile snapshots 6 / 6
renderStatusReadout MODEL is flat (no raised bezel, no glyph)
0.8288109999999733ms
renderStatusReadout READY (label only)
0.31840699999997923ms
renderStatusReadout AWAITING
0.28642600000000584ms
renderStatusReadout HUB READY (no-session hub state)
0.43782899999996516ms
renderSessionReadout keeps name/model/state, flat & non-interactive
4.165726000000063ms
renderSessionReadout openclaw hides model, shows STANDBY
0.3212419999999838ms
timeline-renderer snapshots 5 / 5
empty timeline
0.4649010000000544ms
single entry
1.2492780000000039ms
multiple entries fisheye
0.5918779999999515ms
detail mode
0.5469740000000911ms
with session status
0.29177599999991344ms
qr-renderer snapshots 3 / 3
extractUrlLabel extracts host:port
0.4445330000000922ms
qrPathData deterministic
10.208358999999973ms
renderQrButtonSvg
7.869970999999964ms
agent-logos snapshots 4 / 4
claude-code watermark
0.5750259999999798ms
openclaw watermark
0.5398400000000265ms
antigravity icon uses the full-color mark
0.6466000000000349ms
CLAUDE_LOGO_PATH is defined
0.44714700000008634ms
text-utils-and-labels.test.ts
19 / 19 11ms
text-utils: CJK width measurement 4 / 4
Latin text is ~0.55em per char
2.922672000000034ms
Korean text is 1em per char (double-width)
0.4636679999999842ms
mixed text measures correctly
0.1773619999999596ms
isWide detects Hangul, CJK, fullwidth
0.41172000000000253ms
text-utils: wrapTextByWidth 3 / 3
short text returns single line
0.9930299999999761ms
long Latin text wraps to multiple lines
0.4717340000000263ms
Korean text wraps at correct pixel width
0.28062499999998636ms
button-renderer: abbreviation 10 / 10
short label renders without abbreviation indicator
1.3160140000000524ms
"Yes, I trust this folder" fits with wrapping (no abbreviation needed)
0.36911100000003216ms
"Yes, allow and don't ask again" wraps into 3 lines
0.27134799999998904ms
very long label triggers abbreviation with ~ indicator
0.9643260000000282ms
short permission labels like "No" render unchanged
0.25106999999997015ms
labelNeedsHaiku returns false for short labels
0.24081100000000788ms
labelNeedsHaiku returns false when heuristic abbreviation fits
0.23589199999997845ms
labelNeedsHaiku returns true for very long unknown labels
0.44881000000003723ms
labelNeedsHaiku returns false when Haiku cache has result
0.2704469999999901ms
BUTTON_MAX_CHARS is reasonable
0.32499899999999116ms
button-renderer: CJK labels 2 / 2
Korean label does not overflow (produces valid SVG)
0.2711980000000267ms
mixed CJK/Latin label renders
0.17493799999999737ms
TUI Dashboard PASS
터미널 대시보드의 상태 렌더링과 테라리움 애니메이션이 올바른가?
51 passed 0 failed 3 files 70ms
tui-dashboard.test.ts
9 / 9 22ms
TUI dashboard models 9 / 9
stores modelCatalog from state_update
4.4074620000000095ms
renders OAuth catalog and Ollama models in wide layout
3.4826810000000137ms
renders disconnected OAuth state
1.0921339999999873ms
renders downstream module health compactly
1.1337330000000065ms
shows current session summary and control hints
0.6507190000000378ms
renders agent list secondary line as model dash compact state
0.49630999999999403ms
renders sibling models in session bridge mode and omits uptime label
0.7983150000000023ms
renders help overlay when helpVisible is on
0.6082389999999691ms
shows numbered session badges
8.736628999999994ms
tui-renderer-snapshots.test.ts
29 / 29 17ms
blockGauge snapshots 7 / 7
0% — all empty, green
5.358483000000007ms
50% — half filled, green
0.4400140000000192ms
75% — yellow threshold
0.3184460000000229ms
95% — red threshold
0.2773589999999899ms
100% — all filled, red
0.2680819999999926ms
clamps negative to 0
0.2585639999999785ms
clamps above 100
0.3254790000000014ms
resetTimeStr 5 / 5
returns empty for undefined
0.5054259999999999ms
returns ↻now for past time
0.38835699999998496ms
formats minutes
0.39838600000001634ms
formats hours and minutes
0.2758359999999982ms
formats days and hours
0.24026000000000636ms
formatUptime 3 / 3
seconds
0.2630020000000002ms
minutes
0.22468000000000643ms
hours and minutes
0.23684400000001915ms
formatTokens 3 / 3
below 1000 unchanged
0.24465799999998694ms
1k-10k with decimal
0.246452000000005ms
10k+ rounded
0.23970900000000483ms
activityDensityBar 3 / 3
empty timestamps — all dim
0.4024829999999895ms
recent burst — bright right side
0.3020259999999837ms
spread timestamps — distributed density
0.3400169999999889ms
getLayout 3 / 3
wide for 120+ cols
0.2863260000000025ms
standard for 80-119 cols
0.25315499999999247ms
narrow for <80 cols
0.24004999999999654ms
shouldShowTerrarium 3 / 3
true for adequate size
0.2980579999999975ms
false for too narrow
0.2153030000000058ms
false for too short
0.18871399999997607ms
spinner 2 / 2
returns braille characters at different frames
2.6375089999999943ms
spinner cycles through 10 frames
0.2371440000000007ms
tui-terrarium-snapshots.test.ts
13 / 13 31ms
TUI terrarium snapshots 13 / 13
initTerrarium creates context with expected structure
6.956275000000005ms
setOctopi configures octopus instances
1.3096720000000062ms
setCrayfish configures crayfish state
0.5669719999999927ms
setJellyfish configures jellyfish instances
0.9791230000000155ms
renderTerrariumFrame empty terrarium (small)
6.258989000000014ms
renderTerrariumFrame empty terrarium (large)
1.1318589999999915ms
renderTerrariumFrame with idle octopus
1.776726999999994ms
renderTerrariumFrame with processing octopus
3.7047970000000134ms
renderTerrariumFrame with routing crayfish
4.649179000000004ms
renderTerrariumFrame with sick crayfish
1.3536550000000034ms
renderTerrariumFrame with OpenCode hollow ring
1.378450999999984ms
renderTerrariumFrame too small returns empty
0.46978999999998905ms
updateTerrarium advances bubble positions
0.49030699999997296ms
Serial Protocol PASS
ESP32와의 시리얼 바이트스트림이 정확히 프레이밍되는가?
40 passed 0 failed 1 files 34ms
esp32-serial-node.test.ts
40 / 40 34ms
SERIAL_FORWARDED_EVENTS 4 / 4
includes all display events
3.8511910000000285ms
includes timeline events (unique to serial)
0.3804620000000227ms
does NOT include plugin-only events
0.5493190000000254ms
required serial events are present
0.42322300000000723ms
ESP32 port detection patterns 5 / 5
matches CH340 ports (86 Box)
0.5924890000000005ms
matches native USB JTAG ports (IPS 3.5", Round AMOLED)
0.4172009999999773ms
matches Linux serial ports
0.3661950000000047ms
excludes Bluetooth and WLAN
0.26585799999998017ms
excludes non-ESP32 ports
0.33662099999997963ms
handleSerialLine (source) 5 / 5
parses device_info message and updates deviceInfo
1.2959160000000338ms
skips debug lines (non-JSON)
0.24134199999997463ms
recovers from malformed JSON
0.5959960000000137ms
ignores JSON without type field
0.23383799999999155ms
does not mark deviceInfo present for non-identifying messages
0.4760909999999967ms
serial I/O error classification 2 / 2
treats nonblocking backpressure as retryable
0.34395399999999654ms
does not retry terminal serial errors
0.28726800000004005ms
prepareForSerial (source) 10 / 10
strips agentCapabilities from state_update
0.8551009999999906ms
strips billingType and remoteUrl from state_update
0.3719660000000431ms
preserves essential state_update fields
1.908171999999979ms
strips bulky state_update fields before device_info arrives
0.9296509999999785ms
trims sessions_list to firmware fields and string sizes
1.2831229999999891ms
forwards per-session D1 mosaic fields (tool/elapsed/awaiting prompt) and trims oversized strings
2.1067450000000463ms
round-robins sessions_list by agent type so non-Claude agents survive the cap
1.3310930000000099ms
roundRobinByAgentType keeps every present agent type and is a no-op under the cap
1.556714999999997ms
strips legacy usage fields from usage_update
0.8457030000000145ms
passes through other events unchanged
0.26942500000001246ms
WiFi provision protocol 1 / 1
provision message has all required fields
2.456799999999987ms
serial buffer management 3 / 3
line splitting handles multiple lines in one chunk
0.47263500000002523ms
handles partial message across chunks
0.5906659999999988ms
truncates buffer when exceeding 8KB limit
0.23121299999996836ms
foreign port detection 3 / 3
flags a port that opened but never sent valid JSON
0.2916259999999511ms
does NOT flag a connection that ever read a valid AgentDeck message
0.272941000000003ms
does NOT flag a connection that already identified its board
0.22144499999996015ms
foreign port denylist threshold 2 / 2
denylists a port only after repeated failed probes
0.5392799999999625ms
treats an elapsed cooldown as no longer denylisted
0.32185299999997596ms
half-open identified CDC recovery 5 / 5
flags an identified CDC port that has never read since (re)connect
0.3925260000000321ms
does NOT flag while the read pipe is alive
0.26962499999996226ms
does NOT flag inside the grace window after connect
4.1182210000000055ms
does NOT flag an unidentified CDC port — that is the foreign path
0.27563599999996313ms
does NOT flag a UART (non-CDC) port — handled by the read-timeout branch
0.20117599999997537ms
Display Rendering PASS
외부 디스플레이에 전송할 이미지 데이터가 올바른가?
19 passed 0 failed 1 files 89ms
pixoo-sprites.test.ts
19 / 19 89ms
getOctopusPaletteForSession 3 / 3
keeps the first additional session near the original terracotta tone
5.146546000000001ms
darkens later sessions while preserving channel ordering
1.3063949999999522ms
clamps very large session indices to the darkest supported tone
0.37490200000002005ms
creatureCellSize 10 / 10
is monotonic non-decreasing across a zoom sweep (cols=24, 32px)
14.716805000000022ms
is monotonic non-decreasing across a zoom sweep (cols=14, 32px)
10.542385000000024ms
is monotonic non-decreasing across a zoom sweep (cols=12, 32px)
11.577247ms
is monotonic non-decreasing across a zoom sweep (cols=8, 32px)
7.001227999999969ms
is monotonic non-decreasing across a zoom sweep (cols=24, 64px)
6.299595000000011ms
is monotonic non-decreasing across a zoom sweep (cols=14, 64px)
9.305342999999993ms
is monotonic non-decreasing across a zoom sweep (cols=12, 64px)
10.70299ms
is monotonic non-decreasing across a zoom sweep (cols=8, 64px)
7.658128999999974ms
is stable for sub-0.25 zoom jitter around a value (no flicker)
0.5349109999999655ms
never returns less than 1
0.19403299999999035ms
Codex cloud low-detail grids 2 / 2
keeps the MD cloud as one rounded body instead of separated dangling lobes
1.7652160000000094ms
keeps the LOD cloud rounded for iDotMatrix-wide shots
0.35828099999997676ms
quantizeCameraPixels 4 / 4
snaps the center onto the device-pixel grid
0.4815810000000056ms
is idempotent
0.3597830000000499ms
preserves zoom and width
0.22375899999997273ms
defaults width to 64 and tolerates degenerate scale
0.32330500000000484ms
Hook Installation PASS
Claude Code hook의 설치, 제거, 마이그레이션이 안전한가?
24 passed 0 failed 1 files 15ms
install.test.ts
24 / 24 15ms
Hook Installer 24 / 24
buildHookEntry › creates matcher-group format with AGENTDECK_PORT env var
3.934207000000015ms
buildHookEntry › uses `*` matcher for tool events and empty matcher for lifecycle events
0.2818070000000148ms
buildHookCommand (POSIX) › reads PORT from AGENTDECK_PORT env var first, then daemon.json, then 9120
0.2877590000000225ms
buildHookCommand (POSIX) › emits newline-separated shell so if/then/for/do keywords are not mis-terminated by `;`
0.4003399999999999ms
buildHookCommandWin (Windows) › wraps a PowerShell one-liner that targets the event endpoint
0.37157600000000457ms
buildHookCommandWin (Windows) › uses single-line PowerShell so cmd.exe can pass it as one -Command argument
0.16133299999998485ms
buildHookCommandWin (Windows) › omits the macOS App Store sandbox-container fallback paths
0.19179900000000316ms
applyHooks › installs hooks to empty settings in matcher-group format
2.2072430000000054ms
applyHooks › preserves non-AgentDeck hooks
0.40627000000000635ms
applyHooks › replaces old flat-format hooks
0.292648000000014ms
applyHooks › replaces old matcher-format hooks
0.2752049999999997ms
applyHooks › is idempotent — running twice produces same result
0.9318440000000123ms
applyHooks › preserves existing non-hook settings
1.3056949999999858ms
removeHooks › removes all AgentDeck hooks (new format)
0.46787599999998974ms
removeHooks › removes old flat-format AgentDeck hooks
0.17656999999999812ms
removeHooks › preserves non-AgentDeck hooks
0.3573990000000151ms
removeHooks › handles empty settings gracefully
0.1949549999999931ms
migrateHooks › migrates old hardcoded port to env var
0.3634500000000003ms
migrateHooks › migrates flat format to matcher-group format
0.3400169999999889ms
migrateHooks › skips already-migrated hooks (new format)
0.19613699999999312ms
migrateHooks › skips non-AgentDeck hooks
0.16536899999999832ms
migrateHooks › migrates multiple events at once
0.5267369999999971ms
migrateHooks › migrates hardcoded port inside matcher-group
0.2386070000000018ms
migrateHooksIfNeeded (file-based) › upgrades old :-9120 fallback hooks to daemon.json-reading format
0.1893750000000125ms
Other Tests
Uncategorized test files
681 passed 0 failed 62 files
antigravity-transcript.test.ts
3 / 3 5ms
antigravity transcript parsing 3 / 3
extracts goal, model (from settings change), state and tool task
3.2238830000000007ms
reports processing when any step is RUNNING; later model change wins
0.429473999999999ms
matches the agy CLI binary as an Antigravity process
0.6716880000000174ms
apme-category-e2e.test.ts
3 / 3 59ms
APME category-aware turn evaluation (E2E) 3 / 3
conversation turn: prompt → classify → judge → turn category + composite persisted
31.367672000000027ms
research turn: rule-based classifier picks research, judge uses research rubric axes
15.09008399999999ms
daemon backfill pass: turns with response but no outcome get committed + null composite
11.82844799999998ms
apme-classifier.test.ts
18 / 18 69ms
classify() 12 / 12
planning — plan mode used
2.8763250000000085ms
planning — short session, no file changes
0.35053599999997687ms
research — web searches dominant
0.22483099999999467ms
research — grep/glob dominant, no file changes
0.32122099999998ms
coding — edit+write dominant with file changes
0.22964999999999236ms
debugging — tests + edits + bash
0.16579999999999018ms
refactoring — many edits, no new files
0.17432600000000775ms
review — mostly reads, minimal edits
0.28747800000002144ms
ops — bash dominant, few edits
0.20670699999999442ms
conversation — very short, no tools
0.2132890000000316ms
multi_agent — multiple Agent delegations
0.15787600000004431ms
unknown — no clear pattern
0.18842200000000275ms
computeSignals() 3 / 3
counts tool calls and identifies dominant tool
24.326183000000015ms
detects plan mode from step payload
8.97940299999999ms
detects web searches
6.524946999999997ms
classifyRun() 2 / 2
returns signals and category for a coding run
6.813633999999979ms
returns unknown for empty runs
8.082334000000003ms
task_category schema migration 1 / 1
runs table has task_signals, task_category, task_category_source columns
7.791243000000009ms
apme-collector.test.ts
13 / 13 191ms
ApmeCollector 13 / 13
openRun → ingestHook → closeRun persists a run with steps
38.648769000000016ms
updateUsage and updateModel reflect in the run row
9.527376000000004ms
listRuns filters by agent and orders by started_at desc
18.609988999999985ms
default rubric v1 is seeded on init
9.40413000000001ms
insertEval + listEvalsForRun round-trip
10.73998899999998ms
excludes _empty runs from the unevaluated run queue
11.910640999999998ms
scorecard view aggregates runs per model
11.888217999999995ms
multi-turn cycle captures prompts and responses (wireAgentApme path)
26.901148999999975ms
setLastClosedTurnResponse fills missing response on closed turn
11.949964999999963ms
setTurnResponse tags efficiency_json.response_kind (text / tool_only / empty)
12.090899000000036ms
no-op gracefully when store is disabled
9.579046000000005ms
ignores an echoed duplicate turn_start (same prompt on a fresh empty turn)
8.529693000000009ms
treats a same-prompt re-send after a response or tool use as a new turn
11.488748999999984ms
apme-http.test.ts
13 / 13 525ms
APME HTTP routes 13 / 13
returns 503 when APME is not initialized
105.82847399999997ms
GET /apme/runs lists recent runs with evals and overall score
64.710804ms
GET /apme/runs filters by agent
33.40931500000005ms
GET /apme/run/:id returns run detail with steps and evals
26.390563000000043ms
GET /apme/run/:id returns 404 for unknown runs
17.723875999999905ms
GET /apme/run/:id includes per-task rollup with attached evals
94.52451800000006ms
GET /apme/tasks/:id returns task detail with evals + turns
74.71112599999992ms
closeTaskExternal with manual signal records outcome + boundary_signal=manual
21.967554999999948ms
GET /apme/scorecard returns model aggregates
18.76335199999994ms
GET /apme/rubric/current returns seeded rubric v1
16.60252700000001ms
POST /apme/vibe records feedback and rejects unknown runs
24.005628ms
POST /apme/recommend returns candidate list
16.79364499999997ms
unknown /apme/* path returns 404
8.747208999999998ms
apme-judge-probe.test.ts
20 / 20 103ms
probeJudgeBackend — MLX 4 / 4
returns unavailable when /v1/models is unreachable
9.074632000000008ms
returns unavailable when /v1/models advertises no chat-capable model
40.34841799999998ms
returns unavailable when chat ping fails (model not loaded)
0.9841829999999732ms
returns ready when catalog AND chat ping both succeed
0.8096050000000332ms
probeJudgeBackend — OpenClaw 4 / 4
returns unavailable when /health is unreachable
0.6366019999999821ms
returns unavailable when /health is up but /models is not (gateway not initialised)
0.7025750000000244ms
returns unavailable when configured model is not in /models catalog
0.772627ms
returns ready when /health + /models both up and model matches
0.6788819999999873ms
probeJudgeBackend — Anthropic API (stub backend) 2 / 2
returns unavailable when ANTHROPIC_API_KEY is not set
0.9578029999999558ms
returns unavailable even when ANTHROPIC_API_KEY is set (callApi is a stub)
0.92641500000002ms
callJudgeWithMeta — effective backend labelling across fallback 3 / 3
FM happy path labels eval as foundationModels
1.4916029999999978ms
FM→MLX fallback (fallbackToMlx=true) labels eval as mlx, not foundationModels
1.6943219999999997ms
FM failure without fallbackToMlx propagates the error (no silent label drift)
2.071930000000009ms
sanitizeForMlx — runtime fallback hygiene 4 / 4
strips FM endpoint and model when forcing to MLX
0.527657999999974ms
strips OpenClaw endpoint and model when forcing to MLX
0.473226000000011ms
returns the same cfg shape when already-clean MLX is passed
0.4032349999999951ms
clears a custom MLX endpoint when source backend is MLX but model is overridden
0.4244539999999688ms
probeJudgeBackend — Foundation Models 3 / 3
returns unavailable when Swift daemon FM endpoint cannot be resolved
37.25984399999999ms
returns unavailable when FM endpoint responds with error body
1.2692370000000324ms
returns ready when FM endpoint responds with text
0.9875800000000368ms
apme-pareto.test.ts
4 / 4 32ms
computePareto 3 / 3
keeps non-dominated points and drops dominated ones
6.3207140000000095ms
sorts the frontier cheapest → most expensive
0.4054399999999987ms
ignores models below minSamples
0.42582799999999565ms
ApmeRecommender on the Pareto frontier 1 / 1
recommends only frontier models, cheapest-first under a tight budget
24.153215999999986ms
apme-runner.test.ts
34 / 34 609ms
detectLanguage 4 / 4
recognizes TypeScript from package.json
6.152076999999963ms
recognizes Swift from .xcodeproj
1.1340830000000324ms
recognizes Kotlin from build.gradle.kts
0.6070170000000417ms
returns null for unknown paths
0.27162799999996423ms
parseJudgeJson 5 / 5
extracts scores and reasoning from a clean JSON blob
1.0531710000000203ms
rescales 0-10 axis to 0-1
0.29541200000005574ms
tolerates prose wrapping and code fences
0.28483299999993505ms
returns null when there is no JSON at all
0.2296809999999141ms
returns null when overall is missing
0.2360519999999724ms
effectiveJudgeModelTag 4 / 4
uses cfg.model for MLX when no pin is set
4.430663999999979ms
uses llm.mlx pin over cfg.model for MLX backend
0.8339310000000069ms
ignores llm.mlx pin for non-MLX backends
0.7253779999999779ms
foundationModels uses the Swift-parity judgeModelLabel
0.4960790000000088ms
callJudge foundationModels routing 4 / 4
returns FM text on ok response
41.162481999999954ms
throws when FM reports unavailable and fallback is disabled
21.27776300000005ms
falls back to MLX when fallbackToMlx is true
134.881975ms
caches auto-resolved FM endpoint failure and routes subsequent calls straight to MLX
13.543993ms
shouldJudge gating 4 / 4
never runs when sampleRate is 0
0.33051899999986745ms
skips clear passes when onlyWhenDisagreement is true
0.2020390000000134ms
runs on failures when onlyWhenDisagreement is true
0.20021500000007109ms
runs for clear passes when onlyWhenDisagreement is false
0.22959000000014385ms
ApmeRunner duplicate guard 1 / 1
does not enqueue the same run while it is already queued or running
33.15640200000007ms
ApmeRunner.runOne 5 / 5
records deterministic failures and invokes judge with rubric prompt
46.076352999999926ms
skips layer 2 on a clean pass when onlyWhenDisagreement is true
15.71508700000004ms
does not notify onResult for no-op run evals
9.64953300000002ms
enqueueTurn skips judge for tool_only and empty turns
31.292102999999997ms
swallows judge errors without inserting partial rows
17.137318999999934ms
runDeterministic (end-to-end spawn) 3 / 3
runs sh-based commands against the project path and reports pass
51.66285099999982ms
captures exit code 1 as tests_pass=0
56.55474499999991ms
skips entirely when the worktree has no changes
48.18380500000012ms
onTaskEvaluated 3 / 3
fires after enqueueTask resolves and carries the composite score + outcome
27.678527999999915ms
derives outcome=fail for low composite scores
21.92685800000004ms
preserves a manually-set outcome — judge does not overwrite `abandoned`
19.40217000000007ms
buildJudgePrompt 1 / 1
includes rubric prompt + task + context fields
0.6224349999999959ms
apme-sample-timeline.test.ts
8 / 8 6ms
sampleEventToTimeline projection 4 / 4
projects user_message → chat_start
3.639614999999992ms
projects a text assistant_message → chat_response but skips tool_only
0.4673750000000041ms
projects tool → tool_resolved with status mapping + input summary
0.4163999999999817ms
skips model and state events (no standalone row)
0.2269950000000165ms
OpenClaw session.tool / session.message → spans (previously dropped) 4 / 4
maps a running tool to a tool_call span carrying input
0.8246639999999843ms
maps a completed tool to a tool_result span carrying output
0.19477499999999281ms
maps a user message to turn_start and assistant to turn_response
0.3628799999999899ms
drops empty/blank messages and nameless tools
0.39457899999999313ms
apme-sample.test.ts
7 / 7 98ms
ApmeStore sample events 5 / 5
round-trips typed trajectory events into a SessionSample
21.915825000000012ms
dedups identical (task, dedupKey) at storage time
6.11975799999999ms
resolves a pending tool event in place (one row, not two)
6.123366000000033ms
recomputeSampleCost sums ModelEvents into the task header
6.439235999999994ms
local models price at $0; unknown models fall back to $0 but flag unpriced
37.04145699999998ms
ApmeCollector → SessionSample (Phase 1 dual-write) 2 / 2
builds a typed trajectory (user → tool pending→resolved → assistant) and cost
12.452786000000003ms
fires onSampleEvent once per inserted event (no dup double-emit)
6.846769999999992ms
apme-scorers.test.ts
6 / 6 6ms
TrajectoryQualityScorer 3 / 3
penalizes consecutive identical tool calls (churn)
3.2842100000000016ms
penalizes tool errors
0.25903499999998303ms
does not apply with fewer than 2 tools
0.166561999999999ms
ToolEfficiencyScorer 1 / 1
is the success rate of resolved tools
0.40497799999999984ms
runSampleScorers 2 / 2
runs only applicable scorers and tags layer/scorer
1.0061740000000157ms
returns nothing for a toolless conversation sample
0.17270299999998429ms
apme-settings.test.ts
15 / 15 18ms
loadApmeConfig — defaults + merge behaviour 12 / 12
returns full defaults when settings.json does not exist
6.516351000000014ms
returns full defaults when settings.json has no apme section
1.627476999999999ms
returns defaults on malformed JSON (must not throw)
0.7345750000000066ms
merges user-set fields on top of defaults
0.9623519999999814ms
clamps sampleRate to [0, 1]
0.8161289999999894ms
falls back to mlx when judge.backend is unknown string
0.6793619999999976ms
downgrades judge.backend="api" to "mlx" on the Node bridge (callApi is a stub)
0.7155700000000138ms
also wipes endpoint/model when downgrading backend="api" → "mlx"
1.0021069999999952ms
also wipes endpoint/model when falling back from unknown backend → "mlx"
0.9381070000000022ms
preserves user-set endpoint/model when keeping their chosen backend
0.9080500000000029ms
respects explicit enabled=false (opt-out)
0.7787979999999948ms
clamps deterministic.timeoutSec to [5, 1800]
1.0341760000000022ms
loadApmeConfig — DEFAULT_APME_CONFIG sanity 3 / 3
default backend is Foundation Models with local MLX fallback (cost-sensitive policy)
0.3421809999999823ms
default sampleRate is 1.0 (judge every closed run; cost is local)
0.2945309999999779ms
default enabled is true (zero-config activation)
0.22515199999998003ms
apme-task-boundary.test.ts
13 / 13 242ms
ApmeCollector task boundaries 11 / 11
first UserPromptSubmit opens a task and attaches the turn
30.615643999999975ms
TodoWrite all-completed is a soft hint — does NOT close the task
14.534875ms
TodoWrite all-completed does not split — later turns stay in one task
14.322156000000007ms
TodoWrite with partial completion does NOT close the task
10.125798999999972ms
next UserPromptSubmit after an explicit boundary opens a new task
13.92566400000004ms
splitRun closes the active task with boundary=clear
17.450525000000027ms
closeRun closes the active task with boundary=session_end
15.380246ms
onTaskClosed fires on an explicit boundary with the task metadata
13.760084999999947ms
onTaskOpened fires with sessionId + agentType + projectName + taskIndex
11.068877000000043ms
onTaskClosed payload includes session, agent, project, and timing
13.083034999999995ms
empty task (no turns between two boundaries) is dropped
20.72595899999999ms
ApmeRunner task eval 2 / 2
enqueueTask invokes judge with turns and persists summary + scores
36.34800799999999ms
skips task eval when all turns are tool_only / empty
29.60173500000002ms
apme-task-milestone.test.ts
2 / 2 533ms
TodoWrite-all-completed → onTaskMilestone 1 / 1
fires once per (task, turn) with attribution; not on partial todos
532.344865ms
opencodeIdleGapTaskBoundary 1 / 1
builds a task_boundary span with the idle_gap signal
0.6700049999999464ms
apme-telemetry-envelope.test.ts
40 / 40 360ms
claudeHookToSpans 7 / 7
emits turn_start with prompt for UserPromptSubmit
4.196698000000026ms
detects /clear and emits a task_boundary span (not turn_start)
0.5417039999999815ms
drops Claude task notification payloads from UserPromptSubmit
0.757047ms
emits tool_call for PreToolUse with gen_ai.tool.name
1.0502060000000029ms
emits tool_result for PostToolUse
0.2863370000000032ms
falls through to raw_step for unknown events (Stop, SessionEnd, …)
0.29193700000001854ms
handles legacy { prompt: ... } shape on UserPromptSubmit
0.18959499999999707ms
claudePtyParserEventToSpans 4 / 4
maps tool_start to a tool_call span
0.45751699999999573ms
maps tool_end to a tool_result span
0.21692600000000084ms
emits a raw_step for spinner_start/idle/spinner_stop
0.2790520000000356ms
drops unknown parser events
0.2225260000000162ms
claudePtyResponseToSpan 3 / 3
returns a turn_response span for non-trivial text
0.40511800000001585ms
marks fallback_to_last_closed when requested
0.18240199999996776ms
returns null for empty / single-character text (filters silence)
0.22699499999998807ms
timelineEntryToSpans 12 / 12
translates chat_start to turn_start with detail as prompt
0.38967999999999847ms
translates chat_response to turn_response
0.24856499999998505ms
translates chat_end with response detail to turn_response with fallback flag
0.25636000000002923ms
drops chat_response / chat_end with empty body
0.3084569999999758ms
translates tool_request with first-token tool name
0.25862500000005184ms
codex_user_prompt_submit → turn_start span
10.717073999999968ms
codex_user_prompt_submit with /clear → task_boundary span
0.36209800000000314ms
codex_tool_start → tool_call span with tool name
0.3829470000000015ms
codex_tool_end → tool_result span
0.2934099999999944ms
codex_stop / codex_session_start / codex_turn_complete → raw_step
0.711291000000017ms
translates tool_exec the same as tool_request (legacy + Codex paths)
0.4977119999999786ms
translates tool_resolved to a tool_result span
0.2632030000000327ms
ApmeCollector.ingestSpan dispatch 13 / 13
turn_start span opens a turn and records the prompt
43.39874900000001ms
turn_response span persists the response on the active turn
21.616647999999998ms
tool_call span increments tool_calls on the active turn
32.831042999999966ms
chat_end fallback does not clobber a prior closed turn response
27.35674300000005ms
Codex timeline path opens turn and counts tools (timelineEntryToSpans)
20.736597000000017ms
task_boundary span with signal=clear splits the run
24.720582999999976ms
task_boundary span with signal=manual closes the active task
26.883351000000005ms
task_boundary span with signal=idle_gap closes the active task
18.693081000000006ms
task_boundary span with signal=todo_complete is a soft hint — does NOT close the task
23.272970999999984ms
task_boundary span with an unknown signal is dropped (no task close, no throw)
27.16937699999994ms
raw_step span inserts a steps row without lifecycle effects
26.946253999999954ms
session_meta span updates the model id on the run
17.056827ms
timeline adapter feeds the same dispatch path correctly
24.25413800000001ms
eval-schema constants 1 / 1
exports a stable schema version string
0.30377900000007685ms
awaiting-overlay.test.ts
18 / 18 16ms
awaiting-overlay 18 / 18
set then get returns the trimmed question
5.481372999999991ms
carries an optional requestId (actionable PreToolUse gate)
0.7982250000000022ms
returns undefined for an unknown session
0.5799749999999904ms
expires after the TTL (5 min)
0.83157700000001ms
re-setting refreshes the TTL (a follow-up prompt keeps the overlay alive)
0.4510050000000092ms
clear removes the entry and reports whether one existed
0.5559609999999964ms
caps question length at 120 chars
0.5085219999999993ms
looksLikePermissionMessage › matches genuine permission prompts
0.5834230000000105ms
looksLikePermissionMessage › rejects the idle ping, non-permission status text, and empty messages
0.47702300000000264ms
isPermissionNotification › uses notification_type when present — only permission_prompt awaits
0.5647669999999891ms
isPermissionNotification › falls back to the message regex only when notification_type is absent
0.41317300000000046ms
shouldGatePreToolUse › gates in default / auto / unknown modes (Claude may prompt)
0.5305329999999913ms
shouldGatePreToolUse › never gates when Claude will not prompt or execute
0.6831090000000017ms
shouldGatePreToolUse › acceptEdits auto-approves edits but still gates Bash
0.5009579999999971ms
applyAwaitingOverlayToObserved › flips a matching observed session to awaiting_permission with the question
1.3141810000000191ms
applyAwaitingOverlayToObserved › matches the uuid after stripping the observed:claude: / observed:codex: prefix
0.48162199999998734ms
applyAwaitingOverlayToObserved › leaves sessions untouched when no overlay exists
0.43277100000000246ms
applyAwaitingOverlayToObserved › propagates the requestId for actionable gates
0.4793979999999749ms
ble-sync-squelch.test.ts
5 / 5 10ms
createSyncCycleSquelch 5 / 5
logs the first two occurrences of a cycle, then suppresses identical repeats
6.424187999999987ms
emits an hourly summary with the repeat count while suppressing
1.1383109999999874ms
flushes and logs immediately when a different exit appears
0.8783950000000118ms
treats 1x vs 2x captures of the same retry error as the same cycle
0.5330280000000016ms
treats an exit after a long healthy run as a fresh incident
0.5631539999999973ms
bridge-core-sessions.test.ts
2 / 2 71ms
BridgeCore sessions_list 2 / 2
broadcastSessionsList enriches sessions before broadcast
16.24393500000002ms
sendInitialState sends enriched sessions_list to the connecting client
54.99076000000002ms
claude-transcript-reader.test.ts
7 / 7 12ms
readLastTurn 7 / 7
extracts assistant text and user prompt from a text-only turn
7.322310999999985ms
flags tool-only turns (tool_use blocks, no text blocks)
0.8615240000000028ms
concatenates text across multiple assistant records for one turn
0.7538119999999822ms
picks the LAST user prompt when multiple turns are in the file
0.7119229999999845ms
returns null for missing file
0.45743699999999876ms
skips malformed lines and continues parsing
0.7385830000000055ms
accepts legacy string content on both roles
0.6667479999999841ms
cli.test.ts
1 / 1 6ms
agentdeck CLI parser 1 / 1
reports a misspelled top-level command as unknown and suggests the closest command
5.732092000000023ms
codex-rate-limits.test.ts
9 / 9 9ms
parseCodexRateLimitsFromText 9 / 9
parses primary/secondary windows and converts resets_at to ISO
5.987411000000009ms
returns the most recent snapshot when multiple lines are present
0.5190119999999752ms
clamps used_percent into 0..100
0.38916900000000965ms
tolerates a truncated leading line (tail window cut mid-line)
0.38125400000001264ms
returns null when no rate_limits line exists
0.26165000000000305ms
omits a window missing required fields
0.5089729999999975ms
keeps a credit-based snapshot when windows are null
0.6199609999999893ms
prefers a windowed snapshot over an older credits-only one
0.34392400000001544ms
still returns null when neither windows, credits, nor limitId are present
0.31255500000000325ms
codex-turn-manager.test.ts
9 / 9 106ms
CodexTurnManager (hook-primary path) 6 / 6
happy path: UPS → tool_start → tool_end → stop emits one chat
31.875405ms
codex_stop does not reset subsequent turn_index numbering
15.295179000000019ms
codex_stop finalizes APME turn (endedAt set, tool_calls flushed)
8.77351600000003ms
next prompt opens a fresh chat_start
7.803578000000016ms
hook freshness window suppresses PTY parser idle close
6.823736999999994ms
long-bash: hook tool_start + tool_end keep the same turn open
6.705846000000008ms
CodexTurnManager (PTY-only fallback when hooks absent) 3 / 3
spinner_start opens turn, prompt-source idle closes after deferral
10.488244000000009ms
timeout-source idle without prior tool_action does not latch
7.52444399999996ms
tool_action then timeout-idle latches; spinner_start closes prev + opens new
9.945074000000034ms
d200h-button-map.test.ts
7 / 7 12ms
D200H buildButtonCommandMap 7 / 7
single-session AWAITING: mode/focus/options/usage/interrupt at expected keys
8.369040000000012ms
multi-session AWAITING: sessions focus by real id, options on row 1
0.9780010000000061ms
observed session (requestId, no options): no fabricated Allow/Deny keys
0.7449950000000172ms
awaiting with no options and no requestId: no fake Yes/No/Always keys
0.5909470000000283ms
options are inert unless AWAITING
0.5336189999999874ms
no real session: hero focus is inert (no synthetic id dispatched)
0.3782380000000103ms
DISCONNECTED frame has no actionable keys
0.32500900000002275ms
device-discovery.test.ts
2 / 2 5ms
Pixoo discovery — config-reply classification 2 / 2
accepts a real GetAllConf reply
3.904359999999997ms
rejects a non-Pixoo HTTP/JSON response
0.5014590000000112ms
display-dim.test.ts
3 / 3 6ms
display dim settings 3 / 3
defaults to enabled full-off when settings are missing
4.864938999999993ms
normalizes minimum-brightness settings
0.43178899999998066ms
embeds the resolved dim instruction in display_state events
1.0551649999999881ms
fallback-task-timeline.test.ts
4 / 4 9ms
FallbackTaskTimeline 4 / 4
opens a task on the first prompt and closes it on session end
6.434036999999989ms
segments on /clear and numbers the next task
0.723323999999991ms
ignores session end with no open task and tracks sessions independently
1.3701149999999984ms
drops the per-session counter on session_end so counts cannot grow unbounded
0.3658450000000073ms
gateway-parity-fixtures.test.ts
33 / 33 10ms
Gateway parity fixtures 33 / 33
fixture set is non-empty
2.43784500000001ms
'auth-pairing-required-error.json' carries a valid frame discriminator
0.9029999999999916ms
'chat-delta.json' carries a valid frame discriminator
0.180829000000017ms
'chat-final-with-tools.json' carries a valid frame discriminator
0.15683400000000347ms
'connect-challenge.json' carries a valid frame discriminator
0.17804399999999987ms
'connect-hello-ok-device-token.json' carries a valid frame discriminator
0.14921999999998548ms
'connect-ok.json' carries a valid frame discriminator
0.13418100000001232ms
'exec-approval-requested.json' carries a valid frame discriminator
0.13088500000000636ms
'health-event.json' carries a valid frame discriminator
0.12845000000001505ms
'logs-tail-response.json' carries a valid frame discriminator
0.13001299999999105ms
'models-list-response.json' carries a valid frame discriminator
0.12451300000000742ms
'rpc-error.json' carries a valid frame discriminator
0.15544099999999617ms
'session-message.json' carries a valid frame discriminator
0.13479300000000194ms
'session-tool.json' carries a valid frame discriminator
0.13357000000002017ms
'sessions-changed.json' carries a valid frame discriminator
0.12458300000000122ms
'tick.json' carries a valid frame discriminator
0.13032400000000166ms
'auth-pairing-required-error.json' conforms to its frame shape
0.43643699999998375ms
'chat-delta.json' conforms to its frame shape
0.1322280000000262ms
'chat-final-with-tools.json' conforms to its frame shape
0.11791099999999233ms
'connect-challenge.json' conforms to its frame shape
0.12417200000001571ms
'connect-hello-ok-device-token.json' conforms to its frame shape
0.15562099999999646ms
'connect-ok.json' conforms to its frame shape
0.2556780000000174ms
'exec-approval-requested.json' conforms to its frame shape
0.211355999999995ms
'health-event.json' conforms to its frame shape
0.13134600000000773ms
'logs-tail-response.json' conforms to its frame shape
0.1371769999999799ms
'models-list-response.json' conforms to its frame shape
0.1345410000000129ms
'rpc-error.json' conforms to its frame shape
0.17882399999999166ms
'session-message.json' conforms to its frame shape
0.11282099999999673ms
'session-tool.json' conforms to its frame shape
0.11320200000000114ms
'sessions-changed.json' conforms to its frame shape
0.14265700000001402ms
'tick.json' conforms to its frame shape
0.11663899999999217ms
chat-final fixture carries the final-state fields the adapter depends on
0.33774300000001745ms
exec.approval.requested fixture exposes options for the user prompt
0.5605189999999993ms
gateway-timeline-attribution.test.ts
3 / 3 5ms
enrichGatewayTimelineEntry 3 / 3
stamps agentType/projectName onto a bare OpenClaw adapter entry
4.075491000000056ms
preserves agentType/projectName the adapter already set
0.38292599999999766ms
does not mutate the input entry
0.31944800000007945ms
openclaw-hook.test.ts
8 / 8 10ms
openclaw-hook → telemetry spans 8 / 8
OPENCLAW_IDLE_GAP_MS is conservative (60–180 s) so multi-turn collab stays together
3.792170999999996ms
chat.send produces exactly one turn_start span carrying the prompt text
1.056699000000009ms
chat.final with a response + tools yields turn_response + per-tool tool_result spans
1.8331019999999967ms
chat.delta emits no spans — deltas are streaming chunks, not eval signals
1.1639700000000062ms
chat.aborted emits a manual task_boundary so the user gesture closes the task immediately
0.41747100000000614ms
chat.error emits nothing — the agent may retry, idle timer keeps running
0.2688229999999976ms
idle-gap task_boundary span carries boundary_signal=idle_gap
0.48613000000000284ms
all emitted spans propagate traceId for run correlation
0.542506000000003ms
openclaw-session.test.ts
5 / 5 5ms
injectOpenClawSession 5 / 5
does NOT inject when the Gateway is reachable but not authenticated (regression: phantom trace)
3.46239300000002ms
injects a minimal session when authenticated (CLI bridge shape)
0.5450409999999977ms
carries daemon-hub extras (state/projectName/modelName/controlMode) when provided
0.3526700000000176ms
is idempotent — does not duplicate an already-present openclaw session
0.35902199999998174ms
returns the original array reference when not injecting (no needless copy)
0.1651899999999955ms
openclaw-timeline-completion.test.ts
3 / 3 70ms
OpenClaw chat final → single completion row 3 / 3
emits chat_response only (no chat_end) when the turn has response text
58.83850899999999ms
marks gateway-initiated (cron) turns automated and skips LLM enrichment
11.100234ms
emits chat_end (not chat_response) for a response-less turn
0.4579469999999901ms
opencode-adapter-state.test.ts
6 / 6 14ms
OpenCodeAdapter run-state arming 6 / 6
arms processing on the first message.part.updated and latches once per turn
9.084870000000024ms
emits idle on session.idle and re-arms on the next turn
1.5041159999999536ms
auto-tracks the session and arms when no active session was resolved at connect
1.161595000000034ms
arms when an assistant message is still generating (no time.completed)
0.8488690000000361ms
does not arm on a completed assistant message alone
0.7830769999999916ms
drops parts for a different active session
0.8312260000000151ms
opencode-client.test.ts
13 / 13 17ms
OpenCodeClient 12 / 12
health › should call /global/health
8.638603999999987ms
listSessions › should call /session with directory and limit
0.8574460000000101ms
createSession › should POST to /session
0.8442809999999952ms
sendMessage › should POST to /session/{id}/message with parts
0.7321110000000033ms
sendMessage › should include model option when provided
0.5884619999999927ms
abortSession › should POST to /session/{id}/abort
0.5338099999999883ms
respondPermission › should POST allow response
0.43843100000000845ms
respondPermission › should POST deny response
0.43128699999999753ms
HTTP error handling › should throw on non-ok response
2.067030000000017ms
disconnect › should prevent reconnection after disconnect
0.42271199999999ms
url accessor › should return server URL
0.24898599999997373ms
url accessor › should strip trailing slash
0.28952200000000516ms
OpenCodeAdapter event mapping 1 / 1
should export OpenCodeSSEEvent type
0.25432599999999184ms
opencode-hook.test.ts
9 / 9 8ms
opencode-hook → telemetry spans 9 / 9
tool part with status=running produces a tool_call span
3.055260000000004ms
tool part with status=completed produces a tool_result span
0.43455399999999145ms
todowrite completion with all todos completed emits a task_boundary span (todo_complete)
0.5655189999999948ms
todowrite completion with a pending todo does NOT emit a task_boundary
0.34189000000000647ms
todowrite reads todos out of state.output JSON string when input is absent
0.36152699999999527ms
non-tool part returns an empty span list
1.101551999999998ms
message.updated for user role with prompt emits a turn_start
0.5987099999999828ms
message.updated for assistant role with response emits session_meta + turn_response
0.5175890000000152ms
assistant message with modelID but no response still emits session_meta (early model attribution)
0.4096969999999942ms
passive-observer.test.ts
9 / 9 10ms
passive-observer parsers 9 / 9
parses ps output without depending on fixed command columns
3.196335000000005ms
summarizes Claude transcripts and redacts tool secrets
1.6940219999999897ms
summarizes Codex rollout metadata, context, and pending tool calls
1.7727990000000204ms
reads idle after task_complete even when sampling dropped tool outputs
0.5549079999999833ms
reads idle after turn_aborted with dangling tool calls
0.30752499999999827ms
clears stale pending calls from a prior turn when a new user message arrives
0.4408559999999966ms
stays processing through mid-turn thinking gaps and agent messages
0.6084189999999978ms
maps lsof field output to Codex rollout files by pid
0.31171299999999746ms
recognizes standalone Antigravity processes for CLI daemon passive discovery
0.6402989999999988ms
permission-resolver.test.ts
12 / 12 20ms
permission-resolver 12 / 12
register → resolve(allow) ends the held response with allow
8.531112999999976ms
resolve(deny) ends with deny
0.7399660000000097ms
times out to "ask" after timeoutMs
1.279896000000008ms
resolving an unknown id returns null and is a no-op
0.5781829999999957ms
double resolve: second returns null (already resolved)
0.6276849999999854ms
abandonPending drops the entry without writing a decision
0.8057890000000043ms
sweepStalePending resolves entries older than maxAge to ask
0.7706230000000005ms
re-registering a duplicate requestId resolves the stale entry to ask first
0.7750609999999938ms
resolving over a dead socket does not throw and still clears the entry
1.8850089999999966ms
fires onResolved exactly once on a device decision
1.5946259999999768ms
fires onResolved with "ask" on timeout
0.6720880000000022ms
drainAllPending resolves every held response to ask
0.7280429999999853ms
project-name.test.ts
18 / 18 101ms
resolveProjectName 10 / 10
returns git toplevel basename from a nested subdir
20.578401000000014ms
falls back to nearest package.json name when no git
6.837392999999992ms
skips package.json with empty name and keeps walking
5.219132000000002ms
falls back to cwd basename when no git and no package.json
5.9358139999999935ms
returns 'unknown' for a basename-less root
4.023965000000004ms
AGENTDECK_PROJECT_NAME env var wins over everything
7.181296000000003ms
envOverride option takes precedence over env var
0.45332899999999654ms
preserves scoped package name verbatim
3.782722000000007ms
git subprocess error (non-repo) does not throw
5.51321999999999ms
malformed package.json is ignored (walks to parent)
4.008696000000015ms
gitToplevelBasename 2 / 2
returns null outside a git worktree
3.4945730000000026ms
returns repo basename from nested subdir
11.527614000000028ms
resolveProjectNameFromCwdCached (passive-observer resolver) 4 / 4
matches the PTY resolver for a git repo subdir (launch-path parity)
10.161836999999991ms
detects a .git FILE (worktree/submodule layout)
0.849109999999996ms
falls back to package.json name, then basename
0.9822100000000091ms
memoizes per cwd (stale after dir changes are acceptable)
6.929473999999971ms
nearestPackageJsonName 2 / 2
returns null when no ancestor has package.json
1.8258739999999989ms
returns nearest ancestor name
1.3596359999999663ms
session-aggregator.test.ts
8 / 8 23ms
session-aggregator 8 / 8
uses ownState for the current session without fetching /health
6.816022000000004ms
fetches sibling /health and merges state and modelName
3.3515359999999816ms
marks the session dead when sibling /health fails with no cache
1.0867749999999887ms
returns cached state when sibling /health fails after a previous success
0.7047390000000178ms
clearSiblingStateCache removes cached entry
0.5270869999999945ms
sweeps cached state for sessions that drop out of the active set
0.6868959999999902ms
buildEnrichedSessionsList includes own session and excludes daemon
8.91683599999999ms
buildEnrichedSessionsList returns own session in single-session mode without /health calls
0.6192199999999843ms
session-deck-awaiting.test.ts
4 / 4 8ms
buildSessionDeck detail-view awaiting 4 / 4
renders REAL options (navigable → select_option), not hardcoded Yes/No/Always
6.023948999999988ms
non-navigable inline prompt → respond with the option shortcut
0.5137719999999888ms
observed session (requestId, no options): no fabricated Allow/Deny — only PTY sessions expose real choices
0.5097639999999899ms
awaiting but not remotely answerable (no options, no requestId): no fake action commands
0.4329000000000178ms
timebox-ble.test.ts
10 / 10 12ms
Timebox device identity 1 / 1
uses the BLE address as the device id
2.4576810000000364ms
micro layout (Timebox 11×11) 9 / 9
returns a size²·3 RGB buffer
1.4193370000000414ms
draws a bright dominant creature for a processing session
1.2541079999999738ms
shows only the status field (no bright creature) when no sessions exist
0.6123769999999809ms
tints the field red on critical usage (≥90%)
0.455332999999996ms
draws the Claude robot as a block mark with dark cutout eyes
1.3805540000000178ms
draws the Codex cloud with a visible prompt mark
0.811839999999961ms
draws OpenCode as one tall hollow ring
0.7812119999999823ms
draws OpenClaw with side claws and teal eyes
0.7692610000000286ms
draws the Antigravity rainbow peak with transparent center hollow
0.6668579999999906ms
timeline-orphan-reaper.test.ts
2 / 2 5ms
BridgeTimelineStore.reapOrphanTaskStarts 2 / 2
synthesizes task_end for orphaned task_start rows only
4.1438090000000045ms
lets a real task_end merge over the synthetic by taskId
0.528649999999999ms
timeline-projection-cutover.test.ts
4 / 4 6ms
BridgeTimelineStore projection cutover 4 / 4
default OFF: every entry passes (no behavior change)
5.115186999999992ms
ON: drops locally-emitted chat/tool rows
0.43537500000002183ms
ON: projected (bypass) chat/tool rows pass through
0.2631930000000011ms
ON: task hierarchy + error rows are never suppressed
0.25421600000001376ms
timeline-task-retention.test.ts
4 / 4 359ms
BridgeTimelineStore task-row retention 4 / 4
keeps an in-flight task_start alive through FIFO overflow
255.013657ms
evicts closed task pairs once the task cap is exceeded, oldest first
98.43670900000001ms
getHistoryForSession returns task rows beyond the per-session limit
4.034132999999997ms
loadPersistedEntries keeps task rows past the generic trim
1.4354680000000144ms
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
17.035145999999997ms
patches the anchored sibling with the primary's live fields (matches macOS / Android)
0.7115119999999706ms
uses the primary's projectName for the #N suffix grouping after anchoring
0.5739350000000059ms
preserves the deterministic #N order when primary anchors a sibling slot
1.281819999999982ms
appends a synthetic primary when no sibling shares its agentType
0.45549299999998993ms
skips the synthetic primary when a sibling shares agentType but no port match (duplicate guard)
0.4218399999999747ms
never appends primary when agentType is daemon or openclaw
0.39300700000001143ms
buildHudEntries — virtual OpenClaw 2 / 2
inserts a virtual OpenClaw row when gateway is available and sessions has none
0.4864509999999882ms
does not insert a virtual row when sessions already contains an openclaw entry
0.39796499999999924ms
buildHudEntries — hotkey eligibility (sibling-only) 1 / 1
primary and virtual rows do not consume hotkey slots
0.41924499999998943ms
formatTaskEvalSuffix — task_end badge for each outcome class 6 / 6
renders ✓ for success
0.3192280000000096ms
renders ✗ for fail
0.21810799999997244ms
renders △ for partial
0.22624400000000833ms
renders ⊘ for abandoned (manual cancel)
0.21277800000001434ms
renders ? as score placeholder when judge has not produced a number yet
0.25224200000002384ms
returns empty string while the eval is still pending (outcome undefined)
0.288078999999982ms
usage-event.test.ts
7 / 7 7ms
buildUsageEvent subscription quota scoping 4 / 4
omits Anthropic quota when the model is not yet known
4.141073000000006ms
omits Anthropic 5h/7d quota for GLM/API-backed models
0.72861400000005ms
keeps Anthropic 5h/7d quota on the daemon hub even with a non-Claude aggregate model
0.42910399999999527ms
keeps Anthropic 5h/7d quota for Claude model aliases
0.39143300000000636ms
buildUsageEvent Codex window normalization 3 / 3
marks an expired window stale and drops its resetsAt (no misleading "now")
0.7279929999999695ms
leaves a live window untouched
0.38135399999998754ms
treats each window independently (5h expired, 7d live)
0.4316079999999829ms
windows-service.test.ts
6 / 6 7ms
xmlEscape 1 / 1
escapes XML metacharacters
3.4110760000000084ms
buildScheduledTaskXml 5 / 5
produces a well-formed v1.2 task with a logon trigger
0.7504050000000007ms
mirrors LaunchAgent KeepAlive / no-stop semantics
0.7159499999999923ms
uses node as unquoted Command and quotes the cli.js path in Arguments
0.2937000000000012ms
XML-escapes special characters in the user id and paths
0.5102950000000135ms
places both UserId fields (trigger + principal) with the same user
1.0694520000000125ms
codex-install.test.ts
32 / 32 35ms
codex-mini-toml: applyManagedBlock 4 / 4
appends fence when absent
4.390730999999988ms
replaces existing fence block
0.8015310000000113ms
apply twice is idempotent
0.40032899999999927ms
moves Codex hook trust state out of the managed fence
0.6338369999999998ms
codex-mini-toml: removeManagedBlock 2 / 2
leaves user content
0.6486650000000225ms
is idempotent without fence
0.20271900000000187ms
codex-mini-toml: hasTopLevelKeyOutsideFence 3 / 3
detects user notify key
0.4337419999999952ms
ignores notify key inside table
0.27225000000001387ms
ignores notify key inside fence
0.23924699999997756ms
codex-mini-toml: hasTableOutsideFence 6 / 6
detects user [otel] table
0.392074000000008ms
detects user [otel.exporter] dotted table
0.2582830000000058ms
detects array-of-table header [[hooks.Stop]]
0.310861999999986ms
ignores Codex hook trust state outside fence
0.28750800000000254ms
ignores [otel] inside fence
0.22938899999999762ms
ignores [otelfoo] (word boundary)
0.24290500000000748ms
codex-mini-toml: quoted 3 / 3
escapes backslash and double quote
0.26618799999999965ms
escapes newline and tab
0.1872500000000059ms
passes simple ASCII
0.19988399999999729ms
codex-install: managedBlockBody 3 / 3
roundtrip preserves user TOML byte-for-byte (load-bearing)
1.967835000000008ms
matches Codex schema (lifecycle hooks + endpoints + notify dummy)
2.205799999999982ms
omits conflicting optional channels when asked
0.8102969999999914ms
codex-install: install / uninstall (file I/O) 11 / 11
creates config with fence when file is absent
4.150380999999982ms
preserves user content when installing into existing config
1.9258450000000096ms
skips when user already has [features] table outside fence
0.86026099999998ms
skips when user already has [hooks] table outside fence
0.8000780000000134ms
omits notify when user has top-level notify
2.0168140000000108ms
omits OTel when user has [otel] table
1.1792279999999948ms
uninstall strips fence and preserves user content
1.423105000000021ms
uninstall is idempotent when no config exists
1.2079719999999838ms
honours AGENTDECK_NO_CODEX_HOOKS=1 opt-out
0.5151039999999796ms
install is idempotent (same port → no rewrite)
1.2576540000000023ms
preserves Codex hook trust state across reinstall
2.730672999999996ms
reconnect-supervisor.test.ts
8 / 8 5ms
ReconnectSupervisor 8 / 8
connects once on start and reports the first open without firing onReconnect
3.1878890000000126ms
reconnects with backoff after a drop and fires onReconnect on re-open
0.552976000000001ms
ignores the spurious close emitted while a connect is in flight
0.23289600000001087ms
retries via connect-timeout when an attempt neither opens nor closes
0.23722400000002608ms
escalates the backoff ladder across consecutive failed attempts
0.26122900000001437ms
forces a fresh connect on wake even when the socket looked open (half-open)
0.3737899999999854ms
reconnects immediately on wake while disconnected (backoff reset)
0.2320850000000121ms
stop() halts the watchdog so wake no longer reconnects
0.19253999999997973ms
bridge-client.test.ts
3 / 3 3.4s
BridgeClient — port provider 3 / 3
skips connect when provider returns null
56.54891299999997ms
connects once provider returns a live port
1263.5795739999999ms
rebinds to a new port when provider value changes
2104.962616ms
encoder-offline-policy.test.ts
3 / 3 5ms
renderOfflineTouchStrip — all-or-nothing 800px slice contract 3 / 3
every slice is a 200x100 canvas carrying the shared banner content
4.10074800000001ms
slices 0..3 offset the same banner by -index*200 (E0..E3 align into one strip)
0.5848950000000173ms
uses a per-slice gradient id so the four panels are independent SVGs
0.47247499999997444ms
session-slot-button.test.ts
12 / 12 6ms
computeCenterSlot 6 / 6
SD+ 4x2 → bottom-center
2.7845739999999637ms
SD MK2 5x3 → true geometric center
0.28347099999996317ms
SD XL 8x4 → middle row, mid column
0.21540399999997817ms
SD Mini 3x2 → bottom-center
0.24450799999999617ms
single key device → slot 0
0.20650699999998778ms
clamps degenerate zero rows/cols to slot 0
0.20808899999997266ms
computeCenterCluster 6 / 6
SD+ 4x2 → 2x2 cluster on geometric center (slots 1,2,5,6)
1.1759819999999763ms
SD XL 8x4 → 2x2 cluster on geometric center (slots 11,12,19,20)
0.31477899999998726ms
SD MK2 5x3 → single full hero on slot 7
0.2686729999999784ms
SD Mini 3x2 (odd cols) → single full hero on slot 4
0.1980310000000145ms
single-key device → single full hero on slot 0
0.23073199999998906ms
degenerate zero dimensions → single hero on slot 0
0.20827999999994518ms
session-slot-manager.test.ts
28 / 28 48ms
SessionSlotManager detail layout 12 / 12
re-points detail focus onto the codex fold representative when the focused thread is absorbed
6.8455940000000055ms
exits detail view when the focused session is gone with no fold successor
0.5208650000000148ms
folds codex companion threads by project before slot assignment
2.544934000000012ms
renders connected no-session list as status cards instead of text-only empty buttons
0.915093000000013ms
puts processing tool info before OpenClaw presets
1.9795759999999518ms
keeps a processing status tile even before tool metadata arrives
0.4701600000000212ms
aliases the model name on detail MODEL surfaces (status card + OpenClaw preset)
1.1163000000000238ms
renders the MODEL tile exactly once in Claude PROCESSING detail (no duplicate)
1.0397459999999796ms
does not duplicate MODEL on OpenClaw idle (preset + status card)
0.6499469999999974ms
does not render a READY/idle tile while a Claude session is PROCESSING
0.5610200000000418ms
does not render a STANDBY/idle tile while an OpenClaw session is PROCESSING
0.5748669999999834ms
uses actual parser options and reserves MORE only when awaiting overflow exists
0.7374500000000239ms
SD+ keypad relocation (Phase 2) 4 / 4
AWAITING permission renders selectable option buttons + ESC on the SD+ keypad
0.8666819999999689ms
shows a SUGGESTED quick-send button leading the IDLE detail content on SD+
0.8830229999999801ms
does NOT add a SUGGESTED button on classic Stream Deck (behavior unchanged)
0.7228729999999928ms
drops the SUGGESTED button when the session leaves IDLE
0.6314319999999611ms
SessionSlotManager list-view usage tiles 12 / 12
pins Claude 5H/7D to the last two keys of a classic Stream Deck (no Codex)
13.919486000000063ms
reserves 4 keys (Claude 5h/7d + Codex 5h/7d), left-aligned, when both agents report quota
0.8907480000000305ms
hides Codex tiles when only Claude reports quota (reserve 2, not 4)
0.7523579999999583ms
hides Claude tiles when only Codex reports quota (reserve 2 Codex tiles)
0.8116489999999885ms
does NOT reserve usage on Stream Deck+ (encoder carries usage)
1.1154480000000149ms
reserves NO usage keys when no quota was fed (hide-if-absent)
0.48153100000001814ms
drops Claude tiles when its quota goes stale (hide-if-absent on stale)
0.6178070000000844ms
fits 13 sessions on a classic deck without paging (15 keys − 2 usage)
1.8706620000000385ms
paginates over capacity: NEXT→ at slot 12, usage at 13/14
0.8823520000000826ms
repositions NEXT→ ahead of a 4-key usage block when paginating
1.0310800000000881ms
pressing a usage tile resolves to refresh-usage
0.374761000000035ms
shows usage tiles even with zero sessions
0.40509800000006635ms
usage-encoder.test.ts
8 / 8 6ms
buildClaudeUsageEncoder 4 / 4
maps the top-level 5h/7d quota to two known tanks
3.7486789999999814ms
shows "Waiting…" before the first payload
0.19287099999999668ms
shows "No usage data" when data arrived but the quota is absent
0.2220649999999864ms
treats stale data as unknown (suppresses the tanks)
0.18597800000000575ms
buildCodexUsageEncoder 4 / 4
maps codexRateLimits primary→5h, secondary→7d
0.41382499999997435ms
falls back to a muted note when Codex reports no rate limits
0.23124400000000378ms
shows "Waiting…" before the first payload
0.13694699999999216ms
renders only the windows Codex actually reports (partial)
0.19141899999999623ms
d200h-layout.test.ts
12 / 12 16ms
usage tiles — usageKnown tri-state 8 / 8
renders a percent when the quota is known
3.817698000000007ms
renders a muted "—" instead of a confident 0% when unknown
0.40556900000001406ms
defaults to known (percent) when the flag is omitted
0.236723000000012ms
wide slot shows "—" for both columns when unknown
0.5316349999999943ms
wide slot shows percents when known
0.2419230000000141ms
parseState infers usageKnown=false when no percent fields are present
0.39889800000000264ms
parseState infers usageKnown=true when a percent is present
0.23788499999997725ms
parseState honors an explicit usageKnown=false even with a coerced 0 percent
0.24340499999999565ms
buildSessionDeck — daemon offline 4 / 4
renders the OFFLINE hero on the center key for a DISCONNECTED state
2.9675359999999955ms
makes EVERY key launch the companion app while offline
2.06894299999999ms
does not show OFFLINE / launch when the daemon is connected
1.41186399999998ms
shows the session list (not OFFLINE) when state is disconnected but sessions exist
2.7772999999999968ms
format-utils.test.ts
24 / 24 10ms
adjustUsagePercent 11 / 11
returns undefined when percent is null
3.9011350000000107ms
returns undefined when percent is undefined
0.27598699999998644ms
returns percent unchanged when resetsAt is null
0.4160190000000057ms
returns percent unchanged when resetsAt is undefined
0.2183689999999956ms
returns percent unchanged when resetsAt is in the future
0.43837100000001783ms
returns 0 when resetsAt is in the past (window expired)
0.2252019999999959ms
returns 0 when resetsAt equals now (edge case)
0.2266040000000089ms
handles invalid date string gracefully (returns percent)
0.20435299999999756ms
handles empty string resetsAt (returns percent)
0.19395299999999338ms
returns percent unchanged when resetsAt is far in the past (>1h)
0.2001239999999882ms
still returns 0 just after the 1h threshold boundary
0.2564399999999978ms
isCodexWindowStale 6 / 6
returns false when resetsAt is undefined
0.23969800000000419ms
returns false for an invalid date string
0.1885740000000169ms
returns false when resetsAt is in the future
0.23604199999999764ms
returns false when resetsAt is in the past but within the grace window
0.1986919999999941ms
returns true when resetsAt is past beyond the grace window
0.19505499999999643ms
honors a custom grace
0.2495270000000005ms
formatResetTime 7 / 7
returns "now" when resetsAt is in the past
0.33093999999999824ms
returns undefined for null input
0.18534700000000726ms
returns minutes-only for < 1h remaining
0.29241799999999785ms
returns hours and minutes for < 24h remaining
0.2725599999999986ms
returns days and hours for >= 24h remaining
0.24371700000000374ms
omits minutes when exactly on the hour
0.23868600000000129ms
passes through pre-formatted strings (no T)
0.16905700000000934ms
llm-settings.test.ts
10 / 10 12ms
llm-settings 10 / 10
returns defaults when settings.json is missing
4.486580000000004ms
reads llm.mlx pin from settings.json
1.002336999999983ms
treats "qwen3-30b" and "default" as placeholders (unpinned)
1.0867350000000044ms
falls back to apme.judge.model when llm.mlx is absent
0.39673300000001177ms
strips /chat/completions suffix from legacy endpoints
0.675485000000009ms
prefers llm.mlx over apme.judge when both set
0.4723940000000084ms
resolveMlxModel: pin > probe > fallback
1.1008309999999994ms
pickMlxModel: 4-layer priority (pin > fallback > first > null)
0.9339290000000062ms
mlxChatUrl reflects endpoint setting
0.5861570000000142ms
caches result for TTL window
0.9287290000000041ms
session-deck-usage.test.ts
13 / 13 20ms
buildSessionDeck list-view usage tiles 13 / 13
pins 5H/7D to the block above the wide button and wires them to query_usage
12.44251700000001ms
does not reserve usage slots when showUsage is off (regression: full grid)
1.3251109999999926ms
draws "—" when usage is unknown
0.3513770000000136ms
fits sessions into the 13 non-usage keys without paging
0.7582899999999881ms
paginates when sessions exceed capacity, NEXT→ sits on the last free key
1.3632120000000327ms
page 2 keeps the usage tiles pinned and shows the remainder
0.6326750000000061ms
shows usage even with zero sessions
0.44717699999995375ms
appends Codex 5H/7D below Claude when codexRateLimits is present (each datum)
0.7675370000000044ms
renders only the Codex window whose datum exists
0.6180370000000153ms
shows a credits tile when Codex reports a credit-based plan (null windows)
0.5591670000000022ms
renders ∞ for an unlimited-credits Codex plan
0.3922539999999799ms
falls back to trailing keys on a tiny deck where the block is not placed
0.48673100000002023ms
never starves the only key on a 1-key deck (usage yields to the session)
0.38382899999999154ms
session-utils.test.ts
16 / 16 18ms
OpenClaw visibility SSOT 2 / 2
isOpenClawSessionActive is true only when gatewayConnected
3.440662000000003ms
hasOpenClawSession detects an emitted openclaw session
0.3350770000000125ms
agentTypeRank 1 / 1
ranks openclaw first, then claude-code, codex-cli, codex-app, opencode, antigravity, others
0.3756230000000187ms
naturalLabelCompare 2 / 2
orders numeric chunks naturally (Agent 2 before Agent 10)
8.743630999999993ms
treats undefined as empty string
0.20223900000002004ms
sortSessions 6 / 6
places openclaw before claude-code regardless of project
0.9037319999999909ms
sorts by project name within the same agent type
0.26144899999999893ms
sorts numbered project names naturally (#2 before #10)
0.22979000000000838ms
breaks ties on startedAt ascending (oldest first)
0.20187800000002198ms
falls back to id natural-compare when startedAt ties to the same ms
0.2473630000000071ms
does not mutate the input array
0.24190300000000775ms
foldCodexSessionsForDisplay 1 / 1
folds Codex CLI and Codex App separately even with the same project
1.4201490000000092ms
assignDisplayNames 4 / 4
passes single sessions through without #N suffix
0.3222939999999994ms
adds #1/#2 suffixes for duplicate (project, agentType) tuples in input order
0.2712980000000016ms
numbers same project across different agentTypes independently
0.2742839999999944ms
produces the same #N assignment as a deterministic sort + display pipeline
0.32919599999999605ms
svg-renderers/model-alias.test.ts
7 / 7 4ms
aliasModelName 3 / 3
shortens claude family-major-minor
2.7114270000000147ms
drops trailing date suffix on claude releases
0.1909170000000131ms
passes gpt and unknown strings through unchanged
0.19594699999998966ms
formatModelEffort 4 / 4
returns aliased model when no effort to show
0.304048999999992ms
appends non-default effort when it fits
0.14576199999999062ms
truncates aliased model name to fit budget with effort suffix
0.236331999999976ms
returns empty string for missing model
0.12794999999999845ms
text-sanitize.test.ts
5 / 5 7ms
stripUnsafeText 4 / 4
strips ANSI CSI sequences but keeps the visible text
4.840823999999998ms
strips OSC sequences and bare ESC forms
0.42464499999999816ms
strips XML-invalid control characters but keeps tab/newline
0.7158200000000079ms
strips lone surrogate halves but keeps full emoji
0.46066200000001345ms
escSvgText 1 / 1
entity-escapes after stripping
0.38047299999999495ms
timeline-summarizer.test.ts
13 / 13 8ms
extractTopicHintWithKind — Korean polite-closer robustness 7 / 7
returns the cleaned topic when the response opens with "네, …"
4.481051000000008ms
returns the original (kind=fallback) when the entire response is just a polite closer
0.3873049999999978ms
returns null for empty / very short text (still)
0.3044500000000028ms
skips lone heading markers and code fences
0.45493099999998776ms
a heading WITH text becomes the topic (heading is the title)
0.2275459999999896ms
strips list bullet markers
0.23808500000001231ms
extractTopicHint convenience returns just the hint string
0.2575119999999913ms
promptSnippetFallback 6 / 6
returns first sentence trimmed
0.29389000000000465ms
returns whole string when no sentence terminator
0.18249100000002727ms
truncates to maxLen with ellipsis
0.36322000000001253ms
cuts at first newline if no sentence terminator
0.15094299999998384ms
returns null for empty / very short input
0.2311329999999998ms
handles Korean prompts
0.18512699999999427ms
timeline-task-hierarchy.test.ts
41 / 41 14ms
deduplicateEntry — task hierarchy 4 / 4
always adds task_start even with identical raw within 8s
2.8385840000000258ms
always adds task_end with same boundarySignal back-to-back
0.2938609999999926ms
always adds task_milestone even with identical raw within 8s
0.19328099999998472ms
still dedupes ordinary chat_start within 8s
0.2223459999999875ms
timelineIconKey 5 / 5
maps task entries to "task"
0.2718490000000031ms
maps tool_request status to success/error/awaiting
0.2177870000000155ms
chat_start in flight is "running"; chat_end is "success"
0.20048499999998626ms
error → error; user_action → user; memory_recall → memory
0.17180099999998788ms
every key has an e-ink glyph of constant 4-char width
0.3177949999999896ms
isInFlightTask 5 / 5
task_start without matching task_end is in flight
0.2373439999999789ms
task_start whose task_end (same taskId) appeared is finished
0.1503409999999974ms
mismatched taskId on task_end does not close it
0.13648599999999078ms
task_start without taskId is never considered in flight
0.13269900000000234ms
non-task_start entries are never in flight
0.2131689999999935ms
isRotatingEntry 5 / 5
chat_start always rotates (icon-key running)
0.15445899999997437ms
orphan task_start rotates via in-flight predicate
0.13150600000000168ms
closed task_start does not rotate
0.12504399999997418ms
static rows do not rotate
0.2547569999999837ms
eval_result and task_end never rotate
0.14722600000001762ms
parseTimelineMarkdown 9 / 9
returns single text line for plain text
1.1333009999999888ms
parses headings 1-6 with required space
0.5765390000000252ms
parses bullets and numbered lists
0.40029899999998975ms
handles code fence — verbatim lines, not interpreted
0.21037400000000162ms
blank line → blank kind
0.18161999999998102ms
parses tables with header separator
0.46400900000000433ms
parses tables without separator (no header)
0.26628900000000044ms
table block ends at first non-table line
0.23216399999998316ms
quote lines parse
0.20977300000001264ms
parseInlineSpans 9 / 9
returns empty for empty string
0.2818680000000029ms
returns single plain span for plain text
0.26544699999999466ms
parses **bold**
0.18533699999997566ms
parses *italic* (single star)
0.21192700000000286ms
parses `code` inline
0.16325599999998985ms
parses [text](url) link
0.1666620000000023ms
unclosed ** falls back to plain
0.15217499999999973ms
multiple spans in one line
0.2054550000000006ms
first-match-wins: ** consumed before * (no double-italic split)
0.1797070000000076ms
prepareMarkdownDetail 4 / 4
preserves markdown markers (chat-response detail goes to client)
0.494876000000005ms
still filters system JSON blobs
0.2969669999999951ms
collapses 3+ blank lines but keeps double-blank paragraph break
0.23727499999995416ms
contrasts with cleanDetailText which strips markdown (non-chat path)
0.81417399999998ms
Android PASS
JUnit + Robolectric · 14 files · 195 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.BridgeDiscoveryTest
2 / 2 12ms
ws url uses primary host and preserves pairing token
12ms
fallback url is absent without a fallback host
net.ProtocolTest
34 / 34 5.2s
parse state_update with all permission modes
4147ms
parse connection connected with sessionId
40ms
parse sessions_list
49ms
PluginCommands selectOption generates valid JSON
61ms
parse timeline_event with fractional timestamps
67ms
parse button_state
46ms
PluginCommands utility with and without value
34ms
parse invalid json returns null
48ms
parse timeline_history
27ms
parse timeline_event upsert
28ms
parse state_update with processing state and tool info
28ms
PluginCommands respond escapes special characters
37ms
parse display_state with dim instruction
35ms
PluginCommands respond generates valid JSON
42ms
parse state_update with permission options
30ms
parse connection disconnected
43ms
parse missing type returns null
32ms
parse deck_slot_map
27ms
parse usage_update with extra usage
29ms
parse state_update with ollama status
26ms
PluginCommands navigateOption
24ms
parse state_update with agent capabilities
23ms
parse unknown type returns null
32ms
parse user_prompt
24ms
BridgeTimelineEntry converts to TimelineEntry
24ms
parse state_update with model catalog
32ms
parse state_update ignores unknown fields
22ms
parse state_update with idle state
18ms
parse display_state sleep and wake
27ms
parse voice_state
20ms
parse encoder_state
18ms
PluginCommands interrupt and escape
19ms
parse usage_update with rate limits
18ms
parse timeline_event
18ms
state.SessionMetricsTest
8 / 8 7ms
reset clears all metrics
6ms
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
9 / 9 11ms
synthetic response-less turn is hidden completely
4ms
multi-agent dashboard timeline projects meaningful session rows
4ms
progress chat_response and progress chat_end are hidden
chat_end is hidden when chat_start already represents a response-less turn
codex tool entries are suppressed from device timeline
1ms
synthetic chat_start is suppressed once completion arrives
task notification chat_start is suppressed
1ms
chat_end is hidden when chat_response already represents the same turn
1ms
same timestamp summaries stay separate by agent and project
state.TimelineStoreTest
50 / 50 42ms
addEntry drops openclaw placeholder with status-only detail
6ms
timelineDisplayGroups hides model_call after model_response in same run
1ms
addEntry allows same type+summary after 5s
1ms
addEntries filters otel noise from bulk replay
3ms
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 merges a meaningful chat_start with its response into one turn
groupConsecutive empty list returns empty
addEntry drops openclaw placeholder tool rows
timelineLifecycleBounds pairs response with prior start
upsertEntry adds new entry if no match
1ms
addEntry stores entry
groupConsecutive does not merge tool_request across sessions
groupConsecutive groups same summary within 60s
timelineDisplayGroups keeps independent sessions visible
1ms
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
1ms
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
addEntry deduplicates within 5s window
upsertEntry propagates summaryKind progression heuristic to llm
timelineDisplayGroups collapses synthetic chat_start once response arrives
2ms
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
9ms
groupConsecutive does not merge distinct run ids on same session
1ms
groupConsecutive folds a whole chat_start-response-end turn into one row
timelineDisplayGroups keeps in-flight start when later completion has distinct run id
addEntry drops codex tool_exec from normal codex session
1ms
addEntry keeps openclaw placeholder summary when detail has content
groupConsecutive requires same summary for other types
addEntry normalizes openclaw cron model_call prompt dump
4ms
updateLastOfType no-op if type not found
groupConsecutive groups tool_request within 10s
1ms
addEntry drops codex tool_exec even when raw is meaningful
upsertEntry merges task_end by taskId beyond the 1s tolerance window
state.TimelineTaskHierarchyTest
29 / 29 23ms
OpenClaw NO_REPLY polling responses are hidden from display projection
mismatched taskId on task_end does not close it
1ms
OpenClaw automated polling chat starts are hidden from display projection
1ms
stripMarkdownInline drops markers including table syntax
4ms
detail redundancy fires when prefix matches summary
1ms
detail redundancy does not fire when content is genuinely new
same project two sessions are not the same context anymore
1ms
closed task_start does not rotate
non task_start entries are never in flight
task_start whose task_end (same taskId) appeared is finished
static rows do not rotate
session_end task boundary is hidden from display projection
3ms
stripMarkdownInline preserves non-table pipes
1ms
task_start without matching task_end is in flight
idle_gap task boundary is hidden from display projection
chat_start always rotates via icon-key running
1ms
task entries never group with each other
iconKey resolves tool_request status to success error awaiting
taskId is the strongest grouping key
OpenClaw LINE notification failures stay visible
iconKey resolves to Task for task entries
eval_result and task_end never rotate
1ms
manual task boundary is visible in display projection
stripMarkdownInline handles single-cell table row
markdown parser parity with shared - basics
2ms
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
8 / 8 225ms
claude processing does not bleed into OpenClaw crayfish on aggregate view
91ms
emitted OpenClaw session shows OpenClaw at rest
21ms
gateway error without an emitted session does not spawn a creature
21ms
gateway error with a live session surfaces sick OpenClaw
17ms
OpenClaw processing routes its own crayfish
15ms
reachable gateway without an emitted session hides OpenClaw and workers
17ms
stuck gatewayConnected without an emitted session still hides OpenClaw
17ms
daemon aggregate keeps OpenClaw crayfish calm while claude works
25ms
terrarium.renderer.EinkAnimationTimingTest
3 / 3 4ms
animation frame advance is elapsed-time based and bounded
2ms
fish simulation scales movement for partial color frames
2ms
color e-ink animation uses video-like cadence
ui.eink.EinkAttentionPanelTest
3 / 3 14ms
non-focused awaiting session hides unavailable live prompt fields
12ms
primary awaiting session is surfaced when not represented by siblings
featured attention prefers focused awaiting session
2ms
ui.eink.SessionDisplayOrderingTest
6 / 6 3ms
naturalLabelCompare orders Agent 2 before Agent 10
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
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
1ms
bare date in past renders renewal needed
future ISO8601 with fractional seconds renders date suffix
1ms
subscriptionTrailing returns date for future
parseUntilInstant accepts blank as null
past until renders renewal needed
bare date string parses as UTC midnight
1ms
subscriptionTrailing returns null for blank or null
null until renders name only
util.TimeFormatUtilsTest
24 / 24 19ms
gaugeBar clamps below 0
1ms
formatCount thousands show K
1ms
formatBytes kilobytes
formatDurationCompact seconds
formatDurationCompact exact minutes no seconds
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
gaugeBar custom width
windowLabel maps minutes to compact day-hour-minute labels
4ms
formatBytes gigabytes
codexLimitRows maps primary and secondary windows with agent tag
5ms
codexLimitRows skips windows with null usedPercent
formatUptime zero returns 0 colon 00
codexLimitRows returns empty when limits null
formatCount millions show M
1ms
formatDurationCompact minutes
1ms
gaugeBar 100 percent is all filled
Robot Framework FAIL
ESP32 Hardware Tests · 1 suites · 4 scenarios · 7 tests · 4 boards
BoardBuildFlash+BootBoot TimeFW SizeBoot HeapLatency
Round0.6s
IPS 3.5"0.6s
TC0010.6s
86Box115.8s
01_build.robot no-hwquicksmoke
3 / 7
Build And Verify 4 boards 1 / 4
Given the "${board}" firmware is built
Then the firmware binary should exist for "${board}"
And the firmware size should be sane for "${board}"
And the partitions binary should exist for "${board}"
✓ 86Box✗ IPS 3.5"✗ Round✗ TC001
Box 86 Build And Verify
1m 56s
IPS 3.5 Build And Verify
PlatformIO build failed for ips_35: UnknownEnvNamesError: Unknown environment names 'ips_35'. Valid names are 'rgb48, amoled, ips10, boot_test_qspi, display_test, led8x32, qspi_test, esp32_c6_147, ips35, axs_test, inkdeck, box_86, ttgo': 1 != 0
606ms
Round AMOLED Build And Verify
PlatformIO build failed for round_amoled: UnknownEnvNamesError: Unknown environment names 'round_amoled'. Valid names are 'box_86, inkdeck, ips35, display_test, ttgo, esp32_c6_147, led8x32, boot_test_qspi, qspi_test, rgb48, axs_test, amoled, ips10': 1 != 0
606ms
Ulanzi TC001 Build And Verify
PlatformIO build failed for ulanzi_tc001: UnknownEnvNamesError: Unknown environment names 'ulanzi_tc001'. Valid names are 'boot_test_qspi, qspi_test, amoled, led8x32, display_test, ttgo, esp32_c6_147, rgb48, box_86, ips35, axs_test, inkdeck, ips10': 1 != 0
606ms
Boot Test Environment Builds Successfully
PlatformIO build failed for boot_test: UnknownEnvNamesError: Unknown environment names 'boot_test'. Valid names are 'ips10, boot_test_qspi, qspi_test, esp32_c6_147, amoled, rgb48, ips35, display_test, led8x32, box_86, ttgo, inkdeck, axs_test': 1 != 0
605ms
Source Files Are Present
PlatformIO Configuration Parses Cleanly
704ms
Scenario Coverage
User scenario mapping against actual test results
5 covered 5 partial/missing 10 with identified gaps
Score Scenario Priority Unit Integ. Platform E2E
6/8
Session Lifecycle
Start session -> processing -> idle -> stop. Core state machine transitions that drive all UI.
  • No end-to-end test with real Claude PTY process
  • No Android UI test for state transitions
critical 4/41/21/2
3/5
Permission Flow
Agent requests permission -> user sees options -> approves/denies -> state transitions back.
  • No multi-option navigation end-to-end test
  • No encoder dial interaction test for option scrolling
critical 2/20/21/1
7/7
Multi-agent Monitoring
Daemon hub orchestrates multiple session bridges, unified dashboard for all agents.
  • No daemon + session bridge coordinated test
  • No multi-agent state aggregation test
high 3/34/4
7/7
Device Connection
mDNS discovery -> auth token validation -> WebSocket/serial state sync with dashboard clients.
  • No real mDNS discovery test
  • No ADB reverse tunnel test
  • No auth token rejection test
high 3/33/31/1
4/5
Timeline Aggregation
Events from multiple sessions -> daemon relay -> dedup -> unified timeline for all clients.
  • No daemon-to-client relay end-to-end test
  • No LLM summary enrichment test
high 2/21/11/2
1/1
Voice Recording & Transcription
Audio capture -> whisper transcription -> text delivery to Claude PTY or clipboard.
  • No audio recording unit test
  • No recording -> transcription -> paste end-to-end
  • No Android voice recording test
  • No silence detection unit test
medium 1/1
2/3
Encoder & Button Interaction
Dial rotate -> option scroll -> push select. Button press -> action trigger. Label rendering.
  • No encoder rotate/push integration test
  • No wide canvas takeover test
  • No Android Deck gesture test
medium 2/3
4/5
Usage Tracking & Rate Limits
API usage fetch -> rate limit gauge -> sibling relay (429 prevention) -> dashboard display.
  • No real API rate limit response test
  • No usage_update WS relay end-to-end
medium 0/12/22/2
2/2
Daemon Singleton Guard
PID check -> port probe -> prevent double daemon. Auto-fallback on port conflict.
  • No port conflict auto-fallback test
  • No LaunchAgent KeepAlive loop prevention test
medium 1/11/1
1/1
Hook Installation & Migration
Install Claude Code hooks -> migrate v2.0 flat format to v2.1 matcher groups -> port injection.
  • No real settings.local.json file test
  • No hook execution verification test
medium 1/1
Coverage
v8 provider · 20,540 lines tracked
Lines ≥17%: 40.6%
Functions ≥15%: 37.4%
Branches ≥14%: 36.6%
Statements ≥16%: 39.1%
bridge
39% Lines
38% Stmts
38% Funcs
35% Branch
6000/15235 lines covered
plugin
35% Lines
33% Stmts
27% Funcs
30% Branch
1229/3548 lines covered
shared
58% Lines
56% Stmts
57% Funcs
51% Branch
815/1415 lines covered
hooks
84% Lines
82% Stmts
88% Funcs
75% Branch
225/269 lines covered
File Stmts Branch Funcs Lines
bridge/src/check-deps.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-transcript-timeline.ts 0% 0% 0% 0%
bridge/src/terminal-status.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/apme/dashboard-html.ts 0% 100% 0% 0%
bridge/src/apme/types.ts 0% 0% 0% 0%
bridge/src/idotmatrix/idotmatrix-discover.ts 0% 0% 0% 0%
bridge/src/modules/adb-module.ts 0% 0% 0% 0%
bridge/src/modules/broadcast-module.ts 0% 100% 0% 0%
bridge/src/modules/idotmatrix-module.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/timebox-module.ts 0% 0% 0% 0%
bridge/src/modules/types.ts 0% 0% 0% 0%
bridge/src/timebox/timebox-discover.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/daemon-server.ts 0% 1% 1% 0%
bridge/src/voice.ts 1% 0% 0% 1%
bridge/src/wake-word.ts 2% 0% 0% 2%
bridge/src/voice-assistant.ts 2% 0% 0% 2%
bridge/src/apme/index.ts 2% 0% 0% 2%
bridge/src/pixoo/pixoo-discover.ts 2% 11% 12% 3%
bridge/src/modules/d200h-module.ts 3% 0% 0% 3%
bridge/src/adb-reverse.ts 3% 0% 0% 4%
bridge/src/pixoo/pixoo-font.ts 3% 0% 0% 4%
bridge/src/whisper-server-manager.ts 4% 0% 0% 4%
bridge/src/apme/hw-sampler.ts 6% 4% 20% 4%
bridge/src/tts.ts 4% 0% 0% 5%
bridge/src/antigravity-local.ts 6% 3% 18% 5%
bridge/src/ollama-probe.ts 5% 0% 0% 5%
bridge/src/session-focus-relay.ts 5% 0% 0% 5%
bridge/src/broadcast.ts 5% 0% 0% 6%
bridge/src/tui/dashboard.ts 5% 11% 3% 6%
bridge/src/mlx-probe.ts 6% 0% 0% 6%
bridge/src/timebox/timebox-daemon-sync.ts 5% 0% 0% 6%
bridge/src/cli.ts 6% 0% 1% 7%
bridge/src/wifi-config.ts 6% 0% 0% 7%
bridge/src/apme/outcome.ts 8% 2% 8% 8%
bridge/src/idotmatrix/idotmatrix-settings.ts 7% 0% 0% 8%
bridge/src/pixoo/pixoo-settings.ts 7% 0% 0% 8%
bridge/src/pixoo/pixoo-client.ts 10% 0% 0% 10%
bridge/src/d200h/image-renderer.ts 10% 9% 16% 10%
bridge/src/timebox/timebox-settings.ts 8% 6% 8% 10%
bridge/src/pixoo/pixoo-camera.ts 11% 6% 6% 11%
bridge/src/d200h/hid-protocol.ts 11% 0% 0% 12%
bridge/src/mdns.ts 14% 28% 25% 12%
bridge/src/pixoo/pixoo-bridge.ts 11% 0% 0% 12%
bridge/src/logger.ts 17% 10% 14% 14%
bridge/src/timeline-summarizer.ts 13% 0% 0% 15%
bridge/src/idotmatrix/idotmatrix-daemon-sync.ts 13% 0% 0% 15%
bridge/src/pixoo/pixoo-sprites.ts 14% 0% 12% 15%
bridge/src/gateway-probe.ts 12% 0% 0% 16%
bridge/src/foundation-models-helper.ts 24% 16% 36% 24%
bridge/src/usage-api.ts 23% 13% 50% 24%
bridge/src/esp32-serial.ts 27% 23% 22% 28%
bridge/src/display-monitor.ts 27% 30% 28% 28%
bridge/src/pixoo/pixoo-renderer.ts 30% 30% 32% 32%
bridge/src/session-activity.ts 29% 30% 42% 34%
bridge/src/codex-auth.ts 36% 8% 25% 37%
bridge/src/bridge-core.ts 38% 41% 26% 40%
bridge/src/codex-rate-limits.ts 43% 55% 55% 43%
bridge/src/usage-tracker.ts 44% 55% 23% 44%
bridge/src/opencode-client.ts 40% 38% 57% 44%
bridge/src/adapters/opencode-adapter.ts 41% 29% 35% 44%
bridge/src/ble-sync-spawn.ts 43% 30% 38% 46%
bridge/src/model-catalog.ts 39% 17% 36% 46%
bridge/src/windows-service.ts 50% 83% 44% 52%
bridge/src/passive-observer.ts 48% 42% 43% 54%
bridge/src/hook-server.ts 53% 29% 54% 55%
bridge/src/ws-server.ts 56% 33% 55% 55%
bridge/src/pty-manager.ts 55% 31% 53% 56%
bridge/src/apme/antigravity-transcript.ts 63% 69% 33% 62%
bridge/src/auth.ts 59% 37% 75% 63%
bridge/src/adapters/openclaw.ts 62% 48% 59% 65%
bridge/src/adapters/claude-code.ts 71% 40% 46% 71%
bridge/src/session-registry.ts 69% 58% 62% 71%
bridge/src/apme/classifier.ts 65% 66% 74% 71%
bridge/src/adapters/index.ts 71% 67% 100% 71%
bridge/src/tui/renderer.ts 70% 55% 94% 72%
bridge/src/usage-event.ts 76% 72% 100% 73%
bridge/src/apme/recommend.ts 71% 39% 67% 74%
bridge/src/tui/terrarium.ts 72% 56% 78% 74%
bridge/src/tui/ansi.ts 74% 49% 84% 75%
bridge/src/apme/claude-transcript-reader.ts 72% 63% 75% 76%
bridge/src/apme/store.ts 68% 71% 83% 80%
bridge/src/session-aggregator.ts 81% 65% 89% 81%
bridge/src/adapters/monitor.ts 81% 60% 87% 81%
bridge/src/apme/runner.ts 76% 64% 72% 82%
bridge/src/adapters/pty-adapter.ts 82% 81% 65% 82%
bridge/src/state-machine.ts 83% 64% 90% 83%
bridge/src/adapters/codex-cli.ts 83% 100% 75% 83%
bridge/src/apme/sample-to-timeline.ts 79% 61% 100% 83%
bridge/src/apme/http.ts 81% 77% 88% 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/adapters/codex-turn-manager.ts 78% 58% 95% 86%
bridge/src/apme/collector.ts 83% 71% 90% 87%
bridge/src/pixoo/micro-glyphs.ts 91% 67% 100% 93%
bridge/src/output-parser.ts 90% 84% 100% 94%
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/utils/project-name.ts 93% 85% 100% 96%
bridge/src/fallback-task-timeline.ts 97% 90% 100% 97%
bridge/src/timeline-store.ts 95% 83% 100% 97%
bridge/src/apme/adapters/openclaw-hook.ts 95% 73% 100% 97%
bridge/src/apme/adapters/opencode-hook.ts 98% 84% 100% 98%
bridge/src/awaiting-overlay.ts 100% 95% 100% 100%
bridge/src/display-dim.ts 95% 69% 100% 100%
bridge/src/openclaw-session.ts 100% 100% 100% 100%
bridge/src/permission-resolver.ts 98% 68% 100% 100%
bridge/src/apme/pareto.ts 100% 81% 100% 100%
bridge/src/apme/settings.ts 97% 85% 100% 100%
bridge/src/apme/adapters/claude-hook.ts 100% 77% 100% 100%
bridge/src/apme/adapters/claude-pty.ts 100% 88% 100% 100%
bridge/src/apme/scorers/index.ts 98% 73% 100% 100%
bridge/src/tui/gauge.ts 98% 96% 100% 100%
hooks/src/install.ts 63% 67% 77% 65%
hooks/src/codex-install.ts 84% 62% 87% 87%
hooks/src/codex-mini-toml.ts 97% 94% 100% 100%
plugin-ulanzi/src/reconnect-supervisor.ts 85% 68% 75% 89%
plugin/src/agent-link.ts 0% 0% 0% 0%
plugin/src/encoder-registry.ts 0% 0% 0% 0%
plugin/src/label-summarizer.ts 0% 0% 0% 0%
plugin/src/plugin.ts 0% 0% 0% 0%
plugin/src/project-picker.ts 0% 0% 0% 0%
plugin/src/project-scanner.ts 0% 0% 0% 0%
plugin/src/timeline-store.ts 0% 0% 0% 0%
plugin/src/voice-local.ts 0% 0% 0% 0%
plugin/src/actions/iterm-dial.ts 0% 0% 0% 0%
plugin/src/actions/option-dial.ts 0% 0% 0% 0%
plugin/src/actions/session-slot-button.ts 0% 0% 0% 0%
plugin/src/actions/utility-dial.ts 0% 0% 0% 0%
plugin/src/actions/voice-dial.ts 0% 0% 0% 0%
plugin/src/renderers/agent-logos.ts 0% 0% 0% 0%
plugin/src/renderers/session-slot-renderer.ts 0% 0% 0% 0%
plugin/src/renderers/text-utils.ts 0% 0% 0% 0%
plugin/src/utility-modes/apme.ts 0% 0% 0% 0%
plugin/src/utility-modes/brightness.ts 0% 0% 0% 0%
plugin/src/utility-modes/darkmode.ts 0% 0% 0% 0%
plugin/src/utility-modes/diag.ts 0% 0% 0% 0%
plugin/src/utility-modes/index.ts 0% 0% 0% 0%
plugin/src/utility-modes/macos.ts 0% 0% 0% 0%
plugin/src/utility-modes/media.ts 0% 0% 0% 0%
plugin/src/utility-modes/mic.ts 0% 0% 0% 0%
plugin/src/utility-modes/permission-mode.ts 0% 0% 0% 0%
plugin/src/utility-modes/timer.ts 0% 0% 0% 0%
plugin/src/utility-modes/tower.ts 0% 0% 0% 0%
plugin/src/utility-modes/types.ts 0% 0% 0% 0%
plugin/src/utility-modes/volume.ts 0% 0% 0% 0%
plugin/src/bridge-client.ts 55% 35% 67% 59%
plugin/src/renderers/timeline-renderer.ts 58% 34% 75% 63%
plugin/src/log.ts 59% 50% 33% 67%
plugin/src/session-slot-manager.ts 77% 73% 75% 79%
plugin/src/utility-modes/usage.ts 74% 74% 56% 79%
plugin/src/renderers/display-tile.ts 77% 50% 100% 80%
plugin/src/renderers/usage-dial-renderer.ts 75% 55% 91% 80%
plugin/src/renderers/button-renderer.ts 82% 72% 100% 82%
plugin/src/renderers/response-renderer.ts 85% 40% 92% 87%
plugin/src/connection-manager.ts 85% 79% 81% 88%
plugin/src/renderers/voice-renderer.ts 88% 57% 87% 90%
plugin/src/renderers/option-renderer.ts 92% 69% 100% 93%
plugin/src/layout-manager.ts 95% 92% 100% 95%
plugin/src/renderers/utility-renderer.ts 98% 57% 100% 98%
plugin/src/center-slot.ts 100% 100% 100% 100%
plugin/src/renderers/qr-renderer.ts 100% 90% 100% 100%
plugin/src/renderers/usage-gauge.ts 99% 76% 100% 100%
shared/src/adapter.ts 0% 100% 100% 0%
shared/src/command-builders.ts 0% 100% 0% 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/pricing.ts 0% 0% 0% 0%
shared/src/sample.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 11% 0% 29% 12%
shared/src/svg-renderers/agent-logos.ts 29% 30% 31% 30%
shared/src/svg-renderers/session-slot-renderer.ts 38% 28% 48% 38%
shared/src/state-colors.ts 38% 50% 67% 42%
shared/src/format-utils.ts 46% 45% 38% 46%
shared/src/d200h-layout.ts 48% 44% 58% 48%
shared/src/timeline-summarizer.ts 73% 63% 57% 76%
shared/src/timeline-icons.ts 85% 78% 75% 81%
shared/src/timeline.ts 77% 72% 100% 83%
shared/src/session-utils.ts 90% 73% 100% 89%
shared/src/connection-status.ts 100% 100% 100% 100%
shared/src/design-tokens.ts 100% 100% 100% 100%
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%