phase: 104_chip_sizing_question_cap
All completion criteria verified. Final report: **Phase 104 — final verification pass: all green** - Verified (no code changes needed): single-line ellipsized `.suggestion-chip` CSS + deleted `.maybe-try` override, `renderChips` full-text `title` + `aria-label`-when-clipped, `maxlength="4000"` + `#char-count` counter + `handleSend` over-cap guard, unit pins file, schemas boundary pins, dedicated E2E suite. - E2E (isolation): `uv run pytest tests/e2e/test_chip_sizing_question_cap.py -v --no-cov` → **6 passed**; regressions: `test_suggestion_chips.py` 8 passed, `test_pinned_composer.py` 4 passed, `test_responsive_polish.py` 7 passed, `test_chat_history.py` 5 passed. - `uv run pytest` → **2102 passed**; `--cov=app` → **99%** (>90%); `uv run ruff check . && uv run pyright` → clean, 0 errors. - Criteria: chip E2E (single-line, clipped, title+aria-label full text) ✅; paste caps at exactly 4,000, send streams, counter hides ✅; programmatic 5,000-char fill → banner, no turn, text kept ✅; 4,000/4,001 boundary pinned + HTML maxlength == JS constant cross-file pin ✅. - Diff scope: `frontend/`, new unit file, `tests/unit/test_schemas.py`, new E2E file, phase files — **no `app/` diff, no migration, no `shared.js` diff**. - Deviations: 4 regression test files touched — 2 genuine DOM-pin conflicts from the new `#char-count` child (explicitly anticipated by the overview) + 3 documented **pre-existing E2E flake fixes** (smooth-scroll race, tab-walk heuristic, 10 ms timeout), each verified pre-existing on the pre-phase-104 tree. - No commit made (harness commits per the execution protocol override). - Next pending phase: `98_sync_summary_visibility`.
This commit is contained in:
@@ -252,6 +252,15 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Phase 104 (owner 2026-09-12): the question-length counter —
|
||||
hidden until 80% of the 4,000-char cap (app.js
|
||||
updateCharCount); the .is-max state uses the --err-* family
|
||||
PLUS a copy change (B3: text + color, never color alone). NOT
|
||||
a live region: per-keystroke feedback is decorative — the
|
||||
over-cap failure path announces through the error banner
|
||||
(role=alert). -->
|
||||
<p class="char-count" id="char-count" hidden></p>
|
||||
|
||||
<!-- Composer (phase 48, 2026-08-29, TODO.md L3): one button, two
|
||||
roles — #send-btn reads "Send" when idle and morphs into the
|
||||
enabled "Stop" control (.is-stop, rose treatment) while a turn
|
||||
@@ -270,12 +279,16 @@
|
||||
precedent as the tuning form's noValidate). -->
|
||||
<form class="composer" id="composer" novalidate>
|
||||
<label class="visually-hidden" for="message-input">Ask Brain of Reese a question</label>
|
||||
<!-- maxlength=4000 mirrors ChatRequest.message max_length=4000
|
||||
(app/schemas.py) — the server 422s beyond; the #char-count
|
||||
line makes the cap visible (app.js updateCharCount). -->
|
||||
<textarea
|
||||
id="message-input"
|
||||
name="message"
|
||||
rows="1"
|
||||
placeholder="Ask me anything…"
|
||||
autocomplete="off"
|
||||
maxlength="4000"
|
||||
></textarea>
|
||||
<button type="submit" class="send-btn" id="send-btn">
|
||||
<span class="spinner" aria-hidden="true" hidden></span>
|
||||
|
||||
Reference in New Issue
Block a user