phase: 193_sync_remaining_count
**Phase 193 — final verification pass: all gates green.**
- **Verified (all 3 tasks already complete in `complete/193_sync_remaining_count/`):** `fmtSyncLabel`'s count part is `total > 0 && total - done > 0 ? \`${total - done} remaining\` : ""` (plain int, hidden at `N==0`, `total===0` → no part); docstrings updated; chunk/image/summaries parts + `counts_line` terminal + `app/` byte-untouched (`git diff --stat`: no `app/` files).
- **Completion criteria:** `N remaining` shape + marker pins ✅ · upload shares the builder (E2E upload arm) ✅ · chunk/image/summaries pins green ✅ · terminal `counts_line` green unedited + A4 title/`#sync-progress` pin ✅ · suite green, coverage 99% ✅ · lint/types clean ✅ · commit + `todo/→complete/` left to the harness (no git index/history commands run).
- `uv run pytest -q --cov=app --cov-report=term-missing` → **exit 0**, junit: **4792 tests, 0 failures/errors/skipped**, `TOTAL 7181 16 → 99%` (>90%)
- `uv run pytest tests/e2e/test_sync_remaining_count.py -v --no-cov` → **3 passed** (isolated, 53 s)
- Isolated `--no-cov` sweep of the 14 sync-lineage suites (label_mobile, upload_progress, chunk_progress, image_progress, progress_box, summary_visibility, archive_upload_sources, status_freshness, upload_no_scan, peak_memory_visible, session_reset, fast_path_deferred_content, git_freeze, smoke) → **14/14 exit 0**
- `uv run ruff check .` → All checks passed · `uv run pyright` → **0 errors**
- **Docs:** README.md reviewed in full (all 2408 lines) + AGENTS.md. Fixed 2 inconsistencies: the sync running-label clause claimed the upload label shows the count — now states it shares the ONE builder/shape but reports no counts since phase 90 (renders bare); phase-190's "the other ~72 rows" → "the other 83 rows of the panel's 86-row catalogue" (mechanically: 86 CATALOG rows, 84 overridable). `N remaining` already in the sync paragraph; task-01's `(n/m)` examples gone. AGENTS.md verified consistent (no clause names the running count part → unchanged per the phase's "do not add if absent"). Mechanically re-verified: all 86 `BOR_*` settings documented + defaults match, `.env.example` 88 vars covered, 0 broken README anchors, all cited file paths exist, 17 palette colors, migrations head `0030`, pages/shell routes, ports 8123/8901, E2E port allocations (new suite's 8211/8914 unique).
- **Notable:** task 02's documented deviation stands — `files_done` is the importer's 1-based *current* file, so the phase doc's `[1-4]` range is unreachable; count-bearing frames are `1 … N−1` (pinned). Pre-existing, untouched: `E2E_APP_PORT_TOOLBUDGET`/`SAVEDOC` both 8129 and `SYNCUP`/`SYCNCEL` both 8133 — harmless under the one-suite-at-a-time rule.
- **Next pending phase:** none — `193_sync_remaining_count` is the last entry in `.agents/phases/todo/`.
This commit is contained in:
@@ -79,8 +79,9 @@ its own (n/m) is its position, idle / settle). setSyncLabel(mainText,
|
||||
countText, chunkText) lands the part under the same present/absent
|
||||
contract as the count part, and the UNTRUNCATED full label — main +
|
||||
" " + count + " " + chunk — rides the button title + #sync-progress
|
||||
(A4 — the in-flight import reads "Syncing… <file> (2/3) · chunk
|
||||
14/38"). The part keeps the pinned mono CSS (flex 0 0 auto, nowrap,
|
||||
(A4 — the in-flight import reads "Syncing… <file> 1 remaining · chunk
|
||||
14/38" — phase 193 counts the files DOWN). The part keeps the pinned
|
||||
mono CSS (flex 0 0 auto, nowrap,
|
||||
--mono, the rule right after .sync-label-count). A node harness (the
|
||||
test-document-viewer pattern) behaviorally pins the rendered parts +
|
||||
the full title across every label state.
|
||||
@@ -141,7 +142,8 @@ the 202/409 click stay bare). setSyncLabel(mainText, countText =
|
||||
"", chunkText = "", running = false, imageText = "") appends the
|
||||
image part LAST to the composed full string — so the box, the
|
||||
button title, and the running aria-label all carry
|
||||
"Syncing… <file> (2/3) · chunk 14/38 · image 3/15". The image part
|
||||
"Syncing… <file> 1 remaining · chunk 14/38 · image 3/15" (phase 193).
|
||||
The image part
|
||||
gets NO span of its own (the running button is the spinner — its
|
||||
parts are hidden, phase 149): it rides ONLY the composed string,
|
||||
while the chunk part keeps its .sync-label-chunk span; the two
|
||||
@@ -189,6 +191,19 @@ app/ no-touch regression guard). The qualifier's byte-identity
|
||||
pinned in test_sync_button.py on the shared fixed clock; the four
|
||||
shapes and the fmtUploadStamp behavior (finished / started /
|
||||
missing / garbage) ride the task-02 pins below.
|
||||
|
||||
Phase 193 (task 01, D1) re-points the running file-count part: the
|
||||
fmtSyncLabel COUNT part is the COUNT-DOWN `N remaining` (N =
|
||||
total - done) — shown while N >= 1, HIDDEN at the final file (N == 0:
|
||||
the main part names the file in flight — a "0 remaining" next to the
|
||||
last file's name is the stale-looking edge the owner's complaint is
|
||||
about), the total > 0 pre-walk guard KEPT, plain integer (no thousands
|
||||
separator); the UPLOAD job shares the builder and the shape (A2). The
|
||||
node harness rows that carried "(2/3)" now carry "1 remaining" (the
|
||||
same 2/3 fixture — the part renders the distance to the end), the
|
||||
harness gains the final-file row (the count part hidden), and the
|
||||
summaries phase's own (n/m) folder position, the "· chunk n/m" /
|
||||
"· image n/m" parts and the terminal counts line stay byte-identical.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -316,6 +331,19 @@ def _tick(js: str) -> str:
|
||||
return js[tick:end]
|
||||
|
||||
|
||||
def _doc_above(js: str, name: str) -> str:
|
||||
"""The block comment immediately above `function <name>` (the
|
||||
builder's docstring — _fn starts AT the keyword, so the lineage
|
||||
paragraphs need this slice)."""
|
||||
i = js.find(f"function {name}")
|
||||
assert i != -1, f"{name} must be defined in sources.js"
|
||||
start = js.rfind("/*", 0, i)
|
||||
assert start != -1, f"{name} must carry a docstring"
|
||||
end = js.find("*/", start)
|
||||
assert start < end < i, f"{name}'s docstring must sit above the function"
|
||||
return js[start:end]
|
||||
|
||||
|
||||
# ---------- fmtSyncLabel: the live-file label PARTS contract ----------
|
||||
|
||||
|
||||
@@ -328,9 +356,10 @@ def test_fmt_sync_label_returns_the_parts_contract() -> None:
|
||||
prefix shows during clone/pull, before any file is indexed — A4;
|
||||
phase 90: the upload run never carries a file or counts, so its
|
||||
label is always the bare "Importing"); the COUNT part — only when
|
||||
total > 0 (the import has started), NO join space (the space is
|
||||
the CSS gap between the parts — the full string's space is
|
||||
re-joined by setSyncLabel for the title / announcer, A4). File
|
||||
total > 0 (the import has started) — is the phase-193 COUNT-DOWN
|
||||
`N remaining` (N = total - done), NO join space of its own (the
|
||||
space between the parts is the CSS gap — the full string's space
|
||||
is re-joined by setSyncLabel for the title / announcer, A4). File
|
||||
before counts in the full-string order."""
|
||||
body = _fn(_js(), "fmtSyncLabel")
|
||||
assert "function fmtSyncLabel(kind, currentFile, done, total)" in body
|
||||
@@ -344,20 +373,95 @@ def test_fmt_sync_label_returns_the_parts_contract() -> None:
|
||||
# the MAIN part: the file appended only when present
|
||||
assert "currentFile ?" in body
|
||||
assert "`${prefix} ${currentFile}`" in body
|
||||
# the COUNT part: only when the import has started (total > 0),
|
||||
# no join space (the parts are joined by setSyncLabel, A4)
|
||||
# the COUNT part (phase 193, D1): only when the import has
|
||||
# started (the kept total > 0 pre-walk guard) AND the run is not
|
||||
# on its final file (total - done > 0), no leading join space
|
||||
# (the parts are joined by setSyncLabel, A4)
|
||||
assert "total > 0" in body
|
||||
assert "`(${done}/${total})`" in body
|
||||
assert "` (${done}/${total})`" not in body, ("no space in the count part")
|
||||
assert "`${total - done} remaining`" in body
|
||||
assert "(${done}/${total})" not in body, (
|
||||
"the pre-phase (done/total) shape is gone (phase 193)"
|
||||
)
|
||||
i_file = body.find("currentFile ?")
|
||||
i_counts = body.find("total > 0")
|
||||
assert -1 < i_file < i_counts, "the file lands before the counts"
|
||||
# the parts return (the byte-identical full strings hold when
|
||||
# setSyncLabel joins them: "Syncing…", "Syncing… <file>",
|
||||
# "Syncing… <file> (n/m)", "Importing")
|
||||
# the parts return (the full strings hold when setSyncLabel joins
|
||||
# them: "Syncing…", "Syncing… <file>",
|
||||
# "Syncing… <file> N remaining", "Importing")
|
||||
assert "return { main, count }" in body
|
||||
|
||||
|
||||
def test_fmt_sync_label_count_part_is_the_n_remaining_part() -> None:
|
||||
"""Phase 193 (task 01, D1): the running file-count part counts
|
||||
DOWN. The fmtSyncLabel count expression is pinned VERBATIM — the
|
||||
kept `total > 0` pre-walk guard (phase 64: no count part before
|
||||
the walk knows the total) AND the new `total - done > 0` guard
|
||||
(the part hides at the final file, ASSUMPTION A1) around the
|
||||
plain-integer `${total - done} remaining` shape (no thousands
|
||||
separator — the existing count part's house style). The docstring
|
||||
names the new part (N = total - done, shown while N >= 1), the
|
||||
hidden-at-the-final-file edge (N == 0 — the main part names the
|
||||
file in flight; a "0 remaining" next to the last file's name is
|
||||
the stale-looking edge), and the upload job sharing the builder
|
||||
and the shape (A2)."""
|
||||
js = _js()
|
||||
body = _fn(js, "fmtSyncLabel")
|
||||
# the exact expression, byte-for-byte (both guards + the shape +
|
||||
# the empty-string else)
|
||||
assert (
|
||||
"const count = total > 0 && total - done > 0"
|
||||
" ? `${total - done} remaining` : \"\";"
|
||||
) in body, "the count expression is the D1 shape"
|
||||
assert "total > 0 &&" in body, "the total > 0 pre-walk guard stays"
|
||||
assert "total - done > 0" in body, (
|
||||
"the part hides at the final file (N == 0, A1)"
|
||||
)
|
||||
# plain integer — no separator/format helper joins the number
|
||||
assert "toLocaleString" not in body and ".toFixed" not in body, (
|
||||
"plain integer, no thousands separator (the house label style)"
|
||||
)
|
||||
doc = _doc_above(js, "fmtSyncLabel")
|
||||
assert "`N remaining`" in doc and "N = total - done" in doc, (
|
||||
"the docstring describes the new part"
|
||||
)
|
||||
assert "N >= 1" in doc, "shown while N >= 1 (A1)"
|
||||
assert "HIDDEN at the final file" in doc and "N == 0" in doc, (
|
||||
"the hidden-at-final-file edge is named in the docstring (A1)"
|
||||
)
|
||||
assert "thousands separator" in doc, "the plain-integer clause is named"
|
||||
assert "pre-walk" in doc, "the phase-64 total > 0 contract is named"
|
||||
assert "shares this builder" in doc, (
|
||||
"the upload job sharing the builder and the shape is named (A2)"
|
||||
)
|
||||
|
||||
|
||||
def test_remaining_part_leaves_the_other_parts_byte_identical() -> None:
|
||||
"""Phase 193 (task 01): the COUNT-DOWN moved exactly ONE part.
|
||||
The fmtSyncPhaseLabel import fall-through still builds the
|
||||
phase-129 "· chunk n/m" and the phase-152 "· image n/m" parts
|
||||
from the status's own fields, the summaries branch still emits
|
||||
its FOLDER position `(${summaries_done}/${summaries_total})`,
|
||||
the bare fmtSyncLabel builder stays free of all three (each part
|
||||
lives only in its own builder), and the terminal counts line
|
||||
(fmtSyncResult — a different surface) never grows the word."""
|
||||
js = _js()
|
||||
phase = _fn(js, "fmtSyncPhaseLabel")
|
||||
assert "`· chunk ${status.current_chunk}/${status.chunks_total}`" in phase
|
||||
assert "`· image ${status.images_done}/${status.images_total}`" in phase
|
||||
assert (
|
||||
"count: `(${status.summaries_done}/${status.summaries_total})`"
|
||||
) in phase, "the summaries folder position keeps its (n/m) shape"
|
||||
bare = _fn(js, "fmtSyncLabel")
|
||||
for part in ("chunk", "image", "summaries"):
|
||||
assert part not in bare, (
|
||||
f"fmtSyncLabel stays {part}-free — the part lives only in its own builder"
|
||||
)
|
||||
assert "remaining" not in _fn(js, "fmtSyncResult"), (
|
||||
"the terminal result line is untouched (the running count part"
|
||||
" is the one change)"
|
||||
)
|
||||
|
||||
|
||||
def test_set_sync_label_is_the_single_parts_writer() -> None:
|
||||
"""setSyncLabel(mainText, countText = "", chunkText = "",
|
||||
running = false, imageText = "") — Phase 128 (task 01) + Phase
|
||||
@@ -374,7 +478,7 @@ def test_set_sync_label_is_the_single_parts_writer() -> None:
|
||||
(countText ? " " + countText : "") + (chunkText ? " " + chunkText
|
||||
: "") + (imageText ? " " + imageText : "") — rides the button
|
||||
title (A4 — the screen reader hears the
|
||||
whole "Syncing… <file> (2/3) · chunk 14/38 · image 3/15" there,
|
||||
whole "Syncing… <file> 1 remaining · chunk 14/38 · image 3/15" there,
|
||||
and in the box — see below). The image part (phase 152) gets NO
|
||||
span of its own (the running button is the spinner — its parts
|
||||
are hidden, phase 149): it rides only the composed full string.
|
||||
@@ -868,6 +972,15 @@ enterSyncRunningState("sync", "src/a/b.md", 2, 3, {
|
||||
current_chunk: 0, chunks_total: 0,
|
||||
});
|
||||
show("import-prebatch");
|
||||
// 2b. Phase 193 (task 01, A1): the FINAL file (files_done ==
|
||||
// files_total) — the count part HIDES (the main part names the
|
||||
// file in flight; a "0 remaining" next to it is the stale-looking
|
||||
// edge):
|
||||
enterSyncRunningState("sync", "src/a/b.md", 3, 3, {
|
||||
phase: "import", current_file: "src/a/b.md", files_done: 3, files_total: 3,
|
||||
current_chunk: 0, chunks_total: 0,
|
||||
});
|
||||
show("import-final");
|
||||
// 3. the prelude (null phase, no file yet):
|
||||
enterSyncRunningState("sync", null, 0, 0, {
|
||||
phase: null, current_file: null, files_done: 0, files_total: 0,
|
||||
@@ -957,9 +1070,13 @@ test-document-viewer pattern). The pinned "· chunk n/m" part (the
|
||||
* import, batch in flight (chunks_total 38 > 0): the chunk part
|
||||
shows "· chunk 14/38" and the UNTRUNCATED title + #sync-progress
|
||||
(the sole live region) read exactly
|
||||
"Syncing… src/a/b.md (2/3) · chunk 14/38" (A4);
|
||||
"Syncing… src/a/b.md 1 remaining · chunk 14/38" (A4 — phase
|
||||
193: the 2/3 fixture now renders the distance to the end);
|
||||
* import before the first batch (0/0): the chunk part hides and
|
||||
the label stays "Syncing… src/a/b.md (2/3)";
|
||||
the label stays "Syncing… src/a/b.md 1 remaining";
|
||||
* import on the FINAL file (phase 193, A1: files_done ==
|
||||
files_total): the COUNT part hides (no "0 remaining") — the
|
||||
main part alone names the file in flight;
|
||||
* every OTHER state — prelude (null phase), the 202/409 click (no
|
||||
status), the upload run (no status, D2), overview, summaries (its
|
||||
own (n/m) is its position), the idle settle — leaves the chunk
|
||||
@@ -982,24 +1099,39 @@ test-document-viewer pattern). The pinned "· chunk n/m" part (the
|
||||
# untruncated label rides the title + the announcer (A4).
|
||||
row = by_tag["import-inflight"]
|
||||
assert row[3] == "Syncing… src/a/b.md", row
|
||||
assert row[4] == "(2/3)" and row[5] is False, row
|
||||
assert row[4] == "1 remaining" and row[5] is False, (
|
||||
"phase 193 (D1): the count part is the count-DOWN (3 − 2 = 1)"
|
||||
)
|
||||
assert row[6] == "· chunk 14/38" and row[7] is False, (
|
||||
"the chunk part shows the batch position (1-based first chunk / file total)"
|
||||
)
|
||||
assert row[1] == "Syncing… src/a/b.md (2/3) · chunk 14/38", row[1]
|
||||
assert row[1] == "Syncing… src/a/b.md 1 remaining · chunk 14/38", row[1]
|
||||
assert row[2] == row[1], "the announcer hears the whole thing (A4)"
|
||||
|
||||
# 2. the import before the first batch (0/0) — the part hides, the
|
||||
# label is the byte-identical phase-64 string.
|
||||
# 2. the import before the first batch (0/0) — the chunk part
|
||||
# hides, the label keeps its phase-64 shape with the phase-193
|
||||
# count part.
|
||||
row = by_tag["import-prebatch"]
|
||||
assert row[1] == "Syncing… src/a/b.md (2/3)", row[1]
|
||||
assert row[1] == "Syncing… src/a/b.md 1 remaining", row[1]
|
||||
assert row[2] == row[1]
|
||||
assert row[6] == "" and row[7] is True, row
|
||||
|
||||
# 2b. the FINAL file (N == 0) — the count part HIDES (phase 193,
|
||||
# A1): no "0 remaining", the main part names the file, and
|
||||
# the A4 full label is just the main part.
|
||||
row = by_tag["import-final"]
|
||||
assert row[3] == "Syncing… src/a/b.md", row
|
||||
assert row[4] == "" and row[5] is True, (
|
||||
"the count part hides at the final file (total - done == 0)"
|
||||
)
|
||||
assert row[1] == "Syncing… src/a/b.md", row[1]
|
||||
assert row[2] == row[1]
|
||||
|
||||
# 3. every other RUNNING state — the chunk part is hidden +
|
||||
# empty, the title is the byte-identical pre-phase-129 label,
|
||||
# and the announcer (the box) hears the whole label (A4).
|
||||
for tag, expected_title in (
|
||||
("import-final", "Syncing… src/a/b.md"),
|
||||
("prelude", "Syncing…"),
|
||||
("click", "Syncing…"),
|
||||
("upload", "Importing"),
|
||||
@@ -1029,7 +1161,15 @@ test-document-viewer pattern). The pinned "· chunk n/m" part (the
|
||||
# upload job is NOT cancellable in this phase) and hidden +
|
||||
# disabled after the real settle (settleSyncButton always hides
|
||||
# it — every terminal + idle passes through it).
|
||||
for tag in ("import-inflight", "import-prebatch", "prelude", "click", "overview", "summaries"):
|
||||
for tag in (
|
||||
"import-inflight",
|
||||
"import-prebatch",
|
||||
"import-final",
|
||||
"prelude",
|
||||
"click",
|
||||
"overview",
|
||||
"summaries",
|
||||
):
|
||||
row = by_tag[tag]
|
||||
assert row[8] is False and row[9] is False, (
|
||||
f"{tag}: the Cancel control must be shown + enabled while a sync run is in flight"
|
||||
@@ -1053,14 +1193,15 @@ def test_image_part_renders_only_in_the_import_phase_under_node() -> None:
|
||||
WITH the last chunk position still on the status (125/126):
|
||||
the composed full string carries BOTH parts — the box, the
|
||||
button title, and the running aria-label all read exactly
|
||||
"Syncing… src/a/b.md (2/3) · chunk 125/126 · image 3/15"
|
||||
(the owner's stuck label, now moving); the chunk part KEEPS
|
||||
"Syncing… src/a/b.md 1 remaining · chunk 125/126 · image 3/15"
|
||||
(the owner's stuck label, now moving; phase 193: the count part
|
||||
is the count-DOWN); the chunk part KEEPS
|
||||
its span ("· chunk 125/126" visible) and the image part gets
|
||||
NO span of its own (it rides the composed string only — the
|
||||
running button is the spinner, phase 149);
|
||||
* import, a purely pictorial PDF (the chunk position never left
|
||||
0/0) in its vision span: the image part shows ALONE —
|
||||
"Syncing… src/a/b.md (2/3) · image 7/7" — and the chunk part
|
||||
"Syncing… src/a/b.md 1 remaining · image 7/7" — and the chunk part
|
||||
stays hidden + empty (the two parts are distinct and each
|
||||
disappears independently on its own 0/0);
|
||||
* every OTHER running state (the pre-batch import, the prelude,
|
||||
@@ -1082,7 +1223,7 @@ def test_image_part_renders_only_in_the_import_phase_under_node() -> None:
|
||||
# (the image part LAST, after the chunk part), on the box, the
|
||||
# title, and the running aria-label (A4) — the chunk span
|
||||
# keeps its own part.
|
||||
full = "Syncing… src/a/b.md (2/3) · chunk 125/126 · image 3/15"
|
||||
full = "Syncing… src/a/b.md 1 remaining · chunk 125/126 · image 3/15"
|
||||
row = by_tag["import-image-span"]
|
||||
assert row[1] == full, row[1]
|
||||
assert row[2] == full, "the announcer (the box) hears the whole thing (A4)"
|
||||
@@ -1095,7 +1236,7 @@ def test_image_part_renders_only_in_the_import_phase_under_node() -> None:
|
||||
# 1c. the image part alone (the chunk position never left 0/0 —
|
||||
# the two parts are independent).
|
||||
row = by_tag["import-image-only"]
|
||||
assert row[1] == "Syncing… src/a/b.md (2/3) · image 7/7", row[1]
|
||||
assert row[1] == "Syncing… src/a/b.md 1 remaining · image 7/7", row[1]
|
||||
assert row[2] == row[1] and row[14] == row[1], row
|
||||
assert row[6] == "" and row[7] is True, (
|
||||
"the chunk part stays hidden + empty (its own 0/0)"
|
||||
@@ -1106,8 +1247,9 @@ def test_image_part_renders_only_in_the_import_phase_under_node() -> None:
|
||||
# hides on its own 0/0 — the overview/summaries transitions
|
||||
# clear the position server-side, the bare builders carry none).
|
||||
for tag, expected_title in (
|
||||
("import-inflight", "Syncing… src/a/b.md (2/3) · chunk 14/38"),
|
||||
("import-prebatch", "Syncing… src/a/b.md (2/3)"),
|
||||
("import-inflight", "Syncing… src/a/b.md 1 remaining · chunk 14/38"),
|
||||
("import-prebatch", "Syncing… src/a/b.md 1 remaining"),
|
||||
("import-final", "Syncing… src/a/b.md"),
|
||||
("prelude", "Syncing…"),
|
||||
("click", "Syncing…"),
|
||||
("upload", "Importing"),
|
||||
@@ -1176,6 +1318,7 @@ def test_progress_box_and_running_button_contract_under_node() -> None:
|
||||
for tag in (
|
||||
"import-inflight",
|
||||
"import-prebatch",
|
||||
"import-final",
|
||||
"prelude",
|
||||
"click",
|
||||
"upload",
|
||||
|
||||
@@ -268,8 +268,9 @@ def test_sync_button_has_icon_and_label_parts() -> None:
|
||||
Phase 128 (task 01): #sync-label is PARTS — the MAIN span
|
||||
(.sync-label-main) carries the idle text (the pre-JS label renders
|
||||
from the static markup; the part CSS may ellipsize it), the
|
||||
COUNT span (.sync-label-count — the pinned "(n/m)" position,
|
||||
never clipped) ships hidden + empty (there is no count at idle),
|
||||
COUNT span (.sync-label-count — the pinned phase-193
|
||||
"N remaining" position, never clipped) ships hidden + empty
|
||||
(there is no count at idle),
|
||||
and — phase 129 (task 04) — the CHUNK span (.sync-label-chunk —
|
||||
the pinned "· chunk n/m" embed-batch position) ships hidden +
|
||||
empty too (no chunk position at idle — the part renders only
|
||||
@@ -516,7 +517,7 @@ def test_fmt_sync_phase_label_image_part_is_pinned_source_level() -> None:
|
||||
`running` flag);
|
||||
* ``setSyncLabel``'s composed ``full`` string appends the image
|
||||
part LAST (after the chunk part) — so a status carrying both
|
||||
positions reads exactly "Syncing… <file> (2540/2540) · chunk
|
||||
positions reads exactly "Syncing… <file> 1 remaining · chunk
|
||||
125/126 · image 3/15" on the box, the title, and the running
|
||||
aria-label (byte-for-byte; the docstring's worked example
|
||||
carries the shape).
|
||||
|
||||
Reference in New Issue
Block a user