Commit Graph

530 Commits

Author SHA1 Message Date
DarkSky 9b81c6debd feat(core): improve mcp management (#15221)
#### PR Dependency Tree


* **PR #15221** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added MCP credential management (create/reveal, list, rotate, revoke)
with expiration and status tracking.
* Introduced read-only vs read/write access modes, with read/write
tooling enabled only when permitted.
* Added workspace MCP credential configuration UI, including token
reveal and setup generation.
  * Added MCP credential GraphQL APIs to back the UI.
* **Changes**
* Replaced legacy access-token support with MCP credentials across
authentication and realtime updates.
* **Bug Fixes**
* MCP authentication now reliably rejects revoked, rotated, expired, or
disabled-user credentials.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-12 19:30:44 +08:00
DarkSky abf37d3dfa feat(core): improve login flow (#15219)
#### PR Dependency Tree


* **PR #15219** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added secure, automatic auth session token refresh and request replay
for expired-token responses across Android, iOS, and Electron.
* Updated sign-in flows to manage sessions without returning tokens to
the app layer.
* Added “Devices” management UI with sign out per device and sign out
all.
  * Enabled support for both Hashcash and Turnstile captcha providers.
* **Bug Fixes**
* Improved refresh de-duplication, inflight cancellation/clear behavior,
and recovery from corrupted/invalid sessions.
* **Tests**
* Expanded auth-session, refresh/revoke, and replay coverage (Electron
unit tests, Android instrumentation tests, iOS auth date parser tests).
* **Chores**
* Removed CAPTCHA site key from build-time configuration and adjusted CI
test execution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-12 18:11:02 +08:00
DarkSky 9581432d21 feat(core): onenote importer (#15198)
#### PR Dependency Tree


* **PR #15198** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added OneNote import support for `.one`, `.onetoc2`, and `.onepkg`,
including OneNote-to-markdown content conversion.
* OneNote now appears in the import flow with a dedicated label and
format tooltip, and file pickers recognize the new OneNote type.

* **Bug Fixes**
* Import options that are desktop-only are now disabled when not running
in the desktop app, with clear messaging.
* Improved imported asset handling by converting non-image embedded
assets into attachments for more consistent results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-06 06:20:52 +08:00
DarkSky 8d72e4dc29 feat(core): import progress & perf (#15197)
#### PR Dependency Tree


* **PR #15197** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a new import pipeline with “plan then commit” batch handling for
Markdown, Notion HTML, Obsidian, and Bear backups.
* Enabled native import sessions with progress, cancellation, and
batch-by-batch committing (including assets, folders, icons, and tags).
  * Added web preflight limits for ZIP and multi-file imports.
* **Bug Fixes**
* Improved import error/warning reporting and continued processing when
some items fail.
* Strengthened snapshot-based file/directory picking to preserve paths.
* **Chores**
  * Updated project packaging/configuration for the new import workflow.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-06 01:29:24 +08:00
Jachin 477015f064 feat(core): support Notion markdown zip imports (#14910)
## What changed
- Markdown zip imports now resolve local `.md` links like `./test/2.md`
into AFFiNE linked-page references when the target document exists in
the same archive.
- Added Notion Markdown `.zip` import support in the desktop import
dialog, including nested zip traversal, Notion title extraction,
hash-stripped folder names, attachments, and folder hierarchy
integration.
- Added i18n entries and adapter coverage for standard Markdown zip
links and Notion Markdown zip imports.

## Why
Markdown and Notion exports often contain links between notes using
relative `.md` paths. Keeping those as plain URLs makes imported
workspaces harder to navigate, so the importer now preassigns document
ids and rewrites resolvable archive-local markdown links into linked
pages.

## Notes
The markdown zip folder hierarchy implementation now comes from latest
`origin/canary`, so this PR only layers relative-link resolution and
Notion Markdown zip support on top of that upstream behavior.

## Validation
- `yarn vitest --run
blocksuite/affine/all/src/__tests__/adapters/markdown.unit.spec.ts`
- `yarn tsc -b blocksuite/affine/all/tsconfig.json --verbose`
- `git diff --check`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for importing Notion Markdown exports in `.zip` format,
including subpages, attachments, and nested folders.
* Internal links inside imported Markdown now resolve correctly between
pages, preserving link text when available.
* The import dialog now includes a dedicated “Notion (Markdown, .zip)”
option.

* **Bug Fixes**
* Improved filename handling so non-Latin characters in ZIP imports are
preserved correctly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
2026-07-05 04:42:48 +08:00
DarkSky 4a7c931eca fix(server): member loading (#15156)
#### PR Dependency Tree


* **PR #15156** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Fixed Stripe subscription syncing for Team plans to update the correct
existing local subscription (avoiding duplicates) while refreshing
quantity and billing/trial period details.
* **UI/UX Improvements**
* Improved workspace member list loading/error states with shared UI
components and steadier pagination behavior.
  * Refined fallback styling for cleaner, more stable layout.
* **Tests**
* Expanded subscription and projection coverage and adjusted
seat-allocation/e2e assertions to be more robust.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-26 21:29:15 +08:00
DarkSky 81760fd45c chore: cleanup legacy logic (#15072) 2026-06-03 16:20:15 +08:00
DarkSky ce9841df9d feat(server): passkey pre-refactor (#15060)
#### PR Dependency Tree


* **PR #15060** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* OpenApp native sign-in and native session exchange (JWT) for mobile &
desktop.
  * Centralized short-lived auth challenge store for one-time tokens.
* Encrypted per-endpoint token storage and native token handlers
(Android, iOS, Electron).

* **Improvements**
* Richer auth-method reporting (password, magic link, OAuth, passkey)
and improved sign-in flows.
* Hardened magic-link, OAuth, and session issuance; JWT-backed sessions
and websocket JWT support.
* UX tweaks: form-based password submit, OTP autocomplete, adjusted
captcha flow.

* **Bug Fixes**
  * Expanded tests and auth-state resets to avoid cross-test leakage.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-01 17:11:15 +08:00
DarkSky 2aa56cbccd chore: bump toolchain & fix lint 2026-05-24 06:47:17 +08:00
steffenrapp f2980503b4 fix(editor): sorting of page emoji display toggle (#15020)
Fixes the order of the new setting toggle introduced in #14999.
It appeared between "Auto-title new docs with current date" and "New doc
date format" which both belong together.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Repositioned the "display add icon option" setting within General
settings for improved interface organization and logical grouping.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/15020?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-24 00:06:21 +08:00
Waqar Bin zafar d20dbfd6a2 feat(editor): add page emoji display toggle #14987 (#14999)
This PR adds a display toggle for Page Emoji, so users can choose
whether the add emoji option is shown in the page header when no emoji
is set.

What changed
read editor setting for display add icon option
hide emoji placeholder entry when the setting is disabled
keep existing behavior for readonly mode and for pages that already have
an emoji
Why
This implements the feature request to control Page Emoji visibility and
improves header cleanliness for users who prefer a minimal UI.

Issue
Closes #14093
<img width="1277" height="726" alt="Screenshot 2026-05-19 at 3 44 14 PM"
src="https://github.com/user-attachments/assets/caa29272-35c0-410d-bd54-2e038e4e0db2"
/>
<img width="1511" height="779" alt="Screenshot 2026-05-19 at 3 44 35 PM"
src="https://github.com/user-attachments/assets/3504136a-d34c-45cc-992b-0056b018ff92"
/>

Testing
verified in editable mode:
setting ON: add emoji placeholder is visible when page has no emoji
setting OFF: add emoji placeholder is hidden when page has no emoji
verified in readonly mode:
no emoji: nothing shown
with emoji: existing emoji is shown
verified no regression for selecting/changing/removing emoji
Screenshots
I will attach screenshots in this section.

Quick rule checks before submit

Base branch is canary.
PR title follows conventional format: type(scope): subject.
Scope editor is valid for this repo.
Include Closes #14093 in the body.
Add your screenshots before creating or right after opening the PR.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an editor setting to toggle whether the "add icon" option is
shown when creating new documents (default: enabled).
* **User Experience**
* When disabled, the add-icon trigger is hidden for documents that use a
placeholder icon; readonly display remains unchanged.
* **Tests**
  * Updated tests to cover the new setting and toggle behavior.
* **Localization**
* Added translations and updated i18n typings and completeness metrics.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14999?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-20 22:20:12 +08:00
DarkSky 9f33d37add feat(core): integrate realtime features (#15003) 2026-05-20 05:48:03 +08:00
DarkSky e222f06e94 feat(editor): extract chat runtime (#14937)
#### PR Dependency Tree


* **PR #14937** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Centralized AI event system and a runtime powering chat sessions and
actions.

* **Improvements**
* Chat UI (composer, messages, toolbar, tabs, panels) now syncs with
runtime snapshots for more consistent state.
* Improved session/tab lifecycle (create, fork, delete), context
embedding status, and history handling.
* More reliable send/stop/retry flows, better telemetry scoping, and
clearer upgrade/login/insert-template prompts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-13 21:57:50 +08:00
DarkSky a1d150a748 fix(server): realtime module not loaded (#14952)
#### PR Dependency Tree


* **PR #14952** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Optimized workspace invite link fetching by separating it from general
workspace configuration queries for improved performance.
* Reorganized transcription-related backend modules to better separate
concerns and enable real-time functionality.

* **Chores**
* Updated generated GraphQL types and iOS query definitions to reflect
API changes.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14952)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-12 18:54:42 +08:00
DarkSky 417d31cabe fix(core): ui state (#14933)
#### PR Dependency Tree


* **PR #14933** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added draft tab option to AI chat interface
* Introduced "Current document" session history view in chat history
popover
  * Added control to show/hide "New Chat" button

* **Improvements**
  * Enhanced chat history preservation when switching between sessions
  * Prevented duplicate session creation requests
  * Improved message handling during session transitions and generation

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14933)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-09 23:33:37 +08:00
karl-kaefer ac37d07e74 feat(editor): add Bear backup import and markdown zip folder hierarchy (#14599)
## Summary

- Add Bear `.bear2bk` backup importer (TextBundle-based zip format)
- Enhance markdown zip import to preserve folder structure from zip
paths
- Add colored highlight (`<mark data-color="...">`) support to HTML
adapter

### Bear Import Details

Bear backups are zip archives of TextBundle directories. The importer:
- Parses Bear-specific markdown (highlights `==text==`, callouts `>
[!NOTE]`, inline tags `#tag`)
- Extracts creation/modification dates from `info.json` metadata
- Filters out trashed notes
- Converts Bear tags to AFFiNE tags (consolidated by root segment)
- Builds folder hierarchy from nested tag paths (e.g.,
`#work/projects/alpha`)
- Uses JSZip for lazy decompression to handle large backups without OOM

### Markdown Zip Folder Hierarchy

`importMarkdownZip` now returns `{ docIds, folderHierarchy }` instead of
just `docIds[]`, enabling the UI to recreate the zip's directory
structure as AFFiNE folders.

## Related Issues

- Implements the TextBundle-based import approach suggested in #14115 /
Discussion #14142
- Addresses folder structure preservation requested in #10003
- Partially addresses frontmatter metadata import from #11286

## Test Plan

- [ ] Import a Bear `.bear2bk` backup file via the import dialog
- [ ] Verify tags are created and assigned to documents
- [ ] Verify folder hierarchy matches Bear's nested tag structure
- [ ] Verify creation/modification dates are preserved
- [ ] Verify highlighted text and callouts render correctly
- [ ] Verify images and attachments are imported
- [ ] Import a markdown zip with nested folders, verify folder structure
is recreated
- [ ] Verify trashed Bear notes are excluded

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Bear (.bear2bk) backup import: bulk import notes, convert/dedupe tags,
create nested folders, and return imported doc IDs plus folder
hierarchy; UI import option and progress integrated.
* Markdown ZIP import now returns an optional folder hierarchy alongside
created doc IDs.

* **Bug Fixes / Improvements**
* Highlighting: mark elements validate color names, default safely, and
apply consistent background styling.

* **Chores**
  * Added runtime dependency for ZIP handling.

* **Documentation**
  * Added localization strings and i18n accessors for Bear import UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2026-05-07 11:29:40 +08:00
Adarsh Singh 440ff0c342 fix(editor): resolve UX inconsistencies in the AI chat interface (#14850)
# Closes #14189.

Fixes the three UX issues reported in the original bug report, plus one
small
adjacent polish on the right-sidebar toggle that was requested during
review.

Each concern in the issue is addressed end-to-end, with the same
treatment
applied to both places the AI chat panel lives: the **sidebar chat
panel**
(right panel on a doc page) and the **standalone `/chat` page**.

---

## 1. `+` button → persistent multi-session tabs (issue point 1)

**Before:** clicking `+` called `createFreshSession()` (standalone) or
`newSession()` (sidebar), both of which tore down the current chat
content
and replaced it in place. There was no way to keep two chats open at
once.

**After:** a browser/IDE-style tab strip lives above the chat content.
Each
open session gets its own tab with a close `×`; the active tab is
highlighted; `+` now adds a tab rather than replacing the chat.

### Details
- New Lit component `ai-chat-tabs`
([packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts)).
- Tab title is derived from `session.title` → first user message → `"New
chat"`.
- Horizontal scroll when tabs overflow, with a `wheel` handler that
converts
    mouse wheel / trackpad vertical swipe into horizontal scroll (native
horizontal trackpad swipes also work natively via `overflow-x: auto`).
- Auto `scrollIntoView({ inline: 'nearest' })` on active tab change, so
a
newly created or newly selected tab slides into view instead of staying
    hidden behind the toolbar.
- Close `×` removes the tab from the strip but leaves the session on the
server (matches the existing **Chat history** dropdown semantics — the
session is still reachable there). Closing the active tab switches to an
    adjacent one; closing the last tab starts a fresh session.
- Persistence: open session IDs are saved per-workspace in
`localStorage`
under `ai-chat-open-tabs:{workspaceId}`. On mount, the React pages
hydrate
  those IDs via `AIProvider.session.getSession` /
  `CopilotClient.getSession` — no new backend or schema work.
- Wiring: identical effects on both variants
([chat.tsx
(sidebar)](packages/frontend/core/src/desktop/pages/workspace/detail-page/tabs/chat.tsx)
and
[chat/index.tsx
(standalone)](packages/frontend/core/src/desktop/pages/workspace/chat/index.tsx))
  — hydrate → sync active session into tabs → persist.
- The tab strip sits on the same row as the existing toolbar icons
  (pin / history / `+`), separated by `flex: 1` + `min-width: 0` so the
  tabs scroll cleanly up to the toolbar boundary.
- The `ShadowlessElement` base class injects its static CSS globally,
and the
`:host` selector does not match in a React-rooted DOM — the component
uses
  tag-selector CSS (`ai-chat-tabs { display: flex; … }`) instead.

## 2. Drag-and-drop attachments (issue point 2)

**Before:** the chat input accepted no DnD. Attaching anything required
the
`+` → file-picker flow.

**After:** the chat input accepts OS files via native HTML5 DnD and
AFFiNE
documents via the repo's existing pragmatic-drag-and-drop
infrastructure.

### Details
- Native handlers (`dragenter/over/leave/drop`) on

[ai-chat-input.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts)
accept OS files: images go into the image preview grid, other files
become
  attachment chips, with the same 50 MB per-file cap as the `+` picker.
- Internal AFFiNE document drags from the nav panel land as doc chips,
  handled via `dropTargetForElements` from
  `@atlaskit/pragmatic-drag-and-drop` (same library the rest of the app
  already uses for internal DnD).
- A "Drop to attach" overlay appears during drag, reusing the existing
focused-border token (`--affine-v2-layer-insideBorder-primaryBorder`)
for
  visual consistency with the focused state.
- The image/file routing logic that previously lived inline in
  `add-popover.ts` was factored into a shared helper

[attachment-utils.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-chips/attachment-utils.ts)
  (`addFilesToChat`), so the `+` picker and the drop handler stay in
  lockstep.
- Analytics: extended the `addEmbeddingDoc.control` union in
[events.ts](packages/frontend/track/src/events.ts) with `'dragDrop'` so
  drag-originated attachments are distinguishable from button-initiated
  ones in telemetry.
- `@atlaskit/pragmatic-drag-and-drop` is promoted from a transitive
  dependency (via `@affine/component`) to a direct dependency of
  `@affine/core` and `yarn.lock` is refreshed accordingly.

## 3. Chat-history tooltip + icon (issue point 3)

**Before:** hovering the chat-history button showed a tooltip whose
background did not invert for dark theme (`--affine-tooltip` is not
theme-aware), and the icon was `ArrowDownSmallIcon` — a chevron that
does
not convey "history."

**After:** the tooltip primitive itself is theme-aware (every tooltip in
the app benefits, not just the chat one), and the icon is the
semantically-clear `HistoryIcon`.

### Details
- [tooltip.ts](blocksuite/affine/components/src/tooltip/tooltip.ts) now
uses
  `var(--affine-v2-tooltips-background, var(--affine-tooltip))` and
  `var(--affine-v2-tooltips-foreground, var(--affine-white))`. The V2
  tokens auto-invert with theme; the old vars remain as fallbacks so
  components that override via the existing `tooltipStyle` escape hatch
  continue to work.
- Triangle arrow colors updated to use the same V2 token.
-
[ai-chat-toolbar.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-toolbar.ts):
  `ArrowDownSmallIcon` → `HistoryIcon`; added
  `data-testid="ai-panel-chat-history"` for future e2e coverage.

## 4. Right-sidebar toggle: tooltips + open-state icon *(adjacent
polish)*

Not part of the original issue, but surfaced while testing the tab strip
—
neither of the two right-sidebar toggle buttons had hover affordance,
and
both used the same icon regardless of the sidebar's state.

- Added `tooltip="Open sidebar"` on the route-container button shown
when
  the sidebar is hidden.
- Added `tooltip="Close sidebar"` on the sidebar-header button shown
when
  the sidebar is expanded.
- The close button now renders a small inline `RightSidebarOpenIcon`
  variant: same outline as `RightSidebarIcon`, but with the right panel
  filled in the AFFiNE accent color to convey the open state. Icon shape
  change is self-contained — no new icon asset added to
  `@blocksuite/icons`.

---

## Commits

- `2adc0c7` — fix(ai-chat): theme-aware tooltip + semantic chat-history
icon *(2 files)*
- `bf26974` — feat(ai-chat): drag-and-drop file and doc attachments in
chat input *(7 files)*
- `fca29c8` — feat(ai-chat): persistent multi-session tab strip *(8
files)*
- `7d5dffe` — feat(workbench): tooltips and open-state icon for the
right-sidebar toggle *(2 files)*

Kept ordered smallest → largest blast radius so the history is easy to
bisect.

---

## Test plan

Verified locally against a fresh server stack (postgres / redis /
mailpit via
compose, migrations run) signed in as `dev@affine.pro`, in both `/chat`
and
the sidebar chat on a doc page, in light and dark themes:

- [x] Tooltip: hover the chat-history icon in dark mode → tooltip is
dark-on-light; toggle to light mode → tooltip is light-on-dark. Existing
tooltips on other surfaces (slash menu, edgeless, linked-doc) still
render correctly.
- [x] Icon: chat-history button renders the history glyph (clock), not a
chevron.
- [x] Drag-and-drop (OS file): drop a PDF / PNG / TXT onto the input →
overlay shows → chips/images appear; file > 50 MB → rejected silently
(same as `+` picker).
- [x] Drag-and-drop (internal doc): drag an AFFiNE doc from the nav
panel → becomes a doc chip.
- [x] Pin-picker, `+` picker, paste-image — all unchanged.
- [x] Tab strip: first chat auto-becomes a tab on first message; `+`
adds tab; click tab switches chat; `×` removes tab and switches to
adjacent; close last tab → new fresh tab spawns.
- [x] Reload browser → tab strip rehydrates from localStorage with the
same sessions.
- [x] Tab overflow: 12+ tabs → horizontal scroll via trackpad vertical
swipe, trackpad horizontal swipe, and mouse wheel; active tab
auto-scrolls into view on `+` click.
- [x] Right-sidebar: hover both toggle buttons → tooltips appear; open
the sidebar → close button shows the filled right-panel icon.
- [x] `yarn lint:ox` and lint-staged both clean on every commit.

Not verified locally (no local model key configured): the assistant
actually
streams a response. Drop/chip flow is independent of that path.

## Out of scope / follow-ups

- No new unit or Playwright tests — the fixes are visually verifiable
and
  reuse existing reducer / state paths. Happy to add tests if reviewers
  prefer.
- `@affine/native` is not required for the web dev stack; I only built
  `@affine/server-native`. Irrelevant to the PR diff.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Multi-tab chat UI with a tabs component, open/close/switch actions,
and per-workspace persistence/restoration.
  * Drag-and-drop attachments into chat input (files and docs).

* **UI/UX**
  * Tooltip theming moved to v2 variables (includes arrow color).
  * Sidebar toggle/close buttons now show tooltips.
  * “Drop to attach” overlay and updated history icon.

* **Behavior**
  * Unified attachment handling with 50MB validation and toast notices.

* **Analytics**
  * Attachment events record drag-and-drop as a control method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2026-05-07 04:04:43 +08:00
DarkSky eb9cc22502 feat(server): refactor for byok (#14911) 2026-05-07 04:03:14 +08:00
Hana B c5b0057778 fix(core): resolve remaining untranslated doc title case in detail page header (#14820)
fix #14735

This PR fixes a remaining desktop case related to #14467.

The previous fix resolved incorrect translation in navigation panels,
but the detail page header tab title was still passing custom document
titles through `i18n.t()`, causing user-defined titles to be
unexpectedly translated.

### Results


https://github.com/user-attachments/assets/4abad3b9-d5d7-442f-b643-6d9ea63fa741

After:
<img width="2100" height="1722" alt="After"
src="https://github.com/user-attachments/assets/0770eae2-e5c5-4816-8d53-e40a4b52800c"
/>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Updated page title retrieval mechanism in workspace detail page
headers. The title is now sourced directly from the document display
metadata service instead of using the previous derivation method.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-15 14:49:41 +08:00
DarkSky a1ae7d11a3 feat(core): add integration panel test 2026-04-07 02:12:02 +08:00
chauhan_s e3391c0577 feat: redirect account click & OAuth to Calendar settings (#14693)
### PR Description

* clicking a linked calendar account now switches settings to Workspace
Integrations and opens the Calendar settings directly
* calendar OAuth returns now land on Workspace Integrations with the
Calendar settings opened instead of the homepage
* Improves UX by reducing friction when managing calendar integrations

https://www.loom.com/share/49fa5c448ce049659877beb42d7bd81a


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Calendar integration settings can now be opened automatically
(including from OAuth redirects) and workspace settings support a
scroll-to-anchor.
* Integration account rows are now clickable for quick access to
settings.

* **Improvements**
* Enhanced visual feedback with interactive hover and focus states for
integration controls.

* **Tests**
* Added tests covering the OAuth redirect behavior and workspace
settings scroll/open handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <darksky2048@gmail.com>
2026-04-07 02:08:36 +08:00
DarkSky 193ec14ad3 feat(server): synthetic root doc (#14794) 2026-04-06 17:16:34 +08:00
DarkSky 64149d909a feat: follow publish mode if no params 2026-04-05 20:43:09 +08:00
chauhan_s f81abe692d fix(core): shared page mode syncing (#14756)
### Summary
This fixes a few inconsistencies in shared page behavior:
fixes https://github.com/toeverything/AFFiNE/issues/14751
- shared pages now open in the correct published mode when the URL does
not already include ?mode=...
- switching between page and edgeless in shared mode now keeps the URL
query param in sync
- the default Copy Link action now follows the current editor mode
- shared viewers can toggle between page and edgeless mode in readonly
share pages

---

### What Changed
- updated shared page mode resolution to prefer URL mode, with backend
publish mode as fallback
- added query-param syncing for shared page mode changes
- made the default share link copy use:
  - page link in page mode
  - edgeless link in edgeless mode
- allowed EditorModeSwitch to toggle both ways in shared mode
- extracted shared-mode behavior into small hooks to keep share-page.tsx
cleaner

---

### Demo

https://www.loom.com/share/a287172321fb4fc5b94f7c67a39298a9


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Mode switching between page and edgeless no longer blocked by shared
gating; shared pages initialize and respect the resolved editor mode.
* Shared page URLs stay in sync with editor mode and copy-link actions
include/preserve the selected mode.

* **Tests**
* Added tests for publish-mode resolution, query-string mode handling,
and default share-mode behavior.

* **Bug Fixes**
  * Updated shared-page “not found” UI text to match new messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2026-04-05 20:20:58 +08:00
DarkSky b0cc2fd389 feat(editor): improve dated doc creation (#14791)
#### PR Dependency Tree


* **PR #14791** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2026-04-05 17:16:31 +08:00
chauhan_s 558400b7db feat: add auto-date titles for new documents (#14716)
## Summary

Adds an Editor setting to automatically title blank new documents with
the current date.
fixes https://github.com/toeverything/AFFiNE/issues/14709
https://www.loom.com/share/953b4eafcfb247839e977dca6f457229

## What Changed

- Added `Auto-title new docs with current date` under Editor settings
- Added `New doc date format`, shown only when auto-title is enabled
- Supported formats:
  - `DD-MM-YYYY`
  - `MM-DD-YYYY`
  - `YYYY-MM-DD`
  - `Journal style (localized)`
- Kept titles unique by appending duplicate-style suffixes:
  - `2026-03-24`
  - `2026-03-24(2)`
  - `2026-03-24(3)`

## Behavior

- Only applies to blank new docs
- Does not override explicitly provided titles
- Uses the existing journal-style localized formatter for the localized
option

## Implementation Notes

- Extended editor setting schema with:
  - `autoTitleNewDocWithCurrentDate`
  - `newDocDateTitleFormat`
- Added a helper for generating unique date-based titles
- Wired title generation into doc creation middleware
- Synced created titles into doc metadata so uniqueness works
consistently

## Tests

- Added unit coverage for:
  - date title formatting
  - duplicate suffix generation
  - doc creation middleware behavior
  - settings UI behavior


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* General settings: toggle to auto-insert current date into new document
titles; selectable formats: DD-MM-YYYY, MM-DD-YYYY, YYYY-MM-DD, and
localized "journal". Date-format chooser appears only when enabled.

* **Behavior**
* Blank new-docs are auto-populated per chosen format; user-provided
titles are preserved. Auto-generated titles avoid collisions by
appending incrementing suffixes.

* **Localization**
* Added translations for the setting, description, format chooser, and
all format labels.

* **Tests**
* Added UI and unit tests covering formatting, uniqueness, middleware
behavior, and interaction.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-05 17:10:01 +08:00
DarkSky 3912d8d74d fix: lint 2026-04-03 20:10:44 +08:00
DarkSky 8ca3f2d53d fix(core): settings i18n refresh (#14760)
replace #14758


#### PR Dependency Tree


* **PR #14760** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Enhanced language switching to ensure the settings dialog properly
reflects language changes when users update their language preference.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-03 03:37:49 +08:00
DarkSky 233004f867 chore: bump oxlint & enable more supported rules (#14769) 2026-04-03 03:36:52 +08:00
chauhan_s 9cf98d9345 fix: restore kanban scroll in fullscreen mode (#14708)
fixes #14679

This fixes a layout issue where Kanban boards stopped horizontally
scrolling in fullscreen/full-width page mode.

https://github.com/user-attachments/assets/375fb8f7-3652-4207-8f9c-ee4cdae881ad


The root cause was not in the Kanban view itself, but in the page-mode
viewport wrapper. In fullscreen mode, the editor expands to full width,
and the existing display: table wrapper caused the outer editor
container to size from Kanban content instead of the viewport. That
prevented the Kanban scroller from owning horizontal overflow correctly.

### What changed
Keep the fullscreen editor wrapper constrained to the viewport width
Override the page-mode viewport content wrapper from display: table to
display: block only when a fullscreen editor is present
Leave the default/non-fullscreen layout behavior unchanged
### Why this works
With the outer fullscreen wrapper locked to viewport width, horizontal
overflow stays inside the Kanban view, so its existing overflow-x:
scroll behavior works again.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved full-screen editor layout rendering to ensure proper width
and display constraints are applied correctly in full-screen mode.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-27 02:18:55 +08:00
DarkSky bcf2a51d41 feat(native): record encoding (#14188)
fix #13784 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Start/stop system or meeting recordings with Ogg/Opus artifacts and
native start/stop APIs; workspace backup recovery.

* **Refactor**
* Simplified recording lifecycle and UI flows; native runtime now
orchestrates recording/processing and reporting.

* **Bug Fixes**
* Stronger path validation, safer import/export dialogs, consistent
error handling/logging, and retry-safe recording processing.

* **Chores**
* Added cross-platform native audio capture and Ogg/Opus encoding
support.

* **Tests**
* New unit, integration, and e2e tests for recording, path guards,
dialogs, and workspace recovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-22 02:50:14 +08:00
DarkSky 16a8f17717 feat(server): improve oidc compatibility (#14686)
fix #13938 
fix #14683 
fix #14532

#### PR Dependency Tree


* **PR #14686** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Flexible OIDC claim mapping for email/name, automatic OIDC discovery
retry with exponential backoff, and explicit OAuth flow modes (popup vs
redirect) propagated through the auth flow.

* **Bug Fixes**
* Stricter OIDC email validation, clearer error messages listing
attempted claim candidates, and improved callback redirect handling for
various flow scenarios.

* **Tests**
* Added unit tests covering OIDC behaviors, backoff scheduler/promise
utilities, and frontend OAuth flow parsing/redirect logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-20 04:02:37 +08:00
DarkSky 1ffb8c922c fix(native): cleanup deleted docs and blobs (#14689) 2026-03-20 04:00:25 +08:00
chauhan_s 31101a69e7 fix: Refine verify email dialog for verify and change email flows (#14671)
### Summary
This PR improves the verify email dialog by giving the verify-email and
change-email flows distinct messaging instead of reusing the same
generic copy.

### What changed
* Use flow-specific body copy in the verify email dialog
* Keep the existing action-specific subtitle behavior for:
  * Verify email
  * Change email
* Update the English i18n strings so each flow explains the correct
intent:
  * Verify email focuses on confirming email ownership
  * Change email focuses on securely starting the email-change process
### Why
The previous dialog message was shared across both flows, which made the
change-email experience feel ambiguous. This update makes the intent
clearer for users and better matches the action they are taking.



https://www.loom.com/share/c64c20570a8242358bd178a2ac50e413


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved clarity in email verification and email change dialog
messages to better explain the confirmation process and link purpose.
* Enhanced distinction between email verification and email change
workflows with context-specific messaging.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-17 23:28:16 +08:00
Francisco Jiménez 0b1a44863f feat(editor): add obsidian vault import support (#14593)
fix #14592 

### Description
> 🤖 **Note:** The code in this Pull Request were developed with the
assistance of AI, but have been thoroughly reviewed and manually tested.

> I noticed there's a check when opening an issue that asks _"Is your
content generated by AI?"_, so I mention it here in case it's a deal
breaker. If so I understand, you can close the PR, just wanted to share
this in case it's useful anyways.

This PR introduces **Obsidian Vault Import Support** to AFFiNE. 

Previously, users migrating from Obsidian had to rely on the generic
Markdown importer, which often resulted in broken cross-links, missing
directory structures, and metadata conflicts because Obsidian relies
heavily on proprietary structures not supported by standard Markdown.

This completely new feature makes migrating to AFFiNE easy.

**Key Features & Implementations:**

1. **Vault (Directory) Selection**
- Utilizes the `openDirectory` blocksuite utility in the import modal to
allow users to select an entire folder directly from their filesystem,
maintaining file context rather than forcing `.zip` uploads.

2. **Wikilink Resolution (Two-Pass Import)**
- Restructured the `importObsidianVault` process into a two-pass
architecture.
- **Pass 1:** Discovers all files, assigns new AFFiNE document IDs, and
maps them efficiently (by title, alias, and filename) into a
high-performance hash map.
- **Pass 2:** Processes the generic markdown AST and correctly maps
custom `[[wikilinks]]` to the actual pre-registered AFFiNE blocksuite
document IDs via `obsidianWikilinkToDeltaMatcher`.
- Safely strips leading emojis from wikilink aliases to prevent
duplicated page icons rendering mid-sentence.

3. **Emoji Metadata & State Fixes**
- Implemented an aggressive, single-pass RegExp to extract multiple
leading/combining emojis (`Emoji_Presentation` / `\ufe0f`) from H1
headers and Frontmatter. Emojis are assigned specifically to the page
icon metadata property and cleanly stripped from the visual document
title.
- Fixed a core mutation bug where the loop iterating over existing
`docMetas` was aggressively overwriting newly minted IDs for the current
import batch. This fully resolves the issue where imported pages
(especially re-imports) were incorrectly flagged as `trashed`.
   - Enforces explicit `trash: false` patch instructions.

4. **Syntax Conversion**
- Implemented conversion of Obsidian-style Callouts (`> [!NOTE] Title`)
into native AFFiNE block formats (`> 💡 **Title**`).
- Hardened the `blockquote` parser so that nested structures (like `> -
list items`) are fully preserved instead of discarded.

### UI Changes
- Updated the Import Modal to include the "Import Obsidian Vault" flow
utilizing the native filesystem directory picker.
- Regenerated and synced `i18n-completenesses.json` correctly up to 100%
across all supported locales for the new modal string additions.

### Testing Instructions
1. Navigate to the Workspace sidebar and click "Import".
2. Select "Obsidian" and use the directory picker to define a
comprehensive Vault folder.
3. Validate that cross-links between documents automatically resolve to
their specific AFFiNE instances.
4. Validate documents containing leading Emojis display exactly one
Emoji (in the page icon area), and none duplicated in the actual title
header.
5. Validate Callouts are rendered cleanly and correctly, and no
documents are incorrectly marked as "Trash".


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Import Obsidian vaults with wikilink resolution, emoji/title
preservation, asset handling, and automatic document creation.
* Folder-based imports via a Directory Picker (with hidden-input
fallback) integrated into the import dialog.

* **Localization**
  * Added Obsidian import label and tooltip translations.

* **Tests**
* Added end-to-end tests validating Obsidian vault import and asset
handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
2026-03-17 00:49:17 +08:00
DarkSky c5d622531c feat: refactor copilot module (#14537) 2026-03-02 13:57:55 +08:00
DarkSky 6d805b302c docs: cleanup outdated infos 2026-02-23 21:03:13 +08:00
DarkSky da57bfe8e7 fix: enhance MCP token handling (#14483)
fix #14475 

#### PR Dependency Tree


* **PR #14483** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Enhanced MCP server token management with improved security—tokens now
display only once with redaction support.
* Updated token creation and deletion workflows with clearer UI state
controls.
* Added tooltip guidance when copying configuration with redacted
tokens.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-21 04:14:14 +08:00
DarkSky d8cc0acdd0 chore: update flags 2026-02-19 10:18:43 +08:00
Neo 35e1411407 fix: docTitle unexpectedly translated (#14467)
fix #14465

In Chinese mode, the document with the specified name may not be
displayed correctly in the sidebar, and it may be mistaken for the
translation of the content that needs to be translated.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed document title display in navigation panels on desktop and
mobile to properly render without additional processing steps.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-17 13:45:31 +00:00
DarkSky 728e02cab7 feat: bump eslint & oxlint (#14452)
#### PR Dependency Tree


* **PR #14452** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved null-safety, dependency tracking, upload validation, and
error logging for more reliable uploads, clipboard, calendar linking,
telemetry, PDF/theme printing, and preview/zoom behavior.
* Tightened handling of all-day calendar events (missing date now
reported).

* **Deprecations**
  * Removed deprecated RadioButton and RadioButtonGroup; use RadioGroup.

* **Chores**
* Unified and upgraded linting/config, reorganized imports, and
standardized binary handling for more consistent builds and tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-16 13:52:08 +08:00
DarkSky c0694c589b fix: editor style (#14440)
#### PR Dependency Tree


* **PR #14440** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Refined CSS styling rules in workspace detail pages for improved
layout rendering consistency.
* Enhanced editor container display handling during loading states to
ensure proper layout adjustments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-14 19:12:24 +08:00
DarkSky 2b71b3f345 feat: improve test & bundler (#14434)
#### PR Dependency Tree


* **PR #14434** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced rspack bundler as an alternative to webpack for optimized
builds.

* **Tests & Quality**
* Added comprehensive editor semantic tests covering markdown, hotkeys,
and slash-menu operations.
* Expanded CI cross-browser testing to Chromium, Firefox, and WebKit;
improved shape-rendering tests to account for zoom.

* **Bug Fixes**
  * Corrected CSS overlay styling for development servers.
  * Fixed TypeScript typings for build tooling.

* **Other**
  * Document duplication now produces consistent "(n)" suffixes.
  * French i18n completeness increased to 100%.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-14 16:09:09 +08:00
DarkSky 72df9cb457 feat: improve editor performance (#14429)
#### PR Dependency Tree


* **PR #14429** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* HTML import now splits lines on <br> into separate paragraphs while
preserving inline formatting.

* **Bug Fixes**
* Paste falls back to inserting after the first paragraph when no
explicit target is found.

* **Style**
  * Improved page-mode viewport styling for consistent content layout.

* **Tests**
* Added snapshot tests for <br>-based paragraph splitting; re-enabled an
e2e drag-page test.

* **Chores**
* Deferred/deduplicated font loading, inline text caching,
drag-handle/pointer optimizations, and safer inline render
synchronization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-14 00:43:36 +08:00
DarkSky b4be9118ad feat: doc status & share status (#14426)
#### PR Dependency Tree


* **PR #14426** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Admin dashboard: view workspace analytics (storage, sync activity, top
shared links) with charts and configurable windows.
* Document analytics tab: see total/unique/guest views and trends over
selectable time windows.
* Last-accessed members: view who last accessed a document, with
pagination.
* Shared links analytics: browse and paginate all shared links with
view/unique/guest metrics and share URLs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-13 01:01:29 +08:00
DarkSky 944fab36ac feat: drop outdated session (#14373)
#### PR Dependency Tree


* **PR #14373** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added client version tracking and validation to ensure application
compatibility across authentication flows and sessions.
* Enhanced OAuth authentication with improved version handling during
sign-in and refresh operations.

* **Bug Fixes**
* Improved payment callback URL handling with safer defaults for
redirect links.

* **Tests**
* Expanded test coverage for client version enforcement and session
management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-05 21:35:36 +08:00
DarkSky a655b79166 feat: basic caldav support (#14372)
fix #13531 

#### PR Dependency Tree


* **PR #14372** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* CalDAV calendar integration: link and sync CalDAV-compatible calendars
(discovery, listing, event sync).
* New UI flow and dialog to link CalDAV accounts with provider
selection, credentials, and display name.

* **API / Config**
* Server exposes CalDAV provider presets in config and new GraphQL
mutation to link CalDAV accounts.
  * New calendar config section for CalDAV with validation and defaults.

* **Tests**
  * Comprehensive CalDAV integration test suite added.

* **Chores**
* Removed analytics tokens from build configuration and reduced Cloud
E2E test shards.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-05 03:04:21 +08:00
DarkSky 403f16b404 chore: drop old client support (#14369) 2026-02-05 02:49:33 +08:00
DarkSky 516d72e83f fix: lint & lockfile 2026-02-02 10:35:52 +08:00
Gabriele 1f94d7d1bc Merge commit from fork 2026-02-01 22:05:19 +08:00