Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
244 commits
Select commit Hold shift + click to select a range
15b4741
Added compatibility with LilyGo T-Deck-Pro V1.1
lewisxhe Jan 21, 2026
e7b6628
Merge branch 'master' into master
thebentern Apr 16, 2026
edf660c
Update variants/esp32s3/t-deck-pro-v1_1/variant.h
thebentern Apr 16, 2026
5cae9e0
Update src/platform/extra_variants/t_deck_pro/variant.cpp
thebentern Apr 16, 2026
7d957f8
Update variants/esp32s3/t-deck-pro-v1_1/platformio.ini
thebentern Apr 16, 2026
d5af07e
Update src/main.cpp
thebentern Apr 16, 2026
79e7ed3
Update src/graphics/EInkDisplay2.cpp
thebentern Apr 16, 2026
c48b5ab
Merge branch 'master' into master
thebentern Apr 17, 2026
2c8dec2
Update meshtastic/device-ui digest to 56e1da4 (#10195)
renovate[bot] Apr 18, 2026
aab4cd0
Compass improvements/refactoring (#10166)
HarukiToreda Apr 18, 2026
c8dac10
Add MCP server for interacting with meshtastic devices and testing fr…
thebentern Apr 18, 2026
34aa5e9
Fix: prompt markdownlint md040 fix for new prompts. (#10199)
h3lix1 Apr 18, 2026
d31d0f8
Added compatibility with LilyGo T-Deck-Pro V1.1
lewisxhe Jan 21, 2026
d0cd8ec
Update variants/esp32s3/t-deck-pro-v1_1/variant.h
thebentern Apr 16, 2026
2beebea
Update src/platform/extra_variants/t_deck_pro/variant.cpp
thebentern Apr 16, 2026
84bb909
Update variants/esp32s3/t-deck-pro-v1_1/platformio.ini
thebentern Apr 16, 2026
9e26cc3
Update src/main.cpp
thebentern Apr 16, 2026
a277108
Update src/graphics/EInkDisplay2.cpp
thebentern Apr 16, 2026
e589de2
Tronk
thebentern Apr 18, 2026
8fd0a7f
Merge branch 'master' into master
thebentern Apr 18, 2026
6b15571
Add MCP server for interacting with meshtastic devices and testing fr…
thebentern Apr 18, 2026
de23e51
Add USB camera and uhubctl support for new test suite. Also included …
thebentern Apr 19, 2026
6c04c37
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 19, 2026
f396200
Add authoring guide for native unit tests in README.md (#10201)
NomDeTom Apr 19, 2026
d50caf2
Add encryption overview to agent instructions in AGENTS.md (#10207)
thebentern Apr 19, 2026
8627bce
Upgrade trunk (#10125)
github-actions[bot] Apr 20, 2026
eba74fa
Update GxEPD2 to v1.6.9 (#10212)
renovate[bot] Apr 21, 2026
4090d9f
SX126x: re-apply 0x8B5 register in resetAGC() to preserve RX sensitiv…
nightjoker7 Apr 21, 2026
84ce1ea
SX126x: re-apply 0x8B5 register in resetAGC() to preserve RX sensitiv…
nightjoker7 Apr 21, 2026
63bce1f
fix(nodedb): force null-terminate name fields in UserLite/User conver…
jaime-roldan Apr 21, 2026
5d9a256
fix(nodedb): force null-terminate name fields in UserLite/User conver…
jaime-roldan Apr 21, 2026
e1f5043
Delete PointerQueue::dequeuePtrFromISR, unused since commit db766f1 (…
cpatulea Apr 10, 2026
23321c4
Reduce key duplication by enabling hardware RNG (#8803)
Komzpa Apr 13, 2026
f5be09c
Add Luckfox Pico Max Waveshare Pico LoRa config (#10175)
Ruledo Apr 16, 2026
25febfd
More cleanly remove LED_BUILTIN (#10179)
jp-bennett Apr 16, 2026
d8e4389
No longer need undefines, thanks to #10179 (#10180)
jp-bennett Apr 17, 2026
0e38a15
Update protobufs (#10223)
github-actions[bot] Apr 21, 2026
a8a5315
Upgrade trunk (#10221)
github-actions[bot] Apr 21, 2026
945f478
BaseUI: Nodelist screen/favorite screen cleanup (#10197)
HarukiToreda Apr 21, 2026
5f836cd
Added support for Spreading Factors 5 and 6 on compatible radios (#10…
derpyspike Apr 14, 2026
d7ba178
Fix: prompt markdownlint md040 fix for new prompts. (#10199)
h3lix1 Apr 18, 2026
76dea77
Add authoring guide for native unit tests in README.md (#10201)
NomDeTom Apr 19, 2026
68383c8
Add encryption overview to agent instructions in AGENTS.md (#10207)
thebentern Apr 19, 2026
3b4c664
feat(t5s3-epaper): add InkHUD port for LilyGo T5 E-Paper S3 Pro (#10211)
giannoug Apr 21, 2026
9361b85
feat(t5s3-epaper): add InkHUD port for LilyGo T5 E-Paper S3 Pro (#10211)
giannoug Apr 21, 2026
db9fdd6
Fix: filter out SKIPPED tests in PlatformIO output to improve log cla…
NomDeTom Apr 21, 2026
2b5daf2
T watch pinfix (#10231)
jp-bennett Apr 22, 2026
b53fe7a
T watch pinfix (#10231)
jp-bennett Apr 22, 2026
fb1de11
Update LovyanGFX to v1.2.20 (#10232)
renovate[bot] Apr 22, 2026
a710841
Upgrade trunk (#10236)
github-actions[bot] Apr 22, 2026
a4b55bc
cardputer-adv: Move variant.cpp -> extra_variants/variant.cpp (#10242)
vidplace7 Apr 22, 2026
fcb9ec0
t5s3-epaper: Move variant.cpp -> extra_variants/variant.cpp (#10241)
vidplace7 Apr 22, 2026
d8b11f0
Improve options to align to names of UI options (#10240)
Xaositek Apr 22, 2026
28e705d
Detach power interrupts for sleep (#10230)
jp-bennett Apr 22, 2026
6171ad8
Remove duplicate GPIO init block in setup() from bad merge in PR #9378
thebentern Apr 23, 2026
a6b1a69
StoreForwardModule::historyAdd: memcpy source size, not buffer capaci…
nightjoker7 Apr 23, 2026
92c0133
Finish evil merge cleanup (#10253)
jp-bennett Apr 23, 2026
4b49147
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 23, 2026
7c27f4e
Revert "Update LovyanGFX to v1.2.20 (#10232)" (#10269)
caveman99 Apr 23, 2026
4c24218
Revert "Update LovyanGFX to v1.2.20 (#10232)" (#10269) (#10270)
caveman99 Apr 23, 2026
66971a0
RadioLibInterface: clear static `instance` on destruction to prevent …
nightjoker7 Apr 23, 2026
48747ee
Upgrade trunk (#10266)
github-actions[bot] Apr 23, 2026
399dde0
Router: demote cross-channel decrypt failures from ERROR to DEBUG (#1…
nightjoker7 Apr 23, 2026
55bf8c2
PhoneAPI: add missing tak_tag case + skip reserved gap in module-conf…
nightjoker7 Apr 23, 2026
cde5a08
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 23, 2026
22d50fe
NimbleBluetooth misc cleanups (#10264)
cpatulea Apr 23, 2026
031f332
We have HardwareRNG, let's use it! (#10274)
jp-bennett Apr 23, 2026
2ed7bba
fix(Power): refactor EXT_CHRG_DETECT to compile-time macros (#10191)
ndoo Apr 23, 2026
2cc13a1
Sane sanitization
thebentern Apr 23, 2026
b2d980f
feat(Power): support EXT_PWR_DETECT_MODE & EXT_PWR_DETECT_VALUE, simp…
ndoo Apr 23, 2026
56c897e
Can't LOG when we don't have logging set up yet in the native test suite
thebentern Apr 23, 2026
7b3f588
Fix example comment in airtime.h (#10275)
VBart Apr 23, 2026
837637b
Only enable wakeup via EXT_CHRG_DETECT if we shut down due to low pow…
jp-bennett Apr 23, 2026
83a98c8
Hash table index for O(1) packet history lookups (#9499)
rcd Apr 23, 2026
d919594
PositionModule::sendLostAndFoundText: use stack buffer, eliminate hea…
nightjoker7 Apr 23, 2026
5ea3d14
Update meshtastic-esp8266-oled-ssd1306 digest to 6bfd1f1 (#10277)
renovate[bot] Apr 24, 2026
924411d
T-Watch S3 Power button managment (#9855)
Emanuele-Mb Apr 24, 2026
ba9cadc
Fix INA226 detection for non-TI compatible chip (Silergy) (#10247)
theKorzh Apr 24, 2026
7adfc3f
Remove incorrect LED_STATE_ON definition for t-beam-s3 (#10280)
jp-bennett Apr 24, 2026
8e65312
Upgrade trunk (#10284)
github-actions[bot] Apr 24, 2026
04b819a
Remove incorrect LED_STATE_ON definition for t-beam-s3 (#10280)
jp-bennett Apr 24, 2026
d47301d
Add PortduinoSetOptions to overwrite the realhardware bool (#10157)
jp-bennett Apr 14, 2026
439b87b
Detach power interrupts for sleep (#10230)
jp-bennett Apr 22, 2026
9306e66
fix(inkhud): scale MapApplet markers with fontSmall line height (#10288)
giannoug Apr 25, 2026
7421953
InkHUD: Add full touch support to T5s3 (#10286)
HarukiToreda Apr 25, 2026
55f1507
Update protobufs (#10295)
github-actions[bot] Apr 25, 2026
7347091
Add script to show unmerged commits from develop to master
thebentern Apr 25, 2026
e7c02da
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 25, 2026
a8c8fd7
Remove redundant power interrupt methods for ESP32
thebentern Apr 25, 2026
2828dbe
t5s3-epaper: Move variant.cpp -> extra_variants/variant.cpp ...again …
vidplace7 Apr 25, 2026
fb678b9
Update platform-native digest to 135b91e (#10300)
renovate[bot] Apr 25, 2026
554188e
Fix main function to setup and loop for Unity test framework
thebentern Apr 25, 2026
7800dc3
Enhance UTF-8 sanitization logic and add delays in test setup for rel…
thebentern Apr 25, 2026
0bd8dee
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 25, 2026
aec0805
Trying another guard approach
thebentern Apr 25, 2026
4d4e146
Merge remote-tracking branch 'origin/master' into develop
thebentern Apr 25, 2026
4ccdd80
Add search duration check for exceeding 15 minutes (#10293)
jp-bennett Apr 26, 2026
8dde4ee
BaseUI: Color Support for TFT Nodes (#10233)
HarukiToreda Apr 26, 2026
b148fac
Update framework version reference for Adafruit nRF52 to latest maste…
thebentern Apr 26, 2026
24c4162
Standardize PMU IRQ handling and enable power button cancel on tbeam-…
jp-bennett Apr 27, 2026
bfadf0c
fix(Router): localize p_encrypted to prevent recursive-overwrite leak…
nightjoker7 Apr 27, 2026
87f1f9d
fix(Router): localize p_encrypted to prevent recursive-overwrite leak…
nightjoker7 Apr 27, 2026
06a6c3e
Native MacOS hello world (#10309)
thebentern Apr 27, 2026
47a6c4c
Upgrade trunk (#10317)
github-actions[bot] Apr 27, 2026
126861f
Native MacOS hello world (#10309)
thebentern Apr 27, 2026
4234fe6
Update meshtastic/device-ui digest to 7289329 (#10313)
renovate[bot] Apr 27, 2026
048e518
Update platform-native digest to 4ea5e09 (#10314)
renovate[bot] Apr 27, 2026
bc17d00
Merge branch 'master' into develop
thebentern Apr 27, 2026
f037ce2
add heltec-v4-r8 board (#10268)
Quency-D Apr 27, 2026
d7db0f5
add heltec-v4-r8 board (#10268)
Quency-D Apr 27, 2026
c0425d7
Actions: Build MacOS binary (#10319)
vidplace7 Apr 27, 2026
6c7ffa1
macOS: enable CH341 LoRa-hardware path (fix serial truncation, docume…
thebentern Apr 28, 2026
9c72767
macOS: enable CH341 LoRa-hardware path (fix serial truncation, docume…
thebentern Apr 28, 2026
8d8ff21
Add clamping logic for milliseconds conversion and unit tests (#10326)
thebentern Apr 29, 2026
11df30a
Upgrade trunk (#10324)
github-actions[bot] Apr 29, 2026
c0e52e6
Update meshtastic/device-ui digest to 1ddcc9d (#10328)
renovate[bot] Apr 29, 2026
22a9346
Debian: Correctly fail upon failure (#10341)
vidplace7 Apr 29, 2026
9ec63b5
Upgrade trunk (#10336)
github-actions[bot] Apr 29, 2026
7be5426
Do not FACTORY_INSTALL on ARCH_PORTDUINO (#10343)
vidplace7 Apr 29, 2026
089af76
Replace FSCom.format() with FSCom.rmDir() for directory cleanup in No…
thebentern Apr 29, 2026
195f42a
Doesn't FSCom
thebentern Apr 29, 2026
ad23c42
Update meshtastic/device-ui digest to 4bf593a (#10346)
renovate[bot] Apr 30, 2026
478444e
Docker-Alpine: Align version between build/main stages (#10347)
vidplace7 Apr 30, 2026
3a87fc8
Add documentation for macOS support in Copilot and Agent instructions
thebentern Apr 30, 2026
24d64a0
Docker: Build for riscv64 (#10345)
vidplace7 Apr 30, 2026
e19f531
Update Screen.cpp (#10344)
HarukiToreda Apr 30, 2026
a0951f2
fix: MQTT connection on Portduino/Linux native nodes (#10330)
WB3IHY Apr 30, 2026
83adfd4
Upgrade trunk (#10354)
github-actions[bot] Apr 30, 2026
173ac58
Update protobufs (#10357)
github-actions[bot] Apr 30, 2026
989b862
Merge remote-tracking branch 'origin/master' into develop
jp-bennett Apr 30, 2026
21cef8c
Add TCP support for Meshtastic MCP interface / tests and update docs …
thebentern Apr 30, 2026
7066abb
Fix MAC_from_string to use input parameter instead of global config f…
thebentern Apr 30, 2026
4ee9598
Docker: Install grpcio-tools from distro (#10358)
vidplace7 Apr 30, 2026
1eb860a
fix(stm32wl,nrf52,fs): flash hardening, FS platform unification, writ…
ndoo May 1, 2026
90744ee
Update PhoneAPI.cpp to reduce chattiness (#10367)
Xaositek May 1, 2026
55f40ec
Add ulfius webserver support to macos native target (#10366)
thebentern May 1, 2026
c0fcf80
MacOS: Correct pkg-config name `openssl` for ulfius. (#10369)
vidplace7 May 1, 2026
0240a00
MacOS: Re-Add Orcania/Yder
vidplace7 May 1, 2026
b7a9555
Update RadioLib dependency to a specific commit (#10370)
jp-bennett May 1, 2026
7cb071c
Update platform-native digest to cab4b21 (#10372)
renovate[bot] May 1, 2026
2d761f6
Upgrade trunk (#10364)
github-actions[bot] May 2, 2026
41f5317
Use OBS instead of launchpad (#10375)
thebentern May 2, 2026
b2bda3b
Enable MESHTASTIC_PREHOP_DROP by default (#9924)
Jord-JD May 2, 2026
6ea0d5e
Add TFT_BACKLIGHT_ON for cardputer to fix builds (#10387)
jp-bennett May 4, 2026
bb86cf4
Merge remote-tracking branch 'origin/master' into develop
jp-bennett May 4, 2026
d559af8
Update LovyanGFX to v1.2.21 (#10373)
renovate[bot] May 5, 2026
fcef46f
dependency swap - INA3221Sensor (#10379)
NomDeTom May 5, 2026
603cce2
Add informSearchFailed method to update GPS power state handling (#10…
thebentern May 5, 2026
cdc47a2
Fix GPS initialization logic for Portduino configuration (#10395)
jessm33 May 5, 2026
6e81074
Fix GPS initialization logic for Portduino configuration (#10395)
jessm33 May 5, 2026
220bb4d
Smart pointers and memory management cleanup (#10400)
thebentern May 6, 2026
33e2bb7
Enhance GPS search failure handling backoff logic (#10404)
thebentern May 7, 2026
b246bcd
Update libpax digest to df42474 (#10406)
renovate[bot] May 7, 2026
b11d29f
fix(mesh): update reconfigure methods to return true instead of RADIO…
NomDeTom May 7, 2026
784e374
Merge remote-tracking branch 'origin/master' into develop
thebentern May 7, 2026
4553d1e
Skip MQTT allocation when disabled (#10411)
h3lix1 May 7, 2026
0f85486
Give ThinkNode-m4 a heartbeat (#10408)
jp-bennett May 7, 2026
5e2ca8a
LR2021 radio on NRF_Promicro (#10401)
NomDeTom May 8, 2026
a8a785b
Upgrade trunk (#10418)
github-actions[bot] May 8, 2026
5512185
Make heartbeat LED play nice with other LEDs (#10423)
jp-bennett May 8, 2026
f63716c
Automated version bumps (#10419)
github-actions[bot] May 9, 2026
b4234b7
Automated version bumps (#10419)
github-actions[bot] May 9, 2026
fefd424
Fix screen geometry update for SH1107 display (#10444)
Bjk8kds May 9, 2026
10a7f10
Fix screen geometry update for SH1107 display (#10444)
Bjk8kds May 9, 2026
1bcabb8
mesh: bound the user-facing notification sprintf calls (#10437)
DatanoiseTV May 9, 2026
94bb21e
2.8: NodeDB shrink, decoupling, and restructuring (#10413)
thebentern May 9, 2026
f6a954b
Implement rotating JSONL recorder for persistent logging (#10428)
thebentern May 10, 2026
d79e62f
Chatty LLMs should pipe down
thebentern May 10, 2026
33319aa
Upgrade trunk (#10451)
github-actions[bot] May 11, 2026
9bc25b3
Add guidance to use Throttle for time-based rate limiting in agent in…
thebentern May 11, 2026
dfcb685
Update protos
thebentern May 11, 2026
0522039
Merge branch 'master' into develop
thebentern May 11, 2026
a23f923
Update subproject commit reference in protobufs
thebentern May 11, 2026
8877608
Protos
thebentern May 11, 2026
8e99ffb
ThinkNode M7 (#8077)
caveman99 May 11, 2026
da61a0d
Refactor mutex handling in PhoneAPI.cpp
jp-bennett May 11, 2026
64fd617
ThinkNode M7 (#8077)
caveman99 May 11, 2026
4446b0f
Add variantDefaultConfig and set eth_enabled to default true (#10454)
jp-bennett May 11, 2026
59b4993
Update protobufs (#10456)
github-actions[bot] May 11, 2026
1c06b70
Merge remote-tracking branch 'origin/master' into develop
jp-bennett May 11, 2026
7f51842
Make power status logging less chatty and track battery presence tran…
thebentern May 11, 2026
811dd42
Update protobufs
thebentern May 11, 2026
b074645
Change node pointer to const in JsonSerialize function
thebentern May 11, 2026
b960121
BaseUI: remove legacy single-message runtime path and keep multimessa…
HarukiToreda May 12, 2026
f7548e7
Remove gradient sync nonce and simplify replay handling (#10459)
thebentern May 12, 2026
cd5d608
Upgrade trunk (#10461)
github-actions[bot] May 12, 2026
7ff6641
Fix missing potential null termination in xmodem filename handling (#…
dirkmueller May 12, 2026
d9cb74e
XModemAdapter: ensure file truncation before receiving and add isBusy…
thebentern May 12, 2026
f3ae02c
Cleanup comments
thebentern May 12, 2026
eead467
Added NodeDB fixtures and refactored to use std maps for better memor…
thebentern May 12, 2026
29a61dc
Fix type declaration for ambientLightingThread and correct uint32_t u…
thebentern May 13, 2026
0a7b3c7
Update NeoPixel to v1.15.5 (#10466)
renovate[bot] May 13, 2026
593909c
Radiolib excludes
thebentern May 13, 2026
039ad42
Fix WiFi TCP/HTTP services not starting without USB serial connected …
tanrax May 13, 2026
5f734da
Trunk
thebentern May 13, 2026
8110887
Turns out it's already excluded
thebentern May 13, 2026
59025e4
Add initial support for Station G3 variant (#10457)
thebentern May 13, 2026
75b7a7d
Missed one
thebentern May 13, 2026
4c3ba61
VSCode: Prepare for pioarduino transition (#10471)
vidplace7 May 13, 2026
c756bbe
Fix WiFi TCP/HTTP services not starting without USB serial connected …
tanrax May 13, 2026
1ae4a53
Trunk
thebentern May 13, 2026
778d1ad
Merge remote-tracking branch 'origin/master' into develop
thebentern May 13, 2026
748668b
Remove ARIAL24 on NRF52
thebentern May 13, 2026
9cd3a86
Cleanup
thebentern May 13, 2026
5a1d2b9
Refine nRF52 flash optimization comment for FONT_LARGE_LOCAL definition
thebentern May 13, 2026
8711945
Ble banner (#8902)
jp-bennett May 13, 2026
cbddf07
Merge pull request #10472 from meshtastic/remove-arial
thebentern May 13, 2026
35b0590
Develop is 2.8 WIP now
thebentern May 13, 2026
7bdff8f
Bump protos
thebentern May 13, 2026
3a0c08b
Merge pull request #10474 from meshtastic/2.8
thebentern May 14, 2026
fce419b
Upgrade trunk (#10476)
github-actions[bot] May 14, 2026
4827498
Clamp direct position packets to channel precision (fixes #8640) (#10…
Jord-JD May 15, 2026
1c05633
Add more support for small fonts in screen resolution determination (…
thebentern May 15, 2026
2a91d18
Add max_session_seconds to LockdownAuth for session management
thebentern May 15, 2026
0570707
Update libch341-spi-userspace digest to 2e5ff75 (#10485)
renovate[bot] May 16, 2026
502c5af
Upgrade trunk (#10481)
github-actions[bot] May 16, 2026
4a1ff18
feat: add Nordic nRF54L15-DK variant (Zephyr + BLE + LoRa) (#10193)
cvaldess May 16, 2026
fc5556b
Clamp direct position packets to channel precision (fixes #8640) (#10…
Jord-JD May 15, 2026
767a748
add optional LED_LORA to indicate LoRa TX (#10465)
jp-bennett May 17, 2026
a541957
ESP32: Migrate to Arduino 3.x (pioarduino) (#9122)
vidplace7 May 17, 2026
3261c04
Fix Antenna Switch on Cardputer (#10491)
caveman99 May 18, 2026
6199faa
cherry pick backport fix for cardputer
caveman99 May 18, 2026
0148a89
Upgrade trunk (#10493)
github-actions[bot] May 19, 2026
af3739f
Update protobufs (#10499)
github-actions[bot] May 19, 2026
23ead5f
Update protobufs (#10500)
github-actions[bot] May 19, 2026
98e0604
Fix antenna switch initialization logic once more
caveman99 May 19, 2026
0832330
Fix antenna switch initialization logic
caveman99 May 19, 2026
622aa04
Enabled SX_LNA_EN by default (#10469)
RikerZhu May 19, 2026
1747e2d
T-Echo-Card support (#10267)
caveman99 May 19, 2026
e2aa44e
T-Echo-Card support (#10267)
caveman99 May 19, 2026
0f9eb86
Enabled SX_LNA_EN by default (#10469)
RikerZhu May 19, 2026
82aefd1
Upgrade trunk (#10503)
github-actions[bot] May 19, 2026
4304480
Merge remote-tracking branch 'origin/master' into develop
thebentern May 19, 2026
00ec692
Develop protos should be on develop
thebentern May 19, 2026
8d08077
Add Ethernet configuration to platformio.ini for ThinkNode variants
thebentern May 20, 2026
2f92eb8
Refactor position precision handling to honor explicit channel settin…
thebentern May 20, 2026
894c555
Actions: Fix tagging upon release. (#10521)
vidplace7 May 21, 2026
f3cb2bf
Refactor keyboard cell height logic for consistency (#10501)
Bjk8kds May 21, 2026
5e69bc6
Enable Narrow and Lite regions for EU (#10120)
NomDeTom May 21, 2026
e10e132
nrf54l15: fix SHT4x libdep -- arduino-sht, not Adafruit_SHT4X (#10515)
cvaldess May 21, 2026
f2c5cb0
fix: first set pinMode, then write to pin (#10520)
kpmy May 21, 2026
91f930d
fix(telemetry): stop emitting -0.001V sentinel when battery unavailab…
jaime-roldan May 22, 2026
c7748a1
Fix update neighbor_info before checking update_interval in handleSet…
thebentern May 22, 2026
ef734b7
fix: mbed TLS crash in Arduino 3.x (pioarduino) (#10535)
mverch67 May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
49 changes: 49 additions & 0 deletions .claude/commands/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Claude Code slash commands for the mcp-server test suite

Three AI-assisted workflows wrapping `mcp-server/run-tests.sh` and the meshtastic MCP tools. Each one has a twin in `.github/prompts/` for Copilot users.

| Slash command | What it does | Copilot equivalent |
| --------------------- | ------------------------------------------------------------------------- | ---------------------------------------- |
| `/test [args]` | Runs the test suite (auto-detects hardware) and interprets failures | `.github/prompts/mcp-test.prompt.md` |
| `/diagnose [role]` | Read-only device health report via the meshtastic MCP tools | `.github/prompts/mcp-diagnose.prompt.md` |
| `/repro <test> [n=5]` | Re-runs one test N times, diffs firmware logs between passes and failures | `.github/prompts/mcp-repro.prompt.md` |

## Why two surfaces

The Claude Code commands and Copilot prompts cover the same three workflows but each speaks its host's idiom:

- **Claude Code** (`/test`) uses `$ARGUMENTS` for pass-through, has direct access to Bash + all MCP tools registered in the user's settings, and runs in the terminal context.
- **Copilot** (`/mcp-test`) runs in VS Code's agent mode; it has terminal + MCP access too but typically asks the operator to confirm inputs interactively.

A contributor using either IDE gets equivalent assistance. Keep the two in sync when behavior changes — the diff of intent should be minimal.

## House rules

- **No destructive writes without explicit operator approval.** Skills that could reflash, factory-reset, or reboot a device must describe the action and stop — the operator authorizes.
- **Interpret failures, don't just echo them.** The skill body should pull firmware log lines from `mcp-server/tests/report.html` (the `Meshtastic debug` section, attached by `tests/conftest.py::pytest_runtest_makereport`) and classify the failure.
- **Keep MCP tool calls sequential per port.** SerialInterface holds an exclusive port lock; two parallel tool calls on the same port deadlock.
- **Never speculate about root cause.** If the evidence doesn't support a classification, say "unknown" and list what you'd need to disambiguate.

## Adding a new command

1. Write the Claude Code version at `.claude/commands/<name>.md` with YAML frontmatter:

```yaml
---
description: one-line purpose (used for auto-invocation by the model)
argument-hint: [optional-hint]
---
```

2. Write the Copilot equivalent at `.github/prompts/mcp-<name>.prompt.md` with:

```yaml
---
mode: agent
description: ...
---
```

3. Add the row to the table above. Cross-link in both bodies.

4. Smoke-test on Claude Code first (`/<name>` should appear in autocomplete), then in VS Code Copilot (`/mcp-<name>` in Chat).
68 changes: 68 additions & 0 deletions .claude/commands/diagnose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
description: Produce a device health report using the meshtastic MCP tools (device_info, list_nodes, get_config, short serial log capture)
argument-hint: [role=all|nrf52|esp32s3|<port>]
---

# `/diagnose` — device health report

Call the meshtastic MCP tool bundle and format a structured health report for one or all detected devices. Zero guesswork for the operator.

## What to do

1. **Enumerate hardware.** Call `mcp__meshtastic__list_devices(include_unknown=True)`. For each entry where `likely_meshtastic=True`, capture `port`, `vid`, `pid`, `description`.

2. **Filter by `$ARGUMENTS`**:
- No args, `all` → every likely-meshtastic device.
- `nrf52` → only devices with `vid == 0x239a`.
- `esp32s3` → only devices with `vid == 0x303a` or `vid == 0x10c4`.
- A `/dev/cu.*` path → only that one port.
- Anything else → treat as a substring match against the `port` string.

3. **For each selected device, in sequence (NOT parallel — SerialInterface holds an exclusive port lock):**
- `mcp__meshtastic__device_info(port=<p>)` — captures `my_node_num`, `long_name`, `short_name`, `firmware_version`, `hw_model`, `region`, `num_nodes`, `primary_channel`.
- `mcp__meshtastic__list_nodes(port=<p>)` — count of peers, which ones have `publicKey` set, SNR/RSSI distribution.
- `mcp__meshtastic__get_config(section="lora", port=<p>)` — region, preset, channel_num, tx_power, hop_limit.
- Optionally, if the device seems unhappy (fails to connect, `num_nodes==1` when ≥2 are plugged in, missing firmware*version), open a short firmware log window: `mcp__meshtastic__serial_open(port=<p>, env=<inferred-env>)`, wait 3s, `serial_read(session_id=<s>, max_lines=100)`, `serial_close(session_id=<s>)`. The env should be inferred from the VID map in `mcp-server/run-tests.sh` (nrf52 → rak4631, esp32s3 → heltec-v3) unless `MESHTASTIC_MCP_ENV*<ROLE>` is set.

4. **Hub health** (call once, not per-device): `mcp__meshtastic__uhubctl_list()` — enumerates every USB hub the host can see. Note which hubs advertise `ppps=true` and which hub hosts each Meshtastic device (cross-reference by VID). Flag it in the report if:
- No hub advertises PPPS → `tests/recovery/` can't run on this setup; hard-recovery via `uhubctl_cycle` isn't available.
- A Meshtastic device is on a non-PPPS hub → note it; operator may want to move the device to a PPPS hub to unlock auto-recovery.
- `uhubctl_list` raises `ConfigError: uhubctl not found` → just say `uhubctl not installed` in the report; don't treat as a fault.

5. **Render per-device report** as:

```text
[nrf52 @ /dev/cu.usbmodem1101] fw=2.7.23.bce2825, hw=RAK4631
owner : Meshtastic 40eb / 40eb
region/band : US, channel 88, LONG_FAST
tx_power : 30 dBm, hop_limit=3
peers : 1 (esp32s3 0x433c2428, pubkey ✓, SNR 6.0 / RSSI -24 dBm)
primary ch : McpTest
hub : 1-1.3 port 2 (PPPS, uhubctl-controllable)
firmware : no panics in last 3s; NodeInfoModule emitted 2 broadcasts
```

Keep it scannable. If a field is missing or abnormal (no pubkey for a known peer, region=UNSET, num_nodes inconsistent with the hub, device on non-PPPS hub), flag it inline with a short `⚠︎ <one-line reason>`.

6. **Cross-device correlation** (only when >1 device is inspected):
- Do both sides see each other in `nodesByNum`? If one does and the other doesn't, that's asymmetric NodeInfo — flag it.
- Do the LoRa configs match? (region, channel_num, modem_preset should all agree; mismatch = no mesh)
- Do the primary channel NAMES match? Mismatch = different PSK = no decode.

7. **Recorder slice (cheap, always available).** The mcp-server runs an autouse log recorder that's been collecting from every connected device. Pull two short slices to surface anything weird that's already happened:
- `mcp__meshtastic__logs_window(start="-2m", level="WARN|ERROR|CRIT", max_lines=20)` — recent firmware errors. If empty, say "no recent errors"; don't manufacture concern.
- `mcp__meshtastic__telemetry_timeline(window="1h", field="free_heap", max_points=60)` — heap trend. If `slope_per_min < -50`, flag it and recommend `/leakhunt window=6h` for a deeper read; otherwise just note the current free heap.
- If `recorder_status` shows `running:false` or `files.telemetry.last_ts` is null, note "recorder has no telemetry yet — enable `set_debug_log_api(True)` to populate" and skip this step gracefully.

8. **Suggest next actions only for specific, recognisable failure modes**:
- Stale PKI pubkey one-way → "run `/test tests/mesh/test_direct_with_ack.py` — the retry + nodeinfo-ping heals this in the test path."
- Region mismatch → "re-bake one side via `./mcp-server/run-tests.sh --force-bake`."
- Device unreachable, reachable via DFU → `touch_1200bps(port=...)` + `pio_flash`. If not even DFU responds AND the device is on a PPPS hub, escalate to `uhubctl_cycle(role=..., confirm=True)`.
- CP2102-wedged-driver on macOS → see the note in `run-tests.sh`.
- Heap slope strongly negative → "run `/leakhunt window=6h` for a full timeline + classification."

## What NOT to do

- No writes. No `set_config`, no `reboot`, no `factory_reset`. This is a read-only diagnostic skill — if the operator wants to change state, they'll ask explicitly.
- No `flash` / `erase_and_flash`. Those are separate escalations.
- No holding SerialInterface across tool calls — open, query, close; next device. The port lock is exclusive.
103 changes: 103 additions & 0 deletions .claude/commands/leakhunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
description: Hunt for memory leaks (and other slow degradations) by reading the persistent recorder's heap timeline + log slice over a window
argument-hint: [window=1h] [field=free_heap] [variant=local]
---

<!-- markdownlint-disable MD029 -->

# `/leakhunt` — read the recorder, classify a memory leak

Use the always-on recorder (`mcp-server/.mtlog/`) to read a heap timeline plus the matching log slice and produce a one-page verdict: **steady / slow leak / fragmentation / OOM-imminent**. No firmware changes, no special build flags — the LocalStats telemetry packet that the firmware already broadcasts every ~60 s carries `heap_free_bytes` and `heap_total_bytes`.

## Two signal paths — pick the right one

| Path | Build flag | Cadence | Per-thread attribution | Cost |
| --------------------- | ---------------- | -------------- | ---------------------- | ------------------------- |
| LocalStats packet | (default) | ~60 s | No | Free — always on |
| `[heap N]` log prefix | `-DDEBUG_HEAP=1` | every log line | Yes (Thread X leaked) | Bigger flash + log volume |

Both feed the same `telemetry_timeline(field="free_heap")` query — when DEBUG_HEAP is on, the recorder synthesizes telemetry rows from log prefixes (tagged `source: debug_heap`), so a single timeline call gets whichever signal is available. **For a slow leak diagnosis, the default path is plenty** (60 s cadence over 6 h = 360 points; linear regression over that nails sub-100-byte/min slopes). **DEBUG_HEAP is for attribution** — when the slope is real and you need to know which thread is leaking.

## What to do

1. **Parse `$ARGUMENTS`**: optional `window` (default `1h`, accepts `30m`/`6h`/`-3d`/etc.), optional `field` (default `free_heap`; alternates: `total_heap`, `battery_level`, anything in the LocalStats variant), optional `variant` (default `local`; alternates: `device`, `environment`, `power`, `airQuality`, `health`).

2. **Verify the recorder is alive** — call `mcp__meshtastic__recorder_status`. Check:
- `running == True`
- `files.telemetry.lines > 0` (at least one telemetry packet recorded — if zero, the device hasn't broadcast LocalStats yet OR `set_debug_log_api` has never been on; tell the operator to run `mcp__meshtastic__set_debug_log_api(enabled=True)` and wait one device-update interval)
- `files.telemetry.last_ts` within the last 5 minutes (if older, the device is silent — log that, not "leak detected")

3. **Detect whether DEBUG_HEAP is active** — `mcp__meshtastic__logs_window(start="-2m", grep=r"\\[heap \\d+\\]", max_lines=3)`. If any line matches, the firmware has the prefix → DEBUG_HEAP is on, expect higher-cadence data and `heap_event` rows. If zero matches over the last 2 minutes, you're on the LocalStats-only path.

4. **Pull the timeline** — `mcp__meshtastic__telemetry_timeline(window=$window, variant=$variant, field=$field, max_points=200)`. Read:
- `samples` — how many raw points contributed
- `min`, `max` — total swing
- `slope_per_min` — units per minute (linear regression over the whole window)

5. **Pull the log context for the same window** — `mcp__meshtastic__logs_window(start="-${window}", grep="Heap status|leaked heap|freed heap|out of memory|Alloc an err|panic|abort", max_lines=200)`. These are the strings the firmware emits when something memory-related happens (`DEBUG_HEAP` builds emit `"Heap status:"` and `"leaked heap"` lines; production builds emit `"Alloc an err"` on failure and `"out of memory"` on OOM).

6. **Pull marker events** so we know if the operator labeled phases — `mcp__meshtastic__events_window(start="-${window}", kind="mark|connection_lost|connection_established")`. If a `connection_lost` overlaps a sharp drop, that's not a leak; that's a reboot.

6a. **(DEBUG_HEAP only) Per-thread attribution** — `mcp__meshtastic__logs_window(start="-${window}", grep="leaked heap", max_lines=200)`. Each row has a structured `heap_event` field with `{kind, thread, before, after, delta}`. Aggregate by thread: sum the `delta` over the window per thread name. The thread with the largest cumulative negative delta is your suspect. Note the count too — a thread with 50× small leaks is different from 1× big leak.

7. **Classify** based on what the data says, NOT on what you wish it said. Use these rules in order:
- **Insufficient data** (< 5 samples): say so. Suggest a longer window or longer wait. Stop.
- **Reboot mid-window**: if any `connection_lost` event is present AND `free_heap` jumped UP at that timestamp, the device rebooted. Note it; pre-reboot trend may be a leak but you only have part of the curve.
- **OOM-imminent**: any `Alloc an err=` or `out of memory` line in the log slice. This trumps everything; flag urgently.
- **Slow leak**: `slope_per_min < -50` AND `max - min > 1000` AND no reboot. The heap is monotonically (or near-monotonically) declining. Estimate time-to-zero: `min / -slope_per_min` minutes. Surface it.
- **Fragmentation suspect**: `slope_per_min` close to zero (|x| < 50) BUT min trends down across the window AND the log slice shows `Alloc an err` warnings WITHOUT total OOM. Means free total is OK but largest contiguous block is shrinking. Recommend a `DEBUG_HEAP` build to confirm.
- **Steady**: |slope_per_min| < 50, no error lines. Heap is fine.
- **Recovery curve**: slope is POSITIVE — heap recovered. Either a workload completed or GC fired. Note it; not a leak.

8. **Report**:

```text
/leakhunt window=6h field=free_heap variant=local
────────────────────────────────────────────────────
recorder : running, telem last_ts 8s ago
build : DEBUG_HEAP=ON (per-line prefix detected)
samples : 14,200 over 6h (cadence ~1.5s, log-line synth)
free_heap : min 92,344 / max 124,008 / range 31,664
slope : -82 bytes/min (negative — heap declining)
reboots : none in window
OOM events : none
error lines : 3× "Alloc an err=ESP_ERR_NO_MEM" at +4h12m, +5h08m, +5h44m
thread leaks : (DEBUG_HEAP) MeshPacket -3,124 B over 18 events
Router -1,408 B over 4 events
others -240 B
verdict : SLOW LEAK — primary suspect MeshPacket thread
est. time-to-OOM: ~1,127 min (~18.8 h) at current slope
evidence : (3 log line citations with uptimes)
```

Then: **what to do next.**
- SLOW LEAK, **DEBUG_HEAP off** → recommend rebuilding with the flag and re-running this skill. Concrete one-liner the operator can copy:
```text
mcp__meshtastic__build(env="<env>", build_flags={"DEBUG_HEAP": 1})
mcp__meshtastic__pio_flash(env="<env>", port="<port>", confirm=True)
```
After flash, set debug_log_api back on and wait one window; re-run `/leakhunt`.
- SLOW LEAK, **DEBUG_HEAP on** → cite the top-leaking thread name from step 6a. Point at the corresponding source file (`grep -rn "ThreadName(\"<name>\")" src/`); the operator decides what to fix.
- FRAGMENTATION SUSPECT → propose pre-allocating any per-packet buffers; or rebuilding with `CONFIG_HEAP_TASK_TRACKING=y` on ESP32 to see who's holding the largest blocks.
- OOM-IMMINENT → flag for immediate attention; don't wait for the next telemetry interval.
- STEADY → say so; stop. Don't invent problems.

## What NOT to do

- Don't assume a leak from a single dip. LocalStats fires every ~60 s and the firmware naturally allocates+frees on each broadcast cycle; one packet sees the trough. Look at the slope, not the deltas.
- Don't recommend code changes. This skill diagnoses; the operator decides what to fix.
- Don't enable `set_debug_log_api` automatically — if it's off, telemetry isn't reaching pubsub anyway, and the recorder will be empty. Tell the operator to flip it on and wait, then re-run.
- Don't run heavy workloads to "trigger the leak." The recorder is passive; we read what's there.

## Companion: `mark_event` for stress runs

If the operator wants to test under stimulus (e.g. blast 50 broadcasts and see what the heap does), they can frame the experiment with markers:

```text
mark_event("burst-start")
… run the workload …
mark_event("burst-end")
/leakhunt window=15m
```

The markers land in both `events.jsonl` and `logs.jsonl`, so the report can show "free_heap dipped 8 KB during the burst window, recovered to baseline within 2 LocalStats cycles" → not a leak.
Loading