fix: detect active permission prompts using line-based counting#71
Merged
haofeif merged 1 commit intoFeb 16, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #71 +/- ##
=======================================
Coverage ? 20.97%
=======================================
Files ? 30
Lines ? 1392
Branches ? 0
=======================================
Hits ? 292
Misses ? 1100
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
5f70dfc to
3835385
Compare
Decouple permission pattern from idle pattern in get_status(). Count idle prompt lines after last [y/n/t]: to distinguish active (<=1 line) from stale (>1 lines) permission prompts. Previous approaches failed because: - awslabs#69: [ \t]* can't bridge newlines, active prompts never detected - awslabs#61: \s* bridges newlines but also matches stale prompts Line-based counting handles \r redraws correctly (same line, no \n) and uses the LAST [y/n/t]: match to handle re-rendered prompts. Applied to both kiro_cli.py and q_cli.py. Unit tests (24 tests, test_permission_prompt_detection.py): Category | Our Fix | awslabs#61 | awslabs#69 Active prompts (P1-P4,P8) | 5/5 | 5/5 | 0/5 Stale prompts (P5-P7) | 4/4 | 0/4 | 4/4* Non-permission (N1-N9) | 8/8 | 8/8 | 8/8 Edge cases (ANSI, multi) | 7/7 | 4/7 | 4/7 Total | 24/24 | 18/24 | 15/24 * awslabs#69 stale tests pass only because prompts are never detected. Integration tests (7 tests, test_kiro_cli_integration.py, real kiro-cli): Test | Our Fix | awslabs#61 | awslabs#69 P1/P2 active | PASS | PASS | FAIL (IDLE) P3/P4 injection | PASS | PASS | FAIL (IDLE) P5/P6 stale | PASS | FAIL (WAITING_USER_ANSWER) | PASS* P7 multiple prompts | PASS | FAIL (never completes) | FAIL (not detected) N4/N5 processing | PASS | PASS | PASS INIT smoke | PASS | PASS | PASS QUERY smoke | PASS | PASS | PASS Total | 7/7 | 5/7 | 4/7 * awslabs#69 P5/P6 passes for wrong reason (nothing ever matches). Opt-in live terminal view via CAO_TEST_WATCH=1.
3835385 to
79a267f
Compare
anilkmr-a2z
approved these changes
Feb 16, 2026
anilkmr-a2z
left a comment
Contributor
There was a problem hiding this comment.
Thanks for fixing this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Permission prompt detection in
get_status()fails in two ways depending on the approach:PR fix: prevent permission prompt pattern from matching stale prompts #69 (current main): Pattern
[ \t]*between[y/n/t]:and idle prompt can't bridge newlines. Active permission prompts are never detected —get_status()returnsIDLEinstead ofWAITING_USER_ANSWER. Messages delivered during active prompts corrupt the terminal.PR fix: Handle CLI prompts with trailing text #61 (previous approach): Pattern
\s*bridges newlines but also matches stale (already-answered) prompts. After the user answersy, the old[y/n/t]:text remains in the terminal buffer.get_status()keeps returningWAITING_USER_ANSWEReven after the command completes.Both approaches fail because they try to combine the permission pattern and idle pattern into a single regex, which can't distinguish active from stale prompts.
Solution
Decouple permission detection from idle detection using line-based counting:
[y/n/t]:independently (non-greedy, no idle pattern suffix)[y/n/t]:WAITING_USER_ANSWERThis works because:
[y/n/t]:then at most one idle prompt on the next line\rredraws stay on the same line (no\n), so they don't inflate the countApplied to both
kiro_cli.pyandq_cli.py.Test Results
Unit Tests (24 tests —
test_permission_prompt_detection.py)* #69 stale tests pass but only because permission prompts are never detected (right result, wrong reason).
Integration Tests (7 tests —
test_kiro_cli_integration.py, real kiro-cli)* #69 P5/P6 passes for wrong reason (nothing ever matches).
Integration tests support
CAO_TEST_WATCH=1to open a Terminal.app window attached to the tmux session for live debugging, and auto-dump terminal output on failure.Files Changed
src/cli_agent_orchestrator/providers/kiro_cli.py— line-based counting inget_status()src/cli_agent_orchestrator/providers/q_cli.py— same fixtest/providers/test_permission_prompt_detection.py— 24 unit tests with 6 fixture filestest/providers/test_kiro_cli_integration.py— 7 integration tests against real kiro-clitest/providers/fixtures/— 6 fixture files with real ANSI terminal captures