Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
acfa7d2
Add badge indicator on layers icon. (#894)
danditomaso Oct 16, 2025
a61bb2d
fix(actions): improve main to stable release workflow (#895)
danditomaso Oct 17, 2025
64d1f0f
fix(ui): logic on waypoint layer component caused 0 to be shown in UI…
danditomaso Oct 18, 2025
fe35376
chore(i18n): New Crowdin Translations by GitHub Action (#899)
github-actions[bot] Oct 21, 2025
c3f073a
Update readme with new widgets (#901)
danditomaso Oct 21, 2025
80c9306
feat(i18n): add fr localization support (#902)
danditomaso Oct 21, 2025
15daa02
feat(ci): add CI workflow to automatically close issue after 60 days …
danditomaso Oct 22, 2025
af2fac1
chore(deps): bump vite from 7.1.9 to 7.1.11 (#903)
dependabot[bot] Oct 23, 2025
fc1e327
Update inactive issue workflow schedule and settings (#905)
danditomaso Oct 23, 2025
cdad811
Persists device and app stores across sessions (#860)
philon- Oct 23, 2025
ff02b14
Fix description for historyReturnWindow (#907)
weebl2000 Oct 24, 2025
0cf677c
Feat(config): Align settings menu to match android/ios (#906)
danditomaso Oct 24, 2025
68ad535
chore: add new folders to biome config (#910)
danditomaso Oct 28, 2025
f375911
chore(i18n): New Crowdin Translations by GitHub Action (#908)
github-actions[bot] Oct 28, 2025
679f798
fix: use correct deprecated GPS coordinate format enum (#917)
dzienisz Oct 29, 2025
1df63bb
style: fix line wrapping for GPS coordinate format enum (#918)
dzienisz Oct 29, 2025
e53edfb
feat(state): enable deviceStore persistance (#922)
danditomaso Oct 31, 2025
3392c9d
fix(core): ensure core package works in browser (#923)
Azarattum Oct 31, 2025
e821a65
fix: add @serialport/bindings-cpp to onlyBuiltDependencies (#914)
benallfree Oct 31, 2025
4386854
feat(ui): Add UI library (#900)
danditomaso Oct 31, 2025
a1a6469
fix: added skelton loader for message items (#927)
danditomaso Nov 4, 2025
1af1295
feat(connections): Add connections page (replaces new device dialog) …
danditomaso Nov 4, 2025
2e60af1
fix(ci): add ui library to excluded list (#928)
danditomaso Nov 4, 2025
d8ad0ef
fix(config): update change registry channel value (#929)
danditomaso Nov 4, 2025
e13d543
chore(i18n): New Crowdin Translations by GitHub Action (#924)
github-actions[bot] Nov 4, 2025
ab03087
fix(connections): ensure connections reflect actual status. (#930)
danditomaso Nov 4, 2025
7c9013a
fix(connection): support port on HTTP connection (#935)
danditomaso Nov 6, 2025
6aeaed9
feat(docker): add arm v7 support (#934)
danditomaso Nov 6, 2025
a00cb20
feat(ui): match avatar color other platforms (#933)
danditomaso Nov 6, 2025
2e03b4a
fix(ui): fix add connection dialog typo (#938)
danditomaso Nov 6, 2025
0c8fcec
fix(i18n): Correct 'disconnected' typo in connections.json (#943)
philon- Nov 10, 2025
d1597ce
chore(i18n): New Crowdin Translations by GitHub Action (#941)
github-actions[bot] Nov 10, 2025
7f21b3b
Add 'packages/web' to excluded directories (#947)
danditomaso Nov 10, 2025
648a9c3
refactor: device connection logic, added nonce to get config only (#946)
danditomaso Nov 12, 2025
ac28fbc
fix: removed duplicate images (#951)
danditomaso Nov 12, 2025
94d5191
feat: add devcontainer (#953)
jsacrist Nov 13, 2025
390b46f
fix(ui): add language switcher to connections page (#954)
danditomaso Nov 13, 2025
b99057d
chore(i18n): New Crowdin Translations by GitHub Action (#958)
github-actions[bot] Nov 18, 2025
295755e
fix: interpolate longName and shortName in PKI backup download (#959)
zeozeozeo Nov 18, 2025
06cc266
fix(ui): removed internet hosted fonts from app (#955)
danditomaso Nov 19, 2025
68cea2e
chore(i18n): New Crowdin Translations by GitHub Action (#962)
github-actions[bot] Nov 23, 2025
8918603
fix(ui): correct typo in languagePicker key and adjust description wi…
dzienisz Nov 25, 2025
0570438
chore(deps-dev): bump happy-dom from 20.0.0 to 20.0.2 (#968)
dependabot[bot] Nov 27, 2025
5debdb4
fix(ui): add "never" i18n string, fix "Favorite" tooltip (#965)
Pmmlabs Nov 27, 2025
6a7be99
feat: add fixed position coordinate picker (#909)
dzienisz Nov 27, 2025
020e9d6
feat(ui): add SNR, RSSI, hops info for messages (#963)
Pmmlabs Nov 27, 2025
94220e7
feat(map): add heatmap layer (#969)
danditomaso Nov 29, 2025
0b2fdb6
Revert "feat(ui): add SNR, RSSI, hops info for messages (#963)" (#974)
danditomaso Dec 2, 2025
3ecea59
Update README with Buf CLI installation instructions (#981)
rj-xy Dec 5, 2025
0108494
Channel bandwidth is kHz, not MHz (#983)
weebl2000 Dec 9, 2025
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
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "meshtastic-web",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"features": {
"ghcr.io/r3dpoint/devcontainer-features/tailwindcss-standalone-cli:1": {
"version": "latest"
},
"ghcr.io/devcontainers-extra/features/pnpm:2": {
"version": "latest"
}
}
}

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
set -euo pipefail

# List packages to exclude (full paths under repo root)
EXCLUDED_DIRS=("packages/protobufs" "packages/transport-deno")
EXCLUDED_DIRS=("packages/protobufs" "packages/transport-deno" "packages/ui" "pacakges/web")

is_excluded() {
local dir="$1"
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/inactive-issue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Close inactive issues
on:
schedule:
- cron: "0 */4 * * *" # every 4 hours
workflow_dispatch: # allow manual runs
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-issue-stale: 60
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 60 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
only-issue-labels: "Bug"
remove-stale-when-updated: true
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
${{ steps.meta.outputs.moving_tag }}
${{ steps.meta.outputs.immutable_tag }}
oci: true
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/arm/v7
labels: |
org.opencontainers.image.source=${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
with:
context: .
file: ./packages/web/infra/Containerfile
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
82 changes: 52 additions & 30 deletions .github/workflows/update-stable-from-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,81 @@ jobs:
update-stable-branch:
name: Update stable from latest release source
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # need full history for reset/push
fetch-depth: 0
fetch-tags: true # IMPORTANT: we need tags to resolve the release commit

- name: Configure Git author
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Determine source ref & SHA
- name: Determine source SHA (prefer tag)
id: meta
shell: bash
run: |
set -euo pipefail
SRC="${{ github.event.release.target_commitish }}"
if [ -z "$SRC" ] || ! git ls-remote --exit-code origin "refs/heads/$SRC" >/dev/null 2>&1; then
# Fallback to main if target_commitish is empty or not a branch
SRC="main"

TAG="${{ github.event.release.tag_name }}"
TARGET="${{ github.event.release.target_commitish || '' }}"

# Always ensure we have latest remote heads/tags
git fetch --tags --prune origin

SHA=""
SRC_DESC=""

# 1) Prefer the release tag commit
if [ -n "${TAG}" ] && git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
SHA="$(git rev-list -n1 "${TAG}")"
SRC_DESC="tag:${TAG}"
fi

echo "Using source branch: $SRC"
git fetch origin "$SRC":"refs/remotes/origin/$SRC" --prune
SHA="$(git rev-parse "origin/$SRC")"
echo "sha=$SHA" >> "$GITHUB_OUTPUT"
echo "src=$SRC" >> "$GITHUB_OUTPUT"
# 2) Fall back to target_commitish if it points to a branch on origin
if [ -z "${SHA}" ] && [ -n "${TARGET}" ] && git ls-remote --exit-code --heads origin "${TARGET}" >/dev/null 2>&1; then
git fetch origin "${TARGET}:${TARGET}" --prune
SHA="$(git rev-parse "${TARGET}^{commit}")"
SRC_DESC="branch:${TARGET}"
fi

# 3) Fall back to main if present
if [ -z "${SHA}" ] && git ls-remote --exit-code --heads origin "main" >/dev/null 2>&1; then
git fetch origin "main:main" --prune
SHA="$(git rev-parse "main^{commit}")"
SRC_DESC="branch:main"
fi

- name: Prepare local stable branch
if [ -z "${SHA}" ]; then
echo "::error::Unable to resolve source commit from tag (${TAG}), target_commitish (${TARGET}), or main."
exit 1
fi

echo "Using source: ${SRC_DESC}"
echo "sha=${SHA}" >> "$GITHUB_OUTPUT"
echo "source=${SRC_DESC}" >> "$GITHUB_OUTPUT"

- name: Create/reset local stable to SHA
shell: bash
run: |
set -euo pipefail
# Ensure we have the remote stable ref if it exists
# Make sure we know if remote stable exists (non-fatal if not)
git fetch origin stable:refs/remotes/origin/stable || true

if git show-ref --verify --quiet refs/heads/stable; then
echo "Local stable exists."
elif git show-ref --verify --quiet refs/remotes/origin/stable; then
echo "Creating local stable tracking branch from remote."
git checkout -b stable --track origin/stable
else
echo "Creating new local stable branch at source SHA."
git checkout -b stable "${{ steps.meta.outputs.sha }}"
fi

- name: Reset stable to source SHA
run: |
git checkout stable
git reset --hard "${{ steps.meta.outputs.sha }}"
# Create or reset local stable in one command
git checkout -B stable "${{ steps.meta.outputs.sha }}"
git status --short --branch

- name: Push stable (force-with-lease)
run: |
# Safer than --force; refuses if remote moved unexpectedly
git push origin stable --force-with-lease
# Safer than --force; refuses if remote moved unexpectedly (protects against races)
REMOTE_STABLE_SHA="$(git rev-parse refs/remotes/origin/stable || echo '')"
if [ -z "$REMOTE_STABLE_SHA" ]; then
# If remote stable doesn't exist, just use --force-with-lease=stable (no SHA)
git push origin stable:stable --force-with-lease=stable
else
# Use the specific SHA for maximum safety
git push origin stable:stable --force-with-lease=stable:$REMOTE_STABLE_SHA
fi
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,12 @@ __screenshots__*
npm/
.idea
**/LICENSE
.DS_Store

packages/protobufs/packages/ts/dist
.pnpm-store/

# Local dev certs
*.pem
*.crt
*.key
42 changes: 19 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ This monorepo consolidates the official [Meshtastic](https://meshtastic.org) web
interface and its supporting JavaScript libraries. It aims to provide a unified
development experience for interacting with Meshtastic devices.

> [!NOTE]
> You can find the main Meshtastic documentation at https://meshtastic.org/docs/introduction/.

### Projects within this Monorepo (`packages/`)

All projects are located within the `packages/` directory:
Expand All @@ -33,7 +36,7 @@ All `Meshtastic JS` packages (core and transports) are published both to

---

## Stats
## Repository activity

| Project | Repobeats |
| :------------- | :-------------------------------------------------------------------------------------------------------------------- |
Expand Down Expand Up @@ -74,6 +77,9 @@ Follow the installation instructions on their home page.
```
This command installs all necessary dependencies for all packages within the
monorepo.
3. **Install the Buf CLI**
Required for building `packages/protobufs`
https://buf.build/docs/cli/installation/

### Running Projects

Expand All @@ -87,28 +93,18 @@ If you encounter any issues, please report them in our
[issues tracker](https://github.com/meshtastic/web/issues). Your feedback helps
improve the stability of future releases

### Contributing

We welcome contributions! Here’s how the deployment flow works for pull
requests:

- **Preview Deployments:**\
Every pull request automatically generates a preview deployment on Vercel.
This allows you and reviewers to easily preview changes before merging.
## Star history

- **Staging Environment (`client-test`):**\
Once your PR is merged, your changes will be available on our staging site:
[client-test.meshtastic.org](https://client-test.meshtastic.org/).\
This environment supports rapid feature iteration and testing without
impacting the production site.
<a href="https://star-history.com/#meshtastic/web&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=meshtastic/web&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=meshtastic/web&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=meshtastic/web&type=Date" width="100%" />
</picture>
</a>

- **Production Releases:**\
At regular intervals, stable and fully tested releases are promoted to our
production site: [client.meshtastic.org](https://client.meshtastic.org/).\
This is the primary interface used by the public to connect with their
Meshtastic nodes.
## Contributors

Please review our
[Contribution Guidelines](https://github.com/meshtastic/web/blob/main/CONTRIBUTING.md)
before submitting a pull request. We appreciate your help in making the project
better!
<a href="https://github.com/meshtastic/web/graphs/contributors">
<img src="https://contrib.rocks/image?repo=meshtastic/web" width="100%"/>
</a>
9 changes: 6 additions & 3 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
"**/*.ts",
"**/*.tsx",
"!npm_modules",
"!dist",
"!**/dist",
"!**/protobufs",
"!**/.*",
"!npm",
"**/*.json",
"!**/locales/*-*/*.json"
"!**/locales/*-*/*.json",
"!**/packages/ui/"
],
"ignoreUnknown": false
},
Expand All @@ -21,7 +24,7 @@
},
"linter": {
"enabled": true,
"includes": ["**", "!test/**"],
"includes": ["**", "!test/**", "!**/dist/**"],
"rules": {
"recommended": true,
"suspicious": {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
"tslog": "^4.9.3"
},
"devDependencies": {
"@types/node": "^24.3.1",
"@biomejs/biome": "2.2.4",
"@types/node": "^24.3.1",
"tsdown": "^0.15.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
},
"pnpm": {
"onlyBuiltDependencies": [
"@serialport/bindings-cpp",
"@tailwindcss/oxide",
"core-js",
"esbuild",
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"license": "GPL-3.0-only",
"tsdown": {
"entry": "mod.ts",
"platform": "browser",
"dts": true,
"format": [
"esm"
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export enum DeviceStatusEnum {
DeviceConnected = 5,
DeviceConfiguring = 6,
DeviceConfigured = 7,
DeviceError = 8,
}

export type LogEventPacket = LogEvent & { date: Date };
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/utils/eventSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,12 @@ export class EventSystem {
*/
public readonly onQueueStatus: SimpleEventDispatcher<Protobuf.Mesh.QueueStatus> =
new SimpleEventDispatcher<Protobuf.Mesh.QueueStatus>();

/**
* Fires when a configCompleteId message is received from the device
*
* @event onConfigComplete
*/
public readonly onConfigComplete: SimpleEventDispatcher<number> =
new SimpleEventDispatcher<number>();
}
26 changes: 16 additions & 10 deletions packages/core/src/utils/transform/decodePacket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,21 +135,27 @@ export const decodePacket = (device: MeshDevice) =>
}

case "configCompleteId": {
if (decodedMessage.payloadVariant.value !== device.configId) {
device.log.error(
Types.Emitter[Types.Emitter.HandleFromRadio],
`❌ Invalid config id received from device, expected ${device.configId} but received ${decodedMessage.payloadVariant.value}`,
);
}

device.log.info(
Types.Emitter[Types.Emitter.HandleFromRadio],
`⚙️ Valid config id received from device: ${device.configId}`,
`⚙️ Received config complete id: ${decodedMessage.payloadVariant.value}`,
);

device.updateDeviceStatus(
Types.DeviceStatusEnum.DeviceConfigured,
// Emit the configCompleteId event for MeshService to handle two-stage flow
device.events.onConfigComplete.dispatch(
decodedMessage.payloadVariant.value,
);

// For backward compatibility: if configId matches, update device status
// MeshService will override this behavior for two-stage flow
if (decodedMessage.payloadVariant.value === device.configId) {
device.log.info(
Types.Emitter[Types.Emitter.HandleFromRadio],
`⚙️ Config id matches device.configId: ${device.configId}`,
);
device.updateDeviceStatus(
Types.DeviceStatusEnum.DeviceConfigured,
);
}
break;
}

Expand Down
22 changes: 22 additions & 0 deletions packages/ui/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/base.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
Loading
Loading