* feat(memos): duplicate a note with its files
Add "Duplicate note" to the note list's context menu and the text editor's
"More note actions" menu. The copy keeps the note's content and tags, is
titled "<title> (copy)" in the UI language, and opens in the editor.
POST /api/v1/memos/:id/duplicate (write:memos) copies every image and
attachment of the note to a new resource with its own stored object and
rewrites the content to reference the copies, so editing or deleting either
note never affects the other. Shares, revisions, the pinned state, public
form links and unsubmitted form uploads are not copied. A note with more
than 20 files or more than 64 MiB of files is refused, and files written for
a copy that fails are removed.
The Web and desktop clients synchronize the note's queued changes before
duplicating and refuse while any remain, including unresolved conflicts;
the editor item stays disabled until the current edit is saved.
* fix(memos): keep committed duplicate files and check the whole desktop outbox
- Copied objects are removed only when the write batch fails. A failure
after the commit, such as a transient error while reading the new memo,
no longer deletes files that committed resource rows reference. When the
memo row is missing after the commit (its notebook was removed meanwhile),
the rows are removed before their objects.
- The sidecar lists at most 200 outbox items, so a conflict of the note
further down the queue was invisible and the stale server version could be
copied. The desktop client now compares the listed items with the
sidecar's status counts and refuses to duplicate unless the whole
outstanding queue was listed, nothing is being synchronized, and no item
belongs to the note.
- Regression tests cover a read failure after the commit and a target
conflict at position 201 behind 200 other conflicts.
* feat(templates): show unedited default templates in the current UI language
Default templates are stored in the language of the workspace's first
sign-in, so switching the UI language left them in that language. While a
default template still equals one of its seeded translations, the web
template center and the Android template picker now show it in the current
UI language, and using it creates the note in that language. Templates the
user created or edited are shown and used exactly as stored.
POST /api/v1/templates/:id/use accepts an optional `locale`; without it the
stored template is used as before, so MCP, agents and older clients are
unaffected.
* fix(templates): edit the stored template and stop localizing retagged defaults
- The template center now keeps each card's stored template next to its
display translation. Editing starts from the stored fields, so saving a
name-only change in another UI language no longer writes the translated
title, description and Markdown.
- A default template whose tags differ from its seeded tags is treated as
edited and is no longer localized.
- Add regression tests for the name-only edit and changed tags.
Add notebook-level share management, directory navigation, and live subtree checks for notes and attachments. Include migration and access-boundary regression tests.
Refs #551
Preserve HTTP status and fixed failure categories for direct and proxied agent requests, display diagnostics beside failed turns, and prevent AI SDK error logging from exposing request data.
Refs #555
Add owner-only attachment summaries and a compact member management table. Keep personal attachment statistics unchanged and exclude Trash from usage totals.
Refs #553
Align editor, AI SDK, query, and Expo SDK 57 dependencies; pin floating versions and rebase the Mermaid and Android sharing patches. Refresh the standalone iOS editor bundle and migrate site content collections while preserving routes.
Validation: typechecks for Web/API, Android, and iOS editor; Web, site, iOS editor, Worker, Docker server, extension, and Android APK builds; 2,994 tests passed, 23 skipped. Built-in browser verified rich-text paste/undo and bilingual site navigation.
USB-device upgrade/data/share verification and desktop cross-version release gates remain pending. Remaining dependency audit advisories are not all resolved.
Video notes keep a hidden marker, and the note list can queue subtitle extraction. The desktop app downloads the audio with yt-dlp and sends it to the selected OpenAI-compatible speech service.
Official entries stay on the bundled registry. The instance returns a community file only when EDGE_EVER_COMMUNITY_REGISTRY_URL is set, and submission opens from its own marketplace entry.
Notes open a right-hand assistant that can attach files and asks before changing note content. Desktop can talk to a local ACP agent without handing over the note directory.
Keep the native editor theme, store column width on this device, and publish account font size, line height, palette, and custom CSS to the editor, public shares, and WeChat paste. Highlight custom CSS with CodeMirror.
Store attachment files in object storage and keep only resource references in the table. A separate public form link appends one row without showing existing records.
Store the selected built-in note font on the account and apply it to the shared note body. System and custom font names keep the default face, so a share downloads a font only after one is chosen.
Allow owners to turn on an auto-generated access password when sharing a note. Visitors must unlock the share page before reading the note or its attachments; existing public links stay open until a password is enabled.
Keep Cloudflare requests short for Agent, tag suggestions, plugin generate, and Paw checks. The instance only prepares credentials and executes tools; CORS failures still fall back to the existing proxy.
Show tool receipts in chat, pin notes with @, wire saved memory, and
let interrupted Agent turns continue. Split tool-side narration from
the user-facing answer.
Keep plugin and theme membership on the workspace so browsers and desktop apps can re-download verified packages. Settings, secrets, and native mobile runtimes stay out of this catalog.
Related Issue: #396
Desktop, Android, and iOS call the configured model API after a short prepare hop so Cloudflare no longer sits in the token path. The web app probes CORS first and direct-connects only when the host allows it; blocked hosts keep using the instance proxy without downloading the API key.
Add a bulk Markdown ZIP action for selected notes, reuse the existing
readable export layout, and keep the desktop bulk action card visible
when a diagram note is open.
Read the latest Release through the instance (cached 5 minutes),
then the public latest/download URL and raw.githubusercontent.com.
Do not treat one plugin's 403 as a total update-check failure.
Prefer the GitHub API asset-id route after the public release URL fails, and skip re-downloading official plugin packages when the live version already matches.
Desktop install was failing with Failed to fetch because the renderer
fetched GitHub metadata directly. Resolve live official releases and
download Release assets via the current EdgeEver instance, so daily
plugin updates still work without a client-side GitHub API round trip.