Repository navigation
Retain failed optimistic sends with visible failure reasons - #50
Merged
Merged
Conversation
Keep rejected text attempts visible with a bounded Not Delivered reason across reloads. Give each send its own local ID and discard thread snapshots that predate a local send or failure, so same-second sends and late responses cannot erase each other. Send-state logic is tested TypeScript with a generated QML module. Preserve stdin-only transport, memory-only message text, and exclusion of provisional bubbles from read marks. Verified with synthetic UI states and 403 tests.
nixfred
added a commit
that referenced
this pull request
Sep 10, 2026
A group with no name showed as a bare id with initials; it now names itself from its participants and draws a composite avatar from their pictures. Carries a real concurrency fix too: an avatarBusy flag holds the request identity until stdout is consumed, so a queued avatar cannot be attributed to the wrong handle. The BlipView hunk did not merge honestly and I did not force it. Git aligned the new Loader against a region main had restructured, producing a conflict whose "theirs" side re-added the avatarMask and MultiEffect blocks that sit directly above, plus the Text and ColumnLayout that sit directly below - taking it wholesale would have duplicated three blocks in a 2600-line QML file, which qmlformat would have happily parsed. Reset the file to main, re-applied this PR's own diff with a three-way apply, and hand-placed the one hunk that still would not land: the avatarCircleComposite Loader above the existing initials Text, with that Text guarded by !avatarCircleComposite.active so the initials stand down while the composite draws. Verified all four intents are present and both composites are wired and guarded. Deploy-line note, which is why this merged third: this PR adds GroupAvatar.mjs but never updated the copy command. #50 and #52 had already moved CLAUDE.md, AGENTS.md and CONTRIBUTING.md to `cp *.qml *.ts *.mjs`, so the gap is closed. Merged alone and deployed by the book, this would have shipped a QML import with no module behind it and killed both surfaces silently. 448 bun tests across nine files, every Mac-side suite, qmlformat on all QML. LR-T: pr-55, group-avatar, composite, avatar-concurrency, merge-resolution LR-D: blip, qml, collector, bridge LR-K: a-conflict-that-duplicates-three-blocks-still-parses Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MjLJVjERSup2CMwVehKja7
nixfred
added a commit
that referenced
this pull request
Sep 10, 2026
Ctrl plus a digit opens the pinned conversation in that slot, following pin order rather than list position, and it keeps working while an editor has focus so it is reachable mid-draft. The conversation view gains a back arrow for mouse users, which the keyboard already had through Esc. Conflict: ui.test.ts, this PR's test block and #50's landing at the same spot. Kept both, and the suite is the proof - a mis-spliced test file fails loudly rather than silently passing. 450 bun tests, Mac-side suites and qmlformat green. LR-T: pr-53, keyboard-shortcuts, pinned, back-arrow LR-D: blip, qml, keyboard LR-K: pin-order-not-list-position Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MjLJVjERSup2CMwVehKja7
nixfred
added a commit
that referenced
this pull request
Sep 10, 2026
ComposerInput.qml exposes a proper editable accessibility field and draws spelling ranges supplied by spellcheck.ts. Draft text reaches the helper on bounded stdin, never argv and never disk, and the helper returns only UTF-16 ranges - it never echoes the text back. That keeps the "message text never lands on disk, never rides argv" invariant intact for a feature that has to read every character you type. The arrow keys go back to native text editing inside the composer, which is what a text field should do. Conflicts: CLAUDE.md, README.md and ui.test.ts, each an independent paragraph or test block landing where #50 had just added its own. Kept both sides. 473 bun tests across twelve files, Mac-side suites and qmlformat green. LR-T: pr-51, composer, accessibility, spellcheck, arrow-keys LR-D: blip, qml, composer LR-K: a-speller-that-never-echoes-the-text-back Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MjLJVjERSup2CMwVehKja7
3 of 5 tasks
nixfred
pushed a commit
that referenced
this pull request
Sep 10, 2026
test-setup.ts already points XDG_CACHE_HOME at a scratch dir so no test touches the developer's caches. bridge.conf was not covered: contact-search reads country_code= through XDG_CONFIG_HOME (falling back to ~/.config), and the preload never set it. On a machine set up outside North America (country_code=47) five tier2 cases failed — "(404) 555-0123" normalized to +474045550123 — while CI, which has no bridge.conf, stayed green. XDG_CONFIG_HOME now gets a scratch dir beside the cache one. One test proves the isolation reaches the reader: the default country code is 1 in the scratch dir, and a bridge.conf written there is what changes it. The test first asserts the variable is set, because without it the scratch path is the literal ./undefined/, which is how stray artifacts of that name get committed. undefined/st.json is removed again: 7d569c3 took it out after 2.2.0 and #50 brought it back. It is the collector's state file written with an unset directory variable — the same class of artifact this preload exists to prevent. Measured: five tier2 failures with country_code=47 before, none after, on the machine that had them and against a fake home on a clean one.
nixfred
added a commit
that referenced
this pull request
Sep 13, 2026
… entry Release audit before 2.5.0, same method as 2.4.0: every merge since v2.4.0 checked against Unreleased. Missing and now written: #73 (security code on wl-copy stdin), #50 (failed send keeps its bubble), #51 (accessible composer, spelling, arrow keys), #52 (resizable panel + compact header), #53 (Ctrl+1-9 pins, back arrow), #55 + 2197e0d (unnamed groups named after people, composite avatar), #59/#60/#61 (contact scans, read-only card view, vCard copy/save), #48 (window restores on its workspace), #36 (no uninvited consent prompt from blip-check). Attributions checked against gh PR authors: #48 is @jefehoser; #36 reported by @jacobaross. Skipped as not user-facing: #64 (test isolation), #65 (README line), CONTRIBUTORS docs. No version bump yet: blip-b2 is landing the avatar-cache fix and #62 for Fred, and 2.5.0 waits for those. LR-T: changelog, release-audit, 2.5.0, attribution, backfill LR-D: blip, docs, release LR-K: audit-the-release-not-assume-it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PeUtMhaSaA9aiazebBUMS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Failed sends currently lose their optimistic bubble. Retain the failed attempt with a bounded Not Delivered reason, distinguish sends by local ID, and reject thread snapshots that predate local send changes. Provisional bubbles remain in memory and never advance read marks.
Validation:
bun test(440 passing). Shared Mac-side CI test suites and shell syntax checks pass. No real conversations were opened or messages sent for testing. Shellcheck is unavailable locally; CI covers it.Based directly on current main (
174b58e), as one focused commit; independent of the other split PRs and contact-write PR #25.