Skip to content

fix(meshcore): preserve node name on empty advert + mute route/scope colors#3772

Closed
Yeraze wants to merge 2 commits into
mainfrom
claude/great-dijkstra-08s9ur
Closed

fix(meshcore): preserve node name on empty advert + mute route/scope colors#3772
Yeraze wants to merge 2 commits into
mainfrom
claude/great-dijkstra-08s9ur

Conversation

@Yeraze

@Yeraze Yeraze commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Summary

Two small bug fixes from today's issue triage:

Fix 1: Preserve node name when advert has empty adv_name (#3756)

Root cause: contact_advertised events from zero-hop repeaters arrive with adv_name as an empty string "". The code used ?? (nullish coalescing) to merge names:

advName: data.adv_name ?? existing.advName,   // "" ?? "MyRepeater" → ""

Since "" is not null/undefined, the empty string won overwrote the stored name. The same value then propagated through persistContact into the DB (the upsertNode merge guard explicitly keeps '' as a valid update).

Fix: Change ?? to || in both the in-memory merge and the persistContact name field so empty strings fall back to the existing value, the same way null/undefined already did.

Test: New regression test in meshcoreManager.contactPersistence.test.ts — dispatches a named advert followed by an empty-name advert for the same key and asserts both the in-memory contact and the DB call preserve the original name.

Fix 2: Route/scope metadata colors more subdued (#3769)

Route and scope lines in MeshCore messages were using --ctp-overlay0 (same shade as the timestamp). For secondary metadata they should be quieter. Moved to --ctp-surface2 (one step more muted in both dark and light Catppuccin themes):

Element Before After
Message text --ctp-text --ctp-text
Timestamp --ctp-overlay0 --ctp-overlay0
Route / scope --ctp-overlay0 --ctp-surface2

Test plan

  • meshcoreManager.contactPersistence.test.ts — all 10 tests pass including new regression
  • Full Vitest suite — 0 failures
  • Manual: verify zero-hop repeater node keeps its name after a re-advert cycle
  • Manual: verify route/scope text is visibly more muted than the timestamp in both dark and light themes

🤖 Generated with Claude Code

https://claude.ai/code/session_016uH3HqQC4r4x7TRqhLTbc3


Generated by Claude Code

claude added 2 commits June 26, 2026 07:30
…as clearly secondary (#3769)

Route and scope lines are secondary metadata and should be visually less
prominent than the timestamp. Moving them from ctp-overlay0 to ctp-surface2
(one step more muted in both dark and light Catppuccin themes) creates the
expected visual hierarchy: message text > sender/time > route/scope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uH3HqQC4r4x7TRqhLTbc3
…name (#3756)

Zero-hop repeaters send contact_advertised with adv_name as an empty
string. The nullish-coalescing operator (??) used to merge names only
falls back on null/undefined, so "" was overwriting the stored name.
Changed ?? to || in both the in-memory contact update and the
persistContact DB write so empty strings are treated as "not observed"
and the previously stored name is preserved.

Regression test added to meshcoreManager.contactPersistence.test.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uH3HqQC4r4x7TRqhLTbc3
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

Claude finished @Yeraze's task —— View job


PR Review

  • Read changed files
  • Review Fix 1: node name preservation logic
  • Review Fix 2: CSS color changes
  • Review test coverage
  • Post final feedback

Overall Assessment

Both fixes are correct, well-scoped, and safe to merge. No issues found that would block approval.


Fix 1: Node name preservation (meshcoreManager.ts)

The change (meshcoreManager.ts:1112):

// Before
advName: data.adv_name ?? existing.advName,

// After
advName: data.adv_name || existing.advName,

And in persistContact (meshcoreManager.ts:1473):

// Before
name: contact.advName ?? contact.name ?? null,

// After  
name: contact.advName || contact.name || null,

Verdict: Correct fix. The root cause analysis in the PR description is accurate — ?? only guards against null/undefined, not empty strings. Switching to || properly treats "" as falsy and falls back to the existing stored value.

One minor observation: The logger line at meshcoreManager.ts:1139 still logs data.adv_name ?? '', which could log an empty string and mask the fact that the empty name was discarded. This is cosmetic and doesn't affect correctness, but using updated.advName ?? '' instead would log the actual resolved name and make debug tracing clearer.


Fix 2: CSS color change (MeshCorePage.css:725-726)

/* Before */
.mc-message-route { color: var(--ctp-overlay0); ... }
.mc-message-scope { color: var(--ctp-overlay0); ... }

/* After */
.mc-message-route { color: var(--ctp-surface2); ... }
.mc-message-scope { color: var(--ctp-surface2); ... }

Verdict: Correct. --ctp-surface2 is indeed more muted than --ctp-overlay0 in both dark and light Catppuccin themes — this is a valid visual hierarchy improvement. The adjacent comment explains the intent clearly.


Test coverage (meshcoreManager.contactPersistence.test.ts)

The new regression test at line 268 is well-structured:

  • Establishes an initial named contact
  • Sends a second advert with adv_name: ''
  • Asserts both the in-memory advName and the upsertNode DB call preserve the original name

Minor style note: The test uses await Promise.resolve(); await Promise.resolve(); (double-flush) to settle microtasks, consistent with the rest of the test file. This is acceptable but slightly fragile compared to a proper flush() helper (which is already defined in this file for the notification tests). Consider using await flush() for consistency in future tests — not a blocker for this PR.


Summary

Area Status
Root cause analysis Correct
Fix implementation Correct
CSS change Correct
Regression test Good coverage
No security concerns
No performance concerns

@Yeraze

Yeraze commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

Superseded. The #3769 metadata-contrast half of this PR already shipped in #3778 (time/route/scope set to --ctp-overlay1), so this PR now conflicts on MeshCorePage.css. PRs #3771 and #3772 are also duplicates of each other. The still-relevant part — the #3756 node-name-on-empty-advert fix (??||) — is being re-submitted as a fresh minimal PR rebased on current main with no CSS changes. Closing in favor of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants