Commits
- prettier/eslint --fix on committed lexicon JSON and generated
atproto lexicon TS (formatting only)
- regenerate excalidraw.test.tsx snapshots for the new
"Support Excalidraw" menu item
- ignore playwright session artifacts in .eslintignore so local
prettier runs match CI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2aFffBQjfVseWte1YydDE
Also ignore crates/**/target so local rust build artifacts don't trip
the prettier check.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- align vitest/@vitest/coverage-v8/@vitest/ui at 3.0.7 (kills the CI
'running mixed versions' warning) and bump @vitejs/plugin-react to
4.3.4 for the vite 5 peer range
- drop deprecated @types/socket.io-client (socket.io replaced by iroh)
- move save-exact into pnpm-workspace.yaml as savePrefix and delete the
root .npmrc, which pnpm 11 ignores entirely; allow react 19 peers for
radix-ui/next to silence unfixable unmet-peer warnings
- link examples/with-script-in-browser to the workspace package again
(pnpm resolved '*' to registry 0.18.1; yarn 1 used to link it)
- remove stale tracked examples/with-nextjs/yarn.lock
- run jsdom tests at http://127.0.0.1:3000 and map localhost to
127.0.0.1 in the atproto loopback redirect_uri, fixing the
'atproto auth initialization failed' stderr in tests (RFC 8252
forbids localhost in loopback OAuth)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spindle has no cross-workflow dependencies, so run the CI steps at the
start of the deploy pipeline instead: deploy-railway.yml now runs
lint/typecheck/tests before railway up (fail-fast steps abort the
deploy on failure) and moves to the microvm engine, while ci.yml
becomes pull_request-only so tests run once per push.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- typeof window was compared to the undefined value instead of the
"undefined" string in App.tsx
- drop GithubIcon/youtubeIcon imports left over from the tangled link swap
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
nixpkgs-unstable removed nodejs_20 after upstream EOL, which broke the
nixery dependency eval. Switch to the new microvm engine while we're at
it and pin the nixpkgs registry to keep resolution on unstable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Typing a handle from memory gave no feedback until submit, where a wrong
guess surfaced as a raw resolver error. Query a public actor index as the
user types and show matching accounts with avatar, display name, and handle.
The index is built off the firehose and won't know about every atproto
account, so suggestions are only ever a shortcut -- submitting always uses
the typed text, and the sign-in path is unchanged.
Only arrow keys arm Enter-to-select; hover is CSS-only, so a list opening
under a resting cursor can't turn Enter into an accidental OAuth redirect.
TextField gains an optional inputProps spread, needed for autoComplete="off"
(the browser's own autofill would otherwise cover the list) and the ARIA
combobox attributes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Only affects visitors with no stored preference; an explicit light/dark
choice still wins.
The fallback lives in two places — useHandleAppTheme and the pre-React
anti-flash script in index.html. Both had to change, or a first-time visitor
on a dark OS would get a white flash before React mounted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sign-in dialog assumed you already had an Atmosphere account, so a
first-time visitor hit a dead end at the handle field.
Creating an account goes through OAuth: an input starting with https:// is
resolved as a PDS URL rather than a handle, and prompt "create" asks that
server for its sign-up screen. Verified against selfhosted.social, which
lands on "Choose a username" rather than the login form.
Because an Atmosphere identity is shared across every atproto app, the button
opens a confirmation first — most people asking for a new account already have
one via Bluesky, Tangled, stream.place or leaflet.pub, and would only fragment
their data by making a second.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(editor): prevent eyedropper preview from overflowing viewport
* generalize
---------
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
* feat(packages/excalidraw): add `props.interaction` and `props.ui`
* fix: prevent browser zoom when interaction disabled
* changelog
* clean up interactive state on disable and consolidate `viewMode` and interaction state updates
* render UI rendered to `children` even if editor-exported
* support `allowed.navigation` and `allowed.embeds/interactiveContent`
* change naming `allowed` -> `enabled`
* changelog: add PR links
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* clear flowchart sessions via consolidated `app.flowchart` after master merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor getters -> methods
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
fix: Incorrect selection of deleted bound text
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
---------
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
- prettier/eslint --fix on committed lexicon JSON and generated
atproto lexicon TS (formatting only)
- regenerate excalidraw.test.tsx snapshots for the new
"Support Excalidraw" menu item
- ignore playwright session artifacts in .eslintignore so local
prettier runs match CI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2aFffBQjfVseWte1YydDE
- align vitest/@vitest/coverage-v8/@vitest/ui at 3.0.7 (kills the CI
'running mixed versions' warning) and bump @vitejs/plugin-react to
4.3.4 for the vite 5 peer range
- drop deprecated @types/socket.io-client (socket.io replaced by iroh)
- move save-exact into pnpm-workspace.yaml as savePrefix and delete the
root .npmrc, which pnpm 11 ignores entirely; allow react 19 peers for
radix-ui/next to silence unfixable unmet-peer warnings
- link examples/with-script-in-browser to the workspace package again
(pnpm resolved '*' to registry 0.18.1; yarn 1 used to link it)
- remove stale tracked examples/with-nextjs/yarn.lock
- run jsdom tests at http://127.0.0.1:3000 and map localhost to
127.0.0.1 in the atproto loopback redirect_uri, fixing the
'atproto auth initialization failed' stderr in tests (RFC 8252
forbids localhost in loopback OAuth)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spindle has no cross-workflow dependencies, so run the CI steps at the
start of the deploy pipeline instead: deploy-railway.yml now runs
lint/typecheck/tests before railway up (fail-fast steps abort the
deploy on failure) and moves to the microvm engine, while ci.yml
becomes pull_request-only so tests run once per push.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Typing a handle from memory gave no feedback until submit, where a wrong
guess surfaced as a raw resolver error. Query a public actor index as the
user types and show matching accounts with avatar, display name, and handle.
The index is built off the firehose and won't know about every atproto
account, so suggestions are only ever a shortcut -- submitting always uses
the typed text, and the sign-in path is unchanged.
Only arrow keys arm Enter-to-select; hover is CSS-only, so a list opening
under a resting cursor can't turn Enter into an accidental OAuth redirect.
TextField gains an optional inputProps spread, needed for autoComplete="off"
(the browser's own autofill would otherwise cover the list) and the ARIA
combobox attributes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Only affects visitors with no stored preference; an explicit light/dark
choice still wins.
The fallback lives in two places — useHandleAppTheme and the pre-React
anti-flash script in index.html. Both had to change, or a first-time visitor
on a dark OS would get a white flash before React mounted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sign-in dialog assumed you already had an Atmosphere account, so a
first-time visitor hit a dead end at the handle field.
Creating an account goes through OAuth: an input starting with https:// is
resolved as a PDS URL rather than a handle, and prompt "create" asks that
server for its sign-up screen. Verified against selfhosted.social, which
lands on "Choose a username" rather than the login form.
Because an Atmosphere identity is shared across every atproto app, the button
opens a confirmation first — most people asking for a new account already have
one via Bluesky, Tangled, stream.place or leaflet.pub, and would only fragment
their data by making a second.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(packages/excalidraw): add `props.interaction` and `props.ui`
* fix: prevent browser zoom when interaction disabled
* changelog
* clean up interactive state on disable and consolidate `viewMode` and interaction state updates
* render UI rendered to `children` even if editor-exported
* support `allowed.navigation` and `allowed.embeds/interactiveContent`
* change naming `allowed` -> `enabled`
* changelog: add PR links
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* clear flowchart sessions via consolidated `app.flowchart` after master merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor getters -> methods
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>