Repository navigation
cloud: v0.37.0
0.37.0 (2026-10-10)
⚠ BREAKING CHANGES
- mail: let conversations have several assignees and grant access to assigned conversations only (#830)
Features
- ai: show charts directly in the chat without building an app (#847) (18a129d)
- capabilities: let apps word their own approval and receipt sentences (#846) (cc5a4d6), closes #811
- cloud: let apps ship their own Assistant skills (#840) (d0b1ac6)
- cloud: show Help only to people who may open the app (#827) (cce4f28)
- dashboard: stream widgets in as they load instead of failing the whole board (#831) (e7ff2ce)
- mail: let conversations have several assignees and grant access to assigned conversations only (#830) (631c73a)
- spaces: remove the timeline view (#798) (ca4f890)
- spaces: select days, create over a range, and show long events as one bar in the month view (#826) (ed10713)
- ui: mark today in every date picker (#839) (de47b30)
Bug Fixes
- ai: keep code runs from failing while they wait for an approval (#832) (cbdaa0f)
- notebooks: count lines through a mirror file as the file shows them, in cat and edit (#802) (de3f6d2)
- ui: keep busy buttons at their width and name them by their loading label (#845) (1bd875a)
- ui: show bare dialogs on iPad instead of only blurring the page (#799) (285b00f)
Performance Improvements
Operator notes
TL;DR: This release contains a security fix. Update promptly, starting with Core. Since Help arrived in 0.7.0, anyone who could reach an installation could read the Help of every registered application without signing in, including administrator-only applications (#827). Help now requires sign-in and shows each person only the applications they may open. Two further changes need preparation. Mail breaks its assignee API (#830): a conversation can have several assignees, the single assignee fields are gone without an alias, saved Mail workflows that read inputs.conversation.assigneeUserId fail at that step, and platform administrators without a mailbox grant no longer get Mail's reminders and notices. Update third-party callers together with Mail and roll all Mail replicas over at once. Core's first start migrates Assistant Skills one way (#840): built-in Skills now ship with their apps. Back up the database right before the update, because going back to an older Core means restoring that backup. There are no new environment variables and no Compose changes, the release has the same 27 images, and the JetStream reservation does not change. Run cld plugins update --all afterwards. Nine PRs are in the tag but missing from the changelog above (see "Also in this release"). If you skipped 0.35.0, its security notes still apply: update the gateway first (see cloud-v0.35.0). If you skipped 0.36.0, Core also builds two send-log search indexes in the background on its first start (see cloud-v0.36.0).
Reference pages at this tag: Help requires sign-in, Who can read Help, Mail conversations have several assignees, Upgrade Mail to several assignees, Assign conversations and limit access to them, Apps ship their own Assistant Skills, Assistant Skills after the upgrade, Dashboard widgets stream in one by one, Identity key operations.
Security
- Help could be read without signing in. This is fixed (#827). The Help API
/api/help/v1/...and the full-page Help at/help/apps/<app>[/<topic>]used a role check that never rejects. Anyone who could reach Cloud could search and read the full Help of every registered application, including Gateway Ops and the accounts and Core administration. Signed-in people, MCP connectors and the Assistant's Help tools could also read the Help of applications they may not open.- What was exposed: Help text and which applications are installed, no user data. The Help of the built-in applications is the same text as in this public repository. If you run in-house or third-party applications whose Help describes internal operations, treat that text as known, and check your reverse proxy's access logs for requests to
/api/help/v1/and/help/apps/from unexpected sources. - Update Core first. Core serves the Help API and the full-page Help, so the new Core ends access without sign-in. The other images of this release carry the remaining parts of the fix.
- Third-party applications keep their own Help routes. An application that mounts the legacy
defineHelpCollection()router serves that Help without sign-in, unless the application guards those routes itself, until it is rebuilt on@k2b/cloud0.30.0, and even then the router only requires sign-in and does not hide the Help from people who may not open the application. Help that an application renders on its own pages follows those pages' access rules. Updating Core changes neither, so ask the authors to move todefineHelp(). No built-in application mounts that router. - Now: without sign-in,
/api/help/v1/...answers401, and/help/apps/...and/app/<id>/helplead to sign-in, so links to Help from outside Cloud ask for sign-in first. OAuth clients of the Help API need thereadoradminscope, as for MCP. A person sees Help only of the applications they may see:nav.requiresRoleslimits Help like the navigation link, an application reached only through the administration shows Help only to administrators, and a service account without a delegated user gets no Help. Guests keep the Help of applications open to guests. Weather now declares that it needs a full account, as its pages already did, so guests no longer see its link or Help. Nothing needs to be configured or migrated.
- What was exposed: Help text and which applications are installed, no user data. The Help of the built-in applications is the same text as in this public repository. If you run in-house or third-party applications whose Help describes internal operations, treat that text as known, and check your reverse proxy's access logs for requests to
Breaking: Mail assignees and assigned-only access
- What people get (#830): a conversation can have up to 20 assignees. Next to View, Edit and Manage, a mailbox grant for a person or group can be View assigned only or Edit assigned only (German Nur zugewiesene ansehen and Nur zugewiesene bearbeiten). Such people see only the conversations currently assigned to them; everything else answers 404. With Edit assigned only they can reply, forward, draft, schedule sends, move, delete, tag from the catalog and snooze those conversations, but they can never compose new mail, assign anyone, merge or split, or manage tags, folders and settings. When the assignment or the grant ends, access ends at once, including queued actions and scheduled sends they started. An assigned-only grant restricts nothing for someone who also has mailbox-wide access, directly or through a group; remove that wider grant first. Spaces leaves such mailboxes out of its invitation picker.
- API, removed without an alias:
assigneeUserIdbecomesassigneeUserIds(an array) andassigneebecomesassigneesin REST (list items, search hits, focus items, collaboration) and in the capabilitiesconversation.read,conversation.assign,conversation.assign.batch,conversation.snoozeandconversation.status.update. The bulk endpointPOST /api/mail/mailboxes/{mailboxId}/conversations/assigntakesassigneeUserIdswith a requiredmodeofadd,removeorreplace(replacewith[]clears). The collaborationPATCHreplaces the whole set.conversation.assignlosesexpectedRevisionand takesmode. A request with the old fields or withoutmodefails validation, with one exception: the collaborationPATCHignores unknown fields, so an oldassigneeUserIdsent together with another change, such ascompletion, is dropped silently while the other change succeeds. The capability IDs stay the same, so update their callers together with Mail, and have MCP clients and other callers refresh cached capability schemas. Mailbox responses and themailbox.listandmailbox.browsecapabilities gainaccessScope; pick a mailbox withaccessScope: "mailbox"before you create new mail. - Saved Mail workflows: a workflow that reads
inputs.conversation.assigneeUserIdkeeps its saved version, but in its runs the field no longer exists: a step that reads it fails with an unavailable reference, andexistson it is false. Saving or validating the workflow again reports the unknown field. Find such workflows withcld mail workflow listandcld mail workflow export <workflow-id>, then useinputs.conversation.assigneeUserIds, for example${{ inputs.conversation.assigneeUserIds.0 }}for the first assignee. The workflow actionassignConversationkeeps itsuserinput and replaces all assignees with that person. - CLI:
cld mail assign --tonow adds people. Add--replaceto replace them, or use--remove.cld mail conversation update --assigneetakes several people and replaces all assignees;--unassignremoves them all. Check scripts that relied on--toreplacing the assignee.cld mail access grant|settakes--scope assigned, andcld mail lsshows each mailbox's scope. - Platform administrators without a mailbox grant no longer count as mailbox users in Mail's background checks: reminders and other conversation notifications, workflow notices, viewing presence, saved views shared with them, and whether they can still work on a conversation they are assigned to. Opening the mailbox already required a grant. An incoming automation that such an administrator authorized pauses its Spaces authorization on its next run; give that person a mailbox grant with Edit (
write) access and have them authorize it again. Give administrators who rely on Mail notifications an explicit grant. - Upgrade: Mail's first start creates
mail.conversation_assignees, copies every existing assignment into it once, and createsmail.mailbox_assigned_access. From then on the new table is the source of assignments; Mail keeps the old columnmail.conversations.assignee_user_idat the earliest assignee so that an older image still shows one. Roll all Mail replicas over in one go: a 0.36.0 replica reads and changes only the old column and treats people with assigned-only access as having no access. Open Mail tabs from before the update cannot assign until they are reloaded. Afterwards, assign two people to a test conversation and check thatcld --json mail show <conversation-id>lists both.
Assistant Skills ship with their apps
- What changes (#840): built-in Skills are no longer templates inside Core. Each app ships its own:
cloud-grids(Grids),cloud-mail(Mail),cloud-notebooks(Notebooks),cloud-contacts(Contacts),cloud-spaces(Spaces),cloud-weather(Weather), andcloud-assistant,scheduled-tasks,skill-creator,assistant-code-modeandassistant-data-analysis(Assistant). Third-party apps can ship Skills the same way. - One-way migration in Core: Core's first start links the installed built-in Skills to their apps. It keeps Skill IDs, access, personal Enabled settings and administrator edits, and deleted Skills stay deleted. It then drops the old seed table
ai.skill_seedsand the template columns ofai.skills. See "Rollback". - Who gets which Skill: an app installs or updates its Skills when it starts with this release. Until then, and while an app does not run, its Skills are not offered. An unchanged Skill follows its app's content; an edited one keeps the edit. App Skills are offered only to people who may open the app, by the same rule as Help: guests no longer see the Skills of Grids, Mail, Contacts, Spaces and Weather, and only administrators see those of an app reached only through the administration. A grant to a specific person, group or service account still gives access, also to someone outside the app's audience, and the migration keeps such grants. Review them if you expect a Skill to become restricted.
- After the update, open Administration → AI Skills. App update available marks an edited Skill whose app ships different content; compare it and reset it to the app version if you want the update. Name in use marks an app Skill whose name an existing Skill already has; Use existing Skill links it and keeps its content. App Skills not installed lists deleted app Skills; Restore installs them again.
- Removed:
cld admin ai skills templatesandassociate, and the routesGET /api/ai/skills/templates/:name,GET /api/admin/core/ai-skills/templatesandPOST /api/admin/core/ai-skills/:skillId/template.cld admin ai skills resetnow resets to the app version you name with--app-version, shown bycld admin ai skills list. Scripts switch to thesourcefield and the reset, restore and adopt actions. Code that used the seed API moves toskill()(see "npm and public API").
Deploy order
- Back up the database right before the update. Core's Skills migration is one-way, and in the Compose template all services share one database.
- Update Core first, all replicas at once. Once a 0.37.0 Core has started, do not start an older Core against the database, also not by restarting an old replica during the rollout. The new Core closes the Help gap and serves the widget stream that the new Dashboard needs.
- Then update the applications soon after. An application still on 0.36.0 keeps working, but Core does not offer its Skills until it runs 0.37.0. Update Assistant early, because it owns
skill-creator,scheduled-tasks, Code Mode and data analysis. An application that starts before Core logsApp skill schema is not available yet; next heartbeat will retryand catches up by itself. - Mail: replace all replicas at once, together with third-party applications, scripts and saved workflows that use the single assignee fields.
- Dashboard after Core: the new Dashboard loads its widgets from Core's new
GET /api/widgets/v1, which a 0.36.0 Core does not have. - Gateway: this release changes only the shared library in the gateway image, so update it in any order. An older gateway or Core ignores the new
skillsfield in registry entries. Keep the gateway at 0.35.0 or later. - CLI: run
cld plugins update --allfor the changed Mail, Notebooks, admin and Assistant commands.
Building images from source: the Dockerfiles now take their Bun base images and the Dockerfile frontend from the public mirror ghcr.io/k2b-dev/mirror, at the same digests as on Docker Hub (#801). A build needs access to ghcr.io without a login, and no longer to Docker Hub. This applies to Dockerfile, Dockerfile.dev, docs-site/Dockerfile and pwas/pwa-auth/Dockerfile. The published release images do not change.
Rollback
- Core cannot go back without a restore. A 0.36.0 Core would install the deleted built-in Skills again, open to everyone signed in, and it would reopen the Help gap. To go back below 0.37.0, roll back every service and restore the backup from step 1. Everything written after the update is lost, so decide early.
- Mail alone can go back to 0.36.0 while Core stays at 0.37.0. Roll back all replicas together. The new tables stay; 0.36.0 shows only the earliest assignee and denies people with assigned-only access, and assignments it changes are lost when Mail is updated again. Callers already on the new fields must go back too.
- Other applications can go back one by one. While one runs below 0.37.0, Core does not offer its Skills; they return with the next update.
- Do not roll the gateway back below 0.35.0 (see the 0.35.0 security notes).
What else changes
- Dashboard (#831): the board appears at once with a fixed space per widget, and each widget fills its space from Core's new streamed
GET /api/widgets/v1. Each widget has 8 seconds instead of 500 ms, Core runs at most eight at a time, and one stream ends after 30 seconds, so on a board with many slow widgets the last ones can time out. A failed widget shows Try again in its own space. The single-widget endpoint keeps its responses and uses the same 8-second budget. Widget handlers are unchanged. Leaving the page no longer logs widget failures. - Code runs and identity issuance (#832): Studio code runs no longer fail with "Identity issuance deadline exceeded" while they wait for an approval or run for a long time. One deadline now covers the whole issuance, and a stall fails with a
TimeoutErrorthat names the stalled step. The shared signer refresh and identity settings load give up after 30 seconds; Core then logsCloud identity signer refresh failedand keeps signing with a still valid cached key. Code Mode tools retry a timed-out issuance for about 35 seconds. Nothing to configure. - Assistant: a chart of known numbers shows directly in the chat through the new built-in
charttool, also in background and scheduled runs, andcld assistantprints its data as a table (#847). Approval cards and receipts use an app's own sentences where it declares them; Mail, Spaces and Files do (#846). Older Cloud versions ignore these sentences. - Spaces and Venue: the Spaces Timeline view is gone. A saved link with
cv=timelineopens the month view of its day, and the row of overdue and undated tasks moves below the Day view. The internalGET /api/spaces/workspace/viewno longer readsfrom,toandincludeTray, calendar snapshots no longer carryrange, and a day view snapshot carriestray(#798). In the month view of Spaces and Venue, a click selects a day instead of opening it. A drag or Shift selects a range, a quick create opens at the selection, and a drag over several days creates one all-day event. Right-click, long press or Shift+F10 opens a day menu with Open day and Open week. Events over several days show as one bar per week (#826). - iPad (#799): bare dialogs open again on iPad in Safari and Chrome. Before, the app launcher and the settings dialogs of Notebooks, Spaces, Mail, Pulse and Venue showed only a blurred page. Each application's image carries the fix.
- Faster first load (#851): the shell loads about 59 KB (Brotli) less JavaScript on every page, and the Mail mailbox about 225 KB less. Dialogs that now load on demand show a spinner on their trigger. From now on, a tab opened before an update that needs code the update removed shows one notice that offers a reload.
- Smaller changes: every date picker marks today (#839). Busy buttons keep their width and no longer show their loading text (#845).
cld notebooks catandeditthrough a mirror file now count lines as the file shows them, including its front matter, so scripts that added the offset themselves must stop doing that (#802).
npm and public API
@k2b/cloud 0.30.0 (breaking; depends on @k2b/ui 0.21.0, @k2b/ssr 0.15.0, @k2b/sync 7.0.0, @k2b/stdlib 0.28.0 and @k2b/nessi 0.17.0)
- Removed (#840):
seedCloudAiSkills,aiSkills.seedOnce,aiSkills.admin.applyTemplate,AiSkillTemplateand the fieldstemplateId,templateVersion,currentTemplateVersionandtemplateStatus. Keep each Skill assrc/skills/<name>/SKILL.mdwith optionalreferences/*.md, declare it withskill()and pass it todefineApp({ skills });app.start()validates it. - Mail and access (#830): the Mail contract changes as described above.
PermissionEditorcan offer a level on part of a resource (allowedLevels[].scope), and generatedcld … accesscommands take--scopewhen the adapter declaresscopes. A scoped grant never counts as a manager. - Help (#827):
preloadLayoutHelp(c, appId)returnsnullwithout a signed-in user.defineHelpCollection()is deprecated; usedefineHelp()withapp.start({ help }). If guests may not use your application, declarenav.requiresRoles: ["user"]. - New:
streamWidgets()from the new entry point@k2b/cloud/browser/widgetsandWidgetStreamLinefrom@k2b/cloud/contracts(#831);importOnDemand()from@k2b/cloud/browser/reload(#851); Actionsentencesin capability presentation catalogs andgetCapabilityActionWording()from@k2b/cloud/capabilities/server(#846);CloudAiChartInputSchema,parseCloudAiChartInput()andcloudAiChartTable()from@k2b/cloud/ai/browser(#847).
@k2b/ui 0.21.0 (additive, with one changed contract)
- Button loading (#845): a busy
Buttonkeeps its idle box, andloadingLabelis no longer shown; it becomes the accessible name while the button is busy. Pass only the idle content and do not swap children onloading. - Calendar month view (#826): selection, quick create and day menu through
renderQuickCreate,selectionMenu,onSelectionChangeandtoolbarContent.ContextMenureturns focus to the element that had it on Escape. - Other: date pickers mark today (#839). A bare dialog takes its content's height, so content that needs a fixed height sets it itself (#799). The
compactwidget frame grows from 12rem to 14rem, and fixed frames scroll taller content (#831).
Also in this release
These commits are in the tag but missing from the changelog above, because release-please hides their types:
- Help rewrites (#836, #837, #848, #852, docs). The in-app Help of Mail, Notebooks, Grids, Core, Accounts, Contacts, Gateway Ops, Pulse, Spaces and Tools now follows the help writing rules in English and German, quotes interface labels exactly and corrects statements that no longer matched the product. It ships in each application's image. The applications themselves do not change.
- #829 docs: help writing rules and a Cloud glossary for application authors, plus a repository check for the built-in Help. No runtime change.
- #801 ci: CI, the release workflows and the image builds pull every former Docker Hub image from the public mirror
ghcr.io/k2b-dev/mirror, pinned to the same digests, because Docker Hub's pull limit had failed release runs. See "Building images from source" above. - #828 ci: CI takes the PDF tools (Poppler) from a pinned image, which now also comes from the mirror, instead of installing them on the runner. Only tests use it.
- #834 test and #838 test(ui): a production page-weight and time-to-interactive baseline script for maintainers, and steadier VideoPlayer tests in WebKit. No runtime change.