Skip to content

[pull] main from tldraw:main#436

Merged
pull[bot] merged 5 commits intocode:mainfrom
tldraw:main
Mar 9, 2026
Merged

[pull] main from tldraw:main#436
pull[bot] merged 5 commits intocode:mainfrom
tldraw:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Mar 9, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

max-drake and others added 5 commits March 9, 2026 15:32
)

In order to simplify widget domain configuration and make local
development reliable, this PR replaces the per-host `MCP_DOMAIN_OPENAI`
/ `MCP_DOMAIN_CLAUDE` environment variables with a single `MCP_IS_DEV`
flag and a `getWidgetDomain()` function that resolves the correct domain
per host.

Reimplemented from
[`max/mcp-app-approvals-fixes`](https://github.com/tldraw/tldraw/tree/max/mcp-app-approvals-fixes)
with a clean commit history.

### Change type

- [x] `improvement`

### Test plan

1. Run `yarn dev` in `apps/mcp-app` — verify local worker starts with
`MCP_IS_DEV=true` and no `ui.domain` is set on the canvas resource
2. Run `yarn dev:tunnel` — verify tunnel mode also passes
`MCP_IS_DEV=true`
3. Deploy to production — verify `MCP_IS_DEV=false` (default in
wrangler.toml) causes `getWidgetDomain()` to return the correct domain
for ChatGPT and Claude hosts
4. Hit `/.well-known/openai-apps-challenge` — verify it returns the
verification string

### Release notes

- Replace per-host domain env vars with `MCP_IS_DEV` flag for simpler
widget domain configuration
- Add `/.well-known/openai-apps-challenge` endpoint for OpenAI domain
verification
- Add `enabled` flag to Logger to suppress logs in production

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how `ui.domain` is computed for ChatGPT/Claude and introduces
a new unauthenticated verification route, which could affect production
widget rendering or deployment validation if misconfigured.
> 
> **Overview**
> **Widget domain handling is refactored** to drop
`MCP_DOMAIN_OPENAI`/`MCP_DOMAIN_CLAUDE` and instead use `MCP_IS_DEV` + a
new `getWidgetDomain()` to set `_meta.ui.domain` only in production
(ChatGPT uses `https://tldraw.com`; Claude hashes the deployed `/mcp`
URL from `WORKER_ORIGIN`).
> 
> **Dev/prod behavior is now explicit**: local `wrangler dev` and tunnel
scripts pass `MCP_IS_DEV:true`, while `wrangler.toml` defaults
`MCP_IS_DEV="false"`; docs are updated accordingly. The worker also adds
`/.well-known/openai-apps-challenge` (no auth) and gates structured
logging behind a new `Logger(enabled)` flag (enabled only in dev).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
50deff3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Closes #7055. When exporting arrows without text labels via
`getSvgElement()`, the `<foreignObject>` element receives negative
width/height values (e.g. `-8.5`), causing browser console errors.

The root cause is in `ArrowShapeUtil.toSvg()`: it unconditionally
renders a `RichTextSVG` for the arrow label and applies
`.expandBy(-ARROW_LABEL_PADDING * scale)` to shrink the bounds by
padding. For empty labels, `getArrowLabelPosition()` returns a
zero-sized box, so subtracting `4.25 * 2 = 8.5` produces negative
dimensions.

The fix skips rendering `RichTextSVG` entirely when the label is empty,
matching the existing guard in the canvas rendering path.

### Change type

- [x] `bugfix`

### Test plan

1. Create an arrow with no text label
2. Export as SVG (File > Export as SVG)
3. Check the browser console — no more `<foreignObject> attribute width:
A negative value is not valid` errors
4. Create an arrow with a text label and export — label renders
correctly

### Release notes

- Fix arrow SVG export producing invalid negative `<foreignObject>`
dimensions when arrows have no text label

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: a small conditional render change limited to SVG export
output, with no impact on arrow geometry or editing behavior beyond
avoiding invalid `<foreignObject>` dimensions.
> 
> **Overview**
> Fixes arrow SVG export emitting invalid `<foreignObject>` sizes when
an arrow has no text label.
> 
> `ArrowShapeUtil.toSvg()` now conditionally renders `RichTextSVG` only
when `richText` is non-empty, avoiding negative label bounds after
padding is applied.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58fb598. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR updates the i18n strings.

### Change type
- [x] `other`

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> String-only changes to French locale JSON files; low risk aside from
potential minor wording/consistency issues in the UI.
> 
> **Overview**
> Updates French i18n strings in `apps/dotcom` locale files and
`assets/translations/fr.json`, including revised wording for pinning a
file, flip actions, and several shape/tool labels.
> 
> Adds/adjusts a few menu/action translations (e.g. invert mouse zoom,
quick zoom) and normalizes some formatting (e.g. opacity percentages
spacing).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e6dbe63. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
Co-authored-by: Mime Čuvalo <mimecuvalo@gmail.com>
Bring the url of the domain anthropic will be hosting its widget on in
line with the
[docs](https://claude.com/docs/connectors/building/mcp-apps/cross-compatibility#domain-handling)

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, isolated change to Claude widget domain computation; main risk
is miscomputing the domain and breaking widget loading in Claude.
> 
> **Overview**
> Fixes Claude widget domain generation to match Anthropic’s docs by
truncating the SHA-256 hex digest to the first 32 characters before
appending `.claudemcpcontent.com`.
> 
> Also updates the inline documentation/example command in
`getWidgetDomain` and slightly refactors the hash string construction
for readability.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9638410. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
In order to simplify the MCP app and remove frontend analytics tracking,
this PR removes the `event` MCP tool and the `trackWidgetEvent` callback
that was used to report widget events (e.g. "build_it_clicked") to
Cloudflare Analytics.

### Change type

- [x] `other`

### Test plan

1. Run the MCP app and verify the share panel "Build it" button still
works
2. Confirm no errors in the console related to the event tool

- [ ] Unit tests
- [ ] End to end tests

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: removes a best-effort analytics-only tool and its caller
without affecting core canvas/checkpoint functionality. Main risk is any
external dependency on the `event` tool name in clients.
> 
> **Overview**
> Removes the app-only MCP tool `event` (and its Cloudflare Analytics
datapoint writes) from `register-tools.ts`.
> 
> Simplifies the widget share panel by deleting `trackWidgetEvent` and
no longer emitting the `build_it_clicked` event when the **Build it**
button is pressed; button behavior otherwise remains unchanged.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b8b0dcf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Mar 9, 2026
@pull pull Bot added the ⤵️ pull label Mar 9, 2026
@pull pull Bot merged commit 899ecb5 into code:main Mar 9, 2026
@pull pull Bot had a problem deploying to bemo-canary March 9, 2026 21:13 Failure
@pull pull Bot had a problem deploying to deploy-production March 9, 2026 21:13 Failure
@pull pull Bot had a problem deploying to vsce publish March 9, 2026 21:13 Failure
@pull pull Bot had a problem deploying to deploy-staging March 9, 2026 21:13 Failure
@pull pull Bot had a problem deploying to bemo-canary March 9, 2026 21:13 Failure
@pull pull Bot had a problem deploying to deploy-staging March 9, 2026 21:13 Error
@pull pull Bot had a problem deploying to deploy-staging March 10, 2026 00:27 Failure
@pull pull Bot temporarily deployed to e2e-dotcom March 10, 2026 02:35 Inactive
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants