matterbridge 3.5.2-dev-20260128-beb91f9 → 3.5.2-dev-20260130-b4e7ef3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # <img src="https://matterbridge.io/assets/matterbridge.svg" alt="Matterbridge Logo" width="64px" height="64px">&nbsp;&nbsp;&nbsp;Matterbridge changelog
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/matterbridge.svg)](https://www.npmjs.com/package/matterbridge)
4
+ [![npm downloads](https://img.shields.io/npm/dt/matterbridge.svg)](https://www.npmjs.com/package/matterbridge)
5
+ [![Docker Version](https://img.shields.io/docker/v/luligu/matterbridge/latest?label=docker%20version)](https://hub.docker.com/r/luligu/matterbridge)
6
+ [![Docker Pulls](https://img.shields.io/docker/pulls/luligu/matterbridge?label=docker%20pulls)](https://hub.docker.com/r/luligu/matterbridge)
7
+ ![Node.js CI](https://github.com/Luligu/matterbridge/actions/workflows/build.yml/badge.svg)
8
+ ![CodeQL](https://github.com/Luligu/matterbridge/actions/workflows/codeql.yml/badge.svg)
9
+ [![codecov](https://codecov.io/gh/Luligu/matterbridge/branch/main/graph/badge.svg)](https://codecov.io/gh/Luligu/matterbridge)
10
+
11
+ [![powered by](https://img.shields.io/badge/powered%20by-matter--history-blue)](https://www.npmjs.com/package/matter-history)
12
+ [![powered by](https://img.shields.io/badge/powered%20by-node--ansi--logger-blue)](https://www.npmjs.com/package/node-ansi-logger)
13
+ [![powered by](https://img.shields.io/badge/powered%20by-node--persist--manager-blue)](https://www.npmjs.com/package/node-persist-manager)
14
+
15
+ ---
16
+
3
17
  All notable changes to this project will be documented in this file.
4
18
 
5
19
  If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge and sponsoring it.
@@ -17,7 +31,7 @@ The project will evolve to a multi-threaded architecture (the CLI will become th
17
31
  - all plugins in bridge mode;
18
32
  - each plugin in childbridge mode;
19
33
 
20
- - check updates;
34
+ - ✅ check updates;
21
35
  - npm install;
22
36
  - ✅ get the global node_modules directory;
23
37
 
@@ -38,9 +52,11 @@ Advantages:
38
52
  - [MatterbridgePlatform]: Verify brand of MatterbridgeEndpoint.
39
53
  - [BasicVideoPlayer]: Added **Basic Video Player** class (suported by SmartThings).
40
54
  - [frontend]: Added **pluginIgnoreList** to avoid to install a plugin that is only a test or a name reservation on npm.
41
- - [docker]: Added instructions about how to disable the health check when you override the frontend port.
55
+ - [docker]: Added instructions about how to disable the health check when you override the frontend port or enable https.
42
56
  - [Alexa]: Added a full review of supported device types and known issues. Thanks [Tamer Salah](https://github.com/tammeryousef1006).
43
- - [virtual]: Added outlet to mounted switch device type in virtual devices (Matter .1.4.2).
57
+ - [virtual]: Added outlet to mounted switch device type in virtual devices (Matter 1.4.2). Now the mounted switch is supported by all controllers.
58
+ - [package]: Added @matterbridge/thread monorepo scoped package.
59
+ - [docker]: Added mb_health bin to be used with docker health check. It allows to reduce the image size by 20MB.
44
60
 
45
61
  ### Changed
46
62
 
@@ -48,6 +64,7 @@ Advantages:
48
64
  - [docker]: Clarified in [README-DOCKER.md](README-DOCKER.md) the content of the matterbridge docker images on Docker Hub.
49
65
  - [frontend]: Bumped `frontend` version to v. 3.4.3.
50
66
  - [frontend]: For the matterbridge docker image with tag dev, the frontend now shows the versions with the tag git.
67
+ - [worker]: Bumped worker module to v. 1.1.0.
51
68
 
52
69
  <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
53
70
 
package/README-DEV.md CHANGED
@@ -174,7 +174,7 @@ npm link
174
174
 
175
175
  Always keep your local instance of matterbridge up to date.
176
176
 
177
- ### WARNING \***\*\*\*\*\***
177
+ ### \***\*\*\*\*\*** WARNING \***\*\*\*\*\***
178
178
 
179
179
  Some error messages are logged on start when a plugin has wrong imports or configurations and the plugin will be disabled to prevent instability and crashes.
180
180
 
package/README-DOCKER.md CHANGED
@@ -95,7 +95,7 @@ sudo docker run --name matterbridge \
95
95
 
96
96
  If you override the command, always start it with `matterbridge --docker`.
97
97
 
98
- **If you change the frontend port, overriding the default command of the images, docker will report the container unhealty unless you add the --no-healthcheck param**.
98
+ **If you change the frontend port (or enable https), overriding the default command of the images, docker will report the container unhealty unless you add the --no-healthcheck param**.
99
99
 
100
100
  ### Run with Docker Compose
101
101
 
@@ -139,7 +139,7 @@ services:
139
139
 
140
140
  If you override the command, always start it with `["matterbridge", "--docker"]`.
141
141
 
142
- **If you change the frontend port, overriding the default command of the images, docker will report the container unhealty unless you add:**.
142
+ **If you change the frontend port (or enable https), overriding the default command of the images, docker will report the container unhealty unless you add:**.
143
143
 
144
144
  ```yaml
145
145
  healthcheck:
package/README.md CHANGED
@@ -647,20 +647,27 @@ Install Google Home on an iPhone and complete the commissioning there. Once set
647
647
 
648
648
  Tested by [Tamer Salah](https://github.com/tammeryousef1006).
649
649
 
650
- Alexa integrates with Matterbridge to locally control non-native devices by acting as a Matter Controller. While Amazon has expanded support to include core categories like lighting, plugs, thermostats, locks, and sensors, many advanced or specialized device types defined in the latest Matter specifications are not yet recognized by the Alexa ecosystem.
650
+ Alexa integrates with Matterbridge to locally control non-native devices by acting as a Matter Controller.
651
+ While Amazon has expanded support to include core categories like lighting, plugs, thermostats, locks, and sensors, many advanced or specialized device types defined in the latest Matter specifications are not yet recognized by the Alexa ecosystem.
652
+
651
653
  Alexa Support vs. Matterbridge Test Results
654
+
652
655
  During testing, Alexa successfully managed most standard smart home categories but failed to recognize or fully support the following types exposed via Matterbridge:
653
- Appliances & Kitchen: Cooktop, Microwave Oven, Oven, Refrigerator, Laundry Washer/Dryer, and Extractor Hood.
654
- Energy & Utilities: Battery Storage, EVSE (Electric Vehicle Supply Equipment), and Solar Power.
655
- Water & Infrastructure: Water Valve, Water Heater, Water Leak/Freeze sensors, Pump, and Rain Sensor.
656
- Media & Controls: Basic Video Player and Speaker.
657
- Specialized Sensors/Inputs: Heat Pump, Latching Switch, Flow, and Pressure.
658
- Limited Support: Cover Lift and Tilt devices only functioned for lift operations, with tilt functionality unsupported.
656
+
657
+ - Appliances & Kitchen: Cooktop, Microwave Oven, Oven, Refrigerator, Laundry Washer/Dryer, and Extractor Hood.
658
+ - Energy & Utilities: Battery Storage, EVSE (Electric Vehicle Supply Equipment), and Solar Power.
659
+ - Water & Infrastructure: Water Valve, Water Heater, Water Leak/Freeze sensors, Pump, and Rain Sensor.
660
+ - Media & Controls: Basic Video Player and Speaker.
661
+ - Specialized Sensors/Inputs: Heat Pump, Latching Switch, Flow, and Pressure.
662
+ - Limited Support: Cover Lift and Tilt devices only functioned for lift operations, with tilt functionality unsupported.
663
+
659
664
  Integration Limitations
665
+
660
666
  Even when a device is recognized, Alexa may face specific bridge-related limitations:
661
- Device Caps: Alexa currently supports a maximum of 50 bridged devices per connection; exceeding this limit may cause devices to disappear from the Alexa App.
662
- Latency: While Matter is designed for local control, status updates in the Alexa app may occasionally lag if the app remains open during external state changes.
663
- Feature Gaps: Advanced features for certain types, such as unlocking specific smart locks, may be disabled by default for security and require manual activation within the app
667
+
668
+ - Device Caps: Alexa currently supports a maximum of 50 bridged devices per connection; exceeding this limit may cause devices to disappear from the Alexa App.
669
+ - Latency: While Matter is designed for local control, status updates in the Alexa app may occasionally lag if the app remains open during external state changes.
670
+ - Feature Gaps: Advanced features for certain types, such as unlocking specific smart locks, may be disabled by default for security and require manual activation within the app
664
671
 
665
672
  Known issues:
666
673
 
@@ -672,13 +679,13 @@ In the zigbee2mqtt and shelly plugins select the option to expose the switch dev
672
679
 
673
680
  ## SmartThings
674
681
 
675
- Tested by Tamer Salah
682
+ Tested by [Tamer Salah](https://github.com/tammeryousef1006).
676
683
 
677
684
  No issues reported so far.
678
685
 
679
686
  ## eWeLink
680
687
 
681
- Tested by Tamer Salah
688
+ Tested by [Tamer Salah](https://github.com/tammeryousef1006).
682
689
 
683
690
  eWeLink needs the standard port 5540 for commissioning.
684
691
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ const { mbHealthMain } = await import('../dist/mb_health.js');
3
+ await mbHealthMain();
@@ -1,8 +1,8 @@
1
1
  import { LogLevel } from 'node-ansi-logger';
2
2
  import { EndpointNumber } from '@matter/types/datatype';
3
3
  import type { RefreshRequiredChanged, WsMessageBroadcast } from './frontendTypes.js';
4
- import type { PlatformConfig, PlatformSchema } from './matterbridgePlatform.js';
5
- import type { ApiMatter, ApiPlugin, BaseDevice, Plugin, StoragePlugin } from './matterbridgeTypes.js';
4
+ import type { PlatformConfig, PlatformMatterbridge, PlatformSchema } from './matterbridgePlatformTypes.js';
5
+ import type { ApiMatter, ApiPlugin, BaseDevice, Plugin, SharedMatterbridge, StoragePlugin } from './matterbridgeTypes.js';
6
6
  export type WorkerSrcType = 'manager' | 'matterbridge' | 'plugins' | 'devices' | 'frontend' | 'matter' | 'platform' | 'spawn' | 'updates';
7
7
  export type WorkerDstType = 'manager' | 'matterbridge' | 'plugins' | 'devices' | 'frontend' | 'matter' | 'platform' | 'spawn' | 'updates' | 'all';
8
8
  type NormalizeRequest<T> = T extends {
@@ -184,6 +184,28 @@ export type WorkerMessageTypes = {
184
184
  };
185
185
  };
186
186
  };
187
+ 'matterbridge_platform': {
188
+ request: {
189
+ params: undefined;
190
+ };
191
+ response: {
192
+ result: {
193
+ data: PlatformMatterbridge;
194
+ success: true;
195
+ };
196
+ };
197
+ };
198
+ 'matterbridge_shared': {
199
+ request: {
200
+ params: undefined;
201
+ };
202
+ response: {
203
+ result: {
204
+ data: SharedMatterbridge;
205
+ success: true;
206
+ };
207
+ };
208
+ };
187
209
  'matter_start': {
188
210
  request: {
189
211
  params: {
@@ -11,10 +11,15 @@ export async function checkUpdates(matterbridge) {
11
11
  const pluginsVersionPromises = [];
12
12
  const pluginsDevVersionPromises = [];
13
13
  const shellyUpdatesPromises = [];
14
- const plugins = (await server.fetch({ type: 'plugins_apipluginarray', src: server.name, dst: 'plugins' }, 1000)).result.plugins;
15
- for (const plugin of plugins) {
16
- pluginsVersionPromises.push(getPluginLatestVersion(log, server, plugin));
17
- pluginsDevVersionPromises.push(getPluginDevVersion(log, server, plugin));
14
+ try {
15
+ const plugins = (await server.fetch({ type: 'plugins_apipluginarray', src: server.name, dst: 'plugins' }, 1000)).result.plugins;
16
+ for (const plugin of plugins) {
17
+ pluginsVersionPromises.push(getPluginLatestVersion(log, server, plugin));
18
+ pluginsDevVersionPromises.push(getPluginDevVersion(log, server, plugin));
19
+ }
20
+ }
21
+ catch (error) {
22
+ log.debug(`Error fetching plugins for update check: ${error instanceof Error ? error.message : error}`);
18
23
  }
19
24
  if (hasParameter('shelly')) {
20
25
  const { getShellySysUpdate, getShellyMainUpdate } = await import('./shelly.js');
@@ -1,5 +1,5 @@
1
1
  import type { EndpointNumber } from '@matter/types';
2
- import type { PlatformConfig } from './matterbridgePlatform.js';
2
+ import type { PlatformConfig } from './matterbridgePlatformTypes.js';
3
3
  import type { ApiClusters, ApiDevice, ApiMatter, ApiPlugin, MatterbridgeInformation, SystemInformation } from './matterbridgeTypes.js';
4
4
  export type RefreshRequiredChanged = 'settings' | 'plugins' | 'devices' | 'matter';
5
5
  export interface ApiSettings {
package/dist/index.d.ts CHANGED
@@ -8,4 +8,5 @@ export * from './matterbridgeDeviceTypes.js';
8
8
  export * from './matterbridgePlatform.js';
9
9
  export * from './matterbridgeAccessoryPlatform.js';
10
10
  export * from './matterbridgeDynamicPlatform.js';
11
+ export * from './matterbridgePlatformTypes.js';
11
12
  export { addVirtualDevice } from './helpers.js';
package/dist/index.js CHANGED
@@ -10,4 +10,5 @@ export * from './matterbridgeDeviceTypes.js';
10
10
  export * from './matterbridgePlatform.js';
11
11
  export * from './matterbridgeAccessoryPlatform.js';
12
12
  export * from './matterbridgeDynamicPlatform.js';
13
+ export * from './matterbridgePlatformTypes.js';
13
14
  export { addVirtualDevice } from './helpers.js';
@@ -12,7 +12,7 @@ import { PluginManager } from './pluginManager.js';
12
12
  import { DeviceManager } from './deviceManager.js';
13
13
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
14
14
  import { Frontend } from './frontend.js';
15
- import { PlatformMatterbridge } from './matterbridgePlatform.js';
15
+ import { PlatformMatterbridge } from './matterbridgePlatformTypes.js';
16
16
  interface MatterbridgeEvents {
17
17
  shutdown: [];
18
18
  restart: [];
@@ -214,6 +214,12 @@ export class Matterbridge extends EventEmitter {
214
214
  this.shellyMainUpdate = true;
215
215
  this.server.respond({ ...msg, result: { success: true } });
216
216
  break;
217
+ case 'matterbridge_platform':
218
+ this.server.respond({ ...msg, result: { data: this.getPlatformMatterbridge(), success: true } });
219
+ break;
220
+ case 'matterbridge_shared':
221
+ this.server.respond({ ...msg, result: { data: this.getSharedMatterbridge(), success: true } });
222
+ break;
217
223
  default:
218
224
  if (this.verbose)
219
225
  this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
@@ -1,5 +1,6 @@
1
1
  import { AnsiLogger } from 'node-ansi-logger';
2
- import { MatterbridgePlatform, PlatformConfig, PlatformMatterbridge } from './matterbridgePlatform.js';
2
+ import { MatterbridgePlatform } from './matterbridgePlatform.js';
3
+ import type { PlatformConfig, PlatformMatterbridge } from './matterbridgePlatformTypes.js';
3
4
  export declare function isMatterbridgeAccessoryPlatform(value: unknown): value is MatterbridgeAccessoryPlatform;
4
5
  export declare class MatterbridgeAccessoryPlatform extends MatterbridgePlatform {
5
6
  constructor(matterbridge: PlatformMatterbridge, log: AnsiLogger, config: PlatformConfig);
@@ -1,5 +1,6 @@
1
1
  import { AnsiLogger } from 'node-ansi-logger';
2
- import { MatterbridgePlatform, PlatformConfig, PlatformMatterbridge } from './matterbridgePlatform.js';
2
+ import { MatterbridgePlatform } from './matterbridgePlatform.js';
3
+ import type { PlatformConfig, PlatformMatterbridge } from './matterbridgePlatformTypes.js';
3
4
  export declare function isMatterbridgeDynamicPlatform(value: unknown): value is MatterbridgeDynamicPlatform;
4
5
  export declare class MatterbridgeDynamicPlatform extends MatterbridgePlatform {
5
6
  constructor(matterbridge: PlatformMatterbridge, log: AnsiLogger, config: PlatformConfig);
@@ -1,39 +1,9 @@
1
1
  import { AnsiLogger, LogLevel } from 'node-ansi-logger';
2
2
  import { NodeStorage } from 'node-persist-manager';
3
- import { EndpointNumber, VendorId } from '@matter/types/datatype';
3
+ import { EndpointNumber } from '@matter/types/datatype';
4
4
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
5
5
  import { ApiSelectDevice, ApiSelectEntity } from './frontendTypes.js';
6
- import { SystemInformation } from './matterbridgeTypes.js';
7
- export type PlatformConfigValue = string | number | boolean | bigint | object | undefined | null;
8
- export type PlatformConfig = {
9
- name: string;
10
- type: string;
11
- version: string;
12
- debug: boolean;
13
- unregisterOnShutdown: boolean;
14
- } & Record<string, PlatformConfigValue>;
15
- export type PlatformSchemaValue = string | number | boolean | bigint | object | undefined | null;
16
- export type PlatformSchema = Record<string, PlatformSchemaValue>;
17
- export type PlatformMatterbridge = {
18
- readonly systemInformation: Readonly<Pick<SystemInformation, 'interfaceName' | 'macAddress' | 'ipv4Address' | 'ipv6Address' | 'nodeVersion' | 'hostname' | 'user' | 'osType' | 'osRelease' | 'osPlatform' | 'osArch' | 'totalMemory' | 'freeMemory' | 'systemUptime' | 'processUptime' | 'cpuUsage' | 'processCpuUsage' | 'rss' | 'heapTotal' | 'heapUsed'>>;
19
- readonly rootDirectory: string;
20
- readonly homeDirectory: string;
21
- readonly matterbridgeDirectory: string;
22
- readonly matterbridgePluginDirectory: string;
23
- readonly matterbridgeCertDirectory: string;
24
- readonly globalModulesDirectory: string;
25
- readonly matterbridgeVersion: string;
26
- readonly matterbridgeLatestVersion: string;
27
- readonly matterbridgeDevVersion: string;
28
- readonly frontendVersion: string;
29
- readonly bridgeMode: 'bridge' | 'childbridge' | 'controller' | '';
30
- readonly restartMode: 'service' | 'docker' | '';
31
- readonly virtualMode: 'disabled' | 'outlet' | 'light' | 'switch' | 'mounted_switch';
32
- readonly aggregatorVendorId: VendorId;
33
- readonly aggregatorVendorName: string;
34
- readonly aggregatorProductId: number;
35
- readonly aggregatorProductName: string;
36
- };
6
+ import { PlatformConfig, PlatformMatterbridge, PlatformSchema } from './matterbridgePlatformTypes.js';
37
7
  export declare function isMatterbridgePlatform(value: unknown): value is MatterbridgePlatform;
38
8
  export declare function assertMatterbridgePlatform(value: unknown, context?: string): asserts value is MatterbridgePlatform;
39
9
  export declare class MatterbridgePlatform {
@@ -0,0 +1,32 @@
1
+ import type { VendorId } from '@matter/main/types';
2
+ import type { SystemInformation } from './matterbridgeTypes.js';
3
+ export type PlatformConfigValue = string | number | boolean | bigint | object | undefined | null;
4
+ export type PlatformConfig = {
5
+ name: string;
6
+ type: string;
7
+ version: string;
8
+ debug: boolean;
9
+ unregisterOnShutdown: boolean;
10
+ } & Record<string, PlatformConfigValue>;
11
+ export type PlatformSchemaValue = string | number | boolean | bigint | object | undefined | null;
12
+ export type PlatformSchema = Record<string, PlatformSchemaValue>;
13
+ export type PlatformMatterbridge = {
14
+ readonly systemInformation: Readonly<Pick<SystemInformation, 'interfaceName' | 'macAddress' | 'ipv4Address' | 'ipv6Address' | 'nodeVersion' | 'hostname' | 'user' | 'osType' | 'osRelease' | 'osPlatform' | 'osArch' | 'totalMemory' | 'freeMemory' | 'systemUptime' | 'processUptime' | 'cpuUsage' | 'processCpuUsage' | 'rss' | 'heapTotal' | 'heapUsed'>>;
15
+ readonly rootDirectory: string;
16
+ readonly homeDirectory: string;
17
+ readonly matterbridgeDirectory: string;
18
+ readonly matterbridgePluginDirectory: string;
19
+ readonly matterbridgeCertDirectory: string;
20
+ readonly globalModulesDirectory: string;
21
+ readonly matterbridgeVersion: string;
22
+ readonly matterbridgeLatestVersion: string;
23
+ readonly matterbridgeDevVersion: string;
24
+ readonly frontendVersion: string;
25
+ readonly bridgeMode: 'bridge' | 'childbridge' | 'controller' | '';
26
+ readonly restartMode: 'service' | 'docker' | '';
27
+ readonly virtualMode: 'disabled' | 'outlet' | 'light' | 'switch' | 'mounted_switch';
28
+ readonly aggregatorVendorId: VendorId;
29
+ readonly aggregatorVendorName: string;
30
+ readonly aggregatorProductId: number;
31
+ readonly aggregatorProductName: string;
32
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,7 +6,8 @@ import type { FabricIndex, VendorId, EndpointNumber, Semtag } from '@matter/type
6
6
  import type { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
7
7
  import type { AdministratorCommissioning } from '@matter/types/clusters/administrator-commissioning';
8
8
  import type { Matterbridge } from './matterbridge.js';
9
- import type { MatterbridgePlatform, PlatformConfig, PlatformSchema } from './matterbridgePlatform.js';
9
+ import type { MatterbridgePlatform } from './matterbridgePlatform.js';
10
+ import type { PlatformConfig, PlatformSchema } from './matterbridgePlatformTypes.js';
10
11
  import type { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
11
12
  export declare const plg = "\u001B[38;5;33m";
12
13
  export declare const dev = "\u001B[38;5;79m";
@@ -0,0 +1,10 @@
1
+ export declare function checkHealth(url: string, timeoutMs: number): Promise<boolean>;
2
+ export declare function fetchHealth(url: string, timeoutMs: number): Promise<{
3
+ ok: boolean;
4
+ statusCode: number;
5
+ body: string;
6
+ json?: unknown;
7
+ }>;
8
+ export declare function mbHealthExitCode(url: string, timeoutMs: number): Promise<number>;
9
+ export declare function mbHealthCli(url: string, timeoutMs: number, exitFn?: (code: number) => never | void): Promise<void>;
10
+ export declare function mbHealthMain(exitFn?: (code: number) => never | void): Promise<void>;
@@ -0,0 +1,77 @@
1
+ import http from 'node:http';
2
+ import https from 'node:https';
3
+ export function checkHealth(url, timeoutMs) {
4
+ return fetchHealth(url, timeoutMs)
5
+ .then(({ ok }) => ok)
6
+ .catch(() => false);
7
+ }
8
+ export function fetchHealth(url, timeoutMs) {
9
+ return new Promise((resolve) => {
10
+ const parsedUrl = new URL(url);
11
+ const requestImpl = parsedUrl.protocol === 'https:' ? https : http;
12
+ const request = requestImpl.request({
13
+ protocol: parsedUrl.protocol,
14
+ hostname: parsedUrl.hostname,
15
+ port: parsedUrl.port,
16
+ path: parsedUrl.pathname + parsedUrl.search,
17
+ method: 'GET',
18
+ headers: {
19
+ 'cache-control': 'no-store',
20
+ accept: 'application/json',
21
+ },
22
+ }, (response) => {
23
+ const chunks = [];
24
+ response.on('data', (chunk) => {
25
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
26
+ });
27
+ response.on('end', () => {
28
+ const statusCode = response.statusCode ?? 0;
29
+ const ok = statusCode >= 200 && statusCode < 300;
30
+ const body = Buffer.concat(chunks).toString('utf8');
31
+ let json;
32
+ try {
33
+ if (body.trim().length > 0)
34
+ json = JSON.parse(body);
35
+ }
36
+ catch {
37
+ json = undefined;
38
+ }
39
+ resolve({ ok, statusCode, body, json });
40
+ });
41
+ response.on('error', () => {
42
+ resolve({ ok: false, statusCode: response.statusCode ?? 0, body: '' });
43
+ });
44
+ });
45
+ request.on('error', () => resolve({ ok: false, statusCode: 0, body: '' }));
46
+ request.setTimeout(timeoutMs, () => {
47
+ request.destroy();
48
+ resolve({ ok: false, statusCode: 0, body: '' });
49
+ });
50
+ request.end();
51
+ });
52
+ }
53
+ export async function mbHealthExitCode(url, timeoutMs) {
54
+ try {
55
+ const { ok } = await fetchHealth(url, timeoutMs);
56
+ return ok ? 0 : 1;
57
+ }
58
+ catch {
59
+ return 1;
60
+ }
61
+ }
62
+ export async function mbHealthCli(url, timeoutMs, exitFn = process.exit) {
63
+ const { ok, statusCode, body, json } = await fetchHealth(url, timeoutMs);
64
+ if (json !== undefined) {
65
+ console.log(JSON.stringify(json, null, 2));
66
+ }
67
+ else if (body) {
68
+ console.log(body);
69
+ }
70
+ else {
71
+ console.log(JSON.stringify({ ok, statusCode }, null, 2));
72
+ }
73
+ exitFn(ok ? 0 : 1);
74
+ }
75
+ export async function mbHealthMain(exitFn = process.exit) {
76
+ await mbHealthCli('http://localhost:8283/health', 5000, exitFn);
77
+ }
@@ -1,7 +1,8 @@
1
1
  import EventEmitter from 'node:events';
2
2
  import { LogLevel } from 'node-ansi-logger';
3
3
  import type { Matterbridge } from './matterbridge.js';
4
- import { type MatterbridgePlatform, type PlatformConfig, type PlatformSchema } from './matterbridgePlatform.js';
4
+ import type { PlatformConfig, PlatformSchema } from './matterbridgePlatformTypes.js';
5
+ import { type MatterbridgePlatform } from './matterbridgePlatform.js';
5
6
  import { ApiPlugin, Plugin, PluginName, StoragePlugin } from './matterbridgeTypes.js';
6
7
  interface PluginManagerEvents {
7
8
  added: [name: string];
package/dist/worker.d.ts CHANGED
@@ -5,4 +5,3 @@ export declare function parentPost(message: ParentPortMessage): void;
5
5
  export declare function parentLog(logName: string | undefined, logLevel: LogLevel, message: string): void;
6
6
  export declare function createESMWorker(name: string, relativePath: string, workerData?: Record<string, boolean | number | string | object>, argv?: string[], env?: NodeJS.ProcessEnv, execArgv?: string[]): Worker;
7
7
  export declare function logWorkerInfo(log: AnsiLogger, logEnv?: boolean): void;
8
- export { ParentPortMessage };
@@ -3,6 +3,7 @@ import { AnsiLogger } from 'node-ansi-logger';
3
3
  import { hasParameter, inspectError } from '@matterbridge/utils';
4
4
  import { BroadcastServer } from './broadcastServer.js';
5
5
  import { logWorkerInfo, parentLog, parentPost } from './worker.js';
6
+ import { checkUpdates } from './checkUpdates.js';
6
7
  const debug = hasParameter('debug') || hasParameter('verbose');
7
8
  const verbose = hasParameter('verbose');
8
9
  if (!isMainThread && parentPort) {
@@ -16,6 +17,8 @@ if (verbose)
16
17
  logWorkerInfo(log, verbose);
17
18
  let success = false;
18
19
  try {
20
+ const shared = (await server.fetch({ type: 'matterbridge_shared', src: `matterbridge`, dst: 'matterbridge' })).result.data;
21
+ await checkUpdates(shared);
19
22
  success = true;
20
23
  log.debug(`Check updates succeeded`);
21
24
  if (!isMainThread && parentPort)
@@ -1,4 +1,4 @@
1
- import { LogLevel } from 'node-ansi-logger';
1
+ import type { LogLevel } from 'node-ansi-logger';
2
2
  export type ParentPortMessage = {
3
3
  type: 'init';
4
4
  threadName: string | null;
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.5.2-dev-20260128-beb91f9",
3
+ "version": "3.5.2-dev-20260130-b4e7ef3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.5.2-dev-20260128-beb91f9",
9
+ "version": "3.5.2-dev-20260130-b4e7ef3",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.16.7",
13
13
  "@matterbridge/dgram": "0.0.3",
14
14
  "@matterbridge/jest-utils": "0.0.1",
15
+ "@matterbridge/thread": "0.0.1",
15
16
  "@matterbridge/utils": "0.0.2",
16
17
  "@matterbridge/vitest-utils": "0.0.1",
17
18
  "archiver": "7.0.1",
@@ -25,6 +26,7 @@
25
26
  "bin": {
26
27
  "matterbridge": "bin/matterbridge.js",
27
28
  "mb_coap": "bin/mb_coap.js",
29
+ "mb_health": "bin/mb_health.js",
28
30
  "mb_mdns": "bin/mb_mdns.js"
29
31
  },
30
32
  "engines": {
@@ -189,6 +191,22 @@
189
191
  "url": "https://www.buymeacoffee.com/luligugithub"
190
192
  }
191
193
  },
194
+ "node_modules/@matterbridge/thread": {
195
+ "version": "0.0.1",
196
+ "resolved": "https://registry.npmjs.org/@matterbridge/thread/-/thread-0.0.1.tgz",
197
+ "integrity": "sha512-jKmsuPACQXmv2PBLIVSf11CfXW9+u5lJTBJ4j9CzYeRN85Jm7ptkiJH888Uf2wW3kSvk0wvuUO7I+sA1fORkFg==",
198
+ "license": "Apache-2.0",
199
+ "dependencies": {
200
+ "node-ansi-logger": "3.1.1"
201
+ },
202
+ "engines": {
203
+ "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
204
+ },
205
+ "funding": {
206
+ "type": "buymeacoffee",
207
+ "url": "https://www.buymeacoffee.com/luligugithub"
208
+ }
209
+ },
192
210
  "node_modules/@matterbridge/utils": {
193
211
  "version": "0.0.2",
194
212
  "resolved": "https://registry.npmjs.org/@matterbridge/utils/-/utils-0.0.2.tgz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.5.2-dev-20260128-beb91f9",
3
+ "version": "3.5.2-dev-20260130-b4e7ef3",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
@@ -44,7 +44,8 @@
44
44
  "bin": {
45
45
  "matterbridge": "bin/matterbridge.js",
46
46
  "mb_mdns": "bin/mb_mdns.js",
47
- "mb_coap": "bin/mb_coap.js"
47
+ "mb_coap": "bin/mb_coap.js",
48
+ "mb_health": "bin/mb_health.js"
48
49
  },
49
50
  "engines": {
50
51
  "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
@@ -111,6 +112,7 @@
111
112
  "@matter/main": "0.16.7",
112
113
  "@matterbridge/dgram": "0.0.3",
113
114
  "@matterbridge/jest-utils": "0.0.1",
115
+ "@matterbridge/thread": "0.0.1",
114
116
  "@matterbridge/utils": "0.0.2",
115
117
  "@matterbridge/vitest-utils": "0.0.1",
116
118
  "archiver": "7.0.1",