Skip to content
Open
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
814a572
feat(node): add Behaviors.forCluster and cluster name/id resolver
Apollon77 Jul 14, 2026
d5fe0d3
feat(node): add Peers.commissioned view
Apollon77 Jul 14, 2026
187bd20
feat(node): add NodeLifecycle.isSeeded/seeded
Apollon77 Jul 14, 2026
181b4f4
feat(node): add commissioning-window helpers on CommissioningClient/C…
Apollon77 Jul 14, 2026
218f6a4
feat(protocol): emit establishment-unresponsive signal after MRP budg…
Apollon77 Jul 14, 2026
de8771b
feat(node): connection-state engine on NetworkClient exposed via Node…
Apollon77 Jul 14, 2026
3a45073
fix(node): redefine connection-state Disconnected as stopped/not-started
Apollon77 Jul 14, 2026
3b9fad2
fix(node): dispose seeded listener after latch; document startup-time…
Apollon77 Jul 14, 2026
5f9e8b1
refactor(types): relocate cluster name/id resolver to ClusterHelper w…
Apollon77 Jul 14, 2026
e8a0504
chore(matter.js): deprecate legacy controller/device API for 0.19 rem…
Apollon77 Jul 14, 2026
df9bfec
docs: add controller migration guide (MIGRATION_CONTROLLER_018, WIP)
Apollon77 Jul 14, 2026
b1ea69c
fix(node): register peer BasicInformation handlers once to prevent du…
Apollon77 Jul 15, 2026
fd2faeb
fix(node): register bridged ConfigurationVersion handler once
Apollon77 Jul 15, 2026
8c4d016
docs: fill migration guide subscription/event-bus/FAQ sections with c…
Apollon77 Jul 15, 2026
24e07fc
Potential fix for pull request finding
Apollon77 Jul 15, 2026
b68c500
docs: map legacy autoConnect/autoSubscribe to NetworkClient state in …
Apollon77 Jul 15, 2026
e4a4504
docs: document node enable/disable and automatic bulk connect in migr…
Apollon77 Jul 15, 2026
89adb50
docs: lead event-bus migration with ChangeNotificationService aggrega…
Apollon77 Jul 15, 2026
4a1ee17
refactor(node): split client-only lifecycle surface into ClientNodeLi…
Apollon77 Jul 15, 2026
2fa68ae
refactor(types): group cluster name/id resolvers under ClusterLookup …
Apollon77 Jul 16, 2026
590234d
chore: stop tracking local plan doc, gitignore docs/superpowers
Apollon77 Jul 16, 2026
41e9e47
feat(shell): add ServerNode/peers-backed ClientNode methods to Matter…
Apollon77 Jul 16, 2026
2b62169
fix(shell): tear down subscription via disable() for autoConnect:fals…
Apollon77 Jul 16, 2026
819712b
refactor(shell): migrate cmd_nodes to ClientNode/peers
Apollon77 Jul 16, 2026
e7a5f6b
fix(shell): migrate cmd_nodes fabric lookup + OTA off legacy Commissi…
Apollon77 Jul 16, 2026
b7fc1a9
refactor(shell): migrate cmd_commission to ClientNode API
Apollon77 Jul 16, 2026
303bdc3
refactor(shell): migrate cluster attribute/command/event commands to …
Apollon77 Jul 16, 2026
db06cad
refactor(shell): migrate cmd_subscribe to auto-subscribe + ChangeNoti…
Apollon77 Jul 16, 2026
e873862
refactor(shell): migrate cmd_icd to ClientNode lifecycle/IcdClient
Apollon77 Jul 16, 2026
9bf817e
refactor(shell): migrate cmd_identify/session/discover to ClientNode/…
Apollon77 Jul 16, 2026
d24f902
refactor(shell): remove CommissioningController backing, finalize Cli…
Apollon77 Jul 16, 2026
a992c0d
fix(shell): tidy cmd_icd watch teardown and restore cmd_discover dedupe
Apollon77 Jul 16, 2026
a726192
fix(shell): defer controller node creation/start to first use (restor…
Apollon77 Jul 17, 2026
6cb04a6
feat(node): add NetworkServer.autoStartCommissionedPeers opt-out for …
Apollon77 Jul 17, 2026
6dbed91
fix(shell): opt out of peer auto-connect, connect/subscribe on demand
Apollon77 Jul 17, 2026
a7c6ef4
docs: document NetworkServer.autoStartCommissionedPeers in controller…
Apollon77 Jul 17, 2026
5264c27
fix(shell): normalize autoSubscribe once at startup so connect no lon…
Apollon77 Jul 17, 2026
57271a3
fix(shell): enable disabled peers on connect
Apollon77 Jul 17, 2026
46bbe96
docs: clarify autoStartCommissionedPeers=false requires explicit enab…
Apollon77 Jul 17, 2026
90ed9ad
fix(shell): controller uses ephemeral operational port, not standard …
Apollon77 Jul 17, 2026
e5b05e7
feat(node): default controller operational port to ephemeral when unset
Apollon77 Jul 17, 2026
b2d7be0
fix(shell): drop port:0 workaround now handled by the library
Apollon77 Jul 17, 2026
b26b1ed
fix(shell): restore OTA field guards, promise-cache node lifecycle, r…
Apollon77 Jul 18, 2026
51151a3
docs: complete controller migration guide from the shell blueprint (d…
Apollon77 Jul 18, 2026
9b023d7
Merge remote-tracking branch 'origin/main' into worktree-feat+clientn…
Apollon77 Jul 18, 2026
eff26ae
feat(shell): close phase-2 ClientNode migration gaps
Apollon77 Jul 18, 2026
76677ff
refactor(shell): format seeded-wait timeout with Duration.format
Apollon77 Jul 18, 2026
d9fba6c
Merge branch 'main' into feat/clientnode-controller-api
Apollon77 Jul 18, 2026
ae6f2ad
docs: clarify autoStartCommissionedPeers vs per-node disable use cases
Apollon77 Jul 18, 2026
64844c8
fix: address #4091 review comments (passcode logging, establishment o…
Apollon77 Jul 18, 2026
273be0e
docs(migration): fabric-label propagation recipe, negotiated interval…
Apollon77 Jul 18, 2026
362e79d
feat(node): add Peers.completeCommissioning for split commissioning
Apollon77 Jul 19, 2026
dbae66e
fix(node): seed discoveryData on live peer + clean up on completeComm…
Apollon77 Jul 19, 2026
fe5c3d4
test(node): cover completeCommissioning non-Ok CommissioningComplete …
Apollon77 Jul 19, 2026
8d5fce8
docs: document finalizeCommissioning PASE-only + split-commissioning …
Apollon77 Jul 19, 2026
8638943
fix(node): guard completeCommissioning against deleting an already-co…
Apollon77 Jul 19, 2026
850d730
test(node): deterministically await re-announcement in failsafe commi…
Apollon77 Jul 19, 2026
277449f
feat(node): send CommissioningComplete with extended failsafe respons…
Apollon77 Jul 19, 2026
6c46f76
fix(node): persist fabric before the node in completeCommissioning (b…
Apollon77 Jul 19, 2026
cca8dfd
fix(node): require an existing shared fabric in completeCommissioning
Apollon77 Jul 19, 2026
28b2531
test(node): cover completeCommissioning rejecting when the shared fab…
Apollon77 Jul 19, 2026
a4b80b2
test(node): comment audit — drop WHAT-restating comments, fix stale i…
Apollon77 Jul 20, 2026
6ff62ca
docs(node): finalizeCommissioning is awaited — document return/throw …
Apollon77 Jul 20, 2026
19e9038
Merge branch 'main' into feat/clientnode-controller-api
Apollon77 Jul 20, 2026
5c6d828
fix(node): address final review — completeCommissioning seeding + polish
Apollon77 Jul 20, 2026
80d7979
fix: address #4091 PR review comments
Apollon77 Jul 20, 2026
a5c301a
Merge branch 'main' into feat/clientnode-controller-api
Apollon77 Jul 21, 2026
547483c
fix(shell): reject partial ip/port in commission command
Apollon77 Jul 21, 2026
6c6b4f6
Merge branch 'main' into feat/clientnode-controller-api
Apollon77 Jul 21, 2026
062facd
Merge branch 'main' into feat/clientnode-controller-api
Apollon77 Jul 27, 2026
b762c2b
Merge remote-tracking branch 'origin/main' into feat/clientnode-contr…
Apollon77 Jul 27, 2026
533ef8a
docs(changelog): move unreleased controller-API entries to WORK IN PR…
Apollon77 Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ isolated-*.log
/.caude/
.claude/
docs/plans/

# Local planning/SDD scratch (never committed)
docs/superpowers/
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@ The main work (all changes without a GitHub username in brackets in the below li
- Fix: `Heap` now stores each item at most once and maintains its position index eagerly, so deleting an item added after an earlier deletion works reliably

- @matter/node
- Feature: Added `NetworkServer.autoStartCommissionedPeers` (default true) to opt out of auto-connecting commissioned peers when the node goes online
- Feature: Added `openBasicCommissioningWindow`/`openEnhancedCommissioningWindow` on `CommissioningClient`/`ClientNode` to open a commissioning window on a commissioned peer
- Feature: Added `NodeLifecycle.isSeeded` and the `seeded` event, indicating a peer node's structure has been read at least once
- Change: A node with commissioning disabled (e.g. a controller) now binds an ephemeral operational port instead of the standard Matter port (5540) when `NetworkServer.port` is unset; commissionable nodes still default to 5540 and an explicit port is always honored
- Fix: `endpoints.size` no longer double-counts the root endpoint
- Fix: Optimize Cluster data updates when structures change for ClientNodes
- Fix: Prevent subscriptions from being activated on a closing session

- @matter/protocol
- Enhancement: Connect to a newly discovered address as soon as it supersedes the previously cached address instead of waiting out the connection retry delay
- Fix: Ensure the commissioning failsafe timer stays within the device's maximum cumulative failsafe

- @project-chip/matter.js
- Deprecation: The legacy controller/device API (CommissioningController, PairedNode, Device/Endpoint/Aggregator, cluster clients) is deprecated and will be removed in 0.19; migrate to @matter/node

## 0.17.6 (2026-07-16)

- @matter/general
Expand Down
675 changes: 675 additions & 0 deletions docs/MIGRATION_CONTROLLER_018.md

Large diffs are not rendered by default.

93 changes: 83 additions & 10 deletions packages/matter.js/src/CommissioningController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function discoveryKey(
return JSON.stringify({ id: identifierData, caps: discoveryCapabilities });
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
export async function runDiscoverCommissionableDevices(
node: ServerNode,
identifierData: CommissionableDeviceIdentifiers,
Expand Down Expand Up @@ -113,6 +114,7 @@ export async function runDiscoverCommissionableDevices(
}
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
export function cancelDiscoverCommissionableDevices(
identifierData: CommissionableDeviceIdentifiers,
discoveryCapabilities: TypeFromPartialBitSchema<typeof DiscoveryCapabilitiesBitmap> | undefined,
Expand All @@ -125,6 +127,9 @@ export function cancelDiscoverCommissionableDevices(
// TODO decline using setRoot*Cluster
// TODO Decline cluster access after announced/paired

/**
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
export type ControllerEnvironmentOptions = {
/**
* Environment to register the node with on start()
Expand All @@ -139,6 +144,8 @@ export type ControllerEnvironmentOptions = {

/**
* Constructor options for the CommissioningController class
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
export type CommissioningControllerOptions = CommissioningControllerNodeOptions & {
/**
Expand Down Expand Up @@ -238,6 +245,8 @@ export type CommissioningControllerOptions = CommissioningControllerNodeOptions
/**
* Configuration for performing discovery + commissioning in one step.
* Kept in the legacy matter.js package; new code uses {@link CommissioningDiscovery.Options} directly.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
export interface DiscoveryAndCommissioningOptions extends CommissioningOptions {
/** Discovery related options. */
Expand Down Expand Up @@ -275,14 +284,22 @@ export interface DiscoveryAndCommissioningOptions extends CommissioningOptions {
};
}

/** Options needed to commission a new node */
/**
* Options needed to commission a new node
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
export type NodeCommissioningOptions = CommissioningControllerNodeOptions & {
commissioning: Omit<DiscoveryAndCommissioningOptions, "fabric" | "discovery" | "passcode">;
discovery: DiscoveryAndCommissioningOptions["discovery"];
passcode: number;
};

/** Controller class to commission and connect multiple nodes into one fabric. */
/**
* Controller class to commission and connect multiple nodes into one fabric.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
export class CommissioningController {
#crypto: Crypto;
#started = false;
Expand All @@ -308,6 +325,7 @@ export class CommissioningController {
* Creates a new CommissioningController instance
*
* @param options The options for the CommissioningController
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
constructor(options: CommissioningControllerOptions) {
if (options.environment === undefined) {
Expand All @@ -323,28 +341,39 @@ export class CommissioningController {
this.#crypto.reportUsage();
}

/** Returns the controller node instance. Throws an error when called before start() or after close(). */
/**
* Returns the controller node instance. Throws an error when called before start() or after close().
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
get node(): ServerNode {
return this.#assertControllerIsStarted().node;
}

/**
* Returns the OTA provider endpoint on the controller node, if enabled and controller node was started.
* Else throws an error.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
get otaProvider(): Endpoint<OtaProviderEndpoint> {
return this.#assertControllerIsStarted().node.endpoints.for("ota-provider") as Endpoint<OtaProviderEndpoint>;
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
get crypto() {
return this.#crypto;
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
get nodeId() {
return this.#controllerInstance?.nodeId;
}

/** Returns the configuration data needed to create a PASE commissioner, e.g. in a mobile app. */
/**
* Returns the configuration data needed to create a PASE commissioner, e.g. in a mobile app.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
get paseCommissionerConfig() {
const controller = this.#assertControllerIsStarted(
"The CommissioningController needs to be started to get the PASE commissioner data.",
Expand Down Expand Up @@ -434,6 +463,8 @@ export class CommissioningController {
/**
* Commissions/Pairs a new device into the controller fabric. The method returns the NodeId of the commissioned
* node on success.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async commissionNode(
nodeOptions: NodeCommissioningOptions,
Expand Down Expand Up @@ -481,6 +512,7 @@ export class CommissioningController {
return nodeId;
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
connectPaseChannel(nodeOptions: NodeCommissioningOptions): Promise<NodeSession> {
const controller = this.#assertControllerIsStarted();

Expand All @@ -491,13 +523,18 @@ export class CommissioningController {
* Completes the commissioning process for a node when the initial commissioning process was done by a PASE
* commissioner. This method should be called to discover the device operational and complete the commissioning
* process.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
completeCommissioningForNode(peerNodeId: NodeId, discoveryData?: DiscoveryData) {
const controller = this.#assertControllerIsStarted();
return controller.completeCommissioning(peerNodeId, discoveryData);
}

/** Check if a given node id is commissioned on this controller. */
/**
* Check if a given node id is commissioned on this controller.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
isNodeCommissioned(nodeId: NodeId) {
const controller = this.#assertControllerIsStarted();
return controller.getCommissionedNodes().includes(nodeId) ?? false;
Expand All @@ -519,6 +556,8 @@ export class CommissioningController {
* use this in case of an error as last option.
* If this method is used the state of the PairedNode instance might be out of sync, so the PairedNode instance
* should be disconnected first.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async removeNode(nodeId: NodeId, tryDecommissioning = true) {
const controller = this.#assertControllerIsStarted();
Expand Down Expand Up @@ -577,6 +616,8 @@ export class CommissioningController {
/**
* Returns the PairedNode instance for a given NodeId. The instance is initialized without auto-connect if not yet
* created.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async getNode(nodeId: NodeId, allowUnknownNode = false) {
const existingNode = this.#pairedNodeForNodeId(nodeId);
Expand Down Expand Up @@ -700,7 +741,10 @@ export class CommissioningController {
return Array.from(this.#initializedNodes.values());
}

/** Returns true if t least one node is commissioned/paired with this controller instance. */
/**
* Returns true if at least one node is commissioned/paired with this controller instance.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
Comment thread
Copilot marked this conversation as resolved.
isCommissioned() {
const controller = this.#assertControllerIsStarted();

Expand All @@ -710,6 +754,8 @@ export class CommissioningController {
/**
* Creates and Return a new InteractionClient to communicate with a node. This is mainly used internally and should
* not be used directly. See the PairedNode class for the public API.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async createInteractionClient(
nodeIdOrSession: NodeId | SecureSession,
Expand Down Expand Up @@ -747,14 +793,20 @@ export class CommissioningController {
return this.#pairedNodeForNodeId(nodeId);
}

/** Returns an array with the NodeIds of all commissioned nodes. */
/**
* Returns an array with the NodeIds of all commissioned nodes.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
getCommissionedNodes() {
const controller = this.#assertControllerIsStarted();

return controller.getCommissionedNodes() ?? [];
}

/** Returns an array with all commissioned NodeIds and their metadata. */
/**
* Returns an array with all commissioned NodeIds and their metadata.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
getCommissionedNodesDetails(): PairedNodeDetails[] {
const controller = this.#assertControllerIsStarted();

Expand All @@ -764,6 +816,8 @@ export class CommissioningController {
/**
* Disconnects all connected nodes and closes the network connections and other resources of the controller.
* You can use "start()" to restart the controller after closing it.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async close() {
this.#observers.close();
Expand All @@ -779,7 +833,10 @@ export class CommissioningController {
this.#started = false;
}

/** Return the port used by the controller for the UDP interface. */
/**
* Return the port used by the controller for the UDP interface.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
getPort(): number | undefined {
return this.#options.localPort;
}
Expand All @@ -797,12 +854,15 @@ export class CommissioningController {
this.#ipv4Disabled = ipv4Disabled;
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
get env() {
return this.#environment;
}

/**
* Initialize the controller and initialize and connect to all commissioned nodes if autoConnect is not set to false.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async start() {
if (this.#ipv4Disabled === undefined) {
Expand Down Expand Up @@ -850,6 +910,8 @@ export class CommissioningController {

/**
* Cancels the discovery process for commissionable devices started with discoverCommissionableDevices().
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
cancelCommissionableDeviceDiscovery(
identifierData: CommissionableDeviceIdentifiers,
Expand All @@ -862,6 +924,8 @@ export class CommissioningController {
* Starts to discover commissionable devices.
* The promise will be fulfilled after the provided timeout or when the discovery is stopped via
* cancelCommissionableDeviceDiscovery(). The discoveredCallback will be called for each discovered device.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async discoverCommissionableDevices(
identifierData: CommissionableDeviceIdentifiers,
Expand All @@ -882,6 +946,8 @@ export class CommissioningController {
/**
* Use this method to reset the Controller storage. The method can only be called if the controller is stopped and
* will remove all commissioning data and paired nodes from the controller.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async resetStorage() {
if (this.#started) {
Expand All @@ -892,7 +958,10 @@ export class CommissioningController {
await this.node.erase(); // TODO check if that's correct
}

/** Returns active session information for all connected nodes. */
/**
* Returns active session information for all connected nodes.
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
getActiveSessionInformation(): ActiveSessionInformation[] {
return this.#controllerInstance?.getActiveSessionInformation() ?? [];
}
Expand Down Expand Up @@ -942,6 +1011,8 @@ export class CommissioningController {
/**
* Updates the fabric label for the controller and all connected nodes.
* The label is used to identify the controller and all connected nodes in the fabric.
*
* @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md.
*/
async updateFabricLabel(label: string) {
const controller = this.#assertControllerIsStarted();
Expand Down Expand Up @@ -992,11 +1063,13 @@ export class CommissioningController {
}
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
get groups(): FabricGroups {
const controllerInstance = this.#assertControllerIsStarted();
return controllerInstance.fabric.groups;
}

/** @deprecated Legacy API, removed in 0.19. Migrate to @matter/node — see docs/MIGRATION_CONTROLLER_018.md. */
get fabric(): Fabric {
const controllerInstance = this.#assertControllerIsStarted();
return controllerInstance.fabric;
Expand Down
Loading
Loading