Skip to content

feat: add @metamask/platform-api-docs package#8012

Open
cryptodev-2s wants to merge 92 commits into
mainfrom
feat/messenger-docs-site
Open

feat: add @metamask/platform-api-docs package#8012
cryptodev-2s wants to merge 92 commits into
mainfrom
feat/messenger-docs-site

Conversation

@cryptodev-2s
Copy link
Copy Markdown
Contributor

@cryptodev-2s cryptodev-2s commented Feb 22, 2026

Explanation

Adds @metamask/platform-api-docs, a publishable package that generates and serves a searchable site documenting the Platform API — the catalog of actions and events available to clients through the message bus.

The package scans TypeScript source and .d.cts declaration files, finds every *Messenger type declaration, walks its Actions and Events type arguments to discover the capability types they reference, extracts JSDoc/handler/payload information for each, and renders the result as a Docusaurus site with per-namespace pages and local search.

Features

  • Anchored on Messenger declarations. Extraction discovers *Messenger type aliases and walks Messenger<Namespace, Actions, Events> to find the capability types — eliminating false positives from unrelated types that happen to share an action/event-like shape.
  • Two capability-type patterns supported. Inline (type FooAction = { type: '...'; handler: ... }) and capability-type constructors (type FooGetStateAction = ControllerGetStateAction<typeof name, State>), including their interface variants.
  • Union expansion. When a Messenger references an umbrella union like FooActions = FooGetAction | FooSetAction, the walker descends through it without documenting the intermediate alias.
  • Scans three layouts. Configured --scan-dirs, packages/*/src/ (.ts), and node_modules/@metamask/*/dist/ (.d.cts).
  • Source links resolve automatically. Reads git remote get-url origin and git symbolic-ref refs/remotes/origin/HEAD to build https://github.com/<owner>/<repo>/blob/<branch>/<path>#L<line> URLs; falls back to main for shallow clones.
  • Project label and commit SHA stamped on the site. --project-label Core / --project-label Extension produces titles like Platform API (Core), and the short Git commit is shown in the intro and navbar so engineers can tell how current the docs are.
  • Dedup across packages. When a capability is declared in two places (e.g. once as the home definition and once as a re-export), the version with JSDoc and from the matching namespace's package wins.
  • Docusaurus site with dark/light mode, offline search (no Algolia), and MDX-safe rendering of JSDoc.

Usage

From the core monorepo:

yarn docs:platform-api:build   # Generate docs and build static site
yarn docs:platform-api:dev     # Dev server with hot reload
yarn docs:platform-api:serve   # Build and serve

From client projects (Extension, Mobile), install @metamask/platform-api-docs as a devDependency and add a script:

{
  "scripts": {
    "docs:platform-api:build": "platform-api-docs --build --project-label MyProject"
  }
}

Implementation

  • packages/platform-api-docs/ — separate workspace from @metamask/messenger-cli (different deps and release cadence).
  • CLI built with yargs; runs Docusaurus through execa. Flags: --build, --serve, --dev, --scan-dir (additive, repeatable), --output, --project-label. Configuration is CLI-only — no package.json config block.
  • AST parsing via ts-morph instead of the raw TypeScript compiler API. Standard JSDoc extraction (jsDoc.getDescription() + getTags()) replaces the previous hand-rolled comment parser.
  • Single-pass extraction. The Messenger walk returns TypeAliasDeclaration/InterfaceDeclaration nodes directly tagged with 'action'/'event' kind, so the main loop doesn't re-walk the source file looking up names.
  • File discovery via the glob package, with results sorted for deterministic output across filesystems.
  • Test coverage: 100% lines / ~93% branches. Defensive guards against AST shapes that don't appear in real messenger types are explicitly marked with // istanbul ignore comments.
  • GitHub Actions workflow (deploy-platform-api-docs.yml) builds docs on PRs (uploads the build as an artifact) and deploys to GitHub Pages on main.

References

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

Medium Risk
Adds a new publishable docs generator plus a GitHub Pages deploy workflow and new tooling/dependency resolutions, which could affect CI/build behavior across the monorepo if misconfigured.

Overview
Adds new @metamask/platform-api-docs workspace that scans TS and .d.cts files for *Messenger type declarations, extracts action/event docs (including JSDoc), and can --build/--dev/--serve a Docusaurus site via a new CLI.

Wires the package into the monorepo via new root docs:platform-api:* scripts, TypeScript project references, eslint ignores/rules, team ownership/README listing, and ignores generated .platform-api-docs/ output.

Adds deploy-platform-api-docs.yml to build docs on PRs (artifact upload) and deploy /platform-api/ to GitHub Pages on main, and updates root dependency resolutions/Lavamoat allowlist for the new tooling.

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

@cryptodev-2s cryptodev-2s self-assigned this Feb 22, 2026
@cryptodev-2s cryptodev-2s force-pushed the feat/messenger-docs-site branch 4 times, most recently from 63f3188 to 7c63a0d Compare February 22, 2026 22:26
@socket-security
Copy link
Copy Markdown

socket-security Bot commented Feb 22, 2026

@socket-security
Copy link
Copy Markdown

socket-security Bot commented Feb 22, 2026

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 High
High CVE: npm @babel/plugin-transform-modules-systemjs generates arbitrary code when compiling malicious input

CVE: GHSA-fv7c-fp4j-7gwp @babel/plugin-transform-modules-systemjs generates arbitrary code when compiling malicious input (HIGH)

Affected versions: >= 7.12.0 < 7.29.4; >= 8.0.0-alpha.0 < 8.0.0-alpha.13

Patched version: 7.29.4

From: ?npm/@docusaurus/core@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/@babel/plugin-transform-modules-systemjs@7.29.0

ℹ Read more on: This package | This alert | What is a CVE?

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: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@babel/plugin-transform-modules-systemjs@7.29.0. 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.

Block High
High CVE: npm fast-uri vulnerable to host confusion via percent-encoded authority delimiters

CVE: GHSA-v39h-62p7-jpjc fast-uri vulnerable to host confusion via percent-encoded authority delimiters (HIGH)

Affected versions: < 3.1.2

Patched version: 3.1.2

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@docusaurus/types@3.10.1npm/@docusaurus/core@3.10.1npm/@docusaurus/theme-common@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/fast-uri@3.1.0

ℹ Read more on: This package | This alert | What is a CVE?

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: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/fast-uri@3.1.0. 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.

Block High
High CVE: npm fast-uri vulnerable to path traversal via percent-encoded dot segments

CVE: GHSA-q3j6-qgpj-74h6 fast-uri vulnerable to path traversal via percent-encoded dot segments (HIGH)

Affected versions: < 3.1.1

Patched version: 3.1.1

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@docusaurus/types@3.10.1npm/@docusaurus/core@3.10.1npm/@docusaurus/theme-common@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/fast-uri@3.1.0

ℹ Read more on: This package | This alert | What is a CVE?

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: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/fast-uri@3.1.0. 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.

Block High
Obfuscated code: npm lunr-languages is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/lunr-languages@1.14.0

ℹ Read more on: This package | This alert | What is obfuscated code?

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 not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/lunr-languages@1.14.0. 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.

Block High
Obfuscated code: npm lunr-languages is 95.0% likely obfuscated

Confidence: 0.95

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/lunr-languages@1.14.0

ℹ Read more on: This package | This alert | What is obfuscated code?

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 not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/lunr-languages@1.14.0. 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.

Block High
Obfuscated code: npm svgo is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/svgo@3.3.3

ℹ Read more on: This package | This alert | What is obfuscated code?

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 not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/svgo@3.3.3. 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.

Block Medium
Network access: npm @algolia/client-personalization in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/@algolia/client-personalization@5.52.0

ℹ 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/@algolia/client-personalization@5.52.0. 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.

Block Medium
Network access: npm @algolia/requester-fetch in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/@algolia/requester-fetch@5.52.0

ℹ 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/@algolia/requester-fetch@5.52.0. 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.

Block Medium
Network access: npm @algolia/requester-node-http in module http

Module: http

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/@algolia/requester-node-http@5.52.0

ℹ 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/@algolia/requester-node-http@5.52.0. 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.

Block Medium
Network access: npm @algolia/requester-node-http in module https

Module: https

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/@algolia/requester-node-http@5.52.0

ℹ 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/@algolia/requester-node-http@5.52.0. 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.

Block Medium
Network access: npm @docsearch/react in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/@docsearch/react@4.6.3

ℹ 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/@docsearch/react@4.6.3. 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.

Block Medium
Network access: npm @emnapi/core in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@emnapi/core@1.10.0

ℹ 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/@emnapi/core@1.10.0. 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.

Block Medium
System shell access: npm @node-rs/jieba in module child_process

Module: child_process

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@node-rs/jieba@1.10.4

ℹ Read more on: This package | This alert | What is shell 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 avoid accessing the shell which can reduce portability, and make it easier for malicious shell access to be introduced.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@node-rs/jieba@1.10.4. 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.

Block Medium
Network access: npm @pnpm/npm-conf in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/@pnpm/npm-conf@3.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/@pnpm/npm-conf@3.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.

Block Medium
Network access: npm @tybys/wasm-util in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@tybys/wasm-util@0.10.1

ℹ 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/@tybys/wasm-util@0.10.1. 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.

Block Medium
System shell access: npm address in module child_process

Module: child_process

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/address@1.2.2

ℹ Read more on: This package | This alert | What is shell 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 avoid accessing the shell which can reduce portability, and make it easier for malicious shell access to be introduced.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/address@1.2.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.

Block Medium
Network access: npm algoliasearch-helper in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/preset-classic@3.10.1npm/algoliasearch-helper@3.28.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/algoliasearch-helper@3.28.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.

Block Medium
Network access: npm babel-plugin-polyfill-corejs3 in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/babel-plugin-polyfill-corejs3@0.13.0

ℹ 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/babel-plugin-polyfill-corejs3@0.13.0. 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.

Block Medium
Network access: npm babel-plugin-polyfill-corejs3 in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/babel-plugin-polyfill-corejs3@0.14.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/babel-plugin-polyfill-corejs3@0.14.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.

Block Medium
Network access: npm clean-css in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/clean-css@5.3.3

ℹ 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/clean-css@5.3.3. 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.

Block Medium
Network access: npm clean-css in module http

Module: http

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/clean-css@5.3.3

ℹ 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/clean-css@5.3.3. 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.

Block Medium
Network access: npm clean-css in module https

Module: https

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/clean-css@5.3.3

ℹ 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/clean-css@5.3.3. 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.

Block Medium
Network access: npm config-chain in module http

Module: http

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/config-chain@1.1.13

ℹ 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/config-chain@1.1.13. 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.

Block Medium
Network access: npm core-js in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/core-js@3.49.0

ℹ 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/core-js@3.49.0. 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.

Block Medium
Network access: npm detect-port in module net

Module: net

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/detect-port@1.6.1

ℹ 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/detect-port@1.6.1. 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.

Block Medium
Network access: npm domutils in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@docusaurus/core@3.10.1npm/domutils@2.8.0

ℹ 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/domutils@2.8.0. 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.

Block Medium
Network access: npm domutils in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@easyops-cn/docusaurus-search-local@0.55.1npm/@docusaurus/core@3.10.1npm/@docusaurus/preset-classic@3.10.1npm/domutils@3.2.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/domutils@3.2.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.

See 117 more rows in the dashboard

View full report

@cryptodev-2s cryptodev-2s force-pushed the feat/messenger-docs-site branch 3 times, most recently from b55b682 to 980f677 Compare February 23, 2026 22:31
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "4.1.1-preview-980f677",
  "@metamask-previews/accounts-controller": "36.0.1-preview-980f677",
  "@metamask-previews/address-book-controller": "7.0.1-preview-980f677",
  "@metamask-previews/ai-controllers": "0.1.0-preview-980f677",
  "@metamask-previews/analytics-controller": "1.0.0-preview-980f677",
  "@metamask-previews/analytics-data-regulation-controller": "0.0.0-preview-980f677",
  "@metamask-previews/announcement-controller": "8.0.0-preview-980f677",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-980f677",
  "@metamask-previews/approval-controller": "8.0.0-preview-980f677",
  "@metamask-previews/assets-controller": "2.0.2-preview-980f677",
  "@metamask-previews/assets-controllers": "100.0.2-preview-980f677",
  "@metamask-previews/base-controller": "9.0.0-preview-980f677",
  "@metamask-previews/bridge-controller": "67.1.1-preview-980f677",
  "@metamask-previews/bridge-status-controller": "67.0.1-preview-980f677",
  "@metamask-previews/build-utils": "3.0.4-preview-980f677",
  "@metamask-previews/chain-agnostic-permission": "1.4.0-preview-980f677",
  "@metamask-previews/claims-controller": "0.4.2-preview-980f677",
  "@metamask-previews/client-controller": "1.0.0-preview-980f677",
  "@metamask-previews/compliance-controller": "1.0.1-preview-980f677",
  "@metamask-previews/composable-controller": "12.0.0-preview-980f677",
  "@metamask-previews/connectivity-controller": "0.1.0-preview-980f677",
  "@metamask-previews/controller-utils": "11.19.0-preview-980f677",
  "@metamask-previews/core-backend": "6.0.0-preview-980f677",
  "@metamask-previews/delegation-controller": "2.0.1-preview-980f677",
  "@metamask-previews/earn-controller": "11.1.1-preview-980f677",
  "@metamask-previews/eip-5792-middleware": "2.1.0-preview-980f677",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-980f677",
  "@metamask-previews/eip1193-permission-middleware": "1.0.3-preview-980f677",
  "@metamask-previews/ens-controller": "19.0.3-preview-980f677",
  "@metamask-previews/error-reporting-service": "3.0.1-preview-980f677",
  "@metamask-previews/eth-block-tracker": "15.0.1-preview-980f677",
  "@metamask-previews/eth-json-rpc-middleware": "23.1.0-preview-980f677",
  "@metamask-previews/eth-json-rpc-provider": "6.0.0-preview-980f677",
  "@metamask-previews/foundryup": "1.0.1-preview-980f677",
  "@metamask-previews/gas-fee-controller": "26.0.3-preview-980f677",
  "@metamask-previews/gator-permissions-controller": "2.0.0-preview-980f677",
  "@metamask-previews/json-rpc-engine": "10.2.2-preview-980f677",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-980f677",
  "@metamask-previews/keyring-controller": "25.1.0-preview-980f677",
  "@metamask-previews/logging-controller": "7.0.1-preview-980f677",
  "@metamask-previews/message-manager": "14.1.0-preview-980f677",
  "@metamask-previews/messenger": "0.3.0-preview-980f677",
  "@metamask-previews/multichain-account-service": "7.0.0-preview-980f677",
  "@metamask-previews/multichain-api-middleware": "1.2.7-preview-980f677",
  "@metamask-previews/multichain-network-controller": "3.0.4-preview-980f677",
  "@metamask-previews/multichain-transactions-controller": "7.0.1-preview-980f677",
  "@metamask-previews/name-controller": "9.0.0-preview-980f677",
  "@metamask-previews/network-controller": "30.0.0-preview-980f677",
  "@metamask-previews/network-enablement-controller": "4.1.2-preview-980f677",
  "@metamask-previews/notification-services-controller": "22.0.0-preview-980f677",
  "@metamask-previews/permission-controller": "12.2.0-preview-980f677",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-980f677",
  "@metamask-previews/perps-controller": "0.0.0-preview-980f677",
  "@metamask-previews/phishing-controller": "16.3.0-preview-980f677",
  "@metamask-previews/polling-controller": "16.0.3-preview-980f677",
  "@metamask-previews/preferences-controller": "22.1.0-preview-980f677",
  "@metamask-previews/profile-metrics-controller": "3.0.1-preview-980f677",
  "@metamask-previews/profile-sync-controller": "27.1.0-preview-980f677",
  "@metamask-previews/ramps-controller": "10.0.0-preview-980f677",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-980f677",
  "@metamask-previews/remote-feature-flag-controller": "4.0.0-preview-980f677",
  "@metamask-previews/sample-controllers": "4.0.3-preview-980f677",
  "@metamask-previews/seedless-onboarding-controller": "8.1.0-preview-980f677",
  "@metamask-previews/selected-network-controller": "26.0.3-preview-980f677",
  "@metamask-previews/shield-controller": "5.0.1-preview-980f677",
  "@metamask-previews/signature-controller": "39.0.4-preview-980f677",
  "@metamask-previews/storage-service": "1.0.0-preview-980f677",
  "@metamask-previews/subscription-controller": "6.0.0-preview-980f677",
  "@metamask-previews/transaction-controller": "62.18.0-preview-980f677",
  "@metamask-previews/transaction-pay-controller": "16.0.0-preview-980f677",
  "@metamask-previews/user-operation-controller": "41.0.3-preview-980f677"
}

@cryptodev-2s cryptodev-2s force-pushed the feat/messenger-docs-site branch from 980f677 to f49a7dd Compare February 24, 2026 15:09
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

1 similar comment
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@cryptodev-2s cryptodev-2s force-pushed the feat/messenger-docs-site branch from f49a7dd to 44fb063 Compare February 24, 2026 16:22
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@cryptodev-2s cryptodev-2s changed the title feat: add Messenger API docs site with local search feat: add @metamask/messenger-docs Feb 24, 2026
@cryptodev-2s cryptodev-2s changed the title feat: add @metamask/messenger-docs feat: add @metamask/messenger-docs Feb 24, 2026
@cryptodev-2s cryptodev-2s changed the title feat: add @metamask/messenger-docs feat: add @metamask/messenger-docs package Feb 24, 2026
cryptodev-2s and others added 8 commits February 25, 2026 18:55
Docusaurus site for browsing controller messenger actions/events,
with offline search powered by docusaurus-search-local.
## Explanation

The messenger docs generation currently lives in
`scripts/generate-messenger-docs/` and the Docusaurus site template in
`docs-site/`. This makes it unusable by external clients
(metamask-extension, metamask-mobile) without access to this monorepo.

This PR extracts both into a new `@metamask/messenger-docs` package at
`packages/messenger-docs/` with a CLI, so any project with `@metamask`
controller dependencies can generate and serve messenger API docs.

### Usage

```bash
# Default: scans cwd for node_modules/@MetaMask controller/service packages
npx @metamask/messenger-docs

# Scan a specific project
npx @metamask/messenger-docs /path/to/project

# Generate + build static site
npx @metamask/messenger-docs --build

# Generate + serve (build + http server)
npx @metamask/messenger-docs --serve

# Generate + dev server (hot reload)
npx @metamask/messenger-docs --dev

# Scan source .ts files instead of .d.cts (for monorepo development)
npx @metamask/messenger-docs --source

# Custom output directory (default: .messenger-docs)
npx @metamask/messenger-docs --output ./my-docs
```

## References

- Builds on top of `feat/messenger-docs-site`

## 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
@cryptodev-2s cryptodev-2s force-pushed the feat/messenger-docs-site branch from cb82c24 to 17adacd Compare February 25, 2026 17:55
@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.3.0-preview-2b9ec1def
@metamask-previews/accounts-controller@38.1.1-preview-2b9ec1def
@metamask-previews/address-book-controller@7.1.2-preview-2b9ec1def
@metamask-previews/ai-controllers@0.6.3-preview-2b9ec1def
@metamask-previews/analytics-controller@1.0.1-preview-2b9ec1def
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-2b9ec1def
@metamask-previews/announcement-controller@8.1.0-preview-2b9ec1def
@metamask-previews/app-metadata-controller@2.0.1-preview-2b9ec1def
@metamask-previews/approval-controller@9.0.1-preview-2b9ec1def
@metamask-previews/assets-controller@7.1.1-preview-2b9ec1def
@metamask-previews/assets-controllers@108.0.0-preview-2b9ec1def
@metamask-previews/authenticated-user-storage@1.0.1-preview-2b9ec1def
@metamask-previews/base-controller@9.1.0-preview-2b9ec1def
@metamask-previews/base-data-service@0.1.2-preview-2b9ec1def
@metamask-previews/bridge-controller@72.0.4-preview-2b9ec1def
@metamask-previews/bridge-status-controller@71.1.4-preview-2b9ec1def
@metamask-previews/build-utils@3.0.4-preview-2b9ec1def
@metamask-previews/chain-agnostic-permission@1.6.1-preview-2b9ec1def
@metamask-previews/chomp-api-service@3.1.0-preview-2b9ec1def
@metamask-previews/claims-controller@0.5.1-preview-2b9ec1def
@metamask-previews/client-controller@1.0.1-preview-2b9ec1def
@metamask-previews/compliance-controller@2.0.1-preview-2b9ec1def
@metamask-previews/composable-controller@12.0.1-preview-2b9ec1def
@metamask-previews/config-registry-controller@0.3.1-preview-2b9ec1def
@metamask-previews/connectivity-controller@0.2.0-preview-2b9ec1def
@metamask-previews/controller-utils@12.1.0-preview-2b9ec1def
@metamask-previews/core-backend@6.2.2-preview-2b9ec1def
@metamask-previews/delegation-controller@3.0.0-preview-2b9ec1def
@metamask-previews/earn-controller@12.1.2-preview-2b9ec1def
@metamask-previews/eip-5792-middleware@3.0.3-preview-2b9ec1def
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-2b9ec1def
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-2b9ec1def
@metamask-previews/ens-controller@19.1.3-preview-2b9ec1def
@metamask-previews/eth-block-tracker@15.0.1-preview-2b9ec1def
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-2b9ec1def
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-2b9ec1def
@metamask-previews/foundryup@1.0.1-preview-2b9ec1def
@metamask-previews/gas-fee-controller@26.2.1-preview-2b9ec1def
@metamask-previews/gator-permissions-controller@4.1.2-preview-2b9ec1def
@metamask-previews/geolocation-controller@0.1.3-preview-2b9ec1def
@metamask-previews/json-rpc-engine@10.5.0-preview-2b9ec1def
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-2b9ec1def
@metamask-previews/keyring-controller@25.5.0-preview-2b9ec1def
@metamask-previews/logging-controller@8.0.2-preview-2b9ec1def
@metamask-previews/message-manager@14.1.2-preview-2b9ec1def
@metamask-previews/messenger@1.2.0-preview-2b9ec1def
@metamask-previews/messenger-cli@0.2.0-preview-2b9ec1def
@metamask-previews/messenger-docs@0.0.0-preview-2b9ec1def
@metamask-previews/money-account-balance-service@1.0.2-preview-2b9ec1def
@metamask-previews/money-account-controller@0.3.0-preview-2b9ec1def
@metamask-previews/money-account-upgrade-controller@2.0.1-preview-2b9ec1def
@metamask-previews/multichain-account-service@9.0.0-preview-2b9ec1def
@metamask-previews/multichain-api-middleware@3.1.2-preview-2b9ec1def
@metamask-previews/multichain-network-controller@3.1.1-preview-2b9ec1def
@metamask-previews/multichain-transactions-controller@7.1.0-preview-2b9ec1def
@metamask-previews/name-controller@9.1.2-preview-2b9ec1def
@metamask-previews/network-controller@32.0.0-preview-2b9ec1def
@metamask-previews/network-enablement-controller@5.1.1-preview-2b9ec1def
@metamask-previews/notification-services-controller@23.1.1-preview-2b9ec1def
@metamask-previews/passkey-controller@2.0.1-preview-2b9ec1def
@metamask-previews/permission-controller@13.1.1-preview-2b9ec1def
@metamask-previews/permission-log-controller@5.1.0-preview-2b9ec1def
@metamask-previews/perps-controller@6.0.1-preview-2b9ec1def
@metamask-previews/phishing-controller@17.1.2-preview-2b9ec1def
@metamask-previews/polling-controller@16.0.5-preview-2b9ec1def
@metamask-previews/preferences-controller@23.1.0-preview-2b9ec1def
@metamask-previews/profile-metrics-controller@3.1.4-preview-2b9ec1def
@metamask-previews/profile-sync-controller@28.0.2-preview-2b9ec1def
@metamask-previews/ramps-controller@13.3.1-preview-2b9ec1def
@metamask-previews/rate-limit-controller@7.0.1-preview-2b9ec1def
@metamask-previews/react-data-query@0.2.0-preview-2b9ec1def
@metamask-previews/remote-feature-flag-controller@4.2.1-preview-2b9ec1def
@metamask-previews/sample-controllers@5.0.1-preview-2b9ec1def
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-2b9ec1def
@metamask-previews/selected-network-controller@26.1.3-preview-2b9ec1def
@metamask-previews/shield-controller@5.1.2-preview-2b9ec1def
@metamask-previews/signature-controller@39.2.2-preview-2b9ec1def
@metamask-previews/snap-account-service@0.0.0-preview-2b9ec1def
@metamask-previews/social-controllers@2.2.1-preview-2b9ec1def
@metamask-previews/storage-service@1.0.1-preview-2b9ec1def
@metamask-previews/subscription-controller@6.1.3-preview-2b9ec1def
@metamask-previews/transaction-controller@65.3.0-preview-2b9ec1def
@metamask-previews/transaction-pay-controller@22.3.1-preview-2b9ec1def
@metamask-previews/user-operation-controller@41.2.2-preview-2b9ec1def

Source links generated by messenger-docs hardcoded `blob/main/` in the
GitHub URL. For consumers whose default branch is something other than
`main` (e.g. `master`, `develop`), every source link would 404.

Resolve the default branch via `git symbolic-ref refs/remotes/origin/HEAD`
when available, falling back to `main` if the symbolic ref isn't set
(e.g. in shallow CI clones).
@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.3.0-preview-fbc0aed37
@metamask-previews/accounts-controller@38.1.1-preview-fbc0aed37
@metamask-previews/address-book-controller@7.1.2-preview-fbc0aed37
@metamask-previews/ai-controllers@0.6.3-preview-fbc0aed37
@metamask-previews/analytics-controller@1.0.1-preview-fbc0aed37
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-fbc0aed37
@metamask-previews/announcement-controller@8.1.0-preview-fbc0aed37
@metamask-previews/app-metadata-controller@2.0.1-preview-fbc0aed37
@metamask-previews/approval-controller@9.0.1-preview-fbc0aed37
@metamask-previews/assets-controller@7.1.1-preview-fbc0aed37
@metamask-previews/assets-controllers@108.0.0-preview-fbc0aed37
@metamask-previews/authenticated-user-storage@1.0.1-preview-fbc0aed37
@metamask-previews/base-controller@9.1.0-preview-fbc0aed37
@metamask-previews/base-data-service@0.1.2-preview-fbc0aed37
@metamask-previews/bridge-controller@72.0.4-preview-fbc0aed37
@metamask-previews/bridge-status-controller@71.1.4-preview-fbc0aed37
@metamask-previews/build-utils@3.0.4-preview-fbc0aed37
@metamask-previews/chain-agnostic-permission@1.6.1-preview-fbc0aed37
@metamask-previews/chomp-api-service@3.1.0-preview-fbc0aed37
@metamask-previews/claims-controller@0.5.1-preview-fbc0aed37
@metamask-previews/client-controller@1.0.1-preview-fbc0aed37
@metamask-previews/compliance-controller@2.0.1-preview-fbc0aed37
@metamask-previews/composable-controller@12.0.1-preview-fbc0aed37
@metamask-previews/config-registry-controller@0.3.1-preview-fbc0aed37
@metamask-previews/connectivity-controller@0.2.0-preview-fbc0aed37
@metamask-previews/controller-utils@12.1.0-preview-fbc0aed37
@metamask-previews/core-backend@6.2.2-preview-fbc0aed37
@metamask-previews/delegation-controller@3.0.0-preview-fbc0aed37
@metamask-previews/earn-controller@12.1.2-preview-fbc0aed37
@metamask-previews/eip-5792-middleware@3.0.3-preview-fbc0aed37
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-fbc0aed37
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-fbc0aed37
@metamask-previews/ens-controller@19.1.3-preview-fbc0aed37
@metamask-previews/eth-block-tracker@15.0.1-preview-fbc0aed37
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-fbc0aed37
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-fbc0aed37
@metamask-previews/foundryup@1.0.1-preview-fbc0aed37
@metamask-previews/gas-fee-controller@26.2.1-preview-fbc0aed37
@metamask-previews/gator-permissions-controller@4.1.2-preview-fbc0aed37
@metamask-previews/geolocation-controller@0.1.3-preview-fbc0aed37
@metamask-previews/json-rpc-engine@10.5.0-preview-fbc0aed37
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-fbc0aed37
@metamask-previews/keyring-controller@25.5.0-preview-fbc0aed37
@metamask-previews/logging-controller@8.0.2-preview-fbc0aed37
@metamask-previews/message-manager@14.1.2-preview-fbc0aed37
@metamask-previews/messenger@1.2.0-preview-fbc0aed37
@metamask-previews/messenger-cli@0.2.0-preview-fbc0aed37
@metamask-previews/messenger-docs@0.0.0-preview-fbc0aed37
@metamask-previews/money-account-balance-service@1.0.2-preview-fbc0aed37
@metamask-previews/money-account-controller@0.3.0-preview-fbc0aed37
@metamask-previews/money-account-upgrade-controller@2.0.1-preview-fbc0aed37
@metamask-previews/multichain-account-service@9.0.0-preview-fbc0aed37
@metamask-previews/multichain-api-middleware@3.1.2-preview-fbc0aed37
@metamask-previews/multichain-network-controller@3.1.1-preview-fbc0aed37
@metamask-previews/multichain-transactions-controller@7.1.0-preview-fbc0aed37
@metamask-previews/name-controller@9.1.2-preview-fbc0aed37
@metamask-previews/network-controller@32.0.0-preview-fbc0aed37
@metamask-previews/network-enablement-controller@5.1.1-preview-fbc0aed37
@metamask-previews/notification-services-controller@23.1.1-preview-fbc0aed37
@metamask-previews/passkey-controller@2.0.1-preview-fbc0aed37
@metamask-previews/permission-controller@13.1.1-preview-fbc0aed37
@metamask-previews/permission-log-controller@5.1.0-preview-fbc0aed37
@metamask-previews/perps-controller@6.0.1-preview-fbc0aed37
@metamask-previews/phishing-controller@17.1.2-preview-fbc0aed37
@metamask-previews/polling-controller@16.0.5-preview-fbc0aed37
@metamask-previews/preferences-controller@23.1.0-preview-fbc0aed37
@metamask-previews/profile-metrics-controller@3.1.4-preview-fbc0aed37
@metamask-previews/profile-sync-controller@28.0.2-preview-fbc0aed37
@metamask-previews/ramps-controller@13.3.1-preview-fbc0aed37
@metamask-previews/rate-limit-controller@7.0.1-preview-fbc0aed37
@metamask-previews/react-data-query@0.2.0-preview-fbc0aed37
@metamask-previews/remote-feature-flag-controller@4.2.1-preview-fbc0aed37
@metamask-previews/sample-controllers@5.0.1-preview-fbc0aed37
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-fbc0aed37
@metamask-previews/selected-network-controller@26.1.3-preview-fbc0aed37
@metamask-previews/shield-controller@5.1.2-preview-fbc0aed37
@metamask-previews/signature-controller@39.2.2-preview-fbc0aed37
@metamask-previews/snap-account-service@0.0.0-preview-fbc0aed37
@metamask-previews/social-controllers@2.2.1-preview-fbc0aed37
@metamask-previews/storage-service@1.0.1-preview-fbc0aed37
@metamask-previews/subscription-controller@6.1.3-preview-fbc0aed37
@metamask-previews/transaction-controller@65.3.0-preview-fbc0aed37
@metamask-previews/transaction-pay-controller@22.3.1-preview-fbc0aed37
@metamask-previews/user-operation-controller@41.2.2-preview-fbc0aed37

Three targeted changes:

- Remove the unreachable `TemplateExpression` branch from
  `resolveTypeString` in extraction.ts. The function is only called
  with `LiteralTypeNode.getLiteral()`, whose result is never a
  `TemplateExpression` — substituted template literals in type position
  are `TemplateLiteralTypeNode` and handled separately.
- Add generate tests that initialize a real git repo in the sandbox
  (`git init` + `git remote add origin ...` + `git symbolic-ref`)
  to cover `resolveDefaultBranch` and the GitHub-vs-non-GitHub branches
  of `resolveRepoBaseUrl`.
- Add markdown tests that exercise namespace pages containing both
  actions and events, including a `repoBaseUrl` source link and a
  deprecated item.

Coverage moves from 86.72 / 70.88 / 94.54 / 86.92 (the temporarily
lowered threshold) back to 91.35 / 75.39 / 94.64 / 91.59, restoring
the original 91 / 72 / 92 / 91 threshold.
Comment thread packages/platform-api-docs/src/cli.ts
Adds two pieces of provenance to the generated site so engineers can
tell at a glance which project the docs were generated from and how
current they are:

- The project label is resolved from `package.json#messenger-docs.title`
  when set, otherwise derived from `package.json#name`
  (`@metamask/core-monorepo` → "Core", `metamask-extension` → "Extension").
- The short Git commit SHA is read via `git rev-parse --short HEAD`.

Both are plumbed into `generate()` (and into Docusaurus via the
`DOCS_PROJECT_LABEL` / `DOCS_COMMIT_SHA` env vars) so that:

- The browser title becomes `Platform API (Core) Reference | Platform API (Core)`.
- The index page heading becomes `# Platform API (Core)` with a
  "_Generated from commit `<sha>`._" line in the intro.
- A `commit <sha>` link appears in the navbar.

Also fixes the `--scan-dir` flag to actually be additive, matching its
documented "Additional directories" semantics. Previously, supplying
`--scan-dir app` silently dropped the default `src` directory; the flag
now appends to the base set (the `scanDirs` config, or `['src']`),
deduplicating while preserving order.
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

1 similar comment
@cryptodev-2s
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@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.4.0-preview-e5cef32c6
@metamask-previews/accounts-controller@38.1.1-preview-e5cef32c6
@metamask-previews/address-book-controller@7.1.2-preview-e5cef32c6
@metamask-previews/ai-controllers@0.6.3-preview-e5cef32c6
@metamask-previews/analytics-controller@1.0.1-preview-e5cef32c6
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-e5cef32c6
@metamask-previews/announcement-controller@8.1.0-preview-e5cef32c6
@metamask-previews/app-metadata-controller@2.0.1-preview-e5cef32c6
@metamask-previews/approval-controller@9.0.1-preview-e5cef32c6
@metamask-previews/assets-controller@7.1.2-preview-e5cef32c6
@metamask-previews/assets-controllers@108.1.0-preview-e5cef32c6
@metamask-previews/authenticated-user-storage@1.0.1-preview-e5cef32c6
@metamask-previews/base-controller@9.1.0-preview-e5cef32c6
@metamask-previews/base-data-service@0.1.3-preview-e5cef32c6
@metamask-previews/bridge-controller@72.0.4-preview-e5cef32c6
@metamask-previews/bridge-status-controller@71.1.4-preview-e5cef32c6
@metamask-previews/build-utils@3.0.4-preview-e5cef32c6
@metamask-previews/chain-agnostic-permission@1.6.1-preview-e5cef32c6
@metamask-previews/chomp-api-service@3.1.0-preview-e5cef32c6
@metamask-previews/claims-controller@0.5.1-preview-e5cef32c6
@metamask-previews/client-controller@1.0.1-preview-e5cef32c6
@metamask-previews/compliance-controller@2.0.1-preview-e5cef32c6
@metamask-previews/composable-controller@12.0.1-preview-e5cef32c6
@metamask-previews/config-registry-controller@0.3.1-preview-e5cef32c6
@metamask-previews/connectivity-controller@0.2.0-preview-e5cef32c6
@metamask-previews/controller-utils@12.1.0-preview-e5cef32c6
@metamask-previews/core-backend@6.2.2-preview-e5cef32c6
@metamask-previews/delegation-controller@3.0.0-preview-e5cef32c6
@metamask-previews/earn-controller@12.1.2-preview-e5cef32c6
@metamask-previews/eip-5792-middleware@3.0.4-preview-e5cef32c6
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-e5cef32c6
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-e5cef32c6
@metamask-previews/ens-controller@19.1.3-preview-e5cef32c6
@metamask-previews/eth-block-tracker@15.0.1-preview-e5cef32c6
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-e5cef32c6
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-e5cef32c6
@metamask-previews/foundryup@1.0.1-preview-e5cef32c6
@metamask-previews/gas-fee-controller@26.2.1-preview-e5cef32c6
@metamask-previews/gator-permissions-controller@4.1.2-preview-e5cef32c6
@metamask-previews/geolocation-controller@0.1.3-preview-e5cef32c6
@metamask-previews/json-rpc-engine@10.5.0-preview-e5cef32c6
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-e5cef32c6
@metamask-previews/keyring-controller@25.5.0-preview-e5cef32c6
@metamask-previews/logging-controller@8.0.2-preview-e5cef32c6
@metamask-previews/message-manager@14.1.2-preview-e5cef32c6
@metamask-previews/messenger@1.2.0-preview-e5cef32c6
@metamask-previews/messenger-cli@0.2.0-preview-e5cef32c6
@metamask-previews/messenger-docs@0.0.0-preview-e5cef32c6
@metamask-previews/money-account-balance-service@1.0.2-preview-e5cef32c6
@metamask-previews/money-account-controller@0.3.0-preview-e5cef32c6
@metamask-previews/money-account-upgrade-controller@2.0.1-preview-e5cef32c6
@metamask-previews/multichain-account-service@10.0.0-preview-e5cef32c6
@metamask-previews/multichain-api-middleware@3.1.2-preview-e5cef32c6
@metamask-previews/multichain-network-controller@3.1.1-preview-e5cef32c6
@metamask-previews/multichain-transactions-controller@7.1.0-preview-e5cef32c6
@metamask-previews/name-controller@9.1.2-preview-e5cef32c6
@metamask-previews/network-controller@32.0.0-preview-e5cef32c6
@metamask-previews/network-enablement-controller@5.1.1-preview-e5cef32c6
@metamask-previews/notification-services-controller@23.1.1-preview-e5cef32c6
@metamask-previews/passkey-controller@2.0.1-preview-e5cef32c6
@metamask-previews/permission-controller@13.1.1-preview-e5cef32c6
@metamask-previews/permission-log-controller@5.1.0-preview-e5cef32c6
@metamask-previews/perps-controller@6.0.1-preview-e5cef32c6
@metamask-previews/phishing-controller@17.1.2-preview-e5cef32c6
@metamask-previews/polling-controller@16.0.5-preview-e5cef32c6
@metamask-previews/preferences-controller@23.1.0-preview-e5cef32c6
@metamask-previews/profile-metrics-controller@3.1.4-preview-e5cef32c6
@metamask-previews/profile-sync-controller@28.1.0-preview-e5cef32c6
@metamask-previews/ramps-controller@13.3.1-preview-e5cef32c6
@metamask-previews/rate-limit-controller@7.0.1-preview-e5cef32c6
@metamask-previews/react-data-query@0.2.1-preview-e5cef32c6
@metamask-previews/remote-feature-flag-controller@4.2.1-preview-e5cef32c6
@metamask-previews/sample-controllers@5.0.1-preview-e5cef32c6
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-e5cef32c6
@metamask-previews/selected-network-controller@26.1.3-preview-e5cef32c6
@metamask-previews/shield-controller@5.1.2-preview-e5cef32c6
@metamask-previews/signature-controller@39.2.2-preview-e5cef32c6
@metamask-previews/snap-account-service@0.1.0-preview-e5cef32c6
@metamask-previews/social-controllers@2.2.1-preview-e5cef32c6
@metamask-previews/storage-service@1.0.1-preview-e5cef32c6
@metamask-previews/subscription-controller@6.1.3-preview-e5cef32c6
@metamask-previews/transaction-controller@65.4.0-preview-e5cef32c6
@metamask-previews/transaction-pay-controller@22.4.0-preview-e5cef32c6
@metamask-previews/user-operation-controller@41.2.2-preview-e5cef32c6
@metamask-previews/wallet@0.0.0-preview-e5cef32c6

Copy link
Copy Markdown
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Did another pass on this, mainly with the goal of simplifying code. I know I have added some things we didn't talk about before but it seems it would be better to get this first PR as right as possible. It's much easier to add things later than remove them. Curious to know your thoughts.

Comment thread .github/workflows/messenger-docs.yml Outdated
@@ -0,0 +1,60 @@
name: Messenger API Docs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about calling this "Deploy Platform API Docs" and calling this file deploy-platform-api-docs.yml? Just want to make sure we stick with this terminology as much as we can.

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.

Renamed in 89832b1. The file is now .github/workflows/deploy-platform-api-docs.yml and the workflow's display name is "Deploy Platform API Docs". The job names and step labels inside it also got updated from "Messenger API docs" → "Platform API docs" in 40ad9c3 (the package rename).

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IIRC this action deploys to the root of the gh-pages branch and doesn't let you choose a subdirectory.

If we ever want to publish package API docs as opposed to platform API docs, it might be better if we put these somewhere specific.

What are your thoughts on using the peaceiris/actions-gh-pages action that we use in other places and deploying the site to a /platform-api subdirectory?

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 34c820f.

  • Swapped actions/deploy-pages for peaceiris/actions-gh-pages@v4.1.0 with destination_dir: platform-api and keep_files: true — the deploy now publishes to gh-pages/platform-api/ and won't clobber any sibling subdirectories (e.g. a future /package-api/).
  • Updated DOCS_BASE_URL to /<repo>/platform-api/ so the built Docusaurus site has the right <base href> for serving from a subdirectory.
  • Replaced actions/upload-pages-artifact with a regular upload-artifact + download-artifact handoff between the build and deploy jobs.
  • Permissions: pages: write + id-token: writecontents: write (peaceiris pushes the build commit directly to gh-pages).
  • Dropped the environment: github-pages block since we're no longer using the Pages deployment environment.
  • Also bumped pinned action versions to match the freshest in this repo (MetaMask/action-checkout-and-setup@v3, actions/upload-artifact@v6, actions/download-artifact@v7).

One thing to flag for when this merges: the repo's Pages settings need to be flipped from "GitHub Actions" back to "Deploy from a branch" (gh-pages branch), since we're no longer using the Pages Actions pipeline.

* @param dir - The directory to search.
* @returns A promise that resolves to an array of absolute file paths.
*/
export async function findTsFiles(dir: string): Promise<string[]> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was 82b3e45 applied? I'm not seeing use of glob here.

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 catch — that commit got reverted when messenger-docs was split out of messenger-cli, and I hadn't re-applied it. Re-applied in 9d2fbf7: findTsFiles and findDtsFiles are now thin wrappers around glob. One small addition — I explicitly sort the results so file processing order is deterministic across filesystems, since downstream dedup and output ordering depend on it.

if (typeArgs.length >= 3) {
actionsArg = typeArgs[1];
eventsArg = typeArgs[2];
} else if (typeArgs.length === 2) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like we are also handling *Messenger<Actions, Events> types. Are there examples of this that you've found? All messenger types within core, snaps, or accounts should have three type arguments. Was this designed to handle messenger types prior to the introduction of @metamask/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.

You're right — no real-world examples in core, snaps, or accounts. The 2-arg branch was leftover from a pre-@metamask/messenger shape and unused in practice. Dropped it in 36158b5 so the walker only accepts the 3-arg Messenger<Namespace, Actions, Events> form.

if (visited.has(name)) {
return;
}
visited.add(name);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like walkTypeReferences mutates its input. Since walkTypeReferences is designed to be called recursively, what are your thoughts on returning the output, making walkTypeReferences a pure function?

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.

Agreed — refactored in 36158b5. The walker is now collectNonUnionTypeNames, returns its result instead of mutating a passed-in Set, and keeps the recursion inside via a local closure so the recursive call sites don't have to pass a shared accumulator around.

* @param context - Shared extraction context.
* @returns The extracted item, or null if the shape doesn't match.
*/
function extractFromInlineShape(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: I'm not sure I've heard the term "inline shape" before. I can guess what it means, but you don't usually find these two words together (it's a bit like saying "red number"). Maybe this could be called extractFromInlineMessengerCapabilityType?

Suggested change
function extractFromInlineShape(
function extractFromInlineMessengerCapabilityType(

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.

Applied your suggestion in 89832b1 — function renamed to extractFromInlineMessengerCapabilityType, and the JSDoc updated to drop "inline shape" in favor of "inline messenger-capability-type" throughout.

* @param context - Shared extraction context.
* @returns The extracted item, or null if the helper doesn't match.
*/
function extractFromGenericHelper(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think we would call ControllerGetStateAction or ControllerStateChangeEvent "helpers". But I know what this is trying to say. We don't have a good name for these. Maybe "type constructors"?

Suggested change
function extractFromGenericHelper(
function extractFromCapabilityTypeConstructor(

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.

Applied your suggestion in 89832b1 — function renamed to extractFromCapabilityTypeConstructor, variable helperNameconstructorName, expectedHelperexpectedConstructor, and the JSDoc now calls them "capability-type constructors" with a parenthetical noting that "type constructor" is the closest term we've got for these.


const raw = jsDocs[0].getText().trim();

// Handle single-line JSDoc: /** Gets the current state. */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I feel like there ought to be a way we can do this more simply.

I asked Claude and it looks like the jsDocs object here also has a getDescription method, which returns the part above all of the tags. So we shouldn't need to parse the raw JSDoc text. We still need to manually get the @deprecate tag and append to the string we're building here but we can do that through another method, getTags. (It looks like we already use this method in getDeprecated.)

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 66c8d81. extractJsDocText now uses jsDoc.getDescription() for the body and jsDoc.getTags() to find every @deprecated tag (rendered as **Deprecated:** <comment> lines). All other tags are dropped — their information is already in the rendered handler/payload signature. The hand-rolled line-by-line parser is gone (~100 lines).

One existing test (handles skipped tag continuation lines) was asserting a quirk of the old parser — that blank-line-separated text after @param tags was reappearing in the description. ts-morph follows standard JSDoc semantics and treats that as continuation of the last tag, so I rewrote the test to assert the more useful property: the description survives and the @param lines don't.

* @param repoBaseUrl - Optional GitHub blob base URL (e.g. "https://github.com/Owner/Repo/blob/sha/").
* @returns The generated markdown string.
*/
export function generateItemMarkdown(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we have to convert the "capability data blob" we've extracted to Markdown? Can we feed Docusaurus JSON instead and then use that to render the page for the capability? I feel like distilling that data into Markdown at this stage discards information that would be useful at the rendering stage and doesn't allow us to control formatting as much as we could. If we can work out a way to use JSON there may be more things in extraction.ts that we can remove (such as the MDX stuff at the bottom of extractJsDocText).

const depText = text.slice('@deprecated'.length).trim();
text = depText ? `**Deprecated:** ${depText}` : '';
} else if (text.startsWith('@')) {
// Strip other tags (@param, @returns, @see, @throws, etc.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm. Why are we stripping @param and @returns? These are the things that describe the action handler or event payload. Right now we seem to be showing a raw representation of the handler or payload type (e.g. () => import("/Users/elliot/code/metamask/core/packages/app-metadata-controller/src/AppMetadataController").AppMetadataControllerState) and I think if we were to show the documented arguments and return type that would be much more useful.

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 point — fixed in 671e21a.

@param and @returns are now extracted as structured data instead of being stripped: ExtractedMessengerCapabilityType gets params: { name, description }[] and returns: string fields. The markdown renderer emits a **Parameters**: name/description table and a **Returns**: line above the existing signature block (now labeled **Handler signature**: so the layered sections read naturally). Backtick-reference linkification flows through param descriptions and the returns line.

When an action's handler resolves to a class method via Class['method'] and the type alias itself has no JSDoc, the action inherits the method's @param / @returns automatically (with the type alias winning if both are present). Events don't get a parameters table — they carry positional payload tuples, not named arguments.

One thing worth flagging: the rich @param JSDoc for most actions in core lives in the auto-generated *-method-action-types.ts files, which our walker treats as imported leaves rather than descending into them. So while the H1 plumbing is complete, the live site won't show parameter tables for most ApprovalController/etc. actions until the cross-file resolution piece (extraction.ts:101) lands. That's the bigger refactor mcmire and I had been discussing as a follow-up.

Copy link
Copy Markdown
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Noticed a few more things.

Comment thread packages/messenger-docs/src/cli.ts Outdated
);
const pkg = JSON.parse(pkgRaw) as Record<string, unknown>;
const config =
(pkg['messenger-docs'] as MessengerDocsConfig | undefined) ?? {};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need to keep this? Can we rely on command-line arguments for configuration for now?

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.

Dropped in c7cde64. The package.json#messenger-docs config block is gone. --scan-dir is now actually additive (appends to the default ['src'], deduplicated, preserving order) and the project label moved to a --project-label flag. CLI-only now — readProjectPackageJson and resolveProjectLabel helpers are gone too.

Comment thread packages/messenger-docs/src/cli.ts Outdated
}

/**
* Derive a human-readable project label from a `package.json` name. Handles
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe this can be a command-line option so that we don't need to derive this?

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 c7cde64. There's now a --project-label flag; if omitted, no label is stamped (the title just becomes Platform API). The derivation logic (deriveProjectLabel) is gone. The root docs:platform-api:{build,dev,serve} scripts pass --project-label Core explicitly.

Comment thread packages/messenger-docs/jest.config.js Outdated
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 75,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible to bring these numbers up to 100%?

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.

Got us to 100% lines and 100% on discovery.ts / markdown.ts in a6585b0. Statements landed at 99.59% and branches at 93.45%. The remaining gap is in defensive guards that protect against AST shapes the TypeScript compiler doesn't produce in real messenger-shaped source files (qualified-name type references, computed method names, non-property-signature members in capability-type literals, etc.) — those are marked with // istanbul ignore comments and short explanatory notes so future readers know they're intentional rather than overlooked.

Along the way I added a bunch of real fixtures for previously-untested paths: .json imports, missing import targets, destructured constants, externally-declared action references, non-Messenger types sharing the *Messenger suffix, capability-type constructors with mismatched or insufficient args, kind-mismatch dedup, broken-symlink failure paths, events-only namespaces, alphabetical namespace ordering, regenerating into an existing output directory, and the git symbolic-ref shallow-clone fallback.

Per review feedback, swap a few generic names for terms that better
describe the concept:

- `MessengerItemDoc` → `ExtractedMessengerCapabilityType`. "Item" was
  generic; we extract documentation about a messenger capability — an
  action or event type.
- `extractItem` → `extractFromMessengerCapabilityType`, matching the
  `extractFromFile` naming pattern.
- `extractFromInlineShape` → `extractFromInlineMessengerCapabilityType`.
  "Inline shape" was unfamiliar phrasing.
- `extractFromGenericHelper` → `extractFromCapabilityTypeConstructor`.
  We don't have a settled term for `ControllerGetStateAction` /
  `ControllerStateChangeEvent` but "type constructor" is closer than
  "generic helper".
- `collectMessengerReferences` → `collectMessengerCapabilityTypeNames`.
  "References" suggested call sites; the function returns type names.
- Returned fields `actions` / `events` → `actionTypeNames` /
  `eventTypeNames` to make it obvious they are names, not whole types.
- Workflow: `messenger-docs.yml` → `deploy-platform-api-docs.yml`,
  workflow display name → "Deploy Platform API Docs", aligning with
  the broader "Platform API" terminology used elsewhere.
Three structural cleanups in extraction.ts:

- The walker (formerly `walkTypeReferences`) is now `collectNonUnionTypeNames`
  and is pure: it returns its result instead of mutating a caller-passed
  `Set`. The recursion is kept inside via a local closure.
- The JSDoc for the walker now spells out the worked example from the
  review thread — given `AccountsControllerActions | AllowedActions`,
  which names land in the result set and which are deliberately skipped.
- Drop the 2-arg `Messenger<Actions, Events>` branch. Every messenger
  type in core, snaps, and accounts uses the 3-arg form
  `Messenger<Namespace, Actions, Events>`; the 2-arg branch was leftover
  from a pre-`@metamask/messenger` shape and unused in practice.
Previously `collectMessengerCapabilityTypeNames` returned two sets of
*names*, and `extractFromFile` then re-walked every top-level statement
in the source file to find the declarations matching those names. That's
two passes over the same AST, and the second pass was effectively a
name-to-declaration lookup that the first pass already had in hand.

Replace it with `collectMessengerCapabilityTypeDeclarations`, which
resolves each leaf type-name to its local `TypeAliasDeclaration` or
`InterfaceDeclaration` as it walks, tagging each with its kind. Skipping
the second walk shrinks `extractFromFile`'s main loop down to a single
iteration over the returned declarations.
Per review feedback, simplify configuration so it lives only on the
command line. There were three sources of truth — derivation from
`package.json#name`, a `messenger-docs.title` override, and the
`messenger-docs.scanDirs` config — for no clear win.

- Drop `messenger-docs.title` and `deriveProjectLabel`. Add a
  `--project-label` flag instead; if absent, no label is stamped.
- Drop `messenger-docs.scanDirs`. Source directories are now the default
  `src/` plus anything supplied via `--scan-dir` (deduplicated).
- Drop the package.json-reading helper.
- Update the README to describe the CLI-only surface area.
- Wire the root `docs:messenger:*` scripts to pass `--project-label Core`.
`extractJsDocText` previously stripped comment delimiters, asterisks,
and tag continuation lines by hand — a state-machine line-by-line
parser. ts-morph already does all of that:

- `jsDoc.getDescription()` returns the body above the first tag with
  delimiters and leading asterisks already removed,
- `jsDoc.getTags()` returns the tags as structured nodes, each with a
  `getCommentText()` for the trailing comment.

Replace the manual parser with calls to those APIs:

- Use the description verbatim.
- For every `@deprecated` tag, append a `**Deprecated:** <comment>`
  line (with the comment's newlines collapsed to spaces).
- Drop all other tags (`@param`, `@returns`, `@see`, …) — their
  information is already present in the rendered handler/payload
  signature.
- Run the result through one `escapeJsDocTextForMdx` helper that
  resolves `{@link}` and escapes stray curly braces.

One existing test (`handles skipped tag continuation lines`) asserted
a quirk of the hand-rolled parser — that a blank-line-separated chunk
of text *after* `@param` tags reappeared in the description. Standard
JSDoc semantics (which ts-morph follows) treat that as continuation of
the last tag, so the test is rewritten to verify the more useful
property: the description survives, the `@param` lines are gone.

Branch threshold dropped temporarily by ~2 points; will be restored in
the coverage commit.
Reviewer asked whether the package can hit 100% coverage. Most of the
remaining uncovered code was either reachable-but-untested or genuinely
defensive:

- **Reachable but missing tests.** Added focused fixtures and tests:
  - `.json` imports skipped without resolution attempts
  - relative imports whose candidate paths don't exist
  - destructured `const` declarations
  - non-Messenger types that share the `*Messenger` name suffix
  - Messenger types with fewer than three type arguments
  - union members that are not type references
  - capability-type-constructor aliases with unknown names
  - capability-type-constructor aliases with insufficient args
  - externally-declared (imported) action references
  - shared capabilities referenced by two messengers
  - capability types where `type` is declared after `handler`
  - dedup paths that exercise replace-same-kind, replace-different-kind,
    and skip-lower-score branches
  - git origin/HEAD missing (the shallow-clone fallback)
  - per-file failures bubbling up as warnings
  - sidebars/index variants for events-only namespaces, deprecation
    markers, plural rendering, and the no-repoBaseUrl default
- **Defensive guards.** Cases that protect against AST shapes the
  TypeScript compiler doesn't actually produce in messenger-shaped
  source files (qualified-name type references, computed method names,
  non-property-signature members in capability type literals, etc.) are
  marked with `// istanbul ignore` comments and explanatory notes.
- **Restructured the template-literal-type span loop.** The previous
  three-way `TypeQuery / LiteralType / else` branch chain had two arms
  that no real-world messenger types exercise. The loop is now a single
  pass over `${typeof X}` substitutions with `// istanbul ignore`
  comments on the bail-out paths, which is what the messenger types we
  extract from actually use.

Coverage thresholds raised to the new baseline: 99% statements, 100%
lines, 93% branches, 96% functions.
Re-applies an earlier change that was lost during the messenger-docs
package split. `findTsFiles` and `findDtsFiles` are now thin wrappers
around `glob`, which replaces the hand-rolled recursive readdir walks.

`glob` doesn't guarantee result order, so the matches are explicitly
sorted before being returned. Downstream consumers (extraction,
dedup, output ordering) depend on a stable file processing order, so
this keeps generated output deterministic across filesystems.
Comment thread packages/platform-api-docs/src/markdown.ts
The package was originally named for where it lived in the codebase
(alongside `messenger-action-types`), but its actual product is the
Platform API documentation site: the catalog of actions and events
available through the message bus. The site title, the workflow
("Deploy Platform API Docs"), and the README copy all already use
"Platform API"; the package and CLI name were the last lingering bits
of the old framing.

Renames in this commit:

- Directory: `packages/messenger-docs/` → `packages/platform-api-docs/`.
- npm name: `@metamask/messenger-docs` → `@metamask/platform-api-docs`.
- Binary: `messenger-docs` → `platform-api-docs` (now explicitly named
  in `bin` rather than implicitly derived from the package name).
- Root scripts: `docs:messenger:{build,dev,serve}` → `docs:platform-api:*`.
- Output directory: `.messenger-docs/` → `.platform-api-docs/`.
- Generated `sidebars.ts` header comment and the synthetic Docusaurus
  site's `package.json#name` updated to match.
- CODEOWNERS, teams.json, tsconfig.{json,build.json}, eslint.config.mjs,
  yarn.config.cjs, .gitignore, and the workflow file all updated to
  reference the new path/name.

The package is still at 0.0.0 with no consumers, so there's no
migration path needed.
The `node_modules/` branch in `generateItemMarkdown` was producing a
nonsensical link when the path wasn't `@metamask/`-scoped: the fallback
used the entire source path as the package name, yielding URLs like
`https://www.npmjs.com/package/node_modules/some-vendor/dist/index.d.ts`.

In practice the scanner only walks `node_modules/@metamask/*/dist`, so
the fallback never fired against real input. The only thing exercising
it was a unit test I added in the coverage-bump commit — so the test
was effectively codifying broken output to inflate coverage.

Restructure to: render an npm link only when the path is actually
`@metamask`-scoped, otherwise fall through to the normal source-link
branches (GitHub blob URL if a repo base URL is available, plain path
otherwise). The two unit tests now assert the correct behavior:

- a plain `**Source**: \`<path>:<line>\`` when no repo URL is given
- a GitHub blob URL when one is

Reported by Cursor Bugbot on PR #8012.
@cryptodev-2s cryptodev-2s changed the title feat: add @metamask/messenger-docs package feat: add @metamask/platform-api-docs package May 15, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

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.

There are 2 total unresolved issues (including 1 from previous review).

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 1b1b547. Configure here.

Comment thread packages/platform-api-docs/src/extraction.ts Outdated
`actions/deploy-pages` deploys to the root of the gh-pages site, which
means a single repo can only publish one doc site through it. If we
ever want to add package API docs (or any other doc surface)
alongside, the platform-api site needs to live in its own
subdirectory.

Switch the deploy mechanism to `peaceiris/actions-gh-pages` and:

- Publish to `gh-pages/platform-api/` via `destination_dir: platform-api`.
- Set `keep_files: true` so sibling subdirectories (e.g. a future
  `/package-api/`) aren't clobbered on each platform-api deploy.
- Update `DOCS_BASE_URL` to `/<repo>/platform-api/` so the built
  Docusaurus site has the right `<base href>`.
- Replace the `actions/upload-pages-artifact` step with a regular
  `actions/upload-artifact` + `actions/download-artifact` pair, since
  we no longer use the Pages-specific artifact pipeline.
- Swap the `pages: write` / `id-token: write` permissions for the
  deploy job to `contents: write` (peaceiris pushes the build commit
  directly to `gh-pages`).
- Drop the `environment: github-pages` block; with peaceiris, the
  deploy isn't gated on a Pages deployment environment.
- Bump pinned action versions to match the freshest in this repo:
  `MetaMask/action-checkout-and-setup@v3`,
  `actions/upload-artifact@v6`, `actions/download-artifact@v7`,
  `peaceiris/actions-gh-pages@v4.1.0`.

Note: when this lands, the repo's GitHub Pages settings need to be
flipped from "GitHub Actions" back to "Deploy from a branch" (gh-pages)
since we're no longer using the Pages Actions pipeline.
`resolveHandler` was matching only the single-quoted form
`ClassName['method']`. TypeScript accepts three syntactically distinct
forms for indexed-access types — `Class['m']`, `Class["m"]`, and
`` Class[`m`] `` — and ts-morph's `getText()` returns whatever the
source used verbatim. When a controller author chose double quotes or
template literals, we'd fail to resolve the handler and fall back to
rendering the raw text instead of the method signature plus its JSDoc.

Updated the regex to a backreferenced quote character class
(`/^(\w+)\[(['"`])(\w+)\2\]$/u`) and shifted the method-name capture
group from `match[2]` to `match[3]` to compensate. Added two tests
covering the double-quoted and template-literal forms.

Bump the action versions in the deploy workflow to the absolute latest
pair (`upload-artifact@v7` / `download-artifact@v8`), since these are
paired by major version and v8 of `download-artifact` flips
hash-mismatch handling from warning to error (a strictly-better
default for an artifact-driven deploy).

Reported by Cursor Bugbot on PR #8012.
The site was rendering action handlers as raw TypeScript types — fine
when the types are clean, but ugly when ts-morph emits a fully-qualified
`import("/abs/path/...").TypeName`. The information engineers actually
want — what each handler argument means and what it returns — was
being thrown away (the `@param` / `@returns` tags were stripped by the
JSDoc parser before reaching the renderer).

Keep those tags as structured data and render them alongside the
handler signature:

- Add `params: { name, description }[]` and `returns: string` fields to
  `ExtractedMessengerCapabilityType` (and `MethodInfo` for inheritance).
- Replace `extractJsDocText` with `extractJsDoc`, which decomposes the
  comment into `{ description, params, returns }` — the description
  body still flows through MDX-escaping and `{@link}` resolution, but
  `@param` and `@returns` tags are pulled out into separate fields.
- Strip the conventional leading `- ` separator from `@param` comments
  (JSDoc style is `@param name - description`; the hyphen is purely
  decorative).
- When an action's handler resolves to a class method, inherit the
  method's `@param`/`@returns` if the type alias doesn't have its own.
  Type-alias-level docs win when both are present.
- In `markdown.ts`, render `**Parameters**:` as a name/description
  table and a `**Returns**:` line, both with backtick-reference
  linkification. The existing signature block is renamed to
  `**Handler signature**:` / `**Payload signature**:` so the new sections
  read naturally.

Events don't get a parameters table — they carry positional payload
tuples, not named arguments.

Coverage held at 100% lines / 94% branches with new fixtures for the
structured-fields path, multi-line params, and class-method inheritance
(including the type-alias-overrides-method ordering rule).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants