github usememos/memos 26.10.0

3 hours ago

Memos 26.10.0 adds a rich editor that shows a memo as it will look while you write, per-user usage limits, and declarative configuration for operators. Browsing, Markdown rendering, sign-in, security, and the server improve throughout, and releases now use calendar versions.

Highlights

  • Editor: Memos opens in a rich editor by default: text looks the way the saved memo will, with a toolbar over selected text, a slash menu, and Markdown shortcuts. Markdown mode in the + menu keeps the raw text, now saved to your account under Settings › Editor; focus mode opens a narrower sheet with larger text. (#6466, #6481, Markdown mode, #6498, #6512, Markdown mode label, editor 26.10.30, focus mode)
  • Suggestions and transcription: New drafts suggest tags, checklist formatting, and visibility from the current filters or View. Transcribe an existing audio attachment into the draft with the configured provider. (#6367, #6375)
  • Browse by creator or Space: Pick a creator or a Space once in the sidebar and Timeline, Calendar, Map, and Attachments all show it. Home, Explore, and profile pages are one place now. (#6378)
  • Filter by attachments: has_attachments and has_image select memos with files or pictures, in Views, Quick Find, and the API. (#6492)
  • Choose a Space while writing: The editor's visibility control is now an audience menu: pick who can read the memo, then the Space it belongs to, or none. It works when editing too, so a memo moves between Spaces from the same menu. (Space selection, audience menu)
  • Usage limits: The memo length and upload size caps, previously two instance settings, are now one feature with two more metrics: memo count and total storage. Settings › Usage limits holds an ordered list of entries; the last entry is the default for everyone, and an entry above it gives the users it names their own limits. A refused save or upload names the limit it hit, and nothing already stored is hidden or removed. My Account shows your usage. (#6456, #6472, defaults and targets, upload size)

Fixes and polish

  • Markdown: Tables fill the width with a tinted header and wrap at words. Footnotes collect at the end of a memo with backlinks. Quotes and callouts hold lists, inline HTML such as <ruby> renders again, collapsible sections and heading sizes are consistent between editing and reading, and Bilibili players embed. Check all and Uncheck all reach tasks inside quotes and nested lists. (tables and footnotes, quotes and callouts, inline HTML, #6364, disclosure spacing, Markdown layout, #6404, #6490, #6508)
  • Code and diagrams: Mermaid diagrams follow the theme and fit the memo's width, labels on custom fills stay readable in dark mode, and pie, git, and timeline palettes follow Mermaid's theme variables; code highlighting is lighter. (Mermaid, highlighting, library update)
  • Images and attachments: Pinch to zoom, pan, and swipe between images; arrow keys switch items again and the full-screen preview has square corners. Attachments open in a new tab with a separate download button, controls stay on screen on mobile, files load on plain HTTP instances, and names containing %, ?, or # download and share correctly. (#6414, #6448, preview navigation, #6496, #6401, HTTP attachments, #6506)
  • Memos and filters: Pinned memos get a clearer marker in single-creator feeds. New memos keep their place after an immediate edit and take the time of saving under a date filter. has_task_list == false matches memos without the property, constant operands no longer shift later filter conditions, deleting a memo removes its whole comment thread, and blurred content stays out of the detail sidebar. (#6369, pin ordering, #6451, #6457, #6382, folded operands, #6424, #6494)
  • Interface: Refreshed logo and brand copy. Menus, dialogs, and controls share one surface style with visible focus; sidebar menus stay anchored while scrolling, submenus stay on screen in narrow viewports, dialogs restore default focus, toasts follow the theme, the composer renders with the Home page, the sidebar switcher shows the Space mark beside the creator, and a memo's timestamp links to it. Link previews and double-click to edit are per-browser choices under Settings › Preferences › This device. (logo, brand copy, #6417, shared controls, #6474, submenu positioning, #6279, #6377, #6402, Home composer, Space mark, memo links, device preferences)
  • Languages and link previews: Norwegian Nynorsk is available, the Korean hidden-content label is neutral, and previews of large pages find their title and image more reliably. (#6394, Korean wording, preview metadata)

Administration and integrations

  • Declarative configuration: Describe identity providers, instance settings, bootstrap users, and their SSO identities in JSON files under /etc/memos/config (--config-dir, MEMOS_CONFIG_DIR). The server applies the directory at startup, or memos config validate | plan | apply | state does it from the command line, so a fresh instance is usable without a browser and staging can match production. Resources the files manage show "Managed by configuration" in Settings and cannot be changed through the UI or API until the file releases them; secrets come from ${env:NAME} and ${file:/path}. (#6507, linked identities)
  • Export: Exporting an account's memos is now an administrator action that streams the archive straight to the download, so large archives no longer depend on server memory. Administrators export any account from Settings › Members or Export & Import; members ask an administrator for their archive. Import is unchanged. (#6514)
  • Sign-in: With passwords disabled and a single SSO provider, sign-in starts SSO automatically and returns you to the page you wanted. Identity providers are validated when created or changed. (#6450, SSO loading state, #6507)
  • Server and security: The HTTP layer runs on the Go standard library with unchanged routes and behavior; report any difference behind your reverse proxy. The last admin cannot be removed, /healthz reports database outages, the admin's username is hidden from anonymous requests, outbound fetches refuse the CGNAT range, token store failures no longer appear as 401, authorization errors are JSON, hidden paths such as /.well-known/ return 404, and MariaDB works. Go and gRPC are updated for CVE-2026-78669 and CVE-2026-84445. (#6475, #6454, #6491, #6256, #6461, #6504, hidden paths, #6497, #6462, #6453)
  • API and MCP: ListAttachments uses the shared opaque page token and returns one only when more results exist. The MCP reaction tool no longer shows a redundant parent argument beside its path. (#6452, page token, MCP reaction tool)
  • Release numbering: Versions are YY.MM.N, such as 26.10.0, with -rc.K for candidates and no v prefix. Stable images also publish the month tag (26.10) and stable; candidates publish only their own tag. (#6362, #6469, development versions)

Upgrade notes

  • Upgrade path: Run 0.31.0 once before installing this release if you are on anything older. Versions before 0.22 go through 0.25.3 first. 0.31.0, 26.10-rc.1, and 26.10.0-rc.2 upgrade directly; fresh installs need nothing. (#6362)
  • Everyone signs in again: Access tokens are tied to the account password. Cached access tokens expire on upgrade, and a password change or admin reset signs the account out elsewhere. Browser sessions renew silently; API clients that hold access tokens must refresh or sign in again. Personal access tokens are unaffected. (token binding)
  • Upload size and memo length: The two instance settings are gone and their values are not carried over. The built-in default is 8 KiB per memo and 32 MiB per file with no count or storage limit; set the all-users entry under Settings › Usage limits if you had changed the old caps. (#6456, upload size)
  • /etc/secrets is no longer read: The deployment configuration files introduced in 0.31.0 (memos-idp-*.json, memos-instance-setting-*.json) are ignored, and the database values they overrode take effect again. Move those resources into a configuration directory as memos.api.Configuration documents, keep the same identity provider UID so linked accounts keep working, and run memos config plan to preview before the first start. (#6507)
  • Export is an administrator action: The Export button is gone for members, and the ExportMemos API is removed. Administrators download any account's archive; the archive content and the import flow are unchanged. (#6514)
  • Removed options: Double-click to edit is a per-browser preference, and the composer's formatting toolbar preference, the built-in Tasks View (use a View with has_task_list && has_incomplete_tasks), and the Move to Space action (use the audience menu) are removed. The editor opens in rich mode; turn on Markdown mode under Settings › Editor to keep writing raw Markdown, as the old per-browser choice is not carried over. (device preferences, #6466, Tasks View, audience menu, #6512)
  • Demo mode: The seeded demo no longer ships a public access token or fixed user ids; its content attaches to users declared in the configuration directory, or to the same four demo users as before when none is declared. (demo seed)
  • API clients: Update paths and renamed fields; binary protobuf clients regenerate from the new schema. The full list below is the API changelog. (#6447)

Breaking API changes

  • UserService.ExportMemos and ExportMemosRequest are removed. Export is an instance-administrator download at
    GET /file/users/{username}/export, authenticated like attachments (Bearer header or session cookie), streaming the
    archive with Content-Disposition. One export runs at a time per instance; a second request receives 429. Members
    ask an administrator for their archive. ImportMemos is unchanged.
  • Access tokens are now bound to the user's password hash and become invalid immediately after a password change or
    an administrator password reset. Pre-upgrade access tokens are also rejected; clients must refresh them or sign in
    again. The browser session that changes its own password can still refresh; other refresh sessions are revoked.
  • Usage limits replace the instance-wide upload size and memo content caps. StorageSetting.upload_size_limit_mb
    and MemoRelatedSetting.content_length_limit are removed and old values are not migrated. The limits are the
    USAGE_LIMITS instance setting, instance/settings/USAGE_LIMITS, an ordered list of entries read and replaced whole
    through GetInstanceSetting and UpdateInstanceSetting; the first entry naming a user applies, the last entry
    applies to all users. The usageLimits/{usage_limit} resource and its five RPCs do not exist. UserUsage returns
    the limit set in effect as limits plus limit_index. Exceeding a limit returns RESOURCE_EXHAUSTED with reason
    QUOTA_EXCEEDED and metadata metric, limit, and usage.
  • MemoRelatedSetting.enable_double_click_edit is removed; double-click editing is now a per-browser preference in
    the web client and is no longer an instance setting. MemoRelatedSetting keeps the single field reactions = 1.
  • The deployment configuration files under /etc/secrets (memos-idp-*.json, memos-instance-setting-*.json)
    introduced in v0.31.0 are no longer read, and the stored values they overrode take effect again. Identity providers,
    instance settings, bootstrap users, and their linked identities are declared instead as memos.api.Configuration
    documents in the configuration directory (--config-dir or MEMOS_CONFIG_DIR, default /etc/memos/config), applied
    at startup unless --config-apply=off, or through memos config plan and memos config apply. Keep an identity
    provider's UID when moving it so linked accounts keep working. An API write that changes a field a file manages
    returns FAILED_PRECONDITION with ErrorInfo{reason: MANAGED_BY_CONFIGURATION} naming the file and fields;
    GET /api/instance/configuration (administrators) lists what is managed.
  • CreateIdentityProvider and UpdateIdentityProvider validate the provider as it will be stored and return
    INVALID_ARGUMENT when it has no title, an invalid identifier_filter, no client_id, a non-absolute or non-HTTP(S)
    auth_url, token_url, or user_info_url, an empty scope entry, or no field_mapping.identifier. A request that
    omitted config or field_mapping previously failed with INTERNAL.
  • UpdateInstanceSetting for STORAGE requires every new or changed S3 storage to have endpoint, region, bucket,
    access_key_id, and access_key_secret (an empty secret still keeps the stored one). For GENERAL,
    week_start_day_offset must be between -1 and 6. BASIC cannot be written. Notification validation errors name
    fields in proto form (smtp_host, use_tls).
  • The API no longer carries a v1 version marker. Every client must update its paths:
    • REST routes move from /api/v1/... to /api/... (for example GET /api/memos). Server-sent events move from
      /api/v1/sse to /api/sse.
    • The proto package memos.api.v1 is now memos.api, so Connect and gRPC procedures move from
      /memos.api.v1.<Service>/<Method> to /memos.api.<Service>/<Method>.
    • Resource types move from memos.api.v1/<Type> to memos.api/<Type>.
    • The domain of google.rpc.ErrorInfo details is now memos.api.
    • For this release only, requests to /api/v1/... and /memos.api.v1.* return 410 Gone with an UNIMPLEMENTED
      error that points here. The next release removes these routes.
  • Field numbers in every message are renumbered from 1 in declaration order, and all reserved ranges are removed.
    JSON field names are unchanged; clients that use the binary protobuf encoding must regenerate from the new schema.
  • Enum values are renumbered from 0 in declaration order, including User.Role (ADMIN = 1, USER = 2) and
    UserSetting.Key (GENERAL = 1, WEBHOOKS = 2, TAGS = 3). Clients that send numeric enum values must update them.
  • Names now follow AIP conventions:
    • MemoService: ListMemoAttachments, ListMemoRelations, ListMemoComments, CreateMemoComment,
      ListMemoReactions, and UpsertMemoReaction take parent instead of name (REST path variable
      {parent=memos/*}). ListMemoCommentsResponse.memos is now comments. The nested MemoRelation.Memo type is
      now MemoRelation.MemoRef. The MemoShare resource singular/plural is now memoShare/memoShares.
    • UserService.ListAllUserStats is now ListUserStats. It requires a parent: users/- for all users (REST
      GET /api/users/-/stats instead of GET /api/users:stats) or users/{user} for one user. The response field
      stats is now user_stats.
    • BatchGetUsersRequest.usernames is now names and takes resource names (users/{user}), not bare usernames.
    • PersonalAccessToken.created_at, expires_at, and last_used_at are now create_time, expire_time, and
      last_use_time.
    • LinkedIdentity.idp_name and extern_uid are now identity_provider and external_uid;
      CreateLinkedIdentityRequest.idp_name is now identity_provider.
    • The MemoView and UserNotification resource singulars are now memoView and userNotification.
    • UserStats.tag_count is now tag_counts.
    • MemoImportPlan, MemoImportReport, and MemoImportIssue are now ImportMemosPlan, ImportMemosReport, and
      ImportMemosIssue. ImportMemosPlan.memos and attachments are now memo_count and attachment_count;
      ImportMemosIssue.memo is now memo_uid.
    • UserNotification.SpaceInvitationPayload.State is now InvitationState.
    • UpdateUserSettingRequest.setting and ListUserSettingsResponse.settings are now user_setting and
      user_settings; UpdateInstanceSettingRequest.setting and BatchGetInstanceSettingsResponse.settings are now
      instance_setting and instance_settings.
    • SignInResponse.access_token_expires_at and RefreshTokenResponse.expires_at are both now
      access_token_expire_time.
    • SignInRequest.SSOCredentials is now SsoCredentials, and its idp_name is now identity_provider.

New Contributors

Full Changelog: v0.31.0...26.10.0

Don't miss a new memos release

NewReleases is sending notifications on new releases.