Skip to content

Releases: OwlShack/OwlBot

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 01:11
v1.3.0
7de9636

v1.3.0 - 2026-10-09

Warning

meshcore-bot is now OwlBot. Updating needs a manual step, or you stay on v1.2.0.

  • Docker: ghcr.io/meshcore-go/meshcore-bot gets no more updates. Pulling it keeps you on
    v1.2.0 with no error. Switch to ghcr.io/owlshack/owlbot.
  • Downloads: release files are now OwlBot-<os>-<arch>. A script that fetches the latest
    meshcore-bot-* file gets a 404.
  • The program is OwlBot. Update service files, scripts and pgrep lines that name
    meshcore-bot, and a Docker command that runs it by name.
  • MQTT: model and client_version now say OwlBot. Update any dashboard or filter that
    matches on meshcore-bot.
  • The repository moved to OwlShack/OwlBot. Old links
    redirect.

Your config file, mqtt_identity.key, bot identities and MQTT topics carry over unchanged. See
Upgrading below.

Baseline v1.2.0. The bot is renamed OwlBot, templates can print dates and times, and it is
built on meshcore-go v1.7.0.

Added

  • Templates can print dates and times. {{date now "15:04"}} gives the current time, and
    {{date .Timestamp "15:04"}} when a channel message was sent. An optional zone such as
    "Pacific/Auckland" sets the time zone, and works the same on every platform.
  • Posts can be scoped to a MeshCore region. floodScope = "region:nz" on a bot or a trigger
    sends its posts so only repeaters that allow #nz pass them on. Unset stays unscoped, as before.
  • Each MQTT broker can set its own topics. packetTopic and statusTopic take {iata},
    {pubkey} and {name}, for brokers that expect a different layout. Unset keeps the current
    topics.
  • Choose how path hashes are joined. {{formatPathBytes .PathHashes " > "}} gives
    A1 > B2 > C3 instead of the default A1, B2, C3.

Changed

  • meshcore-bot is renamed OwlBot. The binary, release downloads and Docker image carry the
    new name. Your config file and mqtt_identity.key carry over as they are, so every bot keeps
    its mesh identity and the MQTT observer keeps its public key.
  • MQTT status reports model as OwlBot. client_version is now OwlBot/<version>.
  • Built on meshcore-go v1.7.0. The bot's own messages go out at firmware transmit priorities
    rather than queuing behind relayed traffic, and it ignores packets firmware discards, such as
    encrypted payloads that are not whole AES blocks.

Fixed

  • The MQTT status says online again as soon as a broker reconnects. When the link drops, the
    broker publishes the bot as offline. It used to stay that way until the next status, up to 5
    minutes later, even though the bot was back.
  • Packets dropped while a broker is down are now logged. They are still not buffered, but a
    warning says when a broker starts dropping them, and the count is logged when it reconnects.
    Before, they went missing without a word, including any heard in the moment before the first
    connection.

Upgrading

  • Docker: switch the image to ghcr.io/owlshack/owlbot. ghcr.io/meshcore-go/meshcore-bot
    stays at v1.2.0. If you mounted only config.toml, copy mqtt_identity.key out of the old
    container first, or the observer starts with a new identity. The README has the command.
  • Binary: replace it with an OwlBot-* download and change any service file or script that
    runs meshcore-bot. Run it from the same directory as before.

What's Changed

Full Changelog: v1.2.0...v1.3.0

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 04:50
5322fab

v1.2.0 - 2026-09-30

Baseline v1.0.6. openHop Modems and SPI radio hats join KISS firmware, the MQTT status now uses
the firmware's own names and meanings, and brokers stay connected through outages and token
refreshes.

Config adds the openhop:// and spi:// connections and the spiBoard, modemToken and
dutyCycle settings. nodeType is no longer needed.

Added

  • openHop Modems. Connect with openhop:///dev/ttyUSB0 over USB, or openhop://host:port
    over the network with modemToken as its password. The modem's radio is set to MeshCore's
    settings on every connect, and a dropped link reconnects on its own.
  • SPI radio hats on a Raspberry Pi. Connect with spi:// and choose the hat by name with
    spiBoard, from 15 SX1262 hats, the same list OwlShack has. A tx above the hat's rating is
    refused rather than turned down. To add a hat or correct one, put a boards.json in the
    directory the bot runs from.
  • Packets the bot sends appear on MQTT. Each one is published with "direction": "tx", as
    firmware nodes publish theirs. Signal fields are left off, since there is no received signal to
    report.
  • Received packets carry score, duration and path. score and duration match the
    firmware's packet log. path is the source and destination prefixes, as the firmware prints them,
    not the route.
  • The status reports more of what the firmware does. mcu_temp_c, last_snr, last_rssi,
    rx_air_secs, tx_air_secs, flood_tx and direct_tx are new in stats, and repeat is new
    at the top level. mcu_temp_c is left out on a board without a temperature sensor.
  • The status reports transmit and receive faults. New counters in stats show packets
    retried, dropped or failed, and whether the channel was busy or the bot sent faster than the radio
    could keep up. They count everything this process sends and receives, not one bot.
  • SPI hats and openHop Modems report chip-level errors. crc_errors, driver_errors and
    recv_recoveries appear in stats where the radio can measure them, and are left out on KISS.
  • dutyCycle limits how much of the time the radio transmits. It is a percentage, like the
    firmware's set dutycycle, and takes fractions such as 0.1 for EU868 sub-bands. The default is
    unchanged, and the duty cycle in use is logged at startup.
  • Slow message handling is logged and counted. One slow reply holds up every bot's receiving,
    so any that takes over half a second is logged and counted in stats.handler_slow.
  • The bot reconnects a radio that is lost. An unplugged modem, a dropped link, or a radio that
    stops answering for about 90 seconds is reconnected on its own, with retries up to every 30
    seconds, and the bots and MQTT status come back with it. Before, the bot kept running but heard
    and sent nothing until it was restarted.

Changed

  • recv_errors now means what it means on a firmware node. It counts packets the radio
    failed to receive. It used to count packets that arrived intact but did not decode, which is now
    packet_parse_errors. Firmware nodes publish recv_errors to the same brokers, so the two now
    agree.
  • battery_percent is replaced by stats.battery_mv. The firmware reports millivolts, and the
    old percentage showed 100% on boards with no battery. battery_mv is left out when the board has
    no battery or has stopped answering.
  • noise_floor moved into stats. It sits with the other radio readings, as the firmware
    reports it.
  • stats.packets_received is now stats.recv, with stats.packets_recv beside it. These are
    the names the firmware and CoreScope use. stats.sent is published alongside
    stats.packets_sent.
  • SNR and RSSI are left out when a packet arrives without them. They used to read 0, which
    looked like a real measurement.
  • The connection chooses the radio. nodeType is ignored, so an existing config still loads
    and it can be deleted.

Fixed

  • A broker that is down at startup is retried. It used to be dropped until the bot was
    restarted or reloaded. It is now retried with a growing delay, up to 5 minutes.
  • Startup no longer waits for brokers. Each unreachable broker could hold up startup for 10
    seconds. The bot now starts at once and connects in the background.
  • Shutdown and reload no longer hang on an unresponsive broker. The last status sent on the way
    down now gives up after 5 seconds rather than waiting forever.
  • A failed token refresh no longer leaves a broker disconnected. The broker used to stay
    down for 6 minutes or more. It now reconnects straight away.
  • Refreshing a token no longer makes the connection flap. The old connection is closed before
    it can push the new one off.
  • packets_sent and queue_len report real values. Both read 0 on every status since v1.0.6.
  • Every counter in a status is taken at the same moment. A packet arriving mid-report could
    show recv: 2 beside a last_rssi of 0.
  • Sends that meet a busy radio are retried again. They had been given up on at the first try.
  • Long packets at slow radio settings are no longer counted as failed. The bot now waits as
    long as the packet takes on air, rather than a fixed time that the largest packets could outlast.
  • A modem that stops answering no longer shows its last battery and temperature. They are left
    out once it has been silent for 45 seconds.
  • A packet that failed to send no longer appears on MQTT as sent.
  • A config mistake on reload keeps the running config. An unknown connection used to stop the
    bot. It is now refused when the config loads, as is spi:// without spiBoard.

Upgrading

  • If you read this node's MQTT status, check recv_errors first. It keeps its name but changes
    meaning, and nothing on the wire marks the change. A rate or delta over it will jump at the
    upgrade. Use packet_parse_errors if you wanted the old count.
  • Other MQTT fields to check: battery_percent is gone, noise_floor has moved into stats,
    stats.packets_received is now stats.recv, and SNR, RSSI, battery_mv and mcu_temp_c
    can be absent.
  • Building from source needs Go 1.26.7.

What's Changed

Full Changelog: v1.0.6...v1.2.0

v1.1.0-alpha.4

v1.1.0-alpha.4 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 30 Jun 04:33
v1.1.0-alpha.4
2446ccc

Highlights

  • Map: neighbor-link SNR topology overlay — draw repeater-to-repeater links colored by signal strength (#13)
  • Monitoring: poll retries are now bounded (configurable max attempts + delay) and fall back to the normal interval instead of re-polling an unreachable node forever (#14)
  • Packets: server-side type filter + hash/path search (#12); Peers: search by pubkey (#11)
  • Internal: context propagation, error hardening, package splits, chat delta-paging, first unit tests (#9, #10)

What's Changed

New Contributors

Full Changelog: v1.1.0-alpha.3...v1.1.0-alpha.4

v1.1.0-alpha.3

v1.1.0-alpha.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 Jun 10:34
v1.1.0-alpha.3
6d7af79

Offline-first hardening on top of alpha.2.

Pre-release. Not promoted to latest, and the stable v1.0.x line is unaffected.

Offline-first fonts

  • No more Google Fonts CDN. Inter and JetBrains Mono are now self-hosted: the latin variable-weight woff2 files are vendored and embedded directly in the binary, served same-origin via @font-face. The app no longer fetches anything from the internet, which matters for air-gapped / LAN deployments and behind locked-down proxies. A single variable file per family covers every weight the app uses. (Also removed two dead, unreferenced font files.)

PWA installable behind an auth proxy

  • Works through SSO / auth gateways (e.g. Pangolin). Browsers fetch the web app manifest without the session cookie by default, so an auth proxy returned a login redirect and the manifest failed to parse, leaving the console marked "not installable." The manifest link now requests with credentials (crossorigin="use-credentials"), so it authenticates like the rest of the app and the Install button appears as expected. The self-hosted fonts help here too: they are now same-origin assets that pass the proxy with the page's cookie.

Full changelog: v1.1.0-alpha.2...v1.1.0-alpha.3

v1.1.0-alpha.2

v1.1.0-alpha.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 Jun 05:33
v1.1.0-alpha.2
13ba9a3

Second alpha in the v1.1 line. Headline: richer in-app chat, on-demand companion adverts, and the web console is now installable as a PWA.

Pre-release. Not promoted to latest, and the stable v1.0.x line is unaffected.

Chat

  • @-mention autocomplete. Typing @ in a channel or room composer pops up name suggestions drawn from that conversation's participants (not your whole contact list), like emoji autocomplete.
  • #hashtag channel chips. Hashtags in messages (e.g. #weather) now render as clickable chips that either offer to add the channel or jump straight to it if you already have it. Adding a channel from a message now selects the newly added thread instead of dropping you on an empty chat screen.

Companions

  • Advert triggers. Send a Flood or Zero-hop advert for a companion on demand. Surfaced as header chips on desktop and folded into a single overflow menu on mobile so the header stays tidy on small screens.
  • Sidebar sub-navigation. The sidebar now lists your companions, so jumping between chats is one click on both desktop and mobile.

Monitoring

  • POLL on the node detail page. The on-demand poll button now lives on the individual node view, not just the monitoring list.

PWA (Phase 1: installability)

  • The web console is now an installable app via a hand-rolled service worker and web app manifest (no Workbox). An Install button appears in the sidebar when the browser offers it. Navigations are network-first and content-hashed assets are cache-first, so it never serves a stale build. No push notifications yet.

Fixes

  • Never flood a node we can reach directly. A peer reachable directly is stored as a 0-hop path, which the send paths previously treated the same as an unknown route and flooded, needlessly rebroadcasting across the whole mesh. Direct neighbours (0-hop) and known multi-hop paths now route direct; only a genuinely unknown route floods. Covers monitoring polls (status/telemetry/neighbours), repeater login and CLI, and companion ACKs. (DMs still flood 0-hop neighbours pending a meshcore-go library release.)

Under the hood

  • CLI command / config-key catalogue extracted to a JSON data file for easier reuse and maintenance.
  • Shared AddChannelDialog plus channel/node API helpers extracted to cut duplication.
  • Tailwind arbitrary-value classes canonicalized, with the convention documented for future contributors.

Full changelog: v1.1.0-alpha.1...v1.1.0-alpha.2

v1.1.0-alpha.1

v1.1.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Jun 04:03
v1.1.0-alpha.1
2ddb7e7

First pre-release of the 1.1 line — a near-complete rewrite. The bot gains a
full web UI, moves all configuration into SQLite, and is now distributed under
the OwlShack name. This is an alpha: expect rough edges and please
report issues.

Highlights

  • New web UI (React SPA at :8080). Operator-console aesthetic over a
    single embedded static binary — no separate frontend to host.
  • Configuration lives in SQLite, not files. A first-run setup wizard
    bootstraps a node; config files become one-time imports. Per-resource config
    screens (Radio, MQTT, Companions, Bots/triggers) edit one thing at a time and
    reload in place — most changes apply with no restart and no dropped sessions.
  • Rebrand to OwlShack.

Web UI

  • Overview / Peers / Map — live peer count and type spectrum, searchable
    peer table, Leaflet map of geolocated peers with type filters and GPS
    track visualization (altitude-colored).
  • Packets — live stream grouped by hash with a detail panel (route, hops,
    signal, observation timeline, raw hex).
  • Trace — interactive path builder + result timeline.
  • Companions → chat — channels and DMs per companion, with delivery status,
    retry, and reply/quote affordances.
  • Contacts / Channels / Repeaters — per-companion management.
  • Repeater Detail — login, status telemetry, CLI terminal with
    autocomplete, neighbours, and a full settings panel (radio, position map
    picker, advert intervals, routing, owner info, security/ACL).

Node monitoring

  • Type-agnostic background poller writing time-series metrics + latest-snapshot
    state, with per-node intervals, on-demand polls, and UI staleness indicators.
  • Telemetry decoding (battery, MCU temp, external sensors) gated by the remote
    node's sharing prefs.

Contacts & peers (this release)

  • Contacts are now self-contained address-book records — each caches its own
    name, type, location, routing path, feature flags and last-seen, refreshed
    from adverts and path learning. Deleting a discovered peer no longer touches a
    saved contact.
  • Per-companion routing — DMs route from the contact's own learned path;
    companions never share a route to a peer.
  • Discovered-peer deletion — individual and bulk, from the Peers and Map
    pages.
  • Cross-linking + self-add prevention — every entity is reachable to its
    detail view from anywhere it's shown; you can't add your own node as a contact.

MQTT observer

  • Configurable broker presets (LetsMesh, Waev, MeshMapper, …), templated
    packet/status topics, and per-broker auth (Ed25519 JWT or basic).
  • Fixes: UTC zone-aware timestamps in payloads; shutdown is panic-safe against
    in-flight deliveries.

Other

  • Room-server chat (login, post, ACK-gated push), repeater ACL surface, and
    unified first-heard reception with a total-heard count.
  • CI guards :latest and the GitHub release flag for pre-release tags.

Upgrade notes

  • Config moves into the database. On first run, point the binary at your
    existing config file once (-config path) to import it; after that the DB is
    the source of truth and the file is no longer read. The legacy
    nodeType/[[bot]]/[[observer]] format imports cleanly.
  • The schema is created/migrated automatically on startup.

Full changelog: v1.0.6...v1.1.0-alpha.1

v1.0.6

Choose a tag to compare

@github-actions github-actions released this 10 May 23:49
4b6892f

What's Changed

Full Changelog: v1.0.5...v1.0.6

v1.0.5

Choose a tag to compare

@github-actions github-actions released this 06 May 23:58
0e9c1b4

What's Changed

Full Changelog: v1.0.4...v1.0.5

v1.0.4

Choose a tag to compare

@github-actions github-actions released this 04 May 01:25
358d09f

What's Changed

Full Changelog: v1.0.3...v1.0.4

v1.0.3

Choose a tag to compare

@github-actions github-actions released this 02 May 08:21
b2dde6f

What's Changed

Full Changelog: v1.0.2...v1.0.3