mb-run 0.0.2 → 0.0.3-dev-20260702-04dfa96

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/npm-shrinkwrap.json +6 -6
  3. package/package.json +3 -2
  4. package/vendor/.claude/rules/matterbridge/matterbridge.instructions.md +356 -0
  5. package/vendor/.claude/rules/testing/unit-tests.instructions.md +66 -0
  6. package/vendor/.claude/settings.json +45 -0
  7. package/vendor/.codex/config.toml +29 -0
  8. package/vendor/.codex/rules/default.rules +43 -0
  9. package/vendor/.devcontainer/devcontainer.json +133 -0
  10. package/vendor/.devcontainer/postCreateCommand.sh +37 -0
  11. package/vendor/.devcontainer/postStartCommand.sh +29 -0
  12. package/vendor/.devcontainer-plugin/devcontainer.json +150 -0
  13. package/vendor/.devcontainer-plugin/install-matterbridge-dev.sh +26 -0
  14. package/vendor/.devcontainer-plugin/install-matterbridge-main.sh +26 -0
  15. package/vendor/.devcontainer-plugin/postCreateCommand.sh +53 -0
  16. package/vendor/.devcontainer-plugin/postStartCommand.sh +32 -0
  17. package/vendor/.gitattributes +2 -0
  18. package/vendor/.github/FUNDING.yml +5 -0
  19. package/vendor/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  20. package/vendor/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  21. package/vendor/.github/copilot-instructions.md +17 -0
  22. package/vendor/.github/instructions/testing/unit-tests.instructions.md +62 -0
  23. package/vendor/.github/workflows/build.yml +75 -0
  24. package/vendor/.github/workflows/codecov.yml +73 -0
  25. package/vendor/.github/workflows/codeql.yml +40 -0
  26. package/vendor/.github/workflows/publish.yml +215 -0
  27. package/vendor/.github-plugin/FUNDING.yml +5 -0
  28. package/vendor/.github-plugin/ISSUE_TEMPLATE/bug_report.md +45 -0
  29. package/vendor/.github-plugin/ISSUE_TEMPLATE/feature_request.md +19 -0
  30. package/vendor/.github-plugin/copilot-instructions.md +17 -0
  31. package/vendor/.github-plugin/instructions/matterbridge/matterbridge.instructions.md +357 -0
  32. package/vendor/.github-plugin/instructions/testing/unit-tests.instructions.md +62 -0
  33. package/vendor/.github-plugin/workflows/build.yml +125 -0
  34. package/vendor/.github-plugin/workflows/codecov.yml +119 -0
  35. package/vendor/.github-plugin/workflows/codeql.yml +40 -0
  36. package/vendor/.github-plugin/workflows/publish.yml +330 -0
  37. package/vendor/.oxfmtrc.root.json +59 -0
  38. package/vendor/.oxlintrc.root.json +257 -0
  39. package/vendor/.prettierignore +22 -0
  40. package/vendor/.vscode/extensions.json +15 -0
  41. package/vendor/.vscode/extensions.native.json +16 -0
  42. package/vendor/.vscode/settings.json +56 -0
  43. package/vendor/.vscode/settings.native.json +56 -0
  44. package/vendor/.vscode/tasks.json +159 -0
  45. package/vendor/AGENTS.md +30 -0
  46. package/vendor/Branch protection.json +87 -0
  47. package/vendor/CHANGELOG.md +42 -0
  48. package/vendor/CLAUDE.md +17 -0
  49. package/vendor/CODEOWNERS +1 -0
  50. package/vendor/CODE_OF_CONDUCT.md +72 -0
  51. package/vendor/CONTRIBUTING.md +52 -0
  52. package/vendor/LICENSE +202 -0
  53. package/vendor/README.md +90 -0
  54. package/vendor/STYLEGUIDE.md +131 -0
  55. package/vendor/bunfig.toml +49 -0
  56. package/vendor/eslint.config.js +215 -0
  57. package/vendor/jest.config.js +70 -0
  58. package/vendor/matterbridge.svg +50 -0
  59. package/vendor/prettier.config.js +27 -0
  60. package/vendor/scripts/clean.mjs +57 -0
  61. package/vendor/scripts/create-release.mjs +175 -0
  62. package/vendor/scripts/deep-clean.mjs +77 -0
  63. package/vendor/scripts/downloads.mjs +273 -0
  64. package/vendor/scripts/esbuild.mjs +207 -0
  65. package/vendor/scripts/git-status.mjs +342 -0
  66. package/vendor/scripts/prepublish-clean.mjs +63 -0
  67. package/vendor/scripts/prune-releases.mjs +430 -0
  68. package/vendor/scripts/prune-tags.mjs +329 -0
  69. package/vendor/scripts/remove-workflows.mjs +420 -0
  70. package/vendor/scripts/run-automator.mjs +80 -0
  71. package/vendor/scripts/version.mjs +109 -0
  72. package/vendor/tsconfig.base.json +25 -0
  73. package/vendor/tsconfig.build.json +10 -0
  74. package/vendor/tsconfig.build.production.json +16 -0
  75. package/vendor/tsconfig.build.production.library.json +16 -0
  76. package/vendor/tsconfig.build.production.monorepo.json +15 -0
  77. package/vendor/tsconfig.jest.json +12 -0
  78. package/vendor/tsconfig.json +9 -0
  79. package/vendor/tsconfig.vitest.json +12 -0
  80. package/vendor/vite.config.ts +53 -0
package/CHANGELOG.md CHANGED
@@ -21,6 +21,16 @@ If you like this project and find it useful, please consider giving it a star on
21
21
 
22
22
  <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="120"></a>
23
23
 
24
+ ## [0.0.3] - Dev branch
25
+
26
+ ### Changed
27
+
28
+ - [package]: Update dependencies.
29
+ - [workflows]: Set node-version matrix back to: [22.x, 24.x, 26.x].
30
+ - [package]: Add vendor to files.
31
+
32
+ <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
33
+
24
34
  ## [0.0.2] - 2026-07-01
25
35
 
26
36
  ### Added
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "mb-run",
3
- "version": "0.0.2",
3
+ "version": "0.0.3-dev-20260702-04dfa96",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "mb-run",
9
- "version": "0.0.2",
9
+ "version": "0.0.3-dev-20260702-04dfa96",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "cross-spawn": "7.0.6",
13
13
  "esbuild": "0.28.1",
14
- "npm-check-updates": "22.2.7",
14
+ "npm-check-updates": "22.2.9",
15
15
  "rollup": "4.62.2",
16
16
  "rollup-plugin-dts": "6.4.1"
17
17
  },
@@ -984,9 +984,9 @@
984
984
  }
985
985
  },
986
986
  "node_modules/npm-check-updates": {
987
- "version": "22.2.7",
988
- "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-22.2.7.tgz",
989
- "integrity": "sha512-Pzs/lTswEe23hT8JUXABl4vgrr0WRKOhw55wAldwngUflk8CwP+grXJt00yGjYiZf2wD1HIfdPa3xaOi1RCyZQ==",
987
+ "version": "22.2.9",
988
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-22.2.9.tgz",
989
+ "integrity": "sha512-DVeZ0KirHfliSsHuR2o7cHE+tW439sVHfJjF6cGWeDiY0Wyl3BI/jS4zV0eixtcMOquFbcF1Su/FsxOvk5MoYA==",
990
990
  "license": "Apache-2.0",
991
991
  "bin": {
992
992
  "ncu": "build/cli.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mb-run",
3
- "version": "0.0.2",
3
+ "version": "0.0.3-dev-20260702-04dfa96",
4
4
  "description": "Matterbridge command line executor",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
@@ -61,13 +61,14 @@
61
61
  "files": [
62
62
  "bin",
63
63
  "dist",
64
+ "vendor",
64
65
  "npm-shrinkwrap.json",
65
66
  "CHANGELOG.md"
66
67
  ],
67
68
  "dependencies": {
68
69
  "cross-spawn": "7.0.6",
69
70
  "esbuild": "0.28.1",
70
- "npm-check-updates": "22.2.7",
71
+ "npm-check-updates": "22.2.9",
71
72
  "rollup": "4.62.2",
72
73
  "rollup-plugin-dts": "6.4.1"
73
74
  }
@@ -0,0 +1,356 @@
1
+ ---
2
+ description: 'How to create MatterbridgeEndpoint instances, register them in Matterbridge plugins, and use the single-class devices exported by the package v. 1.0.1'
3
+ ---
4
+
5
+ # Matterbridge Endpoint Guide
6
+
7
+ Use this guide when writing Matterbridge code in this repository or when authoring a plugin that consumes Matterbridge.
8
+
9
+ ## Public imports
10
+
11
+ - Import core classes, endpoint helpers, and device type definitions from `matterbridge`.
12
+ - Import single-class devices from `matterbridge/devices`.
13
+
14
+ ```ts
15
+ import {
16
+ MatterbridgeAccessoryPlatform,
17
+ MatterbridgeDynamicPlatform,
18
+ MatterbridgeEndpoint,
19
+ addFixedLabel,
20
+ addUserLabel,
21
+ contactSensor,
22
+ getAttribute,
23
+ onOffLight,
24
+ powerSource,
25
+ setAttribute,
26
+ subscribeAttribute,
27
+ updateAttribute,
28
+ } from 'matterbridge';
29
+
30
+ import { LaundryWasher, RoboticVacuumCleaner } from 'matterbridge/devices';
31
+ ```
32
+
33
+ ## Create a MatterbridgeEndpoint
34
+
35
+ `MatterbridgeEndpoint` is the low-level building block for custom Matterbridge devices.
36
+
37
+ Constructor:
38
+
39
+ ```ts
40
+ new MatterbridgeEndpoint(
41
+ definition: DeviceTypeDefinition | AtLeastOne<DeviceTypeDefinition>,
42
+ options: MatterbridgeEndpointOptions = {},
43
+ debug = false,
44
+ )
45
+ ```
46
+
47
+ Recommended pattern:
48
+
49
+ ```ts
50
+ const device = new MatterbridgeEndpoint([contactSensor, powerSource], { id: 'EntryDoor' })
51
+ .createDefaultIdentifyClusterServer()
52
+ .createDefaultBridgedDeviceBasicInformationClusterServer(
53
+ 'Entry Door',
54
+ 'ENTRY-DOOR-001',
55
+ 0xfff1,
56
+ 'Matterbridge',
57
+ 'Entry Door Sensor',
58
+ )
59
+ .createDefaultBooleanStateClusterServer(false)
60
+ .createDefaultPowerSourceReplaceableBatteryClusterServer(75)
61
+ .addRequiredClusters();
62
+ ```
63
+
64
+ Rules that matter:
65
+
66
+ - `definition` can be a single device type or an array of device types.
67
+ - Use multiple device types when the endpoint needs more than one role, for example `[contactSensor, powerSource]`.
68
+ - Call one of the Basic Information helpers before `registerDevice()`. Without `deviceName`, `serialNumber`, and `uniqueId`, registration fails.
69
+ - Call `addRequiredClusters()` at the end of the chain so any required clusters (server or client) that you did not explicitly create are added automatically.
70
+ - Use `addOptionalClusterServers()` only when you really want the optional clusters defined by the selected device type(s).
71
+
72
+ ## MatterbridgeEndpointOptions
73
+
74
+ `MatterbridgeEndpointOptions` supports:
75
+
76
+ - `id`: stable storage key for the endpoint.
77
+ - `number`: explicit endpoint number when you need one.
78
+ - `tagList`: semantic tags used for disambiguation, especially for composed devices or `mode: 'matter'` endpoints.
79
+ - `mode`: `undefined`, `'server'`, or `'matter'`.
80
+
81
+ Mode selection:
82
+
83
+ - `undefined`: normal bridged endpoint. This is the default for most DynamicPlatform devices.
84
+ - `'server'`: create an independent Matter device with its own server node.
85
+ - `'matter'`: add the endpoint directly to the Matterbridge server node alongside the aggregator.
86
+
87
+ Practical guidance:
88
+
89
+ - Use `mode: undefined` for normal bridged devices shown as children of the bridge.
90
+ - Use `mode: 'server'` when the device must be paired independently.
91
+ - Use `mode: 'matter'` when the device should be a native Matter endpoint on the server node.
92
+ - When using `mode: 'matter'`, respect Matter disambiguation rules and supply a `tagList` when sibling endpoints could be ambiguous.
93
+
94
+ Implementation details worth remembering:
95
+
96
+ - Spaces and `.` are removed from the internal endpoint id. The original value is retained as `originalId`.
97
+ - Non-Latin ids are normalized to a generated unique id.
98
+ - `id` should remain stable across restarts.
99
+
100
+ ## Choose the right Basic Information helper
101
+
102
+ Use the helper that matches how the endpoint is exposed:
103
+
104
+ - `createDefaultBasicInformationClusterServer(...)`
105
+ Use for `mode: 'server'`, `mode: 'matter'`, and AccessoryPlatform devices.
106
+ - `createDefaultBridgedDeviceBasicInformationClusterServer(...)`
107
+ Use for bridged DynamicPlatform endpoints.
108
+
109
+ Important behavior:
110
+
111
+ - `createDefaultBasicInformationClusterServer(...)` sets the metadata on the endpoint.
112
+ - For bridged endpoints, `registerDevice()` can add the `BridgedDeviceBasicInformation` cluster automatically when the device is running as a bridged endpoint in bridge mode, or in childbridge mode on a `DynamicPlatform`.
113
+ - Explicitly calling `createDefaultBridgedDeviceBasicInformationClusterServer(...)` is clearer for bridged devices and matches the repo examples.
114
+
115
+ ## Register the endpoint from a plugin
116
+
117
+ In plugin code, prefer `this.registerDevice(device)` instead of calling Matterbridge internals directly.
118
+
119
+ DynamicPlatform bridged device:
120
+
121
+ ```ts
122
+ import { MatterbridgeDynamicPlatform, MatterbridgeEndpoint, onOffLight } from 'matterbridge';
123
+
124
+ export default function initializePlugin(matterbridge, log, config) {
125
+ return new ExamplePlatform(matterbridge, log, config);
126
+ }
127
+
128
+ class ExamplePlatform extends MatterbridgeDynamicPlatform {
129
+ async onStart(reason) {
130
+ await this.ready;
131
+
132
+ const device = new MatterbridgeEndpoint(onOffLight, { id: 'OnOffLightPlugin' })
133
+ .createDefaultBridgedDeviceBasicInformationClusterServer(
134
+ 'Kitchen Light',
135
+ 'LIGHT-001',
136
+ 0xfff1,
137
+ 'Matterbridge',
138
+ 'Matterbridge OnOffLight',
139
+ )
140
+ .addRequiredClusterServers();
141
+
142
+ await this.registerDevice(device);
143
+ }
144
+ }
145
+ ```
146
+
147
+ AccessoryPlatform device:
148
+
149
+ ```ts
150
+ import { MatterbridgeAccessoryPlatform, MatterbridgeEndpoint, temperatureSensor } from 'matterbridge';
151
+
152
+ export default function initializePlugin(matterbridge, log, config) {
153
+ return new ExamplePlatform(matterbridge, log, config);
154
+ }
155
+
156
+ class ExamplePlatform extends MatterbridgeAccessoryPlatform {
157
+ async onStart(reason) {
158
+ await this.ready;
159
+
160
+ const device = new MatterbridgeEndpoint(temperatureSensor, { id: 'TemperatureSensorPlugin' })
161
+ .createDefaultBasicInformationClusterServer(
162
+ 'Temperature Sensor',
163
+ 'TEMP-001',
164
+ 0xfff1,
165
+ 'Matterbridge',
166
+ 0x8000,
167
+ 'Matterbridge Temperature Sensor',
168
+ )
169
+ .addRequiredClusterServers();
170
+
171
+ await this.registerDevice(device);
172
+ }
173
+ }
174
+ ```
175
+
176
+ Standalone Matter device from a plugin:
177
+
178
+ ```ts
179
+ const device = new MatterbridgeEndpoint(pressureSensor, { id: 'ServerNodeDevice', mode: 'server' })
180
+ .createDefaultBasicInformationClusterServer(
181
+ 'Server Node Device',
182
+ 'SERVER-001',
183
+ 0xfff1,
184
+ 'Matterbridge',
185
+ 0x8000,
186
+ 'Matterbridge Server Node Device',
187
+ )
188
+ .addRequiredClusterServers();
189
+
190
+ await this.registerDevice(device);
191
+ ```
192
+
193
+ Native Matter endpoint on the server node:
194
+
195
+ ```ts
196
+ const device = new MatterbridgeEndpoint(pressureSensor, { id: 'MatterNodeDevice', mode: 'matter' })
197
+ .createDefaultBasicInformationClusterServer(
198
+ 'Matter Node Device',
199
+ 'MATTER-001',
200
+ 0xfff1,
201
+ 'Matterbridge',
202
+ 0x8000,
203
+ 'Matterbridge Matter Node Device',
204
+ )
205
+ .addRequiredClusterServers();
206
+
207
+ await this.registerDevice(device);
208
+ ```
209
+
210
+ Plugin rules:
211
+
212
+ - `await this.ready` before creating or registering devices.
213
+ - Always call `this.registerDevice(device)` from the platform.
214
+ - Use `this.unregisterDevice(device)` or `this.unregisterAllDevices()` during shutdown or development resets.
215
+ - AccessoryPlatform plugins can only expose one normal accessory device. If you need multiple bridged devices, use `MatterbridgeDynamicPlatform`.
216
+ - Use stable names and serial numbers so the derived `uniqueId` stays stable.
217
+
218
+ ## Useful MatterbridgeEndpoint helpers
219
+
220
+ Common helpers on the endpoint instance:
221
+
222
+ - `hasClusterServer(cluster)`
223
+ - `hasAttributeServer(cluster, attribute)`
224
+ - `getAttribute(cluster, attribute)`
225
+ - `setAttribute(cluster, attribute, value)`
226
+ - `updateAttribute(cluster, attribute, value)`
227
+ - `subscribeAttribute(cluster, attribute, listener)`
228
+ - `addRequiredClusterServers()`
229
+ - `addOptionalClusterServers()`
230
+ - `addRequiredClusters()`
231
+
232
+ Example:
233
+
234
+ ```ts
235
+ await device.updateAttribute('OnOff', 'onOff', true);
236
+ ```
237
+
238
+ Cluster references can be passed in several ways:
239
+
240
+ - behavior type
241
+ - cluster type
242
+ - cluster id
243
+ - cluster name string such as `'OnOff'`
244
+
245
+ Behavior type and cluster type are preferred because they are type-safe and avoid typos.
246
+
247
+ Using the cluster name string is useful in plugins because it avoids importing every cluster type.
248
+
249
+ ## When to use a raw endpoint vs a single-class device
250
+
251
+ Use a raw `MatterbridgeEndpoint` when:
252
+
253
+ - you are building a custom combination of device types and clusters
254
+ - you want full control over which default cluster servers are created
255
+ - you are implementing a plugin-specific device model
256
+
257
+ Use a single-class device when:
258
+
259
+ - Matterbridge already ships a class for the device category you need
260
+ - you want a working device with sensible default clusters and behaviors
261
+ - you prefer a higher-level constructor over manual endpoint assembly
262
+
263
+ ## Single-class devices
264
+
265
+ Single-class devices are exported from `matterbridge/devices`.
266
+
267
+ These classes already extend `MatterbridgeEndpoint` and usually do all of the following internally:
268
+
269
+ - create the correct device type combination
270
+ - create Basic Information
271
+ - create Power Source when needed
272
+ - create the default cluster servers and behavior wiring required by the device
273
+
274
+ Current exported single-class devices:
275
+
276
+ - Media: `BasicVideoPlayer`, `CastingVideoPlayer`, `Speaker`
277
+ - Matter 1.5 additions: `Closure`, `ClosurePanel`, `IrrigationSystem`, `SoilSensor`
278
+ - Robotic: `RoboticVacuumCleaner`
279
+ - Appliances: `AirConditioner`, `Cooktop`, `Dishwasher`, `ExtractorHood`, `LaundryDryer`, `LaundryWasher`, `MicrowaveOven`, `Oven`, `Refrigerator`
280
+ - Energy: `BatteryStorage`, `Evse`, `HeatPump`, `SolarPower`, `WaterHeater`
281
+
282
+ ### Basic single-class example
283
+
284
+ ```ts
285
+ import { LaundryWasher } from 'matterbridge/devices';
286
+
287
+ const washer = new LaundryWasher('Laundry Washer', 'LW-001');
288
+ await this.registerDevice(washer);
289
+ ```
290
+
291
+ This is enough because the class constructor already creates the required device types, basic information, power source, and default cluster servers.
292
+
293
+ ### Single-class example with explicit mode
294
+
295
+ Some single-class devices expose `mode` directly in their constructor. For example:
296
+
297
+ ```ts
298
+ import { RoboticVacuumCleaner } from 'matterbridge/devices';
299
+
300
+ const robot = new RoboticVacuumCleaner('Robot Vacuum', 'RVC-001', 'server');
301
+ await this.registerDevice(robot);
302
+ ```
303
+
304
+ Use this when the class supports it and you want a standalone or native Matter device instead of a bridged endpoint.
305
+
306
+ ### Composed single-class devices
307
+
308
+ Some single-class devices are composed devices and need child endpoints added after construction:
309
+
310
+ - `Oven`: create the oven, then call `addCabinet(...)`
311
+ - `Cooktop`: create the cooktop, then call `addSurface(...)`
312
+ - `Refrigerator`: create the refrigerator, then call `addCabinet(...)`
313
+
314
+ Example:
315
+
316
+ ```ts
317
+ import { PositionTag } from '@matter/node';
318
+ import { Cooktop } from 'matterbridge/devices';
319
+
320
+ const cooktop = new Cooktop('Cooktop', 'CT-001');
321
+ cooktop.addSurface('Surface Top Left', [
322
+ { mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: PositionTag.Top.label },
323
+ { mfgCode: null, namespaceId: PositionTag.Left.namespaceId, tag: PositionTag.Left.tag, label: PositionTag.Left.label },
324
+ ]);
325
+
326
+ await this.registerDevice(cooktop);
327
+ ```
328
+
329
+ For composed devices and for `mode: 'matter'`, use semantic tags carefully. `tagList` exists to satisfy Matter endpoint disambiguation rules.
330
+
331
+ ## Recommended plugin workflow
332
+
333
+ For most plugins, follow this order:
334
+
335
+ 1. Wait for `this.ready`.
336
+ 2. Create the endpoint or single-class device.
337
+ 3. Set device identity with one of the Basic Information helpers if you are using a raw `MatterbridgeEndpoint`.
338
+ 4. Add explicit cluster servers you need.
339
+ 5. Call `addRequiredClusterServers()` last.
340
+ 6. Register the device with `await this.registerDevice(device)`.
341
+ 7. Optionally add UI metadata with `setSelectDevice()` and `setSelectEntity()`.
342
+
343
+ ## Avoid these mistakes
344
+
345
+ - Do not register a raw `MatterbridgeEndpoint` before assigning basic identity metadata.
346
+ - Do not use `MatterbridgeAccessoryPlatform` for multiple normal bridged accessories.
347
+ - Do not forget that some bridged endpoints need semantic tags for disambiguation.
348
+ - Do not assume single-class devices all share the same constructor shape. Check the device class when you need custom defaults or a mode argument.
349
+ - Do not call Matterbridge internals directly from plugin code when `registerDevice()` already handles validation and mode-specific setup.
350
+
351
+ ## Short decision guide
352
+
353
+ - Need a custom sensor, switch, or actuator with a few clusters: use `MatterbridgeEndpoint`.
354
+ - Need a supported appliance, robotic, media, energy, closure, irrigation, or soil device: start with `matterbridge/devices`.
355
+ - Need one standalone accessory with its own server node: use `mode: 'server'` or a single-class device that exposes it.
356
+ - Need multiple bridged devices in a plugin: use `MatterbridgeDynamicPlatform`.
@@ -0,0 +1,66 @@
1
+ ---
2
+ description: 'Testing standards for unit tests in the project v.1.0.3'
3
+ paths:
4
+ - '**/src/**/*.test.ts'
5
+ - '**/src/**/*.spec.ts'
6
+ - '**/test/**/*.ts'
7
+ - '**/vitest/**/*.ts'
8
+ - '**/buntest/**/*.ts'
9
+ ---
10
+
11
+ # Testing Standards for Unit Tests
12
+
13
+ ## 1. Test Framework
14
+
15
+ - Jest is available in the repository when the file `jest.config.js` exists.
16
+ - Vitest is available in the repository when the file `vite.config.ts` exists.
17
+ - Bun test is available in the repository when the file `bunfig.toml` exists.
18
+ - Jest tests live in `test` folders. Follow the existing convention in the repository for test file placement.
19
+ - Vitest tests live in `vitest` folders. Follow the existing convention in the repository for test file placement.
20
+ - Bun test tests live in `buntest` folders. Follow the existing convention in the repository for test file placement.
21
+ - Ensure that tests are written in TypeScript and follow the ESM module format.
22
+
23
+ ## 2. Test Structure
24
+
25
+ - Organize tests in file name `*.test.ts` in the `test`, `vitest`, or `buntest` folders.
26
+ - Use `describe` blocks to group related tests and `test` blocks for individual test cases.
27
+
28
+ ## 3. Test Naming
29
+
30
+ - Use descriptive test names that clearly indicate the behavior being tested.
31
+ - Follow the format: `should [expected behavior] when [condition]`.
32
+
33
+ ## 4. Test Data
34
+
35
+ - Use small, deterministic test data to ensure tests are reliable and easy to understand.
36
+
37
+ ## 5. Test Coverage
38
+
39
+ - Aim for high test coverage, but prioritize meaningful tests over achieving 100% coverage.
40
+
41
+ ## 6. Mocking with Jest
42
+
43
+ - If using Jest, use `jest.unstable_mockModule` for mocking dependencies in ESM modules.
44
+ - If using Jest, avoid using `jest.mock` as it is not compatible with ESM modules.
45
+
46
+ ## 7. Running Tests
47
+
48
+ - Run the relevant full test unit from start to finish rather than assuming isolated single-test execution is reliable.
49
+ - If only one test framework is installed, use `npm run test -- yourTest.test.ts` or `npm run test:coverage -- yourTest.test.ts` when the touched area can be validated by running the full relevant test file.
50
+ - When both Jest and Vitest are installed, use `npm run test -- yourTest.test.ts` for Jest or `npm run test:vitest -- yourTest.test.ts` for Vitest.
51
+ - When Bun test is installed, use `bun test yourTest.test.ts`.
52
+ - Use the existing `tasks.json` test tasks for areas that require grouped test files, custom coverage targets, or custom ignore-pattern handling.
53
+ - Avoid running all tests unnecessarily to save time and tokens.
54
+
55
+ ## 8. Test Assertions
56
+
57
+ - Use appropriate Jest, Vitest, or Bun test matchers for assertions (e.g., `toBe`, `toEqual`, `toThrow`).
58
+ - Ensure that assertions are clear and directly related to the behavior being tested.
59
+
60
+ ## 9. Performance
61
+
62
+ - Avoid optimization in tests; focus on correctness and clarity.
63
+ - Use simple loops and structures in tests to maintain readability and performance.
64
+ - Avoid complex setups that may slow down test execution unless necessary for the behavior being tested.
65
+ - Prefer simple test cases that are easy to understand and maintain over complex ones that may be difficult to debug.
66
+ - Some tests in this repo are intentionally structured as multi-step flows, where state persists across successive steps within a single test unit. Run those test units in full, and keep each test unit isolated from other test units.
@@ -0,0 +1,45 @@
1
+ // Claude settings v. 1.0.1
2
+ {
3
+ "$schema": "https://json.schemastore.org/claude-code-settings.json",
4
+ "permissions": {
5
+ "deny": [
6
+ "Read(./.env)",
7
+ "Read(./.env.*)",
8
+ "Read(./**/secrets/**)",
9
+ "Bash(git pull:*)",
10
+ "Bash(git merge:*)",
11
+ "Bash(git push:*)",
12
+ "Bash(git rebase:*)",
13
+ "Bash(git commit --amend:*)",
14
+ "Bash(git reset --hard:*)",
15
+ "Bash(git filter-branch:*)",
16
+ "Bash(git branch -D:*)",
17
+ "Bash(git branch -d:*)",
18
+ "Bash(git tag -d:*)",
19
+ "Bash(git reflog expire:*)",
20
+ "Bash(git reflog delete:*)",
21
+ "Bash(git push --delete:*)",
22
+ "Bash(git push --force:*)",
23
+ "Bash(git push -f:*)"
24
+ ],
25
+ "ask": [
26
+ "Bash(git commit:*)",
27
+ "Bash(npm install:*)",
28
+ "Bash(npm i:*)",
29
+ "Bash(npm uninstall:*)",
30
+ "Bash(bun install:*)",
31
+ "Bash(bun i:*)",
32
+ "Bash(bun uninstall:*)",
33
+ "Bash(bun add:*)",
34
+ "Bash(bun remove:*)"
35
+ ],
36
+ "allow": [
37
+ "Bash(npm run typecheck)",
38
+ "Bash(npm run build)",
39
+ "Bash(npm run test:*)",
40
+ "Bash(npm run lint)",
41
+ "Bash(npm run format)",
42
+ "Bash(bun test)"
43
+ ]
44
+ }
45
+ }
@@ -0,0 +1,29 @@
1
+ # Codex config v. 1.0.1
2
+
3
+ approval_policy = "on-request"
4
+ approvals_reviewer = "user"
5
+ default_permissions = "matterbridge_safe"
6
+ web_search = "live"
7
+
8
+ [shell_environment_policy]
9
+ inherit = "core"
10
+
11
+ [windows]
12
+ sandbox = "elevated"
13
+
14
+ [permissions.matterbridge_safe.network]
15
+ enabled = false
16
+
17
+ [permissions.matterbridge_safe]
18
+ description = "Workspace access with sensitive files denied and network disabled."
19
+ extends = ":workspace"
20
+
21
+ [permissions.matterbridge_safe.filesystem]
22
+ glob_scan_max_depth = 4
23
+
24
+ [permissions.matterbridge_safe.filesystem.":workspace_roots"]
25
+ ".env" = "deny"
26
+ ".env.*" = "deny"
27
+ "**/.env" = "deny"
28
+ "**/.env.*" = "deny"
29
+ "**/secrets/**" = "deny"
@@ -0,0 +1,43 @@
1
+ # Codex rules v. 1.0.1
2
+
3
+ # Git mutations
4
+ prefix_rule(pattern = ["git", "pull"], decision = "forbidden", justification = "Do not change local refs without explicit manual control.")
5
+ prefix_rule(pattern = ["git", "merge"], decision = "forbidden", justification = "Do not merge automatically.")
6
+ prefix_rule(pattern = ["git", "push"], decision = "forbidden", justification = "Do not push automatically.")
7
+ prefix_rule(pattern = ["git", "rebase"], decision = "forbidden", justification = "Do not rewrite branch history automatically.")
8
+ prefix_rule(pattern = ["git", "commit"], decision = "forbidden", justification = "Do not create commits automatically.")
9
+ prefix_rule(pattern = ["git", "commit", "--amend"], decision = "forbidden", justification = "Do not amend commits automatically.")
10
+ prefix_rule(pattern = ["git", "reset", "--hard"], decision = "forbidden", justification = "Destructive reset is blocked.")
11
+ prefix_rule(pattern = ["git", "filter-branch"], decision = "forbidden", justification = "History rewriting is blocked.")
12
+ prefix_rule(pattern = ["git", "branch", "-D"], decision = "forbidden", justification = "Branch deletion is blocked.")
13
+ prefix_rule(pattern = ["git", "branch", "-d"], decision = "forbidden", justification = "Branch deletion is blocked.")
14
+ prefix_rule(pattern = ["git", "tag", "-d"], decision = "forbidden", justification = "Tag deletion is blocked.")
15
+ prefix_rule(pattern = ["git", "reflog", "expire"], decision = "forbidden", justification = "Reflog mutation is blocked.")
16
+ prefix_rule(pattern = ["git", "reflog", "delete"], decision = "forbidden", justification = "Reflog mutation is blocked.")
17
+
18
+ # Dependency installs
19
+ prefix_rule(pattern = ["npm", "install"], decision = "prompt", justification = "Ask before installing dependencies.")
20
+ prefix_rule(pattern = ["npm", "i"], decision = "prompt", justification = "Ask before installing dependencies.")
21
+ prefix_rule(pattern = ["npm", "uninstall"], decision = "prompt", justification = "Ask before uninstalling dependencies.")
22
+ prefix_rule(pattern = ["bun", "install"], decision = "prompt", justification = "Ask before installing dependencies.")
23
+ prefix_rule(pattern = ["bun", "i"], decision = "prompt", justification = "Ask before installing dependencies.")
24
+ prefix_rule(pattern = ["bun", "uninstall"], decision = "prompt", justification = "Ask before uninstalling dependencies.")
25
+ prefix_rule(pattern = ["bun", "add"], decision = "prompt", justification = "Ask before installing dependencies.")
26
+ prefix_rule(pattern = ["bun", "remove"], decision = "prompt", justification = "Ask before uninstalling dependencies.")
27
+
28
+ # Validation scripts
29
+ prefix_rule(pattern = ["npm", "run", "typecheck"], decision = "allow")
30
+ prefix_rule(pattern = ["npm", "run", "build"], decision = "allow")
31
+ prefix_rule(pattern = ["npm", "run", "test"], decision = "allow")
32
+ prefix_rule(pattern = ["npm", "run", "test:watch"], decision = "allow")
33
+ prefix_rule(pattern = ["npm", "run", "test:verbose"], decision = "allow")
34
+ prefix_rule(pattern = ["npm", "run", "test:coverage"], decision = "allow")
35
+ prefix_rule(pattern = ["npm", "run", "lint"], decision = "allow")
36
+ prefix_rule(pattern = ["npm", "run", "format"], decision = "allow")
37
+ prefix_rule(pattern = ["bun", "test"], decision = "allow")
38
+
39
+ # External network and containers
40
+ prefix_rule(pattern = ["curl"], decision = "prompt", justification = "Ask before external network fetches.")
41
+ prefix_rule(pattern = ["Invoke-WebRequest"], decision = "prompt", justification = "Ask before external network fetches.")
42
+ prefix_rule(pattern = ["docker", "pull"], decision = "prompt", justification = "Ask before downloading Docker images.")
43
+ prefix_rule(pattern = ["docker", "run"], decision = "prompt", justification = "Ask before running Docker containers.")