Commit Graph
27 Commits
Author SHA1 Message Date
ad692eef74 test(e2e): real-device Playwright messaging suite (#1121)
* fix(connections): connect to the just-added connection via the live store

addConnectionAndConnect() adds a connection and then connects to it in the
same tick, but connect() resolved the id against the memoized `connections`
closure, which is stale until the hook re-renders. The just-added id was
therefore reported as an unknown connection id and Save silently never
connected any HTTP/Serial/Bluetooth device. Read savedConnections from
useDeviceStore.getState() so the lookup always sees the live store.

* test(e2e): real-device Playwright messaging suite

Drives the actual web app in Chromium against real meshtasticd firmware over
the HTTP phone API and verifies text messaging in both directions across a
two-node mesh. Nodes mesh over the firmware's built-in UDP multicast
(224.0.0.69) with no MQTT/relay; distinct node numbers, real encryption.

- Default backend: two Docker meshtasticd sim nodes (daily-debian). The same
  specs run against physical hardware via E2E_DEVICE_MODE=hardware.
- An off-browser Python meshtastic peer (e2e/peer/peer.py) drives/asserts the
  non-browser node over the TCP phone API, mirroring firmware mcp-server tests.
- Coverage: connect over HTTPS, mesh->web receive, web->mesh send. Direct
  messages are fixme'd (see below). CI workflow runs it on Linux.

Bugs surfaced by the suite:
- Fixed (prior commit): connect-on-save never connected (stale-closure id
  lookup in useConnections).
- Not fixed: apps/web/src/core/subscriptions.ts throws 'ReferenceError:
  nodeDB is not defined' on every device-metrics telemetry packet (the #1050
  migration removed that store); caught per-packet, so messaging still works.
- Not fixed: direct messages are blocked by a PKI 'Keys Mismatch' (the SDK's
  stored peer public key != the key presented during NodeInfo exchange), seen
  even with fresh sim nodes.

* test(e2e): address Copilot review feedback

- waitForTcp(): destroy the probe socket on the error path so repeated
  connection failures don't accumulate sockets/FDs across the retry loop.
- Don't remove the mesh containers in Playwright globalTeardown in CI — it
  raced the workflow's failure log capture. Teardown is now gated on
  E2E_DOCKER_DOWN only; CI dumps device logs on failure and tears the mesh
  down in a final always() workflow step.

* fix(sdk): fold device-metrics telemetry into nodes

apps/web/src/core/subscriptions.ts called nodeDB.addDeviceMetrics() on every
device-metrics telemetry packet, but the #1050 migration removed that store —
so it threw 'ReferenceError: nodeDB is not defined' on each telemetry packet
(caught per-packet by the SDK's HandleFromRadio, so messaging still worked but
the error spammed the console).

Route device metrics into the SDK NodesClient via onTelemetryPacket instead —
mirroring the existing position handler; the Node domain already carries a
deviceMetrics field — and drop the dead app-side handler. Adds a NodesClient
test covering the fold.

* docs(e2e): accurate DM root cause + bug status

The direct-message fixme is a simulator limitation, not a web-app bug: the
keyless meshtasticd sim nodes NAK a DM with NO_CHANNEL (routing error 6) — no
Curve25519 keypair is provisioned/shared, and current firmware can't deliver a
direct message without a per-node key / decryptable channel. The app surfaces
this correctly (key-refresh dialog). Re-enable against hardware or once the sim
provisions keys.

Also: mark the nodeDB telemetry bug fixed and note the CI teardown change.

* docs(e2e): precise DM root cause (firmware/sim PKI)

Followed up on the suggestion to provision keys in config.security: the keys
ARE settable and persist (verified via admin), but on the native meshtasticd
sim they don't sync to the node's owner / NodeInfo key — owner.public_key stays
empty and the node keeps its MAC-derived num — so the two nodes never exchange
keys. Combined with the firmware refusing non-PKI DMs ('Unknown public key for
destination ... refusing to send legacy DM'), the DM is NAK'd with NO_CHANNEL.
A firmware/sim limitation; DMs work on real hardware. Spec stays fixme.

* docs(e2e): definitive DM root cause (SimRadio PKC payload limit)

Per the steer to research the firmware: PKI keygen is gated on a set LoRa
region (NodeDB.cpp:3051) and the sim boots region-UNSET — setting lora.region
via admin DOES make the nodes generate and exchange keys (verified both ways).
But a PKI-encrypted DM still can't traverse the SimRadio: the PKC overhead
exceeds its payload limit ('Payload size larger than compressed message allows!
Send empty payload'), so the packet is truncated and the receiver NAKs
NO_CHANNEL ('No suitable channel found for decoding, hash 0x0'). The firmware
skips PKC under --sim (Router.cpp:730) for exactly this reason, but --sim also
disables the config-file loading the web app needs, so they're mutually
exclusive. DMs work on real hardware; spec stays fixme with this detail.

---------

Co-authored-by: Dan Ditomaso <dan.ditomaso@gmail.com>
2026-06-20 11:19:50 -04:00
Ben MeadorsandGitHub cffa7f28ed fix(core): remove orphaned packages/core left by the #1050 squash-merge (#1120)
#1050 (Phase C) deleted packages/core in favor of @meshtastic/sdk, but the
squash-merge hit a delete/modify conflict with #1097 (which had modified
packages/core/package.json and src/meshDevice.ts), leaving those two files
behind as a broken stub. Its package.json still declared a tsdown build
(entry: "mod.ts") while mod.ts and the rest of the source were gone, so the
'Push to Main CI' build-and-package loop failed with:
  Error: Cannot find entry: "mod.ts"

Nothing depends on the workspace @meshtastic/core — the app resolves
@meshtastic/core to the JSR-published @jsr/meshtastic__core@2.6.6 — so finish
the deletion and drop the now-unused pnpm-lock importer.

Verified locally: frozen-lockfile install passes and the full build-and-package
loop builds every package green (sdk, sdk-react, sdk-storage-sqlocal, all
transports).
2026-06-15 17:44:58 -05:00
Ben MeadorsandGitHub 6b298d1648 fix(infra): use apps/web paths in Containerfile after monorepo move (#1110)
The Release Web workflow builds the Docker image with the repo root as
context (file: ./apps/web/infra/Containerfile), but the Containerfile's
ADD/COPY still referenced ./packages/web/dist and
./packages/web/infra/default.conf. After #1097 moved the web app to
apps/web, those paths no longer exist, so buildx failed with
'"/packages/web/infra/default.conf": not found'.

Point both at ./apps/web/. Verified with a local multi-stage docker
build against the apps/web build output.
2026-06-15 15:26:26 -05:00
Ben MeadorsandGitHub bbe9a0d5cd feat(protobufs): sync to firmware-current and consume workspace package (#1097)
* feat(protobufs): sync to firmware-current and consume workspace package

Sync the vendored .proto sources to firmware-current (v2.7.25+48), regenerate the v2 TS bindings, and consume the workspace @meshtastic/protobufs (workspace:*) in place of the stale JSR 2.7.20 — finishing the monorepo migration (core was already workspace:*).

Includes the one required breaking-change fix: admin nodedb_reset changed int32 to bool, so resetNodes() now sends value: true.

* build(protobufs): vendor generated bindings for workspace consumers

The package is consumed via workspace:* — its exports point at the TS source, which imports ./dist/meshtastic/*_pb.ts — so the generated output must exist at build time. CI builds web/core with no codegen step and the runners have no buf CLI, so the bindings are vendored here (kept gitignored; lint/format skip them). Regenerate with: pnpm --filter @meshtastic/protobufs gen

* fix(protobufs): clean script removes the actual generated output dir

buf writes bindings to packages/ts/dist, but clean was removing a non-existent root dist — so it never cleaned stale output. Addresses Copilot review feedback.

* refactor: move web app packages/web -> apps/web

Aligns the web app with the apps/web layout (matching the Vercel web-test Root Directory and the SDK-migration direction). Pure directory move plus root config: pnpm-workspace (adds apps/*), vitest projects, root tsconfig reference, and the pr/release-web/nightly workflows. vercel.json moved with the app. Build + 36 validation tests green.

* feat: config fields, module pages, key verification, telemetry capture

Incorporates the firmware-current feature work onto the protobuf foundation: new config fields (Display message bubbles; LoRa fem_lna_mode + serial_hal_only; Telemetry air_quality_screen_enabled); 4 new ModuleConfig pages (TrafficManagement, StatusMessage, TAK, RemoteHardware); the manual Key Verification flow (sendKeyVerification + ClientNotificationDialog stages + Verify Key button); live telemetry capture (nodeDB addDeviceMetrics) and admin hardening (toggleMutedNode, graceful PortNum default); plus the sdk-preview ConfigEditor demo and store/config tests. Build + lint + format + 131 tests green.

* chore: drop #1062 (unsaved-change-detection) to match upstream revert

#1062 was merged to main by accident (per @danditomaso) and is being reverted. Reverse-applied its diff here via 3-way so #1097 stays consistent with where main is headed, while keeping the feature changes layered on the same files (deviceStore/changeRegistry). Build + 131 tests + lint + format green.

* fix(nodes): clean up SNR display in node table and map popup

SNR is a ratio measured in dB, not dBm (which is absolute power); the
node table and map popup both mislabeled it and crammed three values
together: '0dBm/50%/50raw'. The trailing '%/raw' pair was the same
heuristic ((snr+10)*5) shown twice — once clamped, once not.

Render SNR in dB rounded to one decimal, color-coded by a 0-100%
signal-quality heuristic (green/yellow/red), with the quality percentage
as a muted secondary. Drop the redundant raw value. Adds unit.db; this
matches the existing SNRTooltip, which already renders dB.
2026-06-15 13:23:28 -05:00
Ben MeadorsandGitHub 5b2c25d8ee Try-fix webserial disconnect not actually disconnecting (#796)
* Try-fix webserial disconnects

* Instantiate abort controller on new connection
2025-08-20 11:01:17 -04:00
Ben MeadorsandGitHub 530d33d1e4 Merge pull request #290 from Hunter275/disabled-dynamicform
CI / build-and-package (push) Canceled after 0s
Rework disabled in DynamicForms
2024-09-05 06:19:17 -05:00
Ben MeadorsandGitHub ce60de92fa Merge pull request #236 from Hunter275/issue-235-position-distance
Correctly set position_precision
2024-06-16 06:33:54 -05:00
Ben MeadorsandGitHub daa05eb62d Merge pull request #233 from meshtastic/dependabot/npm_and_yarn/braces-3.0.3
Bump braces from 3.0.2 to 3.0.3
2024-06-15 06:55:38 -05:00
Ben MeadorsandGitHub 8ad1fbaa1c Merge pull request #234 from Hunter275/revert-remove-node-work
revert "remove node work" commit
2024-06-15 06:17:44 -05:00
Ben MeadorsandGitHub 0b1e206702 Merge pull request #203 from PixnBits/chore/pnpm-setup-v4
chore(workflows): use pnpm/action-setup@v4
2024-06-14 20:44:43 -05:00
Ben MeadorsandGitHub a67a0da2d8 Merge pull request #214 from ashokasec/issue-212-dark-mode-toast
Fix issue #212: Change toast text color to white in dark mode
2024-06-14 20:39:37 -05:00
Ben MeadorsandGitHub 258b972320 Merge pull request #210 from fifieldt/add-connection-info
Add Connection info to Nodes Table
2024-06-14 20:37:55 -05:00
Ben MeadorsandGitHub 37ff9cb30c Merge pull request #207 from nojronatron/155-bugfix-adc-mult-override
change validation type to IsNumber
2024-06-14 20:37:29 -05:00
Ben MeadorsandGitHub af6a418b59 Merge pull request #216 from Hunter275/issue-215-battery-level-display
add battery and voltage to sidebar
2024-06-14 20:23:33 -05:00
Ben MeadorsandGitHub 9d2084bd3a Merge pull request #232 from Hunter275/pr-177-duplicate
DUPLICATE: Support for cmdk v1.0.0
2024-06-14 17:11:24 -05:00
Ben MeadorsandGitHub de30cf9248 Merge pull request #218 from Hunter275/issue-217-hop-limit-above-7
hop limit is now a select instead of a number
2024-06-14 16:42:04 -05:00
Ben MeadorsandGitHub 89f0b97492 Merge pull request #220 from Hunter275/issue-219-suffix-overlap
Fix padding on suffix
2024-06-14 16:41:31 -05:00
Ben MeadorsandGitHub 0c28a208f2 Merge pull request #223 from Hunter275/issue-180-qr-code-add-channels
QR Code: Add/Replace query string
2024-06-14 16:41:03 -05:00
Ben MeadorsandGitHub 535f5d97c4 Merge pull request #227 from Hunter275/issue-175-position-precision
Added Position settings per channel
2024-06-14 16:40:36 -05:00
Ben MeadorsandGitHub 90b8250214 Merge pull request #231 from Hunter275/issue-229-search-icon
Swap Search icon
2024-06-14 16:18:58 -05:00
Ben MeadorsandGitHub 3038889a2b Merge pull request #143 from pdxlocations/psk-description
Modify PSK options in description
2023-11-13 20:41:57 -06:00
Ben MeadorsandGitHub 68b207b67f Merge pull request #140 from pdxlocations/url-validation
Fix URL Validation
2023-11-02 09:20:46 -05:00
Ben MeadorsandGitHub 4fd0ab689f Merge pull request #132 from pdxlocations/nodes-on-map
Put the Nodes on the Map!
2023-09-27 13:05:20 -05:00
Ben Meadors aeeaf85dac Lock that down 2023-09-07 18:13:31 -05:00
Ben MeadorsandGitHub 77f0466739 Merge pull request #130 from pdxlocations/updade-js-version
Update js version 2.2.3-1
2023-09-07 17:58:29 -05:00
Ben MeadorsandGitHub d22bcf321b Merge pull request #44 from IZ1IVA/patch-1
Fixed typos
2022-10-15 07:27:52 -05:00
Ben Meadors a5b9e63d8f Format display of lat / lng 2021-05-03 08:36:48 -05:00