diff --git a/CHANGELOG.md b/CHANGELOG.md index 971a0bc11..523e8716f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ ## [Unreleased] +## [v0.51.185] — 2026-05-31 — Release FE (stage-batchE — clarify-card bug-fix batch: identical-prompt dedup + autofill guard + GBK startup crash) + +### Fixed +- The clarify popup could remain visible with stale input state after sending a response when the next queued clarification prompt was text-identical to the previous one. The dedupe signature now includes the prompt's `clarify_id`, so a newly queued identical prompt is treated as new instead of being mistaken for the one already answered (#3245, closes #3241). +- Chrome's password manager could autofill the clarify-card input with saved credentials (typically a provider base URL), causing a phantom "Clarification closed" toast on every session completion and injecting the saved URL into the main composer. The clarify input now carries `autocomplete="off"` plus a `readonly` guard that is lifted only when an actual clarification prompt is shown (or on focus), so the browser's heuristic autofill skips it (#3247). +- Prevent a server startup crash on non-UTF-8 Windows locales (e.g. Chinese GBK codepage): `_run_git()` now decodes git subprocess output as UTF-8 with `errors='replace'` and defensively guards against `None` streams, instead of letting a `UnicodeDecodeError` on binary `git diff --binary` output leave `stdout=None` and take down `import api.updates` with an `AttributeError` (#3249). + ## [v0.51.184] — 2026-05-31 — Release FD (stage-batchD — raw audio upload mode + scroll-preserve + non-POSIX test skip) ### Added diff --git a/api/updates.py b/api/updates.py index 4269e1996..55d0c75a2 100644 --- a/api/updates.py +++ b/api/updates.py @@ -166,9 +166,13 @@ def _run_git(args, cwd, timeout=10): r = subprocess.run( ['git'] + args, cwd=str(cwd), capture_output=True, text=True, timeout=timeout, + encoding='utf-8', errors='replace', ) - stdout = r.stdout.strip() - stderr = r.stderr.strip() + # On non-UTF-8 locales (e.g. Chinese Windows GBK), a binary git + # output that fails to decode used to leave r.stdout = None and crash + # the whole import with AttributeError. Guard against None defensively. + stdout = (r.stdout or '').strip() + stderr = (r.stderr or '').strip() if r.returncode == 0: return stdout, True return stderr or stdout or f"git exited with status {r.returncode}", False diff --git a/static/index.html b/static/index.html index 35421eaed..32efe8583 100644 --- a/static/index.html +++ b/static/index.html @@ -496,7 +496,7 @@
- +
Pick a choice, or type your own answer below.
diff --git a/static/messages.js b/static/messages.js index df823092e..a5ff0572f 100644 --- a/static/messages.js +++ b/static/messages.js @@ -2834,7 +2834,7 @@ function _ensureClarifyCardDom() {
- +
Please choose one option, or type your own response below.
@@ -3074,6 +3074,7 @@ function showClarifyCard(pending) { question, choices, sid: pending._session_id || (S.session && S.session.session_id) || null, + clarify_id: pending.clarify_id || null, }); const card = _ensureClarifyCardDom(); if (!card) return; @@ -3137,6 +3138,7 @@ function showClarifyCard(pending) { if (input) { if (!sameClarify) input.value = ''; input.disabled = false; + input.removeAttribute('readonly'); input.onkeydown = (e) => { if (e.key === 'Enter') { e.preventDefault(); diff --git a/tests/test_sprint30.py b/tests/test_sprint30.py index f34aac455..5bcdfd449 100644 --- a/tests/test_sprint30.py +++ b/tests/test_sprint30.py @@ -664,3 +664,5 @@ class TestClarifyCardTimerLogic: body = m.group(0) assert 'JSON.stringify' in body, 'showClarifyCard must compute a signature via JSON.stringify' assert '_clarifySignature' in body, 'showClarifyCard must check/set _clarifySignature' + assert 'clarify_id: pending.clarify_id || null' in body, \ + 'showClarifyCard signature must include clarify_id so a newly queued identical prompt is not mistaken for the previous one'