Skip to content

[pull] main from tldraw:main#435

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

[pull] main from tldraw:main#435
pull[bot] merged 3 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 : )

ds300 and others added 3 commits March 9, 2026 09:41
…om viewport (#8171)

When the tooltip singleton's trigger element has an ancestor with a CSS
`transform` (e.g. `transform3d`), `position: fixed` positions relative
to that ancestor's containing block rather than the viewport. Since
`getBoundingClientRect()` always returns viewport-relative coordinates,
directly using those values as `left`/`top` produces incorrect
positioning.

This PR fixes the issue by first placing the trigger at `(0, 0)`,
reading back the containing block's offset via
`getBoundingClientRect()`, and then subtracting that offset to compute
the correct CSS position.

### Change type

- [x] `bugfix`

### Test plan

1. Embed tldraw inside a container that uses `transform:
translate3d(...)` or similar CSS transform
2. Hover over toolbar buttons and other tooltip-bearing elements
3. Verify tooltips appear correctly positioned next to their target
elements

### Release notes

- Fixed tooltip positioning when tldraw is rendered inside a container
with CSS transforms.

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change that adjusts how tooltip trigger `left`/`top`
are computed; main risk is minor regressions in edge-case
layout/positioning.
> 
> **Overview**
> Fixes incorrect tooltip placement when `tldraw` is rendered inside a
transformed/offset containing block by adjusting the singleton trigger’s
`position: fixed` coordinates.
> 
> The trigger is now temporarily placed at `(0,0)`, its containing-block
offset is read via `getBoundingClientRect()`, and that offset is
subtracted from the target element’s viewport rect to compute the
correct `left`/`top`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d384470. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ovements (#8168)

In order to improve MCP client identity tracking and fix several widget
UX issues, this PR refactors the MCP app with a clean commit history.

Clean reimplementation of
[`max/mcp-fixes`](https://github.com/tldraw/tldraw/tree/max/mcp-fixes).

**Key changes:**

- **Rename `cloudflare-worker.ts` → `worker.ts`** for clarity
- **Fix build scripts** so dev:stdio, dev:tunnel, and deploy always
build the widget first
- **Centralize server metadata** — use shared constants (name, version,
title, etc.) across server and widget; bump version to 0.1.0; extract
`injectBootstrapData()` helper
- **Add client host name resolution** — resolve connecting client
identity (cursor, vscode, claude, chatgpt) from MCP client version
string; thread through bootstrap data; use for domain resolution instead
of raw client strings; persist in worker SQLite
- **Extract image guard and app context** into separate modules; rename
context to `McpAppContext`
- **Improve widget UI** — show "Build it" only in code editors; reorder
share panel buttons; use download icon; simplify state; use typed host
context; query host capabilities for fullscreen/download
- **Add explicit tool annotations** — `readOnlyHint`/`destructiveHint`
on all tools so MCP clients can make better auto-approval decisions
- **Add README** with architecture overview, setup instructions, and dev
workflow

### Change type

- [x] `improvement`

### Test plan

1. Connect via Cursor — verify "Build it" button appears, download and
fullscreen buttons work
2. Connect via Claude Desktop — verify "Build it" is hidden, download
and fullscreen work
3. Connect via ChatGPT — verify resource domain resolves correctly
4. Run `yarn dev:stdio` — verify widget builds before server starts

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes MCP server metadata/bootstrap
injection and client-based domain resolution across both Node and Worker
entry points, which could affect connectivity or resource loading in
different hosts.
> 
> **Overview**
> **Client/host identity is now normalized and propagated end-to-end.**
The server/worker resolve a canonical host name
(`cursor`/`vscode`/`claude`/`chatgpt`) from the MCP client string,
persist it in the Durable Object, and embed it into the widget bootstrap
so the UI and HTTP `domain` selection use the same identity.
> 
> **Server/tool registration is tightened and standardized.** Server
metadata is centralized via shared constants (including a version bump
to `0.1.0`), bootstrap HTML injection is extracted to a helper, and all
tools now include explicit `readOnlyHint`/`destructiveHint` annotations
(plus annotations for the app-only `event` tool).
> 
> **Widget UX and host integration are refined.** Host context handling
is typed/safer, fullscreen/download buttons are gated by host
capabilities, the Share panel is reordered with an icon download button,
and the "Build it" action is shown only for code-editor hosts;
image/asset/embed inputs are proactively blocked via extracted
`image-guard` overrides.
> 
> **Dev/deploy ergonomics and docs.** `dev:stdio`, `dev:http`,
`dev:tunnel`, and `deploy` now always build the widget first, the
Cloudflare entry point is set to `src/worker.ts`, and a new `README.md`
documents architecture and setup.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5d15524. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…#8130)

Closes #8125


https://github.com/user-attachments/assets/cf96fc2a-c7f2-4448-8ccf-42e0eaa5ba2b

Arrow endpoints flicker when `normalizedAnchor` coordinates are exactly
0 or 1 (shape edges/corners). At these exact values, the intersection
math becomes numerically unstable — small floating-point errors cause
intersections to toggle between found and not-found across frames.

**Solution:** if arrow is precise or forceImprecise, clamp each anchor
coordinate from [0, 1] to [0.001, 0.999]. This clamping happens inside
`getArrowTerminalInArrowSpace`, which runs every time the arrow info is
recomputed (i.e. whenever the arrow or its bound shapes change). The
binding record in the store is never modified — the nudge only exists
ephemerally during computation, so the intersection math never sees an
exact boundary value.

### Change type

- [x] `bugfix`

### Test plan

1. Create a shape and programmatically bind a self-referential arrow
with anchors at exact boundary positions (e.g. `{x: 0, y: 0}`, `{x: 0.5,
y: 0}`)
2. Verify arrows render without flickering
3. Resize and move the shape — arrows should remain stable

- [x] Unit tests

### Release notes

- Fix arrow endpoint flickering when anchors are at exact shape
boundaries

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches core arrow terminal computation; clamping precise anchors near
0/1 can subtly shift endpoints (up to ~0.1% of shape size) and may
affect arrow rendering/attachment in edge cases.
> 
> **Overview**
> Prevents arrow endpoint flicker when a bound terminal’s
`normalizedAnchor` lands exactly on a shape edge/corner by clamping
precise anchors away from `0`/`1` during `getArrowTerminalInArrowSpace`
computations.
> 
> Adds a small epsilon-based `clampNormalizedAnchor` helper and
refactors the terminal point calculation to use the clamped anchor
without mutating stored binding data.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f4ecde2. 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 had a problem deploying to bemo-canary March 9, 2026 15:13 Failure
@pull pull Bot merged commit 6846df5 into code:main Mar 9, 2026
3 of 7 checks passed
@pull pull Bot had a problem deploying to deploy-production March 9, 2026 15:13 Failure
@pull pull Bot had a problem deploying to deploy-staging March 9, 2026 15:13 Failure
@pull pull Bot had a problem deploying to vsce publish March 9, 2026 15:13 Failure
@pull pull Bot had a problem deploying to deploy-staging March 9, 2026 15:13 Error
@pull pull Bot had a problem deploying to bemo-canary March 9, 2026 15:13 Failure
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.

3 participants