Skip to content

Commit d4e4b97

Browse files
committed
fix: tolerate remapped Claude idle hint
1 parent 9854891 commit d4e4b97

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

src/ding.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,9 @@ fn classify_claude_composer(plain: &str, expected: &str) -> ComposerState {
504504
};
505505
let exact = logical_inputs.iter().any(|input| input == expected);
506506
let placeholder = logical_inputs.len() == 1 && is_claude_idle_placeholder(&logical_inputs[0]);
507-
let idle_footer = footer.contains("⏵⏵")
508-
&& footer.contains("shift+tab to cycle")
509-
&& footer.contains("permissions on");
507+
// The keybinding hint is runtime-composed and may be absent or remapped. The mode marker and
508+
// permission state are the stable safety signals; active/modal/changed states remain fail-closed.
509+
let idle_footer = footer.contains("⏵⏵") && footer.contains("permissions on");
510510
let blocked = interaction_blocked(plain);
511511
if exact {
512512
if idle_footer && !blocked {
@@ -1426,6 +1426,10 @@ mod tests {
14261426
)
14271427
}
14281428

1429+
fn idle_claude_screen_without_hint() -> String {
1430+
idle_claude_screen().replace(" (shift+tab to cycle)", "")
1431+
}
1432+
14291433
fn staged_claude_screen(text: &str) -> String {
14301434
assert!(text.is_ascii());
14311435
let rule = claude_rule();
@@ -1469,6 +1473,10 @@ mod tests {
14691473
classify_composer(&idle_claude_screen(), expected),
14701474
ComposerState::EmptySafe
14711475
);
1476+
assert_eq!(
1477+
classify_composer(&idle_claude_screen_without_hint(), expected),
1478+
ComposerState::EmptySafe
1479+
);
14721480
assert_eq!(
14731481
classify_composer(&staged_claude_screen(expected), expected),
14741482
ComposerState::ExactSafe

0 commit comments

Comments
 (0)