Skip to content

feat(analytics-controller): add optional event fragments for journey-scoped properties - #10055

Merged
gauthierpetetin merged 12 commits into
mainfrom
feat/analytics-controller-event-fragments
Sep 3, 2026
Merged

gauthierpetetin merged 12 commits into
mainfrom
feat/analytics-controller-event-fragments

Conversation

@gauthierpetetin

@gauthierpetetin gauthierpetetin commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Explanation

Clients currently re-derive the same analytics properties for every event in a signature or transaction confirmation. That duplication is easy to get wrong and hard to keep consistent as more UI pieces contribute to the same journey.

This adds optional event fragments to AnalyticsController, disabled by default via isEventFragmentsEnabled. A fragment is a persisted bag of properties and sensitiveProperties that any part of a client can write to while a journey is in progress:

  • Funnel. Declare initialEvent, successEvent, and failureEvent. Creation can emit the initial event, and finalizeEventFragment emits success or failure.
  • Property bag. Declare no event names. The client reads the fragment back with getEventFragmentById when it emits its own event.

Emission goes through trackEvent, so consent gating, anonymous event splitting, the pre-consent queue, and geolocation enrichment all apply. Accumulation uses that same consent gate: fragments are only stored while the user is opted in, or while they are undecided and the pre-consent queue is enabled. eventFragments is persisted but excluded from state logs, debug snapshots, and UI, matching the other analytics queues.

This is not a breaking change. Clients must opt in with the constructor flag.

Here's a draft PR on Extension repo where this code can be tested: MetaMask/metamask-extension#45961

References

Contributes to: https://github.com/MetaMask/MetaMask-planning/issues/7582

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

Made with Cursor

…scoped properties

Clients currently re-derive the same analytics properties for every event in a
signature or transaction flow. Fragments let those properties accumulate once,
with consent, persistence, and emission going through the existing trackEvent path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gauthierpetetin
gauthierpetetin requested review from a team as code owners September 1, 2026 17:56
@cursor

cursor Bot commented Sep 1, 2026

Copy link
Copy Markdown

Current version of PR was reviewed by /review-bugbot on Sep 1, 19:46 GMT+2. It flagged 0 findings.

Bugbot on commit 9b468c3 is skipped.

Copilot AI left a comment

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.

Pull request overview

Adds an optional “event fragments” feature to @metamask/analytics-controller, allowing clients (when opted-in via isEventFragmentsEnabled) to persist and update journey-scoped analytics property bags and optionally emit initial/success/failure events through the existing trackEvent pipeline and consent gating.

Changes:

  • Introduces AnalyticsEventFragment* types and exports them from the package public API.
  • Extends AnalyticsController state, metadata, messenger methods, and implementation to support fragment lifecycle (create/upsert/update/get/delete/finalize) with consent-aware reconciliation on init.
  • Adds selectors + comprehensive tests, and documents the feature in the README/changelog.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/analytics-controller/src/selectors.ts Adds selectors for reading all fragments and a fragment by ID.
packages/analytics-controller/src/selectors.test.ts Adds unit tests for the new selectors.
packages/analytics-controller/src/index.ts Exposes event fragment types and new controller method action types from the public entrypoint.
packages/analytics-controller/src/EventFragment.types.ts Defines the event fragment data model and option/payload types.
packages/analytics-controller/src/AnalyticsController.ts Implements fragment storage, reconciliation on init, consent gating integration, and lifecycle methods.
packages/analytics-controller/src/AnalyticsController.test.ts Adds extensive tests covering fragment behavior, consent gating, persistence, and messenger exposure.
packages/analytics-controller/src/AnalyticsController-method-action-types.ts Adds messenger action type definitions for fragment lifecycle methods.
packages/analytics-controller/README.md Documents the new feature and its usage patterns.
packages/analytics-controller/CHANGELOG.md Adds an Unreleased entry describing the new feature.
Suppressed comments (3)

packages/analytics-controller/src/AnalyticsController.ts:541

  • mergeEventFragmentContext returns { ...base, ...override }, but base/override are AnalyticsContext | undefined. Coalesce to {} before spreading to avoid TypeScript errors and make the intent explicit.
  return { ...base, ...override };

packages/analytics-controller/src/AnalyticsController-method-action-types.ts:101

  • The getEventFragmentById action-type JSDoc omits the consent gate, but the handler returns undefined when capture is not allowed (opted out, or undecided without pre-consent queue). Align the docs with the implementation to avoid consumer confusion.
 * @returns The fragment, or `undefined` when no fragment has that ID or the
 * event fragments feature is disabled.
 */

packages/analytics-controller/src/AnalyticsController.ts:1629

  • finalizeEventFragment is a logged no-op when the feature is disabled or consent gating disallows capture, so the @throws doc should note that a missing fragment will not throw in those ignored-call states.
   * @throws Error if no fragment has that ID.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/analytics-controller/src/selectors.ts Outdated
Comment thread packages/analytics-controller/CHANGELOG.md Outdated
Comment thread packages/analytics-controller/src/AnalyticsController-method-action-types.ts Outdated
Comment thread packages/analytics-controller/src/AnalyticsController.ts
Comment thread packages/analytics-controller/src/AnalyticsController.ts Outdated
Comment thread packages/analytics-controller/src/AnalyticsController.ts Outdated
…ngelog to PR

Regenerate AnalyticsController method action types after JSDoc updates and
add the PR link required by the changelog CI check.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/analytics-controller/src/AnalyticsController.ts
gauthierpetetin and others added 5 commits September 1, 2026 20:21
Keep a single event fragments bullet with the PR link and remove nested
detail bullets from the Unreleased section.

Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent accidental mutation of the shared empty record returned by
selectEventFragments when state has no fragments yet.

Co-authored-by: Cursor <cursoragent@cursor.com>
…preading

Default omitted properties, sensitiveProperties, and context to empty
objects so fragment merge and create paths stay type-safe.

Co-authored-by: Cursor <cursoragent@cursor.com>
Document that updateEventFragment and finalizeEventFragment only throw for
a missing fragment when the call is not ignored by consent or feature flags.

Co-authored-by: Cursor <cursoragent@cursor.com>
Snapshot fragment IDs before awaited init work so reconciliation drops only
stale non-persistent leftovers, not in-flight journeys started while init runs.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit 1b12a93. Configure here.

Comment thread packages/analytics-controller/src/AnalyticsController.ts
gauthierpetetin and others added 2 commits September 2, 2026 06:27
Snapshot fragment createdAt at init start so purge can distinguish stale
leftovers from fragments replaced via createEventFragment while init runs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Apply Prettier formatting for lint:misc:check and add tests covering
fragment context preservation and AnalyticsPlatformAdapterSetupError.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gauthierpetetin

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

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

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

@NicolasMassart NicolasMassart left a comment

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.

suggestions for some changes on fragments

Comment thread packages/analytics-controller/src/AnalyticsController.ts
Comment thread packages/analytics-controller/src/AnalyticsController.ts Outdated
gauthierpetetin and others added 3 commits September 2, 2026 12:34
Drop persisted fragments whose lastUpdated is older than 24 hours on
init so abandoned journeys cannot keep properties in storage indefinitely.

Co-authored-by: Cursor <cursoragent@cursor.com>
Expose ReadonlyAnalyticsEventFragment from create and get so callers
cannot mutate controller state without going through update or upsert.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gauthierpetetin
gauthierpetetin added this pull request to the merge queue Sep 3, 2026
Merged via the queue into main with commit 7f59ebc Sep 3, 2026
196 checks passed
@gauthierpetetin
gauthierpetetin deleted the feat/analytics-controller-event-fragments branch September 3, 2026 14:02
@gauthierpetetin gauthierpetetin mentioned this pull request Sep 3, 2026
3 of 4 tasks
adonesky1 pushed a commit to wzrdk3lly/core that referenced this pull request Sep 3, 2026
## Explanation

**Summary**

Publish `@metamask/analytics-controller@2.1.0` so clients can opt into
journey-scoped event fragments from
[MetaMask#10055](MetaMask#10055).

**Problem**

Clients that track multi-step user journeys (signature requests,
transaction confirmations, and similar flows) must re-derive the same
analytics properties at every step, or build ad hoc state to carry them
forward. There is no shared controller primitive for accumulating
properties across a journey and optionally closing it with a success or
failure event.

**Solution**

- `@metamask/analytics-controller@2.1.0` (minor): add optional event
fragments, disabled by default via `isEventFragmentsEnabled`
- Funnel shape: declare `initialEvent`, `successEvent`, and/or
`failureEvent`, then call `finalizeEventFragment`
- Property-bag shape: declare no event names and read accumulated
properties back with `getEventFragmentById` when emitting a custom event
- Fragment methods respect the same consent gate as `trackEvent`, return
read-only copies from `createEventFragment` / `getEventFragmentById`,
and discard stale non-persistent or expired persisted fragments on
`init`

Workspace dependents bump their `@metamask/analytics-controller` range
to `^2.1.0` but are not published in this release:

- `@metamask/network-controller`
- `@metamask/wallet-cli`

**Risk**

No breaking API changes. Event fragments are disabled by default, so
existing consumers keep current behavior until they opt in with
`isEventFragmentsEnabled`.

### `@metamask/analytics-controller@2.1.0`

#### Added

- Add optional event fragments to `AnalyticsController` (disabled by
default via `isEventFragmentsEnabled`), letting clients accumulate
analytics properties across a user journey and optionally emit an
initial, success, or failure event for it
([MetaMask#10055](MetaMask#10055))

#### Changed

- Bump `@metamask/utils` from `^11.11.0` to `^11.12.0`
([MetaMask#10076](MetaMask#10076))

## References

- Related to MetaMask#10055

## Checklist

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

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
pull Bot pushed a commit to Reality2byte/metamask-extension that referenced this pull request Sep 7, 2026
…etaMask#45961)

## **Description**

### Context

Event fragments currently live on the Extension-only
`MetaMetricsController`. Shared analytics work is moving into
`@metamask/analytics-controller`, which now supports optional event
fragments behind `isEventFragmentsEnabled`.

This PR migrates the two real fragment consumers onto that shared API:

1. Signature funnel (`create` / `update` / `finalize`)
2. Transaction UI metrics property bag (`upsert` / `get`)

Requires `@metamask/analytics-controller@^2.1.0` (released from
MetaMask/core#10055).

### Problem

Keeping fragment state and lifecycle in `MetaMetricsController` blocks
deprecation of that controller and duplicates journey-scoped analytics
logic that should be platform-agnostic.

### Solution

- Enable `isEventFragmentsEnabled` in `AnalyticsControllerInit`
- Add Extension analytics facade helpers that flatten Extension-specific
fields into core fragment `properties` / `context`
- Repoint signature tracking middleware and transaction UI metrics to
`AnalyticsController` fragment actions
- Remove fragment state, methods, alarm, and UI selectors/hooks from
`MetaMetricsController`
- Add migration `225` to drop persisted
`MetaMetricsController.fragments`
- Consume published `@metamask/analytics-controller@^2.1.0`

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

<!--
Depends on: MetaMask/core#10055
-->

## **Manual testing steps**

1. Run `yarn start` and load `dist/chrome` as an unpacked extension. Opt
into MetaMetrics.
2. Run `yarn dapp`. Trigger `personal_sign`, then approve. Confirm
`Signature Requested` then `Signature Approved`, and that
`AnalyticsController.eventFragments` contains `signature-<id>` while
open and removes it after approve.
3. Trigger another signature and reject it. Confirm `Signature Rejected`
and that the fragment is removed.
4. Start a Send confirmation. While it is open, confirm
`AnalyticsController.eventFragments['transaction-ui-<transactionId>']`
exists as a property bag with no `initialEvent` / `successEvent` /
`failureEvent`.
5. Submit or reject the Send. Confirm transaction metrics still include
UI properties, and that no `"Transaction Fragment Created"` event is
emitted.
6. Toggle MetaMetrics off and retry a signature. Confirm tracking stops
and there are no background fragment API errors.

<!--
## **Screenshots/Recordings**
### **Before**
### **After**
-->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches signature and transaction analytics funnels and drops
persisted fragment state on upgrade, so metric continuity or edge-case
journey tracking could regress despite broad test updates.
> 
> **Overview**
> Moves **event fragment** lifecycle out of `MetaMetricsController` into
**`AnalyticsController`** (`@metamask/analytics-controller@^2.1.0`,
`isEventFragmentsEnabled: true`). Extension code now goes through new
**`analytics` facade** helpers (`createEventFragment`,
`updateEventFragment`, `upsertEventFragment`, `getEventFragmentById`,
`finalizeEventFragment`) that flatten MetaMetrics-specific fields into
the shared controller shape.
> 
> **Signature** RPC tracking and **transaction UI metrics** property
bags are repointed to these APIs (including `upsert` for
`transaction-ui-*` fragments without dummy success events).
`MetaMetricsController` drops `fragments` state, fragment messenger
actions, startup abandoned-fragment handling, and the finalize alarm.
> 
> **Migration 225** removes persisted `MetaMetricsController.fragments`
(not migrated—journeys cannot resume after restart). UI loses
Redux-backed fragments: **`useEventFragment`**, fragment selectors, and
background **`createEventFragment` / `finalizeEventFragment`** RPC
actions; confirmations still call **`updateEventFragment`** via the
analytics path.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3a32312. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

3 participants