feat(meshcore): define a contact's forwarding path by repeater name#3550
Conversation
…efault MeshCore lets you manually define a contact's forwarding path. The previous "Edit Path…" was raw comma-separated hex behind the off-by-default `meshcoreAdvancedPathEdit` toggle. This makes it a first-class, on-by-default feature with a name-aware editor. - New src/utils/meshcorePath.ts: pure helpers mapping repeaters ↔ path hops (a hop is the first byte of the repeater's public key), with name resolution (incl. 1-byte-hash collisions and unknown hops). Unit tested. - MeshCoreContactDetailPanel: "Define Path…" modal now builds the route by picking repeaters/room servers by name (ordered list with ↑/↓/✕), pre-fills from the existing out_path resolving each hop to a name, and keeps a raw-hex byte fallback for repeaters not yet known. Emits the same comma-separated hex chain the API already accepts. - Un-gated: removed the meshcoreAdvancedPathEdit 403 check from the PUT .../out-path route, the panel's advancedPathEditEnabled gate, the DirectMessagesView toggle fetch, and the SettingsTab toggle + the setting key itself. Now gated only by nodes:write + Companion device. - Tests: meshcorePath suite; panel tests (build-by-name save, pre-populate + resolve); route/settings tests updated (403-gate test removed). The backend (set_out_path bridge → meshcore.js setContactPath → CMD_ADD_UPDATE _CONTACT) and the manager's setContactOutPath were already in place; this is the UX + access change on top. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: feat(meshcore): define a contact's forwarding path by repeater nameTasks:
Overall this is a well-scoped, clean PR. The core path-resolution logic is solid and the UX improvement is meaningful. A few issues worth addressing before merge: Bugs / Correctness
export function hopByteForKey(publicKey: string): PathHop {
return publicKey.slice(0, 2).toLowerCase();
}This assumes MeshCore always uses a 1-byte path hash (2 hex chars = 1 byte). The server-side backend at
key={`${byte}-${i}`}Using
Actually re-reading: the route allows Missing Mock:
|
| Category | Finding |
|---|---|
| Bug | Off-by-one in addHop vs handleSaveEditor 64-hop guard |
| Bug | hopByteForKey assumes 1-byte hash width — needs a doc comment or guard |
| Test gap | Missing SourceContext mock in panel tests |
| Test gap | No coverage for custom hex input / reorder buttons |
| Style | Double-OR condition for actions card visibility could be simplified |
The off-by-one in the hop guard and the missing SourceContext mock are the most important to address before merge. The rest is lower priority.
…3550) Claude review feedback on the define-path PR: - Add the SourceContext mock to the panel tests (matches other suites; the panel calls useSource()). - Document hopByteForKey's 1-byte-path-hash assumption and that multi-byte hash widths are out of scope. - Add coverage for the reorder (↑) button and the custom-hex-byte input (invalid rejected, valid added + saved). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — addressed in
Two I'm declining, with reasons:
|
|
Claude finished @Yeraze's task —— View job PR Review: feat(meshcore): define a contact's forwarding path by repeater nameTasks:
This is a clean, well-scoped PR that upgrades the path editor from a hidden raw-hex toggle to a first-class name-aware feature. The items raised in the prior review have been addressed. Here's the updated assessment: What was addressed since last review ✓
Remaining observationsOff-by-one consistency (non-blocking — author declined, reasoning is sound) The Stale warning box always shows (minor UX issue) The amber "Manual paths bypass auto-discovery…" warning in the dialog (
When a repeater appears in the dropdown and is selected twice (e.g. to create a loop), the path editor accepts it without any visual indicator. MeshCore firmware probably rejects or silently ignores loops, but there's no client-side warning. Low priority — real-world paths rarely loop — but worth a follow-up. Missing "cancel closes modal" test (nice-to-have) The previous review flagged this; it was not added. The modal cancel button (
Code quality
Test coverage summary
SecurityNo concerns. Route correctly requires SummaryThe two items from the prior review that were marked as action items ( Verdict: ready to merge with the optional |
Finalize the 4.11.0 release (from 4.11.0-rc2) and bring documentation up to date with everything new since 4.10. Version bump across all five files: package.json, package-lock.json, helm/meshmonitor/Chart.yaml, desktop/src-tauri/tauri.conf.json, desktop/package.json. Documentation: - CHANGELOG: finalize the Unreleased section as [4.11.0], adding the previously-missing entries — headline MeshCore virtual node (#3540), MeshCore path-by-repeater-name (#3550), MeshCore map icons + filtering (#3563), per-node Hide from Map (#3565), telemetry time-range selector (#3530), newer AirQualityMetrics fields (#3517), UI/map unification (#3561), plus the bug-fix and documentation changes since 4.10.4. - virtual-node.md: document the new MeshCore Virtual Node alongside the Meshtastic one (default port 5000, per-source enablement, admin-command safety, MeshCore app setup, troubleshooting) + a two-variants intro note. - configuration/index.md, docs/index.md, README.md: mention the MeshCore Virtual Node in the Virtual Node feature blurbs. - CLAUDE.md: refresh stale version header (4.10.0 -> 4.11.0) and migration count (84 -> 92, latest 092_add_hide_from_map_to_nodes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
MeshCore lets a user manually define a contact's forwarding path (the
out_path— the ordered list of repeater hops a message takes). MeshMonitor already had the backend for this, but the UI was a raw comma-separated hex input hidden behind an off-by-defaultmeshcoreAdvancedPathEdittoggle. This makes it a first-class, on-by-default feature with a name-aware editor that mirrors the MeshCore app's flow.What changed
Name-based path editor (
MeshCoreContactDetailPanel):out_path, resolving each hop byte back to a repeater name (or "Unknown (0x..)" for repeaters you haven't met).PUT .../out-pathroute accepts — no backend protocol change.New helper (
src/utils/meshcorePath.ts): pure functions mapping repeaters ↔ hops. A hop is the first byte of the repeater's public key (MeshCore's default 1-byte path hash). Handles hash collisions and unknown hops. Unit-tested.Enabled by default (toggle removed):
meshcoreAdvancedPathEdit403 gate from thePUT .../out-pathroute.advancedPathEditEnabledgate and the DM view's toggle fetch.meshcoreAdvancedPathEditsetting key entirely.nodes:write+ a Companion device (unchanged access model otherwise).Testing
meshcorePathunit suite (parse/join/resolve, name resolution + collisions).tscclean for touched files.Not in this PR
The backend stack (
set_out_pathbridge → meshcore.jssetContactPath→CMD_ADD_UPDATE_CONTACT, and the manager'ssetContactOutPath) already existed — this is the UX + access-model change on top.A separate, pre-existing issue (not touched here): the MeshCore DM contact list is sourced from
getContacts()(the device's in-memory companion contact list) rather than the richer observed-node list, which can show a sparse/unnamed set on some sources. To be investigated in a follow-up PR.🤖 Generated with Claude Code