AgentDeck · Continuous integration

Test Report

The most recent CI run, in full: which tests passed, which user scenarios are covered, how the numbers are trending, and where the gaps are. This is the maintainer's evidence that the build works — not a product analytics dashboard.

LATEST RUN · PASS · GENERATED 2026-08-20 11:20:54

Status
PASS
3620 executed tests
Passed
3618
99.9% pass rate
Failed
0
 
Duration
38.5s
31.9s vitest + 6.6s android
TS Line Coverage
55.1%
14,474/26,257 TypeScript lines
Total Tests
3620
Pass Rate
99.9%
Line Coverage
55.1%

Vitest

PASS
Pass 3243 Fail 0 207 files Coverage + JSON report

Android

PASS
Pass 375 Fail 0 29 files JUnit + Robolectric on ubuntu

Apple (XCTest)

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

Robot Framework

NOT RUN
Physical hardware suite; not executed on GitHub-hosted runners
Terminal Output Parsing PASS
Does the bridge interpret Claude Code and Codex terminal output correctly?
264 passed 0 failed 3 files 259ms
output-parser.test.ts
220 / 220 201ms
OutputParser 220 / 220
basic option parsing › parses clean numbered options with newlines
16.942657999999994ms
basic option parsing › detects (recommended) marker
2.635487000000012ms
basic option parsing › detects ✔ selected marker
1.4471090000000117ms
basic option parsing › handles both recommended and selected on different options
1.0533360000000016ms
basic option parsing › parses full Claude model selector with labels and middle dot
1.6436950000000365ms
ANSI-stripped options › parses concatenated text with · delimiter
1.1275979999999777ms
ANSI-stripped options › extracts version numbers from · delimited labels
0.7484170000000177ms
chunked input debounce › does NOT emit immediately on first chunk
0.6743850000000293ms
chunked input debounce › batches multiple chunks into single emission
1.3621709999999894ms
chunked input debounce › resets debounce timer when new chunk with options arrives
1.1075480000000084ms
chunked input debounce › simulates real /model flow: split across chunks
1.9700260000000185ms
model ID date rejection › does NOT parse 20251001 from model ID as option number
1.5015600000000404ms
model ID date rejection › rejects large numbers that look like dates
1.0124040000000036ms
version number rejection › does NOT parse version "4.6" followed by digit as option
1.1907030000000418ms
version number rejection › does NOT parse "6)" from "4.6)" as option 6
0.9040309999999749ms
stale buffer overwrite › newer options overwrite older ones with same index
1.0971619999999689ms
permission prompts › detects Yes/No/Always pattern
1.9029350000000136ms
permission prompts › keeps ALL real options when a numbered prompt contains "Yes, allow once" (no collapse to 3)
2.069505000000049ms
permission prompts › detects (Y)es/(N)o pattern
1.2764720000000125ms
permission prompts › emits immediately with no debounce
0.8361489999999776ms
permission prompts › sets yes_no_always prompt type
0.6677649999999744ms
permission prompts › sets yes_no prompt type
0.6302279999999882ms
permission prompts › extracts the multi-line question header above yes/no/always options
1.0101809999999887ms
permission prompts › extracts the question from a box-framed permission prompt
1.1724049999999693ms
permission prompts › extracts the inline question from the (Y)es/(N)o line
0.7352670000000217ms
permission prompts › does not mistake box-drawing or footer chrome for a question
0.8857340000000136ms
permission prompts › suppresses false idle from user prompt echo after permission (interactive cooldown)
0.852643999999998ms
permission prompts › allows real idle after interactive cooldown expires
0.6915309999999977ms
diff prompts › detects (V)iew/(A)pply/(D)eny pattern
1.0587639999999965ms
diff prompts › detects lowercase (a)pply/(d)eny/(v)iew pattern
0.7545769999999834ms
diff prompts › emits immediately with no debounce
0.6548459999999636ms
diff prompts › suppresses false idle from user prompt echo after diff (interactive cooldown)
0.9603559999999902ms
various option counts › handles 1 option
0.5996529999999893ms
various option counts › handles 2 options
0.627806000000021ms
various option counts › handles 5+ options
0.6102290000000039ms
various option counts › marks direct-input options as freeform instead of a normal choice
0.9774519999999711ms
various option counts › handles bullet-style options
0.8126229999999737ms
option updates › emits new options when data changes after first emission
0.8408559999999738ms
spinner cancels option timer › spinner cancels pending option debounce
0.6849109999999996ms
idle vs option debounce › idle prompt is ignored when option debounce is pending
0.9121039999999994ms
idle vs option debounce › idle prompt fires normally when no option debounce is pending
0.7152869999999893ms
interactive prompt during spinner › parses a navigable prompt when spinner and prompt share the first chunk
0.8550870000000259ms
interactive prompt during spinner › keeps a visible prompt active through spinner redraw floods
1.6242359999999962ms
interactive prompt during spinner › allows real processing immediately after the prompt is selected
0.9603949999999486ms
interactive prompt during spinner › does not arm prompt lifecycle from stale numbered prose
0.5364680000000135ms
interactive prompt during spinner › stops spinner when permission prompt arrives
1.027667000000008ms
interactive prompt during spinner › stops spinner when diff prompt arrives
0.7277760000000058ms
interactive prompt during spinner › stops spinner when option prompt arrives
0.7530239999999822ms
interactive prompt during spinner › stops spinner when idle prompt arrives in small chunk
0.6904099999999858ms
interactive prompt during spinner › ignores idle prompt in large chunk during spinner (screen redraw)
0.5007640000000038ms
cleanOptionLabel (via parseOptions) › deduplicates exact CamelCase matches
0.6107900000000086ms
cleanOptionLabel (via parseOptions) › preserves labels without · delimiter
4.111805000000004ms
cleanOptionLabel (via parseOptions) › removes (recommended) from label text
0.637580000000014ms
cleanOptionLabel (via parseOptions) › removes ✔ from label text
0.5357960000000048ms
cleanOptionLabel (via parseOptions) › extracts version from identity before middle dot
0.5581700000000183ms
metadata events › emits project_name from startup banner
0.5243690000000356ms
metadata events › emits project_name only once (caches)
0.4577290000000289ms
metadata events › parses absolute path for project_name
0.4229970000000094ms
metadata events › seedProjectName disables the scrape (resolver wins over basename)
0.4966580000000249ms
metadata events › seeded name survives reset(); scrape stays disabled
0.7039700000000266ms
metadata events › seeding 'unknown' keeps the scrape live as fallback
0.6075449999999591ms
metadata events › emits model_info with model and plan
0.6974500000000035ms
metadata events › emits model_info without plan
0.6868040000000519ms
metadata events › emits model_info only once for same model (caches)
0.608846000000085ms
metadata events › re-emits model_info when model changes
0.6745449999999664ms
metadata events › parses ANSI-stripped model_info
0.7588680000000068ms
metadata events › detects API billing plan
0.5576999999999543ms
metadata events › emits status_line with duration and tokens
0.7445109999999886ms
metadata events › parses zero-minute status line
0.5689459999999826ms
metadata events › emits tool_action from ⏺ pattern
0.4537430000000313ms
metadata events › extracts various tool names
0.4797120000000632ms
user prompt › emits user_prompt after first idle has been seen
0.7770299999999679ms
user prompt › does NOT emit user_prompt before first idle
0.647534999999948ms
user prompt › filters out mode banner text
0.6896080000000211ms
user prompt › filters out numbered option lines
0.7785619999999653ms
user prompt › filters out keyboard hint text
0.6696479999999383ms
user prompt › filters out "esc to interrupt" text
0.6765989999998965ms
user prompt › filters out autocomplete suggestions
1.5349310000000287ms
user prompt › filters out box-drawing decorative lines
0.607503999999949ms
usage info › parses usage percentage
0.8509810000000471ms
usage info › parses usage cost
0.8749670000000833ms
usage info › parses session percentage with hour limit
0.7077560000000176ms
usage info › parses reset time with timezone
0.6404139999999643ms
usage info › parses time remaining
0.6137840000000097ms
spinner lifecycle › emits spinner_start on spinner char (after idle seen)
0.6283959999999524ms
spinner lifecycle › does NOT emit spinner_start before first idle
0.5494969999999739ms
spinner lifecycle › emits spinner_stop after debounce (2000ms)
0.6722019999999702ms
spinner lifecycle › does NOT emit duplicate spinner_start on repeated chars
0.6371390000000474ms
spinner lifecycle › resets spinner debounce timer on repeated chars
0.737700000000018ms
spinner lifecycle › ignores spinner chars in large text blocks (>80 non-ws)
0.8082860000000665ms
spinner lifecycle › recognizes all spinner characters
1.6461879999999383ms
idle detection › emits idle after IDLE_DEBOUNCE_MS (300ms)
0.7677260000000388ms
idle detection › sets seenFirstIdle on first idle prompt
0.8472860000000537ms
idle detection › cancels idle timer when spinner starts
0.655046000000084ms
idle detection › recognizes > as idle prompt char
0.5163170000000719ms
mode detection › detects plan mode
0.8263839999999618ms
mode detection › detects accept edits mode
0.6725930000000062ms
mode detection › detects default mode after Shift+Tab
0.6935139999999365ms
mode detection › detects default mode via idle prompt after Shift+Tab
0.6470640000000003ms
mode detection › emits default mode on Shift+Tab timeout (2s)
0.6651510000000371ms
mode detection › detects ANSI-stripped plan mode text
0.5724710000000641ms
mode detection › detects ANSI-stripped accept edits text
0.6843699999999444ms
mode detection › clears pending mode switch when mode banner is detected
0.5800030000000334ms
reset › clears cached project name and model name
0.6482560000000603ms
reset › disables spinner detection (clears seenFirstIdle)
0.7461939999999458ms
reset › allows re-detection after new idle prompt post-reset
0.753193999999894ms
reset › allows re-detection of project name after reset
0.5537440000000515ms
reset › allows re-detection of model info after reset
0.5791619999999966ms
buffer management › truncates buffer when exceeding 8192 chars
1.3436329999999543ms
buffer management › keeps the last 4096 chars after truncation
0.8682769999999209ms
option navigation › cursor movement during option selection does NOT trigger idle
1.0102309999999761ms
option navigation › cursor movement does NOT trigger user_prompt
0.8757789999999659ms
option navigation › normal cursor movement between options emits no idle or user_prompt
2.920071000000007ms
option navigation › real idle prompt still works after option navigation
1.4230820000000222ms
option navigation › effort/hint text during navigation does not trigger events
1.0741580000000113ms
option navigation › IDLE_PROMPT requires space/tab/NBSP after ❯ (not newline)
0.7361190000000306ms
option navigation › USER_PROMPT requires space/tab after ❯ (not newline)
0.816139000000021ms
permission reclassification › reclassifies numbered Yes/No options as permission_prompt
1.3034920000000056ms
permission reclassification › does NOT reclassify regular options as permission
0.9040610000000697ms
permission reclassification › does NOT reclassify cursor-selection UI with "Enter to confirm" as permission
0.9265249999999696ms
permission reclassification › detects cursor-selection UI even when ANSI stripping removes spaces
3.2643449999999348ms
permission reclassification › includes navigable and cursorIndex in reclassified permission_prompt
0.7884470000000192ms
permission reclassification › infers shortcuts for reclassified permission options
0.9280669999999418ms
permission reclassification › infers shortcut "a" for "don't ask again" labels
0.6148960000000443ms
permission reclassification › infers shortcut "a" for "allow all sessions" labels
2.6945519999999306ms
ghost text suggestion › detects SGR 90 (bright black) ghost text on prompt line
1.811557999999991ms
ghost text suggestion › detects ghost text via Strategy 1 (Try "..." in clean text)
0.6693179999999757ms
ghost text suggestion › unwraps Try "..." wrapper with smart quotes
0.7341259999999465ms
ghost text suggestion › unwraps Try "..." wrapper with straight quotes
1.0109719999999243ms
ghost text suggestion › detects ghost text on first idle (❯ and suggestion in same chunk)
0.672292000000084ms
ghost text suggestion › clears suggestion on spinner start
0.629827999999975ms
ghost text suggestion › debounces rapid updates
0.6961780000000317ms
ghost text suggestion › ignores dim (SGR 2) text without ❯ prompt context
0.546873000000005ms
ghost text suggestion › detects dim (SGR 2) ghost text on ❯ prompt line
0.5183310000001029ms
ghost text suggestion › detects ghost text with cursor-forward spacing (Strategy 1)
0.54520100000002ms
ghost text suggestion › filters UI chrome fragments
0.8211360000000241ms
ghost text suggestion › filters box-drawing lines as UI chrome
0.5781409999999596ms
ghost text suggestion › filters file paths (false positive from screen redraws)
0.6081760000000713ms
ghost text suggestion › detects 256-color gray ghost text
0.49307199999998375ms
ghost text suggestion › handles multi-segment ghost text on prompt line
0.6447309999999788ms
ghost text suggestion › ignores ghost text on non-prompt lines
0.60325899999998ms
ghost text suggestion › detects 24-bit RGB gray ghost text
0.7237999999999829ms
ghost text suggestion › ignores 24-bit RGB non-gray colors (e.g. blue prompt char)
0.6528729999999996ms
ghost text suggestion › filters out short gray text like prompt char itself
0.6720320000000584ms
ghost text suggestion › suppresses ghost text detection during spinner (processing)
0.6861730000000534ms
ghost text suggestion › rejects digit+operator fragments like diff markers "96 +"
0.6732640000000174ms
ghost text UI chrome filtering › filters out "Tip:" segments on prompt line
0.7567940000000135ms
ghost text UI chrome filtering › filters out "(ctrl+...)" shortcut hints on prompt line
0.6277860000000146ms
ghost text UI chrome filtering › filters concatenated UI chrome even in scheduleSuggestion
0.5972090000000208ms
ghost text UI chrome filtering › keeps ghost text when UI chrome is also present on the line
0.683809999999994ms
filters out extended thinking indicators › rejects "(thought for 1s)" as ghost text via isUiChrome
0.6818959999999379ms
filters out extended thinking indicators › rejects "(thought for 1s)>" via scheduleSuggestion
0.608916000000022ms
filters out extended thinking indicators › rejects longer thinking durations like "(thought for 15s)"
0.6345150000000785ms
filters out extended thinking indicators › rejects "(thought for 1m 30s)" multipart duration
0.5646199999999908ms
filters out extended thinking indicators › rejects "✻ Cooked for 1m 26s" sparkle indicator
0.5638190000000805ms
filters out extended thinking indicators › rejects "✻ Cooked for 5s" short duration variant
0.550698999999895ms
filters out extended thinking indicators › rejects "Cooked for 10s" without sparkle (cross-chunk)
0.6047399999999925ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 2 (dim)
0.5853920000000699ms
parenthesized placeholder filtering › rejects "(no content)" via SGR 90 (bright black)
0.6596630000000232ms
parenthesized placeholder filtering › rejects "(loading...)"
0.5783099999999877ms
parenthesized placeholder filtering › rejects "(empty)"
0.5798030000000836ms
parenthesized placeholder filtering › rejects "(waiting for response)"
0.5558770000000095ms
parenthesized placeholder filtering › allows "fix the broken (auth) module" — parens in middle
0.6317910000000211ms
parenthesized placeholder filtering › allows "(optional) refactor the code" — paren prefix with text after
0.5370289999999613ms
stacked ANSI + cross-chunk ghost text › detects ghost text with stacked ANSI escapes (gray + italic)
0.5665630000000874ms
stacked ANSI + cross-chunk ghost text › detects ghost text with combined SGR params (2;90 = dim+bright-black)
0.7478250000000344ms
stacked ANSI + cross-chunk ghost text › detects cross-chunk ghost text (❯ and gray text in separate feeds)
0.6358679999999595ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when chunk contains ⎿ output fence
0.5597030000000132ms
stacked ANSI + cross-chunk ghost text › does NOT cross-chunk detect when new chunk has \n (different line)
0.45674799999994775ms
ghost option from stale buffer › excludes stale numbered list items before actual option prompt
0.9603359999999839ms
ghost option from stale buffer › bypasses chunk size guard when ❯ cursor is present in large chunk
0.8077660000000151ms
ghost option from stale buffer › a stale markdown "1." line from chat must not overwrite the ❯-marked option
0.6559879999999794ms
ghost option from stale buffer › still works with scrambled TUI order after backward scan
0.5942039999999906ms
ghost option from stale buffer › excludes file path fragments from Read() tool in permission prompt
0.707445000000007ms
option index ordering › returns options sorted by index even when TUI lines arrive out of order
0.6636190000000397ms
split ANSI sequence buffering › handles ANSI SGR codes split across chunks
0.8110309999999572ms
split ANSI sequence buffering › handles bare ESC at end of chunk
0.6278350000000046ms
split ANSI sequence buffering › does not buffer complete ANSI sequences
0.6544450000000097ms
large chunk guard for option detection › does NOT detect numbered items in large response chunks as options
0.7072449999999435ms
large chunk guard for option detection › still detects real options in small TUI chunks
0.5502480000000105ms
CUP-positioned options › parses options using CUP (\x1b[row;colH) instead of newlines
0.7416359999999713ms
CUP-positioned options › parses options using CUD (\x1b[B) for vertical movement
0.719983999999954ms
trailing TUI chrome stripping › strips "Esc to cancel" from last option label
0.6666529999999966ms
trailing TUI chrome stripping › strips "Enter to confirm" from last option label
0.5694270000000188ms
trailing TUI chrome stripping › does NOT strip "Esc" when it appears within legitimate label text
0.532271000000037ms
CJK suggestion detection › accepts ghost text containing CJK characters
1.4568830000000617ms
CJK suggestion detection › accepts ghost text that is purely CJK (no ASCII words)
0.8414469999999028ms
AskUserQuestion with separators and descriptions › handles AskUserQuestion with separator and descriptions
0.6952370000000201ms
AskUserQuestion with separators and descriptions › handles options starting from non-zero index (buffer truncation)
0.6760870000000523ms
AskUserQuestion tall prompt with oversized separator › keeps leading options a/b when a giant box-drawing rule contaminates a later option
0.9202250000000731ms
hierarchical CC prompt shapes › captures 5-option plan approval with long labels
0.7072440000000597ms
hierarchical CC prompt shapes › captures OpenClaw scope selection (numbered list)
2.9722850000000562ms
hierarchical CC prompt shapes › captures OpenClaw token-action step (short numbered list)
0.7811660000000984ms
permission scroll does not trigger idle (Bug 1) › scroll chunk with ❯ option text does NOT cause idle when navigable
0.7641300000000228ms
permission scroll does not trigger idle (Bug 1) › /model combined chunk: confirmation + idle prompt clears options
0.9627990000000182ms
permission scroll does not trigger idle (Bug 1) › /model separate chunks: ANSI reposition timer does not block idle
0.9555090000000064ms
permission scroll does not trigger idle (Bug 1) › cursor move chunk with option text does NOT falsely trigger idle
0.9631090000000313ms
permission scroll does not trigger idle (Bug 1) › genuine idle prompt exits navigable state and emits idle
0.8868250000000444ms
TUI cursor-overwrite label correction (Bug 2) › fixes contaminated permission option label using correction line
0.9077670000000353ms
TUI cursor-overwrite label correction (Bug 2) › leaves labels unchanged when no correction line is present
0.6812360000000126ms
genuine idle detection (semantic) › "❯ \n" is genuine idle — only prompt character, no label text
0.5961979999999585ms
genuine idle detection (semantic) › "❯ Beta" is NOT idle — has label text after prompt char
0.5602740000000495ms
genuine idle detection (semantic) › "❯ A" is NOT idle — single-char label still counts
0.6719819999999572ms
genuine idle detection (semantic) › ">" also treated as idle prompt character
0.4334430000000111ms
effort level parsing › detects "High effort" selection pattern
0.47958199999993667ms
effort level parsing › detects "Medium effort" selection pattern
0.3833670000000211ms
effort level parsing › detects "Low effort" selection pattern
0.42749300000002677ms
effort level parsing › detects "with high effort" confirmation line
0.3810439999999744ms
effort level parsing › detects effort in model info line
0.3993709999999737ms
effort level parsing › caches effort level — no re-emit on same value
0.3510479999999916ms
effort level parsing › emits on effort level change
0.3806929999999511ms
effort level parsing › resets effort level on reset()
0.3798020000000406ms
effort level parsing › does not match "effort" in unrelated context
0.3326309999999921ms
effort level parsing › does not match effort inside numbered option lines
0.48275699999999233ms
effort level parsing › getter returns current effort level
0.35386300000004667ms
effort level parsing › detects "Max effort" (Opus 4.7 variant)
0.3691159999999627ms
effort level parsing › detects "xhigh effort" (Opus 4.7 variant)
0.9332350000000815ms
effort level parsing › detects "default effort" (per-model default variant)
0.42995799999994233ms
effort level parsing › detects "fast effort" (Opus 4.6 variant)
0.3790199999999686ms
effort level parsing › detects effort in /model confirmation line with max
0.3727209999999559ms
codex-output-parser.test.ts
29 / 29 32ms
CodexOutputParser 29 / 29
idle detection › emits idle on ❯ prompt with source=prompt
9.32663100000002ms
idle detection › emits idle on > prompt
1.2138369999999838ms
idle detection › debounces rapid idle signals
0.7407850000000167ms
spinner detection › emits spinner_start on braille spinner chars after first idle
1.2071479999999895ms
spinner detection › does not emit spinner_start before first idle
0.7268740000000093ms
spinner detection › emits spinner_stop + idle on timeout with source=timeout
0.7078649999999982ms
spinner detection › emits spinner_stop when idle prompt appears
0.478289999999987ms
spinner detection › detects "Thinking" text as processing
0.49849100000000135ms
permission prompt detection › emits permission_prompt on Allow/Deny pattern
1.6208010000000002ms
permission prompt detection › emits permission_prompt on y/n pattern
0.7916019999999833ms
permission prompt detection › stops spinner when approval detected
0.6230079999999987ms
permission prompt detection › extracts Allow once / Always allow options
0.49895100000000525ms
permission prompt detection › detects the current Codex command approval prompt as awaiting permission
1.3772940000000062ms
tool action detection › detects Running: command pattern
2.254924000000017ms
tool action detection › detects file operation patterns
0.7311809999999923ms
tool action detection › detects Editing file pattern
0.5681549999999902ms
tool action detection › dedups repeated emits of the same (tool, args) within window
0.4662519999999972ms
tool action detection › emits a different command immediately
0.39792900000000486ms
tool action detection › re-emits the same command after the dedup window elapses
0.4080539999999928ms
tool action detection › re-emits the same command after a turn boundary (idle resets dedup)
0.6491169999999897ms
model info detection › detects gpt model name
0.5052909999999997ms
model info detection › detects o-series model
0.448695999999984ms
model info detection › does not re-emit same model
0.41856999999998834ms
project name detection › detects working directory
2.2990760000000137ms
project name detection › detects project from path
0.6639999999999873ms
project name detection › only detects project name once
0.5923919999999896ms
buffer management › truncates buffer at 8192 chars
0.575616999999994ms
buffer management › handles incomplete ANSI sequences
0.6877959999999916ms
getProjectName › returns null when no project detected
0.47236100000000647ms
cursor-sync.test.ts
15 / 15 25ms
Cursor Synchronization 15 / 15
terminal keyboard cursor tracking › emits cursor_update when full option redraw arrives with ❯ at new position
12.374000000000024ms
terminal keyboard cursor tracking › triggers buffer re-parse on small non-❯ chunk during navigable state
1.9117780000000266ms
terminal keyboard cursor tracking › does not emit cursor_update when cursor position unchanged
1.091793999999993ms
genuine idle distinction › treats "❯ \n" as genuine idle (clears navigable state)
0.9060039999999958ms
genuine idle distinction › does NOT treat "❯ Beta" as idle (cursor on option label)
1.0747579999999743ms
genuine idle distinction › does NOT treat "❯ Allow once" as idle (permission cursor move)
1.6735890000000495ms
cursor authority in StateMachine › accepts optimistic update immediately
1.4679399999999987ms
cursor authority in StateMachine › suppresses stale PTY value within 200ms of optimistic update
0.4872940000000199ms
cursor authority in StateMachine › accepts PTY value after 200ms grace period
0.42241599999999835ms
cursor authority in StateMachine › always accepts PTY when no recent optimistic update
0.38795399999997926ms
cursor authority in StateMachine › resets authority on state transition out of AWAITING
0.7066429999999855ms
cursor authority in StateMachine › default source parameter is pty
0.3717800000000011ms
select_option proportional delay › delay scales with step count
0.392770999999982ms
option re-emission with cursorIndex › AWAITING_OPTION update triggers state_changed with options
0.5560570000000098ms
option re-emission with cursorIndex › updateCursorIndex emits snapshot with new cursor value
0.48530999999996993ms
State Machine & Adapters PASS
Are agent state transitions and type-specific command routes correct?
196 passed 0 failed 3 files 180ms
state-machine.test.ts
76 / 76 80ms
StateMachine 76 / 76
basic transitions › starts in DISCONNECTED
10.852929000000017ms
basic transitions › SessionStart → IDLE
1.3681100000000015ms
basic transitions › UserPromptSubmit → PROCESSING
1.6614920000000097ms
basic transitions › Stop → IDLE from PROCESSING
0.8291290000000231ms
basic transitions › SessionEnd → DISCONNECTED from any state
0.6103590000000167ms
permission flow › permission_prompt → AWAITING_PERMISSION
1.335961999999995ms
permission flow › user respond → PROCESSING from AWAITING_PERMISSION
0.8313119999999685ms
terminal UI authority boundary › accepts a real interaction affordance
0.6683360000000107ms
terminal UI authority boundary › ignores terminal lifecycle guesses
0.6476249999999482ms
option flow › option_prompt → AWAITING_OPTION
0.6276650000000359ms
option flow › select_option → PROCESSING from AWAITING_OPTION
0.5703790000000026ms
option flow › option_prompt carries the question into the snapshot
0.7446610000000078ms
diff flow › diff_prompt → AWAITING_DIFF
0.6466030000000274ms
diff flow › respond → PROCESSING from AWAITING_DIFF
0.6213249999999562ms
interrupt › interrupt → IDLE from PROCESSING
0.5687560000000076ms
interrupt › interrupt → IDLE from AWAITING_PERMISSION
0.6091170000000261ms
strict transitions › allows IDLE → AWAITING_PERMISSION (prompt without spinner)
0.5157859999999914ms
strict transitions › blocks invalid transition: DISCONNECTED → PROCESSING
0.4828870000000052ms
strict transitions › allows wildcard session_end from any state
0.6217960000000176ms
stuck timeout › PROCESSING for >5min → auto-recovery to IDLE
1.323773000000017ms
stuck timeout › AWAITING_PERMISSION persists indefinitely — a genuine wait is never auto-recovered
0.7005649999999832ms
stuck timeout › AWAITING_OPTION persists indefinitely (no wall-clock recovery)
0.6411059999999793ms
stuck timeout › AWAITING_DIFF persists indefinitely (no wall-clock recovery)
0.6384209999999939ms
stuck timeout › AWAITING leaves only on a real signal — parser spinner (OpenCode/OpenClaw adapters) → PROCESSING
0.6622469999999794ms
stuck timeout › timer resets on state change before timeout
0.6413459999999986ms
stuck timeout › no timeout in IDLE state
0.5167380000000321ms
hook exits from awaiting states › Stop from AWAITING_PERMISSION → IDLE with prompt fields cleared
1.5851470000000063ms
hook exits from awaiting states › Stop from AWAITING_OPTION → IDLE (keyboard-answered AskUserQuestion ends the turn)
0.7265939999999773ms
hook exits from awaiting states › Stop from AWAITING_DIFF → IDLE
0.6264229999999884ms
hook exits from awaiting states › UserPromptSubmit from AWAITING_PERMISSION → PROCESSING (new turn dismisses the prompt)
0.6402439999999956ms
hook exits from awaiting states › PostToolUse after the grace period dismisses AWAITING_PERMISSION → PROCESSING
0.9020179999999982ms
hook exits from awaiting states › PreToolUse after the grace period dismisses AWAITING_OPTION → PROCESSING
0.9596050000000105ms
hook exits from awaiting states › tool activity within the grace period keeps a fresh prompt awaiting
0.6914309999999659ms
hook exits from awaiting states › PreToolUse from IDLE recovers a dropped user_prompt_submit → PROCESSING
0.6283159999999839ms
hook exits from awaiting states › codex_turn_complete from AWAITING_OPTION → IDLE (notify closes a keyboard-answered prompt)
0.7349760000000174ms
hook exits from awaiting states › codex_tool_end after the grace period dismisses AWAITING_PERMISSION → PROCESSING
0.7467939999999658ms
hook exits from awaiting states › a parallel sibling finishing does not dismiss the prompt while the gated tool is in flight
0.9887590000000159ms
hook exits from awaiting states › a straggler PostToolUse landing after Stop does not reopen a finished session
0.777860999999973ms
hook exits from awaiting states › a re-detected prompt refreshes the dismissal grace
0.7360180000000014ms
hook exits from awaiting states › the daemon hub machine never dismisses prompts or reopens IDLE on tool activity
0.8142859999999814ms
parser events › spinner_start → PROCESSING from IDLE
0.5882459999999696ms
parser events › spinner_stop → IDLE from PROCESSING
0.6064430000000129ms
parser events › idle → IDLE from PROCESSING
0.5966279999999529ms
parser events › mode_change updates permission mode
0.6688369999999964ms
snapshot › emits state_changed on transitions
0.7695479999999861ms
snapshot › includes tool info in snapshot
3.6192890000000375ms
snapshot › clears tool info on PostToolUse
0.7979010000000244ms
snapshot › includes project name and model
0.9211970000000065ms
billingType detection › defaults to unknown
3.7354540000000043ms
billingType detection › detects subscription from "Claude Max" plan
0.7254930000000286ms
billingType detection › detects subscription from "Max" (case-insensitive)
0.8381520000000364ms
billingType detection › detects api from "api.anthropic.com"
2.137707999999975ms
billingType detection › detects api (case-insensitive)
0.7347960000000171ms
billingType detection › stays unknown for unrecognized plan
1.1444030000000112ms
billingType detection › stays unknown when plan is absent
0.5569589999999494ms
billingType detection › persists billingType across subsequent model_info without plan
0.678120999999976ms
billingType detection › emits state_changed when billingType is set
0.5100180000000023ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_OPTION to PROCESSING
0.6395029999999906ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_PERMISSION to PROCESSING
0.6124730000000227ms
spinner_start recovery from awaiting states › spinner_start transitions from AWAITING_DIFF to PROCESSING
0.5119310000000041ms
spinner_start recovery from awaiting states › clears options and navigable state on spinner_start from AWAITING_OPTION
3.288511000000028ms
spinner_start recovery from awaiting states › stores navigable and cursorIndex from permission_prompt
0.4859109999999873ms
spinner_start recovery from awaiting states › cursor index tracking via updateCursorIndex
0.5624369999999885ms
cursor authority (optimistic vs pty) › optimistic source updates cursor immediately
0.6185909999999808ms
cursor authority (optimistic vs pty) › suppresses stale PTY within 200ms of optimistic
0.4736130000000003ms
cursor authority (optimistic vs pty) › accepts PTY after 200ms grace period
0.3890350000000353ms
cursor authority (optimistic vs pty) › emits state_changed on optimistic update
0.48209600000001274ms
cursor authority (optimistic vs pty) › does NOT emit state_changed when stale PTY is suppressed
0.46048300000001063ms
codex_* hook events › codex_session_start → IDLE
0.3102679999999509ms
codex_* hook events › codex_user_prompt_submit → PROCESSING
0.3744440000000395ms
codex_* hook events › codex_tool_start sets currentTool from tool_name
0.420092000000011ms
codex_* hook events › codex_tool_end clears currentTool
0.3563570000000027ms
codex_* hook events › codex_stop → IDLE from PROCESSING
0.3982400000000439ms
codex_* hook events › codex_turn_complete closes PROCESSING when codex_stop is absent
0.3437979999999925ms
codex_* hook events › codex_turn_complete remains idempotent after codex_stop
0.33740799999998217ms
codex_* hook events › full codex lifecycle preserves state transitions
0.45802900000001046ms
adapter.test.ts
95 / 95 66ms
createAdapter factory 5 / 5
creates ClaudeCodeAdapter for "claude-code"
3.3830130000000054ms
creates OpenClawAdapter for "openclaw"
0.8239999999998417ms
passes gatewayUrl to OpenClawAdapter
0.15362099999993006ms
creates CodexCliAdapter for "codex-cli"
0.43694699999991826ms
throws for unknown agent type
0.951863000000003ms
ClaudeCodeAdapter 17 / 17
capabilities › reports all Claude Code capabilities as true
0.8936550000000807ms
handleCommand routing › handles respond → returns true
0.4745349999998325ms
handleCommand routing › handles switch_mode → returns true
0.4227659999999105ms
handleCommand routing › handles interrupt → returns true
0.31975099999999657ms
handleCommand routing › handles escape → returns true
0.21540399999980764ms
handleCommand routing › defers select_option to bridge → returns false
0.20475800000008348ms
handleCommand routing › defers navigate_option to bridge → returns false
0.1999510000000555ms
handleCommand routing › defers send_prompt to bridge → returns false
0.26435799999990195ms
handleCommand routing › defers voice to bridge → returns false
0.2594810000000507ms
handleCommand routing › defers query_usage to bridge → returns false
0.19190899999989597ms
switch_mode debounce › debounces rapid switch_mode calls (< 100ms apart)
0.7844810000001416ms
lifecycle › isAlive returns false before start
0.2520199999999022ms
lifecycle › getTtyPath returns undefined before start
0.28425799999990886ms
lifecycle › getProjectName returns null before start
0.28760299999999006ms
lifecycle › getHttpServer returns an object
0.341715000000022ms
onRawData callback › can register callback without error
0.3707379999998466ms
onDiag handler › can register handler without error
0.35055800000009185ms
OpenClawAdapter 17 / 17
capabilities › reports OpenClaw capabilities correctly
0.3274730000000545ms
handleCommand routing › handles respond → returns true (RPC)
0.4772280000001956ms
handleCommand routing › handles select_option → returns true (RPC)
0.18205399999988003ms
handleCommand routing › handles navigate_option → returns true (no-op)
0.16389700000013363ms
handleCommand routing › handles send_prompt → returns false without session key
0.293777000000091ms
handleCommand routing › handles interrupt → returns true (RPC)
0.27701699999988705ms
handleCommand routing › handles escape → returns true (RPC)
0.21355100000005223ms
handleCommand routing › defers switch_mode → returns false (not supported)
0.22001099999988583ms
handleCommand routing › defers voice to bridge → returns false
0.14813299999991614ms
handleCommand routing › defers query_usage to bridge → returns false
0.17862900000000081ms
lifecycle › isAlive returns false before start
0.14229500000010376ms
lifecycle › getTtyPath returns undefined (no PTY)
0.125678999999991ms
lifecycle › getProjectName returns null before start
0.13046700000018063ms
lifecycle › getHttpServer returns an object
0.11848800000007031ms
lifecycle › attachTerminal is a no-op
0.259270000000015ms
onRawData callback › can register callback without error
0.2610429999999724ms
onDiag handler › can register handler without error
0.26955499999985477ms
OpenClawAdapter gateway protocol 13 / 13
sends connect request with correct format on connect.challenge
3.5972560000000158ms
becomes alive after hello-ok response
6.90510600000016ms
emits spinner_start on chat delta event
0.7558379999998124ms
emits idle on chat final event
0.7448719999999867ms
emits idle on chat aborted event
0.600734999999986ms
emits idle on chat error event
0.8106200000001991ms
emits permission_prompt on exec.approval.requested
1.2862970000001042ms
sends exec.approval.resolve on respond after approval request
2.1420949999999266ms
sends exec.approval.resolve with deny on respond "n"
1.069189999999935ms
sends chat.send on send_prompt with active session
0.9007860000001529ms
sends chat.abort on interrupt with active session and runId
0.6916519999999764ms
emits SessionEnd on shutdown event
0.4786110000000008ms
clears pendingApprovalId on exec.approval.resolved
0.6432580000000598ms
CodexCliAdapter 16 / 16
capabilities › reports Codex CLI capabilities correctly
0.47159000000010565ms
handleCommand routing › handles respond → returns true
0.27636600000005274ms
handleCommand routing › handles interrupt → returns true
0.21250999999983833ms
handleCommand routing › handles escape → returns true
0.24896400000011454ms
handleCommand routing › does not handle switch_mode → returns false
0.18531899999993584ms
handleCommand routing › defers select_option to bridge → returns false
0.19926999999984218ms
handleCommand routing › defers navigate_option to bridge → returns false
0.19455300000004172ms
handleCommand routing › defers send_prompt to bridge → returns false
0.27290099999981976ms
handleCommand routing › defers voice to bridge → returns false
0.28825400000005175ms
handleCommand routing › defers query_usage to bridge → returns false
0.291398000000072ms
lifecycle › isAlive returns false before start
0.2713889999999992ms
lifecycle › getTtyPath returns undefined before start
0.26268499999991946ms
lifecycle › getProjectName returns null before start
0.32184400000005553ms
lifecycle › getHttpServer returns an object
0.28388699999982236ms
onRawData callback › can register callback without error
0.4054000000000997ms
onDiag handler › can register handler without error
0.46212599999989834ms
CodexCliAdapter start lifecycle 3 / 3
emits SessionStart and connected on start
2.0721889999999803ms
feeds PTY data to output parser and emits activity
2.9352939999998853ms
exports only terminal UI affordances, not parser lifecycle guesses
1.1466760000000704ms
MonitorAdapter 18 / 18
capabilities › reports monitor capabilities correctly
0.8461439999998674ms
handleCommand routing › rejects respond (no PTY)
0.5100879999999961ms
handleCommand routing › rejects interrupt (no PTY)
0.3773580000001857ms
handleCommand routing › rejects escape (no PTY)
0.36402799999996205ms
handleCommand routing › rejects switch_mode (no PTY)
0.40928599999983817ms
handleCommand routing › rejects select_option (no PTY)
0.47842999999988933ms
handleCommand routing › rejects send_prompt (no PTY)
0.42859500000008666ms
handleCommand routing › defers voice to bridge
0.427614000000176ms
handleCommand routing › defers query_usage to bridge
0.39863000000013926ms
lifecycle › isAlive always returns true
0.3086240000000089ms
lifecycle › getTtyPath returns undefined (no PTY)
0.240402000000131ms
lifecycle › getProjectName returns null
0.23647600000003877ms
lifecycle › getHttpServer returns an object
0.29766799999993054ms
lifecycle › writeInput is a no-op (no PTY)
0.3308589999999185ms
lifecycle › attachTerminal is a no-op
0.35934100000008584ms
lifecycle › onRawData is a no-op
0.47963199999981043ms
start and event emission › emits connected event on start
0.4169369999999617ms
start and event emission › exposes hook server for external wiring
0.27786799999989853ms
ClaudeCodeAdapter start lifecycle 6 / 6
emits SessionStart and connected on start
1.3916150000000016ms
uses claude as default command
1.0067260000000715ms
feeds PTY data to output parser and emits activity
4.320875000000115ms
exports terminal UI detail without exporting lifecycle or tool guesses
1.2158200000001216ms
emits SessionEnd and disconnected on PTY exit
1.0528549999999086ms
registers rawData callback without error
1.1286290000000463ms
protocol-contract.test.ts
25 / 25 33ms
Protocol Contract — StateUpdateEvent 5 / 5
minimal state_update has required fields
4.414260000000013ms
full state_update has all optional fields as correct types
0.7810659999999814ms
state_update serializes to valid JSON
0.19062700000000632ms
state enum values are lowercase strings
0.3553750000000093ms
promptType values match known set
0.1758649999999875ms
Protocol Contract — UsageEvent 3 / 3
has all required numeric fields
0.26018099999998867ms
rate limit fields are present when available
1.0279879999999935ms
tokenStatus matches known values
0.2565960000000018ms
Protocol Contract — SessionsListEvent 2 / 2
sessions have required fields
0.48607200000000716ms
agentType is optional string
0.1612130000000036ms
Protocol Contract — ButtonStateEvent 1 / 1
buttons have required fields
0.4673429999999996ms
Protocol Contract — EncoderStateEvent 1 / 1
encoders have required fields
0.5099280000000022ms
Protocol Contract — TimelineEventMsg 1 / 1
entry has required fields
0.23985099999998738ms
Protocol Contract — ConnectionEvent 1 / 1
has required fields
0.1915790000000186ms
Protocol Contract — DisplayStateEvent 1 / 1
has boolean displayOn
0.1563950000000034ms
Protocol Contract — PluginCommand shapes 6 / 6
respond command has value
0.1927699999999959ms
select_option has numeric index
0.1932910000000163ms
navigate_option has direction
0.15634499999998752ms
send_prompt has text
0.11976999999998839ms
utility command has action
0.15067700000000173ms
clear_session_focus is fieldless
0.8766999999999996ms
Protocol Contract — BridgeEvent discriminated union 2 / 2
all event types in union have type field
1.1338779999999815ms
SERIAL_FORWARDED_EVENTS covers expected types
19.560648999999984ms
Protocol Contract — Backward Compatibility 2 / 2
state_update can be parsed with only required fields (old client)
0.33971200000002ms
usage_update required fields are sufficient for display
0.21163799999999355ms
Timeline Pipeline PASS
Are timeline storage, deduplication, and cross-session relays correct?
125 passed 0 failed 3 files 1.3s
timeline.test.ts
78 / 78 32ms
cleanDetailText 12 / 12
returns empty/falsy input unchanged
2.1007529999999974ms
strips markdown bold
0.4486650000000054ms
strips markdown headings
0.2607930000000067ms
strips code fences
0.12546899999998118ms
strips inline backticks
0.11155800000000227ms
strips markdown links
0.09954000000001884ms
strips blockquotes
0.09026599999998552ms
strips list markers
0.10129200000000083ms
collapses multiple blank lines
0.12578999999999496ms
filters system JSON blobs (connectionId)
0.14407700000001ms
extracts error from JSON blob
0.1305059999999969ms
compacts other JSON
0.10891399999999862ms
cleanRawText 2 / 2
strips bold, headings, links, backticks
0.18823299999999676ms
returns empty/falsy unchanged
0.14508800000001543ms
cleanNopMarkers 3 / 3
removes NOP markers
0.33591599999999744ms
collapses resulting blank lines
0.1342920000000163ms
returns empty/falsy unchanged
0.10124199999998496ms
normalizeTimelineEntryForStorage 12 / 12
summarizes OpenClaw cron model_call prompts instead of storing shell-like instructions
1.763766000000004ms
drops low-signal OpenClaw placeholder tool rows
0.29491400000000567ms
keeps OpenClaw placeholder tool rows when detail carries input or output
0.21313100000000418ms
keeps coalesced Codex subagent lifecycle rows
0.15642500000001291ms
drops OpenClaw NO_REPLY polling responses from the user-facing timeline
0.3343930000000057ms
drops OpenClaw automated polling chat starts from the user-facing timeline
0.290206999999981ms
drops Claude task notification chat starts from the user-facing timeline
0.17362199999999461ms
keeps OpenClaw LINE userId notification failures visible
0.3321599999999876ms
drops Codex command tool rows even when detail carries input
0.16149300000000721ms
drops OpenCode tool rows so a tool-heavy turn does not flood the strip
0.2658700000000067ms
drops Antigravity tool rows too (forward-compat with the observed classifier)
0.12520800000001486ms
extracts readable labels from cron headers
0.25045699999998305ms
isAssistantProgressUpdate 2 / 2
detects non-terminal build/status updates
0.4852210000000241ms
does not classify final completion reports as progress
0.5294269999999983ms
extractSemanticCore 4 / 4
strips duration suffix for chat_end
0.19321100000001934ms
keeps full text for chat_end without separator
0.12277399999999261ms
keeps full text for non-chat_end types
0.10359599999998181ms
trims whitespace
0.11218900000000076ms
isRepetitiveEntry 12 / 12
detects exact duplicate chat_end entries
0.6646349999999757ms
detects keyword-similar entries
0.6222669999999937ms
returns -1 for non-matching entries
0.2749740000000145ms
ignores entries outside window
0.2198410000000024ms
only applies to chat_end, chat_start, and error types
0.2197309999999959ms
dedupes repeated error entries within 1h window
0.2740619999999865ms
matches chat_start entries
0.20260500000000548ms
dedupes automated entries regardless of content
0.19957099999999173ms
exempts error rows from the content-agnostic automated collapse
0.3057410000000118ms
does not dedup automated vs non-automated
0.23095700000001784ms
uses 8h window for automated entries
0.23039700000001062ms
expires automated dedup after 8h
0.13765800000001605ms
parseLogLine 21 / 21
returns null for null/undefined/non-object
0.6396019999999965ms
returns null for empty message
0.16325599999998985ms
returns null for model start/complete (suppressed)
0.18144300000000158ms
parses memory/recall (legacy structured)
0.48305799999999977ms
parses tool execution (legacy structured)
0.378438999999986ms
filters gateway/ws subsystem
0.2331609999999955ms
filters infrastructure noise
0.6525719999999922ms
filters channel infra reconnect noise
1.0497799999999984ms
filters connection status JSON blobs
0.6383209999999906ms
filters transient fetch timeouts
0.3615639999999871ms
filters edit mismatch errors (agent retries)
0.19765800000001832ms
filters failover cascade noise
0.19628500000001736ms
parses genuine errors
0.8686579999999822ms
parses error from message pattern (not level)
0.772843000000023ms
filters model/inference patterns (suppressed)
0.5838289999999802ms
does not synthesize memory_recall from message text alone
0.3961269999999786ms
does not synthesize tool_exec from message text alone
0.22241500000001224ms
parses ISO timestamp correctly via error pattern
0.34597099999996317ms
falls back to Date.now() for invalid timestamp on error message
0.45050800000001345ms
truncates long tool raw to 500 chars
0.4280949999999848ms
filters whatsapp noise from channel infra subsystem
0.41192100000000664ms
parseSlashCommandPrompt 6 / 6
parses a bare command
0.9493489999999838ms
parses a command with arguments
0.26628100000004906ms
parses plugin-scoped command names
0.25934999999998354ms
parses the Claude Code command XML envelope
0.3737029999999777ms
normalizes an envelope name missing the leading slash
0.3019949999999767ms
rejects ordinary prompts and filesystem paths
2.620956000000035ms
normalizeCommandPrompt 2 / 2
collapses an XML envelope to "/name args"
0.28591999999997597ms
passes ordinary prompts through unchanged
0.28442799999999124ms
deduplicateEntry — interrupted close + cross-session guards 2 / 2
never repetitive-merges rows from different sessions
0.6939049999999725ms
adds interrupted chat_end rows instead of merging them by semantic core
0.3157449999999926ms
timeline-integration.test.ts
42 / 42 38ms
BridgeTimelineStore 18 / 18
adds and retrieves entries
6.326164000000006ms
filters history by timestamp
0.6217459999999733ms
returns timeline history sorted by timestamp after late upserts
1.6147109999999998ms
returns per-session history sorted by timestamp after late upserts
0.7611050000000432ms
normalizes OpenClaw cron prompt dumps before storing history
1.8549019999999814ms
drops low-signal OpenClaw placeholder tool rows before broadcast/history
0.6477759999999648ms
drops Codex tool_exec rows before broadcast/history
3.6005400000000236ms
loads persisted timeline history without replaying Codex tool_exec firehose
1.398194999999987ms
calls listeners on new entries
0.6240600000000427ms
upsert updates existing entry with same ts+type
0.8124830000000429ms
upsert keeps timeline attribution fields
0.5494569999999612ms
upsert adds new entry when no match exists
0.3973280000000159ms
task_end updates in place by taskId and carries judge fields
0.899454999999989ms
updateEntryStatus updates approval status
0.34444899999999734ms
getLastEntry returns most recent of given type
0.5004729999999995ms
getLastEntry returns null when type not found
0.2596309999999562ms
removeListener stops notifications
0.4227969999999459ms
enforces MAX_ENTRIES (200) with FIFO
6.7743390000000545ms
deduplicateEntry pipeline 5 / 5
exact duplicate within 8s → skip
0.23430300000001125ms
same type, different content → add
0.1861900000000105ms
different type, same raw → add
0.1712880000000041ms
chat_response identical raw 6s apart → skip (multi-producer race)
0.2206820000000107ms
chat_response near-duplicate beyond 8s → repetitive merge
0.3770680000000084ms
BridgeTimelineStore.setAttributor — history replay attribution 10 / 10
addEntry passes the entry through the attributor before storage
0.3233060000000023ms
caller-set fields take precedence over attributor (idempotent)
0.2746630000000323ms
listener (broadcast) receives the same attributed entry
0.2579680000000053ms
upsertEntry propagates summaryKind to existing entry (LLM enrichment regression)
0.37137899999999036ms
upsertEntry routes through the attributor too
0.42095299999999725ms
late upsert preserves the original entry attribution after task rotation (regression)
0.48093399999999065ms
merge path (repetitive dedup) does not re-attribute after task rotation
0.3965570000000298ms
upsert with no existing match falls through to attributor (insert path)
0.20618999999999232ms
caller-set taskId on upsert overrides existing entry attribution
0.2341819999999757ms
history replay returns entries with taskId/runId set (regression)
0.4803829999999607ms
completion multi-producer double-emit (regression) 1 / 1
identical chat_response from two emit paths is collapsed by store
0.4766169999999761ms
Timeline → WS broadcast pipeline 4 / 4
store entries trigger broadcast via listener
0.36713299999996707ms
upsert entries broadcast with upsert flag
0.3270120000000247ms
exact duplicate within 5s is skipped by store
0.23638600000003862ms
different content within 5s is NOT deduped
0.22174400000000105ms
TimelineEntry types 4 / 4
common entry types have expected shape
1.477655000000027ms
entries with status field
0.2750740000000178ms
entries with detail field
0.330317999999977ms
entries with automated flag
0.20127299999995785ms
session-timeline-relay.test.ts
5 / 5 1.2s
SessionTimelineRelay 5 / 5
connects to sibling and relays timeline_event
314.941157ms
relays timeline_history entries
305.12879399999997ms
removes subscription when session disappears
202.53397100000007ms
ignores daemon sessions
0.4194919999999911ms
handles upsert timeline events
402.8494230000001ms
Daemon & Infrastructure PASS
Are the daemon singleton, session registry, and usage relay stable?
88 passed 0 failed 4 files 3.5s
daemon-lifecycle.test.ts
21 / 21 49ms
daemon.json lifecycle 8 / 8
writeDaemonInfo creates daemon.json with correct content
4.182366999999999ms
readDaemonInfo returns info when PID is alive
0.9726140000000214ms
readDaemonInfo returns null and removes file when PID is dead
0.6348360000000071ms
readDaemonInfo returns null when file does not exist
0.3452800000000025ms
removeDaemonInfo deletes daemon.json
0.7338550000000055ms
removeDaemonInfo is safe when file already gone
1.0957199999999716ms
self-heals daemon.json after an external deletion
1.4942199999999843ms
repairs a malformed daemon.json without rewriting a healthy record
1.0342170000000124ms
session registry with real files 7 / 7
register creates sessions.json
1.7779970000000276ms
register replaces existing entry with same id
1.0130850000000464ms
deregister removes session by id
1.2735769999999889ms
listActive prunes dead PIDs
1.044922999999983ms
multiple sessions coexist
1.0636409999999614ms
findExistingDaemon returns daemon session
1.0157689999999775ms
findExistingDaemon returns null when no daemon
0.58522099999999ms
findDaemonPort 4 / 4
returns port from daemon.json (priority 1)
0.6136440000000221ms
falls back to sessions.json daemon entry
0.6145650000000273ms
returns null when no daemon anywhere
0.38483999999999696ms
daemon.json takes precedence over sessions.json
1.004412000000002ms
probeDaemonHealth 2 / 2
returns health JSON from running server
25.309444000000042ms
returns null for closed port
2.302367000000004ms
session-registry.test.ts
28 / 28 2.1s
Session Registry Logic 24 / 24
pruneDeadSessions › keeps alive sessions
4.925935999999979ms
pruneDeadSessions › removes sessions with dead PIDs
0.7404750000000035ms
pruneDeadSessions › keeps old sessions if PID is alive
0.4555459999999698ms
pruneDeadSessions › handles mix of alive and dead sessions
2.759945000000016ms
port allocation logic › returns base port when no ports are used
0.4204429999999775ms
port allocation logic › returns next port when base is taken
1.7254580000000033ms
port allocation logic › skips used ports
0.24532900000002655ms
port allocation logic › finds gaps in used ports
0.26271500000001424ms
port allocation logic › throws when all ports are taken
1.2477190000000178ms
atomic write › write-then-rename produces valid JSON
2.889901000000009ms
shouldConcedePortToOccupant (startup-race hardening) › does not concede to a non-daemon occupant (session bridge)
0.2993810000000394ms
shouldConcedePortToOccupant (startup-race hardening) › does not concede when the probe failed (null occupant)
0.18612000000001672ms
shouldConcedePortToOccupant (startup-race hardening) › concedes to a daemon backed by a live, distinct PID
0.24194499999998698ms
shouldConcedePortToOccupant (startup-race hardening) › does NOT concede to a forged/stale daemon whose PID is dead
0.22707200000002103ms
shouldConcedePortToOccupant (startup-race hardening) › does NOT concede when the reported PID is our own
0.23946999999998297ms
shouldConcedePortToOccupant (startup-race hardening) › trusts the mode when no PID is reported (e.g. Swift App Store daemon)
0.20336599999995997ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › finds a Swift daemon sitting on a fallback port inside the window
30.23653200000001ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › ignores non-daemon occupants (session bridges) and skipped ports
6.661518999999998ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › returns empty when the window is quiet
2.535207000000014ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForDaemonExit resolves true once /health stops answering
504.50966600000004ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForDaemonExit resolves false when the daemon never leaves
759.1760519999999ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForPortBindable refuses a port that is still bound
457.2353330000003ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForPortBindable resolves true once the socket is actually released
301.9153259999998ms
scanDaemonPortWindow / waitForDaemonExit (split-brain guard) › waitForPortBindable resolves true immediately for a free port
0.4940639999999803ms
daemon port window 4 / 4
defaults when unset or blank
0.4497769999998127ms
accepts a well-formed range
0.5394320000000334ms
falls back to the default for anything it cannot trust
0.6068940000000111ms
reports whether the resolved window is the documented one
0.31851000000006024ms
usage-relay.test.ts
14 / 14 891ms
Usage relay — HTTP (Tier 1) 3 / 3
fetches usage from sibling GET /usage
57.38304299999999ms
returns null usage when sibling has no data
11.625463000000025ms
rejects stale data (>5 min old)
3.8751340000000027ms
Usage relay — WebSocket (Tier 2) 2 / 2
receives usage_update from sibling WS on connect
263.95800500000007ms
does not send usage_update when sibling has no data
255.781025ms
Usage relay — scoped limits round-trip 2 / 2
preserves scopedLimits (active + severity) over the sibling WS relay
255.2138960000001ms
carries scopedLimits through the HTTP /usage relay tier
3.0712040000000798ms
HookServer GET /usage (relay source) 2 / 2
returns cached usage via onApiUsage getter
10.104411999999911ms
returns fresh usage after update
6.155847999999878ms
429 prevention — relay-first strategy 2 / 2
sibling with data prevents direct API call
2.7968399999999747ms
multiple siblings — first with data wins
19.230767000000014ms
ApiUsageData shape 3 / 3
has all required fields
0.3926519999999982ms
serializes to valid JSON and back
0.19766699999991033ms
handles null optional fields
0.21074700000008306ms
bridge-core.test.ts
25 / 25 509ms
BridgeCore Orchestration 25 / 25
buildStateEvent › builds state_update with IDLE state
26.34103700000003ms
buildStateEvent › includes cached ollamaStatus and gatewayAvailable
4.811323000000016ms
buildStateEvent › computes promptType for permission options
1.8506360000000086ms
buildStateEvent › computes promptType yes_no_always for 3+ permission options
1.3803179999999884ms
usage management › updateApiUsage caches and broadcasts
18.819492999999966ms
usage management › buildUsage includes API usage data
1.3505830000000287ms
usage management › buildUsage works without API data
0.975418999999988ms
usage management › inferredBillingType propagates to StateMachine
0.8557690000000093ms
usage management › stale fetch results › a not-fresh result keeps the numbers but marks them stale
1.1423399999999901ms
usage management › stale fetch results › a not-fresh result does NOT advance lastApiFetchTime
1.0582630000000108ms
usage management › stale fetch results › a fresh result clears staleness again
1.0347279999999728ms
usage management › stale fetch results › a null result (no numbers at all) marks an existing cache stale
1.0394150000000764ms
usage management › stale fetch results › reports freshness back to the caller
1.10813799999994ms
sendInitialState › sends state_update, usage_update, connection, display_state on connect
11.611761999999999ms
sendInitialState › includes timeline_history when entries exist
5.285558000000037ms
sendInitialState › caps initial timeline_history below the ESP32 WebSocket frame limit
4.087784000000056ms
state change broadcast › state_changed emits to WS clients when wired by caller
2.3545540000000074ms
wireTimeline › timeline entries broadcast as timeline_event
53.823818000000074ms
hasClients guard › wsServer.getClientCount reflects connected clients
254.46749899999998ms
hasClients guard › external client count provider extends hasClients
1.2368920000000116ms
voice assistant state › updateVoiceAssistantState caches and triggers state broadcast
54.05122499999993ms
voice assistant state › disabled voice assistant state is not included in event
1.2169020000001183ms
session registry › registerSession writes to sessions.json
2.0825649999999314ms
session registry › deregisterSession removes from sessions.json
1.9038859999998294ms
broadcast coordination › broadcast sends to WS and SSE callback
54.21339399999988ms
Integration Tests PASS
Does the end-to-end pipeline work in a real server environment?
35 passed 0 failed 2 files 1.5s
server-integration.test.ts
19 / 19 1.2s
Server Integration 19 / 19
SessionStart hook → IDLE state broadcast
73.30186900000001ms
PreToolUse responds 200 with an EMPTY body (managed sessions must not gate)
13.058079999999904ms
non-PreToolUse hooks still ack with { received: true }
9.650259000000005ms
full session lifecycle: SessionStart → UserPromptSubmit → Stop
15.37794299999996ms
PreToolUse → PostToolUse cycle broadcasts tool info
17.342309999999998ms
SessionEnd → DISCONNECTED
10.605346000000054ms
GET /health returns valid JSON
7.2935509999999795ms
GET /usage returns data when getter is set
6.926909000000023ms
GET /usage returns null when no getter
6.24236899999994ms
GET /devices returns empty when no getter
6.130598999999961ms
POST to unknown route returns 404
6.483980999999972ms
hook endpoint responds immediately
6.553296000000046ms
SSE client receives state_update events
69.15425500000003ms
broadcasts to multiple WS clients
9.041192000000024ms
WS command from client triggers callback
106.1938540000001ms
rapid hook events do not corrupt state
277.4594770000001ms
token counts accumulate through hook events
17.857760999999982ms
client_register {clientType:"tui"} appears in getTuiClients until the WS closes
410.0717750000001ms
malformed tui client_register falls back to a "terminal" identity
117.90719400000012ms
tier3-integration.test.ts
16 / 16 265ms
mDNS crash recovery 3 / 3
invalidateMdnsInstance does not throw when no instance exists
3.512238000000025ms
isNonFatalMdnsError matches recoverable mDNS multicast failures
0.6978199999999788ms
isNonFatalMdnsError does NOT match unrelated fatal errors
0.3417850000000726ms
Display sleep/wake broadcast 7 / 7
DisplayMonitor initial state is ON
0.3855200000000423ms
parses macOS lock/session presence from ioreg output
1.6032940000000053ms
treats an absent ScreenIsLocked key as UNLOCKED when IOConsoleUsers is visible
0.44479899999998906ms
display_state event has correct shape
0.2537720000000263ms
display_state broadcasts to WS clients
90.72974299999998ms
display_state broadcasts to multiple clients
58.655028000000016ms
SSE also receives display_state
76.18045299999994ms
Voice transcription endpoint 4 / 4
returns 503 when no voice manager is set
14.491957999999954ms
returns 400 for empty audio data
4.78861900000004ms
returns transcription from voice manager
5.187991000000011ms
returns 500 when voice manager throws
4.705884999999967ms
WsServer broadcast hooks (serial relay) 2 / 2
onBroadcast hook receives all broadcast events
1.505847000000017ms
broadcast hook errors do not crash server
1.0337070000000494ms
Stream Deck Plugin UI PASS
Are plugin connections, option layouts, and renderers correct?
63 passed 0 failed 3 files 1.7s
connection-manager.test.ts
17 / 17 17ms
ConnectionManager 17 / 17
starts disconnected
3.6808619999999905ms
start() begins bridge connection to daemon
1.861221999999998ms
start() installs a port provider so daemon.json is re-read every attempt
0.5294169999999667ms
emits connected when bridge connects
1.520419000000004ms
emits disconnected when bridge disconnects
0.5890770000000316ms
forwards state_update from bridge
1.059364999999957ms
send() delegates to bridge
2.0174769999999853ms
send() drops command when not connected
0.3910189999999716ms
getBridgePort returns bridge port
0.42654199999998355ms
getConnectionSnapshot exposes connection and discovery state
0.3950950000000262ms
retryNow probes daemon discovery and reconnects immediately when disconnected
0.5597129999999879ms
switchToOpenClaw() › sends switch_agent command to bridge
0.7368490000000065ms
switchToClaude() › sends switch_agent command to bridge
0.4646690000000149ms
findDaemonPort() candidate fallthrough › prefers the CLI daemon when it is healthy
0.6787820000000124ms
findDaemonPort() candidate fallthrough › falls through to the Swift daemon after the CLI port fails
0.5238679999999931ms
findDaemonPort() candidate fallthrough › reports the daemon as found even when every candidate has failed
0.7169989999999871ms
findDaemonPort() candidate fallthrough › reports missing when no daemon.json exists
0.44721299999997655ms
connection-integration.test.ts
6 / 6 1.7s
ConnectionManager Integration — Real WebSocket 6 / 6
client connects and receives broadcast events
230.95964999999995ms
multiple clients receive same broadcast
211.24296200000003ms
client sends command to server
154.24849299999994ms
handles rapid connect/disconnect without crashes
410.7744650000001ms
server detects client disconnect
253.08487600000012ms
bridge → gateway priority: second server takes over on disconnect
406.2081249999999ms
renderer-snapshots.test.ts
40 / 40 31ms
utility-renderer snapshots 2 / 2
renderUtilityGeneric with icon
6.129898999999966ms
renderUtilityGeneric muted (text-only value)
0.7395040000000108ms
launcher-renderer snapshots 3 / 3
renderLauncher first entry
0.7659429999999929ms
renderLauncher last entry
0.32030199999996967ms
renderLauncherEmpty
0.39480399999996507ms
usage-dial-renderer snapshots 1 / 1
renderUsageSession
0.7104499999999803ms
usage-gauge snapshots 7 / 7
renderUsageGauge Claude 5h (green ramp, low usage)
1.671385999999984ms
renderUsageGauge Claude 7d
0.461024000000009ms
renderUsageGauge Codex 5h uses the blue brand logo + amber ramp
0.8979319999999689ms
renderUsageGauge Codex 7d
0.5201830000000314ms
renderUsageGauge critical (>80 used → red ramp)
0.5750759999999673ms
renderUsageGauge full-bleed fill (no narrow 60px tank rect)
0.39393400000000156ms
renderUsageGauge unknown draws a dim tile + dash, no fill
0.6165479999999661ms
usage-encoder level-fill (SD+ 200x100) snapshots 7 / 7
both-view Claude shows both windows + terracotta brand logo
1.2690400000000182ms
both-view Codex uses the blue brand logo + severity ramp
0.776348999999982ms
single 5h view enlarges the 5H window across the LCD
0.5526219999999853ms
single 7d view enlarges the 7D window across the LCD
0.46551099999999224ms
note suppresses the gauges (No Codex usage)
0.5407440000000179ms
Waiting note before the first usage payload
0.3942030000000045ms
a single unknown window draws a dash panel, the other a real fill
0.4811539999999468ms
session-slot-renderer snapshots 10 / 10
disconnected hero is icon-rich
1.7982979999999884ms
disconnected non-center slot is empty
0.40083400000003166ms
disconnected cluster quadrant tl
0.5452809999999886ms
disconnected cluster quadrant tr
0.4066420000000335ms
disconnected cluster quadrant bl
0.4463519999999903ms
disconnected cluster quadrant br
0.3899769999999876ms
connected no-session card is icon-rich
0.44078400000000784ms
active idle session uses orbiting focus border
1.4177050000000122ms
stale session dims the render and shows a STALE badge
0.47088899999999967ms
wraps names with larger typography on original Stream Deck keys
0.592552000000012ms
display-tile snapshots 6 / 6
renderStatusReadout MODEL is flat (no raised bezel, no glyph)
0.5537530000000288ms
renderStatusReadout READY (label only)
0.2502269999999953ms
renderStatusReadout AWAITING
0.35292100000003757ms
renderStatusReadout HUB READY (no-session hub state)
0.27717799999999215ms
renderSessionReadout keeps name/model/state, flat & non-interactive
0.5655320000000188ms
renderSessionReadout openclaw hides model, shows STANDBY
0.3073529999999778ms
agent-logos snapshots 4 / 4
claude-code watermark
0.480433000000005ms
openclaw watermark
0.5354859999999917ms
antigravity icon uses the full-color mark
0.6000030000000152ms
CLAUDE_LOGO_PATH is defined
0.445650999999998ms
TUI Dashboard PASS
Does the terminal dashboard render state and terrarium motion correctly?
53 passed 0 failed 3 files 75ms
tui-dashboard.test.ts
10 / 10 24ms
TUI dashboard models 10 / 10
stores modelCatalog from state_update
3.7541820000000143ms
renders OAuth catalog and Ollama models in wide layout
4.605093000000011ms
renders disconnected OAuth state
1.2167119999999727ms
renders downstream module health compactly
0.9997749999999996ms
renders Stream Deck, WiFi-only ESP32, and TUI dashboard downstream rows
0.9340460000000235ms
shows current session summary and control hints
0.6181310000000053ms
renders agent list secondary line as model dash compact state
0.5449610000000007ms
renders sibling models in session bridge mode and omits uptime label
0.91724099999999ms
renders help overlay when helpVisible is on
0.6104690000000232ms
shows numbered session badges
8.55908599999998ms
tui-renderer-snapshots.test.ts
29 / 29 18ms
blockGauge snapshots 7 / 7
0% — all empty, green
5.857307999999989ms
50% — half filled, green
0.5153460000000223ms
75% — yellow threshold
0.34848500000003924ms
95% — red threshold
0.3028960000000325ms
100% — all filled, red
0.4644000000000119ms
clamps negative to 0
0.3195210000000088ms
clamps above 100
0.304678000000024ms
resetTimeStr 5 / 5
returns empty for undefined
0.5884960000000206ms
returns ↻now for past time
0.4875640000000203ms
formats minutes
0.5119209999999725ms
formats hours and minutes
0.2593699999999899ms
formats days and hours
0.31439399999999296ms
formatUptime 3 / 3
seconds
0.2827050000000213ms
minutes
0.21575500000000147ms
hours and minutes
0.19727700000004234ms
formatTokens 3 / 3
below 1000 unchanged
0.26712200000002895ms
1k-10k with decimal
0.23204899999996087ms
10k+ rounded
0.21045700000001943ms
activityDensityBar 3 / 3
empty timestamps — all dim
0.446091000000024ms
recent burst — bright right side
0.4694069999999897ms
spread timestamps — distributed density
0.34143399999999247ms
getLayout 3 / 3
wide for 120+ cols
0.37335200000001123ms
standard for 80-119 cols
0.27939100000003236ms
narrow for <80 cols
0.24136299999997846ms
shouldShowTerrarium 3 / 3
true for adequate size
0.296196000000009ms
false for too narrow
0.19903899999997066ms
false for too short
0.175754999999981ms
spinner 2 / 2
returns braille characters at different frames
2.271049000000005ms
spinner cycles through 10 frames
0.329796999999985ms
tui-terrarium-snapshots.test.ts
14 / 14 33ms
TUI terrarium snapshots 14 / 14
initTerrarium creates context with expected structure
6.163298999999995ms
setOctopi configures octopus instances
1.0333860000000072ms
draws an octopus for Claude and for nobody else
1.3978950000000054ms
setCrayfish configures crayfish state
0.6889470000000415ms
setJellyfish configures jellyfish instances
0.8687479999999823ms
renderTerrariumFrame empty terrarium (small)
5.537567000000024ms
renderTerrariumFrame empty terrarium (large)
2.092140000000029ms
renderTerrariumFrame with idle octopus
3.0616489999999885ms
renderTerrariumFrame with processing octopus
2.5303289999999947ms
renderTerrariumFrame with routing crayfish
3.654162000000042ms
renderTerrariumFrame with sick crayfish
2.667256000000009ms
renderTerrariumFrame with OpenCode hollow ring
2.299221999999986ms
renderTerrariumFrame too small returns empty
0.5886559999999577ms
updateTerrarium advances bubble positions
0.6421770000000038ms
Serial Protocol PASS
Is the ESP32 serial byte stream framed correctly?
69 passed 0 failed 1 files 50ms
esp32-serial-node.test.ts
69 / 69 50ms
SERIAL_FORWARDED_EVENTS 4 / 4
includes all display events
3.3202290000000403ms
includes timeline events (unique to serial)
0.3365559999999732ms
does NOT include plugin-only events
0.42726300000003903ms
required serial events are present
0.41887100000008104ms
ESP32 port detection patterns 5 / 5
matches CH340 ports (86 Box)
0.5999229999999898ms
matches native USB JTAG ports (IPS 3.5", Round AMOLED)
0.38526999999999134ms
matches Linux serial ports
0.35349199999996017ms
excludes Bluetooth and WLAN
0.2648389999999381ms
excludes non-ESP32 ports
0.3999220000000605ms
handleSerialLine (source) 7 / 7
parses device_info message and updates deviceInfo
1.276391999999987ms
skips debug lines (non-JSON)
0.702637999999979ms
opens a panic capture window on crash markers and captures the dump
2.3318199999999933ms
closes the panic window after expiry and caps captured lines
0.28045299999996587ms
recovers from malformed JSON
0.5703490000000784ms
ignores JSON without type field
0.2423949999999877ms
does not mark deviceInfo present for non-identifying messages
0.3860509999999522ms
budgetTimelineEntries 2 / 2
keeps the newest entries under the byte budget, in chronological order
4.774557999999956ms
passes small histories through untouched
1.2503729999999678ms
serial I/O error classification 2 / 2
treats nonblocking backpressure as retryable
0.38433900000006815ms
does not retry terminal serial errors
0.28408699999999953ms
prepareForSerial (source) 14 / 14
strips agentCapabilities from state_update
0.9112619999999652ms
strips billingType and remoteUrl from state_update
0.3047780000000557ms
preserves essential state_update fields
2.048084000000017ms
strips bulky state_update fields before device_info arrives
0.7252210000000332ms
trims sessions_list to firmware fields and string sizes
1.17641100000003ms
forwards per-session D1 mosaic fields (tool/elapsed/awaiting prompt) and trims oversized strings
1.5422620000000506ms
round-robins sessions_list by agent type so non-Claude agents survive the cap
1.3595269999999573ms
roundRobinByAgentType keeps every present agent type and is a no-op under the cap
0.8070249999999533ms
strips legacy usage fields from usage_update
0.8128429999999298ms
preserves Codex window freshness for firmware-side hiding
1.3037530000000288ms
passes through other events unchanged
0.2478329999999005ms
caps timeline raw by UTF-8 BYTES on a code-point boundary (한글-safe)
0.757280000000037ms
forwards daemon-computed lastEvent* fields byte-capped, omitted when absent
1.525617000000011ms
caps timeline_history to the firmware ring (64) AND the line-buffer byte budget
0.9026890000000094ms
WiFi provision protocol 5 / 5
provision message has all required fields
2.053270999999995ms
auto-provisions first-setup boards and refreshes IPS10 endpoint while online
0.3750049999999874ms
re-arms the pairing token on boards the WiFi gate skips
0.28908500000000004ms
costs one write per board per token, not one per device_info frame
0.277197000000001ms
never writes a credential to an unidentified or empty peer
0.25701699999990524ms
serial buffer management 3 / 3
line splitting handles multiple lines in one chunk
0.4015549999999166ms
handles partial message across chunks
0.44322699999997894ms
truncates buffer when exceeding 8KB limit
0.16896500000007109ms
foreign port detection 3 / 3
flags a port that opened but never sent valid JSON
0.21915999999998803ms
does NOT flag a connection that ever read a valid AgentDeck message
0.1797310000000607ms
does NOT flag a connection that already identified its board
0.18446800000003805ms
foreign port denylist threshold 2 / 2
denylists a port only after repeated failed probes
0.44369800000004034ms
treats an elapsed cooldown as no longer denylisted
0.2560449999999719ms
half-open identified CDC recovery 5 / 5
flags an identified CDC port that has never read since (re)connect
0.39026699999999437ms
does NOT flag while the read pipe is alive
0.24077299999999013ms
does NOT flag inside the grace window after connect
0.18939499999999043ms
does NOT flag an unidentified CDC port — that is the foreign path
0.22067200000003595ms
does NOT flag a UART (non-CDC) port — handled by the read-timeout branch
0.16385700000000725ms
serial keepalive ack contract 2 / 2
contains the quoted "keepalive" substring the firmware strstr-matches
0.18940499999996518ms
is the exact frame the deployed firmware acks
0.14824299999997947ms
half-open identified UART recovery 6 / 6
flags an identified UART whose RX died mid-connection
0.2654489999999896ms
does NOT flag while reads are current
0.21094699999991917ms
does NOT flag below the silence timeout (one lost device_info is not death)
0.1794600000000628ms
does NOT flag a never-read UART — that is the initial-read/foreign path
0.1581579999999576ms
does NOT flag an unidentified UART
0.1644179999999551ms
does NOT flag a CDC port — handled by isHalfOpenIdentifiedCdc/CDC clauses
0.15881899999999405ms
device-info re-identify gating 6 / 6
retries a brand-new (unseeded) connection that has not yet identified
0.2802719999999681ms
retries a CACHE-SEEDED connection (stale deviceInfo, not yet fresh) — the inkdeck bug
0.16903400000001056ms
STOPS once a live device_info has landed on this connection
0.1535310000000436ms
stops after the request budget is exhausted
0.17233900000007907ms
paces requests — no retry inside the retry interval
0.25143900000000485ms
does not retry a disconnected connection
0.236095999999975ms
serialOpenFailureBackoffMs 3 / 3
ramps 10→20→40→80→160→300s and reaches the 5-min block at the 6th failure
0.4919310000000223ms
never exceeds the 5-min block for any transient failCount
4.940688000000023ms
uses the flat 5-min block for EACCES (permanent) failures
0.2902970000000096ms
Display Rendering PASS
Is image data for external displays rendered correctly?
19 passed 0 failed 1 files 69ms
pixoo-sprites.test.ts
19 / 19 69ms
getOctopusPaletteForSession 3 / 3
keeps the first additional session near the original terracotta tone
4.403308999999979ms
darkens later sessions while preserving channel ordering
0.6521820000000389ms
clamps very large session indices to the darkest supported tone
0.3971180000000345ms
creatureCellSize 10 / 10
is monotonic non-decreasing across a zoom sweep (cols=24, 32px)
9.977659999999958ms
is monotonic non-decreasing across a zoom sweep (cols=14, 32px)
7.159348000000023ms
is monotonic non-decreasing across a zoom sweep (cols=12, 32px)
6.761459000000002ms
is monotonic non-decreasing across a zoom sweep (cols=8, 32px)
8.458092999999963ms
is monotonic non-decreasing across a zoom sweep (cols=24, 64px)
5.777206999999976ms
is monotonic non-decreasing across a zoom sweep (cols=14, 64px)
7.054910000000007ms
is monotonic non-decreasing across a zoom sweep (cols=12, 64px)
7.101081000000022ms
is monotonic non-decreasing across a zoom sweep (cols=8, 64px)
6.387024999999994ms
is stable for sub-0.25 zoom jitter around a value (no flicker)
0.5783609999999726ms
never returns less than 1
0.21896000000003824ms
Codex cloud low-detail grids 2 / 2
keeps the MD cloud as one rounded body instead of separated dangling lobes
1.7044159999999806ms
keeps the LOD cloud rounded for iDotMatrix-wide shots
0.35825899999997546ms
quantizeCameraPixels 4 / 4
snaps the center onto the device-pixel grid
0.3936219999999935ms
is idempotent
0.22241500000001224ms
preserves zoom and width
0.22153300000002218ms
defaults width to 64 and tolerates degenerate scale
0.2625760000000241ms
Hook Installation PASS
Are Claude Code hook installation, removal, and migration safe?
44 passed 0 failed 1 files 314ms
install.test.ts
44 / 44 314ms
Hook Installer 30 / 30
buildHookEntry › creates matcher-group format with AGENTDECK_PORT env var
3.6233950000000164ms
buildHookEntry › uses `*` matcher for tool events and empty matcher for lifecycle events
0.44588199999998324ms
buildHookCommand (POSIX) › reads PORT from AGENTDECK_PORT env var first, then daemon.json, then 9120
0.38726300000001856ms
buildHookCommand (POSIX) › keeps strict port-validation markers in every co-owned hook writer
1.8754040000000032ms
buildHookCommand (POSIX) › rejects non-numeric and out-of-range ports before URL construction
242.56562100000002ms
buildHookCommand (POSIX) › accepts a validated daemon.json port
32.48266799999999ms
buildHookCommand (POSIX) › bounds the fire-and-forget POST so a wedged daemon cannot stall session exit
0.426853000000051ms
buildHookCommand (POSIX) › emits newline-separated shell so if/then/for/do keywords are not mis-terminated by `;`
0.3337219999999661ms
buildHookCommandWin (Windows) › wraps a PowerShell one-liner that targets the event endpoint
0.3906680000000051ms
buildHookCommandWin (Windows) › uses single-line PowerShell so cmd.exe can pass it as one -Command argument
0.12154300000008789ms
buildHookCommandWin (Windows) › omits the macOS App Store sandbox-container fallback paths
0.12493799999992916ms
buildHookCommandWin (Windows) › reads stdin as UTF-8 and posts UTF-8 bytes with charset (#46)
0.25561500000003434ms
applyHooks › installs hooks to empty settings in matcher-group format
3.6513270000000375ms
applyHooks › preserves non-AgentDeck hooks
0.5314999999999372ms
applyHooks › replaces old flat-format hooks
0.3552149999999301ms
applyHooks › replaces old matcher-format hooks
0.36301700000001347ms
applyHooks › is idempotent — running twice produces same result
0.8851219999999103ms
applyHooks › preserves existing non-hook settings
0.8774009999999635ms
removeHooks › removes all AgentDeck hooks (new format)
0.3234469999999874ms
removeHooks › removes old flat-format AgentDeck hooks
0.16394600000000992ms
removeHooks › preserves non-AgentDeck hooks
0.2373169999999618ms
removeHooks › handles empty settings gracefully
0.11501300000008996ms
migrateHooks › migrates old hardcoded port to env var
0.3303969999999481ms
migrateHooks › migrates flat format to matcher-group format
0.22265500000003158ms
migrateHooks › skips already-migrated hooks (new format)
0.15634499999998752ms
migrateHooks › skips non-AgentDeck hooks
0.10750200000006771ms
migrateHooks › migrates multiple events at once
0.48775399999999536ms
migrateHooks › migrates hardcoded port inside matcher-group
0.21775800000000345ms
migrateHooksIfNeeded (file-based) › upgrades old :-9120 fallback hooks to daemon.json-reading format
0.15241900000000896ms
migrateHooksIfNeeded (file-based) › self-heals installed hooks that predate strict port validation
2.0659010000000535ms
steering hook channels (request-response) 2 / 2
PreToolUse and Stop echo the daemon response to stdout; others stay fire-and-forget
0.288283999999976ms
migration 5 rewrites legacy Stop hooks to the current platform hook set (request-response on POSIX)
0.3881050000001096ms
install target (~/.claude/settings.json) 5 / 5
installs into the watched settings.json, never settings.local.json
2.8233809999999266ms
strips AgentDeck hooks out of the legacy file while keeping the user keys
1.2454549999999927ms
relocates pre-move installs from the legacy file into settings.json
3.7382980000001ms
leaves a settings.json without AgentDeck hooks untouched
0.6696980000000394ms
uninstalls from both the current and the legacy file
1.7511769999999842ms
Kiro v3 global hook installer 3 / 3
skips hosts where Kiro has never created its config root
1.5224719999999934ms
writes the measured v1 standalone schema with prefixed lifecycle endpoints
1.4121360000000323ms
is idempotent, preserves an occupied path, and only removes its own file
1.1463959999999815ms
migration 7 — unbounded curl self-heal 3 / 3
flags a pre-fix hook set that every earlier migration passes by
0.9667660000000069ms
rebuilds unbounded hooks on migrate and then leaves the file alone
1.6965649999999641ms
does not flag the request-response hooks for lacking a short timeout
0.5663729999999987ms
uninstall wiring 1 / 1
the uninstall entry point actually calls the Kiro remover
0.3746139999999514ms
Other Tests
Uncategorized test files
2287 passed 0 failed 183 files
adb-transport.test.ts
4 / 4 3ms
isNetworkAdbTransport 4 / 4
flags adb-over-TCP serials (adb connect :)
3.0211089999999956ms
flags wireless-debugging mDNS instance names
0.23433299999999235ms
passes USB serials through
0.16659099999998261ms
does not flag the local emulator
0.12415699999999674ms
antigravity-transcript.test.ts
4 / 4 5ms
antigravity transcript parsing 4 / 4
extracts goal, model (from settings change), state and tool task
3.4054859999999962ms
reports processing when the newest step is RUNNING; later model change wins
0.5279340000000161ms
reports idle when only historical steps are RUNNING (newest step is DONE)
0.327321999999981ms
matches the agy CLI binary as an Antigravity process
1.3459459999999694ms
apme-abandoned-run-reaper.test.ts
7 / 7 79ms
abandoned APME run reaper 7 / 7
finds runs with real work that the empty-shell reaper cannot see
24.39394599999997ms
measures staleness from last activity, not started_at
9.278398999999979ms
counts steps and sample events as activity, not just turns
9.587535000000003ms
closes turns, tasks and the run at the last activity, not now
12.167558999999983ms
is idempotent and drops out of the candidate list once reaped
7.369254000000012ms
leaves reaped runs to the normal eval queue
7.9300890000000095ms
reports a run the collector still owns as live
8.12786699999998ms
apme-category-e2e.test.ts
3 / 3 53ms
APME category-aware turn evaluation (E2E) 3 / 3
conversation turn: prompt → classify → judge → turn category + composite persisted
30.520309000000026ms
research turn: rule-based classifier picks research, judge uses research rubric axes
12.517130000000009ms
daemon backfill pass: turns with response but no outcome get committed + null composite
10.459351999999967ms
apme-classifier.test.ts
18 / 18 86ms
classify() 12 / 12
planning — plan mode used
2.9456950000000006ms
planning — short session, no file changes
0.2971369999999638ms
research — web searches dominant
0.24450799999999617ms
research — grep/glob dominant, no file changes
0.36554000000000997ms
coding — edit+write dominant with file changes
0.30160399999999754ms
debugging — tests + edits + bash
0.2257799999999861ms
refactoring — many edits, no new files
0.24481900000000678ms
review — mostly reads, minimal edits
0.23551499999996395ms
ops — bash dominant, few edits
0.24693200000001525ms
conversation — very short, no tools
0.19827800000001616ms
multi_agent — multiple Agent delegations
0.23222999999995864ms
unknown — no clear pattern
0.2520600000000286ms
computeSignals() 3 / 3
counts tool calls and identifies dominant tool
27.82514299999997ms
detects plan mode from step payload
10.351464000000021ms
detects web searches
10.50761ms
classifyRun() 2 / 2
returns signals and category for a coding run
9.802659000000006ms
returns unknown for empty runs
11.768358000000035ms
task_category schema migration 1 / 1
runs table has task_signals, task_category, task_category_source columns
9.343646999999976ms
apme-collector.test.ts
15 / 15 233ms
ApmeCollector 15 / 15
openRun → ingestHook → closeRun persists a run with steps
51.52494200000001ms
updateUsage and updateModel reflect in the run row
10.722193000000004ms
listRuns filters by agent and orders by started_at desc
19.662072000000023ms
default rubric v1 is seeded on init
8.201999ms
insertEval + listEvalsForRun round-trip
9.397878999999989ms
excludes _empty runs from the unevaluated run queue
12.279808000000003ms
scorecard view aggregates runs per model
10.111984000000007ms
multi-turn cycle captures prompts and responses (wireAgentApme path)
32.50628900000004ms
setLastClosedTurnResponse fills missing response on closed turn
11.044928000000027ms
setTurnResponse tags efficiency_json.response_kind (text / tool_only / empty)
14.306369000000018ms
no-op gracefully when store is disabled
10.397483999999963ms
ignores an echoed duplicate turn_start (same prompt on a fresh empty turn)
10.398626000000036ms
treats a same-prompt re-send after a response or tool use as a new turn
10.909493999999995ms
an agent_error span records the failure reason in the trajectory without closing the task
12.033036999999922ms
drops an agent_error span with no open task instead of inventing one
8.554459000000065ms
apme-dashboard-html.test.ts
4 / 4 4ms
apmeDashboardHtml — data-quality affordances 4 / 4
explains an un-scored completed run instead of showing a bare header
3.2945100000000025ms
surfaces manual reviews as a distinct, layer-filtered section
0.45889099999999416ms
each aggregate tab has a graceful empty state (no NaN / blank grid)
0.29320099999998206ms
active sessions are flagged as pending, not silently score-less
0.1859100000000069ms
apme-http.test.ts
13 / 13 282ms
APME HTTP routes 13 / 13
returns 503 when APME is not initialized
56.87158699999998ms
GET /apme/runs lists recent runs with evals and overall score
30.93370200000004ms
GET /apme/runs filters by agent
11.900306ms
GET /apme/run/:id returns run detail with steps and evals
20.887663000000032ms
GET /apme/run/:id returns 404 for unknown runs
11.33489899999995ms
GET /apme/run/:id includes per-task rollup with attached evals
33.38111699999996ms
GET /apme/tasks/:id returns task detail with evals + turns
28.049744999999916ms
closeTaskExternal with manual signal records outcome + boundary_signal=manual
9.26347700000008ms
GET /apme/scorecard returns model aggregates
16.05064500000003ms
GET /apme/rubric/current returns seeded rubric v1
11.651903000000061ms
POST /apme/vibe records feedback and rejects unknown runs
23.574711999999977ms
POST /apme/recommend returns candidate list
16.56214ms
unknown /apme/* path returns 404
11.16082300000005ms
apme-judge-detect.test.ts
5 / 5 7ms
detectLocalJudgeProviders 5 / 5
drops embedding-only Ollama models
5.723556000000002ms
reports no provider when every Ollama model is an embedder
0.4866519999999923ms
keeps models from servers that report no capabilities at all
0.3544430000000034ms
still detects OpenAI-compatible servers via /v1/models
0.5323119999999903ms
returns nothing when no local server answers
0.291167999999999ms
apme-judge-probe.test.ts
19 / 19 105ms
probeJudgeBackend — MLX 4 / 4
returns unavailable when /v1/models is unreachable
5.240790000000004ms
returns unavailable when /v1/models advertises no chat-capable model
38.62072499999999ms
returns unavailable when chat ping fails (model not loaded)
1.4224219999999832ms
returns ready when catalog AND chat ping both succeed
1.0589439999999968ms
probeJudgeBackend — OpenClaw 4 / 4
returns unavailable when /health is unreachable
0.9456240000000093ms
returns unavailable when /health is up but /models is not (gateway not initialised)
1.0002359999999726ms
returns unavailable when configured model is not in /models catalog
1.0664760000000229ms
returns ready when /health + /models both up and model matches
0.9189139999999725ms
probeJudgeBackend — Anthropic API (opt-in backend) 1 / 1
returns unavailable with setup guidance when no credential is present
0.861095999999975ms
callJudgeWithMeta — effective backend labelling across fallback 3 / 3
FM happy path labels eval as foundationModels
1.473809000000017ms
FM→MLX fallback (fallbackToMlx=true) labels eval as mlx, not foundationModels
2.048023999999998ms
FM failure without fallbackToMlx propagates the error (no silent label drift)
2.4312000000000467ms
sanitizeForMlx — runtime fallback hygiene 4 / 4
strips FM endpoint and model when forcing to MLX
0.7838600000000042ms
strips OpenClaw endpoint and model when forcing to MLX
0.6403640000000337ms
returns the same cfg shape when already-clean MLX is passed
0.540493999999967ms
clears a custom MLX endpoint when source backend is MLX but model is overridden
0.5320210000000429ms
probeJudgeBackend — Foundation Models 3 / 3
returns unavailable when Swift daemon FM endpoint cannot be resolved
41.955655999999976ms
returns unavailable when FM endpoint responds with error body
1.2150800000000004ms
returns ready when FM endpoint responds with text
0.8373209999999744ms
apme-manual-review.test.ts
2 / 2 36ms
manual_review eval roundtrip 2 / 2
persists a manual_review eval on a task and reads it back with the layer flag intact
25.94802899999999ms
manual_review evals do not contaminate the automatic-layer filters
9.588510000000014ms
apme-observed-turn-response.test.ts
4 / 4 61ms
observed turn response archiving 4 / 4
archives the reply on the turn and as an assistant_message event
30.646848999999975ms
tags a tool-only turn so the judge skips it instead of scoring silence
8.254668000000038ms
keeps each turn's reply on its own turn across a multi-turn task
12.34054900000001ms
lands a late reply on the last closed turn without overwriting one
10.031873000000019ms
apme-pareto.test.ts
4 / 4 30ms
computePareto 3 / 3
keeps non-dominated points and drops dominated ones
3.8219040000000177ms
sorts the frontier cheapest → most expensive
0.3863020000000006ms
ignores models below minSamples
0.3439779999999928ms
ApmeRecommender on the Pareto frontier 1 / 1
recommends only frontier models, cheapest-first under a tight budget
25.028183000000013ms
apme-runner.test.ts
41 / 41 740ms
detectLanguage 4 / 4
recognizes TypeScript from package.json
3.59695499999998ms
recognizes Swift from .xcodeproj
0.7036490000000413ms
recognizes Kotlin from build.gradle.kts
0.48903599999994185ms
returns null for unknown paths
0.20654100000001563ms
parseJudgeJson 5 / 5
extracts scores and reasoning from a clean JSON blob
0.7310109999999668ms
rescales 0-10 axis to 0-1
0.21406199999989894ms
tolerates prose wrapping and code fences
0.1594199999999546ms
returns null when there is no JSON at all
0.11535400000002483ms
returns null when overall is missing
0.11934899999994286ms
effectiveJudgeModelTag 4 / 4
uses cfg.model for MLX when no pin is set
1.0314129999999295ms
uses llm.mlx pin over cfg.model for MLX backend
0.6260919999999714ms
ignores llm.mlx pin for non-MLX backends
0.5229969999999184ms
foundationModels uses the Swift-parity judgeModelLabel
0.32229499999994005ms
callJudge foundationModels routing 4 / 4
returns FM text on ok response
29.040501000000063ms
throws when FM reports unavailable and fallback is disabled
46.63143400000001ms
falls back to MLX when fallbackToMlx is true
158.102345ms
caches auto-resolved FM endpoint failure and routes subsequent calls straight to MLX
14.75344199999995ms
shouldJudge gating 4 / 4
never runs when sampleRate is 0
0.25252100000000155ms
skips clear passes when onlyWhenDisagreement is true
0.12434700000005705ms
runs on failures when onlyWhenDisagreement is true
0.1138819999999896ms
runs for clear passes when onlyWhenDisagreement is false
0.11487299999998868ms
ApmeRunner duplicate guard 1 / 1
does not enqueue the same run while it is already queued or running
13.81505900000002ms
ApmeRunner.runOne 5 / 5
records deterministic failures and invokes judge with rubric prompt
52.19500000000005ms
skips layer 2 on a clean pass when onlyWhenDisagreement is true
20.071587999999906ms
does not notify onResult for no-op run evals
9.75926800000002ms
enqueueTurn skips judge for tool_only and empty turns
35.70825300000001ms
swallows judge errors without inserting partial rows
21.980277ms
runDeterministic (end-to-end spawn) 3 / 3
runs sh-based commands against the project path and reports pass
78.9095040000002ms
captures exit code 1 as tests_pass=0
60.862503999999944ms
skips entirely when the worktree has no changes
41.59172199999989ms
onTaskEvaluated 3 / 3
fires after enqueueTask resolves and carries the composite score + outcome
29.651965999999902ms
derives outcome=fail for low composite scores
17.04004299999997ms
preserves a manually-set outcome — judge does not overwrite `abandoned`
16.151607000000013ms
buildJudgePrompt 2 / 2
includes rubric prompt + task + context fields
0.3446289999999408ms
collects the diff with user diff drivers disabled (--no-ext-diff)
46.50901099999987ms
judgeBackendSupported 3 / 3
darwin supports every backend
0.47244099999988975ms
darwin-only backends (foundationModels, mlx) are unsupported elsewhere
0.30765299999984563ms
portable backends stay supported off-darwin
0.231157999999823ms
judge failure backoff 3 / 3
a failed judge blocks immediate re-enqueue and retries after the backoff expires
12.169716999999991ms
a successful judge clears the failure state and persists evals
11.369617000000062ms
parks the run after JUDGE_RETRY_MAX_ATTEMPTS failures until restart
11.163917999999967ms
apme-sample-timeline.test.ts
8 / 8 7ms
sampleEventToTimeline projection 4 / 4
projects user_message → chat_start
3.58162200000001ms
projects a text assistant_message → chat_response but skips tool_only
0.5392820000000142ms
projects tool → tool_resolved with status mapping + input summary
0.4189099999999826ms
skips model and state events (no standalone row)
0.23492400000000657ms
OpenClaw session.tool / session.message → spans (previously dropped) 4 / 4
maps a running tool to a tool_call span carrying input
1.0200360000000046ms
maps a completed tool to a tool_result span carrying output
0.23638599999998178ms
maps a user message to turn_start and assistant to turn_response
0.39958200000000943ms
drops empty/blank messages and nameless tools
0.3861610000000155ms
apme-sample.test.ts
7 / 7 88ms
ApmeStore sample events 5 / 5
round-trips typed trajectory events into a SessionSample
29.68974000000003ms
dedups identical (task, dedupKey) at storage time
9.05735599999997ms
resolves a pending tool event in place (one row, not two)
7.271748000000002ms
recomputeSampleCost sums ModelEvents into the task header
7.67822000000001ms
local models price at $0; unknown models fall back to $0 but flag unpriced
7.319284000000039ms
ApmeCollector → SessionSample (Phase 1 dual-write) 2 / 2
builds a typed trajectory (user → tool pending→resolved → assistant) and cost
16.157437000000016ms
fires onSampleEvent once per inserted event (no dup double-emit)
11.038429000000008ms
apme-scorers.test.ts
6 / 6 6ms
TrajectoryQualityScorer 3 / 3
penalizes consecutive identical tool calls (churn)
3.1863270000000057ms
penalizes tool errors
0.3103669999999852ms
does not apply with fewer than 2 tools
0.18809300000000917ms
ToolEfficiencyScorer 1 / 1
is the success rate of resolved tools
0.5747849999999914ms
runSampleScorers 2 / 2
runs only applicable scorers and tags layer/scorer
1.249100999999996ms
returns nothing for a toolless conversation sample
0.2474420000000066ms
apme-settings.test.ts
14 / 14 11ms
loadApmeConfig — defaults + merge behaviour 11 / 11
returns full defaults when settings.json does not exist
3.646739999999994ms
returns full defaults when settings.json has no apme section
0.7870849999999905ms
returns defaults on malformed JSON (must not throw)
0.5225570000000062ms
merges user-set fields on top of defaults
0.7675360000000069ms
clamps sampleRate to [0, 1]
0.6840000000000259ms
falls back to mlx when judge.backend is unknown string
0.5641889999999989ms
honours judge.backend="api" (opt-in Anthropic API judge) without downgrading
0.5644489999999962ms
also wipes endpoint/model when falling back from unknown backend → "mlx"
0.6537450000000149ms
preserves user-set endpoint/model when keeping their chosen backend
0.5792120000000125ms
respects explicit enabled=false (opt-out)
0.4914799999999957ms
clamps deterministic.timeoutSec to [5, 1800]
0.7709810000000061ms
loadApmeConfig — DEFAULT_APME_CONFIG sanity 3 / 3
default backend is Foundation Models with local MLX fallback (cost-sensitive policy)
0.19068699999999694ms
default sampleRate is 1.0 (judge every closed run; cost is local)
0.11589399999999728ms
default enabled is true (zero-config activation)
0.10478699999998753ms
apme-stop-delivery.test.ts
21 / 21 266ms
turns.end_source 17 / 17
a real Stop closes the turn and tags it `stop`
34.082964000000004ms
a watchdog-injected Stop is tagged `synthetic_stop`, not `stop`
10.387179000000003ms
a turn still open when the next prompt arrives is tagged `next_prompt`
13.574256999999989ms
a duplicate/late Stop cannot re-attribute an already-closed turn
11.171438999999964ms
`ended_at` is stamped at the Stop, not at the following prompt
8.101527000000033ms
closing the run tags the open turn `session_end`, `/clear` tags it `clear`
11.589087000000006ms
a cancel is tagged `interrupted`, even though it arrives as a synthetic Stop
8.076319000000012ms
a client abort is tagged `aborted`, even though it arrives as a synthetic Stop
10.80410599999999ms
a cancel outranks an abort when both flags somehow arrive
12.128459999999961ms
a displaced turn whose transcript shows a cancel is `interrupted`, not `next_prompt`
9.46592099999998ms
a displaced turn whose transcript shows a client abort is `aborted`
9.259180000000015ms
a displaced turn the assistant never answered is `superseded`, not a lost Stop
10.994016999999985ms
a displaced turn that called tools is never `superseded`, whatever the transcript says
12.96050200000002ms
no evidence in the window still means `next_prompt` — absence is never a verdict
13.243352999999956ms
never reads a transcript for a non-Claude agent or a pathless hook
13.022706000000085ms
an unreadable transcript falls back to `next_prompt` rather than guessing
12.396333000000027ms
the response still lands on the turn when the Stop closes it first
13.285773000000063ms
ApmeStore.stopDelivery 4 / 4
buckets each closing signal and keeps open turns in the denominator
12.81544400000007ms
counts cancels in their own column, outside every loss bucket
13.126712999999995ms
reports pre-instrument rows separately instead of guessing a bucket
11.135334999999941ms
windows on started_at and can filter to one agent
13.284700000000043ms
apme-task-boundary.test.ts
15 / 15 327ms
ApmeCollector task boundaries 13 / 13
first UserPromptSubmit opens a task and attaches the turn
29.62448999999998ms
TodoWrite all-completed is a soft hint — does NOT close the task
16.764409ms
TodoWrite all-completed does not split — later turns stay in one task
19.357123ms
TodoWrite with partial completion does NOT close the task
11.846053999999981ms
next UserPromptSubmit after an explicit boundary opens a new task
21.34339200000005ms
splitRun closes the active task with boundary=clear
28.089098000000035ms
closeRun closes the active task with boundary=session_end
17.21058099999999ms
onTaskClosed fires on an explicit boundary with the task metadata
14.205736000000002ms
onTaskOpened is DEFERRED: fires on the second turn, not the first
15.923694000000012ms
onTaskOpened also promotes on a TodoWrite plan within the first turn
15.237680000000012ms
groups follow-up prompts under one header; single-turn stays headerless
27.440531999999962ms
onTaskClosed payload includes session, agent, project, and timing
17.59270600000002ms
empty task (no turns between two boundaries) is dropped
29.808492ms
ApmeRunner task eval 2 / 2
enqueueTask invokes judge with turns and persists summary + scores
33.80994199999998ms
skips task eval when all turns are tool_only / empty
28.216931000000045ms
apme-task-milestone.test.ts
2 / 2 32ms
TodoWrite-all-completed → onTaskMilestone 1 / 1
fires once per (task, turn) with attribution; not on partial todos
30.541072999999983ms
opencodeIdleGapTaskBoundary 1 / 1
builds a task_boundary span with the idle_gap signal
0.6742449999999849ms
apme-task-page-and-graph.test.ts
17 / 17 146ms
task page 6 / 6
carries the run context a bare task row lacks
23.796802000000014ms
counts turns whose reply was never archived
7.477547999999956ms
pages without losing the unfiltered total
9.003715999999997ms
filters by agent, project and open/closed state
8.847219999999993ms
hides bookkeeping shells the collector tagged _empty
7.249764000000027ms
offers facets from the whole store, not the current page
7.513130999999987ms
tool payload path extraction 4 / 4
reads a path from the tool input, wherever the shape puts it
0.4473639999999932ms
returns null rather than inventing a path
0.498911000000021ms
keys a file on its path relative to the project root
0.30425800000000436ms
falls back to the path tail without claiming two paths are one file
0.20429799999999432ms
graph projection 7 / 7
projects the containment spine and the derived entity hubs
11.142956999999967ms
connects two tasks that share only a file — the cross-link no ancestor gives
9.655026999999961ms
collapses repeated calls into one weighted edge
11.959595000000036ms
draws the /clear continuation edge only when both runs are in the slice
8.906939999999963ms
prunes one-off hubs but never containment nodes
12.604476000000034ms
reports what it left out so a partial slice never reads as complete
12.040627000000029ms
attaches trajectory to turns when asked, and to the task when not
13.32086499999997ms
apme-telemetry-envelope.test.ts
33 / 33 464ms
claudeHookToSpans 7 / 7
emits turn_start with prompt for UserPromptSubmit
3.4899239999999736ms
detects /clear and emits a task_boundary span (not turn_start)
0.46322800000001507ms
drops Claude task notification payloads from UserPromptSubmit
0.7441709999999944ms
emits tool_call for PreToolUse with gen_ai.tool.name
0.9165499999999724ms
emits tool_result for PostToolUse
0.2217340000000263ms
falls through to raw_step for unknown events (Stop, SessionEnd, …)
0.32223499999997784ms
handles legacy { prompt: ... } shape on UserPromptSubmit
0.1728310000000306ms
timelineEntryToSpans 12 / 12
translates chat_start to turn_start with detail as prompt
0.373361999999986ms
translates chat_response to turn_response
0.23232999999999038ms
translates chat_end with response detail to turn_response with fallback flag
0.1806320000000028ms
drops chat_response / chat_end with empty body
0.28911499999998114ms
translates tool_request with first-token tool name
0.28872499999999945ms
codex_user_prompt_submit → turn_start span
16.29862700000001ms
codex_user_prompt_submit with /clear → task_boundary span
0.45903099999998176ms
codex_tool_start → tool_call span with tool name
0.9386630000000196ms
codex_tool_end → tool_result span
0.420112999999958ms
codex_stop / codex_session_start / codex_turn_complete → raw_step
0.9948770000000309ms
translates tool_exec the same as tool_request (legacy + Codex paths)
0.4125310000000013ms
translates tool_resolved to a tool_result span
0.19163900000000922ms
ApmeCollector.ingestSpan dispatch 13 / 13
turn_start span opens a turn and records the prompt
45.341177000000016ms
turn_response span persists the response on the active turn
29.116890999999953ms
tool_call span increments tool_calls on the active turn
55.55967100000004ms
chat_end fallback does not clobber a prior closed turn response
48.99520800000005ms
Codex timeline path opens turn and counts tools (timelineEntryToSpans)
38.05874300000005ms
task_boundary span with signal=clear splits the run
31.533052999999995ms
task_boundary span with signal=manual closes the active task
33.802605000000085ms
task_boundary span with signal=idle_gap closes the active task
34.70289600000001ms
task_boundary span with signal=todo_complete is a soft hint — does NOT close the task
27.59696699999995ms
task_boundary span with an unknown signal is dropped (no task close, no throw)
23.247077999999988ms
raw_step span inserts a steps row without lifecycle effects
23.981040000000007ms
session_meta span updates the model id on the run
19.620863999999983ms
timeline adapter feeds the same dispatch path correctly
23.71985600000005ms
eval-schema constants 1 / 1
exports a stable schema version string
0.2688339999999698ms
ask-gate-decisions.test.ts
20 / 20 10ms
askGateDecision — who pays for the hold 4 / 4
holds only when there is no way to type into the session
2.9009670000000085ms
never holds when the answer could be typed instead
0.3295659999999998ms
never holds a session no device can see
0.30047299999998245ms
never holds with the gate off or nobody connected
0.2702470000000119ms
askPressVerdict — what may commit an answer 9 / 9
accepts a press that names the live question
2.5147560000000055ms
refuses a press that does not name its question
0.32738299999999754ms
refuses a press aimed at a question the prompt moved past
0.2095860000000016ms
refuses to answer an overlay the held gate does not own
0.15003600000000006ms
refuses anything that is not an option selection
0.15760700000001293ms
refuses an index that is not in the live option list
0.21578499999998257ms
matches on the option index, not its array position
0.2243580000000236ms
refuses when no question is open at all
0.16192399999999907ms
accepts an answer from a device that could only hold part of the question
0.6944660000000056ms
askEchoMatches — a truncated echo still names its question 7 / 7
accepts an exact echo
0.3100369999999941ms
accepts a long enough prefix
0.13409200000000965ms
refuses a prefix too short to identify the question
0.12147200000001135ms
refuses an echo that diverges from the live question
0.09793700000000172ms
refuses an echo LONGER than the live question
0.11934000000002243ms
accepts an echo cut inside a grapheme, as the Swift mirror does
0.3745839999999987ms
refuses a superseded question that shares a long prefix
0.1805219999999963ms
ask-gate.test.ts
6 / 6 10ms
AskUserQuestion ask-gate (device answer → agent) 6 / 6
delivers a single-question answer as the hook decision reason
6.154164999999978ms
walks a multi-question call one question at a time, then answers with all pairs
1.529923999999994ms
releases with an EMPTY body when nobody answers, so the terminal picker shows
1.1223490000000425ms
does not hold when nothing could answer, leaving zero added latency
0.4372280000000046ms
keeps a partially answered prompt out of the agent when the hold expires
0.5257609999999886ms
clears the prompt on PostToolUse when the tool did run (injection path)
0.4526909999999589ms
auth-token-adoption.test.ts
10 / 10 170ms
adoptPeerToken 7 / 7
serves the incumbent daemon token after adopting it
60.13812300000001ms
keeps accepting the superseded token so devices are not locked out mid-convergence
12.156813ms
survives a restart — adoption is persisted, not in-memory
20.55426399999999ms
is a no-op when the incumbent serves the token we already hold
9.616708000000017ms
refuses a missing or malformed peer token rather than adopting a blank credential
11.655777999999998ms
bounds the accepted key ring instead of growing it forever
8.66395399999999ms
never records the same token twice in the ring
9.54228599999999ms
rotateToken 1 / 1
retires the accepted ring too, or rotation would not retire a leaked token
10.247167999999988ms
data-dir resolution 2 / 2
keeps the token beside the rest of the daemon state
9.224077000000023ms
inherits the legacy credential instead of un-pairing an existing fleet
18.01759100000004ms
awaiting-overlay.test.ts
39 / 39 40ms
awaiting-overlay 39 / 39
set then get returns the trimmed question
7.1986479999999915ms
carries an optional requestId (actionable PreToolUse gate)
0.631610999999964ms
preserves a structured AskUserQuestion as a display-only option lifecycle
2.4203339999999685ms
rejects malformed AskUserQuestion payloads instead of surfacing a dead prompt
0.7549769999999967ms
does not let a generic permission Notification overwrite AskUserQuestion
0.6641800000000444ms
returns undefined for an unknown session
0.40875500000004195ms
survives a long away-wait, then expires past the generous backstop
1.054476999999963ms
re-setting refreshes the TTL (a follow-up prompt keeps the overlay alive)
0.5767280000000028ms
clear removes the entry and reports whether one existed
0.5282750000000078ms
caps question length at 120 chars
0.4326019999999744ms
looksLikePermissionMessage › matches genuine permission prompts
0.9200049999999464ms
looksLikePermissionMessage › rejects the idle ping, non-permission status text, and empty messages
0.5232669999999757ms
isPermissionNotification › uses notification_type when present — only permission_prompt awaits
0.637911000000031ms
isPermissionNotification › falls back to the message regex only when notification_type is absent
0.5620759999999905ms
shouldGatePreToolUse › gates in default / unknown modes (Claude may prompt)
0.5859320000000139ms
shouldGatePreToolUse › never gates when Claude will not prompt or execute
0.9953989999999635ms
shouldGatePreToolUse › acceptEdits auto-approves edits but still gates Bash
0.5485760000000255ms
applyAwaitingOverlayToObserved › flips a matching observed session to awaiting_permission with the question
1.0620989999999892ms
applyAwaitingOverlayToObserved › matches the uuid after stripping the observed:claude: / observed:codex: prefix
0.6534239999999727ms
applyAwaitingOverlayToObserved › leaves sessions untouched when no overlay exists
0.49211099999996577ms
applyAwaitingOverlayToObserved › propagates the requestId for actionable gates
0.6020169999999894ms
applyAwaitingOverlayToObserved › renders AskUserQuestion as awaiting_option with real choices and no actionable requestId
0.7921120000000315ms
transcript-recency supersession (ESC-dismissed prompt) › drops a display-only overlay once the transcript moves past it, and purges the entry
0.7134240000000318ms
transcript-recency supersession (ESC-dismissed prompt) › keeps the overlay while the transcript stays frozen (genuine wait)
0.6647609999999986ms
transcript-recency supersession (ESC-dismissed prompt) › holds within the jitter margin (a write at ~setAt is not a resolution)
0.625650999999948ms
transcript-recency supersession (ESC-dismissed prompt) › keeps the overlay when the session carries no transcript recency
0.5883150000000228ms
transcript-recency supersession (ESC-dismissed prompt) › never drops a held device-approval gate on recency (its tool is blocked, resolve via onResolved)
0.6548460000000205ms
transcript-recency supersession (ESC-dismissed prompt) › never drops AskUserQuestion on transcript mtime movement during a genuine wait
0.6603240000000028ms
AskUserQuestion tool lifecycle › ignores unrelated or stale tool completions
0.7943260000000123ms
AskUserQuestion tool lifecycle › clears only the matching PostToolUse/PostToolUseFailure id
0.6458519999999908ms
multi-group AskUserQuestion progression › presents the first group and keeps the rest for later
2.0173880000000395ms
multi-group AskUserQuestion progression › advances one group per answer and projects its question/options
1.215048999999965ms
multi-group AskUserQuestion progression › reports completion on the last group and keeps every Q→A pair
0.8750479999999925ms
multi-group AskUserQuestion progression › surfaces group position to devices only when there is more than one
2.4747859999999946ms
multi-group AskUserQuestion progression › skips malformed groups instead of presenting a dead prompt
0.8767500000000155ms
multi-group AskUserQuestion progression › ignores advancement when no option prompt is pending
0.57723900000002ms
multi-group AskUserQuestion progression › clears every group on the matching PostToolUse
0.6358769999999936ms
display-only notification flow (daemon restore contract) › permission_prompt notification → awaiting with NO requestId; next hook clears
0.8664649999999483ms
display-only notification flow (daemon restore contract) › idle ping / auto-approved tool never sets the overlay (the 2026-06-27 false-attention bug)
0.5066530000000284ms
ble-sync-squelch.test.ts
5 / 5 15ms
createSyncCycleSquelch 5 / 5
logs the first two occurrences of a cycle, then suppresses identical repeats
10.968203000000017ms
emits an hourly summary with the repeat count while suppressing
1.69371000000001ms
flushes and logs immediately when a different exit appears
1.4237739999999803ms
treats 1x vs 2x captures of the same retry error as the same cycle
0.6456819999999936ms
treats an exit after a long healthy run as a fresh incident
0.7712009999999907ms
ble-sync-status.test.ts
14 / 14 9ms
parseStatusLine 2 / 2
parses an AGENTDECK_STATUS line
3.016522000000009ms
rejects a non-status line and malformed JSON
0.3439380000000085ms
createBleLinkTracker 9 / 9
reports "sync not started" before anything is spawned
0.4393709999999942ms
reports no device when nothing is configured
0.16540900000001102ms
goes connected on a streaming status line — the regression this fixes
0.3756350000000168ms
distinguishes host-display pause from a dead link
0.3055399999999793ms
keeps hasFrame sticky across a disconnect and surfaces the error
0.1997299999999882ms
clears a stale error once the client recovers
0.1472219999999993ms
reports the backoff window after an exit, then falls back to connecting
2.144738999999987ms
surfaces a missing BLE runtime instead of an unexplained disconnect
0.2667820000000063ms
a respawn clears the connected flag until the child reports again
0.20469799999997917ms
mergeBleLinkSnapshots 3 / 3
is connected only when every panel is
0.41772899999998003ms
reports no-device state when there are no trackers yet
0.19316099999997505ms
takes the newest push time across panels
0.1624540000000252ms
bridge-core-sessions.test.ts
2 / 2 78ms
BridgeCore sessions_list 2 / 2
broadcastSessionsList enriches sessions before broadcast
20.875617000000034ms
sendInitialState sends enriched sessions_list to the connecting client
57.497990000000016ms
calendar.test.ts
16 / 16 46ms
parseCalendarSettings 1 / 1
accepts a single url or a list, rejects everything else
2.903311000000002ms
ICS parsing 3 / 3
unfolds continuation lines
0.3503369999999961ms
parses date, local, and UTC instants
0.5631979999999999ms
parses VEVENTs with summary escaping and TZID params
1.4653859999999952ms
occursOn (recurrence) 6 / 6
non-recurring: literal date only
0.4311090000000206ms
DAILY with INTERVAL and UNTIL
0.45497499999999036ms
WEEKLY honors BYDAY
0.36537000000001285ms
DAILY COUNT exhausts
0.22721200000000863ms
MONTHLY and YEARLY match the start day
0.22412700000000996ms
EXDATE removes an instance
0.193460999999985ms
buildTodayEvents 4 / 4
keeps only what is left of today, all-day first, capped and sorted
8.135167999999993ms
an in-progress event survives the past filter via its end time
0.25143900000000485ms
RECURRENCE-ID override replaces the master instance
0.3109880000000089ms
trims titles to the UTF-8 byte budget
0.4818949999999518ms
CalendarProvider 2 / 2
fetches, caches, and re-filters cached parses against the current clock
28.229810000000043ms
resolves undefined when unconfigured or on a cold failure
0.5645999999999844ms
card-feed.test.ts
41 / 41 40ms
classifySessionCard 3 / 3
permission gate → live with the long-poll TTL
5.970469000000037ms
awaiting prompt without requestId → live with the awaiting backstop TTL
1.7092140000000313ms
idle/processing sessions → info without expiry
1.6871699999999805ms
buildCardFeed 4 / 4
derives one card per session with cardId session:
1.1604269999999701ms
module cards (M7) follow the session projections and carry no session body
4.24583199999995ms
builds a module-only feed for an offline-first Pocket reader
0.509617999999989ms
pull cadence hint: idle roster → idle interval, active roster → active interval
0.785933ms
applyOutboxDecisions 11 / 11
dismiss is always acknowledged, never dispatched
1.9679629999999975ms
permission_decision applies only while the gate is still pending
2.1587499999999977ms
permission_decision without requestId/decision is rejected
0.2705569999999966ms
select_option routes session-scoped when the session is still awaiting
0.6761079999999993ms
select_option expires when the prompt question changed
0.3190500000000043ms
select_option expires when the session is no longer awaiting
0.243616999999972ms
unknown session → unknown_card
0.21748700000000554ms
respond routes through session_command with the value
0.5125020000000404ms
send_prompt queues via session_command for any alive session
0.4132020000000125ms
malformed decisions are rejected without dispatch, order preserved
0.3611940000000118ms
empty/absent decisions array → ok with no results
0.27098799999998846ms
FeedPullTracker 8 / 8
normalizes v4-mapped and loopback client addresses
0.3820350000000303ms
first pull carries no interval; the second measures it against the advertised cadence
0.865743000000009ms
a gap far off the advertised cadence is not counted as honoured
0.5341240000000198ms
compares against the cadence advertised on the PREVIOUS pull, not the current one
0.31814900000000534ms
learns the board from an outbox push and keeps it for later anonymous pulls
0.41986199999996643ms
tracks clients independently and reports the median observed interval
1.1306220000000167ms
bounds its history ring, newest first
0.4901580000000081ms
formats the pull line with the drift verdict
0.46166499999998223ms
conditional pull (deckSig) 7 / 7
stamps a deckSig and short-circuits to unchanged on a matching echo
0.6864029999999843ms
a ticking elapsedSec does not defeat the signature
0.340342000000021ms
an idle roster stays signature-stable across a long clock advance (the idle-night case)
0.6219360000000052ms
a real content change still breaks the match even when elapsedSec moves
0.31688700000000836ms
expiresAt churn does not defeat the signature (live cards re-stamp every build)
0.2968970000000013ms
content change breaks the match
0.683620000000019ms
glance is covered by the signature
0.42476900000002615ms
glance builders 5 / 5
trimUtf8Bytes trims on rune boundaries by byte budget
0.5107580000000098ms
buildGlanceUsage derives Claude and Codex rows with integer percents
1.5450109999999881ms
buildGlanceUsage emits no row for a provider with no numbers
0.17397199999999202ms
buildGlanceWrapup ranks attention first and folds overflow
0.5015149999999835ms
buildGlance returns undefined when there is nothing to say
0.28781399999996893ms
pull telemetry 3 / 3
parsePullTelemetry keeps in-range values and drops garbage
0.4678840000000264ms
tracker records telemetry and unchanged counts per client
3.4566940000000272ms
formats unchanged pulls and telemetry into the log line
0.45839999999998327ms
card-modules.test.ts
17 / 17 12ms
module card ids 2 / 2
round-trips module::, including keys that contain colons
2.6722230000000025ms
rejects session card ids and malformed ones
0.2715080000000114ms
sealModuleCard — the ≤4-choice rule as a clamp 6 / 6
binds at most three choices, because slot 1 is the device Later
1.2733070000000168ms
drops choices missing an id or a label rather than shipping a blank button
0.24425800000000208ms
caps context lines and omits empty collections entirely
0.2563260000000014ms
trims text to a UTF-8 byte budget on a code-point boundary
0.5466120000000103ms
bounds stable choice ids for fixed firmware outbox buffers
0.2551640000000077ms
stamps the card id and keeps the class/expiry the module asked for
0.2030059999999878ms
buildModuleCards 1 / 1
a module that throws is skipped, the rest of the feed survives
0.39687799999998674ms
THREAD module 4 / 4
produces nothing when there is no live session
0.36774299999999016ms
leads with how many threads need the user
0.4465820000000065ms
checkpoints an idle session with its last milestone
0.1891650000000027ms
says what did not fit instead of implying the list is complete
0.2897170000000244ms
card_choice routing 4 / 4
routes a choice to the authoring module with the card key
2.8836310000000083ms
is terminal — never retryable — for unknown, read-only, or id-less cards
0.33153899999999226ms
a throwing module reports error rather than taking the batch down
0.24109300000000644ms
reaches the module through the outbox path, without touching session state
0.7646710000000212ms
claude-interrupt-marker.test.ts
7 / 7 4ms
isClaudeInterruptRecord 6 / 6
matches both marker spellings Claude Code writes
3.184714000000014ms
matches on `interruptedMessageId` even if the marker text changes
0.36778400000000033ms
does NOT match the marker quoted inside a tool_result
0.19788800000000606ms
does NOT match an assistant that mentions the marker
0.18544900000000553ms
does not match ordinary records or junk
0.18016099999999824ms
tolerates an empty `interruptedMessageId` instead of trusting its presence
0.11117699999999786ms
isClaudeInterruptMessage 1 / 1
reads string content as well as text blocks
0.24087299999999345ms
claude-transcript-reader.test.ts
23 / 23 20ms
readLastTurn 7 / 7
extracts assistant text and user prompt from a text-only turn
3.9498669999999834ms
flags tool-only turns (tool_use blocks, no text blocks)
0.7216459999999927ms
concatenates text across multiple assistant records for one turn
0.6870140000000049ms
picks the LAST user prompt when multiple turns are in the file
0.6370390000000157ms
returns null for missing file
0.5368880000000047ms
skips malformed lines and continues parsing
0.5718809999999905ms
accepts legacy string content on both roles
0.5573389999999847ms
readTurnEndProbe 8 / 8
reports end_turn with the record timestamp on a finished turn
1.6069889999999987ms
skips trailing non-message records (mode markers)
0.675627999999989ms
reports tool_use mid-turn (prompt open / tools pending)
0.5653009999999767ms
reports the user role while a tool_result is the tail (assistant pending)
0.7170600000000036ms
returns null timestamp when the record has none, and null on unreadable file
0.5729120000000023ms
skips a truncated final line (concurrent write)
0.57270299999999ms
flags the ESC interrupt marker as the turn end
0.8629799999999932ms
does not read a quoted marker inside a tool_result as an interrupt
0.625392000000005ms
readOpenTurnEvidence 8 / 8
finds a marker buried under the retyped prompt that followed it
0.8334450000000118ms
will not pay this turn for the previous turn's cancel
0.5799930000000018ms
a stampless record does not hide markers behind it
0.5211640000000273ms
returns null on a clean turn and on an unreadable file
0.5936140000000023ms
distinguishes an unreadable transcript from one holding no evidence
0.6363580000000013ms
reports the client abort that ends a turn with no Stop hook
0.5569990000000189ms
will not pay this turn for the previous turn's abort
0.5861729999999739ms
reports a turn that never ran — two prompts, no assistant record between
0.5408149999999807ms
claude-turn-watchdog.test.ts
15 / 15 22ms
ClaudeTurnWatchdog 15 / 15
closes a turn whose Stop was dropped once the transcript shows end_turn
8.271924000000013ms
fires at most once per turn
1.8702260000000024ms
ignores the previous turn's end_turn (timestamp before turn open)
0.7655729999999892ms
closes a turn the user cancelled, tagged as an interrupt rather than a loss
0.8910919999999862ms
closes a turn the client aborted (usage limit / auth / API error)
0.7307400000000257ms
ignores the previous turn's abort
0.7238299999999924ms
ignores the previous turn's interrupt marker
0.7133739999999875ms
a plain user record is not an interrupt
0.6722719999999924ms
never closes a genuine wait (stop_reason tool_use)
0.6444500000000062ms
does not probe while the hook channel is active
1.970296999999988ms
disarms when the real Stop arrives
0.6957570000000146ms
skips the transcript read when mtime has not advanced
0.8193540000000041ms
disarms on SessionEnd without killing later recovery (/clear fires SessionEnd mid-session)
0.8195239999999728ms
stop() (bridge shutdown) disarms permanently
0.6038389999999936ms
waits without a transcript path and recovers once one is learned
0.7781319999999994ms
cli.test.ts
36 / 36 50ms
agentdeck CLI parser 1 / 1
reports a misspelled top-level command as unknown and suggests the closest command
7.976989000000003ms
esp32-ota target resolution 5 / 5
maps short aliases to their canonical device_info.board string
0.7517520000000104ms
leaves a canonical board string unchanged
0.292870999999991ms
passes an unknown target (e.g. a raw IP) through untouched for IP targeting
0.23288000000002285ms
every alias resolves to a board that is itself a canonical entry (self-consistent SSOT)
1.9396500000000287ms
drops the retired esp32_c6_147 board from the OTA target set
0.29388299999993706ms
tokenizeArgString 4 / 4
splits bare flags on whitespace
0.6771790000000237ms
collapses runs of whitespace and trims
0.23577499999998963ms
keeps a quoted value with spaces as one token
0.30451800000003004ms
returns [] for empty or undefined
0.31932099999994534ms
applyGlobalEnvArgs 9 / 9
splices env tokens immediately after the session subcommand
0.3532920000000104ms
inserts env tokens before user-typed flags (scalar options: retyping wins on last-write)
0.24394699999993463ms
applies to monitor as well
0.20953499999995984ms
is a no-op for non-session commands
0.23033599999996568ms
is a no-op for a non-session command whose positional VALUE is a session word
0.19156899999995858ms
is a no-op when the var is unset or empty
0.24754300000006424ms
does not match a session word that appears as a flag value
0.23987099999999373ms
skips the splice entirely when the user typed --no-env-args
0.22800299999994422ms
strips an env-smuggled --no-env-args instead of letting it half-disable the layers
0.20864400000004935ms
weaveAgentCommand 4 / 4
appends the per-agent var to the default command
0.3888960000000452ms
appends onto an explicit -c command without replacing it
0.18246499999997923ms
uses the agent-specific var and ignores others
0.20423800000003212ms
returns the command unchanged when the var is unset or blank
0.1759150000000318ms
resolveAgentCommand (per-agent half of the --no-env-args hatch) 2 / 2
weaves when env args are enabled
0.23679600000002665ms
returns the command untouched when the hatch disabled env args
0.17769700000008015ms
env defaults through real option parsing 3 / 3
an env-provided boolean flag sticks as the default
0.7086369999999533ms
--no-env-args genuinely overrides an env boolean per-invocation
0.3495060000000194ms
a retyped scalar option wins over the env default (last-write through parseArg)
0.44003200000008746ms
daemon autostart posture 5 / 5
--enterprise is the admin spelling of the loopback posture
0.4220660000000862ms
does not fold --local into --enterprise
1.314047999999957ms
a plain install carries no posture flags
0.20904400000006262ms
the LaunchAgent argv carries the posture, one per flag
7.886233000000061ms
a plain LaunchAgent is byte-identical to the pre-posture one
14.04001299999993ms
claude action wiring (parseAsync end-to-end) 3 / 3
without the hatch: env flags parse in and the agent command is woven
3.380710000000022ms
--no-env-args disables BOTH layers for the invocation
0.7604749999999285ms
a session bridge drives no device but ADB, even without --local
0.5873839999999291ms
codex-auth.test.ts
7 / 7 5ms
resolveChatGptRenewalDate 7 / 7
rolls a stale monthly window forward to the next renewal boundary
3.5577360000000056ms
rolls forward across many missed cycles in one step
0.31479400000000624ms
rolls a stale annual window forward by a year
0.20614000000000487ms
passes a future date through untouched
0.1828350000000114ms
leaves a past date raw when there is no start to derive a period
0.1765359999999987ms
leaves an untrustworthy (too-short) window raw
0.18568999999999392ms
passes malformed and empty inputs through
0.3318390000000022ms
codex-hook-silence.test.ts
5 / 5 15ms
CodexHookSilenceWarning 5 / 5
warns once when the PTY is active but no codex_* event ever arrived
11.757973000000021ms
stays quiet when any codex hook event arrives (channel proven)
1.2071369999999888ms
stays quiet when the terminal was barely used (session may not have started)
0.6680949999999939ms
warns late when activity only crosses the threshold after the deadline
0.6268929999999955ms
stop() disarms (session shutdown)
0.5879549999999938ms
codex-otel.test.ts
16 / 16 11ms
codex OTLP span parser 8 / 8
reads a full turn from dotted span names
3.424014999999997ms
normalizes underscore and slash span-name variants
0.3282039999999995ms
rejects short numeric ids and prefers the durable alias on the same span
0.6079949999999883ms
ignores a tool span own cwd but inherits the thread-scoped one
0.9491280000000017ms
falls through to resource-level attributes
0.22615999999999303ms
drops unknown spans and spans with no identity at all
0.2856299999999976ms
summarizes span names for diagnostics
0.32579999999998677ms
finds no durable identity in a live ChatGPT.app Codex batch
0.6256719999999802ms
CodexOtelTracker 8 / 8
overlays state and tool onto the matching observed row instead of duplicating it
1.6319770000000062ms
synthesizes a codex-app row only when the process scan found nothing
0.8775009999999952ms
rejects a superseded turnEnd so a stale span cannot close the live turn
0.385770999999977ms
lets a follow-up turn revive a thread its own turnEnd retired
0.31163899999998534ms
expires a finished thread, and a quiet one, instead of pinning a creature
0.5651909999999702ms
stops overriding observer state once its own observation goes stale
0.3710389999999961ms
never lets progress-only activity spans open or revive a thread
0.37207100000000537ms
leaves non-codex rows untouched
0.21131800000000567ms
codex-rate-limits-live.test.ts
21 / 21 412ms
parseLiveCodexRateLimits 4 / 4
maps the app-server shape onto the wire shape
3.7539309999999944ms
accepts the rollout spelling of the window length
0.22665100000000393ms
clamps out-of-range percentages
0.14771299999998178ms
returns null when the result carries no usable limits
0.16797299999998927ms
pickFresherCodexRateLimits 4 / 4
prefers the newer capture
0.2865120000000161ms
keeps a passive reading that is newer than the cached live one
0.13221900000002051ms
handles either side being absent
0.14840399999999931ms
lets a stamped snapshot beat an unstamped one
0.32665200000002415ms
shouldQueryCodexRateLimitsLive 4 / 4
queries when the passive snapshot has gone quiet
0.2285240000000215ms
skips while Codex is mid-turn (the rollout is writing fresh readings)
0.12024100000002136ms
honours the minimum interval between spawns
0.23072799999999916ms
backs off hard after repeated misses (no Codex CLI installed)
0.14469800000000532ms
codexSpawnPlan 5 / 5
runs a plain binary directly on posix
0.23452400000002172ms
asks for a shell on Windows .cmd/.bat shims, which spawn refuses to run bare
0.37627699999998754ms
quotes a shim path with spaces, since the shell re-parses the command line
0.15514300000000958ms
leaves a real Windows executable alone — the shell is only for the shims
0.14465799999999263ms
never asks for a shell on posix, even for a file that happens to end in .cmd
0.1722289999999873ms
queryCodexRateLimitsLive 4 / 4
reads the rate limits out of the JSON-RPC stream
38.017656999999986ms
resolves null when the server never answers, without hanging
303.80610300000006ms
resolves null when the binary does not exist
12.456403999999907ms
resolves null when the server exits before replying
50.33155099999999ms
codex-rate-limits.test.ts
18 / 18 32ms
parseCodexRateLimitsFromText 9 / 9
parses primary/secondary windows and converts resets_at to ISO
4.37321399999999ms
returns the most recent snapshot when multiple lines are present
0.3574179999999956ms
clamps used_percent into 0..100
0.30283600000001343ms
tolerates a truncated leading line (tail window cut mid-line)
0.20785300000000007ms
returns null when no rate_limits line exists
0.1788389999999822ms
omits a window missing required fields
0.32328699999999344ms
keeps a credit-based snapshot when windows are null
0.37687800000000493ms
prefers a windowed snapshot over an older credits-only one
0.1853399999999965ms
still returns null when neither windows, credits, nor limitId are present
0.17362099999999714ms
pickCodexRateLimits (file selection across day-dirs) 6 / 6
returns null when the tree does not exist
1.0030999999999892ms
picks the active prior-day rollout over a newer empty day-dir
14.14435499999999ms
falls through a newer empty file to an older one with data in the same day-dir
1.3557309999999916ms
chooses the newest captured snapshot across concurrent active rollouts
1.4633629999999869ms
invalidates the cache when a non-leading rollout writes a newer snapshot
1.786660000000012ms
reaches across a month boundary for a still-active prior-month session
1.4971539999999948ms
capturedAt (snapshot freshness anchor) 3 / 3
stamps the snapshot line timestamp, not the file mtime
1.2675979999999925ms
falls back to the file mtime when the line carries no timestamp
1.2312139999999943ms
falls back to the file mtime when the line timestamp is unparseable
1.1194250000000068ms
codex-rollout-response.test.ts
9 / 9 18ms
codex rollout response reader 9 / 9
locates a rollout by the session uuid embedded in the filename
5.933874000000003ms
prefers task_complete.last_agent_message (authoritative turn close)
1.719067999999993ms
falls back to the newest agent_message when no task_complete follows
1.265455999999972ms
returns empty for missing rollouts, malformed lines, and bad ids
1.5745310000000075ms
failed turns › reports the error a task_complete carries instead of a reply
1.5166729999999973ms
failed turns › reports a standalone error record
1.0103409999999826ms
failed turns › unwraps the upstream JSON body Codex nests in the message
1.107637000000011ms
failed turns › never inherits the previous turn's reply
1.249100999999996ms
failed turns › still returns a successful reply unchanged
1.5139489999999967ms
codex-turn-manager.test.ts
12 / 12 131ms
CodexTurnManager (hook-primary path) 8 / 8
happy path: UPS → tool_start → tool_end → stop emits one chat
32.780602999999985ms
a benign `message` on codex_stop is never rendered as an error
7.603643000000034ms
an explicit `error` on codex_stop renders the error close row
7.168937000000028ms
codex_stop does not reset subsequent turn_index numbering
13.423840999999982ms
codex_stop finalizes APME turn (endedAt set, tool_calls flushed)
11.89194299999997ms
next prompt opens a fresh chat_start
8.78194099999996ms
turn-complete notify closes a turn when codex_stop is absent
6.883033000000012ms
long-bash: hook tool_start + tool_end keep the same turn open
7.665861000000007ms
CodexTurnManager (stale-turn recovery on prompt-submit) 4 / 4
missed codex_stop: next prompt closes the stale turn and opens a fresh row
10.114508ms
late prompt text fills a tool_start-opened turn without splitting it
7.218758000000037ms
duplicate prompt echo within the window is a no-op
7.1128289999999765ms
text-less stale turn older than the fill window is closed, not filled
9.729852999999991ms
daemon-port.test.ts
15 / 15 14ms
daemon port — validation 2 / 2
accepts only integers inside the bindable range
2.256766999999968ms
rejects text that parseInt would silently truncate
0.49996299999997973ms
daemon port — precedence 7 / 7
falls back to the documented default when nothing is set
0.9228889999999978ms
orders flag › env › settings › default
0.3835980000000063ms
reads a persisted port stored as a string (hand-edited settings.json)
0.15184799999997267ms
ignores an unusable persisted port instead of refusing to start
0.7433699999999703ms
ignores a malformed env override the same way
0.2260010000000534ms
names every source
0.3147739999999999ms
waits long enough to outlast the measured kernel port reservation
0.2389699999999948ms
daemon port — persistence round trip 4 / 4
persists, reads back, and clears
3.1833520000000135ms
preserves unrelated settings when writing
1.0673570000000154ms
writes over a malformed settings.json rather than refusing
0.860635000000002ms
never records the port the daemon actually landed on
2.0120790000000284ms
port window exhaustion message 2 / 2
separates ports this install owns from ports it cannot see into
0.46897599999999784ms
does not tell a user to stop sessions they do not have
0.1971770000000106ms
daemon-takeover.test.ts
16 / 16 41ms
negotiateIncumbentDaemon 7 / 7
takes neither the token nor the port from another user's daemon
3.8591800000000376ms
refuses loudly when that port was asked for by name
0.4082750000000033ms
still hands the port over between two daemons of the same user
0.5325820000000476ms
proceeds when ownership cannot be proven, because absence is not evidence
0.5091559999999618ms
falls back to /shutdown when the app is too old for /stand-down
1.1291200000000003ms
a live Node daemon of ours means "already running", not a takeover
0.46297799999996414ms
an empty port is not a negotiation
0.46016300000002275ms
findDaemonPortAsync port scan 3 / 3
will not join another user's daemon, and says so instead of failing silently
2.680665999999974ms
joins a daemon of ours found by the same scan
0.6130840000000148ms
joins a daemon whose ownership is unproven
0.47586599999999635ms
localPeerOwnership 2 / 2
reads this process as ours and a dead pid as unknown
0.8910609999999792ms
isForeignDaemon reports only a definite refusal
0.40038199999997914ms
discovered-daemon selection 4 / 4
prefers this user's daemon over whichever answered first
25.779106999999954ms
demotes but never drops another user's daemon
0.3708690000000274ms
an explicitly named host outranks even our own daemon
0.25547500000004675ms
ranks a daemon that predates the TXT keys last, without excluding it
0.7954919999999674ms
daemon-target.test.ts
27 / 27 19ms
daemon-target helpers 27 / 27
isLoopbackHost › treats loopback forms as local
2.9473969999999667ms
isLoopbackHost › treats LAN/remote hosts as non-local
0.2960560000000214ms
formatHostForUrl › brackets bare IPv6 literals
0.3196509999999648ms
formatHostForUrl › leaves IPv4 and already-bracketed hosts untouched
0.28541000000001304ms
parseHostHint › defaults the port to 9120 when none is given
1.5288020000000415ms
parseHostHint › parses host:port
0.2962660000000028ms
parseHostHint › does not mistake bare IPv6 for host:port
0.24818399999998064ms
parseHostHint › parses bracketed IPv6 with and without a port
0.29740800000001855ms
resolveDaemonTarget precedence + opt-in gate › prefers a local daemon and never consults remote paths
1.9173569999999813ms
resolveDaemonTarget precedence + opt-in gate › refuses (null + warn) an incapable loopback daemon under --remote-daemon with no host hint
3.717257000000018ms
resolveDaemonTarget precedence + opt-in gate › falls through to a capable named host when the loopback daemon is incapable
0.9355490000000373ms
resolveDaemonTarget precedence + opt-in gate › refuses an ssh -L tunnel to an incapable daemon named via --daemon-host 127.0.0.1
0.7668149999999514ms
resolveDaemonTarget precedence + opt-in gate › prefers an explicit tokenHint over the daemon-advertised token
0.3095559999999864ms
resolveDaemonTarget precedence + opt-in gate › uses tokenHint on the mDNS path too
0.32209499999999025ms
resolveDaemonTarget precedence + opt-in gate › warns once (with provisioning hint) when a remote target has no token at all
0.46955699999995204ms
resolveDaemonTarget precedence + opt-in gate › still returns an incapable local daemon without the switch (local default untouched)
0.35714699999999766ms
resolveDaemonTarget precedence + opt-in gate › warnRemoteOnce logs a given key at most once (resolver re-runs on every backoff)
0.32214500000003454ms
resolveDaemonTarget precedence + opt-in gate › ignores an explicit host without --remote-daemon: the switch gates BOTH remote paths
0.3733920000000239ms
resolveDaemonTarget precedence + opt-in gate › resolves an explicit host with --remote-daemon, without touching mDNS
0.3704879999999662ms
resolveDaemonTarget precedence + opt-in gate › returns null for an unreachable explicit host without falling through to mDNS
0.36375800000001846ms
resolveDaemonTarget precedence + opt-in gate › refuses (null + warn) an explicit remote daemon lacking sameSocketControl
0.4234180000000265ms
resolveDaemonTarget precedence + opt-in gate › runs mDNS discovery ONLY when the --remote-daemon switch is set
0.394032999999979ms
resolveDaemonTarget precedence + opt-in gate › never leaves the machine with no opt-in (no host, no switch)
0.3873940000000289ms
deriveRemoteAttachOpts (shared CLI/index derivation) › is inert with no flags and no env
0.24179400000002715ms
deriveRemoteAttachOpts (shared CLI/index derivation) › flags a host given without the switch as ignored
0.25287099999997054ms
deriveRemoteAttachOpts (shared CLI/index derivation) › does not warn when the opt-in arrives via env alone
0.1715379999999982ms
deriveRemoteAttachOpts (shared CLI/index derivation) › honors env host aliases in precedence order
0.17397199999999202ms
daemon-ws-client.test.ts
6 / 6 577ms
DaemonWsClient register frame 3 / 3
always includes an explicit integer weight (unweighted ⇒ 0, never omitted)
3.4501849999999763ms
carries the launch-time --weight value
0.21745700000002444ms
normalizes garbage weights so the wire only ever sees in-range integers
0.17679700000002185ms
DaemonWsClient target re-resolution (real socket, short backoff) 3 / 3
clears the cached target on a null resolution and only redials once a valid target resolves again
215.32431199999996ms
capability downgrade through the REAL resolver: incapable local daemon ⇒ no new socket (reviewer end-to-end case)
205.22609ms
client guard: refuses to dial a non-null capability-less target under remote intent
152.41964499999995ms
default-settings-drift.test.ts
5 / 5 6ms
config/default-settings.json 5 / 5
parses as an object
3.002791000000002ms
carries only keys a loader actually reads
1.0942080000000374ms
states the MLX defaults that shared/src/llm-settings.ts applies
0.32217500000001564ms
states the APME defaults that loadApmeConfig() applies
0.6315010000000143ms
does not resurrect the removed whisper / autoTune keys
0.5247800000000211ms
device-discovery.test.ts
2 / 2 3ms
Pixoo discovery — config-reply classification 2 / 2
accepts a real GetAllConf reply
2.71766199999999ms
rejects a non-Pixoo HTTP/JSON response
0.39618600000000015ms
device-photo.test.ts
10 / 10 15ms
DevicePhotoCollector 8 / 8
assembles frames into a JPEG file and reports the target session
4.544500999999997ms
ignores binary frames with no open capture
0.4617549999999824ms
keeps captures separate per connection
0.677078999999992ms
returns null for a cancelled or empty capture
0.4089360000000113ms
drops a capture whose byte count disagrees with the board claim
0.3109880000000089ms
drops an oversized capture instead of writing a truncated JPEG
3.7201299999999833ms
reaps captures whose photo_end never arrived
0.5838389999999833ms
abandon drops the open capture for a dead socket
0.4495369999999923ms
prunePhotoDir 2 / 2
keeps only the newest N photos
2.288656000000003ms
is silent on a missing directory
1.326738000000006ms
device-voice-reply.test.ts
33 / 33 14ms
speakableReply 5 / 5
replaces fenced code with a spoken marker instead of reciting it
3.649765000000002ms
strips markdown scaffolding and URLs that read as noise
0.551400000000001ms
returns empty when nothing speakable survives
0.29859899999999584ms
cuts at a sentence boundary when the cap lands mid-sentence
0.3865920000000074ms
hard-caps when no sentence boundary is near the cap
0.2740320000000054ms
pcmFromWav 3 / 3
walks chunks rather than assuming the data starts at byte 44
0.8802650000000085ms
rejects non-RIFF and truncated input
0.2436670000000163ms
clamps a data chunk that claims more bytes than the file holds
0.28732300000001487ms
pcmFrames 1 / 1
splits into fixed frames with a short tail
0.48065400000001546ms
DeviceVoiceReplyRouter 10 / 10
only arms boards that advertise an amplifier
1.6013760000000161ms
does not arm without a session id
0.21280000000001564ms
matches only the session that was dictated to
0.2668520000000285ms
expires an arming once the window closes, so a stale answer stays silent
0.19722699999999804ms
keeps an arming across a transport blip, and refuses to stream while down
0.5366680000000201ms
streams begin, paced PCM frames, then end
0.39301100000000133ms
consumes the arming so one dictation yields one spoken reply
0.25996199999997316ms
stops mid-stream when the board disconnects and sends no end frame
0.21738799999997127ms
refuses a WAV it cannot parse rather than streaming garbage
0.16325599999998985ms
disarm removes a target without streaming
0.1503460000000132ms
session-id keying across the two forms 8 / 8
matches a bare-uuid completion against a prefixed arming
0.14760200000000623ms
matches in the other direction too
0.16578900000001795ms
normalizes the claude prefix
0.17900000000003047ms
normalizes the codex prefix
0.08651099999997314ms
normalizes the codex-app prefix
0.07472200000000839ms
normalizes the opencode prefix
0.07038599999998496ms
normalizes the antigravity prefix
0.07031599999999116ms
still keeps different sessions apart
0.14530899999999747ms
long-running turns 3 / 3
keeps an arming alive while the session is still working
0.31318200000004026ms
still expires a session that went quiet
0.171387999999979ms
refresh accepts either id form and ignores an empty list
0.15771799999998848ms
following the board across transports 3 / 3
streams to the board's current transport when the armed one is gone
0.30376699999999346ms
gives up when the board is not reachable at all
0.187041000000022ms
prefers the armed transport while it is still open
0.2682140000000004ms
device-voice.test.ts
18 / 18 81ms
dropSilentInterleave 5 / 5
drops a digitally silent odd slot (ips10 duplex shape)
2.7826390000000174ms
drops a digitally silent even slot (flipped alignment)
0.32475900000002866ms
passes true mono audio through untouched
0.19870900000000802ms
still collapses when the stuffed slot carries rare glitch spikes
0.8507209999999645ms
passes silence and tiny buffers through untouched
0.3076340000000073ms
normalizePcm 5 / 5
boosts a quiet capture toward the target peak
0.46104400000001533ms
caps the gain so near-silence does not become full-scale noise
0.20478800000000774ms
leaves already-loud audio untouched
0.23036600000000362ms
leaves pure silence untouched
0.21007600000001503ms
clamps instead of wrapping at the int16 edge
0.6718309999999974ms
buildWav 1 / 1
wraps PCM in a canonical 16-bit mono header
0.6644900000000007ms
DeviceVoiceCollector 7 / 7
assembles frames into a WAV and reports the target session
4.5917479999999955ms
ignores binary frames with no open utterance
0.24029100000001336ms
keeps utterances separate per connection
0.668988000000013ms
returns null for a cancelled or empty utterance
0.3206729999999993ms
caps a runaway utterance instead of buffering without bound
59.48354699999999ms
reports device-side and in-flight PCM loss before transcription
7.494912999999997ms
abandons and sweeps stale utterances
0.5477849999999762ms
discovery-security.test.ts
5 / 5 14ms
LAN discovery credential boundary (issue #145) 5 / 5
never serializes a pairing credential into a UDP discovery beacon
8.313756000000012ms
keeps the beacon secret-free across periodic re-sends
1.3590959999999939ms
does not materialize or log a token-bearing pairing URL in ../index.ts
1.036260000000027ms
does not materialize or log a token-bearing pairing URL in ../daemon-server.ts
2.0308370000000195ms
keeps per-session project metadata off LAN discovery
0.9060739999999896ms
display-dim.test.ts
3 / 3 5ms
display dim settings 3 / 3
defaults to enabled full-off when settings are missing
3.092055000000016ms
normalizes minimum-brightness settings
0.28134299999999257ms
embeds the resolved dim instruction in display_state events
0.6228179999999952ms
docs-wire-contract.test.ts
11 / 11 12ms
documented LAN boundary matches the gate 3 / 3
daemon.md quotes exactly the fields buildPublicHealth emits
3.7888439999999832ms
the documented payload carries no credential, inventory or state
2.08878500000003ms
GET /health is the only route an unauthorized peer reaches
0.6303379999999947ms
auth and wire specs stay visible in the published rail 5 / 5
docs/wire-compatibility.md is not in the collapsed group
0.9571510000000103ms
docs/protocol.md is not in the collapsed group
0.5804239999999936ms
docs/gateway-protocol.md is not in the collapsed group
0.5162270000000149ms
docs/daemon.md is not in the collapsed group
0.794996000000026ms
groups them with the other surface specs
1.170342000000005ms
wire compatibility contract stays bound to its subjects 3 / 3
is cataloged in the design system
0.5290459999999939ms
names helpers that still exist, so the id rules stay actionable
0.8056930000000193ms
quotes the retain-on-absent merge shape the rules depend on
0.18117300000000114ms
dot-matrix-glyphs.test.ts
18 / 18 73ms
canonical dot-matrix agent masks 2 / 2
ships every official agent mark at Pixoo/iDotMatrix and TC001 resolutions
8.929012999999998ms
preserves the official negative-space features instead of filled approximations
0.800736000000029ms
Timebox Mini Agent Beacon 10 / 10
renders octopus from a non-empty official 9×9 mask
1.1864969999999744ms
renders jellyfish from a non-empty official 9×9 mask
0.32674199999996745ms
renders opencode from a non-empty official 9×9 mask
0.2718189999999936ms
renders crayfish from a non-empty official 9×9 mask
0.4485050000000115ms
renders antigravity from a non-empty official 9×9 mask
0.5368180000000393ms
renders kiro from a non-empty official 9×9 mask
0.4490260000000035ms
keeps OpenCode hollow and OpenClaw teal-eyed at physical resolution
0.8565189999999916ms
keeps identity fixed and moves only the perimeter rail while processing
4.847188000000017ms
renders a device-native standby tide when no agent exists
0.6248710000000415ms
uses a continuous dim status frame instead of isolated floating pixels
0.50014299999998ms
iDotMatrix native 32×32 stage 1 / 1
keeps a vivid official mark and four source-keyed telemetry rails
5.911529999999971ms
Pixoo64 provider usage HUD 2 / 2
renders Claude and Codex as matching percentage-plus-reset bands
29.984061999999994ms
uses the empty Codex primary zone for the subscription date
14.690056999999968ms
Pixoo adaptive push policy 3 / 3
separates state latency from stable animation cadence
0.9361789999999814ms
uses safe moving single frames for active Pixoo states
0.2777679999999805ms
keeps the safe active cadence at 2.5 seconds
0.15591499999999314ms
esp32-ota-stage-key.test.ts
6 / 6 13ms
pull-OTA staging 6 / 6
resolves an IP target to the board the advert is keyed on
5.158155000000079ms
keeps an unknown target verbatim rather than inventing a board
1.0486290000000054ms
adverts an IP-targeted stage to the board that pulls the feed
3.096261000000027ms
reports pullSeen=false when no feed pull has ever been observed
1.2015089999999873ms
reports pullSeen=true once that board has actually pulled the feed
1.4695420000000468ms
resolves a target through the feed tracker when the board has slept out of the WS roster
0.7691379999999981ms
esp32-transport-dedup.test.ts
7 / 7 3ms
isWifiTransportRedundant 7 / 7
dedups when the same board id is live on serial (both report matching IP)
2.1204119999999875ms
dedups by board id alone when serial reports no IP (radio parked / pre-DHCP)
0.1884340000000293ms
dedups when the WiFi side has no IP but the board id matches serial
0.13100700000006782ms
does NOT dedup a WiFi-only board with no serial presence (86box: USB power-only)
0.12736200000006193ms
does NOT dedup two distinct physical units of the same model on different IPs
0.1052190000000337ms
never dedups an unresolved/unknown board identity
0.2215640000000576ms
returns false when nothing is live on serial (WiFi is the only path)
0.10256400000002941ms
esp32-wifi-ota-reconnect.test.ts
3 / 3 518ms
WiFi OTA reconnect-follow 3 / 3
completes a transfer across a mid-flight WS disconnect by resending on the reconnected socket
61.003660999999965ms
fails fast when the board drops mid-OTA and never reconnects
455.05180000000007ms
a clean transfer (no disconnect) completes with zero reconnect-resends
1.5334479999999076ms
fallback-task-timeline.test.ts
4 / 4 5ms
FallbackTaskTimeline 4 / 4
opens a task on the first prompt and closes it on session end
3.7330200000000104ms
segments on /clear and numbers the next task
0.601095000000015ms
ignores session end with no open task and tracks sessions independently
1.11208400000001ms
drops the per-session counter on session_end so counts cannot grow unbounded
0.27246999999999844ms
fm-helper-arch.test.ts
10 / 10 5ms
machoMatchesArch 7 / 7
accepts a thin binary matching the requested arch
2.0946240000000103ms
rejects a thin binary built for the other CPU
0.21562499999998863ms
accepts a fat binary that carries a native slice
0.3253599999999892ms
rejects a fat binary with no native slice
0.12713099999999145ms
rejects non-Mach-O and truncated input
0.23465299999998024ms
rejects a truncated fat header instead of over-reading
0.13524400000000014ms
rejects unknown architectures outright
0.09864900000002308ms
npm tarball determinism 3 / 3
never ships a baked helper binary
0.9239210000000071ms
has no prepack hook baking machine-dependent artifacts
0.1597799999999836ms
ships the helper source and build script for on-demand compilation
0.24502899999998817ms
fm-helper-build.test.ts
4 / 4 3ms
fm-helper build invariants 4 / 4
declares a non-empty NSMicrophoneUsageDescription
2.1550840000000164ms
declares a non-empty NSSpeechRecognitionUsageDescription
0.23876899999999068ms
embeds the plist into the __TEXT segment at link time
0.3363960000000077ms
ad-hoc signs with the identifier the plist declares
0.25787800000000516ms
ships a binary carrying the usage strings
produces a signed binary macOS can prompt for
focus-relay-samesocket.test.ts
10 / 10 12ms
SessionFocusRelay — same-socket reverse control (primary) 10 / 10
focuses via the live push socket and sends session_focus_down
4.961019000000022ms
routes a command down the push socket as session_command_down
0.6377110000000243ms
ignores commands that are not in the routed set
0.7130440000000249ms
relays only RELAYED_EVENTS from the focused session up
0.42745400000001155ms
sends session_unfocus_down on unfocus and clears focus
0.564549999999997ms
drops focus when the worker push socket closes
1.3554300000000126ms
a stale socket close does not tear down focus held by a newer socket
0.7250720000000115ms
migrateSender is a no-op for unfocused sessions and same-socket re-registers
0.3706479999999601ms
stamps relayed prompt_options with the session identity
1.318324999999959ms
does nothing when neither a push socket nor a local session exists
0.6221170000000029ms
gateway-parity-fixtures.test.ts
33 / 33 7ms
Gateway parity fixtures 33 / 33
fixture set is non-empty
2.3160970000000134ms
'auth-pairing-required-error.json' carries a valid frame discriminator
0.8991340000000037ms
'chat-delta.json' carries a valid frame discriminator
0.19282000000001176ms
'chat-final-with-tools.json' carries a valid frame discriminator
0.17228900000000635ms
'connect-challenge.json' carries a valid frame discriminator
0.23275099999997906ms
'connect-hello-ok-device-token.json' carries a valid frame discriminator
0.152499999999975ms
'connect-ok.json' carries a valid frame discriminator
0.12817300000000387ms
'exec-approval-requested.json' carries a valid frame discriminator
0.10259400000001051ms
'health-event.json' carries a valid frame discriminator
0.10004100000000449ms
'logs-tail-response.json' carries a valid frame discriminator
0.16853399999999397ms
'models-list-response.json' carries a valid frame discriminator
0.10975500000000693ms
'rpc-error.json' carries a valid frame discriminator
0.0921690000000126ms
'session-message.json' carries a valid frame discriminator
0.09130700000000047ms
'session-tool.json' carries a valid frame discriminator
0.09264900000002285ms
'sessions-changed.json' carries a valid frame discriminator
0.13654600000000983ms
'tick.json' carries a valid frame discriminator
0.09996100000000752ms
'auth-pairing-required-error.json' conforms to its frame shape
0.3497959999999978ms
'chat-delta.json' conforms to its frame shape
0.09597399999998402ms
'chat-final-with-tools.json' conforms to its frame shape
0.07428200000001084ms
'connect-challenge.json' conforms to its frame shape
0.08213399999999638ms
'connect-hello-ok-device-token.json' conforms to its frame shape
0.1128400000000056ms
'connect-ok.json' conforms to its frame shape
0.1891300000000058ms
'exec-approval-requested.json' conforms to its frame shape
0.10348600000000374ms
'health-event.json' conforms to its frame shape
0.09490200000001892ms
'logs-tail-response.json' conforms to its frame shape
0.10733200000001375ms
'models-list-response.json' conforms to its frame shape
0.10302500000000236ms
'rpc-error.json' conforms to its frame shape
0.14563900000001695ms
'session-message.json' conforms to its frame shape
0.13945999999998548ms
'session-tool.json' conforms to its frame shape
0.16692099999997367ms
'sessions-changed.json' conforms to its frame shape
0.1068000000000211ms
'tick.json' conforms to its frame shape
0.09053599999998596ms
chat-final fixture carries the final-state fields the adapter depends on
0.3730419999999981ms
exec.approval.requested fixture exposes options for the user prompt
0.4943939999999998ms
gateway-timeline-attribution.test.ts
3 / 3 2ms
enrichGatewayTimelineEntry 3 / 3
stamps agentType/projectName onto a bare OpenClaw adapter entry
2.19079899999997ms
preserves agentType/projectName the adapter already set
0.23590500000000247ms
does not mutate the input entry
0.20190400000001318ms
glance-frame.test.ts
11 / 11 370ms
wmoIconKey 1 / 1
maps WMO code groups to icon keys
3.290725000000009ms
renderGlanceFrameSvg 3 / 3
lays out the content and escapes markup
2.2056510000000458ms
renders an honest empty state when there is nothing to show
0.3076730000000225ms
ellipsizes long work lines before the hard column clip
0.5495779999999968ms
packMono 3 / 3
packs MSB-first with 1 = white
0.5429670000000328ms
pads row tails to byte boundaries
0.3211830000000191ms
dithers mid-gray into a stable ordered pattern
0.4583799999999769ms
renderGlanceFrame 4 / 4
produces the exact framebuffer size with a stable sig for stable input
156.180997ms
rotates X3 into physical space with the device GfxRenderer Portrait mapping
1.2294410000000084ms
sig ignores the clock stamp but tracks content — a clock tick must not void the conditional
147.20735200000001ms
landscape preset fills the X4 framebuffer
57.475324ms
hook-codex-sessions.test.ts
10 / 10 10ms
HookCodexSessions 10 / 10
surfaces a Codex the process scan never found
6.041365999999982ms
yields to the observer instead of doubling the row
0.5916699999999935ms
matches the observer row in either id form
0.3841989999999953ms
tracks tool state through a turn
0.47781899999998245ms
reaps a finished session, and one that died without a stop hook
0.6637290000000178ms
lets a follow-up prompt revive a finished session
0.24105299999999374ms
opens a row from a mid-turn hook when the session start predates the daemon
0.28330600000001027ms
never lets a trailing tool callback resurrect a finished session
0.5386210000000062ms
keeps the first cwd instead of relabelling on a later hook
0.36013200000002143ms
ignores non-codex events and payloads with no session id
0.5337140000000034ms
hook-server-usage-relay.test.ts
3 / 3 84ms
GET /usage — relay source contract 3 / 3
serves numbers together with a positive fetchedAt
61.36425600000001ms
withholds numbers that carry no timestamp (fetchedAt 0)
16.606239999999957ms
reports the same empty shape when no usage source is registered
5.894428000000062ms
http-auth-gate.test.ts
13 / 13 7ms
gateHttpRequest (issue #145 LAN default-deny) 3 / 3
lets an authorized request reach any route
2.9639620000000093ms
serves only the public health payload to unauthorized peers
0.25140799999999786ms
denies every other route to unauthorized peers
0.7724630000000161ms
POST /pair — only a route while the operator holds a window open 5 / 5
is denied exactly like an unknown path when no window is open
0.37436299999998823ms
opens for redemption only while a window is open
0.173041000000012ms
defaults to closed when the caller forgets to pass the window state
0.12643099999999663ms
an open window does not unlock anything else, or any other method
0.17747700000001032ms
still serves public health while a window is open
0.0903459999999825ms
buildPublicHealth 1 / 1
never contains credentials, module inventory, or session state
1.202810999999997ms
isAuthorizedHttpRequest 4 / 4
trusts same-machine connections without a token
0.25389200000000756ms
accepts a valid query token from a remote peer
0.23772800000000416ms
accepts a valid Authorization: Bearer header
0.15982099999999377ms
rejects remote peers with a wrong or missing token
0.2747140000000172ms
idotmatrix-settings.test.ts
3 / 3 3ms
iDotMatrix extra name prefixes 3 / 3
keeps the configured prefixes
2.5024469999999894ms
drops blanks and non-strings instead of passing them to the scanner
0.3380790000000218ms
treats a missing or malformed key as no extra prefixes
0.20618999999999232ms
kiro-diagnostics.test.ts
12 / 12 28ms
Kiro privacy-safe diagnostics 12 / 12
correlates an explicit resume id without serializing content, paths, ids, or commands
10.646969999999953ms
distinguishes cwd correlation, ACP records, and process-only IDE observation
2.4460730000000126ms
reports missing prerequisites without treating them as a command failure
0.8502900000000295ms
only exposes allowlisted transcript schema markers
0.7064429999999788ms
summarizes measured v3 message envelopes and recognizes completed turns
2.0383089999999697ms
takes the spoken reply, not the trailing redacted Reasoning block
0.464349000000027ms
separates a not-yet-prompted transcript from an unrecognized one
1.7162440000000174ms
reports an unreadable transcript as unrecognized, not as not-yet-prompted
0.6353070000000116ms
counts only non-blank transcript lines as evidence of content
0.4919310000000223ms
discovers the measured v3 workspace/session directory layout
6.238301999999976ms
projects measured SQLite v2 rows and recognizes their schema marker
1.4201180000000022ms
uses prompt-history mtime as a content-free pending-turn marker
0.4659910000000309ms
kiro-timeline-feed.test.ts
6 / 6 5ms
KiroTimelineFeed 6 / 6
emits the last turn — and only that — the first time it sees a session
2.916681000000011ms
cuts the seeded turn at its prompt, never mid-turn
0.34752299999999536ms
emits only what appeared after the first sighting
0.3511490000000208ms
emits the first row of a session that was empty when first seen
0.2833769999999731ms
forgets a session that is no longer observed
0.3575089999999932ms
orders rows across sessions and survives a reader that throws
0.382805999999988ms
kiro-transcript-timeline.test.ts
7 / 7 13ms
kiroTimelineForSession 7 / 7
turns a real transcript into paired chat rows
5.198385999999999ms
reads the timestamp as seconds, not milliseconds
1.1380829999999946ms
gives every reply record in one turn its own timestamp
1.3056550000000016ms
keeps thinking blocks and tool results out of the rows
1.730195000000009ms
honours since and limit against the row timestamps
0.9917729999999949ms
returns nothing rather than guessing when it cannot read
1.0695909999999742ms
finds a session under a workspace-hash directory, not just cli/
0.8223880000000179ms
linux-service.test.ts
38 / 38 204ms
buildUnitFile 8 / 8
produces a well-formed unit with the three standard sections
3.8601620000000025ms
runs the daemon in the foreground so systemd supervises the real process
0.4239779999999769ms
carries the network posture in ExecStart, quoted like every other unit word
0.2797509999999761ms
mirrors LaunchAgent KeepAlive via Restart=on-failure
0.2612829999999917ms
waits for the network to be online
0.2576679999999669ms
defaults the working directory to ~/.agentdeck
0.3782199999999989ms
derives BOTH WorkingDirectory and Environment from one dataDirOverride
0.25083699999999ms
reflects the AGENTDECK_DATA_DIR override in WorkingDirectory and Environment
0.2993099999999913ms
unit-file escaping (golden bytes) 18 / 18
emits NO Environment= line when the override is not set
0.6779109999999946ms
passes a plain path with a space through quoted and unescaped
0.44759399999998095ms
escapes % as %% (specifier expansion) in Environment and WorkingDirectory
0.2908979999999701ms
C-escapes backslash and double quote inside the quoted Environment value
0.3132919999999899ms
keeps $ SINGLE in Environment= (systemd does not expand $ there)
0.3336530000000266ms
doubles $ and % in ExecStart words (expanded there even inside quotes)
0.2828959999999938ms
escapeUnitEnvAssignment / escapeExecWord expose the per-directive rules
0.504449999999963ms
rejects control characters in the override (newline)
1.5066080000000284ms
rejects control characters in the override (carriage return)
0.3510289999999827ms
rejects control characters in the override (NUL)
0.3861210000000028ms
rejects non-absolute overrides (relative path)
0.9551779999999894ms
rejects non-absolute overrides (bare tilde)
0.3446390000000292ms
rejects non-absolute overrides (tilde path)
0.34758399999998346ms
rejects non-absolute overrides (ignore-missing prefix)
0.29828900000001113ms
rejects edge whitespace the unit parser would trim (leading space)
0.5044600000000514ms
rejects edge whitespace the unit parser would trim (trailing space)
0.38324700000003986ms
rejects edge whitespace the unit parser would trim (trailing tab)
0.31236999999998716ms
validateDataDirOverride accepts a hostile-but-legal absolute path
0.5473140000000285ms
Environment= round-trip (systemd parse semantics) 6 / 6
round-trips the raw value (space)
0.4535730000000058ms
round-trips the raw value (percent specifier)
0.3057799999999702ms
round-trips the raw value (double quote)
0.20692200000002003ms
round-trips the raw value (backslash)
0.1998710000000301ms
round-trips the raw value (dollar)
0.1927400000000148ms
round-trips the raw value (everything at once)
0.19526399999995192ms
getDataDir 2 / 2
defaults to ~/.agentdeck
0.37220000000002074ms
honors AGENTDECK_DATA_DIR
0.2565659999999639ms
installUnit (fresh data dir) 2 / 2
creates a not-yet-existing data directory before touching systemd
183.411994ms
rejects an invalid override BEFORE creating any directory
1.0378429999999526ms
getUnitPath / getUnitDir 2 / 2
defaults to ~/.config/systemd/user
0.5323319999999967ms
honors $XDG_CONFIG_HOME
0.4412540000000149ms
mdns-discover.test.ts
5 / 5 61ms
discoverDaemons 5 / 5
returns a reachable daemon, preferring the /health pairingToken over TXT
16.596856000000002ms
filters out daemons that do not advertise sameSocketControl (e.g. Swift App Store)
11.077495999999996ms
drops link-local and loopback addresses
11.062013999999976ms
excludes candidates whose /health is not a daemon
11.063255000000026ms
falls back to the TXT ip when no usable addresses are present
10.848311000000024ms
mdns-hostname.test.ts
4 / 4 16ms
mDNS service hostname 4 / 4
never publishes A/AAAA records under the macOS system hostname
11.77873199999999ms
identifies which daemon it is without naming the account
1.7348719999999958ms
never puts a pairing token in the multicast TXT record (issue #145)
1.0512830000000122ms
keeps the service hostname stable across recovery re-publishes
2.1903770000000122ms
network-posture.test.ts
18 / 18 13ms
module registry SSOT 3 / 3
MODULE_NAMES matches the modules createDefaultModules actually registers
4.612844999999993ms
allModulesOff() switches off every registered module
1.0770820000000185ms
covers the two modules the hand-written --local records used to omit
0.27433300000006966ms
resolveDaemonPosture 4 / 4
defaults to the open posture
0.6137540000000854ms
reads the env switch
0.403116999999952ms
treats --loopback and the env var as the same switch
0.33715699999993376ms
keeps --local and --loopback independent
0.3218250000001035ms
daemonModuleConfigs 8 / 8
leaves everything enabled in the default posture
0.5256309999999758ms
loopback silences every module that touches the network
0.5216850000000477ms
loopback keeps USB serial — a board on a cable is not a network peer
0.2666510000000244ms
loopback keeps ADB reverse — the tunnel rides USB into the host loopback
0.2392610000000559ms
loopback still honours the AGENTDECK_DAEMON_NO_SERIAL diagnostic gate
0.31526499999995394ms
--local turns off every module, serial included
0.5222559999999703ms
--local wins over loopback when both are set
0.256354999999985ms
a module added later defaults to off in both restricted postures
0.47444400000006226ms
describeDaemonPosture 3 / 3
names what is off, not just the bind address
0.8915130000000318ms
folds the USB channels into the off-list when --local is also set
0.41201999999998407ms
points at the switch when the daemon is wide open
0.4098670000000766ms
observed-hook-classify.test.ts
8 / 8 4ms
classifyObservedHookEvent 8 / 8
passes Claude-mapped events through with claude-code attribution
3.3439540000000534ms
maps codex_* lifecycle names to their boundary with codex-cli attribution
0.43692699999996876ms
maps codex notify turn_complete to stop (single completion row per turn)
0.1372559999999794ms
keeps Codex subagent hooks attributed to Codex
0.19617600000003677ms
maps opencode_* plugin events to their boundary with opencode attribution
0.18620000000009895ms
accepts antigravity_* for forward-compatibility (no installer yet)
0.13865899999996145ms
maps Kiro 2.x and 3.x hook vocabulary without requiring managed launch
0.18352600000002894ms
leaves unknown or unprefixed names untouched (claude fallback)
0.12430799999992814ms
observed-inject.test.ts
18 / 18 9ms
parseTmuxPanes 2 / 2
maps pane ttys (dev-prefix stripped) to pane ids
2.916881999999987ms
ignores malformed lines
0.2613240000000019ms
buildItermSelectScript 3 / 3
targets the session by tty and types Down x index then Enter
0.5964579999999842ms
index 0 is a bare Enter
0.34731299999998555ms
can emit the arrows without the Enter that would act on them
0.2506270000000086ms
parseProcessTable with tty column 1 / 1
parses tty and treats ?? as none
0.6683970000000272ms
buildTerminalAppSelectTabScript 2 / 2
selects the tab by tty without activating the app
0.33762799999999515ms
returns notfound when no tab matches
0.21268100000003187ms
buildPostKeysScript 3 / 3
matches by bundle id first, then localized name
0.5273639999999773ms
posts to the pid (never activates) and ends with Return
0.4789610000000266ms
carries a second Return only when a grouped prompt needs submitting
0.25117800000003854ms
buildAppButtonPressScript 2 / 2
matches the button by label with prefix tolerance and clicks it
0.4369980000000169ms
escapes quotes in labels
0.21577500000000782ms
buildAppKeysScript 1 / 1
raises the app, keys, and restores the previous frontmost app
0.39676800000000867ms
escapeAppleScript 1 / 1
escapes backslashes and quotes
0.20210499999996046ms
app-host resolution 3 / 3
extracts the app name from a bundle path
0.3768370000000232ms
walks the ancestry to find the hosting app
0.36467900000002373ms
returns undefined for a plain terminal session
0.24101299999995263ms
observed-steering.test.ts
44 / 44 51ms
shouldHoldPreToolUse — precision guards (never hold auto-approved calls) 17 / 17
holds a prompt-prone Bash call with no matching rules (the genuine-wait case)
6.26890800000001ms
never holds when disabled
0.634143999999992ms
never holds with zero connected clients (nobody can answer)
0.6054120000000012ms
never holds never-prompt tools (Read/Glob/Grep/TodoWrite)
0.7711610000000064ms
never holds MCP tools (per-server trust state is invisible)
0.62022300000001ms
never holds unknown tools (not in the prompt-prone set)
0.7854519999999638ms
never holds in auto-approving permission modes
0.8535850000000096ms
acceptEdits: never holds edit-family tools, still holds Bash
0.8843710000000442ms
never holds when a user-level allow rule prefix-matches the command
1.5400989999999979ms
never holds when a PROJECT-LOCAL allow rule matches (session "always allow" persists here)
1.1809880000000135ms
never holds on a bare tool-name allow rule
1.0754499999999894ms
never holds a non-Bash tool when any allow rule exists for it (loose spec match)
1.1230500000000347ms
never holds when a deny rule may match (Claude auto-denies without prompting)
1.1588150000000041ms
never holds when ANY settings file is unparseable (rule picture unknown)
1.1698220000000106ms
compound command: allow rule on the first segment suppresses the hold
1.228839999999991ms
holds on a strict ask-rule match (Claude will definitely prompt)
1.3494220000000041ms
allows only one held gate per session (parallel tool calls pass through)
1.464505000000031ms
auto-approval learner (session "always allow" is invisible — learn it) 4 / 4
suppresses a signature after undecided release + tool_end with no permission prompt
2.2148240000000214ms
does NOT suppress when a permission prompt was shown in between (genuine wait)
0.93267400000002ms
does NOT learn from device-decided releases
0.8227189999999496ms
signature granularity: Bash uses the first two command tokens
0.734847000000002ms
soft STOP 3 / 3
consumeStop is one-shot
0.896349999999984ms
clearOnUserPrompt clears stop + directives (user took over)
1.003710999999953ms
clearStop drops the flag without consuming semantics
0.7476550000000088ms
turn-end directive queue 7 / 7
caps the queue and pops exactly one per takeDirective
1.0889589999999885ms
rejects empty text
0.6503789999999867ms
a pending STOP outranks directives: queue is discarded, nothing delivered
0.7618269999999825ms
empty queue always returns undefined (no stop_hook_active loop)
0.6691269999999463ms
a synthetic Stop leaves the queue intact — nothing is listening on that response
0.8917330000000447ms
takeDirectiveForStop tolerates a missing payload
0.6826080000000161ms
steeringSnapshot reflects both flags for device badges
1.724425999999994ms
evaluatePermissionRules verdicts 4 / 4
none when no files exist
0.8794439999999781ms
exact vs prefix Bash specs
1.625567999999987ms
deny beats allow
1.2201970000000415ms
ask rules never match loosely on unparseable specs (no over-holding)
1.2202869999999848ms
beginAskGate (AskUserQuestion always prompts — no precision guards) 6 / 6
holds without consulting permission rules or the prompt-prone set
1.541971999999987ms
holds even where the rule surface is unreadable (the sandbox case)
0.7708209999999553ms
never holds when disabled or with nobody to answer
0.810169999999971ms
keeps the one-gate-per-session invariant in both directions
0.901627000000019ms
releases the session so the next question can hold again
0.8197139999999763ms
an unanswered ask teaches the auto-approval learner nothing
0.9395450000000096ms
buildAskAnswerReason (the device answer reaching the agent) 2 / 2
states every Q→A pair and forbids re-asking
1.016601000000037ms
drops groups that were never answered
0.86475200000001ms
buildGateQuestion (device-native semantics, no TUI mirroring) 1 / 1
previews the Bash command / file path / url
0.9285780000000159ms
observed-turn-watchdogs.test.ts
11 / 11 16ms
ObservedTurnWatchdogs 11 / 11
recovers a dropped Stop and reports the session it belongs to
6.229137999999978ms
keeps sessions independent — one session's Stop must not disarm another
0.7438699999999869ms
one session's tool traffic does not keep another's watchdog quiet
0.8131340000000193ms
a real Stop pre-empts recovery for that session
1.226616999999976ms
the synthetic Stop it triggers disarms it, so it fires once per turn
0.6346049999999934ms
never closes a genuine wait (transcript still shows tool_use)
0.5577399999999955ms
only admits a session that has submitted a prompt
0.4432480000000112ms
sweep() drops cold sessions so their poll timers cannot outlive them
1.380217999999985ms
sweep() leaves a session that is still posting hooks alone
1.6646559999999795ms
caps tracked sessions, evicting the coldest first
0.7866140000000144ms
stop() (daemon teardown) kills every session timer
0.6207649999999774ms
openclaw-approval-flow.test.ts
15 / 15 19ms
the user can see what they are approving 2 / 2
puts the real command on the timeline row and the prompt
7.099407999999983ms
exposes the prompt for the session row
0.6802150000000324ms
the user can actually resolve it 6 / 6
sends a decision the Gateway accepts — never the bare "allow"
2.0832960000000185ms
maps each option index to its own decision
0.5049300000000017ms
resolves a shortcut `respond` press too
0.38582999999999856ms
drops a press whose question echo names a different approval
2.061312999999984ms
accepts a truncated echo — small surfaces cut the question
0.389837ms
keeps the prompt on screen when the resolve fails
2.1820960000000014ms
the prompt goes away when the approval does 7 / 7
labels a real allow as approved (not denied)
0.44637199999999666ms
a deny ends the turn rather than resuming it
0.24877499999996644ms
closes the approval when the run is cancelled under it
0.6006140000000073ms
closes the approval when the turn errors out
0.546231999999975ms
adopts an approval that was already waiting when the adapter connected
0.6763080000000059ms
adopts the OLDEST waiting approval — that is the one blocking the agent
0.38095399999997426ms
a resolution for a different approval does not clear the pending one
0.24439799999998968ms
openclaw-chat-error.test.ts
4 / 4 10ms
OpenClaw chat error → timeline row 3 / 3
keeps the provider sentence as the row label and puts the turn context in detail
7.30012099999999ms
flags an errored gateway-initiated turn automated, like every other close row
0.5339230000000157ms
describes a message-less error frame instead of writing the word "unknown"
0.3531019999999785ms
OpenClaw chat error → APME lifecycle 1 / 1
records the failure and re-arms the idle-gap timer so the task can still close
1.3242529999999988ms
openclaw-hook.test.ts
12 / 12 9ms
openclaw-hook → telemetry spans 12 / 12
OPENCLAW_IDLE_GAP_MS is conservative (60–180 s) so multi-turn collab stays together
2.045049000000006ms
chat.send produces exactly one turn_start span carrying the prompt text
0.856490000000008ms
chat.final with a response + tools yields turn_response + per-tool tool_result spans
1.4227920000000154ms
chat.delta emits no spans — deltas are streaming chunks, not eval signals
1.0266660000000343ms
chat.aborted emits a manual task_boundary so the user gesture closes the task immediately
0.3054300000000012ms
chat.error emits an agent_error span — and NOT a task_boundary, the agent may retry
0.5742950000000064ms
idle-gap task_boundary span carries boundary_signal=idle_gap
0.37534500000003845ms
agent_error carries the turn context the Gateway frame omits
0.368774999999971ms
agent_error falls back to a describable label when the frame carries no message
0.376166000000012ms
omits detail entirely when it would only repeat the label
0.2292349999999601ms
label is byte-equal to the projected row raw, so the two never render twice
0.6018660000000295ms
all emitted spans propagate traceId for run correlation
0.3626160000000027ms
openclaw-session.test.ts
7 / 7 6ms
injectOpenClawSession 7 / 7
does NOT inject when the Gateway is reachable but not authenticated (regression: phantom trace)
3.264313999999956ms
injects a minimal session when authenticated (CLI bridge shape)
0.5706890000000158ms
carries daemon-hub extras (state/projectName/modelName/controlMode) when provided
0.24907500000000482ms
carries the pending approval so decks render real, pressable options
1.2573730000000296ms
leaves the prompt fields off when nothing is pending
0.24281500000000733ms
is idempotent — does not duplicate an already-present openclaw session
0.28960599999999204ms
returns the original array reference when not injecting (no needless copy)
0.1205009999999902ms
openclaw-timeline-completion.test.ts
3 / 3 74ms
OpenClaw chat final → single completion row 3 / 3
emits chat_response only (no chat_end) when the turn has response text
61.990714000000025ms
marks gateway-initiated (cron) turns automated and skips LLM enrichment
11.688565999999923ms
emits chat_end (not chat_response) for a response-less turn
0.8379109999999628ms
opencode-adapter-state.test.ts
11 / 11 26ms
OpenCodeAdapter run-state arming 6 / 6
arms processing on the first message.part.updated and latches once per turn
11.014263000000028ms
emits idle on session.idle and re-arms on the next turn
2.201024000000075ms
auto-tracks the session and arms when no active session was resolved at connect
1.4604490000000396ms
arms when an assistant message is still generating (no time.completed)
1.3152900000000045ms
does not arm on a completed assistant message alone
0.8755189999999402ms
drops parts for a different active session
0.9272459999999683ms
OpenCodeAdapter timeline turn shape 5 / 5
upserts the user prompt into chat_start when the user message carries text
1.2740389999999024ms
routes user text parts to the prompt, not the response
2.363467999999898ms
emits chat_response XOR chat_end — response turns produce no chat_end
1.2930370000000266ms
closes response-less (tool-only) turns with chat_end
1.0295899999999847ms
resets prompt/response state between turns
1.7260179999999536ms
opencode-client.test.ts
13 / 13 14ms
OpenCodeClient 12 / 12
health › should call /global/health
6.418783000000019ms
listSessions › should call /session with directory and limit
0.6322420000000193ms
createSession › should POST to /session
0.7436800000000119ms
sendMessage › should POST to /session/{id}/message with parts
0.5810449999999889ms
sendMessage › should include model option when provided
0.4158560000000193ms
abortSession › should POST to /session/{id}/abort
0.46283600000001ms
respondPermission › should POST allow response
0.42933700000000385ms
respondPermission › should POST deny response
0.46651299999999196ms
HTTP error handling › should throw on non-ok response
2.1611440000000073ms
disconnect › should prevent reconnection after disconnect
0.3859510000000057ms
url accessor › should return server URL
0.26508900000001745ms
url accessor › should strip trailing slash
0.23976099999998723ms
OpenCodeAdapter event mapping 1 / 1
should export OpenCodeSSEEvent type
0.18963500000000977ms
opencode-hook.test.ts
9 / 9 8ms
opencode-hook → telemetry spans 9 / 9
tool part with status=running produces a tool_call span
3.7643869999999993ms
tool part with status=completed produces a tool_result span
0.34469899999999143ms
todowrite completion with all todos completed emits a task_boundary span (todo_complete)
0.4885550000000194ms
todowrite completion with a pending todo does NOT emit a task_boundary
0.26983699999999544ms
todowrite reads todos out of state.output JSON string when input is absent
0.32817399999999ms
non-tool part returns an empty span list
1.08058699999998ms
message.updated for user role with prompt emits a turn_start
0.5115000000000123ms
message.updated for assistant role with response emits session_meta + turn_response
0.4789109999999823ms
assistant message with modelID but no response still emits session_meta (early model attribution)
0.45666700000003857ms
opencode-steering.test.ts
6 / 6 2.0s
opencode steering queue 6 / 6
poll drains queued commands immediately
5.322823ms
a parked long-poll wakes the moment a command arrives
0.4563370000000191ms
long-poll resolves empty after the wait window
1000.916751ms
permission_respond commands pass through with id + decision intact
0.30719199999998636ms
caps the queue
0.5857920000000831ms
steerability reflects a live poller
1000.8178310000001ms
pairing-window.test.ts
41 / 41 37ms
window lifecycle 7 / 7
is closed until the operator opens one
4.1799029999999675ms
mints a code of the documented shape
1.3710739999999646ms
never repeats a code across many opens (i.e. it is actually random)
5.873381999999992ms
replaces a window rather than leaving two valid secrets running
1.6263589999999795ms
closes on the operator asking
0.46987699999999677ms
clamps a window length nobody should be able to ask for
0.43451500000003307ms
clamps the device count to at least one
0.3760960000000182ms
redemption 8 / 8
hands over the token for the right code and closes a one-device window
0.7069439999999645ms
reads the token live, so a handover reaches a device pairing right now
0.4087660000000142ms
never mints a token for a refused redemption
1.7533199999999738ms
refuses everything once the window is closed
0.46555100000000493ms
pairs several devices from one window, then closes
0.49523499999997966ms
closes the window after the attempt budget, across peers
0.5483649999999898ms
does not spend the budget on malformed submissions
0.46304699999996046ms
accepts the code with the separators the display added
0.274392999999975ms
cable-free ESP32 re-arm 14 / 14
is off unless the operator named the board
0.29867900000004965ms
adopts only the addresses the operator named
0.4320900000000165ms
is closed when no window is open at all
0.34112299999998186ms
expires with the window, enforced on read
2.93059199999999ms
re-arms a board once, not on every reconnect
0.4992520000000127ms
reports the re-armed board to the operator
2.2738429999999994ms
sanitizes a board name from an unauthenticated peer
0.3497260000000324ms
names an unflashed board generically rather than blank
0.3442779999999743ms
rejects malformed addresses instead of storing them
0.589937999999961ms
bounds how many boards one window may re-arm
0.4917599999999993ms
shows what is still pending, so a silent board is visible
0.4344740000000229ms
stays open for the code after every board is re-armed
0.3278530000000046ms
stays open for a pending board after the code is redeemed
0.40971700000000055ms
closes once both halves are spent
0.3241979999999671ms
expiry is enforced on read, not by the timer 3 / 3
refuses a window whose deadline passed even if no timer ran
0.72333900000001ms
refuses the right code after expiry
0.6659219999999664ms
is still open one millisecond before the deadline
0.6024669999999901ms
operator status 9 / 9
never contains the code — the opener already has it, nothing else needs it
0.5093370000000164ms
reports who paired and who guessed wrong
0.8267650000000231ms
sanitizes the device label, which is untrusted text from an unpaired peer
0.5539039999999886ms
falls back to a placeholder rather than an empty or non-string label
0.4161659999999756ms
still reports the pairing after the window closed on it
0.5099680000000149ms
does not report a previous run's pairings to the next window
0.5512400000000071ms
forgets the receipt rather than keeping it for the life of the daemon
0.6573099999999954ms
the receipt carries no code and no token
0.39909099999999853ms
counts down in whole seconds and never shows 0 while open
0.36141400000002477ms
passive-observer.test.ts
32 / 32 33ms
passive-observer parsers 32 / 32
expires a silent observed processing state without hiding fresh work
5.017814000000044ms
parses ps output without depending on fixed command columns
1.7409410000000207ms
parses Win32_Process JSON, converting bytes to KB and dropping null command lines
0.6208540000000085ms
parses the bare object ConvertTo-Json emits for a single row
0.3224559999999883ms
returns no rows for non-JSON scan output
0.24491899999998168ms
parses scan output that arrives with a UTF-8 BOM
1.5009999999999764ms
summarizes Claude transcripts and redacts tool secrets
2.255314999999996ms
reads idle after an ESC/interrupt marker aborts a pending tool_use
0.5904189999999971ms
summarizes Codex rollout metadata, context, and pending tool calls
1.3473079999999982ms
reads idle after task_complete even when sampling dropped tool outputs
0.3776189999999815ms
reads idle after turn_aborted with dangling tool calls
0.27284100000008493ms
clears stale pending calls from a prior turn when a new user message arrives
0.26980699999990065ms
stays processing through mid-turn thinking gaps and agent messages
0.3876639999999725ms
maps lsof field output to Codex rollout files by pid
0.48974699999996574ms
keeps every rollout a desktop app-server pid holds open, deduped
0.2453899999999294ms
admits Codex Desktop app-server but rejects helper lookalikes
1.077833000000055ms
matches Win32 command lines — quoted paths, backslashes, .exe suffix
0.4026460000000043ms
finds an npm-installed Claude Code, which never puts "claude" in argv[0]
0.586763000000019ms
drops Electron child processes that reuse the app binary name
0.7973009999999476ms
matches Kiro CLI and IDE owners while rejecting Electron helpers
1.4766329999999925ms
collapses the Kiro launcher and kiro-cli-chat child to one chat process
0.6021769999999833ms
collapses the real four-deep chat tree, acp child included, to one process
0.42596100000002934ms
reads Kiro 2.x metadata and transcript turn state
3.09619100000009ms
reads a Kiro tool subject out of the nested operations shape
0.5415249999999787ms
reads documented Kiro ACP session notifications for the v3 fallback
0.4891460000000052ms
correlates a naturally launched Kiro process with its newest cwd session
1.9731400000000576ms
marks internal subagent rollouts from session_meta source
0.3607030000000577ms
reuses unchanged rollout summaries and invalidates changes/removals
0.7721820000000434ms
surfaces top-level Desktop rollouts and excludes internal subagents
1.221728999999982ms
dedupes a hook-observed Desktop conversation without hiding sibling rollouts
0.6973100000000159ms
counts Codex cached input once when the producer folds it into input_tokens
0.5302980000000161ms
recognizes standalone Antigravity processes for CLI daemon passive discovery
0.5047289999999975ms
peripheral-mapping.test.ts
10 / 10 6ms
parsePeripheralMappings 2 / 2
keeps valid entries and drops malformed ones
3.8538119999999765ms
returns empty when the block is absent or not an array
0.3468019999999967ms
resolvePeripheralAction 5 / 5
matches a tag case-insensitively and honors the project filter
0.4533930000000055ms
without a project filter targets the session that needs a human
0.13908899999998425ms
matches IR codes too
0.12586900000002288ms
returns undefined for an unmapped tag or an empty roster
0.15962099999998713ms
does not cross kinds (an nfc uid never matches an ir event)
0.10144300000001749ms
commandForAction 3 / 3
approve prefers a held gate and falls back to the live prompt
0.33339200000000346ms
deny mirrors approve
0.32633099999998194ms
maps focus / review / stop to existing daemon commands
0.2216630000000066ms
permission-resolver.test.ts
12 / 12 13ms
permission-resolver 12 / 12
register → resolve(allow) ends the held response with allow
5.855594999999994ms
resolve(deny) ends with deny
0.5126319999999964ms
times out to an EMPTY pass-through body after timeoutMs (never an explicit "ask")
0.9983430000000055ms
resolving an unknown id returns null and is a no-op
0.3847990000000152ms
double resolve: second returns null (already resolved)
0.3684740000000204ms
abandonPending drops the entry without writing a decision
0.4491560000000163ms
sweepStalePending releases entries older than maxAge as pass-through
0.4478340000000003ms
re-registering a duplicate requestId releases the stale entry first
0.5805939999999907ms
resolving over a dead socket does not throw and still clears the entry
1.2999969999999905ms
fires onResolved exactly once on a device decision
1.0854140000000143ms
fires onResolved with "pass" on timeout (arms the auto-approval learner)
0.4915399999999863ms
drainAllPending releases every held response as pass-through
0.47317199999997683ms
pixoo-autodiscover-default.test.ts
5 / 5 7ms
pixooAutoDiscoverFrom 3 / 3
is OFF when the setting is absent
3.0582139999999924ms
is OFF for anything that is not an explicit true
0.5553960000000018ms
is ON only when explicitly opted in
0.2064110000000028ms
discoverPixoo cloud opt-out 2 / 2
queries the Divoom cloud by default
0.7244000000000028ms
never touches the cloud when cloud is false
2.3842799999999897ms
pixoo-creature-sync.test.ts
19 / 19 18ms
pixoo creature sync — Codex folding 5 / 5
draws one cloud per project, not one per codex thread
11.276047000000005ms
keeps separate projects as separate clouds
0.35907100000002856ms
surfaces the busiest state in a folded group
0.2902169999999842ms
does NOT fold Claude Code — several octopuses on one project is deliberate
0.3682349999999701ms
ignores dead sessions
0.2487649999999917ms
pixoo creature sync — per-type bands 3 / 3
clusters each agent type into its own X band
0.611060000000009ms
stratifies types vertically so a mixed tank stays readable
0.3088849999999752ms
shrinks creatures as a band fills up
0.34749299999998584ms
pixoo creature sync — the `_primary` fallback 4 / 4
synthesizes a creature before the first sessions list arrives
0.4242479999999773ms
draws an empty tank once an empty list is known
0.18994599999996353ms
does not synthesize a creature for a non-creature agent
0.16579000000001543ms
does not stamp the stateEvent onto a real session
0.30456900000001497ms
pixoo creature sync — unknown agent types 3 / 3
draws no creature for an agent type it has never heard of
0.18206400000002532ms
does not let an unknown agent become a Claude octopus alongside real ones
0.2072830000000181ms
gives every known agent type its own creature
0.873896000000002ms
pixoo creature sync — Usage HUD safe area floor 4 / 4
keeps normal ground depth (0.80) when no usage HUD is active
0.2216940000000136ms
clamps idle creatures to 0.72 when a single-provider HUD is active
0.30973699999998416ms
clamps idle creatures to 0.65 when a dual-provider HUD is active
0.3685939999999732ms
does not alter upper/mid-water processing creatures when HUD is active
0.2559559999999692ms
pixoo-usage-rails.test.ts
7 / 7 30ms
iDotMatrix 32×32 telemetry rails 5 / 5
spends no row on a provider that reports nothing
4.52007500000002ms
reads a windowless free-tier Codex block as no Codex rows
0.7054620000000114ms
still fills all four rows when both providers report both windows
0.690228999999988ms
gives the panel back entirely when no provider reports usage
1.1931859999999972ms
keeps a stale (ended) Codex window off the rails, not on a blank row
1.2531359999999836ms
Pixoo64 usage HUD bands 2 / 2
drops the Codex band for a windowless free-tier block, and the lone Claude band slides down
17.026083ms
draws no HUD at all when neither provider reports usage
3.6565050000000383ms
pocket-autonomy.test.ts
9 / 9 13ms
AutonomousPocketEngine 8 / 8
cold-start explores a preference quest and the strongest available signal
5.5600709999999935ms
learns from choices and stops repeating the cold-start survey
1.4288410000000056ms
treats a retried outbox answer as idempotent
0.5498570000000029ms
treats Later as a neutral read-state and does not return the same card
0.6499680000000012ms
lets a read-only pulse be marked Done through the reserved Later action
0.4898980000000108ms
persists only aggregate learning state and opaque fingerprints
2.2579389999999933ms
counts delivered cards with no response as weak negative evidence after a day
0.4565470000000005ms
routes only stable Pocket choices
0.8878559999999993ms
parsePocketAutonomyConfig 1 / 1
defaults on absent settings and clamps explicit bounds
0.3598709999999983ms
project-name.test.ts
18 / 18 108ms
resolveProjectName 10 / 10
returns git toplevel basename from a nested subdir
17.250641ms
falls back to nearest package.json name when no git
5.030513999999982ms
skips package.json with empty name and keeps walking
4.778733999999986ms
falls back to cwd basename when no git and no package.json
4.9242240000000095ms
returns 'unknown' for a basename-less root
4.351076000000006ms
AGENTDECK_PROJECT_NAME env var wins over everything
7.64871500000001ms
envOverride option takes precedence over env var
0.56831600000001ms
preserves scoped package name verbatim
4.693035000000009ms
git subprocess error (non-repo) does not throw
5.532929999999993ms
malformed package.json is ignored (walks to parent)
5.082542000000018ms
gitToplevelBasename 2 / 2
returns null outside a git worktree
4.3592829999999765ms
returns repo basename from nested subdir
15.309739000000008ms
resolveProjectNameFromCwdCached (passive-observer resolver) 4 / 4
matches the PTY resolver for a git repo subdir (launch-path parity)
13.277042999999992ms
detects a .git FILE (worktree/submodule layout)
1.2474979999999505ms
falls back to package.json name, then basename
1.1256340000000478ms
memoizes per cwd (stale after dir changes are acceptable)
9.280141000000015ms
nearestPackageJsonName 2 / 2
returns null when no ancestor has package.json
1.5533289999999624ms
returns nearest ancestor name
0.9130250000000046ms
pty-manager-stdin.test.ts
2 / 2 6ms
PtyManager.attachTerminal 2 / 2
preserves multi-byte characters split across stdin chunk boundaries
4.65730099999999ms
forwards single-byte input unchanged
0.5898679999999956ms
python-ble-runtime.test.ts
5 / 5 19ms
optional Python BLE runtime 4 / 4
resolves packaged scripts from the bridge package and keeps the venv in the data directory
5.1297130000000095ms
reports missing npm assets instead of silently disabling BLE
1.2353090000000009ms
creates and marks a persistent environment on first explicit setup
7.2742819999999995ms
accepts a compatible legacy checkout venv without modifying it
3.980592999999999ms
bridge npm BLE assets 1 / 1
publishes every Python client and the dependency manifest
0.7825980000000072ms
remote-reverse-e2e.test.ts
5 / 5 763ms
same-socket reverse control (worker ↔ daemon, real sockets) 5 / 5
registers over a single outbound socket with explicit remoteAttach intent
2.9954199999999673ms
ignores down-frames addressed to a foreign session
303.00386ms
emits the focus snapshot up when the daemon focuses (session_focus_down)
52.83517800000004ms
applies a command sent down the same socket (session_command_down)
51.406863000000044ms
forwards live events up only while focused
351.7046099999999ms
remote-sessions.test.ts
7 / 7 8ms
remote-sessions registry 7 / 7
registers a remote session with display host/port
5.230474000000015ms
keeps startedAt stable but refreshes target on re-register
0.43755900000002157ms
re-register swaps the sender; the old socket cannot remove or overwrite
0.6377600000000143ms
updates state only for known sessions
0.3344730000000027ms
renders enriched rows marked alive/managed
0.7327730000000088ms
normalizes remote weight and preserves it for legacy re-registration
0.4342940000000226ms
removes a session
0.30824400000000196ms
review-runner.test.ts
15 / 15 9ms
renderReviewHtml 3 / 3
is self-contained (no external asset URLs) and shows risk + findings
3.705467999999996ms
escapes HTML in judge-provided text (no injection)
0.3686749999999961ms
empty findings renders a calm "nothing worth flagging" note, not an empty grid
0.2559850000000097ms
judgeTierNote — honest capability labelling 3 / 3
flags on-device models as basic screening
0.2822649999999953ms
flags local MLX depth as model-size dependent
0.22158300000000963ms
does not append a caveat for frontier backends
0.2509380000000192ms
renderJudgeGuidanceHtml — no-judge setup flow 3 / 3
ranks API → OpenRouter → OpenClaw → local → Apple, and states the local model minimum
0.8242809999999849ms
reassures that not using REVIEW is a supported choice (no background nagging)
0.3396619999999757ms
surfaces the current backend + reason so the user knows what failed
0.3533520000000294ms
openAIChatUrl — endpoint normalization (Ollama / OpenRouter / LM Studio) 4 / 4
bare host → /v1/chat/completions
0.48617799999999534ms
base with /v1 → appends chat/completions
0.20537899999999354ms
already-full URL is preserved
0.12650000000002137ms
trailing slash tolerated
0.10887400000001435ms
renderJudgeGuidanceHtml — detected local providers 2 / 2
surfaces detected servers with a ready-to-paste openai config
0.2984390000000303ms
omits the detected block when nothing is running
0.1792400000000498ms
session-aggregator.test.ts
8 / 8 28ms
session-aggregator 8 / 8
uses ownState for the current session without fetching /health
6.38970999999998ms
fetches sibling /health and merges state and modelName
3.7952339999999936ms
marks the session dead when sibling /health fails with no cache
1.5756860000000188ms
returns cached state when sibling /health fails after a previous success
0.5359670000000278ms
clearSiblingStateCache removes cached entry
0.7258630000000039ms
sweeps cached state for sessions that drop out of the active set
0.7542060000000106ms
buildEnrichedSessionsList includes own session and excludes daemon
12.469448999999997ms
buildEnrichedSessionsList returns own session in single-session mode without /health calls
0.6990019999999504ms
session-deck-awaiting.test.ts
4 / 4 9ms
buildSessionDeck detail-view awaiting 4 / 4
renders REAL options (navigable → select_option), not hardcoded Yes/No/Always
6.4317629999999895ms
non-navigable inline prompt → respond with the option shortcut
0.47471400000000585ms
observed session (requestId, no options): no fabricated Allow/Deny — only PTY sessions expose real choices
0.5243499999999983ms
awaiting but not remotely answerable (no options, no requestId): no fake action commands
0.853114000000005ms
session-id-resolve.test.ts
4 / 4 4ms
resolveSessionIdPrefix 4 / 4
returns exact matches untouched
2.738613000000015ms
restores the ESP32 31-char truncation of an observed id
0.2865110000000186ms
leaves ambiguous prefixes unresolved
0.30993599999999333ms
leaves unknown ids and empty input untouched
0.2098060000000146ms
session-push-channel.test.ts
10 / 10 19ms
session push channel (real handler, fake sockets) 10 / 10
registers an ssh -L (loopback) worker as remote via the explicit remoteAttach flag
8.282018999999991ms
carries the session weight into the remote sessions list
0.8372800000000211ms
does NOT register a plain local worker (loopback, no flag) — but still acks
1.0999360000000138ms
still registers a flag-less worker from a non-local IP (pre-flag back-compat)
0.92201799999998ms
worker reconnect: new socket takes over, old close cannot kill the new registration or focus
1.7252470000000244ms
session_event_up: only the registered sender may speak for a session
2.0691150000000107ms
session_push_state overlap: a pre-reconnect socket can change neither the remote registry nor the effective push-state cache
2.245019999999954ms
session_push_state from a never-registered stranger socket is fully rejected
0.6381210000000124ms
session_push_state with no remote registration keeps the plain unguarded local path
0.5386110000000031ms
leaves non-push frames unconsumed
0.3793009999999981ms
session-transcript-timeline.test.ts
5 / 5 7ms
lastAssistantTextFromTranscript 5 / 5
returns the last assistant text at Stop time
4.279342999999983ms
skips tool_result user continuations between assistant messages
0.6983510000000024ms
returns empty when the tail is an unanswered prompt
0.6229879999999639ms
returns empty for a missing file
0.2556149999999775ms
skips malformed tail lines
0.8048820000000205ms
subagent-timeline-store.test.ts
4 / 4 24ms
subagent rows in the bridge timeline store 4 / 4
keeps siblings of one fan-out that share a label and an instant
5.080488000000003ms
still dedups identical rows that claim no child identity
0.5753770000000031ms
upserts a growing dispatch burst in place, past the 1s tolerance
0.8290380000000255ms
does not shed the dispatch row ahead of ordinary tool rows
17.464602000000014ms
subagent-timeline.test.ts
10 / 10 10ms
SubagentTimelineTracker 10 / 10
collapses start and stop into existing compatible Timeline types
6.156888999999978ms
consumes child tool hooks without producing per-tool noise or controls
0.45956199999997693ms
keeps future child notification and stop hooks out of parent control
0.17229000000000383ms
summarizes team task completion without exposing team settings
0.6668329999999969ms
recognizes Codex lifecycle names and preserves the provider
0.42346699999998805ms
keeps a simultaneous fan-out distinguishable and counted
0.8648420000000101ms
reports an explicit zero once a fan-out drains, never absence
0.3692760000000135ms
does not pin a parent at "running" when a stop hook is lost
0.27158900000000585ms
separates one wave from the next
0.2728209999999933ms
reports a census change so the parent row can be rebroadcast
0.2530610000000024ms
timebox-ble.test.ts
12 / 12 11ms
Timebox device identity 1 / 1
uses the BLE address as the device id
1.949785999999989ms
micro layout (Timebox 11×11) 11 / 11
returns a size²·3 RGB buffer
1.7960239999999885ms
draws a bright dominant creature for a processing session
1.54016900000002ms
degrades parent-linked subagents to fixed perimeter companions
1.1746379999999874ms
shows the device-native standby tide when no session exists
0.44122500000000286ms
moves critical usage to a red perimeter rail without tinting identity
0.32157399999999825ms
maps claude-code to its shaded official mark and product color
0.4516299999999944ms
maps codex-cli to its shaded official mark and product color
0.3940029999999979ms
maps opencode to its shaded official mark and product color
0.3785799999999995ms
maps openclaw to its shaded official mark and product color
0.25081800000000953ms
preserves OpenCode negative space and OpenClaw teal eyes
0.6252920000000017ms
renders the generated Antigravity mark as a multicolor open arc
0.599552999999986ms
timeline-orphan-reaper.test.ts
5 / 5 6ms
BridgeTimelineStore.reapOrphanTaskStarts 5 / 5
synthesizes task_end for orphaned task_start rows only
3.568842999999987ms
anchors the synthetic end after the task's last row with an approx duration
0.7442209999999818ms
closes stale orphaned chat_start rows without touching live or completed turns
0.8749870000000044ms
anchors the synthetic chat_end before the session's next chat_start
0.5863830000000121ms
lets a real task_end merge over the synthetic by taskId
0.41955200000001014ms
timeline-persistence.test.ts
13 / 13 32ms
persistence is opt-in 2 / 2
writes nothing until enablePersistence is called
8.658285000000035ms
writes once enabled
6.40898900000002ms
write behaviour 5 / 5
coalesces a burst of entries into a single write
1.4394069999999601ms
leaves no temp file behind
1.924607999999978ms
flushes pending entries on shutdown instead of losing them
1.8810119999999984ms
stopPersistence is safe when nothing is pending
1.749684000000002ms
survives an unwritable path rather than taking the daemon down
1.2530859999999961ms
round-trip 2 / 2
a written file reloads into an equivalent buffer
1.7084130000000073ms
restored history is included in the next write, not truncated away
2.336777999999981ms
cross-implementation format contract (Swift DaemonTimelineStore) 4 / 4
writes a plain JSON array, not a wrapper object
0.965202999999974ms
every row carries the ts/type/raw triple both implementations require
1.143081000000052ms
reads a file in the shape the Swift daemon writes
0.9789940000000001ms
treats a corrupt file as empty history rather than throwing
0.8596840000000157ms
timeline-projection-cutover.test.ts
4 / 4 5ms
BridgeTimelineStore projection cutover 4 / 4
default OFF: every entry passes (no behavior change)
4.957118000000037ms
ON: drops locally-emitted chat/tool rows
0.3527310000000057ms
ON: projected (bypass) chat/tool rows pass through
0.3029460000000199ms
ON: task hierarchy + error rows are never suppressed
0.3010730000000308ms
timeline-summarizer-chain.test.ts
5 / 5 7ms
summarizeResponse provider chain 5 / 5
prefers on-device Foundation Models over MLX
4.009545999999972ms
falls to MLX when the helper is unavailable
1.0625099999999748ms
falls to Ollama when the helper and MLX are both down
0.6272140000000377ms
returns null when every provider is down so the caller uses the heuristic
1.3688399999999774ms
probes the helper once, not once per summary
0.3848799999999528ms
timeline-task-retention.test.ts
6 / 6 346ms
BridgeTimelineStore task-row retention 6 / 6
keeps an in-flight task_start alive through FIFO overflow
246.655958ms
evicts closed task pairs once the task cap is exceeded, oldest first
90.73531299999996ms
sheds tool_exec before chat_start so a tool-heavy turn survives replay
3.2008590000000368ms
getHistoryForSession returns task rows beyond the per-session limit
3.3689620000000104ms
getHistoryForSession canonicalizes observed session ids
0.8271649999999227ms
loadPersistedEntries keeps task rows past the generic trim
1.1965320000000474ms
tui-hud-entries.test.ts
16 / 16 21ms
buildHudEntries — primary anchoring 7 / 7
promotes the matching-port sibling to primary instead of appending a duplicate
15.071271000000024ms
patches the anchored sibling with the primary's live fields (matches macOS / Android)
0.6212249999999813ms
uses the primary's projectName for the #N suffix grouping after anchoring
0.4060709999999972ms
preserves the deterministic #N order when primary anchors a sibling slot
1.1626899999999978ms
appends a synthetic primary when no sibling shares its agentType
0.3583789999999567ms
skips the synthetic primary when a sibling shares agentType but no port match (duplicate guard)
0.30961600000000544ms
never appends primary when agentType is daemon or openclaw
0.3004529999999477ms
buildHudEntries — virtual OpenClaw 2 / 2
inserts a virtual OpenClaw row when gateway is available and sessions has none
0.5050400000000081ms
does not insert a virtual row when sessions already contains an openclaw entry
0.3135819999999967ms
buildHudEntries — hotkey eligibility (sibling-only) 1 / 1
primary and virtual rows do not consume hotkey slots
0.3293759999999679ms
formatTaskEvalSuffix — task_end badge for each outcome class 6 / 6
renders ✓ for success
0.22915499999999156ms
renders ✗ for fail
0.18483800000001338ms
renders △ for partial
0.13674600000001647ms
renders ⊘ for abandoned (manual cancel)
0.12619000000000824ms
renders ? as score placeholder when judge has not produced a number yet
0.1197400000000357ms
returns empty string while the eval is still pending (outcome undefined)
0.1588289999999688ms
usage-api.test.ts
24 / 24 13ms
resolveOAuthCredentials 11 / 11
darwin: parses the Keychain blob and never reads a file
3.87889899999999ms
win32: reads /.credentials.json and never spawns the security CLI
1.2732369999999946ms
win32: CLAUDE_CODE_OAUTH_TOKEN takes precedence over the file, expiresAt undefined
0.3101769999999817ms
win32: an empty CLAUDE_CODE_OAUTH_TOKEN falls through to the file
0.27648600000000556ms
win32: a whitespace-only CLAUDE_CODE_OAUTH_TOKEN falls through to the file
0.24416700000000446ms
win32: a padded env token is trimmed before use
0.15849900000000616ms
linux: honors a relocated configDir (CLAUDE_CONFIG_DIR)
0.38048299999999813ms
win32: neither file nor env → null, no throw
0.2485939999999971ms
win32: malformed / partial JSON → null, never throws
0.4936630000000264ms
win32: valid token but non-numeric expiresAt → token kept, expiresAt undefined
0.37442400000000475ms
darwin: security CLI returns null (no keychain entry) → null
0.20086200000000076ms
buildCredSources (production wiring) 3 / 3
wires the real platform, env, and default configDir
0.681506000000013ms
honors CLAUDE_CONFIG_DIR when set
0.19312099999999077ms
passes the security + file readers as UN-invoked function references (lazy thunks)
0.1608929999999873ms
parseScopedLimits 6 / 6
keeps only model-scoped entries (drops session / weekly_all)
0.3455600000000061ms
sorts worst-first: active ahead of inactive, then by descending percent
0.9338659999999948ms
inactive limits sort by descending percent
0.3163269999999727ms
falls back to kind when the model has no display_name
0.18849299999999403ms
skips entries without a numeric percent
0.19284100000001558ms
returns [] for non-array / missing input
0.2943640000000016ms
fileCacheExpired — TTL slack 4 / 4
expires a cache that is a fetch-latency hair under the nominal TTL
0.2067920000000072ms
expires at the nominal TTL and beyond
0.24732200000002535ms
still holds a genuinely recent cache — the cross-session 429 dedupe survives
0.1779380000000117ms
slack stays well inside the poll interval
0.14632100000000037ms
usage-event.test.ts
33 / 33 15ms
buildUsageEvent subscription quota scoping 4 / 4
omits Anthropic quota when the model is not yet known
3.6320780000000354ms
omits Anthropic 5h/7d quota for GLM/API-backed models
0.6684359999999856ms
keeps Anthropic 5h/7d quota on the daemon hub even with a non-Claude aggregate model
0.3566059999999993ms
keeps Anthropic 5h/7d quota for Claude model aliases
0.299521000000027ms
buildUsageEvent scoped limits 3 / 3
forwards scopedLimits for a subscription Claude model
0.9217079999999669ms
omits scopedLimits for an API/GLM-backed model even when present
0.22157299999997804ms
omits scopedLimits when the scoped array is empty (no phantom key)
0.2093550000000164ms
buildUsageEvent staleness contract 5 / 5
flags usageStale when no quota numbers ride the frame (never fetched)
0.2985400000000027ms
does not flag usageStale when fresh quota numbers are present
0.37578600000000506ms
always puts usageStale on the wire, never omits it
0.30201399999998557ms
keeps usageStale true when cached numbers ride a stale frame
0.2625150000000076ms
does not force usageStale when the cost-based API-billing percent is present
0.23325099999999566ms
buildUsageEvent Codex window normalization 10 / 10
marks an expired window stale and drops its resetsAt (no misleading "now")
0.5134429999999952ms
leaves a live window untouched
0.32269500000001017ms
forwards capturedAt so consumers can age the reading themselves
0.26210399999996525ms
does NOT set `stale` on a merely-old snapshot of a live window
0.8511819999999943ms
keeps capturedAt through the credits-only synthetic window
0.31893000000002303ms
treats each window independently (5h expired, 7d live)
0.41373299999997926ms
routes a weekly window arriving in Codex's primary slot to the secondary (7D) wire slot
0.34812399999998433ms
maps exhausted credit-based plan (null windows) to a 100% primary gauge
0.3004420000000323ms
maps an unlimited credit plan to a 0% primary gauge
0.284958999999958ms
leaves a partial credit balance absent (no honest percentage)
0.2730809999999906ms
mergeRelayedSessionUsage 4 / 4
keeps the relay session counters
0.43924099999998134ms
keeps the daemon account half authoritative — a quota-less relay cannot blank the gauge
0.45372300000002497ms
leaves the daemon value in place for a session field the relay omits
0.2750239999999735ms
does not mutate either input
0.2431760000000054ms
buildUsageEvent Codex plan reconciliation 7 / 7
voids a snapshot minted under a plan the account no longer holds
0.34113400000001093ms
keeps a snapshot whose plan still matches the account
0.2683940000000007ms
keeps a genuine free-tier snapshot — free is a plan, not a synonym for void
0.2286149999999907ms
keeps the snapshot when either side reports no plan (absence is no information)
0.3352649999999926ms
emits the account tier even with no rollout at all, so a client can RETRACT
0.21956099999999878ms
stays absent for a user with no Codex account at all
0.18451799999996865ms
still names the plan in the subscriptions footer after voiding
0.2416740000000459ms
usage-relay-fallback.test.ts
5 / 5 69ms
fetchUsageRelayed — direct-API fallback (regression: fa1d98c9) 5 / 5
no siblings → uses the direct API
3.871368000000075ms
siblings exist but the relay yields nothing → falls back to the direct API
23.02264100000002ms
siblings exist but only serve null usage → falls back to the direct API
22.982140000000072ms
sibling serves fresh usage → relay wins, direct API not called (429 prevention preserved)
12.676555000000008ms
stale sibling data (>5 min old) is ignored → falls back to the direct API
5.728984999999966ms
weather.test.ts
11 / 11 8ms
parseWeatherSettings 2 / 2
accepts lat/lon + optional place
2.603940000000023ms
rejects missing, malformed, or out-of-range config
0.2765459999999962ms
wmoSummary 1 / 1
maps representative WMO codes to short words
0.44183500000002596ms
findTodayRainWindow 3 / 3
finds the first remaining contiguous window ≥ the floor with its peak
0.43748899999997093ms
single qualifying hour → no endHm
0.18005099999999175ms
no qualifying hour today (tomorrow does not count) → undefined
0.18976599999996324ms
toGlanceWeather 1 / 1
rounds temps, maps codes, and carries tomorrow + rain window
0.3636979999999994ms
WeatherProvider 4 / 4
unconfigured → undefined without fetching
1.0399360000000115ms
fetches once, then serves from cache inside the window
1.170411999999999ms
serves the stale cache on fetch failure, up to the stale-serve bound
0.5758670000000166ms
failure with no cache → undefined (never throws)
0.2640779999999836ms
windows-service.test.ts
8 / 8 6ms
xmlEscape 1 / 1
escapes XML metacharacters
1.967802000000006ms
buildScheduledTaskXml 7 / 7
produces a well-formed v1.2 task with a logon trigger
0.5936140000000023ms
mirrors LaunchAgent KeepAlive / no-stop semantics
0.7597930000000019ms
uses node as unquoted Command and quotes the cli.js path in Arguments
0.3102269999999976ms
carries the network posture in Arguments — Task Scheduler has no env element
0.3321100000000001ms
emits no trailing space when there is no posture to carry
0.25178900000000226ms
XML-escapes special characters in the user id and paths
0.4686360000000036ms
places both UserId fields (trigger + principal) with the same user
1.2997060000000147ms
ws-server-auth.test.ts
3 / 3 100ms
WsServer remote auth 3 / 3
rejects a remote connection with no token
34.12769099999997ms
accepts the machine token
62.27812700000004ms
rejects any non-machine token — the machine token is the ONLY accepted credential
3.9435920000000806ms
codex-install.test.ts
42 / 42 93ms
codex-mini-toml: applyManagedBlock 4 / 4
appends fence when absent
3.034358999999995ms
replaces existing fence block
0.6616460000000188ms
apply twice is idempotent
0.33863999999999805ms
moves Codex hook trust state out of the managed fence
0.4965179999999805ms
codex-mini-toml: removeManagedBlock 2 / 2
leaves user content
0.7721229999999935ms
is idempotent without fence
0.20080200000001014ms
codex-mini-toml: hasTopLevelKeyOutsideFence 3 / 3
detects user notify key
0.41525500000000193ms
ignores notify key inside table
0.2962359999999933ms
ignores notify key inside fence
0.24721199999999044ms
codex-mini-toml: hasTableOutsideFence 6 / 6
detects user [otel] table
0.44169500000000994ms
detects user [otel.exporter] dotted table
0.2492249999999956ms
detects array-of-table header [[hooks.Stop]]
0.28184400000000664ms
ignores Codex hook trust state outside fence
0.28235499999999547ms
ignores [otel] inside fence
0.21860900000001493ms
ignores [otelfoo] (word boundary)
0.23615599999999404ms
codex-mini-toml: hasIncompatibleHookTableOutsideFence 2 / 2
allows official lifecycle arrays to merge
0.5216450000000066ms
rejects regular hook tables while ignoring trust state
0.35675699999998756ms
codex-mini-toml: quoted 3 / 3
escapes backslash and double quote
0.28480899999999565ms
escapes newline and tab
0.18466800000001626ms
passes simple ASCII
0.1831059999999809ms
codex-install: managedBlockBody 6 / 6
roundtrip preserves user TOML byte-for-byte (load-bearing)
4.852299999999985ms
matches Codex schema (lifecycle hooks + endpoints + notify dummy)
2.9804570000000012ms
uses PowerShell command hooks on Windows
8.894295ms
windows notify sidecar reads payload from $args and posts codex_turn_complete
0.5611250000000041ms
falls back instead of emitting an out-of-range OTel endpoint
1.5181860000000142ms
omits conflicting optional channels when asked
1.4174749999999676ms
codex-install: install / uninstall (file I/O) 16 / 16
creates config with fence when file is absent
3.8724599999999896ms
preserves user content when installing into existing config
3.3532979999999952ms
skips when user already has [features] table outside fence
0.8162849999999935ms
preserves user lifecycle arrays in the same TOML representation
2.550159000000008ms
skips when user has an incompatible regular [hooks] table
0.7361589999999865ms
omits notify when user has top-level notify
4.748919999999998ms
omits OTel when user has [otel] table
2.325061000000005ms
omits OTel by default on Windows installs
5.186007000000018ms
writes the notify sidecar script on Windows and removes it on uninstall
10.408364000000006ms
downgrades to lifecycle-only with a warning when the sidecar write fails
5.707693000000006ms
skips notify on Windows when user has top-level notify (no sidecar written)
5.502593999999988ms
uninstall strips fence and preserves user content
2.8327449999999885ms
uninstall is idempotent when no config exists
1.4258970000000204ms
honours AGENTDECK_NO_CODEX_HOOKS=1 opt-out
0.6302990000000364ms
install is idempotent (same port → no rewrite)
4.101986000000011ms
preserves Codex hook trust state across reinstall
7.554693999999984ms
opencode-install.test.ts
13 / 13 159ms
opencodePluginSource contract 6 / 6
posts the four lifecycle events the daemon pipeline understands
2.0821040000000153ms
carries the payload fields the daemon reads
0.3285139999999842ms
self-disables inside managed agentdeck PTYs (AGENTDECK_PORT marker)
0.22033100000001582ms
resolves the daemon port from the canonical daemon.json candidates
0.1895550000000128ms
bounds every network call (peer silence is a first-class signal)
0.21380199999998695ms
separates user prompt parts from assistant response parts by messageID role
0.1599300000000028ms
AgentDeckObserver event sequencing 2 / 2
posts one user_prompt_submit per user message, including after the turn settles
79.22135300000002ms
still reports a genuine second turn on a new user message
72.44333ms
installOpenCodeHooksIfNeeded 5 / 5
writes the plugin file (creating parent dirs) and is idempotent
1.299225999999976ms
refreshes a stale or edited plugin file
1.2167310000000384ms
honours the AGENTDECK_NO_OPENCODE_HOOKS opt-out
0.4257109999999784ms
uninstall removes the plugin file and is idempotent
0.6843999999999824ms
default path lives under the opencode plugins dir
0.3168569999999704ms
anim-schedule.test.ts
11 / 11 11ms
D200H animation schedule 11 / 11
spans exactly one animation cycle
2.1525210000000072ms
steps evenly and monotonically through the cycle
1.1013379999999984ms
keeps the dash step small enough to read as motion, not as a jump
0.13775699999999347ms
paces the loop at the Stream Deck tick so both surfaces share a tempo
0.25630599999999504ms
gives each key its own phase without breaking the loop
1.8248870000000181ms
is deterministic per key so a tile keeps encoding to the same bytes
0.23341100000001802ms
identifies a rotated loop by its OWN first frame, not by deck 0
1.6105149999999924ms
starts each key at the frame its phase offset names
2.025529000000006ms
separates neighbouring keys by a visible fraction of the cycle
0.3804330000000107ms
spreads a full deck across the cycle instead of clustering
0.1544420000000173ms
probes a frame that a moving tile cannot match by accident
1.269912000000005ms
deck-signature.test.ts
9 / 9 6ms
D200H deckSignature — every render-affecting change must be visible 9 / 9
is stable when nothing changed
3.3029129999999896ms
changes when a multi-question prompt advances to the next question
0.3687150000000088ms
changes when only the question text moves
0.21932999999998515ms
changes when only the option labels move
0.20880400000001487ms
changes when only the group index moves
0.2033659999999884ms
changes when answerability flips (dead-button regression)
0.19750700000000165ms
changes when the prompt shape flips to multi-select
0.2340730000000235ms
changes on review badge transitions
0.30464800000001446ms
changes on usage-only updates (quota gauges ride a separate event)
1.2608980000000258ms
manifest-localization.test.ts
6 / 6 10ms
ulanzi manifest ↔ localization alignment 6 / 6
declares exactly one dynamic action
4.21646800000002ms
en.json repeats the manifest text verbatim
0.6538550000000214ms
zh_CN.json Actions is index-aligned with the manifest
3.9307179999999846ms
zh_HK.json Actions is index-aligned with the manifest
0.678812000000022ms
ja_JP.json Actions is index-aligned with the manifest
0.4448990000000208ms
ko_KR.json Actions is index-aligned with the manifest
0.4671530000000246ms
property-inspector.test.ts
10 / 10 30ms
ulanzi property inspector 10 / 10
is declared by the manifest and present on disk
3.163302000000016ms
loads the SDK Property Inspector libraries that the package ships
1.0660850000000153ms
opens the H5 tutorial through the SDK, at a path the package contains
0.6394930000000159ms
is self-contained — no remote asset can leave either surface half-drawn
1.4503739999999823ms
keeps English in the markup, not only in the language files
0.41999300000000517ms
resolves every data-localize key against every shipped language
9.743909000000002ms
resolves every runtime string lookup against every shipped language
3.7375769999999875ms
keeps every language key-aligned with canonical en
9.351929999999982ms
preserves the {port} placeholder the script substitutes
0.6760320000000206ms
reads the daemon only through routes that carry no secret
0.30712199999999257ms
reconnect-supervisor.test.ts
8 / 8 12ms
ReconnectSupervisor 8 / 8
connects once on start and reports the first open without firing onReconnect
7.287801999999999ms
reconnects with backoff after a drop and fires onReconnect on re-open
0.951121999999998ms
ignores the spurious close emitted while a connect is in flight
0.38404799999997863ms
retries via connect-timeout when an attempt neither opens nor closes
0.3039579999999944ms
escalates the backoff ladder across consecutive failed attempts
0.39480499999999097ms
forces a fresh connect on wake even when the socket looked open (half-open)
0.45442500000001473ms
reconnects immediately on wake while disconnected (backoff reset)
0.4303779999999904ms
stop() halts the watchdog so wake no longer reconnects
0.5179300000000069ms
state-store.test.ts
6 / 6 9ms
D200H StateStore session isolation 3 / 3
does not use the global OpenClaw model while Claude focus is pending
4.597431000000029ms
ignores unscoped and foreign prompt options for the selected session
0.41750899999999547ms
applies prompt options only to their correlated session
1.2928269999999884ms
D200H StateStore — observed rows are not shadowed by the focus reply 3 / 3
keeps the live question and options when the focus reply lands
0.4863720000000171ms
lets the roster row win even over a snapshot stored before the row arrived
0.33743799999996327ms
still lets a managed session's live state override its roster row
0.7222579999999539ms
bridge-client.test.ts
3 / 3 3.4s
BridgeClient — port provider 3 / 3
skips connect when provider returns null
58.30268100000001ms
connects once provider returns a live port
1265.310713ms
rebinds to a new port when provider value changes
2107.0987020000002ms
device-profile.test.ts
3 / 3 4ms
Stream Deck device profiles 3 / 3
maps every documented Elgato DeviceType without conflating families
2.8631300000000124ms
uses the larger text profile only for original 72px keys
0.2921699999999987ms
does not coerce missing or malformed device types to Stream Deck
0.4801519999999755ms
encoder-offline-policy.test.ts
3 / 3 7ms
renderOfflineTouchStrip — all-or-nothing 800px slice contract 3 / 3
every slice is a 200x100 canvas carrying the shared banner content
4.841458999999986ms
slices 0..3 offset the same banner by -index*200 (E0..E3 align into one strip)
0.6096580000000245ms
uses a per-slice gradient id so the four panels are independent SVGs
0.9390730000000076ms
focused-detail-state.test.ts
5 / 5 7ms
FocusedDetailState 5 / 5
does not carry an OpenClaw GLM model into a focused Claude session
5.3233039999999505ms
drops late options from another session and unscoped legacy options
0.6243000000000052ms
accepts options correlated to the selected session
0.4317500000000223ms
keeps an observed session's live prompt when the focus reply lands
0.33838899999994965ms
still lets a managed session's live state replace its detail snapshot
0.2647489999999948ms
launcher-target.test.ts
16 / 16 11ms
launcher: runTarget fallback chain 8 / 8
opens a desktop app for an app: target
3.743977000000001ms
opens a browser tab for a url: target
0.36875599999999054ms
stops at the first step that succeeds
0.2291049999999757ms
falls through to the URL when the app is not installed
0.45540500000001316ms
rejects when every step fails, so the dial can showAlert
1.658017000000001ms
rejects an unrecognized scheme rather than guessing
0.3857110000000148ms
rejects an empty target
0.2668819999999812ms
tolerates whitespace around chain steps
0.21758800000000633ms
launcher: shipped defaults 2 / 2
every default target parses into runnable steps
0.8325629999999933ms
falls back to a URL for both agents that have a desktop app
0.2646879999999783ms
launcher: entry list and rolling 6 / 6
lists every agent in a stable order
0.5125819999999806ms
honours a per-agent override from the Property Inspector
0.28769300000001863ms
ignores a blank override rather than launching nothing
0.1331909999999823ms
wraps the rolling index in both directions
0.2308879999999931ms
never returns a negative or out-of-range index
0.6522620000000074ms
returns 0 for an empty list instead of NaN
0.10310499999999934ms
manifest-platform.test.ts
2 / 2 5ms
Stream Deck Marketplace platform contract 2 / 2
ships installable entries for both maintained desktop platforms
3.7431449999999984ms
mirrors the plugin package version as X.Y.Z.0
0.5365580000000136ms
session-slot-manager.test.ts
53 / 53 71ms
SessionSlotManager detail layout 20 / 20
re-points detail focus onto the codex fold representative when the focused thread is absorbed
7.283875999999964ms
exits detail view when the focused session is gone with no fold successor
0.6403240000001915ms
folds codex companion threads by project before slot assignment
2.5662529999999606ms
renders connected no-session list as status cards instead of text-only empty buttons
0.9035600000001978ms
renders the OpenClaw exec approval from the row when the relay says idle
1.7447370000002138ms
shows an OpenClaw approval as display-only when it is not deliverable
0.47854099999995015ms
puts processing tool info before OpenClaw presets
1.3290609999999106ms
keeps a processing status tile even before tool metadata arrives
0.4445499999999356ms
aliases the model name on detail MODEL surfaces (status card + OpenClaw preset)
1.4959619999999632ms
renders the MODEL tile exactly once in Claude PROCESSING detail (no duplicate)
1.1320840000000771ms
does not duplicate MODEL on OpenClaw idle (preset + status card)
0.5918409999999312ms
does not render a READY/idle tile while a Claude session is PROCESSING
0.5595419999999649ms
keeps observed Claude PROCESSING free of queued task buttons
0.6890280000000075ms
observed AskUserQuestion: options are inert without liveAnswerable, pressable with it
1.5448160000000826ms
renders no MODEL tile for observed Codex PROCESSING on every Stream Deck layout
1.7816530000000057ms
never renders MODEL as a key for any observed session state
2.307113999999956ms
does not render a STANDBY/idle tile while an OpenClaw session is PROCESSING
0.5481850000001032ms
uses actual parser options and reserves MORE only when awaiting overflow exists
0.6724930000000313ms
resets option paging when the question changes, not just when awaiting ends
0.9418980000000374ms
makes observed options pressable exactly when the daemon says they are answerable
4.911495000000059ms
SD+ keypad relocation (Phase 2) 4 / 4
AWAITING permission renders selectable option buttons + ESC on the SD+ keypad
0.7032690000000912ms
shows a SUGGESTED quick-send button leading the IDLE detail content on SD+
0.6263319999998203ms
does NOT add a SUGGESTED button on classic Stream Deck (behavior unchanged)
0.7181909999999334ms
drops the SUGGESTED button when the session leaves IDLE
0.6058020000000397ms
SessionSlotManager list-view usage tiles 15 / 15
pins Claude 5H/7D to the last two keys of a classic Stream Deck (no Codex)
11.587084000000004ms
reserves 4 keys (Claude 5h/7d + Codex 5h/7d), left-aligned, when both agents report quota
1.0886789999999564ms
hides Codex tiles when only Claude reports quota (reserve 2, not 4)
0.9692090000000917ms
hides Claude tiles when only Codex reports quota (reserve 2 Codex tiles)
0.9955079999999725ms
does NOT reserve usage on Stream Deck+ (encoder carries usage)
0.9879869999999755ms
does NOT reserve usage on the Stream Deck + XL (6 dials carry usage)
3.6391439999999875ms
pins usage to the last keys of the Stream Deck XL (no encoder, 32 keys)
0.5634180000001834ms
isPlusFamily covers both dial-bearing families but not the plain XL
0.31975099999999657ms
reserves NO usage keys when no quota was fed (hide-if-absent)
0.4099069999999756ms
drops Claude tiles when its quota goes stale (hide-if-absent on stale)
0.5760179999999764ms
fits 13 sessions on a classic deck without paging (15 keys − 2 usage)
0.8251820000000407ms
paginates over capacity: NEXT→ at slot 12, usage at 13/14
0.7448010000000522ms
repositions NEXT→ ahead of a 4-key usage block when paginating
1.0523250000001099ms
pressing a usage tile resolves to refresh-usage
0.3465519999999742ms
shows usage tiles even with zero sessions
0.4111899999998059ms
VOICE hold-to-talk key 4 / 4
renders VOICE after the CC idle presets and maps its press to voice-ptt-begin
0.7297590000000582ms
keeps localAction on materialized CC presets so REVIEW presses dispatch
0.32124399999997877ms
restyles the VOICE key from daemon voice_state transitions
1.0881879999999455ms
offers VOICE on observed Claude idle next to REVIEW (terminal-injection delivery)
0.4618350000000646ms
SessionSlotManager detail cache ownership 3 / 3
does not carry the previous session model into the next detail view
0.31451400000014473ms
seeds the detail readout from the session row rather than blanking it
0.24984599999993407ms
drops the cached model when re-entering a session that has none
0.2777579999999489ms
SessionSlotManager scoped cap vs the Codex usage keys 7 / 7
gives the key Codex vacated to the scoped cap on a free ChatGPT tier
1.0281679999998232ms
shows Claude 5H, 7D, active Fable, and Codex weekly together on 4 reserved keys
1.604966000000104ms
keeps Codex windows beside active Fable and enables paging when >4 gauges exist
0.5794619999999213ms
places an inactive cap after live Codex windows on 4 reserved keys
0.7450420000000122ms
drops the scoped cap along with the Claude gauges when usage goes stale
0.47545499999978347ms
shows Claude 5H, 7D, Fable, and a lone 30-day Codex window together across 4 reserved keys
0.670659999999998ms
shows the scoped cap for a Codex-less, Claude-only user too
0.540854999999965ms
streamdeck-profiles-sync.test.ts
6 / 6 10ms
bundled Stream Deck profiles in sync 6 / 6
agentdeck-sd.streamDeckProfile matches the SSOT
4.6374409999999955ms
agentdeck-sdmini.streamDeckProfile matches the SSOT
0.7916020000000117ms
agentdeck-sdplus.streamDeckProfile matches the SSOT
0.8348469999999963ms
agentdeck-sdxl.streamDeckProfile matches the SSOT
1.0251030000000014ms
agentdeck-sdplusxl.streamDeckProfile matches the SSOT
1.1266060000000095ms
covers exactly the five shipped device families
0.9993240000000014ms
system-dispatch.test.ts
6 / 6 13ms
system: selectBackend platform mapping 3 / 3
maps win32 to the windows backend
2.7379320000000007ms
maps darwin to the mac backend
0.24864400000001297ms
falls back to the mac backend on platforms the Stream Deck app does not exist on
0.2268720000000144ms
system: setOutputVolume debounce 3 / 3
coalesces rapid rotation — only the final value commits
6.793766999999974ms
commits again after the debounce window settles
0.8194239999999979ms
swallows backend failures — a bad tick must not become an unhandled rejection
0.780764999999974ms
system-win32-open.test.ts
5 / 5 10ms
win32: openUrl via rundll32 2 / 2
passes the URL as a single argv to rundll32, never through cmd
4.865904999999998ms
rejects when rundll32 fails so callers can fall back
2.3830480000000023ms
win32: openApp via Start Apps lookup 2 / 2
passes an exact Start-menu name through the environment, not PowerShell source
1.5683609999999817ms
rejects a missing Start-menu app so the |url: fallback chain can take over
1.0491690000000062ms
win32: openAgentDeckAppOrGitHub 1 / 1
goes straight to the project page — there is no Windows desktop app
0.48657199999999534ms
system-win32-volume.test.ts
14 / 14 31ms
win32 volume coprocess 14 / 14
spawns powershell with -EncodedCommand carrying the ReadLine server script
8.181496999999979ms
waits for READY before writing, then GET resolves from an OK line
2.6284670000000006ms
SET and MUTE use the wire format and parse the post-state echo
1.0845429999999965ms
an ERR line rejects only that request; the child keeps serving
2.2483749999999816ms
serializes: the second request is not written until the first resolves
0.6179300000000012ms
coalesces queued SETs while the child hangs — only the final value is written
1.025593999999984ms
kills a hung child on the first-request timeout and respawns lazily
2.119440999999995ms
breaker: three never-served children (incl. hung-killed-by-timeout) flip unsupported
1.679518999999999ms
a served child dying is NOT a strike, and resets the count
4.441597000000002ms
a spawn 'error' without 'exit' (ENOENT) still rejects and counts a strike
3.1728160000000116ms
a zombie child's late buffered stdout cannot resolve the new child's request
1.4374540000000025ms
a child exit rejects the in-flight and all queued requests
1.1159899999999823ms
a stream 'error' event is absorbed — an unlistened stream error would crash the process
0.8749970000000076ms
dispose writes EXIT and kills the child
1.0820389999999804ms
usage-encoder.test.ts
28 / 28 10ms
buildClaudeUsageEncoder 4 / 4
maps the top-level 5h/7d quota to two known tanks
3.392638000000005ms
shows "Waiting…" before the first payload
0.18377600000002303ms
shows "No usage data" when data arrived but the quota is absent
0.16343599999999014ms
treats stale data as unknown (suppresses the tanks)
0.14687100000000441ms
buildCodexUsageEncoder 4 / 4
maps codexRateLimits primary→5h, secondary→7d
0.5289470000000165ms
falls back to a muted note when Codex reports no rate limits
0.232260000000025ms
shows "Waiting…" before the first payload
0.14302599999999188ms
renders only the windows Codex actually reports (partial)
0.38617199999998775ms
buildCodexUsageEncoder — single live window 8 / 8
shows the subscription tier and its next renewal
0.4170080000000098ms
leaves the countdown to the gauge instead of restating it on the card
0.41762900000000514ms
picks the ChatGPT subscription by name, never by position
0.18679099999999949ms
drops the renewal line when the subscription has no boundary
0.17044599999999832ms
falls back to the bare plan tier when no subscription is reported
0.14056200000001695ms
falls back to the absolute reset instant when even the tier is unknown
0.2649989999999889ms
adds no card at all when the stale window leaves nothing knowable
0.13874899999999002ms
adds no side card while both windows are live
0.12076199999998494ms
buildCodexUsageEncoder — snapshot freshness 4 / 4
says nothing extra for a fresh snapshot
0.32500899999999433ms
THE REGRESSION: an aged snapshot is dated, and the percent survives
0.2607330000000161ms
renders the age into the LCD even though the side card owns the reset slot
0.7338440000000048ms
a legacy producer (no capturedAt) is unchanged
0.1220130000000097ms
renderUsageEncoderBoth — single live window 5 / 5
keeps the lone weekly gauge in its canonical right column, side card on the left
0.35441400000001977ms
keeps the gauge printing its own countdown, like E2 does
0.21332200000000512ms
keeps a lone 5h gauge in the left column instead
0.18503899999998907ms
renders the side card smaller than the gauge percentage
0.1644070000000113ms
still renders two gauges when both windows are live
0.21988099999998667ms
availableUsageViews 3 / 3
drops the zoom stop for a window the provider no longer reports
0.31894099999999526ms
keeps every stop while both windows are live
0.16000099999999406ms
leaves only the gauge and session stops when no window exists
0.11671600000002513ms
usage-scoped.test.ts
13 / 13 11ms
sanitizeScopedLabel 2 / 2
drops control chars / newlines and collapses whitespace
2.512302000000034ms
is null/undefined safe
0.29710700000003953ms
splitResetTwoLine 2 / 2
splits a two-unit countdown at the first boundary
1.337664000000018ms
leaves a single-unit string on one line
0.29083700000001045ms
pickWorstScopedLimit 3 / 3
returns the worst-sorted [0] (store keeps active-first, percent-desc)
0.3528210000000058ms
returns undefined when the snapshot is stale (a stale number reads as live)
0.2531710000000089ms
returns undefined when there are no scoped limits
0.22254500000002508ms
scoped gauge treatment — active vs inactive 4 / 4
an ACTIVE cap at 98% wears the critical red ramp
1.0121239999999716ms
an INACTIVE cap at 98% wears the calm informational cyan, NOT red
0.2659400000000005ms
the triple view mutes an inactive worst-scoped panel (no red from a 99% inactive cap)
0.7957079999999905ms
renders the unknown tile when there is no scoped cap
0.65221200000002ms
scoped label on the compact gauge 1 / 1
sanitizes, uppercases and truncates the model label
0.294633000000033ms
scoped store merge — omitted key clears 1 / 1
an update that omits scopedLimits clears a prior set (no phantom latch)
1.8803510000000188ms
npm-registry-visibility.test.ts
2 / 2 6ms
npm registry visibility 2 / 2
retries until a newly published version becomes visible
5.563015000000007ms
fails after the bounded attempt count
0.5793329999999912ms
release-notes.test.ts
11 / 11 11ms
release notes lookup 11 / 11
npm at its declared version has an entry
3.6642160000000104ms
streamdeck at its declared version has an entry
0.6118409999999983ms
ulanzi at its declared version has an entry
0.5151850000000024ms
android at its declared version has an entry
0.4995209999999872ms
esp32 at its declared version has an entry
0.5008740000000103ms
apple at its declared version has an entry
0.5199020000000019ms
matches a channel named anywhere in a multi-channel heading
0.6719910000000198ms
does not let a prefix version match a longer one
0.421133999999995ms
never falls back to a bare version heading
0.3976389999999981ms
stops a section at the next heading
0.33633599999998864ms
rejects anything that is not a delivery tag
1.674822000000006ms
version-policy.test.ts
5 / 5 6ms
cross-target version compatibility 3 / 3
ignores patch values and ordering within the same major.minor line
2.185028999999986ms
rejects different major or minor lines
0.22066199999997593ms
requires strict numeric X.Y.Z versions
0.9229700000000207ms
release tag identity 2 / 2
matches a release tag against that target, not the root patch
1.1346889999999803ms
can resolve every maintained target source
0.9011270000000025ms
setup-args.test.ts
4 / 4 2ms
parseSetupArgs 4 / 4
prints next steps by default instead of installing the daemon
2.2438689999999895ms
--yes / -y finishes the install without a second command
0.3360259999999755ms
--enterprise implies --yes
0.15278999999998177ms
ignores unknown flags rather than refusing to install
0.12243499999999585ms
brand-assets-contract.test.ts
11 / 11 8ms
canonical agent brand assets 11 / 11
keeps the Claude compatibility export on the Claude Code robot mark
2.5824369999999988ms
claudecode.svg is the geometry used by shared renderers
0.5148649999999861ms
codex.svg is the geometry used by shared renderers
0.6460130000000106ms
openclaw.svg is the geometry used by shared renderers
0.245238999999998ms
opencode.svg is the geometry used by shared renderers
0.11125799999999231ms
antigravity.svg is the geometry used by shared renderers
0.11540399999998385ms
kiro.svg is the geometry used by shared renderers
0.12013099999998644ms
mirrors every canonical path on Android and Apple vector surfaces
1.8502359999999953ms
generates constrained-device masks directly from canonical SVG files
0.7603149999999914ms
records the upstream source and trademark holder for every agent mark
0.7454920000000129ms
does not retain alternate logo-source dumps
0.48484999999999445ms
codex-freshness-rules.test.ts
8 / 8 8ms
codex freshness threshold invariants 2 / 2
is an absolute duration, not a fraction of any window
2.7407759999999826ms
is a whole number of minutes, so every platform can print it
0.4227860000000021ms
generated mirrors in sync 5 / 5
apple/AgentDeck/Model/CodexFreshnessRules.generated.swift matches the SSOT
0.5436380000000156ms
android/app/src/main/kotlin/dev/agentdeck/util/CodexFreshnessRules.generated.kt matches the SSOT
0.3047990000000027ms
emits the threshold in each platform's own unit
0.4747339999999838ms
mirrors the plan-reconciliation rule to Swift (the other PRODUCER of the wire snapshot)
0.4916600000000244ms
emits the same three footnote states the TS SSOT resolves
0.518400000000014ms
TS side still produces what the mirrors promise 1 / 1
threshold boundary matches the emitted constant
1.7582670000000178ms
creature-layout.test.ts
19 / 19 37ms
creature-layout bands 14 / 14
returns nothing for a count of zero or less
4.132881999999995ms
'octopus' keeps every slot inside its X band
5.481242000000009ms
'cloud' keeps every slot inside its X band
5.210834999999975ms
'opencode' keeps every slot inside its X band
4.143408000000022ms
'antigravity' keeps every slot inside its X band
5.245497ms
'octopus' emits exactly `count` slots
2.1834169999999915ms
'cloud' emits exactly `count` slots
1.043990999999977ms
'opencode' emits exactly `count` slots
0.9465749999999957ms
'antigravity' emits exactly `count` slots
1.2051850000000002ms
'octopus' stays on one row up to its limit, then wraps
0.5864130000000216ms
'cloud' stays on one row up to its limit, then wraps
0.15398199999998496ms
'opencode' stays on one row up to its limit, then wraps
0.12628000000000839ms
'antigravity' stays on one row up to its limit, then wraps
0.11313999999998714ms
anchors each band at a distinct X center, so types read as clusters
0.4326020000000028ms
crowd shrink 5 / 5
never grows the scale as a band fills up
1.8120380000000011ms
honors the 0.40 hard floor even when a band is packed
2.213382999999993ms
shrinks a crowded row enough to cap neighbor overlap at ~half a body
0.29583500000001095ms
gives a lone creature the band-native full scale
0.42308700000000954ms
centers a lone creature in its band
0.3145639999999901ms
d200h-layout.test.ts
28 / 28 32ms
usage tiles — usageKnown tri-state 8 / 8
renders a percent when the quota is known
3.946181000000024ms
renders a muted "—" instead of a confident 0% when unknown
0.47681800000003705ms
defaults to known (percent) when the flag is omitted
0.22955599999994547ms
wide slot shows "—" for both columns when unknown
0.6535639999999603ms
wide slot shows percents when known
0.29422299999998813ms
parseState infers usageKnown=false when no percent fields are present
0.4756760000000213ms
parseState infers usageKnown=true when a percent is present
0.25651599999997643ms
parseState honors an explicit usageKnown=false even with a coerced 0 percent
0.24564999999995507ms
buildSessionDeck — daemon offline 4 / 4
renders the OFFLINE hero on the center key for a DISCONNECTED state
3.6774970000000167ms
makes EVERY key launch the companion app while offline
2.2611349999999675ms
does not show OFFLINE / launch when the daemon is connected
1.3796370000000024ms
shows the session list (not OFFLINE) when state is disconnected but sessions exist
2.803440999999964ms
buildSessionDeck — selected session isolation 1 / 1
does not render another agent model while selected-session focus is pending
1.786709999999971ms
buildSessionDeck — per-model scoped caps 3 / 3
surfaces the worst ACTIVE scoped cap with the critical ramp
1.522942999999998ms
renders an INACTIVE scoped cap muted (informational cyan), never the ramp
0.6646900000000073ms
parseState carries scopedLimits through
0.4669129999999768ms
usage tiles — Codex snapshot freshness 4 / 4
prints the countdown, undimmed, for a fresh snapshot
1.0194549999999936ms
THE REGRESSION: an aged snapshot keeps its % but is dimmed and dated
2.472763000000043ms
an ended window still reads "stale", not an age
0.4213940000000207ms
a legacy producer (no capturedAt) renders exactly as before
0.41212999999999056ms
usage tiles — scoped caps and the three-key strip budget 4 / 4
emits at most ONE scoped tile, however many caps arrive
0.6474549999999795ms
documents the cost: the scoped tile takes the slot Codex 5H used to hold
0.7905499999999961ms
sanitizes and truncates the API label before it reaches SVG text
0.3849299999999971ms
renders no scoped tile when there are none
0.34991600000000744ms
VOICE tile — hold-to-talk contract 4 / 4
tells the user to hold, not to tap
0.8253429999999753ms
reads as listening while the daemon captures
0.8231499999999983ms
still declares the wire commands the layout is responsible for
1.6560829999999669ms
goes inert only while transcribing
0.37785800000000336ms
d200h-observed.test.ts
14 / 14 17ms
D200H observed session detail 14 / 14
idle: REVIEW + VOICE are the actionable cells — no fake prompts, inert STOP
6.992738000000003ms
idle while recording: the VOICE tile flips to a stop toggle
0.6003039999999942ms
processing: soft STOP is the only action; no queued task or REVIEW mid-turn
1.830535999999995ms
processing: last review verdict stays visible as an inert badge
0.5868340000000103ms
processing + stopRequested: STOP replaced by STOPPING tile, no queue presets
0.8118920000000003ms
awaiting + requestId: exactly ALLOW/DENY permission_decision cells
0.6929329999999823ms
awaiting WITHOUT requestId: answer-in-terminal only, never fabricated Allow/Deny
0.4742640000000051ms
AskUserQuestion options are visible but inert without a live-answer host
1.2474479999999915ms
liveAnswerable turns the same options into select_option presses
0.7909710000000132ms
codex observed idle: REVIEW only — steering stays inert (notify-only hooks)
0.44391899999999396ms
codex observed processing: nothing actionable — REVIEW waits for turn end
0.4111490000000231ms
opencode observed idle: inject-now presets via session_command (plugin queue)
0.8331739999999854ms
opencode observed permission gate: ALLOW/DENY carry the ocperm requestId
0.4180499999999938ms
managed sessions keep the original idle quick-actions (regression)
0.8216070000000002ms
d200h-openclaw-approval.test.ts
4 / 4 16ms
D200H — OpenClaw exec approval 4 / 4
renders the real command and its decisions, not the global idle state
10.061247000000009ms
every decision is a pressable select_option carrying its own index
3.1117849999999976ms
keeps the relayed event authoritative when IT is the one with the prompt
1.08866900000001ms
an idle gateway row still reads as idle
0.7857630000000029ms
format-utils.test.ts
58 / 58 19ms
formatDurationSec 4 / 4
formats sub-minute spans as seconds
2.155946ms
formats minute spans, dropping a zero-second remainder
0.26113300000000095ms
formats hour spans, dropping a zero-minute remainder
0.2912780000000055ms
clamps negatives to zero
0.21020599999999945ms
formatAntigravityPlanShort 6 / 6
shortens "Google AI Pro" to "AGY Pro"
0.3808039999999835ms
shortens "Google AI Ultra" to "AGY Ultra"
0.24483800000001565ms
strips an "Antigravity " prefix
0.2381689999999992ms
returns undefined for blank/absent input
0.2754639999999995ms
is idempotent on already-shortened values
0.1879329999999868ms
collapses a bare "Google AI" to "AGY"
0.12815299999999752ms
adjustUsagePercent 11 / 11
returns undefined when percent is null
0.20310599999999113ms
returns undefined when percent is undefined
0.1215219999999988ms
returns percent unchanged when resetsAt is null
0.16524900000001708ms
returns percent unchanged when resetsAt is undefined
0.3455099999999902ms
returns percent unchanged when resetsAt is in the future
0.45393300000000636ms
returns 0 when resetsAt is in the past (window expired)
0.22357600000000843ms
returns 0 when resetsAt equals now (edge case)
0.2404019999999889ms
handles invalid date string gracefully (returns percent)
0.21280100000001312ms
handles empty string resetsAt (returns percent)
0.19693599999999378ms
returns percent unchanged when resetsAt is far in the past (>1h)
0.23562499999999886ms
still returns 0 just after the 1h threshold boundary
0.22292600000000107ms
isCodexWindowStale 6 / 6
returns false when resetsAt is undefined
0.30953599999998005ms
returns false for an invalid date string
0.20713100000000395ms
returns false when resetsAt is in the future
0.21649600000000646ms
returns false when resetsAt is in the past but within the grace window
0.218970000000013ms
returns true when resetsAt is past beyond the grace window
0.2441169999999886ms
honors a custom grace
0.257788000000005ms
codex snapshot freshness 14 / 14
codexSnapshotAgeMs › returns undefined for missing / unparseable stamps
0.3191309999999987ms
codexSnapshotAgeMs › measures age against the supplied clock
0.27147899999999936ms
codexSnapshotAgeMs › clamps a future stamp to zero rather than going negative
0.22394700000000967ms
isCodexSnapshotAged › is false when there is nothing to judge
0.3176690000000235ms
isCodexSnapshotAged › is false for a snapshot inside the threshold
0.25917000000001167ms
isCodexSnapshotAged › is false exactly at the threshold, true past it
0.2587999999999795ms
isCodexSnapshotAged › honors a custom max age
0.2465310000000045ms
formatSnapshotAge › rounds DOWN so the label never overstates freshness
0.47102899999998726ms
formatSnapshotAge › returns undefined when there is nothing to say
0.2003219999999999ms
codexUsageFootnote › says nothing for a live window with a fresh snapshot
0.28791400000000067ms
codexUsageFootnote › THE REGRESSION: a 4h-old snapshot behind a 6-day-out weekly reset is aged
1.2510629999999878ms
codexUsageFootnote › an ended window outranks age — "stale", not an age
0.28428800000000365ms
codexUsageFootnote › says nothing when there is no window at all
0.1975970000000018ms
codexUsageFootnote › says nothing for a live window with no capture stamp (legacy producer)
0.17766800000001126ms
formatResetTime 7 / 7
returns "now" when resetsAt is in the past
0.30055300000000784ms
returns undefined for null input
0.1832159999999874ms
returns minutes-only for < 1h remaining
0.3349939999999947ms
returns hours and minutes for < 24h remaining
0.26829399999999737ms
returns days and hours for >= 24h remaining
0.2776179999999897ms
omits minutes when exactly on the hour
0.2503370000000018ms
passes through pre-formatted strings (no T)
0.19087799999999788ms
codexSnapshotMatchesAccountPlan 3 / 3
voids a snapshot minted under a plan the account no longer holds
0.2900669999999934ms
keeps a matching snapshot, free included — free is a plan, not a synonym for void
0.31079800000000546ms
treats an unknown tier on either side as no information, never as licence to void
0.2756339999999966ms
isCodexFreePlan 2 / 2
recognises the free tier regardless of case or padding
0.28618099999999913ms
is false for every paid tier and for an unknown one
0.39849000000000956ms
scopedLimitClaimsUsageKey 2 / 2
claims a key when a scoped cap is present
0.3225850000000037ms
claims nothing when there is no cap
0.2140019999999936ms
codexWindowsBeside 3 / 3
retains all Codex windows beside the scoped cap
0.4858210000000156ms
leaves Codex untouched when no cap claims a key
0.2429559999999924ms
returns empty when Codex reports nothing
0.24104299999999057ms
idotmatrix-identity.test.ts
12 / 12 8ms
BLE UUID normalization 3 / 3
expands the short advertisement forms onto the Bluetooth base UUID
3.489262999999994ms
left-pads a short form that dropped its leading zeroes
0.34830400000001305ms
leaves an unrelated 128-bit UUID alone
0.19486399999999549ms
iDotMatrix discovery predicate 6 / 6
matches the iDotMatrix and iPixel name families case-insensitively
0.45607599999999593ms
does not match unrelated peripherals
0.2512879999999882ms
accepts a user-configured prefix for the next rebrand
0.23500400000000354ms
identifies an unnamed peripheral by its advertised service UUID
0.362796000000003ms
still identifies a named panel that keeps the service out of its advertisement
0.20456699999999728ms
rejects a peripheral with neither signal
0.3077030000000036ms
generated mirrors in sync 3 / 3
apple/AgentDeck/Daemon/Modules/IDotMatrixIdentity.generated.swift matches the SSOT
0.46778400000002307ms
bridge/src/idotmatrix/identity_generated.py matches the SSOT
0.29464300000000776ms
emitters embed the SSOT literals (sanity on the emitters themselves)
0.783409000000006ms
llm-settings.test.ts
10 / 10 13ms
llm-settings 10 / 10
returns defaults when settings.json is missing
4.654037000000017ms
reads llm.mlx pin from settings.json
0.7848820000000103ms
treats "qwen3-30b" and "default" as placeholders (unpinned)
1.105684999999994ms
falls back to apme.judge.model when llm.mlx is absent
0.6533239999999978ms
strips /chat/completions suffix from legacy endpoints
0.5735139999999888ms
prefers llm.mlx over apme.judge when both set
0.45984200000000897ms
resolveMlxModel: pin > probe > fallback
1.724745999999982ms
pickMlxModel: 4-layer priority (pin > fallback > first > null)
0.850781000000012ms
mlxChatUrl reflects endpoint setting
0.5624870000000044ms
caches result for TTL window
2.480254000000002ms
mdns-identity.test.ts
7 / 7 5ms
sanitizeMdnsLabel 2 / 2
keeps a hostname greppable and collision-free
2.309316000000024ms
bounds the label so the whole instance name stays inside DNS-SD limits
0.3973489999999913ms
mdnsUserTag 2 / 2
is stable, short, and never the account name
0.5165880000000129ms
separates two accounts on one machine
0.705742000000015ms
buildMdnsInstanceName 2 / 2
names host, user and port — the three ways two daemons can differ
0.17310100000000261ms
degrades to the old shape rather than emitting a malformed name
0.1600310000000036ms
generated Swift mirror 1 / 1
matches this source
0.38813399999997955ms
model-provider.test.ts
8 / 8 10ms
modelProvider 2 / 2
names the provider behind every id shape the wire actually carries
3.3865980000000206ms
answers unknown rather than guessing — the polarity is the point
0.5029069999999933ms
offHarnessProvider 4 / 4
badges the real case: Claude Code answering from z.ai
0.3811139999999966ms
says nothing when the harness is where it belongs
0.2954849999999851ms
never turns two unknowns into a claim
0.2464610000000107ms
leaves multi-provider harnesses alone
0.5874950000000183ms
generated mirrors 2 / 2
are in sync with this source
2.971913999999998ms
carry every provider, so no mirror can silently drop one
1.3522360000000049ms
no-side-effects.test.ts
4 / 4 23ms
shared is side-effect free 4 / 4
finds source files to check
1.9150740000000042ms
has no top-level executable statements
10.358304000000004ms
performs no import-time I/O, timers, or global mutation
11.208883999999983ms
declares sideEffects: false so bundlers actually act on this
0.4201319999999953ms
observed-agent-rules.test.ts
5 / 5 108ms
observed session ids 2 / 2
strips every advertised prefix, Kiro included
2.426884000000001ms
keeps the regex and the list from disagreeing about which agents exist
0.3772480000000087ms
observed tool_exec suppression 1 / 1
covers every observed agent whose tool rows are a firehose
0.28411800000000653ms
generated mirrors 2 / 2
match this source
0.5237889999999936ms
leaves no hand-written copy of the list anywhere in the app sources
103.95240099999998ms
openclaw-approval-rules-sync.test.ts
4 / 4 6ms
generated mirror in sync 4 / 4
apple/AgentDeck/Daemon/Gateway/OpenClawApprovalRules.generated.swift matches the SSOT
3.1235429999999837ms
the Swift mirror carries every decision the TS union declares
0.7241100000000245ms
neither side ever offers the plain "allow" the Gateway rejects
1.388620000000003ms
the Swift mirror reads the nested request, not flat fields
0.29085799999998585ms
openclaw-approval.test.ts
18 / 18 8ms
parseExecApprovalRequest 12 / 12
reads the command out of the nested request
2.1650289999999757ms
never renders `ask` as if it were the question
0.28141399999998384ms
carries cwd and warning as supporting detail
0.1834559999999783ms
offers exactly the decisions the request allows
0.8432000000000244ms
drops allow-always when the policy withholds it
0.2618739999999775ms
honors unavailableDecisions on top of the allowed set
0.26983699999999544ms
always keeps a deny — a prompt you can only accept is not a prompt
0.2752439999999865ms
still produces an answerable prompt when no command was reported
0.42660300000000007ms
falls back to flat fields if a Gateway ever inlines them
0.2302270000000135ms
falls back to argv when only that is present
0.22749200000001224ms
returns null only when there is no usable id
0.45303200000000743ms
carries the expiry so a stale prompt can be swept
0.18921499999999014ms
answering 6 / 6
maps an option index to the decision that option carries
0.33294100000000526ms
refuses an out-of-range index instead of guessing
0.20615000000000805ms
accepts shortcuts, decision names, and the y/n/a spellings
0.48900599999998917ms
never turns an unrecognized press into an approval
0.25871899999998504ms
refuses "always" when the request forbids allow-always
0.24931499999999573ms
classifies which decisions let the command run
0.3092359999999985ms
pairing-code-rules-sync.test.ts
12 / 12 9ms
generated mirrors in sync 5 / 5
apple/AgentDeck/Model/PairingCodeRules.generated.swift matches the SSOT
2.8872169999999926ms
android/app/src/main/kotlin/dev/agentdeck/net/PairingCodeRules.generated.kt matches the SSOT
0.3246990000000096ms
emitters embed the SSOT constants (sanity on the emitters themselves)
0.5084459999999922ms
the Swift mirror emits every outcome the TS union declares
0.34696299999998814ms
Kotlin stays a client mirror — no evaluator, no HTTP statuses
0.30449900000002117ms
status contract the mirrors must agree on 7 / 7
accepted answers 200 in TS and in the Swift mirror
1.8929600000000164ms
no-window answers 401 in TS and in the Swift mirror
0.4051499999999919ms
expired answers 410 in TS and in the Swift mirror
0.2550239999999917ms
exhausted answers 429 in TS and in the Swift mirror
0.35659700000002204ms
mismatch answers 401 in TS and in the Swift mirror
0.2866819999999848ms
malformed answers 400 in TS and in the Swift mirror
0.26662099999998645ms
the Swift mirror decides expiry before it reads the code
0.3808830000000114ms
pairing-code.test.ts
23 / 23 10ms
normalizePairingCode 5 / 5
accepts a bare code
2.807938000000007ms
accepts the separators a human or a formatted display introduces
0.46799400000000446ms
rejects anything that is not exactly the code length
0.3508679999999913ms
rejects non-strings rather than coercing them
0.32769300000001067ms
isPairingCode only accepts the canonical form
0.279861000000011ms
formatPairingCode 3 / 3
groups the code in half for reading aloud
0.22425799999999185ms
normalizes before grouping, so formatting is idempotent
0.19377200000002404ms
passes through anything it cannot parse instead of mangling it
0.14268500000000017ms
evaluatePairingRedemption 11 / 11
accepts the right code and closes a single-redemption window
0.5415859999999952ms
keeps a multi-device window open until its last credential
0.2984399999999994ms
accepts a code that arrives with the separators it was displayed with
0.17792699999998263ms
answers 401 with no window, so a closed daemon looks like an unknown route
0.24638100000001373ms
decides expiry before it looks at the code
0.28061199999999076ms
treats the expiry instant as closed, not as the last open millisecond
0.28053299999999126ms
burns one attempt per well-formed wrong code and closes on the last one
0.8802849999999864ms
refuses a window whose attempts are already spent, even for the right code
0.2918899999999951ms
refuses a window with no credentials left
0.22334599999999227ms
does not spend an attempt on a malformed submission
0.8571410000000128ms
gives an attacker at most PAIRING_MAX_FAILED_ATTEMPTS guesses per window
0.2994109999999921ms
pairingWindowSecondsRemaining 2 / 2
rounds up so a countdown never shows 0 while the window is still open
0.3192809999999895ms
floors at zero for an expired or absent window
0.21597500000001446ms
constants 2 / 2
keeps the code long enough that the attempt cap is the real defence
0.2701769999999897ms
keeps the window short enough to be an operator action, not a mode
0.38549000000000433ms
pricing.test.ts
11 / 11 5ms
isLocalModel 5 / 5
accepts the judge tag the runner emits for Foundation Models
2.5479860000000087ms
accepts the bare Foundation Models spellings
0.28050300000001016ms
accepts raw ids as a local server advertises them
0.15958999999998014ms
accepts the explicit local prefixes
0.1544930000000022ms
does not claim hosted models are local
0.2486340000000098ms
local models cost nothing and say so 3 / 3
prices local judge tags at $0
0.24662100000000464ms
reports them as priced, not as unpriced
0.3133820000000185ms
groups them under the local provider
0.262235000000004ms
normalizeModelId 3 / 3
strips hosted provider prefixes
0.23954100000000267ms
keeps the org segment of a local id
0.12629000000001156ms
still prices a hosted model after normalization
0.17300000000000182ms
protocol-generated-sync.test.ts
12 / 12 6ms
generated protocol artifacts in sync 12 / 12
generated/protocol/bridge-event-schema.json matches the SSOT
2.223997999999483ms
generated/protocol/plugin-command-schema.json matches the SSOT
0.3023960000009538ms
generated/protocol/gateway-frame-schema.json matches the SSOT
0.23101799999858486ms
generated/protocol/BridgeEvent.swift matches the SSOT
0.8610559999997349ms
generated/protocol/PluginCommand.swift matches the SSOT
0.19343099999969127ms
generated/protocol/GatewayFrame.swift matches the SSOT
0.5125019999995857ms
generated/protocol/BridgeEvent.kt matches the SSOT
0.3934829999998328ms
generated/protocol/PluginCommand.kt matches the SSOT
0.18785299999944982ms
generated/protocol/GatewayFrame.kt matches the SSOT
0.36763299999984156ms
generated/protocol/AgentCommand.swift matches the SSOT
0.19202899999982037ms
generated/protocol/AgentCommand.kt matches the SSOT
0.18907500000022992ms
shared/src/command-builders.ts matches the SSOT
0.1320290000003297ms
session-deck-usage.test.ts
22 / 22 36ms
buildSessionDeck list-view usage tiles 17 / 17
pins 5H/7D to the bottom strip and wires them to query_usage
17.288567999999998ms
leaves the upper grid and the clock-side keys entirely to sessions
0.9940270000000169ms
fills the strip from the right, freeing the leftmost key for a session
0.533032999999989ms
does not reserve usage slots when showUsage is off (regression: full grid)
1.138764999999978ms
frees the usage slots (no residue) when usage is unknown
0.6148359999999684ms
frees only the Claude slots when Codex-only usage is present (partial)
0.8039099999999735ms
fits sessions into the 13 non-usage keys without paging
0.7461339999999836ms
paginates when sessions exceed capacity, NEXT→ sits on the last free key
1.3498319999999921ms
page 2 keeps the usage tiles pinned and shows the remainder
0.7247810000000072ms
shows usage even with zero sessions
0.4146039999999971ms
caps the strip at 3 keys, dropping the 4th tile (Claude prioritised)
2.906807000000015ms
renders only the Codex window whose datum exists
0.4470630000000142ms
labels the Codex weekly window "7D" when it arrives in the primary slot (secondary null)
0.7575309999999718ms
shows a credits tile when Codex reports a credit-based plan (null windows)
0.673985000000016ms
renders ∞ for an unlimited-credits Codex plan
0.5435689999999909ms
falls back to trailing keys on a tiny deck where the strip is not placed
0.5495379999999841ms
never starves the only key on a 1-key deck (usage yields to the session)
0.3954149999999572ms
buildSessionDeck scoped cap vs the third usage key 5 / 5
gives the key Codex vacated to the scoped cap on a free ChatGPT tier
0.8801149999999893ms
lets an ACTIVE cap TAKE the Codex key — it is the limit that binds
0.6600139999999897ms
leaves the first Codex window standing when Codex reports two
0.5444200000000023ms
never lets an INACTIVE cap displace a live Codex window
0.6249709999999595ms
shows nothing but Claude when neither Codex nor a scoped cap exists
0.5869640000000231ms
session-slot-anim.test.ts
12 / 12 18ms
session slot animation cycle 9 / 9
returns to its starting phase after one cycle (processing, active=false)
7.0916ms
returns to its starting phase after one cycle (processing, active=true)
1.5358319999999992ms
returns to its starting phase after one cycle (awaiting_permission, active=false)
0.784610999999984ms
returns to its starting phase after one cycle (awaiting_permission, active=true)
0.9661440000000141ms
returns to its starting phase after one cycle (idle, active=false)
0.7154769999999928ms
returns to its starting phase after one cycle (idle, active=true)
0.9168999999999983ms
animates the processing border without an explicit start frame
0.6289060000000006ms
keeps a supplied start frame as a phase offset, not a freeze
0.6918410000000108ms
leaves an unfocused idle tile static — it must not be encoded as a loop
0.4212440000000015ms
tile identity is byte-stable 3 / 3
renders the same quiet slot identically every time
0.44069399999997927ms
renders the same empty slot identically every time
0.3695859999999982ms
emits no random-looking ids from any session-slot renderer
1.5794879999999978ms
session-utils.test.ts
46 / 46 25ms
OpenClaw visibility SSOT 2 / 2
isOpenClawSessionActive is true only when gatewayConnected
2.167574000000002ms
hasOpenClawSession detects an emitted openclaw session
0.29503400000001534ms
agentTypeRank 1 / 1
ranks known agents stably, with Kiro after the existing agent set
0.3511190000000113ms
naturalLabelCompare 2 / 2
orders numeric chunks naturally (Agent 2 before Agent 10)
7.847072999999995ms
treats undefined as empty string
0.2604419999999834ms
sortSessions 6 / 6
places openclaw before claude-code regardless of project
0.9529150000000186ms
sorts by project name within the same agent type
0.25507399999997915ms
sorts numbered project names naturally (#2 before #10)
0.19145900000000893ms
breaks ties on startedAt ascending (oldest first)
0.19031699999999319ms
falls back to id natural-compare when startedAt ties to the same ms
0.1901759999999797ms
does not mutate the input array
0.16961599999999066ms
sessionWeight 5 / 5
returns the weight when it is a finite number (incl. negatives and 0)
0.22067200000000753ms
collapses missing / null / non-finite weights to 0
0.15539400000000114ms
accepts both documented bounds unchanged
0.1373570000000086ms
clamps out-of-range values to the documented bounds
0.20276499999999942ms
integer-truncates fractional values so all platform mirrors agree
0.1286139999999989ms
sanitizeWeightForWire 2 / 2
drops non-numbers and non-finite values to undefined (wire omits the key)
0.3001820000000066ms
passes in-range integers and clamps/truncates the rest
0.2185790000000054ms
sortSessions weight comparator safety 1 / 1
orders opposite-sign extreme in-range weights without overflow tricks
0.20184399999999414ms
sortSessions weight override 6 / 6
orders by weight ascending: negatives, then unweighted/0, then positives
0.18056199999998057ms
treats an unweighted session the same as weight 0
0.19294999999999618ms
weight beats agentType — a weighted claude-code sorts before an unweighted openclaw
0.17108799999999746ms
within the same weight, existing ordering (agentType → project → startedAt → id) still applies
0.19201899999998773ms
maps terminal tab order onto the deck: tab N (weight N) lands in slot N
0.18288599999999633ms
does not change ordering when no session has a weight (backward compatible)
0.26424800000000914ms
foldCodexSessionsForDisplay 4 / 4
folds Codex CLI and Codex App separately even with the same project
1.3968929999999773ms
never folds same-project Codex sessions pinned to distinct weights
0.20768200000000547ms
keeps distinct-weight sessions unfolded across state changes
0.3719900000000109ms
still folds same-project Codex sessions when both are unweighted or share a weight
0.40755400000000463ms
assignDisplayNames 4 / 4
passes single sessions through without #N suffix
0.33917100000002165ms
adds #1/#2 suffixes for duplicate (project, agentType) tuples in input order
0.36444899999997915ms
numbers same project across different agentTypes independently
0.41555599999998094ms
produces the same #N assignment as a deterministic sort + display pipeline
0.5128430000000037ms
normalizeProjectForGrouping 2 / 2
strips path and trailing #N suffix
0.43206100000000447ms
handles empty/undefined
0.1685939999999846ms
projectGroupKey 5 / 5
exact match groups
0.2528400000000204ms
long multi-token stems fuse
0.18542899999999918ms
delimiter extension fuses ("foo…" + "foo…-1")
0.144818000000015ms
short sibling projects stay separate
0.20942600000000766ms
stems with fewer than 2 delimiters stay separate
0.18162399999999934ms
groupSessionsByProject 3 / 3
clusters same-stem worktrees and keeps singletons flat
0.8658329999999808ms
groups duplicate sessions of the same project (#N suffixed)
0.5007540000000006ms
preserves input order within groups
0.4010940000000005ms
rawSessionId / sameSession 3 / 3
strips every observed agent prefix
0.4526309999999967ms
leaves managed and already-bare ids alone
0.21351200000000858ms
sameSession bridges the two keying forms
0.26600100000001703ms
session-weight-rules.test.ts
6 / 6 6ms
session weight range invariants 2 / 2
range is symmetric around the neutral band and fits every platform integer
3.022059000000013ms
sessionWeight clamps exactly to the SSOT bounds
0.3879540000000077ms
generated mirrors in sync 3 / 3
apple/AgentDeck/Model/SessionWeightRules.generated.swift matches the SSOT
0.3801019999999937ms
android/app/src/main/kotlin/dev/agentdeck/net/SessionWeightRules.generated.kt matches the SSOT
0.23769800000002306ms
emitters embed the SSOT literals (sanity on the emitters themselves)
0.4971090000000231ms
self-contained hand-port copies 1 / 1
D200HLayoutModel.swift carries the same weight-range literals
0.491691000000003ms
state-transitions.test.ts
8 / 8 15ms
generated mirrors in sync 4 / 4
apple/AgentDeck/Daemon/Core/StateTransitions.generated.swift matches the SSOT
3.2766929999999945ms
every daemon-only generated file carries the macOS guard
0.44409899999999425ms
emits a Swift case name for every state, with a rawValue only where they differ
0.6549760000000049ms
carries each transition note into the mirror
1.0807680000000062ms
transition table invariants 4 / 4
is deterministic — no two rows match the same (from, trigger, source)
1.4953910000000121ms
leaves AWAITING_* without a wall-clock backstop
1.327809000000002ms
gives every AWAITING_* state a hook-driven exit
0.6487369999999828ms
every row targets a real state and a known source
5.115830999999986ms
subagent-activity.test.ts
4 / 4 4ms
deriveSubagentActivity 4 / 4
pairs summarized starts and completions under their parent session
3.6814629999999795ms
uses team completion rows only as a recent completion pulse
0.3769880000000114ms
ignores ordinary tools and expires orphaned starts
0.21554500000002008ms
sorts history rows before pairing them
0.1662900000000036ms
svg-renderers/model-alias.test.ts
7 / 7 5ms
aliasModelName 3 / 3
shortens claude family-major-minor
3.277384000000012ms
drops trailing date suffix on claude releases
0.2230350000000101ms
passes gpt and unknown strings through unchanged
0.2269820000000209ms
formatModelEffort 4 / 4
returns aliased model when no effort to show
0.323757999999998ms
appends non-default effort when it fits
0.16959600000001274ms
truncates aliased model name to fit budget with effort suffix
0.30747199999999ms
returns empty string for missing model
0.15680699999998637ms
terrarium-rules.test.ts
5 / 5 4ms
terrarium rules invariants 2 / 2
floor-rest clear anchor stays left of the crayfish claws
2.731273000000016ms
rest strips sit above the crayfish, below mid-water
0.29953100000000177ms
generated mirrors in sync 3 / 3
apple/AgentDeck/Terrarium/TerrariumRules.generated.swift matches the SSOT
0.5204830000000129ms
android/app/src/main/kotlin/dev/agentdeck/terrarium/TerrariumRules.generated.kt matches the SSOT
0.30716300000000274ms
esp32/src/ui/terrarium/terrarium_rules_generated.h matches the SSOT
0.25561400000000845ms
text-sanitize.test.ts
5 / 5 5ms
stripUnsafeText 4 / 4
strips ANSI CSI sequences but keeps the visible text
2.9912239999999883ms
strips OSC sequences and bare ESC forms
0.4001130000000046ms
strips XML-invalid control characters but keeps tab/newline
0.38282599999999434ms
strips lone surrogate halves but keeps full emoji
0.3738119999999867ms
escSvgText 1 / 1
entity-escapes after stripping
0.2934009999999887ms
timeline-summarizer.test.ts
13 / 13 5ms
extractTopicHintWithKind — Korean polite-closer robustness 7 / 7
returns the cleaned topic when the response opens with "네, …"
2.451049999999981ms
returns the original (kind=fallback) when the entire response is just a polite closer
0.33863999999999805ms
returns null for empty / very short text (still)
0.2237869999999873ms
skips lone heading markers and code fences
0.3036170000000027ms
a heading WITH text becomes the topic (heading is the title)
0.16731199999998125ms
strips list bullet markers
0.1393899999999917ms
extractTopicHint convenience returns just the hint string
0.1423939999999959ms
promptSnippetFallback 6 / 6
returns first sentence trimmed
0.23327199999999948ms
returns whole string when no sentence terminator
0.24009100000000672ms
truncates to maxLen with ellipsis
0.23458299999998644ms
cuts at first newline if no sentence terminator
0.14605000000000246ms
returns null for empty / very short input
0.13318099999997912ms
handles Korean prompts
0.1293850000000134ms
timeline-task-display.test.ts
15 / 15 8ms
timelineIsMeaningfulTaskTitle 2 / 2
rejects empty and auto-minted numeric titles
3.2333480000000066ms
accepts real titles
0.3471720000000005ms
timelineTaskClosure 2 / 2
finds the matching task_end by taskId
0.3588100000000054ms
ignores mismatched ids and non-headers
0.32382700000002274ms
timelineShouldRenderTaskRow 7 / 7
never renders task_end standalone — including interrupted reaper rows
0.30265500000001566ms
passes non-task rows through
0.18120300000001066ms
hides bare "Task N" headers with no eval payload (open or interrupted)
0.3434469999999976ms
shows headers with meaningful titles
0.2134709999999984ms
shows judged tasks via the closure eval payload
0.2277520000000095ms
_empty category hides regardless of source
0.2628260000000182ms
a non-_empty closure category alone qualifies as eval payload
0.21948000000000434ms
timelineTaskHeaderDisplay 4 / 4
folds closure label, badge fields, and closedAt into the header
0.7559280000000115ms
keeps a meaningful own title over the judge summary
0.265168999999986ms
open task: not closed, no closure text, falls back to own raw
0.3204020000000014ms
closedAtMs falls back to the closure ts when endedAt is absent
0.19041599999999903ms
timeline-task-hierarchy.test.ts
47 / 47 16ms
deduplicateEntry — task hierarchy 4 / 4
always adds task_start even with identical raw within 8s
2.487684999999999ms
always adds task_end with same boundarySignal back-to-back
0.33765900000000215ms
always adds task_milestone even with identical raw within 8s
0.23682700000000523ms
still dedupes ordinary chat_start within 8s
0.2463109999999915ms
timelineIconKey 5 / 5
maps task entries to "task"
0.2624749999999949ms
maps tool_request status to success/error/awaiting
0.3262510000000134ms
chat_start in flight is "running"; chat_end is "success"
0.18781300000000556ms
error → error; user_action → user; memory_recall → memory
0.1645080000000121ms
every key has an e-ink glyph of constant 4-char width
0.43517499999998677ms
isInFlightTask 6 / 6
task_start without matching task_end is in flight
0.30361800000000017ms
task_start whose task_end (same taskId) appeared is finished
0.14808299999998553ms
mismatched taskId on task_end does not close it
0.11952999999999747ms
task_start without taskId is never considered in flight
0.10378700000001118ms
non-task_start entries are never in flight
0.1315580000000125ms
task_start older than the staleness cap is no longer in flight
0.21768799999998123ms
isRotatingEntry 10 / 10
chat_start without a timestamp rotates (icon-key running, legacy rows)
0.30619100000001254ms
fresh chat_start rotates
0.21169900000001007ms
chat_start older than the age cap stops rotating
0.14270500000000652ms
chat_start with a later same-session completion stops rotating
0.15496400000000676ms
chat_start superseded by a newer same-session prompt stops rotating
0.14954499999998916ms
other sessions' completions do not stop a running chat_start
0.1282329999999945ms
orphan task_start rotates via in-flight predicate
0.11182900000000018ms
closed task_start does not rotate
0.11016499999999496ms
static rows do not rotate
0.18337600000000975ms
eval_result and task_end never rotate
0.12929499999998484ms
parseTimelineMarkdown 9 / 9
returns single text line for plain text
1.1416580000000067ms
parses headings 1-6 with required space
0.5821669999999983ms
parses bullets and numbered lists
0.4034469999999999ms
handles code fence — verbatim lines, not interpreted
0.2966959999999972ms
blank line → blank kind
0.23293100000000777ms
parses tables with header separator
0.4742039999999861ms
parses tables without separator (no header)
0.2799009999999953ms
table block ends at first non-table line
0.2252990000000068ms
quote lines parse
0.1834559999999783ms
parseInlineSpans 9 / 9
returns empty for empty string
0.3856299999999919ms
returns single plain span for plain text
0.22932499999998868ms
parses **bold**
0.17828799999998068ms
parses *italic* (single star)
0.16319500000000176ms
parses `code` inline
0.2551039999999887ms
parses [text](url) link
0.22316599999999198ms
unclosed ** falls back to plain
0.14948499999999854ms
multiple spans in one line
0.1769170000000031ms
first-match-wins: ** consumed before * (no double-italic split)
0.13097700000000145ms
prepareMarkdownDetail 4 / 4
preserves markdown markers (chat-response detail goes to client)
0.5548149999999907ms
still filters system JSON blobs
0.18535900000000538ms
collapses 3+ blank lines but keeps double-blank paragraph break
0.12128300000000536ms
contrasts with cleanDetailText which strips markdown (non-chat path)
0.749559000000005ms
voice-ptt.test.ts
8 / 8 6ms
Stream Deck VOICE hold lifecycle 5 / 5
maps key-down plus a real hold to begin then end
4.050277999999992ms
cancels a key-clack tap shorter than the minimum hold
0.3448490000000106ms
cancels a held key that disappears during a page or profile switch
0.2726499999999987ms
ignores lifecycle events from another action instance
0.1872719999999788ms
maps terminal PTT actions to daemon wire commands
0.17475299999998128ms
cancelActive — releases that can never arrive 3 / 3
cancels the open hold without knowing which key owns it
0.2188899999999876ms
is a no-op when nothing is held, so a stray socket close sends nothing
0.11924899999999639ms
does not fire twice for one hold
0.133340000000004ms
voice-reply-digest.test.ts
15 / 15 11ms
spokenDigest parity cases 7 / 7
first sentence only, not the whole paragraph
4.167102999999997ms
explicit summary label wins over the opening sentence
0.46082400000000234ms
bare summary label takes the line after it
0.4013439999999946ms
a heading-only first line is skipped for the prose under it
0.5522109999999998ms
code fences never get recited
0.17737699999997858ms
a version number does not end the sentence
0.1447769999999764ms
nothing speakable stays empty
0.14576899999997295ms
spokenDigest 6 / 6
reads one sentence out of a long answer, not the whole thing
0.4608029999999985ms
keeps a summary line even when it is the last thing in the reply
0.3597019999999702ms
does not treat prose that merely opens with a label word as a summary
1.135458999999969ms
cuts an over-long single sentence on a word boundary
0.6507899999999722ms
honours full: true for callers that opted back in
0.29253999999997404ms
stays empty when there is nothing to say
0.23474299999998038ms
speakableReply 2 / 2
keeps the whole readable answer
0.6156669999999735ms
caps at the monologue ceiling
0.25671599999998307ms
Android PASS
JUnit + Robolectric · 29 files · 375 tests
MainActivityOverrideRecoveryTest
5 / 5 5ms
a timed-out startup read is distinguishable from genuine defaults
3ms
recreate when the user changes the panel override
1ms
expired startup read recovers a persisted show-anyway choice
no recreate when storage matches what the instance was built from
pressing show anyway takes effect through the same comparison
MainActivityScreenPolicyTest
6 / 6 1ms
LCD releases keep-screen-on for host full-off sleep
1ms
LCD releases keep-screen-on when keep-awake is disabled
LCD releases keep-screen-on for legacy sleep event without dim config
LCD stays on for minimum-brightness dim mode
LCD stays on when host disables downstream dimming
e-ink stays on during host full-off sleep
data.DashboardOrientationTest
3 / 3 1ms
defaults keep e-ink fixed and tablets auto-rotating
legacy unspecified preference still counts as auto
1ms
manual rotate toggles fixed modes from auto using current posture
net.AndroidDashboardRegistrationTest
3 / 3 46ms
repeated identity does not duplicate registration churn
36ms
disconnected change is retried when the socket opens
1ms
connected profile change publishes new wire kind without reconnect
8ms
net.AutoConnectRulesTest
6 / 6 17ms
the canonical port is preferred but not required
14ms
the first loopback re-probe waits, and later ones back off
the backoff is capped, and never inverts or overflows
1ms
only the daemon hub is dialable
no daemon means no dial
2ms
a negative miss count is treated as the first probe
net.BridgeDiscoveryTest
2 / 2 7ms
ws url uses primary host and preserves pairing token
7ms
fallback url is absent without a fallback host
net.PairingCodeClientTest
14 / 14 4.9s
an unexpected status is reported rather than guessed at
4419ms
normalize accepts a bare code
47ms
a missing attempt count degrades to unknown, never to zero
43ms
410 and 429 mean the window is gone, not that the code was wrong
40ms
normalize rejects anything that is not the code length
37ms
constants match the daemon's
36ms
200 without a token is a daemon fault, not a pairing
44ms
normalize accepts the separators the code was displayed with
35ms
format groups the code the way the CLI prints it
33ms
401 mismatch is a retryable wrong code, and carries the budget
31ms
200 with a token pairs, using the endpoint we actually reached
32ms
401 no-window sends the user to the Mac instead of retyping
31ms
400 malformed is retryable and spends none of the budget
30ms
401 with no body at all is treated as no window
30ms
net.PairingCredentialTest
26 / 26 16ms
a live connection to another endpoint is left alone
1ms
an endpoint that closed us 4001 is not redialled
2ms
with nothing refused the last error stands
a tokenless url persists when nothing better is stored
a refused endpoint is dialled again once we hold a credential for it
paired endpoint inherits its stored credential
token extraction treats empty as absent
default port matches an explicit default port
a refusal is remembered per endpoint, not globally
the advice a camera-less reader is given is one it can actually take
1ms
an explicitly credentialed discovery wins
pairing is still offered to a device riding the USB tunnel
different host or port are different daemons
4ms
a tokenless url for a different daemon still persists
pairing is not offered to a device already on the LAN
1ms
a refusal outranks whatever the last attempt reported
the USB attempt is not preempted while it is still in flight
the LAN endpoint is dialled once nothing else is in flight
unparseable inputs never compare equal
credential is not part of a daemon's identity
a tokenless url may not displace a stored credential for the same daemon
localhost and blank are never persisted
every refused spelling of one daemon stays refused
a credentialed url always persists
1ms
no stored credential leaves the discovered url untouched
a different daemon never inherits another endpoint's credential
1ms
net.ProtocolTest
34 / 34 1.1s
parse state_update with all permission modes
117ms
parse connection connected with sessionId
41ms
parse sessions_list
33ms
PluginCommands selectOption generates valid JSON
29ms
parse timeline_event with fractional timestamps
58ms
parse button_state
29ms
PluginCommands utility with and without value
26ms
parse invalid json returns null
33ms
parse timeline_history
30ms
parse timeline_event upsert
27ms
parse state_update with processing state and tool info
29ms
PluginCommands respond escapes special characters
33ms
parse display_state with dim instruction
27ms
PluginCommands respond generates valid JSON
27ms
parse state_update with permission options
29ms
parse connection disconnected
30ms
parse missing type returns null
26ms
parse deck_slot_map
39ms
parse usage_update with extra usage
40ms
parse state_update with ollama status
42ms
PluginCommands navigateOption
38ms
parse state_update with agent capabilities
27ms
parse unknown type returns null
24ms
parse user_prompt
25ms
BridgeTimelineEntry converts to TimelineEntry
24ms
parse state_update with model catalog
26ms
parse state_update ignores unknown fields
28ms
parse state_update with idle state
30ms
parse display_state sleep and wake
23ms
parse voice_state
26ms
parse encoder_state
26ms
PluginCommands interrupt and escape
25ms
parse usage_update with rate limits
24ms
parse timeline_event
23ms
service.PanelPolicyTransitionManagerTest
3 / 3 1ms
installing the active panel policy is a no-op
1ms
eink to lcd restores old effects before applying and re-evaluating
lcd to eink uses the same coherent transition
state.SessionMetricsTest
8 / 8 9ms
reset clears all metrics
8ms
onMessageReceived updates lastMessageAt
onConnected sets connectedSince
onDisconnected clears connectedSince
clean reconnect after disconnect does not increment
initial state has no connection
1ms
reconnect increments reconnectCount when still connected
onMessageReceived increments count
state.TimelineDisplayScenarioTest
13 / 13 11ms
synthetic response-less turn is hidden completely
3ms
multi-agent dashboard timeline projects meaningful session rows
3ms
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
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
answered turn is not folded
task_end boundary blocks fold
1ms
still-open queued prompts are not folded
queued prompt folds into next turn
same timestamp summaries stay separate by agent and project
state.TimelineStoreTest
63 / 63 36ms
addEntry drops openclaw placeholder with status-only detail
2ms
timelineDisplayGroups hides model_call after model_response in same run
1ms
deriveSubagentActivity ignores ordinary tools and expires orphaned starts
2ms
addEntry allows same type+summary after 5s
1ms
addEntries filters otel noise from bulk replay
2ms
TimelineSessionFilter label prefers project then friendly agent
1ms
clear empties the store
addEntry keeps coalesced codex subagent lifecycle
upsertEntry updates existing entry within 1s tolerance
addEntry drops opencode tool_exec so a tool-heavy turn does not flood
1ms
upsertEntry without taskId falls back to ts-window match
1ms
timelineDisplayGroups keeps in-flight chat_start until completion
groupConsecutive merges a meaningful chat_start with its response into one turn
addEntry drops antigravity tool_exec forward-compat
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
matchesTimelineFilter keeps sessionless OpenClaw rows under gateway
matchesTimelineFilter falls back to project plus agent for legacy sessionless rows
groupConsecutive does not merge tool_request across sessions
groupConsecutive groups same summary within 60s
matchesTimelineFilter canonicalizes observed session prefixes
timelineDisplayGroups keeps independent sessions visible
updateLastOfType modifies the last matching entry
1ms
upsertEntry refuses to insert otel noise via add fallback
addEntries merges and deduplicates
addEntry drops openclaw placeholder with arbitrary future status
upsertEntry preserves existing detail if new detail is null
deriveSubagentActivity pairs starts and completions per parent
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
matchesTimelineFilter with sessionId ignores project fallback
upsertEntry preserves timeline attribution
turn merge looks past interleaved rows from other sessions
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
1ms
timelineDisplayGroups collapses synthetic chat_start once response arrives
groupConsecutive splits different types but folds the turn completion
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
10ms
groupConsecutive does not merge distinct run ids on same session
groupConsecutive folds a whole chat_start-response-end turn into one row
timelineDisplayGroups keeps in-flight start when later completion has distinct run id
1ms
addEntry drops codex tool_exec from normal codex session
addEntry keeps openclaw placeholder summary when detail has content
groupConsecutive requires same summary for other types
addEntry normalizes openclaw cron model_call prompt dump
3ms
matchesTimelineFilter matches by sessionId
updateLastOfType no-op if type not found
turn merge never crosses a newer same-session chat_start
groupConsecutive groups tool_request within 10s
addEntry drops codex tool_exec even when raw is meaningful
upsertEntry merges task_end by taskId beyond the 1s tolerance window
state.TimelineTaskHierarchyTest
39 / 39 26ms
OpenClaw NO_REPLY polling responses are hidden from display projection
1ms
chat_start with a later same-session completion stops rotating
mismatched taskId on task_end does not close it
chat_start older than the age cap stops rotating
summary is redundant with detail for standalone response prefix truncation
8ms
OpenClaw automated polling chat starts are hidden from display projection
stripMarkdownInline drops markers including table syntax
1ms
interrupted reaper closure pair leaves no visible row
summary is not redundant for merged prompt-response turn
1ms
detail redundancy fires when prefix matches summary
1ms
detail redundancy does not fire when content is genuinely new
1ms
same project two sessions are not the same context anymore
closed task_start does not rotate
non task_start entries are never in flight
fresh chat_start rotates via icon-key running
task_start whose task_end (same taskId) appeared is finished
1ms
static rows do not rotate
session_end task boundary is hidden from display projection
stripMarkdownInline preserves non-table pipes
task_start older than the staleness cap is no longer in flight
1ms
task_start without matching task_end is in flight
chat_start superseded by a newer same-session prompt stops rotating
idle_gap task boundary is hidden from display projection
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
1ms
promote informative lead skips generic outcome paragraph
other sessions completions do not stop a running chat_start
iconKey resolves to Task for task entries
judged closure makes a bare header visible with the summary as title
2ms
eval_result and task_end never rotate
stripMarkdownInline handles single-cell table row
1ms
markdown parser parity with shared - basics
3ms
task_start without taskId is never considered in flight
orphan task_start rotates via in-flight predicate
markdown parser code fence is verbatim
eink glyphs are constant 4-char width
closed task renders as a single header row, never a standalone task_end
terrarium.CreatureLayoutTest
3 / 3 7ms
no row overlaps more than ~50 percent across realistic counts
6ms
low counts keep full size and do not shrink
floor-rest clear anchor stays left of the crayfish claws
1ms
terrarium.TerrariumStateTest
10 / 10 299ms
claude processing does not bleed into OpenClaw crayfish on aggregate view
31ms
primary Kiro session routes to the canonical vector-mark creature
27ms
Kiro IDE sibling does not fall back to an octopus
23ms
emitted OpenClaw session shows OpenClaw at rest
23ms
gateway error without an emitted session does not spawn a creature
40ms
gateway error with a live session surfaces sick OpenClaw
53ms
OpenClaw processing routes its own crayfish
33ms
reachable gateway without an emitted session hides OpenClaw and workers
23ms
stuck gatewayConnected without an emitted session still hides OpenClaw
21ms
daemon aggregate keeps OpenClaw crayfish calm while claude works
20ms
terrarium.renderer.EinkAnimationTimingTest
3 / 3 5ms
animation frame advance is elapsed-time based and bounded
3ms
fish simulation scales movement for partial color frames
2ms
color e-ink animation uses video-like cadence
ui.common.ConnectionSetupGuideTest
1 / 1 0ms
disconnected guidance states the host prerequisite and both setup paths
ui.eink.EinkAttentionPanelTest
4 / 4 18ms
non-focused awaiting session hides unavailable live prompt fields
10ms
primary awaiting session is surfaced when not represented by siblings
1ms
featured attention prefers focused awaiting session
7ms
observed AskUserQuestion choices are visible but not actionable
ui.eink.EinkLimitRowTextTest
5 / 5 3ms
no row overruns the card, whatever the label and percentage
2ms
the percentage is never truncated, even by an over-long label
1ms
the common two-character row keeps the full eight-cell gauge
the gauge still reads as a proportion
a maxed scoped cap keeps its digits and pays for them in gauge cells
ui.eink.SessionDisplayOrderingTest
11 / 11 8ms
naturalLabelCompare orders Agent 2 before Agent 10
1ms
compareSessionsForDisplay breaks ties on startedAt ascending (oldest first)
1ms
compareSessionsForDisplay maps terminal tab order onto the deck
compareSessionsForDisplay sorts openclaw before claude-code regardless of project
compareSessionsForDisplay tie-breaks on natural id when startedAt is identical
1ms
agentTypeRank places openclaw first
sessionWeight accepts the documented bounds and clamps beyond them
compareSessionsForDisplay is stable across re-sorts of any input order
1ms
compareSessionsForDisplay orders opposite-sign extreme weights without Int overflow
compareSessionsForDisplay orders by weight ascending before everything else
1ms
sessionWeight collapses null to 0 and preserves finite values
ui.monitor.MonitorLayoutScaleTest
8 / 8 10ms
isTablet is true exactly for the classes with room for side rails
3ms
eink bands grow with the panel and portrait is never shorter than landscape
1ms
side rails cannot overlap at the narrowest width of their size class
5ms
rail fractions leave room for the terrarium between them
size class boundaries match the device profile
every size class resolves to an eink scale
1ms
every size class resolves to a monitor scale
larger classes never render denser than smaller ones
ui.monitor.OpenClawDisplayLinesTest
4 / 4 4ms
empty when no default tagged
4ms
empty catalog yields empty list
keeps only default model when present
empty when default is unavailable
ui.monitor.SubscriptionLineTest
12 / 12 16ms
subscriptionTrailing flags expired for past dates
12ms
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
subscriptionTrailing returns null for blank or null
1ms
null until renders name only
ui.monitor.TimelineDayBreakTest
6 / 6 29ms
index 0 anchors an older buffer but stays silent on today
29ms
separator lands on the first row of the new day
out-of-range index yields no separator
all-today buffer gets no separator at all
a day older than this year carries the year
same instant reads as a different day across zones
util.DeviceProfileHolderTest
1 / 1 30ms
listeners receive genuine changes but not repeated installation
30ms
util.DeviceProfileTest
44 / 44 15ms
onyx mono model is not color eink
3ms
real property values are eink signals
hisense eink reader is detected by model
reader with a generic manufacturer is detected from the brand in its model
1ms
screen below the floor is unsupported
oneplus x is not an eink device despite its onyx codename
false-like property values are not eink signals
hisense lcd phone is not an eink device
1ms
verified hisense eink families retain model detection
1ms
generic models named leaf or poke are not eink devices
1ms
onyx note air 3 c is color eink
short label prefers a named vendor and otherwise names the form factor
crema stays eink and does not require system fixed rotation
1ms
color signal alone establishes eink evidence
onyx boox stays eink
eink override wins over a negative detection
compact screens are supported but flagged as tight
kobo stays eink
1ms
auto override is not reported as overridden
size class boundaries
color signal upgrades an otherwise mono verdict
hisense lcd television model numbers do not match short eink families
build characteristics eink is detected
1ms
false-like color property values remain rejected
television renders with a no-touch caveat
moaan pantone is color eink and requires system fixed rotation
wire kind keeps the two value vocabulary the swift topology maps
1ms
display name does not repeat an embedded brand
1ms
eink override keeps a color panel in color
automotive renders with its own caveat
a touchless tablet is limited even without a tv ui mode
panel override round trips through storage
1ms
hisense q5 is a reflective lcd not an eink panel
huawei nova is not an eink device
1ms
describe names the panel size and evidence
build string only match is flagged as unverified
redmi note is not an eink device
display name degrades gracefully when build fields are empty
unlisted reader with eink system property is detected
watch is unsupported regardless of size
aggregate property check ignores false-like values
1ms
lcd override wins over a positive detection
phone sized lcd is handheld and tablet sized lcd is tablet
unlisted reader with vendor eink api is detected
util.SessionGroupingTest
7 / 7 2ms
short siblings stay separate
groups duplicate #N sessions of the same project
1ms
delimiter extension fuses
exact match groups
long multi-token stems fuse
normalize strips path and trailing #N suffix
clusters same-stem worktrees and keeps singletons flat
1ms
util.TimeFormatUtilsTest
31 / 31 10ms
gaugeBar clamps below 0
2ms
formatCount thousands show K
1ms
formatBytes kilobytes
formatDurationCompact seconds
codex footnote ended window outranks age
1ms
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
codexLimitRows dates an aged reading of a still-live weekly window
2ms
gaugeBar custom width
codex footnote fires only past the threshold
1ms
codex snapshot threshold matches the TypeScript SSOT
windowLabel maps minutes to compact day-hour-minute labels
formatBytes gigabytes
codexLimitRows maps primary and secondary windows with agent tag
codexLimitRows skips windows with null usedPercent
formatUptime zero returns 0 colon 00
codexLimitRows returns empty when limits null
formatCount millions show M
1ms
codex snapshot age ignores missing and malformed stamps
formatDurationCompact minutes
1ms
codexLimitRows leaves a legacy producer without capturedAt unchanged
gaugeBar 100 percent is all filled
codex snapshot age label rounds down
ESP32 Firmware Verification NOT RUN
Robot Framework · physical hardware behavior when an HW-tagged run is supplied · 0 suites · 0 scenarios · 0 tests · 0 boards
No Robot Framework test results available.
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
2/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 1/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
1/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 1/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 · 26,257 lines tracked
Lines ≥17%: 55.1%
Functions ≥15%: 54.2%
Branches ≥14%: 49.9%
Statements ≥16%: 54.0%
bridge
53% Lines
52% Stmts
52% Funcs
47% Branch
11453/21732 lines covered
plugin
51% Lines
49% Stmts
47% Funcs
48% Branch
1005/1972 lines covered
shared
76% Lines
74% Stmts
75% Funcs
70% Branch
1562/2066 lines covered
hooks
94% Lines
92% Stmts
96% Funcs
88% Branch
389/414 lines covered
File Stmts Branch Funcs Lines
bridge/src/check-deps.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/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/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/voice.ts 0% 0% 0% 0%
bridge/src/apme/types.ts 0% 0% 0% 0%
bridge/src/idotmatrix/idotmatrix-discover.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/wake-word.ts 2% 0% 0% 2%
bridge/src/apme/index.ts 2% 0% 0% 2%
bridge/src/voice-assistant.ts 2% 0% 0% 2%
bridge/src/pixoo/pixoo-font.ts 3% 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/adb-reverse.ts 5% 6% 9% 5%
bridge/src/modules/index.ts 6% 0% 33% 6%
bridge/src/tui/dashboard.ts 5% 11% 3% 6%
bridge/src/wifi-config.ts 6% 0% 0% 7%
bridge/src/timebox/timebox-daemon-sync.ts 6% 0% 0% 7%
bridge/src/apme/outcome.ts 8% 2% 8% 8%
bridge/src/modules/idotmatrix-module.ts 6% 0% 0% 8%
bridge/src/modules/timebox-module.ts 6% 0% 0% 8%
bridge/src/modules/pixoo-module.ts 6% 0% 0% 8%
bridge/src/cli.ts 8% 4% 11% 9%
bridge/src/daemon-server.ts 9% 7% 11% 9%
bridge/src/pixoo/pixoo-client.ts 10% 0% 0% 10%
bridge/src/timebox/timebox-settings.ts 8% 6% 8% 10%
bridge/src/pixoo/pixoo-bridge.ts 12% 4% 4% 12%
bridge/src/pixoo/pixoo-settings.ts 11% 0% 10% 12%
bridge/src/idotmatrix/idotmatrix-settings.ts 18% 33% 17% 15%
bridge/src/idotmatrix/idotmatrix-daemon-sync.ts 14% 0% 0% 16%
bridge/src/gateway-probe.ts 12% 0% 0% 16%
bridge/src/review-runner.ts 16% 22% 21% 17%
bridge/src/modules/serial-module.ts 17% 0% 0% 18%
bridge/src/modules/adb-module.ts 17% 0% 0% 19%
bridge/src/session-transcript-timeline.ts 24% 16% 14% 23%
bridge/src/foundation-models-helper.ts 29% 23% 29% 28%
bridge/src/display-monitor.ts 27% 30% 28% 28%
bridge/src/observed-inject.ts 31% 18% 50% 30%
bridge/src/pixoo/pixoo-sprites.ts 29% 15% 43% 31%
bridge/src/esp32-serial.ts 33% 35% 24% 34%
bridge/src/session-activity.ts 29% 30% 42% 34%
bridge/src/logger.ts 38% 21% 62% 38%
bridge/src/usage-api.ts 39% 35% 61% 40%
bridge/src/modules/broadcast-module.ts 43% 100% 25% 43%
bridge/src/modules/mdns-module.ts 43% 100% 25% 43%
bridge/src/usage-tracker.ts 44% 55% 23% 44%
bridge/src/opencode-client.ts 40% 38% 57% 44%
bridge/src/bridge-core.ts 43% 43% 30% 45%
bridge/src/ble-sync-spawn.ts 45% 33% 41% 46%
bridge/src/model-catalog.ts 40% 19% 40% 47%
bridge/src/pixoo/pixoo-camera.ts 51% 37% 50% 51%
bridge/src/adapters/opencode-adapter.ts 49% 38% 41% 53%
bridge/src/windows-service.ts 53% 78% 50% 54%
bridge/src/hook-server.ts 54% 32% 54% 56%
bridge/src/codex-auth.ts 61% 41% 40% 60%
bridge/src/session-focus-relay.ts 62% 61% 56% 62%
bridge/src/apme/antigravity-transcript.ts 63% 74% 33% 63%
bridge/src/kiro-session.ts 62% 61% 48% 65%
bridge/src/ws-server.ts 65% 58% 58% 66%
bridge/src/passive-observer.ts 62% 59% 66% 66%
bridge/src/adapters/openclaw.ts 66% 56% 69% 69%
bridge/src/tui/renderer.ts 69% 55% 92% 71%
bridge/src/apme/classifier.ts 65% 66% 74% 71%
bridge/src/adapters/index.ts 71% 67% 100% 71%
bridge/src/adapters/claude-code.ts 72% 40% 50% 72%
bridge/src/mdns.ts 71% 53% 83% 73%
bridge/src/python-ble-runtime.ts 72% 64% 87% 73%
bridge/src/apme/recommend.ts 71% 39% 67% 74%
bridge/src/tui/terrarium.ts 72% 56% 78% 74%
bridge/src/session-registry.ts 72% 75% 59% 75%
bridge/src/apme/runner.ts 69% 59% 65% 75%
bridge/src/pty-manager.ts 76% 51% 73% 75%
bridge/src/tui/ansi.ts 74% 49% 84% 75%
bridge/src/apme/http.ts 74% 66% 88% 76%
bridge/src/linux-service.ts 73% 100% 72% 76%
bridge/src/pixoo/pixoo-renderer.ts 78% 66% 82% 79%
bridge/src/codex-rate-limits-live.ts 80% 74% 67% 80%
bridge/src/mlx-probe.ts 76% 38% 25% 81%
bridge/src/adapters/monitor.ts 81% 60% 87% 81%
bridge/src/pixoo/pixoo-discover.ts 74% 63% 75% 82%
bridge/src/adapters/pty-adapter.ts 82% 81% 65% 82%
bridge/src/kiro-diagnostics.ts 85% 64% 87% 84%
bridge/src/session-timeline-relay.ts 80% 62% 71% 84%
bridge/src/daemon-takeover.ts 84% 77% 100% 84%
bridge/src/apme/store.ts 72% 73% 88% 84%
bridge/src/state-machine.ts 84% 68% 87% 85%
bridge/src/apme/adapters/codex-hook.ts 79% 60% 100% 85%
bridge/src/apme/claude-transcript-reader.ts 82% 77% 86% 85%
bridge/src/kiro-timeline-feed.ts 84% 65% 86% 86%
bridge/src/broadcast.ts 79% 56% 56% 87%
bridge/src/device-photo.ts 88% 87% 87% 88%
bridge/src/apme/collector.ts 85% 73% 89% 88%
bridge/src/glance-frame.ts 89% 80% 84% 88%
bridge/src/apme/sample-to-timeline.ts 84% 67% 100% 90%
bridge/src/pocket-autonomy.ts 86% 66% 89% 91%
bridge/src/daemon-ws-client.ts 85% 72% 81% 91%
bridge/src/usage-event.ts 92% 86% 100% 91%
bridge/src/device-voice.ts 89% 74% 83% 92%
bridge/src/session-aggregator.ts 91% 75% 100% 92%
bridge/src/adapters/codex-cli.ts 92% 100% 88% 92%
bridge/src/device-voice-reply.ts 85% 76% 65% 92%
bridge/src/network-posture.ts 93% 88% 100% 92%
bridge/src/mdns-discover.ts 90% 74% 100% 93%
bridge/src/codex-rollout-response.ts 89% 86% 89% 93%
bridge/src/codex-output-parser.ts 90% 84% 95% 94%
bridge/src/output-parser.ts 90% 84% 100% 94%
bridge/src/apme/adapters/timeline.ts 95% 76% 100% 94%
bridge/src/opencode-steering.ts 95% 87% 100% 94%
bridge/src/peripheral-mapping.ts 96% 95% 100% 94%
bridge/src/pixoo/micro-glyphs.ts 92% 86% 100% 94%
bridge/src/auth.ts 92% 88% 100% 95%
bridge/src/fallback-task-timeline.ts 95% 82% 83% 95%
bridge/src/apme/classify-turn.ts 91% 80% 100% 95%
bridge/src/apme/adapters/codex-turn-manager.ts 90% 79% 100% 95%
bridge/src/kiro-transcript-timeline.ts 88% 80% 100% 95%
bridge/src/claude-turn-watchdog.ts 93% 91% 88% 95%
bridge/src/utils/project-name.ts 93% 85% 100% 96%
bridge/src/codex-otel.ts 89% 84% 100% 96%
bridge/src/subagent-timeline.ts 95% 82% 100% 96%
bridge/src/ask-gate.ts 97% 97% 100% 96%
bridge/src/pairing-window.ts 95% 89% 88% 96%
bridge/src/observed-steering.ts 93% 87% 96% 97%
bridge/src/codex-rate-limits.ts 93% 84% 100% 97%
bridge/src/calendar.ts 95% 84% 96% 97%
bridge/src/session-push-channel.ts 97% 82% 50% 97%
bridge/src/timeline-summarizer.ts 92% 54% 75% 97%
bridge/src/observed-turn-watchdogs.ts 96% 75% 100% 97%
bridge/src/awaiting-overlay.ts 92% 85% 100% 98%
bridge/src/permission-resolver.ts 94% 70% 91% 98%
bridge/src/apme/adapters/opencode-hook.ts 98% 84% 100% 98%
bridge/src/hook-codex-sessions.ts 93% 87% 83% 98%
bridge/src/apme/adapters/openclaw-hook.ts 96% 82% 100% 98%
bridge/src/timeline-store.ts 96% 85% 100% 99%
bridge/src/weather.ts 95% 86% 92% 99%
bridge/src/card-feed.ts 92% 83% 100% 99%
bridge/src/ble-sync-status.ts 100% 91% 100% 100%
bridge/src/card-modules.ts 100% 90% 100% 100%
bridge/src/claude-interrupt-marker.ts 95% 92% 100% 100%
bridge/src/claude-permission-rules.ts 93% 80% 100% 100%
bridge/src/codex-hook-silence.ts 94% 79% 100% 100%
bridge/src/daemon-port.ts 100% 88% 100% 100%
bridge/src/daemon-settings.ts 95% 75% 100% 100%
bridge/src/display-dim.ts 95% 69% 100% 100%
bridge/src/http-auth-gate.ts 100% 93% 100% 100%
bridge/src/openclaw-session.ts 100% 100% 100% 100%
bridge/src/remote-sessions.ts 100% 100% 100% 100%
bridge/src/session-id-resolve.ts 100% 93% 100% 100%
bridge/src/apme/dashboard-html.ts 100% 100% 100% 100%
bridge/src/apme/graph.ts 95% 83% 100% 100%
bridge/src/apme/judge-detect.ts 98% 85% 100% 100%
bridge/src/apme/pareto.ts 100% 81% 100% 100%
bridge/src/apme/settings.ts 97% 86% 100% 100%
bridge/src/apme/adapters/claude-hook.ts 100% 77% 100% 100%
bridge/src/apme/scorers/index.ts 98% 73% 100% 100%
bridge/src/modules/types.ts 100% 100% 100% 100%
bridge/src/pixoo/official-dot-glyphs.generated.ts 100% 100% 100% 100%
bridge/src/tui/gauge.ts 96% 93% 100% 100%
bridge/src/utils/redact-secrets.ts 100% 50% 100% 100%
hooks/src/install.ts 89% 87% 93% 91%
hooks/src/opencode-install.ts 93% 82% 100% 93%
hooks/src/codex-install.ts 91% 82% 96% 93%
hooks/src/codex-mini-toml.ts 98% 94% 100% 100%
plugin-ulanzi/src/reconnect-supervisor.ts 85% 68% 75% 89%
plugin/src/agent-link.ts 0% 0% 0% 0%
plugin/src/display-dim.ts 0% 0% 0% 0%
plugin/src/encoder-registry.ts 0% 100% 0% 0%
plugin/src/plugin.ts 0% 0% 0% 0%
plugin/src/actions/iterm-dial.ts 0% 0% 0% 0%
plugin/src/actions/launcher-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/usage-limit-button.ts 0% 0% 0% 0%
plugin/src/actions/utility-dial.ts 0% 0% 0% 0%
plugin/src/renderers/agent-logos.ts 0% 0% 0% 0%
plugin/src/renderers/button-renderer.ts 0% 100% 0% 0%
plugin/src/renderers/session-slot-renderer.ts 0% 0% 0% 0%
plugin/src/system/darwin.ts 0% 0% 0% 0%
plugin/src/system/types.ts 0% 0% 0% 0%
plugin/src/bridge-client.ts 55% 35% 67% 59%
plugin/src/system/index.ts 65% 100% 50% 62%
plugin/src/log.ts 59% 50% 33% 67%
plugin/src/system/win32.ts 63% 80% 62% 67%
plugin/src/renderers/display-tile.ts 77% 53% 100% 80%
plugin/src/session-slot-manager.ts 85% 78% 89% 86%
plugin/src/utility-modes/usage.ts 83% 81% 87% 87%
plugin/src/focused-detail-state.ts 91% 76% 86% 90%
plugin/src/connection-manager.ts 92% 88% 82% 95%
plugin/src/system/win32-volume.ts 94% 81% 92% 97%
plugin/src/renderers/usage-gauge.ts 96% 84% 94% 98%
plugin/src/device-profile.ts 100% 100% 100% 100%
plugin/src/launch-targets.ts 100% 93% 100% 100%
plugin/src/renderers/launcher-renderer.ts 100% 50% 100% 100%
plugin/src/renderers/usage-dial-renderer.ts 90% 47% 100% 100%
plugin/src/renderers/utility-renderer.ts 100% 75% 100% 100%
shared/src/adapter.ts 0% 100% 100% 0%
shared/src/apme-graph.ts 0% 100% 0% 0%
shared/src/command-builders.ts 0% 100% 0% 0%
shared/src/eval-schema.ts 0% 0% 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/sample.ts 0% 0% 0% 0%
shared/src/telemetry-envelope.ts 0% 0% 0% 0%
shared/src/timeline-label.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/state-colors.ts 38% 50% 67% 42%
shared/src/svg-renderers/agent-logos.ts 50% 39% 58% 52%
shared/src/svg-renderers/text-utils.ts 55% 47% 86% 60%
shared/src/format-utils.ts 64% 66% 71% 64%
shared/src/svg-renderers/session-slot-renderer.ts 64% 59% 74% 64%
shared/src/d200h-layout.ts 75% 74% 84% 75%
shared/src/timeline-summarizer.ts 73% 63% 57% 76%
shared/src/timeline.ts 79% 74% 100% 86%
shared/src/timeline-icons.ts 86% 79% 80% 89%
shared/src/subagent-activity.ts 90% 77% 86% 93%
shared/src/session-utils.ts 95% 86% 100% 96%
shared/src/pricing.ts 91% 77% 88% 96%
shared/src/creature-layout.ts 94% 89% 86% 98%
shared/src/connection-status.ts 100% 100% 100% 100%
shared/src/design-tokens.ts 100% 100% 100% 100%
shared/src/idotmatrix-identity.ts 100% 94% 100% 100%
shared/src/llm-settings.ts 100% 98% 100% 100%
shared/src/mdns-identity.ts 100% 100% 100% 100%
shared/src/model-provider.ts 100% 92% 100% 100%
shared/src/openclaw-approval.ts 97% 93% 100% 100%
shared/src/pairing-code.ts 98% 96% 100% 100%
shared/src/protocol.ts 100% 100% 100% 100%
shared/src/states.ts 100% 100% 100% 100%
shared/src/terrarium-rules.ts 100% 100% 100% 100%
shared/src/timeline-markdown.ts 99% 92% 100% 100%
shared/src/timeline-task-display.ts 100% 97% 100% 100%
shared/src/voice-ptt.ts 100% 100% 100% 100%
shared/src/voice-reply-digest.ts 97% 90% 100% 100%