Skip to content

feat(platform-api-docs): add root-messenger strategy - #9913

Merged
cryptodev-2s merged 9 commits into
mainfrom
feat/platform-api-docs-root-messenger-strategy
Aug 27, 2026
Merged

cryptodev-2s merged 9 commits into
mainfrom
feat/platform-api-docs-root-messenger-strategy

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

Explanation

@metamask/platform-api-docs documents the platform API — every messenger action and event a project exposes. Until now it had one way of finding them: parse every TypeScript source and declaration file it can reach (the scan directories, packages/*/src, and node_modules/@metamask/*/dist/**/*.d.cts) and walk every type alias named *Messenger.

That is the right approach for this monorepo, which has no single messenger aggregating every capability. It is a poor fit for a client, which already declares the complete set on its root messenger. Re-deriving that from the whole dependency tree means parsing ~11,600 files in metamask-mobile and ~4,500 in metamask-extension, to rediscover something the client has written down in one place.

This PR adds a second strategy that reads what the client already declares.

--strategy

  • scan (default) — unchanged behaviour, and the only option for a project with no single aggregating messenger.
  • root-messenger — resolves the two types named by --root-actions and --root-events (each written <file>#<TypeName>) and lets the TypeScript type checker enumerate them. Only the named files are opened; the checker pulls in the rest.

Flags belonging to the strategy that wasn't selected are rejected rather than ignored, via a yargs .check, so a mistaken invocation fails loudly instead of quietly producing docs built the wrong way. The <file>#<TypeName> references are parsed in a yargs .coerce, so a malformed one is reported like any other
bad argument before work begins.

Why the type checker rather than the AST

This is the non-obvious part. The two clients declare their root unions differently:

  • metamask-mobile writes GlobalActions by hand as a union of type references. A syntactic walk would work.
  • metamask-extension derives RootMessengerActions from a registry of messenger factories via
    MessengerActions<ReturnType<(typeof MESSENGER_FACTORIES)[…]['getMessenger']>>.
    There is no syntactic union to walk — only the type checker can say what it contains.

Going through the checker handles both shapes with one code path. Once it reports which capability types are in the union, each declaration is handed to the existing extractor in extraction.ts, so JSDoc, handler/payload signatures, source links, and deprecation flags come out identical to scan. The new module is a discovery front-end, not a second extractor.

Two details worth knowing:

  • A capability declared as a type alias carries its name and JSDoc on the alias symbol; the plain symbol points at the anonymous object type. An interface has no alias symbol, being its own declaration, so both are
    consulted. Missing the interface case silently dropped 61 actions and 8 events on mobile before it was fixed.
  • For a lone generic instantiation (type Actions = Foo<Bar>) the checker attributes the alias to the root union itself, which would hand the extractor the wrong declaration. That case is guarded.

Failure behaviour

Generation now fails loudly instead of producing an empty site. writeOutput deletes docs/ before writing, so a root union that resolves to nothing — a renamed type, or imports that don't resolve — would previously have replaced a
published docs directory with an empty one and exited 0. It now throws, naming both references.

Capability types that can't be documented are reported with their names rather than counted, in three buckets: declared inline (no name or JSDoc), unresolved (any/unknown, usually a failed import), and unextractable (a shape the extractor rejects). A count alone isn't actionable at this scale.

Also fixed: MDX escaping

escapeJsDocTextForMdx escaped { and } but not <, which MDX reads as the start of a JSX tag. A @returns comment such as Promise<PointsBoostDto[]> therefore failed the site build rather than rendering:

Unexpected character `[` (U+005B) in name, expected a name character…

This is pre-existing and independent of the new strategy — scan produces the byte-identical line — but it blocked --build and --serve for both clients, so it is fixed here. Affects description, @param, and @returns text; handler and payload signatures were already safe inside fenced code blocks.


Benchmarks

Measured on a warm checkout, doc generation only.

Project scan root-messenger Speedup
metamask-extension 47.9s 4.7s ~10×
metamask-mobile 96.9s 5.7s ~17×

scan parses ~5,600 app/**/*.ts plus ~6,026 .d.cts in mobile, and ~4,472 .d.cts in the extension. root-messenger opens the entry file and lets the checker pull in only what the union references.

Strategy comparison

metamask-mobile

scan root-messenger
Namespaces 112 103
Actions 1184 1157
Events 181 171
Unique capabilities 1365 1328 (97.3%)

The 37 not documented are mostly controllers genuinely not on the root messenger — PasskeyController alone accounts for 17, plus RatesController (4), the sample controllers, and the decrypt/encrypt message managers. Nothing is found by root-messenger that scan misses.

metamask-extension

scan root-messenger
Namespaces 119 115
Actions 1209 1085
Events 183 176
Unique capabilities 1392 1261 (90.6%)

99 of the 131-capability gap is PerpsController, and the cause is worth flagging to the extension team rather than treating as a tool limitation:

export type PerpsControllerMessenger = Messenger<
  'PerpsController',
  AllowedActions,   // actions Perps may CALL
  AllowedEvents
>;

RootMessengerActions is MessengerActions<ChildMessengers> — the union of what each child messenger is allowed to call, not what each controller provides. A controller whose actions are only invoked from the UI, never from another controller's messenger, never appears. PerpsController is registered in
MESSENGER_FACTORIES yet contributes zero constituents.

root-messenger documents exactly what the named types contain. Full coverage in. the extension needs an aggregate of provided actions, which is an extension-side change.

Conversely, root-messenger finds 6 capabilities scan misses(MultichainRoutingService ×4, PPOMController ×2).

Reported-but-skipped, current run: mobile 39 unextractable; extension 2 inline + 33 unextractable.


Usage in clients

Once published, add the dependency and two scripts. For metamask-mobile:

{
  "scripts": {
    "docs:platform-api:build": "platform-api-docs --build --project-label Mobile --strategy root-messenger --root-actions 'app/core/Engine/types.ts#GlobalActions' --root-events 'app/core/Engine/types.ts#GlobalEvents'",
    "docs:platform-api:serve": "platform-api-docs --serve --project-label Mobile --site-base-url / --strategy root-messenger --root-actions 'app/core/Engine/types.ts#GlobalActions' --root-events 'app/core/Engine/types.ts#GlobalEvents'"
  }
}

For metamask-extension, the label and references change:

--project-label Extension
--root-actions 'app/scripts/lib/messenger.ts#RootMessengerActions'
--root-events  'app/scripts/lib/messenger.ts#RootMessengerEvents'

Notes for consumers:

  • Keep the # inside quotes — unquoted, most shells treat it as a comment and silently truncate the argument.
  • --root-actions / --root-events are relative to the project path, not the shell's working directory.
  • Output defaults to <project-path>/.platform-api-docs; gitignore it.
  • metamask-extension additionally needs its postcss-loader/jiti resolution narrowed to postcss-loader@^8.2.1/jiti. The unversioned form also stubs the postcss-loader@^7.3.4 that @docusaurus/bundler depends on, replacing jiti with an empty package and breaking the site build. Narrowing preserves the stub's original intent for the extension's own postcss-loader@8.2.1.

References

Fixes: https://consensyssoftware.atlassian.net/browse/WPC-1202

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
Changes are confined to the docs CLI and generation pipeline; default scan behavior is preserved with an explicit strategy field in tests.

Overview
Adds a root-messenger discovery path alongside the existing scan default: the CLI accepts --strategy, --root-actions, and --root-events (<file>#<TypeName>), validates that strategy-specific flags are not mixed, and routes generation through type-checker resolution of the project’s root action/event unions instead of scanning the whole tree.

New root-messenger-discovery walks those unions (including checker-derived unions like MessengerActions<…>), reuses the shared extractor in extraction.ts (with classifyMessengerCapabilityTypeDeclaration exported for reuse), warns on skipped inline or unextractable capabilities, and throws when unions resolve to any/unknown or would produce zero docs so an empty site cannot overwrite published output.

escapeJsDocTextForMdx now escapes < as well as braces so generic types in JSDoc do not break MDX builds. README, changelog, and broad CLI/generate/discovery tests cover the new behavior.

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

@cryptodev-2s
cryptodev-2s requested a review from a team as a code owner August 19, 2026 21:30
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts
@cryptodev-2s
cryptodev-2s force-pushed the feat/platform-api-docs-root-messenger-strategy branch from 8db1696 to 81fb650 Compare August 19, 2026 21:35
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@cryptodev-2s
cryptodev-2s requested a review from mcmire August 19, 2026 21:42
@cryptodev-2s cryptodev-2s self-assigned this Aug 19, 2026
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@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 5fe1f30. Configure here.

Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@cryptodev-2s
cryptodev-2s force-pushed the feat/platform-api-docs-root-messenger-strategy branch from e514f29 to 3c77cf4 Compare August 20, 2026 12:41
@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@8.0.0-preview-3c77cf4
@metamask-previews/accounts-controller@39.1.0-preview-3c77cf4
@metamask-previews/address-book-controller@7.1.2-preview-3c77cf4
@metamask-previews/ai-controllers@0.8.0-preview-3c77cf4
@metamask-previews/analytics-controller@2.0.0-preview-3c77cf4
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-3c77cf4
@metamask-previews/announcement-controller@8.1.0-preview-3c77cf4
@metamask-previews/app-metadata-controller@2.0.1-preview-3c77cf4
@metamask-previews/approval-controller@9.0.2-preview-3c77cf4
@metamask-previews/assets-controller@13.1.4-preview-3c77cf4
@metamask-previews/assets-controllers@111.1.1-preview-3c77cf4
@metamask-previews/authenticated-user-storage@3.0.1-preview-3c77cf4
@metamask-previews/base-controller@9.1.0-preview-3c77cf4
@metamask-previews/base-data-service@0.1.3-preview-3c77cf4
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-3c77cf4
@metamask-previews/bridge-controller@79.2.0-preview-3c77cf4
@metamask-previews/bridge-status-controller@75.1.0-preview-3c77cf4
@metamask-previews/build-utils@3.0.4-preview-3c77cf4
@metamask-previews/chain-agnostic-permission@1.7.0-preview-3c77cf4
@metamask-previews/chomp-api-service@4.0.0-preview-3c77cf4
@metamask-previews/claims-controller@0.6.0-preview-3c77cf4
@metamask-previews/client-controller@1.0.1-preview-3c77cf4
@metamask-previews/client-utils@2.0.2-preview-3c77cf4
@metamask-previews/compliance-controller@2.1.0-preview-3c77cf4
@metamask-previews/composable-controller@12.0.1-preview-3c77cf4
@metamask-previews/config-registry-controller@2.0.1-preview-3c77cf4
@metamask-previews/connectivity-controller@0.3.0-preview-3c77cf4
@metamask-previews/controller-utils@12.3.0-preview-3c77cf4
@metamask-previews/core-backend@8.1.2-preview-3c77cf4
@metamask-previews/delegation-controller@3.0.2-preview-3c77cf4
@metamask-previews/earn-controller@12.2.5-preview-3c77cf4
@metamask-previews/eip-5792-middleware@3.0.5-preview-3c77cf4
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-3c77cf4
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-3c77cf4
@metamask-previews/eth-block-tracker@15.0.1-preview-3c77cf4
@metamask-previews/eth-json-rpc-middleware@24.0.0-preview-3c77cf4
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-3c77cf4
@metamask-previews/foundryup@1.0.1-preview-3c77cf4
@metamask-previews/gas-fee-controller@26.3.1-preview-3c77cf4
@metamask-previews/gator-permissions-controller@5.0.1-preview-3c77cf4
@metamask-previews/geolocation-controller@1.0.0-preview-3c77cf4
@metamask-previews/java-tron-up@1.0.0-preview-3c77cf4
@metamask-previews/json-rpc-engine@10.5.0-preview-3c77cf4
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-3c77cf4
@metamask-previews/keyring-controller@27.1.1-preview-3c77cf4
@metamask-previews/kyc-controller@0.0.0-preview-3c77cf4
@metamask-previews/local-node-utils@1.0.0-preview-3c77cf4
@metamask-previews/logging-controller@9.0.0-preview-3c77cf4
@metamask-previews/message-manager@14.1.2-preview-3c77cf4
@metamask-previews/messenger@2.0.0-preview-3c77cf4
@metamask-previews/messenger-cli@0.2.0-preview-3c77cf4
@metamask-previews/money-account-api-data-service@0.4.0-preview-3c77cf4
@metamask-previews/money-account-balance-service@2.4.1-preview-3c77cf4
@metamask-previews/money-account-controller@1.0.0-preview-3c77cf4
@metamask-previews/money-account-upgrade-controller@3.0.1-preview-3c77cf4
@metamask-previews/money-account-utils@1.1.0-preview-3c77cf4
@metamask-previews/multichain-account-service@13.0.2-preview-3c77cf4
@metamask-previews/multichain-api-middleware@4.0.2-preview-3c77cf4
@metamask-previews/multichain-network-controller@3.2.3-preview-3c77cf4
@metamask-previews/multichain-transactions-controller@7.1.2-preview-3c77cf4
@metamask-previews/name-controller@9.1.2-preview-3c77cf4
@metamask-previews/network-connection-banner-controller@0.2.0-preview-3c77cf4
@metamask-previews/network-controller@35.0.1-preview-3c77cf4
@metamask-previews/network-enablement-controller@6.0.3-preview-3c77cf4
@metamask-previews/notification-services-controller@26.0.1-preview-3c77cf4
@metamask-previews/passkey-controller@3.0.0-preview-3c77cf4
@metamask-previews/permission-controller@13.1.1-preview-3c77cf4
@metamask-previews/permission-log-controller@5.1.0-preview-3c77cf4
@metamask-previews/perps-controller@12.1.0-preview-3c77cf4
@metamask-previews/phishing-controller@17.3.1-preview-3c77cf4
@metamask-previews/platform-api-docs@0.0.0-preview-3c77cf4
@metamask-previews/polling-controller@16.0.9-preview-3c77cf4
@metamask-previews/preferences-controller@23.1.0-preview-3c77cf4
@metamask-previews/profile-metrics-controller@4.0.3-preview-3c77cf4
@metamask-previews/profile-sync-controller@29.0.0-preview-3c77cf4
@metamask-previews/ramps-controller@20.0.0-preview-3c77cf4
@metamask-previews/rate-limit-controller@7.0.1-preview-3c77cf4
@metamask-previews/react-data-query@0.2.2-preview-3c77cf4
@metamask-previews/remote-feature-flag-controller@5.0.0-preview-3c77cf4
@metamask-previews/sample-controllers@5.0.4-preview-3c77cf4
@metamask-previews/seedless-onboarding-controller@10.1.1-preview-3c77cf4
@metamask-previews/selected-network-controller@26.1.6-preview-3c77cf4
@metamask-previews/sentinel-api-service@1.0.0-preview-3c77cf4
@metamask-previews/shield-controller@6.0.0-preview-3c77cf4
@metamask-previews/signature-controller@39.2.9-preview-3c77cf4
@metamask-previews/smart-transactions-controller@25.1.0-preview-3c77cf4
@metamask-previews/snap-account-service@2.1.2-preview-3c77cf4
@metamask-previews/social-controllers@2.7.1-preview-3c77cf4
@metamask-previews/solana-test-validator-up@1.0.0-preview-3c77cf4
@metamask-previews/stellar-quickstart-up@0.0.0-preview-3c77cf4
@metamask-previews/storage-service@1.0.2-preview-3c77cf4
@metamask-previews/subscription-controller@8.0.0-preview-3c77cf4
@metamask-previews/transaction-controller@69.5.2-preview-3c77cf4
@metamask-previews/transaction-pay-controller@26.4.0-preview-3c77cf4
@metamask-previews/user-operation-controller@41.2.8-preview-3c77cf4
@metamask-previews/wallet@11.0.0-preview-3c77cf4
@metamask-previews/wallet-cli@0.0.0-preview-3c77cf4

@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.

I went through the changes here and made a bunch of comments. I've collected suggestions for most of them in this PR: #9981. Most of the changes are to root-messenger-discovery.ts, to make it easier to understand. I tried to break things up into commits so if you want to cherry-pick anything you can.

The only thing I didn't do was to consolidate the existing "scan strategy" code into one file just like we've done with the "root messenger strategy" code. I figured that was a larger refactor.

I also haven't manually tested this flow yet. I will do that shortly.

Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/cli.ts Outdated
Comment thread packages/platform-api-docs/src/cli.ts Outdated
Comment thread packages/platform-api-docs/src/cli.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
mcmire and others added 2 commits August 27, 2026 08:47
## Explanation

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

- Refactor and clean up `cli.ts`
- Update `cli.ts` to extract `parseArguments`, further clean `main`
- Revise `root-messenger-discovery.ts` (update terminology, JSDoc)
- Simplify `{Scan,RootMessenger}StrategyOptions`, enforce that
`generate` takes strategy

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

## 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](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Programmatic callers of `generate` must pass `strategy` (breaking for
library use); root-messenger discovery is heavily renamed but CLI-facing
behavior should stay the same.
> 
> **Overview**
> Refactors **platform-api-docs** around clearer typing and naming for
the scan vs **root-messenger** discovery paths, without changing CLI
flags.
> 
> **CLI (`cli.ts`)** pulls argument parsing into **`parseArguments`**,
models options as a discriminated union (`ParsedArguments`), and has
**`checkStrategyArgs`** return normalized scan or root-messenger args
instead of only validating. **`--root-actions`** / **`--root-events`**
are coerced via **`parseRootCapabilitiesTypeReference`** at parse time;
**`main`** calls **`generate`** in separate branches with typed options.
> 
> **`generate`** now **requires** an explicit **`strategy: 'scan' |
'root-messenger'`** on **`GenerateOptions`** (scan and root-messenger
option shapes are a strict union). Scan tests pass **`strategy:
'scan'`** accordingly.
> 
> **Root-messenger discovery** renames and restructures APIs:
**`RootTypeReference`** → **`RootCapabilitiesTypeReference`**,
**`parseRootTypeReference`** → **`parseRootCapabilitiesTypeReference`**,
**`discoverFromRootMessenger`** →
**`discoverFromRootMessengerCapabilitiesTypes`**, with result fields
**`capabilityPackets`** / **`skippedCapabilities`**
(**`unnamedCapabilities`**, **`unextractableCapabilities`**). Internal
helpers use object parameters and expanded JSDoc; extraction behavior is
unchanged.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4f7745c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@cryptodev-2s
cryptodev-2s enabled auto-merge August 27, 2026 07:12
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@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.

Some more suggestions. I forgot that in my PR I made an effort to represent --root-actions and --root-events as references to capability collection types rather than unions (because technically neither may be a true union). So most of these changes are to make sure the JSDoc captures that point of view.

I have some more changes to make to the README but I left a comment there about reformatting first.

Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/generate.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/src/root-messenger-discovery.ts Outdated
Comment thread packages/platform-api-docs/README.md Outdated
@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@8.0.0-preview-a846a890c
@metamask-previews/accounts-controller@39.1.1-preview-a846a890c
@metamask-previews/address-book-controller@7.1.2-preview-a846a890c
@metamask-previews/ai-controllers@0.8.0-preview-a846a890c
@metamask-previews/analytics-controller@2.0.0-preview-a846a890c
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-a846a890c
@metamask-previews/announcement-controller@8.1.0-preview-a846a890c
@metamask-previews/app-metadata-controller@2.0.1-preview-a846a890c
@metamask-previews/approval-controller@9.0.2-preview-a846a890c
@metamask-previews/assets-controller@14.0.2-preview-a846a890c
@metamask-previews/assets-controllers@111.1.3-preview-a846a890c
@metamask-previews/authenticated-user-storage@3.0.2-preview-a846a890c
@metamask-previews/base-controller@9.1.0-preview-a846a890c
@metamask-previews/base-data-service@1.0.0-preview-a846a890c
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-a846a890c
@metamask-previews/bridge-controller@80.0.0-preview-a846a890c
@metamask-previews/bridge-status-controller@75.3.0-preview-a846a890c
@metamask-previews/build-utils@3.0.4-preview-a846a890c
@metamask-previews/chain-agnostic-permission@1.7.0-preview-a846a890c
@metamask-previews/chomp-api-service@4.0.1-preview-a846a890c
@metamask-previews/claims-controller@0.6.1-preview-a846a890c
@metamask-previews/client-controller@1.0.1-preview-a846a890c
@metamask-previews/client-utils@2.1.1-preview-a846a890c
@metamask-previews/compliance-controller@2.1.0-preview-a846a890c
@metamask-previews/composable-controller@12.0.1-preview-a846a890c
@metamask-previews/config-registry-controller@3.1.0-preview-a846a890c
@metamask-previews/connectivity-controller@0.3.0-preview-a846a890c
@metamask-previews/controller-utils@12.3.0-preview-a846a890c
@metamask-previews/core-backend@9.0.0-preview-a846a890c
@metamask-previews/delegation-controller@3.0.2-preview-a846a890c
@metamask-previews/earn-controller@12.2.6-preview-a846a890c
@metamask-previews/eip-5792-middleware@3.0.5-preview-a846a890c
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-a846a890c
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-a846a890c
@metamask-previews/eth-block-tracker@15.0.1-preview-a846a890c
@metamask-previews/eth-json-rpc-middleware@24.0.1-preview-a846a890c
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-a846a890c
@metamask-previews/foundryup@1.0.1-preview-a846a890c
@metamask-previews/gas-fee-controller@26.3.2-preview-a846a890c
@metamask-previews/gator-permissions-controller@5.0.2-preview-a846a890c
@metamask-previews/geolocation-controller@1.0.0-preview-a846a890c
@metamask-previews/java-tron-up@1.0.0-preview-a846a890c
@metamask-previews/json-rpc-engine@10.5.0-preview-a846a890c
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-a846a890c
@metamask-previews/keyring-controller@27.1.1-preview-a846a890c
@metamask-previews/kyc-controller@0.0.0-preview-a846a890c
@metamask-previews/local-node-utils@1.0.0-preview-a846a890c
@metamask-previews/logging-controller@9.0.0-preview-a846a890c
@metamask-previews/message-manager@14.1.2-preview-a846a890c
@metamask-previews/messenger@2.0.0-preview-a846a890c
@metamask-previews/messenger-cli@0.2.0-preview-a846a890c
@metamask-previews/money-account-api-data-service@0.4.1-preview-a846a890c
@metamask-previews/money-account-balance-service@2.4.3-preview-a846a890c
@metamask-previews/money-account-controller@1.0.0-preview-a846a890c
@metamask-previews/money-account-upgrade-controller@3.0.2-preview-a846a890c
@metamask-previews/money-account-utils@1.1.0-preview-a846a890c
@metamask-previews/multichain-account-service@13.0.2-preview-a846a890c
@metamask-previews/multichain-api-middleware@4.0.3-preview-a846a890c
@metamask-previews/multichain-network-controller@3.2.4-preview-a846a890c
@metamask-previews/multichain-transactions-controller@7.1.2-preview-a846a890c
@metamask-previews/name-controller@9.1.2-preview-a846a890c
@metamask-previews/network-connection-banner-controller@0.2.1-preview-a846a890c
@metamask-previews/network-controller@36.0.0-preview-a846a890c
@metamask-previews/network-enablement-controller@6.0.5-preview-a846a890c
@metamask-previews/notification-services-controller@26.0.1-preview-a846a890c
@metamask-previews/passkey-controller@3.1.0-preview-a846a890c
@metamask-previews/permission-controller@13.1.1-preview-a846a890c
@metamask-previews/permission-log-controller@5.1.0-preview-a846a890c
@metamask-previews/perps-controller@13.0.0-preview-a846a890c
@metamask-previews/phishing-controller@17.4.0-preview-a846a890c
@metamask-previews/platform-api-docs@0.0.0-preview-a846a890c
@metamask-previews/polling-controller@16.0.9-preview-a846a890c
@metamask-previews/preferences-controller@23.1.0-preview-a846a890c
@metamask-previews/profile-metrics-controller@4.0.3-preview-a846a890c
@metamask-previews/profile-sync-controller@29.0.0-preview-a846a890c
@metamask-previews/ramps-controller@20.0.0-preview-a846a890c
@metamask-previews/rate-limit-controller@7.0.1-preview-a846a890c
@metamask-previews/react-data-query@1.0.0-preview-a846a890c
@metamask-previews/remote-feature-flag-controller@6.0.0-preview-a846a890c
@metamask-previews/sample-controllers@5.0.6-preview-a846a890c
@metamask-previews/seedless-onboarding-controller@10.1.1-preview-a846a890c
@metamask-previews/selected-network-controller@26.1.7-preview-a846a890c
@metamask-previews/sentinel-api-service@1.0.1-preview-a846a890c
@metamask-previews/shield-controller@6.0.1-preview-a846a890c
@metamask-previews/signature-controller@39.2.10-preview-a846a890c
@metamask-previews/smart-transactions-controller@25.1.1-preview-a846a890c
@metamask-previews/snap-account-service@2.1.2-preview-a846a890c
@metamask-previews/social-controllers@2.8.0-preview-a846a890c
@metamask-previews/solana-test-validator-up@1.0.0-preview-a846a890c
@metamask-previews/stellar-quickstart-up@0.0.0-preview-a846a890c
@metamask-previews/storage-service@1.0.2-preview-a846a890c
@metamask-previews/subscription-controller@8.0.1-preview-a846a890c
@metamask-previews/transaction-controller@69.6.1-preview-a846a890c
@metamask-previews/transaction-pay-controller@27.0.0-preview-a846a890c
@metamask-previews/user-operation-controller@41.2.9-preview-a846a890c
@metamask-previews/wallet@12.0.2-preview-a846a890c
@metamask-previews/wallet-cli@0.0.0-preview-a846a890c

@cryptodev-2s
cryptodev-2s requested a review from mcmire August 27, 2026 15:52
@mcmire

mcmire commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

@cryptodev-2s I found MetaMask/metamask-extension#40352 and MetaMask/metamask-mobile#26526 and tried them out.

On Extension this is what I'm seeing:

Warning: skipped 2 capability types declared inline, with no name to document: { type: "PreferencesController:getState"; handler: () => { isMultiAccountBala..., { type: "RewardsController:stateChange"; payload: [import("../controllers/rew...
Warning: skipped 33 capability types whose shape could not be read: AuthenticatedUserStorageInvalidateQueriesAction (node_modules/@metamask/authenticated-user-storage/dist/authenticated-user-storage.d.cts:23), MoneyAccountApiDataServiceInvalidateQueriesAction (node_modules/@metamask/money-account-api-data-service/dist/money-account-api-data-service.d.cts:30), MoneyAccountBalanceServiceInvalidateQueriesAction (node_modules/@metamask/money-account-balance-service/dist/money-account-balance-service.d.cts:33), SentinelApiServiceInvalidateQueriesAction (node_modules/@metamask/sentinel-api-service/dist/types.d.cts:11), ControllerGetStateAction (node_modules/@metamask/base-controller/dist/BaseController.d.cts:112), ClaimsServiceInvalidateQueriesAction (node_modules/@metamask/claims-controller/dist/ClaimsService.d.cts:15), ShieldApiServiceInvalidateQueriesAction (node_modules/@metamask/shield-controller/dist/shield-api-service.d.cts:57), SubscriptionServiceInvalidateQueriesAction (node_modules/@metamask/subscription-controller/dist/SubscriptionService.d.cts:12), AuthenticatedUserStorageCacheUpdatedEvent (node_modules/@metamask/authenticated-user-storage/dist/authenticated-user-storage.d.cts:45), AuthenticatedUserStorageGranularCacheUpdatedEvent (node_modules/@metamask/authenticated-user-storage/dist/authenticated-user-storage.d.cts:50), and 23 more

On Mobile this is what I'm seeing:

Warning: skipped 39 capability types whose shape could not be read: MoneyAccountBalanceServiceInvalidateQueriesAction (node_modules/@metamask/money-account-balance-service/dist/money-account-balance-service.d.cts:33), MoneyAccountApiDataServiceInvalidateQueriesAction (node_modules/@metamask/money-account-api-data-service/dist/money-account-api-data-service.d.cts:30), DataServiceInvalidateQueriesAction (node_modules/@metamask/base-data-service/dist/BaseDataService.d.cts:16), SubscriptionServiceInvalidateQueriesAction (node_modules/@metamask/subscription-controller/dist/SubscriptionService.d.cts:12), ShieldApiServiceInvalidateQueriesAction (node_modules/@metamask/shield-controller/dist/shield-api-service.d.cts:57), ClaimsServiceInvalidateQueriesAction (node_modules/@metamask/claims-controller/dist/ClaimsService.d.cts:15), DataServiceInvalidateQueriesAction (node_modules/@metamask/base-data-service/dist/BaseDataService.d.cts:16), AuthenticatedUserStorageInvalidateQueriesAction (node_modules/@metamask/authenticated-user-storage/dist/authenticated-user-storage.d.cts:23), ChompApiServiceInvalidateQueriesAction (node_modules/@metamask/chomp-api-service/dist/chomp-api-service.d.cts:17), SentinelApiServiceInvalidateQueriesAction (node_modules/@metamask/sentinel-api-service/dist/types.d.cts:11), and 29 more

I wonder if it may be worth it eventually to throw errors instead of printing warnings if we encounter issues. That will motivate us to correct them. Or maybe there's a lint rule or some other check we can add to prevent these problems from creeping into the codebase altogether that would be nice too...

Still, this worked great and I can see that there are clear differences between Extension and Mobile (for instance, Extension includes AccountOrderController but Mobile does not, and Mobile includes CardController but Extension does not). And the platform-api-docs command ran super fast, which is great. The one for core still runs slow, but it sounds like you are working on that in your next PR.

At this point I think all of the remaining comments I have are super minor everything looks good. Nice work 👏🏻

@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.

LGTM!

@cryptodev-2s
cryptodev-2s added this pull request to the merge queue Aug 27, 2026
Merged via the queue into main with commit a949073 Aug 27, 2026
47 checks passed
@cryptodev-2s
cryptodev-2s deleted the feat/platform-api-docs-root-messenger-strategy branch August 27, 2026 21:02
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Sep 2, 2026
…MetaMask#9990)

Stacked on MetaMask#9913, targets its branch.

Replaces hand-rolled file discovery with
`Project#addSourceFilesAtPaths`, which takes glob patterns directly.
Drops `discovery.ts`, the per-file add/extract loops,
`listTargetSubdirectories`, and the `glob` dependency. Also merges the
two `Project` factories (they differed by one field) and removes the
redundant `getSourceFile()` guard, closing
MetaMask#9913 (comment).

Net 254 lines deleted. Generation over this monorepo: **114s to 8.6s**.

Output is byte identical. `diff -r` on full docs trees generated before
and after, for core, mobile and extension: all empty, sidebars included.

## Two traps, if you touch these patterns

Both produced wrong output while the whole suite stayed green.

- **Glob roots need `realpath`.** The matcher does not follow a
symlinked *ancestor*. Under `/var/folders/...` the declaration glob
returned 0 where `/private/var/...` returned 1980, so any project under
`/tmp` or `/var` would have emitted empty docs.
- **Negations must be anchored.** `!**/*.test.ts` resolves against the
process cwd, not against the pattern it accompanies. Since `yarn
workspace` sets cwd to the package dir, every exclusion silently stopped
matching and test fixtures leaked in (117 namespaces instead of 112).

Related: declaration-file exclusions are deliberately narrower than the
source ones. A blanket `dist/**` matches the segment those files live
under and drops all 1980.

## Behaviour change

A broken symlink used to emit a per-file parse warning. The matcher now
resolves it away before ts-morph sees it, so it is skipped silently;
valid files are still documented. One test rewritten to match.

## Follow-up

Second step makes each strategy self contained, which is what
MetaMask#9913 (comment) asked
for. Worth knowing before that review: `extraction.ts` is a scan-only
front end welded onto a shared core, so the split has to cut through it
too, not just `generate.ts`.

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Internal tooling refactor with byte-identical output claimed; main
risk is glob/exclusion edge cases on unusual filesystem layouts, now
covered by new tests.
> 
> **Overview**
> **Speeds up doc generation** by replacing per-file `glob` discovery
and `addSourceFileAtPath` loops with a single shared ts-morph `Project`
that bulk-loads matches via `addSourceFilesAtPaths`. Removes
`discovery.ts`, the `glob` dependency, and merges the two project
factories into shared `createProject()` in `ts-project.ts`.
> 
> The scan strategy now builds **resolved, forward-slashed glob roots**
(`toGlobPath` + `realpath`) and **content-root–anchored exclusion
negations** so test/dist skips work when cwd ≠ project root and monorepo
packages named `test`/`dist` are not excluded wholesale. Added source
files are **sorted by path** for stable dedup/source links; extraction
uses a **realpath’d project root** for relative source paths.
> 
> **Behavior:** unreadable paths (e.g. broken symlinks) are skipped
without per-file parse warnings; valid files still document. Tests cover
the `packages/test` exclusion edge case and the symlink case.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
55c4a26. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
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