Conversation
…nload (#8200) In order to ensure tldr downloads always reflect the latest state, this PR changes `onDownloadTldr` to read directly from the durable object's SQLite storage instead of fetching from R2. The R2 copy can lag behind when a persist hasn't been triggered yet, whereas the SQLite storage is the authoritative source of truth. Since the snapshot is fully loaded into memory either way (the R2 path parsed via `.json()`), there's no streaming advantage lost. ### Change type - [x] `bugfix` ### Test plan 1. Open a tldraw file and make some edits 2. Immediately download the file as .tldr 3. Verify the downloaded file contains the latest edits ### Release notes - Fixed tldr file downloads to always include the latest changes by reading from the authoritative storage instead of the R2 cache. ### Code changes | Section | LOC change | | --------------- | ---------- | | Apps | +3 / -6 | Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk, small change isolated to the download path that only alters the snapshot source from R2 to in-memory SQLite state. Main risk is unexpected behavior if SQLite storage isn’t initialized or `getSnapshot()` differs from the persisted R2 format. > > **Overview** > `.tldr` downloads (`onDownloadTldr`) now build the exported records from the Durable Object’s live SQLite-backed storage (`getStorage()` + `SQLiteSyncStorage.getSnapshot()`) instead of fetching/parsing the room snapshot from R2. > > This prevents downloads from lagging behind recent edits when persistence to R2 hasn’t run yet, while keeping the rest of the export flow (asset pruning and asset inlining) the same. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 681bb75. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…8038) In order to show users a helpful error page instead of a blank white screen when Clerk is down or rate-limited (429), this PR adds error boundaries and a loading timeout to the Clerk authentication flow. When Clerk is unavailable, `auth.isLoaded` stays `false` indefinitely and tldraw.com renders a blank white page. This PR catches that case with a 10-second timeout and also wraps the Clerk provider tree in error boundaries. ### Change type - [x] `bugfix` ### Test plan 1. Start `yarn dev-app` 2. Block Clerk's script loading (e.g. via DevTools network blocking for `clerk.tldraw.com`) 3. Reload the page 4. After ~10 seconds, the error page appears with "Unable to connect" and a "Refresh" button 5. Unblock Clerk and click "Refresh" — app loads normally ### Release notes - Show an error page instead of a blank screen when the authentication service is unavailable ### Code changes | Section | LOC change | | --------------- | ----------- | | Apps | +116 / -31 | | Automated files | +27 / -0 |
#8199) In order to fix ChatGPT copy-paste issues and improve the MCP app's host-detection reliability, this PR refactors hostname resolution, replaces the debug module with an integrated dev log panel, and adds mobile platform handling. Reimplemented from [`max/fix-mcp-app-chatgpt-copy-paste`](https://github.com/tldraw/tldraw/tree/max/fix-mcp-app-chatgpt-copy-paste) with a clean commit history. ### Change type - [x] `improvement` ### Test plan 1. Run `yarn dev` in `apps/mcp-app` and connect from Cursor/Claude Desktop — verify the canvas loads and tools work 2. Connect from ChatGPT via `yarn dev:tunnel` — verify host detection resolves to `chatgpt` 3. Verify the dev log panel appears when `MCP_IS_DEV=true` and can be toggled via the toolbar button 4. Verify fullscreen toggle works in desktop clients and is disabled on mobile platforms - [ ] Unit tests - [ ] End to end tests ### Release notes - Improve MCP app host detection for ChatGPT clients - Add integrated dev log panel visible in dev mode - Resolve host name client-side for more reliable detection - Disable fullscreen on mobile platforms - Clean up verbose server-side logging - Update README with separate Claude Desktop local/remote setup instructions <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes how host identity is resolved, what bootstrap data is injected into the widget, and how fullscreen/display-mode is handled (including new mobile restrictions), which can impact client compatibility (ChatGPT/Claude/Cursor/VS Code). No auth or data-storage model changes beyond logging/bootstrapping. > > **Overview** > Improves MCP host detection by splitting hostname resolution into server-side (`resolveMcpAppHostNameFromServerInfo`) vs client-side (`resolveMcpAppHostNameFromClientInfo`) parsing and broadening ChatGPT detection; the widget now resolves host name from `app.getHostVersion()` instead of relying on server-injected `hostName`. > > Replaces the old ad-hoc widget `debug.ts` logging with an integrated **dev log panel** gated by a new `isDev` bootstrap flag (injected by the canvas resource) and a toolbar toggle. > > Adjusts UI behavior for mobile hosts by disabling fullscreen capability and forcing an exit from fullscreen if the host platform becomes `mobile`, and removes verbose server-side `console.error` checkpoint/debug logging. Adds an MIT `LICENSE.md`, updates the `README` setup instructions, and enables `preview_urls` in `wrangler.toml`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 450b792. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…8202) In order to prevent visual overflow (thick strokes, arrowheads, etc.) from being clipped in exports while avoiding unnecessary whitespace, this PR introduces an `'auto'` padding mode that renders with default padding then trims to actual visual content bounds. Clean reimplementation of [`fix/export-visual-overflow`](https://github.com/tldraw/tldraw/tree/fix/export-visual-overflow). ### Change type - [x] `improvement` ### Test plan 1. Export shapes with visual overflow (thick borders, arrowheads extending beyond bounds) 2. Verify the export captures the full visual content without clipping 3. Verify no extra whitespace around the content 4. Test with explicit numeric padding — should behave as before (fixed padding, no trimming) 5. Test frame exports — should still use frame bounds without padding - [x] Unit tests - [x] End to end tests ### API changes - Changed `TLSvgExportOptions.padding` from `number` to `number | 'auto'` - `'auto'` (default): renders with default padding, trims to visual content - `number`: fixed padding, no trimming (previous behavior with explicit padding) - Added `getSvgAsImageWithOptions` (internal) — returns `{ blob, width, height }` instead of bare `Blob` - Added `trimSvgToContent` (internal) — trims SVG viewBox to visual content bounds ### Release notes - Exports now automatically trim to visual content bounds, capturing overflow (strokes, arrowheads) without extra whitespace - The `padding` export option now accepts `'auto'` to enable this behavior (default) ### Code changes | Section | LOC change | | --------------- | ----------- | | Core code | +354 / -30 | | Tests | +103 / -101 | | Automated files | +3 / -1 (+ 44 binary snapshots) | | Apps | +3 / -3 | | Config/tooling | +1 / -0 | <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes core export rendering and introduces a new `'auto'` padding mode in the public `TLSvgExportOptions` API; incorrect trimming/cropping could affect all exported PNG/JPEG/WebP/SVG outputs. > > **Overview** > Exports now support a new **`padding: 'auto'` mode** (and make it the default behavior when `padding` isn’t a number) that renders with default padding to capture visual overflow, then trims back to the actual visual content bounds to avoid extra whitespace. > > This threads a new `trimPadding` value through `getSvgJsx` → `exportToSvg` → `Editor.getSvgElement/getSvgString` and updates `Editor.toImage` to trim both raster exports (via a new internal `getSvgAsImageWithOptions` canvas pipeline) and SVG exports (via a new internal `trimSvgToContent` that adjusts the SVG viewBox/dimensions). App export UI defaults were adjusted and the export calls now pass `'auto'` when padding is toggled off; related unit tests were updated to match the new bounds return shape and padding-applied signaling. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 880d9ec. 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: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )