phase: 128_sync_label_mobile
Build and Push Containers / build-and-push-app (push) Successful in 2m32s
Build and Push Containers / build-and-push-db (push) Successful in 12s

Everything verified and 100% green. The earlier rejection was a report-format issue, not a test failure — all work is in the working tree. Final report:

**Phase 128 final pass — verified (all 3 tasks complete; no code defects found)**
- Verified: `#sync-label` parts markup, `setSyncLabel` writer, part builders (A4 untruncated title/aria-live), flex-row CSS + mobile media query — all match design 1:1.
- `uv run pytest --cov=app --cov-report=term`: 3024 passed; TOTAL coverage **99%** (>90% gate).
- `uv run pytest tests/e2e/test_sync_label_mobile.py -v --no-cov`: 4 passed (119s, isolated).
- `uv run ruff check .`: clean; `uv run pyright`: 0 errors.
- Criteria: (1) mobile 390×844 label in-viewport, count visible in import+summaries — ✅ E2E; (2) desktop strings/cap/title unchanged — ✅ E2E+unit; (3) E2E isolated green — ✅; (4) full suite green — ✅.
- Docs: README.md fixed 5 pre-existing gaps (PDF phase-126 section + `pdf` token, hidden-folders toggle ph.105, document dates ph.106, private git-source masked tokens ph.121, doc-draft Discard ph.115); AGENTS.md verified consistent — no changes.
- Notable: double-`-q` (addopts `-q` + CLI `-q`) suppresses pytest's summary line — standard `-qq` behavior, not a bug; exit codes confirm green.
- Next pending phase: `129_sync_chunk_progress`.
This commit is contained in:
2026-09-27 23:58:57 -04:00
parent 6e654df387
commit 1139f007cf
34 changed files with 2203 additions and 173 deletions
+24 -9
View File
@@ -2063,14 +2063,28 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
/* Phase 64: the live-file label ("Syncing… <file> (n/m)" / "Importing
<file> (n/m)") — a long source/relative/path ellipsizes inside the
pill; the full path lives in the button title + #sync-result (the
aria-live announcer). */
aria-live announcer). Phase 128 (task 02): the label is a FLEX ROW
of two parts — .sync-label-main (the prefix + file/folder: min-width
0, the shrinkable item whose ellipsis engages) + .sync-label-count
(the pinned "(n/m)": flex 0 0 auto, NEVER clipped — the
.sync-result mono language, a position reads as data). */
.sync-label {
display: inline-block;
display: inline-flex;
align-items: baseline;
gap: 0.35rem;
min-width: 0;
max-width: min(16rem, 40vw);
}
.sync-label-main {
min-width: 0; /* the flex item that shrinks — what engages the ellipsis */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: bottom;
}
.sync-label-count {
flex: 0 0 auto; /* NEVER clipped — the (n/m) position is the point */
white-space: nowrap;
font-family: var(--mono); /* the .sync-result mono language (position reads as data) */
}
/* Last-result announcer — soft ink, small mono */
.sync-result {
@@ -5313,14 +5327,15 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
target to discover on a phone). The RAG page-head row wraps so
the Sync pill drops below the "Knowledge base" title at full
width; the History page-head already wraps the pill below its
title block. The Sync label's min(16rem, 40vw) cap lifts so the
live-file text ellipsizes against the FULL width (min-width: 0
lets the nowrap flex item shrink, which is what engages the
ellipsis); the refresh glyph joins its visible label. The
aria-labels keep the accessible names. */
title block. The Sync label's min(16rem, 40vw) cap lifts and the
label FILLS the pill (phase 128: flex 1 1 auto) — .sync-label-main
ellipsizes against the width left by the pinned .sync-label-count,
so the (n/m) stays on-screen at the right edge, never clipped;
the refresh glyph joins its visible label. The aria-labels keep
the accessible names. */
.page-head-row { flex-wrap: wrap; }
.sync-btn { width: 100%; }
.sync-label { max-width: none; min-width: 0; }
.sync-label { max-width: none; flex: 1 1 auto; min-width: 0; }
.history-refresh { width: 100%; }
.history-refresh svg { display: block; }
.sync-result {