The ai-plan-checker.ts was passing the prompt directly as a shell argument, which can cause E2BIG errors when the terminal buffer is large (8KB+). This fix applies the same temp file approach already used in ai-idle-checker.ts: - Write prompt to a temp file instead of passing as shell argument - Pipe the file to claude via stdin: `cat prompt.txt | claude -p ...` - Clean up prompt file after check completes Also fixes a race condition in the cancel() method of both AI checkers where the poll timer could fire between setting checkCancelled and clearing timers. Now timers are cleared before resolving the promise to prevent this race. Includes test utilities and analysis documents for the respawn controller created by other agents: - test/respawn-test-utils.ts - MockSession, MockAiIdleChecker utilities - test/respawn-analysis.md - Code analysis and issue identification - test/respawn-scenarios.md - Test scenario documentation - test/respawn-test-plan.md - Testing architecture documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
32 KiB
Respawn Controller Test Scenarios
This document identifies edge cases and scenarios not currently covered by the existing test suite in test/respawn-controller.test.ts. These scenarios are designed to find gaps in test coverage and ensure robust behavior.
Table of Contents
- State Transition Scenarios
- AI Idle Checker Integration Scenarios
- AI Plan Checker Integration Scenarios
- Timeout and Cooldown Scenarios
- Error Recovery Scenarios
- Concurrent Operation Scenarios
- Configuration Change Scenarios
- Buffer and Memory Scenarios
- Edge Cases in Pattern Detection
- Event Emission and Listener Scenarios
State Transition Scenarios
STS-001: Full Cycle with All Steps Enabled
Description: Complete respawn cycle traversing all states when sendClear, sendInit, and kickstartPrompt are all enabled.
Initial State: watching with all config options enabled
Actions:
- Start controller with
sendClear: true,sendInit: true,kickstartPrompt: 'continue' - Simulate completion message
- Wait for confirmation
- Simulate completion for each step without triggering work after /init
Expected Behavior:
- States visited in order: watching -> confirming_idle -> ai_checking -> sending_update -> waiting_update -> sending_clear -> waiting_clear -> sending_init -> waiting_init -> monitoring_init -> sending_kickstart -> waiting_kickstart -> watching
- All stepSent/stepCompleted events emitted
- Cycle count increments
Priority: HIGH
STS-002: Cycle Skipping Clear Step
Description: Respawn cycle when sendClear is disabled.
Initial State: watching with sendClear: false, sendInit: true
Actions:
- Trigger idle detection
- Complete update step
Expected Behavior:
- Should skip directly from waiting_update to sending_init
- No 'clear' step events emitted
Priority: MEDIUM
STS-003: Cycle Skipping Init Step
Description: Respawn cycle when sendInit is disabled.
Initial State: watching with sendClear: true, sendInit: false
Actions:
- Trigger idle detection
- Complete update step
- Complete clear step
Expected Behavior:
- Should complete cycle after clear
- No 'init' step events emitted
- Should not enter monitoring_init state
Priority: MEDIUM
STS-004: Cycle with Neither Clear nor Init
Description: Respawn cycle when both sendClear and sendInit are disabled.
Initial State: watching with sendClear: false, sendInit: false
Actions:
- Trigger idle detection
- Complete update step
Expected Behavior:
- Cycle completes immediately after update
- Only update step events emitted
Priority: MEDIUM
STS-005: Work Triggered During monitoring_init
Description: When /init actually triggers Claude to start working.
Initial State: monitoring_init with kickstartPrompt configured
Actions:
- Reach monitoring_init state
- Simulate working patterns (e.g., "Thinking...")
Expected Behavior:
- Should emit stepCompleted for 'init'
- Should NOT enter sending_kickstart
- Should complete cycle and return to watching
- Log message: "/init triggered work, skipping kickstart"
Priority: HIGH
STS-006: State Transition During Step Timer
Description: Stopping controller while step delay timer is pending.
Initial State: sending_update (during interStepDelayMs wait)
Actions:
- Start controller and trigger idle
- While in sending_update (during delay), call stop()
Expected Behavior:
- Step timer should be cleared
- No stepSent event emitted
- State transitions to stopped cleanly
Priority: MEDIUM
STS-007: Clear Fallback Timer Trigger
Description: /clear step completes via fallback timer when no prompt detected.
Initial State: waiting_clear
Actions:
- Send /clear command
- Do NOT simulate prompt detection
- Wait for CLEAR_FALLBACK_TIMEOUT_MS (10s)
Expected Behavior:
- Fallback timer fires
- Logs "clear fallback: proceeding to /init"
- Proceeds to sendInit (or completeCycle if sendInit false)
- stepCompleted event emitted for 'clear'
Priority: MEDIUM
STS-008: Clear Fallback Timer Cancelled by Prompt
Description: Clear fallback timer is cancelled when prompt is detected.
Initial State: waiting_clear
Actions:
- Send /clear command
- Simulate prompt detection before fallback timeout
Expected Behavior:
- Fallback timer cancelled with reason "prompt detected"
- timerCancelled event emitted for 'clear-fallback'
- Normal flow continues
Priority: MEDIUM
STS-009: Multiple Rapid State Transitions
Description: Rapid cycling through multiple states without settling.
Initial State: watching
Actions:
- Simulate completion message
- Before confirmation completes, simulate working
- Immediately after, simulate completion again
- Repeat several times rapidly
Expected Behavior:
- Controller handles transitions gracefully
- No duplicate state entries
- Timers properly cleaned up
- No memory leaks from orphaned timers
Priority: HIGH
STS-010: Resume from Non-Watching State
Description: Calling resume() when in a state other than watching.
Initial State: sending_update or any non-watching state
Actions:
- Pause controller
- Call resume()
Expected Behavior:
- Should remain in current state
- Should not call checkIdleAndMaybeStart
- Only watching state triggers idle check on resume
Priority: LOW
AI Idle Checker Integration Scenarios
AIC-001: AI Checker Returns IDLE Verdict
Description: AI idle check completes successfully with IDLE verdict.
Initial State: ai_checking
Actions:
- Trigger AI check via completion message + silence
- Mock AI checker to return IDLE
Expected Behavior:
- aiCheckCompleted event emitted with IDLE verdict
- onIdleConfirmed called
- Respawn cycle begins
- No cooldown started
Priority: HIGH
AIC-002: AI Checker Returns WORKING Verdict
Description: AI idle check completes with WORKING verdict.
Initial State: ai_checking
Actions:
- Trigger AI check
- Mock AI checker to return WORKING
Expected Behavior:
- aiCheckCompleted event emitted
- State returns to watching
- Cooldown started (aiIdleCheckCooldownMs)
- aiCheckCooldown event emitted
- No respawn cycle started
Priority: HIGH
AIC-003: AI Checker Returns ERROR Verdict
Description: AI idle check fails with ERROR verdict.
Initial State: ai_checking
Actions:
- Trigger AI check
- Mock AI checker to return ERROR
Expected Behavior:
- aiCheckFailed event emitted
- State returns to watching
- consecutiveErrors incremented
- Pre-filter and no-output timers restarted
Priority: HIGH
AIC-004: AI Checker Throws Exception
Description: AI idle check throws an exception during execution.
Initial State: ai_checking
Actions:
- Trigger AI check
- Mock AI checker to throw Error
Expected Behavior:
- Exception caught
- aiCheckFailed event emitted
- State returns to watching
- Controller remains stable
Priority: HIGH
AIC-005: AI Checker Cancelled Mid-Check
Description: AI check cancelled by new working patterns.
Initial State: ai_checking
Actions:
- Start AI check
- Before completion, simulate working pattern
Expected Behavior:
- AI check cancelled
- Log: "Working patterns detected during AI check, cancelling"
- State returns to watching
- AI check result ignored when it arrives
Priority: HIGH
AIC-006: AI Checker Cancelled by Substantial Output
Description: AI check cancelled when substantial (>2 chars) output arrives.
Initial State: ai_checking
Actions:
- Start AI check
- Simulate output longer than 2 characters (after ANSI stripping)
Expected Behavior:
- AI check cancelled
- Log includes "Substantial output during AI check"
- State returns to watching
Priority: MEDIUM
AIC-007: AI Checker on Cooldown - Check Skipped
Description: AI check attempt while on cooldown from previous WORKING verdict.
Initial State: watching with AI checker on cooldown
Actions:
- Get WORKING verdict (starts cooldown)
- Immediately trigger another pre-filter pass
Expected Behavior:
- AI check not started
- Log: "AI check on cooldown (Xs remaining), waiting..."
- Controller stays in watching state
Priority: HIGH
AIC-008: AI Checker Cooldown Expires
Description: Controller behavior when AI checker cooldown expires.
Initial State: watching with AI checker on cooldown
Actions:
- Wait for cooldown to expire
- Check that pre-filter timer is restarted
Expected Behavior:
- aiCheckCooldown event emitted (false, null)
- Pre-filter timer restarted
- Next idle signal can trigger AI check
Priority: MEDIUM
AIC-009: AI Checker Disabled After Max Consecutive Errors
Description: AI checker auto-disables after too many errors.
Initial State: watching with AI check enabled
Actions:
- Cause maxConsecutiveErrors (3) failures
- Attempt another idle detection
Expected Behavior:
- AI checker status becomes 'disabled'
- disabled event emitted with reason
- Falls back to noOutputTimeoutMs for detection
- Log: "AI check unavailable (disabled)"
Priority: HIGH
AIC-010: AI Checker Re-enabled via Config Update
Description: Re-enabling AI checker after it was disabled.
Initial State: AI checker disabled
Actions:
- Call updateConfig({ aiIdleCheckEnabled: true })
Expected Behavior:
- AI checker status becomes 'ready'
- disabledReason cleared
- Next idle detection can use AI check
Priority: MEDIUM
AIC-011: AI Check Triggered via No-Output Fallback
Description: AI check triggered by noOutputTimeoutMs when no output at all.
Initial State: watching with no output received
Actions:
- Start controller
- Wait for noOutputTimeoutMs without any terminal output
Expected Behavior:
- AI check triggered via no-output fallback path
- aiCheckStarted event emitted
- Log: "No-output fallback: Xs silence"
Priority: MEDIUM
AIC-012: AI Check via Pre-Filter Path (No Completion Message)
Description: AI check triggered by pre-filter timer without completion message.
Initial State: watching with output received but no completion message
Actions:
- Receive some output (sets lastOutputTime)
- Wait for completionConfirmMs of silence
- Wait for working patterns to be absent for 3s
- Wait for tokens to be stable
Expected Behavior:
- Pre-filter passes
- AI check started
- Works even without completion message detection
Priority: MEDIUM
AIC-013: State Change During AI Check - Result Ignored
Description: AI check result arrives after state has changed.
Initial State: ai_checking
Actions:
- Start AI check
- Stop controller before result arrives
- AI check completes
Expected Behavior:
- Result ignored
- Log: "AI check result ignored (state is now stopped)"
- No state transition attempted
Priority: MEDIUM
AI Plan Checker Integration Scenarios
APC-001: Plan Check Returns PLAN_MODE
Description: AI plan check confirms plan mode, triggers auto-accept.
Initial State: watching with plan mode UI in buffer
Actions:
- Simulate plan mode output (numbered list + selector)
- Wait for autoAcceptDelayMs
- Mock plan checker to return PLAN_MODE
Expected Behavior:
- planCheckCompleted event emitted
- Enter sent via writeViaScreen
- autoAcceptSent event emitted
- hasReceivedOutput reset to false
Priority: HIGH
APC-002: Plan Check Returns NOT_PLAN_MODE
Description: AI plan check determines not plan mode.
Initial State: watching with ambiguous output
Actions:
- Simulate output that passes pre-filter
- Mock plan checker to return NOT_PLAN_MODE
Expected Behavior:
- planCheckCompleted event emitted
- No Enter sent
- Cooldown started (aiPlanCheckCooldownMs)
Priority: HIGH
APC-003: Plan Check Already Checking
Description: Plan check attempt while already checking.
Initial State: Plan checker status = 'checking'
Actions:
- Start a plan check
- Trigger another auto-accept attempt before first completes
Expected Behavior:
- Second check skipped
- Log: "plan check already in progress"
- Only one check runs
Priority: MEDIUM
APC-004: Plan Check Cancelled by New Output
Description: New output during plan check cancels it.
Initial State: Plan check running
Actions:
- Start plan check
- Simulate new terminal output
Expected Behavior:
- Plan check cancelled
- Log: "New output during plan check, cancelling (stale)"
- Result discarded
Priority: HIGH
APC-005: Plan Check Result Stale (Output During Check)
Description: Plan check completes but output arrived during check.
Initial State: Plan check running
Actions:
- Start plan check
- Record planCheckStartTime
- Simulate output (updates lastOutputTime)
- Plan check returns PLAN_MODE
Expected Behavior:
- Result discarded (lastOutputTime > planCheckStartTime)
- Log: "Result discarded (output arrived during check)"
- No Enter sent
Priority: HIGH
APC-006: Plan Check Result When State Changed
Description: Plan check returns PLAN_MODE but state is no longer watching.
Initial State: Plan check running
Actions:
- Start plan check
- Trigger respawn cycle (state changes to sending_update)
- Plan check returns PLAN_MODE
Expected Behavior:
- Result not acted upon
- Log includes "state is X, not sending Enter"
- No auto-accept
Priority: MEDIUM
APC-007: Pre-Filter Blocks - No Numbered Options
Description: Pre-filter rejects output without numbered options.
Initial State: watching
Actions:
- Simulate output without numbered list pattern
- Wait for autoAcceptDelayMs
Expected Behavior:
- Pre-filter fails (PLAN_MODE_OPTION_PATTERN not matched)
- Log: "pre-filter did not match plan mode patterns"
- No plan check started
Priority: MEDIUM
APC-008: Pre-Filter Blocks - No Selector Arrow
Description: Pre-filter rejects output without selector indicator.
Initial State: watching
Actions:
- Simulate numbered list without selector (no ">" or arrow)
- Wait for autoAcceptDelayMs
Expected Behavior:
- Pre-filter fails (PLAN_MODE_SELECTOR_PATTERN not matched)
- No plan check started
Priority: MEDIUM
APC-009: Pre-Filter Blocks - Working Pattern After Selector
Description: Pre-filter rejects when working pattern appears after selector.
Initial State: watching
Actions:
- Simulate: "1. Yes\n> 1.\nThinking..."
- Wait for autoAcceptDelayMs
Expected Behavior:
- Pre-filter fails (working pattern after selector)
- No plan check started
Priority: MEDIUM
APC-010: Pre-Filter Passes - Working Pattern Before Selector
Description: Pre-filter allows working patterns if they appear before the selector.
Initial State: watching with AI plan check disabled
Actions:
- Simulate: "Thinking...\nDone.\n> 1. Yes\n 2. No"
- Wait for autoAcceptDelayMs
Expected Behavior:
- Pre-filter passes (working pattern is before selector)
- Auto-accept triggered (since AI plan check disabled)
Priority: MEDIUM
APC-011: Plan Check on Cooldown
Description: Plan check skipped when on cooldown.
Initial State: Plan checker on cooldown
Actions:
- Get NOT_PLAN_MODE verdict (starts cooldown)
- Simulate plan mode output
- Wait for autoAcceptDelayMs
Expected Behavior:
- Plan check skipped
- Log: "plan checker on cooldown (Xs remaining)"
- No auto-accept
Priority: MEDIUM
Timeout and Cooldown Scenarios
TC-001: Step Confirmation Timer Interrupted by Working
Description: Step confirmation timer cancelled by working patterns.
Initial State: waiting_update with step confirm timer running
Actions:
- Simulate completion message in waiting_update
- Before confirmation timer fires, simulate working pattern
Expected Behavior:
- Step confirm timer cancelled
- Log: "Step confirmation cancelled (working detected)"
- Remains in waiting_update, waiting for real completion
Priority: HIGH
TC-002: Completion Confirm Timer Interrupted by Output
Description: Confirmation timer restart when output arrives during confirmation.
Initial State: confirming_idle with timer running
Actions:
- Detect completion message
- Timer fires but lastOutputTime changed
Expected Behavior:
- Timer restarts instead of confirming
- Log: "Output during confirmation, resetting"
- State remains confirming_idle
Priority: MEDIUM
TC-003: Multiple Cooldowns Active Simultaneously
Description: Both AI idle checker and plan checker on cooldown.
Initial State: Both checkers on cooldown
Actions:
- Trigger WORKING verdict on idle checker
- Trigger NOT_PLAN_MODE on plan checker
- Try to trigger both checks
Expected Behavior:
- Both checks skipped
- Controller falls back appropriately
- Cooldowns expire independently
Priority: MEDIUM
TC-004: Zero-Duration Timers
Description: Configuration with zero-duration timeouts.
Initial State: watching with completionConfirmMs: 0, interStepDelayMs: 0
Actions:
- Trigger completion message
- Complete full cycle
Expected Behavior:
- Timers fire immediately (or within next event loop)
- Cycle completes without hanging
- No errors from zero-duration setTimeout
Priority: LOW
TC-005: Very Long Timeout Values
Description: Configuration with extremely long timeouts.
Initial State: watching with noOutputTimeoutMs: 3600000 (1 hour)
Actions:
- Start controller
- Stop before timeout
Expected Behavior:
- Timer properly cleared on stop
- No dangling timers
- Memory not leaked
Priority: LOW
TC-006: Timer Tracking Accuracy
Description: Active timer info reflects actual remaining time.
Initial State: Timer running
Actions:
- Start a tracked timer (e.g., completion-confirm)
- Call getActiveTimers() at various intervals
- Check remainingMs decreases appropriately
Expected Behavior:
- remainingMs decreases over time
- Never negative
- Removed from list after firing
Priority: LOW
Error Recovery Scenarios
ER-001: Session Event Handler Throws
Description: Exception thrown in terminal data handler.
Initial State: watching
Actions:
- Cause handleTerminalData to throw (via malformed input)
- Continue sending normal output
Expected Behavior:
- Controller should not crash
- Should handle exception gracefully
- Should continue processing subsequent events
Priority: HIGH
ER-002: writeViaScreen Fails
Description: Writing to session fails during step send.
Initial State: sending_update
Actions:
- Mock writeViaScreen to return false or throw
- Let step delay timer fire
Expected Behavior:
- Error should be caught
- Controller should emit error event
- Should not hang in sending state indefinitely
Priority: MEDIUM
ER-003: Recovery After Partial Cycle Failure
Description: Controller recovers after failing mid-cycle.
Initial State: waiting_clear when error occurs
Actions:
- Simulate error during waiting_clear
- Controller returns to watching or stopped
- Try to start new cycle
Expected Behavior:
- Clean state for new cycle
- No leftover timers or state
- New cycle works normally
Priority: MEDIUM
ER-004: AI Checker Process Spawn Failure
Description: Screen process fails to spawn for AI check.
Initial State: ai_checking
Actions:
- Trigger AI check
- Mock screen spawn to fail
Expected Behavior:
- Error caught
- aiCheckFailed event emitted
- consecutiveErrors incremented
- Falls back gracefully
Priority: MEDIUM
ER-005: Temp File Cleanup Failure
Description: Temp file deletion fails in AI checker cleanup.
Initial State: AI check completing
Actions:
- Complete AI check
- Mock unlink to throw
Expected Behavior:
- Exception caught (best effort cleanup)
- Check still completes
- No crash
Priority: LOW
Concurrent Operation Scenarios
CO-001: Start Called While Stopping
Description: Calling start() immediately after stop().
Initial State: Transitioning from running to stopped
Actions:
- Call stop()
- Immediately call start()
Expected Behavior:
- Clean restart
- No duplicate listeners
- Single watching state
Priority: MEDIUM
CO-002: Multiple Terminal Events in Same Tick
Description: Multiple terminal events processed synchronously.
Initial State: watching
Actions:
- Emit multiple 'terminal' events without yielding
- Check state consistency
Expected Behavior:
- All events processed in order
- State remains consistent
- No race conditions in timer management
Priority: HIGH
CO-003: Config Update During AI Check
Description: Updating AI config while check is in progress.
Initial State: ai_checking
Actions:
- Start AI check
- Call updateConfig({ aiIdleCheckEnabled: false })
- AI check completes
Expected Behavior:
- Pending check completes
- Future checks use new config
- No crash
Priority: LOW
CO-004: Pause During AI Check
Description: Pausing controller while AI check is running.
Initial State: ai_checking
Actions:
- Start AI check
- Call pause()
- AI check completes
Expected Behavior:
- Timers cleared by pause
- AI check result may arrive but timers won't fire
- Resume can restart monitoring
Priority: LOW
CO-005: Buffer Append During Trim
Description: New data arrives while buffer is being trimmed.
Initial State: Buffer near MAX_RESPAWN_BUFFER_SIZE
Actions:
- Fill buffer to trigger trim
- Simultaneously append more data
Expected Behavior:
- Buffer stays within limits
- No data corruption
- Append operation completes
Priority: LOW
Configuration Change Scenarios
CC-001: Disable Respawn While Running
Description: Setting enabled to false while controller is running.
Initial State: watching with cycle in progress
Actions:
- Call updateConfig({ enabled: false })
- Check controller behavior
Expected Behavior:
- Config updated (for reference)
- Controller continues current operation
- On restart, start() will be no-op
Priority: LOW
CC-002: Change updatePrompt During Cycle
Description: Changing update prompt while cycle is in progress.
Initial State: waiting_update
Actions:
- Call updateConfig({ updatePrompt: 'new prompt' })
- Start next cycle
Expected Behavior:
- Current cycle uses old prompt (already sent)
- Next cycle uses new prompt
Priority: LOW
CC-003: Toggle sendClear Mid-Cycle
Description: Changing sendClear while in waiting_update.
Initial State: waiting_update with sendClear: true
Actions:
- Call updateConfig({ sendClear: false })
- Update step completes
Expected Behavior:
- Should use updated config value
- Skip clear and proceed appropriately
Priority: MEDIUM
CC-004: Change Timeout Values During Wait
Description: Modifying timeout values while timer is running.
Initial State: Timer running with completionConfirmMs: 10000
Actions:
- Call updateConfig({ completionConfirmMs: 1000 })
- Check when timer fires
Expected Behavior:
- Current timer uses old value
- Next timer uses new value
- No crash or undefined behavior
Priority: LOW
CC-005: Update kickstartPrompt to Undefined
Description: Removing kickstart prompt during monitoring_init.
Initial State: monitoring_init with kickstartPrompt set
Actions:
- Call updateConfig({ kickstartPrompt: undefined })
- /init doesn't trigger work
Expected Behavior:
- Should check config at decision time
- May skip kickstart or use stale value
- (Behavior should be defined)
Priority: LOW
Buffer and Memory Scenarios
BM-001: Buffer Trim at Exact Boundary
Description: Buffer exactly at MAX_RESPAWN_BUFFER_SIZE.
Initial State: Buffer at exactly 1MB
Actions:
- Fill buffer to exactly 1MB
- Append 1 more character
Expected Behavior:
- Trim triggered
- Buffer reduced to RESPAWN_BUFFER_TRIM_SIZE (512KB)
- Most recent data preserved
Priority: LOW
BM-002: Continuous High-Volume Output
Description: Sustained high-volume terminal output.
Initial State: watching
Actions:
- Send 1MB of data per second for 10 seconds
- Check memory usage and behavior
Expected Behavior:
- Buffer stays bounded
- No memory growth over time
- Detection still functions
Priority: MEDIUM
BM-003: Buffer Clear During Pattern Match
Description: Buffer cleared while pattern detection is occurring.
Initial State: Processing terminal data
Actions:
- Process data that triggers completeCycle
- completeCycle clears buffer
- More data arrives in same handler
Expected Behavior:
- New data appended to fresh buffer
- No stale data patterns matched
Priority: LOW
BM-004: Action Log Growth
Description: Action log entries accumulating over time.
Initial State: Many cycles completed
Actions:
- Run many cycles (>20)
- Check recentActions length
Expected Behavior:
- Limited to 20 entries max
- Oldest entries discarded
- Memory stable
Priority: LOW
Edge Cases in Pattern Detection
PD-001: Completion Message Without "Worked"
Description: Time duration pattern without "Worked" prefix.
Initial State: watching
Actions:
- Simulate: "Waiting for 5s before retry"
- Check if completion detected
Expected Behavior:
- NOT detected as completion (requires "Worked" prefix)
- No false positive
Priority: HIGH
PD-002: Nested Working Patterns in Text
Description: Working pattern words in non-working context.
Initial State: watching
Actions:
- Simulate: "The 'Thinking' file was created"
- Check workingDetected status
Expected Behavior:
- Currently: Would detect as working (false positive)
- Expected: Should not detect (pattern in quotes)
- (This is a known limitation)
Priority: LOW (known limitation)
PD-003: Unicode Prompt Variants
Description: Various Unicode prompt characters.
Initial State: watching
Actions:
- Test: Regular '>' vs Unicode '>' vs fullwidth '>'
- Check promptDetected
Expected Behavior:
- Standard patterns detected
- Variant characters may not be detected
- (Document which are supported)
Priority: LOW
PD-004: ANSI Codes Splitting Patterns
Description: ANSI escape codes inserted within patterns.
Initial State: watching
Actions:
- Simulate: "Wor\x1b[32mked\x1b[0m for 2m 46s"
- Check completion detection
Expected Behavior:
- Pattern may not match (ANSI in middle of "Worked")
- (This is edge case behavior)
Priority: LOW
PD-005: Token Count at Boundary Values
Description: Token counts with k/M suffixes.
Initial State: watching
Actions:
- Simulate: "999.9k tokens" -> "1.0M tokens"
- Check lastTokenCount value
Expected Behavior:
- 999.9k = 999900
- 1.0M = 1000000
- Token change detected
Priority: LOW
PD-006: Empty String Token Pattern
Description: Token pattern with malformed numbers.
Initial State: watching
Actions:
- Simulate: "tokens", " tokens", ".k tokens"
- Check extractTokenCount returns
Expected Behavior:
- Returns null for invalid patterns
- No crash
Priority: LOW
PD-007: Multiple Completion Messages Same Data
Description: Multiple "Worked for Xm Xs" in single terminal chunk.
Initial State: watching
Actions:
- Simulate: "Worked for 1s... Worked for 2m 30s"
- Check behavior
Expected Behavior:
- First match triggers detection
- completionMessageTime set
- Single confirmation timer started
Priority: LOW
PD-008: Spinner Character in Normal Text
Description: Spinner Unicode character in regular output.
Initial State: watching
Actions:
- Simulate: "The sequence is: ⠋ ⠙ ⠹"
- Check workingDetected
Expected Behavior:
- Currently: Detects as working
- This is expected behavior (conservative)
Priority: LOW (expected behavior)
Event Emission and Listener Scenarios
EE-001: No Listeners Registered
Description: Events emitted with no listeners.
Initial State: Controller with no event listeners
Actions:
- Start controller
- Run through cycle
Expected Behavior:
- No errors
- Events still emitted (just not handled)
- Controller functions normally
Priority: LOW
EE-002: Listener Throws Exception
Description: Event listener throws during event handling.
Initial State: Listener registered that throws
Actions:
- Register listener: on('stateChanged', () => { throw Error })
- Cause state change
Expected Behavior:
- Exception propagates (EventEmitter default)
- (May want to catch in production)
Priority: MEDIUM
EE-003: Listener Removes Itself
Description: Listener that removes itself during event handling.
Initial State: Self-removing listener registered
Actions:
- Register one-time listener
- Cause event
Expected Behavior:
- Listener called once
- Properly removed
- No memory leak
Priority: LOW
EE-004: DetectionUpdate Interval Cleanup
Description: Detection update interval properly cleaned up.
Initial State: Controller running with detection updates
Actions:
- Start controller (starts 500ms interval)
- Stop controller
- Check interval cleared
Expected Behavior:
- detectionUpdateTimer cleared on stop
- No interval continuing after stop
- No memory leak
Priority: MEDIUM
EE-005: Timer Events During Stop
Description: Timer fires during stop() execution.
Initial State: Multiple timers running
Actions:
- Call stop()
- Timer fires during cleanup
Expected Behavior:
- Timer callback checks state
- No action taken if stopped
- Clean shutdown
Priority: LOW
Summary
Priority Distribution
| Priority | Count | Description |
|---|---|---|
| HIGH | 18 | Critical functionality and common paths |
| MEDIUM | 24 | Important edge cases and integrations |
| LOW | 22 | Rare edge cases and nice-to-have coverage |
Coverage Gaps Identified
- Full cycle with all steps enabled - No test covers the complete path through all states
- Clear fallback timer - Not tested (10s timeout when no prompt detected)
- AI checker consecutive errors leading to disable - Not integration tested
- Plan checker result discarding - Stale result handling not fully tested
- Step confirmation timer - The completionConfirmMs wait after each step not tested
- Working pattern detection during waiting states - Limited coverage
- Buffer edge cases - Trim behavior not tested
- Timer tracking for UI - getActiveTimers() accuracy not verified
- Event listener error handling - Not tested
- Elicitation flag lifecycle - Partial coverage
Recommended Test Implementation Order
- STS-001 (Full cycle) - Establishes complete flow understanding
- AIC-001, AIC-002, AIC-003 - Core AI checker verdicts
- APC-001, APC-004, APC-005 - Core plan checker scenarios
- STS-005 (Work during monitoring_init) - Important flow branch
- TC-001 (Step confirm interrupted) - Timer reliability
- ER-001 (Handler throws) - Robustness
- CO-002 (Multiple events same tick) - Concurrency safety