Skip to content

feat(messenger): add delegateAll with exhaustive type checking#8338

Open
cryptodev-2s wants to merge 13 commits into
mainfrom
add-messenger-delegate-all
Open

feat(messenger): add delegateAll with exhaustive type checking#8338
cryptodev-2s wants to merge 13 commits into
mainfrom
add-messenger-delegate-all

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Explanation

Messenger.delegate() accepts a partial list of actions/events without compile-time enforcement that all required items are present. This means missing a delegation (e.g., a newly added AllowedAction) silently compiles and only fails at runtime.

delegateAll() wraps delegate() with a RequireExhaustive branded intersection type that produces a clear TypeScript error showing exactly which actions or events are missing from the list. Own-namespace actions of the delegatee are automatically excluded from the check.

Example error when an action is missing:

Property '__missing' is missing in type '[...]'
  but required in type '{ __missing: "KeyringController:signTypedMessage" }'.

References

Changelog

@metamask/messenger

  • Added: delegateAll() method — strict alternative to delegate() that requires all external actions and events to be listed
  • Added: MessengerNamespace<M> utility type — extracts the namespace string literal from a Messenger type
  • Added: RequireExhaustive<Required, Provided> utility type — validates tuple exhaustiveness at compile time

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Low Risk
Additive API and type-level checks only; delegateAll forwards to existing delegate with no runtime behavior change beyond new call sites.

Overview
Adds delegateAll on Messenger, a strict alternative to delegate that must list every external action and event the child messenger needs (excluding the delegatee’s own namespace). Missing items fail at compile time via an internal RequireExhaustive branded type that surfaces missing delegation keys; runtime behavior still delegates through delegate.

Also exports MessengerNamespace to read a messenger’s namespace from its type, wires TSTyche compile-time tests (Messenger.tst.ts), splits test into test:unit + test:types, and excludes *.tst.ts from Jest coverage and the build.

Reviewed by Cursor Bugbot for commit cb9e3aa. Bugbot is set up for automated code reviews on this repo. Configure here.

@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.0.0-preview-c6e356a6a
@metamask-previews/accounts-controller@37.1.1-preview-c6e356a6a
@metamask-previews/address-book-controller@7.1.1-preview-c6e356a6a
@metamask-previews/ai-controllers@0.6.3-preview-c6e356a6a
@metamask-previews/analytics-controller@1.0.1-preview-c6e356a6a
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-c6e356a6a
@metamask-previews/announcement-controller@8.1.0-preview-c6e356a6a
@metamask-previews/app-metadata-controller@2.0.1-preview-c6e356a6a
@metamask-previews/approval-controller@9.0.1-preview-c6e356a6a
@metamask-previews/assets-controller@3.2.1-preview-c6e356a6a
@metamask-previews/assets-controllers@103.0.0-preview-c6e356a6a
@metamask-previews/base-controller@9.0.1-preview-c6e356a6a
@metamask-previews/base-data-service@0.1.1-preview-c6e356a6a
@metamask-previews/bridge-controller@69.2.3-preview-c6e356a6a
@metamask-previews/bridge-status-controller@70.0.3-preview-c6e356a6a
@metamask-previews/build-utils@3.0.4-preview-c6e356a6a
@metamask-previews/chain-agnostic-permission@1.5.0-preview-c6e356a6a
@metamask-previews/claims-controller@0.5.0-preview-c6e356a6a
@metamask-previews/client-controller@1.0.1-preview-c6e356a6a
@metamask-previews/compliance-controller@1.0.2-preview-c6e356a6a
@metamask-previews/composable-controller@12.0.1-preview-c6e356a6a
@metamask-previews/config-registry-controller@0.2.0-preview-c6e356a6a
@metamask-previews/connectivity-controller@0.2.0-preview-c6e356a6a
@metamask-previews/controller-utils@11.19.0-preview-c6e356a6a
@metamask-previews/core-backend@6.2.1-preview-c6e356a6a
@metamask-previews/delegation-controller@2.1.0-preview-c6e356a6a
@metamask-previews/earn-controller@11.2.1-preview-c6e356a6a
@metamask-previews/eip-5792-middleware@3.0.2-preview-c6e356a6a
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-c6e356a6a
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-c6e356a6a
@metamask-previews/ens-controller@19.1.1-preview-c6e356a6a
@metamask-previews/eth-block-tracker@15.0.1-preview-c6e356a6a
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-c6e356a6a
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-c6e356a6a
@metamask-previews/foundryup@1.0.1-preview-c6e356a6a
@metamask-previews/gas-fee-controller@26.1.1-preview-c6e356a6a
@metamask-previews/gator-permissions-controller@3.0.0-preview-c6e356a6a
@metamask-previews/geolocation-controller@0.1.2-preview-c6e356a6a
@metamask-previews/json-rpc-engine@10.2.4-preview-c6e356a6a
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-c6e356a6a
@metamask-previews/keyring-controller@25.1.1-preview-c6e356a6a
@metamask-previews/logging-controller@8.0.1-preview-c6e356a6a
@metamask-previews/message-manager@14.1.1-preview-c6e356a6a
@metamask-previews/messenger@1.0.0-preview-c6e356a6a
@metamask-previews/multichain-account-service@8.0.1-preview-c6e356a6a
@metamask-previews/multichain-api-middleware@2.0.0-preview-c6e356a6a
@metamask-previews/multichain-network-controller@3.0.6-preview-c6e356a6a
@metamask-previews/multichain-transactions-controller@7.0.4-preview-c6e356a6a
@metamask-previews/name-controller@9.1.1-preview-c6e356a6a
@metamask-previews/network-controller@30.0.1-preview-c6e356a6a
@metamask-previews/network-enablement-controller@5.0.1-preview-c6e356a6a
@metamask-previews/notification-services-controller@23.0.1-preview-c6e356a6a
@metamask-previews/permission-controller@12.3.0-preview-c6e356a6a
@metamask-previews/permission-log-controller@5.1.0-preview-c6e356a6a
@metamask-previews/perps-controller@2.0.0-preview-c6e356a6a
@metamask-previews/phishing-controller@17.1.0-preview-c6e356a6a
@metamask-previews/polling-controller@16.0.4-preview-c6e356a6a
@metamask-previews/preferences-controller@23.1.0-preview-c6e356a6a
@metamask-previews/profile-metrics-controller@3.1.2-preview-c6e356a6a
@metamask-previews/profile-sync-controller@28.0.2-preview-c6e356a6a
@metamask-previews/ramps-controller@12.1.0-preview-c6e356a6a
@metamask-previews/rate-limit-controller@7.0.1-preview-c6e356a6a
@metamask-previews/react-data-query@0.2.0-preview-c6e356a6a
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-c6e356a6a
@metamask-previews/sample-controllers@4.0.4-preview-c6e356a6a
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-c6e356a6a
@metamask-previews/selected-network-controller@26.1.0-preview-c6e356a6a
@metamask-previews/shield-controller@5.1.0-preview-c6e356a6a
@metamask-previews/signature-controller@39.1.2-preview-c6e356a6a
@metamask-previews/social-controllers@0.0.0-preview-c6e356a6a
@metamask-previews/storage-service@1.0.1-preview-c6e356a6a
@metamask-previews/subscription-controller@6.1.1-preview-c6e356a6a
@metamask-previews/transaction-controller@63.3.1-preview-c6e356a6a
@metamask-previews/transaction-pay-controller@19.0.0-preview-c6e356a6a
@metamask-previews/user-operation-controller@41.1.1-preview-c6e356a6a

@cryptodev-2s
cryptodev-2s force-pushed the add-messenger-delegate-all branch from 5bd4a95 to f0e25c9 Compare March 30, 2026 17:44
`delegate` accepts partial action/event lists without compile-time
enforcement that all required items are present. `delegateAll` uses
a branded intersection type to produce a clear TS error showing
exactly which actions or events are missing.
@cryptodev-2s
cryptodev-2s force-pushed the add-messenger-delegate-all branch from f0e25c9 to 0bc2ac9 Compare April 7, 2026 16:59
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.0.0-preview-0bc2ac9
@metamask-previews/accounts-controller@37.2.0-preview-0bc2ac9
@metamask-previews/address-book-controller@7.1.1-preview-0bc2ac9
@metamask-previews/ai-controllers@0.6.3-preview-0bc2ac9
@metamask-previews/analytics-controller@1.0.1-preview-0bc2ac9
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-0bc2ac9
@metamask-previews/announcement-controller@8.1.0-preview-0bc2ac9
@metamask-previews/app-metadata-controller@2.0.1-preview-0bc2ac9
@metamask-previews/approval-controller@9.0.1-preview-0bc2ac9
@metamask-previews/assets-controller@4.0.0-preview-0bc2ac9
@metamask-previews/assets-controllers@103.1.1-preview-0bc2ac9
@metamask-previews/base-controller@9.0.1-preview-0bc2ac9
@metamask-previews/base-data-service@0.1.1-preview-0bc2ac9
@metamask-previews/bridge-controller@70.0.1-preview-0bc2ac9
@metamask-previews/bridge-status-controller@70.0.5-preview-0bc2ac9
@metamask-previews/build-utils@3.0.4-preview-0bc2ac9
@metamask-previews/chain-agnostic-permission@1.5.0-preview-0bc2ac9
@metamask-previews/claims-controller@0.5.0-preview-0bc2ac9
@metamask-previews/client-controller@1.0.1-preview-0bc2ac9
@metamask-previews/compliance-controller@2.0.0-preview-0bc2ac9
@metamask-previews/composable-controller@12.0.1-preview-0bc2ac9
@metamask-previews/config-registry-controller@0.2.0-preview-0bc2ac9
@metamask-previews/connectivity-controller@0.2.0-preview-0bc2ac9
@metamask-previews/controller-utils@11.20.0-preview-0bc2ac9
@metamask-previews/core-backend@6.2.1-preview-0bc2ac9
@metamask-previews/delegation-controller@2.1.0-preview-0bc2ac9
@metamask-previews/earn-controller@11.2.1-preview-0bc2ac9
@metamask-previews/eip-5792-middleware@3.0.3-preview-0bc2ac9
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-0bc2ac9
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-0bc2ac9
@metamask-previews/ens-controller@19.1.1-preview-0bc2ac9
@metamask-previews/eth-block-tracker@15.0.1-preview-0bc2ac9
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-0bc2ac9
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-0bc2ac9
@metamask-previews/foundryup@1.0.1-preview-0bc2ac9
@metamask-previews/gas-fee-controller@26.1.1-preview-0bc2ac9
@metamask-previews/gator-permissions-controller@3.0.1-preview-0bc2ac9
@metamask-previews/geolocation-controller@0.1.2-preview-0bc2ac9
@metamask-previews/json-rpc-engine@10.2.4-preview-0bc2ac9
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-0bc2ac9
@metamask-previews/keyring-controller@25.2.0-preview-0bc2ac9
@metamask-previews/logging-controller@8.0.1-preview-0bc2ac9
@metamask-previews/message-manager@14.1.1-preview-0bc2ac9
@metamask-previews/messenger@1.1.1-preview-0bc2ac9
@metamask-previews/messenger-cli@0.1.0-preview-0bc2ac9
@metamask-previews/money-account-controller@0.1.0-preview-0bc2ac9
@metamask-previews/multichain-account-service@8.0.1-preview-0bc2ac9
@metamask-previews/multichain-api-middleware@2.0.0-preview-0bc2ac9
@metamask-previews/multichain-network-controller@3.0.6-preview-0bc2ac9
@metamask-previews/multichain-transactions-controller@7.0.4-preview-0bc2ac9
@metamask-previews/name-controller@9.1.1-preview-0bc2ac9
@metamask-previews/network-controller@30.0.1-preview-0bc2ac9
@metamask-previews/network-enablement-controller@5.0.2-preview-0bc2ac9
@metamask-previews/notification-services-controller@23.0.1-preview-0bc2ac9
@metamask-previews/permission-controller@12.3.0-preview-0bc2ac9
@metamask-previews/permission-log-controller@5.1.0-preview-0bc2ac9
@metamask-previews/perps-controller@2.0.0-preview-0bc2ac9
@metamask-previews/phishing-controller@17.1.1-preview-0bc2ac9
@metamask-previews/polling-controller@16.0.4-preview-0bc2ac9
@metamask-previews/preferences-controller@23.1.0-preview-0bc2ac9
@metamask-previews/profile-metrics-controller@3.1.3-preview-0bc2ac9
@metamask-previews/profile-sync-controller@28.0.2-preview-0bc2ac9
@metamask-previews/ramps-controller@13.0.0-preview-0bc2ac9
@metamask-previews/rate-limit-controller@7.0.1-preview-0bc2ac9
@metamask-previews/react-data-query@0.2.0-preview-0bc2ac9
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-0bc2ac9
@metamask-previews/sample-controllers@4.0.4-preview-0bc2ac9
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-0bc2ac9
@metamask-previews/selected-network-controller@26.1.0-preview-0bc2ac9
@metamask-previews/shield-controller@5.1.1-preview-0bc2ac9
@metamask-previews/signature-controller@39.1.2-preview-0bc2ac9
@metamask-previews/social-controllers@0.1.0-preview-0bc2ac9
@metamask-previews/storage-service@1.0.1-preview-0bc2ac9
@metamask-previews/subscription-controller@6.1.2-preview-0bc2ac9
@metamask-previews/transaction-controller@64.0.0-preview-0bc2ac9
@metamask-previews/transaction-pay-controller@19.0.3-preview-0bc2ac9
@metamask-previews/user-operation-controller@41.2.0-preview-0bc2ac9

@cryptodev-2s
cryptodev-2s marked this pull request as ready for review July 24, 2026 13:39
@cryptodev-2s
cryptodev-2s requested a review from a team as a code owner July 24, 2026 13:39

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall strategy seems sound, but I had some suggestions.

expect(childMessenger.call('Source:getValue')).toBe(42);
});

it('produces a type error when an action is missing', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have found that Jest doesn't always check type errors, so I am not sure this will work as intended.

What are your thoughts about adding tstyche to this package and writing compile-time tests? We could include this test and also the one before it (since it also seems like that is meant to test the type and not the behavior).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Added tstyche in e2fca54 and moved the exhaustiveness cases (missing action + own namespace exclusion) into Messenger.delegateAll.tst.ts. yarn test now runs unit tests and type tests.

Comment thread packages/messenger/src/Messenger.ts Outdated
Comment on lines +1199 to +1202
const DelegatedActions extends readonly (MessengerActions<Delegatee> &
Action)['type'][],
const DelegatedEvents extends readonly (MessengerEvents<Delegatee> &
Event)['type'][],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need const ... readonly here? If we take these away we can remove the type assertions below.

Suggested change
const DelegatedActions extends readonly (MessengerActions<Delegatee> &
Action)['type'][],
const DelegatedEvents extends readonly (MessengerEvents<Delegatee> &
Event)['type'][],
DelegatedActions extends (MessengerActions<Delegatee> & Action)['type'][],
DelegatedEvents extends (MessengerEvents<Delegatee> & Event)['type'][],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the very least, we should extract the type first, then perform an intersection of them. We found in the past that performing an intersection first led to a "union type too complex to represent" error: #8748

Suggested change
const DelegatedActions extends readonly (MessengerActions<Delegatee> &
Action)['type'][],
const DelegatedEvents extends readonly (MessengerEvents<Delegatee> &
Event)['type'][],
const DelegatedActions extends
readonly (MessengerActions<Delegatee>['type'] & Action['type'])[],
const DelegatedEvents extends readonly (MessengerEvents<Delegatee>['type'] &
Event['type'])[],

Or if we go with the above suggestion:

Suggested change
const DelegatedActions extends readonly (MessengerActions<Delegatee> &
Action)['type'][],
const DelegatedEvents extends readonly (MessengerEvents<Delegatee> &
Event)['type'][],
DelegatedActions extends (MessengerActions<Delegatee>['type'] &
Action['type'])[],
DelegatedEvents extends (MessengerEvents<Delegatee>['type'] &
Event['type'])[],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 08fc1b3. Dropped const/readonly and switched to MessengerActions<Delegatee>['type'] & Action['type'] (same for events), matching delegate/revoke. Casts are gone as a result.

Comment thread packages/messenger/src/Messenger.ts Outdated
Comment on lines +1224 to +1228
this.delegate({
actions: actions as (MessengerActions<Delegatee> & Action)['type'][],
events: events as (MessengerEvents<Delegatee> & Event)['type'][],
messenger,
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.delegate({
actions: actions as (MessengerActions<Delegatee> & Action)['type'][],
events: events as (MessengerEvents<Delegatee> & Event)['type'][],
messenger,
});
this.delegate({ actions, events, messenger });

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Now this.delegate({ actions, events, messenger }).

Comment thread packages/messenger/src/Messenger.ts Outdated
actions: RequireExhaustive<
NotNamespacedBy<
MessengerNamespace<Delegatee>,
(MessengerActions<Delegatee> & Action)['type']

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar optimization as above:

Suggested change
(MessengerActions<Delegatee> & Action)['type']
MessengerActions<Delegatee>['type'] & Action['type']

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Updated to MessengerActions<Delegatee>['type'] & Action['type'].

Comment thread packages/messenger/src/Messenger.ts Outdated
events: RequireExhaustive<
NotNamespacedBy<
MessengerNamespace<Delegatee>,
(MessengerEvents<Delegatee> & Event)['type']

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar optimization as above:

Suggested change
(MessengerEvents<Delegatee> & Event)['type']
MessengerEvents<Delegatee>['type'] & Event['type']

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Updated to MessengerEvents<Delegatee>['type'] & Event['type'].

Comment thread packages/messenger/src/Messenger.ts Outdated
Provided extends readonly string[],
> = [Exclude<Required, Provided[number]>] extends [never]
? Provided
: Provided & { missingDelegations: Exclude<Required, Provided[number]> };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Do we want to name this property something non-standard on purpose so engineers don't mistake it for a property they ought to set?

Suggested change
: Provided & { missingDelegations: Exclude<Required, Provided[number]> };
// eslint-disable-next-line @typescript-eslint/naming-convention
: Provided & { __MISSING_DELEGATIONS__: Exclude<Required, Provided[number]> };

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Renamed to __MISSING_DELEGATIONS__ so it does not look like a real option.

Align delegateAll type params with delegate/revoke, drop casts, and
rename the missing-delegations brand for clearer type errors.
Move exhaustiveness checks out of Jest into compile-time tests so
missing delegations are verified by the type checker.
Comment thread packages/messenger/tsconfig.build.json Outdated
@socket-security

socket-security Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedtstyche@​5.0.29410010095100

View full report

@socket-security

socket-security Bot commented Jul 25, 2026

Copy link
Copy Markdown

Caution

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Block Medium
Network access: npm tstyche in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: packages/messenger/package.jsonnpm/tstyche@5.0.2

ℹ Read more on: This package | This alert | What is network access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/tstyche@5.0.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Keep Jest test files out of the build when excluding TSTyche files,
format misc lint failures, and allow messenger's combined test script.
@cryptodev-2s
cryptodev-2s requested a review from mcmire July 27, 2026 10:22

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0f82791. Configure here.

Comment thread packages/messenger/src/Messenger.ts
Require every external delegatee action/event in the exhaustiveness
check, even when the source type omits them, and cover missing events
plus unsupported source deps in tstyche.
Mirror the Jest layout with one Messenger type test file and nested
describes instead of a per-method file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants