Commit Graph
56 Commits
Author SHA1 Message Date
kamilkrzywda eda1cbd125 Add #rss command family with LLM tags and summaries (v0.20.0)
CI / build + unit (pull_request) Successful in 1m15s
#rss subcommands on the command channel: help / add <url> <name> /
remove <name> / tags / sources / get <name|#tag>. Sources are stored in
a new rss_sources table in the existing MESH_DB_PATH file (second
node:sqlite connection, case-insensitive names); feeds parsed with
fast-xml-parser (RSS 2.0 + Atom); AI tags and headline summaries via
injected LlmService.chat() with bounded maxTokens (50/200).

CommandService gains prefix registration so one handler owns the whole
#rss family while #ping stays an exact match; wired in CommandModule's
factory — still no constructor-level cycle, no forwardRef. One dead feed
does not sink a tag summary.
2026-09-25 18:44:06 +00:00
kamilkrzywda 023cd3eef3 Merge pull request 'Add OpenAI-compatible LLM client service (v0.19.0)' (#40) from feat/llm-client into main
CI / build + unit (push) Successful in 40s
Add OpenAI-compatible LLM client service (v0.19.0) (#40)
v0.19.0
2026-09-25 20:09:32 +02:00
kamilkrzywda c5a2815c01 Add OpenAI-compatible LLM client service (v0.19.0)
CI / build + unit (pull_request) Successful in 1m14s
LlmService wraps the local OpenAI-compatible server (default
http://192.168.1.70:1111/v1, no auth) with native fetch only — no new
dependencies. listModels() -> data[].id; chat(messages, opts?) ->
choices[0].message.content (non-2xx throws with status + body snippet);
summarize(text) = chat() with a concise-summary system prompt.

Env: LLM_API_BASE / LLM_MODEL (qwen3.8-27b) / LLM_TIMEOUT_MS (60000,
AbortSignal.timeout). Plain feature module wired into app.module.ts;
docs synced (AGENTS.md, README env list).
2026-09-25 18:07:21 +00:00
kamilkrzywda 55e59d4963 Merge pull request 'Route command replies through respond() — same channel, threaded quote (v0.18.1)' (#39) from fix/command-replies-respond into main
CI / build + unit (push) Successful in 1m10s
v0.18.1
2026-09-25 19:32:31 +02:00
kamilkrzywda 9d4c9594af Route command replies through MeshService.respond() — same channel, threaded quote (v0.18.1)
CI / build + unit (pull_request) Successful in 42s
2026-09-25 17:30:28 +00:00
kamilkrzywda d375f2a943 Merge pull request 'v0.18.0: channel-2 auto-responder with extensible #command boilerplate' (#38) from feat/channel2-autoresponder into main
CI / build + unit (push) Successful in 1m16s
v0.18.0
2026-09-25 19:14:15 +02:00
kamilkrzywda 931b42bb1e Add channel-2 #command auto-responder (v0.18.0)
CI / build + unit (pull_request) Successful in 41s
Event-driven CommandService dispatches exact case-sensitive #command
matches on COMMAND_CHANNEL (default 2) through a single-registration-point
registry; first command #ping -> #pong!. Replies ride COMMAND_CHANNEL:
directed DM back to the sender when present, else broadcast. Failing
handler/send only logs a warn.

DI: CommandModule's factory injects MeshService and attaches itself via
MeshService.attachCommands() — a constructor-level cycle leaves one side
null in NestJS 12's injector (verified), so no forwardRef is used.

Tests 106 -> 121; docs synced (AGENTS.md, MESHTASTIC.md, README).
2026-09-25 17:11:52 +00:00
kamilkrzywda 2b2e494023 Merge pull request 'Multi-channel notify gate + ch0 DM-only filtering (v0.17.0)' (#37) from feat/multi-channel-notify into main
CI / build + unit (push) Successful in 40s
v0.17.0
2026-09-25 18:21:16 +02:00
kamilkrzywda 4ae932befe mesh: MESH_NOTIFY_CHANNEL as comma-separated list + ch0 DM-only notify gate; v0.17.0
CI / build + unit (pull_request) Successful in 1m8s
2026-09-25 16:18:07 +00:00
kamilkrzywda ff57f3eae1 Merge pull request 'v0.15.0+v0.16.0: /api/respond reply endpoint + message-id in notifier wrapper, GET /api/forwarded ring' (#36) from feat/respond-endpoint into main
CI / build + unit (push) Successful in 1m17s
v0.16.0
2026-09-25 17:53:55 +02:00
kamilkrzywda b7b2044d84 mesh: GET /api/forwarded — last 100 messages forwarded to opencode; v0.16.0 docs
CI / build + unit (pull_request) Successful in 41s
2026-09-25 15:51:43 +00:00
kamilkrzywda e62f831ee5 mesh: in-memory ring of the last 100 messages forwarded to opencode 2026-09-25 15:48:09 +00:00
kamilkrzywda bd18bdfd8a docs: v0.15.0 changelog, README/AGENTS respond + notifier wrapper updates, version bump 2026-09-25 15:39:52 +00:00
kamilkrzywda c33f4613b5 mesh: POST /api/respond + MCP respond tool — reply to a message by packet id 2026-09-25 15:32:34 +00:00
kamilkrzywda 88b617f8b7 opencode: notifier wrapper gains the packet id (id <n>) 2026-09-25 15:06:31 +00:00
kamilkrzywda 34e7bfe0bb mesh: persist destination (to) on captured rx history records 2026-09-25 15:02:21 +00:00
kamilkrzywda b677c05681 Merge pull request 'v0.14.0 — in-process opencode notifier replaces the forwarder service' (#35) from feat/opencode-notifier into main
CI / build + unit (push) Successful in 42s
v0.14.0
2026-09-25 16:17:39 +02:00
kamilkrzywda 83e47c9609 docs+changelog: v0.14.0 — in-process opencode notifier replaces the forwarder
CI / build + unit (pull_request) Successful in 1m0s
2026-09-25 14:14:37 +00:00
kamilkrzywda 5eb1a79e70 mesh: replace notify webhook with in-process opencode notifier; drop forwarder service 2026-09-25 14:14:37 +00:00
kamilkrzywda 7d7c569d08 opencode: add in-process OpencodeService notifier (port of ops/forwarder) 2026-09-25 14:06:25 +00:00
kamilkrzywda c0c069ef08 Merge pull request 'Battery alerts → testowy channel (ch2) — v0.13.1' (#34) from fix/battery-alert-channel into main
CI / build + unit (push) Successful in 39s
v0.13.1
2026-09-25 15:04:11 +02:00
kamilkrzywda 1b712f7eee battery: send alerts on channel "testowy" (index 2), not the pinned send channel
CI / build + unit (pull_request) Successful in 1m0s
Owner request. BatteryAlertService reads new env BATTERY_ALERT_CHANNEL
(default 2) at construction and passes it through MeshService.sendText,
which gains an optional trailing channel argument defaulting to the
pinned MESH_SEND_CHANNEL — every other sender is untouched. Threshold,
cooldown, merged one-message-per-cycle format and @mentions unchanged.
2026-09-25 13:02:56 +00:00
kamilkrzywda 6f6b704dcf Merge pull request 'v0.13.0 — battery-low alert module (merged broadcasts, @mentions, cooldown)' (#33) from feat/battery-alerts into main
CI / build + unit (push) Successful in 43s
v0.13.0
2026-09-25 14:53:01 +02:00
kamilkrzywda fe8d2dbe0b battery: merge multiple low-battery nodes into one broadcast per cycle
CI / build + unit (pull_request) Successful in 1m0s
Owner follow-up: 'if multiple ppl shows at once — merge messages to one'.
check() now collects every qualifying node (at/below threshold and not
within its per-node cooldown) and sends AT MOST ONE broadcast per cycle
containing all of them, recording the alert timestamp for each after
sending; nothing is sent when none qualify. Format: '⚠️ battery low:
@!<hex> (<name>) <X>%[, @!<hex> (<name>) <Y>%]' — single-node case uses
the same one-entry template. Cooldown semantics unchanged.
2026-09-25 12:51:25 +00:00
kamilkrzywda d0b71e6e91 battery: low-battery alert module (v0.13.0)
BatteryAlertModule + BatteryAlertService wired into app.module like
the weather module. Every BATTERY_CHECK_INTERVAL_MS (default 60 s) the
service scans the node state backing GET /api/nodes and broadcasts a
single-packet '⚠️ @!<8-hex> battery low: <X>% (<name>)' alert for every
node at or below BATTERY_ALERT_THRESHOLD percent (default 20, <= on
purpose) not alerted within BATTERY_ALERT_COOLDOWN_MS (default 6 h,
in-memory map — resets on restart). Sends ride the pinned send channel
via MeshService.sendText like every other bot send.
2026-09-25 12:39:45 +00:00
kamilkrzywda 8ddd91d4b5 mesh: update node batteryLevel from live NODEINFO_APP packets
battery_level was only populated during the initial sync; NodeInfo
frames streamed as NODEINFO_APP (port 4) now refresh deviceMetrics in
the node database so /api/nodes and downstream consumers see current
values between syncs. decodeNodeInfo + PORT_NODEINFO_APP added to the
codec, one branch in the existing packet-handling path.
2026-09-25 12:39:45 +00:00
kamilkrzywda 6ce0b1ae7b MESHTASTIC.md: questions get their answer on the channel (owner standing rule) (#32)
CI / build + unit (push) Successful in 20s
v0.12.8
2026-09-25 14:09:10 +02:00
kamilkrzywda 15d93ec2a4 Optional replyId on send (API + MCP) — protocol-level threaded replies (#31)
CI / build + unit (push) Successful in 33s
v0.12.7
2026-09-25 13:53:47 +02:00
kamilkrzywda 0909fbc6e2 MESHTASTIC.md: back to channel-only replies (no DMs) (#30)
CI / build + unit (push) Successful in 33s
v0.12.6
2026-09-25 13:00:05 +02:00
kamilkrzywda b8ae5d39f7 MESHTASTIC.md: reply to senders as DMs; always respond before starting work (#29)
CI / build + unit (push) Successful in 33s
v0.12.5
2026-09-25 12:52:11 +02:00
kamilkrzywda 5999159e17 Forwarder: resolve opencode workspace/session dynamically per request (#28)
CI / build + unit (push) Successful in 32s
v0.12.4
2026-09-25 12:24:39 +02:00
kamilkrzywda 36021ec2e8 Retry notify webhook POST with backoff (2 s / 10 s / 30 s) before dropping (#27)
CI / build + unit (push) Successful in 1m2s
v0.12.3
2026-09-25 11:48:39 +02:00
kamilkrzywda dca0dfa894 Run notify forwarder as a compose service (host networking, restart policy) (#26)
CI / build + unit (push) Successful in 19s
v0.12.2
2026-09-25 10:49:51 +02:00
kamilkrzywda 5e03546f40 Fix weather module DI (MeshService export + value import) and pass WEATHER_CRON through compose (#25)
CI / build + unit (push) Successful in 31s
v0.12.1
2026-09-25 10:01:38 +02:00
kamilkrzywda 261f7ed18c Hourly cron weather report for Lublin (Open-Meteo) broadcast on mesh (#24)
CI / build + unit (push) Successful in 1m5s
v0.12.0
2026-09-25 09:48:03 +02:00
kamilkrzywda 180a9ce134 Add MESHTASTIC.md communication rules + AGENTS.md mention (#23)
CI / build + unit (push) Successful in 1m5s
v0.11.3
2026-09-25 09:37:30 +02:00
kamilkrzywda d3d1913b83 Self-echo filter for notify webhook (skip own-node messages) (#22)
CI / build + unit (push) Successful in 43s
v0.11.2
2026-09-25 08:51:03 +02:00
kamilkrzywda 3d0e369230 Notify webhook also fires for injected messages (channel match) + compose env passthroughs (#21)
CI / build + unit (push) Successful in 35s
v0.11.1
2026-09-25 03:56:53 +02:00
kamilkrzywda 024dabda97 Outbound notification webhook (MESH_NOTIFY_URL) on RX text — issue #17 (#20)
CI / build + unit (push) Successful in 36s
v0.11.0
2026-09-25 03:35:50 +02:00
kamilkrzywda 74f3080626 Persist message history to SQLite with 1s poller (#15) (#19)
CI / build + unit (push) Successful in 1m4s
v0.10.0
2026-09-25 02:46:17 +02:00
kamilkrzywda 756086d107 Inbox injection endpoint: POST /api/messages + MCP inject_message (#12) (#18)
CI / build + unit (push) Successful in 1m14s
v0.9.0
2026-09-25 01:51:50 +02:00
kamilkrzywda 0571c7095e Telemetry stream: GET /api/telemetry + MCP get_telemetry (#16)
CI / build + unit (push) Successful in 21s
v0.8.0
2026-09-24 23:56:11 +02:00
kamilkrzywda ba5e60daf0 Fix BigInt serialization in GET /api/device (500 on real hardware) (#14)
CI / build + unit (push) Successful in 18s
v0.7.1
2026-09-24 23:14:32 +02:00
kamilkrzywda 4beaa377c4 Device info endpoint + richer node summaries (GET /api/device, MCP device_info) (#13)
CI / build + unit (push) Successful in 36s
v0.7.0
2026-09-24 22:46:40 +02:00
kamilkrzywda b31fb35464 MCP server at POST /mcp (official SDK, stateless Streamable HTTP) (#11)
CI / build + unit (push) Successful in 1m6s
v0.6.0
2026-09-24 20:39:45 +02:00
kamilkrzywda 108aa400d3 Publish on 'test' channel (index 3) by default (#10)
CI / build + unit (push) Successful in 34s
v0.5.0
2026-09-24 19:44:11 +02:00
kamilkrzywda f640f6658c Send to by node name or broadcast sentinel (GET-free resolution via node DB) (#9)
CI / build + unit (push) Successful in 33s
v0.4.0
2026-09-24 16:47:51 +02:00
kamilkrzywda 57ad27d66f Message history with delivery tracking (GET /api/messages) (#8)
CI / build + unit (push) Successful in 32s
v0.3.0
2026-09-24 16:19:32 +02:00
kamilkrzywda 5292303786 Node database: collect nodes during sync, expose GET /api/nodes (#7)
CI / build + unit (push) Successful in 39s
v0.2.0
2026-09-24 15:37:03 +02:00
kamilkrzywda adfbc9800b Send want_config_id on connect to trigger initial sync (#6)
CI / build + unit (push) Successful in 39s
Send want_config_id on connect to trigger initial sync (#6)

Firmware only streams myInfo/channels/configComplete after receiving a
ToRadio with want_config_id — the service previously wrote nothing on
connect, so /api/channels stayed [] and myNodeNum null. v0.1.4.
v0.1.4
2026-09-23 22:42:03 +02:00