forked from tldraw/tldraw
-
Notifications
You must be signed in to change notification settings - Fork 1
init rivet support #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
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
This PR updates the i18n strings.
### Change type
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds new i18n key `95d2109dc8` ("Build with tldraw SDK") across all
locales and compiled locale files.
>
> - **Internationalization**:
> - Add new translation key `95d2109dc8` for "Build with tldraw SDK" in
`apps/dotcom/client/public/tla/locales/*` and compiled
`locales-compiled/*` across all supported languages.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bc1373b. 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>
@steveruizok oh i see - yeah this is a regression from last week's change tldraw#6924 this app will just hotfix by itself when i land this PR ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Spread user properties in PostHog `identify` call instead of nesting them under `properties`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 76ea674. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
We have disparate origin checks that are varying in domains, and we want to tighten up asset-upload as well. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Moves origin checks into shared utilities and applies unified CORS/origin middleware across workers, updating the request post-processing hook signature. > > - **Shared (worker-shared)**: > - **Origins utilities**: Add `isAllowedOrigin` and `blockUnknownOrigins` in `packages/worker-shared/src/origins.ts` and export from `index.ts`. > - **Request handling**: Change `handleApiRequest` `after` hook signature to `(response, request)` to support CORS helpers that need the request. > - **Workers**: > - **asset-upload-worker**: Switch CORS `origin` to `isAllowedOrigin`; add `blockUnknownOrigins` middleware; update to `corsify` via new hook signature. > - **sync-worker**: Replace local origin logic with shared `blockUnknownOrigins`/`isAllowedOrigin`; pass `request` to `corsify`; remove duplicated origin helpers. > - **image-resize-worker**: Reuse shared `isAllowedOrigin` for `isValidOrigin`; tidy imports. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 60477d1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds `https://analytics.google.com` to CSP `connect-src` allowlist. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8e97fc5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Summary - Reorganized `packages/worker-shared/package.json` to correctly classify development and build-time dependencies - Moved `@cloudflare/workers-types`, `typescript`, and `lazyrepo` to `devDependencies` ## Rationale These dependencies are only needed during development and build time, not at runtime. This change: - Clarifies the actual runtime dependencies of the package - Follows best practices for dependency classification - May reduce bundle size in environments that distinguish between production and development dependencies ## Changes **Moved to devDependencies:** - `@cloudflare/workers-types` - TypeScript type definitions - `typescript` - Build-time compiler - `lazyrepo` - Build system tool **Remaining in dependencies:** - `@tldraw/utils` - `@tldraw/validate` - `cloudflare-workers-unfurl` - `itty-router` - `toucan-js` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Reclassifies build-only packages from dependencies to devDependencies in packages/worker-shared/package.json. > > - **package.json (worker-shared)**: > - **Dependency classification**: > - Moved `@cloudflare/workers-types`, `typescript`, and `lazyrepo` to `devDependencies`. > - Kept runtime deps: `@tldraw/utils`, `@tldraw/validate`, `cloudflare-workers-unfurl`, `itty-router`, `toucan-js`. > - **Dev tooling**: > - Ensured `vitest` remains in `devDependencies`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit cf8887d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude <noreply@anthropic.com>
Add 15-minute timeout to dotcom hotfix script to prevent action timeouts. Now throws an error (sent to Discord) if PR checks don't complete in time, leaving 5 minutes buffer before the 20-minute GitHub Action timeout. ### Change type - [x] `improvement` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a 15-minute timeout to the dotcom hotfix script while waiting for PR checks, throwing an error if not ready in time. > > - **Scripts**: > - `internal/scripts/trigger-dotcom-hotfix.ts` > - Add 15-minute maximum wait with elapsed-time tracking when polling PR `mergeable_state`. > - On timeout, log and throw an error with PR link. > - Retains initial 5-minute delay and 15s polling cadence. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c3dfe88. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…#6964) This is a PR to improve our analytics banner. As part of the onboarding project, I had to get my head into the analytics work and figured I'd do a detail pass while I was here. As noted in greater detail by the bots below, the biggest change is **removing react** dependencies and just making the banner with DOM APIs. The reason for this is that we were shipping react / react-dom as part of the analytics script bundle, which seemed like a waste for two components. I also moved a lot of the **services** (like posthog, hubspot, etc) into their own files and into a common interface. If we want to add or remove services in the future, or if we want to adjust the functionality we're using for any of the services, then we can do that easily. We also add a new **analytics worker** that checks whether we need to show the cookie banner for a user, or whether we can opt them into analytics automatically. We're not using any ad trackers or selling people's medical data or any other sneaky stuff, so we're fine with providing an opt-out to users in California etc. The worker itself is very simple and uses cf-headers to identify the location of the IP request. Finally, I aligned the **design** of the components. The privacy preferences in particular needed some love, so love it got. We now use dark mode banners on light mode and light mode banners on dark mode for increased contrast. The next step of forced engagement would be immediate centered cookie wall, which tbh might be better than a sneaky thing crawling up the screen later. We'll iterate. None of the behavior should have changed materially, though a few things here and there will have been tightened up. I'd done a lot of work while still working in React (ie, using an external store for the consent) and confirmed things are doing what they should be. Reminder that this banner is currently only used on tldraw computer and tldraw.dev. We'll need to do similar work on tldraw.com (or perhaps migrate to using this analytics app instead). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replaces React-based analytics with a modular vanilla JS implementation and introduces a Cloudflare worker to determine consent by geo, updating build, tests, and CI/deploy. > > - **Analytics app (vanilla, modular architecture)**: > - Replace React/Radix implementation with DOM-based components and a unified `Analytics` class (`apps/analytics/src/index.ts`, `components/`, `state/`, `types.ts`). > - Add modular services with a common interface: `PostHog`, `GA4`, `HubSpot`, `Reo` (`src/analytics-services/*`). > - Introduce cookie consent and theme state managers (`src/state/*`), consent banner and privacy dialog (`src/components/*`). > - Geo-based consent check utility calling worker (`src/utils/consent-check.ts`). > - Update styles to new tokens and compact UI (`src/styles.css`). > - Remove React build setup; adjust Vite/TS/Vitest configs and deps (`vite.config.ts`, `tsconfig.json`, `vitest.config.ts`, `package.json`). > - Add preview `index.html` and expose global API (`window.tlanalytics`). > - **Cloudflare analytics worker** (`apps/analytics-worker`): > - New worker to determine if explicit consent is required via `CF-IPCountry` with CORS and caching (`src/worker.ts`, `wrangler.toml`). > - Package, TS/Vitest configs, and docs (`CONTEXT.md`). > - **CI/Deploy**: > - New workflow to deploy analytics worker (`.github/workflows/deploy-analytics.yml`). > - Deployment script for worker and preview env handling (`internal/scripts/deploy-analytics.ts`, update `internal/scripts/lib/deploy.ts`). > - **Misc**: > - Add ignore rules for analytics public assets (`.prettierignore`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e4db4db. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Enhanced the ExternalLink component to support an optional eventName
prop for analytics tracking. Updated the TlaSidebarDotDevLink to track
clicks and dismissals using the trackEvent utility.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Add optional analytics tracking to `ExternalLink` and wire up tracking
for sidebar dotdev link and feedback dialog links.
>
> - **Analytics**:
> - Enhance `ExternalLink`
(`apps/dotcom/client/src/tla/components/ExternalLink/ExternalLink.tsx`):
> - Accepts optional `eventName` prop; fires `trackEvent(eventName, {
link })` on click and preserves existing `onClick`.
> - Sidebar
(`apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarDotDevLink.tsx`):
> - Track link click via `eventName="sidebar-dotdev-link-clicked"`.
> - Track dismiss button via
`trackEvent('sidebar-dotdev-link-dismissed')`.
> - Feedback dialog
(`apps/dotcom/client/src/tla/components/dialogs/SubmitFeedbackDialog.tsx`):
> - Add `eventName` to Discord and GitHub `ExternalLink`s to track
clicks.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f91ccbd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Added an example that showcases how to create a bezier curve shape, useful for vector editing. ## Demo  ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` ### Release notes - Added a new bezier curve example <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a cubic bezier curve shape example with custom handles, snapping, editing/translation interactions, and undo/redo while editing. > > - **Examples**: > - Add cubic bezier curve example in `apps/examples/src/examples/cubic-bezier-shape/` with entry `README.md` and `CubicBezierShapeExample.tsx`. > - **Shape Util** (`CubicBezierShape.tsx`): > - Implement `bezier-curve` shape (`BezierCurveShapeUtil`) with `CubicBezier2d` geometry, SVG rendering, bounds/handle snapping, and resize behavior. > - Provide four handles (`start`, `end`, `cp1`, `cp2`), auto-collapse control points near endpoints, and meta-key gestures for handle drag behaviors and curve bending during translate. > - Show dashed control lines when selected during edit/drag/translate. > - **Editor State Overrides** (`CubicBezierShapeExample.tsx`): > - Customize select tool states to: collapse cp1/cp2 on meta-click, remain in editing after handle drag, and allow translating while in editing. > - Register the custom shape and mount an initial curve at viewport center. > - **UI/Handles** (`CustomHandles.tsx`): > - Custom `Handles` component to display handles for `bezier-curve` during edit/drag/translate and default behavior for other shapes. > - **Undo/Redo** (`SneakyUndoRedoWhileEditing.tsx`): > - Add keybinding hook to perform undo/redo while preserving editing state. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 16a4811. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com> Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR makes the analytics on tldraw.com use the new analytics worker
to check whether consent is required.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Switch consent checks to `consent.tldraw.xyz`, return explicit consent
status, auto-opt-in where allowed, and wire up routes/CSP/deploy for the
new domain.
>
> - **Consent infrastructure**:
> - **Cloudflare Worker**: Add production route with custom domain
`consent.tldraw.xyz` in `apps/analytics-worker/wrangler.toml`.
> - **Deploy**: For previews, set `customDomain` to
`${previewId}-consent.tldraw.xyz` in
`internal/scripts/deploy-analytics.ts`.
> - **Analytics library (`apps/analytics`)**:
> - Update `shouldRequireConsent` to return `'requires-consent' |
'no-consent-needed'` and fetch from `https://consent.tldraw.xyz`.
> - Initialize consent using the new result enum; adjust logic to set
`'unknown'` only when `'requires-consent'`.
> - Move `window.tlanalytics` setup earlier in `src/index.ts`.
> - **Dotcom UI**:
> - `TlaCookieConsent`: perform consent check on mount, delay banner
until resolved, auto opt-in when `'no-consent-needed'`, and hide banner
(via opacity) when manage dialog is open.
> - **Security**:
> - Add `https://consent.tldraw.xyz` to `connect-src` in
`apps/dotcom/client/src/utils/csp.ts`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
06edc47. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Mime Čuvalo <mimecuvalo@gmail.com>
### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds `https://tldraw.dev` to CORS allowlists and mocks the consent service in e2e tests for deterministic banner behavior. > > - **Workers/CORS**: > - Allow exact origin `https://tldraw.dev` in `apps/analytics-worker/src/worker.ts` and `packages/worker-shared/src/origins.ts`. > - **Tests**: > - In `apps/dotcom/client/e2e/tests/cookie-consent.spec.ts`, mock `https://consent.tldraw.xyz` to always return `{ requires_consent: true, country_code: 'TEST' }` to ensure the banner displays during tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b8b83c4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
@MitjaBezensek and I did some frontend work and testing on staging and found a couple of things that need to be fixed before we push the groups data model to production tomorrow. 1. We should throw an error if old User DOs try to connect to the new replicator (cloudflare will kill them and restart them with the new worker script very soon after this happens so it's no biggie to throw an error) 2. We needed to propagate the user's name to their home group name so that the shared file name triggers work correctly for files shared from a user's home group. 3. We improved a check for the groups_backend flag. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Reject legacy clients by erroring on guestFileIds in registerUser; add triggers to sync/initialize home group names from user names; update migration flag check to groups_backend. > > - **Backend (replicator)**: > - `TLPostgresReplicator.registerUser`: remove support for `guestFileIds` and throw if provided to block legacy clients. > - **Database (migrations)**: > - Add `update_home_group_name` trigger/function to sync a home group’s `name` when the corresponding `user.name` changes. > - Add `initialize_home_group_name` trigger/function to set a home group’s `name` from the corresponding `user.name` on insert. > - Update migration check to use `flags LIKE '%groups_backend%'` instead of `'%groups%'`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b333e97. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Invoke PostHog opt_in_capturing when consent is granted and opt_out_capturing when revoked within configurePosthog. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f9b7d1c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
we are seeing slowness when loading rooms in production, this should help us narrow down exactly which operation(s) is causing it. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds granular timing analytics around room load, auth, rate limiting, group checks, R2/Supabase I/O, and create-from-source to pinpoint slowness. > > - **Backend (sync-worker TLDrawDurableObject)** > - **Timing instrumentation**: Add `timer()` helper and emit metrics across key paths. > - `getAppFileRecord`: measure success/error durations. > - `onRequest`: measure auth, rate-limit checks, group membership query, `getRoom`, and total request time. > - `handleFileCreateFromSource`: measure await-persist, R2 fetch/put, and total fetch time. > - `loadFromDatabase`: measure R2 fetch, create-from-source, Supabase fetch, total time, and error path. > - **Minor**: avoid double JSON parsing in R2 load by reusing `snapshot` var. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bd09db0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This reverts commit 2e5f9f2. ### API changes - Revert the 120 fps changes. ### Change type - [x] `bugfix` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Standardizes throttling to 60fps (removing custom/120fps logic), updates TLSyncClient scheduling, simplifies FPS debug display, and adjusts the utils API. > > - **Utils**: > - Reverts `fpsThrottle` to fixed 60fps; removes custom FPS support and related state. > - Updates docs/comments and `throttleToNextFrame` to reference 60fps. > - API change: `fpsThrottle(fn)` no longer accepts `getTargetFps`. > - **Sync Core** (`packages/sync-core/src/lib/TLSyncClient.ts`): > - Removes dynamic sync FPS logic (`SOLO_MODE_FPS`, `COLLABORATIVE_MODE_FPS`, `getSyncFps`). > - `flushPendingPushRequests` and `scheduleRebase` now use `fpsThrottle()` without FPS getter. > - **UI** (`packages/tldraw/src/lib/ui/components/DefaultDebugPanel.tsx`): > - Simplifies FPS output to `FPS <current>` (removes max FPS display). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c9995c0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This should reduce the amount of traffic going through the replicator. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replaces per-event file_state updates with a single throttled updater that batches session, edit, and visit info every 10s, removing old handlers. > > - **Editor**: > - Add `FileStateUpdater` to coalesce `lastSessionState`, `lastEditAt`, and `lastVisitAt` updates, throttled to 10,000ms. > - Replace ad-hoc session-state listener and remove `SneakyFileUpdateHandler` usage. > - **App**: > - Remove `onFileEdit` and `onFileSessionStateUpdate` methods and related usage. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 98ed362. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
We changed some env variable, using this to trigger another deploy to staging. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > No code changes; this PR is a no-op to trigger a redeploy. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 60920d1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
adds `url` so that we can discover which sites are using tldraw ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds the current page URL to the watermark/evaluation tracking fetch in `LicenseManager.maybeTrack`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3343b8c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…raw#6998) - Bumps the client protocol version to 3. - Removes feature flag logic for `tldraw_groups_init` - Defaults all new users to the new groups initialization flow In a few days we'll bump the backend and make the clients update. ### Change type - [x] `improvement` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Bumps protocol to v3 and always use groups-based `init` for new users, removing the feature flag and legacy user insert path. > > - **Protocol**: > - Bump `Z_PROTOCOL_VERSION` and `MIN_Z_PROTOCOL_VERSION` to `3` in `packages/dotcom-shared/src/types.ts`. > - **App initialization** (`apps/dotcom/client/src/tla/app/TldrawApp.ts`): > - Remove `localStorage` feature flag `tldraw_groups_init` and legacy `user.insert` path. > - Always call `z.mutate.init({ user, time })` for new user creation. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 575dc07. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Updated openUrl and runtime.openWindow to accept an allowReferrer parameter, enabling control over whether the referrer is sent when opening external links. Refactored related components and hooks to support this option for improved flexibility and privacy handling. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [x] `api` - [ ] `other` ### API changes - Adds an optional parameter to `openWindow` and `runtime.openWindow` to allow referrers on links that open in new tabs. ### Release notes - Adds the option to include referrer on links that open in new tabs. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds an optional allowReferrer flag to window-opening utilities and updates editor/dotcom components to use it for selected external links. > > - **API / Core**: > - Extend `packages/editor` public API: `openWindow(url, target?, allowReferrer?)` and `runtime.openWindow(url, target, allowReferrer?)`. > - Add wrapper support in `window-open.ts` and update API report. > - **Editor components**: > - `Watermark`: pass `allowReferrer: true` for unlicensed CTA; keep default for licensed link. > - `RichTextLabel` and `Toolbar/LinkEditor`: replace direct `window.open` calls with `openWindow(...)` and wire `allowReferrer` as needed. > - **Dotcom client**: > - `utils/url.openUrl(url, allowReferrer?)` and `useOpenUrlAndTrack` accept/forward the flag. > - Update menu items (`Links.tsx`, `tla/.../menu-items.tsx`) to opt-in `allowReferrer` for specific `tldraw.dev` links. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 773aefc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Summary - allow `QueryExpression` to handle nested object properties and extend `executeQuery` to filter nested criteria - expose helpers on `StoreQueries` for retrieving ids and records to support the new query shape - expand store query tests with nested shape data and assertions for nested matching ## Testing - yarn vitest run packages/store/src/lib/executeQuery.test.ts ### API Changes - Store queries now support comparisons on nested properties. ------ https://chatgpt.com/codex/tasks/task_b_68f734d0a7748321b36b12cdd3de4351 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Enable querying and indexing of nested record properties (via backslash-delimited paths), update types/helpers, and expand tests for nested/reactive scenarios. > > - **Store Queries / Indexing**: > - Support nested property indexes using backslash-delimited `path` (e.g., `metadata\sessionId`) in `StoreQueries.index` and `__uncached_createIndex`. > - Indexing skips undefined nested values and handles adds/updates/removes incrementally. > - Generalize `RSIndex`, `RSIndexMap`, `RSIndexDiff` to use `any` key types. > - **Query Language**: > - Extend `QueryExpression` to recursively support nested objects. > - `objectMatchesQuery` now matches nested criteria. > - `executeQuery` flattens nested matchers to paths and queries corresponding indexes; intersects results. > - **StoreQueries helpers**: > - Add internal `getAllIdsForType` and `getRecordById` to support efficient queries. > - `ids()` uses `getAllIdsForType` for empty queries. > - **Tests**: > - Add extensive tests for nested queries, deep nesting, operators (`eq`, `neq`, `gt`) on nested fields, reactivity, batch ops, and mixed criteria. > - **API Report**: > - Reflect new nested `QueryExpression`, path-based index signatures, new internal helpers, and generalized `RSIndex*` types. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5dc7bab. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Summary Adds batch migration functionality to migrate all users from the legacy file_state model to the new groups backend. Includes real-time progress tracking, ability to stop migrations, and a user count endpoint. ### Change type - [x] `improvement` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds an admin UI and SSE backend to batch-migrate users to the groups backend with configurable batching, live progress, and unmigrated count. > > - **Admin UI (client)**: > - **Batch Migration section** in `apps/dotcom/client/src/pages/admin.tsx` with controls for `batchSize`, `batchSleepMs`, and optional `maxUsers`, plus start/stop. > - Real-time progress log and stats (total, completed, succeeded, failed, percent), and a button to fetch unmigrated user count. > - New styles in `apps/dotcom/client/src/pages/admin.module.css` for stats, counts, config inputs, and logs. > - **Admin API (worker)**: > - `GET /api/app/admin/unmigrated_users_count` returns number of users without `groups_backend`. > - `GET /api/app/admin/migrate_users_batch` streams Server-Sent Events with progress, supports `batchSize`, `batchSleepMs`, `maxUsers`, and stop-on-client-cancel. > - Helpers: `getUnmigratedUsers` and `performBatchUserMigration` to query and migrate users in batches with throttling and detailed progress. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ab8c45c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
deletions were going through but we were also triggering an error due to
a 'on file exit' behaviour where a file_state update was triggered and
that was failing due to the fact that the file had been deleted.
### Change type
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Prevents updates on deleted files and replaces onFileExit with a
direct lastVisitAt update to avoid deletion-related errors.
>
> - **App logic (`TldrawApp.ts`)**:
> - Add guards in `updateFileState` and `updateFile` to skip updates
when the file is missing or `isDeleted`.
> - Remove `onFileExit` method.
> - **Editor (`TlaEditor.tsx`)**:
> - In unmount cleanup, replace `app.onFileExit(fileId)` with
`app.updateFileState(fileId, { lastVisitAt })`, preserving the existing
error guard.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ba0e318. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Hopefully this will make it more obvious what is happening. ### Change type - [x] `improvement`
Fixes two issues with our production deployment Discord messages: 1. Fixed step count for dotcom deployments 2. Added deployment prefixes - Analytics and dotcom deployments now post with [ANALYTICS] and [DOTCOM] prefixes respectively, making it easier to distinguish which deployment posted each message when they run in parallel. An alternative approach would be for all steps to use the same message, which might be better? That said we would loose the timestamps so we wouldn't know how long the steps took 🤷♂️ ### Before (dotcom and analytics worker deploy messages are interleaving) ``` --- production dotcom deploy pre-flight --- setting up deploy ✅ --- production analytics worker deploy pre-flight --- cloudflare deploy dry run ✅ building dotcom app ✅ --- pre-flight complete, starting real analytics worker deploy --- deploying analytics worker to cloudflare ✅ Deploy complete! cloudflare deploy dry run ✅ --- pre-flight complete, starting real dotcom deploy --- deploying asset uploader to cloudflare ✅ deploying multiplayer worker to cloudflare ✅ deploying image resizer to cloudflare ✅ deploying health worker to cloudflare ✅ deploying fairy worker to cloudflare ✅ deploying dotcom app to vercel ✅ Deploy complete! ``` ### After ``` [DOTCOM] --- production dotcom deploy pre-flight --- [DOTCOM] setting up deploy ✅ [ANALYTICS] --- production analytics worker deploy pre-flight --- [ANALYTICS] cloudflare deploy dry run ✅ [DOTCOM] building dotcom app ✅ [ANALYTICS] --- pre-flight complete, starting real analytics worker deploy --- [ANALYTICS] deploying analytics worker to cloudflare ✅ [ANALYTICS] Deploy complete! [DOTCOM] cloudflare deploy dry run ✅ [DOTCOM] --- pre-flight complete, starting real dotcom deploy --- [DOTCOM] deploying asset uploader to cloudflare ✅ [DOTCOM] deploying multiplayer worker to cloudflare ✅ [DOTCOM] deploying image resizer to cloudflare ✅ [DOTCOM] deploying health worker to cloudflare ✅ [DOTCOM] deploying fairy worker to cloudflare ✅ [DOTCOM] deploying dotcom app to vercel ✅ [DOTCOM] Deploy complete! ``` ### Change type - [x] `improvement` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds message prefixes to Discord deploy notifications for analytics/dotcom and fixes dotcom total step count; introduces `messagePrefix` support in the Discord helper. > > - **Deploy Scripts** > - `internal/scripts/deploy-dotcom.ts`: > - Set Discord `totalSteps` to `previewId ? 10 : 9`. > - Add `messagePrefix: "[DOTCOM]"` to Discord notifications. > - `internal/scripts/deploy-analytics.ts`: > - Add `messagePrefix: "[ANALYTICS]"` to Discord notifications. > - **Library** > - `internal/scripts/lib/discord.ts`: > - Extend `Discord` constructor to accept optional `messagePrefix`. > - Prefix all sent and edited messages with `messagePrefix` when provided. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0c9aa6e. 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] > Updates Spanish `tool.rich-text-bold` from "Atrevido" to "Negrita". > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bdec887. 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>
reverts part of tldraw#6626 to fix https://discord.com/channels/859816885297741824/1429837310920495229 ### Change type - [x] `bugfix` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Moves `tl-canvas__in-front` outside the canvas and applies modal overlay styling to it to match `.tl-canvas`. > > - **Editor**: > - Moves `tl-canvas__in-front` container outside `.tl-canvas` in `packages/editor/src/lib/components/default-components/DefaultCanvas.tsx`. > - **Styles**: > - Extends modal overlay styling to ` .tl-canvas__in-front` alongside `.tl-canvas` in `templates/chat/src/app/styles.css` (same radius, shadow, and insets). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7494a2d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
If you close tab or refresh, your latest viewport position might not be saved. Adding this beforeunload callback seems to work locally (_most_ of the time?) anyway it can't hurt. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Flushes pending file state updates on tab close/refresh to persist the latest session/viewport state. > > - **Editor**: > - Add `beforeunload` listener in `TlaEditor.tsx` `FileStateUpdater` to `flush` throttled `update`, ensuring latest `session state` and timestamps are saved when the page is closed or refreshed. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5e8b0c2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…gs (tldraw#7128) we usually get translations same day but the login stuff went out before translations were ready so we didn't notice this issue until now. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Ensure untranslated strings fall back to English by merging fetched locale messages with the English bundle. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 59298bc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
cc @derekcicerone ### Change type - [ ] `bugfix` - [x] `improvement` - [ ] `feature` - [ ] `api` - [ ] `other` ### Release notes - cross-realm: adapt `useCanvasEvents` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Scopes the canvas pointermove listener to the editor container’s ownerDocument to support cross-realm contexts. > > - **Editor**: > - `useCanvasEvents`: > - Derives `ownerDocument` from `editor.getContainer().ownerDocument`. > - Attaches/removes `pointermove` listener on `ownerDocument.body` instead of `document.body`. > - Updates effect dependencies to include `ownerDocument`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bccc226. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
made it hard to do rich text for custom shapes downstream ### Change type - [x] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [ ] `other` ### Release notes - add export for `DefaultLabelColorStyle`, used with `labelColor` which is necessary for rich text in custom shapes ### API changes - add export for `DefaultLabelColorStyle`, used with `labelColor` which is necessary for rich text in custom shapes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Export `DefaultLabelColorStyle` from `@tldraw/tlschema` and update the API report accordingly. > > - **Exports**: > - Add `DefaultLabelColorStyle` to `packages/tlschema/src/index.ts` from `styles/TLColorStyle`. > - **API**: > - Include `DefaultLabelColorStyle` in `packages/tlschema/api-report.api.md`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4689e57. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
this is work that was in the fairy branch, landing this parent tweak ahead of the SDK release ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` ### Release notes - examples: dynamic tools <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a new example that dynamically adds/removes a custom Heart tool and updates the toolbar using setTool/removeTool. > > - **Examples**: > - **New example** `apps/examples/src/examples/dynamic-tools/DynamicToolsExample.tsx`: > - Implements `HeartTool` (`StateNode`) creating a heart emoji on click. > - Uses `editor.setTool` / `editor.removeTool` to dynamically register/unregister the tool. > - Adds UI overrides to expose `tools.heart` with custom icon and toolbar item. > - Integrates a toggle button (in `InFrontOfTheCanvas`) to add/remove the tool at runtime. > - Supplies `customAssetUrls` for `heart-icon`. > - **Docs**: > - Adds `README.md` describing dynamic tool addition/removal. > - **Styles**: > - Adds `dynamic-tools.css` for the toggle button positioning. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3e218db. 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] > Refreshes i18n across many locales, adding translations for groups/invites, file‑linking, auth/terms/privacy prompts, and related UI; removes/renames a few deprecated keys. > > - **i18n/localization**: > - Add new strings across `apps/dotcom/client/public/tla/locales*/**.json` for: `groups` (create/delete/leave, settings, members/roles), `invites` (copy, accept/join, invalid link), `file links` (add/paste URL), `auth` flows (continue with email, Google sign-in, verification code, guest), `legal/cookies` (accept analytics, terms of use, privacy policy), and various UI prompts (save, show more/less, danger zone, room limits). > - Adjust/rename some keys (e.g., pin/unpin/upload strings removed or replaced) and add richer status/tooltip texts (rate limiting, errors, read‑only, publish/unpublish). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dd016a8. 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>
This PR improves fairy collaboration 2.0. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds project orchestration with awaitable tasks, splits working mode into drone/solo, introduces personal todo list and viewport-bound parts, and updates UI/debug for projects and in-canvas tasks. > > - **Agent/Modes**: > - Split `working` into `working-drone` and `working-solo`; add mode hooks `onEnter/onExit/onRequestComplete` and mode transition notifications. > - New wait/notify system: agents can `waitFor` conditions; notify on `task-completed` and `agent-mode-transition`. > - **Actions**: > - New `await-tasks-completion` action. > - Rename/adjust: `create-solo-task` → `create-task`; `update-todo-list` → `update-shared-todo-list`. > - Separate task completion: `mark-my-task-done` (drone) and `mark-task-done` (solo). > - Improve `start-task`, `direct-to-start-project-task`, `fly-to-bounds`, `sleep`, `update-personal-todo-list` behaviors and interruptions. > - **Prompt/Parts**: > - Split `viewportBounds` into `userViewportBounds` and `agentViewportBounds` parts. > - Add `personalTodoList` and augment `currentProject` with `role` and `plan`; update system prompt for orchestration. > - **Schema/Types**: > - Extend `FairyProject` with `plan`; add `FairyWaitCondition` types; export new parts/actions. > - **UI**: > - Group chat → project creation flow with `onStartProject`; HUD header shows "Create project" for multi-select. > - In-canvas task list: bounds overlay (debug flag), component rename to `InCanvasTaskList`. > - Debug dialog: separate Home/Fairy options; global `$fairyDebugFlags` with `showTaskBounds`; project inspector shows `plan`. > - **Styling/Assets**: > - Add styles for debug/options and task bounds; new `propellor` hat variant. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 82641ab. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Max Drake <maxdrake46@gmail.com>
Add some basic group e2e tests. There's a ton more we could add, but went for the most basic ones for now as they do tend to be on the slow side. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds end-to-end tests and fixtures for groups (CRUD, reorder, file ops, sharing) with supporting test utilities and minor test-id/DO route adjustments. > > - **E2E Tests**: > - Add `tests/groups.spec.ts` covering group create/rename/delete, expand/collapse persistence, reordering via drag, file create/move/drag/pin/unpin/duplicate/delete, move-to-home, and sharing/invitation flows with cross-user propagation. > - **Fixtures/Helpers**: > - New `GroupInviteDialog` fixture; register in `tla-test.ts` and `helpers.ts`. > - Extend `Sidebar` fixture with group operations, file operations within groups, drag-and-drop utilities, and invite-link copy methods; add `createGroupButton` selector. > - `Database` fixture: add `enableGroupsFrontend()` and simplify cleanup to hit `prepare-for-test` without legacy header. > - Remove init-mode code from `HomePage`. > - **App UI**: > - Change sidebar create-group button test id to `tla-create-group` in `TlaSidebar.tsx`. > - **Sync Worker (test utilities)**: > - Simplify `__test__prepareForTest`: always set `groups_backend`, clear all user groups, and recreate home group; update `/app/__test__/user/:userId/prepare-for-test` route accordingly. > - **Cleanup**: > - Remove `run-both-modes.sh` and `init-mode-verification.spec.ts`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 18c142a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
see title ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Stops including <!-- CURSOR_SUMMARY --> sections when generating the draft changelog. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fbfa8d7. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This adds a variant of the sign in modal which automatically accepts the group invite. <img width="1134" height="1312" alt="CleanShot 2025-11-18 at 13 41 01@2x" src="https://github.com/user-attachments/assets/aa29dd03-21d9-4a06-97c7-52abd6bf897c" /> ### Change type - [x] `other` ### Test plan 1. Create group invite link. 2. Accept it in another browser that is logged out. 3. You should see the new sign in dialog variant and after logging in you should see the group you were invited to. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds an invite-aware sign-in flow that auto-accepts group invites, updates invite/sign-in dialogs and routing, and refreshes related i18n strings. > > - **Auth/Invites**: > - Add invite-aware `TlaSignInDialog` that shows group info, supports Google/email sign-in, and triggers auto-accept via `onInviteAccepted` with `?accept=true`. > - Simplify `TlaInviteDialog`: remove sign-in branch; always show “Accept and join group” (no HTML in copy). > - **Routing/URLs**: > - Use `routes.tlaInvite(...)` for invite links in `GroupSettingsDialog` and Google OAuth redirect. > - `local.tsx`: when logged out, show `TlaSignInDialog` for invites and navigate to invite URL with `accept=true` on completion. > - `file.tsx`: only show `TlaInviteDialog` when user is signed in. > - `useInviteDetails`: fetch invite by `inviteSecret` from location state and clear it via `navigate(replace)`. > - **i18n**: > - Replace invite title string with plain text (`You have been invited to join group:`) and add `Sign in or create an account to accept the invitation.`; remove older HTML-based keys. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1d8e53d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
An example showing how you could use a callback with `onInteractionEnd` ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a new example demonstrating `onInteractionEnd` to control behavior after translating a newly created shape. > > - **Examples**: > - Add `apps/examples/src/examples/interaction-end-callback/InteractionEndExample.tsx` showcasing a custom `QuickShapeTool` that: > - Creates a `geo` shape on pointer down, switches to `select.translating`, and uses `onInteractionEnd` to update the shape's `fill` to `pattern` and return to `quick-shape`. > - Add `apps/examples/src/examples/interaction-end-callback/README.md` documenting usage of `onInteractionEnd` for translate/resize/rotate interactions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ecafafb. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Add an example to demonstrate the new `snapReferenceHandleId` property. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a new example showcasing `snapReferenceHandleId` via a custom Y-shaped shape and accompanying README. > > - **Examples**: > - **New example** `apps/examples/src/examples/custom-relative-snapping/CustomRelativeSnappingExample.tsx`. > - Defines `YShape` and `YShapeUtil` with four handles; arms use `snapReferenceHandleId: 'center'` for shift-angle snapping. > - Renders three lines from center to arms; updates arm positions on handle drag. > - On mount, creates and selects a `y-shape` at viewport center. > - **Docs**: > - Adds `README.md` with metadata and brief explanation of `snapReferenceHandleId` for control-point angle snapping. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2dd9aaf. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This pull request updates the English localization and sign-in dialog messaging to unify and simplify the description of tldraw as a product. Several older, redundant, or less concise messages have been removed and replaced with a single, clearer message about tldraw being a free online whiteboard and the benefits of creating an account. This ensures consistency across the UI and improves the onboarding experience for new users. **Localization and Messaging Updates:** * Replaced multiple older messages (e.g., "tldraw is a free and instant virtual whiteboard.", "Create a free account to save your work, collaborate in real-time, and more.", and "Sign in or create an account to accept the invitation.") with a new, unified message: "tldraw is a free online whiteboard. Create an account to save your files and work with your friends." in both `en.json` and `locales-compiled/en.json`. [[1]](diffhunk://#diff-00aff287a2ba64df0ac85108a2a353c57dbd6ff2fcf0af506a371533b0ae27ecL26-L37) [[2]](diffhunk://#diff-00aff287a2ba64df0ac85108a2a353c57dbd6ff2fcf0af506a371533b0ae27ecR260-R262) [[3]](diffhunk://#diff-00aff287a2ba64df0ac85108a2a353c57dbd6ff2fcf0af506a371533b0ae27ecL450-L452) [[4]](diffhunk://#diff-172557233305d8563de0969a2f73486aaafa7f44e657aebd4664797a492ac730L54-L59) [[5]](diffhunk://#diff-172557233305d8563de0969a2f73486aaafa7f44e657aebd4664797a492ac730L72-L77) [[6]](diffhunk://#diff-172557233305d8563de0969a2f73486aaafa7f44e657aebd4664797a492ac730R560-R565) [[7]](diffhunk://#diff-172557233305d8563de0969a2f73486aaafa7f44e657aebd4664797a492ac730L1048-L1053) * Updated the `TlaSignInDialog.tsx` component to use the new unified message in both the invitation and default sign-in flows, removing references to the older, now-deleted messages. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Unifies sign-in dialog copy by replacing multiple older strings with a single message and updating the dialog to use it in both invite and default flows. > > - **Localization (en)** > - Remove redundant strings from `apps/dotcom/client/public/tla/locales/en.json` and compiled `locales-compiled/en.json`. > - Add unified message `"76dea3c9ca"`: `"tldraw is a free online whiteboard. Create an account to save your files and work with your friends."`. > - **UI** > - Update `src/tla/components/dialogs/TlaSignInDialog.tsx` to display the new unified message for both invite and default sign-in cases; remove references to deleted strings. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3bfc213. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Expands i18n across the Fairy UI (hat names, HUD toggle labels), includes `src/fairy` in extraction, updates locales, and converts Fairy Debug View to plain strings. > > - **i18n**: > - Include `src/fairy` in `i18n:extract`. > - Add numerous Fairy-related messages to `public/tla/locales*/en.json` (hat types, HUD toggles, group chat, task list, etc.). > - `src/fairy/FairyConfigDialog.tsx`: map hat variants to translated names. > - `src/fairy/FairyHUD.tsx`: use i18n for toggle labels; plumb labels through header props. > - `src/fairy/FairyGroupChat.tsx`: minor label tweaks to use translated "Name"/"Personality". > - **Debug**: > - `src/fairy/FairyDebugDialog.tsx`: replace i18n components with plain strings for titles, labels, and headers. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d6798b5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
we were pushing the new branch using the tag as a ref before the tag had
been pushed, this command pushes the tag in addition to the branch
### Change type
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Updates `internal/scripts/publish-new.ts` to push the release branch
and tag in one command using `--follow-tags`.
>
> - **Release script (`internal/scripts/publish-new.ts`)**:
> - Replace two separate `git push` calls with a single `git push origin
${gitTag}:${branchName} --follow-tags` to push both the release branch
and annotated tag.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dd29e6e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
we forgot to put this pin icon behind the feature flag. <img width="261" height="175" alt="image" src="https://github.com/user-attachments/assets/8cc45169-02ab-4bf9-a4c3-dd993fac3b4d" /> ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Show the sidebar inline pin icon only when `groups_frontend` flag is enabled (in file link and rename input). > > - **Sidebar**: > - `TlaSidebarFileLinkInner` and `TlaSidebarInlineInput` now render `pinIcon` only when `isPinned` and `useHasFlag('groups_frontend')` are true. > - Added `useHasFlag` usage to both components. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8bcb01d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
argh so this wasn't creating a branch, chatgpt lied to me 😭 ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Corrects git push to create/update the release branch by pushing HEAD to `refs/heads/<branch>` with tags. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 67c4515. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This PR adds an example that demonstrates how to use tldraw's various "easter egg" styles programmatically. It shows how to use: - White - Fill - Lined fill - Label color - Scale ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` ### Test plan 1. Open the easter egg example. 2. Check you can see the five demo shapes, and that they have the correct styles. - [ ] Unit tests - [ ] End to end tests ### Release notes - Added an example showing how to use tldraw's hidden easter egg shape styles programmatically. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is generating a summary for commit 518f80e. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Removed trailing periods from 'Open tldraw.' and 'Back to tldraw.' messages in ErrorPage, and clarified the rate limit error message in TlaFileError to 'Too many requests. Please slow down.' for improved user understanding. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Standardizes error copy (removes trailing periods and clarifies rate limit text) and updates English locale entries accordingly. > > - **UI copy**: > - Update `ErrorPage` go-back link text to `Open tldraw` (in iframe) and `Back to tldraw` (no trailing periods). > - In `TlaFileError`, change rate limit message to `Too many requests. Please slow down.` > - **i18n (en)**: > - Add/update keys for `Back to tldraw`, `Open tldraw`, and the new rate limit message in `apps/dotcom/client/public/tla/locales*.json`. > - Remove old variants with trailing periods and the previous `Please slow down.` string. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 43a1b2a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Summary We're not using PostHog surveys, so disable the surveys module to prevent loading an unnecessary 30.2 kB script at runtime. This adds `disable_surveys: true` to the PostHog configuration to prevent the surveys module from being dynamically loaded. ## References - PostHog PR adding the `disable_surveys` option: PostHog/posthog-js#1123 ## Test plan - [ ] Verify that `surveys.js` is no longer requested in the network tab when loading tldraw.com - [ ] Verify that analytics still work as expected (event tracking, page views, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Disable PostHog surveys by setting `disable_surveys: true` in the analytics config to avoid loading the surveys module. > > - **Analytics**: > - Update `apps/dotcom/client/src/utils/analytics.tsx` PostHog config to set `disable_surveys: true`, preventing the surveys module from loading. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 451912a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude <noreply@anthropic.com>
Duplicate tracking removed:
- Code copy now only fires `click_copy_code` via `trackCopyCode()`,
removed duplicate `docs.copy.code-block` PostHog event
- Both button clicks and manual copy (Cmd+C) tracked separately, no
duplication
Consent tracking fixed:
- Renamed `consent_changed` → `consent_update`
- Disabled GTM-specific consent events in enable/disable
- Now fires single `consent_update` with proper structured consent
object:
```ts
{
event: 'consent_update',
consent: {
ad_user_data: 'granted',
ad_personalization: 'granted',
ad_storage: 'granted',
analytics_storage: 'granted'
}
}
```
Cleanup:
- Removed unused name param from CopyButton
### Change type
- [x] `other`
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Centralizes consent_update emission in analytics core and removes
duplicate docs copy tracking by standardizing on trackCopyCode and
simplifying CopyButton.
>
> - **Analytics**:
> - Centralizes consent tracking in `apps/analytics/src/index.ts`,
emitting `track('consent_update', { consent: ... })` with detailed
grant/deny state.
> - `apps/analytics/src/analytics-services/gtm.ts`: stops pushing
consent updates on `enable/disable`; retains identify/event/pageview
flows.
> - **Docs**:
> - Standardizes code-copy telemetry via
`window.tlanalytics.trackCopyCode` only; removes custom
`track('docs.copy.code-block', ...)`.
> - Simplifies `CopyButton` API (removes `name` prop) and updates call
sites in `pre.tsx` and `code-files.tsx`.
> - Keeps Google Ads conversion firing on copy in `app/analytics.tsx`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
eacfd14. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Make sure we correctly send the changes (after services are enabled and before they are disabled). ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Reorders consent tracking so `consent_update` fires after enabling on opt-in and before disabling on opt-out, ensuring the event is captured. > > - **Analytics consent flow (`apps/analytics/src/index.ts`)**: > - Reorders `consent_update` tracking relative to service state changes: > - On `opted-in`: enable services, then track `consent_update`. > - On opt-out/unknown: track `consent_update`, then disable services. > - Centralizes `consentState` construction for granted/denied fields used in the event payload. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit cd54b1a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
continues the work done in tldraw#6739 ### Change type - [ ] `bugfix` - [x] `improvement` - [ ] `feature` - [ ] `api` - [ ] `other` ### Test plan 1. Tested manually in https://github.com/Andarist/tldraw-augmentation-test 2. The most complex `TLIndexedShapes` also tested manually in [TS playground](https://www.typescriptlang.org/play/?ts=6.0.0-dev.20251027#code/JYOwLgpgTgZghgYwgAgCoBkBCcDOEDKAFnAA4QA8qAnmQDTIAKUA9iTgHzIDeAUMsmBoQAXGiEBuPshIs2opqxySAvjx6CyadAEEoLAO5FSKALxbseI2XIAiOHub6b9LsgAmwKKJxgooAObIyuySGigYmMwAHlam5rgExNY2AEbRztzIUaIgAK4AtinQ4shUOQVFUEEh6kJaAML2brHIZhEJsbYITRmuCMwANsxeyD5+IIHBoXUYAOIsuSQtbVgdSRQ2-gskvcjAbt6+AdXTmhgAavsQzMvxluu2AG5XzLtgwPkiyHmFxdIDcCoAVEaUGEDgIBOajCWgAIhB4LkBmBllIAD5aXQGWLo8zRHH8DEYRpQZrrXFzbYE5BE9CXNzXWKSHgQKIkYZgPbgaDwJBaWZDFJwAaxBRsACypG4qhZbI5XMgsEQ4XQAuYQpF6zFOElJG4Um6pPKAwGJQA9GbkKyEANcgzkPpgGBCMh4AMcFQDbkfMx8qJXEKAF4BOCHcaTc2W1mQEBuB1Ol1wZD9fIkAYQSADKjJ71gX2jcn8Z4M5j+gQfL4-SolNOA4HIUHpiElYVgVDRsPHZSRq1RGNxhmI5EF4xSLbMRbG03IC17MAAchwyCT-SgKBw63oTuTEPnnKK7mAODgKXTbjNzEe0D8DJAPBlrPZUE5MIwAElY6yIGTjEuzLx+FnAB1FAnWgOBIGQS9oGXZBchAYBmEhZgYGXXJ-E+bk4wAawgKglwhAcETgJFOQ3YwBCEHAADopFnVBCCPZcTUcJdvQEZguRtO0UAACmGZMkI8d4kOFLNe24+0BOgvQrgASgEQgUEHEjh3Isgl1AKCQBQfxmFowCzToy0P0UlAAANcHM5MAW9FB9BQewUBgYBkWgY4J05Dxj1Pb8Rw0gzkAAbQAaS5KRCWQXCqBQ-lBWFUVZB1UgIppOFiNI2IgpsMIbAAXWXJcwujCBYyXDB4SHFF1my3K8tSgB+GdLVXdd1gItdmP0QECMeOBXJPdNl1jHcQBAZh9xQGSb1vUZOIc5AACtcy4217WdCB8lS-hir7Uq3CXTZthsbbkCakLTtEXb+yXaLYrmeLNWMbVdVOprZ2AVDtxKsrYLyE0jxdPrbRQDa4LwKpiCXbzBr850mPU0G6hwebnNcxU5yg3JOUdZ1vggK8oFO-gHvVBKtSS3VQoKn6Du+JEBjS+DB1Ab9ibO-HCfZq7LuQC7+H4K68qu3sbuQI6Jx2RrmsEzrEY6xyBm6-Dlz6gbfOGuNujGiaGymwmZtKuaHRQZafFWnizK2gWBYAUT7KBEDASh0Eq1TquMFxKLIEXglSkXafK12MuRLKcqEfLpY+r6FwI9wQ7I9ZvfslAdLhziECUhBsL2GPFz1o3pv2W9Tuu-bbrw+7VUexLFFem3+Hey1PsxqGC+Qg2rkhDbITssycx9fJ-OUhFQCdRC7wbgX2nuYxyBC+hSY1WuJVIan2F56PW9wb5daKQvO9mnvkDXPvWSPd4JmT5jgASJcYAEoowAxmFvNrT0p-4e3fCdl23cyzcmQwi+w3jbUQs4+5gwQLmfMiN44uQQiJSeDcZ6JDngvOKZMnpkBemvMKAAyKKldUJL3Js9SmpA8o1G7GoWca4UYDCvHGd8n4ojfliDgYQPALTcMtK+dAH4GRsJ-BpVo+pZw22gYPUQqDOg2CkXmfIuxZwKNgeSCRn8gwhk7BMSQGj+BTF4Q3Ys1wZGrFnskExrwvazgAFS02-LY5AVijGf3LJ8covwoB6MtG49+9ZGzghAD4txzE2wdlGEcXRriBaGP0cuBw+gzFYkcEyGWrUEkGBifwNI2Q8QxHWD2DJuSjGqFnLOWEAB5W2+AABy85UDIGIFeZA9ioiSUcTuUkPAgA) (previous iteration can be found in: [TS playground](https://www.typescriptlang.org/play/?ts=6.0.0-dev.20251027#code/JYOwLgpgTgZghgYwgAgCoBkBCcDOEDKAFnAA4QA8qAnmQDTIAKUA9iTgHzIDeAUMsmBoQAXGiEBuPshIs2opqxySAvjx6CyadAEEoLAO4K2yALzdkAE2BRROMFFABzZKo0oMug0VIozGbHjeZOQA5HB6zPoh9B4RhrIc6kJamMwAHkY4puZpoiAArgC2AEbQ4shUeUWlUC5Jmv7pQb4puATEwSHF6dEp6Zns9e7oAMLhFpnZXMgIzAA2zDbIdg4gzq7JGGNQFs3Z-m3NoQjjvVvjA0NaAGrAFhDMk2bTYMCFIsgFJWXSc3BUTlE3XmEDgIDqbhudweez8WEOHQoIQAbtDmGd0Ld7o8EoMrhgACIQeD5OZgWFaTyRPYAHz6aVpWm2u0RyDpGCxMMRanuCD+UBQsxAdgEcxGi3aPlE+RAwAAjvkUDgqCV5jwIGkSIswAJkuKBUdUJw-GzdWRmDBRfrJZoAPS2mYS5aIrInEAgZg60rIZjI6AOCz3EA8Xn8wXMYU6sBzIkksnNaWyhVKlXdObqzXas0oADyfqg+gcYDgxTmEFjcFJ5MRlGNaFNBTmc1NMvuMFAEAsprcFtFFarzTUoEgsEQw378cRmQAsqRuFJwgZRHnoIXgMXS+XiZXJz5KDo4gNJPwTjtl-m1xuyxPq3vzjsj1JurlkNbDVh+rjj8hUdjz6uixLa9twHGsOTRR9VAzLUoB1YdoHgJAtAAcQWYo4DmZoZznDVIBACwskJEDdzIbCSG4KCNRguDwAQscULQjCsISWdyN4E9xiqJtyntZANT5fJ7mQfR10IZB4DmZUpAQfI7GYQpRGmdCAC8nDgWx7CcFweIdXCIHw4TROQOBHUKEgy0gOYqBmWSwHk50fCkX8HkUgQ3g+L4anKcz-kBZBgTLMFygwsBUFwjTVnWHS+LSPCu1AYzTJIOBXk3YT-h4SjM1g5B4NHJCMFQ5h0MwqcWLned+F4xdIlc-RiEgfMIq05RkF40BZjMlLgDSvThWACMZgFFKICyME+IiWpgEtKhmHyZAZU695wFysBMrUKis0hDAAEl8I1TtmiyZ4eAASHa8EwEIFAAANcBumY-lklB9BesEo2YcTgDJaAfXyHUrBwIDOwcsgcDOgBtABpXLwQAawgWbLUKxjSp8MjjKyGG+oI5AEaRrQb2YxRWLO06AH42odWYBVB0bjNpjD9H+MbkTgb7geMgy3Q9L0UF9f07iDZZPte5AACtbNhgShKuiBCjJ06e0taM31ZHHCPQImypJ0hoYAXUVymocV0R2stdcYrisbPlJOZgBwMS2bmRUBGuha8FqYgskB4Guyuh26ezEXhJQdsfqmnU5p1ESrs+CB80V06UeKpidbYViDat-TccbZs6VbYkOwsJPKZABPoCT0QTdO07q-1s3qadR2fDGxm5mZqhWfZv40rBLsec9fz+fzAMgzO7HYpzrJ8d7aZoYAJlhvHEd7Ii41vUjyvI3Bs17VWJT2DXCeIzeIDIxf9eQY2l7yCuoAbk+N+JjO9ahher9UWvKYAUViqBEBgH3NrHw9AXhCGri4QYtdRBVQdNNN2KZVTNkDnYb6zY5YCnoJbd4YIshyw9r9b2nwh4CwLEWPCq1Fa8RujDAAZCvAm68dxnzIg9TSCA4a5SyM9Ls11aZ2T4sKfIAjCCB2KAAkACAxIRissZEg5lgD00EQQtsLCg5uBwLQahDpPT8JEngGyclCg+nLj7Iu5cuz2wRsgG6JBQCKWUA9fQc05hdmSjgfBYjXTXU4YrZWfZT5HynvhTWRUSovxwJnehjC15ayCenKJpBDa1wpvwKmHstI3QOIEGsUN6B-xlhQcJad0bbwNvQPOLZ9rtksd2IQ+8YwJJ8OwdgzjXFdhcVALh-CIBJ14sUf6AhPqFDgDYyEgMfJd2QIUJ0QoEAOwgPQMWz1EGOj0KNLU+EtJtmLsHDCwA2jg1SadP+9hAHAOaXQcwbhIHKGgTA9JvFakYSssslAw1pFrJksYumWRen0FUQ7P2fzQ7t2GhYay4cRwg2jv5ayBC7o4AenySseAk45JtBQfJyAAByEZcV22BvuEpaMt66xIAbVp60eC8QFDgeYfouy7X2mkQ6LphC0ttFy4OLL7hspZK3KYPL0lGLsgpVouS9wACIfniulWAjJcr7ItzICK0V6SVJqWamsSQvFRX3L1Q6UVzlmCiExUcaVpqFXmF4gAKhxp2O1P40Tqo1W5d4VRvhQCNe69JUy-IBVBCAX1frjJkjCrFHVjhQ3pMNW6hmS5KRxGaNFGmKAar6ATc+c1H4GSIjTU6Z8PLVC8V4gSHMP98C4pCKgZAxA-TIAdWkIpFhnWngsEAA)) ### Description The main goal of this PR is to allow users to provide users to strictly type all their custom shapes' props. Previously people would have to resort to using an unknown shape, casting, or "casting" through generics (where tldraw types would just accept their type arguments happily). With the new system in place users can augment a builtin tldraw interface like this: ```ts const CIRCLE_CLIP_TYPE = 'circle-clip' declare module 'tldraw' { export interface TLGlobalShapePropsMap { [CIRCLE_CLIP_TYPE]: { w: number h: number } } } export type CircleClipShape = TLShape<typeof CIRCLE_CLIP_TYPE> ``` Once this is done, users can now use the shape type like this: ```ts editor.updateShape({ id: shapeId, type: 'circle-clip', props: { w: 100, h: 100, }, }) ``` Thanks to the power of discriminated unions, this will now error if the user tries to update the shape with the wrong props. That said, for the time-being, I kept generic parameters in the editor methods to: - maintain backwards compatibility - keep this documented pattern working: https://tldraw.dev/docs/shapes#Meta-information⚠️ this allows users to bypass the created augmentation system and locally call methods with shapes having *more* properties than prescribed by the augmentation system. Given the TS structural type system... this is something that can always happen when arguments are not passed inline so it's largely fine as the users should start using the new system anyway. This should allow them to do it gradually though. This PR consists of: - the mentioned augmentation system. Related changes are mostly local to [`TLShape` file](https://github.com/tldraw/tldraw/pull/7091/files#diff-74a7534c2bdfff2f6ef9e068496c69dca2a7b09d05c1ff482485fd30480694d3) - using the new system in the [examples](https://github.com/tldraw/tldraw/pull/7091/files#diff-5f23c6b955fcdcf8a402446d96178e12241ca0cb01af4e73535cc1ca261f81f0), [templates](https://github.com/tldraw/tldraw/pull/7091/files#diff-5845112b17d3eb903a41e90e834858e5b8ab71b6350348811d183137824e4f07) and tests - updating the docs to reflect the new system [here](https://github.com/tldraw/tldraw/pull/7091/files#diff-1b0ad2aab7ced6fc26f40f9929d2d16269b8fa505bdf4b18b5b746facc5bcefc) and in the "guides" in the examples - followup code changes required by the new system, they can be found all over the place. - the same kind of changes related to the bindings (this PR includes the work done in tldraw#7133 ) ### API changes Numerous typings changes! make @ds300 compile a list <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces module-augmentation-driven typing for custom shapes and bindings, updates core editor APIs and utilities to support it, and migrates docs, examples, templates, and tests accordingly. > > - **Types & Schema**: > - Add `TLGlobalShapePropsMap`/`TLGlobalBindingPropsMap`, `TLIndexedShapes`/`TLIndexedBindings`, `ExtractShapeByProps`, and `TLCreateShapePartial`. > - Refactor `TLBaseShape`/`TLBaseBinding` and shape/binding record validators to work with augmented types. > - **Editor API**: > - Overload `getShapeUtil`, `isShapeOfType`, and `getBindings*` for typed shape/binding keys. > - Update `createShape(s)`/`updateShape(s)` generics and accept typed partials. > - Tighten types across selection, snapping, export, reparenting, etc. > - **Bindings**: > - Generic `BindingUtil`/callbacks now use typed `TLBinding`; connection/arrow binding utilities updated. > - **Docs & Guides**: > - Rewrite shape/binding guides to use module augmentation (`TLShape<typeof TYPE>`), update API docs. > - **Examples & Templates**: > - Migrate all examples and app templates to declare module augmentations and use typed shapes; remove legacy generic casts. > - **Tests**: > - Update tests to new typing model and API overloads; add tests for type narrowing and create/update generics. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ac324a6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Our claude config has a hook set to run prettier on `Edit|MultiEdit|Write`. This causes issues with imports as it always does the import first, then writes (which runs prettier and removes the unused import), only then it adds the usage. This PR uses an alternative. What if we only trigger prettier on `Stop` event, which triggers when claude is done. Think it wont trigger if claude gets interrupted by the user. Worth a try, can always revert. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Switches the Claude hook to run Prettier on Stop, formatting only changed files detected by git diff. > > - **Config (`.claude/settings.json`)**: > - Switch hook from `PostToolUse` to `Stop`. > - Update Prettier command to format only changed files (`git diff --name-only --diff-filter=ACMR | grep -E '\.(ts|tsx|js|jsx|json|md)$' | xargs -r yarn run -T prettier --write`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2ff3d46. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This PR lands the completed FaeOS. There is still further UI and backend work to do. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [ ] `api` - [x] `other` ### Release notes - improve 2-fairy experience - add memory gates for fairies - finalize model choice improve support for various models <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduce duo-project orchestration and model selection, add memory-level gating, refactor tasks (string IDs, titles) and persistence, plus prompt/worker updates and UI/debug improvements. > > - **Fairy Orchestration & Modes**: > - Add duo orchestration flow (`duo-orchestrating-*`, `working-orchestrator`) with new actions: create/start/direct/await/complete duo tasks and end duo projects. > - Update group chat to start duo projects and set roles; sidebar/orchestrator indicators support `duo-orchestrator`. > - Mode chart gains waiting states, prompt start/end/cancel hooks, and response-time logging. > - **Tasks & Persistence**: > - Refactor tasks to string IDs with `title`; drag tool, list UI, and actions updated accordingly. > - Rename persisted `sharedTodoList` → `fairyTaskList`; agent state uses `personalTodoList`. > - **Memory & Chat History**: > - Introduce memory levels (`fairy`|`project`|`task`) and `memory-transition` items; filter chat history by current mode. > - **Model Selection & Usage**: > - Add selectable model (`gemini-3-pro-preview`, `claude-4.5-sonnet`, `gpt-5.1`) via debug UI; include `modelName` prompt part. > - Track cumulative usage and cost per-model (incl. cached input); worker selects provider by model and adds Anthropic cache breakpoints. > - **Prompt/Schema Updates**: > - Expand agent action schemas and prompt parts for duo/project context; system prompt updated for solo/orchestrator/duo flows. > - **UI/UX**: > - Debug view: model dropdown, response-time flag; project/task inspectors; "Clear task list" → "Disband projects". > - HUD spinner optimization and minor label tweaks. > - **i18n**: > - Add strings for model label, response-time logging, and disband projects; remove obsolete "Clear task list". > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 231d734. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Max Drake <maxdrake46@gmail.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

Describe what your pull request does. If you can, add GIFs or images showing the before and after of your change.
Change type
bugfiximprovementfeatureapiotherTest plan
Release notes