mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-22 16:01:07 +00:00
@@ -1,7 +1,7 @@
|
||||
id = "codex"
|
||||
version = "2026.09.05.1"
|
||||
version = "2026.09.12.1"
|
||||
min_engine_version = 3
|
||||
updated_at = "2026-09-05T00:00:00Z"
|
||||
updated_at = "2026-09-12T00:00:00Z"
|
||||
|
||||
[[rules]]
|
||||
id = "osc_title_blocked"
|
||||
@@ -69,6 +69,8 @@ id = "weak_blocker"
|
||||
state = "blocked"
|
||||
priority = 600
|
||||
region = "whole_recent_without_current_prompt_marker"
|
||||
# Sparkles can replace the space after ›. A later response marker makes that prompt stale.
|
||||
not = [{ regex = ['(?m)^›[⠁⠂⠄⠈⠐⠠⡀⢀][^\n]*(?:\n(?:[^•■✗✓\n][^\n]*)?)*\z'] }]
|
||||
any = [
|
||||
{ contains = ["[y/n]"] },
|
||||
{ contains = ["yes (y)"] },
|
||||
|
||||
@@ -1194,6 +1194,46 @@ fn codex_weak_blocker_ignores_wrapped_current_prompt_text() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_sparkle_prompt_preserves_live_states() {
|
||||
for marker in ["› ", "›⠁", "›⠂", "›⠄", "›⠈", "›⠐", "›⠠", "›⡀", "›⢀"]
|
||||
{
|
||||
let screen = format!("Do you want to proceed? [y/n]\n{marker}unsent draft\n");
|
||||
let result = osc_explain(Agent::Codex, &screen, "project | Ready", "");
|
||||
assert_eq!(result.state, AgentState::Idle, "{marker}");
|
||||
|
||||
let working = format!(
|
||||
"Do you want to proceed? [y/n]\n• Working (4s • esc to interrupt)\n{marker}draft\n"
|
||||
);
|
||||
let result = osc_explain(Agent::Codex, &working, "project", "");
|
||||
assert_eq!(result.state, AgentState::Working, "{marker}");
|
||||
|
||||
let approval = format!("{screen}Press enter to confirm or esc to cancel\n");
|
||||
let result = osc_explain(Agent::Codex, &approval, "project", "");
|
||||
assert_eq!(result.state, AgentState::Blocked, "{marker}");
|
||||
assert!(result.visible_blocker);
|
||||
|
||||
for response_marker in ['•', '■', '✗', '✓'] {
|
||||
let response = format!("{screen}{response_marker} Do you want to proceed? [y/n]\n");
|
||||
let result = osc_explain(Agent::Codex, &response, "project", "");
|
||||
assert_eq!(
|
||||
result.state,
|
||||
AgentState::Blocked,
|
||||
"{marker} {response_marker}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_weak_blocker_does_not_ignore_arbitrary_prompt_suffixes() {
|
||||
for line in ["›text", "›⠋draft", "›⠀draft", " ›⠁draft", "quoted ›⠁draft"] {
|
||||
let screen = format!("Do you want to proceed? [y/n]\n{line}\n");
|
||||
let result = osc_explain(Agent::Codex, &screen, "project", "");
|
||||
assert_eq!(result.state, AgentState::Blocked, "{line}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_transcript_viewer_outranks_working_fallback() {
|
||||
let screen = "• Working (4s • esc to interrupt)\n\
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
id = "codex"
|
||||
version = "2026.09.05.1"
|
||||
version = "2026.09.12.1"
|
||||
min_engine_version = 3
|
||||
updated_at = "2026-09-05T00:00:00Z"
|
||||
updated_at = "2026-09-12T00:00:00Z"
|
||||
|
||||
[[rules]]
|
||||
id = "osc_title_blocked"
|
||||
@@ -69,6 +69,8 @@ id = "weak_blocker"
|
||||
state = "blocked"
|
||||
priority = 600
|
||||
region = "whole_recent_without_current_prompt_marker"
|
||||
# Sparkles can replace the space after ›. A later response marker makes that prompt stale.
|
||||
not = [{ regex = ['(?m)^›[⠁⠂⠄⠈⠐⠠⡀⢀][^\n]*(?:\n(?:[^•■✗✓\n][^\n]*)?)*\z'] }]
|
||||
any = [
|
||||
{ contains = ["[y/n]"] },
|
||||
{ contains = ["yes (y)"] },
|
||||
|
||||
Reference in New Issue
Block a user