Skip to content

fix: track local Studio sharing CTA interactions - #7566

Merged
terencecho merged 4 commits into
mainfrom
codex/share-cta-analytics
Nov 11, 2026
Merged

terencecho merged 4 commits into
mainfrom
codex/share-cta-analytics

Conversation

@terencecho

@terencecho terencecho commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Count local Studio share-modal upgrade clicks, audience selections, editable-source toggles, navigation to sharing settings/the shared page, and action intent. Upgrade clicks distinguish the project limit from sharing permissions. Events use the existing guarded bridge and telemetry policy; only bounded categories and booleans reach analytics, never share URLs, project paths or invitee addresses.

Where upgrade clicks come from

  • share_upgrade_clicked { client_surface: local_studio, reason, cta: share_modal_upgrade }. reason is project_limit or sharing_permissions; cta names the button.
  • The modal's Upgrade to Pro link opens /pricing?entry=local_studio_share, so the pricing page can tell which link a visit came from; nothing else about that page or what follows checkout changes for these buyers. hyperframes share's source-files notice links /pricing?from=cli&entry=cli_share: like the CLI's other upgrade links, from=cli shows the CLI's plan wording and, after checkout, "You're on Pro. Go back to your terminal." instead of the web landing page. Both pricing hosts keep the query through their redirect (hyperframes.dev/pricing?entry=… → hyperframes.studio/pricing?entry=…, 200).
  • The modal still opens the link only on hyperframes.dev and dev.hyperframes.dev at /pricing; any query is allowed, and a look-alike host is refused (new test).

Validation

After the link-tagging commit: 51 local Studio share tests and 108 CLI share tests passed; CLI and Studio typecheck clean; oxlint and oxfmt clean on changed files.

46 focused CLI/bridge/telemetry tests and 49 local Studio tests passed. CLI and Studio typechecks passed. Full workspace build passed before the final event-parser simplification; lint, formatting and complexity hooks passed on the final code. Hosted CI is pending. No live telemetry events were sent and no purchase flow was exercised. Clicks are intent, not successful permission changes or purchases.

fails without the fix:

  • packages/studio/src/components/share/QuickShare.test.tsx › "keeps the plan link's entry so the pricing page can count where the visit came from" fails on main: the modal only accepted the exact URL https://hyperframes.dev/pricing, so a link with a query hid Upgrade to Pro.
  • packages/cli/src/server/sharePresentation.test.ts › "preserves authoritative plan free for the upgrade offer" fails on main: the free plan's upgradeUrl is https://hyperframes.dev/pricing with no entry.
  • packages/cli/src/share/telemetry.test.ts › "forwards only bounded CTA fields with the local Studio surface" fails on main: share_upgrade_clicked doesn't exist there.

Before

The local Studio Share window on main's link, for a Free workspace with 3 of 5 links used, dark theme. The line under the window is the Upgrade to Pro link's address, read from the rendered link.

before-upgrade-link

After

Same window from this branch's build with the link this branch sends. The window looks the same; the Upgrade to Pro link now opens /pricing?entry=local_studio_share.

after-upgrade-link-entry-only

🤖 Generated with Claude Code

@mintlify

mintlify Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Nov 11, 2026, 8:57 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 267 (base branch 267), smooth 92 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (8)

Unstable (3)

  • seqrotatenudge-none-pct-r0-root-z100: tracking 0.03, pressJump 0, drop 0, reload 3.03, render 0.04, renderKey -, undo false, teleport true / tracking 0.03, pressJump 0, drop 0, reload 0, render 0.08, renderKey -, undo true, teleport true / tracking 0.03, pressJump 0, drop 0, reload 0, render 0.08, renderKey -, undo true, teleport true
  • seqplainkeys-none-px-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true
  • seqplainkeys-none-pct-r0-nested-z100: tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport true / tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport true / tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport true

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

Verdict: REQUEST CHANGES · 3 blockers · 0 important · 0 nits · head f7e5560

  • blocker (required check): Studio and player captures is red: "After asset … is byte-identical to Before asset". The diff touches .tsx under packages/studio, so ## No visible change isn't available. Re-capture the After from this head's build.
  • blocker: Comments is red. The ratchet raised the comment share in 3 files (↓ inline). Cut the lines or move the meaning into names.
  • blocker (body): this is a fix: PR with no fails without the fix: line. Name the new test(s) by describe › it title that fail on main, e.g. shareEvents.test.ts › "accepts a bounded sharing interaction: share_upgrade_clicked".
Scope

Read all 14 files. The bridge and validation path checks out: Studio → /api/share/events (CSRF + shareEventInput exact two keys, allowlisted values) → trackShareInteraction. browserTelemetryAllowed gates the client. shareSite() produces only hyperframes.dev / dev.hyperframes.dev, which matches PRICING_ORIGINS. I checked that hyperframes.dev/pricing?entry=… and dev. keep entry through the redirect (200). CI Typecheck/Lint/Test passed. Producer integration and the timeline gate were still running when I reviewed.

— Genesis

Comment thread packages/cli/src/share/telemetry.ts Resolved
…e from

The local Studio share modal's Upgrade to Pro link opens
/pricing?from=cli&entry=local_studio_share, and hyperframes share's source-files
notice links /pricing?from=cli&entry=cli_share, so the pricing page can tell
which link a visit came from and return the visitor to their terminal. The
modal accepts its own pricing page with any query, still only on
hyperframes.dev's two origins. share_upgrade_clicked carries
cta=share_modal_upgrade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omments

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

Verdict: APPROVE — 3 resolved, 0 open, 1 new (important) · f7e5560 → a7ec797

CI is green, including captures and Comments.

— Genesis

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed at a7ec797ecc905ffc010a88e314b22540528855fc.

No blocker found. New events pass through the existing browser opt-out and guarded local bridge, which accepts only declared enum/boolean fields. CLI emission refreshes persisted opt-out before sending. Source-upload consent and share mutation behavior are unchanged. Pricing links keep their categorical entry tags.

Nit: packages/cli/src/server/sharePresentation.ts:60: as the existing review notes, from=cli on the local Studio link selects terminal-oriented pricing and post-purchase instructions. Prefer keeping entry=local_studio_share and dropping from=cli for this browser surface; keep the marker on the actual CLI link. This does not prevent completing checkout.

Validation: full bun run build passed; 57 CLI/bridge/policy tests and 51 Studio tests passed through pytest-gate.sh, including disabled telemetry and bounded event input. No live analytics delivery or purchase was exercised.

Need: yes, measure sharing intent · Size: ok · Reuse: existing telemetry policy, bridge and event transport · Simpler: already small enum additions · Structure: fine (checked shareEventInput, emit and browserTelemetryAllowed; no split)
Risk: low — categorical events retain existing opt-out controls.

Verdict: APPROVE
Reasoning: The added interactions stay within the existing telemetry policy and do not alter sharing permissions or source consent.

— Rames

Only entry=local_studio_share is added to the local Studio share window's
Upgrade to Pro link. from=cli would have told these buyers to go back to their
terminal after checkout, but they return to a browser tab. hyperframes share's
link keeps from=cli, as the CLI's other upgrade links do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed at 6ae945a1c0c3bef36a95f35abca8e3119d947d9b.

Read the complete four-file delta from approved a7ec797e. My pricing-link nit is resolved: local Studio now keeps entry=local_studio_share without selecting the terminal audience. The actual CLI link retains from=cli&entry=cli_share. The existing exact-origin/path pricing-link check accepts the entry-only URL, and both tests and docs match it. Telemetry and opt-out code are unchanged.

Source-only delta review; the prior build and 108 focused passing tests were at a7ec797e, not this head. No live purchase or new test run.

Need: yes, preserve browser purchase flow · Size: ok · Reuse: existing pricing URL check · Simpler: remove one query marker · Structure: fine (checked planOffer and isPricingPage; no split)
Risk: low — localized link correction.

Verdict: APPROVE
Reasoning: The new URL preserves attribution while keeping local Studio buyers on the browser-oriented flow.

— Rames

@terencecho
terencecho enabled auto-merge November 11, 2026 21:05
@terencecho
terencecho added this pull request to the merge queue Nov 11, 2026
Merged via the queue into main with commit 2a70733 Nov 11, 2026
132 of 133 checks passed
@terencecho
terencecho deleted the codex/share-cta-analytics branch November 11, 2026 21:33
@terencecho terencecho mentioned this pull request Nov 11, 2026
3 of 4 tasks

This branch was successfully deployed

1 active deployment
staging - docs — 6ae945a1 Deployed Nov 11, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants